From f50f473ae6915a4367b33059c463f41cae85ead7 Mon Sep 17 00:00:00 2001 From: David Howells Date: Mon, 28 Mar 2011 12:53:29 +0100 Subject: [PATCH] --- yaml --- r: 243391 b: refs/heads/master c: eac522ef438f8ea173569fd0469371bc5d317947 h: refs/heads/master i: 243389: 977f26127a996a7f2468d0bdad990f45824ce9ff 243387: 49c401f3156579681b8ec39fa435542b331209e9 243383: 265c0dfcf6dbb89a67a4b0cbae52ac8c794a5dcf 243375: 69c8e8733221ade6f75220761d1c6803a29092c8 243359: e5bfe3edc153fbfc9878dcd412bef54e97c23403 243327: 2b791a9592e15fafe60b5c0b8fb97e27a3c39e9c v: v3 --- [refs] | 2 +- .../ABI/testing/sysfs-bus-pci-devices-cciss | 12 - .../ABI/testing/sysfs-driver-samsung-laptop | 19 - .../ABI/testing/sysfs-platform-asus-wmi | 31 - .../ABI/testing/sysfs-platform-eeepc-wmi | 10 + trunk/Documentation/DocBook/Makefile | 1 + trunk/Documentation/DocBook/rapidio.tmpl | 1 + .../Documentation/development-process/1.Intro | 18 +- .../development-process/2.Process | 177 +- .../development-process/3.Early-stage | 31 +- .../development-process/4.Coding | 21 +- .../development-process/5.Posting | 28 +- .../development-process/6.Followthrough | 16 +- .../development-process/7.AdvancedTopics | 4 +- trunk/Documentation/dynamic-debug-howto.txt | 4 +- trunk/Documentation/hwmon/f71882fg | 19 - trunk/Documentation/laptops/sony-laptop.txt | 37 +- trunk/MAINTAINERS | 35 +- trunk/arch/alpha/Kconfig | 1 - trunk/arch/alpha/kernel/irq.c | 67 +- trunk/arch/alpha/kernel/irq_alpha.c | 2 +- trunk/arch/alpha/kernel/irq_i8259.c | 2 +- trunk/arch/alpha/kernel/irq_pyxis.c | 2 +- trunk/arch/alpha/kernel/irq_srm.c | 2 +- trunk/arch/alpha/kernel/sys_alcor.c | 2 +- trunk/arch/alpha/kernel/sys_cabriolet.c | 4 +- trunk/arch/alpha/kernel/sys_dp264.c | 2 +- trunk/arch/alpha/kernel/sys_eb64p.c | 2 +- trunk/arch/alpha/kernel/sys_eiger.c | 2 +- trunk/arch/alpha/kernel/sys_jensen.c | 10 +- trunk/arch/alpha/kernel/sys_marvel.c | 8 +- trunk/arch/alpha/kernel/sys_mikasa.c | 3 +- trunk/arch/alpha/kernel/sys_noritake.c | 3 +- trunk/arch/alpha/kernel/sys_rawhide.c | 3 +- trunk/arch/alpha/kernel/sys_rx164.c | 2 +- trunk/arch/alpha/kernel/sys_sable.c | 4 +- trunk/arch/alpha/kernel/sys_takara.c | 3 +- trunk/arch/alpha/kernel/sys_titan.c | 2 +- trunk/arch/alpha/kernel/sys_wildfire.c | 12 +- trunk/arch/arm/Kconfig | 2 - trunk/arch/arm/common/gic.c | 15 +- trunk/arch/arm/common/it8152.c | 4 +- trunk/arch/arm/common/locomo.c | 17 +- trunk/arch/arm/common/sa1111.c | 24 +- trunk/arch/arm/common/vic.c | 6 +- trunk/arch/arm/include/asm/hw_irq.h | 8 + trunk/arch/arm/kernel/bios32.c | 25 + trunk/arch/arm/kernel/ecard.c | 6 +- trunk/arch/arm/kernel/irq.c | 70 +- trunk/arch/arm/mach-at91/at91cap9_devices.c | 6 +- trunk/arch/arm/mach-at91/gpio.c | 43 +- .../arm/mach-at91/include/mach/at572d940hf.h | 2 +- trunk/arch/arm/mach-at91/irq.c | 3 +- trunk/arch/arm/mach-bcmring/irq.c | 10 +- trunk/arch/arm/mach-clps711x/irq.c | 8 +- trunk/arch/arm/mach-davinci/cp_intc.c | 4 +- trunk/arch/arm/mach-davinci/gpio.c | 49 +- trunk/arch/arm/mach-davinci/irq.c | 6 +- trunk/arch/arm/mach-dove/include/mach/dove.h | 2 +- trunk/arch/arm/mach-dove/irq.c | 20 +- trunk/arch/arm/mach-dove/mpp.c | 3 + trunk/arch/arm/mach-ebsa110/core.c | 4 +- trunk/arch/arm/mach-ep93xx/gpio.c | 52 +- trunk/arch/arm/mach-exynos4/Kconfig | 7 +- trunk/arch/arm/mach-exynos4/Makefile | 2 +- .../mach-exynos4/include/mach/debug-macro.S | 4 +- trunk/arch/arm/mach-exynos4/irq-combiner.c | 13 +- trunk/arch/arm/mach-exynos4/irq-eint.c | 15 +- trunk/arch/arm/mach-exynos4/mach-smdkc210.c | 2 +- trunk/arch/arm/mach-exynos4/mach-smdkv310.c | 2 +- trunk/arch/arm/mach-footbridge/common.c | 3 +- .../arch/arm/mach-footbridge/dc21285-timer.c | 2 +- trunk/arch/arm/mach-footbridge/isa-irq.c | 10 +- trunk/arch/arm/mach-gemini/gpio.c | 14 +- trunk/arch/arm/mach-gemini/irq.c | 6 +- trunk/arch/arm/mach-h720x/common.c | 22 +- trunk/arch/arm/mach-h720x/cpu-h7202.c | 17 +- trunk/arch/arm/mach-iop13xx/irq.c | 10 +- trunk/arch/arm/mach-iop13xx/msi.c | 6 +- trunk/arch/arm/mach-iop32x/irq.c | 3 +- trunk/arch/arm/mach-iop33x/irq.c | 5 +- trunk/arch/arm/mach-ixp2000/core.c | 20 +- trunk/arch/arm/mach-ixp2000/ixdp2x00.c | 6 +- trunk/arch/arm/mach-ixp2000/ixdp2x01.c | 6 +- trunk/arch/arm/mach-ixp23xx/core.c | 14 +- trunk/arch/arm/mach-ixp23xx/ixdp2351.c | 12 +- trunk/arch/arm/mach-ixp23xx/roadrunner.c | 4 +- trunk/arch/arm/mach-ixp4xx/avila-pci.c | 8 +- trunk/arch/arm/mach-ixp4xx/common.c | 4 +- trunk/arch/arm/mach-ixp4xx/coyote-pci.c | 4 +- trunk/arch/arm/mach-ixp4xx/dsmg600-pci.c | 12 +- trunk/arch/arm/mach-ixp4xx/fsg-pci.c | 6 +- trunk/arch/arm/mach-ixp4xx/gateway7001-pci.c | 4 +- trunk/arch/arm/mach-ixp4xx/goramo_mlr.c | 12 +- trunk/arch/arm/mach-ixp4xx/gtwx5715-pci.c | 4 +- trunk/arch/arm/mach-ixp4xx/ixdp425-pci.c | 8 +- trunk/arch/arm/mach-ixp4xx/ixdpg425-pci.c | 4 +- trunk/arch/arm/mach-ixp4xx/nas100d-pci.c | 10 +- trunk/arch/arm/mach-ixp4xx/nslu2-pci.c | 6 +- trunk/arch/arm/mach-ixp4xx/vulcan-pci.c | 4 +- trunk/arch/arm/mach-ixp4xx/wg302v2-pci.c | 4 +- trunk/arch/arm/mach-kirkwood/irq.c | 15 +- trunk/arch/arm/mach-ks8695/gpio.c | 2 +- trunk/arch/arm/mach-ks8695/irq.c | 18 +- trunk/arch/arm/mach-lpc32xx/irq.c | 10 +- trunk/arch/arm/mach-mmp/irq-mmp2.c | 18 +- trunk/arch/arm/mach-mmp/irq-pxa168.c | 3 +- trunk/arch/arm/mach-msm/board-msm8960.c | 2 +- trunk/arch/arm/mach-msm/board-msm8x60.c | 2 +- trunk/arch/arm/mach-msm/board-trout-gpio.c | 10 +- trunk/arch/arm/mach-msm/board-trout-mmc.c | 2 +- trunk/arch/arm/mach-msm/gpio-v2.c | 49 +- trunk/arch/arm/mach-msm/gpio.c | 18 +- trunk/arch/arm/mach-msm/irq-vic.c | 7 +- trunk/arch/arm/mach-msm/irq.c | 7 +- trunk/arch/arm/mach-msm/sirc.c | 11 +- trunk/arch/arm/mach-mv78xx0/irq.c | 8 +- trunk/arch/arm/mach-mx3/mach-mx31ads.c | 7 +- .../arm/mach-mx5/eukrea_mbimx51-baseboard.c | 2 +- trunk/arch/arm/mach-mx5/mx51_efika.c | 6 +- trunk/arch/arm/mach-mxs/gpio.c | 10 +- trunk/arch/arm/mach-mxs/icoll.c | 3 +- trunk/arch/arm/mach-netx/generic.c | 6 +- trunk/arch/arm/mach-ns9xxx/board-a9m9750dev.c | 8 +- .../arch/arm/mach-ns9xxx/include/mach/board.h | 2 + .../arm/mach-ns9xxx/include/mach/module.h | 5 + trunk/arch/arm/mach-ns9xxx/irq.c | 59 +- trunk/arch/arm/mach-nuc93x/irq.c | 4 +- trunk/arch/arm/mach-omap1/board-osk.c | 6 +- trunk/arch/arm/mach-omap1/board-palmz71.c | 8 +- trunk/arch/arm/mach-omap1/board-voiceblue.c | 8 +- trunk/arch/arm/mach-omap1/fpga.c | 10 +- trunk/arch/arm/mach-omap1/irq.c | 4 +- trunk/arch/arm/mach-omap2/board-omap4panda.c | 28 + trunk/arch/arm/mach-omap2/devices.c | 2 +- trunk/arch/arm/mach-omap2/gpmc.c | 13 +- trunk/arch/arm/mach-omap2/irq.c | 3 +- trunk/arch/arm/mach-omap2/omap_l3_smx.c | 11 +- trunk/arch/arm/mach-orion5x/db88f5281-setup.c | 4 +- trunk/arch/arm/mach-orion5x/irq.c | 8 +- trunk/arch/arm/mach-orion5x/rd88f5182-setup.c | 4 +- .../arm/mach-orion5x/terastation_pro2-setup.c | 2 +- trunk/arch/arm/mach-orion5x/ts209-setup.c | 4 +- trunk/arch/arm/mach-pnx4008/irq.c | 10 +- trunk/arch/arm/mach-pxa/balloon3.c | 8 +- trunk/arch/arm/mach-pxa/cm-x2xx-pci.c | 5 +- trunk/arch/arm/mach-pxa/cm-x300.c | 2 +- trunk/arch/arm/mach-pxa/irq.c | 12 +- trunk/arch/arm/mach-pxa/lpd270.c | 8 +- trunk/arch/arm/mach-pxa/lubbock.c | 8 +- trunk/arch/arm/mach-pxa/mainstone.c | 8 +- trunk/arch/arm/mach-pxa/pcm990-baseboard.c | 8 +- trunk/arch/arm/mach-pxa/pxa3xx.c | 4 +- trunk/arch/arm/mach-pxa/viper.c | 8 +- trunk/arch/arm/mach-pxa/zeus.c | 19 +- trunk/arch/arm/mach-rpc/irq.c | 14 +- trunk/arch/arm/mach-s3c2410/bast-irq.c | 6 +- trunk/arch/arm/mach-s3c2412/irq.c | 12 +- trunk/arch/arm/mach-s3c2416/irq.c | 8 +- trunk/arch/arm/mach-s3c2440/irq.c | 10 +- trunk/arch/arm/mach-s3c2440/s3c244x-irq.c | 14 +- trunk/arch/arm/mach-s3c2443/irq.c | 8 +- trunk/arch/arm/mach-s3c64xx/irq-eint.c | 13 +- trunk/arch/arm/mach-s5p64x0/cpu.c | 2 +- .../arch/arm/mach-s5pv210/include/mach/irqs.h | 6 +- trunk/arch/arm/mach-s5pv210/mach-smdkv210.c | 1 + trunk/arch/arm/mach-sa1100/cerf.c | 2 +- trunk/arch/arm/mach-sa1100/irq.c | 16 +- trunk/arch/arm/mach-sa1100/neponset.c | 8 +- trunk/arch/arm/mach-sa1100/pleb.c | 2 +- trunk/arch/arm/mach-shark/irq.c | 3 +- trunk/arch/arm/mach-shmobile/board-ap4evb.c | 4 +- trunk/arch/arm/mach-shmobile/board-mackerel.c | 6 +- trunk/arch/arm/mach-shmobile/intc-sh7367.c | 6 +- trunk/arch/arm/mach-shmobile/intc-sh7372.c | 6 +- trunk/arch/arm/mach-shmobile/intc-sh7377.c | 6 +- trunk/arch/arm/mach-tcc8k/irq.c | 6 +- trunk/arch/arm/mach-tegra/gpio.c | 39 +- trunk/arch/arm/mach-tegra/irq.c | 5 +- trunk/arch/arm/mach-ux500/Kconfig | 1 - .../arm/mach-ux500/board-mop500-regulators.c | 201 -- .../arm/mach-ux500/board-mop500-regulators.h | 3 - trunk/arch/arm/mach-ux500/board-mop500.c | 50 +- trunk/arch/arm/mach-ux500/board-mop500.h | 4 - .../include/mach/irqs-board-mop500.h | 15 +- trunk/arch/arm/mach-ux500/modem-irq-db5500.c | 3 +- trunk/arch/arm/mach-versatile/core.c | 2 +- trunk/arch/arm/mach-vt8500/irq.c | 14 +- trunk/arch/arm/mach-w90x900/irq.c | 4 +- trunk/arch/arm/plat-mxc/3ds_debugboard.c | 14 +- trunk/arch/arm/plat-mxc/avic.c | 4 +- trunk/arch/arm/plat-mxc/gpio.c | 24 +- trunk/arch/arm/plat-mxc/irq-common.c | 4 +- trunk/arch/arm/plat-mxc/tzic.c | 4 +- trunk/arch/arm/plat-nomadik/gpio.c | 57 +- trunk/arch/arm/plat-omap/gpio.c | 31 +- trunk/arch/arm/plat-omap/include/plat/irqs.h | 2 +- .../arch/arm/plat-omap/include/plat/onenand.h | 1 - trunk/arch/arm/plat-orion/gpio.c | 31 +- trunk/arch/arm/plat-orion/irq.c | 8 +- trunk/arch/arm/plat-pxa/gpio.c | 6 +- .../arm/plat-pxa/include/plat/pxa3xx_nand.h | 2 +- trunk/arch/arm/plat-s3c24xx/irq.c | 43 +- trunk/arch/arm/plat-s5p/cpu.c | 8 +- trunk/arch/arm/plat-s5p/irq-eint.c | 7 +- trunk/arch/arm/plat-s5p/irq-gpioint.c | 22 +- trunk/arch/arm/plat-samsung/init.c | 2 +- trunk/arch/arm/plat-samsung/irq-uart.c | 10 +- trunk/arch/arm/plat-samsung/irq-vic-timer.c | 11 +- trunk/arch/arm/plat-samsung/wakeup-mask.c | 8 +- trunk/arch/arm/plat-spear/shirq.c | 12 +- trunk/arch/arm/plat-stmp3xxx/irq.c | 3 +- trunk/arch/arm/plat-stmp3xxx/pinmux.c | 13 +- trunk/arch/arm/plat-versatile/fpga-irq.c | 12 +- trunk/arch/blackfin/kernel/irqchip.c | 2 +- trunk/arch/blackfin/kernel/trace.c | 7 +- trunk/arch/blackfin/mach-bf561/smp.c | 6 +- .../arch/blackfin/mach-common/ints-priority.c | 43 +- trunk/arch/cris/Kconfig | 4 +- .../arch/cris/arch-v10/drivers/axisflashmap.c | 6 + trunk/arch/cris/arch-v10/drivers/pcf8563.c | 2 +- trunk/arch/cris/arch-v10/kernel/signal.c | 2 +- trunk/arch/cris/arch-v32/drivers/Kconfig | 1 + trunk/arch/cris/arch-v32/drivers/Makefile | 1 + .../arch/cris/arch-v32/drivers/axisflashmap.c | 6 + trunk/arch/cris/arch-v32/drivers/pcf8563.c | 377 +++ trunk/arch/frv/Kconfig | 2 - trunk/arch/frv/kernel/irq-mb93091.c | 28 +- trunk/arch/frv/kernel/irq-mb93093.c | 31 +- trunk/arch/frv/kernel/irq-mb93493.c | 25 +- trunk/arch/frv/kernel/irq.c | 80 +- trunk/arch/ia64/Kconfig | 1 - trunk/arch/ia64/hp/sim/hpsim_irq.c | 31 +- trunk/arch/ia64/include/asm/hw_irq.h | 3 + trunk/arch/ia64/kernel/iosapic.c | 119 +- trunk/arch/ia64/kernel/irq.c | 73 +- trunk/arch/ia64/kernel/irq_ia64.c | 10 +- trunk/arch/ia64/kernel/irq_lsapic.c | 23 +- trunk/arch/ia64/kernel/mca.c | 4 +- trunk/arch/ia64/kernel/msi_ia64.c | 49 +- trunk/arch/ia64/kernel/smpboot.c | 14 +- trunk/arch/ia64/sn/kernel/irq.c | 97 +- trunk/arch/ia64/sn/kernel/msi_sn.c | 32 +- trunk/arch/ia64/xen/irq_xen.c | 4 +- trunk/arch/m68k/kernel/irq.c | 2 +- trunk/arch/m68k/platform/5249/intc2.c | 4 +- trunk/arch/m68k/platform/5272/intc.c | 12 +- trunk/arch/m68k/platform/68328/ints.c | 4 +- trunk/arch/m68k/platform/68360/ints.c | 4 +- trunk/arch/m68k/platform/coldfire/intc-2.c | 10 +- trunk/arch/m68k/platform/coldfire/intc-simr.c | 10 +- trunk/arch/m68k/platform/coldfire/intc.c | 6 +- trunk/arch/microblaze/Kconfig | 1 - trunk/arch/microblaze/kernel/intc.c | 6 +- trunk/arch/microblaze/kernel/irq.c | 42 + trunk/arch/microblaze/pci/pci-common.c | 2 +- trunk/arch/mips/alchemy/devboards/bcsr.c | 6 +- .../mips/alchemy/devboards/db1200/setup.c | 15 +- .../alchemy/devboards/db1x00/board_setup.c | 50 +- .../alchemy/devboards/pb1000/board_setup.c | 2 +- .../alchemy/devboards/pb1100/board_setup.c | 8 +- .../alchemy/devboards/pb1200/board_setup.c | 2 +- .../alchemy/devboards/pb1500/board_setup.c | 16 +- .../alchemy/devboards/pb1550/board_setup.c | 6 +- trunk/arch/mips/alchemy/mtx-1/board_setup.c | 10 +- trunk/arch/mips/alchemy/xxs1500/board_setup.c | 24 +- trunk/arch/mips/ar7/irq.c | 4 +- trunk/arch/mips/ath79/irq.c | 4 +- trunk/arch/mips/bcm63xx/irq.c | 4 +- trunk/arch/mips/cavium-octeon/octeon-irq.c | 1389 ++++----- trunk/arch/mips/cavium-octeon/setup.c | 12 + trunk/arch/mips/cavium-octeon/smp.c | 39 +- trunk/arch/mips/dec/ioasic-irq.c | 4 +- trunk/arch/mips/dec/kn02-irq.c | 2 +- trunk/arch/mips/emma/markeins/irq.c | 6 +- .../mips/include/asm/mach-cavium-octeon/irq.h | 243 +- trunk/arch/mips/include/asm/octeon/octeon.h | 2 - trunk/arch/mips/include/asm/unistd.h | 2 +- trunk/arch/mips/jazz/irq.c | 2 +- trunk/arch/mips/jz4740/gpio.c | 14 +- trunk/arch/mips/jz4740/irq.c | 4 +- trunk/arch/mips/kernel/i8259.c | 6 +- trunk/arch/mips/kernel/irq-gic.c | 2 +- trunk/arch/mips/kernel/irq-gt641xx.c | 4 +- trunk/arch/mips/kernel/irq-msc01.c | 12 +- trunk/arch/mips/kernel/irq-rm7000.c | 2 +- trunk/arch/mips/kernel/irq-rm9000.c | 4 +- trunk/arch/mips/kernel/irq.c | 2 +- trunk/arch/mips/kernel/irq_cpu.c | 4 +- trunk/arch/mips/kernel/irq_txx9.c | 4 +- trunk/arch/mips/kernel/smtc.c | 2 +- trunk/arch/mips/lasat/interrupt.c | 2 +- trunk/arch/mips/loongson/common/bonito-irq.c | 3 +- trunk/arch/mips/mti-malta/malta-int.c | 2 +- trunk/arch/mips/mti-malta/malta-time.c | 2 +- trunk/arch/mips/pci/msi-octeon.c | 24 +- .../mips/pmc-sierra/msp71xx/msp_irq_cic.c | 2 +- .../mips/pmc-sierra/msp71xx/msp_irq_slp.c | 2 +- trunk/arch/mips/pmc-sierra/msp71xx/msp_smp.c | 2 +- trunk/arch/mips/pnx833x/common/interrupts.c | 6 +- trunk/arch/mips/pnx8550/common/int.c | 10 +- trunk/arch/mips/powertv/asic/irq_asic.c | 2 +- trunk/arch/mips/rb532/irq.c | 4 +- trunk/arch/mips/sgi-ip22/ip22-int.c | 2 +- trunk/arch/mips/sgi-ip27/ip27-irq.c | 2 +- trunk/arch/mips/sgi-ip27/ip27-timer.c | 2 +- trunk/arch/mips/sgi-ip32/ip32-irq.c | 40 +- trunk/arch/mips/sibyte/bcm1480/irq.c | 3 +- trunk/arch/mips/sibyte/sb1250/irq.c | 3 +- trunk/arch/mips/sni/a20r.c | 2 +- trunk/arch/mips/sni/pcimt.c | 2 +- trunk/arch/mips/sni/pcit.c | 4 +- trunk/arch/mips/sni/rm200.c | 4 +- trunk/arch/mips/txx9/generic/irq_tx4927.c | 2 +- trunk/arch/mips/txx9/generic/irq_tx4938.c | 2 +- trunk/arch/mips/txx9/generic/irq_tx4939.c | 6 +- trunk/arch/mips/txx9/jmr3927/irq.c | 5 +- trunk/arch/mips/txx9/rbtx4927/irq.c | 6 +- trunk/arch/mips/txx9/rbtx4938/irq.c | 6 +- trunk/arch/mips/txx9/rbtx4939/irq.c | 4 +- trunk/arch/mips/vr41xx/common/icu.c | 4 +- trunk/arch/mips/vr41xx/common/irq.c | 2 +- trunk/arch/mn10300/Kconfig | 1 - trunk/arch/mn10300/kernel/irq.c | 85 +- trunk/arch/mn10300/kernel/mn10300-serial.c | 2 +- trunk/arch/mn10300/kernel/smp.c | 12 +- trunk/arch/mn10300/unit-asb2364/irq-fpga.c | 3 +- trunk/arch/parisc/kernel/irq.c | 32 +- trunk/arch/powerpc/Kconfig | 2 - trunk/arch/powerpc/kernel/irq.c | 81 +- trunk/arch/powerpc/kernel/machine_kexec.c | 6 +- trunk/arch/powerpc/kernel/pci-common.c | 2 +- .../powerpc/platforms/512x/mpc5121_ads_cpld.c | 6 +- trunk/arch/powerpc/platforms/52xx/media5200.c | 19 +- .../arch/powerpc/platforms/52xx/mpc52xx_gpt.c | 10 +- .../arch/powerpc/platforms/52xx/mpc52xx_pic.c | 6 +- .../powerpc/platforms/82xx/pq2ads-pci-pic.c | 16 +- trunk/arch/powerpc/platforms/85xx/ksi8560.c | 4 +- .../arch/powerpc/platforms/85xx/mpc85xx_ads.c | 4 +- .../arch/powerpc/platforms/85xx/mpc85xx_cds.c | 2 +- .../arch/powerpc/platforms/85xx/mpc85xx_ds.c | 4 +- trunk/arch/powerpc/platforms/85xx/sbc8560.c | 4 +- .../platforms/85xx/socrates_fpga_pic.c | 12 +- trunk/arch/powerpc/platforms/85xx/stx_gp3.c | 4 +- trunk/arch/powerpc/platforms/85xx/tqm85xx.c | 4 +- trunk/arch/powerpc/platforms/86xx/gef_pic.c | 8 +- trunk/arch/powerpc/platforms/86xx/pic.c | 4 +- trunk/arch/powerpc/platforms/8xx/m8xx_setup.c | 6 +- trunk/arch/powerpc/platforms/cell/Kconfig | 1 - trunk/arch/powerpc/platforms/cell/axon_msi.c | 14 +- .../powerpc/platforms/cell/beat_interrupt.c | 5 +- trunk/arch/powerpc/platforms/cell/interrupt.c | 62 +- trunk/arch/powerpc/platforms/cell/setup.c | 8 +- .../arch/powerpc/platforms/cell/spider-pic.c | 21 +- trunk/arch/powerpc/platforms/chrp/setup.c | 4 +- .../platforms/embedded6xx/flipper-pic.c | 10 +- .../powerpc/platforms/embedded6xx/hlwd-pic.c | 20 +- .../powerpc/platforms/embedded6xx/holly.c | 4 +- .../platforms/embedded6xx/mpc7448_hpc2.c | 4 +- trunk/arch/powerpc/platforms/iseries/irq.c | 4 +- trunk/arch/powerpc/platforms/maple/pci.c | 2 +- trunk/arch/powerpc/platforms/pasemi/setup.c | 2 +- trunk/arch/powerpc/platforms/powermac/pci.c | 2 +- trunk/arch/powerpc/platforms/powermac/pic.c | 17 +- trunk/arch/powerpc/platforms/ps3/interrupt.c | 14 +- trunk/arch/powerpc/platforms/pseries/msi.c | 4 +- trunk/arch/powerpc/platforms/pseries/setup.c | 4 +- trunk/arch/powerpc/platforms/pseries/xics.c | 8 +- trunk/arch/powerpc/sysdev/cpm1.c | 4 +- trunk/arch/powerpc/sysdev/cpm2_pic.c | 47 +- trunk/arch/powerpc/sysdev/fsl_msi.c | 43 +- trunk/arch/powerpc/sysdev/i8259.c | 8 +- trunk/arch/powerpc/sysdev/ipic.c | 22 +- trunk/arch/powerpc/sysdev/mpc8xx_pic.c | 11 +- trunk/arch/powerpc/sysdev/mpc8xxx_gpio.c | 12 +- trunk/arch/powerpc/sysdev/mpic.c | 43 +- trunk/arch/powerpc/sysdev/mpic_pasemi_msi.c | 8 +- trunk/arch/powerpc/sysdev/mpic_u3msi.c | 8 +- trunk/arch/powerpc/sysdev/mv64x60_pic.c | 5 +- trunk/arch/powerpc/sysdev/qe_lib/qe_ic.c | 16 +- trunk/arch/powerpc/sysdev/tsi108_pci.c | 6 +- trunk/arch/powerpc/sysdev/uic.c | 41 +- trunk/arch/powerpc/sysdev/xilinx_intc.c | 20 +- trunk/arch/score/Kconfig | 2 - trunk/arch/score/include/asm/irqflags.h | 2 +- trunk/arch/score/kernel/irq.c | 53 +- trunk/arch/sh/boards/board-magicpanelr2.c | 12 +- trunk/arch/sh/boards/mach-cayman/irq.c | 4 +- trunk/arch/sh/boards/mach-dreamcast/irq.c | 3 +- trunk/arch/sh/boards/mach-ecovec24/setup.c | 2 +- trunk/arch/sh/boards/mach-microdev/irq.c | 2 +- trunk/arch/sh/boards/mach-se/7206/irq.c | 5 +- trunk/arch/sh/boards/mach-se/7343/irq.c | 23 +- trunk/arch/sh/boards/mach-se/7722/irq.c | 15 +- trunk/arch/sh/boards/mach-se/7724/irq.c | 15 +- trunk/arch/sh/boards/mach-x3proto/gpio.c | 8 +- trunk/arch/sh/cchips/hd6446x/hd64461.c | 6 +- trunk/arch/sh/kernel/cpu/irq/imask.c | 4 +- trunk/arch/sh/kernel/cpu/irq/intc-sh5.c | 2 +- trunk/arch/sh/kernel/cpu/irq/ipr.c | 6 +- trunk/arch/sparc/Kconfig | 2 - trunk/arch/sparc/kernel/irq_64.c | 123 +- trunk/arch/sparc/kernel/pci.c | 2 +- trunk/arch/sparc/kernel/pci_msi.c | 15 +- trunk/arch/tile/Kconfig | 1 - trunk/arch/tile/kernel/irq.c | 45 +- trunk/arch/unicore32/Kconfig | 1 - trunk/arch/unicore32/kernel/irq.c | 58 +- trunk/arch/x86/crypto/aesni-intel_asm.S | 5 +- trunk/arch/x86/crypto/aesni-intel_glue.c | 14 +- trunk/arch/x86/include/asm/percpu.h | 10 +- trunk/arch/x86/lib/cmpxchg16b_emu.S | 14 +- trunk/arch/x86/platform/olpc/olpc-xo1.c | 23 +- trunk/arch/x86/xen/p2m.c | 10 +- trunk/drivers/acpi/video.c | 6 + trunk/drivers/ata/pata_ixp4xx_cf.c | 2 +- trunk/drivers/ata/pata_rb532_cf.c | 4 +- trunk/drivers/block/cciss.c | 86 +- trunk/drivers/block/cciss.h | 1 - trunk/drivers/block/cciss_cmd.h | 1 - trunk/drivers/block/cciss_scsi.c | 13 +- trunk/drivers/block/drbd/drbd_actlog.c | 335 +- trunk/drivers/block/drbd/drbd_bitmap.c | 750 ++--- trunk/drivers/block/drbd/drbd_int.h | 270 +- trunk/drivers/block/drbd/drbd_main.c | 673 ++-- trunk/drivers/block/drbd/drbd_nl.c | 183 +- trunk/drivers/block/drbd/drbd_proc.c | 114 +- trunk/drivers/block/drbd/drbd_receiver.c | 608 ++-- trunk/drivers/block/drbd/drbd_req.c | 169 +- trunk/drivers/block/drbd/drbd_req.h | 36 +- trunk/drivers/block/drbd/drbd_strings.c | 6 +- trunk/drivers/block/drbd/drbd_worker.c | 360 +-- trunk/drivers/block/drbd/drbd_wrappers.h | 2 +- trunk/drivers/char/tpm/tpm.c | 2 +- trunk/drivers/dma/ipu/ipu_irq.c | 58 +- trunk/drivers/edac/amd64_edac.c | 2 +- trunk/drivers/gpio/Kconfig | 5 - trunk/drivers/gpio/Makefile | 1 - trunk/drivers/gpio/ab8500-gpio.c | 522 ---- trunk/drivers/hwmon/Kconfig | 17 +- trunk/drivers/hwmon/f71882fg.c | 126 +- trunk/drivers/hwmon/gpio-fan.c | 2 +- trunk/drivers/hwmon/pmbus_core.c | 70 +- trunk/drivers/hwspinlock/Kconfig | 1 - trunk/drivers/ide/ide-io.c | 12 +- trunk/drivers/input/keyboard/lm8323.c | 4 +- trunk/drivers/input/serio/ams_delta_serio.c | 2 +- .../input/touchscreen/mainstone-wm97xx.c | 2 +- .../input/touchscreen/zylonite-wm97xx.c | 2 +- trunk/drivers/md/md.c | 8 +- trunk/drivers/memstick/host/r592.c | 6 +- trunk/drivers/mfd/88pm860x-core.c | 11 +- trunk/drivers/mfd/Kconfig | 3 +- trunk/drivers/mfd/Makefile | 2 +- trunk/drivers/mfd/ab3550-core.c | 12 +- trunk/drivers/mfd/ab8500-core.c | 26 +- trunk/drivers/mfd/ab8500-i2c.c | 2 +- trunk/drivers/mfd/asic3.c | 38 +- trunk/drivers/mfd/cs5535-mfd.c | 16 - trunk/drivers/mfd/ezx-pcap.c | 34 +- trunk/drivers/mfd/htc-egpio.c | 23 +- trunk/drivers/mfd/htc-i2cpld.c | 33 +- trunk/drivers/mfd/jz4740-adc.c | 16 +- trunk/drivers/mfd/max8925-core.c | 10 +- trunk/drivers/mfd/max8997-irq.c | 377 --- trunk/drivers/mfd/max8998-irq.c | 8 +- trunk/drivers/mfd/max8998.c | 4 +- trunk/drivers/mfd/mfd-core.c | 53 +- trunk/drivers/mfd/pcf50633-core.c | 2 +- trunk/drivers/mfd/rdc321x-southbridge.c | 1 - trunk/drivers/mfd/stmpe.c | 12 +- trunk/drivers/mfd/t7l66xb.c | 21 +- trunk/drivers/mfd/tc3589x.c | 12 +- trunk/drivers/mfd/tc6393xb.c | 21 +- trunk/drivers/mfd/tps6586x.c | 6 +- trunk/drivers/mfd/twl4030-irq.c | 66 +- trunk/drivers/mfd/twl6030-irq.c | 25 +- trunk/drivers/mfd/wl1273-core.c | 2 +- trunk/drivers/mfd/wm831x-irq.c | 8 +- trunk/drivers/mfd/wm8350-irq.c | 8 +- trunk/drivers/mfd/wm8994-irq.c | 8 +- trunk/drivers/misc/sgi-gru/grufile.c | 2 +- trunk/drivers/mmc/host/sdhci-spear.c | 2 +- trunk/drivers/mtd/Kconfig | 18 +- trunk/drivers/mtd/Makefile | 4 +- trunk/drivers/mtd/chips/cfi_cmdset_0001.c | 2 +- trunk/drivers/mtd/chips/cfi_cmdset_0002.c | 3 +- trunk/drivers/mtd/chips/cfi_cmdset_0020.c | 2 +- trunk/drivers/mtd/devices/m25p80.c | 5 +- trunk/drivers/mtd/devices/mtdram.c | 1 - trunk/drivers/mtd/devices/phram.c | 3 - trunk/drivers/mtd/maps/Kconfig | 13 +- trunk/drivers/mtd/maps/Makefile | 1 - trunk/drivers/mtd/maps/ceiva.c | 6 + trunk/drivers/mtd/maps/integrator-flash.c | 10 + trunk/drivers/mtd/maps/latch-addr-flash.c | 272 -- trunk/drivers/mtd/maps/physmap.c | 8 + trunk/drivers/mtd/maps/physmap_of.c | 8 + trunk/drivers/mtd/maps/sa1100-flash.c | 8 + trunk/drivers/mtd/maps/ts5500_flash.c | 1 + trunk/drivers/mtd/mtd_blkdevs.c | 42 +- trunk/drivers/mtd/mtdconcat.c | 8 +- trunk/drivers/mtd/mtdcore.c | 6 +- trunk/drivers/mtd/mtdswap.c | 1587 ---------- trunk/drivers/mtd/nand/Kconfig | 15 - trunk/drivers/mtd/nand/Makefile | 1 - trunk/drivers/mtd/nand/atmel_nand.c | 166 +- trunk/drivers/mtd/nand/davinci_nand.c | 3 + trunk/drivers/mtd/nand/mpc5121_nfc.c | 5 +- trunk/drivers/mtd/nand/mxc_nand.c | 31 +- trunk/drivers/mtd/nand/nand_base.c | 42 +- trunk/drivers/mtd/nand/nand_bbt.c | 8 +- trunk/drivers/mtd/nand/nand_bch.c | 243 -- trunk/drivers/mtd/nand/nandsim.c | 43 +- trunk/drivers/mtd/nand/omap2.c | 16 +- trunk/drivers/mtd/nand/pxa3xx_nand.c | 977 +++--- trunk/drivers/mtd/onenand/omap2.c | 7 +- trunk/drivers/mtd/onenand/onenand_base.c | 15 +- trunk/drivers/mtd/sm_ftl.c | 18 - trunk/drivers/mtd/tests/mtd_speedtest.c | 80 +- trunk/drivers/mtd/tests/mtd_subpagetest.c | 10 +- trunk/drivers/net/bfin_mac.c | 13 +- trunk/drivers/net/bnx2.c | 2 +- trunk/drivers/net/can/c_can/c_can.c | 16 +- trunk/drivers/net/can/c_can/c_can_platform.c | 9 +- trunk/drivers/net/cxgb3/cxgb3_main.c | 14 +- trunk/drivers/net/dm9000.c | 8 +- trunk/drivers/net/jme.c | 30 +- trunk/drivers/net/ksz884x.c | 2 +- trunk/drivers/net/mlx4/en_netdev.c | 3 - trunk/drivers/net/myri10ge/myri10ge.c | 37 +- trunk/drivers/net/netxen/netxen_nic_ethtool.c | 2 +- trunk/drivers/net/qlcnic/qlcnic_ethtool.c | 2 +- trunk/drivers/net/s2io.c | 2 +- trunk/drivers/net/tg3.c | 6 +- trunk/drivers/net/vmxnet3/vmxnet3_ethtool.c | 4 +- trunk/drivers/net/vxge/vxge-ethtool.c | 4 +- trunk/drivers/net/wireless/p54/p54spi.c | 3 +- trunk/drivers/net/wireless/wl1251/sdio.c | 2 +- trunk/drivers/net/wireless/wl1251/spi.c | 2 +- trunk/drivers/parisc/eisa.c | 2 +- trunk/drivers/parisc/gsc.c | 4 +- trunk/drivers/parisc/superio.c | 3 +- trunk/drivers/pci/dmar.c | 12 +- trunk/drivers/pci/htirq.c | 16 +- trunk/drivers/pci/intel-iommu.c | 2 +- trunk/drivers/pci/intr_remapping.c | 2 +- trunk/drivers/pci/msi.c | 10 +- trunk/drivers/pcmcia/bfin_cf_pcmcia.c | 2 +- trunk/drivers/pcmcia/db1xxx_ss.c | 2 +- trunk/drivers/pcmcia/sa1100_nanoengine.c | 2 +- trunk/drivers/pcmcia/soc_common.c | 14 +- trunk/drivers/pcmcia/xxs1500_ss.c | 2 +- trunk/drivers/platform/x86/Kconfig | 90 +- trunk/drivers/platform/x86/Makefile | 9 +- trunk/drivers/platform/x86/acer-wmi.c | 127 +- trunk/drivers/platform/x86/asus-laptop.c | 182 +- trunk/drivers/platform/x86/asus-nb-wmi.c | 98 - trunk/drivers/platform/x86/asus-wmi.c | 1656 ---------- trunk/drivers/platform/x86/asus-wmi.h | 58 - trunk/drivers/platform/x86/compal-laptop.c | 8 +- trunk/drivers/platform/x86/dell-wmi-aio.c | 171 - trunk/drivers/platform/x86/eeepc-laptop.c | 2 +- trunk/drivers/platform/x86/eeepc-wmi.c | 912 +++++- trunk/drivers/platform/x86/hp-wmi.c | 312 +- trunk/drivers/platform/x86/ideapad-laptop.c | 2 - trunk/drivers/platform/x86/intel_ips.c | 2 +- .../drivers/platform/x86/intel_mid_powerbtn.c | 148 - .../drivers/platform/x86/intel_mid_thermal.c | 576 ---- trunk/drivers/platform/x86/intel_pmic_gpio.c | 8 +- .../drivers/platform/x86/intel_rar_register.c | 2 +- trunk/drivers/platform/x86/intel_scu_ipc.c | 2 +- trunk/drivers/platform/x86/msi-laptop.c | 95 +- trunk/drivers/platform/x86/samsung-laptop.c | 832 ----- trunk/drivers/platform/x86/sony-laptop.c | 501 +-- trunk/drivers/platform/x86/thinkpad_acpi.c | 4 +- trunk/drivers/platform/x86/xo15-ebook.c | 180 -- trunk/drivers/power/z2_battery.c | 4 +- trunk/drivers/regulator/Kconfig | 2 +- trunk/drivers/regulator/ab3100.c | 51 +- trunk/drivers/regulator/ab8500.c | 270 +- trunk/drivers/regulator/core.c | 116 +- trunk/drivers/regulator/max8997.c | 1 - trunk/drivers/regulator/max8998.c | 1 - trunk/drivers/regulator/tps6524x-regulator.c | 2 +- trunk/drivers/regulator/wm831x-dcdc.c | 32 +- trunk/drivers/regulator/wm831x-isink.c | 8 +- trunk/drivers/regulator/wm831x-ldo.c | 17 +- trunk/drivers/rtc/rtc-sh.c | 6 +- trunk/drivers/sh/intc/core.c | 23 +- trunk/drivers/sh/intc/virq.c | 12 +- .../staging/brcm80211/brcmfmac/bcmsdh_linux.c | 4 +- .../arch/arm/mach-omap2/cyashalomap_kernel.c | 2 +- .../astoria/block/cyasblkdev_block.c | 2 +- trunk/drivers/tty/hvc/hvc_xen.c | 2 +- trunk/drivers/tty/serial/msm_serial_hs.c | 4 +- trunk/drivers/usb/host/oxu210hp-hcd.c | 2 +- trunk/drivers/usb/musb/tusb6010.c | 2 +- trunk/drivers/vlynq/vlynq.c | 64 +- trunk/drivers/w1/masters/ds1wm.c | 4 +- trunk/drivers/watchdog/davinci_wdt.c | 22 +- trunk/drivers/watchdog/max63xx_wdt.c | 20 +- trunk/drivers/watchdog/nv_tco.c | 2 +- trunk/drivers/watchdog/pnx4008_wdt.c | 28 +- trunk/drivers/watchdog/s3c2410_wdt.c | 19 +- trunk/drivers/watchdog/softdog.c | 16 +- trunk/drivers/watchdog/sp5100_tco.c | 16 +- trunk/drivers/xen/events.c | 26 +- trunk/drivers/xen/gntdev.c | 6 +- trunk/fs/btrfs/btrfs_inode.h | 3 +- trunk/fs/btrfs/compression.c | 17 +- trunk/fs/btrfs/ctree.c | 159 +- trunk/fs/btrfs/ctree.h | 19 +- trunk/fs/btrfs/delayed-ref.c | 6 - trunk/fs/btrfs/dir-item.c | 45 +- trunk/fs/btrfs/disk-io.c | 132 +- trunk/fs/btrfs/extent-tree.c | 229 +- trunk/fs/btrfs/extent_io.c | 3 - trunk/fs/btrfs/extent_io.h | 1 - trunk/fs/btrfs/file-item.c | 5 +- trunk/fs/btrfs/file.c | 388 ++- trunk/fs/btrfs/free-space-cache.c | 510 ++- trunk/fs/btrfs/free-space-cache.h | 2 - trunk/fs/btrfs/inode-map.c | 3 +- trunk/fs/btrfs/inode.c | 366 +-- trunk/fs/btrfs/ioctl.c | 100 +- trunk/fs/btrfs/ordered-data.c | 8 - trunk/fs/btrfs/relocation.c | 8 +- trunk/fs/btrfs/root-tree.c | 6 +- trunk/fs/btrfs/super.c | 5 - trunk/fs/btrfs/transaction.c | 14 +- trunk/fs/btrfs/tree-log.c | 57 +- trunk/fs/btrfs/volumes.c | 164 +- trunk/fs/btrfs/volumes.h | 12 - trunk/fs/btrfs/xattr.c | 2 - trunk/fs/ceph/addr.c | 2 +- trunk/fs/ceph/snap.c | 4 +- trunk/fs/ecryptfs/crypto.c | 2 +- trunk/fs/ecryptfs/ecryptfs_kernel.h | 30 +- trunk/fs/ecryptfs/file.c | 9 +- trunk/fs/ecryptfs/inode.c | 24 + trunk/fs/ecryptfs/keystore.c | 272 +- trunk/fs/ecryptfs/main.c | 10 +- trunk/fs/ecryptfs/mmap.c | 61 +- trunk/fs/ecryptfs/read_write.c | 12 +- trunk/fs/ecryptfs/super.c | 3 +- trunk/fs/inode.c | 2 +- trunk/fs/jffs2/xattr.c | 2 +- trunk/fs/nfs/namespace.c | 4 +- trunk/fs/nfs/nfs4state.c | 3 +- trunk/fs/nfs/pagelist.c | 4 +- trunk/fs/nfs/write.c | 13 +- trunk/fs/ocfs2/acl.c | 1 + trunk/fs/ocfs2/alloc.c | 214 +- trunk/fs/ocfs2/aops.c | 82 +- trunk/fs/ocfs2/buffer_head_io.c | 49 +- trunk/fs/ocfs2/cluster/heartbeat.c | 3 + trunk/fs/ocfs2/cluster/masklog.c | 20 +- trunk/fs/ocfs2/cluster/masklog.h | 105 +- trunk/fs/ocfs2/cluster/tcp.c | 10 +- trunk/fs/ocfs2/dcache.c | 45 +- trunk/fs/ocfs2/dir.c | 121 +- trunk/fs/ocfs2/dlm/dlmconvert.c | 6 +- trunk/fs/ocfs2/dlm/dlmdomain.c | 36 +- trunk/fs/ocfs2/dlm/dlmlock.c | 10 +- trunk/fs/ocfs2/dlm/dlmmaster.c | 6 +- trunk/fs/ocfs2/dlm/dlmrecovery.c | 9 +- trunk/fs/ocfs2/dlm/dlmunlock.c | 4 +- trunk/fs/ocfs2/dlmglue.c | 246 +- trunk/fs/ocfs2/export.c | 47 +- trunk/fs/ocfs2/extent_map.c | 10 +- trunk/fs/ocfs2/file.c | 220 +- trunk/fs/ocfs2/heartbeat.c | 4 +- trunk/fs/ocfs2/inode.c | 134 +- trunk/fs/ocfs2/ioctl.c | 41 +- trunk/fs/ocfs2/journal.c | 168 +- trunk/fs/ocfs2/localalloc.c | 109 +- trunk/fs/ocfs2/locks.c | 1 + trunk/fs/ocfs2/mmap.c | 7 +- trunk/fs/ocfs2/namei.c | 175 +- trunk/fs/ocfs2/ocfs2.h | 23 +- trunk/fs/ocfs2/ocfs2_trace.h | 2739 ----------------- trunk/fs/ocfs2/quota_global.c | 45 +- trunk/fs/ocfs2/quota_local.c | 16 +- trunk/fs/ocfs2/refcounttree.c | 158 +- trunk/fs/ocfs2/reservations.c | 57 +- trunk/fs/ocfs2/resize.c | 23 +- trunk/fs/ocfs2/slot_map.c | 16 +- trunk/fs/ocfs2/suballoc.c | 189 +- trunk/fs/ocfs2/super.c | 89 +- trunk/fs/ocfs2/symlink.c | 14 +- trunk/fs/ocfs2/sysfile.c | 1 + trunk/fs/ocfs2/uptodate.c | 73 +- trunk/fs/ocfs2/xattr.c | 155 +- trunk/fs/proc/task_mmu.c | 3 +- trunk/fs/xfs/linux-2.6/xfs_buf.c | 344 ++- trunk/fs/xfs/linux-2.6/xfs_buf.h | 40 +- trunk/fs/xfs/linux-2.6/xfs_file.c | 6 +- trunk/fs/xfs/linux-2.6/xfs_ioctl.c | 4 - trunk/fs/xfs/linux-2.6/xfs_super.c | 36 +- trunk/fs/xfs/linux-2.6/xfs_sync.c | 30 +- trunk/fs/xfs/xfs_inode.c | 2 +- trunk/fs/xfs/xfs_inode_item.c | 6 +- trunk/fs/xfs/xfs_trans_buf.c | 3 +- trunk/fs/xfs/xfs_vnodeops.c | 3 +- trunk/fs/xfs/xfs_vnodeops.h | 1 - trunk/include/linux/bch.h | 79 - trunk/include/linux/can/core.h | 9 +- trunk/include/linux/drbd.h | 23 +- trunk/include/linux/drbd_limits.h | 12 +- trunk/include/linux/drbd_nl.h | 13 +- trunk/include/linux/drbd_tag_magic.h | 1 - trunk/include/linux/ethtool.h | 1 - trunk/include/linux/fs.h | 2 - trunk/include/linux/input.h | 7 - trunk/include/linux/irq.h | 180 +- trunk/include/linux/irqdesc.h | 60 +- trunk/include/linux/mfd/ab8500.h | 47 - trunk/include/linux/mfd/ab8500/gpio.h | 21 - trunk/include/linux/mfd/core.h | 27 +- trunk/include/linux/mfd/max8997-private.h | 21 - trunk/include/linux/mfd/max8997.h | 7 +- trunk/include/linux/mtd/blktrans.h | 3 - trunk/include/linux/mtd/cfi.h | 1 - trunk/include/linux/mtd/latch-addr-flash.h | 29 - trunk/include/linux/mtd/nand.h | 3 - trunk/include/linux/mtd/nand_bch.h | 72 - trunk/include/linux/mtd/onenand.h | 1 - trunk/include/linux/nfs_page.h | 1 + trunk/include/linux/regulator/ab8500.h | 51 +- trunk/include/linux/regulator/consumer.h | 2 - trunk/include/linux/regulator/driver.h | 11 +- trunk/include/linux/regulator/machine.h | 1 - trunk/include/linux/skbuff.h | 8 +- trunk/include/linux/sonypi.h | 1 - trunk/include/net/dst.h | 2 +- trunk/include/net/rose.h | 8 +- trunk/include/net/xfrm.h | 22 - trunk/include/sound/pcm.h | 4 +- trunk/include/trace/events/btrfs.h | 667 ---- trunk/ipc/util.c | 4 +- trunk/kernel/irq/Kconfig | 8 +- trunk/kernel/irq/autoprobe.c | 4 +- trunk/kernel/irq/chip.c | 283 +- trunk/kernel/irq/compat.h | 72 + trunk/kernel/irq/debug.h | 12 +- trunk/kernel/irq/dummychip.c | 9 + trunk/kernel/irq/handle.c | 19 +- trunk/kernel/irq/internals.h | 16 + trunk/kernel/irq/irqdesc.c | 3 +- trunk/kernel/irq/manage.c | 102 +- trunk/kernel/irq/migration.c | 15 +- trunk/kernel/irq/proc.c | 8 +- trunk/kernel/irq/resend.c | 1 + trunk/kernel/irq/settings.h | 55 +- trunk/kernel/irq/spurious.c | 11 +- trunk/kernel/signal.c | 4 +- trunk/lib/Kconfig | 39 - trunk/lib/Makefile | 1 - trunk/lib/bch.c | 1368 -------- trunk/mm/memory.c | 2 +- trunk/mm/percpu.c | 3 +- trunk/net/bridge/br_if.c | 6 +- trunk/net/bridge/br_private.h | 2 +- trunk/net/bridge/br_stp_if.c | 9 +- trunk/net/can/af_can.c | 9 +- trunk/net/can/bcm.c | 4 +- trunk/net/can/raw.c | 4 +- trunk/net/core/dev.c | 55 +- trunk/net/core/ethtool.c | 17 +- trunk/net/ipv4/fib_trie.c | 4 +- trunk/net/ipv4/ip_options.c | 6 +- trunk/net/ipv4/raw.c | 1 - trunk/net/ipv6/ip6mr.c | 2 +- trunk/net/irda/iriap.c | 6 - trunk/net/irda/irnet/irnet_ppp.c | 3 - trunk/net/rose/af_rose.c | 8 +- trunk/net/rose/rose_loopback.c | 13 +- trunk/net/rose/rose_route.c | 20 +- trunk/net/rose/rose_subr.c | 101 +- trunk/net/sunrpc/sched.c | 4 +- trunk/net/xfrm/xfrm_input.c | 4 +- trunk/net/xfrm/xfrm_output.c | 4 +- trunk/net/xfrm/xfrm_replay.c | 17 +- trunk/net/xfrm/xfrm_state.c | 6 - trunk/net/xfrm/xfrm_user.c | 24 - trunk/security/selinux/ss/services.c | 2 +- trunk/sound/core/init.c | 4 - trunk/sound/core/pcm_native.c | 9 + trunk/sound/oss/dev_table.h | 2 +- trunk/sound/oss/midi_synth.c | 30 +- trunk/sound/oss/midi_synth.h | 2 +- trunk/sound/oss/opl3.c | 23 +- trunk/sound/oss/sequencer.c | 2 +- trunk/sound/pci/asihpi/asihpi.c | 137 +- trunk/sound/pci/hda/patch_analog.c | 89 - trunk/sound/pci/hda/patch_realtek.c | 2 +- trunk/sound/usb/quirks-table.h | 40 - 798 files changed, 11750 insertions(+), 24273 deletions(-) delete mode 100644 trunk/Documentation/ABI/testing/sysfs-driver-samsung-laptop delete mode 100644 trunk/Documentation/ABI/testing/sysfs-platform-asus-wmi create mode 100644 trunk/Documentation/ABI/testing/sysfs-platform-eeepc-wmi create mode 100644 trunk/arch/cris/arch-v32/drivers/pcf8563.c delete mode 100644 trunk/drivers/gpio/ab8500-gpio.c delete mode 100644 trunk/drivers/mfd/max8997-irq.c delete mode 100644 trunk/drivers/mtd/maps/latch-addr-flash.c delete mode 100644 trunk/drivers/mtd/mtdswap.c delete mode 100644 trunk/drivers/mtd/nand/nand_bch.c delete mode 100644 trunk/drivers/platform/x86/asus-nb-wmi.c delete mode 100644 trunk/drivers/platform/x86/asus-wmi.c delete mode 100644 trunk/drivers/platform/x86/asus-wmi.h delete mode 100644 trunk/drivers/platform/x86/dell-wmi-aio.c delete mode 100644 trunk/drivers/platform/x86/intel_mid_powerbtn.c delete mode 100644 trunk/drivers/platform/x86/intel_mid_thermal.c delete mode 100644 trunk/drivers/platform/x86/samsung-laptop.c delete mode 100644 trunk/drivers/platform/x86/xo15-ebook.c delete mode 100644 trunk/fs/ocfs2/ocfs2_trace.h delete mode 100644 trunk/include/linux/bch.h delete mode 100644 trunk/include/linux/mfd/ab8500/gpio.h delete mode 100644 trunk/include/linux/mtd/latch-addr-flash.h delete mode 100644 trunk/include/linux/mtd/nand_bch.h delete mode 100644 trunk/include/trace/events/btrfs.h create mode 100644 trunk/kernel/irq/compat.h delete mode 100644 trunk/lib/bch.c diff --git a/[refs] b/[refs] index c0853192134a..e4c33115ff7b 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 90f1e7481eebfd47e7dbf7c8c0cbfe31e025e031 +refs/heads/master: eac522ef438f8ea173569fd0469371bc5d317947 diff --git a/trunk/Documentation/ABI/testing/sysfs-bus-pci-devices-cciss b/trunk/Documentation/ABI/testing/sysfs-bus-pci-devices-cciss index f5bb0a3bb8c0..4f29e5f1ebfa 100644 --- a/trunk/Documentation/ABI/testing/sysfs-bus-pci-devices-cciss +++ b/trunk/Documentation/ABI/testing/sysfs-bus-pci-devices-cciss @@ -59,15 +59,3 @@ Kernel Version: 2.6.31 Contact: iss_storagedev@hp.com Description: Displays the usage count (number of opens) of logical drive Y of controller X. - -Where: /sys/bus/pci/devices//ccissX/resettable -Date: February 2011 -Kernel Version: 2.6.38 -Contact: iss_storagedev@hp.com -Description: Value of 1 indicates the controller can honor the reset_devices - kernel parameter. Value of 0 indicates reset_devices cannot be - honored. This is to allow, for example, kexec tools to be able - to warn the user if they designate an unresettable device as - a dump device, as kdump requires resetting the device in order - to work reliably. - diff --git a/trunk/Documentation/ABI/testing/sysfs-driver-samsung-laptop b/trunk/Documentation/ABI/testing/sysfs-driver-samsung-laptop deleted file mode 100644 index 0a810231aad4..000000000000 --- a/trunk/Documentation/ABI/testing/sysfs-driver-samsung-laptop +++ /dev/null @@ -1,19 +0,0 @@ -What: /sys/devices/platform/samsung/performance_level -Date: January 1, 2010 -KernelVersion: 2.6.33 -Contact: Greg Kroah-Hartman -Description: Some Samsung laptops have different "performance levels" - that are can be modified by a function key, and by this - sysfs file. These values don't always make a whole lot - of sense, but some users like to modify them to keep - their fans quiet at all costs. Reading from this file - will show the current performance level. Writing to the - file can change this value. - Valid options: - "silent" - "normal" - "overclock" - Note that not all laptops support all of these options. - Specifically, not all support the "overclock" option, - and it's still unknown if this value even changes - anything, other than making the user feel a bit better. diff --git a/trunk/Documentation/ABI/testing/sysfs-platform-asus-wmi b/trunk/Documentation/ABI/testing/sysfs-platform-asus-wmi deleted file mode 100644 index 2e7df91620de..000000000000 --- a/trunk/Documentation/ABI/testing/sysfs-platform-asus-wmi +++ /dev/null @@ -1,31 +0,0 @@ -What: /sys/devices/platform//cpufv -Date: Oct 2010 -KernelVersion: 2.6.37 -Contact: "Corentin Chary" -Description: - Change CPU clock configuration (write-only). - There are three available clock configuration: - * 0 -> Super Performance Mode - * 1 -> High Performance Mode - * 2 -> Power Saving Mode - -What: /sys/devices/platform//camera -Date: Jan 2010 -KernelVersion: 2.6.39 -Contact: "Corentin Chary" -Description: - Control the camera. 1 means on, 0 means off. - -What: /sys/devices/platform//cardr -Date: Jan 2010 -KernelVersion: 2.6.39 -Contact: "Corentin Chary" -Description: - Control the card reader. 1 means on, 0 means off. - -What: /sys/devices/platform//touchpad -Date: Jan 2010 -KernelVersion: 2.6.39 -Contact: "Corentin Chary" -Description: - Control the card touchpad. 1 means on, 0 means off. diff --git a/trunk/Documentation/ABI/testing/sysfs-platform-eeepc-wmi b/trunk/Documentation/ABI/testing/sysfs-platform-eeepc-wmi new file mode 100644 index 000000000000..e4b5fef5fadd --- /dev/null +++ b/trunk/Documentation/ABI/testing/sysfs-platform-eeepc-wmi @@ -0,0 +1,10 @@ +What: /sys/devices/platform/eeepc-wmi/cpufv +Date: Oct 2010 +KernelVersion: 2.6.37 +Contact: "Corentin Chary" +Description: + Change CPU clock configuration (write-only). + There are three available clock configuration: + * 0 -> Super Performance Mode + * 1 -> High Performance Mode + * 2 -> Power Saving Mode diff --git a/trunk/Documentation/DocBook/Makefile b/trunk/Documentation/DocBook/Makefile index 8436b018c289..2deb069aedf1 100644 --- a/trunk/Documentation/DocBook/Makefile +++ b/trunk/Documentation/DocBook/Makefile @@ -55,6 +55,7 @@ mandocs: $(MAN) build_images = mkdir -p $(objtree)/Documentation/DocBook/media/ && \ cp $(srctree)/Documentation/DocBook/dvb/*.png \ $(srctree)/Documentation/DocBook/v4l/*.gif \ + $(srctree)/Documentation/DocBook/v4l/*.png \ $(objtree)/Documentation/DocBook/media/ xmldoclinks: diff --git a/trunk/Documentation/DocBook/rapidio.tmpl b/trunk/Documentation/DocBook/rapidio.tmpl index 50479360d845..54eb26b57372 100644 --- a/trunk/Documentation/DocBook/rapidio.tmpl +++ b/trunk/Documentation/DocBook/rapidio.tmpl @@ -133,6 +133,7 @@ !Idrivers/rapidio/rio-sysfs.c PPC32 support +!Earch/powerpc/sysdev/fsl_rio.c !Iarch/powerpc/sysdev/fsl_rio.c diff --git a/trunk/Documentation/development-process/1.Intro b/trunk/Documentation/development-process/1.Intro index 9b614480aa84..8cc2cba2b10d 100644 --- a/trunk/Documentation/development-process/1.Intro +++ b/trunk/Documentation/development-process/1.Intro @@ -56,13 +56,13 @@ information on kernel development. 1.2: WHAT THIS DOCUMENT IS ABOUT -The Linux kernel, at over 8 million lines of code and well over 1000 -contributors to each release, is one of the largest and most active free -software projects in existence. Since its humble beginning in 1991, this -kernel has evolved into a best-of-breed operating system component which -runs on pocket-sized digital music players, desktop PCs, the largest -supercomputers in existence, and all types of systems in between. It is a -robust, efficient, and scalable solution for almost any situation. +The Linux kernel, at over 6 million lines of code and well over 1000 active +contributors, is one of the largest and most active free software projects +in existence. Since its humble beginning in 1991, this kernel has evolved +into a best-of-breed operating system component which runs on pocket-sized +digital music players, desktop PCs, the largest supercomputers in +existence, and all types of systems in between. It is a robust, efficient, +and scalable solution for almost any situation. With the growth of Linux has come an increase in the number of developers (and companies) wishing to participate in its development. Hardware @@ -115,7 +115,7 @@ This document was written by Jonathan Corbet, corbet@lwn.net. It has been improved by comments from Johannes Berg, James Berry, Alex Chiang, Roland Dreier, Randy Dunlap, Jake Edge, Jiri Kosina, Matt Mackall, Arthur Marsh, Amanda McPherson, Andrew Morton, Andrew Price, Tsugikazu Shibata, and -Jochen Voß. +Jochen Voß. This work was supported by the Linux Foundation; thanks especially to Amanda McPherson, who saw the value of this effort and made it all happen. @@ -221,7 +221,7 @@ include: - Everything that was said above about code review applies doubly to closed-source code. Since this code is not available at all, it cannot have been reviewed by the community and will, beyond doubt, have serious - problems. + problems. Makers of embedded systems, in particular, may be tempted to disregard much of what has been said in this section in the belief that they are shipping diff --git a/trunk/Documentation/development-process/2.Process b/trunk/Documentation/development-process/2.Process index 4823577c6509..911a45186340 100644 --- a/trunk/Documentation/development-process/2.Process +++ b/trunk/Documentation/development-process/2.Process @@ -14,15 +14,16 @@ The kernel developers use a loosely time-based release process, with a new major kernel release happening every two or three months. The recent release history looks like this: - 2.6.38 March 14, 2011 - 2.6.37 January 4, 2011 - 2.6.36 October 20, 2010 - 2.6.35 August 1, 2010 - 2.6.34 May 15, 2010 - 2.6.33 February 24, 2010 + 2.6.26 July 13, 2008 + 2.6.25 April 16, 2008 + 2.6.24 January 24, 2008 + 2.6.23 October 9, 2007 + 2.6.22 July 8, 2007 + 2.6.21 April 25, 2007 + 2.6.20 February 4, 2007 Every 2.6.x release is a major kernel release with new features, internal -API changes, and more. A typical 2.6 release can contain nearly 10,000 +API changes, and more. A typical 2.6 release can contain over 10,000 changesets with changes to several hundred thousand lines of code. 2.6 is thus the leading edge of Linux kernel development; the kernel uses a rolling development model which is continually integrating major changes. @@ -41,13 +42,13 @@ merge window do not come out of thin air; they have been collected, tested, and staged ahead of time. How that process works will be described in detail later on). -The merge window lasts for approximately two weeks. At the end of this -time, Linus Torvalds will declare that the window is closed and release the -first of the "rc" kernels. For the kernel which is destined to be 2.6.40, -for example, the release which happens at the end of the merge window will -be called 2.6.40-rc1. The -rc1 release is the signal that the time to -merge new features has passed, and that the time to stabilize the next -kernel has begun. +The merge window lasts for two weeks. At the end of this time, Linus +Torvalds will declare that the window is closed and release the first of +the "rc" kernels. For the kernel which is destined to be 2.6.26, for +example, the release which happens at the end of the merge window will be +called 2.6.26-rc1. The -rc1 release is the signal that the time to merge +new features has passed, and that the time to stabilize the next kernel has +begun. Over the next six to ten weeks, only patches which fix problems should be submitted to the mainline. On occasion a more significant change will be @@ -65,19 +66,20 @@ will get up to somewhere between -rc6 and -rc9 before the kernel is considered to be sufficiently stable and the final 2.6.x release is made. At that point the whole process starts over again. -As an example, here is how the 2.6.38 development cycle went (all dates in -2011): - - January 4 2.6.37 stable release - January 18 2.6.38-rc1, merge window closes - January 21 2.6.38-rc2 - February 1 2.6.38-rc3 - February 7 2.6.38-rc4 - February 15 2.6.38-rc5 - February 21 2.6.38-rc6 - March 1 2.6.38-rc7 - March 7 2.6.38-rc8 - March 14 2.6.38 stable release +As an example, here is how the 2.6.25 development cycle went (all dates in +2008): + + January 24 2.6.24 stable release + February 10 2.6.25-rc1, merge window closes + February 15 2.6.25-rc2 + February 24 2.6.25-rc3 + March 4 2.6.25-rc4 + March 9 2.6.25-rc5 + March 16 2.6.25-rc6 + March 25 2.6.25-rc7 + April 1 2.6.25-rc8 + April 11 2.6.25-rc9 + April 16 2.6.25 stable release How do the developers decide when to close the development cycle and create the stable release? The most significant metric used is the list of @@ -85,7 +87,7 @@ regressions from previous releases. No bugs are welcome, but those which break systems which worked in the past are considered to be especially serious. For this reason, patches which cause regressions are looked upon unfavorably and are quite likely to be reverted during the stabilization -period. +period. The developers' goal is to fix all known regressions before the stable release is made. In the real world, this kind of perfection is hard to @@ -97,34 +99,26 @@ kernels go out with a handful of known regressions though, hopefully, none of them are serious. Once a stable release is made, its ongoing maintenance is passed off to the -"stable team," currently consisting of Greg Kroah-Hartman. The stable team -will release occasional updates to the stable release using the 2.6.x.y -numbering scheme. To be considered for an update release, a patch must (1) -fix a significant bug, and (2) already be merged into the mainline for the -next development kernel. Kernels will typically receive stable updates for -a little more than one development cycle past their initial release. So, -for example, the 2.6.36 kernel's history looked like: - - October 10 2.6.36 stable release - November 22 2.6.36.1 - December 9 2.6.36.2 - January 7 2.6.36.3 - February 17 2.6.36.4 - -2.6.36.4 was the final stable update for the 2.6.36 release. - -Some kernels are designated "long term" kernels; they will receive support -for a longer period. As of this writing, the current long term kernels -and their maintainers are: - - 2.6.27 Willy Tarreau (Deep-frozen stable kernel) - 2.6.32 Greg Kroah-Hartman - 2.6.35 Andi Kleen (Embedded flag kernel) - -The selection of a kernel for long-term support is purely a matter of a -maintainer having the need and the time to maintain that release. There -are no known plans for long-term support for any specific upcoming -release. +"stable team," currently comprised of Greg Kroah-Hartman and Chris Wright. +The stable team will release occasional updates to the stable release using +the 2.6.x.y numbering scheme. To be considered for an update release, a +patch must (1) fix a significant bug, and (2) already be merged into the +mainline for the next development kernel. Continuing our 2.6.25 example, +the history (as of this writing) is: + + May 1 2.6.25.1 + May 6 2.6.25.2 + May 9 2.6.25.3 + May 15 2.6.25.4 + June 7 2.6.25.5 + June 9 2.6.25.6 + June 16 2.6.25.7 + June 21 2.6.25.8 + June 24 2.6.25.9 + +Stable updates for a given kernel are made for approximately six months; +after that, the maintenance of stable releases is solely the responsibility +of the distributors which have shipped that particular kernel. 2.2: THE LIFECYCLE OF A PATCH @@ -136,7 +130,7 @@ each patch implements a change which is desirable to have in the mainline. This process can happen quickly for minor fixes, or, in the case of large and controversial changes, go on for years. Much developer frustration comes from a lack of understanding of this process or from attempts to -circumvent it. +circumvent it. In the hopes of reducing that frustration, this document will describe how a patch gets into the kernel. What follows below is an introduction which @@ -199,8 +193,8 @@ involved. 2.3: HOW PATCHES GET INTO THE KERNEL There is exactly one person who can merge patches into the mainline kernel -repository: Linus Torvalds. But, of the over 9,500 patches which went -into the 2.6.38 kernel, only 112 (around 1.3%) were directly chosen by Linus +repository: Linus Torvalds. But, of the over 12,000 patches which went +into the 2.6.25 kernel, only 250 (around 2%) were directly chosen by Linus himself. The kernel project has long since grown to a size where no single developer could possibly inspect and select every patch unassisted. The way the kernel developers have addressed this growth is through the use of @@ -235,7 +229,7 @@ first in trees dedicated to network device drivers, wireless networking, etc. This chain of repositories can be arbitrarily long, though it rarely exceeds two or three links. Since each maintainer in the chain trusts those managing lower-level trees, this process is known as the "chain of -trust." +trust." Clearly, in a system like this, getting patches into the kernel depends on finding the right maintainer. Sending patches directly to Linus is not @@ -260,7 +254,7 @@ The answer comes in the form of -next trees, where subsystem trees are collected for testing and review. The older of these trees, maintained by Andrew Morton, is called "-mm" (for memory management, which is how it got started). The -mm tree integrates patches from a long list of subsystem -trees; it also has some patches aimed at helping with debugging. +trees; it also has some patches aimed at helping with debugging. Beyond that, -mm contains a significant collection of patches which have been selected by Andrew directly. These patches may have been posted on a @@ -270,8 +264,8 @@ subsystem tree of last resort; if there is no other obvious path for a patch into the mainline, it is likely to end up in -mm. Miscellaneous patches which accumulate in -mm will eventually either be forwarded on to an appropriate subsystem tree or be sent directly to Linus. In a typical -development cycle, approximately 5-10% of the patches going into the -mainline get there via -mm. +development cycle, approximately 10% of the patches going into the mainline +get there via -mm. The current -mm patch is available in the "mmotm" (-mm of the moment) directory at: @@ -281,7 +275,7 @@ directory at: Use of the MMOTM tree is likely to be a frustrating experience, though; there is a definite chance that it will not even compile. -The primary tree for next-cycle patch merging is linux-next, maintained by +The other -next tree, started more recently, is linux-next, maintained by Stephen Rothwell. The linux-next tree is, by design, a snapshot of what the mainline is expected to look like after the next merge window closes. Linux-next trees are announced on the linux-kernel and linux-next mailing @@ -293,14 +287,25 @@ Some information about linux-next has been gathered at: http://linux.f-seidel.de/linux-next/pmwiki/ -Linux-next has become an integral part of the kernel development process; -all patches merged during a given merge window should really have found -their way into linux-next some time before the merge window opens. - +How the linux-next tree will fit into the development process is still +changing. As of this writing, the first full development cycle involving +linux-next (2.6.26) is coming to an end; thus far, it has proved to be a +valuable resource for finding and fixing integration problems before the +beginning of the merge window. See http://lwn.net/Articles/287155/ for +more information on how linux-next has worked to set up the 2.6.27 merge +window. + +Some developers have begun to suggest that linux-next should be used as the +target for future development as well. The linux-next tree does tend to be +far ahead of the mainline and is more representative of the tree into which +any new work will be merged. The downside to this idea is that the +volatility of linux-next tends to make it a difficult development target. +See http://lwn.net/Articles/289013/ for more information on this topic, and +stay tuned; much is still in flux where linux-next is involved. 2.4.1: STAGING TREES -The kernel source tree contains the drivers/staging/ directory, where +The kernel source tree now contains the drivers/staging/ directory, where many sub-directories for drivers or filesystems that are on their way to being added to the kernel tree live. They remain in drivers/staging while they still need more work; once complete, they can be moved into the @@ -308,23 +313,15 @@ kernel proper. This is a way to keep track of drivers that aren't up to Linux kernel coding or quality standards, but people may want to use them and track development. -Greg Kroah-Hartman currently maintains the staging tree. Drivers that -still need work are sent to him, with each driver having its own -subdirectory in drivers/staging/. Along with the driver source files, a -TODO file should be present in the directory as well. The TODO file lists -the pending work that the driver needs for acceptance into the kernel -proper, as well as a list of people that should be Cc'd for any patches to -the driver. Current rules require that drivers contributed to staging -must, at a minimum, compile properly. - -Staging can be a relatively easy way to get new drivers into the mainline -where, with luck, they will come to the attention of other developers and -improve quickly. Entry into staging is not the end of the story, though; -code in staging which is not seeing regular progress will eventually be -removed. Distributors also tend to be relatively reluctant to enable -staging drivers. So staging is, at best, a stop on the way toward becoming -a proper mainline driver. - +Greg Kroah-Hartman currently (as of 2.6.36) maintains the staging tree. +Drivers that still need work are sent to him, with each driver having +its own subdirectory in drivers/staging/. Along with the driver source +files, a TODO file should be present in the directory as well. The TODO +file lists the pending work that the driver needs for acceptance into +the kernel proper, as well as a list of people that should be Cc'd for any +patches to the driver. Staging drivers that don't currently build should +have their config entries depend upon CONFIG_BROKEN. Once they can +be successfully built without outside patches, CONFIG_BROKEN can be removed. 2.5: TOOLS @@ -350,7 +347,11 @@ page at: http://git-scm.com/ -That page has pointers to documentation and tutorials. +That page has pointers to documentation and tutorials. One should be +aware, in particular, of the Kernel Hacker's Guide to git, which has +information specific to kernel development: + + http://linux.yyz.us/git-howto.html Among the kernel developers who do not use git, the most popular choice is almost certainly Mercurial: @@ -407,7 +408,7 @@ There are a few hints which can help with linux-kernel survival: important to filter on both the topic of interest (though note that long-running conversations can drift away from the original subject without changing the email subject line) and the people who are - participating. + participating. - Do not feed the trolls. If somebody is trying to stir up an angry response, ignore them. diff --git a/trunk/Documentation/development-process/3.Early-stage b/trunk/Documentation/development-process/3.Early-stage index f87ba7b3fbac..307a159a70ca 100644 --- a/trunk/Documentation/development-process/3.Early-stage +++ b/trunk/Documentation/development-process/3.Early-stage @@ -110,8 +110,8 @@ the kernel community's standards. Some examples include: - The AppArmor security module made use of internal virtual filesystem data structures in ways which were considered to be unsafe and - unreliable. This concern (among others) kept AppArmor out of the - mainline for years. + unreliable. This code has since been significantly reworked, but + remains outside of the mainline. In each of these cases, a great deal of pain and extra work could have been avoided with some early discussion with the kernel developers. @@ -138,19 +138,6 @@ patches, and who, if anybody, is attaching Signed-off-by lines to those patches. Those are the people who will be best placed to help with a new development project. -The task of finding the right maintainer is sometimes challenging enough -that the kernel developers have added a script to ease the process: - - .../scripts/get_maintainer.pl - -This script will return the current maintainer(s) for a given file or -directory when given the "-f" option. If passed a patch on the -command line, it will list the maintainers who should probably receive -copies of the patch. There are a number of options regulating how hard -get_maintainer.pl will search for maintainers; please be careful about -using the more aggressive options as you may end up including developers -who have no real interest in the code you are modifying. - If all else fails, talking to Andrew Morton can be an effective way to track down a maintainer for a specific piece of code. @@ -168,15 +155,11 @@ reaction, but, instead, little or no reaction at all. The sad truth of the matter is (1) kernel developers tend to be busy, (2) there is no shortage of people with grand plans and little code (or even prospect of code) to back them up, and (3) nobody is obligated to review or comment on ideas -posted by others. Beyond that, high-level designs often hide problems -which are only reviewed when somebody actually tries to implement those -designs; for that reason, kernel developers would rather see the code. - -If a request-for-comments posting yields little in the way of comments, do -not assume that it means there is no interest in the project. -Unfortunately, you also cannot assume that there are no problems with your -idea. The best thing to do in this situation is to proceed, keeping the -community informed as you go. +posted by others. If a request-for-comments posting yields little in the +way of comments, do not assume that it means there is no interest in the +project. Unfortunately, you also cannot assume that there are no problems +with your idea. The best thing to do in this situation is to proceed, +keeping the community informed as you go. 3.5: GETTING OFFICIAL BUY-IN diff --git a/trunk/Documentation/development-process/4.Coding b/trunk/Documentation/development-process/4.Coding index f3f1a469443c..2278693c8ffa 100644 --- a/trunk/Documentation/development-process/4.Coding +++ b/trunk/Documentation/development-process/4.Coding @@ -131,11 +131,6 @@ classic time/space tradeoff taught in beginning data structures classes often does not apply to contemporary hardware. Space *is* time, in that a larger program will run slower than one which is more compact. -More recent compilers take an increasingly active role in deciding whether -a given function should actually be inlined or not. So the liberal -placement of "inline" keywords may not just be excessive; it could also be -irrelevant. - * Locking @@ -290,13 +285,6 @@ be found at https://sparse.wiki.kernel.org/index.php/Main_Page if your distributor does not package it); it can then be run on the code by adding "C=1" to your make command. -The "Coccinelle" tool (http://coccinelle.lip6.fr/) is able to find a wide -variety of potential coding problems; it can also propose fixes for those -problems. Quite a few "semantic patches" for the kernel have been packaged -under the scripts/coccinelle directory; running "make coccicheck" will run -through those semantic patches and report on any problems found. See -Documentation/coccinelle.txt for more information. - Other kinds of portability errors are best found by compiling your code for other architectures. If you do not happen to have an S/390 system or a Blackfin development board handy, you can still perform the compilation @@ -320,9 +308,7 @@ The first piece of documentation for any patch is its associated changelog. Log entries should describe the problem being solved, the form of the solution, the people who worked on the patch, any relevant effects on performance, and anything else that might be needed to -understand the patch. Be sure that the changelog says *why* the patch is -worth applying; a surprising number of developers fail to provide that -information. +understand the patch. Any code which adds a new user-space interface - including new sysfs or /proc files - should include documentation of that interface which enables @@ -335,7 +321,7 @@ boot-time parameters. Any patch which adds new parameters should add the appropriate entries to this file. Any new configuration options must be accompanied by help text which -clearly explains the options and when the user might want to select them. +clearly explains the options and when the user might want to select them. Internal API information for many subsystems is documented by way of specially-formatted comments; these comments can be extracted and formatted @@ -386,8 +372,7 @@ which is broken by the change. For a widely-used function, this duty can lead to literally hundreds or thousands of changes - many of which are likely to conflict with work being done by other developers. Needless to say, this can be a large job, so it is best to be sure that the -justification is solid. Note that the Coccinelle tool can help with -wide-ranging API changes. +justification is solid. When making an incompatible API change, one should, whenever possible, ensure that code which has not been updated is caught by the compiler. diff --git a/trunk/Documentation/development-process/5.Posting b/trunk/Documentation/development-process/5.Posting index 903a2546f138..f622c1e9f0f9 100644 --- a/trunk/Documentation/development-process/5.Posting +++ b/trunk/Documentation/development-process/5.Posting @@ -60,15 +60,12 @@ even in the short term. Patches must be prepared against a specific version of the kernel. As a general rule, a patch should be based on the current mainline as found in -Linus's git tree. When basing on mainline, start with a well-known release -point - a stable or -rc release - rather than branching off the mainline at -an arbitrary spot. - -It may become necessary to make versions against -mm, linux-next, or a -subsystem tree, though, to facilitate wider testing and review. Depending -on the area of your patch and what is going on elsewhere, basing a patch -against these other trees can require a significant amount of work -resolving conflicts and dealing with API changes. +Linus's git tree. It may become necessary to make versions against -mm, +linux-next, or a subsystem tree, though, to facilitate wider testing and +review. Depending on the area of your patch and what is going on +elsewhere, basing a patch against these other trees can require a +significant amount of work resolving conflicts and dealing with API +changes. Only the most simple changes should be formatted as a single patch; everything else should be made as a logical series of changes. Splitting @@ -103,11 +100,11 @@ rules of thumb, however, which can help considerably: result is a broken kernel, you will make life harder for developers and users who are engaging in the noble work of tracking down problems. - - Do not overdo it, though. One developer once posted a set of edits + - Do not overdo it, though. One developer recently posted a set of edits to a single file as 500 separate patches - an act which did not make him the most popular person on the kernel mailing list. A single patch can be reasonably large as long as it still contains a single *logical* - change. + change. - It can be tempting to add a whole new infrastructure with a series of patches, but to leave that infrastructure unused until the final patch @@ -165,8 +162,7 @@ To that end, the summary line should describe the effects of and motivation for the change as well as possible given the one-line constraint. The detailed description can then amplify on those topics and provide any needed additional information. If the patch fixes a bug, cite the commit -which introduced the bug if possible (and please provide both the commit ID -and the title when citing commits). If a problem is associated with +which introduced the bug if possible. If a problem is associated with specific log or compiler output, include that output to help others searching for a solution to the same problem. If the change is meant to support other changes coming in later patch, say so. If internal APIs are @@ -234,7 +230,7 @@ take care of: which have had gratuitous white-space changes or line wrapping performed by the mail client will not apply at the other end, and often will not be examined in any detail. If there is any doubt at all, mail the patch - to yourself and convince yourself that it shows up intact. + to yourself and convince yourself that it shows up intact. Documentation/email-clients.txt has some helpful hints on making specific mail clients work for sending patches. @@ -291,7 +287,7 @@ something like: where "nn" is the ordinal number of the patch, "mm" is the total number of patches in the series, and "subsys" is the name of the affected subsystem. -Clearly, nn/mm can be omitted for a single, standalone patch. +Clearly, nn/mm can be omitted for a single, standalone patch. If you have a significant series of patches, it is customary to send an introductory description as part zero. This convention is not universally @@ -303,5 +299,5 @@ In general, the second and following parts of a multi-part patch should be sent as a reply to the first part so that they all thread together at the receiving end. Tools like git and quilt have commands to mail out a set of patches with the proper threading. If you have a long series, though, and -are using git, please stay away from the --chain-reply-to option to avoid +are using git, please provide the --no-chain-reply-to option to avoid creating exceptionally deep nesting. diff --git a/trunk/Documentation/development-process/6.Followthrough b/trunk/Documentation/development-process/6.Followthrough index 41d324a9420d..a8fba3d83a85 100644 --- a/trunk/Documentation/development-process/6.Followthrough +++ b/trunk/Documentation/development-process/6.Followthrough @@ -66,11 +66,6 @@ be easy to become blinded by your own solution to a problem to the point that you don't realize that something is fundamentally wrong or, perhaps, you're not even solving the right problem. -Andrew Morton has suggested that every review comment which does not result -in a code change should result in an additional code comment instead; that -can help future reviewers avoid the questions which came up the first time -around. - One fatal mistake is to ignore review comments in the hope that they will go away. They will not go away. If you repost code without having responded to the comments you got the time before, you're likely to find @@ -105,7 +100,7 @@ entry into a subsystem maintainer's tree. How that works varies from one subsystem to the next; each maintainer has his or her own way of doing things. In particular, there may be more than one tree - one, perhaps, dedicated to patches planned for the next merge window, and another for -longer-term work. +longer-term work. For patches applying to areas for which there is no obvious subsystem tree (memory management patches, for example), the default tree often ends up @@ -114,10 +109,11 @@ through the -mm tree. Inclusion into a subsystem tree can bring a higher level of visibility to a patch. Now other developers working with that tree will get the patch by -default. Subsystem trees typically feed linux-next as well, making their -contents visible to the development community as a whole. At this point, -there's a good chance that you will get more comments from a new set of -reviewers; these comments need to be answered as in the previous round. +default. Subsystem trees typically feed into -mm and linux-next as well, +making their contents visible to the development community as a whole. At +this point, there's a good chance that you will get more comments from a +new set of reviewers; these comments need to be answered as in the previous +round. What may also happen at this point, depending on the nature of your patch, is that conflicts with work being done by others turn up. In the worst diff --git a/trunk/Documentation/development-process/7.AdvancedTopics b/trunk/Documentation/development-process/7.AdvancedTopics index 26dc3fa196e4..837179447e17 100644 --- a/trunk/Documentation/development-process/7.AdvancedTopics +++ b/trunk/Documentation/development-process/7.AdvancedTopics @@ -119,7 +119,7 @@ can affect your ability to get trees pulled in the future. Quoting Linus: to trust things *without* then having to go and check every individual change by hand. -(http://lwn.net/Articles/224135/). +(http://lwn.net/Articles/224135/). To avoid this kind of situation, ensure that all patches within a given branch stick closely to the associated topic; a "driver fixes" branch @@ -138,7 +138,7 @@ When requesting a pull, be sure to give all the relevant information: where your tree is, what branch to pull, and what changes will result from the pull. The git request-pull command can be helpful in this regard; it will format the request as other developers expect, and will also check to be -sure that you have remembered to push those changes to the public server. +sure that you have remembered to push those changes to the public server. 7.2: REVIEWING PATCHES diff --git a/trunk/Documentation/dynamic-debug-howto.txt b/trunk/Documentation/dynamic-debug-howto.txt index f959909d7154..e6c4b757025b 100644 --- a/trunk/Documentation/dynamic-debug-howto.txt +++ b/trunk/Documentation/dynamic-debug-howto.txt @@ -6,7 +6,7 @@ This document describes how to use the dynamic debug (ddebug) feature. Dynamic debug is designed to allow you to dynamically enable/disable kernel code to obtain additional kernel information. Currently, if -CONFIG_DYNAMIC_DEBUG is set, then all pr_debug()/dev_dbg() calls can be +CONFIG_DYNAMIC_DEBUG is set, then all pr_debug()/dev_debug() calls can be dynamically enabled per-callsite. Dynamic debug has even more useful features: @@ -26,7 +26,7 @@ Dynamic debug has even more useful features: Controlling dynamic debug Behaviour =================================== -The behaviour of pr_debug()/dev_dbg()s are controlled via writing to a +The behaviour of pr_debug()/dev_debug()s are controlled via writing to a control file in the 'debugfs' filesystem. Thus, you must first mount the debugfs filesystem, in order to make use of this feature. Subsequently, we refer to the control file as: /dynamic_debug/control. For example, if you want to diff --git a/trunk/Documentation/hwmon/f71882fg b/trunk/Documentation/hwmon/f71882fg index df02245d1419..4d0bc70f1852 100644 --- a/trunk/Documentation/hwmon/f71882fg +++ b/trunk/Documentation/hwmon/f71882fg @@ -2,10 +2,6 @@ Kernel driver f71882fg ====================== Supported chips: - * Fintek F71808E - Prefix: 'f71808e' - Addresses scanned: none, address read from Super I/O config space - Datasheet: Not public * Fintek F71858FG Prefix: 'f71858fg' Addresses scanned: none, address read from Super I/O config space @@ -30,25 +26,10 @@ Supported chips: Prefix: 'f71889ed' Addresses scanned: none, address read from Super I/O config space Datasheet: Should become available on the Fintek website soon - * Fintek F71889A - Prefix: 'f71889a' - Addresses scanned: none, address read from Super I/O config space - Datasheet: Should become available on the Fintek website soon * Fintek F8000 Prefix: 'f8000' Addresses scanned: none, address read from Super I/O config space Datasheet: Not public - * Fintek F81801U - Prefix: 'f71889fg' - Addresses scanned: none, address read from Super I/O config space - Datasheet: Not public - Note: This is the 64-pin variant of the F71889FG, they have the - same device ID and are fully compatible as far as hardware - monitoring is concerned. - * Fintek F81865F - Prefix: 'f81865f' - Addresses scanned: none, address read from Super I/O config space - Datasheet: Available from the Fintek website Author: Hans de Goede diff --git a/trunk/Documentation/laptops/sony-laptop.txt b/trunk/Documentation/laptops/sony-laptop.txt index 2bd4e82e5d9f..23ce7d350d1a 100644 --- a/trunk/Documentation/laptops/sony-laptop.txt +++ b/trunk/Documentation/laptops/sony-laptop.txt @@ -14,8 +14,7 @@ Some models report hotkeys through the SNC or SPIC devices, such events are reported both through the ACPI subsystem as acpi events and through the INPUT subsystem. See the logs of acpid or /proc/acpi/event and /proc/bus/input/devices to find out what those events are and which input -devices are created by the driver. Additionally, loading the driver with the -debug option will report all events in the kernel log. +devices are created by the driver. Backlight control: ------------------ @@ -65,16 +64,6 @@ powers off the sound card, # echo "1" > /sys/devices/platform/sony-laptop/audiopower powers on the sound card. - -RFkill control: ---------------- -More recent Vaio models expose a consistent set of ACPI methods to -control radio frequency emitting devices. If you are a lucky owner of -such a laptop you will find the necessary rfkill devices under -/sys/class/rfkill. Check those starting with sony-* in - # grep . /sys/class/rfkill/*/{state,name} - - Development: ------------ @@ -86,21 +75,8 @@ pass the option 'debug=1'. REPEAT: DON'T DO THIS IF YOU DON'T LIKE RISKY BUSINESS. In your kernel logs you will find the list of all ACPI methods -the SNC device has on your laptop. - -* For new models you will see a long list of meaningless method names, -reading the DSDT table source should reveal that: -(1) the SNC device uses an internal capability lookup table -(2) SN00 is used to find values in the lookup table -(3) SN06 and SN07 are used to call into the real methods based on - offsets you can obtain iterating the table using SN00 -(4) SN02 used to enable events. -Some values in the capability lookup table are more or less known, see -the code for all sony_call_snc_handle calls, others are more obscure. - -* For old models you can see the GCDP/GCDP methods used to pwer on/off -the CD drive, but there are others and they are usually different from -model to model. +the SNC device has on your laptop. You can see the GCDP/GCDP methods +used to pwer on/off the CD drive, but there are others. I HAVE NO IDEA WHAT THOSE METHODS DO. @@ -132,8 +108,9 @@ Bugs/Limitations: laptop, including permanent damage. * The sony-laptop and sonypi drivers do not interact at all. In the - future, sonypi will be removed and replaced by sony-laptop. + future, sonypi could use sony-laptop to do (part of) its business. * spicctrl, which is the userspace tool used to communicate with the - sonypi driver (through /dev/sonypi) is deprecated as well since all - its features are now available under the sysfs tree via sony-laptop. + sonypi driver (through /dev/sonypi) does not try to use the + sony-laptop driver. In the future, spicctrl could try sonypi first, + and if it isn't present, try sony-laptop instead. diff --git a/trunk/MAINTAINERS b/trunk/MAINTAINERS index 6b4b9cdec370..4fb9017b4413 100644 --- a/trunk/MAINTAINERS +++ b/trunk/MAINTAINERS @@ -548,8 +548,10 @@ S: Maintained F: sound/aoa/ APM DRIVER +M: Stephen Rothwell L: linux-laptop@vger.kernel.org -S: Orphan +W: http://www.canb.auug.org.au/~sfr/ +S: Supported F: arch/x86/kernel/apm_32.c F: include/linux/apm_bios.h @@ -1157,14 +1159,14 @@ S: Maintained F: Documentation/hwmon/asc7621 F: drivers/hwmon/asc7621.c -ASUS NOTEBOOKS AND EEEPC ACPI/WMI EXTRAS DRIVERS +ASUS ACPI EXTRAS DRIVER M: Corentin Chary +M: Karol Kozimor L: acpi4asus-user@lists.sourceforge.net L: platform-driver-x86@vger.kernel.org W: http://acpi4asus.sf.net S: Maintained -F: drivers/platform/x86/asus*.c -F: drivers/platform/x86/eeepc*.c +F: drivers/platform/x86/asus_acpi.c ASUS ASB100 HARDWARE MONITOR DRIVER M: "Mark M. Hoffman" @@ -1172,6 +1174,14 @@ L: lm-sensors@lm-sensors.org S: Maintained F: drivers/hwmon/asb100.c +ASUS LAPTOP EXTRAS DRIVER +M: Corentin Chary +L: acpi4asus-user@lists.sourceforge.net +L: platform-driver-x86@vger.kernel.org +W: http://acpi4asus.sf.net +S: Maintained +F: drivers/platform/x86/asus-laptop.c + ASYNCHRONOUS TRANSFERS/TRANSFORMS (IOAT) API M: Dan Williams W: http://sourceforge.net/projects/xscaleiop @@ -2406,6 +2416,22 @@ T: git git://git.alsa-project.org/alsa-kernel.git S: Maintained F: sound/usb/misc/ua101.c +EEEPC LAPTOP EXTRAS DRIVER +M: Corentin Chary +L: acpi4asus-user@lists.sourceforge.net +L: platform-driver-x86@vger.kernel.org +W: http://acpi4asus.sf.net +S: Maintained +F: drivers/platform/x86/eeepc-laptop.c + +EEEPC WMI EXTRAS DRIVER +M: Corentin Chary +L: acpi4asus-user@lists.sourceforge.net +L: platform-driver-x86@vger.kernel.org +W: http://acpi4asus.sf.net +S: Maintained +F: drivers/platform/x86/eeepc-wmi.c + EFIFB FRAMEBUFFER DRIVER L: linux-fbdev@vger.kernel.org M: Peter Jones @@ -6607,7 +6633,6 @@ F: drivers/media/video/zr364xx.c USER-MODE LINUX (UML) M: Jeff Dike -M: Richard Weinberger L: user-mode-linux-devel@lists.sourceforge.net L: user-mode-linux-user@lists.sourceforge.net W: http://user-mode-linux.sourceforge.net diff --git a/trunk/arch/alpha/Kconfig b/trunk/arch/alpha/Kconfig index bd4160c57196..cc31bec2e316 100644 --- a/trunk/arch/alpha/Kconfig +++ b/trunk/arch/alpha/Kconfig @@ -11,7 +11,6 @@ config ALPHA select HAVE_GENERIC_HARDIRQS select GENERIC_IRQ_PROBE select AUTO_IRQ_AFFINITY if SMP - select GENERIC_IRQ_SHOW select GENERIC_HARDIRQS_NO_DEPRECATED help The Alpha is a 64-bit general-purpose processor designed and diff --git a/trunk/arch/alpha/kernel/irq.c b/trunk/arch/alpha/kernel/irq.c index 381431a2d6d9..a19d60082299 100644 --- a/trunk/arch/alpha/kernel/irq.c +++ b/trunk/arch/alpha/kernel/irq.c @@ -67,21 +67,68 @@ int irq_select_affinity(unsigned int irq) } #endif /* CONFIG_SMP */ -int arch_show_interrupts(struct seq_file *p, int prec) +int +show_interrupts(struct seq_file *p, void *v) { int j; + int irq = *(loff_t *) v; + struct irqaction * action; + struct irq_desc *desc; + unsigned long flags; #ifdef CONFIG_SMP - seq_puts(p, "IPI: "); - for_each_online_cpu(j) - seq_printf(p, "%10lu ", cpu_data[j].ipi_count); - seq_putc(p, '\n'); + if (irq == 0) { + seq_puts(p, " "); + for_each_online_cpu(j) + seq_printf(p, "CPU%d ", j); + seq_putc(p, '\n'); + } +#endif + + if (irq < ACTUAL_NR_IRQS) { + desc = irq_to_desc(irq); + + if (!desc) + return 0; + + raw_spin_lock_irqsave(&desc->lock, flags); + action = desc->action; + if (!action) + goto unlock; + seq_printf(p, "%3d: ", irq); +#ifndef CONFIG_SMP + seq_printf(p, "%10u ", kstat_irqs(irq)); +#else + for_each_online_cpu(j) + seq_printf(p, "%10u ", kstat_irqs_cpu(irq, j)); #endif - seq_puts(p, "PMI: "); - for_each_online_cpu(j) - seq_printf(p, "%10lu ", per_cpu(irq_pmi_count, j)); - seq_puts(p, " Performance Monitoring\n"); - seq_printf(p, "ERR: %10lu\n", irq_err_count); + seq_printf(p, " %14s", get_irq_desc_chip(desc)->name); + seq_printf(p, " %c%s", + (action->flags & IRQF_DISABLED)?'+':' ', + action->name); + + for (action=action->next; action; action = action->next) { + seq_printf(p, ", %c%s", + (action->flags & IRQF_DISABLED)?'+':' ', + action->name); + } + + seq_putc(p, '\n'); +unlock: + raw_spin_unlock_irqrestore(&desc->lock, flags); + } else if (irq == ACTUAL_NR_IRQS) { +#ifdef CONFIG_SMP + seq_puts(p, "IPI: "); + for_each_online_cpu(j) + seq_printf(p, "%10lu ", cpu_data[j].ipi_count); + seq_putc(p, '\n'); +#endif + seq_puts(p, "PMI: "); + for_each_online_cpu(j) + seq_printf(p, "%10lu ", per_cpu(irq_pmi_count, j)); + seq_puts(p, " Performance Monitoring\n"); + seq_printf(p, "ERR: %10lu\n", irq_err_count); + } return 0; } diff --git a/trunk/arch/alpha/kernel/irq_alpha.c b/trunk/arch/alpha/kernel/irq_alpha.c index 1479dc6ebd97..411ca11d0a18 100644 --- a/trunk/arch/alpha/kernel/irq_alpha.c +++ b/trunk/arch/alpha/kernel/irq_alpha.c @@ -228,7 +228,7 @@ struct irqaction timer_irqaction = { void __init init_rtc_irq(void) { - irq_set_chip_and_handler_name(RTC_IRQ, &no_irq_chip, + set_irq_chip_and_handler_name(RTC_IRQ, &no_irq_chip, handle_simple_irq, "RTC"); setup_irq(RTC_IRQ, &timer_irqaction); } diff --git a/trunk/arch/alpha/kernel/irq_i8259.c b/trunk/arch/alpha/kernel/irq_i8259.c index e1861c77dabc..c7cc9813e45f 100644 --- a/trunk/arch/alpha/kernel/irq_i8259.c +++ b/trunk/arch/alpha/kernel/irq_i8259.c @@ -92,7 +92,7 @@ init_i8259a_irqs(void) outb(0xff, 0xA1); /* mask all of 8259A-2 */ for (i = 0; i < 16; i++) { - irq_set_chip_and_handler(i, &i8259a_irq_type, handle_level_irq); + set_irq_chip_and_handler(i, &i8259a_irq_type, handle_level_irq); } setup_irq(2, &cascade); diff --git a/trunk/arch/alpha/kernel/irq_pyxis.c b/trunk/arch/alpha/kernel/irq_pyxis.c index 13c97a5b31e8..b30227fa7f5f 100644 --- a/trunk/arch/alpha/kernel/irq_pyxis.c +++ b/trunk/arch/alpha/kernel/irq_pyxis.c @@ -102,7 +102,7 @@ init_pyxis_irqs(unsigned long ignore_mask) for (i = 16; i < 48; ++i) { if ((ignore_mask >> i) & 1) continue; - irq_set_chip_and_handler(i, &pyxis_irq_type, handle_level_irq); + set_irq_chip_and_handler(i, &pyxis_irq_type, handle_level_irq); irq_set_status_flags(i, IRQ_LEVEL); } diff --git a/trunk/arch/alpha/kernel/irq_srm.c b/trunk/arch/alpha/kernel/irq_srm.c index a79fa30e7552..82a47bba41c4 100644 --- a/trunk/arch/alpha/kernel/irq_srm.c +++ b/trunk/arch/alpha/kernel/irq_srm.c @@ -51,7 +51,7 @@ init_srm_irqs(long max, unsigned long ignore_mask) for (i = 16; i < max; ++i) { if (i < 64 && ((ignore_mask >> i) & 1)) continue; - irq_set_chip_and_handler(i, &srm_irq_type, handle_level_irq); + set_irq_chip_and_handler(i, &srm_irq_type, handle_level_irq); irq_set_status_flags(i, IRQ_LEVEL); } } diff --git a/trunk/arch/alpha/kernel/sys_alcor.c b/trunk/arch/alpha/kernel/sys_alcor.c index 0e1439904cdb..88d95e872f55 100644 --- a/trunk/arch/alpha/kernel/sys_alcor.c +++ b/trunk/arch/alpha/kernel/sys_alcor.c @@ -125,7 +125,7 @@ alcor_init_irq(void) on while IRQ probing. */ if (i >= 16+20 && i <= 16+30) continue; - irq_set_chip_and_handler(i, &alcor_irq_type, handle_level_irq); + set_irq_chip_and_handler(i, &alcor_irq_type, handle_level_irq); irq_set_status_flags(i, IRQ_LEVEL); } i8259a_irq_type.irq_ack = alcor_isa_mask_and_ack_irq; diff --git a/trunk/arch/alpha/kernel/sys_cabriolet.c b/trunk/arch/alpha/kernel/sys_cabriolet.c index c8c112d51584..57eb6307bc27 100644 --- a/trunk/arch/alpha/kernel/sys_cabriolet.c +++ b/trunk/arch/alpha/kernel/sys_cabriolet.c @@ -105,8 +105,8 @@ common_init_irq(void (*srm_dev_int)(unsigned long v)) outb(0xff, 0x806); for (i = 16; i < 35; ++i) { - irq_set_chip_and_handler(i, &cabriolet_irq_type, - handle_level_irq); + set_irq_chip_and_handler(i, &cabriolet_irq_type, + handle_level_irq); irq_set_status_flags(i, IRQ_LEVEL); } } diff --git a/trunk/arch/alpha/kernel/sys_dp264.c b/trunk/arch/alpha/kernel/sys_dp264.c index 5ac00fd4cd0c..481df4ecb651 100644 --- a/trunk/arch/alpha/kernel/sys_dp264.c +++ b/trunk/arch/alpha/kernel/sys_dp264.c @@ -270,7 +270,7 @@ init_tsunami_irqs(struct irq_chip * ops, int imin, int imax) { long i; for (i = imin; i <= imax; ++i) { - irq_set_chip_and_handler(i, ops, handle_level_irq); + set_irq_chip_and_handler(i, ops, handle_level_irq); irq_set_status_flags(i, IRQ_LEVEL); } } diff --git a/trunk/arch/alpha/kernel/sys_eb64p.c b/trunk/arch/alpha/kernel/sys_eb64p.c index a7a23b40eec5..402e908ffb3e 100644 --- a/trunk/arch/alpha/kernel/sys_eb64p.c +++ b/trunk/arch/alpha/kernel/sys_eb64p.c @@ -118,7 +118,7 @@ eb64p_init_irq(void) init_i8259a_irqs(); for (i = 16; i < 32; ++i) { - irq_set_chip_and_handler(i, &eb64p_irq_type, handle_level_irq); + set_irq_chip_and_handler(i, &eb64p_irq_type, handle_level_irq); irq_set_status_flags(i, IRQ_LEVEL); } diff --git a/trunk/arch/alpha/kernel/sys_eiger.c b/trunk/arch/alpha/kernel/sys_eiger.c index a60cd5b2621e..0b44a54c1522 100644 --- a/trunk/arch/alpha/kernel/sys_eiger.c +++ b/trunk/arch/alpha/kernel/sys_eiger.c @@ -138,7 +138,7 @@ eiger_init_irq(void) init_i8259a_irqs(); for (i = 16; i < 128; ++i) { - irq_set_chip_and_handler(i, &eiger_irq_type, handle_level_irq); + set_irq_chip_and_handler(i, &eiger_irq_type, handle_level_irq); irq_set_status_flags(i, IRQ_LEVEL); } } diff --git a/trunk/arch/alpha/kernel/sys_jensen.c b/trunk/arch/alpha/kernel/sys_jensen.c index 7f1a87f176e2..00341b75c8b2 100644 --- a/trunk/arch/alpha/kernel/sys_jensen.c +++ b/trunk/arch/alpha/kernel/sys_jensen.c @@ -171,11 +171,11 @@ jensen_init_irq(void) { init_i8259a_irqs(); - irq_set_chip_and_handler(1, &jensen_local_irq_type, handle_level_irq); - irq_set_chip_and_handler(4, &jensen_local_irq_type, handle_level_irq); - irq_set_chip_and_handler(3, &jensen_local_irq_type, handle_level_irq); - irq_set_chip_and_handler(7, &jensen_local_irq_type, handle_level_irq); - irq_set_chip_and_handler(9, &jensen_local_irq_type, handle_level_irq); + set_irq_chip_and_handler(1, &jensen_local_irq_type, handle_level_irq); + set_irq_chip_and_handler(4, &jensen_local_irq_type, handle_level_irq); + set_irq_chip_and_handler(3, &jensen_local_irq_type, handle_level_irq); + set_irq_chip_and_handler(7, &jensen_local_irq_type, handle_level_irq); + set_irq_chip_and_handler(9, &jensen_local_irq_type, handle_level_irq); common_init_isa_dma(); } diff --git a/trunk/arch/alpha/kernel/sys_marvel.c b/trunk/arch/alpha/kernel/sys_marvel.c index 388b99d1779d..e61910734e41 100644 --- a/trunk/arch/alpha/kernel/sys_marvel.c +++ b/trunk/arch/alpha/kernel/sys_marvel.c @@ -276,7 +276,7 @@ init_io7_irqs(struct io7 *io7, /* Set up the lsi irqs. */ for (i = 0; i < 128; ++i) { - irq_set_chip_and_handler(base + i, lsi_ops, handle_level_irq); + set_irq_chip_and_handler(base + i, lsi_ops, handle_level_irq); irq_set_status_flags(i, IRQ_LEVEL); } @@ -290,7 +290,7 @@ init_io7_irqs(struct io7 *io7, /* Set up the msi irqs. */ for (i = 128; i < (128 + 512); ++i) { - irq_set_chip_and_handler(base + i, msi_ops, handle_level_irq); + set_irq_chip_and_handler(base + i, msi_ops, handle_level_irq); irq_set_status_flags(i, IRQ_LEVEL); } @@ -308,8 +308,8 @@ marvel_init_irq(void) /* Reserve the legacy irqs. */ for (i = 0; i < 16; ++i) { - irq_set_chip_and_handler(i, &marvel_legacy_irq_type, - handle_level_irq); + set_irq_chip_and_handler(i, &marvel_legacy_irq_type, + handle_level_irq); } /* Init the io7 irqs. */ diff --git a/trunk/arch/alpha/kernel/sys_mikasa.c b/trunk/arch/alpha/kernel/sys_mikasa.c index 0e6e4697a025..cf7f43dd3147 100644 --- a/trunk/arch/alpha/kernel/sys_mikasa.c +++ b/trunk/arch/alpha/kernel/sys_mikasa.c @@ -98,8 +98,7 @@ mikasa_init_irq(void) mikasa_update_irq_hw(0); for (i = 16; i < 32; ++i) { - irq_set_chip_and_handler(i, &mikasa_irq_type, - handle_level_irq); + set_irq_chip_and_handler(i, &mikasa_irq_type, handle_level_irq); irq_set_status_flags(i, IRQ_LEVEL); } diff --git a/trunk/arch/alpha/kernel/sys_noritake.c b/trunk/arch/alpha/kernel/sys_noritake.c index a00ac7087167..92bc188e94a9 100644 --- a/trunk/arch/alpha/kernel/sys_noritake.c +++ b/trunk/arch/alpha/kernel/sys_noritake.c @@ -127,8 +127,7 @@ noritake_init_irq(void) outw(0, 0x54c); for (i = 16; i < 48; ++i) { - irq_set_chip_and_handler(i, &noritake_irq_type, - handle_level_irq); + set_irq_chip_and_handler(i, &noritake_irq_type, handle_level_irq); irq_set_status_flags(i, IRQ_LEVEL); } diff --git a/trunk/arch/alpha/kernel/sys_rawhide.c b/trunk/arch/alpha/kernel/sys_rawhide.c index 7f52161f3d88..936d4140ed5f 100644 --- a/trunk/arch/alpha/kernel/sys_rawhide.c +++ b/trunk/arch/alpha/kernel/sys_rawhide.c @@ -180,8 +180,7 @@ rawhide_init_irq(void) } for (i = 16; i < 128; ++i) { - irq_set_chip_and_handler(i, &rawhide_irq_type, - handle_level_irq); + set_irq_chip_and_handler(i, &rawhide_irq_type, handle_level_irq); irq_set_status_flags(i, IRQ_LEVEL); } diff --git a/trunk/arch/alpha/kernel/sys_rx164.c b/trunk/arch/alpha/kernel/sys_rx164.c index 216d94d9c0c1..cea22a62913b 100644 --- a/trunk/arch/alpha/kernel/sys_rx164.c +++ b/trunk/arch/alpha/kernel/sys_rx164.c @@ -99,7 +99,7 @@ rx164_init_irq(void) rx164_update_irq_hw(0); for (i = 16; i < 40; ++i) { - irq_set_chip_and_handler(i, &rx164_irq_type, handle_level_irq); + set_irq_chip_and_handler(i, &rx164_irq_type, handle_level_irq); irq_set_status_flags(i, IRQ_LEVEL); } diff --git a/trunk/arch/alpha/kernel/sys_sable.c b/trunk/arch/alpha/kernel/sys_sable.c index da714e427c5f..a349538aabc9 100644 --- a/trunk/arch/alpha/kernel/sys_sable.c +++ b/trunk/arch/alpha/kernel/sys_sable.c @@ -518,8 +518,8 @@ sable_lynx_init_irq(int nr_of_irqs) long i; for (i = 0; i < nr_of_irqs; ++i) { - irq_set_chip_and_handler(i, &sable_lynx_irq_type, - handle_level_irq); + set_irq_chip_and_handler(i, &sable_lynx_irq_type, + handle_level_irq); irq_set_status_flags(i, IRQ_LEVEL); } diff --git a/trunk/arch/alpha/kernel/sys_takara.c b/trunk/arch/alpha/kernel/sys_takara.c index a31f8cd9bd6b..42a5331f13c4 100644 --- a/trunk/arch/alpha/kernel/sys_takara.c +++ b/trunk/arch/alpha/kernel/sys_takara.c @@ -138,8 +138,7 @@ takara_init_irq(void) takara_update_irq_hw(i, -1); for (i = 16; i < 128; ++i) { - irq_set_chip_and_handler(i, &takara_irq_type, - handle_level_irq); + set_irq_chip_and_handler(i, &takara_irq_type, handle_level_irq); irq_set_status_flags(i, IRQ_LEVEL); } diff --git a/trunk/arch/alpha/kernel/sys_titan.c b/trunk/arch/alpha/kernel/sys_titan.c index fea0e4620994..8c13a0c77830 100644 --- a/trunk/arch/alpha/kernel/sys_titan.c +++ b/trunk/arch/alpha/kernel/sys_titan.c @@ -179,7 +179,7 @@ init_titan_irqs(struct irq_chip * ops, int imin, int imax) { long i; for (i = imin; i <= imax; ++i) { - irq_set_chip_and_handler(i, ops, handle_level_irq); + set_irq_chip_and_handler(i, ops, handle_level_irq); irq_set_status_flags(i, IRQ_LEVEL); } } diff --git a/trunk/arch/alpha/kernel/sys_wildfire.c b/trunk/arch/alpha/kernel/sys_wildfire.c index d3cb28bb8eb0..ca60a387ef0a 100644 --- a/trunk/arch/alpha/kernel/sys_wildfire.c +++ b/trunk/arch/alpha/kernel/sys_wildfire.c @@ -183,17 +183,17 @@ wildfire_init_irq_per_pca(int qbbno, int pcano) for (i = 0; i < 16; ++i) { if (i == 2) continue; - irq_set_chip_and_handler(i + irq_bias, &wildfire_irq_type, - handle_level_irq); + set_irq_chip_and_handler(i+irq_bias, &wildfire_irq_type, + handle_level_irq); irq_set_status_flags(i + irq_bias, IRQ_LEVEL); } - irq_set_chip_and_handler(36 + irq_bias, &wildfire_irq_type, - handle_level_irq); + set_irq_chip_and_handler(36+irq_bias, &wildfire_irq_type, + handle_level_irq); irq_set_status_flags(36 + irq_bias, IRQ_LEVEL); for (i = 40; i < 64; ++i) { - irq_set_chip_and_handler(i + irq_bias, &wildfire_irq_type, - handle_level_irq); + set_irq_chip_and_handler(i+irq_bias, &wildfire_irq_type, + handle_level_irq); irq_set_status_flags(i + irq_bias, IRQ_LEVEL); } diff --git a/trunk/arch/arm/Kconfig b/trunk/arch/arm/Kconfig index 7c0effb69fc7..93d595a7477a 100644 --- a/trunk/arch/arm/Kconfig +++ b/trunk/arch/arm/Kconfig @@ -28,7 +28,6 @@ config ARM select HAVE_C_RECORDMCOUNT select HAVE_GENERIC_HARDIRQS select HAVE_SPARSE_IRQ - select GENERIC_IRQ_SHOW help The ARM series is a line of low-power-consumption RISC chip designs licensed by ARM Ltd and targeted at embedded applications and @@ -2010,7 +2009,6 @@ menu "Power management options" source "kernel/power/Kconfig" config ARCH_SUSPEND_POSSIBLE - depends on !ARCH_S5P64X0 && !ARCH_S5P6442 def_bool y endmenu diff --git a/trunk/arch/arm/common/gic.c b/trunk/arch/arm/common/gic.c index f70ec7dadebb..cb6b041c39d2 100644 --- a/trunk/arch/arm/common/gic.c +++ b/trunk/arch/arm/common/gic.c @@ -213,8 +213,8 @@ static int gic_set_wake(struct irq_data *d, unsigned int on) static void gic_handle_cascade_irq(unsigned int irq, struct irq_desc *desc) { - struct gic_chip_data *chip_data = irq_get_handler_data(irq); - struct irq_chip *chip = irq_get_chip(irq); + struct gic_chip_data *chip_data = get_irq_data(irq); + struct irq_chip *chip = get_irq_chip(irq); unsigned int cascade_irq, gic_irq; unsigned long status; @@ -257,9 +257,9 @@ void __init gic_cascade_irq(unsigned int gic_nr, unsigned int irq) { if (gic_nr >= MAX_GIC_NR) BUG(); - if (irq_set_handler_data(irq, &gic_data[gic_nr]) != 0) + if (set_irq_data(irq, &gic_data[gic_nr]) != 0) BUG(); - irq_set_chained_handler(irq, gic_handle_cascade_irq); + set_irq_chained_handler(irq, gic_handle_cascade_irq); } static void __init gic_dist_init(struct gic_chip_data *gic, @@ -319,8 +319,9 @@ static void __init gic_dist_init(struct gic_chip_data *gic, * Setup the Linux IRQ subsystem. */ for (i = irq_start; i < irq_limit; i++) { - irq_set_chip_and_handler(i, &gic_chip, handle_level_irq); - irq_set_chip_data(i, gic); + set_irq_chip(i, &gic_chip); + set_irq_chip_data(i, gic); + set_irq_handler(i, handle_level_irq); set_irq_flags(i, IRQF_VALID | IRQF_PROBE); } @@ -381,7 +382,7 @@ void __cpuinit gic_enable_ppi(unsigned int irq) unsigned long flags; local_irq_save(flags); - irq_set_status_flags(irq, IRQ_NOPROBE); + irq_to_desc(irq)->status |= IRQ_NOPROBE; gic_unmask_irq(irq_get_irq_data(irq)); local_irq_restore(flags); } diff --git a/trunk/arch/arm/common/it8152.c b/trunk/arch/arm/common/it8152.c index 7a21927c52e1..fcddd48fe9da 100644 --- a/trunk/arch/arm/common/it8152.c +++ b/trunk/arch/arm/common/it8152.c @@ -88,8 +88,8 @@ void it8152_init_irq(void) __raw_writel((0), IT8152_INTC_LDCNIRR); for (irq = IT8152_IRQ(0); irq <= IT8152_LAST_IRQ; irq++) { - irq_set_chip_and_handler(irq, &it8152_irq_chip, - handle_level_irq); + set_irq_chip(irq, &it8152_irq_chip); + set_irq_handler(irq, handle_level_irq); set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); } } diff --git a/trunk/arch/arm/common/locomo.c b/trunk/arch/arm/common/locomo.c index b55c3625d7ee..a026a6bf4892 100644 --- a/trunk/arch/arm/common/locomo.c +++ b/trunk/arch/arm/common/locomo.c @@ -140,7 +140,7 @@ static struct locomo_dev_info locomo_devices[] = { static void locomo_handler(unsigned int irq, struct irq_desc *desc) { - struct locomo *lchip = irq_get_chip_data(irq); + struct locomo *lchip = get_irq_chip_data(irq); int req, i; /* Acknowledge the parent IRQ */ @@ -197,14 +197,15 @@ static void locomo_setup_irq(struct locomo *lchip) /* * Install handler for IRQ_LOCOMO_HW. */ - irq_set_irq_type(lchip->irq, IRQ_TYPE_EDGE_FALLING); - irq_set_chip_data(lchip->irq, lchip); - irq_set_chained_handler(lchip->irq, locomo_handler); + set_irq_type(lchip->irq, IRQ_TYPE_EDGE_FALLING); + set_irq_chip_data(lchip->irq, lchip); + set_irq_chained_handler(lchip->irq, locomo_handler); /* Install handlers for IRQ_LOCOMO_* */ for ( ; irq <= lchip->irq_base + 3; irq++) { - irq_set_chip_and_handler(irq, &locomo_chip, handle_level_irq); - irq_set_chip_data(irq, lchip); + set_irq_chip(irq, &locomo_chip); + set_irq_chip_data(irq, lchip); + set_irq_handler(irq, handle_level_irq); set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); } } @@ -475,8 +476,8 @@ static void __locomo_remove(struct locomo *lchip) device_for_each_child(lchip->dev, NULL, locomo_remove_child); if (lchip->irq != NO_IRQ) { - irq_set_chained_handler(lchip->irq, NULL); - irq_set_handler_data(lchip->irq, NULL); + set_irq_chained_handler(lchip->irq, NULL); + set_irq_data(lchip->irq, NULL); } iounmap(lchip->base); diff --git a/trunk/arch/arm/common/sa1111.c b/trunk/arch/arm/common/sa1111.c index a12b33c0dc42..eb9796b0dab2 100644 --- a/trunk/arch/arm/common/sa1111.c +++ b/trunk/arch/arm/common/sa1111.c @@ -202,7 +202,7 @@ static void sa1111_irq_handler(unsigned int irq, struct irq_desc *desc) { unsigned int stat0, stat1, i; - struct sa1111 *sachip = irq_get_handler_data(irq); + struct sa1111 *sachip = get_irq_data(irq); void __iomem *mapbase = sachip->base + SA1111_INTC; stat0 = sa1111_readl(mapbase + SA1111_INTSTATCLR0); @@ -472,25 +472,25 @@ static void sa1111_setup_irq(struct sa1111 *sachip) sa1111_writel(~0, irqbase + SA1111_INTSTATCLR1); for (irq = IRQ_GPAIN0; irq <= SSPROR; irq++) { - irq_set_chip_and_handler(irq, &sa1111_low_chip, - handle_edge_irq); - irq_set_chip_data(irq, sachip); + set_irq_chip(irq, &sa1111_low_chip); + set_irq_chip_data(irq, sachip); + set_irq_handler(irq, handle_edge_irq); set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); } for (irq = AUDXMTDMADONEA; irq <= IRQ_S1_BVD1_STSCHG; irq++) { - irq_set_chip_and_handler(irq, &sa1111_high_chip, - handle_edge_irq); - irq_set_chip_data(irq, sachip); + set_irq_chip(irq, &sa1111_high_chip); + set_irq_chip_data(irq, sachip); + set_irq_handler(irq, handle_edge_irq); set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); } /* * Register SA1111 interrupt */ - irq_set_irq_type(sachip->irq, IRQ_TYPE_EDGE_RISING); - irq_set_handler_data(sachip->irq, sachip); - irq_set_chained_handler(sachip->irq, sa1111_irq_handler); + set_irq_type(sachip->irq, IRQ_TYPE_EDGE_RISING); + set_irq_data(sachip->irq, sachip); + set_irq_chained_handler(sachip->irq, sa1111_irq_handler); } /* @@ -815,8 +815,8 @@ static void __sa1111_remove(struct sa1111 *sachip) clk_disable(sachip->clk); if (sachip->irq != NO_IRQ) { - irq_set_chained_handler(sachip->irq, NULL); - irq_set_handler_data(sachip->irq, NULL); + set_irq_chained_handler(sachip->irq, NULL); + set_irq_data(sachip->irq, NULL); release_mem_region(sachip->phys + SA1111_INTC, 512); } diff --git a/trunk/arch/arm/common/vic.c b/trunk/arch/arm/common/vic.c index 113085a77123..ae5fe7292e0d 100644 --- a/trunk/arch/arm/common/vic.c +++ b/trunk/arch/arm/common/vic.c @@ -305,9 +305,9 @@ static void __init vic_set_irq_sources(void __iomem *base, if (vic_sources & (1 << i)) { unsigned int irq = irq_start + i; - irq_set_chip_and_handler(irq, &vic_chip, - handle_level_irq); - irq_set_chip_data(irq, base); + set_irq_chip(irq, &vic_chip); + set_irq_chip_data(irq, base); + set_irq_handler(irq, handle_level_irq); set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); } } diff --git a/trunk/arch/arm/include/asm/hw_irq.h b/trunk/arch/arm/include/asm/hw_irq.h index a71b417b1856..5586b7c8ef6f 100644 --- a/trunk/arch/arm/include/asm/hw_irq.h +++ b/trunk/arch/arm/include/asm/hw_irq.h @@ -10,6 +10,14 @@ static inline void ack_bad_irq(int irq) irq_err_count++; } +/* + * Obsolete inline function for calling irq descriptor handlers. + */ +static inline void desc_handle_irq(unsigned int irq, struct irq_desc *desc) +{ + desc->handle_irq(irq, desc); +} + void set_irq_flags(unsigned int irq, unsigned int flags); #define IRQF_VALID (1 << 0) diff --git a/trunk/arch/arm/kernel/bios32.c b/trunk/arch/arm/kernel/bios32.c index e4ee050aad7d..d86fcd44b220 100644 --- a/trunk/arch/arm/kernel/bios32.c +++ b/trunk/arch/arm/kernel/bios32.c @@ -158,6 +158,31 @@ static void __devinit pci_fixup_dec21285(struct pci_dev *dev) } DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_21285, pci_fixup_dec21285); +/* + * Same as above. The PrPMC800 carrier board for the PrPMC1100 + * card maps the host-bridge @ 00:01:00 for some reason and it + * ends up getting scanned. Note that we only want to do this + * fixup when we find the IXP4xx on a PrPMC system, which is why + * we check the machine type. We could be running on a board + * with an IXP4xx target device and we don't want to kill the + * resources in that case. + */ +static void __devinit pci_fixup_prpmc1100(struct pci_dev *dev) +{ + int i; + + if (machine_is_prpmc1100()) { + dev->class &= 0xff; + dev->class |= PCI_CLASS_BRIDGE_HOST << 8; + for (i = 0; i < PCI_NUM_RESOURCES; i++) { + dev->resource[i].start = 0; + dev->resource[i].end = 0; + dev->resource[i].flags = 0; + } + } +} +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IXP4XX, pci_fixup_prpmc1100); + /* * PCI IDE controllers use non-standard I/O port decoding, respect it. */ diff --git a/trunk/arch/arm/kernel/ecard.c b/trunk/arch/arm/kernel/ecard.c index d16500110ee9..2ad62df37730 100644 --- a/trunk/arch/arm/kernel/ecard.c +++ b/trunk/arch/arm/kernel/ecard.c @@ -1043,8 +1043,8 @@ ecard_probe(int slot, card_type_t type) */ if (slot < 8) { ec->irq = 32 + slot; - irq_set_chip_and_handler(ec->irq, &ecard_chip, - handle_level_irq); + set_irq_chip(ec->irq, &ecard_chip); + set_irq_handler(ec->irq, handle_level_irq); set_irq_flags(ec->irq, IRQF_VALID); } @@ -1103,7 +1103,7 @@ static int __init ecard_init(void) irqhw = ecard_probeirqhw(); - irq_set_chained_handler(IRQ_EXPANSIONCARD, + set_irq_chained_handler(IRQ_EXPANSIONCARD, irqhw ? ecard_irqexp_handler : ecard_irq_handler); ecard_proc_init(); diff --git a/trunk/arch/arm/kernel/irq.c b/trunk/arch/arm/kernel/irq.c index 83bbad03fcc6..3535d3793e65 100644 --- a/trunk/arch/arm/kernel/irq.c +++ b/trunk/arch/arm/kernel/irq.c @@ -51,18 +51,63 @@ unsigned long irq_err_count; -int arch_show_interrupts(struct seq_file *p, int prec) +int show_interrupts(struct seq_file *p, void *v) { + int i = *(loff_t *) v, cpu; + struct irq_desc *desc; + struct irqaction * action; + unsigned long flags; + int prec, n; + + for (prec = 3, n = 1000; prec < 10 && n <= nr_irqs; prec++) + n *= 10; + +#ifdef CONFIG_SMP + if (prec < 4) + prec = 4; +#endif + + if (i == 0) { + char cpuname[12]; + + seq_printf(p, "%*s ", prec, ""); + for_each_present_cpu(cpu) { + sprintf(cpuname, "CPU%d", cpu); + seq_printf(p, " %10s", cpuname); + } + seq_putc(p, '\n'); + } + + if (i < nr_irqs) { + desc = irq_to_desc(i); + raw_spin_lock_irqsave(&desc->lock, flags); + action = desc->action; + if (!action) + goto unlock; + + seq_printf(p, "%*d: ", prec, i); + for_each_present_cpu(cpu) + seq_printf(p, "%10u ", kstat_irqs_cpu(i, cpu)); + seq_printf(p, " %10s", desc->irq_data.chip->name ? : "-"); + seq_printf(p, " %s", action->name); + for (action = action->next; action; action = action->next) + seq_printf(p, ", %s", action->name); + + seq_putc(p, '\n'); +unlock: + raw_spin_unlock_irqrestore(&desc->lock, flags); + } else if (i == nr_irqs) { #ifdef CONFIG_FIQ - show_fiq_list(p, prec); + show_fiq_list(p, prec); #endif #ifdef CONFIG_SMP - show_ipi_list(p, prec); + show_ipi_list(p, prec); #endif #ifdef CONFIG_LOCAL_TIMERS - show_local_irqs(p, prec); + show_local_irqs(p, prec); #endif - seq_printf(p, "%*s: %10lu\n", prec, "Err", irq_err_count); + seq_printf(p, "%*s: %10lu\n", prec, "Err", irq_err_count); + } return 0; } @@ -99,21 +144,24 @@ asm_do_IRQ(unsigned int irq, struct pt_regs *regs) void set_irq_flags(unsigned int irq, unsigned int iflags) { - unsigned long clr = 0, set = IRQ_NOREQUEST | IRQ_NOPROBE | IRQ_NOAUTOEN; + struct irq_desc *desc; + unsigned long flags; if (irq >= nr_irqs) { printk(KERN_ERR "Trying to set irq flags for IRQ%d\n", irq); return; } + desc = irq_to_desc(irq); + raw_spin_lock_irqsave(&desc->lock, flags); + desc->status |= IRQ_NOREQUEST | IRQ_NOPROBE | IRQ_NOAUTOEN; if (iflags & IRQF_VALID) - clr |= IRQ_NOREQUEST; + desc->status &= ~IRQ_NOREQUEST; if (iflags & IRQF_PROBE) - clr |= IRQ_NOPROBE; + desc->status &= ~IRQ_NOPROBE; if (!(iflags & IRQF_NOAUTOEN)) - clr |= IRQ_NOAUTOEN; - /* Order is clear bits in "clr" then set bits in "set" */ - irq_modify_status(irq, clr, set & ~clr); + desc->status &= ~IRQ_NOAUTOEN; + raw_spin_unlock_irqrestore(&desc->lock, flags); } void __init init_IRQ(void) diff --git a/trunk/arch/arm/mach-at91/at91cap9_devices.c b/trunk/arch/arm/mach-at91/at91cap9_devices.c index 9ffbf3a2dfea..d1f775e86353 100644 --- a/trunk/arch/arm/mach-at91/at91cap9_devices.c +++ b/trunk/arch/arm/mach-at91/at91cap9_devices.c @@ -72,7 +72,7 @@ void __init at91_add_device_usbh(struct at91_usbh_data *data) return; if (cpu_is_at91cap9_revB()) - irq_set_irq_type(AT91CAP9_ID_UHP, IRQ_TYPE_LEVEL_HIGH); + set_irq_type(AT91CAP9_ID_UHP, IRQ_TYPE_LEVEL_HIGH); /* Enable VBus control for UHP ports */ for (i = 0; i < data->ports; i++) { @@ -157,7 +157,7 @@ static struct platform_device at91_usba_udc_device = { void __init at91_add_device_usba(struct usba_platform_data *data) { if (cpu_is_at91cap9_revB()) { - irq_set_irq_type(AT91CAP9_ID_UDPHS, IRQ_TYPE_LEVEL_HIGH); + set_irq_type(AT91CAP9_ID_UDPHS, IRQ_TYPE_LEVEL_HIGH); at91_sys_write(AT91_MATRIX_UDPHS, AT91_MATRIX_SELECT_UDPHS | AT91_MATRIX_UDPHS_BYPASS_LOCK); } @@ -861,7 +861,7 @@ void __init at91_add_device_lcdc(struct atmel_lcdfb_info *data) return; if (cpu_is_at91cap9_revB()) - irq_set_irq_type(AT91CAP9_ID_LCDC, IRQ_TYPE_LEVEL_HIGH); + set_irq_type(AT91CAP9_ID_LCDC, IRQ_TYPE_LEVEL_HIGH); at91_set_A_periph(AT91_PIN_PC1, 0); /* LCDHSYNC */ at91_set_A_periph(AT91_PIN_PC2, 0); /* LCDDOTCK */ diff --git a/trunk/arch/arm/mach-at91/gpio.c b/trunk/arch/arm/mach-at91/gpio.c index 4615528205c8..af818a21587c 100644 --- a/trunk/arch/arm/mach-at91/gpio.c +++ b/trunk/arch/arm/mach-at91/gpio.c @@ -287,7 +287,7 @@ static int gpio_irq_set_wake(struct irq_data *d, unsigned state) else wakeups[bank] &= ~mask; - irq_set_irq_wake(gpio_chip[bank].bank->id, state); + set_irq_wake(gpio_chip[bank].bank->id, state); return 0; } @@ -375,7 +375,6 @@ static int gpio_irq_type(struct irq_data *d, unsigned type) static struct irq_chip gpio_irqchip = { .name = "GPIO", - .irq_disable = gpio_irq_mask, .irq_mask = gpio_irq_mask, .irq_unmask = gpio_irq_unmask, .irq_set_type = gpio_irq_type, @@ -385,14 +384,16 @@ static struct irq_chip gpio_irqchip = { static void gpio_irq_handler(unsigned irq, struct irq_desc *desc) { unsigned pin; - struct irq_data *idata = irq_desc_get_irq_data(desc); - struct irq_chip *chip = irq_data_get_irq_chip(idata); - struct at91_gpio_chip *at91_gpio = irq_data_get_irq_chip_data(idata); - void __iomem *pio = at91_gpio->regbase; + struct irq_desc *gpio; + struct at91_gpio_chip *at91_gpio; + void __iomem *pio; u32 isr; + at91_gpio = get_irq_chip_data(irq); + pio = at91_gpio->regbase; + /* temporarily mask (level sensitive) parent IRQ */ - chip->irq_ack(idata); + desc->irq_data.chip->irq_ack(&desc->irq_data); for (;;) { /* Reading ISR acks pending (edge triggered) GPIO interrupts. * When there none are pending, we're finished unless we need @@ -408,15 +409,27 @@ static void gpio_irq_handler(unsigned irq, struct irq_desc *desc) } pin = at91_gpio->chip.base; + gpio = &irq_desc[pin]; while (isr) { - if (isr & 1) - generic_handle_irq(pin); + if (isr & 1) { + if (unlikely(gpio->depth)) { + /* + * The core ARM interrupt handler lazily disables IRQs so + * another IRQ must be generated before it actually gets + * here to be disabled on the GPIO controller. + */ + gpio_irq_mask(irq_get_irq_data(pin)); + } + else + generic_handle_irq(pin); + } pin++; + gpio++; isr >>= 1; } } - chip->irq_unmask(idata); + desc->irq_data.chip->irq_unmask(&desc->irq_data); /* now it may re-trigger */ } @@ -505,14 +518,14 @@ void __init at91_gpio_irq_setup(void) __raw_writel(~0, this->regbase + PIO_IDR); for (i = 0, pin = this->chip.base; i < 32; i++, pin++) { - irq_set_lockdep_class(pin, &gpio_lock_class); + lockdep_set_class(&irq_desc[pin].lock, &gpio_lock_class); /* * Can use the "simple" and not "edge" handler since it's * shorter, and the AIC handles interrupts sanely. */ - irq_set_chip_and_handler(pin, &gpio_irqchip, - handle_simple_irq); + set_irq_chip(pin, &gpio_irqchip); + set_irq_handler(pin, handle_simple_irq); set_irq_flags(pin, IRQF_VALID); } @@ -523,8 +536,8 @@ void __init at91_gpio_irq_setup(void) if (prev && prev->next == this) continue; - irq_set_chip_data(id, this); - irq_set_chained_handler(id, gpio_irq_handler); + set_irq_chip_data(id, this); + set_irq_chained_handler(id, gpio_irq_handler); } pr_info("AT91: %d gpio irqs in %d banks\n", pin - PIN_BASE, gpio_banks); } diff --git a/trunk/arch/arm/mach-at91/include/mach/at572d940hf.h b/trunk/arch/arm/mach-at91/include/mach/at572d940hf.h index be510cfc56be..2d9b0af9c4d5 100644 --- a/trunk/arch/arm/mach-at91/include/mach/at572d940hf.h +++ b/trunk/arch/arm/mach-at91/include/mach/at572d940hf.h @@ -89,7 +89,7 @@ /* * System Peripherals (offset from AT91_BASE_SYS) */ -#define AT91_SDRAMC0 (0xffffea00 - AT91_BASE_SYS) +#define AT91_SDRAMC (0xffffea00 - AT91_BASE_SYS) #define AT91_SMC (0xffffec00 - AT91_BASE_SYS) #define AT91_MATRIX (0xffffee00 - AT91_BASE_SYS) #define AT91_AIC (0xfffff000 - AT91_BASE_SYS) diff --git a/trunk/arch/arm/mach-at91/irq.c b/trunk/arch/arm/mach-at91/irq.c index 9665265ec757..b56d6b3a4087 100644 --- a/trunk/arch/arm/mach-at91/irq.c +++ b/trunk/arch/arm/mach-at91/irq.c @@ -143,7 +143,8 @@ void __init at91_aic_init(unsigned int priority[NR_AIC_IRQS]) /* Active Low interrupt, with the specified priority */ at91_sys_write(AT91_AIC_SMR(i), AT91_AIC_SRCTYPE_LOW | priority[i]); - irq_set_chip_and_handler(i, &at91_aic_chip, handle_level_irq); + set_irq_chip(i, &at91_aic_chip); + set_irq_handler(i, handle_level_irq); set_irq_flags(i, IRQF_VALID | IRQF_PROBE); /* Perform 8 End Of Interrupt Command to make sure AIC will not Lock out nIRQ */ diff --git a/trunk/arch/arm/mach-bcmring/irq.c b/trunk/arch/arm/mach-bcmring/irq.c index c48feaf4e8e9..84dcda0d1d9a 100644 --- a/trunk/arch/arm/mach-bcmring/irq.c +++ b/trunk/arch/arm/mach-bcmring/irq.c @@ -93,11 +93,11 @@ static void vic_init(void __iomem *base, struct irq_chip *chip, unsigned int i; for (i = 0; i < 32; i++) { unsigned int irq = irq_start + i; - irq_set_chip(irq, chip); - irq_set_chip_data(irq, base); + set_irq_chip(irq, chip); + set_irq_chip_data(irq, base); if (vic_sources & (1 << i)) { - irq_set_handler(irq, handle_level_irq); + set_irq_handler(irq, handle_level_irq); set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); } } @@ -119,9 +119,9 @@ void __init bcmring_init_irq(void) /* special cases */ if (INTCHW_INTC1_GPIO0 & IRQ_INTC1_VALID_MASK) { - irq_set_handler(IRQ_GPIO0, handle_simple_irq); + set_irq_handler(IRQ_GPIO0, handle_simple_irq); } if (INTCHW_INTC1_GPIO1 & IRQ_INTC1_VALID_MASK) { - irq_set_handler(IRQ_GPIO1, handle_simple_irq); + set_irq_handler(IRQ_GPIO1, handle_simple_irq); } } diff --git a/trunk/arch/arm/mach-clps711x/irq.c b/trunk/arch/arm/mach-clps711x/irq.c index c2eceee645e3..86da7a1b2bbe 100644 --- a/trunk/arch/arm/mach-clps711x/irq.c +++ b/trunk/arch/arm/mach-clps711x/irq.c @@ -112,13 +112,13 @@ void __init clps711x_init_irq(void) for (i = 0; i < NR_IRQS; i++) { if (INT1_IRQS & (1 << i)) { - irq_set_chip_and_handler(i, &int1_chip, - handle_level_irq); + set_irq_handler(i, handle_level_irq); + set_irq_chip(i, &int1_chip); set_irq_flags(i, IRQF_VALID | IRQF_PROBE); } if (INT2_IRQS & (1 << i)) { - irq_set_chip_and_handler(i, &int2_chip, - handle_level_irq); + set_irq_handler(i, handle_level_irq); + set_irq_chip(i, &int2_chip); set_irq_flags(i, IRQF_VALID | IRQF_PROBE); } } diff --git a/trunk/arch/arm/mach-davinci/cp_intc.c b/trunk/arch/arm/mach-davinci/cp_intc.c index f83152d643c5..9abc80a86a22 100644 --- a/trunk/arch/arm/mach-davinci/cp_intc.c +++ b/trunk/arch/arm/mach-davinci/cp_intc.c @@ -167,9 +167,9 @@ void __init cp_intc_init(void) /* Set up genirq dispatching for cp_intc */ for (i = 0; i < num_irq; i++) { - irq_set_chip(i, &cp_intc_irq_chip); + set_irq_chip(i, &cp_intc_irq_chip); set_irq_flags(i, IRQF_VALID | IRQF_PROBE); - irq_set_handler(i, handle_edge_irq); + set_irq_handler(i, handle_edge_irq); } /* Enable global interrupt */ diff --git a/trunk/arch/arm/mach-davinci/gpio.c b/trunk/arch/arm/mach-davinci/gpio.c index a0b838894ac9..20d66e5e4663 100644 --- a/trunk/arch/arm/mach-davinci/gpio.c +++ b/trunk/arch/arm/mach-davinci/gpio.c @@ -62,7 +62,7 @@ static inline struct davinci_gpio_regs __iomem *irq2regs(int irq) { struct davinci_gpio_regs __iomem *g; - g = (__force struct davinci_gpio_regs __iomem *)irq_get_chip_data(irq); + g = (__force struct davinci_gpio_regs __iomem *)get_irq_chip_data(irq); return g; } @@ -208,7 +208,7 @@ pure_initcall(davinci_gpio_setup); static void gpio_irq_disable(struct irq_data *d) { struct davinci_gpio_regs __iomem *g = irq2regs(d->irq); - u32 mask = (u32) irq_data_get_irq_handler_data(d); + u32 mask = (u32) irq_data_get_irq_data(d); __raw_writel(mask, &g->clr_falling); __raw_writel(mask, &g->clr_rising); @@ -217,8 +217,8 @@ static void gpio_irq_disable(struct irq_data *d) static void gpio_irq_enable(struct irq_data *d) { struct davinci_gpio_regs __iomem *g = irq2regs(d->irq); - u32 mask = (u32) irq_data_get_irq_handler_data(d); - unsigned status = irqd_get_trigger_type(d); + u32 mask = (u32) irq_data_get_irq_data(d); + unsigned status = irq_desc[d->irq].status; status &= IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING; if (!status) @@ -233,11 +233,21 @@ static void gpio_irq_enable(struct irq_data *d) static int gpio_irq_type(struct irq_data *d, unsigned trigger) { struct davinci_gpio_regs __iomem *g = irq2regs(d->irq); - u32 mask = (u32) irq_data_get_irq_handler_data(d); + u32 mask = (u32) irq_data_get_irq_data(d); if (trigger & ~(IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING)) return -EINVAL; + irq_desc[d->irq].status &= ~IRQ_TYPE_SENSE_MASK; + irq_desc[d->irq].status |= trigger; + + /* don't enable the IRQ if it's currently disabled */ + if (irq_desc[d->irq].depth == 0) { + __raw_writel(mask, (trigger & IRQ_TYPE_EDGE_FALLING) + ? &g->set_falling : &g->clr_falling); + __raw_writel(mask, (trigger & IRQ_TYPE_EDGE_RISING) + ? &g->set_rising : &g->clr_rising); + } return 0; } @@ -246,7 +256,6 @@ static struct irq_chip gpio_irqchip = { .irq_enable = gpio_irq_enable, .irq_disable = gpio_irq_disable, .irq_set_type = gpio_irq_type, - .flags = IRQCHIP_SET_TYPE_MASKED, }; static void @@ -276,7 +285,7 @@ gpio_irq_handler(unsigned irq, struct irq_desc *desc) status >>= 16; /* now demux them to the right lowlevel handler */ - n = (int)irq_get_handler_data(irq); + n = (int)get_irq_data(irq); while (status) { res = ffs(status); n += res; @@ -314,7 +323,7 @@ static int gpio_to_irq_unbanked(struct gpio_chip *chip, unsigned offset) static int gpio_irq_type_unbanked(struct irq_data *d, unsigned trigger) { struct davinci_gpio_regs __iomem *g = irq2regs(d->irq); - u32 mask = (u32) irq_data_get_irq_handler_data(d); + u32 mask = (u32) irq_data_get_irq_data(d); if (trigger & ~(IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING)) return -EINVAL; @@ -386,7 +395,7 @@ static int __init davinci_gpio_irq_setup(void) /* AINTC handles mask/unmask; GPIO handles triggering */ irq = bank_irq; - gpio_irqchip_unbanked = *irq_get_chip(irq); + gpio_irqchip_unbanked = *get_irq_desc_chip(irq_to_desc(irq)); gpio_irqchip_unbanked.name = "GPIO-AINTC"; gpio_irqchip_unbanked.irq_set_type = gpio_irq_type_unbanked; @@ -397,10 +406,10 @@ static int __init davinci_gpio_irq_setup(void) /* set the direct IRQs up to use that irqchip */ for (gpio = 0; gpio < soc_info->gpio_unbanked; gpio++, irq++) { - irq_set_chip(irq, &gpio_irqchip_unbanked); - irq_set_handler_data(irq, (void *)__gpio_mask(gpio)); - irq_set_chip_data(irq, (__force void *)g); - irq_set_status_flags(irq, IRQ_TYPE_EDGE_BOTH); + set_irq_chip(irq, &gpio_irqchip_unbanked); + set_irq_data(irq, (void *) __gpio_mask(gpio)); + set_irq_chip_data(irq, (__force void *) g); + irq_desc[irq].status |= IRQ_TYPE_EDGE_BOTH; } goto done; @@ -421,15 +430,15 @@ static int __init davinci_gpio_irq_setup(void) __raw_writel(~0, &g->clr_rising); /* set up all irqs in this bank */ - irq_set_chained_handler(bank_irq, gpio_irq_handler); - irq_set_chip_data(bank_irq, (__force void *)g); - irq_set_handler_data(bank_irq, (void *)irq); + set_irq_chained_handler(bank_irq, gpio_irq_handler); + set_irq_chip_data(bank_irq, (__force void *) g); + set_irq_data(bank_irq, (void *) irq); for (i = 0; i < 16 && gpio < ngpio; i++, irq++, gpio++) { - irq_set_chip(irq, &gpio_irqchip); - irq_set_chip_data(irq, (__force void *)g); - irq_set_handler_data(irq, (void *)__gpio_mask(gpio)); - irq_set_handler(irq, handle_simple_irq); + set_irq_chip(irq, &gpio_irqchip); + set_irq_chip_data(irq, (__force void *) g); + set_irq_data(irq, (void *) __gpio_mask(gpio)); + set_irq_handler(irq, handle_simple_irq); set_irq_flags(irq, IRQF_VALID); } diff --git a/trunk/arch/arm/mach-davinci/irq.c b/trunk/arch/arm/mach-davinci/irq.c index e6269a6e0014..5e05c9b64e1f 100644 --- a/trunk/arch/arm/mach-davinci/irq.c +++ b/trunk/arch/arm/mach-davinci/irq.c @@ -154,11 +154,11 @@ void __init davinci_irq_init(void) /* set up genirq dispatch for ARM INTC */ for (i = 0; i < davinci_soc_info.intc_irq_num; i++) { - irq_set_chip(i, &davinci_irq_chip_0); + set_irq_chip(i, &davinci_irq_chip_0); set_irq_flags(i, IRQF_VALID | IRQF_PROBE); if (i != IRQ_TINT1_TINT34) - irq_set_handler(i, handle_edge_irq); + set_irq_handler(i, handle_edge_irq); else - irq_set_handler(i, handle_level_irq); + set_irq_handler(i, handle_level_irq); } } diff --git a/trunk/arch/arm/mach-dove/include/mach/dove.h b/trunk/arch/arm/mach-dove/include/mach/dove.h index b20ec9af7882..e5fcdd3f5bf5 100644 --- a/trunk/arch/arm/mach-dove/include/mach/dove.h +++ b/trunk/arch/arm/mach-dove/include/mach/dove.h @@ -136,7 +136,7 @@ #define DOVE_MPP_GENERAL_VIRT_BASE (DOVE_SB_REGS_VIRT_BASE | 0xe803c) #define DOVE_AU1_SPDIFO_GPIO_EN (1 << 1) #define DOVE_NAND_GPIO_EN (1 << 0) -#define DOVE_MPP_CTRL4_VIRT_BASE (DOVE_GPIO_LO_VIRT_BASE + 0x40) +#define DOVE_MPP_CTRL4_VIRT_BASE (DOVE_GPIO_VIRT_BASE + 0x40) #define DOVE_SPI_GPIO_SEL (1 << 5) #define DOVE_UART1_GPIO_SEL (1 << 4) #define DOVE_AU1_GPIO_SEL (1 << 3) diff --git a/trunk/arch/arm/mach-dove/irq.c b/trunk/arch/arm/mach-dove/irq.c index f07fd16e0c9b..101707fa2e2c 100644 --- a/trunk/arch/arm/mach-dove/irq.c +++ b/trunk/arch/arm/mach-dove/irq.c @@ -86,7 +86,8 @@ static void pmu_irq_handler(unsigned int irq, struct irq_desc *desc) if (!(cause & (1 << irq))) continue; irq = pmu_to_irq(irq); - generic_handle_irq(irq); + desc = irq_desc + irq; + desc_handle_irq(irq, desc); } } @@ -102,14 +103,14 @@ void __init dove_init_irq(void) */ orion_gpio_init(0, 32, DOVE_GPIO_LO_VIRT_BASE, 0, IRQ_DOVE_GPIO_START); - irq_set_chained_handler(IRQ_DOVE_GPIO_0_7, gpio_irq_handler); - irq_set_chained_handler(IRQ_DOVE_GPIO_8_15, gpio_irq_handler); - irq_set_chained_handler(IRQ_DOVE_GPIO_16_23, gpio_irq_handler); - irq_set_chained_handler(IRQ_DOVE_GPIO_24_31, gpio_irq_handler); + set_irq_chained_handler(IRQ_DOVE_GPIO_0_7, gpio_irq_handler); + set_irq_chained_handler(IRQ_DOVE_GPIO_8_15, gpio_irq_handler); + set_irq_chained_handler(IRQ_DOVE_GPIO_16_23, gpio_irq_handler); + set_irq_chained_handler(IRQ_DOVE_GPIO_24_31, gpio_irq_handler); orion_gpio_init(32, 32, DOVE_GPIO_HI_VIRT_BASE, 0, IRQ_DOVE_GPIO_START + 32); - irq_set_chained_handler(IRQ_DOVE_HIGH_GPIO, gpio_irq_handler); + set_irq_chained_handler(IRQ_DOVE_HIGH_GPIO, gpio_irq_handler); orion_gpio_init(64, 8, DOVE_GPIO2_VIRT_BASE, 0, IRQ_DOVE_GPIO_START + 64); @@ -121,9 +122,10 @@ void __init dove_init_irq(void) writel(0, PMU_INTERRUPT_CAUSE); for (i = IRQ_DOVE_PMU_START; i < NR_IRQS; i++) { - irq_set_chip_and_handler(i, &pmu_irq_chip, handle_level_irq); - irq_set_status_flags(i, IRQ_LEVEL); + set_irq_chip(i, &pmu_irq_chip); + set_irq_handler(i, handle_level_irq); + irq_desc[i].status |= IRQ_LEVEL; set_irq_flags(i, IRQF_VALID); } - irq_set_chained_handler(IRQ_DOVE_PMU, pmu_irq_handler); + set_irq_chained_handler(IRQ_DOVE_PMU, pmu_irq_handler); } diff --git a/trunk/arch/arm/mach-dove/mpp.c b/trunk/arch/arm/mach-dove/mpp.c index c66c76346904..71db2bdf2f28 100644 --- a/trunk/arch/arm/mach-dove/mpp.c +++ b/trunk/arch/arm/mach-dove/mpp.c @@ -147,6 +147,9 @@ void __init dove_mpp_conf(unsigned int *mpp_list) u32 pmu_sig_ctrl[PMU_SIG_REGS]; int i; + /* Initialize gpiolib. */ + orion_gpio_init(); + for (i = 0; i < MPP_NR_REGS; i++) mpp_ctrl[i] = readl(MPP_CTRL(i)); diff --git a/trunk/arch/arm/mach-ebsa110/core.c b/trunk/arch/arm/mach-ebsa110/core.c index 087bc771ac23..7df083f37fa7 100644 --- a/trunk/arch/arm/mach-ebsa110/core.c +++ b/trunk/arch/arm/mach-ebsa110/core.c @@ -66,8 +66,8 @@ static void __init ebsa110_init_irq(void) local_irq_restore(flags); for (irq = 0; irq < NR_IRQS; irq++) { - irq_set_chip_and_handler(irq, &ebsa110_irq_chip, - handle_level_irq); + set_irq_chip(irq, &ebsa110_irq_chip); + set_irq_handler(irq, handle_level_irq); set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); } } diff --git a/trunk/arch/arm/mach-ep93xx/gpio.c b/trunk/arch/arm/mach-ep93xx/gpio.c index 180b8a9d0d21..34e071d79761 100644 --- a/trunk/arch/arm/mach-ep93xx/gpio.c +++ b/trunk/arch/arm/mach-ep93xx/gpio.c @@ -117,7 +117,7 @@ static void ep93xx_gpio_irq_ack(struct irq_data *d) int port = line >> 3; int port_mask = 1 << (line & 7); - if (irqd_get_trigger_type(d) == IRQ_TYPE_EDGE_BOTH) { + if ((irq_desc[d->irq].status & IRQ_TYPE_SENSE_MASK) == IRQ_TYPE_EDGE_BOTH) { gpio_int_type2[port] ^= port_mask; /* switch edge direction */ ep93xx_gpio_update_int_params(port); } @@ -131,7 +131,7 @@ static void ep93xx_gpio_irq_mask_ack(struct irq_data *d) int port = line >> 3; int port_mask = 1 << (line & 7); - if (irqd_get_trigger_type(d) == IRQ_TYPE_EDGE_BOTH) + if ((irq_desc[d->irq].status & IRQ_TYPE_SENSE_MASK) == IRQ_TYPE_EDGE_BOTH) gpio_int_type2[port] ^= port_mask; /* switch edge direction */ gpio_int_unmasked[port] &= ~port_mask; @@ -165,10 +165,10 @@ static void ep93xx_gpio_irq_unmask(struct irq_data *d) */ static int ep93xx_gpio_irq_type(struct irq_data *d, unsigned int type) { + struct irq_desc *desc = irq_desc + d->irq; const int gpio = irq_to_gpio(d->irq); const int port = gpio >> 3; const int port_mask = 1 << (gpio & 7); - irq_flow_handler_t handler; gpio_direction_input(gpio); @@ -176,22 +176,22 @@ static int ep93xx_gpio_irq_type(struct irq_data *d, unsigned int type) case IRQ_TYPE_EDGE_RISING: gpio_int_type1[port] |= port_mask; gpio_int_type2[port] |= port_mask; - handler = handle_edge_irq; + desc->handle_irq = handle_edge_irq; break; case IRQ_TYPE_EDGE_FALLING: gpio_int_type1[port] |= port_mask; gpio_int_type2[port] &= ~port_mask; - handler = handle_edge_irq; + desc->handle_irq = handle_edge_irq; break; case IRQ_TYPE_LEVEL_HIGH: gpio_int_type1[port] &= ~port_mask; gpio_int_type2[port] |= port_mask; - handler = handle_level_irq; + desc->handle_irq = handle_level_irq; break; case IRQ_TYPE_LEVEL_LOW: gpio_int_type1[port] &= ~port_mask; gpio_int_type2[port] &= ~port_mask; - handler = handle_level_irq; + desc->handle_irq = handle_level_irq; break; case IRQ_TYPE_EDGE_BOTH: gpio_int_type1[port] |= port_mask; @@ -200,17 +200,18 @@ static int ep93xx_gpio_irq_type(struct irq_data *d, unsigned int type) gpio_int_type2[port] &= ~port_mask; /* falling */ else gpio_int_type2[port] |= port_mask; /* rising */ - handler = handle_edge_irq; + desc->handle_irq = handle_edge_irq; break; default: pr_err("failed to set irq type %d for gpio %d\n", type, gpio); return -EINVAL; } - __irq_set_handler_locked(d->irq, handler); - gpio_int_enabled[port] |= port_mask; + desc->status &= ~IRQ_TYPE_SENSE_MASK; + desc->status |= type & IRQ_TYPE_SENSE_MASK; + ep93xx_gpio_update_int_params(port); return 0; @@ -231,29 +232,20 @@ void __init ep93xx_gpio_init_irq(void) for (gpio_irq = gpio_to_irq(0); gpio_irq <= gpio_to_irq(EP93XX_GPIO_LINE_MAX_IRQ); ++gpio_irq) { - irq_set_chip_and_handler(gpio_irq, &ep93xx_gpio_irq_chip, - handle_level_irq); + set_irq_chip(gpio_irq, &ep93xx_gpio_irq_chip); + set_irq_handler(gpio_irq, handle_level_irq); set_irq_flags(gpio_irq, IRQF_VALID); } - irq_set_chained_handler(IRQ_EP93XX_GPIO_AB, - ep93xx_gpio_ab_irq_handler); - irq_set_chained_handler(IRQ_EP93XX_GPIO0MUX, - ep93xx_gpio_f_irq_handler); - irq_set_chained_handler(IRQ_EP93XX_GPIO1MUX, - ep93xx_gpio_f_irq_handler); - irq_set_chained_handler(IRQ_EP93XX_GPIO2MUX, - ep93xx_gpio_f_irq_handler); - irq_set_chained_handler(IRQ_EP93XX_GPIO3MUX, - ep93xx_gpio_f_irq_handler); - irq_set_chained_handler(IRQ_EP93XX_GPIO4MUX, - ep93xx_gpio_f_irq_handler); - irq_set_chained_handler(IRQ_EP93XX_GPIO5MUX, - ep93xx_gpio_f_irq_handler); - irq_set_chained_handler(IRQ_EP93XX_GPIO6MUX, - ep93xx_gpio_f_irq_handler); - irq_set_chained_handler(IRQ_EP93XX_GPIO7MUX, - ep93xx_gpio_f_irq_handler); + set_irq_chained_handler(IRQ_EP93XX_GPIO_AB, ep93xx_gpio_ab_irq_handler); + set_irq_chained_handler(IRQ_EP93XX_GPIO0MUX, ep93xx_gpio_f_irq_handler); + set_irq_chained_handler(IRQ_EP93XX_GPIO1MUX, ep93xx_gpio_f_irq_handler); + set_irq_chained_handler(IRQ_EP93XX_GPIO2MUX, ep93xx_gpio_f_irq_handler); + set_irq_chained_handler(IRQ_EP93XX_GPIO3MUX, ep93xx_gpio_f_irq_handler); + set_irq_chained_handler(IRQ_EP93XX_GPIO4MUX, ep93xx_gpio_f_irq_handler); + set_irq_chained_handler(IRQ_EP93XX_GPIO5MUX, ep93xx_gpio_f_irq_handler); + set_irq_chained_handler(IRQ_EP93XX_GPIO6MUX, ep93xx_gpio_f_irq_handler); + set_irq_chained_handler(IRQ_EP93XX_GPIO7MUX, ep93xx_gpio_f_irq_handler); } diff --git a/trunk/arch/arm/mach-exynos4/Kconfig b/trunk/arch/arm/mach-exynos4/Kconfig index e849f67be47d..a021b5240bba 100644 --- a/trunk/arch/arm/mach-exynos4/Kconfig +++ b/trunk/arch/arm/mach-exynos4/Kconfig @@ -20,11 +20,6 @@ config EXYNOS4_MCT help Use MCT (Multi Core Timer) as kernel timers -config EXYNOS4_DEV_AHCI - bool - help - Compile in platform device definitions for AHCI - config EXYNOS4_DEV_PD bool help @@ -139,9 +134,9 @@ config MACH_ARMLEX4210 select S3C_DEV_HSMMC select S3C_DEV_HSMMC2 select S3C_DEV_HSMMC3 - select EXYNOS4_DEV_AHCI select EXYNOS4_DEV_SYSMMU select EXYNOS4_SETUP_SDHCI + select SATA_AHCI_PLATFORM help Machine support for Samsung ARMLEX4210 based on EXYNOS4210 diff --git a/trunk/arch/arm/mach-exynos4/Makefile b/trunk/arch/arm/mach-exynos4/Makefile index 9be104f63c0b..b8f0e7d82d7e 100644 --- a/trunk/arch/arm/mach-exynos4/Makefile +++ b/trunk/arch/arm/mach-exynos4/Makefile @@ -39,7 +39,6 @@ obj-$(CONFIG_MACH_NURI) += mach-nuri.o # device support obj-y += dev-audio.o -obj-$(CONFIG_EXYNOS4_DEV_AHCI) += dev-ahci.o obj-$(CONFIG_EXYNOS4_DEV_PD) += dev-pd.o obj-$(CONFIG_EXYNOS4_DEV_SYSMMU) += dev-sysmmu.o @@ -54,3 +53,4 @@ obj-$(CONFIG_EXYNOS4_SETUP_I2C7) += setup-i2c7.o obj-$(CONFIG_EXYNOS4_SETUP_KEYPAD) += setup-keypad.o obj-$(CONFIG_EXYNOS4_SETUP_SDHCI) += setup-sdhci.o obj-$(CONFIG_EXYNOS4_SETUP_SDHCI_GPIO) += setup-sdhci-gpio.o +obj-$(CONFIG_SATA_AHCI_PLATFORM) += dev-ahci.o diff --git a/trunk/arch/arm/mach-exynos4/include/mach/debug-macro.S b/trunk/arch/arm/mach-exynos4/include/mach/debug-macro.S index a442ef861167..58bbd049a6c4 100644 --- a/trunk/arch/arm/mach-exynos4/include/mach/debug-macro.S +++ b/trunk/arch/arm/mach-exynos4/include/mach/debug-macro.S @@ -21,8 +21,8 @@ */ .macro addruart, rp, rv - ldr \rp, = S3C_PA_UART - ldr \rv, = S3C_VA_UART + ldreq \rp, = S3C_PA_UART + ldrne \rv, = S3C_VA_UART #if CONFIG_DEBUG_S3C_UART != 0 add \rp, \rp, #(0x10000 * CONFIG_DEBUG_S3C_UART) add \rv, \rv, #(0x10000 * CONFIG_DEBUG_S3C_UART) diff --git a/trunk/arch/arm/mach-exynos4/irq-combiner.c b/trunk/arch/arm/mach-exynos4/irq-combiner.c index f488b66d6806..31618d91ce15 100644 --- a/trunk/arch/arm/mach-exynos4/irq-combiner.c +++ b/trunk/arch/arm/mach-exynos4/irq-combiner.c @@ -54,8 +54,8 @@ static void combiner_unmask_irq(struct irq_data *data) static void combiner_handle_cascade_irq(unsigned int irq, struct irq_desc *desc) { - struct combiner_chip_data *chip_data = irq_get_handler_data(irq); - struct irq_chip *chip = irq_get_chip(irq); + struct combiner_chip_data *chip_data = get_irq_data(irq); + struct irq_chip *chip = get_irq_chip(irq); unsigned int cascade_irq, combiner_irq; unsigned long status; @@ -93,9 +93,9 @@ void __init combiner_cascade_irq(unsigned int combiner_nr, unsigned int irq) { if (combiner_nr >= MAX_COMBINER_NR) BUG(); - if (irq_set_handler_data(irq, &combiner_data[combiner_nr]) != 0) + if (set_irq_data(irq, &combiner_data[combiner_nr]) != 0) BUG(); - irq_set_chained_handler(irq, combiner_handle_cascade_irq); + set_irq_chained_handler(irq, combiner_handle_cascade_irq); } void __init combiner_init(unsigned int combiner_nr, void __iomem *base, @@ -119,8 +119,9 @@ void __init combiner_init(unsigned int combiner_nr, void __iomem *base, for (i = irq_start; i < combiner_data[combiner_nr].irq_offset + MAX_IRQ_IN_COMBINER; i++) { - irq_set_chip_and_handler(i, &combiner_chip, handle_level_irq); - irq_set_chip_data(i, &combiner_data[combiner_nr]); + set_irq_chip(i, &combiner_chip); + set_irq_chip_data(i, &combiner_data[combiner_nr]); + set_irq_handler(i, handle_level_irq); set_irq_flags(i, IRQF_VALID | IRQF_PROBE); } } diff --git a/trunk/arch/arm/mach-exynos4/irq-eint.c b/trunk/arch/arm/mach-exynos4/irq-eint.c index 9d87d2ac7f68..4f7ad4a796e4 100644 --- a/trunk/arch/arm/mach-exynos4/irq-eint.c +++ b/trunk/arch/arm/mach-exynos4/irq-eint.c @@ -190,8 +190,8 @@ static void exynos4_irq_demux_eint16_31(unsigned int irq, struct irq_desc *desc) static void exynos4_irq_eint0_15(unsigned int irq, struct irq_desc *desc) { - u32 *irq_data = irq_get_handler_data(irq); - struct irq_chip *chip = irq_get_chip(irq); + u32 *irq_data = get_irq_data(irq); + struct irq_chip *chip = get_irq_chip(irq); chip->irq_mask(&desc->irq_data); @@ -208,19 +208,18 @@ int __init exynos4_init_irq_eint(void) int irq; for (irq = 0 ; irq <= 31 ; irq++) { - irq_set_chip_and_handler(IRQ_EINT(irq), &exynos4_irq_eint, - handle_level_irq); + set_irq_chip(IRQ_EINT(irq), &exynos4_irq_eint); + set_irq_handler(IRQ_EINT(irq), handle_level_irq); set_irq_flags(IRQ_EINT(irq), IRQF_VALID); } - irq_set_chained_handler(IRQ_EINT16_31, exynos4_irq_demux_eint16_31); + set_irq_chained_handler(IRQ_EINT16_31, exynos4_irq_demux_eint16_31); for (irq = 0 ; irq <= 15 ; irq++) { eint0_15_data[irq] = IRQ_EINT(irq); - irq_set_handler_data(exynos4_get_irq_nr(irq), - &eint0_15_data[irq]); - irq_set_chained_handler(exynos4_get_irq_nr(irq), + set_irq_data(exynos4_get_irq_nr(irq), &eint0_15_data[irq]); + set_irq_chained_handler(exynos4_get_irq_nr(irq), exynos4_irq_eint0_15); } diff --git a/trunk/arch/arm/mach-exynos4/mach-smdkc210.c b/trunk/arch/arm/mach-exynos4/mach-smdkc210.c index e645f7a955f0..25a256818122 100644 --- a/trunk/arch/arm/mach-exynos4/mach-smdkc210.c +++ b/trunk/arch/arm/mach-exynos4/mach-smdkc210.c @@ -125,7 +125,7 @@ static struct resource smdkc210_smsc911x_resources[] = { }; static struct smsc911x_platform_config smsc9215_config = { - .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_LOW, + .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_HIGH, .irq_type = SMSC911X_IRQ_TYPE_PUSH_PULL, .flags = SMSC911X_USE_16BIT | SMSC911X_FORCE_INTERNAL_PHY, .phy_interface = PHY_INTERFACE_MODE_MII, diff --git a/trunk/arch/arm/mach-exynos4/mach-smdkv310.c b/trunk/arch/arm/mach-exynos4/mach-smdkv310.c index 152676471b67..88e0275143be 100644 --- a/trunk/arch/arm/mach-exynos4/mach-smdkv310.c +++ b/trunk/arch/arm/mach-exynos4/mach-smdkv310.c @@ -127,7 +127,7 @@ static struct resource smdkv310_smsc911x_resources[] = { }; static struct smsc911x_platform_config smsc9215_config = { - .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_LOW, + .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_HIGH, .irq_type = SMSC911X_IRQ_TYPE_PUSH_PULL, .flags = SMSC911X_USE_16BIT | SMSC911X_FORCE_INTERNAL_PHY, .phy_interface = PHY_INTERFACE_MODE_MII, diff --git a/trunk/arch/arm/mach-footbridge/common.c b/trunk/arch/arm/mach-footbridge/common.c index 38a44f9b9da2..84c5f258f2d8 100644 --- a/trunk/arch/arm/mach-footbridge/common.c +++ b/trunk/arch/arm/mach-footbridge/common.c @@ -102,7 +102,8 @@ static void __init __fb_init_irq(void) *CSR_FIQ_DISABLE = -1; for (irq = _DC21285_IRQ(0); irq < _DC21285_IRQ(20); irq++) { - irq_set_chip_and_handler(irq, &fb_chip, handle_level_irq); + set_irq_chip(irq, &fb_chip); + set_irq_handler(irq, handle_level_irq); set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); } } diff --git a/trunk/arch/arm/mach-footbridge/dc21285-timer.c b/trunk/arch/arm/mach-footbridge/dc21285-timer.c index 5f1f9867fc70..a921fe92b858 100644 --- a/trunk/arch/arm/mach-footbridge/dc21285-timer.c +++ b/trunk/arch/arm/mach-footbridge/dc21285-timer.c @@ -30,7 +30,7 @@ static int cksrc_dc21285_enable(struct clocksource *cs) return 0; } -static void cksrc_dc21285_disable(struct clocksource *cs) +static int cksrc_dc21285_disable(struct clocksource *cs) { *CSR_TIMER2_CNTL = 0; } diff --git a/trunk/arch/arm/mach-footbridge/isa-irq.c b/trunk/arch/arm/mach-footbridge/isa-irq.c index c3a0abbc9049..de7a5cb5dbe1 100644 --- a/trunk/arch/arm/mach-footbridge/isa-irq.c +++ b/trunk/arch/arm/mach-footbridge/isa-irq.c @@ -151,14 +151,14 @@ void __init isa_init_irq(unsigned int host_irq) if (host_irq != (unsigned int)-1) { for (irq = _ISA_IRQ(0); irq < _ISA_IRQ(8); irq++) { - irq_set_chip_and_handler(irq, &isa_lo_chip, - handle_level_irq); + set_irq_chip(irq, &isa_lo_chip); + set_irq_handler(irq, handle_level_irq); set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); } for (irq = _ISA_IRQ(8); irq < _ISA_IRQ(16); irq++) { - irq_set_chip_and_handler(irq, &isa_hi_chip, - handle_level_irq); + set_irq_chip(irq, &isa_hi_chip); + set_irq_handler(irq, handle_level_irq); set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); } @@ -166,7 +166,7 @@ void __init isa_init_irq(unsigned int host_irq) request_resource(&ioport_resource, &pic2_resource); setup_irq(IRQ_ISA_CASCADE, &irq_cascade); - irq_set_chained_handler(host_irq, isa_irq_handler); + set_irq_chained_handler(host_irq, isa_irq_handler); /* * On the NetWinder, don't automatically diff --git a/trunk/arch/arm/mach-gemini/gpio.c b/trunk/arch/arm/mach-gemini/gpio.c index fdc7ef1391d3..fa3d333f21e1 100644 --- a/trunk/arch/arm/mach-gemini/gpio.c +++ b/trunk/arch/arm/mach-gemini/gpio.c @@ -127,8 +127,8 @@ static int gpio_set_irq_type(struct irq_data *d, unsigned int type) static void gpio_irq_handler(unsigned int irq, struct irq_desc *desc) { - unsigned int port = (unsigned int)irq_desc_get_handler_data(desc); unsigned int gpio_irq_no, irq_stat; + unsigned int port = (unsigned int)get_irq_data(irq); irq_stat = __raw_readl(GPIO_BASE(port) + GPIO_INT_STAT); @@ -138,7 +138,9 @@ static void gpio_irq_handler(unsigned int irq, struct irq_desc *desc) if ((irq_stat & 1) == 0) continue; - generic_handle_irq(gpio_irq_no); + BUG_ON(!(irq_desc[gpio_irq_no].handle_irq)); + irq_desc[gpio_irq_no].handle_irq(gpio_irq_no, + &irq_desc[gpio_irq_no]); } } @@ -217,13 +219,13 @@ void __init gemini_gpio_init(void) for (j = GPIO_IRQ_BASE + i * 32; j < GPIO_IRQ_BASE + (i + 1) * 32; j++) { - irq_set_chip_and_handler(j, &gpio_irq_chip, - handle_edge_irq); + set_irq_chip(j, &gpio_irq_chip); + set_irq_handler(j, handle_edge_irq); set_irq_flags(j, IRQF_VALID); } - irq_set_chained_handler(IRQ_GPIO(i), gpio_irq_handler); - irq_set_handler_data(IRQ_GPIO(i), (void *)i); + set_irq_chained_handler(IRQ_GPIO(i), gpio_irq_handler); + set_irq_data(IRQ_GPIO(i), (void *)i); } BUG_ON(gpiochip_add(&gemini_gpio_chip)); diff --git a/trunk/arch/arm/mach-gemini/irq.c b/trunk/arch/arm/mach-gemini/irq.c index 9485a8fdf851..96bc227dd849 100644 --- a/trunk/arch/arm/mach-gemini/irq.c +++ b/trunk/arch/arm/mach-gemini/irq.c @@ -81,13 +81,13 @@ void __init gemini_init_irq(void) request_resource(&iomem_resource, &irq_resource); for (i = 0; i < NR_IRQS; i++) { - irq_set_chip(i, &gemini_irq_chip); + set_irq_chip(i, &gemini_irq_chip); if((i >= IRQ_TIMER1 && i <= IRQ_TIMER3) || (i >= IRQ_SERIRQ0 && i <= IRQ_SERIRQ1)) { - irq_set_handler(i, handle_edge_irq); + set_irq_handler(i, handle_edge_irq); mode |= 1 << i; level |= 1 << i; } else { - irq_set_handler(i, handle_level_irq); + set_irq_handler(i, handle_level_irq); } set_irq_flags(i, IRQF_VALID | IRQF_PROBE); } diff --git a/trunk/arch/arm/mach-h720x/common.c b/trunk/arch/arm/mach-h720x/common.c index 51d4e44ab973..1f28c90932c7 100644 --- a/trunk/arch/arm/mach-h720x/common.c +++ b/trunk/arch/arm/mach-h720x/common.c @@ -199,29 +199,29 @@ void __init h720x_init_irq (void) /* Initialize global IRQ's, fast path */ for (irq = 0; irq < NR_GLBL_IRQS; irq++) { - irq_set_chip_and_handler(irq, &h720x_global_chip, - handle_level_irq); + set_irq_chip(irq, &h720x_global_chip); + set_irq_handler(irq, handle_level_irq); set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); } /* Initialize multiplexed IRQ's, slow path */ for (irq = IRQ_CHAINED_GPIOA(0) ; irq <= IRQ_CHAINED_GPIOD(31); irq++) { - irq_set_chip_and_handler(irq, &h720x_gpio_chip, - handle_edge_irq); + set_irq_chip(irq, &h720x_gpio_chip); + set_irq_handler(irq, handle_edge_irq); set_irq_flags(irq, IRQF_VALID ); } - irq_set_chained_handler(IRQ_GPIOA, h720x_gpioa_demux_handler); - irq_set_chained_handler(IRQ_GPIOB, h720x_gpiob_demux_handler); - irq_set_chained_handler(IRQ_GPIOC, h720x_gpioc_demux_handler); - irq_set_chained_handler(IRQ_GPIOD, h720x_gpiod_demux_handler); + set_irq_chained_handler(IRQ_GPIOA, h720x_gpioa_demux_handler); + set_irq_chained_handler(IRQ_GPIOB, h720x_gpiob_demux_handler); + set_irq_chained_handler(IRQ_GPIOC, h720x_gpioc_demux_handler); + set_irq_chained_handler(IRQ_GPIOD, h720x_gpiod_demux_handler); #ifdef CONFIG_CPU_H7202 for (irq = IRQ_CHAINED_GPIOE(0) ; irq <= IRQ_CHAINED_GPIOE(31); irq++) { - irq_set_chip_and_handler(irq, &h720x_gpio_chip, - handle_edge_irq); + set_irq_chip(irq, &h720x_gpio_chip); + set_irq_handler(irq, handle_edge_irq); set_irq_flags(irq, IRQF_VALID ); } - irq_set_chained_handler(IRQ_GPIOE, h720x_gpioe_demux_handler); + set_irq_chained_handler(IRQ_GPIOE, h720x_gpioe_demux_handler); #endif /* Enable multiplexed irq's */ diff --git a/trunk/arch/arm/mach-h720x/cpu-h7202.c b/trunk/arch/arm/mach-h720x/cpu-h7202.c index c37d570b852d..ac3f91442376 100644 --- a/trunk/arch/arm/mach-h720x/cpu-h7202.c +++ b/trunk/arch/arm/mach-h720x/cpu-h7202.c @@ -141,18 +141,13 @@ h7202_timer_interrupt(int irq, void *dev_id) /* * mask multiplexed timer IRQs */ -static void inline __mask_timerx_irq(unsigned int irq) +static void inline mask_timerx_irq(struct irq_data *d) { unsigned int bit; - bit = 2 << ((irq == IRQ_TIMER64B) ? 4 : (irq - IRQ_TIMER1)); + bit = 2 << ((d->irq == IRQ_TIMER64B) ? 4 : (d->irq - IRQ_TIMER1)); CPU_REG (TIMER_VIRT, TIMER_TOPCTRL) &= ~bit; } -static void inline mask_timerx_irq(struct irq_data *d) -{ - __mask_timerx_irq(d->irq); -} - /* * unmask multiplexed timer IRQs */ @@ -201,12 +196,12 @@ void __init h7202_init_irq (void) for (irq = IRQ_TIMER1; irq < IRQ_CHAINED_TIMERX(NR_TIMERX_IRQS); irq++) { - __mask_timerx_irq(irq); - irq_set_chip_and_handler(irq, &h7202_timerx_chip, - handle_edge_irq); + mask_timerx_irq(irq); + set_irq_chip(irq, &h7202_timerx_chip); + set_irq_handler(irq, handle_edge_irq); set_irq_flags(irq, IRQF_VALID ); } - irq_set_chained_handler(IRQ_TIMERX, h7202_timerx_demux_handler); + set_irq_chained_handler(IRQ_TIMERX, h7202_timerx_demux_handler); h720x_init_irq(); } diff --git a/trunk/arch/arm/mach-iop13xx/irq.c b/trunk/arch/arm/mach-iop13xx/irq.c index bc739701c301..a233470dd10c 100644 --- a/trunk/arch/arm/mach-iop13xx/irq.c +++ b/trunk/arch/arm/mach-iop13xx/irq.c @@ -224,15 +224,15 @@ void __init iop13xx_init_irq(void) for(i = 0; i <= IRQ_IOP13XX_HPI; i++) { if (i < 32) - irq_set_chip(i, &iop13xx_irqchip1); + set_irq_chip(i, &iop13xx_irqchip1); else if (i < 64) - irq_set_chip(i, &iop13xx_irqchip2); + set_irq_chip(i, &iop13xx_irqchip2); else if (i < 96) - irq_set_chip(i, &iop13xx_irqchip3); + set_irq_chip(i, &iop13xx_irqchip3); else - irq_set_chip(i, &iop13xx_irqchip4); + set_irq_chip(i, &iop13xx_irqchip4); - irq_set_handler(i, handle_level_irq); + set_irq_handler(i, handle_level_irq); set_irq_flags(i, IRQF_VALID | IRQF_PROBE); } diff --git a/trunk/arch/arm/mach-iop13xx/msi.c b/trunk/arch/arm/mach-iop13xx/msi.c index 560d5b2dec22..c9c02e3698bc 100644 --- a/trunk/arch/arm/mach-iop13xx/msi.c +++ b/trunk/arch/arm/mach-iop13xx/msi.c @@ -118,7 +118,7 @@ static void iop13xx_msi_handler(unsigned int irq, struct irq_desc *desc) void __init iop13xx_msi_init(void) { - irq_set_chained_handler(IRQ_IOP13XX_INBD_MSI, iop13xx_msi_handler); + set_irq_chained_handler(IRQ_IOP13XX_INBD_MSI, iop13xx_msi_handler); } /* @@ -178,7 +178,7 @@ int arch_setup_msi_irq(struct pci_dev *pdev, struct msi_desc *desc) if (irq < 0) return irq; - irq_set_msi_desc(irq, desc); + set_irq_msi(irq, desc); msg.address_hi = 0x0; msg.address_lo = IOP13XX_MU_MIMR_PCI; @@ -187,7 +187,7 @@ int arch_setup_msi_irq(struct pci_dev *pdev, struct msi_desc *desc) msg.data = (id << IOP13XX_MU_MIMR_CORE_SELECT) | (irq & 0x7f); write_msi_msg(irq, &msg); - irq_set_chip_and_handler(irq, &iop13xx_msi_chip, handle_simple_irq); + set_irq_chip_and_handler(irq, &iop13xx_msi_chip, handle_simple_irq); return 0; } diff --git a/trunk/arch/arm/mach-iop32x/irq.c b/trunk/arch/arm/mach-iop32x/irq.c index d7ee2789d890..d3426a120599 100644 --- a/trunk/arch/arm/mach-iop32x/irq.c +++ b/trunk/arch/arm/mach-iop32x/irq.c @@ -68,7 +68,8 @@ void __init iop32x_init_irq(void) *IOP3XX_PCIIRSR = 0x0f; for (i = 0; i < NR_IRQS; i++) { - irq_set_chip_and_handler(i, &ext_chip, handle_level_irq); + set_irq_chip(i, &ext_chip); + set_irq_handler(i, handle_level_irq); set_irq_flags(i, IRQF_VALID | IRQF_PROBE); } } diff --git a/trunk/arch/arm/mach-iop33x/irq.c b/trunk/arch/arm/mach-iop33x/irq.c index f7f5d3e451c7..0ff2f74363a5 100644 --- a/trunk/arch/arm/mach-iop33x/irq.c +++ b/trunk/arch/arm/mach-iop33x/irq.c @@ -110,9 +110,8 @@ void __init iop33x_init_irq(void) *IOP3XX_PCIIRSR = 0x0f; for (i = 0; i < NR_IRQS; i++) { - irq_set_chip_and_handler(i, - (i < 32) ? &iop33x_irqchip1 : &iop33x_irqchip2, - handle_level_irq); + set_irq_chip(i, (i < 32) ? &iop33x_irqchip1 : &iop33x_irqchip2); + set_irq_handler(i, handle_level_irq); set_irq_flags(i, IRQF_VALID | IRQF_PROBE); } } diff --git a/trunk/arch/arm/mach-ixp2000/core.c b/trunk/arch/arm/mach-ixp2000/core.c index 4068166c8993..5fc4e064b650 100644 --- a/trunk/arch/arm/mach-ixp2000/core.c +++ b/trunk/arch/arm/mach-ixp2000/core.c @@ -476,8 +476,8 @@ void __init ixp2000_init_irq(void) */ for (irq = IRQ_IXP2000_SOFT_INT; irq <= IRQ_IXP2000_THDB3; irq++) { if ((1 << irq) & IXP2000_VALID_IRQ_MASK) { - irq_set_chip_and_handler(irq, &ixp2000_irq_chip, - handle_level_irq); + set_irq_chip(irq, &ixp2000_irq_chip); + set_irq_handler(irq, handle_level_irq); set_irq_flags(irq, IRQF_VALID); } else set_irq_flags(irq, 0); } @@ -485,21 +485,21 @@ void __init ixp2000_init_irq(void) for (irq = IRQ_IXP2000_DRAM0_MIN_ERR; irq <= IRQ_IXP2000_SP_INT; irq++) { if((1 << (irq - IRQ_IXP2000_DRAM0_MIN_ERR)) & IXP2000_VALID_ERR_IRQ_MASK) { - irq_set_chip_and_handler(irq, &ixp2000_err_irq_chip, - handle_level_irq); + set_irq_chip(irq, &ixp2000_err_irq_chip); + set_irq_handler(irq, handle_level_irq); set_irq_flags(irq, IRQF_VALID); } else set_irq_flags(irq, 0); } - irq_set_chained_handler(IRQ_IXP2000_ERRSUM, ixp2000_err_irq_handler); + set_irq_chained_handler(IRQ_IXP2000_ERRSUM, ixp2000_err_irq_handler); for (irq = IRQ_IXP2000_GPIO0; irq <= IRQ_IXP2000_GPIO7; irq++) { - irq_set_chip_and_handler(irq, &ixp2000_GPIO_irq_chip, - handle_level_irq); + set_irq_chip(irq, &ixp2000_GPIO_irq_chip); + set_irq_handler(irq, handle_level_irq); set_irq_flags(irq, IRQF_VALID); } - irq_set_chained_handler(IRQ_IXP2000_GPIO, ixp2000_GPIO_irq_handler); + set_irq_chained_handler(IRQ_IXP2000_GPIO, ixp2000_GPIO_irq_handler); /* * Enable PCI irqs. The actual PCI[AB] decoding is done in @@ -508,8 +508,8 @@ void __init ixp2000_init_irq(void) */ ixp2000_reg_write(IXP2000_IRQ_ENABLE_SET, (1 << IRQ_IXP2000_PCI)); for (irq = IRQ_IXP2000_PCIA; irq <= IRQ_IXP2000_PCIB; irq++) { - irq_set_chip_and_handler(irq, &ixp2000_pci_irq_chip, - handle_level_irq); + set_irq_chip(irq, &ixp2000_pci_irq_chip); + set_irq_handler(irq, handle_level_irq); set_irq_flags(irq, IRQF_VALID); } } diff --git a/trunk/arch/arm/mach-ixp2000/ixdp2x00.c b/trunk/arch/arm/mach-ixp2000/ixdp2x00.c index 235638f800e5..7d90d3f13ee8 100644 --- a/trunk/arch/arm/mach-ixp2000/ixdp2x00.c +++ b/trunk/arch/arm/mach-ixp2000/ixdp2x00.c @@ -158,13 +158,13 @@ void __init ixdp2x00_init_irq(volatile unsigned long *stat_reg, volatile unsigne *board_irq_mask = 0xffffffff; for(irq = IXP2000_BOARD_IRQ(0); irq < IXP2000_BOARD_IRQ(board_irq_count); irq++) { - irq_set_chip_and_handler(irq, &ixdp2x00_cpld_irq_chip, - handle_level_irq); + set_irq_chip(irq, &ixdp2x00_cpld_irq_chip); + set_irq_handler(irq, handle_level_irq); set_irq_flags(irq, IRQF_VALID); } /* Hook into PCI interrupt */ - irq_set_chained_handler(IRQ_IXP2000_PCIB, ixdp2x00_irq_handler); + set_irq_chained_handler(IRQ_IXP2000_PCIB, ixdp2x00_irq_handler); } /************************************************************************* diff --git a/trunk/arch/arm/mach-ixp2000/ixdp2x01.c b/trunk/arch/arm/mach-ixp2000/ixdp2x01.c index 84835b209557..34b1b2af37c8 100644 --- a/trunk/arch/arm/mach-ixp2000/ixdp2x01.c +++ b/trunk/arch/arm/mach-ixp2000/ixdp2x01.c @@ -115,8 +115,8 @@ void __init ixdp2x01_init_irq(void) for (irq = NR_IXP2000_IRQS; irq < NR_IXDP2X01_IRQS; irq++) { if (irq & valid_irq_mask) { - irq_set_chip_and_handler(irq, &ixdp2x01_irq_chip, - handle_level_irq); + set_irq_chip(irq, &ixdp2x01_irq_chip); + set_irq_handler(irq, handle_level_irq); set_irq_flags(irq, IRQF_VALID); } else { set_irq_flags(irq, 0); @@ -124,7 +124,7 @@ void __init ixdp2x01_init_irq(void) } /* Hook into PCI interrupts */ - irq_set_chained_handler(IRQ_IXP2000_PCIB, ixdp2x01_irq_handler); + set_irq_chained_handler(IRQ_IXP2000_PCIB, ixdp2x01_irq_handler); } diff --git a/trunk/arch/arm/mach-ixp23xx/core.c b/trunk/arch/arm/mach-ixp23xx/core.c index a1bee33d183e..9c8a33903216 100644 --- a/trunk/arch/arm/mach-ixp23xx/core.c +++ b/trunk/arch/arm/mach-ixp23xx/core.c @@ -289,12 +289,12 @@ static void ixp23xx_config_irq(unsigned int irq, enum ixp23xx_irq_type type) { switch (type) { case IXP23XX_IRQ_LEVEL: - irq_set_chip_and_handler(irq, &ixp23xx_irq_level_chip, - handle_level_irq); + set_irq_chip(irq, &ixp23xx_irq_level_chip); + set_irq_handler(irq, handle_level_irq); break; case IXP23XX_IRQ_EDGE: - irq_set_chip_and_handler(irq, &ixp23xx_irq_edge_chip, - handle_edge_irq); + set_irq_chip(irq, &ixp23xx_irq_edge_chip); + set_irq_handler(irq, handle_edge_irq); break; } set_irq_flags(irq, IRQF_VALID); @@ -324,12 +324,12 @@ void __init ixp23xx_init_irq(void) } for (irq = IRQ_IXP23XX_INTA; irq <= IRQ_IXP23XX_INTB; irq++) { - irq_set_chip_and_handler(irq, &ixp23xx_pci_irq_chip, - handle_level_irq); + set_irq_chip(irq, &ixp23xx_pci_irq_chip); + set_irq_handler(irq, handle_level_irq); set_irq_flags(irq, IRQF_VALID); } - irq_set_chained_handler(IRQ_IXP23XX_PCI_INT_RPH, pci_handler); + set_irq_chained_handler(IRQ_IXP23XX_PCI_INT_RPH, pci_handler); } diff --git a/trunk/arch/arm/mach-ixp23xx/ixdp2351.c b/trunk/arch/arm/mach-ixp23xx/ixdp2351.c index 8dcba17c81e7..181116aa6591 100644 --- a/trunk/arch/arm/mach-ixp23xx/ixdp2351.c +++ b/trunk/arch/arm/mach-ixp23xx/ixdp2351.c @@ -136,8 +136,8 @@ void __init ixdp2351_init_irq(void) irq++) { if (IXDP2351_INTA_IRQ_MASK(irq) & IXDP2351_INTA_IRQ_VALID) { set_irq_flags(irq, IRQF_VALID); - irq_set_chip_and_handler(irq, &ixdp2351_inta_chip, - handle_level_irq); + set_irq_handler(irq, handle_level_irq); + set_irq_chip(irq, &ixdp2351_inta_chip); } } @@ -147,13 +147,13 @@ void __init ixdp2351_init_irq(void) irq++) { if (IXDP2351_INTB_IRQ_MASK(irq) & IXDP2351_INTB_IRQ_VALID) { set_irq_flags(irq, IRQF_VALID); - irq_set_chip_and_handler(irq, &ixdp2351_intb_chip, - handle_level_irq); + set_irq_handler(irq, handle_level_irq); + set_irq_chip(irq, &ixdp2351_intb_chip); } } - irq_set_chained_handler(IRQ_IXP23XX_INTA, ixdp2351_inta_handler); - irq_set_chained_handler(IRQ_IXP23XX_INTB, ixdp2351_intb_handler); + set_irq_chained_handler(IRQ_IXP23XX_INTA, ixdp2351_inta_handler); + set_irq_chained_handler(IRQ_IXP23XX_INTB, ixdp2351_intb_handler); } /* diff --git a/trunk/arch/arm/mach-ixp23xx/roadrunner.c b/trunk/arch/arm/mach-ixp23xx/roadrunner.c index 8fe0c6273262..76c61ba73218 100644 --- a/trunk/arch/arm/mach-ixp23xx/roadrunner.c +++ b/trunk/arch/arm/mach-ixp23xx/roadrunner.c @@ -110,8 +110,8 @@ static int __init roadrunner_map_irq(struct pci_dev *dev, u8 idsel, u8 pin) static void __init roadrunner_pci_preinit(void) { - irq_set_irq_type(IRQ_ROADRUNNER_PCI_INTC, IRQ_TYPE_LEVEL_LOW); - irq_set_irq_type(IRQ_ROADRUNNER_PCI_INTD, IRQ_TYPE_LEVEL_LOW); + set_irq_type(IRQ_ROADRUNNER_PCI_INTC, IRQ_TYPE_LEVEL_LOW); + set_irq_type(IRQ_ROADRUNNER_PCI_INTD, IRQ_TYPE_LEVEL_LOW); ixp23xx_pci_preinit(); } diff --git a/trunk/arch/arm/mach-ixp4xx/avila-pci.c b/trunk/arch/arm/mach-ixp4xx/avila-pci.c index 162043ff29ff..845e1b500548 100644 --- a/trunk/arch/arm/mach-ixp4xx/avila-pci.c +++ b/trunk/arch/arm/mach-ixp4xx/avila-pci.c @@ -39,10 +39,10 @@ void __init avila_pci_preinit(void) { - irq_set_irq_type(IXP4XX_GPIO_IRQ(INTA), IRQ_TYPE_LEVEL_LOW); - irq_set_irq_type(IXP4XX_GPIO_IRQ(INTB), IRQ_TYPE_LEVEL_LOW); - irq_set_irq_type(IXP4XX_GPIO_IRQ(INTC), IRQ_TYPE_LEVEL_LOW); - irq_set_irq_type(IXP4XX_GPIO_IRQ(INTD), IRQ_TYPE_LEVEL_LOW); + set_irq_type(IXP4XX_GPIO_IRQ(INTA), IRQ_TYPE_LEVEL_LOW); + set_irq_type(IXP4XX_GPIO_IRQ(INTB), IRQ_TYPE_LEVEL_LOW); + set_irq_type(IXP4XX_GPIO_IRQ(INTC), IRQ_TYPE_LEVEL_LOW); + set_irq_type(IXP4XX_GPIO_IRQ(INTD), IRQ_TYPE_LEVEL_LOW); ixp4xx_pci_preinit(); } diff --git a/trunk/arch/arm/mach-ixp4xx/common.c b/trunk/arch/arm/mach-ixp4xx/common.c index ed19bc314318..9fd894271d5d 100644 --- a/trunk/arch/arm/mach-ixp4xx/common.c +++ b/trunk/arch/arm/mach-ixp4xx/common.c @@ -252,8 +252,8 @@ void __init ixp4xx_init_irq(void) /* Default to all level triggered */ for(i = 0; i < NR_IRQS; i++) { - irq_set_chip_and_handler(i, &ixp4xx_irq_chip, - handle_level_irq); + set_irq_chip(i, &ixp4xx_irq_chip); + set_irq_handler(i, handle_level_irq); set_irq_flags(i, IRQF_VALID); } } diff --git a/trunk/arch/arm/mach-ixp4xx/coyote-pci.c b/trunk/arch/arm/mach-ixp4xx/coyote-pci.c index 37fda7d6e83d..b978ea8bd6f0 100644 --- a/trunk/arch/arm/mach-ixp4xx/coyote-pci.c +++ b/trunk/arch/arm/mach-ixp4xx/coyote-pci.c @@ -32,8 +32,8 @@ void __init coyote_pci_preinit(void) { - irq_set_irq_type(IXP4XX_GPIO_IRQ(SLOT0_INTA), IRQ_TYPE_LEVEL_LOW); - irq_set_irq_type(IXP4XX_GPIO_IRQ(SLOT1_INTA), IRQ_TYPE_LEVEL_LOW); + set_irq_type(IXP4XX_GPIO_IRQ(SLOT0_INTA), IRQ_TYPE_LEVEL_LOW); + set_irq_type(IXP4XX_GPIO_IRQ(SLOT1_INTA), IRQ_TYPE_LEVEL_LOW); ixp4xx_pci_preinit(); } diff --git a/trunk/arch/arm/mach-ixp4xx/dsmg600-pci.c b/trunk/arch/arm/mach-ixp4xx/dsmg600-pci.c index c7612010b3fc..fa70fed462ba 100644 --- a/trunk/arch/arm/mach-ixp4xx/dsmg600-pci.c +++ b/trunk/arch/arm/mach-ixp4xx/dsmg600-pci.c @@ -35,12 +35,12 @@ void __init dsmg600_pci_preinit(void) { - irq_set_irq_type(IXP4XX_GPIO_IRQ(INTA), IRQ_TYPE_LEVEL_LOW); - irq_set_irq_type(IXP4XX_GPIO_IRQ(INTB), IRQ_TYPE_LEVEL_LOW); - irq_set_irq_type(IXP4XX_GPIO_IRQ(INTC), IRQ_TYPE_LEVEL_LOW); - irq_set_irq_type(IXP4XX_GPIO_IRQ(INTD), IRQ_TYPE_LEVEL_LOW); - irq_set_irq_type(IXP4XX_GPIO_IRQ(INTE), IRQ_TYPE_LEVEL_LOW); - irq_set_irq_type(IXP4XX_GPIO_IRQ(INTF), IRQ_TYPE_LEVEL_LOW); + set_irq_type(IXP4XX_GPIO_IRQ(INTA), IRQ_TYPE_LEVEL_LOW); + set_irq_type(IXP4XX_GPIO_IRQ(INTB), IRQ_TYPE_LEVEL_LOW); + set_irq_type(IXP4XX_GPIO_IRQ(INTC), IRQ_TYPE_LEVEL_LOW); + set_irq_type(IXP4XX_GPIO_IRQ(INTD), IRQ_TYPE_LEVEL_LOW); + set_irq_type(IXP4XX_GPIO_IRQ(INTE), IRQ_TYPE_LEVEL_LOW); + set_irq_type(IXP4XX_GPIO_IRQ(INTF), IRQ_TYPE_LEVEL_LOW); ixp4xx_pci_preinit(); } diff --git a/trunk/arch/arm/mach-ixp4xx/fsg-pci.c b/trunk/arch/arm/mach-ixp4xx/fsg-pci.c index 44ccde9d4879..5a810c930624 100644 --- a/trunk/arch/arm/mach-ixp4xx/fsg-pci.c +++ b/trunk/arch/arm/mach-ixp4xx/fsg-pci.c @@ -32,9 +32,9 @@ void __init fsg_pci_preinit(void) { - irq_set_irq_type(IXP4XX_GPIO_IRQ(INTA), IRQ_TYPE_LEVEL_LOW); - irq_set_irq_type(IXP4XX_GPIO_IRQ(INTB), IRQ_TYPE_LEVEL_LOW); - irq_set_irq_type(IXP4XX_GPIO_IRQ(INTC), IRQ_TYPE_LEVEL_LOW); + set_irq_type(IXP4XX_GPIO_IRQ(INTA), IRQ_TYPE_LEVEL_LOW); + set_irq_type(IXP4XX_GPIO_IRQ(INTB), IRQ_TYPE_LEVEL_LOW); + set_irq_type(IXP4XX_GPIO_IRQ(INTC), IRQ_TYPE_LEVEL_LOW); ixp4xx_pci_preinit(); } diff --git a/trunk/arch/arm/mach-ixp4xx/gateway7001-pci.c b/trunk/arch/arm/mach-ixp4xx/gateway7001-pci.c index fc1124168874..7e93a0975c4d 100644 --- a/trunk/arch/arm/mach-ixp4xx/gateway7001-pci.c +++ b/trunk/arch/arm/mach-ixp4xx/gateway7001-pci.c @@ -29,8 +29,8 @@ void __init gateway7001_pci_preinit(void) { - irq_set_irq_type(IRQ_IXP4XX_GPIO10, IRQ_TYPE_LEVEL_LOW); - irq_set_irq_type(IRQ_IXP4XX_GPIO11, IRQ_TYPE_LEVEL_LOW); + set_irq_type(IRQ_IXP4XX_GPIO10, IRQ_TYPE_LEVEL_LOW); + set_irq_type(IRQ_IXP4XX_GPIO11, IRQ_TYPE_LEVEL_LOW); ixp4xx_pci_preinit(); } diff --git a/trunk/arch/arm/mach-ixp4xx/goramo_mlr.c b/trunk/arch/arm/mach-ixp4xx/goramo_mlr.c index 3e8c0e33b59c..d0e4861ac03d 100644 --- a/trunk/arch/arm/mach-ixp4xx/goramo_mlr.c +++ b/trunk/arch/arm/mach-ixp4xx/goramo_mlr.c @@ -420,8 +420,8 @@ static void __init gmlr_init(void) gpio_line_config(GPIO_HSS1_RTS_N, IXP4XX_GPIO_OUT); gpio_line_config(GPIO_HSS0_DCD_N, IXP4XX_GPIO_IN); gpio_line_config(GPIO_HSS1_DCD_N, IXP4XX_GPIO_IN); - irq_set_irq_type(IXP4XX_GPIO_IRQ(GPIO_HSS0_DCD_N), IRQ_TYPE_EDGE_BOTH); - irq_set_irq_type(IXP4XX_GPIO_IRQ(GPIO_HSS1_DCD_N), IRQ_TYPE_EDGE_BOTH); + set_irq_type(IXP4XX_GPIO_IRQ(GPIO_HSS0_DCD_N), IRQ_TYPE_EDGE_BOTH); + set_irq_type(IXP4XX_GPIO_IRQ(GPIO_HSS1_DCD_N), IRQ_TYPE_EDGE_BOTH); set_control(CONTROL_HSS0_DTR_N, 1); set_control(CONTROL_HSS1_DTR_N, 1); @@ -441,10 +441,10 @@ static void __init gmlr_init(void) #ifdef CONFIG_PCI static void __init gmlr_pci_preinit(void) { - irq_set_irq_type(IXP4XX_GPIO_IRQ(GPIO_IRQ_ETHA), IRQ_TYPE_LEVEL_LOW); - irq_set_irq_type(IXP4XX_GPIO_IRQ(GPIO_IRQ_ETHB), IRQ_TYPE_LEVEL_LOW); - irq_set_irq_type(IXP4XX_GPIO_IRQ(GPIO_IRQ_NEC), IRQ_TYPE_LEVEL_LOW); - irq_set_irq_type(IXP4XX_GPIO_IRQ(GPIO_IRQ_MPCI), IRQ_TYPE_LEVEL_LOW); + set_irq_type(IXP4XX_GPIO_IRQ(GPIO_IRQ_ETHA), IRQ_TYPE_LEVEL_LOW); + set_irq_type(IXP4XX_GPIO_IRQ(GPIO_IRQ_ETHB), IRQ_TYPE_LEVEL_LOW); + set_irq_type(IXP4XX_GPIO_IRQ(GPIO_IRQ_NEC), IRQ_TYPE_LEVEL_LOW); + set_irq_type(IXP4XX_GPIO_IRQ(GPIO_IRQ_MPCI), IRQ_TYPE_LEVEL_LOW); ixp4xx_pci_preinit(); } diff --git a/trunk/arch/arm/mach-ixp4xx/gtwx5715-pci.c b/trunk/arch/arm/mach-ixp4xx/gtwx5715-pci.c index 38cc0725dbd8..25d2c333c204 100644 --- a/trunk/arch/arm/mach-ixp4xx/gtwx5715-pci.c +++ b/trunk/arch/arm/mach-ixp4xx/gtwx5715-pci.c @@ -43,8 +43,8 @@ */ void __init gtwx5715_pci_preinit(void) { - irq_set_irq_type(IXP4XX_GPIO_IRQ(INTA), IRQ_TYPE_LEVEL_LOW); - irq_set_irq_type(IXP4XX_GPIO_IRQ(INTB), IRQ_TYPE_LEVEL_LOW); + set_irq_type(IXP4XX_GPIO_IRQ(INTA), IRQ_TYPE_LEVEL_LOW); + set_irq_type(IXP4XX_GPIO_IRQ(INTB), IRQ_TYPE_LEVEL_LOW); ixp4xx_pci_preinit(); } diff --git a/trunk/arch/arm/mach-ixp4xx/ixdp425-pci.c b/trunk/arch/arm/mach-ixp4xx/ixdp425-pci.c index 58f400417eaf..1ba165a6edac 100644 --- a/trunk/arch/arm/mach-ixp4xx/ixdp425-pci.c +++ b/trunk/arch/arm/mach-ixp4xx/ixdp425-pci.c @@ -36,10 +36,10 @@ void __init ixdp425_pci_preinit(void) { - irq_set_irq_type(IXP4XX_GPIO_IRQ(INTA), IRQ_TYPE_LEVEL_LOW); - irq_set_irq_type(IXP4XX_GPIO_IRQ(INTB), IRQ_TYPE_LEVEL_LOW); - irq_set_irq_type(IXP4XX_GPIO_IRQ(INTC), IRQ_TYPE_LEVEL_LOW); - irq_set_irq_type(IXP4XX_GPIO_IRQ(INTD), IRQ_TYPE_LEVEL_LOW); + set_irq_type(IXP4XX_GPIO_IRQ(INTA), IRQ_TYPE_LEVEL_LOW); + set_irq_type(IXP4XX_GPIO_IRQ(INTB), IRQ_TYPE_LEVEL_LOW); + set_irq_type(IXP4XX_GPIO_IRQ(INTC), IRQ_TYPE_LEVEL_LOW); + set_irq_type(IXP4XX_GPIO_IRQ(INTD), IRQ_TYPE_LEVEL_LOW); ixp4xx_pci_preinit(); } diff --git a/trunk/arch/arm/mach-ixp4xx/ixdpg425-pci.c b/trunk/arch/arm/mach-ixp4xx/ixdpg425-pci.c index e64f6d041488..4ed7ac614920 100644 --- a/trunk/arch/arm/mach-ixp4xx/ixdpg425-pci.c +++ b/trunk/arch/arm/mach-ixp4xx/ixdpg425-pci.c @@ -25,8 +25,8 @@ void __init ixdpg425_pci_preinit(void) { - irq_set_irq_type(IRQ_IXP4XX_GPIO6, IRQ_TYPE_LEVEL_LOW); - irq_set_irq_type(IRQ_IXP4XX_GPIO7, IRQ_TYPE_LEVEL_LOW); + set_irq_type(IRQ_IXP4XX_GPIO6, IRQ_TYPE_LEVEL_LOW); + set_irq_type(IRQ_IXP4XX_GPIO7, IRQ_TYPE_LEVEL_LOW); ixp4xx_pci_preinit(); } diff --git a/trunk/arch/arm/mach-ixp4xx/nas100d-pci.c b/trunk/arch/arm/mach-ixp4xx/nas100d-pci.c index 428d1202b799..d0cea34cf61e 100644 --- a/trunk/arch/arm/mach-ixp4xx/nas100d-pci.c +++ b/trunk/arch/arm/mach-ixp4xx/nas100d-pci.c @@ -33,11 +33,11 @@ void __init nas100d_pci_preinit(void) { - irq_set_irq_type(IXP4XX_GPIO_IRQ(INTA), IRQ_TYPE_LEVEL_LOW); - irq_set_irq_type(IXP4XX_GPIO_IRQ(INTB), IRQ_TYPE_LEVEL_LOW); - irq_set_irq_type(IXP4XX_GPIO_IRQ(INTC), IRQ_TYPE_LEVEL_LOW); - irq_set_irq_type(IXP4XX_GPIO_IRQ(INTD), IRQ_TYPE_LEVEL_LOW); - irq_set_irq_type(IXP4XX_GPIO_IRQ(INTE), IRQ_TYPE_LEVEL_LOW); + set_irq_type(IXP4XX_GPIO_IRQ(INTA), IRQ_TYPE_LEVEL_LOW); + set_irq_type(IXP4XX_GPIO_IRQ(INTB), IRQ_TYPE_LEVEL_LOW); + set_irq_type(IXP4XX_GPIO_IRQ(INTC), IRQ_TYPE_LEVEL_LOW); + set_irq_type(IXP4XX_GPIO_IRQ(INTD), IRQ_TYPE_LEVEL_LOW); + set_irq_type(IXP4XX_GPIO_IRQ(INTE), IRQ_TYPE_LEVEL_LOW); ixp4xx_pci_preinit(); } diff --git a/trunk/arch/arm/mach-ixp4xx/nslu2-pci.c b/trunk/arch/arm/mach-ixp4xx/nslu2-pci.c index 2e85f76b950d..1eb5a90470bc 100644 --- a/trunk/arch/arm/mach-ixp4xx/nslu2-pci.c +++ b/trunk/arch/arm/mach-ixp4xx/nslu2-pci.c @@ -32,9 +32,9 @@ void __init nslu2_pci_preinit(void) { - irq_set_irq_type(IXP4XX_GPIO_IRQ(INTA), IRQ_TYPE_LEVEL_LOW); - irq_set_irq_type(IXP4XX_GPIO_IRQ(INTB), IRQ_TYPE_LEVEL_LOW); - irq_set_irq_type(IXP4XX_GPIO_IRQ(INTC), IRQ_TYPE_LEVEL_LOW); + set_irq_type(IXP4XX_GPIO_IRQ(INTA), IRQ_TYPE_LEVEL_LOW); + set_irq_type(IXP4XX_GPIO_IRQ(INTB), IRQ_TYPE_LEVEL_LOW); + set_irq_type(IXP4XX_GPIO_IRQ(INTC), IRQ_TYPE_LEVEL_LOW); ixp4xx_pci_preinit(); } diff --git a/trunk/arch/arm/mach-ixp4xx/vulcan-pci.c b/trunk/arch/arm/mach-ixp4xx/vulcan-pci.c index 03bdec5140a7..f3111c6840ef 100644 --- a/trunk/arch/arm/mach-ixp4xx/vulcan-pci.c +++ b/trunk/arch/arm/mach-ixp4xx/vulcan-pci.c @@ -38,8 +38,8 @@ void __init vulcan_pci_preinit(void) pr_info("Vulcan PCI: limiting CardBus memory size to %dMB\n", (int)(pci_cardbus_mem_size >> 20)); #endif - irq_set_irq_type(IXP4XX_GPIO_IRQ(INTA), IRQ_TYPE_LEVEL_LOW); - irq_set_irq_type(IXP4XX_GPIO_IRQ(INTB), IRQ_TYPE_LEVEL_LOW); + set_irq_type(IXP4XX_GPIO_IRQ(INTA), IRQ_TYPE_LEVEL_LOW); + set_irq_type(IXP4XX_GPIO_IRQ(INTB), IRQ_TYPE_LEVEL_LOW); ixp4xx_pci_preinit(); } diff --git a/trunk/arch/arm/mach-ixp4xx/wg302v2-pci.c b/trunk/arch/arm/mach-ixp4xx/wg302v2-pci.c index 17f3cf59a31b..9b59ed03b151 100644 --- a/trunk/arch/arm/mach-ixp4xx/wg302v2-pci.c +++ b/trunk/arch/arm/mach-ixp4xx/wg302v2-pci.c @@ -29,8 +29,8 @@ void __init wg302v2_pci_preinit(void) { - irq_set_irq_type(IRQ_IXP4XX_GPIO8, IRQ_TYPE_LEVEL_LOW); - irq_set_irq_type(IRQ_IXP4XX_GPIO9, IRQ_TYPE_LEVEL_LOW); + set_irq_type(IRQ_IXP4XX_GPIO8, IRQ_TYPE_LEVEL_LOW); + set_irq_type(IRQ_IXP4XX_GPIO9, IRQ_TYPE_LEVEL_LOW); ixp4xx_pci_preinit(); } diff --git a/trunk/arch/arm/mach-kirkwood/irq.c b/trunk/arch/arm/mach-kirkwood/irq.c index 05d193a25b25..cbdb5863d13b 100644 --- a/trunk/arch/arm/mach-kirkwood/irq.c +++ b/trunk/arch/arm/mach-kirkwood/irq.c @@ -35,15 +35,14 @@ void __init kirkwood_init_irq(void) */ orion_gpio_init(0, 32, GPIO_LOW_VIRT_BASE, 0, IRQ_KIRKWOOD_GPIO_START); - irq_set_chained_handler(IRQ_KIRKWOOD_GPIO_LOW_0_7, gpio_irq_handler); - irq_set_chained_handler(IRQ_KIRKWOOD_GPIO_LOW_8_15, gpio_irq_handler); - irq_set_chained_handler(IRQ_KIRKWOOD_GPIO_LOW_16_23, gpio_irq_handler); - irq_set_chained_handler(IRQ_KIRKWOOD_GPIO_LOW_24_31, gpio_irq_handler); + set_irq_chained_handler(IRQ_KIRKWOOD_GPIO_LOW_0_7, gpio_irq_handler); + set_irq_chained_handler(IRQ_KIRKWOOD_GPIO_LOW_8_15, gpio_irq_handler); + set_irq_chained_handler(IRQ_KIRKWOOD_GPIO_LOW_16_23, gpio_irq_handler); + set_irq_chained_handler(IRQ_KIRKWOOD_GPIO_LOW_24_31, gpio_irq_handler); orion_gpio_init(32, 18, GPIO_HIGH_VIRT_BASE, 0, IRQ_KIRKWOOD_GPIO_START + 32); - irq_set_chained_handler(IRQ_KIRKWOOD_GPIO_HIGH_0_7, gpio_irq_handler); - irq_set_chained_handler(IRQ_KIRKWOOD_GPIO_HIGH_8_15, gpio_irq_handler); - irq_set_chained_handler(IRQ_KIRKWOOD_GPIO_HIGH_16_23, - gpio_irq_handler); + set_irq_chained_handler(IRQ_KIRKWOOD_GPIO_HIGH_0_7, gpio_irq_handler); + set_irq_chained_handler(IRQ_KIRKWOOD_GPIO_HIGH_8_15, gpio_irq_handler); + set_irq_chained_handler(IRQ_KIRKWOOD_GPIO_HIGH_16_23, gpio_irq_handler); } diff --git a/trunk/arch/arm/mach-ks8695/gpio.c b/trunk/arch/arm/mach-ks8695/gpio.c index 31e456508a6f..55fbf7111a5b 100644 --- a/trunk/arch/arm/mach-ks8695/gpio.c +++ b/trunk/arch/arm/mach-ks8695/gpio.c @@ -80,7 +80,7 @@ int ks8695_gpio_interrupt(unsigned int pin, unsigned int type) local_irq_restore(flags); /* Set IRQ triggering type */ - irq_set_irq_type(gpio_irq[pin], type); + set_irq_type(gpio_irq[pin], type); /* enable interrupt mode */ ks8695_gpio_mode(pin, 0); diff --git a/trunk/arch/arm/mach-ks8695/irq.c b/trunk/arch/arm/mach-ks8695/irq.c index a78092dcd6fb..7998ccaa6333 100644 --- a/trunk/arch/arm/mach-ks8695/irq.c +++ b/trunk/arch/arm/mach-ks8695/irq.c @@ -115,12 +115,12 @@ static int ks8695_irq_set_type(struct irq_data *d, unsigned int type) } if (level_triggered) { - irq_set_chip_and_handler(d->irq, &ks8695_irq_level_chip, - handle_level_irq); + set_irq_chip(d->irq, &ks8695_irq_level_chip); + set_irq_handler(d->irq, handle_level_irq); } else { - irq_set_chip_and_handler(d->irq, &ks8695_irq_edge_chip, - handle_edge_irq); + set_irq_chip(d->irq, &ks8695_irq_edge_chip); + set_irq_handler(d->irq, handle_edge_irq); } __raw_writel(ctrl, KS8695_GPIO_VA + KS8695_IOPC); @@ -158,18 +158,16 @@ void __init ks8695_init_irq(void) case KS8695_IRQ_UART_RX: case KS8695_IRQ_COMM_TX: case KS8695_IRQ_COMM_RX: - irq_set_chip_and_handler(irq, - &ks8695_irq_level_chip, - handle_level_irq); + set_irq_chip(irq, &ks8695_irq_level_chip); + set_irq_handler(irq, handle_level_irq); break; /* Edge-triggered interrupts */ default: /* clear pending bit */ ks8695_irq_ack(irq_get_irq_data(irq)); - irq_set_chip_and_handler(irq, - &ks8695_irq_edge_chip, - handle_edge_irq); + set_irq_chip(irq, &ks8695_irq_edge_chip); + set_irq_handler(irq, handle_edge_irq); } set_irq_flags(irq, IRQF_VALID); diff --git a/trunk/arch/arm/mach-lpc32xx/irq.c b/trunk/arch/arm/mach-lpc32xx/irq.c index 4eae566dfdc7..316ecbf6c586 100644 --- a/trunk/arch/arm/mach-lpc32xx/irq.c +++ b/trunk/arch/arm/mach-lpc32xx/irq.c @@ -290,7 +290,7 @@ static int lpc32xx_set_irq_type(struct irq_data *d, unsigned int type) } /* Ok to use the level handler for all types */ - irq_set_handler(d->irq, handle_level_irq); + set_irq_handler(d->irq, handle_level_irq); return 0; } @@ -390,8 +390,8 @@ void __init lpc32xx_init_irq(void) /* Configure supported IRQ's */ for (i = 0; i < NR_IRQS; i++) { - irq_set_chip_and_handler(i, &lpc32xx_irq_chip, - handle_level_irq); + set_irq_chip(i, &lpc32xx_irq_chip); + set_irq_handler(i, handle_level_irq); set_irq_flags(i, IRQF_VALID); } @@ -406,8 +406,8 @@ void __init lpc32xx_init_irq(void) __raw_writel(0, LPC32XX_INTC_MASK(LPC32XX_SIC2_BASE)); /* MIC SUBIRQx interrupts will route handling to the chain handlers */ - irq_set_chained_handler(IRQ_LPC32XX_SUB1IRQ, lpc32xx_sic1_handler); - irq_set_chained_handler(IRQ_LPC32XX_SUB2IRQ, lpc32xx_sic2_handler); + set_irq_chained_handler(IRQ_LPC32XX_SUB1IRQ, lpc32xx_sic1_handler); + set_irq_chained_handler(IRQ_LPC32XX_SUB2IRQ, lpc32xx_sic2_handler); /* Initially disable all wake events */ __raw_writel(0, LPC32XX_CLKPWR_P01_ER); diff --git a/trunk/arch/arm/mach-mmp/irq-mmp2.c b/trunk/arch/arm/mach-mmp/irq-mmp2.c index d21c5441a3d0..fa037038e7b8 100644 --- a/trunk/arch/arm/mach-mmp/irq-mmp2.c +++ b/trunk/arch/arm/mach-mmp/irq-mmp2.c @@ -110,9 +110,9 @@ static void init_mux_irq(struct irq_chip *chip, int start, int num) if (chip->irq_ack) chip->irq_ack(d); - irq_set_chip(irq, chip); + set_irq_chip(irq, chip); set_irq_flags(irq, IRQF_VALID); - irq_set_handler(irq, handle_level_irq); + set_irq_handler(irq, handle_level_irq); } } @@ -122,7 +122,7 @@ void __init mmp2_init_icu(void) for (irq = 0; irq < IRQ_MMP2_MUX_BASE; irq++) { icu_mask_irq(irq_get_irq_data(irq)); - irq_set_chip(irq, &icu_irq_chip); + set_irq_chip(irq, &icu_irq_chip); set_irq_flags(irq, IRQF_VALID); switch (irq) { @@ -133,7 +133,7 @@ void __init mmp2_init_icu(void) case IRQ_MMP2_SSP_MUX: break; default: - irq_set_handler(irq, handle_level_irq); + set_irq_handler(irq, handle_level_irq); break; } } @@ -149,9 +149,9 @@ void __init mmp2_init_icu(void) init_mux_irq(&misc_irq_chip, IRQ_MMP2_MISC_BASE, 15); init_mux_irq(&ssp_irq_chip, IRQ_MMP2_SSP_BASE, 2); - irq_set_chained_handler(IRQ_MMP2_PMIC_MUX, pmic_irq_demux); - irq_set_chained_handler(IRQ_MMP2_RTC_MUX, rtc_irq_demux); - irq_set_chained_handler(IRQ_MMP2_TWSI_MUX, twsi_irq_demux); - irq_set_chained_handler(IRQ_MMP2_MISC_MUX, misc_irq_demux); - irq_set_chained_handler(IRQ_MMP2_SSP_MUX, ssp_irq_demux); + set_irq_chained_handler(IRQ_MMP2_PMIC_MUX, pmic_irq_demux); + set_irq_chained_handler(IRQ_MMP2_RTC_MUX, rtc_irq_demux); + set_irq_chained_handler(IRQ_MMP2_TWSI_MUX, twsi_irq_demux); + set_irq_chained_handler(IRQ_MMP2_MISC_MUX, misc_irq_demux); + set_irq_chained_handler(IRQ_MMP2_SSP_MUX, ssp_irq_demux); } diff --git a/trunk/arch/arm/mach-mmp/irq-pxa168.c b/trunk/arch/arm/mach-mmp/irq-pxa168.c index 89706a0d08f1..f86b450cb93c 100644 --- a/trunk/arch/arm/mach-mmp/irq-pxa168.c +++ b/trunk/arch/arm/mach-mmp/irq-pxa168.c @@ -48,7 +48,8 @@ void __init icu_init_irq(void) for (irq = 0; irq < 64; irq++) { icu_mask_irq(irq_get_irq_data(irq)); - irq_set_chip_and_handler(irq, &icu_irq_chip, handle_level_irq); + set_irq_chip(irq, &icu_irq_chip); + set_irq_handler(irq, handle_level_irq); set_irq_flags(irq, IRQF_VALID); } } diff --git a/trunk/arch/arm/mach-msm/board-msm8960.c b/trunk/arch/arm/mach-msm/board-msm8960.c index 35c7ceeb3f29..1993721d472e 100644 --- a/trunk/arch/arm/mach-msm/board-msm8960.c +++ b/trunk/arch/arm/mach-msm/board-msm8960.c @@ -53,7 +53,7 @@ static void __init msm8960_init_irq(void) */ for (i = GIC_PPI_START; i < GIC_SPI_START; i++) { if (i != AVS_SVICINT && i != AVS_SVICINTSWDONE) - irq_set_handler(i, handle_percpu_irq); + set_irq_handler(i, handle_percpu_irq); } } diff --git a/trunk/arch/arm/mach-msm/board-msm8x60.c b/trunk/arch/arm/mach-msm/board-msm8x60.c index 1163b6fd05d2..b3c55f138fce 100644 --- a/trunk/arch/arm/mach-msm/board-msm8x60.c +++ b/trunk/arch/arm/mach-msm/board-msm8x60.c @@ -56,7 +56,7 @@ static void __init msm8x60_init_irq(void) */ for (i = GIC_PPI_START; i < GIC_SPI_START; i++) { if (i != AVS_SVICINT && i != AVS_SVICINTSWDONE) - irq_set_handler(i, handle_percpu_irq); + set_irq_handler(i, handle_percpu_irq); } } diff --git a/trunk/arch/arm/mach-msm/board-trout-gpio.c b/trunk/arch/arm/mach-msm/board-trout-gpio.c index 87e1d01edecc..31117a4499c4 100644 --- a/trunk/arch/arm/mach-msm/board-trout-gpio.c +++ b/trunk/arch/arm/mach-msm/board-trout-gpio.c @@ -214,17 +214,17 @@ int __init trout_init_gpio(void) { int i; for(i = TROUT_INT_START; i <= TROUT_INT_END; i++) { - irq_set_chip_and_handler(i, &trout_gpio_irq_chip, - handle_edge_irq); + set_irq_chip(i, &trout_gpio_irq_chip); + set_irq_handler(i, handle_edge_irq); set_irq_flags(i, IRQF_VALID); } for (i = 0; i < ARRAY_SIZE(msm_gpio_banks); i++) gpiochip_add(&msm_gpio_banks[i].chip); - irq_set_irq_type(MSM_GPIO_TO_INT(17), IRQF_TRIGGER_HIGH); - irq_set_chained_handler(MSM_GPIO_TO_INT(17), trout_gpio_irq_handler); - irq_set_irq_wake(MSM_GPIO_TO_INT(17), 1); + set_irq_type(MSM_GPIO_TO_INT(17), IRQF_TRIGGER_HIGH); + set_irq_chained_handler(MSM_GPIO_TO_INT(17), trout_gpio_irq_handler); + set_irq_wake(MSM_GPIO_TO_INT(17), 1); return 0; } diff --git a/trunk/arch/arm/mach-msm/board-trout-mmc.c b/trunk/arch/arm/mach-msm/board-trout-mmc.c index f7a9724788b0..44be8464657b 100644 --- a/trunk/arch/arm/mach-msm/board-trout-mmc.c +++ b/trunk/arch/arm/mach-msm/board-trout-mmc.c @@ -174,7 +174,7 @@ int __init trout_init_mmc(unsigned int sys_rev) if (IS_ERR(vreg_sdslot)) return PTR_ERR(vreg_sdslot); - irq_set_irq_wake(TROUT_GPIO_TO_INT(TROUT_GPIO_SDMC_CD_N), 1); + set_irq_wake(TROUT_GPIO_TO_INT(TROUT_GPIO_SDMC_CD_N), 1); if (!opt_disable_sdcard) msm_add_sdcc(2, &trout_sdslot_data, diff --git a/trunk/arch/arm/mach-msm/gpio-v2.c b/trunk/arch/arm/mach-msm/gpio-v2.c index 56a964e52ad3..0de19ec74e34 100644 --- a/trunk/arch/arm/mach-msm/gpio-v2.c +++ b/trunk/arch/arm/mach-msm/gpio-v2.c @@ -230,18 +230,18 @@ static void msm_gpio_update_dual_edge_pos(unsigned gpio) val, val2); } -static void msm_gpio_irq_ack(struct irq_data *d) +static void msm_gpio_irq_ack(unsigned int irq) { - int gpio = msm_irq_to_gpio(&msm_gpio.gpio_chip, d->irq); + int gpio = msm_irq_to_gpio(&msm_gpio.gpio_chip, irq); writel(BIT(INTR_STATUS), GPIO_INTR_STATUS(gpio)); if (test_bit(gpio, msm_gpio.dual_edge_irqs)) msm_gpio_update_dual_edge_pos(gpio); } -static void msm_gpio_irq_mask(struct irq_data *d) +static void msm_gpio_irq_mask(unsigned int irq) { - int gpio = msm_irq_to_gpio(&msm_gpio.gpio_chip, d->irq); + int gpio = msm_irq_to_gpio(&msm_gpio.gpio_chip, irq); unsigned long irq_flags; spin_lock_irqsave(&tlmm_lock, irq_flags); @@ -251,9 +251,9 @@ static void msm_gpio_irq_mask(struct irq_data *d) spin_unlock_irqrestore(&tlmm_lock, irq_flags); } -static void msm_gpio_irq_unmask(struct irq_data *d) +static void msm_gpio_irq_unmask(unsigned int irq) { - int gpio = msm_irq_to_gpio(&msm_gpio.gpio_chip, d->irq); + int gpio = msm_irq_to_gpio(&msm_gpio.gpio_chip, irq); unsigned long irq_flags; spin_lock_irqsave(&tlmm_lock, irq_flags); @@ -263,9 +263,9 @@ static void msm_gpio_irq_unmask(struct irq_data *d) spin_unlock_irqrestore(&tlmm_lock, irq_flags); } -static int msm_gpio_irq_set_type(struct irq_data *d, unsigned int flow_type) +static int msm_gpio_irq_set_type(unsigned int irq, unsigned int flow_type) { - int gpio = msm_irq_to_gpio(&msm_gpio.gpio_chip, d->irq); + int gpio = msm_irq_to_gpio(&msm_gpio.gpio_chip, irq); unsigned long irq_flags; uint32_t bits; @@ -275,14 +275,14 @@ static int msm_gpio_irq_set_type(struct irq_data *d, unsigned int flow_type) if (flow_type & IRQ_TYPE_EDGE_BOTH) { bits |= BIT(INTR_DECT_CTL); - __irq_set_handler_locked(d->irq, handle_edge_irq); + irq_desc[irq].handle_irq = handle_edge_irq; if ((flow_type & IRQ_TYPE_EDGE_BOTH) == IRQ_TYPE_EDGE_BOTH) __set_bit(gpio, msm_gpio.dual_edge_irqs); else __clear_bit(gpio, msm_gpio.dual_edge_irqs); } else { bits &= ~BIT(INTR_DECT_CTL); - __irq_set_handler_locked(d->irq, handle_level_irq); + irq_desc[irq].handle_irq = handle_level_irq; __clear_bit(gpio, msm_gpio.dual_edge_irqs); } @@ -309,7 +309,6 @@ static int msm_gpio_irq_set_type(struct irq_data *d, unsigned int flow_type) */ static void msm_summary_irq_handler(unsigned int irq, struct irq_desc *desc) { - struct irq_data *data = irq_desc_get_irq_data(desc); unsigned long i; for (i = find_first_bit(msm_gpio.enabled_irqs, NR_GPIO_IRQS); @@ -319,21 +318,21 @@ static void msm_summary_irq_handler(unsigned int irq, struct irq_desc *desc) generic_handle_irq(msm_gpio_to_irq(&msm_gpio.gpio_chip, i)); } - data->chip->irq_ack(data); + desc->chip->ack(irq); } -static int msm_gpio_irq_set_wake(struct irq_data *d, unsigned int on) +static int msm_gpio_irq_set_wake(unsigned int irq, unsigned int on) { - int gpio = msm_irq_to_gpio(&msm_gpio.gpio_chip, d->irq); + int gpio = msm_irq_to_gpio(&msm_gpio.gpio_chip, irq); if (on) { if (bitmap_empty(msm_gpio.wake_irqs, NR_GPIO_IRQS)) - irq_set_irq_wake(TLMM_SCSS_SUMMARY_IRQ, 1); + set_irq_wake(TLMM_SCSS_SUMMARY_IRQ, 1); set_bit(gpio, msm_gpio.wake_irqs); } else { clear_bit(gpio, msm_gpio.wake_irqs); if (bitmap_empty(msm_gpio.wake_irqs, NR_GPIO_IRQS)) - irq_set_irq_wake(TLMM_SCSS_SUMMARY_IRQ, 0); + set_irq_wake(TLMM_SCSS_SUMMARY_IRQ, 0); } return 0; @@ -341,11 +340,11 @@ static int msm_gpio_irq_set_wake(struct irq_data *d, unsigned int on) static struct irq_chip msm_gpio_irq_chip = { .name = "msmgpio", - .irq_mask = msm_gpio_irq_mask, - .irq_unmask = msm_gpio_irq_unmask, - .irq_ack = msm_gpio_irq_ack, - .irq_set_type = msm_gpio_irq_set_type, - .irq_set_wake = msm_gpio_irq_set_wake, + .mask = msm_gpio_irq_mask, + .unmask = msm_gpio_irq_unmask, + .ack = msm_gpio_irq_ack, + .set_type = msm_gpio_irq_set_type, + .set_wake = msm_gpio_irq_set_wake, }; static int __devinit msm_gpio_probe(struct platform_device *dev) @@ -362,12 +361,12 @@ static int __devinit msm_gpio_probe(struct platform_device *dev) for (i = 0; i < msm_gpio.gpio_chip.ngpio; ++i) { irq = msm_gpio_to_irq(&msm_gpio.gpio_chip, i); - irq_set_chip_and_handler(irq, &msm_gpio_irq_chip, - handle_level_irq); + set_irq_chip(irq, &msm_gpio_irq_chip); + set_irq_handler(irq, handle_level_irq); set_irq_flags(irq, IRQF_VALID); } - irq_set_chained_handler(TLMM_SCSS_SUMMARY_IRQ, + set_irq_chained_handler(TLMM_SCSS_SUMMARY_IRQ, msm_summary_irq_handler); return 0; } @@ -379,7 +378,7 @@ static int __devexit msm_gpio_remove(struct platform_device *dev) if (ret < 0) return ret; - irq_set_handler(TLMM_SCSS_SUMMARY_IRQ, NULL); + set_irq_handler(TLMM_SCSS_SUMMARY_IRQ, NULL); return 0; } diff --git a/trunk/arch/arm/mach-msm/gpio.c b/trunk/arch/arm/mach-msm/gpio.c index 5ea273b00da8..176af9dcb8ee 100644 --- a/trunk/arch/arm/mach-msm/gpio.c +++ b/trunk/arch/arm/mach-msm/gpio.c @@ -293,10 +293,10 @@ static int msm_gpio_irq_set_type(struct irq_data *d, unsigned int flow_type) val = readl(msm_chip->regs.int_edge); if (flow_type & IRQ_TYPE_EDGE_BOTH) { writel(val | mask, msm_chip->regs.int_edge); - __irq_set_handler_locked(d->irq, handle_edge_irq); + irq_desc[d->irq].handle_irq = handle_edge_irq; } else { writel(val & ~mask, msm_chip->regs.int_edge); - __irq_set_handler_locked(d->irq, handle_level_irq); + irq_desc[d->irq].handle_irq = handle_level_irq; } if ((flow_type & IRQ_TYPE_EDGE_BOTH) == IRQ_TYPE_EDGE_BOTH) { msm_chip->both_edge_detect |= mask; @@ -354,9 +354,9 @@ static int __init msm_init_gpio(void) msm_gpio_chips[j].chip.base + msm_gpio_chips[j].chip.ngpio) j++; - irq_set_chip_data(i, &msm_gpio_chips[j]); - irq_set_chip_and_handler(i, &msm_gpio_irq_chip, - handle_edge_irq); + set_irq_chip_data(i, &msm_gpio_chips[j]); + set_irq_chip(i, &msm_gpio_irq_chip); + set_irq_handler(i, handle_edge_irq); set_irq_flags(i, IRQF_VALID); } @@ -366,10 +366,10 @@ static int __init msm_init_gpio(void) gpiochip_add(&msm_gpio_chips[i].chip); } - irq_set_chained_handler(INT_GPIO_GROUP1, msm_gpio_irq_handler); - irq_set_chained_handler(INT_GPIO_GROUP2, msm_gpio_irq_handler); - irq_set_irq_wake(INT_GPIO_GROUP1, 1); - irq_set_irq_wake(INT_GPIO_GROUP2, 2); + set_irq_chained_handler(INT_GPIO_GROUP1, msm_gpio_irq_handler); + set_irq_chained_handler(INT_GPIO_GROUP2, msm_gpio_irq_handler); + set_irq_wake(INT_GPIO_GROUP1, 1); + set_irq_wake(INT_GPIO_GROUP2, 2); return 0; } diff --git a/trunk/arch/arm/mach-msm/irq-vic.c b/trunk/arch/arm/mach-msm/irq-vic.c index 1b54f807c2d0..68c28bbdc969 100644 --- a/trunk/arch/arm/mach-msm/irq-vic.c +++ b/trunk/arch/arm/mach-msm/irq-vic.c @@ -313,11 +313,11 @@ static int msm_irq_set_type(struct irq_data *d, unsigned int flow_type) type = msm_irq_shadow_reg[index].int_type; if (flow_type & (IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING)) { type |= b; - __irq_set_handler_locked(d->irq, handle_edge_irq); + irq_desc[d->irq].handle_irq = handle_edge_irq; } if (flow_type & (IRQF_TRIGGER_HIGH | IRQF_TRIGGER_LOW)) { type &= ~b; - __irq_set_handler_locked(d->irq, handle_level_irq); + irq_desc[d->irq].handle_irq = handle_level_irq; } writel(type, treg); msm_irq_shadow_reg[index].int_type = type; @@ -357,7 +357,8 @@ void __init msm_init_irq(void) writel(3, VIC_INT_MASTEREN); for (n = 0; n < NR_MSM_IRQS; n++) { - irq_set_chip_and_handler(n, &msm_irq_chip, handle_level_irq); + set_irq_chip(n, &msm_irq_chip); + set_irq_handler(n, handle_level_irq); set_irq_flags(n, IRQF_VALID); } } diff --git a/trunk/arch/arm/mach-msm/irq.c b/trunk/arch/arm/mach-msm/irq.c index ea514be390c6..0b27d899f40e 100644 --- a/trunk/arch/arm/mach-msm/irq.c +++ b/trunk/arch/arm/mach-msm/irq.c @@ -100,11 +100,11 @@ static int msm_irq_set_type(struct irq_data *d, unsigned int flow_type) if (flow_type & (IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING)) { writel(readl(treg) | b, treg); - __irq_set_handler_locked(d->irq, handle_edge_irq); + irq_desc[d->irq].handle_irq = handle_edge_irq; } if (flow_type & (IRQF_TRIGGER_HIGH | IRQF_TRIGGER_LOW)) { writel(readl(treg) & (~b), treg); - __irq_set_handler_locked(d->irq, handle_level_irq); + irq_desc[d->irq].handle_irq = handle_level_irq; } return 0; } @@ -145,7 +145,8 @@ void __init msm_init_irq(void) writel(1, VIC_INT_MASTEREN); for (n = 0; n < NR_MSM_IRQS; n++) { - irq_set_chip_and_handler(n, &msm_irq_chip, handle_level_irq); + set_irq_chip(n, &msm_irq_chip); + set_irq_handler(n, handle_level_irq); set_irq_flags(n, IRQF_VALID); } } diff --git a/trunk/arch/arm/mach-msm/sirc.c b/trunk/arch/arm/mach-msm/sirc.c index 689e78c95f38..11b54c7aeb09 100644 --- a/trunk/arch/arm/mach-msm/sirc.c +++ b/trunk/arch/arm/mach-msm/sirc.c @@ -105,10 +105,10 @@ static int sirc_irq_set_type(struct irq_data *d, unsigned int flow_type) val = readl(sirc_regs.int_type); if (flow_type & (IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING)) { val |= mask; - __irq_set_handler_locked(d->irq, handle_edge_irq); + irq_desc[d->irq].handle_irq = handle_edge_irq; } else { val &= ~mask; - __irq_set_handler_locked(d->irq, handle_level_irq); + irq_desc[d->irq].handle_irq = handle_level_irq; } writel(val, sirc_regs.int_type); @@ -158,14 +158,15 @@ void __init msm_init_sirc(void) wake_enable = 0; for (i = FIRST_SIRC_IRQ; i < LAST_SIRC_IRQ; i++) { - irq_set_chip_and_handler(i, &sirc_irq_chip, handle_edge_irq); + set_irq_chip(i, &sirc_irq_chip); + set_irq_handler(i, handle_edge_irq); set_irq_flags(i, IRQF_VALID); } for (i = 0; i < ARRAY_SIZE(sirc_reg_table); i++) { - irq_set_chained_handler(sirc_reg_table[i].cascade_irq, + set_irq_chained_handler(sirc_reg_table[i].cascade_irq, sirc_irq_handler); - irq_set_irq_wake(sirc_reg_table[i].cascade_irq, 1); + set_irq_wake(sirc_reg_table[i].cascade_irq, 1); } return; } diff --git a/trunk/arch/arm/mach-mv78xx0/irq.c b/trunk/arch/arm/mach-mv78xx0/irq.c index 3e24431bb5ea..08da497c39c2 100644 --- a/trunk/arch/arm/mach-mv78xx0/irq.c +++ b/trunk/arch/arm/mach-mv78xx0/irq.c @@ -38,8 +38,8 @@ void __init mv78xx0_init_irq(void) orion_gpio_init(0, 32, GPIO_VIRT_BASE, mv78xx0_core_index() ? 0x18 : 0, IRQ_MV78XX0_GPIO_START); - irq_set_chained_handler(IRQ_MV78XX0_GPIO_0_7, gpio_irq_handler); - irq_set_chained_handler(IRQ_MV78XX0_GPIO_8_15, gpio_irq_handler); - irq_set_chained_handler(IRQ_MV78XX0_GPIO_16_23, gpio_irq_handler); - irq_set_chained_handler(IRQ_MV78XX0_GPIO_24_31, gpio_irq_handler); + set_irq_chained_handler(IRQ_MV78XX0_GPIO_0_7, gpio_irq_handler); + set_irq_chained_handler(IRQ_MV78XX0_GPIO_8_15, gpio_irq_handler); + set_irq_chained_handler(IRQ_MV78XX0_GPIO_16_23, gpio_irq_handler); + set_irq_chained_handler(IRQ_MV78XX0_GPIO_24_31, gpio_irq_handler); } diff --git a/trunk/arch/arm/mach-mx3/mach-mx31ads.c b/trunk/arch/arm/mach-mx3/mach-mx31ads.c index 3d095d69bc68..4e4b780c481d 100644 --- a/trunk/arch/arm/mach-mx3/mach-mx31ads.c +++ b/trunk/arch/arm/mach-mx3/mach-mx31ads.c @@ -199,11 +199,12 @@ static void __init mx31ads_init_expio(void) __raw_writew(0xFFFF, PBC_INTSTATUS_REG); for (i = MXC_EXP_IO_BASE; i < (MXC_EXP_IO_BASE + MXC_MAX_EXP_IO_LINES); i++) { - irq_set_chip_and_handler(i, &expio_irq_chip, handle_level_irq); + set_irq_chip(i, &expio_irq_chip); + set_irq_handler(i, handle_level_irq); set_irq_flags(i, IRQF_VALID); } - irq_set_irq_type(EXPIO_PARENT_INT, IRQ_TYPE_LEVEL_HIGH); - irq_set_chained_handler(EXPIO_PARENT_INT, mx31ads_expio_irq_handler); + set_irq_type(EXPIO_PARENT_INT, IRQ_TYPE_LEVEL_HIGH); + set_irq_chained_handler(EXPIO_PARENT_INT, mx31ads_expio_irq_handler); } #ifdef CONFIG_MACH_MX31ADS_WM1133_EV1 diff --git a/trunk/arch/arm/mach-mx5/eukrea_mbimx51-baseboard.c b/trunk/arch/arm/mach-mx5/eukrea_mbimx51-baseboard.c index 4a8550529b04..e83ffadb65f8 100644 --- a/trunk/arch/arm/mach-mx5/eukrea_mbimx51-baseboard.c +++ b/trunk/arch/arm/mach-mx5/eukrea_mbimx51-baseboard.c @@ -212,7 +212,7 @@ void __init eukrea_mbimx51_baseboard_init(void) gpio_request(MBIMX51_TSC2007_GPIO, "tsc2007_irq"); gpio_direction_input(MBIMX51_TSC2007_GPIO); - irq_set_irq_type(MBIMX51_TSC2007_IRQ, IRQF_TRIGGER_FALLING); + set_irq_type(MBIMX51_TSC2007_IRQ, IRQF_TRIGGER_FALLING); i2c_register_board_info(1, mbimx51_i2c_devices, ARRAY_SIZE(mbimx51_i2c_devices)); diff --git a/trunk/arch/arm/mach-mx5/mx51_efika.c b/trunk/arch/arm/mach-mx5/mx51_efika.c index 868af8f435fa..51a67fc7f0ef 100644 --- a/trunk/arch/arm/mach-mx5/mx51_efika.c +++ b/trunk/arch/arm/mach-mx5/mx51_efika.c @@ -572,10 +572,8 @@ static struct mc13xxx_regulator_init_data mx51_efika_regulators[] = { static struct mc13xxx_platform_data mx51_efika_mc13892_data = { .flags = MC13XXX_USE_RTC | MC13XXX_USE_REGULATOR, - .regulators = { - .num_regulators = ARRAY_SIZE(mx51_efika_regulators), - .regulators = mx51_efika_regulators, - }, + .num_regulators = ARRAY_SIZE(mx51_efika_regulators), + .regulators = mx51_efika_regulators, }; static struct spi_board_info mx51_efika_spi_board_info[] __initdata = { diff --git a/trunk/arch/arm/mach-mxs/gpio.c b/trunk/arch/arm/mach-mxs/gpio.c index 2c950fef71a8..56fa2ed15222 100644 --- a/trunk/arch/arm/mach-mxs/gpio.c +++ b/trunk/arch/arm/mach-mxs/gpio.c @@ -136,7 +136,7 @@ static int mxs_gpio_set_irq_type(struct irq_data *d, unsigned int type) static void mxs_gpio_irq_handler(u32 irq, struct irq_desc *desc) { u32 irq_stat; - struct mxs_gpio_port *port = (struct mxs_gpio_port *)irq_get_handler_data(irq); + struct mxs_gpio_port *port = (struct mxs_gpio_port *)get_irq_data(irq); u32 gpio_irq_no_base = port->virtual_irq_start; desc->irq_data.chip->irq_ack(&desc->irq_data); @@ -265,14 +265,14 @@ int __init mxs_gpio_init(struct mxs_gpio_port *port, int cnt) for (j = port[i].virtual_irq_start; j < port[i].virtual_irq_start + 32; j++) { - irq_set_chip_and_handler(j, &gpio_irq_chip, - handle_level_irq); + set_irq_chip(j, &gpio_irq_chip); + set_irq_handler(j, handle_level_irq); set_irq_flags(j, IRQF_VALID); } /* setup one handler for each entry */ - irq_set_chained_handler(port[i].irq, mxs_gpio_irq_handler); - irq_set_handler_data(port[i].irq, &port[i]); + set_irq_chained_handler(port[i].irq, mxs_gpio_irq_handler); + set_irq_data(port[i].irq, &port[i]); /* register gpio chip */ port[i].chip.direction_input = mxs_gpio_direction_input; diff --git a/trunk/arch/arm/mach-mxs/icoll.c b/trunk/arch/arm/mach-mxs/icoll.c index 23ca9d083b2c..0f4c120fc169 100644 --- a/trunk/arch/arm/mach-mxs/icoll.c +++ b/trunk/arch/arm/mach-mxs/icoll.c @@ -74,7 +74,8 @@ void __init icoll_init_irq(void) mxs_reset_block(icoll_base + HW_ICOLL_CTRL); for (i = 0; i < MXS_INTERNAL_IRQS; i++) { - irq_set_chip_and_handler(i, &mxs_icoll_chip, handle_level_irq); + set_irq_chip(i, &mxs_icoll_chip); + set_irq_handler(i, handle_level_irq); set_irq_flags(i, IRQF_VALID); } } diff --git a/trunk/arch/arm/mach-netx/generic.c b/trunk/arch/arm/mach-netx/generic.c index 00023b5cf12b..29ffa750fbe6 100644 --- a/trunk/arch/arm/mach-netx/generic.c +++ b/trunk/arch/arm/mach-netx/generic.c @@ -171,13 +171,13 @@ void __init netx_init_irq(void) vic_init(__io(io_p2v(NETX_PA_VIC)), 0, ~0, 0); for (irq = NETX_IRQ_HIF_CHAINED(0); irq <= NETX_IRQ_HIF_LAST; irq++) { - irq_set_chip_and_handler(irq, &netx_hif_chip, - handle_level_irq); + set_irq_chip(irq, &netx_hif_chip); + set_irq_handler(irq, handle_level_irq); set_irq_flags(irq, IRQF_VALID); } writel(NETX_DPMAS_INT_EN_GLB_EN, NETX_DPMAS_INT_EN); - irq_set_chained_handler(NETX_IRQ_HIF, netx_hif_demux_handler); + set_irq_chained_handler(NETX_IRQ_HIF, netx_hif_demux_handler); } static int __init netx_init(void) diff --git a/trunk/arch/arm/mach-ns9xxx/board-a9m9750dev.c b/trunk/arch/arm/mach-ns9xxx/board-a9m9750dev.c index e27687d53504..0c0d5248c368 100644 --- a/trunk/arch/arm/mach-ns9xxx/board-a9m9750dev.c +++ b/trunk/arch/arm/mach-ns9xxx/board-a9m9750dev.c @@ -107,8 +107,8 @@ void __init board_a9m9750dev_init_irq(void) __func__); for (i = FPGA_IRQ(0); i <= FPGA_IRQ(7); ++i) { - irq_set_chip_and_handler(i, &a9m9750dev_fpga_chip, - handle_level_irq); + set_irq_chip(i, &a9m9750dev_fpga_chip); + set_irq_handler(i, handle_level_irq); set_irq_flags(i, IRQF_VALID); } @@ -118,8 +118,8 @@ void __init board_a9m9750dev_init_irq(void) REGSET(eic, SYS_EIC, LVEDG, LEVEL); __raw_writel(eic, SYS_EIC(2)); - irq_set_chained_handler(IRQ_NS9XXX_EXT2, - a9m9750dev_fpga_demux_handler); + set_irq_chained_handler(IRQ_NS9XXX_EXT2, + a9m9750dev_fpga_demux_handler); } void __init board_a9m9750dev_init_machine(void) diff --git a/trunk/arch/arm/mach-ns9xxx/include/mach/board.h b/trunk/arch/arm/mach-ns9xxx/include/mach/board.h index 19ca6de46a45..f7e9196eb9ab 100644 --- a/trunk/arch/arm/mach-ns9xxx/include/mach/board.h +++ b/trunk/arch/arm/mach-ns9xxx/include/mach/board.h @@ -14,10 +14,12 @@ #include #define board_is_a9m9750dev() (0 \ + || machine_is_cc9p9360dev() \ || machine_is_cc9p9750dev() \ ) #define board_is_a9mvali() (0 \ + || machine_is_cc9p9360val() \ || machine_is_cc9p9750val() \ ) diff --git a/trunk/arch/arm/mach-ns9xxx/include/mach/module.h b/trunk/arch/arm/mach-ns9xxx/include/mach/module.h index 628e9752589b..f851a6b7da6c 100644 --- a/trunk/arch/arm/mach-ns9xxx/include/mach/module.h +++ b/trunk/arch/arm/mach-ns9xxx/include/mach/module.h @@ -18,6 +18,7 @@ ) #define module_is_cc9c() (0 \ + || machine_is_cc9c() \ ) #define module_is_cc9p9210() (0 \ @@ -31,17 +32,21 @@ ) #define module_is_cc9p9360() (0 \ + || machine_is_a9m9360() \ || machine_is_cc9p9360dev() \ || machine_is_cc9p9360js() \ + || machine_is_cc9p9360val() \ ) #define module_is_cc9p9750() (0 \ || machine_is_a9m9750() \ + || machine_is_cc9p9750dev() \ || machine_is_cc9p9750js() \ || machine_is_cc9p9750val() \ ) #define module_is_ccw9c() (0 \ + || machine_is_ccw9c() \ ) #define module_is_inc20otter() (0 \ diff --git a/trunk/arch/arm/mach-ns9xxx/irq.c b/trunk/arch/arm/mach-ns9xxx/irq.c index 37ab0a2b83ad..389fa5c669de 100644 --- a/trunk/arch/arm/mach-ns9xxx/irq.c +++ b/trunk/arch/arm/mach-ns9xxx/irq.c @@ -31,11 +31,17 @@ static void ns9xxx_mask_irq(struct irq_data *d) __raw_writel(ic, SYS_IC(prio / 4)); } -static void ns9xxx_eoi_irq(struct irq_data *d) +static void ns9xxx_ack_irq(struct irq_data *d) { __raw_writel(0, SYS_ISRADDR); } +static void ns9xxx_maskack_irq(struct irq_data *d) +{ + ns9xxx_mask_irq(d); + ns9xxx_ack_irq(d); +} + static void ns9xxx_unmask_irq(struct irq_data *d) { /* XXX: better use cpp symbols */ @@ -46,11 +52,56 @@ static void ns9xxx_unmask_irq(struct irq_data *d) } static struct irq_chip ns9xxx_chip = { - .irq_eoi = ns9xxx_eoi_irq, + .irq_ack = ns9xxx_ack_irq, .irq_mask = ns9xxx_mask_irq, + .irq_mask_ack = ns9xxx_maskack_irq, .irq_unmask = ns9xxx_unmask_irq, }; +#if 0 +#define handle_irq handle_level_irq +#else +static void handle_prio_irq(unsigned int irq, struct irq_desc *desc) +{ + struct irqaction *action; + irqreturn_t action_ret; + + raw_spin_lock(&desc->lock); + + BUG_ON(desc->status & IRQ_INPROGRESS); + + desc->status &= ~(IRQ_REPLAY | IRQ_WAITING); + kstat_incr_irqs_this_cpu(irq, desc); + + action = desc->action; + if (unlikely(!action || (desc->status & IRQ_DISABLED))) + goto out_mask; + + desc->status |= IRQ_INPROGRESS; + raw_spin_unlock(&desc->lock); + + action_ret = handle_IRQ_event(irq, action); + + /* XXX: There is no direct way to access noirqdebug, so check + * unconditionally for spurious irqs... + * Maybe this function should go to kernel/irq/chip.c? */ + note_interrupt(irq, desc, action_ret); + + raw_spin_lock(&desc->lock); + desc->status &= ~IRQ_INPROGRESS; + + if (desc->status & IRQ_DISABLED) +out_mask: + desc->irq_data.chip->irq_mask(&desc->irq_data); + + /* ack unconditionally to unmask lower prio irqs */ + desc->irq_data.chip->irq_ack(&desc->irq_data); + + raw_spin_unlock(&desc->lock); +} +#define handle_irq handle_prio_irq +#endif + void __init ns9xxx_init_irq(void) { int i; @@ -67,8 +118,8 @@ void __init ns9xxx_init_irq(void) __raw_writel(prio2irq(i), SYS_IVA(i)); for (i = 0; i <= 31; ++i) { - irq_set_chip_and_handler(i, &ns9xxx_chip, handle_fasteoi_irq); + set_irq_chip(i, &ns9xxx_chip); + set_irq_handler(i, handle_irq); set_irq_flags(i, IRQF_VALID); - irq_set_status_flags(i, IRQ_LEVEL); } } diff --git a/trunk/arch/arm/mach-nuc93x/irq.c b/trunk/arch/arm/mach-nuc93x/irq.c index aa279f23e342..1f8a05a22834 100644 --- a/trunk/arch/arm/mach-nuc93x/irq.c +++ b/trunk/arch/arm/mach-nuc93x/irq.c @@ -59,8 +59,8 @@ void __init nuc93x_init_irq(void) __raw_writel(0xFFFFFFFE, REG_AIC_MDCR); for (irqno = IRQ_WDT; irqno <= NR_IRQS; irqno++) { - irq_set_chip_and_handler(irqno, &nuc93x_irq_chip, - handle_level_irq); + set_irq_chip(irqno, &nuc93x_irq_chip); + set_irq_handler(irqno, handle_level_irq); set_irq_flags(irqno, IRQF_VALID); } } diff --git a/trunk/arch/arm/mach-omap1/board-osk.c b/trunk/arch/arm/mach-omap1/board-osk.c index e68dfde1918e..7c5e2112c776 100644 --- a/trunk/arch/arm/mach-omap1/board-osk.c +++ b/trunk/arch/arm/mach-omap1/board-osk.c @@ -276,7 +276,7 @@ static void __init osk_init_cf(void) return; } /* the CF I/O IRQ is really active-low */ - irq_set_irq_type(gpio_to_irq(62), IRQ_TYPE_EDGE_FALLING); + set_irq_type(gpio_to_irq(62), IRQ_TYPE_EDGE_FALLING); } static void __init osk_init_irq(void) @@ -482,7 +482,7 @@ static void __init osk_mistral_init(void) omap_cfg_reg(P20_1610_GPIO4); /* PENIRQ */ gpio_request(4, "ts_int"); gpio_direction_input(4); - irq_set_irq_type(gpio_to_irq(4), IRQ_TYPE_EDGE_FALLING); + set_irq_type(gpio_to_irq(4), IRQ_TYPE_EDGE_FALLING); spi_register_board_info(mistral_boardinfo, ARRAY_SIZE(mistral_boardinfo)); @@ -500,7 +500,7 @@ static void __init osk_mistral_init(void) int irq = gpio_to_irq(OMAP_MPUIO(2)); gpio_direction_input(OMAP_MPUIO(2)); - irq_set_irq_type(irq, IRQ_TYPE_EDGE_RISING); + set_irq_type(irq, IRQ_TYPE_EDGE_RISING); #ifdef CONFIG_PM /* share the IRQ in case someone wants to use the * button for more than wakeup from system sleep. diff --git a/trunk/arch/arm/mach-omap1/board-palmz71.c b/trunk/arch/arm/mach-omap1/board-palmz71.c index 45f01d2c3a7a..d7bbbe721a75 100644 --- a/trunk/arch/arm/mach-omap1/board-palmz71.c +++ b/trunk/arch/arm/mach-omap1/board-palmz71.c @@ -256,12 +256,12 @@ palmz71_powercable(int irq, void *dev_id) { if (gpio_get_value(PALMZ71_USBDETECT_GPIO)) { printk(KERN_INFO "PM: Power cable connected\n"); - irq_set_irq_type(gpio_to_irq(PALMZ71_USBDETECT_GPIO), - IRQ_TYPE_EDGE_FALLING); + set_irq_type(gpio_to_irq(PALMZ71_USBDETECT_GPIO), + IRQ_TYPE_EDGE_FALLING); } else { printk(KERN_INFO "PM: Power cable disconnected\n"); - irq_set_irq_type(gpio_to_irq(PALMZ71_USBDETECT_GPIO), - IRQ_TYPE_EDGE_RISING); + set_irq_type(gpio_to_irq(PALMZ71_USBDETECT_GPIO), + IRQ_TYPE_EDGE_RISING); } return IRQ_HANDLED; } diff --git a/trunk/arch/arm/mach-omap1/board-voiceblue.c b/trunk/arch/arm/mach-omap1/board-voiceblue.c index 65d24204937a..bdc0ac8dc21f 100644 --- a/trunk/arch/arm/mach-omap1/board-voiceblue.c +++ b/trunk/arch/arm/mach-omap1/board-voiceblue.c @@ -279,10 +279,10 @@ static void __init voiceblue_init(void) gpio_request(13, "16C554 irq"); gpio_request(14, "16C554 irq"); gpio_request(15, "16C554 irq"); - irq_set_irq_type(gpio_to_irq(12), IRQ_TYPE_EDGE_RISING); - irq_set_irq_type(gpio_to_irq(13), IRQ_TYPE_EDGE_RISING); - irq_set_irq_type(gpio_to_irq(14), IRQ_TYPE_EDGE_RISING); - irq_set_irq_type(gpio_to_irq(15), IRQ_TYPE_EDGE_RISING); + set_irq_type(gpio_to_irq(12), IRQ_TYPE_EDGE_RISING); + set_irq_type(gpio_to_irq(13), IRQ_TYPE_EDGE_RISING); + set_irq_type(gpio_to_irq(14), IRQ_TYPE_EDGE_RISING); + set_irq_type(gpio_to_irq(15), IRQ_TYPE_EDGE_RISING); platform_add_devices(voiceblue_devices, ARRAY_SIZE(voiceblue_devices)); omap_board_config = voiceblue_config; diff --git a/trunk/arch/arm/mach-omap1/fpga.c b/trunk/arch/arm/mach-omap1/fpga.c index cddbf8b089ce..0ace7998aaa5 100644 --- a/trunk/arch/arm/mach-omap1/fpga.c +++ b/trunk/arch/arm/mach-omap1/fpga.c @@ -156,17 +156,17 @@ void omap1510_fpga_init_irq(void) * The touchscreen interrupt is level-sensitive, so * we'll use the regular mask_ack routine for it. */ - irq_set_chip(i, &omap_fpga_irq_ack); + set_irq_chip(i, &omap_fpga_irq_ack); } else { /* * All FPGA interrupts except the touchscreen are * edge-sensitive, so we won't mask them. */ - irq_set_chip(i, &omap_fpga_irq); + set_irq_chip(i, &omap_fpga_irq); } - irq_set_handler(i, handle_edge_irq); + set_irq_handler(i, handle_edge_irq); set_irq_flags(i, IRQF_VALID); } @@ -183,6 +183,6 @@ void omap1510_fpga_init_irq(void) return; } gpio_direction_input(13); - irq_set_irq_type(gpio_to_irq(13), IRQ_TYPE_EDGE_RISING); - irq_set_chained_handler(OMAP1510_INT_FPGA, innovator_fpga_IRQ_demux); + set_irq_type(gpio_to_irq(13), IRQ_TYPE_EDGE_RISING); + set_irq_chained_handler(OMAP1510_INT_FPGA, innovator_fpga_IRQ_demux); } diff --git a/trunk/arch/arm/mach-omap1/irq.c b/trunk/arch/arm/mach-omap1/irq.c index 5d3da7a63af3..731dd33bff51 100644 --- a/trunk/arch/arm/mach-omap1/irq.c +++ b/trunk/arch/arm/mach-omap1/irq.c @@ -230,8 +230,8 @@ void __init omap_init_irq(void) irq_trigger = irq_banks[i].trigger_map >> IRQ_BIT(j); omap_irq_set_cfg(j, 0, 0, irq_trigger); - irq_set_chip_and_handler(j, &omap_irq_chip, - handle_level_irq); + set_irq_chip(j, &omap_irq_chip); + set_irq_handler(j, handle_level_irq); set_irq_flags(j, IRQF_VALID); } } diff --git a/trunk/arch/arm/mach-omap2/board-omap4panda.c b/trunk/arch/arm/mach-omap2/board-omap4panda.c index f3a7b1011914..c936c6d7ded0 100644 --- a/trunk/arch/arm/mach-omap2/board-omap4panda.c +++ b/trunk/arch/arm/mach-omap2/board-omap4panda.c @@ -285,6 +285,19 @@ static int __init omap4_twl6030_hsmmc_init(struct omap2_hsmmc_info *controllers) return 0; } +static struct regulator_init_data omap4_panda_vaux1 = { + .constraints = { + .min_uV = 1000000, + .max_uV = 3000000, + .apply_uV = true, + .valid_modes_mask = REGULATOR_MODE_NORMAL + | REGULATOR_MODE_STANDBY, + .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE + | REGULATOR_CHANGE_MODE + | REGULATOR_CHANGE_STATUS, + }, +}; + static struct regulator_init_data omap4_panda_vaux2 = { .constraints = { .min_uV = 1200000, @@ -340,6 +353,19 @@ static struct regulator_init_data omap4_panda_vpp = { }, }; +static struct regulator_init_data omap4_panda_vusim = { + .constraints = { + .min_uV = 1200000, + .max_uV = 2900000, + .apply_uV = true, + .valid_modes_mask = REGULATOR_MODE_NORMAL + | REGULATOR_MODE_STANDBY, + .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE + | REGULATOR_CHANGE_MODE + | REGULATOR_CHANGE_STATUS, + }, +}; + static struct regulator_init_data omap4_panda_vana = { .constraints = { .min_uV = 2100000, @@ -398,10 +424,12 @@ static struct twl4030_platform_data omap4_panda_twldata = { /* Regulators */ .vmmc = &omap4_panda_vmmc, .vpp = &omap4_panda_vpp, + .vusim = &omap4_panda_vusim, .vana = &omap4_panda_vana, .vcxio = &omap4_panda_vcxio, .vdac = &omap4_panda_vdac, .vusb = &omap4_panda_vusb, + .vaux1 = &omap4_panda_vaux1, .vaux2 = &omap4_panda_vaux2, .vaux3 = &omap4_panda_vaux3, .clk32kg = &omap4_panda_clk32kg, diff --git a/trunk/arch/arm/mach-omap2/devices.c b/trunk/arch/arm/mach-omap2/devices.c index 84d1b735fe80..e97851492847 100644 --- a/trunk/arch/arm/mach-omap2/devices.c +++ b/trunk/arch/arm/mach-omap2/devices.c @@ -66,7 +66,7 @@ static int __init omap3_l3_init(void) WARN(IS_ERR(od), "could not build omap_device for %s\n", oh_name); - return IS_ERR(od) ? PTR_ERR(od) : 0; + return PTR_ERR(od); } postcore_initcall(omap3_l3_init); diff --git a/trunk/arch/arm/mach-omap2/gpmc.c b/trunk/arch/arm/mach-omap2/gpmc.c index 130034bf01d5..674174365f78 100644 --- a/trunk/arch/arm/mach-omap2/gpmc.c +++ b/trunk/arch/arm/mach-omap2/gpmc.c @@ -693,7 +693,6 @@ static int __init gpmc_init(void) { u32 l, irq; int cs, ret = -EINVAL; - int gpmc_irq; char *ck = NULL; if (cpu_is_omap24xx()) { @@ -702,15 +701,12 @@ static int __init gpmc_init(void) l = OMAP2420_GPMC_BASE; else l = OMAP34XX_GPMC_BASE; - gpmc_irq = INT_34XX_GPMC_IRQ; } else if (cpu_is_omap34xx()) { ck = "gpmc_fck"; l = OMAP34XX_GPMC_BASE; - gpmc_irq = INT_34XX_GPMC_IRQ; } else if (cpu_is_omap44xx()) { ck = "gpmc_ck"; l = OMAP44XX_GPMC_BASE; - gpmc_irq = OMAP44XX_IRQ_GPMC; } if (WARN_ON(!ck)) @@ -743,17 +739,16 @@ static int __init gpmc_init(void) /* initalize the irq_chained */ irq = OMAP_GPMC_IRQ_BASE; for (cs = 0; cs < GPMC_CS_NUM; cs++) { - irq_set_chip_and_handler(irq, &dummy_irq_chip, - handle_simple_irq); + set_irq_handler(irq, handle_simple_irq); set_irq_flags(irq, IRQF_VALID); irq++; } - ret = request_irq(gpmc_irq, + ret = request_irq(INT_34XX_GPMC_IRQ, gpmc_handle_irq, IRQF_SHARED, "gpmc", gpmc_base); if (ret) pr_err("gpmc: irq-%d could not claim: err %d\n", - gpmc_irq, ret); + INT_34XX_GPMC_IRQ, ret); return ret; } postcore_initcall(gpmc_init); @@ -762,6 +757,8 @@ static irqreturn_t gpmc_handle_irq(int irq, void *dev) { u8 cs; + if (irq != INT_34XX_GPMC_IRQ) + return IRQ_HANDLED; /* check cs to invoke the irq */ cs = ((gpmc_read_reg(GPMC_PREFETCH_CONFIG1)) >> CS_NUM_SHIFT) & 0x7; if (OMAP_GPMC_IRQ_BASE+cs <= OMAP_GPMC_IRQ_END) diff --git a/trunk/arch/arm/mach-omap2/irq.c b/trunk/arch/arm/mach-omap2/irq.c index 237e4530abf2..bc524b94fd59 100644 --- a/trunk/arch/arm/mach-omap2/irq.c +++ b/trunk/arch/arm/mach-omap2/irq.c @@ -223,7 +223,8 @@ void __init omap_init_irq(void) nr_of_irqs, nr_banks, nr_banks > 1 ? "s" : ""); for (i = 0; i < nr_of_irqs; i++) { - irq_set_chip_and_handler(i, &omap_irq_chip, handle_level_irq); + set_irq_chip(i, &omap_irq_chip); + set_irq_handler(i, handle_level_irq); set_irq_flags(i, IRQF_VALID); } } diff --git a/trunk/arch/arm/mach-omap2/omap_l3_smx.c b/trunk/arch/arm/mach-omap2/omap_l3_smx.c index 5f2da7565b68..265bff3acb9e 100644 --- a/trunk/arch/arm/mach-omap2/omap_l3_smx.c +++ b/trunk/arch/arm/mach-omap2/omap_l3_smx.c @@ -226,6 +226,7 @@ static int __init omap3_l3_probe(struct platform_device *pdev) struct omap3_l3 *l3; struct resource *res; int ret; + int irq; l3 = kzalloc(sizeof(*l3), GFP_KERNEL); if (!l3) { @@ -248,17 +249,18 @@ static int __init omap3_l3_probe(struct platform_device *pdev) goto err2; } - l3->debug_irq = platform_get_irq(pdev, 0); - ret = request_irq(l3->debug_irq, omap3_l3_app_irq, + irq = platform_get_irq(pdev, 0); + ret = request_irq(irq, omap3_l3_app_irq, IRQF_DISABLED | IRQF_TRIGGER_RISING, "l3-debug-irq", l3); if (ret) { dev_err(&pdev->dev, "couldn't request debug irq\n"); goto err3; } + l3->debug_irq = irq; - l3->app_irq = platform_get_irq(pdev, 1); - ret = request_irq(l3->app_irq, omap3_l3_app_irq, + irq = platform_get_irq(pdev, 1); + ret = request_irq(irq, omap3_l3_app_irq, IRQF_DISABLED | IRQF_TRIGGER_RISING, "l3-app-irq", l3); @@ -267,6 +269,7 @@ static int __init omap3_l3_probe(struct platform_device *pdev) goto err4; } + l3->app_irq = irq; goto err0; err4: diff --git a/trunk/arch/arm/mach-orion5x/db88f5281-setup.c b/trunk/arch/arm/mach-orion5x/db88f5281-setup.c index b7d4591214e0..c10a11715376 100644 --- a/trunk/arch/arm/mach-orion5x/db88f5281-setup.c +++ b/trunk/arch/arm/mach-orion5x/db88f5281-setup.c @@ -213,7 +213,7 @@ void __init db88f5281_pci_preinit(void) pin = DB88F5281_PCI_SLOT0_IRQ_PIN; if (gpio_request(pin, "PCI Int1") == 0) { if (gpio_direction_input(pin) == 0) { - irq_set_irq_type(gpio_to_irq(pin), IRQ_TYPE_LEVEL_LOW); + set_irq_type(gpio_to_irq(pin), IRQ_TYPE_LEVEL_LOW); } else { printk(KERN_ERR "db88f5281_pci_preinit faield to " "set_irq_type pin %d\n", pin); @@ -226,7 +226,7 @@ void __init db88f5281_pci_preinit(void) pin = DB88F5281_PCI_SLOT1_SLOT2_IRQ_PIN; if (gpio_request(pin, "PCI Int2") == 0) { if (gpio_direction_input(pin) == 0) { - irq_set_irq_type(gpio_to_irq(pin), IRQ_TYPE_LEVEL_LOW); + set_irq_type(gpio_to_irq(pin), IRQ_TYPE_LEVEL_LOW); } else { printk(KERN_ERR "db88f5281_pci_preinit faield " "to set_irq_type pin %d\n", pin); diff --git a/trunk/arch/arm/mach-orion5x/irq.c b/trunk/arch/arm/mach-orion5x/irq.c index 43cf8bc9767b..ed85891f8699 100644 --- a/trunk/arch/arm/mach-orion5x/irq.c +++ b/trunk/arch/arm/mach-orion5x/irq.c @@ -34,8 +34,8 @@ void __init orion5x_init_irq(void) * Initialize gpiolib for GPIOs 0-31. */ orion_gpio_init(0, 32, GPIO_VIRT_BASE, 0, IRQ_ORION5X_GPIO_START); - irq_set_chained_handler(IRQ_ORION5X_GPIO_0_7, gpio_irq_handler); - irq_set_chained_handler(IRQ_ORION5X_GPIO_8_15, gpio_irq_handler); - irq_set_chained_handler(IRQ_ORION5X_GPIO_16_23, gpio_irq_handler); - irq_set_chained_handler(IRQ_ORION5X_GPIO_24_31, gpio_irq_handler); + set_irq_chained_handler(IRQ_ORION5X_GPIO_0_7, gpio_irq_handler); + set_irq_chained_handler(IRQ_ORION5X_GPIO_8_15, gpio_irq_handler); + set_irq_chained_handler(IRQ_ORION5X_GPIO_16_23, gpio_irq_handler); + set_irq_chained_handler(IRQ_ORION5X_GPIO_24_31, gpio_irq_handler); } diff --git a/trunk/arch/arm/mach-orion5x/rd88f5182-setup.c b/trunk/arch/arm/mach-orion5x/rd88f5182-setup.c index 4fc46772a087..67ec6959b267 100644 --- a/trunk/arch/arm/mach-orion5x/rd88f5182-setup.c +++ b/trunk/arch/arm/mach-orion5x/rd88f5182-setup.c @@ -148,7 +148,7 @@ void __init rd88f5182_pci_preinit(void) pin = RD88F5182_PCI_SLOT0_IRQ_A_PIN; if (gpio_request(pin, "PCI IntA") == 0) { if (gpio_direction_input(pin) == 0) { - irq_set_irq_type(gpio_to_irq(pin), IRQ_TYPE_LEVEL_LOW); + set_irq_type(gpio_to_irq(pin), IRQ_TYPE_LEVEL_LOW); } else { printk(KERN_ERR "rd88f5182_pci_preinit faield to " "set_irq_type pin %d\n", pin); @@ -161,7 +161,7 @@ void __init rd88f5182_pci_preinit(void) pin = RD88F5182_PCI_SLOT0_IRQ_B_PIN; if (gpio_request(pin, "PCI IntB") == 0) { if (gpio_direction_input(pin) == 0) { - irq_set_irq_type(gpio_to_irq(pin), IRQ_TYPE_LEVEL_LOW); + set_irq_type(gpio_to_irq(pin), IRQ_TYPE_LEVEL_LOW); } else { printk(KERN_ERR "rd88f5182_pci_preinit faield to " "set_irq_type pin %d\n", pin); diff --git a/trunk/arch/arm/mach-orion5x/terastation_pro2-setup.c b/trunk/arch/arm/mach-orion5x/terastation_pro2-setup.c index 616004143912..5653ee6c71d8 100644 --- a/trunk/arch/arm/mach-orion5x/terastation_pro2-setup.c +++ b/trunk/arch/arm/mach-orion5x/terastation_pro2-setup.c @@ -88,7 +88,7 @@ void __init tsp2_pci_preinit(void) pin = TSP2_PCI_SLOT0_IRQ_PIN; if (gpio_request(pin, "PCI Int1") == 0) { if (gpio_direction_input(pin) == 0) { - irq_set_irq_type(gpio_to_irq(pin), IRQ_TYPE_LEVEL_LOW); + set_irq_type(gpio_to_irq(pin), IRQ_TYPE_LEVEL_LOW); } else { printk(KERN_ERR "tsp2_pci_preinit failed " "to set_irq_type pin %d\n", pin); diff --git a/trunk/arch/arm/mach-orion5x/ts209-setup.c b/trunk/arch/arm/mach-orion5x/ts209-setup.c index f0f43e13ac87..8bbd27ea6735 100644 --- a/trunk/arch/arm/mach-orion5x/ts209-setup.c +++ b/trunk/arch/arm/mach-orion5x/ts209-setup.c @@ -117,7 +117,7 @@ void __init qnap_ts209_pci_preinit(void) pin = QNAP_TS209_PCI_SLOT0_IRQ_PIN; if (gpio_request(pin, "PCI Int1") == 0) { if (gpio_direction_input(pin) == 0) { - irq_set_irq_type(gpio_to_irq(pin), IRQ_TYPE_LEVEL_LOW); + set_irq_type(gpio_to_irq(pin), IRQ_TYPE_LEVEL_LOW); } else { printk(KERN_ERR "qnap_ts209_pci_preinit failed to " "set_irq_type pin %d\n", pin); @@ -131,7 +131,7 @@ void __init qnap_ts209_pci_preinit(void) pin = QNAP_TS209_PCI_SLOT1_IRQ_PIN; if (gpio_request(pin, "PCI Int2") == 0) { if (gpio_direction_input(pin) == 0) { - irq_set_irq_type(gpio_to_irq(pin), IRQ_TYPE_LEVEL_LOW); + set_irq_type(gpio_to_irq(pin), IRQ_TYPE_LEVEL_LOW); } else { printk(KERN_ERR "qnap_ts209_pci_preinit failed " "to set_irq_type pin %d\n", pin); diff --git a/trunk/arch/arm/mach-pnx4008/irq.c b/trunk/arch/arm/mach-pnx4008/irq.c index 7608c7a288cf..c69c180aec76 100644 --- a/trunk/arch/arm/mach-pnx4008/irq.c +++ b/trunk/arch/arm/mach-pnx4008/irq.c @@ -58,22 +58,22 @@ static int pnx4008_set_irq_type(struct irq_data *d, unsigned int type) case IRQ_TYPE_EDGE_RISING: __raw_writel(__raw_readl(INTC_ATR(d->irq)) | INTC_BIT(d->irq), INTC_ATR(d->irq)); /*edge sensitive */ __raw_writel(__raw_readl(INTC_APR(d->irq)) | INTC_BIT(d->irq), INTC_APR(d->irq)); /*rising edge */ - irq_set_handler(d->irq, handle_edge_irq); + set_irq_handler(d->irq, handle_edge_irq); break; case IRQ_TYPE_EDGE_FALLING: __raw_writel(__raw_readl(INTC_ATR(d->irq)) | INTC_BIT(d->irq), INTC_ATR(d->irq)); /*edge sensitive */ __raw_writel(__raw_readl(INTC_APR(d->irq)) & ~INTC_BIT(d->irq), INTC_APR(d->irq)); /*falling edge */ - irq_set_handler(d->irq, handle_edge_irq); + set_irq_handler(d->irq, handle_edge_irq); break; case IRQ_TYPE_LEVEL_LOW: __raw_writel(__raw_readl(INTC_ATR(d->irq)) & ~INTC_BIT(d->irq), INTC_ATR(d->irq)); /*level sensitive */ __raw_writel(__raw_readl(INTC_APR(d->irq)) & ~INTC_BIT(d->irq), INTC_APR(d->irq)); /*low level */ - irq_set_handler(d->irq, handle_level_irq); + set_irq_handler(d->irq, handle_level_irq); break; case IRQ_TYPE_LEVEL_HIGH: __raw_writel(__raw_readl(INTC_ATR(d->irq)) & ~INTC_BIT(d->irq), INTC_ATR(d->irq)); /*level sensitive */ __raw_writel(__raw_readl(INTC_APR(d->irq)) | INTC_BIT(d->irq), INTC_APR(d->irq)); /* high level */ - irq_set_handler(d->irq, handle_level_irq); + set_irq_handler(d->irq, handle_level_irq); break; /* IRQ_TYPE_EDGE_BOTH is not supported */ @@ -98,7 +98,7 @@ void __init pnx4008_init_irq(void) /* configure IRQ's */ for (i = 0; i < NR_IRQS; i++) { set_irq_flags(i, IRQF_VALID); - irq_set_chip(i, &pnx4008_irq_chip); + set_irq_chip(i, &pnx4008_irq_chip); pnx4008_set_irq_type(irq_get_irq_data(i), pnx4008_irq_type[i]); } diff --git a/trunk/arch/arm/mach-pxa/balloon3.c b/trunk/arch/arm/mach-pxa/balloon3.c index 38dea05df7f8..d2af73321dae 100644 --- a/trunk/arch/arm/mach-pxa/balloon3.c +++ b/trunk/arch/arm/mach-pxa/balloon3.c @@ -527,13 +527,13 @@ static void __init balloon3_init_irq(void) pxa27x_init_irq(); /* setup extra Balloon3 irqs */ for (irq = BALLOON3_IRQ(0); irq <= BALLOON3_IRQ(7); irq++) { - irq_set_chip_and_handler(irq, &balloon3_irq_chip, - handle_level_irq); + set_irq_chip(irq, &balloon3_irq_chip); + set_irq_handler(irq, handle_level_irq); set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); } - irq_set_chained_handler(BALLOON3_AUX_NIRQ, balloon3_irq_handler); - irq_set_irq_type(BALLOON3_AUX_NIRQ, IRQ_TYPE_EDGE_FALLING); + set_irq_chained_handler(BALLOON3_AUX_NIRQ, balloon3_irq_handler); + set_irq_type(BALLOON3_AUX_NIRQ, IRQ_TYPE_EDGE_FALLING); pr_debug("%s: chained handler installed - irq %d automatically " "enabled\n", __func__, BALLOON3_AUX_NIRQ); diff --git a/trunk/arch/arm/mach-pxa/cm-x2xx-pci.c b/trunk/arch/arm/mach-pxa/cm-x2xx-pci.c index 8b1a30959fae..a2380cd76f80 100644 --- a/trunk/arch/arm/mach-pxa/cm-x2xx-pci.c +++ b/trunk/arch/arm/mach-pxa/cm-x2xx-pci.c @@ -70,10 +70,9 @@ void __cmx2xx_pci_init_irq(int irq_gpio) cmx2xx_it8152_irq_gpio = irq_gpio; - irq_set_irq_type(gpio_to_irq(irq_gpio), IRQ_TYPE_EDGE_RISING); + set_irq_type(gpio_to_irq(irq_gpio), IRQ_TYPE_EDGE_RISING); - irq_set_chained_handler(gpio_to_irq(irq_gpio), - cmx2xx_it8152_irq_demux); + set_irq_chained_handler(gpio_to_irq(irq_gpio), cmx2xx_it8152_irq_demux); } #ifdef CONFIG_PM diff --git a/trunk/arch/arm/mach-pxa/cm-x300.c b/trunk/arch/arm/mach-pxa/cm-x300.c index 06d0a03f462d..bfca7ed2fea3 100644 --- a/trunk/arch/arm/mach-pxa/cm-x300.c +++ b/trunk/arch/arm/mach-pxa/cm-x300.c @@ -765,7 +765,7 @@ static void __init cm_x300_init_da9030(void) { pxa3xx_set_i2c_power_info(&cm_x300_pwr_i2c_info); i2c_register_board_info(1, &cm_x300_pmic_info, 1); - irq_set_irq_wake(IRQ_WAKEUP0, 1); + set_irq_wake(IRQ_WAKEUP0, 1); } static void __init cm_x300_init_wi2wi(void) diff --git a/trunk/arch/arm/mach-pxa/irq.c b/trunk/arch/arm/mach-pxa/irq.c index 6251e3f5c62c..2693e3c3776f 100644 --- a/trunk/arch/arm/mach-pxa/irq.c +++ b/trunk/arch/arm/mach-pxa/irq.c @@ -137,9 +137,9 @@ static void __init pxa_init_low_gpio_irq(set_wake_t fn) GEDR0 = 0x3; for (irq = IRQ_GPIO0; irq <= IRQ_GPIO1; irq++) { - irq_set_chip_and_handler(irq, &pxa_low_gpio_chip, - handle_edge_irq); - irq_set_chip_data(irq, irq_base(0)); + set_irq_chip(irq, &pxa_low_gpio_chip); + set_irq_chip_data(irq, irq_base(0)); + set_irq_handler(irq, handle_edge_irq); set_irq_flags(irq, IRQF_VALID); } @@ -165,9 +165,9 @@ void __init pxa_init_irq(int irq_nr, set_wake_t fn) __raw_writel(i | IPR_VALID, IRQ_BASE + IPR(i)); irq = PXA_IRQ(i); - irq_set_chip_and_handler(irq, &pxa_internal_irq_chip, - handle_level_irq); - irq_set_chip_data(irq, base); + set_irq_chip(irq, &pxa_internal_irq_chip); + set_irq_chip_data(irq, base); + set_irq_handler(irq, handle_level_irq); set_irq_flags(irq, IRQF_VALID); } } diff --git a/trunk/arch/arm/mach-pxa/lpd270.c b/trunk/arch/arm/mach-pxa/lpd270.c index 6307f70ae22a..c9a3e775c2de 100644 --- a/trunk/arch/arm/mach-pxa/lpd270.c +++ b/trunk/arch/arm/mach-pxa/lpd270.c @@ -149,12 +149,12 @@ static void __init lpd270_init_irq(void) /* setup extra LogicPD PXA270 irqs */ for (irq = LPD270_IRQ(2); irq <= LPD270_IRQ(4); irq++) { - irq_set_chip_and_handler(irq, &lpd270_irq_chip, - handle_level_irq); + set_irq_chip(irq, &lpd270_irq_chip); + set_irq_handler(irq, handle_level_irq); set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); } - irq_set_chained_handler(IRQ_GPIO(0), lpd270_irq_handler); - irq_set_irq_type(IRQ_GPIO(0), IRQ_TYPE_EDGE_FALLING); + set_irq_chained_handler(IRQ_GPIO(0), lpd270_irq_handler); + set_irq_type(IRQ_GPIO(0), IRQ_TYPE_EDGE_FALLING); } diff --git a/trunk/arch/arm/mach-pxa/lubbock.c b/trunk/arch/arm/mach-pxa/lubbock.c index 0fea945dd6f2..dca20de306bb 100644 --- a/trunk/arch/arm/mach-pxa/lubbock.c +++ b/trunk/arch/arm/mach-pxa/lubbock.c @@ -165,13 +165,13 @@ static void __init lubbock_init_irq(void) /* setup extra lubbock irqs */ for (irq = LUBBOCK_IRQ(0); irq <= LUBBOCK_LAST_IRQ; irq++) { - irq_set_chip_and_handler(irq, &lubbock_irq_chip, - handle_level_irq); + set_irq_chip(irq, &lubbock_irq_chip); + set_irq_handler(irq, handle_level_irq); set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); } - irq_set_chained_handler(IRQ_GPIO(0), lubbock_irq_handler); - irq_set_irq_type(IRQ_GPIO(0), IRQ_TYPE_EDGE_FALLING); + set_irq_chained_handler(IRQ_GPIO(0), lubbock_irq_handler); + set_irq_type(IRQ_GPIO(0), IRQ_TYPE_EDGE_FALLING); } #ifdef CONFIG_PM diff --git a/trunk/arch/arm/mach-pxa/mainstone.c b/trunk/arch/arm/mach-pxa/mainstone.c index 29b6e7a94e11..f9542220595a 100644 --- a/trunk/arch/arm/mach-pxa/mainstone.c +++ b/trunk/arch/arm/mach-pxa/mainstone.c @@ -166,8 +166,8 @@ static void __init mainstone_init_irq(void) /* setup extra Mainstone irqs */ for(irq = MAINSTONE_IRQ(0); irq <= MAINSTONE_IRQ(15); irq++) { - irq_set_chip_and_handler(irq, &mainstone_irq_chip, - handle_level_irq); + set_irq_chip(irq, &mainstone_irq_chip); + set_irq_handler(irq, handle_level_irq); if (irq == MAINSTONE_IRQ(10) || irq == MAINSTONE_IRQ(14)) set_irq_flags(irq, IRQF_VALID | IRQF_PROBE | IRQF_NOAUTOEN); else @@ -179,8 +179,8 @@ static void __init mainstone_init_irq(void) MST_INTMSKENA = 0; MST_INTSETCLR = 0; - irq_set_chained_handler(IRQ_GPIO(0), mainstone_irq_handler); - irq_set_irq_type(IRQ_GPIO(0), IRQ_TYPE_EDGE_FALLING); + set_irq_chained_handler(IRQ_GPIO(0), mainstone_irq_handler); + set_irq_type(IRQ_GPIO(0), IRQ_TYPE_EDGE_FALLING); } #ifdef CONFIG_PM diff --git a/trunk/arch/arm/mach-pxa/pcm990-baseboard.c b/trunk/arch/arm/mach-pxa/pcm990-baseboard.c index 4d0120540124..9dbf3ccd4150 100644 --- a/trunk/arch/arm/mach-pxa/pcm990-baseboard.c +++ b/trunk/arch/arm/mach-pxa/pcm990-baseboard.c @@ -281,16 +281,16 @@ static void __init pcm990_init_irq(void) /* setup extra PCM990 irqs */ for (irq = PCM027_IRQ(0); irq <= PCM027_IRQ(3); irq++) { - irq_set_chip_and_handler(irq, &pcm990_irq_chip, - handle_level_irq); + set_irq_chip(irq, &pcm990_irq_chip); + set_irq_handler(irq, handle_level_irq); set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); } PCM990_INTMSKENA = 0x00; /* disable all Interrupts */ PCM990_INTSETCLR = 0xFF; - irq_set_chained_handler(PCM990_CTRL_INT_IRQ, pcm990_irq_handler); - irq_set_irq_type(PCM990_CTRL_INT_IRQ, PCM990_CTRL_INT_IRQ_EDGE); + set_irq_chained_handler(PCM990_CTRL_INT_IRQ, pcm990_irq_handler); + set_irq_type(PCM990_CTRL_INT_IRQ, PCM990_CTRL_INT_IRQ_EDGE); } static int pcm990_mci_init(struct device *dev, irq_handler_t mci_detect_int, diff --git a/trunk/arch/arm/mach-pxa/pxa3xx.c b/trunk/arch/arm/mach-pxa/pxa3xx.c index 8dd107391157..f374247b8466 100644 --- a/trunk/arch/arm/mach-pxa/pxa3xx.c +++ b/trunk/arch/arm/mach-pxa/pxa3xx.c @@ -362,8 +362,8 @@ static void __init pxa_init_ext_wakeup_irq(set_wake_t fn) int irq; for (irq = IRQ_WAKEUP0; irq <= IRQ_WAKEUP1; irq++) { - irq_set_chip_and_handler(irq, &pxa_ext_wakeup_chip, - handle_edge_irq); + set_irq_chip(irq, &pxa_ext_wakeup_chip); + set_irq_handler(irq, handle_edge_irq); set_irq_flags(irq, IRQF_VALID); } diff --git a/trunk/arch/arm/mach-pxa/viper.c b/trunk/arch/arm/mach-pxa/viper.c index aa70331c0805..12279214c875 100644 --- a/trunk/arch/arm/mach-pxa/viper.c +++ b/trunk/arch/arm/mach-pxa/viper.c @@ -310,14 +310,14 @@ static void __init viper_init_irq(void) /* setup ISA IRQs */ for (level = 0; level < ARRAY_SIZE(viper_isa_irqs); level++) { isa_irq = viper_bit_to_irq(level); - irq_set_chip_and_handler(isa_irq, &viper_irq_chip, - handle_edge_irq); + set_irq_chip(isa_irq, &viper_irq_chip); + set_irq_handler(isa_irq, handle_edge_irq); set_irq_flags(isa_irq, IRQF_VALID | IRQF_PROBE); } - irq_set_chained_handler(gpio_to_irq(VIPER_CPLD_GPIO), + set_irq_chained_handler(gpio_to_irq(VIPER_CPLD_GPIO), viper_irq_handler); - irq_set_irq_type(gpio_to_irq(VIPER_CPLD_GPIO), IRQ_TYPE_EDGE_BOTH); + set_irq_type(gpio_to_irq(VIPER_CPLD_GPIO), IRQ_TYPE_EDGE_BOTH); } /* Flat Panel */ diff --git a/trunk/arch/arm/mach-pxa/zeus.c b/trunk/arch/arm/mach-pxa/zeus.c index 139aa7f2ed90..730f51e57c17 100644 --- a/trunk/arch/arm/mach-pxa/zeus.c +++ b/trunk/arch/arm/mach-pxa/zeus.c @@ -136,23 +136,22 @@ static void __init zeus_init_irq(void) /* Peripheral IRQs. It would be nice to move those inside driver configuration, but it is not supported at the moment. */ - irq_set_irq_type(gpio_to_irq(ZEUS_AC97_GPIO), IRQ_TYPE_EDGE_RISING); - irq_set_irq_type(gpio_to_irq(ZEUS_WAKEUP_GPIO), IRQ_TYPE_EDGE_RISING); - irq_set_irq_type(gpio_to_irq(ZEUS_PTT_GPIO), IRQ_TYPE_EDGE_RISING); - irq_set_irq_type(gpio_to_irq(ZEUS_EXTGPIO_GPIO), - IRQ_TYPE_EDGE_FALLING); - irq_set_irq_type(gpio_to_irq(ZEUS_CAN_GPIO), IRQ_TYPE_EDGE_FALLING); + set_irq_type(gpio_to_irq(ZEUS_AC97_GPIO), IRQ_TYPE_EDGE_RISING); + set_irq_type(gpio_to_irq(ZEUS_WAKEUP_GPIO), IRQ_TYPE_EDGE_RISING); + set_irq_type(gpio_to_irq(ZEUS_PTT_GPIO), IRQ_TYPE_EDGE_RISING); + set_irq_type(gpio_to_irq(ZEUS_EXTGPIO_GPIO), IRQ_TYPE_EDGE_FALLING); + set_irq_type(gpio_to_irq(ZEUS_CAN_GPIO), IRQ_TYPE_EDGE_FALLING); /* Setup ISA IRQs */ for (level = 0; level < ARRAY_SIZE(zeus_isa_irqs); level++) { isa_irq = zeus_bit_to_irq(level); - irq_set_chip_and_handler(isa_irq, &zeus_irq_chip, - handle_edge_irq); + set_irq_chip(isa_irq, &zeus_irq_chip); + set_irq_handler(isa_irq, handle_edge_irq); set_irq_flags(isa_irq, IRQF_VALID | IRQF_PROBE); } - irq_set_irq_type(gpio_to_irq(ZEUS_ISA_GPIO), IRQ_TYPE_EDGE_RISING); - irq_set_chained_handler(gpio_to_irq(ZEUS_ISA_GPIO), zeus_irq_handler); + set_irq_type(gpio_to_irq(ZEUS_ISA_GPIO), IRQ_TYPE_EDGE_RISING); + set_irq_chained_handler(gpio_to_irq(ZEUS_ISA_GPIO), zeus_irq_handler); } diff --git a/trunk/arch/arm/mach-rpc/irq.c b/trunk/arch/arm/mach-rpc/irq.c index 2e1b5309fbab..d29cd9b737fc 100644 --- a/trunk/arch/arm/mach-rpc/irq.c +++ b/trunk/arch/arm/mach-rpc/irq.c @@ -133,25 +133,25 @@ void __init rpc_init_irq(void) switch (irq) { case 0 ... 7: - irq_set_chip_and_handler(irq, &iomd_a_chip, - handle_level_irq); + set_irq_chip(irq, &iomd_a_chip); + set_irq_handler(irq, handle_level_irq); set_irq_flags(irq, flags); break; case 8 ... 15: - irq_set_chip_and_handler(irq, &iomd_b_chip, - handle_level_irq); + set_irq_chip(irq, &iomd_b_chip); + set_irq_handler(irq, handle_level_irq); set_irq_flags(irq, flags); break; case 16 ... 21: - irq_set_chip_and_handler(irq, &iomd_dma_chip, - handle_level_irq); + set_irq_chip(irq, &iomd_dma_chip); + set_irq_handler(irq, handle_level_irq); set_irq_flags(irq, flags); break; case 64 ... 71: - irq_set_chip(irq, &iomd_fiq_chip); + set_irq_chip(irq, &iomd_fiq_chip); set_irq_flags(irq, IRQF_VALID); break; } diff --git a/trunk/arch/arm/mach-s3c2410/bast-irq.c b/trunk/arch/arm/mach-s3c2410/bast-irq.c index bc53d2d16d1a..606cb6b1cc47 100644 --- a/trunk/arch/arm/mach-s3c2410/bast-irq.c +++ b/trunk/arch/arm/mach-s3c2410/bast-irq.c @@ -147,15 +147,15 @@ static __init int bast_irq_init(void) __raw_writeb(0x0, BAST_VA_PC104_IRQMASK); - irq_set_chained_handler(IRQ_ISA, bast_irq_pc104_demux); + set_irq_chained_handler(IRQ_ISA, bast_irq_pc104_demux); /* register our IRQs */ for (i = 0; i < 4; i++) { unsigned int irqno = bast_pc104_irqs[i]; - irq_set_chip_and_handler(irqno, &bast_pc104_chip, - handle_level_irq); + set_irq_chip(irqno, &bast_pc104_chip); + set_irq_handler(irqno, handle_level_irq); set_irq_flags(irqno, IRQF_VALID); } } diff --git a/trunk/arch/arm/mach-s3c2412/irq.c b/trunk/arch/arm/mach-s3c2412/irq.c index f3355d2ec634..eddb52ba5b65 100644 --- a/trunk/arch/arm/mach-s3c2412/irq.c +++ b/trunk/arch/arm/mach-s3c2412/irq.c @@ -175,18 +175,18 @@ static int s3c2412_irq_add(struct sys_device *sysdev) unsigned int irqno; for (irqno = IRQ_EINT0; irqno <= IRQ_EINT3; irqno++) { - irq_set_chip_and_handler(irqno, &s3c2412_irq_eint0t4, - handle_edge_irq); + set_irq_chip(irqno, &s3c2412_irq_eint0t4); + set_irq_handler(irqno, handle_edge_irq); set_irq_flags(irqno, IRQF_VALID); } /* add demux support for CF/SDI */ - irq_set_chained_handler(IRQ_S3C2412_CFSDI, s3c2412_irq_demux_cfsdi); + set_irq_chained_handler(IRQ_S3C2412_CFSDI, s3c2412_irq_demux_cfsdi); for (irqno = IRQ_S3C2412_SDI; irqno <= IRQ_S3C2412_CF; irqno++) { - irq_set_chip_and_handler(irqno, &s3c2412_irq_cfsdi, - handle_level_irq); + set_irq_chip(irqno, &s3c2412_irq_cfsdi); + set_irq_handler(irqno, handle_level_irq); set_irq_flags(irqno, IRQF_VALID); } @@ -195,7 +195,7 @@ static int s3c2412_irq_add(struct sys_device *sysdev) s3c2412_irq_rtc_chip = s3c_irq_chip; s3c2412_irq_rtc_chip.irq_set_wake = s3c2412_irq_rtc_wake; - irq_set_chip(IRQ_RTC, &s3c2412_irq_rtc_chip); + set_irq_chip(IRQ_RTC, &s3c2412_irq_rtc_chip); return 0; } diff --git a/trunk/arch/arm/mach-s3c2416/irq.c b/trunk/arch/arm/mach-s3c2416/irq.c index 77b38f2381c1..680fe386aca5 100644 --- a/trunk/arch/arm/mach-s3c2416/irq.c +++ b/trunk/arch/arm/mach-s3c2416/irq.c @@ -202,11 +202,13 @@ static int __init s3c2416_add_sub(unsigned int base, { unsigned int irqno; - irq_set_chip_and_handler(base, &s3c_irq_level_chip, handle_level_irq); - irq_set_chained_handler(base, demux); + set_irq_chip(base, &s3c_irq_level_chip); + set_irq_handler(base, handle_level_irq); + set_irq_chained_handler(base, demux); for (irqno = start; irqno <= end; irqno++) { - irq_set_chip_and_handler(irqno, chip, handle_level_irq); + set_irq_chip(irqno, chip); + set_irq_handler(irqno, handle_level_irq); set_irq_flags(irqno, IRQF_VALID); } diff --git a/trunk/arch/arm/mach-s3c2440/irq.c b/trunk/arch/arm/mach-s3c2440/irq.c index eb1cc0f0705e..acad4428bef0 100644 --- a/trunk/arch/arm/mach-s3c2440/irq.c +++ b/trunk/arch/arm/mach-s3c2440/irq.c @@ -100,13 +100,13 @@ static int s3c2440_irq_add(struct sys_device *sysdev) /* add new chained handler for wdt, ac7 */ - irq_set_chip_and_handler(IRQ_WDT, &s3c_irq_level_chip, - handle_level_irq); - irq_set_chained_handler(IRQ_WDT, s3c_irq_demux_wdtac97); + set_irq_chip(IRQ_WDT, &s3c_irq_level_chip); + set_irq_handler(IRQ_WDT, handle_level_irq); + set_irq_chained_handler(IRQ_WDT, s3c_irq_demux_wdtac97); for (irqno = IRQ_S3C2440_WDT; irqno <= IRQ_S3C2440_AC97; irqno++) { - irq_set_chip_and_handler(irqno, &s3c_irq_wdtac97, - handle_level_irq); + set_irq_chip(irqno, &s3c_irq_wdtac97); + set_irq_handler(irqno, handle_level_irq); set_irq_flags(irqno, IRQF_VALID); } diff --git a/trunk/arch/arm/mach-s3c2440/s3c244x-irq.c b/trunk/arch/arm/mach-s3c2440/s3c244x-irq.c index de07c2feaa32..83daf4ece764 100644 --- a/trunk/arch/arm/mach-s3c2440/s3c244x-irq.c +++ b/trunk/arch/arm/mach-s3c2440/s3c244x-irq.c @@ -95,19 +95,19 @@ static int s3c244x_irq_add(struct sys_device *sysdev) { unsigned int irqno; - irq_set_chip_and_handler(IRQ_NFCON, &s3c_irq_level_chip, - handle_level_irq); + set_irq_chip(IRQ_NFCON, &s3c_irq_level_chip); + set_irq_handler(IRQ_NFCON, handle_level_irq); set_irq_flags(IRQ_NFCON, IRQF_VALID); /* add chained handler for camera */ - irq_set_chip_and_handler(IRQ_CAM, &s3c_irq_level_chip, - handle_level_irq); - irq_set_chained_handler(IRQ_CAM, s3c_irq_demux_cam); + set_irq_chip(IRQ_CAM, &s3c_irq_level_chip); + set_irq_handler(IRQ_CAM, handle_level_irq); + set_irq_chained_handler(IRQ_CAM, s3c_irq_demux_cam); for (irqno = IRQ_S3C2440_CAM_C; irqno <= IRQ_S3C2440_CAM_P; irqno++) { - irq_set_chip_and_handler(irqno, &s3c_irq_cam, - handle_level_irq); + set_irq_chip(irqno, &s3c_irq_cam); + set_irq_handler(irqno, handle_level_irq); set_irq_flags(irqno, IRQF_VALID); } diff --git a/trunk/arch/arm/mach-s3c2443/irq.c b/trunk/arch/arm/mach-s3c2443/irq.c index 83ecb1173fb1..c7820f9c1352 100644 --- a/trunk/arch/arm/mach-s3c2443/irq.c +++ b/trunk/arch/arm/mach-s3c2443/irq.c @@ -230,11 +230,13 @@ static int __init s3c2443_add_sub(unsigned int base, { unsigned int irqno; - irq_set_chip_and_handler(base, &s3c_irq_level_chip, handle_level_irq); - irq_set_chained_handler(base, demux); + set_irq_chip(base, &s3c_irq_level_chip); + set_irq_handler(base, handle_level_irq); + set_irq_chained_handler(base, demux); for (irqno = start; irqno <= end; irqno++) { - irq_set_chip_and_handler(irqno, chip, handle_level_irq); + set_irq_chip(irqno, chip); + set_irq_handler(irqno, handle_level_irq); set_irq_flags(irqno, IRQF_VALID); } diff --git a/trunk/arch/arm/mach-s3c64xx/irq-eint.c b/trunk/arch/arm/mach-s3c64xx/irq-eint.c index 4d203be1f4c3..2ead8189da74 100644 --- a/trunk/arch/arm/mach-s3c64xx/irq-eint.c +++ b/trunk/arch/arm/mach-s3c64xx/irq-eint.c @@ -197,15 +197,16 @@ static int __init s3c64xx_init_irq_eint(void) int irq; for (irq = IRQ_EINT(0); irq <= IRQ_EINT(27); irq++) { - irq_set_chip_and_handler(irq, &s3c_irq_eint, handle_level_irq); - irq_set_chip_data(irq, (void *)eint_irq_to_bit(irq)); + set_irq_chip(irq, &s3c_irq_eint); + set_irq_chip_data(irq, (void *)eint_irq_to_bit(irq)); + set_irq_handler(irq, handle_level_irq); set_irq_flags(irq, IRQF_VALID); } - irq_set_chained_handler(IRQ_EINT0_3, s3c_irq_demux_eint0_3); - irq_set_chained_handler(IRQ_EINT4_11, s3c_irq_demux_eint4_11); - irq_set_chained_handler(IRQ_EINT12_19, s3c_irq_demux_eint12_19); - irq_set_chained_handler(IRQ_EINT20_27, s3c_irq_demux_eint20_27); + set_irq_chained_handler(IRQ_EINT0_3, s3c_irq_demux_eint0_3); + set_irq_chained_handler(IRQ_EINT4_11, s3c_irq_demux_eint4_11); + set_irq_chained_handler(IRQ_EINT12_19, s3c_irq_demux_eint12_19); + set_irq_chained_handler(IRQ_EINT20_27, s3c_irq_demux_eint20_27); return 0; } diff --git a/trunk/arch/arm/mach-s5p64x0/cpu.c b/trunk/arch/arm/mach-s5p64x0/cpu.c index a5c00952ea35..b8d02eb4cf30 100644 --- a/trunk/arch/arm/mach-s5p64x0/cpu.c +++ b/trunk/arch/arm/mach-s5p64x0/cpu.c @@ -119,7 +119,7 @@ void __init s5p6450_map_io(void) s3c_adc_setname("s3c64xx-adc"); iotable_init(s5p64x0_iodesc, ARRAY_SIZE(s5p64x0_iodesc)); - iotable_init(s5p6450_iodesc, ARRAY_SIZE(s5p6450_iodesc)); + iotable_init(s5p6450_iodesc, ARRAY_SIZE(s5p6440_iodesc)); } /* diff --git a/trunk/arch/arm/mach-s5pv210/include/mach/irqs.h b/trunk/arch/arm/mach-s5pv210/include/mach/irqs.h index b9f9ec33384d..26710b35ef87 100644 --- a/trunk/arch/arm/mach-s5pv210/include/mach/irqs.h +++ b/trunk/arch/arm/mach-s5pv210/include/mach/irqs.h @@ -99,9 +99,9 @@ #define IRQ_TC IRQ_PENDN #define IRQ_KEYPAD S5P_IRQ_VIC2(25) #define IRQ_CG S5P_IRQ_VIC2(26) -#define IRQ_SSS_INT S5P_IRQ_VIC2(27) -#define IRQ_SSS_HASH S5P_IRQ_VIC2(28) -#define IRQ_PCM2 S5P_IRQ_VIC2(29) +#define IRQ_SEC S5P_IRQ_VIC2(27) +#define IRQ_SECRX S5P_IRQ_VIC2(28) +#define IRQ_SECTX S5P_IRQ_VIC2(29) #define IRQ_SDMIRQ S5P_IRQ_VIC2(30) #define IRQ_SDMFIQ S5P_IRQ_VIC2(31) diff --git a/trunk/arch/arm/mach-s5pv210/mach-smdkv210.c b/trunk/arch/arm/mach-s5pv210/mach-smdkv210.c index c6a9e86c2d5c..bc08ac42e7cc 100644 --- a/trunk/arch/arm/mach-s5pv210/mach-smdkv210.c +++ b/trunk/arch/arm/mach-s5pv210/mach-smdkv210.c @@ -44,6 +44,7 @@ #include #include #include +#include #include /* Following are default values for UCON, ULCON and UFCON UART registers */ diff --git a/trunk/arch/arm/mach-sa1100/cerf.c b/trunk/arch/arm/mach-sa1100/cerf.c index 7f3da4b11ec9..98d780608c7e 100644 --- a/trunk/arch/arm/mach-sa1100/cerf.c +++ b/trunk/arch/arm/mach-sa1100/cerf.c @@ -96,7 +96,7 @@ static struct resource cerf_flash_resource = { static void __init cerf_init_irq(void) { sa1100_init_irq(); - irq_set_irq_type(CERF_ETH_IRQ, IRQ_TYPE_EDGE_RISING); + set_irq_type(CERF_ETH_IRQ, IRQ_TYPE_EDGE_RISING); } static struct map_desc cerf_io_desc[] __initdata = { diff --git a/trunk/arch/arm/mach-sa1100/irq.c b/trunk/arch/arm/mach-sa1100/irq.c index 423ddb3d65e9..3d85dfad9c1f 100644 --- a/trunk/arch/arm/mach-sa1100/irq.c +++ b/trunk/arch/arm/mach-sa1100/irq.c @@ -323,28 +323,28 @@ void __init sa1100_init_irq(void) ICCR = 1; for (irq = 0; irq <= 10; irq++) { - irq_set_chip_and_handler(irq, &sa1100_low_gpio_chip, - handle_edge_irq); + set_irq_chip(irq, &sa1100_low_gpio_chip); + set_irq_handler(irq, handle_edge_irq); set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); } for (irq = 12; irq <= 31; irq++) { - irq_set_chip_and_handler(irq, &sa1100_normal_chip, - handle_level_irq); + set_irq_chip(irq, &sa1100_normal_chip); + set_irq_handler(irq, handle_level_irq); set_irq_flags(irq, IRQF_VALID); } for (irq = 32; irq <= 48; irq++) { - irq_set_chip_and_handler(irq, &sa1100_high_gpio_chip, - handle_edge_irq); + set_irq_chip(irq, &sa1100_high_gpio_chip); + set_irq_handler(irq, handle_edge_irq); set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); } /* * Install handler for GPIO 11-27 edge detect interrupts */ - irq_set_chip(IRQ_GPIO11_27, &sa1100_normal_chip); - irq_set_chained_handler(IRQ_GPIO11_27, sa1100_high_gpio_handler); + set_irq_chip(IRQ_GPIO11_27, &sa1100_normal_chip); + set_irq_chained_handler(IRQ_GPIO11_27, sa1100_high_gpio_handler); sa1100_init_gpio(); } diff --git a/trunk/arch/arm/mach-sa1100/neponset.c b/trunk/arch/arm/mach-sa1100/neponset.c index b4fa53a1427e..4aad01f73660 100644 --- a/trunk/arch/arm/mach-sa1100/neponset.c +++ b/trunk/arch/arm/mach-sa1100/neponset.c @@ -145,8 +145,8 @@ static int __devinit neponset_probe(struct platform_device *dev) /* * Install handler for GPIO25. */ - irq_set_irq_type(IRQ_GPIO25, IRQ_TYPE_EDGE_RISING); - irq_set_chained_handler(IRQ_GPIO25, neponset_irq_handler); + set_irq_type(IRQ_GPIO25, IRQ_TYPE_EDGE_RISING); + set_irq_chained_handler(IRQ_GPIO25, neponset_irq_handler); /* * We would set IRQ_GPIO25 to be a wake-up IRQ, but @@ -161,9 +161,9 @@ static int __devinit neponset_probe(struct platform_device *dev) * Setup other Neponset IRQs. SA1111 will be done by the * generic SA1111 code. */ - irq_set_handler(IRQ_NEPONSET_SMC9196, handle_simple_irq); + set_irq_handler(IRQ_NEPONSET_SMC9196, handle_simple_irq); set_irq_flags(IRQ_NEPONSET_SMC9196, IRQF_VALID | IRQF_PROBE); - irq_set_handler(IRQ_NEPONSET_USAR, handle_simple_irq); + set_irq_handler(IRQ_NEPONSET_USAR, handle_simple_irq); set_irq_flags(IRQ_NEPONSET_USAR, IRQF_VALID | IRQF_PROBE); /* diff --git a/trunk/arch/arm/mach-sa1100/pleb.c b/trunk/arch/arm/mach-sa1100/pleb.c index 65161f2bea29..42b80400c100 100644 --- a/trunk/arch/arm/mach-sa1100/pleb.c +++ b/trunk/arch/arm/mach-sa1100/pleb.c @@ -142,7 +142,7 @@ static void __init pleb_map_io(void) GPDR &= ~GPIO_ETH0_IRQ; - irq_set_irq_type(GPIO_ETH0_IRQ, IRQ_TYPE_EDGE_FALLING); + set_irq_type(GPIO_ETH0_IRQ, IRQ_TYPE_EDGE_FALLING); } MACHINE_START(PLEB, "PLEB") diff --git a/trunk/arch/arm/mach-shark/irq.c b/trunk/arch/arm/mach-shark/irq.c index 5dce13e429f3..831fc66dfa4d 100644 --- a/trunk/arch/arm/mach-shark/irq.c +++ b/trunk/arch/arm/mach-shark/irq.c @@ -80,7 +80,8 @@ void __init shark_init_irq(void) int irq; for (irq = 0; irq < NR_IRQS; irq++) { - irq_set_chip_and_handler(irq, &fb_chip, handle_edge_irq); + set_irq_chip(irq, &fb_chip); + set_irq_handler(irq, handle_edge_irq); set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); } diff --git a/trunk/arch/arm/mach-shmobile/board-ap4evb.c b/trunk/arch/arm/mach-shmobile/board-ap4evb.c index 08cc45137bdc..a94f29da5d30 100644 --- a/trunk/arch/arm/mach-shmobile/board-ap4evb.c +++ b/trunk/arch/arm/mach-shmobile/board-ap4evb.c @@ -1255,7 +1255,7 @@ static void __init ap4evb_init(void) gpio_request(GPIO_FN_KEYIN4, NULL); /* enable TouchScreen */ - irq_set_irq_type(IRQ28, IRQ_TYPE_LEVEL_LOW); + set_irq_type(IRQ28, IRQ_TYPE_LEVEL_LOW); tsc_device.irq = IRQ28; i2c_register_board_info(1, &tsc_device, 1); @@ -1311,7 +1311,7 @@ static void __init ap4evb_init(void) lcdc_info.ch[0].lcd_size_cfg.height = 91; /* enable TouchScreen */ - irq_set_irq_type(IRQ7, IRQ_TYPE_LEVEL_LOW); + set_irq_type(IRQ7, IRQ_TYPE_LEVEL_LOW); tsc_device.irq = IRQ7; i2c_register_board_info(0, &tsc_device, 1); diff --git a/trunk/arch/arm/mach-shmobile/board-mackerel.c b/trunk/arch/arm/mach-shmobile/board-mackerel.c index f0d0af14ae06..49bc07482179 100644 --- a/trunk/arch/arm/mach-shmobile/board-mackerel.c +++ b/trunk/arch/arm/mach-shmobile/board-mackerel.c @@ -1124,15 +1124,15 @@ static void __init mackerel_init(void) /* enable Keypad */ gpio_request(GPIO_FN_IRQ9_42, NULL); - irq_set_irq_type(IRQ9, IRQ_TYPE_LEVEL_HIGH); + set_irq_type(IRQ9, IRQ_TYPE_LEVEL_HIGH); /* enable Touchscreen */ gpio_request(GPIO_FN_IRQ7_40, NULL); - irq_set_irq_type(IRQ7, IRQ_TYPE_LEVEL_LOW); + set_irq_type(IRQ7, IRQ_TYPE_LEVEL_LOW); /* enable Accelerometer */ gpio_request(GPIO_FN_IRQ21, NULL); - irq_set_irq_type(IRQ21, IRQ_TYPE_LEVEL_HIGH); + set_irq_type(IRQ21, IRQ_TYPE_LEVEL_HIGH); /* enable SDHI0 */ gpio_request(GPIO_FN_SDHICD0, NULL); diff --git a/trunk/arch/arm/mach-shmobile/intc-sh7367.c b/trunk/arch/arm/mach-shmobile/intc-sh7367.c index cc442d198cdc..2fe9704d5ea1 100644 --- a/trunk/arch/arm/mach-shmobile/intc-sh7367.c +++ b/trunk/arch/arm/mach-shmobile/intc-sh7367.c @@ -421,7 +421,7 @@ static struct intc_desc intcs_desc __initdata = { static void intcs_demux(unsigned int irq, struct irq_desc *desc) { - void __iomem *reg = (void *)irq_get_handler_data(irq); + void __iomem *reg = (void *)get_irq_data(irq); unsigned int evtcodeas = ioread32(reg); generic_handle_irq(intcs_evt2irq(evtcodeas)); @@ -435,6 +435,6 @@ void __init sh7367_init_irq(void) register_intc_controller(&intcs_desc); /* demux using INTEVTSA */ - irq_set_handler_data(evt2irq(0xf80), (void *)intevtsa); - irq_set_chained_handler(evt2irq(0xf80), intcs_demux); + set_irq_data(evt2irq(0xf80), (void *)intevtsa); + set_irq_chained_handler(evt2irq(0xf80), intcs_demux); } diff --git a/trunk/arch/arm/mach-shmobile/intc-sh7372.c b/trunk/arch/arm/mach-shmobile/intc-sh7372.c index 7a4960f9c1e3..ca5f9d17b39a 100644 --- a/trunk/arch/arm/mach-shmobile/intc-sh7372.c +++ b/trunk/arch/arm/mach-shmobile/intc-sh7372.c @@ -601,7 +601,7 @@ static struct intc_desc intcs_desc __initdata = { static void intcs_demux(unsigned int irq, struct irq_desc *desc) { - void __iomem *reg = (void *)irq_get_handler_data(irq); + void __iomem *reg = (void *)get_irq_data(irq); unsigned int evtcodeas = ioread32(reg); generic_handle_irq(intcs_evt2irq(evtcodeas)); @@ -615,6 +615,6 @@ void __init sh7372_init_irq(void) register_intc_controller(&intcs_desc); /* demux using INTEVTSA */ - irq_set_handler_data(evt2irq(0xf80), (void *)intevtsa); - irq_set_chained_handler(evt2irq(0xf80), intcs_demux); + set_irq_data(evt2irq(0xf80), (void *)intevtsa); + set_irq_chained_handler(evt2irq(0xf80), intcs_demux); } diff --git a/trunk/arch/arm/mach-shmobile/intc-sh7377.c b/trunk/arch/arm/mach-shmobile/intc-sh7377.c index fe45154ce660..dd568382cc9f 100644 --- a/trunk/arch/arm/mach-shmobile/intc-sh7377.c +++ b/trunk/arch/arm/mach-shmobile/intc-sh7377.c @@ -626,7 +626,7 @@ static struct intc_desc intcs_desc __initdata = { static void intcs_demux(unsigned int irq, struct irq_desc *desc) { - void __iomem *reg = (void *)irq_get_handler_data(irq); + void __iomem *reg = (void *)get_irq_data(irq); unsigned int evtcodeas = ioread32(reg); generic_handle_irq(intcs_evt2irq(evtcodeas)); @@ -641,6 +641,6 @@ void __init sh7377_init_irq(void) register_intc_controller(&intcs_desc); /* demux using INTEVTSA */ - irq_set_handler_data(evt2irq(INTCS_INTVECT), (void *)intevtsa); - irq_set_chained_handler(evt2irq(INTCS_INTVECT), intcs_demux); + set_irq_data(evt2irq(INTCS_INTVECT), (void *)intevtsa); + set_irq_chained_handler(evt2irq(INTCS_INTVECT), intcs_demux); } diff --git a/trunk/arch/arm/mach-tcc8k/irq.c b/trunk/arch/arm/mach-tcc8k/irq.c index 209fa5c65d4c..aa9231f4fc6e 100644 --- a/trunk/arch/arm/mach-tcc8k/irq.c +++ b/trunk/arch/arm/mach-tcc8k/irq.c @@ -102,10 +102,10 @@ void __init tcc8k_init_irq(void) for (irqno = 0; irqno < NR_IRQS; irqno++) { if (irqno < 32) - irq_set_chip(irqno, &tcc8000_irq_chip0); + set_irq_chip(irqno, &tcc8000_irq_chip0); else - irq_set_chip(irqno, &tcc8000_irq_chip1); - irq_set_handler(irqno, handle_level_irq); + set_irq_chip(irqno, &tcc8000_irq_chip1); + set_irq_handler(irqno, handle_level_irq); set_irq_flags(irqno, IRQF_VALID); } } diff --git a/trunk/arch/arm/mach-tegra/gpio.c b/trunk/arch/arm/mach-tegra/gpio.c index 76a3f654220f..12090a2cf3e0 100644 --- a/trunk/arch/arm/mach-tegra/gpio.c +++ b/trunk/arch/arm/mach-tegra/gpio.c @@ -208,9 +208,9 @@ static int tegra_gpio_irq_set_type(struct irq_data *d, unsigned int type) spin_unlock_irqrestore(&bank->lvl_lock[port], flags); if (type & (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_LEVEL_HIGH)) - __irq_set_handler_locked(d->irq, handle_level_irq); + __set_irq_handler_unlocked(d->irq, handle_level_irq); else if (type & (IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING)) - __irq_set_handler_locked(d->irq, handle_edge_irq); + __set_irq_handler_unlocked(d->irq, handle_edge_irq); return 0; } @@ -224,7 +224,7 @@ static void tegra_gpio_irq_handler(unsigned int irq, struct irq_desc *desc) desc->irq_data.chip->irq_ack(&desc->irq_data); - bank = irq_get_handler_data(irq); + bank = get_irq_data(irq); for (port = 0; port < 4; port++) { int gpio = tegra_gpio_compose(bank->bank, port, 0); @@ -275,6 +275,13 @@ void tegra_gpio_resume(void) } local_irq_restore(flags); + + for (i = INT_GPIO_BASE; i < (INT_GPIO_BASE + TEGRA_NR_GPIOS); i++) { + struct irq_desc *desc = irq_to_desc(i); + if (!desc || (desc->status & IRQ_WAKEUP)) + continue; + enable_irq(i); + } } void tegra_gpio_suspend(void) @@ -282,6 +289,18 @@ void tegra_gpio_suspend(void) unsigned long flags; int b, p, i; + for (i = INT_GPIO_BASE; i < (INT_GPIO_BASE + TEGRA_NR_GPIOS); i++) { + struct irq_desc *desc = irq_to_desc(i); + if (!desc) + continue; + if (desc->status & IRQ_WAKEUP) { + int gpio = i - INT_GPIO_BASE; + pr_debug("gpio %d.%d is wakeup\n", gpio/8, gpio&7); + continue; + } + disable_irq(i); + } + local_irq_save(flags); for (b = 0; b < ARRAY_SIZE(tegra_gpio_banks); b++) { struct tegra_gpio_bank *bank = &tegra_gpio_banks[b]; @@ -301,7 +320,7 @@ void tegra_gpio_suspend(void) static int tegra_gpio_wake_enable(struct irq_data *d, unsigned int enable) { struct tegra_gpio_bank *bank = irq_data_get_irq_chip_data(d); - return irq_set_irq_wake(bank->irq, enable); + return set_irq_wake(bank->irq, enable); } #endif @@ -340,18 +359,18 @@ static int __init tegra_gpio_init(void) for (i = INT_GPIO_BASE; i < (INT_GPIO_BASE + TEGRA_NR_GPIOS); i++) { bank = &tegra_gpio_banks[GPIO_BANK(irq_to_gpio(i))]; - irq_set_lockdep_class(i, &gpio_lock_class); - irq_set_chip_data(i, bank); - irq_set_chip_and_handler(i, &tegra_gpio_irq_chip, - handle_simple_irq); + lockdep_set_class(&irq_desc[i].lock, &gpio_lock_class); + set_irq_chip_data(i, bank); + set_irq_chip(i, &tegra_gpio_irq_chip); + set_irq_handler(i, handle_simple_irq); set_irq_flags(i, IRQF_VALID); } for (i = 0; i < ARRAY_SIZE(tegra_gpio_banks); i++) { bank = &tegra_gpio_banks[i]; - irq_set_chained_handler(bank->irq, tegra_gpio_irq_handler); - irq_set_handler_data(bank->irq, bank); + set_irq_chained_handler(bank->irq, tegra_gpio_irq_handler); + set_irq_data(bank->irq, bank); for (j = 0; j < 4; j++) spin_lock_init(&bank->lvl_lock[j]); diff --git a/trunk/arch/arm/mach-tegra/irq.c b/trunk/arch/arm/mach-tegra/irq.c index 4330d8995b27..dfbc219ea492 100644 --- a/trunk/arch/arm/mach-tegra/irq.c +++ b/trunk/arch/arm/mach-tegra/irq.c @@ -144,7 +144,7 @@ void __init tegra_init_irq(void) gic_init(0, 29, IO_ADDRESS(TEGRA_ARM_INT_DIST_BASE), IO_ADDRESS(TEGRA_ARM_PERIF_BASE + 0x100)); - gic = irq_get_chip(29); + gic = get_irq_chip(29); tegra_gic_unmask_irq = gic->irq_unmask; tegra_gic_mask_irq = gic->irq_mask; tegra_gic_ack_irq = gic->irq_ack; @@ -154,7 +154,8 @@ void __init tegra_init_irq(void) for (i = 0; i < INT_MAIN_NR; i++) { irq = INT_PRI_BASE + i; - irq_set_chip_and_handler(irq, &tegra_irq, handle_level_irq); + set_irq_chip(irq, &tegra_irq); + set_irq_handler(irq, handle_level_irq); set_irq_flags(irq, IRQF_VALID); } } diff --git a/trunk/arch/arm/mach-ux500/Kconfig b/trunk/arch/arm/mach-ux500/Kconfig index 58626013aa32..203b986280f5 100644 --- a/trunk/arch/arm/mach-ux500/Kconfig +++ b/trunk/arch/arm/mach-ux500/Kconfig @@ -23,7 +23,6 @@ menu "Ux500 target platform" config MACH_U8500 bool "U8500 Development platform" depends on UX500_SOC_DB8500 - select TPS6105X help Include support for the mop500 development platform. diff --git a/trunk/arch/arm/mach-ux500/board-mop500-regulators.c b/trunk/arch/arm/mach-ux500/board-mop500-regulators.c index 9ed0f90cfe23..875c91b2f8a4 100644 --- a/trunk/arch/arm/mach-ux500/board-mop500-regulators.c +++ b/trunk/arch/arm/mach-ux500/board-mop500-regulators.c @@ -13,30 +13,6 @@ #include #include "board-mop500-regulators.h" -/* - * TPS61052 regulator - */ -static struct regulator_consumer_supply tps61052_vaudio_consumers[] = { - /* - * Boost converter supply to raise voltage on audio speaker, this - * is actually connected to three pins, VInVhfL (left amplifier) - * VInVhfR (right amplifier) and VIntDClassInt - all three must - * be connected to the same voltage. - */ - REGULATOR_SUPPLY("vintdclassint", "ab8500-codec.0"), -}; - -struct regulator_init_data tps61052_regulator = { - .constraints = { - .name = "vaudio-hf", - .min_uV = 4500000, - .max_uV = 4500000, - .valid_ops_mask = REGULATOR_CHANGE_STATUS, - }, - .num_consumer_supplies = ARRAY_SIZE(tps61052_vaudio_consumers), - .consumer_supplies = tps61052_vaudio_consumers, -}; - static struct regulator_consumer_supply ab8500_vaux1_consumers[] = { /* External displays, connector on board 2v5 power supply */ REGULATOR_SUPPLY("vaux12v5", "mcde.0"), @@ -86,182 +62,6 @@ static struct regulator_consumer_supply ab8500_vana_consumers[] = { REGULATOR_SUPPLY("vsmps2", "mcde.0"), }; -/* ab8500 regulator register initialization */ -struct ab8500_regulator_reg_init -ab8500_regulator_reg_init[AB8500_NUM_REGULATOR_REGISTERS] = { - /* - * VanaRequestCtrl = HP/LP depending on VxRequest - * VextSupply1RequestCtrl = HP/LP depending on VxRequest - */ - INIT_REGULATOR_REGISTER(AB8500_REGUREQUESTCTRL2, 0x00), - /* - * VextSupply2RequestCtrl = HP/LP depending on VxRequest - * VextSupply3RequestCtrl = HP/LP depending on VxRequest - * Vaux1RequestCtrl = HP/LP depending on VxRequest - * Vaux2RequestCtrl = HP/LP depending on VxRequest - */ - INIT_REGULATOR_REGISTER(AB8500_REGUREQUESTCTRL3, 0x00), - /* - * Vaux3RequestCtrl = HP/LP depending on VxRequest - * SwHPReq = Control through SWValid disabled - */ - INIT_REGULATOR_REGISTER(AB8500_REGUREQUESTCTRL4, 0x00), - /* - * VanaSysClkReq1HPValid = disabled - * Vaux1SysClkReq1HPValid = disabled - * Vaux2SysClkReq1HPValid = disabled - * Vaux3SysClkReq1HPValid = disabled - */ - INIT_REGULATOR_REGISTER(AB8500_REGUSYSCLKREQ1HPVALID1, 0x00), - /* - * VextSupply1SysClkReq1HPValid = disabled - * VextSupply2SysClkReq1HPValid = disabled - * VextSupply3SysClkReq1HPValid = SysClkReq1 controlled - */ - INIT_REGULATOR_REGISTER(AB8500_REGUSYSCLKREQ1HPVALID2, 0x40), - /* - * VanaHwHPReq1Valid = disabled - * Vaux1HwHPreq1Valid = disabled - * Vaux2HwHPReq1Valid = disabled - * Vaux3HwHPReqValid = disabled - */ - INIT_REGULATOR_REGISTER(AB8500_REGUHWHPREQ1VALID1, 0x00), - /* - * VextSupply1HwHPReq1Valid = disabled - * VextSupply2HwHPReq1Valid = disabled - * VextSupply3HwHPReq1Valid = disabled - */ - INIT_REGULATOR_REGISTER(AB8500_REGUHWHPREQ1VALID2, 0x00), - /* - * VanaHwHPReq2Valid = disabled - * Vaux1HwHPReq2Valid = disabled - * Vaux2HwHPReq2Valid = disabled - * Vaux3HwHPReq2Valid = disabled - */ - INIT_REGULATOR_REGISTER(AB8500_REGUHWHPREQ2VALID1, 0x00), - /* - * VextSupply1HwHPReq2Valid = disabled - * VextSupply2HwHPReq2Valid = disabled - * VextSupply3HwHPReq2Valid = HWReq2 controlled - */ - INIT_REGULATOR_REGISTER(AB8500_REGUHWHPREQ2VALID2, 0x04), - /* - * VanaSwHPReqValid = disabled - * Vaux1SwHPReqValid = disabled - */ - INIT_REGULATOR_REGISTER(AB8500_REGUSWHPREQVALID1, 0x00), - /* - * Vaux2SwHPReqValid = disabled - * Vaux3SwHPReqValid = disabled - * VextSupply1SwHPReqValid = disabled - * VextSupply2SwHPReqValid = disabled - * VextSupply3SwHPReqValid = disabled - */ - INIT_REGULATOR_REGISTER(AB8500_REGUSWHPREQVALID2, 0x00), - /* - * SysClkReq2Valid1 = SysClkReq2 controlled - * SysClkReq3Valid1 = disabled - * SysClkReq4Valid1 = SysClkReq4 controlled - * SysClkReq5Valid1 = disabled - * SysClkReq6Valid1 = SysClkReq6 controlled - * SysClkReq7Valid1 = disabled - * SysClkReq8Valid1 = disabled - */ - INIT_REGULATOR_REGISTER(AB8500_REGUSYSCLKREQVALID1, 0x2a), - /* - * SysClkReq2Valid2 = disabled - * SysClkReq3Valid2 = disabled - * SysClkReq4Valid2 = disabled - * SysClkReq5Valid2 = disabled - * SysClkReq6Valid2 = SysClkReq6 controlled - * SysClkReq7Valid2 = disabled - * SysClkReq8Valid2 = disabled - */ - INIT_REGULATOR_REGISTER(AB8500_REGUSYSCLKREQVALID2, 0x20), - /* - * VTVoutEna = disabled - * Vintcore12Ena = disabled - * Vintcore12Sel = 1.25 V - * Vintcore12LP = inactive (HP) - * VTVoutLP = inactive (HP) - */ - INIT_REGULATOR_REGISTER(AB8500_REGUMISC1, 0x10), - /* - * VaudioEna = disabled - * VdmicEna = disabled - * Vamic1Ena = disabled - * Vamic2Ena = disabled - */ - INIT_REGULATOR_REGISTER(AB8500_VAUDIOSUPPLY, 0x00), - /* - * Vamic1_dzout = high-Z when Vamic1 is disabled - * Vamic2_dzout = high-Z when Vamic2 is disabled - */ - INIT_REGULATOR_REGISTER(AB8500_REGUCTRL1VAMIC, 0x00), - /* - * VPll = Hw controlled - * VanaRegu = force off - */ - INIT_REGULATOR_REGISTER(AB8500_VPLLVANAREGU, 0x02), - /* - * VrefDDREna = disabled - * VrefDDRSleepMode = inactive (no pulldown) - */ - INIT_REGULATOR_REGISTER(AB8500_VREFDDR, 0x00), - /* - * VextSupply1Regu = HW control - * VextSupply2Regu = HW control - * VextSupply3Regu = HW control - * ExtSupply2Bypass = ExtSupply12LPn ball is 0 when Ena is 0 - * ExtSupply3Bypass = ExtSupply3LPn ball is 0 when Ena is 0 - */ - INIT_REGULATOR_REGISTER(AB8500_EXTSUPPLYREGU, 0x2a), - /* - * Vaux1Regu = force HP - * Vaux2Regu = force off - */ - INIT_REGULATOR_REGISTER(AB8500_VAUX12REGU, 0x01), - /* - * Vaux3regu = force off - */ - INIT_REGULATOR_REGISTER(AB8500_VRF1VAUX3REGU, 0x00), - /* - * Vsmps1 = 1.15V - */ - INIT_REGULATOR_REGISTER(AB8500_VSMPS1SEL1, 0x24), - /* - * Vaux1Sel = 2.5 V - */ - INIT_REGULATOR_REGISTER(AB8500_VAUX1SEL, 0x08), - /* - * Vaux2Sel = 2.9 V - */ - INIT_REGULATOR_REGISTER(AB8500_VAUX2SEL, 0x0d), - /* - * Vaux3Sel = 2.91 V - */ - INIT_REGULATOR_REGISTER(AB8500_VRF1VAUX3SEL, 0x07), - /* - * VextSupply12LP = disabled (no LP) - */ - INIT_REGULATOR_REGISTER(AB8500_REGUCTRL2SPARE, 0x00), - /* - * Vaux1Disch = short discharge time - * Vaux2Disch = short discharge time - * Vaux3Disch = short discharge time - * Vintcore12Disch = short discharge time - * VTVoutDisch = short discharge time - * VaudioDisch = short discharge time - */ - INIT_REGULATOR_REGISTER(AB8500_REGUCTRLDISCH, 0x00), - /* - * VanaDisch = short discharge time - * VdmicPullDownEna = pulldown disabled when Vdmic is disabled - * VdmicDisch = short discharge time - */ - INIT_REGULATOR_REGISTER(AB8500_REGUCTRLDISCH2, 0x00), -}; - /* AB8500 regulators */ struct regulator_init_data ab8500_regulators[AB8500_NUM_REGULATORS] = { /* supplies to the display/camera */ @@ -272,7 +72,6 @@ struct regulator_init_data ab8500_regulators[AB8500_NUM_REGULATORS] = { .max_uV = 2900000, .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE | REGULATOR_CHANGE_STATUS, - .boot_on = 1, /* must be on for display */ }, .num_consumer_supplies = ARRAY_SIZE(ab8500_vaux1_consumers), .consumer_supplies = ab8500_vaux1_consumers, diff --git a/trunk/arch/arm/mach-ux500/board-mop500-regulators.h b/trunk/arch/arm/mach-ux500/board-mop500-regulators.h index 94992158d962..2675fae52537 100644 --- a/trunk/arch/arm/mach-ux500/board-mop500-regulators.h +++ b/trunk/arch/arm/mach-ux500/board-mop500-regulators.h @@ -14,9 +14,6 @@ #include #include -extern struct ab8500_regulator_reg_init -ab8500_regulator_reg_init[AB8500_NUM_REGULATOR_REGISTERS]; extern struct regulator_init_data ab8500_regulators[AB8500_NUM_REGULATORS]; -extern struct regulator_init_data tps61052_regulator; #endif diff --git a/trunk/arch/arm/mach-ux500/board-mop500.c b/trunk/arch/arm/mach-ux500/board-mop500.c index dc8746d7826e..8790d984cac8 100644 --- a/trunk/arch/arm/mach-ux500/board-mop500.c +++ b/trunk/arch/arm/mach-ux500/board-mop500.c @@ -20,10 +20,7 @@ #include #include #include -#include #include -#include -#include #include #include #include @@ -44,35 +41,10 @@ #include "board-mop500.h" #include "board-mop500-regulators.h" -static struct ab8500_gpio_platform_data ab8500_gpio_pdata = { - .gpio_base = MOP500_AB8500_GPIO(0), - .irq_base = MOP500_AB8500_VIR_GPIO_IRQ_BASE, - /* config_reg is the initial configuration of ab8500 pins. - * The pins can be configured as GPIO or alt functions based - * on value present in GpioSel1 to GpioSel6 and AlternatFunction - * register. This is the array of 7 configuration settings. - * One has to compile time decide these settings. Below is the - * explaination of these setting - * GpioSel1 = 0x00 => Pins GPIO1 to GPIO8 are not used as GPIO - * GpioSel2 = 0x1E => Pins GPIO10 to GPIO13 are configured as GPIO - * GpioSel3 = 0x80 => Pin GPIO24 is configured as GPIO - * GpioSel4 = 0x01 => Pin GPIo25 is configured as GPIO - * GpioSel5 = 0x7A => Pins GPIO34, GPIO36 to GPIO39 are conf as GPIO - * GpioSel6 = 0x00 => Pins GPIO41 & GPIo42 are not configured as GPIO - * AlternaFunction = 0x00 => If Pins GPIO10 to 13 are not configured - * as GPIO then this register selectes the alternate fucntions - */ - .config_reg = {0x00, 0x1E, 0x80, 0x01, - 0x7A, 0x00, 0x00}, -}; - static struct ab8500_platform_data ab8500_platdata = { .irq_base = MOP500_AB8500_IRQ_BASE, - .regulator_reg_init = ab8500_regulator_reg_init, - .num_regulator_reg_init = ARRAY_SIZE(ab8500_regulator_reg_init), .regulator = ab8500_regulators, .num_regulator = ARRAY_SIZE(ab8500_regulators), - .gpio = &ab8500_gpio_pdata, }; static struct resource ab8500_resources[] = { @@ -93,15 +65,6 @@ struct platform_device ab8500_device = { .resource = ab8500_resources, }; -/* - * TPS61052 - */ - -static struct tps6105x_platform_data mop500_tps61052_data = { - .mode = TPS6105X_MODE_VOLTAGE, - .regulator_data = &tps61052_regulator, -}; - /* * TC35892 */ @@ -172,7 +135,7 @@ static struct lp5521_platform_data __initdata lp5521_sec_data = { .clock_mode = LP5521_CLOCK_EXT, }; -static struct i2c_board_info __initdata mop500_i2c0_devices[] = { +static struct i2c_board_info mop500_i2c0_devices[] = { { I2C_BOARD_INFO("tc3589x", 0x42), .irq = NOMADIK_GPIO_TO_IRQ(217), @@ -180,14 +143,6 @@ static struct i2c_board_info __initdata mop500_i2c0_devices[] = { }, }; -/* I2C0 devices only available prior to HREFv60 */ -static struct i2c_board_info __initdata mop500_i2c0_old_devices[] = { - { - I2C_BOARD_INFO("tps61052", 0x33), - .platform_data = &mop500_tps61052_data, - }, -}; - static struct i2c_board_info __initdata mop500_i2c2_devices[] = { { /* lp5521 LED driver, 1st device */ @@ -450,9 +405,6 @@ static void __init mop500_init_machine(void) i2c_register_board_info(0, mop500_i2c0_devices, ARRAY_SIZE(mop500_i2c0_devices)); - if (!machine_is_hrefv60()) - i2c_register_board_info(0, mop500_i2c0_old_devices, - ARRAY_SIZE(mop500_i2c0_old_devices)); i2c_register_board_info(2, mop500_i2c2_devices, ARRAY_SIZE(mop500_i2c2_devices)); } diff --git a/trunk/arch/arm/mach-ux500/board-mop500.h b/trunk/arch/arm/mach-ux500/board-mop500.h index 03a31cc9b084..56722f4be71b 100644 --- a/trunk/arch/arm/mach-ux500/board-mop500.h +++ b/trunk/arch/arm/mach-ux500/board-mop500.h @@ -27,10 +27,6 @@ #define GPIO_BU21013_CS MOP500_EGPIO(13) #define GPIO_SDMMC_EN MOP500_EGPIO(17) #define GPIO_SDMMC_1V8_3V_SEL MOP500_EGPIO(18) -#define MOP500_EGPIO_END MOP500_EGPIO(24) - -/* GPIOs on the AB8500 mixed-signals circuit */ -#define MOP500_AB8500_GPIO(x) (MOP500_EGPIO_END + (x)) struct i2c_board_info; diff --git a/trunk/arch/arm/mach-ux500/include/mach/irqs-board-mop500.h b/trunk/arch/arm/mach-ux500/include/mach/irqs-board-mop500.h index 97ef55f84934..7cdeb2af0ebb 100644 --- a/trunk/arch/arm/mach-ux500/include/mach/irqs-board-mop500.h +++ b/trunk/arch/arm/mach-ux500/include/mach/irqs-board-mop500.h @@ -35,20 +35,9 @@ #define MOP500_STMPE1601_IRQBASE MOP500_EGPIO_IRQ_END #define MOP500_STMPE1601_IRQ(x) (MOP500_STMPE1601_IRQBASE + (x)) -#define MOP500_STMPE1601_IRQ_END \ - MOP500_STMPE1601_IRQ(STMPE_NR_INTERNAL_IRQS) +#define MOP500_NR_IRQS MOP500_STMPE1601_IRQ(STMPE_NR_INTERNAL_IRQS) -/* AB8500 virtual gpio IRQ */ -#define AB8500_VIR_GPIO_NR_IRQS 16 - -#define MOP500_AB8500_VIR_GPIO_IRQ_BASE \ - MOP500_STMPE1601_IRQ_END -#define MOP500_AB8500_VIR_GPIO_IRQ_END \ - (MOP500_AB8500_VIR_GPIO_IRQ_BASE + AB8500_VIR_GPIO_NR_IRQS) - -#define MOP500_NR_IRQS MOP500_AB8500_VIR_GPIO_IRQ_END - -#define MOP500_IRQ_END MOP500_NR_IRQS +#define MOP500_IRQ_END MOP500_NR_IRQS #if MOP500_IRQ_END > IRQ_BOARD_END #undef IRQ_BOARD_END diff --git a/trunk/arch/arm/mach-ux500/modem-irq-db5500.c b/trunk/arch/arm/mach-ux500/modem-irq-db5500.c index 6b86416c94c9..e1296a7447c8 100644 --- a/trunk/arch/arm/mach-ux500/modem-irq-db5500.c +++ b/trunk/arch/arm/mach-ux500/modem-irq-db5500.c @@ -90,7 +90,8 @@ static irqreturn_t modem_cpu_irq_handler(int irq, void *data) static void create_virtual_irq(int irq, struct irq_chip *modem_irq_chip) { - irq_set_chip_and_handler(irq, modem_irq_chip, handle_simple_irq); + set_irq_chip(irq, modem_irq_chip); + set_irq_handler(irq, handle_simple_irq); set_irq_flags(irq, IRQF_VALID); pr_debug("modem_irq: Created virtual IRQ %d\n", irq); diff --git a/trunk/arch/arm/mach-versatile/core.c b/trunk/arch/arm/mach-versatile/core.c index 96e59e3ee4f5..eb7ffa0ee8b5 100644 --- a/trunk/arch/arm/mach-versatile/core.c +++ b/trunk/arch/arm/mach-versatile/core.c @@ -314,7 +314,7 @@ static struct mmci_platform_data mmc0_plat_data = { .gpio_cd = -1, }; -static struct resource chalcd_resources[] = { +static struct resource char_lcd_resources[] = { { .start = VERSATILE_CHAR_LCD_BASE, .end = (VERSATILE_CHAR_LCD_BASE + SZ_4K - 1), diff --git a/trunk/arch/arm/mach-vt8500/irq.c b/trunk/arch/arm/mach-vt8500/irq.c index 245140c0df10..5f4ddde4f02a 100644 --- a/trunk/arch/arm/mach-vt8500/irq.c +++ b/trunk/arch/arm/mach-vt8500/irq.c @@ -97,15 +97,15 @@ static int vt8500_irq_set_type(unsigned int irq, unsigned int flow_type) return -EINVAL; case IRQF_TRIGGER_HIGH: dctr |= VT8500_TRIGGER_HIGH; - __irq_set_handler_locked(orig_irq, handle_level_irq); + irq_desc[orig_irq].handle_irq = handle_level_irq; break; case IRQF_TRIGGER_FALLING: dctr |= VT8500_TRIGGER_FALLING; - __irq_set_handler_locked(orig_irq, handle_edge_irq); + irq_desc[orig_irq].handle_irq = handle_edge_irq; break; case IRQF_TRIGGER_RISING: dctr |= VT8500_TRIGGER_RISING; - __irq_set_handler_locked(orig_irq, handle_edge_irq); + irq_desc[orig_irq].handle_irq = handle_edge_irq; break; } writeb(dctr, base + VT8500_IC_DCTR + irq); @@ -136,8 +136,8 @@ void __init vt8500_init_irq(void) /* Disable all interrupts and route them to IRQ */ writeb(0x00, ic_regbase + VT8500_IC_DCTR + i); - irq_set_chip_and_handler(i, &vt8500_irq_chip, - handle_level_irq); + set_irq_chip(i, &vt8500_irq_chip); + set_irq_handler(i, handle_level_irq); set_irq_flags(i, IRQF_VALID); } } else { @@ -167,8 +167,8 @@ void __init wm8505_init_irq(void) writeb(0x00, sic_regbase + VT8500_IC_DCTR + i - 64); - irq_set_chip_and_handler(i, &vt8500_irq_chip, - handle_level_irq); + set_irq_chip(i, &vt8500_irq_chip); + set_irq_handler(i, handle_level_irq); set_irq_flags(i, IRQF_VALID); } } else { diff --git a/trunk/arch/arm/mach-w90x900/irq.c b/trunk/arch/arm/mach-w90x900/irq.c index 7bf143c443f1..9c350103dcda 100644 --- a/trunk/arch/arm/mach-w90x900/irq.c +++ b/trunk/arch/arm/mach-w90x900/irq.c @@ -207,8 +207,8 @@ void __init nuc900_init_irq(void) __raw_writel(0xFFFFFFFE, REG_AIC_MDCR); for (irqno = IRQ_WDT; irqno <= IRQ_ADC; irqno++) { - irq_set_chip_and_handler(irqno, &nuc900_irq_chip, - handle_level_irq); + set_irq_chip(irqno, &nuc900_irq_chip); + set_irq_handler(irqno, handle_level_irq); set_irq_flags(irqno, IRQF_VALID); } } diff --git a/trunk/arch/arm/plat-mxc/3ds_debugboard.c b/trunk/arch/arm/plat-mxc/3ds_debugboard.c index f0ba0726306c..c856fa397606 100644 --- a/trunk/arch/arm/plat-mxc/3ds_debugboard.c +++ b/trunk/arch/arm/plat-mxc/3ds_debugboard.c @@ -100,9 +100,14 @@ static void mxc_expio_irq_handler(u32 irq, struct irq_desc *desc) expio_irq = MXC_BOARD_IRQ_START; for (; int_valid != 0; int_valid >>= 1, expio_irq++) { + struct irq_desc *d; if ((int_valid & 1) == 0) continue; - generic_handle_irq(expio_irq); + d = irq_desc + expio_irq; + if (unlikely(!(d->handle_irq))) + pr_err("\nEXPIO irq: %d unhandled\n", expio_irq); + else + d->handle_irq(expio_irq, d); } desc->irq_data.chip->irq_ack(&desc->irq_data); @@ -181,11 +186,12 @@ int __init mxc_expio_init(u32 base, u32 p_irq) __raw_writew(0x1F, brd_io + INTR_MASK_REG); for (i = MXC_EXP_IO_BASE; i < (MXC_EXP_IO_BASE + MXC_MAX_EXP_IO_LINES); i++) { - irq_set_chip_and_handler(i, &expio_irq_chip, handle_level_irq); + set_irq_chip(i, &expio_irq_chip); + set_irq_handler(i, handle_level_irq); set_irq_flags(i, IRQF_VALID); } - irq_set_irq_type(p_irq, IRQF_TRIGGER_LOW); - irq_set_chained_handler(p_irq, mxc_expio_irq_handler); + set_irq_type(p_irq, IRQF_TRIGGER_LOW); + set_irq_chained_handler(p_irq, mxc_expio_irq_handler); /* Register Lan device on the debugboard */ smsc911x_resources[0].start = LAN9217_BASE_ADDR(base); diff --git a/trunk/arch/arm/plat-mxc/avic.c b/trunk/arch/arm/plat-mxc/avic.c index 09e2bd0fcdca..deb284bc7c4b 100644 --- a/trunk/arch/arm/plat-mxc/avic.c +++ b/trunk/arch/arm/plat-mxc/avic.c @@ -139,8 +139,8 @@ void __init mxc_init_irq(void __iomem *irqbase) __raw_writel(0, avic_base + AVIC_INTTYPEH); __raw_writel(0, avic_base + AVIC_INTTYPEL); for (i = 0; i < MXC_INTERNAL_IRQS; i++) { - irq_set_chip_and_handler(i, &mxc_avic_chip.base, - handle_level_irq); + set_irq_chip(i, &mxc_avic_chip.base); + set_irq_handler(i, handle_level_irq); set_irq_flags(i, IRQF_VALID); } diff --git a/trunk/arch/arm/plat-mxc/gpio.c b/trunk/arch/arm/plat-mxc/gpio.c index 7a107246fd98..57d59855f9ec 100644 --- a/trunk/arch/arm/plat-mxc/gpio.c +++ b/trunk/arch/arm/plat-mxc/gpio.c @@ -175,7 +175,7 @@ static void mxc_gpio_irq_handler(struct mxc_gpio_port *port, u32 irq_stat) static void mx3_gpio_irq_handler(u32 irq, struct irq_desc *desc) { u32 irq_stat; - struct mxc_gpio_port *port = irq_get_handler_data(irq); + struct mxc_gpio_port *port = get_irq_data(irq); irq_stat = __raw_readl(port->base + GPIO_ISR) & __raw_readl(port->base + GPIO_IMR); @@ -188,7 +188,7 @@ static void mx2_gpio_irq_handler(u32 irq, struct irq_desc *desc) { int i; u32 irq_msk, irq_stat; - struct mxc_gpio_port *port = irq_get_handler_data(irq); + struct mxc_gpio_port *port = get_irq_data(irq); /* walk through all interrupt status registers */ for (i = 0; i < gpio_table_size; i++) { @@ -311,8 +311,8 @@ int __init mxc_gpio_init(struct mxc_gpio_port *port, int cnt) __raw_writel(~0, port[i].base + GPIO_ISR); for (j = port[i].virtual_irq_start; j < port[i].virtual_irq_start + 32; j++) { - irq_set_chip_and_handler(j, &gpio_irq_chip, - handle_level_irq); + set_irq_chip(j, &gpio_irq_chip); + set_irq_handler(j, handle_level_irq); set_irq_flags(j, IRQF_VALID); } @@ -331,23 +331,21 @@ int __init mxc_gpio_init(struct mxc_gpio_port *port, int cnt) if (cpu_is_mx1() || cpu_is_mx3() || cpu_is_mx25() || cpu_is_mx51()) { /* setup one handler for each entry */ - irq_set_chained_handler(port[i].irq, - mx3_gpio_irq_handler); - irq_set_handler_data(port[i].irq, &port[i]); + set_irq_chained_handler(port[i].irq, mx3_gpio_irq_handler); + set_irq_data(port[i].irq, &port[i]); if (port[i].irq_high) { /* setup handler for GPIO 16 to 31 */ - irq_set_chained_handler(port[i].irq_high, - mx3_gpio_irq_handler); - irq_set_handler_data(port[i].irq_high, - &port[i]); + set_irq_chained_handler(port[i].irq_high, + mx3_gpio_irq_handler); + set_irq_data(port[i].irq_high, &port[i]); } } } if (cpu_is_mx2()) { /* setup one handler for all GPIO interrupts */ - irq_set_chained_handler(port[0].irq, mx2_gpio_irq_handler); - irq_set_handler_data(port[0].irq, port); + set_irq_chained_handler(port[0].irq, mx2_gpio_irq_handler); + set_irq_data(port[0].irq, port); } return 0; diff --git a/trunk/arch/arm/plat-mxc/irq-common.c b/trunk/arch/arm/plat-mxc/irq-common.c index e1c6eff7258a..0c799ac27730 100644 --- a/trunk/arch/arm/plat-mxc/irq-common.c +++ b/trunk/arch/arm/plat-mxc/irq-common.c @@ -29,7 +29,7 @@ int imx_irq_set_priority(unsigned char irq, unsigned char prio) ret = -ENOSYS; - base = irq_get_chip(irq); + base = get_irq_chip(irq); if (base) { chip = container_of(base, struct mxc_irq_chip, base); if (chip->set_priority) @@ -48,7 +48,7 @@ int mxc_set_irq_fiq(unsigned int irq, unsigned int type) ret = -ENOSYS; - base = irq_get_chip(irq); + base = get_irq_chip(irq); if (base) { chip = container_of(base, struct mxc_irq_chip, base); if (chip->set_irq_fiq) diff --git a/trunk/arch/arm/plat-mxc/tzic.c b/trunk/arch/arm/plat-mxc/tzic.c index 57f9395f87ce..bc3a6be8a27f 100644 --- a/trunk/arch/arm/plat-mxc/tzic.c +++ b/trunk/arch/arm/plat-mxc/tzic.c @@ -167,8 +167,8 @@ void __init tzic_init_irq(void __iomem *irqbase) /* all IRQ no FIQ Warning :: No selection */ for (i = 0; i < MXC_INTERNAL_IRQS; i++) { - irq_set_chip_and_handler(i, &mxc_tzic_chip.base, - handle_level_irq); + set_irq_chip(i, &mxc_tzic_chip.base); + set_irq_handler(i, handle_level_irq); set_irq_flags(i, IRQF_VALID); } diff --git a/trunk/arch/arm/plat-nomadik/gpio.c b/trunk/arch/arm/plat-nomadik/gpio.c index f49748eca1a3..80643bc38e10 100644 --- a/trunk/arch/arm/plat-nomadik/gpio.c +++ b/trunk/arch/arm/plat-nomadik/gpio.c @@ -54,7 +54,6 @@ struct nmk_gpio_chip { u32 rwimsc; u32 fwimsc; u32 slpm; - u32 enabled; }; static struct nmk_gpio_chip * @@ -319,7 +318,7 @@ static int __nmk_config_pins(pin_cfg_t *cfgs, int num, bool sleep) struct nmk_gpio_chip *nmk_chip; int pin = PIN_NUM(cfgs[i]); - nmk_chip = irq_get_chip_data(NOMADIK_GPIO_TO_IRQ(pin)); + nmk_chip = get_irq_chip_data(NOMADIK_GPIO_TO_IRQ(pin)); if (!nmk_chip) { ret = -EINVAL; break; @@ -398,7 +397,7 @@ int nmk_gpio_set_slpm(int gpio, enum nmk_gpio_slpm mode) struct nmk_gpio_chip *nmk_chip; unsigned long flags; - nmk_chip = irq_get_chip_data(NOMADIK_GPIO_TO_IRQ(gpio)); + nmk_chip = get_irq_chip_data(NOMADIK_GPIO_TO_IRQ(gpio)); if (!nmk_chip) return -EINVAL; @@ -431,7 +430,7 @@ int nmk_gpio_set_pull(int gpio, enum nmk_gpio_pull pull) struct nmk_gpio_chip *nmk_chip; unsigned long flags; - nmk_chip = irq_get_chip_data(NOMADIK_GPIO_TO_IRQ(gpio)); + nmk_chip = get_irq_chip_data(NOMADIK_GPIO_TO_IRQ(gpio)); if (!nmk_chip) return -EINVAL; @@ -457,7 +456,7 @@ int nmk_gpio_set_mode(int gpio, int gpio_mode) struct nmk_gpio_chip *nmk_chip; unsigned long flags; - nmk_chip = irq_get_chip_data(NOMADIK_GPIO_TO_IRQ(gpio)); + nmk_chip = get_irq_chip_data(NOMADIK_GPIO_TO_IRQ(gpio)); if (!nmk_chip) return -EINVAL; @@ -474,7 +473,7 @@ int nmk_gpio_get_mode(int gpio) struct nmk_gpio_chip *nmk_chip; u32 afunc, bfunc, bit; - nmk_chip = irq_get_chip_data(NOMADIK_GPIO_TO_IRQ(gpio)); + nmk_chip = get_irq_chip_data(NOMADIK_GPIO_TO_IRQ(gpio)); if (!nmk_chip) return -EINVAL; @@ -542,6 +541,13 @@ static void __nmk_gpio_irq_modify(struct nmk_gpio_chip *nmk_chip, static void __nmk_gpio_set_wake(struct nmk_gpio_chip *nmk_chip, int gpio, bool on) { +#ifdef CONFIG_ARCH_U8500 + if (cpu_is_u8500v2()) { + __nmk_gpio_set_slpm(nmk_chip, gpio - nmk_chip->chip.base, + on ? NMK_GPIO_SLPM_WAKEUP_ENABLE + : NMK_GPIO_SLPM_WAKEUP_DISABLE); + } +#endif __nmk_gpio_irq_modify(nmk_chip, gpio, WAKE, on); } @@ -558,11 +564,6 @@ static int nmk_gpio_irq_maskunmask(struct irq_data *d, bool enable) if (!nmk_chip) return -EINVAL; - if (enable) - nmk_chip->enabled |= bitmask; - else - nmk_chip->enabled &= ~bitmask; - spin_lock_irqsave(&nmk_gpio_slpm_lock, flags); spin_lock(&nmk_chip->lock); @@ -589,6 +590,8 @@ static void nmk_gpio_irq_unmask(struct irq_data *d) static int nmk_gpio_irq_set_wake(struct irq_data *d, unsigned int on) { + struct irq_desc *desc = irq_to_desc(d->irq); + bool enabled = !(desc->status & IRQ_DISABLED); struct nmk_gpio_chip *nmk_chip; unsigned long flags; u32 bitmask; @@ -603,7 +606,7 @@ static int nmk_gpio_irq_set_wake(struct irq_data *d, unsigned int on) spin_lock_irqsave(&nmk_gpio_slpm_lock, flags); spin_lock(&nmk_chip->lock); - if (!(nmk_chip->enabled & bitmask)) + if (!enabled) __nmk_gpio_set_wake(nmk_chip, gpio, on); if (on) @@ -619,7 +622,9 @@ static int nmk_gpio_irq_set_wake(struct irq_data *d, unsigned int on) static int nmk_gpio_irq_set_type(struct irq_data *d, unsigned int type) { - bool enabled, wake = irqd_is_wakeup_set(d); + struct irq_desc *desc = irq_to_desc(d->irq); + bool enabled = !(desc->status & IRQ_DISABLED); + bool wake = desc->wake_depth; int gpio; struct nmk_gpio_chip *nmk_chip; unsigned long flags; @@ -636,8 +641,6 @@ static int nmk_gpio_irq_set_type(struct irq_data *d, unsigned int type) if (type & IRQ_TYPE_LEVEL_LOW) return -EINVAL; - enabled = nmk_chip->enabled & bitmask; - spin_lock_irqsave(&nmk_chip->lock, flags); if (enabled) @@ -678,7 +681,7 @@ static void __nmk_gpio_irq_handler(unsigned int irq, struct irq_desc *desc, u32 status) { struct nmk_gpio_chip *nmk_chip; - struct irq_chip *host_chip = irq_get_chip(irq); + struct irq_chip *host_chip = get_irq_chip(irq); unsigned int first_irq; if (host_chip->irq_mask_ack) @@ -689,7 +692,7 @@ static void __nmk_gpio_irq_handler(unsigned int irq, struct irq_desc *desc, host_chip->irq_ack(&desc->irq_data); } - nmk_chip = irq_get_handler_data(irq); + nmk_chip = get_irq_data(irq); first_irq = NOMADIK_GPIO_TO_IRQ(nmk_chip->chip.base); while (status) { int bit = __ffs(status); @@ -703,7 +706,7 @@ static void __nmk_gpio_irq_handler(unsigned int irq, struct irq_desc *desc, static void nmk_gpio_irq_handler(unsigned int irq, struct irq_desc *desc) { - struct nmk_gpio_chip *nmk_chip = irq_get_handler_data(irq); + struct nmk_gpio_chip *nmk_chip = get_irq_data(irq); u32 status = readl(nmk_chip->addr + NMK_GPIO_IS); __nmk_gpio_irq_handler(irq, desc, status); @@ -712,7 +715,7 @@ static void nmk_gpio_irq_handler(unsigned int irq, struct irq_desc *desc) static void nmk_gpio_secondary_irq_handler(unsigned int irq, struct irq_desc *desc) { - struct nmk_gpio_chip *nmk_chip = irq_get_handler_data(irq); + struct nmk_gpio_chip *nmk_chip = get_irq_data(irq); u32 status = nmk_chip->get_secondary_status(nmk_chip->bank); __nmk_gpio_irq_handler(irq, desc, status); @@ -725,20 +728,20 @@ static int nmk_gpio_init_irq(struct nmk_gpio_chip *nmk_chip) first_irq = NOMADIK_GPIO_TO_IRQ(nmk_chip->chip.base); for (i = first_irq; i < first_irq + nmk_chip->chip.ngpio; i++) { - irq_set_chip_and_handler(i, &nmk_gpio_irq_chip, - handle_edge_irq); + set_irq_chip(i, &nmk_gpio_irq_chip); + set_irq_handler(i, handle_edge_irq); set_irq_flags(i, IRQF_VALID); - irq_set_chip_data(i, nmk_chip); - irq_set_irq_type(i, IRQ_TYPE_EDGE_FALLING); + set_irq_chip_data(i, nmk_chip); + set_irq_type(i, IRQ_TYPE_EDGE_FALLING); } - irq_set_chained_handler(nmk_chip->parent_irq, nmk_gpio_irq_handler); - irq_set_handler_data(nmk_chip->parent_irq, nmk_chip); + set_irq_chained_handler(nmk_chip->parent_irq, nmk_gpio_irq_handler); + set_irq_data(nmk_chip->parent_irq, nmk_chip); if (nmk_chip->secondary_parent_irq >= 0) { - irq_set_chained_handler(nmk_chip->secondary_parent_irq, + set_irq_chained_handler(nmk_chip->secondary_parent_irq, nmk_gpio_secondary_irq_handler); - irq_set_handler_data(nmk_chip->secondary_parent_irq, nmk_chip); + set_irq_data(nmk_chip->secondary_parent_irq, nmk_chip); } return 0; diff --git a/trunk/arch/arm/plat-omap/gpio.c b/trunk/arch/arm/plat-omap/gpio.c index d2adcdda23cf..971d18636942 100644 --- a/trunk/arch/arm/plat-omap/gpio.c +++ b/trunk/arch/arm/plat-omap/gpio.c @@ -755,12 +755,18 @@ static int gpio_irq_type(struct irq_data *d, unsigned type) bank = irq_data_get_irq_chip_data(d); spin_lock_irqsave(&bank->lock, flags); retval = _set_gpio_triggering(bank, get_gpio_index(gpio), type); + if (retval == 0) { + struct irq_desc *desc = irq_to_desc(d->irq); + + desc->status &= ~IRQ_TYPE_SENSE_MASK; + desc->status |= type; + } spin_unlock_irqrestore(&bank->lock, flags); if (type & (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_LEVEL_HIGH)) - __irq_set_handler_locked(d->irq, handle_level_irq); + __set_irq_handler_unlocked(d->irq, handle_level_irq); else if (type & (IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING)) - __irq_set_handler_locked(d->irq, handle_edge_irq); + __set_irq_handler_unlocked(d->irq, handle_edge_irq); return retval; } @@ -1140,7 +1146,7 @@ static void gpio_irq_handler(unsigned int irq, struct irq_desc *desc) desc->irq_data.chip->irq_ack(&desc->irq_data); - bank = irq_get_handler_data(irq); + bank = get_irq_data(irq); #ifdef CONFIG_ARCH_OMAP1 if (bank->method == METHOD_MPUIO) isr_reg = bank->base + @@ -1264,7 +1270,8 @@ static void gpio_unmask_irq(struct irq_data *d) unsigned int gpio = d->irq - IH_GPIO_BASE; struct gpio_bank *bank = irq_data_get_irq_chip_data(d); unsigned int irq_mask = 1 << get_gpio_index(gpio); - u32 trigger = irqd_get_trigger_type(d); + struct irq_desc *desc = irq_to_desc(d->irq); + u32 trigger = desc->status & IRQ_TYPE_SENSE_MASK; if (trigger) _set_gpio_triggering(bank, get_gpio_index(gpio), trigger); @@ -1665,17 +1672,19 @@ static void __init omap_gpio_chip_init(struct gpio_bank *bank) for (j = bank->virtual_irq_start; j < bank->virtual_irq_start + bank_width; j++) { - irq_set_lockdep_class(j, &gpio_lock_class); - irq_set_chip_data(j, bank); + struct irq_desc *d = irq_to_desc(j); + + lockdep_set_class(&d->lock, &gpio_lock_class); + set_irq_chip_data(j, bank); if (bank_is_mpuio(bank)) - irq_set_chip(j, &mpuio_irq_chip); + set_irq_chip(j, &mpuio_irq_chip); else - irq_set_chip(j, &gpio_irq_chip); - irq_set_handler(j, handle_simple_irq); + set_irq_chip(j, &gpio_irq_chip); + set_irq_handler(j, handle_simple_irq); set_irq_flags(j, IRQF_VALID); } - irq_set_chained_handler(bank->irq, gpio_irq_handler); - irq_set_handler_data(bank->irq, bank); + set_irq_chained_handler(bank->irq, gpio_irq_handler); + set_irq_data(bank->irq, bank); } static int __devinit omap_gpio_probe(struct platform_device *pdev) diff --git a/trunk/arch/arm/plat-omap/include/plat/irqs.h b/trunk/arch/arm/plat-omap/include/plat/irqs.h index 5a25098ea7ea..d77928370463 100644 --- a/trunk/arch/arm/plat-omap/include/plat/irqs.h +++ b/trunk/arch/arm/plat-omap/include/plat/irqs.h @@ -416,7 +416,7 @@ /* GPMC related */ #define OMAP_GPMC_IRQ_BASE (TWL_IRQ_END) -#define OMAP_GPMC_NR_IRQS 8 +#define OMAP_GPMC_NR_IRQS 7 #define OMAP_GPMC_IRQ_END (OMAP_GPMC_IRQ_BASE + OMAP_GPMC_NR_IRQS) diff --git a/trunk/arch/arm/plat-omap/include/plat/onenand.h b/trunk/arch/arm/plat-omap/include/plat/onenand.h index 2858667d2e4f..cbe897ca7f9e 100644 --- a/trunk/arch/arm/plat-omap/include/plat/onenand.h +++ b/trunk/arch/arm/plat-omap/include/plat/onenand.h @@ -32,7 +32,6 @@ struct omap_onenand_platform_data { int dma_channel; u8 flags; u8 regulator_can_sleep; - u8 skip_initial_unlocking; }; #define ONENAND_MAX_PARTITIONS 8 diff --git a/trunk/arch/arm/plat-orion/gpio.c b/trunk/arch/arm/plat-orion/gpio.c index a431a138f402..078894bc3b9a 100644 --- a/trunk/arch/arm/plat-orion/gpio.c +++ b/trunk/arch/arm/plat-orion/gpio.c @@ -324,8 +324,9 @@ EXPORT_SYMBOL(orion_gpio_set_blink); static void gpio_irq_ack(struct irq_data *d) { struct orion_gpio_chip *ochip = irq_data_get_irq_chip_data(d); - int type = irqd_get_trigger_type(d); + int type; + type = irq_desc[d->irq].status & IRQ_TYPE_SENSE_MASK; if (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING)) { int pin = d->irq - ochip->secondary_irq_base; @@ -336,10 +337,11 @@ static void gpio_irq_ack(struct irq_data *d) static void gpio_irq_mask(struct irq_data *d) { struct orion_gpio_chip *ochip = irq_data_get_irq_chip_data(d); - int type = irqd_get_trigger_type(d); + int type; void __iomem *reg; int pin; + type = irq_desc[d->irq].status & IRQ_TYPE_SENSE_MASK; if (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING)) reg = GPIO_EDGE_MASK(ochip); else @@ -353,10 +355,11 @@ static void gpio_irq_mask(struct irq_data *d) static void gpio_irq_unmask(struct irq_data *d) { struct orion_gpio_chip *ochip = irq_data_get_irq_chip_data(d); - int type = irqd_get_trigger_type(d); + int type; void __iomem *reg; int pin; + type = irq_desc[d->irq].status & IRQ_TYPE_SENSE_MASK; if (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING)) reg = GPIO_EDGE_MASK(ochip); else @@ -386,9 +389,9 @@ static int gpio_irq_set_type(struct irq_data *d, u32 type) * Set edge/level type. */ if (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING)) { - __irq_set_handler_locked(d->irq, handle_edge_irq); + set_irq_handler(d->irq, handle_edge_irq); } else if (type & (IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_LEVEL_LOW)) { - __irq_set_handler_locked(d->irq, handle_level_irq); + set_irq_handler(d->irq, handle_level_irq); } else { printk(KERN_ERR "failed to set irq=%d (type=%d)\n", d->irq, type); @@ -474,10 +477,10 @@ void __init orion_gpio_init(int gpio_base, int ngpio, for (i = 0; i < ngpio; i++) { unsigned int irq = secondary_irq_base + i; - irq_set_chip_and_handler(irq, &orion_gpio_irq_chip, - handle_level_irq); - irq_set_chip_data(irq, ochip); - irq_set_status_flags(irq, IRQ_LEVEL); + set_irq_chip(irq, &orion_gpio_irq_chip); + set_irq_handler(irq, handle_level_irq); + set_irq_chip_data(irq, ochip); + irq_desc[irq].status |= IRQ_LEVEL; set_irq_flags(irq, IRQF_VALID); } } @@ -485,7 +488,7 @@ void __init orion_gpio_init(int gpio_base, int ngpio, void orion_gpio_irq_handler(int pinoff) { struct orion_gpio_chip *ochip; - u32 cause, type; + u32 cause; int i; ochip = orion_gpio_chip_find(pinoff); @@ -497,14 +500,15 @@ void orion_gpio_irq_handler(int pinoff) for (i = 0; i < ochip->chip.ngpio; i++) { int irq; + struct irq_desc *desc; irq = ochip->secondary_irq_base + i; if (!(cause & (1 << i))) continue; - type = irqd_get_trigger_type(irq_get_irq_data(irq)); - if ((type & IRQ_TYPE_SENSE_MASK) == IRQ_TYPE_EDGE_BOTH) { + desc = irq_desc + irq; + if ((desc->status & IRQ_TYPE_SENSE_MASK) == IRQ_TYPE_EDGE_BOTH) { /* Swap polarity (race with GPIO line) */ u32 polarity; @@ -512,6 +516,7 @@ void orion_gpio_irq_handler(int pinoff) polarity ^= 1 << i; writel(polarity, GPIO_IN_POL(ochip)); } - generic_handle_irq(irq); + + desc_handle_irq(irq, desc); } } diff --git a/trunk/arch/arm/plat-orion/irq.c b/trunk/arch/arm/plat-orion/irq.c index d8d638e09f8f..7d0c7eb59f09 100644 --- a/trunk/arch/arm/plat-orion/irq.c +++ b/trunk/arch/arm/plat-orion/irq.c @@ -56,10 +56,10 @@ void __init orion_irq_init(unsigned int irq_start, void __iomem *maskaddr) for (i = 0; i < 32; i++) { unsigned int irq = irq_start + i; - irq_set_chip_and_handler(irq, &orion_irq_chip, - handle_level_irq); - irq_set_chip_data(irq, maskaddr); - irq_set_status_flags(irq, IRQ_LEVEL); + set_irq_chip(irq, &orion_irq_chip); + set_irq_chip_data(irq, maskaddr); + set_irq_handler(irq, handle_level_irq); + irq_desc[irq].status |= IRQ_LEVEL; set_irq_flags(irq, IRQF_VALID); } } diff --git a/trunk/arch/arm/plat-pxa/gpio.c b/trunk/arch/arm/plat-pxa/gpio.c index dce088f45678..e7de6ae2a1e8 100644 --- a/trunk/arch/arm/plat-pxa/gpio.c +++ b/trunk/arch/arm/plat-pxa/gpio.c @@ -284,13 +284,13 @@ void __init pxa_init_gpio(int mux_irq, int start, int end, set_wake_t fn) } for (irq = gpio_to_irq(start); irq <= gpio_to_irq(end); irq++) { - irq_set_chip_and_handler(irq, &pxa_muxed_gpio_chip, - handle_edge_irq); + set_irq_chip(irq, &pxa_muxed_gpio_chip); + set_irq_handler(irq, handle_edge_irq); set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); } /* Install handler for GPIO>=2 edge detect interrupts */ - irq_set_chained_handler(mux_irq, pxa_gpio_demux_handler); + set_irq_chained_handler(mux_irq, pxa_gpio_demux_handler); pxa_muxed_gpio_chip.irq_set_wake = fn; } diff --git a/trunk/arch/arm/plat-pxa/include/plat/pxa3xx_nand.h b/trunk/arch/arm/plat-pxa/include/plat/pxa3xx_nand.h index 442301fe48b4..01a8448e471c 100644 --- a/trunk/arch/arm/plat-pxa/include/plat/pxa3xx_nand.h +++ b/trunk/arch/arm/plat-pxa/include/plat/pxa3xx_nand.h @@ -30,7 +30,6 @@ struct pxa3xx_nand_cmdset { }; struct pxa3xx_nand_flash { - char *name; uint32_t chip_id; unsigned int page_per_block; /* Pages per block (PG_PER_BLK) */ unsigned int page_size; /* Page size in bytes (PAGE_SZ) */ @@ -38,6 +37,7 @@ struct pxa3xx_nand_flash { unsigned int dfc_width; /* Width of flash controller(DWIDTH_C) */ unsigned int num_blocks; /* Number of physical blocks in Flash */ + struct pxa3xx_nand_cmdset *cmdset; /* NAND command set */ struct pxa3xx_nand_timing *timing; /* NAND Flash timing */ }; diff --git a/trunk/arch/arm/plat-s3c24xx/irq.c b/trunk/arch/arm/plat-s3c24xx/irq.c index 9aee7e1668b1..4434cb56bd9a 100644 --- a/trunk/arch/arm/plat-s3c24xx/irq.c +++ b/trunk/arch/arm/plat-s3c24xx/irq.c @@ -592,8 +592,8 @@ void __init s3c24xx_init_irq(void) case IRQ_UART1: case IRQ_UART2: case IRQ_ADCPARENT: - irq_set_chip_and_handler(irqno, &s3c_irq_level_chip, - handle_level_irq); + set_irq_chip(irqno, &s3c_irq_level_chip); + set_irq_handler(irqno, handle_level_irq); break; case IRQ_RESERVED6: @@ -603,35 +603,35 @@ void __init s3c24xx_init_irq(void) default: //irqdbf("registering irq %d (s3c irq)\n", irqno); - irq_set_chip_and_handler(irqno, &s3c_irq_chip, - handle_edge_irq); + set_irq_chip(irqno, &s3c_irq_chip); + set_irq_handler(irqno, handle_edge_irq); set_irq_flags(irqno, IRQF_VALID); } } /* setup the cascade irq handlers */ - irq_set_chained_handler(IRQ_EINT4t7, s3c_irq_demux_extint4t7); - irq_set_chained_handler(IRQ_EINT8t23, s3c_irq_demux_extint8); + set_irq_chained_handler(IRQ_EINT4t7, s3c_irq_demux_extint4t7); + set_irq_chained_handler(IRQ_EINT8t23, s3c_irq_demux_extint8); - irq_set_chained_handler(IRQ_UART0, s3c_irq_demux_uart0); - irq_set_chained_handler(IRQ_UART1, s3c_irq_demux_uart1); - irq_set_chained_handler(IRQ_UART2, s3c_irq_demux_uart2); - irq_set_chained_handler(IRQ_ADCPARENT, s3c_irq_demux_adc); + set_irq_chained_handler(IRQ_UART0, s3c_irq_demux_uart0); + set_irq_chained_handler(IRQ_UART1, s3c_irq_demux_uart1); + set_irq_chained_handler(IRQ_UART2, s3c_irq_demux_uart2); + set_irq_chained_handler(IRQ_ADCPARENT, s3c_irq_demux_adc); /* external interrupts */ for (irqno = IRQ_EINT0; irqno <= IRQ_EINT3; irqno++) { irqdbf("registering irq %d (ext int)\n", irqno); - irq_set_chip_and_handler(irqno, &s3c_irq_eint0t4, - handle_edge_irq); + set_irq_chip(irqno, &s3c_irq_eint0t4); + set_irq_handler(irqno, handle_edge_irq); set_irq_flags(irqno, IRQF_VALID); } for (irqno = IRQ_EINT4; irqno <= IRQ_EINT23; irqno++) { irqdbf("registering irq %d (extended s3c irq)\n", irqno); - irq_set_chip_and_handler(irqno, &s3c_irqext_chip, - handle_edge_irq); + set_irq_chip(irqno, &s3c_irqext_chip); + set_irq_handler(irqno, handle_edge_irq); set_irq_flags(irqno, IRQF_VALID); } @@ -641,28 +641,29 @@ void __init s3c24xx_init_irq(void) for (irqno = IRQ_S3CUART_RX0; irqno <= IRQ_S3CUART_ERR0; irqno++) { irqdbf("registering irq %d (s3c uart0 irq)\n", irqno); - irq_set_chip_and_handler(irqno, &s3c_irq_uart0, - handle_level_irq); + set_irq_chip(irqno, &s3c_irq_uart0); + set_irq_handler(irqno, handle_level_irq); set_irq_flags(irqno, IRQF_VALID); } for (irqno = IRQ_S3CUART_RX1; irqno <= IRQ_S3CUART_ERR1; irqno++) { irqdbf("registering irq %d (s3c uart1 irq)\n", irqno); - irq_set_chip_and_handler(irqno, &s3c_irq_uart1, - handle_level_irq); + set_irq_chip(irqno, &s3c_irq_uart1); + set_irq_handler(irqno, handle_level_irq); set_irq_flags(irqno, IRQF_VALID); } for (irqno = IRQ_S3CUART_RX2; irqno <= IRQ_S3CUART_ERR2; irqno++) { irqdbf("registering irq %d (s3c uart2 irq)\n", irqno); - irq_set_chip_and_handler(irqno, &s3c_irq_uart2, - handle_level_irq); + set_irq_chip(irqno, &s3c_irq_uart2); + set_irq_handler(irqno, handle_level_irq); set_irq_flags(irqno, IRQF_VALID); } for (irqno = IRQ_TC; irqno <= IRQ_ADC; irqno++) { irqdbf("registering irq %d (s3c adc irq)\n", irqno); - irq_set_chip_and_handler(irqno, &s3c_irq_adc, handle_edge_irq); + set_irq_chip(irqno, &s3c_irq_adc); + set_irq_handler(irqno, handle_edge_irq); set_irq_flags(irqno, IRQF_VALID); } diff --git a/trunk/arch/arm/plat-s5p/cpu.c b/trunk/arch/arm/plat-s5p/cpu.c index 5cf5e721e6ca..c3bfe9b13acf 100644 --- a/trunk/arch/arm/plat-s5p/cpu.c +++ b/trunk/arch/arm/plat-s5p/cpu.c @@ -39,7 +39,7 @@ static const char name_exynos4210[] = "EXYNOS4210"; static struct cpu_table cpu_ids[] __initdata = { { .idcode = 0x56440100, - .idmask = 0xfffff000, + .idmask = 0xffffff00, .map_io = s5p6440_map_io, .init_clocks = s5p6440_init_clocks, .init_uarts = s5p6440_init_uarts, @@ -47,7 +47,7 @@ static struct cpu_table cpu_ids[] __initdata = { .name = name_s5p6440, }, { .idcode = 0x36442000, - .idmask = 0xfffff000, + .idmask = 0xffffff00, .map_io = s5p6442_map_io, .init_clocks = s5p6442_init_clocks, .init_uarts = s5p6442_init_uarts, @@ -55,7 +55,7 @@ static struct cpu_table cpu_ids[] __initdata = { .name = name_s5p6442, }, { .idcode = 0x36450000, - .idmask = 0xfffff000, + .idmask = 0xffffff00, .map_io = s5p6450_map_io, .init_clocks = s5p6450_init_clocks, .init_uarts = s5p6450_init_uarts, @@ -79,7 +79,7 @@ static struct cpu_table cpu_ids[] __initdata = { .name = name_s5pv210, }, { .idcode = 0x43210000, - .idmask = 0xfffe0000, + .idmask = 0xfffff000, .map_io = exynos4_map_io, .init_clocks = exynos4_init_clocks, .init_uarts = exynos4_init_uarts, diff --git a/trunk/arch/arm/plat-s5p/irq-eint.c b/trunk/arch/arm/plat-s5p/irq-eint.c index b5bb774985b0..225aa25405db 100644 --- a/trunk/arch/arm/plat-s5p/irq-eint.c +++ b/trunk/arch/arm/plat-s5p/irq-eint.c @@ -205,14 +205,15 @@ int __init s5p_init_irq_eint(void) int irq; for (irq = IRQ_EINT(0); irq <= IRQ_EINT(15); irq++) - irq_set_chip(irq, &s5p_irq_vic_eint); + set_irq_chip(irq, &s5p_irq_vic_eint); for (irq = IRQ_EINT(16); irq <= IRQ_EINT(31); irq++) { - irq_set_chip_and_handler(irq, &s5p_irq_eint, handle_level_irq); + set_irq_chip(irq, &s5p_irq_eint); + set_irq_handler(irq, handle_level_irq); set_irq_flags(irq, IRQF_VALID); } - irq_set_chained_handler(IRQ_EINT16_31, s5p_irq_demux_eint16_31); + set_irq_chained_handler(IRQ_EINT16_31, s5p_irq_demux_eint16_31); return 0; } diff --git a/trunk/arch/arm/plat-s5p/irq-gpioint.c b/trunk/arch/arm/plat-s5p/irq-gpioint.c index 46dd078147d8..cd87d3256e03 100644 --- a/trunk/arch/arm/plat-s5p/irq-gpioint.c +++ b/trunk/arch/arm/plat-s5p/irq-gpioint.c @@ -43,13 +43,13 @@ LIST_HEAD(banks); static int s5p_gpioint_get_offset(struct irq_data *data) { - struct s3c_gpio_chip *chip = irq_data_get_irq_handler_data(data); + struct s3c_gpio_chip *chip = irq_data_get_irq_data(data); return data->irq - chip->irq_base; } static void s5p_gpioint_ack(struct irq_data *data) { - struct s3c_gpio_chip *chip = irq_data_get_irq_handler_data(data); + struct s3c_gpio_chip *chip = irq_data_get_irq_data(data); int group, offset, pend_offset; unsigned int value; @@ -64,7 +64,7 @@ static void s5p_gpioint_ack(struct irq_data *data) static void s5p_gpioint_mask(struct irq_data *data) { - struct s3c_gpio_chip *chip = irq_data_get_irq_handler_data(data); + struct s3c_gpio_chip *chip = irq_data_get_irq_data(data); int group, offset, mask_offset; unsigned int value; @@ -79,7 +79,7 @@ static void s5p_gpioint_mask(struct irq_data *data) static void s5p_gpioint_unmask(struct irq_data *data) { - struct s3c_gpio_chip *chip = irq_data_get_irq_handler_data(data); + struct s3c_gpio_chip *chip = irq_data_get_irq_data(data); int group, offset, mask_offset; unsigned int value; @@ -100,7 +100,7 @@ static void s5p_gpioint_mask_ack(struct irq_data *data) static int s5p_gpioint_set_type(struct irq_data *data, unsigned int type) { - struct s3c_gpio_chip *chip = irq_data_get_irq_handler_data(data); + struct s3c_gpio_chip *chip = irq_data_get_irq_data(data); int group, offset, con_offset; unsigned int value; @@ -149,7 +149,7 @@ static struct irq_chip s5p_gpioint = { static void s5p_gpioint_handler(unsigned int irq, struct irq_desc *desc) { - struct s5p_gpioint_bank *bank = irq_get_handler_data(irq); + struct s5p_gpioint_bank *bank = get_irq_data(irq); int group, pend_offset, mask_offset; unsigned int pend, mask; @@ -200,8 +200,8 @@ static __init int s5p_gpioint_add(struct s3c_gpio_chip *chip) if (!bank->chips) return -ENOMEM; - irq_set_chained_handler(bank->irq, s5p_gpioint_handler); - irq_set_handler_data(bank->irq, bank); + set_irq_chained_handler(bank->irq, s5p_gpioint_handler); + set_irq_data(bank->irq, bank); bank->handler = s5p_gpioint_handler; printk(KERN_INFO "Registered chained gpio int handler for interrupt %d.\n", bank->irq); @@ -219,9 +219,9 @@ static __init int s5p_gpioint_add(struct s3c_gpio_chip *chip) bank->chips[group - bank->start] = chip; for (i = 0; i < chip->chip.ngpio; i++) { irq = chip->irq_base + i; - irq_set_chip(irq, &s5p_gpioint); - irq_set_handler_data(irq, chip); - irq_set_handler(irq, handle_level_irq); + set_irq_chip(irq, &s5p_gpioint); + set_irq_data(irq, chip); + set_irq_handler(irq, handle_level_irq); set_irq_flags(irq, IRQF_VALID); } return 0; diff --git a/trunk/arch/arm/plat-samsung/init.c b/trunk/arch/arm/plat-samsung/init.c index 79d10fca9090..6790edfaca6f 100644 --- a/trunk/arch/arm/plat-samsung/init.c +++ b/trunk/arch/arm/plat-samsung/init.c @@ -36,7 +36,7 @@ static struct cpu_table * __init s3c_lookup_cpu(unsigned long idcode, unsigned int count) { for (; count != 0; count--, tab++) { - if ((idcode & tab->idmask) == (tab->idcode & tab->idmask)) + if ((idcode & tab->idmask) == tab->idcode) return tab; } diff --git a/trunk/arch/arm/plat-samsung/irq-uart.c b/trunk/arch/arm/plat-samsung/irq-uart.c index 4d4e571af553..4e770355ccbc 100644 --- a/trunk/arch/arm/plat-samsung/irq-uart.c +++ b/trunk/arch/arm/plat-samsung/irq-uart.c @@ -107,6 +107,7 @@ static struct irq_chip s3c_irq_uart = { static void __init s3c_init_uart_irq(struct s3c_uart_irq *uirq) { + struct irq_desc *desc = irq_to_desc(uirq->parent_irq); void __iomem *reg_base = uirq->regs; unsigned int irq; int offs; @@ -117,13 +118,14 @@ static void __init s3c_init_uart_irq(struct s3c_uart_irq *uirq) for (offs = 0; offs < 3; offs++) { irq = uirq->base_irq + offs; - irq_set_chip_and_handler(irq, &s3c_irq_uart, handle_level_irq); - irq_set_chip_data(irq, uirq); + set_irq_chip(irq, &s3c_irq_uart); + set_irq_chip_data(irq, uirq); + set_irq_handler(irq, handle_level_irq); set_irq_flags(irq, IRQF_VALID); } - irq_set_handler_data(uirq->parent_irq, uirq); - irq_set_chained_handler(uirq->parent_irq, s3c_irq_demux_uart); + desc->irq_data.handler_data = uirq; + set_irq_chained_handler(uirq->parent_irq, s3c_irq_demux_uart); } /** diff --git a/trunk/arch/arm/plat-samsung/irq-vic-timer.c b/trunk/arch/arm/plat-samsung/irq-vic-timer.c index d6ad66ab9290..dd8692ae5c4c 100644 --- a/trunk/arch/arm/plat-samsung/irq-vic-timer.c +++ b/trunk/arch/arm/plat-samsung/irq-vic-timer.c @@ -77,11 +77,14 @@ static struct irq_chip s3c_irq_timer = { void __init s3c_init_vic_timer_irq(unsigned int parent_irq, unsigned int timer_irq) { + struct irq_desc *desc = irq_to_desc(parent_irq); - irq_set_chained_handler(parent_irq, s3c_irq_demux_vic_timer); - irq_set_handler_data(parent_irq, (void *)timer_irq); + set_irq_chained_handler(parent_irq, s3c_irq_demux_vic_timer); - irq_set_chip_and_handler(timer_irq, &s3c_irq_timer, handle_level_irq); - irq_set_chip_data(timer_irq, (void *)(1 << (timer_irq - IRQ_TIMER0))); + set_irq_chip(timer_irq, &s3c_irq_timer); + set_irq_chip_data(timer_irq, (void *)(1 << (timer_irq - IRQ_TIMER0))); + set_irq_handler(timer_irq, handle_level_irq); set_irq_flags(timer_irq, IRQF_VALID); + + desc->irq_data.handler_data = (void *)timer_irq; } diff --git a/trunk/arch/arm/plat-samsung/wakeup-mask.c b/trunk/arch/arm/plat-samsung/wakeup-mask.c index dc814037297b..2e09b6ad84ca 100644 --- a/trunk/arch/arm/plat-samsung/wakeup-mask.c +++ b/trunk/arch/arm/plat-samsung/wakeup-mask.c @@ -22,7 +22,7 @@ void samsung_sync_wakemask(void __iomem *reg, struct samsung_wakeup_mask *mask, int nr_mask) { - struct irq_data *data; + struct irq_desc *desc; u32 val; val = __raw_readl(reg); @@ -33,10 +33,10 @@ void samsung_sync_wakemask(void __iomem *reg, continue; } - data = irq_get_irq_data(mask->irq); + desc = irq_to_desc(mask->irq); - /* bit of a liberty to read this directly from irq_data. */ - if (irqd_is_wakeup_set(data)) + /* bit of a liberty to read this directly from irq_desc. */ + if (desc->wake_depth > 0) val &= ~mask->bit; else val |= mask->bit; diff --git a/trunk/arch/arm/plat-spear/shirq.c b/trunk/arch/arm/plat-spear/shirq.c index 961fb7261243..78189035e7f1 100644 --- a/trunk/arch/arm/plat-spear/shirq.c +++ b/trunk/arch/arm/plat-spear/shirq.c @@ -68,7 +68,7 @@ static struct irq_chip shirq_chip = { static void shirq_handler(unsigned irq, struct irq_desc *desc) { u32 i, val, mask; - struct spear_shirq *shirq = irq_get_handler_data(irq); + struct spear_shirq *shirq = get_irq_data(irq); desc->irq_data.chip->irq_ack(&desc->irq_data); while ((val = readl(shirq->regs.base + shirq->regs.status_reg) & @@ -105,14 +105,14 @@ int spear_shirq_register(struct spear_shirq *shirq) if (!shirq->dev_count) return -EINVAL; - irq_set_chained_handler(shirq->irq, shirq_handler); + set_irq_chained_handler(shirq->irq, shirq_handler); for (i = 0; i < shirq->dev_count; i++) { - irq_set_chip_and_handler(shirq->dev_config[i].virq, - &shirq_chip, handle_simple_irq); + set_irq_chip(shirq->dev_config[i].virq, &shirq_chip); + set_irq_handler(shirq->dev_config[i].virq, handle_simple_irq); set_irq_flags(shirq->dev_config[i].virq, IRQF_VALID); - irq_set_chip_data(shirq->dev_config[i].virq, shirq); + set_irq_chip_data(shirq->dev_config[i].virq, shirq); } - irq_set_handler_data(shirq->irq, shirq); + set_irq_data(shirq->irq, shirq); return 0; } diff --git a/trunk/arch/arm/plat-stmp3xxx/irq.c b/trunk/arch/arm/plat-stmp3xxx/irq.c index 6fdf9acf82ed..aaa168683d4e 100644 --- a/trunk/arch/arm/plat-stmp3xxx/irq.c +++ b/trunk/arch/arm/plat-stmp3xxx/irq.c @@ -35,7 +35,8 @@ void __init stmp3xxx_init_irq(struct irq_chip *chip) /* Disable all interrupts initially */ for (i = 0; i < NR_REAL_IRQS; i++) { chip->irq_mask(irq_get_irq_data(i)); - irq_set_chip_and_handler(i, chip, handle_level_irq); + set_irq_chip(i, chip); + set_irq_handler(i, handle_level_irq); set_irq_flags(i, IRQF_VALID | IRQF_PROBE); } diff --git a/trunk/arch/arm/plat-stmp3xxx/pinmux.c b/trunk/arch/arm/plat-stmp3xxx/pinmux.c index 3def03b3217d..66d5bac3ace2 100644 --- a/trunk/arch/arm/plat-stmp3xxx/pinmux.c +++ b/trunk/arch/arm/plat-stmp3xxx/pinmux.c @@ -489,13 +489,14 @@ static void stmp3xxx_gpio_free(struct gpio_chip *chip, unsigned offset) static void stmp3xxx_gpio_irq(u32 irq, struct irq_desc *desc) { - struct stmp3xxx_pinmux_bank *pm = irq_get_handler_data(irq); + struct stmp3xxx_pinmux_bank *pm = get_irq_data(irq); int gpio_irq = pm->virq; u32 stat = __raw_readl(pm->irqstat); while (stat) { if (stat & 1) - generic_handle_irq(gpio_irq); + irq_desc[gpio_irq].handle_irq(gpio_irq, + &irq_desc[gpio_irq]); gpio_irq++; stat >>= 1; } @@ -533,15 +534,15 @@ int __init stmp3xxx_pinmux_init(int virtual_irq_start) for (virq = pm->virq; virq < pm->virq; virq++) { gpio_irq_chip.irq_mask(irq_get_irq_data(virq)); - irq_set_chip_and_handler(virq, &gpio_irq_chip, - handle_level_irq); + set_irq_chip(virq, &gpio_irq_chip); + set_irq_handler(virq, handle_level_irq); set_irq_flags(virq, IRQF_VALID); } r = gpiochip_add(&pm->chip); if (r < 0) break; - irq_set_chained_handler(pm->irq, stmp3xxx_gpio_irq); - irq_set_handler_data(pm->irq, pm); + set_irq_chained_handler(pm->irq, stmp3xxx_gpio_irq); + set_irq_data(pm->irq, pm); } return r; } diff --git a/trunk/arch/arm/plat-versatile/fpga-irq.c b/trunk/arch/arm/plat-versatile/fpga-irq.c index f0cc8e19b094..31d945d37e4f 100644 --- a/trunk/arch/arm/plat-versatile/fpga-irq.c +++ b/trunk/arch/arm/plat-versatile/fpga-irq.c @@ -30,7 +30,7 @@ static void fpga_irq_unmask(struct irq_data *d) static void fpga_irq_handle(unsigned int irq, struct irq_desc *desc) { - struct fpga_irq_data *f = irq_desc_get_handler_data(desc); + struct fpga_irq_data *f = get_irq_desc_data(desc); u32 status = readl(f->base + IRQ_STATUS); if (status == 0) { @@ -55,17 +55,17 @@ void __init fpga_irq_init(int parent_irq, u32 valid, struct fpga_irq_data *f) f->chip.irq_unmask = fpga_irq_unmask; if (parent_irq != -1) { - irq_set_handler_data(parent_irq, f); - irq_set_chained_handler(parent_irq, fpga_irq_handle); + set_irq_data(parent_irq, f); + set_irq_chained_handler(parent_irq, fpga_irq_handle); } for (i = 0; i < 32; i++) { if (valid & (1 << i)) { unsigned int irq = f->irq_start + i; - irq_set_chip_data(irq, f); - irq_set_chip_and_handler(irq, &f->chip, - handle_level_irq); + set_irq_chip_data(irq, f); + set_irq_chip(irq, &f->chip); + set_irq_handler(irq, handle_level_irq); set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); } } diff --git a/trunk/arch/blackfin/kernel/irqchip.c b/trunk/arch/blackfin/kernel/irqchip.c index 1696d34f51c2..8f079392aff0 100644 --- a/trunk/arch/blackfin/kernel/irqchip.c +++ b/trunk/arch/blackfin/kernel/irqchip.c @@ -48,7 +48,7 @@ int show_interrupts(struct seq_file *p, void *v) seq_printf(p, "%3d: ", i); for_each_online_cpu(j) seq_printf(p, "%10u ", kstat_irqs_cpu(i, j)); - seq_printf(p, " %8s", irq_desc_get_chip(desc)->name); + seq_printf(p, " %8s", get_irq_desc_chip(desc)->name); seq_printf(p, " %s", action->name); for (action = action->next; action; action = action->next) seq_printf(p, " %s", action->name); diff --git a/trunk/arch/blackfin/kernel/trace.c b/trunk/arch/blackfin/kernel/trace.c index 050db44fe919..05b550891ce5 100644 --- a/trunk/arch/blackfin/kernel/trace.c +++ b/trunk/arch/blackfin/kernel/trace.c @@ -912,11 +912,10 @@ void show_regs(struct pt_regs *fp) /* if no interrupts are going off, don't print this out */ if (fp->ipend & ~0x3F) { for (i = 0; i < (NR_IRQS - 1); i++) { - struct irq_desc *desc = irq_to_desc(i); if (!in_atomic) - raw_spin_lock_irqsave(&desc->lock, flags); + raw_spin_lock_irqsave(&irq_desc[i].lock, flags); - action = desc->action; + action = irq_desc[i].action; if (!action) goto unlock; @@ -929,7 +928,7 @@ void show_regs(struct pt_regs *fp) pr_cont("\n"); unlock: if (!in_atomic) - raw_spin_unlock_irqrestore(&desc->lock, flags); + raw_spin_unlock_irqrestore(&irq_desc[i].lock, flags); } } diff --git a/trunk/arch/blackfin/mach-bf561/smp.c b/trunk/arch/blackfin/mach-bf561/smp.c index 7b07740cf68c..5d68bf613b0b 100644 --- a/trunk/arch/blackfin/mach-bf561/smp.c +++ b/trunk/arch/blackfin/mach-bf561/smp.c @@ -154,13 +154,13 @@ void platform_clear_ipi(unsigned int cpu, int irq) void __cpuinit bfin_local_timer_setup(void) { #if defined(CONFIG_TICKSOURCE_CORETMR) - struct irq_data *data = irq_get_irq_data(IRQ_CORETMR); - struct irq_chip *chip = irq_data_get_irq_chip(data); + struct irq_chip *chip = get_irq_chip(IRQ_CORETMR); + struct irq_desc *desc = irq_to_desc(IRQ_CORETMR); bfin_coretmr_init(); bfin_coretmr_clockevent_init(); - chip->irq_unmask(data); + chip->irq_unmask(&desc->irq_data); #else /* Power down the core timer, just to play safe. */ bfin_write_TCNTL(0); diff --git a/trunk/arch/blackfin/mach-common/ints-priority.c b/trunk/arch/blackfin/mach-common/ints-priority.c index 43d9fb195c1e..6cd52395a999 100644 --- a/trunk/arch/blackfin/mach-common/ints-priority.c +++ b/trunk/arch/blackfin/mach-common/ints-priority.c @@ -559,7 +559,7 @@ static inline void bfin_set_irq_handler(unsigned irq, irq_flow_handler_t handle) #ifdef CONFIG_IPIPE handle = handle_level_irq; #endif - __irq_set_handler_locked(irq, handle); + __set_irq_handler_unlocked(irq, handle); } static DECLARE_BITMAP(gpio_enabled, MAX_BLACKFIN_GPIOS); @@ -578,9 +578,10 @@ static void bfin_gpio_ack_irq(struct irq_data *d) static void bfin_gpio_mask_ack_irq(struct irq_data *d) { unsigned int irq = d->irq; + struct irq_desc *desc = irq_to_desc(irq); u32 gpionr = irq_to_gpio(irq); - if (!irqd_is_level_type(d)) + if (desc->handle_irq == handle_edge_irq) set_gpio_data(gpionr, 0); set_gpio_maska(gpionr, 0); @@ -836,11 +837,12 @@ void init_pint_lut(void) static void bfin_gpio_ack_irq(struct irq_data *d) { + struct irq_desc *desc = irq_to_desc(d->irq); u32 pint_val = irq2pint_lut[d->irq - SYS_IRQS]; u32 pintbit = PINT_BIT(pint_val); u32 bank = PINT_2_BANK(pint_val); - if (irqd_get_trigger_type(d) == IRQ_TYPE_EDGE_BOTH) { + if ((desc->status & IRQ_TYPE_SENSE_MASK) == IRQ_TYPE_EDGE_BOTH) { if (pint[bank]->invert_set & pintbit) pint[bank]->invert_clear = pintbit; else @@ -852,11 +854,12 @@ static void bfin_gpio_ack_irq(struct irq_data *d) static void bfin_gpio_mask_ack_irq(struct irq_data *d) { + struct irq_desc *desc = irq_to_desc(d->irq); u32 pint_val = irq2pint_lut[d->irq - SYS_IRQS]; u32 pintbit = PINT_BIT(pint_val); u32 bank = PINT_2_BANK(pint_val); - if (irqd_get_trigger_type(d) == IRQ_TYPE_EDGE_BOTH) { + if ((desc->status & IRQ_TYPE_SENSE_MASK) == IRQ_TYPE_EDGE_BOTH) { if (pint[bank]->invert_set & pintbit) pint[bank]->invert_clear = pintbit; else @@ -1163,9 +1166,9 @@ int __init init_arch_irq(void) for (irq = 0; irq <= SYS_IRQS; irq++) { if (irq <= IRQ_CORETMR) - irq_set_chip(irq, &bfin_core_irqchip); + set_irq_chip(irq, &bfin_core_irqchip); else - irq_set_chip(irq, &bfin_internal_irqchip); + set_irq_chip(irq, &bfin_internal_irqchip); switch (irq) { #if defined(CONFIG_BF53x) @@ -1189,50 +1192,50 @@ int __init init_arch_irq(void) #elif defined(CONFIG_BF538) || defined(CONFIG_BF539) case IRQ_PORTF_INTA: #endif - irq_set_chained_handler(irq, bfin_demux_gpio_irq); + set_irq_chained_handler(irq, + bfin_demux_gpio_irq); break; #ifdef BF537_GENERIC_ERROR_INT_DEMUX case IRQ_GENERIC_ERROR: - irq_set_chained_handler(irq, bfin_demux_error_irq); + set_irq_chained_handler(irq, bfin_demux_error_irq); break; #endif #if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE) case IRQ_MAC_ERROR: - irq_set_chained_handler(irq, - bfin_demux_mac_status_irq); + set_irq_chained_handler(irq, bfin_demux_mac_status_irq); break; #endif #ifdef CONFIG_SMP case IRQ_SUPPLE_0: case IRQ_SUPPLE_1: - irq_set_handler(irq, handle_percpu_irq); + set_irq_handler(irq, handle_percpu_irq); break; #endif #ifdef CONFIG_TICKSOURCE_CORETMR case IRQ_CORETMR: # ifdef CONFIG_SMP - irq_set_handler(irq, handle_percpu_irq); + set_irq_handler(irq, handle_percpu_irq); break; # else - irq_set_handler(irq, handle_simple_irq); + set_irq_handler(irq, handle_simple_irq); break; # endif #endif #ifdef CONFIG_TICKSOURCE_GPTMR0 case IRQ_TIMER0: - irq_set_handler(irq, handle_simple_irq); + set_irq_handler(irq, handle_simple_irq); break; #endif #ifdef CONFIG_IPIPE default: - irq_set_handler(irq, handle_level_irq); + set_irq_handler(irq, handle_level_irq); break; #else /* !CONFIG_IPIPE */ default: - irq_set_handler(irq, handle_simple_irq); + set_irq_handler(irq, handle_simple_irq); break; #endif /* !CONFIG_IPIPE */ } @@ -1240,22 +1243,22 @@ int __init init_arch_irq(void) #ifdef BF537_GENERIC_ERROR_INT_DEMUX for (irq = IRQ_PPI_ERROR; irq <= IRQ_UART1_ERROR; irq++) - irq_set_chip_and_handler(irq, &bfin_generic_error_irqchip, + set_irq_chip_and_handler(irq, &bfin_generic_error_irqchip, handle_level_irq); #if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE) - irq_set_chained_handler(IRQ_MAC_ERROR, bfin_demux_mac_status_irq); + set_irq_chained_handler(IRQ_MAC_ERROR, bfin_demux_mac_status_irq); #endif #endif #if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE) for (irq = IRQ_MAC_PHYINT; irq <= IRQ_MAC_STMDONE; irq++) - irq_set_chip_and_handler(irq, &bfin_mac_status_irqchip, + set_irq_chip_and_handler(irq, &bfin_mac_status_irqchip, handle_level_irq); #endif /* if configured as edge, then will be changed to do_edge_IRQ */ for (irq = GPIO_IRQ_BASE; irq < (GPIO_IRQ_BASE + MAX_BLACKFIN_GPIOS); irq++) - irq_set_chip_and_handler(irq, &bfin_gpio_irqchip, + set_irq_chip_and_handler(irq, &bfin_gpio_irqchip, handle_level_irq); bfin_write_IMASK(0); diff --git a/trunk/arch/cris/Kconfig b/trunk/arch/cris/Kconfig index 617925ddd142..4db5b46e1eff 100644 --- a/trunk/arch/cris/Kconfig +++ b/trunk/arch/cris/Kconfig @@ -276,6 +276,7 @@ config ETRAX_AXISFLASHMAP select MTD_CHAR select MTD_BLOCK select MTD_PARTITIONS + select MTD_CONCAT select MTD_COMPLEX_MAPPINGS help This option enables MTD mapping of flash devices. Needed to use @@ -296,7 +297,8 @@ config ETRAX_RTC choice prompt "RTC chip" depends on ETRAX_RTC - default ETRAX_DS1302 + default ETRAX_PCF8563 if ETRAX_ARCH_V32 + default ETRAX_DS1302 if ETRAX_ARCH_V10 config ETRAX_DS1302 depends on ETRAX_ARCH_V10 diff --git a/trunk/arch/cris/arch-v10/drivers/axisflashmap.c b/trunk/arch/cris/arch-v10/drivers/axisflashmap.c index ed708e19d09e..b2079703af7e 100644 --- a/trunk/arch/cris/arch-v10/drivers/axisflashmap.c +++ b/trunk/arch/cris/arch-v10/drivers/axisflashmap.c @@ -234,6 +234,7 @@ static struct mtd_info *flash_probe(void) } if (mtd_cse0 && mtd_cse1) { +#ifdef CONFIG_MTD_CONCAT struct mtd_info *mtds[] = { mtd_cse0, mtd_cse1 }; /* Since the concatenation layer adds a small overhead we @@ -245,6 +246,11 @@ static struct mtd_info *flash_probe(void) */ mtd_cse = mtd_concat_create(mtds, ARRAY_SIZE(mtds), "cse0+cse1"); +#else + printk(KERN_ERR "%s and %s: Cannot concatenate due to kernel " + "(mis)configuration!\n", map_cse0.name, map_cse1.name); + mtd_cse = NULL; +#endif if (!mtd_cse) { printk(KERN_ERR "%s and %s: Concatenation failed!\n", map_cse0.name, map_cse1.name); diff --git a/trunk/arch/cris/arch-v10/drivers/pcf8563.c b/trunk/arch/cris/arch-v10/drivers/pcf8563.c index 1391b731ad1c..ea69faba9b62 100644 --- a/trunk/arch/cris/arch-v10/drivers/pcf8563.c +++ b/trunk/arch/cris/arch-v10/drivers/pcf8563.c @@ -345,7 +345,7 @@ static long pcf8563_unlocked_ioctl(struct file *filp, unsigned int cmd, unsigned int ret; mutex_lock(&pcf8563_mutex); - ret = pcf8563_ioctl(filp, cmd, arg); + return pcf8563_ioctl(filp, cmd, arg); mutex_unlock(&pcf8563_mutex); return ret; diff --git a/trunk/arch/cris/arch-v10/kernel/signal.c b/trunk/arch/cris/arch-v10/kernel/signal.c index e78fe49a9849..b6be705c2a3e 100644 --- a/trunk/arch/cris/arch-v10/kernel/signal.c +++ b/trunk/arch/cris/arch-v10/kernel/signal.c @@ -537,7 +537,7 @@ void do_signal(int canrestart, struct pt_regs *regs) RESTART_CRIS_SYS(regs); } if (regs->r10 == -ERESTART_RESTARTBLOCK) { - regs->r9 = __NR_restart_syscall; + regs->r10 = __NR_restart_syscall; regs->irp -= 2; } } diff --git a/trunk/arch/cris/arch-v32/drivers/Kconfig b/trunk/arch/cris/arch-v32/drivers/Kconfig index 1633b120aa81..a2dd740c5907 100644 --- a/trunk/arch/cris/arch-v32/drivers/Kconfig +++ b/trunk/arch/cris/arch-v32/drivers/Kconfig @@ -406,6 +406,7 @@ config ETRAX_AXISFLASHMAP select MTD_CHAR select MTD_BLOCK select MTD_PARTITIONS + select MTD_CONCAT select MTD_COMPLEX_MAPPINGS help This option enables MTD mapping of flash devices. Needed to use diff --git a/trunk/arch/cris/arch-v32/drivers/Makefile b/trunk/arch/cris/arch-v32/drivers/Makefile index 39aa3c117a86..e8c02437edaf 100644 --- a/trunk/arch/cris/arch-v32/drivers/Makefile +++ b/trunk/arch/cris/arch-v32/drivers/Makefile @@ -7,6 +7,7 @@ obj-$(CONFIG_ETRAX_AXISFLASHMAP) += axisflashmap.o obj-$(CONFIG_ETRAXFS) += mach-fs/ obj-$(CONFIG_CRIS_MACH_ARTPEC3) += mach-a3/ obj-$(CONFIG_ETRAX_IOP_FW_LOAD) += iop_fw_load.o +obj-$(CONFIG_ETRAX_PCF8563) += pcf8563.o obj-$(CONFIG_ETRAX_I2C) += i2c.o obj-$(CONFIG_ETRAX_SYNCHRONOUS_SERIAL) += sync_serial.o obj-$(CONFIG_PCI) += pci/ diff --git a/trunk/arch/cris/arch-v32/drivers/axisflashmap.c b/trunk/arch/cris/arch-v32/drivers/axisflashmap.c index 3d751250271b..51e1e85df96d 100644 --- a/trunk/arch/cris/arch-v32/drivers/axisflashmap.c +++ b/trunk/arch/cris/arch-v32/drivers/axisflashmap.c @@ -275,6 +275,7 @@ static struct mtd_info *flash_probe(void) } if (count > 1) { +#ifdef CONFIG_MTD_CONCAT /* Since the concatenation layer adds a small overhead we * could try to figure out if the chips in cse0 and cse1 are * identical and reprobe the whole cse0+cse1 window. But since @@ -283,6 +284,11 @@ static struct mtd_info *flash_probe(void) * complicating the probing procedure. */ mtd_total = mtd_concat_create(mtds, count, "cse0+cse1"); +#else + printk(KERN_ERR "%s and %s: Cannot concatenate due to kernel " + "(mis)configuration!\n", map_cse0.name, map_cse1.name); + mtd_toal = NULL; +#endif if (!mtd_total) { printk(KERN_ERR "%s and %s: Concatenation failed!\n", map_cse0.name, map_cse1.name); diff --git a/trunk/arch/cris/arch-v32/drivers/pcf8563.c b/trunk/arch/cris/arch-v32/drivers/pcf8563.c new file mode 100644 index 000000000000..b6e4fc0aad42 --- /dev/null +++ b/trunk/arch/cris/arch-v32/drivers/pcf8563.c @@ -0,0 +1,377 @@ +/* + * PCF8563 RTC + * + * From Phillips' datasheet: + * + * The PCF8563 is a CMOS real-time clock/calendar optimized for low power + * consumption. A programmable clock output, interrupt output and voltage + * low detector are also provided. All address and data are transferred + * serially via two-line bidirectional I2C-bus. Maximum bus speed is + * 400 kbits/s. The built-in word address register is incremented + * automatically after each written or read byte. + * + * Copyright (c) 2002-2007, Axis Communications AB + * All rights reserved. + * + * Author: Tobias Anderberg . + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "i2c.h" + +#define PCF8563_MAJOR 121 /* Local major number. */ +#define DEVICE_NAME "rtc" /* Name which is registered in /proc/devices. */ +#define PCF8563_NAME "PCF8563" +#define DRIVER_VERSION "$Revision: 1.17 $" + +/* Two simple wrapper macros, saves a few keystrokes. */ +#define rtc_read(x) i2c_readreg(RTC_I2C_READ, x) +#define rtc_write(x,y) i2c_writereg(RTC_I2C_WRITE, x, y) + +static DEFINE_MUTEX(pcf8563_mutex); +static DEFINE_MUTEX(rtc_lock); /* Protect state etc */ + +static const unsigned char days_in_month[] = + { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; + +static long pcf8563_unlocked_ioctl(struct file *filp, unsigned int cmd, unsigned long arg); + +/* Cache VL bit value read at driver init since writing the RTC_SECOND + * register clears the VL status. + */ +static int voltage_low; + +static const struct file_operations pcf8563_fops = { + .owner = THIS_MODULE, + .unlocked_ioctl = pcf8563_unlocked_ioctl, + .llseek = noop_llseek, +}; + +unsigned char +pcf8563_readreg(int reg) +{ + unsigned char res = rtc_read(reg); + + /* The PCF8563 does not return 0 for unimplemented bits. */ + switch (reg) { + case RTC_SECONDS: + case RTC_MINUTES: + res &= 0x7F; + break; + case RTC_HOURS: + case RTC_DAY_OF_MONTH: + res &= 0x3F; + break; + case RTC_WEEKDAY: + res &= 0x07; + break; + case RTC_MONTH: + res &= 0x1F; + break; + case RTC_CONTROL1: + res &= 0xA8; + break; + case RTC_CONTROL2: + res &= 0x1F; + break; + case RTC_CLOCKOUT_FREQ: + case RTC_TIMER_CONTROL: + res &= 0x83; + break; + } + return res; +} + +void +pcf8563_writereg(int reg, unsigned char val) +{ + rtc_write(reg, val); +} + +void +get_rtc_time(struct rtc_time *tm) +{ + tm->tm_sec = rtc_read(RTC_SECONDS); + tm->tm_min = rtc_read(RTC_MINUTES); + tm->tm_hour = rtc_read(RTC_HOURS); + tm->tm_mday = rtc_read(RTC_DAY_OF_MONTH); + tm->tm_wday = rtc_read(RTC_WEEKDAY); + tm->tm_mon = rtc_read(RTC_MONTH); + tm->tm_year = rtc_read(RTC_YEAR); + + if (tm->tm_sec & 0x80) { + printk(KERN_ERR "%s: RTC Voltage Low - reliable date/time " + "information is no longer guaranteed!\n", PCF8563_NAME); + } + + tm->tm_year = bcd2bin(tm->tm_year) + + ((tm->tm_mon & 0x80) ? 100 : 0); + tm->tm_sec &= 0x7F; + tm->tm_min &= 0x7F; + tm->tm_hour &= 0x3F; + tm->tm_mday &= 0x3F; + tm->tm_wday &= 0x07; /* Not coded in BCD. */ + tm->tm_mon &= 0x1F; + + tm->tm_sec = bcd2bin(tm->tm_sec); + tm->tm_min = bcd2bin(tm->tm_min); + tm->tm_hour = bcd2bin(tm->tm_hour); + tm->tm_mday = bcd2bin(tm->tm_mday); + tm->tm_mon = bcd2bin(tm->tm_mon); + tm->tm_mon--; /* Month is 1..12 in RTC but 0..11 in linux */ +} + +int __init +pcf8563_init(void) +{ + static int res; + static int first = 1; + + if (!first) + return res; + first = 0; + + /* Initiate the i2c protocol. */ + res = i2c_init(); + if (res < 0) { + printk(KERN_CRIT "pcf8563_init: Failed to init i2c.\n"); + return res; + } + + /* + * First of all we need to reset the chip. This is done by + * clearing control1, control2 and clk freq and resetting + * all alarms. + */ + if (rtc_write(RTC_CONTROL1, 0x00) < 0) + goto err; + + if (rtc_write(RTC_CONTROL2, 0x00) < 0) + goto err; + + if (rtc_write(RTC_CLOCKOUT_FREQ, 0x00) < 0) + goto err; + + if (rtc_write(RTC_TIMER_CONTROL, 0x03) < 0) + goto err; + + /* Reset the alarms. */ + if (rtc_write(RTC_MINUTE_ALARM, 0x80) < 0) + goto err; + + if (rtc_write(RTC_HOUR_ALARM, 0x80) < 0) + goto err; + + if (rtc_write(RTC_DAY_ALARM, 0x80) < 0) + goto err; + + if (rtc_write(RTC_WEEKDAY_ALARM, 0x80) < 0) + goto err; + + /* Check for low voltage, and warn about it. */ + if (rtc_read(RTC_SECONDS) & 0x80) { + voltage_low = 1; + printk(KERN_WARNING "%s: RTC Voltage Low - reliable " + "date/time information is no longer guaranteed!\n", + PCF8563_NAME); + } + + return res; + +err: + printk(KERN_INFO "%s: Error initializing chip.\n", PCF8563_NAME); + res = -1; + return res; +} + +void __exit +pcf8563_exit(void) +{ + unregister_chrdev(PCF8563_MAJOR, DEVICE_NAME); +} + +/* + * ioctl calls for this driver. Why return -ENOTTY upon error? Because + * POSIX says so! + */ +static int pcf8563_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) +{ + /* Some sanity checks. */ + if (_IOC_TYPE(cmd) != RTC_MAGIC) + return -ENOTTY; + + if (_IOC_NR(cmd) > RTC_MAX_IOCTL) + return -ENOTTY; + + switch (cmd) { + case RTC_RD_TIME: + { + struct rtc_time tm; + + mutex_lock(&rtc_lock); + memset(&tm, 0, sizeof tm); + get_rtc_time(&tm); + + if (copy_to_user((struct rtc_time *) arg, &tm, + sizeof tm)) { + mutex_unlock(&rtc_lock); + return -EFAULT; + } + + mutex_unlock(&rtc_lock); + + return 0; + } + case RTC_SET_TIME: + { + int leap; + int year; + int century; + struct rtc_time tm; + + memset(&tm, 0, sizeof tm); + if (!capable(CAP_SYS_TIME)) + return -EPERM; + + if (copy_from_user(&tm, (struct rtc_time *) arg, + sizeof tm)) + return -EFAULT; + + /* Convert from struct tm to struct rtc_time. */ + tm.tm_year += 1900; + tm.tm_mon += 1; + + /* + * Check if tm.tm_year is a leap year. A year is a leap + * year if it is divisible by 4 but not 100, except + * that years divisible by 400 _are_ leap years. + */ + year = tm.tm_year; + leap = (tm.tm_mon == 2) && + ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0); + + /* Perform some sanity checks. */ + if ((tm.tm_year < 1970) || + (tm.tm_mon > 12) || + (tm.tm_mday == 0) || + (tm.tm_mday > days_in_month[tm.tm_mon] + leap) || + (tm.tm_wday >= 7) || + (tm.tm_hour >= 24) || + (tm.tm_min >= 60) || + (tm.tm_sec >= 60)) + return -EINVAL; + + century = (tm.tm_year >= 2000) ? 0x80 : 0; + tm.tm_year = tm.tm_year % 100; + + tm.tm_year = bin2bcd(tm.tm_year); + tm.tm_mon = bin2bcd(tm.tm_mon); + tm.tm_mday = bin2bcd(tm.tm_mday); + tm.tm_hour = bin2bcd(tm.tm_hour); + tm.tm_min = bin2bcd(tm.tm_min); + tm.tm_sec = bin2bcd(tm.tm_sec); + tm.tm_mon |= century; + + mutex_lock(&rtc_lock); + + rtc_write(RTC_YEAR, tm.tm_year); + rtc_write(RTC_MONTH, tm.tm_mon); + rtc_write(RTC_WEEKDAY, tm.tm_wday); /* Not coded in BCD. */ + rtc_write(RTC_DAY_OF_MONTH, tm.tm_mday); + rtc_write(RTC_HOURS, tm.tm_hour); + rtc_write(RTC_MINUTES, tm.tm_min); + rtc_write(RTC_SECONDS, tm.tm_sec); + + mutex_unlock(&rtc_lock); + + return 0; + } + case RTC_VL_READ: + if (voltage_low) + printk(KERN_ERR "%s: RTC Voltage Low - " + "reliable date/time information is no " + "longer guaranteed!\n", PCF8563_NAME); + + if (copy_to_user((int *) arg, &voltage_low, sizeof(int))) + return -EFAULT; + return 0; + + case RTC_VL_CLR: + { + /* Clear the VL bit in the seconds register in case + * the time has not been set already (which would + * have cleared it). This does not really matter + * because of the cached voltage_low value but do it + * anyway for consistency. */ + + int ret = rtc_read(RTC_SECONDS); + + rtc_write(RTC_SECONDS, (ret & 0x7F)); + + /* Clear the cached value. */ + voltage_low = 0; + + return 0; + } + default: + return -ENOTTY; + } + + return 0; +} + +static long pcf8563_unlocked_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) +{ + int ret; + + mutex_lock(&pcf8563_mutex); + return pcf8563_ioctl(filp, cmd, arg); + mutex_unlock(&pcf8563_mutex); + + return ret; +} + +static int __init pcf8563_register(void) +{ + if (pcf8563_init() < 0) { + printk(KERN_INFO "%s: Unable to initialize Real-Time Clock " + "Driver, %s\n", PCF8563_NAME, DRIVER_VERSION); + return -1; + } + + if (register_chrdev(PCF8563_MAJOR, DEVICE_NAME, &pcf8563_fops) < 0) { + printk(KERN_INFO "%s: Unable to get major numer %d for RTC " + "device.\n", PCF8563_NAME, PCF8563_MAJOR); + return -1; + } + + printk(KERN_INFO "%s Real-Time Clock Driver, %s\n", PCF8563_NAME, + DRIVER_VERSION); + + /* Check for low voltage, and warn about it. */ + if (voltage_low) { + printk(KERN_WARNING "%s: RTC Voltage Low - reliable date/time " + "information is no longer guaranteed!\n", PCF8563_NAME); + } + + return 0; +} + +module_init(pcf8563_register); +module_exit(pcf8563_exit); diff --git a/trunk/arch/frv/Kconfig b/trunk/arch/frv/Kconfig index e06e3c3434a4..f6037b2da25e 100644 --- a/trunk/arch/frv/Kconfig +++ b/trunk/arch/frv/Kconfig @@ -6,8 +6,6 @@ config FRV select HAVE_IRQ_WORK select HAVE_PERF_EVENTS select HAVE_GENERIC_HARDIRQS - select GENERIC_IRQ_SHOW - select GENERIC_HARDIRQS_NO_DEPRECATED config ZONE_DMA bool diff --git a/trunk/arch/frv/kernel/irq-mb93091.c b/trunk/arch/frv/kernel/irq-mb93091.c index 372fe60b1c2e..4dd9adaf115a 100644 --- a/trunk/arch/frv/kernel/irq-mb93091.c +++ b/trunk/arch/frv/kernel/irq-mb93091.c @@ -36,45 +36,45 @@ /* * on-motherboard FPGA PIC operations */ -static void frv_fpga_mask(struct irq_data *d) +static void frv_fpga_mask(unsigned int irq) { uint16_t imr = __get_IMR(); - imr |= 1 << (d->irq - IRQ_BASE_FPGA); + imr |= 1 << (irq - IRQ_BASE_FPGA); __set_IMR(imr); } -static void frv_fpga_ack(struct irq_data *d) +static void frv_fpga_ack(unsigned int irq) { __clr_IFR(1 << (irq - IRQ_BASE_FPGA)); } -static void frv_fpga_mask_ack(struct irq_data *d) +static void frv_fpga_mask_ack(unsigned int irq) { uint16_t imr = __get_IMR(); - imr |= 1 << (d->irq - IRQ_BASE_FPGA); + imr |= 1 << (irq - IRQ_BASE_FPGA); __set_IMR(imr); - __clr_IFR(1 << (d->irq - IRQ_BASE_FPGA)); + __clr_IFR(1 << (irq - IRQ_BASE_FPGA)); } -static void frv_fpga_unmask(struct irq_data *d) +static void frv_fpga_unmask(unsigned int irq) { uint16_t imr = __get_IMR(); - imr &= ~(1 << (d->irq - IRQ_BASE_FPGA)); + imr &= ~(1 << (irq - IRQ_BASE_FPGA)); __set_IMR(imr); } static struct irq_chip frv_fpga_pic = { .name = "mb93091", - .irq_ack = frv_fpga_ack, - .irq_mask = frv_fpga_mask, - .irq_mask_ack = frv_fpga_mask_ack, - .irq_unmask = frv_fpga_unmask, + .ack = frv_fpga_ack, + .mask = frv_fpga_mask, + .mask_ack = frv_fpga_mask_ack, + .unmask = frv_fpga_unmask, }; /* @@ -146,9 +146,9 @@ void __init fpga_init(void) __clr_IFR(0x0000); for (irq = IRQ_BASE_FPGA + 1; irq <= IRQ_BASE_FPGA + 14; irq++) - irq_set_chip_and_handler(irq, &frv_fpga_pic, handle_level_irq); + set_irq_chip_and_handler(irq, &frv_fpga_pic, handle_level_irq); - irq_set_chip_and_handler(IRQ_FPGA_NMI, &frv_fpga_pic, handle_edge_irq); + set_irq_chip_and_handler(IRQ_FPGA_NMI, &frv_fpga_pic, handle_edge_irq); /* the FPGA drives the first four external IRQ inputs on the CPU PIC */ setup_irq(IRQ_CPU_EXTERNAL0, &fpga_irq[0]); diff --git a/trunk/arch/frv/kernel/irq-mb93093.c b/trunk/arch/frv/kernel/irq-mb93093.c index 4d4ad09d3c91..e45209031873 100644 --- a/trunk/arch/frv/kernel/irq-mb93093.c +++ b/trunk/arch/frv/kernel/irq-mb93093.c @@ -35,44 +35,45 @@ /* * off-CPU FPGA PIC operations */ -static void frv_fpga_mask(struct irq_data *d) +static void frv_fpga_mask(unsigned int irq) { uint16_t imr = __get_IMR(); - imr |= 1 << (d->irq - IRQ_BASE_FPGA); + imr |= 1 << (irq - IRQ_BASE_FPGA); __set_IMR(imr); } -static void frv_fpga_ack(struct irq_data *d) +static void frv_fpga_ack(unsigned int irq) { - __clr_IFR(1 << (d->irq - IRQ_BASE_FPGA)); + __clr_IFR(1 << (irq - IRQ_BASE_FPGA)); } -static void frv_fpga_mask_ack(struct irq_data *d) +static void frv_fpga_mask_ack(unsigned int irq) { uint16_t imr = __get_IMR(); - imr |= 1 << (d->irq - IRQ_BASE_FPGA); + imr |= 1 << (irq - IRQ_BASE_FPGA); __set_IMR(imr); - __clr_IFR(1 << (d->irq - IRQ_BASE_FPGA)); + __clr_IFR(1 << (irq - IRQ_BASE_FPGA)); } -static void frv_fpga_unmask(struct irq_data *d) +static void frv_fpga_unmask(unsigned int irq) { uint16_t imr = __get_IMR(); - imr &= ~(1 << (d->irq - IRQ_BASE_FPGA)); + imr &= ~(1 << (irq - IRQ_BASE_FPGA)); __set_IMR(imr); } static struct irq_chip frv_fpga_pic = { .name = "mb93093", - .irq_ack = frv_fpga_ack, - .irq_mask = frv_fpga_mask, - .irq_mask_ack = frv_fpga_mask_ack, - .irq_unmask = frv_fpga_unmask, + .ack = frv_fpga_ack, + .mask = frv_fpga_mask, + .mask_ack = frv_fpga_mask_ack, + .unmask = frv_fpga_unmask, + .end = frv_fpga_end, }; /* @@ -93,7 +94,7 @@ static irqreturn_t fpga_interrupt(int irq, void *_mask) irq = 31 - irq; mask &= ~(1 << irq); - generic_handle_irq(IRQ_BASE_FPGA + irq); + generic_irq_handle(IRQ_BASE_FPGA + irq); } return IRQ_HANDLED; @@ -124,7 +125,7 @@ void __init fpga_init(void) __clr_IFR(0x0000); for (irq = IRQ_BASE_FPGA + 8; irq <= IRQ_BASE_FPGA + 10; irq++) - irq_set_chip_and_handler(irq, &frv_fpga_pic, handle_edge_irq); + set_irq_chip_and_handler(irq, &frv_fpga_pic, handle_edge_irq); /* the FPGA drives external IRQ input #2 on the CPU PIC */ setup_irq(IRQ_CPU_EXTERNAL2, &fpga_irq[0]); diff --git a/trunk/arch/frv/kernel/irq-mb93493.c b/trunk/arch/frv/kernel/irq-mb93493.c index 4d034c7840c9..ba55ecdfb245 100644 --- a/trunk/arch/frv/kernel/irq-mb93493.c +++ b/trunk/arch/frv/kernel/irq-mb93493.c @@ -45,46 +45,46 @@ * daughter board PIC operations * - there is no way to ACK interrupts in the MB93493 chip */ -static void frv_mb93493_mask(struct irq_data *d) +static void frv_mb93493_mask(unsigned int irq) { uint32_t iqsr; volatile void *piqsr; - if (IRQ_ROUTING & (1 << (d->irq - IRQ_BASE_MB93493))) + if (IRQ_ROUTING & (1 << (irq - IRQ_BASE_MB93493))) piqsr = __addr_MB93493_IQSR(1); else piqsr = __addr_MB93493_IQSR(0); iqsr = readl(piqsr); - iqsr &= ~(1 << (d->irq - IRQ_BASE_MB93493 + 16)); + iqsr &= ~(1 << (irq - IRQ_BASE_MB93493 + 16)); writel(iqsr, piqsr); } -static void frv_mb93493_ack(struct irq_data *d) +static void frv_mb93493_ack(unsigned int irq) { } -static void frv_mb93493_unmask(struct irq_data *d) +static void frv_mb93493_unmask(unsigned int irq) { uint32_t iqsr; volatile void *piqsr; - if (IRQ_ROUTING & (1 << (d->irq - IRQ_BASE_MB93493))) + if (IRQ_ROUTING & (1 << (irq - IRQ_BASE_MB93493))) piqsr = __addr_MB93493_IQSR(1); else piqsr = __addr_MB93493_IQSR(0); iqsr = readl(piqsr); - iqsr |= 1 << (d->irq - IRQ_BASE_MB93493 + 16); + iqsr |= 1 << (irq - IRQ_BASE_MB93493 + 16); writel(iqsr, piqsr); } static struct irq_chip frv_mb93493_pic = { .name = "mb93093", - .irq_ack = frv_mb93493_ack, - .irq_mask = frv_mb93493_mask, - .irq_mask_ack = frv_mb93493_mask, - .irq_unmask = frv_mb93493_unmask, + .ack = frv_mb93493_ack, + .mask = frv_mb93493_mask, + .mask_ack = frv_mb93493_mask, + .unmask = frv_mb93493_unmask, }; /* @@ -139,8 +139,7 @@ void __init mb93493_init(void) int irq; for (irq = IRQ_BASE_MB93493 + 0; irq <= IRQ_BASE_MB93493 + 10; irq++) - irq_set_chip_and_handler(irq, &frv_mb93493_pic, - handle_edge_irq); + set_irq_chip_and_handler(irq, &frv_mb93493_pic, handle_edge_irq); /* the MB93493 drives external IRQ inputs on the CPU PIC */ setup_irq(IRQ_CPU_MB93493_0, &mb93493_irq[0]); diff --git a/trunk/arch/frv/kernel/irq.c b/trunk/arch/frv/kernel/irq.c index a5f624a9f559..625136625a7f 100644 --- a/trunk/arch/frv/kernel/irq.c +++ b/trunk/arch/frv/kernel/irq.c @@ -47,45 +47,89 @@ extern void __init mb93493_init(void); atomic_t irq_err_count; -int arch_show_interrupts(struct seq_file *p, int prec) +/* + * Generic, controller-independent functions: + */ +int show_interrupts(struct seq_file *p, void *v) { - seq_printf(p, "%*s: ", prec, "ERR"); - seq_printf(p, "%10u\n", atomic_read(&irq_err_count)); + int i = *(loff_t *) v, cpu; + struct irqaction * action; + unsigned long flags; + + if (i == 0) { + char cpuname[12]; + + seq_printf(p, " "); + for_each_present_cpu(cpu) { + sprintf(cpuname, "CPU%d", cpu); + seq_printf(p, " %10s", cpuname); + } + seq_putc(p, '\n'); + } + + if (i < NR_IRQS) { + raw_spin_lock_irqsave(&irq_desc[i].lock, flags); + action = irq_desc[i].action; + if (action) { + seq_printf(p, "%3d: ", i); + for_each_present_cpu(cpu) + seq_printf(p, "%10u ", kstat_irqs_cpu(i, cpu)); + seq_printf(p, " %10s", irq_desc[i].chip->name ? : "-"); + seq_printf(p, " %s", action->name); + for (action = action->next; + action; + action = action->next) + seq_printf(p, ", %s", action->name); + + seq_putc(p, '\n'); + } + + raw_spin_unlock_irqrestore(&irq_desc[i].lock, flags); + } else if (i == NR_IRQS) { + seq_printf(p, "Err: %10u\n", atomic_read(&irq_err_count)); + } + return 0; } /* * on-CPU PIC operations */ -static void frv_cpupic_ack(struct irq_data *d) +static void frv_cpupic_ack(unsigned int irqlevel) { - __clr_RC(d->irq); + __clr_RC(irqlevel); __clr_IRL(); } -static void frv_cpupic_mask(struct irq_data *d) +static void frv_cpupic_mask(unsigned int irqlevel) { - __set_MASK(d->irq); + __set_MASK(irqlevel); } -static void frv_cpupic_mask_ack(struct irq_data *d) +static void frv_cpupic_mask_ack(unsigned int irqlevel) { - __set_MASK(d->irq); - __clr_RC(d->irq); + __set_MASK(irqlevel); + __clr_RC(irqlevel); __clr_IRL(); } -static void frv_cpupic_unmask(struct irq_data *d) +static void frv_cpupic_unmask(unsigned int irqlevel) +{ + __clr_MASK(irqlevel); +} + +static void frv_cpupic_end(unsigned int irqlevel) { - __clr_MASK(d->irq); + __clr_MASK(irqlevel); } static struct irq_chip frv_cpu_pic = { .name = "cpu", - .irq_ack = frv_cpupic_ack, - .irq_mask = frv_cpupic_mask, - .irq_mask_ack = frv_cpupic_mask_ack, - .irq_unmask = frv_cpupic_unmask, + .ack = frv_cpupic_ack, + .mask = frv_cpupic_mask, + .mask_ack = frv_cpupic_mask_ack, + .unmask = frv_cpupic_unmask, + .end = frv_cpupic_end, }; /* @@ -117,10 +161,10 @@ void __init init_IRQ(void) int level; for (level = 1; level <= 14; level++) - irq_set_chip_and_handler(level, &frv_cpu_pic, + set_irq_chip_and_handler(level, &frv_cpu_pic, handle_level_irq); - irq_set_handler(IRQ_CPU_TIMER0, handle_edge_irq); + set_irq_handler(IRQ_CPU_TIMER0, handle_edge_irq); /* set the trigger levels for internal interrupt sources * - timers all falling-edge diff --git a/trunk/arch/ia64/Kconfig b/trunk/arch/ia64/Kconfig index c4ea0925cdbd..fcf3b437a2d9 100644 --- a/trunk/arch/ia64/Kconfig +++ b/trunk/arch/ia64/Kconfig @@ -26,7 +26,6 @@ config IA64 select GENERIC_IRQ_PROBE select GENERIC_PENDING_IRQ if SMP select IRQ_PER_CPU - select GENERIC_IRQ_SHOW default y help The Itanium Processor Family is Intel's 64-bit successor to diff --git a/trunk/arch/ia64/hp/sim/hpsim_irq.c b/trunk/arch/ia64/hp/sim/hpsim_irq.c index 4bd9a63260ee..b272261d77cc 100644 --- a/trunk/arch/ia64/hp/sim/hpsim_irq.c +++ b/trunk/arch/ia64/hp/sim/hpsim_irq.c @@ -11,41 +11,42 @@ #include static unsigned int -hpsim_irq_startup(struct irq_data *data) +hpsim_irq_startup (unsigned int irq) { return 0; } static void -hpsim_irq_noop(struct irq_data *data) +hpsim_irq_noop (unsigned int irq) { } static int -hpsim_set_affinity_noop(struct irq_data *d, const struct cpumask *b, bool f) +hpsim_set_affinity_noop(unsigned int a, const struct cpumask *b) { return 0; } static struct irq_chip irq_type_hp_sim = { - .name = "hpsim", - .irq_startup = hpsim_irq_startup, - .irq_shutdown = hpsim_irq_noop, - .irq_enable = hpsim_irq_noop, - .irq_disable = hpsim_irq_noop, - .irq_ack = hpsim_irq_noop, - .irq_set_affinity = hpsim_set_affinity_noop, + .name = "hpsim", + .startup = hpsim_irq_startup, + .shutdown = hpsim_irq_noop, + .enable = hpsim_irq_noop, + .disable = hpsim_irq_noop, + .ack = hpsim_irq_noop, + .end = hpsim_irq_noop, + .set_affinity = hpsim_set_affinity_noop, }; void __init hpsim_irq_init (void) { + struct irq_desc *idesc; int i; - for_each_active_irq(i) { - struct irq_chip *chip = irq_get_chip(i); - - if (chip == &no_irq_chip) - irq_set_chip(i, &irq_type_hp_sim); + for (i = 0; i < NR_IRQS; ++i) { + idesc = irq_desc + i; + if (idesc->chip == &no_irq_chip) + idesc->chip = &irq_type_hp_sim; } } diff --git a/trunk/arch/ia64/include/asm/hw_irq.h b/trunk/arch/ia64/include/asm/hw_irq.h index a681d02cb324..bf2e37493e04 100644 --- a/trunk/arch/ia64/include/asm/hw_irq.h +++ b/trunk/arch/ia64/include/asm/hw_irq.h @@ -151,6 +151,9 @@ static inline void ia64_native_resend_irq(unsigned int vector) /* * Default implementations for the irq-descriptor API: */ + +extern struct irq_desc irq_desc[NR_IRQS]; + #ifndef CONFIG_IA64_GENERIC static inline ia64_vector __ia64_irq_to_vector(int irq) { diff --git a/trunk/arch/ia64/kernel/iosapic.c b/trunk/arch/ia64/kernel/iosapic.c index b0f9afebb146..22c38404f539 100644 --- a/trunk/arch/ia64/kernel/iosapic.c +++ b/trunk/arch/ia64/kernel/iosapic.c @@ -257,7 +257,7 @@ set_rte (unsigned int gsi, unsigned int irq, unsigned int dest, int mask) } static void -nop (struct irq_data *data) +nop (unsigned int irq) { /* do nothing... */ } @@ -287,9 +287,8 @@ kexec_disable_iosapic(void) #endif static void -mask_irq (struct irq_data *data) +mask_irq (unsigned int irq) { - unsigned int irq = data->irq; u32 low32; int rte_index; struct iosapic_rte_info *rte; @@ -306,9 +305,8 @@ mask_irq (struct irq_data *data) } static void -unmask_irq (struct irq_data *data) +unmask_irq (unsigned int irq) { - unsigned int irq = data->irq; u32 low32; int rte_index; struct iosapic_rte_info *rte; @@ -325,11 +323,9 @@ unmask_irq (struct irq_data *data) static int -iosapic_set_affinity(struct irq_data *data, const struct cpumask *mask, - bool force) +iosapic_set_affinity(unsigned int irq, const struct cpumask *mask) { #ifdef CONFIG_SMP - unsigned int irq = data->irq; u32 high32, low32; int cpu, dest, rte_index; int redir = (irq & IA64_IRQ_REDIRECTED) ? 1 : 0; @@ -383,33 +379,32 @@ iosapic_set_affinity(struct irq_data *data, const struct cpumask *mask, */ static unsigned int -iosapic_startup_level_irq (struct irq_data *data) +iosapic_startup_level_irq (unsigned int irq) { - unmask_irq(data); + unmask_irq(irq); return 0; } static void -iosapic_unmask_level_irq (struct irq_data *data) +iosapic_unmask_level_irq (unsigned int irq) { - unsigned int irq = data->irq; ia64_vector vec = irq_to_vector(irq); struct iosapic_rte_info *rte; int do_unmask_irq = 0; irq_complete_move(irq); - if (unlikely(irqd_is_setaffinity_pending(data))) { + if (unlikely(irq_desc[irq].status & IRQ_MOVE_PENDING)) { do_unmask_irq = 1; - mask_irq(data); + mask_irq(irq); } else - unmask_irq(data); + unmask_irq(irq); list_for_each_entry(rte, &iosapic_intr_info[irq].rtes, rte_list) iosapic_eoi(rte->iosapic->addr, vec); if (unlikely(do_unmask_irq)) { - irq_move_masked_irq(data); - unmask_irq(data); + move_masked_irq(irq); + unmask_irq(irq); } } @@ -419,15 +414,15 @@ iosapic_unmask_level_irq (struct irq_data *data) #define iosapic_ack_level_irq nop static struct irq_chip irq_type_iosapic_level = { - .name = "IO-SAPIC-level", - .irq_startup = iosapic_startup_level_irq, - .irq_shutdown = iosapic_shutdown_level_irq, - .irq_enable = iosapic_enable_level_irq, - .irq_disable = iosapic_disable_level_irq, - .irq_ack = iosapic_ack_level_irq, - .irq_mask = mask_irq, - .irq_unmask = iosapic_unmask_level_irq, - .irq_set_affinity = iosapic_set_affinity + .name = "IO-SAPIC-level", + .startup = iosapic_startup_level_irq, + .shutdown = iosapic_shutdown_level_irq, + .enable = iosapic_enable_level_irq, + .disable = iosapic_disable_level_irq, + .ack = iosapic_ack_level_irq, + .mask = mask_irq, + .unmask = iosapic_unmask_level_irq, + .set_affinity = iosapic_set_affinity }; /* @@ -435,9 +430,9 @@ static struct irq_chip irq_type_iosapic_level = { */ static unsigned int -iosapic_startup_edge_irq (struct irq_data *data) +iosapic_startup_edge_irq (unsigned int irq) { - unmask_irq(data); + unmask_irq(irq); /* * IOSAPIC simply drops interrupts pended while the * corresponding pin was masked, so we can't know if an @@ -447,25 +442,37 @@ iosapic_startup_edge_irq (struct irq_data *data) } static void -iosapic_ack_edge_irq (struct irq_data *data) +iosapic_ack_edge_irq (unsigned int irq) { - irq_complete_move(data->irq); - irq_move_irq(data); + struct irq_desc *idesc = irq_desc + irq; + + irq_complete_move(irq); + move_native_irq(irq); + /* + * Once we have recorded IRQ_PENDING already, we can mask the + * interrupt for real. This prevents IRQ storms from unhandled + * devices. + */ + if ((idesc->status & (IRQ_PENDING|IRQ_DISABLED)) == + (IRQ_PENDING|IRQ_DISABLED)) + mask_irq(irq); } #define iosapic_enable_edge_irq unmask_irq #define iosapic_disable_edge_irq nop +#define iosapic_end_edge_irq nop static struct irq_chip irq_type_iosapic_edge = { - .name = "IO-SAPIC-edge", - .irq_startup = iosapic_startup_edge_irq, - .irq_shutdown = iosapic_disable_edge_irq, - .irq_enable = iosapic_enable_edge_irq, - .irq_disable = iosapic_disable_edge_irq, - .irq_ack = iosapic_ack_edge_irq, - .irq_mask = mask_irq, - .irq_unmask = unmask_irq, - .irq_set_affinity = iosapic_set_affinity + .name = "IO-SAPIC-edge", + .startup = iosapic_startup_edge_irq, + .shutdown = iosapic_disable_edge_irq, + .enable = iosapic_enable_edge_irq, + .disable = iosapic_disable_edge_irq, + .ack = iosapic_ack_edge_irq, + .end = iosapic_end_edge_irq, + .mask = mask_irq, + .unmask = unmask_irq, + .set_affinity = iosapic_set_affinity }; static unsigned int @@ -555,7 +562,8 @@ static int register_intr (unsigned int gsi, int irq, unsigned char delivery, unsigned long polarity, unsigned long trigger) { - struct irq_chip *chip, *irq_type; + struct irq_desc *idesc; + struct irq_chip *irq_type; int index; struct iosapic_rte_info *rte; @@ -602,18 +610,19 @@ register_intr (unsigned int gsi, int irq, unsigned char delivery, irq_type = iosapic_get_irq_chip(trigger); - chip = irq_get_chip(irq); - if (irq_type != NULL && chip != irq_type) { - if (chip != &no_irq_chip) + idesc = irq_desc + irq; + if (irq_type != NULL && idesc->chip != irq_type) { + if (idesc->chip != &no_irq_chip) printk(KERN_WARNING "%s: changing vector %d from %s to %s\n", __func__, irq_to_vector(irq), - chip->name, irq_type->name); - chip = irq_type; + idesc->chip->name, irq_type->name); + idesc->chip = irq_type; } - __irq_set_chip_handler_name_locked(irq, chip, trigger == IOSAPIC_EDGE ? - handle_edge_irq : handle_level_irq, - NULL); + if (trigger == IOSAPIC_EDGE) + __set_irq_handler_unlocked(irq, handle_edge_irq); + else + __set_irq_handler_unlocked(irq, handle_level_irq); return 0; } @@ -723,7 +732,6 @@ iosapic_register_intr (unsigned int gsi, struct iosapic_rte_info *rte; u32 low32; unsigned char dmode; - struct irq_desc *desc; /* * If this GSI has already been registered (i.e., it's a @@ -751,13 +759,12 @@ iosapic_register_intr (unsigned int gsi, goto unlock_iosapic_lock; } - desc = irq_to_desc(irq); - raw_spin_lock(&desc->lock); + raw_spin_lock(&irq_desc[irq].lock); dest = get_target_cpu(gsi, irq); dmode = choose_dmode(); err = register_intr(gsi, irq, dmode, polarity, trigger); if (err < 0) { - raw_spin_unlock(&desc->lock); + raw_spin_unlock(&irq_desc[irq].lock); irq = err; goto unlock_iosapic_lock; } @@ -776,7 +783,7 @@ iosapic_register_intr (unsigned int gsi, (polarity == IOSAPIC_POL_HIGH ? "high" : "low"), cpu_logical_id(dest), dest, irq_to_vector(irq)); - raw_spin_unlock(&desc->lock); + raw_spin_unlock(&irq_desc[irq].lock); unlock_iosapic_lock: spin_unlock_irqrestore(&iosapic_lock, flags); return irq; @@ -787,6 +794,7 @@ iosapic_unregister_intr (unsigned int gsi) { unsigned long flags; int irq, index; + struct irq_desc *idesc; u32 low32; unsigned long trigger, polarity; unsigned int dest; @@ -816,6 +824,7 @@ iosapic_unregister_intr (unsigned int gsi) if (--rte->refcnt > 0) goto out; + idesc = irq_desc + irq; rte->refcnt = NO_REF_RTE; /* Mask the interrupt */ @@ -839,7 +848,7 @@ iosapic_unregister_intr (unsigned int gsi) if (iosapic_intr_info[irq].count == 0) { #ifdef CONFIG_SMP /* Clear affinity */ - cpumask_setall(irq_get_irq_data(irq)->affinity); + cpumask_setall(idesc->affinity); #endif /* Clear the interrupt information */ iosapic_intr_info[irq].dest = 0; diff --git a/trunk/arch/ia64/kernel/irq.c b/trunk/arch/ia64/kernel/irq.c index ad69606613eb..94ee9d067cbd 100644 --- a/trunk/arch/ia64/kernel/irq.c +++ b/trunk/arch/ia64/kernel/irq.c @@ -53,9 +53,47 @@ atomic_t irq_err_count; /* * /proc/interrupts printing: */ -int arch_show_interrupts(struct seq_file *p, int prec) + +int show_interrupts(struct seq_file *p, void *v) { - seq_printf(p, "ERR: %10u\n", atomic_read(&irq_err_count)); + int i = *(loff_t *) v, j; + struct irqaction * action; + unsigned long flags; + + if (i == 0) { + char cpuname[16]; + seq_printf(p, " "); + for_each_online_cpu(j) { + snprintf(cpuname, 10, "CPU%d", j); + seq_printf(p, "%10s ", cpuname); + } + seq_putc(p, '\n'); + } + + if (i < NR_IRQS) { + raw_spin_lock_irqsave(&irq_desc[i].lock, flags); + action = irq_desc[i].action; + if (!action) + goto skip; + seq_printf(p, "%3d: ",i); +#ifndef CONFIG_SMP + seq_printf(p, "%10u ", kstat_irqs(i)); +#else + for_each_online_cpu(j) { + seq_printf(p, "%10u ", kstat_irqs_cpu(i, j)); + } +#endif + seq_printf(p, " %14s", irq_desc[i].chip->name); + seq_printf(p, " %s", action->name); + + for (action=action->next; action; action = action->next) + seq_printf(p, ", %s", action->name); + + seq_putc(p, '\n'); +skip: + raw_spin_unlock_irqrestore(&irq_desc[i].lock, flags); + } else if (i == NR_IRQS) + seq_printf(p, "ERR: %10u\n", atomic_read(&irq_err_count)); return 0; } @@ -65,7 +103,7 @@ static char irq_redir [NR_IRQS]; // = { [0 ... NR_IRQS-1] = 1 }; void set_irq_affinity_info (unsigned int irq, int hwid, int redir) { if (irq < NR_IRQS) { - cpumask_copy(irq_get_irq_data(irq)->affinity, + cpumask_copy(irq_desc[irq].affinity, cpumask_of(cpu_logical_id(hwid))); irq_redir[irq] = (char) (redir & 0xff); } @@ -92,14 +130,13 @@ unsigned int vectors_in_migration[NR_IRQS]; */ static void migrate_irqs(void) { + struct irq_desc *desc; int irq, new_cpu; for (irq=0; irq < NR_IRQS; irq++) { - struct irq_desc *desc = irq_to_desc(irq); - struct irq_data *data = irq_desc_get_irq_data(desc); - struct irq_chip *chip = irq_data_get_irq_chip(data); + desc = irq_desc + irq; - if (irqd_irq_disabled(data)) + if (desc->status == IRQ_DISABLED) continue; /* @@ -108,10 +145,10 @@ static void migrate_irqs(void) * tell CPU not to respond to these local intr sources. * such as ITV,CPEI,MCA etc. */ - if (irqd_is_per_cpu(data)) + if (desc->status == IRQ_PER_CPU) continue; - if (cpumask_any_and(data->affinity, cpu_online_mask) + if (cpumask_any_and(irq_desc[irq].affinity, cpu_online_mask) >= nr_cpu_ids) { /* * Save it for phase 2 processing @@ -123,16 +160,16 @@ static void migrate_irqs(void) /* * Al three are essential, currently WARN_ON.. maybe panic? */ - if (chip && chip->irq_disable && - chip->irq_enable && chip->irq_set_affinity) { - chip->irq_disable(data); - chip->irq_set_affinity(data, - cpumask_of(new_cpu), false); - chip->irq_enable(data); + if (desc->chip && desc->chip->disable && + desc->chip->enable && desc->chip->set_affinity) { + desc->chip->disable(irq); + desc->chip->set_affinity(irq, + cpumask_of(new_cpu)); + desc->chip->enable(irq); } else { - WARN_ON((!chip || !chip->irq_disable || - !chip->irq_enable || - !chip->irq_set_affinity)); + WARN_ON((!(desc->chip) || !(desc->chip->disable) || + !(desc->chip->enable) || + !(desc->chip->set_affinity))); } } } diff --git a/trunk/arch/ia64/kernel/irq_ia64.c b/trunk/arch/ia64/kernel/irq_ia64.c index 5b704740f160..38c07b866901 100644 --- a/trunk/arch/ia64/kernel/irq_ia64.c +++ b/trunk/arch/ia64/kernel/irq_ia64.c @@ -343,7 +343,7 @@ static irqreturn_t smp_irq_move_cleanup_interrupt(int irq, void *dev_id) if (irq < 0) continue; - desc = irq_to_desc(irq); + desc = irq_desc + irq; cfg = irq_cfg + irq; raw_spin_lock(&desc->lock); if (!cfg->move_cleanup_count) @@ -626,15 +626,17 @@ static struct irqaction tlb_irqaction = { void ia64_native_register_percpu_irq (ia64_vector vec, struct irqaction *action) { + struct irq_desc *desc; unsigned int irq; irq = vec; BUG_ON(bind_irq_vector(irq, vec, CPU_MASK_ALL)); - irq_set_status_flags(irq, IRQ_PER_CPU); - irq_set_chip(irq, &irq_type_ia64_lsapic); + desc = irq_desc + irq; + desc->status |= IRQ_PER_CPU; + set_irq_chip(irq, &irq_type_ia64_lsapic); if (action) setup_irq(irq, action); - irq_set_handler(irq, handle_percpu_irq); + set_irq_handler(irq, handle_percpu_irq); } void __init diff --git a/trunk/arch/ia64/kernel/irq_lsapic.c b/trunk/arch/ia64/kernel/irq_lsapic.c index 1b3a776e5161..fc1549d4564d 100644 --- a/trunk/arch/ia64/kernel/irq_lsapic.c +++ b/trunk/arch/ia64/kernel/irq_lsapic.c @@ -15,30 +15,31 @@ #include static unsigned int -lsapic_noop_startup (struct irq_data *data) +lsapic_noop_startup (unsigned int irq) { return 0; } static void -lsapic_noop (struct irq_data *data) +lsapic_noop (unsigned int irq) { /* nothing to do... */ } -static int lsapic_retrigger(struct irq_data *data) +static int lsapic_retrigger(unsigned int irq) { - ia64_resend_irq(data->irq); + ia64_resend_irq(irq); return 1; } struct irq_chip irq_type_ia64_lsapic = { - .name = "LSAPIC", - .irq_startup = lsapic_noop_startup, - .irq_shutdown = lsapic_noop, - .irq_enable = lsapic_noop, - .irq_disable = lsapic_noop, - .irq_ack = lsapic_noop, - .irq_retrigger = lsapic_retrigger, + .name = "LSAPIC", + .startup = lsapic_noop_startup, + .shutdown = lsapic_noop, + .enable = lsapic_noop, + .disable = lsapic_noop, + .ack = lsapic_noop, + .end = lsapic_noop, + .retrigger = lsapic_retrigger, }; diff --git a/trunk/arch/ia64/kernel/mca.c b/trunk/arch/ia64/kernel/mca.c index 84fb405eee87..80d50b83d419 100644 --- a/trunk/arch/ia64/kernel/mca.c +++ b/trunk/arch/ia64/kernel/mca.c @@ -2125,6 +2125,7 @@ ia64_mca_late_init(void) cpe_poll_timer.function = ia64_mca_cpe_poll; { + struct irq_desc *desc; unsigned int irq; if (cpe_vector >= 0) { @@ -2132,7 +2133,8 @@ ia64_mca_late_init(void) irq = local_vector_to_irq(cpe_vector); if (irq > 0) { cpe_poll_enabled = 0; - irq_set_status_flags(irq, IRQ_PER_CPU); + desc = irq_desc + irq; + desc->status |= IRQ_PER_CPU; setup_irq(irq, &mca_cpe_irqaction); ia64_cpe_irq = irq; ia64_mca_register_cpev(cpe_vector); diff --git a/trunk/arch/ia64/kernel/msi_ia64.c b/trunk/arch/ia64/kernel/msi_ia64.c index 009df5434a7a..00b19a416eab 100644 --- a/trunk/arch/ia64/kernel/msi_ia64.c +++ b/trunk/arch/ia64/kernel/msi_ia64.c @@ -12,13 +12,12 @@ static struct irq_chip ia64_msi_chip; #ifdef CONFIG_SMP -static int ia64_set_msi_irq_affinity(struct irq_data *idata, - const cpumask_t *cpu_mask, bool force) +static int ia64_set_msi_irq_affinity(unsigned int irq, + const cpumask_t *cpu_mask) { struct msi_msg msg; u32 addr, data; int cpu = first_cpu(*cpu_mask); - unsigned int irq = idata->irq; if (!cpu_online(cpu)) return -1; @@ -39,7 +38,7 @@ static int ia64_set_msi_irq_affinity(struct irq_data *idata, msg.data = data; write_msi_msg(irq, &msg); - cpumask_copy(idata->affinity, cpumask_of(cpu)); + cpumask_copy(irq_desc[irq].affinity, cpumask_of(cpu)); return 0; } @@ -56,7 +55,7 @@ int ia64_setup_msi_irq(struct pci_dev *pdev, struct msi_desc *desc) if (irq < 0) return irq; - irq_set_msi_desc(irq, desc); + set_irq_msi(irq, desc); cpus_and(mask, irq_to_domain(irq), cpu_online_map); dest_phys_id = cpu_physical_id(first_cpu(mask)); vector = irq_to_vector(irq); @@ -75,7 +74,7 @@ int ia64_setup_msi_irq(struct pci_dev *pdev, struct msi_desc *desc) MSI_DATA_VECTOR(vector); write_msi_msg(irq, &msg); - irq_set_chip_and_handler(irq, &ia64_msi_chip, handle_edge_irq); + set_irq_chip_and_handler(irq, &ia64_msi_chip, handle_edge_irq); return 0; } @@ -85,16 +84,16 @@ void ia64_teardown_msi_irq(unsigned int irq) destroy_irq(irq); } -static void ia64_ack_msi_irq(struct irq_data *data) +static void ia64_ack_msi_irq(unsigned int irq) { - irq_complete_move(data->irq); - irq_move_irq(data); + irq_complete_move(irq); + move_native_irq(irq); ia64_eoi(); } -static int ia64_msi_retrigger_irq(struct irq_data *data) +static int ia64_msi_retrigger_irq(unsigned int irq) { - unsigned int vector = irq_to_vector(data->irq); + unsigned int vector = irq_to_vector(irq); ia64_resend_irq(vector); return 1; @@ -104,14 +103,14 @@ static int ia64_msi_retrigger_irq(struct irq_data *data) * Generic ops used on most IA64 platforms. */ static struct irq_chip ia64_msi_chip = { - .name = "PCI-MSI", - .irq_mask = mask_msi_irq, - .irq_unmask = unmask_msi_irq, - .irq_ack = ia64_ack_msi_irq, + .name = "PCI-MSI", + .irq_mask = mask_msi_irq, + .irq_unmask = unmask_msi_irq, + .ack = ia64_ack_msi_irq, #ifdef CONFIG_SMP - .irq_set_affinity = ia64_set_msi_irq_affinity, + .set_affinity = ia64_set_msi_irq_affinity, #endif - .irq_retrigger = ia64_msi_retrigger_irq, + .retrigger = ia64_msi_retrigger_irq, }; @@ -133,10 +132,8 @@ void arch_teardown_msi_irq(unsigned int irq) #ifdef CONFIG_DMAR #ifdef CONFIG_SMP -static int dmar_msi_set_affinity(struct irq_data *data, - const struct cpumask *mask, bool force) +static int dmar_msi_set_affinity(unsigned int irq, const struct cpumask *mask) { - unsigned int irq = data->irq; struct irq_cfg *cfg = irq_cfg + irq; struct msi_msg msg; int cpu = cpumask_first(mask); @@ -155,7 +152,7 @@ static int dmar_msi_set_affinity(struct irq_data *data, msg.address_lo |= MSI_ADDR_DEST_ID_CPU(cpu_physical_id(cpu)); dmar_msi_write(irq, &msg); - cpumask_copy(data->affinity, mask); + cpumask_copy(irq_desc[irq].affinity, mask); return 0; } @@ -165,11 +162,11 @@ static struct irq_chip dmar_msi_type = { .name = "DMAR_MSI", .irq_unmask = dmar_msi_unmask, .irq_mask = dmar_msi_mask, - .irq_ack = ia64_ack_msi_irq, + .ack = ia64_ack_msi_irq, #ifdef CONFIG_SMP - .irq_set_affinity = dmar_msi_set_affinity, + .set_affinity = dmar_msi_set_affinity, #endif - .irq_retrigger = ia64_msi_retrigger_irq, + .retrigger = ia64_msi_retrigger_irq, }; static int @@ -206,8 +203,8 @@ int arch_setup_dmar_msi(unsigned int irq) if (ret < 0) return ret; dmar_msi_write(irq, &msg); - irq_set_chip_and_handler_name(irq, &dmar_msi_type, handle_edge_irq, - "edge"); + set_irq_chip_and_handler_name(irq, &dmar_msi_type, handle_edge_irq, + "edge"); return 0; } #endif /* CONFIG_DMAR */ diff --git a/trunk/arch/ia64/kernel/smpboot.c b/trunk/arch/ia64/kernel/smpboot.c index 44f11ee411c0..d003b502a432 100644 --- a/trunk/arch/ia64/kernel/smpboot.c +++ b/trunk/arch/ia64/kernel/smpboot.c @@ -677,7 +677,7 @@ extern void fixup_irqs(void); int migrate_platform_irqs(unsigned int cpu) { int new_cpei_cpu; - struct irq_data *data = NULL; + struct irq_desc *desc = NULL; const struct cpumask *mask; int retval = 0; @@ -693,20 +693,20 @@ int migrate_platform_irqs(unsigned int cpu) new_cpei_cpu = any_online_cpu(cpu_online_map); mask = cpumask_of(new_cpei_cpu); set_cpei_target_cpu(new_cpei_cpu); - data = irq_get_irq_data(ia64_cpe_irq); + desc = irq_desc + ia64_cpe_irq; /* * Switch for now, immediately, we need to do fake intr * as other interrupts, but need to study CPEI behaviour with * polling before making changes. */ - if (data && data->chip) { - data->chip->irq_disable(data); - data->chip->irq_set_affinity(data, mask, false); - data->chip->irq_enable(data); + if (desc) { + desc->chip->disable(ia64_cpe_irq); + desc->chip->set_affinity(ia64_cpe_irq, mask); + desc->chip->enable(ia64_cpe_irq); printk ("Re-targetting CPEI to cpu %d\n", new_cpei_cpu); } } - if (!data) { + if (!desc) { printk ("Unable to retarget CPEI, offline cpu [%d] failed\n", cpu); retval = -EBUSY; } diff --git a/trunk/arch/ia64/sn/kernel/irq.c b/trunk/arch/ia64/sn/kernel/irq.c index 7f399f9d99c7..13c15d968098 100644 --- a/trunk/arch/ia64/sn/kernel/irq.c +++ b/trunk/arch/ia64/sn/kernel/irq.c @@ -23,9 +23,11 @@ #include #include +static void force_interrupt(int irq); static void register_intr_pda(struct sn_irq_info *sn_irq_info); static void unregister_intr_pda(struct sn_irq_info *sn_irq_info); +int sn_force_interrupt_flag = 1; extern int sn_ioif_inited; struct list_head **sn_irq_lh; static DEFINE_SPINLOCK(sn_irq_info_lock); /* non-IRQ lock */ @@ -76,40 +78,62 @@ u64 sn_intr_redirect(nasid_t local_nasid, int local_widget, return ret_stuff.status; } -static unsigned int sn_startup_irq(struct irq_data *data) +static unsigned int sn_startup_irq(unsigned int irq) { return 0; } -static void sn_shutdown_irq(struct irq_data *data) +static void sn_shutdown_irq(unsigned int irq) { } extern void ia64_mca_register_cpev(int); -static void sn_disable_irq(struct irq_data *data) +static void sn_disable_irq(unsigned int irq) { - if (data->irq == local_vector_to_irq(IA64_CPE_VECTOR)) + if (irq == local_vector_to_irq(IA64_CPE_VECTOR)) ia64_mca_register_cpev(0); } -static void sn_enable_irq(struct irq_data *data) +static void sn_enable_irq(unsigned int irq) { - if (data->irq == local_vector_to_irq(IA64_CPE_VECTOR)) - ia64_mca_register_cpev(data->irq); + if (irq == local_vector_to_irq(IA64_CPE_VECTOR)) + ia64_mca_register_cpev(irq); } -static void sn_ack_irq(struct irq_data *data) +static void sn_ack_irq(unsigned int irq) { u64 event_occurred, mask; - unsigned int irq = data->irq & 0xff; + irq = irq & 0xff; event_occurred = HUB_L((u64*)LOCAL_MMR_ADDR(SH_EVENT_OCCURRED)); mask = event_occurred & SH_ALL_INT_MASK; HUB_S((u64*)LOCAL_MMR_ADDR(SH_EVENT_OCCURRED_ALIAS), mask); __set_bit(irq, (volatile void *)pda->sn_in_service_ivecs); - irq_move_irq(data); + move_native_irq(irq); +} + +static void sn_end_irq(unsigned int irq) +{ + int ivec; + u64 event_occurred; + + ivec = irq & 0xff; + if (ivec == SGI_UART_VECTOR) { + event_occurred = HUB_L((u64*)LOCAL_MMR_ADDR (SH_EVENT_OCCURRED)); + /* If the UART bit is set here, we may have received an + * interrupt from the UART that the driver missed. To + * make sure, we IPI ourselves to force us to look again. + */ + if (event_occurred & SH_EVENT_OCCURRED_UART_INT_MASK) { + platform_send_ipi(smp_processor_id(), SGI_UART_VECTOR, + IA64_IPI_DM_INT, 0); + } + } + __clear_bit(ivec, (volatile void *)pda->sn_in_service_ivecs); + if (sn_force_interrupt_flag) + force_interrupt(irq); } static void sn_irq_info_free(struct rcu_head *head); @@ -204,11 +228,9 @@ struct sn_irq_info *sn_retarget_vector(struct sn_irq_info *sn_irq_info, return new_irq_info; } -static int sn_set_affinity_irq(struct irq_data *data, - const struct cpumask *mask, bool force) +static int sn_set_affinity_irq(unsigned int irq, const struct cpumask *mask) { struct sn_irq_info *sn_irq_info, *sn_irq_info_safe; - unsigned int irq = data->irq; nasid_t nasid; int slice; @@ -237,25 +259,26 @@ void sn_set_err_irq_affinity(unsigned int irq) { } #endif static void -sn_mask_irq(struct irq_data *data) +sn_mask_irq(unsigned int irq) { } static void -sn_unmask_irq(struct irq_data *data) +sn_unmask_irq(unsigned int irq) { } struct irq_chip irq_type_sn = { - .name = "SN hub", - .irq_startup = sn_startup_irq, - .irq_shutdown = sn_shutdown_irq, - .irq_enable = sn_enable_irq, - .irq_disable = sn_disable_irq, - .irq_ack = sn_ack_irq, - .irq_mask = sn_mask_irq, - .irq_unmask = sn_unmask_irq, - .irq_set_affinity = sn_set_affinity_irq + .name = "SN hub", + .startup = sn_startup_irq, + .shutdown = sn_shutdown_irq, + .enable = sn_enable_irq, + .disable = sn_disable_irq, + .ack = sn_ack_irq, + .end = sn_end_irq, + .mask = sn_mask_irq, + .unmask = sn_unmask_irq, + .set_affinity = sn_set_affinity_irq }; ia64_vector sn_irq_to_vector(int irq) @@ -273,13 +296,15 @@ unsigned int sn_local_vector_to_irq(u8 vector) void sn_irq_init(void) { int i; + struct irq_desc *base_desc = irq_desc; ia64_first_device_vector = IA64_SN2_FIRST_DEVICE_VECTOR; ia64_last_device_vector = IA64_SN2_LAST_DEVICE_VECTOR; for (i = 0; i < NR_IRQS; i++) { - if (irq_get_chip(i) == &no_irq_chip) - irq_set_chip(i, &irq_type_sn); + if (base_desc[i].chip == &no_irq_chip) { + base_desc[i].chip = &irq_type_sn; + } } } @@ -353,6 +378,7 @@ void sn_irq_fixup(struct pci_dev *pci_dev, struct sn_irq_info *sn_irq_info) int cpu = nasid_slice_to_cpuid(nasid, slice); #ifdef CONFIG_SMP int cpuphys; + struct irq_desc *desc; #endif pci_dev_get(pci_dev); @@ -369,11 +395,12 @@ void sn_irq_fixup(struct pci_dev *pci_dev, struct sn_irq_info *sn_irq_info) #ifdef CONFIG_SMP cpuphys = cpu_physical_id(cpu); set_irq_affinity_info(sn_irq_info->irq_irq, cpuphys, 0); + desc = irq_to_desc(sn_irq_info->irq_irq); /* * Affinity was set by the PROM, prevent it from * being reset by the request_irq() path. */ - irqd_mark_affinity_was_set(irq_get_irq_data(sn_irq_info->irq_irq)); + desc->status |= IRQ_AFFINITY_SET; #endif } @@ -412,11 +439,25 @@ sn_call_force_intr_provider(struct sn_irq_info *sn_irq_info) pci_provider = sn_pci_provider[sn_irq_info->irq_bridge_type]; /* Don't force an interrupt if the irq has been disabled */ - if (!irqd_irq_disabled(sn_irq_info->irq_irq) && + if (!(irq_desc[sn_irq_info->irq_irq].status & IRQ_DISABLED) && pci_provider && pci_provider->force_interrupt) (*pci_provider->force_interrupt)(sn_irq_info); } +static void force_interrupt(int irq) +{ + struct sn_irq_info *sn_irq_info; + + if (!sn_ioif_inited) + return; + + rcu_read_lock(); + list_for_each_entry_rcu(sn_irq_info, sn_irq_lh[irq], list) + sn_call_force_intr_provider(sn_irq_info); + + rcu_read_unlock(); +} + /* * Check for lost interrupts. If the PIC int_status reg. says that * an interrupt has been sent, but not handled, and the interrupt diff --git a/trunk/arch/ia64/sn/kernel/msi_sn.c b/trunk/arch/ia64/sn/kernel/msi_sn.c index 2b98b9e088de..a5e500f02853 100644 --- a/trunk/arch/ia64/sn/kernel/msi_sn.c +++ b/trunk/arch/ia64/sn/kernel/msi_sn.c @@ -144,16 +144,16 @@ int sn_setup_msi_irq(struct pci_dev *pdev, struct msi_desc *entry) */ msg.data = 0x100 + irq; - irq_set_msi_desc(irq, entry); + set_irq_msi(irq, entry); write_msi_msg(irq, &msg); - irq_set_chip_and_handler(irq, &sn_msi_chip, handle_edge_irq); + set_irq_chip_and_handler(irq, &sn_msi_chip, handle_edge_irq); return 0; } #ifdef CONFIG_SMP -static int sn_set_msi_irq_affinity(struct irq_data *data, - const struct cpumask *cpu_mask, bool force) +static int sn_set_msi_irq_affinity(unsigned int irq, + const struct cpumask *cpu_mask) { struct msi_msg msg; int slice; @@ -164,7 +164,7 @@ static int sn_set_msi_irq_affinity(struct irq_data *data, struct sn_irq_info *sn_irq_info; struct sn_irq_info *new_irq_info; struct sn_pcibus_provider *provider; - unsigned int cpu, irq = data->irq; + unsigned int cpu; cpu = cpumask_first(cpu_mask); sn_irq_info = sn_msi_info[irq].sn_irq_info; @@ -206,33 +206,33 @@ static int sn_set_msi_irq_affinity(struct irq_data *data, msg.address_lo = (u32)(bus_addr & 0x00000000ffffffff); write_msi_msg(irq, &msg); - cpumask_copy(data->affinity, cpu_mask); + cpumask_copy(irq_desc[irq].affinity, cpu_mask); return 0; } #endif /* CONFIG_SMP */ -static void sn_ack_msi_irq(struct irq_data *data) +static void sn_ack_msi_irq(unsigned int irq) { - irq_move_irq(data); + move_native_irq(irq); ia64_eoi(); } -static int sn_msi_retrigger_irq(struct irq_data *data) +static int sn_msi_retrigger_irq(unsigned int irq) { - unsigned int vector = data->irq; + unsigned int vector = irq; ia64_resend_irq(vector); return 1; } static struct irq_chip sn_msi_chip = { - .name = "PCI-MSI", - .irq_mask = mask_msi_irq, - .irq_unmask = unmask_msi_irq, - .irq_ack = sn_ack_msi_irq, + .name = "PCI-MSI", + .irq_mask = mask_msi_irq, + .irq_unmask = unmask_msi_irq, + .ack = sn_ack_msi_irq, #ifdef CONFIG_SMP - .irq_set_affinity = sn_set_msi_irq_affinity, + .set_affinity = sn_set_msi_irq_affinity, #endif - .irq_retrigger = sn_msi_retrigger_irq, + .retrigger = sn_msi_retrigger_irq, }; diff --git a/trunk/arch/ia64/xen/irq_xen.c b/trunk/arch/ia64/xen/irq_xen.c index 108bb858acf2..a3fb7cf9ae1d 100644 --- a/trunk/arch/ia64/xen/irq_xen.c +++ b/trunk/arch/ia64/xen/irq_xen.c @@ -138,6 +138,7 @@ static void __xen_register_percpu_irq(unsigned int cpu, unsigned int vec, struct irqaction *action, int save) { + struct irq_desc *desc; int irq = 0; if (xen_slab_ready) { @@ -222,7 +223,8 @@ __xen_register_percpu_irq(unsigned int cpu, unsigned int vec, * mark the interrupt for migrations and trigger it * on cpu hotplug. */ - irq_set_status_flags(irq, IRQ_PER_CPU); + desc = irq_desc + irq; + desc->status |= IRQ_PER_CPU; } } diff --git a/trunk/arch/m68k/kernel/irq.c b/trunk/arch/m68k/kernel/irq.c index 15dbc3e9d20c..c7dd48f37bee 100644 --- a/trunk/arch/m68k/kernel/irq.c +++ b/trunk/arch/m68k/kernel/irq.c @@ -44,7 +44,7 @@ int show_interrupts(struct seq_file *p, void *v) if (ap) { seq_printf(p, "%3d: ", irq); seq_printf(p, "%10u ", kstat_irqs(irq)); - seq_printf(p, "%14s ", irq_desc_get_chip(desc)->name); + seq_printf(p, "%14s ", get_irq_desc_chip(desc)->name); seq_printf(p, "%s", ap->name); for (ap = ap->next; ap; ap = ap->next) diff --git a/trunk/arch/m68k/platform/5249/intc2.c b/trunk/arch/m68k/platform/5249/intc2.c index f343bf7bf5b0..8f4b63e17366 100644 --- a/trunk/arch/m68k/platform/5249/intc2.c +++ b/trunk/arch/m68k/platform/5249/intc2.c @@ -51,8 +51,8 @@ static int __init mcf_intc2_init(void) /* GPIO interrupt sources */ for (irq = MCFINTC2_GPIOIRQ0; (irq <= MCFINTC2_GPIOIRQ7); irq++) { - irq_set_chip(irq, &intc2_irq_gpio_chip); - irq_set_handler(irq, handle_edge_irq); + set_irq_chip(irq, &intc2_irq_gpio_chip); + set_irq_handler(irq, handle_edge_irq); } return 0; diff --git a/trunk/arch/m68k/platform/5272/intc.c b/trunk/arch/m68k/platform/5272/intc.c index 43e6e96f087f..969ff0a467c6 100644 --- a/trunk/arch/m68k/platform/5272/intc.c +++ b/trunk/arch/m68k/platform/5272/intc.c @@ -145,7 +145,7 @@ static int intc_irq_set_type(struct irq_data *d, unsigned int type) */ static void intc_external_irq(unsigned int irq, struct irq_desc *desc) { - irq_desc_get_chip(desc)->irq_ack(&desc->irq_data); + get_irq_desc_chip(desc)->irq_ack(&desc->irq_data); handle_simple_irq(irq, desc); } @@ -171,16 +171,16 @@ void __init init_IRQ(void) writel(0x88888888, MCF_MBAR + MCFSIM_ICR4); for (irq = 0; (irq < NR_IRQS); irq++) { - irq_set_chip(irq, &intc_irq_chip); + set_irq_chip(irq, &intc_irq_chip); edge = 0; if ((irq >= MCFINT_VECBASE) && (irq <= MCFINT_VECMAX)) edge = intc_irqmap[irq - MCFINT_VECBASE].ack; if (edge) { - irq_set_irq_type(irq, IRQ_TYPE_EDGE_RISING); - irq_set_handler(irq, intc_external_irq); + set_irq_type(irq, IRQ_TYPE_EDGE_RISING); + set_irq_handler(irq, intc_external_irq); } else { - irq_set_irq_type(irq, IRQ_TYPE_LEVEL_HIGH); - irq_set_handler(irq, handle_level_irq); + set_irq_type(irq, IRQ_TYPE_LEVEL_HIGH); + set_irq_handler(irq, handle_level_irq); } } } diff --git a/trunk/arch/m68k/platform/68328/ints.c b/trunk/arch/m68k/platform/68328/ints.c index a90288cf7446..e5631831a200 100644 --- a/trunk/arch/m68k/platform/68328/ints.c +++ b/trunk/arch/m68k/platform/68328/ints.c @@ -179,8 +179,8 @@ void __init init_IRQ(void) IMR = ~0; for (i = 0; (i < NR_IRQS); i++) { - irq_set_chip(i, &intc_irq_chip); - irq_set_handler(i, handle_level_irq); + set_irq_chip(i, &intc_irq_chip); + set_irq_handler(i, handle_level_irq); } } diff --git a/trunk/arch/m68k/platform/68360/ints.c b/trunk/arch/m68k/platform/68360/ints.c index 4af0f4e30f74..8de3feb568c6 100644 --- a/trunk/arch/m68k/platform/68360/ints.c +++ b/trunk/arch/m68k/platform/68360/ints.c @@ -132,8 +132,8 @@ void init_IRQ(void) pquicc->intr_cimr = 0x00000000; for (i = 0; (i < NR_IRQS); i++) { - irq_set_chip(i, &intc_irq_chip); - irq_set_handler(i, handle_level_irq); + set_irq_chip(i, &intc_irq_chip); + set_irq_handler(i, handle_level_irq); } } diff --git a/trunk/arch/m68k/platform/coldfire/intc-2.c b/trunk/arch/m68k/platform/coldfire/intc-2.c index 74b55cfbc3cb..2cbfbf035db9 100644 --- a/trunk/arch/m68k/platform/coldfire/intc-2.c +++ b/trunk/arch/m68k/platform/coldfire/intc-2.c @@ -164,7 +164,7 @@ static int intc_irq_set_type(struct irq_data *d, unsigned int type) } if (tb) - irq_set_handler(irq, handle_edge_irq); + set_irq_handler(irq, handle_edge_irq); irq -= EINT0; pa = __raw_readw(MCFEPORT_EPPAR); @@ -204,11 +204,11 @@ void __init init_IRQ(void) for (irq = MCFINT_VECBASE; (irq < MCFINT_VECBASE + NR_VECS); irq++) { if ((irq >= EINT1) && (irq <=EINT7)) - irq_set_chip(irq, &intc_irq_chip_edge_port); + set_irq_chip(irq, &intc_irq_chip_edge_port); else - irq_set_chip(irq, &intc_irq_chip); - irq_set_irq_type(irq, IRQ_TYPE_LEVEL_HIGH); - irq_set_handler(irq, handle_level_irq); + set_irq_chip(irq, &intc_irq_chip); + set_irq_type(irq, IRQ_TYPE_LEVEL_HIGH); + set_irq_handler(irq, handle_level_irq); } } diff --git a/trunk/arch/m68k/platform/coldfire/intc-simr.c b/trunk/arch/m68k/platform/coldfire/intc-simr.c index d6a4d9d53e42..e642b24ab729 100644 --- a/trunk/arch/m68k/platform/coldfire/intc-simr.c +++ b/trunk/arch/m68k/platform/coldfire/intc-simr.c @@ -141,7 +141,7 @@ static int intc_irq_set_type(struct irq_data *d, unsigned int type) } if (tb) - irq_set_handler(irq, handle_edge_irq); + set_irq_handler(irq, handle_edge_irq); ebit = irq2ebit(irq) * 2; pa = __raw_readw(MCFEPORT_EPPAR); @@ -181,11 +181,11 @@ void __init init_IRQ(void) eirq = MCFINT_VECBASE + 64 + (MCFINTC1_ICR0 ? 64 : 0); for (irq = MCFINT_VECBASE; (irq < eirq); irq++) { if ((irq >= EINT1) && (irq <= EINT7)) - irq_set_chip(irq, &intc_irq_chip_edge_port); + set_irq_chip(irq, &intc_irq_chip_edge_port); else - irq_set_chip(irq, &intc_irq_chip); - irq_set_irq_type(irq, IRQ_TYPE_LEVEL_HIGH); - irq_set_handler(irq, handle_level_irq); + set_irq_chip(irq, &intc_irq_chip); + set_irq_type(irq, IRQ_TYPE_LEVEL_HIGH); + set_irq_handler(irq, handle_level_irq); } } diff --git a/trunk/arch/m68k/platform/coldfire/intc.c b/trunk/arch/m68k/platform/coldfire/intc.c index c28a6ed6cb23..d648081a63f6 100644 --- a/trunk/arch/m68k/platform/coldfire/intc.c +++ b/trunk/arch/m68k/platform/coldfire/intc.c @@ -143,9 +143,9 @@ void __init init_IRQ(void) mcf_maskimr(0xffffffff); for (irq = 0; (irq < NR_IRQS); irq++) { - irq_set_chip(irq, &intc_irq_chip); - irq_set_irq_type(irq, IRQ_TYPE_LEVEL_HIGH); - irq_set_handler(irq, handle_level_irq); + set_irq_chip(irq, &intc_irq_chip); + set_irq_type(irq, IRQ_TYPE_LEVEL_HIGH); + set_irq_handler(irq, handle_level_irq); } } diff --git a/trunk/arch/microblaze/Kconfig b/trunk/arch/microblaze/Kconfig index c49c326e7af1..5f0cf0e32653 100644 --- a/trunk/arch/microblaze/Kconfig +++ b/trunk/arch/microblaze/Kconfig @@ -18,7 +18,6 @@ config MICROBLAZE select HAVE_GENERIC_HARDIRQS select GENERIC_IRQ_PROBE select GENERIC_HARDIRQS_NO_DEPRECATED - select GENERIC_IRQ_SHOW config SWAP def_bool n diff --git a/trunk/arch/microblaze/kernel/intc.c b/trunk/arch/microblaze/kernel/intc.c index 5ba7e162833b..e4661285118e 100644 --- a/trunk/arch/microblaze/kernel/intc.c +++ b/trunk/arch/microblaze/kernel/intc.c @@ -50,7 +50,7 @@ static void intc_enable_or_unmask(struct irq_data *d) * ack function since the handle_level_irq function * acks the irq before calling the interrupt handler */ - if (irqd_is_level_type(d)) + if (irq_to_desc(d->irq)->status & IRQ_LEVEL) out_be32(INTC_BASE + IAR, mask); } @@ -157,11 +157,11 @@ void __init init_IRQ(void) for (i = 0; i < nr_irq; ++i) { if (intr_type & (0x00000001 << i)) { - irq_set_chip_and_handler_name(i, &intc_dev, + set_irq_chip_and_handler_name(i, &intc_dev, handle_edge_irq, intc_dev.name); irq_clear_status_flags(i, IRQ_LEVEL); } else { - irq_set_chip_and_handler_name(i, &intc_dev, + set_irq_chip_and_handler_name(i, &intc_dev, handle_level_irq, intc_dev.name); irq_set_status_flags(i, IRQ_LEVEL); } diff --git a/trunk/arch/microblaze/kernel/irq.c b/trunk/arch/microblaze/kernel/irq.c index ce7ac8435d5c..098822413729 100644 --- a/trunk/arch/microblaze/kernel/irq.c +++ b/trunk/arch/microblaze/kernel/irq.c @@ -47,6 +47,48 @@ void __irq_entry do_IRQ(struct pt_regs *regs) trace_hardirqs_on(); } +int show_interrupts(struct seq_file *p, void *v) +{ + int i = *(loff_t *) v, j; + struct irq_desc *desc; + struct irqaction *action; + unsigned long flags; + + if (i == 0) { + seq_printf(p, " "); + for_each_online_cpu(j) + seq_printf(p, "CPU%-8d", j); + seq_putc(p, '\n'); + } + + if (i < nr_irq) { + desc = irq_to_desc(i); + raw_spin_lock_irqsave(&desc->lock, flags); + action = desc->action; + if (!action) + goto skip; + seq_printf(p, "%3d: ", i); +#ifndef CONFIG_SMP + seq_printf(p, "%10u ", kstat_irqs(i)); +#else + for_each_online_cpu(j) + seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]); +#endif + seq_printf(p, " %8s", desc->status & + IRQ_LEVEL ? "level" : "edge"); + seq_printf(p, " %8s", desc->irq_data.chip->name); + seq_printf(p, " %s", action->name); + + for (action = action->next; action; action = action->next) + seq_printf(p, ", %s", action->name); + + seq_putc(p, '\n'); +skip: + raw_spin_unlock_irqrestore(&desc->lock, flags); + } + return 0; +} + /* MS: There is no any advance mapping mechanism. We are using simple 32bit intc without any cascades or any connection that's why mapping is 1:1 */ unsigned int irq_create_mapping(struct irq_host *host, irq_hw_number_t hwirq) diff --git a/trunk/arch/microblaze/pci/pci-common.c b/trunk/arch/microblaze/pci/pci-common.c index 53599067d2f9..1e01a1253631 100644 --- a/trunk/arch/microblaze/pci/pci-common.c +++ b/trunk/arch/microblaze/pci/pci-common.c @@ -237,7 +237,7 @@ int pci_read_irq_line(struct pci_dev *pci_dev) virq = irq_create_mapping(NULL, line); if (virq != NO_IRQ) - irq_set_irq_type(virq, IRQ_TYPE_LEVEL_LOW); + set_irq_type(virq, IRQ_TYPE_LEVEL_LOW); } else { pr_debug(" Got one, spec %d cells (0x%08x 0x%08x...) on %s\n", oirq.size, oirq.specifier[0], oirq.specifier[1], diff --git a/trunk/arch/mips/alchemy/devboards/bcsr.c b/trunk/arch/mips/alchemy/devboards/bcsr.c index 596ad00e7f05..f91c43a7d5dc 100644 --- a/trunk/arch/mips/alchemy/devboards/bcsr.c +++ b/trunk/arch/mips/alchemy/devboards/bcsr.c @@ -142,8 +142,8 @@ void __init bcsr_init_irq(int csc_start, int csc_end, int hook_irq) bcsr_csc_base = csc_start; for (irq = csc_start; irq <= csc_end; irq++) - irq_set_chip_and_handler_name(irq, &bcsr_irq_type, - handle_level_irq, "level"); + set_irq_chip_and_handler_name(irq, &bcsr_irq_type, + handle_level_irq, "level"); - irq_set_chained_handler(hook_irq, bcsr_csc_handler); + set_irq_chained_handler(hook_irq, bcsr_csc_handler); } diff --git a/trunk/arch/mips/alchemy/devboards/db1200/setup.c b/trunk/arch/mips/alchemy/devboards/db1200/setup.c index 4a8980027ecf..887619547553 100644 --- a/trunk/arch/mips/alchemy/devboards/db1200/setup.c +++ b/trunk/arch/mips/alchemy/devboards/db1200/setup.c @@ -63,19 +63,20 @@ void __init board_setup(void) static int __init db1200_arch_init(void) { /* GPIO7 is low-level triggered CPLD cascade */ - irq_set_irq_type(AU1200_GPIO7_INT, IRQF_TRIGGER_LOW); + set_irq_type(AU1200_GPIO7_INT, IRQF_TRIGGER_LOW); bcsr_init_irq(DB1200_INT_BEGIN, DB1200_INT_END, AU1200_GPIO7_INT); /* insert/eject pairs: one of both is always screaming. To avoid * issues they must not be automatically enabled when initially * requested. */ - irq_set_status_flags(DB1200_SD0_INSERT_INT, IRQ_NOAUTOEN); - irq_set_status_flags(DB1200_SD0_EJECT_INT, IRQ_NOAUTOEN); - irq_set_status_flags(DB1200_PC0_INSERT_INT, IRQ_NOAUTOEN); - irq_set_status_flags(DB1200_PC0_EJECT_INT, IRQ_NOAUTOEN); - irq_set_status_flags(DB1200_PC1_INSERT_INT, IRQ_NOAUTOEN); - irq_set_status_flags(DB1200_PC1_EJECT_INT, IRQ_NOAUTOEN); + irq_to_desc(DB1200_SD0_INSERT_INT)->status |= IRQ_NOAUTOEN; + irq_to_desc(DB1200_SD0_EJECT_INT)->status |= IRQ_NOAUTOEN; + irq_to_desc(DB1200_PC0_INSERT_INT)->status |= IRQ_NOAUTOEN; + irq_to_desc(DB1200_PC0_EJECT_INT)->status |= IRQ_NOAUTOEN; + irq_to_desc(DB1200_PC1_INSERT_INT)->status |= IRQ_NOAUTOEN; + irq_to_desc(DB1200_PC1_EJECT_INT)->status |= IRQ_NOAUTOEN; + return 0; } arch_initcall(db1200_arch_init); diff --git a/trunk/arch/mips/alchemy/devboards/db1x00/board_setup.c b/trunk/arch/mips/alchemy/devboards/db1x00/board_setup.c index 05f120ff90f9..9e45971343ed 100644 --- a/trunk/arch/mips/alchemy/devboards/db1x00/board_setup.c +++ b/trunk/arch/mips/alchemy/devboards/db1x00/board_setup.c @@ -215,35 +215,35 @@ void __init board_setup(void) static int __init db1x00_init_irq(void) { #if defined(CONFIG_MIPS_MIRAGE) - irq_set_irq_type(AU1500_GPIO7_INT, IRQF_TRIGGER_RISING); /* TS pendown */ + set_irq_type(AU1500_GPIO7_INT, IRQF_TRIGGER_RISING); /* TS pendown */ #elif defined(CONFIG_MIPS_DB1550) - irq_set_irq_type(AU1550_GPIO0_INT, IRQF_TRIGGER_LOW); /* CD0# */ - irq_set_irq_type(AU1550_GPIO1_INT, IRQF_TRIGGER_LOW); /* CD1# */ - irq_set_irq_type(AU1550_GPIO3_INT, IRQF_TRIGGER_LOW); /* CARD0# */ - irq_set_irq_type(AU1550_GPIO5_INT, IRQF_TRIGGER_LOW); /* CARD1# */ - irq_set_irq_type(AU1550_GPIO21_INT, IRQF_TRIGGER_LOW); /* STSCHG0# */ - irq_set_irq_type(AU1550_GPIO22_INT, IRQF_TRIGGER_LOW); /* STSCHG1# */ + set_irq_type(AU1550_GPIO0_INT, IRQF_TRIGGER_LOW); /* CD0# */ + set_irq_type(AU1550_GPIO1_INT, IRQF_TRIGGER_LOW); /* CD1# */ + set_irq_type(AU1550_GPIO3_INT, IRQF_TRIGGER_LOW); /* CARD0# */ + set_irq_type(AU1550_GPIO5_INT, IRQF_TRIGGER_LOW); /* CARD1# */ + set_irq_type(AU1550_GPIO21_INT, IRQF_TRIGGER_LOW); /* STSCHG0# */ + set_irq_type(AU1550_GPIO22_INT, IRQF_TRIGGER_LOW); /* STSCHG1# */ #elif defined(CONFIG_MIPS_DB1500) - irq_set_irq_type(AU1500_GPIO0_INT, IRQF_TRIGGER_LOW); /* CD0# */ - irq_set_irq_type(AU1500_GPIO3_INT, IRQF_TRIGGER_LOW); /* CD1# */ - irq_set_irq_type(AU1500_GPIO2_INT, IRQF_TRIGGER_LOW); /* CARD0# */ - irq_set_irq_type(AU1500_GPIO5_INT, IRQF_TRIGGER_LOW); /* CARD1# */ - irq_set_irq_type(AU1500_GPIO1_INT, IRQF_TRIGGER_LOW); /* STSCHG0# */ - irq_set_irq_type(AU1500_GPIO4_INT, IRQF_TRIGGER_LOW); /* STSCHG1# */ + set_irq_type(AU1500_GPIO0_INT, IRQF_TRIGGER_LOW); /* CD0# */ + set_irq_type(AU1500_GPIO3_INT, IRQF_TRIGGER_LOW); /* CD1# */ + set_irq_type(AU1500_GPIO2_INT, IRQF_TRIGGER_LOW); /* CARD0# */ + set_irq_type(AU1500_GPIO5_INT, IRQF_TRIGGER_LOW); /* CARD1# */ + set_irq_type(AU1500_GPIO1_INT, IRQF_TRIGGER_LOW); /* STSCHG0# */ + set_irq_type(AU1500_GPIO4_INT, IRQF_TRIGGER_LOW); /* STSCHG1# */ #elif defined(CONFIG_MIPS_DB1100) - irq_set_irq_type(AU1100_GPIO0_INT, IRQF_TRIGGER_LOW); /* CD0# */ - irq_set_irq_type(AU1100_GPIO3_INT, IRQF_TRIGGER_LOW); /* CD1# */ - irq_set_irq_type(AU1100_GPIO2_INT, IRQF_TRIGGER_LOW); /* CARD0# */ - irq_set_irq_type(AU1100_GPIO5_INT, IRQF_TRIGGER_LOW); /* CARD1# */ - irq_set_irq_type(AU1100_GPIO1_INT, IRQF_TRIGGER_LOW); /* STSCHG0# */ - irq_set_irq_type(AU1100_GPIO4_INT, IRQF_TRIGGER_LOW); /* STSCHG1# */ + set_irq_type(AU1100_GPIO0_INT, IRQF_TRIGGER_LOW); /* CD0# */ + set_irq_type(AU1100_GPIO3_INT, IRQF_TRIGGER_LOW); /* CD1# */ + set_irq_type(AU1100_GPIO2_INT, IRQF_TRIGGER_LOW); /* CARD0# */ + set_irq_type(AU1100_GPIO5_INT, IRQF_TRIGGER_LOW); /* CARD1# */ + set_irq_type(AU1100_GPIO1_INT, IRQF_TRIGGER_LOW); /* STSCHG0# */ + set_irq_type(AU1100_GPIO4_INT, IRQF_TRIGGER_LOW); /* STSCHG1# */ #elif defined(CONFIG_MIPS_DB1000) - irq_set_irq_type(AU1000_GPIO0_INT, IRQF_TRIGGER_LOW); /* CD0# */ - irq_set_irq_type(AU1000_GPIO3_INT, IRQF_TRIGGER_LOW); /* CD1# */ - irq_set_irq_type(AU1000_GPIO2_INT, IRQF_TRIGGER_LOW); /* CARD0# */ - irq_set_irq_type(AU1000_GPIO5_INT, IRQF_TRIGGER_LOW); /* CARD1# */ - irq_set_irq_type(AU1000_GPIO1_INT, IRQF_TRIGGER_LOW); /* STSCHG0# */ - irq_set_irq_type(AU1000_GPIO4_INT, IRQF_TRIGGER_LOW); /* STSCHG1# */ + set_irq_type(AU1000_GPIO0_INT, IRQF_TRIGGER_LOW); /* CD0# */ + set_irq_type(AU1000_GPIO3_INT, IRQF_TRIGGER_LOW); /* CD1# */ + set_irq_type(AU1000_GPIO2_INT, IRQF_TRIGGER_LOW); /* CARD0# */ + set_irq_type(AU1000_GPIO5_INT, IRQF_TRIGGER_LOW); /* CARD1# */ + set_irq_type(AU1000_GPIO1_INT, IRQF_TRIGGER_LOW); /* STSCHG0# */ + set_irq_type(AU1000_GPIO4_INT, IRQF_TRIGGER_LOW); /* STSCHG1# */ #endif return 0; } diff --git a/trunk/arch/mips/alchemy/devboards/pb1000/board_setup.c b/trunk/arch/mips/alchemy/devboards/pb1000/board_setup.c index 2d85c4b5be09..f6540ec47a64 100644 --- a/trunk/arch/mips/alchemy/devboards/pb1000/board_setup.c +++ b/trunk/arch/mips/alchemy/devboards/pb1000/board_setup.c @@ -197,7 +197,7 @@ void __init board_setup(void) static int __init pb1000_init_irq(void) { - irq_set_irq_type(AU1000_GPIO15_INT, IRQF_TRIGGER_LOW); + set_irq_type(AU1000_GPIO15_INT, IRQF_TRIGGER_LOW); return 0; } arch_initcall(pb1000_init_irq); diff --git a/trunk/arch/mips/alchemy/devboards/pb1100/board_setup.c b/trunk/arch/mips/alchemy/devboards/pb1100/board_setup.c index d108fd573aaf..90dda5f3ecc5 100644 --- a/trunk/arch/mips/alchemy/devboards/pb1100/board_setup.c +++ b/trunk/arch/mips/alchemy/devboards/pb1100/board_setup.c @@ -117,10 +117,10 @@ void __init board_setup(void) static int __init pb1100_init_irq(void) { - irq_set_irq_type(AU1100_GPIO9_INT, IRQF_TRIGGER_LOW); /* PCCD# */ - irq_set_irq_type(AU1100_GPIO10_INT, IRQF_TRIGGER_LOW); /* PCSTSCHG# */ - irq_set_irq_type(AU1100_GPIO11_INT, IRQF_TRIGGER_LOW); /* PCCard# */ - irq_set_irq_type(AU1100_GPIO13_INT, IRQF_TRIGGER_LOW); /* DC_IRQ# */ + set_irq_type(AU1100_GPIO9_INT, IRQF_TRIGGER_LOW); /* PCCD# */ + set_irq_type(AU1100_GPIO10_INT, IRQF_TRIGGER_LOW); /* PCSTSCHG# */ + set_irq_type(AU1100_GPIO11_INT, IRQF_TRIGGER_LOW); /* PCCard# */ + set_irq_type(AU1100_GPIO13_INT, IRQF_TRIGGER_LOW); /* DC_IRQ# */ return 0; } diff --git a/trunk/arch/mips/alchemy/devboards/pb1200/board_setup.c b/trunk/arch/mips/alchemy/devboards/pb1200/board_setup.c index 6d06b07c2381..8b4466f2d44a 100644 --- a/trunk/arch/mips/alchemy/devboards/pb1200/board_setup.c +++ b/trunk/arch/mips/alchemy/devboards/pb1200/board_setup.c @@ -142,7 +142,7 @@ static int __init pb1200_init_irq(void) panic("Game over. Your score is 0."); } - irq_set_irq_type(AU1200_GPIO7_INT, IRQF_TRIGGER_LOW); + set_irq_type(AU1200_GPIO7_INT, IRQF_TRIGGER_LOW); bcsr_init_irq(PB1200_INT_BEGIN, PB1200_INT_END, AU1200_GPIO7_INT); return 0; diff --git a/trunk/arch/mips/alchemy/devboards/pb1500/board_setup.c b/trunk/arch/mips/alchemy/devboards/pb1500/board_setup.c index 83f46215eb0c..9cd9dfa698e7 100644 --- a/trunk/arch/mips/alchemy/devboards/pb1500/board_setup.c +++ b/trunk/arch/mips/alchemy/devboards/pb1500/board_setup.c @@ -134,14 +134,14 @@ void __init board_setup(void) static int __init pb1500_init_irq(void) { - irq_set_irq_type(AU1500_GPIO9_INT, IRQF_TRIGGER_LOW); /* CD0# */ - irq_set_irq_type(AU1500_GPIO10_INT, IRQF_TRIGGER_LOW); /* CARD0 */ - irq_set_irq_type(AU1500_GPIO11_INT, IRQF_TRIGGER_LOW); /* STSCHG0# */ - irq_set_irq_type(AU1500_GPIO204_INT, IRQF_TRIGGER_HIGH); - irq_set_irq_type(AU1500_GPIO201_INT, IRQF_TRIGGER_LOW); - irq_set_irq_type(AU1500_GPIO202_INT, IRQF_TRIGGER_LOW); - irq_set_irq_type(AU1500_GPIO203_INT, IRQF_TRIGGER_LOW); - irq_set_irq_type(AU1500_GPIO205_INT, IRQF_TRIGGER_LOW); + set_irq_type(AU1500_GPIO9_INT, IRQF_TRIGGER_LOW); /* CD0# */ + set_irq_type(AU1500_GPIO10_INT, IRQF_TRIGGER_LOW); /* CARD0 */ + set_irq_type(AU1500_GPIO11_INT, IRQF_TRIGGER_LOW); /* STSCHG0# */ + set_irq_type(AU1500_GPIO204_INT, IRQF_TRIGGER_HIGH); + set_irq_type(AU1500_GPIO201_INT, IRQF_TRIGGER_LOW); + set_irq_type(AU1500_GPIO202_INT, IRQF_TRIGGER_LOW); + set_irq_type(AU1500_GPIO203_INT, IRQF_TRIGGER_LOW); + set_irq_type(AU1500_GPIO205_INT, IRQF_TRIGGER_LOW); return 0; } diff --git a/trunk/arch/mips/alchemy/devboards/pb1550/board_setup.c b/trunk/arch/mips/alchemy/devboards/pb1550/board_setup.c index b790213848bd..9d7d6edafa8d 100644 --- a/trunk/arch/mips/alchemy/devboards/pb1550/board_setup.c +++ b/trunk/arch/mips/alchemy/devboards/pb1550/board_setup.c @@ -73,9 +73,9 @@ void __init board_setup(void) static int __init pb1550_init_irq(void) { - irq_set_irq_type(AU1550_GPIO0_INT, IRQF_TRIGGER_LOW); - irq_set_irq_type(AU1550_GPIO1_INT, IRQF_TRIGGER_LOW); - irq_set_irq_type(AU1550_GPIO201_205_INT, IRQF_TRIGGER_HIGH); + set_irq_type(AU1550_GPIO0_INT, IRQF_TRIGGER_LOW); + set_irq_type(AU1550_GPIO1_INT, IRQF_TRIGGER_LOW); + set_irq_type(AU1550_GPIO201_205_INT, IRQF_TRIGGER_HIGH); /* enable both PCMCIA card irqs in the shared line */ alchemy_gpio2_enable_int(201); diff --git a/trunk/arch/mips/alchemy/mtx-1/board_setup.c b/trunk/arch/mips/alchemy/mtx-1/board_setup.c index cf436ab679ae..40b84b991191 100644 --- a/trunk/arch/mips/alchemy/mtx-1/board_setup.c +++ b/trunk/arch/mips/alchemy/mtx-1/board_setup.c @@ -123,11 +123,11 @@ mtx1_pci_idsel(unsigned int devsel, int assert) static int __init mtx1_init_irq(void) { - irq_set_irq_type(AU1500_GPIO204_INT, IRQF_TRIGGER_HIGH); - irq_set_irq_type(AU1500_GPIO201_INT, IRQF_TRIGGER_LOW); - irq_set_irq_type(AU1500_GPIO202_INT, IRQF_TRIGGER_LOW); - irq_set_irq_type(AU1500_GPIO203_INT, IRQF_TRIGGER_LOW); - irq_set_irq_type(AU1500_GPIO205_INT, IRQF_TRIGGER_LOW); + set_irq_type(AU1500_GPIO204_INT, IRQF_TRIGGER_HIGH); + set_irq_type(AU1500_GPIO201_INT, IRQF_TRIGGER_LOW); + set_irq_type(AU1500_GPIO202_INT, IRQF_TRIGGER_LOW); + set_irq_type(AU1500_GPIO203_INT, IRQF_TRIGGER_LOW); + set_irq_type(AU1500_GPIO205_INT, IRQF_TRIGGER_LOW); return 0; } diff --git a/trunk/arch/mips/alchemy/xxs1500/board_setup.c b/trunk/arch/mips/alchemy/xxs1500/board_setup.c index febfb0fb0896..80c521e5290d 100644 --- a/trunk/arch/mips/alchemy/xxs1500/board_setup.c +++ b/trunk/arch/mips/alchemy/xxs1500/board_setup.c @@ -85,19 +85,19 @@ void __init board_setup(void) static int __init xxs1500_init_irq(void) { - irq_set_irq_type(AU1500_GPIO204_INT, IRQF_TRIGGER_HIGH); - irq_set_irq_type(AU1500_GPIO201_INT, IRQF_TRIGGER_LOW); - irq_set_irq_type(AU1500_GPIO202_INT, IRQF_TRIGGER_LOW); - irq_set_irq_type(AU1500_GPIO203_INT, IRQF_TRIGGER_LOW); - irq_set_irq_type(AU1500_GPIO205_INT, IRQF_TRIGGER_LOW); - irq_set_irq_type(AU1500_GPIO207_INT, IRQF_TRIGGER_LOW); + set_irq_type(AU1500_GPIO204_INT, IRQF_TRIGGER_HIGH); + set_irq_type(AU1500_GPIO201_INT, IRQF_TRIGGER_LOW); + set_irq_type(AU1500_GPIO202_INT, IRQF_TRIGGER_LOW); + set_irq_type(AU1500_GPIO203_INT, IRQF_TRIGGER_LOW); + set_irq_type(AU1500_GPIO205_INT, IRQF_TRIGGER_LOW); + set_irq_type(AU1500_GPIO207_INT, IRQF_TRIGGER_LOW); - irq_set_irq_type(AU1500_GPIO0_INT, IRQF_TRIGGER_LOW); - irq_set_irq_type(AU1500_GPIO1_INT, IRQF_TRIGGER_LOW); - irq_set_irq_type(AU1500_GPIO2_INT, IRQF_TRIGGER_LOW); - irq_set_irq_type(AU1500_GPIO3_INT, IRQF_TRIGGER_LOW); - irq_set_irq_type(AU1500_GPIO4_INT, IRQF_TRIGGER_LOW); /* CF irq */ - irq_set_irq_type(AU1500_GPIO5_INT, IRQF_TRIGGER_LOW); + set_irq_type(AU1500_GPIO0_INT, IRQF_TRIGGER_LOW); + set_irq_type(AU1500_GPIO1_INT, IRQF_TRIGGER_LOW); + set_irq_type(AU1500_GPIO2_INT, IRQF_TRIGGER_LOW); + set_irq_type(AU1500_GPIO3_INT, IRQF_TRIGGER_LOW); + set_irq_type(AU1500_GPIO4_INT, IRQF_TRIGGER_LOW); /* CF irq */ + set_irq_type(AU1500_GPIO5_INT, IRQF_TRIGGER_LOW); return 0; } diff --git a/trunk/arch/mips/ar7/irq.c b/trunk/arch/mips/ar7/irq.c index 03db3daadbd8..a6484b60642f 100644 --- a/trunk/arch/mips/ar7/irq.c +++ b/trunk/arch/mips/ar7/irq.c @@ -119,11 +119,11 @@ static void __init ar7_irq_init(int base) for (i = 0; i < 40; i++) { writel(i, REG(CHNL_OFFSET(i))); /* Primary IRQ's */ - irq_set_chip_and_handler(base + i, &ar7_irq_type, + set_irq_chip_and_handler(base + i, &ar7_irq_type, handle_level_irq); /* Secondary IRQ's */ if (i < 32) - irq_set_chip_and_handler(base + i + 40, + set_irq_chip_and_handler(base + i + 40, &ar7_sec_irq_type, handle_level_irq); } diff --git a/trunk/arch/mips/ath79/irq.c b/trunk/arch/mips/ath79/irq.c index ac610d5fe3ba..7c02bc948a31 100644 --- a/trunk/arch/mips/ath79/irq.c +++ b/trunk/arch/mips/ath79/irq.c @@ -124,11 +124,11 @@ static void __init ath79_misc_irq_init(void) for (i = ATH79_MISC_IRQ_BASE; i < ATH79_MISC_IRQ_BASE + ATH79_MISC_IRQ_COUNT; i++) { - irq_set_chip_and_handler(i, &ath79_misc_irq_chip, + set_irq_chip_and_handler(i, &ath79_misc_irq_chip, handle_level_irq); } - irq_set_chained_handler(ATH79_CPU_IRQ_MISC, ath79_misc_irq_handler); + set_irq_chained_handler(ATH79_CPU_IRQ_MISC, ath79_misc_irq_handler); } asmlinkage void plat_irq_dispatch(void) diff --git a/trunk/arch/mips/bcm63xx/irq.c b/trunk/arch/mips/bcm63xx/irq.c index cea6021cb8d7..1691531aa34d 100644 --- a/trunk/arch/mips/bcm63xx/irq.c +++ b/trunk/arch/mips/bcm63xx/irq.c @@ -230,11 +230,11 @@ void __init arch_init_irq(void) mips_cpu_irq_init(); for (i = IRQ_INTERNAL_BASE; i < NR_IRQS; ++i) - irq_set_chip_and_handler(i, &bcm63xx_internal_irq_chip, + set_irq_chip_and_handler(i, &bcm63xx_internal_irq_chip, handle_level_irq); for (i = IRQ_EXT_BASE; i < IRQ_EXT_BASE + 4; ++i) - irq_set_chip_and_handler(i, &bcm63xx_external_irq_chip, + set_irq_chip_and_handler(i, &bcm63xx_external_irq_chip, handle_edge_irq); setup_irq(IRQ_MIPS_BASE + 2, &cpu_ip2_cascade_action); diff --git a/trunk/arch/mips/cavium-octeon/octeon-irq.c b/trunk/arch/mips/cavium-octeon/octeon-irq.c index ffd4ae660f79..ce7500cdf5b7 100644 --- a/trunk/arch/mips/cavium-octeon/octeon-irq.c +++ b/trunk/arch/mips/cavium-octeon/octeon-irq.c @@ -3,13 +3,10 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (C) 2004-2008, 2009, 2010, 2011 Cavium Networks + * Copyright (C) 2004-2008, 2009, 2010 Cavium Networks */ - -#include -#include -#include #include +#include #include #include @@ -17,47 +14,6 @@ static DEFINE_RAW_SPINLOCK(octeon_irq_ciu0_lock); static DEFINE_RAW_SPINLOCK(octeon_irq_ciu1_lock); -static DEFINE_PER_CPU(unsigned long, octeon_irq_ciu0_en_mirror); -static DEFINE_PER_CPU(unsigned long, octeon_irq_ciu1_en_mirror); - -static __read_mostly u8 octeon_irq_ciu_to_irq[8][64]; - -union octeon_ciu_chip_data { - void *p; - unsigned long l; - struct { - unsigned int line:6; - unsigned int bit:6; - } s; -}; - -struct octeon_core_chip_data { - struct mutex core_irq_mutex; - bool current_en; - bool desired_en; - u8 bit; -}; - -#define MIPS_CORE_IRQ_LINES 8 - -static struct octeon_core_chip_data octeon_irq_core_chip_data[MIPS_CORE_IRQ_LINES]; - -static void __init octeon_irq_set_ciu_mapping(int irq, int line, int bit, - struct irq_chip *chip, - irq_flow_handler_t handler) -{ - union octeon_ciu_chip_data cd; - - irq_set_chip_and_handler(irq, chip, handler); - - cd.l = 0; - cd.s.line = line; - cd.s.bit = bit; - - irq_set_chip_data(irq, cd.p); - octeon_irq_ciu_to_irq[line][bit] = irq; -} - static int octeon_coreid_for_cpu(int cpu) { #ifdef CONFIG_SMP @@ -67,20 +23,9 @@ static int octeon_coreid_for_cpu(int cpu) #endif } -static int octeon_cpu_for_coreid(int coreid) -{ -#ifdef CONFIG_SMP - return cpu_number_map(coreid); -#else - return smp_processor_id(); -#endif -} - -static void octeon_irq_core_ack(struct irq_data *data) +static void octeon_irq_core_ack(unsigned int irq) { - struct octeon_core_chip_data *cd = irq_data_get_irq_chip_data(data); - unsigned int bit = cd->bit; - + unsigned int bit = irq - OCTEON_IRQ_SW0; /* * We don't need to disable IRQs to make these atomic since * they are already disabled earlier in the low level @@ -92,121 +37,131 @@ static void octeon_irq_core_ack(struct irq_data *data) clear_c0_cause(0x100 << bit); } -static void octeon_irq_core_eoi(struct irq_data *data) +static void octeon_irq_core_eoi(unsigned int irq) { - struct octeon_core_chip_data *cd = irq_data_get_irq_chip_data(data); - + struct irq_desc *desc = irq_to_desc(irq); + unsigned int bit = irq - OCTEON_IRQ_SW0; + /* + * If an IRQ is being processed while we are disabling it the + * handler will attempt to unmask the interrupt after it has + * been disabled. + */ + if ((unlikely(desc->status & IRQ_DISABLED))) + return; /* * We don't need to disable IRQs to make these atomic since * they are already disabled earlier in the low level * interrupt code. */ - set_c0_status(0x100 << cd->bit); + set_c0_status(0x100 << bit); } -static void octeon_irq_core_set_enable_local(void *arg) +static void octeon_irq_core_enable(unsigned int irq) { - struct irq_data *data = arg; - struct octeon_core_chip_data *cd = irq_data_get_irq_chip_data(data); - unsigned int mask = 0x100 << cd->bit; + unsigned long flags; + unsigned int bit = irq - OCTEON_IRQ_SW0; /* - * Interrupts are already disabled, so these are atomic. + * We need to disable interrupts to make sure our updates are + * atomic. */ - if (cd->desired_en) - set_c0_status(mask); - else - clear_c0_status(mask); - + local_irq_save(flags); + set_c0_status(0x100 << bit); + local_irq_restore(flags); } -static void octeon_irq_core_disable(struct irq_data *data) +static void octeon_irq_core_disable_local(unsigned int irq) { - struct octeon_core_chip_data *cd = irq_data_get_irq_chip_data(data); - cd->desired_en = false; + unsigned long flags; + unsigned int bit = irq - OCTEON_IRQ_SW0; + /* + * We need to disable interrupts to make sure our updates are + * atomic. + */ + local_irq_save(flags); + clear_c0_status(0x100 << bit); + local_irq_restore(flags); } -static void octeon_irq_core_enable(struct irq_data *data) +static void octeon_irq_core_disable(unsigned int irq) { - struct octeon_core_chip_data *cd = irq_data_get_irq_chip_data(data); - cd->desired_en = true; +#ifdef CONFIG_SMP + on_each_cpu((void (*)(void *)) octeon_irq_core_disable_local, + (void *) (long) irq, 1); +#else + octeon_irq_core_disable_local(irq); +#endif } -static void octeon_irq_core_bus_lock(struct irq_data *data) -{ - struct octeon_core_chip_data *cd = irq_data_get_irq_chip_data(data); +static struct irq_chip octeon_irq_chip_core = { + .name = "Core", + .enable = octeon_irq_core_enable, + .disable = octeon_irq_core_disable, + .ack = octeon_irq_core_ack, + .eoi = octeon_irq_core_eoi, +}; - mutex_lock(&cd->core_irq_mutex); -} -static void octeon_irq_core_bus_sync_unlock(struct irq_data *data) +static void octeon_irq_ciu0_ack(unsigned int irq) { - struct octeon_core_chip_data *cd = irq_data_get_irq_chip_data(data); - - if (cd->desired_en != cd->current_en) { - on_each_cpu(octeon_irq_core_set_enable_local, data, 1); - - cd->current_en = cd->desired_en; + switch (irq) { + case OCTEON_IRQ_GMX_DRP0: + case OCTEON_IRQ_GMX_DRP1: + case OCTEON_IRQ_IPD_DRP: + case OCTEON_IRQ_KEY_ZERO: + case OCTEON_IRQ_TIMER0: + case OCTEON_IRQ_TIMER1: + case OCTEON_IRQ_TIMER2: + case OCTEON_IRQ_TIMER3: + { + int index = cvmx_get_core_num() * 2; + u64 mask = 1ull << (irq - OCTEON_IRQ_WORKQ0); + /* + * CIU timer type interrupts must be acknoleged by + * writing a '1' bit to their sum0 bit. + */ + cvmx_write_csr(CVMX_CIU_INTX_SUM0(index), mask); + break; + } + default: + break; } - mutex_unlock(&cd->core_irq_mutex); + /* + * In order to avoid any locking accessing the CIU, we + * acknowledge CIU interrupts by disabling all of them. This + * way we can use a per core register and avoid any out of + * core locking requirements. This has the side affect that + * CIU interrupts can't be processed recursively. + * + * We don't need to disable IRQs to make these atomic since + * they are already disabled earlier in the low level + * interrupt code. + */ + clear_c0_status(0x100 << 2); } -static struct irq_chip octeon_irq_chip_core = { - .name = "Core", - .irq_enable = octeon_irq_core_enable, - .irq_disable = octeon_irq_core_disable, - .irq_ack = octeon_irq_core_ack, - .irq_eoi = octeon_irq_core_eoi, - .irq_bus_lock = octeon_irq_core_bus_lock, - .irq_bus_sync_unlock = octeon_irq_core_bus_sync_unlock, - - .irq_cpu_online = octeon_irq_core_eoi, - .irq_cpu_offline = octeon_irq_core_ack, - .flags = IRQCHIP_ONOFFLINE_ENABLED, -}; - -static void __init octeon_irq_init_core(void) +static void octeon_irq_ciu0_eoi(unsigned int irq) { - int i; - int irq; - struct octeon_core_chip_data *cd; - - for (i = 0; i < MIPS_CORE_IRQ_LINES; i++) { - cd = &octeon_irq_core_chip_data[i]; - cd->current_en = false; - cd->desired_en = false; - cd->bit = i; - mutex_init(&cd->core_irq_mutex); - - irq = OCTEON_IRQ_SW0 + i; - switch (irq) { - case OCTEON_IRQ_TIMER: - case OCTEON_IRQ_SW0: - case OCTEON_IRQ_SW1: - case OCTEON_IRQ_5: - case OCTEON_IRQ_PERF: - irq_set_chip_data(irq, cd); - irq_set_chip_and_handler(irq, &octeon_irq_chip_core, - handle_percpu_irq); - break; - default: - break; - } - } + /* + * Enable all CIU interrupts again. We don't need to disable + * IRQs to make these atomic since they are already disabled + * earlier in the low level interrupt code. + */ + set_c0_status(0x100 << 2); } -static int next_cpu_for_irq(struct irq_data *data) +static int next_coreid_for_irq(struct irq_desc *desc) { #ifdef CONFIG_SMP - int cpu; - int weight = cpumask_weight(data->affinity); + int coreid; + int weight = cpumask_weight(desc->affinity); if (weight > 1) { - cpu = smp_processor_id(); + int cpu = smp_processor_id(); for (;;) { - cpu = cpumask_next(cpu, data->affinity); + cpu = cpumask_next(cpu, desc->affinity); if (cpu >= nr_cpu_ids) { cpu = -1; continue; @@ -214,175 +169,83 @@ static int next_cpu_for_irq(struct irq_data *data) break; } } + coreid = octeon_coreid_for_cpu(cpu); } else if (weight == 1) { - cpu = cpumask_first(data->affinity); + coreid = octeon_coreid_for_cpu(cpumask_first(desc->affinity)); } else { - cpu = smp_processor_id(); + coreid = cvmx_get_core_num(); } - return cpu; + return coreid; #else - return smp_processor_id(); + return cvmx_get_core_num(); #endif } -static void octeon_irq_ciu_enable(struct irq_data *data) -{ - int cpu = next_cpu_for_irq(data); - int coreid = octeon_coreid_for_cpu(cpu); - unsigned long *pen; - unsigned long flags; - union octeon_ciu_chip_data cd; - - cd.p = irq_data_get_irq_chip_data(data); - - if (cd.s.line == 0) { - raw_spin_lock_irqsave(&octeon_irq_ciu0_lock, flags); - pen = &per_cpu(octeon_irq_ciu0_en_mirror, cpu); - set_bit(cd.s.bit, pen); - cvmx_write_csr(CVMX_CIU_INTX_EN0(coreid * 2), *pen); - raw_spin_unlock_irqrestore(&octeon_irq_ciu0_lock, flags); - } else { - raw_spin_lock_irqsave(&octeon_irq_ciu1_lock, flags); - pen = &per_cpu(octeon_irq_ciu1_en_mirror, cpu); - set_bit(cd.s.bit, pen); - cvmx_write_csr(CVMX_CIU_INTX_EN1(coreid * 2 + 1), *pen); - raw_spin_unlock_irqrestore(&octeon_irq_ciu1_lock, flags); - } -} - -static void octeon_irq_ciu_enable_local(struct irq_data *data) +static void octeon_irq_ciu0_enable(unsigned int irq) { - unsigned long *pen; + struct irq_desc *desc = irq_to_desc(irq); + int coreid = next_coreid_for_irq(desc); unsigned long flags; - union octeon_ciu_chip_data cd; - - cd.p = irq_data_get_irq_chip_data(data); + uint64_t en0; + int bit = irq - OCTEON_IRQ_WORKQ0; /* Bit 0-63 of EN0 */ - if (cd.s.line == 0) { - raw_spin_lock_irqsave(&octeon_irq_ciu0_lock, flags); - pen = &__get_cpu_var(octeon_irq_ciu0_en_mirror); - set_bit(cd.s.bit, pen); - cvmx_write_csr(CVMX_CIU_INTX_EN0(cvmx_get_core_num() * 2), *pen); - raw_spin_unlock_irqrestore(&octeon_irq_ciu0_lock, flags); - } else { - raw_spin_lock_irqsave(&octeon_irq_ciu1_lock, flags); - pen = &__get_cpu_var(octeon_irq_ciu1_en_mirror); - set_bit(cd.s.bit, pen); - cvmx_write_csr(CVMX_CIU_INTX_EN1(cvmx_get_core_num() * 2 + 1), *pen); - raw_spin_unlock_irqrestore(&octeon_irq_ciu1_lock, flags); - } + raw_spin_lock_irqsave(&octeon_irq_ciu0_lock, flags); + en0 = cvmx_read_csr(CVMX_CIU_INTX_EN0(coreid * 2)); + en0 |= 1ull << bit; + cvmx_write_csr(CVMX_CIU_INTX_EN0(coreid * 2), en0); + cvmx_read_csr(CVMX_CIU_INTX_EN0(coreid * 2)); + raw_spin_unlock_irqrestore(&octeon_irq_ciu0_lock, flags); } -static void octeon_irq_ciu_disable_local(struct irq_data *data) -{ - unsigned long *pen; - unsigned long flags; - union octeon_ciu_chip_data cd; - - cd.p = irq_data_get_irq_chip_data(data); - - if (cd.s.line == 0) { - raw_spin_lock_irqsave(&octeon_irq_ciu0_lock, flags); - pen = &__get_cpu_var(octeon_irq_ciu0_en_mirror); - clear_bit(cd.s.bit, pen); - cvmx_write_csr(CVMX_CIU_INTX_EN0(cvmx_get_core_num() * 2), *pen); - raw_spin_unlock_irqrestore(&octeon_irq_ciu0_lock, flags); - } else { - raw_spin_lock_irqsave(&octeon_irq_ciu1_lock, flags); - pen = &__get_cpu_var(octeon_irq_ciu1_en_mirror); - clear_bit(cd.s.bit, pen); - cvmx_write_csr(CVMX_CIU_INTX_EN1(cvmx_get_core_num() * 2 + 1), *pen); - raw_spin_unlock_irqrestore(&octeon_irq_ciu1_lock, flags); - } -} - -static void octeon_irq_ciu_disable_all(struct irq_data *data) +static void octeon_irq_ciu0_enable_mbox(unsigned int irq) { + int coreid = cvmx_get_core_num(); unsigned long flags; - unsigned long *pen; - int cpu; - union octeon_ciu_chip_data cd; + uint64_t en0; + int bit = irq - OCTEON_IRQ_WORKQ0; /* Bit 0-63 of EN0 */ - wmb(); /* Make sure flag changes arrive before register updates. */ - - cd.p = irq_data_get_irq_chip_data(data); - - if (cd.s.line == 0) { - raw_spin_lock_irqsave(&octeon_irq_ciu0_lock, flags); - for_each_online_cpu(cpu) { - int coreid = octeon_coreid_for_cpu(cpu); - pen = &per_cpu(octeon_irq_ciu0_en_mirror, cpu); - clear_bit(cd.s.bit, pen); - cvmx_write_csr(CVMX_CIU_INTX_EN0(coreid * 2), *pen); - } - raw_spin_unlock_irqrestore(&octeon_irq_ciu0_lock, flags); - } else { - raw_spin_lock_irqsave(&octeon_irq_ciu1_lock, flags); - for_each_online_cpu(cpu) { - int coreid = octeon_coreid_for_cpu(cpu); - pen = &per_cpu(octeon_irq_ciu1_en_mirror, cpu); - clear_bit(cd.s.bit, pen); - cvmx_write_csr(CVMX_CIU_INTX_EN1(coreid * 2 + 1), *pen); - } - raw_spin_unlock_irqrestore(&octeon_irq_ciu1_lock, flags); - } + raw_spin_lock_irqsave(&octeon_irq_ciu0_lock, flags); + en0 = cvmx_read_csr(CVMX_CIU_INTX_EN0(coreid * 2)); + en0 |= 1ull << bit; + cvmx_write_csr(CVMX_CIU_INTX_EN0(coreid * 2), en0); + cvmx_read_csr(CVMX_CIU_INTX_EN0(coreid * 2)); + raw_spin_unlock_irqrestore(&octeon_irq_ciu0_lock, flags); } -static void octeon_irq_ciu_enable_all(struct irq_data *data) +static void octeon_irq_ciu0_disable(unsigned int irq) { + int bit = irq - OCTEON_IRQ_WORKQ0; /* Bit 0-63 of EN0 */ unsigned long flags; - unsigned long *pen; + uint64_t en0; int cpu; - union octeon_ciu_chip_data cd; - - cd.p = irq_data_get_irq_chip_data(data); - - if (cd.s.line == 0) { - raw_spin_lock_irqsave(&octeon_irq_ciu0_lock, flags); - for_each_online_cpu(cpu) { - int coreid = octeon_coreid_for_cpu(cpu); - pen = &per_cpu(octeon_irq_ciu0_en_mirror, cpu); - set_bit(cd.s.bit, pen); - cvmx_write_csr(CVMX_CIU_INTX_EN0(coreid * 2), *pen); - } - raw_spin_unlock_irqrestore(&octeon_irq_ciu0_lock, flags); - } else { - raw_spin_lock_irqsave(&octeon_irq_ciu1_lock, flags); - for_each_online_cpu(cpu) { - int coreid = octeon_coreid_for_cpu(cpu); - pen = &per_cpu(octeon_irq_ciu1_en_mirror, cpu); - set_bit(cd.s.bit, pen); - cvmx_write_csr(CVMX_CIU_INTX_EN1(coreid * 2 + 1), *pen); - } - raw_spin_unlock_irqrestore(&octeon_irq_ciu1_lock, flags); + raw_spin_lock_irqsave(&octeon_irq_ciu0_lock, flags); + for_each_online_cpu(cpu) { + int coreid = octeon_coreid_for_cpu(cpu); + en0 = cvmx_read_csr(CVMX_CIU_INTX_EN0(coreid * 2)); + en0 &= ~(1ull << bit); + cvmx_write_csr(CVMX_CIU_INTX_EN0(coreid * 2), en0); } + /* + * We need to do a read after the last update to make sure all + * of them are done. + */ + cvmx_read_csr(CVMX_CIU_INTX_EN0(cvmx_get_core_num() * 2)); + raw_spin_unlock_irqrestore(&octeon_irq_ciu0_lock, flags); } /* * Enable the irq on the next core in the affinity set for chips that * have the EN*_W1{S,C} registers. */ -static void octeon_irq_ciu_enable_v2(struct irq_data *data) +static void octeon_irq_ciu0_enable_v2(unsigned int irq) { - u64 mask; - int cpu = next_cpu_for_irq(data); - union octeon_ciu_chip_data cd; - - cd.p = irq_data_get_irq_chip_data(data); - mask = 1ull << (cd.s.bit); + int index; + u64 mask = 1ull << (irq - OCTEON_IRQ_WORKQ0); + struct irq_desc *desc = irq_to_desc(irq); - /* - * Called under the desc lock, so these should never get out - * of sync. - */ - if (cd.s.line == 0) { - int index = octeon_coreid_for_cpu(cpu) * 2; - set_bit(cd.s.bit, &per_cpu(octeon_irq_ciu0_en_mirror, cpu)); + if ((desc->status & IRQ_DISABLED) == 0) { + index = next_coreid_for_irq(desc) * 2; cvmx_write_csr(CVMX_CIU_INTX_EN0_W1S(index), mask); - } else { - int index = octeon_coreid_for_cpu(cpu) * 2 + 1; - set_bit(cd.s.bit, &per_cpu(octeon_irq_ciu1_en_mirror, cpu)); - cvmx_write_csr(CVMX_CIU_INTX_EN1_W1S(index), mask); } } @@ -390,155 +253,83 @@ static void octeon_irq_ciu_enable_v2(struct irq_data *data) * Enable the irq on the current CPU for chips that * have the EN*_W1{S,C} registers. */ -static void octeon_irq_ciu_enable_local_v2(struct irq_data *data) -{ - u64 mask; - union octeon_ciu_chip_data cd; - - cd.p = irq_data_get_irq_chip_data(data); - mask = 1ull << (cd.s.bit); - - if (cd.s.line == 0) { - int index = cvmx_get_core_num() * 2; - set_bit(cd.s.bit, &__get_cpu_var(octeon_irq_ciu0_en_mirror)); - cvmx_write_csr(CVMX_CIU_INTX_EN0_W1S(index), mask); - } else { - int index = cvmx_get_core_num() * 2 + 1; - set_bit(cd.s.bit, &__get_cpu_var(octeon_irq_ciu1_en_mirror)); - cvmx_write_csr(CVMX_CIU_INTX_EN1_W1S(index), mask); - } -} - -static void octeon_irq_ciu_disable_local_v2(struct irq_data *data) +static void octeon_irq_ciu0_enable_mbox_v2(unsigned int irq) { - u64 mask; - union octeon_ciu_chip_data cd; + int index; + u64 mask = 1ull << (irq - OCTEON_IRQ_WORKQ0); - cd.p = irq_data_get_irq_chip_data(data); - mask = 1ull << (cd.s.bit); - - if (cd.s.line == 0) { - int index = cvmx_get_core_num() * 2; - clear_bit(cd.s.bit, &__get_cpu_var(octeon_irq_ciu0_en_mirror)); - cvmx_write_csr(CVMX_CIU_INTX_EN0_W1C(index), mask); - } else { - int index = cvmx_get_core_num() * 2 + 1; - clear_bit(cd.s.bit, &__get_cpu_var(octeon_irq_ciu1_en_mirror)); - cvmx_write_csr(CVMX_CIU_INTX_EN1_W1C(index), mask); - } + index = cvmx_get_core_num() * 2; + cvmx_write_csr(CVMX_CIU_INTX_EN0_W1S(index), mask); } /* - * Write to the W1C bit in CVMX_CIU_INTX_SUM0 to clear the irq. + * Disable the irq on the current core for chips that have the EN*_W1{S,C} + * registers. */ -static void octeon_irq_ciu_ack(struct irq_data *data) -{ - u64 mask; - union octeon_ciu_chip_data cd; - - cd.p = data->chip_data; - mask = 1ull << (cd.s.bit); - - if (cd.s.line == 0) { - int index = cvmx_get_core_num() * 2; +static void octeon_irq_ciu0_ack_v2(unsigned int irq) +{ + int index = cvmx_get_core_num() * 2; + u64 mask = 1ull << (irq - OCTEON_IRQ_WORKQ0); + + switch (irq) { + case OCTEON_IRQ_GMX_DRP0: + case OCTEON_IRQ_GMX_DRP1: + case OCTEON_IRQ_IPD_DRP: + case OCTEON_IRQ_KEY_ZERO: + case OCTEON_IRQ_TIMER0: + case OCTEON_IRQ_TIMER1: + case OCTEON_IRQ_TIMER2: + case OCTEON_IRQ_TIMER3: + /* + * CIU timer type interrupts must be acknoleged by + * writing a '1' bit to their sum0 bit. + */ cvmx_write_csr(CVMX_CIU_INTX_SUM0(index), mask); - } else { - cvmx_write_csr(CVMX_CIU_INT_SUM1, mask); + break; + default: + break; } + + cvmx_write_csr(CVMX_CIU_INTX_EN0_W1C(index), mask); } /* - * Disable the irq on the all cores for chips that have the EN*_W1{S,C} + * Enable the irq on the current core for chips that have the EN*_W1{S,C} * registers. */ -static void octeon_irq_ciu_disable_all_v2(struct irq_data *data) +static void octeon_irq_ciu0_eoi_mbox_v2(unsigned int irq) { - int cpu; - u64 mask; - union octeon_ciu_chip_data cd; - - wmb(); /* Make sure flag changes arrive before register updates. */ - - cd.p = data->chip_data; - mask = 1ull << (cd.s.bit); + struct irq_desc *desc = irq_to_desc(irq); + int index = cvmx_get_core_num() * 2; + u64 mask = 1ull << (irq - OCTEON_IRQ_WORKQ0); - if (cd.s.line == 0) { - for_each_online_cpu(cpu) { - int index = octeon_coreid_for_cpu(cpu) * 2; - clear_bit(cd.s.bit, &per_cpu(octeon_irq_ciu0_en_mirror, cpu)); - cvmx_write_csr(CVMX_CIU_INTX_EN0_W1C(index), mask); - } - } else { - for_each_online_cpu(cpu) { - int index = octeon_coreid_for_cpu(cpu) * 2 + 1; - clear_bit(cd.s.bit, &per_cpu(octeon_irq_ciu1_en_mirror, cpu)); - cvmx_write_csr(CVMX_CIU_INTX_EN1_W1C(index), mask); - } - } + if (likely((desc->status & IRQ_DISABLED) == 0)) + cvmx_write_csr(CVMX_CIU_INTX_EN0_W1S(index), mask); } /* - * Enable the irq on the all cores for chips that have the EN*_W1{S,C} + * Disable the irq on the all cores for chips that have the EN*_W1{S,C} * registers. */ -static void octeon_irq_ciu_enable_all_v2(struct irq_data *data) +static void octeon_irq_ciu0_disable_all_v2(unsigned int irq) { + u64 mask = 1ull << (irq - OCTEON_IRQ_WORKQ0); + int index; int cpu; - u64 mask; - union octeon_ciu_chip_data cd; - - cd.p = data->chip_data; - mask = 1ull << (cd.s.bit); - - if (cd.s.line == 0) { - for_each_online_cpu(cpu) { - int index = octeon_coreid_for_cpu(cpu) * 2; - set_bit(cd.s.bit, &per_cpu(octeon_irq_ciu0_en_mirror, cpu)); - cvmx_write_csr(CVMX_CIU_INTX_EN0_W1S(index), mask); - } - } else { - for_each_online_cpu(cpu) { - int index = octeon_coreid_for_cpu(cpu) * 2 + 1; - set_bit(cd.s.bit, &per_cpu(octeon_irq_ciu1_en_mirror, cpu)); - cvmx_write_csr(CVMX_CIU_INTX_EN1_W1S(index), mask); - } + for_each_online_cpu(cpu) { + index = octeon_coreid_for_cpu(cpu) * 2; + cvmx_write_csr(CVMX_CIU_INTX_EN0_W1C(index), mask); } } #ifdef CONFIG_SMP - -static void octeon_irq_cpu_offline_ciu(struct irq_data *data) -{ - int cpu = smp_processor_id(); - cpumask_t new_affinity; - - if (!cpumask_test_cpu(cpu, data->affinity)) - return; - - if (cpumask_weight(data->affinity) > 1) { - /* - * It has multi CPU affinity, just remove this CPU - * from the affinity set. - */ - cpumask_copy(&new_affinity, data->affinity); - cpumask_clear_cpu(cpu, &new_affinity); - } else { - /* Otherwise, put it on lowest numbered online CPU. */ - cpumask_clear(&new_affinity); - cpumask_set_cpu(cpumask_first(cpu_online_mask), &new_affinity); - } - __irq_set_affinity_locked(data, &new_affinity); -} - -static int octeon_irq_ciu_set_affinity(struct irq_data *data, - const struct cpumask *dest, bool force) +static int octeon_irq_ciu0_set_affinity(unsigned int irq, const struct cpumask *dest) { int cpu; - bool enable_one = !irqd_irq_disabled(data) && !irqd_irq_masked(data); + struct irq_desc *desc = irq_to_desc(irq); + int enable_one = (desc->status & IRQ_DISABLED) == 0; unsigned long flags; - union octeon_ciu_chip_data cd; - - cd.p = data->chip_data; + int bit = irq - OCTEON_IRQ_WORKQ0; /* Bit 0-63 of EN0 */ /* * For non-v2 CIU, we will allow only single CPU affinity. @@ -548,40 +339,26 @@ static int octeon_irq_ciu_set_affinity(struct irq_data *data, if (cpumask_weight(dest) != 1) return -EINVAL; - if (!enable_one) - return 0; - - if (cd.s.line == 0) { - raw_spin_lock_irqsave(&octeon_irq_ciu0_lock, flags); - for_each_online_cpu(cpu) { - int coreid = octeon_coreid_for_cpu(cpu); - unsigned long *pen = &per_cpu(octeon_irq_ciu0_en_mirror, cpu); - - if (cpumask_test_cpu(cpu, dest) && enable_one) { - enable_one = false; - set_bit(cd.s.bit, pen); - } else { - clear_bit(cd.s.bit, pen); - } - cvmx_write_csr(CVMX_CIU_INTX_EN0(coreid * 2), *pen); + raw_spin_lock_irqsave(&octeon_irq_ciu0_lock, flags); + for_each_online_cpu(cpu) { + int coreid = octeon_coreid_for_cpu(cpu); + uint64_t en0 = + cvmx_read_csr(CVMX_CIU_INTX_EN0(coreid * 2)); + if (cpumask_test_cpu(cpu, dest) && enable_one) { + enable_one = 0; + en0 |= 1ull << bit; + } else { + en0 &= ~(1ull << bit); } - raw_spin_unlock_irqrestore(&octeon_irq_ciu0_lock, flags); - } else { - raw_spin_lock_irqsave(&octeon_irq_ciu1_lock, flags); - for_each_online_cpu(cpu) { - int coreid = octeon_coreid_for_cpu(cpu); - unsigned long *pen = &per_cpu(octeon_irq_ciu1_en_mirror, cpu); - - if (cpumask_test_cpu(cpu, dest) && enable_one) { - enable_one = false; - set_bit(cd.s.bit, pen); - } else { - clear_bit(cd.s.bit, pen); - } - cvmx_write_csr(CVMX_CIU_INTX_EN1(coreid * 2 + 1), *pen); - } - raw_spin_unlock_irqrestore(&octeon_irq_ciu1_lock, flags); + cvmx_write_csr(CVMX_CIU_INTX_EN0(coreid * 2), en0); } + /* + * We need to do a read after the last update to make sure all + * of them are done. + */ + cvmx_read_csr(CVMX_CIU_INTX_EN0(cvmx_get_core_num() * 2)); + raw_spin_unlock_irqrestore(&octeon_irq_ciu0_lock, flags); + return 0; } @@ -589,149 +366,103 @@ static int octeon_irq_ciu_set_affinity(struct irq_data *data, * Set affinity for the irq for chips that have the EN*_W1{S,C} * registers. */ -static int octeon_irq_ciu_set_affinity_v2(struct irq_data *data, - const struct cpumask *dest, - bool force) +static int octeon_irq_ciu0_set_affinity_v2(unsigned int irq, + const struct cpumask *dest) { int cpu; - bool enable_one = !irqd_irq_disabled(data) && !irqd_irq_masked(data); - u64 mask; - union octeon_ciu_chip_data cd; - - if (!enable_one) - return 0; - - cd.p = data->chip_data; - mask = 1ull << cd.s.bit; - - if (cd.s.line == 0) { - for_each_online_cpu(cpu) { - unsigned long *pen = &per_cpu(octeon_irq_ciu0_en_mirror, cpu); - int index = octeon_coreid_for_cpu(cpu) * 2; - if (cpumask_test_cpu(cpu, dest) && enable_one) { - enable_one = false; - set_bit(cd.s.bit, pen); - cvmx_write_csr(CVMX_CIU_INTX_EN0_W1S(index), mask); - } else { - clear_bit(cd.s.bit, pen); - cvmx_write_csr(CVMX_CIU_INTX_EN0_W1C(index), mask); - } - } - } else { - for_each_online_cpu(cpu) { - unsigned long *pen = &per_cpu(octeon_irq_ciu1_en_mirror, cpu); - int index = octeon_coreid_for_cpu(cpu) * 2 + 1; - if (cpumask_test_cpu(cpu, dest) && enable_one) { - enable_one = false; - set_bit(cd.s.bit, pen); - cvmx_write_csr(CVMX_CIU_INTX_EN1_W1S(index), mask); - } else { - clear_bit(cd.s.bit, pen); - cvmx_write_csr(CVMX_CIU_INTX_EN1_W1C(index), mask); - } + int index; + struct irq_desc *desc = irq_to_desc(irq); + int enable_one = (desc->status & IRQ_DISABLED) == 0; + u64 mask = 1ull << (irq - OCTEON_IRQ_WORKQ0); + + for_each_online_cpu(cpu) { + index = octeon_coreid_for_cpu(cpu) * 2; + if (cpumask_test_cpu(cpu, dest) && enable_one) { + enable_one = 0; + cvmx_write_csr(CVMX_CIU_INTX_EN0_W1S(index), mask); + } else { + cvmx_write_csr(CVMX_CIU_INTX_EN0_W1C(index), mask); } } return 0; } #endif -/* - * The v1 CIU code already masks things, so supply a dummy version to - * the core chip code. - */ -static void octeon_irq_dummy_mask(struct irq_data *data) -{ -} - /* * Newer octeon chips have support for lockless CIU operation. */ -static struct irq_chip octeon_irq_chip_ciu_v2 = { - .name = "CIU", - .irq_enable = octeon_irq_ciu_enable_v2, - .irq_disable = octeon_irq_ciu_disable_all_v2, - .irq_mask = octeon_irq_ciu_disable_local_v2, - .irq_unmask = octeon_irq_ciu_enable_v2, +static struct irq_chip octeon_irq_chip_ciu0_v2 = { + .name = "CIU0", + .enable = octeon_irq_ciu0_enable_v2, + .disable = octeon_irq_ciu0_disable_all_v2, + .eoi = octeon_irq_ciu0_enable_v2, #ifdef CONFIG_SMP - .irq_set_affinity = octeon_irq_ciu_set_affinity_v2, - .irq_cpu_offline = octeon_irq_cpu_offline_ciu, + .set_affinity = octeon_irq_ciu0_set_affinity_v2, #endif }; -static struct irq_chip octeon_irq_chip_ciu_edge_v2 = { - .name = "CIU-E", - .irq_enable = octeon_irq_ciu_enable_v2, - .irq_disable = octeon_irq_ciu_disable_all_v2, - .irq_ack = octeon_irq_ciu_ack, - .irq_mask = octeon_irq_ciu_disable_local_v2, - .irq_unmask = octeon_irq_ciu_enable_v2, +static struct irq_chip octeon_irq_chip_ciu0 = { + .name = "CIU0", + .enable = octeon_irq_ciu0_enable, + .disable = octeon_irq_ciu0_disable, + .eoi = octeon_irq_ciu0_eoi, #ifdef CONFIG_SMP - .irq_set_affinity = octeon_irq_ciu_set_affinity_v2, - .irq_cpu_offline = octeon_irq_cpu_offline_ciu, + .set_affinity = octeon_irq_ciu0_set_affinity, #endif }; -static struct irq_chip octeon_irq_chip_ciu = { - .name = "CIU", - .irq_enable = octeon_irq_ciu_enable, - .irq_disable = octeon_irq_ciu_disable_all, - .irq_mask = octeon_irq_dummy_mask, -#ifdef CONFIG_SMP - .irq_set_affinity = octeon_irq_ciu_set_affinity, - .irq_cpu_offline = octeon_irq_cpu_offline_ciu, -#endif -}; - -static struct irq_chip octeon_irq_chip_ciu_edge = { - .name = "CIU-E", - .irq_enable = octeon_irq_ciu_enable, - .irq_disable = octeon_irq_ciu_disable_all, - .irq_mask = octeon_irq_dummy_mask, - .irq_ack = octeon_irq_ciu_ack, -#ifdef CONFIG_SMP - .irq_set_affinity = octeon_irq_ciu_set_affinity, - .irq_cpu_offline = octeon_irq_cpu_offline_ciu, -#endif +/* The mbox versions don't do any affinity or round-robin. */ +static struct irq_chip octeon_irq_chip_ciu0_mbox_v2 = { + .name = "CIU0-M", + .enable = octeon_irq_ciu0_enable_mbox_v2, + .disable = octeon_irq_ciu0_disable, + .eoi = octeon_irq_ciu0_eoi_mbox_v2, }; -/* The mbox versions don't do any affinity or round-robin. */ -static struct irq_chip octeon_irq_chip_ciu_mbox_v2 = { - .name = "CIU-M", - .irq_enable = octeon_irq_ciu_enable_all_v2, - .irq_disable = octeon_irq_ciu_disable_all_v2, - .irq_ack = octeon_irq_ciu_disable_local_v2, - .irq_eoi = octeon_irq_ciu_enable_local_v2, - - .irq_cpu_online = octeon_irq_ciu_enable_local_v2, - .irq_cpu_offline = octeon_irq_ciu_disable_local_v2, - .flags = IRQCHIP_ONOFFLINE_ENABLED, +static struct irq_chip octeon_irq_chip_ciu0_mbox = { + .name = "CIU0-M", + .enable = octeon_irq_ciu0_enable_mbox, + .disable = octeon_irq_ciu0_disable, + .eoi = octeon_irq_ciu0_eoi, }; -static struct irq_chip octeon_irq_chip_ciu_mbox = { - .name = "CIU-M", - .irq_enable = octeon_irq_ciu_enable_all, - .irq_disable = octeon_irq_ciu_disable_all, +static void octeon_irq_ciu1_ack(unsigned int irq) +{ + /* + * In order to avoid any locking accessing the CIU, we + * acknowledge CIU interrupts by disabling all of them. This + * way we can use a per core register and avoid any out of + * core locking requirements. This has the side affect that + * CIU interrupts can't be processed recursively. We don't + * need to disable IRQs to make these atomic since they are + * already disabled earlier in the low level interrupt code. + */ + clear_c0_status(0x100 << 3); +} - .irq_cpu_online = octeon_irq_ciu_enable_local, - .irq_cpu_offline = octeon_irq_ciu_disable_local, - .flags = IRQCHIP_ONOFFLINE_ENABLED, -}; +static void octeon_irq_ciu1_eoi(unsigned int irq) +{ + /* + * Enable all CIU interrupts again. We don't need to disable + * IRQs to make these atomic since they are already disabled + * earlier in the low level interrupt code. + */ + set_c0_status(0x100 << 3); +} -/* - * Watchdog interrupts are special. They are associated with a single - * core, so we hardwire the affinity to that core. - */ -static void octeon_irq_ciu_wd_enable(struct irq_data *data) +static void octeon_irq_ciu1_enable(unsigned int irq) { + struct irq_desc *desc = irq_to_desc(irq); + int coreid = next_coreid_for_irq(desc); unsigned long flags; - unsigned long *pen; - int coreid = data->irq - OCTEON_IRQ_WDOG0; /* Bit 0-63 of EN1 */ - int cpu = octeon_cpu_for_coreid(coreid); + uint64_t en1; + int bit = irq - OCTEON_IRQ_WDOG0; /* Bit 0-63 of EN1 */ raw_spin_lock_irqsave(&octeon_irq_ciu1_lock, flags); - pen = &per_cpu(octeon_irq_ciu1_en_mirror, cpu); - set_bit(coreid, pen); - cvmx_write_csr(CVMX_CIU_INTX_EN1(coreid * 2 + 1), *pen); + en1 = cvmx_read_csr(CVMX_CIU_INTX_EN1(coreid * 2 + 1)); + en1 |= 1ull << bit; + cvmx_write_csr(CVMX_CIU_INTX_EN1(coreid * 2 + 1), en1); + cvmx_read_csr(CVMX_CIU_INTX_EN1(coreid * 2 + 1)); raw_spin_unlock_irqrestore(&octeon_irq_ciu1_lock, flags); } @@ -739,281 +470,286 @@ static void octeon_irq_ciu_wd_enable(struct irq_data *data) * Watchdog interrupts are special. They are associated with a single * core, so we hardwire the affinity to that core. */ -static void octeon_irq_ciu1_wd_enable_v2(struct irq_data *data) +static void octeon_irq_ciu1_wd_enable(unsigned int irq) { - int coreid = data->irq - OCTEON_IRQ_WDOG0; - int cpu = octeon_cpu_for_coreid(coreid); + unsigned long flags; + uint64_t en1; + int bit = irq - OCTEON_IRQ_WDOG0; /* Bit 0-63 of EN1 */ + int coreid = bit; - set_bit(coreid, &per_cpu(octeon_irq_ciu1_en_mirror, cpu)); - cvmx_write_csr(CVMX_CIU_INTX_EN1_W1S(coreid * 2 + 1), 1ull << coreid); + raw_spin_lock_irqsave(&octeon_irq_ciu1_lock, flags); + en1 = cvmx_read_csr(CVMX_CIU_INTX_EN1(coreid * 2 + 1)); + en1 |= 1ull << bit; + cvmx_write_csr(CVMX_CIU_INTX_EN1(coreid * 2 + 1), en1); + cvmx_read_csr(CVMX_CIU_INTX_EN1(coreid * 2 + 1)); + raw_spin_unlock_irqrestore(&octeon_irq_ciu1_lock, flags); } - -static struct irq_chip octeon_irq_chip_ciu_wd_v2 = { - .name = "CIU-W", - .irq_enable = octeon_irq_ciu1_wd_enable_v2, - .irq_disable = octeon_irq_ciu_disable_all_v2, - .irq_mask = octeon_irq_ciu_disable_local_v2, - .irq_unmask = octeon_irq_ciu_enable_local_v2, -}; - -static struct irq_chip octeon_irq_chip_ciu_wd = { - .name = "CIU-W", - .irq_enable = octeon_irq_ciu_wd_enable, - .irq_disable = octeon_irq_ciu_disable_all, - .irq_mask = octeon_irq_dummy_mask, -}; - -static void octeon_irq_ip2_v1(void) +static void octeon_irq_ciu1_disable(unsigned int irq) { - const unsigned long core_id = cvmx_get_core_num(); - u64 ciu_sum = cvmx_read_csr(CVMX_CIU_INTX_SUM0(core_id * 2)); - - ciu_sum &= __get_cpu_var(octeon_irq_ciu0_en_mirror); - clear_c0_status(STATUSF_IP2); - if (likely(ciu_sum)) { - int bit = fls64(ciu_sum) - 1; - int irq = octeon_irq_ciu_to_irq[0][bit]; - if (likely(irq)) - do_IRQ(irq); - else - spurious_interrupt(); - } else { - spurious_interrupt(); + int bit = irq - OCTEON_IRQ_WDOG0; /* Bit 0-63 of EN1 */ + unsigned long flags; + uint64_t en1; + int cpu; + raw_spin_lock_irqsave(&octeon_irq_ciu1_lock, flags); + for_each_online_cpu(cpu) { + int coreid = octeon_coreid_for_cpu(cpu); + en1 = cvmx_read_csr(CVMX_CIU_INTX_EN1(coreid * 2 + 1)); + en1 &= ~(1ull << bit); + cvmx_write_csr(CVMX_CIU_INTX_EN1(coreid * 2 + 1), en1); } - set_c0_status(STATUSF_IP2); + /* + * We need to do a read after the last update to make sure all + * of them are done. + */ + cvmx_read_csr(CVMX_CIU_INTX_EN1(cvmx_get_core_num() * 2 + 1)); + raw_spin_unlock_irqrestore(&octeon_irq_ciu1_lock, flags); } -static void octeon_irq_ip2_v2(void) -{ - const unsigned long core_id = cvmx_get_core_num(); - u64 ciu_sum = cvmx_read_csr(CVMX_CIU_INTX_SUM0(core_id * 2)); - - ciu_sum &= __get_cpu_var(octeon_irq_ciu0_en_mirror); - if (likely(ciu_sum)) { - int bit = fls64(ciu_sum) - 1; - int irq = octeon_irq_ciu_to_irq[0][bit]; - if (likely(irq)) - do_IRQ(irq); - else - spurious_interrupt(); - } else { - spurious_interrupt(); - } -} -static void octeon_irq_ip3_v1(void) +/* + * Enable the irq on the current core for chips that have the EN*_W1{S,C} + * registers. + */ +static void octeon_irq_ciu1_enable_v2(unsigned int irq) { - u64 ciu_sum = cvmx_read_csr(CVMX_CIU_INT_SUM1); - - ciu_sum &= __get_cpu_var(octeon_irq_ciu1_en_mirror); - clear_c0_status(STATUSF_IP3); - if (likely(ciu_sum)) { - int bit = fls64(ciu_sum) - 1; - int irq = octeon_irq_ciu_to_irq[1][bit]; - if (likely(irq)) - do_IRQ(irq); - else - spurious_interrupt(); - } else { - spurious_interrupt(); + int index; + u64 mask = 1ull << (irq - OCTEON_IRQ_WDOG0); + struct irq_desc *desc = irq_to_desc(irq); + + if ((desc->status & IRQ_DISABLED) == 0) { + index = next_coreid_for_irq(desc) * 2 + 1; + cvmx_write_csr(CVMX_CIU_INTX_EN1_W1S(index), mask); } - set_c0_status(STATUSF_IP3); } -static void octeon_irq_ip3_v2(void) +/* + * Watchdog interrupts are special. They are associated with a single + * core, so we hardwire the affinity to that core. + */ +static void octeon_irq_ciu1_wd_enable_v2(unsigned int irq) { - u64 ciu_sum = cvmx_read_csr(CVMX_CIU_INT_SUM1); - - ciu_sum &= __get_cpu_var(octeon_irq_ciu1_en_mirror); - if (likely(ciu_sum)) { - int bit = fls64(ciu_sum) - 1; - int irq = octeon_irq_ciu_to_irq[1][bit]; - if (likely(irq)) - do_IRQ(irq); - else - spurious_interrupt(); - } else { - spurious_interrupt(); + int index; + int coreid = irq - OCTEON_IRQ_WDOG0; + u64 mask = 1ull << (irq - OCTEON_IRQ_WDOG0); + struct irq_desc *desc = irq_to_desc(irq); + + if ((desc->status & IRQ_DISABLED) == 0) { + index = coreid * 2 + 1; + cvmx_write_csr(CVMX_CIU_INTX_EN1_W1S(index), mask); } } -static void octeon_irq_ip4_mask(void) +/* + * Disable the irq on the current core for chips that have the EN*_W1{S,C} + * registers. + */ +static void octeon_irq_ciu1_ack_v2(unsigned int irq) { - clear_c0_status(STATUSF_IP4); - spurious_interrupt(); -} - -static void (*octeon_irq_ip2)(void); -static void (*octeon_irq_ip3)(void); -static void (*octeon_irq_ip4)(void); + int index = cvmx_get_core_num() * 2 + 1; + u64 mask = 1ull << (irq - OCTEON_IRQ_WDOG0); -void __cpuinitdata (*octeon_irq_setup_secondary)(void); + cvmx_write_csr(CVMX_CIU_INTX_EN1_W1C(index), mask); +} -static void __cpuinit octeon_irq_percpu_enable(void) +/* + * Disable the irq on the all cores for chips that have the EN*_W1{S,C} + * registers. + */ +static void octeon_irq_ciu1_disable_all_v2(unsigned int irq) { - irq_cpu_online(); + u64 mask = 1ull << (irq - OCTEON_IRQ_WDOG0); + int index; + int cpu; + for_each_online_cpu(cpu) { + index = octeon_coreid_for_cpu(cpu) * 2 + 1; + cvmx_write_csr(CVMX_CIU_INTX_EN1_W1C(index), mask); + } } -static void __cpuinit octeon_irq_init_ciu_percpu(void) +#ifdef CONFIG_SMP +static int octeon_irq_ciu1_set_affinity(unsigned int irq, + const struct cpumask *dest) { - int coreid = cvmx_get_core_num(); + int cpu; + struct irq_desc *desc = irq_to_desc(irq); + int enable_one = (desc->status & IRQ_DISABLED) == 0; + unsigned long flags; + int bit = irq - OCTEON_IRQ_WDOG0; /* Bit 0-63 of EN1 */ + /* - * Disable All CIU Interrupts. The ones we need will be - * enabled later. Read the SUM register so we know the write - * completed. + * For non-v2 CIU, we will allow only single CPU affinity. + * This removes the need to do locking in the .ack/.eoi + * functions. */ - cvmx_write_csr(CVMX_CIU_INTX_EN0((coreid * 2)), 0); - cvmx_write_csr(CVMX_CIU_INTX_EN0((coreid * 2 + 1)), 0); - cvmx_write_csr(CVMX_CIU_INTX_EN1((coreid * 2)), 0); - cvmx_write_csr(CVMX_CIU_INTX_EN1((coreid * 2 + 1)), 0); - cvmx_read_csr(CVMX_CIU_INTX_SUM0((coreid * 2))); + if (cpumask_weight(dest) != 1) + return -EINVAL; + + raw_spin_lock_irqsave(&octeon_irq_ciu1_lock, flags); + for_each_online_cpu(cpu) { + int coreid = octeon_coreid_for_cpu(cpu); + uint64_t en1 = + cvmx_read_csr(CVMX_CIU_INTX_EN1(coreid * 2 + 1)); + if (cpumask_test_cpu(cpu, dest) && enable_one) { + enable_one = 0; + en1 |= 1ull << bit; + } else { + en1 &= ~(1ull << bit); + } + cvmx_write_csr(CVMX_CIU_INTX_EN1(coreid * 2 + 1), en1); + } + /* + * We need to do a read after the last update to make sure all + * of them are done. + */ + cvmx_read_csr(CVMX_CIU_INTX_EN1(cvmx_get_core_num() * 2 + 1)); + raw_spin_unlock_irqrestore(&octeon_irq_ciu1_lock, flags); + + return 0; } -static void __cpuinit octeon_irq_setup_secondary_ciu(void) +/* + * Set affinity for the irq for chips that have the EN*_W1{S,C} + * registers. + */ +static int octeon_irq_ciu1_set_affinity_v2(unsigned int irq, + const struct cpumask *dest) { + int cpu; + int index; + struct irq_desc *desc = irq_to_desc(irq); + int enable_one = (desc->status & IRQ_DISABLED) == 0; + u64 mask = 1ull << (irq - OCTEON_IRQ_WDOG0); + for_each_online_cpu(cpu) { + index = octeon_coreid_for_cpu(cpu) * 2 + 1; + if (cpumask_test_cpu(cpu, dest) && enable_one) { + enable_one = 0; + cvmx_write_csr(CVMX_CIU_INTX_EN1_W1S(index), mask); + } else { + cvmx_write_csr(CVMX_CIU_INTX_EN1_W1C(index), mask); + } + } + return 0; +} +#endif - __get_cpu_var(octeon_irq_ciu0_en_mirror) = 0; - __get_cpu_var(octeon_irq_ciu1_en_mirror) = 0; - - octeon_irq_init_ciu_percpu(); - octeon_irq_percpu_enable(); +/* + * Newer octeon chips have support for lockless CIU operation. + */ +static struct irq_chip octeon_irq_chip_ciu1_v2 = { + .name = "CIU1", + .enable = octeon_irq_ciu1_enable_v2, + .disable = octeon_irq_ciu1_disable_all_v2, + .eoi = octeon_irq_ciu1_enable_v2, +#ifdef CONFIG_SMP + .set_affinity = octeon_irq_ciu1_set_affinity_v2, +#endif +}; - /* Enable the CIU lines */ - set_c0_status(STATUSF_IP3 | STATUSF_IP2); - clear_c0_status(STATUSF_IP4); -} +static struct irq_chip octeon_irq_chip_ciu1 = { + .name = "CIU1", + .enable = octeon_irq_ciu1_enable, + .disable = octeon_irq_ciu1_disable, + .eoi = octeon_irq_ciu1_eoi, +#ifdef CONFIG_SMP + .set_affinity = octeon_irq_ciu1_set_affinity, +#endif +}; -static void __init octeon_irq_init_ciu(void) -{ - unsigned int i; - struct irq_chip *chip; - struct irq_chip *chip_edge; - struct irq_chip *chip_mbox; - struct irq_chip *chip_wd; +static struct irq_chip octeon_irq_chip_ciu1_wd_v2 = { + .name = "CIU1-W", + .enable = octeon_irq_ciu1_wd_enable_v2, + .disable = octeon_irq_ciu1_disable_all_v2, + .eoi = octeon_irq_ciu1_wd_enable_v2, +}; - octeon_irq_init_ciu_percpu(); - octeon_irq_setup_secondary = octeon_irq_setup_secondary_ciu; +static struct irq_chip octeon_irq_chip_ciu1_wd = { + .name = "CIU1-W", + .enable = octeon_irq_ciu1_wd_enable, + .disable = octeon_irq_ciu1_disable, + .eoi = octeon_irq_ciu1_eoi, +}; - if (OCTEON_IS_MODEL(OCTEON_CN58XX_PASS2_X) || - OCTEON_IS_MODEL(OCTEON_CN56XX_PASS2_X) || - OCTEON_IS_MODEL(OCTEON_CN52XX_PASS2_X) || - OCTEON_IS_MODEL(OCTEON_CN6XXX)) { - octeon_irq_ip2 = octeon_irq_ip2_v2; - octeon_irq_ip3 = octeon_irq_ip3_v2; - chip = &octeon_irq_chip_ciu_v2; - chip_edge = &octeon_irq_chip_ciu_edge_v2; - chip_mbox = &octeon_irq_chip_ciu_mbox_v2; - chip_wd = &octeon_irq_chip_ciu_wd_v2; - } else { - octeon_irq_ip2 = octeon_irq_ip2_v1; - octeon_irq_ip3 = octeon_irq_ip3_v1; - chip = &octeon_irq_chip_ciu; - chip_edge = &octeon_irq_chip_ciu_edge; - chip_mbox = &octeon_irq_chip_ciu_mbox; - chip_wd = &octeon_irq_chip_ciu_wd; - } - octeon_irq_ip4 = octeon_irq_ip4_mask; - - /* Mips internal */ - octeon_irq_init_core(); - - /* CIU_0 */ - for (i = 0; i < 16; i++) - octeon_irq_set_ciu_mapping(i + OCTEON_IRQ_WORKQ0, 0, i + 0, chip, handle_level_irq); - for (i = 0; i < 16; i++) - octeon_irq_set_ciu_mapping(i + OCTEON_IRQ_GPIO0, 0, i + 16, chip, handle_level_irq); - - octeon_irq_set_ciu_mapping(OCTEON_IRQ_MBOX0, 0, 32, chip_mbox, handle_percpu_irq); - octeon_irq_set_ciu_mapping(OCTEON_IRQ_MBOX1, 0, 33, chip_mbox, handle_percpu_irq); - - octeon_irq_set_ciu_mapping(OCTEON_IRQ_UART0, 0, 34, chip, handle_level_irq); - octeon_irq_set_ciu_mapping(OCTEON_IRQ_UART1, 0, 35, chip, handle_level_irq); - - for (i = 0; i < 4; i++) - octeon_irq_set_ciu_mapping(i + OCTEON_IRQ_PCI_INT0, 0, i + 36, chip, handle_level_irq); - for (i = 0; i < 4; i++) - octeon_irq_set_ciu_mapping(i + OCTEON_IRQ_PCI_MSI0, 0, i + 40, chip, handle_level_irq); - - octeon_irq_set_ciu_mapping(OCTEON_IRQ_TWSI, 0, 45, chip, handle_level_irq); - octeon_irq_set_ciu_mapping(OCTEON_IRQ_RML, 0, 46, chip, handle_level_irq); - octeon_irq_set_ciu_mapping(OCTEON_IRQ_TRACE0, 0, 47, chip, handle_level_irq); - - for (i = 0; i < 2; i++) - octeon_irq_set_ciu_mapping(i + OCTEON_IRQ_GMX_DRP0, 0, i + 48, chip_edge, handle_edge_irq); - - octeon_irq_set_ciu_mapping(OCTEON_IRQ_IPD_DRP, 0, 50, chip_edge, handle_edge_irq); - octeon_irq_set_ciu_mapping(OCTEON_IRQ_KEY_ZERO, 0, 51, chip_edge, handle_edge_irq); - - for (i = 0; i < 4; i++) - octeon_irq_set_ciu_mapping(i + OCTEON_IRQ_TIMER0, 0, i + 52, chip_edge, handle_edge_irq); - - octeon_irq_set_ciu_mapping(OCTEON_IRQ_USB0, 0, 56, chip, handle_level_irq); - octeon_irq_set_ciu_mapping(OCTEON_IRQ_PCM, 0, 57, chip, handle_level_irq); - octeon_irq_set_ciu_mapping(OCTEON_IRQ_MPI, 0, 58, chip, handle_level_irq); - octeon_irq_set_ciu_mapping(OCTEON_IRQ_TWSI2, 0, 59, chip, handle_level_irq); - octeon_irq_set_ciu_mapping(OCTEON_IRQ_POWIQ, 0, 60, chip, handle_level_irq); - octeon_irq_set_ciu_mapping(OCTEON_IRQ_IPDPPTHR, 0, 61, chip, handle_level_irq); - octeon_irq_set_ciu_mapping(OCTEON_IRQ_MII0, 0, 62, chip, handle_level_irq); - octeon_irq_set_ciu_mapping(OCTEON_IRQ_BOOTDMA, 0, 63, chip, handle_level_irq); - - /* CIU_1 */ - for (i = 0; i < 16; i++) - octeon_irq_set_ciu_mapping(i + OCTEON_IRQ_WDOG0, 1, i + 0, chip_wd, handle_level_irq); - - octeon_irq_set_ciu_mapping(OCTEON_IRQ_UART2, 1, 16, chip, handle_level_irq); - octeon_irq_set_ciu_mapping(OCTEON_IRQ_USB1, 1, 17, chip, handle_level_irq); - octeon_irq_set_ciu_mapping(OCTEON_IRQ_MII1, 1, 18, chip, handle_level_irq); - octeon_irq_set_ciu_mapping(OCTEON_IRQ_NAND, 1, 19, chip, handle_level_irq); - octeon_irq_set_ciu_mapping(OCTEON_IRQ_MIO, 1, 20, chip, handle_level_irq); - octeon_irq_set_ciu_mapping(OCTEON_IRQ_IOB, 1, 21, chip, handle_level_irq); - octeon_irq_set_ciu_mapping(OCTEON_IRQ_FPA, 1, 22, chip, handle_level_irq); - octeon_irq_set_ciu_mapping(OCTEON_IRQ_POW, 1, 23, chip, handle_level_irq); - octeon_irq_set_ciu_mapping(OCTEON_IRQ_L2C, 1, 24, chip, handle_level_irq); - octeon_irq_set_ciu_mapping(OCTEON_IRQ_IPD, 1, 25, chip, handle_level_irq); - octeon_irq_set_ciu_mapping(OCTEON_IRQ_PIP, 1, 26, chip, handle_level_irq); - octeon_irq_set_ciu_mapping(OCTEON_IRQ_PKO, 1, 27, chip, handle_level_irq); - octeon_irq_set_ciu_mapping(OCTEON_IRQ_ZIP, 1, 28, chip, handle_level_irq); - octeon_irq_set_ciu_mapping(OCTEON_IRQ_TIM, 1, 29, chip, handle_level_irq); - octeon_irq_set_ciu_mapping(OCTEON_IRQ_RAD, 1, 30, chip, handle_level_irq); - octeon_irq_set_ciu_mapping(OCTEON_IRQ_KEY, 1, 31, chip, handle_level_irq); - octeon_irq_set_ciu_mapping(OCTEON_IRQ_DFA, 1, 32, chip, handle_level_irq); - octeon_irq_set_ciu_mapping(OCTEON_IRQ_USBCTL, 1, 33, chip, handle_level_irq); - octeon_irq_set_ciu_mapping(OCTEON_IRQ_SLI, 1, 34, chip, handle_level_irq); - octeon_irq_set_ciu_mapping(OCTEON_IRQ_DPI, 1, 35, chip, handle_level_irq); - - octeon_irq_set_ciu_mapping(OCTEON_IRQ_AGX0, 1, 36, chip, handle_level_irq); - - octeon_irq_set_ciu_mapping(OCTEON_IRQ_AGL, 1, 46, chip, handle_level_irq); - - octeon_irq_set_ciu_mapping(OCTEON_IRQ_PTP, 1, 47, chip_edge, handle_edge_irq); - - octeon_irq_set_ciu_mapping(OCTEON_IRQ_PEM0, 1, 48, chip, handle_level_irq); - octeon_irq_set_ciu_mapping(OCTEON_IRQ_PEM1, 1, 49, chip, handle_level_irq); - octeon_irq_set_ciu_mapping(OCTEON_IRQ_SRIO0, 1, 50, chip, handle_level_irq); - octeon_irq_set_ciu_mapping(OCTEON_IRQ_SRIO1, 1, 51, chip, handle_level_irq); - octeon_irq_set_ciu_mapping(OCTEON_IRQ_LMC0, 1, 52, chip, handle_level_irq); - octeon_irq_set_ciu_mapping(OCTEON_IRQ_DFM, 1, 56, chip, handle_level_irq); - octeon_irq_set_ciu_mapping(OCTEON_IRQ_RST, 1, 63, chip, handle_level_irq); - - /* Enable the CIU lines */ - set_c0_status(STATUSF_IP3 | STATUSF_IP2); - clear_c0_status(STATUSF_IP4); -} +static void (*octeon_ciu0_ack)(unsigned int); +static void (*octeon_ciu1_ack)(unsigned int); void __init arch_init_irq(void) { + unsigned int irq; + struct irq_chip *chip0; + struct irq_chip *chip0_mbox; + struct irq_chip *chip1; + struct irq_chip *chip1_wd; + #ifdef CONFIG_SMP /* Set the default affinity to the boot cpu. */ cpumask_clear(irq_default_affinity); cpumask_set_cpu(smp_processor_id(), irq_default_affinity); #endif - octeon_irq_init_ciu(); + + if (NR_IRQS < OCTEON_IRQ_LAST) + pr_err("octeon_irq_init: NR_IRQS is set too low\n"); + + if (OCTEON_IS_MODEL(OCTEON_CN58XX_PASS2_X) || + OCTEON_IS_MODEL(OCTEON_CN56XX_PASS2_X) || + OCTEON_IS_MODEL(OCTEON_CN52XX_PASS2_X)) { + octeon_ciu0_ack = octeon_irq_ciu0_ack_v2; + octeon_ciu1_ack = octeon_irq_ciu1_ack_v2; + chip0 = &octeon_irq_chip_ciu0_v2; + chip0_mbox = &octeon_irq_chip_ciu0_mbox_v2; + chip1 = &octeon_irq_chip_ciu1_v2; + chip1_wd = &octeon_irq_chip_ciu1_wd_v2; + } else { + octeon_ciu0_ack = octeon_irq_ciu0_ack; + octeon_ciu1_ack = octeon_irq_ciu1_ack; + chip0 = &octeon_irq_chip_ciu0; + chip0_mbox = &octeon_irq_chip_ciu0_mbox; + chip1 = &octeon_irq_chip_ciu1; + chip1_wd = &octeon_irq_chip_ciu1_wd; + } + + /* 0 - 15 reserved for i8259 master and slave controller. */ + + /* 17 - 23 Mips internal */ + for (irq = OCTEON_IRQ_SW0; irq <= OCTEON_IRQ_TIMER; irq++) { + set_irq_chip_and_handler(irq, &octeon_irq_chip_core, + handle_percpu_irq); + } + + /* 24 - 87 CIU_INT_SUM0 */ + for (irq = OCTEON_IRQ_WORKQ0; irq <= OCTEON_IRQ_BOOTDMA; irq++) { + switch (irq) { + case OCTEON_IRQ_MBOX0: + case OCTEON_IRQ_MBOX1: + set_irq_chip_and_handler(irq, chip0_mbox, handle_percpu_irq); + break; + default: + set_irq_chip_and_handler(irq, chip0, handle_fasteoi_irq); + break; + } + } + + /* 88 - 151 CIU_INT_SUM1 */ + for (irq = OCTEON_IRQ_WDOG0; irq <= OCTEON_IRQ_WDOG15; irq++) + set_irq_chip_and_handler(irq, chip1_wd, handle_fasteoi_irq); + + for (irq = OCTEON_IRQ_UART2; irq <= OCTEON_IRQ_RESERVED151; irq++) + set_irq_chip_and_handler(irq, chip1, handle_fasteoi_irq); + + set_c0_status(0x300 << 2); } asmlinkage void plat_irq_dispatch(void) { + const unsigned long core_id = cvmx_get_core_num(); + const uint64_t ciu_sum0_address = CVMX_CIU_INTX_SUM0(core_id * 2); + const uint64_t ciu_en0_address = CVMX_CIU_INTX_EN0(core_id * 2); + const uint64_t ciu_sum1_address = CVMX_CIU_INT_SUM1; + const uint64_t ciu_en1_address = CVMX_CIU_INTX_EN1(core_id * 2 + 1); unsigned long cop0_cause; unsigned long cop0_status; + uint64_t ciu_en; + uint64_t ciu_sum; + unsigned int irq; while (1) { cop0_cause = read_c0_cause(); @@ -1021,16 +757,33 @@ asmlinkage void plat_irq_dispatch(void) cop0_cause &= cop0_status; cop0_cause &= ST0_IM; - if (unlikely(cop0_cause & STATUSF_IP2)) - octeon_irq_ip2(); - else if (unlikely(cop0_cause & STATUSF_IP3)) - octeon_irq_ip3(); - else if (unlikely(cop0_cause & STATUSF_IP4)) - octeon_irq_ip4(); - else if (likely(cop0_cause)) + if (unlikely(cop0_cause & STATUSF_IP2)) { + ciu_sum = cvmx_read_csr(ciu_sum0_address); + ciu_en = cvmx_read_csr(ciu_en0_address); + ciu_sum &= ciu_en; + if (likely(ciu_sum)) { + irq = fls64(ciu_sum) + OCTEON_IRQ_WORKQ0 - 1; + octeon_ciu0_ack(irq); + do_IRQ(irq); + } else { + spurious_interrupt(); + } + } else if (unlikely(cop0_cause & STATUSF_IP3)) { + ciu_sum = cvmx_read_csr(ciu_sum1_address); + ciu_en = cvmx_read_csr(ciu_en1_address); + ciu_sum &= ciu_en; + if (likely(ciu_sum)) { + irq = fls64(ciu_sum) + OCTEON_IRQ_WDOG0 - 1; + octeon_ciu1_ack(irq); + do_IRQ(irq); + } else { + spurious_interrupt(); + } + } else if (likely(cop0_cause)) { do_IRQ(fls(cop0_cause) - 9 + MIPS_CPU_IRQ_BASE); - else + } else { break; + } } } @@ -1038,7 +791,83 @@ asmlinkage void plat_irq_dispatch(void) void fixup_irqs(void) { - irq_cpu_offline(); + int irq; + struct irq_desc *desc; + cpumask_t new_affinity; + unsigned long flags; + int do_set_affinity; + int cpu; + + cpu = smp_processor_id(); + + for (irq = OCTEON_IRQ_SW0; irq <= OCTEON_IRQ_TIMER; irq++) + octeon_irq_core_disable_local(irq); + + for (irq = OCTEON_IRQ_WORKQ0; irq < OCTEON_IRQ_LAST; irq++) { + desc = irq_to_desc(irq); + switch (irq) { + case OCTEON_IRQ_MBOX0: + case OCTEON_IRQ_MBOX1: + /* The eoi function will disable them on this CPU. */ + desc->chip->eoi(irq); + break; + case OCTEON_IRQ_WDOG0: + case OCTEON_IRQ_WDOG1: + case OCTEON_IRQ_WDOG2: + case OCTEON_IRQ_WDOG3: + case OCTEON_IRQ_WDOG4: + case OCTEON_IRQ_WDOG5: + case OCTEON_IRQ_WDOG6: + case OCTEON_IRQ_WDOG7: + case OCTEON_IRQ_WDOG8: + case OCTEON_IRQ_WDOG9: + case OCTEON_IRQ_WDOG10: + case OCTEON_IRQ_WDOG11: + case OCTEON_IRQ_WDOG12: + case OCTEON_IRQ_WDOG13: + case OCTEON_IRQ_WDOG14: + case OCTEON_IRQ_WDOG15: + /* + * These have special per CPU semantics and + * are handled in the watchdog driver. + */ + break; + default: + raw_spin_lock_irqsave(&desc->lock, flags); + /* + * If this irq has an action, it is in use and + * must be migrated if it has affinity to this + * cpu. + */ + if (desc->action && cpumask_test_cpu(cpu, desc->affinity)) { + if (cpumask_weight(desc->affinity) > 1) { + /* + * It has multi CPU affinity, + * just remove this CPU from + * the affinity set. + */ + cpumask_copy(&new_affinity, desc->affinity); + cpumask_clear_cpu(cpu, &new_affinity); + } else { + /* + * Otherwise, put it on lowest + * numbered online CPU. + */ + cpumask_clear(&new_affinity); + cpumask_set_cpu(cpumask_first(cpu_online_mask), &new_affinity); + } + do_set_affinity = 1; + } else { + do_set_affinity = 0; + } + raw_spin_unlock_irqrestore(&desc->lock, flags); + + if (do_set_affinity) + irq_set_affinity(irq, &new_affinity); + + break; + } + } } #endif /* CONFIG_HOTPLUG_CPU */ diff --git a/trunk/arch/mips/cavium-octeon/setup.c b/trunk/arch/mips/cavium-octeon/setup.c index 8b139bf4a1b5..b0c3686c96dd 100644 --- a/trunk/arch/mips/cavium-octeon/setup.c +++ b/trunk/arch/mips/cavium-octeon/setup.c @@ -420,6 +420,7 @@ void octeon_user_io_init(void) void __init prom_init(void) { struct cvmx_sysinfo *sysinfo; + const int coreid = cvmx_get_core_num(); int i; int argc; #ifdef CONFIG_CAVIUM_RESERVE32 @@ -536,6 +537,17 @@ void __init prom_init(void) octeon_uart = octeon_get_boot_uart(); + /* + * Disable All CIU Interrupts. The ones we need will be + * enabled later. Read the SUM register so we know the write + * completed. + */ + cvmx_write_csr(CVMX_CIU_INTX_EN0((coreid * 2)), 0); + cvmx_write_csr(CVMX_CIU_INTX_EN0((coreid * 2 + 1)), 0); + cvmx_write_csr(CVMX_CIU_INTX_EN1((coreid * 2)), 0); + cvmx_write_csr(CVMX_CIU_INTX_EN1((coreid * 2 + 1)), 0); + cvmx_read_csr(CVMX_CIU_INTX_SUM0((coreid * 2))); + #ifdef CONFIG_SMP octeon_write_lcd("LinuxSMP"); #else diff --git a/trunk/arch/mips/cavium-octeon/smp.c b/trunk/arch/mips/cavium-octeon/smp.c index ba78b21cc8d0..391cefe556b3 100644 --- a/trunk/arch/mips/cavium-octeon/smp.c +++ b/trunk/arch/mips/cavium-octeon/smp.c @@ -171,19 +171,41 @@ static void octeon_boot_secondary(int cpu, struct task_struct *idle) * After we've done initial boot, this function is called to allow the * board code to clean up state, if needed */ -static void __cpuinit octeon_init_secondary(void) +static void octeon_init_secondary(void) { + const int coreid = cvmx_get_core_num(); + union cvmx_ciu_intx_sum0 interrupt_enable; unsigned int sr; +#ifdef CONFIG_HOTPLUG_CPU + struct linux_app_boot_info *labi; + + labi = (struct linux_app_boot_info *)PHYS_TO_XKSEG_CACHED(LABI_ADDR_IN_BOOTLOADER); + + if (labi->labi_signature != LABI_SIGNATURE) + panic("The bootloader version on this board is incorrect."); +#endif + sr = set_c0_status(ST0_BEV); write_c0_ebase((u32)ebase); write_c0_status(sr); octeon_check_cpu_bist(); octeon_init_cvmcount(); - - octeon_irq_setup_secondary(); - raw_local_irq_enable(); + /* + pr_info("SMP: CPU%d (CoreId %lu) started\n", cpu, coreid); + */ + /* Enable Mailbox interrupts to this core. These are the only + interrupts allowed on line 3 */ + cvmx_write_csr(CVMX_CIU_MBOX_CLRX(coreid), 0xffffffff); + interrupt_enable.u64 = 0; + interrupt_enable.s.mbox = 0x3; + cvmx_write_csr(CVMX_CIU_INTX_EN0((coreid * 2)), interrupt_enable.u64); + cvmx_write_csr(CVMX_CIU_INTX_EN0((coreid * 2 + 1)), 0); + cvmx_write_csr(CVMX_CIU_INTX_EN1((coreid * 2)), 0); + cvmx_write_csr(CVMX_CIU_INTX_EN1((coreid * 2 + 1)), 0); + /* Enable core interrupt processing for 2,3 and 7 */ + set_c0_status(0x8c01); } /** @@ -192,15 +214,6 @@ static void __cpuinit octeon_init_secondary(void) */ void octeon_prepare_cpus(unsigned int max_cpus) { -#ifdef CONFIG_HOTPLUG_CPU - struct linux_app_boot_info *labi; - - labi = (struct linux_app_boot_info *)PHYS_TO_XKSEG_CACHED(LABI_ADDR_IN_BOOTLOADER); - - if (labi->labi_signature != LABI_SIGNATURE) - panic("The bootloader version on this board is incorrect."); -#endif - cvmx_write_csr(CVMX_CIU_MBOX_CLRX(cvmx_get_core_num()), 0xffffffff); if (request_irq(OCTEON_IRQ_MBOX0, mailbox_interrupt, IRQF_DISABLED, "mailbox0", mailbox_interrupt)) { diff --git a/trunk/arch/mips/dec/ioasic-irq.c b/trunk/arch/mips/dec/ioasic-irq.c index 824e08c73798..8d9a5fc607e4 100644 --- a/trunk/arch/mips/dec/ioasic-irq.c +++ b/trunk/arch/mips/dec/ioasic-irq.c @@ -68,10 +68,10 @@ void __init init_ioasic_irqs(int base) fast_iob(); for (i = base; i < base + IO_INR_DMA; i++) - irq_set_chip_and_handler(i, &ioasic_irq_type, + set_irq_chip_and_handler(i, &ioasic_irq_type, handle_level_irq); for (; i < base + IO_IRQ_LINES; i++) - irq_set_chip(i, &ioasic_dma_irq_type); + set_irq_chip(i, &ioasic_dma_irq_type); ioasic_irq_base = base; } diff --git a/trunk/arch/mips/dec/kn02-irq.c b/trunk/arch/mips/dec/kn02-irq.c index 37199f742c45..ef31d98c4fb8 100644 --- a/trunk/arch/mips/dec/kn02-irq.c +++ b/trunk/arch/mips/dec/kn02-irq.c @@ -73,7 +73,7 @@ void __init init_kn02_irqs(int base) iob(); for (i = base; i < base + KN02_IRQ_LINES; i++) - irq_set_chip_and_handler(i, &kn02_irq_type, handle_level_irq); + set_irq_chip_and_handler(i, &kn02_irq_type, handle_level_irq); kn02_irq_base = base; } diff --git a/trunk/arch/mips/emma/markeins/irq.c b/trunk/arch/mips/emma/markeins/irq.c index 3dbd7a5a6ad3..9b1207ae2256 100644 --- a/trunk/arch/mips/emma/markeins/irq.c +++ b/trunk/arch/mips/emma/markeins/irq.c @@ -69,7 +69,7 @@ void emma2rh_irq_init(void) u32 i; for (i = 0; i < NUM_EMMA2RH_IRQ; i++) - irq_set_chip_and_handler_name(EMMA2RH_IRQ_BASE + i, + set_irq_chip_and_handler_name(EMMA2RH_IRQ_BASE + i, &emma2rh_irq_controller, handle_level_irq, "level"); } @@ -105,7 +105,7 @@ void emma2rh_sw_irq_init(void) u32 i; for (i = 0; i < NUM_EMMA2RH_IRQ_SW; i++) - irq_set_chip_and_handler_name(EMMA2RH_SW_IRQ_BASE + i, + set_irq_chip_and_handler_name(EMMA2RH_SW_IRQ_BASE + i, &emma2rh_sw_irq_controller, handle_level_irq, "level"); } @@ -162,7 +162,7 @@ void emma2rh_gpio_irq_init(void) u32 i; for (i = 0; i < NUM_EMMA2RH_IRQ_GPIO; i++) - irq_set_chip_and_handler_name(EMMA2RH_GPIO_IRQ_BASE + i, + set_irq_chip_and_handler_name(EMMA2RH_GPIO_IRQ_BASE + i, &emma2rh_gpio_irq_controller, handle_edge_irq, "edge"); } diff --git a/trunk/arch/mips/include/asm/mach-cavium-octeon/irq.h b/trunk/arch/mips/include/asm/mach-cavium-octeon/irq.h index 5b05f186e395..6ddab8aef644 100644 --- a/trunk/arch/mips/include/asm/mach-cavium-octeon/irq.h +++ b/trunk/arch/mips/include/asm/mach-cavium-octeon/irq.h @@ -11,91 +11,172 @@ #define NR_IRQS OCTEON_IRQ_LAST #define MIPS_CPU_IRQ_BASE OCTEON_IRQ_SW0 -enum octeon_irq { -/* 1 - 8 represent the 8 MIPS standard interrupt sources */ - OCTEON_IRQ_SW0 = 1, - OCTEON_IRQ_SW1, -/* CIU0, CUI2, CIU4 are 3, 4, 5 */ - OCTEON_IRQ_5 = 6, - OCTEON_IRQ_PERF, - OCTEON_IRQ_TIMER, -/* sources in CIU_INTX_EN0 */ - OCTEON_IRQ_WORKQ0, - OCTEON_IRQ_GPIO0 = OCTEON_IRQ_WORKQ0 + 16, - OCTEON_IRQ_WDOG0 = OCTEON_IRQ_GPIO0 + 16, - OCTEON_IRQ_WDOG15 = OCTEON_IRQ_WDOG0 + 15, - OCTEON_IRQ_MBOX0 = OCTEON_IRQ_WDOG0 + 16, - OCTEON_IRQ_MBOX1, - OCTEON_IRQ_UART0, - OCTEON_IRQ_UART1, - OCTEON_IRQ_UART2, - OCTEON_IRQ_PCI_INT0, - OCTEON_IRQ_PCI_INT1, - OCTEON_IRQ_PCI_INT2, - OCTEON_IRQ_PCI_INT3, - OCTEON_IRQ_PCI_MSI0, - OCTEON_IRQ_PCI_MSI1, - OCTEON_IRQ_PCI_MSI2, - OCTEON_IRQ_PCI_MSI3, - - OCTEON_IRQ_TWSI, - OCTEON_IRQ_TWSI2, - OCTEON_IRQ_RML, - OCTEON_IRQ_TRACE0, - OCTEON_IRQ_GMX_DRP0 = OCTEON_IRQ_TRACE0 + 4, - OCTEON_IRQ_IPD_DRP = OCTEON_IRQ_GMX_DRP0 + 5, - OCTEON_IRQ_KEY_ZERO, - OCTEON_IRQ_TIMER0, - OCTEON_IRQ_TIMER1, - OCTEON_IRQ_TIMER2, - OCTEON_IRQ_TIMER3, - OCTEON_IRQ_USB0, - OCTEON_IRQ_USB1, - OCTEON_IRQ_PCM, - OCTEON_IRQ_MPI, - OCTEON_IRQ_POWIQ, - OCTEON_IRQ_IPDPPTHR, - OCTEON_IRQ_MII0, - OCTEON_IRQ_MII1, - OCTEON_IRQ_BOOTDMA, - - OCTEON_IRQ_NAND, - OCTEON_IRQ_MIO, /* Summary of MIO_BOOT_ERR */ - OCTEON_IRQ_IOB, /* Summary of IOB_INT_SUM */ - OCTEON_IRQ_FPA, /* Summary of FPA_INT_SUM */ - OCTEON_IRQ_POW, /* Summary of POW_ECC_ERR */ - OCTEON_IRQ_L2C, /* Summary of L2C_INT_STAT */ - OCTEON_IRQ_IPD, /* Summary of IPD_INT_SUM */ - OCTEON_IRQ_PIP, /* Summary of PIP_INT_REG */ - OCTEON_IRQ_PKO, /* Summary of PKO_REG_ERROR */ - OCTEON_IRQ_ZIP, /* Summary of ZIP_ERROR */ - OCTEON_IRQ_TIM, /* Summary of TIM_REG_ERROR */ - OCTEON_IRQ_RAD, /* Summary of RAD_REG_ERROR */ - OCTEON_IRQ_KEY, /* Summary of KEY_INT_SUM */ - OCTEON_IRQ_DFA, /* Summary of DFA */ - OCTEON_IRQ_USBCTL, /* Summary of USBN0_INT_SUM */ - OCTEON_IRQ_SLI, /* Summary of SLI_INT_SUM */ - OCTEON_IRQ_DPI, /* Summary of DPI_INT_SUM */ - OCTEON_IRQ_AGX0, /* Summary of GMX0*+PCS0_INT*_REG */ - OCTEON_IRQ_AGL = OCTEON_IRQ_AGX0 + 5, - OCTEON_IRQ_PTP, - OCTEON_IRQ_PEM0, - OCTEON_IRQ_PEM1, - OCTEON_IRQ_SRIO0, - OCTEON_IRQ_SRIO1, - OCTEON_IRQ_LMC0, - OCTEON_IRQ_DFM = OCTEON_IRQ_LMC0 + 4, /* Summary of DFM */ - OCTEON_IRQ_RST, -}; +/* 0 - 7 represent the i8259 master */ +#define OCTEON_IRQ_I8259M0 0 +#define OCTEON_IRQ_I8259M1 1 +#define OCTEON_IRQ_I8259M2 2 +#define OCTEON_IRQ_I8259M3 3 +#define OCTEON_IRQ_I8259M4 4 +#define OCTEON_IRQ_I8259M5 5 +#define OCTEON_IRQ_I8259M6 6 +#define OCTEON_IRQ_I8259M7 7 +/* 8 - 15 represent the i8259 slave */ +#define OCTEON_IRQ_I8259S0 8 +#define OCTEON_IRQ_I8259S1 9 +#define OCTEON_IRQ_I8259S2 10 +#define OCTEON_IRQ_I8259S3 11 +#define OCTEON_IRQ_I8259S4 12 +#define OCTEON_IRQ_I8259S5 13 +#define OCTEON_IRQ_I8259S6 14 +#define OCTEON_IRQ_I8259S7 15 +/* 16 - 23 represent the 8 MIPS standard interrupt sources */ +#define OCTEON_IRQ_SW0 16 +#define OCTEON_IRQ_SW1 17 +#define OCTEON_IRQ_CIU0 18 +#define OCTEON_IRQ_CIU1 19 +#define OCTEON_IRQ_CIU4 20 +#define OCTEON_IRQ_5 21 +#define OCTEON_IRQ_PERF 22 +#define OCTEON_IRQ_TIMER 23 +/* 24 - 87 represent the sources in CIU_INTX_EN0 */ +#define OCTEON_IRQ_WORKQ0 24 +#define OCTEON_IRQ_WORKQ1 25 +#define OCTEON_IRQ_WORKQ2 26 +#define OCTEON_IRQ_WORKQ3 27 +#define OCTEON_IRQ_WORKQ4 28 +#define OCTEON_IRQ_WORKQ5 29 +#define OCTEON_IRQ_WORKQ6 30 +#define OCTEON_IRQ_WORKQ7 31 +#define OCTEON_IRQ_WORKQ8 32 +#define OCTEON_IRQ_WORKQ9 33 +#define OCTEON_IRQ_WORKQ10 34 +#define OCTEON_IRQ_WORKQ11 35 +#define OCTEON_IRQ_WORKQ12 36 +#define OCTEON_IRQ_WORKQ13 37 +#define OCTEON_IRQ_WORKQ14 38 +#define OCTEON_IRQ_WORKQ15 39 +#define OCTEON_IRQ_GPIO0 40 +#define OCTEON_IRQ_GPIO1 41 +#define OCTEON_IRQ_GPIO2 42 +#define OCTEON_IRQ_GPIO3 43 +#define OCTEON_IRQ_GPIO4 44 +#define OCTEON_IRQ_GPIO5 45 +#define OCTEON_IRQ_GPIO6 46 +#define OCTEON_IRQ_GPIO7 47 +#define OCTEON_IRQ_GPIO8 48 +#define OCTEON_IRQ_GPIO9 49 +#define OCTEON_IRQ_GPIO10 50 +#define OCTEON_IRQ_GPIO11 51 +#define OCTEON_IRQ_GPIO12 52 +#define OCTEON_IRQ_GPIO13 53 +#define OCTEON_IRQ_GPIO14 54 +#define OCTEON_IRQ_GPIO15 55 +#define OCTEON_IRQ_MBOX0 56 +#define OCTEON_IRQ_MBOX1 57 +#define OCTEON_IRQ_UART0 58 +#define OCTEON_IRQ_UART1 59 +#define OCTEON_IRQ_PCI_INT0 60 +#define OCTEON_IRQ_PCI_INT1 61 +#define OCTEON_IRQ_PCI_INT2 62 +#define OCTEON_IRQ_PCI_INT3 63 +#define OCTEON_IRQ_PCI_MSI0 64 +#define OCTEON_IRQ_PCI_MSI1 65 +#define OCTEON_IRQ_PCI_MSI2 66 +#define OCTEON_IRQ_PCI_MSI3 67 +#define OCTEON_IRQ_RESERVED68 68 /* Summary of CIU_INT_SUM1 */ +#define OCTEON_IRQ_TWSI 69 +#define OCTEON_IRQ_RML 70 +#define OCTEON_IRQ_TRACE 71 +#define OCTEON_IRQ_GMX_DRP0 72 +#define OCTEON_IRQ_GMX_DRP1 73 +#define OCTEON_IRQ_IPD_DRP 74 +#define OCTEON_IRQ_KEY_ZERO 75 +#define OCTEON_IRQ_TIMER0 76 +#define OCTEON_IRQ_TIMER1 77 +#define OCTEON_IRQ_TIMER2 78 +#define OCTEON_IRQ_TIMER3 79 +#define OCTEON_IRQ_USB0 80 +#define OCTEON_IRQ_PCM 81 +#define OCTEON_IRQ_MPI 82 +#define OCTEON_IRQ_TWSI2 83 +#define OCTEON_IRQ_POWIQ 84 +#define OCTEON_IRQ_IPDPPTHR 85 +#define OCTEON_IRQ_MII0 86 +#define OCTEON_IRQ_BOOTDMA 87 +/* 88 - 151 represent the sources in CIU_INTX_EN1 */ +#define OCTEON_IRQ_WDOG0 88 +#define OCTEON_IRQ_WDOG1 89 +#define OCTEON_IRQ_WDOG2 90 +#define OCTEON_IRQ_WDOG3 91 +#define OCTEON_IRQ_WDOG4 92 +#define OCTEON_IRQ_WDOG5 93 +#define OCTEON_IRQ_WDOG6 94 +#define OCTEON_IRQ_WDOG7 95 +#define OCTEON_IRQ_WDOG8 96 +#define OCTEON_IRQ_WDOG9 97 +#define OCTEON_IRQ_WDOG10 98 +#define OCTEON_IRQ_WDOG11 99 +#define OCTEON_IRQ_WDOG12 100 +#define OCTEON_IRQ_WDOG13 101 +#define OCTEON_IRQ_WDOG14 102 +#define OCTEON_IRQ_WDOG15 103 +#define OCTEON_IRQ_UART2 104 +#define OCTEON_IRQ_USB1 105 +#define OCTEON_IRQ_MII1 106 +#define OCTEON_IRQ_RESERVED107 107 +#define OCTEON_IRQ_RESERVED108 108 +#define OCTEON_IRQ_RESERVED109 109 +#define OCTEON_IRQ_RESERVED110 110 +#define OCTEON_IRQ_RESERVED111 111 +#define OCTEON_IRQ_RESERVED112 112 +#define OCTEON_IRQ_RESERVED113 113 +#define OCTEON_IRQ_RESERVED114 114 +#define OCTEON_IRQ_RESERVED115 115 +#define OCTEON_IRQ_RESERVED116 116 +#define OCTEON_IRQ_RESERVED117 117 +#define OCTEON_IRQ_RESERVED118 118 +#define OCTEON_IRQ_RESERVED119 119 +#define OCTEON_IRQ_RESERVED120 120 +#define OCTEON_IRQ_RESERVED121 121 +#define OCTEON_IRQ_RESERVED122 122 +#define OCTEON_IRQ_RESERVED123 123 +#define OCTEON_IRQ_RESERVED124 124 +#define OCTEON_IRQ_RESERVED125 125 +#define OCTEON_IRQ_RESERVED126 126 +#define OCTEON_IRQ_RESERVED127 127 +#define OCTEON_IRQ_RESERVED128 128 +#define OCTEON_IRQ_RESERVED129 129 +#define OCTEON_IRQ_RESERVED130 130 +#define OCTEON_IRQ_RESERVED131 131 +#define OCTEON_IRQ_RESERVED132 132 +#define OCTEON_IRQ_RESERVED133 133 +#define OCTEON_IRQ_RESERVED134 134 +#define OCTEON_IRQ_RESERVED135 135 +#define OCTEON_IRQ_RESERVED136 136 +#define OCTEON_IRQ_RESERVED137 137 +#define OCTEON_IRQ_RESERVED138 138 +#define OCTEON_IRQ_RESERVED139 139 +#define OCTEON_IRQ_RESERVED140 140 +#define OCTEON_IRQ_RESERVED141 141 +#define OCTEON_IRQ_RESERVED142 142 +#define OCTEON_IRQ_RESERVED143 143 +#define OCTEON_IRQ_RESERVED144 144 +#define OCTEON_IRQ_RESERVED145 145 +#define OCTEON_IRQ_RESERVED146 146 +#define OCTEON_IRQ_RESERVED147 147 +#define OCTEON_IRQ_RESERVED148 148 +#define OCTEON_IRQ_RESERVED149 149 +#define OCTEON_IRQ_RESERVED150 150 +#define OCTEON_IRQ_RESERVED151 151 #ifdef CONFIG_PCI_MSI -/* 152 - 407 represent the MSI interrupts 0-255 */ -#define OCTEON_IRQ_MSI_BIT0 (OCTEON_IRQ_RST + 1) +/* 152 - 215 represent the MSI interrupts 0-63 */ +#define OCTEON_IRQ_MSI_BIT0 152 +#define OCTEON_IRQ_MSI_LAST (OCTEON_IRQ_MSI_BIT0 + 255) -#define OCTEON_IRQ_MSI_LAST (OCTEON_IRQ_MSI_BIT0 + 255) -#define OCTEON_IRQ_LAST (OCTEON_IRQ_MSI_LAST + 1) +#define OCTEON_IRQ_LAST (OCTEON_IRQ_MSI_LAST + 1) #else -#define OCTEON_IRQ_LAST (OCTEON_IRQ_RST + 1) +#define OCTEON_IRQ_LAST 152 #endif #endif diff --git a/trunk/arch/mips/include/asm/octeon/octeon.h b/trunk/arch/mips/include/asm/octeon/octeon.h index f72f768cd3a4..6b34afd0d4e7 100644 --- a/trunk/arch/mips/include/asm/octeon/octeon.h +++ b/trunk/arch/mips/include/asm/octeon/octeon.h @@ -257,6 +257,4 @@ extern struct cvmx_bootinfo *octeon_bootinfo; extern uint64_t octeon_bootloader_entry_addr; -extern void (*octeon_irq_setup_secondary)(void); - #endif /* __ASM_OCTEON_OCTEON_H */ diff --git a/trunk/arch/mips/include/asm/unistd.h b/trunk/arch/mips/include/asm/unistd.h index fa2e37ea2be1..dae22c1d2c82 100644 --- a/trunk/arch/mips/include/asm/unistd.h +++ b/trunk/arch/mips/include/asm/unistd.h @@ -1005,7 +1005,7 @@ #define __NR_name_to_handle_at (__NR_Linux + 303) #define __NR_open_by_handle_at (__NR_Linux + 304) #define __NR_clock_adjtime (__NR_Linux + 305) -#define __NR_syncfs (__NR_Linux + 306) +#define __NR_clock_adjtime (__NR_Linux + 306) /* * Offset of the last N32 flavoured syscall diff --git a/trunk/arch/mips/jazz/irq.c b/trunk/arch/mips/jazz/irq.c index 260df4750949..40f7c6b1e260 100644 --- a/trunk/arch/mips/jazz/irq.c +++ b/trunk/arch/mips/jazz/irq.c @@ -56,7 +56,7 @@ void __init init_r4030_ints(void) int i; for (i = JAZZ_IRQ_START; i <= JAZZ_IRQ_END; i++) - irq_set_chip_and_handler(i, &r4030_irq_type, handle_level_irq); + set_irq_chip_and_handler(i, &r4030_irq_type, handle_level_irq); r4030_write_reg16(JAZZ_IO_IRQ_ENABLE, 0); r4030_read_reg16(JAZZ_IO_IRQ_SOURCE); /* clear pending IRQs */ diff --git a/trunk/arch/mips/jz4740/gpio.c b/trunk/arch/mips/jz4740/gpio.c index 73031f7fc827..bd2fc29b95e0 100644 --- a/trunk/arch/mips/jz4740/gpio.c +++ b/trunk/arch/mips/jz4740/gpio.c @@ -306,7 +306,7 @@ static void jz_gpio_irq_demux_handler(unsigned int irq, struct irq_desc *desc) uint32_t flag; unsigned int gpio_irq; unsigned int gpio_bank; - struct jz_gpio_chip *chip = irq_desc_get_handler_data(desc); + struct jz_gpio_chip *chip = get_irq_desc_data(desc); gpio_bank = JZ4740_IRQ_GPIO0 - irq; @@ -416,7 +416,7 @@ static int jz_gpio_irq_set_wake(struct irq_data *data, unsigned int on) chip->wakeup &= ~IRQ_TO_BIT(data->irq); spin_unlock(&chip->lock); - irq_set_irq_wake(chip->irq, on); + set_irq_wake(chip->irq, on); return 0; } @@ -510,14 +510,14 @@ static int jz4740_gpio_chip_init(struct jz_gpio_chip *chip, unsigned int id) gpiochip_add(&chip->gpio_chip); chip->irq = JZ4740_IRQ_INTC_GPIO(id); - irq_set_handler_data(chip->irq, chip); - irq_set_chained_handler(chip->irq, jz_gpio_irq_demux_handler); + set_irq_data(chip->irq, chip); + set_irq_chained_handler(chip->irq, jz_gpio_irq_demux_handler); for (irq = chip->irq_base; irq < chip->irq_base + chip->gpio_chip.ngpio; ++irq) { irq_set_lockdep_class(irq, &gpio_lock_class); - irq_set_chip_data(irq, chip); - irq_set_chip_and_handler(irq, &jz_gpio_irq_chip, - handle_level_irq); + set_irq_chip_data(irq, chip); + set_irq_chip_and_handler(irq, &jz_gpio_irq_chip, + handle_level_irq); } return 0; diff --git a/trunk/arch/mips/jz4740/irq.c b/trunk/arch/mips/jz4740/irq.c index d82c0c430e03..dcc5593a9389 100644 --- a/trunk/arch/mips/jz4740/irq.c +++ b/trunk/arch/mips/jz4740/irq.c @@ -104,8 +104,8 @@ void __init arch_init_irq(void) writel(0xffffffff, jz_intc_base + JZ_REG_INTC_SET_MASK); for (i = JZ4740_IRQ_BASE; i < JZ4740_IRQ_BASE + 32; i++) { - irq_set_chip_data(i, (void *)IRQ_BIT(i)); - irq_set_chip_and_handler(i, &intc_irq_type, handle_level_irq); + set_irq_chip_data(i, (void *)IRQ_BIT(i)); + set_irq_chip_and_handler(i, &intc_irq_type, handle_level_irq); } setup_irq(2, &jz4740_cascade_action); diff --git a/trunk/arch/mips/kernel/i8259.c b/trunk/arch/mips/kernel/i8259.c index c018696765d4..e221662bb80c 100644 --- a/trunk/arch/mips/kernel/i8259.c +++ b/trunk/arch/mips/kernel/i8259.c @@ -110,7 +110,7 @@ int i8259A_irq_pending(unsigned int irq) void make_8259A_irq(unsigned int irq) { disable_irq_nosync(irq); - irq_set_chip_and_handler(irq, &i8259A_chip, handle_level_irq); + set_irq_chip_and_handler(irq, &i8259A_chip, handle_level_irq); enable_irq(irq); } @@ -336,8 +336,8 @@ void __init init_i8259_irqs(void) init_8259A(0); for (i = I8259A_IRQ_BASE; i < I8259A_IRQ_BASE + 16; i++) { - irq_set_chip_and_handler(i, &i8259A_chip, handle_level_irq); - irq_set_probe(i); + set_irq_chip_and_handler(i, &i8259A_chip, handle_level_irq); + set_irq_probe(i); } setup_irq(I8259A_IRQ_BASE + PIC_CASCADE_IR, &irq2); diff --git a/trunk/arch/mips/kernel/irq-gic.c b/trunk/arch/mips/kernel/irq-gic.c index 0c527f652196..43cd9628251a 100644 --- a/trunk/arch/mips/kernel/irq-gic.c +++ b/trunk/arch/mips/kernel/irq-gic.c @@ -229,7 +229,7 @@ static void __init gic_basic_init(int numintrs, int numvpes, vpe_local_setup(numvpes); for (i = _irqbase; i < (_irqbase + numintrs); i++) - irq_set_chip(i, &gic_irq_controller); + set_irq_chip(i, &gic_irq_controller); } void __init gic_init(unsigned long gic_base_addr, diff --git a/trunk/arch/mips/kernel/irq-gt641xx.c b/trunk/arch/mips/kernel/irq-gt641xx.c index 883fc6cead36..7fd176fa367a 100644 --- a/trunk/arch/mips/kernel/irq-gt641xx.c +++ b/trunk/arch/mips/kernel/irq-gt641xx.c @@ -126,6 +126,6 @@ void __init gt641xx_irq_init(void) * bit31: logical or of bits[25:1]. */ for (i = 1; i < 30; i++) - irq_set_chip_and_handler(GT641XX_IRQ_BASE + i, - >641xx_irq_chip, handle_level_irq); + set_irq_chip_and_handler(GT641XX_IRQ_BASE + i, + >641xx_irq_chip, handle_level_irq); } diff --git a/trunk/arch/mips/kernel/irq-msc01.c b/trunk/arch/mips/kernel/irq-msc01.c index 0c6afeed89d2..fc800cd9947e 100644 --- a/trunk/arch/mips/kernel/irq-msc01.c +++ b/trunk/arch/mips/kernel/irq-msc01.c @@ -137,20 +137,16 @@ void __init init_msc_irqs(unsigned long icubase, unsigned int irqbase, msc_irqma switch (imp->im_type) { case MSC01_IRQ_EDGE: - irq_set_chip_and_handler_name(irqbase + n, - &msc_edgeirq_type, - handle_edge_irq, - "edge"); + set_irq_chip_and_handler_name(irqbase + n, + &msc_edgeirq_type, handle_edge_irq, "edge"); if (cpu_has_veic) MSCIC_WRITE(MSC01_IC_SUP+n*8, MSC01_IC_SUP_EDGE_BIT); else MSCIC_WRITE(MSC01_IC_SUP+n*8, MSC01_IC_SUP_EDGE_BIT | imp->im_lvl); break; case MSC01_IRQ_LEVEL: - irq_set_chip_and_handler_name(irqbase + n, - &msc_levelirq_type, - handle_level_irq, - "level"); + set_irq_chip_and_handler_name(irqbase+n, + &msc_levelirq_type, handle_level_irq, "level"); if (cpu_has_veic) MSCIC_WRITE(MSC01_IC_SUP+n*8, 0); else diff --git a/trunk/arch/mips/kernel/irq-rm7000.c b/trunk/arch/mips/kernel/irq-rm7000.c index a8a8977d5887..fd24fd98b041 100644 --- a/trunk/arch/mips/kernel/irq-rm7000.c +++ b/trunk/arch/mips/kernel/irq-rm7000.c @@ -45,6 +45,6 @@ void __init rm7k_cpu_irq_init(void) clear_c0_intcontrol(0x00000f00); /* Mask all */ for (i = base; i < base + 4; i++) - irq_set_chip_and_handler(i, &rm7k_irq_controller, + set_irq_chip_and_handler(i, &rm7k_irq_controller, handle_percpu_irq); } diff --git a/trunk/arch/mips/kernel/irq-rm9000.c b/trunk/arch/mips/kernel/irq-rm9000.c index 38874a4b9255..ca463ec9bad5 100644 --- a/trunk/arch/mips/kernel/irq-rm9000.c +++ b/trunk/arch/mips/kernel/irq-rm9000.c @@ -98,10 +98,10 @@ void __init rm9k_cpu_irq_init(void) clear_c0_intcontrol(0x0000f000); /* Mask all */ for (i = base; i < base + 4; i++) - irq_set_chip_and_handler(i, &rm9k_irq_controller, + set_irq_chip_and_handler(i, &rm9k_irq_controller, handle_level_irq); rm9000_perfcount_irq = base + 1; - irq_set_chip_and_handler(rm9000_perfcount_irq, &rm9k_perfcounter_irq, + set_irq_chip_and_handler(rm9000_perfcount_irq, &rm9k_perfcounter_irq, handle_percpu_irq); } diff --git a/trunk/arch/mips/kernel/irq.c b/trunk/arch/mips/kernel/irq.c index 9b734d74ae8e..1b68ebe1b458 100644 --- a/trunk/arch/mips/kernel/irq.c +++ b/trunk/arch/mips/kernel/irq.c @@ -102,7 +102,7 @@ void __init init_IRQ(void) #endif for (i = 0; i < NR_IRQS; i++) - irq_set_noprobe(i); + set_irq_noprobe(i); arch_init_irq(); diff --git a/trunk/arch/mips/kernel/irq_cpu.c b/trunk/arch/mips/kernel/irq_cpu.c index 6e71b284f6c9..fd945c56bc33 100644 --- a/trunk/arch/mips/kernel/irq_cpu.c +++ b/trunk/arch/mips/kernel/irq_cpu.c @@ -109,10 +109,10 @@ void __init mips_cpu_irq_init(void) */ if (cpu_has_mipsmt) for (i = irq_base; i < irq_base + 2; i++) - irq_set_chip_and_handler(i, &mips_mt_cpu_irq_controller, + set_irq_chip_and_handler(i, &mips_mt_cpu_irq_controller, handle_percpu_irq); for (i = irq_base + 2; i < irq_base + 8; i++) - irq_set_chip_and_handler(i, &mips_cpu_irq_controller, + set_irq_chip_and_handler(i, &mips_cpu_irq_controller, handle_percpu_irq); } diff --git a/trunk/arch/mips/kernel/irq_txx9.c b/trunk/arch/mips/kernel/irq_txx9.c index b0c55b50218e..526e1581549a 100644 --- a/trunk/arch/mips/kernel/irq_txx9.c +++ b/trunk/arch/mips/kernel/irq_txx9.c @@ -154,8 +154,8 @@ void __init txx9_irq_init(unsigned long baseaddr) for (i = 0; i < TXx9_MAX_IR; i++) { txx9irq[i].level = 4; /* middle level */ txx9irq[i].mode = TXx9_IRCR_LOW; - irq_set_chip_and_handler(TXX9_IRQ_BASE + i, &txx9_irq_chip, - handle_level_irq); + set_irq_chip_and_handler(TXX9_IRQ_BASE + i, + &txx9_irq_chip, handle_level_irq); } /* mask all IRC interrupts */ diff --git a/trunk/arch/mips/kernel/smtc.c b/trunk/arch/mips/kernel/smtc.c index 5a88cc4ccd5a..f7e2c7807d7b 100644 --- a/trunk/arch/mips/kernel/smtc.c +++ b/trunk/arch/mips/kernel/smtc.c @@ -1146,7 +1146,7 @@ static void setup_cross_vpe_interrupts(unsigned int nvpe) setup_irq_smtc(cpu_ipi_irq, &irq_ipi, (0x100 << MIPS_CPU_IPI_IRQ)); - irq_set_handler(cpu_ipi_irq, handle_percpu_irq); + set_irq_handler(cpu_ipi_irq, handle_percpu_irq); } /* diff --git a/trunk/arch/mips/lasat/interrupt.c b/trunk/arch/mips/lasat/interrupt.c index de4c165515d7..670e3e70d198 100644 --- a/trunk/arch/mips/lasat/interrupt.c +++ b/trunk/arch/mips/lasat/interrupt.c @@ -128,7 +128,7 @@ void __init arch_init_irq(void) mips_cpu_irq_init(); for (i = LASAT_IRQ_BASE; i <= LASAT_IRQ_END; i++) - irq_set_chip_and_handler(i, &lasat_irq_type, handle_level_irq); + set_irq_chip_and_handler(i, &lasat_irq_type, handle_level_irq); setup_irq(LASAT_CASCADE_IRQ, &cascade); } diff --git a/trunk/arch/mips/loongson/common/bonito-irq.c b/trunk/arch/mips/loongson/common/bonito-irq.c index f27d7ccca92a..1549361696ad 100644 --- a/trunk/arch/mips/loongson/common/bonito-irq.c +++ b/trunk/arch/mips/loongson/common/bonito-irq.c @@ -44,8 +44,7 @@ void bonito_irq_init(void) u32 i; for (i = LOONGSON_IRQ_BASE; i < LOONGSON_IRQ_BASE + 32; i++) - irq_set_chip_and_handler(i, &bonito_irq_type, - handle_level_irq); + set_irq_chip_and_handler(i, &bonito_irq_type, handle_level_irq); #ifdef CONFIG_CPU_LOONGSON2E setup_irq(LOONGSON_IRQ_BASE + 10, &dma_timeout_irqaction); diff --git a/trunk/arch/mips/mti-malta/malta-int.c b/trunk/arch/mips/mti-malta/malta-int.c index 9027061f0ead..b79b24afe3a2 100644 --- a/trunk/arch/mips/mti-malta/malta-int.c +++ b/trunk/arch/mips/mti-malta/malta-int.c @@ -472,7 +472,7 @@ static void __init fill_ipi_map(void) void __init arch_init_ipiirq(int irq, struct irqaction *action) { setup_irq(irq, action); - irq_set_handler(irq, handle_percpu_irq); + set_irq_handler(irq, handle_percpu_irq); } void __init arch_init_irq(void) diff --git a/trunk/arch/mips/mti-malta/malta-time.c b/trunk/arch/mips/mti-malta/malta-time.c index 1620b83cd13e..3c6f190aa61c 100644 --- a/trunk/arch/mips/mti-malta/malta-time.c +++ b/trunk/arch/mips/mti-malta/malta-time.c @@ -119,7 +119,7 @@ static void __init plat_perf_setup(void) set_vi_handler(cp0_perfcount_irq, mips_perf_dispatch); mips_cpu_perf_irq = MIPS_CPU_IRQ_BASE + cp0_perfcount_irq; #ifdef CONFIG_SMP - irq_set_handler(mips_cpu_perf_irq, handle_percpu_irq); + set_irq_handler(mips_cpu_perf_irq, handle_percpu_irq); #endif } } diff --git a/trunk/arch/mips/pci/msi-octeon.c b/trunk/arch/mips/pci/msi-octeon.c index 5d530f89d872..d8080499872a 100644 --- a/trunk/arch/mips/pci/msi-octeon.c +++ b/trunk/arch/mips/pci/msi-octeon.c @@ -172,7 +172,7 @@ int arch_setup_msi_irq(struct pci_dev *dev, struct msi_desc *desc) pci_write_config_word(dev, desc->msi_attrib.pos + PCI_MSI_FLAGS, control); - irq_set_msi_desc(irq, desc); + set_irq_msi(irq, desc); write_msi_msg(irq, &msg); return 0; } @@ -259,11 +259,11 @@ static DEFINE_RAW_SPINLOCK(octeon_irq_msi_lock); static u64 msi_rcv_reg[4]; static u64 mis_ena_reg[4]; -static void octeon_irq_msi_enable_pcie(struct irq_data *data) +static void octeon_irq_msi_enable_pcie(unsigned int irq) { u64 en; unsigned long flags; - int msi_number = data->irq - OCTEON_IRQ_MSI_BIT0; + int msi_number = irq - OCTEON_IRQ_MSI_BIT0; int irq_index = msi_number >> 6; int irq_bit = msi_number & 0x3f; @@ -275,11 +275,11 @@ static void octeon_irq_msi_enable_pcie(struct irq_data *data) raw_spin_unlock_irqrestore(&octeon_irq_msi_lock, flags); } -static void octeon_irq_msi_disable_pcie(struct irq_data *data) +static void octeon_irq_msi_disable_pcie(unsigned int irq) { u64 en; unsigned long flags; - int msi_number = data->irq - OCTEON_IRQ_MSI_BIT0; + int msi_number = irq - OCTEON_IRQ_MSI_BIT0; int irq_index = msi_number >> 6; int irq_bit = msi_number & 0x3f; @@ -293,11 +293,11 @@ static void octeon_irq_msi_disable_pcie(struct irq_data *data) static struct irq_chip octeon_irq_chip_msi_pcie = { .name = "MSI", - .irq_enable = octeon_irq_msi_enable_pcie, - .irq_disable = octeon_irq_msi_disable_pcie, + .enable = octeon_irq_msi_enable_pcie, + .disable = octeon_irq_msi_disable_pcie, }; -static void octeon_irq_msi_enable_pci(struct irq_data *data) +static void octeon_irq_msi_enable_pci(unsigned int irq) { /* * Octeon PCI doesn't have the ability to mask/unmask MSI @@ -308,15 +308,15 @@ static void octeon_irq_msi_enable_pci(struct irq_data *data) */ } -static void octeon_irq_msi_disable_pci(struct irq_data *data) +static void octeon_irq_msi_disable_pci(unsigned int irq) { /* See comment in enable */ } static struct irq_chip octeon_irq_chip_msi_pci = { .name = "MSI", - .irq_enable = octeon_irq_msi_enable_pci, - .irq_disable = octeon_irq_msi_disable_pci, + .enable = octeon_irq_msi_enable_pci, + .disable = octeon_irq_msi_disable_pci, }; /* @@ -388,7 +388,7 @@ int __init octeon_msi_initialize(void) } for (irq = OCTEON_IRQ_MSI_BIT0; irq <= OCTEON_IRQ_MSI_LAST; irq++) - irq_set_chip_and_handler(irq, msi, handle_simple_irq); + set_irq_chip_and_handler(irq, msi, handle_simple_irq); if (octeon_has_feature(OCTEON_FEATURE_PCIE)) { if (request_irq(OCTEON_IRQ_PCI_MSI0, octeon_msi_interrupt0, diff --git a/trunk/arch/mips/pmc-sierra/msp71xx/msp_irq_cic.c b/trunk/arch/mips/pmc-sierra/msp71xx/msp_irq_cic.c index c4fa2d775d8b..352f29d9226f 100644 --- a/trunk/arch/mips/pmc-sierra/msp71xx/msp_irq_cic.c +++ b/trunk/arch/mips/pmc-sierra/msp71xx/msp_irq_cic.c @@ -182,7 +182,7 @@ void __init msp_cic_irq_init(void) /* initialize all the IRQ descriptors */ for (i = MSP_CIC_INTBASE ; i < MSP_CIC_INTBASE + 32 ; i++) { - irq_set_chip_and_handler(i, &msp_cic_irq_controller, + set_irq_chip_and_handler(i, &msp_cic_irq_controller, handle_level_irq); #ifdef CONFIG_MIPS_MT_SMTC /* Mask of CIC interrupt */ diff --git a/trunk/arch/mips/pmc-sierra/msp71xx/msp_irq_slp.c b/trunk/arch/mips/pmc-sierra/msp71xx/msp_irq_slp.c index 5bbcc47da6b9..8f51e4adc438 100644 --- a/trunk/arch/mips/pmc-sierra/msp71xx/msp_irq_slp.c +++ b/trunk/arch/mips/pmc-sierra/msp71xx/msp_irq_slp.c @@ -77,7 +77,7 @@ void __init msp_slp_irq_init(void) /* initialize all the IRQ descriptors */ for (i = MSP_SLP_INTBASE; i < MSP_PER_INTBASE + 32; i++) - irq_set_chip_and_handler(i, &msp_slp_irq_controller, + set_irq_chip_and_handler(i, &msp_slp_irq_controller, handle_level_irq); } diff --git a/trunk/arch/mips/pmc-sierra/msp71xx/msp_smp.c b/trunk/arch/mips/pmc-sierra/msp71xx/msp_smp.c index bec17901ff03..43a9e26e1c69 100644 --- a/trunk/arch/mips/pmc-sierra/msp71xx/msp_smp.c +++ b/trunk/arch/mips/pmc-sierra/msp71xx/msp_smp.c @@ -64,7 +64,7 @@ static struct irqaction irq_call = { void __init arch_init_ipiirq(int irq, struct irqaction *action) { setup_irq(irq, action); - irq_set_handler(irq, handle_percpu_irq); + set_irq_handler(irq, handle_percpu_irq); } void __init msp_vsmp_int_init(void) diff --git a/trunk/arch/mips/pnx833x/common/interrupts.c b/trunk/arch/mips/pnx833x/common/interrupts.c index adc171c8846f..b226bcb0a2f4 100644 --- a/trunk/arch/mips/pnx833x/common/interrupts.c +++ b/trunk/arch/mips/pnx833x/common/interrupts.c @@ -259,13 +259,11 @@ void __init arch_init_irq(void) /* Set IRQ information in irq_desc */ for (irq = PNX833X_PIC_IRQ_BASE; irq < (PNX833X_PIC_IRQ_BASE + PNX833X_PIC_NUM_IRQ); irq++) { pnx833x_hard_disable_pic_irq(irq); - irq_set_chip_and_handler(irq, &pnx833x_pic_irq_type, - handle_simple_irq); + set_irq_chip_and_handler(irq, &pnx833x_pic_irq_type, handle_simple_irq); } for (irq = PNX833X_GPIO_IRQ_BASE; irq < (PNX833X_GPIO_IRQ_BASE + PNX833X_GPIO_NUM_IRQ); irq++) - irq_set_chip_and_handler(irq, &pnx833x_gpio_irq_type, - handle_simple_irq); + set_irq_chip_and_handler(irq, &pnx833x_gpio_irq_type, handle_simple_irq); /* Set PIC priority limiter register to 0 */ PNX833X_PIC_INT_PRIORITY = 0; diff --git a/trunk/arch/mips/pnx8550/common/int.c b/trunk/arch/mips/pnx8550/common/int.c index 6b93c81779c1..dbdc35c3531d 100644 --- a/trunk/arch/mips/pnx8550/common/int.c +++ b/trunk/arch/mips/pnx8550/common/int.c @@ -183,7 +183,7 @@ void __init arch_init_irq(void) int configPR; for (i = 0; i < PNX8550_INT_CP0_TOTINT; i++) - irq_set_chip_and_handler(i, &level_irq_type, handle_level_irq); + set_irq_chip_and_handler(i, &level_irq_type, handle_level_irq); /* init of GIC/IPC interrupts */ /* should be done before cp0 since cp0 init enables the GIC int */ @@ -206,7 +206,7 @@ void __init arch_init_irq(void) /* mask/priority is still 0 so we will not get any * interrupts until it is unmasked */ - irq_set_chip_and_handler(i, &level_irq_type, handle_level_irq); + set_irq_chip_and_handler(i, &level_irq_type, handle_level_irq); } /* Priority level 0 */ @@ -215,20 +215,20 @@ void __init arch_init_irq(void) /* Set int vector table address */ PNX8550_GIC_VECTOR_0 = PNX8550_GIC_VECTOR_1 = 0; - irq_set_chip_and_handler(MIPS_CPU_GIC_IRQ, &level_irq_type, + set_irq_chip_and_handler(MIPS_CPU_GIC_IRQ, &level_irq_type, handle_level_irq); setup_irq(MIPS_CPU_GIC_IRQ, &gic_action); /* init of Timer interrupts */ for (i = PNX8550_INT_TIMER_MIN; i <= PNX8550_INT_TIMER_MAX; i++) - irq_set_chip_and_handler(i, &level_irq_type, handle_level_irq); + set_irq_chip_and_handler(i, &level_irq_type, handle_level_irq); /* Stop Timer 1-3 */ configPR = read_c0_config7(); configPR |= 0x00000038; write_c0_config7(configPR); - irq_set_chip_and_handler(MIPS_CPU_TIMER_IRQ, &level_irq_type, + set_irq_chip_and_handler(MIPS_CPU_TIMER_IRQ, &level_irq_type, handle_level_irq); setup_irq(MIPS_CPU_TIMER_IRQ, &timer_action); } diff --git a/trunk/arch/mips/powertv/asic/irq_asic.c b/trunk/arch/mips/powertv/asic/irq_asic.c index 7fb97fb0931e..6f1c8ef6a719 100644 --- a/trunk/arch/mips/powertv/asic/irq_asic.c +++ b/trunk/arch/mips/powertv/asic/irq_asic.c @@ -112,5 +112,5 @@ void __init asic_irq_init(void) * Initialize interrupt handlers. */ for (i = 0; i < NR_IRQS; i++) - irq_set_chip_and_handler(i, &asic_irq_chip, handle_level_irq); + set_irq_chip_and_handler(i, &asic_irq_chip, handle_level_irq); } diff --git a/trunk/arch/mips/rb532/irq.c b/trunk/arch/mips/rb532/irq.c index 7c6db74e3fad..b32a768da894 100644 --- a/trunk/arch/mips/rb532/irq.c +++ b/trunk/arch/mips/rb532/irq.c @@ -207,8 +207,8 @@ void __init arch_init_irq(void) pr_info("Initializing IRQ's: %d out of %d\n", RC32434_NR_IRQS, NR_IRQS); for (i = 0; i < RC32434_NR_IRQS; i++) - irq_set_chip_and_handler(i, &rc32434_irq_type, - handle_level_irq); + set_irq_chip_and_handler(i, &rc32434_irq_type, + handle_level_irq); } /* Main Interrupt dispatcher */ diff --git a/trunk/arch/mips/sgi-ip22/ip22-int.c b/trunk/arch/mips/sgi-ip22/ip22-int.c index 476423a01296..e6e64750e90a 100644 --- a/trunk/arch/mips/sgi-ip22/ip22-int.c +++ b/trunk/arch/mips/sgi-ip22/ip22-int.c @@ -312,7 +312,7 @@ void __init arch_init_irq(void) else handler = &ip22_local3_irq_type; - irq_set_chip_and_handler(i, handler, handle_level_irq); + set_irq_chip_and_handler(i, handler, handle_level_irq); } /* vector handler. this register the IRQ as non-sharable */ diff --git a/trunk/arch/mips/sgi-ip27/ip27-irq.c b/trunk/arch/mips/sgi-ip27/ip27-irq.c index 11488719dd97..f2d09d7700dd 100644 --- a/trunk/arch/mips/sgi-ip27/ip27-irq.c +++ b/trunk/arch/mips/sgi-ip27/ip27-irq.c @@ -337,7 +337,7 @@ static struct irq_chip bridge_irq_type = { void __devinit register_bridge_irq(unsigned int irq) { - irq_set_chip_and_handler(irq, &bridge_irq_type, handle_level_irq); + set_irq_chip_and_handler(irq, &bridge_irq_type, handle_level_irq); } int __devinit request_bridge_irq(struct bridge_controller *bc) diff --git a/trunk/arch/mips/sgi-ip27/ip27-timer.c b/trunk/arch/mips/sgi-ip27/ip27-timer.c index a152538d3c97..c01f558a2a09 100644 --- a/trunk/arch/mips/sgi-ip27/ip27-timer.c +++ b/trunk/arch/mips/sgi-ip27/ip27-timer.c @@ -153,7 +153,7 @@ static void __init hub_rt_clock_event_global_init(void) panic("Allocation of irq number for timer failed"); } while (xchg(&rt_timer_irq, irq)); - irq_set_chip_and_handler(irq, &rt_irq_type, handle_percpu_irq); + set_irq_chip_and_handler(irq, &rt_irq_type, handle_percpu_irq); setup_irq(irq, &hub_rt_irqaction); } diff --git a/trunk/arch/mips/sgi-ip32/ip32-irq.c b/trunk/arch/mips/sgi-ip32/ip32-irq.c index c65ea76d56c7..e0a3ce4a8d48 100644 --- a/trunk/arch/mips/sgi-ip32/ip32-irq.c +++ b/trunk/arch/mips/sgi-ip32/ip32-irq.c @@ -451,51 +451,43 @@ void __init arch_init_irq(void) for (irq = CRIME_IRQ_BASE; irq <= IP32_IRQ_MAX; irq++) { switch (irq) { case MACE_VID_IN1_IRQ ... MACE_PCI_BRIDGE_IRQ: - irq_set_chip_and_handler_name(irq, - &ip32_mace_interrupt, - handle_level_irq, - "level"); + set_irq_chip_and_handler_name(irq,&ip32_mace_interrupt, + handle_level_irq, "level"); break; case MACEPCI_SCSI0_IRQ ... MACEPCI_SHARED2_IRQ: - irq_set_chip_and_handler_name(irq, - &ip32_macepci_interrupt, - handle_level_irq, - "level"); + set_irq_chip_and_handler_name(irq, + &ip32_macepci_interrupt, handle_level_irq, + "level"); break; case CRIME_CPUERR_IRQ: case CRIME_MEMERR_IRQ: - irq_set_chip_and_handler_name(irq, - &crime_level_interrupt, - handle_level_irq, - "level"); + set_irq_chip_and_handler_name(irq, + &crime_level_interrupt, handle_level_irq, + "level"); break; case CRIME_GBE0_IRQ ... CRIME_GBE3_IRQ: case CRIME_RE_EMPTY_E_IRQ ... CRIME_RE_IDLE_E_IRQ: case CRIME_SOFT0_IRQ ... CRIME_SOFT2_IRQ: case CRIME_VICE_IRQ: - irq_set_chip_and_handler_name(irq, - &crime_edge_interrupt, - handle_edge_irq, - "edge"); + set_irq_chip_and_handler_name(irq, + &crime_edge_interrupt, handle_edge_irq, "edge"); break; case MACEISA_PARALLEL_IRQ: case MACEISA_SERIAL1_TDMAPR_IRQ: case MACEISA_SERIAL2_TDMAPR_IRQ: - irq_set_chip_and_handler_name(irq, - &ip32_maceisa_edge_interrupt, - handle_edge_irq, - "edge"); + set_irq_chip_and_handler_name(irq, + &ip32_maceisa_edge_interrupt, handle_edge_irq, + "edge"); break; default: - irq_set_chip_and_handler_name(irq, - &ip32_maceisa_level_interrupt, - handle_level_irq, - "level"); + set_irq_chip_and_handler_name(irq, + &ip32_maceisa_level_interrupt, handle_level_irq, + "level"); break; } } diff --git a/trunk/arch/mips/sibyte/bcm1480/irq.c b/trunk/arch/mips/sibyte/bcm1480/irq.c index 09740d60e187..89e8188a4665 100644 --- a/trunk/arch/mips/sibyte/bcm1480/irq.c +++ b/trunk/arch/mips/sibyte/bcm1480/irq.c @@ -216,8 +216,7 @@ void __init init_bcm1480_irqs(void) int i; for (i = 0; i < BCM1480_NR_IRQS; i++) { - irq_set_chip_and_handler(i, &bcm1480_irq_type, - handle_level_irq); + set_irq_chip_and_handler(i, &bcm1480_irq_type, handle_level_irq); bcm1480_irq_owner[i] = 0; } } diff --git a/trunk/arch/mips/sibyte/sb1250/irq.c b/trunk/arch/mips/sibyte/sb1250/irq.c index be4460a5f6a8..fd269ea8d8a8 100644 --- a/trunk/arch/mips/sibyte/sb1250/irq.c +++ b/trunk/arch/mips/sibyte/sb1250/irq.c @@ -190,8 +190,7 @@ void __init init_sb1250_irqs(void) int i; for (i = 0; i < SB1250_NR_IRQS; i++) { - irq_set_chip_and_handler(i, &sb1250_irq_type, - handle_level_irq); + set_irq_chip_and_handler(i, &sb1250_irq_type, handle_level_irq); sb1250_irq_owner[i] = 0; } } diff --git a/trunk/arch/mips/sni/a20r.c b/trunk/arch/mips/sni/a20r.c index c48194c3073b..72b94155778d 100644 --- a/trunk/arch/mips/sni/a20r.c +++ b/trunk/arch/mips/sni/a20r.c @@ -209,7 +209,7 @@ void __init sni_a20r_irq_init(void) int i; for (i = SNI_A20R_IRQ_BASE + 2 ; i < SNI_A20R_IRQ_BASE + 8; i++) - irq_set_chip_and_handler(i, &a20r_irq_type, handle_level_irq); + set_irq_chip_and_handler(i, &a20r_irq_type, handle_level_irq); sni_hwint = a20r_hwint; change_c0_status(ST0_IM, IE_IRQ0); setup_irq(SNI_A20R_IRQ_BASE + 3, &sni_isa_irq); diff --git a/trunk/arch/mips/sni/pcimt.c b/trunk/arch/mips/sni/pcimt.c index ed3b3d317358..cfcc68abc5b2 100644 --- a/trunk/arch/mips/sni/pcimt.c +++ b/trunk/arch/mips/sni/pcimt.c @@ -296,7 +296,7 @@ void __init sni_pcimt_irq_init(void) mips_cpu_irq_init(); /* Actually we've got more interrupts to handle ... */ for (i = PCIMT_IRQ_INT2; i <= PCIMT_IRQ_SCSI; i++) - irq_set_chip_and_handler(i, &pcimt_irq_type, handle_level_irq); + set_irq_chip_and_handler(i, &pcimt_irq_type, handle_level_irq); sni_hwint = sni_pcimt_hwint; change_c0_status(ST0_IM, IE_IRQ1|IE_IRQ3); } diff --git a/trunk/arch/mips/sni/pcit.c b/trunk/arch/mips/sni/pcit.c index b5246373d16b..0846e99a6efe 100644 --- a/trunk/arch/mips/sni/pcit.c +++ b/trunk/arch/mips/sni/pcit.c @@ -238,7 +238,7 @@ void __init sni_pcit_irq_init(void) mips_cpu_irq_init(); for (i = SNI_PCIT_INT_START; i <= SNI_PCIT_INT_END; i++) - irq_set_chip_and_handler(i, &pcit_irq_type, handle_level_irq); + set_irq_chip_and_handler(i, &pcit_irq_type, handle_level_irq); *(volatile u32 *)SNI_PCIT_INT_REG = 0; sni_hwint = sni_pcit_hwint; change_c0_status(ST0_IM, IE_IRQ1); @@ -251,7 +251,7 @@ void __init sni_pcit_cplus_irq_init(void) mips_cpu_irq_init(); for (i = SNI_PCIT_INT_START; i <= SNI_PCIT_INT_END; i++) - irq_set_chip_and_handler(i, &pcit_irq_type, handle_level_irq); + set_irq_chip_and_handler(i, &pcit_irq_type, handle_level_irq); *(volatile u32 *)SNI_PCIT_INT_REG = 0x40000000; sni_hwint = sni_pcit_hwint_cplus; change_c0_status(ST0_IM, IE_IRQ0); diff --git a/trunk/arch/mips/sni/rm200.c b/trunk/arch/mips/sni/rm200.c index a7e5a6d917b1..f05d8e593300 100644 --- a/trunk/arch/mips/sni/rm200.c +++ b/trunk/arch/mips/sni/rm200.c @@ -413,7 +413,7 @@ void __init sni_rm200_i8259_irqs(void) sni_rm200_init_8259A(); for (i = RM200_I8259A_IRQ_BASE; i < RM200_I8259A_IRQ_BASE + 16; i++) - irq_set_chip_and_handler(i, &sni_rm200_i8259A_chip, + set_irq_chip_and_handler(i, &sni_rm200_i8259A_chip, handle_level_irq); setup_irq(RM200_I8259A_IRQ_BASE + PIC_CASCADE_IR, &sni_rm200_irq2); @@ -477,7 +477,7 @@ void __init sni_rm200_irq_init(void) mips_cpu_irq_init(); /* Actually we've got more interrupts to handle ... */ for (i = SNI_RM200_INT_START; i <= SNI_RM200_INT_END; i++) - irq_set_chip_and_handler(i, &rm200_irq_type, handle_level_irq); + set_irq_chip_and_handler(i, &rm200_irq_type, handle_level_irq); sni_hwint = sni_rm200_hwint; change_c0_status(ST0_IM, IE_IRQ0); setup_irq(SNI_RM200_INT_START + 0, &sni_rm200_i8259A_irq); diff --git a/trunk/arch/mips/txx9/generic/irq_tx4927.c b/trunk/arch/mips/txx9/generic/irq_tx4927.c index 7e3ac5782da4..e1828e8bcaef 100644 --- a/trunk/arch/mips/txx9/generic/irq_tx4927.c +++ b/trunk/arch/mips/txx9/generic/irq_tx4927.c @@ -35,7 +35,7 @@ void __init tx4927_irq_init(void) mips_cpu_irq_init(); txx9_irq_init(TX4927_IRC_REG & 0xfffffffffULL); - irq_set_chained_handler(MIPS_CPU_IRQ_BASE + TX4927_IRC_INT, + set_irq_chained_handler(MIPS_CPU_IRQ_BASE + TX4927_IRC_INT, handle_simple_irq); /* raise priority for errors, timers, SIO */ txx9_irq_set_pri(TX4927_IR_ECCERR, 7); diff --git a/trunk/arch/mips/txx9/generic/irq_tx4938.c b/trunk/arch/mips/txx9/generic/irq_tx4938.c index aace85653329..a6e6e805097a 100644 --- a/trunk/arch/mips/txx9/generic/irq_tx4938.c +++ b/trunk/arch/mips/txx9/generic/irq_tx4938.c @@ -23,7 +23,7 @@ void __init tx4938_irq_init(void) mips_cpu_irq_init(); txx9_irq_init(TX4938_IRC_REG & 0xfffffffffULL); - irq_set_chained_handler(MIPS_CPU_IRQ_BASE + TX4938_IRC_INT, + set_irq_chained_handler(MIPS_CPU_IRQ_BASE + TX4938_IRC_INT, handle_simple_irq); /* raise priority for errors, timers, SIO */ txx9_irq_set_pri(TX4938_IR_ECCERR, 7); diff --git a/trunk/arch/mips/txx9/generic/irq_tx4939.c b/trunk/arch/mips/txx9/generic/irq_tx4939.c index 6b067dbd2ae1..93b6edbedd64 100644 --- a/trunk/arch/mips/txx9/generic/irq_tx4939.c +++ b/trunk/arch/mips/txx9/generic/irq_tx4939.c @@ -176,8 +176,8 @@ void __init tx4939_irq_init(void) for (i = 1; i < TX4939_NUM_IR; i++) { tx4939irq[i].level = 4; /* middle level */ tx4939irq[i].mode = TXx9_IRCR_LOW; - irq_set_chip_and_handler(TXX9_IRQ_BASE + i, &tx4939_irq_chip, - handle_level_irq); + set_irq_chip_and_handler(TXX9_IRQ_BASE + i, + &tx4939_irq_chip, handle_level_irq); } /* mask all IRC interrupts */ @@ -193,7 +193,7 @@ void __init tx4939_irq_init(void) __raw_writel(TXx9_IRCER_ICE, &tx4939_ircptr->den.r); __raw_writel(irc_elevel, &tx4939_ircptr->msk.r); - irq_set_chained_handler(MIPS_CPU_IRQ_BASE + TX4939_IRC_INT, + set_irq_chained_handler(MIPS_CPU_IRQ_BASE + TX4939_IRC_INT, handle_simple_irq); /* raise priority for errors, timers, sio */ diff --git a/trunk/arch/mips/txx9/jmr3927/irq.c b/trunk/arch/mips/txx9/jmr3927/irq.c index c22c859a2c49..92a5c1b400f0 100644 --- a/trunk/arch/mips/txx9/jmr3927/irq.c +++ b/trunk/arch/mips/txx9/jmr3927/irq.c @@ -120,9 +120,8 @@ void __init jmr3927_irq_setup(void) tx3927_irq_init(); for (i = JMR3927_IRQ_IOC; i < JMR3927_IRQ_IOC + JMR3927_NR_IRQ_IOC; i++) - irq_set_chip_and_handler(i, &jmr3927_irq_ioc, - handle_level_irq); + set_irq_chip_and_handler(i, &jmr3927_irq_ioc, handle_level_irq); /* setup IOC interrupt 1 (PCI, MODEM) */ - irq_set_chained_handler(JMR3927_IRQ_IOCINT, handle_simple_irq); + set_irq_chained_handler(JMR3927_IRQ_IOCINT, handle_simple_irq); } diff --git a/trunk/arch/mips/txx9/rbtx4927/irq.c b/trunk/arch/mips/txx9/rbtx4927/irq.c index 6c22c496090b..7c0a048b307c 100644 --- a/trunk/arch/mips/txx9/rbtx4927/irq.c +++ b/trunk/arch/mips/txx9/rbtx4927/irq.c @@ -164,9 +164,9 @@ static void __init toshiba_rbtx4927_irq_ioc_init(void) for (i = RBTX4927_IRQ_IOC; i < RBTX4927_IRQ_IOC + RBTX4927_NR_IRQ_IOC; i++) - irq_set_chip_and_handler(i, &toshiba_rbtx4927_irq_ioc_type, + set_irq_chip_and_handler(i, &toshiba_rbtx4927_irq_ioc_type, handle_level_irq); - irq_set_chained_handler(RBTX4927_IRQ_IOCINT, handle_simple_irq); + set_irq_chained_handler(RBTX4927_IRQ_IOCINT, handle_simple_irq); } static int rbtx4927_irq_dispatch(int pending) @@ -194,5 +194,5 @@ void __init rbtx4927_irq_setup(void) tx4927_irq_init(); toshiba_rbtx4927_irq_ioc_init(); /* Onboard 10M Ether: High Active */ - irq_set_irq_type(RBTX4927_RTL_8019_IRQ, IRQF_TRIGGER_HIGH); + set_irq_type(RBTX4927_RTL_8019_IRQ, IRQF_TRIGGER_HIGH); } diff --git a/trunk/arch/mips/txx9/rbtx4938/irq.c b/trunk/arch/mips/txx9/rbtx4938/irq.c index 58cd7a9272cc..2ec4fe1b1670 100644 --- a/trunk/arch/mips/txx9/rbtx4938/irq.c +++ b/trunk/arch/mips/txx9/rbtx4938/irq.c @@ -132,10 +132,10 @@ static void __init toshiba_rbtx4938_irq_ioc_init(void) for (i = RBTX4938_IRQ_IOC; i < RBTX4938_IRQ_IOC + RBTX4938_NR_IRQ_IOC; i++) - irq_set_chip_and_handler(i, &toshiba_rbtx4938_irq_ioc_type, + set_irq_chip_and_handler(i, &toshiba_rbtx4938_irq_ioc_type, handle_level_irq); - irq_set_chained_handler(RBTX4938_IRQ_IOCINT, handle_simple_irq); + set_irq_chained_handler(RBTX4938_IRQ_IOCINT, handle_simple_irq); } void __init rbtx4938_irq_setup(void) @@ -153,5 +153,5 @@ void __init rbtx4938_irq_setup(void) tx4938_irq_init(); toshiba_rbtx4938_irq_ioc_init(); /* Onboard 10M Ether: High Active */ - irq_set_irq_type(RBTX4938_IRQ_ETHER, IRQF_TRIGGER_HIGH); + set_irq_type(RBTX4938_IRQ_ETHER, IRQF_TRIGGER_HIGH); } diff --git a/trunk/arch/mips/txx9/rbtx4939/irq.c b/trunk/arch/mips/txx9/rbtx4939/irq.c index 69a80616f0c9..70074632fb99 100644 --- a/trunk/arch/mips/txx9/rbtx4939/irq.c +++ b/trunk/arch/mips/txx9/rbtx4939/irq.c @@ -88,8 +88,8 @@ void __init rbtx4939_irq_setup(void) tx4939_irq_init(); for (i = RBTX4939_IRQ_IOC; i < RBTX4939_IRQ_IOC + RBTX4939_NR_IRQ_IOC; i++) - irq_set_chip_and_handler(i, &rbtx4939_ioc_irq_chip, + set_irq_chip_and_handler(i, &rbtx4939_ioc_irq_chip, handle_level_irq); - irq_set_chained_handler(RBTX4939_IRQ_IOCINT, handle_simple_irq); + set_irq_chained_handler(RBTX4939_IRQ_IOCINT, handle_simple_irq); } diff --git a/trunk/arch/mips/vr41xx/common/icu.c b/trunk/arch/mips/vr41xx/common/icu.c index a39ef3207d71..f53156bb9aa8 100644 --- a/trunk/arch/mips/vr41xx/common/icu.c +++ b/trunk/arch/mips/vr41xx/common/icu.c @@ -710,11 +710,11 @@ static int __init vr41xx_icu_init(void) icu2_write(MGIUINTHREG, 0xffff); for (i = SYSINT1_IRQ_BASE; i <= SYSINT1_IRQ_LAST; i++) - irq_set_chip_and_handler(i, &sysint1_irq_type, + set_irq_chip_and_handler(i, &sysint1_irq_type, handle_level_irq); for (i = SYSINT2_IRQ_BASE; i <= SYSINT2_IRQ_LAST; i++) - irq_set_chip_and_handler(i, &sysint2_irq_type, + set_irq_chip_and_handler(i, &sysint2_irq_type, handle_level_irq); cascade_irq(INT0_IRQ, icu_get_irq); diff --git a/trunk/arch/mips/vr41xx/common/irq.c b/trunk/arch/mips/vr41xx/common/irq.c index 70a3b85f3757..9ff7f397c0e1 100644 --- a/trunk/arch/mips/vr41xx/common/irq.c +++ b/trunk/arch/mips/vr41xx/common/irq.c @@ -87,7 +87,7 @@ static void irq_dispatch(unsigned int irq) atomic_inc(&irq_err_count); else irq_dispatch(irq); - if (!irqd_irq_disabled(idata) && chip->irq_unmask) + if (!(desc->status & IRQ_DISABLED) && chip->irq_unmask) chip->irq_unmask(idata); } else do_IRQ(irq); diff --git a/trunk/arch/mn10300/Kconfig b/trunk/arch/mn10300/Kconfig index a523c94fa698..d8ab97a73db2 100644 --- a/trunk/arch/mn10300/Kconfig +++ b/trunk/arch/mn10300/Kconfig @@ -3,7 +3,6 @@ config MN10300 select HAVE_OPROFILE select HAVE_GENERIC_HARDIRQS select GENERIC_HARDIRQS_NO_DEPRECATED - select GENERIC_IRQ_SHOW select HAVE_ARCH_TRACEHOOK select HAVE_ARCH_KGDB diff --git a/trunk/arch/mn10300/kernel/irq.c b/trunk/arch/mn10300/kernel/irq.c index 86af0d7d0771..5f7fc3eb45e6 100644 --- a/trunk/arch/mn10300/kernel/irq.c +++ b/trunk/arch/mn10300/kernel/irq.c @@ -263,7 +263,7 @@ void set_intr_level(int irq, u16 level) */ void mn10300_set_lateack_irq_type(int irq) { - irq_set_chip_and_handler(irq, &mn10300_cpu_pic_level, + set_irq_chip_and_handler(irq, &mn10300_cpu_pic_level, handle_level_irq); } @@ -275,12 +275,12 @@ void __init init_IRQ(void) int irq; for (irq = 0; irq < NR_IRQS; irq++) - if (irq_get_chip(irq) == &no_irq_chip) + if (get_irq_chip(irq) == &no_irq_chip) /* due to the PIC latching interrupt requests, even * when the IRQ is disabled, IRQ_PENDING is superfluous * and we can use handle_level_irq() for edge-triggered * interrupts */ - irq_set_chip_and_handler(irq, &mn10300_cpu_pic_edge, + set_irq_chip_and_handler(irq, &mn10300_cpu_pic_edge, handle_level_irq); unit_init_IRQ(); @@ -335,42 +335,91 @@ asmlinkage void do_IRQ(void) /* * Display interrupt management information through /proc/interrupts */ -int arch_show_interrupts(struct seq_file *p, int prec) +int show_interrupts(struct seq_file *p, void *v) { -#ifdef CONFIG_MN10300_WD_TIMER - int j; + int i = *(loff_t *) v, j, cpu; + struct irqaction *action; + unsigned long flags; + + switch (i) { + /* display column title bar naming CPUs */ + case 0: + seq_printf(p, " "); + for (j = 0; j < NR_CPUS; j++) + if (cpu_online(j)) + seq_printf(p, "CPU%d ", j); + seq_putc(p, '\n'); + break; + + /* display information rows, one per active CPU */ + case 1 ... NR_IRQS - 1: + raw_spin_lock_irqsave(&irq_desc[i].lock, flags); + + action = irq_desc[i].action; + if (action) { + seq_printf(p, "%3d: ", i); + for_each_present_cpu(cpu) + seq_printf(p, "%10u ", kstat_irqs_cpu(i, cpu)); + + if (i < NR_CPU_IRQS) + seq_printf(p, " %14s.%u", + irq_desc[i].irq_data.chip->name, + (GxICR(i) & GxICR_LEVEL) >> + GxICR_LEVEL_SHIFT); + else + seq_printf(p, " %14s", + irq_desc[i].irq_data.chip->name); + + seq_printf(p, " %s", action->name); + + for (action = action->next; + action; + action = action->next) + seq_printf(p, ", %s", action->name); + + seq_putc(p, '\n'); + } - seq_printf(p, "%*s: ", prec, "NMI"); - for (j = 0; j < NR_CPUS; j++) - if (cpu_online(j)) - seq_printf(p, "%10u ", nmi_count(j)); - seq_putc(p, '\n'); + raw_spin_unlock_irqrestore(&irq_desc[i].lock, flags); + break; + + /* polish off with NMI and error counters */ + case NR_IRQS: +#ifdef CONFIG_MN10300_WD_TIMER + seq_printf(p, "NMI: "); + for (j = 0; j < NR_CPUS; j++) + if (cpu_online(j)) + seq_printf(p, "%10u ", nmi_count(j)); + seq_putc(p, '\n'); #endif - seq_printf(p, "%*s: ", prec, "ERR"); - seq_printf(p, "%10u\n", atomic_read(&irq_err_count)); + seq_printf(p, "ERR: %10u\n", atomic_read(&irq_err_count)); + break; + } + return 0; } #ifdef CONFIG_HOTPLUG_CPU void migrate_irqs(void) { + irq_desc_t *desc; int irq; unsigned int self, new; unsigned long flags; self = smp_processor_id(); for (irq = 0; irq < NR_IRQS; irq++) { - struct irq_data *data = irq_get_irq_data(irq); + desc = irq_desc + irq; - if (irqd_is_per_cpu(data)) + if (desc->status == IRQ_PER_CPU) continue; - if (cpu_isset(self, data->affinity) && + if (cpu_isset(self, irq_desc[irq].affinity) && !cpus_intersects(irq_affinity[irq], cpu_online_map)) { int cpu_id; cpu_id = first_cpu(cpu_online_map); - cpu_set(cpu_id, data->affinity); + cpu_set(cpu_id, irq_desc[irq].affinity); } /* We need to operate irq_affinity_online atomically. */ arch_local_cli_save(flags); @@ -381,7 +430,7 @@ void migrate_irqs(void) GxICR(irq) = x & GxICR_LEVEL; tmp = GxICR(irq); - new = any_online_cpu(data->affinity); + new = any_online_cpu(irq_desc[irq].affinity); irq_affinity_online[irq] = new; CROSS_GxICR(irq, new) = diff --git a/trunk/arch/mn10300/kernel/mn10300-serial.c b/trunk/arch/mn10300/kernel/mn10300-serial.c index 94901c56baf1..efca426a2ed4 100644 --- a/trunk/arch/mn10300/kernel/mn10300-serial.c +++ b/trunk/arch/mn10300/kernel/mn10300-serial.c @@ -933,7 +933,7 @@ static int mn10300_serial_startup(struct uart_port *_port) NUM2GxICR_LEVEL(CONFIG_MN10300_SERIAL_IRQ_LEVEL)); set_intr_level(port->tx_irq, NUM2GxICR_LEVEL(CONFIG_MN10300_SERIAL_IRQ_LEVEL)); - irq_set_chip(port->tm_irq, &mn10300_serial_pic); + set_irq_chip(port->tm_irq, &mn10300_serial_pic); if (request_irq(port->rx_irq, mn10300_serial_interrupt, IRQF_DISABLED, port->rx_name, port) < 0) diff --git a/trunk/arch/mn10300/kernel/smp.c b/trunk/arch/mn10300/kernel/smp.c index 226c826a2194..51c02f97dcea 100644 --- a/trunk/arch/mn10300/kernel/smp.c +++ b/trunk/arch/mn10300/kernel/smp.c @@ -156,15 +156,15 @@ static void init_ipi(void) u16 tmp16; /* set up the reschedule IPI */ - irq_set_chip_and_handler(RESCHEDULE_IPI, &mn10300_ipi_type, - handle_percpu_irq); + set_irq_chip_and_handler(RESCHEDULE_IPI, + &mn10300_ipi_type, handle_percpu_irq); setup_irq(RESCHEDULE_IPI, &reschedule_ipi); set_intr_level(RESCHEDULE_IPI, RESCHEDULE_GxICR_LV); mn10300_ipi_enable(RESCHEDULE_IPI); /* set up the call function IPI */ - irq_set_chip_and_handler(CALL_FUNC_SINGLE_IPI, &mn10300_ipi_type, - handle_percpu_irq); + set_irq_chip_and_handler(CALL_FUNC_SINGLE_IPI, + &mn10300_ipi_type, handle_percpu_irq); setup_irq(CALL_FUNC_SINGLE_IPI, &call_function_ipi); set_intr_level(CALL_FUNC_SINGLE_IPI, CALL_FUNCTION_GxICR_LV); mn10300_ipi_enable(CALL_FUNC_SINGLE_IPI); @@ -172,8 +172,8 @@ static void init_ipi(void) /* set up the local timer IPI */ #if !defined(CONFIG_GENERIC_CLOCKEVENTS) || \ defined(CONFIG_GENERIC_CLOCKEVENTS_BROADCAST) - irq_set_chip_and_handler(LOCAL_TIMER_IPI, &mn10300_ipi_type, - handle_percpu_irq); + set_irq_chip_and_handler(LOCAL_TIMER_IPI, + &mn10300_ipi_type, handle_percpu_irq); setup_irq(LOCAL_TIMER_IPI, &local_timer_ipi); set_intr_level(LOCAL_TIMER_IPI, LOCAL_TIMER_GxICR_LV); mn10300_ipi_enable(LOCAL_TIMER_IPI); diff --git a/trunk/arch/mn10300/unit-asb2364/irq-fpga.c b/trunk/arch/mn10300/unit-asb2364/irq-fpga.c index e16c216f31dc..ee84e62b16ed 100644 --- a/trunk/arch/mn10300/unit-asb2364/irq-fpga.c +++ b/trunk/arch/mn10300/unit-asb2364/irq-fpga.c @@ -100,8 +100,7 @@ void __init irq_fpga_init(void) SyncExBus(); for (irq = NR_CPU_IRQS; irq < NR_IRQS; irq++) - irq_set_chip_and_handler(irq, &asb2364_fpga_pic, - handle_level_irq); + set_irq_chip_and_handler(irq, &asb2364_fpga_pic, handle_level_irq); /* the FPGA drives the XIRQ1 input on the CPU PIC */ setup_irq(XIRQ1, &fpga_irq[0]); diff --git a/trunk/arch/parisc/kernel/irq.c b/trunk/arch/parisc/kernel/irq.c index c0b1affc06a8..cb450e1e79b3 100644 --- a/trunk/arch/parisc/kernel/irq.c +++ b/trunk/arch/parisc/kernel/irq.c @@ -113,8 +113,13 @@ int cpu_check_affinity(struct irq_data *d, const struct cpumask *dest) int cpu_dest; /* timer and ipi have to always be received on all CPUs */ - if (irqd_is_per_cpu(d)) + if (CHECK_IRQ_PER_CPU(irq_to_desc(d->irq)->status)) { + /* Bad linux design decision. The mask has already + * been set; we must reset it. Will fix - tglx + */ + cpumask_setall(d->affinity); return -EINVAL; + } /* whatever mask they set, we just allow one CPU */ cpu_dest = first_cpu(*dest); @@ -169,11 +174,10 @@ int show_interrupts(struct seq_file *p, void *v) } if (i < NR_IRQS) { - struct irq_desc *desc = irq_to_desc(i); struct irqaction *action; - raw_spin_lock_irqsave(&desc->lock, flags); - action = desc->action; + raw_spin_lock_irqsave(&irq_desc[i].lock, flags); + action = irq_desc[i].action; if (!action) goto skip; seq_printf(p, "%3d: ", i); @@ -184,7 +188,7 @@ int show_interrupts(struct seq_file *p, void *v) seq_printf(p, "%10u ", kstat_irqs(i)); #endif - seq_printf(p, " %14s", irq_desc_get_chip(desc)->name); + seq_printf(p, " %14s", irq_desc[i].irq_data.chip->name); #ifndef PARISC_IRQ_CR16_COUNTS seq_printf(p, " %s", action->name); @@ -216,7 +220,7 @@ int show_interrupts(struct seq_file *p, void *v) seq_putc(p, '\n'); skip: - raw_spin_unlock_irqrestore(&desc->lock, flags); + raw_spin_unlock_irqrestore(&irq_desc[i].lock, flags); } return 0; @@ -234,15 +238,15 @@ int show_interrupts(struct seq_file *p, void *v) int cpu_claim_irq(unsigned int irq, struct irq_chip *type, void *data) { - if (irq_has_action(irq)) + if (irq_desc[irq].action) return -EBUSY; - if (irq_get_chip(irq) != &cpu_interrupt_type) + if (get_irq_chip(irq) != &cpu_interrupt_type) return -EBUSY; /* for iosapic interrupts */ if (type) { - irq_set_chip_and_handler(irq, type, handle_percpu_irq); - irq_set_chip_data(irq, data); + set_irq_chip_and_handler(irq, type, handle_percpu_irq); + set_irq_chip_data(irq, data); __cpu_unmask_irq(irq); } return 0; @@ -353,7 +357,7 @@ void do_cpu_irq_mask(struct pt_regs *regs) #ifdef CONFIG_SMP desc = irq_to_desc(irq); cpumask_copy(&dest, desc->irq_data.affinity); - if (irqd_is_per_cpu(&desc->irq_data) && + if (CHECK_IRQ_PER_CPU(desc->status) && !cpu_isset(smp_processor_id(), dest)) { int cpu = first_cpu(dest); @@ -394,14 +398,14 @@ static void claim_cpu_irqs(void) { int i; for (i = CPU_IRQ_BASE; i <= CPU_IRQ_MAX; i++) { - irq_set_chip_and_handler(i, &cpu_interrupt_type, + set_irq_chip_and_handler(i, &cpu_interrupt_type, handle_percpu_irq); } - irq_set_handler(TIMER_IRQ, handle_percpu_irq); + set_irq_handler(TIMER_IRQ, handle_percpu_irq); setup_irq(TIMER_IRQ, &timer_action); #ifdef CONFIG_SMP - irq_set_handler(IPI_IRQ, handle_percpu_irq); + set_irq_handler(IPI_IRQ, handle_percpu_irq); setup_irq(IPI_IRQ, &ipi_action); #endif } diff --git a/trunk/arch/powerpc/Kconfig b/trunk/arch/powerpc/Kconfig index d0e8a1dbf822..3584e4d4a4ad 100644 --- a/trunk/arch/powerpc/Kconfig +++ b/trunk/arch/powerpc/Kconfig @@ -139,8 +139,6 @@ config PPC select HAVE_SPARSE_IRQ select IRQ_PER_CPU select GENERIC_HARDIRQS_NO_DEPRECATED - select GENERIC_IRQ_SHOW - select GENERIC_IRQ_SHOW_LEVEL config EARLY_PRINTK bool diff --git a/trunk/arch/powerpc/kernel/irq.c b/trunk/arch/powerpc/kernel/irq.c index 63625e0650b5..0a5570338b96 100644 --- a/trunk/arch/powerpc/kernel/irq.c +++ b/trunk/arch/powerpc/kernel/irq.c @@ -195,7 +195,7 @@ notrace void arch_local_irq_restore(unsigned long en) EXPORT_SYMBOL(arch_local_irq_restore); #endif /* CONFIG_PPC64 */ -int arch_show_interrupts(struct seq_file *p, int prec) +static int show_other_interrupts(struct seq_file *p, int prec) { int j; @@ -231,6 +231,65 @@ int arch_show_interrupts(struct seq_file *p, int prec) return 0; } +int show_interrupts(struct seq_file *p, void *v) +{ + unsigned long flags, any_count = 0; + int i = *(loff_t *) v, j, prec; + struct irqaction *action; + struct irq_desc *desc; + struct irq_chip *chip; + + if (i > nr_irqs) + return 0; + + for (prec = 3, j = 1000; prec < 10 && j <= nr_irqs; ++prec) + j *= 10; + + if (i == nr_irqs) + return show_other_interrupts(p, prec); + + /* print header */ + if (i == 0) { + seq_printf(p, "%*s", prec + 8, ""); + for_each_online_cpu(j) + seq_printf(p, "CPU%-8d", j); + seq_putc(p, '\n'); + } + + desc = irq_to_desc(i); + if (!desc) + return 0; + + raw_spin_lock_irqsave(&desc->lock, flags); + for_each_online_cpu(j) + any_count |= kstat_irqs_cpu(i, j); + action = desc->action; + if (!action && !any_count) + goto out; + + seq_printf(p, "%*d: ", prec, i); + for_each_online_cpu(j) + seq_printf(p, "%10u ", kstat_irqs_cpu(i, j)); + + chip = get_irq_desc_chip(desc); + if (chip) + seq_printf(p, " %-16s", chip->name); + else + seq_printf(p, " %-16s", "None"); + seq_printf(p, " %-8s", (desc->status & IRQ_LEVEL) ? "Level" : "Edge"); + + if (action) { + seq_printf(p, " %s", action->name); + while ((action = action->next) != NULL) + seq_printf(p, ", %s", action->name); + } + + seq_putc(p, '\n'); +out: + raw_spin_unlock_irqrestore(&desc->lock, flags); + return 0; +} + /* * /proc/stat helpers */ @@ -256,26 +315,24 @@ void fixup_irqs(const struct cpumask *map) alloc_cpumask_var(&mask, GFP_KERNEL); for_each_irq(irq) { - struct irq_data *data; struct irq_chip *chip; desc = irq_to_desc(irq); if (!desc) continue; - data = irq_desc_get_irq_data(desc); - if (irqd_is_per_cpu(data)) + if (desc->status & IRQ_PER_CPU) continue; - chip = irq_data_get_irq_chip(data); + chip = get_irq_desc_chip(desc); - cpumask_and(mask, data->affinity, map); + cpumask_and(mask, desc->irq_data.affinity, map); if (cpumask_any(mask) >= nr_cpu_ids) { printk("Breaking affinity for irq %i\n", irq); cpumask_copy(mask, map); } if (chip->irq_set_affinity) - chip->irq_set_affinity(data, mask, true); + chip->irq_set_affinity(&desc->irq_data, mask, true); else if (desc->action && !(warned++)) printk("Cannot set affinity for irq %i\n", irq); } @@ -561,7 +618,7 @@ struct irq_host *irq_alloc_host(struct device_node *of_node, smp_wmb(); /* Clear norequest flags */ - irq_clear_status_flags(i, IRQ_NOREQUEST); + irq_to_desc(i)->status &= ~IRQ_NOREQUEST; /* Legacy flags are left to default at this point, * one can then use irq_create_mapping() to @@ -770,8 +827,8 @@ unsigned int irq_create_of_mapping(struct device_node *controller, /* Set type if specified and different than the current one */ if (type != IRQ_TYPE_NONE && - type != (irqd_get_trigger_type(irq_get_irq_data(virq)))) - irq_set_irq_type(virq, type); + type != (irq_to_desc(virq)->status & IRQF_TRIGGER_MASK)) + set_irq_type(virq, type); return virq; } EXPORT_SYMBOL_GPL(irq_create_of_mapping); @@ -794,7 +851,7 @@ void irq_dispose_mapping(unsigned int virq) return; /* remove chip and handler */ - irq_set_chip_and_handler(virq, NULL, NULL); + set_irq_chip_and_handler(virq, NULL, NULL); /* Make sure it's completed */ synchronize_irq(virq); @@ -1099,7 +1156,7 @@ static int virq_debug_show(struct seq_file *m, void *private) seq_printf(m, "%5d ", i); seq_printf(m, "0x%05lx ", virq_to_hw(i)); - chip = irq_desc_get_chip(desc); + chip = get_irq_desc_chip(desc); if (chip && chip->name) p = chip->name; else diff --git a/trunk/arch/powerpc/kernel/machine_kexec.c b/trunk/arch/powerpc/kernel/machine_kexec.c index 7ee50f0547cb..bd1e1ff17b2d 100644 --- a/trunk/arch/powerpc/kernel/machine_kexec.c +++ b/trunk/arch/powerpc/kernel/machine_kexec.c @@ -31,17 +31,17 @@ void machine_kexec_mask_interrupts(void) { if (!desc) continue; - chip = irq_desc_get_chip(desc); + chip = get_irq_desc_chip(desc); if (!chip) continue; - if (chip->irq_eoi && irqd_irq_inprogress(&desc->irq_data)) + if (chip->irq_eoi && desc->status & IRQ_INPROGRESS) chip->irq_eoi(&desc->irq_data); if (chip->irq_mask) chip->irq_mask(&desc->irq_data); - if (chip->irq_disable && !irqd_irq_disabled(&desc->irq_data)) + if (chip->irq_disable && !(desc->status & IRQ_DISABLED)) chip->irq_disable(&desc->irq_data); } } diff --git a/trunk/arch/powerpc/kernel/pci-common.c b/trunk/arch/powerpc/kernel/pci-common.c index 893af2a9cd03..3cd85faa8ac6 100644 --- a/trunk/arch/powerpc/kernel/pci-common.c +++ b/trunk/arch/powerpc/kernel/pci-common.c @@ -261,7 +261,7 @@ int pci_read_irq_line(struct pci_dev *pci_dev) virq = irq_create_mapping(NULL, line); if (virq != NO_IRQ) - irq_set_irq_type(virq, IRQ_TYPE_LEVEL_LOW); + set_irq_type(virq, IRQ_TYPE_LEVEL_LOW); } else { pr_debug(" Got one, spec %d cells (0x%08x 0x%08x...) on %s\n", oirq.size, oirq.specifier[0], oirq.specifier[1], diff --git a/trunk/arch/powerpc/platforms/512x/mpc5121_ads_cpld.c b/trunk/arch/powerpc/platforms/512x/mpc5121_ads_cpld.c index cfc4b2009982..fde0ea50c97d 100644 --- a/trunk/arch/powerpc/platforms/512x/mpc5121_ads_cpld.c +++ b/trunk/arch/powerpc/platforms/512x/mpc5121_ads_cpld.c @@ -132,8 +132,8 @@ static int cpld_pic_host_map(struct irq_host *h, unsigned int virq, irq_hw_number_t hw) { - irq_set_status_flags(virq, IRQ_LEVEL); - irq_set_chip_and_handler(virq, &cpld_pic, handle_level_irq); + irq_to_desc(virq)->status |= IRQ_LEVEL; + set_irq_chip_and_handler(virq, &cpld_pic, handle_level_irq); return 0; } @@ -198,7 +198,7 @@ mpc5121_ads_cpld_pic_init(void) goto end; } - irq_set_chained_handler(cascade_irq, cpld_pic_cascade); + set_irq_chained_handler(cascade_irq, cpld_pic_cascade); end: of_node_put(np); } diff --git a/trunk/arch/powerpc/platforms/52xx/media5200.c b/trunk/arch/powerpc/platforms/52xx/media5200.c index 57a6a349e932..2bd1e6cf1f58 100644 --- a/trunk/arch/powerpc/platforms/52xx/media5200.c +++ b/trunk/arch/powerpc/platforms/52xx/media5200.c @@ -82,7 +82,7 @@ static struct irq_chip media5200_irq_chip = { void media5200_irq_cascade(unsigned int virq, struct irq_desc *desc) { - struct irq_chip *chip = irq_desc_get_chip(desc); + struct irq_chip *chip = get_irq_desc_chip(desc); int sub_virq, val; u32 status, enable; @@ -107,7 +107,7 @@ void media5200_irq_cascade(unsigned int virq, struct irq_desc *desc) /* Processing done; can reenable the cascade now */ raw_spin_lock(&desc->lock); chip->irq_ack(&desc->irq_data); - if (!irqd_irq_disabled(&desc->irq_data)) + if (!(desc->status & IRQ_DISABLED)) chip->irq_unmask(&desc->irq_data); raw_spin_unlock(&desc->lock); } @@ -115,10 +115,15 @@ void media5200_irq_cascade(unsigned int virq, struct irq_desc *desc) static int media5200_irq_map(struct irq_host *h, unsigned int virq, irq_hw_number_t hw) { + struct irq_desc *desc = irq_to_desc(virq); + pr_debug("%s: h=%p, virq=%i, hwirq=%i\n", __func__, h, virq, (int)hw); - irq_set_chip_data(virq, &media5200_irq); - irq_set_chip_and_handler(virq, &media5200_irq_chip, handle_level_irq); - irq_set_status_flags(virq, IRQ_LEVEL); + set_irq_chip_data(virq, &media5200_irq); + set_irq_chip_and_handler(virq, &media5200_irq_chip, handle_level_irq); + set_irq_type(virq, IRQ_TYPE_LEVEL_LOW); + desc->status &= ~(IRQ_TYPE_SENSE_MASK | IRQ_LEVEL); + desc->status |= IRQ_TYPE_LEVEL_LOW | IRQ_LEVEL; + return 0; } @@ -182,8 +187,8 @@ static void __init media5200_init_irq(void) media5200_irq.irqhost->host_data = &media5200_irq; - irq_set_handler_data(cascade_virq, &media5200_irq); - irq_set_chained_handler(cascade_virq, media5200_irq_cascade); + set_irq_data(cascade_virq, &media5200_irq); + set_irq_chained_handler(cascade_virq, media5200_irq_cascade); return; diff --git a/trunk/arch/powerpc/platforms/52xx/mpc52xx_gpt.c b/trunk/arch/powerpc/platforms/52xx/mpc52xx_gpt.c index 6c39b9cc2fa3..6da44f0f2934 100644 --- a/trunk/arch/powerpc/platforms/52xx/mpc52xx_gpt.c +++ b/trunk/arch/powerpc/platforms/52xx/mpc52xx_gpt.c @@ -192,7 +192,7 @@ static struct irq_chip mpc52xx_gpt_irq_chip = { void mpc52xx_gpt_irq_cascade(unsigned int virq, struct irq_desc *desc) { - struct mpc52xx_gpt_priv *gpt = irq_get_handler_data(virq); + struct mpc52xx_gpt_priv *gpt = get_irq_data(virq); int sub_virq; u32 status; @@ -209,8 +209,8 @@ static int mpc52xx_gpt_irq_map(struct irq_host *h, unsigned int virq, struct mpc52xx_gpt_priv *gpt = h->host_data; dev_dbg(gpt->dev, "%s: h=%p, virq=%i\n", __func__, h, virq); - irq_set_chip_data(virq, gpt); - irq_set_chip_and_handler(virq, &mpc52xx_gpt_irq_chip, handle_edge_irq); + set_irq_chip_data(virq, gpt); + set_irq_chip_and_handler(virq, &mpc52xx_gpt_irq_chip, handle_edge_irq); return 0; } @@ -259,8 +259,8 @@ mpc52xx_gpt_irq_setup(struct mpc52xx_gpt_priv *gpt, struct device_node *node) } gpt->irqhost->host_data = gpt; - irq_set_handler_data(cascade_virq, gpt); - irq_set_chained_handler(cascade_virq, mpc52xx_gpt_irq_cascade); + set_irq_data(cascade_virq, gpt); + set_irq_chained_handler(cascade_virq, mpc52xx_gpt_irq_cascade); /* If the GPT is currently disabled, then change it to be in Input * Capture mode. If the mode is non-zero, then the pin could be diff --git a/trunk/arch/powerpc/platforms/52xx/mpc52xx_pic.c b/trunk/arch/powerpc/platforms/52xx/mpc52xx_pic.c index 3ddea96273ca..9f3ed582d082 100644 --- a/trunk/arch/powerpc/platforms/52xx/mpc52xx_pic.c +++ b/trunk/arch/powerpc/platforms/52xx/mpc52xx_pic.c @@ -214,7 +214,7 @@ static int mpc52xx_extirq_set_type(struct irq_data *d, unsigned int flow_type) ctrl_reg |= (type << (22 - (l2irq * 2))); out_be32(&intr->ctrl, ctrl_reg); - __irq_set_handler_locked(d->irq, handler); + __set_irq_handler_unlocked(d->irq, handler); return 0; } @@ -414,7 +414,7 @@ static int mpc52xx_irqhost_map(struct irq_host *h, unsigned int virq, else hndlr = handle_level_irq; - irq_set_chip_and_handler(virq, &mpc52xx_extirq_irqchip, hndlr); + set_irq_chip_and_handler(virq, &mpc52xx_extirq_irqchip, hndlr); pr_debug("%s: External IRQ%i virq=%x, hw=%x. type=%x\n", __func__, l2irq, virq, (int)irq, type); return 0; @@ -431,7 +431,7 @@ static int mpc52xx_irqhost_map(struct irq_host *h, unsigned int virq, return -EINVAL; } - irq_set_chip_and_handler(virq, irqchip, handle_level_irq); + set_irq_chip_and_handler(virq, irqchip, handle_level_irq); pr_debug("%s: virq=%x, l1=%i, l2=%i\n", __func__, virq, l1irq, l2irq); return 0; diff --git a/trunk/arch/powerpc/platforms/82xx/pq2ads-pci-pic.c b/trunk/arch/powerpc/platforms/82xx/pq2ads-pci-pic.c index 4a4eb6ffa12f..926dfdaaf57a 100644 --- a/trunk/arch/powerpc/platforms/82xx/pq2ads-pci-pic.c +++ b/trunk/arch/powerpc/platforms/82xx/pq2ads-pci-pic.c @@ -81,7 +81,7 @@ static struct irq_chip pq2ads_pci_ic = { static void pq2ads_pci_irq_demux(unsigned int irq, struct irq_desc *desc) { - struct pq2ads_pci_pic *priv = irq_desc_get_handler_data(desc); + struct pq2ads_pci_pic *priv = get_irq_desc_data(desc); u32 stat, mask, pend; int bit; @@ -106,17 +106,17 @@ static void pq2ads_pci_irq_demux(unsigned int irq, struct irq_desc *desc) static int pci_pic_host_map(struct irq_host *h, unsigned int virq, irq_hw_number_t hw) { - irq_set_status_flags(virq, IRQ_LEVEL); - irq_set_chip_data(virq, h->host_data); - irq_set_chip_and_handler(virq, &pq2ads_pci_ic, handle_level_irq); + irq_to_desc(virq)->status |= IRQ_LEVEL; + set_irq_chip_data(virq, h->host_data); + set_irq_chip_and_handler(virq, &pq2ads_pci_ic, handle_level_irq); return 0; } static void pci_host_unmap(struct irq_host *h, unsigned int virq) { /* remove chip and handler */ - irq_set_chip_data(virq, NULL); - irq_set_chip(virq, NULL); + set_irq_chip_data(virq, NULL); + set_irq_chip(virq, NULL); } static struct irq_host_ops pci_pic_host_ops = { @@ -175,8 +175,8 @@ int __init pq2ads_pci_init_irq(void) priv->host = host; host->host_data = priv; - irq_set_handler_data(irq, priv); - irq_set_chained_handler(irq, pq2ads_pci_irq_demux); + set_irq_data(irq, priv); + set_irq_chained_handler(irq, pq2ads_pci_irq_demux); of_node_put(np); return 0; diff --git a/trunk/arch/powerpc/platforms/85xx/ksi8560.c b/trunk/arch/powerpc/platforms/85xx/ksi8560.c index c46f9359be15..64447e48f3d5 100644 --- a/trunk/arch/powerpc/platforms/85xx/ksi8560.c +++ b/trunk/arch/powerpc/platforms/85xx/ksi8560.c @@ -56,7 +56,7 @@ static void machine_restart(char *cmd) static void cpm2_cascade(unsigned int irq, struct irq_desc *desc) { - struct irq_chip *chip = irq_desc_get_chip(desc); + struct irq_chip *chip = get_irq_desc_chip(desc); int cascade_irq; while ((cascade_irq = cpm2_get_irq()) >= 0) @@ -106,7 +106,7 @@ static void __init ksi8560_pic_init(void) cpm2_pic_init(np); of_node_put(np); - irq_set_chained_handler(irq, cpm2_cascade); + set_irq_chained_handler(irq, cpm2_cascade); #endif } diff --git a/trunk/arch/powerpc/platforms/85xx/mpc85xx_ads.c b/trunk/arch/powerpc/platforms/85xx/mpc85xx_ads.c index 3b2c9bb66199..1352d1107bfd 100644 --- a/trunk/arch/powerpc/platforms/85xx/mpc85xx_ads.c +++ b/trunk/arch/powerpc/platforms/85xx/mpc85xx_ads.c @@ -50,7 +50,7 @@ static int mpc85xx_exclude_device(struct pci_controller *hose, static void cpm2_cascade(unsigned int irq, struct irq_desc *desc) { - struct irq_chip *chip = irq_desc_get_chip(desc); + struct irq_chip *chip = get_irq_desc_chip(desc); int cascade_irq; while ((cascade_irq = cpm2_get_irq()) >= 0) @@ -101,7 +101,7 @@ static void __init mpc85xx_ads_pic_init(void) cpm2_pic_init(np); of_node_put(np); - irq_set_chained_handler(irq, cpm2_cascade); + set_irq_chained_handler(irq, cpm2_cascade); #endif } diff --git a/trunk/arch/powerpc/platforms/85xx/mpc85xx_cds.c b/trunk/arch/powerpc/platforms/85xx/mpc85xx_cds.c index 6299a2a51ae8..458d91fba91d 100644 --- a/trunk/arch/powerpc/platforms/85xx/mpc85xx_cds.c +++ b/trunk/arch/powerpc/platforms/85xx/mpc85xx_cds.c @@ -255,7 +255,7 @@ static int mpc85xx_cds_8259_attach(void) } /* Success. Connect our low-level cascade handler. */ - irq_set_handler(cascade_irq, mpc85xx_8259_cascade_handler); + set_irq_handler(cascade_irq, mpc85xx_8259_cascade_handler); return 0; } diff --git a/trunk/arch/powerpc/platforms/85xx/mpc85xx_ds.c b/trunk/arch/powerpc/platforms/85xx/mpc85xx_ds.c index c7b97f70312e..793ead7993ab 100644 --- a/trunk/arch/powerpc/platforms/85xx/mpc85xx_ds.c +++ b/trunk/arch/powerpc/platforms/85xx/mpc85xx_ds.c @@ -47,7 +47,7 @@ #ifdef CONFIG_PPC_I8259 static void mpc85xx_8259_cascade(unsigned int irq, struct irq_desc *desc) { - struct irq_chip *chip = irq_desc_get_chip(desc); + struct irq_chip *chip = get_irq_desc_chip(desc); unsigned int cascade_irq = i8259_irq(); if (cascade_irq != NO_IRQ) { @@ -122,7 +122,7 @@ void __init mpc85xx_ds_pic_init(void) i8259_init(cascade_node, 0); of_node_put(cascade_node); - irq_set_chained_handler(cascade_irq, mpc85xx_8259_cascade); + set_irq_chained_handler(cascade_irq, mpc85xx_8259_cascade); #endif /* CONFIG_PPC_I8259 */ } diff --git a/trunk/arch/powerpc/platforms/85xx/sbc8560.c b/trunk/arch/powerpc/platforms/85xx/sbc8560.c index d2dfd465fbf6..d7e28ec3e072 100644 --- a/trunk/arch/powerpc/platforms/85xx/sbc8560.c +++ b/trunk/arch/powerpc/platforms/85xx/sbc8560.c @@ -41,7 +41,7 @@ static void cpm2_cascade(unsigned int irq, struct irq_desc *desc) { - struct irq_chip *chip = irq_desc_get_chip(desc); + struct irq_chip *chip = get_irq_desc_chip(desc); int cascade_irq; while ((cascade_irq = cpm2_get_irq()) >= 0) @@ -92,7 +92,7 @@ static void __init sbc8560_pic_init(void) cpm2_pic_init(np); of_node_put(np); - irq_set_chained_handler(irq, cpm2_cascade); + set_irq_chained_handler(irq, cpm2_cascade); #endif } diff --git a/trunk/arch/powerpc/platforms/85xx/socrates_fpga_pic.c b/trunk/arch/powerpc/platforms/85xx/socrates_fpga_pic.c index db864623b4ae..79d85aca4767 100644 --- a/trunk/arch/powerpc/platforms/85xx/socrates_fpga_pic.c +++ b/trunk/arch/powerpc/platforms/85xx/socrates_fpga_pic.c @@ -93,7 +93,7 @@ static inline unsigned int socrates_fpga_pic_get_irq(unsigned int irq) void socrates_fpga_pic_cascade(unsigned int irq, struct irq_desc *desc) { - struct irq_chip *chip = irq_desc_get_chip(desc); + struct irq_chip *chip = get_irq_desc_chip(desc); unsigned int cascade_irq; /* @@ -245,9 +245,9 @@ static int socrates_fpga_pic_host_map(struct irq_host *h, unsigned int virq, irq_hw_number_t hwirq) { /* All interrupts are LEVEL sensitive */ - irq_set_status_flags(virq, IRQ_LEVEL); - irq_set_chip_and_handler(virq, &socrates_fpga_pic_chip, - handle_fasteoi_irq); + irq_to_desc(virq)->status |= IRQ_LEVEL; + set_irq_chip_and_handler(virq, &socrates_fpga_pic_chip, + handle_fasteoi_irq); return 0; } @@ -308,8 +308,8 @@ void socrates_fpga_pic_init(struct device_node *pic) pr_warning("FPGA PIC: can't get irq%d.\n", i); continue; } - irq_set_chained_handler(socrates_fpga_irqs[i], - socrates_fpga_pic_cascade); + set_irq_chained_handler(socrates_fpga_irqs[i], + socrates_fpga_pic_cascade); } socrates_fpga_pic_iobase = of_iomap(pic, 0); diff --git a/trunk/arch/powerpc/platforms/85xx/stx_gp3.c b/trunk/arch/powerpc/platforms/85xx/stx_gp3.c index 5387e9f06bdb..2b62b064eac7 100644 --- a/trunk/arch/powerpc/platforms/85xx/stx_gp3.c +++ b/trunk/arch/powerpc/platforms/85xx/stx_gp3.c @@ -46,7 +46,7 @@ static void cpm2_cascade(unsigned int irq, struct irq_desc *desc) { - struct irq_chip *chip = irq_desc_get_chip(desc); + struct irq_chip *chip = get_irq_desc_chip(desc); int cascade_irq; while ((cascade_irq = cpm2_get_irq()) >= 0) @@ -102,7 +102,7 @@ static void __init stx_gp3_pic_init(void) cpm2_pic_init(np); of_node_put(np); - irq_set_chained_handler(irq, cpm2_cascade); + set_irq_chained_handler(irq, cpm2_cascade); #endif } diff --git a/trunk/arch/powerpc/platforms/85xx/tqm85xx.c b/trunk/arch/powerpc/platforms/85xx/tqm85xx.c index 325de772725a..2265b68e3279 100644 --- a/trunk/arch/powerpc/platforms/85xx/tqm85xx.c +++ b/trunk/arch/powerpc/platforms/85xx/tqm85xx.c @@ -44,7 +44,7 @@ static void cpm2_cascade(unsigned int irq, struct irq_desc *desc) { - struct irq_chip *chip = irq_desc_get_chip(desc); + struct irq_chip *chip = get_irq_desc_chip(desc); int cascade_irq; while ((cascade_irq = cpm2_get_irq()) >= 0) @@ -100,7 +100,7 @@ static void __init tqm85xx_pic_init(void) cpm2_pic_init(np); of_node_put(np); - irq_set_chained_handler(irq, cpm2_cascade); + set_irq_chained_handler(irq, cpm2_cascade); #endif } diff --git a/trunk/arch/powerpc/platforms/86xx/gef_pic.c b/trunk/arch/powerpc/platforms/86xx/gef_pic.c index 0beec7d5566b..0adfe3b740cd 100644 --- a/trunk/arch/powerpc/platforms/86xx/gef_pic.c +++ b/trunk/arch/powerpc/platforms/86xx/gef_pic.c @@ -95,7 +95,7 @@ static int gef_pic_cascade_irq; void gef_pic_cascade(unsigned int irq, struct irq_desc *desc) { - struct irq_chip *chip = irq_desc_get_chip(desc); + struct irq_chip *chip = get_irq_desc_chip(desc); unsigned int cascade_irq; /* @@ -163,8 +163,8 @@ static int gef_pic_host_map(struct irq_host *h, unsigned int virq, irq_hw_number_t hwirq) { /* All interrupts are LEVEL sensitive */ - irq_set_status_flags(virq, IRQ_LEVEL); - irq_set_chip_and_handler(virq, &gef_pic_chip, handle_level_irq); + irq_to_desc(virq)->status |= IRQ_LEVEL; + set_irq_chip_and_handler(virq, &gef_pic_chip, handle_level_irq); return 0; } @@ -225,7 +225,7 @@ void __init gef_pic_init(struct device_node *np) return; /* Chain with parent controller */ - irq_set_chained_handler(gef_pic_cascade_irq, gef_pic_cascade); + set_irq_chained_handler(gef_pic_cascade_irq, gef_pic_cascade); } /* diff --git a/trunk/arch/powerpc/platforms/86xx/pic.c b/trunk/arch/powerpc/platforms/86xx/pic.c index 8ef8960abda6..cbe33639b478 100644 --- a/trunk/arch/powerpc/platforms/86xx/pic.c +++ b/trunk/arch/powerpc/platforms/86xx/pic.c @@ -19,7 +19,7 @@ #ifdef CONFIG_PPC_I8259 static void mpc86xx_8259_cascade(unsigned int irq, struct irq_desc *desc) { - struct irq_chip *chip = irq_desc_get_chip(desc); + struct irq_chip *chip = get_irq_desc_chip(desc); unsigned int cascade_irq = i8259_irq(); if (cascade_irq != NO_IRQ) @@ -77,6 +77,6 @@ void __init mpc86xx_init_irq(void) i8259_init(cascade_node, 0); of_node_put(cascade_node); - irq_set_chained_handler(cascade_irq, mpc86xx_8259_cascade); + set_irq_chained_handler(cascade_irq, mpc86xx_8259_cascade); #endif } diff --git a/trunk/arch/powerpc/platforms/8xx/m8xx_setup.c b/trunk/arch/powerpc/platforms/8xx/m8xx_setup.c index 9ecce995dd4b..fabb108e8744 100644 --- a/trunk/arch/powerpc/platforms/8xx/m8xx_setup.c +++ b/trunk/arch/powerpc/platforms/8xx/m8xx_setup.c @@ -226,11 +226,11 @@ static void cpm_cascade(unsigned int irq, struct irq_desc *desc) generic_handle_irq(cascade_irq); - chip = irq_desc_get_chip(cdesc); + chip = get_irq_desc_chip(cdesc); chip->irq_eoi(&cdesc->irq_data); } - chip = irq_desc_get_chip(desc); + chip = get_irq_desc_chip(desc); chip->irq_eoi(&desc->irq_data); } @@ -251,5 +251,5 @@ void __init mpc8xx_pics_init(void) irq = cpm_pic_init(); if (irq != NO_IRQ) - irq_set_chained_handler(irq, cpm_cascade); + set_irq_chained_handler(irq, cpm_cascade); } diff --git a/trunk/arch/powerpc/platforms/cell/Kconfig b/trunk/arch/powerpc/platforms/cell/Kconfig index 81239ebed83f..48cd7d2e1b75 100644 --- a/trunk/arch/powerpc/platforms/cell/Kconfig +++ b/trunk/arch/powerpc/platforms/cell/Kconfig @@ -9,7 +9,6 @@ config PPC_CELL_COMMON select PPC_INDIRECT_IO select PPC_NATIVE select PPC_RTAS - select IRQ_EDGE_EOI_HANDLER config PPC_CELL_NATIVE bool diff --git a/trunk/arch/powerpc/platforms/cell/axon_msi.c b/trunk/arch/powerpc/platforms/cell/axon_msi.c index bb5ebf8fa80b..c48b66a67e42 100644 --- a/trunk/arch/powerpc/platforms/cell/axon_msi.c +++ b/trunk/arch/powerpc/platforms/cell/axon_msi.c @@ -93,8 +93,8 @@ static void msic_dcr_write(struct axon_msic *msic, unsigned int dcr_n, u32 val) static void axon_msi_cascade(unsigned int irq, struct irq_desc *desc) { - struct irq_chip *chip = irq_desc_get_chip(desc); - struct axon_msic *msic = irq_get_handler_data(irq); + struct irq_chip *chip = get_irq_desc_chip(desc); + struct axon_msic *msic = get_irq_data(irq); u32 write_offset, msi; int idx; int retry = 0; @@ -287,7 +287,7 @@ static int axon_msi_setup_msi_irqs(struct pci_dev *dev, int nvec, int type) } dev_dbg(&dev->dev, "axon_msi: allocated virq 0x%x\n", virq); - irq_set_msi_desc(virq, entry); + set_irq_msi(virq, entry); msg.data = virq; write_msi_msg(virq, &msg); } @@ -305,7 +305,7 @@ static void axon_msi_teardown_msi_irqs(struct pci_dev *dev) if (entry->irq == NO_IRQ) continue; - irq_set_msi_desc(entry->irq, NULL); + set_irq_msi(entry->irq, NULL); irq_dispose_mapping(entry->irq); } } @@ -320,7 +320,7 @@ static struct irq_chip msic_irq_chip = { static int msic_host_map(struct irq_host *h, unsigned int virq, irq_hw_number_t hw) { - irq_set_chip_and_handler(virq, &msic_irq_chip, handle_simple_irq); + set_irq_chip_and_handler(virq, &msic_irq_chip, handle_simple_irq); return 0; } @@ -400,8 +400,8 @@ static int axon_msi_probe(struct platform_device *device) msic->irq_host->host_data = msic; - irq_set_handler_data(virq, msic); - irq_set_chained_handler(virq, axon_msi_cascade); + set_irq_data(virq, msic); + set_irq_chained_handler(virq, axon_msi_cascade); pr_devel("axon_msi: irq 0x%x setup for axon_msi\n", virq); /* Enable the MSIC hardware */ diff --git a/trunk/arch/powerpc/platforms/cell/beat_interrupt.c b/trunk/arch/powerpc/platforms/cell/beat_interrupt.c index 4cb9e147c307..0b8f7d7135c5 100644 --- a/trunk/arch/powerpc/platforms/cell/beat_interrupt.c +++ b/trunk/arch/powerpc/platforms/cell/beat_interrupt.c @@ -136,14 +136,15 @@ static void beatic_pic_host_unmap(struct irq_host *h, unsigned int virq) static int beatic_pic_host_map(struct irq_host *h, unsigned int virq, irq_hw_number_t hw) { + struct irq_desc *desc = irq_to_desc(virq); int64_t err; err = beat_construct_and_connect_irq_plug(virq, hw); if (err < 0) return -EIO; - irq_set_status_flags(virq, IRQ_LEVEL); - irq_set_chip_and_handler(virq, &beatic_pic, handle_fasteoi_irq); + desc->status |= IRQ_LEVEL; + set_irq_chip_and_handler(virq, &beatic_pic, handle_fasteoi_irq); return 0; } diff --git a/trunk/arch/powerpc/platforms/cell/interrupt.c b/trunk/arch/powerpc/platforms/cell/interrupt.c index a19bec078703..624d26e72f1d 100644 --- a/trunk/arch/powerpc/platforms/cell/interrupt.c +++ b/trunk/arch/powerpc/platforms/cell/interrupt.c @@ -101,9 +101,9 @@ static void iic_ioexc_eoi(struct irq_data *d) static void iic_ioexc_cascade(unsigned int irq, struct irq_desc *desc) { - struct irq_chip *chip = irq_desc_get_chip(desc); + struct irq_chip *chip = get_irq_desc_chip(desc); struct cbe_iic_regs __iomem *node_iic = - (void __iomem *)irq_desc_get_handler_data(desc); + (void __iomem *)get_irq_desc_data(desc); unsigned int base = (irq & 0xffffff00) | IIC_IRQ_TYPE_IOEXC; unsigned long bits, ack; int cascade; @@ -235,19 +235,67 @@ static int iic_host_match(struct irq_host *h, struct device_node *node) "IBM,CBEA-Internal-Interrupt-Controller"); } +extern int noirqdebug; + +static void handle_iic_irq(unsigned int irq, struct irq_desc *desc) +{ + struct irq_chip *chip = get_irq_desc_chip(desc); + + raw_spin_lock(&desc->lock); + + desc->status &= ~(IRQ_REPLAY | IRQ_WAITING); + + /* + * If we're currently running this IRQ, or its disabled, + * we shouldn't process the IRQ. Mark it pending, handle + * the necessary masking and go out + */ + if (unlikely((desc->status & (IRQ_INPROGRESS | IRQ_DISABLED)) || + !desc->action)) { + desc->status |= IRQ_PENDING; + goto out_eoi; + } + + kstat_incr_irqs_this_cpu(irq, desc); + + /* Mark the IRQ currently in progress.*/ + desc->status |= IRQ_INPROGRESS; + + do { + struct irqaction *action = desc->action; + irqreturn_t action_ret; + + if (unlikely(!action)) + goto out_eoi; + + desc->status &= ~IRQ_PENDING; + raw_spin_unlock(&desc->lock); + action_ret = handle_IRQ_event(irq, action); + if (!noirqdebug) + note_interrupt(irq, desc, action_ret); + raw_spin_lock(&desc->lock); + + } while ((desc->status & (IRQ_PENDING | IRQ_DISABLED)) == IRQ_PENDING); + + desc->status &= ~IRQ_INPROGRESS; +out_eoi: + chip->irq_eoi(&desc->irq_data); + raw_spin_unlock(&desc->lock); +} + static int iic_host_map(struct irq_host *h, unsigned int virq, irq_hw_number_t hw) { switch (hw & IIC_IRQ_TYPE_MASK) { case IIC_IRQ_TYPE_IPI: - irq_set_chip_and_handler(virq, &iic_chip, handle_percpu_irq); + set_irq_chip_and_handler(virq, &iic_chip, handle_percpu_irq); break; case IIC_IRQ_TYPE_IOEXC: - irq_set_chip_and_handler(virq, &iic_ioexc_chip, + set_irq_chip_and_handler(virq, &iic_ioexc_chip, handle_iic_irq); break; default: - irq_set_chip_and_handler(virq, &iic_chip, handle_edge_eoi_irq); + set_irq_chip_and_handler(virq, &iic_chip, handle_iic_irq); } return 0; } @@ -364,8 +412,8 @@ static int __init setup_iic(void) * irq_data is a generic pointer that gets passed back * to us later, so the forced cast is fine. */ - irq_set_handler_data(cascade, (void __force *)node_iic); - irq_set_chained_handler(cascade, iic_ioexc_cascade); + set_irq_data(cascade, (void __force *)node_iic); + set_irq_chained_handler(cascade , iic_ioexc_cascade); out_be64(&node_iic->iic_ir, (1 << 12) /* priority */ | (node << 4) /* dest node */ | diff --git a/trunk/arch/powerpc/platforms/cell/setup.c b/trunk/arch/powerpc/platforms/cell/setup.c index fd57bfe00edf..6a28d027d959 100644 --- a/trunk/arch/powerpc/platforms/cell/setup.c +++ b/trunk/arch/powerpc/platforms/cell/setup.c @@ -187,8 +187,8 @@ machine_subsys_initcall(cell, cell_publish_devices); static void cell_mpic_cascade(unsigned int irq, struct irq_desc *desc) { - struct irq_chip *chip = irq_desc_get_chip(desc); - struct mpic *mpic = irq_desc_get_handler_data(desc); + struct irq_chip *chip = get_irq_desc_chip(desc); + struct mpic *mpic = get_irq_desc_data(desc); unsigned int virq; virq = mpic_get_one_irq(mpic); @@ -223,8 +223,8 @@ static void __init mpic_init_IRQ(void) printk(KERN_INFO "%s : hooking up to IRQ %d\n", dn->full_name, virq); - irq_set_handler_data(virq, mpic); - irq_set_chained_handler(virq, cell_mpic_cascade); + set_irq_data(virq, mpic); + set_irq_chained_handler(virq, cell_mpic_cascade); } } diff --git a/trunk/arch/powerpc/platforms/cell/spider-pic.c b/trunk/arch/powerpc/platforms/cell/spider-pic.c index c5cf50e6b45a..b38cdfc1deb8 100644 --- a/trunk/arch/powerpc/platforms/cell/spider-pic.c +++ b/trunk/arch/powerpc/platforms/cell/spider-pic.c @@ -102,7 +102,7 @@ static void spider_ack_irq(struct irq_data *d) /* Reset edge detection logic if necessary */ - if (irqd_is_level_type(d)) + if (irq_to_desc(d->irq)->status & IRQ_LEVEL) return; /* Only interrupts 47 to 50 can be set to edge */ @@ -119,6 +119,7 @@ static int spider_set_irq_type(struct irq_data *d, unsigned int type) struct spider_pic *pic = spider_virq_to_pic(d->irq); unsigned int hw = irq_map[d->irq].hwirq; void __iomem *cfg = spider_get_irq_config(pic, hw); + struct irq_desc *desc = irq_to_desc(d->irq); u32 old_mask; u32 ic; @@ -146,6 +147,12 @@ static int spider_set_irq_type(struct irq_data *d, unsigned int type) return -EINVAL; } + /* Update irq_desc */ + desc->status &= ~(IRQ_TYPE_SENSE_MASK | IRQ_LEVEL); + desc->status |= type & IRQ_TYPE_SENSE_MASK; + if (type & (IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_LEVEL_LOW)) + desc->status |= IRQ_LEVEL; + /* Configure the source. One gross hack that was there before and * that I've kept around is the priority to the BE which I set to * be the same as the interrupt source number. I don't know wether @@ -171,10 +178,10 @@ static struct irq_chip spider_pic = { static int spider_host_map(struct irq_host *h, unsigned int virq, irq_hw_number_t hw) { - irq_set_chip_and_handler(virq, &spider_pic, handle_level_irq); + set_irq_chip_and_handler(virq, &spider_pic, handle_level_irq); /* Set default irq type */ - irq_set_irq_type(virq, IRQ_TYPE_NONE); + set_irq_type(virq, IRQ_TYPE_NONE); return 0; } @@ -200,8 +207,8 @@ static struct irq_host_ops spider_host_ops = { static void spider_irq_cascade(unsigned int irq, struct irq_desc *desc) { - struct irq_chip *chip = irq_desc_get_chip(desc); - struct spider_pic *pic = irq_desc_get_handler_data(desc); + struct irq_chip *chip = get_irq_desc_chip(desc); + struct spider_pic *pic = get_irq_desc_data(desc); unsigned int cs, virq; cs = in_be32(pic->regs + TIR_CS) >> 24; @@ -321,8 +328,8 @@ static void __init spider_init_one(struct device_node *of_node, int chip, virq = spider_find_cascade_and_node(pic); if (virq == NO_IRQ) return; - irq_set_handler_data(virq, pic); - irq_set_chained_handler(virq, spider_irq_cascade); + set_irq_data(virq, pic); + set_irq_chained_handler(virq, spider_irq_cascade); printk(KERN_INFO "spider_pic: node %d, addr: 0x%lx %s\n", pic->node_id, addr, of_node->full_name); diff --git a/trunk/arch/powerpc/platforms/chrp/setup.c b/trunk/arch/powerpc/platforms/chrp/setup.c index 122786498419..4c1288451a21 100644 --- a/trunk/arch/powerpc/platforms/chrp/setup.c +++ b/trunk/arch/powerpc/platforms/chrp/setup.c @@ -365,7 +365,7 @@ void __init chrp_setup_arch(void) static void chrp_8259_cascade(unsigned int irq, struct irq_desc *desc) { - struct irq_chip *chip = irq_desc_get_chip(desc); + struct irq_chip *chip = get_irq_desc_chip(desc); unsigned int cascade_irq = i8259_irq(); if (cascade_irq != NO_IRQ) @@ -517,7 +517,7 @@ static void __init chrp_find_8259(void) if (cascade_irq == NO_IRQ) printk(KERN_ERR "i8259: failed to map cascade irq\n"); else - irq_set_chained_handler(cascade_irq, + set_irq_chained_handler(cascade_irq, chrp_8259_cascade); } } diff --git a/trunk/arch/powerpc/platforms/embedded6xx/flipper-pic.c b/trunk/arch/powerpc/platforms/embedded6xx/flipper-pic.c index 12aa62b6f227..0aca0e28a8e5 100644 --- a/trunk/arch/powerpc/platforms/embedded6xx/flipper-pic.c +++ b/trunk/arch/powerpc/platforms/embedded6xx/flipper-pic.c @@ -101,16 +101,16 @@ static struct irq_host *flipper_irq_host; static int flipper_pic_map(struct irq_host *h, unsigned int virq, irq_hw_number_t hwirq) { - irq_set_chip_data(virq, h->host_data); - irq_set_status_flags(virq, IRQ_LEVEL); - irq_set_chip_and_handler(virq, &flipper_pic, handle_level_irq); + set_irq_chip_data(virq, h->host_data); + irq_to_desc(virq)->status |= IRQ_LEVEL; + set_irq_chip_and_handler(virq, &flipper_pic, handle_level_irq); return 0; } static void flipper_pic_unmap(struct irq_host *h, unsigned int irq) { - irq_set_chip_data(irq, NULL); - irq_set_chip(irq, NULL); + set_irq_chip_data(irq, NULL); + set_irq_chip(irq, NULL); } static int flipper_pic_match(struct irq_host *h, struct device_node *np) diff --git a/trunk/arch/powerpc/platforms/embedded6xx/hlwd-pic.c b/trunk/arch/powerpc/platforms/embedded6xx/hlwd-pic.c index 2bdddfc9d520..35e448bd8479 100644 --- a/trunk/arch/powerpc/platforms/embedded6xx/hlwd-pic.c +++ b/trunk/arch/powerpc/platforms/embedded6xx/hlwd-pic.c @@ -94,16 +94,16 @@ static struct irq_host *hlwd_irq_host; static int hlwd_pic_map(struct irq_host *h, unsigned int virq, irq_hw_number_t hwirq) { - irq_set_chip_data(virq, h->host_data); - irq_set_status_flags(virq, IRQ_LEVEL); - irq_set_chip_and_handler(virq, &hlwd_pic, handle_level_irq); + set_irq_chip_data(virq, h->host_data); + irq_to_desc(virq)->status |= IRQ_LEVEL; + set_irq_chip_and_handler(virq, &hlwd_pic, handle_level_irq); return 0; } static void hlwd_pic_unmap(struct irq_host *h, unsigned int irq) { - irq_set_chip_data(irq, NULL); - irq_set_chip(irq, NULL); + set_irq_chip_data(irq, NULL); + set_irq_chip(irq, NULL); } static struct irq_host_ops hlwd_irq_host_ops = { @@ -129,8 +129,8 @@ static unsigned int __hlwd_pic_get_irq(struct irq_host *h) static void hlwd_pic_irq_cascade(unsigned int cascade_virq, struct irq_desc *desc) { - struct irq_chip *chip = irq_desc_get_chip(desc); - struct irq_host *irq_host = irq_get_handler_data(cascade_virq); + struct irq_chip *chip = get_irq_desc_chip(desc); + struct irq_host *irq_host = get_irq_data(cascade_virq); unsigned int virq; raw_spin_lock(&desc->lock); @@ -145,7 +145,7 @@ static void hlwd_pic_irq_cascade(unsigned int cascade_virq, raw_spin_lock(&desc->lock); chip->irq_ack(&desc->irq_data); /* IRQ_LEVEL */ - if (!irqd_irq_disabled(&desc->irq_data) && chip->irq_unmask) + if (!(desc->status & IRQ_DISABLED) && chip->irq_unmask) chip->irq_unmask(&desc->irq_data); raw_spin_unlock(&desc->lock); } @@ -218,8 +218,8 @@ void hlwd_pic_probe(void) host = hlwd_pic_init(np); BUG_ON(!host); cascade_virq = irq_of_parse_and_map(np, 0); - irq_set_handler_data(cascade_virq, host); - irq_set_chained_handler(cascade_virq, + set_irq_data(cascade_virq, host); + set_irq_chained_handler(cascade_virq, hlwd_pic_irq_cascade); hlwd_irq_host = host; break; diff --git a/trunk/arch/powerpc/platforms/embedded6xx/holly.c b/trunk/arch/powerpc/platforms/embedded6xx/holly.c index 487bda0d18d8..b21fde589ca7 100644 --- a/trunk/arch/powerpc/platforms/embedded6xx/holly.c +++ b/trunk/arch/powerpc/platforms/embedded6xx/holly.c @@ -198,8 +198,8 @@ static void __init holly_init_IRQ(void) cascade_pci_irq = irq_of_parse_and_map(tsi_pci, 0); pr_debug("%s: tsi108 cascade_pci_irq = 0x%x\n", __func__, (u32) cascade_pci_irq); tsi108_pci_int_init(cascade_node); - irq_set_handler_data(cascade_pci_irq, mpic); - irq_set_chained_handler(cascade_pci_irq, tsi108_irq_cascade); + set_irq_data(cascade_pci_irq, mpic); + set_irq_chained_handler(cascade_pci_irq, tsi108_irq_cascade); #endif /* Configure MPIC outputs to CPU0 */ tsi108_write_reg(TSI108_MPIC_OFFSET + 0x30c, 0); diff --git a/trunk/arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.c b/trunk/arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.c index 1cb907c94359..7a2ba39d7811 100644 --- a/trunk/arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.c +++ b/trunk/arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.c @@ -153,8 +153,8 @@ static void __init mpc7448_hpc2_init_IRQ(void) DBG("%s: tsi108 cascade_pci_irq = 0x%x\n", __func__, (u32) cascade_pci_irq); tsi108_pci_int_init(cascade_node); - irq_set_handler_data(cascade_pci_irq, mpic); - irq_set_chained_handler(cascade_pci_irq, tsi108_irq_cascade); + set_irq_data(cascade_pci_irq, mpic); + set_irq_chained_handler(cascade_pci_irq, tsi108_irq_cascade); #endif /* Configure MPIC outputs to CPU0 */ tsi108_write_reg(TSI108_MPIC_OFFSET + 0x30c, 0); diff --git a/trunk/arch/powerpc/platforms/iseries/irq.c b/trunk/arch/powerpc/platforms/iseries/irq.c index 52a6889832c7..4fb96f0b2df6 100644 --- a/trunk/arch/powerpc/platforms/iseries/irq.c +++ b/trunk/arch/powerpc/platforms/iseries/irq.c @@ -220,7 +220,7 @@ void __init iSeries_activate_IRQs() if (!desc) continue; - chip = irq_desc_get_chip(desc); + chip = get_irq_desc_chip(desc); if (chip && chip->irq_startup) { raw_spin_lock_irqsave(&desc->lock, flags); chip->irq_startup(&desc->irq_data); @@ -346,7 +346,7 @@ unsigned int iSeries_get_irq(void) static int iseries_irq_host_map(struct irq_host *h, unsigned int virq, irq_hw_number_t hw) { - irq_set_chip_and_handler(virq, &iseries_pic, handle_fasteoi_irq); + set_irq_chip_and_handler(virq, &iseries_pic, handle_fasteoi_irq); return 0; } diff --git a/trunk/arch/powerpc/platforms/maple/pci.c b/trunk/arch/powerpc/platforms/maple/pci.c index dd2e48b28508..04296ffff8bf 100644 --- a/trunk/arch/powerpc/platforms/maple/pci.c +++ b/trunk/arch/powerpc/platforms/maple/pci.c @@ -498,7 +498,7 @@ void __devinit maple_pci_irq_fixup(struct pci_dev *dev) printk(KERN_DEBUG "Fixup U4 PCIe IRQ\n"); dev->irq = irq_create_mapping(NULL, 1); if (dev->irq != NO_IRQ) - irq_set_irq_type(dev->irq, IRQ_TYPE_LEVEL_LOW); + set_irq_type(dev->irq, IRQ_TYPE_LEVEL_LOW); } /* Hide AMD8111 IDE interrupt when in legacy mode so diff --git a/trunk/arch/powerpc/platforms/pasemi/setup.c b/trunk/arch/powerpc/platforms/pasemi/setup.c index 7c858e6f843c..a6067b38d2ca 100644 --- a/trunk/arch/powerpc/platforms/pasemi/setup.c +++ b/trunk/arch/powerpc/platforms/pasemi/setup.c @@ -239,7 +239,7 @@ static __init void pas_init_IRQ(void) if (nmiprop) { nmi_virq = irq_create_mapping(NULL, *nmiprop); mpic_irq_set_priority(nmi_virq, 15); - irq_set_irq_type(nmi_virq, IRQ_TYPE_EDGE_RISING); + set_irq_type(nmi_virq, IRQ_TYPE_EDGE_RISING); mpic_unmask_irq(irq_get_irq_data(nmi_virq)); } diff --git a/trunk/arch/powerpc/platforms/powermac/pci.c b/trunk/arch/powerpc/platforms/powermac/pci.c index ab6898942700..3bc075c788ef 100644 --- a/trunk/arch/powerpc/platforms/powermac/pci.c +++ b/trunk/arch/powerpc/platforms/powermac/pci.c @@ -988,7 +988,7 @@ void __devinit pmac_pci_irq_fixup(struct pci_dev *dev) dev->vendor == PCI_VENDOR_ID_DEC && dev->device == PCI_DEVICE_ID_DEC_TULIP_PLUS) { dev->irq = irq_create_mapping(NULL, 60); - irq_set_irq_type(dev->irq, IRQ_TYPE_LEVEL_LOW); + set_irq_type(dev->irq, IRQ_TYPE_LEVEL_LOW); } #endif /* CONFIG_PPC32 */ } diff --git a/trunk/arch/powerpc/platforms/powermac/pic.c b/trunk/arch/powerpc/platforms/powermac/pic.c index 023f24086a0a..c55812bb6a51 100644 --- a/trunk/arch/powerpc/platforms/powermac/pic.c +++ b/trunk/arch/powerpc/platforms/powermac/pic.c @@ -157,7 +157,7 @@ static unsigned int pmac_startup_irq(struct irq_data *d) int i = src >> 5; raw_spin_lock_irqsave(&pmac_pic_lock, flags); - if (!irqd_is_level_type(d)) + if ((irq_to_desc(d->irq)->status & IRQ_LEVEL) == 0) out_le32(&pmac_irq_hw[i]->ack, bit); __set_bit(src, ppc_cached_irq_mask); __pmac_set_irq_mask(src, 0); @@ -289,6 +289,7 @@ static int pmac_pic_host_match(struct irq_host *h, struct device_node *node) static int pmac_pic_host_map(struct irq_host *h, unsigned int virq, irq_hw_number_t hw) { + struct irq_desc *desc = irq_to_desc(virq); int level; if (hw >= max_irqs) @@ -299,9 +300,9 @@ static int pmac_pic_host_map(struct irq_host *h, unsigned int virq, */ level = !!(level_mask[hw >> 5] & (1UL << (hw & 0x1f))); if (level) - irq_set_status_flags(virq, IRQ_LEVEL); - irq_set_chip_and_handler(virq, &pmac_pic, - level ? handle_level_irq : handle_edge_irq); + desc->status |= IRQ_LEVEL; + set_irq_chip_and_handler(virq, &pmac_pic, level ? + handle_level_irq : handle_edge_irq); return 0; } @@ -471,8 +472,8 @@ int of_irq_map_oldworld(struct device_node *device, int index, static void pmac_u3_cascade(unsigned int irq, struct irq_desc *desc) { - struct irq_chip *chip = irq_desc_get_chip(desc); - struct mpic *mpic = irq_desc_get_handler_data(desc); + struct irq_chip *chip = get_irq_desc_chip(desc); + struct mpic *mpic = get_irq_desc_data(desc); unsigned int cascade_irq = mpic_get_one_irq(mpic); if (cascade_irq != NO_IRQ) @@ -590,8 +591,8 @@ static int __init pmac_pic_probe_mpic(void) of_node_put(slave); return 0; } - irq_set_handler_data(cascade, mpic2); - irq_set_chained_handler(cascade, pmac_u3_cascade); + set_irq_data(cascade, mpic2); + set_irq_chained_handler(cascade, pmac_u3_cascade); of_node_put(slave); return 0; diff --git a/trunk/arch/powerpc/platforms/ps3/interrupt.c b/trunk/arch/powerpc/platforms/ps3/interrupt.c index f2f6413b81d3..3988c86682a5 100644 --- a/trunk/arch/powerpc/platforms/ps3/interrupt.c +++ b/trunk/arch/powerpc/platforms/ps3/interrupt.c @@ -194,7 +194,7 @@ static int ps3_virq_setup(enum ps3_cpu_binding cpu, unsigned long outlet, pr_debug("%s:%d: outlet %lu => cpu %u, virq %u\n", __func__, __LINE__, outlet, cpu, *virq); - result = irq_set_chip_data(*virq, pd); + result = set_irq_chip_data(*virq, pd); if (result) { pr_debug("%s:%d: set_irq_chip_data failed\n", @@ -221,12 +221,12 @@ static int ps3_virq_setup(enum ps3_cpu_binding cpu, unsigned long outlet, static int ps3_virq_destroy(unsigned int virq) { - const struct ps3_private *pd = irq_get_chip_data(virq); + const struct ps3_private *pd = get_irq_chip_data(virq); pr_debug("%s:%d: ppe_id %llu, thread_id %llu, virq %u\n", __func__, __LINE__, pd->ppe_id, pd->thread_id, virq); - irq_set_chip_data(virq, NULL); + set_irq_chip_data(virq, NULL); irq_dispose_mapping(virq); pr_debug("%s:%d <-\n", __func__, __LINE__); @@ -256,7 +256,7 @@ int ps3_irq_plug_setup(enum ps3_cpu_binding cpu, unsigned long outlet, goto fail_setup; } - pd = irq_get_chip_data(*virq); + pd = get_irq_chip_data(*virq); /* Binds outlet to cpu + virq. */ @@ -291,7 +291,7 @@ EXPORT_SYMBOL_GPL(ps3_irq_plug_setup); int ps3_irq_plug_destroy(unsigned int virq) { int result; - const struct ps3_private *pd = irq_get_chip_data(virq); + const struct ps3_private *pd = get_irq_chip_data(virq); pr_debug("%s:%d: ppe_id %llu, thread_id %llu, virq %u\n", __func__, __LINE__, pd->ppe_id, pd->thread_id, virq); @@ -661,7 +661,7 @@ static void dump_bmp(struct ps3_private* pd) {}; static void ps3_host_unmap(struct irq_host *h, unsigned int virq) { - irq_set_chip_data(virq, NULL); + set_irq_chip_data(virq, NULL); } static int ps3_host_map(struct irq_host *h, unsigned int virq, @@ -670,7 +670,7 @@ static int ps3_host_map(struct irq_host *h, unsigned int virq, pr_debug("%s:%d: hwirq %lu, virq %u\n", __func__, __LINE__, hwirq, virq); - irq_set_chip_and_handler(virq, &ps3_irq_chip, handle_fasteoi_irq); + set_irq_chip_and_handler(virq, &ps3_irq_chip, handle_fasteoi_irq); return 0; } diff --git a/trunk/arch/powerpc/platforms/pseries/msi.c b/trunk/arch/powerpc/platforms/pseries/msi.c index 38d24e7e7bb1..18ac801f8e90 100644 --- a/trunk/arch/powerpc/platforms/pseries/msi.c +++ b/trunk/arch/powerpc/platforms/pseries/msi.c @@ -137,7 +137,7 @@ static void rtas_teardown_msi_irqs(struct pci_dev *pdev) if (entry->irq == NO_IRQ) continue; - irq_set_msi_desc(entry->irq, NULL); + set_irq_msi(entry->irq, NULL); irq_dispose_mapping(entry->irq); } @@ -437,7 +437,7 @@ static int rtas_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type) } dev_dbg(&pdev->dev, "rtas_msi: allocated virq %d\n", virq); - irq_set_msi_desc(virq, entry); + set_irq_msi(virq, entry); /* Read config space back so we can restore after reset */ read_msi_msg(virq, &msg); diff --git a/trunk/arch/powerpc/platforms/pseries/setup.c b/trunk/arch/powerpc/platforms/pseries/setup.c index c319d04aa799..2a0089a2c829 100644 --- a/trunk/arch/powerpc/platforms/pseries/setup.c +++ b/trunk/arch/powerpc/platforms/pseries/setup.c @@ -114,7 +114,7 @@ static void __init fwnmi_init(void) static void pseries_8259_cascade(unsigned int irq, struct irq_desc *desc) { - struct irq_chip *chip = irq_desc_get_chip(desc); + struct irq_chip *chip = get_irq_desc_chip(desc); unsigned int cascade_irq = i8259_irq(); if (cascade_irq != NO_IRQ) @@ -169,7 +169,7 @@ static void __init pseries_setup_i8259_cascade(void) printk(KERN_DEBUG "pic: PCI 8259 intack at 0x%016lx\n", intack); i8259_init(found, intack); of_node_put(found); - irq_set_chained_handler(cascade, pseries_8259_cascade); + set_irq_chained_handler(cascade, pseries_8259_cascade); } static void __init pseries_mpic_init_IRQ(void) diff --git a/trunk/arch/powerpc/platforms/pseries/xics.c b/trunk/arch/powerpc/platforms/pseries/xics.c index 6c1e638f0ce9..01fea46c0335 100644 --- a/trunk/arch/powerpc/platforms/pseries/xics.c +++ b/trunk/arch/powerpc/platforms/pseries/xics.c @@ -470,8 +470,8 @@ static int xics_host_map(struct irq_host *h, unsigned int virq, /* Insert the interrupt mapping into the radix tree for fast lookup */ irq_radix_revmap_insert(xics_host, virq, hw); - irq_set_status_flags(virq, IRQ_LEVEL); - irq_set_chip_and_handler(virq, xics_irq_chip, handle_fasteoi_irq); + irq_to_desc(virq)->status |= IRQ_LEVEL; + set_irq_chip_and_handler(virq, xics_irq_chip, handle_fasteoi_irq); return 0; } @@ -600,7 +600,7 @@ static void xics_request_ipi(void) * IPIs are marked IRQF_DISABLED as they must run with irqs * disabled */ - irq_set_handler(ipi, handle_percpu_irq); + set_irq_handler(ipi, handle_percpu_irq); if (firmware_has_feature(FW_FEATURE_LPAR)) rc = request_irq(ipi, xics_ipi_action_lpar, IRQF_DISABLED|IRQF_PERCPU, "IPI", NULL); @@ -912,7 +912,7 @@ void xics_migrate_irqs_away(void) if (desc == NULL || desc->action == NULL) continue; - chip = irq_desc_get_chip(desc); + chip = get_irq_desc_chip(desc); if (chip == NULL || chip->irq_set_affinity == NULL) continue; diff --git a/trunk/arch/powerpc/sysdev/cpm1.c b/trunk/arch/powerpc/sysdev/cpm1.c index 8b5aba263323..0476bcc7c3e1 100644 --- a/trunk/arch/powerpc/sysdev/cpm1.c +++ b/trunk/arch/powerpc/sysdev/cpm1.c @@ -103,8 +103,8 @@ static int cpm_pic_host_map(struct irq_host *h, unsigned int virq, { pr_debug("cpm_pic_host_map(%d, 0x%lx)\n", virq, hw); - irq_set_status_flags(virq, IRQ_LEVEL); - irq_set_chip_and_handler(virq, &cpm_pic, handle_fasteoi_irq); + irq_to_desc(virq)->status |= IRQ_LEVEL; + set_irq_chip_and_handler(virq, &cpm_pic, handle_fasteoi_irq); return 0; } diff --git a/trunk/arch/powerpc/sysdev/cpm2_pic.c b/trunk/arch/powerpc/sysdev/cpm2_pic.c index 5495c1be472b..473032556715 100644 --- a/trunk/arch/powerpc/sysdev/cpm2_pic.c +++ b/trunk/arch/powerpc/sysdev/cpm2_pic.c @@ -115,25 +115,32 @@ static void cpm2_ack(struct irq_data *d) static void cpm2_end_irq(struct irq_data *d) { + struct irq_desc *desc; int bit, word; unsigned int irq_nr = virq_to_hw(d->irq); - bit = irq_to_siubit[irq_nr]; - word = irq_to_siureg[irq_nr]; + desc = irq_to_desc(irq_nr); + if (!(desc->status & (IRQ_DISABLED|IRQ_INPROGRESS)) + && desc->action) { - ppc_cached_irq_mask[word] |= 1 << bit; - out_be32(&cpm2_intctl->ic_simrh + word, ppc_cached_irq_mask[word]); + bit = irq_to_siubit[irq_nr]; + word = irq_to_siureg[irq_nr]; - /* - * Work around large numbers of spurious IRQs on PowerPC 82xx - * systems. - */ - mb(); + ppc_cached_irq_mask[word] |= 1 << bit; + out_be32(&cpm2_intctl->ic_simrh + word, ppc_cached_irq_mask[word]); + + /* + * Work around large numbers of spurious IRQs on PowerPC 82xx + * systems. + */ + mb(); + } } static int cpm2_set_irq_type(struct irq_data *d, unsigned int flow_type) { unsigned int src = virq_to_hw(d->irq); + struct irq_desc *desc = irq_to_desc(d->irq); unsigned int vold, vnew, edibit; /* Port C interrupts are either IRQ_TYPE_EDGE_FALLING or @@ -155,11 +162,13 @@ static int cpm2_set_irq_type(struct irq_data *d, unsigned int flow_type) goto err_sense; } - irqd_set_trigger_type(d, flow_type); - if (flow_type & IRQ_TYPE_LEVEL_LOW) - __irq_set_handler_locked(d->irq, handle_level_irq); - else - __irq_set_handler_locked(d->irq, handle_edge_irq); + desc->status &= ~(IRQ_TYPE_SENSE_MASK | IRQ_LEVEL); + desc->status |= flow_type & IRQ_TYPE_SENSE_MASK; + if (flow_type & IRQ_TYPE_LEVEL_LOW) { + desc->status |= IRQ_LEVEL; + desc->handle_irq = handle_level_irq; + } else + desc->handle_irq = handle_edge_irq; /* internal IRQ senses are LEVEL_LOW * EXT IRQ and Port C IRQ senses are programmable @@ -170,8 +179,7 @@ static int cpm2_set_irq_type(struct irq_data *d, unsigned int flow_type) if (src >= CPM2_IRQ_PORTC15 && src <= CPM2_IRQ_PORTC0) edibit = (31 - (CPM2_IRQ_PORTC0 - src)); else - return (flow_type & IRQ_TYPE_LEVEL_LOW) ? - IRQ_SET_MASK_OK_NOCOPY : -EINVAL; + return (flow_type & IRQ_TYPE_LEVEL_LOW) ? 0 : -EINVAL; vold = in_be32(&cpm2_intctl->ic_siexr); @@ -182,7 +190,7 @@ static int cpm2_set_irq_type(struct irq_data *d, unsigned int flow_type) if (vold != vnew) out_be32(&cpm2_intctl->ic_siexr, vnew); - return IRQ_SET_MASK_OK_NOCOPY; + return 0; err_sense: pr_err("CPM2 PIC: sense type 0x%x not supported\n", flow_type); @@ -196,7 +204,6 @@ static struct irq_chip cpm2_pic = { .irq_ack = cpm2_ack, .irq_eoi = cpm2_end_irq, .irq_set_type = cpm2_set_irq_type, - .flags = IRQCHIP_EOI_IF_HANDLED, }; unsigned int cpm2_get_irq(void) @@ -219,8 +226,8 @@ static int cpm2_pic_host_map(struct irq_host *h, unsigned int virq, { pr_debug("cpm2_pic_host_map(%d, 0x%lx)\n", virq, hw); - irq_set_status_flags(virq, IRQ_LEVEL); - irq_set_chip_and_handler(virq, &cpm2_pic, handle_level_irq); + irq_to_desc(virq)->status |= IRQ_LEVEL; + set_irq_chip_and_handler(virq, &cpm2_pic, handle_level_irq); return 0; } diff --git a/trunk/arch/powerpc/sysdev/fsl_msi.c b/trunk/arch/powerpc/sysdev/fsl_msi.c index d5679dc1e20f..58e09b2833f2 100644 --- a/trunk/arch/powerpc/sysdev/fsl_msi.c +++ b/trunk/arch/powerpc/sysdev/fsl_msi.c @@ -64,10 +64,10 @@ static int fsl_msi_host_map(struct irq_host *h, unsigned int virq, struct fsl_msi *msi_data = h->host_data; struct irq_chip *chip = &fsl_msi_chip; - irq_set_status_flags(virq, IRQ_TYPE_EDGE_FALLING); + irq_to_desc(virq)->status |= IRQ_TYPE_EDGE_FALLING; - irq_set_chip_data(virq, msi_data); - irq_set_chip_and_handler(virq, chip, handle_edge_irq); + set_irq_chip_data(virq, msi_data); + set_irq_chip_and_handler(virq, chip, handle_edge_irq); return 0; } @@ -110,8 +110,8 @@ static void fsl_teardown_msi_irqs(struct pci_dev *pdev) list_for_each_entry(entry, &pdev->msi_list, list) { if (entry->irq == NO_IRQ) continue; - msi_data = irq_get_handler_data(entry->irq); - irq_set_msi_desc(entry->irq, NULL); + msi_data = get_irq_data(entry->irq); + set_irq_msi(entry->irq, NULL); msi_bitmap_free_hwirqs(&msi_data->bitmap, virq_to_hw(entry->irq), 1); irq_dispose_mapping(entry->irq); @@ -168,8 +168,8 @@ static int fsl_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type) rc = -ENOSPC; goto out_free; } - irq_set_handler_data(virq, msi_data); - irq_set_msi_desc(virq, entry); + set_irq_data(virq, msi_data); + set_irq_msi(virq, entry); fsl_compose_msi_msg(pdev, hwirq, &msg, msi_data); write_msi_msg(virq, &msg); @@ -183,8 +183,7 @@ static int fsl_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type) static void fsl_msi_cascade(unsigned int irq, struct irq_desc *desc) { - struct irq_chip *chip = irq_desc_get_chip(desc); - struct irq_data *idata = irq_desc_get_irq_data(desc); + struct irq_chip *chip = get_irq_desc_chip(desc); unsigned int cascade_irq; struct fsl_msi *msi_data; int msir_index = -1; @@ -193,20 +192,20 @@ static void fsl_msi_cascade(unsigned int irq, struct irq_desc *desc) u32 have_shift = 0; struct fsl_msi_cascade_data *cascade_data; - cascade_data = (struct fsl_msi_cascade_data *)irq_get_handler_data(irq); + cascade_data = (struct fsl_msi_cascade_data *)get_irq_data(irq); msi_data = cascade_data->msi_data; raw_spin_lock(&desc->lock); if ((msi_data->feature & FSL_PIC_IP_MASK) == FSL_PIC_IP_IPIC) { if (chip->irq_mask_ack) - chip->irq_mask_ack(idata); + chip->irq_mask_ack(&desc->irq_data); else { - chip->irq_mask(idata); - chip->irq_ack(idata); + chip->irq_mask(&desc->irq_data); + chip->irq_ack(&desc->irq_data); } } - if (unlikely(irqd_irq_inprogress(idata))) + if (unlikely(desc->status & IRQ_INPROGRESS)) goto unlock; msir_index = cascade_data->index; @@ -214,7 +213,7 @@ static void fsl_msi_cascade(unsigned int irq, struct irq_desc *desc) if (msir_index >= NR_MSI_REG) cascade_irq = NO_IRQ; - irqd_set_chained_irq_inprogress(idata); + desc->status |= IRQ_INPROGRESS; switch (msi_data->feature & FSL_PIC_IP_MASK) { case FSL_PIC_IP_MPIC: msir_value = fsl_msi_read(msi_data->msi_regs, @@ -236,15 +235,15 @@ static void fsl_msi_cascade(unsigned int irq, struct irq_desc *desc) have_shift += intr_index + 1; msir_value = msir_value >> (intr_index + 1); } - irqd_clr_chained_irq_inprogress(idata); + desc->status &= ~IRQ_INPROGRESS; switch (msi_data->feature & FSL_PIC_IP_MASK) { case FSL_PIC_IP_MPIC: - chip->irq_eoi(idata); + chip->irq_eoi(&desc->irq_data); break; case FSL_PIC_IP_IPIC: - if (!irqd_irq_disabled(idata) && chip->irq_unmask) - chip->irq_unmask(idata); + if (!(desc->status & IRQ_DISABLED) && chip->irq_unmask) + chip->irq_unmask(&desc->irq_data); break; } unlock: @@ -262,7 +261,7 @@ static int fsl_of_msi_remove(struct platform_device *ofdev) for (i = 0; i < NR_MSI_REG; i++) { virq = msi->msi_virqs[i]; if (virq != NO_IRQ) { - cascade_data = irq_get_handler_data(virq); + cascade_data = get_irq_data(virq); kfree(cascade_data); irq_dispose_mapping(virq); } @@ -298,8 +297,8 @@ static int __devinit fsl_msi_setup_hwirq(struct fsl_msi *msi, msi->msi_virqs[irq_index] = virt_msir; cascade_data->index = offset + irq_index; cascade_data->msi_data = msi; - irq_set_handler_data(virt_msir, cascade_data); - irq_set_chained_handler(virt_msir, fsl_msi_cascade); + set_irq_data(virt_msir, cascade_data); + set_irq_chained_handler(virt_msir, fsl_msi_cascade); return 0; } diff --git a/trunk/arch/powerpc/sysdev/i8259.c b/trunk/arch/powerpc/sysdev/i8259.c index 142770cb84b6..aeda4c8d0a0a 100644 --- a/trunk/arch/powerpc/sysdev/i8259.c +++ b/trunk/arch/powerpc/sysdev/i8259.c @@ -175,13 +175,13 @@ static int i8259_host_map(struct irq_host *h, unsigned int virq, /* We block the internal cascade */ if (hw == 2) - irq_set_status_flags(virq, IRQ_NOREQUEST); + irq_to_desc(virq)->status |= IRQ_NOREQUEST; /* We use the level handler only for now, we might want to * be more cautious here but that works for now */ - irq_set_status_flags(virq, IRQ_LEVEL); - irq_set_chip_and_handler(virq, &i8259_pic, handle_level_irq); + irq_to_desc(virq)->status |= IRQ_LEVEL; + set_irq_chip_and_handler(virq, &i8259_pic, handle_level_irq); return 0; } @@ -191,7 +191,7 @@ static void i8259_host_unmap(struct irq_host *h, unsigned int virq) i8259_mask_irq(irq_get_irq_data(virq)); /* remove chip and handler */ - irq_set_chip_and_handler(virq, NULL, NULL); + set_irq_chip_and_handler(virq, NULL, NULL); /* Make sure it's completed */ synchronize_irq(virq); diff --git a/trunk/arch/powerpc/sysdev/ipic.c b/trunk/arch/powerpc/sysdev/ipic.c index fa438be962b7..497047dc986e 100644 --- a/trunk/arch/powerpc/sysdev/ipic.c +++ b/trunk/arch/powerpc/sysdev/ipic.c @@ -605,6 +605,7 @@ static int ipic_set_irq_type(struct irq_data *d, unsigned int flow_type) { struct ipic *ipic = ipic_from_irq(d->irq); unsigned int src = ipic_irq_to_hw(d->irq); + struct irq_desc *desc = irq_to_desc(d->irq); unsigned int vold, vnew, edibit; if (flow_type == IRQ_TYPE_NONE) @@ -622,16 +623,17 @@ static int ipic_set_irq_type(struct irq_data *d, unsigned int flow_type) printk(KERN_ERR "ipic: edge sense not supported on internal " "interrupts\n"); return -EINVAL; - } - irqd_set_trigger_type(d, flow_type); + desc->status &= ~(IRQ_TYPE_SENSE_MASK | IRQ_LEVEL); + desc->status |= flow_type & IRQ_TYPE_SENSE_MASK; if (flow_type & IRQ_TYPE_LEVEL_LOW) { - __irq_set_handler_locked(d->irq, handle_level_irq); - d->chip = &ipic_level_irq_chip; + desc->status |= IRQ_LEVEL; + desc->handle_irq = handle_level_irq; + desc->irq_data.chip = &ipic_level_irq_chip; } else { - __irq_set_handler_locked(d->irq, handle_edge_irq); - d->chip = &ipic_edge_irq_chip; + desc->handle_irq = handle_edge_irq; + desc->irq_data.chip = &ipic_edge_irq_chip; } /* only EXT IRQ senses are programmable on ipic @@ -653,7 +655,7 @@ static int ipic_set_irq_type(struct irq_data *d, unsigned int flow_type) } if (vold != vnew) ipic_write(ipic->regs, IPIC_SECNR, vnew); - return IRQ_SET_MASK_OK_NOCOPY; + return 0; } /* level interrupts and edge interrupts have different ack operations */ @@ -685,11 +687,11 @@ static int ipic_host_map(struct irq_host *h, unsigned int virq, { struct ipic *ipic = h->host_data; - irq_set_chip_data(virq, ipic); - irq_set_chip_and_handler(virq, &ipic_level_irq_chip, handle_level_irq); + set_irq_chip_data(virq, ipic); + set_irq_chip_and_handler(virq, &ipic_level_irq_chip, handle_level_irq); /* Set default irq type */ - irq_set_irq_type(virq, IRQ_TYPE_NONE); + set_irq_type(virq, IRQ_TYPE_NONE); return 0; } diff --git a/trunk/arch/powerpc/sysdev/mpc8xx_pic.c b/trunk/arch/powerpc/sysdev/mpc8xx_pic.c index f550e23632f8..1a75a7fb4a99 100644 --- a/trunk/arch/powerpc/sysdev/mpc8xx_pic.c +++ b/trunk/arch/powerpc/sysdev/mpc8xx_pic.c @@ -72,6 +72,13 @@ static void mpc8xx_end_irq(struct irq_data *d) static int mpc8xx_set_irq_type(struct irq_data *d, unsigned int flow_type) { + struct irq_desc *desc = irq_to_desc(d->irq); + + desc->status &= ~(IRQ_TYPE_SENSE_MASK | IRQ_LEVEL); + desc->status |= flow_type & IRQ_TYPE_SENSE_MASK; + if (flow_type & (IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_LEVEL_LOW)) + desc->status |= IRQ_LEVEL; + if (flow_type & IRQ_TYPE_EDGE_FALLING) { irq_hw_number_t hw = (unsigned int)irq_map[d->irq].hwirq; unsigned int siel = in_be32(&siu_reg->sc_siel); @@ -80,7 +87,7 @@ static int mpc8xx_set_irq_type(struct irq_data *d, unsigned int flow_type) if ((hw & 1) == 0) { siel |= (0x80000000 >> hw); out_be32(&siu_reg->sc_siel, siel); - __irq_set_handler_locked(irq, handle_edge_irq); + desc->handle_irq = handle_edge_irq; } } return 0; @@ -117,7 +124,7 @@ static int mpc8xx_pic_host_map(struct irq_host *h, unsigned int virq, pr_debug("mpc8xx_pic_host_map(%d, 0x%lx)\n", virq, hw); /* Set default irq handle */ - irq_set_chip_and_handler(virq, &mpc8xx_pic, handle_level_irq); + set_irq_chip_and_handler(virq, &mpc8xx_pic, handle_level_irq); return 0; } diff --git a/trunk/arch/powerpc/sysdev/mpc8xxx_gpio.c b/trunk/arch/powerpc/sysdev/mpc8xxx_gpio.c index 0892a2841c2b..232e701245d7 100644 --- a/trunk/arch/powerpc/sysdev/mpc8xxx_gpio.c +++ b/trunk/arch/powerpc/sysdev/mpc8xxx_gpio.c @@ -145,7 +145,7 @@ static int mpc8xxx_gpio_to_irq(struct gpio_chip *gc, unsigned offset) static void mpc8xxx_gpio_irq_cascade(unsigned int irq, struct irq_desc *desc) { - struct mpc8xxx_gpio_chip *mpc8xxx_gc = irq_desc_get_handler_data(desc); + struct mpc8xxx_gpio_chip *mpc8xxx_gc = get_irq_desc_data(desc); struct of_mm_gpio_chip *mm = &mpc8xxx_gc->mm_gc; unsigned int mask; @@ -278,9 +278,9 @@ static int mpc8xxx_gpio_irq_map(struct irq_host *h, unsigned int virq, if (mpc8xxx_gc->of_dev_id_data) mpc8xxx_irq_chip.irq_set_type = mpc8xxx_gc->of_dev_id_data; - irq_set_chip_data(virq, h->host_data); - irq_set_chip_and_handler(virq, &mpc8xxx_irq_chip, handle_level_irq); - irq_set_irq_type(virq, IRQ_TYPE_NONE); + set_irq_chip_data(virq, h->host_data); + set_irq_chip_and_handler(virq, &mpc8xxx_irq_chip, handle_level_irq); + set_irq_type(virq, IRQ_TYPE_NONE); return 0; } @@ -369,8 +369,8 @@ static void __init mpc8xxx_add_controller(struct device_node *np) out_be32(mm_gc->regs + GPIO_IER, 0xffffffff); out_be32(mm_gc->regs + GPIO_IMR, 0); - irq_set_handler_data(hwirq, mpc8xxx_gc); - irq_set_chained_handler(hwirq, mpc8xxx_gpio_irq_cascade); + set_irq_data(hwirq, mpc8xxx_gc); + set_irq_chained_handler(hwirq, mpc8xxx_gpio_irq_cascade); skip_irq: return; diff --git a/trunk/arch/powerpc/sysdev/mpic.c b/trunk/arch/powerpc/sysdev/mpic.c index f91c065bed5a..0f7c6718d261 100644 --- a/trunk/arch/powerpc/sysdev/mpic.c +++ b/trunk/arch/powerpc/sysdev/mpic.c @@ -361,7 +361,7 @@ static inline void mpic_ht_end_irq(struct mpic *mpic, unsigned int source) } static void mpic_startup_ht_interrupt(struct mpic *mpic, unsigned int source, - bool level) + unsigned int irqflags) { struct mpic_irq_fixup *fixup = &mpic->fixups[source]; unsigned long flags; @@ -370,14 +370,14 @@ static void mpic_startup_ht_interrupt(struct mpic *mpic, unsigned int source, if (fixup->base == NULL) return; - DBG("startup_ht_interrupt(0x%x) index: %d\n", - source, fixup->index); + DBG("startup_ht_interrupt(0x%x, 0x%x) index: %d\n", + source, irqflags, fixup->index); raw_spin_lock_irqsave(&mpic->fixup_lock, flags); /* Enable and configure */ writeb(0x10 + 2 * fixup->index, fixup->base + 2); tmp = readl(fixup->base + 4); tmp &= ~(0x23U); - if (level) + if (irqflags & IRQ_LEVEL) tmp |= 0x22; writel(tmp, fixup->base + 4); raw_spin_unlock_irqrestore(&mpic->fixup_lock, flags); @@ -389,7 +389,8 @@ static void mpic_startup_ht_interrupt(struct mpic *mpic, unsigned int source, #endif } -static void mpic_shutdown_ht_interrupt(struct mpic *mpic, unsigned int source) +static void mpic_shutdown_ht_interrupt(struct mpic *mpic, unsigned int source, + unsigned int irqflags) { struct mpic_irq_fixup *fixup = &mpic->fixups[source]; unsigned long flags; @@ -398,7 +399,7 @@ static void mpic_shutdown_ht_interrupt(struct mpic *mpic, unsigned int source) if (fixup->base == NULL) return; - DBG("shutdown_ht_interrupt(0x%x)\n", source); + DBG("shutdown_ht_interrupt(0x%x, 0x%x)\n", source, irqflags); /* Disable */ raw_spin_lock_irqsave(&mpic->fixup_lock, flags); @@ -615,7 +616,7 @@ static struct mpic *mpic_find(unsigned int irq) if (irq < NUM_ISA_INTERRUPTS) return NULL; - return irq_get_chip_data(irq); + return get_irq_chip_data(irq); } /* Determine if the linux irq is an IPI */ @@ -649,7 +650,7 @@ static inline struct mpic * mpic_from_ipi(struct irq_data *d) /* Get the mpic structure from the irq number */ static inline struct mpic * mpic_from_irq(unsigned int irq) { - return irq_get_chip_data(irq); + return get_irq_chip_data(irq); } /* Get the mpic structure from the irq data */ @@ -737,7 +738,7 @@ static void mpic_unmask_ht_irq(struct irq_data *d) mpic_unmask_irq(d); - if (irqd_is_level_type(d)) + if (irq_to_desc(d->irq)->status & IRQ_LEVEL) mpic_ht_end_irq(mpic, src); } @@ -747,7 +748,7 @@ static unsigned int mpic_startup_ht_irq(struct irq_data *d) unsigned int src = mpic_irq_to_hw(d->irq); mpic_unmask_irq(d); - mpic_startup_ht_interrupt(mpic, src, irqd_is_level_type(d)); + mpic_startup_ht_interrupt(mpic, src, irq_to_desc(d->irq)->status); return 0; } @@ -757,7 +758,7 @@ static void mpic_shutdown_ht_irq(struct irq_data *d) struct mpic *mpic = mpic_from_irq_data(d); unsigned int src = mpic_irq_to_hw(d->irq); - mpic_shutdown_ht_interrupt(mpic, src); + mpic_shutdown_ht_interrupt(mpic, src, irq_to_desc(d->irq)->status); mpic_mask_irq(d); } @@ -774,7 +775,7 @@ static void mpic_end_ht_irq(struct irq_data *d) * latched another edge interrupt coming in anyway */ - if (irqd_is_level_type(d)) + if (irq_to_desc(d->irq)->status & IRQ_LEVEL) mpic_ht_end_irq(mpic, src); mpic_eoi(mpic); } @@ -863,6 +864,7 @@ int mpic_set_irq_type(struct irq_data *d, unsigned int flow_type) { struct mpic *mpic = mpic_from_irq_data(d); unsigned int src = mpic_irq_to_hw(d->irq); + struct irq_desc *desc = irq_to_desc(d->irq); unsigned int vecpri, vold, vnew; DBG("mpic: set_irq_type(mpic:@%p,virq:%d,src:0x%x,type:0x%x)\n", @@ -877,7 +879,10 @@ int mpic_set_irq_type(struct irq_data *d, unsigned int flow_type) if (flow_type == IRQ_TYPE_NONE) flow_type = IRQ_TYPE_LEVEL_LOW; - irqd_set_trigger_type(d, flow_type); + desc->status &= ~(IRQ_TYPE_SENSE_MASK | IRQ_LEVEL); + desc->status |= flow_type & IRQ_TYPE_SENSE_MASK; + if (flow_type & (IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_LEVEL_LOW)) + desc->status |= IRQ_LEVEL; if (mpic_is_ht_interrupt(mpic, src)) vecpri = MPIC_VECPRI_POLARITY_POSITIVE | @@ -892,7 +897,7 @@ int mpic_set_irq_type(struct irq_data *d, unsigned int flow_type) if (vold != vnew) mpic_irq_write(src, MPIC_INFO(IRQ_VECTOR_PRI), vnew); - return IRQ_SET_MASK_OK_NOCOPY;; + return 0; } void mpic_set_vector(unsigned int virq, unsigned int vector) @@ -978,8 +983,8 @@ static int mpic_host_map(struct irq_host *h, unsigned int virq, WARN_ON(!(mpic->flags & MPIC_PRIMARY)); DBG("mpic: mapping as IPI\n"); - irq_set_chip_data(virq, mpic); - irq_set_chip_and_handler(virq, &mpic->hc_ipi, + set_irq_chip_data(virq, mpic); + set_irq_chip_and_handler(virq, &mpic->hc_ipi, handle_percpu_irq); return 0; } @@ -1001,11 +1006,11 @@ static int mpic_host_map(struct irq_host *h, unsigned int virq, DBG("mpic: mapping to irq chip @%p\n", chip); - irq_set_chip_data(virq, mpic); - irq_set_chip_and_handler(virq, chip, handle_fasteoi_irq); + set_irq_chip_data(virq, mpic); + set_irq_chip_and_handler(virq, chip, handle_fasteoi_irq); /* Set default irq type */ - irq_set_irq_type(virq, IRQ_TYPE_NONE); + set_irq_type(virq, IRQ_TYPE_NONE); /* If the MPIC was reset, then all vectors have already been * initialized. Otherwise, a per source lazy initialization diff --git a/trunk/arch/powerpc/sysdev/mpic_pasemi_msi.c b/trunk/arch/powerpc/sysdev/mpic_pasemi_msi.c index 38e62382070c..0b7794acfce1 100644 --- a/trunk/arch/powerpc/sysdev/mpic_pasemi_msi.c +++ b/trunk/arch/powerpc/sysdev/mpic_pasemi_msi.c @@ -81,7 +81,7 @@ static void pasemi_msi_teardown_msi_irqs(struct pci_dev *pdev) if (entry->irq == NO_IRQ) continue; - irq_set_msi_desc(entry->irq, NULL); + set_irq_msi(entry->irq, NULL); msi_bitmap_free_hwirqs(&msi_mpic->msi_bitmap, virq_to_hw(entry->irq), ALLOC_CHUNK); irq_dispose_mapping(entry->irq); @@ -131,9 +131,9 @@ static int pasemi_msi_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type) */ mpic_set_vector(virq, 0); - irq_set_msi_desc(virq, entry); - irq_set_chip(virq, &mpic_pasemi_msi_chip); - irq_set_irq_type(virq, IRQ_TYPE_EDGE_RISING); + set_irq_msi(virq, entry); + 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%x) " \ "addr 0x%x\n", virq, hwirq, msg.address_lo); diff --git a/trunk/arch/powerpc/sysdev/mpic_u3msi.c b/trunk/arch/powerpc/sysdev/mpic_u3msi.c index 9a7aa0ed9c1c..71900ac78270 100644 --- a/trunk/arch/powerpc/sysdev/mpic_u3msi.c +++ b/trunk/arch/powerpc/sysdev/mpic_u3msi.c @@ -129,7 +129,7 @@ static void u3msi_teardown_msi_irqs(struct pci_dev *pdev) if (entry->irq == NO_IRQ) continue; - irq_set_msi_desc(entry->irq, NULL); + set_irq_msi(entry->irq, NULL); msi_bitmap_free_hwirqs(&msi_mpic->msi_bitmap, virq_to_hw(entry->irq), 1); irq_dispose_mapping(entry->irq); @@ -166,9 +166,9 @@ static int u3msi_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type) return -ENOSPC; } - irq_set_msi_desc(virq, entry); - irq_set_chip(virq, &mpic_u3msi_chip); - irq_set_irq_type(virq, IRQ_TYPE_EDGE_RISING); + set_irq_msi(virq, entry); + set_irq_chip(virq, &mpic_u3msi_chip); + set_irq_type(virq, IRQ_TYPE_EDGE_RISING); pr_debug("u3msi: allocated virq 0x%x (hw 0x%x) addr 0x%lx\n", virq, hwirq, (unsigned long)addr); diff --git a/trunk/arch/powerpc/sysdev/mv64x60_pic.c b/trunk/arch/powerpc/sysdev/mv64x60_pic.c index e9c633c7c083..bc61ebb8987c 100644 --- a/trunk/arch/powerpc/sysdev/mv64x60_pic.c +++ b/trunk/arch/powerpc/sysdev/mv64x60_pic.c @@ -213,12 +213,11 @@ static int mv64x60_host_map(struct irq_host *h, unsigned int virq, { int level1; - irq_set_status_flags(virq, IRQ_LEVEL); + irq_to_desc(virq)->status |= IRQ_LEVEL; level1 = (hwirq & MV64x60_LEVEL1_MASK) >> MV64x60_LEVEL1_OFFSET; BUG_ON(level1 > MV64x60_LEVEL1_GPP); - irq_set_chip_and_handler(virq, mv64x60_chips[level1], - handle_level_irq); + set_irq_chip_and_handler(virq, mv64x60_chips[level1], handle_level_irq); return 0; } diff --git a/trunk/arch/powerpc/sysdev/qe_lib/qe_ic.c b/trunk/arch/powerpc/sysdev/qe_lib/qe_ic.c index 832d6924ad1c..8c9ded8ea07c 100644 --- a/trunk/arch/powerpc/sysdev/qe_lib/qe_ic.c +++ b/trunk/arch/powerpc/sysdev/qe_lib/qe_ic.c @@ -189,7 +189,7 @@ static inline void qe_ic_write(volatile __be32 __iomem * base, unsigned int reg static inline struct qe_ic *qe_ic_from_irq(unsigned int virq) { - return irq_get_chip_data(virq); + return get_irq_chip_data(virq); } static inline struct qe_ic *qe_ic_from_irq_data(struct irq_data *d) @@ -267,10 +267,10 @@ static int qe_ic_host_map(struct irq_host *h, unsigned int virq, /* Default chip */ chip = &qe_ic->hc_irq; - irq_set_chip_data(virq, qe_ic); - irq_set_status_flags(virq, IRQ_LEVEL); + set_irq_chip_data(virq, qe_ic); + irq_to_desc(virq)->status |= IRQ_LEVEL; - irq_set_chip_and_handler(virq, chip, handle_level_irq); + set_irq_chip_and_handler(virq, chip, handle_level_irq); return 0; } @@ -386,13 +386,13 @@ void __init qe_ic_init(struct device_node *node, unsigned int flags, qe_ic_write(qe_ic->regs, QEIC_CICR, temp); - irq_set_handler_data(qe_ic->virq_low, qe_ic); - irq_set_chained_handler(qe_ic->virq_low, low_handler); + set_irq_data(qe_ic->virq_low, qe_ic); + set_irq_chained_handler(qe_ic->virq_low, low_handler); if (qe_ic->virq_high != NO_IRQ && qe_ic->virq_high != qe_ic->virq_low) { - irq_set_handler_data(qe_ic->virq_high, qe_ic); - irq_set_chained_handler(qe_ic->virq_high, high_handler); + set_irq_data(qe_ic->virq_high, qe_ic); + set_irq_chained_handler(qe_ic->virq_high, high_handler); } } diff --git a/trunk/arch/powerpc/sysdev/tsi108_pci.c b/trunk/arch/powerpc/sysdev/tsi108_pci.c index 4d18658116e5..02c91db90037 100644 --- a/trunk/arch/powerpc/sysdev/tsi108_pci.c +++ b/trunk/arch/powerpc/sysdev/tsi108_pci.c @@ -391,8 +391,8 @@ static int pci_irq_host_map(struct irq_host *h, unsigned int virq, DBG("%s(%d, 0x%lx)\n", __func__, virq, hw); if ((virq >= 1) && (virq <= 4)){ irq = virq + IRQ_PCI_INTAD_BASE - 1; - irq_set_status_flags(irq, IRQ_LEVEL); - irq_set_chip(irq, &tsi108_pci_irq); + irq_to_desc(irq)->status |= IRQ_LEVEL; + set_irq_chip(irq, &tsi108_pci_irq); } return 0; } @@ -431,7 +431,7 @@ void __init tsi108_pci_int_init(struct device_node *node) void tsi108_irq_cascade(unsigned int irq, struct irq_desc *desc) { - struct irq_chip *chip = irq_desc_get_chip(desc); + struct irq_chip *chip = get_irq_desc_chip(desc); unsigned int cascade_irq = get_pci_source(); if (cascade_irq != NO_IRQ) diff --git a/trunk/arch/powerpc/sysdev/uic.c b/trunk/arch/powerpc/sysdev/uic.c index 5d9138516628..835f7958b237 100644 --- a/trunk/arch/powerpc/sysdev/uic.c +++ b/trunk/arch/powerpc/sysdev/uic.c @@ -57,6 +57,7 @@ struct uic { static void uic_unmask_irq(struct irq_data *d) { + struct irq_desc *desc = irq_to_desc(d->irq); struct uic *uic = irq_data_get_irq_chip_data(d); unsigned int src = uic_irq_to_hw(d->irq); unsigned long flags; @@ -65,7 +66,7 @@ static void uic_unmask_irq(struct irq_data *d) sr = 1 << (31-src); spin_lock_irqsave(&uic->lock, flags); /* ack level-triggered interrupts here */ - if (irqd_is_level_type(d)) + if (desc->status & IRQ_LEVEL) mtdcr(uic->dcrbase + UIC_SR, sr); er = mfdcr(uic->dcrbase + UIC_ER); er |= sr; @@ -100,6 +101,7 @@ static void uic_ack_irq(struct irq_data *d) static void uic_mask_ack_irq(struct irq_data *d) { + struct irq_desc *desc = irq_to_desc(d->irq); struct uic *uic = irq_data_get_irq_chip_data(d); unsigned int src = uic_irq_to_hw(d->irq); unsigned long flags; @@ -118,7 +120,7 @@ static void uic_mask_ack_irq(struct irq_data *d) * level interrupts are ack'ed after the actual * isr call in the uic_unmask_irq() */ - if (!irqd_is_level_type(d)) + if (!(desc->status & IRQ_LEVEL)) mtdcr(uic->dcrbase + UIC_SR, sr); spin_unlock_irqrestore(&uic->lock, flags); } @@ -127,6 +129,7 @@ static int uic_set_irq_type(struct irq_data *d, unsigned int flow_type) { struct uic *uic = irq_data_get_irq_chip_data(d); unsigned int src = uic_irq_to_hw(d->irq); + struct irq_desc *desc = irq_to_desc(d->irq); unsigned long flags; int trigger, polarity; u32 tr, pr, mask; @@ -163,6 +166,11 @@ static int uic_set_irq_type(struct irq_data *d, unsigned int flow_type) mtdcr(uic->dcrbase + UIC_PR, pr); mtdcr(uic->dcrbase + UIC_TR, tr); + desc->status &= ~(IRQ_TYPE_SENSE_MASK | IRQ_LEVEL); + desc->status |= flow_type & IRQ_TYPE_SENSE_MASK; + if (!trigger) + desc->status |= IRQ_LEVEL; + spin_unlock_irqrestore(&uic->lock, flags); return 0; @@ -182,13 +190,13 @@ static int uic_host_map(struct irq_host *h, unsigned int virq, { struct uic *uic = h->host_data; - irq_set_chip_data(virq, uic); + set_irq_chip_data(virq, uic); /* Despite the name, handle_level_irq() works for both level * and edge irqs on UIC. FIXME: check this is correct */ - irq_set_chip_and_handler(virq, &uic_irq_chip, handle_level_irq); + set_irq_chip_and_handler(virq, &uic_irq_chip, handle_level_irq); /* Set default irq type */ - irq_set_irq_type(virq, IRQ_TYPE_NONE); + set_irq_type(virq, IRQ_TYPE_NONE); return 0; } @@ -212,18 +220,17 @@ static struct irq_host_ops uic_host_ops = { void uic_irq_cascade(unsigned int virq, struct irq_desc *desc) { - struct irq_chip *chip = irq_desc_get_chip(desc); - struct irq_data *idata = irq_desc_get_irq_data(desc); - struct uic *uic = irq_get_handler_data(virq); + struct irq_chip *chip = get_irq_desc_chip(desc); + struct uic *uic = get_irq_data(virq); u32 msr; int src; int subvirq; raw_spin_lock(&desc->lock); - if (irqd_is_level_type(idata)) - chip->irq_mask(idata); + if (desc->status & IRQ_LEVEL) + chip->irq_mask(&desc->irq_data); else - chip->irq_mask_ack(idata); + chip->irq_mask_ack(&desc->irq_data); raw_spin_unlock(&desc->lock); msr = mfdcr(uic->dcrbase + UIC_MSR); @@ -237,10 +244,10 @@ void uic_irq_cascade(unsigned int virq, struct irq_desc *desc) uic_irq_ret: raw_spin_lock(&desc->lock); - if (irqd_is_level_type(idata)) - chip->irq_ack(idata); - if (!irqd_irq_disabled(idata) && chip->irq_unmask) - chip->irq_unmask(idata); + if (desc->status & IRQ_LEVEL) + chip->irq_ack(&desc->irq_data); + if (!(desc->status & IRQ_DISABLED) && chip->irq_unmask) + chip->irq_unmask(&desc->irq_data); raw_spin_unlock(&desc->lock); } @@ -329,8 +336,8 @@ void __init uic_init_tree(void) cascade_virq = irq_of_parse_and_map(np, 0); - irq_set_handler_data(cascade_virq, uic); - irq_set_chained_handler(cascade_virq, uic_irq_cascade); + set_irq_data(cascade_virq, uic); + set_irq_chained_handler(cascade_virq, uic_irq_cascade); /* FIXME: setup critical cascade?? */ } diff --git a/trunk/arch/powerpc/sysdev/xilinx_intc.c b/trunk/arch/powerpc/sysdev/xilinx_intc.c index 0a13fc19e287..7436f3ed4df6 100644 --- a/trunk/arch/powerpc/sysdev/xilinx_intc.c +++ b/trunk/arch/powerpc/sysdev/xilinx_intc.c @@ -79,6 +79,12 @@ static void xilinx_intc_mask(struct irq_data *d) static int xilinx_intc_set_type(struct irq_data *d, unsigned int flow_type) { + struct irq_desc *desc = irq_to_desc(d->irq); + + desc->status &= ~(IRQ_TYPE_SENSE_MASK | IRQ_LEVEL); + desc->status |= flow_type & IRQ_TYPE_SENSE_MASK; + if (flow_type & (IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_LEVEL_LOW)) + desc->status |= IRQ_LEVEL; return 0; } @@ -164,15 +170,15 @@ static int xilinx_intc_xlate(struct irq_host *h, struct device_node *ct, static int xilinx_intc_map(struct irq_host *h, unsigned int virq, irq_hw_number_t irq) { - irq_set_chip_data(virq, h->host_data); + set_irq_chip_data(virq, h->host_data); if (xilinx_intc_typetable[irq] == IRQ_TYPE_LEVEL_HIGH || xilinx_intc_typetable[irq] == IRQ_TYPE_LEVEL_LOW) { - irq_set_chip_and_handler(virq, &xilinx_intc_level_irqchip, - handle_level_irq); + set_irq_chip_and_handler(virq, &xilinx_intc_level_irqchip, + handle_level_irq); } else { - irq_set_chip_and_handler(virq, &xilinx_intc_edge_irqchip, - handle_edge_irq); + set_irq_chip_and_handler(virq, &xilinx_intc_edge_irqchip, + handle_edge_irq); } return 0; } @@ -223,7 +229,7 @@ int xilinx_intc_get_irq(void) */ static void xilinx_i8259_cascade(unsigned int irq, struct irq_desc *desc) { - struct irq_chip *chip = irq_desc_get_chip(desc); + struct irq_chip *chip = get_irq_desc_chip(desc); unsigned int cascade_irq = i8259_irq(); if (cascade_irq) @@ -250,7 +256,7 @@ static void __init xilinx_i8259_setup_cascade(void) } i8259_init(cascade_node, 0); - irq_set_chained_handler(cascade_irq, xilinx_i8259_cascade); + set_irq_chained_handler(cascade_irq, xilinx_i8259_cascade); /* Program irq 7 (usb/audio), 14/15 (ide) to level sensitive */ /* This looks like a dirty hack to me --gcl */ diff --git a/trunk/arch/score/Kconfig b/trunk/arch/score/Kconfig index 4278bbc032ce..27b2295f41f3 100644 --- a/trunk/arch/score/Kconfig +++ b/trunk/arch/score/Kconfig @@ -3,8 +3,6 @@ menu "Machine selection" config SCORE def_bool y select HAVE_GENERIC_HARDIRQS - select GENERIC_HARDIRQS_NO_DEPRECATED - select GENERIC_IRQ_SHOW choice prompt "System type" diff --git a/trunk/arch/score/include/asm/irqflags.h b/trunk/arch/score/include/asm/irqflags.h index 37c6ac9dd6e8..5c7563891e28 100644 --- a/trunk/arch/score/include/asm/irqflags.h +++ b/trunk/arch/score/include/asm/irqflags.h @@ -29,7 +29,7 @@ static inline unsigned long arch_local_save_flags(void) static inline unsigned long arch_local_irq_save(void) { - unsigned long flags; + unsigned long flags asm volatile( " mfcr r8, cr0 \n" diff --git a/trunk/arch/score/kernel/irq.c b/trunk/arch/score/kernel/irq.c index d4196732c65e..47647dde09ca 100644 --- a/trunk/arch/score/kernel/irq.c +++ b/trunk/arch/score/kernel/irq.c @@ -52,9 +52,9 @@ asmlinkage void do_IRQ(int irq) irq_exit(); } -static void score_mask(struct irq_data *d) +static void score_mask(unsigned int irq_nr) { - unsigned int irq_source = 63 - d->irq; + unsigned int irq_source = 63 - irq_nr; if (irq_source < 32) __raw_writel((__raw_readl(SCORE_PIC + INT_MASKL) | \ @@ -64,9 +64,9 @@ static void score_mask(struct irq_data *d) (1 << (irq_source - 32))), SCORE_PIC + INT_MASKH); } -static void score_unmask(struct irq_data *d) +static void score_unmask(unsigned int irq_nr) { - unsigned int irq_source = 63 - d->irq; + unsigned int irq_source = 63 - irq_nr; if (irq_source < 32) __raw_writel((__raw_readl(SCORE_PIC + INT_MASKL) & \ @@ -78,9 +78,9 @@ static void score_unmask(struct irq_data *d) struct irq_chip score_irq_chip = { .name = "Score7-level", - .irq_mask = score_mask, - .irq_mask_ack = score_mask, - .irq_unmask = score_unmask, + .mask = score_mask, + .mask_ack = score_mask, + .unmask = score_unmask, }; /* @@ -92,7 +92,7 @@ void __init init_IRQ(void) unsigned long target_addr; for (index = 0; index < NR_IRQS; ++index) - irq_set_chip_and_handler(index, &score_irq_chip, + set_irq_chip_and_handler(index, &score_irq_chip, handle_level_irq); for (target_addr = IRQ_VECTOR_BASE_ADDR; @@ -109,3 +109,40 @@ void __init init_IRQ(void) : : "r" (EXCEPTION_VECTOR_BASE_ADDR | \ VECTOR_ADDRESS_OFFSET_MODE16)); } + +/* + * Generic, controller-independent functions: + */ +int show_interrupts(struct seq_file *p, void *v) +{ + int i = *(loff_t *)v, cpu; + struct irqaction *action; + unsigned long flags; + + if (i == 0) { + seq_puts(p, " "); + for_each_online_cpu(cpu) + seq_printf(p, "CPU%d ", cpu); + seq_putc(p, '\n'); + } + + if (i < NR_IRQS) { + spin_lock_irqsave(&irq_desc[i].lock, flags); + action = irq_desc[i].action; + if (!action) + goto unlock; + + seq_printf(p, "%3d: ", i); + seq_printf(p, "%10u ", kstat_irqs(i)); + seq_printf(p, " %8s", irq_desc[i].chip->name ? : "-"); + seq_printf(p, " %s", action->name); + for (action = action->next; action; action = action->next) + seq_printf(p, ", %s", action->name); + + seq_putc(p, '\n'); +unlock: + spin_unlock_irqrestore(&irq_desc[i].lock, flags); + } + + return 0; +} diff --git a/trunk/arch/sh/boards/board-magicpanelr2.c b/trunk/arch/sh/boards/board-magicpanelr2.c index 93f5039099b7..efba450a0518 100644 --- a/trunk/arch/sh/boards/board-magicpanelr2.c +++ b/trunk/arch/sh/boards/board-magicpanelr2.c @@ -388,12 +388,12 @@ static void __init init_mpr2_IRQ(void) { plat_irq_setup_pins(IRQ_MODE_IRQ); /* install handlers for IRQ0-5 */ - irq_set_irq_type(32, IRQ_TYPE_LEVEL_LOW); /* IRQ0 CAN1 */ - irq_set_irq_type(33, IRQ_TYPE_LEVEL_LOW); /* IRQ1 CAN2 */ - irq_set_irq_type(34, IRQ_TYPE_LEVEL_LOW); /* IRQ2 CAN3 */ - irq_set_irq_type(35, IRQ_TYPE_LEVEL_LOW); /* IRQ3 SMSC9115 */ - irq_set_irq_type(36, IRQ_TYPE_EDGE_RISING); /* IRQ4 touchscreen */ - irq_set_irq_type(37, IRQ_TYPE_EDGE_FALLING); /* IRQ5 touchscreen */ + set_irq_type(32, IRQ_TYPE_LEVEL_LOW); /* IRQ0 CAN1 */ + set_irq_type(33, IRQ_TYPE_LEVEL_LOW); /* IRQ1 CAN2 */ + set_irq_type(34, IRQ_TYPE_LEVEL_LOW); /* IRQ2 CAN3 */ + set_irq_type(35, IRQ_TYPE_LEVEL_LOW); /* IRQ3 SMSC9115 */ + set_irq_type(36, IRQ_TYPE_EDGE_RISING); /* IRQ4 touchscreen */ + set_irq_type(37, IRQ_TYPE_EDGE_FALLING); /* IRQ5 touchscreen */ intc_set_priority(32, 13); /* IRQ0 CAN1 */ intc_set_priority(33, 13); /* IRQ0 CAN2 */ diff --git a/trunk/arch/sh/boards/mach-cayman/irq.c b/trunk/arch/sh/boards/mach-cayman/irq.c index 311bcebdbd07..d7ac5af9d102 100644 --- a/trunk/arch/sh/boards/mach-cayman/irq.c +++ b/trunk/arch/sh/boards/mach-cayman/irq.c @@ -149,8 +149,8 @@ void init_cayman_irq(void) } for (i = 0; i < NR_EXT_IRQS; i++) { - irq_set_chip_and_handler(START_EXT_IRQS + i, - &cayman_irq_type, handle_level_irq); + set_irq_chip_and_handler(START_EXT_IRQS + i, &cayman_irq_type, + handle_level_irq); } /* Setup the SMSC interrupt */ diff --git a/trunk/arch/sh/boards/mach-dreamcast/irq.c b/trunk/arch/sh/boards/mach-dreamcast/irq.c index 78cf2ab89d7a..72e7ac9549da 100644 --- a/trunk/arch/sh/boards/mach-dreamcast/irq.c +++ b/trunk/arch/sh/boards/mach-dreamcast/irq.c @@ -161,6 +161,7 @@ void systemasic_irq_init(void) return; } - irq_set_chip_and_handler(i, &systemasic_int, handle_level_irq); + set_irq_chip_and_handler(i, &systemasic_int, + handle_level_irq); } } diff --git a/trunk/arch/sh/boards/mach-ecovec24/setup.c b/trunk/arch/sh/boards/mach-ecovec24/setup.c index 3fbae0d0b6c8..e44480ce2ea8 100644 --- a/trunk/arch/sh/boards/mach-ecovec24/setup.c +++ b/trunk/arch/sh/boards/mach-ecovec24/setup.c @@ -1102,7 +1102,7 @@ static int __init arch_setup(void) /* enable TouchScreen */ i2c_register_board_info(0, &ts_i2c_clients, 1); - irq_set_irq_type(IRQ0, IRQ_TYPE_LEVEL_LOW); + set_irq_type(IRQ0, IRQ_TYPE_LEVEL_LOW); } /* enable CEU0 */ diff --git a/trunk/arch/sh/boards/mach-microdev/irq.c b/trunk/arch/sh/boards/mach-microdev/irq.c index 4fb00369f0e2..c35001fd9032 100644 --- a/trunk/arch/sh/boards/mach-microdev/irq.c +++ b/trunk/arch/sh/boards/mach-microdev/irq.c @@ -117,7 +117,7 @@ static struct irq_chip microdev_irq_type = { static void __init make_microdev_irq(unsigned int irq) { disable_irq_nosync(irq); - irq_set_chip_and_handler(irq, µdev_irq_type, handle_level_irq); + set_irq_chip_and_handler(irq, µdev_irq_type, handle_level_irq); disable_microdev_irq(irq_get_irq_data(irq)); } diff --git a/trunk/arch/sh/boards/mach-se/7206/irq.c b/trunk/arch/sh/boards/mach-se/7206/irq.c index 0db058e709e9..9070d7e60704 100644 --- a/trunk/arch/sh/boards/mach-se/7206/irq.c +++ b/trunk/arch/sh/boards/mach-se/7206/irq.c @@ -92,8 +92,9 @@ static void eoi_se7206_irq(struct irq_data *data) { unsigned short sts0,sts1; unsigned int irq = data->irq; + struct irq_desc *desc = irq_to_desc(irq); - if (!irqd_irq_disabled(data) && !irqd_irq_inprogress(data)) + if (!(desc->status & (IRQ_DISABLED|IRQ_INPROGRESS))) enable_se7206_irq(data); /* FPGA isr clear */ sts0 = __raw_readw(INTSTS0); @@ -125,7 +126,7 @@ static struct irq_chip se7206_irq_chip __read_mostly = { static void make_se7206_irq(unsigned int irq) { disable_irq_nosync(irq); - irq_set_chip_and_handler_name(irq, &se7206_irq_chip, + set_irq_chip_and_handler_name(irq, &se7206_irq_chip, handle_level_irq, "level"); disable_se7206_irq(irq_get_irq_data(irq)); } diff --git a/trunk/arch/sh/boards/mach-se/7343/irq.c b/trunk/arch/sh/boards/mach-se/7343/irq.c index fd45ffc48340..76255a19417f 100644 --- a/trunk/arch/sh/boards/mach-se/7343/irq.c +++ b/trunk/arch/sh/boards/mach-se/7343/irq.c @@ -67,20 +67,19 @@ void __init init_7343se_IRQ(void) return; se7343_fpga_irq[i] = irq; - irq_set_chip_and_handler_name(se7343_fpga_irq[i], + set_irq_chip_and_handler_name(se7343_fpga_irq[i], &se7343_irq_chip, - handle_level_irq, - "level"); + handle_level_irq, "level"); - irq_set_chip_data(se7343_fpga_irq[i], (void *)i); + set_irq_chip_data(se7343_fpga_irq[i], (void *)i); } - irq_set_chained_handler(IRQ0_IRQ, se7343_irq_demux); - irq_set_irq_type(IRQ0_IRQ, IRQ_TYPE_LEVEL_LOW); - irq_set_chained_handler(IRQ1_IRQ, se7343_irq_demux); - irq_set_irq_type(IRQ1_IRQ, IRQ_TYPE_LEVEL_LOW); - irq_set_chained_handler(IRQ4_IRQ, se7343_irq_demux); - irq_set_irq_type(IRQ4_IRQ, IRQ_TYPE_LEVEL_LOW); - irq_set_chained_handler(IRQ5_IRQ, se7343_irq_demux); - irq_set_irq_type(IRQ5_IRQ, IRQ_TYPE_LEVEL_LOW); + set_irq_chained_handler(IRQ0_IRQ, se7343_irq_demux); + set_irq_type(IRQ0_IRQ, IRQ_TYPE_LEVEL_LOW); + set_irq_chained_handler(IRQ1_IRQ, se7343_irq_demux); + set_irq_type(IRQ1_IRQ, IRQ_TYPE_LEVEL_LOW); + set_irq_chained_handler(IRQ4_IRQ, se7343_irq_demux); + set_irq_type(IRQ4_IRQ, IRQ_TYPE_LEVEL_LOW); + set_irq_chained_handler(IRQ5_IRQ, se7343_irq_demux); + set_irq_type(IRQ5_IRQ, IRQ_TYPE_LEVEL_LOW); } diff --git a/trunk/arch/sh/boards/mach-se/7722/irq.c b/trunk/arch/sh/boards/mach-se/7722/irq.c index aac92f21ebd2..c013f95628ed 100644 --- a/trunk/arch/sh/boards/mach-se/7722/irq.c +++ b/trunk/arch/sh/boards/mach-se/7722/irq.c @@ -67,17 +67,16 @@ void __init init_se7722_IRQ(void) return; se7722_fpga_irq[i] = irq; - irq_set_chip_and_handler_name(se7722_fpga_irq[i], + set_irq_chip_and_handler_name(se7722_fpga_irq[i], &se7722_irq_chip, - handle_level_irq, - "level"); + handle_level_irq, "level"); - irq_set_chip_data(se7722_fpga_irq[i], (void *)i); + set_irq_chip_data(se7722_fpga_irq[i], (void *)i); } - irq_set_chained_handler(IRQ0_IRQ, se7722_irq_demux); - irq_set_irq_type(IRQ0_IRQ, IRQ_TYPE_LEVEL_LOW); + set_irq_chained_handler(IRQ0_IRQ, se7722_irq_demux); + set_irq_type(IRQ0_IRQ, IRQ_TYPE_LEVEL_LOW); - irq_set_chained_handler(IRQ1_IRQ, se7722_irq_demux); - irq_set_irq_type(IRQ1_IRQ, IRQ_TYPE_LEVEL_LOW); + set_irq_chained_handler(IRQ1_IRQ, se7722_irq_demux); + set_irq_type(IRQ1_IRQ, IRQ_TYPE_LEVEL_LOW); } diff --git a/trunk/arch/sh/boards/mach-se/7724/irq.c b/trunk/arch/sh/boards/mach-se/7724/irq.c index c6342ce7768d..5bd87c22b65b 100644 --- a/trunk/arch/sh/boards/mach-se/7724/irq.c +++ b/trunk/arch/sh/boards/mach-se/7724/irq.c @@ -140,16 +140,17 @@ void __init init_se7724_IRQ(void) return; } - irq_set_chip_and_handler_name(irq, &se7724_irq_chip, + set_irq_chip_and_handler_name(irq, + &se7724_irq_chip, handle_level_irq, "level"); } - irq_set_chained_handler(IRQ0_IRQ, se7724_irq_demux); - irq_set_irq_type(IRQ0_IRQ, IRQ_TYPE_LEVEL_LOW); + set_irq_chained_handler(IRQ0_IRQ, se7724_irq_demux); + set_irq_type(IRQ0_IRQ, IRQ_TYPE_LEVEL_LOW); - irq_set_chained_handler(IRQ1_IRQ, se7724_irq_demux); - irq_set_irq_type(IRQ1_IRQ, IRQ_TYPE_LEVEL_LOW); + set_irq_chained_handler(IRQ1_IRQ, se7724_irq_demux); + set_irq_type(IRQ1_IRQ, IRQ_TYPE_LEVEL_LOW); - irq_set_chained_handler(IRQ2_IRQ, se7724_irq_demux); - irq_set_irq_type(IRQ2_IRQ, IRQ_TYPE_LEVEL_LOW); + set_irq_chained_handler(IRQ2_IRQ, se7724_irq_demux); + set_irq_type(IRQ2_IRQ, IRQ_TYPE_LEVEL_LOW); } diff --git a/trunk/arch/sh/boards/mach-x3proto/gpio.c b/trunk/arch/sh/boards/mach-x3proto/gpio.c index f33b2b57019c..239e74066253 100644 --- a/trunk/arch/sh/boards/mach-x3proto/gpio.c +++ b/trunk/arch/sh/boards/mach-x3proto/gpio.c @@ -102,8 +102,8 @@ int __init x3proto_gpio_setup(void) spin_lock_irqsave(&x3proto_gpio_lock, flags); x3proto_gpio_irq_map[i] = irq; - irq_set_chip_and_handler_name(irq, &dummy_irq_chip, - handle_simple_irq, "gpio"); + set_irq_chip_and_handler_name(irq, &dummy_irq_chip, + handle_simple_irq, "gpio"); spin_unlock_irqrestore(&x3proto_gpio_lock, flags); } @@ -113,8 +113,8 @@ int __init x3proto_gpio_setup(void) x3proto_gpio_chip.base + x3proto_gpio_chip.ngpio, ilsel); - irq_set_chained_handler(ilsel, x3proto_gpio_irq_handler); - irq_set_irq_wake(ilsel, 1); + set_irq_chained_handler(ilsel, x3proto_gpio_irq_handler); + set_irq_wake(ilsel, 1); return 0; diff --git a/trunk/arch/sh/cchips/hd6446x/hd64461.c b/trunk/arch/sh/cchips/hd6446x/hd64461.c index eb4ea4d44d59..177a10b25cad 100644 --- a/trunk/arch/sh/cchips/hd6446x/hd64461.c +++ b/trunk/arch/sh/cchips/hd6446x/hd64461.c @@ -107,12 +107,12 @@ int __init setup_hd64461(void) return -EINVAL; } - irq_set_chip_and_handler(i, &hd64461_irq_chip, + set_irq_chip_and_handler(i, &hd64461_irq_chip, handle_level_irq); } - irq_set_chained_handler(CONFIG_HD64461_IRQ, hd64461_irq_demux); - irq_set_irq_type(CONFIG_HD64461_IRQ, IRQ_TYPE_LEVEL_LOW); + set_irq_chained_handler(CONFIG_HD64461_IRQ, hd64461_irq_demux); + set_irq_type(CONFIG_HD64461_IRQ, IRQ_TYPE_LEVEL_LOW); #ifdef CONFIG_HD64461_ENABLER printk(KERN_INFO "HD64461: enabling PCMCIA devices\n"); diff --git a/trunk/arch/sh/kernel/cpu/irq/imask.c b/trunk/arch/sh/kernel/cpu/irq/imask.c index 39b6a24c159d..32c825c9488e 100644 --- a/trunk/arch/sh/kernel/cpu/irq/imask.c +++ b/trunk/arch/sh/kernel/cpu/irq/imask.c @@ -80,6 +80,6 @@ static struct irq_chip imask_irq_chip = { void make_imask_irq(unsigned int irq) { - irq_set_chip_and_handler_name(irq, &imask_irq_chip, handle_level_irq, - "level"); + set_irq_chip_and_handler_name(irq, &imask_irq_chip, + handle_level_irq, "level"); } diff --git a/trunk/arch/sh/kernel/cpu/irq/intc-sh5.c b/trunk/arch/sh/kernel/cpu/irq/intc-sh5.c index 9e056a3a0c73..5af48f8357e5 100644 --- a/trunk/arch/sh/kernel/cpu/irq/intc-sh5.c +++ b/trunk/arch/sh/kernel/cpu/irq/intc-sh5.c @@ -135,7 +135,7 @@ void __init plat_irq_setup(void) /* Set default: per-line enable/disable, priority driven ack/eoi */ for (i = 0; i < NR_INTC_IRQS; i++) - irq_set_chip_and_handler(i, &intc_irq_type, handle_level_irq); + set_irq_chip_and_handler(i, &intc_irq_type, handle_level_irq); /* Disable all interrupts and set all priorities to 0 to avoid trouble */ diff --git a/trunk/arch/sh/kernel/cpu/irq/ipr.c b/trunk/arch/sh/kernel/cpu/irq/ipr.c index 5de6dff5c21b..7516c35ee514 100644 --- a/trunk/arch/sh/kernel/cpu/irq/ipr.c +++ b/trunk/arch/sh/kernel/cpu/irq/ipr.c @@ -74,9 +74,9 @@ void register_ipr_controller(struct ipr_desc *desc) } disable_irq_nosync(p->irq); - irq_set_chip_and_handler_name(p->irq, &desc->chip, - handle_level_irq, "level"); - irq_set_chip_data(p->irq, p); + set_irq_chip_and_handler_name(p->irq, &desc->chip, + handle_level_irq, "level"); + set_irq_chip_data(p->irq, p); disable_ipr_irq(irq_get_irq_data(p->irq)); } } diff --git a/trunk/arch/sparc/Kconfig b/trunk/arch/sparc/Kconfig index 14b234631f5f..f766e6bf370e 100644 --- a/trunk/arch/sparc/Kconfig +++ b/trunk/arch/sparc/Kconfig @@ -52,8 +52,6 @@ config SPARC64 select PERF_USE_VMALLOC select HAVE_GENERIC_HARDIRQS select GENERIC_HARDIRQS_NO_DEPRECATED - select GENERIC_IRQ_SHOW - select IRQ_PREFLOW_FASTEOI config ARCH_DEFCONFIG string diff --git a/trunk/arch/sparc/kernel/irq_64.c b/trunk/arch/sparc/kernel/irq_64.c index b1d275ce3435..eb16e3b8a2dd 100644 --- a/trunk/arch/sparc/kernel/irq_64.c +++ b/trunk/arch/sparc/kernel/irq_64.c @@ -162,14 +162,47 @@ void irq_free(unsigned int irq) /* * /proc/interrupts printing: */ -int arch_show_interrupts(struct seq_file *p, int prec) + +int show_interrupts(struct seq_file *p, void *v) { - int j; + int i = *(loff_t *) v, j; + struct irqaction * action; + unsigned long flags; - seq_printf(p, "NMI: "); - for_each_online_cpu(j) - seq_printf(p, "%10u ", cpu_data(j).__nmi_count); - seq_printf(p, " Non-maskable interrupts\n"); + if (i == 0) { + seq_printf(p, " "); + for_each_online_cpu(j) + seq_printf(p, "CPU%d ",j); + seq_putc(p, '\n'); + } + + if (i < NR_IRQS) { + raw_spin_lock_irqsave(&irq_desc[i].lock, flags); + action = irq_desc[i].action; + if (!action) + goto skip; + seq_printf(p, "%3d: ",i); +#ifndef CONFIG_SMP + seq_printf(p, "%10u ", kstat_irqs(i)); +#else + for_each_online_cpu(j) + seq_printf(p, "%10u ", kstat_irqs_cpu(i, j)); +#endif + seq_printf(p, " %9s", irq_desc[i].irq_data.chip->name); + seq_printf(p, " %s", action->name); + + for (action=action->next; action; action = action->next) + seq_printf(p, ", %s", action->name); + + seq_putc(p, '\n'); +skip: + raw_spin_unlock_irqrestore(&irq_desc[i].lock, flags); + } else if (i == NR_IRQS) { + seq_printf(p, "NMI: "); + for_each_online_cpu(j) + seq_printf(p, "%10u ", cpu_data(j).__nmi_count); + seq_printf(p, " Non-maskable interrupts\n"); + } return 0; } @@ -311,6 +344,10 @@ static void sun4u_irq_disable(struct irq_data *data) static void sun4u_irq_eoi(struct irq_data *data) { struct irq_handler_data *handler_data = data->handler_data; + struct irq_desc *desc = irq_desc + data->irq; + + if (unlikely(desc->status & (IRQ_DISABLED|IRQ_INPROGRESS))) + return; if (likely(handler_data)) upa_writeq(ICLR_IDLE, handler_data->iclr); @@ -365,8 +402,12 @@ static void sun4v_irq_disable(struct irq_data *data) static void sun4v_irq_eoi(struct irq_data *data) { unsigned int ino = irq_table[data->irq].dev_ino; + struct irq_desc *desc = irq_desc + data->irq; int err; + if (unlikely(desc->status & (IRQ_DISABLED|IRQ_INPROGRESS))) + return; + err = sun4v_intr_setstate(ino, HV_INTR_STATE_IDLE); if (err != HV_EOK) printk(KERN_ERR "sun4v_intr_setstate(%x): " @@ -440,9 +481,13 @@ static void sun4v_virq_disable(struct irq_data *data) static void sun4v_virq_eoi(struct irq_data *data) { + struct irq_desc *desc = irq_desc + data->irq; unsigned long dev_handle, dev_ino; int err; + if (unlikely(desc->status & (IRQ_DISABLED|IRQ_INPROGRESS))) + return; + dev_handle = irq_table[data->irq].dev_handle; dev_ino = irq_table[data->irq].dev_ino; @@ -460,7 +505,6 @@ static struct irq_chip sun4u_irq = { .irq_disable = sun4u_irq_disable, .irq_eoi = sun4u_irq_eoi, .irq_set_affinity = sun4u_set_affinity, - .flags = IRQCHIP_EOI_IF_HANDLED, }; static struct irq_chip sun4v_irq = { @@ -469,7 +513,6 @@ static struct irq_chip sun4v_irq = { .irq_disable = sun4v_irq_disable, .irq_eoi = sun4v_irq_eoi, .irq_set_affinity = sun4v_set_affinity, - .flags = IRQCHIP_EOI_IF_HANDLED, }; static struct irq_chip sun4v_virq = { @@ -478,28 +521,30 @@ static struct irq_chip sun4v_virq = { .irq_disable = sun4v_virq_disable, .irq_eoi = sun4v_virq_eoi, .irq_set_affinity = sun4v_virt_set_affinity, - .flags = IRQCHIP_EOI_IF_HANDLED, }; -static void pre_flow_handler(struct irq_data *d) +static void pre_flow_handler(unsigned int irq, struct irq_desc *desc) { - struct irq_handler_data *handler_data = irq_data_get_irq_handler_data(d); - unsigned int ino = irq_table[d->irq].dev_ino; + struct irq_handler_data *handler_data = get_irq_data(irq); + unsigned int ino = irq_table[irq].dev_ino; handler_data->pre_handler(ino, handler_data->arg1, handler_data->arg2); + + handle_fasteoi_irq(irq, desc); } void irq_install_pre_handler(int irq, void (*func)(unsigned int, void *, void *), void *arg1, void *arg2) { - struct irq_handler_data *handler_data = irq_get_handler_data(irq); + struct irq_handler_data *handler_data = get_irq_data(irq); + struct irq_desc *desc = irq_desc + irq; handler_data->pre_handler = func; handler_data->arg1 = arg1; handler_data->arg2 = arg2; - __irq_set_preflow_handler(irq, pre_flow_handler); + desc->handle_irq = pre_flow_handler; } unsigned int build_irq(int inofixup, unsigned long iclr, unsigned long imap) @@ -517,11 +562,13 @@ unsigned int build_irq(int inofixup, unsigned long iclr, unsigned long imap) if (!irq) { irq = irq_alloc(0, ino); bucket_set_irq(__pa(bucket), irq); - irq_set_chip_and_handler_name(irq, &sun4u_irq, - handle_fasteoi_irq, "IVEC"); + set_irq_chip_and_handler_name(irq, + &sun4u_irq, + handle_fasteoi_irq, + "IVEC"); } - handler_data = irq_get_handler_data(irq); + handler_data = get_irq_data(irq); if (unlikely(handler_data)) goto out; @@ -530,7 +577,7 @@ unsigned int build_irq(int inofixup, unsigned long iclr, unsigned long imap) prom_printf("IRQ: kzalloc(irq_handler_data) failed.\n"); prom_halt(); } - irq_set_handler_data(irq, handler_data); + set_irq_data(irq, handler_data); handler_data->imap = imap; handler_data->iclr = iclr; @@ -553,11 +600,12 @@ static unsigned int sun4v_build_common(unsigned long sysino, if (!irq) { irq = irq_alloc(0, sysino); bucket_set_irq(__pa(bucket), irq); - irq_set_chip_and_handler_name(irq, chip, handle_fasteoi_irq, + set_irq_chip_and_handler_name(irq, chip, + handle_fasteoi_irq, "IVEC"); } - handler_data = irq_get_handler_data(irq); + handler_data = get_irq_data(irq); if (unlikely(handler_data)) goto out; @@ -566,7 +614,7 @@ static unsigned int sun4v_build_common(unsigned long sysino, prom_printf("IRQ: kzalloc(irq_handler_data) failed.\n"); prom_halt(); } - irq_set_handler_data(irq, handler_data); + set_irq_data(irq, handler_data); /* Catch accidental accesses to these things. IMAP/ICLR handling * is done by hypervisor calls on sun4v platforms, not by direct @@ -591,6 +639,7 @@ unsigned int sun4v_build_virq(u32 devhandle, unsigned int devino) struct irq_handler_data *handler_data; unsigned long hv_err, cookie; struct ino_bucket *bucket; + struct irq_desc *desc; unsigned int irq; bucket = kzalloc(sizeof(struct ino_bucket), GFP_ATOMIC); @@ -611,7 +660,8 @@ unsigned int sun4v_build_virq(u32 devhandle, unsigned int devino) irq = irq_alloc(devhandle, devino); bucket_set_irq(__pa(bucket), irq); - irq_set_chip_and_handler_name(irq, &sun4v_virq, handle_fasteoi_irq, + set_irq_chip_and_handler_name(irq, &sun4v_virq, + handle_fasteoi_irq, "IVEC"); handler_data = kzalloc(sizeof(struct irq_handler_data), GFP_ATOMIC); @@ -622,8 +672,10 @@ unsigned int sun4v_build_virq(u32 devhandle, unsigned int devino) * especially wrt. locking, we do not let request_irq() enable * the interrupt. */ - irq_set_status_flags(irq, IRQ_NOAUTOEN); - irq_set_handler_data(irq, handler_data); + desc = irq_desc + irq; + desc->status |= IRQ_NOAUTOEN; + + set_irq_data(irq, handler_data); /* Catch accidental accesses to these things. IMAP/ICLR handling * is done by hypervisor calls on sun4v platforms, not by direct @@ -682,6 +734,7 @@ void __irq_entry handler_irq(int pil, struct pt_regs *regs) orig_sp = set_hardirq_stack(); while (bucket_pa) { + struct irq_desc *desc; unsigned long next_pa; unsigned int irq; @@ -689,7 +742,10 @@ void __irq_entry handler_irq(int pil, struct pt_regs *regs) irq = bucket_get_irq(bucket_pa); bucket_clear_chain_pa(bucket_pa); - generic_handle_irq(irq); + desc = irq_desc + irq; + + if (!(desc->status & IRQ_DISABLED)) + desc->handle_irq(irq, desc); bucket_pa = next_pa; } @@ -732,18 +788,19 @@ void fixup_irqs(void) unsigned int irq; for (irq = 0; irq < NR_IRQS; irq++) { - struct irq_desc *desc = irq_to_desc(irq); - struct irq_data *data = irq_desc_get_irq_data(desc); unsigned long flags; - raw_spin_lock_irqsave(&desc->lock, flags); - if (desc->action && !irqd_is_per_cpu(data)) { + raw_spin_lock_irqsave(&irq_desc[irq].lock, flags); + if (irq_desc[irq].action && + !(irq_desc[irq].status & IRQ_PER_CPU)) { + struct irq_data *data = irq_get_irq_data(irq); + if (data->chip->irq_set_affinity) data->chip->irq_set_affinity(data, - data->affinity, - false); + data->affinity, + false); } - raw_spin_unlock_irqrestore(&desc->lock, flags); + raw_spin_unlock_irqrestore(&irq_desc[irq].lock, flags); } tick_ops->disable_irq(); @@ -981,5 +1038,5 @@ void __init init_IRQ(void) : "i" (PSTATE_IE) : "g1"); - irq_to_desc(0)->action = &timer_irq_action; + irq_desc[0].action = &timer_irq_action; } diff --git a/trunk/arch/sparc/kernel/pci.c b/trunk/arch/sparc/kernel/pci.c index 713dc91020a6..44f41e312f73 100644 --- a/trunk/arch/sparc/kernel/pci.c +++ b/trunk/arch/sparc/kernel/pci.c @@ -1012,7 +1012,7 @@ int arch_setup_msi_irq(struct pci_dev *pdev, struct msi_desc *desc) void arch_teardown_msi_irq(unsigned int irq) { - struct msi_desc *entry = irq_get_msi_desc(irq); + struct msi_desc *entry = get_irq_msi(irq); struct pci_dev *pdev = entry->dev; struct pci_pbm_info *pbm = pdev->dev.archdata.host_controller; diff --git a/trunk/arch/sparc/kernel/pci_msi.c b/trunk/arch/sparc/kernel/pci_msi.c index 30982e9ab626..550e937720e7 100644 --- a/trunk/arch/sparc/kernel/pci_msi.c +++ b/trunk/arch/sparc/kernel/pci_msi.c @@ -30,10 +30,13 @@ static irqreturn_t sparc64_msiq_interrupt(int irq, void *cookie) err = ops->dequeue_msi(pbm, msiqid, &head, &msi); if (likely(err > 0)) { + struct irq_desc *desc; unsigned int irq; irq = pbm->msi_irq_table[msi - pbm->msi_first]; - generic_handle_irq(irq); + desc = irq_desc + irq; + + desc->handle_irq(irq, desc); } if (unlikely(err < 0)) @@ -133,8 +136,8 @@ static int sparc64_setup_msi_irq(unsigned int *irq_p, if (!*irq_p) goto out_err; - irq_set_chip_and_handler_name(*irq_p, &msi_irq, handle_simple_irq, - "MSI"); + set_irq_chip_and_handler_name(*irq_p, &msi_irq, + handle_simple_irq, "MSI"); err = alloc_msi(pbm); if (unlikely(err < 0)) @@ -160,7 +163,7 @@ static int sparc64_setup_msi_irq(unsigned int *irq_p, } msg.data = msi; - irq_set_msi_desc(*irq_p, entry); + set_irq_msi(*irq_p, entry); write_msi_msg(*irq_p, &msg); return 0; @@ -169,7 +172,7 @@ static int sparc64_setup_msi_irq(unsigned int *irq_p, free_msi(pbm, msi); out_irq_free: - irq_set_chip(*irq_p, NULL); + set_irq_chip(*irq_p, NULL); irq_free(*irq_p); *irq_p = 0; @@ -208,7 +211,7 @@ static void sparc64_teardown_msi_irq(unsigned int irq, free_msi(pbm, msi_num); - irq_set_chip(irq, NULL); + set_irq_chip(irq, NULL); irq_free(irq); } diff --git a/trunk/arch/tile/Kconfig b/trunk/arch/tile/Kconfig index 5e34a9fee9b3..f3b78701c219 100644 --- a/trunk/arch/tile/Kconfig +++ b/trunk/arch/tile/Kconfig @@ -12,7 +12,6 @@ config TILE select GENERIC_IRQ_PROBE select GENERIC_PENDING_IRQ if SMP select GENERIC_HARDIRQS_NO_DEPRECATED - select GENERIC_IRQ_SHOW # FIXME: investigate whether we need/want these options. # select HAVE_IOREMAP_PROT diff --git a/trunk/arch/tile/kernel/irq.c b/trunk/arch/tile/kernel/irq.c index aa0134db2dd6..0baa7580121f 100644 --- a/trunk/arch/tile/kernel/irq.c +++ b/trunk/arch/tile/kernel/irq.c @@ -241,14 +241,14 @@ void tile_irq_activate(unsigned int irq, int tile_irq_type) irq_flow_handler_t handle = handle_level_irq; if (tile_irq_type == TILE_IRQ_PERCPU) handle = handle_percpu_irq; - irq_set_chip_and_handler(irq, &tile_irq_chip, handle); + set_irq_chip_and_handler(irq, &tile_irq_chip, handle); /* * Flag interrupts that are hardware-cleared so that ack() * won't clear them. */ if (tile_irq_type == TILE_IRQ_HW_CLEAR) - irq_set_chip_data(irq, (void *)IS_HW_CLEARED); + set_irq_chip_data(irq, (void *)IS_HW_CLEARED); } EXPORT_SYMBOL(tile_irq_activate); @@ -262,6 +262,47 @@ void ack_bad_irq(unsigned int irq) * Generic, controller-independent functions: */ +int show_interrupts(struct seq_file *p, void *v) +{ + int i = *(loff_t *) v, j; + struct irqaction *action; + unsigned long flags; + + if (i == 0) { + seq_printf(p, " "); + for (j = 0; j < NR_CPUS; j++) + if (cpu_online(j)) + seq_printf(p, "CPU%-8d", j); + seq_putc(p, '\n'); + } + + if (i < NR_IRQS) { + struct irq_desc *desc = irq_to_desc(i); + + raw_spin_lock_irqsave(&desc->lock, flags); + action = desc->action; + if (!action) + goto skip; + seq_printf(p, "%3d: ", i); +#ifndef CONFIG_SMP + seq_printf(p, "%10u ", kstat_irqs(i)); +#else + for_each_online_cpu(j) + seq_printf(p, "%10u ", kstat_irqs_cpu(i, j)); +#endif + seq_printf(p, " %14s", get_irq_desc_chip(desc)->name); + seq_printf(p, " %s", action->name); + + for (action = action->next; action; action = action->next) + seq_printf(p, ", %s", action->name); + + seq_putc(p, '\n'); +skip: + raw_spin_unlock_irqrestore(&desc->lock, flags); + } + return 0; +} + #if CHIP_HAS_IPI() int create_irq(void) { diff --git a/trunk/arch/unicore32/Kconfig b/trunk/arch/unicore32/Kconfig index 04e024919b2b..4a36db45fb3d 100644 --- a/trunk/arch/unicore32/Kconfig +++ b/trunk/arch/unicore32/Kconfig @@ -11,7 +11,6 @@ config UNICORE32 select GENERIC_FIND_FIRST_BIT select GENERIC_IRQ_PROBE select GENERIC_HARDIRQS_NO_DEPRECATED - select GENERIC_IRQ_SHOW select ARCH_WANT_FRAME_POINTERS help UniCore-32 is 32-bit Instruction Set Architecture, diff --git a/trunk/arch/unicore32/kernel/irq.c b/trunk/arch/unicore32/kernel/irq.c index 2aa30a364bbe..b23624cf3062 100644 --- a/trunk/arch/unicore32/kernel/irq.c +++ b/trunk/arch/unicore32/kernel/irq.c @@ -321,24 +321,24 @@ void __init init_IRQ(void) writel(1, INTC_ICCR); for (irq = 0; irq < IRQ_GPIOHIGH; irq++) { - irq_set_chip(irq, &puv3_low_gpio_chip); - irq_set_handler(irq, handle_edge_irq); + set_irq_chip(irq, &puv3_low_gpio_chip); + set_irq_handler(irq, handle_edge_irq); irq_modify_status(irq, IRQ_NOREQUEST | IRQ_NOPROBE | IRQ_NOAUTOEN, 0); } for (irq = IRQ_GPIOHIGH + 1; irq < IRQ_GPIO0; irq++) { - irq_set_chip(irq, &puv3_normal_chip); - irq_set_handler(irq, handle_level_irq); + set_irq_chip(irq, &puv3_normal_chip); + set_irq_handler(irq, handle_level_irq); irq_modify_status(irq, IRQ_NOREQUEST | IRQ_NOAUTOEN, IRQ_NOPROBE); } for (irq = IRQ_GPIO0; irq <= IRQ_GPIO27; irq++) { - irq_set_chip(irq, &puv3_high_gpio_chip); - irq_set_handler(irq, handle_edge_irq); + set_irq_chip(irq, &puv3_high_gpio_chip); + set_irq_handler(irq, handle_edge_irq); irq_modify_status(irq, IRQ_NOREQUEST | IRQ_NOPROBE | IRQ_NOAUTOEN, 0); @@ -347,14 +347,56 @@ void __init init_IRQ(void) /* * Install handler for GPIO 0-27 edge detect interrupts */ - irq_set_chip(IRQ_GPIOHIGH, &puv3_normal_chip); - irq_set_chained_handler(IRQ_GPIOHIGH, puv3_gpio_handler); + set_irq_chip(IRQ_GPIOHIGH, &puv3_normal_chip); + set_irq_chained_handler(IRQ_GPIOHIGH, puv3_gpio_handler); #ifdef CONFIG_PUV3_GPIO puv3_init_gpio(); #endif } +int show_interrupts(struct seq_file *p, void *v) +{ + int i = *(loff_t *) v, cpu; + struct irq_desc *desc; + struct irqaction *action; + unsigned long flags; + + if (i == 0) { + char cpuname[12]; + + seq_printf(p, " "); + for_each_present_cpu(cpu) { + sprintf(cpuname, "CPU%d", cpu); + seq_printf(p, " %10s", cpuname); + } + seq_putc(p, '\n'); + } + + if (i < nr_irqs) { + desc = irq_to_desc(i); + raw_spin_lock_irqsave(&desc->lock, flags); + action = desc->action; + if (!action) + goto unlock; + + seq_printf(p, "%3d: ", i); + for_each_present_cpu(cpu) + seq_printf(p, "%10u ", kstat_irqs_cpu(i, cpu)); + seq_printf(p, " %10s", desc->irq_data.chip->name ? : "-"); + seq_printf(p, " %s", action->name); + for (action = action->next; action; action = action->next) + seq_printf(p, ", %s", action->name); + + seq_putc(p, '\n'); +unlock: + raw_spin_unlock_irqrestore(&desc->lock, flags); + } else if (i == nr_irqs) { + seq_printf(p, "Error in interrupt!\n"); + } + return 0; +} + /* * do_IRQ handles all hardware IRQ's. Decoded IRQs should not * come via this function. Instead, they should provide their diff --git a/trunk/arch/x86/crypto/aesni-intel_asm.S b/trunk/arch/x86/crypto/aesni-intel_asm.S index be6d9e365a80..adcf794b22e2 100644 --- a/trunk/arch/x86/crypto/aesni-intel_asm.S +++ b/trunk/arch/x86/crypto/aesni-intel_asm.S @@ -1612,7 +1612,6 @@ _zero_cipher_left_encrypt: movdqa SHUF_MASK(%rip), %xmm10 PSHUFB_XMM %xmm10, %xmm0 - ENCRYPT_SINGLE_BLOCK %xmm0, %xmm1 # Encrypt(K, Yn) sub $16, %r11 add %r13, %r11 @@ -1635,9 +1634,7 @@ _zero_cipher_left_encrypt: # GHASH computation for the last <16 byte block sub %r13, %r11 add $16, %r11 - - movdqa SHUF_MASK(%rip), %xmm10 - PSHUFB_XMM %xmm10, %xmm0 + PSHUFB_XMM %xmm10, %xmm1 # shuffle xmm0 back to output as ciphertext diff --git a/trunk/arch/x86/crypto/aesni-intel_glue.c b/trunk/arch/x86/crypto/aesni-intel_glue.c index 2577613fb32b..e0e6340c8dad 100644 --- a/trunk/arch/x86/crypto/aesni-intel_glue.c +++ b/trunk/arch/x86/crypto/aesni-intel_glue.c @@ -828,15 +828,9 @@ static int rfc4106_init(struct crypto_tfm *tfm) struct cryptd_aead *cryptd_tfm; struct aesni_rfc4106_gcm_ctx *ctx = (struct aesni_rfc4106_gcm_ctx *) PTR_ALIGN((u8 *)crypto_tfm_ctx(tfm), AESNI_ALIGN); - struct crypto_aead *cryptd_child; - struct aesni_rfc4106_gcm_ctx *child_ctx; cryptd_tfm = cryptd_alloc_aead("__driver-gcm-aes-aesni", 0, 0); if (IS_ERR(cryptd_tfm)) return PTR_ERR(cryptd_tfm); - - cryptd_child = cryptd_aead_child(cryptd_tfm); - child_ctx = aesni_rfc4106_gcm_ctx_get(cryptd_child); - memcpy(child_ctx, ctx, sizeof(*ctx)); ctx->cryptd_tfm = cryptd_tfm; tfm->crt_aead.reqsize = sizeof(struct aead_request) + crypto_aead_reqsize(&cryptd_tfm->base); @@ -929,9 +923,6 @@ static int rfc4106_set_key(struct crypto_aead *parent, const u8 *key, int ret = 0; struct crypto_tfm *tfm = crypto_aead_tfm(parent); struct aesni_rfc4106_gcm_ctx *ctx = aesni_rfc4106_gcm_ctx_get(parent); - struct crypto_aead *cryptd_child = cryptd_aead_child(ctx->cryptd_tfm); - struct aesni_rfc4106_gcm_ctx *child_ctx = - aesni_rfc4106_gcm_ctx_get(cryptd_child); u8 *new_key_mem = NULL; if (key_len < 4) { @@ -975,7 +966,6 @@ static int rfc4106_set_key(struct crypto_aead *parent, const u8 *key, goto exit; } ret = rfc4106_set_hash_subkey(ctx->hash_subkey, key, key_len); - memcpy(child_ctx, ctx, sizeof(*ctx)); exit: kfree(new_key_mem); return ret; @@ -1007,6 +997,7 @@ static int rfc4106_encrypt(struct aead_request *req) int ret; struct crypto_aead *tfm = crypto_aead_reqtfm(req); struct aesni_rfc4106_gcm_ctx *ctx = aesni_rfc4106_gcm_ctx_get(tfm); + struct crypto_aead *cryptd_child = cryptd_aead_child(ctx->cryptd_tfm); if (!irq_fpu_usable()) { struct aead_request *cryptd_req = @@ -1015,7 +1006,6 @@ static int rfc4106_encrypt(struct aead_request *req) aead_request_set_tfm(cryptd_req, &ctx->cryptd_tfm->base); return crypto_aead_encrypt(cryptd_req); } else { - struct crypto_aead *cryptd_child = cryptd_aead_child(ctx->cryptd_tfm); kernel_fpu_begin(); ret = cryptd_child->base.crt_aead.encrypt(req); kernel_fpu_end(); @@ -1028,6 +1018,7 @@ static int rfc4106_decrypt(struct aead_request *req) int ret; struct crypto_aead *tfm = crypto_aead_reqtfm(req); struct aesni_rfc4106_gcm_ctx *ctx = aesni_rfc4106_gcm_ctx_get(tfm); + struct crypto_aead *cryptd_child = cryptd_aead_child(ctx->cryptd_tfm); if (!irq_fpu_usable()) { struct aead_request *cryptd_req = @@ -1036,7 +1027,6 @@ static int rfc4106_decrypt(struct aead_request *req) aead_request_set_tfm(cryptd_req, &ctx->cryptd_tfm->base); return crypto_aead_decrypt(cryptd_req); } else { - struct crypto_aead *cryptd_child = cryptd_aead_child(ctx->cryptd_tfm); kernel_fpu_begin(); ret = cryptd_child->base.crt_aead.decrypt(req); kernel_fpu_end(); diff --git a/trunk/arch/x86/include/asm/percpu.h b/trunk/arch/x86/include/asm/percpu.h index d475b4398d8b..a09e1f052d84 100644 --- a/trunk/arch/x86/include/asm/percpu.h +++ b/trunk/arch/x86/include/asm/percpu.h @@ -45,7 +45,7 @@ #include #ifdef CONFIG_SMP -#define __percpu_prefix "%%"__stringify(__percpu_seg)":" +#define __percpu_arg(x) "%%"__stringify(__percpu_seg)":%P" #x #define __my_cpu_offset percpu_read(this_cpu_off) /* @@ -62,11 +62,9 @@ (typeof(*(ptr)) __kernel __force *)tcp_ptr__; \ }) #else -#define __percpu_prefix "" +#define __percpu_arg(x) "%P" #x #endif -#define __percpu_arg(x) __percpu_prefix "%P" #x - /* * Initialized pointers to per-cpu variables needed for the boot * processor need to use these macros to get the proper address @@ -518,11 +516,11 @@ do { \ typeof(o2) __n2 = n2; \ typeof(o2) __dummy; \ alternative_io("call this_cpu_cmpxchg16b_emu\n\t" P6_NOP4, \ - "cmpxchg16b " __percpu_prefix "(%%rsi)\n\tsetz %0\n\t", \ + "cmpxchg16b %%gs:(%%rsi)\n\tsetz %0\n\t", \ X86_FEATURE_CX16, \ ASM_OUTPUT2("=a"(__ret), "=d"(__dummy)), \ "S" (&pcp1), "b"(__n1), "c"(__n2), \ - "a"(__o1), "d"(__o2) : "memory"); \ + "a"(__o1), "d"(__o2)); \ __ret; \ }) diff --git a/trunk/arch/x86/lib/cmpxchg16b_emu.S b/trunk/arch/x86/lib/cmpxchg16b_emu.S index 1e572c507d06..3e8b08a6de2b 100644 --- a/trunk/arch/x86/lib/cmpxchg16b_emu.S +++ b/trunk/arch/x86/lib/cmpxchg16b_emu.S @@ -10,12 +10,6 @@ #include #include -#ifdef CONFIG_SMP -#define SEG_PREFIX %gs: -#else -#define SEG_PREFIX -#endif - .text /* @@ -43,13 +37,13 @@ this_cpu_cmpxchg16b_emu: pushf cli - cmpq SEG_PREFIX(%rsi), %rax + cmpq %gs:(%rsi), %rax jne not_same - cmpq SEG_PREFIX 8(%rsi), %rdx + cmpq %gs:8(%rsi), %rdx jne not_same - movq %rbx, SEG_PREFIX(%rsi) - movq %rcx, SEG_PREFIX 8(%rsi) + movq %rbx, %gs:(%rsi) + movq %rcx, %gs:8(%rsi) popf mov $1, %al diff --git a/trunk/arch/x86/platform/olpc/olpc-xo1.c b/trunk/arch/x86/platform/olpc/olpc-xo1.c index ab81fb271760..99513642a0e6 100644 --- a/trunk/arch/x86/platform/olpc/olpc-xo1.c +++ b/trunk/arch/x86/platform/olpc/olpc-xo1.c @@ -72,9 +72,9 @@ static int __devinit olpc_xo1_probe(struct platform_device *pdev) dev_err(&pdev->dev, "can't fetch device resource info\n"); return -EIO; } - if (strcmp(pdev->name, "cs5535-pms") == 0) + if (strcmp(pdev->name, "olpc-xo1-pms") == 0) pms_base = res->start; - else if (strcmp(pdev->name, "olpc-xo1-pm-acpi") == 0) + else if (strcmp(pdev->name, "olpc-xo1-ac-acpi") == 0) acpi_base = res->start; /* If we have both addresses, we can override the poweroff hook */ @@ -90,9 +90,9 @@ static int __devexit olpc_xo1_remove(struct platform_device *pdev) { mfd_cell_disable(pdev); - if (strcmp(pdev->name, "cs5535-pms") == 0) + if (strcmp(pdev->name, "olpc-xo1-pms") == 0) pms_base = 0; - else if (strcmp(pdev->name, "olpc-xo1-pm-acpi") == 0) + else if (strcmp(pdev->name, "olpc-xo1-acpi") == 0) acpi_base = 0; pm_power_off = NULL; @@ -101,7 +101,7 @@ static int __devexit olpc_xo1_remove(struct platform_device *pdev) static struct platform_driver cs5535_pms_drv = { .driver = { - .name = "cs5535-pms", + .name = "olpc-xo1-pms", .owner = THIS_MODULE, }, .probe = olpc_xo1_probe, @@ -110,7 +110,7 @@ static struct platform_driver cs5535_pms_drv = { static struct platform_driver cs5535_acpi_drv = { .driver = { - .name = "olpc-xo1-pm-acpi", + .name = "olpc-xo1-acpi", .owner = THIS_MODULE, }, .probe = olpc_xo1_probe, @@ -121,21 +121,22 @@ static int __init olpc_xo1_init(void) { int r; - r = platform_driver_register(&cs5535_pms_drv); + r = mfd_shared_platform_driver_register(&cs5535_pms_drv, "cs5535-pms"); if (r) return r; - r = platform_driver_register(&cs5535_acpi_drv); + r = mfd_shared_platform_driver_register(&cs5535_acpi_drv, + "cs5535-acpi"); if (r) - platform_driver_unregister(&cs5535_pms_drv); + mfd_shared_platform_driver_unregister(&cs5535_pms_drv); return r; } static void __exit olpc_xo1_exit(void) { - platform_driver_unregister(&cs5535_acpi_drv); - platform_driver_unregister(&cs5535_pms_drv); + mfd_shared_platform_driver_unregister(&cs5535_acpi_drv); + mfd_shared_platform_driver_unregister(&cs5535_pms_drv); } MODULE_AUTHOR("Daniel Drake "); diff --git a/trunk/arch/x86/xen/p2m.c b/trunk/arch/x86/xen/p2m.c index 141eb0de8b06..215a3ce61068 100644 --- a/trunk/arch/x86/xen/p2m.c +++ b/trunk/arch/x86/xen/p2m.c @@ -497,7 +497,7 @@ static bool alloc_p2m(unsigned long pfn) return true; } -static bool __init __early_alloc_p2m(unsigned long pfn) +bool __early_alloc_p2m(unsigned long pfn) { unsigned topidx, mididx, idx; @@ -530,7 +530,7 @@ static bool __init __early_alloc_p2m(unsigned long pfn) } return idx != 0; } -unsigned long __init set_phys_range_identity(unsigned long pfn_s, +unsigned long set_phys_range_identity(unsigned long pfn_s, unsigned long pfn_e) { unsigned long pfn; @@ -671,9 +671,7 @@ int m2p_add_override(unsigned long mfn, struct page *page) page->private = mfn; page->index = pfn_to_mfn(pfn); - if (unlikely(!set_phys_to_machine(pfn, FOREIGN_FRAME(mfn)))) - return -ENOMEM; - + __set_phys_to_machine(pfn, FOREIGN_FRAME(mfn)); if (!PageHighMem(page)) /* Just zap old mapping for now */ pte_clear(&init_mm, address, ptep); @@ -711,7 +709,7 @@ int m2p_remove_override(struct page *page) spin_lock_irqsave(&m2p_override_lock, flags); list_del(&page->lru); spin_unlock_irqrestore(&m2p_override_lock, flags); - set_phys_to_machine(pfn, page->index); + __set_phys_to_machine(pfn, page->index); if (!PageHighMem(page)) set_pte_at(&init_mm, address, ptep, diff --git a/trunk/drivers/acpi/video.c b/trunk/drivers/acpi/video.c index 31e9e10f657e..a18e497f1c3c 100644 --- a/trunk/drivers/acpi/video.c +++ b/trunk/drivers/acpi/video.c @@ -824,6 +824,11 @@ static void acpi_video_device_find_cap(struct acpi_video_device *device) device->backlight->props.brightness = acpi_video_get_brightness(device->backlight); + result = sysfs_create_link(&device->backlight->dev.kobj, + &device->dev->dev.kobj, "device"); + if (result) + printk(KERN_ERR PREFIX "Create sysfs link\n"); + device->cooling_dev = thermal_cooling_device_register("LCD", device->dev, &video_cooling_ops); if (IS_ERR(device->cooling_dev)) { @@ -1376,6 +1381,7 @@ static int acpi_video_bus_put_one_device(struct acpi_video_device *device) "Cant remove video notify handler\n"); } if (device->backlight) { + sysfs_remove_link(&device->backlight->dev.kobj, "device"); backlight_device_unregister(device->backlight); device->backlight = NULL; } diff --git a/trunk/drivers/ata/pata_ixp4xx_cf.c b/trunk/drivers/ata/pata_ixp4xx_cf.c index f6b3f995f58a..5253b271b3fe 100644 --- a/trunk/drivers/ata/pata_ixp4xx_cf.c +++ b/trunk/drivers/ata/pata_ixp4xx_cf.c @@ -167,7 +167,7 @@ static __devinit int ixp4xx_pata_probe(struct platform_device *pdev) irq = platform_get_irq(pdev, 0); if (irq) - irq_set_irq_type(irq, IRQ_TYPE_EDGE_RISING); + set_irq_type(irq, IRQ_TYPE_EDGE_RISING); /* Setup expansion bus chip selects */ *data->cs0_cfg = data->cs0_bits; diff --git a/trunk/drivers/ata/pata_rb532_cf.c b/trunk/drivers/ata/pata_rb532_cf.c index 1b9d10d9c5d9..baeaf938d55b 100644 --- a/trunk/drivers/ata/pata_rb532_cf.c +++ b/trunk/drivers/ata/pata_rb532_cf.c @@ -60,10 +60,10 @@ static irqreturn_t rb532_pata_irq_handler(int irq, void *dev_instance) struct rb532_cf_info *info = ah->private_data; if (gpio_get_value(info->gpio_line)) { - irq_set_irq_type(info->irq, IRQ_TYPE_LEVEL_LOW); + set_irq_type(info->irq, IRQ_TYPE_LEVEL_LOW); ata_sff_interrupt(info->irq, dev_instance); } else { - irq_set_irq_type(info->irq, IRQ_TYPE_LEVEL_HIGH); + set_irq_type(info->irq, IRQ_TYPE_LEVEL_HIGH); } return IRQ_HANDLED; diff --git a/trunk/drivers/block/cciss.c b/trunk/drivers/block/cciss.c index 9bf13988f1a2..35658f445fca 100644 --- a/trunk/drivers/block/cciss.c +++ b/trunk/drivers/block/cciss.c @@ -193,7 +193,7 @@ static int __devinit cciss_find_cfg_addrs(struct pci_dev *pdev, u64 *cfg_offset); static int __devinit cciss_pci_find_memory_BAR(struct pci_dev *pdev, unsigned long *memory_bar); -static inline u32 cciss_tag_discard_error_bits(ctlr_info_t *h, u32 tag); + /* performant mode helper functions */ static void calc_bucket_map(int *bucket, int num_buckets, int nsgs, @@ -231,7 +231,7 @@ static const struct block_device_operations cciss_fops = { */ static void set_performant_mode(ctlr_info_t *h, CommandList_struct *c) { - if (likely(h->transMethod & CFGTBL_Trans_Performant)) + if (likely(h->transMethod == CFGTBL_Trans_Performant)) c->busaddr |= 1 | (h->blockFetchTable[c->Header.SGList] << 1); } @@ -556,44 +556,6 @@ static void __devinit cciss_procinit(ctlr_info_t *h) #define to_hba(n) container_of(n, struct ctlr_info, dev) #define to_drv(n) container_of(n, drive_info_struct, dev) -/* List of controllers which cannot be reset on kexec with reset_devices */ -static u32 unresettable_controller[] = { - 0x324a103C, /* Smart Array P712m */ - 0x324b103C, /* SmartArray P711m */ - 0x3223103C, /* Smart Array P800 */ - 0x3234103C, /* Smart Array P400 */ - 0x3235103C, /* Smart Array P400i */ - 0x3211103C, /* Smart Array E200i */ - 0x3212103C, /* Smart Array E200 */ - 0x3213103C, /* Smart Array E200i */ - 0x3214103C, /* Smart Array E200i */ - 0x3215103C, /* Smart Array E200i */ - 0x3237103C, /* Smart Array E500 */ - 0x323D103C, /* Smart Array P700m */ - 0x409C0E11, /* Smart Array 6400 */ - 0x409D0E11, /* Smart Array 6400 EM */ -}; - -static int ctlr_is_resettable(struct ctlr_info *h) -{ - int i; - - for (i = 0; i < ARRAY_SIZE(unresettable_controller); i++) - if (unresettable_controller[i] == h->board_id) - return 0; - return 1; -} - -static ssize_t host_show_resettable(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - struct ctlr_info *h = to_hba(dev); - - return snprintf(buf, 20, "%d\n", ctlr_is_resettable(h)); -} -static DEVICE_ATTR(resettable, S_IRUGO, host_show_resettable, NULL); - static ssize_t host_store_rescan(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) @@ -779,7 +741,6 @@ static DEVICE_ATTR(usage_count, S_IRUGO, cciss_show_usage_count, NULL); static struct attribute *cciss_host_attrs[] = { &dev_attr_rescan.attr, - &dev_attr_resettable.attr, NULL }; @@ -1012,8 +973,8 @@ static void cmd_special_free(ctlr_info_t *h, CommandList_struct *c) temp64.val32.upper = c->ErrDesc.Addr.upper; pci_free_consistent(h->pdev, sizeof(ErrorInfo_struct), c->err_info, (dma_addr_t) temp64.val); - pci_free_consistent(h->pdev, sizeof(CommandList_struct), c, - (dma_addr_t) cciss_tag_discard_error_bits(h, (u32) c->busaddr)); + pci_free_consistent(h->pdev, sizeof(CommandList_struct), + c, (dma_addr_t) c->busaddr); } static inline ctlr_info_t *get_host(struct gendisk *disk) @@ -1529,7 +1490,8 @@ static int cciss_bigpassthru(ctlr_info_t *h, void __user *argp) return -EINVAL; if (!capable(CAP_SYS_RAWIO)) return -EPERM; - ioc = kmalloc(sizeof(*ioc), GFP_KERNEL); + ioc = (BIG_IOCTL_Command_struct *) + kmalloc(sizeof(*ioc), GFP_KERNEL); if (!ioc) { status = -ENOMEM; goto cleanup1; @@ -2691,10 +2653,6 @@ static int process_sendcmd_error(ctlr_info_t *h, CommandList_struct *c) c->Request.CDB[0]); return_status = IO_NEEDS_RETRY; break; - case CMD_UNABORTABLE: - dev_warn(&h->pdev->dev, "cmd unabortable\n"); - return_status = IO_ERROR; - break; default: dev_warn(&h->pdev->dev, "cmd 0x%02x returned " "unknown status %x\n", c->Request.CDB[0], @@ -3145,13 +3103,6 @@ static inline void complete_command(ctlr_info_t *h, CommandList_struct *cmd, (cmd->rq->cmd_type == REQ_TYPE_BLOCK_PC) ? DID_PASSTHROUGH : DID_ERROR); break; - case CMD_UNABORTABLE: - dev_warn(&h->pdev->dev, "cmd %p unabortable\n", cmd); - rq->errors = make_status_bytes(SAM_STAT_GOOD, - cmd->err_info->CommandStatus, DRIVER_OK, - cmd->rq->cmd_type == REQ_TYPE_BLOCK_PC ? - DID_PASSTHROUGH : DID_ERROR); - break; default: dev_warn(&h->pdev->dev, "cmd %p returned " "unknown status %x\n", cmd, @@ -3185,13 +3136,10 @@ static inline u32 cciss_tag_to_index(u32 tag) return tag >> DIRECT_LOOKUP_SHIFT; } -static inline u32 cciss_tag_discard_error_bits(ctlr_info_t *h, u32 tag) +static inline u32 cciss_tag_discard_error_bits(u32 tag) { -#define CCISS_PERF_ERROR_BITS ((1 << DIRECT_LOOKUP_SHIFT) - 1) -#define CCISS_SIMPLE_ERROR_BITS 0x03 - if (likely(h->transMethod & CFGTBL_Trans_Performant)) - return tag & ~CCISS_PERF_ERROR_BITS; - return tag & ~CCISS_SIMPLE_ERROR_BITS; +#define CCISS_ERROR_BITS 0x03 + return tag & ~CCISS_ERROR_BITS; } static inline void cciss_mark_tag_indexed(u32 *tag) @@ -3411,7 +3359,7 @@ static inline u32 next_command(ctlr_info_t *h) { u32 a; - if (unlikely(!(h->transMethod & CFGTBL_Trans_Performant))) + if (unlikely(h->transMethod != CFGTBL_Trans_Performant)) return h->access.command_completed(h); if ((*(h->reply_pool_head) & 1) == (h->reply_pool_wraparound)) { @@ -3446,12 +3394,14 @@ static inline u32 process_indexed_cmd(ctlr_info_t *h, u32 raw_tag) /* process completion of a non-indexed command */ static inline u32 process_nonindexed_cmd(ctlr_info_t *h, u32 raw_tag) { + u32 tag; CommandList_struct *c = NULL; __u32 busaddr_masked, tag_masked; - tag_masked = cciss_tag_discard_error_bits(h, raw_tag); + tag = cciss_tag_discard_error_bits(raw_tag); list_for_each_entry(c, &h->cmpQ, list) { - busaddr_masked = cciss_tag_discard_error_bits(h, c->busaddr); + busaddr_masked = cciss_tag_discard_error_bits(c->busaddr); + tag_masked = cciss_tag_discard_error_bits(tag); if (busaddr_masked == tag_masked) { finish_cmd(h, c, raw_tag); return next_command(h); @@ -3803,8 +3753,7 @@ static void __devinit cciss_wait_for_mode_change_ack(ctlr_info_t *h) } } -static __devinit void cciss_enter_performant_mode(ctlr_info_t *h, - u32 use_short_tags) +static __devinit void cciss_enter_performant_mode(ctlr_info_t *h) { /* This is a bit complicated. There are 8 registers on * the controller which we write to to tell it 8 different @@ -3859,7 +3808,7 @@ static __devinit void cciss_enter_performant_mode(ctlr_info_t *h, writel(0, &h->transtable->RepQCtrAddrHigh32); writel(h->reply_pool_dhandle, &h->transtable->RepQAddr0Low32); writel(0, &h->transtable->RepQAddr0High32); - writel(CFGTBL_Trans_Performant | use_short_tags, + writel(CFGTBL_Trans_Performant, &(h->cfgtable->HostWrite.TransportRequest)); writel(CFGTBL_ChangeReq, h->vaddr + SA5_DOORBELL); @@ -3906,8 +3855,7 @@ static void __devinit cciss_put_controller_into_performant_mode(ctlr_info_t *h) if ((h->reply_pool == NULL) || (h->blockFetchTable == NULL)) goto clean_up; - cciss_enter_performant_mode(h, - trans_support & CFGTBL_Trans_use_short_tags); + cciss_enter_performant_mode(h); /* Change the access methods to the performant access methods */ h->access = SA5_performant_access; diff --git a/trunk/drivers/block/cciss.h b/trunk/drivers/block/cciss.h index 554bbd907d14..579f74918493 100644 --- a/trunk/drivers/block/cciss.h +++ b/trunk/drivers/block/cciss.h @@ -222,7 +222,6 @@ static void SA5_submit_command( ctlr_info_t *h, CommandList_struct *c) h->ctlr, c->busaddr); #endif /* CCISS_DEBUG */ writel(c->busaddr, h->vaddr + SA5_REQUEST_PORT_OFFSET); - readl(h->vaddr + SA5_REQUEST_PORT_OFFSET); h->commands_outstanding++; if ( h->commands_outstanding > h->max_outstanding) h->max_outstanding = h->commands_outstanding; diff --git a/trunk/drivers/block/cciss_cmd.h b/trunk/drivers/block/cciss_cmd.h index cd441bef031f..35463d2f0ee7 100644 --- a/trunk/drivers/block/cciss_cmd.h +++ b/trunk/drivers/block/cciss_cmd.h @@ -56,7 +56,6 @@ #define CFGTBL_Trans_Simple 0x00000002l #define CFGTBL_Trans_Performant 0x00000004l -#define CFGTBL_Trans_use_short_tags 0x20000000l #define CFGTBL_BusType_Ultra2 0x00000001l #define CFGTBL_BusType_Ultra3 0x00000002l diff --git a/trunk/drivers/block/cciss_scsi.c b/trunk/drivers/block/cciss_scsi.c index df793803f5ae..727d0225b7d0 100644 --- a/trunk/drivers/block/cciss_scsi.c +++ b/trunk/drivers/block/cciss_scsi.c @@ -824,18 +824,13 @@ static void complete_scsi_command(CommandList_struct *c, int timeout, break; case CMD_UNSOLICITED_ABORT: cmd->result = DID_ABORT << 16; - dev_warn(&h->pdev->dev, "%p aborted due to an " + dev_warn(&h->pdev->dev, "%p aborted do to an " "unsolicited abort\n", c); break; case CMD_TIMEOUT: cmd->result = DID_TIME_OUT << 16; dev_warn(&h->pdev->dev, "%p timedout\n", c); break; - case CMD_UNABORTABLE: - cmd->result = DID_ERROR << 16; - dev_warn(&h->pdev->dev, "c %p command " - "unabortable\n", c); - break; default: cmd->result = DID_ERROR << 16; dev_warn(&h->pdev->dev, @@ -1012,15 +1007,11 @@ cciss_scsi_interpret_error(ctlr_info_t *h, CommandList_struct *c) break; case CMD_UNSOLICITED_ABORT: dev_warn(&h->pdev->dev, - "%p aborted due to an unsolicited abort\n", c); + "%p aborted do to an unsolicited abort\n", c); break; case CMD_TIMEOUT: dev_warn(&h->pdev->dev, "%p timedout\n", c); break; - case CMD_UNABORTABLE: - dev_warn(&h->pdev->dev, - "%p unabortable\n", c); - break; default: dev_warn(&h->pdev->dev, "%p returned unknown status %x\n", diff --git a/trunk/drivers/block/drbd/drbd_actlog.c b/trunk/drivers/block/drbd/drbd_actlog.c index 2a1642bc451d..aca302492ff2 100644 --- a/trunk/drivers/block/drbd/drbd_actlog.c +++ b/trunk/drivers/block/drbd/drbd_actlog.c @@ -92,7 +92,7 @@ static int _drbd_md_sync_page_io(struct drbd_conf *mdev, bio->bi_end_io = drbd_md_io_complete; bio->bi_rw = rw; - if (drbd_insert_fault(mdev, (rw & WRITE) ? DRBD_FAULT_MD_WR : DRBD_FAULT_MD_RD)) + if (FAULT_ACTIVE(mdev, (rw & WRITE) ? DRBD_FAULT_MD_WR : DRBD_FAULT_MD_RD)) bio_endio(bio, -EIO); else submit_bio(rw, bio); @@ -176,17 +176,13 @@ static struct lc_element *_al_get(struct drbd_conf *mdev, unsigned int enr) struct lc_element *al_ext; struct lc_element *tmp; unsigned long al_flags = 0; - int wake; spin_lock_irq(&mdev->al_lock); tmp = lc_find(mdev->resync, enr/AL_EXT_PER_BM_SECT); if (unlikely(tmp != NULL)) { struct bm_extent *bm_ext = lc_entry(tmp, struct bm_extent, lce); if (test_bit(BME_NO_WRITES, &bm_ext->flags)) { - wake = !test_and_set_bit(BME_PRIORITY, &bm_ext->flags); spin_unlock_irq(&mdev->al_lock); - if (wake) - wake_up(&mdev->al_wait); return NULL; } } @@ -262,33 +258,6 @@ void drbd_al_complete_io(struct drbd_conf *mdev, sector_t sector) spin_unlock_irqrestore(&mdev->al_lock, flags); } -#if (PAGE_SHIFT + 3) < (AL_EXTENT_SHIFT - BM_BLOCK_SHIFT) -/* Currently BM_BLOCK_SHIFT, BM_EXT_SHIFT and AL_EXTENT_SHIFT - * are still coupled, or assume too much about their relation. - * Code below will not work if this is violated. - * Will be cleaned up with some followup patch. - */ -# error FIXME -#endif - -static unsigned int al_extent_to_bm_page(unsigned int al_enr) -{ - return al_enr >> - /* bit to page */ - ((PAGE_SHIFT + 3) - - /* al extent number to bit */ - (AL_EXTENT_SHIFT - BM_BLOCK_SHIFT)); -} - -static unsigned int rs_extent_to_bm_page(unsigned int rs_enr) -{ - return rs_enr >> - /* bit to page */ - ((PAGE_SHIFT + 3) - - /* al extent number to bit */ - (BM_EXT_SHIFT - BM_BLOCK_SHIFT)); -} - int w_al_write_transaction(struct drbd_conf *mdev, struct drbd_work *w, int unused) { @@ -316,7 +285,7 @@ w_al_write_transaction(struct drbd_conf *mdev, struct drbd_work *w, int unused) * For now, we must not write the transaction, * if we cannot write out the bitmap of the evicted extent. */ if (mdev->state.conn < C_CONNECTED && evicted != LC_FREE) - drbd_bm_write_page(mdev, al_extent_to_bm_page(evicted)); + drbd_bm_write_sect(mdev, evicted/AL_EXT_PER_BM_SECT); /* The bitmap write may have failed, causing a state change. */ if (mdev->state.disk < D_INCONSISTENT) { @@ -365,7 +334,7 @@ w_al_write_transaction(struct drbd_conf *mdev, struct drbd_work *w, int unused) + mdev->ldev->md.al_offset + mdev->al_tr_pos; if (!drbd_md_sync_page_io(mdev, mdev->ldev, sector, WRITE)) - drbd_chk_io_error(mdev, 1, true); + drbd_chk_io_error(mdev, 1, TRUE); if (++mdev->al_tr_pos > div_ceil(mdev->act_log->nr_elements, AL_EXTENTS_PT)) @@ -542,6 +511,225 @@ int drbd_al_read_log(struct drbd_conf *mdev, struct drbd_backing_dev *bdev) return 1; } +static void atodb_endio(struct bio *bio, int error) +{ + struct drbd_atodb_wait *wc = bio->bi_private; + struct drbd_conf *mdev = wc->mdev; + struct page *page; + int uptodate = bio_flagged(bio, BIO_UPTODATE); + + /* strange behavior of some lower level drivers... + * fail the request by clearing the uptodate flag, + * but do not return any error?! */ + if (!error && !uptodate) + error = -EIO; + + drbd_chk_io_error(mdev, error, TRUE); + if (error && wc->error == 0) + wc->error = error; + + if (atomic_dec_and_test(&wc->count)) + complete(&wc->io_done); + + page = bio->bi_io_vec[0].bv_page; + put_page(page); + bio_put(bio); + mdev->bm_writ_cnt++; + put_ldev(mdev); +} + +/* sector to word */ +#define S2W(s) ((s)<<(BM_EXT_SHIFT-BM_BLOCK_SHIFT-LN2_BPL)) + +/* activity log to on disk bitmap -- prepare bio unless that sector + * is already covered by previously prepared bios */ +static int atodb_prepare_unless_covered(struct drbd_conf *mdev, + struct bio **bios, + unsigned int enr, + struct drbd_atodb_wait *wc) __must_hold(local) +{ + struct bio *bio; + struct page *page; + sector_t on_disk_sector; + unsigned int page_offset = PAGE_SIZE; + int offset; + int i = 0; + int err = -ENOMEM; + + /* We always write aligned, full 4k blocks, + * so we can ignore the logical_block_size (for now) */ + enr &= ~7U; + on_disk_sector = enr + mdev->ldev->md.md_offset + + mdev->ldev->md.bm_offset; + + D_ASSERT(!(on_disk_sector & 7U)); + + /* Check if that enr is already covered by an already created bio. + * Caution, bios[] is not NULL terminated, + * but only initialized to all NULL. + * For completely scattered activity log, + * the last invocation iterates over all bios, + * and finds the last NULL entry. + */ + while ((bio = bios[i])) { + if (bio->bi_sector == on_disk_sector) + return 0; + i++; + } + /* bios[i] == NULL, the next not yet used slot */ + + /* GFP_KERNEL, we are not in the write-out path */ + bio = bio_alloc(GFP_KERNEL, 1); + if (bio == NULL) + return -ENOMEM; + + if (i > 0) { + const struct bio_vec *prev_bv = bios[i-1]->bi_io_vec; + page_offset = prev_bv->bv_offset + prev_bv->bv_len; + page = prev_bv->bv_page; + } + if (page_offset == PAGE_SIZE) { + page = alloc_page(__GFP_HIGHMEM); + if (page == NULL) + goto out_bio_put; + page_offset = 0; + } else { + get_page(page); + } + + offset = S2W(enr); + drbd_bm_get_lel(mdev, offset, + min_t(size_t, S2W(8), drbd_bm_words(mdev) - offset), + kmap(page) + page_offset); + kunmap(page); + + bio->bi_private = wc; + bio->bi_end_io = atodb_endio; + bio->bi_bdev = mdev->ldev->md_bdev; + bio->bi_sector = on_disk_sector; + + if (bio_add_page(bio, page, 4096, page_offset) != 4096) + goto out_put_page; + + atomic_inc(&wc->count); + /* we already know that we may do this... + * get_ldev_if_state(mdev,D_ATTACHING); + * just get the extra reference, so that the local_cnt reflects + * the number of pending IO requests DRBD at its backing device. + */ + atomic_inc(&mdev->local_cnt); + + bios[i] = bio; + + return 0; + +out_put_page: + err = -EINVAL; + put_page(page); +out_bio_put: + bio_put(bio); + return err; +} + +/** + * drbd_al_to_on_disk_bm() - * Writes bitmap parts covered by active AL extents + * @mdev: DRBD device. + * + * Called when we detach (unconfigure) local storage, + * or when we go from R_PRIMARY to R_SECONDARY role. + */ +void drbd_al_to_on_disk_bm(struct drbd_conf *mdev) +{ + int i, nr_elements; + unsigned int enr; + struct bio **bios; + struct drbd_atodb_wait wc; + + ERR_IF (!get_ldev_if_state(mdev, D_ATTACHING)) + return; /* sorry, I don't have any act_log etc... */ + + wait_event(mdev->al_wait, lc_try_lock(mdev->act_log)); + + nr_elements = mdev->act_log->nr_elements; + + /* GFP_KERNEL, we are not in anyone's write-out path */ + bios = kzalloc(sizeof(struct bio *) * nr_elements, GFP_KERNEL); + if (!bios) + goto submit_one_by_one; + + atomic_set(&wc.count, 0); + init_completion(&wc.io_done); + wc.mdev = mdev; + wc.error = 0; + + for (i = 0; i < nr_elements; i++) { + enr = lc_element_by_index(mdev->act_log, i)->lc_number; + if (enr == LC_FREE) + continue; + /* next statement also does atomic_inc wc.count and local_cnt */ + if (atodb_prepare_unless_covered(mdev, bios, + enr/AL_EXT_PER_BM_SECT, + &wc)) + goto free_bios_submit_one_by_one; + } + + /* unnecessary optimization? */ + lc_unlock(mdev->act_log); + wake_up(&mdev->al_wait); + + /* all prepared, submit them */ + for (i = 0; i < nr_elements; i++) { + if (bios[i] == NULL) + break; + if (FAULT_ACTIVE(mdev, DRBD_FAULT_MD_WR)) { + bios[i]->bi_rw = WRITE; + bio_endio(bios[i], -EIO); + } else { + submit_bio(WRITE, bios[i]); + } + } + + /* always (try to) flush bitmap to stable storage */ + drbd_md_flush(mdev); + + /* In case we did not submit a single IO do not wait for + * them to complete. ( Because we would wait forever here. ) + * + * In case we had IOs and they are already complete, there + * is not point in waiting anyways. + * Therefore this if () ... */ + if (atomic_read(&wc.count)) + wait_for_completion(&wc.io_done); + + put_ldev(mdev); + + kfree(bios); + return; + + free_bios_submit_one_by_one: + /* free everything by calling the endio callback directly. */ + for (i = 0; i < nr_elements && bios[i]; i++) + bio_endio(bios[i], 0); + + kfree(bios); + + submit_one_by_one: + dev_warn(DEV, "Using the slow drbd_al_to_on_disk_bm()\n"); + + for (i = 0; i < mdev->act_log->nr_elements; i++) { + enr = lc_element_by_index(mdev->act_log, i)->lc_number; + if (enr == LC_FREE) + continue; + /* Really slow: if we have al-extents 16..19 active, + * sector 4 will be written four times! Synchronous! */ + drbd_bm_write_sect(mdev, enr/AL_EXT_PER_BM_SECT); + } + + lc_unlock(mdev->act_log); + wake_up(&mdev->al_wait); + put_ldev(mdev); +} + /** * drbd_al_apply_to_bm() - Sets the bitmap to diry(1) where covered ba active AL extents * @mdev: DRBD device. @@ -621,7 +809,7 @@ static int w_update_odbm(struct drbd_conf *mdev, struct drbd_work *w, int unused return 1; } - drbd_bm_write_page(mdev, rs_extent_to_bm_page(udw->enr)); + drbd_bm_write_sect(mdev, udw->enr); put_ldev(mdev); kfree(udw); @@ -701,6 +889,7 @@ static void drbd_try_clear_on_disk_bm(struct drbd_conf *mdev, sector_t sector, dev_warn(DEV, "Kicking resync_lru element enr=%u " "out with rs_failed=%d\n", ext->lce.lc_number, ext->rs_failed); + set_bit(WRITE_BM_AFTER_RESYNC, &mdev->flags); } ext->rs_left = rs_left; ext->rs_failed = success ? 0 : count; @@ -719,6 +908,7 @@ static void drbd_try_clear_on_disk_bm(struct drbd_conf *mdev, sector_t sector, drbd_queue_work_front(&mdev->data.work, &udw->w); } else { dev_warn(DEV, "Could not kmalloc an udw\n"); + set_bit(WRITE_BM_AFTER_RESYNC, &mdev->flags); } } } else { @@ -729,22 +919,6 @@ static void drbd_try_clear_on_disk_bm(struct drbd_conf *mdev, sector_t sector, } } -void drbd_advance_rs_marks(struct drbd_conf *mdev, unsigned long still_to_go) -{ - unsigned long now = jiffies; - unsigned long last = mdev->rs_mark_time[mdev->rs_last_mark]; - int next = (mdev->rs_last_mark + 1) % DRBD_SYNC_MARKS; - if (time_after_eq(now, last + DRBD_SYNC_MARK_STEP)) { - if (mdev->rs_mark_left[mdev->rs_last_mark] != still_to_go && - mdev->state.conn != C_PAUSED_SYNC_T && - mdev->state.conn != C_PAUSED_SYNC_S) { - mdev->rs_mark_time[next] = now; - mdev->rs_mark_left[next] = still_to_go; - mdev->rs_last_mark = next; - } - } -} - /* clear the bit corresponding to the piece of storage in question: * size byte of data starting from sector. Only clear a bits of the affected * one ore more _aligned_ BM_BLOCK_SIZE blocks. @@ -762,7 +936,7 @@ void __drbd_set_in_sync(struct drbd_conf *mdev, sector_t sector, int size, int wake_up = 0; unsigned long flags; - if (size <= 0 || (size & 0x1ff) != 0 || size > DRBD_MAX_BIO_SIZE) { + if (size <= 0 || (size & 0x1ff) != 0 || size > DRBD_MAX_SEGMENT_SIZE) { dev_err(DEV, "drbd_set_in_sync: sector=%llus size=%d nonsense!\n", (unsigned long long)sector, size); return; @@ -795,9 +969,21 @@ void __drbd_set_in_sync(struct drbd_conf *mdev, sector_t sector, int size, */ count = drbd_bm_clear_bits(mdev, sbnr, ebnr); if (count && get_ldev(mdev)) { - drbd_advance_rs_marks(mdev, drbd_bm_total_weight(mdev)); + unsigned long now = jiffies; + unsigned long last = mdev->rs_mark_time[mdev->rs_last_mark]; + int next = (mdev->rs_last_mark + 1) % DRBD_SYNC_MARKS; + if (time_after_eq(now, last + DRBD_SYNC_MARK_STEP)) { + unsigned long tw = drbd_bm_total_weight(mdev); + if (mdev->rs_mark_left[mdev->rs_last_mark] != tw && + mdev->state.conn != C_PAUSED_SYNC_T && + mdev->state.conn != C_PAUSED_SYNC_S) { + mdev->rs_mark_time[next] = now; + mdev->rs_mark_left[next] = tw; + mdev->rs_last_mark = next; + } + } spin_lock_irqsave(&mdev->al_lock, flags); - drbd_try_clear_on_disk_bm(mdev, sector, count, true); + drbd_try_clear_on_disk_bm(mdev, sector, count, TRUE); spin_unlock_irqrestore(&mdev->al_lock, flags); /* just wake_up unconditional now, various lc_chaged(), @@ -812,27 +998,27 @@ void __drbd_set_in_sync(struct drbd_conf *mdev, sector_t sector, int size, /* * this is intended to set one request worth of data out of sync. * affects at least 1 bit, - * and at most 1+DRBD_MAX_BIO_SIZE/BM_BLOCK_SIZE bits. + * and at most 1+DRBD_MAX_SEGMENT_SIZE/BM_BLOCK_SIZE bits. * * called by tl_clear and drbd_send_dblock (==drbd_make_request). * so this can be _any_ process. */ -int __drbd_set_out_of_sync(struct drbd_conf *mdev, sector_t sector, int size, +void __drbd_set_out_of_sync(struct drbd_conf *mdev, sector_t sector, int size, const char *file, const unsigned int line) { unsigned long sbnr, ebnr, lbnr, flags; sector_t esector, nr_sectors; - unsigned int enr, count = 0; + unsigned int enr, count; struct lc_element *e; - if (size <= 0 || (size & 0x1ff) != 0 || size > DRBD_MAX_BIO_SIZE) { + if (size <= 0 || (size & 0x1ff) != 0 || size > DRBD_MAX_SEGMENT_SIZE) { dev_err(DEV, "sector: %llus, size: %d\n", (unsigned long long)sector, size); - return 0; + return; } if (!get_ldev(mdev)) - return 0; /* no disk, no metadata, no bitmap to set bits in */ + return; /* no disk, no metadata, no bitmap to set bits in */ nr_sectors = drbd_get_capacity(mdev->this_bdev); esector = sector + (size >> 9) - 1; @@ -862,8 +1048,6 @@ int __drbd_set_out_of_sync(struct drbd_conf *mdev, sector_t sector, int size, out: put_ldev(mdev); - - return count; } static @@ -944,10 +1128,7 @@ int drbd_rs_begin_io(struct drbd_conf *mdev, sector_t sector) unsigned int enr = BM_SECT_TO_EXT(sector); struct bm_extent *bm_ext; int i, sig; - int sa = 200; /* Step aside 200 times, then grab the extent and let app-IO wait. - 200 times -> 20 seconds. */ -retry: sig = wait_event_interruptible(mdev->al_wait, (bm_ext = _bme_get(mdev, enr))); if (sig) @@ -958,25 +1139,16 @@ int drbd_rs_begin_io(struct drbd_conf *mdev, sector_t sector) for (i = 0; i < AL_EXT_PER_BM_SECT; i++) { sig = wait_event_interruptible(mdev->al_wait, - !_is_in_al(mdev, enr * AL_EXT_PER_BM_SECT + i) || - test_bit(BME_PRIORITY, &bm_ext->flags)); - - if (sig || (test_bit(BME_PRIORITY, &bm_ext->flags) && sa)) { + !_is_in_al(mdev, enr * AL_EXT_PER_BM_SECT + i)); + if (sig) { spin_lock_irq(&mdev->al_lock); if (lc_put(mdev->resync, &bm_ext->lce) == 0) { - bm_ext->flags = 0; /* clears BME_NO_WRITES and eventually BME_PRIORITY */ + clear_bit(BME_NO_WRITES, &bm_ext->flags); mdev->resync_locked--; wake_up(&mdev->al_wait); } spin_unlock_irq(&mdev->al_lock); - if (sig) - return -EINTR; - if (schedule_timeout_interruptible(HZ/10)) - return -EINTR; - if (sa && --sa == 0) - dev_warn(DEV,"drbd_rs_begin_io() stepped aside for 20sec." - "Resync stalled?\n"); - goto retry; + return -EINTR; } } set_bit(BME_LOCKED, &bm_ext->flags); @@ -1119,7 +1291,8 @@ void drbd_rs_complete_io(struct drbd_conf *mdev, sector_t sector) } if (lc_put(mdev->resync, &bm_ext->lce) == 0) { - bm_ext->flags = 0; /* clear BME_LOCKED, BME_NO_WRITES and BME_PRIORITY */ + clear_bit(BME_LOCKED, &bm_ext->flags); + clear_bit(BME_NO_WRITES, &bm_ext->flags); mdev->resync_locked--; wake_up(&mdev->al_wait); } @@ -1210,7 +1383,7 @@ void drbd_rs_failed_io(struct drbd_conf *mdev, sector_t sector, int size) sector_t esector, nr_sectors; int wake_up = 0; - if (size <= 0 || (size & 0x1ff) != 0 || size > DRBD_MAX_BIO_SIZE) { + if (size <= 0 || (size & 0x1ff) != 0 || size > DRBD_MAX_SEGMENT_SIZE) { dev_err(DEV, "drbd_rs_failed_io: sector=%llus size=%d nonsense!\n", (unsigned long long)sector, size); return; @@ -1247,7 +1420,7 @@ void drbd_rs_failed_io(struct drbd_conf *mdev, sector_t sector, int size) mdev->rs_failed += count; if (get_ldev(mdev)) { - drbd_try_clear_on_disk_bm(mdev, sector, count, false); + drbd_try_clear_on_disk_bm(mdev, sector, count, FALSE); put_ldev(mdev); } diff --git a/trunk/drivers/block/drbd/drbd_bitmap.c b/trunk/drivers/block/drbd/drbd_bitmap.c index 76210ba401ac..0645ca829a94 100644 --- a/trunk/drivers/block/drbd/drbd_bitmap.c +++ b/trunk/drivers/block/drbd/drbd_bitmap.c @@ -28,56 +28,18 @@ #include #include #include - #include "drbd_int.h" - /* OPAQUE outside this file! * interface defined in drbd_int.h * convention: * function name drbd_bm_... => used elsewhere, "public". * function name bm_... => internal to implementation, "private". - */ - -/* - * LIMITATIONS: - * We want to support >= peta byte of backend storage, while for now still using - * a granularity of one bit per 4KiB of storage. - * 1 << 50 bytes backend storage (1 PiB) - * 1 << (50 - 12) bits needed - * 38 --> we need u64 to index and count bits - * 1 << (38 - 3) bitmap bytes needed - * 35 --> we still need u64 to index and count bytes - * (that's 32 GiB of bitmap for 1 PiB storage) - * 1 << (35 - 2) 32bit longs needed - * 33 --> we'd even need u64 to index and count 32bit long words. - * 1 << (35 - 3) 64bit longs needed - * 32 --> we could get away with a 32bit unsigned int to index and count - * 64bit long words, but I rather stay with unsigned long for now. - * We probably should neither count nor point to bytes or long words - * directly, but either by bitnumber, or by page index and offset. - * 1 << (35 - 12) - * 22 --> we need that much 4KiB pages of bitmap. - * 1 << (22 + 3) --> on a 64bit arch, - * we need 32 MiB to store the array of page pointers. - * - * Because I'm lazy, and because the resulting patch was too large, too ugly - * and still incomplete, on 32bit we still "only" support 16 TiB (minus some), - * (1 << 32) bits * 4k storage. - * - - * bitmap storage and IO: - * Bitmap is stored little endian on disk, and is kept little endian in - * core memory. Currently we still hold the full bitmap in core as long - * as we are "attached" to a local disk, which at 32 GiB for 1PiB storage - * seems excessive. - * - * We plan to reduce the amount of in-core bitmap pages by pageing them in - * and out against their on-disk location as necessary, but need to make - * sure we don't cause too much meta data IO, and must not deadlock in - * tight memory situations. This needs some more work. + * Note that since find_first_bit returns int, at the current granularity of + * the bitmap (4KB per byte), this implementation "only" supports up to + * 1<<(32+12) == 16 TB... */ /* @@ -93,9 +55,13 @@ struct drbd_bitmap { struct page **bm_pages; spinlock_t bm_lock; - - /* see LIMITATIONS: above */ - + /* WARNING unsigned long bm_*: + * 32bit number of bit offset is just enough for 512 MB bitmap. + * it will blow up if we make the bitmap bigger... + * not that it makes much sense to have a bitmap that large, + * rather change the granularity to 16k or 64k or something. + * (that implies other problems, however...) + */ unsigned long bm_set; /* nr of set bits; THINK maybe atomic_t? */ unsigned long bm_bits; size_t bm_words; @@ -103,18 +69,29 @@ struct drbd_bitmap { sector_t bm_dev_capacity; struct mutex bm_change; /* serializes resize operations */ - wait_queue_head_t bm_io_wait; /* used to serialize IO of single pages */ + atomic_t bm_async_io; + wait_queue_head_t bm_io_wait; - enum bm_flag bm_flags; + unsigned long bm_flags; /* debugging aid, in case we are still racy somewhere */ char *bm_why; struct task_struct *bm_task; }; +/* definition of bits in bm_flags */ +#define BM_LOCKED 0 +#define BM_MD_IO_ERROR 1 +#define BM_P_VMALLOCED 2 + static int __bm_change_bits_to(struct drbd_conf *mdev, const unsigned long s, unsigned long e, int val, const enum km_type km); +static int bm_is_locked(struct drbd_bitmap *b) +{ + return test_bit(BM_LOCKED, &b->bm_flags); +} + #define bm_print_lock_info(m) __bm_print_lock_info(m, __func__) static void __bm_print_lock_info(struct drbd_conf *mdev, const char *func) { @@ -131,7 +108,7 @@ static void __bm_print_lock_info(struct drbd_conf *mdev, const char *func) b->bm_task == mdev->worker.task ? "worker" : "?"); } -void drbd_bm_lock(struct drbd_conf *mdev, char *why, enum bm_flag flags) +void drbd_bm_lock(struct drbd_conf *mdev, char *why) { struct drbd_bitmap *b = mdev->bitmap; int trylock_failed; @@ -154,9 +131,8 @@ void drbd_bm_lock(struct drbd_conf *mdev, char *why, enum bm_flag flags) b->bm_task == mdev->worker.task ? "worker" : "?"); mutex_lock(&b->bm_change); } - if (BM_LOCKED_MASK & b->bm_flags) + if (__test_and_set_bit(BM_LOCKED, &b->bm_flags)) dev_err(DEV, "FIXME bitmap already locked in bm_lock\n"); - b->bm_flags |= flags & BM_LOCKED_MASK; b->bm_why = why; b->bm_task = current; @@ -170,137 +146,31 @@ void drbd_bm_unlock(struct drbd_conf *mdev) return; } - if (!(BM_LOCKED_MASK & mdev->bitmap->bm_flags)) + if (!__test_and_clear_bit(BM_LOCKED, &mdev->bitmap->bm_flags)) dev_err(DEV, "FIXME bitmap not locked in bm_unlock\n"); - b->bm_flags &= ~BM_LOCKED_MASK; b->bm_why = NULL; b->bm_task = NULL; mutex_unlock(&b->bm_change); } -/* we store some "meta" info about our pages in page->private */ -/* at a granularity of 4k storage per bitmap bit: - * one peta byte storage: 1<<50 byte, 1<<38 * 4k storage blocks - * 1<<38 bits, - * 1<<23 4k bitmap pages. - * Use 24 bits as page index, covers 2 peta byte storage - * at a granularity of 4k per bit. - * Used to report the failed page idx on io error from the endio handlers. - */ -#define BM_PAGE_IDX_MASK ((1UL<<24)-1) -/* this page is currently read in, or written back */ -#define BM_PAGE_IO_LOCK 31 -/* if there has been an IO error for this page */ -#define BM_PAGE_IO_ERROR 30 -/* this is to be able to intelligently skip disk IO, - * set if bits have been set since last IO. */ -#define BM_PAGE_NEED_WRITEOUT 29 -/* to mark for lazy writeout once syncer cleared all clearable bits, - * we if bits have been cleared since last IO. */ -#define BM_PAGE_LAZY_WRITEOUT 28 - -/* store_page_idx uses non-atomic assingment. It is only used directly after - * allocating the page. All other bm_set_page_* and bm_clear_page_* need to - * use atomic bit manipulation, as set_out_of_sync (and therefore bitmap - * changes) may happen from various contexts, and wait_on_bit/wake_up_bit - * requires it all to be atomic as well. */ -static void bm_store_page_idx(struct page *page, unsigned long idx) -{ - BUG_ON(0 != (idx & ~BM_PAGE_IDX_MASK)); - page_private(page) |= idx; -} - -static unsigned long bm_page_to_idx(struct page *page) -{ - return page_private(page) & BM_PAGE_IDX_MASK; -} - -/* As is very unlikely that the same page is under IO from more than one - * context, we can get away with a bit per page and one wait queue per bitmap. - */ -static void bm_page_lock_io(struct drbd_conf *mdev, int page_nr) -{ - struct drbd_bitmap *b = mdev->bitmap; - void *addr = &page_private(b->bm_pages[page_nr]); - wait_event(b->bm_io_wait, !test_and_set_bit(BM_PAGE_IO_LOCK, addr)); -} - -static void bm_page_unlock_io(struct drbd_conf *mdev, int page_nr) -{ - struct drbd_bitmap *b = mdev->bitmap; - void *addr = &page_private(b->bm_pages[page_nr]); - clear_bit(BM_PAGE_IO_LOCK, addr); - smp_mb__after_clear_bit(); - wake_up(&mdev->bitmap->bm_io_wait); -} - -/* set _before_ submit_io, so it may be reset due to being changed - * while this page is in flight... will get submitted later again */ -static void bm_set_page_unchanged(struct page *page) -{ - /* use cmpxchg? */ - clear_bit(BM_PAGE_NEED_WRITEOUT, &page_private(page)); - clear_bit(BM_PAGE_LAZY_WRITEOUT, &page_private(page)); -} - -static void bm_set_page_need_writeout(struct page *page) +/* word offset to long pointer */ +static unsigned long *__bm_map_paddr(struct drbd_bitmap *b, unsigned long offset, const enum km_type km) { - set_bit(BM_PAGE_NEED_WRITEOUT, &page_private(page)); -} - -static int bm_test_page_unchanged(struct page *page) -{ - volatile const unsigned long *addr = &page_private(page); - return (*addr & ((1UL<> PAGE_SHIFT; */ - unsigned int page_nr = long_nr >> (PAGE_SHIFT - LN2_BPL + 3); + page_nr = offset >> (PAGE_SHIFT - LN2_BPL + 3); BUG_ON(page_nr >= b->bm_number_of_pages); - return page_nr; -} + page = b->bm_pages[page_nr]; -static unsigned int bm_bit_to_page_idx(struct drbd_bitmap *b, u64 bitnr) -{ - /* page_nr = (bitnr/8) >> PAGE_SHIFT; */ - unsigned int page_nr = bitnr >> (PAGE_SHIFT + 3); - BUG_ON(page_nr >= b->bm_number_of_pages); - return page_nr; -} - -static unsigned long *__bm_map_pidx(struct drbd_bitmap *b, unsigned int idx, const enum km_type km) -{ - struct page *page = b->bm_pages[idx]; return (unsigned long *) kmap_atomic(page, km); } -static unsigned long *bm_map_pidx(struct drbd_bitmap *b, unsigned int idx) +static unsigned long * bm_map_paddr(struct drbd_bitmap *b, unsigned long offset) { - return __bm_map_pidx(b, idx, KM_IRQ1); + return __bm_map_paddr(b, offset, KM_IRQ1); } static void __bm_unmap(unsigned long *p_addr, const enum km_type km) @@ -332,7 +202,6 @@ static void bm_unmap(unsigned long *p_addr) * to be able to report device specific. */ - static void bm_free_pages(struct page **pages, unsigned long number) { unsigned long i; @@ -400,9 +269,6 @@ static struct page **bm_realloc_pages(struct drbd_bitmap *b, unsigned long want) bm_vk_free(new_pages, vmalloced); return NULL; } - /* we want to know which page it is - * from the endio handlers */ - bm_store_page_idx(page, i); new_pages[i] = page; } } else { @@ -414,9 +280,9 @@ static struct page **bm_realloc_pages(struct drbd_bitmap *b, unsigned long want) } if (vmalloced) - b->bm_flags |= BM_P_VMALLOCED; + set_bit(BM_P_VMALLOCED, &b->bm_flags); else - b->bm_flags &= ~BM_P_VMALLOCED; + clear_bit(BM_P_VMALLOCED, &b->bm_flags); return new_pages; } @@ -453,7 +319,7 @@ void drbd_bm_cleanup(struct drbd_conf *mdev) { ERR_IF (!mdev->bitmap) return; bm_free_pages(mdev->bitmap->bm_pages, mdev->bitmap->bm_number_of_pages); - bm_vk_free(mdev->bitmap->bm_pages, (BM_P_VMALLOCED & mdev->bitmap->bm_flags)); + bm_vk_free(mdev->bitmap->bm_pages, test_bit(BM_P_VMALLOCED, &mdev->bitmap->bm_flags)); kfree(mdev->bitmap); mdev->bitmap = NULL; } @@ -463,39 +329,22 @@ void drbd_bm_cleanup(struct drbd_conf *mdev) * this masks out the remaining bits. * Returns the number of bits cleared. */ -#define BITS_PER_PAGE (1UL << (PAGE_SHIFT + 3)) -#define BITS_PER_PAGE_MASK (BITS_PER_PAGE - 1) -#define BITS_PER_LONG_MASK (BITS_PER_LONG - 1) static int bm_clear_surplus(struct drbd_bitmap *b) { - unsigned long mask; - unsigned long *p_addr, *bm; - int tmp; + const unsigned long mask = (1UL << (b->bm_bits & (BITS_PER_LONG-1))) - 1; + size_t w = b->bm_bits >> LN2_BPL; int cleared = 0; + unsigned long *p_addr, *bm; - /* number of bits modulo bits per page */ - tmp = (b->bm_bits & BITS_PER_PAGE_MASK); - /* mask the used bits of the word containing the last bit */ - mask = (1UL << (tmp & BITS_PER_LONG_MASK)) -1; - /* bitmap is always stored little endian, - * on disk and in core memory alike */ - mask = cpu_to_lel(mask); - - p_addr = bm_map_pidx(b, b->bm_number_of_pages - 1); - bm = p_addr + (tmp/BITS_PER_LONG); - if (mask) { - /* If mask != 0, we are not exactly aligned, so bm now points - * to the long containing the last bit. - * If mask == 0, bm already points to the word immediately - * after the last (long word aligned) bit. */ + p_addr = bm_map_paddr(b, w); + bm = p_addr + MLPP(w); + if (w < b->bm_words) { cleared = hweight_long(*bm & ~mask); *bm &= mask; - bm++; + w++; bm++; } - if (BITS_PER_LONG == 32 && ((bm - p_addr) & 1) == 1) { - /* on a 32bit arch, we may need to zero out - * a padding long to align with a 64bit remote */ + if (w < b->bm_words) { cleared += hweight_long(*bm); *bm = 0; } @@ -505,75 +354,66 @@ static int bm_clear_surplus(struct drbd_bitmap *b) static void bm_set_surplus(struct drbd_bitmap *b) { - unsigned long mask; + const unsigned long mask = (1UL << (b->bm_bits & (BITS_PER_LONG-1))) - 1; + size_t w = b->bm_bits >> LN2_BPL; unsigned long *p_addr, *bm; - int tmp; - - /* number of bits modulo bits per page */ - tmp = (b->bm_bits & BITS_PER_PAGE_MASK); - /* mask the used bits of the word containing the last bit */ - mask = (1UL << (tmp & BITS_PER_LONG_MASK)) -1; - /* bitmap is always stored little endian, - * on disk and in core memory alike */ - mask = cpu_to_lel(mask); - - p_addr = bm_map_pidx(b, b->bm_number_of_pages - 1); - bm = p_addr + (tmp/BITS_PER_LONG); - if (mask) { - /* If mask != 0, we are not exactly aligned, so bm now points - * to the long containing the last bit. - * If mask == 0, bm already points to the word immediately - * after the last (long word aligned) bit. */ + + p_addr = bm_map_paddr(b, w); + bm = p_addr + MLPP(w); + if (w < b->bm_words) { *bm |= ~mask; - bm++; + bm++; w++; } - if (BITS_PER_LONG == 32 && ((bm - p_addr) & 1) == 1) { - /* on a 32bit arch, we may need to zero out - * a padding long to align with a 64bit remote */ - *bm = ~0UL; + if (w < b->bm_words) { + *bm = ~(0UL); } bm_unmap(p_addr); } -/* you better not modify the bitmap while this is running, - * or its results will be stale */ -static unsigned long bm_count_bits(struct drbd_bitmap *b) +static unsigned long __bm_count_bits(struct drbd_bitmap *b, const int swap_endian) { - unsigned long *p_addr; + unsigned long *p_addr, *bm, offset = 0; unsigned long bits = 0; - unsigned long mask = (1UL << (b->bm_bits & BITS_PER_LONG_MASK)) -1; - int idx, i, last_word; - - /* all but last page */ - for (idx = 0; idx < b->bm_number_of_pages - 1; idx++) { - p_addr = __bm_map_pidx(b, idx, KM_USER0); - for (i = 0; i < LWPP; i++) - bits += hweight_long(p_addr[i]); + unsigned long i, do_now; + + while (offset < b->bm_words) { + i = do_now = min_t(size_t, b->bm_words-offset, LWPP); + p_addr = __bm_map_paddr(b, offset, KM_USER0); + bm = p_addr + MLPP(offset); + while (i--) { +#ifndef __LITTLE_ENDIAN + if (swap_endian) + *bm = lel_to_cpu(*bm); +#endif + bits += hweight_long(*bm++); + } __bm_unmap(p_addr, KM_USER0); + offset += do_now; cond_resched(); } - /* last (or only) page */ - last_word = ((b->bm_bits - 1) & BITS_PER_PAGE_MASK) >> LN2_BPL; - p_addr = __bm_map_pidx(b, idx, KM_USER0); - for (i = 0; i < last_word; i++) - bits += hweight_long(p_addr[i]); - p_addr[last_word] &= cpu_to_lel(mask); - bits += hweight_long(p_addr[last_word]); - /* 32bit arch, may have an unused padding long */ - if (BITS_PER_LONG == 32 && (last_word & 1) == 0) - p_addr[last_word+1] = 0; - __bm_unmap(p_addr, KM_USER0); + return bits; } +static unsigned long bm_count_bits(struct drbd_bitmap *b) +{ + return __bm_count_bits(b, 0); +} + +static unsigned long bm_count_bits_swap_endian(struct drbd_bitmap *b) +{ + return __bm_count_bits(b, 1); +} + /* offset and len in long words.*/ static void bm_memset(struct drbd_bitmap *b, size_t offset, int c, size_t len) { unsigned long *p_addr, *bm; - unsigned int idx; size_t do_now, end; +#define BM_SECTORS_PER_BIT (BM_BLOCK_SIZE/512) + end = offset + len; if (end > b->bm_words) { @@ -583,16 +423,15 @@ static void bm_memset(struct drbd_bitmap *b, size_t offset, int c, size_t len) while (offset < end) { do_now = min_t(size_t, ALIGN(offset + 1, LWPP), end) - offset; - idx = bm_word_to_page_idx(b, offset); - p_addr = bm_map_pidx(b, idx); + p_addr = bm_map_paddr(b, offset); bm = p_addr + MLPP(offset); if (bm+do_now > p_addr + LWPP) { printk(KERN_ALERT "drbd: BUG BUG BUG! p_addr:%p bm:%p do_now:%d\n", p_addr, bm, (int)do_now); - } else - memset(bm, c, do_now * sizeof(long)); + break; /* breaks to after catch_oob_access_end() only! */ + } + memset(bm, c, do_now * sizeof(long)); bm_unmap(p_addr); - bm_set_page_need_writeout(b->bm_pages[idx]); offset += do_now; } } @@ -608,7 +447,7 @@ static void bm_memset(struct drbd_bitmap *b, size_t offset, int c, size_t len) int drbd_bm_resize(struct drbd_conf *mdev, sector_t capacity, int set_new_bits) { struct drbd_bitmap *b = mdev->bitmap; - unsigned long bits, words, owords, obits; + unsigned long bits, words, owords, obits, *p_addr, *bm; unsigned long want, have, onpages; /* number of pages */ struct page **npages, **opages = NULL; int err = 0, growing; @@ -616,7 +455,7 @@ int drbd_bm_resize(struct drbd_conf *mdev, sector_t capacity, int set_new_bits) ERR_IF(!b) return -ENOMEM; - drbd_bm_lock(mdev, "resize", BM_LOCKED_MASK); + drbd_bm_lock(mdev, "resize"); dev_info(DEV, "drbd_bm_resize called with capacity == %llu\n", (unsigned long long)capacity); @@ -624,7 +463,7 @@ int drbd_bm_resize(struct drbd_conf *mdev, sector_t capacity, int set_new_bits) if (capacity == b->bm_dev_capacity) goto out; - opages_vmalloced = (BM_P_VMALLOCED & b->bm_flags); + opages_vmalloced = test_bit(BM_P_VMALLOCED, &b->bm_flags); if (capacity == 0) { spin_lock_irq(&b->bm_lock); @@ -652,23 +491,18 @@ int drbd_bm_resize(struct drbd_conf *mdev, sector_t capacity, int set_new_bits) words = ALIGN(bits, 64) >> LN2_BPL; if (get_ldev(mdev)) { - u64 bits_on_disk = ((u64)mdev->ldev->md.md_size_sect-MD_BM_OFFSET) << 12; + D_ASSERT((u64)bits <= (((u64)mdev->ldev->md.md_size_sect-MD_BM_OFFSET) << 12)); put_ldev(mdev); - if (bits > bits_on_disk) { - dev_info(DEV, "bits = %lu\n", bits); - dev_info(DEV, "bits_on_disk = %llu\n", bits_on_disk); - err = -ENOSPC; - goto out; - } } - want = ALIGN(words*sizeof(long), PAGE_SIZE) >> PAGE_SHIFT; + /* one extra long to catch off by one errors */ + want = ALIGN((words+1)*sizeof(long), PAGE_SIZE) >> PAGE_SHIFT; have = b->bm_number_of_pages; if (want == have) { D_ASSERT(b->bm_pages != NULL); npages = b->bm_pages; } else { - if (drbd_insert_fault(mdev, DRBD_FAULT_BM_ALLOC)) + if (FAULT_ACTIVE(mdev, DRBD_FAULT_BM_ALLOC)) npages = NULL; else npages = bm_realloc_pages(b, want); @@ -708,6 +542,11 @@ int drbd_bm_resize(struct drbd_conf *mdev, sector_t capacity, int set_new_bits) bm_free_pages(opages + want, have - want); } + p_addr = bm_map_paddr(b, words); + bm = p_addr + MLPP(words); + *bm = DRBD_MAGIC; + bm_unmap(p_addr); + (void)bm_clear_surplus(b); spin_unlock_irq(&b->bm_lock); @@ -715,7 +554,7 @@ int drbd_bm_resize(struct drbd_conf *mdev, sector_t capacity, int set_new_bits) bm_vk_free(opages, opages_vmalloced); if (!growing) b->bm_set = bm_count_bits(b); - dev_info(DEV, "resync bitmap: bits=%lu words=%lu pages=%lu\n", bits, words, want); + dev_info(DEV, "resync bitmap: bits=%lu words=%lu\n", bits, words); out: drbd_bm_unlock(mdev); @@ -785,7 +624,6 @@ void drbd_bm_merge_lel(struct drbd_conf *mdev, size_t offset, size_t number, struct drbd_bitmap *b = mdev->bitmap; unsigned long *p_addr, *bm; unsigned long word, bits; - unsigned int idx; size_t end, do_now; end = offset + number; @@ -800,18 +638,16 @@ void drbd_bm_merge_lel(struct drbd_conf *mdev, size_t offset, size_t number, spin_lock_irq(&b->bm_lock); while (offset < end) { do_now = min_t(size_t, ALIGN(offset+1, LWPP), end) - offset; - idx = bm_word_to_page_idx(b, offset); - p_addr = bm_map_pidx(b, idx); + p_addr = bm_map_paddr(b, offset); bm = p_addr + MLPP(offset); offset += do_now; while (do_now--) { bits = hweight_long(*bm); - word = *bm | *buffer++; + word = *bm | lel_to_cpu(*buffer++); *bm++ = word; b->bm_set += hweight_long(word) - bits; } bm_unmap(p_addr); - bm_set_page_need_writeout(b->bm_pages[idx]); } /* with 32bit <-> 64bit cross-platform connect * this is only correct for current usage, @@ -820,6 +656,7 @@ void drbd_bm_merge_lel(struct drbd_conf *mdev, size_t offset, size_t number, */ if (end == b->bm_words) b->bm_set -= bm_clear_surplus(b); + spin_unlock_irq(&b->bm_lock); } @@ -849,11 +686,11 @@ void drbd_bm_get_lel(struct drbd_conf *mdev, size_t offset, size_t number, else { while (offset < end) { do_now = min_t(size_t, ALIGN(offset+1, LWPP), end) - offset; - p_addr = bm_map_pidx(b, bm_word_to_page_idx(b, offset)); + p_addr = bm_map_paddr(b, offset); bm = p_addr + MLPP(offset); offset += do_now; while (do_now--) - *buffer++ = *bm++; + *buffer++ = cpu_to_lel(*bm++); bm_unmap(p_addr); } } @@ -887,22 +724,9 @@ void drbd_bm_clear_all(struct drbd_conf *mdev) spin_unlock_irq(&b->bm_lock); } -struct bm_aio_ctx { - struct drbd_conf *mdev; - atomic_t in_flight; - struct completion done; - unsigned flags; -#define BM_AIO_COPY_PAGES 1 - int error; -}; - -/* bv_page may be a copy, or may be the original */ static void bm_async_io_complete(struct bio *bio, int error) { - struct bm_aio_ctx *ctx = bio->bi_private; - struct drbd_conf *mdev = ctx->mdev; - struct drbd_bitmap *b = mdev->bitmap; - unsigned int idx = bm_page_to_idx(bio->bi_io_vec[0].bv_page); + struct drbd_bitmap *b = bio->bi_private; int uptodate = bio_flagged(bio, BIO_UPTODATE); @@ -913,83 +737,38 @@ static void bm_async_io_complete(struct bio *bio, int error) if (!error && !uptodate) error = -EIO; - if ((ctx->flags & BM_AIO_COPY_PAGES) == 0 && - !bm_test_page_unchanged(b->bm_pages[idx])) - dev_warn(DEV, "bitmap page idx %u changed during IO!\n", idx); - if (error) { - /* ctx error will hold the completed-last non-zero error code, - * in case error codes differ. */ - ctx->error = error; - bm_set_page_io_err(b->bm_pages[idx]); - /* Not identical to on disk version of it. - * Is BM_PAGE_IO_ERROR enough? */ - if (__ratelimit(&drbd_ratelimit_state)) - dev_err(DEV, "IO ERROR %d on bitmap page idx %u\n", - error, idx); - } else { - bm_clear_page_io_err(b->bm_pages[idx]); - dynamic_dev_dbg(DEV, "bitmap page idx %u completed\n", idx); + /* doh. what now? + * for now, set all bits, and flag MD_IO_ERROR */ + __set_bit(BM_MD_IO_ERROR, &b->bm_flags); } - - bm_page_unlock_io(mdev, idx); - - /* FIXME give back to page pool */ - if (ctx->flags & BM_AIO_COPY_PAGES) - put_page(bio->bi_io_vec[0].bv_page); + if (atomic_dec_and_test(&b->bm_async_io)) + wake_up(&b->bm_io_wait); bio_put(bio); - - if (atomic_dec_and_test(&ctx->in_flight)) - complete(&ctx->done); } -static void bm_page_io_async(struct bm_aio_ctx *ctx, int page_nr, int rw) __must_hold(local) +static void bm_page_io_async(struct drbd_conf *mdev, struct drbd_bitmap *b, int page_nr, int rw) __must_hold(local) { /* we are process context. we always get a bio */ struct bio *bio = bio_alloc(GFP_KERNEL, 1); - struct drbd_conf *mdev = ctx->mdev; - struct drbd_bitmap *b = mdev->bitmap; - struct page *page; unsigned int len; - sector_t on_disk_sector = mdev->ldev->md.md_offset + mdev->ldev->md.bm_offset; on_disk_sector += ((sector_t)page_nr) << (PAGE_SHIFT-9); /* this might happen with very small - * flexible external meta data device, - * or with PAGE_SIZE > 4k */ + * flexible external meta data device */ len = min_t(unsigned int, PAGE_SIZE, (drbd_md_last_sector(mdev->ldev) - on_disk_sector + 1)<<9); - /* serialize IO on this page */ - bm_page_lock_io(mdev, page_nr); - /* before memcpy and submit, - * so it can be redirtied any time */ - bm_set_page_unchanged(b->bm_pages[page_nr]); - - if (ctx->flags & BM_AIO_COPY_PAGES) { - /* FIXME alloc_page is good enough for now, but actually needs - * to use pre-allocated page pool */ - void *src, *dest; - page = alloc_page(__GFP_HIGHMEM|__GFP_WAIT); - dest = kmap_atomic(page, KM_USER0); - src = kmap_atomic(b->bm_pages[page_nr], KM_USER1); - memcpy(dest, src, PAGE_SIZE); - kunmap_atomic(src, KM_USER1); - kunmap_atomic(dest, KM_USER0); - bm_store_page_idx(page, page_nr); - } else - page = b->bm_pages[page_nr]; - bio->bi_bdev = mdev->ldev->md_bdev; bio->bi_sector = on_disk_sector; - bio_add_page(bio, page, len, 0); - bio->bi_private = ctx; + bio_add_page(bio, b->bm_pages[page_nr], len, 0); + bio->bi_private = b; bio->bi_end_io = bm_async_io_complete; - if (drbd_insert_fault(mdev, (rw & WRITE) ? DRBD_FAULT_MD_WR : DRBD_FAULT_MD_RD)) { + if (FAULT_ACTIVE(mdev, (rw & WRITE) ? DRBD_FAULT_MD_WR : DRBD_FAULT_MD_RD)) { bio->bi_rw |= rw; bio_endio(bio, -EIO); } else { @@ -997,84 +776,87 @@ static void bm_page_io_async(struct bm_aio_ctx *ctx, int page_nr, int rw) __must } } +# if defined(__LITTLE_ENDIAN) + /* nothing to do, on disk == in memory */ +# define bm_cpu_to_lel(x) ((void)0) +# else +static void bm_cpu_to_lel(struct drbd_bitmap *b) +{ + /* need to cpu_to_lel all the pages ... + * this may be optimized by using + * cpu_to_lel(-1) == -1 and cpu_to_lel(0) == 0; + * the following is still not optimal, but better than nothing */ + unsigned int i; + unsigned long *p_addr, *bm; + if (b->bm_set == 0) { + /* no page at all; avoid swap if all is 0 */ + i = b->bm_number_of_pages; + } else if (b->bm_set == b->bm_bits) { + /* only the last page */ + i = b->bm_number_of_pages - 1; + } else { + /* all pages */ + i = 0; + } + for (; i < b->bm_number_of_pages; i++) { + p_addr = kmap_atomic(b->bm_pages[i], KM_USER0); + for (bm = p_addr; bm < p_addr + PAGE_SIZE/sizeof(long); bm++) + *bm = cpu_to_lel(*bm); + kunmap_atomic(p_addr, KM_USER0); + } +} +# endif +/* lel_to_cpu == cpu_to_lel */ +# define bm_lel_to_cpu(x) bm_cpu_to_lel(x) + /* * bm_rw: read/write the whole bitmap from/to its on disk location. */ -static int bm_rw(struct drbd_conf *mdev, int rw, unsigned lazy_writeout_upper_idx) __must_hold(local) +static int bm_rw(struct drbd_conf *mdev, int rw) __must_hold(local) { - struct bm_aio_ctx ctx = { - .mdev = mdev, - .in_flight = ATOMIC_INIT(1), - .done = COMPLETION_INITIALIZER_ONSTACK(ctx.done), - .flags = lazy_writeout_upper_idx ? BM_AIO_COPY_PAGES : 0, - }; struct drbd_bitmap *b = mdev->bitmap; - int num_pages, i, count = 0; + /* sector_t sector; */ + int bm_words, num_pages, i; unsigned long now; char ppb[10]; int err = 0; - /* - * We are protected against bitmap disappearing/resizing by holding an - * ldev reference (caller must have called get_ldev()). - * For read/write, we are protected against changes to the bitmap by - * the bitmap lock (see drbd_bitmap_io). - * For lazy writeout, we don't care for ongoing changes to the bitmap, - * as we submit copies of pages anyways. - */ - if (!ctx.flags) - WARN_ON(!(BM_LOCKED_MASK & b->bm_flags)); + WARN_ON(!bm_is_locked(b)); - num_pages = b->bm_number_of_pages; + /* no spinlock here, the drbd_bm_lock should be enough! */ + + bm_words = drbd_bm_words(mdev); + num_pages = (bm_words*sizeof(long) + PAGE_SIZE-1) >> PAGE_SHIFT; + + /* on disk bitmap is little endian */ + if (rw == WRITE) + bm_cpu_to_lel(b); now = jiffies; + atomic_set(&b->bm_async_io, num_pages); + __clear_bit(BM_MD_IO_ERROR, &b->bm_flags); /* let the layers below us try to merge these bios... */ - for (i = 0; i < num_pages; i++) { - /* ignore completely unchanged pages */ - if (lazy_writeout_upper_idx && i == lazy_writeout_upper_idx) - break; - if (rw & WRITE) { - if (bm_test_page_unchanged(b->bm_pages[i])) { - dynamic_dev_dbg(DEV, "skipped bm write for idx %u\n", i); - continue; - } - /* during lazy writeout, - * ignore those pages not marked for lazy writeout. */ - if (lazy_writeout_upper_idx && - !bm_test_page_lazy_writeout(b->bm_pages[i])) { - dynamic_dev_dbg(DEV, "skipped bm lazy write for idx %u\n", i); - continue; - } - } - atomic_inc(&ctx.in_flight); - bm_page_io_async(&ctx, i, rw); - ++count; - cond_resched(); - } + for (i = 0; i < num_pages; i++) + bm_page_io_async(mdev, b, i, rw); - /* - * We initialize ctx.in_flight to one to make sure bm_async_io_complete - * will not complete() early, and decrement / test it here. If there - * are still some bios in flight, we need to wait for them here. - */ - if (!atomic_dec_and_test(&ctx.in_flight)) - wait_for_completion(&ctx.done); - dev_info(DEV, "bitmap %s of %u pages took %lu jiffies\n", - rw == WRITE ? "WRITE" : "READ", - count, jiffies - now); + wait_event(b->bm_io_wait, atomic_read(&b->bm_async_io) == 0); - if (ctx.error) { + if (test_bit(BM_MD_IO_ERROR, &b->bm_flags)) { dev_alert(DEV, "we had at least one MD IO ERROR during bitmap IO\n"); - drbd_chk_io_error(mdev, 1, true); - err = -EIO; /* ctx.error ? */ + drbd_chk_io_error(mdev, 1, TRUE); + err = -EIO; } now = jiffies; if (rw == WRITE) { + /* swap back endianness */ + bm_lel_to_cpu(b); + /* flush bitmap to stable storage */ drbd_md_flush(mdev); } else /* rw == READ */ { - b->bm_set = bm_count_bits(b); + /* just read, if necessary adjust endianness */ + b->bm_set = bm_count_bits_swap_endian(b); dev_info(DEV, "recounting of set bits took additional %lu jiffies\n", jiffies - now); } @@ -1092,128 +874,112 @@ static int bm_rw(struct drbd_conf *mdev, int rw, unsigned lazy_writeout_upper_id */ int drbd_bm_read(struct drbd_conf *mdev) __must_hold(local) { - return bm_rw(mdev, READ, 0); + return bm_rw(mdev, READ); } /** * drbd_bm_write() - Write the whole bitmap to its on disk location. * @mdev: DRBD device. - * - * Will only write pages that have changed since last IO. */ int drbd_bm_write(struct drbd_conf *mdev) __must_hold(local) { - return bm_rw(mdev, WRITE, 0); -} - -/** - * drbd_bm_lazy_write_out() - Write bitmap pages 0 to @upper_idx-1, if they have changed. - * @mdev: DRBD device. - * @upper_idx: 0: write all changed pages; +ve: page index to stop scanning for changed pages - */ -int drbd_bm_write_lazy(struct drbd_conf *mdev, unsigned upper_idx) __must_hold(local) -{ - return bm_rw(mdev, WRITE, upper_idx); + return bm_rw(mdev, WRITE); } - /** - * drbd_bm_write_page: Writes a PAGE_SIZE aligned piece of bitmap + * drbd_bm_write_sect: Writes a 512 (MD_SECTOR_SIZE) byte piece of the bitmap * @mdev: DRBD device. - * @idx: bitmap page index + * @enr: Extent number in the resync lru (happens to be sector offset) * - * We don't want to special case on logical_block_size of the backend device, - * so we submit PAGE_SIZE aligned pieces. - * Note that on "most" systems, PAGE_SIZE is 4k. - * - * In case this becomes an issue on systems with larger PAGE_SIZE, - * we may want to change this again to write 4k aligned 4k pieces. + * The BM_EXT_SIZE is on purpose exactly the amount of the bitmap covered + * by a single sector write. Therefore enr == sector offset from the + * start of the bitmap. */ -int drbd_bm_write_page(struct drbd_conf *mdev, unsigned int idx) __must_hold(local) +int drbd_bm_write_sect(struct drbd_conf *mdev, unsigned long enr) __must_hold(local) { - struct bm_aio_ctx ctx = { - .mdev = mdev, - .in_flight = ATOMIC_INIT(1), - .done = COMPLETION_INITIALIZER_ONSTACK(ctx.done), - .flags = BM_AIO_COPY_PAGES, - }; - - if (bm_test_page_unchanged(mdev->bitmap->bm_pages[idx])) { - dynamic_dev_dbg(DEV, "skipped bm page write for idx %u\n", idx); - return 0; - } - - bm_page_io_async(&ctx, idx, WRITE_SYNC); - wait_for_completion(&ctx.done); - - if (ctx.error) - drbd_chk_io_error(mdev, 1, true); - /* that should force detach, so the in memory bitmap will be - * gone in a moment as well. */ + sector_t on_disk_sector = enr + mdev->ldev->md.md_offset + + mdev->ldev->md.bm_offset; + int bm_words, num_words, offset; + int err = 0; + mutex_lock(&mdev->md_io_mutex); + bm_words = drbd_bm_words(mdev); + offset = S2W(enr); /* word offset into bitmap */ + num_words = min(S2W(1), bm_words - offset); + if (num_words < S2W(1)) + memset(page_address(mdev->md_io_page), 0, MD_SECTOR_SIZE); + drbd_bm_get_lel(mdev, offset, num_words, + page_address(mdev->md_io_page)); + if (!drbd_md_sync_page_io(mdev, mdev->ldev, on_disk_sector, WRITE)) { + int i; + err = -EIO; + dev_err(DEV, "IO ERROR writing bitmap sector %lu " + "(meta-disk sector %llus)\n", + enr, (unsigned long long)on_disk_sector); + drbd_chk_io_error(mdev, 1, TRUE); + for (i = 0; i < AL_EXT_PER_BM_SECT; i++) + drbd_bm_ALe_set_all(mdev, enr*AL_EXT_PER_BM_SECT+i); + } mdev->bm_writ_cnt++; - return ctx.error; + mutex_unlock(&mdev->md_io_mutex); + return err; } /* NOTE * find_first_bit returns int, we return unsigned long. - * For this to work on 32bit arch with bitnumbers > (1<<32), - * we'd need to return u64, and get a whole lot of other places - * fixed where we still use unsigned long. + * should not make much difference anyways, but ... * * this returns a bit number, NOT a sector! */ +#define BPP_MASK ((1UL << (PAGE_SHIFT+3)) - 1) static unsigned long __bm_find_next(struct drbd_conf *mdev, unsigned long bm_fo, const int find_zero_bit, const enum km_type km) { struct drbd_bitmap *b = mdev->bitmap; + unsigned long i = -1UL; unsigned long *p_addr; - unsigned long bit_offset; - unsigned i; - + unsigned long bit_offset; /* bit offset of the mapped page. */ if (bm_fo > b->bm_bits) { dev_err(DEV, "bm_fo=%lu bm_bits=%lu\n", bm_fo, b->bm_bits); - bm_fo = DRBD_END_OF_BITMAP; } else { while (bm_fo < b->bm_bits) { - /* bit offset of the first bit in the page */ - bit_offset = bm_fo & ~BITS_PER_PAGE_MASK; - p_addr = __bm_map_pidx(b, bm_bit_to_page_idx(b, bm_fo), km); + unsigned long offset; + bit_offset = bm_fo & ~BPP_MASK; /* bit offset of the page */ + offset = bit_offset >> LN2_BPL; /* word offset of the page */ + p_addr = __bm_map_paddr(b, offset, km); if (find_zero_bit) - i = find_next_zero_bit_le(p_addr, - PAGE_SIZE*8, bm_fo & BITS_PER_PAGE_MASK); + i = find_next_zero_bit(p_addr, PAGE_SIZE*8, bm_fo & BPP_MASK); else - i = find_next_bit_le(p_addr, - PAGE_SIZE*8, bm_fo & BITS_PER_PAGE_MASK); + i = find_next_bit(p_addr, PAGE_SIZE*8, bm_fo & BPP_MASK); __bm_unmap(p_addr, km); if (i < PAGE_SIZE*8) { - bm_fo = bit_offset + i; - if (bm_fo >= b->bm_bits) + i = bit_offset + i; + if (i >= b->bm_bits) break; goto found; } bm_fo = bit_offset + PAGE_SIZE*8; } - bm_fo = DRBD_END_OF_BITMAP; + i = -1UL; } found: - return bm_fo; + return i; } static unsigned long bm_find_next(struct drbd_conf *mdev, unsigned long bm_fo, const int find_zero_bit) { struct drbd_bitmap *b = mdev->bitmap; - unsigned long i = DRBD_END_OF_BITMAP; + unsigned long i = -1UL; ERR_IF(!b) return i; ERR_IF(!b->bm_pages) return i; spin_lock_irq(&b->bm_lock); - if (BM_DONT_TEST & b->bm_flags) + if (bm_is_locked(b)) bm_print_lock_info(mdev); i = __bm_find_next(mdev, bm_fo, find_zero_bit, KM_IRQ1); @@ -1239,13 +1005,13 @@ unsigned long drbd_bm_find_next_zero(struct drbd_conf *mdev, unsigned long bm_fo * you must take drbd_bm_lock() first */ unsigned long _drbd_bm_find_next(struct drbd_conf *mdev, unsigned long bm_fo) { - /* WARN_ON(!(BM_DONT_SET & mdev->b->bm_flags)); */ + /* WARN_ON(!bm_is_locked(mdev)); */ return __bm_find_next(mdev, bm_fo, 0, KM_USER1); } unsigned long _drbd_bm_find_next_zero(struct drbd_conf *mdev, unsigned long bm_fo) { - /* WARN_ON(!(BM_DONT_SET & mdev->b->bm_flags)); */ + /* WARN_ON(!bm_is_locked(mdev)); */ return __bm_find_next(mdev, bm_fo, 1, KM_USER1); } @@ -1261,9 +1027,8 @@ static int __bm_change_bits_to(struct drbd_conf *mdev, const unsigned long s, struct drbd_bitmap *b = mdev->bitmap; unsigned long *p_addr = NULL; unsigned long bitnr; - unsigned int last_page_nr = -1U; + unsigned long last_page_nr = -1UL; int c = 0; - int changed_total = 0; if (e >= b->bm_bits) { dev_err(DEV, "ASSERT FAILED: bit_s=%lu bit_e=%lu bm_bits=%lu\n", @@ -1271,33 +1036,23 @@ static int __bm_change_bits_to(struct drbd_conf *mdev, const unsigned long s, e = b->bm_bits ? b->bm_bits -1 : 0; } for (bitnr = s; bitnr <= e; bitnr++) { - unsigned int page_nr = bm_bit_to_page_idx(b, bitnr); + unsigned long offset = bitnr>>LN2_BPL; + unsigned long page_nr = offset >> (PAGE_SHIFT - LN2_BPL + 3); if (page_nr != last_page_nr) { if (p_addr) __bm_unmap(p_addr, km); - if (c < 0) - bm_set_page_lazy_writeout(b->bm_pages[last_page_nr]); - else if (c > 0) - bm_set_page_need_writeout(b->bm_pages[last_page_nr]); - changed_total += c; - c = 0; - p_addr = __bm_map_pidx(b, page_nr, km); + p_addr = __bm_map_paddr(b, offset, km); last_page_nr = page_nr; } if (val) - c += (0 == __test_and_set_bit_le(bitnr & BITS_PER_PAGE_MASK, p_addr)); + c += (0 == __test_and_set_bit(bitnr & BPP_MASK, p_addr)); else - c -= (0 != __test_and_clear_bit_le(bitnr & BITS_PER_PAGE_MASK, p_addr)); + c -= (0 != __test_and_clear_bit(bitnr & BPP_MASK, p_addr)); } if (p_addr) __bm_unmap(p_addr, km); - if (c < 0) - bm_set_page_lazy_writeout(b->bm_pages[last_page_nr]); - else if (c > 0) - bm_set_page_need_writeout(b->bm_pages[last_page_nr]); - changed_total += c; - b->bm_set += changed_total; - return changed_total; + b->bm_set += c; + return c; } /* returns number of bits actually changed. @@ -1315,7 +1070,7 @@ static int bm_change_bits_to(struct drbd_conf *mdev, const unsigned long s, ERR_IF(!b->bm_pages) return 0; spin_lock_irqsave(&b->bm_lock, flags); - if ((val ? BM_DONT_SET : BM_DONT_CLEAR) & b->bm_flags) + if (bm_is_locked(b)) bm_print_lock_info(mdev); c = __bm_change_bits_to(mdev, s, e, val, KM_IRQ1); @@ -1432,11 +1187,12 @@ int drbd_bm_test_bit(struct drbd_conf *mdev, const unsigned long bitnr) ERR_IF(!b->bm_pages) return 0; spin_lock_irqsave(&b->bm_lock, flags); - if (BM_DONT_TEST & b->bm_flags) + if (bm_is_locked(b)) bm_print_lock_info(mdev); if (bitnr < b->bm_bits) { - p_addr = bm_map_pidx(b, bm_bit_to_page_idx(b, bitnr)); - i = test_bit_le(bitnr & BITS_PER_PAGE_MASK, p_addr) ? 1 : 0; + unsigned long offset = bitnr>>LN2_BPL; + p_addr = bm_map_paddr(b, offset); + i = test_bit(bitnr & BPP_MASK, p_addr) ? 1 : 0; bm_unmap(p_addr); } else if (bitnr == b->bm_bits) { i = -1; @@ -1454,10 +1210,10 @@ int drbd_bm_count_bits(struct drbd_conf *mdev, const unsigned long s, const unsi { unsigned long flags; struct drbd_bitmap *b = mdev->bitmap; - unsigned long *p_addr = NULL; + unsigned long *p_addr = NULL, page_nr = -1; unsigned long bitnr; - unsigned int page_nr = -1U; int c = 0; + size_t w; /* If this is called without a bitmap, that is a bug. But just to be * robust in case we screwed up elsewhere, in that case pretend there @@ -1467,20 +1223,20 @@ int drbd_bm_count_bits(struct drbd_conf *mdev, const unsigned long s, const unsi ERR_IF(!b->bm_pages) return 1; spin_lock_irqsave(&b->bm_lock, flags); - if (BM_DONT_TEST & b->bm_flags) + if (bm_is_locked(b)) bm_print_lock_info(mdev); for (bitnr = s; bitnr <= e; bitnr++) { - unsigned int idx = bm_bit_to_page_idx(b, bitnr); - if (page_nr != idx) { - page_nr = idx; + w = bitnr >> LN2_BPL; + if (page_nr != w >> (PAGE_SHIFT - LN2_BPL + 3)) { + page_nr = w >> (PAGE_SHIFT - LN2_BPL + 3); if (p_addr) bm_unmap(p_addr); - p_addr = bm_map_pidx(b, idx); + p_addr = bm_map_paddr(b, w); } ERR_IF (bitnr >= b->bm_bits) { dev_err(DEV, "bitnr=%lu bm_bits=%lu\n", bitnr, b->bm_bits); } else { - c += (0 != test_bit_le(bitnr - (page_nr << (PAGE_SHIFT+3)), p_addr)); + c += (0 != test_bit(bitnr - (page_nr << (PAGE_SHIFT+3)), p_addr)); } } if (p_addr) @@ -1515,7 +1271,7 @@ int drbd_bm_e_weight(struct drbd_conf *mdev, unsigned long enr) ERR_IF(!b->bm_pages) return 0; spin_lock_irqsave(&b->bm_lock, flags); - if (BM_DONT_TEST & b->bm_flags) + if (bm_is_locked(b)) bm_print_lock_info(mdev); s = S2W(enr); @@ -1523,7 +1279,7 @@ int drbd_bm_e_weight(struct drbd_conf *mdev, unsigned long enr) count = 0; if (s < b->bm_words) { int n = e-s; - p_addr = bm_map_pidx(b, bm_word_to_page_idx(b, s)); + p_addr = bm_map_paddr(b, s); bm = p_addr + MLPP(s); while (n--) count += hweight_long(*bm++); @@ -1535,20 +1291,18 @@ int drbd_bm_e_weight(struct drbd_conf *mdev, unsigned long enr) return count; } -/* Set all bits covered by the AL-extent al_enr. - * Returns number of bits changed. */ +/* set all bits covered by the AL-extent al_enr */ unsigned long drbd_bm_ALe_set_all(struct drbd_conf *mdev, unsigned long al_enr) { struct drbd_bitmap *b = mdev->bitmap; unsigned long *p_addr, *bm; unsigned long weight; - unsigned long s, e; - int count, i, do_now; + int count, s, e, i, do_now; ERR_IF(!b) return 0; ERR_IF(!b->bm_pages) return 0; spin_lock_irq(&b->bm_lock); - if (BM_DONT_SET & b->bm_flags) + if (bm_is_locked(b)) bm_print_lock_info(mdev); weight = b->bm_set; @@ -1560,7 +1314,7 @@ unsigned long drbd_bm_ALe_set_all(struct drbd_conf *mdev, unsigned long al_enr) count = 0; if (s < b->bm_words) { i = do_now = e-s; - p_addr = bm_map_pidx(b, bm_word_to_page_idx(b, s)); + p_addr = bm_map_paddr(b, s); bm = p_addr + MLPP(s); while (i--) { count += hweight_long(*bm); @@ -1572,7 +1326,7 @@ unsigned long drbd_bm_ALe_set_all(struct drbd_conf *mdev, unsigned long al_enr) if (e == b->bm_words) b->bm_set -= bm_clear_surplus(b); } else { - dev_err(DEV, "start offset (%lu) too large in drbd_bm_ALe_set_all\n", s); + dev_err(DEV, "start offset (%d) too large in drbd_bm_ALe_set_all\n", s); } weight = b->bm_set - weight; spin_unlock_irq(&b->bm_lock); diff --git a/trunk/drivers/block/drbd/drbd_int.h b/trunk/drivers/block/drbd/drbd_int.h index 81030d8d654b..b0bd27dfc1e8 100644 --- a/trunk/drivers/block/drbd/drbd_int.h +++ b/trunk/drivers/block/drbd/drbd_int.h @@ -72,6 +72,13 @@ extern int fault_devs; extern char usermode_helper[]; +#ifndef TRUE +#define TRUE 1 +#endif +#ifndef FALSE +#define FALSE 0 +#endif + /* I don't remember why XCPU ... * This is used to wake the asender, * and to interrupt sending the sending task @@ -97,7 +104,6 @@ extern char usermode_helper[]; #define ID_SYNCER (-1ULL) #define ID_VACANT 0 #define is_syncer_block_id(id) ((id) == ID_SYNCER) -#define UUID_NEW_BM_OFFSET ((u64)0x0001000000000000ULL) struct drbd_conf; @@ -131,19 +137,20 @@ enum { DRBD_FAULT_MAX, }; +#ifdef CONFIG_DRBD_FAULT_INJECTION extern unsigned int _drbd_insert_fault(struct drbd_conf *mdev, unsigned int type); - static inline int drbd_insert_fault(struct drbd_conf *mdev, unsigned int type) { -#ifdef CONFIG_DRBD_FAULT_INJECTION return fault_rate && (enable_faults & (1< P_MAY_IGNORE) ... */ P_MAX_OPT_CMD = 0x101, @@ -264,7 +269,6 @@ static inline const char *cmdname(enum drbd_packets cmd) [P_RS_IS_IN_SYNC] = "CsumRSIsInSync", [P_COMPRESSED_BITMAP] = "CBitmap", [P_DELAY_PROBE] = "DelayProbe", - [P_OUT_OF_SYNC] = "OutOfSync", [P_MAX_CMD] = NULL, }; @@ -508,7 +512,7 @@ struct p_sizes { u64 d_size; /* size of disk */ u64 u_size; /* user requested size */ u64 c_size; /* current exported size */ - u32 max_bio_size; /* Maximal size of a BIO */ + u32 max_segment_size; /* Maximal size of a BIO */ u16 queue_order_type; /* not yet implemented in DRBD*/ u16 dds_flags; /* use enum dds_flags here. */ } __packed; @@ -546,13 +550,6 @@ struct p_discard { u32 pad; } __packed; -struct p_block_desc { - struct p_header80 head; - u64 sector; - u32 blksize; - u32 pad; /* to multiple of 8 Byte */ -} __packed; - /* Valid values for the encoding field. * Bump proto version when changing this. */ enum drbd_bitmap_code { @@ -650,7 +647,6 @@ union p_polymorph { struct p_block_req block_req; struct p_delay_probe93 delay_probe93; struct p_rs_uuid rs_uuid; - struct p_block_desc block_desc; } __packed; /**********************************************************************/ @@ -681,6 +677,13 @@ static inline enum drbd_thread_state get_t_state(struct drbd_thread *thi) return thi->t_state; } + +/* + * Having this as the first member of a struct provides sort of "inheritance". + * "derived" structs can be "drbd_queue_work()"ed. + * The callback should know and cast back to the descendant struct. + * drbd_request and drbd_epoch_entry are descendants of drbd_work. + */ struct drbd_work; typedef int (*drbd_work_cb)(struct drbd_conf *, struct drbd_work *, int cancel); struct drbd_work { @@ -709,6 +712,9 @@ struct drbd_request { * starting a new epoch... */ + /* up to here, the struct layout is identical to drbd_epoch_entry; + * we might be able to use that to our advantage... */ + struct list_head tl_requests; /* ring list in the transfer log */ struct bio *master_bio; /* master bio pointer */ unsigned long rq_state; /* see comments above _req_mod() */ @@ -825,7 +831,7 @@ enum { CRASHED_PRIMARY, /* This node was a crashed primary. * Gets cleared when the state.conn * goes into C_CONNECTED state. */ - NO_BARRIER_SUPP, /* underlying block device doesn't implement barriers */ + WRITE_BM_AFTER_RESYNC, /* A kmalloc() during resync failed */ CONSIDER_RESYNC, MD_NO_FUA, /* Users wants us to not use FUA/FLUSH on meta data dev */ @@ -850,37 +856,10 @@ enum { GOT_PING_ACK, /* set when we receive a ping_ack packet, misc wait gets woken */ NEW_CUR_UUID, /* Create new current UUID when thawing IO */ AL_SUSPENDED, /* Activity logging is currently suspended. */ - AHEAD_TO_SYNC_SOURCE, /* Ahead -> SyncSource queued */ }; struct drbd_bitmap; /* opaque for drbd_conf */ -/* definition of bits in bm_flags to be used in drbd_bm_lock - * and drbd_bitmap_io and friends. */ -enum bm_flag { - /* do we need to kfree, or vfree bm_pages? */ - BM_P_VMALLOCED = 0x10000, /* internal use only, will be masked out */ - - /* currently locked for bulk operation */ - BM_LOCKED_MASK = 0x7, - - /* in detail, that is: */ - BM_DONT_CLEAR = 0x1, - BM_DONT_SET = 0x2, - BM_DONT_TEST = 0x4, - - /* (test bit, count bit) allowed (common case) */ - BM_LOCKED_TEST_ALLOWED = 0x3, - - /* testing bits, as well as setting new bits allowed, but clearing bits - * would be unexpected. Used during bitmap receive. Setting new bits - * requires sending of "out-of-sync" information, though. */ - BM_LOCKED_SET_ALLOWED = 0x1, - - /* clear is not expected while bitmap is locked for bulk operation */ -}; - - /* TODO sort members for performance * MAYBE group them further */ @@ -946,7 +925,6 @@ struct drbd_md_io { struct bm_io_work { struct drbd_work w; char *why; - enum bm_flag flags; int (*io_fn)(struct drbd_conf *mdev); void (*done)(struct drbd_conf *mdev, int rv); }; @@ -985,12 +963,9 @@ struct drbd_conf { struct drbd_work resync_work, unplug_work, go_diskless, - md_sync_work, - start_resync_work; + md_sync_work; struct timer_list resync_timer; struct timer_list md_sync_timer; - struct timer_list start_resync_timer; - struct timer_list request_timer; #ifdef DRBD_DEBUG_MD_SYNC struct { unsigned int line; @@ -1025,9 +1000,9 @@ struct drbd_conf { struct hlist_head *tl_hash; unsigned int tl_hash_s; - /* blocks to resync in this run [unit BM_BLOCK_SIZE] */ + /* blocks to sync in this run [unit BM_BLOCK_SIZE] */ unsigned long rs_total; - /* number of resync blocks that failed in this run */ + /* number of sync IOs that failed in this run */ unsigned long rs_failed; /* Syncer's start time [unit jiffies] */ unsigned long rs_start; @@ -1127,7 +1102,6 @@ struct drbd_conf { struct fifo_buffer rs_plan_s; /* correction values of resync planer */ int rs_in_flight; /* resync sectors in flight (to proxy, in proxy and from proxy) */ int rs_planed; /* resync sectors already planed */ - atomic_t ap_in_flight; /* App sectors in flight (waiting for ack) */ }; static inline struct drbd_conf *minor_to_mdev(unsigned int minor) @@ -1189,19 +1163,14 @@ enum dds_flags { }; extern void drbd_init_set_defaults(struct drbd_conf *mdev); -extern enum drbd_state_rv drbd_change_state(struct drbd_conf *mdev, - enum chg_state_flags f, - union drbd_state mask, - union drbd_state val); +extern int drbd_change_state(struct drbd_conf *mdev, enum chg_state_flags f, + union drbd_state mask, union drbd_state val); extern void drbd_force_state(struct drbd_conf *, union drbd_state, union drbd_state); -extern enum drbd_state_rv _drbd_request_state(struct drbd_conf *, - union drbd_state, - union drbd_state, - enum chg_state_flags); -extern enum drbd_state_rv __drbd_set_state(struct drbd_conf *, union drbd_state, - enum chg_state_flags, - struct completion *done); +extern int _drbd_request_state(struct drbd_conf *, union drbd_state, + union drbd_state, enum chg_state_flags); +extern int __drbd_set_state(struct drbd_conf *, union drbd_state, + enum chg_state_flags, struct completion *done); extern void print_st_err(struct drbd_conf *, union drbd_state, union drbd_state, int); extern int drbd_thread_start(struct drbd_thread *thi); @@ -1226,7 +1195,7 @@ extern int drbd_send(struct drbd_conf *mdev, struct socket *sock, extern int drbd_send_protocol(struct drbd_conf *mdev); extern int drbd_send_uuids(struct drbd_conf *mdev); extern int drbd_send_uuids_skip_initial_sync(struct drbd_conf *mdev); -extern int drbd_gen_and_send_sync_uuid(struct drbd_conf *mdev); +extern int drbd_send_sync_uuid(struct drbd_conf *mdev, u64 val); extern int drbd_send_sizes(struct drbd_conf *mdev, int trigger_reply, enum dds_flags flags); extern int _drbd_send_state(struct drbd_conf *mdev); extern int drbd_send_state(struct drbd_conf *mdev); @@ -1251,10 +1220,11 @@ extern int drbd_send_ack_dp(struct drbd_conf *mdev, enum drbd_packets cmd, struct p_data *dp, int data_size); extern int drbd_send_ack_ex(struct drbd_conf *mdev, enum drbd_packets cmd, sector_t sector, int blksize, u64 block_id); -extern int drbd_send_oos(struct drbd_conf *mdev, struct drbd_request *req); extern int drbd_send_block(struct drbd_conf *mdev, enum drbd_packets cmd, struct drbd_epoch_entry *e); extern int drbd_send_dblock(struct drbd_conf *mdev, struct drbd_request *req); +extern int _drbd_send_barrier(struct drbd_conf *mdev, + struct drbd_tl_epoch *barrier); extern int drbd_send_drequest(struct drbd_conf *mdev, int cmd, sector_t sector, int size, u64 block_id); extern int drbd_send_drequest_csum(struct drbd_conf *mdev, @@ -1265,13 +1235,14 @@ extern int drbd_send_ov_request(struct drbd_conf *mdev,sector_t sector,int size) extern int drbd_send_bitmap(struct drbd_conf *mdev); extern int _drbd_send_bitmap(struct drbd_conf *mdev); -extern int drbd_send_sr_reply(struct drbd_conf *mdev, enum drbd_state_rv retcode); +extern int drbd_send_sr_reply(struct drbd_conf *mdev, int retcode); extern void drbd_free_bc(struct drbd_backing_dev *ldev); extern void drbd_mdev_cleanup(struct drbd_conf *mdev); -void drbd_print_uuids(struct drbd_conf *mdev, const char *text); +/* drbd_meta-data.c (still in drbd_main.c) */ extern void drbd_md_sync(struct drbd_conf *mdev); extern int drbd_md_read(struct drbd_conf *mdev, struct drbd_backing_dev *bdev); +/* maybe define them below as inline? */ extern void drbd_uuid_set(struct drbd_conf *mdev, int idx, u64 val) __must_hold(local); extern void _drbd_uuid_set(struct drbd_conf *mdev, int idx, u64 val) __must_hold(local); extern void drbd_uuid_new_current(struct drbd_conf *mdev) __must_hold(local); @@ -1290,12 +1261,10 @@ extern void drbd_md_mark_dirty_(struct drbd_conf *mdev, extern void drbd_queue_bitmap_io(struct drbd_conf *mdev, int (*io_fn)(struct drbd_conf *), void (*done)(struct drbd_conf *, int), - char *why, enum bm_flag flags); -extern int drbd_bitmap_io(struct drbd_conf *mdev, - int (*io_fn)(struct drbd_conf *), - char *why, enum bm_flag flags); + char *why); extern int drbd_bmio_set_n_write(struct drbd_conf *mdev); extern int drbd_bmio_clear_n_write(struct drbd_conf *mdev); +extern int drbd_bitmap_io(struct drbd_conf *mdev, int (*io_fn)(struct drbd_conf *), char *why); extern void drbd_go_diskless(struct drbd_conf *mdev); extern void drbd_ldev_destroy(struct drbd_conf *mdev); @@ -1344,7 +1313,6 @@ struct bm_extent { #define BME_NO_WRITES 0 /* bm_extent.flags: no more requests on this one! */ #define BME_LOCKED 1 /* bm_extent.flags: syncer active on this one. */ -#define BME_PRIORITY 2 /* finish resync IO on this extent ASAP! App IO waiting! */ /* drbd_bitmap.c */ /* @@ -1422,9 +1390,7 @@ struct bm_extent { * you should use 64bit OS for that much storage, anyways. */ #define DRBD_MAX_SECTORS_FLEX BM_BIT_TO_SECT(0xffff7fff) #else -/* we allow up to 1 PiB now on 64bit architecture with "flexible" meta data */ -#define DRBD_MAX_SECTORS_FLEX (1UL << 51) -/* corresponds to (1UL << 38) bits right now. */ +#define DRBD_MAX_SECTORS_FLEX BM_BIT_TO_SECT(0x1LU << 32) #endif #endif @@ -1432,7 +1398,7 @@ struct bm_extent { * With a value of 8 all IO in one 128K block make it to the same slot of the * hash table. */ #define HT_SHIFT 8 -#define DRBD_MAX_BIO_SIZE (1U<<(9+HT_SHIFT)) +#define DRBD_MAX_SEGMENT_SIZE (1U<<(9+HT_SHIFT)) #define DRBD_MAX_SIZE_H80_PACKET (1 << 15) /* The old header only allows packets up to 32Kib data */ @@ -1444,20 +1410,16 @@ extern int drbd_bm_resize(struct drbd_conf *mdev, sector_t sectors, int set_new extern void drbd_bm_cleanup(struct drbd_conf *mdev); extern void drbd_bm_set_all(struct drbd_conf *mdev); extern void drbd_bm_clear_all(struct drbd_conf *mdev); -/* set/clear/test only a few bits at a time */ extern int drbd_bm_set_bits( struct drbd_conf *mdev, unsigned long s, unsigned long e); extern int drbd_bm_clear_bits( struct drbd_conf *mdev, unsigned long s, unsigned long e); -extern int drbd_bm_count_bits( - struct drbd_conf *mdev, const unsigned long s, const unsigned long e); -/* bm_set_bits variant for use while holding drbd_bm_lock, - * may process the whole bitmap in one go */ +/* bm_set_bits variant for use while holding drbd_bm_lock */ extern void _drbd_bm_set_bits(struct drbd_conf *mdev, const unsigned long s, const unsigned long e); extern int drbd_bm_test_bit(struct drbd_conf *mdev, unsigned long bitnr); extern int drbd_bm_e_weight(struct drbd_conf *mdev, unsigned long enr); -extern int drbd_bm_write_page(struct drbd_conf *mdev, unsigned int idx) __must_hold(local); +extern int drbd_bm_write_sect(struct drbd_conf *mdev, unsigned long enr) __must_hold(local); extern int drbd_bm_read(struct drbd_conf *mdev) __must_hold(local); extern int drbd_bm_write(struct drbd_conf *mdev) __must_hold(local); extern unsigned long drbd_bm_ALe_set_all(struct drbd_conf *mdev, @@ -1465,8 +1427,6 @@ extern unsigned long drbd_bm_ALe_set_all(struct drbd_conf *mdev, extern size_t drbd_bm_words(struct drbd_conf *mdev); extern unsigned long drbd_bm_bits(struct drbd_conf *mdev); extern sector_t drbd_bm_capacity(struct drbd_conf *mdev); - -#define DRBD_END_OF_BITMAP (~(unsigned long)0) extern unsigned long drbd_bm_find_next(struct drbd_conf *mdev, unsigned long bm_fo); /* bm_find_next variants for use while you hold drbd_bm_lock() */ extern unsigned long _drbd_bm_find_next(struct drbd_conf *mdev, unsigned long bm_fo); @@ -1477,12 +1437,14 @@ extern int drbd_bm_rs_done(struct drbd_conf *mdev); /* for receive_bitmap */ extern void drbd_bm_merge_lel(struct drbd_conf *mdev, size_t offset, size_t number, unsigned long *buffer); -/* for _drbd_send_bitmap */ +/* for _drbd_send_bitmap and drbd_bm_write_sect */ extern void drbd_bm_get_lel(struct drbd_conf *mdev, size_t offset, size_t number, unsigned long *buffer); -extern void drbd_bm_lock(struct drbd_conf *mdev, char *why, enum bm_flag flags); +extern void drbd_bm_lock(struct drbd_conf *mdev, char *why); extern void drbd_bm_unlock(struct drbd_conf *mdev); + +extern int drbd_bm_count_bits(struct drbd_conf *mdev, const unsigned long s, const unsigned long e); /* drbd_main.c */ extern struct kmem_cache *drbd_request_cache; @@ -1505,7 +1467,7 @@ extern void drbd_free_mdev(struct drbd_conf *mdev); extern int proc_details; /* drbd_req */ -extern int drbd_make_request(struct request_queue *q, struct bio *bio); +extern int drbd_make_request_26(struct request_queue *q, struct bio *bio); extern int drbd_read_remote(struct drbd_conf *mdev, struct drbd_request *req); extern int drbd_merge_bvec(struct request_queue *q, struct bvec_merge_data *bvm, struct bio_vec *bvec); extern int is_valid_ar_handle(struct drbd_request *, sector_t); @@ -1520,9 +1482,8 @@ enum determine_dev_size { dev_size_error = -1, unchanged = 0, shrunk = 1, grew = extern enum determine_dev_size drbd_determin_dev_size(struct drbd_conf *, enum dds_flags) __must_hold(local); extern void resync_after_online_grow(struct drbd_conf *); extern void drbd_setup_queue_param(struct drbd_conf *mdev, unsigned int) __must_hold(local); -extern enum drbd_state_rv drbd_set_role(struct drbd_conf *mdev, - enum drbd_role new_role, - int force); +extern int drbd_set_role(struct drbd_conf *mdev, enum drbd_role new_role, + int force); extern enum drbd_disk_state drbd_try_outdate_peer(struct drbd_conf *mdev); extern void drbd_try_outdate_peer_async(struct drbd_conf *mdev); extern int drbd_khelper(struct drbd_conf *mdev, char *cmd); @@ -1538,7 +1499,6 @@ extern int drbd_resync_finished(struct drbd_conf *mdev); extern int drbd_md_sync_page_io(struct drbd_conf *mdev, struct drbd_backing_dev *bdev, sector_t sector, int rw); extern void drbd_ov_oos_found(struct drbd_conf*, sector_t, int); -extern void drbd_rs_controller_reset(struct drbd_conf *mdev); static inline void ov_oos_print(struct drbd_conf *mdev) { @@ -1562,23 +1522,21 @@ extern int w_e_end_csum_rs_req(struct drbd_conf *, struct drbd_work *, int); extern int w_e_end_ov_reply(struct drbd_conf *, struct drbd_work *, int); extern int w_e_end_ov_req(struct drbd_conf *, struct drbd_work *, int); extern int w_ov_finished(struct drbd_conf *, struct drbd_work *, int); -extern int w_resync_timer(struct drbd_conf *, struct drbd_work *, int); +extern int w_resync_inactive(struct drbd_conf *, struct drbd_work *, int); extern int w_resume_next_sg(struct drbd_conf *, struct drbd_work *, int); extern int w_send_write_hint(struct drbd_conf *, struct drbd_work *, int); +extern int w_make_resync_request(struct drbd_conf *, struct drbd_work *, int); extern int w_send_dblock(struct drbd_conf *, struct drbd_work *, int); extern int w_send_barrier(struct drbd_conf *, struct drbd_work *, int); extern int w_send_read_req(struct drbd_conf *, struct drbd_work *, int); extern int w_prev_work_done(struct drbd_conf *, struct drbd_work *, int); extern int w_e_reissue(struct drbd_conf *, struct drbd_work *, int); extern int w_restart_disk_io(struct drbd_conf *, struct drbd_work *, int); -extern int w_send_oos(struct drbd_conf *, struct drbd_work *, int); -extern int w_start_resync(struct drbd_conf *, struct drbd_work *, int); extern void resync_timer_fn(unsigned long data); -extern void start_resync_timer_fn(unsigned long data); /* drbd_receiver.c */ -extern int drbd_rs_should_slow_down(struct drbd_conf *mdev, sector_t sector); +extern int drbd_rs_should_slow_down(struct drbd_conf *mdev); extern int drbd_submit_ee(struct drbd_conf *mdev, struct drbd_epoch_entry *e, const unsigned rw, const int fault_type); extern int drbd_release_ee(struct drbd_conf *mdev, struct list_head *list); @@ -1661,16 +1619,16 @@ extern int drbd_rs_del_all(struct drbd_conf *mdev); extern void drbd_rs_failed_io(struct drbd_conf *mdev, sector_t sector, int size); extern int drbd_al_read_log(struct drbd_conf *mdev, struct drbd_backing_dev *); -extern void drbd_advance_rs_marks(struct drbd_conf *mdev, unsigned long still_to_go); extern void __drbd_set_in_sync(struct drbd_conf *mdev, sector_t sector, int size, const char *file, const unsigned int line); #define drbd_set_in_sync(mdev, sector, size) \ __drbd_set_in_sync(mdev, sector, size, __FILE__, __LINE__) -extern int __drbd_set_out_of_sync(struct drbd_conf *mdev, sector_t sector, +extern void __drbd_set_out_of_sync(struct drbd_conf *mdev, sector_t sector, int size, const char *file, const unsigned int line); #define drbd_set_out_of_sync(mdev, sector, size) \ __drbd_set_out_of_sync(mdev, sector, size, __FILE__, __LINE__) extern void drbd_al_apply_to_bm(struct drbd_conf *mdev); +extern void drbd_al_to_on_disk_bm(struct drbd_conf *mdev); extern void drbd_al_shrink(struct drbd_conf *mdev); @@ -1789,11 +1747,11 @@ static inline void drbd_state_unlock(struct drbd_conf *mdev) wake_up(&mdev->misc_wait); } -static inline enum drbd_state_rv -_drbd_set_state(struct drbd_conf *mdev, union drbd_state ns, - enum chg_state_flags flags, struct completion *done) +static inline int _drbd_set_state(struct drbd_conf *mdev, + union drbd_state ns, enum chg_state_flags flags, + struct completion *done) { - enum drbd_state_rv rv; + int rv; read_lock(&global_state_lock); rv = __drbd_set_state(mdev, ns, flags, done); @@ -2024,17 +1982,17 @@ static inline int drbd_send_ping_ack(struct drbd_conf *mdev) static inline void drbd_thread_stop(struct drbd_thread *thi) { - _drbd_thread_stop(thi, false, true); + _drbd_thread_stop(thi, FALSE, TRUE); } static inline void drbd_thread_stop_nowait(struct drbd_thread *thi) { - _drbd_thread_stop(thi, false, false); + _drbd_thread_stop(thi, FALSE, FALSE); } static inline void drbd_thread_restart_nowait(struct drbd_thread *thi) { - _drbd_thread_stop(thi, true, false); + _drbd_thread_stop(thi, TRUE, FALSE); } /* counts how many answer packets packets we expect from our peer, @@ -2188,18 +2146,17 @@ extern int _get_ldev_if_state(struct drbd_conf *mdev, enum drbd_disk_state mins) static inline void drbd_get_syncer_progress(struct drbd_conf *mdev, unsigned long *bits_left, unsigned int *per_mil_done) { - /* this is to break it at compile time when we change that, in case we - * want to support more than (1<<32) bits on a 32bit arch. */ + /* + * this is to break it at compile time when we change that + * (we may feel 4TB maximum storage per drbd is not enough) + */ typecheck(unsigned long, mdev->rs_total); /* note: both rs_total and rs_left are in bits, i.e. in * units of BM_BLOCK_SIZE. * for the percentage, we don't care. */ - if (mdev->state.conn == C_VERIFY_S || mdev->state.conn == C_VERIFY_T) - *bits_left = mdev->ov_left; - else - *bits_left = drbd_bm_total_weight(mdev) - mdev->rs_failed; + *bits_left = drbd_bm_total_weight(mdev) - mdev->rs_failed; /* >> 10 to prevent overflow, * +1 to prevent division by zero */ if (*bits_left > mdev->rs_total) { @@ -2214,19 +2171,10 @@ static inline void drbd_get_syncer_progress(struct drbd_conf *mdev, *bits_left, mdev->rs_total, mdev->rs_failed); *per_mil_done = 0; } else { - /* Make sure the division happens in long context. - * We allow up to one petabyte storage right now, - * at a granularity of 4k per bit that is 2**38 bits. - * After shift right and multiplication by 1000, - * this should still fit easily into a 32bit long, - * so we don't need a 64bit division on 32bit arch. - * Note: currently we don't support such large bitmaps on 32bit - * arch anyways, but no harm done to be prepared for it here. - */ - unsigned int shift = mdev->rs_total >= (1ULL << 32) ? 16 : 10; - unsigned long left = *bits_left >> shift; - unsigned long total = 1UL + (mdev->rs_total >> shift); - unsigned long tmp = 1000UL - left * 1000UL/total; + /* make sure the calculation happens in long context */ + unsigned long tmp = 1000UL - + (*bits_left >> 10)*1000UL + / ((mdev->rs_total >> 10) + 1UL); *per_mil_done = tmp; } } @@ -2245,9 +2193,8 @@ static inline int drbd_get_max_buffers(struct drbd_conf *mdev) return mxb; } -static inline int drbd_state_is_stable(struct drbd_conf *mdev) +static inline int drbd_state_is_stable(union drbd_state s) { - union drbd_state s = mdev->state; /* DO NOT add a default clause, we want the compiler to warn us * for any newly introduced state we may have forgotten to add here */ @@ -2264,9 +2211,11 @@ static inline int drbd_state_is_stable(struct drbd_conf *mdev) case C_VERIFY_T: case C_PAUSED_SYNC_S: case C_PAUSED_SYNC_T: - case C_AHEAD: - case C_BEHIND: - /* transitional states, IO allowed */ + /* maybe stable, look at the disk state */ + break; + + /* no new io accepted during tansitional states + * like handshake or teardown */ case C_DISCONNECTING: case C_UNCONNECTED: case C_TIMEOUT: @@ -2277,15 +2226,7 @@ static inline int drbd_state_is_stable(struct drbd_conf *mdev) case C_WF_REPORT_PARAMS: case C_STARTING_SYNC_S: case C_STARTING_SYNC_T: - break; - - /* Allow IO in BM exchange states with new protocols */ case C_WF_BITMAP_S: - if (mdev->agreed_pro_version < 96) - return 0; - break; - - /* no new io accepted in these states */ case C_WF_BITMAP_T: case C_WF_SYNC_UUID: case C_MASK: @@ -2320,47 +2261,41 @@ static inline int is_susp(union drbd_state s) return s.susp || s.susp_nod || s.susp_fen; } -static inline bool may_inc_ap_bio(struct drbd_conf *mdev) +static inline int __inc_ap_bio_cond(struct drbd_conf *mdev) { int mxb = drbd_get_max_buffers(mdev); if (is_susp(mdev->state)) - return false; + return 0; if (test_bit(SUSPEND_IO, &mdev->flags)) - return false; + return 0; /* to avoid potential deadlock or bitmap corruption, * in various places, we only allow new application io * to start during "stable" states. */ /* no new io accepted when attaching or detaching the disk */ - if (!drbd_state_is_stable(mdev)) - return false; + if (!drbd_state_is_stable(mdev->state)) + return 0; /* since some older kernels don't have atomic_add_unless, * and we are within the spinlock anyways, we have this workaround. */ if (atomic_read(&mdev->ap_bio_cnt) > mxb) - return false; + return 0; if (test_bit(BITMAP_IO, &mdev->flags)) - return false; - return true; -} - -static inline bool inc_ap_bio_cond(struct drbd_conf *mdev, int count) -{ - bool rv = false; - - spin_lock_irq(&mdev->req_lock); - rv = may_inc_ap_bio(mdev); - if (rv) - atomic_add(count, &mdev->ap_bio_cnt); - spin_unlock_irq(&mdev->req_lock); - - return rv; + return 0; + return 1; } +/* I'd like to use wait_event_lock_irq, + * but I'm not sure when it got introduced, + * and not sure when it has 3 or 4 arguments */ static inline void inc_ap_bio(struct drbd_conf *mdev, int count) { + /* compare with after_state_ch, + * os.conn != C_WF_BITMAP_S && ns.conn == C_WF_BITMAP_S */ + DEFINE_WAIT(wait); + /* we wait here * as long as the device is suspended * until the bitmap is no longer on the fly during connection @@ -2369,7 +2304,16 @@ static inline void inc_ap_bio(struct drbd_conf *mdev, int count) * to avoid races with the reconnect code, * we need to atomic_inc within the spinlock. */ - wait_event(mdev->misc_wait, inc_ap_bio_cond(mdev, count)); + spin_lock_irq(&mdev->req_lock); + while (!__inc_ap_bio_cond(mdev)) { + prepare_to_wait(&mdev->misc_wait, &wait, TASK_UNINTERRUPTIBLE); + spin_unlock_irq(&mdev->req_lock); + schedule(); + finish_wait(&mdev->misc_wait, &wait); + spin_lock_irq(&mdev->req_lock); + } + atomic_add(count, &mdev->ap_bio_cnt); + spin_unlock_irq(&mdev->req_lock); } static inline void dec_ap_bio(struct drbd_conf *mdev) @@ -2389,11 +2333,9 @@ static inline void dec_ap_bio(struct drbd_conf *mdev) } } -static inline int drbd_set_ed_uuid(struct drbd_conf *mdev, u64 val) +static inline void drbd_set_ed_uuid(struct drbd_conf *mdev, u64 val) { - int changed = mdev->ed_uuid != val; mdev->ed_uuid = val; - return changed; } static inline int seq_cmp(u32 a, u32 b) diff --git a/trunk/drivers/block/drbd/drbd_main.c b/trunk/drivers/block/drbd/drbd_main.c index dfc85f32d317..8a43ce0edeed 100644 --- a/trunk/drivers/block/drbd/drbd_main.c +++ b/trunk/drivers/block/drbd/drbd_main.c @@ -85,8 +85,7 @@ MODULE_AUTHOR("Philipp Reisner , " MODULE_DESCRIPTION("drbd - Distributed Replicated Block Device v" REL_VERSION); MODULE_VERSION(REL_VERSION); MODULE_LICENSE("GPL"); -MODULE_PARM_DESC(minor_count, "Maximum number of drbd devices (" - __stringify(DRBD_MINOR_COUNT_MIN) "-" __stringify(DRBD_MINOR_COUNT_MAX) ")"); +MODULE_PARM_DESC(minor_count, "Maximum number of drbd devices (1-255)"); MODULE_ALIAS_BLOCKDEV_MAJOR(DRBD_MAJOR); #include @@ -116,7 +115,7 @@ module_param(fault_devs, int, 0644); #endif /* module parameter, defined */ -unsigned int minor_count = DRBD_MINOR_COUNT_DEF; +unsigned int minor_count = 32; int disable_sendpage; int allow_oos; unsigned int cn_idx = CN_IDX_DRBD; @@ -336,7 +335,6 @@ void tl_release(struct drbd_conf *mdev, unsigned int barrier_nr, drbd_force_state(mdev, NS(conn, C_PROTOCOL_ERROR)); } - /** * _tl_restart() - Walks the transfer log, and applies an action to all requests * @mdev: DRBD device. @@ -458,7 +456,7 @@ void tl_restart(struct drbd_conf *mdev, enum drbd_req_event what) } /** - * cl_wide_st_chg() - true if the state change is a cluster wide one + * cl_wide_st_chg() - TRUE if the state change is a cluster wide one * @mdev: DRBD device. * @os: old (current) state. * @ns: new (wanted) state. @@ -475,13 +473,12 @@ static int cl_wide_st_chg(struct drbd_conf *mdev, (os.conn == C_CONNECTED && ns.conn == C_VERIFY_S); } -enum drbd_state_rv -drbd_change_state(struct drbd_conf *mdev, enum chg_state_flags f, - union drbd_state mask, union drbd_state val) +int drbd_change_state(struct drbd_conf *mdev, enum chg_state_flags f, + union drbd_state mask, union drbd_state val) { unsigned long flags; union drbd_state os, ns; - enum drbd_state_rv rv; + int rv; spin_lock_irqsave(&mdev->req_lock, flags); os = mdev->state; @@ -505,22 +502,20 @@ void drbd_force_state(struct drbd_conf *mdev, drbd_change_state(mdev, CS_HARD, mask, val); } -static enum drbd_state_rv is_valid_state(struct drbd_conf *, union drbd_state); -static enum drbd_state_rv is_valid_state_transition(struct drbd_conf *, - union drbd_state, - union drbd_state); +static int is_valid_state(struct drbd_conf *mdev, union drbd_state ns); +static int is_valid_state_transition(struct drbd_conf *, + union drbd_state, union drbd_state); static union drbd_state sanitize_state(struct drbd_conf *mdev, union drbd_state os, union drbd_state ns, const char **warn_sync_abort); int drbd_send_state_req(struct drbd_conf *, union drbd_state, union drbd_state); -static enum drbd_state_rv -_req_st_cond(struct drbd_conf *mdev, union drbd_state mask, - union drbd_state val) +static enum drbd_state_ret_codes _req_st_cond(struct drbd_conf *mdev, + union drbd_state mask, union drbd_state val) { union drbd_state os, ns; unsigned long flags; - enum drbd_state_rv rv; + int rv; if (test_and_clear_bit(CL_ST_CHG_SUCCESS, &mdev->flags)) return SS_CW_SUCCESS; @@ -541,7 +536,7 @@ _req_st_cond(struct drbd_conf *mdev, union drbd_state mask, if (rv == SS_SUCCESS) { rv = is_valid_state_transition(mdev, ns, os); if (rv == SS_SUCCESS) - rv = SS_UNKNOWN_ERROR; /* cont waiting, otherwise fail. */ + rv = 0; /* cont waiting, otherwise fail. */ } } spin_unlock_irqrestore(&mdev->req_lock, flags); @@ -559,14 +554,14 @@ _req_st_cond(struct drbd_conf *mdev, union drbd_state mask, * Should not be called directly, use drbd_request_state() or * _drbd_request_state(). */ -static enum drbd_state_rv -drbd_req_state(struct drbd_conf *mdev, union drbd_state mask, - union drbd_state val, enum chg_state_flags f) +static int drbd_req_state(struct drbd_conf *mdev, + union drbd_state mask, union drbd_state val, + enum chg_state_flags f) { struct completion done; unsigned long flags; union drbd_state os, ns; - enum drbd_state_rv rv; + int rv; init_completion(&done); @@ -641,11 +636,10 @@ drbd_req_state(struct drbd_conf *mdev, union drbd_state mask, * Cousin of drbd_request_state(), useful with the CS_WAIT_COMPLETE * flag, or when logging of failed state change requests is not desired. */ -enum drbd_state_rv -_drbd_request_state(struct drbd_conf *mdev, union drbd_state mask, - union drbd_state val, enum chg_state_flags f) +int _drbd_request_state(struct drbd_conf *mdev, union drbd_state mask, + union drbd_state val, enum chg_state_flags f) { - enum drbd_state_rv rv; + int rv; wait_event(mdev->state_wait, (rv = drbd_req_state(mdev, mask, val, f)) != SS_IN_TRANSIENT_STATE); @@ -669,8 +663,8 @@ static void print_st(struct drbd_conf *mdev, char *name, union drbd_state ns) ); } -void print_st_err(struct drbd_conf *mdev, union drbd_state os, - union drbd_state ns, enum drbd_state_rv err) +void print_st_err(struct drbd_conf *mdev, + union drbd_state os, union drbd_state ns, int err) { if (err == SS_IN_TRANSIENT_STATE) return; @@ -680,18 +674,32 @@ void print_st_err(struct drbd_conf *mdev, union drbd_state os, } +#define drbd_peer_str drbd_role_str +#define drbd_pdsk_str drbd_disk_str + +#define drbd_susp_str(A) ((A) ? "1" : "0") +#define drbd_aftr_isp_str(A) ((A) ? "1" : "0") +#define drbd_peer_isp_str(A) ((A) ? "1" : "0") +#define drbd_user_isp_str(A) ((A) ? "1" : "0") + +#define PSC(A) \ + ({ if (ns.A != os.A) { \ + pbp += sprintf(pbp, #A "( %s -> %s ) ", \ + drbd_##A##_str(os.A), \ + drbd_##A##_str(ns.A)); \ + } }) + /** * is_valid_state() - Returns an SS_ error code if ns is not valid * @mdev: DRBD device. * @ns: State to consider. */ -static enum drbd_state_rv -is_valid_state(struct drbd_conf *mdev, union drbd_state ns) +static int is_valid_state(struct drbd_conf *mdev, union drbd_state ns) { /* See drbd_state_sw_errors in drbd_strings.c */ enum drbd_fencing_p fp; - enum drbd_state_rv rv = SS_SUCCESS; + int rv = SS_SUCCESS; fp = FP_DONT_CARE; if (get_ldev(mdev)) { @@ -754,11 +762,10 @@ is_valid_state(struct drbd_conf *mdev, union drbd_state ns) * @ns: new state. * @os: old state. */ -static enum drbd_state_rv -is_valid_state_transition(struct drbd_conf *mdev, union drbd_state ns, - union drbd_state os) +static int is_valid_state_transition(struct drbd_conf *mdev, + union drbd_state ns, union drbd_state os) { - enum drbd_state_rv rv = SS_SUCCESS; + int rv = SS_SUCCESS; if ((ns.conn == C_STARTING_SYNC_T || ns.conn == C_STARTING_SYNC_S) && os.conn > C_CONNECTED) @@ -793,10 +800,6 @@ is_valid_state_transition(struct drbd_conf *mdev, union drbd_state ns, os.conn < C_CONNECTED) rv = SS_NEED_CONNECTION; - if ((ns.conn == C_SYNC_TARGET || ns.conn == C_SYNC_SOURCE) - && os.conn < C_WF_REPORT_PARAMS) - rv = SS_NEED_CONNECTION; /* No NetworkFailure -> SyncTarget etc... */ - return rv; } @@ -814,7 +817,6 @@ static union drbd_state sanitize_state(struct drbd_conf *mdev, union drbd_state union drbd_state ns, const char **warn_sync_abort) { enum drbd_fencing_p fp; - enum drbd_disk_state disk_min, disk_max, pdsk_min, pdsk_max; fp = FP_DONT_CARE; if (get_ldev(mdev)) { @@ -867,6 +869,56 @@ static union drbd_state sanitize_state(struct drbd_conf *mdev, union drbd_state ns.conn = C_CONNECTED; } + if (ns.conn >= C_CONNECTED && + ((ns.disk == D_CONSISTENT || ns.disk == D_OUTDATED) || + (ns.disk == D_NEGOTIATING && ns.conn == C_WF_BITMAP_T))) { + switch (ns.conn) { + case C_WF_BITMAP_T: + case C_PAUSED_SYNC_T: + ns.disk = D_OUTDATED; + break; + case C_CONNECTED: + case C_WF_BITMAP_S: + case C_SYNC_SOURCE: + case C_PAUSED_SYNC_S: + ns.disk = D_UP_TO_DATE; + break; + case C_SYNC_TARGET: + ns.disk = D_INCONSISTENT; + dev_warn(DEV, "Implicitly set disk state Inconsistent!\n"); + break; + } + if (os.disk == D_OUTDATED && ns.disk == D_UP_TO_DATE) + dev_warn(DEV, "Implicitly set disk from Outdated to UpToDate\n"); + } + + if (ns.conn >= C_CONNECTED && + (ns.pdsk == D_CONSISTENT || ns.pdsk == D_OUTDATED)) { + switch (ns.conn) { + case C_CONNECTED: + case C_WF_BITMAP_T: + case C_PAUSED_SYNC_T: + case C_SYNC_TARGET: + ns.pdsk = D_UP_TO_DATE; + break; + case C_WF_BITMAP_S: + case C_PAUSED_SYNC_S: + /* remap any consistent state to D_OUTDATED, + * but disallow "upgrade" of not even consistent states. + */ + ns.pdsk = + (D_DISKLESS < os.pdsk && os.pdsk < D_OUTDATED) + ? os.pdsk : D_OUTDATED; + break; + case C_SYNC_SOURCE: + ns.pdsk = D_INCONSISTENT; + dev_warn(DEV, "Implicitly set pdsk Inconsistent!\n"); + break; + } + if (os.pdsk == D_OUTDATED && ns.pdsk == D_UP_TO_DATE) + dev_warn(DEV, "Implicitly set pdsk from Outdated to UpToDate\n"); + } + /* Connection breaks down before we finished "Negotiating" */ if (ns.conn < C_CONNECTED && ns.disk == D_NEGOTIATING && get_ldev_if_state(mdev, D_NEGOTIATING)) { @@ -881,94 +933,6 @@ static union drbd_state sanitize_state(struct drbd_conf *mdev, union drbd_state put_ldev(mdev); } - /* D_CONSISTENT and D_OUTDATED vanish when we get connected */ - if (ns.conn >= C_CONNECTED && ns.conn < C_AHEAD) { - if (ns.disk == D_CONSISTENT || ns.disk == D_OUTDATED) - ns.disk = D_UP_TO_DATE; - if (ns.pdsk == D_CONSISTENT || ns.pdsk == D_OUTDATED) - ns.pdsk = D_UP_TO_DATE; - } - - /* Implications of the connection stat on the disk states */ - disk_min = D_DISKLESS; - disk_max = D_UP_TO_DATE; - pdsk_min = D_INCONSISTENT; - pdsk_max = D_UNKNOWN; - switch ((enum drbd_conns)ns.conn) { - case C_WF_BITMAP_T: - case C_PAUSED_SYNC_T: - case C_STARTING_SYNC_T: - case C_WF_SYNC_UUID: - case C_BEHIND: - disk_min = D_INCONSISTENT; - disk_max = D_OUTDATED; - pdsk_min = D_UP_TO_DATE; - pdsk_max = D_UP_TO_DATE; - break; - case C_VERIFY_S: - case C_VERIFY_T: - disk_min = D_UP_TO_DATE; - disk_max = D_UP_TO_DATE; - pdsk_min = D_UP_TO_DATE; - pdsk_max = D_UP_TO_DATE; - break; - case C_CONNECTED: - disk_min = D_DISKLESS; - disk_max = D_UP_TO_DATE; - pdsk_min = D_DISKLESS; - pdsk_max = D_UP_TO_DATE; - break; - case C_WF_BITMAP_S: - case C_PAUSED_SYNC_S: - case C_STARTING_SYNC_S: - case C_AHEAD: - disk_min = D_UP_TO_DATE; - disk_max = D_UP_TO_DATE; - pdsk_min = D_INCONSISTENT; - pdsk_max = D_CONSISTENT; /* D_OUTDATED would be nice. But explicit outdate necessary*/ - break; - case C_SYNC_TARGET: - disk_min = D_INCONSISTENT; - disk_max = D_INCONSISTENT; - pdsk_min = D_UP_TO_DATE; - pdsk_max = D_UP_TO_DATE; - break; - case C_SYNC_SOURCE: - disk_min = D_UP_TO_DATE; - disk_max = D_UP_TO_DATE; - pdsk_min = D_INCONSISTENT; - pdsk_max = D_INCONSISTENT; - break; - case C_STANDALONE: - case C_DISCONNECTING: - case C_UNCONNECTED: - case C_TIMEOUT: - case C_BROKEN_PIPE: - case C_NETWORK_FAILURE: - case C_PROTOCOL_ERROR: - case C_TEAR_DOWN: - case C_WF_CONNECTION: - case C_WF_REPORT_PARAMS: - case C_MASK: - break; - } - if (ns.disk > disk_max) - ns.disk = disk_max; - - if (ns.disk < disk_min) { - dev_warn(DEV, "Implicitly set disk from %s to %s\n", - drbd_disk_str(ns.disk), drbd_disk_str(disk_min)); - ns.disk = disk_min; - } - if (ns.pdsk > pdsk_max) - ns.pdsk = pdsk_max; - - if (ns.pdsk < pdsk_min) { - dev_warn(DEV, "Implicitly set pdsk from %s to %s\n", - drbd_disk_str(ns.pdsk), drbd_disk_str(pdsk_min)); - ns.pdsk = pdsk_min; - } - if (fp == FP_STONITH && (ns.role == R_PRIMARY && ns.conn < C_CONNECTED && ns.pdsk > D_OUTDATED) && !(os.role == R_PRIMARY && os.conn < C_CONNECTED && os.pdsk > D_OUTDATED)) @@ -997,10 +961,6 @@ static union drbd_state sanitize_state(struct drbd_conf *mdev, union drbd_state /* helper for __drbd_set_state */ static void set_ov_position(struct drbd_conf *mdev, enum drbd_conns cs) { - if (mdev->agreed_pro_version < 90) - mdev->ov_start_sector = 0; - mdev->rs_total = drbd_bm_bits(mdev); - mdev->ov_position = 0; if (cs == C_VERIFY_T) { /* starting online verify from an arbitrary position * does not fit well into the existing protocol. @@ -1010,15 +970,11 @@ static void set_ov_position(struct drbd_conf *mdev, enum drbd_conns cs) mdev->ov_start_sector = ~(sector_t)0; } else { unsigned long bit = BM_SECT_TO_BIT(mdev->ov_start_sector); - if (bit >= mdev->rs_total) { + if (bit >= mdev->rs_total) mdev->ov_start_sector = BM_BIT_TO_SECT(mdev->rs_total - 1); - mdev->rs_total = 1; - } else - mdev->rs_total -= bit; mdev->ov_position = mdev->ov_start_sector; } - mdev->ov_left = mdev->rs_total; } static void drbd_resume_al(struct drbd_conf *mdev) @@ -1036,12 +992,12 @@ static void drbd_resume_al(struct drbd_conf *mdev) * * Caller needs to hold req_lock, and global_state_lock. Do not call directly. */ -enum drbd_state_rv -__drbd_set_state(struct drbd_conf *mdev, union drbd_state ns, - enum chg_state_flags flags, struct completion *done) +int __drbd_set_state(struct drbd_conf *mdev, + union drbd_state ns, enum chg_state_flags flags, + struct completion *done) { union drbd_state os; - enum drbd_state_rv rv = SS_SUCCESS; + int rv = SS_SUCCESS; const char *warn_sync_abort = NULL; struct after_state_chg_work *ascw; @@ -1077,46 +1033,22 @@ __drbd_set_state(struct drbd_conf *mdev, union drbd_state ns, dev_warn(DEV, "%s aborted.\n", warn_sync_abort); { - char *pbp, pb[300]; - pbp = pb; - *pbp = 0; - if (ns.role != os.role) - pbp += sprintf(pbp, "role( %s -> %s ) ", - drbd_role_str(os.role), - drbd_role_str(ns.role)); - if (ns.peer != os.peer) - pbp += sprintf(pbp, "peer( %s -> %s ) ", - drbd_role_str(os.peer), - drbd_role_str(ns.peer)); - if (ns.conn != os.conn) - pbp += sprintf(pbp, "conn( %s -> %s ) ", - drbd_conn_str(os.conn), - drbd_conn_str(ns.conn)); - if (ns.disk != os.disk) - pbp += sprintf(pbp, "disk( %s -> %s ) ", - drbd_disk_str(os.disk), - drbd_disk_str(ns.disk)); - if (ns.pdsk != os.pdsk) - pbp += sprintf(pbp, "pdsk( %s -> %s ) ", - drbd_disk_str(os.pdsk), - drbd_disk_str(ns.pdsk)); - if (is_susp(ns) != is_susp(os)) - pbp += sprintf(pbp, "susp( %d -> %d ) ", - is_susp(os), - is_susp(ns)); - if (ns.aftr_isp != os.aftr_isp) - pbp += sprintf(pbp, "aftr_isp( %d -> %d ) ", - os.aftr_isp, - ns.aftr_isp); - if (ns.peer_isp != os.peer_isp) - pbp += sprintf(pbp, "peer_isp( %d -> %d ) ", - os.peer_isp, - ns.peer_isp); - if (ns.user_isp != os.user_isp) - pbp += sprintf(pbp, "user_isp( %d -> %d ) ", - os.user_isp, - ns.user_isp); - dev_info(DEV, "%s\n", pb); + char *pbp, pb[300]; + pbp = pb; + *pbp = 0; + PSC(role); + PSC(peer); + PSC(conn); + PSC(disk); + PSC(pdsk); + if (is_susp(ns) != is_susp(os)) + pbp += sprintf(pbp, "susp( %s -> %s ) ", + drbd_susp_str(is_susp(os)), + drbd_susp_str(is_susp(ns))); + PSC(aftr_isp); + PSC(peer_isp); + PSC(user_isp); + dev_info(DEV, "%s\n", pb); } /* solve the race between becoming unconfigured, @@ -1142,10 +1074,6 @@ __drbd_set_state(struct drbd_conf *mdev, union drbd_state ns, atomic_inc(&mdev->local_cnt); mdev->state = ns; - - if (os.disk == D_ATTACHING && ns.disk >= D_NEGOTIATING) - drbd_print_uuids(mdev, "attached to UUIDs"); - wake_up(&mdev->misc_wait); wake_up(&mdev->state_wait); @@ -1153,7 +1081,7 @@ __drbd_set_state(struct drbd_conf *mdev, union drbd_state ns, if ((os.conn == C_VERIFY_S || os.conn == C_VERIFY_T) && ns.conn < C_CONNECTED) { mdev->ov_start_sector = - BM_BIT_TO_SECT(drbd_bm_bits(mdev) - mdev->ov_left); + BM_BIT_TO_SECT(mdev->rs_total - mdev->ov_left); dev_info(DEV, "Online Verify reached sector %llu\n", (unsigned long long)mdev->ov_start_sector); } @@ -1178,7 +1106,14 @@ __drbd_set_state(struct drbd_conf *mdev, union drbd_state ns, unsigned long now = jiffies; int i; - set_ov_position(mdev, ns.conn); + mdev->ov_position = 0; + mdev->rs_total = drbd_bm_bits(mdev); + if (mdev->agreed_pro_version >= 90) + set_ov_position(mdev, ns.conn); + else + mdev->ov_start_sector = 0; + mdev->ov_left = mdev->rs_total + - BM_SECT_TO_BIT(mdev->ov_position); mdev->rs_start = now; mdev->rs_last_events = 0; mdev->rs_last_sect_ev = 0; @@ -1186,12 +1121,10 @@ __drbd_set_state(struct drbd_conf *mdev, union drbd_state ns, mdev->ov_last_oos_start = 0; for (i = 0; i < DRBD_SYNC_MARKS; i++) { - mdev->rs_mark_left[i] = mdev->ov_left; + mdev->rs_mark_left[i] = mdev->rs_total; mdev->rs_mark_time[i] = now; } - drbd_rs_controller_reset(mdev); - if (ns.conn == C_VERIFY_S) { dev_info(DEV, "Starting Online Verify from sector %llu\n", (unsigned long long)mdev->ov_position); @@ -1295,26 +1228,6 @@ static void abw_start_sync(struct drbd_conf *mdev, int rv) } } -int drbd_bitmap_io_from_worker(struct drbd_conf *mdev, - int (*io_fn)(struct drbd_conf *), - char *why, enum bm_flag flags) -{ - int rv; - - D_ASSERT(current == mdev->worker.task); - - /* open coded non-blocking drbd_suspend_io(mdev); */ - set_bit(SUSPEND_IO, &mdev->flags); - - drbd_bm_lock(mdev, why, flags); - rv = io_fn(mdev); - drbd_bm_unlock(mdev); - - drbd_resume_io(mdev); - - return rv; -} - /** * after_state_ch() - Perform after state change actions that may sleep * @mdev: DRBD device. @@ -1353,14 +1266,16 @@ static void after_state_ch(struct drbd_conf *mdev, union drbd_state os, nsm.i = -1; if (ns.susp_nod) { - if (os.conn < C_CONNECTED && ns.conn >= C_CONNECTED) - what = resend; + if (os.conn < C_CONNECTED && ns.conn >= C_CONNECTED) { + if (ns.conn == C_CONNECTED) + what = resend, nsm.susp_nod = 0; + else /* ns.conn > C_CONNECTED */ + dev_err(DEV, "Unexpected Resynd going on!\n"); + } if (os.disk == D_ATTACHING && ns.disk > D_ATTACHING) - what = restart_frozen_disk_io; + what = restart_frozen_disk_io, nsm.susp_nod = 0; - if (what != nothing) - nsm.susp_nod = 0; } if (ns.susp_fen) { @@ -1391,30 +1306,13 @@ static void after_state_ch(struct drbd_conf *mdev, union drbd_state os, spin_unlock_irq(&mdev->req_lock); } - /* Became sync source. With protocol >= 96, we still need to send out - * the sync uuid now. Need to do that before any drbd_send_state, or - * the other side may go "paused sync" before receiving the sync uuids, - * which is unexpected. */ - if ((os.conn != C_SYNC_SOURCE && os.conn != C_PAUSED_SYNC_S) && - (ns.conn == C_SYNC_SOURCE || ns.conn == C_PAUSED_SYNC_S) && - mdev->agreed_pro_version >= 96 && get_ldev(mdev)) { - drbd_gen_and_send_sync_uuid(mdev); - put_ldev(mdev); - } - /* Do not change the order of the if above and the two below... */ if (os.pdsk == D_DISKLESS && ns.pdsk > D_DISKLESS) { /* attach on the peer */ drbd_send_uuids(mdev); drbd_send_state(mdev); } - /* No point in queuing send_bitmap if we don't have a connection - * anymore, so check also the _current_ state, not only the new state - * at the time this work was queued. */ - if (os.conn != C_WF_BITMAP_S && ns.conn == C_WF_BITMAP_S && - mdev->state.conn == C_WF_BITMAP_S) - drbd_queue_bitmap_io(mdev, &drbd_send_bitmap, NULL, - "send_bitmap (WFBitMapS)", - BM_LOCKED_TEST_ALLOWED); + if (os.conn != C_WF_BITMAP_S && ns.conn == C_WF_BITMAP_S) + drbd_queue_bitmap_io(mdev, &drbd_send_bitmap, NULL, "send_bitmap (WFBitMapS)"); /* Lost contact to peer's copy of the data */ if ((os.pdsk >= D_INCONSISTENT && @@ -1445,23 +1343,7 @@ static void after_state_ch(struct drbd_conf *mdev, union drbd_state os, /* D_DISKLESS Peer becomes secondary */ if (os.peer == R_PRIMARY && ns.peer == R_SECONDARY) - /* We may still be Primary ourselves. - * No harm done if the bitmap still changes, - * redirtied pages will follow later. */ - drbd_bitmap_io_from_worker(mdev, &drbd_bm_write, - "demote diskless peer", BM_LOCKED_SET_ALLOWED); - put_ldev(mdev); - } - - /* Write out all changed bits on demote. - * Though, no need to da that just yet - * if there is a resync going on still */ - if (os.role == R_PRIMARY && ns.role == R_SECONDARY && - mdev->state.conn <= C_CONNECTED && get_ldev(mdev)) { - /* No changes to the bitmap expected this time, so assert that, - * even though no harm was done if it did change. */ - drbd_bitmap_io_from_worker(mdev, &drbd_bm_write, - "demote", BM_LOCKED_TEST_ALLOWED); + drbd_al_to_on_disk_bm(mdev); put_ldev(mdev); } @@ -1489,23 +1371,15 @@ static void after_state_ch(struct drbd_conf *mdev, union drbd_state os, if (os.conn == C_WF_REPORT_PARAMS && ns.conn >= C_CONNECTED) drbd_send_state(mdev); - if (os.conn != C_AHEAD && ns.conn == C_AHEAD) - drbd_send_state(mdev); - /* We are in the progress to start a full sync... */ if ((os.conn != C_STARTING_SYNC_T && ns.conn == C_STARTING_SYNC_T) || (os.conn != C_STARTING_SYNC_S && ns.conn == C_STARTING_SYNC_S)) - /* no other bitmap changes expected during this phase */ - drbd_queue_bitmap_io(mdev, - &drbd_bmio_set_n_write, &abw_start_sync, - "set_n_write from StartingSync", BM_LOCKED_TEST_ALLOWED); + drbd_queue_bitmap_io(mdev, &drbd_bmio_set_n_write, &abw_start_sync, "set_n_write from StartingSync"); /* We are invalidating our self... */ if (os.conn < C_CONNECTED && ns.conn < C_CONNECTED && os.disk > D_INCONSISTENT && ns.disk == D_INCONSISTENT) - /* other bitmap operation expected during this phase */ - drbd_queue_bitmap_io(mdev, &drbd_bmio_set_n_write, NULL, - "set_n_write from invalidate", BM_LOCKED_MASK); + drbd_queue_bitmap_io(mdev, &drbd_bmio_set_n_write, NULL, "set_n_write from invalidate"); /* first half of local IO error, failure to attach, * or administrative detach */ @@ -1560,6 +1434,8 @@ static void after_state_ch(struct drbd_conf *mdev, union drbd_state os, if (drbd_send_state(mdev)) dev_warn(DEV, "Notified peer that I'm now diskless.\n"); + else + dev_err(DEV, "Sending state for being diskless failed\n"); /* corresponding get_ldev in __drbd_set_state * this may finaly trigger drbd_ldev_destroy. */ put_ldev(mdev); @@ -1583,19 +1459,6 @@ static void after_state_ch(struct drbd_conf *mdev, union drbd_state os, if (os.disk < D_UP_TO_DATE && os.conn >= C_SYNC_SOURCE && ns.conn == C_CONNECTED) drbd_send_state(mdev); - /* This triggers bitmap writeout of potentially still unwritten pages - * if the resync finished cleanly, or aborted because of peer disk - * failure, or because of connection loss. - * For resync aborted because of local disk failure, we cannot do - * any bitmap writeout anymore. - * No harm done if some bits change during this phase. - */ - if (os.conn > C_CONNECTED && ns.conn <= C_CONNECTED && get_ldev(mdev)) { - drbd_queue_bitmap_io(mdev, &drbd_bm_write, NULL, - "write from resync_finished", BM_LOCKED_SET_ALLOWED); - put_ldev(mdev); - } - /* free tl_hash if we Got thawed and are C_STANDALONE */ if (ns.conn == C_STANDALONE && !is_susp(ns) && mdev->tl_hash) drbd_free_tl_hash(mdev); @@ -1696,7 +1559,7 @@ int drbd_thread_start(struct drbd_thread *thi) if (!try_module_get(THIS_MODULE)) { dev_err(DEV, "Failed to get module reference in drbd_thread_start\n"); spin_unlock_irqrestore(&thi->t_lock, flags); - return false; + return FALSE; } init_completion(&thi->stop); @@ -1713,7 +1576,7 @@ int drbd_thread_start(struct drbd_thread *thi) dev_err(DEV, "Couldn't start thread\n"); module_put(THIS_MODULE); - return false; + return FALSE; } spin_lock_irqsave(&thi->t_lock, flags); thi->task = nt; @@ -1733,7 +1596,7 @@ int drbd_thread_start(struct drbd_thread *thi) break; } - return true; + return TRUE; } @@ -1831,8 +1694,8 @@ int _drbd_send_cmd(struct drbd_conf *mdev, struct socket *sock, { int sent, ok; - ERR_IF(!h) return false; - ERR_IF(!size) return false; + ERR_IF(!h) return FALSE; + ERR_IF(!size) return FALSE; h->magic = BE_DRBD_MAGIC; h->command = cpu_to_be16(cmd); @@ -1841,8 +1704,8 @@ int _drbd_send_cmd(struct drbd_conf *mdev, struct socket *sock, sent = drbd_send(mdev, sock, h, size, msg_flags); ok = (sent == size); - if (!ok && !signal_pending(current)) - dev_warn(DEV, "short sent %s size=%d sent=%d\n", + if (!ok) + dev_err(DEV, "short sent %s size=%d sent=%d\n", cmdname(cmd), (int)size, sent); return ok; } @@ -1977,7 +1840,7 @@ int drbd_send_protocol(struct drbd_conf *mdev) else { dev_err(DEV, "--dry-run is not supported by peer"); kfree(p); - return -1; + return 0; } } p->conn_flags = cpu_to_be32(cf); @@ -2025,36 +1888,12 @@ int drbd_send_uuids_skip_initial_sync(struct drbd_conf *mdev) return _drbd_send_uuids(mdev, 8); } -void drbd_print_uuids(struct drbd_conf *mdev, const char *text) -{ - if (get_ldev_if_state(mdev, D_NEGOTIATING)) { - u64 *uuid = mdev->ldev->md.uuid; - dev_info(DEV, "%s %016llX:%016llX:%016llX:%016llX\n", - text, - (unsigned long long)uuid[UI_CURRENT], - (unsigned long long)uuid[UI_BITMAP], - (unsigned long long)uuid[UI_HISTORY_START], - (unsigned long long)uuid[UI_HISTORY_END]); - put_ldev(mdev); - } else { - dev_info(DEV, "%s effective data uuid: %016llX\n", - text, - (unsigned long long)mdev->ed_uuid); - } -} -int drbd_gen_and_send_sync_uuid(struct drbd_conf *mdev) +int drbd_send_sync_uuid(struct drbd_conf *mdev, u64 val) { struct p_rs_uuid p; - u64 uuid; - D_ASSERT(mdev->state.disk == D_UP_TO_DATE); - - uuid = mdev->ldev->md.uuid[UI_BITMAP] + UUID_NEW_BM_OFFSET; - drbd_uuid_set(mdev, UI_BITMAP, uuid); - drbd_print_uuids(mdev, "updated sync UUID"); - drbd_md_sync(mdev); - p.uuid = cpu_to_be64(uuid); + p.uuid = cpu_to_be64(val); return drbd_send_cmd(mdev, USE_DATA_SOCKET, P_SYNC_UUID, (struct p_header80 *)&p, sizeof(p)); @@ -2082,7 +1921,7 @@ int drbd_send_sizes(struct drbd_conf *mdev, int trigger_reply, enum dds_flags fl p.d_size = cpu_to_be64(d_size); p.u_size = cpu_to_be64(u_size); p.c_size = cpu_to_be64(trigger_reply ? 0 : drbd_get_capacity(mdev->this_bdev)); - p.max_bio_size = cpu_to_be32(queue_max_hw_sectors(mdev->rq_queue) << 9); + p.max_segment_size = cpu_to_be32(queue_max_segment_size(mdev->rq_queue)); p.queue_order_type = cpu_to_be16(q_order_type); p.dds_flags = cpu_to_be16(flags); @@ -2133,7 +1972,7 @@ int drbd_send_state_req(struct drbd_conf *mdev, (struct p_header80 *)&p, sizeof(p)); } -int drbd_send_sr_reply(struct drbd_conf *mdev, enum drbd_state_rv retcode) +int drbd_send_sr_reply(struct drbd_conf *mdev, int retcode) { struct p_req_state_reply p; @@ -2237,15 +2076,9 @@ int fill_bitmap_rle_bits(struct drbd_conf *mdev, return len; } -/** - * send_bitmap_rle_or_plain - * - * Return 0 when done, 1 when another iteration is needed, and a negative error - * code upon failure. - */ -static int +enum { OK, FAILED, DONE } send_bitmap_rle_or_plain(struct drbd_conf *mdev, - struct p_header80 *h, struct bm_xfer_ctx *c) + struct p_header80 *h, struct bm_xfer_ctx *c) { struct p_compressed_bm *p = (void*)h; unsigned long num_words; @@ -2255,7 +2088,7 @@ send_bitmap_rle_or_plain(struct drbd_conf *mdev, len = fill_bitmap_rle_bits(mdev, p, c); if (len < 0) - return -EIO; + return FAILED; if (len) { DCBP_set_code(p, RLE_VLI_Bits); @@ -2285,14 +2118,11 @@ send_bitmap_rle_or_plain(struct drbd_conf *mdev, if (c->bit_offset > c->bm_bits) c->bit_offset = c->bm_bits; } - if (ok) { - if (len == 0) { - INFO_bm_xfer_stats(mdev, "send", c); - return 0; - } else - return 1; - } - return -EIO; + ok = ok ? ((len == 0) ? DONE : OK) : FAILED; + + if (ok == DONE) + INFO_bm_xfer_stats(mdev, "send", c); + return ok; } /* See the comment at receive_bitmap() */ @@ -2300,16 +2130,16 @@ int _drbd_send_bitmap(struct drbd_conf *mdev) { struct bm_xfer_ctx c; struct p_header80 *p; - int err; + int ret; - ERR_IF(!mdev->bitmap) return false; + ERR_IF(!mdev->bitmap) return FALSE; /* maybe we should use some per thread scratch page, * and allocate that during initial device creation? */ p = (struct p_header80 *) __get_free_page(GFP_NOIO); if (!p) { dev_err(DEV, "failed to allocate one page buffer in %s\n", __func__); - return false; + return FALSE; } if (get_ldev(mdev)) { @@ -2335,11 +2165,11 @@ int _drbd_send_bitmap(struct drbd_conf *mdev) }; do { - err = send_bitmap_rle_or_plain(mdev, p, &c); - } while (err > 0); + ret = send_bitmap_rle_or_plain(mdev, p, &c); + } while (ret == OK); free_page((unsigned long) p); - return err == 0; + return (ret == DONE); } int drbd_send_bitmap(struct drbd_conf *mdev) @@ -2362,7 +2192,7 @@ int drbd_send_b_ack(struct drbd_conf *mdev, u32 barrier_nr, u32 set_size) p.set_size = cpu_to_be32(set_size); if (mdev->state.conn < C_CONNECTED) - return false; + return FALSE; ok = drbd_send_cmd(mdev, USE_META_SOCKET, P_BARRIER_ACK, (struct p_header80 *)&p, sizeof(p)); return ok; @@ -2390,7 +2220,7 @@ static int _drbd_send_ack(struct drbd_conf *mdev, enum drbd_packets cmd, p.seq_num = cpu_to_be32(atomic_add_return(1, &mdev->packet_seq)); if (!mdev->meta.socket || mdev->state.conn < C_CONNECTED) - return false; + return FALSE; ok = drbd_send_cmd(mdev, USE_META_SOCKET, cmd, (struct p_header80 *)&p, sizeof(p)); return ok; @@ -2496,8 +2326,8 @@ int drbd_send_ov_request(struct drbd_conf *mdev, sector_t sector, int size) } /* called on sndtimeo - * returns false if we should retry, - * true if we think connection is dead + * returns FALSE if we should retry, + * TRUE if we think connection is dead */ static int we_should_drop_the_connection(struct drbd_conf *mdev, struct socket *sock) { @@ -2510,7 +2340,7 @@ static int we_should_drop_the_connection(struct drbd_conf *mdev, struct socket * || mdev->state.conn < C_CONNECTED; if (drop_it) - return true; + return TRUE; drop_it = !--mdev->ko_count; if (!drop_it) { @@ -2701,39 +2531,13 @@ int drbd_send_dblock(struct drbd_conf *mdev, struct drbd_request *req) if (ok && dgs) { dgb = mdev->int_dig_out; drbd_csum_bio(mdev, mdev->integrity_w_tfm, req->master_bio, dgb); - ok = dgs == drbd_send(mdev, mdev->data.socket, dgb, dgs, 0); + ok = drbd_send(mdev, mdev->data.socket, dgb, dgs, 0); } if (ok) { - /* For protocol A, we have to memcpy the payload into - * socket buffers, as we may complete right away - * as soon as we handed it over to tcp, at which point the data - * pages may become invalid. - * - * For data-integrity enabled, we copy it as well, so we can be - * sure that even if the bio pages may still be modified, it - * won't change the data on the wire, thus if the digest checks - * out ok after sending on this side, but does not fit on the - * receiving side, we sure have detected corruption elsewhere. - */ - if (mdev->net_conf->wire_protocol == DRBD_PROT_A || dgs) + if (mdev->net_conf->wire_protocol == DRBD_PROT_A) ok = _drbd_send_bio(mdev, req->master_bio); else ok = _drbd_send_zc_bio(mdev, req->master_bio); - - /* double check digest, sometimes buffers have been modified in flight. */ - if (dgs > 0 && dgs <= 64) { - /* 64 byte, 512 bit, is the larges digest size - * currently supported in kernel crypto. */ - unsigned char digest[64]; - drbd_csum_bio(mdev, mdev->integrity_w_tfm, req->master_bio, digest); - if (memcmp(mdev->int_dig_out, digest, dgs)) { - dev_warn(DEV, - "Digest mismatch, buffer modified by upper layers during write: %llus +%u\n", - (unsigned long long)req->sector, req->size); - } - } /* else if (dgs > 64) { - ... Be noisy about digest too large ... - } */ } drbd_put_data_sock(mdev); @@ -2783,7 +2587,7 @@ int drbd_send_block(struct drbd_conf *mdev, enum drbd_packets cmd, if (ok && dgs) { dgb = mdev->int_dig_out; drbd_csum_ee(mdev, mdev->integrity_w_tfm, e, dgb); - ok = dgs == drbd_send(mdev, mdev->data.socket, dgb, dgs, 0); + ok = drbd_send(mdev, mdev->data.socket, dgb, dgs, 0); } if (ok) ok = _drbd_send_zc_ee(mdev, e); @@ -2793,16 +2597,6 @@ int drbd_send_block(struct drbd_conf *mdev, enum drbd_packets cmd, return ok; } -int drbd_send_oos(struct drbd_conf *mdev, struct drbd_request *req) -{ - struct p_block_desc p; - - p.sector = cpu_to_be64(req->sector); - p.blksize = cpu_to_be32(req->size); - - return drbd_send_cmd(mdev, USE_DATA_SOCKET, P_OUT_OF_SYNC, &p.head, sizeof(p)); -} - /* drbd_send distinguishes two cases: @@ -2976,7 +2770,6 @@ void drbd_init_set_defaults(struct drbd_conf *mdev) atomic_set(&mdev->pp_in_use_by_net, 0); atomic_set(&mdev->rs_sect_in, 0); atomic_set(&mdev->rs_sect_ev, 0); - atomic_set(&mdev->ap_in_flight, 0); mutex_init(&mdev->md_io_mutex); mutex_init(&mdev->data.mutex); @@ -3005,27 +2798,19 @@ void drbd_init_set_defaults(struct drbd_conf *mdev) INIT_LIST_HEAD(&mdev->unplug_work.list); INIT_LIST_HEAD(&mdev->go_diskless.list); INIT_LIST_HEAD(&mdev->md_sync_work.list); - INIT_LIST_HEAD(&mdev->start_resync_work.list); INIT_LIST_HEAD(&mdev->bm_io_work.w.list); - mdev->resync_work.cb = w_resync_timer; + mdev->resync_work.cb = w_resync_inactive; mdev->unplug_work.cb = w_send_write_hint; mdev->go_diskless.cb = w_go_diskless; mdev->md_sync_work.cb = w_md_sync; mdev->bm_io_work.w.cb = w_bitmap_io; - mdev->start_resync_work.cb = w_start_resync; init_timer(&mdev->resync_timer); init_timer(&mdev->md_sync_timer); - init_timer(&mdev->start_resync_timer); - init_timer(&mdev->request_timer); mdev->resync_timer.function = resync_timer_fn; mdev->resync_timer.data = (unsigned long) mdev; mdev->md_sync_timer.function = md_sync_timer_fn; mdev->md_sync_timer.data = (unsigned long) mdev; - mdev->start_resync_timer.function = start_resync_timer_fn; - mdev->start_resync_timer.data = (unsigned long) mdev; - mdev->request_timer.function = request_timer_fn; - mdev->request_timer.data = (unsigned long) mdev; init_waitqueue_head(&mdev->misc_wait); init_waitqueue_head(&mdev->state_wait); @@ -3096,8 +2881,6 @@ void drbd_mdev_cleanup(struct drbd_conf *mdev) D_ASSERT(list_empty(&mdev->resync_work.list)); D_ASSERT(list_empty(&mdev->unplug_work.list)); D_ASSERT(list_empty(&mdev->go_diskless.list)); - - drbd_set_defaults(mdev); } @@ -3140,7 +2923,7 @@ static void drbd_destroy_mempools(void) static int drbd_create_mempools(void) { struct page *page; - const int number = (DRBD_MAX_BIO_SIZE/PAGE_SIZE) * minor_count; + const int number = (DRBD_MAX_SEGMENT_SIZE/PAGE_SIZE) * minor_count; int i; /* prepare our caches and mempools */ @@ -3304,20 +3087,11 @@ static void drbd_cleanup(void) unregister_reboot_notifier(&drbd_notifier); - /* first remove proc, - * drbdsetup uses it's presence to detect - * whether DRBD is loaded. - * If we would get stuck in proc removal, - * but have netlink already deregistered, - * some drbdsetup commands may wait forever - * for an answer. - */ - if (drbd_proc) - remove_proc_entry("drbd", NULL); - drbd_nl_cleanup(); if (minor_table) { + if (drbd_proc) + remove_proc_entry("drbd", NULL); i = minor_count; while (i--) drbd_delete_device(i); @@ -3345,7 +3119,7 @@ static int drbd_congested(void *congested_data, int bdi_bits) char reason = '-'; int r = 0; - if (!may_inc_ap_bio(mdev)) { + if (!__inc_ap_bio_cond(mdev)) { /* DRBD has frozen IO */ r = bdi_bits; reason = 'd'; @@ -3398,7 +3172,7 @@ struct drbd_conf *drbd_new_device(unsigned int minor) goto out_no_disk; mdev->vdisk = disk; - set_disk_ro(disk, true); + set_disk_ro(disk, TRUE); disk->queue = q; disk->major = DRBD_MAJOR; @@ -3414,8 +3188,8 @@ struct drbd_conf *drbd_new_device(unsigned int minor) q->backing_dev_info.congested_fn = drbd_congested; q->backing_dev_info.congested_data = mdev; - blk_queue_make_request(q, drbd_make_request); - blk_queue_max_hw_sectors(q, DRBD_MAX_BIO_SIZE >> 9); + blk_queue_make_request(q, drbd_make_request_26); + blk_queue_max_segment_size(q, DRBD_MAX_SEGMENT_SIZE); blk_queue_bounce_limit(q, BLK_BOUNCE_ANY); blk_queue_merge_bvec(q, drbd_merge_bvec); q->queue_lock = &mdev->req_lock; @@ -3477,7 +3251,6 @@ void drbd_free_mdev(struct drbd_conf *mdev) put_disk(mdev->vdisk); blk_cleanup_queue(mdev->rq_queue); free_cpumask_var(mdev->cpu_mask); - drbd_free_tl_hash(mdev); kfree(mdev); } @@ -3493,7 +3266,7 @@ int __init drbd_init(void) return -EINVAL; } - if (minor_count < DRBD_MINOR_COUNT_MIN || minor_count > DRBD_MINOR_COUNT_MAX) { + if (1 > minor_count || minor_count > 255) { printk(KERN_ERR "drbd: invalid minor_count (%d)\n", minor_count); #ifdef MODULE @@ -3675,7 +3448,7 @@ void drbd_md_sync(struct drbd_conf *mdev) if (!drbd_md_sync_page_io(mdev, mdev->ldev, sector, WRITE)) { /* this was a try anyways ... */ dev_err(DEV, "meta data update failed!\n"); - drbd_chk_io_error(mdev, 1, true); + drbd_chk_io_error(mdev, 1, TRUE); } /* Update mdev->ldev->md.la_size_sect, @@ -3691,7 +3464,7 @@ void drbd_md_sync(struct drbd_conf *mdev) * @mdev: DRBD device. * @bdev: Device from which the meta data should be read in. * - * Return 0 (NO_ERROR) on success, and an enum drbd_ret_code in case + * Return 0 (NO_ERROR) on success, and an enum drbd_ret_codes in case * something goes wrong. Currently only: ERR_IO_MD_DISK, ERR_MD_INVALID. */ int drbd_md_read(struct drbd_conf *mdev, struct drbd_backing_dev *bdev) @@ -3761,6 +3534,28 @@ int drbd_md_read(struct drbd_conf *mdev, struct drbd_backing_dev *bdev) return rv; } +static void debug_drbd_uuid(struct drbd_conf *mdev, enum drbd_uuid_index index) +{ + static char *uuid_str[UI_EXTENDED_SIZE] = { + [UI_CURRENT] = "CURRENT", + [UI_BITMAP] = "BITMAP", + [UI_HISTORY_START] = "HISTORY_START", + [UI_HISTORY_END] = "HISTORY_END", + [UI_SIZE] = "SIZE", + [UI_FLAGS] = "FLAGS", + }; + + if (index >= UI_EXTENDED_SIZE) { + dev_warn(DEV, " uuid_index >= EXTENDED_SIZE\n"); + return; + } + + dynamic_dev_dbg(DEV, " uuid[%s] now %016llX\n", + uuid_str[index], + (unsigned long long)mdev->ldev->md.uuid[index]); +} + + /** * drbd_md_mark_dirty() - Mark meta data super block as dirty * @mdev: DRBD device. @@ -3790,8 +3585,10 @@ static void drbd_uuid_move_history(struct drbd_conf *mdev) __must_hold(local) { int i; - for (i = UI_HISTORY_START; i < UI_HISTORY_END; i++) + for (i = UI_HISTORY_START; i < UI_HISTORY_END; i++) { mdev->ldev->md.uuid[i+1] = mdev->ldev->md.uuid[i]; + debug_drbd_uuid(mdev, i+1); + } } void _drbd_uuid_set(struct drbd_conf *mdev, int idx, u64 val) __must_hold(local) @@ -3806,6 +3603,7 @@ void _drbd_uuid_set(struct drbd_conf *mdev, int idx, u64 val) __must_hold(local) } mdev->ldev->md.uuid[idx] = val; + debug_drbd_uuid(mdev, idx); drbd_md_mark_dirty(mdev); } @@ -3815,6 +3613,7 @@ void drbd_uuid_set(struct drbd_conf *mdev, int idx, u64 val) __must_hold(local) if (mdev->ldev->md.uuid[idx]) { drbd_uuid_move_history(mdev); mdev->ldev->md.uuid[UI_HISTORY_START] = mdev->ldev->md.uuid[idx]; + debug_drbd_uuid(mdev, UI_HISTORY_START); } _drbd_uuid_set(mdev, idx, val); } @@ -3829,16 +3628,14 @@ void drbd_uuid_set(struct drbd_conf *mdev, int idx, u64 val) __must_hold(local) void drbd_uuid_new_current(struct drbd_conf *mdev) __must_hold(local) { u64 val; - unsigned long long bm_uuid = mdev->ldev->md.uuid[UI_BITMAP]; - - if (bm_uuid) - dev_warn(DEV, "bm UUID was already set: %llX\n", bm_uuid); + dev_info(DEV, "Creating new current UUID\n"); + D_ASSERT(mdev->ldev->md.uuid[UI_BITMAP] == 0); mdev->ldev->md.uuid[UI_BITMAP] = mdev->ldev->md.uuid[UI_CURRENT]; + debug_drbd_uuid(mdev, UI_BITMAP); get_random_bytes(&val, sizeof(u64)); _drbd_uuid_set(mdev, UI_CURRENT, val); - drbd_print_uuids(mdev, "new current UUID"); /* get it to stable storage _now_ */ drbd_md_sync(mdev); } @@ -3852,12 +3649,16 @@ void drbd_uuid_set_bm(struct drbd_conf *mdev, u64 val) __must_hold(local) drbd_uuid_move_history(mdev); mdev->ldev->md.uuid[UI_HISTORY_START] = mdev->ldev->md.uuid[UI_BITMAP]; mdev->ldev->md.uuid[UI_BITMAP] = 0; + debug_drbd_uuid(mdev, UI_HISTORY_START); + debug_drbd_uuid(mdev, UI_BITMAP); } else { - unsigned long long bm_uuid = mdev->ldev->md.uuid[UI_BITMAP]; - if (bm_uuid) - dev_warn(DEV, "bm UUID was already set: %llX\n", bm_uuid); + if (mdev->ldev->md.uuid[UI_BITMAP]) + dev_warn(DEV, "bm UUID already set"); + + mdev->ldev->md.uuid[UI_BITMAP] = val; + mdev->ldev->md.uuid[UI_BITMAP] &= ~((u64)1); - mdev->ldev->md.uuid[UI_BITMAP] = val & ~((u64)1); + debug_drbd_uuid(mdev, UI_BITMAP); } drbd_md_mark_dirty(mdev); } @@ -3913,19 +3714,15 @@ int drbd_bmio_clear_n_write(struct drbd_conf *mdev) static int w_bitmap_io(struct drbd_conf *mdev, struct drbd_work *w, int unused) { struct bm_io_work *work = container_of(w, struct bm_io_work, w); - int rv = -EIO; + int rv; D_ASSERT(atomic_read(&mdev->ap_bio_cnt) == 0); - if (get_ldev(mdev)) { - drbd_bm_lock(mdev, work->why, work->flags); - rv = work->io_fn(mdev); - drbd_bm_unlock(mdev); - put_ldev(mdev); - } + drbd_bm_lock(mdev, work->why); + rv = work->io_fn(mdev); + drbd_bm_unlock(mdev); clear_bit(BITMAP_IO, &mdev->flags); - smp_mb__after_clear_bit(); wake_up(&mdev->misc_wait); if (work->done) @@ -3933,7 +3730,6 @@ static int w_bitmap_io(struct drbd_conf *mdev, struct drbd_work *w, int unused) clear_bit(BITMAP_IO_QUEUED, &mdev->flags); work->why = NULL; - work->flags = 0; return 1; } @@ -3988,7 +3784,7 @@ void drbd_go_diskless(struct drbd_conf *mdev) void drbd_queue_bitmap_io(struct drbd_conf *mdev, int (*io_fn)(struct drbd_conf *), void (*done)(struct drbd_conf *, int), - char *why, enum bm_flag flags) + char *why) { D_ASSERT(current == mdev->worker.task); @@ -4002,15 +3798,15 @@ void drbd_queue_bitmap_io(struct drbd_conf *mdev, mdev->bm_io_work.io_fn = io_fn; mdev->bm_io_work.done = done; mdev->bm_io_work.why = why; - mdev->bm_io_work.flags = flags; - spin_lock_irq(&mdev->req_lock); set_bit(BITMAP_IO, &mdev->flags); if (atomic_read(&mdev->ap_bio_cnt) == 0) { - if (!test_and_set_bit(BITMAP_IO_QUEUED, &mdev->flags)) + if (list_empty(&mdev->bm_io_work.w.list)) { + set_bit(BITMAP_IO_QUEUED, &mdev->flags); drbd_queue_work(&mdev->data.work, &mdev->bm_io_work.w); + } else + dev_err(DEV, "FIXME avoided double queuing bm_io_work\n"); } - spin_unlock_irq(&mdev->req_lock); } /** @@ -4022,22 +3818,19 @@ void drbd_queue_bitmap_io(struct drbd_conf *mdev, * freezes application IO while that the actual IO operations runs. This * functions MAY NOT be called from worker context. */ -int drbd_bitmap_io(struct drbd_conf *mdev, int (*io_fn)(struct drbd_conf *), - char *why, enum bm_flag flags) +int drbd_bitmap_io(struct drbd_conf *mdev, int (*io_fn)(struct drbd_conf *), char *why) { int rv; D_ASSERT(current != mdev->worker.task); - if ((flags & BM_LOCKED_SET_ALLOWED) == 0) - drbd_suspend_io(mdev); + drbd_suspend_io(mdev); - drbd_bm_lock(mdev, why, flags); + drbd_bm_lock(mdev, why); rv = io_fn(mdev); drbd_bm_unlock(mdev); - if ((flags & BM_LOCKED_SET_ALLOWED) == 0) - drbd_resume_io(mdev); + drbd_resume_io(mdev); return rv; } diff --git a/trunk/drivers/block/drbd/drbd_nl.c b/trunk/drivers/block/drbd/drbd_nl.c index 03b29f78a37d..fe81c851ca88 100644 --- a/trunk/drivers/block/drbd/drbd_nl.c +++ b/trunk/drivers/block/drbd/drbd_nl.c @@ -288,11 +288,10 @@ void drbd_try_outdate_peer_async(struct drbd_conf *mdev) dev_err(DEV, "out of mem, failed to invoke fence-peer helper\n"); } -enum drbd_state_rv -drbd_set_role(struct drbd_conf *mdev, enum drbd_role new_role, int force) +int drbd_set_role(struct drbd_conf *mdev, enum drbd_role new_role, int force) { const int max_tries = 4; - enum drbd_state_rv rv = SS_UNKNOWN_ERROR; + int r = 0; int try = 0; int forced = 0; union drbd_state mask, val; @@ -307,17 +306,17 @@ drbd_set_role(struct drbd_conf *mdev, enum drbd_role new_role, int force) val.i = 0; val.role = new_role; while (try++ < max_tries) { - rv = _drbd_request_state(mdev, mask, val, CS_WAIT_COMPLETE); + r = _drbd_request_state(mdev, mask, val, CS_WAIT_COMPLETE); /* in case we first succeeded to outdate, * but now suddenly could establish a connection */ - if (rv == SS_CW_FAILED_BY_PEER && mask.pdsk != 0) { + if (r == SS_CW_FAILED_BY_PEER && mask.pdsk != 0) { val.pdsk = 0; mask.pdsk = 0; continue; } - if (rv == SS_NO_UP_TO_DATE_DISK && force && + if (r == SS_NO_UP_TO_DATE_DISK && force && (mdev->state.disk < D_UP_TO_DATE && mdev->state.disk >= D_INCONSISTENT)) { mask.disk = D_MASK; @@ -326,7 +325,7 @@ drbd_set_role(struct drbd_conf *mdev, enum drbd_role new_role, int force) continue; } - if (rv == SS_NO_UP_TO_DATE_DISK && + if (r == SS_NO_UP_TO_DATE_DISK && mdev->state.disk == D_CONSISTENT && mask.pdsk == 0) { D_ASSERT(mdev->state.pdsk == D_UNKNOWN); nps = drbd_try_outdate_peer(mdev); @@ -342,9 +341,9 @@ drbd_set_role(struct drbd_conf *mdev, enum drbd_role new_role, int force) continue; } - if (rv == SS_NOTHING_TO_DO) + if (r == SS_NOTHING_TO_DO) goto fail; - if (rv == SS_PRIMARY_NOP && mask.pdsk == 0) { + if (r == SS_PRIMARY_NOP && mask.pdsk == 0) { nps = drbd_try_outdate_peer(mdev); if (force && nps > D_OUTDATED) { @@ -357,24 +356,25 @@ drbd_set_role(struct drbd_conf *mdev, enum drbd_role new_role, int force) continue; } - if (rv == SS_TWO_PRIMARIES) { + if (r == SS_TWO_PRIMARIES) { /* Maybe the peer is detected as dead very soon... retry at most once more in this case. */ - schedule_timeout_interruptible((mdev->net_conf->ping_timeo+1)*HZ/10); + __set_current_state(TASK_INTERRUPTIBLE); + schedule_timeout((mdev->net_conf->ping_timeo+1)*HZ/10); if (try < max_tries) try = max_tries - 1; continue; } - if (rv < SS_SUCCESS) { - rv = _drbd_request_state(mdev, mask, val, + if (r < SS_SUCCESS) { + r = _drbd_request_state(mdev, mask, val, CS_VERBOSE + CS_WAIT_COMPLETE); - if (rv < SS_SUCCESS) + if (r < SS_SUCCESS) goto fail; } break; } - if (rv < SS_SUCCESS) + if (r < SS_SUCCESS) goto fail; if (forced) @@ -384,7 +384,7 @@ drbd_set_role(struct drbd_conf *mdev, enum drbd_role new_role, int force) wait_event(mdev->misc_wait, atomic_read(&mdev->ap_pending_cnt) == 0); if (new_role == R_SECONDARY) { - set_disk_ro(mdev->vdisk, true); + set_disk_ro(mdev->vdisk, TRUE); if (get_ldev(mdev)) { mdev->ldev->md.uuid[UI_CURRENT] &= ~(u64)1; put_ldev(mdev); @@ -394,7 +394,7 @@ drbd_set_role(struct drbd_conf *mdev, enum drbd_role new_role, int force) mdev->net_conf->want_lose = 0; put_net_conf(mdev); } - set_disk_ro(mdev->vdisk, false); + set_disk_ro(mdev->vdisk, FALSE); if (get_ldev(mdev)) { if (((mdev->state.conn < C_CONNECTED || mdev->state.pdsk <= D_FAILED) @@ -406,8 +406,10 @@ drbd_set_role(struct drbd_conf *mdev, enum drbd_role new_role, int force) } } - /* writeout of activity log covered areas of the bitmap - * to stable storage done in after state change already */ + if ((new_role == R_SECONDARY) && get_ldev(mdev)) { + drbd_al_to_on_disk_bm(mdev); + put_ldev(mdev); + } if (mdev->state.conn >= C_WF_REPORT_PARAMS) { /* if this was forced, we should consider sync */ @@ -421,7 +423,7 @@ drbd_set_role(struct drbd_conf *mdev, enum drbd_role new_role, int force) kobject_uevent(&disk_to_dev(mdev->vdisk)->kobj, KOBJ_CHANGE); fail: mutex_unlock(&mdev->state_mutex); - return rv; + return r; } static struct drbd_conf *ensure_mdev(int minor, int create) @@ -526,19 +528,17 @@ static void drbd_md_set_sector_offsets(struct drbd_conf *mdev, } } -/* input size is expected to be in KB */ char *ppsize(char *buf, unsigned long long size) { - /* Needs 9 bytes at max including trailing NUL: - * -1ULL ==> "16384 EB" */ + /* Needs 9 bytes at max. */ static char units[] = { 'K', 'M', 'G', 'T', 'P', 'E' }; int base = 0; - while (size >= 10000 && base < sizeof(units)-1) { + while (size >= 10000) { /* shift + round */ size = (size >> 10) + !!(size & (1<<9)); base++; } - sprintf(buf, "%u %cB", (unsigned)size, units[base]); + sprintf(buf, "%lu %cB", (long)size, units[base]); return buf; } @@ -642,19 +642,11 @@ enum determine_dev_size drbd_determin_dev_size(struct drbd_conf *mdev, enum dds_ || prev_size != mdev->ldev->md.md_size_sect; if (la_size_changed || md_moved) { - int err; - drbd_al_shrink(mdev); /* All extents inactive. */ dev_info(DEV, "Writing the whole bitmap, %s\n", la_size_changed && md_moved ? "size changed and md moved" : la_size_changed ? "size changed" : "md moved"); - /* next line implicitly does drbd_suspend_io()+drbd_resume_io() */ - err = drbd_bitmap_io(mdev, &drbd_bm_write, - "size changed", BM_LOCKED_MASK); - if (err) { - rv = dev_size_error; - goto out; - } + rv = drbd_bitmap_io(mdev, &drbd_bm_write, "size changed"); /* does drbd_resume_io() ! */ drbd_md_mark_dirty(mdev); } @@ -773,21 +765,22 @@ static int drbd_check_al_size(struct drbd_conf *mdev) return 0; } -void drbd_setup_queue_param(struct drbd_conf *mdev, unsigned int max_bio_size) __must_hold(local) +void drbd_setup_queue_param(struct drbd_conf *mdev, unsigned int max_seg_s) __must_hold(local) { struct request_queue * const q = mdev->rq_queue; struct request_queue * const b = mdev->ldev->backing_bdev->bd_disk->queue; int max_segments = mdev->ldev->dc.max_bio_bvecs; - int max_hw_sectors = min(queue_max_hw_sectors(b), max_bio_size >> 9); - blk_queue_logical_block_size(q, 512); - blk_queue_max_hw_sectors(q, max_hw_sectors); - /* This is the workaround for "bio would need to, but cannot, be split" */ + max_seg_s = min(queue_max_sectors(b) * queue_logical_block_size(b), max_seg_s); + + blk_queue_max_hw_sectors(q, max_seg_s >> 9); blk_queue_max_segments(q, max_segments ? max_segments : BLK_MAX_SEGMENTS); - blk_queue_segment_boundary(q, PAGE_CACHE_SIZE-1); - blk_queue_stack_limits(q, b); + blk_queue_max_segment_size(q, max_seg_s); + blk_queue_logical_block_size(q, 512); + blk_queue_segment_boundary(q, PAGE_SIZE-1); + blk_stack_limits(&q->limits, &b->limits, 0); - dev_info(DEV, "max BIO size = %u\n", queue_max_hw_sectors(q) << 9); + dev_info(DEV, "max_segment_size ( = BIO size ) = %u\n", queue_max_segment_size(q)); if (q->backing_dev_info.ra_pages != b->backing_dev_info.ra_pages) { dev_info(DEV, "Adjusting my ra_pages to backing device's (%lu -> %lu)\n", @@ -857,7 +850,7 @@ static void drbd_suspend_al(struct drbd_conf *mdev) static int drbd_nl_disk_conf(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp, struct drbd_nl_cfg_reply *reply) { - enum drbd_ret_code retcode; + enum drbd_ret_codes retcode; enum determine_dev_size dd; sector_t max_possible_sectors; sector_t min_md_device_sectors; @@ -865,8 +858,8 @@ static int drbd_nl_disk_conf(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp struct block_device *bdev; struct lru_cache *resync_lru = NULL; union drbd_state ns, os; - unsigned int max_bio_size; - enum drbd_state_rv rv; + unsigned int max_seg_s; + int rv; int cp_discovered = 0; int logical_block_size; @@ -1012,10 +1005,9 @@ static int drbd_nl_disk_conf(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp /* and for any other previously queued work */ drbd_flush_workqueue(mdev); - rv = _drbd_request_state(mdev, NS(disk, D_ATTACHING), CS_VERBOSE); - retcode = rv; /* FIXME: Type mismatch. */ + retcode = _drbd_request_state(mdev, NS(disk, D_ATTACHING), CS_VERBOSE); drbd_resume_io(mdev); - if (rv < SS_SUCCESS) + if (retcode < SS_SUCCESS) goto fail; if (!get_ldev_if_state(mdev, D_ATTACHING)) @@ -1117,20 +1109,20 @@ static int drbd_nl_disk_conf(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp mdev->read_cnt = 0; mdev->writ_cnt = 0; - max_bio_size = DRBD_MAX_BIO_SIZE; + max_seg_s = DRBD_MAX_SEGMENT_SIZE; if (mdev->state.conn == C_CONNECTED) { /* We are Primary, Connected, and now attach a new local * backing store. We must not increase the user visible maximum * bio size on this device to something the peer may not be * able to handle. */ if (mdev->agreed_pro_version < 94) - max_bio_size = queue_max_hw_sectors(mdev->rq_queue) << 9; + max_seg_s = queue_max_segment_size(mdev->rq_queue); else if (mdev->agreed_pro_version == 94) - max_bio_size = DRBD_MAX_SIZE_H80_PACKET; + max_seg_s = DRBD_MAX_SIZE_H80_PACKET; /* else: drbd 8.3.9 and later, stay with default */ } - drbd_setup_queue_param(mdev, max_bio_size); + drbd_setup_queue_param(mdev, max_seg_s); /* If I am currently not R_PRIMARY, * but meta data primary indicator is set, @@ -1162,14 +1154,12 @@ static int drbd_nl_disk_conf(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp if (drbd_md_test_flag(mdev->ldev, MDF_FULL_SYNC)) { dev_info(DEV, "Assuming that all blocks are out of sync " "(aka FullSync)\n"); - if (drbd_bitmap_io(mdev, &drbd_bmio_set_n_write, - "set_n_write from attaching", BM_LOCKED_MASK)) { + if (drbd_bitmap_io(mdev, &drbd_bmio_set_n_write, "set_n_write from attaching")) { retcode = ERR_IO_MD_DISK; goto force_diskless_dec; } } else { - if (drbd_bitmap_io(mdev, &drbd_bm_read, - "read from attaching", BM_LOCKED_MASK) < 0) { + if (drbd_bitmap_io(mdev, &drbd_bm_read, "read from attaching") < 0) { retcode = ERR_IO_MD_DISK; goto force_diskless_dec; } @@ -1177,11 +1167,7 @@ static int drbd_nl_disk_conf(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp if (cp_discovered) { drbd_al_apply_to_bm(mdev); - if (drbd_bitmap_io(mdev, &drbd_bm_write, - "crashed primary apply AL", BM_LOCKED_MASK)) { - retcode = ERR_IO_MD_DISK; - goto force_diskless_dec; - } + drbd_al_to_on_disk_bm(mdev); } if (_drbd_bm_total_weight(mdev) == drbd_bm_bits(mdev)) @@ -1293,7 +1279,7 @@ static int drbd_nl_net_conf(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp, struct drbd_nl_cfg_reply *reply) { int i, ns; - enum drbd_ret_code retcode; + enum drbd_ret_codes retcode; struct net_conf *new_conf = NULL; struct crypto_hash *tfm = NULL; struct crypto_hash *integrity_w_tfm = NULL; @@ -1338,8 +1324,6 @@ static int drbd_nl_net_conf(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp, new_conf->wire_protocol = DRBD_PROT_C; new_conf->ping_timeo = DRBD_PING_TIMEO_DEF; new_conf->rr_conflict = DRBD_RR_CONFLICT_DEF; - new_conf->on_congestion = DRBD_ON_CONGESTION_DEF; - new_conf->cong_extents = DRBD_CONG_EXTENTS_DEF; if (!net_conf_from_tags(mdev, nlp->tag_list, new_conf)) { retcode = ERR_MANDATORY_TAG; @@ -1361,11 +1345,6 @@ static int drbd_nl_net_conf(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp, } } - if (new_conf->on_congestion != OC_BLOCK && new_conf->wire_protocol != DRBD_PROT_A) { - retcode = ERR_CONG_NOT_PROTO_A; - goto fail; - } - if (mdev->state.role == R_PRIMARY && new_conf->want_lose) { retcode = ERR_DISCARD; goto fail; @@ -1546,21 +1525,6 @@ static int drbd_nl_disconnect(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nl struct drbd_nl_cfg_reply *reply) { int retcode; - struct disconnect dc; - - memset(&dc, 0, sizeof(struct disconnect)); - if (!disconnect_from_tags(mdev, nlp->tag_list, &dc)) { - retcode = ERR_MANDATORY_TAG; - goto fail; - } - - if (dc.force) { - spin_lock_irq(&mdev->req_lock); - if (mdev->state.conn >= C_WF_CONNECTION) - _drbd_set_state(_NS(mdev, conn, C_DISCONNECTING), CS_HARD, NULL); - spin_unlock_irq(&mdev->req_lock); - goto done; - } retcode = _drbd_request_state(mdev, NS(conn, C_DISCONNECTING), CS_ORDERED); @@ -1878,10 +1842,6 @@ static int drbd_nl_invalidate(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nl { int retcode; - /* If there is still bitmap IO pending, probably because of a previous - * resync just being finished, wait for it before requesting a new resync. */ - wait_event(mdev->misc_wait, !test_bit(BITMAP_IO, &mdev->flags)); - retcode = _drbd_request_state(mdev, NS(conn, C_STARTING_SYNC_T), CS_ORDERED); if (retcode < SS_SUCCESS && retcode != SS_NEED_CONNECTION) @@ -1917,10 +1877,6 @@ static int drbd_nl_invalidate_peer(struct drbd_conf *mdev, struct drbd_nl_cfg_re { int retcode; - /* If there is still bitmap IO pending, probably because of a previous - * resync just being finished, wait for it before requesting a new resync. */ - wait_event(mdev->misc_wait, !test_bit(BITMAP_IO, &mdev->flags)); - retcode = _drbd_request_state(mdev, NS(conn, C_STARTING_SYNC_S), CS_ORDERED); if (retcode < SS_SUCCESS) { @@ -1929,9 +1885,9 @@ static int drbd_nl_invalidate_peer(struct drbd_conf *mdev, struct drbd_nl_cfg_re into a full resync. */ retcode = drbd_request_state(mdev, NS(pdsk, D_INCONSISTENT)); if (retcode >= SS_SUCCESS) { + /* open coded drbd_bitmap_io() */ if (drbd_bitmap_io(mdev, &drbd_bmio_set_susp_al, - "set_n_write from invalidate_peer", - BM_LOCKED_SET_ALLOWED)) + "set_n_write from invalidate_peer")) retcode = ERR_IO_MD_DISK; } } else @@ -1958,17 +1914,9 @@ static int drbd_nl_resume_sync(struct drbd_conf *mdev, struct drbd_nl_cfg_req *n struct drbd_nl_cfg_reply *reply) { int retcode = NO_ERROR; - union drbd_state s; - if (drbd_request_state(mdev, NS(user_isp, 0)) == SS_NOTHING_TO_DO) { - s = mdev->state; - if (s.conn == C_PAUSED_SYNC_S || s.conn == C_PAUSED_SYNC_T) { - retcode = s.aftr_isp ? ERR_PIC_AFTER_DEP : - s.peer_isp ? ERR_PIC_PEER_DEP : ERR_PAUSE_IS_CLEAR; - } else { - retcode = ERR_PAUSE_IS_CLEAR; - } - } + if (drbd_request_state(mdev, NS(user_isp, 0)) == SS_NOTHING_TO_DO) + retcode = ERR_PAUSE_IS_CLEAR; reply->ret_code = retcode; return 0; @@ -2106,11 +2054,6 @@ static int drbd_nl_start_ov(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp, reply->ret_code = ERR_MANDATORY_TAG; return 0; } - - /* If there is still bitmap IO pending, e.g. previous resync or verify - * just being finished, wait for it before requesting a new resync. */ - wait_event(mdev->misc_wait, !test_bit(BITMAP_IO, &mdev->flags)); - /* w_make_ov_request expects position to be aligned */ mdev->ov_start_sector = args.start_sector & ~BM_SECT_PER_BIT; reply->ret_code = drbd_request_state(mdev,NS(conn,C_VERIFY_S)); @@ -2154,8 +2097,7 @@ static int drbd_nl_new_c_uuid(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nl drbd_uuid_new_current(mdev); /* New current, previous to UI_BITMAP */ if (args.clear_bm) { - err = drbd_bitmap_io(mdev, &drbd_bmio_clear_n_write, - "clear_n_write from new_c_uuid", BM_LOCKED_MASK); + err = drbd_bitmap_io(mdev, &drbd_bmio_clear_n_write, "clear_n_write from new_c_uuid"); if (err) { dev_err(DEV, "Writing bitmap failed with %d\n",err); retcode = ERR_IO_MD_DISK; @@ -2163,7 +2105,6 @@ static int drbd_nl_new_c_uuid(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nl if (skip_initial_sync) { drbd_send_uuids_skip_initial_sync(mdev); _drbd_uuid_set(mdev, UI_BITMAP, 0); - drbd_print_uuids(mdev, "cleared bitmap UUID"); spin_lock_irq(&mdev->req_lock); _drbd_set_state(_NS2(mdev, disk, D_UP_TO_DATE, pdsk, D_UP_TO_DATE), CS_VERBOSE, NULL); @@ -2248,8 +2189,7 @@ static void drbd_connector_callback(struct cn_msg *req, struct netlink_skb_parms goto fail; } - if (nlp->packet_type >= P_nl_after_last_packet || - nlp->packet_type == P_return_code_only) { + if (nlp->packet_type >= P_nl_after_last_packet) { retcode = ERR_PACKET_NR; goto fail; } @@ -2265,7 +2205,7 @@ static void drbd_connector_callback(struct cn_msg *req, struct netlink_skb_parms reply_size += cm->reply_body_size; /* allocation not in the IO path, cqueue thread context */ - cn_reply = kzalloc(reply_size, GFP_KERNEL); + cn_reply = kmalloc(reply_size, GFP_KERNEL); if (!cn_reply) { retcode = ERR_NOMEM; goto fail; @@ -2273,7 +2213,7 @@ static void drbd_connector_callback(struct cn_msg *req, struct netlink_skb_parms reply = (struct drbd_nl_cfg_reply *) cn_reply->data; reply->packet_type = - cm->reply_body_size ? nlp->packet_type : P_return_code_only; + cm->reply_body_size ? nlp->packet_type : P_nl_after_last_packet; reply->minor = nlp->drbd_minor; reply->ret_code = NO_ERROR; /* Might by modified by cm->function. */ /* reply->tag_list; might be modified by cm->function. */ @@ -2436,7 +2376,7 @@ void drbd_bcast_ee(struct drbd_conf *mdev, /* receiver thread context, which is not in the writeout path (of this node), * but may be in the writeout path of the _other_ node. * GFP_NOIO to avoid potential "distributed deadlock". */ - cn_reply = kzalloc( + cn_reply = kmalloc( sizeof(struct cn_msg)+ sizeof(struct drbd_nl_cfg_reply)+ sizeof(struct dump_ee_tag_len_struct)+ @@ -2458,11 +2398,10 @@ void drbd_bcast_ee(struct drbd_conf *mdev, tl = tl_add_int(tl, T_ee_sector, &e->sector); tl = tl_add_int(tl, T_ee_block_id, &e->block_id); - /* dump the first 32k */ - len = min_t(unsigned, e->size, 32 << 10); put_unaligned(T_ee_data, tl++); - put_unaligned(len, tl++); + put_unaligned(e->size, tl++); + len = e->size; page = e->pages; page_chain_for_each(page) { void *d = kmap_atomic(page, KM_USER0); @@ -2471,8 +2410,6 @@ void drbd_bcast_ee(struct drbd_conf *mdev, kunmap_atomic(d, KM_USER0); tl = (unsigned short*)((char*)tl + l); len -= l; - if (len == 0) - break; } put_unaligned(TT_END, tl++); /* Close the tag list */ @@ -2571,7 +2508,6 @@ void drbd_nl_send_reply(struct cn_msg *req, int ret_code) (struct drbd_nl_cfg_reply *)cn_reply->data; int rr; - memset(buffer, 0, sizeof(buffer)); cn_reply->id = req->id; cn_reply->seq = req->seq; @@ -2579,7 +2515,6 @@ void drbd_nl_send_reply(struct cn_msg *req, int ret_code) cn_reply->len = sizeof(struct drbd_nl_cfg_reply); cn_reply->flags = 0; - reply->packet_type = P_return_code_only; reply->minor = ((struct drbd_nl_cfg_req *)req->data)->drbd_minor; reply->ret_code = ret_code; diff --git a/trunk/drivers/block/drbd/drbd_proc.c b/trunk/drivers/block/drbd/drbd_proc.c index 2959cdfb77f5..7e6ac307e2de 100644 --- a/trunk/drivers/block/drbd/drbd_proc.c +++ b/trunk/drivers/block/drbd/drbd_proc.c @@ -34,7 +34,6 @@ #include "drbd_int.h" static int drbd_proc_open(struct inode *inode, struct file *file); -static int drbd_proc_release(struct inode *inode, struct file *file); struct proc_dir_entry *drbd_proc; @@ -43,22 +42,9 @@ const struct file_operations drbd_proc_fops = { .open = drbd_proc_open, .read = seq_read, .llseek = seq_lseek, - .release = drbd_proc_release, + .release = single_release, }; -void seq_printf_with_thousands_grouping(struct seq_file *seq, long v) -{ - /* v is in kB/sec. We don't expect TiByte/sec yet. */ - if (unlikely(v >= 1000000)) { - /* cool: > GiByte/s */ - seq_printf(seq, "%ld,", v / 1000000); - v /= 1000000; - seq_printf(seq, "%03ld,%03ld", v/1000, v % 1000); - } else if (likely(v >= 1000)) - seq_printf(seq, "%ld,%03ld", v/1000, v % 1000); - else - seq_printf(seq, "%ld", v); -} /*lge * progress bars shamelessly adapted from driver/md/md.c @@ -85,15 +71,10 @@ static void drbd_syncer_progress(struct drbd_conf *mdev, struct seq_file *seq) seq_printf(seq, "."); seq_printf(seq, "] "); - if (mdev->state.conn == C_VERIFY_S || mdev->state.conn == C_VERIFY_T) - seq_printf(seq, "verified:"); - else - seq_printf(seq, "sync'ed:"); - seq_printf(seq, "%3u.%u%% ", res / 10, res % 10); - - /* if more than a few GB, display in MB */ - if (mdev->rs_total > (4UL << (30 - BM_BLOCK_SHIFT))) - seq_printf(seq, "(%lu/%lu)M", + seq_printf(seq, "sync'ed:%3u.%u%% ", res / 10, res % 10); + /* if more than 1 GB display in MB */ + if (mdev->rs_total > 0x100000L) + seq_printf(seq, "(%lu/%lu)M\n\t", (unsigned long) Bit2KB(rs_left >> 10), (unsigned long) Bit2KB(mdev->rs_total >> 10)); else @@ -113,7 +94,6 @@ static void drbd_syncer_progress(struct drbd_conf *mdev, struct seq_file *seq) /* Rolling marks. last_mark+1 may just now be modified. last_mark+2 is * at least (DRBD_SYNC_MARKS-2)*DRBD_SYNC_MARK_STEP old, and has at * least DRBD_SYNC_MARK_STEP time before it will be modified. */ - /* ------------------------ ~18s average ------------------------ */ i = (mdev->rs_last_mark + 2) % DRBD_SYNC_MARKS; dt = (jiffies - mdev->rs_mark_time[i]) / HZ; if (dt > (DRBD_SYNC_MARK_STEP * DRBD_SYNC_MARKS)) @@ -127,24 +107,14 @@ static void drbd_syncer_progress(struct drbd_conf *mdev, struct seq_file *seq) seq_printf(seq, "finish: %lu:%02lu:%02lu", rt / 3600, (rt % 3600) / 60, rt % 60); + /* current speed average over (SYNC_MARKS * SYNC_MARK_STEP) jiffies */ dbdt = Bit2KB(db/dt); - seq_printf(seq, " speed: "); - seq_printf_with_thousands_grouping(seq, dbdt); - seq_printf(seq, " ("); - /* ------------------------- ~3s average ------------------------ */ - if (proc_details >= 1) { - /* this is what drbd_rs_should_slow_down() uses */ - i = (mdev->rs_last_mark + DRBD_SYNC_MARKS-1) % DRBD_SYNC_MARKS; - dt = (jiffies - mdev->rs_mark_time[i]) / HZ; - if (!dt) - dt++; - db = mdev->rs_mark_left[i] - rs_left; - dbdt = Bit2KB(db/dt); - seq_printf_with_thousands_grouping(seq, dbdt); - seq_printf(seq, " -- "); - } + if (dbdt > 1000) + seq_printf(seq, " speed: %ld,%03ld", + dbdt/1000, dbdt % 1000); + else + seq_printf(seq, " speed: %ld", dbdt); - /* --------------------- long term average ---------------------- */ /* mean speed since syncer started * we do account for PausedSync periods */ dt = (jiffies - mdev->rs_start - mdev->rs_paused) / HZ; @@ -152,34 +122,20 @@ static void drbd_syncer_progress(struct drbd_conf *mdev, struct seq_file *seq) dt = 1; db = mdev->rs_total - rs_left; dbdt = Bit2KB(db/dt); - seq_printf_with_thousands_grouping(seq, dbdt); - seq_printf(seq, ")"); - - if (mdev->state.conn == C_SYNC_TARGET || - mdev->state.conn == C_VERIFY_S) { - seq_printf(seq, " want: "); - seq_printf_with_thousands_grouping(seq, mdev->c_sync_rate); - } - seq_printf(seq, " K/sec%s\n", stalled ? " (stalled)" : ""); + if (dbdt > 1000) + seq_printf(seq, " (%ld,%03ld)", + dbdt/1000, dbdt % 1000); + else + seq_printf(seq, " (%ld)", dbdt); - if (proc_details >= 1) { - /* 64 bit: - * we convert to sectors in the display below. */ - unsigned long bm_bits = drbd_bm_bits(mdev); - unsigned long bit_pos; - if (mdev->state.conn == C_VERIFY_S || - mdev->state.conn == C_VERIFY_T) - bit_pos = bm_bits - mdev->ov_left; + if (mdev->state.conn == C_SYNC_TARGET) { + if (mdev->c_sync_rate > 1000) + seq_printf(seq, " want: %d,%03d", + mdev->c_sync_rate / 1000, mdev->c_sync_rate % 1000); else - bit_pos = mdev->bm_resync_fo; - /* Total sectors may be slightly off for oddly - * sized devices. So what. */ - seq_printf(seq, - "\t%3d%% sector pos: %llu/%llu\n", - (int)(bit_pos / (bm_bits/100+1)), - (unsigned long long)bit_pos * BM_SECT_PER_BIT, - (unsigned long long)bm_bits * BM_SECT_PER_BIT); + seq_printf(seq, " want: %d", mdev->c_sync_rate); } + seq_printf(seq, " K/sec%s\n", stalled ? " (stalled)" : ""); } static void resync_dump_detail(struct seq_file *seq, struct lc_element *e) @@ -276,16 +232,20 @@ static int drbd_seq_show(struct seq_file *seq, void *v) mdev->epochs, write_ordering_chars[mdev->write_ordering] ); - seq_printf(seq, " oos:%llu\n", - Bit2KB((unsigned long long) - drbd_bm_total_weight(mdev))); + seq_printf(seq, " oos:%lu\n", + Bit2KB(drbd_bm_total_weight(mdev))); } if (mdev->state.conn == C_SYNC_SOURCE || - mdev->state.conn == C_SYNC_TARGET || - mdev->state.conn == C_VERIFY_S || - mdev->state.conn == C_VERIFY_T) + mdev->state.conn == C_SYNC_TARGET) drbd_syncer_progress(mdev, seq); + if (mdev->state.conn == C_VERIFY_S || mdev->state.conn == C_VERIFY_T) + seq_printf(seq, "\t%3d%% %lu/%lu\n", + (int)((mdev->rs_total-mdev->ov_left) / + (mdev->rs_total/100+1)), + mdev->rs_total - mdev->ov_left, + mdev->rs_total); + if (proc_details >= 1 && get_ldev_if_state(mdev, D_FAILED)) { lc_seq_printf_stats(seq, mdev->resync); lc_seq_printf_stats(seq, mdev->act_log); @@ -305,15 +265,7 @@ static int drbd_seq_show(struct seq_file *seq, void *v) static int drbd_proc_open(struct inode *inode, struct file *file) { - if (try_module_get(THIS_MODULE)) - return single_open(file, drbd_seq_show, PDE(inode)->data); - return -ENODEV; -} - -static int drbd_proc_release(struct inode *inode, struct file *file) -{ - module_put(THIS_MODULE); - return single_release(inode, file); + return single_open(file, drbd_seq_show, PDE(inode)->data); } /* PROC FS stuff end */ diff --git a/trunk/drivers/block/drbd/drbd_receiver.c b/trunk/drivers/block/drbd/drbd_receiver.c index fe1564c7d8b6..8e68be939deb 100644 --- a/trunk/drivers/block/drbd/drbd_receiver.c +++ b/trunk/drivers/block/drbd/drbd_receiver.c @@ -277,7 +277,7 @@ static void drbd_pp_free(struct drbd_conf *mdev, struct page *page, int is_net) atomic_t *a = is_net ? &mdev->pp_in_use_by_net : &mdev->pp_in_use; int i; - if (drbd_pp_vacant > (DRBD_MAX_BIO_SIZE/PAGE_SIZE)*minor_count) + if (drbd_pp_vacant > (DRBD_MAX_SEGMENT_SIZE/PAGE_SIZE)*minor_count) i = page_chain_free(page); else { struct page *tmp; @@ -319,7 +319,7 @@ struct drbd_epoch_entry *drbd_alloc_ee(struct drbd_conf *mdev, struct page *page; unsigned nr_pages = (data_size + PAGE_SIZE -1) >> PAGE_SHIFT; - if (drbd_insert_fault(mdev, DRBD_FAULT_AL_EE)) + if (FAULT_ACTIVE(mdev, DRBD_FAULT_AL_EE)) return NULL; e = mempool_alloc(drbd_ee_mempool, gfp_mask & ~__GFP_HIGHMEM); @@ -725,16 +725,16 @@ static int drbd_socket_okay(struct drbd_conf *mdev, struct socket **sock) char tb[4]; if (!*sock) - return false; + return FALSE; rr = drbd_recv_short(mdev, *sock, tb, 4, MSG_DONTWAIT | MSG_PEEK); if (rr > 0 || rr == -EAGAIN) { - return true; + return TRUE; } else { sock_release(*sock); *sock = NULL; - return false; + return FALSE; } } @@ -768,7 +768,8 @@ static int drbd_connect(struct drbd_conf *mdev) if (s || ++try >= 3) break; /* give the other side time to call bind() & listen() */ - schedule_timeout_interruptible(HZ / 10); + __set_current_state(TASK_INTERRUPTIBLE); + schedule_timeout(HZ / 10); } if (s) { @@ -787,7 +788,8 @@ static int drbd_connect(struct drbd_conf *mdev) } if (sock && msock) { - schedule_timeout_interruptible(HZ / 10); + __set_current_state(TASK_INTERRUPTIBLE); + schedule_timeout(HZ / 10); ok = drbd_socket_okay(mdev, &sock); ok = drbd_socket_okay(mdev, &msock) && ok; if (ok) @@ -904,7 +906,7 @@ static int drbd_connect(struct drbd_conf *mdev) put_ldev(mdev); } - if (drbd_send_protocol(mdev) == -1) + if (!drbd_send_protocol(mdev)) return -1; drbd_send_sync_param(mdev, &mdev->sync_conf); drbd_send_sizes(mdev, 0, 0); @@ -912,7 +914,6 @@ static int drbd_connect(struct drbd_conf *mdev) drbd_send_state(mdev); clear_bit(USE_DEGR_WFC_T, &mdev->flags); clear_bit(RESIZE_PENDING, &mdev->flags); - mod_timer(&mdev->request_timer, jiffies + HZ); /* just start it here. */ return 1; @@ -931,9 +932,8 @@ static int drbd_recv_header(struct drbd_conf *mdev, enum drbd_packets *cmd, unsi r = drbd_recv(mdev, h, sizeof(*h)); if (unlikely(r != sizeof(*h))) { - if (!signal_pending(current)) - dev_warn(DEV, "short read expecting header on sock: r=%d\n", r); - return false; + dev_err(DEV, "short read expecting header on sock: r=%d\n", r); + return FALSE; } if (likely(h->h80.magic == BE_DRBD_MAGIC)) { @@ -947,11 +947,11 @@ static int drbd_recv_header(struct drbd_conf *mdev, enum drbd_packets *cmd, unsi be32_to_cpu(h->h80.magic), be16_to_cpu(h->h80.command), be16_to_cpu(h->h80.length)); - return false; + return FALSE; } mdev->last_received = jiffies; - return true; + return TRUE; } static void drbd_flush(struct drbd_conf *mdev) @@ -1074,16 +1074,6 @@ void drbd_bump_write_ordering(struct drbd_conf *mdev, enum write_ordering_e wo) * @mdev: DRBD device. * @e: epoch entry * @rw: flag field, see bio->bi_rw - * - * May spread the pages to multiple bios, - * depending on bio_add_page restrictions. - * - * Returns 0 if all bios have been submitted, - * -ENOMEM if we could not allocate enough bios, - * -ENOSPC (any better suggestion?) if we have not been able to bio_add_page a - * single page to an empty bio (which should never happen and likely indicates - * that the lower level IO stack is in some way broken). This has been observed - * on certain Xen deployments. */ /* TODO allocate from our own bio_set. */ int drbd_submit_ee(struct drbd_conf *mdev, struct drbd_epoch_entry *e, @@ -1096,7 +1086,6 @@ int drbd_submit_ee(struct drbd_conf *mdev, struct drbd_epoch_entry *e, unsigned ds = e->size; unsigned n_bios = 0; unsigned nr_pages = (ds + PAGE_SIZE -1) >> PAGE_SHIFT; - int err = -ENOMEM; /* In most cases, we will only need one bio. But in case the lower * level restrictions happen to be different at this offset on this @@ -1122,17 +1111,8 @@ int drbd_submit_ee(struct drbd_conf *mdev, struct drbd_epoch_entry *e, page_chain_for_each(page) { unsigned len = min_t(unsigned, ds, PAGE_SIZE); if (!bio_add_page(bio, page, len, 0)) { - /* A single page must always be possible! - * But in case it fails anyways, - * we deal with it, and complain (below). */ - if (bio->bi_vcnt == 0) { - dev_err(DEV, - "bio_add_page failed for len=%u, " - "bi_vcnt=0 (bi_sector=%llu)\n", - len, (unsigned long long)bio->bi_sector); - err = -ENOSPC; - goto fail; - } + /* a single page must always be possible! */ + BUG_ON(bio->bi_vcnt == 0); goto next_bio; } ds -= len; @@ -1158,7 +1138,7 @@ int drbd_submit_ee(struct drbd_conf *mdev, struct drbd_epoch_entry *e, bios = bios->bi_next; bio_put(bio); } - return err; + return -ENOMEM; } static int receive_Barrier(struct drbd_conf *mdev, enum drbd_packets cmd, unsigned int data_size) @@ -1180,7 +1160,7 @@ static int receive_Barrier(struct drbd_conf *mdev, enum drbd_packets cmd, unsign switch (mdev->write_ordering) { case WO_none: if (rv == FE_RECYCLED) - return true; + return TRUE; /* receiver context, in the writeout path of the other node. * avoid potential distributed deadlock */ @@ -1208,10 +1188,10 @@ static int receive_Barrier(struct drbd_conf *mdev, enum drbd_packets cmd, unsign D_ASSERT(atomic_read(&epoch->active) == 0); D_ASSERT(epoch->flags == 0); - return true; + return TRUE; default: dev_err(DEV, "Strangeness in mdev->write_ordering %d\n", mdev->write_ordering); - return false; + return FALSE; } epoch->flags = 0; @@ -1229,7 +1209,7 @@ static int receive_Barrier(struct drbd_conf *mdev, enum drbd_packets cmd, unsign } spin_unlock(&mdev->epoch_lock); - return true; + return TRUE; } /* used from receive_RSDataReply (recv_resync_read) @@ -1251,25 +1231,21 @@ read_in_block(struct drbd_conf *mdev, u64 id, sector_t sector, int data_size) __ if (dgs) { rr = drbd_recv(mdev, dig_in, dgs); if (rr != dgs) { - if (!signal_pending(current)) - dev_warn(DEV, - "short read receiving data digest: read %d expected %d\n", - rr, dgs); + dev_warn(DEV, "short read receiving data digest: read %d expected %d\n", + rr, dgs); return NULL; } } data_size -= dgs; - ERR_IF(data_size == 0) return NULL; ERR_IF(data_size & 0x1ff) return NULL; - ERR_IF(data_size > DRBD_MAX_BIO_SIZE) return NULL; + ERR_IF(data_size > DRBD_MAX_SEGMENT_SIZE) return NULL; /* even though we trust out peer, * we sometimes have to double check. */ if (sector + (data_size>>9) > capacity) { - dev_err(DEV, "request from peer beyond end of local disk: " - "capacity: %llus < sector: %llus + size: %u\n", + dev_err(DEV, "capacity: %llus < sector: %llus + size: %u\n", (unsigned long long)capacity, (unsigned long long)sector, data_size); return NULL; @@ -1288,16 +1264,15 @@ read_in_block(struct drbd_conf *mdev, u64 id, sector_t sector, int data_size) __ unsigned len = min_t(int, ds, PAGE_SIZE); data = kmap(page); rr = drbd_recv(mdev, data, len); - if (drbd_insert_fault(mdev, DRBD_FAULT_RECEIVE)) { + if (FAULT_ACTIVE(mdev, DRBD_FAULT_RECEIVE)) { dev_err(DEV, "Fault injection: Corrupting data on receive\n"); data[0] = data[0] ^ (unsigned long)-1; } kunmap(page); if (rr != len) { drbd_free_ee(mdev, e); - if (!signal_pending(current)) - dev_warn(DEV, "short read receiving data: read %d expected %d\n", - rr, len); + dev_warn(DEV, "short read receiving data: read %d expected %d\n", + rr, len); return NULL; } ds -= rr; @@ -1306,8 +1281,7 @@ read_in_block(struct drbd_conf *mdev, u64 id, sector_t sector, int data_size) __ if (dgs) { drbd_csum_ee(mdev, mdev->integrity_r_tfm, e, dig_vv); if (memcmp(dig_in, dig_vv, dgs)) { - dev_err(DEV, "Digest integrity check FAILED: %llus +%u\n", - (unsigned long long)sector, data_size); + dev_err(DEV, "Digest integrity check FAILED.\n"); drbd_bcast_ee(mdev, "digest failed", dgs, dig_in, dig_vv, e); drbd_free_ee(mdev, e); @@ -1328,7 +1302,7 @@ static int drbd_drain_block(struct drbd_conf *mdev, int data_size) void *data; if (!data_size) - return true; + return TRUE; page = drbd_pp_alloc(mdev, 1, 1); @@ -1337,10 +1311,8 @@ static int drbd_drain_block(struct drbd_conf *mdev, int data_size) rr = drbd_recv(mdev, data, min_t(int, data_size, PAGE_SIZE)); if (rr != min_t(int, data_size, PAGE_SIZE)) { rv = 0; - if (!signal_pending(current)) - dev_warn(DEV, - "short read receiving data: read %d expected %d\n", - rr, min_t(int, data_size, PAGE_SIZE)); + dev_warn(DEV, "short read receiving data: read %d expected %d\n", + rr, min_t(int, data_size, PAGE_SIZE)); break; } data_size -= rr; @@ -1365,10 +1337,8 @@ static int recv_dless_read(struct drbd_conf *mdev, struct drbd_request *req, if (dgs) { rr = drbd_recv(mdev, dig_in, dgs); if (rr != dgs) { - if (!signal_pending(current)) - dev_warn(DEV, - "short read receiving data reply digest: read %d expected %d\n", - rr, dgs); + dev_warn(DEV, "short read receiving data reply digest: read %d expected %d\n", + rr, dgs); return 0; } } @@ -1389,10 +1359,9 @@ static int recv_dless_read(struct drbd_conf *mdev, struct drbd_request *req, expect); kunmap(bvec->bv_page); if (rr != expect) { - if (!signal_pending(current)) - dev_warn(DEV, "short read receiving data reply: " - "read %d expected %d\n", - rr, expect); + dev_warn(DEV, "short read receiving data reply: " + "read %d expected %d\n", + rr, expect); return 0; } data_size -= rr; @@ -1456,10 +1425,11 @@ static int recv_resync_read(struct drbd_conf *mdev, sector_t sector, int data_si atomic_add(data_size >> 9, &mdev->rs_sect_ev); if (drbd_submit_ee(mdev, e, WRITE, DRBD_FAULT_RS_WR) == 0) - return true; + return TRUE; - /* don't care for the reason here */ - dev_err(DEV, "submit failed, triggering re-connect\n"); + /* drbd_submit_ee currently fails for one reason only: + * not being able to allocate enough bios. + * Is dropping the connection going to help? */ spin_lock_irq(&mdev->req_lock); list_del(&e->w.list); spin_unlock_irq(&mdev->req_lock); @@ -1467,7 +1437,7 @@ static int recv_resync_read(struct drbd_conf *mdev, sector_t sector, int data_si drbd_free_ee(mdev, e); fail: put_ldev(mdev); - return false; + return FALSE; } static int receive_DataReply(struct drbd_conf *mdev, enum drbd_packets cmd, unsigned int data_size) @@ -1484,7 +1454,7 @@ static int receive_DataReply(struct drbd_conf *mdev, enum drbd_packets cmd, unsi spin_unlock_irq(&mdev->req_lock); if (unlikely(!req)) { dev_err(DEV, "Got a corrupt block_id/sector pair(1).\n"); - return false; + return FALSE; } /* hlist_del(&req->colision) is done in _req_may_be_done, to avoid @@ -1641,15 +1611,15 @@ static int drbd_wait_peer_seq(struct drbd_conf *mdev, const u32 packet_seq) return ret; } -/* see also bio_flags_to_wire() - * DRBD_REQ_*, because we need to semantically map the flags to data packet - * flags and back. We may replicate to other kernel versions. */ -static unsigned long wire_flags_to_bio(struct drbd_conf *mdev, u32 dpf) +static unsigned long write_flags_to_bio(struct drbd_conf *mdev, u32 dpf) { - return (dpf & DP_RW_SYNC ? REQ_SYNC : 0) | - (dpf & DP_FUA ? REQ_FUA : 0) | - (dpf & DP_FLUSH ? REQ_FLUSH : 0) | - (dpf & DP_DISCARD ? REQ_DISCARD : 0); + if (mdev->agreed_pro_version >= 95) + return (dpf & DP_RW_SYNC ? REQ_SYNC : 0) | + (dpf & DP_FUA ? REQ_FUA : 0) | + (dpf & DP_FLUSH ? REQ_FUA : 0) | + (dpf & DP_DISCARD ? REQ_DISCARD : 0); + else + return dpf & DP_RW_SYNC ? REQ_SYNC : 0; } /* mirrored write */ @@ -1662,6 +1632,9 @@ static int receive_Data(struct drbd_conf *mdev, enum drbd_packets cmd, unsigned u32 dp_flags; if (!get_ldev(mdev)) { + if (__ratelimit(&drbd_ratelimit_state)) + dev_err(DEV, "Can not write mirrored data block " + "to local disk.\n"); spin_lock(&mdev->peer_seq_lock); if (mdev->peer_seq+1 == be32_to_cpu(p->seq_num)) mdev->peer_seq++; @@ -1681,23 +1654,23 @@ static int receive_Data(struct drbd_conf *mdev, enum drbd_packets cmd, unsigned e = read_in_block(mdev, p->block_id, sector, data_size); if (!e) { put_ldev(mdev); - return false; + return FALSE; } e->w.cb = e_end_block; - dp_flags = be32_to_cpu(p->dp_flags); - rw |= wire_flags_to_bio(mdev, dp_flags); - - if (dp_flags & DP_MAY_SET_IN_SYNC) - e->flags |= EE_MAY_SET_IN_SYNC; - spin_lock(&mdev->epoch_lock); e->epoch = mdev->current_epoch; atomic_inc(&e->epoch->epoch_size); atomic_inc(&e->epoch->active); spin_unlock(&mdev->epoch_lock); + dp_flags = be32_to_cpu(p->dp_flags); + rw |= write_flags_to_bio(mdev, dp_flags); + + if (dp_flags & DP_MAY_SET_IN_SYNC) + e->flags |= EE_MAY_SET_IN_SYNC; + /* I'm the receiver, I do hold a net_cnt reference. */ if (!mdev->net_conf->two_primaries) { spin_lock_irq(&mdev->req_lock); @@ -1800,7 +1773,7 @@ static int receive_Data(struct drbd_conf *mdev, enum drbd_packets cmd, unsigned put_ldev(mdev); wake_asender(mdev); finish_wait(&mdev->misc_wait, &wait); - return true; + return TRUE; } if (signal_pending(current)) { @@ -1856,10 +1829,11 @@ static int receive_Data(struct drbd_conf *mdev, enum drbd_packets cmd, unsigned } if (drbd_submit_ee(mdev, e, rw, DRBD_FAULT_DT_WR) == 0) - return true; + return TRUE; - /* don't care for the reason here */ - dev_err(DEV, "submit failed, triggering re-connect\n"); + /* drbd_submit_ee currently fails for one reason only: + * not being able to allocate enough bios. + * Is dropping the connection going to help? */ spin_lock_irq(&mdev->req_lock); list_del(&e->w.list); hlist_del_init(&e->colision); @@ -1868,10 +1842,12 @@ static int receive_Data(struct drbd_conf *mdev, enum drbd_packets cmd, unsigned drbd_al_complete_io(mdev, e->sector); out_interrupted: - drbd_may_finish_epoch(mdev, e->epoch, EV_PUT + EV_CLEANUP); + /* yes, the epoch_size now is imbalanced. + * but we drop the connection anyways, so we don't have a chance to + * receive a barrier... atomic_inc(&mdev->epoch_size); */ put_ldev(mdev); drbd_free_ee(mdev, e); - return false; + return FALSE; } /* We may throttle resync, if the lower device seems to be busy, @@ -1885,11 +1861,10 @@ static int receive_Data(struct drbd_conf *mdev, enum drbd_packets cmd, unsigned * The current sync rate used here uses only the most recent two step marks, * to have a short time average so we can react faster. */ -int drbd_rs_should_slow_down(struct drbd_conf *mdev, sector_t sector) +int drbd_rs_should_slow_down(struct drbd_conf *mdev) { struct gendisk *disk = mdev->ldev->backing_bdev->bd_contains->bd_disk; unsigned long db, dt, dbdt; - struct lc_element *tmp; int curr_events; int throttle = 0; @@ -1897,22 +1872,9 @@ int drbd_rs_should_slow_down(struct drbd_conf *mdev, sector_t sector) if (mdev->sync_conf.c_min_rate == 0) return 0; - spin_lock_irq(&mdev->al_lock); - tmp = lc_find(mdev->resync, BM_SECT_TO_EXT(sector)); - if (tmp) { - struct bm_extent *bm_ext = lc_entry(tmp, struct bm_extent, lce); - if (test_bit(BME_PRIORITY, &bm_ext->flags)) { - spin_unlock_irq(&mdev->al_lock); - return 0; - } - /* Do not slow down if app IO is already waiting for this extent */ - } - spin_unlock_irq(&mdev->al_lock); - curr_events = (int)part_stat_read(&disk->part0, sectors[0]) + (int)part_stat_read(&disk->part0, sectors[1]) - atomic_read(&mdev->rs_sect_ev); - if (!mdev->rs_last_events || curr_events - mdev->rs_last_events > 64) { unsigned long rs_left; int i; @@ -1921,12 +1883,8 @@ int drbd_rs_should_slow_down(struct drbd_conf *mdev, sector_t sector) /* sync speed average over the last 2*DRBD_SYNC_MARK_STEP, * approx. */ - i = (mdev->rs_last_mark + DRBD_SYNC_MARKS-1) % DRBD_SYNC_MARKS; - - if (mdev->state.conn == C_VERIFY_S || mdev->state.conn == C_VERIFY_T) - rs_left = mdev->ov_left; - else - rs_left = drbd_bm_total_weight(mdev) - mdev->rs_failed; + i = (mdev->rs_last_mark + DRBD_SYNC_MARKS-2) % DRBD_SYNC_MARKS; + rs_left = drbd_bm_total_weight(mdev) - mdev->rs_failed; dt = ((long)jiffies - (long)mdev->rs_mark_time[i]) / HZ; if (!dt) @@ -1954,15 +1912,15 @@ static int receive_DataRequest(struct drbd_conf *mdev, enum drbd_packets cmd, un sector = be64_to_cpu(p->sector); size = be32_to_cpu(p->blksize); - if (size <= 0 || (size & 0x1ff) != 0 || size > DRBD_MAX_BIO_SIZE) { + if (size <= 0 || (size & 0x1ff) != 0 || size > DRBD_MAX_SEGMENT_SIZE) { dev_err(DEV, "%s:%d: sector: %llus, size: %u\n", __FILE__, __LINE__, (unsigned long long)sector, size); - return false; + return FALSE; } if (sector + (size>>9) > capacity) { dev_err(DEV, "%s:%d: sector: %llus, size: %u\n", __FILE__, __LINE__, (unsigned long long)sector, size); - return false; + return FALSE; } if (!get_ldev_if_state(mdev, D_UP_TO_DATE)) { @@ -1999,7 +1957,7 @@ static int receive_DataRequest(struct drbd_conf *mdev, enum drbd_packets cmd, un e = drbd_alloc_ee(mdev, p->block_id, sector, size, GFP_NOIO); if (!e) { put_ldev(mdev); - return false; + return FALSE; } switch (cmd) { @@ -2012,8 +1970,6 @@ static int receive_DataRequest(struct drbd_conf *mdev, enum drbd_packets cmd, un case P_RS_DATA_REQUEST: e->w.cb = w_e_end_rsdata_req; fault_type = DRBD_FAULT_RS_RD; - /* used in the sector offset progress display */ - mdev->bm_resync_fo = BM_SECT_TO_BIT(sector); break; case P_OV_REPLY: @@ -2035,11 +1991,7 @@ static int receive_DataRequest(struct drbd_conf *mdev, enum drbd_packets cmd, un if (cmd == P_CSUM_RS_REQUEST) { D_ASSERT(mdev->agreed_pro_version >= 89); e->w.cb = w_e_end_csum_rs_req; - /* used in the sector offset progress display */ - mdev->bm_resync_fo = BM_SECT_TO_BIT(sector); } else if (cmd == P_OV_REPLY) { - /* track progress, we may need to throttle */ - atomic_add(size >> 9, &mdev->rs_sect_in); e->w.cb = w_e_end_ov_reply; dec_rs_pending(mdev); /* drbd_rs_begin_io done when we sent this request, @@ -2051,16 +2003,9 @@ static int receive_DataRequest(struct drbd_conf *mdev, enum drbd_packets cmd, un case P_OV_REQUEST: if (mdev->ov_start_sector == ~(sector_t)0 && mdev->agreed_pro_version >= 90) { - unsigned long now = jiffies; - int i; mdev->ov_start_sector = sector; mdev->ov_position = sector; - mdev->ov_left = drbd_bm_bits(mdev) - BM_SECT_TO_BIT(sector); - mdev->rs_total = mdev->ov_left; - for (i = 0; i < DRBD_SYNC_MARKS; i++) { - mdev->rs_mark_left[i] = mdev->ov_left; - mdev->rs_mark_time[i] = now; - } + mdev->ov_left = mdev->rs_total - BM_SECT_TO_BIT(sector); dev_info(DEV, "Online Verify start sector: %llu\n", (unsigned long long)sector); } @@ -2097,9 +2042,9 @@ static int receive_DataRequest(struct drbd_conf *mdev, enum drbd_packets cmd, un * we would also throttle its application reads. * In that case, throttling is done on the SyncTarget only. */ - if (mdev->state.peer != R_PRIMARY && drbd_rs_should_slow_down(mdev, sector)) - schedule_timeout_uninterruptible(HZ/10); - if (drbd_rs_begin_io(mdev, sector)) + if (mdev->state.peer != R_PRIMARY && drbd_rs_should_slow_down(mdev)) + msleep(100); + if (drbd_rs_begin_io(mdev, e->sector)) goto out_free_e; submit_for_resync: @@ -2112,10 +2057,11 @@ static int receive_DataRequest(struct drbd_conf *mdev, enum drbd_packets cmd, un spin_unlock_irq(&mdev->req_lock); if (drbd_submit_ee(mdev, e, READ, fault_type) == 0) - return true; + return TRUE; - /* don't care for the reason here */ - dev_err(DEV, "submit failed, triggering re-connect\n"); + /* drbd_submit_ee currently fails for one reason only: + * not being able to allocate enough bios. + * Is dropping the connection going to help? */ spin_lock_irq(&mdev->req_lock); list_del(&e->w.list); spin_unlock_irq(&mdev->req_lock); @@ -2124,7 +2070,7 @@ static int receive_DataRequest(struct drbd_conf *mdev, enum drbd_packets cmd, un out_free_e: put_ldev(mdev); drbd_free_ee(mdev, e); - return false; + return FALSE; } static int drbd_asb_recover_0p(struct drbd_conf *mdev) __must_hold(local) @@ -2201,7 +2147,10 @@ static int drbd_asb_recover_0p(struct drbd_conf *mdev) __must_hold(local) static int drbd_asb_recover_1p(struct drbd_conf *mdev) __must_hold(local) { - int hg, rv = -100; + int self, peer, hg, rv = -100; + + self = mdev->ldev->md.uuid[UI_BITMAP] & 1; + peer = mdev->p_uuid[UI_BITMAP] & 1; switch (mdev->net_conf->after_sb_1p) { case ASB_DISCARD_YOUNGER_PRI: @@ -2228,14 +2177,12 @@ static int drbd_asb_recover_1p(struct drbd_conf *mdev) __must_hold(local) case ASB_CALL_HELPER: hg = drbd_asb_recover_0p(mdev); if (hg == -1 && mdev->state.role == R_PRIMARY) { - enum drbd_state_rv rv2; - - drbd_set_role(mdev, R_SECONDARY, 0); + self = drbd_set_role(mdev, R_SECONDARY, 0); /* drbd_change_state() does not sleep while in SS_IN_TRANSIENT_STATE, * we might be here in C_WF_REPORT_PARAMS which is transient. * we do not need to wait for the after state change work either. */ - rv2 = drbd_change_state(mdev, CS_VERBOSE, NS(role, R_SECONDARY)); - if (rv2 != SS_SUCCESS) { + self = drbd_change_state(mdev, CS_VERBOSE, NS(role, R_SECONDARY)); + if (self != SS_SUCCESS) { drbd_khelper(mdev, "pri-lost-after-sb"); } else { dev_warn(DEV, "Successfully gave up primary role.\n"); @@ -2250,7 +2197,10 @@ static int drbd_asb_recover_1p(struct drbd_conf *mdev) __must_hold(local) static int drbd_asb_recover_2p(struct drbd_conf *mdev) __must_hold(local) { - int hg, rv = -100; + int self, peer, hg, rv = -100; + + self = mdev->ldev->md.uuid[UI_BITMAP] & 1; + peer = mdev->p_uuid[UI_BITMAP] & 1; switch (mdev->net_conf->after_sb_2p) { case ASB_DISCARD_YOUNGER_PRI: @@ -2270,13 +2220,11 @@ static int drbd_asb_recover_2p(struct drbd_conf *mdev) __must_hold(local) case ASB_CALL_HELPER: hg = drbd_asb_recover_0p(mdev); if (hg == -1) { - enum drbd_state_rv rv2; - /* drbd_change_state() does not sleep while in SS_IN_TRANSIENT_STATE, * we might be here in C_WF_REPORT_PARAMS which is transient. * we do not need to wait for the after state change work either. */ - rv2 = drbd_change_state(mdev, CS_VERBOSE, NS(role, R_SECONDARY)); - if (rv2 != SS_SUCCESS) { + self = drbd_change_state(mdev, CS_VERBOSE, NS(role, R_SECONDARY)); + if (self != SS_SUCCESS) { drbd_khelper(mdev, "pri-lost-after-sb"); } else { dev_warn(DEV, "Successfully gave up primary role.\n"); @@ -2315,8 +2263,6 @@ static void drbd_uuid_dump(struct drbd_conf *mdev, char *text, u64 *uuid, -2 C_SYNC_TARGET set BitMap -100 after split brain, disconnect -1000 unrelated data --1091 requires proto 91 --1096 requires proto 96 */ static int drbd_uuid_compare(struct drbd_conf *mdev, int *rule_nr) __must_hold(local) { @@ -2346,7 +2292,7 @@ static int drbd_uuid_compare(struct drbd_conf *mdev, int *rule_nr) __must_hold(l if (mdev->p_uuid[UI_BITMAP] == (u64)0 && mdev->ldev->md.uuid[UI_BITMAP] != (u64)0) { if (mdev->agreed_pro_version < 91) - return -1091; + return -1001; if ((mdev->ldev->md.uuid[UI_BITMAP] & ~((u64)1)) == (mdev->p_uuid[UI_HISTORY_START] & ~((u64)1)) && (mdev->ldev->md.uuid[UI_HISTORY_START] & ~((u64)1)) == (mdev->p_uuid[UI_HISTORY_START + 1] & ~((u64)1))) { @@ -2367,7 +2313,7 @@ static int drbd_uuid_compare(struct drbd_conf *mdev, int *rule_nr) __must_hold(l if (mdev->ldev->md.uuid[UI_BITMAP] == (u64)0 && mdev->p_uuid[UI_BITMAP] != (u64)0) { if (mdev->agreed_pro_version < 91) - return -1091; + return -1001; if ((mdev->ldev->md.uuid[UI_HISTORY_START] & ~((u64)1)) == (mdev->p_uuid[UI_BITMAP] & ~((u64)1)) && (mdev->ldev->md.uuid[UI_HISTORY_START + 1] & ~((u64)1)) == (mdev->p_uuid[UI_HISTORY_START] & ~((u64)1))) { @@ -2412,22 +2358,17 @@ static int drbd_uuid_compare(struct drbd_conf *mdev, int *rule_nr) __must_hold(l *rule_nr = 51; peer = mdev->p_uuid[UI_HISTORY_START] & ~((u64)1); if (self == peer) { - if (mdev->agreed_pro_version < 96 ? - (mdev->ldev->md.uuid[UI_HISTORY_START] & ~((u64)1)) == - (mdev->p_uuid[UI_HISTORY_START + 1] & ~((u64)1)) : - peer + UUID_NEW_BM_OFFSET == (mdev->p_uuid[UI_BITMAP] & ~((u64)1))) { + self = mdev->ldev->md.uuid[UI_HISTORY_START] & ~((u64)1); + peer = mdev->p_uuid[UI_HISTORY_START + 1] & ~((u64)1); + if (self == peer) { /* The last P_SYNC_UUID did not get though. Undo the last start of resync as sync source modifications of the peer's UUIDs. */ if (mdev->agreed_pro_version < 91) - return -1091; + return -1001; mdev->p_uuid[UI_BITMAP] = mdev->p_uuid[UI_HISTORY_START]; mdev->p_uuid[UI_HISTORY_START] = mdev->p_uuid[UI_HISTORY_START + 1]; - - dev_info(DEV, "Did not got last syncUUID packet, corrected:\n"); - drbd_uuid_dump(mdev, "peer", mdev->p_uuid, mdev->p_uuid[UI_SIZE], mdev->p_uuid[UI_FLAGS]); - return -1; } } @@ -2449,20 +2390,20 @@ static int drbd_uuid_compare(struct drbd_conf *mdev, int *rule_nr) __must_hold(l *rule_nr = 71; self = mdev->ldev->md.uuid[UI_HISTORY_START] & ~((u64)1); if (self == peer) { - if (mdev->agreed_pro_version < 96 ? - (mdev->ldev->md.uuid[UI_HISTORY_START + 1] & ~((u64)1)) == - (mdev->p_uuid[UI_HISTORY_START] & ~((u64)1)) : - self + UUID_NEW_BM_OFFSET == (mdev->ldev->md.uuid[UI_BITMAP] & ~((u64)1))) { + self = mdev->ldev->md.uuid[UI_HISTORY_START + 1] & ~((u64)1); + peer = mdev->p_uuid[UI_HISTORY_START] & ~((u64)1); + if (self == peer) { /* The last P_SYNC_UUID did not get though. Undo the last start of resync as sync source modifications of our UUIDs. */ if (mdev->agreed_pro_version < 91) - return -1091; + return -1001; _drbd_uuid_set(mdev, UI_BITMAP, mdev->ldev->md.uuid[UI_HISTORY_START]); _drbd_uuid_set(mdev, UI_HISTORY_START, mdev->ldev->md.uuid[UI_HISTORY_START + 1]); - dev_info(DEV, "Last syncUUID did not get through, corrected:\n"); + dev_info(DEV, "Undid last start of resync:\n"); + drbd_uuid_dump(mdev, "self", mdev->ldev->md.uuid, mdev->state.disk >= D_NEGOTIATING ? drbd_bm_total_weight(mdev) : 0, 0); @@ -2525,8 +2466,8 @@ static enum drbd_conns drbd_sync_handshake(struct drbd_conf *mdev, enum drbd_rol dev_alert(DEV, "Unrelated data, aborting!\n"); return C_MASK; } - if (hg < -1000) { - dev_alert(DEV, "To resolve this both sides have to support at least protocol %d\n", -hg - 1000); + if (hg == -1001) { + dev_alert(DEV, "To resolve this both sides have to support at least protocol\n"); return C_MASK; } @@ -2625,8 +2566,7 @@ static enum drbd_conns drbd_sync_handshake(struct drbd_conf *mdev, enum drbd_rol if (abs(hg) >= 2) { dev_info(DEV, "Writing the whole bitmap, full sync required after drbd_sync_handshake.\n"); - if (drbd_bitmap_io(mdev, &drbd_bmio_set_n_write, "set_n_write from sync_handshake", - BM_LOCKED_SET_ALLOWED)) + if (drbd_bitmap_io(mdev, &drbd_bmio_set_n_write, "set_n_write from sync_handshake")) return C_MASK; } @@ -2720,7 +2660,7 @@ static int receive_protocol(struct drbd_conf *mdev, enum drbd_packets cmd, unsig unsigned char *my_alg = mdev->net_conf->integrity_alg; if (drbd_recv(mdev, p_integrity_alg, data_size) != data_size) - return false; + return FALSE; p_integrity_alg[SHARED_SECRET_MAX-1] = 0; if (strcmp(p_integrity_alg, my_alg)) { @@ -2731,11 +2671,11 @@ static int receive_protocol(struct drbd_conf *mdev, enum drbd_packets cmd, unsig my_alg[0] ? my_alg : (unsigned char *)""); } - return true; + return TRUE; disconnect: drbd_force_state(mdev, NS(conn, C_DISCONNECTING)); - return false; + return FALSE; } /* helper function @@ -2767,7 +2707,7 @@ struct crypto_hash *drbd_crypto_alloc_digest_safe(const struct drbd_conf *mdev, static int receive_SyncParam(struct drbd_conf *mdev, enum drbd_packets cmd, unsigned int packet_size) { - int ok = true; + int ok = TRUE; struct p_rs_param_95 *p = &mdev->data.rbuf.rs_param_95; unsigned int header_size, data_size, exp_max_sz; struct crypto_hash *verify_tfm = NULL; @@ -2785,7 +2725,7 @@ static int receive_SyncParam(struct drbd_conf *mdev, enum drbd_packets cmd, unsi if (packet_size > exp_max_sz) { dev_err(DEV, "SyncParam packet too long: received %u, expected <= %u bytes\n", packet_size, exp_max_sz); - return false; + return FALSE; } if (apv <= 88) { @@ -2805,7 +2745,7 @@ static int receive_SyncParam(struct drbd_conf *mdev, enum drbd_packets cmd, unsi memset(p->verify_alg, 0, 2 * SHARED_SECRET_MAX); if (drbd_recv(mdev, &p->head.payload, header_size) != header_size) - return false; + return FALSE; mdev->sync_conf.rate = be32_to_cpu(p->rate); @@ -2815,11 +2755,11 @@ static int receive_SyncParam(struct drbd_conf *mdev, enum drbd_packets cmd, unsi dev_err(DEV, "verify-alg too long, " "peer wants %u, accepting only %u byte\n", data_size, SHARED_SECRET_MAX); - return false; + return FALSE; } if (drbd_recv(mdev, p->verify_alg, data_size) != data_size) - return false; + return FALSE; /* we expect NUL terminated string */ /* but just in case someone tries to be evil */ @@ -2913,7 +2853,7 @@ static int receive_SyncParam(struct drbd_conf *mdev, enum drbd_packets cmd, unsi /* but free the verify_tfm again, if csums_tfm did not work out */ crypto_free_hash(verify_tfm); drbd_force_state(mdev, NS(conn, C_DISCONNECTING)); - return false; + return FALSE; } static void drbd_setup_order_type(struct drbd_conf *mdev, int peer) @@ -2939,7 +2879,7 @@ static int receive_sizes(struct drbd_conf *mdev, enum drbd_packets cmd, unsigned { struct p_sizes *p = &mdev->data.rbuf.sizes; enum determine_dev_size dd = unchanged; - unsigned int max_bio_size; + unsigned int max_seg_s; sector_t p_size, p_usize, my_usize; int ldsc = 0; /* local disk size changed */ enum dds_flags ddsf; @@ -2950,7 +2890,7 @@ static int receive_sizes(struct drbd_conf *mdev, enum drbd_packets cmd, unsigned if (p_size == 0 && mdev->state.disk == D_DISKLESS) { dev_err(DEV, "some backing storage is needed\n"); drbd_force_state(mdev, NS(conn, C_DISCONNECTING)); - return false; + return FALSE; } /* just store the peer's disk size for now. @@ -2987,17 +2927,18 @@ static int receive_sizes(struct drbd_conf *mdev, enum drbd_packets cmd, unsigned drbd_force_state(mdev, NS(conn, C_DISCONNECTING)); mdev->ldev->dc.disk_size = my_usize; put_ldev(mdev); - return false; + return FALSE; } put_ldev(mdev); } +#undef min_not_zero ddsf = be16_to_cpu(p->dds_flags); if (get_ldev(mdev)) { dd = drbd_determin_dev_size(mdev, ddsf); put_ldev(mdev); if (dd == dev_size_error) - return false; + return FALSE; drbd_md_sync(mdev); } else { /* I am diskless, need to accept the peer's size. */ @@ -3011,14 +2952,14 @@ static int receive_sizes(struct drbd_conf *mdev, enum drbd_packets cmd, unsigned } if (mdev->agreed_pro_version < 94) - max_bio_size = be32_to_cpu(p->max_bio_size); + max_seg_s = be32_to_cpu(p->max_segment_size); else if (mdev->agreed_pro_version == 94) - max_bio_size = DRBD_MAX_SIZE_H80_PACKET; + max_seg_s = DRBD_MAX_SIZE_H80_PACKET; else /* drbd 8.3.8 onwards */ - max_bio_size = DRBD_MAX_BIO_SIZE; + max_seg_s = DRBD_MAX_SEGMENT_SIZE; - if (max_bio_size != queue_max_hw_sectors(mdev->rq_queue) << 9) - drbd_setup_queue_param(mdev, max_bio_size); + if (max_seg_s != queue_max_segment_size(mdev->rq_queue)) + drbd_setup_queue_param(mdev, max_seg_s); drbd_setup_order_type(mdev, be16_to_cpu(p->queue_order_type)); put_ldev(mdev); @@ -3044,14 +2985,14 @@ static int receive_sizes(struct drbd_conf *mdev, enum drbd_packets cmd, unsigned } } - return true; + return TRUE; } static int receive_uuids(struct drbd_conf *mdev, enum drbd_packets cmd, unsigned int data_size) { struct p_uuids *p = &mdev->data.rbuf.uuids; u64 *p_uuid; - int i, updated_uuids = 0; + int i; p_uuid = kmalloc(sizeof(u64)*UI_EXTENDED_SIZE, GFP_NOIO); @@ -3068,7 +3009,7 @@ static int receive_uuids(struct drbd_conf *mdev, enum drbd_packets cmd, unsigned dev_err(DEV, "Can only connect to data with current UUID=%016llX\n", (unsigned long long)mdev->ed_uuid); drbd_force_state(mdev, NS(conn, C_DISCONNECTING)); - return false; + return FALSE; } if (get_ldev(mdev)) { @@ -3080,21 +3021,19 @@ static int receive_uuids(struct drbd_conf *mdev, enum drbd_packets cmd, unsigned if (skip_initial_sync) { dev_info(DEV, "Accepted new current UUID, preparing to skip initial sync\n"); drbd_bitmap_io(mdev, &drbd_bmio_clear_n_write, - "clear_n_write from receive_uuids", - BM_LOCKED_TEST_ALLOWED); + "clear_n_write from receive_uuids"); _drbd_uuid_set(mdev, UI_CURRENT, p_uuid[UI_CURRENT]); _drbd_uuid_set(mdev, UI_BITMAP, 0); _drbd_set_state(_NS2(mdev, disk, D_UP_TO_DATE, pdsk, D_UP_TO_DATE), CS_VERBOSE, NULL); drbd_md_sync(mdev); - updated_uuids = 1; } put_ldev(mdev); } else if (mdev->state.disk < D_INCONSISTENT && mdev->state.role == R_PRIMARY) { /* I am a diskless primary, the peer just created a new current UUID for me. */ - updated_uuids = drbd_set_ed_uuid(mdev, p_uuid[UI_CURRENT]); + drbd_set_ed_uuid(mdev, p_uuid[UI_CURRENT]); } /* Before we test for the disk state, we should wait until an eventually @@ -3103,12 +3042,9 @@ static int receive_uuids(struct drbd_conf *mdev, enum drbd_packets cmd, unsigned new disk state... */ wait_event(mdev->misc_wait, !test_bit(CLUSTER_ST_CHANGE, &mdev->flags)); if (mdev->state.conn >= C_CONNECTED && mdev->state.disk < D_INCONSISTENT) - updated_uuids |= drbd_set_ed_uuid(mdev, p_uuid[UI_CURRENT]); + drbd_set_ed_uuid(mdev, p_uuid[UI_CURRENT]); - if (updated_uuids) - drbd_print_uuids(mdev, "receiver updated UUIDs to"); - - return true; + return TRUE; } /** @@ -3145,7 +3081,7 @@ static int receive_req_state(struct drbd_conf *mdev, enum drbd_packets cmd, unsi { struct p_req_state *p = &mdev->data.rbuf.req_state; union drbd_state mask, val; - enum drbd_state_rv rv; + int rv; mask.i = be32_to_cpu(p->mask); val.i = be32_to_cpu(p->val); @@ -3153,7 +3089,7 @@ static int receive_req_state(struct drbd_conf *mdev, enum drbd_packets cmd, unsi if (test_bit(DISCARD_CONCURRENT, &mdev->flags) && test_bit(CLUSTER_ST_CHANGE, &mdev->flags)) { drbd_send_sr_reply(mdev, SS_CONCURRENT_ST_CHG); - return true; + return TRUE; } mask = convert_state(mask); @@ -3164,7 +3100,7 @@ static int receive_req_state(struct drbd_conf *mdev, enum drbd_packets cmd, unsi drbd_send_sr_reply(mdev, rv); drbd_md_sync(mdev); - return true; + return TRUE; } static int receive_state(struct drbd_conf *mdev, enum drbd_packets cmd, unsigned int data_size) @@ -3209,7 +3145,7 @@ static int receive_state(struct drbd_conf *mdev, enum drbd_packets cmd, unsigned peer_state.conn == C_CONNECTED) { if (drbd_bm_total_weight(mdev) <= mdev->rs_failed) drbd_resync_finished(mdev); - return true; + return TRUE; } } @@ -3225,9 +3161,6 @@ static int receive_state(struct drbd_conf *mdev, enum drbd_packets cmd, unsigned if (ns.conn == C_WF_REPORT_PARAMS) ns.conn = C_CONNECTED; - if (peer_state.conn == C_AHEAD) - ns.conn = C_BEHIND; - if (mdev->p_uuid && peer_state.disk >= D_NEGOTIATING && get_ldev_if_state(mdev, D_NEGOTIATING)) { int cr; /* consider resync */ @@ -3262,10 +3195,10 @@ static int receive_state(struct drbd_conf *mdev, enum drbd_packets cmd, unsigned real_peer_disk = D_DISKLESS; } else { if (test_and_clear_bit(CONN_DRY_RUN, &mdev->flags)) - return false; + return FALSE; D_ASSERT(os.conn == C_WF_REPORT_PARAMS); drbd_force_state(mdev, NS(conn, C_DISCONNECTING)); - return false; + return FALSE; } } } @@ -3290,7 +3223,7 @@ static int receive_state(struct drbd_conf *mdev, enum drbd_packets cmd, unsigned drbd_uuid_new_current(mdev); clear_bit(NEW_CUR_UUID, &mdev->flags); drbd_force_state(mdev, NS2(conn, C_PROTOCOL_ERROR, susp, 0)); - return false; + return FALSE; } rv = _drbd_set_state(mdev, ns, cs_flags, NULL); ns = mdev->state; @@ -3298,7 +3231,7 @@ static int receive_state(struct drbd_conf *mdev, enum drbd_packets cmd, unsigned if (rv < SS_SUCCESS) { drbd_force_state(mdev, NS(conn, C_DISCONNECTING)); - return false; + return FALSE; } if (os.conn > C_WF_REPORT_PARAMS) { @@ -3316,7 +3249,7 @@ static int receive_state(struct drbd_conf *mdev, enum drbd_packets cmd, unsigned drbd_md_sync(mdev); /* update connected indicator, la_size, ... */ - return true; + return TRUE; } static int receive_sync_uuid(struct drbd_conf *mdev, enum drbd_packets cmd, unsigned int data_size) @@ -3325,7 +3258,6 @@ static int receive_sync_uuid(struct drbd_conf *mdev, enum drbd_packets cmd, unsi wait_event(mdev->misc_wait, mdev->state.conn == C_WF_SYNC_UUID || - mdev->state.conn == C_BEHIND || mdev->state.conn < C_CONNECTED || mdev->state.disk < D_NEGOTIATING); @@ -3337,42 +3269,32 @@ static int receive_sync_uuid(struct drbd_conf *mdev, enum drbd_packets cmd, unsi _drbd_uuid_set(mdev, UI_CURRENT, be64_to_cpu(p->uuid)); _drbd_uuid_set(mdev, UI_BITMAP, 0UL); - drbd_print_uuids(mdev, "updated sync uuid"); drbd_start_resync(mdev, C_SYNC_TARGET); put_ldev(mdev); } else dev_err(DEV, "Ignoring SyncUUID packet!\n"); - return true; + return TRUE; } -/** - * receive_bitmap_plain - * - * Return 0 when done, 1 when another iteration is needed, and a negative error - * code upon failure. - */ -static int +enum receive_bitmap_ret { OK, DONE, FAILED }; + +static enum receive_bitmap_ret receive_bitmap_plain(struct drbd_conf *mdev, unsigned int data_size, unsigned long *buffer, struct bm_xfer_ctx *c) { unsigned num_words = min_t(size_t, BM_PACKET_WORDS, c->bm_words - c->word_offset); unsigned want = num_words * sizeof(long); - int err; if (want != data_size) { dev_err(DEV, "%s:want (%u) != data_size (%u)\n", __func__, want, data_size); - return -EIO; + return FAILED; } if (want == 0) - return 0; - err = drbd_recv(mdev, buffer, want); - if (err != want) { - if (err >= 0) - err = -EIO; - return err; - } + return DONE; + if (drbd_recv(mdev, buffer, want) != want) + return FAILED; drbd_bm_merge_lel(mdev, c->word_offset, num_words, buffer); @@ -3381,16 +3303,10 @@ receive_bitmap_plain(struct drbd_conf *mdev, unsigned int data_size, if (c->bit_offset > c->bm_bits) c->bit_offset = c->bm_bits; - return 1; + return OK; } -/** - * recv_bm_rle_bits - * - * Return 0 when done, 1 when another iteration is needed, and a negative error - * code upon failure. - */ -static int +static enum receive_bitmap_ret recv_bm_rle_bits(struct drbd_conf *mdev, struct p_compressed_bm *p, struct bm_xfer_ctx *c) @@ -3410,18 +3326,18 @@ recv_bm_rle_bits(struct drbd_conf *mdev, bits = bitstream_get_bits(&bs, &look_ahead, 64); if (bits < 0) - return -EIO; + return FAILED; for (have = bits; have > 0; s += rl, toggle = !toggle) { bits = vli_decode_bits(&rl, look_ahead); if (bits <= 0) - return -EIO; + return FAILED; if (toggle) { e = s + rl -1; if (e >= c->bm_bits) { dev_err(DEV, "bitmap overflow (e:%lu) while decoding bm RLE packet\n", e); - return -EIO; + return FAILED; } _drbd_bm_set_bits(mdev, s, e); } @@ -3431,14 +3347,14 @@ recv_bm_rle_bits(struct drbd_conf *mdev, have, bits, look_ahead, (unsigned int)(bs.cur.b - p->code), (unsigned int)bs.buf_len); - return -EIO; + return FAILED; } look_ahead >>= bits; have -= bits; bits = bitstream_get_bits(&bs, &tmp, 64 - have); if (bits < 0) - return -EIO; + return FAILED; look_ahead |= tmp << have; have += bits; } @@ -3446,16 +3362,10 @@ recv_bm_rle_bits(struct drbd_conf *mdev, c->bit_offset = s; bm_xfer_ctx_bit_to_word_offset(c); - return (s != c->bm_bits); + return (s == c->bm_bits) ? DONE : OK; } -/** - * decode_bitmap_c - * - * Return 0 when done, 1 when another iteration is needed, and a negative error - * code upon failure. - */ -static int +static enum receive_bitmap_ret decode_bitmap_c(struct drbd_conf *mdev, struct p_compressed_bm *p, struct bm_xfer_ctx *c) @@ -3469,7 +3379,7 @@ decode_bitmap_c(struct drbd_conf *mdev, dev_err(DEV, "receive_bitmap_c: unknown encoding %u\n", p->encoding); drbd_force_state(mdev, NS(conn, C_PROTOCOL_ERROR)); - return -EIO; + return FAILED; } void INFO_bm_xfer_stats(struct drbd_conf *mdev, @@ -3518,13 +3428,13 @@ static int receive_bitmap(struct drbd_conf *mdev, enum drbd_packets cmd, unsigne { struct bm_xfer_ctx c; void *buffer; - int err; - int ok = false; + enum receive_bitmap_ret ret; + int ok = FALSE; struct p_header80 *h = &mdev->data.rbuf.header.h80; - drbd_bm_lock(mdev, "receive bitmap", BM_LOCKED_SET_ALLOWED); - /* you are supposed to send additional out-of-sync information - * if you actually set bits during this phase */ + wait_event(mdev->misc_wait, !atomic_read(&mdev->ap_bio_cnt)); + + drbd_bm_lock(mdev, "receive bitmap"); /* maybe we should use some per thread scratch page, * and allocate that during initial device creation? */ @@ -3539,9 +3449,9 @@ static int receive_bitmap(struct drbd_conf *mdev, enum drbd_packets cmd, unsigne .bm_words = drbd_bm_words(mdev), }; - for(;;) { + do { if (cmd == P_BITMAP) { - err = receive_bitmap_plain(mdev, data_size, buffer, &c); + ret = receive_bitmap_plain(mdev, data_size, buffer, &c); } else if (cmd == P_COMPRESSED_BITMAP) { /* MAYBE: sanity check that we speak proto >= 90, * and the feature is enabled! */ @@ -3558,9 +3468,9 @@ static int receive_bitmap(struct drbd_conf *mdev, enum drbd_packets cmd, unsigne goto out; if (data_size <= (sizeof(*p) - sizeof(p->head))) { dev_err(DEV, "ReportCBitmap packet too small (l:%u)\n", data_size); - goto out; + return FAILED; } - err = decode_bitmap_c(mdev, p, &c); + ret = decode_bitmap_c(mdev, p, &c); } else { dev_warn(DEV, "receive_bitmap: cmd neither ReportBitMap nor ReportCBitMap (is 0x%x)", cmd); goto out; @@ -3569,26 +3479,24 @@ static int receive_bitmap(struct drbd_conf *mdev, enum drbd_packets cmd, unsigne c.packets[cmd == P_BITMAP]++; c.bytes[cmd == P_BITMAP] += sizeof(struct p_header80) + data_size; - if (err <= 0) { - if (err < 0) - goto out; + if (ret != OK) break; - } + if (!drbd_recv_header(mdev, &cmd, &data_size)) goto out; - } + } while (ret == OK); + if (ret == FAILED) + goto out; INFO_bm_xfer_stats(mdev, "receive", &c); if (mdev->state.conn == C_WF_BITMAP_T) { - enum drbd_state_rv rv; - ok = !drbd_send_bitmap(mdev); if (!ok) goto out; /* Omit CS_ORDERED with this state transition to avoid deadlocks. */ - rv = _drbd_request_state(mdev, NS(conn, C_WF_SYNC_UUID), CS_VERBOSE); - D_ASSERT(rv == SS_SUCCESS); + ok = _drbd_request_state(mdev, NS(conn, C_WF_SYNC_UUID), CS_VERBOSE); + D_ASSERT(ok == SS_SUCCESS); } else if (mdev->state.conn != C_WF_BITMAP_S) { /* admin may have requested C_DISCONNECTING, * other threads may have noticed network errors */ @@ -3596,7 +3504,7 @@ static int receive_bitmap(struct drbd_conf *mdev, enum drbd_packets cmd, unsigne drbd_conn_str(mdev->state.conn)); } - ok = true; + ok = TRUE; out: drbd_bm_unlock(mdev); if (ok && mdev->state.conn == C_WF_BITMAP_S) @@ -3630,26 +3538,7 @@ static int receive_UnplugRemote(struct drbd_conf *mdev, enum drbd_packets cmd, u * with the data requests being unplugged */ drbd_tcp_quickack(mdev->data.socket); - return true; -} - -static int receive_out_of_sync(struct drbd_conf *mdev, enum drbd_packets cmd, unsigned int data_size) -{ - struct p_block_desc *p = &mdev->data.rbuf.block_desc; - - switch (mdev->state.conn) { - case C_WF_SYNC_UUID: - case C_WF_BITMAP_T: - case C_BEHIND: - break; - default: - dev_err(DEV, "ASSERT FAILED cstate = %s, expected: WFSyncUUID|WFBitMapT|Behind\n", - drbd_conn_str(mdev->state.conn)); - } - - drbd_set_out_of_sync(mdev, be64_to_cpu(p->sector), be32_to_cpu(p->blksize)); - - return true; + return TRUE; } typedef int (*drbd_cmd_handler_f)(struct drbd_conf *, enum drbd_packets cmd, unsigned int to_receive); @@ -3682,7 +3571,6 @@ static struct data_cmd drbd_cmd_handler[] = { [P_OV_REPLY] = { 1, sizeof(struct p_block_req), receive_DataRequest }, [P_CSUM_RS_REQUEST] = { 1, sizeof(struct p_block_req), receive_DataRequest }, [P_DELAY_PROBE] = { 0, sizeof(struct p_delay_probe93), receive_skip }, - [P_OUT_OF_SYNC] = { 0, sizeof(struct p_block_desc), receive_out_of_sync }, /* anything missing from this table is in * the asender_tbl, see get_asender_cmd */ [P_MAX_CMD] = { 0, 0, NULL }, @@ -3722,8 +3610,7 @@ static void drbdd(struct drbd_conf *mdev) if (shs) { rv = drbd_recv(mdev, &header->h80.payload, shs); if (unlikely(rv != shs)) { - if (!signal_pending(current)) - dev_warn(DEV, "short read while reading sub header: rv=%d\n", rv); + dev_err(DEV, "short read while reading sub header: rv=%d\n", rv); goto err_out; } } @@ -3795,6 +3682,9 @@ static void drbd_disconnect(struct drbd_conf *mdev) if (mdev->state.conn == C_STANDALONE) return; + if (mdev->state.conn >= C_WF_CONNECTION) + dev_err(DEV, "ASSERT FAILED cstate = %s, expected < WFConnection\n", + drbd_conn_str(mdev->state.conn)); /* asender does not clean up anything. it must not interfere, either */ drbd_thread_stop(&mdev->asender); @@ -3823,8 +3713,6 @@ static void drbd_disconnect(struct drbd_conf *mdev) atomic_set(&mdev->rs_pending_cnt, 0); wake_up(&mdev->misc_wait); - del_timer(&mdev->request_timer); - /* make sure syncer is stopped and w_resume_next_sg queued */ del_timer_sync(&mdev->resync_timer); resync_timer_fn((unsigned long)mdev); @@ -3870,6 +3758,13 @@ static void drbd_disconnect(struct drbd_conf *mdev) if (os.conn == C_DISCONNECTING) { wait_event(mdev->net_cnt_wait, atomic_read(&mdev->net_cnt) == 0); + if (!is_susp(mdev->state)) { + /* we must not free the tl_hash + * while application io is still on the fly */ + wait_event(mdev->misc_wait, !atomic_read(&mdev->ap_bio_cnt)); + drbd_free_tl_hash(mdev); + } + crypto_free_hash(mdev->cram_hmac_tfm); mdev->cram_hmac_tfm = NULL; @@ -3878,10 +3773,6 @@ static void drbd_disconnect(struct drbd_conf *mdev) drbd_request_state(mdev, NS(conn, C_STANDALONE)); } - /* serialize with bitmap writeout triggered by the state change, - * if any. */ - wait_event(mdev->misc_wait, !test_bit(BITMAP_IO, &mdev->flags)); - /* tcp_close and release of sendpage pages can be deferred. I don't * want to use SO_LINGER, because apparently it can be deferred for * more than 20 seconds (longest time I checked). @@ -3982,8 +3873,7 @@ static int drbd_do_handshake(struct drbd_conf *mdev) rv = drbd_recv(mdev, &p->head.payload, expect); if (rv != expect) { - if (!signal_pending(current)) - dev_warn(DEV, "short read receiving handshake packet: l=%u\n", rv); + dev_err(DEV, "short read receiving handshake packet: l=%u\n", rv); return 0; } @@ -4085,8 +3975,7 @@ static int drbd_do_auth(struct drbd_conf *mdev) rv = drbd_recv(mdev, peers_ch, length); if (rv != length) { - if (!signal_pending(current)) - dev_warn(DEV, "short read AuthChallenge: l=%u\n", rv); + dev_err(DEV, "short read AuthChallenge: l=%u\n", rv); rv = 0; goto fail; } @@ -4133,8 +4022,7 @@ static int drbd_do_auth(struct drbd_conf *mdev) rv = drbd_recv(mdev, response , resp_size); if (rv != resp_size) { - if (!signal_pending(current)) - dev_warn(DEV, "short read receiving AuthResponse: l=%u\n", rv); + dev_err(DEV, "short read receiving AuthResponse: l=%u\n", rv); rv = 0; goto fail; } @@ -4186,7 +4074,8 @@ int drbdd_init(struct drbd_thread *thi) h = drbd_connect(mdev); if (h == 0) { drbd_disconnect(mdev); - schedule_timeout_interruptible(HZ); + __set_current_state(TASK_INTERRUPTIBLE); + schedule_timeout(HZ); } if (h == -1) { dev_warn(DEV, "Discarding network configuration.\n"); @@ -4224,7 +4113,7 @@ static int got_RqSReply(struct drbd_conf *mdev, struct p_header80 *h) } wake_up(&mdev->state_wait); - return true; + return TRUE; } static int got_Ping(struct drbd_conf *mdev, struct p_header80 *h) @@ -4240,7 +4129,7 @@ static int got_PingAck(struct drbd_conf *mdev, struct p_header80 *h) if (!test_and_set_bit(GOT_PING_ACK, &mdev->flags)) wake_up(&mdev->misc_wait); - return true; + return TRUE; } static int got_IsInSync(struct drbd_conf *mdev, struct p_header80 *h) @@ -4263,7 +4152,7 @@ static int got_IsInSync(struct drbd_conf *mdev, struct p_header80 *h) dec_rs_pending(mdev); atomic_add(blksize >> 9, &mdev->rs_sect_in); - return true; + return TRUE; } /* when we receive the ACK for a write request, @@ -4287,6 +4176,8 @@ static struct drbd_request *_ack_id_to_req(struct drbd_conf *mdev, return req; } } + dev_err(DEV, "_ack_id_to_req: failed to find req %p, sector %llus in list\n", + (void *)(unsigned long)id, (unsigned long long)sector); return NULL; } @@ -4304,17 +4195,15 @@ static int validate_req_change_req_state(struct drbd_conf *mdev, req = validator(mdev, id, sector); if (unlikely(!req)) { spin_unlock_irq(&mdev->req_lock); - - dev_err(DEV, "%s: failed to find req %p, sector %llus\n", func, - (void *)(unsigned long)id, (unsigned long long)sector); - return false; + dev_err(DEV, "%s: got a corrupt block_id/sector pair\n", func); + return FALSE; } __req_mod(req, what, &m); spin_unlock_irq(&mdev->req_lock); if (m.bio) complete_master_bio(mdev, &m); - return true; + return TRUE; } static int got_BlockAck(struct drbd_conf *mdev, struct p_header80 *h) @@ -4329,7 +4218,7 @@ static int got_BlockAck(struct drbd_conf *mdev, struct p_header80 *h) if (is_syncer_block_id(p->block_id)) { drbd_set_in_sync(mdev, sector, blksize); dec_rs_pending(mdev); - return true; + return TRUE; } switch (be16_to_cpu(h->command)) { case P_RS_WRITE_ACK: @@ -4350,7 +4239,7 @@ static int got_BlockAck(struct drbd_conf *mdev, struct p_header80 *h) break; default: D_ASSERT(0); - return false; + return FALSE; } return validate_req_change_req_state(mdev, p->block_id, sector, @@ -4361,44 +4250,20 @@ static int got_NegAck(struct drbd_conf *mdev, struct p_header80 *h) { struct p_block_ack *p = (struct p_block_ack *)h; sector_t sector = be64_to_cpu(p->sector); - int size = be32_to_cpu(p->blksize); - struct drbd_request *req; - struct bio_and_error m; + + if (__ratelimit(&drbd_ratelimit_state)) + dev_warn(DEV, "Got NegAck packet. Peer is in troubles?\n"); update_peer_seq(mdev, be32_to_cpu(p->seq_num)); if (is_syncer_block_id(p->block_id)) { + int size = be32_to_cpu(p->blksize); dec_rs_pending(mdev); drbd_rs_failed_io(mdev, sector, size); - return true; + return TRUE; } - - spin_lock_irq(&mdev->req_lock); - req = _ack_id_to_req(mdev, p->block_id, sector); - if (!req) { - spin_unlock_irq(&mdev->req_lock); - if (mdev->net_conf->wire_protocol == DRBD_PROT_A || - mdev->net_conf->wire_protocol == DRBD_PROT_B) { - /* Protocol A has no P_WRITE_ACKs, but has P_NEG_ACKs. - The master bio might already be completed, therefore the - request is no longer in the collision hash. - => Do not try to validate block_id as request. */ - /* In Protocol B we might already have got a P_RECV_ACK - but then get a P_NEG_ACK after wards. */ - drbd_set_out_of_sync(mdev, sector, size); - return true; - } else { - dev_err(DEV, "%s: failed to find req %p, sector %llus\n", __func__, - (void *)(unsigned long)p->block_id, (unsigned long long)sector); - return false; - } - } - __req_mod(req, neg_acked, &m); - spin_unlock_irq(&mdev->req_lock); - - if (m.bio) - complete_master_bio(mdev, &m); - return true; + return validate_req_change_req_state(mdev, p->block_id, sector, + _ack_id_to_req, __func__ , neg_acked); } static int got_NegDReply(struct drbd_conf *mdev, struct p_header80 *h) @@ -4429,20 +4294,11 @@ static int got_NegRSDReply(struct drbd_conf *mdev, struct p_header80 *h) if (get_ldev_if_state(mdev, D_FAILED)) { drbd_rs_complete_io(mdev, sector); - switch (be16_to_cpu(h->command)) { - case P_NEG_RS_DREPLY: - drbd_rs_failed_io(mdev, sector, size); - case P_RS_CANCEL: - break; - default: - D_ASSERT(0); - put_ldev(mdev); - return false; - } + drbd_rs_failed_io(mdev, sector, size); put_ldev(mdev); } - return true; + return TRUE; } static int got_BarrierAck(struct drbd_conf *mdev, struct p_header80 *h) @@ -4451,14 +4307,7 @@ static int got_BarrierAck(struct drbd_conf *mdev, struct p_header80 *h) tl_release(mdev, p->barrier, be32_to_cpu(p->set_size)); - if (mdev->state.conn == C_AHEAD && - atomic_read(&mdev->ap_in_flight) == 0 && - !test_and_set_bit(AHEAD_TO_SYNC_SOURCE, &mdev->current_epoch->flags)) { - mdev->start_resync_timer.expires = jiffies + HZ; - add_timer(&mdev->start_resync_timer); - } - - return true; + return TRUE; } static int got_OVResult(struct drbd_conf *mdev, struct p_header80 *h) @@ -4479,18 +4328,12 @@ static int got_OVResult(struct drbd_conf *mdev, struct p_header80 *h) ov_oos_print(mdev); if (!get_ldev(mdev)) - return true; + return TRUE; drbd_rs_complete_io(mdev, sector); dec_rs_pending(mdev); - --mdev->ov_left; - - /* let's advance progress step marks only for every other megabyte */ - if ((mdev->ov_left & 0x200) == 0x200) - drbd_advance_rs_marks(mdev, mdev->ov_left); - - if (mdev->ov_left == 0) { + if (--mdev->ov_left == 0) { w = kmalloc(sizeof(*w), GFP_NOIO); if (w) { w->cb = w_ov_finished; @@ -4502,12 +4345,12 @@ static int got_OVResult(struct drbd_conf *mdev, struct p_header80 *h) } } put_ldev(mdev); - return true; + return TRUE; } static int got_skip(struct drbd_conf *mdev, struct p_header80 *h) { - return true; + return TRUE; } struct asender_cmd { @@ -4535,7 +4378,6 @@ static struct asender_cmd *get_asender_cmd(int cmd) [P_STATE_CHG_REPLY] = { sizeof(struct p_req_state_reply), got_RqSReply }, [P_RS_IS_IN_SYNC] = { sizeof(struct p_block_ack), got_IsInSync }, [P_DELAY_PROBE] = { sizeof(struct p_delay_probe93), got_skip }, - [P_RS_CANCEL] = { sizeof(struct p_block_ack), got_NegRSDReply}, [P_MAX_CMD] = { 0, NULL }, }; if (cmd > P_MAX_CMD || asender_tbl[cmd].process == NULL) diff --git a/trunk/drivers/block/drbd/drbd_req.c b/trunk/drivers/block/drbd/drbd_req.c index 5c0c8be1bb0a..ad3fc6228f27 100644 --- a/trunk/drivers/block/drbd/drbd_req.c +++ b/trunk/drivers/block/drbd/drbd_req.c @@ -140,14 +140,9 @@ static void _about_to_complete_local_write(struct drbd_conf *mdev, struct hlist_node *n; struct hlist_head *slot; - /* Before we can signal completion to the upper layers, - * we may need to close the current epoch. - * We can skip this, if this request has not even been sent, because we - * did not have a fully established connection yet/anymore, during - * bitmap exchange, or while we are C_AHEAD due to congestion policy. - */ + /* before we can signal completion to the upper layers, + * we may need to close the current epoch */ if (mdev->state.conn >= C_CONNECTED && - (s & RQ_NET_SENT) != 0 && req->epoch == mdev->newest_tle->br_number) queue_barrier(mdev); @@ -445,7 +440,7 @@ int __req_mod(struct drbd_request *req, enum drbd_req_event what, req->rq_state |= RQ_LOCAL_COMPLETED; req->rq_state &= ~RQ_LOCAL_PENDING; - __drbd_chk_io_error(mdev, false); + __drbd_chk_io_error(mdev, FALSE); _req_may_be_done_not_susp(req, m); put_ldev(mdev); break; @@ -466,7 +461,7 @@ int __req_mod(struct drbd_request *req, enum drbd_req_event what, D_ASSERT(!(req->rq_state & RQ_NET_MASK)); - __drbd_chk_io_error(mdev, false); + __drbd_chk_io_error(mdev, FALSE); put_ldev(mdev); /* no point in retrying if there is no good remote data, @@ -550,14 +545,6 @@ int __req_mod(struct drbd_request *req, enum drbd_req_event what, break; - case queue_for_send_oos: - req->rq_state |= RQ_NET_QUEUED; - req->w.cb = w_send_oos; - drbd_queue_work(&mdev->data.work, &req->w); - break; - - case oos_handed_to_network: - /* actually the same */ case send_canceled: /* treat it the same */ case send_failed: @@ -571,9 +558,6 @@ int __req_mod(struct drbd_request *req, enum drbd_req_event what, case handed_over_to_network: /* assert something? */ - if (bio_data_dir(req->master_bio) == WRITE) - atomic_add(req->size>>9, &mdev->ap_in_flight); - if (bio_data_dir(req->master_bio) == WRITE && mdev->net_conf->wire_protocol == DRBD_PROT_A) { /* this is what is dangerous about protocol A: @@ -607,9 +591,6 @@ int __req_mod(struct drbd_request *req, enum drbd_req_event what, dec_ap_pending(mdev); req->rq_state &= ~(RQ_NET_OK|RQ_NET_PENDING); req->rq_state |= RQ_NET_DONE; - if (req->rq_state & RQ_NET_SENT && req->rq_state & RQ_WRITE) - atomic_sub(req->size>>9, &mdev->ap_in_flight); - /* if it is still queued, we may not complete it here. * it will be canceled soon. */ if (!(req->rq_state & RQ_NET_QUEUED)) @@ -647,17 +628,14 @@ int __req_mod(struct drbd_request *req, enum drbd_req_event what, req->rq_state |= RQ_NET_OK; D_ASSERT(req->rq_state & RQ_NET_PENDING); dec_ap_pending(mdev); - atomic_sub(req->size>>9, &mdev->ap_in_flight); req->rq_state &= ~RQ_NET_PENDING; _req_may_be_done_not_susp(req, m); break; case neg_acked: /* assert something? */ - if (req->rq_state & RQ_NET_PENDING) { + if (req->rq_state & RQ_NET_PENDING) dec_ap_pending(mdev); - atomic_sub(req->size>>9, &mdev->ap_in_flight); - } req->rq_state &= ~(RQ_NET_OK|RQ_NET_PENDING); req->rq_state |= RQ_NET_DONE; @@ -712,11 +690,8 @@ int __req_mod(struct drbd_request *req, enum drbd_req_event what, dev_err(DEV, "FIXME (barrier_acked but pending)\n"); list_move(&req->tl_requests, &mdev->out_of_sequence_requests); } - if ((req->rq_state & RQ_NET_MASK) != 0) { - req->rq_state |= RQ_NET_DONE; - if (mdev->net_conf->wire_protocol == DRBD_PROT_A) - atomic_sub(req->size>>9, &mdev->ap_in_flight); - } + D_ASSERT(req->rq_state & RQ_NET_SENT); + req->rq_state |= RQ_NET_DONE; _req_may_be_done(req, m); /* Allowed while state.susp */ break; @@ -763,14 +738,14 @@ static int drbd_may_do_local_read(struct drbd_conf *mdev, sector_t sector, int s return 0 == drbd_bm_count_bits(mdev, sbnr, ebnr); } -static int drbd_make_request_common(struct drbd_conf *mdev, struct bio *bio, unsigned long start_time) +static int drbd_make_request_common(struct drbd_conf *mdev, struct bio *bio) { const int rw = bio_rw(bio); const int size = bio->bi_size; const sector_t sector = bio->bi_sector; struct drbd_tl_epoch *b = NULL; struct drbd_request *req; - int local, remote, send_oos = 0; + int local, remote; int err = -EIO; int ret = 0; @@ -784,7 +759,6 @@ static int drbd_make_request_common(struct drbd_conf *mdev, struct bio *bio, uns bio_endio(bio, -ENOMEM); return 0; } - req->start_time = start_time; local = get_ldev(mdev); if (!local) { @@ -834,9 +808,9 @@ static int drbd_make_request_common(struct drbd_conf *mdev, struct bio *bio, uns drbd_al_begin_io(mdev, sector); } - remote = remote && drbd_should_do_remote(mdev->state); - send_oos = rw == WRITE && drbd_should_send_oos(mdev->state); - D_ASSERT(!(remote && send_oos)); + remote = remote && (mdev->state.pdsk == D_UP_TO_DATE || + (mdev->state.pdsk == D_INCONSISTENT && + mdev->state.conn >= C_CONNECTED)); if (!(local || remote) && !is_susp(mdev->state)) { if (__ratelimit(&drbd_ratelimit_state)) @@ -850,7 +824,7 @@ static int drbd_make_request_common(struct drbd_conf *mdev, struct bio *bio, uns * but there is a race between testing the bit and pointer outside the * spinlock, and grabbing the spinlock. * if we lost that race, we retry. */ - if (rw == WRITE && (remote || send_oos) && + if (rw == WRITE && remote && mdev->unused_spare_tle == NULL && test_bit(CREATE_BARRIER, &mdev->flags)) { allocate_barrier: @@ -868,19 +842,18 @@ static int drbd_make_request_common(struct drbd_conf *mdev, struct bio *bio, uns if (is_susp(mdev->state)) { /* If we got suspended, use the retry mechanism of generic_make_request() to restart processing of this - bio. In the next call to drbd_make_request + bio. In the next call to drbd_make_request_26 we sleep in inc_ap_bio() */ ret = 1; spin_unlock_irq(&mdev->req_lock); goto fail_free_complete; } - if (remote || send_oos) { - remote = drbd_should_do_remote(mdev->state); - send_oos = rw == WRITE && drbd_should_send_oos(mdev->state); - D_ASSERT(!(remote && send_oos)); - - if (!(remote || send_oos)) + if (remote) { + remote = (mdev->state.pdsk == D_UP_TO_DATE || + (mdev->state.pdsk == D_INCONSISTENT && + mdev->state.conn >= C_CONNECTED)); + if (!remote) dev_warn(DEV, "lost connection while grabbing the req_lock!\n"); if (!(local || remote)) { dev_err(DEV, "IO ERROR: neither local nor remote disk\n"); @@ -893,7 +866,7 @@ static int drbd_make_request_common(struct drbd_conf *mdev, struct bio *bio, uns mdev->unused_spare_tle = b; b = NULL; } - if (rw == WRITE && (remote || send_oos) && + if (rw == WRITE && remote && mdev->unused_spare_tle == NULL && test_bit(CREATE_BARRIER, &mdev->flags)) { /* someone closed the current epoch @@ -916,7 +889,7 @@ static int drbd_make_request_common(struct drbd_conf *mdev, struct bio *bio, uns * barrier packet. To get the write ordering right, we only have to * make sure that, if this is a write request and it triggered a * barrier packet, this request is queued within the same spinlock. */ - if ((remote || send_oos) && mdev->unused_spare_tle && + if (remote && mdev->unused_spare_tle && test_and_clear_bit(CREATE_BARRIER, &mdev->flags)) { _tl_add_barrier(mdev, mdev->unused_spare_tle); mdev->unused_spare_tle = NULL; @@ -964,34 +937,6 @@ static int drbd_make_request_common(struct drbd_conf *mdev, struct bio *bio, uns ? queue_for_net_write : queue_for_net_read); } - if (send_oos && drbd_set_out_of_sync(mdev, sector, size)) - _req_mod(req, queue_for_send_oos); - - if (remote && - mdev->net_conf->on_congestion != OC_BLOCK && mdev->agreed_pro_version >= 96) { - int congested = 0; - - if (mdev->net_conf->cong_fill && - atomic_read(&mdev->ap_in_flight) >= mdev->net_conf->cong_fill) { - dev_info(DEV, "Congestion-fill threshold reached\n"); - congested = 1; - } - - if (mdev->act_log->used >= mdev->net_conf->cong_extents) { - dev_info(DEV, "Congestion-extents threshold reached\n"); - congested = 1; - } - - if (congested) { - queue_barrier(mdev); /* last barrier, after mirrored writes */ - - if (mdev->net_conf->on_congestion == OC_PULL_AHEAD) - _drbd_set_state(_NS(mdev, conn, C_AHEAD), 0, NULL); - else /*mdev->net_conf->on_congestion == OC_DISCONNECT */ - _drbd_set_state(_NS(mdev, conn, C_DISCONNECTING), 0, NULL); - } - } - spin_unlock_irq(&mdev->req_lock); kfree(b); /* if someone else has beaten us to it... */ @@ -1004,9 +949,9 @@ static int drbd_make_request_common(struct drbd_conf *mdev, struct bio *bio, uns * stable storage, and this is a WRITE, we may not even submit * this bio. */ if (get_ldev(mdev)) { - if (drbd_insert_fault(mdev, rw == WRITE ? DRBD_FAULT_DT_WR - : rw == READ ? DRBD_FAULT_DT_RD - : DRBD_FAULT_DT_RA)) + if (FAULT_ACTIVE(mdev, rw == WRITE ? DRBD_FAULT_DT_WR + : rw == READ ? DRBD_FAULT_DT_RD + : DRBD_FAULT_DT_RA)) bio_endio(req->private_bio, -EIO); else generic_make_request(req->private_bio); @@ -1073,19 +1018,16 @@ static int drbd_fail_request_early(struct drbd_conf *mdev, int is_write) return 0; } -int drbd_make_request(struct request_queue *q, struct bio *bio) +int drbd_make_request_26(struct request_queue *q, struct bio *bio) { unsigned int s_enr, e_enr; struct drbd_conf *mdev = (struct drbd_conf *) q->queuedata; - unsigned long start_time; if (drbd_fail_request_early(mdev, bio_data_dir(bio) & WRITE)) { bio_endio(bio, -EPERM); return 0; } - start_time = jiffies; - /* * what we "blindly" assume: */ @@ -1100,12 +1042,12 @@ int drbd_make_request(struct request_queue *q, struct bio *bio) if (likely(s_enr == e_enr)) { inc_ap_bio(mdev, 1); - return drbd_make_request_common(mdev, bio, start_time); + return drbd_make_request_common(mdev, bio); } /* can this bio be split generically? * Maybe add our own split-arbitrary-bios function. */ - if (bio->bi_vcnt != 1 || bio->bi_idx != 0 || bio->bi_size > DRBD_MAX_BIO_SIZE) { + if (bio->bi_vcnt != 1 || bio->bi_idx != 0 || bio->bi_size > DRBD_MAX_SEGMENT_SIZE) { /* rather error out here than BUG in bio_split */ dev_err(DEV, "bio would need to, but cannot, be split: " "(vcnt=%u,idx=%u,size=%u,sector=%llu)\n", @@ -1127,7 +1069,11 @@ int drbd_make_request(struct request_queue *q, struct bio *bio) const int sps = 1 << HT_SHIFT; /* sectors per slot */ const int mask = sps - 1; const sector_t first_sectors = sps - (sect & mask); - bp = bio_split(bio, first_sectors); + bp = bio_split(bio, +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,28) + bio_split_pool, +#endif + first_sectors); /* we need to get a "reference count" (ap_bio_cnt) * to avoid races with the disconnect/reconnect/suspend code. @@ -1138,10 +1084,10 @@ int drbd_make_request(struct request_queue *q, struct bio *bio) D_ASSERT(e_enr == s_enr + 1); - while (drbd_make_request_common(mdev, &bp->bio1, start_time)) + while (drbd_make_request_common(mdev, &bp->bio1)) inc_ap_bio(mdev, 1); - while (drbd_make_request_common(mdev, &bp->bio2, start_time)) + while (drbd_make_request_common(mdev, &bp->bio2)) inc_ap_bio(mdev, 1); dec_ap_bio(mdev); @@ -1152,7 +1098,7 @@ int drbd_make_request(struct request_queue *q, struct bio *bio) } /* This is called by bio_add_page(). With this function we reduce - * the number of BIOs that span over multiple DRBD_MAX_BIO_SIZEs + * the number of BIOs that span over multiple DRBD_MAX_SEGMENT_SIZEs * units (was AL_EXTENTs). * * we do the calculation within the lower 32bit of the byte offsets, @@ -1162,7 +1108,7 @@ int drbd_make_request(struct request_queue *q, struct bio *bio) * As long as the BIO is empty we have to allow at least one bvec, * regardless of size and offset. so the resulting bio may still * cross extent boundaries. those are dealt with (bio_split) in - * drbd_make_request. + * drbd_make_request_26. */ int drbd_merge_bvec(struct request_queue *q, struct bvec_merge_data *bvm, struct bio_vec *bvec) { @@ -1172,8 +1118,8 @@ int drbd_merge_bvec(struct request_queue *q, struct bvec_merge_data *bvm, struct unsigned int bio_size = bvm->bi_size; int limit, backing_limit; - limit = DRBD_MAX_BIO_SIZE - - ((bio_offset & (DRBD_MAX_BIO_SIZE-1)) + bio_size); + limit = DRBD_MAX_SEGMENT_SIZE + - ((bio_offset & (DRBD_MAX_SEGMENT_SIZE-1)) + bio_size); if (limit < 0) limit = 0; if (bio_size == 0) { @@ -1190,42 +1136,3 @@ int drbd_merge_bvec(struct request_queue *q, struct bvec_merge_data *bvm, struct } return limit; } - -void request_timer_fn(unsigned long data) -{ - struct drbd_conf *mdev = (struct drbd_conf *) data; - struct drbd_request *req; /* oldest request */ - struct list_head *le; - unsigned long et = 0; /* effective timeout = ko_count * timeout */ - - if (get_net_conf(mdev)) { - et = mdev->net_conf->timeout*HZ/10 * mdev->net_conf->ko_count; - put_net_conf(mdev); - } - if (!et || mdev->state.conn < C_WF_REPORT_PARAMS) - return; /* Recurring timer stopped */ - - spin_lock_irq(&mdev->req_lock); - le = &mdev->oldest_tle->requests; - if (list_empty(le)) { - spin_unlock_irq(&mdev->req_lock); - mod_timer(&mdev->request_timer, jiffies + et); - return; - } - - le = le->prev; - req = list_entry(le, struct drbd_request, tl_requests); - if (time_is_before_eq_jiffies(req->start_time + et)) { - if (req->rq_state & RQ_NET_PENDING) { - dev_warn(DEV, "Remote failed to finish a request within ko-count * timeout\n"); - _drbd_set_state(_NS(mdev, conn, C_TIMEOUT), CS_VERBOSE, NULL); - } else { - dev_warn(DEV, "Local backing block device frozen?\n"); - mod_timer(&mdev->request_timer, jiffies + et); - } - } else { - mod_timer(&mdev->request_timer, req->start_time + et); - } - - spin_unlock_irq(&mdev->req_lock); -} diff --git a/trunk/drivers/block/drbd/drbd_req.h b/trunk/drivers/block/drbd/drbd_req.h index 32e2c3e6a813..ab2bd09d54b4 100644 --- a/trunk/drivers/block/drbd/drbd_req.h +++ b/trunk/drivers/block/drbd/drbd_req.h @@ -82,16 +82,14 @@ enum drbd_req_event { to_be_submitted, /* XXX yes, now I am inconsistent... - * these are not "events" but "actions" + * these two are not "events" but "actions" * oh, well... */ queue_for_net_write, queue_for_net_read, - queue_for_send_oos, send_canceled, send_failed, handed_over_to_network, - oos_handed_to_network, connection_lost_while_pending, read_retry_remote_canceled, recv_acked_by_peer, @@ -291,6 +289,7 @@ static inline struct drbd_request *drbd_req_new(struct drbd_conf *mdev, req->epoch = 0; req->sector = bio_src->bi_sector; req->size = bio_src->bi_size; + req->start_time = jiffies; INIT_HLIST_NODE(&req->colision); INIT_LIST_HEAD(&req->tl_requests); INIT_LIST_HEAD(&req->w.list); @@ -322,7 +321,6 @@ extern int __req_mod(struct drbd_request *req, enum drbd_req_event what, struct bio_and_error *m); extern void complete_master_bio(struct drbd_conf *mdev, struct bio_and_error *m); -extern void request_timer_fn(unsigned long data); /* use this if you don't want to deal with calling complete_master_bio() * outside the spinlock, e.g. when walking some list on cleanup. */ @@ -340,43 +338,23 @@ static inline int _req_mod(struct drbd_request *req, enum drbd_req_event what) return rv; } -/* completion of master bio is outside of our spinlock. - * We still may or may not be inside some irqs disabled section - * of the lower level driver completion callback, so we need to - * spin_lock_irqsave here. */ +/* completion of master bio is outside of spinlock. + * If you need it irqsave, do it your self! + * Which means: don't use from bio endio callback. */ static inline int req_mod(struct drbd_request *req, enum drbd_req_event what) { - unsigned long flags; struct drbd_conf *mdev = req->mdev; struct bio_and_error m; int rv; - spin_lock_irqsave(&mdev->req_lock, flags); + spin_lock_irq(&mdev->req_lock); rv = __req_mod(req, what, &m); - spin_unlock_irqrestore(&mdev->req_lock, flags); + spin_unlock_irq(&mdev->req_lock); if (m.bio) complete_master_bio(mdev, &m); return rv; } - -static inline bool drbd_should_do_remote(union drbd_state s) -{ - return s.pdsk == D_UP_TO_DATE || - (s.pdsk >= D_INCONSISTENT && - s.conn >= C_WF_BITMAP_T && - s.conn < C_AHEAD); - /* Before proto 96 that was >= CONNECTED instead of >= C_WF_BITMAP_T. - That is equivalent since before 96 IO was frozen in the C_WF_BITMAP* - states. */ -} -static inline bool drbd_should_send_oos(union drbd_state s) -{ - return s.conn == C_AHEAD || s.conn == C_WF_BITMAP_S; - /* pdsk = D_INCONSISTENT as a consequence. Protocol 96 check not necessary - since we enter state C_AHEAD only if proto >= 96 */ -} - #endif diff --git a/trunk/drivers/block/drbd/drbd_strings.c b/trunk/drivers/block/drbd/drbd_strings.c index c44a2a602772..85179e1fb50a 100644 --- a/trunk/drivers/block/drbd/drbd_strings.c +++ b/trunk/drivers/block/drbd/drbd_strings.c @@ -48,8 +48,6 @@ static const char *drbd_conn_s_names[] = { [C_PAUSED_SYNC_T] = "PausedSyncT", [C_VERIFY_S] = "VerifyS", [C_VERIFY_T] = "VerifyT", - [C_AHEAD] = "Ahead", - [C_BEHIND] = "Behind", }; static const char *drbd_role_s_names[] = { @@ -94,7 +92,7 @@ static const char *drbd_state_sw_errors[] = { const char *drbd_conn_str(enum drbd_conns s) { /* enums are unsigned... */ - return s > C_BEHIND ? "TOO_LARGE" : drbd_conn_s_names[s]; + return s > C_PAUSED_SYNC_T ? "TOO_LARGE" : drbd_conn_s_names[s]; } const char *drbd_role_str(enum drbd_role s) @@ -107,7 +105,7 @@ const char *drbd_disk_str(enum drbd_disk_state s) return s > D_UP_TO_DATE ? "TOO_LARGE" : drbd_disk_s_names[s]; } -const char *drbd_set_st_err_str(enum drbd_state_rv err) +const char *drbd_set_st_err_str(enum drbd_state_ret_codes err) { return err <= SS_AFTER_LAST_ERROR ? "TOO_SMALL" : err > SS_TWO_PRIMARIES ? "TOO_LARGE" diff --git a/trunk/drivers/block/drbd/drbd_worker.c b/trunk/drivers/block/drbd/drbd_worker.c index f7e6c92f8d03..e027446590d3 100644 --- a/trunk/drivers/block/drbd/drbd_worker.c +++ b/trunk/drivers/block/drbd/drbd_worker.c @@ -39,17 +39,18 @@ #include "drbd_req.h" static int w_make_ov_request(struct drbd_conf *mdev, struct drbd_work *w, int cancel); -static int w_make_resync_request(struct drbd_conf *mdev, - struct drbd_work *w, int cancel); -/* endio handlers: - * drbd_md_io_complete (defined here) - * drbd_endio_pri (defined here) - * drbd_endio_sec (defined here) - * bm_async_io_complete (defined in drbd_bitmap.c) - * +/* defined here: + drbd_md_io_complete + drbd_endio_sec + drbd_endio_pri + + * more endio handlers: + atodb_endio in drbd_actlog.c + drbd_bm_async_io_complete in drbd_bitmap.c + * For all these callbacks, note the following: * The callbacks will be called in irq context by the IDE drivers, * and in Softirqs/Tasklets/BH context by the SCSI drivers. @@ -93,7 +94,7 @@ void drbd_endio_read_sec_final(struct drbd_epoch_entry *e) __releases(local) if (list_empty(&mdev->read_ee)) wake_up(&mdev->ee_wait); if (test_bit(__EE_WAS_ERROR, &e->flags)) - __drbd_chk_io_error(mdev, false); + __drbd_chk_io_error(mdev, FALSE); spin_unlock_irqrestore(&mdev->req_lock, flags); drbd_queue_work(&mdev->data.work, &e->w); @@ -136,7 +137,7 @@ static void drbd_endio_write_sec_final(struct drbd_epoch_entry *e) __releases(lo : list_empty(&mdev->active_ee); if (test_bit(__EE_WAS_ERROR, &e->flags)) - __drbd_chk_io_error(mdev, false); + __drbd_chk_io_error(mdev, FALSE); spin_unlock_irqrestore(&mdev->req_lock, flags); if (is_syncer_req) @@ -162,15 +163,14 @@ void drbd_endio_sec(struct bio *bio, int error) int uptodate = bio_flagged(bio, BIO_UPTODATE); int is_write = bio_data_dir(bio) == WRITE; - if (error && __ratelimit(&drbd_ratelimit_state)) + if (error) dev_warn(DEV, "%s: error=%d s=%llus\n", is_write ? "write" : "read", error, (unsigned long long)e->sector); if (!error && !uptodate) { - if (__ratelimit(&drbd_ratelimit_state)) - dev_warn(DEV, "%s: setting error to -EIO s=%llus\n", - is_write ? "write" : "read", - (unsigned long long)e->sector); + dev_warn(DEV, "%s: setting error to -EIO s=%llus\n", + is_write ? "write" : "read", + (unsigned long long)e->sector); /* strange behavior of some lower level drivers... * fail the request by clearing the uptodate flag, * but do not return any error?! */ @@ -250,6 +250,13 @@ int w_read_retry_remote(struct drbd_conf *mdev, struct drbd_work *w, int cancel) return w_send_read_req(mdev, w, 0); } +int w_resync_inactive(struct drbd_conf *mdev, struct drbd_work *w, int cancel) +{ + ERR_IF(cancel) return 1; + dev_err(DEV, "resync inactive, but callback triggered??\n"); + return 1; /* Simply ignore this! */ +} + void drbd_csum_ee(struct drbd_conf *mdev, struct crypto_hash *tfm, struct drbd_epoch_entry *e, void *digest) { struct hash_desc desc; @@ -348,7 +355,7 @@ static int read_for_csum(struct drbd_conf *mdev, sector_t sector, int size) if (!get_ldev(mdev)) return -EIO; - if (drbd_rs_should_slow_down(mdev, sector)) + if (drbd_rs_should_slow_down(mdev)) goto defer; /* GFP_TRY, because if there is no memory available right now, this may @@ -366,10 +373,9 @@ static int read_for_csum(struct drbd_conf *mdev, sector_t sector, int size) if (drbd_submit_ee(mdev, e, READ, DRBD_FAULT_RS_RD) == 0) return 0; - /* If it failed because of ENOMEM, retry should help. If it failed - * because bio_add_page failed (probably broken lower level driver), - * retry may or may not help. - * If it does not, you may need to force disconnect. */ + /* drbd_submit_ee currently fails for one reason only: + * not being able to allocate enough bios. + * Is dropping the connection going to help? */ spin_lock_irq(&mdev->req_lock); list_del(&e->w.list); spin_unlock_irq(&mdev->req_lock); @@ -380,25 +386,26 @@ static int read_for_csum(struct drbd_conf *mdev, sector_t sector, int size) return -EAGAIN; } -int w_resync_timer(struct drbd_conf *mdev, struct drbd_work *w, int cancel) +void resync_timer_fn(unsigned long data) { + struct drbd_conf *mdev = (struct drbd_conf *) data; + int queue; + + queue = 1; switch (mdev->state.conn) { case C_VERIFY_S: - w_make_ov_request(mdev, w, cancel); + mdev->resync_work.cb = w_make_ov_request; break; case C_SYNC_TARGET: - w_make_resync_request(mdev, w, cancel); + mdev->resync_work.cb = w_make_resync_request; break; + default: + queue = 0; + mdev->resync_work.cb = w_resync_inactive; } - return 1; -} - -void resync_timer_fn(unsigned long data) -{ - struct drbd_conf *mdev = (struct drbd_conf *) data; - - if (list_empty(&mdev->resync_work.list)) + /* harmless race: list_empty outside data.work.q_lock */ + if (list_empty(&mdev->resync_work.list) && queue) drbd_queue_work(&mdev->data.work, &mdev->resync_work); } @@ -431,7 +438,7 @@ static void fifo_add_val(struct fifo_buffer *fb, int value) fb->values[i] += value; } -static int drbd_rs_controller(struct drbd_conf *mdev) +int drbd_rs_controller(struct drbd_conf *mdev) { unsigned int sect_in; /* Number of sectors that came in since the last turn */ unsigned int want; /* The number of sectors we want in the proxy */ @@ -485,36 +492,29 @@ static int drbd_rs_controller(struct drbd_conf *mdev) return req_sect; } -static int drbd_rs_number_requests(struct drbd_conf *mdev) -{ - int number; - if (mdev->rs_plan_s.size) { /* mdev->sync_conf.c_plan_ahead */ - number = drbd_rs_controller(mdev) >> (BM_BLOCK_SHIFT - 9); - mdev->c_sync_rate = number * HZ * (BM_BLOCK_SIZE / 1024) / SLEEP_TIME; - } else { - mdev->c_sync_rate = mdev->sync_conf.rate; - number = SLEEP_TIME * mdev->c_sync_rate / ((BM_BLOCK_SIZE / 1024) * HZ); - } - - /* ignore the amount of pending requests, the resync controller should - * throttle down to incoming reply rate soon enough anyways. */ - return number; -} - -static int w_make_resync_request(struct drbd_conf *mdev, - struct drbd_work *w, int cancel) +int w_make_resync_request(struct drbd_conf *mdev, + struct drbd_work *w, int cancel) { unsigned long bit; sector_t sector; const sector_t capacity = drbd_get_capacity(mdev->this_bdev); - int max_bio_size; - int number, rollback_i, size; + int max_segment_size; + int number, rollback_i, size, pe, mx; int align, queued, sndbuf; int i = 0; if (unlikely(cancel)) return 1; + if (unlikely(mdev->state.conn < C_CONNECTED)) { + dev_err(DEV, "Confused in w_make_resync_request()! cstate < Connected"); + return 0; + } + + if (mdev->state.conn != C_SYNC_TARGET) + dev_err(DEV, "%s in w_make_resync_request\n", + drbd_conn_str(mdev->state.conn)); + if (mdev->rs_total == 0) { /* empty resync? */ drbd_resync_finished(mdev); @@ -527,19 +527,49 @@ static int w_make_resync_request(struct drbd_conf *mdev, to continue resync with a broken disk makes no sense at all */ dev_err(DEV, "Disk broke down during resync!\n"); + mdev->resync_work.cb = w_resync_inactive; return 1; } /* starting with drbd 8.3.8, we can handle multi-bio EEs, * if it should be necessary */ - max_bio_size = - mdev->agreed_pro_version < 94 ? queue_max_hw_sectors(mdev->rq_queue) << 9 : - mdev->agreed_pro_version < 95 ? DRBD_MAX_SIZE_H80_PACKET : DRBD_MAX_BIO_SIZE; + max_segment_size = + mdev->agreed_pro_version < 94 ? queue_max_segment_size(mdev->rq_queue) : + mdev->agreed_pro_version < 95 ? DRBD_MAX_SIZE_H80_PACKET : DRBD_MAX_SEGMENT_SIZE; - number = drbd_rs_number_requests(mdev); - if (number == 0) + if (mdev->rs_plan_s.size) { /* mdev->sync_conf.c_plan_ahead */ + number = drbd_rs_controller(mdev) >> (BM_BLOCK_SHIFT - 9); + mdev->c_sync_rate = number * HZ * (BM_BLOCK_SIZE / 1024) / SLEEP_TIME; + } else { + mdev->c_sync_rate = mdev->sync_conf.rate; + number = SLEEP_TIME * mdev->c_sync_rate / ((BM_BLOCK_SIZE / 1024) * HZ); + } + + /* Throttle resync on lower level disk activity, which may also be + * caused by application IO on Primary/SyncTarget. + * Keep this after the call to drbd_rs_controller, as that assumes + * to be called as precisely as possible every SLEEP_TIME, + * and would be confused otherwise. */ + if (drbd_rs_should_slow_down(mdev)) goto requeue; + mutex_lock(&mdev->data.mutex); + if (mdev->data.socket) + mx = mdev->data.socket->sk->sk_rcvbuf / sizeof(struct p_block_req); + else + mx = 1; + mutex_unlock(&mdev->data.mutex); + + /* For resync rates >160MB/sec, allow more pending RS requests */ + if (number > mx) + mx = number; + + /* Limit the number of pending RS requests to no more than the peer's receive buffer */ + pe = atomic_read(&mdev->rs_pending_cnt); + if ((pe + number) > mx) { + number = mx - pe; + } + for (i = 0; i < number; i++) { /* Stop generating RS requests, when half of the send buffer is filled */ mutex_lock(&mdev->data.mutex); @@ -558,16 +588,16 @@ static int w_make_resync_request(struct drbd_conf *mdev, size = BM_BLOCK_SIZE; bit = drbd_bm_find_next(mdev, mdev->bm_resync_fo); - if (bit == DRBD_END_OF_BITMAP) { + if (bit == -1UL) { mdev->bm_resync_fo = drbd_bm_bits(mdev); + mdev->resync_work.cb = w_resync_inactive; put_ldev(mdev); return 1; } sector = BM_BIT_TO_SECT(bit); - if (drbd_rs_should_slow_down(mdev, sector) || - drbd_try_rs_begin_io(mdev, sector)) { + if (drbd_try_rs_begin_io(mdev, sector)) { mdev->bm_resync_fo = bit; goto requeue; } @@ -578,7 +608,7 @@ static int w_make_resync_request(struct drbd_conf *mdev, goto next_sector; } -#if DRBD_MAX_BIO_SIZE > BM_BLOCK_SIZE +#if DRBD_MAX_SEGMENT_SIZE > BM_BLOCK_SIZE /* try to find some adjacent bits. * we stop if we have already the maximum req size. * @@ -588,7 +618,7 @@ static int w_make_resync_request(struct drbd_conf *mdev, align = 1; rollback_i = i; for (;;) { - if (size + BM_BLOCK_SIZE > max_bio_size) + if (size + BM_BLOCK_SIZE > max_segment_size) break; /* Be always aligned */ @@ -655,6 +685,7 @@ static int w_make_resync_request(struct drbd_conf *mdev, * resync data block, and the last bit is cleared. * until then resync "work" is "inactive" ... */ + mdev->resync_work.cb = w_resync_inactive; put_ldev(mdev); return 1; } @@ -675,18 +706,27 @@ static int w_make_ov_request(struct drbd_conf *mdev, struct drbd_work *w, int ca if (unlikely(cancel)) return 1; - number = drbd_rs_number_requests(mdev); + if (unlikely(mdev->state.conn < C_CONNECTED)) { + dev_err(DEV, "Confused in w_make_ov_request()! cstate < Connected"); + return 0; + } + + number = SLEEP_TIME*mdev->sync_conf.rate / ((BM_BLOCK_SIZE/1024)*HZ); + if (atomic_read(&mdev->rs_pending_cnt) > number) + goto requeue; + + number -= atomic_read(&mdev->rs_pending_cnt); sector = mdev->ov_position; for (i = 0; i < number; i++) { if (sector >= capacity) { + mdev->resync_work.cb = w_resync_inactive; return 1; } size = BM_BLOCK_SIZE; - if (drbd_rs_should_slow_down(mdev, sector) || - drbd_try_rs_begin_io(mdev, sector)) { + if (drbd_try_rs_begin_io(mdev, sector)) { mdev->ov_position = sector; goto requeue; } @@ -704,33 +744,11 @@ static int w_make_ov_request(struct drbd_conf *mdev, struct drbd_work *w, int ca mdev->ov_position = sector; requeue: - mdev->rs_in_flight += (i << (BM_BLOCK_SHIFT - 9)); mod_timer(&mdev->resync_timer, jiffies + SLEEP_TIME); return 1; } -void start_resync_timer_fn(unsigned long data) -{ - struct drbd_conf *mdev = (struct drbd_conf *) data; - - drbd_queue_work(&mdev->data.work, &mdev->start_resync_work); -} - -int w_start_resync(struct drbd_conf *mdev, struct drbd_work *w, int cancel) -{ - if (atomic_read(&mdev->unacked_cnt) || atomic_read(&mdev->rs_pending_cnt)) { - dev_warn(DEV, "w_start_resync later...\n"); - mdev->start_resync_timer.expires = jiffies + HZ/10; - add_timer(&mdev->start_resync_timer); - return 1; - } - - drbd_start_resync(mdev, C_SYNC_SOURCE); - clear_bit(AHEAD_TO_SYNC_SOURCE, &mdev->current_epoch->flags); - return 1; -} - int w_ov_finished(struct drbd_conf *mdev, struct drbd_work *w, int cancel) { kfree(w); @@ -764,7 +782,6 @@ int drbd_resync_finished(struct drbd_conf *mdev) union drbd_state os, ns; struct drbd_work *w; char *khelper_cmd = NULL; - int verify_done = 0; /* Remove all elements from the resync LRU. Since future actions * might set bits in the (main) bitmap, then the entries in the @@ -775,7 +792,8 @@ int drbd_resync_finished(struct drbd_conf *mdev) * queue (or even the read operations for those packets * is not finished by now). Retry in 100ms. */ - schedule_timeout_interruptible(HZ / 10); + __set_current_state(TASK_INTERRUPTIBLE); + schedule_timeout(HZ / 10); w = kmalloc(sizeof(struct drbd_work), GFP_ATOMIC); if (w) { w->cb = w_resync_finished; @@ -800,8 +818,6 @@ int drbd_resync_finished(struct drbd_conf *mdev) spin_lock_irq(&mdev->req_lock); os = mdev->state; - verify_done = (os.conn == C_VERIFY_S || os.conn == C_VERIFY_T); - /* This protects us against multiple calls (that can happen in the presence of application IO), and against connectivity loss just before we arrive here. */ if (os.conn <= C_CONNECTED) @@ -811,7 +827,8 @@ int drbd_resync_finished(struct drbd_conf *mdev) ns.conn = C_CONNECTED; dev_info(DEV, "%s done (total %lu sec; paused %lu sec; %lu K/sec)\n", - verify_done ? "Online verify " : "Resync", + (os.conn == C_VERIFY_S || os.conn == C_VERIFY_T) ? + "Online verify " : "Resync", dt + mdev->rs_paused, mdev->rs_paused, dbdt); n_oos = drbd_bm_total_weight(mdev); @@ -869,18 +886,14 @@ int drbd_resync_finished(struct drbd_conf *mdev) } } - if (!(os.conn == C_VERIFY_S || os.conn == C_VERIFY_T)) { - /* for verify runs, we don't update uuids here, - * so there would be nothing to report. */ - drbd_uuid_set_bm(mdev, 0UL); - drbd_print_uuids(mdev, "updated UUIDs"); - if (mdev->p_uuid) { - /* Now the two UUID sets are equal, update what we - * know of the peer. */ - int i; - for (i = UI_CURRENT ; i <= UI_HISTORY_END ; i++) - mdev->p_uuid[i] = mdev->ldev->md.uuid[i]; - } + drbd_uuid_set_bm(mdev, 0UL); + + if (mdev->p_uuid) { + /* Now the two UUID sets are equal, update what we + * know of the peer. */ + int i; + for (i = UI_CURRENT ; i <= UI_HISTORY_END ; i++) + mdev->p_uuid[i] = mdev->ldev->md.uuid[i]; } } @@ -892,11 +905,15 @@ int drbd_resync_finished(struct drbd_conf *mdev) mdev->rs_total = 0; mdev->rs_failed = 0; mdev->rs_paused = 0; - if (verify_done) - mdev->ov_start_sector = 0; + mdev->ov_start_sector = 0; drbd_md_sync(mdev); + if (test_and_clear_bit(WRITE_BM_AFTER_RESYNC, &mdev->flags)) { + dev_info(DEV, "Writing the whole bitmap\n"); + drbd_queue_bitmap_io(mdev, &drbd_bm_write, NULL, "write from resync_finished"); + } + if (khelper_cmd) drbd_khelper(mdev, khelper_cmd); @@ -977,9 +994,7 @@ int w_e_end_rsdata_req(struct drbd_conf *mdev, struct drbd_work *w, int cancel) put_ldev(mdev); } - if (mdev->state.conn == C_AHEAD) { - ok = drbd_send_ack(mdev, P_RS_CANCEL, e); - } else if (likely((e->flags & EE_WAS_ERROR) == 0)) { + if (likely((e->flags & EE_WAS_ERROR) == 0)) { if (likely(mdev->state.pdsk >= D_INCONSISTENT)) { inc_rs_pending(mdev); ok = drbd_send_block(mdev, P_RS_DATA_REPLY, e); @@ -1081,27 +1096,25 @@ int w_e_end_ov_req(struct drbd_conf *mdev, struct drbd_work *w, int cancel) if (unlikely(cancel)) goto out; - digest_size = crypto_hash_digestsize(mdev->verify_tfm); - digest = kmalloc(digest_size, GFP_NOIO); - if (!digest) { - ok = 0; /* terminate the connection in case the allocation failed */ + if (unlikely((e->flags & EE_WAS_ERROR) != 0)) goto out; - } - if (likely(!(e->flags & EE_WAS_ERROR))) + digest_size = crypto_hash_digestsize(mdev->verify_tfm); + /* FIXME if this allocation fails, online verify will not terminate! */ + digest = kmalloc(digest_size, GFP_NOIO); + if (digest) { drbd_csum_ee(mdev, mdev->verify_tfm, e, digest); - else - memset(digest, 0, digest_size); - - inc_rs_pending(mdev); - ok = drbd_send_drequest_csum(mdev, e->sector, e->size, - digest, digest_size, P_OV_REPLY); - if (!ok) - dec_rs_pending(mdev); - kfree(digest); + inc_rs_pending(mdev); + ok = drbd_send_drequest_csum(mdev, e->sector, e->size, + digest, digest_size, P_OV_REPLY); + if (!ok) + dec_rs_pending(mdev); + kfree(digest); + } out: drbd_free_ee(mdev, e); + dec_unacked(mdev); return ok; @@ -1116,6 +1129,7 @@ void drbd_ov_oos_found(struct drbd_conf *mdev, sector_t sector, int size) mdev->ov_last_oos_size = size>>9; } drbd_set_out_of_sync(mdev, sector, size); + set_bit(WRITE_BM_AFTER_RESYNC, &mdev->flags); } int w_e_end_ov_reply(struct drbd_conf *mdev, struct drbd_work *w, int cancel) @@ -1151,6 +1165,10 @@ int w_e_end_ov_reply(struct drbd_conf *mdev, struct drbd_work *w, int cancel) eq = !memcmp(digest, di->digest, digest_size); kfree(digest); } + } else { + ok = drbd_send_ack(mdev, P_NEG_RS_DREPLY, e); + if (__ratelimit(&drbd_ratelimit_state)) + dev_err(DEV, "Sending NegDReply. I guess it gets messy.\n"); } dec_unacked(mdev); @@ -1164,13 +1182,7 @@ int w_e_end_ov_reply(struct drbd_conf *mdev, struct drbd_work *w, int cancel) drbd_free_ee(mdev, e); - --mdev->ov_left; - - /* let's advance progress step marks only for every other megabyte */ - if ((mdev->ov_left & 0x200) == 0x200) - drbd_advance_rs_marks(mdev, mdev->ov_left); - - if (mdev->ov_left == 0) { + if (--mdev->ov_left == 0) { ov_oos_print(mdev); drbd_resync_finished(mdev); } @@ -1223,22 +1235,6 @@ int w_send_write_hint(struct drbd_conf *mdev, struct drbd_work *w, int cancel) return drbd_send_short_cmd(mdev, P_UNPLUG_REMOTE); } -int w_send_oos(struct drbd_conf *mdev, struct drbd_work *w, int cancel) -{ - struct drbd_request *req = container_of(w, struct drbd_request, w); - int ok; - - if (unlikely(cancel)) { - req_mod(req, send_canceled); - return 1; - } - - ok = drbd_send_oos(mdev, req); - req_mod(req, oos_handed_to_network); - - return ok; -} - /** * w_send_dblock() - Worker callback to send a P_DATA packet in order to mirror a write request * @mdev: DRBD device. @@ -1434,17 +1430,6 @@ int drbd_alter_sa(struct drbd_conf *mdev, int na) return retcode; } -void drbd_rs_controller_reset(struct drbd_conf *mdev) -{ - atomic_set(&mdev->rs_sect_in, 0); - atomic_set(&mdev->rs_sect_ev, 0); - mdev->rs_in_flight = 0; - mdev->rs_planed = 0; - spin_lock(&mdev->peer_seq_lock); - fifo_set(&mdev->rs_plan_s, 0); - spin_unlock(&mdev->peer_seq_lock); -} - /** * drbd_start_resync() - Start the resync process * @mdev: DRBD device. @@ -1458,18 +1443,13 @@ void drbd_start_resync(struct drbd_conf *mdev, enum drbd_conns side) union drbd_state ns; int r; - if (mdev->state.conn >= C_SYNC_SOURCE && mdev->state.conn < C_AHEAD) { + if (mdev->state.conn >= C_SYNC_SOURCE) { dev_err(DEV, "Resync already running!\n"); return; } - if (mdev->state.conn < C_AHEAD) { - /* In case a previous resync run was aborted by an IO error/detach on the peer. */ - drbd_rs_cancel_all(mdev); - /* This should be done when we abort the resync. We definitely do not - want to have this for connections going back and forth between - Ahead/Behind and SyncSource/SyncTarget */ - } + /* In case a previous resync run was aborted by an IO error/detach on the peer. */ + drbd_rs_cancel_all(mdev); if (side == C_SYNC_TARGET) { /* Since application IO was locked out during C_WF_BITMAP_T and @@ -1483,20 +1463,6 @@ void drbd_start_resync(struct drbd_conf *mdev, enum drbd_conns side) drbd_force_state(mdev, NS(conn, C_DISCONNECTING)); return; } - } else /* C_SYNC_SOURCE */ { - r = drbd_khelper(mdev, "before-resync-source"); - r = (r >> 8) & 0xff; - if (r > 0) { - if (r == 3) { - dev_info(DEV, "before-resync-source handler returned %d, " - "ignoring. Old userland tools?", r); - } else { - dev_info(DEV, "before-resync-source handler returned %d, " - "dropping connection.\n", r); - drbd_force_state(mdev, NS(conn, C_DISCONNECTING)); - return; - } - } } drbd_state_lock(mdev); @@ -1506,6 +1472,18 @@ void drbd_start_resync(struct drbd_conf *mdev, enum drbd_conns side) return; } + if (side == C_SYNC_TARGET) { + mdev->bm_resync_fo = 0; + } else /* side == C_SYNC_SOURCE */ { + u64 uuid; + + get_random_bytes(&uuid, sizeof(u64)); + drbd_uuid_set(mdev, UI_BITMAP, uuid); + drbd_send_sync_uuid(mdev, uuid); + + D_ASSERT(mdev->state.disk == D_UP_TO_DATE); + } + write_lock_irq(&global_state_lock); ns = mdev->state; @@ -1543,24 +1521,13 @@ void drbd_start_resync(struct drbd_conf *mdev, enum drbd_conns side) _drbd_pause_after(mdev); } write_unlock_irq(&global_state_lock); + put_ldev(mdev); if (r == SS_SUCCESS) { dev_info(DEV, "Began resync as %s (will sync %lu KB [%lu bits set]).\n", drbd_conn_str(ns.conn), (unsigned long) mdev->rs_total << (BM_BLOCK_SHIFT-10), (unsigned long) mdev->rs_total); - if (side == C_SYNC_TARGET) - mdev->bm_resync_fo = 0; - - /* Since protocol 96, we must serialize drbd_gen_and_send_sync_uuid - * with w_send_oos, or the sync target will get confused as to - * how much bits to resync. We cannot do that always, because for an - * empty resync and protocol < 95, we need to do it here, as we call - * drbd_resync_finished from here in that case. - * We drbd_gen_and_send_sync_uuid here for protocol < 96, - * and from after_state_ch otherwise. */ - if (side == C_SYNC_SOURCE && mdev->agreed_pro_version < 96) - drbd_gen_and_send_sync_uuid(mdev); if (mdev->agreed_pro_version < 95 && mdev->rs_total == 0) { /* This still has a race (about when exactly the peers @@ -1580,7 +1547,13 @@ void drbd_start_resync(struct drbd_conf *mdev, enum drbd_conns side) drbd_resync_finished(mdev); } - drbd_rs_controller_reset(mdev); + atomic_set(&mdev->rs_sect_in, 0); + atomic_set(&mdev->rs_sect_ev, 0); + mdev->rs_in_flight = 0; + mdev->rs_planed = 0; + spin_lock(&mdev->peer_seq_lock); + fifo_set(&mdev->rs_plan_s, 0); + spin_unlock(&mdev->peer_seq_lock); /* ns.conn may already be != mdev->state.conn, * we may have been paused in between, or become paused until * the timer triggers. @@ -1590,7 +1563,6 @@ void drbd_start_resync(struct drbd_conf *mdev, enum drbd_conns side) drbd_md_sync(mdev); } - put_ldev(mdev); drbd_state_unlock(mdev); } diff --git a/trunk/drivers/block/drbd/drbd_wrappers.h b/trunk/drivers/block/drbd/drbd_wrappers.h index 151f1a37478f..53586fa5ae1b 100644 --- a/trunk/drivers/block/drbd/drbd_wrappers.h +++ b/trunk/drivers/block/drbd/drbd_wrappers.h @@ -39,7 +39,7 @@ static inline void drbd_generic_make_request(struct drbd_conf *mdev, return; } - if (drbd_insert_fault(mdev, fault_type)) + if (FAULT_ACTIVE(mdev, fault_type)) bio_endio(bio, -EIO); else generic_make_request(bio); diff --git a/trunk/drivers/char/tpm/tpm.c b/trunk/drivers/char/tpm/tpm.c index 7beb0e25f1e1..1f46f1cd9225 100644 --- a/trunk/drivers/char/tpm/tpm.c +++ b/trunk/drivers/char/tpm/tpm.c @@ -980,7 +980,7 @@ int tpm_open(struct inode *inode, struct file *file) return -EBUSY; } - chip->data_buffer = kzalloc(TPM_BUFSIZE, GFP_KERNEL); + chip->data_buffer = kmalloc(TPM_BUFSIZE * sizeof(u8), GFP_KERNEL); if (chip->data_buffer == NULL) { clear_bit(0, &chip->is_open); put_device(chip->dev); diff --git a/trunk/drivers/dma/ipu/ipu_irq.c b/trunk/drivers/dma/ipu/ipu_irq.c index ab8a4eff072a..dd8ebc75b667 100644 --- a/trunk/drivers/dma/ipu/ipu_irq.c +++ b/trunk/drivers/dma/ipu/ipu_irq.c @@ -94,9 +94,9 @@ static struct ipu_irq_map *src2map(unsigned int src) return NULL; } -static void ipu_irq_unmask(struct irq_data *d) +static void ipu_irq_unmask(unsigned int irq) { - struct ipu_irq_map *map = irq_data_get_irq_chip_data(d); + struct ipu_irq_map *map = get_irq_chip_data(irq); struct ipu_irq_bank *bank; uint32_t reg; unsigned long lock_flags; @@ -106,7 +106,7 @@ static void ipu_irq_unmask(struct irq_data *d) bank = map->bank; if (!bank) { spin_unlock_irqrestore(&bank_lock, lock_flags); - pr_err("IPU: %s(%u) - unmapped!\n", __func__, d->irq); + pr_err("IPU: %s(%u) - unmapped!\n", __func__, irq); return; } @@ -117,9 +117,9 @@ static void ipu_irq_unmask(struct irq_data *d) spin_unlock_irqrestore(&bank_lock, lock_flags); } -static void ipu_irq_mask(struct irq_data *d) +static void ipu_irq_mask(unsigned int irq) { - struct ipu_irq_map *map = irq_data_get_irq_chip_data(d); + struct ipu_irq_map *map = get_irq_chip_data(irq); struct ipu_irq_bank *bank; uint32_t reg; unsigned long lock_flags; @@ -129,7 +129,7 @@ static void ipu_irq_mask(struct irq_data *d) bank = map->bank; if (!bank) { spin_unlock_irqrestore(&bank_lock, lock_flags); - pr_err("IPU: %s(%u) - unmapped!\n", __func__, d->irq); + pr_err("IPU: %s(%u) - unmapped!\n", __func__, irq); return; } @@ -140,9 +140,9 @@ static void ipu_irq_mask(struct irq_data *d) spin_unlock_irqrestore(&bank_lock, lock_flags); } -static void ipu_irq_ack(struct irq_data *d) +static void ipu_irq_ack(unsigned int irq) { - struct ipu_irq_map *map = irq_data_get_irq_chip_data(d); + struct ipu_irq_map *map = get_irq_chip_data(irq); struct ipu_irq_bank *bank; unsigned long lock_flags; @@ -151,7 +151,7 @@ static void ipu_irq_ack(struct irq_data *d) bank = map->bank; if (!bank) { spin_unlock_irqrestore(&bank_lock, lock_flags); - pr_err("IPU: %s(%u) - unmapped!\n", __func__, d->irq); + pr_err("IPU: %s(%u) - unmapped!\n", __func__, irq); return; } @@ -167,7 +167,7 @@ static void ipu_irq_ack(struct irq_data *d) */ bool ipu_irq_status(unsigned int irq) { - struct ipu_irq_map *map = irq_get_chip_data(irq); + struct ipu_irq_map *map = get_irq_chip_data(irq); struct ipu_irq_bank *bank; unsigned long lock_flags; bool ret; @@ -269,7 +269,7 @@ int ipu_irq_unmap(unsigned int source) /* Chained IRQ handler for IPU error interrupt */ static void ipu_irq_err(unsigned int irq, struct irq_desc *desc) { - struct ipu *ipu = irq_get_handler_data(irq); + struct ipu *ipu = get_irq_data(irq); u32 status; int i, line; @@ -310,7 +310,7 @@ static void ipu_irq_err(unsigned int irq, struct irq_desc *desc) /* Chained IRQ handler for IPU function interrupt */ static void ipu_irq_fn(unsigned int irq, struct irq_desc *desc) { - struct ipu *ipu = irq_desc_get_handler_data(desc); + struct ipu *ipu = get_irq_data(irq); u32 status; int i, line; @@ -345,10 +345,10 @@ static void ipu_irq_fn(unsigned int irq, struct irq_desc *desc) } static struct irq_chip ipu_irq_chip = { - .name = "ipu_irq", - .irq_ack = ipu_irq_ack, - .irq_mask = ipu_irq_mask, - .irq_unmask = ipu_irq_unmask, + .name = "ipu_irq", + .ack = ipu_irq_ack, + .mask = ipu_irq_mask, + .unmask = ipu_irq_unmask, }; /* Install the IRQ handler */ @@ -366,26 +366,26 @@ int __init ipu_irq_attach_irq(struct ipu *ipu, struct platform_device *dev) int ret; irq = irq_base + i; - ret = irq_set_chip(irq, &ipu_irq_chip); + ret = set_irq_chip(irq, &ipu_irq_chip); if (ret < 0) return ret; - ret = irq_set_chip_data(irq, irq_map + i); + ret = set_irq_chip_data(irq, irq_map + i); if (ret < 0) return ret; irq_map[i].ipu = ipu; irq_map[i].irq = irq; irq_map[i].source = -EINVAL; - irq_set_handler(irq, handle_level_irq); + set_irq_handler(irq, handle_level_irq); #ifdef CONFIG_ARM set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); #endif } - irq_set_handler_data(ipu->irq_fn, ipu); - irq_set_chained_handler(ipu->irq_fn, ipu_irq_fn); + set_irq_data(ipu->irq_fn, ipu); + set_irq_chained_handler(ipu->irq_fn, ipu_irq_fn); - irq_set_handler_data(ipu->irq_err, ipu); - irq_set_chained_handler(ipu->irq_err, ipu_irq_err); + set_irq_data(ipu->irq_err, ipu); + set_irq_chained_handler(ipu->irq_err, ipu_irq_err); return 0; } @@ -397,17 +397,17 @@ void ipu_irq_detach_irq(struct ipu *ipu, struct platform_device *dev) irq_base = pdata->irq_base; - irq_set_chained_handler(ipu->irq_fn, NULL); - irq_set_handler_data(ipu->irq_fn, NULL); + set_irq_chained_handler(ipu->irq_fn, NULL); + set_irq_data(ipu->irq_fn, NULL); - irq_set_chained_handler(ipu->irq_err, NULL); - irq_set_handler_data(ipu->irq_err, NULL); + set_irq_chained_handler(ipu->irq_err, NULL); + set_irq_data(ipu->irq_err, NULL); for (irq = irq_base; irq < irq_base + CONFIG_MX3_IPU_IRQS; irq++) { #ifdef CONFIG_ARM set_irq_flags(irq, 0); #endif - irq_set_chip(irq, NULL); - irq_set_chip_data(irq, NULL); + set_irq_chip(irq, NULL); + set_irq_chip_data(irq, NULL); } } diff --git a/trunk/drivers/edac/amd64_edac.c b/trunk/drivers/edac/amd64_edac.c index 31e71c4fc831..0be30e978c85 100644 --- a/trunk/drivers/edac/amd64_edac.c +++ b/trunk/drivers/edac/amd64_edac.c @@ -2679,7 +2679,7 @@ static int __init amd64_edac_init(void) mcis = kzalloc(amd_nb_num() * sizeof(mcis[0]), GFP_KERNEL); ecc_stngs = kzalloc(amd_nb_num() * sizeof(ecc_stngs[0]), GFP_KERNEL); if (!(mcis && ecc_stngs)) - goto err_free; + goto err_ret; msrs = msrs_alloc(); if (!msrs) diff --git a/trunk/drivers/gpio/Kconfig b/trunk/drivers/gpio/Kconfig index d3b295305542..d8d0cda2641d 100644 --- a/trunk/drivers/gpio/Kconfig +++ b/trunk/drivers/gpio/Kconfig @@ -414,9 +414,4 @@ config GPIO_JANZ_TTL This driver provides support for driving the pins in output mode only. Input mode is not supported. -config AB8500_GPIO - bool "ST-Ericsson AB8500 Mixed Signal Circuit gpio functions" - depends on AB8500_CORE && BROKEN - help - Select this to enable the AB8500 IC GPIO driver endif diff --git a/trunk/drivers/gpio/Makefile b/trunk/drivers/gpio/Makefile index becef5954356..3351cf87b0ed 100644 --- a/trunk/drivers/gpio/Makefile +++ b/trunk/drivers/gpio/Makefile @@ -42,4 +42,3 @@ obj-$(CONFIG_GPIO_JANZ_TTL) += janz-ttl.o obj-$(CONFIG_GPIO_SX150X) += sx150x.o obj-$(CONFIG_GPIO_VX855) += vx855_gpio.o obj-$(CONFIG_GPIO_ML_IOH) += ml_ioh_gpio.o -obj-$(CONFIG_AB8500_GPIO) += ab8500-gpio.o diff --git a/trunk/drivers/gpio/ab8500-gpio.c b/trunk/drivers/gpio/ab8500-gpio.c deleted file mode 100644 index e7b834d054b7..000000000000 --- a/trunk/drivers/gpio/ab8500-gpio.c +++ /dev/null @@ -1,522 +0,0 @@ -/* - * Copyright (C) ST-Ericsson SA 2011 - * - * Author: BIBEK BASU - * License terms: GNU General Public License (GPL) version 2 - * - * 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 - -/* - * GPIO registers offset - * Bank: 0x10 - */ -#define AB8500_GPIO_SEL1_REG 0x00 -#define AB8500_GPIO_SEL2_REG 0x01 -#define AB8500_GPIO_SEL3_REG 0x02 -#define AB8500_GPIO_SEL4_REG 0x03 -#define AB8500_GPIO_SEL5_REG 0x04 -#define AB8500_GPIO_SEL6_REG 0x05 - -#define AB8500_GPIO_DIR1_REG 0x10 -#define AB8500_GPIO_DIR2_REG 0x11 -#define AB8500_GPIO_DIR3_REG 0x12 -#define AB8500_GPIO_DIR4_REG 0x13 -#define AB8500_GPIO_DIR5_REG 0x14 -#define AB8500_GPIO_DIR6_REG 0x15 - -#define AB8500_GPIO_OUT1_REG 0x20 -#define AB8500_GPIO_OUT2_REG 0x21 -#define AB8500_GPIO_OUT3_REG 0x22 -#define AB8500_GPIO_OUT4_REG 0x23 -#define AB8500_GPIO_OUT5_REG 0x24 -#define AB8500_GPIO_OUT6_REG 0x25 - -#define AB8500_GPIO_PUD1_REG 0x30 -#define AB8500_GPIO_PUD2_REG 0x31 -#define AB8500_GPIO_PUD3_REG 0x32 -#define AB8500_GPIO_PUD4_REG 0x33 -#define AB8500_GPIO_PUD5_REG 0x34 -#define AB8500_GPIO_PUD6_REG 0x35 - -#define AB8500_GPIO_IN1_REG 0x40 -#define AB8500_GPIO_IN2_REG 0x41 -#define AB8500_GPIO_IN3_REG 0x42 -#define AB8500_GPIO_IN4_REG 0x43 -#define AB8500_GPIO_IN5_REG 0x44 -#define AB8500_GPIO_IN6_REG 0x45 -#define AB8500_GPIO_ALTFUN_REG 0x45 -#define ALTFUN_REG_INDEX 6 -#define AB8500_NUM_GPIO 42 -#define AB8500_NUM_VIR_GPIO_IRQ 16 - -enum ab8500_gpio_action { - NONE, - STARTUP, - SHUTDOWN, - MASK, - UNMASK -}; - -struct ab8500_gpio { - struct gpio_chip chip; - struct ab8500 *parent; - struct device *dev; - struct mutex lock; - u32 irq_base; - enum ab8500_gpio_action irq_action; - u16 rising; - u16 falling; -}; -/** - * to_ab8500_gpio() - get the pointer to ab8500_gpio - * @chip: Member of the structure ab8500_gpio - */ -static inline struct ab8500_gpio *to_ab8500_gpio(struct gpio_chip *chip) -{ - return container_of(chip, struct ab8500_gpio, chip); -} - -static int ab8500_gpio_set_bits(struct gpio_chip *chip, u8 reg, - unsigned offset, int val) -{ - struct ab8500_gpio *ab8500_gpio = to_ab8500_gpio(chip); - u8 pos = offset % 8; - int ret; - - reg = reg + (offset / 8); - ret = abx500_mask_and_set_register_interruptible(ab8500_gpio->dev, - AB8500_MISC, reg, 1 << pos, val << pos); - if (ret < 0) - dev_err(ab8500_gpio->dev, "%s write failed\n", __func__); - return ret; -} -/** - * ab8500_gpio_get() - Get the particular GPIO value - * @chip: Gpio device - * @offset: GPIO number to read - */ -static int ab8500_gpio_get(struct gpio_chip *chip, unsigned offset) -{ - struct ab8500_gpio *ab8500_gpio = to_ab8500_gpio(chip); - u8 mask = 1 << (offset % 8); - u8 reg = AB8500_GPIO_OUT1_REG + (offset / 8); - int ret; - u8 data; - ret = abx500_get_register_interruptible(ab8500_gpio->dev, AB8500_MISC, - reg, &data); - if (ret < 0) { - dev_err(ab8500_gpio->dev, "%s read failed\n", __func__); - return ret; - } - return (data & mask) >> (offset % 8); -} - -static void ab8500_gpio_set(struct gpio_chip *chip, unsigned offset, int val) -{ - struct ab8500_gpio *ab8500_gpio = to_ab8500_gpio(chip); - int ret; - /* Write the data */ - ret = ab8500_gpio_set_bits(chip, AB8500_GPIO_OUT1_REG, offset, 1); - if (ret < 0) - dev_err(ab8500_gpio->dev, "%s write failed\n", __func__); -} - -static int ab8500_gpio_direction_output(struct gpio_chip *chip, unsigned offset, - int val) -{ - int ret; - /* set direction as output */ - ret = ab8500_gpio_set_bits(chip, AB8500_GPIO_DIR1_REG, offset, 1); - if (ret < 0) - return ret; - /* disable pull down */ - ret = ab8500_gpio_set_bits(chip, AB8500_GPIO_PUD1_REG, offset, 1); - if (ret < 0) - return ret; - /* set the output as 1 or 0 */ - return ab8500_gpio_set_bits(chip, AB8500_GPIO_OUT1_REG, offset, val); - -} - -static int ab8500_gpio_direction_input(struct gpio_chip *chip, unsigned offset) -{ - /* set the register as input */ - return ab8500_gpio_set_bits(chip, AB8500_GPIO_DIR1_REG, offset, 0); -} - -static int ab8500_gpio_to_irq(struct gpio_chip *chip, unsigned offset) -{ - /* - * Only some GPIOs are interrupt capable, and they are - * organized in discontiguous clusters: - * - * GPIO6 to GPIO13 - * GPIO24 and GPIO25 - * GPIO36 to GPIO41 - */ - static struct ab8500_gpio_irq_cluster { - int start; - int end; - } clusters[] = { - {.start = 6, .end = 13}, - {.start = 24, .end = 25}, - {.start = 36, .end = 41}, - }; - struct ab8500_gpio *ab8500_gpio = to_ab8500_gpio(chip); - int base = ab8500_gpio->irq_base; - int i; - - for (i = 0; i < ARRAY_SIZE(clusters); i++) { - struct ab8500_gpio_irq_cluster *cluster = &clusters[i]; - - if (offset >= cluster->start && offset <= cluster->end) - return base + offset - cluster->start; - - /* Advance by the number of gpios in this cluster */ - base += cluster->end - cluster->start + 1; - } - - return -EINVAL; -} - -static struct gpio_chip ab8500gpio_chip = { - .label = "ab8500_gpio", - .owner = THIS_MODULE, - .direction_input = ab8500_gpio_direction_input, - .get = ab8500_gpio_get, - .direction_output = ab8500_gpio_direction_output, - .set = ab8500_gpio_set, - .to_irq = ab8500_gpio_to_irq, -}; - -static unsigned int irq_to_rising(unsigned int irq) -{ - struct ab8500_gpio *ab8500_gpio = get_irq_chip_data(irq); - int offset = irq - ab8500_gpio->irq_base; - int new_irq = offset + AB8500_INT_GPIO6R - + ab8500_gpio->parent->irq_base; - return new_irq; -} - -static unsigned int irq_to_falling(unsigned int irq) -{ - struct ab8500_gpio *ab8500_gpio = get_irq_chip_data(irq); - int offset = irq - ab8500_gpio->irq_base; - int new_irq = offset + AB8500_INT_GPIO6F - + ab8500_gpio->parent->irq_base; - return new_irq; - -} - -static unsigned int rising_to_irq(unsigned int irq, void *dev) -{ - struct ab8500_gpio *ab8500_gpio = dev; - int offset = irq - AB8500_INT_GPIO6R - - ab8500_gpio->parent->irq_base ; - int new_irq = offset + ab8500_gpio->irq_base; - return new_irq; -} - -static unsigned int falling_to_irq(unsigned int irq, void *dev) -{ - struct ab8500_gpio *ab8500_gpio = dev; - int offset = irq - AB8500_INT_GPIO6F - - ab8500_gpio->parent->irq_base ; - int new_irq = offset + ab8500_gpio->irq_base; - return new_irq; - -} - -/* - * IRQ handler - */ - -static irqreturn_t handle_rising(int irq, void *dev) -{ - - handle_nested_irq(rising_to_irq(irq , dev)); - return IRQ_HANDLED; -} - -static irqreturn_t handle_falling(int irq, void *dev) -{ - - handle_nested_irq(falling_to_irq(irq, dev)); - return IRQ_HANDLED; -} - -static void ab8500_gpio_irq_lock(unsigned int irq) -{ - struct ab8500_gpio *ab8500_gpio = get_irq_chip_data(irq); - mutex_lock(&ab8500_gpio->lock); -} - -static void ab8500_gpio_irq_sync_unlock(unsigned int irq) -{ - struct ab8500_gpio *ab8500_gpio = get_irq_chip_data(irq); - int offset = irq - ab8500_gpio->irq_base; - bool rising = ab8500_gpio->rising & BIT(offset); - bool falling = ab8500_gpio->falling & BIT(offset); - int ret; - - switch (ab8500_gpio->irq_action) { - case STARTUP: - if (rising) - ret = request_threaded_irq(irq_to_rising(irq), - NULL, handle_rising, - IRQF_TRIGGER_RISING, - "ab8500-gpio-r", ab8500_gpio); - if (falling) - ret = request_threaded_irq(irq_to_falling(irq), - NULL, handle_falling, - IRQF_TRIGGER_FALLING, - "ab8500-gpio-f", ab8500_gpio); - break; - case SHUTDOWN: - if (rising) - free_irq(irq_to_rising(irq), ab8500_gpio); - if (falling) - free_irq(irq_to_falling(irq), ab8500_gpio); - break; - case MASK: - if (rising) - disable_irq(irq_to_rising(irq)); - if (falling) - disable_irq(irq_to_falling(irq)); - break; - case UNMASK: - if (rising) - enable_irq(irq_to_rising(irq)); - if (falling) - enable_irq(irq_to_falling(irq)); - break; - case NONE: - break; - } - ab8500_gpio->irq_action = NONE; - ab8500_gpio->rising &= ~(BIT(offset)); - ab8500_gpio->falling &= ~(BIT(offset)); - mutex_unlock(&ab8500_gpio->lock); -} - - -static void ab8500_gpio_irq_mask(unsigned int irq) -{ - struct ab8500_gpio *ab8500_gpio = get_irq_chip_data(irq); - ab8500_gpio->irq_action = MASK; -} - -static void ab8500_gpio_irq_unmask(unsigned int irq) -{ - struct ab8500_gpio *ab8500_gpio = get_irq_chip_data(irq); - ab8500_gpio->irq_action = UNMASK; -} - -static int ab8500_gpio_irq_set_type(unsigned int irq, unsigned int type) -{ - struct ab8500_gpio *ab8500_gpio = get_irq_chip_data(irq); - int offset = irq - ab8500_gpio->irq_base; - - if (type == IRQ_TYPE_EDGE_BOTH) { - ab8500_gpio->rising = BIT(offset); - ab8500_gpio->falling = BIT(offset); - } else if (type == IRQ_TYPE_EDGE_RISING) { - ab8500_gpio->rising = BIT(offset); - } else { - ab8500_gpio->falling = BIT(offset); - } - return 0; -} - -unsigned int ab8500_gpio_irq_startup(unsigned int irq) -{ - struct ab8500_gpio *ab8500_gpio = get_irq_chip_data(irq); - ab8500_gpio->irq_action = STARTUP; - return 0; -} - -void ab8500_gpio_irq_shutdown(unsigned int irq) -{ - struct ab8500_gpio *ab8500_gpio = get_irq_chip_data(irq); - ab8500_gpio->irq_action = SHUTDOWN; -} - -static struct irq_chip ab8500_gpio_irq_chip = { - .name = "ab8500-gpio", - .startup = ab8500_gpio_irq_startup, - .shutdown = ab8500_gpio_irq_shutdown, - .bus_lock = ab8500_gpio_irq_lock, - .bus_sync_unlock = ab8500_gpio_irq_sync_unlock, - .mask = ab8500_gpio_irq_mask, - .unmask = ab8500_gpio_irq_unmask, - .set_type = ab8500_gpio_irq_set_type, -}; - -static int ab8500_gpio_irq_init(struct ab8500_gpio *ab8500_gpio) -{ - u32 base = ab8500_gpio->irq_base; - int irq; - - for (irq = base; irq < base + AB8500_NUM_VIR_GPIO_IRQ ; irq++) { - set_irq_chip_data(irq, ab8500_gpio); - set_irq_chip_and_handler(irq, &ab8500_gpio_irq_chip, - handle_simple_irq); - set_irq_nested_thread(irq, 1); -#ifdef CONFIG_ARM - set_irq_flags(irq, IRQF_VALID); -#else - set_irq_noprobe(irq); -#endif - } - - return 0; -} - -static void ab8500_gpio_irq_remove(struct ab8500_gpio *ab8500_gpio) -{ - int base = ab8500_gpio->irq_base; - int irq; - - for (irq = base; irq < base + AB8500_NUM_VIR_GPIO_IRQ; irq++) { -#ifdef CONFIG_ARM - set_irq_flags(irq, 0); -#endif - set_irq_chip_and_handler(irq, NULL, NULL); - set_irq_chip_data(irq, NULL); - } -} - -static int __devinit ab8500_gpio_probe(struct platform_device *pdev) -{ - struct ab8500_platform_data *ab8500_pdata = - dev_get_platdata(pdev->dev.parent); - struct ab8500_gpio_platform_data *pdata; - struct ab8500_gpio *ab8500_gpio; - int ret; - int i; - - pdata = ab8500_pdata->gpio; - if (!pdata) { - dev_err(&pdev->dev, "gpio platform data missing\n"); - return -ENODEV; - } - - ab8500_gpio = kzalloc(sizeof(struct ab8500_gpio), GFP_KERNEL); - if (ab8500_gpio == NULL) { - dev_err(&pdev->dev, "failed to allocate memory\n"); - return -ENOMEM; - } - ab8500_gpio->dev = &pdev->dev; - ab8500_gpio->parent = dev_get_drvdata(pdev->dev.parent); - ab8500_gpio->chip = ab8500gpio_chip; - ab8500_gpio->chip.ngpio = AB8500_NUM_GPIO; - ab8500_gpio->chip.dev = &pdev->dev; - ab8500_gpio->chip.base = pdata->gpio_base; - ab8500_gpio->irq_base = pdata->irq_base; - /* initialize the lock */ - mutex_init(&ab8500_gpio->lock); - /* - * AB8500 core will handle and clear the IRQ - * configre GPIO based on config-reg value. - * These values are for selecting the PINs as - * GPIO or alternate function - */ - for (i = AB8500_GPIO_SEL1_REG; i <= AB8500_GPIO_SEL6_REG; i++) { - ret = abx500_set_register_interruptible(ab8500_gpio->dev, - AB8500_MISC, i, - pdata->config_reg[i]); - if (ret < 0) - goto out_free; - } - ret = abx500_set_register_interruptible(ab8500_gpio->dev, AB8500_MISC, - AB8500_GPIO_ALTFUN_REG, - pdata->config_reg[ALTFUN_REG_INDEX]); - if (ret < 0) - goto out_free; - - ret = ab8500_gpio_irq_init(ab8500_gpio); - if (ret) - goto out_free; - ret = gpiochip_add(&ab8500_gpio->chip); - if (ret) { - dev_err(&pdev->dev, "unable to add gpiochip: %d\n", - ret); - goto out_rem_irq; - } - platform_set_drvdata(pdev, ab8500_gpio); - return 0; - -out_rem_irq: - ab8500_gpio_irq_remove(ab8500_gpio); -out_free: - mutex_destroy(&ab8500_gpio->lock); - kfree(ab8500_gpio); - return ret; -} - -/* - * ab8500_gpio_remove() - remove Ab8500-gpio driver - * @pdev : Platform device registered - */ -static int __devexit ab8500_gpio_remove(struct platform_device *pdev) -{ - struct ab8500_gpio *ab8500_gpio = platform_get_drvdata(pdev); - int ret; - - ret = gpiochip_remove(&ab8500_gpio->chip); - if (ret < 0) { - dev_err(ab8500_gpio->dev, "unable to remove gpiochip:\ - %d\n", ret); - return ret; - } - - platform_set_drvdata(pdev, NULL); - mutex_destroy(&ab8500_gpio->lock); - kfree(ab8500_gpio); - - return 0; -} - -static struct platform_driver ab8500_gpio_driver = { - .driver = { - .name = "ab8500-gpio", - .owner = THIS_MODULE, - }, - .probe = ab8500_gpio_probe, - .remove = __devexit_p(ab8500_gpio_remove), -}; - -static int __init ab8500_gpio_init(void) -{ - return platform_driver_register(&ab8500_gpio_driver); -} -arch_initcall(ab8500_gpio_init); - -static void __exit ab8500_gpio_exit(void) -{ - platform_driver_unregister(&ab8500_gpio_driver); -} -module_exit(ab8500_gpio_exit); - -MODULE_AUTHOR("BIBEK BASU "); -MODULE_DESCRIPTION("Driver allows to use AB8500 unused pins\ - to be used as GPIO"); -MODULE_ALIAS("AB8500 GPIO driver"); -MODULE_LICENSE("GPL v2"); diff --git a/trunk/drivers/hwmon/Kconfig b/trunk/drivers/hwmon/Kconfig index 060ef6327876..81131eda5544 100644 --- a/trunk/drivers/hwmon/Kconfig +++ b/trunk/drivers/hwmon/Kconfig @@ -315,22 +315,11 @@ config SENSORS_F71805F will be called f71805f. config SENSORS_F71882FG - tristate "Fintek F71882FG and compatibles" + tristate "Fintek F71858FG, F71862FG, F71882FG, F71889FG and F8000" help If you say yes here you get support for hardware monitoring - features of many Fintek Super-I/O (LPC) chips. The currently - supported chips are: - F71808E - F71858FG - F71862FG - F71863FG - F71869F/E - F71882FG - F71883FG - F71889FG/ED/A - F8000 - F81801U - F81865F + features of the Fintek F71858FG, F71862FG/71863FG, F71882FG/F71883FG, + F71889FG and F8000 Super-I/O chips. This driver can also be built as a module. If so, the module will be called f71882fg. diff --git a/trunk/drivers/hwmon/f71882fg.c b/trunk/drivers/hwmon/f71882fg.c index ca07a32447c2..a4d430ee7e20 100644 --- a/trunk/drivers/hwmon/f71882fg.c +++ b/trunk/drivers/hwmon/f71882fg.c @@ -54,9 +54,7 @@ #define SIO_F71882_ID 0x0541 /* Chipset ID */ #define SIO_F71889_ID 0x0723 /* Chipset ID */ #define SIO_F71889E_ID 0x0909 /* Chipset ID */ -#define SIO_F71889A_ID 0x1005 /* Chipset ID */ #define SIO_F8000_ID 0x0581 /* Chipset ID */ -#define SIO_F81865_ID 0x0704 /* Chipset ID */ #define REGION_LENGTH 8 #define ADDR_REG_OFFSET 5 @@ -108,7 +106,7 @@ module_param(force_id, ushort, 0); MODULE_PARM_DESC(force_id, "Override the detected device ID"); enum chips { f71808e, f71858fg, f71862fg, f71869, f71882fg, f71889fg, - f71889ed, f71889a, f8000, f81865f }; + f71889ed, f8000 }; static const char *f71882fg_names[] = { "f71808e", @@ -116,76 +114,42 @@ static const char *f71882fg_names[] = { "f71862fg", "f71869", /* Both f71869f and f71869e, reg. compatible and same id */ "f71882fg", - "f71889fg", /* f81801u too, same id */ + "f71889fg", "f71889ed", - "f71889a", "f8000", - "f81865f", }; -static const char f71882fg_has_in[][F71882FG_MAX_INS] = { - [f71808e] = { 1, 1, 1, 1, 1, 1, 0, 1, 1 }, - [f71858fg] = { 1, 1, 1, 0, 0, 0, 0, 0, 0 }, - [f71862fg] = { 1, 1, 1, 1, 1, 1, 1, 1, 1 }, - [f71869] = { 1, 1, 1, 1, 1, 1, 1, 1, 1 }, - [f71882fg] = { 1, 1, 1, 1, 1, 1, 1, 1, 1 }, - [f71889fg] = { 1, 1, 1, 1, 1, 1, 1, 1, 1 }, - [f71889ed] = { 1, 1, 1, 1, 1, 1, 1, 1, 1 }, - [f71889a] = { 1, 1, 1, 1, 1, 1, 1, 1, 1 }, - [f8000] = { 1, 1, 1, 0, 0, 0, 0, 0, 0 }, - [f81865f] = { 1, 1, 1, 1, 1, 1, 1, 0, 0 }, +static const char f71882fg_has_in[8][F71882FG_MAX_INS] = { + { 1, 1, 1, 1, 1, 1, 0, 1, 1 }, /* f71808e */ + { 1, 1, 1, 0, 0, 0, 0, 0, 0 }, /* f71858fg */ + { 1, 1, 1, 1, 1, 1, 1, 1, 1 }, /* f71862fg */ + { 1, 1, 1, 1, 1, 1, 1, 1, 1 }, /* f71869 */ + { 1, 1, 1, 1, 1, 1, 1, 1, 1 }, /* f71882fg */ + { 1, 1, 1, 1, 1, 1, 1, 1, 1 }, /* f71889fg */ + { 1, 1, 1, 1, 1, 1, 1, 1, 1 }, /* f71889ed */ + { 1, 1, 1, 0, 0, 0, 0, 0, 0 }, /* f8000 */ }; -static const char f71882fg_has_in1_alarm[] = { - [f71808e] = 0, - [f71858fg] = 0, - [f71862fg] = 0, - [f71869] = 0, - [f71882fg] = 1, - [f71889fg] = 1, - [f71889ed] = 1, - [f71889a] = 1, - [f8000] = 0, - [f81865f] = 1, +static const char f71882fg_has_in1_alarm[8] = { + 0, /* f71808e */ + 0, /* f71858fg */ + 0, /* f71862fg */ + 0, /* f71869 */ + 1, /* f71882fg */ + 1, /* f71889fg */ + 1, /* f71889ed */ + 0, /* f8000 */ }; -static const char f71882fg_has_beep[] = { - [f71808e] = 0, - [f71858fg] = 0, - [f71862fg] = 1, - [f71869] = 1, - [f71882fg] = 1, - [f71889fg] = 1, - [f71889ed] = 1, - [f71889a] = 1, - [f8000] = 0, - [f81865f] = 1, -}; - -static const char f71882fg_nr_fans[] = { - [f71808e] = 3, - [f71858fg] = 3, - [f71862fg] = 3, - [f71869] = 3, - [f71882fg] = 4, - [f71889fg] = 3, - [f71889ed] = 3, - [f71889a] = 3, - [f8000] = 3, - [f81865f] = 2, -}; - -static const char f71882fg_nr_temps[] = { - [f71808e] = 2, - [f71858fg] = 3, - [f71862fg] = 3, - [f71869] = 3, - [f71882fg] = 3, - [f71889fg] = 3, - [f71889ed] = 3, - [f71889a] = 3, - [f8000] = 3, - [f81865f] = 2, +static const char f71882fg_has_beep[8] = { + 0, /* f71808e */ + 0, /* f71858fg */ + 1, /* f71862fg */ + 1, /* f71869 */ + 1, /* f71882fg */ + 1, /* f71889fg */ + 1, /* f71889ed */ + 0, /* f8000 */ }; static struct platform_device *f71882fg_pdev; @@ -1107,9 +1071,9 @@ static u16 f71882fg_read_temp(struct f71882fg_data *data, int nr) static struct f71882fg_data *f71882fg_update_device(struct device *dev) { struct f71882fg_data *data = dev_get_drvdata(dev); - int nr_fans = f71882fg_nr_fans[data->type]; - int nr_temps = f71882fg_nr_temps[data->type]; int nr, reg, point; + int nr_fans = (data->type == f71882fg) ? 4 : 3; + int nr_temps = (data->type == f71808e) ? 2 : 3; mutex_lock(&data->update_lock); @@ -2078,9 +2042,8 @@ static int __devinit f71882fg_probe(struct platform_device *pdev) { struct f71882fg_data *data; struct f71882fg_sio_data *sio_data = pdev->dev.platform_data; - int nr_fans = f71882fg_nr_fans[sio_data->type]; - int nr_temps = f71882fg_nr_temps[sio_data->type]; - int err, i; + int err, i, nr_fans = (sio_data->type == f71882fg) ? 4 : 3; + int nr_temps = (sio_data->type == f71808e) ? 2 : 3; u8 start_reg, reg; data = kzalloc(sizeof(struct f71882fg_data), GFP_KERNEL); @@ -2175,7 +2138,6 @@ static int __devinit f71882fg_probe(struct platform_device *pdev) /* Fall through to select correct fan/pwm reg bank! */ case f71889fg: case f71889ed: - case f71889a: reg = f71882fg_read8(data, F71882FG_REG_FAN_FAULT_T); if (reg & F71882FG_FAN_NEG_TEMP_EN) data->auto_point_temp_signed = 1; @@ -2201,12 +2163,16 @@ static int __devinit f71882fg_probe(struct platform_device *pdev) case f71862fg: err = (data->pwm_enable & 0x15) != 0x15; break; + case f71808e: + case f71869: + case f71882fg: + case f71889fg: + case f71889ed: + err = 0; + break; case f8000: err = data->pwm_enable & 0x20; break; - default: - err = 0; - break; } if (err) { dev_err(&pdev->dev, @@ -2233,7 +2199,6 @@ static int __devinit f71882fg_probe(struct platform_device *pdev) case f71869: case f71889fg: case f71889ed: - case f71889a: for (i = 0; i < nr_fans; i++) { data->pwm_auto_point_mapping[i] = f71882fg_read8(data, @@ -2311,9 +2276,8 @@ static int __devinit f71882fg_probe(struct platform_device *pdev) static int f71882fg_remove(struct platform_device *pdev) { struct f71882fg_data *data = platform_get_drvdata(pdev); - int nr_fans = f71882fg_nr_fans[data->type]; - int nr_temps = f71882fg_nr_temps[data->type]; - int i; + int i, nr_fans = (data->type == f71882fg) ? 4 : 3; + int nr_temps = (data->type == f71808e) ? 2 : 3; u8 start_reg = f71882fg_read8(data, F71882FG_REG_START); if (data->hwmon_dev) @@ -2442,15 +2406,9 @@ static int __init f71882fg_find(int sioaddr, unsigned short *address, case SIO_F71889E_ID: sio_data->type = f71889ed; break; - case SIO_F71889A_ID: - sio_data->type = f71889a; - break; case SIO_F8000_ID: sio_data->type = f8000; break; - case SIO_F81865_ID: - sio_data->type = f81865f; - break; default: pr_info("Unsupported Fintek device: %04x\n", (unsigned int)devid); diff --git a/trunk/drivers/hwmon/gpio-fan.c b/trunk/drivers/hwmon/gpio-fan.c index 89aa9fb743af..f141a1de519c 100644 --- a/trunk/drivers/hwmon/gpio-fan.c +++ b/trunk/drivers/hwmon/gpio-fan.c @@ -116,7 +116,7 @@ static int fan_alarm_init(struct gpio_fan_data *fan_data, return 0; INIT_WORK(&fan_data->alarm_work, fan_alarm_notify); - irq_set_irq_type(alarm_irq, IRQ_TYPE_EDGE_BOTH); + set_irq_type(alarm_irq, IRQ_TYPE_EDGE_BOTH); err = request_irq(alarm_irq, fan_alarm_irq_handler, IRQF_SHARED, "GPIO fan alarm", fan_data); if (err) diff --git a/trunk/drivers/hwmon/pmbus_core.c b/trunk/drivers/hwmon/pmbus_core.c index edfb92e41735..6474512f49b0 100644 --- a/trunk/drivers/hwmon/pmbus_core.c +++ b/trunk/drivers/hwmon/pmbus_core.c @@ -752,7 +752,7 @@ static void pmbus_add_boolean_cmp(struct pmbus_data *data, static void pmbus_add_sensor(struct pmbus_data *data, const char *name, const char *type, int seq, int page, int reg, enum pmbus_sensor_classes class, - bool update, bool readonly) + bool update) { struct pmbus_sensor *sensor; @@ -765,7 +765,7 @@ static void pmbus_add_sensor(struct pmbus_data *data, sensor->reg = reg; sensor->class = class; sensor->update = update; - if (readonly) + if (update) PMBUS_ADD_GET_ATTR(data, sensor->name, sensor, data->num_sensors); else @@ -916,14 +916,14 @@ static void pmbus_find_attributes(struct i2c_client *client, i0 = data->num_sensors; pmbus_add_label(data, "in", in_index, "vin", 0); - pmbus_add_sensor(data, "in", "input", in_index, 0, - PMBUS_READ_VIN, PSC_VOLTAGE_IN, true, true); + pmbus_add_sensor(data, "in", "input", in_index, + 0, PMBUS_READ_VIN, PSC_VOLTAGE_IN, true); if (pmbus_check_word_register(client, 0, PMBUS_VIN_UV_WARN_LIMIT)) { i1 = data->num_sensors; pmbus_add_sensor(data, "in", "min", in_index, 0, PMBUS_VIN_UV_WARN_LIMIT, - PSC_VOLTAGE_IN, false, false); + PSC_VOLTAGE_IN, false); if (info->func[0] & PMBUS_HAVE_STATUS_INPUT) { pmbus_add_boolean_reg(data, "in", "min_alarm", in_index, @@ -937,7 +937,7 @@ static void pmbus_find_attributes(struct i2c_client *client, i1 = data->num_sensors; pmbus_add_sensor(data, "in", "lcrit", in_index, 0, PMBUS_VIN_UV_FAULT_LIMIT, - PSC_VOLTAGE_IN, false, false); + PSC_VOLTAGE_IN, false); if (info->func[0] & PMBUS_HAVE_STATUS_INPUT) { pmbus_add_boolean_reg(data, "in", "lcrit_alarm", in_index, @@ -951,7 +951,7 @@ static void pmbus_find_attributes(struct i2c_client *client, i1 = data->num_sensors; pmbus_add_sensor(data, "in", "max", in_index, 0, PMBUS_VIN_OV_WARN_LIMIT, - PSC_VOLTAGE_IN, false, false); + PSC_VOLTAGE_IN, false); if (info->func[0] & PMBUS_HAVE_STATUS_INPUT) { pmbus_add_boolean_reg(data, "in", "max_alarm", in_index, @@ -965,7 +965,7 @@ static void pmbus_find_attributes(struct i2c_client *client, i1 = data->num_sensors; pmbus_add_sensor(data, "in", "crit", in_index, 0, PMBUS_VIN_OV_FAULT_LIMIT, - PSC_VOLTAGE_IN, false, false); + PSC_VOLTAGE_IN, false); if (info->func[0] & PMBUS_HAVE_STATUS_INPUT) { pmbus_add_boolean_reg(data, "in", "crit_alarm", in_index, @@ -988,7 +988,7 @@ static void pmbus_find_attributes(struct i2c_client *client, if (info->func[0] & PMBUS_HAVE_VCAP) { pmbus_add_label(data, "in", in_index, "vcap", 0); pmbus_add_sensor(data, "in", "input", in_index, 0, - PMBUS_READ_VCAP, PSC_VOLTAGE_IN, true, true); + PMBUS_READ_VCAP, PSC_VOLTAGE_IN, true); in_index++; } @@ -1004,13 +1004,13 @@ static void pmbus_find_attributes(struct i2c_client *client, i0 = data->num_sensors; pmbus_add_label(data, "in", in_index, "vout", page + 1); pmbus_add_sensor(data, "in", "input", in_index, page, - PMBUS_READ_VOUT, PSC_VOLTAGE_OUT, true, true); + PMBUS_READ_VOUT, PSC_VOLTAGE_OUT, true); if (pmbus_check_word_register(client, page, PMBUS_VOUT_UV_WARN_LIMIT)) { i1 = data->num_sensors; pmbus_add_sensor(data, "in", "min", in_index, page, PMBUS_VOUT_UV_WARN_LIMIT, - PSC_VOLTAGE_OUT, false, false); + PSC_VOLTAGE_OUT, false); if (info->func[page] & PMBUS_HAVE_STATUS_VOUT) { pmbus_add_boolean_reg(data, "in", "min_alarm", in_index, @@ -1025,7 +1025,7 @@ static void pmbus_find_attributes(struct i2c_client *client, i1 = data->num_sensors; pmbus_add_sensor(data, "in", "lcrit", in_index, page, PMBUS_VOUT_UV_FAULT_LIMIT, - PSC_VOLTAGE_OUT, false, false); + PSC_VOLTAGE_OUT, false); if (info->func[page] & PMBUS_HAVE_STATUS_VOUT) { pmbus_add_boolean_reg(data, "in", "lcrit_alarm", in_index, @@ -1040,7 +1040,7 @@ static void pmbus_find_attributes(struct i2c_client *client, i1 = data->num_sensors; pmbus_add_sensor(data, "in", "max", in_index, page, PMBUS_VOUT_OV_WARN_LIMIT, - PSC_VOLTAGE_OUT, false, false); + PSC_VOLTAGE_OUT, false); if (info->func[page] & PMBUS_HAVE_STATUS_VOUT) { pmbus_add_boolean_reg(data, "in", "max_alarm", in_index, @@ -1055,7 +1055,7 @@ static void pmbus_find_attributes(struct i2c_client *client, i1 = data->num_sensors; pmbus_add_sensor(data, "in", "crit", in_index, page, PMBUS_VOUT_OV_FAULT_LIMIT, - PSC_VOLTAGE_OUT, false, false); + PSC_VOLTAGE_OUT, false); if (info->func[page] & PMBUS_HAVE_STATUS_VOUT) { pmbus_add_boolean_reg(data, "in", "crit_alarm", in_index, @@ -1088,14 +1088,14 @@ static void pmbus_find_attributes(struct i2c_client *client, if (info->func[0] & PMBUS_HAVE_IIN) { i0 = data->num_sensors; pmbus_add_label(data, "curr", in_index, "iin", 0); - pmbus_add_sensor(data, "curr", "input", in_index, 0, - PMBUS_READ_IIN, PSC_CURRENT_IN, true, true); + pmbus_add_sensor(data, "curr", "input", in_index, + 0, PMBUS_READ_IIN, PSC_CURRENT_IN, true); if (pmbus_check_word_register(client, 0, PMBUS_IIN_OC_WARN_LIMIT)) { i1 = data->num_sensors; pmbus_add_sensor(data, "curr", "max", in_index, 0, PMBUS_IIN_OC_WARN_LIMIT, - PSC_CURRENT_IN, false, false); + PSC_CURRENT_IN, false); if (info->func[0] & PMBUS_HAVE_STATUS_INPUT) { pmbus_add_boolean_reg(data, "curr", "max_alarm", in_index, @@ -1108,7 +1108,7 @@ static void pmbus_find_attributes(struct i2c_client *client, i1 = data->num_sensors; pmbus_add_sensor(data, "curr", "crit", in_index, 0, PMBUS_IIN_OC_FAULT_LIMIT, - PSC_CURRENT_IN, false, false); + PSC_CURRENT_IN, false); if (info->func[0] & PMBUS_HAVE_STATUS_INPUT) pmbus_add_boolean_reg(data, "curr", "crit_alarm", @@ -1131,13 +1131,13 @@ static void pmbus_find_attributes(struct i2c_client *client, i0 = data->num_sensors; pmbus_add_label(data, "curr", in_index, "iout", page + 1); pmbus_add_sensor(data, "curr", "input", in_index, page, - PMBUS_READ_IOUT, PSC_CURRENT_OUT, true, true); + PMBUS_READ_IOUT, PSC_CURRENT_OUT, true); if (pmbus_check_word_register(client, page, PMBUS_IOUT_OC_WARN_LIMIT)) { i1 = data->num_sensors; pmbus_add_sensor(data, "curr", "max", in_index, page, PMBUS_IOUT_OC_WARN_LIMIT, - PSC_CURRENT_OUT, false, false); + PSC_CURRENT_OUT, false); if (info->func[page] & PMBUS_HAVE_STATUS_IOUT) { pmbus_add_boolean_reg(data, "curr", "max_alarm", in_index, @@ -1151,7 +1151,7 @@ static void pmbus_find_attributes(struct i2c_client *client, i1 = data->num_sensors; pmbus_add_sensor(data, "curr", "lcrit", in_index, page, PMBUS_IOUT_UC_FAULT_LIMIT, - PSC_CURRENT_OUT, false, false); + PSC_CURRENT_OUT, false); if (info->func[page] & PMBUS_HAVE_STATUS_IOUT) { pmbus_add_boolean_reg(data, "curr", "lcrit_alarm", @@ -1166,7 +1166,7 @@ static void pmbus_find_attributes(struct i2c_client *client, i1 = data->num_sensors; pmbus_add_sensor(data, "curr", "crit", in_index, page, PMBUS_IOUT_OC_FAULT_LIMIT, - PSC_CURRENT_OUT, false, false); + PSC_CURRENT_OUT, false); if (info->func[page] & PMBUS_HAVE_STATUS_IOUT) { pmbus_add_boolean_reg(data, "curr", "crit_alarm", @@ -1199,13 +1199,13 @@ static void pmbus_find_attributes(struct i2c_client *client, i0 = data->num_sensors; pmbus_add_label(data, "power", in_index, "pin", 0); pmbus_add_sensor(data, "power", "input", in_index, - 0, PMBUS_READ_PIN, PSC_POWER, true, true); + 0, PMBUS_READ_PIN, PSC_POWER, true); if (pmbus_check_word_register(client, 0, PMBUS_PIN_OP_WARN_LIMIT)) { i1 = data->num_sensors; pmbus_add_sensor(data, "power", "max", in_index, 0, PMBUS_PIN_OP_WARN_LIMIT, PSC_POWER, - false, false); + false); if (info->func[0] & PMBUS_HAVE_STATUS_INPUT) pmbus_add_boolean_reg(data, "power", "alarm", @@ -1228,7 +1228,7 @@ static void pmbus_find_attributes(struct i2c_client *client, i0 = data->num_sensors; pmbus_add_label(data, "power", in_index, "pout", page + 1); pmbus_add_sensor(data, "power", "input", in_index, page, - PMBUS_READ_POUT, PSC_POWER, true, true); + PMBUS_READ_POUT, PSC_POWER, true); /* * Per hwmon sysfs API, power_cap is to be used to limit output * power. @@ -1241,8 +1241,7 @@ static void pmbus_find_attributes(struct i2c_client *client, if (pmbus_check_word_register(client, page, PMBUS_POUT_MAX)) { i1 = data->num_sensors; pmbus_add_sensor(data, "power", "cap", in_index, page, - PMBUS_POUT_MAX, PSC_POWER, - false, false); + PMBUS_POUT_MAX, PSC_POWER, false); need_alarm = true; } if (pmbus_check_word_register(client, page, @@ -1250,7 +1249,7 @@ static void pmbus_find_attributes(struct i2c_client *client, i1 = data->num_sensors; pmbus_add_sensor(data, "power", "max", in_index, page, PMBUS_POUT_OP_WARN_LIMIT, PSC_POWER, - false, false); + false); need_alarm = true; } if (need_alarm && (info->func[page] & PMBUS_HAVE_STATUS_IOUT)) @@ -1265,7 +1264,7 @@ static void pmbus_find_attributes(struct i2c_client *client, i1 = data->num_sensors; pmbus_add_sensor(data, "power", "crit", in_index, page, PMBUS_POUT_OP_FAULT_LIMIT, PSC_POWER, - false, false); + false); if (info->func[page] & PMBUS_HAVE_STATUS_IOUT) pmbus_add_boolean_reg(data, "power", "crit_alarm", @@ -1303,7 +1302,7 @@ static void pmbus_find_attributes(struct i2c_client *client, i0 = data->num_sensors; pmbus_add_sensor(data, "temp", "input", in_index, page, pmbus_temp_registers[t], - PSC_TEMPERATURE, true, true); + PSC_TEMPERATURE, true); /* * PMBus provides only one status register for TEMP1-3. @@ -1324,7 +1323,7 @@ static void pmbus_find_attributes(struct i2c_client *client, i1 = data->num_sensors; pmbus_add_sensor(data, "temp", "min", in_index, page, PMBUS_UT_WARN_LIMIT, - PSC_TEMPERATURE, true, false); + PSC_TEMPERATURE, true); if (info->func[page] & PMBUS_HAVE_STATUS_TEMP) { pmbus_add_boolean_cmp(data, "temp", "min_alarm", in_index, i1, i0, @@ -1339,7 +1338,7 @@ static void pmbus_find_attributes(struct i2c_client *client, pmbus_add_sensor(data, "temp", "lcrit", in_index, page, PMBUS_UT_FAULT_LIMIT, - PSC_TEMPERATURE, true, false); + PSC_TEMPERATURE, true); if (info->func[page] & PMBUS_HAVE_STATUS_TEMP) { pmbus_add_boolean_cmp(data, "temp", "lcrit_alarm", in_index, i1, i0, @@ -1353,7 +1352,7 @@ static void pmbus_find_attributes(struct i2c_client *client, i1 = data->num_sensors; pmbus_add_sensor(data, "temp", "max", in_index, page, PMBUS_OT_WARN_LIMIT, - PSC_TEMPERATURE, true, false); + PSC_TEMPERATURE, true); if (info->func[page] & PMBUS_HAVE_STATUS_TEMP) { pmbus_add_boolean_cmp(data, "temp", "max_alarm", in_index, i0, i1, @@ -1367,7 +1366,7 @@ static void pmbus_find_attributes(struct i2c_client *client, i1 = data->num_sensors; pmbus_add_sensor(data, "temp", "crit", in_index, page, PMBUS_OT_FAULT_LIMIT, - PSC_TEMPERATURE, true, false); + PSC_TEMPERATURE, true); if (info->func[page] & PMBUS_HAVE_STATUS_TEMP) { pmbus_add_boolean_cmp(data, "temp", "crit_alarm", in_index, i0, i1, @@ -1422,8 +1421,7 @@ static void pmbus_find_attributes(struct i2c_client *client, i0 = data->num_sensors; pmbus_add_sensor(data, "fan", "input", in_index, page, - pmbus_fan_registers[f], PSC_FAN, true, - true); + pmbus_fan_registers[f], PSC_FAN, true); /* * Each fan status register covers multiple fans, diff --git a/trunk/drivers/hwspinlock/Kconfig b/trunk/drivers/hwspinlock/Kconfig index 1f29bab6b3e5..eb4af28f8567 100644 --- a/trunk/drivers/hwspinlock/Kconfig +++ b/trunk/drivers/hwspinlock/Kconfig @@ -4,7 +4,6 @@ config HWSPINLOCK tristate "Generic Hardware Spinlock framework" - depends on ARCH_OMAP4 help Say y here to support the generic hardware spinlock framework. You only need to enable this if you have hardware spinlock module diff --git a/trunk/drivers/ide/ide-io.c b/trunk/drivers/ide/ide-io.c index 0e406d73b2c8..f4077840d3ab 100644 --- a/trunk/drivers/ide/ide-io.c +++ b/trunk/drivers/ide/ide-io.c @@ -440,7 +440,6 @@ void do_ide_request(struct request_queue *q) struct ide_host *host = hwif->host; struct request *rq = NULL; ide_startstop_t startstop; - unsigned long queue_run_ms = 3; /* old plug delay */ spin_unlock_irq(q->queue_lock); @@ -460,9 +459,6 @@ void do_ide_request(struct request_queue *q) prev_port = hwif->host->cur_port; if (drive->dev_flags & IDE_DFLAG_SLEEPING && time_after(drive->sleep, jiffies)) { - unsigned long left = jiffies - drive->sleep; - - queue_run_ms = jiffies_to_msecs(left + 1); ide_unlock_port(hwif); goto plug_device; } @@ -551,10 +547,8 @@ void do_ide_request(struct request_queue *q) plug_device_2: spin_lock_irq(q->queue_lock); - if (rq) { + if (rq) blk_requeue_request(q, rq); - blk_delay_queue(q, queue_run_ms); - } } void ide_requeue_and_plug(ide_drive_t *drive, struct request *rq) @@ -568,10 +562,6 @@ void ide_requeue_and_plug(ide_drive_t *drive, struct request *rq) blk_requeue_request(q, rq); spin_unlock_irqrestore(q->queue_lock, flags); - - /* Use 3ms as that was the old plug delay */ - if (rq) - blk_delay_queue(q, 3); } static int drive_is_ready(ide_drive_t *drive) diff --git a/trunk/drivers/input/keyboard/lm8323.c b/trunk/drivers/input/keyboard/lm8323.c index 71f744a8e686..b732870ecc89 100644 --- a/trunk/drivers/input/keyboard/lm8323.c +++ b/trunk/drivers/input/keyboard/lm8323.c @@ -809,7 +809,7 @@ static int lm8323_suspend(struct device *dev) struct lm8323_chip *lm = i2c_get_clientdata(client); int i; - irq_set_irq_wake(client->irq, 0); + set_irq_wake(client->irq, 0); disable_irq(client->irq); mutex_lock(&lm->lock); @@ -838,7 +838,7 @@ static int lm8323_resume(struct device *dev) led_classdev_resume(&lm->pwm[i].cdev); enable_irq(client->irq); - irq_set_irq_wake(client->irq, 1); + set_irq_wake(client->irq, 1); return 0; } diff --git a/trunk/drivers/input/serio/ams_delta_serio.c b/trunk/drivers/input/serio/ams_delta_serio.c index 4b2a42f9f0bb..ebe955325677 100644 --- a/trunk/drivers/input/serio/ams_delta_serio.c +++ b/trunk/drivers/input/serio/ams_delta_serio.c @@ -149,7 +149,7 @@ static int __init ams_delta_serio_init(void) * at FIQ level, switch back from edge to simple interrupt handler * to avoid bad interaction. */ - irq_set_handler(gpio_to_irq(AMS_DELTA_GPIO_PIN_KEYBRD_CLK), + set_irq_handler(gpio_to_irq(AMS_DELTA_GPIO_PIN_KEYBRD_CLK), handle_simple_irq); serio_register_port(ams_delta_serio); diff --git a/trunk/drivers/input/touchscreen/mainstone-wm97xx.c b/trunk/drivers/input/touchscreen/mainstone-wm97xx.c index 3242e7076258..b6b8b1c7ecea 100644 --- a/trunk/drivers/input/touchscreen/mainstone-wm97xx.c +++ b/trunk/drivers/input/touchscreen/mainstone-wm97xx.c @@ -219,7 +219,7 @@ static int wm97xx_acc_startup(struct wm97xx *wm) } wm->pen_irq = gpio_to_irq(irq); - irq_set_irq_type(wm->pen_irq, IRQ_TYPE_EDGE_BOTH); + set_irq_type(wm->pen_irq, IRQ_TYPE_EDGE_BOTH); } else /* pen irq not supported */ pen_int = 0; diff --git a/trunk/drivers/input/touchscreen/zylonite-wm97xx.c b/trunk/drivers/input/touchscreen/zylonite-wm97xx.c index 5b0f15ec874a..048849867643 100644 --- a/trunk/drivers/input/touchscreen/zylonite-wm97xx.c +++ b/trunk/drivers/input/touchscreen/zylonite-wm97xx.c @@ -193,7 +193,7 @@ static int zylonite_wm97xx_probe(struct platform_device *pdev) gpio_touch_irq = mfp_to_gpio(MFP_PIN_GPIO26); wm->pen_irq = IRQ_GPIO(gpio_touch_irq); - irq_set_irq_type(IRQ_GPIO(gpio_touch_irq), IRQ_TYPE_EDGE_BOTH); + set_irq_type(IRQ_GPIO(gpio_touch_irq), IRQ_TYPE_EDGE_BOTH); wm97xx_config_gpio(wm, WM97XX_GPIO_13, WM97XX_GPIO_IN, WM97XX_GPIO_POL_HIGH, diff --git a/trunk/drivers/md/md.c b/trunk/drivers/md/md.c index 8b66e04c2ea6..06ecea751a39 100644 --- a/trunk/drivers/md/md.c +++ b/trunk/drivers/md/md.c @@ -1777,6 +1777,12 @@ int md_integrity_register(mddev_t *mddev) continue; if (rdev->raid_disk < 0) continue; + /* + * If at least one rdev is not integrity capable, we can not + * enable data integrity for the md device. + */ + if (!bdev_get_integrity(rdev->bdev)) + return -EINVAL; if (!reference) { /* Use the first rdev as the reference */ reference = rdev; @@ -1787,8 +1793,6 @@ int md_integrity_register(mddev_t *mddev) rdev->bdev->bd_disk) < 0) return -EINVAL; } - if (!reference || !bdev_get_integrity(reference->bdev)) - return 0; /* * All component devices are integrity capable and have matching * profiles, register the common profile for the md device. diff --git a/trunk/drivers/memstick/host/r592.c b/trunk/drivers/memstick/host/r592.c index 700d420a59ac..767406c95291 100644 --- a/trunk/drivers/memstick/host/r592.c +++ b/trunk/drivers/memstick/host/r592.c @@ -23,7 +23,7 @@ #include #include "r592.h" -static int r592_enable_dma = 1; +static int enable_dma = 1; static int debug; static const char *tpc_names[] = { @@ -267,7 +267,7 @@ static void r592_stop_dma(struct r592_device *dev, int error) /* Test if hardware supports DMA */ static void r592_check_dma(struct r592_device *dev) { - dev->dma_capable = r592_enable_dma && + dev->dma_capable = enable_dma && (r592_read_reg(dev, R592_FIFO_DMA_SETTINGS) & R592_FIFO_DMA_SETTINGS_CAP); } @@ -898,7 +898,7 @@ static void __exit r592_module_exit(void) module_init(r592_module_init); module_exit(r592_module_exit); -module_param_named(enable_dma, r592_enable_dma, bool, S_IRUGO); +module_param(enable_dma, bool, S_IRUGO); MODULE_PARM_DESC(enable_dma, "Enable usage of the DMA (default)"); module_param(debug, int, S_IRUGO | S_IWUSR); MODULE_PARM_DESC(debug, "Debug level (0-3)"); diff --git a/trunk/drivers/mfd/88pm860x-core.c b/trunk/drivers/mfd/88pm860x-core.c index 011cb6ce861b..9c511c1604a5 100644 --- a/trunk/drivers/mfd/88pm860x-core.c +++ b/trunk/drivers/mfd/88pm860x-core.c @@ -416,6 +416,7 @@ static int __devinit device_irq_init(struct pm860x_chip *chip, : chip->companion; unsigned char status_buf[INT_STATUS_NUM]; unsigned long flags = IRQF_TRIGGER_FALLING | IRQF_ONESHOT; + struct irq_desc *desc; int i, data, mask, ret = -EINVAL; int __irq; @@ -467,17 +468,19 @@ static int __devinit device_irq_init(struct pm860x_chip *chip, if (!chip->core_irq) goto out; + desc = irq_to_desc(chip->core_irq); + /* register IRQ by genirq */ for (i = 0; i < ARRAY_SIZE(pm860x_irqs); i++) { __irq = i + chip->irq_base; - irq_set_chip_data(__irq, chip); - irq_set_chip_and_handler(__irq, &pm860x_irq_chip, + set_irq_chip_data(__irq, chip); + set_irq_chip_and_handler(__irq, &pm860x_irq_chip, handle_edge_irq); - irq_set_nested_thread(__irq, 1); + set_irq_nested_thread(__irq, 1); #ifdef CONFIG_ARM set_irq_flags(__irq, IRQF_VALID); #else - irq_set_noprobe(__irq); + set_irq_noprobe(__irq); #endif } diff --git a/trunk/drivers/mfd/Kconfig b/trunk/drivers/mfd/Kconfig index 9a46d64996a9..a9a1af49281e 100644 --- a/trunk/drivers/mfd/Kconfig +++ b/trunk/drivers/mfd/Kconfig @@ -133,7 +133,6 @@ config TPS6105X tristate "TPS61050/61052 Boost Converters" depends on I2C select REGULATOR - select MFD_CORE select REGULATOR_FIXED_VOLTAGE help This option enables a driver for the TP61050/TPS61052 @@ -592,7 +591,7 @@ config AB3550_CORE config MFD_CS5535 tristate "Support for CS5535 and CS5536 southbridge core functions" select MFD_CORE - depends on PCI && X86 + depends on PCI ---help--- This is the core driver for CS5535/CS5536 MFD functions. This is necessary for using the board's GPIO and MFGPT functionality. diff --git a/trunk/drivers/mfd/Makefile b/trunk/drivers/mfd/Makefile index ef489f253402..47f5709f3828 100644 --- a/trunk/drivers/mfd/Makefile +++ b/trunk/drivers/mfd/Makefile @@ -63,7 +63,7 @@ obj-$(CONFIG_UCB1400_CORE) += ucb1400_core.o obj-$(CONFIG_PMIC_DA903X) += da903x.o max8925-objs := max8925-core.o max8925-i2c.o obj-$(CONFIG_MFD_MAX8925) += max8925.o -obj-$(CONFIG_MFD_MAX8997) += max8997.o max8997-irq.o +obj-$(CONFIG_MFD_MAX8997) += max8997.o obj-$(CONFIG_MFD_MAX8998) += max8998.o max8998-irq.o pcf50633-objs := pcf50633-core.o pcf50633-irq.o diff --git a/trunk/drivers/mfd/ab3550-core.c b/trunk/drivers/mfd/ab3550-core.c index ff86acf3e6bd..c12d04285226 100644 --- a/trunk/drivers/mfd/ab3550-core.c +++ b/trunk/drivers/mfd/ab3550-core.c @@ -668,7 +668,7 @@ static int ab3550_startup_irq_enabled(struct device *dev, unsigned int irq) struct ab3550_platform_data *plf_data; bool val; - ab = irq_get_chip_data(irq); + ab = get_irq_chip_data(irq); plf_data = ab->i2c_client[0]->dev.platform_data; irq -= plf_data->irq.base; val = ((ab->startup_events[irq / 8] & BIT(irq % 8)) != 0); @@ -1296,14 +1296,14 @@ static int __init ab3550_probe(struct i2c_client *client, unsigned int irq; irq = ab3550_plf_data->irq.base + i; - irq_set_chip_data(irq, ab); - irq_set_chip_and_handler(irq, &ab3550_irq_chip, - handle_simple_irq); - irq_set_nested_thread(irq, 1); + set_irq_chip_data(irq, ab); + set_irq_chip_and_handler(irq, &ab3550_irq_chip, + handle_simple_irq); + set_irq_nested_thread(irq, 1); #ifdef CONFIG_ARM set_irq_flags(irq, IRQF_VALID); #else - irq_set_noprobe(irq); + set_irq_noprobe(irq); #endif } diff --git a/trunk/drivers/mfd/ab8500-core.c b/trunk/drivers/mfd/ab8500-core.c index 67d01c938284..6e185b272d00 100644 --- a/trunk/drivers/mfd/ab8500-core.c +++ b/trunk/drivers/mfd/ab8500-core.c @@ -334,14 +334,14 @@ static int ab8500_irq_init(struct ab8500 *ab8500) int irq; for (irq = base; irq < base + AB8500_NR_IRQS; irq++) { - irq_set_chip_data(irq, ab8500); - irq_set_chip_and_handler(irq, &ab8500_irq_chip, + set_irq_chip_data(irq, ab8500); + set_irq_chip_and_handler(irq, &ab8500_irq_chip, handle_simple_irq); - irq_set_nested_thread(irq, 1); + set_irq_nested_thread(irq, 1); #ifdef CONFIG_ARM set_irq_flags(irq, IRQF_VALID); #else - irq_set_noprobe(irq); + set_irq_noprobe(irq); #endif } @@ -357,20 +357,11 @@ static void ab8500_irq_remove(struct ab8500 *ab8500) #ifdef CONFIG_ARM set_irq_flags(irq, 0); #endif - irq_set_chip_and_handler(irq, NULL, NULL); - irq_set_chip_data(irq, NULL); + set_irq_chip_and_handler(irq, NULL, NULL); + set_irq_chip_data(irq, NULL); } } -static struct resource ab8500_gpio_resources[] = { - { - .name = "GPIO_INT6", - .start = AB8500_INT_GPIO6R, - .end = AB8500_INT_GPIO41F, - .flags = IORESOURCE_IRQ, - } -}; - static struct resource ab8500_gpadc_resources[] = { { .name = "HW_CONV_END", @@ -604,11 +595,6 @@ static struct mfd_cell ab8500_devs[] = { { .name = "ab8500-regulator", }, - { - .name = "ab8500-gpio", - .num_resources = ARRAY_SIZE(ab8500_gpio_resources), - .resources = ab8500_gpio_resources, - }, { .name = "ab8500-gpadc", .num_resources = ARRAY_SIZE(ab8500_gpadc_resources), diff --git a/trunk/drivers/mfd/ab8500-i2c.c b/trunk/drivers/mfd/ab8500-i2c.c index 821e6b86afd2..6820327adf4a 100644 --- a/trunk/drivers/mfd/ab8500-i2c.c +++ b/trunk/drivers/mfd/ab8500-i2c.c @@ -97,7 +97,7 @@ static void __exit ab8500_i2c_exit(void) { platform_driver_unregister(&ab8500_i2c_driver); } -arch_initcall(ab8500_i2c_init); +subsys_initcall(ab8500_i2c_init); module_exit(ab8500_i2c_exit); MODULE_AUTHOR("Mattias WALLIN irq_data.chip->irq_ack(&desc->irq_data); - data->chip->irq_ack(irq_data); + asic = get_irq_data(irq); for (iter = 0 ; iter < MAX_ASIC_ISR_LOOPS; iter++) { u32 status; @@ -187,7 +188,8 @@ static void asic3_irq_demux(unsigned int irq, struct irq_desc *desc) irqnr = asic->irq_base + (ASIC3_GPIOS_PER_BANK * bank) + i; - generic_handle_irq(irqnr); + desc = irq_to_desc(irqnr); + desc->handle_irq(irqnr, desc); if (asic->irq_bothedge[bank] & bit) asic3_irq_flip_edge(asic, base, bit); @@ -198,8 +200,11 @@ static void asic3_irq_demux(unsigned int irq, struct irq_desc *desc) /* Handle remaining IRQs in the status register */ for (i = ASIC3_NUM_GPIOS; i < ASIC3_NR_IRQS; i++) { /* They start at bit 4 and go up */ - if (status & (1 << (i - ASIC3_NUM_GPIOS + 4))) - generic_handle_irq(asic->irq_base + i); + if (status & (1 << (i - ASIC3_NUM_GPIOS + 4))) { + desc = irq_to_desc(asic->irq_base + i); + desc->handle_irq(asic->irq_base + i, + desc); + } } } @@ -388,21 +393,21 @@ static int __init asic3_irq_probe(struct platform_device *pdev) for (irq = irq_base; irq < irq_base + ASIC3_NR_IRQS; irq++) { if (irq < asic->irq_base + ASIC3_NUM_GPIOS) - irq_set_chip(irq, &asic3_gpio_irq_chip); + set_irq_chip(irq, &asic3_gpio_irq_chip); else - irq_set_chip(irq, &asic3_irq_chip); + set_irq_chip(irq, &asic3_irq_chip); - irq_set_chip_data(irq, asic); - irq_set_handler(irq, handle_level_irq); + set_irq_chip_data(irq, asic); + set_irq_handler(irq, handle_level_irq); set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); } asic3_write_register(asic, ASIC3_OFFSET(INTR, INT_MASK), ASIC3_INTMASK_GINTMASK); - irq_set_chained_handler(asic->irq_nr, asic3_irq_demux); - irq_set_irq_type(asic->irq_nr, IRQ_TYPE_EDGE_RISING); - irq_set_handler_data(asic->irq_nr, asic); + set_irq_chained_handler(asic->irq_nr, asic3_irq_demux); + set_irq_type(asic->irq_nr, IRQ_TYPE_EDGE_RISING); + set_irq_data(asic->irq_nr, asic); return 0; } @@ -416,10 +421,11 @@ static void asic3_irq_remove(struct platform_device *pdev) for (irq = irq_base; irq < irq_base + ASIC3_NR_IRQS; irq++) { set_irq_flags(irq, 0); - irq_set_chip_and_handler(irq, NULL, NULL); - irq_set_chip_data(irq, NULL); + set_irq_handler(irq, NULL); + set_irq_chip(irq, NULL); + set_irq_chip_data(irq, NULL); } - irq_set_chained_handler(asic->irq_nr, NULL); + set_irq_chained_handler(asic->irq_nr, NULL); } /* GPIOs */ diff --git a/trunk/drivers/mfd/cs5535-mfd.c b/trunk/drivers/mfd/cs5535-mfd.c index 155fa0407882..886a06871065 100644 --- a/trunk/drivers/mfd/cs5535-mfd.c +++ b/trunk/drivers/mfd/cs5535-mfd.c @@ -27,7 +27,6 @@ #include #include #include -#include #define DRV_NAME "cs5535-mfd" @@ -112,20 +111,6 @@ static __devinitdata struct mfd_cell cs5535_mfd_cells[] = { }, }; -#ifdef CONFIG_OLPC -static void __devinit cs5535_clone_olpc_cells(void) -{ - const char *acpi_clones[] = { "olpc-xo1-pm-acpi", "olpc-xo1-sci-acpi" }; - - if (!machine_is_olpc()) - return; - - mfd_clone_cell("cs5535-acpi", acpi_clones, ARRAY_SIZE(acpi_clones)); -} -#else -static void cs5535_clone_olpc_cells(void) { } -#endif - static int __devinit cs5535_mfd_probe(struct pci_dev *pdev, const struct pci_device_id *id) { @@ -154,7 +139,6 @@ static int __devinit cs5535_mfd_probe(struct pci_dev *pdev, dev_err(&pdev->dev, "MFD add devices failed: %d\n", err); goto err_disable; } - cs5535_clone_olpc_cells(); dev_info(&pdev->dev, "%zu devices registered.\n", ARRAY_SIZE(cs5535_mfd_cells)); diff --git a/trunk/drivers/mfd/ezx-pcap.c b/trunk/drivers/mfd/ezx-pcap.c index f2f4029e21a0..9e2d8dd5f9e5 100644 --- a/trunk/drivers/mfd/ezx-pcap.c +++ b/trunk/drivers/mfd/ezx-pcap.c @@ -162,7 +162,6 @@ static void pcap_unmask_irq(struct irq_data *d) static struct irq_chip pcap_irq_chip = { .name = "pcap", - .irq_disable = pcap_mask_irq, .irq_mask = pcap_mask_irq, .irq_unmask = pcap_unmask_irq, }; @@ -197,8 +196,17 @@ static void pcap_isr_work(struct work_struct *work) local_irq_disable(); service = isr & ~msr; for (irq = pcap->irq_base; service; service >>= 1, irq++) { - if (service & 1) - generic_handle_irq(irq); + if (service & 1) { + struct irq_desc *desc = irq_to_desc(irq); + + if (WARN(!desc, "Invalid PCAP IRQ %d\n", irq)) + break; + + if (desc->status & IRQ_DISABLED) + note_interrupt(irq, desc, IRQ_NONE); + else + desc->handle_irq(irq, desc); + } } local_irq_enable(); ezx_pcap_write(pcap, PCAP_REG_MSR, pcap->msr); @@ -207,7 +215,7 @@ static void pcap_isr_work(struct work_struct *work) static void pcap_irq_handler(unsigned int irq, struct irq_desc *desc) { - struct pcap_chip *pcap = irq_get_handler_data(irq); + struct pcap_chip *pcap = get_irq_data(irq); desc->irq_data.chip->irq_ack(&desc->irq_data); queue_work(pcap->workqueue, &pcap->isr_work); @@ -411,7 +419,7 @@ static int __devexit ezx_pcap_remove(struct spi_device *spi) /* cleanup irqchip */ for (i = pcap->irq_base; i < (pcap->irq_base + PCAP_NIRQS); i++) - irq_set_chip_and_handler(i, NULL, NULL); + set_irq_chip_and_handler(i, NULL, NULL); destroy_workqueue(pcap->workqueue); @@ -468,12 +476,12 @@ static int __devinit ezx_pcap_probe(struct spi_device *spi) /* setup irq chip */ for (i = pcap->irq_base; i < (pcap->irq_base + PCAP_NIRQS); i++) { - irq_set_chip_and_handler(i, &pcap_irq_chip, handle_simple_irq); - irq_set_chip_data(i, pcap); + set_irq_chip_and_handler(i, &pcap_irq_chip, handle_simple_irq); + set_irq_chip_data(i, pcap); #ifdef CONFIG_ARM set_irq_flags(i, IRQF_VALID); #else - irq_set_noprobe(i); + set_irq_noprobe(i); #endif } @@ -482,10 +490,10 @@ static int __devinit ezx_pcap_probe(struct spi_device *spi) ezx_pcap_write(pcap, PCAP_REG_ISR, PCAP_CLEAR_INTERRUPT_REGISTER); pcap->msr = PCAP_MASK_ALL_INTERRUPT; - irq_set_irq_type(spi->irq, IRQ_TYPE_EDGE_RISING); - irq_set_handler_data(spi->irq, pcap); - irq_set_chained_handler(spi->irq, pcap_irq_handler); - irq_set_irq_wake(spi->irq, 1); + set_irq_type(spi->irq, IRQ_TYPE_EDGE_RISING); + set_irq_data(spi->irq, pcap); + set_irq_chained_handler(spi->irq, pcap_irq_handler); + set_irq_wake(spi->irq, 1); /* ADC */ adc_irq = pcap_to_irq(pcap, (pdata->config & PCAP_SECOND_PORT) ? @@ -514,7 +522,7 @@ static int __devinit ezx_pcap_probe(struct spi_device *spi) free_irq(adc_irq, pcap); free_irqchip: for (i = pcap->irq_base; i < (pcap->irq_base + PCAP_NIRQS); i++) - irq_set_chip_and_handler(i, NULL, NULL); + set_irq_chip_and_handler(i, NULL, NULL); /* destroy_workqueue: */ destroy_workqueue(pcap->workqueue); free_pcap: diff --git a/trunk/drivers/mfd/htc-egpio.c b/trunk/drivers/mfd/htc-egpio.c index bbaec0ccba8f..d00b6d1a69e5 100644 --- a/trunk/drivers/mfd/htc-egpio.c +++ b/trunk/drivers/mfd/htc-egpio.c @@ -100,7 +100,7 @@ static struct irq_chip egpio_muxed_chip = { static void egpio_handler(unsigned int irq, struct irq_desc *desc) { - struct egpio_info *ei = irq_desc_get_handler_data(desc); + struct egpio_info *ei = get_irq_data(irq); int irqpin; /* Read current pins. */ @@ -113,7 +113,9 @@ static void egpio_handler(unsigned int irq, struct irq_desc *desc) for_each_set_bit(irqpin, &readval, ei->nirqs) { /* Run irq handler */ pr_debug("got IRQ %d\n", irqpin); - generic_handle_irq(ei->irq_start + irqpin); + irq = ei->irq_start + irqpin; + desc = irq_to_desc(irq); + desc->handle_irq(irq, desc); } } @@ -344,14 +346,14 @@ static int __init egpio_probe(struct platform_device *pdev) ei->ack_write = 0; irq_end = ei->irq_start + ei->nirqs; for (irq = ei->irq_start; irq < irq_end; irq++) { - irq_set_chip_and_handler(irq, &egpio_muxed_chip, - handle_simple_irq); - irq_set_chip_data(irq, ei); + set_irq_chip(irq, &egpio_muxed_chip); + set_irq_chip_data(irq, ei); + set_irq_handler(irq, handle_simple_irq); set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); } - irq_set_irq_type(ei->chained_irq, IRQ_TYPE_EDGE_RISING); - irq_set_handler_data(ei->chained_irq, ei); - irq_set_chained_handler(ei->chained_irq, egpio_handler); + set_irq_type(ei->chained_irq, IRQ_TYPE_EDGE_RISING); + set_irq_data(ei->chained_irq, ei); + set_irq_chained_handler(ei->chained_irq, egpio_handler); ack_irqs(ei); device_init_wakeup(&pdev->dev, 1); @@ -373,10 +375,11 @@ static int __exit egpio_remove(struct platform_device *pdev) if (ei->chained_irq) { irq_end = ei->irq_start + ei->nirqs; for (irq = ei->irq_start; irq < irq_end; irq++) { - irq_set_chip_and_handler(irq, NULL, NULL); + set_irq_chip(irq, NULL); + set_irq_handler(irq, NULL); set_irq_flags(irq, 0); } - irq_set_chained_handler(ei->chained_irq, NULL); + set_irq_chained_handler(ei->chained_irq, NULL); device_init_wakeup(&pdev->dev, 0); } iounmap(ei->base_addr); diff --git a/trunk/drivers/mfd/htc-i2cpld.c b/trunk/drivers/mfd/htc-i2cpld.c index d55065cc324c..296ad1562f69 100644 --- a/trunk/drivers/mfd/htc-i2cpld.c +++ b/trunk/drivers/mfd/htc-i2cpld.c @@ -58,7 +58,6 @@ struct htcpld_chip { uint irq_start; int nirqs; - unsigned int flow_type; /* * Work structure to allow for setting values outside of any * possible interrupt context @@ -98,7 +97,12 @@ static void htcpld_unmask(struct irq_data *data) static int htcpld_set_type(struct irq_data *data, unsigned int flags) { - struct htcpld_chip *chip = irq_data_get_irq_chip_data(data); + struct irq_desc *d = irq_to_desc(data->irq); + + if (!d) { + pr_err("HTCPLD invalid IRQ: %d\n", data->irq); + return -EINVAL; + } if (flags & ~IRQ_TYPE_SENSE_MASK) return -EINVAL; @@ -107,7 +111,9 @@ static int htcpld_set_type(struct irq_data *data, unsigned int flags) if (flags & (IRQ_TYPE_LEVEL_LOW|IRQ_TYPE_LEVEL_HIGH)) return -EINVAL; - chip->flow_type = flags; + d->status &= ~IRQ_TYPE_SENSE_MASK; + d->status |= flags; + return 0; } @@ -129,6 +135,7 @@ static irqreturn_t htcpld_handler(int irq, void *dev) unsigned int i; unsigned long flags; int irqpin; + struct irq_desc *desc; if (!htcpld) { pr_debug("htcpld is null in ISR\n"); @@ -188,19 +195,23 @@ static irqreturn_t htcpld_handler(int irq, void *dev) * associated interrupts. */ for (irqpin = 0; irqpin < chip->nirqs; irqpin++) { - unsigned oldb, newb, type = chip->flow_type; + unsigned oldb, newb; + int flags; irq = chip->irq_start + irqpin; + desc = irq_to_desc(irq); + flags = desc->status; /* Run the IRQ handler, but only if the bit value * changed, and the proper flags are set */ oldb = (old_val >> irqpin) & 1; newb = (uval >> irqpin) & 1; - if ((!oldb && newb && (type & IRQ_TYPE_EDGE_RISING)) || - (oldb && !newb && (type & IRQ_TYPE_EDGE_FALLING))) { + if ((!oldb && newb && (flags & IRQ_TYPE_EDGE_RISING)) || + (oldb && !newb && + (flags & IRQ_TYPE_EDGE_FALLING))) { pr_debug("fire IRQ %d\n", irqpin); - generic_handle_irq(irq); + desc->handle_irq(irq, desc); } } } @@ -348,13 +359,13 @@ static int __devinit htcpld_setup_chip_irq( /* Setup irq handlers */ irq_end = chip->irq_start + chip->nirqs; for (irq = chip->irq_start; irq < irq_end; irq++) { - irq_set_chip_and_handler(irq, &htcpld_muxed_chip, - handle_simple_irq); - irq_set_chip_data(irq, chip); + set_irq_chip(irq, &htcpld_muxed_chip); + set_irq_chip_data(irq, chip); + set_irq_handler(irq, handle_simple_irq); #ifdef CONFIG_ARM set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); #else - irq_set_probe(irq); + set_irq_probe(irq); #endif } diff --git a/trunk/drivers/mfd/jz4740-adc.c b/trunk/drivers/mfd/jz4740-adc.c index a0bd0cf05af3..aa518b9beaf5 100644 --- a/trunk/drivers/mfd/jz4740-adc.c +++ b/trunk/drivers/mfd/jz4740-adc.c @@ -112,7 +112,7 @@ static struct irq_chip jz4740_adc_irq_chip = { static void jz4740_adc_irq_demux(unsigned int irq, struct irq_desc *desc) { - struct jz4740_adc *adc = irq_desc_get_handler_data(desc); + struct jz4740_adc *adc = get_irq_desc_data(desc); uint8_t status; unsigned int i; @@ -310,13 +310,13 @@ static int __devinit jz4740_adc_probe(struct platform_device *pdev) platform_set_drvdata(pdev, adc); for (irq = adc->irq_base; irq < adc->irq_base + 5; ++irq) { - irq_set_chip_data(irq, adc); - irq_set_chip_and_handler(irq, &jz4740_adc_irq_chip, - handle_level_irq); + set_irq_chip_data(irq, adc); + set_irq_chip_and_handler(irq, &jz4740_adc_irq_chip, + handle_level_irq); } - irq_set_handler_data(adc->irq, adc); - irq_set_chained_handler(adc->irq, jz4740_adc_irq_demux); + set_irq_data(adc->irq, adc); + set_irq_chained_handler(adc->irq, jz4740_adc_irq_demux); writeb(0x00, adc->base + JZ_REG_ADC_ENABLE); writeb(0xff, adc->base + JZ_REG_ADC_CTRL); @@ -347,8 +347,8 @@ static int __devexit jz4740_adc_remove(struct platform_device *pdev) mfd_remove_devices(&pdev->dev); - irq_set_handler_data(adc->irq, NULL); - irq_set_chained_handler(adc->irq, NULL); + set_irq_data(adc->irq, NULL); + set_irq_chained_handler(adc->irq, NULL); iounmap(adc->base); release_mem_region(adc->mem->start, resource_size(adc->mem)); diff --git a/trunk/drivers/mfd/max8925-core.c b/trunk/drivers/mfd/max8925-core.c index 58cc5fdde016..0e998dc4e7d8 100644 --- a/trunk/drivers/mfd/max8925-core.c +++ b/trunk/drivers/mfd/max8925-core.c @@ -517,6 +517,7 @@ static int max8925_irq_init(struct max8925_chip *chip, int irq, struct max8925_platform_data *pdata) { unsigned long flags = IRQF_TRIGGER_FALLING | IRQF_ONESHOT; + struct irq_desc *desc; int i, ret; int __irq; @@ -543,18 +544,19 @@ static int max8925_irq_init(struct max8925_chip *chip, int irq, mutex_init(&chip->irq_lock); chip->core_irq = irq; chip->irq_base = pdata->irq_base; + desc = irq_to_desc(chip->core_irq); /* register with genirq */ for (i = 0; i < ARRAY_SIZE(max8925_irqs); i++) { __irq = i + chip->irq_base; - irq_set_chip_data(__irq, chip); - irq_set_chip_and_handler(__irq, &max8925_irq_chip, + set_irq_chip_data(__irq, chip); + set_irq_chip_and_handler(__irq, &max8925_irq_chip, handle_edge_irq); - irq_set_nested_thread(__irq, 1); + set_irq_nested_thread(__irq, 1); #ifdef CONFIG_ARM set_irq_flags(__irq, IRQF_VALID); #else - irq_set_noprobe(__irq); + set_irq_noprobe(__irq); #endif } if (!irq) { diff --git a/trunk/drivers/mfd/max8997-irq.c b/trunk/drivers/mfd/max8997-irq.c deleted file mode 100644 index 638bf7e4d3b3..000000000000 --- a/trunk/drivers/mfd/max8997-irq.c +++ /dev/null @@ -1,377 +0,0 @@ -/* - * max8997-irq.c - Interrupt controller support for MAX8997 - * - * Copyright (C) 2011 Samsung Electronics Co.Ltd - * MyungJoo Ham - * - * 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 - * - * This driver is based on max8998-irq.c - */ - -#include -#include -#include -#include -#include - -static const u8 max8997_mask_reg[] = { - [PMIC_INT1] = MAX8997_REG_INT1MSK, - [PMIC_INT2] = MAX8997_REG_INT2MSK, - [PMIC_INT3] = MAX8997_REG_INT3MSK, - [PMIC_INT4] = MAX8997_REG_INT4MSK, - [FUEL_GAUGE] = MAX8997_REG_INVALID, - [MUIC_INT1] = MAX8997_MUIC_REG_INTMASK1, - [MUIC_INT2] = MAX8997_MUIC_REG_INTMASK2, - [MUIC_INT3] = MAX8997_MUIC_REG_INTMASK3, - [GPIO_LOW] = MAX8997_REG_INVALID, - [GPIO_HI] = MAX8997_REG_INVALID, - [FLASH_STATUS] = MAX8997_REG_INVALID, -}; - -static struct i2c_client *get_i2c(struct max8997_dev *max8997, - enum max8997_irq_source src) -{ - switch (src) { - case PMIC_INT1 ... PMIC_INT4: - return max8997->i2c; - case FUEL_GAUGE: - return NULL; - case MUIC_INT1 ... MUIC_INT3: - return max8997->muic; - case GPIO_LOW ... GPIO_HI: - return max8997->i2c; - case FLASH_STATUS: - return max8997->i2c; - default: - return ERR_PTR(-EINVAL); - } - - return ERR_PTR(-EINVAL); -} - -struct max8997_irq_data { - int mask; - enum max8997_irq_source group; -}; - -#define DECLARE_IRQ(idx, _group, _mask) \ - [(idx)] = { .group = (_group), .mask = (_mask) } -static const struct max8997_irq_data max8997_irqs[] = { - DECLARE_IRQ(MAX8997_PMICIRQ_PWRONR, PMIC_INT1, 1 << 0), - DECLARE_IRQ(MAX8997_PMICIRQ_PWRONF, PMIC_INT1, 1 << 1), - DECLARE_IRQ(MAX8997_PMICIRQ_PWRON1SEC, PMIC_INT1, 1 << 3), - DECLARE_IRQ(MAX8997_PMICIRQ_JIGONR, PMIC_INT1, 1 << 4), - DECLARE_IRQ(MAX8997_PMICIRQ_JIGONF, PMIC_INT1, 1 << 5), - DECLARE_IRQ(MAX8997_PMICIRQ_LOWBAT2, PMIC_INT1, 1 << 6), - DECLARE_IRQ(MAX8997_PMICIRQ_LOWBAT1, PMIC_INT1, 1 << 7), - - DECLARE_IRQ(MAX8997_PMICIRQ_JIGR, PMIC_INT2, 1 << 0), - DECLARE_IRQ(MAX8997_PMICIRQ_JIGF, PMIC_INT2, 1 << 1), - DECLARE_IRQ(MAX8997_PMICIRQ_MR, PMIC_INT2, 1 << 2), - DECLARE_IRQ(MAX8997_PMICIRQ_DVS1OK, PMIC_INT2, 1 << 3), - DECLARE_IRQ(MAX8997_PMICIRQ_DVS2OK, PMIC_INT2, 1 << 4), - DECLARE_IRQ(MAX8997_PMICIRQ_DVS3OK, PMIC_INT2, 1 << 5), - DECLARE_IRQ(MAX8997_PMICIRQ_DVS4OK, PMIC_INT2, 1 << 6), - - DECLARE_IRQ(MAX8997_PMICIRQ_CHGINS, PMIC_INT3, 1 << 0), - DECLARE_IRQ(MAX8997_PMICIRQ_CHGRM, PMIC_INT3, 1 << 1), - DECLARE_IRQ(MAX8997_PMICIRQ_DCINOVP, PMIC_INT3, 1 << 2), - DECLARE_IRQ(MAX8997_PMICIRQ_TOPOFFR, PMIC_INT3, 1 << 3), - DECLARE_IRQ(MAX8997_PMICIRQ_CHGRSTF, PMIC_INT3, 1 << 5), - DECLARE_IRQ(MAX8997_PMICIRQ_MBCHGTMEXPD, PMIC_INT3, 1 << 7), - - DECLARE_IRQ(MAX8997_PMICIRQ_RTC60S, PMIC_INT4, 1 << 0), - DECLARE_IRQ(MAX8997_PMICIRQ_RTCA1, PMIC_INT4, 1 << 1), - DECLARE_IRQ(MAX8997_PMICIRQ_RTCA2, PMIC_INT4, 1 << 2), - DECLARE_IRQ(MAX8997_PMICIRQ_SMPL_INT, PMIC_INT4, 1 << 3), - DECLARE_IRQ(MAX8997_PMICIRQ_RTC1S, PMIC_INT4, 1 << 4), - DECLARE_IRQ(MAX8997_PMICIRQ_WTSR, PMIC_INT4, 1 << 5), - - DECLARE_IRQ(MAX8997_MUICIRQ_ADCError, MUIC_INT1, 1 << 2), - DECLARE_IRQ(MAX8997_MUICIRQ_ADCLow, MUIC_INT1, 1 << 1), - DECLARE_IRQ(MAX8997_MUICIRQ_ADC, MUIC_INT1, 1 << 0), - - DECLARE_IRQ(MAX8997_MUICIRQ_VBVolt, MUIC_INT2, 1 << 4), - DECLARE_IRQ(MAX8997_MUICIRQ_DBChg, MUIC_INT2, 1 << 3), - DECLARE_IRQ(MAX8997_MUICIRQ_DCDTmr, MUIC_INT2, 1 << 2), - DECLARE_IRQ(MAX8997_MUICIRQ_ChgDetRun, MUIC_INT2, 1 << 1), - DECLARE_IRQ(MAX8997_MUICIRQ_ChgTyp, MUIC_INT2, 1 << 0), - - DECLARE_IRQ(MAX8997_MUICIRQ_OVP, MUIC_INT3, 1 << 2), -}; - -static void max8997_irq_lock(struct irq_data *data) -{ - struct max8997_dev *max8997 = irq_get_chip_data(data->irq); - - mutex_lock(&max8997->irqlock); -} - -static void max8997_irq_sync_unlock(struct irq_data *data) -{ - struct max8997_dev *max8997 = irq_get_chip_data(data->irq); - int i; - - for (i = 0; i < MAX8997_IRQ_GROUP_NR; i++) { - u8 mask_reg = max8997_mask_reg[i]; - struct i2c_client *i2c = get_i2c(max8997, i); - - if (mask_reg == MAX8997_REG_INVALID || - IS_ERR_OR_NULL(i2c)) - continue; - max8997->irq_masks_cache[i] = max8997->irq_masks_cur[i]; - - max8997_write_reg(i2c, max8997_mask_reg[i], - max8997->irq_masks_cur[i]); - } - - mutex_unlock(&max8997->irqlock); -} - -static const inline struct max8997_irq_data * -irq_to_max8997_irq(struct max8997_dev *max8997, int irq) -{ - return &max8997_irqs[irq - max8997->irq_base]; -} - -static void max8997_irq_mask(struct irq_data *data) -{ - struct max8997_dev *max8997 = irq_get_chip_data(data->irq); - const struct max8997_irq_data *irq_data = irq_to_max8997_irq(max8997, - data->irq); - - max8997->irq_masks_cur[irq_data->group] |= irq_data->mask; -} - -static void max8997_irq_unmask(struct irq_data *data) -{ - struct max8997_dev *max8997 = irq_get_chip_data(data->irq); - const struct max8997_irq_data *irq_data = irq_to_max8997_irq(max8997, - data->irq); - - max8997->irq_masks_cur[irq_data->group] &= ~irq_data->mask; -} - -static struct irq_chip max8997_irq_chip = { - .name = "max8997", - .irq_bus_lock = max8997_irq_lock, - .irq_bus_sync_unlock = max8997_irq_sync_unlock, - .irq_mask = max8997_irq_mask, - .irq_unmask = max8997_irq_unmask, -}; - -#define MAX8997_IRQSRC_PMIC (1 << 1) -#define MAX8997_IRQSRC_FUELGAUGE (1 << 2) -#define MAX8997_IRQSRC_MUIC (1 << 3) -#define MAX8997_IRQSRC_GPIO (1 << 4) -#define MAX8997_IRQSRC_FLASH (1 << 5) -static irqreturn_t max8997_irq_thread(int irq, void *data) -{ - struct max8997_dev *max8997 = data; - u8 irq_reg[MAX8997_IRQ_GROUP_NR] = {}; - u8 irq_src; - int ret; - int i; - - ret = max8997_read_reg(max8997->i2c, MAX8997_REG_INTSRC, &irq_src); - if (ret < 0) { - dev_err(max8997->dev, "Failed to read interrupt source: %d\n", - ret); - return IRQ_NONE; - } - - if (irq_src & MAX8997_IRQSRC_PMIC) { - /* PMIC INT1 ~ INT4 */ - max8997_bulk_read(max8997->i2c, MAX8997_REG_INT1, 4, - &irq_reg[PMIC_INT1]); - } - if (irq_src & MAX8997_IRQSRC_FUELGAUGE) { - /* - * TODO: FUEL GAUGE - * - * This is to be supported by Max17042 driver. When - * an interrupt incurs here, it should be relayed to a - * Max17042 device that is connected (probably by - * platform-data). However, we do not have interrupt - * handling in Max17042 driver currently. The Max17042 IRQ - * driver should be ready to be used as a stand-alone device and - * a Max8997-dependent device. Because it is not ready in - * Max17042-side and it is not too critical in operating - * Max8997, we do not implement this in initial releases. - */ - irq_reg[FUEL_GAUGE] = 0; - } - if (irq_src & MAX8997_IRQSRC_MUIC) { - /* MUIC INT1 ~ INT3 */ - max8997_bulk_read(max8997->muic, MAX8997_MUIC_REG_INT1, 3, - &irq_reg[MUIC_INT1]); - } - if (irq_src & MAX8997_IRQSRC_GPIO) { - /* GPIO Interrupt */ - u8 gpio_info[MAX8997_NUM_GPIO]; - - irq_reg[GPIO_LOW] = 0; - irq_reg[GPIO_HI] = 0; - - max8997_bulk_read(max8997->i2c, MAX8997_REG_GPIOCNTL1, - MAX8997_NUM_GPIO, gpio_info); - for (i = 0; i < MAX8997_NUM_GPIO; i++) { - bool interrupt = false; - - switch (gpio_info[i] & MAX8997_GPIO_INT_MASK) { - case MAX8997_GPIO_INT_BOTH: - if (max8997->gpio_status[i] != gpio_info[i]) - interrupt = true; - break; - case MAX8997_GPIO_INT_RISE: - if ((max8997->gpio_status[i] != gpio_info[i]) && - (gpio_info[i] & MAX8997_GPIO_DATA_MASK)) - interrupt = true; - break; - case MAX8997_GPIO_INT_FALL: - if ((max8997->gpio_status[i] != gpio_info[i]) && - !(gpio_info[i] & MAX8997_GPIO_DATA_MASK)) - interrupt = true; - break; - default: - break; - } - - if (interrupt) { - if (i < 8) - irq_reg[GPIO_LOW] |= (1 << i); - else - irq_reg[GPIO_HI] |= (1 << (i - 8)); - } - - } - } - if (irq_src & MAX8997_IRQSRC_FLASH) { - /* Flash Status Interrupt */ - ret = max8997_read_reg(max8997->i2c, MAX8997_REG_FLASHSTATUS, - &irq_reg[FLASH_STATUS]); - } - - /* Apply masking */ - for (i = 0; i < MAX8997_IRQ_GROUP_NR; i++) - irq_reg[i] &= ~max8997->irq_masks_cur[i]; - - /* Report */ - for (i = 0; i < MAX8997_IRQ_NR; i++) { - if (irq_reg[max8997_irqs[i].group] & max8997_irqs[i].mask) - handle_nested_irq(max8997->irq_base + i); - } - - return IRQ_HANDLED; -} - -int max8997_irq_resume(struct max8997_dev *max8997) -{ - if (max8997->irq && max8997->irq_base) - max8997_irq_thread(max8997->irq_base, max8997); - return 0; -} - -int max8997_irq_init(struct max8997_dev *max8997) -{ - int i; - int cur_irq; - int ret; - u8 val; - - if (!max8997->irq) { - dev_warn(max8997->dev, "No interrupt specified.\n"); - max8997->irq_base = 0; - return 0; - } - - if (!max8997->irq_base) { - dev_err(max8997->dev, "No interrupt base specified.\n"); - return 0; - } - - mutex_init(&max8997->irqlock); - - /* Mask individual interrupt sources */ - for (i = 0; i < MAX8997_IRQ_GROUP_NR; i++) { - struct i2c_client *i2c; - - max8997->irq_masks_cur[i] = 0xff; - max8997->irq_masks_cache[i] = 0xff; - i2c = get_i2c(max8997, i); - - if (IS_ERR_OR_NULL(i2c)) - continue; - if (max8997_mask_reg[i] == MAX8997_REG_INVALID) - continue; - - max8997_write_reg(i2c, max8997_mask_reg[i], 0xff); - } - - for (i = 0; i < MAX8997_NUM_GPIO; i++) { - max8997->gpio_status[i] = (max8997_read_reg(max8997->i2c, - MAX8997_REG_GPIOCNTL1 + i, - &val) - & MAX8997_GPIO_DATA_MASK) ? - true : false; - } - - /* Register with genirq */ - for (i = 0; i < MAX8997_IRQ_NR; i++) { - cur_irq = i + max8997->irq_base; - irq_set_chip_data(cur_irq, max8997); - irq_set_chip_and_handler(cur_irq, &max8997_irq_chip, - handle_edge_irq); - irq_set_nested_thread(cur_irq, 1); -#ifdef CONFIG_ARM - set_irq_flags(cur_irq, IRQF_VALID); -#else - irq_set_noprobe(cur_irq); -#endif - } - - ret = request_threaded_irq(max8997->irq, NULL, max8997_irq_thread, - IRQF_TRIGGER_FALLING | IRQF_ONESHOT, - "max8997-irq", max8997); - - if (ret) { - dev_err(max8997->dev, "Failed to request IRQ %d: %d\n", - max8997->irq, ret); - return ret; - } - - if (!max8997->ono) - return 0; - - ret = request_threaded_irq(max8997->ono, NULL, max8997_irq_thread, - IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING | - IRQF_ONESHOT, "max8997-ono", max8997); - - if (ret) - dev_err(max8997->dev, "Failed to request ono-IRQ %d: %d\n", - max8997->ono, ret); - - return 0; -} - -void max8997_irq_exit(struct max8997_dev *max8997) -{ - if (max8997->ono) - free_irq(max8997->ono, max8997); - - if (max8997->irq) - free_irq(max8997->irq, max8997); -} diff --git a/trunk/drivers/mfd/max8998-irq.c b/trunk/drivers/mfd/max8998-irq.c index 5919710dc9ed..3903e1fbb334 100644 --- a/trunk/drivers/mfd/max8998-irq.c +++ b/trunk/drivers/mfd/max8998-irq.c @@ -224,14 +224,14 @@ int max8998_irq_init(struct max8998_dev *max8998) /* register with genirq */ for (i = 0; i < MAX8998_IRQ_NR; i++) { cur_irq = i + max8998->irq_base; - irq_set_chip_data(cur_irq, max8998); - irq_set_chip_and_handler(cur_irq, &max8998_irq_chip, + set_irq_chip_data(cur_irq, max8998); + set_irq_chip_and_handler(cur_irq, &max8998_irq_chip, handle_edge_irq); - irq_set_nested_thread(cur_irq, 1); + set_irq_nested_thread(cur_irq, 1); #ifdef CONFIG_ARM set_irq_flags(cur_irq, IRQF_VALID); #else - irq_set_noprobe(cur_irq); + set_irq_noprobe(cur_irq); #endif } diff --git a/trunk/drivers/mfd/max8998.c b/trunk/drivers/mfd/max8998.c index 9ec7570f5b81..c00214257da2 100644 --- a/trunk/drivers/mfd/max8998.c +++ b/trunk/drivers/mfd/max8998.c @@ -209,7 +209,7 @@ static int max8998_suspend(struct device *dev) struct max8998_dev *max8998 = i2c_get_clientdata(i2c); if (max8998->wakeup) - irq_set_irq_wake(max8998->irq, 1); + set_irq_wake(max8998->irq, 1); return 0; } @@ -219,7 +219,7 @@ static int max8998_resume(struct device *dev) struct max8998_dev *max8998 = i2c_get_clientdata(i2c); if (max8998->wakeup) - irq_set_irq_wake(max8998->irq, 0); + set_irq_wake(max8998->irq, 0); /* * In LP3974, if IRQ registers are not "read & clear" * when it's set during sleep, the interrupt becomes diff --git a/trunk/drivers/mfd/mfd-core.c b/trunk/drivers/mfd/mfd-core.c index d01574d98870..79eda0264fb2 100644 --- a/trunk/drivers/mfd/mfd-core.c +++ b/trunk/drivers/mfd/mfd-core.c @@ -184,12 +184,16 @@ void mfd_remove_devices(struct device *parent) } EXPORT_SYMBOL(mfd_remove_devices); -int mfd_clone_cell(const char *cell, const char **clones, size_t n_clones) +static int add_shared_platform_device(const char *cell, const char *name) { struct mfd_cell cell_entry; struct device *dev; struct platform_device *pdev; - int i; + int err; + + /* check if we've already registered a device (don't fail if we have) */ + if (bus_find_device_by_name(&platform_bus_type, NULL, name)) + return 0; /* fetch the parent cell's device (should already be registered!) */ dev = bus_find_device_by_name(&platform_bus_type, NULL, cell); @@ -202,17 +206,44 @@ int mfd_clone_cell(const char *cell, const char **clones, size_t n_clones) WARN_ON(!cell_entry.enable); - for (i = 0; i < n_clones; i++) { - cell_entry.name = clones[i]; - /* don't give up if a single call fails; just report error */ - if (mfd_add_device(pdev->dev.parent, -1, &cell_entry, NULL, 0)) - dev_err(dev, "failed to create platform device '%s'\n", - clones[i]); - } + cell_entry.name = name; + err = mfd_add_device(pdev->dev.parent, -1, &cell_entry, NULL, 0); + if (err) + dev_err(dev, "MFD add devices failed: %d\n", err); + return err; +} - return 0; +int mfd_shared_platform_driver_register(struct platform_driver *drv, + const char *cellname) +{ + int err; + + err = add_shared_platform_device(cellname, drv->driver.name); + if (err) + printk(KERN_ERR "failed to add platform device %s\n", + drv->driver.name); + + err = platform_driver_register(drv); + if (err) + printk(KERN_ERR "failed to add platform driver %s\n", + drv->driver.name); + + return err; +} +EXPORT_SYMBOL(mfd_shared_platform_driver_register); + +void mfd_shared_platform_driver_unregister(struct platform_driver *drv) +{ + struct device *dev; + + dev = bus_find_device_by_name(&platform_bus_type, NULL, + drv->driver.name); + if (dev) + platform_device_unregister(to_platform_device(dev)); + + platform_driver_unregister(drv); } -EXPORT_SYMBOL(mfd_clone_cell); +EXPORT_SYMBOL(mfd_shared_platform_driver_unregister); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Ian Molton, Dmitry Baryshkov"); diff --git a/trunk/drivers/mfd/pcf50633-core.c b/trunk/drivers/mfd/pcf50633-core.c index c7687f6a78a0..c1306ed43e3c 100644 --- a/trunk/drivers/mfd/pcf50633-core.c +++ b/trunk/drivers/mfd/pcf50633-core.c @@ -356,7 +356,7 @@ static int __devexit pcf50633_remove(struct i2c_client *client) return 0; } -static const struct i2c_device_id pcf50633_id_table[] = { +static struct i2c_device_id pcf50633_id_table[] = { {"pcf50633", 0x73}, {/* end of list */} }; diff --git a/trunk/drivers/mfd/rdc321x-southbridge.c b/trunk/drivers/mfd/rdc321x-southbridge.c index 10dbe6374a89..193c940225b5 100644 --- a/trunk/drivers/mfd/rdc321x-southbridge.c +++ b/trunk/drivers/mfd/rdc321x-southbridge.c @@ -97,7 +97,6 @@ static DEFINE_PCI_DEVICE_TABLE(rdc321x_sb_table) = { { PCI_DEVICE(PCI_VENDOR_ID_RDC, PCI_DEVICE_ID_RDC_R6030) }, {} }; -MODULE_DEVICE_TABLE(pci, rdc321x_sb_table); static struct pci_driver rdc321x_sb_driver = { .name = "RDC321x Southbridge", diff --git a/trunk/drivers/mfd/stmpe.c b/trunk/drivers/mfd/stmpe.c index 7ab7746631d4..3e5732b58c49 100644 --- a/trunk/drivers/mfd/stmpe.c +++ b/trunk/drivers/mfd/stmpe.c @@ -762,14 +762,14 @@ static int __devinit stmpe_irq_init(struct stmpe *stmpe) int irq; for (irq = base; irq < base + num_irqs; irq++) { - irq_set_chip_data(irq, stmpe); - irq_set_chip_and_handler(irq, &stmpe_irq_chip, + set_irq_chip_data(irq, stmpe); + set_irq_chip_and_handler(irq, &stmpe_irq_chip, handle_edge_irq); - irq_set_nested_thread(irq, 1); + set_irq_nested_thread(irq, 1); #ifdef CONFIG_ARM set_irq_flags(irq, IRQF_VALID); #else - irq_set_noprobe(irq); + set_irq_noprobe(irq); #endif } @@ -786,8 +786,8 @@ static void stmpe_irq_remove(struct stmpe *stmpe) #ifdef CONFIG_ARM set_irq_flags(irq, 0); #endif - irq_set_chip_and_handler(irq, NULL, NULL); - irq_set_chip_data(irq, NULL); + set_irq_chip_and_handler(irq, NULL, NULL); + set_irq_chip_data(irq, NULL); } } diff --git a/trunk/drivers/mfd/t7l66xb.c b/trunk/drivers/mfd/t7l66xb.c index 42830e692964..af57fc706a4c 100644 --- a/trunk/drivers/mfd/t7l66xb.c +++ b/trunk/drivers/mfd/t7l66xb.c @@ -186,7 +186,7 @@ static struct mfd_cell t7l66xb_cells[] = { /* Handle the T7L66XB interrupt mux */ static void t7l66xb_irq(unsigned int irq, struct irq_desc *desc) { - struct t7l66xb *t7l66xb = irq_get_handler_data(irq); + struct t7l66xb *t7l66xb = get_irq_data(irq); unsigned int isr; unsigned int i, irq_base; @@ -243,16 +243,17 @@ static void t7l66xb_attach_irq(struct platform_device *dev) irq_base = t7l66xb->irq_base; for (irq = irq_base; irq < irq_base + T7L66XB_NR_IRQS; irq++) { - irq_set_chip_and_handler(irq, &t7l66xb_chip, handle_level_irq); - irq_set_chip_data(irq, t7l66xb); + set_irq_chip(irq, &t7l66xb_chip); + set_irq_chip_data(irq, t7l66xb); + set_irq_handler(irq, handle_level_irq); #ifdef CONFIG_ARM set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); #endif } - irq_set_irq_type(t7l66xb->irq, IRQ_TYPE_EDGE_FALLING); - irq_set_handler_data(t7l66xb->irq, t7l66xb); - irq_set_chained_handler(t7l66xb->irq, t7l66xb_irq); + set_irq_type(t7l66xb->irq, IRQ_TYPE_EDGE_FALLING); + set_irq_data(t7l66xb->irq, t7l66xb); + set_irq_chained_handler(t7l66xb->irq, t7l66xb_irq); } static void t7l66xb_detach_irq(struct platform_device *dev) @@ -262,15 +263,15 @@ static void t7l66xb_detach_irq(struct platform_device *dev) irq_base = t7l66xb->irq_base; - irq_set_chained_handler(t7l66xb->irq, NULL); - irq_set_handler_data(t7l66xb->irq, NULL); + set_irq_chained_handler(t7l66xb->irq, NULL); + set_irq_data(t7l66xb->irq, NULL); for (irq = irq_base; irq < irq_base + T7L66XB_NR_IRQS; irq++) { #ifdef CONFIG_ARM set_irq_flags(irq, 0); #endif - irq_set_chip(irq, NULL); - irq_set_chip_data(irq, NULL); + set_irq_chip(irq, NULL); + set_irq_chip_data(irq, NULL); } } diff --git a/trunk/drivers/mfd/tc3589x.c b/trunk/drivers/mfd/tc3589x.c index c27e515b0722..729dbeed2ce0 100644 --- a/trunk/drivers/mfd/tc3589x.c +++ b/trunk/drivers/mfd/tc3589x.c @@ -192,14 +192,14 @@ static int tc3589x_irq_init(struct tc3589x *tc3589x) int irq; for (irq = base; irq < base + TC3589x_NR_INTERNAL_IRQS; irq++) { - irq_set_chip_data(irq, tc3589x); - irq_set_chip_and_handler(irq, &dummy_irq_chip, + set_irq_chip_data(irq, tc3589x); + set_irq_chip_and_handler(irq, &dummy_irq_chip, handle_edge_irq); - irq_set_nested_thread(irq, 1); + set_irq_nested_thread(irq, 1); #ifdef CONFIG_ARM set_irq_flags(irq, IRQF_VALID); #else - irq_set_noprobe(irq); + set_irq_noprobe(irq); #endif } @@ -215,8 +215,8 @@ static void tc3589x_irq_remove(struct tc3589x *tc3589x) #ifdef CONFIG_ARM set_irq_flags(irq, 0); #endif - irq_set_chip_and_handler(irq, NULL, NULL); - irq_set_chip_data(irq, NULL); + set_irq_chip_and_handler(irq, NULL, NULL); + set_irq_chip_data(irq, NULL); } } diff --git a/trunk/drivers/mfd/tc6393xb.c b/trunk/drivers/mfd/tc6393xb.c index fc53ce287601..3d62ded86a8f 100644 --- a/trunk/drivers/mfd/tc6393xb.c +++ b/trunk/drivers/mfd/tc6393xb.c @@ -513,7 +513,7 @@ static int tc6393xb_register_gpio(struct tc6393xb *tc6393xb, int gpio_base) static void tc6393xb_irq(unsigned int irq, struct irq_desc *desc) { - struct tc6393xb *tc6393xb = irq_get_handler_data(irq); + struct tc6393xb *tc6393xb = get_irq_data(irq); unsigned int isr; unsigned int i, irq_base; @@ -572,14 +572,15 @@ static void tc6393xb_attach_irq(struct platform_device *dev) irq_base = tc6393xb->irq_base; for (irq = irq_base; irq < irq_base + TC6393XB_NR_IRQS; irq++) { - irq_set_chip_and_handler(irq, &tc6393xb_chip, handle_edge_irq); - irq_set_chip_data(irq, tc6393xb); + set_irq_chip(irq, &tc6393xb_chip); + set_irq_chip_data(irq, tc6393xb); + set_irq_handler(irq, handle_edge_irq); set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); } - irq_set_irq_type(tc6393xb->irq, IRQ_TYPE_EDGE_FALLING); - irq_set_handler_data(tc6393xb->irq, tc6393xb); - irq_set_chained_handler(tc6393xb->irq, tc6393xb_irq); + set_irq_type(tc6393xb->irq, IRQ_TYPE_EDGE_FALLING); + set_irq_data(tc6393xb->irq, tc6393xb); + set_irq_chained_handler(tc6393xb->irq, tc6393xb_irq); } static void tc6393xb_detach_irq(struct platform_device *dev) @@ -587,15 +588,15 @@ static void tc6393xb_detach_irq(struct platform_device *dev) struct tc6393xb *tc6393xb = platform_get_drvdata(dev); unsigned int irq, irq_base; - irq_set_chained_handler(tc6393xb->irq, NULL); - irq_set_handler_data(tc6393xb->irq, NULL); + set_irq_chained_handler(tc6393xb->irq, NULL); + set_irq_data(tc6393xb->irq, NULL); irq_base = tc6393xb->irq_base; for (irq = irq_base; irq < irq_base + TC6393XB_NR_IRQS; irq++) { set_irq_flags(irq, 0); - irq_set_chip(irq, NULL); - irq_set_chip_data(irq, NULL); + set_irq_chip(irq, NULL); + set_irq_chip_data(irq, NULL); } } diff --git a/trunk/drivers/mfd/tps6586x.c b/trunk/drivers/mfd/tps6586x.c index b600808690c1..0aa9186aec19 100644 --- a/trunk/drivers/mfd/tps6586x.c +++ b/trunk/drivers/mfd/tps6586x.c @@ -422,10 +422,10 @@ static int __devinit tps6586x_irq_init(struct tps6586x *tps6586x, int irq, for (i = 0; i < ARRAY_SIZE(tps6586x_irqs); i++) { int __irq = i + tps6586x->irq_base; - irq_set_chip_data(__irq, tps6586x); - irq_set_chip_and_handler(__irq, &tps6586x->irq_chip, + set_irq_chip_data(__irq, tps6586x); + set_irq_chip_and_handler(__irq, &tps6586x->irq_chip, handle_simple_irq); - irq_set_nested_thread(__irq, 1); + set_irq_nested_thread(__irq, 1); #ifdef CONFIG_ARM set_irq_flags(__irq, IRQF_VALID); #endif diff --git a/trunk/drivers/mfd/twl4030-irq.c b/trunk/drivers/mfd/twl4030-irq.c index 8a7ee3139b86..63a30e88908f 100644 --- a/trunk/drivers/mfd/twl4030-irq.c +++ b/trunk/drivers/mfd/twl4030-irq.c @@ -320,8 +320,24 @@ static int twl4030_irq_thread(void *data) for (module_irq = twl4030_irq_base; pih_isr; pih_isr >>= 1, module_irq++) { - if (pih_isr & 0x1) - generic_handle_irq(module_irq); + if (pih_isr & 0x1) { + struct irq_desc *d = irq_to_desc(module_irq); + + if (!d) { + pr_err("twl4030: Invalid SIH IRQ: %d\n", + module_irq); + return -EINVAL; + } + + /* These can't be masked ... always warn + * if we get any surprises. + */ + if (d->status & IRQ_DISABLED) + note_interrupt(module_irq, d, + IRQ_NONE); + else + d->handle_irq(module_irq, d); + } } local_irq_enable(); @@ -454,7 +470,7 @@ static inline void activate_irq(int irq) set_irq_flags(irq, IRQF_VALID); #else /* same effect on other architectures */ - irq_set_noprobe(irq); + set_irq_noprobe(irq); #endif } @@ -544,18 +560,24 @@ static void twl4030_sih_do_edge(struct work_struct *work) /* Modify only the bits we know must change */ while (edge_change) { int i = fls(edge_change) - 1; - struct irq_data *idata = irq_get_irq_data(i + agent->irq_base); + struct irq_desc *d = irq_to_desc(i + agent->irq_base); int byte = 1 + (i >> 2); int off = (i & 0x3) * 2; - unsigned int type; + + if (!d) { + pr_err("twl4030: Invalid IRQ: %d\n", + i + agent->irq_base); + return; + } bytes[byte] &= ~(0x03 << off); - type = irqd_get_trigger_type(idata); - if (type & IRQ_TYPE_EDGE_RISING) + raw_spin_lock_irq(&d->lock); + if (d->status & IRQ_TYPE_EDGE_RISING) bytes[byte] |= BIT(off + 1); - if (type & IRQ_TYPE_EDGE_FALLING) + if (d->status & IRQ_TYPE_EDGE_FALLING) bytes[byte] |= BIT(off + 0); + raw_spin_unlock_irq(&d->lock); edge_change &= ~BIT(i); } @@ -604,13 +626,21 @@ static void twl4030_sih_unmask(struct irq_data *data) static int twl4030_sih_set_type(struct irq_data *data, unsigned trigger) { struct sih_agent *sih = irq_data_get_irq_chip_data(data); + struct irq_desc *desc = irq_to_desc(data->irq); unsigned long flags; + if (!desc) { + pr_err("twl4030: Invalid IRQ: %d\n", data->irq); + return -EINVAL; + } + if (trigger & ~(IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING)) return -EINVAL; spin_lock_irqsave(&sih_agent_lock, flags); - if (irqd_get_trigger_type(data) != trigger) { + if ((desc->status & IRQ_TYPE_SENSE_MASK) != trigger) { + desc->status &= ~IRQ_TYPE_SENSE_MASK; + desc->status |= trigger; sih->edge_change |= BIT(data->irq - sih->irq_base); queue_work(wq, &sih->edge_work); } @@ -650,7 +680,7 @@ static inline int sih_read_isr(const struct sih *sih) */ static void handle_twl4030_sih(unsigned irq, struct irq_desc *desc) { - struct sih_agent *agent = irq_get_handler_data(irq); + struct sih_agent *agent = get_irq_data(irq); const struct sih *sih = agent->sih; int isr; @@ -724,9 +754,9 @@ int twl4030_sih_setup(int module) for (i = 0; i < sih->bits; i++) { irq = irq_base + i; - irq_set_chip_and_handler(irq, &twl4030_sih_irq_chip, - handle_edge_irq); - irq_set_chip_data(irq, agent); + set_irq_chip_and_handler(irq, &twl4030_sih_irq_chip, + handle_edge_irq); + set_irq_chip_data(irq, agent); activate_irq(irq); } @@ -735,8 +765,8 @@ int twl4030_sih_setup(int module) /* replace generic PIH handler (handle_simple_irq) */ irq = sih_mod + twl4030_irq_base; - irq_set_handler_data(irq, agent); - irq_set_chained_handler(irq, handle_twl4030_sih); + set_irq_data(irq, agent); + set_irq_chained_handler(irq, handle_twl4030_sih); pr_info("twl4030: %s (irq %d) chaining IRQs %d..%d\n", sih->name, irq, irq_base, twl4030_irq_next - 1); @@ -785,8 +815,8 @@ int twl4030_init_irq(int irq_num, unsigned irq_base, unsigned irq_end) twl4030_sih_irq_chip.irq_ack = dummy_irq_chip.irq_ack; for (i = irq_base; i < irq_end; i++) { - irq_set_chip_and_handler(i, &twl4030_irq_chip, - handle_simple_irq); + set_irq_chip_and_handler(i, &twl4030_irq_chip, + handle_simple_irq); activate_irq(i); } twl4030_irq_next = i; @@ -826,7 +856,7 @@ int twl4030_init_irq(int irq_num, unsigned irq_base, unsigned irq_end) /* clean up twl4030_sih_setup */ fail: for (i = irq_base; i < irq_end; i++) - irq_set_chip_and_handler(i, NULL, NULL); + set_irq_chip_and_handler(i, NULL, NULL); destroy_workqueue(wq); wq = NULL; return status; diff --git a/trunk/drivers/mfd/twl6030-irq.c b/trunk/drivers/mfd/twl6030-irq.c index fa937052fbab..4082ed73613f 100644 --- a/trunk/drivers/mfd/twl6030-irq.c +++ b/trunk/drivers/mfd/twl6030-irq.c @@ -140,7 +140,22 @@ static int twl6030_irq_thread(void *data) if (sts.int_sts & 0x1) { int module_irq = twl6030_irq_base + twl6030_interrupt_mapping[i]; - generic_handle_irq(module_irq); + struct irq_desc *d = irq_to_desc(module_irq); + + if (!d) { + pr_err("twl6030: Invalid SIH IRQ: %d\n", + module_irq); + return -EINVAL; + } + + /* These can't be masked ... always warn + * if we get any surprises. + */ + if (d->status & IRQ_DISABLED) + note_interrupt(module_irq, d, + IRQ_NONE); + else + d->handle_irq(module_irq, d); } local_irq_enable(); @@ -183,7 +198,7 @@ static inline void activate_irq(int irq) set_irq_flags(irq, IRQF_VALID); #else /* same effect on other architectures */ - irq_set_noprobe(irq); + set_irq_noprobe(irq); #endif } @@ -320,8 +335,8 @@ int twl6030_init_irq(int irq_num, unsigned irq_base, unsigned irq_end) twl6030_irq_chip.irq_set_type = NULL; for (i = irq_base; i < irq_end; i++) { - irq_set_chip_and_handler(i, &twl6030_irq_chip, - handle_simple_irq); + set_irq_chip_and_handler(i, &twl6030_irq_chip, + handle_simple_irq); activate_irq(i); } @@ -350,7 +365,7 @@ int twl6030_init_irq(int irq_num, unsigned irq_base, unsigned irq_end) fail_kthread: for (i = irq_base; i < irq_end; i++) - irq_set_chip_and_handler(i, NULL, NULL); + set_irq_chip_and_handler(i, NULL, NULL); return status; } diff --git a/trunk/drivers/mfd/wl1273-core.c b/trunk/drivers/mfd/wl1273-core.c index 04914f2836c0..f76f6c798046 100644 --- a/trunk/drivers/mfd/wl1273-core.c +++ b/trunk/drivers/mfd/wl1273-core.c @@ -25,7 +25,7 @@ #define DRIVER_DESC "WL1273 FM Radio Core" -static const struct i2c_device_id wl1273_driver_id_table[] = { +static struct i2c_device_id wl1273_driver_id_table[] = { { WL1273_FM_DRIVER_NAME, 0 }, { } }; diff --git a/trunk/drivers/mfd/wm831x-irq.c b/trunk/drivers/mfd/wm831x-irq.c index 23e66af89dea..a5cd17e18d09 100644 --- a/trunk/drivers/mfd/wm831x-irq.c +++ b/trunk/drivers/mfd/wm831x-irq.c @@ -553,17 +553,17 @@ int wm831x_irq_init(struct wm831x *wm831x, int irq) for (cur_irq = wm831x->irq_base; cur_irq < ARRAY_SIZE(wm831x_irqs) + wm831x->irq_base; cur_irq++) { - irq_set_chip_data(cur_irq, wm831x); - irq_set_chip_and_handler(cur_irq, &wm831x_irq_chip, + set_irq_chip_data(cur_irq, wm831x); + set_irq_chip_and_handler(cur_irq, &wm831x_irq_chip, handle_edge_irq); - irq_set_nested_thread(cur_irq, 1); + set_irq_nested_thread(cur_irq, 1); /* ARM needs us to explicitly flag the IRQ as valid * and will set them noprobe when we do so. */ #ifdef CONFIG_ARM set_irq_flags(cur_irq, IRQF_VALID); #else - irq_set_noprobe(cur_irq); + set_irq_noprobe(cur_irq); #endif } diff --git a/trunk/drivers/mfd/wm8350-irq.c b/trunk/drivers/mfd/wm8350-irq.c index ed4b22a167b3..5839966ebd85 100644 --- a/trunk/drivers/mfd/wm8350-irq.c +++ b/trunk/drivers/mfd/wm8350-irq.c @@ -518,17 +518,17 @@ int wm8350_irq_init(struct wm8350 *wm8350, int irq, for (cur_irq = wm8350->irq_base; cur_irq < ARRAY_SIZE(wm8350_irqs) + wm8350->irq_base; cur_irq++) { - irq_set_chip_data(cur_irq, wm8350); - irq_set_chip_and_handler(cur_irq, &wm8350_irq_chip, + set_irq_chip_data(cur_irq, wm8350); + set_irq_chip_and_handler(cur_irq, &wm8350_irq_chip, handle_edge_irq); - irq_set_nested_thread(cur_irq, 1); + set_irq_nested_thread(cur_irq, 1); /* ARM needs us to explicitly flag the IRQ as valid * and will set them noprobe when we do so. */ #ifdef CONFIG_ARM set_irq_flags(cur_irq, IRQF_VALID); #else - irq_set_noprobe(cur_irq); + set_irq_noprobe(cur_irq); #endif } diff --git a/trunk/drivers/mfd/wm8994-irq.c b/trunk/drivers/mfd/wm8994-irq.c index 71c6e8f9aedb..1e3bf4a2ff8e 100644 --- a/trunk/drivers/mfd/wm8994-irq.c +++ b/trunk/drivers/mfd/wm8994-irq.c @@ -278,17 +278,17 @@ int wm8994_irq_init(struct wm8994 *wm8994) for (cur_irq = wm8994->irq_base; cur_irq < ARRAY_SIZE(wm8994_irqs) + wm8994->irq_base; cur_irq++) { - irq_set_chip_data(cur_irq, wm8994); - irq_set_chip_and_handler(cur_irq, &wm8994_irq_chip, + set_irq_chip_data(cur_irq, wm8994); + set_irq_chip_and_handler(cur_irq, &wm8994_irq_chip, handle_edge_irq); - irq_set_nested_thread(cur_irq, 1); + set_irq_nested_thread(cur_irq, 1); /* ARM needs us to explicitly flag the IRQ as valid * and will set them noprobe when we do so. */ #ifdef CONFIG_ARM set_irq_flags(cur_irq, IRQF_VALID); #else - irq_set_noprobe(cur_irq); + set_irq_noprobe(cur_irq); #endif } diff --git a/trunk/drivers/misc/sgi-gru/grufile.c b/trunk/drivers/misc/sgi-gru/grufile.c index 20e4e9395b61..28852dfa310d 100644 --- a/trunk/drivers/misc/sgi-gru/grufile.c +++ b/trunk/drivers/misc/sgi-gru/grufile.c @@ -373,7 +373,7 @@ static int gru_chiplet_setup_tlb_irq(int chiplet, char *irq_name, if (gru_irq_count[chiplet] == 0) { gru_chip[chiplet].name = irq_name; - ret = irq_set_chip(irq, &gru_chip[chiplet]); + ret = set_irq_chip(irq, &gru_chip[chiplet]); if (ret) { printk(KERN_ERR "%s: set_irq_chip failed, errno=%d\n", GRU_DRIVER_ID_STR, -ret); diff --git a/trunk/drivers/mmc/host/sdhci-spear.c b/trunk/drivers/mmc/host/sdhci-spear.c index 60a4c97d3d18..d70c54c7b70a 100644 --- a/trunk/drivers/mmc/host/sdhci-spear.c +++ b/trunk/drivers/mmc/host/sdhci-spear.c @@ -50,7 +50,7 @@ static irqreturn_t sdhci_gpio_irq(int irq, void *dev_id) /* val == 1 -> card removed, val == 0 -> card inserted */ /* if card removed - set irq for low level, else vice versa */ gpio_irq_type = val ? IRQF_TRIGGER_LOW : IRQF_TRIGGER_HIGH; - irq_set_irq_type(irq, gpio_irq_type); + set_irq_type(irq, gpio_irq_type); if (sdhci->data->card_power_gpio >= 0) { if (!sdhci->data->power_always_enb) { diff --git a/trunk/drivers/mtd/Kconfig b/trunk/drivers/mtd/Kconfig index b4567c35a322..77414702cb00 100644 --- a/trunk/drivers/mtd/Kconfig +++ b/trunk/drivers/mtd/Kconfig @@ -33,6 +33,14 @@ config MTD_TESTS should normally be compiled as kernel modules. The modules perform various checks and verifications when loaded. +config MTD_CONCAT + tristate "MTD concatenating support" + help + Support for concatenating several MTD devices into a single + (virtual) one. This allows you to have -for example- a JFFS(2) + file system spanning multiple physical flash chips. If unsure, + say 'Y'. + config MTD_PARTITIONS bool "MTD partitioning support" help @@ -325,16 +333,6 @@ config MTD_OOPS To use, add console=ttyMTDx to the kernel command line, where x is the MTD device number to use. -config MTD_SWAP - tristate "Swap on MTD device support" - depends on MTD && SWAP - select MTD_BLKDEVS - help - Provides volatile block device driver on top of mtd partition - suitable for swapping. The mapping of written blocks is not saved. - The driver provides wear leveling by storing erase counter into the - OOB. - source "drivers/mtd/chips/Kconfig" source "drivers/mtd/maps/Kconfig" diff --git a/trunk/drivers/mtd/Makefile b/trunk/drivers/mtd/Makefile index d578095fb255..d4e7f25b1ebb 100644 --- a/trunk/drivers/mtd/Makefile +++ b/trunk/drivers/mtd/Makefile @@ -4,10 +4,11 @@ # Core functionality. obj-$(CONFIG_MTD) += mtd.o -mtd-y := mtdcore.o mtdsuper.o mtdconcat.o +mtd-y := mtdcore.o mtdsuper.o mtd-$(CONFIG_MTD_PARTITIONS) += mtdpart.o mtd-$(CONFIG_MTD_OF_PARTS) += ofpart.o +obj-$(CONFIG_MTD_CONCAT) += mtdconcat.o obj-$(CONFIG_MTD_REDBOOT_PARTS) += redboot.o obj-$(CONFIG_MTD_CMDLINE_PARTS) += cmdlinepart.o obj-$(CONFIG_MTD_AFS_PARTS) += afs.o @@ -25,7 +26,6 @@ obj-$(CONFIG_RFD_FTL) += rfd_ftl.o obj-$(CONFIG_SSFDC) += ssfdc.o obj-$(CONFIG_SM_FTL) += sm_ftl.o obj-$(CONFIG_MTD_OOPS) += mtdoops.o -obj-$(CONFIG_MTD_SWAP) += mtdswap.o nftl-objs := nftlcore.o nftlmount.o inftl-objs := inftlcore.o inftlmount.o diff --git a/trunk/drivers/mtd/chips/cfi_cmdset_0001.c b/trunk/drivers/mtd/chips/cfi_cmdset_0001.c index 092aef11120c..4aaa88f8ab5f 100644 --- a/trunk/drivers/mtd/chips/cfi_cmdset_0001.c +++ b/trunk/drivers/mtd/chips/cfi_cmdset_0001.c @@ -455,7 +455,7 @@ struct mtd_info *cfi_cmdset_0001(struct map_info *map, int primary) mtd->flags = MTD_CAP_NORFLASH; mtd->name = map->name; mtd->writesize = 1; - mtd->writebufsize = cfi_interleave(cfi) << cfi->cfiq->MaxBufWriteSize; + mtd->writebufsize = 1 << cfi->cfiq->MaxBufWriteSize; mtd->reboot_notifier.notifier_call = cfi_intelext_reboot; diff --git a/trunk/drivers/mtd/chips/cfi_cmdset_0002.c b/trunk/drivers/mtd/chips/cfi_cmdset_0002.c index f9a5331e9445..f072fcfde04e 100644 --- a/trunk/drivers/mtd/chips/cfi_cmdset_0002.c +++ b/trunk/drivers/mtd/chips/cfi_cmdset_0002.c @@ -349,7 +349,6 @@ static struct cfi_fixup cfi_fixup_table[] = { { CFI_MFR_ATMEL, CFI_ID_ANY, fixup_convert_atmel_pri }, #ifdef AMD_BOOTLOC_BUG { CFI_MFR_AMD, CFI_ID_ANY, fixup_amd_bootblock }, - { CFI_MFR_AMIC, CFI_ID_ANY, fixup_amd_bootblock }, { CFI_MFR_MACRONIX, CFI_ID_ANY, fixup_amd_bootblock }, #endif { CFI_MFR_AMD, 0x0050, fixup_use_secsi }, @@ -441,7 +440,7 @@ struct mtd_info *cfi_cmdset_0002(struct map_info *map, int primary) mtd->flags = MTD_CAP_NORFLASH; mtd->name = map->name; mtd->writesize = 1; - mtd->writebufsize = cfi_interleave(cfi) << cfi->cfiq->MaxBufWriteSize; + mtd->writebufsize = 1 << cfi->cfiq->MaxBufWriteSize; DEBUG(MTD_DEBUG_LEVEL3, "MTD %s(): write buffer size %d\n", __func__, mtd->writebufsize); diff --git a/trunk/drivers/mtd/chips/cfi_cmdset_0020.c b/trunk/drivers/mtd/chips/cfi_cmdset_0020.c index ed56ad3884fb..c04b7658abe9 100644 --- a/trunk/drivers/mtd/chips/cfi_cmdset_0020.c +++ b/trunk/drivers/mtd/chips/cfi_cmdset_0020.c @@ -238,7 +238,7 @@ static struct mtd_info *cfi_staa_setup(struct map_info *map) mtd->resume = cfi_staa_resume; mtd->flags = MTD_CAP_NORFLASH & ~MTD_BIT_WRITEABLE; mtd->writesize = 8; /* FIXME: Should be 0 for STMicro flashes w/out ECC */ - mtd->writebufsize = cfi_interleave(cfi) << cfi->cfiq->MaxBufWriteSize; + mtd->writebufsize = 1 << cfi->cfiq->MaxBufWriteSize; map->fldrv = &cfi_staa_chipdrv; __module_get(THIS_MODULE); mtd->name = map->name; diff --git a/trunk/drivers/mtd/devices/m25p80.c b/trunk/drivers/mtd/devices/m25p80.c index 3fb981d4bb51..e4eba6cc1b2e 100644 --- a/trunk/drivers/mtd/devices/m25p80.c +++ b/trunk/drivers/mtd/devices/m25p80.c @@ -655,8 +655,7 @@ static const struct spi_device_id m25p_ids[] = { { "at26df161a", INFO(0x1f4601, 0, 64 * 1024, 32, SECT_4K) }, { "at26df321", INFO(0x1f4700, 0, 64 * 1024, 64, SECT_4K) }, - /* EON -- en25xxx */ - { "en25f32", INFO(0x1c3116, 0, 64 * 1024, 64, SECT_4K) }, + /* EON -- en25pxx */ { "en25p32", INFO(0x1c2016, 0, 64 * 1024, 64, 0) }, { "en25p64", INFO(0x1c2017, 0, 64 * 1024, 128, 0) }, @@ -729,8 +728,6 @@ static const struct spi_device_id m25p_ids[] = { { "m25pe80", INFO(0x208014, 0, 64 * 1024, 16, 0) }, { "m25pe16", INFO(0x208015, 0, 64 * 1024, 32, SECT_4K) }, - { "m25px64", INFO(0x207117, 0, 64 * 1024, 128, 0) }, - /* Winbond -- w25x "blocks" are 64K, "sectors" are 4KiB */ { "w25x10", INFO(0xef3011, 0, 64 * 1024, 2, SECT_4K) }, { "w25x20", INFO(0xef3012, 0, 64 * 1024, 4, SECT_4K) }, diff --git a/trunk/drivers/mtd/devices/mtdram.c b/trunk/drivers/mtd/devices/mtdram.c index 1483e18971ce..26a6e809013d 100644 --- a/trunk/drivers/mtd/devices/mtdram.c +++ b/trunk/drivers/mtd/devices/mtdram.c @@ -121,7 +121,6 @@ int mtdram_init_device(struct mtd_info *mtd, void *mapped_address, mtd->flags = MTD_CAP_RAM; mtd->size = size; mtd->writesize = 1; - mtd->writebufsize = 64; /* Mimic CFI NOR flashes */ mtd->erasesize = MTDRAM_ERASE_SIZE; mtd->priv = mapped_address; diff --git a/trunk/drivers/mtd/devices/phram.c b/trunk/drivers/mtd/devices/phram.c index 8d28fa02a5a2..52393282eaf1 100644 --- a/trunk/drivers/mtd/devices/phram.c +++ b/trunk/drivers/mtd/devices/phram.c @@ -117,7 +117,6 @@ static void unregister_devices(void) list_for_each_entry_safe(this, safe, &phram_list, list) { del_mtd_device(&this->mtd); iounmap(this->mtd.priv); - kfree(this->mtd.name); kfree(this); } } @@ -276,8 +275,6 @@ static int phram_setup(const char *val, struct kernel_param *kp) ret = register_device(name, start, len); if (!ret) pr_info("%s device: %#x at %#x\n", name, len, start); - else - kfree(name); return ret; } diff --git a/trunk/drivers/mtd/maps/Kconfig b/trunk/drivers/mtd/maps/Kconfig index 44b1f46458ca..5d37d315fa98 100644 --- a/trunk/drivers/mtd/maps/Kconfig +++ b/trunk/drivers/mtd/maps/Kconfig @@ -114,7 +114,7 @@ config MTD_SUN_UFLASH config MTD_SC520CDP tristate "CFI Flash device mapped on AMD SC520 CDP" - depends on X86 && MTD_CFI + depends on X86 && MTD_CFI && MTD_CONCAT help The SC520 CDP board has two banks of CFI-compliant chips and one Dual-in-line JEDEC chip. This 'mapping' driver supports that @@ -262,7 +262,7 @@ config MTD_BCM963XX config MTD_DILNETPC tristate "CFI Flash device mapped on DIL/Net PC" - depends on X86 && MTD_PARTITIONS && MTD_CFI_INTELEXT && BROKEN + depends on X86 && MTD_CONCAT && MTD_PARTITIONS && MTD_CFI_INTELEXT && BROKEN help MTD map driver for SSV DIL/Net PC Boards "DNP" and "ADNP". For details, see @@ -552,13 +552,4 @@ config MTD_PISMO When built as a module, it will be called pismo.ko -config MTD_LATCH_ADDR - tristate "Latch-assisted Flash Chip Support" - depends on MTD_COMPLEX_MAPPINGS - help - Map driver which allows flashes to be partially physically addressed - and have the upper address lines set by a board specific code. - - If compiled as a module, it will be called latch-addr-flash. - endmenu diff --git a/trunk/drivers/mtd/maps/Makefile b/trunk/drivers/mtd/maps/Makefile index 08533bd5cba7..c7869c7a6b18 100644 --- a/trunk/drivers/mtd/maps/Makefile +++ b/trunk/drivers/mtd/maps/Makefile @@ -59,4 +59,3 @@ obj-$(CONFIG_MTD_RBTX4939) += rbtx4939-flash.o obj-$(CONFIG_MTD_VMU) += vmu-flash.o obj-$(CONFIG_MTD_GPIO_ADDR) += gpio-addr-flash.o obj-$(CONFIG_MTD_BCM963XX) += bcm963xx-flash.o -obj-$(CONFIG_MTD_LATCH_ADDR) += latch-addr-flash.o diff --git a/trunk/drivers/mtd/maps/ceiva.c b/trunk/drivers/mtd/maps/ceiva.c index e5f645b775ad..c09f4f57093e 100644 --- a/trunk/drivers/mtd/maps/ceiva.c +++ b/trunk/drivers/mtd/maps/ceiva.c @@ -194,10 +194,16 @@ static int __init clps_setup_mtd(struct clps_info *clps, int nr, struct mtd_info * We detected multiple devices. Concatenate * them together. */ +#ifdef CONFIG_MTD_CONCAT *rmtd = mtd_concat_create(subdev, found, "clps flash"); if (*rmtd == NULL) ret = -ENXIO; +#else + printk(KERN_ERR "clps flash: multiple devices " + "found but MTD concat support disabled.\n"); + ret = -ENXIO; +#endif } } diff --git a/trunk/drivers/mtd/maps/integrator-flash.c b/trunk/drivers/mtd/maps/integrator-flash.c index e22ff5adbbf4..2aac41bde8b3 100644 --- a/trunk/drivers/mtd/maps/integrator-flash.c +++ b/trunk/drivers/mtd/maps/integrator-flash.c @@ -202,6 +202,7 @@ static int armflash_probe(struct platform_device *dev) if (info->nr_subdev == 1) info->mtd = info->subdev[0].mtd; else if (info->nr_subdev > 1) { +#ifdef CONFIG_MTD_CONCAT struct mtd_info *cdev[info->nr_subdev]; /* @@ -214,6 +215,11 @@ static int armflash_probe(struct platform_device *dev) dev_name(&dev->dev)); if (info->mtd == NULL) err = -ENXIO; +#else + printk(KERN_ERR "armflash: multiple devices found but " + "MTD concat support disabled.\n"); + err = -ENXIO; +#endif } if (err < 0) @@ -238,8 +244,10 @@ static int armflash_probe(struct platform_device *dev) cleanup: if (info->mtd) { del_mtd_partitions(info->mtd); +#ifdef CONFIG_MTD_CONCAT if (info->mtd != info->subdev[0].mtd) mtd_concat_destroy(info->mtd); +#endif } kfree(info->parts); subdev_err: @@ -264,8 +272,10 @@ static int armflash_remove(struct platform_device *dev) if (info) { if (info->mtd) { del_mtd_partitions(info->mtd); +#ifdef CONFIG_MTD_CONCAT if (info->mtd != info->subdev[0].mtd) mtd_concat_destroy(info->mtd); +#endif } kfree(info->parts); diff --git a/trunk/drivers/mtd/maps/latch-addr-flash.c b/trunk/drivers/mtd/maps/latch-addr-flash.c deleted file mode 100644 index ee2548085334..000000000000 --- a/trunk/drivers/mtd/maps/latch-addr-flash.c +++ /dev/null @@ -1,272 +0,0 @@ -/* - * Interface for NOR flash driver whose high address lines are latched - * - * Copyright © 2000 Nicolas Pitre - * Copyright © 2005-2008 Analog Devices Inc. - * Copyright © 2008 MontaVista Software, Inc. - * - * This file is licensed under the terms of the GNU General Public License - * version 2. This program is licensed "as is" without any warranty of any - * kind, whether express or implied. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define DRIVER_NAME "latch-addr-flash" - -struct latch_addr_flash_info { - struct mtd_info *mtd; - struct map_info map; - struct resource *res; - - void (*set_window)(unsigned long offset, void *data); - void *data; - - /* cache; could be found out of res */ - unsigned long win_mask; - - int nr_parts; - struct mtd_partition *parts; - - spinlock_t lock; -}; - -static map_word lf_read(struct map_info *map, unsigned long ofs) -{ - struct latch_addr_flash_info *info; - map_word datum; - - info = (struct latch_addr_flash_info *)map->map_priv_1; - - spin_lock(&info->lock); - - info->set_window(ofs, info->data); - datum = inline_map_read(map, info->win_mask & ofs); - - spin_unlock(&info->lock); - - return datum; -} - -static void lf_write(struct map_info *map, map_word datum, unsigned long ofs) -{ - struct latch_addr_flash_info *info; - - info = (struct latch_addr_flash_info *)map->map_priv_1; - - spin_lock(&info->lock); - - info->set_window(ofs, info->data); - inline_map_write(map, datum, info->win_mask & ofs); - - spin_unlock(&info->lock); -} - -static void lf_copy_from(struct map_info *map, void *to, - unsigned long from, ssize_t len) -{ - struct latch_addr_flash_info *info = - (struct latch_addr_flash_info *) map->map_priv_1; - unsigned n; - - while (len > 0) { - n = info->win_mask + 1 - (from & info->win_mask); - if (n > len) - n = len; - - spin_lock(&info->lock); - - info->set_window(from, info->data); - memcpy_fromio(to, map->virt + (from & info->win_mask), n); - - spin_unlock(&info->lock); - - to += n; - from += n; - len -= n; - } -} - -static char *rom_probe_types[] = { "cfi_probe", NULL }; - -static char *part_probe_types[] = { "cmdlinepart", NULL }; - -static int latch_addr_flash_remove(struct platform_device *dev) -{ - struct latch_addr_flash_info *info; - struct latch_addr_flash_data *latch_addr_data; - - info = platform_get_drvdata(dev); - if (info == NULL) - return 0; - platform_set_drvdata(dev, NULL); - - latch_addr_data = dev->dev.platform_data; - - if (info->mtd != NULL) { - if (mtd_has_partitions()) { - if (info->nr_parts) { - del_mtd_partitions(info->mtd); - kfree(info->parts); - } else if (latch_addr_data->nr_parts) { - del_mtd_partitions(info->mtd); - } else { - del_mtd_device(info->mtd); - } - } else { - del_mtd_device(info->mtd); - } - map_destroy(info->mtd); - } - - if (info->map.virt != NULL) - iounmap(info->map.virt); - - if (info->res != NULL) - release_mem_region(info->res->start, resource_size(info->res)); - - kfree(info); - - if (latch_addr_data->done) - latch_addr_data->done(latch_addr_data->data); - - return 0; -} - -static int __devinit latch_addr_flash_probe(struct platform_device *dev) -{ - struct latch_addr_flash_data *latch_addr_data; - struct latch_addr_flash_info *info; - resource_size_t win_base = dev->resource->start; - resource_size_t win_size = resource_size(dev->resource); - char **probe_type; - int chipsel; - int err; - - latch_addr_data = dev->dev.platform_data; - if (latch_addr_data == NULL) - return -ENODEV; - - pr_notice("latch-addr platform flash device: %#llx byte " - "window at %#.8llx\n", - (unsigned long long)win_size, (unsigned long long)win_base); - - chipsel = dev->id; - - if (latch_addr_data->init) { - err = latch_addr_data->init(latch_addr_data->data, chipsel); - if (err != 0) - return err; - } - - info = kzalloc(sizeof(struct latch_addr_flash_info), GFP_KERNEL); - if (info == NULL) { - err = -ENOMEM; - goto done; - } - - platform_set_drvdata(dev, info); - - info->res = request_mem_region(win_base, win_size, DRIVER_NAME); - if (info->res == NULL) { - dev_err(&dev->dev, "Could not reserve memory region\n"); - err = -EBUSY; - goto free_info; - } - - info->map.name = DRIVER_NAME; - info->map.size = latch_addr_data->size; - info->map.bankwidth = latch_addr_data->width; - - info->map.phys = NO_XIP; - info->map.virt = ioremap(win_base, win_size); - if (!info->map.virt) { - err = -ENOMEM; - goto free_res; - } - - info->map.map_priv_1 = (unsigned long)info; - - info->map.read = lf_read; - info->map.copy_from = lf_copy_from; - info->map.write = lf_write; - info->set_window = latch_addr_data->set_window; - info->data = latch_addr_data->data; - info->win_mask = win_size - 1; - - spin_lock_init(&info->lock); - - for (probe_type = rom_probe_types; !info->mtd && *probe_type; - probe_type++) - info->mtd = do_map_probe(*probe_type, &info->map); - - if (info->mtd == NULL) { - dev_err(&dev->dev, "map_probe failed\n"); - err = -ENODEV; - goto iounmap; - } - info->mtd->owner = THIS_MODULE; - - if (mtd_has_partitions()) { - - err = parse_mtd_partitions(info->mtd, - (const char **)part_probe_types, - &info->parts, 0); - if (err > 0) { - add_mtd_partitions(info->mtd, info->parts, err); - return 0; - } - if (latch_addr_data->nr_parts) { - pr_notice("Using latch-addr-flash partition information\n"); - add_mtd_partitions(info->mtd, latch_addr_data->parts, - latch_addr_data->nr_parts); - return 0; - } - } - add_mtd_device(info->mtd); - return 0; - -iounmap: - iounmap(info->map.virt); -free_res: - release_mem_region(info->res->start, resource_size(info->res)); -free_info: - kfree(info); -done: - if (latch_addr_data->done) - latch_addr_data->done(latch_addr_data->data); - return err; -} - -static struct platform_driver latch_addr_flash_driver = { - .probe = latch_addr_flash_probe, - .remove = __devexit_p(latch_addr_flash_remove), - .driver = { - .name = DRIVER_NAME, - }, -}; - -static int __init latch_addr_flash_init(void) -{ - return platform_driver_register(&latch_addr_flash_driver); -} -module_init(latch_addr_flash_init); - -static void __exit latch_addr_flash_exit(void) -{ - platform_driver_unregister(&latch_addr_flash_driver); -} -module_exit(latch_addr_flash_exit); - -MODULE_AUTHOR("David Griego "); -MODULE_DESCRIPTION("MTD map driver for flashes addressed physically with upper " - "address lines being set board specifically"); -MODULE_LICENSE("GPL v2"); diff --git a/trunk/drivers/mtd/maps/physmap.c b/trunk/drivers/mtd/maps/physmap.c index 7522df4f71f1..4c18b98a3110 100644 --- a/trunk/drivers/mtd/maps/physmap.c +++ b/trunk/drivers/mtd/maps/physmap.c @@ -59,8 +59,10 @@ static int physmap_flash_remove(struct platform_device *dev) #else del_mtd_device(info->cmtd); #endif +#ifdef CONFIG_MTD_CONCAT if (info->cmtd != info->mtd[0]) mtd_concat_destroy(info->cmtd); +#endif } for (i = 0; i < MAX_RESOURCES; i++) { @@ -157,9 +159,15 @@ static int physmap_flash_probe(struct platform_device *dev) /* * We detected multiple devices. Concatenate them together. */ +#ifdef CONFIG_MTD_CONCAT info->cmtd = mtd_concat_create(info->mtd, devices_found, dev_name(&dev->dev)); if (info->cmtd == NULL) err = -ENXIO; +#else + printk(KERN_ERR "physmap-flash: multiple devices " + "found but MTD concat support disabled.\n"); + err = -ENXIO; +#endif } if (err) goto err_out; diff --git a/trunk/drivers/mtd/maps/physmap_of.c b/trunk/drivers/mtd/maps/physmap_of.c index bd483f0c57e1..3db0cb083d31 100644 --- a/trunk/drivers/mtd/maps/physmap_of.c +++ b/trunk/drivers/mtd/maps/physmap_of.c @@ -104,10 +104,12 @@ static int of_flash_remove(struct platform_device *dev) return 0; dev_set_drvdata(&dev->dev, NULL); +#ifdef CONFIG_MTD_CONCAT if (info->cmtd != info->list[0].mtd) { del_mtd_device(info->cmtd); mtd_concat_destroy(info->cmtd); } +#endif if (info->cmtd) { if (OF_FLASH_PARTS(info)) { @@ -335,10 +337,16 @@ static int __devinit of_flash_probe(struct platform_device *dev) /* * We detected multiple devices. Concatenate them together. */ +#ifdef CONFIG_MTD_CONCAT info->cmtd = mtd_concat_create(mtd_list, info->list_size, dev_name(&dev->dev)); if (info->cmtd == NULL) err = -ENXIO; +#else + printk(KERN_ERR "physmap_of: multiple devices " + "found but MTD concat support disabled.\n"); + err = -ENXIO; +#endif } if (err) goto err_out; diff --git a/trunk/drivers/mtd/maps/sa1100-flash.c b/trunk/drivers/mtd/maps/sa1100-flash.c index da875908ea8e..f3af87e08ecd 100644 --- a/trunk/drivers/mtd/maps/sa1100-flash.c +++ b/trunk/drivers/mtd/maps/sa1100-flash.c @@ -232,8 +232,10 @@ static void sa1100_destroy(struct sa_info *info, struct flash_platform_data *pla else del_mtd_partitions(info->mtd); #endif +#ifdef CONFIG_MTD_CONCAT if (info->mtd != info->subdev[0].mtd) mtd_concat_destroy(info->mtd); +#endif } kfree(info->parts); @@ -319,6 +321,7 @@ sa1100_setup_mtd(struct platform_device *pdev, struct flash_platform_data *plat) info->mtd = info->subdev[0].mtd; ret = 0; } else if (info->num_subdev > 1) { +#ifdef CONFIG_MTD_CONCAT struct mtd_info *cdev[nr]; /* * We detected multiple devices. Concatenate them together. @@ -330,6 +333,11 @@ sa1100_setup_mtd(struct platform_device *pdev, struct flash_platform_data *plat) plat->name); if (info->mtd == NULL) ret = -ENXIO; +#else + printk(KERN_ERR "SA1100 flash: multiple devices " + "found but MTD concat support disabled.\n"); + ret = -ENXIO; +#endif } if (ret == 0) diff --git a/trunk/drivers/mtd/maps/ts5500_flash.c b/trunk/drivers/mtd/maps/ts5500_flash.c index e02dfa9d4ddd..e2147bf11c88 100644 --- a/trunk/drivers/mtd/maps/ts5500_flash.c +++ b/trunk/drivers/mtd/maps/ts5500_flash.c @@ -94,6 +94,7 @@ static int __init init_ts5500_map(void) return 0; err1: + map_destroy(mymtd); iounmap(ts5500_map.virt); err2: return rc; diff --git a/trunk/drivers/mtd/mtd_blkdevs.c b/trunk/drivers/mtd/mtd_blkdevs.c index a534e1f0c348..e0a2373bf0e2 100644 --- a/trunk/drivers/mtd/mtd_blkdevs.c +++ b/trunk/drivers/mtd/mtd_blkdevs.c @@ -40,7 +40,7 @@ static LIST_HEAD(blktrans_majors); static DEFINE_MUTEX(blktrans_ref_mutex); -static void blktrans_dev_release(struct kref *kref) +void blktrans_dev_release(struct kref *kref) { struct mtd_blktrans_dev *dev = container_of(kref, struct mtd_blktrans_dev, ref); @@ -67,7 +67,7 @@ static struct mtd_blktrans_dev *blktrans_dev_get(struct gendisk *disk) return dev; } -static void blktrans_dev_put(struct mtd_blktrans_dev *dev) +void blktrans_dev_put(struct mtd_blktrans_dev *dev) { mutex_lock(&blktrans_ref_mutex); kref_put(&dev->ref, blktrans_dev_release); @@ -119,43 +119,18 @@ static int do_blktrans_request(struct mtd_blktrans_ops *tr, } } -int mtd_blktrans_cease_background(struct mtd_blktrans_dev *dev) -{ - if (kthread_should_stop()) - return 1; - - return dev->bg_stop; -} -EXPORT_SYMBOL_GPL(mtd_blktrans_cease_background); - static int mtd_blktrans_thread(void *arg) { struct mtd_blktrans_dev *dev = arg; - struct mtd_blktrans_ops *tr = dev->tr; struct request_queue *rq = dev->rq; struct request *req = NULL; - int background_done = 0; spin_lock_irq(rq->queue_lock); while (!kthread_should_stop()) { int res; - dev->bg_stop = false; if (!req && !(req = blk_fetch_request(rq))) { - if (tr->background && !background_done) { - spin_unlock_irq(rq->queue_lock); - mutex_lock(&dev->lock); - tr->background(dev); - mutex_unlock(&dev->lock); - spin_lock_irq(rq->queue_lock); - /* - * Do background processing just once per idle - * period. - */ - background_done = !dev->bg_stop; - continue; - } set_current_state(TASK_INTERRUPTIBLE); if (kthread_should_stop()) @@ -177,8 +152,6 @@ static int mtd_blktrans_thread(void *arg) if (!__blk_end_request_cur(req, res)) req = NULL; - - background_done = 0; } if (req) @@ -199,10 +172,8 @@ static void mtd_blktrans_request(struct request_queue *rq) if (!dev) while ((req = blk_fetch_request(rq)) != NULL) __blk_end_request_all(req, -ENODEV); - else { - dev->bg_stop = true; + else wake_up_process(dev->thread); - } } static int blktrans_open(struct block_device *bdev, fmode_t mode) @@ -408,10 +379,9 @@ int add_mtd_blktrans_dev(struct mtd_blktrans_dev *new) new->rq->queuedata = new; blk_queue_logical_block_size(new->rq, tr->blksize); - if (tr->discard) { - queue_flag_set_unlocked(QUEUE_FLAG_DISCARD, new->rq); - new->rq->limits.max_discard_sectors = UINT_MAX; - } + if (tr->discard) + queue_flag_set_unlocked(QUEUE_FLAG_DISCARD, + new->rq); gd->queue = new->rq; diff --git a/trunk/drivers/mtd/mtdconcat.c b/trunk/drivers/mtd/mtdconcat.c index 5060e608ea5d..5f5777bd3f75 100644 --- a/trunk/drivers/mtd/mtdconcat.c +++ b/trunk/drivers/mtd/mtdconcat.c @@ -750,7 +750,6 @@ struct mtd_info *mtd_concat_create(struct mtd_info *subdev[], /* subdevices to c struct mtd_concat *concat; uint32_t max_erasesize, curr_erasesize; int num_erase_region; - int max_writebufsize = 0; printk(KERN_NOTICE "Concatenating MTD devices:\n"); for (i = 0; i < num_devs; i++) @@ -777,12 +776,7 @@ struct mtd_info *mtd_concat_create(struct mtd_info *subdev[], /* subdevices to c concat->mtd.size = subdev[0]->size; concat->mtd.erasesize = subdev[0]->erasesize; concat->mtd.writesize = subdev[0]->writesize; - - for (i = 0; i < num_devs; i++) - if (max_writebufsize < subdev[i]->writebufsize) - max_writebufsize = subdev[i]->writebufsize; - concat->mtd.writebufsize = max_writebufsize; - + concat->mtd.writebufsize = subdev[0]->writebufsize; concat->mtd.subpage_sft = subdev[0]->subpage_sft; concat->mtd.oobsize = subdev[0]->oobsize; concat->mtd.oobavail = subdev[0]->oobavail; diff --git a/trunk/drivers/mtd/mtdcore.c b/trunk/drivers/mtd/mtdcore.c index da69bc8a5a7d..527cebf58da4 100644 --- a/trunk/drivers/mtd/mtdcore.c +++ b/trunk/drivers/mtd/mtdcore.c @@ -43,7 +43,7 @@ * backing device capabilities for non-mappable devices (such as NAND flash) * - permits private mappings, copies are taken of the data */ -static struct backing_dev_info mtd_bdi_unmappable = { +struct backing_dev_info mtd_bdi_unmappable = { .capabilities = BDI_CAP_MAP_COPY, }; @@ -52,7 +52,7 @@ static struct backing_dev_info mtd_bdi_unmappable = { * - permits private mappings, copies are taken of the data * - permits non-writable shared mappings */ -static struct backing_dev_info mtd_bdi_ro_mappable = { +struct backing_dev_info mtd_bdi_ro_mappable = { .capabilities = (BDI_CAP_MAP_COPY | BDI_CAP_MAP_DIRECT | BDI_CAP_EXEC_MAP | BDI_CAP_READ_MAP), }; @@ -62,7 +62,7 @@ static struct backing_dev_info mtd_bdi_ro_mappable = { * - permits private mappings, copies are taken of the data * - permits non-writable shared mappings */ -static struct backing_dev_info mtd_bdi_rw_mappable = { +struct backing_dev_info mtd_bdi_rw_mappable = { .capabilities = (BDI_CAP_MAP_COPY | BDI_CAP_MAP_DIRECT | BDI_CAP_EXEC_MAP | BDI_CAP_READ_MAP | BDI_CAP_WRITE_MAP), diff --git a/trunk/drivers/mtd/mtdswap.c b/trunk/drivers/mtd/mtdswap.c deleted file mode 100644 index 237913c5c92c..000000000000 --- a/trunk/drivers/mtd/mtdswap.c +++ /dev/null @@ -1,1587 +0,0 @@ -/* - * Swap block device support for MTDs - * Turns an MTD device into a swap device with block wear leveling - * - * Copyright © 2007,2011 Nokia Corporation. All rights reserved. - * - * Authors: Jarkko Lavinen - * - * Based on Richard Purdie's earlier implementation in 2007. Background - * support and lock-less operation written by Adrian Hunter. - * - * 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. - * - * 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., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define MTDSWAP_PREFIX "mtdswap" - -/* - * The number of free eraseblocks when GC should stop - */ -#define CLEAN_BLOCK_THRESHOLD 20 - -/* - * Number of free eraseblocks below which GC can also collect low frag - * blocks. - */ -#define LOW_FRAG_GC_TRESHOLD 5 - -/* - * Wear level cost amortization. We want to do wear leveling on the background - * without disturbing gc too much. This is made by defining max GC frequency. - * Frequency value 6 means 1/6 of the GC passes will pick an erase block based - * on the biggest wear difference rather than the biggest dirtiness. - * - * The lower freq2 should be chosen so that it makes sure the maximum erase - * difference will decrease even if a malicious application is deliberately - * trying to make erase differences large. - */ -#define MAX_ERASE_DIFF 4000 -#define COLLECT_NONDIRTY_BASE MAX_ERASE_DIFF -#define COLLECT_NONDIRTY_FREQ1 6 -#define COLLECT_NONDIRTY_FREQ2 4 - -#define PAGE_UNDEF UINT_MAX -#define BLOCK_UNDEF UINT_MAX -#define BLOCK_ERROR (UINT_MAX - 1) -#define BLOCK_MAX (UINT_MAX - 2) - -#define EBLOCK_BAD (1 << 0) -#define EBLOCK_NOMAGIC (1 << 1) -#define EBLOCK_BITFLIP (1 << 2) -#define EBLOCK_FAILED (1 << 3) -#define EBLOCK_READERR (1 << 4) -#define EBLOCK_IDX_SHIFT 5 - -struct swap_eb { - struct rb_node rb; - struct rb_root *root; - - unsigned int flags; - unsigned int active_count; - unsigned int erase_count; - unsigned int pad; /* speeds up pointer decremtnt */ -}; - -#define MTDSWAP_ECNT_MIN(rbroot) (rb_entry(rb_first(rbroot), struct swap_eb, \ - rb)->erase_count) -#define MTDSWAP_ECNT_MAX(rbroot) (rb_entry(rb_last(rbroot), struct swap_eb, \ - rb)->erase_count) - -struct mtdswap_tree { - struct rb_root root; - unsigned int count; -}; - -enum { - MTDSWAP_CLEAN, - MTDSWAP_USED, - MTDSWAP_LOWFRAG, - MTDSWAP_HIFRAG, - MTDSWAP_DIRTY, - MTDSWAP_BITFLIP, - MTDSWAP_FAILING, - MTDSWAP_TREE_CNT, -}; - -struct mtdswap_dev { - struct mtd_blktrans_dev *mbd_dev; - struct mtd_info *mtd; - struct device *dev; - - unsigned int *page_data; - unsigned int *revmap; - - unsigned int eblks; - unsigned int spare_eblks; - unsigned int pages_per_eblk; - unsigned int max_erase_count; - struct swap_eb *eb_data; - - struct mtdswap_tree trees[MTDSWAP_TREE_CNT]; - - unsigned long long sect_read_count; - unsigned long long sect_write_count; - unsigned long long mtd_write_count; - unsigned long long mtd_read_count; - unsigned long long discard_count; - unsigned long long discard_page_count; - - unsigned int curr_write_pos; - struct swap_eb *curr_write; - - char *page_buf; - char *oob_buf; - - struct dentry *debugfs_root; -}; - -struct mtdswap_oobdata { - __le16 magic; - __le32 count; -} __attribute__((packed)); - -#define MTDSWAP_MAGIC_CLEAN 0x2095 -#define MTDSWAP_MAGIC_DIRTY (MTDSWAP_MAGIC_CLEAN + 1) -#define MTDSWAP_TYPE_CLEAN 0 -#define MTDSWAP_TYPE_DIRTY 1 -#define MTDSWAP_OOBSIZE sizeof(struct mtdswap_oobdata) - -#define MTDSWAP_ERASE_RETRIES 3 /* Before marking erase block bad */ -#define MTDSWAP_IO_RETRIES 3 - -enum { - MTDSWAP_SCANNED_CLEAN, - MTDSWAP_SCANNED_DIRTY, - MTDSWAP_SCANNED_BITFLIP, - MTDSWAP_SCANNED_BAD, -}; - -/* - * In the worst case mtdswap_writesect() has allocated the last clean - * page from the current block and is then pre-empted by the GC - * thread. The thread can consume a full erase block when moving a - * block. - */ -#define MIN_SPARE_EBLOCKS 2 -#define MIN_ERASE_BLOCKS (MIN_SPARE_EBLOCKS + 1) - -#define TREE_ROOT(d, name) (&d->trees[MTDSWAP_ ## name].root) -#define TREE_EMPTY(d, name) (TREE_ROOT(d, name)->rb_node == NULL) -#define TREE_NONEMPTY(d, name) (!TREE_EMPTY(d, name)) -#define TREE_COUNT(d, name) (d->trees[MTDSWAP_ ## name].count) - -#define MTDSWAP_MBD_TO_MTDSWAP(dev) ((struct mtdswap_dev *)dev->priv) - -static char partitions[128] = ""; -module_param_string(partitions, partitions, sizeof(partitions), 0444); -MODULE_PARM_DESC(partitions, "MTD partition numbers to use as swap " - "partitions=\"1,3,5\""); - -static unsigned int spare_eblocks = 10; -module_param(spare_eblocks, uint, 0444); -MODULE_PARM_DESC(spare_eblocks, "Percentage of spare erase blocks for " - "garbage collection (default 10%)"); - -static bool header; /* false */ -module_param(header, bool, 0444); -MODULE_PARM_DESC(header, - "Include builtin swap header (default 0, without header)"); - -static int mtdswap_gc(struct mtdswap_dev *d, unsigned int background); - -static loff_t mtdswap_eb_offset(struct mtdswap_dev *d, struct swap_eb *eb) -{ - return (loff_t)(eb - d->eb_data) * d->mtd->erasesize; -} - -static void mtdswap_eb_detach(struct mtdswap_dev *d, struct swap_eb *eb) -{ - unsigned int oldidx; - struct mtdswap_tree *tp; - - if (eb->root) { - tp = container_of(eb->root, struct mtdswap_tree, root); - oldidx = tp - &d->trees[0]; - - d->trees[oldidx].count--; - rb_erase(&eb->rb, eb->root); - } -} - -static void __mtdswap_rb_add(struct rb_root *root, struct swap_eb *eb) -{ - struct rb_node **p, *parent = NULL; - struct swap_eb *cur; - - p = &root->rb_node; - while (*p) { - parent = *p; - cur = rb_entry(parent, struct swap_eb, rb); - if (eb->erase_count > cur->erase_count) - p = &(*p)->rb_right; - else - p = &(*p)->rb_left; - } - - rb_link_node(&eb->rb, parent, p); - rb_insert_color(&eb->rb, root); -} - -static void mtdswap_rb_add(struct mtdswap_dev *d, struct swap_eb *eb, int idx) -{ - struct rb_root *root; - - if (eb->root == &d->trees[idx].root) - return; - - mtdswap_eb_detach(d, eb); - root = &d->trees[idx].root; - __mtdswap_rb_add(root, eb); - eb->root = root; - d->trees[idx].count++; -} - -static struct rb_node *mtdswap_rb_index(struct rb_root *root, unsigned int idx) -{ - struct rb_node *p; - unsigned int i; - - p = rb_first(root); - i = 0; - while (i < idx && p) { - p = rb_next(p); - i++; - } - - return p; -} - -static int mtdswap_handle_badblock(struct mtdswap_dev *d, struct swap_eb *eb) -{ - int ret; - loff_t offset; - - d->spare_eblks--; - eb->flags |= EBLOCK_BAD; - mtdswap_eb_detach(d, eb); - eb->root = NULL; - - /* badblocks not supported */ - if (!d->mtd->block_markbad) - return 1; - - offset = mtdswap_eb_offset(d, eb); - dev_warn(d->dev, "Marking bad block at %08llx\n", offset); - ret = d->mtd->block_markbad(d->mtd, offset); - - if (ret) { - dev_warn(d->dev, "Mark block bad failed for block at %08llx " - "error %d\n", offset, ret); - return ret; - } - - return 1; - -} - -static int mtdswap_handle_write_error(struct mtdswap_dev *d, struct swap_eb *eb) -{ - unsigned int marked = eb->flags & EBLOCK_FAILED; - struct swap_eb *curr_write = d->curr_write; - - eb->flags |= EBLOCK_FAILED; - if (curr_write == eb) { - d->curr_write = NULL; - - if (!marked && d->curr_write_pos != 0) { - mtdswap_rb_add(d, eb, MTDSWAP_FAILING); - return 0; - } - } - - return mtdswap_handle_badblock(d, eb); -} - -static int mtdswap_read_oob(struct mtdswap_dev *d, loff_t from, - struct mtd_oob_ops *ops) -{ - int ret = d->mtd->read_oob(d->mtd, from, ops); - - if (ret == -EUCLEAN) - return ret; - - if (ret) { - dev_warn(d->dev, "Read OOB failed %d for block at %08llx\n", - ret, from); - return ret; - } - - if (ops->oobretlen < ops->ooblen) { - dev_warn(d->dev, "Read OOB return short read (%zd bytes not " - "%zd) for block at %08llx\n", - ops->oobretlen, ops->ooblen, from); - return -EIO; - } - - return 0; -} - -static int mtdswap_read_markers(struct mtdswap_dev *d, struct swap_eb *eb) -{ - struct mtdswap_oobdata *data, *data2; - int ret; - loff_t offset; - struct mtd_oob_ops ops; - - offset = mtdswap_eb_offset(d, eb); - - /* Check first if the block is bad. */ - if (d->mtd->block_isbad && d->mtd->block_isbad(d->mtd, offset)) - return MTDSWAP_SCANNED_BAD; - - ops.ooblen = 2 * d->mtd->ecclayout->oobavail; - ops.oobbuf = d->oob_buf; - ops.ooboffs = 0; - ops.datbuf = NULL; - ops.mode = MTD_OOB_AUTO; - - ret = mtdswap_read_oob(d, offset, &ops); - - if (ret && ret != -EUCLEAN) - return ret; - - data = (struct mtdswap_oobdata *)d->oob_buf; - data2 = (struct mtdswap_oobdata *) - (d->oob_buf + d->mtd->ecclayout->oobavail); - - if (le16_to_cpu(data->magic) == MTDSWAP_MAGIC_CLEAN) { - eb->erase_count = le32_to_cpu(data->count); - if (ret == -EUCLEAN) - ret = MTDSWAP_SCANNED_BITFLIP; - else { - if (le16_to_cpu(data2->magic) == MTDSWAP_MAGIC_DIRTY) - ret = MTDSWAP_SCANNED_DIRTY; - else - ret = MTDSWAP_SCANNED_CLEAN; - } - } else { - eb->flags |= EBLOCK_NOMAGIC; - ret = MTDSWAP_SCANNED_DIRTY; - } - - return ret; -} - -static int mtdswap_write_marker(struct mtdswap_dev *d, struct swap_eb *eb, - u16 marker) -{ - struct mtdswap_oobdata n; - int ret; - loff_t offset; - struct mtd_oob_ops ops; - - ops.ooboffs = 0; - ops.oobbuf = (uint8_t *)&n; - ops.mode = MTD_OOB_AUTO; - ops.datbuf = NULL; - - if (marker == MTDSWAP_TYPE_CLEAN) { - n.magic = cpu_to_le16(MTDSWAP_MAGIC_CLEAN); - n.count = cpu_to_le32(eb->erase_count); - ops.ooblen = MTDSWAP_OOBSIZE; - offset = mtdswap_eb_offset(d, eb); - } else { - n.magic = cpu_to_le16(MTDSWAP_MAGIC_DIRTY); - ops.ooblen = sizeof(n.magic); - offset = mtdswap_eb_offset(d, eb) + d->mtd->writesize; - } - - ret = d->mtd->write_oob(d->mtd, offset , &ops); - - if (ret) { - dev_warn(d->dev, "Write OOB failed for block at %08llx " - "error %d\n", offset, ret); - if (ret == -EIO || ret == -EBADMSG) - mtdswap_handle_write_error(d, eb); - return ret; - } - - if (ops.oobretlen != ops.ooblen) { - dev_warn(d->dev, "Short OOB write for block at %08llx: " - "%zd not %zd\n", - offset, ops.oobretlen, ops.ooblen); - return ret; - } - - return 0; -} - -/* - * Are there any erase blocks without MAGIC_CLEAN header, presumably - * because power was cut off after erase but before header write? We - * need to guestimate the erase count. - */ -static void mtdswap_check_counts(struct mtdswap_dev *d) -{ - struct rb_root hist_root = RB_ROOT; - struct rb_node *medrb; - struct swap_eb *eb; - unsigned int i, cnt, median; - - cnt = 0; - for (i = 0; i < d->eblks; i++) { - eb = d->eb_data + i; - - if (eb->flags & (EBLOCK_NOMAGIC | EBLOCK_BAD | EBLOCK_READERR)) - continue; - - __mtdswap_rb_add(&hist_root, eb); - cnt++; - } - - if (cnt == 0) - return; - - medrb = mtdswap_rb_index(&hist_root, cnt / 2); - median = rb_entry(medrb, struct swap_eb, rb)->erase_count; - - d->max_erase_count = MTDSWAP_ECNT_MAX(&hist_root); - - for (i = 0; i < d->eblks; i++) { - eb = d->eb_data + i; - - if (eb->flags & (EBLOCK_NOMAGIC | EBLOCK_READERR)) - eb->erase_count = median; - - if (eb->flags & (EBLOCK_NOMAGIC | EBLOCK_BAD | EBLOCK_READERR)) - continue; - - rb_erase(&eb->rb, &hist_root); - } -} - -static void mtdswap_scan_eblks(struct mtdswap_dev *d) -{ - int status; - unsigned int i, idx; - struct swap_eb *eb; - - for (i = 0; i < d->eblks; i++) { - eb = d->eb_data + i; - - status = mtdswap_read_markers(d, eb); - if (status < 0) - eb->flags |= EBLOCK_READERR; - else if (status == MTDSWAP_SCANNED_BAD) { - eb->flags |= EBLOCK_BAD; - continue; - } - - switch (status) { - case MTDSWAP_SCANNED_CLEAN: - idx = MTDSWAP_CLEAN; - break; - case MTDSWAP_SCANNED_DIRTY: - case MTDSWAP_SCANNED_BITFLIP: - idx = MTDSWAP_DIRTY; - break; - default: - idx = MTDSWAP_FAILING; - } - - eb->flags |= (idx << EBLOCK_IDX_SHIFT); - } - - mtdswap_check_counts(d); - - for (i = 0; i < d->eblks; i++) { - eb = d->eb_data + i; - - if (eb->flags & EBLOCK_BAD) - continue; - - idx = eb->flags >> EBLOCK_IDX_SHIFT; - mtdswap_rb_add(d, eb, idx); - } -} - -/* - * Place eblk into a tree corresponding to its number of active blocks - * it contains. - */ -static void mtdswap_store_eb(struct mtdswap_dev *d, struct swap_eb *eb) -{ - unsigned int weight = eb->active_count; - unsigned int maxweight = d->pages_per_eblk; - - if (eb == d->curr_write) - return; - - if (eb->flags & EBLOCK_BITFLIP) - mtdswap_rb_add(d, eb, MTDSWAP_BITFLIP); - else if (eb->flags & (EBLOCK_READERR | EBLOCK_FAILED)) - mtdswap_rb_add(d, eb, MTDSWAP_FAILING); - if (weight == maxweight) - mtdswap_rb_add(d, eb, MTDSWAP_USED); - else if (weight == 0) - mtdswap_rb_add(d, eb, MTDSWAP_DIRTY); - else if (weight > (maxweight/2)) - mtdswap_rb_add(d, eb, MTDSWAP_LOWFRAG); - else - mtdswap_rb_add(d, eb, MTDSWAP_HIFRAG); -} - - -static void mtdswap_erase_callback(struct erase_info *done) -{ - wait_queue_head_t *wait_q = (wait_queue_head_t *)done->priv; - wake_up(wait_q); -} - -static int mtdswap_erase_block(struct mtdswap_dev *d, struct swap_eb *eb) -{ - struct mtd_info *mtd = d->mtd; - struct erase_info erase; - wait_queue_head_t wq; - unsigned int retries = 0; - int ret; - - eb->erase_count++; - if (eb->erase_count > d->max_erase_count) - d->max_erase_count = eb->erase_count; - -retry: - init_waitqueue_head(&wq); - memset(&erase, 0, sizeof(struct erase_info)); - - erase.mtd = mtd; - erase.callback = mtdswap_erase_callback; - erase.addr = mtdswap_eb_offset(d, eb); - erase.len = mtd->erasesize; - erase.priv = (u_long)&wq; - - ret = mtd->erase(mtd, &erase); - if (ret) { - if (retries++ < MTDSWAP_ERASE_RETRIES) { - dev_warn(d->dev, - "erase of erase block %#llx on %s failed", - erase.addr, mtd->name); - yield(); - goto retry; - } - - dev_err(d->dev, "Cannot erase erase block %#llx on %s\n", - erase.addr, mtd->name); - - mtdswap_handle_badblock(d, eb); - return -EIO; - } - - ret = wait_event_interruptible(wq, erase.state == MTD_ERASE_DONE || - erase.state == MTD_ERASE_FAILED); - if (ret) { - dev_err(d->dev, "Interrupted erase block %#llx erassure on %s", - erase.addr, mtd->name); - return -EINTR; - } - - if (erase.state == MTD_ERASE_FAILED) { - if (retries++ < MTDSWAP_ERASE_RETRIES) { - dev_warn(d->dev, - "erase of erase block %#llx on %s failed", - erase.addr, mtd->name); - yield(); - goto retry; - } - - mtdswap_handle_badblock(d, eb); - return -EIO; - } - - return 0; -} - -static int mtdswap_map_free_block(struct mtdswap_dev *d, unsigned int page, - unsigned int *block) -{ - int ret; - struct swap_eb *old_eb = d->curr_write; - struct rb_root *clean_root; - struct swap_eb *eb; - - if (old_eb == NULL || d->curr_write_pos >= d->pages_per_eblk) { - do { - if (TREE_EMPTY(d, CLEAN)) - return -ENOSPC; - - clean_root = TREE_ROOT(d, CLEAN); - eb = rb_entry(rb_first(clean_root), struct swap_eb, rb); - rb_erase(&eb->rb, clean_root); - eb->root = NULL; - TREE_COUNT(d, CLEAN)--; - - ret = mtdswap_write_marker(d, eb, MTDSWAP_TYPE_DIRTY); - } while (ret == -EIO || ret == -EBADMSG); - - if (ret) - return ret; - - d->curr_write_pos = 0; - d->curr_write = eb; - if (old_eb) - mtdswap_store_eb(d, old_eb); - } - - *block = (d->curr_write - d->eb_data) * d->pages_per_eblk + - d->curr_write_pos; - - d->curr_write->active_count++; - d->revmap[*block] = page; - d->curr_write_pos++; - - return 0; -} - -static unsigned int mtdswap_free_page_cnt(struct mtdswap_dev *d) -{ - return TREE_COUNT(d, CLEAN) * d->pages_per_eblk + - d->pages_per_eblk - d->curr_write_pos; -} - -static unsigned int mtdswap_enough_free_pages(struct mtdswap_dev *d) -{ - return mtdswap_free_page_cnt(d) > d->pages_per_eblk; -} - -static int mtdswap_write_block(struct mtdswap_dev *d, char *buf, - unsigned int page, unsigned int *bp, int gc_context) -{ - struct mtd_info *mtd = d->mtd; - struct swap_eb *eb; - size_t retlen; - loff_t writepos; - int ret; - -retry: - if (!gc_context) - while (!mtdswap_enough_free_pages(d)) - if (mtdswap_gc(d, 0) > 0) - return -ENOSPC; - - ret = mtdswap_map_free_block(d, page, bp); - eb = d->eb_data + (*bp / d->pages_per_eblk); - - if (ret == -EIO || ret == -EBADMSG) { - d->curr_write = NULL; - eb->active_count--; - d->revmap[*bp] = PAGE_UNDEF; - goto retry; - } - - if (ret < 0) - return ret; - - writepos = (loff_t)*bp << PAGE_SHIFT; - ret = mtd->write(mtd, writepos, PAGE_SIZE, &retlen, buf); - if (ret == -EIO || ret == -EBADMSG) { - d->curr_write_pos--; - eb->active_count--; - d->revmap[*bp] = PAGE_UNDEF; - mtdswap_handle_write_error(d, eb); - goto retry; - } - - if (ret < 0) { - dev_err(d->dev, "Write to MTD device failed: %d (%zd written)", - ret, retlen); - goto err; - } - - if (retlen != PAGE_SIZE) { - dev_err(d->dev, "Short write to MTD device: %zd written", - retlen); - ret = -EIO; - goto err; - } - - return ret; - -err: - d->curr_write_pos--; - eb->active_count--; - d->revmap[*bp] = PAGE_UNDEF; - - return ret; -} - -static int mtdswap_move_block(struct mtdswap_dev *d, unsigned int oldblock, - unsigned int *newblock) -{ - struct mtd_info *mtd = d->mtd; - struct swap_eb *eb, *oldeb; - int ret; - size_t retlen; - unsigned int page, retries; - loff_t readpos; - - page = d->revmap[oldblock]; - readpos = (loff_t) oldblock << PAGE_SHIFT; - retries = 0; - -retry: - ret = mtd->read(mtd, readpos, PAGE_SIZE, &retlen, d->page_buf); - - if (ret < 0 && ret != -EUCLEAN) { - oldeb = d->eb_data + oldblock / d->pages_per_eblk; - oldeb->flags |= EBLOCK_READERR; - - dev_err(d->dev, "Read Error: %d (block %u)\n", ret, - oldblock); - retries++; - if (retries < MTDSWAP_IO_RETRIES) - goto retry; - - goto read_error; - } - - if (retlen != PAGE_SIZE) { - dev_err(d->dev, "Short read: %zd (block %u)\n", retlen, - oldblock); - ret = -EIO; - goto read_error; - } - - ret = mtdswap_write_block(d, d->page_buf, page, newblock, 1); - if (ret < 0) { - d->page_data[page] = BLOCK_ERROR; - dev_err(d->dev, "Write error: %d\n", ret); - return ret; - } - - eb = d->eb_data + *newblock / d->pages_per_eblk; - d->page_data[page] = *newblock; - d->revmap[oldblock] = PAGE_UNDEF; - eb = d->eb_data + oldblock / d->pages_per_eblk; - eb->active_count--; - - return 0; - -read_error: - d->page_data[page] = BLOCK_ERROR; - d->revmap[oldblock] = PAGE_UNDEF; - return ret; -} - -static int mtdswap_gc_eblock(struct mtdswap_dev *d, struct swap_eb *eb) -{ - unsigned int i, block, eblk_base, newblock; - int ret, errcode; - - errcode = 0; - eblk_base = (eb - d->eb_data) * d->pages_per_eblk; - - for (i = 0; i < d->pages_per_eblk; i++) { - if (d->spare_eblks < MIN_SPARE_EBLOCKS) - return -ENOSPC; - - block = eblk_base + i; - if (d->revmap[block] == PAGE_UNDEF) - continue; - - ret = mtdswap_move_block(d, block, &newblock); - if (ret < 0 && !errcode) - errcode = ret; - } - - return errcode; -} - -static int __mtdswap_choose_gc_tree(struct mtdswap_dev *d) -{ - int idx, stopat; - - if (TREE_COUNT(d, CLEAN) < LOW_FRAG_GC_TRESHOLD) - stopat = MTDSWAP_LOWFRAG; - else - stopat = MTDSWAP_HIFRAG; - - for (idx = MTDSWAP_BITFLIP; idx >= stopat; idx--) - if (d->trees[idx].root.rb_node != NULL) - return idx; - - return -1; -} - -static int mtdswap_wlfreq(unsigned int maxdiff) -{ - unsigned int h, x, y, dist, base; - - /* - * Calculate linear ramp down from f1 to f2 when maxdiff goes from - * MAX_ERASE_DIFF to MAX_ERASE_DIFF + COLLECT_NONDIRTY_BASE. Similar - * to triangle with height f1 - f1 and width COLLECT_NONDIRTY_BASE. - */ - - dist = maxdiff - MAX_ERASE_DIFF; - if (dist > COLLECT_NONDIRTY_BASE) - dist = COLLECT_NONDIRTY_BASE; - - /* - * Modelling the slop as right angular triangle with base - * COLLECT_NONDIRTY_BASE and height freq1 - freq2. The ratio y/x is - * equal to the ratio h/base. - */ - h = COLLECT_NONDIRTY_FREQ1 - COLLECT_NONDIRTY_FREQ2; - base = COLLECT_NONDIRTY_BASE; - - x = dist - base; - y = (x * h + base / 2) / base; - - return COLLECT_NONDIRTY_FREQ2 + y; -} - -static int mtdswap_choose_wl_tree(struct mtdswap_dev *d) -{ - static unsigned int pick_cnt; - unsigned int i, idx = -1, wear, max; - struct rb_root *root; - - max = 0; - for (i = 0; i <= MTDSWAP_DIRTY; i++) { - root = &d->trees[i].root; - if (root->rb_node == NULL) - continue; - - wear = d->max_erase_count - MTDSWAP_ECNT_MIN(root); - if (wear > max) { - max = wear; - idx = i; - } - } - - if (max > MAX_ERASE_DIFF && pick_cnt >= mtdswap_wlfreq(max) - 1) { - pick_cnt = 0; - return idx; - } - - pick_cnt++; - return -1; -} - -static int mtdswap_choose_gc_tree(struct mtdswap_dev *d, - unsigned int background) -{ - int idx; - - if (TREE_NONEMPTY(d, FAILING) && - (background || (TREE_EMPTY(d, CLEAN) && TREE_EMPTY(d, DIRTY)))) - return MTDSWAP_FAILING; - - idx = mtdswap_choose_wl_tree(d); - if (idx >= MTDSWAP_CLEAN) - return idx; - - return __mtdswap_choose_gc_tree(d); -} - -static struct swap_eb *mtdswap_pick_gc_eblk(struct mtdswap_dev *d, - unsigned int background) -{ - struct rb_root *rp = NULL; - struct swap_eb *eb = NULL; - int idx; - - if (background && TREE_COUNT(d, CLEAN) > CLEAN_BLOCK_THRESHOLD && - TREE_EMPTY(d, DIRTY) && TREE_EMPTY(d, FAILING)) - return NULL; - - idx = mtdswap_choose_gc_tree(d, background); - if (idx < 0) - return NULL; - - rp = &d->trees[idx].root; - eb = rb_entry(rb_first(rp), struct swap_eb, rb); - - rb_erase(&eb->rb, rp); - eb->root = NULL; - d->trees[idx].count--; - return eb; -} - -static unsigned int mtdswap_test_patt(unsigned int i) -{ - return i % 2 ? 0x55555555 : 0xAAAAAAAA; -} - -static unsigned int mtdswap_eblk_passes(struct mtdswap_dev *d, - struct swap_eb *eb) -{ - struct mtd_info *mtd = d->mtd; - unsigned int test, i, j, patt, mtd_pages; - loff_t base, pos; - unsigned int *p1 = (unsigned int *)d->page_buf; - unsigned char *p2 = (unsigned char *)d->oob_buf; - struct mtd_oob_ops ops; - int ret; - - ops.mode = MTD_OOB_AUTO; - ops.len = mtd->writesize; - ops.ooblen = mtd->ecclayout->oobavail; - ops.ooboffs = 0; - ops.datbuf = d->page_buf; - ops.oobbuf = d->oob_buf; - base = mtdswap_eb_offset(d, eb); - mtd_pages = d->pages_per_eblk * PAGE_SIZE / mtd->writesize; - - for (test = 0; test < 2; test++) { - pos = base; - for (i = 0; i < mtd_pages; i++) { - patt = mtdswap_test_patt(test + i); - memset(d->page_buf, patt, mtd->writesize); - memset(d->oob_buf, patt, mtd->ecclayout->oobavail); - ret = mtd->write_oob(mtd, pos, &ops); - if (ret) - goto error; - - pos += mtd->writesize; - } - - pos = base; - for (i = 0; i < mtd_pages; i++) { - ret = mtd->read_oob(mtd, pos, &ops); - if (ret) - goto error; - - patt = mtdswap_test_patt(test + i); - for (j = 0; j < mtd->writesize/sizeof(int); j++) - if (p1[j] != patt) - goto error; - - for (j = 0; j < mtd->ecclayout->oobavail; j++) - if (p2[j] != (unsigned char)patt) - goto error; - - pos += mtd->writesize; - } - - ret = mtdswap_erase_block(d, eb); - if (ret) - goto error; - } - - eb->flags &= ~EBLOCK_READERR; - return 1; - -error: - mtdswap_handle_badblock(d, eb); - return 0; -} - -static int mtdswap_gc(struct mtdswap_dev *d, unsigned int background) -{ - struct swap_eb *eb; - int ret; - - if (d->spare_eblks < MIN_SPARE_EBLOCKS) - return 1; - - eb = mtdswap_pick_gc_eblk(d, background); - if (!eb) - return 1; - - ret = mtdswap_gc_eblock(d, eb); - if (ret == -ENOSPC) - return 1; - - if (eb->flags & EBLOCK_FAILED) { - mtdswap_handle_badblock(d, eb); - return 0; - } - - eb->flags &= ~EBLOCK_BITFLIP; - ret = mtdswap_erase_block(d, eb); - if ((eb->flags & EBLOCK_READERR) && - (ret || !mtdswap_eblk_passes(d, eb))) - return 0; - - if (ret == 0) - ret = mtdswap_write_marker(d, eb, MTDSWAP_TYPE_CLEAN); - - if (ret == 0) - mtdswap_rb_add(d, eb, MTDSWAP_CLEAN); - else if (ret != -EIO && ret != -EBADMSG) - mtdswap_rb_add(d, eb, MTDSWAP_DIRTY); - - return 0; -} - -static void mtdswap_background(struct mtd_blktrans_dev *dev) -{ - struct mtdswap_dev *d = MTDSWAP_MBD_TO_MTDSWAP(dev); - int ret; - - while (1) { - ret = mtdswap_gc(d, 1); - if (ret || mtd_blktrans_cease_background(dev)) - return; - } -} - -static void mtdswap_cleanup(struct mtdswap_dev *d) -{ - vfree(d->eb_data); - vfree(d->revmap); - vfree(d->page_data); - kfree(d->oob_buf); - kfree(d->page_buf); -} - -static int mtdswap_flush(struct mtd_blktrans_dev *dev) -{ - struct mtdswap_dev *d = MTDSWAP_MBD_TO_MTDSWAP(dev); - - if (d->mtd->sync) - d->mtd->sync(d->mtd); - return 0; -} - -static unsigned int mtdswap_badblocks(struct mtd_info *mtd, uint64_t size) -{ - loff_t offset; - unsigned int badcnt; - - badcnt = 0; - - if (mtd->block_isbad) - for (offset = 0; offset < size; offset += mtd->erasesize) - if (mtd->block_isbad(mtd, offset)) - badcnt++; - - return badcnt; -} - -static int mtdswap_writesect(struct mtd_blktrans_dev *dev, - unsigned long page, char *buf) -{ - struct mtdswap_dev *d = MTDSWAP_MBD_TO_MTDSWAP(dev); - unsigned int newblock, mapped; - struct swap_eb *eb; - int ret; - - d->sect_write_count++; - - if (d->spare_eblks < MIN_SPARE_EBLOCKS) - return -ENOSPC; - - if (header) { - /* Ignore writes to the header page */ - if (unlikely(page == 0)) - return 0; - - page--; - } - - mapped = d->page_data[page]; - if (mapped <= BLOCK_MAX) { - eb = d->eb_data + (mapped / d->pages_per_eblk); - eb->active_count--; - mtdswap_store_eb(d, eb); - d->page_data[page] = BLOCK_UNDEF; - d->revmap[mapped] = PAGE_UNDEF; - } - - ret = mtdswap_write_block(d, buf, page, &newblock, 0); - d->mtd_write_count++; - - if (ret < 0) - return ret; - - eb = d->eb_data + (newblock / d->pages_per_eblk); - d->page_data[page] = newblock; - - return 0; -} - -/* Provide a dummy swap header for the kernel */ -static int mtdswap_auto_header(struct mtdswap_dev *d, char *buf) -{ - union swap_header *hd = (union swap_header *)(buf); - - memset(buf, 0, PAGE_SIZE - 10); - - hd->info.version = 1; - hd->info.last_page = d->mbd_dev->size - 1; - hd->info.nr_badpages = 0; - - memcpy(buf + PAGE_SIZE - 10, "SWAPSPACE2", 10); - - return 0; -} - -static int mtdswap_readsect(struct mtd_blktrans_dev *dev, - unsigned long page, char *buf) -{ - struct mtdswap_dev *d = MTDSWAP_MBD_TO_MTDSWAP(dev); - struct mtd_info *mtd = d->mtd; - unsigned int realblock, retries; - loff_t readpos; - struct swap_eb *eb; - size_t retlen; - int ret; - - d->sect_read_count++; - - if (header) { - if (unlikely(page == 0)) - return mtdswap_auto_header(d, buf); - - page--; - } - - realblock = d->page_data[page]; - if (realblock > BLOCK_MAX) { - memset(buf, 0x0, PAGE_SIZE); - if (realblock == BLOCK_UNDEF) - return 0; - else - return -EIO; - } - - eb = d->eb_data + (realblock / d->pages_per_eblk); - BUG_ON(d->revmap[realblock] == PAGE_UNDEF); - - readpos = (loff_t)realblock << PAGE_SHIFT; - retries = 0; - -retry: - ret = mtd->read(mtd, readpos, PAGE_SIZE, &retlen, buf); - - d->mtd_read_count++; - if (ret == -EUCLEAN) { - eb->flags |= EBLOCK_BITFLIP; - mtdswap_rb_add(d, eb, MTDSWAP_BITFLIP); - ret = 0; - } - - if (ret < 0) { - dev_err(d->dev, "Read error %d\n", ret); - eb->flags |= EBLOCK_READERR; - mtdswap_rb_add(d, eb, MTDSWAP_FAILING); - retries++; - if (retries < MTDSWAP_IO_RETRIES) - goto retry; - - return ret; - } - - if (retlen != PAGE_SIZE) { - dev_err(d->dev, "Short read %zd\n", retlen); - return -EIO; - } - - return 0; -} - -static int mtdswap_discard(struct mtd_blktrans_dev *dev, unsigned long first, - unsigned nr_pages) -{ - struct mtdswap_dev *d = MTDSWAP_MBD_TO_MTDSWAP(dev); - unsigned long page; - struct swap_eb *eb; - unsigned int mapped; - - d->discard_count++; - - for (page = first; page < first + nr_pages; page++) { - mapped = d->page_data[page]; - if (mapped <= BLOCK_MAX) { - eb = d->eb_data + (mapped / d->pages_per_eblk); - eb->active_count--; - mtdswap_store_eb(d, eb); - d->page_data[page] = BLOCK_UNDEF; - d->revmap[mapped] = PAGE_UNDEF; - d->discard_page_count++; - } else if (mapped == BLOCK_ERROR) { - d->page_data[page] = BLOCK_UNDEF; - d->discard_page_count++; - } - } - - return 0; -} - -static int mtdswap_show(struct seq_file *s, void *data) -{ - struct mtdswap_dev *d = (struct mtdswap_dev *) s->private; - unsigned long sum; - unsigned int count[MTDSWAP_TREE_CNT]; - unsigned int min[MTDSWAP_TREE_CNT]; - unsigned int max[MTDSWAP_TREE_CNT]; - unsigned int i, cw = 0, cwp = 0, cwecount = 0, bb_cnt, mapped, pages; - uint64_t use_size; - char *name[] = {"clean", "used", "low", "high", "dirty", "bitflip", - "failing"}; - - mutex_lock(&d->mbd_dev->lock); - - for (i = 0; i < MTDSWAP_TREE_CNT; i++) { - struct rb_root *root = &d->trees[i].root; - - if (root->rb_node) { - count[i] = d->trees[i].count; - min[i] = rb_entry(rb_first(root), struct swap_eb, - rb)->erase_count; - max[i] = rb_entry(rb_last(root), struct swap_eb, - rb)->erase_count; - } else - count[i] = 0; - } - - if (d->curr_write) { - cw = 1; - cwp = d->curr_write_pos; - cwecount = d->curr_write->erase_count; - } - - sum = 0; - for (i = 0; i < d->eblks; i++) - sum += d->eb_data[i].erase_count; - - use_size = (uint64_t)d->eblks * d->mtd->erasesize; - bb_cnt = mtdswap_badblocks(d->mtd, use_size); - - mapped = 0; - pages = d->mbd_dev->size; - for (i = 0; i < pages; i++) - if (d->page_data[i] != BLOCK_UNDEF) - mapped++; - - mutex_unlock(&d->mbd_dev->lock); - - for (i = 0; i < MTDSWAP_TREE_CNT; i++) { - if (!count[i]) - continue; - - if (min[i] != max[i]) - seq_printf(s, "%s:\t%5d erase blocks, erased min %d, " - "max %d times\n", - name[i], count[i], min[i], max[i]); - else - seq_printf(s, "%s:\t%5d erase blocks, all erased %d " - "times\n", name[i], count[i], min[i]); - } - - if (bb_cnt) - seq_printf(s, "bad:\t%5u erase blocks\n", bb_cnt); - - if (cw) - seq_printf(s, "current erase block: %u pages used, %u free, " - "erased %u times\n", - cwp, d->pages_per_eblk - cwp, cwecount); - - seq_printf(s, "total erasures: %lu\n", sum); - - seq_printf(s, "\n"); - - seq_printf(s, "mtdswap_readsect count: %llu\n", d->sect_read_count); - seq_printf(s, "mtdswap_writesect count: %llu\n", d->sect_write_count); - seq_printf(s, "mtdswap_discard count: %llu\n", d->discard_count); - seq_printf(s, "mtd read count: %llu\n", d->mtd_read_count); - seq_printf(s, "mtd write count: %llu\n", d->mtd_write_count); - seq_printf(s, "discarded pages count: %llu\n", d->discard_page_count); - - seq_printf(s, "\n"); - seq_printf(s, "total pages: %u\n", pages); - seq_printf(s, "pages mapped: %u\n", mapped); - - return 0; -} - -static int mtdswap_open(struct inode *inode, struct file *file) -{ - return single_open(file, mtdswap_show, inode->i_private); -} - -static const struct file_operations mtdswap_fops = { - .open = mtdswap_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; - -static int mtdswap_add_debugfs(struct mtdswap_dev *d) -{ - struct gendisk *gd = d->mbd_dev->disk; - struct device *dev = disk_to_dev(gd); - - struct dentry *root; - struct dentry *dent; - - root = debugfs_create_dir(gd->disk_name, NULL); - if (IS_ERR(root)) - return 0; - - if (!root) { - dev_err(dev, "failed to initialize debugfs\n"); - return -1; - } - - d->debugfs_root = root; - - dent = debugfs_create_file("stats", S_IRUSR, root, d, - &mtdswap_fops); - if (!dent) { - dev_err(d->dev, "debugfs_create_file failed\n"); - debugfs_remove_recursive(root); - d->debugfs_root = NULL; - return -1; - } - - return 0; -} - -static int mtdswap_init(struct mtdswap_dev *d, unsigned int eblocks, - unsigned int spare_cnt) -{ - struct mtd_info *mtd = d->mbd_dev->mtd; - unsigned int i, eblk_bytes, pages, blocks; - int ret = -ENOMEM; - - d->mtd = mtd; - d->eblks = eblocks; - d->spare_eblks = spare_cnt; - d->pages_per_eblk = mtd->erasesize >> PAGE_SHIFT; - - pages = d->mbd_dev->size; - blocks = eblocks * d->pages_per_eblk; - - for (i = 0; i < MTDSWAP_TREE_CNT; i++) - d->trees[i].root = RB_ROOT; - - d->page_data = vmalloc(sizeof(int)*pages); - if (!d->page_data) - goto page_data_fail; - - d->revmap = vmalloc(sizeof(int)*blocks); - if (!d->revmap) - goto revmap_fail; - - eblk_bytes = sizeof(struct swap_eb)*d->eblks; - d->eb_data = vmalloc(eblk_bytes); - if (!d->eb_data) - goto eb_data_fail; - - memset(d->eb_data, 0, eblk_bytes); - for (i = 0; i < pages; i++) - d->page_data[i] = BLOCK_UNDEF; - - for (i = 0; i < blocks; i++) - d->revmap[i] = PAGE_UNDEF; - - d->page_buf = kmalloc(PAGE_SIZE, GFP_KERNEL); - if (!d->page_buf) - goto page_buf_fail; - - d->oob_buf = kmalloc(2 * mtd->ecclayout->oobavail, GFP_KERNEL); - if (!d->oob_buf) - goto oob_buf_fail; - - mtdswap_scan_eblks(d); - - return 0; - -oob_buf_fail: - kfree(d->page_buf); -page_buf_fail: - vfree(d->eb_data); -eb_data_fail: - vfree(d->revmap); -revmap_fail: - vfree(d->page_data); -page_data_fail: - printk(KERN_ERR "%s: init failed (%d)\n", MTDSWAP_PREFIX, ret); - return ret; -} - -static void mtdswap_add_mtd(struct mtd_blktrans_ops *tr, struct mtd_info *mtd) -{ - struct mtdswap_dev *d; - struct mtd_blktrans_dev *mbd_dev; - char *parts; - char *this_opt; - unsigned long part; - unsigned int eblocks, eavailable, bad_blocks, spare_cnt; - uint64_t swap_size, use_size, size_limit; - struct nand_ecclayout *oinfo; - int ret; - - parts = &partitions[0]; - if (!*parts) - return; - - while ((this_opt = strsep(&parts, ",")) != NULL) { - if (strict_strtoul(this_opt, 0, &part) < 0) - return; - - if (mtd->index == part) - break; - } - - if (mtd->index != part) - return; - - if (mtd->erasesize < PAGE_SIZE || mtd->erasesize % PAGE_SIZE) { - printk(KERN_ERR "%s: Erase size %u not multiple of PAGE_SIZE " - "%lu\n", MTDSWAP_PREFIX, mtd->erasesize, PAGE_SIZE); - return; - } - - if (PAGE_SIZE % mtd->writesize || mtd->writesize > PAGE_SIZE) { - printk(KERN_ERR "%s: PAGE_SIZE %lu not multiple of write size" - " %u\n", MTDSWAP_PREFIX, PAGE_SIZE, mtd->writesize); - return; - } - - oinfo = mtd->ecclayout; - if (!mtd->oobsize || !oinfo || oinfo->oobavail < MTDSWAP_OOBSIZE) { - printk(KERN_ERR "%s: Not enough free bytes in OOB, " - "%d available, %lu needed.\n", - MTDSWAP_PREFIX, oinfo->oobavail, MTDSWAP_OOBSIZE); - return; - } - - if (spare_eblocks > 100) - spare_eblocks = 100; - - use_size = mtd->size; - size_limit = (uint64_t) BLOCK_MAX * PAGE_SIZE; - - if (mtd->size > size_limit) { - printk(KERN_WARNING "%s: Device too large. Limiting size to " - "%llu bytes\n", MTDSWAP_PREFIX, size_limit); - use_size = size_limit; - } - - eblocks = mtd_div_by_eb(use_size, mtd); - use_size = eblocks * mtd->erasesize; - bad_blocks = mtdswap_badblocks(mtd, use_size); - eavailable = eblocks - bad_blocks; - - if (eavailable < MIN_ERASE_BLOCKS) { - printk(KERN_ERR "%s: Not enough erase blocks. %u available, " - "%d needed\n", MTDSWAP_PREFIX, eavailable, - MIN_ERASE_BLOCKS); - return; - } - - spare_cnt = div_u64((uint64_t)eavailable * spare_eblocks, 100); - - if (spare_cnt < MIN_SPARE_EBLOCKS) - spare_cnt = MIN_SPARE_EBLOCKS; - - if (spare_cnt > eavailable - 1) - spare_cnt = eavailable - 1; - - swap_size = (uint64_t)(eavailable - spare_cnt) * mtd->erasesize + - (header ? PAGE_SIZE : 0); - - printk(KERN_INFO "%s: Enabling MTD swap on device %lu, size %llu KB, " - "%u spare, %u bad blocks\n", - MTDSWAP_PREFIX, part, swap_size / 1024, spare_cnt, bad_blocks); - - d = kzalloc(sizeof(struct mtdswap_dev), GFP_KERNEL); - if (!d) - return; - - mbd_dev = kzalloc(sizeof(struct mtd_blktrans_dev), GFP_KERNEL); - if (!mbd_dev) { - kfree(d); - return; - } - - d->mbd_dev = mbd_dev; - mbd_dev->priv = d; - - mbd_dev->mtd = mtd; - mbd_dev->devnum = mtd->index; - mbd_dev->size = swap_size >> PAGE_SHIFT; - mbd_dev->tr = tr; - - if (!(mtd->flags & MTD_WRITEABLE)) - mbd_dev->readonly = 1; - - if (mtdswap_init(d, eblocks, spare_cnt) < 0) - goto init_failed; - - if (add_mtd_blktrans_dev(mbd_dev) < 0) - goto cleanup; - - d->dev = disk_to_dev(mbd_dev->disk); - - ret = mtdswap_add_debugfs(d); - if (ret < 0) - goto debugfs_failed; - - return; - -debugfs_failed: - del_mtd_blktrans_dev(mbd_dev); - -cleanup: - mtdswap_cleanup(d); - -init_failed: - kfree(mbd_dev); - kfree(d); -} - -static void mtdswap_remove_dev(struct mtd_blktrans_dev *dev) -{ - struct mtdswap_dev *d = MTDSWAP_MBD_TO_MTDSWAP(dev); - - debugfs_remove_recursive(d->debugfs_root); - del_mtd_blktrans_dev(dev); - mtdswap_cleanup(d); - kfree(d); -} - -static struct mtd_blktrans_ops mtdswap_ops = { - .name = "mtdswap", - .major = 0, - .part_bits = 0, - .blksize = PAGE_SIZE, - .flush = mtdswap_flush, - .readsect = mtdswap_readsect, - .writesect = mtdswap_writesect, - .discard = mtdswap_discard, - .background = mtdswap_background, - .add_mtd = mtdswap_add_mtd, - .remove_dev = mtdswap_remove_dev, - .owner = THIS_MODULE, -}; - -static int __init mtdswap_modinit(void) -{ - return register_mtd_blktrans(&mtdswap_ops); -} - -static void __exit mtdswap_modexit(void) -{ - deregister_mtd_blktrans(&mtdswap_ops); -} - -module_init(mtdswap_modinit); -module_exit(mtdswap_modexit); - - -MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Jarkko Lavinen "); -MODULE_DESCRIPTION("Block device access to an MTD suitable for using as " - "swap space"); diff --git a/trunk/drivers/mtd/nand/Kconfig b/trunk/drivers/mtd/nand/Kconfig index a92054e945e1..4f6c06f16328 100644 --- a/trunk/drivers/mtd/nand/Kconfig +++ b/trunk/drivers/mtd/nand/Kconfig @@ -31,21 +31,6 @@ config MTD_NAND_VERIFY_WRITE device thinks the write was successful, a bit could have been flipped accidentally due to device wear or something else. -config MTD_NAND_BCH - tristate - select BCH - depends on MTD_NAND_ECC_BCH - default MTD_NAND - -config MTD_NAND_ECC_BCH - bool "Support software BCH ECC" - default n - help - This enables support for software BCH error correction. Binary BCH - codes are more powerful and cpu intensive than traditional Hamming - ECC codes. They are used with NAND devices requiring more than 1 bit - of error correction. - config MTD_SM_COMMON tristate default n diff --git a/trunk/drivers/mtd/nand/Makefile b/trunk/drivers/mtd/nand/Makefile index 5745d831168e..8ad6faec72cb 100644 --- a/trunk/drivers/mtd/nand/Makefile +++ b/trunk/drivers/mtd/nand/Makefile @@ -4,7 +4,6 @@ obj-$(CONFIG_MTD_NAND) += nand.o obj-$(CONFIG_MTD_NAND_ECC) += nand_ecc.o -obj-$(CONFIG_MTD_NAND_BCH) += nand_bch.o obj-$(CONFIG_MTD_NAND_IDS) += nand_ids.o obj-$(CONFIG_MTD_SM_COMMON) += sm_common.o diff --git a/trunk/drivers/mtd/nand/atmel_nand.c b/trunk/drivers/mtd/nand/atmel_nand.c index 6fae04b3fc6d..ccce0f03b5dc 100644 --- a/trunk/drivers/mtd/nand/atmel_nand.c +++ b/trunk/drivers/mtd/nand/atmel_nand.c @@ -48,9 +48,6 @@ #define no_ecc 0 #endif -static int use_dma = 1; -module_param(use_dma, int, 0); - static int on_flash_bbt = 0; module_param(on_flash_bbt, int, 0); @@ -92,20 +89,11 @@ struct atmel_nand_host { struct nand_chip nand_chip; struct mtd_info mtd; void __iomem *io_base; - dma_addr_t io_phys; struct atmel_nand_data *board; struct device *dev; void __iomem *ecc; - - struct completion comp; - struct dma_chan *dma_chan; }; -static int cpu_has_dma(void) -{ - return cpu_is_at91sam9rl() || cpu_is_at91sam9g45(); -} - /* * Enable NAND. */ @@ -162,7 +150,7 @@ static int atmel_nand_device_ready(struct mtd_info *mtd) /* * Minimal-overhead PIO for data access. */ -static void atmel_read_buf8(struct mtd_info *mtd, u8 *buf, int len) +static void atmel_read_buf(struct mtd_info *mtd, u8 *buf, int len) { struct nand_chip *nand_chip = mtd->priv; @@ -176,7 +164,7 @@ static void atmel_read_buf16(struct mtd_info *mtd, u8 *buf, int len) __raw_readsw(nand_chip->IO_ADDR_R, buf, len / 2); } -static void atmel_write_buf8(struct mtd_info *mtd, const u8 *buf, int len) +static void atmel_write_buf(struct mtd_info *mtd, const u8 *buf, int len) { struct nand_chip *nand_chip = mtd->priv; @@ -190,121 +178,6 @@ static void atmel_write_buf16(struct mtd_info *mtd, const u8 *buf, int len) __raw_writesw(nand_chip->IO_ADDR_W, buf, len / 2); } -static void dma_complete_func(void *completion) -{ - complete(completion); -} - -static int atmel_nand_dma_op(struct mtd_info *mtd, void *buf, int len, - int is_read) -{ - struct dma_device *dma_dev; - enum dma_ctrl_flags flags; - dma_addr_t dma_src_addr, dma_dst_addr, phys_addr; - struct dma_async_tx_descriptor *tx = NULL; - dma_cookie_t cookie; - struct nand_chip *chip = mtd->priv; - struct atmel_nand_host *host = chip->priv; - void *p = buf; - int err = -EIO; - enum dma_data_direction dir = is_read ? DMA_FROM_DEVICE : DMA_TO_DEVICE; - - if (buf >= high_memory) { - struct page *pg; - - if (((size_t)buf & PAGE_MASK) != - ((size_t)(buf + len - 1) & PAGE_MASK)) { - dev_warn(host->dev, "Buffer not fit in one page\n"); - goto err_buf; - } - - pg = vmalloc_to_page(buf); - if (pg == 0) { - dev_err(host->dev, "Failed to vmalloc_to_page\n"); - goto err_buf; - } - p = page_address(pg) + ((size_t)buf & ~PAGE_MASK); - } - - dma_dev = host->dma_chan->device; - - flags = DMA_CTRL_ACK | DMA_PREP_INTERRUPT | DMA_COMPL_SKIP_SRC_UNMAP | - DMA_COMPL_SKIP_DEST_UNMAP; - - phys_addr = dma_map_single(dma_dev->dev, p, len, dir); - if (dma_mapping_error(dma_dev->dev, phys_addr)) { - dev_err(host->dev, "Failed to dma_map_single\n"); - goto err_buf; - } - - if (is_read) { - dma_src_addr = host->io_phys; - dma_dst_addr = phys_addr; - } else { - dma_src_addr = phys_addr; - dma_dst_addr = host->io_phys; - } - - tx = dma_dev->device_prep_dma_memcpy(host->dma_chan, dma_dst_addr, - dma_src_addr, len, flags); - if (!tx) { - dev_err(host->dev, "Failed to prepare DMA memcpy\n"); - goto err_dma; - } - - init_completion(&host->comp); - tx->callback = dma_complete_func; - tx->callback_param = &host->comp; - - cookie = tx->tx_submit(tx); - if (dma_submit_error(cookie)) { - dev_err(host->dev, "Failed to do DMA tx_submit\n"); - goto err_dma; - } - - dma_async_issue_pending(host->dma_chan); - wait_for_completion(&host->comp); - - err = 0; - -err_dma: - dma_unmap_single(dma_dev->dev, phys_addr, len, dir); -err_buf: - if (err != 0) - dev_warn(host->dev, "Fall back to CPU I/O\n"); - return err; -} - -static void atmel_read_buf(struct mtd_info *mtd, u8 *buf, int len) -{ - struct nand_chip *chip = mtd->priv; - struct atmel_nand_host *host = chip->priv; - - if (use_dma && len >= mtd->oobsize) - if (atmel_nand_dma_op(mtd, buf, len, 1) == 0) - return; - - if (host->board->bus_width_16) - atmel_read_buf16(mtd, buf, len); - else - atmel_read_buf8(mtd, buf, len); -} - -static void atmel_write_buf(struct mtd_info *mtd, const u8 *buf, int len) -{ - struct nand_chip *chip = mtd->priv; - struct atmel_nand_host *host = chip->priv; - - if (use_dma && len >= mtd->oobsize) - if (atmel_nand_dma_op(mtd, (void *)buf, len, 0) == 0) - return; - - if (host->board->bus_width_16) - atmel_write_buf16(mtd, buf, len); - else - atmel_write_buf8(mtd, buf, len); -} - /* * Calculate HW ECC * @@ -525,8 +398,6 @@ static int __init atmel_nand_probe(struct platform_device *pdev) return -ENOMEM; } - host->io_phys = (dma_addr_t)mem->start; - host->io_base = ioremap(mem->start, mem->end - mem->start + 1); if (host->io_base == NULL) { printk(KERN_ERR "atmel_nand: ioremap failed\n"); @@ -577,11 +448,14 @@ static int __init atmel_nand_probe(struct platform_device *pdev) nand_chip->chip_delay = 20; /* 20us command delay time */ - if (host->board->bus_width_16) /* 16-bit bus width */ + if (host->board->bus_width_16) { /* 16-bit bus width */ nand_chip->options |= NAND_BUSWIDTH_16; - - nand_chip->read_buf = atmel_read_buf; - nand_chip->write_buf = atmel_write_buf; + nand_chip->read_buf = atmel_read_buf16; + nand_chip->write_buf = atmel_write_buf16; + } else { + nand_chip->read_buf = atmel_read_buf; + nand_chip->write_buf = atmel_write_buf; + } platform_set_drvdata(pdev, host); atmel_nand_enable(host); @@ -599,22 +473,6 @@ static int __init atmel_nand_probe(struct platform_device *pdev) nand_chip->options |= NAND_USE_FLASH_BBT; } - if (cpu_has_dma() && use_dma) { - dma_cap_mask_t mask; - - dma_cap_zero(mask); - dma_cap_set(DMA_MEMCPY, mask); - host->dma_chan = dma_request_channel(mask, 0, NULL); - if (!host->dma_chan) { - dev_err(host->dev, "Failed to request DMA channel\n"); - use_dma = 0; - } - } - if (use_dma) - dev_info(host->dev, "Using DMA for NAND access.\n"); - else - dev_info(host->dev, "No DMA support for NAND access.\n"); - /* first scan to find the device and get the page size */ if (nand_scan_ident(mtd, 1, NULL)) { res = -ENXIO; @@ -697,8 +555,6 @@ static int __init atmel_nand_probe(struct platform_device *pdev) err_no_card: atmel_nand_disable(host); platform_set_drvdata(pdev, NULL); - if (host->dma_chan) - dma_release_channel(host->dma_chan); if (host->ecc) iounmap(host->ecc); err_ecc_ioremap: @@ -722,10 +578,6 @@ static int __exit atmel_nand_remove(struct platform_device *pdev) if (host->ecc) iounmap(host->ecc); - - if (host->dma_chan) - dma_release_channel(host->dma_chan); - iounmap(host->io_base); kfree(host); diff --git a/trunk/drivers/mtd/nand/davinci_nand.c b/trunk/drivers/mtd/nand/davinci_nand.c index aff3468867ac..a90fde3ede28 100644 --- a/trunk/drivers/mtd/nand/davinci_nand.c +++ b/trunk/drivers/mtd/nand/davinci_nand.c @@ -37,6 +37,9 @@ #include #include +#include + + /* * This is a device driver for the NAND flash controller found on the * various DaVinci family chips. It handles up to four SoC chipselects, diff --git a/trunk/drivers/mtd/nand/mpc5121_nfc.c b/trunk/drivers/mtd/nand/mpc5121_nfc.c index 0b81b5b499d1..c2f95437e5e9 100644 --- a/trunk/drivers/mtd/nand/mpc5121_nfc.c +++ b/trunk/drivers/mtd/nand/mpc5121_nfc.c @@ -29,7 +29,6 @@ #include #include #include -#include #include #include #include @@ -758,9 +757,9 @@ static int __devinit mpc5121_nfc_probe(struct platform_device *op) /* Enable NFC clock */ prv->clk = clk_get(dev, "nfc_clk"); - if (IS_ERR(prv->clk)) { + if (!prv->clk) { dev_err(dev, "Unable to acquire NFC clock!\n"); - retval = PTR_ERR(prv->clk); + retval = -ENODEV; goto error; } diff --git a/trunk/drivers/mtd/nand/mxc_nand.c b/trunk/drivers/mtd/nand/mxc_nand.c index 42a95fb41504..5ae1d9ee2cf1 100644 --- a/trunk/drivers/mtd/nand/mxc_nand.c +++ b/trunk/drivers/mtd/nand/mxc_nand.c @@ -211,31 +211,6 @@ static struct nand_ecclayout nandv2_hw_eccoob_largepage = { } }; -/* OOB description for 4096 byte pages with 128 byte OOB */ -static struct nand_ecclayout nandv2_hw_eccoob_4k = { - .eccbytes = 8 * 9, - .eccpos = { - 7, 8, 9, 10, 11, 12, 13, 14, 15, - 23, 24, 25, 26, 27, 28, 29, 30, 31, - 39, 40, 41, 42, 43, 44, 45, 46, 47, - 55, 56, 57, 58, 59, 60, 61, 62, 63, - 71, 72, 73, 74, 75, 76, 77, 78, 79, - 87, 88, 89, 90, 91, 92, 93, 94, 95, - 103, 104, 105, 106, 107, 108, 109, 110, 111, - 119, 120, 121, 122, 123, 124, 125, 126, 127, - }, - .oobfree = { - {.offset = 2, .length = 4}, - {.offset = 16, .length = 7}, - {.offset = 32, .length = 7}, - {.offset = 48, .length = 7}, - {.offset = 64, .length = 7}, - {.offset = 80, .length = 7}, - {.offset = 96, .length = 7}, - {.offset = 112, .length = 7}, - } -}; - #ifdef CONFIG_MTD_PARTITIONS static const char *part_probes[] = { "RedBoot", "cmdlinepart", NULL }; #endif @@ -666,9 +641,9 @@ static void mxc_nand_read_buf(struct mtd_info *mtd, u_char *buf, int len) n = min(n, len); - memcpy(buf, host->data_buf + col, n); + memcpy(buf, host->data_buf + col, len); - host->buf_start += n; + host->buf_start += len; } /* Used by the upper layer to verify the data in NAND Flash @@ -1210,8 +1185,6 @@ static int __init mxcnd_probe(struct platform_device *pdev) if (mtd->writesize == 2048) this->ecc.layout = oob_largepage; - if (nfc_is_v21() && mtd->writesize == 4096) - this->ecc.layout = &nandv2_hw_eccoob_4k; /* second phase scan */ if (nand_scan_tail(mtd)) { diff --git a/trunk/drivers/mtd/nand/nand_base.c b/trunk/drivers/mtd/nand/nand_base.c index 85cfc061d41c..a9c6ce745767 100644 --- a/trunk/drivers/mtd/nand/nand_base.c +++ b/trunk/drivers/mtd/nand/nand_base.c @@ -42,7 +42,6 @@ #include #include #include -#include #include #include #include @@ -2378,7 +2377,7 @@ static int nand_do_write_oob(struct mtd_info *mtd, loff_t to, return -EINVAL; } - /* Do not allow write past end of device */ + /* Do not allow reads past end of device */ if (unlikely(to >= mtd->size || ops->ooboffs + ops->ooblen > ((mtd->size >> chip->page_shift) - @@ -3249,7 +3248,7 @@ int nand_scan_tail(struct mtd_info *mtd) /* * If no default placement scheme is given, select an appropriate one */ - if (!chip->ecc.layout && (chip->ecc.mode != NAND_ECC_SOFT_BCH)) { + if (!chip->ecc.layout) { switch (mtd->oobsize) { case 8: chip->ecc.layout = &nand_oob_8; @@ -3352,40 +3351,6 @@ int nand_scan_tail(struct mtd_info *mtd) chip->ecc.bytes = 3; break; - case NAND_ECC_SOFT_BCH: - if (!mtd_nand_has_bch()) { - printk(KERN_WARNING "CONFIG_MTD_ECC_BCH not enabled\n"); - BUG(); - } - chip->ecc.calculate = nand_bch_calculate_ecc; - chip->ecc.correct = nand_bch_correct_data; - chip->ecc.read_page = nand_read_page_swecc; - chip->ecc.read_subpage = nand_read_subpage; - chip->ecc.write_page = nand_write_page_swecc; - chip->ecc.read_page_raw = nand_read_page_raw; - chip->ecc.write_page_raw = nand_write_page_raw; - chip->ecc.read_oob = nand_read_oob_std; - chip->ecc.write_oob = nand_write_oob_std; - /* - * Board driver should supply ecc.size and ecc.bytes values to - * select how many bits are correctable; see nand_bch_init() - * for details. - * Otherwise, default to 4 bits for large page devices - */ - if (!chip->ecc.size && (mtd->oobsize >= 64)) { - chip->ecc.size = 512; - chip->ecc.bytes = 7; - } - chip->ecc.priv = nand_bch_init(mtd, - chip->ecc.size, - chip->ecc.bytes, - &chip->ecc.layout); - if (!chip->ecc.priv) { - printk(KERN_WARNING "BCH ECC initialization failed!\n"); - BUG(); - } - break; - case NAND_ECC_NONE: printk(KERN_WARNING "NAND_ECC_NONE selected by board driver. " "This is not recommended !!\n"); @@ -3536,9 +3501,6 @@ void nand_release(struct mtd_info *mtd) { struct nand_chip *chip = mtd->priv; - if (chip->ecc.mode == NAND_ECC_SOFT_BCH) - nand_bch_free((struct nand_bch_control *)chip->ecc.priv); - #ifdef CONFIG_MTD_PARTITIONS /* Deregister partitions */ del_mtd_partitions(mtd); diff --git a/trunk/drivers/mtd/nand/nand_bbt.c b/trunk/drivers/mtd/nand/nand_bbt.c index a1e8b30078d9..6ebd869993aa 100644 --- a/trunk/drivers/mtd/nand/nand_bbt.c +++ b/trunk/drivers/mtd/nand/nand_bbt.c @@ -1101,16 +1101,12 @@ static void mark_bbt_region(struct mtd_info *mtd, struct nand_bbt_descr *td) static void verify_bbt_descr(struct mtd_info *mtd, struct nand_bbt_descr *bd) { struct nand_chip *this = mtd->priv; - u32 pattern_len; - u32 bits; + u32 pattern_len = bd->len; + u32 bits = bd->options & NAND_BBT_NRBITS_MSK; u32 table_size; if (!bd) return; - - pattern_len = bd->len; - bits = bd->options & NAND_BBT_NRBITS_MSK; - BUG_ON((this->options & NAND_USE_FLASH_BBT_NO_OOB) && !(this->options & NAND_USE_FLASH_BBT)); BUG_ON(!bits); diff --git a/trunk/drivers/mtd/nand/nand_bch.c b/trunk/drivers/mtd/nand/nand_bch.c deleted file mode 100644 index 0f931e757116..000000000000 --- a/trunk/drivers/mtd/nand/nand_bch.c +++ /dev/null @@ -1,243 +0,0 @@ -/* - * This file provides ECC correction for more than 1 bit per block of data, - * using binary BCH codes. It relies on the generic BCH library lib/bch.c. - * - * Copyright © 2011 Ivan Djelic - * - * This file 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 file 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 file; 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 - -/** - * struct nand_bch_control - private NAND BCH control structure - * @bch: BCH control structure - * @ecclayout: private ecc layout for this BCH configuration - * @errloc: error location array - * @eccmask: XOR ecc mask, allows erased pages to be decoded as valid - */ -struct nand_bch_control { - struct bch_control *bch; - struct nand_ecclayout ecclayout; - unsigned int *errloc; - unsigned char *eccmask; -}; - -/** - * nand_bch_calculate_ecc - [NAND Interface] Calculate ECC for data block - * @mtd: MTD block structure - * @buf: input buffer with raw data - * @code: output buffer with ECC - */ -int nand_bch_calculate_ecc(struct mtd_info *mtd, const unsigned char *buf, - unsigned char *code) -{ - const struct nand_chip *chip = mtd->priv; - struct nand_bch_control *nbc = chip->ecc.priv; - unsigned int i; - - memset(code, 0, chip->ecc.bytes); - encode_bch(nbc->bch, buf, chip->ecc.size, code); - - /* apply mask so that an erased page is a valid codeword */ - for (i = 0; i < chip->ecc.bytes; i++) - code[i] ^= nbc->eccmask[i]; - - return 0; -} -EXPORT_SYMBOL(nand_bch_calculate_ecc); - -/** - * nand_bch_correct_data - [NAND Interface] Detect and correct bit error(s) - * @mtd: MTD block structure - * @buf: raw data read from the chip - * @read_ecc: ECC from the chip - * @calc_ecc: the ECC calculated from raw data - * - * Detect and correct bit errors for a data byte block - */ -int nand_bch_correct_data(struct mtd_info *mtd, unsigned char *buf, - unsigned char *read_ecc, unsigned char *calc_ecc) -{ - const struct nand_chip *chip = mtd->priv; - struct nand_bch_control *nbc = chip->ecc.priv; - unsigned int *errloc = nbc->errloc; - int i, count; - - count = decode_bch(nbc->bch, NULL, chip->ecc.size, read_ecc, calc_ecc, - NULL, errloc); - if (count > 0) { - for (i = 0; i < count; i++) { - if (errloc[i] < (chip->ecc.size*8)) - /* error is located in data, correct it */ - buf[errloc[i] >> 3] ^= (1 << (errloc[i] & 7)); - /* else error in ecc, no action needed */ - - DEBUG(MTD_DEBUG_LEVEL0, "%s: corrected bitflip %u\n", - __func__, errloc[i]); - } - } else if (count < 0) { - printk(KERN_ERR "ecc unrecoverable error\n"); - count = -1; - } - return count; -} -EXPORT_SYMBOL(nand_bch_correct_data); - -/** - * nand_bch_init - [NAND Interface] Initialize NAND BCH error correction - * @mtd: MTD block structure - * @eccsize: ecc block size in bytes - * @eccbytes: ecc length in bytes - * @ecclayout: output default layout - * - * Returns: - * a pointer to a new NAND BCH control structure, or NULL upon failure - * - * Initialize NAND BCH error correction. Parameters @eccsize and @eccbytes - * are used to compute BCH parameters m (Galois field order) and t (error - * correction capability). @eccbytes should be equal to the number of bytes - * required to store m*t bits, where m is such that 2^m-1 > @eccsize*8. - * - * Example: to configure 4 bit correction per 512 bytes, you should pass - * @eccsize = 512 (thus, m=13 is the smallest integer such that 2^m-1 > 512*8) - * @eccbytes = 7 (7 bytes are required to store m*t = 13*4 = 52 bits) - */ -struct nand_bch_control * -nand_bch_init(struct mtd_info *mtd, unsigned int eccsize, unsigned int eccbytes, - struct nand_ecclayout **ecclayout) -{ - unsigned int m, t, eccsteps, i; - struct nand_ecclayout *layout; - struct nand_bch_control *nbc = NULL; - unsigned char *erased_page; - - if (!eccsize || !eccbytes) { - printk(KERN_WARNING "ecc parameters not supplied\n"); - goto fail; - } - - m = fls(1+8*eccsize); - t = (eccbytes*8)/m; - - nbc = kzalloc(sizeof(*nbc), GFP_KERNEL); - if (!nbc) - goto fail; - - nbc->bch = init_bch(m, t, 0); - if (!nbc->bch) - goto fail; - - /* verify that eccbytes has the expected value */ - if (nbc->bch->ecc_bytes != eccbytes) { - printk(KERN_WARNING "invalid eccbytes %u, should be %u\n", - eccbytes, nbc->bch->ecc_bytes); - goto fail; - } - - eccsteps = mtd->writesize/eccsize; - - /* if no ecc placement scheme was provided, build one */ - if (!*ecclayout) { - - /* handle large page devices only */ - if (mtd->oobsize < 64) { - printk(KERN_WARNING "must provide an oob scheme for " - "oobsize %d\n", mtd->oobsize); - goto fail; - } - - layout = &nbc->ecclayout; - layout->eccbytes = eccsteps*eccbytes; - - /* reserve 2 bytes for bad block marker */ - if (layout->eccbytes+2 > mtd->oobsize) { - printk(KERN_WARNING "no suitable oob scheme available " - "for oobsize %d eccbytes %u\n", mtd->oobsize, - eccbytes); - goto fail; - } - /* put ecc bytes at oob tail */ - for (i = 0; i < layout->eccbytes; i++) - layout->eccpos[i] = mtd->oobsize-layout->eccbytes+i; - - layout->oobfree[0].offset = 2; - layout->oobfree[0].length = mtd->oobsize-2-layout->eccbytes; - - *ecclayout = layout; - } - - /* sanity checks */ - if (8*(eccsize+eccbytes) >= (1 << m)) { - printk(KERN_WARNING "eccsize %u is too large\n", eccsize); - goto fail; - } - if ((*ecclayout)->eccbytes != (eccsteps*eccbytes)) { - printk(KERN_WARNING "invalid ecc layout\n"); - goto fail; - } - - nbc->eccmask = kmalloc(eccbytes, GFP_KERNEL); - nbc->errloc = kmalloc(t*sizeof(*nbc->errloc), GFP_KERNEL); - if (!nbc->eccmask || !nbc->errloc) - goto fail; - /* - * compute and store the inverted ecc of an erased ecc block - */ - erased_page = kmalloc(eccsize, GFP_KERNEL); - if (!erased_page) - goto fail; - - memset(erased_page, 0xff, eccsize); - memset(nbc->eccmask, 0, eccbytes); - encode_bch(nbc->bch, erased_page, eccsize, nbc->eccmask); - kfree(erased_page); - - for (i = 0; i < eccbytes; i++) - nbc->eccmask[i] ^= 0xff; - - return nbc; -fail: - nand_bch_free(nbc); - return NULL; -} -EXPORT_SYMBOL(nand_bch_init); - -/** - * nand_bch_free - [NAND Interface] Release NAND BCH ECC resources - * @nbc: NAND BCH control structure - */ -void nand_bch_free(struct nand_bch_control *nbc) -{ - if (nbc) { - free_bch(nbc->bch); - kfree(nbc->errloc); - kfree(nbc->eccmask); - kfree(nbc); - } -} -EXPORT_SYMBOL(nand_bch_free); - -MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Ivan Djelic "); -MODULE_DESCRIPTION("NAND software BCH ECC support"); diff --git a/trunk/drivers/mtd/nand/nandsim.c b/trunk/drivers/mtd/nand/nandsim.c index 213181be0d9a..a5aa99f014ba 100644 --- a/trunk/drivers/mtd/nand/nandsim.c +++ b/trunk/drivers/mtd/nand/nandsim.c @@ -34,7 +34,6 @@ #include #include #include -#include #include #include #include @@ -109,7 +108,6 @@ static unsigned int rptwear = 0; static unsigned int overridesize = 0; static char *cache_file = NULL; static unsigned int bbt; -static unsigned int bch; module_param(first_id_byte, uint, 0400); module_param(second_id_byte, uint, 0400); @@ -134,7 +132,6 @@ module_param(rptwear, uint, 0400); module_param(overridesize, uint, 0400); module_param(cache_file, charp, 0400); module_param(bbt, uint, 0400); -module_param(bch, uint, 0400); MODULE_PARM_DESC(first_id_byte, "The first byte returned by NAND Flash 'read ID' command (manufacturer ID)"); MODULE_PARM_DESC(second_id_byte, "The second byte returned by NAND Flash 'read ID' command (chip ID)"); @@ -168,8 +165,6 @@ MODULE_PARM_DESC(overridesize, "Specifies the NAND Flash size overriding the I " e.g. 5 means a size of 32 erase blocks"); MODULE_PARM_DESC(cache_file, "File to use to cache nand pages instead of memory"); MODULE_PARM_DESC(bbt, "0 OOB, 1 BBT with marker in OOB, 2 BBT with marker in data area"); -MODULE_PARM_DESC(bch, "Enable BCH ecc and set how many bits should " - "be correctable in 512-byte blocks"); /* The largest possible page size */ #define NS_LARGEST_PAGE_SIZE 4096 @@ -2314,43 +2309,7 @@ static int __init ns_init_module(void) if ((retval = parse_gravepages()) != 0) goto error; - retval = nand_scan_ident(nsmtd, 1, NULL); - if (retval) { - NS_ERR("cannot scan NAND Simulator device\n"); - if (retval > 0) - retval = -ENXIO; - goto error; - } - - if (bch) { - unsigned int eccsteps, eccbytes; - if (!mtd_nand_has_bch()) { - NS_ERR("BCH ECC support is disabled\n"); - retval = -EINVAL; - goto error; - } - /* use 512-byte ecc blocks */ - eccsteps = nsmtd->writesize/512; - eccbytes = (bch*13+7)/8; - /* do not bother supporting small page devices */ - if ((nsmtd->oobsize < 64) || !eccsteps) { - NS_ERR("bch not available on small page devices\n"); - retval = -EINVAL; - goto error; - } - if ((eccbytes*eccsteps+2) > nsmtd->oobsize) { - NS_ERR("invalid bch value %u\n", bch); - retval = -EINVAL; - goto error; - } - chip->ecc.mode = NAND_ECC_SOFT_BCH; - chip->ecc.size = 512; - chip->ecc.bytes = eccbytes; - NS_INFO("using %u-bit/%u bytes BCH ECC\n", bch, chip->ecc.size); - } - - retval = nand_scan_tail(nsmtd); - if (retval) { + if ((retval = nand_scan(nsmtd, 1)) != 0) { NS_ERR("can't register NAND Simulator\n"); if (retval > 0) retval = -ENXIO; diff --git a/trunk/drivers/mtd/nand/omap2.c b/trunk/drivers/mtd/nand/omap2.c index da9a351c9d79..7b8f1fffc528 100644 --- a/trunk/drivers/mtd/nand/omap2.c +++ b/trunk/drivers/mtd/nand/omap2.c @@ -668,8 +668,6 @@ static void gen_true_ecc(u8 *ecc_buf) * * This function compares two ECC's and indicates if there is an error. * If the error can be corrected it will be corrected to the buffer. - * If there is no error, %0 is returned. If there is an error but it - * was corrected, %1 is returned. Otherwise, %-1 is returned. */ static int omap_compare_ecc(u8 *ecc_data1, /* read from NAND memory */ u8 *ecc_data2, /* read from register */ @@ -775,7 +773,7 @@ static int omap_compare_ecc(u8 *ecc_data1, /* read from NAND memory */ page_data[find_byte] ^= (1 << find_bit); - return 1; + return 0; default: if (isEccFF) { if (ecc_data2[0] == 0 && @@ -796,11 +794,8 @@ static int omap_compare_ecc(u8 *ecc_data1, /* read from NAND memory */ * @calc_ecc: ecc read from HW ECC registers * * Compares the ecc read from nand spare area with ECC registers values - * and if ECC's mismatched, it will call 'omap_compare_ecc' for error - * detection and correction. If there are no errors, %0 is returned. If - * there were errors and all of the errors were corrected, the number of - * corrected errors is returned. If uncorrectable errors exist, %-1 is - * returned. + * and if ECC's mismached, it will call 'omap_compare_ecc' for error detection + * and correction. */ static int omap_correct_data(struct mtd_info *mtd, u_char *dat, u_char *read_ecc, u_char *calc_ecc) @@ -808,7 +803,6 @@ static int omap_correct_data(struct mtd_info *mtd, u_char *dat, struct omap_nand_info *info = container_of(mtd, struct omap_nand_info, mtd); int blockCnt = 0, i = 0, ret = 0; - int stat = 0; /* Ex NAND_ECC_HW12_2048 */ if ((info->nand.ecc.mode == NAND_ECC_HW) && @@ -822,14 +816,12 @@ static int omap_correct_data(struct mtd_info *mtd, u_char *dat, ret = omap_compare_ecc(read_ecc, calc_ecc, dat); if (ret < 0) return ret; - /* keep track of the number of corrected errors */ - stat += ret; } read_ecc += 3; calc_ecc += 3; dat += 512; } - return stat; + return 0; } /** diff --git a/trunk/drivers/mtd/nand/pxa3xx_nand.c b/trunk/drivers/mtd/nand/pxa3xx_nand.c index ab7f4c33ced6..ea2c288df3f6 100644 --- a/trunk/drivers/mtd/nand/pxa3xx_nand.c +++ b/trunk/drivers/mtd/nand/pxa3xx_nand.c @@ -27,8 +27,6 @@ #include #define CHIP_DELAY_TIMEOUT (2 * HZ/10) -#define NAND_STOP_DELAY (2 * HZ/50) -#define PAGE_CHUNK_SIZE (2048) /* registers and bit definitions */ #define NDCR (0x00) /* Control register */ @@ -54,18 +52,16 @@ #define NDCR_ND_MODE (0x3 << 21) #define NDCR_NAND_MODE (0x0) #define NDCR_CLR_PG_CNT (0x1 << 20) -#define NDCR_STOP_ON_UNCOR (0x1 << 19) +#define NDCR_CLR_ECC (0x1 << 19) #define NDCR_RD_ID_CNT_MASK (0x7 << 16) #define NDCR_RD_ID_CNT(x) (((x) << 16) & NDCR_RD_ID_CNT_MASK) #define NDCR_RA_START (0x1 << 15) #define NDCR_PG_PER_BLK (0x1 << 14) #define NDCR_ND_ARB_EN (0x1 << 12) -#define NDCR_INT_MASK (0xFFF) #define NDSR_MASK (0xfff) -#define NDSR_RDY (0x1 << 12) -#define NDSR_FLASH_RDY (0x1 << 11) +#define NDSR_RDY (0x1 << 11) #define NDSR_CS0_PAGED (0x1 << 10) #define NDSR_CS1_PAGED (0x1 << 9) #define NDSR_CS0_CMDD (0x1 << 8) @@ -78,7 +74,6 @@ #define NDSR_RDDREQ (0x1 << 1) #define NDSR_WRCMDREQ (0x1) -#define NDCB0_ST_ROW_EN (0x1 << 26) #define NDCB0_AUTO_RS (0x1 << 25) #define NDCB0_CSEL (0x1 << 24) #define NDCB0_CMD_TYPE_MASK (0x7 << 21) @@ -109,21 +104,18 @@ enum { }; enum { - STATE_IDLE = 0, + STATE_READY = 0, STATE_CMD_HANDLE, STATE_DMA_READING, STATE_DMA_WRITING, STATE_DMA_DONE, STATE_PIO_READING, STATE_PIO_WRITING, - STATE_CMD_DONE, - STATE_READY, }; struct pxa3xx_nand_info { struct nand_chip nand_chip; - struct nand_hw_control controller; struct platform_device *pdev; struct pxa3xx_nand_cmdset *cmdset; @@ -134,7 +126,6 @@ struct pxa3xx_nand_info { unsigned int buf_start; unsigned int buf_count; - struct mtd_info *mtd; /* DMA information */ int drcmr_dat; int drcmr_cmd; @@ -158,7 +149,6 @@ struct pxa3xx_nand_info { int use_ecc; /* use HW ECC ? */ int use_dma; /* use DMA ? */ - int is_ready; unsigned int page_size; /* page size of attached chip */ unsigned int data_size; /* data size in FIFO */ @@ -211,22 +201,20 @@ static struct pxa3xx_nand_timing timing[] = { }; static struct pxa3xx_nand_flash builtin_flash_types[] = { -{ "DEFAULT FLASH", 0, 0, 2048, 8, 8, 0, &timing[0] }, -{ "64MiB 16-bit", 0x46ec, 32, 512, 16, 16, 4096, &timing[1] }, -{ "256MiB 8-bit", 0xdaec, 64, 2048, 8, 8, 2048, &timing[1] }, -{ "4GiB 8-bit", 0xd7ec, 128, 4096, 8, 8, 8192, &timing[1] }, -{ "128MiB 8-bit", 0xa12c, 64, 2048, 8, 8, 1024, &timing[2] }, -{ "128MiB 16-bit", 0xb12c, 64, 2048, 16, 16, 1024, &timing[2] }, -{ "512MiB 8-bit", 0xdc2c, 64, 2048, 8, 8, 4096, &timing[2] }, -{ "512MiB 16-bit", 0xcc2c, 64, 2048, 16, 16, 4096, &timing[2] }, -{ "256MiB 16-bit", 0xba20, 64, 2048, 16, 16, 2048, &timing[3] }, + { 0, 0, 2048, 8, 8, 0, &default_cmdset, &timing[0] }, + { 0x46ec, 32, 512, 16, 16, 4096, &default_cmdset, &timing[1] }, + { 0xdaec, 64, 2048, 8, 8, 2048, &default_cmdset, &timing[1] }, + { 0xd7ec, 128, 4096, 8, 8, 8192, &default_cmdset, &timing[1] }, + { 0xa12c, 64, 2048, 8, 8, 1024, &default_cmdset, &timing[2] }, + { 0xb12c, 64, 2048, 16, 16, 1024, &default_cmdset, &timing[2] }, + { 0xdc2c, 64, 2048, 8, 8, 4096, &default_cmdset, &timing[2] }, + { 0xcc2c, 64, 2048, 16, 16, 4096, &default_cmdset, &timing[2] }, + { 0xba20, 64, 2048, 16, 16, 2048, &default_cmdset, &timing[3] }, }; /* Define a default flash type setting serve as flash detecting only */ #define DEFAULT_FLASH_TYPE (&builtin_flash_types[0]) -const char *mtd_names[] = {"pxa3xx_nand-0", NULL}; - #define NDTR0_tCH(c) (min((c), 7) << 19) #define NDTR0_tCS(c) (min((c), 7) << 16) #define NDTR0_tWH(c) (min((c), 7) << 11) @@ -264,6 +252,25 @@ static void pxa3xx_nand_set_timing(struct pxa3xx_nand_info *info, nand_writel(info, NDTR1CS0, ndtr1); } +#define WAIT_EVENT_TIMEOUT 10 + +static int wait_for_event(struct pxa3xx_nand_info *info, uint32_t event) +{ + int timeout = WAIT_EVENT_TIMEOUT; + uint32_t ndsr; + + while (timeout--) { + ndsr = nand_readl(info, NDSR) & NDSR_MASK; + if (ndsr & event) { + nand_writel(info, NDSR, ndsr); + return 0; + } + udelay(10); + } + + return -ETIMEDOUT; +} + static void pxa3xx_set_datasize(struct pxa3xx_nand_info *info) { int oob_enable = info->reg_ndcr & NDCR_SPARE_EN; @@ -284,45 +291,69 @@ static void pxa3xx_set_datasize(struct pxa3xx_nand_info *info) } } -/** - * NOTE: it is a must to set ND_RUN firstly, then write - * command buffer, otherwise, it does not work. - * We enable all the interrupt at the same time, and - * let pxa3xx_nand_irq to handle all logic. - */ -static void pxa3xx_nand_start(struct pxa3xx_nand_info *info) +static int prepare_read_prog_cmd(struct pxa3xx_nand_info *info, + uint16_t cmd, int column, int page_addr) { - uint32_t ndcr; + const struct pxa3xx_nand_cmdset *cmdset = info->cmdset; + pxa3xx_set_datasize(info); + + /* generate values for NDCBx registers */ + info->ndcb0 = cmd | ((cmd & 0xff00) ? NDCB0_DBC : 0); + info->ndcb1 = 0; + info->ndcb2 = 0; + info->ndcb0 |= NDCB0_ADDR_CYC(info->row_addr_cycles + info->col_addr_cycles); + + if (info->col_addr_cycles == 2) { + /* large block, 2 cycles for column address + * row address starts from 3rd cycle + */ + info->ndcb1 |= page_addr << 16; + if (info->row_addr_cycles == 3) + info->ndcb2 = (page_addr >> 16) & 0xff; + } else + /* small block, 1 cycles for column address + * row address starts from 2nd cycle + */ + info->ndcb1 = page_addr << 8; - ndcr = info->reg_ndcr; - ndcr |= info->use_ecc ? NDCR_ECC_EN : 0; - ndcr |= info->use_dma ? NDCR_DMA_EN : 0; - ndcr |= NDCR_ND_RUN; + if (cmd == cmdset->program) + info->ndcb0 |= NDCB0_CMD_TYPE(1) | NDCB0_AUTO_RS; - /* clear status bits and run */ - nand_writel(info, NDCR, 0); - nand_writel(info, NDSR, NDSR_MASK); - nand_writel(info, NDCR, ndcr); + return 0; } -static void pxa3xx_nand_stop(struct pxa3xx_nand_info *info) +static int prepare_erase_cmd(struct pxa3xx_nand_info *info, + uint16_t cmd, int page_addr) { - uint32_t ndcr; - int timeout = NAND_STOP_DELAY; + info->ndcb0 = cmd | ((cmd & 0xff00) ? NDCB0_DBC : 0); + info->ndcb0 |= NDCB0_CMD_TYPE(2) | NDCB0_AUTO_RS | NDCB0_ADDR_CYC(3); + info->ndcb1 = page_addr; + info->ndcb2 = 0; + return 0; +} - /* wait RUN bit in NDCR become 0 */ - ndcr = nand_readl(info, NDCR); - while ((ndcr & NDCR_ND_RUN) && (timeout-- > 0)) { - ndcr = nand_readl(info, NDCR); - udelay(1); - } +static int prepare_other_cmd(struct pxa3xx_nand_info *info, uint16_t cmd) +{ + const struct pxa3xx_nand_cmdset *cmdset = info->cmdset; - if (timeout <= 0) { - ndcr &= ~NDCR_ND_RUN; - nand_writel(info, NDCR, ndcr); - } - /* clear status bits */ - nand_writel(info, NDSR, NDSR_MASK); + info->ndcb0 = cmd | ((cmd & 0xff00) ? NDCB0_DBC : 0); + info->ndcb1 = 0; + info->ndcb2 = 0; + + info->oob_size = 0; + if (cmd == cmdset->read_id) { + info->ndcb0 |= NDCB0_CMD_TYPE(3); + info->data_size = 8; + } else if (cmd == cmdset->read_status) { + info->ndcb0 |= NDCB0_CMD_TYPE(4); + info->data_size = 8; + } else if (cmd == cmdset->reset || cmd == cmdset->lock || + cmd == cmdset->unlock) { + info->ndcb0 |= NDCB0_CMD_TYPE(5); + } else + return -EINVAL; + + return 0; } static void enable_int(struct pxa3xx_nand_info *info, uint32_t int_mask) @@ -341,8 +372,39 @@ static void disable_int(struct pxa3xx_nand_info *info, uint32_t int_mask) nand_writel(info, NDCR, ndcr | int_mask); } -static void handle_data_pio(struct pxa3xx_nand_info *info) +/* NOTE: it is a must to set ND_RUN firstly, then write command buffer + * otherwise, it does not work + */ +static int write_cmd(struct pxa3xx_nand_info *info) { + uint32_t ndcr; + + /* clear status bits and run */ + nand_writel(info, NDSR, NDSR_MASK); + + ndcr = info->reg_ndcr; + + ndcr |= info->use_ecc ? NDCR_ECC_EN : 0; + ndcr |= info->use_dma ? NDCR_DMA_EN : 0; + ndcr |= NDCR_ND_RUN; + + nand_writel(info, NDCR, ndcr); + + if (wait_for_event(info, NDSR_WRCMDREQ)) { + printk(KERN_ERR "timed out writing command\n"); + return -ETIMEDOUT; + } + + nand_writel(info, NDCB0, info->ndcb0); + nand_writel(info, NDCB0, info->ndcb1); + nand_writel(info, NDCB0, info->ndcb2); + return 0; +} + +static int handle_data_pio(struct pxa3xx_nand_info *info) +{ + int ret, timeout = CHIP_DELAY_TIMEOUT; + switch (info->state) { case STATE_PIO_WRITING: __raw_writesl(info->mmio_base + NDDB, info->data_buff, @@ -350,6 +412,14 @@ static void handle_data_pio(struct pxa3xx_nand_info *info) if (info->oob_size > 0) __raw_writesl(info->mmio_base + NDDB, info->oob_buff, DIV_ROUND_UP(info->oob_size, 4)); + + enable_int(info, NDSR_CS0_BBD | NDSR_CS0_CMDD); + + ret = wait_for_completion_timeout(&info->cmd_complete, timeout); + if (!ret) { + printk(KERN_ERR "program command time out\n"); + return -1; + } break; case STATE_PIO_READING: __raw_readsl(info->mmio_base + NDDB, info->data_buff, @@ -361,11 +431,14 @@ static void handle_data_pio(struct pxa3xx_nand_info *info) default: printk(KERN_ERR "%s: invalid state %d\n", __func__, info->state); - BUG(); + return -EINVAL; } + + info->state = STATE_READY; + return 0; } -static void start_data_dma(struct pxa3xx_nand_info *info) +static void start_data_dma(struct pxa3xx_nand_info *info, int dir_out) { struct pxa_dma_desc *desc = info->data_desc; int dma_len = ALIGN(info->data_size + info->oob_size, 32); @@ -373,21 +446,14 @@ static void start_data_dma(struct pxa3xx_nand_info *info) desc->ddadr = DDADR_STOP; desc->dcmd = DCMD_ENDIRQEN | DCMD_WIDTH4 | DCMD_BURST32 | dma_len; - switch (info->state) { - case STATE_DMA_WRITING: + if (dir_out) { desc->dsadr = info->data_buff_phys; desc->dtadr = info->mmio_phys + NDDB; desc->dcmd |= DCMD_INCSRCADDR | DCMD_FLOWTRG; - break; - case STATE_DMA_READING: + } else { desc->dtadr = info->data_buff_phys; desc->dsadr = info->mmio_phys + NDDB; desc->dcmd |= DCMD_INCTRGADDR | DCMD_FLOWSRC; - break; - default: - printk(KERN_ERR "%s: invalid state %d\n", __func__, - info->state); - BUG(); } DRCMR(info->drcmr_dat) = DRCMR_MAPVLD | info->data_dma_ch; @@ -405,62 +471,93 @@ static void pxa3xx_nand_data_dma_irq(int channel, void *data) if (dcsr & DCSR_BUSERR) { info->retcode = ERR_DMABUSERR; + complete(&info->cmd_complete); } - info->state = STATE_DMA_DONE; - enable_int(info, NDCR_INT_MASK); - nand_writel(info, NDSR, NDSR_WRDREQ | NDSR_RDDREQ); + if (info->state == STATE_DMA_WRITING) { + info->state = STATE_DMA_DONE; + enable_int(info, NDSR_CS0_BBD | NDSR_CS0_CMDD); + } else { + info->state = STATE_READY; + complete(&info->cmd_complete); + } } static irqreturn_t pxa3xx_nand_irq(int irq, void *devid) { struct pxa3xx_nand_info *info = devid; - unsigned int status, is_completed = 0; + unsigned int status; status = nand_readl(info, NDSR); - if (status & NDSR_DBERR) - info->retcode = ERR_DBERR; - if (status & NDSR_SBERR) - info->retcode = ERR_SBERR; - if (status & (NDSR_RDDREQ | NDSR_WRDREQ)) { - /* whether use dma to transfer data */ + if (status & (NDSR_RDDREQ | NDSR_DBERR | NDSR_SBERR)) { + if (status & NDSR_DBERR) + info->retcode = ERR_DBERR; + else if (status & NDSR_SBERR) + info->retcode = ERR_SBERR; + + disable_int(info, NDSR_RDDREQ | NDSR_DBERR | NDSR_SBERR); + if (info->use_dma) { - disable_int(info, NDCR_INT_MASK); - info->state = (status & NDSR_RDDREQ) ? - STATE_DMA_READING : STATE_DMA_WRITING; - start_data_dma(info); - goto NORMAL_IRQ_EXIT; + info->state = STATE_DMA_READING; + start_data_dma(info, 0); } else { - info->state = (status & NDSR_RDDREQ) ? - STATE_PIO_READING : STATE_PIO_WRITING; - handle_data_pio(info); + info->state = STATE_PIO_READING; + complete(&info->cmd_complete); } - } - if (status & NDSR_CS0_CMDD) { - info->state = STATE_CMD_DONE; - is_completed = 1; - } - if (status & NDSR_FLASH_RDY) { - info->is_ready = 1; + } else if (status & NDSR_WRDREQ) { + disable_int(info, NDSR_WRDREQ); + if (info->use_dma) { + info->state = STATE_DMA_WRITING; + start_data_dma(info, 1); + } else { + info->state = STATE_PIO_WRITING; + complete(&info->cmd_complete); + } + } else if (status & (NDSR_CS0_BBD | NDSR_CS0_CMDD)) { + if (status & NDSR_CS0_BBD) + info->retcode = ERR_BBERR; + + disable_int(info, NDSR_CS0_BBD | NDSR_CS0_CMDD); info->state = STATE_READY; + complete(&info->cmd_complete); + } + nand_writel(info, NDSR, status); + return IRQ_HANDLED; +} + +static int pxa3xx_nand_do_cmd(struct pxa3xx_nand_info *info, uint32_t event) +{ + uint32_t ndcr; + int ret, timeout = CHIP_DELAY_TIMEOUT; + + if (write_cmd(info)) { + info->retcode = ERR_SENDCMD; + goto fail_stop; } - if (status & NDSR_WRCMDREQ) { - nand_writel(info, NDSR, NDSR_WRCMDREQ); - status &= ~NDSR_WRCMDREQ; - info->state = STATE_CMD_HANDLE; - nand_writel(info, NDCB0, info->ndcb0); - nand_writel(info, NDCB0, info->ndcb1); - nand_writel(info, NDCB0, info->ndcb2); + info->state = STATE_CMD_HANDLE; + + enable_int(info, event); + + ret = wait_for_completion_timeout(&info->cmd_complete, timeout); + if (!ret) { + printk(KERN_ERR "command execution timed out\n"); + info->retcode = ERR_SENDCMD; + goto fail_stop; } - /* clear NDSR to let the controller exit the IRQ */ - nand_writel(info, NDSR, status); - if (is_completed) - complete(&info->cmd_complete); -NORMAL_IRQ_EXIT: - return IRQ_HANDLED; + if (info->use_dma == 0 && info->data_size > 0) + if (handle_data_pio(info)) + goto fail_stop; + + return 0; + +fail_stop: + ndcr = nand_readl(info, NDCR); + nand_writel(info, NDCR, ndcr & ~NDCR_ND_RUN); + udelay(10); + return -ETIMEDOUT; } static int pxa3xx_nand_dev_ready(struct mtd_info *mtd) @@ -477,218 +574,125 @@ static inline int is_buf_blank(uint8_t *buf, size_t len) return 1; } -static int prepare_command_pool(struct pxa3xx_nand_info *info, int command, - uint16_t column, int page_addr) +static void pxa3xx_nand_cmdfunc(struct mtd_info *mtd, unsigned command, + int column, int page_addr) { - uint16_t cmd; - int addr_cycle, exec_cmd, ndcb0; - struct mtd_info *mtd = info->mtd; - - ndcb0 = 0; - addr_cycle = 0; - exec_cmd = 1; - - /* reset data and oob column point to handle data */ - info->buf_start = 0; - info->buf_count = 0; - info->oob_size = 0; - info->use_ecc = 0; - info->is_ready = 0; - info->retcode = ERR_NONE; + struct pxa3xx_nand_info *info = mtd->priv; + const struct pxa3xx_nand_cmdset *cmdset = info->cmdset; + int ret; - switch (command) { - case NAND_CMD_READ0: - case NAND_CMD_PAGEPROG: - info->use_ecc = 1; - case NAND_CMD_READOOB: - pxa3xx_set_datasize(info); - break; - case NAND_CMD_SEQIN: - exec_cmd = 0; - break; - default: - info->ndcb1 = 0; - info->ndcb2 = 0; - break; - } + info->use_dma = (use_dma) ? 1 : 0; + info->use_ecc = 0; + info->data_size = 0; + info->state = STATE_READY; - info->ndcb0 = ndcb0; - addr_cycle = NDCB0_ADDR_CYC(info->row_addr_cycles - + info->col_addr_cycles); + init_completion(&info->cmd_complete); switch (command) { case NAND_CMD_READOOB: - case NAND_CMD_READ0: - cmd = info->cmdset->read1; - if (command == NAND_CMD_READOOB) - info->buf_start = mtd->writesize + column; - else - info->buf_start = column; - - if (unlikely(info->page_size < PAGE_CHUNK_SIZE)) - info->ndcb0 |= NDCB0_CMD_TYPE(0) - | addr_cycle - | (cmd & NDCB0_CMD1_MASK); - else - info->ndcb0 |= NDCB0_CMD_TYPE(0) - | NDCB0_DBC - | addr_cycle - | cmd; + /* disable HW ECC to get all the OOB data */ + info->buf_count = mtd->writesize + mtd->oobsize; + info->buf_start = mtd->writesize + column; + memset(info->data_buff, 0xFF, info->buf_count); - case NAND_CMD_SEQIN: - /* small page addr setting */ - if (unlikely(info->page_size < PAGE_CHUNK_SIZE)) { - info->ndcb1 = ((page_addr & 0xFFFFFF) << 8) - | (column & 0xFF); + if (prepare_read_prog_cmd(info, cmdset->read1, column, page_addr)) + break; - info->ndcb2 = 0; - } else { - info->ndcb1 = ((page_addr & 0xFFFF) << 16) - | (column & 0xFFFF); + pxa3xx_nand_do_cmd(info, NDSR_RDDREQ | NDSR_DBERR | NDSR_SBERR); - if (page_addr & 0xFF0000) - info->ndcb2 = (page_addr & 0xFF0000) >> 16; - else - info->ndcb2 = 0; - } + /* We only are OOB, so if the data has error, does not matter */ + if (info->retcode == ERR_DBERR) + info->retcode = ERR_NONE; + break; + case NAND_CMD_READ0: + info->use_ecc = 1; + info->retcode = ERR_NONE; + info->buf_start = column; info->buf_count = mtd->writesize + mtd->oobsize; memset(info->data_buff, 0xFF, info->buf_count); - break; - - case NAND_CMD_PAGEPROG: - if (is_buf_blank(info->data_buff, - (mtd->writesize + mtd->oobsize))) { - exec_cmd = 0; + if (prepare_read_prog_cmd(info, cmdset->read1, column, page_addr)) break; - } - cmd = info->cmdset->program; - info->ndcb0 |= NDCB0_CMD_TYPE(0x1) - | NDCB0_AUTO_RS - | NDCB0_ST_ROW_EN - | NDCB0_DBC - | cmd - | addr_cycle; - break; - - case NAND_CMD_READID: - cmd = info->cmdset->read_id; - info->buf_count = info->read_id_bytes; - info->ndcb0 |= NDCB0_CMD_TYPE(3) - | NDCB0_ADDR_CYC(1) - | cmd; + pxa3xx_nand_do_cmd(info, NDSR_RDDREQ | NDSR_DBERR | NDSR_SBERR); - info->data_size = 8; + if (info->retcode == ERR_DBERR) { + /* for blank page (all 0xff), HW will calculate its ECC as + * 0, which is different from the ECC information within + * OOB, ignore such double bit errors + */ + if (is_buf_blank(info->data_buff, mtd->writesize)) + info->retcode = ERR_NONE; + } break; - case NAND_CMD_STATUS: - cmd = info->cmdset->read_status; - info->buf_count = 1; - info->ndcb0 |= NDCB0_CMD_TYPE(4) - | NDCB0_ADDR_CYC(1) - | cmd; + case NAND_CMD_SEQIN: + info->buf_start = column; + info->buf_count = mtd->writesize + mtd->oobsize; + memset(info->data_buff, 0xff, info->buf_count); - info->data_size = 8; + /* save column/page_addr for next CMD_PAGEPROG */ + info->seqin_column = column; + info->seqin_page_addr = page_addr; break; + case NAND_CMD_PAGEPROG: + info->use_ecc = (info->seqin_column >= mtd->writesize) ? 0 : 1; - case NAND_CMD_ERASE1: - cmd = info->cmdset->erase; - info->ndcb0 |= NDCB0_CMD_TYPE(2) - | NDCB0_AUTO_RS - | NDCB0_ADDR_CYC(3) - | NDCB0_DBC - | cmd; - info->ndcb1 = page_addr; - info->ndcb2 = 0; + if (prepare_read_prog_cmd(info, cmdset->program, + info->seqin_column, info->seqin_page_addr)) + break; + pxa3xx_nand_do_cmd(info, NDSR_WRDREQ); break; - case NAND_CMD_RESET: - cmd = info->cmdset->reset; - info->ndcb0 |= NDCB0_CMD_TYPE(5) - | cmd; + case NAND_CMD_ERASE1: + if (prepare_erase_cmd(info, cmdset->erase, page_addr)) + break; + pxa3xx_nand_do_cmd(info, NDSR_CS0_BBD | NDSR_CS0_CMDD); break; - case NAND_CMD_ERASE2: - exec_cmd = 0; - break; - - default: - exec_cmd = 0; - printk(KERN_ERR "pxa3xx-nand: non-supported" - " command %x\n", command); break; - } + case NAND_CMD_READID: + case NAND_CMD_STATUS: + info->use_dma = 0; /* force PIO read */ + info->buf_start = 0; + info->buf_count = (command == NAND_CMD_READID) ? + info->read_id_bytes : 1; - return exec_cmd; -} + if (prepare_other_cmd(info, (command == NAND_CMD_READID) ? + cmdset->read_id : cmdset->read_status)) + break; -static void pxa3xx_nand_cmdfunc(struct mtd_info *mtd, unsigned command, - int column, int page_addr) -{ - struct pxa3xx_nand_info *info = mtd->priv; - int ret, exec_cmd; + pxa3xx_nand_do_cmd(info, NDSR_RDDREQ); + break; + case NAND_CMD_RESET: + if (prepare_other_cmd(info, cmdset->reset)) + break; - /* - * if this is a x16 device ,then convert the input - * "byte" address into a "word" address appropriate - * for indexing a word-oriented device - */ - if (info->reg_ndcr & NDCR_DWIDTH_M) - column /= 2; + ret = pxa3xx_nand_do_cmd(info, NDSR_CS0_CMDD); + if (ret == 0) { + int timeout = 2; + uint32_t ndcr; - exec_cmd = prepare_command_pool(info, command, column, page_addr); - if (exec_cmd) { - init_completion(&info->cmd_complete); - pxa3xx_nand_start(info); + while (timeout--) { + if (nand_readl(info, NDSR) & NDSR_RDY) + break; + msleep(10); + } - ret = wait_for_completion_timeout(&info->cmd_complete, - CHIP_DELAY_TIMEOUT); - if (!ret) { - printk(KERN_ERR "Wait time out!!!\n"); - /* Stop State Machine for next command cycle */ - pxa3xx_nand_stop(info); + ndcr = nand_readl(info, NDCR); + nand_writel(info, NDCR, ndcr & ~NDCR_ND_RUN); } - info->state = STATE_IDLE; + break; + default: + printk(KERN_ERR "non-supported command.\n"); + break; } -} - -static void pxa3xx_nand_write_page_hwecc(struct mtd_info *mtd, - struct nand_chip *chip, const uint8_t *buf) -{ - chip->write_buf(mtd, buf, mtd->writesize); - chip->write_buf(mtd, chip->oob_poi, mtd->oobsize); -} -static int pxa3xx_nand_read_page_hwecc(struct mtd_info *mtd, - struct nand_chip *chip, uint8_t *buf, int page) -{ - struct pxa3xx_nand_info *info = mtd->priv; - - chip->read_buf(mtd, buf, mtd->writesize); - chip->read_buf(mtd, chip->oob_poi, mtd->oobsize); - - if (info->retcode == ERR_SBERR) { - switch (info->use_ecc) { - case 1: - mtd->ecc_stats.corrected++; - break; - case 0: - default: - break; - } - } else if (info->retcode == ERR_DBERR) { - /* - * for blank page (all 0xff), HW will calculate its ECC as - * 0, which is different from the ECC information within - * OOB, ignore such double bit errors - */ - if (is_buf_blank(buf, mtd->writesize)) - mtd->ecc_stats.failed++; + if (info->retcode == ERR_DBERR) { + printk(KERN_ERR "double bit error @ page %08x\n", page_addr); + info->retcode = ERR_NONE; } - - return 0; } static uint8_t pxa3xx_nand_read_byte(struct mtd_info *mtd) @@ -765,12 +769,73 @@ static int pxa3xx_nand_waitfunc(struct mtd_info *mtd, struct nand_chip *this) return 0; } +static void pxa3xx_nand_ecc_hwctl(struct mtd_info *mtd, int mode) +{ + return; +} + +static int pxa3xx_nand_ecc_calculate(struct mtd_info *mtd, + const uint8_t *dat, uint8_t *ecc_code) +{ + return 0; +} + +static int pxa3xx_nand_ecc_correct(struct mtd_info *mtd, + uint8_t *dat, uint8_t *read_ecc, uint8_t *calc_ecc) +{ + struct pxa3xx_nand_info *info = mtd->priv; + /* + * Any error include ERR_SEND_CMD, ERR_DBERR, ERR_BUSERR, we + * consider it as a ecc error which will tell the caller the + * read fail We have distinguish all the errors, but the + * nand_read_ecc only check this function return value + * + * Corrected (single-bit) errors must also be noted. + */ + if (info->retcode == ERR_SBERR) + return 1; + else if (info->retcode != ERR_NONE) + return -1; + + return 0; +} + +static int __readid(struct pxa3xx_nand_info *info, uint32_t *id) +{ + const struct pxa3xx_nand_cmdset *cmdset = info->cmdset; + uint32_t ndcr; + uint8_t id_buff[8]; + + if (prepare_other_cmd(info, cmdset->read_id)) { + printk(KERN_ERR "failed to prepare command\n"); + return -EINVAL; + } + + /* Send command */ + if (write_cmd(info)) + goto fail_timeout; + + /* Wait for CMDDM(command done successfully) */ + if (wait_for_event(info, NDSR_RDDREQ)) + goto fail_timeout; + + __raw_readsl(info->mmio_base + NDDB, id_buff, 2); + *id = id_buff[0] | (id_buff[1] << 8); + return 0; + +fail_timeout: + ndcr = nand_readl(info, NDCR); + nand_writel(info, NDCR, ndcr & ~NDCR_ND_RUN); + udelay(10); + return -ETIMEDOUT; +} + static int pxa3xx_nand_config_flash(struct pxa3xx_nand_info *info, const struct pxa3xx_nand_flash *f) { struct platform_device *pdev = info->pdev; struct pxa3xx_nand_platform_data *pdata = pdev->dev.platform_data; - uint32_t ndcr = 0x0; /* enable all interrupts */ + uint32_t ndcr = 0x00000FFF; /* disable all interrupts */ if (f->page_size != 2048 && f->page_size != 512) return -EINVAL; @@ -779,8 +844,9 @@ static int pxa3xx_nand_config_flash(struct pxa3xx_nand_info *info, return -EINVAL; /* calculate flash information */ - info->cmdset = &default_cmdset; + info->cmdset = f->cmdset; info->page_size = f->page_size; + info->oob_buff = info->data_buff + f->page_size; info->read_id_bytes = (f->page_size == 2048) ? 4 : 2; /* calculate addressing information */ @@ -810,18 +876,87 @@ static int pxa3xx_nand_config_flash(struct pxa3xx_nand_info *info, static int pxa3xx_nand_detect_config(struct pxa3xx_nand_info *info) { uint32_t ndcr = nand_readl(info, NDCR); + struct nand_flash_dev *type = NULL; + uint32_t id = -1, page_per_block, num_blocks; + int i; + + page_per_block = ndcr & NDCR_PG_PER_BLK ? 64 : 32; info->page_size = ndcr & NDCR_PAGE_SZ ? 2048 : 512; - /* set info fields needed to read id */ + /* set info fields needed to __readid */ info->read_id_bytes = (info->page_size == 2048) ? 4 : 2; info->reg_ndcr = ndcr; info->cmdset = &default_cmdset; + if (__readid(info, &id)) + return -ENODEV; + + /* Lookup the flash id */ + id = (id >> 8) & 0xff; /* device id is byte 2 */ + for (i = 0; nand_flash_ids[i].name != NULL; i++) { + if (id == nand_flash_ids[i].id) { + type = &nand_flash_ids[i]; + break; + } + } + + if (!type) + return -ENODEV; + + /* fill the missing flash information */ + i = __ffs(page_per_block * info->page_size); + num_blocks = type->chipsize << (20 - i); + + /* calculate addressing information */ + info->col_addr_cycles = (info->page_size == 2048) ? 2 : 1; + + if (num_blocks * page_per_block > 65536) + info->row_addr_cycles = 3; + else + info->row_addr_cycles = 2; + info->ndtr0cs0 = nand_readl(info, NDTR0CS0); info->ndtr1cs0 = nand_readl(info, NDTR1CS0); return 0; } +static int pxa3xx_nand_detect_flash(struct pxa3xx_nand_info *info, + const struct pxa3xx_nand_platform_data *pdata) +{ + const struct pxa3xx_nand_flash *f; + uint32_t id = -1; + int i; + + if (pdata->keep_config) + if (pxa3xx_nand_detect_config(info) == 0) + return 0; + + /* we use default timing to detect id */ + f = DEFAULT_FLASH_TYPE; + pxa3xx_nand_config_flash(info, f); + if (__readid(info, &id)) + goto fail_detect; + + for (i=0; inum_flash - 1; i++) { + /* we first choose the flash definition from platfrom */ + if (i < pdata->num_flash) + f = pdata->flash + i; + else + f = &builtin_flash_types[i - pdata->num_flash + 1]; + if (f->chip_id == id) { + dev_info(&info->pdev->dev, "detect chip id: 0x%x\n", id); + pxa3xx_nand_config_flash(info, f); + return 0; + } + } + + dev_warn(&info->pdev->dev, + "failed to detect configured nand flash; found %04x instead of\n", + id); +fail_detect: + return -ENODEV; +} + /* the maximum possible buffer size for large page with OOB data * is: 2048 + 64 = 2112 bytes, allocate a page here for both the * data buffer and the DMA descriptor @@ -863,144 +998,82 @@ static int pxa3xx_nand_init_buff(struct pxa3xx_nand_info *info) return 0; } -static int pxa3xx_nand_sensing(struct pxa3xx_nand_info *info) -{ - struct mtd_info *mtd = info->mtd; - struct nand_chip *chip = mtd->priv; +static struct nand_ecclayout hw_smallpage_ecclayout = { + .eccbytes = 6, + .eccpos = {8, 9, 10, 11, 12, 13 }, + .oobfree = { {2, 6} } +}; - /* use the common timing to make a try */ - pxa3xx_nand_config_flash(info, &builtin_flash_types[0]); - chip->cmdfunc(mtd, NAND_CMD_RESET, 0, 0); - if (info->is_ready) - return 1; - else - return 0; -} +static struct nand_ecclayout hw_largepage_ecclayout = { + .eccbytes = 24, + .eccpos = { + 40, 41, 42, 43, 44, 45, 46, 47, + 48, 49, 50, 51, 52, 53, 54, 55, + 56, 57, 58, 59, 60, 61, 62, 63}, + .oobfree = { {2, 38} } +}; -static int pxa3xx_nand_scan(struct mtd_info *mtd) +static void pxa3xx_nand_init_mtd(struct mtd_info *mtd, + struct pxa3xx_nand_info *info) { - struct pxa3xx_nand_info *info = mtd->priv; - struct platform_device *pdev = info->pdev; - struct pxa3xx_nand_platform_data *pdata = pdev->dev.platform_data; - struct nand_flash_dev pxa3xx_flash_ids[2] = { {NULL,}, {NULL,} }; - const struct pxa3xx_nand_flash *f = NULL; - struct nand_chip *chip = mtd->priv; - uint32_t id = -1; - uint64_t chipsize; - int i, ret, num; - - if (pdata->keep_config && !pxa3xx_nand_detect_config(info)) - goto KEEP_CONFIG; - - ret = pxa3xx_nand_sensing(info); - if (!ret) { - kfree(mtd); - info->mtd = NULL; - printk(KERN_INFO "There is no nand chip on cs 0!\n"); - - return -EINVAL; - } - - chip->cmdfunc(mtd, NAND_CMD_READID, 0, 0); - id = *((uint16_t *)(info->data_buff)); - if (id != 0) - printk(KERN_INFO "Detect a flash id %x\n", id); - else { - kfree(mtd); - info->mtd = NULL; - printk(KERN_WARNING "Read out ID 0, potential timing set wrong!!\n"); - - return -EINVAL; - } - - num = ARRAY_SIZE(builtin_flash_types) + pdata->num_flash - 1; - for (i = 0; i < num; i++) { - if (i < pdata->num_flash) - f = pdata->flash + i; - else - f = &builtin_flash_types[i - pdata->num_flash + 1]; - - /* find the chip in default list */ - if (f->chip_id == id) - break; - } - - if (i >= (ARRAY_SIZE(builtin_flash_types) + pdata->num_flash - 1)) { - kfree(mtd); - info->mtd = NULL; - printk(KERN_ERR "ERROR!! flash not defined!!!\n"); - - return -EINVAL; - } - - pxa3xx_nand_config_flash(info, f); - pxa3xx_flash_ids[0].name = f->name; - pxa3xx_flash_ids[0].id = (f->chip_id >> 8) & 0xffff; - pxa3xx_flash_ids[0].pagesize = f->page_size; - chipsize = (uint64_t)f->num_blocks * f->page_per_block * f->page_size; - pxa3xx_flash_ids[0].chipsize = chipsize >> 20; - pxa3xx_flash_ids[0].erasesize = f->page_size * f->page_per_block; - if (f->flash_width == 16) - pxa3xx_flash_ids[0].options = NAND_BUSWIDTH_16; -KEEP_CONFIG: - if (nand_scan_ident(mtd, 1, pxa3xx_flash_ids)) - return -ENODEV; - /* calculate addressing information */ - info->col_addr_cycles = (mtd->writesize >= 2048) ? 2 : 1; - info->oob_buff = info->data_buff + mtd->writesize; - if ((mtd->size >> chip->page_shift) > 65536) - info->row_addr_cycles = 3; + struct nand_chip *this = &info->nand_chip; + + this->options = (info->reg_ndcr & NDCR_DWIDTH_C) ? NAND_BUSWIDTH_16: 0; + + this->waitfunc = pxa3xx_nand_waitfunc; + this->select_chip = pxa3xx_nand_select_chip; + this->dev_ready = pxa3xx_nand_dev_ready; + this->cmdfunc = pxa3xx_nand_cmdfunc; + this->read_word = pxa3xx_nand_read_word; + this->read_byte = pxa3xx_nand_read_byte; + this->read_buf = pxa3xx_nand_read_buf; + this->write_buf = pxa3xx_nand_write_buf; + this->verify_buf = pxa3xx_nand_verify_buf; + + this->ecc.mode = NAND_ECC_HW; + this->ecc.hwctl = pxa3xx_nand_ecc_hwctl; + this->ecc.calculate = pxa3xx_nand_ecc_calculate; + this->ecc.correct = pxa3xx_nand_ecc_correct; + this->ecc.size = info->page_size; + + if (info->page_size == 2048) + this->ecc.layout = &hw_largepage_ecclayout; else - info->row_addr_cycles = 2; - mtd->name = mtd_names[0]; - chip->ecc.mode = NAND_ECC_HW; - chip->ecc.size = f->page_size; - - chip->options = (f->flash_width == 16) ? NAND_BUSWIDTH_16 : 0; - chip->options |= NAND_NO_AUTOINCR; - chip->options |= NAND_NO_READRDY; + this->ecc.layout = &hw_smallpage_ecclayout; - return nand_scan_tail(mtd); + this->chip_delay = 25; } -static -struct pxa3xx_nand_info *alloc_nand_resource(struct platform_device *pdev) +static int pxa3xx_nand_probe(struct platform_device *pdev) { + struct pxa3xx_nand_platform_data *pdata; struct pxa3xx_nand_info *info; - struct nand_chip *chip; + struct nand_chip *this; struct mtd_info *mtd; struct resource *r; - int ret, irq; + int ret = 0, irq; + + pdata = pdev->dev.platform_data; + + if (!pdata) { + dev_err(&pdev->dev, "no platform data defined\n"); + return -ENODEV; + } mtd = kzalloc(sizeof(struct mtd_info) + sizeof(struct pxa3xx_nand_info), GFP_KERNEL); if (!mtd) { dev_err(&pdev->dev, "failed to allocate memory\n"); - return NULL; + return -ENOMEM; } info = (struct pxa3xx_nand_info *)(&mtd[1]); - chip = (struct nand_chip *)(&mtd[1]); info->pdev = pdev; - info->mtd = mtd; + + this = &info->nand_chip; mtd->priv = info; mtd->owner = THIS_MODULE; - chip->ecc.read_page = pxa3xx_nand_read_page_hwecc; - chip->ecc.write_page = pxa3xx_nand_write_page_hwecc; - chip->controller = &info->controller; - chip->waitfunc = pxa3xx_nand_waitfunc; - chip->select_chip = pxa3xx_nand_select_chip; - chip->dev_ready = pxa3xx_nand_dev_ready; - chip->cmdfunc = pxa3xx_nand_cmdfunc; - chip->read_word = pxa3xx_nand_read_word; - chip->read_byte = pxa3xx_nand_read_byte; - chip->read_buf = pxa3xx_nand_read_buf; - chip->write_buf = pxa3xx_nand_write_buf; - chip->verify_buf = pxa3xx_nand_verify_buf; - - spin_lock_init(&chip->controller->lock); - init_waitqueue_head(&chip->controller->wq); info->clk = clk_get(&pdev->dev, NULL); if (IS_ERR(info->clk)) { dev_err(&pdev->dev, "failed to get nand clock\n"); @@ -1068,12 +1141,43 @@ struct pxa3xx_nand_info *alloc_nand_resource(struct platform_device *pdev) goto fail_free_buf; } - platform_set_drvdata(pdev, info); + ret = pxa3xx_nand_detect_flash(info, pdata); + if (ret) { + dev_err(&pdev->dev, "failed to detect flash\n"); + ret = -ENODEV; + goto fail_free_irq; + } - return info; + pxa3xx_nand_init_mtd(mtd, info); -fail_free_buf: + platform_set_drvdata(pdev, mtd); + + if (nand_scan(mtd, 1)) { + dev_err(&pdev->dev, "failed to scan nand\n"); + ret = -ENXIO; + goto fail_free_irq; + } + +#ifdef CONFIG_MTD_PARTITIONS + if (mtd_has_cmdlinepart()) { + static const char *probes[] = { "cmdlinepart", NULL }; + struct mtd_partition *parts; + int nr_parts; + + nr_parts = parse_mtd_partitions(mtd, probes, &parts, 0); + + if (nr_parts) + return add_mtd_partitions(mtd, parts, nr_parts); + } + + return add_mtd_partitions(mtd, pdata->parts, pdata->nr_parts); +#else + return 0; +#endif + +fail_free_irq: free_irq(irq, info); +fail_free_buf: if (use_dma) { pxa_free_dma(info->data_dma_ch); dma_free_coherent(&pdev->dev, info->data_buff_size, @@ -1089,18 +1193,22 @@ struct pxa3xx_nand_info *alloc_nand_resource(struct platform_device *pdev) clk_put(info->clk); fail_free_mtd: kfree(mtd); - return NULL; + return ret; } static int pxa3xx_nand_remove(struct platform_device *pdev) { - struct pxa3xx_nand_info *info = platform_get_drvdata(pdev); - struct mtd_info *mtd = info->mtd; + struct mtd_info *mtd = platform_get_drvdata(pdev); + struct pxa3xx_nand_info *info = mtd->priv; struct resource *r; int irq; platform_set_drvdata(pdev, NULL); + del_mtd_device(mtd); +#ifdef CONFIG_MTD_PARTITIONS + del_mtd_partitions(mtd); +#endif irq = platform_get_irq(pdev, 0); if (irq >= 0) free_irq(irq, info); @@ -1118,62 +1226,17 @@ static int pxa3xx_nand_remove(struct platform_device *pdev) clk_disable(info->clk); clk_put(info->clk); - if (mtd) { - del_mtd_device(mtd); -#ifdef CONFIG_MTD_PARTITIONS - del_mtd_partitions(mtd); -#endif - kfree(mtd); - } - return 0; -} - -static int pxa3xx_nand_probe(struct platform_device *pdev) -{ - struct pxa3xx_nand_platform_data *pdata; - struct pxa3xx_nand_info *info; - - pdata = pdev->dev.platform_data; - if (!pdata) { - dev_err(&pdev->dev, "no platform data defined\n"); - return -ENODEV; - } - - info = alloc_nand_resource(pdev); - if (info == NULL) - return -ENOMEM; - - if (pxa3xx_nand_scan(info->mtd)) { - dev_err(&pdev->dev, "failed to scan nand\n"); - pxa3xx_nand_remove(pdev); - return -ENODEV; - } - -#ifdef CONFIG_MTD_PARTITIONS - if (mtd_has_cmdlinepart()) { - const char *probes[] = { "cmdlinepart", NULL }; - struct mtd_partition *parts; - int nr_parts; - - nr_parts = parse_mtd_partitions(info->mtd, probes, &parts, 0); - - if (nr_parts) - return add_mtd_partitions(info->mtd, parts, nr_parts); - } - - return add_mtd_partitions(info->mtd, pdata->parts, pdata->nr_parts); -#else + kfree(mtd); return 0; -#endif } #ifdef CONFIG_PM static int pxa3xx_nand_suspend(struct platform_device *pdev, pm_message_t state) { - struct pxa3xx_nand_info *info = platform_get_drvdata(pdev); - struct mtd_info *mtd = info->mtd; + struct mtd_info *mtd = (struct mtd_info *)platform_get_drvdata(pdev); + struct pxa3xx_nand_info *info = mtd->priv; - if (info->state) { + if (info->state != STATE_READY) { dev_err(&pdev->dev, "driver busy, state = %d\n", info->state); return -EAGAIN; } @@ -1183,8 +1246,8 @@ static int pxa3xx_nand_suspend(struct platform_device *pdev, pm_message_t state) static int pxa3xx_nand_resume(struct platform_device *pdev) { - struct pxa3xx_nand_info *info = platform_get_drvdata(pdev); - struct mtd_info *mtd = info->mtd; + struct mtd_info *mtd = (struct mtd_info *)platform_get_drvdata(pdev); + struct pxa3xx_nand_info *info = mtd->priv; nand_writel(info, NDTR0CS0, info->ndtr0cs0); nand_writel(info, NDTR1CS0, info->ndtr1cs0); diff --git a/trunk/drivers/mtd/onenand/omap2.c b/trunk/drivers/mtd/onenand/omap2.c index f591f615d3f6..14a49abe057e 100644 --- a/trunk/drivers/mtd/onenand/omap2.c +++ b/trunk/drivers/mtd/onenand/omap2.c @@ -629,7 +629,6 @@ static int __devinit omap2_onenand_probe(struct platform_device *pdev) { struct omap_onenand_platform_data *pdata; struct omap2_onenand *c; - struct onenand_chip *this; int r; pdata = pdev->dev.platform_data; @@ -727,8 +726,9 @@ static int __devinit omap2_onenand_probe(struct platform_device *pdev) c->mtd.dev.parent = &pdev->dev; - this = &c->onenand; if (c->dma_channel >= 0) { + struct onenand_chip *this = &c->onenand; + this->wait = omap2_onenand_wait; if (cpu_is_omap34xx()) { this->read_bufferram = omap3_onenand_read_bufferram; @@ -749,9 +749,6 @@ static int __devinit omap2_onenand_probe(struct platform_device *pdev) c->onenand.disable = omap2_onenand_disable; } - if (pdata->skip_initial_unlocking) - this->options |= ONENAND_SKIP_INITIAL_UNLOCKING; - if ((r = onenand_scan(&c->mtd, 1)) < 0) goto err_release_regulator; diff --git a/trunk/drivers/mtd/onenand/onenand_base.c b/trunk/drivers/mtd/onenand/onenand_base.c index 56a8b2005bda..bac41caa8df7 100644 --- a/trunk/drivers/mtd/onenand/onenand_base.c +++ b/trunk/drivers/mtd/onenand/onenand_base.c @@ -1132,8 +1132,6 @@ static int onenand_mlc_read_ops_nolock(struct mtd_info *mtd, loff_t from, onenand_update_bufferram(mtd, from, !ret); if (ret == -EBADMSG) ret = 0; - if (ret) - break; } this->read_bufferram(mtd, ONENAND_DATARAM, buf, column, thislen); @@ -1648,10 +1646,11 @@ static int onenand_verify(struct mtd_info *mtd, const u_char *buf, loff_t addr, int ret = 0; int thislen, column; - column = addr & (this->writesize - 1); - while (len != 0) { - thislen = min_t(int, this->writesize - column, len); + thislen = min_t(int, this->writesize, len); + column = addr & (this->writesize - 1); + if (column + thislen > this->writesize) + thislen = this->writesize - column; this->command(mtd, ONENAND_CMD_READ, addr, this->writesize); @@ -1665,13 +1664,12 @@ static int onenand_verify(struct mtd_info *mtd, const u_char *buf, loff_t addr, this->read_bufferram(mtd, ONENAND_DATARAM, this->verify_buf, 0, mtd->writesize); - if (memcmp(buf, this->verify_buf + column, thislen)) + if (memcmp(buf, this->verify_buf, thislen)) return -EBADMSG; len -= thislen; buf += thislen; addr += thislen; - column = 0; } return 0; @@ -4085,8 +4083,7 @@ int onenand_scan(struct mtd_info *mtd, int maxchips) mtd->writebufsize = mtd->writesize; /* Unlock whole block */ - if (!(this->options & ONENAND_SKIP_INITIAL_UNLOCKING)) - this->unlock_all(mtd); + this->unlock_all(mtd); ret = this->scan_bbt(mtd); if ((!FLEXONENAND(this)) || ret) diff --git a/trunk/drivers/mtd/sm_ftl.c b/trunk/drivers/mtd/sm_ftl.c index 2b0daae4018d..ac0d6a8613b5 100644 --- a/trunk/drivers/mtd/sm_ftl.c +++ b/trunk/drivers/mtd/sm_ftl.c @@ -64,16 +64,12 @@ struct attribute_group *sm_create_sysfs_attributes(struct sm_ftl *ftl) SM_SMALL_PAGE - SM_CIS_VENDOR_OFFSET); char *vendor = kmalloc(vendor_len, GFP_KERNEL); - if (!vendor) - goto error1; memcpy(vendor, ftl->cis_buffer + SM_CIS_VENDOR_OFFSET, vendor_len); vendor[vendor_len] = 0; /* Initialize sysfs attributes */ vendor_attribute = kzalloc(sizeof(struct sm_sysfs_attribute), GFP_KERNEL); - if (!vendor_attribute) - goto error2; sysfs_attr_init(&vendor_attribute->dev_attr.attr); @@ -87,24 +83,12 @@ struct attribute_group *sm_create_sysfs_attributes(struct sm_ftl *ftl) /* Create array of pointers to the attributes */ attributes = kzalloc(sizeof(struct attribute *) * (NUM_ATTRIBUTES + 1), GFP_KERNEL); - if (!attributes) - goto error3; attributes[0] = &vendor_attribute->dev_attr.attr; /* Finally create the attribute group */ attr_group = kzalloc(sizeof(struct attribute_group), GFP_KERNEL); - if (!attr_group) - goto error4; attr_group->attrs = attributes; return attr_group; -error4: - kfree(attributes); -error3: - kfree(vendor_attribute); -error2: - kfree(vendor); -error1: - return NULL; } void sm_delete_sysfs_attributes(struct sm_ftl *ftl) @@ -1194,8 +1178,6 @@ static void sm_add_mtd(struct mtd_blktrans_ops *tr, struct mtd_info *mtd) } ftl->disk_attributes = sm_create_sysfs_attributes(ftl); - if (!ftl->disk_attributes) - goto error6; trans->disk_attributes = ftl->disk_attributes; sm_printk("Found %d MiB xD/SmartMedia FTL on mtd%d", diff --git a/trunk/drivers/mtd/tests/mtd_speedtest.c b/trunk/drivers/mtd/tests/mtd_speedtest.c index 627d4e2466a3..161feeb7b8b9 100644 --- a/trunk/drivers/mtd/tests/mtd_speedtest.c +++ b/trunk/drivers/mtd/tests/mtd_speedtest.c @@ -16,7 +16,7 @@ * * Test read and write speed of a MTD device. * - * Author: Adrian Hunter + * Author: Adrian Hunter */ #include @@ -33,11 +33,6 @@ static int dev; module_param(dev, int, S_IRUGO); MODULE_PARM_DESC(dev, "MTD device number to use"); -static int count; -module_param(count, int, S_IRUGO); -MODULE_PARM_DESC(count, "Maximum number of eraseblocks to use " - "(0 means use all)"); - static struct mtd_info *mtd; static unsigned char *iobuf; static unsigned char *bbt; @@ -94,33 +89,6 @@ static int erase_eraseblock(int ebnum) return 0; } -static int multiblock_erase(int ebnum, int blocks) -{ - int err; - struct erase_info ei; - loff_t addr = ebnum * mtd->erasesize; - - memset(&ei, 0, sizeof(struct erase_info)); - ei.mtd = mtd; - ei.addr = addr; - ei.len = mtd->erasesize * blocks; - - err = mtd->erase(mtd, &ei); - if (err) { - printk(PRINT_PREF "error %d while erasing EB %d, blocks %d\n", - err, ebnum, blocks); - return err; - } - - if (ei.state == MTD_ERASE_FAILED) { - printk(PRINT_PREF "some erase error occurred at EB %d," - "blocks %d\n", ebnum, blocks); - return -EIO; - } - - return 0; -} - static int erase_whole_device(void) { int err; @@ -314,16 +282,13 @@ static inline void stop_timing(void) static long calc_speed(void) { - uint64_t k; - long ms; + long ms, k, speed; ms = (finish.tv_sec - start.tv_sec) * 1000 + (finish.tv_usec - start.tv_usec) / 1000; - if (ms == 0) - return 0; - k = goodebcnt * (mtd->erasesize / 1024) * 1000; - do_div(k, ms); - return k; + k = goodebcnt * mtd->erasesize / 1024; + speed = (k * 1000) / ms; + return speed; } static int scan_for_bad_eraseblocks(void) @@ -355,16 +320,13 @@ static int scan_for_bad_eraseblocks(void) static int __init mtd_speedtest_init(void) { - int err, i, blocks, j, k; + int err, i; long speed; uint64_t tmp; printk(KERN_INFO "\n"); printk(KERN_INFO "=================================================\n"); - if (count) - printk(PRINT_PREF "MTD device: %d count: %d\n", dev, count); - else - printk(PRINT_PREF "MTD device: %d\n", dev); + printk(PRINT_PREF "MTD device: %d\n", dev); mtd = get_mtd_device(NULL, dev); if (IS_ERR(mtd)) { @@ -391,9 +353,6 @@ static int __init mtd_speedtest_init(void) (unsigned long long)mtd->size, mtd->erasesize, pgsize, ebcnt, pgcnt, mtd->oobsize); - if (count > 0 && count < ebcnt) - ebcnt = count; - err = -ENOMEM; iobuf = kmalloc(mtd->erasesize, GFP_KERNEL); if (!iobuf) { @@ -525,31 +484,6 @@ static int __init mtd_speedtest_init(void) speed = calc_speed(); printk(PRINT_PREF "erase speed is %ld KiB/s\n", speed); - /* Multi-block erase all eraseblocks */ - for (k = 1; k < 7; k++) { - blocks = 1 << k; - printk(PRINT_PREF "Testing %dx multi-block erase speed\n", - blocks); - start_timing(); - for (i = 0; i < ebcnt; ) { - for (j = 0; j < blocks && (i + j) < ebcnt; j++) - if (bbt[i + j]) - break; - if (j < 1) { - i++; - continue; - } - err = multiblock_erase(i, j); - if (err) - goto out; - cond_resched(); - i += j; - } - stop_timing(); - speed = calc_speed(); - printk(PRINT_PREF "%dx multi-block erase speed is %ld KiB/s\n", - blocks, speed); - } printk(PRINT_PREF "finished\n"); out: kfree(iobuf); diff --git a/trunk/drivers/mtd/tests/mtd_subpagetest.c b/trunk/drivers/mtd/tests/mtd_subpagetest.c index 334eae53a3db..11204e8aab5f 100644 --- a/trunk/drivers/mtd/tests/mtd_subpagetest.c +++ b/trunk/drivers/mtd/tests/mtd_subpagetest.c @@ -394,11 +394,6 @@ static int __init mtd_subpagetest_init(void) } subpgsize = mtd->writesize >> mtd->subpage_sft; - tmp = mtd->size; - do_div(tmp, mtd->erasesize); - ebcnt = tmp; - pgcnt = mtd->erasesize / mtd->writesize; - printk(PRINT_PREF "MTD device size %llu, eraseblock size %u, " "page size %u, subpage size %u, count of eraseblocks %u, " "pages per eraseblock %u, OOB size %u\n", @@ -418,6 +413,11 @@ static int __init mtd_subpagetest_init(void) goto out; } + tmp = mtd->size; + do_div(tmp, mtd->erasesize); + ebcnt = tmp; + pgcnt = mtd->erasesize / mtd->writesize; + err = scan_for_bad_eraseblocks(); if (err) goto out; diff --git a/trunk/drivers/net/bfin_mac.c b/trunk/drivers/net/bfin_mac.c index 68d45ba2d9b9..22abfb39d813 100644 --- a/trunk/drivers/net/bfin_mac.c +++ b/trunk/drivers/net/bfin_mac.c @@ -1237,17 +1237,8 @@ static int bfin_mac_enable(struct phy_device *phydev) if (phydev->interface == PHY_INTERFACE_MODE_RMII) { opmode |= RMII; /* For Now only 100MBit are supported */ -#if defined(CONFIG_BF537) || defined(CONFIG_BF536) - if (__SILICON_REVISION__ < 3) { - /* - * This isn't publicly documented (fun times!), but in - * silicon <=0.2, the RX and TX pins are clocked together. - * So in order to recv, we must enable the transmit side - * as well. This will cause a spurious TX interrupt too, - * but we can easily consume that. - */ - opmode |= TE; - } +#if (defined(CONFIG_BF537) || defined(CONFIG_BF536)) && CONFIG_BF_REV_0_2 + opmode |= TE; #endif } diff --git a/trunk/drivers/net/bnx2.c b/trunk/drivers/net/bnx2.c index 8e6d618b5305..d1865cc97313 100644 --- a/trunk/drivers/net/bnx2.c +++ b/trunk/drivers/net/bnx2.c @@ -8317,7 +8317,7 @@ static const struct net_device_ops bnx2_netdev_ops = { #endif }; -static inline void vlan_features_add(struct net_device *dev, u32 flags) +static void inline vlan_features_add(struct net_device *dev, u32 flags) { dev->vlan_features |= flags; } diff --git a/trunk/drivers/net/can/c_can/c_can.c b/trunk/drivers/net/can/c_can/c_can.c index 31552959aed7..110eda01843c 100644 --- a/trunk/drivers/net/can/c_can/c_can.c +++ b/trunk/drivers/net/can/c_can/c_can.c @@ -588,9 +588,14 @@ static void c_can_chip_config(struct net_device *dev) { struct c_can_priv *priv = netdev_priv(dev); - /* enable automatic retransmission */ - priv->write_reg(priv, &priv->regs->control, - CONTROL_ENABLE_AR); + if (priv->can.ctrlmode & CAN_CTRLMODE_ONE_SHOT) + /* disable automatic retransmission */ + priv->write_reg(priv, &priv->regs->control, + CONTROL_DISABLE_AR); + else + /* enable automatic retransmission */ + priv->write_reg(priv, &priv->regs->control, + CONTROL_ENABLE_AR); if (priv->can.ctrlmode & (CAN_CTRLMODE_LISTENONLY & CAN_CTRLMODE_LOOPBACK)) { @@ -699,6 +704,7 @@ static void c_can_do_tx(struct net_device *dev) for (/* nix */; (priv->tx_next - priv->tx_echo) > 0; priv->tx_echo++) { msg_obj_no = get_tx_echo_msg_obj(priv); + c_can_inval_msg_object(dev, 0, msg_obj_no); val = c_can_read_reg32(priv, &priv->regs->txrqst1); if (!(val & (1 << msg_obj_no))) { can_get_echo_skb(dev, @@ -707,7 +713,6 @@ static void c_can_do_tx(struct net_device *dev) &priv->regs->ifregs[0].msg_cntrl) & IF_MCONT_DLC_MASK; stats->tx_packets++; - c_can_inval_msg_object(dev, 0, msg_obj_no); } } @@ -1107,7 +1112,8 @@ struct net_device *alloc_c_can_dev(void) priv->can.bittiming_const = &c_can_bittiming_const; priv->can.do_set_mode = c_can_set_mode; priv->can.do_get_berr_counter = c_can_get_berr_counter; - priv->can.ctrlmode_supported = CAN_CTRLMODE_LOOPBACK | + priv->can.ctrlmode_supported = CAN_CTRLMODE_ONE_SHOT | + CAN_CTRLMODE_LOOPBACK | CAN_CTRLMODE_LISTENONLY | CAN_CTRLMODE_BERR_REPORTING; diff --git a/trunk/drivers/net/can/c_can/c_can_platform.c b/trunk/drivers/net/can/c_can/c_can_platform.c index cc90824f2c9c..e629b961ae2d 100644 --- a/trunk/drivers/net/can/c_can/c_can_platform.c +++ b/trunk/drivers/net/can/c_can/c_can_platform.c @@ -73,8 +73,7 @@ static int __devinit c_can_plat_probe(struct platform_device *pdev) void __iomem *addr; struct net_device *dev; struct c_can_priv *priv; - struct resource *mem; - int irq; + struct resource *mem, *irq; #ifdef CONFIG_HAVE_CLK struct clk *clk; @@ -89,8 +88,8 @@ static int __devinit c_can_plat_probe(struct platform_device *pdev) /* get the platform data */ mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); - irq = platform_get_irq(pdev, 0); - if (!mem || irq <= 0) { + irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0); + if (!mem || (irq <= 0)) { ret = -ENODEV; goto exit_free_clk; } @@ -118,7 +117,7 @@ static int __devinit c_can_plat_probe(struct platform_device *pdev) priv = netdev_priv(dev); - dev->irq = irq; + dev->irq = irq->start; priv->regs = addr; #ifdef CONFIG_HAVE_CLK priv->can.clock.freq = clk_get_rate(clk); diff --git a/trunk/drivers/net/cxgb3/cxgb3_main.c b/trunk/drivers/net/cxgb3/cxgb3_main.c index 910893143295..4d538a4e9d55 100644 --- a/trunk/drivers/net/cxgb3/cxgb3_main.c +++ b/trunk/drivers/net/cxgb3/cxgb3_main.c @@ -1983,20 +1983,14 @@ static int set_coalesce(struct net_device *dev, struct ethtool_coalesce *c) { struct port_info *pi = netdev_priv(dev); struct adapter *adapter = pi->adapter; - struct qset_params *qsp; - struct sge_qset *qs; - int i; + struct qset_params *qsp = &adapter->params.sge.qset[0]; + struct sge_qset *qs = &adapter->sge.qs[0]; if (c->rx_coalesce_usecs * 10 > M_NEWTIMER) return -EINVAL; - for (i = 0; i < pi->nqsets; i++) { - qsp = &adapter->params.sge.qset[i]; - qs = &adapter->sge.qs[i]; - qsp->coalesce_usecs = c->rx_coalesce_usecs; - t3_update_qset_coalesce(qs, qsp); - } - + qsp->coalesce_usecs = c->rx_coalesce_usecs; + t3_update_qset_coalesce(qs, qsp); return 0; } diff --git a/trunk/drivers/net/dm9000.c b/trunk/drivers/net/dm9000.c index b7af5bab9937..317708113601 100644 --- a/trunk/drivers/net/dm9000.c +++ b/trunk/drivers/net/dm9000.c @@ -621,9 +621,9 @@ static int dm9000_set_wol(struct net_device *dev, struct ethtool_wolinfo *w) /* change in wol state, update IRQ state */ if (!dm->wake_state) - irq_set_irq_wake(dm->irq_wake, 1); + set_irq_wake(dm->irq_wake, 1); else if (dm->wake_state & !opts) - irq_set_irq_wake(dm->irq_wake, 0); + set_irq_wake(dm->irq_wake, 0); } dm->wake_state = opts; @@ -1424,13 +1424,13 @@ dm9000_probe(struct platform_device *pdev) } else { /* test to see if irq is really wakeup capable */ - ret = irq_set_irq_wake(db->irq_wake, 1); + ret = set_irq_wake(db->irq_wake, 1); if (ret) { dev_err(db->dev, "irq %d cannot set wakeup (%d)\n", db->irq_wake, ret); ret = 0; } else { - irq_set_irq_wake(db->irq_wake, 0); + set_irq_wake(db->irq_wake, 0); db->wake_supported = 1; } } diff --git a/trunk/drivers/net/jme.c b/trunk/drivers/net/jme.c index 994c80939c7a..f690474f4409 100644 --- a/trunk/drivers/net/jme.c +++ b/trunk/drivers/net/jme.c @@ -273,7 +273,7 @@ jme_clear_pm(struct jme_adapter *jme) { jwrite32(jme, JME_PMCS, 0xFFFF0000 | jme->reg_pmcs); pci_set_power_state(jme->pdev, PCI_D0); - device_set_wakeup_enable(&jme->pdev->dev, false); + pci_enable_wake(jme->pdev, PCI_D0, false); } static int @@ -2538,8 +2538,6 @@ jme_set_wol(struct net_device *netdev, jwrite32(jme, JME_PMCS, jme->reg_pmcs); - device_set_wakeup_enable(&jme->pdev->dev, jme->reg_pmcs); - return 0; } @@ -3174,9 +3172,9 @@ jme_shutdown(struct pci_dev *pdev) } #ifdef CONFIG_PM -static int jme_suspend(struct device *dev) +static int +jme_suspend(struct pci_dev *pdev, pm_message_t state) { - struct pci_dev *pdev = to_pci_dev(dev); struct net_device *netdev = pci_get_drvdata(pdev); struct jme_adapter *jme = netdev_priv(netdev); @@ -3208,18 +3206,22 @@ static int jme_suspend(struct device *dev) tasklet_hi_enable(&jme->rxclean_task); tasklet_hi_enable(&jme->rxempty_task); + pci_save_state(pdev); jme_powersave_phy(jme); + pci_enable_wake(jme->pdev, PCI_D3hot, true); + pci_set_power_state(pdev, PCI_D3hot); return 0; } -static int jme_resume(struct device *dev) +static int +jme_resume(struct pci_dev *pdev) { - struct pci_dev *pdev = to_pci_dev(dev); struct net_device *netdev = pci_get_drvdata(pdev); struct jme_adapter *jme = netdev_priv(netdev); - jwrite32(jme, JME_PMCS, 0xFFFF0000 | jme->reg_pmcs); + jme_clear_pm(jme); + pci_restore_state(pdev); jme_phy_on(jme); if (test_bit(JME_FLAG_SSET, &jme->flags)) @@ -3236,13 +3238,6 @@ static int jme_resume(struct device *dev) return 0; } - -static SIMPLE_DEV_PM_OPS(jme_pm_ops, jme_suspend, jme_resume); -#define JME_PM_OPS (&jme_pm_ops) - -#else - -#define JME_PM_OPS NULL #endif static DEFINE_PCI_DEVICE_TABLE(jme_pci_tbl) = { @@ -3256,8 +3251,11 @@ static struct pci_driver jme_driver = { .id_table = jme_pci_tbl, .probe = jme_init_one, .remove = __devexit_p(jme_remove_one), +#ifdef CONFIG_PM + .suspend = jme_suspend, + .resume = jme_resume, +#endif /* CONFIG_PM */ .shutdown = jme_shutdown, - .driver.pm = JME_PM_OPS, }; static int __init diff --git a/trunk/drivers/net/ksz884x.c b/trunk/drivers/net/ksz884x.c index 7f7d5708a658..540a8dcbcc46 100644 --- a/trunk/drivers/net/ksz884x.c +++ b/trunk/drivers/net/ksz884x.c @@ -4898,7 +4898,7 @@ static netdev_tx_t netdev_tx(struct sk_buff *skb, struct net_device *dev) goto unlock; } skb_copy_and_csum_dev(org_skb, skb->data); - org_skb->ip_summed = CHECKSUM_NONE; + org_skb->ip_summed = 0; skb->len = org_skb->len; copy_old_skb(org_skb, skb); } diff --git a/trunk/drivers/net/mlx4/en_netdev.c b/trunk/drivers/net/mlx4/en_netdev.c index 4f158baa0246..5762ebde4455 100644 --- a/trunk/drivers/net/mlx4/en_netdev.c +++ b/trunk/drivers/net/mlx4/en_netdev.c @@ -742,9 +742,6 @@ int mlx4_en_start_port(struct net_device *dev) 0, MLX4_PROT_ETH)) mlx4_warn(mdev, "Failed Attaching Broadcast\n"); - /* Must redo promiscuous mode setup. */ - priv->flags &= ~(MLX4_EN_FLAG_PROMISC | MLX4_EN_FLAG_MC_PROMISC); - /* Schedule multicast task to populate multicast list */ queue_work(mdev->workqueue, &priv->mcast_task); diff --git a/trunk/drivers/net/myri10ge/myri10ge.c b/trunk/drivers/net/myri10ge/myri10ge.c index 673dc600c891..1f4e8680a96a 100644 --- a/trunk/drivers/net/myri10ge/myri10ge.c +++ b/trunk/drivers/net/myri10ge/myri10ge.c @@ -1312,26 +1312,17 @@ myri10ge_unmap_rx_page(struct pci_dev *pdev, * page into an skb */ static inline int -myri10ge_rx_done(struct myri10ge_slice_state *ss, int len, __wsum csum, - int lro_enabled) +myri10ge_rx_done(struct myri10ge_slice_state *ss, struct myri10ge_rx_buf *rx, + int bytes, int len, __wsum csum) { struct myri10ge_priv *mgp = ss->mgp; struct sk_buff *skb; struct skb_frag_struct rx_frags[MYRI10GE_MAX_FRAGS_PER_FRAME]; - struct myri10ge_rx_buf *rx; - int i, idx, hlen, remainder, bytes; + int i, idx, hlen, remainder; struct pci_dev *pdev = mgp->pdev; struct net_device *dev = mgp->dev; u8 *va; - if (len <= mgp->small_bytes) { - rx = &ss->rx_small; - bytes = mgp->small_bytes; - } else { - rx = &ss->rx_big; - bytes = mgp->big_bytes; - } - len += MXGEFW_PAD; idx = rx->cnt & rx->mask; va = page_address(rx->info[idx].page) + rx->info[idx].page_offset; @@ -1350,7 +1341,7 @@ myri10ge_rx_done(struct myri10ge_slice_state *ss, int len, __wsum csum, remainder -= MYRI10GE_ALLOC_SIZE; } - if (lro_enabled) { + if (dev->features & NETIF_F_LRO) { rx_frags[0].page_offset += MXGEFW_PAD; rx_frags[0].size -= MXGEFW_PAD; len -= MXGEFW_PAD; @@ -1472,7 +1463,7 @@ myri10ge_clean_rx_done(struct myri10ge_slice_state *ss, int budget) { struct myri10ge_rx_done *rx_done = &ss->rx_done; struct myri10ge_priv *mgp = ss->mgp; - + struct net_device *netdev = mgp->dev; unsigned long rx_bytes = 0; unsigned long rx_packets = 0; unsigned long rx_ok; @@ -1483,18 +1474,18 @@ myri10ge_clean_rx_done(struct myri10ge_slice_state *ss, int budget) u16 length; __wsum checksum; - /* - * Prevent compiler from generating more than one ->features memory - * access to avoid theoretical race condition with functions that - * change NETIF_F_LRO flag at runtime. - */ - bool lro_enabled = ACCESS_ONCE(mgp->dev->features) & NETIF_F_LRO; - while (rx_done->entry[idx].length != 0 && work_done < budget) { length = ntohs(rx_done->entry[idx].length); rx_done->entry[idx].length = 0; checksum = csum_unfold(rx_done->entry[idx].checksum); - rx_ok = myri10ge_rx_done(ss, length, checksum, lro_enabled); + if (length <= mgp->small_bytes) + rx_ok = myri10ge_rx_done(ss, &ss->rx_small, + mgp->small_bytes, + length, checksum); + else + rx_ok = myri10ge_rx_done(ss, &ss->rx_big, + mgp->big_bytes, + length, checksum); rx_packets += rx_ok; rx_bytes += rx_ok * (unsigned long)length; cnt++; @@ -1506,7 +1497,7 @@ myri10ge_clean_rx_done(struct myri10ge_slice_state *ss, int budget) ss->stats.rx_packets += rx_packets; ss->stats.rx_bytes += rx_bytes; - if (lro_enabled) + if (netdev->features & NETIF_F_LRO) lro_flush_all(&rx_done->lro_mgr); /* restock receive rings if needed */ diff --git a/trunk/drivers/net/netxen/netxen_nic_ethtool.c b/trunk/drivers/net/netxen/netxen_nic_ethtool.c index 3bdcc803ec68..653d308e0f5d 100644 --- a/trunk/drivers/net/netxen/netxen_nic_ethtool.c +++ b/trunk/drivers/net/netxen/netxen_nic_ethtool.c @@ -871,7 +871,7 @@ static int netxen_nic_set_flags(struct net_device *netdev, u32 data) struct netxen_adapter *adapter = netdev_priv(netdev); int hw_lro; - if (ethtool_invalid_flags(netdev, data, ETH_FLAG_LRO)) + if (data & ~ETH_FLAG_LRO) return -EINVAL; if (!(adapter->capabilities & NX_FW_CAPABILITY_HW_LRO)) diff --git a/trunk/drivers/net/qlcnic/qlcnic_ethtool.c b/trunk/drivers/net/qlcnic/qlcnic_ethtool.c index 45b2755d6cba..4c14510e2a87 100644 --- a/trunk/drivers/net/qlcnic/qlcnic_ethtool.c +++ b/trunk/drivers/net/qlcnic/qlcnic_ethtool.c @@ -1003,7 +1003,7 @@ static int qlcnic_set_flags(struct net_device *netdev, u32 data) struct qlcnic_adapter *adapter = netdev_priv(netdev); int hw_lro; - if (ethtool_invalid_flags(netdev, data, ETH_FLAG_LRO)) + if (data & ~ETH_FLAG_LRO) return -EINVAL; if (!(adapter->capabilities & QLCNIC_FW_CAPABILITY_HW_LRO)) diff --git a/trunk/drivers/net/s2io.c b/trunk/drivers/net/s2io.c index 356e74d20b80..2ad6364103ea 100644 --- a/trunk/drivers/net/s2io.c +++ b/trunk/drivers/net/s2io.c @@ -6726,7 +6726,7 @@ static int s2io_ethtool_set_flags(struct net_device *dev, u32 data) int rc = 0; int changed = 0; - if (ethtool_invalid_flags(dev, data, ETH_FLAG_LRO)) + if (data & ~ETH_FLAG_LRO) return -EINVAL; if (data & ETH_FLAG_LRO) { diff --git a/trunk/drivers/net/tg3.c b/trunk/drivers/net/tg3.c index 73c942d85f07..ebec88882c3b 100644 --- a/trunk/drivers/net/tg3.c +++ b/trunk/drivers/net/tg3.c @@ -48,9 +48,9 @@ #include #include -#include +#include #include -#include +#include #ifdef CONFIG_SPARC #include @@ -13118,7 +13118,7 @@ static void __devinit tg3_read_fw_ver(struct tg3 *tp) static struct pci_dev * __devinit tg3_find_peer(struct tg3 *); -static inline void vlan_features_add(struct net_device *dev, unsigned long flags) +static void inline vlan_features_add(struct net_device *dev, unsigned long flags) { dev->vlan_features |= flags; } diff --git a/trunk/drivers/net/vmxnet3/vmxnet3_ethtool.c b/trunk/drivers/net/vmxnet3/vmxnet3_ethtool.c index 51f2ef142a5b..81254be85b92 100644 --- a/trunk/drivers/net/vmxnet3/vmxnet3_ethtool.c +++ b/trunk/drivers/net/vmxnet3/vmxnet3_ethtool.c @@ -304,8 +304,8 @@ vmxnet3_set_flags(struct net_device *netdev, u32 data) u8 lro_present = (netdev->features & NETIF_F_LRO) == 0 ? 0 : 1; unsigned long flags; - if (ethtool_invalid_flags(netdev, data, ETH_FLAG_LRO)) - return -EINVAL; + if (data & ~ETH_FLAG_LRO) + return -EOPNOTSUPP; if (lro_requested ^ lro_present) { /* toggle the LRO feature*/ diff --git a/trunk/drivers/net/vxge/vxge-ethtool.c b/trunk/drivers/net/vxge/vxge-ethtool.c index c5eb034107fd..1dd3a21b3a43 100644 --- a/trunk/drivers/net/vxge/vxge-ethtool.c +++ b/trunk/drivers/net/vxge/vxge-ethtool.c @@ -1117,8 +1117,8 @@ static int vxge_set_flags(struct net_device *dev, u32 data) struct vxgedev *vdev = netdev_priv(dev); enum vxge_hw_status status; - if (ethtool_invalid_flags(dev, data, ETH_FLAG_RXHASH)) - return -EINVAL; + if (data & ~ETH_FLAG_RXHASH) + return -EOPNOTSUPP; if (!!(data & ETH_FLAG_RXHASH) == vdev->devh->config.rth_en) return 0; diff --git a/trunk/drivers/net/wireless/p54/p54spi.c b/trunk/drivers/net/wireless/p54/p54spi.c index 7ecc0bda57b3..18d24b7b1e34 100644 --- a/trunk/drivers/net/wireless/p54/p54spi.c +++ b/trunk/drivers/net/wireless/p54/p54spi.c @@ -649,7 +649,8 @@ static int __devinit p54spi_probe(struct spi_device *spi) goto err_free_common; } - irq_set_irq_type(gpio_to_irq(p54spi_gpio_irq), IRQ_TYPE_EDGE_RISING); + set_irq_type(gpio_to_irq(p54spi_gpio_irq), + IRQ_TYPE_EDGE_RISING); disable_irq(gpio_to_irq(p54spi_gpio_irq)); diff --git a/trunk/drivers/net/wireless/wl1251/sdio.c b/trunk/drivers/net/wireless/wl1251/sdio.c index f51a0241a440..d550b5e68d3c 100644 --- a/trunk/drivers/net/wireless/wl1251/sdio.c +++ b/trunk/drivers/net/wireless/wl1251/sdio.c @@ -265,7 +265,7 @@ static int wl1251_sdio_probe(struct sdio_func *func, goto disable; } - irq_set_irq_type(wl->irq, IRQ_TYPE_EDGE_RISING); + set_irq_type(wl->irq, IRQ_TYPE_EDGE_RISING); disable_irq(wl->irq); wl1251_sdio_ops.enable_irq = wl1251_enable_line_irq; diff --git a/trunk/drivers/net/wireless/wl1251/spi.c b/trunk/drivers/net/wireless/wl1251/spi.c index af6448c4d3e2..ac872b38960f 100644 --- a/trunk/drivers/net/wireless/wl1251/spi.c +++ b/trunk/drivers/net/wireless/wl1251/spi.c @@ -286,7 +286,7 @@ static int __devinit wl1251_spi_probe(struct spi_device *spi) goto out_free; } - irq_set_irq_type(wl->irq, IRQ_TYPE_EDGE_RISING); + set_irq_type(wl->irq, IRQ_TYPE_EDGE_RISING); disable_irq(wl->irq); diff --git a/trunk/drivers/parisc/eisa.c b/trunk/drivers/parisc/eisa.c index 103095bbe8c0..deeec32a5803 100644 --- a/trunk/drivers/parisc/eisa.c +++ b/trunk/drivers/parisc/eisa.c @@ -340,7 +340,7 @@ static int __init eisa_probe(struct parisc_device *dev) /* Reserve IRQ2 */ setup_irq(2, &irq2_action); for (i = 0; i < 16; i++) { - irq_set_chip_and_handler(i, &eisa_interrupt_type, + set_irq_chip_and_handler(i, &eisa_interrupt_type, handle_simple_irq); } diff --git a/trunk/drivers/parisc/gsc.c b/trunk/drivers/parisc/gsc.c index 1bab5a2cd359..ef31080cf591 100644 --- a/trunk/drivers/parisc/gsc.c +++ b/trunk/drivers/parisc/gsc.c @@ -152,8 +152,8 @@ int gsc_assign_irq(struct irq_chip *type, void *data) if (irq > GSC_IRQ_MAX) return NO_IRQ; - irq_set_chip_and_handler(irq, type, handle_simple_irq); - irq_set_chip_data(irq, data); + set_irq_chip_and_handler(irq, type, handle_simple_irq); + set_irq_chip_data(irq, data); return irq++; } diff --git a/trunk/drivers/parisc/superio.c b/trunk/drivers/parisc/superio.c index e3b76d409dee..a4d8ff66a639 100644 --- a/trunk/drivers/parisc/superio.c +++ b/trunk/drivers/parisc/superio.c @@ -355,8 +355,7 @@ int superio_fixup_irq(struct pci_dev *pcidev) #endif for (i = 0; i < 16; i++) { - irq_set_chip_and_handler(i, &superio_interrupt_type, - handle_simple_irq); + set_irq_chip_and_handler(i, &superio_interrupt_type, handle_simple_irq); } /* diff --git a/trunk/drivers/pci/dmar.c b/trunk/drivers/pci/dmar.c index 12e02bf92c4a..09933eb9126b 100644 --- a/trunk/drivers/pci/dmar.c +++ b/trunk/drivers/pci/dmar.c @@ -1226,7 +1226,7 @@ const char *dmar_get_fault_reason(u8 fault_reason, int *fault_type) void dmar_msi_unmask(struct irq_data *data) { - struct intel_iommu *iommu = irq_data_get_irq_handler_data(data); + struct intel_iommu *iommu = irq_data_get_irq_data(data); unsigned long flag; /* unmask it */ @@ -1240,7 +1240,7 @@ void dmar_msi_unmask(struct irq_data *data) void dmar_msi_mask(struct irq_data *data) { unsigned long flag; - struct intel_iommu *iommu = irq_data_get_irq_handler_data(data); + struct intel_iommu *iommu = irq_data_get_irq_data(data); /* mask it */ spin_lock_irqsave(&iommu->register_lock, flag); @@ -1252,7 +1252,7 @@ void dmar_msi_mask(struct irq_data *data) void dmar_msi_write(int irq, struct msi_msg *msg) { - struct intel_iommu *iommu = irq_get_handler_data(irq); + struct intel_iommu *iommu = get_irq_data(irq); unsigned long flag; spin_lock_irqsave(&iommu->register_lock, flag); @@ -1264,7 +1264,7 @@ void dmar_msi_write(int irq, struct msi_msg *msg) void dmar_msi_read(int irq, struct msi_msg *msg) { - struct intel_iommu *iommu = irq_get_handler_data(irq); + struct intel_iommu *iommu = get_irq_data(irq); unsigned long flag; spin_lock_irqsave(&iommu->register_lock, flag); @@ -1382,12 +1382,12 @@ int dmar_set_interrupt(struct intel_iommu *iommu) return -EINVAL; } - irq_set_handler_data(irq, iommu); + set_irq_data(irq, iommu); iommu->irq = irq; ret = arch_setup_dmar_msi(irq); if (ret) { - irq_set_handler_data(irq, NULL); + set_irq_data(irq, NULL); iommu->irq = 0; destroy_irq(irq); return ret; diff --git a/trunk/drivers/pci/htirq.c b/trunk/drivers/pci/htirq.c index db057b6fe0c8..834842aa5bbf 100644 --- a/trunk/drivers/pci/htirq.c +++ b/trunk/drivers/pci/htirq.c @@ -34,7 +34,7 @@ struct ht_irq_cfg { void write_ht_irq_msg(unsigned int irq, struct ht_irq_msg *msg) { - struct ht_irq_cfg *cfg = irq_get_handler_data(irq); + struct ht_irq_cfg *cfg = get_irq_data(irq); unsigned long flags; spin_lock_irqsave(&ht_irq_lock, flags); if (cfg->msg.address_lo != msg->address_lo) { @@ -53,13 +53,13 @@ void write_ht_irq_msg(unsigned int irq, struct ht_irq_msg *msg) void fetch_ht_irq_msg(unsigned int irq, struct ht_irq_msg *msg) { - struct ht_irq_cfg *cfg = irq_get_handler_data(irq); + struct ht_irq_cfg *cfg = get_irq_data(irq); *msg = cfg->msg; } void mask_ht_irq(struct irq_data *data) { - struct ht_irq_cfg *cfg = irq_data_get_irq_handler_data(data); + struct ht_irq_cfg *cfg = irq_data_get_irq_data(data); struct ht_irq_msg msg = cfg->msg; msg.address_lo |= 1; @@ -68,7 +68,7 @@ void mask_ht_irq(struct irq_data *data) void unmask_ht_irq(struct irq_data *data) { - struct ht_irq_cfg *cfg = irq_data_get_irq_handler_data(data); + struct ht_irq_cfg *cfg = irq_data_get_irq_data(data); struct ht_irq_msg msg = cfg->msg; msg.address_lo &= ~1; @@ -126,7 +126,7 @@ int __ht_create_irq(struct pci_dev *dev, int idx, ht_irq_update_t *update) kfree(cfg); return -EBUSY; } - irq_set_handler_data(irq, cfg); + set_irq_data(irq, cfg); if (arch_setup_ht_irq(irq, dev) < 0) { ht_destroy_irq(irq); @@ -162,9 +162,9 @@ void ht_destroy_irq(unsigned int irq) { struct ht_irq_cfg *cfg; - cfg = irq_get_handler_data(irq); - irq_set_chip(irq, NULL); - irq_set_handler_data(irq, NULL); + cfg = get_irq_data(irq); + set_irq_chip(irq, NULL); + set_irq_data(irq, NULL); destroy_irq(irq); kfree(cfg); diff --git a/trunk/drivers/pci/intel-iommu.c b/trunk/drivers/pci/intel-iommu.c index 7da3bef60d87..a4115f1afe1f 100644 --- a/trunk/drivers/pci/intel-iommu.c +++ b/trunk/drivers/pci/intel-iommu.c @@ -1206,7 +1206,7 @@ void free_dmar_iommu(struct intel_iommu *iommu) iommu_disable_translation(iommu); if (iommu->irq) { - irq_set_handler_data(iommu->irq, NULL); + set_irq_data(iommu->irq, NULL); /* This will mask the irq */ free_irq(iommu->irq, iommu); destroy_irq(iommu->irq); diff --git a/trunk/drivers/pci/intr_remapping.c b/trunk/drivers/pci/intr_remapping.c index a22557b20283..ec87cd66f3eb 100644 --- a/trunk/drivers/pci/intr_remapping.c +++ b/trunk/drivers/pci/intr_remapping.c @@ -50,7 +50,7 @@ static DEFINE_SPINLOCK(irq_2_ir_lock); static struct irq_2_iommu *irq_2_iommu(unsigned int irq) { - struct irq_cfg *cfg = irq_get_chip_data(irq); + struct irq_cfg *cfg = get_irq_chip_data(irq); return cfg ? &cfg->irq_2_iommu : NULL; } diff --git a/trunk/drivers/pci/msi.c b/trunk/drivers/pci/msi.c index 2f10328bf661..44b0aeee83e5 100644 --- a/trunk/drivers/pci/msi.c +++ b/trunk/drivers/pci/msi.c @@ -236,7 +236,7 @@ void __read_msi_msg(struct msi_desc *entry, struct msi_msg *msg) void read_msi_msg(unsigned int irq, struct msi_msg *msg) { - struct msi_desc *entry = irq_get_msi_desc(irq); + struct msi_desc *entry = get_irq_msi(irq); __read_msi_msg(entry, msg); } @@ -253,7 +253,7 @@ void __get_cached_msi_msg(struct msi_desc *entry, struct msi_msg *msg) void get_cached_msi_msg(unsigned int irq, struct msi_msg *msg) { - struct msi_desc *entry = irq_get_msi_desc(irq); + struct msi_desc *entry = get_irq_msi(irq); __get_cached_msi_msg(entry, msg); } @@ -297,7 +297,7 @@ void __write_msi_msg(struct msi_desc *entry, struct msi_msg *msg) void write_msi_msg(unsigned int irq, struct msi_msg *msg) { - struct msi_desc *entry = irq_get_msi_desc(irq); + struct msi_desc *entry = get_irq_msi(irq); __write_msi_msg(entry, msg); } @@ -354,7 +354,7 @@ static void __pci_restore_msi_state(struct pci_dev *dev) if (!dev->msi_enabled) return; - entry = irq_get_msi_desc(dev->irq); + entry = get_irq_msi(dev->irq); pos = entry->msi_attrib.pos; pci_intx_for_msi(dev, 0); @@ -519,7 +519,7 @@ static void msix_program_entries(struct pci_dev *dev, PCI_MSIX_ENTRY_VECTOR_CTRL; entries[i].vector = entry->irq; - irq_set_msi_desc(entry->irq, entry); + set_irq_msi(entry->irq, entry); entry->masked = readl(entry->mask_base + offset); msix_mask_irq(entry, 1); i++; diff --git a/trunk/drivers/pcmcia/bfin_cf_pcmcia.c b/trunk/drivers/pcmcia/bfin_cf_pcmcia.c index 49221395101e..eae9cbe37a3e 100644 --- a/trunk/drivers/pcmcia/bfin_cf_pcmcia.c +++ b/trunk/drivers/pcmcia/bfin_cf_pcmcia.c @@ -235,7 +235,7 @@ static int __devinit bfin_cf_probe(struct platform_device *pdev) cf->irq = irq; cf->socket.pci_irq = irq; - irq_set_irq_type(irq, IRQF_TRIGGER_LOW); + set_irq_type(irq, IRQF_TRIGGER_LOW); io_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); attr_mem = platform_get_resource(pdev, IORESOURCE_MEM, 1); diff --git a/trunk/drivers/pcmcia/db1xxx_ss.c b/trunk/drivers/pcmcia/db1xxx_ss.c index 01757f18a208..27575e6378a1 100644 --- a/trunk/drivers/pcmcia/db1xxx_ss.c +++ b/trunk/drivers/pcmcia/db1xxx_ss.c @@ -181,7 +181,7 @@ static int db1x_pcmcia_setup_irqs(struct db1x_pcmcia_sock *sock) /* all other (older) Db1x00 boards use a GPIO to show * card detection status: use both-edge triggers. */ - irq_set_irq_type(sock->insert_irq, IRQ_TYPE_EDGE_BOTH); + set_irq_type(sock->insert_irq, IRQ_TYPE_EDGE_BOTH); ret = request_irq(sock->insert_irq, db1000_pcmcia_cdirq, 0, "pcmcia_carddetect", sock); diff --git a/trunk/drivers/pcmcia/sa1100_nanoengine.c b/trunk/drivers/pcmcia/sa1100_nanoengine.c index 93b9c9ba57c3..3d2652e2f5ae 100644 --- a/trunk/drivers/pcmcia/sa1100_nanoengine.c +++ b/trunk/drivers/pcmcia/sa1100_nanoengine.c @@ -86,7 +86,7 @@ static int nanoengine_pcmcia_hw_init(struct soc_pcmcia_socket *skt) GPDR &= ~nano_skts[i].input_pins; GPDR |= nano_skts[i].output_pins; GPCR = nano_skts[i].clear_outputs; - irq_set_irq_type(nano_skts[i].transition_pins, IRQ_TYPE_EDGE_BOTH); + set_irq_type(nano_skts[i].transition_pins, IRQ_TYPE_EDGE_BOTH); skt->socket.pci_irq = nano_skts[i].pci_irq; return soc_pcmcia_request_irqs(skt, diff --git a/trunk/drivers/pcmcia/soc_common.c b/trunk/drivers/pcmcia/soc_common.c index 768f9572a8c8..5a9a392eacdf 100644 --- a/trunk/drivers/pcmcia/soc_common.c +++ b/trunk/drivers/pcmcia/soc_common.c @@ -155,11 +155,11 @@ static int soc_common_pcmcia_config_skt( */ if (skt->irq_state != 1 && state->io_irq) { skt->irq_state = 1; - irq_set_irq_type(skt->socket.pci_irq, - IRQ_TYPE_EDGE_FALLING); + set_irq_type(skt->socket.pci_irq, + IRQ_TYPE_EDGE_FALLING); } else if (skt->irq_state == 1 && state->io_irq == 0) { skt->irq_state = 0; - irq_set_irq_type(skt->socket.pci_irq, IRQ_TYPE_NONE); + set_irq_type(skt->socket.pci_irq, IRQ_TYPE_NONE); } skt->cs_state = *state; @@ -537,7 +537,7 @@ int soc_pcmcia_request_irqs(struct soc_pcmcia_socket *skt, IRQF_DISABLED, irqs[i].str, skt); if (res) break; - irq_set_irq_type(irqs[i].irq, IRQ_TYPE_NONE); + set_irq_type(irqs[i].irq, IRQ_TYPE_NONE); } if (res) { @@ -570,7 +570,7 @@ void soc_pcmcia_disable_irqs(struct soc_pcmcia_socket *skt, for (i = 0; i < nr; i++) if (irqs[i].sock == skt->nr) - irq_set_irq_type(irqs[i].irq, IRQ_TYPE_NONE); + set_irq_type(irqs[i].irq, IRQ_TYPE_NONE); } EXPORT_SYMBOL(soc_pcmcia_disable_irqs); @@ -581,8 +581,8 @@ void soc_pcmcia_enable_irqs(struct soc_pcmcia_socket *skt, for (i = 0; i < nr; i++) if (irqs[i].sock == skt->nr) { - irq_set_irq_type(irqs[i].irq, IRQ_TYPE_EDGE_RISING); - irq_set_irq_type(irqs[i].irq, IRQ_TYPE_EDGE_BOTH); + set_irq_type(irqs[i].irq, IRQ_TYPE_EDGE_RISING); + set_irq_type(irqs[i].irq, IRQ_TYPE_EDGE_BOTH); } } EXPORT_SYMBOL(soc_pcmcia_enable_irqs); diff --git a/trunk/drivers/pcmcia/xxs1500_ss.c b/trunk/drivers/pcmcia/xxs1500_ss.c index 379f4218857d..3b67a1b6a197 100644 --- a/trunk/drivers/pcmcia/xxs1500_ss.c +++ b/trunk/drivers/pcmcia/xxs1500_ss.c @@ -274,7 +274,7 @@ static int __devinit xxs1500_pcmcia_probe(struct platform_device *pdev) * edge detector. */ irq = gpio_to_irq(GPIO_CDA); - irq_set_irq_type(irq, IRQ_TYPE_EDGE_BOTH); + set_irq_type(irq, IRQ_TYPE_EDGE_BOTH); ret = request_irq(irq, cdirq, 0, "pcmcia_carddetect", sock); if (ret) { dev_err(&pdev->dev, "cannot setup cd irq\n"); diff --git a/trunk/drivers/platform/x86/Kconfig b/trunk/drivers/platform/x86/Kconfig index 2ee442c2a5db..222dfb737b11 100644 --- a/trunk/drivers/platform/x86/Kconfig +++ b/trunk/drivers/platform/x86/Kconfig @@ -101,19 +101,6 @@ config DELL_WMI To compile this driver as a module, choose M here: the module will be called dell-wmi. -config DELL_WMI_AIO - tristate "WMI Hotkeys for Dell All-In-One series" - depends on ACPI_WMI - depends on INPUT - select INPUT_SPARSEKMAP - ---help--- - Say Y here if you want to support WMI-based hotkeys on Dell - All-In-One machines. - - To compile this driver as a module, choose M here: the module will - be called dell-wmi. - - config FUJITSU_LAPTOP tristate "Fujitsu Laptop Extras" depends on ACPI @@ -451,53 +438,23 @@ config EEEPC_LAPTOP Bluetooth, backlight and allows powering on/off some other devices. - If you have an Eee PC laptop, say Y or M here. If this driver - doesn't work on your Eee PC, try eeepc-wmi instead. + If you have an Eee PC laptop, say Y or M here. -config ASUS_WMI - tristate "ASUS WMI Driver (EXPERIMENTAL)" +config EEEPC_WMI + tristate "Eee PC WMI Hotkey Driver (EXPERIMENTAL)" depends on ACPI_WMI depends on INPUT - depends on HWMON depends on EXPERIMENTAL depends on BACKLIGHT_CLASS_DEVICE depends on RFKILL || RFKILL = n - depends on HOTPLUG_PCI select INPUT_SPARSEKMAP select LEDS_CLASS select NEW_LEDS ---help--- - Say Y here if you have a WMI aware Asus laptop (like Eee PCs or new - Asus Notebooks). + Say Y here if you want to support WMI-based hotkeys on Eee PC laptops. To compile this driver as a module, choose M here: the module will - be called asus-wmi. - -config ASUS_NB_WMI - tristate "Asus Notebook WMI Driver (EXPERIMENTAL)" - depends on ASUS_WMI - ---help--- - This is a driver for newer Asus notebooks. It adds extra features - like wireless radio and bluetooth control, leds, hotkeys, backlight... - - For more informations, see - - - If you have an ACPI-WMI compatible Asus Notebook, say Y or M - here. - -config EEEPC_WMI - tristate "Eee PC WMI Driver (EXPERIMENTAL)" - depends on ASUS_WMI - ---help--- - This is a driver for newer Eee PC laptops. It adds extra features - like wireless radio and bluetooth control, leds, hotkeys, backlight... - - For more informations, see - - - If you have an ACPI-WMI compatible Eee PC laptop (>= 1000), say Y or M - here. + be called eeepc-wmi. config ACPI_WMI tristate "WMI" @@ -659,21 +616,6 @@ config GPIO_INTEL_PMIC Say Y here to support GPIO via the SCU IPC interface on Intel MID platforms. -config INTEL_MID_POWER_BUTTON - tristate "power button driver for Intel MID platforms" - depends on INTEL_SCU_IPC && INPUT - help - This driver handles the power button on the Intel MID platforms. - - If unsure, say N. - -config INTEL_MFLD_THERMAL - tristate "Thermal driver for Intel Medfield platform" - depends on INTEL_SCU_IPC && THERMAL - help - Say Y here to enable thermal driver support for the Intel Medfield - platform. - config RAR_REGISTER bool "Restricted Access Region Register Driver" depends on PCI && X86_MRST @@ -730,26 +672,4 @@ config XO1_RFKILL Support for enabling/disabling the WLAN interface on the OLPC XO-1 laptop. -config XO15_EBOOK - tristate "OLPC XO-1.5 ebook switch" - depends on ACPI && INPUT - ---help--- - Support for the ebook switch on the OLPC XO-1.5 laptop. - - This switch is triggered as the screen is rotated and folded down to - convert the device into ebook form. - -config SAMSUNG_LAPTOP - tristate "Samsung Laptop driver" - depends on RFKILL && BACKLIGHT_CLASS_DEVICE && X86 - ---help--- - This module implements a driver for a wide range of different - Samsung laptops. It offers control over the different - function keys, wireless LED, LCD backlight level, and - sometimes provides a "performance_control" sysfs file to allow - the performance level of the laptop to be changed. - - To compile this driver as a module, choose M here: the module - will be called samsung-laptop. - endif # X86_PLATFORM_DEVICES diff --git a/trunk/drivers/platform/x86/Makefile b/trunk/drivers/platform/x86/Makefile index 029e8861d086..299aefb3e74c 100644 --- a/trunk/drivers/platform/x86/Makefile +++ b/trunk/drivers/platform/x86/Makefile @@ -3,8 +3,6 @@ # x86 Platform-Specific Drivers # obj-$(CONFIG_ASUS_LAPTOP) += asus-laptop.o -obj-$(CONFIG_ASUS_WMI) += asus-wmi.o -obj-$(CONFIG_ASUS_NB_WMI) += asus-nb-wmi.o obj-$(CONFIG_EEEPC_LAPTOP) += eeepc-laptop.o obj-$(CONFIG_EEEPC_WMI) += eeepc-wmi.o obj-$(CONFIG_MSI_LAPTOP) += msi-laptop.o @@ -12,7 +10,6 @@ obj-$(CONFIG_ACPI_CMPC) += classmate-laptop.o obj-$(CONFIG_COMPAL_LAPTOP) += compal-laptop.o obj-$(CONFIG_DELL_LAPTOP) += dell-laptop.o obj-$(CONFIG_DELL_WMI) += dell-wmi.o -obj-$(CONFIG_DELL_WMI_AIO) += dell-wmi-aio.o obj-$(CONFIG_ACER_WMI) += acer-wmi.o obj-$(CONFIG_ACERHDF) += acerhdf.o obj-$(CONFIG_HP_ACCEL) += hp_accel.o @@ -32,13 +29,9 @@ obj-$(CONFIG_TOPSTAR_LAPTOP) += topstar-laptop.o obj-$(CONFIG_ACPI_TOSHIBA) += toshiba_acpi.o obj-$(CONFIG_TOSHIBA_BT_RFKILL) += toshiba_bluetooth.o obj-$(CONFIG_INTEL_SCU_IPC) += intel_scu_ipc.o -obj-$(CONFIG_INTEL_SCU_IPC_UTIL) += intel_scu_ipcutil.o -obj-$(CONFIG_INTEL_MFLD_THERMAL) += intel_mid_thermal.o +obj-$(CONFIG_INTEL_SCU_IPC_UTIL)+= intel_scu_ipcutil.o obj-$(CONFIG_RAR_REGISTER) += intel_rar_register.o obj-$(CONFIG_INTEL_IPS) += intel_ips.o obj-$(CONFIG_GPIO_INTEL_PMIC) += intel_pmic_gpio.o obj-$(CONFIG_XO1_RFKILL) += xo1-rfkill.o -obj-$(CONFIG_XO15_EBOOK) += xo15-ebook.o obj-$(CONFIG_IBM_RTL) += ibm_rtl.o -obj-$(CONFIG_SAMSUNG_LAPTOP) += samsung-laptop.o -obj-$(CONFIG_INTEL_MFLD_THERMAL) += intel_mid_thermal.o diff --git a/trunk/drivers/platform/x86/acer-wmi.c b/trunk/drivers/platform/x86/acer-wmi.c index 5ea6c3477d17..c9784705f6ac 100644 --- a/trunk/drivers/platform/x86/acer-wmi.c +++ b/trunk/drivers/platform/x86/acer-wmi.c @@ -22,8 +22,6 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - #include #include #include @@ -48,6 +46,12 @@ MODULE_AUTHOR("Carlos Corbacho"); MODULE_DESCRIPTION("Acer Laptop WMI Extras Driver"); MODULE_LICENSE("GPL"); +#define ACER_LOGPREFIX "acer-wmi: " +#define ACER_ERR KERN_ERR ACER_LOGPREFIX +#define ACER_NOTICE KERN_NOTICE ACER_LOGPREFIX +#define ACER_INFO KERN_INFO ACER_LOGPREFIX +#define ACER_WARNING KERN_WARNING ACER_LOGPREFIX + /* * Magic Number * Meaning is unknown - this number is required for writing to ACPI for AMW0 @@ -80,7 +84,7 @@ MODULE_LICENSE("GPL"); #define AMW0_GUID1 "67C3371D-95A3-4C37-BB61-DD47B491DAAB" #define AMW0_GUID2 "431F16ED-0C2B-444C-B267-27DEB140CF9C" #define WMID_GUID1 "6AF4F258-B401-42FD-BE91-3D4AC2D7C0D3" -#define WMID_GUID2 "95764E09-FB56-4E83-B31A-37761F60994A" +#define WMID_GUID2 "95764E09-FB56-4e83-B31A-37761F60994A" #define WMID_GUID3 "61EF69EA-865C-4BC3-A502-A0DEBA0CB531" /* @@ -89,7 +93,7 @@ MODULE_LICENSE("GPL"); #define ACERWMID_EVENT_GUID "676AA15E-6A47-4D9F-A2CC-1E6D18D14026" MODULE_ALIAS("wmi:67C3371D-95A3-4C37-BB61-DD47B491DAAB"); -MODULE_ALIAS("wmi:6AF4F258-B401-42Fd-BE91-3D4AC2D7C0D3"); +MODULE_ALIAS("wmi:6AF4F258-B401-42fd-BE91-3D4AC2D7C0D3"); MODULE_ALIAS("wmi:676AA15E-6A47-4D9F-A2CC-1E6D18D14026"); enum acer_wmi_event_ids { @@ -104,7 +108,7 @@ static const struct key_entry acer_wmi_keymap[] = { {KE_KEY, 0x23, {KEY_PROG3} }, /* P_Key */ {KE_KEY, 0x24, {KEY_PROG4} }, /* Social networking_Key */ {KE_KEY, 0x64, {KEY_SWITCHVIDEOMODE} }, /* Display Switch */ - {KE_KEY, 0x82, {KEY_TOUCHPAD_TOGGLE} }, /* Touch Pad On/Off */ + {KE_KEY, 0x82, {KEY_F22} }, /* Touch Pad On/Off */ {KE_END, 0} }; @@ -217,7 +221,6 @@ struct acer_debug { static struct rfkill *wireless_rfkill; static struct rfkill *bluetooth_rfkill; static struct rfkill *threeg_rfkill; -static bool rfkill_inited; /* Each low-level interface must define at least some of the following */ struct wmi_interface { @@ -842,7 +845,7 @@ static void type_aa_dmi_decode(const struct dmi_header *header, void *dummy) has_type_aa = true; type_aa = (struct hotkey_function_type_aa *) header; - pr_info("Function bitmap for Communication Button: 0x%x\n", + printk(ACER_INFO "Function bitmap for Communication Button: 0x%x\n", type_aa->commun_func_bitmap); if (type_aa->commun_func_bitmap & ACER_WMID3_GDS_WIRELESS) @@ -988,7 +991,6 @@ static int __devinit acer_led_init(struct device *dev) static void acer_led_exit(void) { - set_u32(LED_OFF, ACER_CAP_MAILLED); led_classdev_unregister(&mail_led); } @@ -1034,7 +1036,7 @@ static int __devinit acer_backlight_init(struct device *dev) bd = backlight_device_register("acer-wmi", dev, NULL, &acer_bl_ops, &props); if (IS_ERR(bd)) { - pr_err("Could not register Acer backlight device\n"); + printk(ACER_ERR "Could not register Acer backlight device\n"); acer_backlight_device = NULL; return PTR_ERR(bd); } @@ -1081,7 +1083,8 @@ static acpi_status wmid3_get_device_status(u32 *value, u16 device) return AE_ERROR; } if (obj->buffer.length != 8) { - pr_warning("Unknown buffer length %d\n", obj->buffer.length); + printk(ACER_WARNING "Unknown buffer length %d\n", + obj->buffer.length); kfree(obj); return AE_ERROR; } @@ -1090,7 +1093,7 @@ static acpi_status wmid3_get_device_status(u32 *value, u16 device) kfree(obj); if (return_value.error_code || return_value.ec_return_value) - pr_warning("Get Device Status failed: " + printk(ACER_WARNING "Get Device Status failed: " "0x%x - 0x%x\n", return_value.error_code, return_value.ec_return_value); else @@ -1158,13 +1161,9 @@ static int acer_rfkill_set(void *data, bool blocked) { acpi_status status; u32 cap = (unsigned long)data; - - if (rfkill_inited) { - status = set_u32(!blocked, cap); - if (ACPI_FAILURE(status)) - return -ENODEV; - } - + status = set_u32(!blocked, cap); + if (ACPI_FAILURE(status)) + return -ENODEV; return 0; } @@ -1188,16 +1187,14 @@ static struct rfkill *acer_rfkill_register(struct device *dev, return ERR_PTR(-ENOMEM); status = get_device_status(&state, cap); + if (ACPI_SUCCESS(status)) + rfkill_init_sw_state(rfkill_dev, !state); err = rfkill_register(rfkill_dev); if (err) { rfkill_destroy(rfkill_dev); return ERR_PTR(err); } - - if (ACPI_SUCCESS(status)) - rfkill_set_sw_state(rfkill_dev, !state); - return rfkill_dev; } @@ -1232,19 +1229,14 @@ static int acer_rfkill_init(struct device *dev) } } - rfkill_inited = true; - - if (ec_raw_mode || !wmi_has_guid(ACERWMID_EVENT_GUID)) - schedule_delayed_work(&acer_rfkill_work, - round_jiffies_relative(HZ)); + schedule_delayed_work(&acer_rfkill_work, round_jiffies_relative(HZ)); return 0; } static void acer_rfkill_exit(void) { - if (ec_raw_mode || !wmi_has_guid(ACERWMID_EVENT_GUID)) - cancel_delayed_work_sync(&acer_rfkill_work); + cancel_delayed_work_sync(&acer_rfkill_work); rfkill_unregister(wireless_rfkill); rfkill_destroy(wireless_rfkill); @@ -1317,7 +1309,7 @@ static void acer_wmi_notify(u32 value, void *context) status = wmi_get_event_data(value, &response); if (status != AE_OK) { - pr_warning("bad event status 0x%x\n", status); + printk(ACER_WARNING "bad event status 0x%x\n", status); return; } @@ -1326,12 +1318,14 @@ static void acer_wmi_notify(u32 value, void *context) if (!obj) return; if (obj->type != ACPI_TYPE_BUFFER) { - pr_warning("Unknown response received %d\n", obj->type); + printk(ACER_WARNING "Unknown response received %d\n", + obj->type); kfree(obj); return; } if (obj->buffer.length != 8) { - pr_warning("Unknown buffer length %d\n", obj->buffer.length); + printk(ACER_WARNING "Unknown buffer length %d\n", + obj->buffer.length); kfree(obj); return; } @@ -1341,26 +1335,13 @@ static void acer_wmi_notify(u32 value, void *context) switch (return_value.function) { case WMID_HOTKEY_EVENT: - if (return_value.device_state) { - u16 device_state = return_value.device_state; - pr_debug("deivces states: 0x%x\n", device_state); - if (has_cap(ACER_CAP_WIRELESS)) - rfkill_set_sw_state(wireless_rfkill, - !(device_state & ACER_WMID3_GDS_WIRELESS)); - if (has_cap(ACER_CAP_BLUETOOTH)) - rfkill_set_sw_state(bluetooth_rfkill, - !(device_state & ACER_WMID3_GDS_BLUETOOTH)); - if (has_cap(ACER_CAP_THREEG)) - rfkill_set_sw_state(threeg_rfkill, - !(device_state & ACER_WMID3_GDS_THREEG)); - } if (!sparse_keymap_report_event(acer_wmi_input_dev, return_value.key_num, 1, true)) - pr_warning("Unknown key number - 0x%x\n", + printk(ACER_WARNING "Unknown key number - 0x%x\n", return_value.key_num); break; default: - pr_warning("Unknown function number - %d - %d\n", + printk(ACER_WARNING "Unknown function number - %d - %d\n", return_value.function, return_value.key_num); break; } @@ -1389,7 +1370,8 @@ wmid3_set_lm_mode(struct lm_input_params *params, return AE_ERROR; } if (obj->buffer.length != 4) { - pr_warning("Unknown buffer length %d\n", obj->buffer.length); + printk(ACER_WARNING "Unknown buffer length %d\n", + obj->buffer.length); kfree(obj); return AE_ERROR; } @@ -1414,11 +1396,11 @@ static int acer_wmi_enable_ec_raw(void) status = wmid3_set_lm_mode(¶ms, &return_value); if (return_value.error_code || return_value.ec_return_value) - pr_warning("Enabling EC raw mode failed: " + printk(ACER_WARNING "Enabling EC raw mode failed: " "0x%x - 0x%x\n", return_value.error_code, return_value.ec_return_value); else - pr_info("Enabled EC raw mode"); + printk(ACER_INFO "Enabled EC raw mode"); return status; } @@ -1437,7 +1419,7 @@ static int acer_wmi_enable_lm(void) status = wmid3_set_lm_mode(¶ms, &return_value); if (return_value.error_code || return_value.ec_return_value) - pr_warning("Enabling Launch Manager failed: " + printk(ACER_WARNING "Enabling Launch Manager failed: " "0x%x - 0x%x\n", return_value.error_code, return_value.ec_return_value); @@ -1571,7 +1553,6 @@ pm_message_t state) if (has_cap(ACER_CAP_MAILLED)) { get_u32(&value, ACER_CAP_MAILLED); - set_u32(LED_OFF, ACER_CAP_MAILLED); data->mailled = value; } @@ -1599,17 +1580,6 @@ static int acer_platform_resume(struct platform_device *device) return 0; } -static void acer_platform_shutdown(struct platform_device *device) -{ - struct acer_data *data = &interface->data; - - if (!data) - return; - - if (has_cap(ACER_CAP_MAILLED)) - set_u32(LED_OFF, ACER_CAP_MAILLED); -} - static struct platform_driver acer_platform_driver = { .driver = { .name = "acer-wmi", @@ -1619,7 +1589,6 @@ static struct platform_driver acer_platform_driver = { .remove = acer_platform_remove, .suspend = acer_platform_suspend, .resume = acer_platform_resume, - .shutdown = acer_platform_shutdown, }; static struct platform_device *acer_platform_device; @@ -1667,7 +1636,7 @@ static int create_debugfs(void) { interface->debug.root = debugfs_create_dir("acer-wmi", NULL); if (!interface->debug.root) { - pr_err("Failed to create debugfs directory"); + printk(ACER_ERR "Failed to create debugfs directory"); return -ENOMEM; } @@ -1688,10 +1657,11 @@ static int __init acer_wmi_init(void) { int err; - pr_info("Acer Laptop ACPI-WMI Extras\n"); + printk(ACER_INFO "Acer Laptop ACPI-WMI Extras\n"); if (dmi_check_system(acer_blacklist)) { - pr_info("Blacklisted hardware detected - not loading\n"); + printk(ACER_INFO "Blacklisted hardware detected - " + "not loading\n"); return -ENODEV; } @@ -1708,11 +1678,12 @@ static int __init acer_wmi_init(void) if (wmi_has_guid(WMID_GUID2) && interface) { if (ACPI_FAILURE(WMID_set_capabilities())) { - pr_err("Unable to detect available WMID devices\n"); + printk(ACER_ERR "Unable to detect available WMID " + "devices\n"); return -ENODEV; } } else if (!wmi_has_guid(WMID_GUID2) && interface) { - pr_err("No WMID device detection method found\n"); + printk(ACER_ERR "No WMID device detection method found\n"); return -ENODEV; } @@ -1720,7 +1691,8 @@ static int __init acer_wmi_init(void) interface = &AMW0_interface; if (ACPI_FAILURE(AMW0_set_capabilities())) { - pr_err("Unable to detect available AMW0 devices\n"); + printk(ACER_ERR "Unable to detect available AMW0 " + "devices\n"); return -ENODEV; } } @@ -1729,7 +1701,8 @@ static int __init acer_wmi_init(void) AMW0_find_mailled(); if (!interface) { - pr_err("No or unsupported WMI interface, unable to load\n"); + printk(ACER_INFO "No or unsupported WMI interface, unable to " + "load\n"); return -ENODEV; } @@ -1737,22 +1710,22 @@ static int __init acer_wmi_init(void) if (acpi_video_backlight_support() && has_cap(ACER_CAP_BRIGHTNESS)) { interface->capability &= ~ACER_CAP_BRIGHTNESS; - pr_info("Brightness must be controlled by " + printk(ACER_INFO "Brightness must be controlled by " "generic video driver\n"); } if (wmi_has_guid(WMID_GUID3)) { if (ec_raw_mode) { if (ACPI_FAILURE(acer_wmi_enable_ec_raw())) { - pr_err("Cannot enable EC raw mode\n"); + printk(ACER_ERR "Cannot enable EC raw mode\n"); return -ENODEV; } } else if (ACPI_FAILURE(acer_wmi_enable_lm())) { - pr_err("Cannot enable Launch Manager mode\n"); + printk(ACER_ERR "Cannot enable Launch Manager mode\n"); return -ENODEV; } } else if (ec_raw_mode) { - pr_info("No WMID EC raw mode enable method\n"); + printk(ACER_INFO "No WMID EC raw mode enable method\n"); } if (wmi_has_guid(ACERWMID_EVENT_GUID)) { @@ -1763,7 +1736,7 @@ static int __init acer_wmi_init(void) err = platform_driver_register(&acer_platform_driver); if (err) { - pr_err("Unable to register platform driver.\n"); + printk(ACER_ERR "Unable to register platform driver.\n"); goto error_platform_register; } @@ -1818,7 +1791,7 @@ static void __exit acer_wmi_exit(void) platform_device_unregister(acer_platform_device); platform_driver_unregister(&acer_platform_driver); - pr_info("Acer Laptop WMI Extras unloaded\n"); + printk(ACER_INFO "Acer Laptop WMI Extras unloaded\n"); return; } diff --git a/trunk/drivers/platform/x86/asus-laptop.c b/trunk/drivers/platform/x86/asus-laptop.c index c53b3ff7978a..5a6f7d7575d6 100644 --- a/trunk/drivers/platform/x86/asus-laptop.c +++ b/trunk/drivers/platform/x86/asus-laptop.c @@ -29,7 +29,7 @@ * John Belmonte - ACPI code for Toshiba laptop was a good starting point. * Eric Burghard - LED display support for W1N * Josh Green - Light Sens support - * Thomas Tuttle - His first patch for led support was very helpful + * Thomas Tuttle - His first patch for led support was very helpfull * Sam Lin - GPS support */ @@ -50,7 +50,6 @@ #include #include #include -#include #include #include @@ -158,9 +157,46 @@ MODULE_PARM_DESC(wwan_status, "Set the wireless status on boot " #define METHOD_BRIGHTNESS_SET "SPLV" #define METHOD_BRIGHTNESS_GET "GPLV" +/* Backlight */ +static acpi_handle lcd_switch_handle; +static char *lcd_switch_paths[] = { + "\\_SB.PCI0.SBRG.EC0._Q10", /* All new models */ + "\\_SB.PCI0.ISA.EC0._Q10", /* A1x */ + "\\_SB.PCI0.PX40.ECD0._Q10", /* L3C */ + "\\_SB.PCI0.PX40.EC0.Q10", /* M1A */ + "\\_SB.PCI0.LPCB.EC0._Q10", /* P30 */ + "\\_SB.PCI0.LPCB.EC0._Q0E", /* P30/P35 */ + "\\_SB.PCI0.PX40.Q10", /* S1x */ + "\\Q10"}; /* A2x, L2D, L3D, M2E */ + /* Display */ #define METHOD_SWITCH_DISPLAY "SDSP" +static acpi_handle display_get_handle; +static char *display_get_paths[] = { + /* A6B, A6K A6R A7D F3JM L4R M6R A3G M6A M6V VX-1 V6J V6V W3Z */ + "\\_SB.PCI0.P0P1.VGA.GETD", + /* A3E A4K, A4D A4L A6J A7J A8J Z71V M9V S5A M5A z33A W1Jc W2V G1 */ + "\\_SB.PCI0.P0P2.VGA.GETD", + /* A6V A6Q */ + "\\_SB.PCI0.P0P3.VGA.GETD", + /* A6T, A6M */ + "\\_SB.PCI0.P0PA.VGA.GETD", + /* L3C */ + "\\_SB.PCI0.PCI1.VGAC.NMAP", + /* Z96F */ + "\\_SB.PCI0.VGA.GETD", + /* A2D */ + "\\ACTD", + /* A4G Z71A W1N W5A W5F M2N M3N M5N M6N S1N S5N */ + "\\ADVG", + /* P30 */ + "\\DNXT", + /* A2H D1 L2D L3D L3H L2E L5D L5C M1A M2E L4L W3V */ + "\\INFB", + /* A3F A6F A3N A3L M6N W3N W6A */ + "\\SSTE"}; + #define METHOD_ALS_CONTROL "ALSC" /* Z71A Z71V */ #define METHOD_ALS_LEVEL "ALSL" /* Z71A Z71V */ @@ -210,6 +246,7 @@ struct asus_laptop { int wireless_status; bool have_rsts; + int lcd_state; struct rfkill *gps_rfkill; @@ -522,6 +559,48 @@ static int asus_led_init(struct asus_laptop *asus) /* * Backlight device */ +static int asus_lcd_status(struct asus_laptop *asus) +{ + return asus->lcd_state; +} + +static int asus_lcd_set(struct asus_laptop *asus, int value) +{ + int lcd = 0; + acpi_status status = 0; + + lcd = !!value; + + if (lcd == asus_lcd_status(asus)) + return 0; + + if (!lcd_switch_handle) + return -ENODEV; + + status = acpi_evaluate_object(lcd_switch_handle, + NULL, NULL, NULL); + + if (ACPI_FAILURE(status)) { + pr_warning("Error switching LCD\n"); + return -ENODEV; + } + + asus->lcd_state = lcd; + return 0; +} + +static void lcd_blank(struct asus_laptop *asus, int blank) +{ + struct backlight_device *bd = asus->backlight_device; + + asus->lcd_state = (blank == FB_BLANK_UNBLANK); + + if (bd) { + bd->props.power = blank; + backlight_update_status(bd); + } +} + static int asus_read_brightness(struct backlight_device *bd) { struct asus_laptop *asus = bl_get_data(bd); @@ -549,9 +628,16 @@ static int asus_set_brightness(struct backlight_device *bd, int value) static int update_bl_status(struct backlight_device *bd) { + struct asus_laptop *asus = bl_get_data(bd); + int rv; int value = bd->props.brightness; - return asus_set_brightness(bd, value); + rv = asus_set_brightness(bd, value); + if (rv) + return rv; + + value = (bd->props.power == FB_BLANK_UNBLANK) ? 1 : 0; + return asus_lcd_set(asus, value); } static const struct backlight_ops asusbl_ops = { @@ -575,7 +661,8 @@ static int asus_backlight_init(struct asus_laptop *asus) struct backlight_properties props; if (acpi_check_handle(asus->handle, METHOD_BRIGHTNESS_GET, NULL) || - acpi_check_handle(asus->handle, METHOD_BRIGHTNESS_SET, NULL)) + acpi_check_handle(asus->handle, METHOD_BRIGHTNESS_SET, NULL) || + !lcd_switch_handle) return 0; memset(&props, 0, sizeof(struct backlight_properties)); @@ -884,6 +971,41 @@ static void asus_set_display(struct asus_laptop *asus, int value) return; } +static int read_display(struct asus_laptop *asus) +{ + unsigned long long value = 0; + acpi_status rv = AE_OK; + + /* + * In most of the case, we know how to set the display, but sometime + * we can't read it + */ + if (display_get_handle) { + rv = acpi_evaluate_integer(display_get_handle, NULL, + NULL, &value); + if (ACPI_FAILURE(rv)) + pr_warning("Error reading display status\n"); + } + + value &= 0x0F; /* needed for some models, shouldn't hurt others */ + + return value; +} + +/* + * Now, *this* one could be more user-friendly, but so far, no-one has + * complained. The significance of bits is the same as in store_disp() + */ +static ssize_t show_disp(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct asus_laptop *asus = dev_get_drvdata(dev); + + if (!display_get_handle) + return -ENODEV; + return sprintf(buf, "%d\n", read_display(asus)); +} + /* * Experimental support for display switching. As of now: 1 should activate * the LCD output, 2 should do for CRT, 4 for TV-Out and 8 for DVI. @@ -1125,6 +1247,15 @@ static void asus_acpi_notify(struct acpi_device *device, u32 event) struct asus_laptop *asus = acpi_driver_data(device); u16 count; + /* + * We need to tell the backlight device when the backlight power is + * switched + */ + if (event == ATKD_LCD_ON) + lcd_blank(asus, FB_BLANK_UNBLANK); + else if (event == ATKD_LCD_OFF) + lcd_blank(asus, FB_BLANK_POWERDOWN); + /* TODO Find a better way to handle events count. */ count = asus->event_count[event % 128]++; acpi_bus_generate_proc_event(asus->device, event, count); @@ -1151,7 +1282,7 @@ static DEVICE_ATTR(bluetooth, S_IRUGO | S_IWUSR, show_bluetooth, store_bluetooth); static DEVICE_ATTR(wimax, S_IRUGO | S_IWUSR, show_wimax, store_wimax); static DEVICE_ATTR(wwan, S_IRUGO | S_IWUSR, show_wwan, store_wwan); -static DEVICE_ATTR(display, S_IWUSR, NULL, store_disp); +static DEVICE_ATTR(display, S_IRUGO | S_IWUSR, show_disp, store_disp); static DEVICE_ATTR(ledd, S_IRUGO | S_IWUSR, show_ledd, store_ledd); static DEVICE_ATTR(ls_level, S_IRUGO | S_IWUSR, show_lslvl, store_lslvl); static DEVICE_ATTR(ls_switch, S_IRUGO | S_IWUSR, show_lssw, store_lssw); @@ -1262,6 +1393,26 @@ static struct platform_driver platform_driver = { } }; +static int asus_handle_init(char *name, acpi_handle * handle, + char **paths, int num_paths) +{ + int i; + acpi_status status; + + for (i = 0; i < num_paths; i++) { + status = acpi_get_handle(NULL, paths[i], handle); + if (ACPI_SUCCESS(status)) + return 0; + } + + *handle = NULL; + return -ENODEV; +} + +#define ASUS_HANDLE_INIT(object) \ + asus_handle_init(#object, &object##_handle, object##_paths, \ + ARRAY_SIZE(object##_paths)) + /* * This function is used to initialize the context with right values. In this * method, we can make all the detection we want, and modify the asus_laptop @@ -1347,6 +1498,10 @@ static int asus_laptop_get_info(struct asus_laptop *asus) if (!acpi_check_handle(asus->handle, METHOD_WL_STATUS, NULL)) asus->have_rsts = true; + /* Scheduled for removal */ + ASUS_HANDLE_INIT(lcd_switch); + ASUS_HANDLE_INIT(display_get); + kfree(model); return AE_OK; @@ -1398,23 +1553,10 @@ static int __devinit asus_acpi_init(struct asus_laptop *asus) asus_als_level(asus, asus->light_level); } + asus->lcd_state = 1; /* LCD should be on when the module load */ return result; } -static void __devinit asus_dmi_check(void) -{ - const char *model; - - model = dmi_get_system_info(DMI_PRODUCT_NAME); - if (!model) - return; - - /* On L1400B WLED control the sound card, don't mess with it ... */ - if (strncmp(model, "L1400B", 6) == 0) { - wlan_status = -1; - } -} - static bool asus_device_present; static int __devinit asus_acpi_add(struct acpi_device *device) @@ -1433,8 +1575,6 @@ static int __devinit asus_acpi_add(struct acpi_device *device) device->driver_data = asus; asus->device = device; - asus_dmi_check(); - result = asus_acpi_init(asus); if (result) goto fail_platform; diff --git a/trunk/drivers/platform/x86/asus-nb-wmi.c b/trunk/drivers/platform/x86/asus-nb-wmi.c deleted file mode 100644 index 0580d99b0798..000000000000 --- a/trunk/drivers/platform/x86/asus-nb-wmi.c +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Asus Notebooks WMI hotkey driver - * - * Copyright(C) 2010 Corentin Chary - * - * 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 - */ - -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - -#include -#include -#include -#include -#include - -#include "asus-wmi.h" - -#define ASUS_NB_WMI_FILE "asus-nb-wmi" - -MODULE_AUTHOR("Corentin Chary "); -MODULE_DESCRIPTION("Asus Notebooks WMI Hotkey Driver"); -MODULE_LICENSE("GPL"); - -#define ASUS_NB_WMI_EVENT_GUID "0B3CBB35-E3C2-45ED-91C2-4C5A6D195D1C" - -MODULE_ALIAS("wmi:"ASUS_NB_WMI_EVENT_GUID); - -static const struct key_entry asus_nb_wmi_keymap[] = { - { KE_KEY, 0x30, { KEY_VOLUMEUP } }, - { KE_KEY, 0x31, { KEY_VOLUMEDOWN } }, - { KE_KEY, 0x32, { KEY_MUTE } }, - { KE_KEY, 0x33, { KEY_DISPLAYTOGGLE } }, /* LCD on */ - { KE_KEY, 0x34, { KEY_DISPLAY_OFF } }, /* LCD off */ - { KE_KEY, 0x40, { KEY_PREVIOUSSONG } }, - { KE_KEY, 0x41, { KEY_NEXTSONG } }, - { KE_KEY, 0x43, { KEY_STOPCD } }, - { KE_KEY, 0x45, { KEY_PLAYPAUSE } }, - { KE_KEY, 0x4c, { KEY_MEDIA } }, - { KE_KEY, 0x50, { KEY_EMAIL } }, - { KE_KEY, 0x51, { KEY_WWW } }, - { KE_KEY, 0x55, { KEY_CALC } }, - { KE_KEY, 0x5C, { KEY_F15 } }, /* Power Gear key */ - { KE_KEY, 0x5D, { KEY_WLAN } }, - { KE_KEY, 0x5E, { KEY_WLAN } }, - { KE_KEY, 0x5F, { KEY_WLAN } }, - { KE_KEY, 0x60, { KEY_SWITCHVIDEOMODE } }, - { KE_KEY, 0x61, { KEY_SWITCHVIDEOMODE } }, - { KE_KEY, 0x62, { KEY_SWITCHVIDEOMODE } }, - { KE_KEY, 0x63, { KEY_SWITCHVIDEOMODE } }, - { KE_KEY, 0x6B, { KEY_TOUCHPAD_TOGGLE } }, - { KE_KEY, 0x7E, { KEY_BLUETOOTH } }, - { KE_KEY, 0x7D, { KEY_BLUETOOTH } }, - { KE_KEY, 0x82, { KEY_CAMERA } }, - { KE_KEY, 0x88, { KEY_RFKILL } }, - { KE_KEY, 0x8A, { KEY_PROG1 } }, - { KE_KEY, 0x95, { KEY_MEDIA } }, - { KE_KEY, 0x99, { KEY_PHONE } }, - { KE_KEY, 0xb5, { KEY_CALC } }, - { KE_KEY, 0xc4, { KEY_KBDILLUMUP } }, - { KE_KEY, 0xc5, { KEY_KBDILLUMDOWN } }, - { KE_END, 0}, -}; - -static struct asus_wmi_driver asus_nb_wmi_driver = { - .name = ASUS_NB_WMI_FILE, - .owner = THIS_MODULE, - .event_guid = ASUS_NB_WMI_EVENT_GUID, - .keymap = asus_nb_wmi_keymap, - .input_name = "Asus WMI hotkeys", - .input_phys = ASUS_NB_WMI_FILE "/input0", -}; - - -static int __init asus_nb_wmi_init(void) -{ - return asus_wmi_register_driver(&asus_nb_wmi_driver); -} - -static void __exit asus_nb_wmi_exit(void) -{ - asus_wmi_unregister_driver(&asus_nb_wmi_driver); -} - -module_init(asus_nb_wmi_init); -module_exit(asus_nb_wmi_exit); diff --git a/trunk/drivers/platform/x86/asus-wmi.c b/trunk/drivers/platform/x86/asus-wmi.c deleted file mode 100644 index efc776cb0c66..000000000000 --- a/trunk/drivers/platform/x86/asus-wmi.c +++ /dev/null @@ -1,1656 +0,0 @@ -/* - * Asus PC WMI hotkey driver - * - * Copyright(C) 2010 Intel Corporation. - * Copyright(C) 2010-2011 Corentin Chary - * - * Portions based on wistron_btns.c: - * Copyright (C) 2005 Miloslav Trmac - * Copyright (C) 2005 Bernhard Rosenkraenzer - * Copyright (C) 2005 Dmitry Torokhov - * - * 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 - */ - -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "asus-wmi.h" - -MODULE_AUTHOR("Corentin Chary , " - "Yong Wang "); -MODULE_DESCRIPTION("Asus Generic WMI Driver"); -MODULE_LICENSE("GPL"); - -#define to_platform_driver(drv) \ - (container_of((drv), struct platform_driver, driver)) - -#define to_asus_wmi_driver(pdrv) \ - (container_of((pdrv), struct asus_wmi_driver, platform_driver)) - -#define ASUS_WMI_MGMT_GUID "97845ED0-4E6D-11DE-8A39-0800200C9A66" - -#define NOTIFY_BRNUP_MIN 0x11 -#define NOTIFY_BRNUP_MAX 0x1f -#define NOTIFY_BRNDOWN_MIN 0x20 -#define NOTIFY_BRNDOWN_MAX 0x2e - -/* WMI Methods */ -#define ASUS_WMI_METHODID_SPEC 0x43455053 /* BIOS SPECification */ -#define ASUS_WMI_METHODID_SFBD 0x44424653 /* Set First Boot Device */ -#define ASUS_WMI_METHODID_GLCD 0x44434C47 /* Get LCD status */ -#define ASUS_WMI_METHODID_GPID 0x44495047 /* Get Panel ID?? (Resol) */ -#define ASUS_WMI_METHODID_QMOD 0x444F4D51 /* Quiet MODe */ -#define ASUS_WMI_METHODID_SPLV 0x4C425053 /* Set Panel Light Value */ -#define ASUS_WMI_METHODID_SFUN 0x4E554653 /* FUNCtionalities */ -#define ASUS_WMI_METHODID_SDSP 0x50534453 /* Set DiSPlay output */ -#define ASUS_WMI_METHODID_GDSP 0x50534447 /* Get DiSPlay output */ -#define ASUS_WMI_METHODID_DEVP 0x50564544 /* DEVice Policy */ -#define ASUS_WMI_METHODID_OSVR 0x5256534F /* OS VeRsion */ -#define ASUS_WMI_METHODID_DSTS 0x53544344 /* Device STatuS */ -#define ASUS_WMI_METHODID_DSTS2 0x53545344 /* Device STatuS #2*/ -#define ASUS_WMI_METHODID_BSTS 0x53545342 /* Bios STatuS ? */ -#define ASUS_WMI_METHODID_DEVS 0x53564544 /* DEVice Set */ -#define ASUS_WMI_METHODID_CFVS 0x53564643 /* CPU Frequency Volt Set */ -#define ASUS_WMI_METHODID_KBFT 0x5446424B /* KeyBoard FilTer */ -#define ASUS_WMI_METHODID_INIT 0x54494E49 /* INITialize */ -#define ASUS_WMI_METHODID_HKEY 0x59454B48 /* Hot KEY ?? */ - -#define ASUS_WMI_UNSUPPORTED_METHOD 0xFFFFFFFE - -/* Wireless */ -#define ASUS_WMI_DEVID_HW_SWITCH 0x00010001 -#define ASUS_WMI_DEVID_WIRELESS_LED 0x00010002 -#define ASUS_WMI_DEVID_WLAN 0x00010011 -#define ASUS_WMI_DEVID_BLUETOOTH 0x00010013 -#define ASUS_WMI_DEVID_GPS 0x00010015 -#define ASUS_WMI_DEVID_WIMAX 0x00010017 -#define ASUS_WMI_DEVID_WWAN3G 0x00010019 -#define ASUS_WMI_DEVID_UWB 0x00010021 - -/* Leds */ -/* 0x000200XX and 0x000400XX */ - -/* Backlight and Brightness */ -#define ASUS_WMI_DEVID_BACKLIGHT 0x00050011 -#define ASUS_WMI_DEVID_BRIGHTNESS 0x00050012 -#define ASUS_WMI_DEVID_KBD_BACKLIGHT 0x00050021 -#define ASUS_WMI_DEVID_LIGHT_SENSOR 0x00050022 /* ?? */ - -/* Misc */ -#define ASUS_WMI_DEVID_CAMERA 0x00060013 - -/* Storage */ -#define ASUS_WMI_DEVID_CARDREADER 0x00080013 - -/* Input */ -#define ASUS_WMI_DEVID_TOUCHPAD 0x00100011 -#define ASUS_WMI_DEVID_TOUCHPAD_LED 0x00100012 - -/* Fan, Thermal */ -#define ASUS_WMI_DEVID_THERMAL_CTRL 0x00110011 -#define ASUS_WMI_DEVID_FAN_CTRL 0x00110012 - -/* Power */ -#define ASUS_WMI_DEVID_PROCESSOR_STATE 0x00120012 - -/* DSTS masks */ -#define ASUS_WMI_DSTS_STATUS_BIT 0x00000001 -#define ASUS_WMI_DSTS_UNKNOWN_BIT 0x00000002 -#define ASUS_WMI_DSTS_PRESENCE_BIT 0x00010000 -#define ASUS_WMI_DSTS_USER_BIT 0x00020000 -#define ASUS_WMI_DSTS_BIOS_BIT 0x00040000 -#define ASUS_WMI_DSTS_BRIGHTNESS_MASK 0x000000FF -#define ASUS_WMI_DSTS_MAX_BRIGTH_MASK 0x0000FF00 - -struct bios_args { - u32 arg0; - u32 arg1; -} __packed; - -/* - * / - debugfs root directory - * dev_id - current dev_id - * ctrl_param - current ctrl_param - * method_id - current method_id - * devs - call DEVS(dev_id, ctrl_param) and print result - * dsts - call DSTS(dev_id) and print result - * call - call method_id(dev_id, ctrl_param) and print result - */ -struct asus_wmi_debug { - struct dentry *root; - u32 method_id; - u32 dev_id; - u32 ctrl_param; -}; - -struct asus_rfkill { - struct asus_wmi *asus; - struct rfkill *rfkill; - u32 dev_id; -}; - -struct asus_wmi { - int dsts_id; - int spec; - int sfun; - - struct input_dev *inputdev; - struct backlight_device *backlight_device; - struct device *hwmon_device; - struct platform_device *platform_device; - - struct led_classdev tpd_led; - int tpd_led_wk; - struct workqueue_struct *led_workqueue; - struct work_struct tpd_led_work; - - struct asus_rfkill wlan; - struct asus_rfkill bluetooth; - struct asus_rfkill wimax; - struct asus_rfkill wwan3g; - - struct hotplug_slot *hotplug_slot; - struct mutex hotplug_lock; - struct mutex wmi_lock; - struct workqueue_struct *hotplug_workqueue; - struct work_struct hotplug_work; - - struct asus_wmi_debug debug; - - struct asus_wmi_driver *driver; -}; - -static int asus_wmi_input_init(struct asus_wmi *asus) -{ - int err; - - asus->inputdev = input_allocate_device(); - if (!asus->inputdev) - return -ENOMEM; - - asus->inputdev->name = asus->driver->input_phys; - asus->inputdev->phys = asus->driver->input_name; - asus->inputdev->id.bustype = BUS_HOST; - asus->inputdev->dev.parent = &asus->platform_device->dev; - - err = sparse_keymap_setup(asus->inputdev, asus->driver->keymap, NULL); - if (err) - goto err_free_dev; - - err = input_register_device(asus->inputdev); - if (err) - goto err_free_keymap; - - return 0; - -err_free_keymap: - sparse_keymap_free(asus->inputdev); -err_free_dev: - input_free_device(asus->inputdev); - return err; -} - -static void asus_wmi_input_exit(struct asus_wmi *asus) -{ - if (asus->inputdev) { - sparse_keymap_free(asus->inputdev); - input_unregister_device(asus->inputdev); - } - - asus->inputdev = NULL; -} - -static int asus_wmi_evaluate_method(u32 method_id, u32 arg0, u32 arg1, - u32 *retval) -{ - struct bios_args args = { - .arg0 = arg0, - .arg1 = arg1, - }; - struct acpi_buffer input = { (acpi_size) sizeof(args), &args }; - struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL }; - acpi_status status; - union acpi_object *obj; - u32 tmp; - - status = wmi_evaluate_method(ASUS_WMI_MGMT_GUID, 1, method_id, - &input, &output); - - if (ACPI_FAILURE(status)) - goto exit; - - obj = (union acpi_object *)output.pointer; - if (obj && obj->type == ACPI_TYPE_INTEGER) - tmp = (u32) obj->integer.value; - else - tmp = 0; - - if (retval) - *retval = tmp; - - kfree(obj); - -exit: - if (ACPI_FAILURE(status)) - return -EIO; - - if (tmp == ASUS_WMI_UNSUPPORTED_METHOD) - return -ENODEV; - - return 0; -} - -static int asus_wmi_get_devstate(struct asus_wmi *asus, u32 dev_id, u32 *retval) -{ - return asus_wmi_evaluate_method(asus->dsts_id, dev_id, 0, retval); -} - -static int asus_wmi_set_devstate(u32 dev_id, u32 ctrl_param, - u32 *retval) -{ - return asus_wmi_evaluate_method(ASUS_WMI_METHODID_DEVS, dev_id, - ctrl_param, retval); -} - -/* Helper for special devices with magic return codes */ -static int asus_wmi_get_devstate_bits(struct asus_wmi *asus, - u32 dev_id, u32 mask) -{ - u32 retval = 0; - int err; - - err = asus_wmi_get_devstate(asus, dev_id, &retval); - - if (err < 0) - return err; - - if (!(retval & ASUS_WMI_DSTS_PRESENCE_BIT)) - return -ENODEV; - - if (mask == ASUS_WMI_DSTS_STATUS_BIT) { - if (retval & ASUS_WMI_DSTS_UNKNOWN_BIT) - return -ENODEV; - } - - return retval & mask; -} - -static int asus_wmi_get_devstate_simple(struct asus_wmi *asus, u32 dev_id) -{ - return asus_wmi_get_devstate_bits(asus, dev_id, - ASUS_WMI_DSTS_STATUS_BIT); -} - -/* - * LEDs - */ -/* - * These functions actually update the LED's, and are called from a - * workqueue. By doing this as separate work rather than when the LED - * subsystem asks, we avoid messing with the Asus ACPI stuff during a - * potentially bad time, such as a timer interrupt. - */ -static void tpd_led_update(struct work_struct *work) -{ - int ctrl_param; - struct asus_wmi *asus; - - asus = container_of(work, struct asus_wmi, tpd_led_work); - - ctrl_param = asus->tpd_led_wk; - asus_wmi_set_devstate(ASUS_WMI_DEVID_TOUCHPAD_LED, ctrl_param, NULL); -} - -static void tpd_led_set(struct led_classdev *led_cdev, - enum led_brightness value) -{ - struct asus_wmi *asus; - - asus = container_of(led_cdev, struct asus_wmi, tpd_led); - - asus->tpd_led_wk = !!value; - queue_work(asus->led_workqueue, &asus->tpd_led_work); -} - -static int read_tpd_led_state(struct asus_wmi *asus) -{ - return asus_wmi_get_devstate_simple(asus, ASUS_WMI_DEVID_TOUCHPAD_LED); -} - -static enum led_brightness tpd_led_get(struct led_classdev *led_cdev) -{ - struct asus_wmi *asus; - - asus = container_of(led_cdev, struct asus_wmi, tpd_led); - - return read_tpd_led_state(asus); -} - -static int asus_wmi_led_init(struct asus_wmi *asus) -{ - int rv; - - if (read_tpd_led_state(asus) < 0) - return 0; - - asus->led_workqueue = create_singlethread_workqueue("led_workqueue"); - if (!asus->led_workqueue) - return -ENOMEM; - INIT_WORK(&asus->tpd_led_work, tpd_led_update); - - asus->tpd_led.name = "asus::touchpad"; - asus->tpd_led.brightness_set = tpd_led_set; - asus->tpd_led.brightness_get = tpd_led_get; - asus->tpd_led.max_brightness = 1; - - rv = led_classdev_register(&asus->platform_device->dev, &asus->tpd_led); - if (rv) { - destroy_workqueue(asus->led_workqueue); - return rv; - } - - return 0; -} - -static void asus_wmi_led_exit(struct asus_wmi *asus) -{ - if (asus->tpd_led.dev) - led_classdev_unregister(&asus->tpd_led); - if (asus->led_workqueue) - destroy_workqueue(asus->led_workqueue); -} - -/* - * PCI hotplug (for wlan rfkill) - */ -static bool asus_wlan_rfkill_blocked(struct asus_wmi *asus) -{ - int result = asus_wmi_get_devstate_simple(asus, ASUS_WMI_DEVID_WLAN); - - if (result < 0) - return false; - return !result; -} - -static void asus_rfkill_hotplug(struct asus_wmi *asus) -{ - struct pci_dev *dev; - struct pci_bus *bus; - bool blocked; - bool absent; - u32 l; - - mutex_lock(&asus->wmi_lock); - blocked = asus_wlan_rfkill_blocked(asus); - mutex_unlock(&asus->wmi_lock); - - mutex_lock(&asus->hotplug_lock); - - if (asus->wlan.rfkill) - rfkill_set_sw_state(asus->wlan.rfkill, blocked); - - if (asus->hotplug_slot) { - bus = pci_find_bus(0, 1); - if (!bus) { - pr_warning("Unable to find PCI bus 1?\n"); - goto out_unlock; - } - - if (pci_bus_read_config_dword(bus, 0, PCI_VENDOR_ID, &l)) { - pr_err("Unable to read PCI config space?\n"); - goto out_unlock; - } - absent = (l == 0xffffffff); - - if (blocked != absent) { - pr_warning("BIOS says wireless lan is %s, " - "but the pci device is %s\n", - blocked ? "blocked" : "unblocked", - absent ? "absent" : "present"); - pr_warning("skipped wireless hotplug as probably " - "inappropriate for this model\n"); - goto out_unlock; - } - - if (!blocked) { - dev = pci_get_slot(bus, 0); - if (dev) { - /* Device already present */ - pci_dev_put(dev); - goto out_unlock; - } - dev = pci_scan_single_device(bus, 0); - if (dev) { - pci_bus_assign_resources(bus); - if (pci_bus_add_device(dev)) - pr_err("Unable to hotplug wifi\n"); - } - } else { - dev = pci_get_slot(bus, 0); - if (dev) { - pci_remove_bus_device(dev); - pci_dev_put(dev); - } - } - } - -out_unlock: - mutex_unlock(&asus->hotplug_lock); -} - -static void asus_rfkill_notify(acpi_handle handle, u32 event, void *data) -{ - struct asus_wmi *asus = data; - - if (event != ACPI_NOTIFY_BUS_CHECK) - return; - - /* - * We can't call directly asus_rfkill_hotplug because most - * of the time WMBC is still being executed and not reetrant. - * There is currently no way to tell ACPICA that we want this - * method to be serialized, we schedule a asus_rfkill_hotplug - * call later, in a safer context. - */ - queue_work(asus->hotplug_workqueue, &asus->hotplug_work); -} - -static int asus_register_rfkill_notifier(struct asus_wmi *asus, char *node) -{ - acpi_status status; - acpi_handle handle; - - status = acpi_get_handle(NULL, node, &handle); - - if (ACPI_SUCCESS(status)) { - status = acpi_install_notify_handler(handle, - ACPI_SYSTEM_NOTIFY, - asus_rfkill_notify, asus); - if (ACPI_FAILURE(status)) - pr_warning("Failed to register notify on %s\n", node); - } else - return -ENODEV; - - return 0; -} - -static void asus_unregister_rfkill_notifier(struct asus_wmi *asus, char *node) -{ - acpi_status status = AE_OK; - acpi_handle handle; - - status = acpi_get_handle(NULL, node, &handle); - - if (ACPI_SUCCESS(status)) { - status = acpi_remove_notify_handler(handle, - ACPI_SYSTEM_NOTIFY, - asus_rfkill_notify); - if (ACPI_FAILURE(status)) - pr_err("Error removing rfkill notify handler %s\n", - node); - } -} - -static int asus_get_adapter_status(struct hotplug_slot *hotplug_slot, - u8 *value) -{ - struct asus_wmi *asus = hotplug_slot->private; - int result = asus_wmi_get_devstate_simple(asus, ASUS_WMI_DEVID_WLAN); - - if (result < 0) - return result; - - *value = !!result; - return 0; -} - -static void asus_cleanup_pci_hotplug(struct hotplug_slot *hotplug_slot) -{ - kfree(hotplug_slot->info); - kfree(hotplug_slot); -} - -static struct hotplug_slot_ops asus_hotplug_slot_ops = { - .owner = THIS_MODULE, - .get_adapter_status = asus_get_adapter_status, - .get_power_status = asus_get_adapter_status, -}; - -static void asus_hotplug_work(struct work_struct *work) -{ - struct asus_wmi *asus; - - asus = container_of(work, struct asus_wmi, hotplug_work); - asus_rfkill_hotplug(asus); -} - -static int asus_setup_pci_hotplug(struct asus_wmi *asus) -{ - int ret = -ENOMEM; - struct pci_bus *bus = pci_find_bus(0, 1); - - if (!bus) { - pr_err("Unable to find wifi PCI bus\n"); - return -ENODEV; - } - - asus->hotplug_workqueue = - create_singlethread_workqueue("hotplug_workqueue"); - if (!asus->hotplug_workqueue) - goto error_workqueue; - - INIT_WORK(&asus->hotplug_work, asus_hotplug_work); - - asus->hotplug_slot = kzalloc(sizeof(struct hotplug_slot), GFP_KERNEL); - if (!asus->hotplug_slot) - goto error_slot; - - asus->hotplug_slot->info = kzalloc(sizeof(struct hotplug_slot_info), - GFP_KERNEL); - if (!asus->hotplug_slot->info) - goto error_info; - - asus->hotplug_slot->private = asus; - asus->hotplug_slot->release = &asus_cleanup_pci_hotplug; - asus->hotplug_slot->ops = &asus_hotplug_slot_ops; - asus_get_adapter_status(asus->hotplug_slot, - &asus->hotplug_slot->info->adapter_status); - - ret = pci_hp_register(asus->hotplug_slot, bus, 0, "asus-wifi"); - if (ret) { - pr_err("Unable to register hotplug slot - %d\n", ret); - goto error_register; - } - - return 0; - -error_register: - kfree(asus->hotplug_slot->info); -error_info: - kfree(asus->hotplug_slot); - asus->hotplug_slot = NULL; -error_slot: - destroy_workqueue(asus->hotplug_workqueue); -error_workqueue: - return ret; -} - -/* - * Rfkill devices - */ -static int asus_rfkill_set(void *data, bool blocked) -{ - struct asus_rfkill *priv = data; - u32 ctrl_param = !blocked; - - return asus_wmi_set_devstate(priv->dev_id, ctrl_param, NULL); -} - -static void asus_rfkill_query(struct rfkill *rfkill, void *data) -{ - struct asus_rfkill *priv = data; - int result; - - result = asus_wmi_get_devstate_simple(priv->asus, priv->dev_id); - - if (result < 0) - return; - - rfkill_set_sw_state(priv->rfkill, !result); -} - -static int asus_rfkill_wlan_set(void *data, bool blocked) -{ - struct asus_rfkill *priv = data; - struct asus_wmi *asus = priv->asus; - int ret; - - /* - * This handler is enabled only if hotplug is enabled. - * In this case, the asus_wmi_set_devstate() will - * trigger a wmi notification and we need to wait - * this call to finish before being able to call - * any wmi method - */ - mutex_lock(&asus->wmi_lock); - ret = asus_rfkill_set(data, blocked); - mutex_unlock(&asus->wmi_lock); - return ret; -} - -static const struct rfkill_ops asus_rfkill_wlan_ops = { - .set_block = asus_rfkill_wlan_set, - .query = asus_rfkill_query, -}; - -static const struct rfkill_ops asus_rfkill_ops = { - .set_block = asus_rfkill_set, - .query = asus_rfkill_query, -}; - -static int asus_new_rfkill(struct asus_wmi *asus, - struct asus_rfkill *arfkill, - const char *name, enum rfkill_type type, int dev_id) -{ - int result = asus_wmi_get_devstate_simple(asus, dev_id); - struct rfkill **rfkill = &arfkill->rfkill; - - if (result < 0) - return result; - - arfkill->dev_id = dev_id; - arfkill->asus = asus; - - if (dev_id == ASUS_WMI_DEVID_WLAN && asus->driver->hotplug_wireless) - *rfkill = rfkill_alloc(name, &asus->platform_device->dev, type, - &asus_rfkill_wlan_ops, arfkill); - else - *rfkill = rfkill_alloc(name, &asus->platform_device->dev, type, - &asus_rfkill_ops, arfkill); - - if (!*rfkill) - return -EINVAL; - - rfkill_init_sw_state(*rfkill, !result); - result = rfkill_register(*rfkill); - if (result) { - rfkill_destroy(*rfkill); - *rfkill = NULL; - return result; - } - return 0; -} - -static void asus_wmi_rfkill_exit(struct asus_wmi *asus) -{ - asus_unregister_rfkill_notifier(asus, "\\_SB.PCI0.P0P5"); - asus_unregister_rfkill_notifier(asus, "\\_SB.PCI0.P0P6"); - asus_unregister_rfkill_notifier(asus, "\\_SB.PCI0.P0P7"); - if (asus->wlan.rfkill) { - rfkill_unregister(asus->wlan.rfkill); - rfkill_destroy(asus->wlan.rfkill); - asus->wlan.rfkill = NULL; - } - /* - * Refresh pci hotplug in case the rfkill state was changed after - * asus_unregister_rfkill_notifier() - */ - asus_rfkill_hotplug(asus); - if (asus->hotplug_slot) - pci_hp_deregister(asus->hotplug_slot); - if (asus->hotplug_workqueue) - destroy_workqueue(asus->hotplug_workqueue); - - if (asus->bluetooth.rfkill) { - rfkill_unregister(asus->bluetooth.rfkill); - rfkill_destroy(asus->bluetooth.rfkill); - asus->bluetooth.rfkill = NULL; - } - if (asus->wimax.rfkill) { - rfkill_unregister(asus->wimax.rfkill); - rfkill_destroy(asus->wimax.rfkill); - asus->wimax.rfkill = NULL; - } - if (asus->wwan3g.rfkill) { - rfkill_unregister(asus->wwan3g.rfkill); - rfkill_destroy(asus->wwan3g.rfkill); - asus->wwan3g.rfkill = NULL; - } -} - -static int asus_wmi_rfkill_init(struct asus_wmi *asus) -{ - int result = 0; - - mutex_init(&asus->hotplug_lock); - mutex_init(&asus->wmi_lock); - - result = asus_new_rfkill(asus, &asus->wlan, "asus-wlan", - RFKILL_TYPE_WLAN, ASUS_WMI_DEVID_WLAN); - - if (result && result != -ENODEV) - goto exit; - - result = asus_new_rfkill(asus, &asus->bluetooth, - "asus-bluetooth", RFKILL_TYPE_BLUETOOTH, - ASUS_WMI_DEVID_BLUETOOTH); - - if (result && result != -ENODEV) - goto exit; - - result = asus_new_rfkill(asus, &asus->wimax, "asus-wimax", - RFKILL_TYPE_WIMAX, ASUS_WMI_DEVID_WIMAX); - - if (result && result != -ENODEV) - goto exit; - - result = asus_new_rfkill(asus, &asus->wwan3g, "asus-wwan3g", - RFKILL_TYPE_WWAN, ASUS_WMI_DEVID_WWAN3G); - - if (result && result != -ENODEV) - goto exit; - - if (!asus->driver->hotplug_wireless) - goto exit; - - result = asus_setup_pci_hotplug(asus); - /* - * If we get -EBUSY then something else is handling the PCI hotplug - - * don't fail in this case - */ - if (result == -EBUSY) - result = 0; - - asus_register_rfkill_notifier(asus, "\\_SB.PCI0.P0P5"); - asus_register_rfkill_notifier(asus, "\\_SB.PCI0.P0P6"); - asus_register_rfkill_notifier(asus, "\\_SB.PCI0.P0P7"); - /* - * Refresh pci hotplug in case the rfkill state was changed during - * setup. - */ - asus_rfkill_hotplug(asus); - -exit: - if (result && result != -ENODEV) - asus_wmi_rfkill_exit(asus); - - if (result == -ENODEV) - result = 0; - - return result; -} - -/* - * Hwmon device - */ -static ssize_t asus_hwmon_pwm1(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - struct asus_wmi *asus = dev_get_drvdata(dev); - u32 value; - int err; - - err = asus_wmi_get_devstate(asus, ASUS_WMI_DEVID_FAN_CTRL, &value); - - if (err < 0) - return err; - - value |= 0xFF; - - if (value == 1) /* Low Speed */ - value = 85; - else if (value == 2) - value = 170; - else if (value == 3) - value = 255; - else if (value != 0) { - pr_err("Unknown fan speed %#x", value); - value = -1; - } - - return sprintf(buf, "%d\n", value); -} - -static SENSOR_DEVICE_ATTR(pwm1, S_IRUGO, asus_hwmon_pwm1, NULL, 0); - -static ssize_t -show_name(struct device *dev, struct device_attribute *attr, char *buf) -{ - return sprintf(buf, "asus\n"); -} -static SENSOR_DEVICE_ATTR(name, S_IRUGO, show_name, NULL, 0); - -static struct attribute *hwmon_attributes[] = { - &sensor_dev_attr_pwm1.dev_attr.attr, - &sensor_dev_attr_name.dev_attr.attr, - NULL -}; - -static mode_t asus_hwmon_sysfs_is_visible(struct kobject *kobj, - struct attribute *attr, int idx) -{ - struct device *dev = container_of(kobj, struct device, kobj); - struct platform_device *pdev = to_platform_device(dev->parent); - struct asus_wmi *asus = platform_get_drvdata(pdev); - bool ok = true; - int dev_id = -1; - u32 value = ASUS_WMI_UNSUPPORTED_METHOD; - - if (attr == &sensor_dev_attr_pwm1.dev_attr.attr) - dev_id = ASUS_WMI_DEVID_FAN_CTRL; - - if (dev_id != -1) { - int err = asus_wmi_get_devstate(asus, dev_id, &value); - - if (err < 0) - return err; - } - - if (dev_id == ASUS_WMI_DEVID_FAN_CTRL) { - /* - * We need to find a better way, probably using sfun, - * bits or spec ... - * Currently we disable it if: - * - ASUS_WMI_UNSUPPORTED_METHOD is returned - * - reverved bits are non-zero - * - sfun and presence bit are not set - */ - if (value != ASUS_WMI_UNSUPPORTED_METHOD || value & 0xFFF80000 - || (!asus->sfun && !(value & ASUS_WMI_DSTS_PRESENCE_BIT))) - ok = false; - } - - return ok ? attr->mode : 0; -} - -static struct attribute_group hwmon_attribute_group = { - .is_visible = asus_hwmon_sysfs_is_visible, - .attrs = hwmon_attributes -}; - -static void asus_wmi_hwmon_exit(struct asus_wmi *asus) -{ - struct device *hwmon; - - hwmon = asus->hwmon_device; - if (!hwmon) - return; - sysfs_remove_group(&hwmon->kobj, &hwmon_attribute_group); - hwmon_device_unregister(hwmon); - asus->hwmon_device = NULL; -} - -static int asus_wmi_hwmon_init(struct asus_wmi *asus) -{ - struct device *hwmon; - int result; - - hwmon = hwmon_device_register(&asus->platform_device->dev); - if (IS_ERR(hwmon)) { - pr_err("Could not register asus hwmon device\n"); - return PTR_ERR(hwmon); - } - asus->hwmon_device = hwmon; - result = sysfs_create_group(&hwmon->kobj, &hwmon_attribute_group); - if (result) - asus_wmi_hwmon_exit(asus); - return result; -} - -/* - * Backlight - */ -static int read_backlight_power(struct asus_wmi *asus) -{ - int ret = asus_wmi_get_devstate_simple(asus, ASUS_WMI_DEVID_BACKLIGHT); - - if (ret < 0) - return ret; - - return ret ? FB_BLANK_UNBLANK : FB_BLANK_POWERDOWN; -} - -static int read_brightness_max(struct asus_wmi *asus) -{ - u32 retval; - int err; - - err = asus_wmi_get_devstate(asus, ASUS_WMI_DEVID_BRIGHTNESS, &retval); - - if (err < 0) - return err; - - retval = retval & ASUS_WMI_DSTS_MAX_BRIGTH_MASK; - retval >>= 8; - - if (!retval) - return -ENODEV; - - return retval; -} - -static int read_brightness(struct backlight_device *bd) -{ - struct asus_wmi *asus = bl_get_data(bd); - u32 retval; - int err; - - err = asus_wmi_get_devstate(asus, ASUS_WMI_DEVID_BRIGHTNESS, &retval); - - if (err < 0) - return err; - - return retval & ASUS_WMI_DSTS_BRIGHTNESS_MASK; -} - -static int update_bl_status(struct backlight_device *bd) -{ - struct asus_wmi *asus = bl_get_data(bd); - u32 ctrl_param; - int power, err; - - ctrl_param = bd->props.brightness; - - err = asus_wmi_set_devstate(ASUS_WMI_DEVID_BRIGHTNESS, - ctrl_param, NULL); - - if (err < 0) - return err; - - power = read_backlight_power(asus); - if (power != -ENODEV && bd->props.power != power) { - ctrl_param = !!(bd->props.power == FB_BLANK_UNBLANK); - err = asus_wmi_set_devstate(ASUS_WMI_DEVID_BACKLIGHT, - ctrl_param, NULL); - } - return err; -} - -static const struct backlight_ops asus_wmi_bl_ops = { - .get_brightness = read_brightness, - .update_status = update_bl_status, -}; - -static int asus_wmi_backlight_notify(struct asus_wmi *asus, int code) -{ - struct backlight_device *bd = asus->backlight_device; - int old = bd->props.brightness; - int new = old; - - if (code >= NOTIFY_BRNUP_MIN && code <= NOTIFY_BRNUP_MAX) - new = code - NOTIFY_BRNUP_MIN + 1; - else if (code >= NOTIFY_BRNDOWN_MIN && code <= NOTIFY_BRNDOWN_MAX) - new = code - NOTIFY_BRNDOWN_MIN; - - bd->props.brightness = new; - backlight_update_status(bd); - backlight_force_update(bd, BACKLIGHT_UPDATE_HOTKEY); - - return old; -} - -static int asus_wmi_backlight_init(struct asus_wmi *asus) -{ - struct backlight_device *bd; - struct backlight_properties props; - int max; - int power; - - max = read_brightness_max(asus); - - if (max == -ENODEV) - max = 0; - else if (max < 0) - return max; - - power = read_backlight_power(asus); - - if (power == -ENODEV) - power = FB_BLANK_UNBLANK; - else if (power < 0) - return power; - - memset(&props, 0, sizeof(struct backlight_properties)); - props.max_brightness = max; - bd = backlight_device_register(asus->driver->name, - &asus->platform_device->dev, asus, - &asus_wmi_bl_ops, &props); - if (IS_ERR(bd)) { - pr_err("Could not register backlight device\n"); - return PTR_ERR(bd); - } - - asus->backlight_device = bd; - - bd->props.brightness = read_brightness(bd); - bd->props.power = power; - backlight_update_status(bd); - - return 0; -} - -static void asus_wmi_backlight_exit(struct asus_wmi *asus) -{ - if (asus->backlight_device) - backlight_device_unregister(asus->backlight_device); - - asus->backlight_device = NULL; -} - -static void asus_wmi_notify(u32 value, void *context) -{ - struct asus_wmi *asus = context; - struct acpi_buffer response = { ACPI_ALLOCATE_BUFFER, NULL }; - union acpi_object *obj; - acpi_status status; - int code; - int orig_code; - - status = wmi_get_event_data(value, &response); - if (status != AE_OK) { - pr_err("bad event status 0x%x\n", status); - return; - } - - obj = (union acpi_object *)response.pointer; - - if (!obj || obj->type != ACPI_TYPE_INTEGER) - goto exit; - - code = obj->integer.value; - orig_code = code; - - if (code >= NOTIFY_BRNUP_MIN && code <= NOTIFY_BRNUP_MAX) - code = NOTIFY_BRNUP_MIN; - else if (code >= NOTIFY_BRNDOWN_MIN && - code <= NOTIFY_BRNDOWN_MAX) - code = NOTIFY_BRNDOWN_MIN; - - if (code == NOTIFY_BRNUP_MIN || code == NOTIFY_BRNDOWN_MIN) { - if (!acpi_video_backlight_support()) - asus_wmi_backlight_notify(asus, orig_code); - } else if (!sparse_keymap_report_event(asus->inputdev, code, 1, true)) - pr_info("Unknown key %x pressed\n", code); - -exit: - kfree(obj); -} - -/* - * Sys helpers - */ -static int parse_arg(const char *buf, unsigned long count, int *val) -{ - if (!count) - return 0; - if (sscanf(buf, "%i", val) != 1) - return -EINVAL; - return count; -} - -static ssize_t store_sys_wmi(struct asus_wmi *asus, int devid, - const char *buf, size_t count) -{ - u32 retval; - int rv, err, value; - - value = asus_wmi_get_devstate_simple(asus, devid); - if (value == -ENODEV) /* Check device presence */ - return value; - - rv = parse_arg(buf, count, &value); - err = asus_wmi_set_devstate(devid, value, &retval); - - if (err < 0) - return err; - - return rv; -} - -static ssize_t show_sys_wmi(struct asus_wmi *asus, int devid, char *buf) -{ - int value = asus_wmi_get_devstate_simple(asus, devid); - - if (value < 0) - return value; - - return sprintf(buf, "%d\n", value); -} - -#define ASUS_WMI_CREATE_DEVICE_ATTR(_name, _mode, _cm) \ - static ssize_t show_##_name(struct device *dev, \ - struct device_attribute *attr, \ - char *buf) \ - { \ - struct asus_wmi *asus = dev_get_drvdata(dev); \ - \ - return show_sys_wmi(asus, _cm, buf); \ - } \ - static ssize_t store_##_name(struct device *dev, \ - struct device_attribute *attr, \ - const char *buf, size_t count) \ - { \ - struct asus_wmi *asus = dev_get_drvdata(dev); \ - \ - return store_sys_wmi(asus, _cm, buf, count); \ - } \ - static struct device_attribute dev_attr_##_name = { \ - .attr = { \ - .name = __stringify(_name), \ - .mode = _mode }, \ - .show = show_##_name, \ - .store = store_##_name, \ - } - -ASUS_WMI_CREATE_DEVICE_ATTR(touchpad, 0644, ASUS_WMI_DEVID_TOUCHPAD); -ASUS_WMI_CREATE_DEVICE_ATTR(camera, 0644, ASUS_WMI_DEVID_CAMERA); -ASUS_WMI_CREATE_DEVICE_ATTR(cardr, 0644, ASUS_WMI_DEVID_CARDREADER); - -static ssize_t store_cpufv(struct device *dev, struct device_attribute *attr, - const char *buf, size_t count) -{ - int value; - - if (!count || sscanf(buf, "%i", &value) != 1) - return -EINVAL; - if (value < 0 || value > 2) - return -EINVAL; - - return asus_wmi_evaluate_method(ASUS_WMI_METHODID_CFVS, value, 0, NULL); -} - -static DEVICE_ATTR(cpufv, S_IRUGO | S_IWUSR, NULL, store_cpufv); - -static struct attribute *platform_attributes[] = { - &dev_attr_cpufv.attr, - &dev_attr_camera.attr, - &dev_attr_cardr.attr, - &dev_attr_touchpad.attr, - NULL -}; - -static mode_t asus_sysfs_is_visible(struct kobject *kobj, - struct attribute *attr, int idx) -{ - struct device *dev = container_of(kobj, struct device, kobj); - struct platform_device *pdev = to_platform_device(dev); - struct asus_wmi *asus = platform_get_drvdata(pdev); - bool ok = true; - int devid = -1; - - if (attr == &dev_attr_camera.attr) - devid = ASUS_WMI_DEVID_CAMERA; - else if (attr == &dev_attr_cardr.attr) - devid = ASUS_WMI_DEVID_CARDREADER; - else if (attr == &dev_attr_touchpad.attr) - devid = ASUS_WMI_DEVID_TOUCHPAD; - - if (devid != -1) - ok = !(asus_wmi_get_devstate_simple(asus, devid) < 0); - - return ok ? attr->mode : 0; -} - -static struct attribute_group platform_attribute_group = { - .is_visible = asus_sysfs_is_visible, - .attrs = platform_attributes -}; - -static void asus_wmi_sysfs_exit(struct platform_device *device) -{ - sysfs_remove_group(&device->dev.kobj, &platform_attribute_group); -} - -static int asus_wmi_sysfs_init(struct platform_device *device) -{ - return sysfs_create_group(&device->dev.kobj, &platform_attribute_group); -} - -/* - * Platform device - */ -static int __init asus_wmi_platform_init(struct asus_wmi *asus) -{ - int rv; - - /* INIT enable hotkeys on some models */ - if (!asus_wmi_evaluate_method(ASUS_WMI_METHODID_INIT, 0, 0, &rv)) - pr_info("Initialization: %#x", rv); - - /* We don't know yet what to do with this version... */ - if (!asus_wmi_evaluate_method(ASUS_WMI_METHODID_SPEC, 0, 0x9, &rv)) { - pr_info("BIOS WMI version: %d.%d", rv >> 8, rv & 0xFF); - asus->spec = rv; - } - - /* - * The SFUN method probably allows the original driver to get the list - * of features supported by a given model. For now, 0x0100 or 0x0800 - * bit signifies that the laptop is equipped with a Wi-Fi MiniPCI card. - * The significance of others is yet to be found. - */ - if (!asus_wmi_evaluate_method(ASUS_WMI_METHODID_SFUN, 0, 0, &rv)) { - pr_info("SFUN value: %#x", rv); - asus->sfun = rv; - } - - /* - * Eee PC and Notebooks seems to have different method_id for DSTS, - * but it may also be related to the BIOS's SPEC. - * Note, on most Eeepc, there is no way to check if a method exist - * or note, while on notebooks, they returns 0xFFFFFFFE on failure, - * but once again, SPEC may probably be used for that kind of things. - */ - if (!asus_wmi_evaluate_method(ASUS_WMI_METHODID_DSTS, 0, 0, NULL)) - asus->dsts_id = ASUS_WMI_METHODID_DSTS; - else if (!asus_wmi_evaluate_method(ASUS_WMI_METHODID_DSTS2, 0, 0, NULL)) - asus->dsts_id = ASUS_WMI_METHODID_DSTS2; - - if (!asus->dsts_id) { - pr_err("Can't find DSTS"); - return -ENODEV; - } - - return asus_wmi_sysfs_init(asus->platform_device); -} - -static void asus_wmi_platform_exit(struct asus_wmi *asus) -{ - asus_wmi_sysfs_exit(asus->platform_device); -} - -/* - * debugfs - */ -struct asus_wmi_debugfs_node { - struct asus_wmi *asus; - char *name; - int (*show) (struct seq_file *m, void *data); -}; - -static int show_dsts(struct seq_file *m, void *data) -{ - struct asus_wmi *asus = m->private; - int err; - u32 retval = -1; - - err = asus_wmi_get_devstate(asus, asus->debug.dev_id, &retval); - - if (err < 0) - return err; - - seq_printf(m, "DSTS(%#x) = %#x\n", asus->debug.dev_id, retval); - - return 0; -} - -static int show_devs(struct seq_file *m, void *data) -{ - struct asus_wmi *asus = m->private; - int err; - u32 retval = -1; - - err = asus_wmi_set_devstate(asus->debug.dev_id, asus->debug.ctrl_param, - &retval); - - if (err < 0) - return err; - - seq_printf(m, "DEVS(%#x, %#x) = %#x\n", asus->debug.dev_id, - asus->debug.ctrl_param, retval); - - return 0; -} - -static int show_call(struct seq_file *m, void *data) -{ - struct asus_wmi *asus = m->private; - struct bios_args args = { - .arg0 = asus->debug.dev_id, - .arg1 = asus->debug.ctrl_param, - }; - struct acpi_buffer input = { (acpi_size) sizeof(args), &args }; - struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL }; - union acpi_object *obj; - acpi_status status; - - status = wmi_evaluate_method(ASUS_WMI_MGMT_GUID, - 1, asus->debug.method_id, - &input, &output); - - if (ACPI_FAILURE(status)) - return -EIO; - - obj = (union acpi_object *)output.pointer; - if (obj && obj->type == ACPI_TYPE_INTEGER) - seq_printf(m, "%#x(%#x, %#x) = %#x\n", asus->debug.method_id, - asus->debug.dev_id, asus->debug.ctrl_param, - (u32) obj->integer.value); - else - seq_printf(m, "%#x(%#x, %#x) = t:%d\n", asus->debug.method_id, - asus->debug.dev_id, asus->debug.ctrl_param, - obj ? obj->type : -1); - - kfree(obj); - - return 0; -} - -static struct asus_wmi_debugfs_node asus_wmi_debug_files[] = { - {NULL, "devs", show_devs}, - {NULL, "dsts", show_dsts}, - {NULL, "call", show_call}, -}; - -static int asus_wmi_debugfs_open(struct inode *inode, struct file *file) -{ - struct asus_wmi_debugfs_node *node = inode->i_private; - - return single_open(file, node->show, node->asus); -} - -static const struct file_operations asus_wmi_debugfs_io_ops = { - .owner = THIS_MODULE, - .open = asus_wmi_debugfs_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; - -static void asus_wmi_debugfs_exit(struct asus_wmi *asus) -{ - debugfs_remove_recursive(asus->debug.root); -} - -static int asus_wmi_debugfs_init(struct asus_wmi *asus) -{ - struct dentry *dent; - int i; - - asus->debug.root = debugfs_create_dir(asus->driver->name, NULL); - if (!asus->debug.root) { - pr_err("failed to create debugfs directory"); - goto error_debugfs; - } - - dent = debugfs_create_x32("method_id", S_IRUGO | S_IWUSR, - asus->debug.root, &asus->debug.method_id); - if (!dent) - goto error_debugfs; - - dent = debugfs_create_x32("dev_id", S_IRUGO | S_IWUSR, - asus->debug.root, &asus->debug.dev_id); - if (!dent) - goto error_debugfs; - - dent = debugfs_create_x32("ctrl_param", S_IRUGO | S_IWUSR, - asus->debug.root, &asus->debug.ctrl_param); - if (!dent) - goto error_debugfs; - - for (i = 0; i < ARRAY_SIZE(asus_wmi_debug_files); i++) { - struct asus_wmi_debugfs_node *node = &asus_wmi_debug_files[i]; - - node->asus = asus; - dent = debugfs_create_file(node->name, S_IFREG | S_IRUGO, - asus->debug.root, node, - &asus_wmi_debugfs_io_ops); - if (!dent) { - pr_err("failed to create debug file: %s\n", node->name); - goto error_debugfs; - } - } - - return 0; - -error_debugfs: - asus_wmi_debugfs_exit(asus); - return -ENOMEM; -} - -/* - * WMI Driver - */ -static int asus_wmi_add(struct platform_device *pdev) -{ - struct platform_driver *pdrv = to_platform_driver(pdev->dev.driver); - struct asus_wmi_driver *wdrv = to_asus_wmi_driver(pdrv); - struct asus_wmi *asus; - acpi_status status; - int err; - - asus = kzalloc(sizeof(struct asus_wmi), GFP_KERNEL); - if (!asus) - return -ENOMEM; - - asus->driver = wdrv; - asus->platform_device = pdev; - wdrv->platform_device = pdev; - platform_set_drvdata(asus->platform_device, asus); - - if (wdrv->quirks) - wdrv->quirks(asus->driver); - - err = asus_wmi_platform_init(asus); - if (err) - goto fail_platform; - - err = asus_wmi_input_init(asus); - if (err) - goto fail_input; - - err = asus_wmi_hwmon_init(asus); - if (err) - goto fail_hwmon; - - err = asus_wmi_led_init(asus); - if (err) - goto fail_leds; - - err = asus_wmi_rfkill_init(asus); - if (err) - goto fail_rfkill; - - if (!acpi_video_backlight_support()) { - err = asus_wmi_backlight_init(asus); - if (err && err != -ENODEV) - goto fail_backlight; - } else - pr_info("Backlight controlled by ACPI video driver\n"); - - status = wmi_install_notify_handler(asus->driver->event_guid, - asus_wmi_notify, asus); - if (ACPI_FAILURE(status)) { - pr_err("Unable to register notify handler - %d\n", status); - err = -ENODEV; - goto fail_wmi_handler; - } - - err = asus_wmi_debugfs_init(asus); - if (err) - goto fail_debugfs; - - return 0; - -fail_debugfs: - wmi_remove_notify_handler(asus->driver->event_guid); -fail_wmi_handler: - asus_wmi_backlight_exit(asus); -fail_backlight: - asus_wmi_rfkill_exit(asus); -fail_rfkill: - asus_wmi_led_exit(asus); -fail_leds: - asus_wmi_hwmon_exit(asus); -fail_hwmon: - asus_wmi_input_exit(asus); -fail_input: - asus_wmi_platform_exit(asus); -fail_platform: - kfree(asus); - return err; -} - -static int asus_wmi_remove(struct platform_device *device) -{ - struct asus_wmi *asus; - - asus = platform_get_drvdata(device); - wmi_remove_notify_handler(asus->driver->event_guid); - asus_wmi_backlight_exit(asus); - asus_wmi_input_exit(asus); - asus_wmi_hwmon_exit(asus); - asus_wmi_led_exit(asus); - asus_wmi_rfkill_exit(asus); - asus_wmi_debugfs_exit(asus); - asus_wmi_platform_exit(asus); - - kfree(asus); - return 0; -} - -/* - * Platform driver - hibernate/resume callbacks - */ -static int asus_hotk_thaw(struct device *device) -{ - struct asus_wmi *asus = dev_get_drvdata(device); - - if (asus->wlan.rfkill) { - bool wlan; - - /* - * Work around bios bug - acpi _PTS turns off the wireless led - * during suspend. Normally it restores it on resume, but - * we should kick it ourselves in case hibernation is aborted. - */ - wlan = asus_wmi_get_devstate_simple(asus, ASUS_WMI_DEVID_WLAN); - asus_wmi_set_devstate(ASUS_WMI_DEVID_WLAN, wlan, NULL); - } - - return 0; -} - -static int asus_hotk_restore(struct device *device) -{ - struct asus_wmi *asus = dev_get_drvdata(device); - int bl; - - /* Refresh both wlan rfkill state and pci hotplug */ - if (asus->wlan.rfkill) - asus_rfkill_hotplug(asus); - - if (asus->bluetooth.rfkill) { - bl = !asus_wmi_get_devstate_simple(asus, - ASUS_WMI_DEVID_BLUETOOTH); - rfkill_set_sw_state(asus->bluetooth.rfkill, bl); - } - if (asus->wimax.rfkill) { - bl = !asus_wmi_get_devstate_simple(asus, ASUS_WMI_DEVID_WIMAX); - rfkill_set_sw_state(asus->wimax.rfkill, bl); - } - if (asus->wwan3g.rfkill) { - bl = !asus_wmi_get_devstate_simple(asus, ASUS_WMI_DEVID_WWAN3G); - rfkill_set_sw_state(asus->wwan3g.rfkill, bl); - } - - return 0; -} - -static const struct dev_pm_ops asus_pm_ops = { - .thaw = asus_hotk_thaw, - .restore = asus_hotk_restore, -}; - -static int asus_wmi_probe(struct platform_device *pdev) -{ - struct platform_driver *pdrv = to_platform_driver(pdev->dev.driver); - struct asus_wmi_driver *wdrv = to_asus_wmi_driver(pdrv); - int ret; - - if (!wmi_has_guid(ASUS_WMI_MGMT_GUID)) { - pr_warning("Management GUID not found\n"); - return -ENODEV; - } - - if (wdrv->event_guid && !wmi_has_guid(wdrv->event_guid)) { - pr_warning("Event GUID not found\n"); - return -ENODEV; - } - - if (wdrv->probe) { - ret = wdrv->probe(pdev); - if (ret) - return ret; - } - - return asus_wmi_add(pdev); -} - -static bool used; - -int asus_wmi_register_driver(struct asus_wmi_driver *driver) -{ - struct platform_driver *platform_driver; - struct platform_device *platform_device; - - if (used) - return -EBUSY; - - platform_driver = &driver->platform_driver; - platform_driver->remove = asus_wmi_remove; - platform_driver->driver.owner = driver->owner; - platform_driver->driver.name = driver->name; - platform_driver->driver.pm = &asus_pm_ops; - - platform_device = platform_create_bundle(platform_driver, - asus_wmi_probe, - NULL, 0, NULL, 0); - if (IS_ERR(platform_device)) - return PTR_ERR(platform_device); - - used = true; - return 0; -} -EXPORT_SYMBOL_GPL(asus_wmi_register_driver); - -void asus_wmi_unregister_driver(struct asus_wmi_driver *driver) -{ - platform_device_unregister(driver->platform_device); - platform_driver_unregister(&driver->platform_driver); - used = false; -} -EXPORT_SYMBOL_GPL(asus_wmi_unregister_driver); - -static int __init asus_wmi_init(void) -{ - if (!wmi_has_guid(ASUS_WMI_MGMT_GUID)) { - pr_info("Asus Management GUID not found"); - return -ENODEV; - } - - pr_info("ASUS WMI generic driver loaded"); - return 0; -} - -static void __exit asus_wmi_exit(void) -{ - pr_info("ASUS WMI generic driver unloaded"); -} - -module_init(asus_wmi_init); -module_exit(asus_wmi_exit); diff --git a/trunk/drivers/platform/x86/asus-wmi.h b/trunk/drivers/platform/x86/asus-wmi.h deleted file mode 100644 index c044522c8766..000000000000 --- a/trunk/drivers/platform/x86/asus-wmi.h +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Asus PC WMI hotkey driver - * - * Copyright(C) 2010 Intel Corporation. - * Copyright(C) 2010-2011 Corentin Chary - * - * Portions based on wistron_btns.c: - * Copyright (C) 2005 Miloslav Trmac - * Copyright (C) 2005 Bernhard Rosenkraenzer - * Copyright (C) 2005 Dmitry Torokhov - * - * 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 - */ - -#ifndef _ASUS_WMI_H_ -#define _ASUS_WMI_H_ - -#include - -struct module; -struct key_entry; -struct asus_wmi; - -struct asus_wmi_driver { - bool hotplug_wireless; - - const char *name; - struct module *owner; - - const char *event_guid; - - const struct key_entry *keymap; - const char *input_name; - const char *input_phys; - - int (*probe) (struct platform_device *device); - void (*quirks) (struct asus_wmi_driver *driver); - - struct platform_driver platform_driver; - struct platform_device *platform_device; -}; - -int asus_wmi_register_driver(struct asus_wmi_driver *driver); -void asus_wmi_unregister_driver(struct asus_wmi_driver *driver); - -#endif /* !_ASUS_WMI_H_ */ diff --git a/trunk/drivers/platform/x86/compal-laptop.c b/trunk/drivers/platform/x86/compal-laptop.c index c16a27641ced..eb95878fa583 100644 --- a/trunk/drivers/platform/x86/compal-laptop.c +++ b/trunk/drivers/platform/x86/compal-laptop.c @@ -201,7 +201,7 @@ static bool extra_features; * into 0x4F and read a few bytes from the output, like so: * u8 writeData = 0x33; * ec_transaction(0x4F, &writeData, 1, buffer, 32, 0); - * That address is labelled "fan1 table information" in the service manual. + * That address is labled "fan1 table information" in the service manual. * It should be clear which value in 'buffer' changes). This seems to be * related to fan speed. It isn't a proper 'realtime' fan speed value * though, because physically stopping or speeding up the fan doesn't @@ -275,7 +275,7 @@ static int set_backlight_level(int level) ec_write(BACKLIGHT_LEVEL_ADDR, level); - return 0; + return 1; } static int get_backlight_level(void) @@ -763,7 +763,7 @@ static int dmi_check_cb(const struct dmi_system_id *id) printk(KERN_INFO DRIVER_NAME": Identified laptop model '%s'\n", id->ident); extra_features = false; - return 1; + return 0; } static int dmi_check_cb_extra(const struct dmi_system_id *id) @@ -772,7 +772,7 @@ static int dmi_check_cb_extra(const struct dmi_system_id *id) "enabling extra features\n", id->ident); extra_features = true; - return 1; + return 0; } static struct dmi_system_id __initdata compal_dmi_table[] = { diff --git a/trunk/drivers/platform/x86/dell-wmi-aio.c b/trunk/drivers/platform/x86/dell-wmi-aio.c deleted file mode 100644 index 0ed84573ae1f..000000000000 --- a/trunk/drivers/platform/x86/dell-wmi-aio.c +++ /dev/null @@ -1,171 +0,0 @@ -/* - * WMI hotkeys support for Dell All-In-One series - * - * 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 - */ -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -MODULE_DESCRIPTION("WMI hotkeys driver for Dell All-In-One series"); -MODULE_LICENSE("GPL"); - -#define EVENT_GUID1 "284A0E6B-380E-472A-921F-E52786257FB4" -#define EVENT_GUID2 "02314822-307C-4F66-BF0E-48AEAEB26CC8" - -static const char *dell_wmi_aio_guids[] = { - EVENT_GUID1, - EVENT_GUID2, - NULL -}; - -MODULE_ALIAS("wmi:"EVENT_GUID1); -MODULE_ALIAS("wmi:"EVENT_GUID2); - -static const struct key_entry dell_wmi_aio_keymap[] = { - { KE_KEY, 0xc0, { KEY_VOLUMEUP } }, - { KE_KEY, 0xc1, { KEY_VOLUMEDOWN } }, - { KE_END, 0 } -}; - -static struct input_dev *dell_wmi_aio_input_dev; - -static void dell_wmi_aio_notify(u32 value, void *context) -{ - struct acpi_buffer response = { ACPI_ALLOCATE_BUFFER, NULL }; - union acpi_object *obj; - acpi_status status; - - status = wmi_get_event_data(value, &response); - if (status != AE_OK) { - pr_info("bad event status 0x%x\n", status); - return; - } - - obj = (union acpi_object *)response.pointer; - if (obj) { - unsigned int scancode; - - switch (obj->type) { - case ACPI_TYPE_INTEGER: - /* Most All-In-One correctly return integer scancode */ - scancode = obj->integer.value; - sparse_keymap_report_event(dell_wmi_aio_input_dev, - scancode, 1, true); - break; - case ACPI_TYPE_BUFFER: - /* Broken machines return the scancode in a buffer */ - if (obj->buffer.pointer && obj->buffer.length > 0) { - scancode = obj->buffer.pointer[0]; - sparse_keymap_report_event( - dell_wmi_aio_input_dev, - scancode, 1, true); - } - break; - } - } - kfree(obj); -} - -static int __init dell_wmi_aio_input_setup(void) -{ - int err; - - dell_wmi_aio_input_dev = input_allocate_device(); - - if (!dell_wmi_aio_input_dev) - return -ENOMEM; - - dell_wmi_aio_input_dev->name = "Dell AIO WMI hotkeys"; - dell_wmi_aio_input_dev->phys = "wmi/input0"; - dell_wmi_aio_input_dev->id.bustype = BUS_HOST; - - err = sparse_keymap_setup(dell_wmi_aio_input_dev, - dell_wmi_aio_keymap, NULL); - if (err) { - pr_err("Unable to setup input device keymap\n"); - goto err_free_dev; - } - err = input_register_device(dell_wmi_aio_input_dev); - if (err) { - pr_info("Unable to register input device\n"); - goto err_free_keymap; - } - return 0; - -err_free_keymap: - sparse_keymap_free(dell_wmi_aio_input_dev); -err_free_dev: - input_free_device(dell_wmi_aio_input_dev); - return err; -} - -static const char *dell_wmi_aio_find(void) -{ - int i; - - for (i = 0; dell_wmi_aio_guids[i] != NULL; i++) - if (wmi_has_guid(dell_wmi_aio_guids[i])) - return dell_wmi_aio_guids[i]; - - return NULL; -} - -static int __init dell_wmi_aio_init(void) -{ - int err; - const char *guid; - - guid = dell_wmi_aio_find(); - if (!guid) { - pr_warning("No known WMI GUID found\n"); - return -ENXIO; - } - - err = dell_wmi_aio_input_setup(); - if (err) - return err; - - err = wmi_install_notify_handler(guid, dell_wmi_aio_notify, NULL); - if (err) { - pr_err("Unable to register notify handler - %d\n", err); - sparse_keymap_free(dell_wmi_aio_input_dev); - input_unregister_device(dell_wmi_aio_input_dev); - return err; - } - - return 0; -} - -static void __exit dell_wmi_aio_exit(void) -{ - const char *guid; - - guid = dell_wmi_aio_find(); - wmi_remove_notify_handler(guid); - sparse_keymap_free(dell_wmi_aio_input_dev); - input_unregister_device(dell_wmi_aio_input_dev); -} - -module_init(dell_wmi_aio_init); -module_exit(dell_wmi_aio_exit); diff --git a/trunk/drivers/platform/x86/eeepc-laptop.c b/trunk/drivers/platform/x86/eeepc-laptop.c index 5f2dd386152b..6605beac0d0e 100644 --- a/trunk/drivers/platform/x86/eeepc-laptop.c +++ b/trunk/drivers/platform/x86/eeepc-laptop.c @@ -1322,7 +1322,7 @@ static void cmsg_quirk(struct eeepc_laptop *eeepc, int cm, const char *name) { int dummy; - /* Some BIOSes do not report cm although it is available. + /* Some BIOSes do not report cm although it is avaliable. Check if cm_getv[cm] works and, if yes, assume cm should be set. */ if (!(eeepc->cm_supported & (1 << cm)) && !read_acpi_int(eeepc->handle, cm_getv[cm], &dummy)) { diff --git a/trunk/drivers/platform/x86/eeepc-wmi.c b/trunk/drivers/platform/x86/eeepc-wmi.c index 0ddc434fb93b..4d38f98aa976 100644 --- a/trunk/drivers/platform/x86/eeepc-wmi.c +++ b/trunk/drivers/platform/x86/eeepc-wmi.c @@ -2,7 +2,7 @@ * Eee PC WMI hotkey driver * * Copyright(C) 2010 Intel Corporation. - * Copyright(C) 2010-2011 Corentin Chary + * Copyright(C) 2010 Corentin Chary * * Portions based on wistron_btns.c: * Copyright (C) 2005 Miloslav Trmac @@ -29,57 +29,841 @@ #include #include #include +#include +#include #include #include -#include +#include +#include +#include +#include +#include +#include +#include #include - -#include "asus-wmi.h" +#include #define EEEPC_WMI_FILE "eeepc-wmi" -MODULE_AUTHOR("Corentin Chary "); +MODULE_AUTHOR("Yong Wang "); MODULE_DESCRIPTION("Eee PC WMI Hotkey Driver"); MODULE_LICENSE("GPL"); #define EEEPC_ACPI_HID "ASUS010" /* old _HID used in eeepc-laptop */ #define EEEPC_WMI_EVENT_GUID "ABBC0F72-8EA1-11D1-00A0-C90629100000" +#define EEEPC_WMI_MGMT_GUID "97845ED0-4E6D-11DE-8A39-0800200C9A66" MODULE_ALIAS("wmi:"EEEPC_WMI_EVENT_GUID); +MODULE_ALIAS("wmi:"EEEPC_WMI_MGMT_GUID); + +#define NOTIFY_BRNUP_MIN 0x11 +#define NOTIFY_BRNUP_MAX 0x1f +#define NOTIFY_BRNDOWN_MIN 0x20 +#define NOTIFY_BRNDOWN_MAX 0x2e -static bool hotplug_wireless; +#define EEEPC_WMI_METHODID_DEVS 0x53564544 +#define EEEPC_WMI_METHODID_DSTS 0x53544344 +#define EEEPC_WMI_METHODID_CFVS 0x53564643 -module_param(hotplug_wireless, bool, 0444); -MODULE_PARM_DESC(hotplug_wireless, - "Enable hotplug for wireless device. " - "If your laptop needs that, please report to " - "acpi4asus-user@lists.sourceforge.net."); +#define EEEPC_WMI_DEVID_BACKLIGHT 0x00050012 +#define EEEPC_WMI_DEVID_TPDLED 0x00100011 +#define EEEPC_WMI_DEVID_WLAN 0x00010011 +#define EEEPC_WMI_DEVID_BLUETOOTH 0x00010013 +#define EEEPC_WMI_DEVID_WWAN3G 0x00010019 static const struct key_entry eeepc_wmi_keymap[] = { /* Sleep already handled via generic ACPI code */ - { KE_KEY, 0x30, { KEY_VOLUMEUP } }, - { KE_KEY, 0x31, { KEY_VOLUMEDOWN } }, - { KE_KEY, 0x32, { KEY_MUTE } }, - { KE_KEY, 0x5c, { KEY_F15 } }, /* Power Gear key */ { KE_KEY, 0x5d, { KEY_WLAN } }, - { KE_KEY, 0x6b, { KEY_TOUCHPAD_TOGGLE } }, /* Toggle Touchpad */ - { KE_KEY, 0x82, { KEY_CAMERA } }, - { KE_KEY, 0x83, { KEY_CAMERA_ZOOMIN } }, - { KE_KEY, 0x88, { KEY_WLAN } }, + { KE_KEY, 0x32, { KEY_MUTE } }, + { KE_KEY, 0x31, { KEY_VOLUMEDOWN } }, + { KE_KEY, 0x30, { KEY_VOLUMEUP } }, + { KE_IGNORE, NOTIFY_BRNDOWN_MIN, { KEY_BRIGHTNESSDOWN } }, + { KE_IGNORE, NOTIFY_BRNUP_MIN, { KEY_BRIGHTNESSUP } }, { KE_KEY, 0xcc, { KEY_SWITCHVIDEOMODE } }, - { KE_KEY, 0xe0, { KEY_PROG1 } }, /* Task Manager */ - { KE_KEY, 0xe1, { KEY_F14 } }, /* Change Resolution */ - { KE_KEY, 0xe9, { KEY_BRIGHTNESS_ZERO } }, - { KE_KEY, 0xeb, { KEY_CAMERA_ZOOMOUT } }, - { KE_KEY, 0xec, { KEY_CAMERA_UP } }, - { KE_KEY, 0xed, { KEY_CAMERA_DOWN } }, - { KE_KEY, 0xee, { KEY_CAMERA_LEFT } }, - { KE_KEY, 0xef, { KEY_CAMERA_RIGHT } }, + { KE_KEY, 0x6b, { KEY_F13 } }, /* Disable Touchpad */ + { KE_KEY, 0xe1, { KEY_F14 } }, + { KE_KEY, 0xe9, { KEY_DISPLAY_OFF } }, + { KE_KEY, 0xe0, { KEY_PROG1 } }, + { KE_KEY, 0x5c, { KEY_F15 } }, { KE_END, 0}, }; -static acpi_status eeepc_wmi_parse_device(acpi_handle handle, u32 level, +struct bios_args { + u32 dev_id; + u32 ctrl_param; +}; + +/* + * eeepc-wmi/ - debugfs root directory + * dev_id - current dev_id + * ctrl_param - current ctrl_param + * devs - call DEVS(dev_id, ctrl_param) and print result + * dsts - call DSTS(dev_id) and print result + */ +struct eeepc_wmi_debug { + struct dentry *root; + u32 dev_id; + u32 ctrl_param; +}; + +struct eeepc_wmi { + struct input_dev *inputdev; + struct backlight_device *backlight_device; + struct platform_device *platform_device; + + struct led_classdev tpd_led; + int tpd_led_wk; + struct workqueue_struct *led_workqueue; + struct work_struct tpd_led_work; + + struct rfkill *wlan_rfkill; + struct rfkill *bluetooth_rfkill; + struct rfkill *wwan3g_rfkill; + + struct eeepc_wmi_debug debug; +}; + +/* Only used in eeepc_wmi_init() and eeepc_wmi_exit() */ +static struct platform_device *platform_device; + +static int eeepc_wmi_input_init(struct eeepc_wmi *eeepc) +{ + int err; + + eeepc->inputdev = input_allocate_device(); + if (!eeepc->inputdev) + return -ENOMEM; + + eeepc->inputdev->name = "Eee PC WMI hotkeys"; + eeepc->inputdev->phys = EEEPC_WMI_FILE "/input0"; + eeepc->inputdev->id.bustype = BUS_HOST; + eeepc->inputdev->dev.parent = &eeepc->platform_device->dev; + + err = sparse_keymap_setup(eeepc->inputdev, eeepc_wmi_keymap, NULL); + if (err) + goto err_free_dev; + + err = input_register_device(eeepc->inputdev); + if (err) + goto err_free_keymap; + + return 0; + +err_free_keymap: + sparse_keymap_free(eeepc->inputdev); +err_free_dev: + input_free_device(eeepc->inputdev); + return err; +} + +static void eeepc_wmi_input_exit(struct eeepc_wmi *eeepc) +{ + if (eeepc->inputdev) { + sparse_keymap_free(eeepc->inputdev); + input_unregister_device(eeepc->inputdev); + } + + eeepc->inputdev = NULL; +} + +static acpi_status eeepc_wmi_get_devstate(u32 dev_id, u32 *retval) +{ + struct acpi_buffer input = { (acpi_size)sizeof(u32), &dev_id }; + struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL }; + union acpi_object *obj; + acpi_status status; + u32 tmp; + + status = wmi_evaluate_method(EEEPC_WMI_MGMT_GUID, + 1, EEEPC_WMI_METHODID_DSTS, &input, &output); + + if (ACPI_FAILURE(status)) + return status; + + obj = (union acpi_object *)output.pointer; + if (obj && obj->type == ACPI_TYPE_INTEGER) + tmp = (u32)obj->integer.value; + else + tmp = 0; + + if (retval) + *retval = tmp; + + kfree(obj); + + return status; + +} + +static acpi_status eeepc_wmi_set_devstate(u32 dev_id, u32 ctrl_param, + u32 *retval) +{ + struct bios_args args = { + .dev_id = dev_id, + .ctrl_param = ctrl_param, + }; + struct acpi_buffer input = { (acpi_size)sizeof(args), &args }; + acpi_status status; + + if (!retval) { + status = wmi_evaluate_method(EEEPC_WMI_MGMT_GUID, 1, + EEEPC_WMI_METHODID_DEVS, + &input, NULL); + } else { + struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL }; + union acpi_object *obj; + u32 tmp; + + status = wmi_evaluate_method(EEEPC_WMI_MGMT_GUID, 1, + EEEPC_WMI_METHODID_DEVS, + &input, &output); + + if (ACPI_FAILURE(status)) + return status; + + obj = (union acpi_object *)output.pointer; + if (obj && obj->type == ACPI_TYPE_INTEGER) + tmp = (u32)obj->integer.value; + else + tmp = 0; + + *retval = tmp; + + kfree(obj); + } + + return status; +} + +/* + * LEDs + */ +/* + * These functions actually update the LED's, and are called from a + * workqueue. By doing this as separate work rather than when the LED + * subsystem asks, we avoid messing with the Eeepc ACPI stuff during a + * potentially bad time, such as a timer interrupt. + */ +static void tpd_led_update(struct work_struct *work) +{ + int ctrl_param; + struct eeepc_wmi *eeepc; + + eeepc = container_of(work, struct eeepc_wmi, tpd_led_work); + + ctrl_param = eeepc->tpd_led_wk; + eeepc_wmi_set_devstate(EEEPC_WMI_DEVID_TPDLED, ctrl_param, NULL); +} + +static void tpd_led_set(struct led_classdev *led_cdev, + enum led_brightness value) +{ + struct eeepc_wmi *eeepc; + + eeepc = container_of(led_cdev, struct eeepc_wmi, tpd_led); + + eeepc->tpd_led_wk = !!value; + queue_work(eeepc->led_workqueue, &eeepc->tpd_led_work); +} + +static int read_tpd_state(struct eeepc_wmi *eeepc) +{ + u32 retval; + acpi_status status; + + status = eeepc_wmi_get_devstate(EEEPC_WMI_DEVID_TPDLED, &retval); + + if (ACPI_FAILURE(status)) + return -1; + else if (!retval || retval == 0x00060000) + /* + * if touchpad led is present, DSTS will set some bits, + * usually 0x00020000. + * 0x00060000 means that the device is not supported + */ + return -ENODEV; + else + /* Status is stored in the first bit */ + return retval & 0x1; +} + +static enum led_brightness tpd_led_get(struct led_classdev *led_cdev) +{ + struct eeepc_wmi *eeepc; + + eeepc = container_of(led_cdev, struct eeepc_wmi, tpd_led); + + return read_tpd_state(eeepc); +} + +static int eeepc_wmi_led_init(struct eeepc_wmi *eeepc) +{ + int rv; + + if (read_tpd_state(eeepc) < 0) + return 0; + + eeepc->led_workqueue = create_singlethread_workqueue("led_workqueue"); + if (!eeepc->led_workqueue) + return -ENOMEM; + INIT_WORK(&eeepc->tpd_led_work, tpd_led_update); + + eeepc->tpd_led.name = "eeepc::touchpad"; + eeepc->tpd_led.brightness_set = tpd_led_set; + eeepc->tpd_led.brightness_get = tpd_led_get; + eeepc->tpd_led.max_brightness = 1; + + rv = led_classdev_register(&eeepc->platform_device->dev, + &eeepc->tpd_led); + if (rv) { + destroy_workqueue(eeepc->led_workqueue); + return rv; + } + + return 0; +} + +static void eeepc_wmi_led_exit(struct eeepc_wmi *eeepc) +{ + if (eeepc->tpd_led.dev) + led_classdev_unregister(&eeepc->tpd_led); + if (eeepc->led_workqueue) + destroy_workqueue(eeepc->led_workqueue); +} + +/* + * Rfkill devices + */ +static int eeepc_rfkill_set(void *data, bool blocked) +{ + int dev_id = (unsigned long)data; + u32 ctrl_param = !blocked; + + return eeepc_wmi_set_devstate(dev_id, ctrl_param, NULL); +} + +static void eeepc_rfkill_query(struct rfkill *rfkill, void *data) +{ + int dev_id = (unsigned long)data; + u32 retval; + acpi_status status; + + status = eeepc_wmi_get_devstate(dev_id, &retval); + + if (ACPI_FAILURE(status)) + return ; + + rfkill_set_sw_state(rfkill, !(retval & 0x1)); +} + +static const struct rfkill_ops eeepc_rfkill_ops = { + .set_block = eeepc_rfkill_set, + .query = eeepc_rfkill_query, +}; + +static int eeepc_new_rfkill(struct eeepc_wmi *eeepc, + struct rfkill **rfkill, + const char *name, + enum rfkill_type type, int dev_id) +{ + int result; + u32 retval; + acpi_status status; + + status = eeepc_wmi_get_devstate(dev_id, &retval); + + if (ACPI_FAILURE(status)) + return -1; + + /* If the device is present, DSTS will always set some bits + * 0x00070000 - 1110000000000000000 - device supported + * 0x00060000 - 1100000000000000000 - not supported + * 0x00020000 - 0100000000000000000 - device supported + * 0x00010000 - 0010000000000000000 - not supported / special mode ? + */ + if (!retval || retval == 0x00060000) + return -ENODEV; + + *rfkill = rfkill_alloc(name, &eeepc->platform_device->dev, type, + &eeepc_rfkill_ops, (void *)(long)dev_id); + + if (!*rfkill) + return -EINVAL; + + rfkill_init_sw_state(*rfkill, !(retval & 0x1)); + result = rfkill_register(*rfkill); + if (result) { + rfkill_destroy(*rfkill); + *rfkill = NULL; + return result; + } + return 0; +} + +static void eeepc_wmi_rfkill_exit(struct eeepc_wmi *eeepc) +{ + if (eeepc->wlan_rfkill) { + rfkill_unregister(eeepc->wlan_rfkill); + rfkill_destroy(eeepc->wlan_rfkill); + eeepc->wlan_rfkill = NULL; + } + if (eeepc->bluetooth_rfkill) { + rfkill_unregister(eeepc->bluetooth_rfkill); + rfkill_destroy(eeepc->bluetooth_rfkill); + eeepc->bluetooth_rfkill = NULL; + } + if (eeepc->wwan3g_rfkill) { + rfkill_unregister(eeepc->wwan3g_rfkill); + rfkill_destroy(eeepc->wwan3g_rfkill); + eeepc->wwan3g_rfkill = NULL; + } +} + +static int eeepc_wmi_rfkill_init(struct eeepc_wmi *eeepc) +{ + int result = 0; + + result = eeepc_new_rfkill(eeepc, &eeepc->wlan_rfkill, + "eeepc-wlan", RFKILL_TYPE_WLAN, + EEEPC_WMI_DEVID_WLAN); + + if (result && result != -ENODEV) + goto exit; + + result = eeepc_new_rfkill(eeepc, &eeepc->bluetooth_rfkill, + "eeepc-bluetooth", RFKILL_TYPE_BLUETOOTH, + EEEPC_WMI_DEVID_BLUETOOTH); + + if (result && result != -ENODEV) + goto exit; + + result = eeepc_new_rfkill(eeepc, &eeepc->wwan3g_rfkill, + "eeepc-wwan3g", RFKILL_TYPE_WWAN, + EEEPC_WMI_DEVID_WWAN3G); + + if (result && result != -ENODEV) + goto exit; + +exit: + if (result && result != -ENODEV) + eeepc_wmi_rfkill_exit(eeepc); + + if (result == -ENODEV) + result = 0; + + return result; +} + +/* + * Backlight + */ +static int read_brightness(struct backlight_device *bd) +{ + u32 retval; + acpi_status status; + + status = eeepc_wmi_get_devstate(EEEPC_WMI_DEVID_BACKLIGHT, &retval); + + if (ACPI_FAILURE(status)) + return -1; + else + return retval & 0xFF; +} + +static int update_bl_status(struct backlight_device *bd) +{ + + u32 ctrl_param; + acpi_status status; + + ctrl_param = bd->props.brightness; + + status = eeepc_wmi_set_devstate(EEEPC_WMI_DEVID_BACKLIGHT, + ctrl_param, NULL); + + if (ACPI_FAILURE(status)) + return -1; + else + return 0; +} + +static const struct backlight_ops eeepc_wmi_bl_ops = { + .get_brightness = read_brightness, + .update_status = update_bl_status, +}; + +static int eeepc_wmi_backlight_notify(struct eeepc_wmi *eeepc, int code) +{ + struct backlight_device *bd = eeepc->backlight_device; + int old = bd->props.brightness; + int new = old; + + if (code >= NOTIFY_BRNUP_MIN && code <= NOTIFY_BRNUP_MAX) + new = code - NOTIFY_BRNUP_MIN + 1; + else if (code >= NOTIFY_BRNDOWN_MIN && code <= NOTIFY_BRNDOWN_MAX) + new = code - NOTIFY_BRNDOWN_MIN; + + bd->props.brightness = new; + backlight_update_status(bd); + backlight_force_update(bd, BACKLIGHT_UPDATE_HOTKEY); + + return old; +} + +static int eeepc_wmi_backlight_init(struct eeepc_wmi *eeepc) +{ + struct backlight_device *bd; + struct backlight_properties props; + + memset(&props, 0, sizeof(struct backlight_properties)); + props.max_brightness = 15; + bd = backlight_device_register(EEEPC_WMI_FILE, + &eeepc->platform_device->dev, eeepc, + &eeepc_wmi_bl_ops, &props); + if (IS_ERR(bd)) { + pr_err("Could not register backlight device\n"); + return PTR_ERR(bd); + } + + eeepc->backlight_device = bd; + + bd->props.brightness = read_brightness(bd); + bd->props.power = FB_BLANK_UNBLANK; + backlight_update_status(bd); + + return 0; +} + +static void eeepc_wmi_backlight_exit(struct eeepc_wmi *eeepc) +{ + if (eeepc->backlight_device) + backlight_device_unregister(eeepc->backlight_device); + + eeepc->backlight_device = NULL; +} + +static void eeepc_wmi_notify(u32 value, void *context) +{ + struct eeepc_wmi *eeepc = context; + struct acpi_buffer response = { ACPI_ALLOCATE_BUFFER, NULL }; + union acpi_object *obj; + acpi_status status; + int code; + int orig_code; + + status = wmi_get_event_data(value, &response); + if (status != AE_OK) { + pr_err("bad event status 0x%x\n", status); + return; + } + + obj = (union acpi_object *)response.pointer; + + if (obj && obj->type == ACPI_TYPE_INTEGER) { + code = obj->integer.value; + orig_code = code; + + if (code >= NOTIFY_BRNUP_MIN && code <= NOTIFY_BRNUP_MAX) + code = NOTIFY_BRNUP_MIN; + else if (code >= NOTIFY_BRNDOWN_MIN && + code <= NOTIFY_BRNDOWN_MAX) + code = NOTIFY_BRNDOWN_MIN; + + if (code == NOTIFY_BRNUP_MIN || code == NOTIFY_BRNDOWN_MIN) { + if (!acpi_video_backlight_support()) + eeepc_wmi_backlight_notify(eeepc, orig_code); + } + + if (!sparse_keymap_report_event(eeepc->inputdev, + code, 1, true)) + pr_info("Unknown key %x pressed\n", code); + } + + kfree(obj); +} + +static ssize_t store_cpufv(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) +{ + int value; + struct acpi_buffer input = { (acpi_size)sizeof(value), &value }; + acpi_status status; + + if (!count || sscanf(buf, "%i", &value) != 1) + return -EINVAL; + if (value < 0 || value > 2) + return -EINVAL; + + status = wmi_evaluate_method(EEEPC_WMI_MGMT_GUID, + 1, EEEPC_WMI_METHODID_CFVS, &input, NULL); + + if (ACPI_FAILURE(status)) + return -EIO; + else + return count; +} + +static DEVICE_ATTR(cpufv, S_IRUGO | S_IWUSR, NULL, store_cpufv); + +static struct attribute *platform_attributes[] = { + &dev_attr_cpufv.attr, + NULL +}; + +static struct attribute_group platform_attribute_group = { + .attrs = platform_attributes +}; + +static void eeepc_wmi_sysfs_exit(struct platform_device *device) +{ + sysfs_remove_group(&device->dev.kobj, &platform_attribute_group); +} + +static int eeepc_wmi_sysfs_init(struct platform_device *device) +{ + return sysfs_create_group(&device->dev.kobj, &platform_attribute_group); +} + +/* + * Platform device + */ +static int __init eeepc_wmi_platform_init(struct eeepc_wmi *eeepc) +{ + int err; + + eeepc->platform_device = platform_device_alloc(EEEPC_WMI_FILE, -1); + if (!eeepc->platform_device) + return -ENOMEM; + platform_set_drvdata(eeepc->platform_device, eeepc); + + err = platform_device_add(eeepc->platform_device); + if (err) + goto fail_platform_device; + + err = eeepc_wmi_sysfs_init(eeepc->platform_device); + if (err) + goto fail_sysfs; + return 0; + +fail_sysfs: + platform_device_del(eeepc->platform_device); +fail_platform_device: + platform_device_put(eeepc->platform_device); + return err; +} + +static void eeepc_wmi_platform_exit(struct eeepc_wmi *eeepc) +{ + eeepc_wmi_sysfs_exit(eeepc->platform_device); + platform_device_unregister(eeepc->platform_device); +} + +/* + * debugfs + */ +struct eeepc_wmi_debugfs_node { + struct eeepc_wmi *eeepc; + char *name; + int (*show)(struct seq_file *m, void *data); +}; + +static int show_dsts(struct seq_file *m, void *data) +{ + struct eeepc_wmi *eeepc = m->private; + acpi_status status; + u32 retval = -1; + + status = eeepc_wmi_get_devstate(eeepc->debug.dev_id, &retval); + + if (ACPI_FAILURE(status)) + return -EIO; + + seq_printf(m, "DSTS(%x) = %x\n", eeepc->debug.dev_id, retval); + + return 0; +} + +static int show_devs(struct seq_file *m, void *data) +{ + struct eeepc_wmi *eeepc = m->private; + acpi_status status; + u32 retval = -1; + + status = eeepc_wmi_set_devstate(eeepc->debug.dev_id, + eeepc->debug.ctrl_param, &retval); + if (ACPI_FAILURE(status)) + return -EIO; + + seq_printf(m, "DEVS(%x, %x) = %x\n", eeepc->debug.dev_id, + eeepc->debug.ctrl_param, retval); + + return 0; +} + +static struct eeepc_wmi_debugfs_node eeepc_wmi_debug_files[] = { + { NULL, "devs", show_devs }, + { NULL, "dsts", show_dsts }, +}; + +static int eeepc_wmi_debugfs_open(struct inode *inode, struct file *file) +{ + struct eeepc_wmi_debugfs_node *node = inode->i_private; + + return single_open(file, node->show, node->eeepc); +} + +static const struct file_operations eeepc_wmi_debugfs_io_ops = { + .owner = THIS_MODULE, + .open = eeepc_wmi_debugfs_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + +static void eeepc_wmi_debugfs_exit(struct eeepc_wmi *eeepc) +{ + debugfs_remove_recursive(eeepc->debug.root); +} + +static int eeepc_wmi_debugfs_init(struct eeepc_wmi *eeepc) +{ + struct dentry *dent; + int i; + + eeepc->debug.root = debugfs_create_dir(EEEPC_WMI_FILE, NULL); + if (!eeepc->debug.root) { + pr_err("failed to create debugfs directory"); + goto error_debugfs; + } + + dent = debugfs_create_x32("dev_id", S_IRUGO|S_IWUSR, + eeepc->debug.root, &eeepc->debug.dev_id); + if (!dent) + goto error_debugfs; + + dent = debugfs_create_x32("ctrl_param", S_IRUGO|S_IWUSR, + eeepc->debug.root, &eeepc->debug.ctrl_param); + if (!dent) + goto error_debugfs; + + for (i = 0; i < ARRAY_SIZE(eeepc_wmi_debug_files); i++) { + struct eeepc_wmi_debugfs_node *node = &eeepc_wmi_debug_files[i]; + + node->eeepc = eeepc; + dent = debugfs_create_file(node->name, S_IFREG | S_IRUGO, + eeepc->debug.root, node, + &eeepc_wmi_debugfs_io_ops); + if (!dent) { + pr_err("failed to create debug file: %s\n", node->name); + goto error_debugfs; + } + } + + return 0; + +error_debugfs: + eeepc_wmi_debugfs_exit(eeepc); + return -ENOMEM; +} + +/* + * WMI Driver + */ +static struct platform_device * __init eeepc_wmi_add(void) +{ + struct eeepc_wmi *eeepc; + acpi_status status; + int err; + + eeepc = kzalloc(sizeof(struct eeepc_wmi), GFP_KERNEL); + if (!eeepc) + return ERR_PTR(-ENOMEM); + + /* + * Register the platform device first. It is used as a parent for the + * sub-devices below. + */ + err = eeepc_wmi_platform_init(eeepc); + if (err) + goto fail_platform; + + err = eeepc_wmi_input_init(eeepc); + if (err) + goto fail_input; + + err = eeepc_wmi_led_init(eeepc); + if (err) + goto fail_leds; + + err = eeepc_wmi_rfkill_init(eeepc); + if (err) + goto fail_rfkill; + + if (!acpi_video_backlight_support()) { + err = eeepc_wmi_backlight_init(eeepc); + if (err) + goto fail_backlight; + } else + pr_info("Backlight controlled by ACPI video driver\n"); + + status = wmi_install_notify_handler(EEEPC_WMI_EVENT_GUID, + eeepc_wmi_notify, eeepc); + if (ACPI_FAILURE(status)) { + pr_err("Unable to register notify handler - %d\n", + status); + err = -ENODEV; + goto fail_wmi_handler; + } + + err = eeepc_wmi_debugfs_init(eeepc); + if (err) + goto fail_debugfs; + + return eeepc->platform_device; + +fail_debugfs: + wmi_remove_notify_handler(EEEPC_WMI_EVENT_GUID); +fail_wmi_handler: + eeepc_wmi_backlight_exit(eeepc); +fail_backlight: + eeepc_wmi_rfkill_exit(eeepc); +fail_rfkill: + eeepc_wmi_led_exit(eeepc); +fail_leds: + eeepc_wmi_input_exit(eeepc); +fail_input: + eeepc_wmi_platform_exit(eeepc); +fail_platform: + kfree(eeepc); + return ERR_PTR(err); +} + +static int eeepc_wmi_remove(struct platform_device *device) +{ + struct eeepc_wmi *eeepc; + + eeepc = platform_get_drvdata(device); + wmi_remove_notify_handler(EEEPC_WMI_EVENT_GUID); + eeepc_wmi_backlight_exit(eeepc); + eeepc_wmi_input_exit(eeepc); + eeepc_wmi_led_exit(eeepc); + eeepc_wmi_rfkill_exit(eeepc); + eeepc_wmi_debugfs_exit(eeepc); + eeepc_wmi_platform_exit(eeepc); + + kfree(eeepc); + return 0; +} + +static struct platform_driver platform_driver = { + .driver = { + .name = EEEPC_WMI_FILE, + .owner = THIS_MODULE, + }, +}; + +static acpi_status __init eeepc_wmi_parse_device(acpi_handle handle, u32 level, void *context, void **retval) { pr_warning("Found legacy ATKD device (%s)", EEEPC_ACPI_HID); @@ -87,7 +871,7 @@ static acpi_status eeepc_wmi_parse_device(acpi_handle handle, u32 level, return AE_CTRL_TERMINATE; } -static int eeepc_wmi_check_atkd(void) +static int __init eeepc_wmi_check_atkd(void) { acpi_status status; bool found = false; @@ -100,8 +884,16 @@ static int eeepc_wmi_check_atkd(void) return -1; } -static int eeepc_wmi_probe(struct platform_device *pdev) +static int __init eeepc_wmi_init(void) { + int err; + + if (!wmi_has_guid(EEEPC_WMI_EVENT_GUID) || + !wmi_has_guid(EEEPC_WMI_MGMT_GUID)) { + pr_warning("No known WMI GUID found\n"); + return -ENODEV; + } + if (eeepc_wmi_check_atkd()) { pr_warning("WMI device present, but legacy ATKD device is also " "present and enabled."); @@ -109,59 +901,33 @@ static int eeepc_wmi_probe(struct platform_device *pdev) "acpi_osi=\"!Windows 2009\""); pr_warning("Can't load eeepc-wmi, use default acpi_osi " "(preferred) or eeepc-laptop"); - return -EBUSY; + return -ENODEV; } - return 0; -} - -static void eeepc_dmi_check(struct asus_wmi_driver *driver) -{ - const char *model; - - model = dmi_get_system_info(DMI_PRODUCT_NAME); - if (!model) - return; - /* - * Whitelist for wlan hotplug - * - * Asus 1000H needs the current hotplug code to handle - * Fn+F2 correctly. We may add other Asus here later, but - * it seems that most of the laptops supported by asus-wmi - * don't need to be on this list - */ - if (strcmp(model, "1000H") == 0) { - driver->hotplug_wireless = true; - pr_info("wlan hotplug enabled\n"); + platform_device = eeepc_wmi_add(); + if (IS_ERR(platform_device)) { + err = PTR_ERR(platform_device); + goto fail_eeepc_wmi; } -} -static void eeepc_wmi_quirks(struct asus_wmi_driver *driver) -{ - driver->hotplug_wireless = hotplug_wireless; - eeepc_dmi_check(driver); -} - -static struct asus_wmi_driver asus_wmi_driver = { - .name = EEEPC_WMI_FILE, - .owner = THIS_MODULE, - .event_guid = EEEPC_WMI_EVENT_GUID, - .keymap = eeepc_wmi_keymap, - .input_name = "Eee PC WMI hotkeys", - .input_phys = EEEPC_WMI_FILE "/input0", - .probe = eeepc_wmi_probe, - .quirks = eeepc_wmi_quirks, -}; + err = platform_driver_register(&platform_driver); + if (err) { + pr_warning("Unable to register platform driver\n"); + goto fail_platform_driver; + } + return 0; -static int __init eeepc_wmi_init(void) -{ - return asus_wmi_register_driver(&asus_wmi_driver); +fail_platform_driver: + eeepc_wmi_remove(platform_device); +fail_eeepc_wmi: + return err; } static void __exit eeepc_wmi_exit(void) { - asus_wmi_unregister_driver(&asus_wmi_driver); + eeepc_wmi_remove(platform_device); + platform_driver_unregister(&platform_driver); } module_init(eeepc_wmi_init); diff --git a/trunk/drivers/platform/x86/hp-wmi.c b/trunk/drivers/platform/x86/hp-wmi.c index 1bc4a7539ba9..9e05af9c41cb 100644 --- a/trunk/drivers/platform/x86/hp-wmi.c +++ b/trunk/drivers/platform/x86/hp-wmi.c @@ -2,7 +2,6 @@ * HP WMI hotkeys * * Copyright (C) 2008 Red Hat - * Copyright (C) 2010, 2011 Anssi Hannula * * Portions based on wistron_btns.c: * Copyright (C) 2005 Miloslav Trmac @@ -52,7 +51,6 @@ MODULE_ALIAS("wmi:5FB7F034-2C63-45e9-BE91-3D44E2C707E4"); #define HPWMI_HARDWARE_QUERY 0x4 #define HPWMI_WIRELESS_QUERY 0x5 #define HPWMI_HOTKEY_QUERY 0xc -#define HPWMI_WIRELESS2_QUERY 0x1b #define PREFIX "HP WMI: " #define UNIMP "Unimplemented " @@ -88,46 +86,7 @@ struct bios_args { struct bios_return { u32 sigpass; u32 return_code; -}; - -enum hp_return_value { - HPWMI_RET_WRONG_SIGNATURE = 0x02, - HPWMI_RET_UNKNOWN_COMMAND = 0x03, - HPWMI_RET_UNKNOWN_CMDTYPE = 0x04, - HPWMI_RET_INVALID_PARAMETERS = 0x05, -}; - -enum hp_wireless2_bits { - HPWMI_POWER_STATE = 0x01, - HPWMI_POWER_SOFT = 0x02, - HPWMI_POWER_BIOS = 0x04, - HPWMI_POWER_HARD = 0x08, -}; - -#define IS_HWBLOCKED(x) ((x & (HPWMI_POWER_BIOS | HPWMI_POWER_HARD)) \ - != (HPWMI_POWER_BIOS | HPWMI_POWER_HARD)) -#define IS_SWBLOCKED(x) !(x & HPWMI_POWER_SOFT) - -struct bios_rfkill2_device_state { - u8 radio_type; - u8 bus_type; - u16 vendor_id; - u16 product_id; - u16 subsys_vendor_id; - u16 subsys_product_id; - u8 rfkill_id; - u8 power; - u8 unknown[4]; -}; - -/* 7 devices fit into the 128 byte buffer */ -#define HPWMI_MAX_RFKILL2_DEVICES 7 - -struct bios_rfkill2_state { - u8 unknown[7]; - u8 count; - u8 pad[8]; - struct bios_rfkill2_device_state device[HPWMI_MAX_RFKILL2_DEVICES]; + u32 value; }; static const struct key_entry hp_wmi_keymap[] = { @@ -149,15 +108,6 @@ static struct rfkill *wifi_rfkill; static struct rfkill *bluetooth_rfkill; static struct rfkill *wwan_rfkill; -struct rfkill2_device { - u8 id; - int num; - struct rfkill *rfkill; -}; - -static int rfkill2_count; -static struct rfkill2_device rfkill2[HPWMI_MAX_RFKILL2_DEVICES]; - static const struct dev_pm_ops hp_wmi_pm_ops = { .resume = hp_wmi_resume_handler, .restore = hp_wmi_resume_handler, @@ -179,8 +129,7 @@ static struct platform_driver hp_wmi_driver = { * query: The commandtype -> What should be queried * write: The command -> 0 read, 1 write, 3 ODM specific * buffer: Buffer used as input and/or output - * insize: Size of input buffer - * outsize: Size of output buffer + * buffersize: Size of buffer * * returns zero on success * an HP WMI query specific error code (which is positive) @@ -191,29 +140,25 @@ static struct platform_driver hp_wmi_driver = { * size. E.g. Battery info query (0x7) is defined to have 1 byte input * and 128 byte output. The caller would do: * buffer = kzalloc(128, GFP_KERNEL); - * ret = hp_wmi_perform_query(0x7, 0, buffer, 1, 128) + * ret = hp_wmi_perform_query(0x7, 0, buffer, 128) */ -static int hp_wmi_perform_query(int query, int write, void *buffer, - int insize, int outsize) +static int hp_wmi_perform_query(int query, int write, u32 *buffer, + int buffersize) { - struct bios_return *bios_return; - int actual_outsize; + struct bios_return bios_return; + acpi_status status; union acpi_object *obj; struct bios_args args = { .signature = 0x55434553, .command = write ? 0x2 : 0x1, .commandtype = query, - .datasize = insize, - .data = 0, + .datasize = buffersize, + .data = *buffer, }; struct acpi_buffer input = { sizeof(struct bios_args), &args }; struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL }; - if (WARN_ON(insize > sizeof(args.data))) - return -EINVAL; - memcpy(&args.data, buffer, insize); - - wmi_evaluate_method(HPWMI_BIOS_GUID, 0, 0x3, &input, &output); + status = wmi_evaluate_method(HPWMI_BIOS_GUID, 0, 0x3, &input, &output); obj = output.pointer; @@ -224,26 +169,10 @@ static int hp_wmi_perform_query(int query, int write, void *buffer, return -EINVAL; } - bios_return = (struct bios_return *)obj->buffer.pointer; + bios_return = *((struct bios_return *)obj->buffer.pointer); - if (bios_return->return_code) { - if (bios_return->return_code != HPWMI_RET_UNKNOWN_CMDTYPE) - printk(KERN_WARNING PREFIX "query 0x%x returned " - "error 0x%x\n", - query, bios_return->return_code); - kfree(obj); - return bios_return->return_code; - } - - if (!outsize) { - /* ignore output data */ - kfree(obj); - return 0; - } + memcpy(buffer, &bios_return.value, sizeof(bios_return.value)); - actual_outsize = min(outsize, (int)(obj->buffer.length - sizeof(*bios_return))); - memcpy(buffer, obj->buffer.pointer + sizeof(*bios_return), actual_outsize); - memset(buffer + actual_outsize, 0, outsize - actual_outsize); kfree(obj); return 0; } @@ -252,7 +181,7 @@ static int hp_wmi_display_state(void) { int state = 0; int ret = hp_wmi_perform_query(HPWMI_DISPLAY_QUERY, 0, &state, - sizeof(state), sizeof(state)); + sizeof(state)); if (ret) return -EINVAL; return state; @@ -262,7 +191,7 @@ static int hp_wmi_hddtemp_state(void) { int state = 0; int ret = hp_wmi_perform_query(HPWMI_HDDTEMP_QUERY, 0, &state, - sizeof(state), sizeof(state)); + sizeof(state)); if (ret) return -EINVAL; return state; @@ -272,7 +201,7 @@ static int hp_wmi_als_state(void) { int state = 0; int ret = hp_wmi_perform_query(HPWMI_ALS_QUERY, 0, &state, - sizeof(state), sizeof(state)); + sizeof(state)); if (ret) return -EINVAL; return state; @@ -282,7 +211,7 @@ static int hp_wmi_dock_state(void) { int state = 0; int ret = hp_wmi_perform_query(HPWMI_HARDWARE_QUERY, 0, &state, - sizeof(state), sizeof(state)); + sizeof(state)); if (ret) return -EINVAL; @@ -294,7 +223,7 @@ static int hp_wmi_tablet_state(void) { int state = 0; int ret = hp_wmi_perform_query(HPWMI_HARDWARE_QUERY, 0, &state, - sizeof(state), sizeof(state)); + sizeof(state)); if (ret) return ret; @@ -308,7 +237,7 @@ static int hp_wmi_set_block(void *data, bool blocked) int ret; ret = hp_wmi_perform_query(HPWMI_WIRELESS_QUERY, 1, - &query, sizeof(query), 0); + &query, sizeof(query)); if (ret) return -EINVAL; return 0; @@ -323,8 +252,7 @@ static bool hp_wmi_get_sw_state(enum hp_wmi_radio r) int wireless = 0; int mask; hp_wmi_perform_query(HPWMI_WIRELESS_QUERY, 0, - &wireless, sizeof(wireless), - sizeof(wireless)); + &wireless, sizeof(wireless)); /* TBD: Pass error */ mask = 0x200 << (r * 8); @@ -340,8 +268,7 @@ static bool hp_wmi_get_hw_state(enum hp_wmi_radio r) int wireless = 0; int mask; hp_wmi_perform_query(HPWMI_WIRELESS_QUERY, 0, - &wireless, sizeof(wireless), - sizeof(wireless)); + &wireless, sizeof(wireless)); /* TBD: Pass error */ mask = 0x800 << (r * 8); @@ -352,51 +279,6 @@ static bool hp_wmi_get_hw_state(enum hp_wmi_radio r) return true; } -static int hp_wmi_rfkill2_set_block(void *data, bool blocked) -{ - int rfkill_id = (int)(long)data; - char buffer[4] = { 0x01, 0x00, rfkill_id, !blocked }; - - if (hp_wmi_perform_query(HPWMI_WIRELESS2_QUERY, 1, - buffer, sizeof(buffer), 0)) - return -EINVAL; - return 0; -} - -static const struct rfkill_ops hp_wmi_rfkill2_ops = { - .set_block = hp_wmi_rfkill2_set_block, -}; - -static int hp_wmi_rfkill2_refresh(void) -{ - int err, i; - struct bios_rfkill2_state state; - - err = hp_wmi_perform_query(HPWMI_WIRELESS2_QUERY, 0, &state, - 0, sizeof(state)); - if (err) - return err; - - for (i = 0; i < rfkill2_count; i++) { - int num = rfkill2[i].num; - struct bios_rfkill2_device_state *devstate; - devstate = &state.device[num]; - - if (num >= state.count || - devstate->rfkill_id != rfkill2[i].id) { - printk(KERN_WARNING PREFIX "power configuration of " - "the wireless devices unexpectedly changed\n"); - continue; - } - - rfkill_set_states(rfkill2[i].rfkill, - IS_SWBLOCKED(devstate->power), - IS_HWBLOCKED(devstate->power)); - } - - return 0; -} - static ssize_t show_display(struct device *dev, struct device_attribute *attr, char *buf) { @@ -447,7 +329,7 @@ static ssize_t set_als(struct device *dev, struct device_attribute *attr, { u32 tmp = simple_strtoul(buf, NULL, 10); int ret = hp_wmi_perform_query(HPWMI_ALS_QUERY, 1, &tmp, - sizeof(tmp), sizeof(tmp)); + sizeof(tmp)); if (ret) return -EINVAL; @@ -520,7 +402,6 @@ static void hp_wmi_notify(u32 value, void *context) case HPWMI_BEZEL_BUTTON: ret = hp_wmi_perform_query(HPWMI_HOTKEY_QUERY, 0, &key_code, - sizeof(key_code), sizeof(key_code)); if (ret) break; @@ -531,11 +412,6 @@ static void hp_wmi_notify(u32 value, void *context) key_code); break; case HPWMI_WIRELESS: - if (rfkill2_count) { - hp_wmi_rfkill2_refresh(); - break; - } - if (wifi_rfkill) rfkill_set_states(wifi_rfkill, hp_wmi_get_sw_state(HPWMI_WIFI), @@ -626,16 +502,32 @@ static void cleanup_sysfs(struct platform_device *device) device_remove_file(&device->dev, &dev_attr_tablet); } -static int __devinit hp_wmi_rfkill_setup(struct platform_device *device) +static int __devinit hp_wmi_bios_setup(struct platform_device *device) { int err; int wireless = 0; err = hp_wmi_perform_query(HPWMI_WIRELESS_QUERY, 0, &wireless, - sizeof(wireless), sizeof(wireless)); + sizeof(wireless)); if (err) return err; + err = device_create_file(&device->dev, &dev_attr_display); + if (err) + goto add_sysfs_error; + err = device_create_file(&device->dev, &dev_attr_hddtemp); + if (err) + goto add_sysfs_error; + err = device_create_file(&device->dev, &dev_attr_als); + if (err) + goto add_sysfs_error; + err = device_create_file(&device->dev, &dev_attr_dock); + if (err) + goto add_sysfs_error; + err = device_create_file(&device->dev, &dev_attr_tablet); + if (err) + goto add_sysfs_error; + if (wireless & 0x1) { wifi_rfkill = rfkill_alloc("hp-wifi", &device->dev, RFKILL_TYPE_WLAN, @@ -681,131 +573,14 @@ static int __devinit hp_wmi_rfkill_setup(struct platform_device *device) return 0; register_wwan_err: rfkill_destroy(wwan_rfkill); - wwan_rfkill = NULL; if (bluetooth_rfkill) rfkill_unregister(bluetooth_rfkill); register_bluetooth_error: rfkill_destroy(bluetooth_rfkill); - bluetooth_rfkill = NULL; if (wifi_rfkill) rfkill_unregister(wifi_rfkill); register_wifi_error: rfkill_destroy(wifi_rfkill); - wifi_rfkill = NULL; - return err; -} - -static int __devinit hp_wmi_rfkill2_setup(struct platform_device *device) -{ - int err, i; - struct bios_rfkill2_state state; - err = hp_wmi_perform_query(HPWMI_WIRELESS2_QUERY, 0, &state, - 0, sizeof(state)); - if (err) - return err; - - if (state.count > HPWMI_MAX_RFKILL2_DEVICES) { - printk(KERN_WARNING PREFIX "unable to parse 0x1b query output\n"); - return -EINVAL; - } - - for (i = 0; i < state.count; i++) { - struct rfkill *rfkill; - enum rfkill_type type; - char *name; - switch (state.device[i].radio_type) { - case HPWMI_WIFI: - type = RFKILL_TYPE_WLAN; - name = "hp-wifi"; - break; - case HPWMI_BLUETOOTH: - type = RFKILL_TYPE_BLUETOOTH; - name = "hp-bluetooth"; - break; - case HPWMI_WWAN: - type = RFKILL_TYPE_WWAN; - name = "hp-wwan"; - break; - default: - printk(KERN_WARNING PREFIX "unknown device type 0x%x\n", - state.device[i].radio_type); - continue; - } - - if (!state.device[i].vendor_id) { - printk(KERN_WARNING PREFIX "zero device %d while %d " - "reported\n", i, state.count); - continue; - } - - rfkill = rfkill_alloc(name, &device->dev, type, - &hp_wmi_rfkill2_ops, (void *)(long)i); - if (!rfkill) { - err = -ENOMEM; - goto fail; - } - - rfkill2[rfkill2_count].id = state.device[i].rfkill_id; - rfkill2[rfkill2_count].num = i; - rfkill2[rfkill2_count].rfkill = rfkill; - - rfkill_init_sw_state(rfkill, - IS_SWBLOCKED(state.device[i].power)); - rfkill_set_hw_state(rfkill, - IS_HWBLOCKED(state.device[i].power)); - - if (!(state.device[i].power & HPWMI_POWER_BIOS)) - printk(KERN_INFO PREFIX "device %s blocked by BIOS\n", - name); - - err = rfkill_register(rfkill); - if (err) { - rfkill_destroy(rfkill); - goto fail; - } - - rfkill2_count++; - } - - return 0; -fail: - for (; rfkill2_count > 0; rfkill2_count--) { - rfkill_unregister(rfkill2[rfkill2_count - 1].rfkill); - rfkill_destroy(rfkill2[rfkill2_count - 1].rfkill); - } - return err; -} - -static int __devinit hp_wmi_bios_setup(struct platform_device *device) -{ - int err; - - /* clear detected rfkill devices */ - wifi_rfkill = NULL; - bluetooth_rfkill = NULL; - wwan_rfkill = NULL; - rfkill2_count = 0; - - if (hp_wmi_rfkill_setup(device)) - hp_wmi_rfkill2_setup(device); - - err = device_create_file(&device->dev, &dev_attr_display); - if (err) - goto add_sysfs_error; - err = device_create_file(&device->dev, &dev_attr_hddtemp); - if (err) - goto add_sysfs_error; - err = device_create_file(&device->dev, &dev_attr_als); - if (err) - goto add_sysfs_error; - err = device_create_file(&device->dev, &dev_attr_dock); - if (err) - goto add_sysfs_error; - err = device_create_file(&device->dev, &dev_attr_tablet); - if (err) - goto add_sysfs_error; - return 0; - add_sysfs_error: cleanup_sysfs(device); return err; @@ -813,14 +588,8 @@ static int __devinit hp_wmi_bios_setup(struct platform_device *device) static int __exit hp_wmi_bios_remove(struct platform_device *device) { - int i; cleanup_sysfs(device); - for (i = 0; i < rfkill2_count; i++) { - rfkill_unregister(rfkill2[i].rfkill); - rfkill_destroy(rfkill2[i].rfkill); - } - if (wifi_rfkill) { rfkill_unregister(wifi_rfkill); rfkill_destroy(wifi_rfkill); @@ -853,9 +622,6 @@ static int hp_wmi_resume_handler(struct device *device) input_sync(hp_wmi_input_dev); } - if (rfkill2_count) - hp_wmi_rfkill2_refresh(); - if (wifi_rfkill) rfkill_set_states(wifi_rfkill, hp_wmi_get_sw_state(HPWMI_WIFI), diff --git a/trunk/drivers/platform/x86/ideapad-laptop.c b/trunk/drivers/platform/x86/ideapad-laptop.c index 21b101899bae..114d95247cdf 100644 --- a/trunk/drivers/platform/x86/ideapad-laptop.c +++ b/trunk/drivers/platform/x86/ideapad-laptop.c @@ -459,8 +459,6 @@ static void ideapad_acpi_notify(struct acpi_device *adevice, u32 event) if (test_bit(vpc_bit, &vpc1)) { if (vpc_bit == 9) ideapad_sync_rfk_state(adevice); - else if (vpc_bit == 4) - read_ec_data(handle, 0x12, &vpc2); else ideapad_input_report(priv, vpc_bit); } diff --git a/trunk/drivers/platform/x86/intel_ips.c b/trunk/drivers/platform/x86/intel_ips.c index 85c8ad43c0c5..1294a39373ba 100644 --- a/trunk/drivers/platform/x86/intel_ips.c +++ b/trunk/drivers/platform/x86/intel_ips.c @@ -1111,7 +1111,7 @@ static int ips_monitor(void *data) last_msecs = jiffies_to_msecs(jiffies); expire = jiffies + msecs_to_jiffies(IPS_SAMPLE_PERIOD); - __set_current_state(TASK_INTERRUPTIBLE); + __set_current_state(TASK_UNINTERRUPTIBLE); mod_timer(&timer, expire); schedule(); diff --git a/trunk/drivers/platform/x86/intel_mid_powerbtn.c b/trunk/drivers/platform/x86/intel_mid_powerbtn.c deleted file mode 100644 index 213e79ba68d5..000000000000 --- a/trunk/drivers/platform/x86/intel_mid_powerbtn.c +++ /dev/null @@ -1,148 +0,0 @@ -/* - * Power button driver for Medfield. - * - * Copyright (C) 2010 Intel Corp - * - * 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; version 2 of the License. - * - * 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 - -#define DRIVER_NAME "msic_power_btn" - -#define MSIC_IRQ_STAT 0x02 - #define MSIC_IRQ_PB (1 << 0) -#define MSIC_PB_CONFIG 0x3e -#define MSIC_PB_STATUS 0x3f - #define MSIC_PB_LEVEL (1 << 3) /* 1 - release, 0 - press */ - -struct mfld_pb_priv { - struct input_dev *input; - unsigned int irq; -}; - -static irqreturn_t mfld_pb_isr(int irq, void *dev_id) -{ - struct mfld_pb_priv *priv = dev_id; - int ret; - u8 pbstat; - - ret = intel_scu_ipc_ioread8(MSIC_PB_STATUS, &pbstat); - if (ret < 0) - return IRQ_HANDLED; - - input_event(priv->input, EV_KEY, KEY_POWER, !(pbstat & MSIC_PB_LEVEL)); - input_sync(priv->input); - - return IRQ_HANDLED; -} - -static int __devinit mfld_pb_probe(struct platform_device *pdev) -{ - struct mfld_pb_priv *priv; - struct input_dev *input; - int irq; - int error; - - irq = platform_get_irq(pdev, 0); - if (irq < 0) - return -EINVAL; - - priv = kzalloc(sizeof(struct mfld_pb_priv), GFP_KERNEL); - input = input_allocate_device(); - if (!priv || !input) { - error = -ENOMEM; - goto err_free_mem; - } - - priv->input = input; - priv->irq = irq; - - input->name = pdev->name; - input->phys = "power-button/input0"; - input->id.bustype = BUS_HOST; - input->dev.parent = &pdev->dev; - - input_set_capability(input, EV_KEY, KEY_POWER); - - error = request_threaded_irq(priv->irq, NULL, mfld_pb_isr, - 0, DRIVER_NAME, priv); - if (error) { - dev_err(&pdev->dev, - "unable to request irq %d for mfld power button\n", - irq); - goto err_free_mem; - } - - error = input_register_device(input); - if (error) { - dev_err(&pdev->dev, - "unable to register input dev, error %d\n", error); - goto err_free_irq; - } - - platform_set_drvdata(pdev, priv); - return 0; - -err_free_irq: - free_irq(priv->irq, priv); -err_free_mem: - input_free_device(input); - kfree(priv); - return error; -} - -static int __devexit mfld_pb_remove(struct platform_device *pdev) -{ - struct mfld_pb_priv *priv = platform_get_drvdata(pdev); - - free_irq(priv->irq, priv); - input_unregister_device(priv->input); - kfree(priv); - - platform_set_drvdata(pdev, NULL); - return 0; -} - -static struct platform_driver mfld_pb_driver = { - .driver = { - .name = DRIVER_NAME, - .owner = THIS_MODULE, - }, - .probe = mfld_pb_probe, - .remove = __devexit_p(mfld_pb_remove), -}; - -static int __init mfld_pb_init(void) -{ - return platform_driver_register(&mfld_pb_driver); -} -module_init(mfld_pb_init); - -static void __exit mfld_pb_exit(void) -{ - platform_driver_unregister(&mfld_pb_driver); -} -module_exit(mfld_pb_exit); - -MODULE_AUTHOR("Hong Liu "); -MODULE_DESCRIPTION("Intel Medfield Power Button Driver"); -MODULE_LICENSE("GPL v2"); -MODULE_ALIAS("platform:" DRIVER_NAME); diff --git a/trunk/drivers/platform/x86/intel_mid_thermal.c b/trunk/drivers/platform/x86/intel_mid_thermal.c deleted file mode 100644 index 6c12db503161..000000000000 --- a/trunk/drivers/platform/x86/intel_mid_thermal.c +++ /dev/null @@ -1,576 +0,0 @@ -/* - * intel_mid_thermal.c - Intel MID platform thermal driver - * - * Copyright (C) 2011 Intel 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 - * the Free Software Foundation; version 2 of the License. - * - * 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. - * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - * Author: Durgadoss R - */ - -#define pr_fmt(fmt) "intel_mid_thermal: " fmt - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -/* Number of thermal sensors */ -#define MSIC_THERMAL_SENSORS 4 - -/* ADC1 - thermal registers */ -#define MSIC_THERM_ADC1CNTL1 0x1C0 -#define MSIC_ADC_ENBL 0x10 -#define MSIC_ADC_START 0x08 - -#define MSIC_THERM_ADC1CNTL3 0x1C2 -#define MSIC_ADCTHERM_ENBL 0x04 -#define MSIC_ADCRRDATA_ENBL 0x05 -#define MSIC_CHANL_MASK_VAL 0x0F - -#define MSIC_STOPBIT_MASK 16 -#define MSIC_ADCTHERM_MASK 4 -#define ADC_CHANLS_MAX 15 /* Number of ADC channels */ -#define ADC_LOOP_MAX (ADC_CHANLS_MAX - MSIC_THERMAL_SENSORS) - -/* ADC channel code values */ -#define SKIN_SENSOR0_CODE 0x08 -#define SKIN_SENSOR1_CODE 0x09 -#define SYS_SENSOR_CODE 0x0A -#define MSIC_DIE_SENSOR_CODE 0x03 - -#define SKIN_THERM_SENSOR0 0 -#define SKIN_THERM_SENSOR1 1 -#define SYS_THERM_SENSOR2 2 -#define MSIC_DIE_THERM_SENSOR3 3 - -/* ADC code range */ -#define ADC_MAX 977 -#define ADC_MIN 162 -#define ADC_VAL0C 887 -#define ADC_VAL20C 720 -#define ADC_VAL40C 508 -#define ADC_VAL60C 315 - -/* ADC base addresses */ -#define ADC_CHNL_START_ADDR 0x1C5 /* increments by 1 */ -#define ADC_DATA_START_ADDR 0x1D4 /* increments by 2 */ - -/* MSIC die attributes */ -#define MSIC_DIE_ADC_MIN 488 -#define MSIC_DIE_ADC_MAX 1004 - -/* This holds the address of the first free ADC channel, - * among the 15 channels - */ -static int channel_index; - -struct platform_info { - struct platform_device *pdev; - struct thermal_zone_device *tzd[MSIC_THERMAL_SENSORS]; -}; - -struct thermal_device_info { - unsigned int chnl_addr; - int direct; - /* This holds the current temperature in millidegree celsius */ - long curr_temp; -}; - -/** - * to_msic_die_temp - converts adc_val to msic_die temperature - * @adc_val: ADC value to be converted - * - * Can sleep - */ -static int to_msic_die_temp(uint16_t adc_val) -{ - return (368 * (adc_val) / 1000) - 220; -} - -/** - * is_valid_adc - checks whether the adc code is within the defined range - * @min: minimum value for the sensor - * @max: maximum value for the sensor - * - * Can sleep - */ -static int is_valid_adc(uint16_t adc_val, uint16_t min, uint16_t max) -{ - return (adc_val >= min) && (adc_val <= max); -} - -/** - * adc_to_temp - converts the ADC code to temperature in C - * @direct: true if ths channel is direct index - * @adc_val: the adc_val that needs to be converted - * @tp: temperature return value - * - * Linear approximation is used to covert the skin adc value into temperature. - * This technique is used to avoid very long look-up table to get - * the appropriate temp value from ADC value. - * The adc code vs sensor temp curve is split into five parts - * to achieve very close approximate temp value with less than - * 0.5C error - */ -static int adc_to_temp(int direct, uint16_t adc_val, unsigned long *tp) -{ - int temp; - - /* Direct conversion for die temperature */ - if (direct) { - if (is_valid_adc(adc_val, MSIC_DIE_ADC_MIN, MSIC_DIE_ADC_MAX)) { - *tp = to_msic_die_temp(adc_val) * 1000; - return 0; - } - return -ERANGE; - } - - if (!is_valid_adc(adc_val, ADC_MIN, ADC_MAX)) - return -ERANGE; - - /* Linear approximation for skin temperature */ - if (adc_val > ADC_VAL0C) - temp = 177 - (adc_val/5); - else if ((adc_val <= ADC_VAL0C) && (adc_val > ADC_VAL20C)) - temp = 111 - (adc_val/8); - else if ((adc_val <= ADC_VAL20C) && (adc_val > ADC_VAL40C)) - temp = 92 - (adc_val/10); - else if ((adc_val <= ADC_VAL40C) && (adc_val > ADC_VAL60C)) - temp = 91 - (adc_val/10); - else - temp = 112 - (adc_val/6); - - /* Convert temperature in celsius to milli degree celsius */ - *tp = temp * 1000; - return 0; -} - -/** - * mid_read_temp - read sensors for temperature - * @temp: holds the current temperature for the sensor after reading - * - * reads the adc_code from the channel and converts it to real - * temperature. The converted value is stored in temp. - * - * Can sleep - */ -static int mid_read_temp(struct thermal_zone_device *tzd, unsigned long *temp) -{ - struct thermal_device_info *td_info = tzd->devdata; - uint16_t adc_val, addr; - uint8_t data = 0; - int ret; - unsigned long curr_temp; - - - addr = td_info->chnl_addr; - - /* Enable the msic for conversion before reading */ - ret = intel_scu_ipc_iowrite8(MSIC_THERM_ADC1CNTL3, MSIC_ADCRRDATA_ENBL); - if (ret) - return ret; - - /* Re-toggle the RRDATARD bit (temporary workaround) */ - ret = intel_scu_ipc_iowrite8(MSIC_THERM_ADC1CNTL3, MSIC_ADCTHERM_ENBL); - if (ret) - return ret; - - /* Read the higher bits of data */ - ret = intel_scu_ipc_ioread8(addr, &data); - if (ret) - return ret; - - /* Shift bits to accomodate the lower two data bits */ - adc_val = (data << 2); - addr++; - - ret = intel_scu_ipc_ioread8(addr, &data);/* Read lower bits */ - if (ret) - return ret; - - /* Adding lower two bits to the higher bits */ - data &= 03; - adc_val += data; - - /* Convert ADC value to temperature */ - ret = adc_to_temp(td_info->direct, adc_val, &curr_temp); - if (ret == 0) - *temp = td_info->curr_temp = curr_temp; - return ret; -} - -/** - * configure_adc - enables/disables the ADC for conversion - * @val: zero: disables the ADC non-zero:enables the ADC - * - * Enable/Disable the ADC depending on the argument - * - * Can sleep - */ -static int configure_adc(int val) -{ - int ret; - uint8_t data; - - ret = intel_scu_ipc_ioread8(MSIC_THERM_ADC1CNTL1, &data); - if (ret) - return ret; - - if (val) { - /* Enable and start the ADC */ - data |= (MSIC_ADC_ENBL | MSIC_ADC_START); - } else { - /* Just stop the ADC */ - data &= (~MSIC_ADC_START); - } - - return intel_scu_ipc_iowrite8(MSIC_THERM_ADC1CNTL1, data); -} - -/** - * set_up_therm_channel - enable thermal channel for conversion - * @base_addr: index of free msic ADC channel - * - * Enable all the three channels for conversion - * - * Can sleep - */ -static int set_up_therm_channel(u16 base_addr) -{ - int ret; - - /* Enable all the sensor channels */ - ret = intel_scu_ipc_iowrite8(base_addr, SKIN_SENSOR0_CODE); - if (ret) - return ret; - - ret = intel_scu_ipc_iowrite8(base_addr + 1, SKIN_SENSOR1_CODE); - if (ret) - return ret; - - ret = intel_scu_ipc_iowrite8(base_addr + 2, SYS_SENSOR_CODE); - if (ret) - return ret; - - /* Since this is the last channel, set the stop bit - to 1 by ORing the DIE_SENSOR_CODE with 0x10 */ - ret = intel_scu_ipc_iowrite8(base_addr + 3, - (MSIC_DIE_SENSOR_CODE | 0x10)); - if (ret) - return ret; - - /* Enable ADC and start it */ - return configure_adc(1); -} - -/** - * reset_stopbit - sets the stop bit to 0 on the given channel - * @addr: address of the channel - * - * Can sleep - */ -static int reset_stopbit(uint16_t addr) -{ - int ret; - uint8_t data; - ret = intel_scu_ipc_ioread8(addr, &data); - if (ret) - return ret; - /* Set the stop bit to zero */ - return intel_scu_ipc_iowrite8(addr, (data & 0xEF)); -} - -/** - * find_free_channel - finds an empty channel for conversion - * - * If the ADC is not enabled then start using 0th channel - * itself. Otherwise find an empty channel by looking for a - * channel in which the stopbit is set to 1. returns the index - * of the first free channel if succeeds or an error code. - * - * Context: can sleep - * - * FIXME: Ultimately the channel allocator will move into the intel_scu_ipc - * code. - */ -static int find_free_channel(void) -{ - int ret; - int i; - uint8_t data; - - /* check whether ADC is enabled */ - ret = intel_scu_ipc_ioread8(MSIC_THERM_ADC1CNTL1, &data); - if (ret) - return ret; - - if ((data & MSIC_ADC_ENBL) == 0) - return 0; - - /* ADC is already enabled; Looking for an empty channel */ - for (i = 0; i < ADC_CHANLS_MAX; i++) { - ret = intel_scu_ipc_ioread8(ADC_CHNL_START_ADDR + i, &data); - if (ret) - return ret; - - if (data & MSIC_STOPBIT_MASK) { - ret = i; - break; - } - } - return (ret > ADC_LOOP_MAX) ? (-EINVAL) : ret; -} - -/** - * mid_initialize_adc - initializing the ADC - * @dev: our device structure - * - * Initialize the ADC for reading thermistor values. Can sleep. - */ -static int mid_initialize_adc(struct device *dev) -{ - u8 data; - u16 base_addr; - int ret; - - /* - * Ensure that adctherm is disabled before we - * initialize the ADC - */ - ret = intel_scu_ipc_ioread8(MSIC_THERM_ADC1CNTL3, &data); - if (ret) - return ret; - - if (data & MSIC_ADCTHERM_MASK) - dev_warn(dev, "ADCTHERM already set"); - - /* Index of the first channel in which the stop bit is set */ - channel_index = find_free_channel(); - if (channel_index < 0) { - dev_err(dev, "No free ADC channels"); - return channel_index; - } - - base_addr = ADC_CHNL_START_ADDR + channel_index; - - if (!(channel_index == 0 || channel_index == ADC_LOOP_MAX)) { - /* Reset stop bit for channels other than 0 and 12 */ - ret = reset_stopbit(base_addr); - if (ret) - return ret; - - /* Index of the first free channel */ - base_addr++; - channel_index++; - } - - ret = set_up_therm_channel(base_addr); - if (ret) { - dev_err(dev, "unable to enable ADC"); - return ret; - } - dev_dbg(dev, "ADC initialization successful"); - return ret; -} - -/** - * initialize_sensor - sets default temp and timer ranges - * @index: index of the sensor - * - * Context: can sleep - */ -static struct thermal_device_info *initialize_sensor(int index) -{ - struct thermal_device_info *td_info = - kzalloc(sizeof(struct thermal_device_info), GFP_KERNEL); - - if (!td_info) - return NULL; - - /* Set the base addr of the channel for this sensor */ - td_info->chnl_addr = ADC_DATA_START_ADDR + 2 * (channel_index + index); - /* Sensor 3 is direct conversion */ - if (index == 3) - td_info->direct = 1; - return td_info; -} - -/** - * mid_thermal_resume - resume routine - * @pdev: platform device structure - * - * mid thermal resume: re-initializes the adc. Can sleep. - */ -static int mid_thermal_resume(struct platform_device *pdev) -{ - return mid_initialize_adc(&pdev->dev); -} - -/** - * mid_thermal_suspend - suspend routine - * @pdev: platform device structure - * - * mid thermal suspend implements the suspend functionality - * by stopping the ADC. Can sleep. - */ -static int mid_thermal_suspend(struct platform_device *pdev, pm_message_t mesg) -{ - /* - * This just stops the ADC and does not disable it. - * temporary workaround until we have a generic ADC driver. - * If 0 is passed, it disables the ADC. - */ - return configure_adc(0); -} - -/** - * read_curr_temp - reads the current temperature and stores in temp - * @temp: holds the current temperature value after reading - * - * Can sleep - */ -static int read_curr_temp(struct thermal_zone_device *tzd, unsigned long *temp) -{ - WARN_ON(tzd == NULL); - return mid_read_temp(tzd, temp); -} - -/* Can't be const */ -static struct thermal_zone_device_ops tzd_ops = { - .get_temp = read_curr_temp, -}; - - -/** - * mid_thermal_probe - mfld thermal initialize - * @pdev: platform device structure - * - * mid thermal probe initializes the hardware and registers - * all the sensors with the generic thermal framework. Can sleep. - */ -static int mid_thermal_probe(struct platform_device *pdev) -{ - static char *name[MSIC_THERMAL_SENSORS] = { - "skin0", "skin1", "sys", "msicdie" - }; - - int ret; - int i; - struct platform_info *pinfo; - - pinfo = kzalloc(sizeof(struct platform_info), GFP_KERNEL); - if (!pinfo) - return -ENOMEM; - - /* Initializing the hardware */ - ret = mid_initialize_adc(&pdev->dev); - if (ret) { - dev_err(&pdev->dev, "ADC init failed"); - kfree(pinfo); - return ret; - } - - /* Register each sensor with the generic thermal framework*/ - for (i = 0; i < MSIC_THERMAL_SENSORS; i++) { - pinfo->tzd[i] = thermal_zone_device_register(name[i], - 0, initialize_sensor(i), - &tzd_ops, 0, 0, 0, 0); - if (IS_ERR(pinfo->tzd[i])) - goto reg_fail; - } - - pinfo->pdev = pdev; - platform_set_drvdata(pdev, pinfo); - return 0; - -reg_fail: - ret = PTR_ERR(pinfo->tzd[i]); - while (--i >= 0) - thermal_zone_device_unregister(pinfo->tzd[i]); - configure_adc(0); - kfree(pinfo); - return ret; -} - -/** - * mid_thermal_remove - mfld thermal finalize - * @dev: platform device structure - * - * MLFD thermal remove unregisters all the sensors from the generic - * thermal framework. Can sleep. - */ -static int mid_thermal_remove(struct platform_device *pdev) -{ - int i; - struct platform_info *pinfo = platform_get_drvdata(pdev); - - for (i = 0; i < MSIC_THERMAL_SENSORS; i++) - thermal_zone_device_unregister(pinfo->tzd[i]); - - platform_set_drvdata(pdev, NULL); - - /* Stop the ADC */ - return configure_adc(0); -} - -/********************************************************************* - * Driver initialisation and finalization - *********************************************************************/ - -#define DRIVER_NAME "msic_sensor" - -static const struct platform_device_id therm_id_table[] = { - { DRIVER_NAME, 1 }, - { } -}; - -static struct platform_driver mid_thermal_driver = { - .driver = { - .name = DRIVER_NAME, - .owner = THIS_MODULE, - }, - .probe = mid_thermal_probe, - .suspend = mid_thermal_suspend, - .resume = mid_thermal_resume, - .remove = __devexit_p(mid_thermal_remove), - .id_table = therm_id_table, -}; - -static int __init mid_thermal_module_init(void) -{ - return platform_driver_register(&mid_thermal_driver); -} - -static void __exit mid_thermal_module_exit(void) -{ - platform_driver_unregister(&mid_thermal_driver); -} - -module_init(mid_thermal_module_init); -module_exit(mid_thermal_module_exit); - -MODULE_AUTHOR("Durgadoss R "); -MODULE_DESCRIPTION("Intel Medfield Platform Thermal Driver"); -MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/platform/x86/intel_pmic_gpio.c b/trunk/drivers/platform/x86/intel_pmic_gpio.c index d653104b59cb..61433d492862 100644 --- a/trunk/drivers/platform/x86/intel_pmic_gpio.c +++ b/trunk/drivers/platform/x86/intel_pmic_gpio.c @@ -257,11 +257,9 @@ static int __devinit platform_pmic_gpio_probe(struct platform_device *pdev) } for (i = 0; i < 8; i++) { - irq_set_chip_and_handler_name(i + pg->irq_base, - &pmic_irqchip, - handle_simple_irq, - "demux"); - irq_set_chip_data(i + pg->irq_base, pg); + set_irq_chip_and_handler_name(i + pg->irq_base, &pmic_irqchip, + handle_simple_irq, "demux"); + set_irq_chip_data(i + pg->irq_base, pg); } return 0; err: diff --git a/trunk/drivers/platform/x86/intel_rar_register.c b/trunk/drivers/platform/x86/intel_rar_register.c index bde47e9080cd..2b11a33325e6 100644 --- a/trunk/drivers/platform/x86/intel_rar_register.c +++ b/trunk/drivers/platform/x86/intel_rar_register.c @@ -485,7 +485,7 @@ EXPORT_SYMBOL(rar_lock); * * The register_rar function is to used by other device drivers * to ensure that this driver is ready. As we cannot be sure of - * the compile/execute order of drivers in the kernel, it is + * the compile/execute order of drivers in ther kernel, it is * best to give this driver a callback function to call when * it is ready to give out addresses. The callback function * would have those steps that continue the initialization of diff --git a/trunk/drivers/platform/x86/intel_scu_ipc.c b/trunk/drivers/platform/x86/intel_scu_ipc.c index 940accbe28d3..a91d510a798b 100644 --- a/trunk/drivers/platform/x86/intel_scu_ipc.c +++ b/trunk/drivers/platform/x86/intel_scu_ipc.c @@ -9,7 +9,7 @@ * as published by the Free Software Foundation; version 2 * of the License. * - * SCU running in ARC processor communicates with other entity running in IA + * SCU runing in ARC processor communicates with other entity running in IA * core through IPC mechanism which in turn messaging between IA core ad SCU. * SCU has two IPC mechanism IPC-1 and IPC-2. IPC-1 is used between IA32 and * SCU where IPC-2 is used between P-Unit and SCU. This driver delas with diff --git a/trunk/drivers/platform/x86/msi-laptop.c b/trunk/drivers/platform/x86/msi-laptop.c index 23fb2afda00b..142d38579314 100644 --- a/trunk/drivers/platform/x86/msi-laptop.c +++ b/trunk/drivers/platform/x86/msi-laptop.c @@ -51,8 +51,6 @@ * laptop as MSI S270. YMMV. */ -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - #include #include #include @@ -62,8 +60,6 @@ #include #include #include -#include -#include #define MSI_DRIVER_VERSION "0.5" @@ -82,9 +78,6 @@ #define MSI_STANDARD_EC_SCM_LOAD_ADDRESS 0x2d #define MSI_STANDARD_EC_SCM_LOAD_MASK (1 << 0) -#define MSI_STANDARD_EC_TOUCHPAD_ADDRESS 0xe4 -#define MSI_STANDARD_EC_TOUCHPAD_MASK (1 << 4) - static int msi_laptop_resume(struct platform_device *device); #define MSI_STANDARD_EC_DEVICES_EXISTS_ADDRESS 0x2f @@ -97,14 +90,6 @@ static int auto_brightness; module_param(auto_brightness, int, 0); MODULE_PARM_DESC(auto_brightness, "Enable automatic brightness control (0: disabled; 1: enabled; 2: don't touch)"); -static const struct key_entry msi_laptop_keymap[] = { - {KE_KEY, KEY_TOUCHPAD_ON, {KEY_TOUCHPAD_ON} }, /* Touch Pad On */ - {KE_KEY, KEY_TOUCHPAD_OFF, {KEY_TOUCHPAD_OFF} },/* Touch Pad On */ - {KE_END, 0} -}; - -static struct input_dev *msi_laptop_input_dev; - static bool old_ec_model; static int wlan_s, bluetooth_s, threeg_s; static int threeg_exists; @@ -447,7 +432,8 @@ static struct platform_device *msipf_device; static int dmi_check_cb(const struct dmi_system_id *id) { - pr_info("Identified laptop model '%s'.\n", id->ident); + printk(KERN_INFO "msi-laptop: Identified laptop model '%s'.\n", + id->ident); return 1; } @@ -619,21 +605,6 @@ static void msi_update_rfkill(struct work_struct *ignored) } static DECLARE_DELAYED_WORK(msi_rfkill_work, msi_update_rfkill); -static void msi_send_touchpad_key(struct work_struct *ignored) -{ - u8 rdata; - int result; - - result = ec_read(MSI_STANDARD_EC_TOUCHPAD_ADDRESS, &rdata); - if (result < 0) - return; - - sparse_keymap_report_event(msi_laptop_input_dev, - (rdata & MSI_STANDARD_EC_TOUCHPAD_MASK) ? - KEY_TOUCHPAD_ON : KEY_TOUCHPAD_OFF, 1, true); -} -static DECLARE_DELAYED_WORK(msi_touchpad_work, msi_send_touchpad_key); - static bool msi_laptop_i8042_filter(unsigned char data, unsigned char str, struct serio *port) { @@ -642,17 +613,12 @@ static bool msi_laptop_i8042_filter(unsigned char data, unsigned char str, if (str & 0x20) return false; - /* 0x54 wwan, 0x62 bluetooth, 0x76 wlan, 0xE4 touchpad toggle*/ + /* 0x54 wwan, 0x62 bluetooth, 0x76 wlan*/ if (unlikely(data == 0xe0)) { extended = true; return false; } else if (unlikely(extended)) { - extended = false; switch (data) { - case 0xE4: - schedule_delayed_work(&msi_touchpad_work, - round_jiffies_relative(0.5 * HZ)); - break; case 0x54: case 0x62: case 0x76: @@ -660,6 +626,7 @@ static bool msi_laptop_i8042_filter(unsigned char data, unsigned char str, round_jiffies_relative(0.5 * HZ)); break; } + extended = false; } return false; @@ -764,42 +731,6 @@ static int msi_laptop_resume(struct platform_device *device) return 0; } -static int __init msi_laptop_input_setup(void) -{ - int err; - - msi_laptop_input_dev = input_allocate_device(); - if (!msi_laptop_input_dev) - return -ENOMEM; - - msi_laptop_input_dev->name = "MSI Laptop hotkeys"; - msi_laptop_input_dev->phys = "msi-laptop/input0"; - msi_laptop_input_dev->id.bustype = BUS_HOST; - - err = sparse_keymap_setup(msi_laptop_input_dev, - msi_laptop_keymap, NULL); - if (err) - goto err_free_dev; - - err = input_register_device(msi_laptop_input_dev); - if (err) - goto err_free_keymap; - - return 0; - -err_free_keymap: - sparse_keymap_free(msi_laptop_input_dev); -err_free_dev: - input_free_device(msi_laptop_input_dev); - return err; -} - -static void msi_laptop_input_destroy(void) -{ - sparse_keymap_free(msi_laptop_input_dev); - input_unregister_device(msi_laptop_input_dev); -} - static int load_scm_model_init(struct platform_device *sdev) { u8 data; @@ -828,23 +759,16 @@ static int load_scm_model_init(struct platform_device *sdev) if (result < 0) goto fail_rfkill; - /* setup input device */ - result = msi_laptop_input_setup(); - if (result) - goto fail_input; - result = i8042_install_filter(msi_laptop_i8042_filter); if (result) { - pr_err("Unable to install key filter\n"); + printk(KERN_ERR + "msi-laptop: Unable to install key filter\n"); goto fail_filter; } return 0; fail_filter: - msi_laptop_input_destroy(); - -fail_input: rfkill_cleanup(); fail_rfkill: @@ -875,7 +799,7 @@ static int __init msi_init(void) /* Register backlight stuff */ if (acpi_video_backlight_support()) { - pr_info("Brightness ignored, must be controlled " + printk(KERN_INFO "MSI: Brightness ignored, must be controlled " "by ACPI video driver\n"); } else { struct backlight_properties props; @@ -930,7 +854,7 @@ static int __init msi_init(void) if (auto_brightness != 2) set_auto_brightness(auto_brightness); - pr_info("driver "MSI_DRIVER_VERSION" successfully loaded.\n"); + printk(KERN_INFO "msi-laptop: driver "MSI_DRIVER_VERSION" successfully loaded.\n"); return 0; @@ -962,7 +886,6 @@ static void __exit msi_cleanup(void) { if (load_scm_model) { i8042_remove_filter(msi_laptop_i8042_filter); - msi_laptop_input_destroy(); cancel_delayed_work_sync(&msi_rfkill_work); rfkill_cleanup(); } @@ -978,7 +901,7 @@ static void __exit msi_cleanup(void) if (auto_brightness != 2) set_auto_brightness(1); - pr_info("driver unloaded.\n"); + printk(KERN_INFO "msi-laptop: driver unloaded.\n"); } module_init(msi_init); diff --git a/trunk/drivers/platform/x86/samsung-laptop.c b/trunk/drivers/platform/x86/samsung-laptop.c deleted file mode 100644 index de434c6dc2d6..000000000000 --- a/trunk/drivers/platform/x86/samsung-laptop.c +++ /dev/null @@ -1,832 +0,0 @@ -/* - * Samsung Laptop driver - * - * Copyright (C) 2009,2011 Greg Kroah-Hartman (gregkh@suse.de) - * Copyright (C) 2009,2011 Novell Inc. - * - * 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. - * - */ -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* - * This driver is needed because a number of Samsung laptops do not hook - * their control settings through ACPI. So we have to poke around in the - * BIOS to do things like brightness values, and "special" key controls. - */ - -/* - * We have 0 - 8 as valid brightness levels. The specs say that level 0 should - * be reserved by the BIOS (which really doesn't make much sense), we tell - * userspace that the value is 0 - 7 and then just tell the hardware 1 - 8 - */ -#define MAX_BRIGHT 0x07 - - -#define SABI_IFACE_MAIN 0x00 -#define SABI_IFACE_SUB 0x02 -#define SABI_IFACE_COMPLETE 0x04 -#define SABI_IFACE_DATA 0x05 - -/* Structure to get data back to the calling function */ -struct sabi_retval { - u8 retval[20]; -}; - -struct sabi_header_offsets { - u8 port; - u8 re_mem; - u8 iface_func; - u8 en_mem; - u8 data_offset; - u8 data_segment; -}; - -struct sabi_commands { - /* - * Brightness is 0 - 8, as described above. - * Value 0 is for the BIOS to use - */ - u8 get_brightness; - u8 set_brightness; - - /* - * first byte: - * 0x00 - wireless is off - * 0x01 - wireless is on - * second byte: - * 0x02 - 3G is off - * 0x03 - 3G is on - * TODO, verify 3G is correct, that doesn't seem right... - */ - u8 get_wireless_button; - u8 set_wireless_button; - - /* 0 is off, 1 is on */ - u8 get_backlight; - u8 set_backlight; - - /* - * 0x80 or 0x00 - no action - * 0x81 - recovery key pressed - */ - u8 get_recovery_mode; - u8 set_recovery_mode; - - /* - * on seclinux: 0 is low, 1 is high, - * on swsmi: 0 is normal, 1 is silent, 2 is turbo - */ - u8 get_performance_level; - u8 set_performance_level; - - /* - * Tell the BIOS that Linux is running on this machine. - * 81 is on, 80 is off - */ - u8 set_linux; -}; - -struct sabi_performance_level { - const char *name; - u8 value; -}; - -struct sabi_config { - const char *test_string; - u16 main_function; - const struct sabi_header_offsets header_offsets; - const struct sabi_commands commands; - const struct sabi_performance_level performance_levels[4]; - u8 min_brightness; - u8 max_brightness; -}; - -static const struct sabi_config sabi_configs[] = { - { - .test_string = "SECLINUX", - - .main_function = 0x4c49, - - .header_offsets = { - .port = 0x00, - .re_mem = 0x02, - .iface_func = 0x03, - .en_mem = 0x04, - .data_offset = 0x05, - .data_segment = 0x07, - }, - - .commands = { - .get_brightness = 0x00, - .set_brightness = 0x01, - - .get_wireless_button = 0x02, - .set_wireless_button = 0x03, - - .get_backlight = 0x04, - .set_backlight = 0x05, - - .get_recovery_mode = 0x06, - .set_recovery_mode = 0x07, - - .get_performance_level = 0x08, - .set_performance_level = 0x09, - - .set_linux = 0x0a, - }, - - .performance_levels = { - { - .name = "silent", - .value = 0, - }, - { - .name = "normal", - .value = 1, - }, - { }, - }, - .min_brightness = 1, - .max_brightness = 8, - }, - { - .test_string = "SwSmi@", - - .main_function = 0x5843, - - .header_offsets = { - .port = 0x00, - .re_mem = 0x04, - .iface_func = 0x02, - .en_mem = 0x03, - .data_offset = 0x05, - .data_segment = 0x07, - }, - - .commands = { - .get_brightness = 0x10, - .set_brightness = 0x11, - - .get_wireless_button = 0x12, - .set_wireless_button = 0x13, - - .get_backlight = 0x2d, - .set_backlight = 0x2e, - - .get_recovery_mode = 0xff, - .set_recovery_mode = 0xff, - - .get_performance_level = 0x31, - .set_performance_level = 0x32, - - .set_linux = 0xff, - }, - - .performance_levels = { - { - .name = "normal", - .value = 0, - }, - { - .name = "silent", - .value = 1, - }, - { - .name = "overclock", - .value = 2, - }, - { }, - }, - .min_brightness = 0, - .max_brightness = 8, - }, - { }, -}; - -static const struct sabi_config *sabi_config; - -static void __iomem *sabi; -static void __iomem *sabi_iface; -static void __iomem *f0000_segment; -static struct backlight_device *backlight_device; -static struct mutex sabi_mutex; -static struct platform_device *sdev; -static struct rfkill *rfk; - -static int force; -module_param(force, bool, 0); -MODULE_PARM_DESC(force, - "Disable the DMI check and forces the driver to be loaded"); - -static int debug; -module_param(debug, bool, S_IRUGO | S_IWUSR); -MODULE_PARM_DESC(debug, "Debug enabled or not"); - -static int sabi_get_command(u8 command, struct sabi_retval *sretval) -{ - int retval = 0; - u16 port = readw(sabi + sabi_config->header_offsets.port); - u8 complete, iface_data; - - mutex_lock(&sabi_mutex); - - /* enable memory to be able to write to it */ - outb(readb(sabi + sabi_config->header_offsets.en_mem), port); - - /* write out the command */ - writew(sabi_config->main_function, sabi_iface + SABI_IFACE_MAIN); - writew(command, sabi_iface + SABI_IFACE_SUB); - writeb(0, sabi_iface + SABI_IFACE_COMPLETE); - outb(readb(sabi + sabi_config->header_offsets.iface_func), port); - - /* write protect memory to make it safe */ - outb(readb(sabi + sabi_config->header_offsets.re_mem), port); - - /* see if the command actually succeeded */ - complete = readb(sabi_iface + SABI_IFACE_COMPLETE); - iface_data = readb(sabi_iface + SABI_IFACE_DATA); - if (complete != 0xaa || iface_data == 0xff) { - pr_warn("SABI get command 0x%02x failed with completion flag 0x%02x and data 0x%02x\n", - command, complete, iface_data); - retval = -EINVAL; - goto exit; - } - /* - * Save off the data into a structure so the caller use it. - * Right now we only want the first 4 bytes, - * There are commands that need more, but not for the ones we - * currently care about. - */ - sretval->retval[0] = readb(sabi_iface + SABI_IFACE_DATA); - sretval->retval[1] = readb(sabi_iface + SABI_IFACE_DATA + 1); - sretval->retval[2] = readb(sabi_iface + SABI_IFACE_DATA + 2); - sretval->retval[3] = readb(sabi_iface + SABI_IFACE_DATA + 3); - -exit: - mutex_unlock(&sabi_mutex); - return retval; - -} - -static int sabi_set_command(u8 command, u8 data) -{ - int retval = 0; - u16 port = readw(sabi + sabi_config->header_offsets.port); - u8 complete, iface_data; - - mutex_lock(&sabi_mutex); - - /* enable memory to be able to write to it */ - outb(readb(sabi + sabi_config->header_offsets.en_mem), port); - - /* write out the command */ - writew(sabi_config->main_function, sabi_iface + SABI_IFACE_MAIN); - writew(command, sabi_iface + SABI_IFACE_SUB); - writeb(0, sabi_iface + SABI_IFACE_COMPLETE); - writeb(data, sabi_iface + SABI_IFACE_DATA); - outb(readb(sabi + sabi_config->header_offsets.iface_func), port); - - /* write protect memory to make it safe */ - outb(readb(sabi + sabi_config->header_offsets.re_mem), port); - - /* see if the command actually succeeded */ - complete = readb(sabi_iface + SABI_IFACE_COMPLETE); - iface_data = readb(sabi_iface + SABI_IFACE_DATA); - if (complete != 0xaa || iface_data == 0xff) { - pr_warn("SABI set command 0x%02x failed with completion flag 0x%02x and data 0x%02x\n", - command, complete, iface_data); - retval = -EINVAL; - } - - mutex_unlock(&sabi_mutex); - return retval; -} - -static void test_backlight(void) -{ - struct sabi_retval sretval; - - sabi_get_command(sabi_config->commands.get_backlight, &sretval); - printk(KERN_DEBUG "backlight = 0x%02x\n", sretval.retval[0]); - - sabi_set_command(sabi_config->commands.set_backlight, 0); - printk(KERN_DEBUG "backlight should be off\n"); - - sabi_get_command(sabi_config->commands.get_backlight, &sretval); - printk(KERN_DEBUG "backlight = 0x%02x\n", sretval.retval[0]); - - msleep(1000); - - sabi_set_command(sabi_config->commands.set_backlight, 1); - printk(KERN_DEBUG "backlight should be on\n"); - - sabi_get_command(sabi_config->commands.get_backlight, &sretval); - printk(KERN_DEBUG "backlight = 0x%02x\n", sretval.retval[0]); -} - -static void test_wireless(void) -{ - struct sabi_retval sretval; - - sabi_get_command(sabi_config->commands.get_wireless_button, &sretval); - printk(KERN_DEBUG "wireless led = 0x%02x\n", sretval.retval[0]); - - sabi_set_command(sabi_config->commands.set_wireless_button, 0); - printk(KERN_DEBUG "wireless led should be off\n"); - - sabi_get_command(sabi_config->commands.get_wireless_button, &sretval); - printk(KERN_DEBUG "wireless led = 0x%02x\n", sretval.retval[0]); - - msleep(1000); - - sabi_set_command(sabi_config->commands.set_wireless_button, 1); - printk(KERN_DEBUG "wireless led should be on\n"); - - sabi_get_command(sabi_config->commands.get_wireless_button, &sretval); - printk(KERN_DEBUG "wireless led = 0x%02x\n", sretval.retval[0]); -} - -static u8 read_brightness(void) -{ - struct sabi_retval sretval; - int user_brightness = 0; - int retval; - - retval = sabi_get_command(sabi_config->commands.get_brightness, - &sretval); - if (!retval) { - user_brightness = sretval.retval[0]; - if (user_brightness != 0) - user_brightness -= sabi_config->min_brightness; - } - return user_brightness; -} - -static void set_brightness(u8 user_brightness) -{ - u8 user_level = user_brightness - sabi_config->min_brightness; - - sabi_set_command(sabi_config->commands.set_brightness, user_level); -} - -static int get_brightness(struct backlight_device *bd) -{ - return (int)read_brightness(); -} - -static int update_status(struct backlight_device *bd) -{ - set_brightness(bd->props.brightness); - - if (bd->props.power == FB_BLANK_UNBLANK) - sabi_set_command(sabi_config->commands.set_backlight, 1); - else - sabi_set_command(sabi_config->commands.set_backlight, 0); - return 0; -} - -static const struct backlight_ops backlight_ops = { - .get_brightness = get_brightness, - .update_status = update_status, -}; - -static int rfkill_set(void *data, bool blocked) -{ - /* Do something with blocked...*/ - /* - * blocked == false is on - * blocked == true is off - */ - if (blocked) - sabi_set_command(sabi_config->commands.set_wireless_button, 0); - else - sabi_set_command(sabi_config->commands.set_wireless_button, 1); - - return 0; -} - -static struct rfkill_ops rfkill_ops = { - .set_block = rfkill_set, -}; - -static int init_wireless(struct platform_device *sdev) -{ - int retval; - - rfk = rfkill_alloc("samsung-wifi", &sdev->dev, RFKILL_TYPE_WLAN, - &rfkill_ops, NULL); - if (!rfk) - return -ENOMEM; - - retval = rfkill_register(rfk); - if (retval) { - rfkill_destroy(rfk); - return -ENODEV; - } - - return 0; -} - -static void destroy_wireless(void) -{ - rfkill_unregister(rfk); - rfkill_destroy(rfk); -} - -static ssize_t get_performance_level(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct sabi_retval sretval; - int retval; - int i; - - /* Read the state */ - retval = sabi_get_command(sabi_config->commands.get_performance_level, - &sretval); - if (retval) - return retval; - - /* The logic is backwards, yeah, lots of fun... */ - for (i = 0; sabi_config->performance_levels[i].name; ++i) { - if (sretval.retval[0] == sabi_config->performance_levels[i].value) - return sprintf(buf, "%s\n", sabi_config->performance_levels[i].name); - } - return sprintf(buf, "%s\n", "unknown"); -} - -static ssize_t set_performance_level(struct device *dev, - struct device_attribute *attr, const char *buf, - size_t count) -{ - if (count >= 1) { - int i; - for (i = 0; sabi_config->performance_levels[i].name; ++i) { - const struct sabi_performance_level *level = - &sabi_config->performance_levels[i]; - if (!strncasecmp(level->name, buf, strlen(level->name))) { - sabi_set_command(sabi_config->commands.set_performance_level, - level->value); - break; - } - } - if (!sabi_config->performance_levels[i].name) - return -EINVAL; - } - return count; -} -static DEVICE_ATTR(performance_level, S_IWUSR | S_IRUGO, - get_performance_level, set_performance_level); - - -static int __init dmi_check_cb(const struct dmi_system_id *id) -{ - pr_info("found laptop model '%s'\n", - id->ident); - return 1; -} - -static struct dmi_system_id __initdata samsung_dmi_table[] = { - { - .ident = "N128", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, - "SAMSUNG ELECTRONICS CO., LTD."), - DMI_MATCH(DMI_PRODUCT_NAME, "N128"), - DMI_MATCH(DMI_BOARD_NAME, "N128"), - }, - .callback = dmi_check_cb, - }, - { - .ident = "N130", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, - "SAMSUNG ELECTRONICS CO., LTD."), - DMI_MATCH(DMI_PRODUCT_NAME, "N130"), - DMI_MATCH(DMI_BOARD_NAME, "N130"), - }, - .callback = dmi_check_cb, - }, - { - .ident = "X125", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, - "SAMSUNG ELECTRONICS CO., LTD."), - DMI_MATCH(DMI_PRODUCT_NAME, "X125"), - DMI_MATCH(DMI_BOARD_NAME, "X125"), - }, - .callback = dmi_check_cb, - }, - { - .ident = "X120/X170", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, - "SAMSUNG ELECTRONICS CO., LTD."), - DMI_MATCH(DMI_PRODUCT_NAME, "X120/X170"), - DMI_MATCH(DMI_BOARD_NAME, "X120/X170"), - }, - .callback = dmi_check_cb, - }, - { - .ident = "NC10", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, - "SAMSUNG ELECTRONICS CO., LTD."), - DMI_MATCH(DMI_PRODUCT_NAME, "NC10"), - DMI_MATCH(DMI_BOARD_NAME, "NC10"), - }, - .callback = dmi_check_cb, - }, - { - .ident = "NP-Q45", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, - "SAMSUNG ELECTRONICS CO., LTD."), - DMI_MATCH(DMI_PRODUCT_NAME, "SQ45S70S"), - DMI_MATCH(DMI_BOARD_NAME, "SQ45S70S"), - }, - .callback = dmi_check_cb, - }, - { - .ident = "X360", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, - "SAMSUNG ELECTRONICS CO., LTD."), - DMI_MATCH(DMI_PRODUCT_NAME, "X360"), - DMI_MATCH(DMI_BOARD_NAME, "X360"), - }, - .callback = dmi_check_cb, - }, - { - .ident = "R518", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, - "SAMSUNG ELECTRONICS CO., LTD."), - DMI_MATCH(DMI_PRODUCT_NAME, "R518"), - DMI_MATCH(DMI_BOARD_NAME, "R518"), - }, - .callback = dmi_check_cb, - }, - { - .ident = "R519/R719", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, - "SAMSUNG ELECTRONICS CO., LTD."), - DMI_MATCH(DMI_PRODUCT_NAME, "R519/R719"), - DMI_MATCH(DMI_BOARD_NAME, "R519/R719"), - }, - .callback = dmi_check_cb, - }, - { - .ident = "N150/N210/N220", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, - "SAMSUNG ELECTRONICS CO., LTD."), - DMI_MATCH(DMI_PRODUCT_NAME, "N150/N210/N220"), - DMI_MATCH(DMI_BOARD_NAME, "N150/N210/N220"), - }, - .callback = dmi_check_cb, - }, - { - .ident = "N150P/N210P/N220P", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, - "SAMSUNG ELECTRONICS CO., LTD."), - DMI_MATCH(DMI_PRODUCT_NAME, "N150P/N210P/N220P"), - DMI_MATCH(DMI_BOARD_NAME, "N150P/N210P/N220P"), - }, - .callback = dmi_check_cb, - }, - { - .ident = "R530/R730", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."), - DMI_MATCH(DMI_PRODUCT_NAME, "R530/R730"), - DMI_MATCH(DMI_BOARD_NAME, "R530/R730"), - }, - .callback = dmi_check_cb, - }, - { - .ident = "NF110/NF210/NF310", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."), - DMI_MATCH(DMI_PRODUCT_NAME, "NF110/NF210/NF310"), - DMI_MATCH(DMI_BOARD_NAME, "NF110/NF210/NF310"), - }, - .callback = dmi_check_cb, - }, - { - .ident = "N145P/N250P/N260P", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."), - DMI_MATCH(DMI_PRODUCT_NAME, "N145P/N250P/N260P"), - DMI_MATCH(DMI_BOARD_NAME, "N145P/N250P/N260P"), - }, - .callback = dmi_check_cb, - }, - { - .ident = "R70/R71", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, - "SAMSUNG ELECTRONICS CO., LTD."), - DMI_MATCH(DMI_PRODUCT_NAME, "R70/R71"), - DMI_MATCH(DMI_BOARD_NAME, "R70/R71"), - }, - .callback = dmi_check_cb, - }, - { - .ident = "P460", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."), - DMI_MATCH(DMI_PRODUCT_NAME, "P460"), - DMI_MATCH(DMI_BOARD_NAME, "P460"), - }, - .callback = dmi_check_cb, - }, - { }, -}; -MODULE_DEVICE_TABLE(dmi, samsung_dmi_table); - -static int find_signature(void __iomem *memcheck, const char *testStr) -{ - int i = 0; - int loca; - - for (loca = 0; loca < 0xffff; loca++) { - char temp = readb(memcheck + loca); - - if (temp == testStr[i]) { - if (i == strlen(testStr)-1) - break; - ++i; - } else { - i = 0; - } - } - return loca; -} - -static int __init samsung_init(void) -{ - struct backlight_properties props; - struct sabi_retval sretval; - unsigned int ifaceP; - int i; - int loca; - int retval; - - mutex_init(&sabi_mutex); - - if (!force && !dmi_check_system(samsung_dmi_table)) - return -ENODEV; - - f0000_segment = ioremap_nocache(0xf0000, 0xffff); - if (!f0000_segment) { - pr_err("Can't map the segment at 0xf0000\n"); - return -EINVAL; - } - - /* Try to find one of the signatures in memory to find the header */ - for (i = 0; sabi_configs[i].test_string != 0; ++i) { - sabi_config = &sabi_configs[i]; - loca = find_signature(f0000_segment, sabi_config->test_string); - if (loca != 0xffff) - break; - } - - if (loca == 0xffff) { - pr_err("This computer does not support SABI\n"); - goto error_no_signature; - } - - /* point to the SMI port Number */ - loca += 1; - sabi = (f0000_segment + loca); - - if (debug) { - printk(KERN_DEBUG "This computer supports SABI==%x\n", - loca + 0xf0000 - 6); - printk(KERN_DEBUG "SABI header:\n"); - printk(KERN_DEBUG " SMI Port Number = 0x%04x\n", - readw(sabi + sabi_config->header_offsets.port)); - printk(KERN_DEBUG " SMI Interface Function = 0x%02x\n", - readb(sabi + sabi_config->header_offsets.iface_func)); - printk(KERN_DEBUG " SMI enable memory buffer = 0x%02x\n", - readb(sabi + sabi_config->header_offsets.en_mem)); - printk(KERN_DEBUG " SMI restore memory buffer = 0x%02x\n", - readb(sabi + sabi_config->header_offsets.re_mem)); - printk(KERN_DEBUG " SABI data offset = 0x%04x\n", - readw(sabi + sabi_config->header_offsets.data_offset)); - printk(KERN_DEBUG " SABI data segment = 0x%04x\n", - readw(sabi + sabi_config->header_offsets.data_segment)); - } - - /* Get a pointer to the SABI Interface */ - ifaceP = (readw(sabi + sabi_config->header_offsets.data_segment) & 0x0ffff) << 4; - ifaceP += readw(sabi + sabi_config->header_offsets.data_offset) & 0x0ffff; - sabi_iface = ioremap_nocache(ifaceP, 16); - if (!sabi_iface) { - pr_err("Can't remap %x\n", ifaceP); - goto exit; - } - if (debug) { - printk(KERN_DEBUG "ifaceP = 0x%08x\n", ifaceP); - printk(KERN_DEBUG "sabi_iface = %p\n", sabi_iface); - - test_backlight(); - test_wireless(); - - retval = sabi_get_command(sabi_config->commands.get_brightness, - &sretval); - printk(KERN_DEBUG "brightness = 0x%02x\n", sretval.retval[0]); - } - - /* Turn on "Linux" mode in the BIOS */ - if (sabi_config->commands.set_linux != 0xff) { - retval = sabi_set_command(sabi_config->commands.set_linux, - 0x81); - if (retval) { - pr_warn("Linux mode was not set!\n"); - goto error_no_platform; - } - } - - /* knock up a platform device to hang stuff off of */ - sdev = platform_device_register_simple("samsung", -1, NULL, 0); - if (IS_ERR(sdev)) - goto error_no_platform; - - /* create a backlight device to talk to this one */ - memset(&props, 0, sizeof(struct backlight_properties)); - props.max_brightness = sabi_config->max_brightness; - backlight_device = backlight_device_register("samsung", &sdev->dev, - NULL, &backlight_ops, - &props); - if (IS_ERR(backlight_device)) - goto error_no_backlight; - - backlight_device->props.brightness = read_brightness(); - backlight_device->props.power = FB_BLANK_UNBLANK; - backlight_update_status(backlight_device); - - retval = init_wireless(sdev); - if (retval) - goto error_no_rfk; - - retval = device_create_file(&sdev->dev, &dev_attr_performance_level); - if (retval) - goto error_file_create; - -exit: - return 0; - -error_file_create: - destroy_wireless(); - -error_no_rfk: - backlight_device_unregister(backlight_device); - -error_no_backlight: - platform_device_unregister(sdev); - -error_no_platform: - iounmap(sabi_iface); - -error_no_signature: - iounmap(f0000_segment); - return -EINVAL; -} - -static void __exit samsung_exit(void) -{ - /* Turn off "Linux" mode in the BIOS */ - if (sabi_config->commands.set_linux != 0xff) - sabi_set_command(sabi_config->commands.set_linux, 0x80); - - device_remove_file(&sdev->dev, &dev_attr_performance_level); - backlight_device_unregister(backlight_device); - destroy_wireless(); - iounmap(sabi_iface); - iounmap(f0000_segment); - platform_device_unregister(sdev); -} - -module_init(samsung_init); -module_exit(samsung_exit); - -MODULE_AUTHOR("Greg Kroah-Hartman "); -MODULE_DESCRIPTION("Samsung Backlight driver"); -MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/platform/x86/sony-laptop.c b/trunk/drivers/platform/x86/sony-laptop.c index e642f5f29504..13d8d63bcca9 100644 --- a/trunk/drivers/platform/x86/sony-laptop.c +++ b/trunk/drivers/platform/x86/sony-laptop.c @@ -71,9 +71,8 @@ #endif #define DRV_PFX "sony-laptop: " -#define dprintk(msg...) do { \ - if (debug) \ - pr_warn(DRV_PFX msg); \ +#define dprintk(msg...) do { \ + if (debug) printk(KERN_WARNING DRV_PFX msg); \ } while (0) #define SONY_LAPTOP_DRIVER_VERSION "0.6" @@ -125,19 +124,6 @@ MODULE_PARM_DESC(minor, "default is -1 (automatic)"); #endif -static int kbd_backlight; /* = 1 */ -module_param(kbd_backlight, int, 0444); -MODULE_PARM_DESC(kbd_backlight, - "set this to 0 to disable keyboard backlight, " - "1 to enable it (default: 0)"); - -static int kbd_backlight_timeout; /* = 0 */ -module_param(kbd_backlight_timeout, int, 0444); -MODULE_PARM_DESC(kbd_backlight_timeout, - "set this to 0 to set the default 10 seconds timeout, " - "1 for 30 seconds, 2 for 60 seconds and 3 to disable timeout " - "(default: 0)"); - enum sony_nc_rfkill { SONY_WIFI, SONY_BLUETOOTH, @@ -416,7 +402,7 @@ static int sony_laptop_setup_input(struct acpi_device *acpi_device) error = kfifo_alloc(&sony_laptop_input.fifo, SONY_LAPTOP_BUF_SIZE, GFP_KERNEL); if (error) { - pr_err(DRV_PFX "kfifo_alloc failed\n"); + printk(KERN_ERR DRV_PFX "kfifo_alloc failed\n"); goto err_dec_users; } @@ -605,7 +591,7 @@ struct sony_nc_value { int value; /* current setting */ int valid; /* Has ever been set */ int debug; /* active only in debug mode ? */ - struct device_attribute devattr; /* sysfs attribute */ + struct device_attribute devattr; /* sysfs atribute */ }; #define SNC_HANDLE_NAMES(_name, _values...) \ @@ -700,7 +686,7 @@ static int acpi_callgetfunc(acpi_handle handle, char *name, int *result) return 0; } - pr_warn(DRV_PFX "acpi_callreadfunc failed\n"); + printk(KERN_WARNING DRV_PFX "acpi_callreadfunc failed\n"); return -1; } @@ -726,7 +712,7 @@ static int acpi_callsetfunc(acpi_handle handle, char *name, int value, if (status == AE_OK) { if (result != NULL) { if (out_obj.type != ACPI_TYPE_INTEGER) { - pr_warn(DRV_PFX "acpi_evaluate_object bad " + printk(KERN_WARNING DRV_PFX "acpi_evaluate_object bad " "return type\n"); return -1; } @@ -735,103 +721,34 @@ static int acpi_callsetfunc(acpi_handle handle, char *name, int value, return 0; } - pr_warn(DRV_PFX "acpi_evaluate_object failed\n"); + printk(KERN_WARNING DRV_PFX "acpi_evaluate_object failed\n"); return -1; } -struct sony_nc_handles { - u16 cap[0x10]; - struct device_attribute devattr; -}; - -static struct sony_nc_handles *handles; - -static ssize_t sony_nc_handles_show(struct device *dev, - struct device_attribute *attr, char *buffer) -{ - ssize_t len = 0; - int i; - - for (i = 0; i < ARRAY_SIZE(handles->cap); i++) { - len += snprintf(buffer + len, PAGE_SIZE - len, "0x%.4x ", - handles->cap[i]); - } - len += snprintf(buffer + len, PAGE_SIZE - len, "\n"); - - return len; -} - -static int sony_nc_handles_setup(struct platform_device *pd) +static int sony_find_snc_handle(int handle) { int i; int result; - handles = kzalloc(sizeof(*handles), GFP_KERNEL); - if (!handles) - return -ENOMEM; - - sysfs_attr_init(&handles->devattr.attr); - handles->devattr.attr.name = "handles"; - handles->devattr.attr.mode = S_IRUGO; - handles->devattr.show = sony_nc_handles_show; - - for (i = 0; i < ARRAY_SIZE(handles->cap); i++) { - if (!acpi_callsetfunc(sony_nc_acpi_handle, - "SN00", i + 0x20, &result)) { - dprintk("caching handle 0x%.4x (offset: 0x%.2x)\n", - result, i); - handles->cap[i] = result; - } - } - - /* allow reading capabilities via sysfs */ - if (device_create_file(&pd->dev, &handles->devattr)) { - kfree(handles); - handles = NULL; - return -1; - } - - return 0; -} - -static int sony_nc_handles_cleanup(struct platform_device *pd) -{ - if (handles) { - device_remove_file(&pd->dev, &handles->devattr); - kfree(handles); - handles = NULL; + for (i = 0x20; i < 0x30; i++) { + acpi_callsetfunc(sony_nc_acpi_handle, "SN00", i, &result); + if (result == handle) + return i-0x20; } - return 0; -} -static int sony_find_snc_handle(int handle) -{ - int i; - for (i = 0; i < 0x10; i++) { - if (handles->cap[i] == handle) { - dprintk("found handle 0x%.4x (offset: 0x%.2x)\n", - handle, i); - return i; - } - } - dprintk("handle 0x%.4x not found\n", handle); return -1; } static int sony_call_snc_handle(int handle, int argument, int *result) { - int ret = 0; int offset = sony_find_snc_handle(handle); if (offset < 0) return -1; - ret = acpi_callsetfunc(sony_nc_acpi_handle, "SN07", offset | argument, - result); - dprintk("called SN07 with 0x%.4x (result: 0x%.4x)\n", offset | argument, - *result); - return ret; + return acpi_callsetfunc(sony_nc_acpi_handle, "SN07", offset | argument, + result); } /* @@ -940,39 +857,11 @@ static int sony_backlight_get_brightness(struct backlight_device *bd) return value - 1; } -static int sony_nc_get_brightness_ng(struct backlight_device *bd) -{ - int result; - int *handle = (int *)bl_get_data(bd); - - sony_call_snc_handle(*handle, 0x0200, &result); - - return result & 0xff; -} - -static int sony_nc_update_status_ng(struct backlight_device *bd) -{ - int value, result; - int *handle = (int *)bl_get_data(bd); - - value = bd->props.brightness; - sony_call_snc_handle(*handle, 0x0100 | (value << 16), &result); - - return sony_nc_get_brightness_ng(bd); -} - +static struct backlight_device *sony_backlight_device; static const struct backlight_ops sony_backlight_ops = { - .options = BL_CORE_SUSPENDRESUME, .update_status = sony_backlight_update_status, .get_brightness = sony_backlight_get_brightness, }; -static const struct backlight_ops sony_backlight_ng_ops = { - .options = BL_CORE_SUSPENDRESUME, - .update_status = sony_nc_update_status_ng, - .get_brightness = sony_nc_get_brightness_ng, -}; -static int backlight_ng_handle; -static struct backlight_device *sony_backlight_device; /* * New SNC-only Vaios event mapping to driver known keys @@ -1083,7 +972,7 @@ static void sony_nc_notify(struct acpi_device *device, u32 event) } if (!key_event->data) - pr_info(DRV_PFX + printk(KERN_INFO DRV_PFX "Unknown event: 0x%x 0x%x\n", key_handle, ev); @@ -1107,7 +996,7 @@ static acpi_status sony_walk_callback(acpi_handle handle, u32 level, struct acpi_device_info *info; if (ACPI_SUCCESS(acpi_get_object_info(handle, &info))) { - pr_warn(DRV_PFX "method: name: %4.4s, args %X\n", + printk(KERN_WARNING DRV_PFX "method: name: %4.4s, args %X\n", (char *)&info->name, info->param_count); kfree(info); @@ -1148,7 +1037,7 @@ static int sony_nc_resume(struct acpi_device *device) ret = acpi_callsetfunc(sony_nc_acpi_handle, *item->acpiset, item->value, NULL); if (ret < 0) { - pr_err(DRV_PFX "%s: %d\n", __func__, ret); + printk("%s: %d\n", __func__, ret); break; } } @@ -1165,6 +1054,11 @@ static int sony_nc_resume(struct acpi_device *device) sony_nc_function_setup(device); } + /* set the last requested brightness level */ + if (sony_backlight_device && + sony_backlight_update_status(sony_backlight_device) < 0) + printk(KERN_WARNING DRV_PFX "unable to restore brightness level\n"); + /* re-read rfkill state */ sony_nc_rfkill_update(); @@ -1312,12 +1206,12 @@ static void sony_nc_rfkill_setup(struct acpi_device *device) device_enum = (union acpi_object *) buffer.pointer; if (!device_enum) { - pr_err(DRV_PFX "No SN06 return object."); + pr_err("Invalid SN06 return object\n"); goto out_no_enum; } if (device_enum->type != ACPI_TYPE_BUFFER) { - pr_err(DRV_PFX "Invalid SN06 return object 0x%.2x\n", - device_enum->type); + pr_err("Invalid SN06 return object type 0x%.2x\n", + device_enum->type); goto out_no_enum; } @@ -1351,209 +1245,6 @@ static void sony_nc_rfkill_setup(struct acpi_device *device) return; } -/* Keyboard backlight feature */ -#define KBDBL_HANDLER 0x137 -#define KBDBL_PRESENT 0xB00 -#define SET_MODE 0xC00 -#define SET_TIMEOUT 0xE00 - -struct kbd_backlight { - int mode; - int timeout; - struct device_attribute mode_attr; - struct device_attribute timeout_attr; -}; - -static struct kbd_backlight *kbdbl_handle; - -static ssize_t __sony_nc_kbd_backlight_mode_set(u8 value) -{ - int result; - - if (value > 1) - return -EINVAL; - - if (sony_call_snc_handle(KBDBL_HANDLER, - (value << 0x10) | SET_MODE, &result)) - return -EIO; - - kbdbl_handle->mode = value; - - return 0; -} - -static ssize_t sony_nc_kbd_backlight_mode_store(struct device *dev, - struct device_attribute *attr, - const char *buffer, size_t count) -{ - int ret = 0; - unsigned long value; - - if (count > 31) - return -EINVAL; - - if (strict_strtoul(buffer, 10, &value)) - return -EINVAL; - - ret = __sony_nc_kbd_backlight_mode_set(value); - if (ret < 0) - return ret; - - return count; -} - -static ssize_t sony_nc_kbd_backlight_mode_show(struct device *dev, - struct device_attribute *attr, char *buffer) -{ - ssize_t count = 0; - count = snprintf(buffer, PAGE_SIZE, "%d\n", kbdbl_handle->mode); - return count; -} - -static int __sony_nc_kbd_backlight_timeout_set(u8 value) -{ - int result; - - if (value > 3) - return -EINVAL; - - if (sony_call_snc_handle(KBDBL_HANDLER, - (value << 0x10) | SET_TIMEOUT, &result)) - return -EIO; - - kbdbl_handle->timeout = value; - - return 0; -} - -static ssize_t sony_nc_kbd_backlight_timeout_store(struct device *dev, - struct device_attribute *attr, - const char *buffer, size_t count) -{ - int ret = 0; - unsigned long value; - - if (count > 31) - return -EINVAL; - - if (strict_strtoul(buffer, 10, &value)) - return -EINVAL; - - ret = __sony_nc_kbd_backlight_timeout_set(value); - if (ret < 0) - return ret; - - return count; -} - -static ssize_t sony_nc_kbd_backlight_timeout_show(struct device *dev, - struct device_attribute *attr, char *buffer) -{ - ssize_t count = 0; - count = snprintf(buffer, PAGE_SIZE, "%d\n", kbdbl_handle->timeout); - return count; -} - -static int sony_nc_kbd_backlight_setup(struct platform_device *pd) -{ - int result; - - if (sony_call_snc_handle(0x137, KBDBL_PRESENT, &result)) - return 0; - if (!(result & 0x02)) - return 0; - - kbdbl_handle = kzalloc(sizeof(*kbdbl_handle), GFP_KERNEL); - if (!kbdbl_handle) - return -ENOMEM; - - sysfs_attr_init(&kbdbl_handle->mode_attr.attr); - kbdbl_handle->mode_attr.attr.name = "kbd_backlight"; - kbdbl_handle->mode_attr.attr.mode = S_IRUGO | S_IWUSR; - kbdbl_handle->mode_attr.show = sony_nc_kbd_backlight_mode_show; - kbdbl_handle->mode_attr.store = sony_nc_kbd_backlight_mode_store; - - sysfs_attr_init(&kbdbl_handle->timeout_attr.attr); - kbdbl_handle->timeout_attr.attr.name = "kbd_backlight_timeout"; - kbdbl_handle->timeout_attr.attr.mode = S_IRUGO | S_IWUSR; - kbdbl_handle->timeout_attr.show = sony_nc_kbd_backlight_timeout_show; - kbdbl_handle->timeout_attr.store = sony_nc_kbd_backlight_timeout_store; - - if (device_create_file(&pd->dev, &kbdbl_handle->mode_attr)) - goto outkzalloc; - - if (device_create_file(&pd->dev, &kbdbl_handle->timeout_attr)) - goto outmode; - - __sony_nc_kbd_backlight_mode_set(kbd_backlight); - __sony_nc_kbd_backlight_timeout_set(kbd_backlight_timeout); - - return 0; - -outmode: - device_remove_file(&pd->dev, &kbdbl_handle->mode_attr); -outkzalloc: - kfree(kbdbl_handle); - kbdbl_handle = NULL; - return -1; -} - -static int sony_nc_kbd_backlight_cleanup(struct platform_device *pd) -{ - if (kbdbl_handle) { - device_remove_file(&pd->dev, &kbdbl_handle->mode_attr); - device_remove_file(&pd->dev, &kbdbl_handle->timeout_attr); - kfree(kbdbl_handle); - } - return 0; -} - -static void sony_nc_backlight_setup(void) -{ - acpi_handle unused; - int max_brightness = 0; - const struct backlight_ops *ops = NULL; - struct backlight_properties props; - - if (sony_find_snc_handle(0x12f) != -1) { - backlight_ng_handle = 0x12f; - ops = &sony_backlight_ng_ops; - max_brightness = 0xff; - - } else if (sony_find_snc_handle(0x137) != -1) { - backlight_ng_handle = 0x137; - ops = &sony_backlight_ng_ops; - max_brightness = 0xff; - - } else if (ACPI_SUCCESS(acpi_get_handle(sony_nc_acpi_handle, "GBRT", - &unused))) { - ops = &sony_backlight_ops; - max_brightness = SONY_MAX_BRIGHTNESS - 1; - - } else - return; - - memset(&props, 0, sizeof(struct backlight_properties)); - props.type = BACKLIGHT_PLATFORM; - props.max_brightness = max_brightness; - sony_backlight_device = backlight_device_register("sony", NULL, - &backlight_ng_handle, - ops, &props); - - if (IS_ERR(sony_backlight_device)) { - pr_warning(DRV_PFX "unable to register backlight device\n"); - sony_backlight_device = NULL; - } else - sony_backlight_device->props.brightness = - ops->get_brightness(sony_backlight_device); -} - -static void sony_nc_backlight_cleanup(void) -{ - if (sony_backlight_device) - backlight_device_unregister(sony_backlight_device); -} - static int sony_nc_add(struct acpi_device *device) { acpi_status status; @@ -1561,8 +1252,8 @@ static int sony_nc_add(struct acpi_device *device) acpi_handle handle; struct sony_nc_value *item; - pr_info(DRV_PFX "%s v%s.\n", SONY_NC_DRIVER_NAME, - SONY_LAPTOP_DRIVER_VERSION); + printk(KERN_INFO DRV_PFX "%s v%s.\n", + SONY_NC_DRIVER_NAME, SONY_LAPTOP_DRIVER_VERSION); sony_nc_acpi_device = device; strcpy(acpi_device_class(device), "sony/hotkey"); @@ -1578,18 +1269,13 @@ static int sony_nc_add(struct acpi_device *device) goto outwalk; } - result = sony_pf_add(); - if (result) - goto outpresent; - if (debug) { - status = acpi_walk_namespace(ACPI_TYPE_METHOD, - sony_nc_acpi_handle, 1, sony_walk_callback, - NULL, NULL, NULL); + status = acpi_walk_namespace(ACPI_TYPE_METHOD, sony_nc_acpi_handle, + 1, sony_walk_callback, NULL, NULL, NULL); if (ACPI_FAILURE(status)) { - pr_warn(DRV_PFX "unable to walk acpi resources\n"); + printk(KERN_WARNING DRV_PFX "unable to walk acpi resources\n"); result = -ENODEV; - goto outpresent; + goto outwalk; } } @@ -1602,12 +1288,6 @@ static int sony_nc_add(struct acpi_device *device) if (ACPI_SUCCESS(acpi_get_handle(sony_nc_acpi_handle, "SN00", &handle))) { dprintk("Doing SNC setup\n"); - result = sony_nc_handles_setup(sony_pf_device); - if (result) - goto outpresent; - result = sony_nc_kbd_backlight_setup(sony_pf_device); - if (result) - goto outsnc; sony_nc_function_setup(device); sony_nc_rfkill_setup(device); } @@ -1615,17 +1295,40 @@ static int sony_nc_add(struct acpi_device *device) /* setup input devices and helper fifo */ result = sony_laptop_setup_input(device); if (result) { - pr_err(DRV_PFX "Unable to create input devices.\n"); - goto outkbdbacklight; + printk(KERN_ERR DRV_PFX + "Unable to create input devices.\n"); + goto outwalk; } if (acpi_video_backlight_support()) { - pr_info(DRV_PFX "brightness ignored, must be " + printk(KERN_INFO DRV_PFX "brightness ignored, must be " "controlled by ACPI video driver\n"); - } else { - sony_nc_backlight_setup(); + } else if (ACPI_SUCCESS(acpi_get_handle(sony_nc_acpi_handle, "GBRT", + &handle))) { + struct backlight_properties props; + memset(&props, 0, sizeof(struct backlight_properties)); + props.type = BACKLIGHT_PLATFORM; + props.max_brightness = SONY_MAX_BRIGHTNESS - 1; + sony_backlight_device = backlight_device_register("sony", NULL, + NULL, + &sony_backlight_ops, + &props); + + if (IS_ERR(sony_backlight_device)) { + printk(KERN_WARNING DRV_PFX "unable to register backlight device\n"); + sony_backlight_device = NULL; + } else { + sony_backlight_device->props.brightness = + sony_backlight_get_brightness + (sony_backlight_device); + } + } + result = sony_pf_add(); + if (result) + goto outbacklight; + /* create sony_pf sysfs attributes related to the SNC device */ for (item = sony_nc_values; item->name; ++item) { @@ -1671,18 +1374,13 @@ static int sony_nc_add(struct acpi_device *device) for (item = sony_nc_values; item->name; ++item) { device_remove_file(&sony_pf_device->dev, &item->devattr); } - sony_nc_backlight_cleanup(); - - sony_laptop_remove_input(); - - outkbdbacklight: - sony_nc_kbd_backlight_cleanup(sony_pf_device); + sony_pf_remove(); - outsnc: - sony_nc_handles_cleanup(sony_pf_device); + outbacklight: + if (sony_backlight_device) + backlight_device_unregister(sony_backlight_device); - outpresent: - sony_pf_remove(); + sony_laptop_remove_input(); outwalk: sony_nc_rfkill_cleanup(); @@ -1693,7 +1391,8 @@ static int sony_nc_remove(struct acpi_device *device, int type) { struct sony_nc_value *item; - sony_nc_backlight_cleanup(); + if (sony_backlight_device) + backlight_device_unregister(sony_backlight_device); sony_nc_acpi_device = NULL; @@ -1701,8 +1400,6 @@ static int sony_nc_remove(struct acpi_device *device, int type) device_remove_file(&sony_pf_device->dev, &item->devattr); } - sony_nc_kbd_backlight_cleanup(sony_pf_device); - sony_nc_handles_cleanup(sony_pf_device); sony_pf_remove(); sony_laptop_remove_input(); sony_nc_rfkill_cleanup(); @@ -1741,6 +1438,7 @@ static struct acpi_driver sony_nc_driver = { #define SONYPI_DEVICE_TYPE1 0x00000001 #define SONYPI_DEVICE_TYPE2 0x00000002 #define SONYPI_DEVICE_TYPE3 0x00000004 +#define SONYPI_DEVICE_TYPE4 0x00000008 #define SONYPI_TYPE1_OFFSET 0x04 #define SONYPI_TYPE2_OFFSET 0x12 @@ -1886,8 +1584,8 @@ static struct sonypi_event sonypi_blueev[] = { /* The set of possible wireless events */ static struct sonypi_event sonypi_wlessev[] = { - { 0x59, SONYPI_EVENT_IGNORE }, - { 0x5a, SONYPI_EVENT_IGNORE }, + { 0x59, SONYPI_EVENT_WIRELESS_ON }, + { 0x5a, SONYPI_EVENT_WIRELESS_OFF }, { 0, 0 } }; @@ -2144,7 +1842,7 @@ static void sony_pic_detect_device_type(struct sony_pic_dev *dev) if (pcidev) pci_dev_put(pcidev); - pr_info(DRV_PFX "detected Type%d model\n", + printk(KERN_INFO DRV_PFX "detected Type%d model\n", dev->model == SONYPI_DEVICE_TYPE1 ? 1 : dev->model == SONYPI_DEVICE_TYPE2 ? 2 : 3); } @@ -2192,7 +1890,7 @@ static int __sony_pic_camera_ready(void) static int __sony_pic_camera_off(void) { if (!camera) { - pr_warn(DRV_PFX "camera control not enabled\n"); + printk(KERN_WARNING DRV_PFX "camera control not enabled\n"); return -ENODEV; } @@ -2212,7 +1910,7 @@ static int __sony_pic_camera_on(void) int i, j, x; if (!camera) { - pr_warn(DRV_PFX "camera control not enabled\n"); + printk(KERN_WARNING DRV_PFX "camera control not enabled\n"); return -ENODEV; } @@ -2235,7 +1933,7 @@ static int __sony_pic_camera_on(void) } if (j == 0) { - pr_warn(DRV_PFX "failed to power on camera\n"); + printk(KERN_WARNING DRV_PFX "failed to power on camera\n"); return -ENODEV; } @@ -2291,7 +1989,7 @@ int sony_pic_camera_command(int command, u8 value) ITERATIONS_SHORT); break; default: - pr_err(DRV_PFX "sony_pic_camera_command invalid: %d\n", + printk(KERN_ERR DRV_PFX "sony_pic_camera_command invalid: %d\n", command); break; } @@ -2698,7 +2396,7 @@ static int sonypi_compat_init(void) error = kfifo_alloc(&sonypi_compat.fifo, SONY_LAPTOP_BUF_SIZE, GFP_KERNEL); if (error) { - pr_err(DRV_PFX "kfifo_alloc failed\n"); + printk(KERN_ERR DRV_PFX "kfifo_alloc failed\n"); return error; } @@ -2708,11 +2406,11 @@ static int sonypi_compat_init(void) sonypi_misc_device.minor = minor; error = misc_register(&sonypi_misc_device); if (error) { - pr_err(DRV_PFX "misc_register failed\n"); + printk(KERN_ERR DRV_PFX "misc_register failed\n"); goto err_free_kfifo; } if (minor == -1) - pr_info(DRV_PFX "device allocated minor is %d\n", + printk(KERN_INFO DRV_PFX "device allocated minor is %d\n", sonypi_misc_device.minor); return 0; @@ -2772,7 +2470,8 @@ sony_pic_read_possible_resource(struct acpi_resource *resource, void *context) } for (i = 0; i < p->interrupt_count; i++) { if (!p->interrupts[i]) { - pr_warn(DRV_PFX "Invalid IRQ %d\n", + printk(KERN_WARNING DRV_PFX + "Invalid IRQ %d\n", p->interrupts[i]); continue; } @@ -2811,7 +2510,7 @@ sony_pic_read_possible_resource(struct acpi_resource *resource, void *context) ioport->io2.address_length); } else { - pr_err(DRV_PFX "Unknown SPIC Type, more than 2 IO Ports\n"); + printk(KERN_ERR DRV_PFX "Unknown SPIC Type, more than 2 IO Ports\n"); return AE_ERROR; } return AE_OK; @@ -2839,7 +2538,7 @@ static int sony_pic_possible_resources(struct acpi_device *device) dprintk("Evaluating _STA\n"); result = acpi_bus_get_status(device); if (result) { - pr_warn(DRV_PFX "Unable to read status\n"); + printk(KERN_WARNING DRV_PFX "Unable to read status\n"); goto end; } @@ -2855,7 +2554,8 @@ static int sony_pic_possible_resources(struct acpi_device *device) status = acpi_walk_resources(device->handle, METHOD_NAME__PRS, sony_pic_read_possible_resource, &spic_dev); if (ACPI_FAILURE(status)) { - pr_warn(DRV_PFX "Failure evaluating %s\n", + printk(KERN_WARNING DRV_PFX + "Failure evaluating %s\n", METHOD_NAME__PRS); result = -ENODEV; } @@ -2969,7 +2669,7 @@ static int sony_pic_enable(struct acpi_device *device, /* check for total failure */ if (ACPI_FAILURE(status)) { - pr_err(DRV_PFX "Error evaluating _SRS\n"); + printk(KERN_ERR DRV_PFX "Error evaluating _SRS\n"); result = -ENODEV; goto end; } @@ -3025,9 +2725,6 @@ static irqreturn_t sony_pic_irq(int irq, void *dev_id) if (ev == dev->event_types[i].events[j].data) { device_event = dev->event_types[i].events[j].event; - /* some events may require ignoring */ - if (!device_event) - return IRQ_HANDLED; goto found; } } @@ -3047,6 +2744,7 @@ static irqreturn_t sony_pic_irq(int irq, void *dev_id) sony_laptop_report_input_event(device_event); acpi_bus_generate_proc_event(dev->acpi_dev, 1, device_event); sonypi_compat_report_event(device_event); + return IRQ_HANDLED; } @@ -3061,7 +2759,7 @@ static int sony_pic_remove(struct acpi_device *device, int type) struct sony_pic_irq *irq, *tmp_irq; if (sony_pic_disable(device)) { - pr_err(DRV_PFX "Couldn't disable device.\n"); + printk(KERN_ERR DRV_PFX "Couldn't disable device.\n"); return -ENXIO; } @@ -3101,8 +2799,8 @@ static int sony_pic_add(struct acpi_device *device) struct sony_pic_ioport *io, *tmp_io; struct sony_pic_irq *irq, *tmp_irq; - pr_info(DRV_PFX "%s v%s.\n", SONY_PIC_DRIVER_NAME, - SONY_LAPTOP_DRIVER_VERSION); + printk(KERN_INFO DRV_PFX "%s v%s.\n", + SONY_PIC_DRIVER_NAME, SONY_LAPTOP_DRIVER_VERSION); spic_dev.acpi_dev = device; strcpy(acpi_device_class(device), "sony/hotkey"); @@ -3112,14 +2810,16 @@ static int sony_pic_add(struct acpi_device *device) /* read _PRS resources */ result = sony_pic_possible_resources(device); if (result) { - pr_err(DRV_PFX "Unable to read possible resources.\n"); + printk(KERN_ERR DRV_PFX + "Unable to read possible resources.\n"); goto err_free_resources; } /* setup input devices and helper fifo */ result = sony_laptop_setup_input(device); if (result) { - pr_err(DRV_PFX "Unable to create input devices.\n"); + printk(KERN_ERR DRV_PFX + "Unable to create input devices.\n"); goto err_free_resources; } @@ -3129,7 +2829,7 @@ static int sony_pic_add(struct acpi_device *device) /* request io port */ list_for_each_entry_reverse(io, &spic_dev.ioports, list) { if (request_region(io->io1.minimum, io->io1.address_length, - "Sony Programmable I/O Device")) { + "Sony Programable I/O Device")) { dprintk("I/O port1: 0x%.4x (0x%.4x) + 0x%.2x\n", io->io1.minimum, io->io1.maximum, io->io1.address_length); @@ -3137,7 +2837,7 @@ static int sony_pic_add(struct acpi_device *device) if (io->io2.minimum) { if (request_region(io->io2.minimum, io->io2.address_length, - "Sony Programmable I/O Device")) { + "Sony Programable I/O Device")) { dprintk("I/O port2: 0x%.4x (0x%.4x) + 0x%.2x\n", io->io2.minimum, io->io2.maximum, io->io2.address_length); @@ -3160,7 +2860,7 @@ static int sony_pic_add(struct acpi_device *device) } } if (!spic_dev.cur_ioport) { - pr_err(DRV_PFX "Failed to request_region.\n"); + printk(KERN_ERR DRV_PFX "Failed to request_region.\n"); result = -ENODEV; goto err_remove_compat; } @@ -3180,7 +2880,7 @@ static int sony_pic_add(struct acpi_device *device) } } if (!spic_dev.cur_irq) { - pr_err(DRV_PFX "Failed to request_irq.\n"); + printk(KERN_ERR DRV_PFX "Failed to request_irq.\n"); result = -ENODEV; goto err_release_region; } @@ -3188,7 +2888,7 @@ static int sony_pic_add(struct acpi_device *device) /* set resource status _SRS */ result = sony_pic_enable(device, spic_dev.cur_ioport, spic_dev.cur_irq); if (result) { - pr_err(DRV_PFX "Couldn't enable device.\n"); + printk(KERN_ERR DRV_PFX "Couldn't enable device.\n"); goto err_free_irq; } @@ -3297,7 +2997,8 @@ static int __init sony_laptop_init(void) if (!no_spic && dmi_check_system(sonypi_dmi_table)) { result = acpi_bus_register_driver(&sony_pic_driver); if (result) { - pr_err(DRV_PFX "Unable to register SPIC driver."); + printk(KERN_ERR DRV_PFX + "Unable to register SPIC driver."); goto out; } spic_drv_registered = 1; @@ -3305,7 +3006,7 @@ static int __init sony_laptop_init(void) result = acpi_bus_register_driver(&sony_nc_driver); if (result) { - pr_err(DRV_PFX "Unable to register SNC driver."); + printk(KERN_ERR DRV_PFX "Unable to register SNC driver."); goto out_unregister_pic; } diff --git a/trunk/drivers/platform/x86/thinkpad_acpi.c b/trunk/drivers/platform/x86/thinkpad_acpi.c index a08561f5349e..947bdcaa0ce9 100644 --- a/trunk/drivers/platform/x86/thinkpad_acpi.c +++ b/trunk/drivers/platform/x86/thinkpad_acpi.c @@ -2407,7 +2407,7 @@ static void hotkey_compare_and_issue_event(struct tp_nvram_state *oldn, * This code is supposed to duplicate the IBM firmware behaviour: * - Pressing MUTE issues mute hotkey message, even when already mute * - Pressing Volume up/down issues volume up/down hotkey messages, - * even when already at maximum or minimum volume + * even when already at maximum or minumum volume * - The act of unmuting issues volume up/down notification, * depending which key was used to unmute * @@ -2990,7 +2990,7 @@ static void tpacpi_send_radiosw_update(void) * rfkill input events, or we will race the rfkill core input * handler. * - * tpacpi_inputdev_send_mutex works as a synchronization point + * tpacpi_inputdev_send_mutex works as a syncronization point * for the above. * * We optimize to avoid numerous calls to hotkey_get_wlsw. diff --git a/trunk/drivers/platform/x86/xo15-ebook.c b/trunk/drivers/platform/x86/xo15-ebook.c deleted file mode 100644 index c1372ed9d2e9..000000000000 --- a/trunk/drivers/platform/x86/xo15-ebook.c +++ /dev/null @@ -1,180 +0,0 @@ -/* - * OLPC XO-1.5 ebook switch driver - * (based on generic ACPI button driver) - * - * Copyright (C) 2009 Paul Fox - * Copyright (C) 2010 One Laptop per Child - * - * 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 -#include -#include - -#define MODULE_NAME "xo15-ebook" -#define PREFIX MODULE_NAME ": " - -#define XO15_EBOOK_CLASS MODULE_NAME -#define XO15_EBOOK_TYPE_UNKNOWN 0x00 -#define XO15_EBOOK_NOTIFY_STATUS 0x80 - -#define XO15_EBOOK_SUBCLASS "ebook" -#define XO15_EBOOK_HID "XO15EBK" -#define XO15_EBOOK_DEVICE_NAME "EBook Switch" - -ACPI_MODULE_NAME(MODULE_NAME); - -MODULE_DESCRIPTION("OLPC XO-1.5 ebook switch driver"); -MODULE_LICENSE("GPL"); - -static const struct acpi_device_id ebook_device_ids[] = { - { XO15_EBOOK_HID, 0 }, - { "", 0 }, -}; -MODULE_DEVICE_TABLE(acpi, ebook_device_ids); - -struct ebook_switch { - struct input_dev *input; - char phys[32]; /* for input device */ -}; - -static int ebook_send_state(struct acpi_device *device) -{ - struct ebook_switch *button = acpi_driver_data(device); - unsigned long long state; - acpi_status status; - - status = acpi_evaluate_integer(device->handle, "EBK", NULL, &state); - if (ACPI_FAILURE(status)) - return -EIO; - - /* input layer checks if event is redundant */ - input_report_switch(button->input, SW_TABLET_MODE, !state); - input_sync(button->input); - return 0; -} - -static void ebook_switch_notify(struct acpi_device *device, u32 event) -{ - switch (event) { - case ACPI_FIXED_HARDWARE_EVENT: - case XO15_EBOOK_NOTIFY_STATUS: - ebook_send_state(device); - break; - default: - ACPI_DEBUG_PRINT((ACPI_DB_INFO, - "Unsupported event [0x%x]\n", event)); - break; - } -} - -static int ebook_switch_resume(struct acpi_device *device) -{ - return ebook_send_state(device); -} - -static int ebook_switch_add(struct acpi_device *device) -{ - struct ebook_switch *button; - struct input_dev *input; - const char *hid = acpi_device_hid(device); - char *name, *class; - int error; - - button = kzalloc(sizeof(struct ebook_switch), GFP_KERNEL); - if (!button) - return -ENOMEM; - - device->driver_data = button; - - button->input = input = input_allocate_device(); - if (!input) { - error = -ENOMEM; - goto err_free_button; - } - - name = acpi_device_name(device); - class = acpi_device_class(device); - - if (strcmp(hid, XO15_EBOOK_HID)) { - printk(KERN_ERR PREFIX "Unsupported hid [%s]\n", hid); - error = -ENODEV; - goto err_free_input; - } - - strcpy(name, XO15_EBOOK_DEVICE_NAME); - sprintf(class, "%s/%s", XO15_EBOOK_CLASS, XO15_EBOOK_SUBCLASS); - - snprintf(button->phys, sizeof(button->phys), "%s/button/input0", hid); - - input->name = name; - input->phys = button->phys; - input->id.bustype = BUS_HOST; - input->dev.parent = &device->dev; - - input->evbit[0] = BIT_MASK(EV_SW); - set_bit(SW_TABLET_MODE, input->swbit); - - error = input_register_device(input); - if (error) - goto err_free_input; - - ebook_send_state(device); - - if (device->wakeup.flags.valid) { - /* Button's GPE is run-wake GPE */ - acpi_enable_gpe(device->wakeup.gpe_device, - device->wakeup.gpe_number); - device_set_wakeup_enable(&device->dev, true); - } - - return 0; - - err_free_input: - input_free_device(input); - err_free_button: - kfree(button); - return error; -} - -static int ebook_switch_remove(struct acpi_device *device, int type) -{ - struct ebook_switch *button = acpi_driver_data(device); - - input_unregister_device(button->input); - kfree(button); - return 0; -} - -static struct acpi_driver xo15_ebook_driver = { - .name = MODULE_NAME, - .class = XO15_EBOOK_CLASS, - .ids = ebook_device_ids, - .ops = { - .add = ebook_switch_add, - .resume = ebook_switch_resume, - .remove = ebook_switch_remove, - .notify = ebook_switch_notify, - }, -}; - -static int __init xo15_ebook_init(void) -{ - return acpi_bus_register_driver(&xo15_ebook_driver); -} - -static void __exit xo15_ebook_exit(void) -{ - acpi_bus_unregister_driver(&xo15_ebook_driver); -} - -module_init(xo15_ebook_init); -module_exit(xo15_ebook_exit); diff --git a/trunk/drivers/power/z2_battery.c b/trunk/drivers/power/z2_battery.c index e5ced3a4c1ed..2a9ab89f83b8 100644 --- a/trunk/drivers/power/z2_battery.c +++ b/trunk/drivers/power/z2_battery.c @@ -215,8 +215,8 @@ static int __devinit z2_batt_probe(struct i2c_client *client, if (ret) goto err2; - irq_set_irq_type(gpio_to_irq(info->charge_gpio), - IRQ_TYPE_EDGE_BOTH); + set_irq_type(gpio_to_irq(info->charge_gpio), + IRQ_TYPE_EDGE_BOTH); ret = request_irq(gpio_to_irq(info->charge_gpio), z2_charge_switch_irq, IRQF_DISABLED, "AC Detect", charger); diff --git a/trunk/drivers/regulator/Kconfig b/trunk/drivers/regulator/Kconfig index b9f29e0d4295..de75f67f4cc3 100644 --- a/trunk/drivers/regulator/Kconfig +++ b/trunk/drivers/regulator/Kconfig @@ -126,7 +126,7 @@ config REGULATOR_MAX8998 and S5PC1XX chips to control VCC_CORE and VCC_USIM voltages. config REGULATOR_TWL4030 - bool "TI TWL4030/TWL5030/TWL6030/TPS659x0 PMIC" + bool "TI TWL4030/TWL5030/TWL6030/TPS695x0 PMIC" depends on TWL4030_CORE help This driver supports the voltage regulators provided by diff --git a/trunk/drivers/regulator/ab3100.c b/trunk/drivers/regulator/ab3100.c index b1d77946e9c6..2dec589a8908 100644 --- a/trunk/drivers/regulator/ab3100.c +++ b/trunk/drivers/regulator/ab3100.c @@ -206,6 +206,29 @@ static int ab3100_enable_regulator(struct regulator_dev *reg) return err; } + /* Per-regulator power on delay from spec */ + switch (abreg->regreg) { + case AB3100_LDO_A: /* Fallthrough */ + case AB3100_LDO_C: /* Fallthrough */ + case AB3100_LDO_D: /* Fallthrough */ + case AB3100_LDO_E: /* Fallthrough */ + case AB3100_LDO_H: /* Fallthrough */ + case AB3100_LDO_K: + udelay(200); + break; + case AB3100_LDO_F: + udelay(600); + break; + case AB3100_LDO_G: + udelay(400); + break; + case AB3100_BUCK: + mdelay(1); + break; + default: + break; + } + return 0; } @@ -427,37 +450,11 @@ static int ab3100_get_voltage_regulator_external(struct regulator_dev *reg) return abreg->plfdata->external_voltage; } -static int ab3100_enable_time_regulator(struct regulator_dev *reg) -{ - struct ab3100_regulator *abreg = reg->reg_data; - - /* Per-regulator power on delay from spec */ - switch (abreg->regreg) { - case AB3100_LDO_A: /* Fallthrough */ - case AB3100_LDO_C: /* Fallthrough */ - case AB3100_LDO_D: /* Fallthrough */ - case AB3100_LDO_E: /* Fallthrough */ - case AB3100_LDO_H: /* Fallthrough */ - case AB3100_LDO_K: - return 200; - case AB3100_LDO_F: - return 600; - case AB3100_LDO_G: - return 400; - case AB3100_BUCK: - return 1000; - default: - break; - } - return 0; -} - static struct regulator_ops regulator_ops_fixed = { .enable = ab3100_enable_regulator, .disable = ab3100_disable_regulator, .is_enabled = ab3100_is_enabled_regulator, .get_voltage = ab3100_get_voltage_regulator, - .enable_time = ab3100_enable_time_regulator, }; static struct regulator_ops regulator_ops_variable = { @@ -467,7 +464,6 @@ static struct regulator_ops regulator_ops_variable = { .get_voltage = ab3100_get_voltage_regulator, .set_voltage = ab3100_set_voltage_regulator, .list_voltage = ab3100_list_voltage_regulator, - .enable_time = ab3100_enable_time_regulator, }; static struct regulator_ops regulator_ops_variable_sleepable = { @@ -478,7 +474,6 @@ static struct regulator_ops regulator_ops_variable_sleepable = { .set_voltage = ab3100_set_voltage_regulator, .set_suspend_voltage = ab3100_set_suspend_voltage_regulator, .list_voltage = ab3100_list_voltage_regulator, - .enable_time = ab3100_enable_time_regulator, }; /* diff --git a/trunk/drivers/regulator/ab8500.c b/trunk/drivers/regulator/ab8500.c index 02f3c2333c83..d9a052c53aec 100644 --- a/trunk/drivers/regulator/ab8500.c +++ b/trunk/drivers/regulator/ab8500.c @@ -9,7 +9,7 @@ * AB8500 peripheral regulators * * AB8500 supports the following regulators: - * VAUX1/2/3, VINTCORE, VTVOUT, VUSB, VAUDIO, VAMIC1/2, VDMIC, VANA + * VAUX1/2/3, VINTCORE, VTVOUT, VAUDIO, VAMIC1/2, VDMIC, VANA */ #include #include @@ -38,7 +38,6 @@ * @voltage_mask: mask to control regulator voltage * @voltages: supported voltage table * @voltages_len: number of supported voltages for the regulator - * @delay: startup/set voltage delay in us */ struct ab8500_regulator_info { struct device *dev; @@ -56,7 +55,6 @@ struct ab8500_regulator_info { u8 voltage_mask; int const *voltages; int voltages_len; - unsigned int delay; }; /* voltage tables for the vauxn/vintcore supplies */ @@ -292,29 +290,6 @@ static int ab8500_regulator_set_voltage(struct regulator_dev *rdev, return ret; } -static int ab8500_regulator_enable_time(struct regulator_dev *rdev) -{ - struct ab8500_regulator_info *info = rdev_get_drvdata(rdev); - - return info->delay; -} - -static int ab8500_regulator_set_voltage_time_sel(struct regulator_dev *rdev, - unsigned int old_sel, - unsigned int new_sel) -{ - struct ab8500_regulator_info *info = rdev_get_drvdata(rdev); - int ret; - - /* If the regulator isn't on, it won't take time here */ - ret = ab8500_regulator_is_enabled(rdev); - if (ret < 0) - return ret; - if (!ret) - return 0; - return info->delay; -} - static struct regulator_ops ab8500_regulator_ops = { .enable = ab8500_regulator_enable, .disable = ab8500_regulator_disable, @@ -322,8 +297,6 @@ static struct regulator_ops ab8500_regulator_ops = { .get_voltage = ab8500_regulator_get_voltage, .set_voltage = ab8500_regulator_set_voltage, .list_voltage = ab8500_list_voltage, - .enable_time = ab8500_regulator_enable_time, - .set_voltage_time_sel = ab8500_regulator_set_voltage_time_sel, }; static int ab8500_fixed_get_voltage(struct regulator_dev *rdev) @@ -344,8 +317,6 @@ static struct regulator_ops ab8500_regulator_fixed_ops = { .is_enabled = ab8500_regulator_is_enabled, .get_voltage = ab8500_fixed_get_voltage, .list_voltage = ab8500_list_voltage, - .enable_time = ab8500_regulator_enable_time, - .set_voltage_time_sel = ab8500_regulator_set_voltage_time_sel, }; static struct ab8500_regulator_info @@ -455,28 +426,12 @@ static struct ab8500_regulator_info .owner = THIS_MODULE, .n_voltages = 1, }, - .delay = 10000, .fixed_uV = 2000000, .update_bank = 0x03, .update_reg = 0x80, .update_mask = 0x82, .update_val_enable = 0x02, }, - [AB8500_LDO_USB] = { - .desc = { - .name = "LDO-USB", - .ops = &ab8500_regulator_fixed_ops, - .type = REGULATOR_VOLTAGE, - .id = AB8500_LDO_USB, - .owner = THIS_MODULE, - .n_voltages = 1, - }, - .fixed_uV = 3300000, - .update_bank = 0x03, - .update_reg = 0x82, - .update_mask = 0x03, - .update_val_enable = 0x01, - }, [AB8500_LDO_AUDIO] = { .desc = { .name = "LDO-AUDIO", @@ -556,186 +511,6 @@ static struct ab8500_regulator_info }; -struct ab8500_reg_init { - u8 bank; - u8 addr; - u8 mask; -}; - -#define REG_INIT(_id, _bank, _addr, _mask) \ - [_id] = { \ - .bank = _bank, \ - .addr = _addr, \ - .mask = _mask, \ - } - -static struct ab8500_reg_init ab8500_reg_init[] = { - /* - * 0x30, VanaRequestCtrl - * 0x0C, VpllRequestCtrl - * 0xc0, VextSupply1RequestCtrl - */ - REG_INIT(AB8500_REGUREQUESTCTRL2, 0x03, 0x04, 0xfc), - /* - * 0x03, VextSupply2RequestCtrl - * 0x0c, VextSupply3RequestCtrl - * 0x30, Vaux1RequestCtrl - * 0xc0, Vaux2RequestCtrl - */ - REG_INIT(AB8500_REGUREQUESTCTRL3, 0x03, 0x05, 0xff), - /* - * 0x03, Vaux3RequestCtrl - * 0x04, SwHPReq - */ - REG_INIT(AB8500_REGUREQUESTCTRL4, 0x03, 0x06, 0x07), - /* - * 0x08, VanaSysClkReq1HPValid - * 0x20, Vaux1SysClkReq1HPValid - * 0x40, Vaux2SysClkReq1HPValid - * 0x80, Vaux3SysClkReq1HPValid - */ - REG_INIT(AB8500_REGUSYSCLKREQ1HPVALID1, 0x03, 0x07, 0xe8), - /* - * 0x10, VextSupply1SysClkReq1HPValid - * 0x20, VextSupply2SysClkReq1HPValid - * 0x40, VextSupply3SysClkReq1HPValid - */ - REG_INIT(AB8500_REGUSYSCLKREQ1HPVALID2, 0x03, 0x08, 0x70), - /* - * 0x08, VanaHwHPReq1Valid - * 0x20, Vaux1HwHPReq1Valid - * 0x40, Vaux2HwHPReq1Valid - * 0x80, Vaux3HwHPReq1Valid - */ - REG_INIT(AB8500_REGUHWHPREQ1VALID1, 0x03, 0x09, 0xe8), - /* - * 0x01, VextSupply1HwHPReq1Valid - * 0x02, VextSupply2HwHPReq1Valid - * 0x04, VextSupply3HwHPReq1Valid - */ - REG_INIT(AB8500_REGUHWHPREQ1VALID2, 0x03, 0x0a, 0x07), - /* - * 0x08, VanaHwHPReq2Valid - * 0x20, Vaux1HwHPReq2Valid - * 0x40, Vaux2HwHPReq2Valid - * 0x80, Vaux3HwHPReq2Valid - */ - REG_INIT(AB8500_REGUHWHPREQ2VALID1, 0x03, 0x0b, 0xe8), - /* - * 0x01, VextSupply1HwHPReq2Valid - * 0x02, VextSupply2HwHPReq2Valid - * 0x04, VextSupply3HwHPReq2Valid - */ - REG_INIT(AB8500_REGUHWHPREQ2VALID2, 0x03, 0x0c, 0x07), - /* - * 0x20, VanaSwHPReqValid - * 0x80, Vaux1SwHPReqValid - */ - REG_INIT(AB8500_REGUSWHPREQVALID1, 0x03, 0x0d, 0xa0), - /* - * 0x01, Vaux2SwHPReqValid - * 0x02, Vaux3SwHPReqValid - * 0x04, VextSupply1SwHPReqValid - * 0x08, VextSupply2SwHPReqValid - * 0x10, VextSupply3SwHPReqValid - */ - REG_INIT(AB8500_REGUSWHPREQVALID2, 0x03, 0x0e, 0x1f), - /* - * 0x02, SysClkReq2Valid1 - * ... - * 0x80, SysClkReq8Valid1 - */ - REG_INIT(AB8500_REGUSYSCLKREQVALID1, 0x03, 0x0f, 0xfe), - /* - * 0x02, SysClkReq2Valid2 - * ... - * 0x80, SysClkReq8Valid2 - */ - REG_INIT(AB8500_REGUSYSCLKREQVALID2, 0x03, 0x10, 0xfe), - /* - * 0x02, VTVoutEna - * 0x04, Vintcore12Ena - * 0x38, Vintcore12Sel - * 0x40, Vintcore12LP - * 0x80, VTVoutLP - */ - REG_INIT(AB8500_REGUMISC1, 0x03, 0x80, 0xfe), - /* - * 0x02, VaudioEna - * 0x04, VdmicEna - * 0x08, Vamic1Ena - * 0x10, Vamic2Ena - */ - REG_INIT(AB8500_VAUDIOSUPPLY, 0x03, 0x83, 0x1e), - /* - * 0x01, Vamic1_dzout - * 0x02, Vamic2_dzout - */ - REG_INIT(AB8500_REGUCTRL1VAMIC, 0x03, 0x84, 0x03), - /* - * 0x0c, VanaRegu - * 0x03, VpllRegu - */ - REG_INIT(AB8500_VPLLVANAREGU, 0x04, 0x06, 0x0f), - /* - * 0x01, VrefDDREna - * 0x02, VrefDDRSleepMode - */ - REG_INIT(AB8500_VREFDDR, 0x04, 0x07, 0x03), - /* - * 0x03, VextSupply1Regu - * 0x0c, VextSupply2Regu - * 0x30, VextSupply3Regu - * 0x40, ExtSupply2Bypass - * 0x80, ExtSupply3Bypass - */ - REG_INIT(AB8500_EXTSUPPLYREGU, 0x04, 0x08, 0xff), - /* - * 0x03, Vaux1Regu - * 0x0c, Vaux2Regu - */ - REG_INIT(AB8500_VAUX12REGU, 0x04, 0x09, 0x0f), - /* - * 0x03, Vaux3Regu - */ - REG_INIT(AB8500_VRF1VAUX3REGU, 0x04, 0x0a, 0x03), - /* - * 0x3f, Vsmps1Sel1 - */ - REG_INIT(AB8500_VSMPS1SEL1, 0x04, 0x13, 0x3f), - /* - * 0x0f, Vaux1Sel - */ - REG_INIT(AB8500_VAUX1SEL, 0x04, 0x1f, 0x0f), - /* - * 0x0f, Vaux2Sel - */ - REG_INIT(AB8500_VAUX2SEL, 0x04, 0x20, 0x0f), - /* - * 0x07, Vaux3Sel - */ - REG_INIT(AB8500_VRF1VAUX3SEL, 0x04, 0x21, 0x07), - /* - * 0x01, VextSupply12LP - */ - REG_INIT(AB8500_REGUCTRL2SPARE, 0x04, 0x22, 0x01), - /* - * 0x04, Vaux1Disch - * 0x08, Vaux2Disch - * 0x10, Vaux3Disch - * 0x20, Vintcore12Disch - * 0x40, VTVoutDisch - * 0x80, VaudioDisch - */ - REG_INIT(AB8500_REGUCTRLDISCH, 0x04, 0x43, 0xfc), - /* - * 0x02, VanaDisch - * 0x04, VdmicPullDownEna - * 0x10, VdmicDisch - */ - REG_INIT(AB8500_REGUCTRLDISCH2, 0x04, 0x44, 0x16), -}; - static __devinit int ab8500_regulator_probe(struct platform_device *pdev) { struct ab8500 *ab8500 = dev_get_drvdata(pdev->dev.parent); @@ -754,51 +529,10 @@ static __devinit int ab8500_regulator_probe(struct platform_device *pdev) /* make sure the platform data has the correct size */ if (pdata->num_regulator != ARRAY_SIZE(ab8500_regulator_info)) { - dev_err(&pdev->dev, "Configuration error: size mismatch.\n"); + dev_err(&pdev->dev, "platform configuration error\n"); return -EINVAL; } - /* initialize registers */ - for (i = 0; i < pdata->num_regulator_reg_init; i++) { - int id; - u8 value; - - id = pdata->regulator_reg_init[i].id; - value = pdata->regulator_reg_init[i].value; - - /* check for configuration errors */ - if (id >= AB8500_NUM_REGULATOR_REGISTERS) { - dev_err(&pdev->dev, - "Configuration error: id outside range.\n"); - return -EINVAL; - } - if (value & ~ab8500_reg_init[id].mask) { - dev_err(&pdev->dev, - "Configuration error: value outside mask.\n"); - return -EINVAL; - } - - /* initialize register */ - err = abx500_mask_and_set_register_interruptible(&pdev->dev, - ab8500_reg_init[id].bank, - ab8500_reg_init[id].addr, - ab8500_reg_init[id].mask, - value); - if (err < 0) { - dev_err(&pdev->dev, - "Failed to initialize 0x%02x, 0x%02x.\n", - ab8500_reg_init[id].bank, - ab8500_reg_init[id].addr); - return err; - } - dev_vdbg(&pdev->dev, - " init: 0x%02x, 0x%02x, 0x%02x, 0x%02x\n", - ab8500_reg_init[id].bank, - ab8500_reg_init[id].addr, - ab8500_reg_init[id].mask, - value); - } - /* register all regulators */ for (i = 0; i < ARRAY_SIZE(ab8500_regulator_info); i++) { struct ab8500_regulator_info *info = NULL; diff --git a/trunk/drivers/regulator/core.c b/trunk/drivers/regulator/core.c index 3ffc6979d164..9fa20957847d 100644 --- a/trunk/drivers/regulator/core.c +++ b/trunk/drivers/regulator/core.c @@ -1629,7 +1629,6 @@ static int _regulator_do_set_voltage(struct regulator_dev *rdev, int min_uV, int max_uV) { int ret; - int delay = 0; unsigned int selector; trace_regulator_set_voltage(rdev_get_name(rdev), min_uV, max_uV); @@ -1663,22 +1662,6 @@ static int _regulator_do_set_voltage(struct regulator_dev *rdev, } } - /* - * If we can't obtain the old selector there is not enough - * info to call set_voltage_time_sel(). - */ - if (rdev->desc->ops->set_voltage_time_sel && - rdev->desc->ops->get_voltage_sel) { - unsigned int old_selector = 0; - - ret = rdev->desc->ops->get_voltage_sel(rdev); - if (ret < 0) - return ret; - old_selector = ret; - delay = rdev->desc->ops->set_voltage_time_sel(rdev, - old_selector, selector); - } - if (best_val != INT_MAX) { ret = rdev->desc->ops->set_voltage_sel(rdev, selector); selector = best_val; @@ -1689,14 +1672,6 @@ static int _regulator_do_set_voltage(struct regulator_dev *rdev, ret = -EINVAL; } - /* Insert any necessary delays */ - if (delay >= 1000) { - mdelay(delay / 1000); - udelay(delay % 1000); - } else if (delay) { - udelay(delay); - } - if (ret == 0) _notifier_call_chain(rdev, REGULATOR_EVENT_VOLTAGE_CHANGE, NULL); @@ -1764,51 +1739,6 @@ int regulator_set_voltage(struct regulator *regulator, int min_uV, int max_uV) } EXPORT_SYMBOL_GPL(regulator_set_voltage); -/** - * regulator_set_voltage_time - get raise/fall time - * @regulator: regulator source - * @old_uV: starting voltage in microvolts - * @new_uV: target voltage in microvolts - * - * Provided with the starting and ending voltage, this function attempts to - * calculate the time in microseconds required to rise or fall to this new - * voltage. - */ -int regulator_set_voltage_time(struct regulator *regulator, - int old_uV, int new_uV) -{ - struct regulator_dev *rdev = regulator->rdev; - struct regulator_ops *ops = rdev->desc->ops; - int old_sel = -1; - int new_sel = -1; - int voltage; - int i; - - /* Currently requires operations to do this */ - if (!ops->list_voltage || !ops->set_voltage_time_sel - || !rdev->desc->n_voltages) - return -EINVAL; - - for (i = 0; i < rdev->desc->n_voltages; i++) { - /* We only look for exact voltage matches here */ - voltage = regulator_list_voltage(regulator, i); - if (voltage < 0) - return -EINVAL; - if (voltage == 0) - continue; - if (voltage == old_uV) - old_sel = i; - if (voltage == new_uV) - new_sel = i; - } - - if (old_sel < 0 || new_sel < 0) - return -EINVAL; - - return ops->set_voltage_time_sel(rdev, old_sel, new_sel); -} -EXPORT_SYMBOL_GPL(regulator_set_voltage_time); - /** * regulator_sync_voltage - re-apply last regulator output voltage * @regulator: regulator source @@ -2635,11 +2565,8 @@ struct regulator_dev *regulator_register(struct regulator_desc *regulator_desc, init_data->consumer_supplies[i].dev, init_data->consumer_supplies[i].dev_name, init_data->consumer_supplies[i].supply); - if (ret < 0) { - dev_err(dev, "Failed to set supply %s\n", - init_data->consumer_supplies[i].supply); + if (ret < 0) goto unset_supplies; - } } list_add(&rdev->list, ®ulator_list); @@ -2725,47 +2652,6 @@ int regulator_suspend_prepare(suspend_state_t state) } EXPORT_SYMBOL_GPL(regulator_suspend_prepare); -/** - * regulator_suspend_finish - resume regulators from system wide suspend - * - * Turn on regulators that might be turned off by regulator_suspend_prepare - * and that should be turned on according to the regulators properties. - */ -int regulator_suspend_finish(void) -{ - struct regulator_dev *rdev; - int ret = 0, error; - - mutex_lock(®ulator_list_mutex); - list_for_each_entry(rdev, ®ulator_list, list) { - struct regulator_ops *ops = rdev->desc->ops; - - mutex_lock(&rdev->mutex); - if ((rdev->use_count > 0 || rdev->constraints->always_on) && - ops->enable) { - error = ops->enable(rdev); - if (error) - ret = error; - } else { - if (!has_full_constraints) - goto unlock; - if (!ops->disable) - goto unlock; - if (ops->is_enabled && !ops->is_enabled(rdev)) - goto unlock; - - error = ops->disable(rdev); - if (error) - ret = error; - } -unlock: - mutex_unlock(&rdev->mutex); - } - mutex_unlock(®ulator_list_mutex); - return ret; -} -EXPORT_SYMBOL_GPL(regulator_suspend_finish); - /** * regulator_has_full_constraints - the system has fully specified constraints * diff --git a/trunk/drivers/regulator/max8997.c b/trunk/drivers/regulator/max8997.c index 77e0cfb30b23..01ef7e9903bb 100644 --- a/trunk/drivers/regulator/max8997.c +++ b/trunk/drivers/regulator/max8997.c @@ -1185,7 +1185,6 @@ static const struct platform_device_id max8997_pmic_id[] = { { "max8997-pmic", 0}, { }, }; -MODULE_DEVICE_TABLE(platform, max8997_pmic_id); static struct platform_driver max8997_pmic_driver = { .driver = { diff --git a/trunk/drivers/regulator/max8998.c b/trunk/drivers/regulator/max8998.c index 43410266f993..0ec49ca527a8 100644 --- a/trunk/drivers/regulator/max8998.c +++ b/trunk/drivers/regulator/max8998.c @@ -887,7 +887,6 @@ static const struct platform_device_id max8998_pmic_id[] = { { "lp3974-pmic", TYPE_LP3974 }, { } }; -MODULE_DEVICE_TABLE(platform, max8998_pmic_id); static struct platform_driver max8998_pmic_driver = { .driver = { diff --git a/trunk/drivers/regulator/tps6524x-regulator.c b/trunk/drivers/regulator/tps6524x-regulator.c index 9166aa0a9df7..176a6be5a8ce 100644 --- a/trunk/drivers/regulator/tps6524x-regulator.c +++ b/trunk/drivers/regulator/tps6524x-regulator.c @@ -596,7 +596,7 @@ static struct regulator_ops regulator_ops = { .get_current_limit = get_current_limit, }; -static int pmic_remove(struct spi_device *spi) +static int __devexit pmic_remove(struct spi_device *spi) { struct tps6524x *hw = spi_get_drvdata(spi); int i; diff --git a/trunk/drivers/regulator/wm831x-dcdc.c b/trunk/drivers/regulator/wm831x-dcdc.c index e93453b1b978..06df898842c0 100644 --- a/trunk/drivers/regulator/wm831x-dcdc.c +++ b/trunk/drivers/regulator/wm831x-dcdc.c @@ -565,8 +565,9 @@ static __devinit int wm831x_buckv_probe(struct platform_device *pdev) } irq = platform_get_irq_byname(pdev, "UV"); - ret = request_threaded_irq(irq, NULL, wm831x_dcdc_uv_irq, - IRQF_TRIGGER_RISING, dcdc->name, dcdc); + ret = wm831x_request_irq(wm831x, irq, wm831x_dcdc_uv_irq, + IRQF_TRIGGER_RISING, dcdc->name, + dcdc); if (ret != 0) { dev_err(&pdev->dev, "Failed to request UV IRQ %d: %d\n", irq, ret); @@ -574,8 +575,9 @@ static __devinit int wm831x_buckv_probe(struct platform_device *pdev) } irq = platform_get_irq_byname(pdev, "HC"); - ret = request_threaded_irq(irq, NULL, wm831x_dcdc_oc_irq, - IRQF_TRIGGER_RISING, dcdc->name, dcdc); + ret = wm831x_request_irq(wm831x, irq, wm831x_dcdc_oc_irq, + IRQF_TRIGGER_RISING, dcdc->name, + dcdc); if (ret != 0) { dev_err(&pdev->dev, "Failed to request HC IRQ %d: %d\n", irq, ret); @@ -587,7 +589,7 @@ static __devinit int wm831x_buckv_probe(struct platform_device *pdev) return 0; err_uv: - free_irq(platform_get_irq_byname(pdev, "UV"), dcdc); + wm831x_free_irq(wm831x, platform_get_irq_byname(pdev, "UV"), dcdc); err_regulator: regulator_unregister(dcdc->regulator); err: @@ -604,8 +606,8 @@ static __devexit int wm831x_buckv_remove(struct platform_device *pdev) platform_set_drvdata(pdev, NULL); - free_irq(platform_get_irq_byname(pdev, "HC"), dcdc); - free_irq(platform_get_irq_byname(pdev, "UV"), dcdc); + wm831x_free_irq(wm831x, platform_get_irq_byname(pdev, "HC"), dcdc); + wm831x_free_irq(wm831x, platform_get_irq_byname(pdev, "UV"), dcdc); regulator_unregister(dcdc->regulator); if (dcdc->dvs_gpio) gpio_free(dcdc->dvs_gpio); @@ -754,8 +756,9 @@ static __devinit int wm831x_buckp_probe(struct platform_device *pdev) } irq = platform_get_irq_byname(pdev, "UV"); - ret = request_threaded_irq(irq, NULL, wm831x_dcdc_uv_irq, - IRQF_TRIGGER_RISING, dcdc->name, dcdc); + ret = wm831x_request_irq(wm831x, irq, wm831x_dcdc_uv_irq, + IRQF_TRIGGER_RISING, dcdc->name, + dcdc); if (ret != 0) { dev_err(&pdev->dev, "Failed to request UV IRQ %d: %d\n", irq, ret); @@ -780,7 +783,7 @@ static __devexit int wm831x_buckp_remove(struct platform_device *pdev) platform_set_drvdata(pdev, NULL); - free_irq(platform_get_irq_byname(pdev, "UV"), dcdc); + wm831x_free_irq(wm831x, platform_get_irq_byname(pdev, "UV"), dcdc); regulator_unregister(dcdc->regulator); kfree(dcdc); @@ -882,9 +885,9 @@ static __devinit int wm831x_boostp_probe(struct platform_device *pdev) } irq = platform_get_irq_byname(pdev, "UV"); - ret = request_threaded_irq(irq, NULL, wm831x_dcdc_uv_irq, - IRQF_TRIGGER_RISING, dcdc->name, - dcdc); + ret = wm831x_request_irq(wm831x, irq, wm831x_dcdc_uv_irq, + IRQF_TRIGGER_RISING, dcdc->name, + dcdc); if (ret != 0) { dev_err(&pdev->dev, "Failed to request UV IRQ %d: %d\n", irq, ret); @@ -905,10 +908,11 @@ static __devinit int wm831x_boostp_probe(struct platform_device *pdev) static __devexit int wm831x_boostp_remove(struct platform_device *pdev) { struct wm831x_dcdc *dcdc = platform_get_drvdata(pdev); + struct wm831x *wm831x = dcdc->wm831x; platform_set_drvdata(pdev, NULL); - free_irq(platform_get_irq_byname(pdev, "UV"), dcdc); + wm831x_free_irq(wm831x, platform_get_irq_byname(pdev, "UV"), dcdc); regulator_unregister(dcdc->regulator); kfree(dcdc); diff --git a/trunk/drivers/regulator/wm831x-isink.c b/trunk/drivers/regulator/wm831x-isink.c index 01f27c7f4236..6c446cd6ad54 100644 --- a/trunk/drivers/regulator/wm831x-isink.c +++ b/trunk/drivers/regulator/wm831x-isink.c @@ -198,8 +198,9 @@ static __devinit int wm831x_isink_probe(struct platform_device *pdev) } irq = platform_get_irq(pdev, 0); - ret = request_threaded_irq(irq, NULL, wm831x_isink_irq, - IRQF_TRIGGER_RISING, isink->name, isink); + ret = wm831x_request_irq(wm831x, irq, wm831x_isink_irq, + IRQF_TRIGGER_RISING, isink->name, + isink); if (ret != 0) { dev_err(&pdev->dev, "Failed to request ISINK IRQ %d: %d\n", irq, ret); @@ -220,10 +221,11 @@ static __devinit int wm831x_isink_probe(struct platform_device *pdev) static __devexit int wm831x_isink_remove(struct platform_device *pdev) { struct wm831x_isink *isink = platform_get_drvdata(pdev); + struct wm831x *wm831x = isink->wm831x; platform_set_drvdata(pdev, NULL); - free_irq(platform_get_irq(pdev, 0), isink); + wm831x_free_irq(wm831x, platform_get_irq(pdev, 0), isink); regulator_unregister(isink->regulator); kfree(isink); diff --git a/trunk/drivers/regulator/wm831x-ldo.c b/trunk/drivers/regulator/wm831x-ldo.c index 2220cf8defb1..c94fc5b7cd5b 100644 --- a/trunk/drivers/regulator/wm831x-ldo.c +++ b/trunk/drivers/regulator/wm831x-ldo.c @@ -354,9 +354,9 @@ static __devinit int wm831x_gp_ldo_probe(struct platform_device *pdev) } irq = platform_get_irq_byname(pdev, "UV"); - ret = request_threaded_irq(irq, NULL, wm831x_ldo_uv_irq, - IRQF_TRIGGER_RISING, ldo->name, - ldo); + ret = wm831x_request_irq(wm831x, irq, wm831x_ldo_uv_irq, + IRQF_TRIGGER_RISING, ldo->name, + ldo); if (ret != 0) { dev_err(&pdev->dev, "Failed to request UV IRQ %d: %d\n", irq, ret); @@ -377,10 +377,11 @@ static __devinit int wm831x_gp_ldo_probe(struct platform_device *pdev) static __devexit int wm831x_gp_ldo_remove(struct platform_device *pdev) { struct wm831x_ldo *ldo = platform_get_drvdata(pdev); + struct wm831x *wm831x = ldo->wm831x; platform_set_drvdata(pdev, NULL); - free_irq(platform_get_irq_byname(pdev, "UV"), ldo); + wm831x_free_irq(wm831x, platform_get_irq_byname(pdev, "UV"), ldo); regulator_unregister(ldo->regulator); kfree(ldo); @@ -618,8 +619,9 @@ static __devinit int wm831x_aldo_probe(struct platform_device *pdev) } irq = platform_get_irq_byname(pdev, "UV"); - ret = request_threaded_irq(irq, NULL, wm831x_ldo_uv_irq, - IRQF_TRIGGER_RISING, ldo->name, ldo); + ret = wm831x_request_irq(wm831x, irq, wm831x_ldo_uv_irq, + IRQF_TRIGGER_RISING, ldo->name, + ldo); if (ret != 0) { dev_err(&pdev->dev, "Failed to request UV IRQ %d: %d\n", irq, ret); @@ -640,8 +642,9 @@ static __devinit int wm831x_aldo_probe(struct platform_device *pdev) static __devexit int wm831x_aldo_remove(struct platform_device *pdev) { struct wm831x_ldo *ldo = platform_get_drvdata(pdev); + struct wm831x *wm831x = ldo->wm831x; - free_irq(platform_get_irq_byname(pdev, "UV"), ldo); + wm831x_free_irq(wm831x, platform_get_irq_byname(pdev, "UV"), ldo); regulator_unregister(ldo->regulator); kfree(ldo); diff --git a/trunk/drivers/rtc/rtc-sh.c b/trunk/drivers/rtc/rtc-sh.c index 6ac55fd48413..e55dc1ac83ab 100644 --- a/trunk/drivers/rtc/rtc-sh.c +++ b/trunk/drivers/rtc/rtc-sh.c @@ -782,11 +782,11 @@ static void sh_rtc_set_irq_wake(struct device *dev, int enabled) struct platform_device *pdev = to_platform_device(dev); struct sh_rtc *rtc = platform_get_drvdata(pdev); - irq_set_irq_wake(rtc->periodic_irq, enabled); + set_irq_wake(rtc->periodic_irq, enabled); if (rtc->carry_irq > 0) { - irq_set_irq_wake(rtc->carry_irq, enabled); - irq_set_irq_wake(rtc->alarm_irq, enabled); + set_irq_wake(rtc->carry_irq, enabled); + set_irq_wake(rtc->alarm_irq, enabled); } } diff --git a/trunk/drivers/sh/intc/core.c b/trunk/drivers/sh/intc/core.c index c6ca115c71df..5833afbf08d7 100644 --- a/trunk/drivers/sh/intc/core.c +++ b/trunk/drivers/sh/intc/core.c @@ -63,7 +63,7 @@ void intc_set_prio_level(unsigned int irq, unsigned int level) static void intc_redirect_irq(unsigned int irq, struct irq_desc *desc) { - generic_handle_irq((unsigned int)irq_get_handler_data(irq)); + generic_handle_irq((unsigned int)get_irq_data(irq)); } static void __init intc_register_irq(struct intc_desc *desc, @@ -116,9 +116,9 @@ static void __init intc_register_irq(struct intc_desc *desc, irq_data = irq_get_irq_data(irq); disable_irq_nosync(irq); - irq_set_chip_and_handler_name(irq, &d->chip, handle_level_irq, - "level"); - irq_set_chip_data(irq, (void *)data[primary]); + set_irq_chip_and_handler_name(irq, &d->chip, + handle_level_irq, "level"); + set_irq_chip_data(irq, (void *)data[primary]); /* * set priority level @@ -340,9 +340,9 @@ int __init register_intc_controller(struct intc_desc *desc) vect2->enum_id = 0; /* redirect this interrupts to the first one */ - irq_set_chip(irq2, &dummy_irq_chip); - irq_set_chained_handler(irq2, intc_redirect_irq); - irq_set_handler_data(irq2, (void *)irq); + set_irq_chip(irq2, &dummy_irq_chip); + set_irq_chained_handler(irq2, intc_redirect_irq); + set_irq_data(irq2, (void *)irq); } } @@ -387,16 +387,19 @@ static int intc_suspend(void) /* enable wakeup irqs belonging to this intc controller */ for_each_active_irq(irq) { struct irq_data *data; + struct irq_desc *desc; struct irq_chip *chip; data = irq_get_irq_data(irq); chip = irq_data_get_irq_chip(data); if (chip != &d->chip) continue; - if (irqd_is_wakeup_set(data)) + desc = irq_to_desc(irq); + if ((desc->status & IRQ_WAKEUP)) chip->irq_enable(data); } } + return 0; } @@ -409,6 +412,7 @@ static void intc_resume(void) for_each_active_irq(irq) { struct irq_data *data; + struct irq_desc *desc; struct irq_chip *chip; data = irq_get_irq_data(irq); @@ -419,7 +423,8 @@ static void intc_resume(void) */ if (chip != &d->chip) continue; - if (irqd_irq_disabled(data)) + desc = irq_to_desc(irq); + if (desc->status & IRQ_DISABLED) chip->irq_disable(data); else chip->irq_enable(data); diff --git a/trunk/drivers/sh/intc/virq.c b/trunk/drivers/sh/intc/virq.c index ce5f81d7cc6b..4e0ff7181164 100644 --- a/trunk/drivers/sh/intc/virq.c +++ b/trunk/drivers/sh/intc/virq.c @@ -110,7 +110,7 @@ static void intc_virq_handler(unsigned int irq, struct irq_desc *desc) { struct irq_data *data = irq_get_irq_data(irq); struct irq_chip *chip = irq_data_get_irq_chip(data); - struct intc_virq_list *entry, *vlist = irq_data_get_irq_handler_data(data); + struct intc_virq_list *entry, *vlist = irq_data_get_irq_data(data); struct intc_desc_int *d = get_intc_desc(irq); chip->irq_mask_ack(data); @@ -118,7 +118,7 @@ static void intc_virq_handler(unsigned int irq, struct irq_desc *desc) for_each_virq(entry, vlist) { unsigned long addr, handle; - handle = (unsigned long)irq_get_handler_data(entry->irq); + handle = (unsigned long)get_irq_data(entry->irq); addr = INTC_REG(d, _INTC_ADDR_E(handle), 0); if (intc_reg_fns[_INTC_FN(handle)](addr, handle, 0)) @@ -229,13 +229,13 @@ static void __init intc_subgroup_map(struct intc_desc_int *d) intc_irq_xlate_set(irq, entry->enum_id, d); - irq_set_chip_and_handler_name(irq, irq_get_chip(entry->pirq), + set_irq_chip_and_handler_name(irq, get_irq_chip(entry->pirq), handle_simple_irq, "virq"); - irq_set_chip_data(irq, irq_get_chip_data(entry->pirq)); + set_irq_chip_data(irq, get_irq_chip_data(entry->pirq)); - irq_set_handler_data(irq, (void *)entry->handle); + set_irq_data(irq, (void *)entry->handle); - irq_set_chained_handler(entry->pirq, intc_virq_handler); + set_irq_chained_handler(entry->pirq, intc_virq_handler); add_virq_to_pirq(entry->pirq, irq); radix_tree_tag_clear(&d->tree, entry->enum_id, diff --git a/trunk/drivers/staging/brcm80211/brcmfmac/bcmsdh_linux.c b/trunk/drivers/staging/brcm80211/brcmfmac/bcmsdh_linux.c index ac5bbc8722e5..e3556ff43bb9 100644 --- a/trunk/drivers/staging/brcm80211/brcmfmac/bcmsdh_linux.c +++ b/trunk/drivers/staging/brcm80211/brcmfmac/bcmsdh_linux.c @@ -341,7 +341,7 @@ int bcmsdh_register_oob_intr(void *dhdp) if (error) return -ENODEV; - irq_set_irq_wake(sdhcinfo->oob_irq, 1); + set_irq_wake(sdhcinfo->oob_irq, 1); sdhcinfo->oob_irq_registered = true; } @@ -352,7 +352,7 @@ void bcmsdh_unregister_oob_intr(void) { SDLX_MSG(("%s: Enter\n", __func__)); - irq_set_irq_wake(sdhcinfo->oob_irq, 0); + set_irq_wake(sdhcinfo->oob_irq, 0); disable_irq(sdhcinfo->oob_irq); /* just in case.. */ free_irq(sdhcinfo->oob_irq, NULL); sdhcinfo->oob_irq_registered = false; diff --git a/trunk/drivers/staging/westbridge/astoria/arch/arm/mach-omap2/cyashalomap_kernel.c b/trunk/drivers/staging/westbridge/astoria/arch/arm/mach-omap2/cyashalomap_kernel.c index 21cdb0637beb..ea9b733c3926 100644 --- a/trunk/drivers/staging/westbridge/astoria/arch/arm/mach-omap2/cyashalomap_kernel.c +++ b/trunk/drivers/staging/westbridge/astoria/arch/arm/mach-omap2/cyashalomap_kernel.c @@ -597,7 +597,7 @@ static int cy_as_hal_configure_interrupts(void *dev_p) int result; int irq_pin = AST_INT; - irq_set_irq_type(OMAP_GPIO_IRQ(irq_pin), IRQ_TYPE_LEVEL_LOW); + set_irq_type(OMAP_GPIO_IRQ(irq_pin), IRQ_TYPE_LEVEL_LOW); /* * for shared IRQS must provide non NULL device ptr diff --git a/trunk/drivers/staging/westbridge/astoria/block/cyasblkdev_block.c b/trunk/drivers/staging/westbridge/astoria/block/cyasblkdev_block.c index 289729daba80..842cd9214a5e 100644 --- a/trunk/drivers/staging/westbridge/astoria/block/cyasblkdev_block.c +++ b/trunk/drivers/staging/westbridge/astoria/block/cyasblkdev_block.c @@ -1191,7 +1191,7 @@ static int cyasblkdev_add_disks(int bus_num, bd->user_disk_1->first_minor = (devidx + 1) << CYASBLKDEV_SHIFT; bd->user_disk_1->minors = 8; bd->user_disk_1->fops = &cyasblkdev_bdops; - bd->user_disk_1->events = DISK_EVENT_MEDIA_CHANGE; + bd->user_disk_0->events = DISK_EVENT_MEDIA_CHANGE; bd->user_disk_1->private_data = bd; bd->user_disk_1->queue = bd->queue.queue; bd->dbgprn_flags = DBGPRN_RD_RQ; diff --git a/trunk/drivers/tty/hvc/hvc_xen.c b/trunk/drivers/tty/hvc/hvc_xen.c index 52fdf60bdbe2..c35f1a73bc8b 100644 --- a/trunk/drivers/tty/hvc/hvc_xen.c +++ b/trunk/drivers/tty/hvc/hvc_xen.c @@ -178,7 +178,7 @@ static int __init xen_hvc_init(void) if (xencons_irq < 0) xencons_irq = 0; /* NO_IRQ */ else - irq_set_noprobe(xencons_irq); + set_irq_noprobe(xencons_irq); hp = hvc_alloc(HVC_COOKIE, xencons_irq, ops, 256); if (IS_ERR(hp)) diff --git a/trunk/drivers/tty/serial/msm_serial_hs.c b/trunk/drivers/tty/serial/msm_serial_hs.c index b906f11f7c1a..2e7fc9cee9cc 100644 --- a/trunk/drivers/tty/serial/msm_serial_hs.c +++ b/trunk/drivers/tty/serial/msm_serial_hs.c @@ -1644,7 +1644,7 @@ static int __devinit msm_hs_probe(struct platform_device *pdev) if (unlikely(uport->irq < 0)) return -ENXIO; - if (unlikely(irq_set_irq_wake(uport->irq, 1))) + if (unlikely(set_irq_wake(uport->irq, 1))) return -ENXIO; if (pdata == NULL || pdata->rx_wakeup_irq < 0) @@ -1658,7 +1658,7 @@ static int __devinit msm_hs_probe(struct platform_device *pdev) if (unlikely(msm_uport->rx_wakeup.irq < 0)) return -ENXIO; - if (unlikely(irq_set_irq_wake(msm_uport->rx_wakeup.irq, 1))) + if (unlikely(set_irq_wake(msm_uport->rx_wakeup.irq, 1))) return -ENXIO; } diff --git a/trunk/drivers/usb/host/oxu210hp-hcd.c b/trunk/drivers/usb/host/oxu210hp-hcd.c index 44e4deb362e1..38193f4e980e 100644 --- a/trunk/drivers/usb/host/oxu210hp-hcd.c +++ b/trunk/drivers/usb/host/oxu210hp-hcd.c @@ -3832,7 +3832,7 @@ static int oxu_drv_probe(struct platform_device *pdev) return -EBUSY; } - ret = irq_set_irq_type(irq, IRQF_TRIGGER_FALLING); + ret = set_irq_type(irq, IRQF_TRIGGER_FALLING); if (ret) { dev_err(&pdev->dev, "error setting irq type\n"); ret = -EFAULT; diff --git a/trunk/drivers/usb/musb/tusb6010.c b/trunk/drivers/usb/musb/tusb6010.c index c47aac4a1f98..2ba3b070ed0b 100644 --- a/trunk/drivers/usb/musb/tusb6010.c +++ b/trunk/drivers/usb/musb/tusb6010.c @@ -943,7 +943,7 @@ static void tusb_musb_enable(struct musb *musb) musb_writel(tbase, TUSB_INT_CTRL_CONF, TUSB_INT_CTRL_CONF_INT_RELCYC(0)); - irq_set_irq_type(musb->nIrq, IRQ_TYPE_LEVEL_LOW); + set_irq_type(musb->nIrq, IRQ_TYPE_LEVEL_LOW); /* maybe force into the Default-A OTG state machine */ if (!(musb_readl(tbase, TUSB_DEV_OTG_STAT) diff --git a/trunk/drivers/vlynq/vlynq.c b/trunk/drivers/vlynq/vlynq.c index aa250cebecd2..f885c868a04d 100644 --- a/trunk/drivers/vlynq/vlynq.c +++ b/trunk/drivers/vlynq/vlynq.c @@ -135,40 +135,40 @@ static void vlynq_reset(struct vlynq_device *dev) msleep(5); } -static void vlynq_irq_unmask(struct irq_data *d) +static void vlynq_irq_unmask(unsigned int irq) { - struct vlynq_device *dev = irq_data_get_irq_chip_data(d); - int virq; u32 val; + struct vlynq_device *dev = get_irq_chip_data(irq); + int virq; BUG_ON(!dev); - virq = d->irq - dev->irq_start; + virq = irq - dev->irq_start; val = readl(&dev->remote->int_device[virq >> 2]); val |= (VINT_ENABLE | virq) << VINT_OFFSET(virq); writel(val, &dev->remote->int_device[virq >> 2]); } -static void vlynq_irq_mask(struct irq_data *d) +static void vlynq_irq_mask(unsigned int irq) { - struct vlynq_device *dev = irq_data_get_irq_chip_data(d); - int virq; u32 val; + struct vlynq_device *dev = get_irq_chip_data(irq); + int virq; BUG_ON(!dev); - virq = d->irq - dev->irq_start; + virq = irq - dev->irq_start; val = readl(&dev->remote->int_device[virq >> 2]); val &= ~(VINT_ENABLE << VINT_OFFSET(virq)); writel(val, &dev->remote->int_device[virq >> 2]); } -static int vlynq_irq_type(struct irq_data *d, unsigned int flow_type) +static int vlynq_irq_type(unsigned int irq, unsigned int flow_type) { - struct vlynq_device *dev = irq_data_get_irq_chip_data(d); - int virq; u32 val; + struct vlynq_device *dev = get_irq_chip_data(irq); + int virq; BUG_ON(!dev); - virq = d->irq - dev->irq_start; + virq = irq - dev->irq_start; val = readl(&dev->remote->int_device[virq >> 2]); switch (flow_type & IRQ_TYPE_SENSE_MASK) { case IRQ_TYPE_EDGE_RISING: @@ -192,9 +192,10 @@ static int vlynq_irq_type(struct irq_data *d, unsigned int flow_type) return 0; } -static void vlynq_local_ack(struct irq_data *d) +static void vlynq_local_ack(unsigned int irq) { - struct vlynq_device *dev = irq_data_get_irq_chip_data(d); + struct vlynq_device *dev = get_irq_chip_data(irq); + u32 status = readl(&dev->local->status); pr_debug("%s: local status: 0x%08x\n", @@ -202,9 +203,10 @@ static void vlynq_local_ack(struct irq_data *d) writel(status, &dev->local->status); } -static void vlynq_remote_ack(struct irq_data *d) +static void vlynq_remote_ack(unsigned int irq) { - struct vlynq_device *dev = irq_data_get_irq_chip_data(d); + struct vlynq_device *dev = get_irq_chip_data(irq); + u32 status = readl(&dev->remote->status); pr_debug("%s: remote status: 0x%08x\n", @@ -236,23 +238,23 @@ static irqreturn_t vlynq_irq(int irq, void *dev_id) static struct irq_chip vlynq_irq_chip = { .name = "vlynq", - .irq_unmask = vlynq_irq_unmask, - .irq_mask = vlynq_irq_mask, - .irq_set_type = vlynq_irq_type, + .unmask = vlynq_irq_unmask, + .mask = vlynq_irq_mask, + .set_type = vlynq_irq_type, }; static struct irq_chip vlynq_local_chip = { .name = "vlynq local error", - .irq_unmask = vlynq_irq_unmask, - .irq_mask = vlynq_irq_mask, - .irq_ack = vlynq_local_ack, + .unmask = vlynq_irq_unmask, + .mask = vlynq_irq_mask, + .ack = vlynq_local_ack, }; static struct irq_chip vlynq_remote_chip = { .name = "vlynq local error", - .irq_unmask = vlynq_irq_unmask, - .irq_mask = vlynq_irq_mask, - .irq_ack = vlynq_remote_ack, + .unmask = vlynq_irq_unmask, + .mask = vlynq_irq_mask, + .ack = vlynq_remote_ack, }; static int vlynq_setup_irq(struct vlynq_device *dev) @@ -289,17 +291,17 @@ static int vlynq_setup_irq(struct vlynq_device *dev) for (i = dev->irq_start; i <= dev->irq_end; i++) { virq = i - dev->irq_start; if (virq == dev->local_irq) { - irq_set_chip_and_handler(i, &vlynq_local_chip, + set_irq_chip_and_handler(i, &vlynq_local_chip, handle_level_irq); - irq_set_chip_data(i, dev); + set_irq_chip_data(i, dev); } else if (virq == dev->remote_irq) { - irq_set_chip_and_handler(i, &vlynq_remote_chip, + set_irq_chip_and_handler(i, &vlynq_remote_chip, handle_level_irq); - irq_set_chip_data(i, dev); + set_irq_chip_data(i, dev); } else { - irq_set_chip_and_handler(i, &vlynq_irq_chip, + set_irq_chip_and_handler(i, &vlynq_irq_chip, handle_simple_irq); - irq_set_chip_data(i, dev); + set_irq_chip_data(i, dev); writel(0, &dev->remote->int_device[virq >> 2]); } } diff --git a/trunk/drivers/w1/masters/ds1wm.c b/trunk/drivers/w1/masters/ds1wm.c index 2f4fa02744a5..95921b77cf86 100644 --- a/trunk/drivers/w1/masters/ds1wm.c +++ b/trunk/drivers/w1/masters/ds1wm.c @@ -368,9 +368,9 @@ static int ds1wm_probe(struct platform_device *pdev) ds1wm_data->active_high = plat->active_high; if (res->flags & IORESOURCE_IRQ_HIGHEDGE) - irq_set_irq_type(ds1wm_data->irq, IRQ_TYPE_EDGE_RISING); + set_irq_type(ds1wm_data->irq, IRQ_TYPE_EDGE_RISING); if (res->flags & IORESOURCE_IRQ_LOWEDGE) - irq_set_irq_type(ds1wm_data->irq, IRQ_TYPE_EDGE_FALLING); + set_irq_type(ds1wm_data->irq, IRQ_TYPE_EDGE_FALLING); ret = request_irq(ds1wm_data->irq, ds1wm_isr, IRQF_DISABLED, "ds1wm", ds1wm_data); diff --git a/trunk/drivers/watchdog/davinci_wdt.c b/trunk/drivers/watchdog/davinci_wdt.c index 51b5551b4e3f..596ba604e78d 100644 --- a/trunk/drivers/watchdog/davinci_wdt.c +++ b/trunk/drivers/watchdog/davinci_wdt.c @@ -202,6 +202,7 @@ static struct miscdevice davinci_wdt_miscdev = { static int __devinit davinci_wdt_probe(struct platform_device *pdev) { int ret = 0, size; + struct resource *res; struct device *dev = &pdev->dev; wdt_clk = clk_get(dev, NULL); @@ -215,31 +216,31 @@ static int __devinit davinci_wdt_probe(struct platform_device *pdev) dev_info(dev, "heartbeat %d sec\n", heartbeat); - wdt_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (wdt_mem == NULL) { + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (res == NULL) { dev_err(dev, "failed to get memory region resource\n"); return -ENOENT; } - size = resource_size(wdt_mem); - if (!request_mem_region(wdt_mem->start, size, pdev->name)) { + size = resource_size(res); + wdt_mem = request_mem_region(res->start, size, pdev->name); + + if (wdt_mem == NULL) { dev_err(dev, "failed to get memory region\n"); return -ENOENT; } - wdt_base = ioremap(wdt_mem->start, size); + wdt_base = ioremap(res->start, size); if (!wdt_base) { dev_err(dev, "failed to map memory region\n"); - release_mem_region(wdt_mem->start, size); - wdt_mem = NULL; return -ENOMEM; } ret = misc_register(&davinci_wdt_miscdev); if (ret < 0) { dev_err(dev, "cannot register misc device\n"); - release_mem_region(wdt_mem->start, size); - wdt_mem = NULL; + release_resource(wdt_mem); + kfree(wdt_mem); } else { set_bit(WDT_DEVICE_INITED, &wdt_status); } @@ -252,7 +253,8 @@ static int __devexit davinci_wdt_remove(struct platform_device *pdev) { misc_deregister(&davinci_wdt_miscdev); if (wdt_mem) { - release_mem_region(wdt_mem->start, resource_size(wdt_mem)); + release_resource(wdt_mem); + kfree(wdt_mem); wdt_mem = NULL; } diff --git a/trunk/drivers/watchdog/max63xx_wdt.c b/trunk/drivers/watchdog/max63xx_wdt.c index 73ba2fd8e591..7a82ce5a6337 100644 --- a/trunk/drivers/watchdog/max63xx_wdt.c +++ b/trunk/drivers/watchdog/max63xx_wdt.c @@ -270,6 +270,7 @@ static int __devinit max63xx_wdt_probe(struct platform_device *pdev) { int ret = 0; int size; + struct resource *res; struct device *dev = &pdev->dev; struct max63xx_timeout *table; @@ -293,19 +294,21 @@ static int __devinit max63xx_wdt_probe(struct platform_device *pdev) max63xx_pdev = pdev; - wdt_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (wdt_mem == NULL) { + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (res == NULL) { dev_err(dev, "failed to get memory region resource\n"); return -ENOENT; } - size = resource_size(wdt_mem); - if (!request_mem_region(wdt_mem->start, size, pdev->name)) { + size = resource_size(res); + wdt_mem = request_mem_region(res->start, size, pdev->name); + + if (wdt_mem == NULL) { dev_err(dev, "failed to get memory region\n"); return -ENOENT; } - wdt_base = ioremap(wdt_mem->start, size); + wdt_base = ioremap(res->start, size); if (!wdt_base) { dev_err(dev, "failed to map memory region\n"); ret = -ENOMEM; @@ -323,8 +326,8 @@ static int __devinit max63xx_wdt_probe(struct platform_device *pdev) out_unmap: iounmap(wdt_base); out_request: - release_mem_region(wdt_mem->start, size); - wdt_mem = NULL; + release_resource(wdt_mem); + kfree(wdt_mem); return ret; } @@ -333,7 +336,8 @@ static int __devexit max63xx_wdt_remove(struct platform_device *pdev) { misc_deregister(&max63xx_wdt_miscdev); if (wdt_mem) { - release_mem_region(wdt_mem->start, resource_size(wdt_mem)); + release_resource(wdt_mem); + kfree(wdt_mem); wdt_mem = NULL; } diff --git a/trunk/drivers/watchdog/nv_tco.c b/trunk/drivers/watchdog/nv_tco.c index afa78a54711e..267377a5a83e 100644 --- a/trunk/drivers/watchdog/nv_tco.c +++ b/trunk/drivers/watchdog/nv_tco.c @@ -302,7 +302,7 @@ MODULE_DEVICE_TABLE(pci, tco_pci_tbl); * Init & exit routines */ -static unsigned char __devinit nv_tco_getdevice(void) +static unsigned char __init nv_tco_getdevice(void) { struct pci_dev *dev = NULL; u32 val; diff --git a/trunk/drivers/watchdog/pnx4008_wdt.c b/trunk/drivers/watchdog/pnx4008_wdt.c index 614933225560..c7cf4cbf8ab3 100644 --- a/trunk/drivers/watchdog/pnx4008_wdt.c +++ b/trunk/drivers/watchdog/pnx4008_wdt.c @@ -254,6 +254,7 @@ static struct miscdevice pnx4008_wdt_miscdev = { static int __devinit pnx4008_wdt_probe(struct platform_device *pdev) { int ret = 0, size; + struct resource *res; if (heartbeat < 1 || heartbeat > MAX_HEARTBEAT) heartbeat = DEFAULT_HEARTBEAT; @@ -261,42 +262,42 @@ static int __devinit pnx4008_wdt_probe(struct platform_device *pdev) printk(KERN_INFO MODULE_NAME "PNX4008 Watchdog Timer: heartbeat %d sec\n", heartbeat); - wdt_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (wdt_mem == NULL) { + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (res == NULL) { printk(KERN_INFO MODULE_NAME "failed to get memory region resouce\n"); return -ENOENT; } - size = resource_size(wdt_mem); + size = resource_size(res); + wdt_mem = request_mem_region(res->start, size, pdev->name); - if (!request_mem_region(wdt_mem->start, size, pdev->name)) { + if (wdt_mem == NULL) { printk(KERN_INFO MODULE_NAME "failed to get memory region\n"); return -ENOENT; } - wdt_base = (void __iomem *)IO_ADDRESS(wdt_mem->start); + wdt_base = (void __iomem *)IO_ADDRESS(res->start); wdt_clk = clk_get(&pdev->dev, NULL); if (IS_ERR(wdt_clk)) { ret = PTR_ERR(wdt_clk); - release_mem_region(wdt_mem->start, size); - wdt_mem = NULL; + release_resource(wdt_mem); + kfree(wdt_mem); goto out; } ret = clk_enable(wdt_clk); if (ret) { - release_mem_region(wdt_mem->start, size); - wdt_mem = NULL; - clk_put(wdt_clk); + release_resource(wdt_mem); + kfree(wdt_mem); goto out; } ret = misc_register(&pnx4008_wdt_miscdev); if (ret < 0) { printk(KERN_ERR MODULE_NAME "cannot register misc device\n"); - release_mem_region(wdt_mem->start, size); - wdt_mem = NULL; + release_resource(wdt_mem); + kfree(wdt_mem); clk_disable(wdt_clk); clk_put(wdt_clk); } else { @@ -319,7 +320,8 @@ static int __devexit pnx4008_wdt_remove(struct platform_device *pdev) clk_put(wdt_clk); if (wdt_mem) { - release_mem_region(wdt_mem->start, resource_size(wdt_mem)); + release_resource(wdt_mem); + kfree(wdt_mem); wdt_mem = NULL; } return 0; diff --git a/trunk/drivers/watchdog/s3c2410_wdt.c b/trunk/drivers/watchdog/s3c2410_wdt.c index f7f5aa00df60..25b39bf35925 100644 --- a/trunk/drivers/watchdog/s3c2410_wdt.c +++ b/trunk/drivers/watchdog/s3c2410_wdt.c @@ -402,6 +402,7 @@ static inline void s3c2410wdt_cpufreq_deregister(void) static int __devinit s3c2410wdt_probe(struct platform_device *pdev) { + struct resource *res; struct device *dev; unsigned int wtcon; int started = 0; @@ -415,19 +416,20 @@ static int __devinit s3c2410wdt_probe(struct platform_device *pdev) /* get the memory region for the watchdog timer */ - wdt_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (wdt_mem == NULL) { + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (res == NULL) { dev_err(dev, "no memory resource specified\n"); return -ENOENT; } - size = resource_size(wdt_mem); - if (!request_mem_region(wdt_mem->start, size, pdev->name)) { + size = resource_size(res); + wdt_mem = request_mem_region(res->start, size, pdev->name); + if (wdt_mem == NULL) { dev_err(dev, "failed to get memory region\n"); return -EBUSY; } - wdt_base = ioremap(wdt_mem->start, size); + wdt_base = ioremap(res->start, size); if (wdt_base == NULL) { dev_err(dev, "failed to ioremap() region\n"); ret = -EINVAL; @@ -522,8 +524,8 @@ static int __devinit s3c2410wdt_probe(struct platform_device *pdev) iounmap(wdt_base); err_req: - release_mem_region(wdt_mem->start, size); - wdt_mem = NULL; + release_resource(wdt_mem); + kfree(wdt_mem); return ret; } @@ -543,7 +545,8 @@ static int __devexit s3c2410wdt_remove(struct platform_device *dev) iounmap(wdt_base); - release_mem_region(wdt_mem->start, resource_size(wdt_mem)); + release_resource(wdt_mem); + kfree(wdt_mem); wdt_mem = NULL; return 0; } diff --git a/trunk/drivers/watchdog/softdog.c b/trunk/drivers/watchdog/softdog.c index bf16ffb4d21e..100b114e3c3c 100644 --- a/trunk/drivers/watchdog/softdog.c +++ b/trunk/drivers/watchdog/softdog.c @@ -48,7 +48,6 @@ #include #include #include -#include #define PFX "SoftDog: " @@ -76,11 +75,6 @@ MODULE_PARM_DESC(soft_noboot, "Softdog action, set to 1 to ignore reboots, 0 to reboot " "(default depends on ONLY_TESTING)"); -static int soft_panic; -module_param(soft_panic, int, 0); -MODULE_PARM_DESC(soft_panic, - "Softdog action, set to 1 to panic, 0 to reboot (default=0)"); - /* * Our timer */ @@ -104,10 +98,7 @@ static void watchdog_fire(unsigned long data) if (soft_noboot) printk(KERN_CRIT PFX "Triggered - Reboot ignored.\n"); - else if (soft_panic) { - printk(KERN_CRIT PFX "Initiating panic.\n"); - panic("Software Watchdog Timer expired."); - } else { + else { printk(KERN_CRIT PFX "Initiating system reboot.\n"); emergency_restart(); printk(KERN_CRIT PFX "Reboot didn't ?????\n"); @@ -276,8 +267,7 @@ static struct notifier_block softdog_notifier = { }; static char banner[] __initdata = KERN_INFO "Software Watchdog Timer: 0.07 " - "initialized. soft_noboot=%d soft_margin=%d sec soft_panic=%d " - "(nowayout= %d)\n"; + "initialized. soft_noboot=%d soft_margin=%d sec (nowayout= %d)\n"; static int __init watchdog_init(void) { @@ -308,7 +298,7 @@ static int __init watchdog_init(void) return ret; } - printk(banner, soft_noboot, soft_margin, soft_panic, nowayout); + printk(banner, soft_noboot, soft_margin, nowayout); return 0; } diff --git a/trunk/drivers/watchdog/sp5100_tco.c b/trunk/drivers/watchdog/sp5100_tco.c index 87e0527669d8..1bc493848ed4 100644 --- a/trunk/drivers/watchdog/sp5100_tco.c +++ b/trunk/drivers/watchdog/sp5100_tco.c @@ -42,7 +42,6 @@ #define PFX TCO_MODULE_NAME ": " /* internal variables */ -static u32 tcobase_phys; static void __iomem *tcobase; static unsigned int pm_iobase; static DEFINE_SPINLOCK(tco_lock); /* Guards the hardware */ @@ -306,18 +305,10 @@ static unsigned char __devinit sp5100_tco_setupdevice(void) /* Low three bits of BASE0 are reserved. */ val = val << 8 | (inb(SP5100_IO_PM_DATA_REG) & 0xf8); - if (!request_mem_region_exclusive(val, SP5100_WDT_MEM_MAP_SIZE, - "SP5100 TCO")) { - printk(KERN_ERR PFX "mmio address 0x%04x already in use\n", - val); - goto unreg_region; - } - tcobase_phys = val; - tcobase = ioremap(val, SP5100_WDT_MEM_MAP_SIZE); if (tcobase == 0) { printk(KERN_ERR PFX "failed to get tcobase address\n"); - goto unreg_mem_region; + goto unreg_region; } /* Enable watchdog decode bit */ @@ -355,8 +346,7 @@ static unsigned char __devinit sp5100_tco_setupdevice(void) /* Done */ return 1; -unreg_mem_region: - release_mem_region(tcobase_phys, SP5100_WDT_MEM_MAP_SIZE); + iounmap(tcobase); unreg_region: release_region(pm_iobase, SP5100_PM_IOPORTS_SIZE); exit: @@ -411,7 +401,6 @@ static int __devinit sp5100_tco_init(struct platform_device *dev) exit: iounmap(tcobase); - release_mem_region(tcobase_phys, SP5100_WDT_MEM_MAP_SIZE); release_region(pm_iobase, SP5100_PM_IOPORTS_SIZE); return ret; } @@ -425,7 +414,6 @@ static void __devexit sp5100_tco_cleanup(void) /* Deregister */ misc_deregister(&sp5100_tco_miscdev); iounmap(tcobase); - release_mem_region(tcobase_phys, SP5100_WDT_MEM_MAP_SIZE); release_region(pm_iobase, SP5100_PM_IOPORTS_SIZE); } diff --git a/trunk/drivers/xen/events.c b/trunk/drivers/xen/events.c index 036343ba204e..02b5a9c05cfa 100644 --- a/trunk/drivers/xen/events.c +++ b/trunk/drivers/xen/events.c @@ -122,7 +122,7 @@ static struct irq_chip xen_pirq_chip; /* Get info for IRQ */ static struct irq_info *info_for_irq(unsigned irq) { - return irq_get_handler_data(irq); + return get_irq_data(irq); } /* Constructors for packed IRQ information. */ @@ -403,7 +403,7 @@ static void xen_irq_init(unsigned irq) info->type = IRQT_UNBOUND; - irq_set_handler_data(irq, info); + set_irq_data(irq, info); list_add_tail(&info->list, &xen_irq_list_head); } @@ -458,11 +458,11 @@ static int __must_check xen_allocate_irq_gsi(unsigned gsi) static void xen_free_irq(unsigned irq) { - struct irq_info *info = irq_get_handler_data(irq); + struct irq_info *info = get_irq_data(irq); list_del(&info->list); - irq_set_handler_data(irq, NULL); + set_irq_data(irq, NULL); kfree(info); @@ -585,7 +585,7 @@ static void ack_pirq(struct irq_data *data) { int evtchn = evtchn_from_irq(data->irq); - irq_move_irq(data); + move_native_irq(data->irq); if (VALID_EVTCHN(evtchn)) { mask_evtchn(evtchn); @@ -639,8 +639,8 @@ int xen_bind_pirq_gsi_to_irq(unsigned gsi, if (irq < 0) goto out; - irq_set_chip_and_handler_name(irq, &xen_pirq_chip, handle_level_irq, - name); + set_irq_chip_and_handler_name(irq, &xen_pirq_chip, + handle_level_irq, name); irq_op.irq = irq; irq_op.vector = 0; @@ -690,8 +690,8 @@ int xen_bind_pirq_msi_to_irq(struct pci_dev *dev, struct msi_desc *msidesc, if (irq == -1) goto out; - irq_set_chip_and_handler_name(irq, &xen_pirq_chip, handle_level_irq, - name); + set_irq_chip_and_handler_name(irq, &xen_pirq_chip, + handle_level_irq, name); xen_irq_info_pirq_init(irq, 0, pirq, 0, vector, 0); ret = irq_set_msi_desc(irq, msidesc); @@ -772,7 +772,7 @@ int bind_evtchn_to_irq(unsigned int evtchn) if (irq == -1) goto out; - irq_set_chip_and_handler_name(irq, &xen_dynamic_chip, + set_irq_chip_and_handler_name(irq, &xen_dynamic_chip, handle_fasteoi_irq, "event"); xen_irq_info_evtchn_init(irq, evtchn); @@ -799,7 +799,7 @@ static int bind_ipi_to_irq(unsigned int ipi, unsigned int cpu) if (irq < 0) goto out; - irq_set_chip_and_handler_name(irq, &xen_percpu_chip, + set_irq_chip_and_handler_name(irq, &xen_percpu_chip, handle_percpu_irq, "ipi"); bind_ipi.vcpu = cpu; @@ -848,7 +848,7 @@ int bind_virq_to_irq(unsigned int virq, unsigned int cpu) if (irq == -1) goto out; - irq_set_chip_and_handler_name(irq, &xen_percpu_chip, + set_irq_chip_and_handler_name(irq, &xen_percpu_chip, handle_percpu_irq, "virq"); bind_virq.virq = virq; @@ -1339,7 +1339,7 @@ static void ack_dynirq(struct irq_data *data) { int evtchn = evtchn_from_irq(data->irq); - irq_move_masked_irq(data); + move_masked_irq(data->irq); if (VALID_EVTCHN(evtchn)) unmask_evtchn(evtchn); diff --git a/trunk/drivers/xen/gntdev.c b/trunk/drivers/xen/gntdev.c index b0f9e8fb0052..017ce600fbc6 100644 --- a/trunk/drivers/xen/gntdev.c +++ b/trunk/drivers/xen/gntdev.c @@ -273,7 +273,7 @@ static int __unmap_grant_pages(struct grant_map *map, int offset, int pages) map->vma->vm_start + map->notify.addr; err = copy_to_user(tmp, &err, 1); if (err) - return -EFAULT; + return err; map->notify.flags &= ~UNMAP_NOTIFY_CLEAR_BYTE; } else if (pgno >= offset && pgno < offset + pages) { uint8_t *tmp = kmap(map->pages[pgno]); @@ -662,7 +662,7 @@ static int gntdev_mmap(struct file *flip, struct vm_area_struct *vma) if (map->flags) { if ((vma->vm_flags & VM_WRITE) && (map->flags & GNTMAP_readonly)) - goto out_unlock_put; + return -EINVAL; } else { map->flags = GNTMAP_host_map; if (!(vma->vm_flags & VM_WRITE)) @@ -700,8 +700,6 @@ static int gntdev_mmap(struct file *flip, struct vm_area_struct *vma) spin_unlock(&priv->lock); return err; -out_unlock_put: - spin_unlock(&priv->lock); out_put_map: if (use_ptemod) map->vma = NULL; diff --git a/trunk/fs/btrfs/btrfs_inode.h b/trunk/fs/btrfs/btrfs_inode.h index 57c3bb2884ce..ccc991c542df 100644 --- a/trunk/fs/btrfs/btrfs_inode.h +++ b/trunk/fs/btrfs/btrfs_inode.h @@ -136,8 +136,9 @@ struct btrfs_inode { * items we think we'll end up using, and reserved_extents is the number * of extent items we've reserved metadata for. */ + spinlock_t accounting_lock; atomic_t outstanding_extents; - atomic_t reserved_extents; + int reserved_extents; /* * ordered_data_close is set by truncate when a file that used diff --git a/trunk/fs/btrfs/compression.c b/trunk/fs/btrfs/compression.c index 41d1d7c70e29..4d2110eafe29 100644 --- a/trunk/fs/btrfs/compression.c +++ b/trunk/fs/btrfs/compression.c @@ -340,8 +340,6 @@ int btrfs_submit_compressed_write(struct inode *inode, u64 start, WARN_ON(start & ((u64)PAGE_CACHE_SIZE - 1)); cb = kmalloc(compressed_bio_size(root, compressed_len), GFP_NOFS); - if (!cb) - return -ENOMEM; atomic_set(&cb->pending_bios, 0); cb->errors = 0; cb->inode = inode; @@ -356,10 +354,6 @@ int btrfs_submit_compressed_write(struct inode *inode, u64 start, bdev = BTRFS_I(inode)->root->fs_info->fs_devices->latest_bdev; bio = compressed_bio_alloc(bdev, first_byte, GFP_NOFS); - if(!bio) { - kfree(cb); - return -ENOMEM; - } bio->bi_private = cb; bio->bi_end_io = end_compressed_bio_write; atomic_inc(&cb->pending_bios); @@ -663,9 +657,8 @@ int btrfs_submit_compressed_read(struct inode *inode, struct bio *bio, atomic_inc(&cb->pending_bios); if (!(BTRFS_I(inode)->flags & BTRFS_INODE_NODATASUM)) { - ret = btrfs_lookup_bio_sums(root, inode, - comp_bio, sums); - BUG_ON(ret); + btrfs_lookup_bio_sums(root, inode, comp_bio, + sums); } sums += (comp_bio->bi_size + root->sectorsize - 1) / root->sectorsize; @@ -690,10 +683,8 @@ int btrfs_submit_compressed_read(struct inode *inode, struct bio *bio, ret = btrfs_bio_wq_end_io(root->fs_info, comp_bio, 0); BUG_ON(ret); - if (!(BTRFS_I(inode)->flags & BTRFS_INODE_NODATASUM)) { - ret = btrfs_lookup_bio_sums(root, inode, comp_bio, sums); - BUG_ON(ret); - } + if (!(BTRFS_I(inode)->flags & BTRFS_INODE_NODATASUM)) + btrfs_lookup_bio_sums(root, inode, comp_bio, sums); ret = btrfs_map_bio(root, READ, comp_bio, mirror_num, 0); BUG_ON(ret); diff --git a/trunk/fs/btrfs/ctree.c b/trunk/fs/btrfs/ctree.c index 84d7ca1fe0ba..b5baff0dccfe 100644 --- a/trunk/fs/btrfs/ctree.c +++ b/trunk/fs/btrfs/ctree.c @@ -147,11 +147,10 @@ noinline void btrfs_release_path(struct btrfs_root *root, struct btrfs_path *p) struct extent_buffer *btrfs_root_node(struct btrfs_root *root) { struct extent_buffer *eb; - - rcu_read_lock(); - eb = rcu_dereference(root->node); + spin_lock(&root->node_lock); + eb = root->node; extent_buffer_get(eb); - rcu_read_unlock(); + spin_unlock(&root->node_lock); return eb; } @@ -166,8 +165,14 @@ struct extent_buffer *btrfs_lock_root_node(struct btrfs_root *root) while (1) { eb = btrfs_root_node(root); btrfs_tree_lock(eb); - if (eb == root->node) + + spin_lock(&root->node_lock); + if (eb == root->node) { + spin_unlock(&root->node_lock); break; + } + spin_unlock(&root->node_lock); + btrfs_tree_unlock(eb); free_extent_buffer(eb); } @@ -453,8 +458,10 @@ static noinline int __btrfs_cow_block(struct btrfs_trans_handle *trans, else parent_start = 0; + spin_lock(&root->node_lock); + root->node = cow; extent_buffer_get(cow); - rcu_assign_pointer(root->node, cow); + spin_unlock(&root->node_lock); btrfs_free_tree_block(trans, root, buf, parent_start, last_ref); @@ -535,9 +542,6 @@ noinline int btrfs_cow_block(struct btrfs_trans_handle *trans, ret = __btrfs_cow_block(trans, root, buf, parent, parent_slot, cow_ret, search_start, 0); - - trace_btrfs_cow_block(root, buf, *cow_ret); - return ret; } @@ -682,8 +686,6 @@ int btrfs_realloc_node(struct btrfs_trans_handle *trans, if (!cur) { cur = read_tree_block(root, blocknr, blocksize, gen); - if (!cur) - return -EIO; } else if (!uptodate) { btrfs_read_buffer(cur, gen); } @@ -730,6 +732,122 @@ static inline unsigned int leaf_data_end(struct btrfs_root *root, return btrfs_item_offset_nr(leaf, nr - 1); } +/* + * extra debugging checks to make sure all the items in a key are + * well formed and in the proper order + */ +static int check_node(struct btrfs_root *root, struct btrfs_path *path, + int level) +{ + struct extent_buffer *parent = NULL; + struct extent_buffer *node = path->nodes[level]; + struct btrfs_disk_key parent_key; + struct btrfs_disk_key node_key; + int parent_slot; + int slot; + struct btrfs_key cpukey; + u32 nritems = btrfs_header_nritems(node); + + if (path->nodes[level + 1]) + parent = path->nodes[level + 1]; + + slot = path->slots[level]; + BUG_ON(nritems == 0); + if (parent) { + parent_slot = path->slots[level + 1]; + btrfs_node_key(parent, &parent_key, parent_slot); + btrfs_node_key(node, &node_key, 0); + BUG_ON(memcmp(&parent_key, &node_key, + sizeof(struct btrfs_disk_key))); + BUG_ON(btrfs_node_blockptr(parent, parent_slot) != + btrfs_header_bytenr(node)); + } + BUG_ON(nritems > BTRFS_NODEPTRS_PER_BLOCK(root)); + if (slot != 0) { + btrfs_node_key_to_cpu(node, &cpukey, slot - 1); + btrfs_node_key(node, &node_key, slot); + BUG_ON(comp_keys(&node_key, &cpukey) <= 0); + } + if (slot < nritems - 1) { + btrfs_node_key_to_cpu(node, &cpukey, slot + 1); + btrfs_node_key(node, &node_key, slot); + BUG_ON(comp_keys(&node_key, &cpukey) >= 0); + } + return 0; +} + +/* + * extra checking to make sure all the items in a leaf are + * well formed and in the proper order + */ +static int check_leaf(struct btrfs_root *root, struct btrfs_path *path, + int level) +{ + struct extent_buffer *leaf = path->nodes[level]; + struct extent_buffer *parent = NULL; + int parent_slot; + struct btrfs_key cpukey; + struct btrfs_disk_key parent_key; + struct btrfs_disk_key leaf_key; + int slot = path->slots[0]; + + u32 nritems = btrfs_header_nritems(leaf); + + if (path->nodes[level + 1]) + parent = path->nodes[level + 1]; + + if (nritems == 0) + return 0; + + if (parent) { + parent_slot = path->slots[level + 1]; + btrfs_node_key(parent, &parent_key, parent_slot); + btrfs_item_key(leaf, &leaf_key, 0); + + BUG_ON(memcmp(&parent_key, &leaf_key, + sizeof(struct btrfs_disk_key))); + BUG_ON(btrfs_node_blockptr(parent, parent_slot) != + btrfs_header_bytenr(leaf)); + } + if (slot != 0 && slot < nritems - 1) { + btrfs_item_key(leaf, &leaf_key, slot); + btrfs_item_key_to_cpu(leaf, &cpukey, slot - 1); + if (comp_keys(&leaf_key, &cpukey) <= 0) { + btrfs_print_leaf(root, leaf); + printk(KERN_CRIT "slot %d offset bad key\n", slot); + BUG_ON(1); + } + if (btrfs_item_offset_nr(leaf, slot - 1) != + btrfs_item_end_nr(leaf, slot)) { + btrfs_print_leaf(root, leaf); + printk(KERN_CRIT "slot %d offset bad\n", slot); + BUG_ON(1); + } + } + if (slot < nritems - 1) { + btrfs_item_key(leaf, &leaf_key, slot); + btrfs_item_key_to_cpu(leaf, &cpukey, slot + 1); + BUG_ON(comp_keys(&leaf_key, &cpukey) >= 0); + if (btrfs_item_offset_nr(leaf, slot) != + btrfs_item_end_nr(leaf, slot + 1)) { + btrfs_print_leaf(root, leaf); + printk(KERN_CRIT "slot %d offset bad\n", slot); + BUG_ON(1); + } + } + BUG_ON(btrfs_item_offset_nr(leaf, 0) + + btrfs_item_size_nr(leaf, 0) != BTRFS_LEAF_DATA_SIZE(root)); + return 0; +} + +static noinline int check_block(struct btrfs_root *root, + struct btrfs_path *path, int level) +{ + return 0; + if (level == 0) + return check_leaf(root, path, level); + return check_node(root, path, level); +} /* * search for key in the extent_buffer. The items start at offset p, @@ -928,7 +1046,9 @@ static noinline int balance_level(struct btrfs_trans_handle *trans, goto enospc; } - rcu_assign_pointer(root->node, child); + spin_lock(&root->node_lock); + root->node = child; + spin_unlock(&root->node_lock); add_root_to_dirty_list(root); btrfs_tree_unlock(child); @@ -1068,6 +1188,7 @@ static noinline int balance_level(struct btrfs_trans_handle *trans, } } /* double check we haven't messed things up */ + check_block(root, path, level); if (orig_ptr != btrfs_node_blockptr(path->nodes[level], path->slots[level])) BUG(); @@ -1677,6 +1798,12 @@ int btrfs_search_slot(struct btrfs_trans_handle *trans, struct btrfs_root if (!cow) btrfs_unlock_up_safe(p, level + 1); + ret = check_block(root, p, level); + if (ret) { + ret = -1; + goto done; + } + ret = bin_search(b, key, level, &slot); if (level != 0) { @@ -2003,8 +2130,10 @@ static noinline int insert_new_root(struct btrfs_trans_handle *trans, btrfs_mark_buffer_dirty(c); + spin_lock(&root->node_lock); old = root->node; - rcu_assign_pointer(root->node, c); + root->node = c; + spin_unlock(&root->node_lock); /* the super has an extra ref to root->node */ free_extent_buffer(old); @@ -3711,8 +3840,7 @@ int btrfs_insert_item(struct btrfs_trans_handle *trans, struct btrfs_root unsigned long ptr; path = btrfs_alloc_path(); - if (!path) - return -ENOMEM; + BUG_ON(!path); ret = btrfs_insert_empty_item(trans, root, path, cpu_key, data_size); if (!ret) { leaf = path->nodes[0]; @@ -4089,7 +4217,6 @@ int btrfs_search_forward(struct btrfs_root *root, struct btrfs_key *min_key, } btrfs_set_path_blocking(path); cur = read_node_slot(root, cur, slot); - BUG_ON(!cur); btrfs_tree_lock(cur); diff --git a/trunk/fs/btrfs/ctree.h b/trunk/fs/btrfs/ctree.h index d47ce8307854..7f78cc78fdd0 100644 --- a/trunk/fs/btrfs/ctree.h +++ b/trunk/fs/btrfs/ctree.h @@ -28,7 +28,6 @@ #include #include #include -#include #include #include "extent_io.h" #include "extent_map.h" @@ -41,7 +40,6 @@ extern struct kmem_cache *btrfs_trans_handle_cachep; extern struct kmem_cache *btrfs_transaction_cachep; extern struct kmem_cache *btrfs_bit_radix_cachep; extern struct kmem_cache *btrfs_path_cachep; -extern struct kmem_cache *btrfs_free_space_cachep; struct btrfs_ordered_sum; #define BTRFS_MAGIC "_BHRfS_M" @@ -784,6 +782,9 @@ struct btrfs_free_cluster { /* first extent starting offset */ u64 window_start; + /* if this cluster simply points at a bitmap in the block group */ + bool points_to_bitmap; + struct btrfs_block_group_cache *block_group; /* * when a cluster is allocated from a block group, we put the @@ -1282,7 +1283,6 @@ struct btrfs_root { #define BTRFS_INODE_NODUMP (1 << 8) #define BTRFS_INODE_NOATIME (1 << 9) #define BTRFS_INODE_DIRSYNC (1 << 10) -#define BTRFS_INODE_COMPRESS (1 << 11) /* some macros to generate set/get funcs for the struct fields. This * assumes there is a lefoo_to_cpu for every type, so lets make a simple @@ -2157,8 +2157,6 @@ int btrfs_free_extent(struct btrfs_trans_handle *trans, u64 root_objectid, u64 owner, u64 offset); int btrfs_free_reserved_extent(struct btrfs_root *root, u64 start, u64 len); -int btrfs_update_reserved_bytes(struct btrfs_block_group_cache *cache, - u64 num_bytes, int reserve, int sinfo); int btrfs_prepare_extent_commit(struct btrfs_trans_handle *trans, struct btrfs_root *root); int btrfs_finish_extent_commit(struct btrfs_trans_handle *trans, @@ -2229,12 +2227,10 @@ u64 btrfs_account_ro_block_groups_free_space(struct btrfs_space_info *sinfo); int btrfs_error_unpin_extent_range(struct btrfs_root *root, u64 start, u64 end); int btrfs_error_discard_extent(struct btrfs_root *root, u64 bytenr, - u64 num_bytes, u64 *actual_bytes); + u64 num_bytes); int btrfs_force_chunk_alloc(struct btrfs_trans_handle *trans, struct btrfs_root *root, u64 type); -int btrfs_trim_fs(struct btrfs_root *root, struct fstrim_range *range); -int btrfs_init_space_info(struct btrfs_fs_info *fs_info); /* ctree.c */ int btrfs_bin_search(struct extent_buffer *eb, struct btrfs_key *key, int level, int *slot); @@ -2396,9 +2392,6 @@ struct btrfs_dir_item *btrfs_lookup_xattr(struct btrfs_trans_handle *trans, struct btrfs_path *path, u64 dir, const char *name, u16 name_len, int mod); -int verify_dir_item(struct btrfs_root *root, - struct extent_buffer *leaf, - struct btrfs_dir_item *dir_item); /* orphan.c */ int btrfs_insert_orphan_item(struct btrfs_trans_handle *trans, @@ -2535,7 +2528,7 @@ int btrfs_update_inode(struct btrfs_trans_handle *trans, struct inode *inode); int btrfs_orphan_add(struct btrfs_trans_handle *trans, struct inode *inode); int btrfs_orphan_del(struct btrfs_trans_handle *trans, struct inode *inode); -int btrfs_orphan_cleanup(struct btrfs_root *root); +void btrfs_orphan_cleanup(struct btrfs_root *root); void btrfs_orphan_pre_snapshot(struct btrfs_trans_handle *trans, struct btrfs_pending_snapshot *pending, u64 *bytes_to_reserve); @@ -2543,7 +2536,7 @@ void btrfs_orphan_post_snapshot(struct btrfs_trans_handle *trans, struct btrfs_pending_snapshot *pending); void btrfs_orphan_commit_root(struct btrfs_trans_handle *trans, struct btrfs_root *root); -int btrfs_cont_expand(struct inode *inode, loff_t oldsize, loff_t size); +int btrfs_cont_expand(struct inode *inode, loff_t size); int btrfs_invalidate_inodes(struct btrfs_root *root); void btrfs_add_delayed_iput(struct inode *inode); void btrfs_run_delayed_iputs(struct btrfs_root *root); diff --git a/trunk/fs/btrfs/delayed-ref.c b/trunk/fs/btrfs/delayed-ref.c index bce28f653899..e807b143b857 100644 --- a/trunk/fs/btrfs/delayed-ref.c +++ b/trunk/fs/btrfs/delayed-ref.c @@ -483,8 +483,6 @@ static noinline int add_delayed_ref_head(struct btrfs_trans_handle *trans, INIT_LIST_HEAD(&head_ref->cluster); mutex_init(&head_ref->mutex); - trace_btrfs_delayed_ref_head(ref, head_ref, action); - existing = tree_insert(&delayed_refs->root, &ref->rb_node); if (existing) { @@ -539,8 +537,6 @@ static noinline int add_delayed_tree_ref(struct btrfs_trans_handle *trans, } full_ref->level = level; - trace_btrfs_delayed_tree_ref(ref, full_ref, action); - existing = tree_insert(&delayed_refs->root, &ref->rb_node); if (existing) { @@ -595,8 +591,6 @@ static noinline int add_delayed_data_ref(struct btrfs_trans_handle *trans, full_ref->objectid = owner; full_ref->offset = offset; - trace_btrfs_delayed_data_ref(ref, full_ref, action); - existing = tree_insert(&delayed_refs->root, &ref->rb_node); if (existing) { diff --git a/trunk/fs/btrfs/dir-item.c b/trunk/fs/btrfs/dir-item.c index c62f02f6ae69..f0cad5ae5be7 100644 --- a/trunk/fs/btrfs/dir-item.c +++ b/trunk/fs/btrfs/dir-item.c @@ -151,7 +151,7 @@ int btrfs_insert_dir_item(struct btrfs_trans_handle *trans, struct btrfs_root ret = PTR_ERR(dir_item); if (ret == -EEXIST) goto second_insert; - goto out_free; + goto out; } leaf = path->nodes[0]; @@ -170,7 +170,7 @@ int btrfs_insert_dir_item(struct btrfs_trans_handle *trans, struct btrfs_root /* FIXME, use some real flag for selecting the extra index */ if (root == root->fs_info->tree_root) { ret = 0; - goto out_free; + goto out; } btrfs_release_path(root, path); @@ -180,7 +180,7 @@ int btrfs_insert_dir_item(struct btrfs_trans_handle *trans, struct btrfs_root name, name_len); if (IS_ERR(dir_item)) { ret2 = PTR_ERR(dir_item); - goto out_free; + goto out; } leaf = path->nodes[0]; btrfs_cpu_key_to_disk(&disk_key, location); @@ -192,9 +192,7 @@ int btrfs_insert_dir_item(struct btrfs_trans_handle *trans, struct btrfs_root name_ptr = (unsigned long)(dir_item + 1); write_extent_buffer(leaf, name, name_ptr, name_len); btrfs_mark_buffer_dirty(leaf); - -out_free: - +out: btrfs_free_path(path); if (ret) return ret; @@ -379,9 +377,6 @@ struct btrfs_dir_item *btrfs_match_dir_item_name(struct btrfs_root *root, leaf = path->nodes[0]; dir_item = btrfs_item_ptr(leaf, path->slots[0], struct btrfs_dir_item); - if (verify_dir_item(root, leaf, dir_item)) - return NULL; - total_len = btrfs_item_size_nr(leaf, path->slots[0]); while (cur < total_len) { this_len = sizeof(*dir_item) + @@ -434,35 +429,3 @@ int btrfs_delete_one_dir_name(struct btrfs_trans_handle *trans, } return ret; } - -int verify_dir_item(struct btrfs_root *root, - struct extent_buffer *leaf, - struct btrfs_dir_item *dir_item) -{ - u16 namelen = BTRFS_NAME_LEN; - u8 type = btrfs_dir_type(leaf, dir_item); - - if (type >= BTRFS_FT_MAX) { - printk(KERN_CRIT "btrfs: invalid dir item type: %d\n", - (int)type); - return 1; - } - - if (type == BTRFS_FT_XATTR) - namelen = XATTR_NAME_MAX; - - if (btrfs_dir_name_len(leaf, dir_item) > namelen) { - printk(KERN_CRIT "btrfS: invalid dir item name len: %u\n", - (unsigned)btrfs_dir_data_len(leaf, dir_item)); - return 1; - } - - /* BTRFS_MAX_XATTR_SIZE is the same for all dir items */ - if (btrfs_dir_data_len(leaf, dir_item) > BTRFS_MAX_XATTR_SIZE(root)) { - printk(KERN_CRIT "btrfs: invalid dir item data len: %u\n", - (unsigned)btrfs_dir_data_len(leaf, dir_item)); - return 1; - } - - return 0; -} diff --git a/trunk/fs/btrfs/disk-io.c b/trunk/fs/btrfs/disk-io.c index d7a7315bd031..830d261d0e6b 100644 --- a/trunk/fs/btrfs/disk-io.c +++ b/trunk/fs/btrfs/disk-io.c @@ -29,7 +29,6 @@ #include #include #include -#include #include "compat.h" #include "ctree.h" #include "disk-io.h" @@ -199,7 +198,7 @@ u32 btrfs_csum_data(struct btrfs_root *root, char *data, u32 seed, size_t len) void btrfs_csum_final(u32 crc, char *result) { - put_unaligned_le32(~crc, result); + *(__le32 *)result = ~cpu_to_le32(crc); } /* @@ -324,7 +323,6 @@ static int btree_read_extent_buffer_pages(struct btrfs_root *root, int num_copies = 0; int mirror_num = 0; - clear_bit(EXTENT_BUFFER_CORRUPT, &eb->bflags); io_tree = &BTRFS_I(root->fs_info->btree_inode)->io_tree; while (1) { ret = read_extent_buffer_pages(io_tree, eb, start, 1, @@ -333,14 +331,6 @@ static int btree_read_extent_buffer_pages(struct btrfs_root *root, !verify_parent_transid(io_tree, eb, parent_transid)) return ret; - /* - * This buffer's crc is fine, but its contents are corrupted, so - * there is no reason to read the other copies, they won't be - * any less wrong. - */ - if (test_bit(EXTENT_BUFFER_CORRUPT, &eb->bflags)) - return ret; - num_copies = btrfs_num_copies(&root->fs_info->mapping_tree, eb->start, eb->len); if (num_copies == 1) @@ -429,73 +419,6 @@ static int check_tree_block_fsid(struct btrfs_root *root, return ret; } -#define CORRUPT(reason, eb, root, slot) \ - printk(KERN_CRIT "btrfs: corrupt leaf, %s: block=%llu," \ - "root=%llu, slot=%d\n", reason, \ - (unsigned long long)btrfs_header_bytenr(eb), \ - (unsigned long long)root->objectid, slot) - -static noinline int check_leaf(struct btrfs_root *root, - struct extent_buffer *leaf) -{ - struct btrfs_key key; - struct btrfs_key leaf_key; - u32 nritems = btrfs_header_nritems(leaf); - int slot; - - if (nritems == 0) - return 0; - - /* Check the 0 item */ - if (btrfs_item_offset_nr(leaf, 0) + btrfs_item_size_nr(leaf, 0) != - BTRFS_LEAF_DATA_SIZE(root)) { - CORRUPT("invalid item offset size pair", leaf, root, 0); - return -EIO; - } - - /* - * Check to make sure each items keys are in the correct order and their - * offsets make sense. We only have to loop through nritems-1 because - * we check the current slot against the next slot, which verifies the - * next slot's offset+size makes sense and that the current's slot - * offset is correct. - */ - for (slot = 0; slot < nritems - 1; slot++) { - btrfs_item_key_to_cpu(leaf, &leaf_key, slot); - btrfs_item_key_to_cpu(leaf, &key, slot + 1); - - /* Make sure the keys are in the right order */ - if (btrfs_comp_cpu_keys(&leaf_key, &key) >= 0) { - CORRUPT("bad key order", leaf, root, slot); - return -EIO; - } - - /* - * Make sure the offset and ends are right, remember that the - * item data starts at the end of the leaf and grows towards the - * front. - */ - if (btrfs_item_offset_nr(leaf, slot) != - btrfs_item_end_nr(leaf, slot + 1)) { - CORRUPT("slot offset bad", leaf, root, slot); - return -EIO; - } - - /* - * Check to make sure that we don't point outside of the leaf, - * just incase all the items are consistent to eachother, but - * all point outside of the leaf. - */ - if (btrfs_item_end_nr(leaf, slot) > - BTRFS_LEAF_DATA_SIZE(root)) { - CORRUPT("slot end outside of leaf", leaf, root, slot); - return -EIO; - } - } - - return 0; -} - #ifdef CONFIG_DEBUG_LOCK_ALLOC void btrfs_set_buffer_lockdep_class(struct extent_buffer *eb, int level) { @@ -562,20 +485,8 @@ static int btree_readpage_end_io_hook(struct page *page, u64 start, u64 end, btrfs_set_buffer_lockdep_class(eb, found_level); ret = csum_tree_block(root, eb, 1); - if (ret) { - ret = -EIO; - goto err; - } - - /* - * If this is a leaf block and it is corrupt, set the corrupt bit so - * that we don't try and read the other copies of this block, just - * return -EIO. - */ - if (found_level == 0 && check_leaf(root, eb)) { - set_bit(EXTENT_BUFFER_CORRUPT, &eb->bflags); + if (ret) ret = -EIO; - } end = min_t(u64, eb->len, PAGE_CACHE_SIZE); end = eb->start + end - 1; @@ -1248,10 +1159,7 @@ struct btrfs_root *btrfs_read_fs_root_no_radix(struct btrfs_root *tree_root, root, fs_info, location->objectid); path = btrfs_alloc_path(); - if (!path) { - kfree(root); - return ERR_PTR(-ENOMEM); - } + BUG_ON(!path); ret = btrfs_search_slot(NULL, tree_root, location, path, 0, 0); if (ret == 0) { l = path->nodes[0]; @@ -1645,8 +1553,6 @@ struct btrfs_root *open_ctree(struct super_block *sb, goto fail_bdi; } - fs_info->btree_inode->i_mapping->flags &= ~__GFP_FS; - INIT_RADIX_TREE(&fs_info->fs_roots_radix, GFP_ATOMIC); INIT_LIST_HEAD(&fs_info->trans_list); INIT_LIST_HEAD(&fs_info->dead_roots); @@ -1777,12 +1683,6 @@ struct btrfs_root *open_ctree(struct super_block *sb, btrfs_check_super_valid(fs_info, sb->s_flags & MS_RDONLY); - /* - * In the long term, we'll store the compression type in the super - * block, and it'll be used for per file compression control. - */ - fs_info->compress_type = BTRFS_COMPRESS_ZLIB; - ret = btrfs_parse_options(tree_root, options); if (ret) { err = ret; @@ -1988,12 +1888,6 @@ struct btrfs_root *open_ctree(struct super_block *sb, fs_info->metadata_alloc_profile = (u64)-1; fs_info->system_alloc_profile = fs_info->metadata_alloc_profile; - ret = btrfs_init_space_info(fs_info); - if (ret) { - printk(KERN_ERR "Failed to initial space info: %d\n", ret); - goto fail_block_groups; - } - ret = btrfs_read_block_groups(extent_root); if (ret) { printk(KERN_ERR "Failed to read block groups: %d\n", ret); @@ -2085,14 +1979,9 @@ struct btrfs_root *open_ctree(struct super_block *sb, if (!(sb->s_flags & MS_RDONLY)) { down_read(&fs_info->cleanup_work_sem); - err = btrfs_orphan_cleanup(fs_info->fs_root); - if (!err) - err = btrfs_orphan_cleanup(fs_info->tree_root); + btrfs_orphan_cleanup(fs_info->fs_root); + btrfs_orphan_cleanup(fs_info->tree_root); up_read(&fs_info->cleanup_work_sem); - if (err) { - close_ctree(tree_root); - return ERR_PTR(err); - } } return tree_root; @@ -2467,12 +2356,8 @@ int btrfs_cleanup_fs_roots(struct btrfs_fs_info *fs_info) root_objectid = gang[ret - 1]->root_key.objectid + 1; for (i = 0; i < ret; i++) { - int err; - root_objectid = gang[i]->root_key.objectid; - err = btrfs_orphan_cleanup(gang[i]); - if (err) - return err; + btrfs_orphan_cleanup(gang[i]); } root_objectid++; } @@ -2983,10 +2868,7 @@ static int btrfs_destroy_pinned_extent(struct btrfs_root *root, break; /* opt_discard */ - if (btrfs_test_opt(root, DISCARD)) - ret = btrfs_error_discard_extent(root, start, - end + 1 - start, - NULL); + ret = btrfs_error_discard_extent(root, start, end + 1 - start); clear_extent_dirty(unpin, start, end, GFP_NOFS); btrfs_error_unpin_extent_range(root, start, end); diff --git a/trunk/fs/btrfs/extent-tree.c b/trunk/fs/btrfs/extent-tree.c index f619c3cb13b7..7b3089b5c2df 100644 --- a/trunk/fs/btrfs/extent-tree.c +++ b/trunk/fs/btrfs/extent-tree.c @@ -36,6 +36,8 @@ static int update_block_group(struct btrfs_trans_handle *trans, struct btrfs_root *root, u64 bytenr, u64 num_bytes, int alloc); +static int update_reserved_bytes(struct btrfs_block_group_cache *cache, + u64 num_bytes, int reserve, int sinfo); static int __btrfs_free_extent(struct btrfs_trans_handle *trans, struct btrfs_root *root, u64 bytenr, u64 num_bytes, u64 parent, @@ -440,7 +442,7 @@ static int cache_block_group(struct btrfs_block_group_cache *cache, * allocate blocks for the tree root we can't do the fast caching since * we likely hold important locks. */ - if (trans && (!trans->transaction->in_commit) && + if (!trans->transaction->in_commit && (root && root != root->fs_info->tree_root)) { spin_lock(&cache->lock); if (cache->cached != BTRFS_CACHE_NO) { @@ -469,7 +471,7 @@ static int cache_block_group(struct btrfs_block_group_cache *cache, if (load_cache_only) return 0; - caching_ctl = kzalloc(sizeof(*caching_ctl), GFP_NOFS); + caching_ctl = kzalloc(sizeof(*caching_ctl), GFP_KERNEL); BUG_ON(!caching_ctl); INIT_LIST_HEAD(&caching_ctl->list); @@ -1738,45 +1740,39 @@ static int remove_extent_backref(struct btrfs_trans_handle *trans, return ret; } -static int btrfs_issue_discard(struct block_device *bdev, +static void btrfs_issue_discard(struct block_device *bdev, u64 start, u64 len) { - return blkdev_issue_discard(bdev, start >> 9, len >> 9, GFP_NOFS, 0); + blkdev_issue_discard(bdev, start >> 9, len >> 9, GFP_KERNEL, 0); } static int btrfs_discard_extent(struct btrfs_root *root, u64 bytenr, - u64 num_bytes, u64 *actual_bytes) + u64 num_bytes) { int ret; - u64 discarded_bytes = 0; + u64 map_length = num_bytes; struct btrfs_multi_bio *multi = NULL; + if (!btrfs_test_opt(root, DISCARD)) + return 0; /* Tell the block device(s) that the sectors can be discarded */ - ret = btrfs_map_block(&root->fs_info->mapping_tree, REQ_DISCARD, - bytenr, &num_bytes, &multi, 0); + ret = btrfs_map_block(&root->fs_info->mapping_tree, READ, + bytenr, &map_length, &multi, 0); if (!ret) { struct btrfs_bio_stripe *stripe = multi->stripes; int i; + if (map_length > num_bytes) + map_length = num_bytes; for (i = 0; i < multi->num_stripes; i++, stripe++) { - ret = btrfs_issue_discard(stripe->dev->bdev, - stripe->physical, - stripe->length); - if (!ret) - discarded_bytes += stripe->length; - else if (ret != -EOPNOTSUPP) - break; + btrfs_issue_discard(stripe->dev->bdev, + stripe->physical, + map_length); } kfree(multi); } - if (discarded_bytes && ret == -EOPNOTSUPP) - ret = 0; - - if (actual_bytes) - *actual_bytes = discarded_bytes; - return ret; } @@ -4000,7 +3996,6 @@ int btrfs_delalloc_reserve_metadata(struct inode *inode, u64 num_bytes) struct btrfs_block_rsv *block_rsv = &root->fs_info->delalloc_block_rsv; u64 to_reserve; int nr_extents; - int reserved_extents; int ret; if (btrfs_transaction_in_commit(root->fs_info)) @@ -4008,24 +4003,25 @@ int btrfs_delalloc_reserve_metadata(struct inode *inode, u64 num_bytes) num_bytes = ALIGN(num_bytes, root->sectorsize); + spin_lock(&BTRFS_I(inode)->accounting_lock); nr_extents = atomic_read(&BTRFS_I(inode)->outstanding_extents) + 1; - reserved_extents = atomic_read(&BTRFS_I(inode)->reserved_extents); - - if (nr_extents > reserved_extents) { - nr_extents -= reserved_extents; + if (nr_extents > BTRFS_I(inode)->reserved_extents) { + nr_extents -= BTRFS_I(inode)->reserved_extents; to_reserve = calc_trans_metadata_size(root, nr_extents); } else { nr_extents = 0; to_reserve = 0; } - + spin_unlock(&BTRFS_I(inode)->accounting_lock); to_reserve += calc_csum_metadata_size(inode, num_bytes); ret = reserve_metadata_bytes(NULL, root, block_rsv, to_reserve, 1); if (ret) return ret; - atomic_add(nr_extents, &BTRFS_I(inode)->reserved_extents); + spin_lock(&BTRFS_I(inode)->accounting_lock); + BTRFS_I(inode)->reserved_extents += nr_extents; atomic_inc(&BTRFS_I(inode)->outstanding_extents); + spin_unlock(&BTRFS_I(inode)->accounting_lock); block_rsv_add_bytes(block_rsv, to_reserve, 1); @@ -4040,30 +4036,20 @@ void btrfs_delalloc_release_metadata(struct inode *inode, u64 num_bytes) struct btrfs_root *root = BTRFS_I(inode)->root; u64 to_free; int nr_extents; - int reserved_extents; num_bytes = ALIGN(num_bytes, root->sectorsize); atomic_dec(&BTRFS_I(inode)->outstanding_extents); WARN_ON(atomic_read(&BTRFS_I(inode)->outstanding_extents) < 0); - reserved_extents = atomic_read(&BTRFS_I(inode)->reserved_extents); - do { - int old, new; - - nr_extents = atomic_read(&BTRFS_I(inode)->outstanding_extents); - if (nr_extents >= reserved_extents) { - nr_extents = 0; - break; - } - old = reserved_extents; - nr_extents = reserved_extents - nr_extents; - new = reserved_extents - nr_extents; - old = atomic_cmpxchg(&BTRFS_I(inode)->reserved_extents, - reserved_extents, new); - if (likely(old == reserved_extents)) - break; - reserved_extents = old; - } while (1); + spin_lock(&BTRFS_I(inode)->accounting_lock); + nr_extents = atomic_read(&BTRFS_I(inode)->outstanding_extents); + if (nr_extents < BTRFS_I(inode)->reserved_extents) { + nr_extents = BTRFS_I(inode)->reserved_extents - nr_extents; + BTRFS_I(inode)->reserved_extents -= nr_extents; + } else { + nr_extents = 0; + } + spin_unlock(&BTRFS_I(inode)->accounting_lock); to_free = calc_csum_metadata_size(inode, num_bytes); if (nr_extents > 0) @@ -4237,8 +4223,8 @@ int btrfs_pin_extent(struct btrfs_root *root, * update size of reserved extents. this function may return -EAGAIN * if 'reserve' is true or 'sinfo' is false. */ -int btrfs_update_reserved_bytes(struct btrfs_block_group_cache *cache, - u64 num_bytes, int reserve, int sinfo) +static int update_reserved_bytes(struct btrfs_block_group_cache *cache, + u64 num_bytes, int reserve, int sinfo) { int ret = 0; if (sinfo) { @@ -4377,9 +4363,7 @@ int btrfs_finish_extent_commit(struct btrfs_trans_handle *trans, if (ret) break; - if (btrfs_test_opt(root, DISCARD)) - ret = btrfs_discard_extent(root, start, - end + 1 - start, NULL); + ret = btrfs_discard_extent(root, start, end + 1 - start); clear_extent_dirty(unpin, start, end, GFP_NOFS); unpin_extent_range(root, start, end); @@ -4720,10 +4704,10 @@ void btrfs_free_tree_block(struct btrfs_trans_handle *trans, WARN_ON(test_bit(EXTENT_BUFFER_DIRTY, &buf->bflags)); btrfs_add_free_space(cache, buf->start, buf->len); - ret = btrfs_update_reserved_bytes(cache, buf->len, 0, 0); + ret = update_reserved_bytes(cache, buf->len, 0, 0); if (ret == -EAGAIN) { /* block group became read-only */ - btrfs_update_reserved_bytes(cache, buf->len, 0, 1); + update_reserved_bytes(cache, buf->len, 0, 1); goto out; } @@ -4760,11 +4744,6 @@ void btrfs_free_tree_block(struct btrfs_trans_handle *trans, } } out: - /* - * Deleting the buffer, clear the corrupt flag since it doesn't matter - * anymore. - */ - clear_bit(EXTENT_BUFFER_CORRUPT, &buf->bflags); btrfs_put_block_group(cache); } @@ -5212,7 +5191,7 @@ static noinline int find_free_extent(struct btrfs_trans_handle *trans, search_start - offset); BUG_ON(offset > search_start); - ret = btrfs_update_reserved_bytes(block_group, num_bytes, 1, + ret = update_reserved_bytes(block_group, num_bytes, 1, (data & BTRFS_BLOCK_GROUP_DATA)); if (ret == -EAGAIN) { btrfs_add_free_space(block_group, offset, num_bytes); @@ -5418,8 +5397,6 @@ int btrfs_reserve_extent(struct btrfs_trans_handle *trans, dump_space_info(sinfo, num_bytes, 1); } - trace_btrfs_reserved_extent_alloc(root, ins->objectid, ins->offset); - return ret; } @@ -5435,15 +5412,12 @@ int btrfs_free_reserved_extent(struct btrfs_root *root, u64 start, u64 len) return -ENOSPC; } - if (btrfs_test_opt(root, DISCARD)) - ret = btrfs_discard_extent(root, start, len, NULL); + ret = btrfs_discard_extent(root, start, len); btrfs_add_free_space(cache, start, len); - btrfs_update_reserved_bytes(cache, len, 0, 1); + update_reserved_bytes(cache, len, 0, 1); btrfs_put_block_group(cache); - trace_btrfs_reserved_extent_free(root, start, len); - return ret; } @@ -5470,8 +5444,7 @@ static int alloc_reserved_file_extent(struct btrfs_trans_handle *trans, size = sizeof(*extent_item) + btrfs_extent_inline_ref_size(type); path = btrfs_alloc_path(); - if (!path) - return -ENOMEM; + BUG_ON(!path); path->leave_spinning = 1; ret = btrfs_insert_empty_item(trans, fs_info->extent_root, path, @@ -5641,7 +5614,7 @@ int btrfs_alloc_logged_file_extent(struct btrfs_trans_handle *trans, put_caching_control(caching_ctl); } - ret = btrfs_update_reserved_bytes(block_group, ins->offset, 1, 1); + ret = update_reserved_bytes(block_group, ins->offset, 1, 1); BUG_ON(ret); btrfs_put_block_group(block_group); ret = alloc_reserved_file_extent(trans, root, 0, root_objectid, @@ -6074,8 +6047,6 @@ static noinline int do_walk_down(struct btrfs_trans_handle *trans, if (reada && level == 1) reada_walk_down(trans, root, wc, path); next = read_tree_block(root, bytenr, blocksize, generation); - if (!next) - return -EIO; btrfs_tree_lock(next); btrfs_set_lock_blocking(next); } @@ -6467,14 +6438,10 @@ int btrfs_drop_subtree(struct btrfs_trans_handle *trans, BUG_ON(root->root_key.objectid != BTRFS_TREE_RELOC_OBJECTID); path = btrfs_alloc_path(); - if (!path) - return -ENOMEM; + BUG_ON(!path); wc = kzalloc(sizeof(*wc), GFP_NOFS); - if (!wc) { - btrfs_free_path(path); - return -ENOMEM; - } + BUG_ON(!wc); btrfs_assert_tree_locked(parent); parent_level = btrfs_header_level(parent); @@ -6932,11 +6899,7 @@ static noinline int get_new_locations(struct inode *reloc_inode, } path = btrfs_alloc_path(); - if (!path) { - if (exts != *extents) - kfree(exts); - return -ENOMEM; - } + BUG_ON(!path); cur_pos = extent_key->objectid - offset; last_byte = extent_key->objectid + extent_key->offset; @@ -6978,10 +6941,6 @@ static noinline int get_new_locations(struct inode *reloc_inode, struct disk_extent *old = exts; max *= 2; exts = kzalloc(sizeof(*exts) * max, GFP_NOFS); - if (!exts) { - ret = -ENOMEM; - goto out; - } memcpy(exts, old, sizeof(*exts) * nr); if (old != *extents) kfree(old); @@ -7464,8 +7423,7 @@ static noinline int replace_extents_in_leaf(struct btrfs_trans_handle *trans, int ret; new_extent = kmalloc(sizeof(*new_extent), GFP_NOFS); - if (!new_extent) - return -ENOMEM; + BUG_ON(!new_extent); ref = btrfs_lookup_leaf_ref(root, leaf->start); BUG_ON(!ref); @@ -7651,8 +7609,7 @@ int btrfs_cleanup_reloc_trees(struct btrfs_root *root) reloc_root = btrfs_read_fs_root_no_name(root->fs_info, &location); BUG_ON(!reloc_root); - ret = btrfs_orphan_cleanup(reloc_root); - BUG_ON(ret); + btrfs_orphan_cleanup(reloc_root); return 0; } @@ -7670,8 +7627,7 @@ static noinline int init_reloc_tree(struct btrfs_trans_handle *trans, return 0; root_item = kmalloc(sizeof(*root_item), GFP_NOFS); - if (!root_item) - return -ENOMEM; + BUG_ON(!root_item); ret = btrfs_copy_root(trans, root, root->commit_root, &eb, BTRFS_TREE_RELOC_OBJECTID); @@ -7697,7 +7653,7 @@ static noinline int init_reloc_tree(struct btrfs_trans_handle *trans, reloc_root = btrfs_read_fs_root_no_radix(root->fs_info->tree_root, &root_key); - BUG_ON(IS_ERR(reloc_root)); + BUG_ON(!reloc_root); reloc_root->last_trans = trans->transid; reloc_root->commit_root = NULL; reloc_root->ref_tree = &root->fs_info->reloc_ref_tree; @@ -7950,10 +7906,6 @@ static noinline int relocate_one_extent(struct btrfs_root *extent_root, eb = read_tree_block(found_root, block_start, block_size, 0); - if (!eb) { - ret = -EIO; - goto out; - } btrfs_tree_lock(eb); BUG_ON(level != btrfs_header_level(eb)); @@ -8669,12 +8621,6 @@ int btrfs_remove_block_group(struct btrfs_trans_handle *trans, BUG_ON(!block_group); BUG_ON(!block_group->ro); - /* - * Free the reserved super bytes from this block group before - * remove it. - */ - free_excluded_extents(root, block_group); - memcpy(&key, &block_group->key, sizeof(key)); if (block_group->flags & (BTRFS_BLOCK_GROUP_DUP | BTRFS_BLOCK_GROUP_RAID1 | @@ -8778,84 +8724,13 @@ int btrfs_remove_block_group(struct btrfs_trans_handle *trans, return ret; } -int btrfs_init_space_info(struct btrfs_fs_info *fs_info) -{ - struct btrfs_space_info *space_info; - int ret; - - ret = update_space_info(fs_info, BTRFS_BLOCK_GROUP_SYSTEM, 0, 0, - &space_info); - if (ret) - return ret; - - ret = update_space_info(fs_info, BTRFS_BLOCK_GROUP_METADATA, 0, 0, - &space_info); - if (ret) - return ret; - - ret = update_space_info(fs_info, BTRFS_BLOCK_GROUP_DATA, 0, 0, - &space_info); - if (ret) - return ret; - - return ret; -} - int btrfs_error_unpin_extent_range(struct btrfs_root *root, u64 start, u64 end) { return unpin_extent_range(root, start, end); } int btrfs_error_discard_extent(struct btrfs_root *root, u64 bytenr, - u64 num_bytes, u64 *actual_bytes) -{ - return btrfs_discard_extent(root, bytenr, num_bytes, actual_bytes); -} - -int btrfs_trim_fs(struct btrfs_root *root, struct fstrim_range *range) + u64 num_bytes) { - struct btrfs_fs_info *fs_info = root->fs_info; - struct btrfs_block_group_cache *cache = NULL; - u64 group_trimmed; - u64 start; - u64 end; - u64 trimmed = 0; - int ret = 0; - - cache = btrfs_lookup_block_group(fs_info, range->start); - - while (cache) { - if (cache->key.objectid >= (range->start + range->len)) { - btrfs_put_block_group(cache); - break; - } - - start = max(range->start, cache->key.objectid); - end = min(range->start + range->len, - cache->key.objectid + cache->key.offset); - - if (end - start >= range->minlen) { - if (!block_group_cache_done(cache)) { - ret = cache_block_group(cache, NULL, root, 0); - if (!ret) - wait_block_group_cache_done(cache); - } - ret = btrfs_trim_block_group(cache, - &group_trimmed, - start, - end, - range->minlen); - - trimmed += group_trimmed; - if (ret) { - btrfs_put_block_group(cache); - break; - } - } - - cache = next_block_group(fs_info->tree_root, cache); - } - - range->len = trimmed; - return ret; + return btrfs_discard_extent(root, bytenr, num_bytes); } diff --git a/trunk/fs/btrfs/extent_io.c b/trunk/fs/btrfs/extent_io.c index 20ddb28602a8..b5b92824a271 100644 --- a/trunk/fs/btrfs/extent_io.c +++ b/trunk/fs/btrfs/extent_io.c @@ -2192,8 +2192,6 @@ static int __extent_writepage(struct page *page, struct writeback_control *wbc, else write_flags = WRITE; - trace___extent_writepage(page, inode, wbc); - WARN_ON(!PageLocked(page)); pg_offset = i_size & (PAGE_CACHE_SIZE - 1); if (page->index > end_index || @@ -3692,7 +3690,6 @@ int map_private_extent_buffer(struct extent_buffer *eb, unsigned long start, "wanted %lu %lu\n", (unsigned long long)eb->start, eb->len, start, min_len); WARN_ON(1); - return -EINVAL; } p = extent_buffer_page(eb, i); diff --git a/trunk/fs/btrfs/extent_io.h b/trunk/fs/btrfs/extent_io.h index f62c5442835d..9318dfefd59c 100644 --- a/trunk/fs/btrfs/extent_io.h +++ b/trunk/fs/btrfs/extent_io.h @@ -31,7 +31,6 @@ #define EXTENT_BUFFER_UPTODATE 0 #define EXTENT_BUFFER_BLOCKING 1 #define EXTENT_BUFFER_DIRTY 2 -#define EXTENT_BUFFER_CORRUPT 3 /* these are flags for extent_clear_unlock_delalloc */ #define EXTENT_CLEAR_UNLOCK_PAGE 0x1 diff --git a/trunk/fs/btrfs/file-item.c b/trunk/fs/btrfs/file-item.c index a6a9d4e8b491..4f19a3e1bf32 100644 --- a/trunk/fs/btrfs/file-item.c +++ b/trunk/fs/btrfs/file-item.c @@ -48,8 +48,7 @@ int btrfs_insert_file_extent(struct btrfs_trans_handle *trans, struct extent_buffer *leaf; path = btrfs_alloc_path(); - if (!path) - return -ENOMEM; + BUG_ON(!path); file_key.objectid = objectid; file_key.offset = pos; btrfs_set_key_type(&file_key, BTRFS_EXTENT_DATA_KEY); @@ -170,8 +169,6 @@ static int __btrfs_lookup_bio_sums(struct btrfs_root *root, struct extent_io_tree *io_tree = &BTRFS_I(inode)->io_tree; path = btrfs_alloc_path(); - if (!path) - return -ENOMEM; if (bio->bi_size > PAGE_CACHE_SIZE * 8) path->reada = 2; diff --git a/trunk/fs/btrfs/file.c b/trunk/fs/btrfs/file.c index 656bc0a892b1..f447b783bb84 100644 --- a/trunk/fs/btrfs/file.c +++ b/trunk/fs/btrfs/file.c @@ -45,14 +45,14 @@ * and be replaced with calls into generic code. */ static noinline int btrfs_copy_from_user(loff_t pos, int num_pages, - size_t write_bytes, + int write_bytes, struct page **prepared_pages, struct iov_iter *i) { size_t copied = 0; - size_t total_copied = 0; int pg = 0; int offset = pos & (PAGE_CACHE_SIZE - 1); + int total_copied = 0; while (write_bytes > 0) { size_t count = min_t(size_t, @@ -88,8 +88,9 @@ static noinline int btrfs_copy_from_user(loff_t pos, int num_pages, total_copied += copied; /* Return to btrfs_file_aio_write to fault page */ - if (unlikely(copied == 0)) + if (unlikely(copied == 0)) { break; + } if (unlikely(copied < PAGE_CACHE_SIZE - offset)) { offset += copied; @@ -108,6 +109,8 @@ static noinline void btrfs_drop_pages(struct page **pages, size_t num_pages) { size_t i; for (i = 0; i < num_pages; i++) { + if (!pages[i]) + break; /* page checked is some magic around finding pages that * have been modified without going through btrfs_set_page_dirty * clear it here @@ -127,12 +130,13 @@ static noinline void btrfs_drop_pages(struct page **pages, size_t num_pages) * this also makes the decision about creating an inline extent vs * doing real data extents, marking pages dirty and delalloc as required. */ -static noinline int dirty_and_release_pages(struct btrfs_root *root, - struct file *file, - struct page **pages, - size_t num_pages, - loff_t pos, - size_t write_bytes) +static noinline int dirty_and_release_pages(struct btrfs_trans_handle *trans, + struct btrfs_root *root, + struct file *file, + struct page **pages, + size_t num_pages, + loff_t pos, + size_t write_bytes) { int err = 0; int i; @@ -150,8 +154,7 @@ static noinline int dirty_and_release_pages(struct btrfs_root *root, end_of_last_block = start_pos + num_bytes - 1; err = btrfs_set_extent_delalloc(inode, start_pos, end_of_last_block, NULL); - if (err) - return err; + BUG_ON(err); for (i = 0; i < num_pages; i++) { struct page *p = pages[i]; @@ -159,14 +162,13 @@ static noinline int dirty_and_release_pages(struct btrfs_root *root, ClearPageChecked(p); set_page_dirty(p); } - - /* - * we've only changed i_size in ram, and we haven't updated - * the disk i_size. There is no need to log the inode - * at this time. - */ - if (end_pos > isize) + if (end_pos > isize) { i_size_write(inode, end_pos); + /* we've only changed i_size in ram, and we haven't updated + * the disk i_size. There is no need to log the inode + * at this time. + */ + } return 0; } @@ -608,8 +610,6 @@ int btrfs_mark_extent_written(struct btrfs_trans_handle *trans, key.offset = split; ret = btrfs_search_slot(trans, root, &key, path, -1, 1); - if (ret < 0) - goto out; if (ret > 0 && path->slots[0] > 0) path->slots[0]--; @@ -819,11 +819,12 @@ static noinline int prepare_pages(struct btrfs_root *root, struct file *file, last_pos = ((u64)index + num_pages) << PAGE_CACHE_SHIFT; if (start_pos > inode->i_size) { - err = btrfs_cont_expand(inode, i_size_read(inode), start_pos); + err = btrfs_cont_expand(inode, start_pos); if (err) return err; } + memset(pages, 0, num_pages * sizeof(struct page *)); again: for (i = 0; i < num_pages; i++) { pages[i] = grab_cache_page(inode->i_mapping, index + i); @@ -895,71 +896,156 @@ static noinline int prepare_pages(struct btrfs_root *root, struct file *file, } -static noinline ssize_t __btrfs_buffered_write(struct file *file, - struct iov_iter *i, - loff_t pos) +static ssize_t btrfs_file_aio_write(struct kiocb *iocb, + const struct iovec *iov, + unsigned long nr_segs, loff_t pos) { + struct file *file = iocb->ki_filp; struct inode *inode = fdentry(file)->d_inode; struct btrfs_root *root = BTRFS_I(inode)->root; struct page **pages = NULL; + struct iov_iter i; + loff_t *ppos = &iocb->ki_pos; + loff_t start_pos; + ssize_t num_written = 0; + ssize_t err = 0; + size_t count; + size_t ocount; + int ret = 0; + int nrptrs; unsigned long first_index; unsigned long last_index; - size_t num_written = 0; - int nrptrs; - int ret; + int will_write; + int buffered = 0; + int copied = 0; + int dirty_pages = 0; + + will_write = ((file->f_flags & O_DSYNC) || IS_SYNC(inode) || + (file->f_flags & O_DIRECT)); + + start_pos = pos; + + vfs_check_frozen(inode->i_sb, SB_FREEZE_WRITE); + + mutex_lock(&inode->i_mutex); + + err = generic_segment_checks(iov, &nr_segs, &ocount, VERIFY_READ); + if (err) + goto out; + count = ocount; + + current->backing_dev_info = inode->i_mapping->backing_dev_info; + err = generic_write_checks(file, &pos, &count, S_ISBLK(inode->i_mode)); + if (err) + goto out; + + if (count == 0) + goto out; + + err = file_remove_suid(file); + if (err) + goto out; + + /* + * If BTRFS flips readonly due to some impossible error + * (fs_info->fs_state now has BTRFS_SUPER_FLAG_ERROR), + * although we have opened a file as writable, we have + * to stop this write operation to ensure FS consistency. + */ + if (root->fs_info->fs_state & BTRFS_SUPER_FLAG_ERROR) { + err = -EROFS; + goto out; + } - nrptrs = min((iov_iter_count(i) + PAGE_CACHE_SIZE - 1) / + file_update_time(file); + BTRFS_I(inode)->sequence++; + + if (unlikely(file->f_flags & O_DIRECT)) { + num_written = generic_file_direct_write(iocb, iov, &nr_segs, + pos, ppos, count, + ocount); + /* + * the generic O_DIRECT will update in-memory i_size after the + * DIOs are done. But our endio handlers that update the on + * disk i_size never update past the in memory i_size. So we + * need one more update here to catch any additions to the + * file + */ + if (inode->i_size != BTRFS_I(inode)->disk_i_size) { + btrfs_ordered_update_i_size(inode, inode->i_size, NULL); + mark_inode_dirty(inode); + } + + if (num_written < 0) { + ret = num_written; + num_written = 0; + goto out; + } else if (num_written == count) { + /* pick up pos changes done by the generic code */ + pos = *ppos; + goto out; + } + /* + * We are going to do buffered for the rest of the range, so we + * need to make sure to invalidate the buffered pages when we're + * done. + */ + buffered = 1; + pos += num_written; + } + + iov_iter_init(&i, iov, nr_segs, count, num_written); + nrptrs = min((iov_iter_count(&i) + PAGE_CACHE_SIZE - 1) / PAGE_CACHE_SIZE, PAGE_CACHE_SIZE / (sizeof(struct page *))); pages = kmalloc(nrptrs * sizeof(struct page *), GFP_KERNEL); - if (!pages) - return -ENOMEM; + if (!pages) { + ret = -ENOMEM; + goto out; + } + + /* generic_write_checks can change our pos */ + start_pos = pos; first_index = pos >> PAGE_CACHE_SHIFT; - last_index = (pos + iov_iter_count(i)) >> PAGE_CACHE_SHIFT; + last_index = (pos + iov_iter_count(&i)) >> PAGE_CACHE_SHIFT; - while (iov_iter_count(i) > 0) { + while (iov_iter_count(&i) > 0) { size_t offset = pos & (PAGE_CACHE_SIZE - 1); - size_t write_bytes = min(iov_iter_count(i), + size_t write_bytes = min(iov_iter_count(&i), nrptrs * (size_t)PAGE_CACHE_SIZE - offset); size_t num_pages = (write_bytes + offset + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT; - size_t dirty_pages; - size_t copied; WARN_ON(num_pages > nrptrs); + memset(pages, 0, sizeof(struct page *) * nrptrs); /* * Fault pages before locking them in prepare_pages * to avoid recursive lock */ - if (unlikely(iov_iter_fault_in_readable(i, write_bytes))) { + if (unlikely(iov_iter_fault_in_readable(&i, write_bytes))) { ret = -EFAULT; - break; + goto out; } ret = btrfs_delalloc_reserve_space(inode, num_pages << PAGE_CACHE_SHIFT); if (ret) - break; + goto out; - /* - * This is going to setup the pages array with the number of - * pages we want, so we don't really need to worry about the - * contents of pages from loop to loop - */ ret = prepare_pages(root, file, pages, num_pages, pos, first_index, last_index, write_bytes); if (ret) { btrfs_delalloc_release_space(inode, num_pages << PAGE_CACHE_SHIFT); - break; + goto out; } copied = btrfs_copy_from_user(pos, num_pages, - write_bytes, pages, i); + write_bytes, pages, &i); /* * if we have trouble faulting in the pages, fall @@ -975,13 +1061,6 @@ static noinline ssize_t __btrfs_buffered_write(struct file *file, PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT; - /* - * If we had a short copy we need to release the excess delaloc - * bytes we reserved. We need to increment outstanding_extents - * because btrfs_delalloc_release_space will decrement it, but - * we still have an outstanding extent for the chunk we actually - * managed to copy. - */ if (num_pages > dirty_pages) { if (copied > 0) atomic_inc( @@ -992,157 +1071,39 @@ static noinline ssize_t __btrfs_buffered_write(struct file *file, } if (copied > 0) { - ret = dirty_and_release_pages(root, file, pages, - dirty_pages, pos, - copied); - if (ret) { - btrfs_delalloc_release_space(inode, - dirty_pages << PAGE_CACHE_SHIFT); - btrfs_drop_pages(pages, num_pages); - break; - } + dirty_and_release_pages(NULL, root, file, pages, + dirty_pages, pos, copied); } btrfs_drop_pages(pages, num_pages); - cond_resched(); - - balance_dirty_pages_ratelimited_nr(inode->i_mapping, - dirty_pages); - if (dirty_pages < (root->leafsize >> PAGE_CACHE_SHIFT) + 1) - btrfs_btree_balance_dirty(root, 1); - btrfs_throttle(root); + if (copied > 0) { + if (will_write) { + filemap_fdatawrite_range(inode->i_mapping, pos, + pos + copied - 1); + } else { + balance_dirty_pages_ratelimited_nr( + inode->i_mapping, + dirty_pages); + if (dirty_pages < + (root->leafsize >> PAGE_CACHE_SHIFT) + 1) + btrfs_btree_balance_dirty(root, 1); + btrfs_throttle(root); + } + } pos += copied; num_written += copied; - } - - kfree(pages); - - return num_written ? num_written : ret; -} -static ssize_t __btrfs_direct_write(struct kiocb *iocb, - const struct iovec *iov, - unsigned long nr_segs, loff_t pos, - loff_t *ppos, size_t count, size_t ocount) -{ - struct file *file = iocb->ki_filp; - struct inode *inode = fdentry(file)->d_inode; - struct iov_iter i; - ssize_t written; - ssize_t written_buffered; - loff_t endbyte; - int err; - - written = generic_file_direct_write(iocb, iov, &nr_segs, pos, ppos, - count, ocount); - - /* - * the generic O_DIRECT will update in-memory i_size after the - * DIOs are done. But our endio handlers that update the on - * disk i_size never update past the in memory i_size. So we - * need one more update here to catch any additions to the - * file - */ - if (inode->i_size != BTRFS_I(inode)->disk_i_size) { - btrfs_ordered_update_i_size(inode, inode->i_size, NULL); - mark_inode_dirty(inode); - } - - if (written < 0 || written == count) - return written; - - pos += written; - count -= written; - iov_iter_init(&i, iov, nr_segs, count, written); - written_buffered = __btrfs_buffered_write(file, &i, pos); - if (written_buffered < 0) { - err = written_buffered; - goto out; + cond_resched(); } - endbyte = pos + written_buffered - 1; - err = filemap_write_and_wait_range(file->f_mapping, pos, endbyte); - if (err) - goto out; - written += written_buffered; - *ppos = pos + written_buffered; - invalidate_mapping_pages(file->f_mapping, pos >> PAGE_CACHE_SHIFT, - endbyte >> PAGE_CACHE_SHIFT); out: - return written ? written : err; -} - -static ssize_t btrfs_file_aio_write(struct kiocb *iocb, - const struct iovec *iov, - unsigned long nr_segs, loff_t pos) -{ - struct file *file = iocb->ki_filp; - struct inode *inode = fdentry(file)->d_inode; - struct btrfs_root *root = BTRFS_I(inode)->root; - loff_t *ppos = &iocb->ki_pos; - ssize_t num_written = 0; - ssize_t err = 0; - size_t count, ocount; - - vfs_check_frozen(inode->i_sb, SB_FREEZE_WRITE); - - mutex_lock(&inode->i_mutex); - - err = generic_segment_checks(iov, &nr_segs, &ocount, VERIFY_READ); - if (err) { - mutex_unlock(&inode->i_mutex); - goto out; - } - count = ocount; - - current->backing_dev_info = inode->i_mapping->backing_dev_info; - err = generic_write_checks(file, &pos, &count, S_ISBLK(inode->i_mode)); - if (err) { - mutex_unlock(&inode->i_mutex); - goto out; - } - - if (count == 0) { - mutex_unlock(&inode->i_mutex); - goto out; - } - - err = file_remove_suid(file); - if (err) { - mutex_unlock(&inode->i_mutex); - goto out; - } - - /* - * If BTRFS flips readonly due to some impossible error - * (fs_info->fs_state now has BTRFS_SUPER_FLAG_ERROR), - * although we have opened a file as writable, we have - * to stop this write operation to ensure FS consistency. - */ - if (root->fs_info->fs_state & BTRFS_SUPER_FLAG_ERROR) { - mutex_unlock(&inode->i_mutex); - err = -EROFS; - goto out; - } - - file_update_time(file); - BTRFS_I(inode)->sequence++; - - if (unlikely(file->f_flags & O_DIRECT)) { - num_written = __btrfs_direct_write(iocb, iov, nr_segs, - pos, ppos, count, ocount); - } else { - struct iov_iter i; - - iov_iter_init(&i, iov, nr_segs, count, num_written); - - num_written = __btrfs_buffered_write(file, &i, pos); - if (num_written > 0) - *ppos = pos + num_written; - } - mutex_unlock(&inode->i_mutex); + if (ret) + err = ret; + + kfree(pages); + *ppos = pos; /* * we want to make sure fsync finds this change @@ -1157,12 +1118,43 @@ static ssize_t btrfs_file_aio_write(struct kiocb *iocb, * one running right now. */ BTRFS_I(inode)->last_trans = root->fs_info->generation + 1; - if (num_written > 0 || num_written == -EIOCBQUEUED) { - err = generic_write_sync(file, pos, num_written); - if (err < 0 && num_written > 0) + + if (num_written > 0 && will_write) { + struct btrfs_trans_handle *trans; + + err = btrfs_wait_ordered_range(inode, start_pos, num_written); + if (err) num_written = err; + + if ((file->f_flags & O_DSYNC) || IS_SYNC(inode)) { + trans = btrfs_start_transaction(root, 0); + if (IS_ERR(trans)) { + num_written = PTR_ERR(trans); + goto done; + } + mutex_lock(&inode->i_mutex); + ret = btrfs_log_dentry_safe(trans, root, + file->f_dentry); + mutex_unlock(&inode->i_mutex); + if (ret == 0) { + ret = btrfs_sync_log(trans, root); + if (ret == 0) + btrfs_end_transaction(trans, root); + else + btrfs_commit_transaction(trans, root); + } else if (ret != BTRFS_NO_LOG_SYNC) { + btrfs_commit_transaction(trans, root); + } else { + btrfs_end_transaction(trans, root); + } + } + if (file->f_flags & O_DIRECT && buffered) { + invalidate_mapping_pages(inode->i_mapping, + start_pos >> PAGE_CACHE_SHIFT, + (start_pos + num_written - 1) >> PAGE_CACHE_SHIFT); + } } -out: +done: current->backing_dev_info = NULL; return num_written ? num_written : err; } @@ -1205,7 +1197,6 @@ int btrfs_sync_file(struct file *file, int datasync) int ret = 0; struct btrfs_trans_handle *trans; - trace_btrfs_sync_file(file, datasync); /* we wait first, since the writeback may change the inode */ root->log_batch++; @@ -1333,8 +1324,7 @@ static long btrfs_fallocate(struct file *file, int mode, goto out; if (alloc_start > inode->i_size) { - ret = btrfs_cont_expand(inode, i_size_read(inode), - alloc_start); + ret = btrfs_cont_expand(inode, alloc_start); if (ret) goto out; } diff --git a/trunk/fs/btrfs/free-space-cache.c b/trunk/fs/btrfs/free-space-cache.c index 0037427d8a9d..a0390657451b 100644 --- a/trunk/fs/btrfs/free-space-cache.c +++ b/trunk/fs/btrfs/free-space-cache.c @@ -393,8 +393,7 @@ int load_free_space_cache(struct btrfs_fs_info *fs_info, break; need_loop = 1; - e = kmem_cache_zalloc(btrfs_free_space_cachep, - GFP_NOFS); + e = kzalloc(sizeof(struct btrfs_free_space), GFP_NOFS); if (!e) { kunmap(page); unlock_page(page); @@ -406,7 +405,7 @@ int load_free_space_cache(struct btrfs_fs_info *fs_info, e->bytes = le64_to_cpu(entry->bytes); if (!e->bytes) { kunmap(page); - kmem_cache_free(btrfs_free_space_cachep, e); + kfree(e); unlock_page(page); page_cache_release(page); goto free_cache; @@ -421,8 +420,7 @@ int load_free_space_cache(struct btrfs_fs_info *fs_info, e->bitmap = kzalloc(PAGE_CACHE_SIZE, GFP_NOFS); if (!e->bitmap) { kunmap(page); - kmem_cache_free( - btrfs_free_space_cachep, e); + kfree(e); unlock_page(page); page_cache_release(page); goto free_cache; @@ -1189,7 +1187,7 @@ static void free_bitmap(struct btrfs_block_group_cache *block_group, { unlink_free_space(block_group, bitmap_info); kfree(bitmap_info->bitmap); - kmem_cache_free(btrfs_free_space_cachep, bitmap_info); + kfree(bitmap_info); block_group->total_bitmaps--; recalculate_thresholds(block_group); } @@ -1287,22 +1285,9 @@ static int insert_into_bitmap(struct btrfs_block_group_cache *block_group, * If we are below the extents threshold then we can add this as an * extent, and don't have to deal with the bitmap */ - if (block_group->free_extents < block_group->extents_thresh) { - /* - * If this block group has some small extents we don't want to - * use up all of our free slots in the cache with them, we want - * to reserve them to larger extents, however if we have plent - * of cache left then go ahead an dadd them, no sense in adding - * the overhead of a bitmap if we don't have to. - */ - if (info->bytes <= block_group->sectorsize * 4) { - if (block_group->free_extents * 2 <= - block_group->extents_thresh) - return 0; - } else { - return 0; - } - } + if (block_group->free_extents < block_group->extents_thresh && + info->bytes > block_group->sectorsize * 4) + return 0; /* * some block groups are so tiny they can't be enveloped by a bitmap, so @@ -1357,8 +1342,8 @@ static int insert_into_bitmap(struct btrfs_block_group_cache *block_group, /* no pre-allocated info, allocate a new one */ if (!info) { - info = kmem_cache_zalloc(btrfs_free_space_cachep, - GFP_NOFS); + info = kzalloc(sizeof(struct btrfs_free_space), + GFP_NOFS); if (!info) { spin_lock(&block_group->tree_lock); ret = -ENOMEM; @@ -1380,7 +1365,7 @@ static int insert_into_bitmap(struct btrfs_block_group_cache *block_group, if (info) { if (info->bitmap) kfree(info->bitmap); - kmem_cache_free(btrfs_free_space_cachep, info); + kfree(info); } return ret; @@ -1413,7 +1398,7 @@ bool try_merge_free_space(struct btrfs_block_group_cache *block_group, else __unlink_free_space(block_group, right_info); info->bytes += right_info->bytes; - kmem_cache_free(btrfs_free_space_cachep, right_info); + kfree(right_info); merged = true; } @@ -1425,7 +1410,7 @@ bool try_merge_free_space(struct btrfs_block_group_cache *block_group, __unlink_free_space(block_group, left_info); info->offset = left_info->offset; info->bytes += left_info->bytes; - kmem_cache_free(btrfs_free_space_cachep, left_info); + kfree(left_info); merged = true; } @@ -1438,7 +1423,7 @@ int btrfs_add_free_space(struct btrfs_block_group_cache *block_group, struct btrfs_free_space *info; int ret = 0; - info = kmem_cache_zalloc(btrfs_free_space_cachep, GFP_NOFS); + info = kzalloc(sizeof(struct btrfs_free_space), GFP_NOFS); if (!info) return -ENOMEM; @@ -1465,7 +1450,7 @@ int btrfs_add_free_space(struct btrfs_block_group_cache *block_group, link: ret = link_free_space(block_group, info); if (ret) - kmem_cache_free(btrfs_free_space_cachep, info); + kfree(info); out: spin_unlock(&block_group->tree_lock); @@ -1535,7 +1520,7 @@ int btrfs_remove_free_space(struct btrfs_block_group_cache *block_group, kfree(info->bitmap); block_group->total_bitmaps--; } - kmem_cache_free(btrfs_free_space_cachep, info); + kfree(info); goto out_lock; } @@ -1571,7 +1556,7 @@ int btrfs_remove_free_space(struct btrfs_block_group_cache *block_group, /* the hole we're creating ends at the end * of the info struct, just free the info */ - kmem_cache_free(btrfs_free_space_cachep, info); + kfree(info); } spin_unlock(&block_group->tree_lock); @@ -1644,28 +1629,30 @@ __btrfs_return_cluster_to_free_space( { struct btrfs_free_space *entry; struct rb_node *node; + bool bitmap; spin_lock(&cluster->lock); if (cluster->block_group != block_group) goto out; + bitmap = cluster->points_to_bitmap; cluster->block_group = NULL; cluster->window_start = 0; list_del_init(&cluster->block_group_list); + cluster->points_to_bitmap = false; + + if (bitmap) + goto out; node = rb_first(&cluster->root); while (node) { - bool bitmap; - entry = rb_entry(node, struct btrfs_free_space, offset_index); node = rb_next(&entry->offset_index); rb_erase(&entry->offset_index, &cluster->root); - - bitmap = (entry->bitmap != NULL); - if (!bitmap) - try_merge_free_space(block_group, entry, false); + BUG_ON(entry->bitmap); + try_merge_free_space(block_group, entry, false); tree_insert_offset(&block_group->free_space_offset, - entry->offset, &entry->offset_index, bitmap); + entry->offset, &entry->offset_index, 0); } cluster->root = RB_ROOT; @@ -1702,7 +1689,7 @@ void btrfs_remove_free_space_cache(struct btrfs_block_group_cache *block_group) unlink_free_space(block_group, info); if (info->bitmap) kfree(info->bitmap); - kmem_cache_free(btrfs_free_space_cachep, info); + kfree(info); if (need_resched()) { spin_unlock(&block_group->tree_lock); cond_resched(); @@ -1735,7 +1722,7 @@ u64 btrfs_find_space_for_alloc(struct btrfs_block_group_cache *block_group, entry->offset += bytes; entry->bytes -= bytes; if (!entry->bytes) - kmem_cache_free(btrfs_free_space_cachep, entry); + kfree(entry); else link_free_space(block_group, entry); } @@ -1788,24 +1775,50 @@ int btrfs_return_cluster_to_free_space( static u64 btrfs_alloc_from_bitmap(struct btrfs_block_group_cache *block_group, struct btrfs_free_cluster *cluster, - struct btrfs_free_space *entry, u64 bytes, u64 min_start) { + struct btrfs_free_space *entry; int err; u64 search_start = cluster->window_start; u64 search_bytes = bytes; u64 ret = 0; + spin_lock(&block_group->tree_lock); + spin_lock(&cluster->lock); + + if (!cluster->points_to_bitmap) + goto out; + + if (cluster->block_group != block_group) + goto out; + + /* + * search_start is the beginning of the bitmap, but at some point it may + * be a good idea to point to the actual start of the free area in the + * bitmap, so do the offset_to_bitmap trick anyway, and set bitmap_only + * to 1 to make sure we get the bitmap entry + */ + entry = tree_search_offset(block_group, + offset_to_bitmap(block_group, search_start), + 1, 0); + if (!entry || !entry->bitmap) + goto out; + search_start = min_start; search_bytes = bytes; err = search_bitmap(block_group, entry, &search_start, &search_bytes); if (err) - return 0; + goto out; ret = search_start; bitmap_clear_bits(block_group, entry, ret, bytes); + if (entry->bytes == 0) + free_bitmap(block_group, entry); +out: + spin_unlock(&cluster->lock); + spin_unlock(&block_group->tree_lock); return ret; } @@ -1823,6 +1836,10 @@ u64 btrfs_alloc_from_cluster(struct btrfs_block_group_cache *block_group, struct rb_node *node; u64 ret = 0; + if (cluster->points_to_bitmap) + return btrfs_alloc_from_bitmap(block_group, cluster, bytes, + min_start); + spin_lock(&cluster->lock); if (bytes > cluster->max_size) goto out; @@ -1835,9 +1852,9 @@ u64 btrfs_alloc_from_cluster(struct btrfs_block_group_cache *block_group, goto out; entry = rb_entry(node, struct btrfs_free_space, offset_index); + while(1) { - if (entry->bytes < bytes || - (!entry->bitmap && entry->offset < min_start)) { + if (entry->bytes < bytes || entry->offset < min_start) { struct rb_node *node; node = rb_next(&entry->offset_index); @@ -1847,27 +1864,10 @@ u64 btrfs_alloc_from_cluster(struct btrfs_block_group_cache *block_group, offset_index); continue; } + ret = entry->offset; - if (entry->bitmap) { - ret = btrfs_alloc_from_bitmap(block_group, - cluster, entry, bytes, - min_start); - if (ret == 0) { - struct rb_node *node; - node = rb_next(&entry->offset_index); - if (!node) - break; - entry = rb_entry(node, struct btrfs_free_space, - offset_index); - continue; - } - } else { - - ret = entry->offset; - - entry->offset += bytes; - entry->bytes -= bytes; - } + entry->offset += bytes; + entry->bytes -= bytes; if (entry->bytes == 0) rb_erase(&entry->offset_index, &cluster->root); @@ -1884,12 +1884,7 @@ u64 btrfs_alloc_from_cluster(struct btrfs_block_group_cache *block_group, block_group->free_space -= bytes; if (entry->bytes == 0) { block_group->free_extents--; - if (entry->bitmap) { - kfree(entry->bitmap); - block_group->total_bitmaps--; - recalculate_thresholds(block_group); - } - kmem_cache_free(btrfs_free_space_cachep, entry); + kfree(entry); } spin_unlock(&block_group->tree_lock); @@ -1909,13 +1904,12 @@ static int btrfs_bitmap_cluster(struct btrfs_block_group_cache *block_group, unsigned long found_bits; unsigned long start = 0; unsigned long total_found = 0; - int ret; bool found = false; i = offset_to_bit(entry->offset, block_group->sectorsize, max_t(u64, offset, entry->offset)); - search_bits = bytes_to_bits(bytes, block_group->sectorsize); - total_bits = bytes_to_bits(min_bytes, block_group->sectorsize); + search_bits = bytes_to_bits(min_bytes, block_group->sectorsize); + total_bits = bytes_to_bits(bytes, block_group->sectorsize); again: found_bits = 0; @@ -1932,7 +1926,7 @@ static int btrfs_bitmap_cluster(struct btrfs_block_group_cache *block_group, } if (!found_bits) - return -ENOSPC; + return -1; if (!found) { start = i; @@ -1956,208 +1950,189 @@ static int btrfs_bitmap_cluster(struct btrfs_block_group_cache *block_group, cluster->window_start = start * block_group->sectorsize + entry->offset; - rb_erase(&entry->offset_index, &block_group->free_space_offset); - ret = tree_insert_offset(&cluster->root, entry->offset, - &entry->offset_index, 1); - BUG_ON(ret); + cluster->points_to_bitmap = true; return 0; } /* - * This searches the block group for just extents to fill the cluster with. + * here we try to find a cluster of blocks in a block group. The goal + * is to find at least bytes free and up to empty_size + bytes free. + * We might not find them all in one contiguous area. + * + * returns zero and sets up cluster if things worked out, otherwise + * it returns -enospc */ -static int setup_cluster_no_bitmap(struct btrfs_block_group_cache *block_group, - struct btrfs_free_cluster *cluster, - u64 offset, u64 bytes, u64 min_bytes) +int btrfs_find_space_cluster(struct btrfs_trans_handle *trans, + struct btrfs_root *root, + struct btrfs_block_group_cache *block_group, + struct btrfs_free_cluster *cluster, + u64 offset, u64 bytes, u64 empty_size) { - struct btrfs_free_space *first = NULL; struct btrfs_free_space *entry = NULL; - struct btrfs_free_space *prev = NULL; - struct btrfs_free_space *last; struct rb_node *node; + struct btrfs_free_space *next; + struct btrfs_free_space *last = NULL; + u64 min_bytes; u64 window_start; u64 window_free; - u64 max_extent; - u64 max_gap = 128 * 1024; + u64 max_extent = 0; + bool found_bitmap = false; + int ret; - entry = tree_search_offset(block_group, offset, 0, 1); - if (!entry) - return -ENOSPC; + /* for metadata, allow allocates with more holes */ + if (btrfs_test_opt(root, SSD_SPREAD)) { + min_bytes = bytes + empty_size; + } else if (block_group->flags & BTRFS_BLOCK_GROUP_METADATA) { + /* + * we want to do larger allocations when we are + * flushing out the delayed refs, it helps prevent + * making more work as we go along. + */ + if (trans->transaction->delayed_refs.flushing) + min_bytes = max(bytes, (bytes + empty_size) >> 1); + else + min_bytes = max(bytes, (bytes + empty_size) >> 4); + } else + min_bytes = max(bytes, (bytes + empty_size) >> 2); + + spin_lock(&block_group->tree_lock); + spin_lock(&cluster->lock); + + /* someone already found a cluster, hooray */ + if (cluster->block_group) { + ret = 0; + goto out; + } +again: + entry = tree_search_offset(block_group, offset, found_bitmap, 1); + if (!entry) { + ret = -ENOSPC; + goto out; + } /* - * We don't want bitmaps, so just move along until we find a normal - * extent entry. + * If found_bitmap is true, we exhausted our search for extent entries, + * and we just want to search all of the bitmaps that we can find, and + * ignore any extent entries we find. */ - while (entry->bitmap) { - node = rb_next(&entry->offset_index); - if (!node) - return -ENOSPC; + while (entry->bitmap || found_bitmap || + (!entry->bitmap && entry->bytes < min_bytes)) { + struct rb_node *node = rb_next(&entry->offset_index); + + if (entry->bitmap && entry->bytes > bytes + empty_size) { + ret = btrfs_bitmap_cluster(block_group, entry, cluster, + offset, bytes + empty_size, + min_bytes); + if (!ret) + goto got_it; + } + + if (!node) { + ret = -ENOSPC; + goto out; + } entry = rb_entry(node, struct btrfs_free_space, offset_index); } + /* + * We already searched all the extent entries from the passed in offset + * to the end and didn't find enough space for the cluster, and we also + * didn't find any bitmaps that met our criteria, just go ahead and exit + */ + if (found_bitmap) { + ret = -ENOSPC; + goto out; + } + + cluster->points_to_bitmap = false; window_start = entry->offset; window_free = entry->bytes; - max_extent = entry->bytes; - first = entry; last = entry; - prev = entry; + max_extent = entry->bytes; - while (window_free <= min_bytes) { - node = rb_next(&entry->offset_index); - if (!node) - return -ENOSPC; - entry = rb_entry(node, struct btrfs_free_space, offset_index); + while (1) { + /* out window is just right, lets fill it */ + if (window_free >= bytes + empty_size) + break; - if (entry->bitmap) + node = rb_next(&last->offset_index); + if (!node) { + if (found_bitmap) + goto again; + ret = -ENOSPC; + goto out; + } + next = rb_entry(node, struct btrfs_free_space, offset_index); + + /* + * we found a bitmap, so if this search doesn't result in a + * cluster, we know to go and search again for the bitmaps and + * start looking for space there + */ + if (next->bitmap) { + if (!found_bitmap) + offset = next->offset; + found_bitmap = true; + last = next; continue; + } + /* * we haven't filled the empty size and the window is * very large. reset and try again */ - if (entry->offset - (prev->offset + prev->bytes) > max_gap || - entry->offset - window_start > (min_bytes * 2)) { - first = entry; + if (next->offset - (last->offset + last->bytes) > 128 * 1024 || + next->offset - window_start > (bytes + empty_size) * 2) { + entry = next; window_start = entry->offset; window_free = entry->bytes; last = entry; max_extent = entry->bytes; } else { - last = entry; - window_free += entry->bytes; + last = next; + window_free += next->bytes; if (entry->bytes > max_extent) max_extent = entry->bytes; } - prev = entry; } - cluster->window_start = first->offset; - - node = &first->offset_index; + cluster->window_start = entry->offset; /* * now we've found our entries, pull them out of the free space * cache and put them into the cluster rbtree + * + * The cluster includes an rbtree, but only uses the offset index + * of each free space cache entry. */ - do { - int ret; - - entry = rb_entry(node, struct btrfs_free_space, offset_index); + while (1) { node = rb_next(&entry->offset_index); - if (entry->bitmap) + if (entry->bitmap && node) { + entry = rb_entry(node, struct btrfs_free_space, + offset_index); continue; + } else if (entry->bitmap && !node) { + break; + } rb_erase(&entry->offset_index, &block_group->free_space_offset); ret = tree_insert_offset(&cluster->root, entry->offset, &entry->offset_index, 0); BUG_ON(ret); - } while (node && entry != last); - - cluster->max_size = max_extent; - - return 0; -} - -/* - * This specifically looks for bitmaps that may work in the cluster, we assume - * that we have already failed to find extents that will work. - */ -static int setup_cluster_bitmap(struct btrfs_block_group_cache *block_group, - struct btrfs_free_cluster *cluster, - u64 offset, u64 bytes, u64 min_bytes) -{ - struct btrfs_free_space *entry; - struct rb_node *node; - int ret = -ENOSPC; - - if (block_group->total_bitmaps == 0) - return -ENOSPC; - entry = tree_search_offset(block_group, - offset_to_bitmap(block_group, offset), - 0, 1); - if (!entry) - return -ENOSPC; + if (!node || entry == last) + break; - node = &entry->offset_index; - do { entry = rb_entry(node, struct btrfs_free_space, offset_index); - node = rb_next(&entry->offset_index); - if (!entry->bitmap) - continue; - if (entry->bytes < min_bytes) - continue; - ret = btrfs_bitmap_cluster(block_group, entry, cluster, offset, - bytes, min_bytes); - } while (ret && node); - - return ret; -} - -/* - * here we try to find a cluster of blocks in a block group. The goal - * is to find at least bytes free and up to empty_size + bytes free. - * We might not find them all in one contiguous area. - * - * returns zero and sets up cluster if things worked out, otherwise - * it returns -enospc - */ -int btrfs_find_space_cluster(struct btrfs_trans_handle *trans, - struct btrfs_root *root, - struct btrfs_block_group_cache *block_group, - struct btrfs_free_cluster *cluster, - u64 offset, u64 bytes, u64 empty_size) -{ - u64 min_bytes; - int ret; - - /* for metadata, allow allocates with more holes */ - if (btrfs_test_opt(root, SSD_SPREAD)) { - min_bytes = bytes + empty_size; - } else if (block_group->flags & BTRFS_BLOCK_GROUP_METADATA) { - /* - * we want to do larger allocations when we are - * flushing out the delayed refs, it helps prevent - * making more work as we go along. - */ - if (trans->transaction->delayed_refs.flushing) - min_bytes = max(bytes, (bytes + empty_size) >> 1); - else - min_bytes = max(bytes, (bytes + empty_size) >> 4); - } else - min_bytes = max(bytes, (bytes + empty_size) >> 2); - - spin_lock(&block_group->tree_lock); - - /* - * If we know we don't have enough space to make a cluster don't even - * bother doing all the work to try and find one. - */ - if (block_group->free_space < min_bytes) { - spin_unlock(&block_group->tree_lock); - return -ENOSPC; - } - - spin_lock(&cluster->lock); - - /* someone already found a cluster, hooray */ - if (cluster->block_group) { - ret = 0; - goto out; } - ret = setup_cluster_no_bitmap(block_group, cluster, offset, bytes, - min_bytes); - if (ret) - ret = setup_cluster_bitmap(block_group, cluster, offset, - bytes, min_bytes); - - if (!ret) { - atomic_inc(&block_group->count); - list_add_tail(&cluster->block_group_list, - &block_group->cluster_list); - cluster->block_group = block_group; - } + cluster->max_size = max_extent; +got_it: + ret = 0; + atomic_inc(&block_group->count); + list_add_tail(&cluster->block_group_list, &block_group->cluster_list); + cluster->block_group = block_group; out: spin_unlock(&cluster->lock); spin_unlock(&block_group->tree_lock); @@ -2174,99 +2149,8 @@ void btrfs_init_free_cluster(struct btrfs_free_cluster *cluster) spin_lock_init(&cluster->refill_lock); cluster->root = RB_ROOT; cluster->max_size = 0; + cluster->points_to_bitmap = false; INIT_LIST_HEAD(&cluster->block_group_list); cluster->block_group = NULL; } -int btrfs_trim_block_group(struct btrfs_block_group_cache *block_group, - u64 *trimmed, u64 start, u64 end, u64 minlen) -{ - struct btrfs_free_space *entry = NULL; - struct btrfs_fs_info *fs_info = block_group->fs_info; - u64 bytes = 0; - u64 actually_trimmed; - int ret = 0; - - *trimmed = 0; - - while (start < end) { - spin_lock(&block_group->tree_lock); - - if (block_group->free_space < minlen) { - spin_unlock(&block_group->tree_lock); - break; - } - - entry = tree_search_offset(block_group, start, 0, 1); - if (!entry) - entry = tree_search_offset(block_group, - offset_to_bitmap(block_group, - start), - 1, 1); - - if (!entry || entry->offset >= end) { - spin_unlock(&block_group->tree_lock); - break; - } - - if (entry->bitmap) { - ret = search_bitmap(block_group, entry, &start, &bytes); - if (!ret) { - if (start >= end) { - spin_unlock(&block_group->tree_lock); - break; - } - bytes = min(bytes, end - start); - bitmap_clear_bits(block_group, entry, - start, bytes); - if (entry->bytes == 0) - free_bitmap(block_group, entry); - } else { - start = entry->offset + BITS_PER_BITMAP * - block_group->sectorsize; - spin_unlock(&block_group->tree_lock); - ret = 0; - continue; - } - } else { - start = entry->offset; - bytes = min(entry->bytes, end - start); - unlink_free_space(block_group, entry); - kfree(entry); - } - - spin_unlock(&block_group->tree_lock); - - if (bytes >= minlen) { - int update_ret; - update_ret = btrfs_update_reserved_bytes(block_group, - bytes, 1, 1); - - ret = btrfs_error_discard_extent(fs_info->extent_root, - start, - bytes, - &actually_trimmed); - - btrfs_add_free_space(block_group, - start, bytes); - if (!update_ret) - btrfs_update_reserved_bytes(block_group, - bytes, 0, 1); - - if (ret) - break; - *trimmed += actually_trimmed; - } - start += bytes; - bytes = 0; - - if (fatal_signal_pending(current)) { - ret = -ERESTARTSYS; - break; - } - - cond_resched(); - } - - return ret; -} diff --git a/trunk/fs/btrfs/free-space-cache.h b/trunk/fs/btrfs/free-space-cache.h index 65c3b935289f..e49ca5c321b5 100644 --- a/trunk/fs/btrfs/free-space-cache.h +++ b/trunk/fs/btrfs/free-space-cache.h @@ -68,6 +68,4 @@ u64 btrfs_alloc_from_cluster(struct btrfs_block_group_cache *block_group, int btrfs_return_cluster_to_free_space( struct btrfs_block_group_cache *block_group, struct btrfs_free_cluster *cluster); -int btrfs_trim_block_group(struct btrfs_block_group_cache *block_group, - u64 *trimmed, u64 start, u64 end, u64 minlen); #endif diff --git a/trunk/fs/btrfs/inode-map.c b/trunk/fs/btrfs/inode-map.c index c05a08f4c411..c56eb5909172 100644 --- a/trunk/fs/btrfs/inode-map.c +++ b/trunk/fs/btrfs/inode-map.c @@ -30,8 +30,7 @@ int btrfs_find_highest_inode(struct btrfs_root *root, u64 *objectid) int slot; path = btrfs_alloc_path(); - if (!path) - return -ENOMEM; + BUG_ON(!path); search_key.objectid = BTRFS_LAST_FREE_OBJECTID; search_key.type = -1; diff --git a/trunk/fs/btrfs/inode.c b/trunk/fs/btrfs/inode.c index 93c28a1d6bdc..119520bdb9a5 100644 --- a/trunk/fs/btrfs/inode.c +++ b/trunk/fs/btrfs/inode.c @@ -50,7 +50,6 @@ #include "tree-log.h" #include "compression.h" #include "locking.h" -#include "free-space-cache.h" struct btrfs_iget_args { u64 ino; @@ -71,7 +70,6 @@ static struct kmem_cache *btrfs_inode_cachep; struct kmem_cache *btrfs_trans_handle_cachep; struct kmem_cache *btrfs_transaction_cachep; struct kmem_cache *btrfs_path_cachep; -struct kmem_cache *btrfs_free_space_cachep; #define S_SHIFT 12 static unsigned char btrfs_type_by_mode[S_IFMT >> S_SHIFT] = { @@ -84,8 +82,7 @@ static unsigned char btrfs_type_by_mode[S_IFMT >> S_SHIFT] = { [S_IFLNK >> S_SHIFT] = BTRFS_FT_SYMLINK, }; -static int btrfs_setsize(struct inode *inode, loff_t newsize); -static int btrfs_truncate(struct inode *inode); +static void btrfs_truncate(struct inode *inode); static int btrfs_finish_ordered_io(struct inode *inode, u64 start, u64 end); static noinline int cow_file_range(struct inode *inode, struct page *locked_page, @@ -291,7 +288,6 @@ static noinline int add_async_extent(struct async_cow *cow, struct async_extent *async_extent; async_extent = kmalloc(sizeof(*async_extent), GFP_NOFS); - BUG_ON(!async_extent); async_extent->start = start; async_extent->ram_size = ram_size; async_extent->compressed_size = compressed_size; @@ -386,11 +382,9 @@ static noinline int compress_file_range(struct inode *inode, */ if (!(BTRFS_I(inode)->flags & BTRFS_INODE_NOCOMPRESS) && (btrfs_test_opt(root, COMPRESS) || - (BTRFS_I(inode)->force_compress) || - (BTRFS_I(inode)->flags & BTRFS_INODE_COMPRESS))) { + (BTRFS_I(inode)->force_compress))) { WARN_ON(pages); pages = kzalloc(sizeof(struct page *) * nr_pages, GFP_NOFS); - BUG_ON(!pages); if (BTRFS_I(inode)->force_compress) compress_type = BTRFS_I(inode)->force_compress; @@ -1260,8 +1254,7 @@ static int run_delalloc_range(struct inode *inode, struct page *locked_page, ret = run_delalloc_nocow(inode, locked_page, start, end, page_started, 0, nr_written); else if (!btrfs_test_opt(root, COMPRESS) && - !(BTRFS_I(inode)->force_compress) && - !(BTRFS_I(inode)->flags & BTRFS_INODE_COMPRESS)) + !(BTRFS_I(inode)->force_compress)) ret = cow_file_range(inode, locked_page, start, end, page_started, nr_written, 1); else @@ -1468,11 +1461,8 @@ static int btrfs_submit_bio_hook(struct inode *inode, int rw, struct bio *bio, if (bio_flags & EXTENT_BIO_COMPRESSED) { return btrfs_submit_compressed_read(inode, bio, mirror_num, bio_flags); - } else if (!skip_sum) { - ret = btrfs_lookup_bio_sums(root, inode, bio, NULL); - if (ret) - return ret; - } + } else if (!skip_sum) + btrfs_lookup_bio_sums(root, inode, bio, NULL); goto mapit; } else if (!skip_sum) { /* csum items have already been cloned */ @@ -1795,8 +1785,6 @@ static int btrfs_finish_ordered_io(struct inode *inode, u64 start, u64 end) static int btrfs_writepage_end_io_hook(struct page *page, u64 start, u64 end, struct extent_state *state, int uptodate) { - trace_btrfs_writepage_end_io_hook(page, start, end, uptodate); - ClearPagePrivate2(page); return btrfs_finish_ordered_io(page->mapping->host, start, end); } @@ -1907,10 +1895,10 @@ static int btrfs_io_failed_hook(struct bio *failed_bio, else rw = READ; - ret = BTRFS_I(inode)->io_tree.ops->submit_bio_hook(inode, rw, bio, + BTRFS_I(inode)->io_tree.ops->submit_bio_hook(inode, rw, bio, failrec->last_mirror, failrec->bio_flags, 0); - return ret; + return 0; } /* @@ -2294,7 +2282,7 @@ int btrfs_orphan_del(struct btrfs_trans_handle *trans, struct inode *inode) * this cleans up any orphans that may be left on the list from the last use * of this root. */ -int btrfs_orphan_cleanup(struct btrfs_root *root) +void btrfs_orphan_cleanup(struct btrfs_root *root) { struct btrfs_path *path; struct extent_buffer *leaf; @@ -2304,13 +2292,10 @@ int btrfs_orphan_cleanup(struct btrfs_root *root) int ret = 0, nr_unlink = 0, nr_truncate = 0; if (cmpxchg(&root->orphan_cleanup_state, 0, ORPHAN_CLEANUP_STARTED)) - return 0; + return; path = btrfs_alloc_path(); - if (!path) { - ret = -ENOMEM; - goto out; - } + BUG_ON(!path); path->reada = -1; key.objectid = BTRFS_ORPHAN_OBJECTID; @@ -2319,8 +2304,11 @@ int btrfs_orphan_cleanup(struct btrfs_root *root) while (1) { ret = btrfs_search_slot(NULL, root, &key, path, 0, 0); - if (ret < 0) - goto out; + if (ret < 0) { + printk(KERN_ERR "Error searching slot for orphan: %d" + "\n", ret); + break; + } /* * if ret == 0 means we found what we were searching for, which @@ -2328,7 +2316,6 @@ int btrfs_orphan_cleanup(struct btrfs_root *root) * find the key and see if we have stuff that matches */ if (ret > 0) { - ret = 0; if (path->slots[0] == 0) break; path->slots[0]--; @@ -2356,10 +2343,7 @@ int btrfs_orphan_cleanup(struct btrfs_root *root) found_key.type = BTRFS_INODE_ITEM_KEY; found_key.offset = 0; inode = btrfs_iget(root->fs_info->sb, &found_key, root, NULL); - if (IS_ERR(inode)) { - ret = PTR_ERR(inode); - goto out; - } + BUG_ON(IS_ERR(inode)); /* * add this inode to the orphan list so btrfs_orphan_del does @@ -2377,10 +2361,7 @@ int btrfs_orphan_cleanup(struct btrfs_root *root) */ if (is_bad_inode(inode)) { trans = btrfs_start_transaction(root, 0); - if (IS_ERR(trans)) { - ret = PTR_ERR(trans); - goto out; - } + BUG_ON(IS_ERR(trans)); btrfs_orphan_del(trans, inode); btrfs_end_transaction(trans, root); iput(inode); @@ -2389,22 +2370,17 @@ int btrfs_orphan_cleanup(struct btrfs_root *root) /* if we have links, this was a truncate, lets do that */ if (inode->i_nlink) { - if (!S_ISREG(inode->i_mode)) { - WARN_ON(1); - iput(inode); - continue; - } nr_truncate++; - ret = btrfs_truncate(inode); + btrfs_truncate(inode); } else { nr_unlink++; } /* this will do delete_inode and everything for us */ iput(inode); - if (ret) - goto out; } + btrfs_free_path(path); + root->orphan_cleanup_state = ORPHAN_CLEANUP_DONE; if (root->orphan_block_rsv) @@ -2413,20 +2389,14 @@ int btrfs_orphan_cleanup(struct btrfs_root *root) if (root->orphan_block_rsv || root->orphan_item_inserted) { trans = btrfs_join_transaction(root, 1); - if (!IS_ERR(trans)) - btrfs_end_transaction(trans, root); + BUG_ON(IS_ERR(trans)); + btrfs_end_transaction(trans, root); } if (nr_unlink) printk(KERN_INFO "btrfs: unlinked %d orphans\n", nr_unlink); if (nr_truncate) printk(KERN_INFO "btrfs: truncated %d orphans\n", nr_truncate); - -out: - if (ret) - printk(KERN_CRIT "btrfs: could not do orphan cleanup %d\n", ret); - btrfs_free_path(path); - return ret; } /* @@ -2537,8 +2507,6 @@ static void btrfs_read_locked_inode(struct inode *inode) BTRFS_I(inode)->flags = btrfs_inode_flags(leaf, inode_item); alloc_group_block = btrfs_inode_block_group(leaf, inode_item); - if (location.objectid == BTRFS_FREE_SPACE_OBJECTID) - inode->i_mapping->flags &= ~__GFP_FS; /* * try to precache a NULL acl entry for files that don't have @@ -2667,10 +2635,10 @@ noinline int btrfs_update_inode(struct btrfs_trans_handle *trans, * recovery code. It remove a link in a directory with a given name, and * also drops the back refs in the inode to the directory */ -static int __btrfs_unlink_inode(struct btrfs_trans_handle *trans, - struct btrfs_root *root, - struct inode *dir, struct inode *inode, - const char *name, int name_len) +int btrfs_unlink_inode(struct btrfs_trans_handle *trans, + struct btrfs_root *root, + struct inode *dir, struct inode *inode, + const char *name, int name_len) { struct btrfs_path *path; int ret = 0; @@ -2742,25 +2710,12 @@ static int __btrfs_unlink_inode(struct btrfs_trans_handle *trans, btrfs_i_size_write(dir, dir->i_size - name_len * 2); inode->i_ctime = dir->i_mtime = dir->i_ctime = CURRENT_TIME; btrfs_update_inode(trans, root, dir); + btrfs_drop_nlink(inode); + ret = btrfs_update_inode(trans, root, inode); out: return ret; } -int btrfs_unlink_inode(struct btrfs_trans_handle *trans, - struct btrfs_root *root, - struct inode *dir, struct inode *inode, - const char *name, int name_len) -{ - int ret; - ret = __btrfs_unlink_inode(trans, root, dir, inode, name, name_len); - if (!ret) { - btrfs_drop_nlink(inode); - ret = btrfs_update_inode(trans, root, inode); - } - return ret; -} - - /* helper to check if there is any shared block in the path */ static int check_path_shared(struct btrfs_root *root, struct btrfs_path *path) @@ -3582,13 +3537,7 @@ static int btrfs_truncate_page(struct address_space *mapping, loff_t from) return ret; } -/* - * This function puts in dummy file extents for the area we're creating a hole - * for. So if we are truncating this file to a larger size we need to insert - * these file extents so that btrfs_get_extent will return a EXTENT_MAP_HOLE for - * the range between oldsize and size - */ -int btrfs_cont_expand(struct inode *inode, loff_t oldsize, loff_t size) +int btrfs_cont_expand(struct inode *inode, loff_t size) { struct btrfs_trans_handle *trans; struct btrfs_root *root = BTRFS_I(inode)->root; @@ -3596,7 +3545,7 @@ int btrfs_cont_expand(struct inode *inode, loff_t oldsize, loff_t size) struct extent_map *em = NULL; struct extent_state *cached_state = NULL; u64 mask = root->sectorsize - 1; - u64 hole_start = (oldsize + mask) & ~mask; + u64 hole_start = (inode->i_size + mask) & ~mask; u64 block_end = (size + mask) & ~mask; u64 last_byte; u64 cur_offset; @@ -3641,15 +3590,13 @@ int btrfs_cont_expand(struct inode *inode, loff_t oldsize, loff_t size) err = btrfs_drop_extents(trans, inode, cur_offset, cur_offset + hole_size, &hint_byte, 1); - if (err) - break; + BUG_ON(err); err = btrfs_insert_file_extent(trans, root, inode->i_ino, cur_offset, 0, 0, hole_size, 0, hole_size, 0, 0, 0); - if (err) - break; + BUG_ON(err); btrfs_drop_extent_cache(inode, hole_start, last_byte - 1, 0); @@ -3669,41 +3616,81 @@ int btrfs_cont_expand(struct inode *inode, loff_t oldsize, loff_t size) return err; } -static int btrfs_setsize(struct inode *inode, loff_t newsize) +static int btrfs_setattr_size(struct inode *inode, struct iattr *attr) { - loff_t oldsize = i_size_read(inode); + struct btrfs_root *root = BTRFS_I(inode)->root; + struct btrfs_trans_handle *trans; + unsigned long nr; int ret; - if (newsize == oldsize) + if (attr->ia_size == inode->i_size) return 0; - if (newsize > oldsize) { - i_size_write(inode, newsize); - btrfs_ordered_update_i_size(inode, i_size_read(inode), NULL); - truncate_pagecache(inode, oldsize, newsize); - ret = btrfs_cont_expand(inode, oldsize, newsize); + if (attr->ia_size > inode->i_size) { + unsigned long limit; + limit = current->signal->rlim[RLIMIT_FSIZE].rlim_cur; + if (attr->ia_size > inode->i_sb->s_maxbytes) + return -EFBIG; + if (limit != RLIM_INFINITY && attr->ia_size > limit) { + send_sig(SIGXFSZ, current, 0); + return -EFBIG; + } + } + + trans = btrfs_start_transaction(root, 5); + if (IS_ERR(trans)) + return PTR_ERR(trans); + + btrfs_set_trans_block_group(trans, inode); + + ret = btrfs_orphan_add(trans, inode); + BUG_ON(ret); + + nr = trans->blocks_used; + btrfs_end_transaction(trans, root); + btrfs_btree_balance_dirty(root, nr); + + if (attr->ia_size > inode->i_size) { + ret = btrfs_cont_expand(inode, attr->ia_size); if (ret) { - btrfs_setsize(inode, oldsize); + btrfs_truncate(inode); return ret; } - mark_inode_dirty(inode); - } else { + i_size_write(inode, attr->ia_size); + btrfs_ordered_update_i_size(inode, inode->i_size, NULL); - /* - * We're truncating a file that used to have good data down to - * zero. Make sure it gets into the ordered flush list so that - * any new writes get down to disk quickly. - */ - if (newsize == 0) - BTRFS_I(inode)->ordered_data_close = 1; + trans = btrfs_start_transaction(root, 0); + BUG_ON(IS_ERR(trans)); + btrfs_set_trans_block_group(trans, inode); + trans->block_rsv = root->orphan_block_rsv; + BUG_ON(!trans->block_rsv); - /* we don't support swapfiles, so vmtruncate shouldn't fail */ - truncate_setsize(inode, newsize); - ret = btrfs_truncate(inode); + ret = btrfs_update_inode(trans, root, inode); + BUG_ON(ret); + if (inode->i_nlink > 0) { + ret = btrfs_orphan_del(trans, inode); + BUG_ON(ret); + } + nr = trans->blocks_used; + btrfs_end_transaction(trans, root); + btrfs_btree_balance_dirty(root, nr); + return 0; } - return ret; + /* + * We're truncating a file that used to have good data down to + * zero. Make sure it gets into the ordered flush list so that + * any new writes get down to disk quickly. + */ + if (attr->ia_size == 0) + BTRFS_I(inode)->ordered_data_close = 1; + + /* we don't support swapfiles, so vmtruncate shouldn't fail */ + ret = vmtruncate(inode, attr->ia_size); + BUG_ON(ret); + + return 0; } static int btrfs_setattr(struct dentry *dentry, struct iattr *attr) @@ -3720,7 +3707,7 @@ static int btrfs_setattr(struct dentry *dentry, struct iattr *attr) return err; if (S_ISREG(inode->i_mode) && (attr->ia_valid & ATTR_SIZE)) { - err = btrfs_setsize(inode, attr->ia_size); + err = btrfs_setattr_size(inode, attr); if (err) return err; } @@ -3743,8 +3730,6 @@ void btrfs_evict_inode(struct inode *inode) unsigned long nr; int ret; - trace_btrfs_inode_evict(inode); - truncate_inode_pages(&inode->i_data, 0); if (inode->i_nlink && (btrfs_root_refs(&root->root_item) != 0 || root == root->fs_info->tree_root)) @@ -4087,6 +4072,7 @@ struct inode *btrfs_iget(struct super_block *s, struct btrfs_key *location, BTRFS_I(inode)->root = root; memcpy(&BTRFS_I(inode)->location, location, sizeof(*location)); btrfs_read_locked_inode(inode); + inode_tree_add(inode); unlock_new_inode(inode); if (new) @@ -4161,10 +4147,8 @@ struct inode *btrfs_lookup_dentry(struct inode *dir, struct dentry *dentry) if (!IS_ERR(inode) && root != sub_root) { down_read(&root->fs_info->cleanup_work_sem); if (!(inode->i_sb->s_flags & MS_RDONLY)) - ret = btrfs_orphan_cleanup(sub_root); + btrfs_orphan_cleanup(sub_root); up_read(&root->fs_info->cleanup_work_sem); - if (ret) - inode = ERR_PTR(ret); } return inode; @@ -4298,9 +4282,6 @@ static int btrfs_real_readdir(struct file *filp, void *dirent, while (di_cur < di_total) { struct btrfs_key location; - if (verify_dir_item(root, leaf, di)) - break; - name_len = btrfs_dir_name_len(leaf, di); if (name_len <= sizeof(tmp_name)) { name_ptr = tmp_name; @@ -4536,8 +4517,6 @@ static struct inode *btrfs_new_inode(struct btrfs_trans_handle *trans, return ERR_PTR(-ENOMEM); if (dir) { - trace_btrfs_inode_request(dir); - ret = btrfs_set_inode_index(dir, index); if (ret) { iput(inode); @@ -4606,16 +4585,12 @@ static struct inode *btrfs_new_inode(struct btrfs_trans_handle *trans, if ((mode & S_IFREG)) { if (btrfs_test_opt(root, NODATASUM)) BTRFS_I(inode)->flags |= BTRFS_INODE_NODATASUM; - if (btrfs_test_opt(root, NODATACOW) || - (BTRFS_I(dir)->flags & BTRFS_INODE_NODATACOW)) + if (btrfs_test_opt(root, NODATACOW)) BTRFS_I(inode)->flags |= BTRFS_INODE_NODATACOW; } insert_inode_hash(inode); inode_tree_add(inode); - - trace_btrfs_inode_new(inode); - return inode; fail: if (dir) @@ -4834,10 +4809,7 @@ static int btrfs_link(struct dentry *old_dentry, struct inode *dir, /* do not allow sys_link's with other subvols of the same device */ if (root->objectid != BTRFS_I(inode)->root->objectid) - return -EXDEV; - - if (inode->i_nlink == ~0U) - return -EMLINK; + return -EPERM; btrfs_inc_nlink(inode); inode->i_ctime = CURRENT_TIME; @@ -5293,9 +5265,6 @@ struct extent_map *btrfs_get_extent(struct inode *inode, struct page *page, } write_unlock(&em_tree->lock); out: - - trace_btrfs_get_extent(root, em); - if (path) btrfs_free_path(path); if (trans) { @@ -5779,10 +5748,6 @@ static void btrfs_endio_direct_read(struct bio *bio, int err) kfree(dip->csums); kfree(dip); - - /* If we had a csum failure make sure to clear the uptodate flag */ - if (err) - clear_bit(BIO_UPTODATE, &bio->bi_flags); dio_end_io(bio, err); } @@ -5884,10 +5849,6 @@ static void btrfs_endio_direct_write(struct bio *bio, int err) kfree(dip->csums); kfree(dip); - - /* If we had an error make sure to clear the uptodate flag */ - if (err) - clear_bit(BIO_UPTODATE, &bio->bi_flags); dio_end_io(bio, err); } @@ -5961,12 +5922,9 @@ static inline int __btrfs_submit_dio_bio(struct bio *bio, struct inode *inode, __btrfs_submit_bio_start_direct_io, __btrfs_submit_bio_done); goto err; - } else if (!skip_sum) { - ret = btrfs_lookup_bio_sums_dio(root, inode, bio, + } else if (!skip_sum) + btrfs_lookup_bio_sums_dio(root, inode, bio, file_offset, csums); - if (ret) - goto err; - } ret = btrfs_map_bio(root, rw, bio, 0, 1); err: @@ -5990,7 +5948,6 @@ static int btrfs_submit_direct_hook(int rw, struct btrfs_dio_private *dip, int nr_pages = 0; u32 *csums = dip->csums; int ret = 0; - int write = rw & REQ_WRITE; bio = btrfs_dio_bio_alloc(orig_bio->bi_bdev, start_sector, GFP_NOFS); if (!bio) @@ -6027,8 +5984,7 @@ static int btrfs_submit_direct_hook(int rw, struct btrfs_dio_private *dip, goto out_err; } - /* Write's use the ordered csums */ - if (!write && !skip_sum) + if (!skip_sum) csums = csums + nr_pages; start_sector += submit_len >> 9; file_offset += submit_len; @@ -6096,8 +6052,7 @@ static void btrfs_submit_direct(int rw, struct bio *bio, struct inode *inode, } dip->csums = NULL; - /* Write's use the ordered csum stuff, so we don't need dip->csums */ - if (!write && !skip_sum) { + if (!skip_sum) { dip->csums = kmalloc(sizeof(u32) * bio->bi_vcnt, GFP_NOFS); if (!dip->csums) { kfree(dip); @@ -6519,42 +6474,28 @@ int btrfs_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf) return ret; } -static int btrfs_truncate(struct inode *inode) +static void btrfs_truncate(struct inode *inode) { struct btrfs_root *root = BTRFS_I(inode)->root; int ret; - int err = 0; struct btrfs_trans_handle *trans; unsigned long nr; u64 mask = root->sectorsize - 1; + if (!S_ISREG(inode->i_mode)) { + WARN_ON(1); + return; + } + ret = btrfs_truncate_page(inode->i_mapping, inode->i_size); if (ret) - return ret; + return; btrfs_wait_ordered_range(inode, inode->i_size & (~mask), (u64)-1); btrfs_ordered_update_i_size(inode, inode->i_size, NULL); - trans = btrfs_start_transaction(root, 5); - if (IS_ERR(trans)) - return PTR_ERR(trans); - - btrfs_set_trans_block_group(trans, inode); - - ret = btrfs_orphan_add(trans, inode); - if (ret) { - btrfs_end_transaction(trans, root); - return ret; - } - - nr = trans->blocks_used; - btrfs_end_transaction(trans, root); - btrfs_btree_balance_dirty(root, nr); - - /* Now start a transaction for the truncate */ trans = btrfs_start_transaction(root, 0); - if (IS_ERR(trans)) - return PTR_ERR(trans); + BUG_ON(IS_ERR(trans)); btrfs_set_trans_block_group(trans, inode); trans->block_rsv = root->orphan_block_rsv; @@ -6581,38 +6522,29 @@ static int btrfs_truncate(struct inode *inode) while (1) { if (!trans) { trans = btrfs_start_transaction(root, 0); - if (IS_ERR(trans)) - return PTR_ERR(trans); + BUG_ON(IS_ERR(trans)); btrfs_set_trans_block_group(trans, inode); trans->block_rsv = root->orphan_block_rsv; } ret = btrfs_block_rsv_check(trans, root, root->orphan_block_rsv, 0, 5); - if (ret == -EAGAIN) { + if (ret) { + BUG_ON(ret != -EAGAIN); ret = btrfs_commit_transaction(trans, root); - if (ret) - return ret; + BUG_ON(ret); trans = NULL; continue; - } else if (ret) { - err = ret; - break; } ret = btrfs_truncate_inode_items(trans, root, inode, inode->i_size, BTRFS_EXTENT_DATA_KEY); - if (ret != -EAGAIN) { - err = ret; + if (ret != -EAGAIN) break; - } ret = btrfs_update_inode(trans, root, inode); - if (ret) { - err = ret; - break; - } + BUG_ON(ret); nr = trans->blocks_used; btrfs_end_transaction(trans, root); @@ -6622,27 +6554,16 @@ static int btrfs_truncate(struct inode *inode) if (ret == 0 && inode->i_nlink > 0) { ret = btrfs_orphan_del(trans, inode); - if (ret) - err = ret; - } else if (ret && inode->i_nlink > 0) { - /* - * Failed to do the truncate, remove us from the in memory - * orphan list. - */ - ret = btrfs_orphan_del(NULL, inode); + BUG_ON(ret); } ret = btrfs_update_inode(trans, root, inode); - if (ret && !err) - err = ret; + BUG_ON(ret); nr = trans->blocks_used; ret = btrfs_end_transaction_throttle(trans, root); - if (ret && !err) - err = ret; + BUG_ON(ret); btrfs_btree_balance_dirty(root, nr); - - return err; } /* @@ -6709,8 +6630,9 @@ struct inode *btrfs_alloc_inode(struct super_block *sb) ei->index_cnt = (u64)-1; ei->last_unlink_trans = 0; + spin_lock_init(&ei->accounting_lock); atomic_set(&ei->outstanding_extents, 0); - atomic_set(&ei->reserved_extents, 0); + ei->reserved_extents = 0; ei->ordered_data_close = 0; ei->orphan_meta_reserved = 0; @@ -6746,7 +6668,7 @@ void btrfs_destroy_inode(struct inode *inode) WARN_ON(!list_empty(&inode->i_dentry)); WARN_ON(inode->i_data.nrpages); WARN_ON(atomic_read(&BTRFS_I(inode)->outstanding_extents)); - WARN_ON(atomic_read(&BTRFS_I(inode)->reserved_extents)); + WARN_ON(BTRFS_I(inode)->reserved_extents); /* * This can happen where we create an inode, but somebody else also @@ -6838,8 +6760,6 @@ void btrfs_destroy_cachep(void) kmem_cache_destroy(btrfs_transaction_cachep); if (btrfs_path_cachep) kmem_cache_destroy(btrfs_path_cachep); - if (btrfs_free_space_cachep) - kmem_cache_destroy(btrfs_free_space_cachep); } int btrfs_init_cachep(void) @@ -6868,12 +6788,6 @@ int btrfs_init_cachep(void) if (!btrfs_path_cachep) goto fail; - btrfs_free_space_cachep = kmem_cache_create("btrfs_free_space_cache", - sizeof(struct btrfs_free_space), 0, - SLAB_RECLAIM_ACCOUNT | SLAB_MEM_SPREAD, NULL); - if (!btrfs_free_space_cachep) - goto fail; - return 0; fail: btrfs_destroy_cachep(); @@ -6892,26 +6806,6 @@ static int btrfs_getattr(struct vfsmount *mnt, return 0; } -/* - * If a file is moved, it will inherit the cow and compression flags of the new - * directory. - */ -static void fixup_inode_flags(struct inode *dir, struct inode *inode) -{ - struct btrfs_inode *b_dir = BTRFS_I(dir); - struct btrfs_inode *b_inode = BTRFS_I(inode); - - if (b_dir->flags & BTRFS_INODE_NODATACOW) - b_inode->flags |= BTRFS_INODE_NODATACOW; - else - b_inode->flags &= ~BTRFS_INODE_NODATACOW; - - if (b_dir->flags & BTRFS_INODE_COMPRESS) - b_inode->flags |= BTRFS_INODE_COMPRESS; - else - b_inode->flags &= ~BTRFS_INODE_COMPRESS; -} - static int btrfs_rename(struct inode *old_dir, struct dentry *old_dentry, struct inode *new_dir, struct dentry *new_dentry) { @@ -7014,12 +6908,11 @@ static int btrfs_rename(struct inode *old_dir, struct dentry *old_dentry, old_dentry->d_name.name, old_dentry->d_name.len); } else { - ret = __btrfs_unlink_inode(trans, root, old_dir, - old_dentry->d_inode, - old_dentry->d_name.name, - old_dentry->d_name.len); - if (!ret) - ret = btrfs_update_inode(trans, root, old_inode); + btrfs_inc_nlink(old_dentry->d_inode); + ret = btrfs_unlink_inode(trans, root, old_dir, + old_dentry->d_inode, + old_dentry->d_name.name, + old_dentry->d_name.len); } BUG_ON(ret); @@ -7046,8 +6939,6 @@ static int btrfs_rename(struct inode *old_dir, struct dentry *old_dentry, } } - fixup_inode_flags(new_dir, old_inode); - ret = btrfs_add_link(trans, new_dir, old_inode, new_dentry->d_name.name, new_dentry->d_name.len, 0, index); @@ -7464,6 +7355,7 @@ static const struct address_space_operations btrfs_symlink_aops = { }; static const struct inode_operations btrfs_file_inode_operations = { + .truncate = btrfs_truncate, .getattr = btrfs_getattr, .setattr = btrfs_setattr, .setxattr = btrfs_setxattr, diff --git a/trunk/fs/btrfs/ioctl.c b/trunk/fs/btrfs/ioctl.c index 7c07fe26b7cf..d1bace3df9b6 100644 --- a/trunk/fs/btrfs/ioctl.c +++ b/trunk/fs/btrfs/ioctl.c @@ -40,7 +40,6 @@ #include #include #include -#include #include "compat.h" #include "ctree.h" #include "disk-io.h" @@ -139,24 +138,6 @@ static int btrfs_ioctl_getflags(struct file *file, void __user *arg) return 0; } -static int check_flags(unsigned int flags) -{ - if (flags & ~(FS_IMMUTABLE_FL | FS_APPEND_FL | \ - FS_NOATIME_FL | FS_NODUMP_FL | \ - FS_SYNC_FL | FS_DIRSYNC_FL | \ - FS_NOCOMP_FL | FS_COMPR_FL | \ - FS_NOCOW_FL | FS_COW_FL)) - return -EOPNOTSUPP; - - if ((flags & FS_NOCOMP_FL) && (flags & FS_COMPR_FL)) - return -EINVAL; - - if ((flags & FS_NOCOW_FL) && (flags & FS_COW_FL)) - return -EINVAL; - - return 0; -} - static int btrfs_ioctl_setflags(struct file *file, void __user *arg) { struct inode *inode = file->f_path.dentry->d_inode; @@ -172,9 +153,10 @@ static int btrfs_ioctl_setflags(struct file *file, void __user *arg) if (copy_from_user(&flags, arg, sizeof(flags))) return -EFAULT; - ret = check_flags(flags); - if (ret) - return ret; + if (flags & ~(FS_IMMUTABLE_FL | FS_APPEND_FL | \ + FS_NOATIME_FL | FS_NODUMP_FL | \ + FS_SYNC_FL | FS_DIRSYNC_FL)) + return -EOPNOTSUPP; if (!inode_owner_or_capable(inode)) return -EACCES; @@ -219,22 +201,6 @@ static int btrfs_ioctl_setflags(struct file *file, void __user *arg) else ip->flags &= ~BTRFS_INODE_DIRSYNC; - /* - * The COMPRESS flag can only be changed by users, while the NOCOMPRESS - * flag may be changed automatically if compression code won't make - * things smaller. - */ - if (flags & FS_NOCOMP_FL) { - ip->flags &= ~BTRFS_INODE_COMPRESS; - ip->flags |= BTRFS_INODE_NOCOMPRESS; - } else if (flags & FS_COMPR_FL) { - ip->flags |= BTRFS_INODE_COMPRESS; - ip->flags &= ~BTRFS_INODE_NOCOMPRESS; - } - if (flags & FS_NOCOW_FL) - ip->flags |= BTRFS_INODE_NODATACOW; - else if (flags & FS_COW_FL) - ip->flags &= ~BTRFS_INODE_NODATACOW; trans = btrfs_join_transaction(root, 1); BUG_ON(IS_ERR(trans)); @@ -247,11 +213,9 @@ static int btrfs_ioctl_setflags(struct file *file, void __user *arg) btrfs_end_transaction(trans, root); mnt_drop_write(file->f_path.mnt); - - ret = 0; out_unlock: mutex_unlock(&inode->i_mutex); - return ret; + return 0; } static int btrfs_ioctl_getversion(struct file *file, int __user *arg) @@ -261,49 +225,6 @@ static int btrfs_ioctl_getversion(struct file *file, int __user *arg) return put_user(inode->i_generation, arg); } -static noinline int btrfs_ioctl_fitrim(struct file *file, void __user *arg) -{ - struct btrfs_root *root = fdentry(file)->d_sb->s_fs_info; - struct btrfs_fs_info *fs_info = root->fs_info; - struct btrfs_device *device; - struct request_queue *q; - struct fstrim_range range; - u64 minlen = ULLONG_MAX; - u64 num_devices = 0; - int ret; - - if (!capable(CAP_SYS_ADMIN)) - return -EPERM; - - mutex_lock(&fs_info->fs_devices->device_list_mutex); - list_for_each_entry(device, &fs_info->fs_devices->devices, dev_list) { - if (!device->bdev) - continue; - q = bdev_get_queue(device->bdev); - if (blk_queue_discard(q)) { - num_devices++; - minlen = min((u64)q->limits.discard_granularity, - minlen); - } - } - mutex_unlock(&fs_info->fs_devices->device_list_mutex); - if (!num_devices) - return -EOPNOTSUPP; - - if (copy_from_user(&range, arg, sizeof(range))) - return -EFAULT; - - range.minlen = max(range.minlen, minlen); - ret = btrfs_trim_fs(root, &range); - if (ret < 0) - return ret; - - if (copy_to_user(arg, &range, sizeof(range))) - return -EFAULT; - - return 0; -} - static noinline int create_subvol(struct btrfs_root *root, struct dentry *dentry, char *name, int namelen, @@ -488,9 +409,7 @@ static int create_snapshot(struct btrfs_root *root, struct dentry *dentry, if (ret) goto fail; - ret = btrfs_orphan_cleanup(pending_snapshot->snap); - if (ret) - goto fail; + btrfs_orphan_cleanup(pending_snapshot->snap); parent = dget_parent(dentry); inode = btrfs_lookup_dentry(parent->d_inode, dentry); @@ -2429,15 +2348,12 @@ static noinline long btrfs_ioctl_start_sync(struct file *file, void __user *argp struct btrfs_root *root = BTRFS_I(file->f_dentry->d_inode)->root; struct btrfs_trans_handle *trans; u64 transid; - int ret; trans = btrfs_start_transaction(root, 0); if (IS_ERR(trans)) return PTR_ERR(trans); transid = trans->transid; - ret = btrfs_commit_transaction_async(trans, root, 0); - if (ret) - return ret; + btrfs_commit_transaction_async(trans, root, 0); if (argp) if (copy_to_user(argp, &transid, sizeof(transid))) @@ -2472,8 +2388,6 @@ long btrfs_ioctl(struct file *file, unsigned int return btrfs_ioctl_setflags(file, argp); case FS_IOC_GETVERSION: return btrfs_ioctl_getversion(file, argp); - case FITRIM: - return btrfs_ioctl_fitrim(file, argp); case BTRFS_IOC_SNAP_CREATE: return btrfs_ioctl_snap_create(file, argp, 0); case BTRFS_IOC_SNAP_CREATE_V2: diff --git a/trunk/fs/btrfs/ordered-data.c b/trunk/fs/btrfs/ordered-data.c index a1c940425307..083a55477375 100644 --- a/trunk/fs/btrfs/ordered-data.c +++ b/trunk/fs/btrfs/ordered-data.c @@ -202,8 +202,6 @@ static int __btrfs_add_ordered_extent(struct inode *inode, u64 file_offset, INIT_LIST_HEAD(&entry->list); INIT_LIST_HEAD(&entry->root_extent_list); - trace_btrfs_ordered_extent_add(inode, entry); - spin_lock(&tree->lock); node = tree_insert(&tree->tree, file_offset, &entry->rb_node); @@ -389,8 +387,6 @@ int btrfs_put_ordered_extent(struct btrfs_ordered_extent *entry) struct list_head *cur; struct btrfs_ordered_sum *sum; - trace_btrfs_ordered_extent_put(entry->inode, entry); - if (atomic_dec_and_test(&entry->refs)) { while (!list_empty(&entry->list)) { cur = entry->list.next; @@ -424,8 +420,6 @@ static int __btrfs_remove_ordered_extent(struct inode *inode, spin_lock(&root->fs_info->ordered_extent_lock); list_del_init(&entry->root_extent_list); - trace_btrfs_ordered_extent_remove(inode, entry); - /* * we have no more ordered extents for this inode and * no dirty pages. We can safely remove it from the @@ -591,8 +585,6 @@ void btrfs_start_ordered_extent(struct inode *inode, u64 start = entry->file_offset; u64 end = start + entry->len - 1; - trace_btrfs_ordered_extent_start(inode, entry); - /* * pages in the range can be dirty, clean or writeback. We * start IO on any dirty ones so the wait doesn't stall waiting diff --git a/trunk/fs/btrfs/relocation.c b/trunk/fs/btrfs/relocation.c index 58250e09eb05..31ade5802ae8 100644 --- a/trunk/fs/btrfs/relocation.c +++ b/trunk/fs/btrfs/relocation.c @@ -1724,7 +1724,6 @@ int replace_path(struct btrfs_trans_handle *trans, eb = read_tree_block(dest, old_bytenr, blocksize, old_ptr_gen); - BUG_ON(!eb); btrfs_tree_lock(eb); if (cow) { ret = btrfs_cow_block(trans, dest, eb, parent, @@ -2514,10 +2513,6 @@ static int do_relocation(struct btrfs_trans_handle *trans, blocksize = btrfs_level_size(root, node->level); generation = btrfs_node_ptr_generation(upper->eb, slot); eb = read_tree_block(root, bytenr, blocksize, generation); - if (!eb) { - err = -EIO; - goto next; - } btrfs_tree_lock(eb); btrfs_set_lock_blocking(eb); @@ -2675,7 +2670,6 @@ static int get_tree_block_key(struct reloc_control *rc, BUG_ON(block->key_ready); eb = read_tree_block(rc->extent_root, block->bytenr, block->key.objectid, block->key.offset); - BUG_ON(!eb); WARN_ON(btrfs_header_level(eb) != block->level); if (block->level == 0) btrfs_item_key_to_cpu(eb, &block->key, 0); @@ -4215,7 +4209,7 @@ int btrfs_recover_relocation(struct btrfs_root *root) if (IS_ERR(fs_root)) err = PTR_ERR(fs_root); else - err = btrfs_orphan_cleanup(fs_root); + btrfs_orphan_cleanup(fs_root); } return err; } diff --git a/trunk/fs/btrfs/root-tree.c b/trunk/fs/btrfs/root-tree.c index 29b2d7c930eb..6a1086e83ffc 100644 --- a/trunk/fs/btrfs/root-tree.c +++ b/trunk/fs/btrfs/root-tree.c @@ -88,8 +88,7 @@ int btrfs_find_last_root(struct btrfs_root *root, u64 objectid, search_key.offset = (u64)-1; path = btrfs_alloc_path(); - if (!path) - return -ENOMEM; + BUG_ON(!path); ret = btrfs_search_slot(NULL, root, &search_key, path, 0, 0); if (ret < 0) goto out; @@ -333,8 +332,7 @@ int btrfs_del_root(struct btrfs_trans_handle *trans, struct btrfs_root *root, struct extent_buffer *leaf; path = btrfs_alloc_path(); - if (!path) - return -ENOMEM; + BUG_ON(!path); ret = btrfs_search_slot(trans, root, key, path, -1, 1); if (ret < 0) goto out; diff --git a/trunk/fs/btrfs/super.c b/trunk/fs/btrfs/super.c index 2edfc039f098..d39a9895d932 100644 --- a/trunk/fs/btrfs/super.c +++ b/trunk/fs/btrfs/super.c @@ -52,9 +52,6 @@ #include "export.h" #include "compression.h" -#define CREATE_TRACE_POINTS -#include - static const struct super_operations btrfs_super_ops; static const char *btrfs_decode_error(struct btrfs_fs_info *fs_info, int errno, @@ -623,8 +620,6 @@ int btrfs_sync_fs(struct super_block *sb, int wait) struct btrfs_root *root = btrfs_sb(sb); int ret; - trace_btrfs_sync_fs(wait); - if (!wait) { filemap_flush(root->fs_info->btree_inode->i_mapping); return 0; diff --git a/trunk/fs/btrfs/transaction.c b/trunk/fs/btrfs/transaction.c index ce48eb59d615..3d73c8d93bbb 100644 --- a/trunk/fs/btrfs/transaction.c +++ b/trunk/fs/btrfs/transaction.c @@ -57,8 +57,7 @@ static noinline int join_transaction(struct btrfs_root *root) if (!cur_trans) { cur_trans = kmem_cache_alloc(btrfs_transaction_cachep, GFP_NOFS); - if (!cur_trans) - return -ENOMEM; + BUG_ON(!cur_trans); root->fs_info->generation++; cur_trans->num_writers = 1; cur_trans->num_joined = 0; @@ -196,11 +195,7 @@ static struct btrfs_trans_handle *start_transaction(struct btrfs_root *root, wait_current_trans(root); ret = join_transaction(root); - if (ret < 0) { - if (type != TRANS_JOIN_NOLOCK) - mutex_unlock(&root->fs_info->trans_mutex); - return ERR_PTR(ret); - } + BUG_ON(ret); cur_trans = root->fs_info->running_transaction; cur_trans->use_count++; @@ -1161,8 +1156,7 @@ int btrfs_commit_transaction_async(struct btrfs_trans_handle *trans, struct btrfs_transaction *cur_trans; ac = kmalloc(sizeof(*ac), GFP_NOFS); - if (!ac) - return -ENOMEM; + BUG_ON(!ac); INIT_DELAYED_WORK(&ac->work, do_async_commit); ac->root = root; @@ -1395,8 +1389,6 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans, put_transaction(cur_trans); put_transaction(cur_trans); - trace_btrfs_transaction_commit(root); - mutex_unlock(&root->fs_info->trans_mutex); if (current->journal_info == trans) diff --git a/trunk/fs/btrfs/tree-log.c b/trunk/fs/btrfs/tree-log.c index c50271ad3157..a4bbb854dfd2 100644 --- a/trunk/fs/btrfs/tree-log.c +++ b/trunk/fs/btrfs/tree-log.c @@ -799,12 +799,12 @@ static noinline int add_inode_ref(struct btrfs_trans_handle *trans, struct inode *dir; int ret; struct btrfs_inode_ref *ref; + struct btrfs_dir_item *di; struct inode *inode; char *name; int namelen; unsigned long ref_ptr; unsigned long ref_end; - int search_done = 0; /* * it is possible that we didn't log all the parent directories @@ -845,10 +845,7 @@ static noinline int add_inode_ref(struct btrfs_trans_handle *trans, * existing back reference, and we don't want to create * dangling pointers in the directory. */ - - if (search_done) - goto insert; - +conflict_again: ret = btrfs_search_slot(NULL, root, key, path, 0, 0); if (ret == 0) { char *victim_name; @@ -889,21 +886,37 @@ static noinline int add_inode_ref(struct btrfs_trans_handle *trans, ret = btrfs_unlink_inode(trans, root, dir, inode, victim_name, victim_name_len); + kfree(victim_name); + btrfs_release_path(root, path); + goto conflict_again; } kfree(victim_name); ptr = (unsigned long)(victim_ref + 1) + victim_name_len; } BUG_ON(ret); + } + btrfs_release_path(root, path); - /* - * NOTE: we have searched root tree and checked the - * coresponding ref, it does not need to check again. - */ - search_done = 1; + /* look for a conflicting sequence number */ + di = btrfs_lookup_dir_index_item(trans, root, path, dir->i_ino, + btrfs_inode_ref_index(eb, ref), + name, namelen, 0); + if (di && !IS_ERR(di)) { + ret = drop_one_dir_item(trans, root, path, dir, di); + BUG_ON(ret); + } + btrfs_release_path(root, path); + + + /* look for a conflicting name */ + di = btrfs_lookup_dir_item(trans, root, path, dir->i_ino, + name, namelen, 0); + if (di && !IS_ERR(di)) { + ret = drop_one_dir_item(trans, root, path, dir, di); + BUG_ON(ret); } btrfs_release_path(root, path); -insert: /* insert our name */ ret = btrfs_add_link(trans, dir, inode, name, namelen, 0, btrfs_inode_ref_index(eb, ref)); @@ -1273,8 +1286,6 @@ static noinline int replay_one_dir_item(struct btrfs_trans_handle *trans, ptr_end = ptr + item_size; while (ptr < ptr_end) { di = (struct btrfs_dir_item *)ptr; - if (verify_dir_item(root, eb, di)) - return -EIO; name_len = btrfs_dir_name_len(eb, di); ret = replay_one_name(trans, root, path, eb, di, key); BUG_ON(ret); @@ -1401,11 +1412,6 @@ static noinline int check_item_in_log(struct btrfs_trans_handle *trans, ptr_end = ptr + item_size; while (ptr < ptr_end) { di = (struct btrfs_dir_item *)ptr; - if (verify_dir_item(root, eb, di)) { - ret = -EIO; - goto out; - } - name_len = btrfs_dir_name_len(eb, di); name = kmalloc(name_len, GFP_NOFS); if (!name) { @@ -1815,8 +1821,7 @@ static int walk_log_tree(struct btrfs_trans_handle *trans, int orig_level; path = btrfs_alloc_path(); - if (!path) - return -ENOMEM; + BUG_ON(!path); level = btrfs_header_level(log->node); orig_level = level; @@ -3102,11 +3107,9 @@ int btrfs_recover_log_trees(struct btrfs_root *log_root_tree) .stage = 0, }; - path = btrfs_alloc_path(); - if (!path) - return -ENOMEM; - fs_info->log_root_recovering = 1; + path = btrfs_alloc_path(); + BUG_ON(!path); trans = btrfs_start_transaction(fs_info->tree_root, 0); BUG_ON(IS_ERR(trans)); @@ -3114,8 +3117,7 @@ int btrfs_recover_log_trees(struct btrfs_root *log_root_tree) wc.trans = trans; wc.pin = 1; - ret = walk_log_tree(trans, log_root_tree, &wc); - BUG_ON(ret); + walk_log_tree(trans, log_root_tree, &wc); again: key.objectid = BTRFS_TREE_LOG_OBJECTID; @@ -3139,7 +3141,8 @@ int btrfs_recover_log_trees(struct btrfs_root *log_root_tree) log = btrfs_read_fs_root_no_radix(log_root_tree, &found_key); - BUG_ON(IS_ERR(log)); + BUG_ON(!log); + tmp_key.objectid = found_key.offset; tmp_key.type = BTRFS_ROOT_ITEM_KEY; diff --git a/trunk/fs/btrfs/volumes.c b/trunk/fs/btrfs/volumes.c index 309a57b9fc85..9d554e8e6583 100644 --- a/trunk/fs/btrfs/volumes.c +++ b/trunk/fs/btrfs/volumes.c @@ -33,6 +33,17 @@ #include "volumes.h" #include "async-thread.h" +struct map_lookup { + u64 type; + int io_align; + int io_width; + int stripe_len; + int sector_size; + int num_stripes; + int sub_stripes; + struct btrfs_bio_stripe stripes[]; +}; + static int init_first_rw_device(struct btrfs_trans_handle *trans, struct btrfs_root *root, struct btrfs_device *device); @@ -1868,8 +1879,6 @@ static int btrfs_relocate_chunk(struct btrfs_root *root, BUG_ON(ret); - trace_btrfs_chunk_free(root, map, chunk_offset, em->len); - if (map->type & BTRFS_BLOCK_GROUP_SYSTEM) { ret = btrfs_del_sys_chunk(root, chunk_objectid, chunk_offset); BUG_ON(ret); @@ -2597,8 +2606,6 @@ static int __btrfs_alloc_chunk(struct btrfs_trans_handle *trans, *num_bytes = chunk_bytes_by_type(type, calc_size, map->num_stripes, sub_stripes); - trace_btrfs_chunk_alloc(info->chunk_root, map, start, *num_bytes); - em = alloc_extent_map(GFP_NOFS); if (!em) { ret = -ENOMEM; @@ -2707,7 +2714,6 @@ static int __finish_chunk_alloc(struct btrfs_trans_handle *trans, item_size); BUG_ON(ret); } - kfree(chunk); return 0; } @@ -2912,10 +2918,7 @@ static int __btrfs_map_block(struct btrfs_mapping_tree *map_tree, int rw, struct extent_map_tree *em_tree = &map_tree->map_tree; u64 offset; u64 stripe_offset; - u64 stripe_end_offset; u64 stripe_nr; - u64 stripe_nr_orig; - u64 stripe_nr_end; int stripes_allocated = 8; int stripes_required = 1; int stripe_index; @@ -2924,7 +2927,7 @@ static int __btrfs_map_block(struct btrfs_mapping_tree *map_tree, int rw, int max_errors = 0; struct btrfs_multi_bio *multi = NULL; - if (multi_ret && !(rw & (REQ_WRITE | REQ_DISCARD))) + if (multi_ret && !(rw & REQ_WRITE)) stripes_allocated = 1; again: if (multi_ret) { @@ -2965,15 +2968,7 @@ static int __btrfs_map_block(struct btrfs_mapping_tree *map_tree, int rw, max_errors = 1; } } - if (rw & REQ_DISCARD) { - if (map->type & (BTRFS_BLOCK_GROUP_RAID0 | - BTRFS_BLOCK_GROUP_RAID1 | - BTRFS_BLOCK_GROUP_DUP | - BTRFS_BLOCK_GROUP_RAID10)) { - stripes_required = map->num_stripes; - } - } - if (multi_ret && (rw & (REQ_WRITE | REQ_DISCARD)) && + if (multi_ret && (rw & REQ_WRITE) && stripes_allocated < stripes_required) { stripes_allocated = map->num_stripes; free_extent_map(em); @@ -2993,15 +2988,12 @@ static int __btrfs_map_block(struct btrfs_mapping_tree *map_tree, int rw, /* stripe_offset is the offset of this block in its stripe*/ stripe_offset = offset - stripe_offset; - if (rw & REQ_DISCARD) - *length = min_t(u64, em->len - offset, *length); - else if (map->type & (BTRFS_BLOCK_GROUP_RAID0 | - BTRFS_BLOCK_GROUP_RAID1 | - BTRFS_BLOCK_GROUP_RAID10 | - BTRFS_BLOCK_GROUP_DUP)) { + if (map->type & (BTRFS_BLOCK_GROUP_RAID0 | BTRFS_BLOCK_GROUP_RAID1 | + BTRFS_BLOCK_GROUP_RAID10 | + BTRFS_BLOCK_GROUP_DUP)) { /* we limit the length of each bio to what fits in a stripe */ *length = min_t(u64, em->len - offset, - map->stripe_len - stripe_offset); + map->stripe_len - stripe_offset); } else { *length = em->len - offset; } @@ -3011,19 +3003,8 @@ static int __btrfs_map_block(struct btrfs_mapping_tree *map_tree, int rw, num_stripes = 1; stripe_index = 0; - stripe_nr_orig = stripe_nr; - stripe_nr_end = (offset + *length + map->stripe_len - 1) & - (~(map->stripe_len - 1)); - do_div(stripe_nr_end, map->stripe_len); - stripe_end_offset = stripe_nr_end * map->stripe_len - - (offset + *length); - if (map->type & BTRFS_BLOCK_GROUP_RAID0) { - if (rw & REQ_DISCARD) - num_stripes = min_t(u64, map->num_stripes, - stripe_nr_end - stripe_nr_orig); - stripe_index = do_div(stripe_nr, map->num_stripes); - } else if (map->type & BTRFS_BLOCK_GROUP_RAID1) { - if (rw & (REQ_WRITE | REQ_DISCARD)) + if (map->type & BTRFS_BLOCK_GROUP_RAID1) { + if (rw & REQ_WRITE) num_stripes = map->num_stripes; else if (mirror_num) stripe_index = mirror_num - 1; @@ -3034,7 +3015,7 @@ static int __btrfs_map_block(struct btrfs_mapping_tree *map_tree, int rw, } } else if (map->type & BTRFS_BLOCK_GROUP_DUP) { - if (rw & (REQ_WRITE | REQ_DISCARD)) + if (rw & REQ_WRITE) num_stripes = map->num_stripes; else if (mirror_num) stripe_index = mirror_num - 1; @@ -3047,10 +3028,6 @@ static int __btrfs_map_block(struct btrfs_mapping_tree *map_tree, int rw, if (rw & REQ_WRITE) num_stripes = map->sub_stripes; - else if (rw & REQ_DISCARD) - num_stripes = min_t(u64, map->sub_stripes * - (stripe_nr_end - stripe_nr_orig), - map->num_stripes); else if (mirror_num) stripe_index += mirror_num - 1; else { @@ -3068,101 +3045,12 @@ static int __btrfs_map_block(struct btrfs_mapping_tree *map_tree, int rw, } BUG_ON(stripe_index >= map->num_stripes); - if (rw & REQ_DISCARD) { - for (i = 0; i < num_stripes; i++) { - multi->stripes[i].physical = - map->stripes[stripe_index].physical + - stripe_offset + stripe_nr * map->stripe_len; - multi->stripes[i].dev = map->stripes[stripe_index].dev; - - if (map->type & BTRFS_BLOCK_GROUP_RAID0) { - u64 stripes; - u32 last_stripe = 0; - int j; - - div_u64_rem(stripe_nr_end - 1, - map->num_stripes, - &last_stripe); - - for (j = 0; j < map->num_stripes; j++) { - u32 test; - - div_u64_rem(stripe_nr_end - 1 - j, - map->num_stripes, &test); - if (test == stripe_index) - break; - } - stripes = stripe_nr_end - 1 - j; - do_div(stripes, map->num_stripes); - multi->stripes[i].length = map->stripe_len * - (stripes - stripe_nr + 1); - - if (i == 0) { - multi->stripes[i].length -= - stripe_offset; - stripe_offset = 0; - } - if (stripe_index == last_stripe) - multi->stripes[i].length -= - stripe_end_offset; - } else if (map->type & BTRFS_BLOCK_GROUP_RAID10) { - u64 stripes; - int j; - int factor = map->num_stripes / - map->sub_stripes; - u32 last_stripe = 0; - - div_u64_rem(stripe_nr_end - 1, - factor, &last_stripe); - last_stripe *= map->sub_stripes; - - for (j = 0; j < factor; j++) { - u32 test; - - div_u64_rem(stripe_nr_end - 1 - j, - factor, &test); - - if (test == - stripe_index / map->sub_stripes) - break; - } - stripes = stripe_nr_end - 1 - j; - do_div(stripes, factor); - multi->stripes[i].length = map->stripe_len * - (stripes - stripe_nr + 1); - - if (i < map->sub_stripes) { - multi->stripes[i].length -= - stripe_offset; - if (i == map->sub_stripes - 1) - stripe_offset = 0; - } - if (stripe_index >= last_stripe && - stripe_index <= (last_stripe + - map->sub_stripes - 1)) { - multi->stripes[i].length -= - stripe_end_offset; - } - } else - multi->stripes[i].length = *length; - - stripe_index++; - if (stripe_index == map->num_stripes) { - /* This could only happen for RAID0/10 */ - stripe_index = 0; - stripe_nr++; - } - } - } else { - for (i = 0; i < num_stripes; i++) { - multi->stripes[i].physical = - map->stripes[stripe_index].physical + - stripe_offset + - stripe_nr * map->stripe_len; - multi->stripes[i].dev = - map->stripes[stripe_index].dev; - stripe_index++; - } + for (i = 0; i < num_stripes; i++) { + multi->stripes[i].physical = + map->stripes[stripe_index].physical + + stripe_offset + stripe_nr * map->stripe_len; + multi->stripes[i].dev = map->stripes[stripe_index].dev; + stripe_index++; } if (multi_ret) { *multi_ret = multi; diff --git a/trunk/fs/btrfs/volumes.h b/trunk/fs/btrfs/volumes.h index cc2eadaf7a27..7fb59d45fe8c 100644 --- a/trunk/fs/btrfs/volumes.h +++ b/trunk/fs/btrfs/volumes.h @@ -126,7 +126,6 @@ struct btrfs_fs_devices { struct btrfs_bio_stripe { struct btrfs_device *dev; u64 physical; - u64 length; /* only used for discard mappings */ }; struct btrfs_multi_bio { @@ -146,17 +145,6 @@ struct btrfs_device_info { u64 max_avail; }; -struct map_lookup { - u64 type; - int io_align; - int io_width; - int stripe_len; - int sector_size; - int num_stripes; - int sub_stripes; - struct btrfs_bio_stripe stripes[]; -}; - /* Used to sort the devices by max_avail(descending sort) */ int btrfs_cmp_device_free_bytes(const void *dev_info1, const void *dev_info2); diff --git a/trunk/fs/btrfs/xattr.c b/trunk/fs/btrfs/xattr.c index a5303b871b13..d779cefcfd7d 100644 --- a/trunk/fs/btrfs/xattr.c +++ b/trunk/fs/btrfs/xattr.c @@ -242,8 +242,6 @@ ssize_t btrfs_listxattr(struct dentry *dentry, char *buffer, size_t size) break; di = btrfs_item_ptr(leaf, slot, struct btrfs_dir_item); - if (verify_dir_item(root, leaf, di)) - continue; name_len = btrfs_dir_name_len(leaf, di); total_size += name_len + 1; diff --git a/trunk/fs/ceph/addr.c b/trunk/fs/ceph/addr.c index 37368ba2e67c..561438b6a50c 100644 --- a/trunk/fs/ceph/addr.c +++ b/trunk/fs/ceph/addr.c @@ -92,7 +92,7 @@ static int ceph_set_page_dirty(struct page *page) ci->i_head_snapc = ceph_get_snap_context(snapc); ++ci->i_wrbuffer_ref_head; if (ci->i_wrbuffer_ref == 0) - ihold(inode); + igrab(inode); ++ci->i_wrbuffer_ref; dout("%p set_page_dirty %p idx %lu head %d/%d -> %d/%d " "snapc %p seq %lld (%d snaps)\n", diff --git a/trunk/fs/ceph/snap.c b/trunk/fs/ceph/snap.c index 0aee66b92af3..f40b9139e437 100644 --- a/trunk/fs/ceph/snap.c +++ b/trunk/fs/ceph/snap.c @@ -463,8 +463,8 @@ void ceph_queue_cap_snap(struct ceph_inode_info *ci) dout("queue_cap_snap %p cap_snap %p queuing under %p\n", inode, capsnap, snapc); - ihold(inode); - + igrab(inode); + atomic_set(&capsnap->nref, 1); capsnap->ci = ci; INIT_LIST_HEAD(&capsnap->ci_item); diff --git a/trunk/fs/ecryptfs/crypto.c b/trunk/fs/ecryptfs/crypto.c index d2a70a4561f9..bfd8b680e648 100644 --- a/trunk/fs/ecryptfs/crypto.c +++ b/trunk/fs/ecryptfs/crypto.c @@ -266,6 +266,7 @@ void ecryptfs_destroy_mount_crypt_stat( &mount_crypt_stat->global_auth_tok_list, mount_crypt_stat_list) { list_del(&auth_tok->mount_crypt_stat_list); + mount_crypt_stat->num_global_auth_toks--; if (auth_tok->global_auth_tok_key && !(auth_tok->flags & ECRYPTFS_AUTH_TOK_INVALID)) key_put(auth_tok->global_auth_tok_key); @@ -1388,7 +1389,6 @@ int ecryptfs_write_metadata(struct dentry *ecryptfs_dentry) rc = -ENOMEM; goto out; } - /* Zeroed page ensures the in-header unencrypted i_size is set to 0 */ rc = ecryptfs_write_headers_virt(virt, virt_len, &size, crypt_stat, ecryptfs_dentry); if (unlikely(rc)) { diff --git a/trunk/fs/ecryptfs/ecryptfs_kernel.h b/trunk/fs/ecryptfs/ecryptfs_kernel.h index bd3cafd0949d..e00753496e3e 100644 --- a/trunk/fs/ecryptfs/ecryptfs_kernel.h +++ b/trunk/fs/ecryptfs/ecryptfs_kernel.h @@ -233,7 +233,7 @@ ecryptfs_get_key_payload_data(struct key *key) struct ecryptfs_key_sig { struct list_head crypt_stat_list; - char keysig[ECRYPTFS_SIG_SIZE_HEX + 1]; + char keysig[ECRYPTFS_SIG_SIZE_HEX]; }; struct ecryptfs_filename { @@ -257,18 +257,19 @@ struct ecryptfs_filename { struct ecryptfs_crypt_stat { #define ECRYPTFS_STRUCT_INITIALIZED 0x00000001 #define ECRYPTFS_POLICY_APPLIED 0x00000002 -#define ECRYPTFS_ENCRYPTED 0x00000004 -#define ECRYPTFS_SECURITY_WARNING 0x00000008 -#define ECRYPTFS_ENABLE_HMAC 0x00000010 -#define ECRYPTFS_ENCRYPT_IV_PAGES 0x00000020 -#define ECRYPTFS_KEY_VALID 0x00000040 -#define ECRYPTFS_METADATA_IN_XATTR 0x00000080 -#define ECRYPTFS_VIEW_AS_ENCRYPTED 0x00000100 -#define ECRYPTFS_KEY_SET 0x00000200 -#define ECRYPTFS_ENCRYPT_FILENAMES 0x00000400 -#define ECRYPTFS_ENCFN_USE_MOUNT_FNEK 0x00000800 -#define ECRYPTFS_ENCFN_USE_FEK 0x00001000 -#define ECRYPTFS_UNLINK_SIGS 0x00002000 +#define ECRYPTFS_NEW_FILE 0x00000004 +#define ECRYPTFS_ENCRYPTED 0x00000008 +#define ECRYPTFS_SECURITY_WARNING 0x00000010 +#define ECRYPTFS_ENABLE_HMAC 0x00000020 +#define ECRYPTFS_ENCRYPT_IV_PAGES 0x00000040 +#define ECRYPTFS_KEY_VALID 0x00000080 +#define ECRYPTFS_METADATA_IN_XATTR 0x00000100 +#define ECRYPTFS_VIEW_AS_ENCRYPTED 0x00000200 +#define ECRYPTFS_KEY_SET 0x00000400 +#define ECRYPTFS_ENCRYPT_FILENAMES 0x00000800 +#define ECRYPTFS_ENCFN_USE_MOUNT_FNEK 0x00001000 +#define ECRYPTFS_ENCFN_USE_FEK 0x00002000 +#define ECRYPTFS_UNLINK_SIGS 0x00004000 u32 flags; unsigned int file_version; size_t iv_bytes; @@ -296,6 +297,7 @@ struct ecryptfs_inode_info { struct inode vfs_inode; struct inode *wii_inode; struct file *lower_file; + struct mutex lower_file_mutex; struct ecryptfs_crypt_stat crypt_stat; }; @@ -331,6 +333,7 @@ struct ecryptfs_global_auth_tok { u32 flags; struct list_head mount_crypt_stat_list; struct key *global_auth_tok_key; + struct ecryptfs_auth_tok *global_auth_tok; unsigned char sig[ECRYPTFS_SIG_SIZE_HEX + 1]; }; @@ -377,6 +380,7 @@ struct ecryptfs_mount_crypt_stat { u32 flags; struct list_head global_auth_tok_list; struct mutex global_auth_tok_list_mutex; + size_t num_global_auth_toks; size_t global_default_cipher_key_size; size_t global_default_fn_cipher_key_bytes; unsigned char global_default_cipher_name[ECRYPTFS_MAX_CIPHER_NAME_SIZE diff --git a/trunk/fs/ecryptfs/file.c b/trunk/fs/ecryptfs/file.c index cedc913d11ba..7d1050e254f9 100644 --- a/trunk/fs/ecryptfs/file.c +++ b/trunk/fs/ecryptfs/file.c @@ -273,14 +273,7 @@ static int ecryptfs_release(struct inode *inode, struct file *file) static int ecryptfs_fsync(struct file *file, int datasync) { - int rc = 0; - - rc = generic_file_fsync(file, datasync); - if (rc) - goto out; - rc = vfs_fsync(ecryptfs_file_to_lower(file), datasync); -out: - return rc; + return vfs_fsync(ecryptfs_file_to_lower(file), datasync); } static int ecryptfs_fasync(int fd, struct file *file, int flag) diff --git a/trunk/fs/ecryptfs/inode.c b/trunk/fs/ecryptfs/inode.c index f99051b7adab..b592938a84bc 100644 --- a/trunk/fs/ecryptfs/inode.c +++ b/trunk/fs/ecryptfs/inode.c @@ -142,6 +142,26 @@ ecryptfs_do_create(struct inode *directory_inode, return rc; } +/** + * grow_file + * @ecryptfs_dentry: the eCryptfs dentry + * + * This is the code which will grow the file to its correct size. + */ +static int grow_file(struct dentry *ecryptfs_dentry) +{ + struct inode *ecryptfs_inode = ecryptfs_dentry->d_inode; + char zero_virt[] = { 0x00 }; + int rc = 0; + + rc = ecryptfs_write(ecryptfs_inode, zero_virt, 0, 1); + i_size_write(ecryptfs_inode, 0); + rc = ecryptfs_write_inode_size_to_metadata(ecryptfs_inode); + ecryptfs_inode_to_private(ecryptfs_inode)->crypt_stat.flags |= + ECRYPTFS_NEW_FILE; + return rc; +} + /** * ecryptfs_initialize_file * @@ -161,6 +181,7 @@ static int ecryptfs_initialize_file(struct dentry *ecryptfs_dentry) crypt_stat->flags &= ~(ECRYPTFS_ENCRYPTED); goto out; } + crypt_stat->flags |= ECRYPTFS_NEW_FILE; ecryptfs_printk(KERN_DEBUG, "Initializing crypto context\n"); rc = ecryptfs_new_file_context(ecryptfs_dentry); if (rc) { @@ -181,6 +202,9 @@ static int ecryptfs_initialize_file(struct dentry *ecryptfs_dentry) printk(KERN_ERR "Error writing headers; rc = [%d]\n", rc); goto out; } + rc = grow_file(ecryptfs_dentry); + if (rc) + printk(KERN_ERR "Error growing file; rc = [%d]\n", rc); out: return rc; } diff --git a/trunk/fs/ecryptfs/keystore.c b/trunk/fs/ecryptfs/keystore.c index 03e609c45012..c1436cff6f2d 100644 --- a/trunk/fs/ecryptfs/keystore.c +++ b/trunk/fs/ecryptfs/keystore.c @@ -65,24 +65,6 @@ static int process_request_key_err(long err_code) return rc; } -static int process_find_global_auth_tok_for_sig_err(int err_code) -{ - int rc = err_code; - - switch (err_code) { - case -ENOENT: - ecryptfs_printk(KERN_WARNING, "Missing auth tok\n"); - break; - case -EINVAL: - ecryptfs_printk(KERN_WARNING, "Invalid auth tok\n"); - break; - default: - rc = process_request_key_err(err_code); - break; - } - return rc; -} - /** * ecryptfs_parse_packet_length * @data: Pointer to memory containing length at offset @@ -421,120 +403,27 @@ parse_tag_67_packet(struct ecryptfs_key_record *key_rec, return rc; } -/** - * ecryptfs_verify_version - * @version: The version number to confirm - * - * Returns zero on good version; non-zero otherwise - */ -static int ecryptfs_verify_version(u16 version) -{ - int rc = 0; - unsigned char major; - unsigned char minor; - - major = ((version >> 8) & 0xFF); - minor = (version & 0xFF); - if (major != ECRYPTFS_VERSION_MAJOR) { - ecryptfs_printk(KERN_ERR, "Major version number mismatch. " - "Expected [%d]; got [%d]\n", - ECRYPTFS_VERSION_MAJOR, major); - rc = -EINVAL; - goto out; - } - if (minor != ECRYPTFS_VERSION_MINOR) { - ecryptfs_printk(KERN_ERR, "Minor version number mismatch. " - "Expected [%d]; got [%d]\n", - ECRYPTFS_VERSION_MINOR, minor); - rc = -EINVAL; - goto out; - } -out: - return rc; -} - -/** - * ecryptfs_verify_auth_tok_from_key - * @auth_tok_key: key containing the authentication token - * @auth_tok: authentication token - * - * Returns zero on valid auth tok; -EINVAL otherwise - */ -static int -ecryptfs_verify_auth_tok_from_key(struct key *auth_tok_key, - struct ecryptfs_auth_tok **auth_tok) -{ - int rc = 0; - - (*auth_tok) = ecryptfs_get_key_payload_data(auth_tok_key); - if (ecryptfs_verify_version((*auth_tok)->version)) { - printk(KERN_ERR "Data structure version mismatch. Userspace " - "tools must match eCryptfs kernel module with major " - "version [%d] and minor version [%d]\n", - ECRYPTFS_VERSION_MAJOR, ECRYPTFS_VERSION_MINOR); - rc = -EINVAL; - goto out; - } - if ((*auth_tok)->token_type != ECRYPTFS_PASSWORD - && (*auth_tok)->token_type != ECRYPTFS_PRIVATE_KEY) { - printk(KERN_ERR "Invalid auth_tok structure " - "returned from key query\n"); - rc = -EINVAL; - goto out; - } -out: - return rc; -} - static int ecryptfs_find_global_auth_tok_for_sig( - struct key **auth_tok_key, - struct ecryptfs_auth_tok **auth_tok, + struct ecryptfs_global_auth_tok **global_auth_tok, struct ecryptfs_mount_crypt_stat *mount_crypt_stat, char *sig) { struct ecryptfs_global_auth_tok *walker; int rc = 0; - (*auth_tok_key) = NULL; - (*auth_tok) = NULL; + (*global_auth_tok) = NULL; mutex_lock(&mount_crypt_stat->global_auth_tok_list_mutex); list_for_each_entry(walker, &mount_crypt_stat->global_auth_tok_list, mount_crypt_stat_list) { - if (memcmp(walker->sig, sig, ECRYPTFS_SIG_SIZE_HEX)) - continue; - - if (walker->flags & ECRYPTFS_AUTH_TOK_INVALID) { - rc = -EINVAL; + if (memcmp(walker->sig, sig, ECRYPTFS_SIG_SIZE_HEX) == 0) { + rc = key_validate(walker->global_auth_tok_key); + if (!rc) + (*global_auth_tok) = walker; goto out; } - - rc = key_validate(walker->global_auth_tok_key); - if (rc) { - if (rc == -EKEYEXPIRED) - goto out; - goto out_invalid_auth_tok; - } - - down_write(&(walker->global_auth_tok_key->sem)); - rc = ecryptfs_verify_auth_tok_from_key( - walker->global_auth_tok_key, auth_tok); - if (rc) - goto out_invalid_auth_tok_unlock; - - (*auth_tok_key) = walker->global_auth_tok_key; - key_get(*auth_tok_key); - goto out; } - rc = -ENOENT; - goto out; -out_invalid_auth_tok_unlock: - up_write(&(walker->global_auth_tok_key->sem)); -out_invalid_auth_tok: - printk(KERN_WARNING "Invalidating auth tok with sig = [%s]\n", sig); - walker->flags |= ECRYPTFS_AUTH_TOK_INVALID; - key_put(walker->global_auth_tok_key); - walker->global_auth_tok_key = NULL; + rc = -EINVAL; out: mutex_unlock(&mount_crypt_stat->global_auth_tok_list_mutex); return rc; @@ -562,11 +451,14 @@ ecryptfs_find_auth_tok_for_sig( struct ecryptfs_mount_crypt_stat *mount_crypt_stat, char *sig) { + struct ecryptfs_global_auth_tok *global_auth_tok; int rc = 0; - rc = ecryptfs_find_global_auth_tok_for_sig(auth_tok_key, auth_tok, - mount_crypt_stat, sig); - if (rc == -ENOENT) { + (*auth_tok_key) = NULL; + (*auth_tok) = NULL; + if (ecryptfs_find_global_auth_tok_for_sig(&global_auth_tok, + mount_crypt_stat, sig)) { + /* if the flag ECRYPTFS_GLOBAL_MOUNT_AUTH_TOK_ONLY is set in the * mount_crypt_stat structure, we prevent to use auth toks that * are not inserted through the ecryptfs_add_global_auth_tok @@ -578,7 +470,8 @@ ecryptfs_find_auth_tok_for_sig( rc = ecryptfs_keyring_auth_tok_for_sig(auth_tok_key, auth_tok, sig); - } + } else + (*auth_tok) = global_auth_tok->global_auth_tok; return rc; } @@ -638,16 +531,6 @@ ecryptfs_write_tag_70_packet(char *dest, size_t *remaining_bytes, } s->desc.flags = CRYPTO_TFM_REQ_MAY_SLEEP; (*packet_size) = 0; - rc = ecryptfs_find_auth_tok_for_sig( - &auth_tok_key, - &s->auth_tok, mount_crypt_stat, - mount_crypt_stat->global_default_fnek_sig); - if (rc) { - printk(KERN_ERR "%s: Error attempting to find auth tok for " - "fnek sig [%s]; rc = [%d]\n", __func__, - mount_crypt_stat->global_default_fnek_sig, rc); - goto out; - } rc = ecryptfs_get_tfm_and_mutex_for_cipher_name( &s->desc.tfm, &s->tfm_mutex, mount_crypt_stat->global_default_fn_cipher_name); @@ -733,6 +616,16 @@ ecryptfs_write_tag_70_packet(char *dest, size_t *remaining_bytes, goto out_free_unlock; } dest[s->i++] = s->cipher_code; + rc = ecryptfs_find_auth_tok_for_sig( + &auth_tok_key, + &s->auth_tok, mount_crypt_stat, + mount_crypt_stat->global_default_fnek_sig); + if (rc) { + printk(KERN_ERR "%s: Error attempting to find auth tok for " + "fnek sig [%s]; rc = [%d]\n", __func__, + mount_crypt_stat->global_default_fnek_sig, rc); + goto out_free_unlock; + } /* TODO: Support other key modules than passphrase for * filename encryption */ if (s->auth_tok->token_type != ECRYPTFS_PASSWORD) { @@ -872,10 +765,8 @@ ecryptfs_write_tag_70_packet(char *dest, size_t *remaining_bytes, out_unlock: mutex_unlock(s->tfm_mutex); out: - if (auth_tok_key) { - up_write(&(auth_tok_key->sem)); + if (auth_tok_key) key_put(auth_tok_key); - } kfree(s); return rc; } @@ -988,15 +879,6 @@ ecryptfs_parse_tag_70_packet(char **filename, size_t *filename_size, __func__, s->cipher_code); goto out; } - rc = ecryptfs_find_auth_tok_for_sig(&auth_tok_key, - &s->auth_tok, mount_crypt_stat, - s->fnek_sig_hex); - if (rc) { - printk(KERN_ERR "%s: Error attempting to find auth tok for " - "fnek sig [%s]; rc = [%d]\n", __func__, s->fnek_sig_hex, - rc); - goto out; - } rc = ecryptfs_get_tfm_and_mutex_for_cipher_name(&s->desc.tfm, &s->tfm_mutex, s->cipher_string); @@ -1043,6 +925,15 @@ ecryptfs_parse_tag_70_packet(char **filename, size_t *filename_size, * >= ECRYPTFS_MAX_IV_BYTES. */ memset(s->iv, 0, ECRYPTFS_MAX_IV_BYTES); s->desc.info = s->iv; + rc = ecryptfs_find_auth_tok_for_sig(&auth_tok_key, + &s->auth_tok, mount_crypt_stat, + s->fnek_sig_hex); + if (rc) { + printk(KERN_ERR "%s: Error attempting to find auth tok for " + "fnek sig [%s]; rc = [%d]\n", __func__, s->fnek_sig_hex, + rc); + goto out_free_unlock; + } /* TODO: Support other key modules than passphrase for * filename encryption */ if (s->auth_tok->token_type != ECRYPTFS_PASSWORD) { @@ -1111,10 +1002,8 @@ ecryptfs_parse_tag_70_packet(char **filename, size_t *filename_size, (*filename_size) = 0; (*filename) = NULL; } - if (auth_tok_key) { - up_write(&(auth_tok_key->sem)); + if (auth_tok_key) key_put(auth_tok_key); - } kfree(s); return rc; } @@ -1631,6 +1520,38 @@ parse_tag_11_packet(unsigned char *data, unsigned char *contents, return rc; } +/** + * ecryptfs_verify_version + * @version: The version number to confirm + * + * Returns zero on good version; non-zero otherwise + */ +static int ecryptfs_verify_version(u16 version) +{ + int rc = 0; + unsigned char major; + unsigned char minor; + + major = ((version >> 8) & 0xFF); + minor = (version & 0xFF); + if (major != ECRYPTFS_VERSION_MAJOR) { + ecryptfs_printk(KERN_ERR, "Major version number mismatch. " + "Expected [%d]; got [%d]\n", + ECRYPTFS_VERSION_MAJOR, major); + rc = -EINVAL; + goto out; + } + if (minor != ECRYPTFS_VERSION_MINOR) { + ecryptfs_printk(KERN_ERR, "Minor version number mismatch. " + "Expected [%d]; got [%d]\n", + ECRYPTFS_VERSION_MINOR, minor); + rc = -EINVAL; + goto out; + } +out: + return rc; +} + int ecryptfs_keyring_auth_tok_for_sig(struct key **auth_tok_key, struct ecryptfs_auth_tok **auth_tok, char *sig) @@ -1642,16 +1563,31 @@ int ecryptfs_keyring_auth_tok_for_sig(struct key **auth_tok_key, printk(KERN_ERR "Could not find key with description: [%s]\n", sig); rc = process_request_key_err(PTR_ERR(*auth_tok_key)); - (*auth_tok_key) = NULL; goto out; } - down_write(&(*auth_tok_key)->sem); - rc = ecryptfs_verify_auth_tok_from_key(*auth_tok_key, auth_tok); + (*auth_tok) = ecryptfs_get_key_payload_data(*auth_tok_key); + if (ecryptfs_verify_version((*auth_tok)->version)) { + printk(KERN_ERR + "Data structure version mismatch. " + "Userspace tools must match eCryptfs " + "kernel module with major version [%d] " + "and minor version [%d]\n", + ECRYPTFS_VERSION_MAJOR, + ECRYPTFS_VERSION_MINOR); + rc = -EINVAL; + goto out_release_key; + } + if ((*auth_tok)->token_type != ECRYPTFS_PASSWORD + && (*auth_tok)->token_type != ECRYPTFS_PRIVATE_KEY) { + printk(KERN_ERR "Invalid auth_tok structure " + "returned from key query\n"); + rc = -EINVAL; + goto out_release_key; + } +out_release_key: if (rc) { - up_write(&(*auth_tok_key)->sem); key_put(*auth_tok_key); (*auth_tok_key) = NULL; - goto out; } out: return rc; @@ -1873,7 +1809,6 @@ int ecryptfs_parse_packet_set(struct ecryptfs_crypt_stat *crypt_stat, find_next_matching_auth_tok: found_auth_tok = 0; if (auth_tok_key) { - up_write(&(auth_tok_key->sem)); key_put(auth_tok_key); auth_tok_key = NULL; } @@ -1960,10 +1895,8 @@ int ecryptfs_parse_packet_set(struct ecryptfs_crypt_stat *crypt_stat, out_wipe_list: wipe_auth_tok_list(&auth_tok_list); out: - if (auth_tok_key) { - up_write(&(auth_tok_key->sem)); + if (auth_tok_key) key_put(auth_tok_key); - } return rc; } @@ -2391,7 +2324,7 @@ ecryptfs_generate_key_packet_set(char *dest_base, size_t max) { struct ecryptfs_auth_tok *auth_tok; - struct key *auth_tok_key = NULL; + struct ecryptfs_global_auth_tok *global_auth_tok; struct ecryptfs_mount_crypt_stat *mount_crypt_stat = &ecryptfs_superblock_to_private( ecryptfs_dentry->d_sb)->mount_crypt_stat; @@ -2410,16 +2343,21 @@ ecryptfs_generate_key_packet_set(char *dest_base, list_for_each_entry(key_sig, &crypt_stat->keysig_list, crypt_stat_list) { memset(key_rec, 0, sizeof(*key_rec)); - rc = ecryptfs_find_global_auth_tok_for_sig(&auth_tok_key, - &auth_tok, + rc = ecryptfs_find_global_auth_tok_for_sig(&global_auth_tok, mount_crypt_stat, key_sig->keysig); if (rc) { - printk(KERN_WARNING "Unable to retrieve auth tok with " - "sig = [%s]\n", key_sig->keysig); - rc = process_find_global_auth_tok_for_sig_err(rc); + printk(KERN_ERR "Error attempting to get the global " + "auth_tok; rc = [%d]\n", rc); goto out_free; } + if (global_auth_tok->flags & ECRYPTFS_AUTH_TOK_INVALID) { + printk(KERN_WARNING + "Skipping invalid auth tok with sig = [%s]\n", + global_auth_tok->sig); + continue; + } + auth_tok = global_auth_tok->global_auth_tok; if (auth_tok->token_type == ECRYPTFS_PASSWORD) { rc = write_tag_3_packet((dest_base + (*len)), &max, auth_tok, @@ -2457,9 +2395,6 @@ ecryptfs_generate_key_packet_set(char *dest_base, rc = -EINVAL; goto out_free; } - up_write(&(auth_tok_key->sem)); - key_put(auth_tok_key); - auth_tok_key = NULL; } if (likely(max > 0)) { dest_base[(*len)] = 0x00; @@ -2472,11 +2407,6 @@ ecryptfs_generate_key_packet_set(char *dest_base, out: if (rc) (*len) = 0; - if (auth_tok_key) { - up_write(&(auth_tok_key->sem)); - key_put(auth_tok_key); - } - mutex_unlock(&crypt_stat->keysig_list_mutex); return rc; } @@ -2494,7 +2424,6 @@ int ecryptfs_add_keysig(struct ecryptfs_crypt_stat *crypt_stat, char *sig) return -ENOMEM; } memcpy(new_key_sig->keysig, sig, ECRYPTFS_SIG_SIZE_HEX); - new_key_sig->keysig[ECRYPTFS_SIG_SIZE_HEX] = '\0'; /* Caller must hold keysig_list_mutex */ list_add(&new_key_sig->crypt_stat_list, &crypt_stat->keysig_list); @@ -2524,6 +2453,7 @@ ecryptfs_add_global_auth_tok(struct ecryptfs_mount_crypt_stat *mount_crypt_stat, mutex_lock(&mount_crypt_stat->global_auth_tok_list_mutex); list_add(&new_auth_tok->mount_crypt_stat_list, &mount_crypt_stat->global_auth_tok_list); + mount_crypt_stat->num_global_auth_toks++; mutex_unlock(&mount_crypt_stat->global_auth_tok_list_mutex); out: return rc; diff --git a/trunk/fs/ecryptfs/main.c b/trunk/fs/ecryptfs/main.c index c27c0ecf90bc..758323a0f09a 100644 --- a/trunk/fs/ecryptfs/main.c +++ b/trunk/fs/ecryptfs/main.c @@ -122,6 +122,7 @@ int ecryptfs_init_persistent_file(struct dentry *ecryptfs_dentry) ecryptfs_inode_to_private(ecryptfs_dentry->d_inode); int rc = 0; + mutex_lock(&inode_info->lower_file_mutex); if (!inode_info->lower_file) { struct dentry *lower_dentry; struct vfsmount *lower_mnt = @@ -137,6 +138,7 @@ int ecryptfs_init_persistent_file(struct dentry *ecryptfs_dentry) inode_info->lower_file = NULL; } } + mutex_unlock(&inode_info->lower_file_mutex); return rc; } @@ -239,14 +241,14 @@ static int ecryptfs_init_global_auth_toks( struct ecryptfs_mount_crypt_stat *mount_crypt_stat) { struct ecryptfs_global_auth_tok *global_auth_tok; - struct ecryptfs_auth_tok *auth_tok; int rc = 0; list_for_each_entry(global_auth_tok, &mount_crypt_stat->global_auth_tok_list, mount_crypt_stat_list) { rc = ecryptfs_keyring_auth_tok_for_sig( - &global_auth_tok->global_auth_tok_key, &auth_tok, + &global_auth_tok->global_auth_tok_key, + &global_auth_tok->global_auth_tok, global_auth_tok->sig); if (rc) { printk(KERN_ERR "Could not find valid key in user " @@ -254,10 +256,8 @@ static int ecryptfs_init_global_auth_toks( "option: [%s]\n", global_auth_tok->sig); global_auth_tok->flags |= ECRYPTFS_AUTH_TOK_INVALID; goto out; - } else { + } else global_auth_tok->flags &= ~ECRYPTFS_AUTH_TOK_INVALID; - up_write(&(global_auth_tok->global_auth_tok_key)->sem); - } } out: return rc; diff --git a/trunk/fs/ecryptfs/mmap.c b/trunk/fs/ecryptfs/mmap.c index 6a44148c5fb9..cc64fca89f8d 100644 --- a/trunk/fs/ecryptfs/mmap.c +++ b/trunk/fs/ecryptfs/mmap.c @@ -62,18 +62,6 @@ static int ecryptfs_writepage(struct page *page, struct writeback_control *wbc) { int rc; - /* - * Refuse to write the page out if we are called from reclaim context - * since our writepage() path may potentially allocate memory when - * calling into the lower fs vfs_write() which may in turn invoke - * us again. - */ - if (current->flags & PF_MEMALLOC) { - redirty_page_for_writepage(wbc, page); - rc = 0; - goto out; - } - rc = ecryptfs_encrypt_page(page); if (rc) { ecryptfs_printk(KERN_WARNING, "Error encrypting " @@ -82,8 +70,8 @@ static int ecryptfs_writepage(struct page *page, struct writeback_control *wbc) goto out; } SetPageUptodate(page); -out: unlock_page(page); +out: return rc; } @@ -205,7 +193,11 @@ static int ecryptfs_readpage(struct file *file, struct page *page) &ecryptfs_inode_to_private(page->mapping->host)->crypt_stat; int rc = 0; - if (!crypt_stat || !(crypt_stat->flags & ECRYPTFS_ENCRYPTED)) { + if (!crypt_stat + || !(crypt_stat->flags & ECRYPTFS_ENCRYPTED) + || (crypt_stat->flags & ECRYPTFS_NEW_FILE)) { + ecryptfs_printk(KERN_DEBUG, + "Passing through unencrypted page\n"); rc = ecryptfs_read_lower_page_segment(page, page->index, 0, PAGE_CACHE_SIZE, page->mapping->host); @@ -303,7 +295,8 @@ static int ecryptfs_write_begin(struct file *file, struct ecryptfs_crypt_stat *crypt_stat = &ecryptfs_inode_to_private(mapping->host)->crypt_stat; - if (!(crypt_stat->flags & ECRYPTFS_ENCRYPTED)) { + if (!(crypt_stat->flags & ECRYPTFS_ENCRYPTED) + || (crypt_stat->flags & ECRYPTFS_NEW_FILE)) { rc = ecryptfs_read_lower_page_segment( page, index, 0, PAGE_CACHE_SIZE, mapping->host); if (rc) { @@ -381,11 +374,6 @@ static int ecryptfs_write_begin(struct file *file, && (pos != 0)) zero_user(page, 0, PAGE_CACHE_SIZE); out: - if (unlikely(rc)) { - unlock_page(page); - page_cache_release(page); - *pagep = NULL; - } return rc; } @@ -498,8 +486,13 @@ static int ecryptfs_write_end(struct file *file, struct ecryptfs_crypt_stat *crypt_stat = &ecryptfs_inode_to_private(ecryptfs_inode)->crypt_stat; int rc; - int need_unlock_page = 1; + if (crypt_stat->flags & ECRYPTFS_NEW_FILE) { + ecryptfs_printk(KERN_DEBUG, "ECRYPTFS_NEW_FILE flag set in " + "crypt_stat at memory location [%p]\n", crypt_stat); + crypt_stat->flags &= ~(ECRYPTFS_NEW_FILE); + } else + ecryptfs_printk(KERN_DEBUG, "Not a new file\n"); ecryptfs_printk(KERN_DEBUG, "Calling fill_zeros_to_end_of_page" "(page w/ index = [0x%.16lx], to = [%d])\n", index, to); if (!(crypt_stat->flags & ECRYPTFS_ENCRYPTED)) { @@ -519,26 +512,26 @@ static int ecryptfs_write_end(struct file *file, "zeros in page with index = [0x%.16lx]\n", index); goto out; } - set_page_dirty(page); - unlock_page(page); - need_unlock_page = 0; + rc = ecryptfs_encrypt_page(page); + if (rc) { + ecryptfs_printk(KERN_WARNING, "Error encrypting page (upper " + "index [0x%.16lx])\n", index); + goto out; + } if (pos + copied > i_size_read(ecryptfs_inode)) { i_size_write(ecryptfs_inode, pos + copied); ecryptfs_printk(KERN_DEBUG, "Expanded file size to " "[0x%.16llx]\n", (unsigned long long)i_size_read(ecryptfs_inode)); - balance_dirty_pages_ratelimited(mapping); - rc = ecryptfs_write_inode_size_to_metadata(ecryptfs_inode); - if (rc) { - printk(KERN_ERR "Error writing inode size to metadata; " - "rc = [%d]\n", rc); - goto out; - } } - rc = copied; + rc = ecryptfs_write_inode_size_to_metadata(ecryptfs_inode); + if (rc) + printk(KERN_ERR "Error writing inode size to metadata; " + "rc = [%d]\n", rc); + else + rc = copied; out: - if (need_unlock_page) - unlock_page(page); + unlock_page(page); page_cache_release(page); return rc; } diff --git a/trunk/fs/ecryptfs/read_write.c b/trunk/fs/ecryptfs/read_write.c index 85d430963116..db184ef15d3d 100644 --- a/trunk/fs/ecryptfs/read_write.c +++ b/trunk/fs/ecryptfs/read_write.c @@ -44,11 +44,15 @@ int ecryptfs_write_lower(struct inode *ecryptfs_inode, char *data, ssize_t rc; inode_info = ecryptfs_inode_to_private(ecryptfs_inode); + mutex_lock(&inode_info->lower_file_mutex); BUG_ON(!inode_info->lower_file); + inode_info->lower_file->f_pos = offset; fs_save = get_fs(); set_fs(get_ds()); - rc = vfs_write(inode_info->lower_file, data, size, &offset); + rc = vfs_write(inode_info->lower_file, data, size, + &inode_info->lower_file->f_pos); set_fs(fs_save); + mutex_unlock(&inode_info->lower_file_mutex); mark_inode_dirty_sync(ecryptfs_inode); return rc; } @@ -230,11 +234,15 @@ int ecryptfs_read_lower(char *data, loff_t offset, size_t size, mm_segment_t fs_save; ssize_t rc; + mutex_lock(&inode_info->lower_file_mutex); BUG_ON(!inode_info->lower_file); + inode_info->lower_file->f_pos = offset; fs_save = get_fs(); set_fs(get_ds()); - rc = vfs_read(inode_info->lower_file, data, size, &offset); + rc = vfs_read(inode_info->lower_file, data, size, + &inode_info->lower_file->f_pos); set_fs(fs_save); + mutex_unlock(&inode_info->lower_file_mutex); return rc; } diff --git a/trunk/fs/ecryptfs/super.c b/trunk/fs/ecryptfs/super.c index bacc882e1ae4..3042fe123a34 100644 --- a/trunk/fs/ecryptfs/super.c +++ b/trunk/fs/ecryptfs/super.c @@ -55,6 +55,7 @@ static struct inode *ecryptfs_alloc_inode(struct super_block *sb) if (unlikely(!inode_info)) goto out; ecryptfs_init_crypt_stat(&inode_info->crypt_stat); + mutex_init(&inode_info->lower_file_mutex); inode_info->lower_file = NULL; inode = &inode_info->vfs_inode; out: @@ -197,7 +198,7 @@ static int ecryptfs_show_options(struct seq_file *m, struct vfsmount *mnt) const struct super_operations ecryptfs_sops = { .alloc_inode = ecryptfs_alloc_inode, .destroy_inode = ecryptfs_destroy_inode, - .drop_inode = generic_drop_inode, + .drop_inode = generic_delete_inode, .statfs = ecryptfs_statfs, .remount_fs = NULL, .evict_inode = ecryptfs_evict_inode, diff --git a/trunk/fs/inode.c b/trunk/fs/inode.c index 5f4e11aaeb5c..05a1f75ae791 100644 --- a/trunk/fs/inode.c +++ b/trunk/fs/inode.c @@ -1167,7 +1167,7 @@ EXPORT_SYMBOL(igrab); * Note: I_NEW is not waited upon so you have to be very careful what you do * with the returned inode. You probably should be using ilookup5() instead. * - * Note2: @test is called with the inode_hash_lock held, so can't sleep. + * Note: @test is called with the inode_hash_lock held, so can't sleep. */ struct inode *ilookup5_nowait(struct super_block *sb, unsigned long hashval, int (*test)(struct inode *, void *), void *data) diff --git a/trunk/fs/jffs2/xattr.c b/trunk/fs/jffs2/xattr.c index 3e93cdd19005..4f9cc0482949 100644 --- a/trunk/fs/jffs2/xattr.c +++ b/trunk/fs/jffs2/xattr.c @@ -31,7 +31,7 @@ * is used to release xattr name/value pair and detach from c->xattrindex. * reclaim_xattr_datum(c) * is used to reclaim xattr name/value pairs on the xattr name/value pair cache when - * memory usage by cache is over c->xdatum_mem_threshold. Currently, this threshold + * memory usage by cache is over c->xdatum_mem_threshold. Currently, this threshold * is hard coded as 32KiB. * do_verify_xattr_datum(c, xd) * is used to load the xdatum informations without name/value pair from the medium. diff --git a/trunk/fs/nfs/namespace.c b/trunk/fs/nfs/namespace.c index 9166fcb66da2..ad92bf731ff5 100644 --- a/trunk/fs/nfs/namespace.c +++ b/trunk/fs/nfs/namespace.c @@ -192,15 +192,13 @@ static rpc_authflavor_t nfs_lookup_with_sec(struct nfs_server *server, struct de auth = rpcauth_create(flavor, clone); if (!auth) { flavor = -EIO; - goto out_shutdown; + goto out; } err = server->nfs_client->rpc_ops->lookup(clone, parent->d_inode, &path->dentry->d_name, fh, fattr); if (err < 0) flavor = err; -out_shutdown: - rpc_shutdown_client(clone); out: return flavor; } diff --git a/trunk/fs/nfs/nfs4state.c b/trunk/fs/nfs/nfs4state.c index a6804f704d9d..ab1bf5bb021f 100644 --- a/trunk/fs/nfs/nfs4state.c +++ b/trunk/fs/nfs/nfs4state.c @@ -590,8 +590,7 @@ nfs4_get_open_state(struct inode *inode, struct nfs4_state_owner *owner) state->owner = owner; atomic_inc(&owner->so_count); list_add(&state->inode_states, &nfsi->open_states); - ihold(inode); - state->inode = inode; + state->inode = igrab(inode); spin_unlock(&inode->i_lock); /* Note: The reclaim code dictates that we add stateless * and read-only stateids to the end of the list */ diff --git a/trunk/fs/nfs/pagelist.c b/trunk/fs/nfs/pagelist.c index c80add6e2213..87a593c2b055 100644 --- a/trunk/fs/nfs/pagelist.c +++ b/trunk/fs/nfs/pagelist.c @@ -135,14 +135,14 @@ void nfs_clear_page_tag_locked(struct nfs_page *req) nfs_unlock_request(req); } -/* +/** * nfs_clear_request - Free up all resources allocated to the request * @req: * * Release page and open context resources associated with a read/write * request after it has completed. */ -static void nfs_clear_request(struct nfs_page *req) +void nfs_clear_request(struct nfs_page *req) { struct page *page = req->wb_page; struct nfs_open_context *ctx = req->wb_context; diff --git a/trunk/fs/nfs/write.c b/trunk/fs/nfs/write.c index af0c6279a4a7..85d75254328e 100644 --- a/trunk/fs/nfs/write.c +++ b/trunk/fs/nfs/write.c @@ -389,8 +389,11 @@ static int nfs_inode_add_request(struct inode *inode, struct nfs_page *req) spin_lock(&inode->i_lock); error = radix_tree_insert(&nfsi->nfs_page_tree, req->wb_index, req); BUG_ON(error); - if (!nfsi->npages && nfs_have_delegation(inode, FMODE_WRITE)) - nfsi->change_attr++; + if (!nfsi->npages) { + igrab(inode); + if (nfs_have_delegation(inode, FMODE_WRITE)) + nfsi->change_attr++; + } set_bit(PG_MAPPED, &req->wb_flags); SetPagePrivate(req->wb_page); set_page_private(req->wb_page, (unsigned long)req); @@ -420,7 +423,11 @@ static void nfs_inode_remove_request(struct nfs_page *req) clear_bit(PG_MAPPED, &req->wb_flags); radix_tree_delete(&nfsi->nfs_page_tree, req->wb_index); nfsi->npages--; - spin_unlock(&inode->i_lock); + if (!nfsi->npages) { + spin_unlock(&inode->i_lock); + iput(inode); + } else + spin_unlock(&inode->i_lock); nfs_release_request(req); } diff --git a/trunk/fs/ocfs2/acl.c b/trunk/fs/ocfs2/acl.c index e913ad130fdd..90f2729b7a5b 100644 --- a/trunk/fs/ocfs2/acl.c +++ b/trunk/fs/ocfs2/acl.c @@ -24,6 +24,7 @@ #include #include +#define MLOG_MASK_PREFIX ML_INODE #include #include "ocfs2.h" diff --git a/trunk/fs/ocfs2/alloc.c b/trunk/fs/ocfs2/alloc.c index b27a0d86f8c5..e4984e259cb6 100644 --- a/trunk/fs/ocfs2/alloc.c +++ b/trunk/fs/ocfs2/alloc.c @@ -30,6 +30,7 @@ #include #include +#define MLOG_MASK_PREFIX ML_DISK_ALLOC #include #include "ocfs2.h" @@ -49,7 +50,6 @@ #include "uptodate.h" #include "xattr.h" #include "refcounttree.h" -#include "ocfs2_trace.h" #include "buffer_head_io.h" @@ -886,7 +886,8 @@ static int ocfs2_validate_extent_block(struct super_block *sb, struct ocfs2_extent_block *eb = (struct ocfs2_extent_block *)bh->b_data; - trace_ocfs2_validate_extent_block((unsigned long long)bh->b_blocknr); + mlog(0, "Validating extent block %llu\n", + (unsigned long long)bh->b_blocknr); BUG_ON(!buffer_uptodate(bh)); @@ -964,6 +965,8 @@ int ocfs2_num_free_extents(struct ocfs2_super *osb, struct buffer_head *eb_bh = NULL; u64 last_eb_blk = 0; + mlog_entry_void(); + el = et->et_root_el; last_eb_blk = ocfs2_et_get_last_eb_blk(et); @@ -984,7 +987,7 @@ int ocfs2_num_free_extents(struct ocfs2_super *osb, bail: brelse(eb_bh); - trace_ocfs2_num_free_extents(retval); + mlog_exit(retval); return retval; } @@ -1007,6 +1010,8 @@ static int ocfs2_create_new_meta_bhs(handle_t *handle, OCFS2_SB(ocfs2_metadata_cache_get_super(et->et_ci)); struct ocfs2_extent_block *eb; + mlog_entry_void(); + count = 0; while (count < wanted) { status = ocfs2_claim_metadata(handle, @@ -1069,8 +1074,8 @@ static int ocfs2_create_new_meta_bhs(handle_t *handle, brelse(bhs[i]); bhs[i] = NULL; } - mlog_errno(status); } + mlog_exit(status); return status; } @@ -1168,6 +1173,8 @@ static int ocfs2_add_branch(handle_t *handle, struct ocfs2_extent_list *el; u32 new_cpos, root_end; + mlog_entry_void(); + BUG_ON(!last_eb_bh || !*last_eb_bh); if (eb_bh) { @@ -1193,11 +1200,8 @@ static int ocfs2_add_branch(handle_t *handle, * from new_cpos). */ if (root_end > new_cpos) { - trace_ocfs2_adjust_rightmost_branch( - (unsigned long long) - ocfs2_metadata_cache_owner(et->et_ci), - root_end, new_cpos); - + mlog(0, "adjust the cluster end from %u to %u\n", + root_end, new_cpos); status = ocfs2_adjust_rightmost_branch(handle, et); if (status) { mlog_errno(status); @@ -1328,6 +1332,7 @@ static int ocfs2_add_branch(handle_t *handle, kfree(new_eb_bhs); } + mlog_exit(status); return status; } @@ -1348,6 +1353,8 @@ static int ocfs2_shift_tree_depth(handle_t *handle, struct ocfs2_extent_list *root_el; struct ocfs2_extent_list *eb_el; + mlog_entry_void(); + status = ocfs2_create_new_meta_bhs(handle, et, 1, meta_ac, &new_eb_bh); if (status < 0) { @@ -1408,6 +1415,7 @@ static int ocfs2_shift_tree_depth(handle_t *handle, bail: brelse(new_eb_bh); + mlog_exit(status); return status; } @@ -1438,6 +1446,8 @@ static int ocfs2_find_branch_target(struct ocfs2_extent_tree *et, struct buffer_head *bh = NULL; struct buffer_head *lowest_bh = NULL; + mlog_entry_void(); + *target_bh = NULL; el = et->et_root_el; @@ -1493,6 +1503,7 @@ static int ocfs2_find_branch_target(struct ocfs2_extent_tree *et, bail: brelse(bh); + mlog_exit(status); return status; } @@ -1529,10 +1540,7 @@ static int ocfs2_grow_tree(handle_t *handle, struct ocfs2_extent_tree *et, * another tree level */ if (shift) { BUG_ON(bh); - trace_ocfs2_grow_tree( - (unsigned long long) - ocfs2_metadata_cache_owner(et->et_ci), - depth); + mlog(0, "need to shift tree depth (current = %d)\n", depth); /* ocfs2_shift_tree_depth will return us a buffer with * the new extent block (so we can pass that to @@ -1562,6 +1570,7 @@ static int ocfs2_grow_tree(handle_t *handle, struct ocfs2_extent_tree *et, /* call ocfs2_add_branch to add the final part of the tree with * the new data. */ + mlog(0, "add branch. bh = %p\n", bh); ret = ocfs2_add_branch(handle, et, bh, last_eb_bh, meta_ac); if (ret < 0) { @@ -1636,9 +1645,8 @@ static void ocfs2_rotate_leaf(struct ocfs2_extent_list *el, } insert_index = i; - trace_ocfs2_rotate_leaf(insert_cpos, insert_index, - has_empty, next_free, - le16_to_cpu(el->l_count)); + mlog(0, "ins %u: index %d, has_empty %d, next_free %d, count %d\n", + insert_cpos, insert_index, has_empty, next_free, le16_to_cpu(el->l_count)); BUG_ON(insert_index < 0); BUG_ON(insert_index >= le16_to_cpu(el->l_count)); @@ -2051,7 +2059,7 @@ static void ocfs2_complete_edge_insert(handle_t *handle, left_el = path_leaf_el(left_path); right_el = path_leaf_el(right_path); for(i = left_path->p_tree_depth - 1; i > subtree_index; i--) { - trace_ocfs2_complete_edge_insert(i); + mlog(0, "Adjust records at index %u\n", i); /* * One nice property of knowing that all of these @@ -2381,9 +2389,7 @@ static int ocfs2_rotate_tree_right(handle_t *handle, goto out; } - trace_ocfs2_rotate_tree_right( - (unsigned long long)ocfs2_metadata_cache_owner(et->et_ci), - insert_cpos, cpos); + mlog(0, "Insert: %u, first left path cpos: %u\n", insert_cpos, cpos); /* * What we want to do here is: @@ -2412,10 +2418,8 @@ static int ocfs2_rotate_tree_right(handle_t *handle, * rotating subtrees. */ while (cpos && insert_cpos <= cpos) { - trace_ocfs2_rotate_tree_right( - (unsigned long long) - ocfs2_metadata_cache_owner(et->et_ci), - insert_cpos, cpos); + mlog(0, "Rotating a tree: ins. cpos: %u, left path cpos: %u\n", + insert_cpos, cpos); ret = ocfs2_find_path(et->et_ci, left_path, cpos); if (ret) { @@ -2457,10 +2461,10 @@ static int ocfs2_rotate_tree_right(handle_t *handle, start = ocfs2_find_subtree_root(et, left_path, right_path); - trace_ocfs2_rotate_subtree(start, - (unsigned long long) - right_path->p_node[start].bh->b_blocknr, - right_path->p_tree_depth); + mlog(0, "Subtree root at index %d (blk %llu, depth %d)\n", + start, + (unsigned long long) right_path->p_node[start].bh->b_blocknr, + right_path->p_tree_depth); ret = ocfs2_extend_rotate_transaction(handle, start, orig_credits, right_path); @@ -2960,7 +2964,8 @@ static int __ocfs2_rotate_tree_left(handle_t *handle, subtree_root = ocfs2_find_subtree_root(et, left_path, right_path); - trace_ocfs2_rotate_subtree(subtree_root, + mlog(0, "Subtree root at index %d (blk %llu, depth %d)\n", + subtree_root, (unsigned long long) right_path->p_node[subtree_root].bh->b_blocknr, right_path->p_tree_depth); @@ -3984,11 +3989,9 @@ static int ocfs2_append_rec_to_path(handle_t *handle, goto out; } - trace_ocfs2_append_rec_to_path( - (unsigned long long) - ocfs2_metadata_cache_owner(et->et_ci), - le32_to_cpu(insert_rec->e_cpos), - left_cpos); + mlog(0, "Append may need a left path update. cpos: %u, " + "left_cpos: %u\n", le32_to_cpu(insert_rec->e_cpos), + left_cpos); /* * No need to worry if the append is already in the @@ -4559,7 +4562,7 @@ static int ocfs2_figure_insert_type(struct ocfs2_extent_tree *et, ocfs2_et_get_last_eb_blk(et), &bh); if (ret) { - mlog_errno(ret); + mlog_exit(ret); goto out; } eb = (struct ocfs2_extent_block *) bh->b_data; @@ -4675,9 +4678,9 @@ int ocfs2_insert_extent(handle_t *handle, struct ocfs2_insert_type insert = {0, }; struct ocfs2_extent_rec rec; - trace_ocfs2_insert_extent_start( - (unsigned long long)ocfs2_metadata_cache_owner(et->et_ci), - cpos, new_clusters); + mlog(0, "add %u clusters at position %u to owner %llu\n", + new_clusters, cpos, + (unsigned long long)ocfs2_metadata_cache_owner(et->et_ci)); memset(&rec, 0, sizeof(rec)); rec.e_cpos = cpu_to_le32(cpos); @@ -4697,9 +4700,11 @@ int ocfs2_insert_extent(handle_t *handle, goto bail; } - trace_ocfs2_insert_extent(insert.ins_appending, insert.ins_contig, - insert.ins_contig_index, free_records, - insert.ins_tree_depth); + mlog(0, "Insert.appending: %u, Insert.Contig: %u, " + "Insert.contig_index: %d, Insert.free_records: %d, " + "Insert.tree_depth: %d\n", + insert.ins_appending, insert.ins_contig, insert.ins_contig_index, + free_records, insert.ins_tree_depth); if (insert.ins_contig == CONTIG_NONE && free_records == 0) { status = ocfs2_grow_tree(handle, et, @@ -4721,6 +4726,7 @@ int ocfs2_insert_extent(handle_t *handle, bail: brelse(last_eb_bh); + mlog_exit(status); return status; } @@ -4740,7 +4746,7 @@ int ocfs2_add_clusters_in_btree(handle_t *handle, struct ocfs2_alloc_context *meta_ac, enum ocfs2_alloc_restarted *reason_ret) { - int status = 0, err = 0; + int status = 0; int free_extents; enum ocfs2_alloc_restarted reason = RESTART_NONE; u32 bit_off, num_bits; @@ -4767,14 +4773,14 @@ int ocfs2_add_clusters_in_btree(handle_t *handle, * 2) we are so fragmented, we've needed to add metadata too * many times. */ if (!free_extents && !meta_ac) { - err = -1; + mlog(0, "we haven't reserved any metadata!\n"); status = -EAGAIN; reason = RESTART_META; goto leave; } else if ((!free_extents) && (ocfs2_alloc_context_bits_left(meta_ac) < ocfs2_extend_meta_needed(et->et_root_el))) { - err = -2; + mlog(0, "filesystem is really fragmented...\n"); status = -EAGAIN; reason = RESTART_META; goto leave; @@ -4799,9 +4805,9 @@ int ocfs2_add_clusters_in_btree(handle_t *handle, } block = ocfs2_clusters_to_blocks(osb->sb, bit_off); - trace_ocfs2_add_clusters_in_btree( - (unsigned long long)ocfs2_metadata_cache_owner(et->et_ci), - bit_off, num_bits); + mlog(0, "Allocating %u clusters at block %u for owner %llu\n", + num_bits, bit_off, + (unsigned long long)ocfs2_metadata_cache_owner(et->et_ci)); status = ocfs2_insert_extent(handle, et, *logical_offset, block, num_bits, flags, meta_ac); if (status < 0) { @@ -4815,15 +4821,16 @@ int ocfs2_add_clusters_in_btree(handle_t *handle, *logical_offset += num_bits; if (clusters_to_add) { - err = clusters_to_add; + mlog(0, "need to alloc once more, wanted = %u\n", + clusters_to_add); status = -EAGAIN; reason = RESTART_TRANS; } leave: + mlog_exit(status); if (reason_ret) *reason_ret = reason; - trace_ocfs2_add_clusters_in_btree_ret(status, reason, err); return status; } @@ -5032,7 +5039,7 @@ int ocfs2_split_extent(handle_t *handle, ocfs2_et_get_last_eb_blk(et), &last_eb_bh); if (ret) { - mlog_errno(ret); + mlog_exit(ret); goto out; } @@ -5049,9 +5056,9 @@ int ocfs2_split_extent(handle_t *handle, ctxt.c_has_empty_extent = ocfs2_is_empty_extent(&el->l_recs[0]); - trace_ocfs2_split_extent(split_index, ctxt.c_contig_type, - ctxt.c_has_empty_extent, - ctxt.c_split_covers_rec); + mlog(0, "index: %d, contig: %u, has_empty: %u, split_covers: %u\n", + split_index, ctxt.c_contig_type, ctxt.c_has_empty_extent, + ctxt.c_split_covers_rec); if (ctxt.c_contig_type == CONTIG_NONE) { if (ctxt.c_split_covers_rec) @@ -5185,9 +5192,8 @@ int ocfs2_mark_extent_written(struct inode *inode, { int ret; - trace_ocfs2_mark_extent_written( - (unsigned long long)OCFS2_I(inode)->ip_blkno, - cpos, len, phys); + mlog(0, "Inode %lu cpos %u, len %u, phys clusters %u\n", + inode->i_ino, cpos, len, phys); if (!ocfs2_writes_unwritten_extents(OCFS2_SB(inode->i_sb))) { ocfs2_error(inode->i_sb, "Inode %llu has unwritten extents " @@ -5506,10 +5512,11 @@ int ocfs2_remove_extent(handle_t *handle, BUG_ON(cpos < le32_to_cpu(rec->e_cpos) || trunc_range > rec_range); - trace_ocfs2_remove_extent( - (unsigned long long)ocfs2_metadata_cache_owner(et->et_ci), - cpos, len, index, le32_to_cpu(rec->e_cpos), - ocfs2_rec_clusters(el, rec)); + mlog(0, "Owner %llu, remove (cpos %u, len %u). Existing index %d " + "(cpos %u, len %u)\n", + (unsigned long long)ocfs2_metadata_cache_owner(et->et_ci), + cpos, len, index, + le32_to_cpu(rec->e_cpos), ocfs2_rec_clusters(el, rec)); if (le32_to_cpu(rec->e_cpos) == cpos || rec_range == trunc_range) { ret = ocfs2_truncate_rec(handle, et, path, index, dealloc, @@ -5788,6 +5795,9 @@ int ocfs2_truncate_log_append(struct ocfs2_super *osb, struct ocfs2_dinode *di; struct ocfs2_truncate_log *tl; + mlog_entry("start_blk = %llu, num_clusters = %u\n", + (unsigned long long)start_blk, num_clusters); + BUG_ON(mutex_trylock(&tl_inode->i_mutex)); start_cluster = ocfs2_blocks_to_clusters(osb->sb, start_blk); @@ -5824,9 +5834,10 @@ int ocfs2_truncate_log_append(struct ocfs2_super *osb, goto bail; } - trace_ocfs2_truncate_log_append( - (unsigned long long)OCFS2_I(tl_inode)->ip_blkno, index, - start_cluster, num_clusters); + mlog(0, "Log truncate of %u clusters starting at cluster %u to " + "%llu (index = %d)\n", num_clusters, start_cluster, + (unsigned long long)OCFS2_I(tl_inode)->ip_blkno, index); + if (ocfs2_truncate_log_can_coalesce(tl, start_cluster)) { /* * Move index back to the record we are coalescing with. @@ -5835,10 +5846,9 @@ int ocfs2_truncate_log_append(struct ocfs2_super *osb, index--; num_clusters += le32_to_cpu(tl->tl_recs[index].t_clusters); - trace_ocfs2_truncate_log_append( - (unsigned long long)OCFS2_I(tl_inode)->ip_blkno, - index, le32_to_cpu(tl->tl_recs[index].t_start), - num_clusters); + mlog(0, "Coalesce with index %u (start = %u, clusters = %u)\n", + index, le32_to_cpu(tl->tl_recs[index].t_start), + num_clusters); } else { tl->tl_recs[index].t_start = cpu_to_le32(start_cluster); tl->tl_used = cpu_to_le16(index + 1); @@ -5849,6 +5859,7 @@ int ocfs2_truncate_log_append(struct ocfs2_super *osb, osb->truncated_clusters += num_clusters; bail: + mlog_exit(status); return status; } @@ -5867,6 +5878,8 @@ static int ocfs2_replay_truncate_records(struct ocfs2_super *osb, struct inode *tl_inode = osb->osb_tl_inode; struct buffer_head *tl_bh = osb->osb_tl_bh; + mlog_entry_void(); + di = (struct ocfs2_dinode *) tl_bh->b_data; tl = &di->id2.i_dealloc; i = le16_to_cpu(tl->tl_used) - 1; @@ -5902,9 +5915,8 @@ static int ocfs2_replay_truncate_records(struct ocfs2_super *osb, /* if start_blk is not set, we ignore the record as * invalid. */ if (start_blk) { - trace_ocfs2_replay_truncate_records( - (unsigned long long)OCFS2_I(tl_inode)->ip_blkno, - i, le32_to_cpu(rec.t_start), num_clusters); + mlog(0, "free record %d, start = %u, clusters = %u\n", + i, le32_to_cpu(rec.t_start), num_clusters); status = ocfs2_free_clusters(handle, data_alloc_inode, data_alloc_bh, start_blk, @@ -5920,6 +5932,7 @@ static int ocfs2_replay_truncate_records(struct ocfs2_super *osb, osb->truncated_clusters = 0; bail: + mlog_exit(status); return status; } @@ -5936,6 +5949,8 @@ int __ocfs2_flush_truncate_log(struct ocfs2_super *osb) struct ocfs2_dinode *di; struct ocfs2_truncate_log *tl; + mlog_entry_void(); + BUG_ON(mutex_trylock(&tl_inode->i_mutex)); di = (struct ocfs2_dinode *) tl_bh->b_data; @@ -5947,9 +5962,8 @@ int __ocfs2_flush_truncate_log(struct ocfs2_super *osb) tl = &di->id2.i_dealloc; num_to_flush = le16_to_cpu(tl->tl_used); - trace_ocfs2_flush_truncate_log( - (unsigned long long)OCFS2_I(tl_inode)->ip_blkno, - num_to_flush); + mlog(0, "Flush %u records from truncate log #%llu\n", + num_to_flush, (unsigned long long)OCFS2_I(tl_inode)->ip_blkno); if (!num_to_flush) { status = 0; goto out; @@ -5995,6 +6009,7 @@ int __ocfs2_flush_truncate_log(struct ocfs2_super *osb) iput(data_alloc_inode); out: + mlog_exit(status); return status; } @@ -6017,11 +6032,15 @@ static void ocfs2_truncate_log_worker(struct work_struct *work) container_of(work, struct ocfs2_super, osb_truncate_log_wq.work); + mlog_entry_void(); + status = ocfs2_flush_truncate_log(osb); if (status < 0) mlog_errno(status); else ocfs2_init_steal_slots(osb); + + mlog_exit(status); } #define OCFS2_TRUNCATE_LOG_FLUSH_INTERVAL (2 * HZ) @@ -6067,6 +6086,7 @@ static int ocfs2_get_truncate_log_info(struct ocfs2_super *osb, *tl_inode = inode; *tl_bh = bh; bail: + mlog_exit(status); return status; } @@ -6086,7 +6106,7 @@ int ocfs2_begin_truncate_log_recovery(struct ocfs2_super *osb, *tl_copy = NULL; - trace_ocfs2_begin_truncate_log_recovery(slot_num); + mlog(0, "recover truncate log from slot %d\n", slot_num); status = ocfs2_get_truncate_log_info(osb, slot_num, &tl_inode, &tl_bh); if (status < 0) { @@ -6103,7 +6123,8 @@ int ocfs2_begin_truncate_log_recovery(struct ocfs2_super *osb, tl = &di->id2.i_dealloc; if (le16_to_cpu(tl->tl_used)) { - trace_ocfs2_truncate_log_recovery_num(le16_to_cpu(tl->tl_used)); + mlog(0, "We'll have %u logs to recover\n", + le16_to_cpu(tl->tl_used)); *tl_copy = kmalloc(tl_bh->b_size, GFP_KERNEL); if (!(*tl_copy)) { @@ -6136,9 +6157,9 @@ int ocfs2_begin_truncate_log_recovery(struct ocfs2_super *osb, if (status < 0 && (*tl_copy)) { kfree(*tl_copy); *tl_copy = NULL; - mlog_errno(status); } + mlog_exit(status); return status; } @@ -6153,6 +6174,8 @@ int ocfs2_complete_truncate_log_recovery(struct ocfs2_super *osb, struct inode *tl_inode = osb->osb_tl_inode; struct ocfs2_truncate_log *tl; + mlog_entry_void(); + if (OCFS2_I(tl_inode)->ip_blkno == le64_to_cpu(tl_copy->i_blkno)) { mlog(ML_ERROR, "Asked to recover my own truncate log!\n"); return -EINVAL; @@ -6160,9 +6183,8 @@ int ocfs2_complete_truncate_log_recovery(struct ocfs2_super *osb, tl = &tl_copy->id2.i_dealloc; num_recs = le16_to_cpu(tl->tl_used); - trace_ocfs2_complete_truncate_log_recovery( - (unsigned long long)le64_to_cpu(tl_copy->i_blkno), - num_recs); + mlog(0, "cleanup %u records from %llu\n", num_recs, + (unsigned long long)le64_to_cpu(tl_copy->i_blkno)); mutex_lock(&tl_inode->i_mutex); for(i = 0; i < num_recs; i++) { @@ -6197,6 +6219,7 @@ int ocfs2_complete_truncate_log_recovery(struct ocfs2_super *osb, bail_up: mutex_unlock(&tl_inode->i_mutex); + mlog_exit(status); return status; } @@ -6205,6 +6228,8 @@ void ocfs2_truncate_log_shutdown(struct ocfs2_super *osb) int status; struct inode *tl_inode = osb->osb_tl_inode; + mlog_entry_void(); + if (tl_inode) { cancel_delayed_work(&osb->osb_truncate_log_wq); flush_workqueue(ocfs2_wq); @@ -6216,6 +6241,8 @@ void ocfs2_truncate_log_shutdown(struct ocfs2_super *osb) brelse(osb->osb_tl_bh); iput(osb->osb_tl_inode); } + + mlog_exit_void(); } int ocfs2_truncate_log_init(struct ocfs2_super *osb) @@ -6224,6 +6251,8 @@ int ocfs2_truncate_log_init(struct ocfs2_super *osb) struct inode *tl_inode = NULL; struct buffer_head *tl_bh = NULL; + mlog_entry_void(); + status = ocfs2_get_truncate_log_info(osb, osb->slot_num, &tl_inode, @@ -6239,6 +6268,7 @@ int ocfs2_truncate_log_init(struct ocfs2_super *osb) osb->osb_tl_bh = tl_bh; osb->osb_tl_inode = tl_inode; + mlog_exit(status); return status; } @@ -6320,8 +6350,8 @@ static int ocfs2_free_cached_blocks(struct ocfs2_super *osb, else bg_blkno = ocfs2_which_suballoc_group(head->free_blk, head->free_bit); - trace_ocfs2_free_cached_blocks( - (unsigned long long)head->free_blk, head->free_bit); + mlog(0, "Free bit: (bit %u, blkno %llu)\n", + head->free_bit, (unsigned long long)head->free_blk); ret = ocfs2_free_suballoc_bits(handle, inode, di_bh, head->free_bit, bg_blkno, 1); @@ -6374,7 +6404,8 @@ int ocfs2_cache_cluster_dealloc(struct ocfs2_cached_dealloc_ctxt *ctxt, return ret; } - trace_ocfs2_cache_cluster_dealloc((unsigned long long)blkno, bit); + mlog(0, "Insert clusters: (bit %u, blk %llu)\n", + bit, (unsigned long long)blkno); item->free_blk = blkno; item->free_bit = bit; @@ -6449,8 +6480,8 @@ int ocfs2_run_deallocs(struct ocfs2_super *osb, fl = ctxt->c_first_suballocator; if (fl->f_first) { - trace_ocfs2_run_deallocs(fl->f_inode_type, - fl->f_slot); + mlog(0, "Free items: (type %u, slot %d)\n", + fl->f_inode_type, fl->f_slot); ret2 = ocfs2_free_cached_blocks(osb, fl->f_inode_type, fl->f_slot, @@ -6527,9 +6558,8 @@ int ocfs2_cache_block_dealloc(struct ocfs2_cached_dealloc_ctxt *ctxt, goto out; } - trace_ocfs2_cache_block_dealloc(type, slot, - (unsigned long long)suballoc, - (unsigned long long)blkno, bit); + mlog(0, "Insert: (type %d, slot %u, bit %u, blk %llu)\n", + type, slot, bit, (unsigned long long)blkno); item->free_bg = suballoc; item->free_blk = blkno; @@ -6975,6 +7005,8 @@ int ocfs2_commit_truncate(struct ocfs2_super *osb, struct ocfs2_extent_tree et; struct ocfs2_cached_dealloc_ctxt dealloc; + mlog_entry_void(); + ocfs2_init_dinode_extent_tree(&et, INODE_CACHE(inode), di_bh); ocfs2_init_dealloc_ctxt(&dealloc); @@ -7009,11 +7041,8 @@ int ocfs2_commit_truncate(struct ocfs2_super *osb, goto bail; } - trace_ocfs2_commit_truncate( - (unsigned long long)OCFS2_I(inode)->ip_blkno, - new_highest_cpos, - OCFS2_I(inode)->ip_clusters, - path->p_tree_depth); + mlog(0, "inode->ip_clusters = %u, tree_depth = %u\n", + OCFS2_I(inode)->ip_clusters, path->p_tree_depth); /* * By now, el will point to the extent list on the bottom most @@ -7107,6 +7136,7 @@ int ocfs2_commit_truncate(struct ocfs2_super *osb, ocfs2_free_path(path); + mlog_exit(status); return status; } diff --git a/trunk/fs/ocfs2/aops.c b/trunk/fs/ocfs2/aops.c index ac97bca282d2..daea0359e974 100644 --- a/trunk/fs/ocfs2/aops.c +++ b/trunk/fs/ocfs2/aops.c @@ -29,6 +29,7 @@ #include #include +#define MLOG_MASK_PREFIX ML_FILE_IO #include #include "ocfs2.h" @@ -44,7 +45,6 @@ #include "super.h" #include "symlink.h" #include "refcounttree.h" -#include "ocfs2_trace.h" #include "buffer_head_io.h" @@ -59,9 +59,8 @@ static int ocfs2_symlink_get_block(struct inode *inode, sector_t iblock, struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); void *kaddr; - trace_ocfs2_symlink_get_block( - (unsigned long long)OCFS2_I(inode)->ip_blkno, - (unsigned long long)iblock, bh_result, create); + mlog_entry("(0x%p, %llu, 0x%p, %d)\n", inode, + (unsigned long long)iblock, bh_result, create); BUG_ON(ocfs2_inode_is_fast_symlink(inode)); @@ -124,6 +123,7 @@ static int ocfs2_symlink_get_block(struct inode *inode, sector_t iblock, bail: brelse(bh); + mlog_exit(err); return err; } @@ -136,8 +136,8 @@ int ocfs2_get_block(struct inode *inode, sector_t iblock, u64 p_blkno, count, past_eof; struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); - trace_ocfs2_get_block((unsigned long long)OCFS2_I(inode)->ip_blkno, - (unsigned long long)iblock, bh_result, create); + mlog_entry("(0x%p, %llu, 0x%p, %d)\n", inode, + (unsigned long long)iblock, bh_result, create); if (OCFS2_I(inode)->ip_flags & OCFS2_INODE_SYSTEM_FILE) mlog(ML_NOTICE, "get_block on system inode 0x%p (%lu)\n", @@ -199,9 +199,8 @@ int ocfs2_get_block(struct inode *inode, sector_t iblock, } past_eof = ocfs2_blocks_for_bytes(inode->i_sb, i_size_read(inode)); - - trace_ocfs2_get_block_end((unsigned long long)OCFS2_I(inode)->ip_blkno, - (unsigned long long)past_eof); + mlog(0, "Inode %lu, past_eof = %llu\n", inode->i_ino, + (unsigned long long)past_eof); if (create && (iblock >= past_eof)) set_buffer_new(bh_result); @@ -209,6 +208,7 @@ int ocfs2_get_block(struct inode *inode, sector_t iblock, if (err < 0) err = -EIO; + mlog_exit(err); return err; } @@ -278,8 +278,7 @@ static int ocfs2_readpage(struct file *file, struct page *page) loff_t start = (loff_t)page->index << PAGE_CACHE_SHIFT; int ret, unlock = 1; - trace_ocfs2_readpage((unsigned long long)oi->ip_blkno, - (page ? page->index : 0)); + mlog_entry("(0x%p, %lu)\n", file, (page ? page->index : 0)); ret = ocfs2_inode_lock_with_page(inode, NULL, 0, page); if (ret != 0) { @@ -324,6 +323,7 @@ static int ocfs2_readpage(struct file *file, struct page *page) out: if (unlock) unlock_page(page); + mlog_exit(ret); return ret; } @@ -396,11 +396,15 @@ static int ocfs2_readpages(struct file *filp, struct address_space *mapping, */ static int ocfs2_writepage(struct page *page, struct writeback_control *wbc) { - trace_ocfs2_writepage( - (unsigned long long)OCFS2_I(page->mapping->host)->ip_blkno, - page->index); + int ret; + + mlog_entry("(0x%p)\n", page); + + ret = block_write_full_page(page, ocfs2_get_block, wbc); - return block_write_full_page(page, ocfs2_get_block, wbc); + mlog_exit(ret); + + return ret; } /* Taken from ext3. We don't necessarily need the full blown @@ -446,8 +450,7 @@ static sector_t ocfs2_bmap(struct address_space *mapping, sector_t block) int err = 0; struct inode *inode = mapping->host; - trace_ocfs2_bmap((unsigned long long)OCFS2_I(inode)->ip_blkno, - (unsigned long long)block); + mlog_entry("(block = %llu)\n", (unsigned long long)block); /* We don't need to lock journal system files, since they aren't * accessed concurrently from multiple nodes. @@ -481,6 +484,8 @@ static sector_t ocfs2_bmap(struct address_space *mapping, sector_t block) bail: status = err ? 0 : p_blkno; + mlog_exit((int)status); + return status; } @@ -611,6 +616,9 @@ static ssize_t ocfs2_direct_IO(int rw, { struct file *file = iocb->ki_filp; struct inode *inode = file->f_path.dentry->d_inode->i_mapping->host; + int ret; + + mlog_entry_void(); /* * Fallback to buffered I/O if we see an inode without @@ -623,10 +631,13 @@ static ssize_t ocfs2_direct_IO(int rw, if (i_size_read(inode) <= offset) return 0; - return __blockdev_direct_IO(rw, iocb, inode, inode->i_sb->s_bdev, - iov, offset, nr_segs, - ocfs2_direct_IO_get_blocks, - ocfs2_dio_end_io, NULL, 0); + ret = __blockdev_direct_IO(rw, iocb, inode, inode->i_sb->s_bdev, + iov, offset, nr_segs, + ocfs2_direct_IO_get_blocks, + ocfs2_dio_end_io, NULL, 0); + + mlog_exit(ret); + return ret; } static void ocfs2_figure_cluster_boundaries(struct ocfs2_super *osb, @@ -1015,12 +1026,6 @@ static int ocfs2_prepare_page_for_write(struct inode *inode, u64 *p_blkno, ocfs2_figure_cluster_boundaries(OCFS2_SB(inode->i_sb), cpos, &cluster_start, &cluster_end); - /* treat the write as new if the a hole/lseek spanned across - * the page boundary. - */ - new = new | ((i_size_read(inode) <= page_offset(page)) && - (page_offset(page) <= user_pos)); - if (page == wc->w_target_page) { map_from = user_pos & (PAGE_CACHE_SIZE - 1); map_to = map_from + user_len; @@ -1529,9 +1534,9 @@ static int ocfs2_try_to_write_inline_data(struct address_space *mapping, struct ocfs2_inode_info *oi = OCFS2_I(inode); struct ocfs2_dinode *di = NULL; - trace_ocfs2_try_to_write_inline_data((unsigned long long)oi->ip_blkno, - len, (unsigned long long)pos, - oi->ip_dyn_features); + mlog(0, "Inode %llu, write of %u bytes at off %llu. features: 0x%x\n", + (unsigned long long)oi->ip_blkno, len, (unsigned long long)pos, + oi->ip_dyn_features); /* * Handle inodes which already have inline data 1st. @@ -1734,13 +1739,6 @@ int ocfs2_write_begin_nolock(struct file *filp, di = (struct ocfs2_dinode *)wc->w_di_bh->b_data; - trace_ocfs2_write_begin_nolock( - (unsigned long long)OCFS2_I(inode)->ip_blkno, - (long long)i_size_read(inode), - le32_to_cpu(di->i_clusters), - pos, len, flags, mmap_page, - clusters_to_alloc, extents_to_split); - /* * We set w_target_from, w_target_to here so that * ocfs2_write_end() knows which range in the target page to @@ -1753,6 +1751,12 @@ int ocfs2_write_begin_nolock(struct file *filp, * ocfs2_lock_allocators(). It greatly over-estimates * the work to be done. */ + mlog(0, "extend inode %llu, i_size = %lld, di->i_clusters = %u," + " clusters_to_add = %u, extents_to_split = %u\n", + (unsigned long long)OCFS2_I(inode)->ip_blkno, + (long long)i_size_read(inode), le32_to_cpu(di->i_clusters), + clusters_to_alloc, extents_to_split); + ocfs2_init_dinode_extent_tree(&et, INODE_CACHE(inode), wc->w_di_bh); ret = ocfs2_lock_allocators(inode, &et, @@ -1934,8 +1938,8 @@ static void ocfs2_write_end_inline(struct inode *inode, loff_t pos, memcpy(di->id2.i_data.id_data + pos, kaddr + pos, *copied); kunmap_atomic(kaddr, KM_USER0); - trace_ocfs2_write_end_inline( - (unsigned long long)OCFS2_I(inode)->ip_blkno, + mlog(0, "Data written to inode at offset %llu. " + "id_count = %u, copied = %u, i_dyn_features = 0x%x\n", (unsigned long long)pos, *copied, le16_to_cpu(di->id2.i_data.id_count), le16_to_cpu(di->i_dyn_features)); diff --git a/trunk/fs/ocfs2/buffer_head_io.c b/trunk/fs/ocfs2/buffer_head_io.c index 5d18ad10c27f..f9d5d3ffc75a 100644 --- a/trunk/fs/ocfs2/buffer_head_io.c +++ b/trunk/fs/ocfs2/buffer_head_io.c @@ -35,8 +35,8 @@ #include "inode.h" #include "journal.h" #include "uptodate.h" + #include "buffer_head_io.h" -#include "ocfs2_trace.h" /* * Bits on bh->b_state used by ocfs2. @@ -55,7 +55,8 @@ int ocfs2_write_block(struct ocfs2_super *osb, struct buffer_head *bh, { int ret = 0; - trace_ocfs2_write_block((unsigned long long)bh->b_blocknr, ci); + mlog_entry("(bh->b_blocknr = %llu, ci=%p)\n", + (unsigned long long)bh->b_blocknr, ci); BUG_ON(bh->b_blocknr < OCFS2_SUPER_BLOCK_BLKNO); BUG_ON(buffer_jbd(bh)); @@ -65,7 +66,6 @@ int ocfs2_write_block(struct ocfs2_super *osb, struct buffer_head *bh, * can get modified during recovery even if read-only. */ if (ocfs2_is_hard_readonly(osb)) { ret = -EROFS; - mlog_errno(ret); goto out; } @@ -91,11 +91,11 @@ int ocfs2_write_block(struct ocfs2_super *osb, struct buffer_head *bh, * uptodate. */ ret = -EIO; put_bh(bh); - mlog_errno(ret); } ocfs2_metadata_cache_io_unlock(ci); out: + mlog_exit(ret); return ret; } @@ -106,10 +106,10 @@ int ocfs2_read_blocks_sync(struct ocfs2_super *osb, u64 block, unsigned int i; struct buffer_head *bh; - trace_ocfs2_read_blocks_sync((unsigned long long)block, nr); - - if (!nr) + if (!nr) { + mlog(ML_BH_IO, "No buffers will be read!\n"); goto bail; + } for (i = 0 ; i < nr ; i++) { if (bhs[i] == NULL) { @@ -123,8 +123,10 @@ int ocfs2_read_blocks_sync(struct ocfs2_super *osb, u64 block, bh = bhs[i]; if (buffer_jbd(bh)) { - trace_ocfs2_read_blocks_sync_jbd( - (unsigned long long)bh->b_blocknr); + mlog(ML_BH_IO, + "trying to sync read a jbd " + "managed bh (blocknr = %llu), skipping\n", + (unsigned long long)bh->b_blocknr); continue; } @@ -184,7 +186,8 @@ int ocfs2_read_blocks(struct ocfs2_caching_info *ci, u64 block, int nr, struct buffer_head *bh; struct super_block *sb = ocfs2_metadata_cache_get_super(ci); - trace_ocfs2_read_blocks_begin(ci, (unsigned long long)block, nr, flags); + mlog_entry("(ci=%p, block=(%llu), nr=(%d), flags=%d)\n", + ci, (unsigned long long)block, nr, flags); BUG_ON(!ci); BUG_ON((flags & OCFS2_BH_READAHEAD) && @@ -204,6 +207,7 @@ int ocfs2_read_blocks(struct ocfs2_caching_info *ci, u64 block, int nr, } if (nr == 0) { + mlog(ML_BH_IO, "No buffers will be read!\n"); status = 0; goto bail; } @@ -247,7 +251,8 @@ int ocfs2_read_blocks(struct ocfs2_caching_info *ci, u64 block, int nr, */ if (!ignore_cache && !ocfs2_buffer_uptodate(ci, bh)) { - trace_ocfs2_read_blocks_from_disk( + mlog(ML_UPTODATE, + "bh (%llu), owner %llu not uptodate\n", (unsigned long long)bh->b_blocknr, (unsigned long long)ocfs2_metadata_cache_owner(ci)); /* We're using ignore_cache here to say @@ -255,10 +260,11 @@ int ocfs2_read_blocks(struct ocfs2_caching_info *ci, u64 block, int nr, ignore_cache = 1; } - trace_ocfs2_read_blocks_bh((unsigned long long)bh->b_blocknr, - ignore_cache, buffer_jbd(bh), buffer_dirty(bh)); - if (buffer_jbd(bh)) { + if (ignore_cache) + mlog(ML_BH_IO, "trying to sync read a jbd " + "managed bh (blocknr = %llu)\n", + (unsigned long long)bh->b_blocknr); continue; } @@ -266,6 +272,9 @@ int ocfs2_read_blocks(struct ocfs2_caching_info *ci, u64 block, int nr, if (buffer_dirty(bh)) { /* This should probably be a BUG, or * at least return an error. */ + mlog(ML_BH_IO, "asking me to sync read a dirty " + "buffer! (blocknr = %llu)\n", + (unsigned long long)bh->b_blocknr); continue; } @@ -358,11 +367,14 @@ int ocfs2_read_blocks(struct ocfs2_caching_info *ci, u64 block, int nr, } ocfs2_metadata_cache_io_unlock(ci); - trace_ocfs2_read_blocks_end((unsigned long long)block, nr, - flags, ignore_cache); + mlog(ML_BH_IO, "block=(%llu), nr=(%d), cached=%s, flags=0x%x\n", + (unsigned long long)block, nr, + ((flags & OCFS2_BH_IGNORE_CACHE) || ignore_cache) ? "no" : "yes", + flags); bail: + mlog_exit(status); return status; } @@ -396,12 +408,13 @@ int ocfs2_write_super_or_backup(struct ocfs2_super *osb, int ret = 0; struct ocfs2_dinode *di = (struct ocfs2_dinode *)bh->b_data; + mlog_entry_void(); + BUG_ON(buffer_jbd(bh)); ocfs2_check_super_or_backup(osb->sb, bh->b_blocknr); if (ocfs2_is_hard_readonly(osb) || ocfs2_is_soft_readonly(osb)) { ret = -EROFS; - mlog_errno(ret); goto out; } @@ -421,9 +434,9 @@ int ocfs2_write_super_or_backup(struct ocfs2_super *osb, if (!buffer_uptodate(bh)) { ret = -EIO; put_bh(bh); - mlog_errno(ret); } out: + mlog_exit(ret); return ret; } diff --git a/trunk/fs/ocfs2/cluster/heartbeat.c b/trunk/fs/ocfs2/cluster/heartbeat.c index 2461eb3272ed..1adab287bd24 100644 --- a/trunk/fs/ocfs2/cluster/heartbeat.c +++ b/trunk/fs/ocfs2/cluster/heartbeat.c @@ -1654,6 +1654,8 @@ static int o2hb_populate_slot_data(struct o2hb_region *reg) struct o2hb_disk_slot *slot; struct o2hb_disk_heartbeat_block *hb_block; + mlog_entry_void(); + ret = o2hb_read_slots(reg, reg->hr_blocks); if (ret) { mlog_errno(ret); @@ -1675,6 +1677,7 @@ static int o2hb_populate_slot_data(struct o2hb_region *reg) } out: + mlog_exit(ret); return ret; } diff --git a/trunk/fs/ocfs2/cluster/masklog.c b/trunk/fs/ocfs2/cluster/masklog.c index 07ac24fd9252..6c61771469af 100644 --- a/trunk/fs/ocfs2/cluster/masklog.c +++ b/trunk/fs/ocfs2/cluster/masklog.c @@ -30,7 +30,7 @@ struct mlog_bits mlog_and_bits = MLOG_BITS_RHS(MLOG_INITIAL_AND_MASK); EXPORT_SYMBOL_GPL(mlog_and_bits); -struct mlog_bits mlog_not_bits = MLOG_BITS_RHS(0); +struct mlog_bits mlog_not_bits = MLOG_BITS_RHS(MLOG_INITIAL_NOT_MASK); EXPORT_SYMBOL_GPL(mlog_not_bits); static ssize_t mlog_mask_show(u64 mask, char *buf) @@ -80,6 +80,8 @@ struct mlog_attribute { } static struct mlog_attribute mlog_attrs[MLOG_MAX_BITS] = { + define_mask(ENTRY), + define_mask(EXIT), define_mask(TCP), define_mask(MSG), define_mask(SOCKET), @@ -91,11 +93,27 @@ static struct mlog_attribute mlog_attrs[MLOG_MAX_BITS] = { define_mask(DLM_THREAD), define_mask(DLM_MASTER), define_mask(DLM_RECOVERY), + define_mask(AIO), + define_mask(JOURNAL), + define_mask(DISK_ALLOC), + define_mask(SUPER), + define_mask(FILE_IO), + define_mask(EXTENT_MAP), define_mask(DLM_GLUE), + define_mask(BH_IO), + define_mask(UPTODATE), + define_mask(NAMEI), + define_mask(INODE), define_mask(VOTE), + define_mask(DCACHE), define_mask(CONN), define_mask(QUORUM), + define_mask(EXPORT), + define_mask(XATTR), + define_mask(QUOTA), + define_mask(REFCOUNT), define_mask(BASTS), + define_mask(RESERVATIONS), define_mask(CLUSTER), define_mask(ERROR), define_mask(NOTICE), diff --git a/trunk/fs/ocfs2/cluster/masklog.h b/trunk/fs/ocfs2/cluster/masklog.h index baa2b9ef7eef..34d6544357d9 100644 --- a/trunk/fs/ocfs2/cluster/masklog.h +++ b/trunk/fs/ocfs2/cluster/masklog.h @@ -82,23 +82,41 @@ /* bits that are frequently given and infrequently matched in the low word */ /* NOTE: If you add a flag, you need to also update masklog.c! */ -#define ML_TCP 0x0000000000000001ULL /* net cluster/tcp.c */ -#define ML_MSG 0x0000000000000002ULL /* net network messages */ -#define ML_SOCKET 0x0000000000000004ULL /* net socket lifetime */ -#define ML_HEARTBEAT 0x0000000000000008ULL /* hb all heartbeat tracking */ -#define ML_HB_BIO 0x0000000000000010ULL /* hb io tracing */ -#define ML_DLMFS 0x0000000000000020ULL /* dlm user dlmfs */ -#define ML_DLM 0x0000000000000040ULL /* dlm general debugging */ -#define ML_DLM_DOMAIN 0x0000000000000080ULL /* dlm domain debugging */ -#define ML_DLM_THREAD 0x0000000000000100ULL /* dlm domain thread */ -#define ML_DLM_MASTER 0x0000000000000200ULL /* dlm master functions */ -#define ML_DLM_RECOVERY 0x0000000000000400ULL /* dlm master functions */ -#define ML_DLM_GLUE 0x0000000000000800ULL /* ocfs2 dlm glue layer */ -#define ML_VOTE 0x0000000000001000ULL /* ocfs2 node messaging */ -#define ML_CONN 0x0000000000002000ULL /* net connection management */ -#define ML_QUORUM 0x0000000000004000ULL /* net connection quorum */ -#define ML_BASTS 0x0000000000008000ULL /* dlmglue asts and basts */ -#define ML_CLUSTER 0x0000000000010000ULL /* cluster stack */ +#define ML_ENTRY 0x0000000000000001ULL /* func call entry */ +#define ML_EXIT 0x0000000000000002ULL /* func call exit */ +#define ML_TCP 0x0000000000000004ULL /* net cluster/tcp.c */ +#define ML_MSG 0x0000000000000008ULL /* net network messages */ +#define ML_SOCKET 0x0000000000000010ULL /* net socket lifetime */ +#define ML_HEARTBEAT 0x0000000000000020ULL /* hb all heartbeat tracking */ +#define ML_HB_BIO 0x0000000000000040ULL /* hb io tracing */ +#define ML_DLMFS 0x0000000000000080ULL /* dlm user dlmfs */ +#define ML_DLM 0x0000000000000100ULL /* dlm general debugging */ +#define ML_DLM_DOMAIN 0x0000000000000200ULL /* dlm domain debugging */ +#define ML_DLM_THREAD 0x0000000000000400ULL /* dlm domain thread */ +#define ML_DLM_MASTER 0x0000000000000800ULL /* dlm master functions */ +#define ML_DLM_RECOVERY 0x0000000000001000ULL /* dlm master functions */ +#define ML_AIO 0x0000000000002000ULL /* ocfs2 aio read and write */ +#define ML_JOURNAL 0x0000000000004000ULL /* ocfs2 journalling functions */ +#define ML_DISK_ALLOC 0x0000000000008000ULL /* ocfs2 disk allocation */ +#define ML_SUPER 0x0000000000010000ULL /* ocfs2 mount / umount */ +#define ML_FILE_IO 0x0000000000020000ULL /* ocfs2 file I/O */ +#define ML_EXTENT_MAP 0x0000000000040000ULL /* ocfs2 extent map caching */ +#define ML_DLM_GLUE 0x0000000000080000ULL /* ocfs2 dlm glue layer */ +#define ML_BH_IO 0x0000000000100000ULL /* ocfs2 buffer I/O */ +#define ML_UPTODATE 0x0000000000200000ULL /* ocfs2 caching sequence #'s */ +#define ML_NAMEI 0x0000000000400000ULL /* ocfs2 directory / namespace */ +#define ML_INODE 0x0000000000800000ULL /* ocfs2 inode manipulation */ +#define ML_VOTE 0x0000000001000000ULL /* ocfs2 node messaging */ +#define ML_DCACHE 0x0000000002000000ULL /* ocfs2 dcache operations */ +#define ML_CONN 0x0000000004000000ULL /* net connection management */ +#define ML_QUORUM 0x0000000008000000ULL /* net connection quorum */ +#define ML_EXPORT 0x0000000010000000ULL /* ocfs2 export operations */ +#define ML_XATTR 0x0000000020000000ULL /* ocfs2 extended attributes */ +#define ML_QUOTA 0x0000000040000000ULL /* ocfs2 quota operations */ +#define ML_REFCOUNT 0x0000000080000000ULL /* refcount tree operations */ +#define ML_BASTS 0x0000000100000000ULL /* dlmglue asts and basts */ +#define ML_RESERVATIONS 0x0000000200000000ULL /* ocfs2 alloc reservations */ +#define ML_CLUSTER 0x0000000400000000ULL /* cluster stack */ /* bits that are infrequently given and frequently matched in the high word */ #define ML_ERROR 0x1000000000000000ULL /* sent to KERN_ERR */ @@ -106,6 +124,7 @@ #define ML_KTHREAD 0x4000000000000000ULL /* kernel thread activity */ #define MLOG_INITIAL_AND_MASK (ML_ERROR|ML_NOTICE) +#define MLOG_INITIAL_NOT_MASK (ML_ENTRY|ML_EXIT) #ifndef MLOG_MASK_PREFIX #define MLOG_MASK_PREFIX 0 #endif @@ -203,6 +222,58 @@ extern struct mlog_bits mlog_and_bits, mlog_not_bits; mlog(ML_ERROR, "status = %lld\n", (long long)_st); \ } while (0) +#if defined(CONFIG_OCFS2_DEBUG_MASKLOG) +#define mlog_entry(fmt, args...) do { \ + mlog(ML_ENTRY, "ENTRY:" fmt , ##args); \ +} while (0) + +#define mlog_entry_void() do { \ + mlog(ML_ENTRY, "ENTRY:\n"); \ +} while (0) + +/* + * We disable this for sparse. + */ +#if !defined(__CHECKER__) +#define mlog_exit(st) do { \ + if (__builtin_types_compatible_p(typeof(st), unsigned long)) \ + mlog(ML_EXIT, "EXIT: %lu\n", (unsigned long) (st)); \ + else if (__builtin_types_compatible_p(typeof(st), signed long)) \ + mlog(ML_EXIT, "EXIT: %ld\n", (signed long) (st)); \ + else if (__builtin_types_compatible_p(typeof(st), unsigned int) \ + || __builtin_types_compatible_p(typeof(st), unsigned short) \ + || __builtin_types_compatible_p(typeof(st), unsigned char)) \ + mlog(ML_EXIT, "EXIT: %u\n", (unsigned int) (st)); \ + else if (__builtin_types_compatible_p(typeof(st), signed int) \ + || __builtin_types_compatible_p(typeof(st), signed short) \ + || __builtin_types_compatible_p(typeof(st), signed char)) \ + mlog(ML_EXIT, "EXIT: %d\n", (signed int) (st)); \ + else if (__builtin_types_compatible_p(typeof(st), long long)) \ + mlog(ML_EXIT, "EXIT: %lld\n", (long long) (st)); \ + else \ + mlog(ML_EXIT, "EXIT: %llu\n", (unsigned long long) (st)); \ +} while (0) +#else +#define mlog_exit(st) do { \ + mlog(ML_EXIT, "EXIT: %lld\n", (long long) (st)); \ +} while (0) +#endif + +#define mlog_exit_ptr(ptr) do { \ + mlog(ML_EXIT, "EXIT: %p\n", ptr); \ +} while (0) + +#define mlog_exit_void() do { \ + mlog(ML_EXIT, "EXIT\n"); \ +} while (0) +#else +#define mlog_entry(...) do { } while (0) +#define mlog_entry_void(...) do { } while (0) +#define mlog_exit(...) do { } while (0) +#define mlog_exit_ptr(...) do { } while (0) +#define mlog_exit_void(...) do { } while (0) +#endif /* defined(CONFIG_OCFS2_DEBUG_MASKLOG) */ + #define mlog_bug_on_msg(cond, fmt, args...) do { \ if (cond) { \ mlog(ML_ERROR, "bug expression: " #cond "\n"); \ diff --git a/trunk/fs/ocfs2/cluster/tcp.c b/trunk/fs/ocfs2/cluster/tcp.c index ee04ff5ee603..3b11cb1e38fc 100644 --- a/trunk/fs/ocfs2/cluster/tcp.c +++ b/trunk/fs/ocfs2/cluster/tcp.c @@ -210,6 +210,10 @@ static inline void o2net_set_func_stop_time(struct o2net_sock_container *sc) sc->sc_tv_func_stop = ktime_get(); } +static ktime_t o2net_get_func_run_time(struct o2net_sock_container *sc) +{ + return ktime_sub(sc->sc_tv_func_stop, sc->sc_tv_func_start); +} #else /* CONFIG_DEBUG_FS */ # define o2net_init_nst(a, b, c, d, e) # define o2net_set_nst_sock_time(a) @@ -223,14 +227,10 @@ static inline void o2net_set_func_stop_time(struct o2net_sock_container *sc) # define o2net_set_advance_stop_time(a) # define o2net_set_func_start_time(a) # define o2net_set_func_stop_time(a) +# define o2net_get_func_run_time(a) (ktime_t)0 #endif /* CONFIG_DEBUG_FS */ #ifdef CONFIG_OCFS2_FS_STATS -static ktime_t o2net_get_func_run_time(struct o2net_sock_container *sc) -{ - return ktime_sub(sc->sc_tv_func_stop, sc->sc_tv_func_start); -} - static void o2net_update_send_stats(struct o2net_send_tracking *nst, struct o2net_sock_container *sc) { diff --git a/trunk/fs/ocfs2/dcache.c b/trunk/fs/ocfs2/dcache.c index e5ba34818332..7eb90403fc8a 100644 --- a/trunk/fs/ocfs2/dcache.c +++ b/trunk/fs/ocfs2/dcache.c @@ -28,6 +28,7 @@ #include #include +#define MLOG_MASK_PREFIX ML_DCACHE #include #include "ocfs2.h" @@ -38,7 +39,6 @@ #include "file.h" #include "inode.h" #include "super.h" -#include "ocfs2_trace.h" void ocfs2_dentry_attach_gen(struct dentry *dentry) { @@ -62,8 +62,8 @@ static int ocfs2_dentry_revalidate(struct dentry *dentry, inode = dentry->d_inode; osb = OCFS2_SB(dentry->d_sb); - trace_ocfs2_dentry_revalidate(dentry, dentry->d_name.len, - dentry->d_name.name); + mlog_entry("(0x%p, '%.*s')\n", dentry, + dentry->d_name.len, dentry->d_name.name); /* For a negative dentry - * check the generation number of the parent and compare with the @@ -73,10 +73,9 @@ static int ocfs2_dentry_revalidate(struct dentry *dentry, unsigned long gen = (unsigned long) dentry->d_fsdata; unsigned long pgen = OCFS2_I(dentry->d_parent->d_inode)->ip_dir_lock_gen; - - trace_ocfs2_dentry_revalidate_negative(dentry->d_name.len, - dentry->d_name.name, - pgen, gen); + mlog(0, "negative dentry: %.*s parent gen: %lu " + "dentry gen: %lu\n", + dentry->d_name.len, dentry->d_name.name, pgen, gen); if (gen != pgen) goto bail; goto valid; @@ -91,8 +90,8 @@ static int ocfs2_dentry_revalidate(struct dentry *dentry, /* did we or someone else delete this inode? */ if (OCFS2_I(inode)->ip_flags & OCFS2_INODE_DELETED) { spin_unlock(&OCFS2_I(inode)->ip_lock); - trace_ocfs2_dentry_revalidate_delete( - (unsigned long long)OCFS2_I(inode)->ip_blkno); + mlog(0, "inode (%llu) deleted, returning false\n", + (unsigned long long)OCFS2_I(inode)->ip_blkno); goto bail; } spin_unlock(&OCFS2_I(inode)->ip_lock); @@ -102,9 +101,10 @@ static int ocfs2_dentry_revalidate(struct dentry *dentry, * inode nlink hits zero, it never goes back. */ if (inode->i_nlink == 0) { - trace_ocfs2_dentry_revalidate_orphaned( - (unsigned long long)OCFS2_I(inode)->ip_blkno, - S_ISDIR(inode->i_mode)); + mlog(0, "Inode %llu orphaned, returning false " + "dir = %d\n", + (unsigned long long)OCFS2_I(inode)->ip_blkno, + S_ISDIR(inode->i_mode)); goto bail; } @@ -113,8 +113,9 @@ static int ocfs2_dentry_revalidate(struct dentry *dentry, * redo it. */ if (!dentry->d_fsdata) { - trace_ocfs2_dentry_revalidate_nofsdata( - (unsigned long long)OCFS2_I(inode)->ip_blkno); + mlog(0, "Inode %llu doesn't have dentry lock, " + "returning false\n", + (unsigned long long)OCFS2_I(inode)->ip_blkno); goto bail; } @@ -122,7 +123,8 @@ static int ocfs2_dentry_revalidate(struct dentry *dentry, ret = 1; bail: - trace_ocfs2_dentry_revalidate_ret(ret); + mlog_exit(ret); + return ret; } @@ -179,8 +181,8 @@ struct dentry *ocfs2_find_local_alias(struct inode *inode, spin_lock(&dentry->d_lock); if (ocfs2_match_dentry(dentry, parent_blkno, skip_unhashed)) { - trace_ocfs2_find_local_alias(dentry->d_name.len, - dentry->d_name.name); + mlog(0, "dentry found: %.*s\n", + dentry->d_name.len, dentry->d_name.name); dget_dlock(dentry); spin_unlock(&dentry->d_lock); @@ -238,8 +240,9 @@ int ocfs2_dentry_attach_lock(struct dentry *dentry, struct dentry *alias; struct ocfs2_dentry_lock *dl = dentry->d_fsdata; - trace_ocfs2_dentry_attach_lock(dentry->d_name.len, dentry->d_name.name, - (unsigned long long)parent_blkno, dl); + mlog(0, "Attach \"%.*s\", parent %llu, fsdata: %p\n", + dentry->d_name.len, dentry->d_name.name, + (unsigned long long)parent_blkno, dl); /* * Negative dentry. We ignore these for now. @@ -289,9 +292,7 @@ int ocfs2_dentry_attach_lock(struct dentry *dentry, (unsigned long long)parent_blkno, (unsigned long long)dl->dl_parent_blkno); - trace_ocfs2_dentry_attach_lock_found(dl->dl_lockres.l_name, - (unsigned long long)parent_blkno, - (unsigned long long)OCFS2_I(inode)->ip_blkno); + mlog(0, "Found: %s\n", dl->dl_lockres.l_name); goto out_attach; } diff --git a/trunk/fs/ocfs2/dir.c b/trunk/fs/ocfs2/dir.c index 9fe5b8fd658f..f97b6f1c61dd 100644 --- a/trunk/fs/ocfs2/dir.c +++ b/trunk/fs/ocfs2/dir.c @@ -43,6 +43,7 @@ #include #include +#define MLOG_MASK_PREFIX ML_NAMEI #include #include "ocfs2.h" @@ -60,7 +61,6 @@ #include "super.h" #include "sysfile.h" #include "uptodate.h" -#include "ocfs2_trace.h" #include "buffer_head_io.h" @@ -322,23 +322,21 @@ static int ocfs2_check_dir_entry(struct inode * dir, const char *error_msg = NULL; const int rlen = le16_to_cpu(de->rec_len); - if (unlikely(rlen < OCFS2_DIR_REC_LEN(1))) + if (rlen < OCFS2_DIR_REC_LEN(1)) error_msg = "rec_len is smaller than minimal"; - else if (unlikely(rlen % 4 != 0)) + else if (rlen % 4 != 0) error_msg = "rec_len % 4 != 0"; - else if (unlikely(rlen < OCFS2_DIR_REC_LEN(de->name_len))) + else if (rlen < OCFS2_DIR_REC_LEN(de->name_len)) error_msg = "rec_len is too small for name_len"; - else if (unlikely( - ((char *) de - bh->b_data) + rlen > dir->i_sb->s_blocksize)) + else if (((char *) de - bh->b_data) + rlen > dir->i_sb->s_blocksize) error_msg = "directory entry across blocks"; - if (unlikely(error_msg != NULL)) + if (error_msg != NULL) mlog(ML_ERROR, "bad entry in directory #%llu: %s - " "offset=%lu, inode=%llu, rec_len=%d, name_len=%d\n", (unsigned long long)OCFS2_I(dir)->ip_blkno, error_msg, offset, (unsigned long long)le64_to_cpu(de->inode), rlen, de->name_len); - return error_msg == NULL ? 1 : 0; } @@ -369,6 +367,8 @@ static inline int ocfs2_search_dirblock(struct buffer_head *bh, int de_len; int ret = 0; + mlog_entry_void(); + de_buf = first_de; dlimit = de_buf + bytes; @@ -402,7 +402,7 @@ static inline int ocfs2_search_dirblock(struct buffer_head *bh, } bail: - trace_ocfs2_search_dirblock(ret); + mlog_exit(ret); return ret; } @@ -447,7 +447,8 @@ static int ocfs2_validate_dir_block(struct super_block *sb, * We don't validate dirents here, that's handled * in-place when the code walks them. */ - trace_ocfs2_validate_dir_block((unsigned long long)bh->b_blocknr); + mlog(0, "Validating dirblock %llu\n", + (unsigned long long)bh->b_blocknr); BUG_ON(!buffer_uptodate(bh)); @@ -705,6 +706,8 @@ static struct buffer_head *ocfs2_find_entry_el(const char *name, int namelen, int num = 0; int nblocks, i, err; + mlog_entry_void(); + sb = dir->i_sb; nblocks = i_size_read(dir) >> sb->s_blocksize_bits; @@ -785,7 +788,7 @@ static struct buffer_head *ocfs2_find_entry_el(const char *name, int namelen, for (; ra_ptr < ra_max; ra_ptr++) brelse(bh_use[ra_ptr]); - trace_ocfs2_find_entry_el(ret); + mlog_exit_ptr(ret); return ret; } @@ -947,9 +950,11 @@ static int ocfs2_dx_dir_search(const char *name, int namelen, goto out; } - trace_ocfs2_dx_dir_search((unsigned long long)OCFS2_I(dir)->ip_blkno, - namelen, name, hinfo->major_hash, - hinfo->minor_hash, (unsigned long long)phys); + mlog(0, "Dir %llu: name: \"%.*s\", lookup of hash: %u.0x%x " + "returns: %llu\n", + (unsigned long long)OCFS2_I(dir)->ip_blkno, + namelen, name, hinfo->major_hash, hinfo->minor_hash, + (unsigned long long)phys); ret = ocfs2_read_dx_leaf(dir, phys, &dx_leaf_bh); if (ret) { @@ -959,9 +964,9 @@ static int ocfs2_dx_dir_search(const char *name, int namelen, dx_leaf = (struct ocfs2_dx_leaf *) dx_leaf_bh->b_data; - trace_ocfs2_dx_dir_search_leaf_info( - le16_to_cpu(dx_leaf->dl_list.de_num_used), - le16_to_cpu(dx_leaf->dl_list.de_count)); + mlog(0, "leaf info: num_used: %d, count: %d\n", + le16_to_cpu(dx_leaf->dl_list.de_num_used), + le16_to_cpu(dx_leaf->dl_list.de_count)); entry_list = &dx_leaf->dl_list; @@ -1161,6 +1166,8 @@ static int __ocfs2_delete_entry(handle_t *handle, struct inode *dir, int i, status = -ENOENT; ocfs2_journal_access_func access = ocfs2_journal_access_db; + mlog_entry("(0x%p, 0x%p, 0x%p, 0x%p)\n", handle, dir, de_del, bh); + if (OCFS2_I(dir)->ip_dyn_features & OCFS2_INLINE_DATA_FL) access = ocfs2_journal_access_di; @@ -1195,6 +1202,7 @@ static int __ocfs2_delete_entry(handle_t *handle, struct inode *dir, de = (struct ocfs2_dir_entry *)((char *)de + le16_to_cpu(de->rec_len)); } bail: + mlog_exit(status); return status; } @@ -1340,8 +1348,8 @@ static int ocfs2_delete_entry_dx(handle_t *handle, struct inode *dir, } } - trace_ocfs2_delete_entry_dx((unsigned long long)OCFS2_I(dir)->ip_blkno, - index); + mlog(0, "Dir %llu: delete entry at index: %d\n", + (unsigned long long)OCFS2_I(dir)->ip_blkno, index); ret = __ocfs2_delete_entry(handle, dir, lookup->dl_entry, leaf_bh, leaf_bh->b_data, leaf_bh->b_size); @@ -1624,6 +1632,8 @@ int __ocfs2_add_entry(handle_t *handle, struct buffer_head *insert_bh = lookup->dl_leaf_bh; char *data_start = insert_bh->b_data; + mlog_entry_void(); + if (!namelen) return -EINVAL; @@ -1755,9 +1765,8 @@ int __ocfs2_add_entry(handle_t *handle, * from ever getting here. */ retval = -ENOSPC; bail: - if (retval) - mlog_errno(retval); + mlog_exit(retval); return retval; } @@ -2019,7 +2028,8 @@ int ocfs2_readdir(struct file * filp, void * dirent, filldir_t filldir) struct inode *inode = filp->f_path.dentry->d_inode; int lock_level = 0; - trace_ocfs2_readdir((unsigned long long)OCFS2_I(inode)->ip_blkno); + mlog_entry("dirino=%llu\n", + (unsigned long long)OCFS2_I(inode)->ip_blkno); error = ocfs2_inode_lock_atime(inode, filp->f_vfsmnt, &lock_level); if (lock_level && error >= 0) { @@ -2041,10 +2051,9 @@ int ocfs2_readdir(struct file * filp, void * dirent, filldir_t filldir) dirent, filldir, NULL); ocfs2_inode_unlock(inode, lock_level); - if (error) - mlog_errno(error); bail_nolock: + mlog_exit(error); return error; } @@ -2060,8 +2069,8 @@ int ocfs2_find_files_on_disk(const char *name, { int status = -ENOENT; - trace_ocfs2_find_files_on_disk(namelen, name, blkno, - (unsigned long long)OCFS2_I(inode)->ip_blkno); + mlog(0, "name=%.*s, blkno=%p, inode=%llu\n", namelen, name, blkno, + (unsigned long long)OCFS2_I(inode)->ip_blkno); status = ocfs2_find_entry(name, namelen, inode, lookup); if (status) @@ -2105,8 +2114,8 @@ int ocfs2_check_dir_for_entry(struct inode *dir, int ret; struct ocfs2_dir_lookup_result lookup = { NULL, }; - trace_ocfs2_check_dir_for_entry( - (unsigned long long)OCFS2_I(dir)->ip_blkno, namelen, name); + mlog_entry("dir %llu, name '%.*s'\n", + (unsigned long long)OCFS2_I(dir)->ip_blkno, namelen, name); ret = -EEXIST; if (ocfs2_find_entry(name, namelen, dir, &lookup) == 0) @@ -2116,8 +2125,7 @@ int ocfs2_check_dir_for_entry(struct inode *dir, bail: ocfs2_free_dir_lookup_result(&lookup); - if (ret) - mlog_errno(ret); + mlog_exit(ret); return ret; } @@ -2316,6 +2324,8 @@ static int ocfs2_fill_new_dir_el(struct ocfs2_super *osb, struct buffer_head *new_bh = NULL; struct ocfs2_dir_entry *de; + mlog_entry_void(); + if (ocfs2_new_dir_wants_trailer(inode)) size = ocfs2_dir_trailer_blk_off(parent->i_sb); @@ -2370,6 +2380,7 @@ static int ocfs2_fill_new_dir_el(struct ocfs2_super *osb, bail: brelse(new_bh); + mlog_exit(status); return status; } @@ -2398,9 +2409,9 @@ static int ocfs2_dx_dir_attach_index(struct ocfs2_super *osb, goto out; } - trace_ocfs2_dx_dir_attach_index( - (unsigned long long)OCFS2_I(dir)->ip_blkno, - (unsigned long long)dr_blkno); + mlog(0, "Dir %llu, attach new index block: %llu\n", + (unsigned long long)OCFS2_I(dir)->ip_blkno, + (unsigned long long)dr_blkno); dx_root_bh = sb_getblk(osb->sb, dr_blkno); if (dx_root_bh == NULL) { @@ -2500,10 +2511,11 @@ static int ocfs2_dx_dir_format_cluster(struct ocfs2_super *osb, dx_leaf->dl_list.de_count = cpu_to_le16(ocfs2_dx_entries_per_leaf(osb->sb)); - trace_ocfs2_dx_dir_format_cluster( - (unsigned long long)OCFS2_I(dir)->ip_blkno, - (unsigned long long)bh->b_blocknr, - le16_to_cpu(dx_leaf->dl_list.de_count)); + mlog(0, + "Dir %llu, format dx_leaf: %llu, entry count: %u\n", + (unsigned long long)OCFS2_I(dir)->ip_blkno, + (unsigned long long)bh->b_blocknr, + le16_to_cpu(dx_leaf->dl_list.de_count)); ocfs2_journal_dirty(handle, bh); } @@ -2747,11 +2759,12 @@ static void ocfs2_dx_dir_index_root_block(struct inode *dir, ocfs2_dx_dir_name_hash(dir, de->name, de->name_len, &hinfo); - trace_ocfs2_dx_dir_index_root_block( - (unsigned long long)dir->i_ino, - hinfo.major_hash, hinfo.minor_hash, - de->name_len, de->name, - le16_to_cpu(dx_root->dr_entries.de_num_used)); + mlog(0, + "dir: %llu, major: 0x%x minor: 0x%x, index: %u, name: %.*s\n", + (unsigned long long)dir->i_ino, hinfo.major_hash, + hinfo.minor_hash, + le16_to_cpu(dx_root->dr_entries.de_num_used), + de->name_len, de->name); ocfs2_dx_entry_list_insert(&dx_root->dr_entries, &hinfo, dirent_blk); @@ -3222,6 +3235,7 @@ static int ocfs2_do_extend_dir(struct super_block *sb, bail: if (did_quota && status < 0) dquot_free_space_nodirty(dir, ocfs2_clusters_to_bytes(sb, 1)); + mlog_exit(status); return status; } @@ -3256,6 +3270,8 @@ static int ocfs2_extend_dir(struct ocfs2_super *osb, struct ocfs2_extent_tree et; struct buffer_head *dx_root_bh = lookup->dl_dx_root_bh; + mlog_entry_void(); + if (OCFS2_I(dir)->ip_dyn_features & OCFS2_INLINE_DATA_FL) { /* * This would be a code error as an inline directory should @@ -3304,8 +3320,8 @@ static int ocfs2_extend_dir(struct ocfs2_super *osb, down_write(&OCFS2_I(dir)->ip_alloc_sem); drop_alloc_sem = 1; dir_i_size = i_size_read(dir); - trace_ocfs2_extend_dir((unsigned long long)OCFS2_I(dir)->ip_blkno, - dir_i_size); + mlog(0, "extending dir %llu (i_size = %lld)\n", + (unsigned long long)OCFS2_I(dir)->ip_blkno, dir_i_size); /* dir->i_size is always block aligned. */ spin_lock(&OCFS2_I(dir)->ip_lock); @@ -3420,6 +3436,7 @@ static int ocfs2_extend_dir(struct ocfs2_super *osb, brelse(new_bh); + mlog_exit(status); return status; } @@ -3566,9 +3583,8 @@ static int ocfs2_find_dir_space_el(struct inode *dir, const char *name, status = 0; bail: brelse(bh); - if (status) - mlog_errno(status); + mlog_exit(status); return status; } @@ -3799,9 +3815,9 @@ static int ocfs2_dx_dir_rebalance(struct ocfs2_super *osb, struct inode *dir, struct ocfs2_dx_root_block *dx_root; struct ocfs2_dx_leaf *tmp_dx_leaf = NULL; - trace_ocfs2_dx_dir_rebalance((unsigned long long)OCFS2_I(dir)->ip_blkno, - (unsigned long long)leaf_blkno, - insert_hash); + mlog(0, "DX Dir: %llu, rebalance leaf leaf_blkno: %llu insert: %u\n", + (unsigned long long)OCFS2_I(dir)->ip_blkno, + (unsigned long long)leaf_blkno, insert_hash); ocfs2_init_dx_root_extent_tree(&et, INODE_CACHE(dir), dx_root_bh); @@ -3881,7 +3897,8 @@ static int ocfs2_dx_dir_rebalance(struct ocfs2_super *osb, struct inode *dir, goto out_commit; } - trace_ocfs2_dx_dir_rebalance_split(leaf_cpos, split_hash, insert_hash); + mlog(0, "Split leaf (%u) at %u, insert major hash is %u\n", + leaf_cpos, split_hash, insert_hash); /* * We have to carefully order operations here. There are items @@ -4338,8 +4355,8 @@ int ocfs2_prepare_dir_for_insert(struct ocfs2_super *osb, unsigned int blocks_wanted = 1; struct buffer_head *bh = NULL; - trace_ocfs2_prepare_dir_for_insert( - (unsigned long long)OCFS2_I(dir)->ip_blkno, namelen); + mlog(0, "getting ready to insert namelen %d into dir %llu\n", + namelen, (unsigned long long)OCFS2_I(dir)->ip_blkno); if (!namelen) { ret = -EINVAL; diff --git a/trunk/fs/ocfs2/dlm/dlmconvert.c b/trunk/fs/ocfs2/dlm/dlmconvert.c index 29a886d1e82c..9f30491e5e88 100644 --- a/trunk/fs/ocfs2/dlm/dlmconvert.c +++ b/trunk/fs/ocfs2/dlm/dlmconvert.c @@ -128,8 +128,8 @@ static enum dlm_status __dlmconvert_master(struct dlm_ctxt *dlm, assert_spin_locked(&res->spinlock); - mlog(0, "type=%d, convert_type=%d, new convert_type=%d\n", - lock->ml.type, lock->ml.convert_type, type); + mlog_entry("type=%d, convert_type=%d, new convert_type=%d\n", + lock->ml.type, lock->ml.convert_type, type); spin_lock(&lock->spinlock); @@ -353,7 +353,7 @@ static enum dlm_status dlm_send_remote_convert_request(struct dlm_ctxt *dlm, struct kvec vec[2]; size_t veclen = 1; - mlog(0, "%.*s\n", res->lockname.len, res->lockname.name); + mlog_entry("%.*s\n", res->lockname.len, res->lockname.name); memset(&convert, 0, sizeof(struct dlm_convert_lock)); convert.node_idx = dlm->node_num; diff --git a/trunk/fs/ocfs2/dlm/dlmdomain.c b/trunk/fs/ocfs2/dlm/dlmdomain.c index 7540a492eaba..7e38a072d720 100644 --- a/trunk/fs/ocfs2/dlm/dlmdomain.c +++ b/trunk/fs/ocfs2/dlm/dlmdomain.c @@ -188,7 +188,7 @@ struct dlm_lock_resource * __dlm_lookup_lockres_full(struct dlm_ctxt *dlm, struct hlist_head *bucket; struct hlist_node *list; - mlog(0, "%.*s\n", len, name); + mlog_entry("%.*s\n", len, name); assert_spin_locked(&dlm->spinlock); @@ -222,7 +222,7 @@ struct dlm_lock_resource * __dlm_lookup_lockres(struct dlm_ctxt *dlm, { struct dlm_lock_resource *res = NULL; - mlog(0, "%.*s\n", len, name); + mlog_entry("%.*s\n", len, name); assert_spin_locked(&dlm->spinlock); @@ -531,7 +531,7 @@ static int dlm_exit_domain_handler(struct o2net_msg *msg, u32 len, void *data, unsigned int node; struct dlm_exit_domain *exit_msg = (struct dlm_exit_domain *) msg->buf; - mlog(0, "%p %u %p", msg, len, data); + mlog_entry("%p %u %p", msg, len, data); if (!dlm_grab(dlm)) return 0; @@ -926,10 +926,9 @@ static int dlm_assert_joined_handler(struct o2net_msg *msg, u32 len, void *data, } static int dlm_match_regions(struct dlm_ctxt *dlm, - struct dlm_query_region *qr, - char *local, int locallen) + struct dlm_query_region *qr) { - char *remote = qr->qr_regions; + char *local = NULL, *remote = qr->qr_regions; char *l, *r; int localnr, i, j, foundit; int status = 0; @@ -958,8 +957,13 @@ static int dlm_match_regions(struct dlm_ctxt *dlm, r += O2HB_MAX_REGION_NAME_LEN; } - localnr = min(O2NM_MAX_REGIONS, locallen/O2HB_MAX_REGION_NAME_LEN); - localnr = o2hb_get_all_regions(local, (u8)localnr); + local = kmalloc(sizeof(qr->qr_regions), GFP_ATOMIC); + if (!local) { + status = -ENOMEM; + goto bail; + } + + localnr = o2hb_get_all_regions(local, O2NM_MAX_REGIONS); /* compare local regions with remote */ l = local; @@ -1008,6 +1012,8 @@ static int dlm_match_regions(struct dlm_ctxt *dlm, } bail: + kfree(local); + return status; } @@ -1069,7 +1075,6 @@ static int dlm_query_region_handler(struct o2net_msg *msg, u32 len, { struct dlm_query_region *qr; struct dlm_ctxt *dlm = NULL; - char *local = NULL; int status = 0; int locked = 0; @@ -1078,13 +1083,6 @@ static int dlm_query_region_handler(struct o2net_msg *msg, u32 len, mlog(0, "Node %u queries hb regions on domain %s\n", qr->qr_node, qr->qr_domain); - /* buffer used in dlm_mast_regions() */ - local = kmalloc(sizeof(qr->qr_regions), GFP_KERNEL); - if (!local) { - status = -ENOMEM; - goto bail; - } - status = -EINVAL; spin_lock(&dlm_domain_lock); @@ -1114,15 +1112,13 @@ static int dlm_query_region_handler(struct o2net_msg *msg, u32 len, goto bail; } - status = dlm_match_regions(dlm, qr, local, sizeof(qr->qr_regions)); + status = dlm_match_regions(dlm, qr); bail: if (locked) spin_unlock(&dlm->spinlock); spin_unlock(&dlm_domain_lock); - kfree(local); - return status; } @@ -1557,7 +1553,7 @@ static int dlm_try_to_join_domain(struct dlm_ctxt *dlm) struct domain_join_ctxt *ctxt; enum dlm_query_join_response_code response = JOIN_DISALLOW; - mlog(0, "%p", dlm); + mlog_entry("%p", dlm); ctxt = kzalloc(sizeof(*ctxt), GFP_KERNEL); if (!ctxt) { diff --git a/trunk/fs/ocfs2/dlm/dlmlock.c b/trunk/fs/ocfs2/dlm/dlmlock.c index 8d39e0fd66f7..7009292aac5a 100644 --- a/trunk/fs/ocfs2/dlm/dlmlock.c +++ b/trunk/fs/ocfs2/dlm/dlmlock.c @@ -128,7 +128,7 @@ static enum dlm_status dlmlock_master(struct dlm_ctxt *dlm, int call_ast = 0, kick_thread = 0; enum dlm_status status = DLM_NORMAL; - mlog(0, "type=%d\n", lock->ml.type); + mlog_entry("type=%d\n", lock->ml.type); spin_lock(&res->spinlock); /* if called from dlm_create_lock_handler, need to @@ -227,8 +227,8 @@ static enum dlm_status dlmlock_remote(struct dlm_ctxt *dlm, enum dlm_status status = DLM_DENIED; int lockres_changed = 1; - mlog(0, "type=%d, lockres %.*s, flags = 0x%x\n", - lock->ml.type, res->lockname.len, + mlog_entry("type=%d\n", lock->ml.type); + mlog(0, "lockres %.*s, flags = 0x%x\n", res->lockname.len, res->lockname.name, flags); spin_lock(&res->spinlock); @@ -308,6 +308,8 @@ static enum dlm_status dlm_send_remote_lock_request(struct dlm_ctxt *dlm, int tmpret, status = 0; enum dlm_status ret; + mlog_entry_void(); + memset(&create, 0, sizeof(create)); create.node_idx = dlm->node_num; create.requested_type = lock->ml.type; @@ -475,6 +477,8 @@ int dlm_create_lock_handler(struct o2net_msg *msg, u32 len, void *data, BUG_ON(!dlm); + mlog_entry_void(); + if (!dlm_grab(dlm)) return DLM_REJECTED; diff --git a/trunk/fs/ocfs2/dlm/dlmmaster.c b/trunk/fs/ocfs2/dlm/dlmmaster.c index 9d67610dfc74..59f0f6bdfc62 100644 --- a/trunk/fs/ocfs2/dlm/dlmmaster.c +++ b/trunk/fs/ocfs2/dlm/dlmmaster.c @@ -426,6 +426,8 @@ static void dlm_mle_release(struct kref *kref) struct dlm_master_list_entry *mle; struct dlm_ctxt *dlm; + mlog_entry_void(); + mle = container_of(kref, struct dlm_master_list_entry, mle_refs); dlm = mle->dlm; @@ -3118,6 +3120,8 @@ static int dlm_add_migration_mle(struct dlm_ctxt *dlm, *oldmle = NULL; + mlog_entry_void(); + assert_spin_locked(&dlm->spinlock); assert_spin_locked(&dlm->master_lock); @@ -3257,7 +3261,7 @@ void dlm_clean_master_list(struct dlm_ctxt *dlm, u8 dead_node) struct hlist_node *list; unsigned int i; - mlog(0, "dlm=%s, dead node=%u\n", dlm->name, dead_node); + mlog_entry("dlm=%s, dead node=%u\n", dlm->name, dead_node); top: assert_spin_locked(&dlm->spinlock); diff --git a/trunk/fs/ocfs2/dlm/dlmrecovery.c b/trunk/fs/ocfs2/dlm/dlmrecovery.c index f1beb6fc254d..aaaffbcbe916 100644 --- a/trunk/fs/ocfs2/dlm/dlmrecovery.c +++ b/trunk/fs/ocfs2/dlm/dlmrecovery.c @@ -727,6 +727,7 @@ static int dlm_remaster_locks(struct dlm_ctxt *dlm, u8 dead_node) if (destroy) dlm_destroy_recovery_area(dlm, dead_node); + mlog_exit(status); return status; } @@ -1495,9 +1496,9 @@ int dlm_mig_lockres_handler(struct o2net_msg *msg, u32 len, void *data, kfree(buf); if (item) kfree(item); - mlog_errno(ret); } + mlog_exit(ret); return ret; } @@ -1566,6 +1567,7 @@ static void dlm_mig_lockres_worker(struct dlm_work_item *item, void *data) dlm_lockres_put(res); } kfree(data); + mlog_exit(ret); } @@ -1984,6 +1986,7 @@ static int dlm_process_recovery_data(struct dlm_ctxt *dlm, dlm_lock_put(newlock); } + mlog_exit(ret); return ret; } @@ -2080,6 +2083,8 @@ static void dlm_finish_local_lockres_recovery(struct dlm_ctxt *dlm, struct hlist_head *bucket; struct dlm_lock_resource *res, *next; + mlog_entry_void(); + assert_spin_locked(&dlm->spinlock); list_for_each_entry_safe(res, next, &dlm->reco.resources, recovering) { @@ -2602,6 +2607,8 @@ static int dlm_send_begin_reco_message(struct dlm_ctxt *dlm, u8 dead_node) int nodenum; int status; + mlog_entry("%u\n", dead_node); + mlog(0, "%s: dead node is %u\n", dlm->name, dead_node); spin_lock(&dlm->spinlock); diff --git a/trunk/fs/ocfs2/dlm/dlmunlock.c b/trunk/fs/ocfs2/dlm/dlmunlock.c index 850aa7e87537..817287c6a6db 100644 --- a/trunk/fs/ocfs2/dlm/dlmunlock.c +++ b/trunk/fs/ocfs2/dlm/dlmunlock.c @@ -317,7 +317,7 @@ static enum dlm_status dlm_send_remote_unlock_request(struct dlm_ctxt *dlm, struct kvec vec[2]; size_t veclen = 1; - mlog(0, "%.*s\n", res->lockname.len, res->lockname.name); + mlog_entry("%.*s\n", res->lockname.len, res->lockname.name); if (owner == dlm->node_num) { /* ended up trying to contact ourself. this means @@ -588,6 +588,8 @@ enum dlm_status dlmunlock(struct dlm_ctxt *dlm, struct dlm_lockstatus *lksb, struct dlm_lock *lock = NULL; int call_ast, is_master; + mlog_entry_void(); + if (!lksb) { dlm_error(DLM_BADARGS); return DLM_BADARGS; diff --git a/trunk/fs/ocfs2/dlmglue.c b/trunk/fs/ocfs2/dlmglue.c index 7642d7ca73e5..e8d94d722ecb 100644 --- a/trunk/fs/ocfs2/dlmglue.c +++ b/trunk/fs/ocfs2/dlmglue.c @@ -64,7 +64,7 @@ struct ocfs2_mask_waiter { unsigned long mw_mask; unsigned long mw_goal; #ifdef CONFIG_OCFS2_FS_STATS - ktime_t mw_lock_start; + unsigned long long mw_lock_start; #endif }; @@ -397,6 +397,8 @@ static void ocfs2_build_lock_name(enum ocfs2_lock_type type, { int len; + mlog_entry_void(); + BUG_ON(type >= OCFS2_NUM_LOCK_TYPES); len = snprintf(name, OCFS2_LOCK_ID_MAX_LEN, "%c%s%016llx%08x", @@ -406,6 +408,8 @@ static void ocfs2_build_lock_name(enum ocfs2_lock_type type, BUG_ON(len != (OCFS2_LOCK_ID_MAX_LEN - 1)); mlog(0, "built lock resource with name: %s\n", name); + + mlog_exit_void(); } static DEFINE_SPINLOCK(ocfs2_dlm_tracking_lock); @@ -431,41 +435,44 @@ static void ocfs2_remove_lockres_tracking(struct ocfs2_lock_res *res) #ifdef CONFIG_OCFS2_FS_STATS static void ocfs2_init_lock_stats(struct ocfs2_lock_res *res) { + res->l_lock_num_prmode = 0; + res->l_lock_num_prmode_failed = 0; + res->l_lock_total_prmode = 0; + res->l_lock_max_prmode = 0; + res->l_lock_num_exmode = 0; + res->l_lock_num_exmode_failed = 0; + res->l_lock_total_exmode = 0; + res->l_lock_max_exmode = 0; res->l_lock_refresh = 0; - memset(&res->l_lock_prmode, 0, sizeof(struct ocfs2_lock_stats)); - memset(&res->l_lock_exmode, 0, sizeof(struct ocfs2_lock_stats)); } static void ocfs2_update_lock_stats(struct ocfs2_lock_res *res, int level, struct ocfs2_mask_waiter *mw, int ret) { - u32 usec; - ktime_t kt; - struct ocfs2_lock_stats *stats; - - if (level == LKM_PRMODE) - stats = &res->l_lock_prmode; - else if (level == LKM_EXMODE) - stats = &res->l_lock_exmode; - else + unsigned long long *num, *sum; + unsigned int *max, *failed; + struct timespec ts = current_kernel_time(); + unsigned long long time = timespec_to_ns(&ts) - mw->mw_lock_start; + + if (level == LKM_PRMODE) { + num = &res->l_lock_num_prmode; + sum = &res->l_lock_total_prmode; + max = &res->l_lock_max_prmode; + failed = &res->l_lock_num_prmode_failed; + } else if (level == LKM_EXMODE) { + num = &res->l_lock_num_exmode; + sum = &res->l_lock_total_exmode; + max = &res->l_lock_max_exmode; + failed = &res->l_lock_num_exmode_failed; + } else return; - kt = ktime_sub(ktime_get(), mw->mw_lock_start); - usec = ktime_to_us(kt); - - stats->ls_gets++; - stats->ls_total += ktime_to_ns(kt); - /* overflow */ - if (unlikely(stats->ls_gets) == 0) { - stats->ls_gets++; - stats->ls_total = ktime_to_ns(kt); - } - - if (stats->ls_max < usec) - stats->ls_max = usec; - + (*num)++; + (*sum) += time; + if (time > *max) + *max = time; if (ret) - stats->ls_fail++; + (*failed)++; } static inline void ocfs2_track_lock_refresh(struct ocfs2_lock_res *lockres) @@ -475,7 +482,8 @@ static inline void ocfs2_track_lock_refresh(struct ocfs2_lock_res *lockres) static inline void ocfs2_init_start_time(struct ocfs2_mask_waiter *mw) { - mw->mw_lock_start = ktime_get(); + struct timespec ts = current_kernel_time(); + mw->mw_lock_start = timespec_to_ns(&ts); } #else static inline void ocfs2_init_lock_stats(struct ocfs2_lock_res *res) @@ -721,6 +729,8 @@ void ocfs2_refcount_lock_res_init(struct ocfs2_lock_res *lockres, void ocfs2_lock_res_free(struct ocfs2_lock_res *res) { + mlog_entry_void(); + if (!(res->l_flags & OCFS2_LOCK_INITIALIZED)) return; @@ -746,11 +756,14 @@ void ocfs2_lock_res_free(struct ocfs2_lock_res *res) memset(&res->l_lksb, 0, sizeof(res->l_lksb)); res->l_flags = 0UL; + mlog_exit_void(); } static inline void ocfs2_inc_holders(struct ocfs2_lock_res *lockres, int level) { + mlog_entry_void(); + BUG_ON(!lockres); switch(level) { @@ -763,11 +776,15 @@ static inline void ocfs2_inc_holders(struct ocfs2_lock_res *lockres, default: BUG(); } + + mlog_exit_void(); } static inline void ocfs2_dec_holders(struct ocfs2_lock_res *lockres, int level) { + mlog_entry_void(); + BUG_ON(!lockres); switch(level) { @@ -782,6 +799,7 @@ static inline void ocfs2_dec_holders(struct ocfs2_lock_res *lockres, default: BUG(); } + mlog_exit_void(); } /* WARNING: This function lives in a world where the only three lock @@ -828,6 +846,8 @@ static void lockres_clear_flags(struct ocfs2_lock_res *lockres, static inline void ocfs2_generic_handle_downconvert_action(struct ocfs2_lock_res *lockres) { + mlog_entry_void(); + BUG_ON(!(lockres->l_flags & OCFS2_LOCK_BUSY)); BUG_ON(!(lockres->l_flags & OCFS2_LOCK_ATTACHED)); BUG_ON(!(lockres->l_flags & OCFS2_LOCK_BLOCKED)); @@ -840,10 +860,14 @@ static inline void ocfs2_generic_handle_downconvert_action(struct ocfs2_lock_res lockres_clear_flags(lockres, OCFS2_LOCK_BLOCKED); } lockres_clear_flags(lockres, OCFS2_LOCK_BUSY); + + mlog_exit_void(); } static inline void ocfs2_generic_handle_convert_action(struct ocfs2_lock_res *lockres) { + mlog_entry_void(); + BUG_ON(!(lockres->l_flags & OCFS2_LOCK_BUSY)); BUG_ON(!(lockres->l_flags & OCFS2_LOCK_ATTACHED)); @@ -865,10 +889,14 @@ static inline void ocfs2_generic_handle_convert_action(struct ocfs2_lock_res *lo lockres_or_flags(lockres, OCFS2_LOCK_UPCONVERT_FINISHING); lockres_clear_flags(lockres, OCFS2_LOCK_BUSY); + + mlog_exit_void(); } static inline void ocfs2_generic_handle_attach_action(struct ocfs2_lock_res *lockres) { + mlog_entry_void(); + BUG_ON((!(lockres->l_flags & OCFS2_LOCK_BUSY))); BUG_ON(lockres->l_flags & OCFS2_LOCK_ATTACHED); @@ -880,12 +908,15 @@ static inline void ocfs2_generic_handle_attach_action(struct ocfs2_lock_res *loc lockres->l_level = lockres->l_requested; lockres_or_flags(lockres, OCFS2_LOCK_ATTACHED); lockres_clear_flags(lockres, OCFS2_LOCK_BUSY); + + mlog_exit_void(); } static int ocfs2_generic_handle_bast(struct ocfs2_lock_res *lockres, int level) { int needs_downconvert = 0; + mlog_entry_void(); assert_spin_locked(&lockres->l_lock); @@ -907,7 +938,8 @@ static int ocfs2_generic_handle_bast(struct ocfs2_lock_res *lockres, if (needs_downconvert) lockres_or_flags(lockres, OCFS2_LOCK_BLOCKED); - mlog(0, "needs_downconvert = %d\n", needs_downconvert); + + mlog_exit(needs_downconvert); return needs_downconvert; } @@ -1119,6 +1151,8 @@ static void ocfs2_unlock_ast(struct ocfs2_dlm_lksb *lksb, int error) struct ocfs2_lock_res *lockres = ocfs2_lksb_to_lock_res(lksb); unsigned long flags; + mlog_entry_void(); + mlog(ML_BASTS, "UNLOCK AST fired for lockres %s, action = %d\n", lockres->l_name, lockres->l_unlock_action); @@ -1128,6 +1162,7 @@ static void ocfs2_unlock_ast(struct ocfs2_dlm_lksb *lksb, int error) "unlock_action %d\n", error, lockres->l_name, lockres->l_unlock_action); spin_unlock_irqrestore(&lockres->l_lock, flags); + mlog_exit_void(); return; } @@ -1151,6 +1186,8 @@ static void ocfs2_unlock_ast(struct ocfs2_dlm_lksb *lksb, int error) lockres->l_unlock_action = OCFS2_UNLOCK_INVALID; wake_up(&lockres->l_event); spin_unlock_irqrestore(&lockres->l_lock, flags); + + mlog_exit_void(); } /* @@ -1196,6 +1233,7 @@ static inline void ocfs2_recover_from_dlm_error(struct ocfs2_lock_res *lockres, { unsigned long flags; + mlog_entry_void(); spin_lock_irqsave(&lockres->l_lock, flags); lockres_clear_flags(lockres, OCFS2_LOCK_BUSY); lockres_clear_flags(lockres, OCFS2_LOCK_UPCONVERT_FINISHING); @@ -1206,6 +1244,7 @@ static inline void ocfs2_recover_from_dlm_error(struct ocfs2_lock_res *lockres, spin_unlock_irqrestore(&lockres->l_lock, flags); wake_up(&lockres->l_event); + mlog_exit_void(); } /* Note: If we detect another process working on the lock (i.e., @@ -1221,6 +1260,8 @@ static int ocfs2_lock_create(struct ocfs2_super *osb, unsigned long flags; unsigned int gen; + mlog_entry_void(); + mlog(0, "lock %s, level = %d, flags = %u\n", lockres->l_name, level, dlm_flags); @@ -1252,6 +1293,7 @@ static int ocfs2_lock_create(struct ocfs2_super *osb, mlog(0, "lock %s, return from ocfs2_dlm_lock\n", lockres->l_name); bail: + mlog_exit(ret); return ret; } @@ -1374,6 +1416,8 @@ static int __ocfs2_cluster_lock(struct ocfs2_super *osb, unsigned int gen; int noqueue_attempted = 0; + mlog_entry_void(); + ocfs2_init_mask_waiter(&mw); if (lockres->l_ops->flags & LOCK_TYPE_USES_LVB) @@ -1539,6 +1583,7 @@ static int __ocfs2_cluster_lock(struct ocfs2_super *osb, caller_ip); } #endif + mlog_exit(ret); return ret; } @@ -1560,6 +1605,7 @@ static void __ocfs2_cluster_unlock(struct ocfs2_super *osb, { unsigned long flags; + mlog_entry_void(); spin_lock_irqsave(&lockres->l_lock, flags); ocfs2_dec_holders(lockres, level); ocfs2_downconvert_on_unlock(osb, lockres); @@ -1568,6 +1614,7 @@ static void __ocfs2_cluster_unlock(struct ocfs2_super *osb, if (lockres->l_lockdep_map.key != NULL) rwsem_release(&lockres->l_lockdep_map, 1, caller_ip); #endif + mlog_exit_void(); } static int ocfs2_create_new_lock(struct ocfs2_super *osb, @@ -1601,6 +1648,8 @@ int ocfs2_create_new_inode_locks(struct inode *inode) BUG_ON(!inode); BUG_ON(!ocfs2_inode_is_new(inode)); + mlog_entry_void(); + mlog(0, "Inode %llu\n", (unsigned long long)OCFS2_I(inode)->ip_blkno); /* NOTE: That we don't increment any of the holder counts, nor @@ -1634,6 +1683,7 @@ int ocfs2_create_new_inode_locks(struct inode *inode) } bail: + mlog_exit(ret); return ret; } @@ -1645,12 +1695,16 @@ int ocfs2_rw_lock(struct inode *inode, int write) BUG_ON(!inode); + mlog_entry_void(); + mlog(0, "inode %llu take %s RW lock\n", (unsigned long long)OCFS2_I(inode)->ip_blkno, write ? "EXMODE" : "PRMODE"); - if (ocfs2_mount_local(osb)) + if (ocfs2_mount_local(osb)) { + mlog_exit(0); return 0; + } lockres = &OCFS2_I(inode)->ip_rw_lockres; @@ -1661,6 +1715,7 @@ int ocfs2_rw_lock(struct inode *inode, int write) if (status < 0) mlog_errno(status); + mlog_exit(status); return status; } @@ -1670,12 +1725,16 @@ void ocfs2_rw_unlock(struct inode *inode, int write) struct ocfs2_lock_res *lockres = &OCFS2_I(inode)->ip_rw_lockres; struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); + mlog_entry_void(); + mlog(0, "inode %llu drop %s RW lock\n", (unsigned long long)OCFS2_I(inode)->ip_blkno, write ? "EXMODE" : "PRMODE"); if (!ocfs2_mount_local(osb)) ocfs2_cluster_unlock(OCFS2_SB(inode->i_sb), lockres, level); + + mlog_exit_void(); } /* @@ -1689,6 +1748,8 @@ int ocfs2_open_lock(struct inode *inode) BUG_ON(!inode); + mlog_entry_void(); + mlog(0, "inode %llu take PRMODE open lock\n", (unsigned long long)OCFS2_I(inode)->ip_blkno); @@ -1703,6 +1764,7 @@ int ocfs2_open_lock(struct inode *inode) mlog_errno(status); out: + mlog_exit(status); return status; } @@ -1714,6 +1776,8 @@ int ocfs2_try_open_lock(struct inode *inode, int write) BUG_ON(!inode); + mlog_entry_void(); + mlog(0, "inode %llu try to take %s open lock\n", (unsigned long long)OCFS2_I(inode)->ip_blkno, write ? "EXMODE" : "PRMODE"); @@ -1735,6 +1799,7 @@ int ocfs2_try_open_lock(struct inode *inode, int write) level, DLM_LKF_NOQUEUE, 0); out: + mlog_exit(status); return status; } @@ -1746,6 +1811,8 @@ void ocfs2_open_unlock(struct inode *inode) struct ocfs2_lock_res *lockres = &OCFS2_I(inode)->ip_open_lockres; struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); + mlog_entry_void(); + mlog(0, "inode %llu drop open lock\n", (unsigned long long)OCFS2_I(inode)->ip_blkno); @@ -1760,7 +1827,7 @@ void ocfs2_open_unlock(struct inode *inode) DLM_LOCK_EX); out: - return; + mlog_exit_void(); } static int ocfs2_flock_handle_signal(struct ocfs2_lock_res *lockres, @@ -1976,6 +2043,8 @@ static void ocfs2_downconvert_on_unlock(struct ocfs2_super *osb, { int kick = 0; + mlog_entry_void(); + /* If we know that another node is waiting on our lock, kick * the downconvert thread * pre-emptively when we reach a release * condition. */ @@ -1996,6 +2065,8 @@ static void ocfs2_downconvert_on_unlock(struct ocfs2_super *osb, if (kick) ocfs2_wake_downconvert_thread(osb); + + mlog_exit_void(); } #define OCFS2_SEC_BITS 34 @@ -2024,6 +2095,8 @@ static void __ocfs2_stuff_meta_lvb(struct inode *inode) struct ocfs2_lock_res *lockres = &oi->ip_inode_lockres; struct ocfs2_meta_lvb *lvb; + mlog_entry_void(); + lvb = ocfs2_dlm_lvb(&lockres->l_lksb); /* @@ -2055,6 +2128,8 @@ static void __ocfs2_stuff_meta_lvb(struct inode *inode) out: mlog_meta_lvb(0, lockres); + + mlog_exit_void(); } static void ocfs2_unpack_timespec(struct timespec *spec, @@ -2070,6 +2145,8 @@ static void ocfs2_refresh_inode_from_lvb(struct inode *inode) struct ocfs2_lock_res *lockres = &oi->ip_inode_lockres; struct ocfs2_meta_lvb *lvb; + mlog_entry_void(); + mlog_meta_lvb(0, lockres); lvb = ocfs2_dlm_lvb(&lockres->l_lksb); @@ -2100,6 +2177,8 @@ static void ocfs2_refresh_inode_from_lvb(struct inode *inode) ocfs2_unpack_timespec(&inode->i_ctime, be64_to_cpu(lvb->lvb_ictime_packed)); spin_unlock(&oi->ip_lock); + + mlog_exit_void(); } static inline int ocfs2_meta_lvb_is_trustable(struct inode *inode, @@ -2126,6 +2205,8 @@ static int ocfs2_should_refresh_lock_res(struct ocfs2_lock_res *lockres) unsigned long flags; int status = 0; + mlog_entry_void(); + refresh_check: spin_lock_irqsave(&lockres->l_lock, flags); if (!(lockres->l_flags & OCFS2_LOCK_NEEDS_REFRESH)) { @@ -2146,7 +2227,7 @@ static int ocfs2_should_refresh_lock_res(struct ocfs2_lock_res *lockres) status = 1; bail: - mlog(0, "status %d\n", status); + mlog_exit(status); return status; } @@ -2156,6 +2237,7 @@ static inline void ocfs2_complete_lock_res_refresh(struct ocfs2_lock_res *lockre int status) { unsigned long flags; + mlog_entry_void(); spin_lock_irqsave(&lockres->l_lock, flags); lockres_clear_flags(lockres, OCFS2_LOCK_REFRESHING); @@ -2164,6 +2246,8 @@ static inline void ocfs2_complete_lock_res_refresh(struct ocfs2_lock_res *lockre spin_unlock_irqrestore(&lockres->l_lock, flags); wake_up(&lockres->l_event); + + mlog_exit_void(); } /* may or may not return a bh if it went to disk. */ @@ -2176,6 +2260,8 @@ static int ocfs2_inode_lock_update(struct inode *inode, struct ocfs2_dinode *fe; struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); + mlog_entry_void(); + if (ocfs2_mount_local(osb)) goto bail; @@ -2244,6 +2330,7 @@ static int ocfs2_inode_lock_update(struct inode *inode, bail_refresh: ocfs2_complete_lock_res_refresh(lockres, status); bail: + mlog_exit(status); return status; } @@ -2287,6 +2374,8 @@ int ocfs2_inode_lock_full_nested(struct inode *inode, BUG_ON(!inode); + mlog_entry_void(); + mlog(0, "inode %llu, take %s META lock\n", (unsigned long long)OCFS2_I(inode)->ip_blkno, ex ? "EXMODE" : "PRMODE"); @@ -2378,6 +2467,7 @@ int ocfs2_inode_lock_full_nested(struct inode *inode, if (local_bh) brelse(local_bh); + mlog_exit(status); return status; } @@ -2427,6 +2517,7 @@ int ocfs2_inode_lock_atime(struct inode *inode, { int ret; + mlog_entry_void(); ret = ocfs2_inode_lock(inode, NULL, 0); if (ret < 0) { mlog_errno(ret); @@ -2454,6 +2545,7 @@ int ocfs2_inode_lock_atime(struct inode *inode, } else *level = 0; + mlog_exit(ret); return ret; } @@ -2464,6 +2556,8 @@ void ocfs2_inode_unlock(struct inode *inode, struct ocfs2_lock_res *lockres = &OCFS2_I(inode)->ip_inode_lockres; struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); + mlog_entry_void(); + mlog(0, "inode %llu drop %s META lock\n", (unsigned long long)OCFS2_I(inode)->ip_blkno, ex ? "EXMODE" : "PRMODE"); @@ -2471,6 +2565,8 @@ void ocfs2_inode_unlock(struct inode *inode, if (!ocfs2_is_hard_readonly(OCFS2_SB(inode->i_sb)) && !ocfs2_mount_local(osb)) ocfs2_cluster_unlock(OCFS2_SB(inode->i_sb), lockres, level); + + mlog_exit_void(); } int ocfs2_orphan_scan_lock(struct ocfs2_super *osb, u32 *seqno) @@ -2521,6 +2617,8 @@ int ocfs2_super_lock(struct ocfs2_super *osb, int level = ex ? DLM_LOCK_EX : DLM_LOCK_PR; struct ocfs2_lock_res *lockres = &osb->osb_super_lockres; + mlog_entry_void(); + if (ocfs2_is_hard_readonly(osb)) return -EROFS; @@ -2552,6 +2650,7 @@ int ocfs2_super_lock(struct ocfs2_super *osb, ocfs2_track_lock_refresh(lockres); } bail: + mlog_exit(status); return status; } @@ -2770,15 +2869,8 @@ static void *ocfs2_dlm_seq_next(struct seq_file *m, void *v, loff_t *pos) return iter; } -/* - * Version is used by debugfs.ocfs2 to determine the format being used - * - * New in version 2 - * - Lock stats printed - * New in version 3 - * - Max time in lock stats is in usecs (instead of nsecs) - */ -#define OCFS2_DLM_DEBUG_STR_VERSION 3 +/* So that debugfs.ocfs2 can determine which format is being used */ +#define OCFS2_DLM_DEBUG_STR_VERSION 2 static int ocfs2_dlm_seq_show(struct seq_file *m, void *v) { int i; @@ -2820,18 +2912,18 @@ static int ocfs2_dlm_seq_show(struct seq_file *m, void *v) seq_printf(m, "0x%x\t", lvb[i]); #ifdef CONFIG_OCFS2_FS_STATS -# define lock_num_prmode(_l) ((_l)->l_lock_prmode.ls_gets) -# define lock_num_exmode(_l) ((_l)->l_lock_exmode.ls_gets) -# define lock_num_prmode_failed(_l) ((_l)->l_lock_prmode.ls_fail) -# define lock_num_exmode_failed(_l) ((_l)->l_lock_exmode.ls_fail) -# define lock_total_prmode(_l) ((_l)->l_lock_prmode.ls_total) -# define lock_total_exmode(_l) ((_l)->l_lock_exmode.ls_total) -# define lock_max_prmode(_l) ((_l)->l_lock_prmode.ls_max) -# define lock_max_exmode(_l) ((_l)->l_lock_exmode.ls_max) -# define lock_refresh(_l) ((_l)->l_lock_refresh) +# define lock_num_prmode(_l) (_l)->l_lock_num_prmode +# define lock_num_exmode(_l) (_l)->l_lock_num_exmode +# define lock_num_prmode_failed(_l) (_l)->l_lock_num_prmode_failed +# define lock_num_exmode_failed(_l) (_l)->l_lock_num_exmode_failed +# define lock_total_prmode(_l) (_l)->l_lock_total_prmode +# define lock_total_exmode(_l) (_l)->l_lock_total_exmode +# define lock_max_prmode(_l) (_l)->l_lock_max_prmode +# define lock_max_exmode(_l) (_l)->l_lock_max_exmode +# define lock_refresh(_l) (_l)->l_lock_refresh #else -# define lock_num_prmode(_l) (0) -# define lock_num_exmode(_l) (0) +# define lock_num_prmode(_l) (0ULL) +# define lock_num_exmode(_l) (0ULL) # define lock_num_prmode_failed(_l) (0) # define lock_num_exmode_failed(_l) (0) # define lock_total_prmode(_l) (0ULL) @@ -2841,8 +2933,8 @@ static int ocfs2_dlm_seq_show(struct seq_file *m, void *v) # define lock_refresh(_l) (0) #endif /* The following seq_print was added in version 2 of this output */ - seq_printf(m, "%u\t" - "%u\t" + seq_printf(m, "%llu\t" + "%llu\t" "%u\t" "%u\t" "%llu\t" @@ -2962,6 +3054,8 @@ int ocfs2_dlm_init(struct ocfs2_super *osb) int status = 0; struct ocfs2_cluster_connection *conn = NULL; + mlog_entry_void(); + if (ocfs2_mount_local(osb)) { osb->node_num = 0; goto local; @@ -3018,12 +3112,15 @@ int ocfs2_dlm_init(struct ocfs2_super *osb) kthread_stop(osb->dc_task); } + mlog_exit(status); return status; } void ocfs2_dlm_shutdown(struct ocfs2_super *osb, int hangup_pending) { + mlog_entry_void(); + ocfs2_drop_osb_locks(osb); /* @@ -3046,6 +3143,8 @@ void ocfs2_dlm_shutdown(struct ocfs2_super *osb, osb->cconn = NULL; ocfs2_dlm_shutdown_debug(osb); + + mlog_exit_void(); } static int ocfs2_drop_lock(struct ocfs2_super *osb, @@ -3127,6 +3226,7 @@ static int ocfs2_drop_lock(struct ocfs2_super *osb, ocfs2_wait_on_busy_lock(lockres); out: + mlog_exit(0); return 0; } @@ -3184,6 +3284,8 @@ int ocfs2_drop_inode_locks(struct inode *inode) { int status, err; + mlog_entry_void(); + /* No need to call ocfs2_mark_lockres_freeing here - * ocfs2_clear_inode has done it for us. */ @@ -3208,6 +3310,7 @@ int ocfs2_drop_inode_locks(struct inode *inode) if (err < 0 && !status) status = err; + mlog_exit(status); return status; } @@ -3249,6 +3352,8 @@ static int ocfs2_downconvert_lock(struct ocfs2_super *osb, int ret; u32 dlm_flags = DLM_LKF_CONVERT; + mlog_entry_void(); + mlog(ML_BASTS, "lockres %s, level %d => %d\n", lockres->l_name, lockres->l_level, new_level); @@ -3270,6 +3375,7 @@ static int ocfs2_downconvert_lock(struct ocfs2_super *osb, ret = 0; bail: + mlog_exit(ret); return ret; } @@ -3279,6 +3385,8 @@ static int ocfs2_prepare_cancel_convert(struct ocfs2_super *osb, { assert_spin_locked(&lockres->l_lock); + mlog_entry_void(); + if (lockres->l_unlock_action == OCFS2_UNLOCK_CANCEL_CONVERT) { /* If we're already trying to cancel a lock conversion * then just drop the spinlock and allow the caller to @@ -3308,6 +3416,8 @@ static int ocfs2_cancel_convert(struct ocfs2_super *osb, { int ret; + mlog_entry_void(); + ret = ocfs2_dlm_unlock(osb->cconn, &lockres->l_lksb, DLM_LKF_CANCEL); if (ret) { @@ -3317,6 +3427,7 @@ static int ocfs2_cancel_convert(struct ocfs2_super *osb, mlog(ML_BASTS, "lockres %s\n", lockres->l_name); + mlog_exit(ret); return ret; } @@ -3332,6 +3443,8 @@ static int ocfs2_unblock_lock(struct ocfs2_super *osb, int set_lvb = 0; unsigned int gen; + mlog_entry_void(); + spin_lock_irqsave(&lockres->l_lock, flags); recheck: @@ -3506,14 +3619,14 @@ static int ocfs2_unblock_lock(struct ocfs2_super *osb, gen); leave: - if (ret) - mlog_errno(ret); + mlog_exit(ret); return ret; leave_requeue: spin_unlock_irqrestore(&lockres->l_lock, flags); ctl->requeue = 1; + mlog_exit(0); return 0; } @@ -3746,6 +3859,8 @@ static void ocfs2_set_qinfo_lvb(struct ocfs2_lock_res *lockres) struct mem_dqinfo *info = sb_dqinfo(oinfo->dqi_gi.dqi_sb, oinfo->dqi_gi.dqi_type); + mlog_entry_void(); + lvb = ocfs2_dlm_lvb(&lockres->l_lksb); lvb->lvb_version = OCFS2_QINFO_LVB_VERSION; lvb->lvb_bgrace = cpu_to_be32(info->dqi_bgrace); @@ -3754,6 +3869,8 @@ static void ocfs2_set_qinfo_lvb(struct ocfs2_lock_res *lockres) lvb->lvb_blocks = cpu_to_be32(oinfo->dqi_gi.dqi_blocks); lvb->lvb_free_blk = cpu_to_be32(oinfo->dqi_gi.dqi_free_blk); lvb->lvb_free_entry = cpu_to_be32(oinfo->dqi_gi.dqi_free_entry); + + mlog_exit_void(); } void ocfs2_qinfo_unlock(struct ocfs2_mem_dqinfo *oinfo, int ex) @@ -3762,8 +3879,10 @@ void ocfs2_qinfo_unlock(struct ocfs2_mem_dqinfo *oinfo, int ex) struct ocfs2_super *osb = OCFS2_SB(oinfo->dqi_gi.dqi_sb); int level = ex ? DLM_LOCK_EX : DLM_LOCK_PR; + mlog_entry_void(); if (!ocfs2_is_hard_readonly(osb) && !ocfs2_mount_local(osb)) ocfs2_cluster_unlock(osb, lockres, level); + mlog_exit_void(); } static int ocfs2_refresh_qinfo(struct ocfs2_mem_dqinfo *oinfo) @@ -3818,6 +3937,8 @@ int ocfs2_qinfo_lock(struct ocfs2_mem_dqinfo *oinfo, int ex) int level = ex ? DLM_LOCK_EX : DLM_LOCK_PR; int status = 0; + mlog_entry_void(); + /* On RO devices, locking really isn't needed... */ if (ocfs2_is_hard_readonly(osb)) { if (ex) @@ -3840,6 +3961,7 @@ int ocfs2_qinfo_lock(struct ocfs2_mem_dqinfo *oinfo, int ex) ocfs2_qinfo_unlock(oinfo, ex); ocfs2_complete_lock_res_refresh(lockres, status); bail: + mlog_exit(status); return status; } @@ -3885,6 +4007,8 @@ static void ocfs2_process_blocked_lock(struct ocfs2_super *osb, * considered valid until we remove the OCFS2_LOCK_QUEUED * flag. */ + mlog_entry_void(); + BUG_ON(!lockres); BUG_ON(!lockres->l_ops); @@ -3918,11 +4042,15 @@ static void ocfs2_process_blocked_lock(struct ocfs2_super *osb, if (ctl.unblock_action != UNBLOCK_CONTINUE && lockres->l_ops->post_unlock) lockres->l_ops->post_unlock(osb, lockres); + + mlog_exit_void(); } static void ocfs2_schedule_blocked_lock(struct ocfs2_super *osb, struct ocfs2_lock_res *lockres) { + mlog_entry_void(); + assert_spin_locked(&lockres->l_lock); if (lockres->l_flags & OCFS2_LOCK_FREEING) { @@ -3943,6 +4071,8 @@ static void ocfs2_schedule_blocked_lock(struct ocfs2_super *osb, osb->blocked_lock_count++; } spin_unlock(&osb->dc_task_lock); + + mlog_exit_void(); } static void ocfs2_downconvert_thread_do_work(struct ocfs2_super *osb) @@ -3950,6 +4080,8 @@ static void ocfs2_downconvert_thread_do_work(struct ocfs2_super *osb) unsigned long processed; struct ocfs2_lock_res *lockres; + mlog_entry_void(); + spin_lock(&osb->dc_task_lock); /* grab this early so we know to try again if a state change and * wake happens part-way through our work */ @@ -3973,6 +4105,8 @@ static void ocfs2_downconvert_thread_do_work(struct ocfs2_super *osb) spin_lock(&osb->dc_task_lock); } spin_unlock(&osb->dc_task_lock); + + mlog_exit_void(); } static int ocfs2_downconvert_thread_lists_empty(struct ocfs2_super *osb) diff --git a/trunk/fs/ocfs2/export.c b/trunk/fs/ocfs2/export.c index 745db42528d5..254652a9b542 100644 --- a/trunk/fs/ocfs2/export.c +++ b/trunk/fs/ocfs2/export.c @@ -26,6 +26,7 @@ #include #include +#define MLOG_MASK_PREFIX ML_EXPORT #include #include "ocfs2.h" @@ -39,7 +40,6 @@ #include "buffer_head_io.h" #include "suballoc.h" -#include "ocfs2_trace.h" struct ocfs2_inode_handle { @@ -56,9 +56,10 @@ static struct dentry *ocfs2_get_dentry(struct super_block *sb, int status, set; struct dentry *result; - trace_ocfs2_get_dentry_begin(sb, handle, (unsigned long long)blkno); + mlog_entry("(0x%p, 0x%p)\n", sb, handle); if (blkno == 0) { + mlog(0, "nfs wants inode with blkno: 0\n"); result = ERR_PTR(-ESTALE); goto bail; } @@ -82,7 +83,6 @@ static struct dentry *ocfs2_get_dentry(struct super_block *sb, } status = ocfs2_test_inode_bit(osb, blkno, &set); - trace_ocfs2_get_dentry_test_bit(status, set); if (status < 0) { if (status == -EINVAL) { /* @@ -90,14 +90,18 @@ static struct dentry *ocfs2_get_dentry(struct super_block *sb, * as an inode, we return -ESTALE to be * nice */ + mlog(0, "test inode bit failed %d\n", status); status = -ESTALE; - } else + } else { mlog(ML_ERROR, "test inode bit failed %d\n", status); + } goto unlock_nfs_sync; } /* If the inode allocator bit is clear, this inode must be stale */ if (!set) { + mlog(0, "inode %llu suballoc bit is clear\n", + (unsigned long long)blkno); status = -ESTALE; goto unlock_nfs_sync; } @@ -110,8 +114,8 @@ static struct dentry *ocfs2_get_dentry(struct super_block *sb, check_err: if (status < 0) { if (status == -ESTALE) { - trace_ocfs2_get_dentry_stale((unsigned long long)blkno, - handle->ih_generation); + mlog(0, "stale inode ino: %llu generation: %u\n", + (unsigned long long)blkno, handle->ih_generation); } result = ERR_PTR(status); goto bail; @@ -126,9 +130,8 @@ static struct dentry *ocfs2_get_dentry(struct super_block *sb, check_gen: if (handle->ih_generation != inode->i_generation) { iput(inode); - trace_ocfs2_get_dentry_generation((unsigned long long)blkno, - handle->ih_generation, - inode->i_generation); + mlog(0, "stale inode ino: %llu generation: %u\n", + (unsigned long long)blkno, handle->ih_generation); result = ERR_PTR(-ESTALE); goto bail; } @@ -138,7 +141,7 @@ static struct dentry *ocfs2_get_dentry(struct super_block *sb, mlog_errno(PTR_ERR(result)); bail: - trace_ocfs2_get_dentry_end(result); + mlog_exit_ptr(result); return result; } @@ -149,8 +152,11 @@ static struct dentry *ocfs2_get_parent(struct dentry *child) struct dentry *parent; struct inode *dir = child->d_inode; - trace_ocfs2_get_parent(child, child->d_name.len, child->d_name.name, - (unsigned long long)OCFS2_I(dir)->ip_blkno); + mlog_entry("(0x%p, '%.*s')\n", child, + child->d_name.len, child->d_name.name); + + mlog(0, "find parent of directory %llu\n", + (unsigned long long)OCFS2_I(dir)->ip_blkno); status = ocfs2_inode_lock(dir, NULL, 0); if (status < 0) { @@ -172,7 +178,7 @@ static struct dentry *ocfs2_get_parent(struct dentry *child) ocfs2_inode_unlock(dir, 0); bail: - trace_ocfs2_get_parent_end(parent); + mlog_exit_ptr(parent); return parent; } @@ -187,9 +193,9 @@ static int ocfs2_encode_fh(struct dentry *dentry, u32 *fh_in, int *max_len, u32 generation; __le32 *fh = (__force __le32 *) fh_in; - trace_ocfs2_encode_fh_begin(dentry, dentry->d_name.len, - dentry->d_name.name, - fh, len, connectable); + mlog_entry("(0x%p, '%.*s', 0x%p, %d, %d)\n", dentry, + dentry->d_name.len, dentry->d_name.name, + fh, len, connectable); if (connectable && (len < 6)) { *max_len = 6; @@ -204,7 +210,8 @@ static int ocfs2_encode_fh(struct dentry *dentry, u32 *fh_in, int *max_len, blkno = OCFS2_I(inode)->ip_blkno; generation = inode->i_generation; - trace_ocfs2_encode_fh_self((unsigned long long)blkno, generation); + mlog(0, "Encoding fh: blkno: %llu, generation: %u\n", + (unsigned long long)blkno, generation); len = 3; fh[0] = cpu_to_le32((u32)(blkno >> 32)); @@ -229,14 +236,14 @@ static int ocfs2_encode_fh(struct dentry *dentry, u32 *fh_in, int *max_len, len = 6; type = 2; - trace_ocfs2_encode_fh_parent((unsigned long long)blkno, - generation); + mlog(0, "Encoding parent: blkno: %llu, generation: %u\n", + (unsigned long long)blkno, generation); } *max_len = len; bail: - trace_ocfs2_encode_fh_type(type); + mlog_exit(type); return type; } diff --git a/trunk/fs/ocfs2/extent_map.c b/trunk/fs/ocfs2/extent_map.c index 23457b491e8c..09e3fdfa6d33 100644 --- a/trunk/fs/ocfs2/extent_map.c +++ b/trunk/fs/ocfs2/extent_map.c @@ -28,6 +28,7 @@ #include #include +#define MLOG_MASK_PREFIX ML_EXTENT_MAP #include #include "ocfs2.h" @@ -38,7 +39,6 @@ #include "inode.h" #include "super.h" #include "symlink.h" -#include "ocfs2_trace.h" #include "buffer_head_io.h" @@ -841,9 +841,10 @@ int ocfs2_read_virt_blocks(struct inode *inode, u64 v_block, int nr, u64 p_block, p_count; int i, count, done = 0; - trace_ocfs2_read_virt_blocks( - inode, (unsigned long long)v_block, nr, bhs, flags, - validate); + mlog_entry("(inode = %p, v_block = %llu, nr = %d, bhs = %p, " + "flags = %x, validate = %p)\n", + inode, (unsigned long long)v_block, nr, bhs, flags, + validate); if (((v_block + nr - 1) << inode->i_sb->s_blocksize_bits) >= i_size_read(inode)) { @@ -896,6 +897,7 @@ int ocfs2_read_virt_blocks(struct inode *inode, u64 v_block, int nr, } out: + mlog_exit(rc); return rc; } diff --git a/trunk/fs/ocfs2/file.c b/trunk/fs/ocfs2/file.c index 41565ae52856..a6651956482e 100644 --- a/trunk/fs/ocfs2/file.c +++ b/trunk/fs/ocfs2/file.c @@ -38,6 +38,7 @@ #include #include +#define MLOG_MASK_PREFIX ML_INODE #include #include "ocfs2.h" @@ -60,7 +61,6 @@ #include "acl.h" #include "quota.h" #include "refcounttree.h" -#include "ocfs2_trace.h" #include "buffer_head_io.h" @@ -99,10 +99,8 @@ static int ocfs2_file_open(struct inode *inode, struct file *file) int mode = file->f_flags; struct ocfs2_inode_info *oi = OCFS2_I(inode); - trace_ocfs2_file_open(inode, file, file->f_path.dentry, - (unsigned long long)OCFS2_I(inode)->ip_blkno, - file->f_path.dentry->d_name.len, - file->f_path.dentry->d_name.name, mode); + mlog_entry("(0x%p, 0x%p, '%.*s')\n", inode, file, + file->f_path.dentry->d_name.len, file->f_path.dentry->d_name.name); if (file->f_mode & FMODE_WRITE) dquot_initialize(inode); @@ -137,6 +135,7 @@ static int ocfs2_file_open(struct inode *inode, struct file *file) } leave: + mlog_exit(status); return status; } @@ -144,19 +143,19 @@ static int ocfs2_file_release(struct inode *inode, struct file *file) { struct ocfs2_inode_info *oi = OCFS2_I(inode); + mlog_entry("(0x%p, 0x%p, '%.*s')\n", inode, file, + file->f_path.dentry->d_name.len, + file->f_path.dentry->d_name.name); + spin_lock(&oi->ip_lock); if (!--oi->ip_open_count) oi->ip_flags &= ~OCFS2_INODE_OPEN_DIRECT; - - trace_ocfs2_file_release(inode, file, file->f_path.dentry, - oi->ip_blkno, - file->f_path.dentry->d_name.len, - file->f_path.dentry->d_name.name, - oi->ip_open_count); spin_unlock(&oi->ip_lock); ocfs2_free_file_private(inode, file); + mlog_exit(0); + return 0; } @@ -178,11 +177,9 @@ static int ocfs2_sync_file(struct file *file, int datasync) struct inode *inode = file->f_mapping->host; struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); - trace_ocfs2_sync_file(inode, file, file->f_path.dentry, - OCFS2_I(inode)->ip_blkno, - file->f_path.dentry->d_name.len, - file->f_path.dentry->d_name.name, - (unsigned long long)datasync); + mlog_entry("(0x%p, %d, 0x%p, '%.*s')\n", file, datasync, + file->f_path.dentry, file->f_path.dentry->d_name.len, + file->f_path.dentry->d_name.name); if (datasync && !(inode->i_state & I_DIRTY_DATASYNC)) { /* @@ -198,8 +195,7 @@ static int ocfs2_sync_file(struct file *file, int datasync) err = jbd2_journal_force_commit(journal); bail: - if (err) - mlog_errno(err); + mlog_exit(err); return (err < 0) ? -EIO : 0; } @@ -255,6 +251,8 @@ int ocfs2_update_inode_atime(struct inode *inode, handle_t *handle; struct ocfs2_dinode *di = (struct ocfs2_dinode *) bh->b_data; + mlog_entry_void(); + handle = ocfs2_start_trans(osb, OCFS2_INODE_UPDATE_CREDITS); if (IS_ERR(handle)) { ret = PTR_ERR(handle); @@ -282,6 +280,7 @@ int ocfs2_update_inode_atime(struct inode *inode, out_commit: ocfs2_commit_trans(OCFS2_SB(inode->i_sb), handle); out: + mlog_exit(ret); return ret; } @@ -292,6 +291,7 @@ static int ocfs2_set_inode_size(handle_t *handle, { int status; + mlog_entry_void(); i_size_write(inode, new_i_size); inode->i_blocks = ocfs2_inode_sector_count(inode); inode->i_ctime = inode->i_mtime = CURRENT_TIME; @@ -303,6 +303,7 @@ static int ocfs2_set_inode_size(handle_t *handle, } bail: + mlog_exit(status); return status; } @@ -374,6 +375,8 @@ static int ocfs2_orphan_for_truncate(struct ocfs2_super *osb, struct ocfs2_dinode *di; u64 cluster_bytes; + mlog_entry_void(); + /* * We need to CoW the cluster contains the offset if it is reflinked * since we will call ocfs2_zero_range_for_truncate later which will @@ -426,6 +429,8 @@ static int ocfs2_orphan_for_truncate(struct ocfs2_super *osb, out_commit: ocfs2_commit_trans(osb, handle); out: + + mlog_exit(status); return status; } @@ -437,14 +442,14 @@ static int ocfs2_truncate_file(struct inode *inode, struct ocfs2_dinode *fe = NULL; struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); + mlog_entry("(inode = %llu, new_i_size = %llu\n", + (unsigned long long)OCFS2_I(inode)->ip_blkno, + (unsigned long long)new_i_size); + /* We trust di_bh because it comes from ocfs2_inode_lock(), which * already validated it */ fe = (struct ocfs2_dinode *) di_bh->b_data; - trace_ocfs2_truncate_file((unsigned long long)OCFS2_I(inode)->ip_blkno, - (unsigned long long)le64_to_cpu(fe->i_size), - (unsigned long long)new_i_size); - mlog_bug_on_msg(le64_to_cpu(fe->i_size) != i_size_read(inode), "Inode %llu, inode i_size = %lld != di " "i_size = %llu, i_flags = 0x%x\n", @@ -454,14 +459,19 @@ static int ocfs2_truncate_file(struct inode *inode, le32_to_cpu(fe->i_flags)); if (new_i_size > le64_to_cpu(fe->i_size)) { - trace_ocfs2_truncate_file_error( - (unsigned long long)le64_to_cpu(fe->i_size), - (unsigned long long)new_i_size); + mlog(0, "asked to truncate file with size (%llu) to size (%llu)!\n", + (unsigned long long)le64_to_cpu(fe->i_size), + (unsigned long long)new_i_size); status = -EINVAL; mlog_errno(status); goto bail; } + mlog(0, "inode %llu, i_size = %llu, new_i_size = %llu\n", + (unsigned long long)le64_to_cpu(fe->i_blkno), + (unsigned long long)le64_to_cpu(fe->i_size), + (unsigned long long)new_i_size); + /* lets handle the simple truncate cases before doing any more * cluster locking. */ if (new_i_size == le64_to_cpu(fe->i_size)) @@ -515,6 +525,7 @@ static int ocfs2_truncate_file(struct inode *inode, if (!status && OCFS2_I(inode)->ip_clusters == 0) status = ocfs2_try_remove_refcount_tree(inode, di_bh); + mlog_exit(status); return status; } @@ -567,6 +578,8 @@ static int __ocfs2_extend_allocation(struct inode *inode, u32 logical_start, struct ocfs2_extent_tree et; int did_quota = 0; + mlog_entry("(clusters_to_add = %u)\n", clusters_to_add); + /* * This function only exists for file systems which don't * support holes. @@ -583,6 +596,11 @@ static int __ocfs2_extend_allocation(struct inode *inode, u32 logical_start, restart_all: BUG_ON(le32_to_cpu(fe->i_clusters) != OCFS2_I(inode)->ip_clusters); + mlog(0, "extend inode %llu, i_size = %lld, di->i_clusters = %u, " + "clusters_to_add = %u\n", + (unsigned long long)OCFS2_I(inode)->ip_blkno, + (long long)i_size_read(inode), le32_to_cpu(fe->i_clusters), + clusters_to_add); ocfs2_init_dinode_extent_tree(&et, INODE_CACHE(inode), bh); status = ocfs2_lock_allocators(inode, &et, clusters_to_add, 0, &data_ac, &meta_ac); @@ -602,12 +620,6 @@ static int __ocfs2_extend_allocation(struct inode *inode, u32 logical_start, } restarted_transaction: - trace_ocfs2_extend_allocation( - (unsigned long long)OCFS2_I(inode)->ip_blkno, - (unsigned long long)i_size_read(inode), - le32_to_cpu(fe->i_clusters), clusters_to_add, - why, restart_func); - status = dquot_alloc_space_nodirty(inode, ocfs2_clusters_to_bytes(osb->sb, clusters_to_add)); if (status) @@ -654,11 +666,13 @@ static int __ocfs2_extend_allocation(struct inode *inode, u32 logical_start, if (why != RESTART_NONE && clusters_to_add) { if (why == RESTART_META) { + mlog(0, "restarting function.\n"); restart_func = 1; status = 0; } else { BUG_ON(why != RESTART_TRANS); + mlog(0, "restarting transaction.\n"); /* TODO: This can be more intelligent. */ credits = ocfs2_calc_extend_credits(osb->sb, &fe->id2.i_list, @@ -675,11 +689,11 @@ static int __ocfs2_extend_allocation(struct inode *inode, u32 logical_start, } } - trace_ocfs2_extend_allocation_end(OCFS2_I(inode)->ip_blkno, + mlog(0, "fe: i_clusters = %u, i_size=%llu\n", le32_to_cpu(fe->i_clusters), - (unsigned long long)le64_to_cpu(fe->i_size), - OCFS2_I(inode)->ip_clusters, - (unsigned long long)i_size_read(inode)); + (unsigned long long)le64_to_cpu(fe->i_size)); + mlog(0, "inode: ip_clusters=%u, i_size=%lld\n", + OCFS2_I(inode)->ip_clusters, (long long)i_size_read(inode)); leave: if (status < 0 && did_quota) @@ -704,6 +718,7 @@ static int __ocfs2_extend_allocation(struct inode *inode, u32 logical_start, brelse(bh); bh = NULL; + mlog_exit(status); return status; } @@ -770,11 +785,10 @@ static int ocfs2_write_zero_page(struct inode *inode, u64 abs_from, if (!zero_to) zero_to = PAGE_CACHE_SIZE; - trace_ocfs2_write_zero_page( - (unsigned long long)OCFS2_I(inode)->ip_blkno, - (unsigned long long)abs_from, - (unsigned long long)abs_to, - index, zero_from, zero_to); + mlog(0, + "abs_from = %llu, abs_to = %llu, index = %lu, zero_from = %u, zero_to = %u\n", + (unsigned long long)abs_from, (unsigned long long)abs_to, + index, zero_from, zero_to); /* We know that zero_from is block aligned */ for (block_start = zero_from; block_start < zero_to; @@ -914,10 +928,9 @@ static int ocfs2_zero_extend_range(struct inode *inode, u64 range_start, u64 next_pos; u64 zero_pos = range_start; - trace_ocfs2_zero_extend_range( - (unsigned long long)OCFS2_I(inode)->ip_blkno, - (unsigned long long)range_start, - (unsigned long long)range_end); + mlog(0, "range_start = %llu, range_end = %llu\n", + (unsigned long long)range_start, + (unsigned long long)range_end); BUG_ON(range_start >= range_end); while (zero_pos < range_end) { @@ -949,9 +962,9 @@ int ocfs2_zero_extend(struct inode *inode, struct buffer_head *di_bh, struct super_block *sb = inode->i_sb; zero_start = ocfs2_align_bytes_to_blocks(sb, i_size_read(inode)); - trace_ocfs2_zero_extend((unsigned long long)OCFS2_I(inode)->ip_blkno, - (unsigned long long)zero_start, - (unsigned long long)i_size_read(inode)); + mlog(0, "zero_start %llu for i_size %llu\n", + (unsigned long long)zero_start, + (unsigned long long)i_size_read(inode)); while (zero_start < zero_to_size) { ret = ocfs2_zero_extend_get_range(inode, di_bh, zero_start, zero_to_size, @@ -1100,20 +1113,30 @@ int ocfs2_setattr(struct dentry *dentry, struct iattr *attr) struct dquot *transfer_to[MAXQUOTAS] = { }; int qtype; - trace_ocfs2_setattr(inode, dentry, - (unsigned long long)OCFS2_I(inode)->ip_blkno, - dentry->d_name.len, dentry->d_name.name, - attr->ia_valid, attr->ia_mode, - attr->ia_uid, attr->ia_gid); + mlog_entry("(0x%p, '%.*s')\n", dentry, + dentry->d_name.len, dentry->d_name.name); /* ensuring we don't even attempt to truncate a symlink */ if (S_ISLNK(inode->i_mode)) attr->ia_valid &= ~ATTR_SIZE; + if (attr->ia_valid & ATTR_MODE) + mlog(0, "mode change: %d\n", attr->ia_mode); + if (attr->ia_valid & ATTR_UID) + mlog(0, "uid change: %d\n", attr->ia_uid); + if (attr->ia_valid & ATTR_GID) + mlog(0, "gid change: %d\n", attr->ia_gid); + if (attr->ia_valid & ATTR_SIZE) + mlog(0, "size change...\n"); + if (attr->ia_valid & (ATTR_ATIME | ATTR_MTIME | ATTR_CTIME)) + mlog(0, "time change...\n"); + #define OCFS2_VALID_ATTRS (ATTR_ATIME | ATTR_MTIME | ATTR_CTIME | ATTR_SIZE \ | ATTR_GID | ATTR_UID | ATTR_MODE) - if (!(attr->ia_valid & OCFS2_VALID_ATTRS)) + if (!(attr->ia_valid & OCFS2_VALID_ATTRS)) { + mlog(0, "can't handle attrs: 0x%x\n", attr->ia_valid); return 0; + } status = inode_change_ok(inode, attr); if (status) @@ -1251,6 +1274,7 @@ int ocfs2_setattr(struct dentry *dentry, struct iattr *attr) mlog_errno(status); } + mlog_exit(status); return status; } @@ -1263,6 +1287,8 @@ int ocfs2_getattr(struct vfsmount *mnt, struct ocfs2_super *osb = sb->s_fs_info; int err; + mlog_entry_void(); + err = ocfs2_inode_revalidate(dentry); if (err) { if (err != -ENOENT) @@ -1276,6 +1302,8 @@ int ocfs2_getattr(struct vfsmount *mnt, stat->blksize = osb->s_clustersize; bail: + mlog_exit(err); + return err; } @@ -1286,6 +1314,8 @@ int ocfs2_permission(struct inode *inode, int mask, unsigned int flags) if (flags & IPERM_FLAG_RCU) return -ECHILD; + mlog_entry_void(); + ret = ocfs2_inode_lock(inode, NULL, 0); if (ret) { if (ret != -ENOENT) @@ -1297,6 +1327,7 @@ int ocfs2_permission(struct inode *inode, int mask, unsigned int flags) ocfs2_inode_unlock(inode, 0); out: + mlog_exit(ret); return ret; } @@ -1308,9 +1339,8 @@ static int __ocfs2_write_remove_suid(struct inode *inode, struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); struct ocfs2_dinode *di; - trace_ocfs2_write_remove_suid( - (unsigned long long)OCFS2_I(inode)->ip_blkno, - inode->i_mode); + mlog_entry("(Inode %llu, mode 0%o)\n", + (unsigned long long)OCFS2_I(inode)->ip_blkno, inode->i_mode); handle = ocfs2_start_trans(osb, OCFS2_INODE_UPDATE_CREDITS); if (IS_ERR(handle)) { @@ -1338,6 +1368,7 @@ static int __ocfs2_write_remove_suid(struct inode *inode, out_trans: ocfs2_commit_trans(osb, handle); out: + mlog_exit(ret); return ret; } @@ -1516,9 +1547,8 @@ static int ocfs2_zero_partial_clusters(struct inode *inode, * partial clusters here. There's no need to worry about * physical allocation - the zeroing code knows to skip holes. */ - trace_ocfs2_zero_partial_clusters( - (unsigned long long)OCFS2_I(inode)->ip_blkno, - (unsigned long long)start, (unsigned long long)end); + mlog(0, "byte start: %llu, end: %llu\n", + (unsigned long long)start, (unsigned long long)end); /* * If both edges are on a cluster boundary then there's no @@ -1542,8 +1572,8 @@ static int ocfs2_zero_partial_clusters(struct inode *inode, if (tmpend > end) tmpend = end; - trace_ocfs2_zero_partial_clusters_range1((unsigned long long)start, - (unsigned long long)tmpend); + mlog(0, "1st range: start: %llu, tmpend: %llu\n", + (unsigned long long)start, (unsigned long long)tmpend); ret = ocfs2_zero_range_for_truncate(inode, handle, start, tmpend); if (ret) @@ -1557,8 +1587,8 @@ static int ocfs2_zero_partial_clusters(struct inode *inode, */ start = end & ~(osb->s_clustersize - 1); - trace_ocfs2_zero_partial_clusters_range2( - (unsigned long long)start, (unsigned long long)end); + mlog(0, "2nd range: start: %llu, end: %llu\n", + (unsigned long long)start, (unsigned long long)end); ret = ocfs2_zero_range_for_truncate(inode, handle, start, end); if (ret) @@ -1658,11 +1688,6 @@ static int ocfs2_remove_inode_range(struct inode *inode, ocfs2_init_dinode_extent_tree(&et, INODE_CACHE(inode), di_bh); ocfs2_init_dealloc_ctxt(&dealloc); - trace_ocfs2_remove_inode_range( - (unsigned long long)OCFS2_I(inode)->ip_blkno, - (unsigned long long)byte_start, - (unsigned long long)byte_len); - if (byte_len == 0) return 0; @@ -1709,6 +1734,11 @@ static int ocfs2_remove_inode_range(struct inode *inode, trunc_end = (byte_start + byte_len) >> osb->s_clustersize_bits; cluster_in_el = trunc_end; + mlog(0, "Inode: %llu, start: %llu, len: %llu, cstart: %u, cend: %u\n", + (unsigned long long)OCFS2_I(inode)->ip_blkno, + (unsigned long long)byte_start, + (unsigned long long)byte_len, trunc_start, trunc_end); + ret = ocfs2_zero_partial_clusters(inode, byte_start, byte_len); if (ret) { mlog_errno(ret); @@ -2063,7 +2093,7 @@ static int ocfs2_prepare_inode_for_write(struct file *file, int ret = 0, meta_level = 0; struct dentry *dentry = file->f_path.dentry; struct inode *inode = dentry->d_inode; - loff_t saved_pos = 0, end; + loff_t saved_pos, end; /* * We start with a read level meta lock and only jump to an ex @@ -2102,10 +2132,12 @@ static int ocfs2_prepare_inode_for_write(struct file *file, /* work on a copy of ppos until we're sure that we won't have * to recalculate it due to relocking. */ - if (appending) + if (appending) { saved_pos = i_size_read(inode); - else + mlog(0, "O_APPEND: inode->i_size=%llu\n", saved_pos); + } else { saved_pos = *ppos; + } end = saved_pos + count; @@ -2176,10 +2208,6 @@ static int ocfs2_prepare_inode_for_write(struct file *file, *ppos = saved_pos; out_unlock: - trace_ocfs2_prepare_inode_for_write(OCFS2_I(inode)->ip_blkno, - saved_pos, appending, count, - direct_io, has_refcount); - if (meta_level >= 0) ocfs2_inode_unlock(inode, meta_level); @@ -2205,11 +2233,10 @@ static ssize_t ocfs2_file_aio_write(struct kiocb *iocb, int full_coherency = !(osb->s_mount_opt & OCFS2_MOUNT_COHERENCY_BUFFERED); - trace_ocfs2_file_aio_write(inode, file, file->f_path.dentry, - (unsigned long long)OCFS2_I(inode)->ip_blkno, - file->f_path.dentry->d_name.len, - file->f_path.dentry->d_name.name, - (unsigned int)nr_segs); + mlog_entry("(0x%p, %u, '%.*s')\n", file, + (unsigned int)nr_segs, + file->f_path.dentry->d_name.len, + file->f_path.dentry->d_name.name); if (iocb->ki_left == 0) return 0; @@ -2375,6 +2402,7 @@ static ssize_t ocfs2_file_aio_write(struct kiocb *iocb, if (written) ret = written; + mlog_exit(ret); return ret; } @@ -2410,11 +2438,10 @@ static ssize_t ocfs2_file_splice_write(struct pipe_inode_info *pipe, .u.file = out, }; - - trace_ocfs2_file_splice_write(inode, out, out->f_path.dentry, - (unsigned long long)OCFS2_I(inode)->ip_blkno, - out->f_path.dentry->d_name.len, - out->f_path.dentry->d_name.name, len); + mlog_entry("(0x%p, 0x%p, %u, '%.*s')\n", out, pipe, + (unsigned int)len, + out->f_path.dentry->d_name.len, + out->f_path.dentry->d_name.name); if (pipe->inode) mutex_lock_nested(&pipe->inode->i_mutex, I_MUTEX_PARENT); @@ -2458,6 +2485,7 @@ static ssize_t ocfs2_file_splice_write(struct pipe_inode_info *pipe, balance_dirty_pages_ratelimited_nr(mapping, nr_pages); } + mlog_exit(ret); return ret; } @@ -2470,10 +2498,10 @@ static ssize_t ocfs2_file_splice_read(struct file *in, int ret = 0, lock_level = 0; struct inode *inode = in->f_path.dentry->d_inode; - trace_ocfs2_file_splice_read(inode, in, in->f_path.dentry, - (unsigned long long)OCFS2_I(inode)->ip_blkno, - in->f_path.dentry->d_name.len, - in->f_path.dentry->d_name.name, len); + mlog_entry("(0x%p, 0x%p, %u, '%.*s')\n", in, pipe, + (unsigned int)len, + in->f_path.dentry->d_name.len, + in->f_path.dentry->d_name.name); /* * See the comment in ocfs2_file_aio_read() @@ -2488,6 +2516,7 @@ static ssize_t ocfs2_file_splice_read(struct file *in, ret = generic_file_splice_read(in, ppos, pipe, len, flags); bail: + mlog_exit(ret); return ret; } @@ -2500,11 +2529,10 @@ static ssize_t ocfs2_file_aio_read(struct kiocb *iocb, struct file *filp = iocb->ki_filp; struct inode *inode = filp->f_path.dentry->d_inode; - trace_ocfs2_file_aio_read(inode, filp, filp->f_path.dentry, - (unsigned long long)OCFS2_I(inode)->ip_blkno, - filp->f_path.dentry->d_name.len, - filp->f_path.dentry->d_name.name, nr_segs); - + mlog_entry("(0x%p, %u, '%.*s')\n", filp, + (unsigned int)nr_segs, + filp->f_path.dentry->d_name.len, + filp->f_path.dentry->d_name.name); if (!inode) { ret = -EINVAL; @@ -2550,7 +2578,8 @@ static ssize_t ocfs2_file_aio_read(struct kiocb *iocb, ocfs2_inode_unlock(inode, lock_level); ret = generic_file_aio_read(iocb, iov, nr_segs, iocb->ki_pos); - trace_generic_file_aio_read_ret(ret); + if (ret == -EINVAL) + mlog(0, "generic_file_aio_read returned -EINVAL\n"); /* buffered aio wouldn't have proper lock coverage today */ BUG_ON(ret == -EIOCBQUEUED && !(filp->f_flags & O_DIRECT)); @@ -2568,6 +2597,7 @@ static ssize_t ocfs2_file_aio_read(struct kiocb *iocb, } if (rw_level != -1) ocfs2_rw_unlock(inode, rw_level); + mlog_exit(ret); return ret; } diff --git a/trunk/fs/ocfs2/heartbeat.c b/trunk/fs/ocfs2/heartbeat.c index d8208b20dc53..1aa863dd901f 100644 --- a/trunk/fs/ocfs2/heartbeat.c +++ b/trunk/fs/ocfs2/heartbeat.c @@ -28,6 +28,7 @@ #include #include +#define MLOG_MASK_PREFIX ML_SUPER #include #include "ocfs2.h" @@ -36,7 +37,6 @@ #include "heartbeat.h" #include "inode.h" #include "journal.h" -#include "ocfs2_trace.h" #include "buffer_head_io.h" @@ -66,7 +66,7 @@ void ocfs2_do_node_down(int node_num, void *data) BUG_ON(osb->node_num == node_num); - trace_ocfs2_do_node_down(node_num); + mlog(0, "ocfs2: node down event for %d\n", node_num); if (!osb->cconn) { /* diff --git a/trunk/fs/ocfs2/inode.c b/trunk/fs/ocfs2/inode.c index 177d3a6c2a5f..4068c6c4c6f6 100644 --- a/trunk/fs/ocfs2/inode.c +++ b/trunk/fs/ocfs2/inode.c @@ -31,6 +31,7 @@ #include +#define MLOG_MASK_PREFIX ML_INODE #include #include "ocfs2.h" @@ -52,7 +53,6 @@ #include "uptodate.h" #include "xattr.h" #include "refcounttree.h" -#include "ocfs2_trace.h" #include "buffer_head_io.h" @@ -131,8 +131,7 @@ struct inode *ocfs2_iget(struct ocfs2_super *osb, u64 blkno, unsigned flags, struct super_block *sb = osb->sb; struct ocfs2_find_inode_args args; - trace_ocfs2_iget_begin((unsigned long long)blkno, flags, - sysfile_type); + mlog_entry("(blkno = %llu)\n", (unsigned long long)blkno); /* Ok. By now we've either got the offsets passed to us by the * caller, or we just pulled them off the bh. Lets do some @@ -153,16 +152,16 @@ struct inode *ocfs2_iget(struct ocfs2_super *osb, u64 blkno, unsigned flags, /* inode was *not* in the inode cache. 2.6.x requires * us to do our own read_inode call and unlock it * afterwards. */ + if (inode && inode->i_state & I_NEW) { + mlog(0, "Inode was not in inode cache, reading it.\n"); + ocfs2_read_locked_inode(inode, &args); + unlock_new_inode(inode); + } if (inode == NULL) { inode = ERR_PTR(-ENOMEM); mlog_errno(PTR_ERR(inode)); goto bail; } - trace_ocfs2_iget5_locked(inode->i_state); - if (inode->i_state & I_NEW) { - ocfs2_read_locked_inode(inode, &args); - unlock_new_inode(inode); - } if (is_bad_inode(inode)) { iput(inode); inode = ERR_PTR(-ESTALE); @@ -171,8 +170,9 @@ struct inode *ocfs2_iget(struct ocfs2_super *osb, u64 blkno, unsigned flags, bail: if (!IS_ERR(inode)) { - trace_ocfs2_iget_end(inode, - (unsigned long long)OCFS2_I(inode)->ip_blkno); + mlog(0, "returning inode with number %llu\n", + (unsigned long long)OCFS2_I(inode)->ip_blkno); + mlog_exit_ptr(inode); } return inode; @@ -192,17 +192,18 @@ static int ocfs2_find_actor(struct inode *inode, void *opaque) struct ocfs2_inode_info *oi = OCFS2_I(inode); int ret = 0; + mlog_entry("(0x%p, %lu, 0x%p)\n", inode, inode->i_ino, opaque); + args = opaque; mlog_bug_on_msg(!inode, "No inode in find actor!\n"); - trace_ocfs2_find_actor(inode, inode->i_ino, opaque, args->fi_blkno); - if (oi->ip_blkno != args->fi_blkno) goto bail; ret = 1; bail: + mlog_exit(ret); return ret; } @@ -217,6 +218,8 @@ static int ocfs2_init_locked_inode(struct inode *inode, void *opaque) static struct lock_class_key ocfs2_quota_ip_alloc_sem_key, ocfs2_file_ip_alloc_sem_key; + mlog_entry("inode = %p, opaque = %p\n", inode, opaque); + inode->i_ino = args->fi_ino; OCFS2_I(inode)->ip_blkno = args->fi_blkno; if (args->fi_sysfile_type != 0) @@ -232,6 +235,7 @@ static int ocfs2_init_locked_inode(struct inode *inode, void *opaque) lockdep_set_class(&OCFS2_I(inode)->ip_alloc_sem, &ocfs2_file_ip_alloc_sem_key); + mlog_exit(0); return 0; } @@ -242,6 +246,9 @@ void ocfs2_populate_inode(struct inode *inode, struct ocfs2_dinode *fe, struct ocfs2_super *osb; int use_plocks = 1; + mlog_entry("(0x%p, size:%llu)\n", inode, + (unsigned long long)le64_to_cpu(fe->i_size)); + sb = inode->i_sb; osb = OCFS2_SB(sb); @@ -293,20 +300,20 @@ void ocfs2_populate_inode(struct inode *inode, struct ocfs2_dinode *fe, inode->i_nlink = ocfs2_read_links_count(fe); - trace_ocfs2_populate_inode(OCFS2_I(inode)->ip_blkno, - le32_to_cpu(fe->i_flags)); if (fe->i_flags & cpu_to_le32(OCFS2_SYSTEM_FL)) { OCFS2_I(inode)->ip_flags |= OCFS2_INODE_SYSTEM_FILE; inode->i_flags |= S_NOQUOTA; } - + if (fe->i_flags & cpu_to_le32(OCFS2_LOCAL_ALLOC_FL)) { OCFS2_I(inode)->ip_flags |= OCFS2_INODE_BITMAP; + mlog(0, "local alloc inode: i_ino=%lu\n", inode->i_ino); } else if (fe->i_flags & cpu_to_le32(OCFS2_BITMAP_FL)) { OCFS2_I(inode)->ip_flags |= OCFS2_INODE_BITMAP; } else if (fe->i_flags & cpu_to_le32(OCFS2_QUOTA_FL)) { inode->i_flags |= S_NOQUOTA; } else if (fe->i_flags & cpu_to_le32(OCFS2_SUPER_BLOCK_FL)) { + mlog(0, "superblock inode: i_ino=%lu\n", inode->i_ino); /* we can't actually hit this as read_inode can't * handle superblocks today ;-) */ BUG(); @@ -374,6 +381,7 @@ void ocfs2_populate_inode(struct inode *inode, struct ocfs2_dinode *fe, if (S_ISDIR(inode->i_mode)) ocfs2_resv_set_type(&OCFS2_I(inode)->ip_la_data_resv, OCFS2_RESV_FLAG_DIR); + mlog_exit_void(); } static int ocfs2_read_locked_inode(struct inode *inode, @@ -386,6 +394,8 @@ static int ocfs2_read_locked_inode(struct inode *inode, int status, can_lock; u32 generation = 0; + mlog_entry("(0x%p, 0x%p)\n", inode, args); + status = -EINVAL; if (inode == NULL || inode->i_sb == NULL) { mlog(ML_ERROR, "bad inode\n"); @@ -433,9 +443,6 @@ static int ocfs2_read_locked_inode(struct inode *inode, && !(args->fi_flags & OCFS2_FI_FLAG_ORPHAN_RECOVERY) && !ocfs2_mount_local(osb); - trace_ocfs2_read_locked_inode( - (unsigned long long)OCFS2_I(inode)->ip_blkno, can_lock); - /* * To maintain backwards compatibility with older versions of * ocfs2-tools, we still store the generation value for system @@ -527,6 +534,7 @@ static int ocfs2_read_locked_inode(struct inode *inode, if (args && bh) brelse(bh); + mlog_exit(status); return status; } @@ -543,6 +551,8 @@ static int ocfs2_truncate_for_delete(struct ocfs2_super *osb, struct ocfs2_dinode *fe; handle_t *handle = NULL; + mlog_entry_void(); + fe = (struct ocfs2_dinode *) fe_bh->b_data; /* @@ -590,6 +600,7 @@ static int ocfs2_truncate_for_delete(struct ocfs2_super *osb, out: if (handle) ocfs2_commit_trans(osb, handle); + mlog_exit(status); return status; } @@ -685,6 +696,8 @@ static int ocfs2_check_orphan_recovery_state(struct ocfs2_super *osb, spin_lock(&osb->osb_lock); if (ocfs2_node_map_test_bit(osb, &osb->osb_recovering_orphan_dirs, slot)) { + mlog(0, "Recovery is happening on orphan dir %d, will skip " + "this inode\n", slot); ret = -EDEADLK; goto out; } @@ -693,7 +706,6 @@ static int ocfs2_check_orphan_recovery_state(struct ocfs2_super *osb, osb->osb_orphan_wipes[slot]++; out: spin_unlock(&osb->osb_lock); - trace_ocfs2_check_orphan_recovery_state(slot, ret); return ret; } @@ -804,10 +816,6 @@ static int ocfs2_inode_is_valid_to_delete(struct inode *inode) struct ocfs2_inode_info *oi = OCFS2_I(inode); struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); - trace_ocfs2_inode_is_valid_to_delete(current, osb->dc_task, - (unsigned long long)oi->ip_blkno, - oi->ip_flags); - /* We shouldn't be getting here for the root directory * inode.. */ if (inode == osb->root_inode) { @@ -820,8 +828,11 @@ static int ocfs2_inode_is_valid_to_delete(struct inode *inode) * have to skip deleting this guy. That's OK though because * the node who's doing the actual deleting should handle it * anyway. */ - if (current == osb->dc_task) + if (current == osb->dc_task) { + mlog(0, "Skipping delete of %lu because we're currently " + "in downconvert\n", inode->i_ino); goto bail; + } spin_lock(&oi->ip_lock); /* OCFS2 *never* deletes system files. This should technically @@ -836,8 +847,11 @@ static int ocfs2_inode_is_valid_to_delete(struct inode *inode) /* If we have allowd wipe of this inode for another node, it * will be marked here so we can safely skip it. Recovery will * cleanup any inodes we might inadvertantly skip here. */ - if (oi->ip_flags & OCFS2_INODE_SKIP_DELETE) + if (oi->ip_flags & OCFS2_INODE_SKIP_DELETE) { + mlog(0, "Skipping delete of %lu because another node " + "has done this for us.\n", inode->i_ino); goto bail_unlock; + } ret = 1; bail_unlock: @@ -854,27 +868,28 @@ static int ocfs2_query_inode_wipe(struct inode *inode, struct buffer_head *di_bh, int *wipe) { - int status = 0, reason = 0; + int status = 0; struct ocfs2_inode_info *oi = OCFS2_I(inode); struct ocfs2_dinode *di; *wipe = 0; - trace_ocfs2_query_inode_wipe_begin((unsigned long long)oi->ip_blkno, - inode->i_nlink); - /* While we were waiting for the cluster lock in * ocfs2_delete_inode, another node might have asked to delete * the inode. Recheck our flags to catch this. */ if (!ocfs2_inode_is_valid_to_delete(inode)) { - reason = 1; + mlog(0, "Skipping delete of %llu because flags changed\n", + (unsigned long long)oi->ip_blkno); goto bail; } /* Now that we have an up to date inode, we can double check * the link count. */ - if (inode->i_nlink) + if (inode->i_nlink) { + mlog(0, "Skipping delete of %llu because nlink = %u\n", + (unsigned long long)oi->ip_blkno, inode->i_nlink); goto bail; + } /* Do some basic inode verification... */ di = (struct ocfs2_dinode *) di_bh->b_data; @@ -889,7 +904,9 @@ static int ocfs2_query_inode_wipe(struct inode *inode, * ORPHANED_FL not. */ if (di->i_dyn_features & cpu_to_le16(OCFS2_HAS_REFCOUNT_FL)) { - reason = 2; + mlog(0, "Reflinked inode %llu is no longer orphaned. " + "it shouldn't be deleted\n", + (unsigned long long)oi->ip_blkno); goto bail; } @@ -926,7 +943,8 @@ static int ocfs2_query_inode_wipe(struct inode *inode, status = ocfs2_try_open_lock(inode, 1); if (status == -EAGAIN) { status = 0; - reason = 3; + mlog(0, "Skipping delete of %llu because it is in use on " + "other nodes\n", (unsigned long long)oi->ip_blkno); goto bail; } if (status < 0) { @@ -935,10 +953,11 @@ static int ocfs2_query_inode_wipe(struct inode *inode, } *wipe = 1; - trace_ocfs2_query_inode_wipe_succ(le16_to_cpu(di->i_orphaned_slot)); + mlog(0, "Inode %llu is ok to wipe from orphan dir %u\n", + (unsigned long long)oi->ip_blkno, + le16_to_cpu(di->i_orphaned_slot)); bail: - trace_ocfs2_query_inode_wipe_end(status, reason); return status; } @@ -948,8 +967,8 @@ static int ocfs2_query_inode_wipe(struct inode *inode, static void ocfs2_cleanup_delete_inode(struct inode *inode, int sync_data) { - trace_ocfs2_cleanup_delete_inode( - (unsigned long long)OCFS2_I(inode)->ip_blkno, sync_data); + mlog(0, "Cleanup inode %llu, sync = %d\n", + (unsigned long long)OCFS2_I(inode)->ip_blkno, sync_data); if (sync_data) write_inode_now(inode, 1); truncate_inode_pages(&inode->i_data, 0); @@ -961,15 +980,15 @@ static void ocfs2_delete_inode(struct inode *inode) sigset_t oldset; struct buffer_head *di_bh = NULL; - trace_ocfs2_delete_inode(inode->i_ino, - (unsigned long long)OCFS2_I(inode)->ip_blkno, - is_bad_inode(inode)); + mlog_entry("(inode->i_ino = %lu)\n", inode->i_ino); /* When we fail in read_inode() we mark inode as bad. The second test * catches the case when inode allocation fails before allocating * a block for inode. */ - if (is_bad_inode(inode) || !OCFS2_I(inode)->ip_blkno) + if (is_bad_inode(inode) || !OCFS2_I(inode)->ip_blkno) { + mlog(0, "Skipping delete of bad inode\n"); goto bail; + } dquot_initialize(inode); @@ -1061,7 +1080,7 @@ static void ocfs2_delete_inode(struct inode *inode) bail_unblock: ocfs2_unblock_signals(&oldset); bail: - return; + mlog_exit_void(); } static void ocfs2_clear_inode(struct inode *inode) @@ -1069,9 +1088,11 @@ static void ocfs2_clear_inode(struct inode *inode) int status; struct ocfs2_inode_info *oi = OCFS2_I(inode); + mlog_entry_void(); + end_writeback(inode); - trace_ocfs2_clear_inode((unsigned long long)oi->ip_blkno, - inode->i_nlink); + mlog(0, "Clearing inode: %llu, nlink = %u\n", + (unsigned long long)OCFS2_I(inode)->ip_blkno, inode->i_nlink); mlog_bug_on_msg(OCFS2_SB(inode->i_sb) == NULL, "Inode=%lu\n", inode->i_ino); @@ -1160,6 +1181,8 @@ static void ocfs2_clear_inode(struct inode *inode) */ jbd2_journal_release_jbd_inode(OCFS2_SB(inode->i_sb)->journal->j_journal, &oi->ip_jinode); + + mlog_exit_void(); } void ocfs2_evict_inode(struct inode *inode) @@ -1181,14 +1204,17 @@ int ocfs2_drop_inode(struct inode *inode) struct ocfs2_inode_info *oi = OCFS2_I(inode); int res; - trace_ocfs2_drop_inode((unsigned long long)oi->ip_blkno, - inode->i_nlink, oi->ip_flags); + mlog_entry_void(); + + mlog(0, "Drop inode %llu, nlink = %u, ip_flags = 0x%x\n", + (unsigned long long)oi->ip_blkno, inode->i_nlink, oi->ip_flags); if (oi->ip_flags & OCFS2_INODE_MAYBE_ORPHANED) res = 1; else res = generic_drop_inode(inode); + mlog_exit_void(); return res; } @@ -1200,11 +1226,11 @@ int ocfs2_inode_revalidate(struct dentry *dentry) struct inode *inode = dentry->d_inode; int status = 0; - trace_ocfs2_inode_revalidate(inode, - inode ? (unsigned long long)OCFS2_I(inode)->ip_blkno : 0ULL, - inode ? (unsigned long long)OCFS2_I(inode)->ip_flags : 0); + mlog_entry("(inode = 0x%p, ino = %llu)\n", inode, + inode ? (unsigned long long)OCFS2_I(inode)->ip_blkno : 0ULL); if (!inode) { + mlog(0, "eep, no inode!\n"); status = -ENOENT; goto bail; } @@ -1212,6 +1238,7 @@ int ocfs2_inode_revalidate(struct dentry *dentry) spin_lock(&OCFS2_I(inode)->ip_lock); if (OCFS2_I(inode)->ip_flags & OCFS2_INODE_DELETED) { spin_unlock(&OCFS2_I(inode)->ip_lock); + mlog(0, "inode deleted!\n"); status = -ENOENT; goto bail; } @@ -1227,6 +1254,8 @@ int ocfs2_inode_revalidate(struct dentry *dentry) } ocfs2_inode_unlock(inode, 0); bail: + mlog_exit(status); + return status; } @@ -1242,7 +1271,8 @@ int ocfs2_mark_inode_dirty(handle_t *handle, int status; struct ocfs2_dinode *fe = (struct ocfs2_dinode *) bh->b_data; - trace_ocfs2_mark_inode_dirty((unsigned long long)OCFS2_I(inode)->ip_blkno); + mlog_entry("(inode %llu)\n", + (unsigned long long)OCFS2_I(inode)->ip_blkno); status = ocfs2_journal_access_di(handle, INODE_CACHE(inode), bh, OCFS2_JOURNAL_ACCESS_WRITE); @@ -1272,6 +1302,7 @@ int ocfs2_mark_inode_dirty(handle_t *handle, ocfs2_journal_dirty(handle, bh); leave: + mlog_exit(status); return status; } @@ -1314,7 +1345,8 @@ int ocfs2_validate_inode_block(struct super_block *sb, int rc; struct ocfs2_dinode *di = (struct ocfs2_dinode *)bh->b_data; - trace_ocfs2_validate_inode_block((unsigned long long)bh->b_blocknr); + mlog(0, "Validating dinode %llu\n", + (unsigned long long)bh->b_blocknr); BUG_ON(!buffer_uptodate(bh)); diff --git a/trunk/fs/ocfs2/ioctl.c b/trunk/fs/ocfs2/ioctl.c index 8f13c5989eae..09de77ce002a 100644 --- a/trunk/fs/ocfs2/ioctl.c +++ b/trunk/fs/ocfs2/ioctl.c @@ -9,6 +9,7 @@ #include #include +#define MLOG_MASK_PREFIX ML_INODE #include #include "ocfs2.h" @@ -45,22 +46,6 @@ static inline void __o2info_set_request_error(struct ocfs2_info_request *kreq, #define o2info_set_request_error(a, b) \ __o2info_set_request_error((struct ocfs2_info_request *)&(a), b) -static inline void __o2info_set_request_filled(struct ocfs2_info_request *req) -{ - req->ir_flags |= OCFS2_INFO_FL_FILLED; -} - -#define o2info_set_request_filled(a) \ - __o2info_set_request_filled((struct ocfs2_info_request *)&(a)) - -static inline void __o2info_clear_request_filled(struct ocfs2_info_request *req) -{ - req->ir_flags &= ~OCFS2_INFO_FL_FILLED; -} - -#define o2info_clear_request_filled(a) \ - __o2info_clear_request_filled((struct ocfs2_info_request *)&(a)) - static int ocfs2_get_inode_attr(struct inode *inode, unsigned *flags) { int status; @@ -74,6 +59,7 @@ static int ocfs2_get_inode_attr(struct inode *inode, unsigned *flags) *flags = OCFS2_I(inode)->ip_attr; ocfs2_inode_unlock(inode, 0); + mlog_exit(status); return status; } @@ -139,6 +125,7 @@ static int ocfs2_set_inode_attr(struct inode *inode, unsigned flags, brelse(bh); + mlog_exit(status); return status; } @@ -152,8 +139,7 @@ int ocfs2_info_handle_blocksize(struct inode *inode, goto bail; oib.ib_blocksize = inode->i_sb->s_blocksize; - - o2info_set_request_filled(oib); + oib.ib_req.ir_flags |= OCFS2_INFO_FL_FILLED; if (o2info_to_user(oib, req)) goto bail; @@ -177,8 +163,7 @@ int ocfs2_info_handle_clustersize(struct inode *inode, goto bail; oic.ic_clustersize = osb->s_clustersize; - - o2info_set_request_filled(oic); + oic.ic_req.ir_flags |= OCFS2_INFO_FL_FILLED; if (o2info_to_user(oic, req)) goto bail; @@ -202,8 +187,7 @@ int ocfs2_info_handle_maxslots(struct inode *inode, goto bail; oim.im_max_slots = osb->max_slots; - - o2info_set_request_filled(oim); + oim.im_req.ir_flags |= OCFS2_INFO_FL_FILLED; if (o2info_to_user(oim, req)) goto bail; @@ -227,8 +211,7 @@ int ocfs2_info_handle_label(struct inode *inode, goto bail; memcpy(oil.il_label, osb->vol_label, OCFS2_MAX_VOL_LABEL_LEN); - - o2info_set_request_filled(oil); + oil.il_req.ir_flags |= OCFS2_INFO_FL_FILLED; if (o2info_to_user(oil, req)) goto bail; @@ -252,8 +235,7 @@ int ocfs2_info_handle_uuid(struct inode *inode, goto bail; memcpy(oiu.iu_uuid_str, osb->uuid_str, OCFS2_TEXT_UUID_LEN + 1); - - o2info_set_request_filled(oiu); + oiu.iu_req.ir_flags |= OCFS2_INFO_FL_FILLED; if (o2info_to_user(oiu, req)) goto bail; @@ -279,8 +261,7 @@ int ocfs2_info_handle_fs_features(struct inode *inode, oif.if_compat_features = osb->s_feature_compat; oif.if_incompat_features = osb->s_feature_incompat; oif.if_ro_compat_features = osb->s_feature_ro_compat; - - o2info_set_request_filled(oif); + oif.if_req.ir_flags |= OCFS2_INFO_FL_FILLED; if (o2info_to_user(oif, req)) goto bail; @@ -305,7 +286,7 @@ int ocfs2_info_handle_journal_size(struct inode *inode, oij.ij_journal_size = osb->journal->j_inode->i_size; - o2info_set_request_filled(oij); + oij.ij_req.ir_flags |= OCFS2_INFO_FL_FILLED; if (o2info_to_user(oij, req)) goto bail; @@ -327,7 +308,7 @@ int ocfs2_info_handle_unknown(struct inode *inode, if (o2info_from_user(oir, req)) goto bail; - o2info_clear_request_filled(oir); + oir.ir_flags &= ~OCFS2_INFO_FL_FILLED; if (o2info_to_user(oir, req)) goto bail; diff --git a/trunk/fs/ocfs2/journal.c b/trunk/fs/ocfs2/journal.c index dcc2d9327150..faa2303dbf0a 100644 --- a/trunk/fs/ocfs2/journal.c +++ b/trunk/fs/ocfs2/journal.c @@ -31,6 +31,7 @@ #include #include +#define MLOG_MASK_PREFIX ML_JOURNAL #include #include "ocfs2.h" @@ -51,7 +52,6 @@ #include "quota.h" #include "buffer_head_io.h" -#include "ocfs2_trace.h" DEFINE_SPINLOCK(trans_inc_lock); @@ -303,15 +303,16 @@ static int ocfs2_commit_cache(struct ocfs2_super *osb) unsigned int flushed; struct ocfs2_journal *journal = NULL; + mlog_entry_void(); + journal = osb->journal; /* Flush all pending commits and checkpoint the journal. */ down_write(&journal->j_trans_barrier); - flushed = atomic_read(&journal->j_num_trans); - trace_ocfs2_commit_cache_begin(flushed); - if (flushed == 0) { + if (atomic_read(&journal->j_num_trans) == 0) { up_write(&journal->j_trans_barrier); + mlog(0, "No transactions for me to flush!\n"); goto finally; } @@ -330,11 +331,13 @@ static int ocfs2_commit_cache(struct ocfs2_super *osb) atomic_set(&journal->j_num_trans, 0); up_write(&journal->j_trans_barrier); - trace_ocfs2_commit_cache_end(journal->j_trans_id, flushed); + mlog(0, "commit_thread: flushed transaction %lu (%u handles)\n", + journal->j_trans_id, flushed); ocfs2_wake_downconvert_thread(osb); wake_up(&journal->j_checkpointed); finally: + mlog_exit(status); return status; } @@ -422,8 +425,9 @@ int ocfs2_extend_trans(handle_t *handle, int nblocks) return 0; old_nblocks = handle->h_buffer_credits; + mlog_entry_void(); - trace_ocfs2_extend_trans(old_nblocks, nblocks); + mlog(0, "Trying to extend transaction by %d blocks\n", nblocks); #ifdef CONFIG_OCFS2_DEBUG_FS status = 1; @@ -436,7 +440,9 @@ int ocfs2_extend_trans(handle_t *handle, int nblocks) #endif if (status > 0) { - trace_ocfs2_extend_trans_restart(old_nblocks + nblocks); + mlog(0, + "jbd2_journal_extend failed, trying " + "jbd2_journal_restart\n"); status = jbd2_journal_restart(handle, old_nblocks + nblocks); if (status < 0) { @@ -447,6 +453,8 @@ int ocfs2_extend_trans(handle_t *handle, int nblocks) status = 0; bail: + + mlog_exit(status); return status; } @@ -614,9 +622,12 @@ static int __ocfs2_journal_access(handle_t *handle, BUG_ON(!handle); BUG_ON(!bh); - trace_ocfs2_journal_access( - (unsigned long long)ocfs2_metadata_cache_owner(ci), - (unsigned long long)bh->b_blocknr, type, bh->b_size); + mlog_entry("bh->b_blocknr=%llu, type=%d (\"%s\"), bh->b_size = %zu\n", + (unsigned long long)bh->b_blocknr, type, + (type == OCFS2_JOURNAL_ACCESS_CREATE) ? + "OCFS2_JOURNAL_ACCESS_CREATE" : + "OCFS2_JOURNAL_ACCESS_WRITE", + bh->b_size); /* we can safely remove this assertion after testing. */ if (!buffer_uptodate(bh)) { @@ -657,6 +668,7 @@ static int __ocfs2_journal_access(handle_t *handle, mlog(ML_ERROR, "Error %d getting %d access to buffer!\n", status, type); + mlog_exit(status); return status; } @@ -725,10 +737,13 @@ void ocfs2_journal_dirty(handle_t *handle, struct buffer_head *bh) { int status; - trace_ocfs2_journal_dirty((unsigned long long)bh->b_blocknr); + mlog_entry("(bh->b_blocknr=%llu)\n", + (unsigned long long)bh->b_blocknr); status = jbd2_journal_dirty_metadata(handle, bh); BUG_ON(status); + + mlog_exit_void(); } #define OCFS2_DEFAULT_COMMIT_INTERVAL (HZ * JBD2_DEFAULT_MAX_COMMIT_AGE) @@ -760,6 +775,8 @@ int ocfs2_journal_init(struct ocfs2_journal *journal, int *dirty) struct ocfs2_super *osb; int inode_lock = 0; + mlog_entry_void(); + BUG_ON(!journal); osb = journal->j_osb; @@ -803,9 +820,10 @@ int ocfs2_journal_init(struct ocfs2_journal *journal, int *dirty) goto done; } - trace_ocfs2_journal_init(inode->i_size, - (unsigned long long)inode->i_blocks, - OCFS2_I(inode)->ip_clusters); + mlog(0, "inode->i_size = %lld\n", inode->i_size); + mlog(0, "inode->i_blocks = %llu\n", + (unsigned long long)inode->i_blocks); + mlog(0, "inode->ip_clusters = %u\n", OCFS2_I(inode)->ip_clusters); /* call the kernels journal init function now */ j_journal = jbd2_journal_init_inode(inode); @@ -815,7 +833,8 @@ int ocfs2_journal_init(struct ocfs2_journal *journal, int *dirty) goto done; } - trace_ocfs2_journal_init_maxlen(j_journal->j_maxlen); + mlog(0, "Returned from jbd2_journal_init_inode\n"); + mlog(0, "j_journal->j_maxlen = %u\n", j_journal->j_maxlen); *dirty = (le32_to_cpu(di->id1.journal1.ij_flags) & OCFS2_JOURNAL_DIRTY_FL); @@ -840,6 +859,7 @@ int ocfs2_journal_init(struct ocfs2_journal *journal, int *dirty) } } + mlog_exit(status); return status; } @@ -862,6 +882,8 @@ static int ocfs2_journal_toggle_dirty(struct ocfs2_super *osb, struct buffer_head *bh = journal->j_bh; struct ocfs2_dinode *fe; + mlog_entry_void(); + fe = (struct ocfs2_dinode *)bh->b_data; /* The journal bh on the osb always comes from ocfs2_journal_init() @@ -884,6 +906,7 @@ static int ocfs2_journal_toggle_dirty(struct ocfs2_super *osb, if (status < 0) mlog_errno(status); + mlog_exit(status); return status; } @@ -898,6 +921,8 @@ void ocfs2_journal_shutdown(struct ocfs2_super *osb) struct inode *inode = NULL; int num_running_trans = 0; + mlog_entry_void(); + BUG_ON(!osb); journal = osb->journal; @@ -914,7 +939,10 @@ void ocfs2_journal_shutdown(struct ocfs2_super *osb) BUG(); num_running_trans = atomic_read(&(osb->journal->j_num_trans)); - trace_ocfs2_journal_shutdown(num_running_trans); + if (num_running_trans > 0) + mlog(0, "Shutting down journal: must wait on %d " + "running transactions!\n", + num_running_trans); /* Do a commit_cache here. It will flush our journal, *and* * release any locks that are still held. @@ -927,7 +955,7 @@ void ocfs2_journal_shutdown(struct ocfs2_super *osb) * completely destroy the journal. */ if (osb->commit_task) { /* Wait for the commit thread */ - trace_ocfs2_journal_shutdown_wait(osb->commit_task); + mlog(0, "Waiting for ocfs2commit to exit....\n"); kthread_stop(osb->commit_task); osb->commit_task = NULL; } @@ -970,6 +998,7 @@ void ocfs2_journal_shutdown(struct ocfs2_super *osb) done: if (inode) iput(inode); + mlog_exit_void(); } static void ocfs2_clear_journal_error(struct super_block *sb, @@ -995,6 +1024,8 @@ int ocfs2_journal_load(struct ocfs2_journal *journal, int local, int replayed) int status = 0; struct ocfs2_super *osb; + mlog_entry_void(); + BUG_ON(!journal); osb = journal->j_osb; @@ -1028,6 +1059,7 @@ int ocfs2_journal_load(struct ocfs2_journal *journal, int local, int replayed) osb->commit_task = NULL; done: + mlog_exit(status); return status; } @@ -1038,6 +1070,8 @@ int ocfs2_journal_wipe(struct ocfs2_journal *journal, int full) { int status; + mlog_entry_void(); + BUG_ON(!journal); status = jbd2_journal_wipe(journal->j_journal, full); @@ -1051,6 +1085,7 @@ int ocfs2_journal_wipe(struct ocfs2_journal *journal, int full) mlog_errno(status); bail: + mlog_exit(status); return status; } @@ -1089,6 +1124,8 @@ static int ocfs2_force_read_journal(struct inode *inode) #define CONCURRENT_JOURNAL_FILL 32ULL struct buffer_head *bhs[CONCURRENT_JOURNAL_FILL]; + mlog_entry_void(); + memset(bhs, 0, sizeof(struct buffer_head *) * CONCURRENT_JOURNAL_FILL); num_blocks = ocfs2_blocks_for_bytes(inode->i_sb, inode->i_size); @@ -1124,6 +1161,7 @@ static int ocfs2_force_read_journal(struct inode *inode) bail: for(i = 0; i < CONCURRENT_JOURNAL_FILL; i++) brelse(bhs[i]); + mlog_exit(status); return status; } @@ -1147,7 +1185,7 @@ struct ocfs2_la_recovery_item { */ void ocfs2_complete_recovery(struct work_struct *work) { - int ret = 0; + int ret; struct ocfs2_journal *journal = container_of(work, struct ocfs2_journal, j_recovery_work); struct ocfs2_super *osb = journal->j_osb; @@ -1156,8 +1194,9 @@ void ocfs2_complete_recovery(struct work_struct *work) struct ocfs2_quota_recovery *qrec; LIST_HEAD(tmp_la_list); - trace_ocfs2_complete_recovery( - (unsigned long long)OCFS2_I(journal->j_inode)->ip_blkno); + mlog_entry_void(); + + mlog(0, "completing recovery from keventd\n"); spin_lock(&journal->j_lock); list_splice_init(&journal->j_la_cleanups, &tmp_la_list); @@ -1166,18 +1205,15 @@ void ocfs2_complete_recovery(struct work_struct *work) list_for_each_entry_safe(item, n, &tmp_la_list, lri_list) { list_del_init(&item->lri_list); + mlog(0, "Complete recovery for slot %d\n", item->lri_slot); + ocfs2_wait_on_quotas(osb); la_dinode = item->lri_la_dinode; - tl_dinode = item->lri_tl_dinode; - qrec = item->lri_qrec; - - trace_ocfs2_complete_recovery_slot(item->lri_slot, - la_dinode ? le64_to_cpu(la_dinode->i_blkno) : 0, - tl_dinode ? le64_to_cpu(tl_dinode->i_blkno) : 0, - qrec); - if (la_dinode) { + mlog(0, "Clean up local alloc %llu\n", + (unsigned long long)le64_to_cpu(la_dinode->i_blkno)); + ret = ocfs2_complete_local_alloc_recovery(osb, la_dinode); if (ret < 0) @@ -1186,7 +1222,11 @@ void ocfs2_complete_recovery(struct work_struct *work) kfree(la_dinode); } + tl_dinode = item->lri_tl_dinode; if (tl_dinode) { + mlog(0, "Clean up truncate log %llu\n", + (unsigned long long)le64_to_cpu(tl_dinode->i_blkno)); + ret = ocfs2_complete_truncate_log_recovery(osb, tl_dinode); if (ret < 0) @@ -1199,7 +1239,9 @@ void ocfs2_complete_recovery(struct work_struct *work) if (ret < 0) mlog_errno(ret); + qrec = item->lri_qrec; if (qrec) { + mlog(0, "Recovering quota files"); ret = ocfs2_finish_quota_recovery(osb, qrec, item->lri_slot); if (ret < 0) @@ -1210,7 +1252,8 @@ void ocfs2_complete_recovery(struct work_struct *work) kfree(item); } - trace_ocfs2_complete_recovery_end(ret); + mlog(0, "Recovery completion\n"); + mlog_exit_void(); } /* NOTE: This function always eats your references to la_dinode and @@ -1296,6 +1339,8 @@ static int __ocfs2_recovery_thread(void *arg) int rm_quota_used = 0, i; struct ocfs2_quota_recovery *qrec; + mlog_entry_void(); + status = ocfs2_wait_on_mount(osb); if (status < 0) { goto bail; @@ -1327,12 +1372,15 @@ static int __ocfs2_recovery_thread(void *arg) * clear it until ocfs2_recover_node() has succeeded. */ node_num = rm->rm_entries[0]; spin_unlock(&osb->osb_lock); + mlog(0, "checking node %d\n", node_num); slot_num = ocfs2_node_num_to_slot(osb, node_num); - trace_ocfs2_recovery_thread_node(node_num, slot_num); if (slot_num == -ENOENT) { status = 0; + mlog(0, "no slot for this node, so no recovery" + "required.\n"); goto skip_recovery; } + mlog(0, "node %d was using slot %d\n", node_num, slot_num); /* It is a bit subtle with quota recovery. We cannot do it * immediately because we have to obtain cluster locks from @@ -1359,7 +1407,7 @@ static int __ocfs2_recovery_thread(void *arg) spin_lock(&osb->osb_lock); } spin_unlock(&osb->osb_lock); - trace_ocfs2_recovery_thread_end(status); + mlog(0, "All nodes recovered\n"); /* Refresh all journal recovery generations from disk */ status = ocfs2_check_journals_nolocks(osb); @@ -1403,6 +1451,7 @@ static int __ocfs2_recovery_thread(void *arg) if (rm_quota) kfree(rm_quota); + mlog_exit(status); /* no one is callint kthread_stop() for us so the kthread() api * requires that we call do_exit(). And it isn't exported, but * complete_and_exit() seems to be a minimal wrapper around it. */ @@ -1412,16 +1461,20 @@ static int __ocfs2_recovery_thread(void *arg) void ocfs2_recovery_thread(struct ocfs2_super *osb, int node_num) { - mutex_lock(&osb->recovery_lock); - - trace_ocfs2_recovery_thread(node_num, osb->node_num, - osb->disable_recovery, osb->recovery_thread_task, - osb->disable_recovery ? - -1 : ocfs2_recovery_map_set(osb, node_num)); + mlog_entry("(node_num=%d, osb->node_num = %d)\n", + node_num, osb->node_num); + mutex_lock(&osb->recovery_lock); if (osb->disable_recovery) goto out; + /* People waiting on recovery will wait on + * the recovery map to empty. */ + if (ocfs2_recovery_map_set(osb, node_num)) + mlog(0, "node %d already in recovery map.\n", node_num); + + mlog(0, "starting recovery thread...\n"); + if (osb->recovery_thread_task) goto out; @@ -1435,6 +1488,8 @@ void ocfs2_recovery_thread(struct ocfs2_super *osb, int node_num) out: mutex_unlock(&osb->recovery_lock); wake_up(&osb->recovery_event); + + mlog_exit_void(); } static int ocfs2_read_journal_inode(struct ocfs2_super *osb, @@ -1508,7 +1563,7 @@ static int ocfs2_replay_journal(struct ocfs2_super *osb, * If not, it needs recovery. */ if (osb->slot_recovery_generations[slot_num] != slot_reco_gen) { - trace_ocfs2_replay_journal_recovered(slot_num, + mlog(0, "Slot %u already recovered (old/new=%u/%u)\n", slot_num, osb->slot_recovery_generations[slot_num], slot_reco_gen); osb->slot_recovery_generations[slot_num] = slot_reco_gen; status = -EBUSY; @@ -1519,7 +1574,7 @@ static int ocfs2_replay_journal(struct ocfs2_super *osb, status = ocfs2_inode_lock_full(inode, &bh, 1, OCFS2_META_LOCK_RECOVERY); if (status < 0) { - trace_ocfs2_replay_journal_lock_err(status); + mlog(0, "status returned from ocfs2_inode_lock=%d\n", status); if (status != -ERESTARTSYS) mlog(ML_ERROR, "Could not lock journal!\n"); goto done; @@ -1532,7 +1587,7 @@ static int ocfs2_replay_journal(struct ocfs2_super *osb, slot_reco_gen = ocfs2_get_recovery_generation(fe); if (!(flags & OCFS2_JOURNAL_DIRTY_FL)) { - trace_ocfs2_replay_journal_skip(node_num); + mlog(0, "No recovery required for node %d\n", node_num); /* Refresh recovery generation for the slot */ osb->slot_recovery_generations[slot_num] = slot_reco_gen; goto done; @@ -1553,6 +1608,7 @@ static int ocfs2_replay_journal(struct ocfs2_super *osb, goto done; } + mlog(0, "calling journal_init_inode\n"); journal = jbd2_journal_init_inode(inode); if (journal == NULL) { mlog(ML_ERROR, "Linux journal layer error\n"); @@ -1572,6 +1628,7 @@ static int ocfs2_replay_journal(struct ocfs2_super *osb, ocfs2_clear_journal_error(osb->sb, journal, slot_num); /* wipe the journal */ + mlog(0, "flushing the journal.\n"); jbd2_journal_lock_updates(journal); status = jbd2_journal_flush(journal); jbd2_journal_unlock_updates(journal); @@ -1608,6 +1665,7 @@ static int ocfs2_replay_journal(struct ocfs2_super *osb, brelse(bh); + mlog_exit(status); return status; } @@ -1630,7 +1688,8 @@ static int ocfs2_recover_node(struct ocfs2_super *osb, struct ocfs2_dinode *la_copy = NULL; struct ocfs2_dinode *tl_copy = NULL; - trace_ocfs2_recover_node(node_num, slot_num, osb->node_num); + mlog_entry("(node_num=%d, slot_num=%d, osb->node_num = %d)\n", + node_num, slot_num, osb->node_num); /* Should not ever be called to recover ourselves -- in that * case we should've called ocfs2_journal_load instead. */ @@ -1639,7 +1698,9 @@ static int ocfs2_recover_node(struct ocfs2_super *osb, status = ocfs2_replay_journal(osb, node_num, slot_num); if (status < 0) { if (status == -EBUSY) { - trace_ocfs2_recover_node_skip(slot_num, node_num); + mlog(0, "Skipping recovery for slot %u (node %u) " + "as another node has recovered it\n", slot_num, + node_num); status = 0; goto done; } @@ -1674,6 +1735,7 @@ static int ocfs2_recover_node(struct ocfs2_super *osb, status = 0; done: + mlog_exit(status); return status; } @@ -1746,8 +1808,8 @@ int ocfs2_mark_dead_nodes(struct ocfs2_super *osb) spin_lock(&osb->osb_lock); osb->slot_recovery_generations[i] = gen; - trace_ocfs2_mark_dead_nodes(i, - osb->slot_recovery_generations[i]); + mlog(0, "Slot %u recovery generation is %u\n", i, + osb->slot_recovery_generations[i]); if (i == osb->slot_num) { spin_unlock(&osb->osb_lock); @@ -1783,6 +1845,7 @@ int ocfs2_mark_dead_nodes(struct ocfs2_super *osb) status = 0; bail: + mlog_exit(status); return status; } @@ -1821,12 +1884,11 @@ void ocfs2_queue_orphan_scan(struct ocfs2_super *osb) os = &osb->osb_orphan_scan; + mlog(0, "Begin orphan scan\n"); + if (atomic_read(&os->os_state) == ORPHAN_SCAN_INACTIVE) goto out; - trace_ocfs2_queue_orphan_scan_begin(os->os_count, os->os_seqno, - atomic_read(&os->os_state)); - status = ocfs2_orphan_scan_lock(osb, &seqno); if (status < 0) { if (status != -EAGAIN) @@ -1856,8 +1918,7 @@ void ocfs2_queue_orphan_scan(struct ocfs2_super *osb) unlock: ocfs2_orphan_scan_unlock(osb, seqno); out: - trace_ocfs2_queue_orphan_scan_end(os->os_count, os->os_seqno, - atomic_read(&os->os_state)); + mlog(0, "Orphan scan completed\n"); return; } @@ -1941,7 +2002,8 @@ static int ocfs2_orphan_filldir(void *priv, const char *name, int name_len, if (IS_ERR(iter)) return 0; - trace_ocfs2_orphan_filldir((unsigned long long)OCFS2_I(iter)->ip_blkno); + mlog(0, "queue orphan %llu\n", + (unsigned long long)OCFS2_I(iter)->ip_blkno); /* No locking is required for the next_orphan queue as there * is only ever a single process doing orphan recovery. */ OCFS2_I(iter)->ip_next_orphan = p->head; @@ -2057,7 +2119,7 @@ static int ocfs2_recover_orphans(struct ocfs2_super *osb, struct inode *iter; struct ocfs2_inode_info *oi; - trace_ocfs2_recover_orphans(slot); + mlog(0, "Recover inodes from orphan dir in slot %d\n", slot); ocfs2_mark_recovering_orphan_dir(osb, slot); ret = ocfs2_queue_orphans(osb, slot, &inode); @@ -2070,8 +2132,7 @@ static int ocfs2_recover_orphans(struct ocfs2_super *osb, while (inode) { oi = OCFS2_I(inode); - trace_ocfs2_recover_orphans_iput( - (unsigned long long)oi->ip_blkno); + mlog(0, "iput orphan %llu\n", (unsigned long long)oi->ip_blkno); iter = oi->ip_next_orphan; @@ -2109,7 +2170,6 @@ static int __ocfs2_wait_on_mount(struct ocfs2_super *osb, int quota) * MOUNTED flag, but this is set right before * dismount_volume() so we can trust it. */ if (atomic_read(&osb->vol_state) == VOLUME_DISABLED) { - trace_ocfs2_wait_on_mount(VOLUME_DISABLED); mlog(0, "mount error, exiting!\n"); return -EBUSY; } diff --git a/trunk/fs/ocfs2/localalloc.c b/trunk/fs/ocfs2/localalloc.c index 210c35237548..ec6adbf8f551 100644 --- a/trunk/fs/ocfs2/localalloc.c +++ b/trunk/fs/ocfs2/localalloc.c @@ -29,6 +29,7 @@ #include #include +#define MLOG_MASK_PREFIX ML_DISK_ALLOC #include #include "ocfs2.h" @@ -42,7 +43,6 @@ #include "suballoc.h" #include "super.h" #include "sysfile.h" -#include "ocfs2_trace.h" #include "buffer_head_io.h" @@ -201,7 +201,8 @@ void ocfs2_la_set_sizes(struct ocfs2_super *osb, int requested_mb) la_max_mb = ocfs2_clusters_to_megabytes(sb, ocfs2_local_alloc_size(sb) * 8); - trace_ocfs2_la_set_sizes(requested_mb, la_max_mb, la_default_mb); + mlog(0, "requested: %dM, max: %uM, default: %uM\n", + requested_mb, la_max_mb, la_default_mb); if (requested_mb == -1) { /* No user request - use defaults */ @@ -275,8 +276,8 @@ int ocfs2_alloc_should_use_local(struct ocfs2_super *osb, u64 bits) ret = 1; bail: - trace_ocfs2_alloc_should_use_local( - (unsigned long long)bits, osb->local_alloc_state, la_bits, ret); + mlog(0, "state=%d, bits=%llu, la_bits=%d, ret=%d\n", + osb->local_alloc_state, (unsigned long long)bits, la_bits, ret); spin_unlock(&osb->osb_lock); return ret; } @@ -290,6 +291,8 @@ int ocfs2_load_local_alloc(struct ocfs2_super *osb) struct inode *inode = NULL; struct ocfs2_local_alloc *la; + mlog_entry_void(); + if (osb->local_alloc_bits == 0) goto bail; @@ -361,10 +364,9 @@ int ocfs2_load_local_alloc(struct ocfs2_super *osb) if (inode) iput(inode); - trace_ocfs2_load_local_alloc(osb->local_alloc_bits); + mlog(0, "Local alloc window bits = %d\n", osb->local_alloc_bits); - if (status) - mlog_errno(status); + mlog_exit(status); return status; } @@ -386,6 +388,8 @@ void ocfs2_shutdown_local_alloc(struct ocfs2_super *osb) struct ocfs2_dinode *alloc_copy = NULL; struct ocfs2_dinode *alloc = NULL; + mlog_entry_void(); + cancel_delayed_work(&osb->la_enable_wq); flush_workqueue(ocfs2_wq); @@ -478,6 +482,8 @@ void ocfs2_shutdown_local_alloc(struct ocfs2_super *osb) if (alloc_copy) kfree(alloc_copy); + + mlog_exit_void(); } /* @@ -496,7 +502,7 @@ int ocfs2_begin_local_alloc_recovery(struct ocfs2_super *osb, struct inode *inode = NULL; struct ocfs2_dinode *alloc; - trace_ocfs2_begin_local_alloc_recovery(slot_num); + mlog_entry("(slot_num = %d)\n", slot_num); *alloc_copy = NULL; @@ -546,8 +552,7 @@ int ocfs2_begin_local_alloc_recovery(struct ocfs2_super *osb, iput(inode); } - if (status) - mlog_errno(status); + mlog_exit(status); return status; } @@ -565,6 +570,8 @@ int ocfs2_complete_local_alloc_recovery(struct ocfs2_super *osb, struct buffer_head *main_bm_bh = NULL; struct inode *main_bm_inode; + mlog_entry_void(); + main_bm_inode = ocfs2_get_system_file_inode(osb, GLOBAL_BITMAP_SYSTEM_INODE, OCFS2_INVALID_SLOT); @@ -613,8 +620,7 @@ int ocfs2_complete_local_alloc_recovery(struct ocfs2_super *osb, out: if (!status) ocfs2_init_steal_slots(osb); - if (status) - mlog_errno(status); + mlog_exit(status); return status; } @@ -634,6 +640,8 @@ int ocfs2_reserve_local_alloc_bits(struct ocfs2_super *osb, struct inode *local_alloc_inode; unsigned int free_bits; + mlog_entry_void(); + BUG_ON(!ac); local_alloc_inode = @@ -704,6 +712,10 @@ int ocfs2_reserve_local_alloc_bits(struct ocfs2_super *osb, goto bail; } + if (ac->ac_max_block) + mlog(0, "Calling in_range for max block %llu\n", + (unsigned long long)ac->ac_max_block); + ac->ac_inode = local_alloc_inode; /* We should never use localalloc from another slot */ ac->ac_alloc_slot = osb->slot_num; @@ -717,12 +729,10 @@ int ocfs2_reserve_local_alloc_bits(struct ocfs2_super *osb, iput(local_alloc_inode); } - trace_ocfs2_reserve_local_alloc_bits( - (unsigned long long)ac->ac_max_block, - bits_wanted, osb->slot_num, status); + mlog(0, "bits=%d, slot=%d, ret=%d\n", bits_wanted, osb->slot_num, + status); - if (status) - mlog_errno(status); + mlog_exit(status); return status; } @@ -739,6 +749,7 @@ int ocfs2_claim_local_alloc_bits(struct ocfs2_super *osb, struct ocfs2_dinode *alloc; struct ocfs2_local_alloc *la; + mlog_entry_void(); BUG_ON(ac->ac_which != OCFS2_AC_USE_LOCAL); local_alloc_inode = ac->ac_inode; @@ -777,8 +788,7 @@ int ocfs2_claim_local_alloc_bits(struct ocfs2_super *osb, ocfs2_journal_dirty(handle, osb->local_alloc_bh); bail: - if (status) - mlog_errno(status); + mlog_exit(status); return status; } @@ -789,11 +799,13 @@ static u32 ocfs2_local_alloc_count_bits(struct ocfs2_dinode *alloc) u32 count = 0; struct ocfs2_local_alloc *la = OCFS2_LOCAL_ALLOC(alloc); + mlog_entry_void(); + buffer = la->la_bitmap; for (i = 0; i < le16_to_cpu(la->la_size); i++) count += hweight8(buffer[i]); - trace_ocfs2_local_alloc_count_bits(count); + mlog_exit(count); return count; } @@ -808,7 +820,10 @@ static int ocfs2_local_alloc_find_clear_bits(struct ocfs2_super *osb, void *bitmap = NULL; struct ocfs2_reservation_map *resmap = &osb->osb_la_resmap; + mlog_entry("(numbits wanted = %u)\n", *numbits); + if (!alloc->id1.bitmap1.i_total) { + mlog(0, "No bits in my window!\n"); bitoff = -1; goto bail; } @@ -868,7 +883,8 @@ static int ocfs2_local_alloc_find_clear_bits(struct ocfs2_super *osb, } } - trace_ocfs2_local_alloc_find_clear_bits_search_bitmap(bitoff, numfound); + mlog(0, "Exiting loop, bitoff = %d, numfound = %d\n", bitoff, + numfound); if (numfound == *numbits) bitoff = startoff - numfound; @@ -879,10 +895,7 @@ static int ocfs2_local_alloc_find_clear_bits(struct ocfs2_super *osb, if (local_resv) ocfs2_resv_discard(resmap, resv); - trace_ocfs2_local_alloc_find_clear_bits(*numbits, - le32_to_cpu(alloc->id1.bitmap1.i_total), - bitoff, numfound); - + mlog_exit(bitoff); return bitoff; } @@ -890,12 +903,15 @@ static void ocfs2_clear_local_alloc(struct ocfs2_dinode *alloc) { struct ocfs2_local_alloc *la = OCFS2_LOCAL_ALLOC(alloc); int i; + mlog_entry_void(); alloc->id1.bitmap1.i_total = 0; alloc->id1.bitmap1.i_used = 0; la->la_bm_off = 0; for(i = 0; i < le16_to_cpu(la->la_size); i++) la->la_bitmap[i] = 0; + + mlog_exit_void(); } #if 0 @@ -936,16 +952,18 @@ static int ocfs2_sync_local_to_main(struct ocfs2_super *osb, void *bitmap; struct ocfs2_local_alloc *la = OCFS2_LOCAL_ALLOC(alloc); - trace_ocfs2_sync_local_to_main( - le32_to_cpu(alloc->id1.bitmap1.i_total), - le32_to_cpu(alloc->id1.bitmap1.i_used)); + mlog_entry("total = %u, used = %u\n", + le32_to_cpu(alloc->id1.bitmap1.i_total), + le32_to_cpu(alloc->id1.bitmap1.i_used)); if (!alloc->id1.bitmap1.i_total) { + mlog(0, "nothing to sync!\n"); goto bail; } if (le32_to_cpu(alloc->id1.bitmap1.i_used) == le32_to_cpu(alloc->id1.bitmap1.i_total)) { + mlog(0, "all bits were taken!\n"); goto bail; } @@ -967,7 +985,8 @@ static int ocfs2_sync_local_to_main(struct ocfs2_super *osb, ocfs2_clusters_to_blocks(osb->sb, start - count); - trace_ocfs2_sync_local_to_main_free( + mlog(0, "freeing %u bits starting at local alloc bit " + "%u (la_start_blk = %llu, blkno = %llu)\n", count, start - count, (unsigned long long)la_start_blk, (unsigned long long)blkno); @@ -988,8 +1007,7 @@ static int ocfs2_sync_local_to_main(struct ocfs2_super *osb, } bail: - if (status) - mlog_errno(status); + mlog_exit(status); return status; } @@ -1114,8 +1132,7 @@ static int ocfs2_local_alloc_reserve_for_window(struct ocfs2_super *osb, *ac = NULL; } - if (status) - mlog_errno(status); + mlog_exit(status); return status; } @@ -1131,12 +1148,17 @@ static int ocfs2_local_alloc_new_window(struct ocfs2_super *osb, struct ocfs2_dinode *alloc = NULL; struct ocfs2_local_alloc *la; + mlog_entry_void(); + alloc = (struct ocfs2_dinode *) osb->local_alloc_bh->b_data; la = OCFS2_LOCAL_ALLOC(alloc); - trace_ocfs2_local_alloc_new_window( - le32_to_cpu(alloc->id1.bitmap1.i_total), - osb->local_alloc_bits); + if (alloc->id1.bitmap1.i_total) + mlog(0, "asking me to alloc a new window over a non-empty " + "one\n"); + + mlog(0, "Allocating %u clusters for a new window.\n", + osb->local_alloc_bits); /* Instruct the allocation code to try the most recently used * cluster group. We'll re-record the group used this pass @@ -1198,13 +1220,13 @@ static int ocfs2_local_alloc_new_window(struct ocfs2_super *osb, ocfs2_resmap_restart(&osb->osb_la_resmap, cluster_count, OCFS2_LOCAL_ALLOC(alloc)->la_bitmap); - trace_ocfs2_local_alloc_new_window_result( - OCFS2_LOCAL_ALLOC(alloc)->la_bm_off, - le32_to_cpu(alloc->id1.bitmap1.i_total)); + mlog(0, "New window allocated:\n"); + mlog(0, "window la_bm_off = %u\n", + OCFS2_LOCAL_ALLOC(alloc)->la_bm_off); + mlog(0, "window bits = %u\n", le32_to_cpu(alloc->id1.bitmap1.i_total)); bail: - if (status) - mlog_errno(status); + mlog_exit(status); return status; } @@ -1221,6 +1243,8 @@ static int ocfs2_local_alloc_slide_window(struct ocfs2_super *osb, struct ocfs2_dinode *alloc_copy = NULL; struct ocfs2_alloc_context *ac = NULL; + mlog_entry_void(); + ocfs2_recalc_la_window(osb, OCFS2_LA_EVENT_SLIDE); /* This will lock the main bitmap for us. */ @@ -1300,8 +1324,7 @@ static int ocfs2_local_alloc_slide_window(struct ocfs2_super *osb, if (ac) ocfs2_free_alloc_context(ac); - if (status) - mlog_errno(status); + mlog_exit(status); return status; } diff --git a/trunk/fs/ocfs2/locks.c b/trunk/fs/ocfs2/locks.c index e57c804069ea..b5cb3ede9408 100644 --- a/trunk/fs/ocfs2/locks.c +++ b/trunk/fs/ocfs2/locks.c @@ -26,6 +26,7 @@ #include #include +#define MLOG_MASK_PREFIX ML_INODE #include #include "ocfs2.h" diff --git a/trunk/fs/ocfs2/mmap.c b/trunk/fs/ocfs2/mmap.c index 3e9393ca39eb..7e32db9c2c99 100644 --- a/trunk/fs/ocfs2/mmap.c +++ b/trunk/fs/ocfs2/mmap.c @@ -31,6 +31,7 @@ #include #include +#define MLOG_MASK_PREFIX ML_FILE_IO #include #include "ocfs2.h" @@ -41,7 +42,6 @@ #include "inode.h" #include "mmap.h" #include "super.h" -#include "ocfs2_trace.h" static int ocfs2_fault(struct vm_area_struct *area, struct vm_fault *vmf) @@ -49,12 +49,13 @@ static int ocfs2_fault(struct vm_area_struct *area, struct vm_fault *vmf) sigset_t oldset; int ret; + mlog_entry("(area=%p, page offset=%lu)\n", area, vmf->pgoff); + ocfs2_block_signals(&oldset); ret = filemap_fault(area, vmf); ocfs2_unblock_signals(&oldset); - trace_ocfs2_fault(OCFS2_I(area->vm_file->f_mapping->host)->ip_blkno, - area, vmf->page, vmf->pgoff); + mlog_exit_ptr(vmf->page); return ret; } diff --git a/trunk/fs/ocfs2/namei.c b/trunk/fs/ocfs2/namei.c index 28f2cc1080d8..d6c25d76b537 100644 --- a/trunk/fs/ocfs2/namei.c +++ b/trunk/fs/ocfs2/namei.c @@ -42,6 +42,7 @@ #include #include +#define MLOG_MASK_PREFIX ML_NAMEI #include #include "ocfs2.h" @@ -62,7 +63,6 @@ #include "uptodate.h" #include "xattr.h" #include "acl.h" -#include "ocfs2_trace.h" #include "buffer_head_io.h" @@ -106,15 +106,17 @@ static struct dentry *ocfs2_lookup(struct inode *dir, struct dentry *dentry, struct dentry *ret; struct ocfs2_inode_info *oi; - trace_ocfs2_lookup(dir, dentry, dentry->d_name.len, - dentry->d_name.name, - (unsigned long long)OCFS2_I(dir)->ip_blkno, 0); + mlog_entry("(0x%p, 0x%p, '%.*s')\n", dir, dentry, + dentry->d_name.len, dentry->d_name.name); if (dentry->d_name.len > OCFS2_MAX_FILENAME_LEN) { ret = ERR_PTR(-ENAMETOOLONG); goto bail; } + mlog(0, "find name %.*s in directory %llu\n", dentry->d_name.len, + dentry->d_name.name, (unsigned long long)OCFS2_I(dir)->ip_blkno); + status = ocfs2_inode_lock_nested(dir, NULL, 0, OI_LS_PARENT); if (status < 0) { if (status != -ENOENT) @@ -180,7 +182,7 @@ static struct dentry *ocfs2_lookup(struct inode *dir, struct dentry *dentry, bail: - trace_ocfs2_lookup_ret(ret); + mlog_exit_ptr(ret); return ret; } @@ -233,9 +235,9 @@ static int ocfs2_mknod(struct inode *dir, sigset_t oldset; int did_block_signals = 0; - trace_ocfs2_mknod(dir, dentry, dentry->d_name.len, dentry->d_name.name, - (unsigned long long)OCFS2_I(dir)->ip_blkno, - (unsigned long)dev, mode); + mlog_entry("(0x%p, 0x%p, %d, %lu, '%.*s')\n", dir, dentry, mode, + (unsigned long)dev, dentry->d_name.len, + dentry->d_name.name); dquot_initialize(dir); @@ -352,6 +354,10 @@ static int ocfs2_mknod(struct inode *dir, goto leave; did_quota_inode = 1; + mlog_entry("(0x%p, 0x%p, %d, %lu, '%.*s')\n", dir, dentry, + inode->i_mode, (unsigned long)dev, dentry->d_name.len, + dentry->d_name.name); + /* do the real work now. */ status = ocfs2_mknod_locked(osb, dir, inode, dev, &new_fe_bh, parent_fe_bh, handle, @@ -430,6 +436,9 @@ static int ocfs2_mknod(struct inode *dir, if (did_block_signals) ocfs2_unblock_signals(&oldset); + if (status == -ENOSPC) + mlog(0, "Disk is full\n"); + brelse(new_fe_bh); brelse(parent_fe_bh); kfree(si.name); @@ -457,8 +466,7 @@ static int ocfs2_mknod(struct inode *dir, iput(inode); } - if (status) - mlog_errno(status); + mlog_exit(status); return status; } @@ -569,8 +577,7 @@ static int __ocfs2_mknod_locked(struct inode *dir, } } - if (status) - mlog_errno(status); + mlog_exit(status); return status; } @@ -608,11 +615,10 @@ static int ocfs2_mkdir(struct inode *dir, { int ret; - trace_ocfs2_mkdir(dir, dentry, dentry->d_name.len, dentry->d_name.name, - OCFS2_I(dir)->ip_blkno, mode); + mlog_entry("(0x%p, 0x%p, %d, '%.*s')\n", dir, dentry, mode, + dentry->d_name.len, dentry->d_name.name); ret = ocfs2_mknod(dir, dentry, mode | S_IFDIR, 0); - if (ret) - mlog_errno(ret); + mlog_exit(ret); return ret; } @@ -624,11 +630,10 @@ static int ocfs2_create(struct inode *dir, { int ret; - trace_ocfs2_create(dir, dentry, dentry->d_name.len, dentry->d_name.name, - (unsigned long long)OCFS2_I(dir)->ip_blkno, mode); + mlog_entry("(0x%p, 0x%p, %d, '%.*s')\n", dir, dentry, mode, + dentry->d_name.len, dentry->d_name.name); ret = ocfs2_mknod(dir, dentry, mode | S_IFREG, 0); - if (ret) - mlog_errno(ret); + mlog_exit(ret); return ret; } @@ -647,9 +652,9 @@ static int ocfs2_link(struct dentry *old_dentry, struct ocfs2_dir_lookup_result lookup = { NULL, }; sigset_t oldset; - trace_ocfs2_link((unsigned long long)OCFS2_I(inode)->ip_blkno, - old_dentry->d_name.len, old_dentry->d_name.name, - dentry->d_name.len, dentry->d_name.name); + mlog_entry("(inode=%lu, old='%.*s' new='%.*s')\n", inode->i_ino, + old_dentry->d_name.len, old_dentry->d_name.name, + dentry->d_name.len, dentry->d_name.name); if (S_ISDIR(inode->i_mode)) return -EPERM; @@ -752,8 +757,7 @@ static int ocfs2_link(struct dentry *old_dentry, ocfs2_free_dir_lookup_result(&lookup); - if (err) - mlog_errno(err); + mlog_exit(err); return err; } @@ -805,17 +809,19 @@ static int ocfs2_unlink(struct inode *dir, struct ocfs2_dir_lookup_result lookup = { NULL, }; struct ocfs2_dir_lookup_result orphan_insert = { NULL, }; - trace_ocfs2_unlink(dir, dentry, dentry->d_name.len, - dentry->d_name.name, - (unsigned long long)OCFS2_I(dir)->ip_blkno, - (unsigned long long)OCFS2_I(inode)->ip_blkno); + mlog_entry("(0x%p, 0x%p, '%.*s')\n", dir, dentry, + dentry->d_name.len, dentry->d_name.name); dquot_initialize(dir); BUG_ON(dentry->d_parent->d_inode != dir); - if (inode == osb->root_inode) + mlog(0, "ino = %llu\n", (unsigned long long)OCFS2_I(inode)->ip_blkno); + + if (inode == osb->root_inode) { + mlog(0, "Cannot delete the root directory\n"); return -EPERM; + } status = ocfs2_inode_lock_nested(dir, &parent_node_bh, 1, OI_LS_PARENT); @@ -837,10 +843,9 @@ static int ocfs2_unlink(struct inode *dir, if (OCFS2_I(inode)->ip_blkno != blkno) { status = -ENOENT; - trace_ocfs2_unlink_noent( - (unsigned long long)OCFS2_I(inode)->ip_blkno, - (unsigned long long)blkno, - OCFS2_I(inode)->ip_flags); + mlog(0, "ip_blkno %llu != dirent blkno %llu ip_flags = %x\n", + (unsigned long long)OCFS2_I(inode)->ip_blkno, + (unsigned long long)blkno, OCFS2_I(inode)->ip_flags); goto leave; } @@ -949,8 +954,7 @@ static int ocfs2_unlink(struct inode *dir, ocfs2_free_dir_lookup_result(&orphan_insert); ocfs2_free_dir_lookup_result(&lookup); - if (status) - mlog_errno(status); + mlog_exit(status); return status; } @@ -971,8 +975,9 @@ static int ocfs2_double_lock(struct ocfs2_super *osb, struct buffer_head **tmpbh; struct inode *tmpinode; - trace_ocfs2_double_lock((unsigned long long)oi1->ip_blkno, - (unsigned long long)oi2->ip_blkno); + mlog_entry("(inode1 = %llu, inode2 = %llu)\n", + (unsigned long long)oi1->ip_blkno, + (unsigned long long)oi2->ip_blkno); if (*bh1) *bh1 = NULL; @@ -983,6 +988,7 @@ static int ocfs2_double_lock(struct ocfs2_super *osb, if (oi1->ip_blkno != oi2->ip_blkno) { if (oi1->ip_blkno < oi2->ip_blkno) { /* switch id1 and id2 around */ + mlog(0, "switching them around...\n"); tmpbh = bh2; bh2 = bh1; bh1 = tmpbh; @@ -1018,13 +1024,8 @@ static int ocfs2_double_lock(struct ocfs2_super *osb, mlog_errno(status); } - trace_ocfs2_double_lock_end( - (unsigned long long)OCFS2_I(inode1)->ip_blkno, - (unsigned long long)OCFS2_I(inode2)->ip_blkno); - bail: - if (status) - mlog_errno(status); + mlog_exit(status); return status; } @@ -1066,9 +1067,10 @@ static int ocfs2_rename(struct inode *old_dir, /* At some point it might be nice to break this function up a * bit. */ - trace_ocfs2_rename(old_dir, old_dentry, new_dir, new_dentry, - old_dentry->d_name.len, old_dentry->d_name.name, - new_dentry->d_name.len, new_dentry->d_name.name); + mlog_entry("(0x%p, 0x%p, 0x%p, 0x%p, from='%.*s' to='%.*s')\n", + old_dir, old_dentry, new_dir, new_dentry, + old_dentry->d_name.len, old_dentry->d_name.name, + new_dentry->d_name.len, new_dentry->d_name.name); dquot_initialize(old_dir); dquot_initialize(new_dir); @@ -1225,15 +1227,16 @@ static int ocfs2_rename(struct inode *old_dir, if (!new_inode) { status = -EACCES; - trace_ocfs2_rename_target_exists(new_dentry->d_name.len, - new_dentry->d_name.name); + mlog(0, "We found an inode for name %.*s but VFS " + "didn't give us one.\n", new_dentry->d_name.len, + new_dentry->d_name.name); goto bail; } if (OCFS2_I(new_inode)->ip_blkno != newfe_blkno) { status = -EACCES; - trace_ocfs2_rename_disagree( + mlog(0, "Inode %llu and dir %llu disagree. flags = %x\n", (unsigned long long)OCFS2_I(new_inode)->ip_blkno, (unsigned long long)newfe_blkno, OCFS2_I(new_inode)->ip_flags); @@ -1256,7 +1259,8 @@ static int ocfs2_rename(struct inode *old_dir, newfe = (struct ocfs2_dinode *) newfe_bh->b_data; - trace_ocfs2_rename_over_existing( + mlog(0, "aha rename over existing... new_blkno=%llu " + "newfebh=%p bhblocknr=%llu\n", (unsigned long long)newfe_blkno, newfe_bh, newfe_bh ? (unsigned long long)newfe_bh->b_blocknr : 0ULL); @@ -1472,8 +1476,7 @@ static int ocfs2_rename(struct inode *old_dir, brelse(old_dir_bh); brelse(new_dir_bh); - if (status) - mlog_errno(status); + mlog_exit(status); return status; } @@ -1498,8 +1501,9 @@ static int ocfs2_create_symlink_data(struct ocfs2_super *osb, * write i_size + 1 bytes. */ blocks = (bytes_left + sb->s_blocksize - 1) >> sb->s_blocksize_bits; - trace_ocfs2_create_symlink_data((unsigned long long)inode->i_blocks, - i_size_read(inode), blocks); + mlog_entry("i_blocks = %llu, i_size = %llu, blocks = %d\n", + (unsigned long long)inode->i_blocks, + i_size_read(inode), blocks); /* Sanity check -- make sure we're going to fit. */ if (bytes_left > @@ -1575,8 +1579,7 @@ static int ocfs2_create_symlink_data(struct ocfs2_super *osb, kfree(bhs); } - if (status) - mlog_errno(status); + mlog_exit(status); return status; } @@ -1607,8 +1610,8 @@ static int ocfs2_symlink(struct inode *dir, sigset_t oldset; int did_block_signals = 0; - trace_ocfs2_symlink_begin(dir, dentry, symname, - dentry->d_name.len, dentry->d_name.name); + mlog_entry("(0x%p, 0x%p, symname='%s' actual='%.*s')\n", dir, + dentry, symname, dentry->d_name.len, dentry->d_name.name); dquot_initialize(dir); @@ -1710,10 +1713,9 @@ static int ocfs2_symlink(struct inode *dir, goto bail; did_quota_inode = 1; - trace_ocfs2_symlink_create(dir, dentry, dentry->d_name.len, - dentry->d_name.name, - (unsigned long long)OCFS2_I(dir)->ip_blkno, - inode->i_mode); + mlog_entry("(0x%p, 0x%p, %d, '%.*s')\n", dir, dentry, + inode->i_mode, dentry->d_name.len, + dentry->d_name.name); status = ocfs2_mknod_locked(osb, dir, inode, 0, &new_fe_bh, parent_fe_bh, handle, @@ -1833,8 +1835,7 @@ static int ocfs2_symlink(struct inode *dir, iput(inode); } - if (status) - mlog_errno(status); + mlog_exit(status); return status; } @@ -1843,6 +1844,8 @@ static int ocfs2_blkno_stringify(u64 blkno, char *name) { int status, namelen; + mlog_entry_void(); + namelen = snprintf(name, OCFS2_ORPHAN_NAMELEN + 1, "%016llx", (long long)blkno); if (namelen <= 0) { @@ -1859,12 +1862,12 @@ static int ocfs2_blkno_stringify(u64 blkno, char *name) goto bail; } - trace_ocfs2_blkno_stringify(blkno, name, namelen); + mlog(0, "built filename '%s' for orphan dir (len=%d)\n", name, + namelen); status = 0; bail: - if (status < 0) - mlog_errno(status); + mlog_exit(status); return status; } @@ -1977,8 +1980,7 @@ static int ocfs2_prepare_orphan_dir(struct ocfs2_super *osb, iput(orphan_dir_inode); } - if (ret) - mlog_errno(ret); + mlog_exit(ret); return ret; } @@ -1995,8 +1997,7 @@ static int ocfs2_orphan_add(struct ocfs2_super *osb, struct ocfs2_dinode *orphan_fe; struct ocfs2_dinode *fe = (struct ocfs2_dinode *) fe_bh->b_data; - trace_ocfs2_orphan_add_begin( - (unsigned long long)OCFS2_I(inode)->ip_blkno); + mlog_entry("(inode->i_ino = %lu)\n", inode->i_ino); status = ocfs2_read_inode_block(orphan_dir_inode, &orphan_dir_bh); if (status < 0) { @@ -2055,14 +2056,13 @@ static int ocfs2_orphan_add(struct ocfs2_super *osb, ocfs2_journal_dirty(handle, fe_bh); - trace_ocfs2_orphan_add_end((unsigned long long)OCFS2_I(inode)->ip_blkno, - osb->slot_num); + mlog(0, "Inode %llu orphaned in slot %d\n", + (unsigned long long)OCFS2_I(inode)->ip_blkno, osb->slot_num); leave: brelse(orphan_dir_bh); - if (status) - mlog_errno(status); + mlog_exit(status); return status; } @@ -2078,15 +2078,17 @@ int ocfs2_orphan_del(struct ocfs2_super *osb, int status = 0; struct ocfs2_dir_lookup_result lookup = { NULL, }; + mlog_entry_void(); + status = ocfs2_blkno_stringify(OCFS2_I(inode)->ip_blkno, name); if (status < 0) { mlog_errno(status); goto leave; } - trace_ocfs2_orphan_del( - (unsigned long long)OCFS2_I(orphan_dir_inode)->ip_blkno, - name, OCFS2_ORPHAN_NAMELEN); + mlog(0, "removing '%s' from orphan dir %llu (namelen=%d)\n", + name, (unsigned long long)OCFS2_I(orphan_dir_inode)->ip_blkno, + OCFS2_ORPHAN_NAMELEN); /* find it's spot in the orphan directory */ status = ocfs2_find_entry(name, OCFS2_ORPHAN_NAMELEN, orphan_dir_inode, @@ -2122,8 +2124,7 @@ int ocfs2_orphan_del(struct ocfs2_super *osb, leave: ocfs2_free_dir_lookup_result(&lookup); - if (status) - mlog_errno(status); + mlog_exit(status); return status; } @@ -2320,6 +2321,9 @@ int ocfs2_create_inode_in_orphan(struct inode *dir, iput(orphan_dir); } + if (status == -ENOSPC) + mlog(0, "Disk is full\n"); + if ((status < 0) && inode) { clear_nlink(inode); iput(inode); @@ -2354,10 +2358,8 @@ int ocfs2_mv_orphaned_inode_to_new(struct inode *dir, struct buffer_head *di_bh = NULL; struct ocfs2_dir_lookup_result lookup = { NULL, }; - trace_ocfs2_mv_orphaned_inode_to_new(dir, dentry, - dentry->d_name.len, dentry->d_name.name, - (unsigned long long)OCFS2_I(dir)->ip_blkno, - (unsigned long long)OCFS2_I(inode)->ip_blkno); + mlog_entry("(0x%p, 0x%p, %.*s')\n", dir, dentry, + dentry->d_name.len, dentry->d_name.name); status = ocfs2_inode_lock(dir, &parent_di_bh, 1); if (status < 0) { @@ -2474,8 +2476,7 @@ int ocfs2_mv_orphaned_inode_to_new(struct inode *dir, ocfs2_free_dir_lookup_result(&lookup); - if (status) - mlog_errno(status); + mlog_exit(status); return status; } diff --git a/trunk/fs/ocfs2/ocfs2.h b/trunk/fs/ocfs2/ocfs2.h index 409285854f64..1a97ba1ec3fc 100644 --- a/trunk/fs/ocfs2/ocfs2.h +++ b/trunk/fs/ocfs2/ocfs2.h @@ -147,17 +147,6 @@ struct ocfs2_lock_res_ops; typedef void (*ocfs2_lock_callback)(int status, unsigned long data); -#ifdef CONFIG_OCFS2_FS_STATS -struct ocfs2_lock_stats { - u64 ls_total; /* Total wait in NSEC */ - u32 ls_gets; /* Num acquires */ - u32 ls_fail; /* Num failed acquires */ - - /* Storing max wait in usecs saves 24 bytes per inode */ - u32 ls_max; /* Max wait in USEC */ -}; -#endif - struct ocfs2_lock_res { void *l_priv; struct ocfs2_lock_res_ops *l_ops; @@ -193,9 +182,15 @@ struct ocfs2_lock_res { struct list_head l_debug_list; #ifdef CONFIG_OCFS2_FS_STATS - struct ocfs2_lock_stats l_lock_prmode; /* PR mode stats */ - u32 l_lock_refresh; /* Disk refreshes */ - struct ocfs2_lock_stats l_lock_exmode; /* EX mode stats */ + unsigned long long l_lock_num_prmode; /* PR acquires */ + unsigned long long l_lock_num_exmode; /* EX acquires */ + unsigned int l_lock_num_prmode_failed; /* Failed PR gets */ + unsigned int l_lock_num_exmode_failed; /* Failed EX gets */ + unsigned long long l_lock_total_prmode; /* Tot wait for PR */ + unsigned long long l_lock_total_exmode; /* Tot wait for EX */ + unsigned int l_lock_max_prmode; /* Max wait for PR */ + unsigned int l_lock_max_exmode; /* Max wait for EX */ + unsigned int l_lock_refresh; /* Disk refreshes */ #endif #ifdef CONFIG_DEBUG_LOCK_ALLOC struct lockdep_map l_lockdep_map; diff --git a/trunk/fs/ocfs2/ocfs2_trace.h b/trunk/fs/ocfs2/ocfs2_trace.h deleted file mode 100644 index a1dae5bb54ac..000000000000 --- a/trunk/fs/ocfs2/ocfs2_trace.h +++ /dev/null @@ -1,2739 +0,0 @@ -#undef TRACE_SYSTEM -#define TRACE_SYSTEM ocfs2 - -#if !defined(_TRACE_OCFS2_H) || defined(TRACE_HEADER_MULTI_READ) -#define _TRACE_OCFS2_H - -#include - -DECLARE_EVENT_CLASS(ocfs2__int, - TP_PROTO(int num), - TP_ARGS(num), - TP_STRUCT__entry( - __field(int, num) - ), - TP_fast_assign( - __entry->num = num; - ), - TP_printk("%d", __entry->num) -); - -#define DEFINE_OCFS2_INT_EVENT(name) \ -DEFINE_EVENT(ocfs2__int, name, \ - TP_PROTO(int num), \ - TP_ARGS(num)) - -DECLARE_EVENT_CLASS(ocfs2__uint, - TP_PROTO(unsigned int num), - TP_ARGS(num), - TP_STRUCT__entry( - __field( unsigned int, num ) - ), - TP_fast_assign( - __entry->num = num; - ), - TP_printk("%u", __entry->num) -); - -#define DEFINE_OCFS2_UINT_EVENT(name) \ -DEFINE_EVENT(ocfs2__uint, name, \ - TP_PROTO(unsigned int num), \ - TP_ARGS(num)) - -DECLARE_EVENT_CLASS(ocfs2__ull, - TP_PROTO(unsigned long long blkno), - TP_ARGS(blkno), - TP_STRUCT__entry( - __field(unsigned long long, blkno) - ), - TP_fast_assign( - __entry->blkno = blkno; - ), - TP_printk("%llu", __entry->blkno) -); - -#define DEFINE_OCFS2_ULL_EVENT(name) \ -DEFINE_EVENT(ocfs2__ull, name, \ - TP_PROTO(unsigned long long num), \ - TP_ARGS(num)) - -DECLARE_EVENT_CLASS(ocfs2__pointer, - TP_PROTO(void *pointer), - TP_ARGS(pointer), - TP_STRUCT__entry( - __field(void *, pointer) - ), - TP_fast_assign( - __entry->pointer = pointer; - ), - TP_printk("%p", __entry->pointer) -); - -#define DEFINE_OCFS2_POINTER_EVENT(name) \ -DEFINE_EVENT(ocfs2__pointer, name, \ - TP_PROTO(void *pointer), \ - TP_ARGS(pointer)) - -DECLARE_EVENT_CLASS(ocfs2__string, - TP_PROTO(const char *name), - TP_ARGS(name), - TP_STRUCT__entry( - __string(name,name) - ), - TP_fast_assign( - __assign_str(name, name); - ), - TP_printk("%s", __get_str(name)) -); - -#define DEFINE_OCFS2_STRING_EVENT(name) \ -DEFINE_EVENT(ocfs2__string, name, \ - TP_PROTO(const char *name), \ - TP_ARGS(name)) - -DECLARE_EVENT_CLASS(ocfs2__int_int, - TP_PROTO(int value1, int value2), - TP_ARGS(value1, value2), - TP_STRUCT__entry( - __field(int, value1) - __field(int, value2) - ), - TP_fast_assign( - __entry->value1 = value1; - __entry->value2 = value2; - ), - TP_printk("%d %d", __entry->value1, __entry->value2) -); - -#define DEFINE_OCFS2_INT_INT_EVENT(name) \ -DEFINE_EVENT(ocfs2__int_int, name, \ - TP_PROTO(int val1, int val2), \ - TP_ARGS(val1, val2)) - -DECLARE_EVENT_CLASS(ocfs2__uint_int, - TP_PROTO(unsigned int value1, int value2), - TP_ARGS(value1, value2), - TP_STRUCT__entry( - __field(unsigned int, value1) - __field(int, value2) - ), - TP_fast_assign( - __entry->value1 = value1; - __entry->value2 = value2; - ), - TP_printk("%u %d", __entry->value1, __entry->value2) -); - -#define DEFINE_OCFS2_UINT_INT_EVENT(name) \ -DEFINE_EVENT(ocfs2__uint_int, name, \ - TP_PROTO(unsigned int val1, int val2), \ - TP_ARGS(val1, val2)) - -DECLARE_EVENT_CLASS(ocfs2__uint_uint, - TP_PROTO(unsigned int value1, unsigned int value2), - TP_ARGS(value1, value2), - TP_STRUCT__entry( - __field(unsigned int, value1) - __field(unsigned int, value2) - ), - TP_fast_assign( - __entry->value1 = value1; - __entry->value2 = value2; - ), - TP_printk("%u %u", __entry->value1, __entry->value2) -); - -#define DEFINE_OCFS2_UINT_UINT_EVENT(name) \ -DEFINE_EVENT(ocfs2__uint_uint, name, \ - TP_PROTO(unsigned int val1, unsigned int val2), \ - TP_ARGS(val1, val2)) - -DECLARE_EVENT_CLASS(ocfs2__ull_uint, - TP_PROTO(unsigned long long value1, unsigned int value2), - TP_ARGS(value1, value2), - TP_STRUCT__entry( - __field(unsigned long long, value1) - __field(unsigned int, value2) - ), - TP_fast_assign( - __entry->value1 = value1; - __entry->value2 = value2; - ), - TP_printk("%llu %u", __entry->value1, __entry->value2) -); - -#define DEFINE_OCFS2_ULL_UINT_EVENT(name) \ -DEFINE_EVENT(ocfs2__ull_uint, name, \ - TP_PROTO(unsigned long long val1, unsigned int val2), \ - TP_ARGS(val1, val2)) - -DECLARE_EVENT_CLASS(ocfs2__ull_int, - TP_PROTO(unsigned long long value1, int value2), - TP_ARGS(value1, value2), - TP_STRUCT__entry( - __field(unsigned long long, value1) - __field(int, value2) - ), - TP_fast_assign( - __entry->value1 = value1; - __entry->value2 = value2; - ), - TP_printk("%llu %d", __entry->value1, __entry->value2) -); - -#define DEFINE_OCFS2_ULL_INT_EVENT(name) \ -DEFINE_EVENT(ocfs2__ull_int, name, \ - TP_PROTO(unsigned long long val1, int val2), \ - TP_ARGS(val1, val2)) - -DECLARE_EVENT_CLASS(ocfs2__ull_ull, - TP_PROTO(unsigned long long value1, unsigned long long value2), - TP_ARGS(value1, value2), - TP_STRUCT__entry( - __field(unsigned long long, value1) - __field(unsigned long long, value2) - ), - TP_fast_assign( - __entry->value1 = value1; - __entry->value2 = value2; - ), - TP_printk("%llu %llu", __entry->value1, __entry->value2) -); - -#define DEFINE_OCFS2_ULL_ULL_EVENT(name) \ -DEFINE_EVENT(ocfs2__ull_ull, name, \ - TP_PROTO(unsigned long long val1, unsigned long long val2), \ - TP_ARGS(val1, val2)) - -DECLARE_EVENT_CLASS(ocfs2__ull_ull_uint, - TP_PROTO(unsigned long long value1, - unsigned long long value2, unsigned int value3), - TP_ARGS(value1, value2, value3), - TP_STRUCT__entry( - __field(unsigned long long, value1) - __field(unsigned long long, value2) - __field(unsigned int, value3) - ), - TP_fast_assign( - __entry->value1 = value1; - __entry->value2 = value2; - __entry->value3 = value3; - ), - TP_printk("%llu %llu %u", - __entry->value1, __entry->value2, __entry->value3) -); - -#define DEFINE_OCFS2_ULL_ULL_UINT_EVENT(name) \ -DEFINE_EVENT(ocfs2__ull_ull_uint, name, \ - TP_PROTO(unsigned long long val1, \ - unsigned long long val2, unsigned int val3), \ - TP_ARGS(val1, val2, val3)) - -DECLARE_EVENT_CLASS(ocfs2__ull_uint_uint, - TP_PROTO(unsigned long long value1, - unsigned int value2, unsigned int value3), - TP_ARGS(value1, value2, value3), - TP_STRUCT__entry( - __field(unsigned long long, value1) - __field(unsigned int, value2) - __field(unsigned int, value3) - ), - TP_fast_assign( - __entry->value1 = value1; - __entry->value2 = value2; - __entry->value3 = value3; - ), - TP_printk("%llu %u %u", __entry->value1, - __entry->value2, __entry->value3) -); - -#define DEFINE_OCFS2_ULL_UINT_UINT_EVENT(name) \ -DEFINE_EVENT(ocfs2__ull_uint_uint, name, \ - TP_PROTO(unsigned long long val1, \ - unsigned int val2, unsigned int val3), \ - TP_ARGS(val1, val2, val3)) - -DECLARE_EVENT_CLASS(ocfs2__uint_uint_uint, - TP_PROTO(unsigned int value1, unsigned int value2, - unsigned int value3), - TP_ARGS(value1, value2, value3), - TP_STRUCT__entry( - __field( unsigned int, value1 ) - __field( unsigned int, value2 ) - __field( unsigned int, value3 ) - ), - TP_fast_assign( - __entry->value1 = value1; - __entry->value2 = value2; - __entry->value3 = value3; - ), - TP_printk("%u %u %u", __entry->value1, __entry->value2, __entry->value3) -); - -#define DEFINE_OCFS2_UINT_UINT_UINT_EVENT(name) \ -DEFINE_EVENT(ocfs2__uint_uint_uint, name, \ - TP_PROTO(unsigned int value1, unsigned int value2, \ - unsigned int value3), \ - TP_ARGS(value1, value2, value3)) - -DECLARE_EVENT_CLASS(ocfs2__ull_ull_ull, - TP_PROTO(unsigned long long value1, - unsigned long long value2, unsigned long long value3), - TP_ARGS(value1, value2, value3), - TP_STRUCT__entry( - __field(unsigned long long, value1) - __field(unsigned long long, value2) - __field(unsigned long long, value3) - ), - TP_fast_assign( - __entry->value1 = value1; - __entry->value2 = value2; - __entry->value3 = value3; - ), - TP_printk("%llu %llu %llu", - __entry->value1, __entry->value2, __entry->value3) -); - -#define DEFINE_OCFS2_ULL_ULL_ULL_EVENT(name) \ -DEFINE_EVENT(ocfs2__ull_ull_ull, name, \ - TP_PROTO(unsigned long long value1, unsigned long long value2, \ - unsigned long long value3), \ - TP_ARGS(value1, value2, value3)) - -DECLARE_EVENT_CLASS(ocfs2__ull_int_int_int, - TP_PROTO(unsigned long long ull, int value1, int value2, int value3), - TP_ARGS(ull, value1, value2, value3), - TP_STRUCT__entry( - __field( unsigned long long, ull ) - __field( int, value1 ) - __field( int, value2 ) - __field( int, value3 ) - ), - TP_fast_assign( - __entry->ull = ull; - __entry->value1 = value1; - __entry->value2 = value2; - __entry->value3 = value3; - ), - TP_printk("%llu %d %d %d", - __entry->ull, __entry->value1, - __entry->value2, __entry->value3) -); - -#define DEFINE_OCFS2_ULL_INT_INT_INT_EVENT(name) \ -DEFINE_EVENT(ocfs2__ull_int_int_int, name, \ - TP_PROTO(unsigned long long ull, int value1, \ - int value2, int value3), \ - TP_ARGS(ull, value1, value2, value3)) - -DECLARE_EVENT_CLASS(ocfs2__ull_uint_uint_uint, - TP_PROTO(unsigned long long ull, unsigned int value1, - unsigned int value2, unsigned int value3), - TP_ARGS(ull, value1, value2, value3), - TP_STRUCT__entry( - __field(unsigned long long, ull) - __field(unsigned int, value1) - __field(unsigned int, value2) - __field(unsigned int, value3) - ), - TP_fast_assign( - __entry->ull = ull; - __entry->value1 = value1; - __entry->value2 = value2; - __entry->value3 = value3; - ), - TP_printk("%llu %u %u %u", - __entry->ull, __entry->value1, - __entry->value2, __entry->value3) -); - -#define DEFINE_OCFS2_ULL_UINT_UINT_UINT_EVENT(name) \ -DEFINE_EVENT(ocfs2__ull_uint_uint_uint, name, \ - TP_PROTO(unsigned long long ull, unsigned int value1, \ - unsigned int value2, unsigned int value3), \ - TP_ARGS(ull, value1, value2, value3)) - -DECLARE_EVENT_CLASS(ocfs2__ull_ull_uint_uint, - TP_PROTO(unsigned long long value1, unsigned long long value2, - unsigned int value3, unsigned int value4), - TP_ARGS(value1, value2, value3, value4), - TP_STRUCT__entry( - __field(unsigned long long, value1) - __field(unsigned long long, value2) - __field(unsigned int, value3) - __field(unsigned int, value4) - ), - TP_fast_assign( - __entry->value1 = value1; - __entry->value2 = value2; - __entry->value3 = value3; - __entry->value4 = value4; - ), - TP_printk("%llu %llu %u %u", - __entry->value1, __entry->value2, - __entry->value3, __entry->value4) -); - -#define DEFINE_OCFS2_ULL_ULL_UINT_UINT_EVENT(name) \ -DEFINE_EVENT(ocfs2__ull_ull_uint_uint, name, \ - TP_PROTO(unsigned long long ull, unsigned long long ull1, \ - unsigned int value2, unsigned int value3), \ - TP_ARGS(ull, ull1, value2, value3)) - -/* Trace events for fs/ocfs2/alloc.c. */ -DECLARE_EVENT_CLASS(ocfs2__btree_ops, - TP_PROTO(unsigned long long owner,\ - unsigned int value1, unsigned int value2), - TP_ARGS(owner, value1, value2), - TP_STRUCT__entry( - __field(unsigned long long, owner) - __field(unsigned int, value1) - __field(unsigned int, value2) - ), - TP_fast_assign( - __entry->owner = owner; - __entry->value1 = value1; - __entry->value2 = value2; - ), - TP_printk("%llu %u %u", - __entry->owner, __entry->value1, __entry->value2) -); - -#define DEFINE_OCFS2_BTREE_EVENT(name) \ -DEFINE_EVENT(ocfs2__btree_ops, name, \ - TP_PROTO(unsigned long long owner, \ - unsigned int value1, unsigned int value2), \ - TP_ARGS(owner, value1, value2)) - -DEFINE_OCFS2_BTREE_EVENT(ocfs2_adjust_rightmost_branch); - -DEFINE_OCFS2_BTREE_EVENT(ocfs2_rotate_tree_right); - -DEFINE_OCFS2_BTREE_EVENT(ocfs2_append_rec_to_path); - -DEFINE_OCFS2_BTREE_EVENT(ocfs2_insert_extent_start); - -DEFINE_OCFS2_BTREE_EVENT(ocfs2_add_clusters_in_btree); - -DEFINE_OCFS2_INT_EVENT(ocfs2_num_free_extents); - -DEFINE_OCFS2_INT_EVENT(ocfs2_complete_edge_insert); - -TRACE_EVENT(ocfs2_grow_tree, - TP_PROTO(unsigned long long owner, int depth), - TP_ARGS(owner, depth), - TP_STRUCT__entry( - __field(unsigned long long, owner) - __field(int, depth) - ), - TP_fast_assign( - __entry->owner = owner; - __entry->depth = depth; - ), - TP_printk("%llu %d", __entry->owner, __entry->depth) -); - -TRACE_EVENT(ocfs2_rotate_subtree, - TP_PROTO(int subtree_root, unsigned long long blkno, - int depth), - TP_ARGS(subtree_root, blkno, depth), - TP_STRUCT__entry( - __field(int, subtree_root) - __field(unsigned long long, blkno) - __field(int, depth) - ), - TP_fast_assign( - __entry->subtree_root = subtree_root; - __entry->blkno = blkno; - __entry->depth = depth; - ), - TP_printk("%d %llu %d", __entry->subtree_root, - __entry->blkno, __entry->depth) -); - -TRACE_EVENT(ocfs2_insert_extent, - TP_PROTO(unsigned int ins_appending, unsigned int ins_contig, - int ins_contig_index, int free_records, int ins_tree_depth), - TP_ARGS(ins_appending, ins_contig, ins_contig_index, free_records, - ins_tree_depth), - TP_STRUCT__entry( - __field(unsigned int, ins_appending) - __field(unsigned int, ins_contig) - __field(int, ins_contig_index) - __field(int, free_records) - __field(int, ins_tree_depth) - ), - TP_fast_assign( - __entry->ins_appending = ins_appending; - __entry->ins_contig = ins_contig; - __entry->ins_contig_index = ins_contig_index; - __entry->free_records = free_records; - __entry->ins_tree_depth = ins_tree_depth; - ), - TP_printk("%u %u %d %d %d", - __entry->ins_appending, __entry->ins_contig, - __entry->ins_contig_index, __entry->free_records, - __entry->ins_tree_depth) -); - -TRACE_EVENT(ocfs2_split_extent, - TP_PROTO(int split_index, unsigned int c_contig_type, - unsigned int c_has_empty_extent, - unsigned int c_split_covers_rec), - TP_ARGS(split_index, c_contig_type, - c_has_empty_extent, c_split_covers_rec), - TP_STRUCT__entry( - __field(int, split_index) - __field(unsigned int, c_contig_type) - __field(unsigned int, c_has_empty_extent) - __field(unsigned int, c_split_covers_rec) - ), - TP_fast_assign( - __entry->split_index = split_index; - __entry->c_contig_type = c_contig_type; - __entry->c_has_empty_extent = c_has_empty_extent; - __entry->c_split_covers_rec = c_split_covers_rec; - ), - TP_printk("%d %u %u %u", __entry->split_index, __entry->c_contig_type, - __entry->c_has_empty_extent, __entry->c_split_covers_rec) -); - -TRACE_EVENT(ocfs2_remove_extent, - TP_PROTO(unsigned long long owner, unsigned int cpos, - unsigned int len, int index, - unsigned int e_cpos, unsigned int clusters), - TP_ARGS(owner, cpos, len, index, e_cpos, clusters), - TP_STRUCT__entry( - __field(unsigned long long, owner) - __field(unsigned int, cpos) - __field(unsigned int, len) - __field(int, index) - __field(unsigned int, e_cpos) - __field(unsigned int, clusters) - ), - TP_fast_assign( - __entry->owner = owner; - __entry->cpos = cpos; - __entry->len = len; - __entry->index = index; - __entry->e_cpos = e_cpos; - __entry->clusters = clusters; - ), - TP_printk("%llu %u %u %d %u %u", - __entry->owner, __entry->cpos, __entry->len, __entry->index, - __entry->e_cpos, __entry->clusters) -); - -TRACE_EVENT(ocfs2_commit_truncate, - TP_PROTO(unsigned long long ino, unsigned int new_cpos, - unsigned int clusters, unsigned int depth), - TP_ARGS(ino, new_cpos, clusters, depth), - TP_STRUCT__entry( - __field(unsigned long long, ino) - __field(unsigned int, new_cpos) - __field(unsigned int, clusters) - __field(unsigned int, depth) - ), - TP_fast_assign( - __entry->ino = ino; - __entry->new_cpos = new_cpos; - __entry->clusters = clusters; - __entry->depth = depth; - ), - TP_printk("%llu %u %u %u", - __entry->ino, __entry->new_cpos, - __entry->clusters, __entry->depth) -); - -TRACE_EVENT(ocfs2_validate_extent_block, - TP_PROTO(unsigned long long blkno), - TP_ARGS(blkno), - TP_STRUCT__entry( - __field(unsigned long long, blkno) - ), - TP_fast_assign( - __entry->blkno = blkno; - ), - TP_printk("%llu ", __entry->blkno) -); - -TRACE_EVENT(ocfs2_rotate_leaf, - TP_PROTO(unsigned int insert_cpos, int insert_index, - int has_empty, int next_free, - unsigned int l_count), - TP_ARGS(insert_cpos, insert_index, has_empty, - next_free, l_count), - TP_STRUCT__entry( - __field(unsigned int, insert_cpos) - __field(int, insert_index) - __field(int, has_empty) - __field(int, next_free) - __field(unsigned int, l_count) - ), - TP_fast_assign( - __entry->insert_cpos = insert_cpos; - __entry->insert_index = insert_index; - __entry->has_empty = has_empty; - __entry->next_free = next_free; - __entry->l_count = l_count; - ), - TP_printk("%u %d %d %d %u", __entry->insert_cpos, - __entry->insert_index, __entry->has_empty, - __entry->next_free, __entry->l_count) -); - -TRACE_EVENT(ocfs2_add_clusters_in_btree_ret, - TP_PROTO(int status, int reason, int err), - TP_ARGS(status, reason, err), - TP_STRUCT__entry( - __field(int, status) - __field(int, reason) - __field(int, err) - ), - TP_fast_assign( - __entry->status = status; - __entry->reason = reason; - __entry->err = err; - ), - TP_printk("%d %d %d", __entry->status, - __entry->reason, __entry->err) -); - -TRACE_EVENT(ocfs2_mark_extent_written, - TP_PROTO(unsigned long long owner, unsigned int cpos, - unsigned int len, unsigned int phys), - TP_ARGS(owner, cpos, len, phys), - TP_STRUCT__entry( - __field(unsigned long long, owner) - __field(unsigned int, cpos) - __field(unsigned int, len) - __field(unsigned int, phys) - ), - TP_fast_assign( - __entry->owner = owner; - __entry->cpos = cpos; - __entry->len = len; - __entry->phys = phys; - ), - TP_printk("%llu %u %u %u", - __entry->owner, __entry->cpos, - __entry->len, __entry->phys) -); - -DECLARE_EVENT_CLASS(ocfs2__truncate_log_ops, - TP_PROTO(unsigned long long blkno, int index, - unsigned int start, unsigned int num), - TP_ARGS(blkno, index, start, num), - TP_STRUCT__entry( - __field(unsigned long long, blkno) - __field(int, index) - __field(unsigned int, start) - __field(unsigned int, num) - ), - TP_fast_assign( - __entry->blkno = blkno; - __entry->index = index; - __entry->start = start; - __entry->num = num; - ), - TP_printk("%llu %d %u %u", - __entry->blkno, __entry->index, - __entry->start, __entry->num) -); - -#define DEFINE_OCFS2_TRUNCATE_LOG_OPS_EVENT(name) \ -DEFINE_EVENT(ocfs2__truncate_log_ops, name, \ - TP_PROTO(unsigned long long blkno, int index, \ - unsigned int start, unsigned int num), \ - TP_ARGS(blkno, index, start, num)) - -DEFINE_OCFS2_TRUNCATE_LOG_OPS_EVENT(ocfs2_truncate_log_append); - -DEFINE_OCFS2_TRUNCATE_LOG_OPS_EVENT(ocfs2_replay_truncate_records); - -DEFINE_OCFS2_ULL_UINT_EVENT(ocfs2_flush_truncate_log); - -DEFINE_OCFS2_INT_EVENT(ocfs2_begin_truncate_log_recovery); - -DEFINE_OCFS2_INT_EVENT(ocfs2_truncate_log_recovery_num); - -DEFINE_OCFS2_ULL_UINT_EVENT(ocfs2_complete_truncate_log_recovery); - -DEFINE_OCFS2_ULL_UINT_EVENT(ocfs2_free_cached_blocks); - -DEFINE_OCFS2_ULL_UINT_EVENT(ocfs2_cache_cluster_dealloc); - -DEFINE_OCFS2_INT_INT_EVENT(ocfs2_run_deallocs); - -TRACE_EVENT(ocfs2_cache_block_dealloc, - TP_PROTO(int type, int slot, unsigned long long suballoc, - unsigned long long blkno, unsigned int bit), - TP_ARGS(type, slot, suballoc, blkno, bit), - TP_STRUCT__entry( - __field(int, type) - __field(int, slot) - __field(unsigned long long, suballoc) - __field(unsigned long long, blkno) - __field(unsigned int, bit) - ), - TP_fast_assign( - __entry->type = type; - __entry->slot = slot; - __entry->suballoc = suballoc; - __entry->blkno = blkno; - __entry->bit = bit; - ), - TP_printk("%d %d %llu %llu %u", - __entry->type, __entry->slot, __entry->suballoc, - __entry->blkno, __entry->bit) -); - -/* End of trace events for fs/ocfs2/alloc.c. */ - -/* Trace events for fs/ocfs2/localalloc.c. */ - -DEFINE_OCFS2_UINT_UINT_UINT_EVENT(ocfs2_la_set_sizes); - -DEFINE_OCFS2_ULL_INT_INT_INT_EVENT(ocfs2_alloc_should_use_local); - -DEFINE_OCFS2_INT_EVENT(ocfs2_load_local_alloc); - -DEFINE_OCFS2_INT_EVENT(ocfs2_begin_local_alloc_recovery); - -DEFINE_OCFS2_ULL_INT_INT_INT_EVENT(ocfs2_reserve_local_alloc_bits); - -DEFINE_OCFS2_UINT_EVENT(ocfs2_local_alloc_count_bits); - -DEFINE_OCFS2_INT_INT_EVENT(ocfs2_local_alloc_find_clear_bits_search_bitmap); - -DEFINE_OCFS2_ULL_INT_INT_INT_EVENT(ocfs2_local_alloc_find_clear_bits); - -DEFINE_OCFS2_INT_INT_EVENT(ocfs2_sync_local_to_main); - -TRACE_EVENT(ocfs2_sync_local_to_main_free, - TP_PROTO(int count, int bit, unsigned long long start_blk, - unsigned long long blkno), - TP_ARGS(count, bit, start_blk, blkno), - TP_STRUCT__entry( - __field(int, count) - __field(int, bit) - __field(unsigned long long, start_blk) - __field(unsigned long long, blkno) - ), - TP_fast_assign( - __entry->count = count; - __entry->bit = bit; - __entry->start_blk = start_blk; - __entry->blkno = blkno; - ), - TP_printk("%d %d %llu %llu", - __entry->count, __entry->bit, __entry->start_blk, - __entry->blkno) -); - -DEFINE_OCFS2_INT_INT_EVENT(ocfs2_local_alloc_new_window); - -DEFINE_OCFS2_ULL_UINT_EVENT(ocfs2_local_alloc_new_window_result); - -/* End of trace events for fs/ocfs2/localalloc.c. */ - -/* Trace events for fs/ocfs2/resize.c. */ - -DEFINE_OCFS2_UINT_UINT_EVENT(ocfs2_update_last_group_and_inode); - -DEFINE_OCFS2_ULL_UINT_EVENT(ocfs2_group_extend); - -DEFINE_OCFS2_ULL_UINT_UINT_UINT_EVENT(ocfs2_group_add); - -/* End of trace events for fs/ocfs2/resize.c. */ - -/* Trace events for fs/ocfs2/suballoc.c. */ - -DEFINE_OCFS2_ULL_EVENT(ocfs2_validate_group_descriptor); - -DEFINE_OCFS2_ULL_UINT_EVENT(ocfs2_block_group_alloc_contig); - -DEFINE_OCFS2_ULL_UINT_EVENT(ocfs2_block_group_alloc_discontig); - -DEFINE_OCFS2_ULL_EVENT(ocfs2_block_group_alloc); - -DEFINE_OCFS2_UINT_UINT_EVENT(ocfs2_reserve_suballoc_bits_nospc); - -DEFINE_OCFS2_UINT_UINT_UINT_EVENT(ocfs2_reserve_suballoc_bits_no_new_group); - -DEFINE_OCFS2_ULL_EVENT(ocfs2_reserve_new_inode_new_group); - -DEFINE_OCFS2_UINT_UINT_EVENT(ocfs2_block_group_set_bits); - -TRACE_EVENT(ocfs2_relink_block_group, - TP_PROTO(unsigned long long i_blkno, unsigned int chain, - unsigned long long bg_blkno, - unsigned long long prev_blkno), - TP_ARGS(i_blkno, chain, bg_blkno, prev_blkno), - TP_STRUCT__entry( - __field(unsigned long long, i_blkno) - __field(unsigned int, chain) - __field(unsigned long long, bg_blkno) - __field(unsigned long long, prev_blkno) - ), - TP_fast_assign( - __entry->i_blkno = i_blkno; - __entry->chain = chain; - __entry->bg_blkno = bg_blkno; - __entry->prev_blkno = prev_blkno; - ), - TP_printk("%llu %u %llu %llu", - __entry->i_blkno, __entry->chain, __entry->bg_blkno, - __entry->prev_blkno) -); - -DEFINE_OCFS2_ULL_UINT_UINT_UINT_EVENT(ocfs2_cluster_group_search_wrong_max_bits); - -DEFINE_OCFS2_ULL_ULL_EVENT(ocfs2_cluster_group_search_max_block); - -DEFINE_OCFS2_ULL_ULL_EVENT(ocfs2_block_group_search_max_block); - -DEFINE_OCFS2_ULL_UINT_UINT_EVENT(ocfs2_search_chain_begin); - -DEFINE_OCFS2_ULL_UINT_EVENT(ocfs2_search_chain_succ); - -DEFINE_OCFS2_ULL_UINT_EVENT(ocfs2_search_chain_end); - -DEFINE_OCFS2_UINT_EVENT(ocfs2_claim_suballoc_bits); - -DEFINE_OCFS2_ULL_UINT_EVENT(ocfs2_claim_new_inode_at_loc); - -DEFINE_OCFS2_UINT_UINT_EVENT(ocfs2_block_group_clear_bits); - -TRACE_EVENT(ocfs2_free_suballoc_bits, - TP_PROTO(unsigned long long inode, unsigned long long group, - unsigned int start_bit, unsigned int count), - TP_ARGS(inode, group, start_bit, count), - TP_STRUCT__entry( - __field(unsigned long long, inode) - __field(unsigned long long, group) - __field(unsigned int, start_bit) - __field(unsigned int, count) - ), - TP_fast_assign( - __entry->inode = inode; - __entry->group = group; - __entry->start_bit = start_bit; - __entry->count = count; - ), - TP_printk("%llu %llu %u %u", __entry->inode, __entry->group, - __entry->start_bit, __entry->count) -); - -TRACE_EVENT(ocfs2_free_clusters, - TP_PROTO(unsigned long long bg_blkno, unsigned long long start_blk, - unsigned int start_bit, unsigned int count), - TP_ARGS(bg_blkno, start_blk, start_bit, count), - TP_STRUCT__entry( - __field(unsigned long long, bg_blkno) - __field(unsigned long long, start_blk) - __field(unsigned int, start_bit) - __field(unsigned int, count) - ), - TP_fast_assign( - __entry->bg_blkno = bg_blkno; - __entry->start_blk = start_blk; - __entry->start_bit = start_bit; - __entry->count = count; - ), - TP_printk("%llu %llu %u %u", __entry->bg_blkno, __entry->start_blk, - __entry->start_bit, __entry->count) -); - -DEFINE_OCFS2_ULL_EVENT(ocfs2_get_suballoc_slot_bit); - -DEFINE_OCFS2_ULL_UINT_EVENT(ocfs2_test_suballoc_bit); - -DEFINE_OCFS2_ULL_EVENT(ocfs2_test_inode_bit); - -/* End of trace events for fs/ocfs2/suballoc.c. */ - -/* Trace events for fs/ocfs2/refcounttree.c. */ - -DEFINE_OCFS2_ULL_EVENT(ocfs2_validate_refcount_block); - -DEFINE_OCFS2_ULL_EVENT(ocfs2_purge_refcount_trees); - -DEFINE_OCFS2_ULL_EVENT(ocfs2_create_refcount_tree); - -DEFINE_OCFS2_ULL_EVENT(ocfs2_create_refcount_tree_blkno); - -DEFINE_OCFS2_ULL_INT_INT_INT_EVENT(ocfs2_change_refcount_rec); - -DEFINE_OCFS2_ULL_UINT_EVENT(ocfs2_expand_inline_ref_root); - -DEFINE_OCFS2_ULL_UINT_UINT_EVENT(ocfs2_divide_leaf_refcount_block); - -DEFINE_OCFS2_ULL_UINT_EVENT(ocfs2_new_leaf_refcount_block); - -DECLARE_EVENT_CLASS(ocfs2__refcount_tree_ops, - TP_PROTO(unsigned long long blkno, int index, - unsigned long long cpos, - unsigned int clusters, unsigned int refcount), - TP_ARGS(blkno, index, cpos, clusters, refcount), - TP_STRUCT__entry( - __field(unsigned long long, blkno) - __field(int, index) - __field(unsigned long long, cpos) - __field(unsigned int, clusters) - __field(unsigned int, refcount) - ), - TP_fast_assign( - __entry->blkno = blkno; - __entry->index = index; - __entry->cpos = cpos; - __entry->clusters = clusters; - __entry->refcount = refcount; - ), - TP_printk("%llu %d %llu %u %u", __entry->blkno, __entry->index, - __entry->cpos, __entry->clusters, __entry->refcount) -); - -#define DEFINE_OCFS2_REFCOUNT_TREE_OPS_EVENT(name) \ -DEFINE_EVENT(ocfs2__refcount_tree_ops, name, \ - TP_PROTO(unsigned long long blkno, int index, \ - unsigned long long cpos, \ - unsigned int count, unsigned int refcount), \ - TP_ARGS(blkno, index, cpos, count, refcount)) - -DEFINE_OCFS2_REFCOUNT_TREE_OPS_EVENT(ocfs2_insert_refcount_rec); - -TRACE_EVENT(ocfs2_split_refcount_rec, - TP_PROTO(unsigned long long cpos, - unsigned int clusters, unsigned int refcount, - unsigned long long split_cpos, - unsigned int split_clusters, unsigned int split_refcount), - TP_ARGS(cpos, clusters, refcount, - split_cpos, split_clusters, split_refcount), - TP_STRUCT__entry( - __field(unsigned long long, cpos) - __field(unsigned int, clusters) - __field(unsigned int, refcount) - __field(unsigned long long, split_cpos) - __field(unsigned int, split_clusters) - __field(unsigned int, split_refcount) - ), - TP_fast_assign( - __entry->cpos = cpos; - __entry->clusters = clusters; - __entry->refcount = refcount; - __entry->split_cpos = split_cpos; - __entry->split_clusters = split_clusters; - __entry->split_refcount = split_refcount; - ), - TP_printk("%llu %u %u %llu %u %u", - __entry->cpos, __entry->clusters, __entry->refcount, - __entry->split_cpos, __entry->split_clusters, - __entry->split_refcount) -); - -DEFINE_OCFS2_REFCOUNT_TREE_OPS_EVENT(ocfs2_split_refcount_rec_insert); - -DEFINE_OCFS2_ULL_ULL_UINT_EVENT(ocfs2_increase_refcount_begin); - -DEFINE_OCFS2_ULL_UINT_UINT_EVENT(ocfs2_increase_refcount_change); - -DEFINE_OCFS2_ULL_UINT_EVENT(ocfs2_increase_refcount_insert); - -DEFINE_OCFS2_ULL_UINT_UINT_EVENT(ocfs2_increase_refcount_split); - -DEFINE_OCFS2_ULL_ULL_UINT_EVENT(ocfs2_remove_refcount_extent); - -DEFINE_OCFS2_ULL_EVENT(ocfs2_restore_refcount_block); - -DEFINE_OCFS2_ULL_ULL_UINT_EVENT(ocfs2_decrease_refcount_rec); - -TRACE_EVENT(ocfs2_decrease_refcount, - TP_PROTO(unsigned long long owner, - unsigned long long cpos, - unsigned int len, int delete), - TP_ARGS(owner, cpos, len, delete), - TP_STRUCT__entry( - __field(unsigned long long, owner) - __field(unsigned long long, cpos) - __field(unsigned int, len) - __field(int, delete) - ), - TP_fast_assign( - __entry->owner = owner; - __entry->cpos = cpos; - __entry->len = len; - __entry->delete = delete; - ), - TP_printk("%llu %llu %u %d", - __entry->owner, __entry->cpos, __entry->len, __entry->delete) -); - -DEFINE_OCFS2_ULL_UINT_UINT_UINT_EVENT(ocfs2_mark_extent_refcounted); - -DEFINE_OCFS2_ULL_UINT_UINT_UINT_EVENT(ocfs2_calc_refcount_meta_credits); - -TRACE_EVENT(ocfs2_calc_refcount_meta_credits_iterate, - TP_PROTO(int recs_add, unsigned long long cpos, - unsigned int clusters, unsigned long long r_cpos, - unsigned int r_clusters, unsigned int refcount, int index), - TP_ARGS(recs_add, cpos, clusters, r_cpos, r_clusters, refcount, index), - TP_STRUCT__entry( - __field(int, recs_add) - __field(unsigned long long, cpos) - __field(unsigned int, clusters) - __field(unsigned long long, r_cpos) - __field(unsigned int, r_clusters) - __field(unsigned int, refcount) - __field(int, index) - ), - TP_fast_assign( - __entry->recs_add = recs_add; - __entry->cpos = cpos; - __entry->clusters = clusters; - __entry->r_cpos = r_cpos; - __entry->r_clusters = r_clusters; - __entry->refcount = refcount; - __entry->index = index; - ), - TP_printk("%d %llu %u %llu %u %u %d", - __entry->recs_add, __entry->cpos, __entry->clusters, - __entry->r_cpos, __entry->r_clusters, - __entry->refcount, __entry->index) -); - -DEFINE_OCFS2_INT_INT_EVENT(ocfs2_add_refcount_flag); - -DEFINE_OCFS2_INT_INT_EVENT(ocfs2_prepare_refcount_change_for_del); - -DEFINE_OCFS2_INT_INT_EVENT(ocfs2_lock_refcount_allocators); - -DEFINE_OCFS2_ULL_UINT_UINT_UINT_EVENT(ocfs2_duplicate_clusters_by_page); - -DEFINE_OCFS2_ULL_UINT_UINT_UINT_EVENT(ocfs2_duplicate_clusters_by_jbd); - -TRACE_EVENT(ocfs2_clear_ext_refcount, - TP_PROTO(unsigned long long ino, unsigned int cpos, - unsigned int len, unsigned int p_cluster, - unsigned int ext_flags), - TP_ARGS(ino, cpos, len, p_cluster, ext_flags), - TP_STRUCT__entry( - __field(unsigned long long, ino) - __field(unsigned int, cpos) - __field(unsigned int, len) - __field(unsigned int, p_cluster) - __field(unsigned int, ext_flags) - ), - TP_fast_assign( - __entry->ino = ino; - __entry->cpos = cpos; - __entry->len = len; - __entry->p_cluster = p_cluster; - __entry->ext_flags = ext_flags; - ), - TP_printk("%llu %u %u %u %u", - __entry->ino, __entry->cpos, __entry->len, - __entry->p_cluster, __entry->ext_flags) -); - -TRACE_EVENT(ocfs2_replace_clusters, - TP_PROTO(unsigned long long ino, unsigned int cpos, - unsigned int old, unsigned int new, unsigned int len, - unsigned int ext_flags), - TP_ARGS(ino, cpos, old, new, len, ext_flags), - TP_STRUCT__entry( - __field(unsigned long long, ino) - __field(unsigned int, cpos) - __field(unsigned int, old) - __field(unsigned int, new) - __field(unsigned int, len) - __field(unsigned int, ext_flags) - ), - TP_fast_assign( - __entry->ino = ino; - __entry->cpos = cpos; - __entry->old = old; - __entry->new = new; - __entry->len = len; - __entry->ext_flags = ext_flags; - ), - TP_printk("%llu %u %u %u %u %u", - __entry->ino, __entry->cpos, __entry->old, __entry->new, - __entry->len, __entry->ext_flags) -); - -DEFINE_OCFS2_ULL_UINT_UINT_UINT_EVENT(ocfs2_make_clusters_writable); - -TRACE_EVENT(ocfs2_refcount_cow_hunk, - TP_PROTO(unsigned long long ino, unsigned int cpos, - unsigned int write_len, unsigned int max_cpos, - unsigned int cow_start, unsigned int cow_len), - TP_ARGS(ino, cpos, write_len, max_cpos, cow_start, cow_len), - TP_STRUCT__entry( - __field(unsigned long long, ino) - __field(unsigned int, cpos) - __field(unsigned int, write_len) - __field(unsigned int, max_cpos) - __field(unsigned int, cow_start) - __field(unsigned int, cow_len) - ), - TP_fast_assign( - __entry->ino = ino; - __entry->cpos = cpos; - __entry->write_len = write_len; - __entry->max_cpos = max_cpos; - __entry->cow_start = cow_start; - __entry->cow_len = cow_len; - ), - TP_printk("%llu %u %u %u %u %u", - __entry->ino, __entry->cpos, __entry->write_len, - __entry->max_cpos, __entry->cow_start, __entry->cow_len) -); - -/* End of trace events for fs/ocfs2/refcounttree.c. */ - -/* Trace events for fs/ocfs2/aops.c. */ - -DECLARE_EVENT_CLASS(ocfs2__get_block, - TP_PROTO(unsigned long long ino, unsigned long long iblock, - void *bh_result, int create), - TP_ARGS(ino, iblock, bh_result, create), - TP_STRUCT__entry( - __field(unsigned long long, ino) - __field(unsigned long long, iblock) - __field(void *, bh_result) - __field(int, create) - ), - TP_fast_assign( - __entry->ino = ino; - __entry->iblock = iblock; - __entry->bh_result = bh_result; - __entry->create = create; - ), - TP_printk("%llu %llu %p %d", - __entry->ino, __entry->iblock, - __entry->bh_result, __entry->create) -); - -#define DEFINE_OCFS2_GET_BLOCK_EVENT(name) \ -DEFINE_EVENT(ocfs2__get_block, name, \ - TP_PROTO(unsigned long long ino, unsigned long long iblock, \ - void *bh_result, int create), \ - TP_ARGS(ino, iblock, bh_result, create)) - -DEFINE_OCFS2_GET_BLOCK_EVENT(ocfs2_symlink_get_block); - -DEFINE_OCFS2_GET_BLOCK_EVENT(ocfs2_get_block); - -DEFINE_OCFS2_ULL_ULL_EVENT(ocfs2_get_block_end); - -DEFINE_OCFS2_ULL_ULL_EVENT(ocfs2_readpage); - -DEFINE_OCFS2_ULL_ULL_EVENT(ocfs2_writepage); - -DEFINE_OCFS2_ULL_ULL_EVENT(ocfs2_bmap); - -TRACE_EVENT(ocfs2_try_to_write_inline_data, - TP_PROTO(unsigned long long ino, unsigned int len, - unsigned long long pos, unsigned int flags), - TP_ARGS(ino, len, pos, flags), - TP_STRUCT__entry( - __field(unsigned long long, ino) - __field(unsigned int, len) - __field(unsigned long long, pos) - __field(unsigned int, flags) - ), - TP_fast_assign( - __entry->ino = ino; - __entry->len = len; - __entry->pos = pos; - __entry->flags = flags; - ), - TP_printk("%llu %u %llu 0x%x", - __entry->ino, __entry->len, __entry->pos, __entry->flags) -); - -TRACE_EVENT(ocfs2_write_begin_nolock, - TP_PROTO(unsigned long long ino, - long long i_size, unsigned int i_clusters, - unsigned long long pos, unsigned int len, - unsigned int flags, void *page, - unsigned int clusters, unsigned int extents_to_split), - TP_ARGS(ino, i_size, i_clusters, pos, len, flags, - page, clusters, extents_to_split), - TP_STRUCT__entry( - __field(unsigned long long, ino) - __field(long long, i_size) - __field(unsigned int, i_clusters) - __field(unsigned long long, pos) - __field(unsigned int, len) - __field(unsigned int, flags) - __field(void *, page) - __field(unsigned int, clusters) - __field(unsigned int, extents_to_split) - ), - TP_fast_assign( - __entry->ino = ino; - __entry->i_size = i_size; - __entry->i_clusters = i_clusters; - __entry->pos = pos; - __entry->len = len; - __entry->flags = flags; - __entry->page = page; - __entry->clusters = clusters; - __entry->extents_to_split = extents_to_split; - ), - TP_printk("%llu %lld %u %llu %u %u %p %u %u", - __entry->ino, __entry->i_size, __entry->i_clusters, - __entry->pos, __entry->len, - __entry->flags, __entry->page, __entry->clusters, - __entry->extents_to_split) -); - -TRACE_EVENT(ocfs2_write_end_inline, - TP_PROTO(unsigned long long ino, - unsigned long long pos, unsigned int copied, - unsigned int id_count, unsigned int features), - TP_ARGS(ino, pos, copied, id_count, features), - TP_STRUCT__entry( - __field(unsigned long long, ino) - __field(unsigned long long, pos) - __field(unsigned int, copied) - __field(unsigned int, id_count) - __field(unsigned int, features) - ), - TP_fast_assign( - __entry->ino = ino; - __entry->pos = pos; - __entry->copied = copied; - __entry->id_count = id_count; - __entry->features = features; - ), - TP_printk("%llu %llu %u %u %u", - __entry->ino, __entry->pos, __entry->copied, - __entry->id_count, __entry->features) -); - -/* End of trace events for fs/ocfs2/aops.c. */ - -/* Trace events for fs/ocfs2/mmap.c. */ - -TRACE_EVENT(ocfs2_fault, - TP_PROTO(unsigned long long ino, - void *area, void *page, unsigned long pgoff), - TP_ARGS(ino, area, page, pgoff), - TP_STRUCT__entry( - __field(unsigned long long, ino) - __field(void *, area) - __field(void *, page) - __field(unsigned long, pgoff) - ), - TP_fast_assign( - __entry->ino = ino; - __entry->area = area; - __entry->page = page; - __entry->pgoff = pgoff; - ), - TP_printk("%llu %p %p %lu", - __entry->ino, __entry->area, __entry->page, __entry->pgoff) -); - -/* End of trace events for fs/ocfs2/mmap.c. */ - -/* Trace events for fs/ocfs2/file.c. */ - -DECLARE_EVENT_CLASS(ocfs2__file_ops, - TP_PROTO(void *inode, void *file, void *dentry, - unsigned long long ino, - unsigned int d_len, const unsigned char *d_name, - unsigned long long para), - TP_ARGS(inode, file, dentry, ino, d_len, d_name, para), - TP_STRUCT__entry( - __field(void *, inode) - __field(void *, file) - __field(void *, dentry) - __field(unsigned long long, ino) - __field(unsigned int, d_len) - __string(d_name, d_name) - __field(unsigned long long, para) - ), - TP_fast_assign( - __entry->inode = inode; - __entry->file = file; - __entry->dentry = dentry; - __entry->ino = ino; - __entry->d_len = d_len; - __assign_str(d_name, d_name); - __entry->para = para; - ), - TP_printk("%p %p %p %llu %llu %.*s", __entry->inode, __entry->file, - __entry->dentry, __entry->ino, __entry->para, - __entry->d_len, __get_str(d_name)) -); - -#define DEFINE_OCFS2_FILE_OPS(name) \ -DEFINE_EVENT(ocfs2__file_ops, name, \ -TP_PROTO(void *inode, void *file, void *dentry, \ - unsigned long long ino, \ - unsigned int d_len, const unsigned char *d_name, \ - unsigned long long mode), \ - TP_ARGS(inode, file, dentry, ino, d_len, d_name, mode)) - -DEFINE_OCFS2_FILE_OPS(ocfs2_file_open); - -DEFINE_OCFS2_FILE_OPS(ocfs2_file_release); - -DEFINE_OCFS2_FILE_OPS(ocfs2_sync_file); - -DEFINE_OCFS2_FILE_OPS(ocfs2_file_aio_write); - -DEFINE_OCFS2_FILE_OPS(ocfs2_file_splice_write); - -DEFINE_OCFS2_FILE_OPS(ocfs2_file_splice_read); - -DEFINE_OCFS2_FILE_OPS(ocfs2_file_aio_read); - -DEFINE_OCFS2_ULL_ULL_ULL_EVENT(ocfs2_truncate_file); - -DEFINE_OCFS2_ULL_ULL_EVENT(ocfs2_truncate_file_error); - -TRACE_EVENT(ocfs2_extend_allocation, - TP_PROTO(unsigned long long ip_blkno, unsigned long long size, - unsigned int clusters, unsigned int clusters_to_add, - int why, int restart_func), - TP_ARGS(ip_blkno, size, clusters, clusters_to_add, why, restart_func), - TP_STRUCT__entry( - __field(unsigned long long, ip_blkno) - __field(unsigned long long, size) - __field(unsigned int, clusters) - __field(unsigned int, clusters_to_add) - __field(int, why) - __field(int, restart_func) - ), - TP_fast_assign( - __entry->ip_blkno = ip_blkno; - __entry->size = size; - __entry->clusters = clusters; - __entry->clusters_to_add = clusters_to_add; - __entry->why = why; - __entry->restart_func = restart_func; - ), - TP_printk("%llu %llu %u %u %d %d", - __entry->ip_blkno, __entry->size, __entry->clusters, - __entry->clusters_to_add, __entry->why, __entry->restart_func) -); - -TRACE_EVENT(ocfs2_extend_allocation_end, - TP_PROTO(unsigned long long ino, - unsigned int di_clusters, unsigned long long di_size, - unsigned int ip_clusters, unsigned long long i_size), - TP_ARGS(ino, di_clusters, di_size, ip_clusters, i_size), - TP_STRUCT__entry( - __field(unsigned long long, ino) - __field(unsigned int, di_clusters) - __field(unsigned long long, di_size) - __field(unsigned int, ip_clusters) - __field(unsigned long long, i_size) - ), - TP_fast_assign( - __entry->ino = ino; - __entry->di_clusters = di_clusters; - __entry->di_size = di_size; - __entry->ip_clusters = ip_clusters; - __entry->i_size = i_size; - ), - TP_printk("%llu %u %llu %u %llu", __entry->ino, __entry->di_clusters, - __entry->di_size, __entry->ip_clusters, __entry->i_size) -); - -TRACE_EVENT(ocfs2_write_zero_page, - TP_PROTO(unsigned long long ino, - unsigned long long abs_from, unsigned long long abs_to, - unsigned long index, unsigned int zero_from, - unsigned int zero_to), - TP_ARGS(ino, abs_from, abs_to, index, zero_from, zero_to), - TP_STRUCT__entry( - __field(unsigned long long, ino) - __field(unsigned long long, abs_from) - __field(unsigned long long, abs_to) - __field(unsigned long, index) - __field(unsigned int, zero_from) - __field(unsigned int, zero_to) - ), - TP_fast_assign( - __entry->ino = ino; - __entry->abs_from = abs_from; - __entry->abs_to = abs_to; - __entry->index = index; - __entry->zero_from = zero_from; - __entry->zero_to = zero_to; - ), - TP_printk("%llu %llu %llu %lu %u %u", __entry->ino, - __entry->abs_from, __entry->abs_to, - __entry->index, __entry->zero_from, __entry->zero_to) -); - -DEFINE_OCFS2_ULL_ULL_ULL_EVENT(ocfs2_zero_extend_range); - -DEFINE_OCFS2_ULL_ULL_ULL_EVENT(ocfs2_zero_extend); - -TRACE_EVENT(ocfs2_setattr, - TP_PROTO(void *inode, void *dentry, - unsigned long long ino, - unsigned int d_len, const unsigned char *d_name, - unsigned int ia_valid, unsigned int ia_mode, - unsigned int ia_uid, unsigned int ia_gid), - TP_ARGS(inode, dentry, ino, d_len, d_name, - ia_valid, ia_mode, ia_uid, ia_gid), - TP_STRUCT__entry( - __field(void *, inode) - __field(void *, dentry) - __field(unsigned long long, ino) - __field(unsigned int, d_len) - __string(d_name, d_name) - __field(unsigned int, ia_valid) - __field(unsigned int, ia_mode) - __field(unsigned int, ia_uid) - __field(unsigned int, ia_gid) - ), - TP_fast_assign( - __entry->inode = inode; - __entry->dentry = dentry; - __entry->ino = ino; - __entry->d_len = d_len; - __assign_str(d_name, d_name); - __entry->ia_valid = ia_valid; - __entry->ia_mode = ia_mode; - __entry->ia_uid = ia_uid; - __entry->ia_gid = ia_gid; - ), - TP_printk("%p %p %llu %.*s %u %u %u %u", __entry->inode, - __entry->dentry, __entry->ino, __entry->d_len, - __get_str(d_name), __entry->ia_valid, __entry->ia_mode, - __entry->ia_uid, __entry->ia_gid) -); - -DEFINE_OCFS2_ULL_UINT_EVENT(ocfs2_write_remove_suid); - -DEFINE_OCFS2_ULL_ULL_ULL_EVENT(ocfs2_zero_partial_clusters); - -DEFINE_OCFS2_ULL_ULL_EVENT(ocfs2_zero_partial_clusters_range1); - -DEFINE_OCFS2_ULL_ULL_EVENT(ocfs2_zero_partial_clusters_range2); - -DEFINE_OCFS2_ULL_ULL_ULL_EVENT(ocfs2_remove_inode_range); - -TRACE_EVENT(ocfs2_prepare_inode_for_write, - TP_PROTO(unsigned long long ino, unsigned long long saved_pos, - int appending, unsigned long count, - int *direct_io, int *has_refcount), - TP_ARGS(ino, saved_pos, appending, count, direct_io, has_refcount), - TP_STRUCT__entry( - __field(unsigned long long, ino) - __field(unsigned long long, saved_pos) - __field(int, appending) - __field(unsigned long, count) - __field(int, direct_io) - __field(int, has_refcount) - ), - TP_fast_assign( - __entry->ino = ino; - __entry->saved_pos = saved_pos; - __entry->appending = appending; - __entry->count = count; - __entry->direct_io = direct_io ? *direct_io : -1; - __entry->has_refcount = has_refcount ? *has_refcount : -1; - ), - TP_printk("%llu %llu %d %lu %d %d", __entry->ino, - __entry->saved_pos, __entry->appending, __entry->count, - __entry->direct_io, __entry->has_refcount) -); - -DEFINE_OCFS2_INT_EVENT(generic_file_aio_read_ret); - -/* End of trace events for fs/ocfs2/file.c. */ - -/* Trace events for fs/ocfs2/inode.c. */ - -TRACE_EVENT(ocfs2_iget_begin, - TP_PROTO(unsigned long long ino, unsigned int flags, int sysfile_type), - TP_ARGS(ino, flags, sysfile_type), - TP_STRUCT__entry( - __field(unsigned long long, ino) - __field(unsigned int, flags) - __field(int, sysfile_type) - ), - TP_fast_assign( - __entry->ino = ino; - __entry->flags = flags; - __entry->sysfile_type = sysfile_type; - ), - TP_printk("%llu %u %d", __entry->ino, - __entry->flags, __entry->sysfile_type) -); - -DEFINE_OCFS2_ULL_EVENT(ocfs2_iget5_locked); - -TRACE_EVENT(ocfs2_iget_end, - TP_PROTO(void *inode, unsigned long long ino), - TP_ARGS(inode, ino), - TP_STRUCT__entry( - __field(void *, inode) - __field(unsigned long long, ino) - ), - TP_fast_assign( - __entry->inode = inode; - __entry->ino = ino; - ), - TP_printk("%p %llu", __entry->inode, __entry->ino) -); - -TRACE_EVENT(ocfs2_find_actor, - TP_PROTO(void *inode, unsigned long long ino, - void *args, unsigned long long fi_blkno), - TP_ARGS(inode, ino, args, fi_blkno), - TP_STRUCT__entry( - __field(void *, inode) - __field(unsigned long long, ino) - __field(void *, args) - __field(unsigned long long, fi_blkno) - ), - TP_fast_assign( - __entry->inode = inode; - __entry->ino = ino; - __entry->args = args; - __entry->fi_blkno = fi_blkno; - ), - TP_printk("%p %llu %p %llu", __entry->inode, __entry->ino, - __entry->args, __entry->fi_blkno) -); - -DEFINE_OCFS2_ULL_UINT_EVENT(ocfs2_populate_inode); - -DEFINE_OCFS2_ULL_INT_EVENT(ocfs2_read_locked_inode); - -DEFINE_OCFS2_INT_INT_EVENT(ocfs2_check_orphan_recovery_state); - -DEFINE_OCFS2_ULL_EVENT(ocfs2_validate_inode_block); - -TRACE_EVENT(ocfs2_inode_is_valid_to_delete, - TP_PROTO(void *task, void *dc_task, unsigned long long ino, - unsigned int flags), - TP_ARGS(task, dc_task, ino, flags), - TP_STRUCT__entry( - __field(void *, task) - __field(void *, dc_task) - __field(unsigned long long, ino) - __field(unsigned int, flags) - ), - TP_fast_assign( - __entry->task = task; - __entry->dc_task = dc_task; - __entry->ino = ino; - __entry->flags = flags; - ), - TP_printk("%p %p %llu %u", __entry->task, __entry->dc_task, - __entry->ino, __entry->flags) -); - -DEFINE_OCFS2_ULL_UINT_EVENT(ocfs2_query_inode_wipe_begin); - -DEFINE_OCFS2_UINT_EVENT(ocfs2_query_inode_wipe_succ); - -DEFINE_OCFS2_INT_INT_EVENT(ocfs2_query_inode_wipe_end); - -DEFINE_OCFS2_ULL_INT_EVENT(ocfs2_cleanup_delete_inode); - -DEFINE_OCFS2_ULL_ULL_UINT_EVENT(ocfs2_delete_inode); - -DEFINE_OCFS2_ULL_UINT_EVENT(ocfs2_clear_inode); - -DEFINE_OCFS2_ULL_UINT_UINT_EVENT(ocfs2_drop_inode); - -TRACE_EVENT(ocfs2_inode_revalidate, - TP_PROTO(void *inode, unsigned long long ino, - unsigned int flags), - TP_ARGS(inode, ino, flags), - TP_STRUCT__entry( - __field(void *, inode) - __field(unsigned long long, ino) - __field(unsigned int, flags) - ), - TP_fast_assign( - __entry->inode = inode; - __entry->ino = ino; - __entry->flags = flags; - ), - TP_printk("%p %llu %u", __entry->inode, __entry->ino, __entry->flags) -); - -DEFINE_OCFS2_ULL_EVENT(ocfs2_mark_inode_dirty); - -/* End of trace events for fs/ocfs2/inode.c. */ - -/* Trace events for fs/ocfs2/extent_map.c. */ - -TRACE_EVENT(ocfs2_read_virt_blocks, - TP_PROTO(void *inode, unsigned long long vblock, int nr, - void *bhs, unsigned int flags, void *validate), - TP_ARGS(inode, vblock, nr, bhs, flags, validate), - TP_STRUCT__entry( - __field(void *, inode) - __field(unsigned long long, vblock) - __field(int, nr) - __field(void *, bhs) - __field(unsigned int, flags) - __field(void *, validate) - ), - TP_fast_assign( - __entry->inode = inode; - __entry->vblock = vblock; - __entry->nr = nr; - __entry->bhs = bhs; - __entry->flags = flags; - __entry->validate = validate; - ), - TP_printk("%p %llu %d %p %x %p", __entry->inode, __entry->vblock, - __entry->nr, __entry->bhs, __entry->flags, __entry->validate) -); - -/* End of trace events for fs/ocfs2/extent_map.c. */ - -/* Trace events for fs/ocfs2/slot_map.c. */ - -DEFINE_OCFS2_UINT_EVENT(ocfs2_refresh_slot_info); - -DEFINE_OCFS2_ULL_UINT_EVENT(ocfs2_map_slot_buffers); - -DEFINE_OCFS2_ULL_UINT_EVENT(ocfs2_map_slot_buffers_block); - -DEFINE_OCFS2_INT_EVENT(ocfs2_find_slot); - -/* End of trace events for fs/ocfs2/slot_map.c. */ - -/* Trace events for fs/ocfs2/heartbeat.c. */ - -DEFINE_OCFS2_INT_EVENT(ocfs2_do_node_down); - -/* End of trace events for fs/ocfs2/heartbeat.c. */ - -/* Trace events for fs/ocfs2/super.c. */ - -TRACE_EVENT(ocfs2_remount, - TP_PROTO(unsigned long s_flags, unsigned long osb_flags, int flags), - TP_ARGS(s_flags, osb_flags, flags), - TP_STRUCT__entry( - __field(unsigned long, s_flags) - __field(unsigned long, osb_flags) - __field(int, flags) - ), - TP_fast_assign( - __entry->s_flags = s_flags; - __entry->osb_flags = osb_flags; - __entry->flags = flags; - ), - TP_printk("%lu %lu %d", __entry->s_flags, - __entry->osb_flags, __entry->flags) -); - -TRACE_EVENT(ocfs2_fill_super, - TP_PROTO(void *sb, void *data, int silent), - TP_ARGS(sb, data, silent), - TP_STRUCT__entry( - __field(void *, sb) - __field(void *, data) - __field(int, silent) - ), - TP_fast_assign( - __entry->sb = sb; - __entry->data = data; - __entry->silent = silent; - ), - TP_printk("%p %p %d", __entry->sb, - __entry->data, __entry->silent) -); - -TRACE_EVENT(ocfs2_parse_options, - TP_PROTO(int is_remount, char *options), - TP_ARGS(is_remount, options), - TP_STRUCT__entry( - __field(int, is_remount) - __string(options, options) - ), - TP_fast_assign( - __entry->is_remount = is_remount; - __assign_str(options, options); - ), - TP_printk("%d %s", __entry->is_remount, __get_str(options)) -); - -DEFINE_OCFS2_POINTER_EVENT(ocfs2_put_super); - -TRACE_EVENT(ocfs2_statfs, - TP_PROTO(void *sb, void *buf), - TP_ARGS(sb, buf), - TP_STRUCT__entry( - __field(void *, sb) - __field(void *, buf) - ), - TP_fast_assign( - __entry->sb = sb; - __entry->buf = buf; - ), - TP_printk("%p %p", __entry->sb, __entry->buf) -); - -DEFINE_OCFS2_POINTER_EVENT(ocfs2_dismount_volume); - -TRACE_EVENT(ocfs2_initialize_super, - TP_PROTO(char *label, char *uuid_str, unsigned long long root_dir, - unsigned long long system_dir, int cluster_bits), - TP_ARGS(label, uuid_str, root_dir, system_dir, cluster_bits), - TP_STRUCT__entry( - __string(label, label) - __string(uuid_str, uuid_str) - __field(unsigned long long, root_dir) - __field(unsigned long long, system_dir) - __field(int, cluster_bits) - ), - TP_fast_assign( - __assign_str(label, label); - __assign_str(uuid_str, uuid_str); - __entry->root_dir = root_dir; - __entry->system_dir = system_dir; - __entry->cluster_bits = cluster_bits; - ), - TP_printk("%s %s %llu %llu %d", __get_str(label), __get_str(uuid_str), - __entry->root_dir, __entry->system_dir, __entry->cluster_bits) -); - -/* End of trace events for fs/ocfs2/super.c. */ - -/* Trace events for fs/ocfs2/xattr.c. */ - -DEFINE_OCFS2_ULL_EVENT(ocfs2_validate_xattr_block); - -DEFINE_OCFS2_UINT_EVENT(ocfs2_xattr_extend_allocation); - -TRACE_EVENT(ocfs2_init_xattr_set_ctxt, - TP_PROTO(const char *name, int meta, int clusters, int credits), - TP_ARGS(name, meta, clusters, credits), - TP_STRUCT__entry( - __string(name, name) - __field(int, meta) - __field(int, clusters) - __field(int, credits) - ), - TP_fast_assign( - __assign_str(name, name); - __entry->meta = meta; - __entry->clusters = clusters; - __entry->credits = credits; - ), - TP_printk("%s %d %d %d", __get_str(name), __entry->meta, - __entry->clusters, __entry->credits) -); - -DECLARE_EVENT_CLASS(ocfs2__xattr_find, - TP_PROTO(unsigned long long ino, const char *name, int name_index, - unsigned int hash, unsigned long long location, - int xe_index), - TP_ARGS(ino, name, name_index, hash, location, xe_index), - TP_STRUCT__entry( - __field(unsigned long long, ino) - __string(name, name) - __field(int, name_index) - __field(unsigned int, hash) - __field(unsigned long long, location) - __field(int, xe_index) - ), - TP_fast_assign( - __entry->ino = ino; - __assign_str(name, name); - __entry->name_index = name_index; - __entry->hash = hash; - __entry->location = location; - __entry->xe_index = xe_index; - ), - TP_printk("%llu %s %d %u %llu %d", __entry->ino, __get_str(name), - __entry->name_index, __entry->hash, __entry->location, - __entry->xe_index) -); - -#define DEFINE_OCFS2_XATTR_FIND_EVENT(name) \ -DEFINE_EVENT(ocfs2__xattr_find, name, \ -TP_PROTO(unsigned long long ino, const char *name, int name_index, \ - unsigned int hash, unsigned long long bucket, \ - int xe_index), \ - TP_ARGS(ino, name, name_index, hash, bucket, xe_index)) - -DEFINE_OCFS2_XATTR_FIND_EVENT(ocfs2_xattr_bucket_find); - -DEFINE_OCFS2_XATTR_FIND_EVENT(ocfs2_xattr_index_block_find); - -DEFINE_OCFS2_XATTR_FIND_EVENT(ocfs2_xattr_index_block_find_rec); - -DEFINE_OCFS2_ULL_ULL_UINT_EVENT(ocfs2_iterate_xattr_buckets); - -DEFINE_OCFS2_ULL_UINT_EVENT(ocfs2_iterate_xattr_bucket); - -DEFINE_OCFS2_ULL_ULL_EVENT(ocfs2_cp_xattr_block_to_bucket_begin); - -DEFINE_OCFS2_UINT_UINT_UINT_EVENT(ocfs2_cp_xattr_block_to_bucket_end); - -DEFINE_OCFS2_ULL_EVENT(ocfs2_xattr_create_index_block_begin); - -DEFINE_OCFS2_ULL_EVENT(ocfs2_xattr_create_index_block); - -DEFINE_OCFS2_ULL_UINT_UINT_UINT_EVENT(ocfs2_defrag_xattr_bucket); - -DEFINE_OCFS2_ULL_ULL_EVENT(ocfs2_mv_xattr_bucket_cross_cluster); - -DEFINE_OCFS2_ULL_ULL_EVENT(ocfs2_divide_xattr_bucket_begin); - -DEFINE_OCFS2_UINT_UINT_UINT_EVENT(ocfs2_divide_xattr_bucket_move); - -DEFINE_OCFS2_ULL_ULL_UINT_EVENT(ocfs2_cp_xattr_bucket); - -DEFINE_OCFS2_ULL_ULL_EVENT(ocfs2_mv_xattr_buckets); - -DEFINE_OCFS2_ULL_ULL_UINT_EVENT(ocfs2_adjust_xattr_cross_cluster); - -DEFINE_OCFS2_ULL_ULL_UINT_UINT_EVENT(ocfs2_add_new_xattr_cluster_begin); - -DEFINE_OCFS2_ULL_UINT_EVENT(ocfs2_add_new_xattr_cluster); - -DEFINE_OCFS2_ULL_UINT_UINT_EVENT(ocfs2_add_new_xattr_cluster_insert); - -DEFINE_OCFS2_ULL_ULL_UINT_UINT_EVENT(ocfs2_extend_xattr_bucket); - -DEFINE_OCFS2_ULL_EVENT(ocfs2_add_new_xattr_bucket); - -DEFINE_OCFS2_ULL_UINT_UINT_EVENT(ocfs2_xattr_bucket_value_truncate); - -DEFINE_OCFS2_ULL_ULL_UINT_UINT_EVENT(ocfs2_rm_xattr_cluster); - -DEFINE_OCFS2_ULL_UINT_EVENT(ocfs2_reflink_xattr_header); - -DEFINE_OCFS2_ULL_INT_EVENT(ocfs2_create_empty_xattr_block); - -DEFINE_OCFS2_STRING_EVENT(ocfs2_xattr_set_entry_bucket); - -DEFINE_OCFS2_STRING_EVENT(ocfs2_xattr_set_entry_index_block); - -DEFINE_OCFS2_ULL_UINT_EVENT(ocfs2_xattr_bucket_value_refcount); - -DEFINE_OCFS2_ULL_UINT_UINT_EVENT(ocfs2_reflink_xattr_buckets); - -DEFINE_OCFS2_ULL_UINT_EVENT(ocfs2_reflink_xattr_rec); - -/* End of trace events for fs/ocfs2/xattr.c. */ - -/* Trace events for fs/ocfs2/reservations.c. */ - -DEFINE_OCFS2_UINT_UINT_EVENT(ocfs2_resv_insert); - -DEFINE_OCFS2_ULL_UINT_UINT_UINT_EVENT(ocfs2_resmap_find_free_bits_begin); - -DEFINE_OCFS2_UINT_UINT_EVENT(ocfs2_resmap_find_free_bits_end); - -TRACE_EVENT(ocfs2_resv_find_window_begin, - TP_PROTO(unsigned int r_start, unsigned int r_end, unsigned int goal, - unsigned int wanted, int empty_root), - TP_ARGS(r_start, r_end, goal, wanted, empty_root), - TP_STRUCT__entry( - __field(unsigned int, r_start) - __field(unsigned int, r_end) - __field(unsigned int, goal) - __field(unsigned int, wanted) - __field(int, empty_root) - ), - TP_fast_assign( - __entry->r_start = r_start; - __entry->r_end = r_end; - __entry->goal = goal; - __entry->wanted = wanted; - __entry->empty_root = empty_root; - ), - TP_printk("%u %u %u %u %d", __entry->r_start, __entry->r_end, - __entry->goal, __entry->wanted, __entry->empty_root) -); - -DEFINE_OCFS2_UINT_UINT_EVENT(ocfs2_resv_find_window_prev); - -DEFINE_OCFS2_INT_INT_EVENT(ocfs2_resv_find_window_next); - -DEFINE_OCFS2_UINT_UINT_UINT_EVENT(ocfs2_cannibalize_resv_begin); - -TRACE_EVENT(ocfs2_cannibalize_resv_end, - TP_PROTO(unsigned int start, unsigned int end, unsigned int len, - unsigned int last_start, unsigned int last_len), - TP_ARGS(start, end, len, last_start, last_len), - TP_STRUCT__entry( - __field(unsigned int, start) - __field(unsigned int, end) - __field(unsigned int, len) - __field(unsigned int, last_start) - __field(unsigned int, last_len) - ), - TP_fast_assign( - __entry->start = start; - __entry->end = end; - __entry->len = len; - __entry->last_start = last_start; - __entry->last_len = last_len; - ), - TP_printk("%u %u %u %u %u", __entry->start, __entry->end, - __entry->len, __entry->last_start, __entry->last_len) -); - -DEFINE_OCFS2_UINT_UINT_EVENT(ocfs2_resmap_resv_bits); - -TRACE_EVENT(ocfs2_resmap_claimed_bits_begin, - TP_PROTO(unsigned int cstart, unsigned int cend, unsigned int clen, - unsigned int r_start, unsigned int r_end, unsigned int r_len, - unsigned int last_start, unsigned int last_len), - TP_ARGS(cstart, cend, clen, r_start, r_end, - r_len, last_start, last_len), - TP_STRUCT__entry( - __field(unsigned int, cstart) - __field(unsigned int, cend) - __field(unsigned int, clen) - __field(unsigned int, r_start) - __field(unsigned int, r_end) - __field(unsigned int, r_len) - __field(unsigned int, last_start) - __field(unsigned int, last_len) - ), - TP_fast_assign( - __entry->cstart = cstart; - __entry->cend = cend; - __entry->clen = clen; - __entry->r_start = r_start; - __entry->r_end = r_end; - __entry->r_len = r_len; - __entry->last_start = last_start; - __entry->last_len = last_len; - ), - TP_printk("%u %u %u %u %u %u %u %u", - __entry->cstart, __entry->cend, __entry->clen, - __entry->r_start, __entry->r_end, __entry->r_len, - __entry->last_start, __entry->last_len) -); - -TRACE_EVENT(ocfs2_resmap_claimed_bits_end, - TP_PROTO(unsigned int start, unsigned int end, unsigned int len, - unsigned int last_start, unsigned int last_len), - TP_ARGS(start, end, len, last_start, last_len), - TP_STRUCT__entry( - __field(unsigned int, start) - __field(unsigned int, end) - __field(unsigned int, len) - __field(unsigned int, last_start) - __field(unsigned int, last_len) - ), - TP_fast_assign( - __entry->start = start; - __entry->end = end; - __entry->len = len; - __entry->last_start = last_start; - __entry->last_len = last_len; - ), - TP_printk("%u %u %u %u %u", __entry->start, __entry->end, - __entry->len, __entry->last_start, __entry->last_len) -); - -/* End of trace events for fs/ocfs2/reservations.c. */ - -/* Trace events for fs/ocfs2/quota_local.c. */ - -DEFINE_OCFS2_ULL_UINT_EVENT(ocfs2_recover_local_quota_file); - -DEFINE_OCFS2_INT_EVENT(ocfs2_finish_quota_recovery); - -DEFINE_OCFS2_ULL_ULL_UINT_EVENT(olq_set_dquot); - -/* End of trace events for fs/ocfs2/quota_local.c. */ - -/* Trace events for fs/ocfs2/quota_global.c. */ - -DEFINE_OCFS2_ULL_EVENT(ocfs2_validate_quota_block); - -TRACE_EVENT(ocfs2_sync_dquot, - TP_PROTO(unsigned int dq_id, long long dqb_curspace, - long long spacechange, long long curinodes, - long long inodechange), - TP_ARGS(dq_id, dqb_curspace, spacechange, curinodes, inodechange), - TP_STRUCT__entry( - __field(unsigned int, dq_id) - __field(long long, dqb_curspace) - __field(long long, spacechange) - __field(long long, curinodes) - __field(long long, inodechange) - ), - TP_fast_assign( - __entry->dq_id = dq_id; - __entry->dqb_curspace = dqb_curspace; - __entry->spacechange = spacechange; - __entry->curinodes = curinodes; - __entry->inodechange = inodechange; - ), - TP_printk("%u %lld %lld %lld %lld", __entry->dq_id, - __entry->dqb_curspace, __entry->spacechange, - __entry->curinodes, __entry->inodechange) -); - -TRACE_EVENT(ocfs2_sync_dquot_helper, - TP_PROTO(unsigned int dq_id, unsigned int dq_type, unsigned long type, - const char *s_id), - TP_ARGS(dq_id, dq_type, type, s_id), - - TP_STRUCT__entry( - __field(unsigned int, dq_id) - __field(unsigned int, dq_type) - __field(unsigned long, type) - __string(s_id, s_id) - ), - TP_fast_assign( - __entry->dq_id = dq_id; - __entry->dq_type = dq_type; - __entry->type = type; - __assign_str(s_id, s_id); - ), - TP_printk("%u %u %lu %s", __entry->dq_id, __entry->dq_type, - __entry->type, __get_str(s_id)) -); - -DEFINE_OCFS2_UINT_INT_EVENT(ocfs2_write_dquot); - -DEFINE_OCFS2_UINT_INT_EVENT(ocfs2_release_dquot); - -DEFINE_OCFS2_UINT_INT_EVENT(ocfs2_acquire_dquot); - -DEFINE_OCFS2_UINT_INT_EVENT(ocfs2_mark_dquot_dirty); - -/* End of trace events for fs/ocfs2/quota_global.c. */ - -/* Trace events for fs/ocfs2/dir.c. */ -DEFINE_OCFS2_INT_EVENT(ocfs2_search_dirblock); - -DEFINE_OCFS2_ULL_EVENT(ocfs2_validate_dir_block); - -DEFINE_OCFS2_POINTER_EVENT(ocfs2_find_entry_el); - -TRACE_EVENT(ocfs2_dx_dir_search, - TP_PROTO(unsigned long long ino, int namelen, const char *name, - unsigned int major_hash, unsigned int minor_hash, - unsigned long long blkno), - TP_ARGS(ino, namelen, name, major_hash, minor_hash, blkno), - TP_STRUCT__entry( - __field(unsigned long long, ino) - __field(int, namelen) - __string(name, name) - __field(unsigned int, major_hash) - __field(unsigned int,minor_hash) - __field(unsigned long long, blkno) - ), - TP_fast_assign( - __entry->ino = ino; - __entry->namelen = namelen; - __assign_str(name, name); - __entry->major_hash = major_hash; - __entry->minor_hash = minor_hash; - __entry->blkno = blkno; - ), - TP_printk("%llu %.*s %u %u %llu", __entry->ino, - __entry->namelen, __get_str(name), - __entry->major_hash, __entry->minor_hash, __entry->blkno) -); - -DEFINE_OCFS2_UINT_UINT_EVENT(ocfs2_dx_dir_search_leaf_info); - -DEFINE_OCFS2_ULL_INT_EVENT(ocfs2_delete_entry_dx); - -DEFINE_OCFS2_ULL_EVENT(ocfs2_readdir); - -TRACE_EVENT(ocfs2_find_files_on_disk, - TP_PROTO(int namelen, const char *name, void *blkno, - unsigned long long dir), - TP_ARGS(namelen, name, blkno, dir), - TP_STRUCT__entry( - __field(int, namelen) - __string(name, name) - __field(void *, blkno) - __field(unsigned long long, dir) - ), - TP_fast_assign( - __entry->namelen = namelen; - __assign_str(name, name); - __entry->blkno = blkno; - __entry->dir = dir; - ), - TP_printk("%.*s %p %llu", __entry->namelen, __get_str(name), - __entry->blkno, __entry->dir) -); - -TRACE_EVENT(ocfs2_check_dir_for_entry, - TP_PROTO(unsigned long long dir, int namelen, const char *name), - TP_ARGS(dir, namelen, name), - TP_STRUCT__entry( - __field(unsigned long long, dir) - __field(int, namelen) - __string(name, name) - ), - TP_fast_assign( - __entry->dir = dir; - __entry->namelen = namelen; - __assign_str(name, name); - ), - TP_printk("%llu %.*s", __entry->dir, - __entry->namelen, __get_str(name)) -); - -DEFINE_OCFS2_ULL_ULL_EVENT(ocfs2_dx_dir_attach_index); - -DEFINE_OCFS2_ULL_ULL_UINT_EVENT(ocfs2_dx_dir_format_cluster); - -TRACE_EVENT(ocfs2_dx_dir_index_root_block, - TP_PROTO(unsigned long long dir, - unsigned int major_hash, unsigned int minor_hash, - int namelen, const char *name, unsigned int num_used), - TP_ARGS(dir, major_hash, minor_hash, namelen, name, num_used), - TP_STRUCT__entry( - __field(unsigned long long, dir) - __field(unsigned int, major_hash) - __field(unsigned int, minor_hash) - __field(int, namelen) - __string(name, name) - __field(unsigned int, num_used) - ), - TP_fast_assign( - __entry->dir = dir; - __entry->major_hash = major_hash; - __entry->minor_hash = minor_hash; - __entry->namelen = namelen; - __assign_str(name, name); - __entry->num_used = num_used; - ), - TP_printk("%llu %x %x %.*s %u", __entry->dir, - __entry->major_hash, __entry->minor_hash, - __entry->namelen, __get_str(name), __entry->num_used) -); - -DEFINE_OCFS2_ULL_ULL_EVENT(ocfs2_extend_dir); - -DEFINE_OCFS2_ULL_ULL_UINT_EVENT(ocfs2_dx_dir_rebalance); - -DEFINE_OCFS2_UINT_UINT_UINT_EVENT(ocfs2_dx_dir_rebalance_split); - -DEFINE_OCFS2_ULL_INT_EVENT(ocfs2_prepare_dir_for_insert); - -/* End of trace events for fs/ocfs2/dir.c. */ - -/* Trace events for fs/ocfs2/namei.c. */ - -DECLARE_EVENT_CLASS(ocfs2__dentry_ops, - TP_PROTO(void *dir, void *dentry, int name_len, const char *name, - unsigned long long dir_blkno, unsigned long long extra), - TP_ARGS(dir, dentry, name_len, name, dir_blkno, extra), - TP_STRUCT__entry( - __field(void *, dir) - __field(void *, dentry) - __field(int, name_len) - __string(name, name) - __field(unsigned long long, dir_blkno) - __field(unsigned long long, extra) - ), - TP_fast_assign( - __entry->dir = dir; - __entry->dentry = dentry; - __entry->name_len = name_len; - __assign_str(name, name); - __entry->dir_blkno = dir_blkno; - __entry->extra = extra; - ), - TP_printk("%p %p %.*s %llu %llu", __entry->dir, __entry->dentry, - __entry->name_len, __get_str(name), - __entry->dir_blkno, __entry->extra) -); - -#define DEFINE_OCFS2_DENTRY_OPS(name) \ -DEFINE_EVENT(ocfs2__dentry_ops, name, \ -TP_PROTO(void *dir, void *dentry, int name_len, const char *name, \ - unsigned long long dir_blkno, unsigned long long extra), \ - TP_ARGS(dir, dentry, name_len, name, dir_blkno, extra)) - -DEFINE_OCFS2_DENTRY_OPS(ocfs2_lookup); - -DEFINE_OCFS2_DENTRY_OPS(ocfs2_mkdir); - -DEFINE_OCFS2_DENTRY_OPS(ocfs2_create); - -DEFINE_OCFS2_DENTRY_OPS(ocfs2_unlink); - -DEFINE_OCFS2_DENTRY_OPS(ocfs2_symlink_create); - -DEFINE_OCFS2_DENTRY_OPS(ocfs2_mv_orphaned_inode_to_new); - -DEFINE_OCFS2_POINTER_EVENT(ocfs2_lookup_ret); - -TRACE_EVENT(ocfs2_mknod, - TP_PROTO(void *dir, void *dentry, int name_len, const char *name, - unsigned long long dir_blkno, unsigned long dev, int mode), - TP_ARGS(dir, dentry, name_len, name, dir_blkno, dev, mode), - TP_STRUCT__entry( - __field(void *, dir) - __field(void *, dentry) - __field(int, name_len) - __string(name, name) - __field(unsigned long long, dir_blkno) - __field(unsigned long, dev) - __field(int, mode) - ), - TP_fast_assign( - __entry->dir = dir; - __entry->dentry = dentry; - __entry->name_len = name_len; - __assign_str(name, name); - __entry->dir_blkno = dir_blkno; - __entry->dev = dev; - __entry->mode = mode; - ), - TP_printk("%p %p %.*s %llu %lu %d", __entry->dir, __entry->dentry, - __entry->name_len, __get_str(name), - __entry->dir_blkno, __entry->dev, __entry->mode) -); - -TRACE_EVENT(ocfs2_link, - TP_PROTO(unsigned long long ino, int old_len, const char *old_name, - int name_len, const char *name), - TP_ARGS(ino, old_len, old_name, name_len, name), - TP_STRUCT__entry( - __field(unsigned long long, ino) - __field(int, old_len) - __string(old_name, old_name) - __field(int, name_len) - __string(name, name) - ), - TP_fast_assign( - __entry->ino = ino; - __entry->old_len = old_len; - __assign_str(old_name, old_name); - __entry->name_len = name_len; - __assign_str(name, name); - ), - TP_printk("%llu %.*s %.*s", __entry->ino, - __entry->old_len, __get_str(old_name), - __entry->name_len, __get_str(name)) -); - -DEFINE_OCFS2_ULL_ULL_UINT_EVENT(ocfs2_unlink_noent); - -DEFINE_OCFS2_ULL_ULL_EVENT(ocfs2_double_lock); - -DEFINE_OCFS2_ULL_ULL_EVENT(ocfs2_double_lock_end); - -TRACE_EVENT(ocfs2_rename, - TP_PROTO(void *old_dir, void *old_dentry, - void *new_dir, void *new_dentry, - int old_len, const char *old_name, - int new_len, const char *new_name), - TP_ARGS(old_dir, old_dentry, new_dir, new_dentry, - old_len, old_name, new_len, new_name), - TP_STRUCT__entry( - __field(void *, old_dir) - __field(void *, old_dentry) - __field(void *, new_dir) - __field(void *, new_dentry) - __field(int, old_len) - __string(old_name, old_name) - __field(int, new_len) - __string(new_name, new_name) - ), - TP_fast_assign( - __entry->old_dir = old_dir; - __entry->old_dentry = old_dentry; - __entry->new_dir = new_dir; - __entry->new_dentry = new_dentry; - __entry->old_len = old_len; - __assign_str(old_name, old_name); - __entry->new_len = new_len; - __assign_str(new_name, new_name); - ), - TP_printk("%p %p %p %p %.*s %.*s", - __entry->old_dir, __entry->old_dentry, - __entry->new_dir, __entry->new_dentry, - __entry->old_len, __get_str(old_name), - __entry->new_len, __get_str(new_name)) -); - -TRACE_EVENT(ocfs2_rename_target_exists, - TP_PROTO(int new_len, const char *new_name), - TP_ARGS(new_len, new_name), - TP_STRUCT__entry( - __field(int, new_len) - __string(new_name, new_name) - ), - TP_fast_assign( - __entry->new_len = new_len; - __assign_str(new_name, new_name); - ), - TP_printk("%.*s", __entry->new_len, __get_str(new_name)) -); - -DEFINE_OCFS2_ULL_ULL_UINT_EVENT(ocfs2_rename_disagree); - -TRACE_EVENT(ocfs2_rename_over_existing, - TP_PROTO(unsigned long long new_blkno, void *new_bh, - unsigned long long newdi_blkno), - TP_ARGS(new_blkno, new_bh, newdi_blkno), - TP_STRUCT__entry( - __field(unsigned long long, new_blkno) - __field(void *, new_bh) - __field(unsigned long long, newdi_blkno) - ), - TP_fast_assign( - __entry->new_blkno = new_blkno; - __entry->new_bh = new_bh; - __entry->newdi_blkno = newdi_blkno; - ), - TP_printk("%llu %p %llu", __entry->new_blkno, __entry->new_bh, - __entry->newdi_blkno) -); - -DEFINE_OCFS2_ULL_ULL_UINT_EVENT(ocfs2_create_symlink_data); - -TRACE_EVENT(ocfs2_symlink_begin, - TP_PROTO(void *dir, void *dentry, const char *symname, - int len, const char *name), - TP_ARGS(dir, dentry, symname, len, name), - TP_STRUCT__entry( - __field(void *, dir) - __field(void *, dentry) - __field(const char *, symname) - __field(int, len) - __string(name, name) - ), - TP_fast_assign( - __entry->dir = dir; - __entry->dentry = dentry; - __entry->symname = symname; - __entry->len = len; - __assign_str(name, name); - ), - TP_printk("%p %p %s %.*s", __entry->dir, __entry->dentry, - __entry->symname, __entry->len, __get_str(name)) -); - -TRACE_EVENT(ocfs2_blkno_stringify, - TP_PROTO(unsigned long long blkno, const char *name, int namelen), - TP_ARGS(blkno, name, namelen), - TP_STRUCT__entry( - __field(unsigned long long, blkno) - __string(name, name) - __field(int, namelen) - ), - TP_fast_assign( - __entry->blkno = blkno; - __assign_str(name, name); - __entry->namelen = namelen; - ), - TP_printk("%llu %s %d", __entry->blkno, __get_str(name), - __entry->namelen) -); - -DEFINE_OCFS2_ULL_EVENT(ocfs2_orphan_add_begin); - -DEFINE_OCFS2_ULL_UINT_EVENT(ocfs2_orphan_add_end); - -TRACE_EVENT(ocfs2_orphan_del, - TP_PROTO(unsigned long long dir, const char *name, int namelen), - TP_ARGS(dir, name, namelen), - TP_STRUCT__entry( - __field(unsigned long long, dir) - __string(name, name) - __field(int, namelen) - ), - TP_fast_assign( - __entry->dir = dir; - __assign_str(name, name); - __entry->namelen = namelen; - ), - TP_printk("%llu %s %d", __entry->dir, __get_str(name), - __entry->namelen) -); - -/* End of trace events for fs/ocfs2/namei.c. */ - -/* Trace events for fs/ocfs2/dcache.c. */ - -TRACE_EVENT(ocfs2_dentry_revalidate, - TP_PROTO(void *dentry, int len, const char *name), - TP_ARGS(dentry, len, name), - TP_STRUCT__entry( - __field(void *, dentry) - __field(int, len) - __string(name, name) - ), - TP_fast_assign( - __entry->dentry = dentry; - __entry->len = len; - __assign_str(name, name); - ), - TP_printk("%p %.*s", __entry->dentry, __entry->len, __get_str(name)) -); - -TRACE_EVENT(ocfs2_dentry_revalidate_negative, - TP_PROTO(int len, const char *name, unsigned long pgen, - unsigned long gen), - TP_ARGS(len, name, pgen, gen), - TP_STRUCT__entry( - __field(int, len) - __string(name, name) - __field(unsigned long, pgen) - __field(unsigned long, gen) - ), - TP_fast_assign( - __entry->len = len; - __assign_str(name, name); - __entry->pgen = pgen; - __entry->gen = gen; - ), - TP_printk("%.*s %lu %lu", __entry->len, __get_str(name), - __entry->pgen, __entry->gen) -); - -DEFINE_OCFS2_ULL_EVENT(ocfs2_dentry_revalidate_delete); - -DEFINE_OCFS2_ULL_INT_EVENT(ocfs2_dentry_revalidate_orphaned); - -DEFINE_OCFS2_ULL_EVENT(ocfs2_dentry_revalidate_nofsdata); - -DEFINE_OCFS2_INT_EVENT(ocfs2_dentry_revalidate_ret); - -TRACE_EVENT(ocfs2_find_local_alias, - TP_PROTO(int len, const char *name), - TP_ARGS(len, name), - TP_STRUCT__entry( - __field(int, len) - __string(name, name) - ), - TP_fast_assign( - __entry->len = len; - __assign_str(name, name); - ), - TP_printk("%.*s", __entry->len, __get_str(name)) -); - -TRACE_EVENT(ocfs2_dentry_attach_lock, - TP_PROTO(int len, const char *name, - unsigned long long parent, void *fsdata), - TP_ARGS(len, name, parent, fsdata), - TP_STRUCT__entry( - __field(int, len) - __string(name, name) - __field(unsigned long long, parent) - __field(void *, fsdata) - ), - TP_fast_assign( - __entry->len = len; - __assign_str(name, name); - __entry->parent = parent; - __entry->fsdata = fsdata; - ), - TP_printk("%.*s %llu %p", __entry->len, __get_str(name), - __entry->parent, __entry->fsdata) -); - -TRACE_EVENT(ocfs2_dentry_attach_lock_found, - TP_PROTO(const char *name, unsigned long long parent, - unsigned long long ino), - TP_ARGS(name, parent, ino), - TP_STRUCT__entry( - __string(name, name) - __field(unsigned long long, parent) - __field(unsigned long long, ino) - ), - TP_fast_assign( - __assign_str(name, name); - __entry->parent = parent; - __entry->ino = ino; - ), - TP_printk("%s %llu %llu", __get_str(name), __entry->parent, __entry->ino) -); -/* End of trace events for fs/ocfs2/dcache.c. */ - -/* Trace events for fs/ocfs2/export.c. */ - -TRACE_EVENT(ocfs2_get_dentry_begin, - TP_PROTO(void *sb, void *handle, unsigned long long blkno), - TP_ARGS(sb, handle, blkno), - TP_STRUCT__entry( - __field(void *, sb) - __field(void *, handle) - __field(unsigned long long, blkno) - ), - TP_fast_assign( - __entry->sb = sb; - __entry->handle = handle; - __entry->blkno = blkno; - ), - TP_printk("%p %p %llu", __entry->sb, __entry->handle, __entry->blkno) -); - -DEFINE_OCFS2_INT_INT_EVENT(ocfs2_get_dentry_test_bit); - -DEFINE_OCFS2_ULL_UINT_EVENT(ocfs2_get_dentry_stale); - -DEFINE_OCFS2_ULL_UINT_UINT_EVENT(ocfs2_get_dentry_generation); - -DEFINE_OCFS2_POINTER_EVENT(ocfs2_get_dentry_end); - -TRACE_EVENT(ocfs2_get_parent, - TP_PROTO(void *child, int len, const char *name, - unsigned long long ino), - TP_ARGS(child, len, name, ino), - TP_STRUCT__entry( - __field(void *, child) - __field(int, len) - __string(name, name) - __field(unsigned long long, ino) - ), - TP_fast_assign( - __entry->child = child; - __entry->len = len; - __assign_str(name, name); - __entry->ino = ino; - ), - TP_printk("%p %.*s %llu", __entry->child, __entry->len, - __get_str(name), __entry->ino) -); - -DEFINE_OCFS2_POINTER_EVENT(ocfs2_get_parent_end); - -TRACE_EVENT(ocfs2_encode_fh_begin, - TP_PROTO(void *dentry, int name_len, const char *name, - void *fh, int len, int connectable), - TP_ARGS(dentry, name_len, name, fh, len, connectable), - TP_STRUCT__entry( - __field(void *, dentry) - __field(int, name_len) - __string(name, name) - __field(void *, fh) - __field(int, len) - __field(int, connectable) - ), - TP_fast_assign( - __entry->dentry = dentry; - __entry->name_len = name_len; - __assign_str(name, name); - __entry->fh = fh; - __entry->len = len; - __entry->connectable = connectable; - ), - TP_printk("%p %.*s %p %d %d", __entry->dentry, __entry->name_len, - __get_str(name), __entry->fh, __entry->len, - __entry->connectable) -); - -DEFINE_OCFS2_ULL_UINT_EVENT(ocfs2_encode_fh_self); - -DEFINE_OCFS2_ULL_UINT_EVENT(ocfs2_encode_fh_parent); - -DEFINE_OCFS2_INT_EVENT(ocfs2_encode_fh_type); - -/* End of trace events for fs/ocfs2/export.c. */ - -/* Trace events for fs/ocfs2/journal.c. */ - -DEFINE_OCFS2_UINT_EVENT(ocfs2_commit_cache_begin); - -DEFINE_OCFS2_ULL_UINT_EVENT(ocfs2_commit_cache_end); - -DEFINE_OCFS2_INT_INT_EVENT(ocfs2_extend_trans); - -DEFINE_OCFS2_INT_EVENT(ocfs2_extend_trans_restart); - -DEFINE_OCFS2_ULL_ULL_UINT_UINT_EVENT(ocfs2_journal_access); - -DEFINE_OCFS2_ULL_EVENT(ocfs2_journal_dirty); - -DEFINE_OCFS2_ULL_ULL_UINT_EVENT(ocfs2_journal_init); - -DEFINE_OCFS2_UINT_EVENT(ocfs2_journal_init_maxlen); - -DEFINE_OCFS2_INT_EVENT(ocfs2_journal_shutdown); - -DEFINE_OCFS2_POINTER_EVENT(ocfs2_journal_shutdown_wait); - -DEFINE_OCFS2_ULL_EVENT(ocfs2_complete_recovery); - -DEFINE_OCFS2_INT_EVENT(ocfs2_complete_recovery_end); - -TRACE_EVENT(ocfs2_complete_recovery_slot, - TP_PROTO(int slot, unsigned long long la_ino, - unsigned long long tl_ino, void *qrec), - TP_ARGS(slot, la_ino, tl_ino, qrec), - TP_STRUCT__entry( - __field(int, slot) - __field(unsigned long long, la_ino) - __field(unsigned long long, tl_ino) - __field(void *, qrec) - ), - TP_fast_assign( - __entry->slot = slot; - __entry->la_ino = la_ino; - __entry->tl_ino = tl_ino; - __entry->qrec = qrec; - ), - TP_printk("%d %llu %llu %p", __entry->slot, __entry->la_ino, - __entry->tl_ino, __entry->qrec) -); - -DEFINE_OCFS2_INT_INT_EVENT(ocfs2_recovery_thread_node); - -DEFINE_OCFS2_INT_EVENT(ocfs2_recovery_thread_end); - -TRACE_EVENT(ocfs2_recovery_thread, - TP_PROTO(int node_num, int osb_node_num, int disable, - void *recovery_thread, int map_set), - TP_ARGS(node_num, osb_node_num, disable, recovery_thread, map_set), - TP_STRUCT__entry( - __field(int, node_num) - __field(int, osb_node_num) - __field(int,disable) - __field(void *, recovery_thread) - __field(int,map_set) - ), - TP_fast_assign( - __entry->node_num = node_num; - __entry->osb_node_num = osb_node_num; - __entry->disable = disable; - __entry->recovery_thread = recovery_thread; - __entry->map_set = map_set; - ), - TP_printk("%d %d %d %p %d", __entry->node_num, - __entry->osb_node_num, __entry->disable, - __entry->recovery_thread, __entry->map_set) -); - -DEFINE_OCFS2_UINT_UINT_UINT_EVENT(ocfs2_replay_journal_recovered); - -DEFINE_OCFS2_INT_EVENT(ocfs2_replay_journal_lock_err); - -DEFINE_OCFS2_INT_EVENT(ocfs2_replay_journal_skip); - -DEFINE_OCFS2_UINT_UINT_UINT_EVENT(ocfs2_recover_node); - -DEFINE_OCFS2_UINT_UINT_EVENT(ocfs2_recover_node_skip); - -DEFINE_OCFS2_UINT_UINT_EVENT(ocfs2_mark_dead_nodes); - -DEFINE_OCFS2_UINT_UINT_UINT_EVENT(ocfs2_queue_orphan_scan_begin); - -DEFINE_OCFS2_UINT_UINT_UINT_EVENT(ocfs2_queue_orphan_scan_end); - -DEFINE_OCFS2_ULL_EVENT(ocfs2_orphan_filldir); - -DEFINE_OCFS2_INT_EVENT(ocfs2_recover_orphans); - -DEFINE_OCFS2_ULL_EVENT(ocfs2_recover_orphans_iput); - -DEFINE_OCFS2_INT_EVENT(ocfs2_wait_on_mount); - -/* End of trace events for fs/ocfs2/journal.c. */ - -/* Trace events for fs/ocfs2/buffer_head_io.c. */ - -DEFINE_OCFS2_ULL_UINT_EVENT(ocfs2_read_blocks_sync); - -DEFINE_OCFS2_ULL_EVENT(ocfs2_read_blocks_sync_jbd); - -DEFINE_OCFS2_ULL_ULL_EVENT(ocfs2_read_blocks_from_disk); - -DEFINE_OCFS2_ULL_INT_INT_INT_EVENT(ocfs2_read_blocks_bh); - -DEFINE_OCFS2_ULL_INT_INT_INT_EVENT(ocfs2_read_blocks_end); - -TRACE_EVENT(ocfs2_write_block, - TP_PROTO(unsigned long long block, void *ci), - TP_ARGS(block, ci), - TP_STRUCT__entry( - __field(unsigned long long, block) - __field(void *, ci) - ), - TP_fast_assign( - __entry->block = block; - __entry->ci = ci; - ), - TP_printk("%llu %p", __entry->block, __entry->ci) -); - -TRACE_EVENT(ocfs2_read_blocks_begin, - TP_PROTO(void *ci, unsigned long long block, - unsigned int nr, int flags), - TP_ARGS(ci, block, nr, flags), - TP_STRUCT__entry( - __field(void *, ci) - __field(unsigned long long, block) - __field(unsigned int, nr) - __field(int, flags) - ), - TP_fast_assign( - __entry->ci = ci; - __entry->block = block; - __entry->nr = nr; - __entry->flags = flags; - ), - TP_printk("%p %llu %u %d", __entry->ci, __entry->block, - __entry->nr, __entry->flags) -); - -/* End of trace events for fs/ocfs2/buffer_head_io.c. */ - -/* Trace events for fs/ocfs2/uptodate.c. */ - -DEFINE_OCFS2_ULL_EVENT(ocfs2_purge_copied_metadata_tree); - -DEFINE_OCFS2_ULL_UINT_UINT_EVENT(ocfs2_metadata_cache_purge); - -DEFINE_OCFS2_ULL_ULL_UINT_EVENT(ocfs2_buffer_cached_begin); - -TRACE_EVENT(ocfs2_buffer_cached_end, - TP_PROTO(int index, void *item), - TP_ARGS(index, item), - TP_STRUCT__entry( - __field(int, index) - __field(void *, item) - ), - TP_fast_assign( - __entry->index = index; - __entry->item = item; - ), - TP_printk("%d %p", __entry->index, __entry->item) -); - -DEFINE_OCFS2_ULL_ULL_UINT_EVENT(ocfs2_append_cache_array); - -DEFINE_OCFS2_ULL_ULL_UINT_EVENT(ocfs2_insert_cache_tree); - -DEFINE_OCFS2_ULL_UINT_UINT_EVENT(ocfs2_expand_cache); - -DEFINE_OCFS2_ULL_UINT_UINT_EVENT(ocfs2_set_buffer_uptodate); - -DEFINE_OCFS2_ULL_ULL_EVENT(ocfs2_set_buffer_uptodate_begin); - -DEFINE_OCFS2_ULL_UINT_UINT_EVENT(ocfs2_remove_metadata_array); - -DEFINE_OCFS2_ULL_ULL_EVENT(ocfs2_remove_metadata_tree); - -DEFINE_OCFS2_ULL_ULL_UINT_UINT_EVENT(ocfs2_remove_block_from_cache); - -/* End of trace events for fs/ocfs2/uptodate.c. */ -#endif /* _TRACE_OCFS2_H */ - -/* This part must be outside protection */ -#undef TRACE_INCLUDE_PATH -#define TRACE_INCLUDE_PATH . -#define TRACE_INCLUDE_FILE ocfs2_trace -#include diff --git a/trunk/fs/ocfs2/quota_global.c b/trunk/fs/ocfs2/quota_global.c index 279aef68025b..a73f64166481 100644 --- a/trunk/fs/ocfs2/quota_global.c +++ b/trunk/fs/ocfs2/quota_global.c @@ -11,6 +11,7 @@ #include #include +#define MLOG_MASK_PREFIX ML_QUOTA #include #include "ocfs2_fs.h" @@ -26,7 +27,6 @@ #include "super.h" #include "buffer_head_io.h" #include "quota.h" -#include "ocfs2_trace.h" /* * Locking of quotas with OCFS2 is rather complex. Here are rules that @@ -130,7 +130,8 @@ int ocfs2_validate_quota_block(struct super_block *sb, struct buffer_head *bh) struct ocfs2_disk_dqtrailer *dqt = ocfs2_block_dqtrailer(sb->s_blocksize, bh->b_data); - trace_ocfs2_validate_quota_block((unsigned long long)bh->b_blocknr); + mlog(0, "Validating quota block %llu\n", + (unsigned long long)bh->b_blocknr); BUG_ON(!buffer_uptodate(bh)); @@ -340,6 +341,8 @@ int ocfs2_global_read_info(struct super_block *sb, int type) u64 pcount; int status; + mlog_entry_void(); + /* Read global header */ gqinode = ocfs2_get_system_file_inode(OCFS2_SB(sb), ino[type], OCFS2_INVALID_SLOT); @@ -399,8 +402,7 @@ int ocfs2_global_read_info(struct super_block *sb, int type) msecs_to_jiffies(oinfo->dqi_syncms)); out_err: - if (status) - mlog_errno(status); + mlog_exit(status); return status; out_unlock: ocfs2_unlock_global_qf(oinfo, 0); @@ -506,10 +508,9 @@ int __ocfs2_sync_dquot(struct dquot *dquot, int freeing) olditime = dquot->dq_dqb.dqb_itime; oldbtime = dquot->dq_dqb.dqb_btime; ocfs2_global_disk2memdqb(dquot, &dqblk); - trace_ocfs2_sync_dquot(dquot->dq_id, dquot->dq_dqb.dqb_curspace, - (long long)spacechange, - dquot->dq_dqb.dqb_curinodes, - (long long)inodechange); + mlog(0, "Syncing global dquot %u space %lld+%lld, inodes %lld+%lld\n", + dquot->dq_id, dquot->dq_dqb.dqb_curspace, (long long)spacechange, + dquot->dq_dqb.dqb_curinodes, (long long)inodechange); if (!test_bit(DQ_LASTSET_B + QIF_SPACE_B, &dquot->dq_flags)) dquot->dq_dqb.dqb_curspace += spacechange; if (!test_bit(DQ_LASTSET_B + QIF_INODES_B, &dquot->dq_flags)) @@ -593,8 +594,8 @@ static int ocfs2_sync_dquot_helper(struct dquot *dquot, unsigned long type) struct ocfs2_super *osb = OCFS2_SB(sb); int status = 0; - trace_ocfs2_sync_dquot_helper(dquot->dq_id, dquot->dq_type, - type, sb->s_id); + mlog_entry("id=%u qtype=%u type=%lu device=%s\n", dquot->dq_id, + dquot->dq_type, type, sb->s_id); if (type != dquot->dq_type) goto out; status = ocfs2_lock_global_qf(oinfo, 1); @@ -620,6 +621,7 @@ static int ocfs2_sync_dquot_helper(struct dquot *dquot, unsigned long type) out_ilock: ocfs2_unlock_global_qf(oinfo, 1); out: + mlog_exit(status); return status; } @@ -645,7 +647,7 @@ static int ocfs2_write_dquot(struct dquot *dquot) struct ocfs2_super *osb = OCFS2_SB(dquot->dq_sb); int status = 0; - trace_ocfs2_write_dquot(dquot->dq_id, dquot->dq_type); + mlog_entry("id=%u, type=%d", dquot->dq_id, dquot->dq_type); handle = ocfs2_start_trans(osb, OCFS2_QWRITE_CREDITS); if (IS_ERR(handle)) { @@ -658,6 +660,7 @@ static int ocfs2_write_dquot(struct dquot *dquot) mutex_unlock(&sb_dqopt(dquot->dq_sb)->dqio_mutex); ocfs2_commit_trans(osb, handle); out: + mlog_exit(status); return status; } @@ -683,7 +686,7 @@ static int ocfs2_release_dquot(struct dquot *dquot) struct ocfs2_super *osb = OCFS2_SB(dquot->dq_sb); int status = 0; - trace_ocfs2_release_dquot(dquot->dq_id, dquot->dq_type); + mlog_entry("id=%u, type=%d", dquot->dq_id, dquot->dq_type); mutex_lock(&dquot->dq_lock); /* Check whether we are not racing with some other dqget() */ @@ -719,8 +722,7 @@ static int ocfs2_release_dquot(struct dquot *dquot) ocfs2_unlock_global_qf(oinfo, 1); out: mutex_unlock(&dquot->dq_lock); - if (status) - mlog_errno(status); + mlog_exit(status); return status; } @@ -741,7 +743,7 @@ static int ocfs2_acquire_dquot(struct dquot *dquot) int need_alloc = ocfs2_global_qinit_alloc(sb, type); handle_t *handle; - trace_ocfs2_acquire_dquot(dquot->dq_id, type); + mlog_entry("id=%u, type=%d", dquot->dq_id, type); mutex_lock(&dquot->dq_lock); /* * We need an exclusive lock, because we're going to update use count @@ -807,8 +809,7 @@ static int ocfs2_acquire_dquot(struct dquot *dquot) set_bit(DQ_ACTIVE_B, &dquot->dq_flags); out: mutex_unlock(&dquot->dq_lock); - if (status) - mlog_errno(status); + mlog_exit(status); return status; } @@ -828,7 +829,7 @@ static int ocfs2_mark_dquot_dirty(struct dquot *dquot) handle_t *handle; struct ocfs2_super *osb = OCFS2_SB(sb); - trace_ocfs2_mark_dquot_dirty(dquot->dq_id, type); + mlog_entry("id=%u, type=%d", dquot->dq_id, type); /* In case user set some limits, sync dquot immediately to global * quota file so that information propagates quicker */ @@ -865,8 +866,7 @@ static int ocfs2_mark_dquot_dirty(struct dquot *dquot) out_ilock: ocfs2_unlock_global_qf(oinfo, 1); out: - if (status) - mlog_errno(status); + mlog_exit(status); return status; } @@ -877,6 +877,8 @@ static int ocfs2_write_info(struct super_block *sb, int type) int status = 0; struct ocfs2_mem_dqinfo *oinfo = sb_dqinfo(sb, type)->dqi_priv; + mlog_entry_void(); + status = ocfs2_lock_global_qf(oinfo, 1); if (status < 0) goto out; @@ -891,8 +893,7 @@ static int ocfs2_write_info(struct super_block *sb, int type) out_ilock: ocfs2_unlock_global_qf(oinfo, 1); out: - if (status) - mlog_errno(status); + mlog_exit(status); return status; } diff --git a/trunk/fs/ocfs2/quota_local.c b/trunk/fs/ocfs2/quota_local.c index dc8007fc9247..dc78764ccc4c 100644 --- a/trunk/fs/ocfs2/quota_local.c +++ b/trunk/fs/ocfs2/quota_local.c @@ -8,6 +8,7 @@ #include #include +#define MLOG_MASK_PREFIX ML_QUOTA #include #include "ocfs2_fs.h" @@ -22,7 +23,6 @@ #include "quota.h" #include "uptodate.h" #include "super.h" -#include "ocfs2_trace.h" /* Number of local quota structures per block */ static inline unsigned int ol_quota_entries_per_block(struct super_block *sb) @@ -475,7 +475,7 @@ static int ocfs2_recover_local_quota_file(struct inode *lqinode, struct ocfs2_recovery_chunk *rchunk, *next; qsize_t spacechange, inodechange; - trace_ocfs2_recover_local_quota_file((unsigned long)lqinode->i_ino, type); + mlog_entry("ino=%lu type=%u", (unsigned long)lqinode->i_ino, type); list_for_each_entry_safe(rchunk, next, &(rec->r_list[type]), rc_list) { chunk = rchunk->rc_chunk; @@ -575,8 +575,7 @@ static int ocfs2_recover_local_quota_file(struct inode *lqinode, } if (status < 0) free_recovery_list(&(rec->r_list[type])); - if (status) - mlog_errno(status); + mlog_exit(status); return status; } @@ -601,7 +600,7 @@ int ocfs2_finish_quota_recovery(struct ocfs2_super *osb, for (type = 0; type < MAXQUOTAS; type++) { if (list_empty(&(rec->r_list[type]))) continue; - trace_ocfs2_finish_quota_recovery(slot_num); + mlog(0, "Recovering quota in slot %d\n", slot_num); lqinode = ocfs2_get_system_file_inode(osb, ino[type], slot_num); if (!lqinode) { status = -ENOENT; @@ -883,10 +882,9 @@ static void olq_set_dquot(struct buffer_head *bh, void *private) dqblk->dqb_inodemod = cpu_to_le64(od->dq_dquot.dq_dqb.dqb_curinodes - od->dq_originodes); spin_unlock(&dq_data_lock); - trace_olq_set_dquot( - (unsigned long long)le64_to_cpu(dqblk->dqb_spacemod), - (unsigned long long)le64_to_cpu(dqblk->dqb_inodemod), - od->dq_dquot.dq_id); + mlog(0, "Writing local dquot %u space %lld inodes %lld\n", + od->dq_dquot.dq_id, (long long)le64_to_cpu(dqblk->dqb_spacemod), + (long long)le64_to_cpu(dqblk->dqb_inodemod)); } /* Write dquot to local quota file */ diff --git a/trunk/fs/ocfs2/refcounttree.c b/trunk/fs/ocfs2/refcounttree.c index 5d32749c896d..c384d634872a 100644 --- a/trunk/fs/ocfs2/refcounttree.c +++ b/trunk/fs/ocfs2/refcounttree.c @@ -16,6 +16,7 @@ */ #include +#define MLOG_MASK_PREFIX ML_REFCOUNT #include #include "ocfs2.h" #include "inode.h" @@ -33,7 +34,6 @@ #include "aops.h" #include "xattr.h" #include "namei.h" -#include "ocfs2_trace.h" #include #include @@ -84,7 +84,8 @@ static int ocfs2_validate_refcount_block(struct super_block *sb, struct ocfs2_refcount_block *rb = (struct ocfs2_refcount_block *)bh->b_data; - trace_ocfs2_validate_refcount_block((unsigned long long)bh->b_blocknr); + mlog(0, "Validating refcount block %llu\n", + (unsigned long long)bh->b_blocknr); BUG_ON(!buffer_uptodate(bh)); @@ -544,8 +545,8 @@ void ocfs2_purge_refcount_trees(struct ocfs2_super *osb) while ((node = rb_last(root)) != NULL) { tree = rb_entry(node, struct ocfs2_refcount_tree, rf_node); - trace_ocfs2_purge_refcount_trees( - (unsigned long long) tree->rf_blkno); + mlog(0, "Purge tree %llu\n", + (unsigned long long) tree->rf_blkno); rb_erase(&tree->rf_node, root); ocfs2_free_refcount_tree(tree); @@ -574,8 +575,7 @@ static int ocfs2_create_refcount_tree(struct inode *inode, BUG_ON(oi->ip_dyn_features & OCFS2_HAS_REFCOUNT_FL); - trace_ocfs2_create_refcount_tree( - (unsigned long long)OCFS2_I(inode)->ip_blkno); + mlog(0, "create tree for inode %lu\n", inode->i_ino); ret = ocfs2_reserve_new_metadata_blocks(osb, 1, &meta_ac); if (ret) { @@ -646,7 +646,8 @@ static int ocfs2_create_refcount_tree(struct inode *inode, di->i_refcount_loc = cpu_to_le64(first_blkno); spin_unlock(&oi->ip_lock); - trace_ocfs2_create_refcount_tree_blkno((unsigned long long)first_blkno); + mlog(0, "created tree for inode %lu, refblock %llu\n", + inode->i_ino, (unsigned long long)first_blkno); ocfs2_journal_dirty(handle, di_bh); @@ -1255,9 +1256,8 @@ static int ocfs2_change_refcount_rec(handle_t *handle, goto out; } - trace_ocfs2_change_refcount_rec( - (unsigned long long)ocfs2_metadata_cache_owner(ci), - index, le32_to_cpu(rec->r_refcount), change); + mlog(0, "change index %d, old count %u, change %d\n", index, + le32_to_cpu(rec->r_refcount), change); le32_add_cpu(&rec->r_refcount, change); if (!rec->r_refcount) { @@ -1353,8 +1353,8 @@ static int ocfs2_expand_inline_ref_root(handle_t *handle, ocfs2_journal_dirty(handle, ref_root_bh); - trace_ocfs2_expand_inline_ref_root((unsigned long long)blkno, - le16_to_cpu(new_rb->rf_records.rl_used)); + mlog(0, "new leaf block %llu, used %u\n", (unsigned long long)blkno, + le16_to_cpu(new_rb->rf_records.rl_used)); *ref_leaf_bh = new_bh; new_bh = NULL; @@ -1466,9 +1466,9 @@ static int ocfs2_divide_leaf_refcount_block(struct buffer_head *ref_leaf_bh, (struct ocfs2_refcount_block *)new_bh->b_data; struct ocfs2_refcount_list *new_rl = &new_rb->rf_records; - trace_ocfs2_divide_leaf_refcount_block( - (unsigned long long)ref_leaf_bh->b_blocknr, - le32_to_cpu(rl->rl_count), le32_to_cpu(rl->rl_used)); + mlog(0, "split old leaf refcount block %llu, count = %u, used = %u\n", + (unsigned long long)ref_leaf_bh->b_blocknr, + le32_to_cpu(rl->rl_count), le32_to_cpu(rl->rl_used)); /* * XXX: Improvement later. @@ -1601,8 +1601,8 @@ static int ocfs2_new_leaf_refcount_block(handle_t *handle, ocfs2_init_refcount_extent_tree(&ref_et, ci, ref_root_bh); - trace_ocfs2_new_leaf_refcount_block( - (unsigned long long)new_bh->b_blocknr, new_cpos); + mlog(0, "insert new leaf block %llu at %u\n", + (unsigned long long)new_bh->b_blocknr, new_cpos); /* Insert the new leaf block with the specific offset cpos. */ ret = ocfs2_insert_extent(handle, &ref_et, new_cpos, new_bh->b_blocknr, @@ -1794,10 +1794,11 @@ static int ocfs2_insert_refcount_rec(handle_t *handle, (le16_to_cpu(rf_list->rl_used) - index) * sizeof(struct ocfs2_refcount_rec)); - trace_ocfs2_insert_refcount_rec( - (unsigned long long)ref_leaf_bh->b_blocknr, index, - (unsigned long long)le64_to_cpu(rec->r_cpos), - le32_to_cpu(rec->r_clusters), le32_to_cpu(rec->r_refcount)); + mlog(0, "insert refcount record start %llu, len %u, count %u " + "to leaf block %llu at index %d\n", + (unsigned long long)le64_to_cpu(rec->r_cpos), + le32_to_cpu(rec->r_clusters), le32_to_cpu(rec->r_refcount), + (unsigned long long)ref_leaf_bh->b_blocknr, index); rf_list->rl_recs[index] = *rec; @@ -1849,12 +1850,10 @@ static int ocfs2_split_refcount_rec(handle_t *handle, BUG_ON(le32_to_cpu(rb->rf_flags) & OCFS2_REFCOUNT_TREE_FL); - trace_ocfs2_split_refcount_rec(le64_to_cpu(orig_rec->r_cpos), - le32_to_cpu(orig_rec->r_clusters), - le32_to_cpu(orig_rec->r_refcount), - le64_to_cpu(split_rec->r_cpos), - le32_to_cpu(split_rec->r_clusters), - le32_to_cpu(split_rec->r_refcount)); + mlog(0, "original r_pos %llu, cluster %u, split %llu, cluster %u\n", + le64_to_cpu(orig_rec->r_cpos), le32_to_cpu(orig_rec->r_clusters), + le64_to_cpu(split_rec->r_cpos), + le32_to_cpu(split_rec->r_clusters)); /* * If we just need to split the header or tail clusters, @@ -1968,11 +1967,12 @@ static int ocfs2_split_refcount_rec(handle_t *handle, if (split_rec->r_refcount) { rf_list->rl_recs[index] = *split_rec; - trace_ocfs2_split_refcount_rec_insert( - (unsigned long long)ref_leaf_bh->b_blocknr, index, - (unsigned long long)le64_to_cpu(split_rec->r_cpos), - le32_to_cpu(split_rec->r_clusters), - le32_to_cpu(split_rec->r_refcount)); + mlog(0, "insert refcount record start %llu, len %u, count %u " + "to leaf block %llu at index %d\n", + (unsigned long long)le64_to_cpu(split_rec->r_cpos), + le32_to_cpu(split_rec->r_clusters), + le32_to_cpu(split_rec->r_refcount), + (unsigned long long)ref_leaf_bh->b_blocknr, index); if (merge) ocfs2_refcount_rec_merge(rb, index); @@ -1997,7 +1997,7 @@ static int __ocfs2_increase_refcount(handle_t *handle, struct ocfs2_refcount_rec rec; unsigned int set_len = 0; - trace_ocfs2_increase_refcount_begin( + mlog(0, "Tree owner %llu, add refcount start %llu, len %u\n", (unsigned long long)ocfs2_metadata_cache_owner(ci), (unsigned long long)cpos, len); @@ -2024,9 +2024,9 @@ static int __ocfs2_increase_refcount(handle_t *handle, */ if (rec.r_refcount && le64_to_cpu(rec.r_cpos) == cpos && set_len <= len) { - trace_ocfs2_increase_refcount_change( - (unsigned long long)cpos, set_len, - le32_to_cpu(rec.r_refcount)); + mlog(0, "increase refcount rec, start %llu, len %u, " + "count %u\n", (unsigned long long)cpos, set_len, + le32_to_cpu(rec.r_refcount)); ret = ocfs2_change_refcount_rec(handle, ci, ref_leaf_bh, index, merge, 1); @@ -2037,7 +2037,7 @@ static int __ocfs2_increase_refcount(handle_t *handle, } else if (!rec.r_refcount) { rec.r_refcount = cpu_to_le32(1); - trace_ocfs2_increase_refcount_insert( + mlog(0, "insert refcount rec, start %llu, len %u\n", (unsigned long long)le64_to_cpu(rec.r_cpos), set_len); ret = ocfs2_insert_refcount_rec(handle, ci, ref_root_bh, @@ -2055,7 +2055,8 @@ static int __ocfs2_increase_refcount(handle_t *handle, rec.r_clusters = cpu_to_le32(set_len); le32_add_cpu(&rec.r_refcount, 1); - trace_ocfs2_increase_refcount_split( + mlog(0, "split refcount rec, start %llu, " + "len %u, count %u\n", (unsigned long long)le64_to_cpu(rec.r_cpos), set_len, le32_to_cpu(rec.r_refcount)); ret = ocfs2_split_refcount_rec(handle, ci, @@ -2094,11 +2095,6 @@ static int ocfs2_remove_refcount_extent(handle_t *handle, BUG_ON(rb->rf_records.rl_used); - trace_ocfs2_remove_refcount_extent( - (unsigned long long)ocfs2_metadata_cache_owner(ci), - (unsigned long long)ref_leaf_bh->b_blocknr, - le32_to_cpu(rb->rf_cpos)); - ocfs2_init_refcount_extent_tree(&et, ci, ref_root_bh); ret = ocfs2_remove_extent(handle, &et, le32_to_cpu(rb->rf_cpos), 1, meta_ac, dealloc); @@ -2141,7 +2137,7 @@ static int ocfs2_remove_refcount_extent(handle_t *handle, if (!rb->rf_list.l_next_free_rec) { BUG_ON(rb->rf_clusters); - trace_ocfs2_restore_refcount_block( + mlog(0, "reset refcount tree root %llu to be a record block.\n", (unsigned long long)ref_root_bh->b_blocknr); rb->rf_flags = 0; @@ -2188,10 +2184,6 @@ static int ocfs2_decrease_refcount_rec(handle_t *handle, BUG_ON(cpos + len > le64_to_cpu(rec->r_cpos) + le32_to_cpu(rec->r_clusters)); - trace_ocfs2_decrease_refcount_rec( - (unsigned long long)ocfs2_metadata_cache_owner(ci), - (unsigned long long)cpos, len); - if (cpos == le64_to_cpu(rec->r_cpos) && len == le32_to_cpu(rec->r_clusters)) ret = ocfs2_change_refcount_rec(handle, ci, @@ -2203,6 +2195,12 @@ static int ocfs2_decrease_refcount_rec(handle_t *handle, le32_add_cpu(&split.r_refcount, -1); + mlog(0, "split refcount rec, start %llu, " + "len %u, count %u, original start %llu, len %u\n", + (unsigned long long)le64_to_cpu(split.r_cpos), + len, le32_to_cpu(split.r_refcount), + (unsigned long long)le64_to_cpu(rec->r_cpos), + le32_to_cpu(rec->r_clusters)); ret = ocfs2_split_refcount_rec(handle, ci, ref_root_bh, ref_leaf_bh, &split, index, 1, @@ -2241,9 +2239,10 @@ static int __ocfs2_decrease_refcount(handle_t *handle, struct super_block *sb = ocfs2_metadata_cache_get_super(ci); struct buffer_head *ref_leaf_bh = NULL; - trace_ocfs2_decrease_refcount( - (unsigned long long)ocfs2_metadata_cache_owner(ci), - (unsigned long long)cpos, len, delete); + mlog(0, "Tree owner %llu, decrease refcount start %llu, " + "len %u, delete %u\n", + (unsigned long long)ocfs2_metadata_cache_owner(ci), + (unsigned long long)cpos, len, delete); while (len) { ret = ocfs2_get_refcount_rec(ci, ref_root_bh, @@ -2353,8 +2352,8 @@ static int ocfs2_mark_extent_refcounted(struct inode *inode, { int ret; - trace_ocfs2_mark_extent_refcounted(OCFS2_I(inode)->ip_blkno, - cpos, len, phys); + mlog(0, "Inode %lu refcount tree cpos %u, len %u, phys cluster %u\n", + inode->i_ino, cpos, len, phys); if (!ocfs2_refcount_tree(OCFS2_SB(inode->i_sb))) { ocfs2_error(inode->i_sb, "Inode %lu want to use refcount " @@ -2393,6 +2392,8 @@ static int ocfs2_calc_refcount_meta_credits(struct super_block *sb, struct buffer_head *ref_leaf_bh = NULL, *prev_bh = NULL; u32 len; + mlog(0, "start_cpos %llu, clusters %u\n", + (unsigned long long)start_cpos, clusters); while (clusters) { ret = ocfs2_get_refcount_rec(ci, ref_root_bh, cpos, clusters, &rec, @@ -2426,11 +2427,12 @@ static int ocfs2_calc_refcount_meta_credits(struct super_block *sb, rb = (struct ocfs2_refcount_block *)ref_leaf_bh->b_data; - trace_ocfs2_calc_refcount_meta_credits_iterate( - recs_add, (unsigned long long)cpos, clusters, - (unsigned long long)le64_to_cpu(rec.r_cpos), - le32_to_cpu(rec.r_clusters), - le32_to_cpu(rec.r_refcount), index); + mlog(0, "recs_add %d,cpos %llu, clusters %u, rec->r_cpos %llu," + "rec->r_clusters %u, rec->r_refcount %u, index %d\n", + recs_add, (unsigned long long)cpos, clusters, + (unsigned long long)le64_to_cpu(rec.r_cpos), + le32_to_cpu(rec.r_clusters), + le32_to_cpu(rec.r_refcount), index); len = min((u64)cpos + clusters, le64_to_cpu(rec.r_cpos) + le32_to_cpu(rec.r_clusters)) - cpos; @@ -2486,6 +2488,7 @@ static int ocfs2_calc_refcount_meta_credits(struct super_block *sb, if (!ref_blocks) goto out; + mlog(0, "we need ref_blocks %d\n", ref_blocks); *meta_add += ref_blocks; *credits += ref_blocks; @@ -2511,10 +2514,6 @@ static int ocfs2_calc_refcount_meta_credits(struct super_block *sb, } out: - - trace_ocfs2_calc_refcount_meta_credits( - (unsigned long long)start_cpos, clusters, - *meta_add, *credits); brelse(ref_leaf_bh); brelse(prev_bh); return ret; @@ -2579,7 +2578,8 @@ int ocfs2_prepare_refcount_change_for_del(struct inode *inode, goto out; } - trace_ocfs2_prepare_refcount_change_for_del(*ref_blocks, *credits); + mlog(0, "reserve new metadata %d blocks, credits = %d\n", + *ref_blocks, *credits); out: brelse(ref_root_bh); @@ -2886,7 +2886,8 @@ static int ocfs2_lock_refcount_allocators(struct super_block *sb, goto out; } - trace_ocfs2_lock_refcount_allocators(meta_add, *credits); + mlog(0, "reserve new metadata %d, clusters %u, credits = %d\n", + meta_add, num_clusters, *credits); ret = ocfs2_reserve_new_metadata_blocks(OCFS2_SB(sb), meta_add, meta_ac); if (ret) { @@ -2936,8 +2937,8 @@ static int ocfs2_duplicate_clusters_by_page(handle_t *handle, loff_t offset, end, map_end; struct address_space *mapping = context->inode->i_mapping; - trace_ocfs2_duplicate_clusters_by_page(cpos, old_cluster, - new_cluster, new_len); + mlog(0, "old_cluster %u, new %u, len %u at offset %u\n", old_cluster, + new_cluster, new_len, cpos); readahead_pages = (ocfs2_cow_contig_clusters(sb) << @@ -3030,8 +3031,8 @@ static int ocfs2_duplicate_clusters_by_jbd(handle_t *handle, struct buffer_head *old_bh = NULL; struct buffer_head *new_bh = NULL; - trace_ocfs2_duplicate_clusters_by_page(cpos, old_cluster, - new_cluster, new_len); + mlog(0, "old_cluster %u, new %u, len %u\n", old_cluster, + new_cluster, new_len); for (i = 0; i < blocks; i++, old_block++, new_block++) { new_bh = sb_getblk(osb->sb, new_block); @@ -3084,8 +3085,8 @@ static int ocfs2_clear_ext_refcount(handle_t *handle, struct super_block *sb = ocfs2_metadata_cache_get_super(et->et_ci); u64 ino = ocfs2_metadata_cache_owner(et->et_ci); - trace_ocfs2_clear_ext_refcount((unsigned long long)ino, - cpos, len, p_cluster, ext_flags); + mlog(0, "inode %llu cpos %u, len %u, p_cluster %u, ext_flags %u\n", + (unsigned long long)ino, cpos, len, p_cluster, ext_flags); memset(&replace_rec, 0, sizeof(replace_rec)); replace_rec.e_cpos = cpu_to_le32(cpos); @@ -3140,8 +3141,8 @@ static int ocfs2_replace_clusters(handle_t *handle, struct ocfs2_caching_info *ci = context->data_et.et_ci; u64 ino = ocfs2_metadata_cache_owner(ci); - trace_ocfs2_replace_clusters((unsigned long long)ino, - cpos, old, new, len, ext_flags); + mlog(0, "inode %llu, cpos %u, old %u, new %u, len %u, ext_flags %u\n", + (unsigned long long)ino, cpos, old, new, len, ext_flags); /*If the old clusters is unwritten, no need to duplicate. */ if (!(ext_flags & OCFS2_EXT_UNWRITTEN)) { @@ -3235,8 +3236,8 @@ static int ocfs2_make_clusters_writable(struct super_block *sb, struct ocfs2_caching_info *ref_ci = &context->ref_tree->rf_ci; struct ocfs2_refcount_rec rec; - trace_ocfs2_make_clusters_writable(cpos, p_cluster, - num_clusters, e_flags); + mlog(0, "cpos %u, p_cluster %u, num_clusters %u, e_flags %u\n", + cpos, p_cluster, num_clusters, e_flags); ret = ocfs2_lock_refcount_allocators(sb, p_cluster, num_clusters, &context->data_et, @@ -3474,9 +3475,9 @@ static int ocfs2_refcount_cow_hunk(struct inode *inode, goto out; } - trace_ocfs2_refcount_cow_hunk(OCFS2_I(inode)->ip_blkno, - cpos, write_len, max_cpos, - cow_start, cow_len); + mlog(0, "CoW inode %lu, cpos %u, write_len %u, cow_start %u, " + "cow_len %u\n", inode->i_ino, + cpos, write_len, cow_start, cow_len); BUG_ON(cow_len == 0); @@ -3755,7 +3756,8 @@ int ocfs2_add_refcount_flag(struct inode *inode, goto out; } - trace_ocfs2_add_refcount_flag(ref_blocks, credits); + mlog(0, "reserve new metadata %d, credits = %d\n", + ref_blocks, credits); if (ref_blocks) { ret = ocfs2_reserve_new_metadata_blocks(OCFS2_SB(inode->i_sb), diff --git a/trunk/fs/ocfs2/reservations.c b/trunk/fs/ocfs2/reservations.c index 41ffd36c689c..3e78db361bc7 100644 --- a/trunk/fs/ocfs2/reservations.c +++ b/trunk/fs/ocfs2/reservations.c @@ -30,10 +30,10 @@ #include #include +#define MLOG_MASK_PREFIX ML_RESERVATIONS #include #include "ocfs2.h" -#include "ocfs2_trace.h" #ifdef CONFIG_OCFS2_DEBUG_FS #define OCFS2_CHECK_RESERVATIONS @@ -321,7 +321,8 @@ static void ocfs2_resv_insert(struct ocfs2_reservation_map *resmap, assert_spin_locked(&resv_lock); - trace_ocfs2_resv_insert(new->r_start, new->r_len); + mlog(0, "Insert reservation start: %u len: %u\n", new->r_start, + new->r_len); while (*p) { parent = *p; @@ -422,8 +423,8 @@ static int ocfs2_resmap_find_free_bits(struct ocfs2_reservation_map *resmap, unsigned int best_start, best_len = 0; int offset, start, found; - trace_ocfs2_resmap_find_free_bits_begin(search_start, search_len, - wanted, resmap->m_bitmap_len); + mlog(0, "Find %u bits within range (%u, len %u) resmap len: %u\n", + wanted, search_start, search_len, resmap->m_bitmap_len); found = best_start = best_len = 0; @@ -462,7 +463,7 @@ static int ocfs2_resmap_find_free_bits(struct ocfs2_reservation_map *resmap, *rlen = best_len; *rstart = best_start; - trace_ocfs2_resmap_find_free_bits_end(best_start, best_len); + mlog(0, "Found start: %u len: %u\n", best_start, best_len); return *rlen; } @@ -486,8 +487,9 @@ static void __ocfs2_resv_find_window(struct ocfs2_reservation_map *resmap, * - our window should be last in all reservations * - need to make sure we don't go past end of bitmap */ - trace_ocfs2_resv_find_window_begin(resv->r_start, ocfs2_resv_end(resv), - goal, wanted, RB_EMPTY_ROOT(root)); + + mlog(0, "resv start: %u resv end: %u goal: %u wanted: %u\n", + resv->r_start, ocfs2_resv_end(resv), goal, wanted); assert_spin_locked(&resv_lock); @@ -496,6 +498,9 @@ static void __ocfs2_resv_find_window(struct ocfs2_reservation_map *resmap, * Easiest case - empty tree. We can just take * whatever window of free bits we want. */ + + mlog(0, "Empty root\n"); + clen = ocfs2_resmap_find_free_bits(resmap, wanted, goal, resmap->m_bitmap_len - goal, &cstart, &clen); @@ -519,6 +524,8 @@ static void __ocfs2_resv_find_window(struct ocfs2_reservation_map *resmap, prev_resv = ocfs2_find_resv_lhs(resmap, goal); if (prev_resv == NULL) { + mlog(0, "Goal on LHS of leftmost window\n"); + /* * A NULL here means that the search code couldn't * find a window that starts before goal. @@ -563,15 +570,13 @@ static void __ocfs2_resv_find_window(struct ocfs2_reservation_map *resmap, next_resv = NULL; } - trace_ocfs2_resv_find_window_prev(prev_resv->r_start, - ocfs2_resv_end(prev_resv)); - prev = &prev_resv->r_node; /* Now we do a linear search for a window, starting at 'prev_rsv' */ while (1) { next = rb_next(prev); if (next) { + mlog(0, "One more resv found in linear search\n"); next_resv = rb_entry(next, struct ocfs2_alloc_reservation, r_node); @@ -580,6 +585,7 @@ static void __ocfs2_resv_find_window(struct ocfs2_reservation_map *resmap, gap_end = next_resv->r_start - 1; gap_len = gap_end - gap_start + 1; } else { + mlog(0, "No next node\n"); /* * We're at the rightmost edge of the * tree. See if a reservation between this @@ -590,8 +596,6 @@ static void __ocfs2_resv_find_window(struct ocfs2_reservation_map *resmap, gap_end = resmap->m_bitmap_len - 1; } - trace_ocfs2_resv_find_window_next(next ? next_resv->r_start: -1, - next ? ocfs2_resv_end(next_resv) : -1); /* * No need to check this gap if we have already found * a larger region of free bits. @@ -650,9 +654,8 @@ static void ocfs2_cannibalize_resv(struct ocfs2_reservation_map *resmap, lru_resv = list_first_entry(&resmap->m_lru, struct ocfs2_alloc_reservation, r_lru); - trace_ocfs2_cannibalize_resv_begin(lru_resv->r_start, - lru_resv->r_len, - ocfs2_resv_end(lru_resv)); + mlog(0, "lru resv: start: %u len: %u end: %u\n", lru_resv->r_start, + lru_resv->r_len, ocfs2_resv_end(lru_resv)); /* * Cannibalize (some or all) of the target reservation and @@ -681,9 +684,10 @@ static void ocfs2_cannibalize_resv(struct ocfs2_reservation_map *resmap, resv->r_len = shrink; } - trace_ocfs2_cannibalize_resv_end(resv->r_start, ocfs2_resv_end(resv), - resv->r_len, resv->r_last_start, - resv->r_last_len); + mlog(0, "Reservation now looks like: r_start: %u r_end: %u " + "r_len: %u r_last_start: %u r_last_len: %u\n", + resv->r_start, ocfs2_resv_end(resv), resv->r_len, + resv->r_last_start, resv->r_last_len); ocfs2_resv_insert(resmap, resv); } @@ -744,6 +748,7 @@ int ocfs2_resmap_resv_bits(struct ocfs2_reservation_map *resmap, if ((resv->r_flags & OCFS2_RESV_FLAG_TMP) || wanted < *clen) wanted = *clen; + mlog(0, "empty reservation, find new window\n"); /* * Try to get a window here. If it works, we must fall * through and test the bitmap . This avoids some @@ -752,7 +757,6 @@ int ocfs2_resmap_resv_bits(struct ocfs2_reservation_map *resmap, * that inode. */ ocfs2_resv_find_window(resmap, resv, wanted); - trace_ocfs2_resmap_resv_bits(resv->r_start, resv->r_len); } BUG_ON(ocfs2_resv_empty(resv)); @@ -809,10 +813,10 @@ void ocfs2_resmap_claimed_bits(struct ocfs2_reservation_map *resmap, spin_lock(&resv_lock); - trace_ocfs2_resmap_claimed_bits_begin(cstart, cend, clen, resv->r_start, - ocfs2_resv_end(resv), resv->r_len, - resv->r_last_start, - resv->r_last_len); + mlog(0, "claim bits: cstart: %u cend: %u clen: %u r_start: %u " + "r_end: %u r_len: %u, r_last_start: %u r_last_len: %u\n", + cstart, cend, clen, resv->r_start, ocfs2_resv_end(resv), + resv->r_len, resv->r_last_start, resv->r_last_len); BUG_ON(cstart < resv->r_start); BUG_ON(cstart > ocfs2_resv_end(resv)); @@ -829,9 +833,10 @@ void ocfs2_resmap_claimed_bits(struct ocfs2_reservation_map *resmap, if (!ocfs2_resv_empty(resv)) ocfs2_resv_mark_lru(resmap, resv); - trace_ocfs2_resmap_claimed_bits_end(resv->r_start, ocfs2_resv_end(resv), - resv->r_len, resv->r_last_start, - resv->r_last_len); + mlog(0, "Reservation now looks like: r_start: %u r_end: %u " + "r_len: %u r_last_start: %u r_last_len: %u\n", + resv->r_start, ocfs2_resv_end(resv), resv->r_len, + resv->r_last_start, resv->r_last_len); ocfs2_check_resmap(resmap); diff --git a/trunk/fs/ocfs2/resize.c b/trunk/fs/ocfs2/resize.c index ec55add7604a..dacd553d8617 100644 --- a/trunk/fs/ocfs2/resize.c +++ b/trunk/fs/ocfs2/resize.c @@ -27,6 +27,7 @@ #include #include +#define MLOG_MASK_PREFIX ML_DISK_ALLOC #include #include "ocfs2.h" @@ -38,7 +39,6 @@ #include "super.h" #include "sysfile.h" #include "uptodate.h" -#include "ocfs2_trace.h" #include "buffer_head_io.h" #include "suballoc.h" @@ -82,6 +82,7 @@ static u16 ocfs2_calc_new_backup_super(struct inode *inode, backups++; } + mlog_exit_void(); return backups; } @@ -102,8 +103,8 @@ static int ocfs2_update_last_group_and_inode(handle_t *handle, u16 cl_bpc = le16_to_cpu(cl->cl_bpc); u16 cl_cpg = le16_to_cpu(cl->cl_cpg); - trace_ocfs2_update_last_group_and_inode(new_clusters, - first_new_cluster); + mlog_entry("(new_clusters=%d, first_new_cluster = %u)\n", + new_clusters, first_new_cluster); ret = ocfs2_journal_access_gd(handle, INODE_CACHE(bm_inode), group_bh, OCFS2_JOURNAL_ACCESS_WRITE); @@ -175,8 +176,7 @@ static int ocfs2_update_last_group_and_inode(handle_t *handle, le16_add_cpu(&group->bg_free_bits_count, -1 * num_bits); } out: - if (ret) - mlog_errno(ret); + mlog_exit(ret); return ret; } @@ -281,6 +281,8 @@ int ocfs2_group_extend(struct inode * inode, int new_clusters) u32 first_new_cluster; u64 lgd_blkno; + mlog_entry_void(); + if (ocfs2_is_hard_readonly(osb) || ocfs2_is_soft_readonly(osb)) return -EROFS; @@ -340,8 +342,7 @@ int ocfs2_group_extend(struct inode * inode, int new_clusters) goto out_unlock; } - - trace_ocfs2_group_extend( + mlog(0, "extend the last group at %llu, new clusters = %d\n", (unsigned long long)le64_to_cpu(group->bg_blkno), new_clusters); handle = ocfs2_start_trans(osb, OCFS2_GROUP_EXTEND_CREDITS); @@ -376,6 +377,7 @@ int ocfs2_group_extend(struct inode * inode, int new_clusters) iput(main_bm_inode); out: + mlog_exit_void(); return ret; } @@ -470,6 +472,8 @@ int ocfs2_group_add(struct inode *inode, struct ocfs2_new_group_input *input) struct ocfs2_chain_rec *cr; u16 cl_bpc; + mlog_entry_void(); + if (ocfs2_is_hard_readonly(osb) || ocfs2_is_soft_readonly(osb)) return -EROFS; @@ -516,8 +520,8 @@ int ocfs2_group_add(struct inode *inode, struct ocfs2_new_group_input *input) goto out_unlock; } - trace_ocfs2_group_add((unsigned long long)input->group, - input->chain, input->clusters, input->frees); + mlog(0, "Add a new group %llu in chain = %u, length = %u\n", + (unsigned long long)input->group, input->chain, input->clusters); handle = ocfs2_start_trans(osb, OCFS2_GROUP_ADD_CREDITS); if (IS_ERR(handle)) { @@ -585,5 +589,6 @@ int ocfs2_group_add(struct inode *inode, struct ocfs2_new_group_input *input) iput(main_bm_inode); out: + mlog_exit_void(); return ret; } diff --git a/trunk/fs/ocfs2/slot_map.c b/trunk/fs/ocfs2/slot_map.c index 26fc0014d509..ab4e0172cc1d 100644 --- a/trunk/fs/ocfs2/slot_map.c +++ b/trunk/fs/ocfs2/slot_map.c @@ -27,6 +27,7 @@ #include #include +#define MLOG_MASK_PREFIX ML_SUPER #include #include "ocfs2.h" @@ -38,7 +39,6 @@ #include "slot_map.h" #include "super.h" #include "sysfile.h" -#include "ocfs2_trace.h" #include "buffer_head_io.h" @@ -142,7 +142,8 @@ int ocfs2_refresh_slot_info(struct ocfs2_super *osb) BUG_ON(si->si_blocks == 0); BUG_ON(si->si_bh == NULL); - trace_ocfs2_refresh_slot_info(si->si_blocks); + mlog(0, "Refreshing slot map, reading %u block(s)\n", + si->si_blocks); /* * We pass -1 as blocknr because we expect all of si->si_bh to @@ -380,7 +381,8 @@ static int ocfs2_map_slot_buffers(struct ocfs2_super *osb, /* The size checks above should ensure this */ BUG_ON((osb->max_slots / si->si_slots_per_block) > blocks); - trace_ocfs2_map_slot_buffers(bytes, si->si_blocks); + mlog(0, "Slot map needs %u buffers for %llu bytes\n", + si->si_blocks, bytes); si->si_bh = kzalloc(sizeof(struct buffer_head *) * si->si_blocks, GFP_KERNEL); @@ -398,7 +400,8 @@ static int ocfs2_map_slot_buffers(struct ocfs2_super *osb, goto bail; } - trace_ocfs2_map_slot_buffers_block((unsigned long long)blkno, i); + mlog(0, "Reading slot map block %u at %llu\n", i, + (unsigned long long)blkno); bh = NULL; /* Acquire a fresh bh */ status = ocfs2_read_blocks(INODE_CACHE(si->si_inode), blkno, @@ -472,6 +475,8 @@ int ocfs2_find_slot(struct ocfs2_super *osb) int slot; struct ocfs2_slot_info *si; + mlog_entry_void(); + si = osb->slot_info; spin_lock(&osb->osb_lock); @@ -500,13 +505,14 @@ int ocfs2_find_slot(struct ocfs2_super *osb) osb->slot_num = slot; spin_unlock(&osb->osb_lock); - trace_ocfs2_find_slot(osb->slot_num); + mlog(0, "taking node slot %d\n", osb->slot_num); status = ocfs2_update_disk_slot(osb, si, osb->slot_num); if (status < 0) mlog_errno(status); bail: + mlog_exit(status); return status; } diff --git a/trunk/fs/ocfs2/suballoc.c b/trunk/fs/ocfs2/suballoc.c index ab6e2061074f..71998d4d61d5 100644 --- a/trunk/fs/ocfs2/suballoc.c +++ b/trunk/fs/ocfs2/suballoc.c @@ -29,6 +29,7 @@ #include #include +#define MLOG_MASK_PREFIX ML_DISK_ALLOC #include #include "ocfs2.h" @@ -43,7 +44,6 @@ #include "super.h" #include "sysfile.h" #include "uptodate.h" -#include "ocfs2_trace.h" #include "buffer_head_io.h" @@ -308,8 +308,8 @@ static int ocfs2_validate_group_descriptor(struct super_block *sb, int rc; struct ocfs2_group_desc *gd = (struct ocfs2_group_desc *)bh->b_data; - trace_ocfs2_validate_group_descriptor( - (unsigned long long)bh->b_blocknr); + mlog(0, "Validating group descriptor %llu\n", + (unsigned long long)bh->b_blocknr); BUG_ON(!buffer_uptodate(bh)); @@ -389,6 +389,8 @@ static int ocfs2_block_group_fill(handle_t *handle, struct ocfs2_group_desc *bg = (struct ocfs2_group_desc *) bg_bh->b_data; struct super_block * sb = alloc_inode->i_sb; + mlog_entry_void(); + if (((unsigned long long) bg_bh->b_blocknr) != group_blkno) { ocfs2_error(alloc_inode->i_sb, "group block (%llu) != " "b_blocknr (%llu)", @@ -434,8 +436,7 @@ static int ocfs2_block_group_fill(handle_t *handle, * allocation time. */ bail: - if (status) - mlog_errno(status); + mlog_exit(status); return status; } @@ -476,8 +477,8 @@ ocfs2_block_group_alloc_contig(struct ocfs2_super *osb, handle_t *handle, /* setup the group */ bg_blkno = ocfs2_clusters_to_blocks(osb->sb, bit_off); - trace_ocfs2_block_group_alloc_contig( - (unsigned long long)bg_blkno, alloc_rec); + mlog(0, "new descriptor, record %u, at block %llu\n", + alloc_rec, (unsigned long long)bg_blkno); bg_bh = sb_getblk(osb->sb, bg_blkno); if (!bg_bh) { @@ -656,8 +657,8 @@ ocfs2_block_group_alloc_discontig(handle_t *handle, /* setup the group */ bg_blkno = ocfs2_clusters_to_blocks(osb->sb, bit_off); - trace_ocfs2_block_group_alloc_discontig( - (unsigned long long)bg_blkno, alloc_rec); + mlog(0, "new descriptor, record %u, at block %llu\n", + alloc_rec, (unsigned long long)bg_blkno); bg_bh = sb_getblk(osb->sb, bg_blkno); if (!bg_bh) { @@ -706,6 +707,8 @@ static int ocfs2_block_group_alloc(struct ocfs2_super *osb, BUG_ON(ocfs2_is_cluster_bitmap(alloc_inode)); + mlog_entry_void(); + cl = &fe->id2.i_chain; status = ocfs2_reserve_clusters_with_limit(osb, le16_to_cpu(cl->cl_cpg), @@ -727,8 +730,8 @@ static int ocfs2_block_group_alloc(struct ocfs2_super *osb, } if (last_alloc_group && *last_alloc_group != 0) { - trace_ocfs2_block_group_alloc( - (unsigned long long)*last_alloc_group); + mlog(0, "use old allocation group %llu for block group alloc\n", + (unsigned long long)*last_alloc_group); ac->ac_last_group = *last_alloc_group; } @@ -793,8 +796,7 @@ static int ocfs2_block_group_alloc(struct ocfs2_super *osb, brelse(bg_bh); - if (status) - mlog_errno(status); + mlog_exit(status); return status; } @@ -812,6 +814,8 @@ static int ocfs2_reserve_suballoc_bits(struct ocfs2_super *osb, struct ocfs2_dinode *fe; u32 free_bits; + mlog_entry_void(); + alloc_inode = ocfs2_get_system_file_inode(osb, type, slot); if (!alloc_inode) { mlog_errno(-EINVAL); @@ -851,15 +855,16 @@ static int ocfs2_reserve_suballoc_bits(struct ocfs2_super *osb, if (bits_wanted > free_bits) { /* cluster bitmap never grows */ if (ocfs2_is_cluster_bitmap(alloc_inode)) { - trace_ocfs2_reserve_suballoc_bits_nospc(bits_wanted, - free_bits); + mlog(0, "Disk Full: wanted=%u, free_bits=%u\n", + bits_wanted, free_bits); status = -ENOSPC; goto bail; } if (!(flags & ALLOC_NEW_GROUP)) { - trace_ocfs2_reserve_suballoc_bits_no_new_group( - slot, bits_wanted, free_bits); + mlog(0, "Alloc File %u Full: wanted=%u, free_bits=%u, " + "and we don't alloc a new group for it.\n", + slot, bits_wanted, free_bits); status = -ENOSPC; goto bail; } @@ -885,8 +890,7 @@ static int ocfs2_reserve_suballoc_bits(struct ocfs2_super *osb, bail: brelse(bh); - if (status) - mlog_errno(status); + mlog_exit(status); return status; } @@ -1048,8 +1052,7 @@ int ocfs2_reserve_new_metadata_blocks(struct ocfs2_super *osb, *ac = NULL; } - if (status) - mlog_errno(status); + mlog_exit(status); return status; } @@ -1116,8 +1119,8 @@ int ocfs2_reserve_new_inode(struct ocfs2_super *osb, spin_lock(&osb->osb_lock); osb->osb_inode_alloc_group = alloc_group; spin_unlock(&osb->osb_lock); - trace_ocfs2_reserve_new_inode_new_group( - (unsigned long long)alloc_group); + mlog(0, "after reservation, new allocation group is " + "%llu\n", (unsigned long long)alloc_group); /* * Some inodes must be freed by us, so try to allocate @@ -1149,8 +1152,7 @@ int ocfs2_reserve_new_inode(struct ocfs2_super *osb, *ac = NULL; } - if (status) - mlog_errno(status); + mlog_exit(status); return status; } @@ -1187,6 +1189,8 @@ static int ocfs2_reserve_clusters_with_limit(struct ocfs2_super *osb, { int status; + mlog_entry_void(); + *ac = kzalloc(sizeof(struct ocfs2_alloc_context), GFP_KERNEL); if (!(*ac)) { status = -ENOMEM; @@ -1225,8 +1229,7 @@ static int ocfs2_reserve_clusters_with_limit(struct ocfs2_super *osb, *ac = NULL; } - if (status) - mlog_errno(status); + mlog_exit(status); return status; } @@ -1354,12 +1357,15 @@ static inline int ocfs2_block_group_set_bits(handle_t *handle, void *bitmap = bg->bg_bitmap; int journal_type = OCFS2_JOURNAL_ACCESS_WRITE; + mlog_entry_void(); + /* All callers get the descriptor via * ocfs2_read_group_descriptor(). Any corruption is a code bug. */ BUG_ON(!OCFS2_IS_VALID_GROUP_DESC(bg)); BUG_ON(le16_to_cpu(bg->bg_free_bits_count) < num_bits); - trace_ocfs2_block_group_set_bits(bit_off, num_bits); + mlog(0, "block_group_set_bits: off = %u, num = %u\n", bit_off, + num_bits); if (ocfs2_is_cluster_bitmap(alloc_inode)) journal_type = OCFS2_JOURNAL_ACCESS_UNDO; @@ -1388,8 +1394,7 @@ static inline int ocfs2_block_group_set_bits(handle_t *handle, ocfs2_journal_dirty(handle, group_bh); bail: - if (status) - mlog_errno(status); + mlog_exit(status); return status; } @@ -1432,10 +1437,10 @@ static int ocfs2_relink_block_group(handle_t *handle, BUG_ON(!OCFS2_IS_VALID_GROUP_DESC(bg)); BUG_ON(!OCFS2_IS_VALID_GROUP_DESC(prev_bg)); - trace_ocfs2_relink_block_group( - (unsigned long long)le64_to_cpu(fe->i_blkno), chain, - (unsigned long long)le64_to_cpu(bg->bg_blkno), - (unsigned long long)le64_to_cpu(prev_bg->bg_blkno)); + mlog(0, "Suballoc %llu, chain %u, move group %llu to top, prev = %llu\n", + (unsigned long long)le64_to_cpu(fe->i_blkno), chain, + (unsigned long long)le64_to_cpu(bg->bg_blkno), + (unsigned long long)le64_to_cpu(prev_bg->bg_blkno)); fe_ptr = le64_to_cpu(fe->id2.i_chain.cl_recs[chain].c_blkno); bg_ptr = le64_to_cpu(bg->bg_next_group); @@ -1479,8 +1484,7 @@ static int ocfs2_relink_block_group(handle_t *handle, prev_bg->bg_next_group = cpu_to_le64(prev_bg_ptr); } - if (status) - mlog_errno(status); + mlog_exit(status); return status; } @@ -1521,10 +1525,10 @@ static int ocfs2_cluster_group_search(struct inode *inode, if ((gd_cluster_off + max_bits) > OCFS2_I(inode)->ip_clusters) { max_bits = OCFS2_I(inode)->ip_clusters - gd_cluster_off; - trace_ocfs2_cluster_group_search_wrong_max_bits( - (unsigned long long)le64_to_cpu(gd->bg_blkno), - le16_to_cpu(gd->bg_bits), - OCFS2_I(inode)->ip_clusters, max_bits); + mlog(0, "Desc %llu, bg_bits %u, clusters %u, use %u\n", + (unsigned long long)le64_to_cpu(gd->bg_blkno), + le16_to_cpu(gd->bg_bits), + OCFS2_I(inode)->ip_clusters, max_bits); } ret = ocfs2_block_group_find_clear_bits(OCFS2_SB(inode->i_sb), @@ -1538,9 +1542,9 @@ static int ocfs2_cluster_group_search(struct inode *inode, gd_cluster_off + res->sr_bit_offset + res->sr_bits); - trace_ocfs2_cluster_group_search_max_block( - (unsigned long long)blkoff, - (unsigned long long)max_block); + mlog(0, "Checking %llu against %llu\n", + (unsigned long long)blkoff, + (unsigned long long)max_block); if (blkoff > max_block) return -ENOSPC; } @@ -1584,9 +1588,9 @@ static int ocfs2_block_group_search(struct inode *inode, if (!ret && max_block) { blkoff = le64_to_cpu(bg->bg_blkno) + res->sr_bit_offset + res->sr_bits; - trace_ocfs2_block_group_search_max_block( - (unsigned long long)blkoff, - (unsigned long long)max_block); + mlog(0, "Checking %llu against %llu\n", + (unsigned long long)blkoff, + (unsigned long long)max_block); if (blkoff > max_block) ret = -ENOSPC; } @@ -1752,9 +1756,9 @@ static int ocfs2_search_chain(struct ocfs2_alloc_context *ac, struct ocfs2_group_desc *bg; chain = ac->ac_chain; - trace_ocfs2_search_chain_begin( - (unsigned long long)OCFS2_I(alloc_inode)->ip_blkno, - bits_wanted, chain); + mlog(0, "trying to alloc %u bits from chain %u, inode %llu\n", + bits_wanted, chain, + (unsigned long long)OCFS2_I(alloc_inode)->ip_blkno); status = ocfs2_read_group_descriptor(alloc_inode, fe, le64_to_cpu(cl->cl_recs[chain].c_blkno), @@ -1795,8 +1799,8 @@ static int ocfs2_search_chain(struct ocfs2_alloc_context *ac, goto bail; } - trace_ocfs2_search_chain_succ( - (unsigned long long)le64_to_cpu(bg->bg_blkno), res->sr_bits); + mlog(0, "alloc succeeds: we give %u bits from block group %llu\n", + res->sr_bits, (unsigned long long)le64_to_cpu(bg->bg_blkno)); res->sr_bg_blkno = le64_to_cpu(bg->bg_blkno); @@ -1857,9 +1861,8 @@ static int ocfs2_search_chain(struct ocfs2_alloc_context *ac, goto bail; } - trace_ocfs2_search_chain_end( - (unsigned long long)le64_to_cpu(fe->i_blkno), - res->sr_bits); + mlog(0, "Allocated %u bits from suballocator %llu\n", res->sr_bits, + (unsigned long long)le64_to_cpu(fe->i_blkno)); out_loc_only: *bits_left = le16_to_cpu(bg->bg_free_bits_count); @@ -1867,8 +1870,7 @@ static int ocfs2_search_chain(struct ocfs2_alloc_context *ac, brelse(group_bh); brelse(prev_group_bh); - if (status) - mlog_errno(status); + mlog_exit(status); return status; } @@ -1886,6 +1888,8 @@ static int ocfs2_claim_suballoc_bits(struct ocfs2_alloc_context *ac, struct ocfs2_chain_list *cl; struct ocfs2_dinode *fe; + mlog_entry_void(); + BUG_ON(ac->ac_bits_given >= ac->ac_bits_wanted); BUG_ON(bits_wanted > (ac->ac_bits_wanted - ac->ac_bits_given)); BUG_ON(!ac->ac_bh); @@ -1941,7 +1945,8 @@ static int ocfs2_claim_suballoc_bits(struct ocfs2_alloc_context *ac, goto bail; } - trace_ocfs2_claim_suballoc_bits(victim); + mlog(0, "Search of victim chain %u came up with nothing, " + "trying all chains now.\n", victim); /* If we didn't pick a good victim, then just default to * searching each chain in order. Don't allow chain relinking @@ -1979,8 +1984,7 @@ static int ocfs2_claim_suballoc_bits(struct ocfs2_alloc_context *ac, } bail: - if (status) - mlog_errno(status); + mlog_exit(status); return status; } @@ -2017,8 +2021,7 @@ int ocfs2_claim_metadata(handle_t *handle, *num_bits = res.sr_bits; status = 0; bail: - if (status) - mlog_errno(status); + mlog_exit(status); return status; } @@ -2169,8 +2172,8 @@ int ocfs2_claim_new_inode_at_loc(handle_t *handle, goto out; } - trace_ocfs2_claim_new_inode_at_loc((unsigned long long)di_blkno, - res->sr_bits); + mlog(0, "Allocated %u bits from suballocator %llu\n", res->sr_bits, + (unsigned long long)di_blkno); atomic_inc(&OCFS2_SB(ac->ac_inode->i_sb)->alloc_stats.bg_allocs); @@ -2198,6 +2201,8 @@ int ocfs2_claim_new_inode(handle_t *handle, int status; struct ocfs2_suballoc_result res; + mlog_entry_void(); + BUG_ON(!ac); BUG_ON(ac->ac_bits_given != 0); BUG_ON(ac->ac_bits_wanted != 1); @@ -2225,8 +2230,7 @@ int ocfs2_claim_new_inode(handle_t *handle, ocfs2_save_inode_ac_group(dir, ac); status = 0; bail: - if (status) - mlog_errno(status); + mlog_exit(status); return status; } @@ -2303,6 +2307,8 @@ int __ocfs2_claim_clusters(handle_t *handle, struct ocfs2_suballoc_result res = { .sr_blkno = 0, }; struct ocfs2_super *osb = OCFS2_SB(ac->ac_inode->i_sb); + mlog_entry_void(); + BUG_ON(ac->ac_bits_given >= ac->ac_bits_wanted); BUG_ON(ac->ac_which != OCFS2_AC_USE_LOCAL @@ -2357,8 +2363,7 @@ int __ocfs2_claim_clusters(handle_t *handle, ac->ac_bits_given += *num_clusters; bail: - if (status) - mlog_errno(status); + mlog_exit(status); return status; } @@ -2387,11 +2392,13 @@ static int ocfs2_block_group_clear_bits(handle_t *handle, unsigned int tmp; struct ocfs2_group_desc *undo_bg = NULL; + mlog_entry_void(); + /* The caller got this descriptor from * ocfs2_read_group_descriptor(). Any corruption is a code bug. */ BUG_ON(!OCFS2_IS_VALID_GROUP_DESC(bg)); - trace_ocfs2_block_group_clear_bits(bit_off, num_bits); + mlog(0, "off = %u, num = %u\n", bit_off, num_bits); BUG_ON(undo_fn && !ocfs2_is_cluster_bitmap(alloc_inode)); status = ocfs2_journal_access_gd(handle, INODE_CACHE(alloc_inode), @@ -2456,6 +2463,8 @@ static int _ocfs2_free_suballoc_bits(handle_t *handle, struct buffer_head *group_bh = NULL; struct ocfs2_group_desc *group; + mlog_entry_void(); + /* The alloc_bh comes from ocfs2_free_dinode() or * ocfs2_free_clusters(). The callers have all locked the * allocator and gotten alloc_bh from the lock call. This @@ -2464,10 +2473,9 @@ static int _ocfs2_free_suballoc_bits(handle_t *handle, BUG_ON(!OCFS2_IS_VALID_DINODE(fe)); BUG_ON((count + start_bit) > ocfs2_bits_per_group(cl)); - trace_ocfs2_free_suballoc_bits( - (unsigned long long)OCFS2_I(alloc_inode)->ip_blkno, - (unsigned long long)bg_blkno, - start_bit, count); + mlog(0, "%llu: freeing %u bits from group %llu, starting at %u\n", + (unsigned long long)OCFS2_I(alloc_inode)->ip_blkno, count, + (unsigned long long)bg_blkno, start_bit); status = ocfs2_read_group_descriptor(alloc_inode, fe, bg_blkno, &group_bh); @@ -2503,8 +2511,7 @@ static int _ocfs2_free_suballoc_bits(handle_t *handle, bail: brelse(group_bh); - if (status) - mlog_errno(status); + mlog_exit(status); return status; } @@ -2549,8 +2556,11 @@ static int _ocfs2_free_clusters(handle_t *handle, /* You can't ever have a contiguous set of clusters * bigger than a block group bitmap so we never have to worry - * about looping on them. - * This is expensive. We can safely remove once this stuff has + * about looping on them. */ + + mlog_entry_void(); + + /* This is expensive. We can safely remove once this stuff has * gotten tested really well. */ BUG_ON(start_blk != ocfs2_clusters_to_blocks(bitmap_inode->i_sb, ocfs2_blocks_to_clusters(bitmap_inode->i_sb, start_blk))); @@ -2559,9 +2569,10 @@ static int _ocfs2_free_clusters(handle_t *handle, ocfs2_block_to_cluster_group(bitmap_inode, start_blk, &bg_blkno, &bg_start_bit); - trace_ocfs2_free_clusters((unsigned long long)bg_blkno, - (unsigned long long)start_blk, - bg_start_bit, num_clusters); + mlog(0, "want to free %u clusters starting at block %llu\n", + num_clusters, (unsigned long long)start_blk); + mlog(0, "bg_blkno = %llu, bg_start_bit = %u\n", + (unsigned long long)bg_blkno, bg_start_bit); status = _ocfs2_free_suballoc_bits(handle, bitmap_inode, bitmap_bh, bg_start_bit, bg_blkno, @@ -2575,8 +2586,7 @@ static int _ocfs2_free_clusters(handle_t *handle, num_clusters); out: - if (status) - mlog_errno(status); + mlog_exit(status); return status; } @@ -2746,7 +2756,7 @@ static int ocfs2_get_suballoc_slot_bit(struct ocfs2_super *osb, u64 blkno, struct buffer_head *inode_bh = NULL; struct ocfs2_dinode *inode_fe; - trace_ocfs2_get_suballoc_slot_bit((unsigned long long)blkno); + mlog_entry("blkno: %llu\n", (unsigned long long)blkno); /* dirty read disk */ status = ocfs2_read_blocks_sync(osb, blkno, 1, &inode_bh); @@ -2783,8 +2793,7 @@ static int ocfs2_get_suballoc_slot_bit(struct ocfs2_super *osb, u64 blkno, bail: brelse(inode_bh); - if (status) - mlog_errno(status); + mlog_exit(status); return status; } @@ -2807,8 +2816,8 @@ static int ocfs2_test_suballoc_bit(struct ocfs2_super *osb, u64 bg_blkno; int status; - trace_ocfs2_test_suballoc_bit((unsigned long long)blkno, - (unsigned int)bit); + mlog_entry("blkno: %llu bit: %u\n", (unsigned long long)blkno, + (unsigned int)bit); alloc_di = (struct ocfs2_dinode *)alloc_bh->b_data; if ((bit + 1) > ocfs2_bits_per_group(&alloc_di->id2.i_chain)) { @@ -2835,8 +2844,7 @@ static int ocfs2_test_suballoc_bit(struct ocfs2_super *osb, bail: brelse(group_bh); - if (status) - mlog_errno(status); + mlog_exit(status); return status; } @@ -2861,7 +2869,7 @@ int ocfs2_test_inode_bit(struct ocfs2_super *osb, u64 blkno, int *res) struct inode *inode_alloc_inode; struct buffer_head *alloc_bh = NULL; - trace_ocfs2_test_inode_bit((unsigned long long)blkno); + mlog_entry("blkno: %llu", (unsigned long long)blkno); status = ocfs2_get_suballoc_slot_bit(osb, blkno, &suballoc_slot, &group_blkno, &suballoc_bit); @@ -2902,7 +2910,6 @@ int ocfs2_test_inode_bit(struct ocfs2_super *osb, u64 blkno, int *res) iput(inode_alloc_inode); brelse(alloc_bh); bail: - if (status) - mlog_errno(status); + mlog_exit(status); return status; } diff --git a/trunk/fs/ocfs2/super.c b/trunk/fs/ocfs2/super.c index 69fa11b35aa4..236ed1bdca2c 100644 --- a/trunk/fs/ocfs2/super.c +++ b/trunk/fs/ocfs2/super.c @@ -42,9 +42,7 @@ #include #include -#define CREATE_TRACE_POINTS -#include "ocfs2_trace.h" - +#define MLOG_MASK_PREFIX ML_SUPER #include #include "ocfs2.h" @@ -443,6 +441,8 @@ static int ocfs2_init_global_system_inodes(struct ocfs2_super *osb) int status = 0; int i; + mlog_entry_void(); + new = ocfs2_iget(osb, osb->root_blkno, OCFS2_FI_FLAG_SYSFILE, 0); if (IS_ERR(new)) { status = PTR_ERR(new); @@ -478,8 +478,7 @@ static int ocfs2_init_global_system_inodes(struct ocfs2_super *osb) } bail: - if (status) - mlog_errno(status); + mlog_exit(status); return status; } @@ -489,6 +488,8 @@ static int ocfs2_init_local_system_inodes(struct ocfs2_super *osb) int status = 0; int i; + mlog_entry_void(); + for (i = OCFS2_LAST_GLOBAL_SYSTEM_INODE + 1; i < NUM_SYSTEM_INODES; i++) { @@ -507,8 +508,7 @@ static int ocfs2_init_local_system_inodes(struct ocfs2_super *osb) } bail: - if (status) - mlog_errno(status); + mlog_exit(status); return status; } @@ -517,6 +517,8 @@ static void ocfs2_release_system_inodes(struct ocfs2_super *osb) int i; struct inode *inode; + mlog_entry_void(); + for (i = 0; i < NUM_GLOBAL_SYSTEM_INODES; i++) { inode = osb->global_system_inodes[i]; if (inode) { @@ -538,7 +540,7 @@ static void ocfs2_release_system_inodes(struct ocfs2_super *osb) } if (!osb->local_system_inodes) - return; + goto out; for (i = 0; i < NUM_LOCAL_SYSTEM_INODES * osb->max_slots; i++) { if (osb->local_system_inodes[i]) { @@ -549,6 +551,9 @@ static void ocfs2_release_system_inodes(struct ocfs2_super *osb) kfree(osb->local_system_inodes); osb->local_system_inodes = NULL; + +out: + mlog_exit(0); } /* We're allocating fs objects, use GFP_NOFS */ @@ -679,9 +684,12 @@ static int ocfs2_remount(struct super_block *sb, int *flags, char *data) } if (*flags & MS_RDONLY) { + mlog(0, "Going to ro mode.\n"); sb->s_flags |= MS_RDONLY; osb->osb_flags |= OCFS2_OSB_SOFT_RO; } else { + mlog(0, "Making ro filesystem writeable.\n"); + if (osb->osb_flags & OCFS2_OSB_ERROR_FS) { mlog(ML_ERROR, "Cannot remount RDWR " "filesystem due to previous errors.\n"); @@ -699,7 +707,6 @@ static int ocfs2_remount(struct super_block *sb, int *flags, char *data) sb->s_flags &= ~MS_RDONLY; osb->osb_flags &= ~OCFS2_OSB_SOFT_RO; } - trace_ocfs2_remount(sb->s_flags, osb->osb_flags, *flags); unlock_osb: spin_unlock(&osb->osb_lock); /* Enable quota accounting after remounting RW */ @@ -1025,7 +1032,7 @@ static int ocfs2_fill_super(struct super_block *sb, void *data, int silent) char nodestr[8]; struct ocfs2_blockcheck_stats stats; - trace_ocfs2_fill_super(sb, data, silent); + mlog_entry("%p, %p, %i", sb, data, silent); if (!ocfs2_parse_options(sb, data, &parsed_options, 0)) { status = -EINVAL; @@ -1201,6 +1208,7 @@ static int ocfs2_fill_super(struct super_block *sb, void *data, int silent) mlog_errno(status); atomic_set(&osb->vol_state, VOLUME_DISABLED); wake_up(&osb->osb_mount_event); + mlog_exit(status); return status; } } @@ -1214,6 +1222,7 @@ static int ocfs2_fill_super(struct super_block *sb, void *data, int silent) /* Start this when the mount is almost sure of being successful */ ocfs2_orphan_scan_start(osb); + mlog_exit(status); return status; read_super_error: @@ -1228,8 +1237,7 @@ static int ocfs2_fill_super(struct super_block *sb, void *data, int silent) ocfs2_dismount_volume(sb, 1); } - if (status) - mlog_errno(status); + mlog_exit(status); return status; } @@ -1312,7 +1320,8 @@ static int ocfs2_parse_options(struct super_block *sb, char *p; u32 tmp; - trace_ocfs2_parse_options(is_remount, options ? options : "(none)"); + mlog_entry("remount: %d, options: \"%s\"\n", is_remount, + options ? options : "(none)"); mopt->commit_interval = 0; mopt->mount_opt = OCFS2_MOUNT_NOINTR; @@ -1529,6 +1538,7 @@ static int ocfs2_parse_options(struct super_block *sb, status = 1; bail: + mlog_exit(status); return status; } @@ -1619,6 +1629,8 @@ static int __init ocfs2_init(void) { int status; + mlog_entry_void(); + ocfs2_print_version(); status = init_ocfs2_uptodate_cache(); @@ -1652,9 +1664,10 @@ static int __init ocfs2_init(void) if (status < 0) { ocfs2_free_mem_caches(); exit_ocfs2_uptodate_cache(); - mlog_errno(status); } + mlog_exit(status); + if (status >= 0) { return register_filesystem(&ocfs2_fs_type); } else @@ -1663,6 +1676,8 @@ static int __init ocfs2_init(void) static void __exit ocfs2_exit(void) { + mlog_entry_void(); + if (ocfs2_wq) { flush_workqueue(ocfs2_wq); destroy_workqueue(ocfs2_wq); @@ -1677,14 +1692,18 @@ static void __exit ocfs2_exit(void) unregister_filesystem(&ocfs2_fs_type); exit_ocfs2_uptodate_cache(); + + mlog_exit_void(); } static void ocfs2_put_super(struct super_block *sb) { - trace_ocfs2_put_super(sb); + mlog_entry("(0x%p)\n", sb); ocfs2_sync_blockdev(sb); ocfs2_dismount_volume(sb, 0); + + mlog_exit_void(); } static int ocfs2_statfs(struct dentry *dentry, struct kstatfs *buf) @@ -1696,7 +1715,7 @@ static int ocfs2_statfs(struct dentry *dentry, struct kstatfs *buf) struct buffer_head *bh = NULL; struct inode *inode = NULL; - trace_ocfs2_statfs(dentry->d_sb, buf); + mlog_entry("(%p, %p)\n", dentry->d_sb, buf); osb = OCFS2_SB(dentry->d_sb); @@ -1743,8 +1762,7 @@ static int ocfs2_statfs(struct dentry *dentry, struct kstatfs *buf) if (inode) iput(inode); - if (status) - mlog_errno(status); + mlog_exit(status); return status; } @@ -1864,6 +1882,8 @@ static int ocfs2_mount_volume(struct super_block *sb) int unlock_super = 0; struct ocfs2_super *osb = OCFS2_SB(sb); + mlog_entry_void(); + if (ocfs2_is_hard_readonly(osb)) goto leave; @@ -1908,6 +1928,7 @@ static int ocfs2_mount_volume(struct super_block *sb) if (unlock_super) ocfs2_super_unlock(osb, 1); + mlog_exit(status); return status; } @@ -1917,7 +1938,7 @@ static void ocfs2_dismount_volume(struct super_block *sb, int mnt_err) struct ocfs2_super *osb = NULL; char nodestr[8]; - trace_ocfs2_dismount_volume(sb); + mlog_entry("(0x%p)\n", sb); BUG_ON(!sb); osb = OCFS2_SB(sb); @@ -2069,6 +2090,8 @@ static int ocfs2_initialize_super(struct super_block *sb, struct ocfs2_super *osb; u64 total_blocks; + mlog_entry_void(); + osb = kzalloc(sizeof(struct ocfs2_super), GFP_KERNEL); if (!osb) { status = -ENOMEM; @@ -2132,6 +2155,7 @@ static int ocfs2_initialize_super(struct super_block *sb, status = -EINVAL; goto bail; } + mlog(0, "max_slots for this device: %u\n", osb->max_slots); ocfs2_orphan_scan_init(osb); @@ -2270,6 +2294,7 @@ static int ocfs2_initialize_super(struct super_block *sb, osb->s_clustersize_bits = le32_to_cpu(di->id2.i_super.s_clustersize_bits); osb->s_clustersize = 1 << osb->s_clustersize_bits; + mlog(0, "clusterbits=%d\n", osb->s_clustersize_bits); if (osb->s_clustersize < OCFS2_MIN_CLUSTERSIZE || osb->s_clustersize > OCFS2_MAX_CLUSTERSIZE) { @@ -2308,10 +2333,11 @@ static int ocfs2_initialize_super(struct super_block *sb, le64_to_cpu(di->id2.i_super.s_first_cluster_group); osb->fs_generation = le32_to_cpu(di->i_fs_generation); osb->uuid_hash = le32_to_cpu(di->id2.i_super.s_uuid_hash); - trace_ocfs2_initialize_super(osb->vol_label, osb->uuid_str, - (unsigned long long)osb->root_blkno, - (unsigned long long)osb->system_dir_blkno, - osb->s_clustersize_bits); + mlog(0, "vol_label: %s\n", osb->vol_label); + mlog(0, "uuid: %s\n", osb->uuid_str); + mlog(0, "root_blkno=%llu, system_dir_blkno=%llu\n", + (unsigned long long)osb->root_blkno, + (unsigned long long)osb->system_dir_blkno); osb->osb_dlm_debug = ocfs2_new_dlm_debug(); if (!osb->osb_dlm_debug) { @@ -2354,6 +2380,7 @@ static int ocfs2_initialize_super(struct super_block *sb, } bail: + mlog_exit(status); return status; } @@ -2369,6 +2396,8 @@ static int ocfs2_verify_volume(struct ocfs2_dinode *di, { int status = -EAGAIN; + mlog_entry_void(); + if (memcmp(di->i_signature, OCFS2_SUPER_BLOCK_SIGNATURE, strlen(OCFS2_SUPER_BLOCK_SIGNATURE)) == 0) { /* We have to do a raw check of the feature here */ @@ -2423,8 +2452,7 @@ static int ocfs2_verify_volume(struct ocfs2_dinode *di, } out: - if (status && status != -EAGAIN) - mlog_errno(status); + mlog_exit(status); return status; } @@ -2437,6 +2465,8 @@ static int ocfs2_check_volume(struct ocfs2_super *osb) * recover * ourselves. */ + mlog_entry_void(); + /* Init our journal object. */ status = ocfs2_journal_init(osb->journal, &dirty); if (status < 0) { @@ -2486,6 +2516,8 @@ static int ocfs2_check_volume(struct ocfs2_super *osb) * ourselves as mounted. */ } + mlog(0, "Journal loaded.\n"); + status = ocfs2_load_local_alloc(osb); if (status < 0) { mlog_errno(status); @@ -2517,8 +2549,7 @@ static int ocfs2_check_volume(struct ocfs2_super *osb) if (local_alloc) kfree(local_alloc); - if (status) - mlog_errno(status); + mlog_exit(status); return status; } @@ -2530,6 +2561,8 @@ static int ocfs2_check_volume(struct ocfs2_super *osb) */ static void ocfs2_delete_osb(struct ocfs2_super *osb) { + mlog_entry_void(); + /* This function assumes that the caller has the main osb resource */ ocfs2_free_slot_info(osb); @@ -2547,6 +2580,8 @@ static void ocfs2_delete_osb(struct ocfs2_super *osb) kfree(osb->uuid_str); ocfs2_put_dlm_debug(osb->osb_dlm_debug); memset(osb, 0, sizeof(struct ocfs2_super)); + + mlog_exit_void(); } /* Put OCFS2 into a readonly state, or (if the user specifies it), diff --git a/trunk/fs/ocfs2/symlink.c b/trunk/fs/ocfs2/symlink.c index 5d22872e2bb3..9975457c981f 100644 --- a/trunk/fs/ocfs2/symlink.c +++ b/trunk/fs/ocfs2/symlink.c @@ -40,6 +40,7 @@ #include #include +#define MLOG_MASK_PREFIX ML_NAMEI #include #include "ocfs2.h" @@ -61,6 +62,8 @@ static char *ocfs2_fast_symlink_getlink(struct inode *inode, char *link = NULL; struct ocfs2_dinode *fe; + mlog_entry_void(); + status = ocfs2_read_inode_block(inode, bh); if (status < 0) { mlog_errno(status); @@ -71,6 +74,7 @@ static char *ocfs2_fast_symlink_getlink(struct inode *inode, fe = (struct ocfs2_dinode *) (*bh)->b_data; link = (char *) fe->id2.i_symlink; bail: + mlog_exit(status); return link; } @@ -84,6 +88,8 @@ static int ocfs2_readlink(struct dentry *dentry, struct buffer_head *bh = NULL; struct inode *inode = dentry->d_inode; + mlog_entry_void(); + link = ocfs2_fast_symlink_getlink(inode, &bh); if (IS_ERR(link)) { ret = PTR_ERR(link); @@ -98,8 +104,7 @@ static int ocfs2_readlink(struct dentry *dentry, brelse(bh); out: - if (ret < 0) - mlog_errno(ret); + mlog_exit(ret); return ret; } @@ -112,6 +117,8 @@ static void *ocfs2_fast_follow_link(struct dentry *dentry, struct inode *inode = dentry->d_inode; struct buffer_head *bh = NULL; + mlog_entry_void(); + BUG_ON(!ocfs2_inode_is_fast_symlink(inode)); target = ocfs2_fast_symlink_getlink(inode, &bh); if (IS_ERR(target)) { @@ -135,8 +142,7 @@ static void *ocfs2_fast_follow_link(struct dentry *dentry, nd_set_link(nd, status ? ERR_PTR(status) : link); brelse(bh); - if (status) - mlog_errno(status); + mlog_exit(status); return NULL; } diff --git a/trunk/fs/ocfs2/sysfile.c b/trunk/fs/ocfs2/sysfile.c index 3d635f4bbb20..902efb23b6a6 100644 --- a/trunk/fs/ocfs2/sysfile.c +++ b/trunk/fs/ocfs2/sysfile.c @@ -27,6 +27,7 @@ #include #include +#define MLOG_MASK_PREFIX ML_INODE #include #include "ocfs2.h" diff --git a/trunk/fs/ocfs2/uptodate.c b/trunk/fs/ocfs2/uptodate.c index 52eaf33d346f..a0a120e82b97 100644 --- a/trunk/fs/ocfs2/uptodate.c +++ b/trunk/fs/ocfs2/uptodate.c @@ -54,13 +54,14 @@ #include #include +#define MLOG_MASK_PREFIX ML_UPTODATE + #include #include "ocfs2.h" #include "inode.h" #include "uptodate.h" -#include "ocfs2_trace.h" struct ocfs2_meta_cache_item { struct rb_node c_node; @@ -151,8 +152,8 @@ static unsigned int ocfs2_purge_copied_metadata_tree(struct rb_root *root) while ((node = rb_last(root)) != NULL) { item = rb_entry(node, struct ocfs2_meta_cache_item, c_node); - trace_ocfs2_purge_copied_metadata_tree( - (unsigned long long) item->c_block); + mlog(0, "Purge item %llu\n", + (unsigned long long) item->c_block); rb_erase(&item->c_node, root); kmem_cache_free(ocfs2_uptodate_cachep, item); @@ -179,9 +180,9 @@ void ocfs2_metadata_cache_purge(struct ocfs2_caching_info *ci) tree = !(ci->ci_flags & OCFS2_CACHE_FL_INLINE); to_purge = ci->ci_num_cached; - trace_ocfs2_metadata_cache_purge( - (unsigned long long)ocfs2_metadata_cache_owner(ci), - to_purge, tree); + mlog(0, "Purge %u %s items from Owner %llu\n", to_purge, + tree ? "array" : "tree", + (unsigned long long)ocfs2_metadata_cache_owner(ci)); /* If we're a tree, save off the root so that we can safely * initialize the cache. We do the work to free tree members @@ -248,10 +249,10 @@ static int ocfs2_buffer_cached(struct ocfs2_caching_info *ci, ocfs2_metadata_cache_lock(ci); - trace_ocfs2_buffer_cached_begin( - (unsigned long long)ocfs2_metadata_cache_owner(ci), - (unsigned long long) bh->b_blocknr, - !!(ci->ci_flags & OCFS2_CACHE_FL_INLINE)); + mlog(0, "Owner %llu, query block %llu (inline = %u)\n", + (unsigned long long)ocfs2_metadata_cache_owner(ci), + (unsigned long long) bh->b_blocknr, + !!(ci->ci_flags & OCFS2_CACHE_FL_INLINE)); if (ci->ci_flags & OCFS2_CACHE_FL_INLINE) index = ocfs2_search_cache_array(ci, bh->b_blocknr); @@ -260,7 +261,7 @@ static int ocfs2_buffer_cached(struct ocfs2_caching_info *ci, ocfs2_metadata_cache_unlock(ci); - trace_ocfs2_buffer_cached_end(index, item); + mlog(0, "index = %d, item = %p\n", index, item); return (index != -1) || (item != NULL); } @@ -305,9 +306,8 @@ static void ocfs2_append_cache_array(struct ocfs2_caching_info *ci, { BUG_ON(ci->ci_num_cached >= OCFS2_CACHE_INFO_MAX_ARRAY); - trace_ocfs2_append_cache_array( - (unsigned long long)ocfs2_metadata_cache_owner(ci), - (unsigned long long)block, ci->ci_num_cached); + mlog(0, "block %llu takes position %u\n", (unsigned long long) block, + ci->ci_num_cached); ci->ci_cache.ci_array[ci->ci_num_cached] = block; ci->ci_num_cached++; @@ -324,9 +324,8 @@ static void __ocfs2_insert_cache_tree(struct ocfs2_caching_info *ci, struct rb_node **p = &ci->ci_cache.ci_tree.rb_node; struct ocfs2_meta_cache_item *tmp; - trace_ocfs2_insert_cache_tree( - (unsigned long long)ocfs2_metadata_cache_owner(ci), - (unsigned long long)block, ci->ci_num_cached); + mlog(0, "Insert block %llu num = %u\n", (unsigned long long) block, + ci->ci_num_cached); while(*p) { parent = *p; @@ -390,9 +389,9 @@ static void ocfs2_expand_cache(struct ocfs2_caching_info *ci, tree[i] = NULL; } - trace_ocfs2_expand_cache( - (unsigned long long)ocfs2_metadata_cache_owner(ci), - ci->ci_flags, ci->ci_num_cached); + mlog(0, "Expanded %llu to a tree cache: flags 0x%x, num = %u\n", + (unsigned long long)ocfs2_metadata_cache_owner(ci), + ci->ci_flags, ci->ci_num_cached); } /* Slow path function - memory allocation is necessary. See the @@ -406,9 +405,9 @@ static void __ocfs2_set_buffer_uptodate(struct ocfs2_caching_info *ci, struct ocfs2_meta_cache_item *tree[OCFS2_CACHE_INFO_MAX_ARRAY] = { NULL, }; - trace_ocfs2_set_buffer_uptodate( - (unsigned long long)ocfs2_metadata_cache_owner(ci), - (unsigned long long)block, expand_tree); + mlog(0, "Owner %llu, block %llu, expand = %d\n", + (unsigned long long)ocfs2_metadata_cache_owner(ci), + (unsigned long long)block, expand_tree); new = kmem_cache_alloc(ocfs2_uptodate_cachep, GFP_NOFS); if (!new) { @@ -434,6 +433,7 @@ static void __ocfs2_set_buffer_uptodate(struct ocfs2_caching_info *ci, ocfs2_metadata_cache_lock(ci); if (ocfs2_insert_can_use_array(ci)) { + mlog(0, "Someone cleared the tree underneath us\n"); /* Ok, items were removed from the cache in between * locks. Detect this and revert back to the fast path */ ocfs2_append_cache_array(ci, block); @@ -490,9 +490,9 @@ void ocfs2_set_buffer_uptodate(struct ocfs2_caching_info *ci, if (ocfs2_buffer_cached(ci, bh)) return; - trace_ocfs2_set_buffer_uptodate_begin( - (unsigned long long)ocfs2_metadata_cache_owner(ci), - (unsigned long long)bh->b_blocknr); + mlog(0, "Owner %llu, inserting block %llu\n", + (unsigned long long)ocfs2_metadata_cache_owner(ci), + (unsigned long long)bh->b_blocknr); /* No need to recheck under spinlock - insertion is guarded by * co_io_lock() */ @@ -542,9 +542,8 @@ static void ocfs2_remove_metadata_array(struct ocfs2_caching_info *ci, BUG_ON(index >= ci->ci_num_cached); BUG_ON(!ci->ci_num_cached); - trace_ocfs2_remove_metadata_array( - (unsigned long long)ocfs2_metadata_cache_owner(ci), - index, ci->ci_num_cached); + mlog(0, "remove index %d (num_cached = %u\n", index, + ci->ci_num_cached); ci->ci_num_cached--; @@ -560,9 +559,8 @@ static void ocfs2_remove_metadata_array(struct ocfs2_caching_info *ci, static void ocfs2_remove_metadata_tree(struct ocfs2_caching_info *ci, struct ocfs2_meta_cache_item *item) { - trace_ocfs2_remove_metadata_tree( - (unsigned long long)ocfs2_metadata_cache_owner(ci), - (unsigned long long)item->c_block); + mlog(0, "remove block %llu from tree\n", + (unsigned long long) item->c_block); rb_erase(&item->c_node, &ci->ci_cache.ci_tree); ci->ci_num_cached--; @@ -575,10 +573,10 @@ static void ocfs2_remove_block_from_cache(struct ocfs2_caching_info *ci, struct ocfs2_meta_cache_item *item = NULL; ocfs2_metadata_cache_lock(ci); - trace_ocfs2_remove_block_from_cache( - (unsigned long long)ocfs2_metadata_cache_owner(ci), - (unsigned long long) block, ci->ci_num_cached, - ci->ci_flags); + mlog(0, "Owner %llu, remove %llu, items = %u, array = %u\n", + (unsigned long long)ocfs2_metadata_cache_owner(ci), + (unsigned long long) block, ci->ci_num_cached, + ci->ci_flags & OCFS2_CACHE_FL_INLINE); if (ci->ci_flags & OCFS2_CACHE_FL_INLINE) { index = ocfs2_search_cache_array(ci, block); @@ -628,6 +626,9 @@ int __init init_ocfs2_uptodate_cache(void) if (!ocfs2_uptodate_cachep) return -ENOMEM; + mlog(0, "%u inlined cache items per inode.\n", + OCFS2_CACHE_INFO_MAX_ARRAY); + return 0; } diff --git a/trunk/fs/ocfs2/xattr.c b/trunk/fs/ocfs2/xattr.c index 57a215dc2d9b..6bb602486c6b 100644 --- a/trunk/fs/ocfs2/xattr.c +++ b/trunk/fs/ocfs2/xattr.c @@ -37,6 +37,7 @@ #include #include +#define MLOG_MASK_PREFIX ML_XATTR #include #include "ocfs2.h" @@ -56,7 +57,6 @@ #include "xattr.h" #include "refcounttree.h" #include "acl.h" -#include "ocfs2_trace.h" struct ocfs2_xattr_def_value_root { struct ocfs2_xattr_value_root xv; @@ -474,7 +474,8 @@ static int ocfs2_validate_xattr_block(struct super_block *sb, struct ocfs2_xattr_block *xb = (struct ocfs2_xattr_block *)bh->b_data; - trace_ocfs2_validate_xattr_block((unsigned long long)bh->b_blocknr); + mlog(0, "Validating xattr block %llu\n", + (unsigned long long)bh->b_blocknr); BUG_ON(!buffer_uptodate(bh)); @@ -714,11 +715,11 @@ static int ocfs2_xattr_extend_allocation(struct inode *inode, u32 prev_clusters, logical_start = le32_to_cpu(vb->vb_xv->xr_clusters); struct ocfs2_extent_tree et; + mlog(0, "(clusters_to_add for xattr= %u)\n", clusters_to_add); + ocfs2_init_xattr_value_extent_tree(&et, INODE_CACHE(inode), vb); while (clusters_to_add) { - trace_ocfs2_xattr_extend_allocation(clusters_to_add); - status = vb->vb_access(handle, INODE_CACHE(inode), vb->vb_bh, OCFS2_JOURNAL_ACCESS_WRITE); if (status < 0) { @@ -753,6 +754,8 @@ static int ocfs2_xattr_extend_allocation(struct inode *inode, */ BUG_ON(why == RESTART_META); + mlog(0, "restarting xattr value extension for %u" + " clusters,.\n", clusters_to_add); credits = ocfs2_calc_extend_credits(inode->i_sb, &vb->vb_xv->xr_list, clusters_to_add); @@ -3243,8 +3246,8 @@ static int ocfs2_init_xattr_set_ctxt(struct inode *inode, } meta_add += extra_meta; - trace_ocfs2_init_xattr_set_ctxt(xi->xi_name, meta_add, - clusters_add, *credits); + mlog(0, "Set xattr %s, reserve meta blocks = %d, clusters = %d, " + "credits = %d\n", xi->xi_name, meta_add, clusters_add, *credits); if (meta_add) { ret = ocfs2_reserve_new_metadata_blocks(osb, meta_add, @@ -3884,10 +3887,8 @@ static int ocfs2_xattr_bucket_find(struct inode *inode, if (found) { xs->here = &xs->header->xh_entries[index]; - trace_ocfs2_xattr_bucket_find(OCFS2_I(inode)->ip_blkno, - name, name_index, name_hash, - (unsigned long long)bucket_blkno(xs->bucket), - index); + mlog(0, "find xattr %s in bucket %llu, entry = %u\n", name, + (unsigned long long)bucket_blkno(xs->bucket), index); } else ret = -ENODATA; @@ -3914,10 +3915,8 @@ static int ocfs2_xattr_index_block_find(struct inode *inode, if (le16_to_cpu(el->l_next_free_rec) == 0) return -ENODATA; - trace_ocfs2_xattr_index_block_find(OCFS2_I(inode)->ip_blkno, - name, name_index, name_hash, - (unsigned long long)root_bh->b_blocknr, - -1); + mlog(0, "find xattr %s, hash = %u, index = %d in xattr tree\n", + name, name_hash, name_index); ret = ocfs2_xattr_get_rec(inode, name_hash, &p_blkno, &first_hash, &num_clusters, el); @@ -3928,10 +3927,9 @@ static int ocfs2_xattr_index_block_find(struct inode *inode, BUG_ON(p_blkno == 0 || num_clusters == 0 || first_hash > name_hash); - trace_ocfs2_xattr_index_block_find_rec(OCFS2_I(inode)->ip_blkno, - name, name_index, first_hash, - (unsigned long long)p_blkno, - num_clusters); + mlog(0, "find xattr extent rec %u clusters from %llu, the first hash " + "in the rec is %u\n", num_clusters, (unsigned long long)p_blkno, + first_hash); ret = ocfs2_xattr_bucket_find(inode, name_index, name, name_hash, p_blkno, first_hash, num_clusters, xs); @@ -3957,9 +3955,8 @@ static int ocfs2_iterate_xattr_buckets(struct inode *inode, return -ENOMEM; } - trace_ocfs2_iterate_xattr_buckets( - (unsigned long long)OCFS2_I(inode)->ip_blkno, - (unsigned long long)blkno, clusters); + mlog(0, "iterating xattr buckets in %u clusters starting from %llu\n", + clusters, (unsigned long long)blkno); for (i = 0; i < num_buckets; i++, blkno += bucket->bu_blocks) { ret = ocfs2_read_xattr_bucket(bucket, blkno); @@ -3975,7 +3972,8 @@ static int ocfs2_iterate_xattr_buckets(struct inode *inode, if (i == 0) num_buckets = le16_to_cpu(bucket_xh(bucket)->xh_num_buckets); - trace_ocfs2_iterate_xattr_bucket((unsigned long long)blkno, + mlog(0, "iterating xattr bucket %llu, first hash %u\n", + (unsigned long long)blkno, le32_to_cpu(bucket_xh(bucket)->xh_entries[0].xe_name_hash)); if (func) { ret = func(inode, bucket, para); @@ -4175,9 +4173,9 @@ static void ocfs2_cp_xattr_block_to_bucket(struct inode *inode, char *src = xb_bh->b_data; char *target = bucket_block(bucket, blks - 1); - trace_ocfs2_cp_xattr_block_to_bucket_begin( - (unsigned long long)xb_bh->b_blocknr, - (unsigned long long)bucket_blkno(bucket)); + mlog(0, "cp xattr from block %llu to bucket %llu\n", + (unsigned long long)xb_bh->b_blocknr, + (unsigned long long)bucket_blkno(bucket)); for (i = 0; i < blks; i++) memset(bucket_block(bucket, i), 0, blocksize); @@ -4213,7 +4211,8 @@ static void ocfs2_cp_xattr_block_to_bucket(struct inode *inode, for (i = 0; i < count; i++) le16_add_cpu(&xh->xh_entries[i].xe_name_offset, off_change); - trace_ocfs2_cp_xattr_block_to_bucket_end(offset, size, off_change); + mlog(0, "copy entry: start = %u, size = %u, offset_change = %u\n", + offset, size, off_change); sort(target + offset, count, sizeof(struct ocfs2_xattr_entry), cmp_xe, swap_xe); @@ -4262,8 +4261,8 @@ static int ocfs2_xattr_create_index_block(struct inode *inode, struct ocfs2_xattr_tree_root *xr; u16 xb_flags = le16_to_cpu(xb->xb_flags); - trace_ocfs2_xattr_create_index_block_begin( - (unsigned long long)xb_bh->b_blocknr); + mlog(0, "create xattr index block for %llu\n", + (unsigned long long)xb_bh->b_blocknr); BUG_ON(xb_flags & OCFS2_XATTR_INDEXED); BUG_ON(!xs->bucket); @@ -4296,7 +4295,8 @@ static int ocfs2_xattr_create_index_block(struct inode *inode, */ blkno = ocfs2_clusters_to_blocks(inode->i_sb, bit_off); - trace_ocfs2_xattr_create_index_block((unsigned long long)blkno); + mlog(0, "allocate 1 cluster from %llu to xattr block\n", + (unsigned long long)blkno); ret = ocfs2_init_xattr_bucket(xs->bucket, blkno); if (ret) { @@ -4400,7 +4400,8 @@ static int ocfs2_defrag_xattr_bucket(struct inode *inode, entries = (char *)xh->xh_entries; xh_free_start = le16_to_cpu(xh->xh_free_start); - trace_ocfs2_defrag_xattr_bucket( + mlog(0, "adjust xattr bucket in %llu, count = %u, " + "xh_free_start = %u, xh_name_value_len = %u.\n", (unsigned long long)blkno, le16_to_cpu(xh->xh_count), xh_free_start, le16_to_cpu(xh->xh_name_value_len)); @@ -4502,9 +4503,8 @@ static int ocfs2_mv_xattr_bucket_cross_cluster(struct inode *inode, BUG_ON(le16_to_cpu(bucket_xh(first)->xh_num_buckets) < num_buckets); BUG_ON(OCFS2_XATTR_BUCKET_SIZE == OCFS2_SB(sb)->s_clustersize); - trace_ocfs2_mv_xattr_bucket_cross_cluster( - (unsigned long long)last_cluster_blkno, - (unsigned long long)new_blkno); + mlog(0, "move half of xattrs in cluster %llu to %llu\n", + (unsigned long long)last_cluster_blkno, (unsigned long long)new_blkno); ret = ocfs2_mv_xattr_buckets(inode, handle, bucket_blkno(first), last_cluster_blkno, new_blkno, @@ -4614,8 +4614,8 @@ static int ocfs2_divide_xattr_bucket(struct inode *inode, struct ocfs2_xattr_entry *xe; int blocksize = inode->i_sb->s_blocksize; - trace_ocfs2_divide_xattr_bucket_begin((unsigned long long)blk, - (unsigned long long)new_blk); + mlog(0, "move some of xattrs from bucket %llu to %llu\n", + (unsigned long long)blk, (unsigned long long)new_blk); s_bucket = ocfs2_xattr_bucket_new(inode); t_bucket = ocfs2_xattr_bucket_new(inode); @@ -4714,9 +4714,9 @@ static int ocfs2_divide_xattr_bucket(struct inode *inode, */ xe = &xh->xh_entries[start]; len = sizeof(struct ocfs2_xattr_entry) * (count - start); - trace_ocfs2_divide_xattr_bucket_move(len, - (int)((char *)xe - (char *)xh), - (int)((char *)xh->xh_entries - (char *)xh)); + mlog(0, "mv xattr entry len %d from %d to %d\n", len, + (int)((char *)xe - (char *)xh), + (int)((char *)xh->xh_entries - (char *)xh)); memmove((char *)xh->xh_entries, (char *)xe, len); xe = &xh->xh_entries[count - start]; len = sizeof(struct ocfs2_xattr_entry) * start; @@ -4788,9 +4788,9 @@ static int ocfs2_cp_xattr_bucket(struct inode *inode, BUG_ON(s_blkno == t_blkno); - trace_ocfs2_cp_xattr_bucket((unsigned long long)s_blkno, - (unsigned long long)t_blkno, - t_is_new); + mlog(0, "cp bucket %llu to %llu, target is %d\n", + (unsigned long long)s_blkno, (unsigned long long)t_blkno, + t_is_new); s_bucket = ocfs2_xattr_bucket_new(inode); t_bucket = ocfs2_xattr_bucket_new(inode); @@ -4862,8 +4862,8 @@ static int ocfs2_mv_xattr_buckets(struct inode *inode, handle_t *handle, int num_buckets = ocfs2_xattr_buckets_per_cluster(osb); struct ocfs2_xattr_bucket *old_first, *new_first; - trace_ocfs2_mv_xattr_buckets((unsigned long long)last_blk, - (unsigned long long)to_blk); + mlog(0, "mv xattrs from cluster %llu to %llu\n", + (unsigned long long)last_blk, (unsigned long long)to_blk); BUG_ON(start_bucket >= num_buckets); if (start_bucket) { @@ -5013,9 +5013,9 @@ static int ocfs2_adjust_xattr_cross_cluster(struct inode *inode, { int ret; - trace_ocfs2_adjust_xattr_cross_cluster( - (unsigned long long)bucket_blkno(first), - (unsigned long long)new_blk, prev_clusters); + mlog(0, "adjust xattrs from cluster %llu len %u to %llu\n", + (unsigned long long)bucket_blkno(first), prev_clusters, + (unsigned long long)new_blk); if (ocfs2_xattr_buckets_per_cluster(OCFS2_SB(inode->i_sb)) > 1) { ret = ocfs2_mv_xattr_bucket_cross_cluster(inode, @@ -5088,10 +5088,10 @@ static int ocfs2_add_new_xattr_cluster(struct inode *inode, struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); struct ocfs2_extent_tree et; - trace_ocfs2_add_new_xattr_cluster_begin( - (unsigned long long)OCFS2_I(inode)->ip_blkno, - (unsigned long long)bucket_blkno(first), - prev_cpos, prev_clusters); + mlog(0, "Add new xattr cluster for %llu, previous xattr hash = %u, " + "previous xattr blkno = %llu\n", + (unsigned long long)OCFS2_I(inode)->ip_blkno, + prev_cpos, (unsigned long long)bucket_blkno(first)); ocfs2_init_xattr_tree_extent_tree(&et, INODE_CACHE(inode), root_bh); @@ -5113,7 +5113,8 @@ static int ocfs2_add_new_xattr_cluster(struct inode *inode, BUG_ON(num_bits > clusters_to_add); block = ocfs2_clusters_to_blocks(osb->sb, bit_off); - trace_ocfs2_add_new_xattr_cluster((unsigned long long)block, num_bits); + mlog(0, "Allocating %u clusters at block %u for xattr in inode %llu\n", + num_bits, bit_off, (unsigned long long)OCFS2_I(inode)->ip_blkno); if (bucket_blkno(first) + (prev_clusters * bpc) == block && (prev_clusters + num_bits) << osb->s_clustersize_bits <= @@ -5129,6 +5130,8 @@ static int ocfs2_add_new_xattr_cluster(struct inode *inode, */ v_start = prev_cpos + prev_clusters; *num_clusters = prev_clusters + num_bits; + mlog(0, "Add contiguous %u clusters to previous extent rec.\n", + num_bits); } else { ret = ocfs2_adjust_xattr_cross_cluster(inode, handle, @@ -5144,8 +5147,8 @@ static int ocfs2_add_new_xattr_cluster(struct inode *inode, } } - trace_ocfs2_add_new_xattr_cluster_insert((unsigned long long)block, - v_start, num_bits); + mlog(0, "Insert %u clusters at block %llu for xattr at %u\n", + num_bits, (unsigned long long)block, v_start); ret = ocfs2_insert_extent(handle, &et, v_start, block, num_bits, 0, ctxt->meta_ac); if (ret < 0) { @@ -5180,9 +5183,9 @@ static int ocfs2_extend_xattr_bucket(struct inode *inode, u64 end_blk; u16 new_bucket = le16_to_cpu(bucket_xh(first)->xh_num_buckets); - trace_ocfs2_extend_xattr_bucket((unsigned long long)target_blk, - (unsigned long long)bucket_blkno(first), - num_clusters, new_bucket); + mlog(0, "extend xattr bucket in %llu, xattr extend rec starting " + "from %llu, len = %u\n", (unsigned long long)target_blk, + (unsigned long long)bucket_blkno(first), num_clusters); /* The extent must have room for an additional bucket */ BUG_ON(new_bucket >= @@ -5262,8 +5265,8 @@ static int ocfs2_add_new_xattr_bucket(struct inode *inode, /* The bucket at the front of the extent */ struct ocfs2_xattr_bucket *first; - trace_ocfs2_add_new_xattr_bucket( - (unsigned long long)bucket_blkno(target)); + mlog(0, "Add new xattr bucket starting from %llu\n", + (unsigned long long)bucket_blkno(target)); /* The first bucket of the original extent */ first = ocfs2_xattr_bucket_new(inode); @@ -5379,8 +5382,8 @@ static int ocfs2_xattr_bucket_value_truncate(struct inode *inode, * modified something. We have to assume they did, and dirty * the whole bucket. This leaves us in a consistent state. */ - trace_ocfs2_xattr_bucket_value_truncate( - (unsigned long long)bucket_blkno(bucket), xe_off, len); + mlog(0, "truncate %u in xattr bucket %llu to %d bytes.\n", + xe_off, (unsigned long long)bucket_blkno(bucket), len); ret = ocfs2_xattr_value_truncate(inode, &vb, len, ctxt); if (ret) { mlog_errno(ret); @@ -5430,9 +5433,8 @@ static int ocfs2_rm_xattr_cluster(struct inode *inode, ocfs2_init_dealloc_ctxt(&dealloc); - trace_ocfs2_rm_xattr_cluster( - (unsigned long long)OCFS2_I(inode)->ip_blkno, - (unsigned long long)blkno, cpos, len); + mlog(0, "rm xattr extent rec at %u len = %u, start from %llu\n", + cpos, len, (unsigned long long)blkno); ocfs2_remove_xattr_clusters_from_cache(INODE_CACHE(inode), blkno, len); @@ -5536,7 +5538,7 @@ static int ocfs2_xattr_set_entry_bucket(struct inode *inode, int ret; struct ocfs2_xa_loc loc; - trace_ocfs2_xattr_set_entry_bucket(xi->xi_name); + mlog_entry("Set xattr %s in xattr bucket\n", xi->xi_name); ocfs2_init_xattr_bucket_xa_loc(&loc, xs->bucket, xs->not_found ? NULL : xs->here); @@ -5568,6 +5570,7 @@ static int ocfs2_xattr_set_entry_bucket(struct inode *inode, out: + mlog_exit(ret); return ret; } @@ -5578,7 +5581,7 @@ static int ocfs2_xattr_set_entry_index_block(struct inode *inode, { int ret; - trace_ocfs2_xattr_set_entry_index_block(xi->xi_name); + mlog_entry("Set xattr %s in xattr index block\n", xi->xi_name); ret = ocfs2_xattr_set_entry_bucket(inode, xi, xs, ctxt); if (!ret) @@ -5634,6 +5637,7 @@ static int ocfs2_xattr_set_entry_index_block(struct inode *inode, mlog_errno(ret); out: + mlog_exit(ret); return ret; } @@ -6037,9 +6041,9 @@ static int ocfs2_xattr_bucket_value_refcount(struct inode *inode, if (ocfs2_meta_ecc(OCFS2_SB(inode->i_sb))) p = &refcount; - trace_ocfs2_xattr_bucket_value_refcount( - (unsigned long long)bucket_blkno(bucket), - le16_to_cpu(xh->xh_count)); + mlog(0, "refcount bucket %llu, count = %u\n", + (unsigned long long)bucket_blkno(bucket), + le16_to_cpu(xh->xh_count)); for (i = 0; i < le16_to_cpu(xh->xh_count); i++) { xe = &xh->xh_entries[i]; @@ -6335,8 +6339,8 @@ static int ocfs2_reflink_xattr_header(handle_t *handle, u32 clusters, cpos, p_cluster, num_clusters; unsigned int ext_flags = 0; - trace_ocfs2_reflink_xattr_header((unsigned long long)old_bh->b_blocknr, - le16_to_cpu(xh->xh_count)); + mlog(0, "reflink xattr in container %llu, count = %u\n", + (unsigned long long)old_bh->b_blocknr, le16_to_cpu(xh->xh_count)); last = &new_xh->xh_entries[le16_to_cpu(new_xh->xh_count)]; for (i = 0, j = 0; i < le16_to_cpu(xh->xh_count); i++, j++) { @@ -6536,8 +6540,8 @@ static int ocfs2_create_empty_xattr_block(struct inode *inode, goto out; } - trace_ocfs2_create_empty_xattr_block( - (unsigned long long)fe_bh->b_blocknr, indexed); + mlog(0, "create new xattr block for inode %llu, index = %d\n", + (unsigned long long)fe_bh->b_blocknr, indexed); ret = ocfs2_create_xattr_block(inode, fe_bh, &ctxt, indexed, ret_bh); if (ret) @@ -6948,8 +6952,8 @@ static int ocfs2_reflink_xattr_buckets(handle_t *handle, if (ret) mlog_errno(ret); - trace_ocfs2_reflink_xattr_buckets((unsigned long long)new_blkno, - num_clusters, reflink_cpos); + mlog(0, "insert new xattr extent rec start %llu len %u to %u\n", + (unsigned long long)new_blkno, num_clusters, reflink_cpos); len -= num_clusters; blkno += ocfs2_clusters_to_blocks(inode->i_sb, num_clusters); @@ -6978,7 +6982,8 @@ static int ocfs2_reflink_xattr_rec(struct inode *inode, struct ocfs2_alloc_context *data_ac = NULL; struct ocfs2_extent_tree et; - trace_ocfs2_reflink_xattr_rec((unsigned long long)blkno, len); + mlog(0, "reflink xattr buckets %llu len %u\n", + (unsigned long long)blkno, len); ocfs2_init_xattr_tree_extent_tree(&et, INODE_CACHE(args->reflink->new_inode), diff --git a/trunk/fs/proc/task_mmu.c b/trunk/fs/proc/task_mmu.c index 2e7addfd9803..7c708a418acc 100644 --- a/trunk/fs/proc/task_mmu.c +++ b/trunk/fs/proc/task_mmu.c @@ -182,8 +182,7 @@ static void m_stop(struct seq_file *m, void *v) struct proc_maps_private *priv = m->private; struct vm_area_struct *vma = v; - if (!IS_ERR(vma)) - vma_stop(priv, vma); + vma_stop(priv, vma); if (priv->task) put_task_struct(priv->task); } diff --git a/trunk/fs/xfs/linux-2.6/xfs_buf.c b/trunk/fs/xfs/linux-2.6/xfs_buf.c index 596bb2c9de42..c05324d3282c 100644 --- a/trunk/fs/xfs/linux-2.6/xfs_buf.c +++ b/trunk/fs/xfs/linux-2.6/xfs_buf.c @@ -93,6 +93,75 @@ xfs_buf_vmap_len( return (bp->b_page_count * PAGE_SIZE) - bp->b_offset; } +/* + * Page Region interfaces. + * + * For pages in filesystems where the blocksize is smaller than the + * pagesize, we use the page->private field (long) to hold a bitmap + * of uptodate regions within the page. + * + * Each such region is "bytes per page / bits per long" bytes long. + * + * NBPPR == number-of-bytes-per-page-region + * BTOPR == bytes-to-page-region (rounded up) + * BTOPRT == bytes-to-page-region-truncated (rounded down) + */ +#if (BITS_PER_LONG == 32) +#define PRSHIFT (PAGE_CACHE_SHIFT - 5) /* (32 == 1<<5) */ +#elif (BITS_PER_LONG == 64) +#define PRSHIFT (PAGE_CACHE_SHIFT - 6) /* (64 == 1<<6) */ +#else +#error BITS_PER_LONG must be 32 or 64 +#endif +#define NBPPR (PAGE_CACHE_SIZE/BITS_PER_LONG) +#define BTOPR(b) (((unsigned int)(b) + (NBPPR - 1)) >> PRSHIFT) +#define BTOPRT(b) (((unsigned int)(b) >> PRSHIFT)) + +STATIC unsigned long +page_region_mask( + size_t offset, + size_t length) +{ + unsigned long mask; + int first, final; + + first = BTOPR(offset); + final = BTOPRT(offset + length - 1); + first = min(first, final); + + mask = ~0UL; + mask <<= BITS_PER_LONG - (final - first); + mask >>= BITS_PER_LONG - (final); + + ASSERT(offset + length <= PAGE_CACHE_SIZE); + ASSERT((final - first) < BITS_PER_LONG && (final - first) >= 0); + + return mask; +} + +STATIC void +set_page_region( + struct page *page, + size_t offset, + size_t length) +{ + set_page_private(page, + page_private(page) | page_region_mask(offset, length)); + if (page_private(page) == ~0UL) + SetPageUptodate(page); +} + +STATIC int +test_page_region( + struct page *page, + size_t offset, + size_t length) +{ + unsigned long mask = page_region_mask(offset, length); + + return (mask && (page_private(page) & mask) == mask); +} + /* * xfs_buf_lru_add - add a buffer to the LRU. * @@ -263,7 +332,7 @@ xfs_buf_free( ASSERT(list_empty(&bp->b_lru)); - if (bp->b_flags & _XBF_PAGES) { + if (bp->b_flags & (_XBF_PAGE_CACHE|_XBF_PAGES)) { uint i; if (xfs_buf_is_vmapped(bp)) @@ -273,22 +342,25 @@ xfs_buf_free( for (i = 0; i < bp->b_page_count; i++) { struct page *page = bp->b_pages[i]; - __free_page(page); + if (bp->b_flags & _XBF_PAGE_CACHE) + ASSERT(!PagePrivate(page)); + page_cache_release(page); } - } else if (bp->b_flags & _XBF_KMEM) - kmem_free(bp->b_addr); + } _xfs_buf_free_pages(bp); xfs_buf_deallocate(bp); } /* - * Allocates all the pages for buffer in question and builds it's page list. + * Finds all pages for buffer in question and builds it's page list. */ STATIC int -xfs_buf_allocate_memory( +_xfs_buf_lookup_pages( xfs_buf_t *bp, uint flags) { + struct address_space *mapping = bp->b_target->bt_mapping; + size_t blocksize = bp->b_target->bt_bsize; size_t size = bp->b_count_desired; size_t nbytes, offset; gfp_t gfp_mask = xb_to_gfp(flags); @@ -297,55 +369,29 @@ xfs_buf_allocate_memory( xfs_off_t end; int error; - /* - * for buffers that are contained within a single page, just allocate - * the memory from the heap - there's no need for the complexity of - * page arrays to keep allocation down to order 0. - */ - if (bp->b_buffer_length < PAGE_SIZE) { - bp->b_addr = kmem_alloc(bp->b_buffer_length, xb_to_km(flags)); - if (!bp->b_addr) { - /* low memory - use alloc_page loop instead */ - goto use_alloc_page; - } - - if (((unsigned long)(bp->b_addr + bp->b_buffer_length - 1) & - PAGE_MASK) != - ((unsigned long)bp->b_addr & PAGE_MASK)) { - /* b_addr spans two pages - use alloc_page instead */ - kmem_free(bp->b_addr); - bp->b_addr = NULL; - goto use_alloc_page; - } - bp->b_offset = offset_in_page(bp->b_addr); - bp->b_pages = bp->b_page_array; - bp->b_pages[0] = virt_to_page(bp->b_addr); - bp->b_page_count = 1; - bp->b_flags |= XBF_MAPPED | _XBF_KMEM; - return 0; - } - -use_alloc_page: end = bp->b_file_offset + bp->b_buffer_length; page_count = xfs_buf_btoc(end) - xfs_buf_btoct(bp->b_file_offset); + error = _xfs_buf_get_pages(bp, page_count, flags); if (unlikely(error)) return error; + bp->b_flags |= _XBF_PAGE_CACHE; offset = bp->b_offset; - first = bp->b_file_offset >> PAGE_SHIFT; - bp->b_flags |= _XBF_PAGES; + first = bp->b_file_offset >> PAGE_CACHE_SHIFT; for (i = 0; i < bp->b_page_count; i++) { struct page *page; uint retries = 0; -retry: - page = alloc_page(gfp_mask); + + retry: + page = find_or_create_page(mapping, first + i, gfp_mask); if (unlikely(page == NULL)) { if (flags & XBF_READ_AHEAD) { bp->b_page_count = i; - error = ENOMEM; - goto out_free_pages; + for (i = 0; i < bp->b_page_count; i++) + unlock_page(bp->b_pages[i]); + return -ENOMEM; } /* @@ -366,16 +412,33 @@ xfs_buf_allocate_memory( XFS_STATS_INC(xb_page_found); - nbytes = min_t(size_t, size, PAGE_SIZE - offset); + nbytes = min_t(size_t, size, PAGE_CACHE_SIZE - offset); size -= nbytes; + + ASSERT(!PagePrivate(page)); + if (!PageUptodate(page)) { + page_count--; + if (blocksize >= PAGE_CACHE_SIZE) { + if (flags & XBF_READ) + bp->b_flags |= _XBF_PAGE_LOCKED; + } else if (!PagePrivate(page)) { + if (test_page_region(page, offset, nbytes)) + page_count++; + } + } + bp->b_pages[i] = page; offset = 0; } - return 0; -out_free_pages: - for (i = 0; i < bp->b_page_count; i++) - __free_page(bp->b_pages[i]); + if (!(bp->b_flags & _XBF_PAGE_LOCKED)) { + for (i = 0; i < bp->b_page_count; i++) + unlock_page(bp->b_pages[i]); + } + + if (page_count == bp->b_page_count) + bp->b_flags |= XBF_DONE; + return error; } @@ -387,23 +450,14 @@ _xfs_buf_map_pages( xfs_buf_t *bp, uint flags) { - ASSERT(bp->b_flags & _XBF_PAGES); + /* A single page buffer is always mappable */ if (bp->b_page_count == 1) { - /* A single page buffer is always mappable */ bp->b_addr = page_address(bp->b_pages[0]) + bp->b_offset; bp->b_flags |= XBF_MAPPED; } else if (flags & XBF_MAPPED) { - int retried = 0; - - do { - bp->b_addr = vm_map_ram(bp->b_pages, bp->b_page_count, - -1, PAGE_KERNEL); - if (bp->b_addr) - break; - vm_unmap_aliases(); - } while (retried++ <= 1); - - if (!bp->b_addr) + bp->b_addr = vm_map_ram(bp->b_pages, bp->b_page_count, + -1, PAGE_KERNEL); + if (unlikely(bp->b_addr == NULL)) return -ENOMEM; bp->b_addr += bp->b_offset; bp->b_flags |= XBF_MAPPED; @@ -514,14 +568,9 @@ _xfs_buf_find( } } - /* - * if the buffer is stale, clear all the external state associated with - * it. We need to keep flags such as how we allocated the buffer memory - * intact here. - */ if (bp->b_flags & XBF_STALE) { ASSERT((bp->b_flags & _XBF_DELWRI_Q) == 0); - bp->b_flags &= XBF_MAPPED | _XBF_KMEM | _XBF_PAGES; + bp->b_flags &= XBF_MAPPED; } trace_xfs_buf_find(bp, flags, _RET_IP_); @@ -542,7 +591,7 @@ xfs_buf_get( xfs_buf_flags_t flags) { xfs_buf_t *bp, *new_bp; - int error = 0; + int error = 0, i; new_bp = xfs_buf_allocate(flags); if (unlikely(!new_bp)) @@ -550,7 +599,7 @@ xfs_buf_get( bp = _xfs_buf_find(target, ioff, isize, flags, new_bp); if (bp == new_bp) { - error = xfs_buf_allocate_memory(bp, flags); + error = _xfs_buf_lookup_pages(bp, flags); if (error) goto no_buffer; } else { @@ -559,6 +608,9 @@ xfs_buf_get( return NULL; } + for (i = 0; i < bp->b_page_count; i++) + mark_page_accessed(bp->b_pages[i]); + if (!(bp->b_flags & XBF_MAPPED)) { error = _xfs_buf_map_pages(bp, flags); if (unlikely(error)) { @@ -659,7 +711,8 @@ xfs_buf_readahead( { struct backing_dev_info *bdi; - if (bdi_read_congested(target->bt_bdi)) + bdi = target->bt_mapping->backing_dev_info; + if (bdi_read_congested(bdi)) return; xfs_buf_read(target, ioff, isize, @@ -737,10 +790,10 @@ xfs_buf_associate_memory( size_t buflen; int page_count; - pageaddr = (unsigned long)mem & PAGE_MASK; + pageaddr = (unsigned long)mem & PAGE_CACHE_MASK; offset = (unsigned long)mem - pageaddr; - buflen = PAGE_ALIGN(len + offset); - page_count = buflen >> PAGE_SHIFT; + buflen = PAGE_CACHE_ALIGN(len + offset); + page_count = buflen >> PAGE_CACHE_SHIFT; /* Free any previous set of page pointers */ if (bp->b_pages) @@ -757,12 +810,13 @@ xfs_buf_associate_memory( for (i = 0; i < bp->b_page_count; i++) { bp->b_pages[i] = mem_to_page((void *)pageaddr); - pageaddr += PAGE_SIZE; + pageaddr += PAGE_CACHE_SIZE; } bp->b_count_desired = len; bp->b_buffer_length = buflen; bp->b_flags |= XBF_MAPPED; + bp->b_flags &= ~_XBF_PAGE_LOCKED; return 0; } @@ -869,7 +923,20 @@ xfs_buf_rele( /* - * Lock a buffer object, if it is not already locked. + * Mutual exclusion on buffers. Locking model: + * + * Buffers associated with inodes for which buffer locking + * is not enabled are not protected by semaphores, and are + * assumed to be exclusively owned by the caller. There is a + * spinlock in the buffer, used by the caller when concurrent + * access is possible. + */ + +/* + * Locks a buffer object, if it is not already locked. Note that this in + * no way locks the underlying pages, so it is only useful for + * synchronizing concurrent use of buffer objects, not for synchronizing + * independent access to the underlying pages. * * If we come across a stale, pinned, locked buffer, we know that we are * being asked to lock a buffer that has been reallocated. Because it is @@ -903,7 +970,10 @@ xfs_buf_lock_value( } /* - * Lock a buffer object. + * Locks a buffer object. + * Note that this in no way locks the underlying pages, so it is only + * useful for synchronizing concurrent use of buffer objects, not for + * synchronizing independent access to the underlying pages. * * If we come across a stale, pinned, locked buffer, we know that we * are being asked to lock a buffer that has been reallocated. Because @@ -1176,8 +1246,10 @@ _xfs_buf_ioend( xfs_buf_t *bp, int schedule) { - if (atomic_dec_and_test(&bp->b_io_remaining) == 1) + if (atomic_dec_and_test(&bp->b_io_remaining) == 1) { + bp->b_flags &= ~_XBF_PAGE_LOCKED; xfs_buf_ioend(bp, schedule); + } } STATIC void @@ -1186,12 +1258,35 @@ xfs_buf_bio_end_io( int error) { xfs_buf_t *bp = (xfs_buf_t *)bio->bi_private; + unsigned int blocksize = bp->b_target->bt_bsize; + struct bio_vec *bvec = bio->bi_io_vec + bio->bi_vcnt - 1; xfs_buf_ioerror(bp, -error); if (!error && xfs_buf_is_vmapped(bp) && (bp->b_flags & XBF_READ)) invalidate_kernel_vmap_range(bp->b_addr, xfs_buf_vmap_len(bp)); + do { + struct page *page = bvec->bv_page; + + ASSERT(!PagePrivate(page)); + if (unlikely(bp->b_error)) { + if (bp->b_flags & XBF_READ) + ClearPageUptodate(page); + } else if (blocksize >= PAGE_CACHE_SIZE) { + SetPageUptodate(page); + } else if (!PagePrivate(page) && + (bp->b_flags & _XBF_PAGE_CACHE)) { + set_page_region(page, bvec->bv_offset, bvec->bv_len); + } + + if (--bvec >= bio->bi_io_vec) + prefetchw(&bvec->bv_page->flags); + + if (bp->b_flags & _XBF_PAGE_LOCKED) + unlock_page(page); + } while (bvec >= bio->bi_io_vec); + _xfs_buf_ioend(bp, 1); bio_put(bio); } @@ -1205,6 +1300,7 @@ _xfs_buf_ioapply( int offset = bp->b_offset; int size = bp->b_count_desired; sector_t sector = bp->b_bn; + unsigned int blocksize = bp->b_target->bt_bsize; total_nr_pages = bp->b_page_count; map_i = 0; @@ -1225,6 +1321,29 @@ _xfs_buf_ioapply( (bp->b_flags & XBF_READ_AHEAD) ? READA : READ; } + /* Special code path for reading a sub page size buffer in -- + * we populate up the whole page, and hence the other metadata + * in the same page. This optimization is only valid when the + * filesystem block size is not smaller than the page size. + */ + if ((bp->b_buffer_length < PAGE_CACHE_SIZE) && + ((bp->b_flags & (XBF_READ|_XBF_PAGE_LOCKED)) == + (XBF_READ|_XBF_PAGE_LOCKED)) && + (blocksize >= PAGE_CACHE_SIZE)) { + bio = bio_alloc(GFP_NOIO, 1); + + bio->bi_bdev = bp->b_target->bt_bdev; + bio->bi_sector = sector - (offset >> BBSHIFT); + bio->bi_end_io = xfs_buf_bio_end_io; + bio->bi_private = bp; + + bio_add_page(bio, bp->b_pages[0], PAGE_CACHE_SIZE, 0); + size = 0; + + atomic_inc(&bp->b_io_remaining); + + goto submit_io; + } next_chunk: atomic_inc(&bp->b_io_remaining); @@ -1238,9 +1357,8 @@ _xfs_buf_ioapply( bio->bi_end_io = xfs_buf_bio_end_io; bio->bi_private = bp; - for (; size && nr_pages; nr_pages--, map_i++) { - int rbytes, nbytes = PAGE_SIZE - offset; + int rbytes, nbytes = PAGE_CACHE_SIZE - offset; if (nbytes > size) nbytes = size; @@ -1255,6 +1373,7 @@ _xfs_buf_ioapply( total_nr_pages--; } +submit_io: if (likely(bio->bi_size)) { if (xfs_buf_is_vmapped(bp)) { flush_kernel_vmap_range(bp->b_addr, @@ -1264,7 +1383,18 @@ _xfs_buf_ioapply( if (size) goto next_chunk; } else { + /* + * if we get here, no pages were added to the bio. However, + * we can't just error out here - if the pages are locked then + * we have to unlock them otherwise we can hang on a later + * access to the page. + */ xfs_buf_ioerror(bp, EIO); + if (bp->b_flags & _XBF_PAGE_LOCKED) { + int i; + for (i = 0; i < bp->b_page_count; i++) + unlock_page(bp->b_pages[i]); + } bio_put(bio); } } @@ -1328,8 +1458,8 @@ xfs_buf_offset( return XFS_BUF_PTR(bp) + offset; offset += bp->b_offset; - page = bp->b_pages[offset >> PAGE_SHIFT]; - return (xfs_caddr_t)page_address(page) + (offset & (PAGE_SIZE-1)); + page = bp->b_pages[offset >> PAGE_CACHE_SHIFT]; + return (xfs_caddr_t)page_address(page) + (offset & (PAGE_CACHE_SIZE-1)); } /* @@ -1351,9 +1481,9 @@ xfs_buf_iomove( page = bp->b_pages[xfs_buf_btoct(boff + bp->b_offset)]; cpoff = xfs_buf_poff(boff + bp->b_offset); csize = min_t(size_t, - PAGE_SIZE-cpoff, bp->b_count_desired-boff); + PAGE_CACHE_SIZE-cpoff, bp->b_count_desired-boff); - ASSERT(((csize + cpoff) <= PAGE_SIZE)); + ASSERT(((csize + cpoff) <= PAGE_CACHE_SIZE)); switch (mode) { case XBRW_ZERO: @@ -1466,6 +1596,7 @@ xfs_free_buftarg( xfs_flush_buftarg(btp, 1); if (mp->m_flags & XFS_MOUNT_BARRIER) xfs_blkdev_issue_flush(btp); + iput(btp->bt_mapping->host); kthread_stop(btp->bt_task); kmem_free(btp); @@ -1489,6 +1620,15 @@ xfs_setsize_buftarg_flags( return EINVAL; } + if (verbose && + (PAGE_CACHE_SIZE / BITS_PER_LONG) > sectorsize) { + printk(KERN_WARNING + "XFS: %u byte sectors in use on device %s. " + "This is suboptimal; %u or greater is ideal.\n", + sectorsize, XFS_BUFTARG_NAME(btp), + (unsigned int)PAGE_CACHE_SIZE / BITS_PER_LONG); + } + return 0; } @@ -1503,7 +1643,7 @@ xfs_setsize_buftarg_early( struct block_device *bdev) { return xfs_setsize_buftarg_flags(btp, - PAGE_SIZE, bdev_logical_block_size(bdev), 0); + PAGE_CACHE_SIZE, bdev_logical_block_size(bdev), 0); } int @@ -1515,6 +1655,40 @@ xfs_setsize_buftarg( return xfs_setsize_buftarg_flags(btp, blocksize, sectorsize, 1); } +STATIC int +xfs_mapping_buftarg( + xfs_buftarg_t *btp, + struct block_device *bdev) +{ + struct backing_dev_info *bdi; + struct inode *inode; + struct address_space *mapping; + static const struct address_space_operations mapping_aops = { + .migratepage = fail_migrate_page, + }; + + inode = new_inode(bdev->bd_inode->i_sb); + if (!inode) { + printk(KERN_WARNING + "XFS: Cannot allocate mapping inode for device %s\n", + XFS_BUFTARG_NAME(btp)); + return ENOMEM; + } + inode->i_ino = get_next_ino(); + inode->i_mode = S_IFBLK; + inode->i_bdev = bdev; + inode->i_rdev = bdev->bd_dev; + bdi = blk_get_backing_dev_info(bdev); + if (!bdi) + bdi = &default_backing_dev_info; + mapping = &inode->i_data; + mapping->a_ops = &mapping_aops; + mapping->backing_dev_info = bdi; + mapping_set_gfp_mask(mapping, GFP_NOFS); + btp->bt_mapping = mapping; + return 0; +} + STATIC int xfs_alloc_delwrite_queue( xfs_buftarg_t *btp, @@ -1543,14 +1717,12 @@ xfs_alloc_buftarg( btp->bt_mount = mp; btp->bt_dev = bdev->bd_dev; btp->bt_bdev = bdev; - btp->bt_bdi = blk_get_backing_dev_info(bdev); - if (!btp->bt_bdi) - goto error; - INIT_LIST_HEAD(&btp->bt_lru); spin_lock_init(&btp->bt_lru_lock); if (xfs_setsize_buftarg_early(btp, bdev)) goto error; + if (xfs_mapping_buftarg(btp, bdev)) + goto error; if (xfs_alloc_delwrite_queue(btp, fsname)) goto error; btp->bt_shrinker.shrink = xfs_buftarg_shrink; diff --git a/trunk/fs/xfs/linux-2.6/xfs_buf.h b/trunk/fs/xfs/linux-2.6/xfs_buf.h index a9a1c4512645..cbe65950e524 100644 --- a/trunk/fs/xfs/linux-2.6/xfs_buf.h +++ b/trunk/fs/xfs/linux-2.6/xfs_buf.h @@ -61,11 +61,30 @@ typedef enum { #define XBF_DONT_BLOCK (1 << 16)/* do not block in current thread */ /* flags used only internally */ +#define _XBF_PAGE_CACHE (1 << 17)/* backed by pagecache */ #define _XBF_PAGES (1 << 18)/* backed by refcounted pages */ #define _XBF_RUN_QUEUES (1 << 19)/* run block device task queue */ -#define _XBF_KMEM (1 << 20)/* backed by heap memory */ #define _XBF_DELWRI_Q (1 << 21)/* buffer on delwri queue */ +/* + * Special flag for supporting metadata blocks smaller than a FSB. + * + * In this case we can have multiple xfs_buf_t on a single page and + * need to lock out concurrent xfs_buf_t readers as they only + * serialise access to the buffer. + * + * If the FSB size >= PAGE_CACHE_SIZE case, we have no serialisation + * between reads of the page. Hence we can have one thread read the + * page and modify it, but then race with another thread that thinks + * the page is not up-to-date and hence reads it again. + * + * The result is that the first modifcation to the page is lost. + * This sort of AGF/AGI reading race can happen when unlinking inodes + * that require truncation and results in the AGI unlinked list + * modifications being lost. + */ +#define _XBF_PAGE_LOCKED (1 << 22) + typedef unsigned int xfs_buf_flags_t; #define XFS_BUF_FLAGS \ @@ -81,10 +100,12 @@ typedef unsigned int xfs_buf_flags_t; { XBF_LOCK, "LOCK" }, /* should never be set */\ { XBF_TRYLOCK, "TRYLOCK" }, /* ditto */\ { XBF_DONT_BLOCK, "DONT_BLOCK" }, /* ditto */\ + { _XBF_PAGE_CACHE, "PAGE_CACHE" }, \ { _XBF_PAGES, "PAGES" }, \ { _XBF_RUN_QUEUES, "RUN_QUEUES" }, \ - { _XBF_KMEM, "KMEM" }, \ - { _XBF_DELWRI_Q, "DELWRI_Q" } + { _XBF_DELWRI_Q, "DELWRI_Q" }, \ + { _XBF_PAGE_LOCKED, "PAGE_LOCKED" } + typedef enum { XBT_FORCE_SLEEP = 0, @@ -99,7 +120,7 @@ typedef struct xfs_bufhash { typedef struct xfs_buftarg { dev_t bt_dev; struct block_device *bt_bdev; - struct backing_dev_info *bt_bdi; + struct address_space *bt_mapping; struct xfs_mount *bt_mount; unsigned int bt_bsize; unsigned int bt_sshift; @@ -118,6 +139,17 @@ typedef struct xfs_buftarg { unsigned int bt_lru_nr; } xfs_buftarg_t; +/* + * xfs_buf_t: Buffer structure for pagecache-based buffers + * + * This buffer structure is used by the pagecache buffer management routines + * to refer to an assembly of pages forming a logical buffer. + * + * The buffer structure is used on a temporary basis only, and discarded when + * released. The real data storage is recorded in the pagecache. Buffers are + * hashed to the block device on which the file system resides. + */ + struct xfs_buf; typedef void (*xfs_buf_iodone_t)(struct xfs_buf *); diff --git a/trunk/fs/xfs/linux-2.6/xfs_file.c b/trunk/fs/xfs/linux-2.6/xfs_file.c index 52aadfbed132..a55c1b46b219 100644 --- a/trunk/fs/xfs/linux-2.6/xfs_file.c +++ b/trunk/fs/xfs/linux-2.6/xfs_file.c @@ -896,7 +896,6 @@ xfs_file_fallocate( xfs_flock64_t bf; xfs_inode_t *ip = XFS_I(inode); int cmd = XFS_IOC_RESVSP; - int attr_flags = XFS_ATTR_NOLOCK; if (mode & ~(FALLOC_FL_KEEP_SIZE | FALLOC_FL_PUNCH_HOLE)) return -EOPNOTSUPP; @@ -919,10 +918,7 @@ xfs_file_fallocate( goto out_unlock; } - if (file->f_flags & O_DSYNC) - attr_flags |= XFS_ATTR_SYNC; - - error = -xfs_change_file_space(ip, cmd, &bf, 0, attr_flags); + error = -xfs_change_file_space(ip, cmd, &bf, 0, XFS_ATTR_NOLOCK); if (error) goto out_unlock; diff --git a/trunk/fs/xfs/linux-2.6/xfs_ioctl.c b/trunk/fs/xfs/linux-2.6/xfs_ioctl.c index acca2c5ca3fa..0ca0e3c024d7 100644 --- a/trunk/fs/xfs/linux-2.6/xfs_ioctl.c +++ b/trunk/fs/xfs/linux-2.6/xfs_ioctl.c @@ -624,10 +624,6 @@ xfs_ioc_space( if (filp->f_flags & (O_NDELAY|O_NONBLOCK)) attr_flags |= XFS_ATTR_NONBLOCK; - - if (filp->f_flags & O_DSYNC) - attr_flags |= XFS_ATTR_SYNC; - if (ioflags & IO_INVIS) attr_flags |= XFS_ATTR_DMI; diff --git a/trunk/fs/xfs/linux-2.6/xfs_super.c b/trunk/fs/xfs/linux-2.6/xfs_super.c index 1ba5c451da36..818c4cf2de86 100644 --- a/trunk/fs/xfs/linux-2.6/xfs_super.c +++ b/trunk/fs/xfs/linux-2.6/xfs_super.c @@ -1078,7 +1078,7 @@ xfs_fs_write_inode( error = 0; goto out_unlock; } - error = xfs_iflush(ip, SYNC_TRYLOCK); + error = xfs_iflush(ip, 0); } out_unlock: @@ -1539,14 +1539,10 @@ xfs_fs_fill_super( if (error) goto out_free_sb; - /* - * we must configure the block size in the superblock before we run the - * full mount process as the mount process can lookup and cache inodes. - * For the same reason we must also initialise the syncd and register - * the inode cache shrinker so that inodes can be reclaimed during - * operations like a quotacheck that iterate all inodes in the - * filesystem. - */ + error = xfs_mountfs(mp); + if (error) + goto out_filestream_unmount; + sb->s_magic = XFS_SB_MAGIC; sb->s_blocksize = mp->m_sb.sb_blocksize; sb->s_blocksize_bits = ffs(sb->s_blocksize) - 1; @@ -1554,16 +1550,6 @@ xfs_fs_fill_super( sb->s_time_gran = 1; set_posix_acl_flag(sb); - error = xfs_syncd_init(mp); - if (error) - goto out_filestream_unmount; - - xfs_inode_shrinker_register(mp); - - error = xfs_mountfs(mp); - if (error) - goto out_syncd_stop; - root = igrab(VFS_I(mp->m_rootip)); if (!root) { error = ENOENT; @@ -1579,11 +1565,14 @@ xfs_fs_fill_super( goto fail_vnrele; } + error = xfs_syncd_init(mp); + if (error) + goto fail_vnrele; + + xfs_inode_shrinker_register(mp); + return 0; - out_syncd_stop: - xfs_inode_shrinker_unregister(mp); - xfs_syncd_stop(mp); out_filestream_unmount: xfs_filestream_unmount(mp); out_free_sb: @@ -1607,9 +1596,6 @@ xfs_fs_fill_super( } fail_unmount: - xfs_inode_shrinker_unregister(mp); - xfs_syncd_stop(mp); - /* * Blow away any referenced inode in the filestreams cache. * This can and will cause log traffic as inodes go inactive diff --git a/trunk/fs/xfs/linux-2.6/xfs_sync.c b/trunk/fs/xfs/linux-2.6/xfs_sync.c index 594cd822d84d..6c10f1d2e3d3 100644 --- a/trunk/fs/xfs/linux-2.6/xfs_sync.c +++ b/trunk/fs/xfs/linux-2.6/xfs_sync.c @@ -761,10 +761,8 @@ xfs_reclaim_inode( struct xfs_perag *pag, int sync_mode) { - int error; + int error = 0; -restart: - error = 0; xfs_ilock(ip, XFS_ILOCK_EXCL); if (!xfs_iflock_nowait(ip)) { if (!(sync_mode & SYNC_WAIT)) @@ -790,31 +788,9 @@ xfs_reclaim_inode( if (xfs_inode_clean(ip)) goto reclaim; - /* - * Now we have an inode that needs flushing. - * - * We do a nonblocking flush here even if we are doing a SYNC_WAIT - * reclaim as we can deadlock with inode cluster removal. - * xfs_ifree_cluster() can lock the inode buffer before it locks the - * ip->i_lock, and we are doing the exact opposite here. As a result, - * doing a blocking xfs_itobp() to get the cluster buffer will result - * in an ABBA deadlock with xfs_ifree_cluster(). - * - * As xfs_ifree_cluser() must gather all inodes that are active in the - * cache to mark them stale, if we hit this case we don't actually want - * to do IO here - we want the inode marked stale so we can simply - * reclaim it. Hence if we get an EAGAIN error on a SYNC_WAIT flush, - * just unlock the inode, back off and try again. Hopefully the next - * pass through will see the stale flag set on the inode. - */ - error = xfs_iflush(ip, SYNC_TRYLOCK | sync_mode); + /* Now we have an inode that needs flushing */ + error = xfs_iflush(ip, sync_mode); if (sync_mode & SYNC_WAIT) { - if (error == EAGAIN) { - xfs_iunlock(ip, XFS_ILOCK_EXCL); - /* backoff longer than in xfs_ifree_cluster */ - delay(2); - goto restart; - } xfs_iflock(ip); goto reclaim; } diff --git a/trunk/fs/xfs/xfs_inode.c b/trunk/fs/xfs/xfs_inode.c index 742c8330994a..da871f532236 100644 --- a/trunk/fs/xfs/xfs_inode.c +++ b/trunk/fs/xfs/xfs_inode.c @@ -2835,7 +2835,7 @@ xfs_iflush( * Get the buffer containing the on-disk inode. */ error = xfs_itobp(mp, NULL, ip, &dip, &bp, - (flags & SYNC_TRYLOCK) ? XBF_TRYLOCK : XBF_LOCK); + (flags & SYNC_WAIT) ? XBF_LOCK : XBF_TRYLOCK); if (error || !bp) { xfs_ifunlock(ip); return error; diff --git a/trunk/fs/xfs/xfs_inode_item.c b/trunk/fs/xfs/xfs_inode_item.c index 46cc40131d4a..fd4f398bd6f1 100644 --- a/trunk/fs/xfs/xfs_inode_item.c +++ b/trunk/fs/xfs/xfs_inode_item.c @@ -760,11 +760,11 @@ xfs_inode_item_push( * Push the inode to it's backing buffer. This will not remove the * inode from the AIL - a further push will be required to trigger a * buffer push. However, this allows all the dirty inodes to be pushed - * to the buffer before it is pushed to disk. The buffer IO completion - * will pull the inode from the AIL, mark it clean and unlock the flush + * to the buffer before it is pushed to disk. THe buffer IO completion + * will pull th einode from the AIL, mark it clean and unlock the flush * lock. */ - (void) xfs_iflush(ip, SYNC_TRYLOCK); + (void) xfs_iflush(ip, 0); xfs_iunlock(ip, XFS_ILOCK_SHARED); } diff --git a/trunk/fs/xfs/xfs_trans_buf.c b/trunk/fs/xfs/xfs_trans_buf.c index 03b3b7f85a3b..3bea66132334 100644 --- a/trunk/fs/xfs/xfs_trans_buf.c +++ b/trunk/fs/xfs/xfs_trans_buf.c @@ -383,8 +383,7 @@ xfs_trans_read_buf( bp = xfs_buf_read(target, blkno, len, flags | XBF_DONT_BLOCK); if (bp == NULL) { *bpp = NULL; - return (flags & XBF_TRYLOCK) ? - 0 : XFS_ERROR(ENOMEM); + return 0; } if (XFS_BUF_GETERROR(bp) != 0) { XFS_BUF_SUPER_STALE(bp); diff --git a/trunk/fs/xfs/xfs_vnodeops.c b/trunk/fs/xfs/xfs_vnodeops.c index c48b4217ec47..37d8146ee15b 100644 --- a/trunk/fs/xfs/xfs_vnodeops.c +++ b/trunk/fs/xfs/xfs_vnodeops.c @@ -2831,8 +2831,7 @@ xfs_change_file_space( ip->i_d.di_flags &= ~XFS_DIFLAG_PREALLOC; xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); - if (attr_flags & XFS_ATTR_SYNC) - xfs_trans_set_sync(tp); + xfs_trans_set_sync(tp); error = xfs_trans_commit(tp, 0); diff --git a/trunk/fs/xfs/xfs_vnodeops.h b/trunk/fs/xfs/xfs_vnodeops.h index 3bcd23353d6c..f6702927eee4 100644 --- a/trunk/fs/xfs/xfs_vnodeops.h +++ b/trunk/fs/xfs/xfs_vnodeops.h @@ -18,7 +18,6 @@ int xfs_setattr(struct xfs_inode *ip, struct iattr *vap, int flags); #define XFS_ATTR_NONBLOCK 0x02 /* return EAGAIN if operation would block */ #define XFS_ATTR_NOLOCK 0x04 /* Don't grab any conflicting locks */ #define XFS_ATTR_NOACL 0x08 /* Don't call xfs_acl_chmod */ -#define XFS_ATTR_SYNC 0x10 /* synchronous operation required */ int xfs_readlink(struct xfs_inode *ip, char *link); int xfs_release(struct xfs_inode *ip); diff --git a/trunk/include/linux/bch.h b/trunk/include/linux/bch.h deleted file mode 100644 index 295b4ef153bb..000000000000 --- a/trunk/include/linux/bch.h +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Generic binary BCH encoding/decoding library - * - * 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. - * - * 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., 51 - * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Copyright © 2011 Parrot S.A. - * - * Author: Ivan Djelic - * - * Description: - * - * This library provides runtime configurable encoding/decoding of binary - * Bose-Chaudhuri-Hocquenghem (BCH) codes. -*/ -#ifndef _BCH_H -#define _BCH_H - -#include - -/** - * struct bch_control - BCH control structure - * @m: Galois field order - * @n: maximum codeword size in bits (= 2^m-1) - * @t: error correction capability in bits - * @ecc_bits: ecc exact size in bits, i.e. generator polynomial degree (<=m*t) - * @ecc_bytes: ecc max size (m*t bits) in bytes - * @a_pow_tab: Galois field GF(2^m) exponentiation lookup table - * @a_log_tab: Galois field GF(2^m) log lookup table - * @mod8_tab: remainder generator polynomial lookup tables - * @ecc_buf: ecc parity words buffer - * @ecc_buf2: ecc parity words buffer - * @xi_tab: GF(2^m) base for solving degree 2 polynomial roots - * @syn: syndrome buffer - * @cache: log-based polynomial representation buffer - * @elp: error locator polynomial - * @poly_2t: temporary polynomials of degree 2t - */ -struct bch_control { - unsigned int m; - unsigned int n; - unsigned int t; - unsigned int ecc_bits; - unsigned int ecc_bytes; -/* private: */ - uint16_t *a_pow_tab; - uint16_t *a_log_tab; - uint32_t *mod8_tab; - uint32_t *ecc_buf; - uint32_t *ecc_buf2; - unsigned int *xi_tab; - unsigned int *syn; - int *cache; - struct gf_poly *elp; - struct gf_poly *poly_2t[4]; -}; - -struct bch_control *init_bch(int m, int t, unsigned int prim_poly); - -void free_bch(struct bch_control *bch); - -void encode_bch(struct bch_control *bch, const uint8_t *data, - unsigned int len, uint8_t *ecc); - -int decode_bch(struct bch_control *bch, const uint8_t *data, unsigned int len, - const uint8_t *recv_ecc, const uint8_t *calc_ecc, - const unsigned int *syn, unsigned int *errloc); - -#endif /* _BCH_H */ diff --git a/trunk/include/linux/can/core.h b/trunk/include/linux/can/core.h index 6f70a6d3a16e..6c507bea275f 100644 --- a/trunk/include/linux/can/core.h +++ b/trunk/include/linux/can/core.h @@ -36,10 +36,10 @@ * @prot: pointer to struct proto structure. */ struct can_proto { - int type; - int protocol; - const struct proto_ops *ops; - struct proto *prot; + int type; + int protocol; + struct proto_ops *ops; + struct proto *prot; }; /* function prototypes for the CAN networklayer core (af_can.c) */ @@ -58,6 +58,5 @@ extern void can_rx_unregister(struct net_device *dev, canid_t can_id, void *data); extern int can_send(struct sk_buff *skb, int loop); -extern int can_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg); #endif /* CAN_CORE_H */ diff --git a/trunk/include/linux/drbd.h b/trunk/include/linux/drbd.h index d18d673ebc78..ef44c7a0638c 100644 --- a/trunk/include/linux/drbd.h +++ b/trunk/include/linux/drbd.h @@ -53,10 +53,10 @@ extern const char *drbd_buildtag(void); -#define REL_VERSION "8.3.10" +#define REL_VERSION "8.3.9" #define API_VERSION 88 #define PRO_VERSION_MIN 86 -#define PRO_VERSION_MAX 96 +#define PRO_VERSION_MAX 95 enum drbd_io_error_p { @@ -96,14 +96,8 @@ enum drbd_on_no_data { OND_SUSPEND_IO }; -enum drbd_on_congestion { - OC_BLOCK, - OC_PULL_AHEAD, - OC_DISCONNECT, -}; - /* KEEP the order, do not delete or insert. Only append. */ -enum drbd_ret_code { +enum drbd_ret_codes { ERR_CODE_BASE = 100, NO_ERROR = 101, ERR_LOCAL_ADDR = 102, @@ -152,9 +146,6 @@ enum drbd_ret_code { ERR_PERM = 152, ERR_NEED_APV_93 = 153, ERR_STONITH_AND_PROT_A = 154, - ERR_CONG_NOT_PROTO_A = 155, - ERR_PIC_AFTER_DEP = 156, - ERR_PIC_PEER_DEP = 157, /* insert new ones above this line */ AFTER_LAST_ERR_CODE @@ -208,10 +199,6 @@ enum drbd_conns { C_VERIFY_T, C_PAUSED_SYNC_S, C_PAUSED_SYNC_T, - - C_AHEAD, - C_BEHIND, - C_MASK = 31 }; @@ -272,7 +259,7 @@ union drbd_state { unsigned int i; }; -enum drbd_state_rv { +enum drbd_state_ret_codes { SS_CW_NO_NEED = 4, SS_CW_SUCCESS = 3, SS_NOTHING_TO_DO = 2, @@ -303,7 +290,7 @@ enum drbd_state_rv { extern const char *drbd_conn_str(enum drbd_conns); extern const char *drbd_role_str(enum drbd_role); extern const char *drbd_disk_str(enum drbd_disk_state); -extern const char *drbd_set_st_err_str(enum drbd_state_rv); +extern const char *drbd_set_st_err_str(enum drbd_state_ret_codes); #define SHARED_SECRET_MAX 64 diff --git a/trunk/include/linux/drbd_limits.h b/trunk/include/linux/drbd_limits.h index bb264a5732de..4ac33f34b77e 100644 --- a/trunk/include/linux/drbd_limits.h +++ b/trunk/include/linux/drbd_limits.h @@ -16,8 +16,7 @@ #define DEBUG_RANGE_CHECK 0 #define DRBD_MINOR_COUNT_MIN 1 -#define DRBD_MINOR_COUNT_MAX 256 -#define DRBD_MINOR_COUNT_DEF 32 +#define DRBD_MINOR_COUNT_MAX 255 #define DRBD_DIALOG_REFRESH_MIN 0 #define DRBD_DIALOG_REFRESH_MAX 600 @@ -130,7 +129,6 @@ #define DRBD_AFTER_SB_2P_DEF ASB_DISCONNECT #define DRBD_RR_CONFLICT_DEF ASB_DISCONNECT #define DRBD_ON_NO_DATA_DEF OND_IO_ERROR -#define DRBD_ON_CONGESTION_DEF OC_BLOCK #define DRBD_MAX_BIO_BVECS_MIN 0 #define DRBD_MAX_BIO_BVECS_MAX 128 @@ -156,13 +154,5 @@ #define DRBD_C_MIN_RATE_MAX (4 << 20) #define DRBD_C_MIN_RATE_DEF 4096 -#define DRBD_CONG_FILL_MIN 0 -#define DRBD_CONG_FILL_MAX (10<<21) /* 10GByte in sectors */ -#define DRBD_CONG_FILL_DEF 0 - -#define DRBD_CONG_EXTENTS_MIN DRBD_AL_EXTENTS_MIN -#define DRBD_CONG_EXTENTS_MAX DRBD_AL_EXTENTS_MAX -#define DRBD_CONG_EXTENTS_DEF DRBD_AL_EXTENTS_DEF - #undef RANGE #endif diff --git a/trunk/include/linux/drbd_nl.h b/trunk/include/linux/drbd_nl.h index ab6159e4fcf0..ade91107c9a5 100644 --- a/trunk/include/linux/drbd_nl.h +++ b/trunk/include/linux/drbd_nl.h @@ -56,9 +56,6 @@ NL_PACKET(net_conf, 5, NL_INTEGER( 39, T_MAY_IGNORE, rr_conflict) NL_INTEGER( 40, T_MAY_IGNORE, ping_timeo) NL_INTEGER( 67, T_MAY_IGNORE, rcvbuf_size) - NL_INTEGER( 81, T_MAY_IGNORE, on_congestion) - NL_INTEGER( 82, T_MAY_IGNORE, cong_fill) - NL_INTEGER( 83, T_MAY_IGNORE, cong_extents) /* 59 addr_family was available in GIT, never released */ NL_BIT( 60, T_MANDATORY, mind_af) NL_BIT( 27, T_MAY_IGNORE, want_lose) @@ -69,9 +66,7 @@ NL_PACKET(net_conf, 5, NL_BIT( 70, T_MANDATORY, dry_run) ) -NL_PACKET(disconnect, 6, - NL_BIT( 84, T_MAY_IGNORE, force) -) +NL_PACKET(disconnect, 6, ) NL_PACKET(resize, 7, NL_INT64( 29, T_MAY_IGNORE, resize_size) @@ -148,13 +143,9 @@ NL_PACKET(new_c_uuid, 26, NL_BIT( 63, T_MANDATORY, clear_bm) ) -#ifdef NL_RESPONSE -NL_RESPONSE(return_code_only, 27) -#endif - #undef NL_PACKET #undef NL_INTEGER #undef NL_INT64 #undef NL_BIT #undef NL_STRING -#undef NL_RESPONSE + diff --git a/trunk/include/linux/drbd_tag_magic.h b/trunk/include/linux/drbd_tag_magic.h index f14a165e82dc..fcdff8410e99 100644 --- a/trunk/include/linux/drbd_tag_magic.h +++ b/trunk/include/linux/drbd_tag_magic.h @@ -7,7 +7,6 @@ /* declare packet_type enums */ enum packet_types { #define NL_PACKET(name, number, fields) P_ ## name = number, -#define NL_RESPONSE(name, number) P_ ## name = number, #define NL_INTEGER(pn, pr, member) #define NL_INT64(pn, pr, member) #define NL_BIT(pn, pr, member) diff --git a/trunk/include/linux/ethtool.h b/trunk/include/linux/ethtool.h index c8fcbdd2b0e7..ae757bcf1280 100644 --- a/trunk/include/linux/ethtool.h +++ b/trunk/include/linux/ethtool.h @@ -680,7 +680,6 @@ int ethtool_op_set_ufo(struct net_device *dev, u32 data); u32 ethtool_op_get_flags(struct net_device *dev); int ethtool_op_set_flags(struct net_device *dev, u32 data, u32 supported); void ethtool_ntuple_flush(struct net_device *dev); -bool ethtool_invalid_flags(struct net_device *dev, u32 data, u32 supported); /** * ðtool_ops - Alter and report network device settings diff --git a/trunk/include/linux/fs.h b/trunk/include/linux/fs.h index 52f283c1edb2..b677bd77f2d6 100644 --- a/trunk/include/linux/fs.h +++ b/trunk/include/linux/fs.h @@ -357,8 +357,6 @@ struct inodes_stat_t { #define FS_TOPDIR_FL 0x00020000 /* Top of directory hierarchies*/ #define FS_EXTENT_FL 0x00080000 /* Extents */ #define FS_DIRECTIO_FL 0x00100000 /* Use direct i/o */ -#define FS_NOCOW_FL 0x00800000 /* Do not cow file */ -#define FS_COW_FL 0x02000000 /* Cow file */ #define FS_RESERVED_FL 0x80000000 /* reserved for ext2 lib */ #define FS_FL_USER_VISIBLE 0x0003DFFF /* User visible flags */ diff --git a/trunk/include/linux/input.h b/trunk/include/linux/input.h index f3a7794a18c4..056ae8a5bd9b 100644 --- a/trunk/include/linux/input.h +++ b/trunk/include/linux/input.h @@ -664,13 +664,6 @@ struct input_keymap_entry { #define KEY_TOUCHPAD_ON 0x213 #define KEY_TOUCHPAD_OFF 0x214 -#define KEY_CAMERA_ZOOMIN 0x215 -#define KEY_CAMERA_ZOOMOUT 0x216 -#define KEY_CAMERA_UP 0x217 -#define KEY_CAMERA_DOWN 0x218 -#define KEY_CAMERA_LEFT 0x219 -#define KEY_CAMERA_RIGHT 0x21a - #define BTN_TRIGGER_HAPPY 0x2c0 #define BTN_TRIGGER_HAPPY1 0x2c0 #define BTN_TRIGGER_HAPPY2 0x2c1 diff --git a/trunk/include/linux/irq.h b/trunk/include/linux/irq.h index 2a375a72ce3c..5d876c9b3a3d 100644 --- a/trunk/include/linux/irq.h +++ b/trunk/include/linux/irq.h @@ -92,6 +92,18 @@ enum { IRQ_NO_BALANCING = (1 << 13), IRQ_MOVE_PCNTXT = (1 << 14), IRQ_NESTED_THREAD = (1 << 15), + +#ifndef CONFIG_GENERIC_HARDIRQS_NO_COMPAT + IRQ_INPROGRESS = (1 << 16), + IRQ_REPLAY = (1 << 17), + IRQ_WAITING = (1 << 18), + IRQ_DISABLED = (1 << 19), + IRQ_PENDING = (1 << 20), + IRQ_MASKED = (1 << 21), + IRQ_MOVE_PENDING = (1 << 22), + IRQ_AFFINITY_SET = (1 << 23), + IRQ_WAKEUP = (1 << 24), +#endif }; #define IRQF_MODIFY_MASK \ @@ -123,7 +135,7 @@ struct msi_desc; * struct irq_data - per irq and irq chip data passed down to chip functions * @irq: interrupt number * @node: node index useful for balancing - * @state_use_accessors: status information for irq chip functions. + * @state_use_accessor: status information for irq chip functions. * Use accessor functions to deal with it * @chip: low level interrupt hardware access * @handler_data: per-IRQ data for the irq_chip methods @@ -162,9 +174,6 @@ struct irq_data { * from suspend * IRDQ_MOVE_PCNTXT - Interrupt can be moved in process * context - * IRQD_IRQ_DISABLED - Disabled state of the interrupt - * IRQD_IRQ_MASKED - Masked state of the interrupt - * IRQD_IRQ_INPROGRESS - In progress state of the interrupt */ enum { IRQD_TRIGGER_MASK = 0xf, @@ -175,9 +184,6 @@ enum { IRQD_LEVEL = (1 << 13), IRQD_WAKEUP_STATE = (1 << 14), IRQD_MOVE_PCNTXT = (1 << 15), - IRQD_IRQ_DISABLED = (1 << 16), - IRQD_IRQ_MASKED = (1 << 17), - IRQD_IRQ_INPROGRESS = (1 << 18), }; static inline bool irqd_is_setaffinity_pending(struct irq_data *d) @@ -200,11 +206,6 @@ static inline bool irqd_affinity_was_set(struct irq_data *d) return d->state_use_accessors & IRQD_AFFINITY_SET; } -static inline void irqd_mark_affinity_was_set(struct irq_data *d) -{ - d->state_use_accessors |= IRQD_AFFINITY_SET; -} - static inline u32 irqd_get_trigger_type(struct irq_data *d) { return d->state_use_accessors & IRQD_TRIGGER_MASK; @@ -234,36 +235,6 @@ static inline bool irqd_can_move_in_process_context(struct irq_data *d) return d->state_use_accessors & IRQD_MOVE_PCNTXT; } -static inline bool irqd_irq_disabled(struct irq_data *d) -{ - return d->state_use_accessors & IRQD_IRQ_DISABLED; -} - -static inline bool irqd_irq_masked(struct irq_data *d) -{ - return d->state_use_accessors & IRQD_IRQ_MASKED; -} - -static inline bool irqd_irq_inprogress(struct irq_data *d) -{ - return d->state_use_accessors & IRQD_IRQ_INPROGRESS; -} - -/* - * Functions for chained handlers which can be enabled/disabled by the - * standard disable_irq/enable_irq calls. Must be called with - * irq_desc->lock held. - */ -static inline void irqd_set_chained_irq_inprogress(struct irq_data *d) -{ - d->state_use_accessors |= IRQD_IRQ_INPROGRESS; -} - -static inline void irqd_clr_chained_irq_inprogress(struct irq_data *d) -{ - d->state_use_accessors &= ~IRQD_IRQ_INPROGRESS; -} - /** * struct irq_chip - hardware interrupt chip descriptor * @@ -300,8 +271,6 @@ static inline void irqd_clr_chained_irq_inprogress(struct irq_data *d) * @irq_set_wake: enable/disable power-management wake-on of an IRQ * @irq_bus_lock: function to lock access to slow bus (i2c) chips * @irq_bus_sync_unlock:function to sync and unlock slow bus (i2c) chips - * @irq_cpu_online: configure an interrupt source for a secondary CPU - * @irq_cpu_offline: un-configure an interrupt source for a secondary CPU * @irq_print_chip: optional to print special chip info in show_interrupts * @flags: chip specific flags * @@ -309,6 +278,28 @@ static inline void irqd_clr_chained_irq_inprogress(struct irq_data *d) */ struct irq_chip { const char *name; +#ifndef CONFIG_GENERIC_HARDIRQS_NO_DEPRECATED + unsigned int (*startup)(unsigned int irq); + void (*shutdown)(unsigned int irq); + void (*enable)(unsigned int irq); + void (*disable)(unsigned int irq); + + void (*ack)(unsigned int irq); + void (*mask)(unsigned int irq); + void (*mask_ack)(unsigned int irq); + void (*unmask)(unsigned int irq); + void (*eoi)(unsigned int irq); + + void (*end)(unsigned int irq); + int (*set_affinity)(unsigned int irq, + const struct cpumask *dest); + int (*retrigger)(unsigned int irq); + int (*set_type)(unsigned int irq, unsigned int flow_type); + int (*set_wake)(unsigned int irq, unsigned int on); + + void (*bus_lock)(unsigned int irq); + void (*bus_sync_unlock)(unsigned int irq); +#endif unsigned int (*irq_startup)(struct irq_data *data); void (*irq_shutdown)(struct irq_data *data); void (*irq_enable)(struct irq_data *data); @@ -328,9 +319,6 @@ struct irq_chip { void (*irq_bus_lock)(struct irq_data *data); void (*irq_bus_sync_unlock)(struct irq_data *data); - void (*irq_cpu_online)(struct irq_data *data); - void (*irq_cpu_offline)(struct irq_data *data); - void (*irq_print_chip)(struct irq_data *data, struct seq_file *p); unsigned long flags; @@ -347,14 +335,11 @@ struct irq_chip { * IRQCHIP_SET_TYPE_MASKED: Mask before calling chip.irq_set_type() * IRQCHIP_EOI_IF_HANDLED: Only issue irq_eoi() when irq was handled * IRQCHIP_MASK_ON_SUSPEND: Mask non wake irqs in the suspend path - * IRQCHIP_ONOFFLINE_ENABLED: Only call irq_on/off_line callbacks - * when irq enabled */ enum { IRQCHIP_SET_TYPE_MASKED = (1 << 0), IRQCHIP_EOI_IF_HANDLED = (1 << 1), IRQCHIP_MASK_ON_SUSPEND = (1 << 2), - IRQCHIP_ONOFFLINE_ENABLED = (1 << 3), }; /* This include will go away once we isolated irq_desc usage to core code */ @@ -379,22 +364,25 @@ struct irqaction; extern int setup_irq(unsigned int irq, struct irqaction *new); extern void remove_irq(unsigned int irq, struct irqaction *act); -extern void irq_cpu_online(void); -extern void irq_cpu_offline(void); -extern int __irq_set_affinity_locked(struct irq_data *data, const struct cpumask *cpumask); - #ifdef CONFIG_GENERIC_HARDIRQS #if defined(CONFIG_SMP) && defined(CONFIG_GENERIC_PENDING_IRQ) +void move_native_irq(int irq); +void move_masked_irq(int irq); void irq_move_irq(struct irq_data *data); void irq_move_masked_irq(struct irq_data *data); #else +static inline void move_native_irq(int irq) { } +static inline void move_masked_irq(int irq) { } static inline void irq_move_irq(struct irq_data *data) { } static inline void irq_move_masked_irq(struct irq_data *data) { } #endif extern int no_irq_affinity; +/* Handle irq action chains: */ +extern irqreturn_t handle_IRQ_event(unsigned int irq, struct irqaction *action); + /* * Built-in IRQ handlers for various IRQ types, * callable via desc->handle_irq() @@ -402,7 +390,6 @@ extern int no_irq_affinity; extern void handle_level_irq(unsigned int irq, struct irq_desc *desc); extern void handle_fasteoi_irq(unsigned int irq, struct irq_desc *desc); extern void handle_edge_irq(unsigned int irq, struct irq_desc *desc); -extern void handle_edge_eoi_irq(unsigned int irq, struct irq_desc *desc); extern void handle_simple_irq(unsigned int irq, struct irq_desc *desc); extern void handle_percpu_irq(unsigned int irq, struct irq_desc *desc); extern void handle_bad_irq(unsigned int irq, struct irq_desc *desc); @@ -551,6 +538,89 @@ static inline struct msi_desc *irq_data_get_msi(struct irq_data *d) return d->msi_desc; } +#ifndef CONFIG_GENERIC_HARDIRQS_NO_COMPAT +/* Please do not use: Use the replacement functions instead */ +static inline int set_irq_chip(unsigned int irq, struct irq_chip *chip) +{ + return irq_set_chip(irq, chip); +} +static inline int set_irq_data(unsigned int irq, void *data) +{ + return irq_set_handler_data(irq, data); +} +static inline int set_irq_chip_data(unsigned int irq, void *data) +{ + return irq_set_chip_data(irq, data); +} +static inline int set_irq_type(unsigned int irq, unsigned int type) +{ + return irq_set_irq_type(irq, type); +} +static inline int set_irq_msi(unsigned int irq, struct msi_desc *entry) +{ + return irq_set_msi_desc(irq, entry); +} +static inline struct irq_chip *get_irq_chip(unsigned int irq) +{ + return irq_get_chip(irq); +} +static inline void *get_irq_chip_data(unsigned int irq) +{ + return irq_get_chip_data(irq); +} +static inline void *get_irq_data(unsigned int irq) +{ + return irq_get_handler_data(irq); +} +static inline void *irq_data_get_irq_data(struct irq_data *d) +{ + return irq_data_get_irq_handler_data(d); +} +static inline struct msi_desc *get_irq_msi(unsigned int irq) +{ + return irq_get_msi_desc(irq); +} +static inline void set_irq_noprobe(unsigned int irq) +{ + irq_set_noprobe(irq); +} +static inline void set_irq_probe(unsigned int irq) +{ + irq_set_probe(irq); +} +static inline void set_irq_nested_thread(unsigned int irq, int nest) +{ + irq_set_nested_thread(irq, nest); +} +static inline void +set_irq_chip_and_handler_name(unsigned int irq, struct irq_chip *chip, + irq_flow_handler_t handle, const char *name) +{ + irq_set_chip_and_handler_name(irq, chip, handle, name); +} +static inline void +set_irq_chip_and_handler(unsigned int irq, struct irq_chip *chip, + irq_flow_handler_t handle) +{ + irq_set_chip_and_handler(irq, chip, handle); +} +static inline void +__set_irq_handler(unsigned int irq, irq_flow_handler_t handle, int is_chained, + const char *name) +{ + __irq_set_handler(irq, handle, is_chained, name); +} +static inline void set_irq_handler(unsigned int irq, irq_flow_handler_t handle) +{ + irq_set_handler(irq, handle); +} +static inline void +set_irq_chained_handler(unsigned int irq, irq_flow_handler_t handle) +{ + irq_set_chained_handler(irq, handle); +} +#endif + int irq_alloc_descs(int irq, unsigned int from, unsigned int cnt, int node); void irq_free_descs(unsigned int irq, unsigned int cnt); int irq_reserve_irqs(unsigned int from, unsigned int cnt); diff --git a/trunk/include/linux/irqdesc.h b/trunk/include/linux/irqdesc.h index a082905b5ebe..15e6c3905f41 100644 --- a/trunk/include/linux/irqdesc.h +++ b/trunk/include/linux/irqdesc.h @@ -35,7 +35,32 @@ struct timer_rand_state; * @name: flow handler name for /proc/interrupts output */ struct irq_desc { + +#ifdef CONFIG_GENERIC_HARDIRQS_NO_DEPRECATED struct irq_data irq_data; +#else + /* + * This union will go away, once we fixed the direct access to + * irq_desc all over the place. The direct fields are a 1:1 + * overlay of irq_data. + */ + union { + struct irq_data irq_data; + struct { + unsigned int irq; + unsigned int node; + unsigned int pad_do_not_even_think_about_it; + struct irq_chip *chip; + void *handler_data; + void *chip_data; + struct msi_desc *msi_desc; +#ifdef CONFIG_SMP + cpumask_var_t affinity; +#endif + }; + }; +#endif + struct timer_rand_state *timer_rand_state; unsigned int __percpu *kstat_irqs; irq_flow_handler_t handle_irq; @@ -43,7 +68,11 @@ struct irq_desc { irq_preflow_handler_t preflow_handler; #endif struct irqaction *action; /* IRQ action list */ +#ifdef CONFIG_GENERIC_HARDIRQS_NO_COMPAT unsigned int status_use_accessors; +#else + unsigned int status; /* IRQ status */ +#endif unsigned int core_internal_state__do_not_mess_with_it; unsigned int depth; /* nested irq disables */ unsigned int wake_depth; /* nested wake enables */ @@ -98,6 +127,27 @@ static inline struct msi_desc *irq_desc_get_msi_desc(struct irq_desc *desc) return desc->irq_data.msi_desc; } +#ifndef CONFIG_GENERIC_HARDIRQS_NO_COMPAT +static inline struct irq_chip *get_irq_desc_chip(struct irq_desc *desc) +{ + return irq_desc_get_chip(desc); +} +static inline void *get_irq_desc_data(struct irq_desc *desc) +{ + return irq_desc_get_handler_data(desc); +} + +static inline void *get_irq_desc_chip_data(struct irq_desc *desc) +{ + return irq_desc_get_chip_data(desc); +} + +static inline struct msi_desc *get_irq_desc_msi(struct irq_desc *desc) +{ + return irq_desc_get_msi_desc(desc); +} +#endif + /* * Architectures call this to let the generic IRQ layer * handle an interrupt. If the descriptor is attached to an @@ -144,13 +194,21 @@ __irq_set_chip_handler_name_locked(unsigned int irq, struct irq_chip *chip, desc->name = name; } +#ifndef CONFIG_GENERIC_HARDIRQS_NO_COMPAT +static inline void __set_irq_handler_unlocked(int irq, + irq_flow_handler_t handler) +{ + __irq_set_handler_locked(irq, handler); +} + static inline int irq_balancing_disabled(unsigned int irq) { struct irq_desc *desc; desc = irq_to_desc(irq); - return desc->status_use_accessors & IRQ_NO_BALANCING_MASK; + return desc->status & IRQ_NO_BALANCING_MASK; } +#endif static inline void irq_set_lockdep_class(unsigned int irq, struct lock_class_key *class) diff --git a/trunk/include/linux/mfd/ab8500.h b/trunk/include/linux/mfd/ab8500.h index b31843075198..56f8dea72152 100644 --- a/trunk/include/linux/mfd/ab8500.h +++ b/trunk/include/linux/mfd/ab8500.h @@ -74,45 +74,6 @@ #define AB8500_INT_ACC_DETECT_21DB_F 37 #define AB8500_INT_ACC_DETECT_21DB_R 38 #define AB8500_INT_GP_SW_ADC_CONV_END 39 -#define AB8500_INT_ACC_DETECT_1DB_F 33 -#define AB8500_INT_ACC_DETECT_1DB_R 34 -#define AB8500_INT_ACC_DETECT_22DB_F 35 -#define AB8500_INT_ACC_DETECT_22DB_R 36 -#define AB8500_INT_ACC_DETECT_21DB_F 37 -#define AB8500_INT_ACC_DETECT_21DB_R 38 -#define AB8500_INT_GP_SW_ADC_CONV_END 39 -#define AB8500_INT_GPIO6R 40 -#define AB8500_INT_GPIO7R 41 -#define AB8500_INT_GPIO8R 42 -#define AB8500_INT_GPIO9R 43 -#define AB8500_INT_GPIO10R 44 -#define AB8500_INT_GPIO11R 45 -#define AB8500_INT_GPIO12R 46 -#define AB8500_INT_GPIO13R 47 -#define AB8500_INT_GPIO24R 48 -#define AB8500_INT_GPIO25R 49 -#define AB8500_INT_GPIO36R 50 -#define AB8500_INT_GPIO37R 51 -#define AB8500_INT_GPIO38R 52 -#define AB8500_INT_GPIO39R 53 -#define AB8500_INT_GPIO40R 54 -#define AB8500_INT_GPIO41R 55 -#define AB8500_INT_GPIO6F 56 -#define AB8500_INT_GPIO7F 57 -#define AB8500_INT_GPIO8F 58 -#define AB8500_INT_GPIO9F 59 -#define AB8500_INT_GPIO10F 60 -#define AB8500_INT_GPIO11F 61 -#define AB8500_INT_GPIO12F 62 -#define AB8500_INT_GPIO13F 63 -#define AB8500_INT_GPIO24F 64 -#define AB8500_INT_GPIO25F 65 -#define AB8500_INT_GPIO36F 66 -#define AB8500_INT_GPIO37F 67 -#define AB8500_INT_GPIO38F 68 -#define AB8500_INT_GPIO39F 69 -#define AB8500_INT_GPIO40F 70 -#define AB8500_INT_GPIO41F 71 #define AB8500_INT_ADP_SOURCE_ERROR 72 #define AB8500_INT_ADP_SINK_ERROR 73 #define AB8500_INT_ADP_PROBE_PLUG 74 @@ -178,27 +139,19 @@ struct ab8500 { u8 oldmask[AB8500_NUM_IRQ_REGS]; }; -struct regulator_reg_init; struct regulator_init_data; -struct ab8500_gpio_platform_data; /** * struct ab8500_platform_data - AB8500 platform data * @irq_base: start of AB8500 IRQs, AB8500_NR_IRQS will be used * @init: board-specific initialization after detection of ab8500 - * @num_regulator_reg_init: number of regulator init registers - * @regulator_reg_init: regulator init registers - * @num_regulator: number of regulators * @regulator: machine-specific constraints for regulators */ struct ab8500_platform_data { int irq_base; void (*init) (struct ab8500 *); - int num_regulator_reg_init; - struct ab8500_regulator_reg_init *regulator_reg_init; int num_regulator; struct regulator_init_data *regulator; - struct ab8500_gpio_platform_data *gpio; }; extern int __devinit ab8500_init(struct ab8500 *ab8500); diff --git a/trunk/include/linux/mfd/ab8500/gpio.h b/trunk/include/linux/mfd/ab8500/gpio.h deleted file mode 100644 index 488a8c920a29..000000000000 --- a/trunk/include/linux/mfd/ab8500/gpio.h +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright ST-Ericsson 2010. - * - * Author: Bibek Basu - * Licensed under GPLv2. - */ - -#ifndef _AB8500_GPIO_H -#define _AB8500_GPIO_H - -/* - * Platform data to register a block: only the initial gpio/irq number. - */ - -struct ab8500_gpio_platform_data { - int gpio_base; - u32 irq_base; - u8 config_reg[7]; -}; - -#endif /* _AB8500_GPIO_H */ diff --git a/trunk/include/linux/mfd/core.h b/trunk/include/linux/mfd/core.h index ad1b19aa6508..1408bf8eed5f 100644 --- a/trunk/include/linux/mfd/core.h +++ b/trunk/include/linux/mfd/core.h @@ -62,24 +62,6 @@ struct mfd_cell { extern int mfd_cell_enable(struct platform_device *pdev); extern int mfd_cell_disable(struct platform_device *pdev); -/* - * "Clone" multiple platform devices for a single cell. This is to be used - * for devices that have multiple users of a cell. For example, if an mfd - * driver wants the cell "foo" to be used by a GPIO driver, an MTD driver, - * and a platform driver, the following bit of code would be use after first - * calling mfd_add_devices(): - * - * const char *fclones[] = { "foo-gpio", "foo-mtd" }; - * err = mfd_clone_cells("foo", fclones, ARRAY_SIZE(fclones)); - * - * Each driver (MTD, GPIO, and platform driver) would then register - * platform_drivers for "foo-mtd", "foo-gpio", and "foo", respectively. - * The cell's .enable/.disable hooks should be used to deal with hardware - * resource contention. - */ -extern int mfd_clone_cell(const char *cell, const char **clones, - size_t n_clones); - /* * Given a platform device that's been created by mfd_add_devices(), fetch * the mfd_cell that created it. @@ -105,4 +87,13 @@ extern int mfd_add_devices(struct device *parent, int id, extern void mfd_remove_devices(struct device *parent); +/* + * For MFD drivers with clients sharing access to resources, these create + * multiple platform devices per cell. Contention handling must still be + * handled via drivers (ie, with enable/disable hooks). + */ +extern int mfd_shared_platform_driver_register(struct platform_driver *drv, + const char *cellname); +extern void mfd_shared_platform_driver_unregister(struct platform_driver *drv); + #endif diff --git a/trunk/include/linux/mfd/max8997-private.h b/trunk/include/linux/mfd/max8997-private.h index 69d1010e2e51..93a9477e075f 100644 --- a/trunk/include/linux/mfd/max8997-private.h +++ b/trunk/include/linux/mfd/max8997-private.h @@ -24,8 +24,6 @@ #include -#define MAX8997_REG_INVALID (0xff) - enum max8997_pmic_reg { MAX8997_REG_PMIC_ID0 = 0x00, MAX8997_REG_PMIC_ID1 = 0x01, @@ -315,7 +313,6 @@ enum max8997_irq { #define MAX8997_REG_BUCK2DVS(x) (MAX8997_REG_BUCK2DVS1 + (x) - 1) #define MAX8997_REG_BUCK5DVS(x) (MAX8997_REG_BUCK5DVS1 + (x) - 1) -#define MAX8997_NUM_GPIO 12 struct max8997_dev { struct device *dev; struct i2c_client *i2c; /* 0xcc / PMIC, Battery Control, and FLASH */ @@ -327,19 +324,11 @@ struct max8997_dev { int type; struct platform_device *battery; /* battery control (not fuel gauge) */ - int irq; - int ono; - int irq_base; bool wakeup; - struct mutex irqlock; - int irq_masks_cur[MAX8997_IRQ_GROUP_NR]; - int irq_masks_cache[MAX8997_IRQ_GROUP_NR]; /* For hibernation */ u8 reg_dump[MAX8997_REG_PMIC_END + MAX8997_MUIC_REG_END + MAX8997_HAPTIC_REG_END]; - - bool gpio_status[MAX8997_NUM_GPIO]; }; enum max8997_types { @@ -347,10 +336,6 @@ enum max8997_types { TYPE_MAX8966, }; -extern int max8997_irq_init(struct max8997_dev *max8997); -extern void max8997_irq_exit(struct max8997_dev *max8997); -extern int max8997_irq_resume(struct max8997_dev *max8997); - extern int max8997_read_reg(struct i2c_client *i2c, u8 reg, u8 *dest); extern int max8997_bulk_read(struct i2c_client *i2c, u8 reg, int count, u8 *buf); @@ -359,10 +344,4 @@ extern int max8997_bulk_write(struct i2c_client *i2c, u8 reg, int count, u8 *buf); extern int max8997_update_reg(struct i2c_client *i2c, u8 reg, u8 val, u8 mask); -#define MAX8997_GPIO_INT_BOTH (0x3 << 4) -#define MAX8997_GPIO_INT_RISE (0x2 << 4) -#define MAX8997_GPIO_INT_FALL (0x1 << 4) - -#define MAX8997_GPIO_INT_MASK (0x3 << 4) -#define MAX8997_GPIO_DATA_MASK (0x1 << 2) #endif /* __LINUX_MFD_MAX8997_PRIV_H */ diff --git a/trunk/include/linux/mfd/max8997.h b/trunk/include/linux/mfd/max8997.h index 60931d089422..cb671b3451bf 100644 --- a/trunk/include/linux/mfd/max8997.h +++ b/trunk/include/linux/mfd/max8997.h @@ -78,11 +78,8 @@ struct max8997_regulator_data { }; struct max8997_platform_data { - /* IRQ */ - int irq_base; - int ono; - int wakeup; - + bool wakeup; + /* IRQ: Not implemented */ /* ---- PMIC ---- */ struct max8997_regulator_data *regulators; int num_regulators; diff --git a/trunk/include/linux/mtd/blktrans.h b/trunk/include/linux/mtd/blktrans.h index 1bbd9f289245..26529ebd59cc 100644 --- a/trunk/include/linux/mtd/blktrans.h +++ b/trunk/include/linux/mtd/blktrans.h @@ -36,7 +36,6 @@ struct mtd_blktrans_dev { struct mtd_info *mtd; struct mutex lock; int devnum; - bool bg_stop; unsigned long size; int readonly; int open; @@ -63,7 +62,6 @@ struct mtd_blktrans_ops { unsigned long block, char *buffer); int (*discard)(struct mtd_blktrans_dev *dev, unsigned long block, unsigned nr_blocks); - void (*background)(struct mtd_blktrans_dev *dev); /* Block layer ioctls */ int (*getgeo)(struct mtd_blktrans_dev *dev, struct hd_geometry *geo); @@ -87,7 +85,6 @@ extern int register_mtd_blktrans(struct mtd_blktrans_ops *tr); extern int deregister_mtd_blktrans(struct mtd_blktrans_ops *tr); extern int add_mtd_blktrans_dev(struct mtd_blktrans_dev *dev); extern int del_mtd_blktrans_dev(struct mtd_blktrans_dev *dev); -extern int mtd_blktrans_cease_background(struct mtd_blktrans_dev *dev); #endif /* __MTD_TRANS_H__ */ diff --git a/trunk/include/linux/mtd/cfi.h b/trunk/include/linux/mtd/cfi.h index 0d823f2dd667..a9baee6864af 100644 --- a/trunk/include/linux/mtd/cfi.h +++ b/trunk/include/linux/mtd/cfi.h @@ -535,7 +535,6 @@ struct cfi_fixup { #define CFI_MFR_CONTINUATION 0x007F #define CFI_MFR_AMD 0x0001 -#define CFI_MFR_AMIC 0x0037 #define CFI_MFR_ATMEL 0x001F #define CFI_MFR_EON 0x001C #define CFI_MFR_FUJITSU 0x0004 diff --git a/trunk/include/linux/mtd/latch-addr-flash.h b/trunk/include/linux/mtd/latch-addr-flash.h deleted file mode 100644 index e94b8e128074..000000000000 --- a/trunk/include/linux/mtd/latch-addr-flash.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Interface for NOR flash driver whose high address lines are latched - * - * Copyright © 2008 MontaVista Software, Inc. - * - * This file is licensed under the terms of the GNU General Public License - * version 2. This program is licensed "as is" without any warranty of any - * kind, whether express or implied. - */ -#ifndef __LATCH_ADDR_FLASH__ -#define __LATCH_ADDR_FLASH__ - -struct map_info; -struct mtd_partition; - -struct latch_addr_flash_data { - unsigned int width; - unsigned int size; - - int (*init)(void *data, int cs); - void (*done)(void *data); - void (*set_window)(unsigned long offset, void *data); - void *data; - - unsigned int nr_parts; - struct mtd_partition *parts; -}; - -#endif diff --git a/trunk/include/linux/mtd/nand.h b/trunk/include/linux/mtd/nand.h index ae67ef56a8f5..1f489b247a29 100644 --- a/trunk/include/linux/mtd/nand.h +++ b/trunk/include/linux/mtd/nand.h @@ -140,7 +140,6 @@ typedef enum { NAND_ECC_HW, NAND_ECC_HW_SYNDROME, NAND_ECC_HW_OOB_FIRST, - NAND_ECC_SOFT_BCH, } nand_ecc_modes_t; /* @@ -340,7 +339,6 @@ struct nand_hw_control { * @prepad: padding information for syndrome based ecc generators * @postpad: padding information for syndrome based ecc generators * @layout: ECC layout control struct pointer - * @priv: pointer to private ecc control data * @hwctl: function to control hardware ecc generator. Must only * be provided if an hardware ECC is available * @calculate: function for ecc calculation or readback from ecc hardware @@ -364,7 +362,6 @@ struct nand_ecc_ctrl { int prepad; int postpad; struct nand_ecclayout *layout; - void *priv; void (*hwctl)(struct mtd_info *mtd, int mode); int (*calculate)(struct mtd_info *mtd, const uint8_t *dat, uint8_t *ecc_code); diff --git a/trunk/include/linux/mtd/nand_bch.h b/trunk/include/linux/mtd/nand_bch.h deleted file mode 100644 index 74acf5367556..000000000000 --- a/trunk/include/linux/mtd/nand_bch.h +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright © 2011 Ivan Djelic - * - * 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. - * - * This file is the header for the NAND BCH ECC implementation. - */ - -#ifndef __MTD_NAND_BCH_H__ -#define __MTD_NAND_BCH_H__ - -struct mtd_info; -struct nand_bch_control; - -#if defined(CONFIG_MTD_NAND_ECC_BCH) - -static inline int mtd_nand_has_bch(void) { return 1; } - -/* - * Calculate BCH ecc code - */ -int nand_bch_calculate_ecc(struct mtd_info *mtd, const u_char *dat, - u_char *ecc_code); - -/* - * Detect and correct bit errors - */ -int nand_bch_correct_data(struct mtd_info *mtd, u_char *dat, u_char *read_ecc, - u_char *calc_ecc); -/* - * Initialize BCH encoder/decoder - */ -struct nand_bch_control * -nand_bch_init(struct mtd_info *mtd, unsigned int eccsize, - unsigned int eccbytes, struct nand_ecclayout **ecclayout); -/* - * Release BCH encoder/decoder resources - */ -void nand_bch_free(struct nand_bch_control *nbc); - -#else /* !CONFIG_MTD_NAND_ECC_BCH */ - -static inline int mtd_nand_has_bch(void) { return 0; } - -static inline int -nand_bch_calculate_ecc(struct mtd_info *mtd, const u_char *dat, - u_char *ecc_code) -{ - return -1; -} - -static inline int -nand_bch_correct_data(struct mtd_info *mtd, unsigned char *buf, - unsigned char *read_ecc, unsigned char *calc_ecc) -{ - return -1; -} - -static inline struct nand_bch_control * -nand_bch_init(struct mtd_info *mtd, unsigned int eccsize, - unsigned int eccbytes, struct nand_ecclayout **ecclayout) -{ - return NULL; -} - -static inline void nand_bch_free(struct nand_bch_control *nbc) {} - -#endif /* CONFIG_MTD_NAND_ECC_BCH */ - -#endif /* __MTD_NAND_BCH_H__ */ diff --git a/trunk/include/linux/mtd/onenand.h b/trunk/include/linux/mtd/onenand.h index 52b6f187bf49..ae418e41d8f5 100644 --- a/trunk/include/linux/mtd/onenand.h +++ b/trunk/include/linux/mtd/onenand.h @@ -198,7 +198,6 @@ struct onenand_chip { #define ONENAND_SKIP_UNLOCK_CHECK (0x0100) #define ONENAND_PAGEBUF_ALLOC (0x1000) #define ONENAND_OOBBUF_ALLOC (0x2000) -#define ONENAND_SKIP_INITIAL_UNLOCKING (0x4000) #define ONENAND_IS_4KB_PAGE(this) \ (this->options & ONENAND_HAS_4KB_PAGE) diff --git a/trunk/include/linux/nfs_page.h b/trunk/include/linux/nfs_page.h index 91af2e49fa3a..8023e4e25133 100644 --- a/trunk/include/linux/nfs_page.h +++ b/trunk/include/linux/nfs_page.h @@ -78,6 +78,7 @@ extern struct nfs_page *nfs_create_request(struct nfs_open_context *ctx, struct page *page, unsigned int offset, unsigned int count); +extern void nfs_clear_request(struct nfs_page *req); extern void nfs_release_request(struct nfs_page *req); diff --git a/trunk/include/linux/regulator/ab8500.h b/trunk/include/linux/regulator/ab8500.h index 76579f964a29..6a210f1511fc 100644 --- a/trunk/include/linux/regulator/ab8500.h +++ b/trunk/include/linux/regulator/ab8500.h @@ -3,8 +3,8 @@ * * License Terms: GNU General Public License v2 * - * Authors: Sundar Iyer for ST-Ericsson - * Bengt Jonsson for ST-Ericsson + * Author: Sundar Iyer for ST-Ericsson + * */ #ifndef __LINUX_MFD_AB8500_REGULATOR_H @@ -17,7 +17,6 @@ enum ab8500_regulator_id { AB8500_LDO_AUX3, AB8500_LDO_INTCORE, AB8500_LDO_TVOUT, - AB8500_LDO_USB, AB8500_LDO_AUDIO, AB8500_LDO_ANAMIC1, AB8500_LDO_ANAMIC2, @@ -25,50 +24,4 @@ enum ab8500_regulator_id { AB8500_LDO_ANA, AB8500_NUM_REGULATORS, }; - -/* AB8500 register initialization */ -struct ab8500_regulator_reg_init { - int id; - u8 value; -}; - -#define INIT_REGULATOR_REGISTER(_id, _value) \ - { \ - .id = _id, \ - .value = _value, \ - } - -/* AB8500 registers */ -enum ab8500_regulator_reg { - AB8500_REGUREQUESTCTRL2, - AB8500_REGUREQUESTCTRL3, - AB8500_REGUREQUESTCTRL4, - AB8500_REGUSYSCLKREQ1HPVALID1, - AB8500_REGUSYSCLKREQ1HPVALID2, - AB8500_REGUHWHPREQ1VALID1, - AB8500_REGUHWHPREQ1VALID2, - AB8500_REGUHWHPREQ2VALID1, - AB8500_REGUHWHPREQ2VALID2, - AB8500_REGUSWHPREQVALID1, - AB8500_REGUSWHPREQVALID2, - AB8500_REGUSYSCLKREQVALID1, - AB8500_REGUSYSCLKREQVALID2, - AB8500_REGUMISC1, - AB8500_VAUDIOSUPPLY, - AB8500_REGUCTRL1VAMIC, - AB8500_VPLLVANAREGU, - AB8500_VREFDDR, - AB8500_EXTSUPPLYREGU, - AB8500_VAUX12REGU, - AB8500_VRF1VAUX3REGU, - AB8500_VAUX1SEL, - AB8500_VAUX2SEL, - AB8500_VRF1VAUX3SEL, - AB8500_REGUCTRL2SPARE, - AB8500_REGUCTRLDISCH, - AB8500_REGUCTRLDISCH2, - AB8500_VSMPS1SEL1, - AB8500_NUM_REGULATOR_REGISTERS, -}; - #endif diff --git a/trunk/include/linux/regulator/consumer.h b/trunk/include/linux/regulator/consumer.h index 9e87c1cb7270..7954f6bd7edb 100644 --- a/trunk/include/linux/regulator/consumer.h +++ b/trunk/include/linux/regulator/consumer.h @@ -153,8 +153,6 @@ int regulator_list_voltage(struct regulator *regulator, unsigned selector); int regulator_is_supported_voltage(struct regulator *regulator, int min_uV, int max_uV); int regulator_set_voltage(struct regulator *regulator, int min_uV, int max_uV); -int regulator_set_voltage_time(struct regulator *regulator, - int old_uV, int new_uV); int regulator_get_voltage(struct regulator *regulator); int regulator_sync_voltage(struct regulator *regulator); int regulator_set_current_limit(struct regulator *regulator, diff --git a/trunk/include/linux/regulator/driver.h b/trunk/include/linux/regulator/driver.h index 6c433b89c80d..b8ed16a33c47 100644 --- a/trunk/include/linux/regulator/driver.h +++ b/trunk/include/linux/regulator/driver.h @@ -63,11 +63,7 @@ enum regulator_status { * when running with the specified parameters. * * @enable_time: Time taken for the regulator voltage output voltage to - * stabilise after being enabled, in microseconds. - * @set_voltage_time_sel: Time taken for the regulator voltage output voltage - * to stabilise after being set to a new value, in microseconds. - * The function provides the from and to voltage selector, the - * function should return the worst case. + * stabalise after being enabled, in microseconds. * * @set_suspend_voltage: Set the voltage for the regulator when the system * is suspended. @@ -107,11 +103,8 @@ struct regulator_ops { int (*set_mode) (struct regulator_dev *, unsigned int mode); unsigned int (*get_mode) (struct regulator_dev *); - /* Time taken to enable or set voltage on the regulator */ + /* Time taken to enable the regulator */ int (*enable_time) (struct regulator_dev *); - int (*set_voltage_time_sel) (struct regulator_dev *, - unsigned int old_selector, - unsigned int new_selector); /* report regulator status ... most other accessors report * control inputs, this reports results of combining inputs diff --git a/trunk/include/linux/regulator/machine.h b/trunk/include/linux/regulator/machine.h index c4c4fc45f856..761c745b9c24 100644 --- a/trunk/include/linux/regulator/machine.h +++ b/trunk/include/linux/regulator/machine.h @@ -186,7 +186,6 @@ struct regulator_init_data { }; int regulator_suspend_prepare(suspend_state_t state); -int regulator_suspend_finish(void); #ifdef CONFIG_REGULATOR void regulator_has_full_constraints(void); diff --git a/trunk/include/linux/skbuff.h b/trunk/include/linux/skbuff.h index 239083bfea13..24cfa626931e 100644 --- a/trunk/include/linux/skbuff.h +++ b/trunk/include/linux/skbuff.h @@ -122,14 +122,8 @@ struct sk_buff_head { struct sk_buff; -/* To allow 64K frame to be packed as single skb without frag_list. Since - * GRO uses frags we allocate at least 16 regardless of page size. - */ -#if (65536/PAGE_SIZE + 2) < 16 -#define MAX_SKB_FRAGS 16 -#else +/* To allow 64K frame to be packed as single skb without frag_list */ #define MAX_SKB_FRAGS (65536/PAGE_SIZE + 2) -#endif typedef struct skb_frag_struct skb_frag_t; diff --git a/trunk/include/linux/sonypi.h b/trunk/include/linux/sonypi.h index c0f87da78f8a..0e6dc3891942 100644 --- a/trunk/include/linux/sonypi.h +++ b/trunk/include/linux/sonypi.h @@ -40,7 +40,6 @@ /* events the user application reading /dev/sonypi can use */ -#define SONYPI_EVENT_IGNORE 0 #define SONYPI_EVENT_JOGDIAL_DOWN 1 #define SONYPI_EVENT_JOGDIAL_UP 2 #define SONYPI_EVENT_JOGDIAL_DOWN_PRESSED 3 diff --git a/trunk/include/net/dst.h b/trunk/include/net/dst.h index 75b95df4afe7..2a46cbaef92d 100644 --- a/trunk/include/net/dst.h +++ b/trunk/include/net/dst.h @@ -345,7 +345,7 @@ static inline void skb_tunnel_rx(struct sk_buff *skb, struct net_device *dev) static inline struct dst_entry *skb_dst_pop(struct sk_buff *skb) { - struct dst_entry *child = dst_clone(skb_dst(skb)->child); + struct dst_entry *child = skb_dst(skb)->child; skb_dst_drop(skb); return child; diff --git a/trunk/include/net/rose.h b/trunk/include/net/rose.h index 555dd198aab7..5ba9f02731eb 100644 --- a/trunk/include/net/rose.h +++ b/trunk/include/net/rose.h @@ -14,12 +14,6 @@ #define ROSE_MIN_LEN 3 -#define ROSE_CALL_REQ_ADDR_LEN_OFF 3 -#define ROSE_CALL_REQ_ADDR_LEN_VAL 0xAA /* each address is 10 digits */ -#define ROSE_CALL_REQ_DEST_ADDR_OFF 4 -#define ROSE_CALL_REQ_SRC_ADDR_OFF 9 -#define ROSE_CALL_REQ_FACILITIES_OFF 14 - #define ROSE_GFI 0x10 #define ROSE_Q_BIT 0x80 #define ROSE_D_BIT 0x40 @@ -220,7 +214,7 @@ extern void rose_requeue_frames(struct sock *); extern int rose_validate_nr(struct sock *, unsigned short); extern void rose_write_internal(struct sock *, int); extern int rose_decode(struct sk_buff *, int *, int *, int *, int *, int *); -extern int rose_parse_facilities(unsigned char *, unsigned int, struct rose_facilities_struct *); +extern int rose_parse_facilities(unsigned char *, struct rose_facilities_struct *); extern void rose_disconnect(struct sock *, int, int, int); /* rose_timer.c */ diff --git a/trunk/include/net/xfrm.h b/trunk/include/net/xfrm.h index 6ae4bc5ce8a7..cffa5dc66449 100644 --- a/trunk/include/net/xfrm.h +++ b/trunk/include/net/xfrm.h @@ -1601,28 +1601,6 @@ static inline int xfrm_replay_state_esn_len(struct xfrm_replay_state_esn *replay } #ifdef CONFIG_XFRM_MIGRATE -static inline int xfrm_replay_clone(struct xfrm_state *x, - struct xfrm_state *orig) -{ - x->replay_esn = kzalloc(xfrm_replay_state_esn_len(orig->replay_esn), - GFP_KERNEL); - if (!x->replay_esn) - return -ENOMEM; - - x->replay_esn->bmp_len = orig->replay_esn->bmp_len; - x->replay_esn->replay_window = orig->replay_esn->replay_window; - - x->preplay_esn = kmemdup(x->replay_esn, - xfrm_replay_state_esn_len(x->replay_esn), - GFP_KERNEL); - if (!x->preplay_esn) { - kfree(x->replay_esn); - return -ENOMEM; - } - - return 0; -} - static inline struct xfrm_algo *xfrm_algo_clone(struct xfrm_algo *orig) { return kmemdup(orig, xfrm_alg_len(orig), GFP_KERNEL); diff --git a/trunk/include/sound/pcm.h b/trunk/include/sound/pcm.h index e1bad1130616..430a9cc045e2 100644 --- a/trunk/include/sound/pcm.h +++ b/trunk/include/sound/pcm.h @@ -1031,7 +1031,9 @@ int snd_pcm_lib_mmap_iomem(struct snd_pcm_substream *substream, struct vm_area_s #define snd_pcm_lib_mmap_iomem NULL #endif -#define snd_pcm_lib_mmap_vmalloc NULL +int snd_pcm_lib_mmap_noncached(struct snd_pcm_substream *substream, + struct vm_area_struct *area); +#define snd_pcm_lib_mmap_vmalloc snd_pcm_lib_mmap_noncached static inline void snd_pcm_limit_isa_dma_size(int dma, size_t *max) { diff --git a/trunk/include/trace/events/btrfs.h b/trunk/include/trace/events/btrfs.h deleted file mode 100644 index f445cff66ab7..000000000000 --- a/trunk/include/trace/events/btrfs.h +++ /dev/null @@ -1,667 +0,0 @@ -#undef TRACE_SYSTEM -#define TRACE_SYSTEM btrfs - -#if !defined(_TRACE_BTRFS_H) || defined(TRACE_HEADER_MULTI_READ) -#define _TRACE_BTRFS_H - -#include -#include - -struct btrfs_root; -struct btrfs_fs_info; -struct btrfs_inode; -struct extent_map; -struct btrfs_ordered_extent; -struct btrfs_delayed_ref_node; -struct btrfs_delayed_tree_ref; -struct btrfs_delayed_data_ref; -struct btrfs_delayed_ref_head; -struct map_lookup; -struct extent_buffer; - -#define show_ref_type(type) \ - __print_symbolic(type, \ - { BTRFS_TREE_BLOCK_REF_KEY, "TREE_BLOCK_REF" }, \ - { BTRFS_EXTENT_DATA_REF_KEY, "EXTENT_DATA_REF" }, \ - { BTRFS_EXTENT_REF_V0_KEY, "EXTENT_REF_V0" }, \ - { BTRFS_SHARED_BLOCK_REF_KEY, "SHARED_BLOCK_REF" }, \ - { BTRFS_SHARED_DATA_REF_KEY, "SHARED_DATA_REF" }) - -#define __show_root_type(obj) \ - __print_symbolic(obj, \ - { BTRFS_ROOT_TREE_OBJECTID, "ROOT_TREE" }, \ - { BTRFS_EXTENT_TREE_OBJECTID, "EXTENT_TREE" }, \ - { BTRFS_CHUNK_TREE_OBJECTID, "CHUNK_TREE" }, \ - { BTRFS_DEV_TREE_OBJECTID, "DEV_TREE" }, \ - { BTRFS_FS_TREE_OBJECTID, "FS_TREE" }, \ - { BTRFS_ROOT_TREE_DIR_OBJECTID, "ROOT_TREE_DIR" }, \ - { BTRFS_CSUM_TREE_OBJECTID, "CSUM_TREE" }, \ - { BTRFS_TREE_LOG_OBJECTID, "TREE_LOG" }, \ - { BTRFS_TREE_RELOC_OBJECTID, "TREE_RELOC" }, \ - { BTRFS_DATA_RELOC_TREE_OBJECTID, "DATA_RELOC_TREE" }) - -#define show_root_type(obj) \ - obj, ((obj >= BTRFS_DATA_RELOC_TREE_OBJECTID) || \ - (obj <= BTRFS_CSUM_TREE_OBJECTID )) ? __show_root_type(obj) : "-" - -TRACE_EVENT(btrfs_transaction_commit, - - TP_PROTO(struct btrfs_root *root), - - TP_ARGS(root), - - TP_STRUCT__entry( - __field( u64, generation ) - __field( u64, root_objectid ) - ), - - TP_fast_assign( - __entry->generation = root->fs_info->generation; - __entry->root_objectid = root->root_key.objectid; - ), - - TP_printk("root = %llu(%s), gen = %llu", - show_root_type(__entry->root_objectid), - (unsigned long long)__entry->generation) -); - -DECLARE_EVENT_CLASS(btrfs__inode, - - TP_PROTO(struct inode *inode), - - TP_ARGS(inode), - - TP_STRUCT__entry( - __field( ino_t, ino ) - __field( blkcnt_t, blocks ) - __field( u64, disk_i_size ) - __field( u64, generation ) - __field( u64, last_trans ) - __field( u64, logged_trans ) - __field( u64, root_objectid ) - ), - - TP_fast_assign( - __entry->ino = inode->i_ino; - __entry->blocks = inode->i_blocks; - __entry->disk_i_size = BTRFS_I(inode)->disk_i_size; - __entry->generation = BTRFS_I(inode)->generation; - __entry->last_trans = BTRFS_I(inode)->last_trans; - __entry->logged_trans = BTRFS_I(inode)->logged_trans; - __entry->root_objectid = - BTRFS_I(inode)->root->root_key.objectid; - ), - - TP_printk("root = %llu(%s), gen = %llu, ino = %lu, blocks = %llu, " - "disk_i_size = %llu, last_trans = %llu, logged_trans = %llu", - show_root_type(__entry->root_objectid), - (unsigned long long)__entry->generation, - (unsigned long)__entry->ino, - (unsigned long long)__entry->blocks, - (unsigned long long)__entry->disk_i_size, - (unsigned long long)__entry->last_trans, - (unsigned long long)__entry->logged_trans) -); - -DEFINE_EVENT(btrfs__inode, btrfs_inode_new, - - TP_PROTO(struct inode *inode), - - TP_ARGS(inode) -); - -DEFINE_EVENT(btrfs__inode, btrfs_inode_request, - - TP_PROTO(struct inode *inode), - - TP_ARGS(inode) -); - -DEFINE_EVENT(btrfs__inode, btrfs_inode_evict, - - TP_PROTO(struct inode *inode), - - TP_ARGS(inode) -); - -#define __show_map_type(type) \ - __print_symbolic(type, \ - { EXTENT_MAP_LAST_BYTE, "LAST_BYTE" }, \ - { EXTENT_MAP_HOLE, "HOLE" }, \ - { EXTENT_MAP_INLINE, "INLINE" }, \ - { EXTENT_MAP_DELALLOC, "DELALLOC" }) - -#define show_map_type(type) \ - type, (type >= EXTENT_MAP_LAST_BYTE) ? "-" : __show_map_type(type) - -#define show_map_flags(flag) \ - __print_flags(flag, "|", \ - { EXTENT_FLAG_PINNED, "PINNED" }, \ - { EXTENT_FLAG_COMPRESSED, "COMPRESSED" }, \ - { EXTENT_FLAG_VACANCY, "VACANCY" }, \ - { EXTENT_FLAG_PREALLOC, "PREALLOC" }) - -TRACE_EVENT(btrfs_get_extent, - - TP_PROTO(struct btrfs_root *root, struct extent_map *map), - - TP_ARGS(root, map), - - TP_STRUCT__entry( - __field( u64, root_objectid ) - __field( u64, start ) - __field( u64, len ) - __field( u64, orig_start ) - __field( u64, block_start ) - __field( u64, block_len ) - __field( unsigned long, flags ) - __field( int, refs ) - __field( unsigned int, compress_type ) - ), - - TP_fast_assign( - __entry->root_objectid = root->root_key.objectid; - __entry->start = map->start; - __entry->len = map->len; - __entry->orig_start = map->orig_start; - __entry->block_start = map->block_start; - __entry->block_len = map->block_len; - __entry->flags = map->flags; - __entry->refs = atomic_read(&map->refs); - __entry->compress_type = map->compress_type; - ), - - TP_printk("root = %llu(%s), start = %llu, len = %llu, " - "orig_start = %llu, block_start = %llu(%s), " - "block_len = %llu, flags = %s, refs = %u, " - "compress_type = %u", - show_root_type(__entry->root_objectid), - (unsigned long long)__entry->start, - (unsigned long long)__entry->len, - (unsigned long long)__entry->orig_start, - show_map_type(__entry->block_start), - (unsigned long long)__entry->block_len, - show_map_flags(__entry->flags), - __entry->refs, __entry->compress_type) -); - -#define show_ordered_flags(flags) \ - __print_symbolic(flags, \ - { BTRFS_ORDERED_IO_DONE, "IO_DONE" }, \ - { BTRFS_ORDERED_COMPLETE, "COMPLETE" }, \ - { BTRFS_ORDERED_NOCOW, "NOCOW" }, \ - { BTRFS_ORDERED_COMPRESSED, "COMPRESSED" }, \ - { BTRFS_ORDERED_PREALLOC, "PREALLOC" }, \ - { BTRFS_ORDERED_DIRECT, "DIRECT" }) - -DECLARE_EVENT_CLASS(btrfs__ordered_extent, - - TP_PROTO(struct inode *inode, struct btrfs_ordered_extent *ordered), - - TP_ARGS(inode, ordered), - - TP_STRUCT__entry( - __field( ino_t, ino ) - __field( u64, file_offset ) - __field( u64, start ) - __field( u64, len ) - __field( u64, disk_len ) - __field( u64, bytes_left ) - __field( unsigned long, flags ) - __field( int, compress_type ) - __field( int, refs ) - __field( u64, root_objectid ) - ), - - TP_fast_assign( - __entry->ino = inode->i_ino; - __entry->file_offset = ordered->file_offset; - __entry->start = ordered->start; - __entry->len = ordered->len; - __entry->disk_len = ordered->disk_len; - __entry->bytes_left = ordered->bytes_left; - __entry->flags = ordered->flags; - __entry->compress_type = ordered->compress_type; - __entry->refs = atomic_read(&ordered->refs); - __entry->root_objectid = - BTRFS_I(inode)->root->root_key.objectid; - ), - - TP_printk("root = %llu(%s), ino = %llu, file_offset = %llu, " - "start = %llu, len = %llu, disk_len = %llu, " - "bytes_left = %llu, flags = %s, compress_type = %d, " - "refs = %d", - show_root_type(__entry->root_objectid), - (unsigned long long)__entry->ino, - (unsigned long long)__entry->file_offset, - (unsigned long long)__entry->start, - (unsigned long long)__entry->len, - (unsigned long long)__entry->disk_len, - (unsigned long long)__entry->bytes_left, - show_ordered_flags(__entry->flags), - __entry->compress_type, __entry->refs) -); - -DEFINE_EVENT(btrfs__ordered_extent, btrfs_ordered_extent_add, - - TP_PROTO(struct inode *inode, struct btrfs_ordered_extent *ordered), - - TP_ARGS(inode, ordered) -); - -DEFINE_EVENT(btrfs__ordered_extent, btrfs_ordered_extent_remove, - - TP_PROTO(struct inode *inode, struct btrfs_ordered_extent *ordered), - - TP_ARGS(inode, ordered) -); - -DEFINE_EVENT(btrfs__ordered_extent, btrfs_ordered_extent_start, - - TP_PROTO(struct inode *inode, struct btrfs_ordered_extent *ordered), - - TP_ARGS(inode, ordered) -); - -DEFINE_EVENT(btrfs__ordered_extent, btrfs_ordered_extent_put, - - TP_PROTO(struct inode *inode, struct btrfs_ordered_extent *ordered), - - TP_ARGS(inode, ordered) -); - -DECLARE_EVENT_CLASS(btrfs__writepage, - - TP_PROTO(struct page *page, struct inode *inode, - struct writeback_control *wbc), - - TP_ARGS(page, inode, wbc), - - TP_STRUCT__entry( - __field( ino_t, ino ) - __field( pgoff_t, index ) - __field( long, nr_to_write ) - __field( long, pages_skipped ) - __field( loff_t, range_start ) - __field( loff_t, range_end ) - __field( char, nonblocking ) - __field( char, for_kupdate ) - __field( char, for_reclaim ) - __field( char, range_cyclic ) - __field( pgoff_t, writeback_index ) - __field( u64, root_objectid ) - ), - - TP_fast_assign( - __entry->ino = inode->i_ino; - __entry->index = page->index; - __entry->nr_to_write = wbc->nr_to_write; - __entry->pages_skipped = wbc->pages_skipped; - __entry->range_start = wbc->range_start; - __entry->range_end = wbc->range_end; - __entry->nonblocking = wbc->nonblocking; - __entry->for_kupdate = wbc->for_kupdate; - __entry->for_reclaim = wbc->for_reclaim; - __entry->range_cyclic = wbc->range_cyclic; - __entry->writeback_index = inode->i_mapping->writeback_index; - __entry->root_objectid = - BTRFS_I(inode)->root->root_key.objectid; - ), - - TP_printk("root = %llu(%s), ino = %lu, page_index = %lu, " - "nr_to_write = %ld, pages_skipped = %ld, range_start = %llu, " - "range_end = %llu, nonblocking = %d, for_kupdate = %d, " - "for_reclaim = %d, range_cyclic = %d, writeback_index = %lu", - show_root_type(__entry->root_objectid), - (unsigned long)__entry->ino, __entry->index, - __entry->nr_to_write, __entry->pages_skipped, - __entry->range_start, __entry->range_end, - __entry->nonblocking, __entry->for_kupdate, - __entry->for_reclaim, __entry->range_cyclic, - (unsigned long)__entry->writeback_index) -); - -DEFINE_EVENT(btrfs__writepage, __extent_writepage, - - TP_PROTO(struct page *page, struct inode *inode, - struct writeback_control *wbc), - - TP_ARGS(page, inode, wbc) -); - -TRACE_EVENT(btrfs_writepage_end_io_hook, - - TP_PROTO(struct page *page, u64 start, u64 end, int uptodate), - - TP_ARGS(page, start, end, uptodate), - - TP_STRUCT__entry( - __field( ino_t, ino ) - __field( pgoff_t, index ) - __field( u64, start ) - __field( u64, end ) - __field( int, uptodate ) - __field( u64, root_objectid ) - ), - - TP_fast_assign( - __entry->ino = page->mapping->host->i_ino; - __entry->index = page->index; - __entry->start = start; - __entry->end = end; - __entry->uptodate = uptodate; - __entry->root_objectid = - BTRFS_I(page->mapping->host)->root->root_key.objectid; - ), - - TP_printk("root = %llu(%s), ino = %lu, page_index = %lu, start = %llu, " - "end = %llu, uptodate = %d", - show_root_type(__entry->root_objectid), - (unsigned long)__entry->ino, (unsigned long)__entry->index, - (unsigned long long)__entry->start, - (unsigned long long)__entry->end, __entry->uptodate) -); - -TRACE_EVENT(btrfs_sync_file, - - TP_PROTO(struct file *file, int datasync), - - TP_ARGS(file, datasync), - - TP_STRUCT__entry( - __field( ino_t, ino ) - __field( ino_t, parent ) - __field( int, datasync ) - __field( u64, root_objectid ) - ), - - TP_fast_assign( - struct dentry *dentry = file->f_path.dentry; - struct inode *inode = dentry->d_inode; - - __entry->ino = inode->i_ino; - __entry->parent = dentry->d_parent->d_inode->i_ino; - __entry->datasync = datasync; - __entry->root_objectid = - BTRFS_I(inode)->root->root_key.objectid; - ), - - TP_printk("root = %llu(%s), ino = %ld, parent = %ld, datasync = %d", - show_root_type(__entry->root_objectid), - (unsigned long)__entry->ino, (unsigned long)__entry->parent, - __entry->datasync) -); - -TRACE_EVENT(btrfs_sync_fs, - - TP_PROTO(int wait), - - TP_ARGS(wait), - - TP_STRUCT__entry( - __field( int, wait ) - ), - - TP_fast_assign( - __entry->wait = wait; - ), - - TP_printk("wait = %d", __entry->wait) -); - -#define show_ref_action(action) \ - __print_symbolic(action, \ - { BTRFS_ADD_DELAYED_REF, "ADD_DELAYED_REF" }, \ - { BTRFS_DROP_DELAYED_REF, "DROP_DELAYED_REF" }, \ - { BTRFS_ADD_DELAYED_EXTENT, "ADD_DELAYED_EXTENT" }, \ - { BTRFS_UPDATE_DELAYED_HEAD, "UPDATE_DELAYED_HEAD" }) - - -TRACE_EVENT(btrfs_delayed_tree_ref, - - TP_PROTO(struct btrfs_delayed_ref_node *ref, - struct btrfs_delayed_tree_ref *full_ref, - int action), - - TP_ARGS(ref, full_ref, action), - - TP_STRUCT__entry( - __field( u64, bytenr ) - __field( u64, num_bytes ) - __field( int, action ) - __field( u64, parent ) - __field( u64, ref_root ) - __field( int, level ) - __field( int, type ) - ), - - TP_fast_assign( - __entry->bytenr = ref->bytenr; - __entry->num_bytes = ref->num_bytes; - __entry->action = action; - __entry->parent = full_ref->parent; - __entry->ref_root = full_ref->root; - __entry->level = full_ref->level; - __entry->type = ref->type; - ), - - TP_printk("bytenr = %llu, num_bytes = %llu, action = %s, " - "parent = %llu(%s), ref_root = %llu(%s), level = %d, " - "type = %s", - (unsigned long long)__entry->bytenr, - (unsigned long long)__entry->num_bytes, - show_ref_action(__entry->action), - show_root_type(__entry->parent), - show_root_type(__entry->ref_root), - __entry->level, show_ref_type(__entry->type)) -); - -TRACE_EVENT(btrfs_delayed_data_ref, - - TP_PROTO(struct btrfs_delayed_ref_node *ref, - struct btrfs_delayed_data_ref *full_ref, - int action), - - TP_ARGS(ref, full_ref, action), - - TP_STRUCT__entry( - __field( u64, bytenr ) - __field( u64, num_bytes ) - __field( int, action ) - __field( u64, parent ) - __field( u64, ref_root ) - __field( u64, owner ) - __field( u64, offset ) - __field( int, type ) - ), - - TP_fast_assign( - __entry->bytenr = ref->bytenr; - __entry->num_bytes = ref->num_bytes; - __entry->action = action; - __entry->parent = full_ref->parent; - __entry->ref_root = full_ref->root; - __entry->owner = full_ref->objectid; - __entry->offset = full_ref->offset; - __entry->type = ref->type; - ), - - TP_printk("bytenr = %llu, num_bytes = %llu, action = %s, " - "parent = %llu(%s), ref_root = %llu(%s), owner = %llu, " - "offset = %llu, type = %s", - (unsigned long long)__entry->bytenr, - (unsigned long long)__entry->num_bytes, - show_ref_action(__entry->action), - show_root_type(__entry->parent), - show_root_type(__entry->ref_root), - (unsigned long long)__entry->owner, - (unsigned long long)__entry->offset, - show_ref_type(__entry->type)) -); - -TRACE_EVENT(btrfs_delayed_ref_head, - - TP_PROTO(struct btrfs_delayed_ref_node *ref, - struct btrfs_delayed_ref_head *head_ref, - int action), - - TP_ARGS(ref, head_ref, action), - - TP_STRUCT__entry( - __field( u64, bytenr ) - __field( u64, num_bytes ) - __field( int, action ) - __field( int, is_data ) - ), - - TP_fast_assign( - __entry->bytenr = ref->bytenr; - __entry->num_bytes = ref->num_bytes; - __entry->action = action; - __entry->is_data = head_ref->is_data; - ), - - TP_printk("bytenr = %llu, num_bytes = %llu, action = %s, is_data = %d", - (unsigned long long)__entry->bytenr, - (unsigned long long)__entry->num_bytes, - show_ref_action(__entry->action), - __entry->is_data) -); - -#define show_chunk_type(type) \ - __print_flags(type, "|", \ - { BTRFS_BLOCK_GROUP_DATA, "DATA" }, \ - { BTRFS_BLOCK_GROUP_SYSTEM, "SYSTEM"}, \ - { BTRFS_BLOCK_GROUP_METADATA, "METADATA"}, \ - { BTRFS_BLOCK_GROUP_RAID0, "RAID0" }, \ - { BTRFS_BLOCK_GROUP_RAID1, "RAID1" }, \ - { BTRFS_BLOCK_GROUP_DUP, "DUP" }, \ - { BTRFS_BLOCK_GROUP_RAID10, "RAID10"}) - -DECLARE_EVENT_CLASS(btrfs__chunk, - - TP_PROTO(struct btrfs_root *root, struct map_lookup *map, - u64 offset, u64 size), - - TP_ARGS(root, map, offset, size), - - TP_STRUCT__entry( - __field( int, num_stripes ) - __field( u64, type ) - __field( int, sub_stripes ) - __field( u64, offset ) - __field( u64, size ) - __field( u64, root_objectid ) - ), - - TP_fast_assign( - __entry->num_stripes = map->num_stripes; - __entry->type = map->type; - __entry->sub_stripes = map->sub_stripes; - __entry->offset = offset; - __entry->size = size; - __entry->root_objectid = root->root_key.objectid; - ), - - TP_printk("root = %llu(%s), offset = %llu, size = %llu, " - "num_stripes = %d, sub_stripes = %d, type = %s", - show_root_type(__entry->root_objectid), - (unsigned long long)__entry->offset, - (unsigned long long)__entry->size, - __entry->num_stripes, __entry->sub_stripes, - show_chunk_type(__entry->type)) -); - -DEFINE_EVENT(btrfs__chunk, btrfs_chunk_alloc, - - TP_PROTO(struct btrfs_root *root, struct map_lookup *map, - u64 offset, u64 size), - - TP_ARGS(root, map, offset, size) -); - -DEFINE_EVENT(btrfs__chunk, btrfs_chunk_free, - - TP_PROTO(struct btrfs_root *root, struct map_lookup *map, - u64 offset, u64 size), - - TP_ARGS(root, map, offset, size) -); - -TRACE_EVENT(btrfs_cow_block, - - TP_PROTO(struct btrfs_root *root, struct extent_buffer *buf, - struct extent_buffer *cow), - - TP_ARGS(root, buf, cow), - - TP_STRUCT__entry( - __field( u64, root_objectid ) - __field( u64, buf_start ) - __field( int, refs ) - __field( u64, cow_start ) - __field( int, buf_level ) - __field( int, cow_level ) - ), - - TP_fast_assign( - __entry->root_objectid = root->root_key.objectid; - __entry->buf_start = buf->start; - __entry->refs = atomic_read(&buf->refs); - __entry->cow_start = cow->start; - __entry->buf_level = btrfs_header_level(buf); - __entry->cow_level = btrfs_header_level(cow); - ), - - TP_printk("root = %llu(%s), refs = %d, orig_buf = %llu " - "(orig_level = %d), cow_buf = %llu (cow_level = %d)", - show_root_type(__entry->root_objectid), - __entry->refs, - (unsigned long long)__entry->buf_start, - __entry->buf_level, - (unsigned long long)__entry->cow_start, - __entry->cow_level) -); - -DECLARE_EVENT_CLASS(btrfs__reserved_extent, - - TP_PROTO(struct btrfs_root *root, u64 start, u64 len), - - TP_ARGS(root, start, len), - - TP_STRUCT__entry( - __field( u64, root_objectid ) - __field( u64, start ) - __field( u64, len ) - ), - - TP_fast_assign( - __entry->root_objectid = root->root_key.objectid; - __entry->start = start; - __entry->len = len; - ), - - TP_printk("root = %llu(%s), start = %llu, len = %llu", - show_root_type(__entry->root_objectid), - (unsigned long long)__entry->start, - (unsigned long long)__entry->len) -); - -DEFINE_EVENT(btrfs__reserved_extent, btrfs_reserved_extent_alloc, - - TP_PROTO(struct btrfs_root *root, u64 start, u64 len), - - TP_ARGS(root, start, len) -); - -DEFINE_EVENT(btrfs__reserved_extent, btrfs_reserved_extent_free, - - TP_PROTO(struct btrfs_root *root, u64 start, u64 len), - - TP_ARGS(root, start, len) -); - -#endif /* _TRACE_BTRFS_H */ - -/* This part must be outside protection */ -#include diff --git a/trunk/ipc/util.c b/trunk/ipc/util.c index 5c0d28921ba8..8fd1b891ec0c 100644 --- a/trunk/ipc/util.c +++ b/trunk/ipc/util.c @@ -317,7 +317,6 @@ static int ipcget_new(struct ipc_namespace *ns, struct ipc_ids *ids, /** * ipc_check_perms - check security and permissions for an IPC - * @ns: IPC namespace * @ipcp: ipc permission set * @ops: the actual security routine to call * @params: its parameters @@ -608,7 +607,6 @@ void ipc_rcu_putref(void *ptr) /** * ipcperms - check IPC permissions - * @ns: IPC namespace * @ipcp: IPC permission set * @flag: desired permission set. * @@ -771,7 +769,7 @@ void ipc_update_perm(struct ipc64_perm *in, struct kern_ipc_perm *out) /** * ipcctl_pre_down - retrieve an ipc and check permissions for some IPC_XXX cmd - * @ns: the ipc namespace + * @ids: the ipc namespace * @ids: the table of ids where to look for the ipc * @id: the id of the ipc to retrieve * @cmd: the cmd to check diff --git a/trunk/kernel/irq/Kconfig b/trunk/kernel/irq/Kconfig index a69c333f78e4..00f2c037267a 100644 --- a/trunk/kernel/irq/Kconfig +++ b/trunk/kernel/irq/Kconfig @@ -10,6 +10,10 @@ menu "IRQ subsystem" config GENERIC_HARDIRQS def_bool y +# Select this to disable the deprecated stuff +config GENERIC_HARDIRQS_NO_DEPRECATED + bool + config GENERIC_HARDIRQS_NO_COMPAT bool @@ -47,10 +51,6 @@ config HARDIRQS_SW_RESEND config IRQ_PREFLOW_FASTEOI bool -# Edge style eoi based handler (cell) -config IRQ_EDGE_EOI_HANDLER - bool - # Support forced irq threading config IRQ_FORCED_THREADING bool diff --git a/trunk/kernel/irq/autoprobe.c b/trunk/kernel/irq/autoprobe.c index 342d8f44e401..394784c57060 100644 --- a/trunk/kernel/irq/autoprobe.c +++ b/trunk/kernel/irq/autoprobe.c @@ -70,8 +70,10 @@ unsigned long probe_irq_on(void) raw_spin_lock_irq(&desc->lock); if (!desc->action && irq_settings_can_probe(desc)) { desc->istate |= IRQS_AUTODETECT | IRQS_WAITING; - if (irq_startup(desc)) + if (irq_startup(desc)) { + irq_compat_set_pending(desc); desc->istate |= IRQS_PENDING; + } } raw_spin_unlock_irq(&desc->lock); } diff --git a/trunk/kernel/irq/chip.c b/trunk/kernel/irq/chip.c index 616ec1c6b06f..c9c0601f0615 100644 --- a/trunk/kernel/irq/chip.c +++ b/trunk/kernel/irq/chip.c @@ -34,14 +34,9 @@ int irq_set_chip(unsigned int irq, struct irq_chip *chip) if (!chip) chip = &no_irq_chip; + irq_chip_set_defaults(chip); desc->irq_data.chip = chip; irq_put_desc_unlock(desc, flags); - /* - * For !CONFIG_SPARSE_IRQ make the irq show up in - * allocated_irqs. For the CONFIG_SPARSE_IRQ case, it is - * already marked, and this call is harmless. - */ - irq_reserve_irq(irq); return 0; } EXPORT_SYMBOL(irq_set_chip); @@ -139,22 +134,26 @@ EXPORT_SYMBOL_GPL(irq_get_irq_data); static void irq_state_clr_disabled(struct irq_desc *desc) { - irqd_clear(&desc->irq_data, IRQD_IRQ_DISABLED); + desc->istate &= ~IRQS_DISABLED; + irq_compat_clr_disabled(desc); } static void irq_state_set_disabled(struct irq_desc *desc) { - irqd_set(&desc->irq_data, IRQD_IRQ_DISABLED); + desc->istate |= IRQS_DISABLED; + irq_compat_set_disabled(desc); } static void irq_state_clr_masked(struct irq_desc *desc) { - irqd_clear(&desc->irq_data, IRQD_IRQ_MASKED); + desc->istate &= ~IRQS_MASKED; + irq_compat_clr_masked(desc); } static void irq_state_set_masked(struct irq_desc *desc) { - irqd_set(&desc->irq_data, IRQD_IRQ_MASKED); + desc->istate |= IRQS_MASKED; + irq_compat_set_masked(desc); } int irq_startup(struct irq_desc *desc) @@ -204,6 +203,126 @@ void irq_disable(struct irq_desc *desc) } } +#ifndef CONFIG_GENERIC_HARDIRQS_NO_DEPRECATED +/* Temporary migration helpers */ +static void compat_irq_mask(struct irq_data *data) +{ + data->chip->mask(data->irq); +} + +static void compat_irq_unmask(struct irq_data *data) +{ + data->chip->unmask(data->irq); +} + +static void compat_irq_ack(struct irq_data *data) +{ + data->chip->ack(data->irq); +} + +static void compat_irq_mask_ack(struct irq_data *data) +{ + data->chip->mask_ack(data->irq); +} + +static void compat_irq_eoi(struct irq_data *data) +{ + data->chip->eoi(data->irq); +} + +static void compat_irq_enable(struct irq_data *data) +{ + data->chip->enable(data->irq); +} + +static void compat_irq_disable(struct irq_data *data) +{ + data->chip->disable(data->irq); +} + +static void compat_irq_shutdown(struct irq_data *data) +{ + data->chip->shutdown(data->irq); +} + +static unsigned int compat_irq_startup(struct irq_data *data) +{ + return data->chip->startup(data->irq); +} + +static int compat_irq_set_affinity(struct irq_data *data, + const struct cpumask *dest, bool force) +{ + return data->chip->set_affinity(data->irq, dest); +} + +static int compat_irq_set_type(struct irq_data *data, unsigned int type) +{ + return data->chip->set_type(data->irq, type); +} + +static int compat_irq_set_wake(struct irq_data *data, unsigned int on) +{ + return data->chip->set_wake(data->irq, on); +} + +static int compat_irq_retrigger(struct irq_data *data) +{ + return data->chip->retrigger(data->irq); +} + +static void compat_bus_lock(struct irq_data *data) +{ + data->chip->bus_lock(data->irq); +} + +static void compat_bus_sync_unlock(struct irq_data *data) +{ + data->chip->bus_sync_unlock(data->irq); +} +#endif + +/* + * Fixup enable/disable function pointers + */ +void irq_chip_set_defaults(struct irq_chip *chip) +{ +#ifndef CONFIG_GENERIC_HARDIRQS_NO_DEPRECATED + if (chip->enable) + chip->irq_enable = compat_irq_enable; + if (chip->disable) + chip->irq_disable = compat_irq_disable; + if (chip->shutdown) + chip->irq_shutdown = compat_irq_shutdown; + if (chip->startup) + chip->irq_startup = compat_irq_startup; + if (!chip->end) + chip->end = dummy_irq_chip.end; + if (chip->bus_lock) + chip->irq_bus_lock = compat_bus_lock; + if (chip->bus_sync_unlock) + chip->irq_bus_sync_unlock = compat_bus_sync_unlock; + if (chip->mask) + chip->irq_mask = compat_irq_mask; + if (chip->unmask) + chip->irq_unmask = compat_irq_unmask; + if (chip->ack) + chip->irq_ack = compat_irq_ack; + if (chip->mask_ack) + chip->irq_mask_ack = compat_irq_mask_ack; + if (chip->eoi) + chip->irq_eoi = compat_irq_eoi; + if (chip->set_affinity) + chip->irq_set_affinity = compat_irq_set_affinity; + if (chip->set_type) + chip->irq_set_type = compat_irq_set_type; + if (chip->set_wake) + chip->irq_set_wake = compat_irq_set_wake; + if (chip->retrigger) + chip->irq_retrigger = compat_irq_retrigger; +#endif +} + static inline void mask_ack_irq(struct irq_desc *desc) { if (desc->irq_data.chip->irq_mask_ack) @@ -253,10 +372,11 @@ void handle_nested_irq(unsigned int irq) kstat_incr_irqs_this_cpu(irq, desc); action = desc->action; - if (unlikely(!action || irqd_irq_disabled(&desc->irq_data))) + if (unlikely(!action || (desc->istate & IRQS_DISABLED))) goto out_unlock; - irqd_set(&desc->irq_data, IRQD_IRQ_INPROGRESS); + irq_compat_set_progress(desc); + desc->istate |= IRQS_INPROGRESS; raw_spin_unlock_irq(&desc->lock); action_ret = action->thread_fn(action->irq, action->dev_id); @@ -264,7 +384,8 @@ void handle_nested_irq(unsigned int irq) note_interrupt(irq, desc, action_ret); raw_spin_lock_irq(&desc->lock); - irqd_clear(&desc->irq_data, IRQD_IRQ_INPROGRESS); + desc->istate &= ~IRQS_INPROGRESS; + irq_compat_clr_progress(desc); out_unlock: raw_spin_unlock_irq(&desc->lock); @@ -295,14 +416,14 @@ handle_simple_irq(unsigned int irq, struct irq_desc *desc) { raw_spin_lock(&desc->lock); - if (unlikely(irqd_irq_inprogress(&desc->irq_data))) + if (unlikely(desc->istate & IRQS_INPROGRESS)) if (!irq_check_poll(desc)) goto out_unlock; desc->istate &= ~(IRQS_REPLAY | IRQS_WAITING); kstat_incr_irqs_this_cpu(irq, desc); - if (unlikely(!desc->action || irqd_irq_disabled(&desc->irq_data))) + if (unlikely(!desc->action || (desc->istate & IRQS_DISABLED))) goto out_unlock; handle_irq_event(desc); @@ -327,7 +448,7 @@ handle_level_irq(unsigned int irq, struct irq_desc *desc) raw_spin_lock(&desc->lock); mask_ack_irq(desc); - if (unlikely(irqd_irq_inprogress(&desc->irq_data))) + if (unlikely(desc->istate & IRQS_INPROGRESS)) if (!irq_check_poll(desc)) goto out_unlock; @@ -338,12 +459,12 @@ handle_level_irq(unsigned int irq, struct irq_desc *desc) * If its disabled or no action available * keep it masked and get out of here */ - if (unlikely(!desc->action || irqd_irq_disabled(&desc->irq_data))) + if (unlikely(!desc->action || (desc->istate & IRQS_DISABLED))) goto out_unlock; handle_irq_event(desc); - if (!irqd_irq_disabled(&desc->irq_data) && !(desc->istate & IRQS_ONESHOT)) + if (!(desc->istate & (IRQS_DISABLED | IRQS_ONESHOT))) unmask_irq(desc); out_unlock: raw_spin_unlock(&desc->lock); @@ -375,7 +496,7 @@ handle_fasteoi_irq(unsigned int irq, struct irq_desc *desc) { raw_spin_lock(&desc->lock); - if (unlikely(irqd_irq_inprogress(&desc->irq_data))) + if (unlikely(desc->istate & IRQS_INPROGRESS)) if (!irq_check_poll(desc)) goto out; @@ -386,7 +507,8 @@ handle_fasteoi_irq(unsigned int irq, struct irq_desc *desc) * If its disabled or no action available * then mask it and get out of here: */ - if (unlikely(!desc->action || irqd_irq_disabled(&desc->irq_data))) { + if (unlikely(!desc->action || (desc->istate & IRQS_DISABLED))) { + irq_compat_set_pending(desc); desc->istate |= IRQS_PENDING; mask_irq(desc); goto out; @@ -436,9 +558,10 @@ handle_edge_irq(unsigned int irq, struct irq_desc *desc) * we shouldn't process the IRQ. Mark it pending, handle * the necessary masking and go out */ - if (unlikely(irqd_irq_disabled(&desc->irq_data) || - irqd_irq_inprogress(&desc->irq_data) || !desc->action)) { + if (unlikely((desc->istate & (IRQS_DISABLED | IRQS_INPROGRESS) || + !desc->action))) { if (!irq_check_poll(desc)) { + irq_compat_set_pending(desc); desc->istate |= IRQS_PENDING; mask_ack_irq(desc); goto out_unlock; @@ -461,65 +584,20 @@ handle_edge_irq(unsigned int irq, struct irq_desc *desc) * Renable it, if it was not disabled in meantime. */ if (unlikely(desc->istate & IRQS_PENDING)) { - if (!irqd_irq_disabled(&desc->irq_data) && - irqd_irq_masked(&desc->irq_data)) + if (!(desc->istate & IRQS_DISABLED) && + (desc->istate & IRQS_MASKED)) unmask_irq(desc); } handle_irq_event(desc); } while ((desc->istate & IRQS_PENDING) && - !irqd_irq_disabled(&desc->irq_data)); + !(desc->istate & IRQS_DISABLED)); out_unlock: raw_spin_unlock(&desc->lock); } -#ifdef CONFIG_IRQ_EDGE_EOI_HANDLER -/** - * handle_edge_eoi_irq - edge eoi type IRQ handler - * @irq: the interrupt number - * @desc: the interrupt description structure for this irq - * - * Similar as the above handle_edge_irq, but using eoi and w/o the - * mask/unmask logic. - */ -void handle_edge_eoi_irq(unsigned int irq, struct irq_desc *desc) -{ - struct irq_chip *chip = irq_desc_get_chip(desc); - - raw_spin_lock(&desc->lock); - - desc->istate &= ~(IRQS_REPLAY | IRQS_WAITING); - /* - * If we're currently running this IRQ, or its disabled, - * we shouldn't process the IRQ. Mark it pending, handle - * the necessary masking and go out - */ - if (unlikely(irqd_irq_disabled(&desc->irq_data) || - irqd_irq_inprogress(&desc->irq_data) || !desc->action)) { - if (!irq_check_poll(desc)) { - desc->istate |= IRQS_PENDING; - goto out_eoi; - } - } - kstat_incr_irqs_this_cpu(irq, desc); - - do { - if (unlikely(!desc->action)) - goto out_eoi; - - handle_irq_event(desc); - - } while ((desc->istate & IRQS_PENDING) && - !irqd_irq_disabled(&desc->irq_data)); - -out_unlock: - chip->irq_eoi(&desc->irq_data); - raw_spin_unlock(&desc->lock); -} -#endif - /** * handle_percpu_irq - Per CPU local irq handler * @irq: the interrupt number @@ -564,7 +642,8 @@ __irq_set_handler(unsigned int irq, irq_flow_handler_t handle, int is_chained, if (handle == handle_bad_irq) { if (desc->irq_data.chip != &no_irq_chip) mask_ack_irq(desc); - irq_state_set_disabled(desc); + irq_compat_set_disabled(desc); + desc->istate |= IRQS_DISABLED; desc->depth = 1; } desc->handle_irq = handle; @@ -605,70 +684,8 @@ void irq_modify_status(unsigned int irq, unsigned long clr, unsigned long set) irqd_set(&desc->irq_data, IRQD_PER_CPU); if (irq_settings_can_move_pcntxt(desc)) irqd_set(&desc->irq_data, IRQD_MOVE_PCNTXT); - if (irq_settings_is_level(desc)) - irqd_set(&desc->irq_data, IRQD_LEVEL); irqd_set(&desc->irq_data, irq_settings_get_trigger_mask(desc)); irq_put_desc_unlock(desc, flags); } - -/** - * irq_cpu_online - Invoke all irq_cpu_online functions. - * - * Iterate through all irqs and invoke the chip.irq_cpu_online() - * for each. - */ -void irq_cpu_online(void) -{ - struct irq_desc *desc; - struct irq_chip *chip; - unsigned long flags; - unsigned int irq; - - for_each_active_irq(irq) { - desc = irq_to_desc(irq); - if (!desc) - continue; - - raw_spin_lock_irqsave(&desc->lock, flags); - - chip = irq_data_get_irq_chip(&desc->irq_data); - if (chip && chip->irq_cpu_online && - (!(chip->flags & IRQCHIP_ONOFFLINE_ENABLED) || - !irqd_irq_disabled(&desc->irq_data))) - chip->irq_cpu_online(&desc->irq_data); - - raw_spin_unlock_irqrestore(&desc->lock, flags); - } -} - -/** - * irq_cpu_offline - Invoke all irq_cpu_offline functions. - * - * Iterate through all irqs and invoke the chip.irq_cpu_offline() - * for each. - */ -void irq_cpu_offline(void) -{ - struct irq_desc *desc; - struct irq_chip *chip; - unsigned long flags; - unsigned int irq; - - for_each_active_irq(irq) { - desc = irq_to_desc(irq); - if (!desc) - continue; - - raw_spin_lock_irqsave(&desc->lock, flags); - - chip = irq_data_get_irq_chip(&desc->irq_data); - if (chip && chip->irq_cpu_offline && - (!(chip->flags & IRQCHIP_ONOFFLINE_ENABLED) || - !irqd_irq_disabled(&desc->irq_data))) - chip->irq_cpu_offline(&desc->irq_data); - - raw_spin_unlock_irqrestore(&desc->lock, flags); - } -} diff --git a/trunk/kernel/irq/compat.h b/trunk/kernel/irq/compat.h new file mode 100644 index 000000000000..6bbaf66aca85 --- /dev/null +++ b/trunk/kernel/irq/compat.h @@ -0,0 +1,72 @@ +/* + * Compat layer for transition period + */ +#ifndef CONFIG_GENERIC_HARDIRQS_NO_COMPAT +static inline void irq_compat_set_progress(struct irq_desc *desc) +{ + desc->status |= IRQ_INPROGRESS; +} + +static inline void irq_compat_clr_progress(struct irq_desc *desc) +{ + desc->status &= ~IRQ_INPROGRESS; +} +static inline void irq_compat_set_disabled(struct irq_desc *desc) +{ + desc->status |= IRQ_DISABLED; +} +static inline void irq_compat_clr_disabled(struct irq_desc *desc) +{ + desc->status &= ~IRQ_DISABLED; +} +static inline void irq_compat_set_pending(struct irq_desc *desc) +{ + desc->status |= IRQ_PENDING; +} + +static inline void irq_compat_clr_pending(struct irq_desc *desc) +{ + desc->status &= ~IRQ_PENDING; +} +static inline void irq_compat_set_masked(struct irq_desc *desc) +{ + desc->status |= IRQ_MASKED; +} + +static inline void irq_compat_clr_masked(struct irq_desc *desc) +{ + desc->status &= ~IRQ_MASKED; +} +static inline void irq_compat_set_move_pending(struct irq_desc *desc) +{ + desc->status |= IRQ_MOVE_PENDING; +} + +static inline void irq_compat_clr_move_pending(struct irq_desc *desc) +{ + desc->status &= ~IRQ_MOVE_PENDING; +} +static inline void irq_compat_set_affinity(struct irq_desc *desc) +{ + desc->status |= IRQ_AFFINITY_SET; +} + +static inline void irq_compat_clr_affinity(struct irq_desc *desc) +{ + desc->status &= ~IRQ_AFFINITY_SET; +} +#else +static inline void irq_compat_set_progress(struct irq_desc *desc) { } +static inline void irq_compat_clr_progress(struct irq_desc *desc) { } +static inline void irq_compat_set_disabled(struct irq_desc *desc) { } +static inline void irq_compat_clr_disabled(struct irq_desc *desc) { } +static inline void irq_compat_set_pending(struct irq_desc *desc) { } +static inline void irq_compat_clr_pending(struct irq_desc *desc) { } +static inline void irq_compat_set_masked(struct irq_desc *desc) { } +static inline void irq_compat_clr_masked(struct irq_desc *desc) { } +static inline void irq_compat_set_move_pending(struct irq_desc *desc) { } +static inline void irq_compat_clr_move_pending(struct irq_desc *desc) { } +static inline void irq_compat_set_affinity(struct irq_desc *desc) { } +static inline void irq_compat_clr_affinity(struct irq_desc *desc) { } +#endif + diff --git a/trunk/kernel/irq/debug.h b/trunk/kernel/irq/debug.h index 306cba37e9a5..d1a33b7fa61d 100644 --- a/trunk/kernel/irq/debug.h +++ b/trunk/kernel/irq/debug.h @@ -4,10 +4,8 @@ #include -#define P(f) if (desc->status_use_accessors & f) printk("%14s set\n", #f) +#define P(f) if (desc->status & f) printk("%14s set\n", #f) #define PS(f) if (desc->istate & f) printk("%14s set\n", #f) -/* FIXME */ -#define PD(f) do { } while (0) static inline void print_irq_desc(unsigned int irq, struct irq_desc *desc) { @@ -30,15 +28,13 @@ static inline void print_irq_desc(unsigned int irq, struct irq_desc *desc) P(IRQ_NOAUTOEN); PS(IRQS_AUTODETECT); + PS(IRQS_INPROGRESS); PS(IRQS_REPLAY); PS(IRQS_WAITING); + PS(IRQS_DISABLED); PS(IRQS_PENDING); - - PD(IRQS_INPROGRESS); - PD(IRQS_DISABLED); - PD(IRQS_MASKED); + PS(IRQS_MASKED); } #undef P #undef PS -#undef PD diff --git a/trunk/kernel/irq/dummychip.c b/trunk/kernel/irq/dummychip.c index b5fcd96c7102..20dc5474947e 100644 --- a/trunk/kernel/irq/dummychip.c +++ b/trunk/kernel/irq/dummychip.c @@ -31,6 +31,13 @@ static unsigned int noop_ret(struct irq_data *data) return 0; } +#ifndef CONFIG_GENERIC_HARDIRQS_NO_DEPRECATED +static void compat_noop(unsigned int irq) { } +#define END_INIT .end = compat_noop +#else +#define END_INIT +#endif + /* * Generic no controller implementation */ @@ -41,6 +48,7 @@ struct irq_chip no_irq_chip = { .irq_enable = noop, .irq_disable = noop, .irq_ack = ack_bad, + END_INIT }; /* @@ -56,4 +64,5 @@ struct irq_chip dummy_irq_chip = { .irq_ack = noop, .irq_mask = noop, .irq_unmask = noop, + END_INIT }; diff --git a/trunk/kernel/irq/handle.c b/trunk/kernel/irq/handle.c index 90cb55f6d7eb..517561fc7317 100644 --- a/trunk/kernel/irq/handle.c +++ b/trunk/kernel/irq/handle.c @@ -175,13 +175,28 @@ irqreturn_t handle_irq_event(struct irq_desc *desc) struct irqaction *action = desc->action; irqreturn_t ret; + irq_compat_clr_pending(desc); desc->istate &= ~IRQS_PENDING; - irqd_set(&desc->irq_data, IRQD_IRQ_INPROGRESS); + irq_compat_set_progress(desc); + desc->istate |= IRQS_INPROGRESS; raw_spin_unlock(&desc->lock); ret = handle_irq_event_percpu(desc, action); raw_spin_lock(&desc->lock); - irqd_clear(&desc->irq_data, IRQD_IRQ_INPROGRESS); + desc->istate &= ~IRQS_INPROGRESS; + irq_compat_clr_progress(desc); return ret; } + +/** + * handle_IRQ_event - irq action chain handler + * @irq: the interrupt number + * @action: the interrupt action chain for this irq + * + * Handles the action chain of an irq event + */ +irqreturn_t handle_IRQ_event(unsigned int irq, struct irqaction *action) +{ + return handle_irq_event_percpu(irq_to_desc(irq), action); +} diff --git a/trunk/kernel/irq/internals.h b/trunk/kernel/irq/internals.h index 6546431447d7..6c6ec9a49027 100644 --- a/trunk/kernel/irq/internals.h +++ b/trunk/kernel/irq/internals.h @@ -15,6 +15,10 @@ #define istate core_internal_state__do_not_mess_with_it +#ifdef CONFIG_GENERIC_HARDIRQS_NO_COMPAT +# define status status_use_accessors +#endif + extern int noirqdebug; /* @@ -40,28 +44,38 @@ enum { * IRQS_SPURIOUS_DISABLED - was disabled due to spurious interrupt * detection * IRQS_POLL_INPROGRESS - polling in progress + * IRQS_INPROGRESS - Interrupt in progress * IRQS_ONESHOT - irq is not unmasked in primary handler * IRQS_REPLAY - irq is replayed * IRQS_WAITING - irq is waiting + * IRQS_DISABLED - irq is disabled * IRQS_PENDING - irq is pending and replayed later + * IRQS_MASKED - irq is masked * IRQS_SUSPENDED - irq is suspended */ enum { IRQS_AUTODETECT = 0x00000001, IRQS_SPURIOUS_DISABLED = 0x00000002, IRQS_POLL_INPROGRESS = 0x00000008, + IRQS_INPROGRESS = 0x00000010, IRQS_ONESHOT = 0x00000020, IRQS_REPLAY = 0x00000040, IRQS_WAITING = 0x00000080, + IRQS_DISABLED = 0x00000100, IRQS_PENDING = 0x00000200, + IRQS_MASKED = 0x00000400, IRQS_SUSPENDED = 0x00000800, }; +#include "compat.h" #include "debug.h" #include "settings.h" #define irq_data_to_desc(data) container_of(data, struct irq_desc, irq_data) +/* Set default functions for irq_chip structures: */ +extern void irq_chip_set_defaults(struct irq_chip *chip); + extern int __irq_set_trigger(struct irq_desc *desc, unsigned int irq, unsigned long flags); extern void __disable_irq(struct irq_desc *desc, unsigned int irq, bool susp); @@ -148,11 +162,13 @@ irq_put_desc_unlock(struct irq_desc *desc, unsigned long flags) static inline void irqd_set_move_pending(struct irq_data *d) { d->state_use_accessors |= IRQD_SETAFFINITY_PENDING; + irq_compat_set_move_pending(irq_data_to_desc(d)); } static inline void irqd_clr_move_pending(struct irq_data *d) { d->state_use_accessors &= ~IRQD_SETAFFINITY_PENDING; + irq_compat_clr_move_pending(irq_data_to_desc(d)); } static inline void irqd_clear(struct irq_data *d, unsigned int mask) diff --git a/trunk/kernel/irq/irqdesc.c b/trunk/kernel/irq/irqdesc.c index 2c039c9b9383..6fb014f172f7 100644 --- a/trunk/kernel/irq/irqdesc.c +++ b/trunk/kernel/irq/irqdesc.c @@ -80,7 +80,7 @@ static void desc_set_defaults(unsigned int irq, struct irq_desc *desc, int node) desc->irq_data.handler_data = NULL; desc->irq_data.msi_desc = NULL; irq_settings_clr_and_set(desc, ~0, _IRQ_DEFAULT_INIT_FLAGS); - irqd_set(&desc->irq_data, IRQD_IRQ_DISABLED); + desc->istate = IRQS_DISABLED; desc->handle_irq = handle_bad_irq; desc->depth = 1; desc->irq_count = 0; @@ -238,6 +238,7 @@ int __init early_irq_init(void) struct irq_desc irq_desc[NR_IRQS] __cacheline_aligned_in_smp = { [0 ... NR_IRQS-1] = { + .istate = IRQS_DISABLED, .handle_irq = handle_bad_irq, .depth = 1, .lock = __RAW_SPIN_LOCK_UNLOCKED(irq_desc->lock), diff --git a/trunk/kernel/irq/manage.c b/trunk/kernel/irq/manage.c index 12a80fdae11c..0a2aa73e536c 100644 --- a/trunk/kernel/irq/manage.c +++ b/trunk/kernel/irq/manage.c @@ -41,7 +41,7 @@ early_param("threadirqs", setup_forced_irqthreads); void synchronize_irq(unsigned int irq) { struct irq_desc *desc = irq_to_desc(irq); - bool inprogress; + unsigned int state; if (!desc) return; @@ -53,16 +53,16 @@ void synchronize_irq(unsigned int irq) * Wait until we're out of the critical section. This might * give the wrong answer due to the lack of memory barriers. */ - while (irqd_irq_inprogress(&desc->irq_data)) + while (desc->istate & IRQS_INPROGRESS) cpu_relax(); /* Ok, that indicated we're done: double-check carefully. */ raw_spin_lock_irqsave(&desc->lock, flags); - inprogress = irqd_irq_inprogress(&desc->irq_data); + state = desc->istate; raw_spin_unlock_irqrestore(&desc->lock, flags); /* Oops, that failed? */ - } while (inprogress); + } while (state & IRQS_INPROGRESS); /* * We made sure that no hardirq handler is running. Now verify @@ -112,13 +112,13 @@ void irq_set_thread_affinity(struct irq_desc *desc) } #ifdef CONFIG_GENERIC_PENDING_IRQ -static inline bool irq_can_move_pcntxt(struct irq_data *data) +static inline bool irq_can_move_pcntxt(struct irq_desc *desc) { - return irqd_can_move_in_process_context(data); + return irq_settings_can_move_pcntxt(desc); } -static inline bool irq_move_pending(struct irq_data *data) +static inline bool irq_move_pending(struct irq_desc *desc) { - return irqd_is_setaffinity_pending(data); + return irqd_is_setaffinity_pending(&desc->irq_data); } static inline void irq_copy_pending(struct irq_desc *desc, const struct cpumask *mask) @@ -131,34 +131,43 @@ irq_get_pending(struct cpumask *mask, struct irq_desc *desc) cpumask_copy(mask, desc->pending_mask); } #else -static inline bool irq_can_move_pcntxt(struct irq_data *data) { return true; } -static inline bool irq_move_pending(struct irq_data *data) { return false; } +static inline bool irq_can_move_pcntxt(struct irq_desc *desc) { return true; } +static inline bool irq_move_pending(struct irq_desc *desc) { return false; } static inline void irq_copy_pending(struct irq_desc *desc, const struct cpumask *mask) { } static inline void irq_get_pending(struct cpumask *mask, struct irq_desc *desc) { } #endif -int __irq_set_affinity_locked(struct irq_data *data, const struct cpumask *mask) +/** + * irq_set_affinity - Set the irq affinity of a given irq + * @irq: Interrupt to set affinity + * @cpumask: cpumask + * + */ +int irq_set_affinity(unsigned int irq, const struct cpumask *mask) { - struct irq_chip *chip = irq_data_get_irq_chip(data); - struct irq_desc *desc = irq_data_to_desc(data); + struct irq_desc *desc = irq_to_desc(irq); + struct irq_chip *chip = desc->irq_data.chip; + unsigned long flags; int ret = 0; - if (!chip || !chip->irq_set_affinity) + if (!chip->irq_set_affinity) return -EINVAL; - if (irq_can_move_pcntxt(data)) { - ret = chip->irq_set_affinity(data, mask, false); + raw_spin_lock_irqsave(&desc->lock, flags); + + if (irq_can_move_pcntxt(desc)) { + ret = chip->irq_set_affinity(&desc->irq_data, mask, false); switch (ret) { case IRQ_SET_MASK_OK: - cpumask_copy(data->affinity, mask); + cpumask_copy(desc->irq_data.affinity, mask); case IRQ_SET_MASK_OK_NOCOPY: irq_set_thread_affinity(desc); ret = 0; } } else { - irqd_set_move_pending(data); + irqd_set_move_pending(&desc->irq_data); irq_copy_pending(desc, mask); } @@ -166,28 +175,8 @@ int __irq_set_affinity_locked(struct irq_data *data, const struct cpumask *mask) kref_get(&desc->affinity_notify->kref); schedule_work(&desc->affinity_notify->work); } - irqd_set(data, IRQD_AFFINITY_SET); - - return ret; -} - -/** - * irq_set_affinity - Set the irq affinity of a given irq - * @irq: Interrupt to set affinity - * @mask: cpumask - * - */ -int irq_set_affinity(unsigned int irq, const struct cpumask *mask) -{ - struct irq_desc *desc = irq_to_desc(irq); - unsigned long flags; - int ret; - - if (!desc) - return -EINVAL; - - raw_spin_lock_irqsave(&desc->lock, flags); - ret = __irq_set_affinity_locked(irq_desc_get_irq_data(desc), mask); + irq_compat_set_affinity(desc); + irqd_set(&desc->irq_data, IRQD_AFFINITY_SET); raw_spin_unlock_irqrestore(&desc->lock, flags); return ret; } @@ -217,7 +206,7 @@ static void irq_affinity_notify(struct work_struct *work) goto out; raw_spin_lock_irqsave(&desc->lock, flags); - if (irq_move_pending(&desc->irq_data)) + if (irq_move_pending(desc)) irq_get_pending(cpumask, desc); else cpumask_copy(cpumask, desc->irq_data.affinity); @@ -296,8 +285,10 @@ setup_affinity(unsigned int irq, struct irq_desc *desc, struct cpumask *mask) if (cpumask_intersects(desc->irq_data.affinity, cpu_online_mask)) set = desc->irq_data.affinity; - else + else { + irq_compat_clr_affinity(desc); irqd_clear(&desc->irq_data, IRQD_AFFINITY_SET); + } } cpumask_and(mask, cpu_online_mask, set); @@ -560,9 +551,9 @@ int __irq_set_trigger(struct irq_desc *desc, unsigned int irq, flags &= IRQ_TYPE_SENSE_MASK; if (chip->flags & IRQCHIP_SET_TYPE_MASKED) { - if (!irqd_irq_masked(&desc->irq_data)) + if (!(desc->istate & IRQS_MASKED)) mask_irq(desc); - if (!irqd_irq_disabled(&desc->irq_data)) + if (!(desc->istate & IRQS_DISABLED)) unmask = 1; } @@ -584,6 +575,8 @@ int __irq_set_trigger(struct irq_desc *desc, unsigned int irq, irqd_set(&desc->irq_data, IRQD_LEVEL); } + if (chip != desc->irq_data.chip) + irq_chip_set_defaults(desc->irq_data.chip); ret = 0; break; default: @@ -658,7 +651,7 @@ static void irq_finalize_oneshot(struct irq_desc *desc, * irq_wake_thread(). See the comment there which explains the * serialization. */ - if (unlikely(irqd_irq_inprogress(&desc->irq_data))) { + if (unlikely(desc->istate & IRQS_INPROGRESS)) { raw_spin_unlock_irq(&desc->lock); chip_bus_sync_unlock(desc); cpu_relax(); @@ -675,10 +668,12 @@ static void irq_finalize_oneshot(struct irq_desc *desc, desc->threads_oneshot &= ~action->thread_mask; - if (!desc->threads_oneshot && !irqd_irq_disabled(&desc->irq_data) && - irqd_irq_masked(&desc->irq_data)) - unmask_irq(desc); - + if (!desc->threads_oneshot && !(desc->istate & IRQS_DISABLED) && + (desc->istate & IRQS_MASKED)) { + irq_compat_clr_masked(desc); + desc->istate &= ~IRQS_MASKED; + desc->irq_data.chip->irq_unmask(&desc->irq_data); + } out_unlock: raw_spin_unlock_irq(&desc->lock); chip_bus_sync_unlock(desc); @@ -772,7 +767,7 @@ static int irq_thread(void *data) atomic_inc(&desc->threads_active); raw_spin_lock_irq(&desc->lock); - if (unlikely(irqd_irq_disabled(&desc->irq_data))) { + if (unlikely(desc->istate & IRQS_DISABLED)) { /* * CHECKME: We might need a dedicated * IRQ_THREAD_PENDING flag here, which @@ -780,6 +775,7 @@ static int irq_thread(void *data) * but AFAICT IRQS_PENDING should be fine as it * retriggers the interrupt itself --- tglx */ + irq_compat_set_pending(desc); desc->istate |= IRQS_PENDING; raw_spin_unlock_irq(&desc->lock); } else { @@ -975,6 +971,8 @@ __setup_irq(unsigned int irq, struct irq_desc *desc, struct irqaction *new) new->thread_mask = 1 << ffz(thread_mask); if (!shared) { + irq_chip_set_defaults(desc->irq_data.chip); + init_waitqueue_head(&desc->wait_for_threads); /* Setup the type (level, edge polarity) if configured: */ @@ -987,8 +985,8 @@ __setup_irq(unsigned int irq, struct irq_desc *desc, struct irqaction *new) } desc->istate &= ~(IRQS_AUTODETECT | IRQS_SPURIOUS_DISABLED | \ - IRQS_ONESHOT | IRQS_WAITING); - irqd_clear(&desc->irq_data, IRQD_IRQ_INPROGRESS); + IRQS_INPROGRESS | IRQS_ONESHOT | \ + IRQS_WAITING); if (new->flags & IRQF_PERCPU) { irqd_set(&desc->irq_data, IRQD_PER_CPU); diff --git a/trunk/kernel/irq/migration.c b/trunk/kernel/irq/migration.c index bc6194698dfd..ec4806d4778b 100644 --- a/trunk/kernel/irq/migration.c +++ b/trunk/kernel/irq/migration.c @@ -53,14 +53,20 @@ void irq_move_masked_irq(struct irq_data *idata) cpumask_clear(desc->pending_mask); } +void move_masked_irq(int irq) +{ + irq_move_masked_irq(irq_get_irq_data(irq)); +} + void irq_move_irq(struct irq_data *idata) { + struct irq_desc *desc = irq_data_to_desc(idata); bool masked; if (likely(!irqd_is_setaffinity_pending(idata))) return; - if (unlikely(irqd_irq_disabled(idata))) + if (unlikely(desc->istate & IRQS_DISABLED)) return; /* @@ -68,10 +74,15 @@ void irq_move_irq(struct irq_data *idata) * threaded interrupt with ONESHOT set, we can end up with an * interrupt storm. */ - masked = irqd_irq_masked(idata); + masked = desc->istate & IRQS_MASKED; if (!masked) idata->chip->irq_mask(idata); irq_move_masked_irq(idata); if (!masked) idata->chip->irq_unmask(idata); } + +void move_native_irq(int irq) +{ + irq_move_irq(irq_get_irq_data(irq)); +} diff --git a/trunk/kernel/irq/proc.c b/trunk/kernel/irq/proc.c index dd201bd35103..626d092eed9a 100644 --- a/trunk/kernel/irq/proc.c +++ b/trunk/kernel/irq/proc.c @@ -364,10 +364,6 @@ int __weak arch_show_interrupts(struct seq_file *p, int prec) return 0; } -#ifndef ACTUAL_NR_IRQS -# define ACTUAL_NR_IRQS nr_irqs -#endif - int show_interrupts(struct seq_file *p, void *v) { static int prec; @@ -377,10 +373,10 @@ int show_interrupts(struct seq_file *p, void *v) struct irqaction *action; struct irq_desc *desc; - if (i > ACTUAL_NR_IRQS) + if (i > nr_irqs) return 0; - if (i == ACTUAL_NR_IRQS) + if (i == nr_irqs) return arch_show_interrupts(p, prec); /* print header and calculate the width of the first column */ diff --git a/trunk/kernel/irq/resend.c b/trunk/kernel/irq/resend.c index 14dd5761e8c9..ad683a99b1ec 100644 --- a/trunk/kernel/irq/resend.c +++ b/trunk/kernel/irq/resend.c @@ -65,6 +65,7 @@ void check_irq_resend(struct irq_desc *desc, unsigned int irq) if (desc->istate & IRQS_REPLAY) return; if (desc->istate & IRQS_PENDING) { + irq_compat_clr_pending(desc); desc->istate &= ~IRQS_PENDING; desc->istate |= IRQS_REPLAY; diff --git a/trunk/kernel/irq/settings.h b/trunk/kernel/irq/settings.h index 0d91730b6330..0227ad358272 100644 --- a/trunk/kernel/irq/settings.h +++ b/trunk/kernel/irq/settings.h @@ -15,8 +15,17 @@ enum { _IRQF_MODIFY_MASK = IRQF_MODIFY_MASK, }; +#define IRQ_INPROGRESS GOT_YOU_MORON +#define IRQ_REPLAY GOT_YOU_MORON +#define IRQ_WAITING GOT_YOU_MORON +#define IRQ_DISABLED GOT_YOU_MORON +#define IRQ_PENDING GOT_YOU_MORON +#define IRQ_MASKED GOT_YOU_MORON +#define IRQ_WAKEUP GOT_YOU_MORON +#define IRQ_MOVE_PENDING GOT_YOU_MORON #define IRQ_PER_CPU GOT_YOU_MORON #define IRQ_NO_BALANCING GOT_YOU_MORON +#define IRQ_AFFINITY_SET GOT_YOU_MORON #define IRQ_LEVEL GOT_YOU_MORON #define IRQ_NOPROBE GOT_YOU_MORON #define IRQ_NOREQUEST GOT_YOU_MORON @@ -28,98 +37,102 @@ enum { static inline void irq_settings_clr_and_set(struct irq_desc *desc, u32 clr, u32 set) { - desc->status_use_accessors &= ~(clr & _IRQF_MODIFY_MASK); - desc->status_use_accessors |= (set & _IRQF_MODIFY_MASK); + desc->status &= ~(clr & _IRQF_MODIFY_MASK); + desc->status |= (set & _IRQF_MODIFY_MASK); } static inline bool irq_settings_is_per_cpu(struct irq_desc *desc) { - return desc->status_use_accessors & _IRQ_PER_CPU; + return desc->status & _IRQ_PER_CPU; } static inline void irq_settings_set_per_cpu(struct irq_desc *desc) { - desc->status_use_accessors |= _IRQ_PER_CPU; + desc->status |= _IRQ_PER_CPU; } static inline void irq_settings_set_no_balancing(struct irq_desc *desc) { - desc->status_use_accessors |= _IRQ_NO_BALANCING; + desc->status |= _IRQ_NO_BALANCING; } static inline bool irq_settings_has_no_balance_set(struct irq_desc *desc) { - return desc->status_use_accessors & _IRQ_NO_BALANCING; + return desc->status & _IRQ_NO_BALANCING; } static inline u32 irq_settings_get_trigger_mask(struct irq_desc *desc) { - return desc->status_use_accessors & IRQ_TYPE_SENSE_MASK; + return desc->status & IRQ_TYPE_SENSE_MASK; } static inline void irq_settings_set_trigger_mask(struct irq_desc *desc, u32 mask) { - desc->status_use_accessors &= ~IRQ_TYPE_SENSE_MASK; - desc->status_use_accessors |= mask & IRQ_TYPE_SENSE_MASK; + desc->status &= ~IRQ_TYPE_SENSE_MASK; + desc->status |= mask & IRQ_TYPE_SENSE_MASK; } static inline bool irq_settings_is_level(struct irq_desc *desc) { - return desc->status_use_accessors & _IRQ_LEVEL; + return desc->status & _IRQ_LEVEL; } static inline void irq_settings_clr_level(struct irq_desc *desc) { - desc->status_use_accessors &= ~_IRQ_LEVEL; + desc->status &= ~_IRQ_LEVEL; } static inline void irq_settings_set_level(struct irq_desc *desc) { - desc->status_use_accessors |= _IRQ_LEVEL; + desc->status |= _IRQ_LEVEL; } static inline bool irq_settings_can_request(struct irq_desc *desc) { - return !(desc->status_use_accessors & _IRQ_NOREQUEST); + return !(desc->status & _IRQ_NOREQUEST); } static inline void irq_settings_clr_norequest(struct irq_desc *desc) { - desc->status_use_accessors &= ~_IRQ_NOREQUEST; + desc->status &= ~_IRQ_NOREQUEST; } static inline void irq_settings_set_norequest(struct irq_desc *desc) { - desc->status_use_accessors |= _IRQ_NOREQUEST; + desc->status |= _IRQ_NOREQUEST; } static inline bool irq_settings_can_probe(struct irq_desc *desc) { - return !(desc->status_use_accessors & _IRQ_NOPROBE); + return !(desc->status & _IRQ_NOPROBE); } static inline void irq_settings_clr_noprobe(struct irq_desc *desc) { - desc->status_use_accessors &= ~_IRQ_NOPROBE; + desc->status &= ~_IRQ_NOPROBE; } static inline void irq_settings_set_noprobe(struct irq_desc *desc) { - desc->status_use_accessors |= _IRQ_NOPROBE; + desc->status |= _IRQ_NOPROBE; } static inline bool irq_settings_can_move_pcntxt(struct irq_desc *desc) { - return desc->status_use_accessors & _IRQ_MOVE_PCNTXT; + return desc->status & _IRQ_MOVE_PCNTXT; } static inline bool irq_settings_can_autoenable(struct irq_desc *desc) { - return !(desc->status_use_accessors & _IRQ_NOAUTOEN); + return !(desc->status & _IRQ_NOAUTOEN); } static inline bool irq_settings_is_nested_thread(struct irq_desc *desc) { - return desc->status_use_accessors & _IRQ_NESTED_THREAD; + return desc->status & _IRQ_NESTED_THREAD; } + +/* Nothing should touch desc->status from now on */ +#undef status +#define status USE_THE_PROPER_WRAPPERS_YOU_MORON diff --git a/trunk/kernel/irq/spurious.c b/trunk/kernel/irq/spurious.c index dfbd550401b2..dd586ebf9c8c 100644 --- a/trunk/kernel/irq/spurious.c +++ b/trunk/kernel/irq/spurious.c @@ -45,12 +45,12 @@ bool irq_wait_for_poll(struct irq_desc *desc) #ifdef CONFIG_SMP do { raw_spin_unlock(&desc->lock); - while (irqd_irq_inprogress(&desc->irq_data)) + while (desc->istate & IRQS_INPROGRESS) cpu_relax(); raw_spin_lock(&desc->lock); - } while (irqd_irq_inprogress(&desc->irq_data)); + } while (desc->istate & IRQS_INPROGRESS); /* Might have been disabled in meantime */ - return !irqd_irq_disabled(&desc->irq_data) && desc->action; + return !(desc->istate & IRQS_DISABLED) && desc->action; #else return false; #endif @@ -75,7 +75,7 @@ static int try_one_irq(int irq, struct irq_desc *desc, bool force) * Do not poll disabled interrupts unless the spurious * disabled poller asks explicitely. */ - if (irqd_irq_disabled(&desc->irq_data) && !force) + if ((desc->istate & IRQS_DISABLED) && !force) goto out; /* @@ -88,11 +88,12 @@ static int try_one_irq(int irq, struct irq_desc *desc, bool force) goto out; /* Already running on another processor */ - if (irqd_irq_inprogress(&desc->irq_data)) { + if (desc->istate & IRQS_INPROGRESS) { /* * Already running: If it is shared get the other * CPU to go looking for our mystery interrupt too */ + irq_compat_set_pending(desc); desc->istate |= IRQS_PENDING; goto out; } diff --git a/trunk/kernel/signal.c b/trunk/kernel/signal.c index 1186cf7fac77..324eff5468ad 100644 --- a/trunk/kernel/signal.c +++ b/trunk/kernel/signal.c @@ -2437,7 +2437,7 @@ SYSCALL_DEFINE3(rt_sigqueueinfo, pid_t, pid, int, sig, /* Not even root can pretend to send signals from the kernel. * Nor can they impersonate a kill()/tgkill(), which adds source info. */ - if (info.si_code >= 0 || info.si_code == SI_TKILL) { + if (info.si_code != SI_QUEUE) { /* We used to allow any < 0 si_code */ WARN_ON_ONCE(info.si_code < 0); return -EPERM; @@ -2457,7 +2457,7 @@ long do_rt_tgsigqueueinfo(pid_t tgid, pid_t pid, int sig, siginfo_t *info) /* Not even root can pretend to send signals from the kernel. * Nor can they impersonate a kill()/tgkill(), which adds source info. */ - if (info->si_code >= 0 || info->si_code == SI_TKILL) { + if (info->si_code != SI_QUEUE) { /* We used to allow any < 0 si_code */ WARN_ON_ONCE(info->si_code < 0); return -EPERM; diff --git a/trunk/lib/Kconfig b/trunk/lib/Kconfig index 9c10e38fc609..23fa7a359db7 100644 --- a/trunk/lib/Kconfig +++ b/trunk/lib/Kconfig @@ -157,45 +157,6 @@ config REED_SOLOMON_ENC16 config REED_SOLOMON_DEC16 boolean -# -# BCH support is selected if needed -# -config BCH - tristate - -config BCH_CONST_PARAMS - boolean - help - Drivers may select this option to force specific constant - values for parameters 'm' (Galois field order) and 't' - (error correction capability). Those specific values must - be set by declaring default values for symbols BCH_CONST_M - and BCH_CONST_T. - Doing so will enable extra compiler optimizations, - improving encoding and decoding performance up to 2x for - usual (m,t) values (typically such that m*t < 200). - When this option is selected, the BCH library supports - only a single (m,t) configuration. This is mainly useful - for NAND flash board drivers requiring known, fixed BCH - parameters. - -config BCH_CONST_M - int - range 5 15 - help - Constant value for Galois field order 'm'. If 'k' is the - number of data bits to protect, 'm' should be chosen such - that (k + m*t) <= 2**m - 1. - Drivers should declare a default value for this symbol if - they select option BCH_CONST_PARAMS. - -config BCH_CONST_T - int - help - Constant value for error correction capability in bits 't'. - Drivers should declare a default value for this symbol if - they select option BCH_CONST_PARAMS. - # # Textsearch support is select'ed if needed # diff --git a/trunk/lib/Makefile b/trunk/lib/Makefile index ef0f28571156..d7872b5c4c1c 100644 --- a/trunk/lib/Makefile +++ b/trunk/lib/Makefile @@ -69,7 +69,6 @@ obj-$(CONFIG_GENERIC_ALLOCATOR) += genalloc.o obj-$(CONFIG_ZLIB_INFLATE) += zlib_inflate/ obj-$(CONFIG_ZLIB_DEFLATE) += zlib_deflate/ obj-$(CONFIG_REED_SOLOMON) += reed_solomon/ -obj-$(CONFIG_BCH) += bch.o obj-$(CONFIG_LZO_COMPRESS) += lzo/ obj-$(CONFIG_LZO_DECOMPRESS) += lzo/ obj-$(CONFIG_XZ_DEC) += xz/ diff --git a/trunk/lib/bch.c b/trunk/lib/bch.c deleted file mode 100644 index bc89dfe4d1b3..000000000000 --- a/trunk/lib/bch.c +++ /dev/null @@ -1,1368 +0,0 @@ -/* - * Generic binary BCH encoding/decoding library - * - * 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. - * - * 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., 51 - * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Copyright © 2011 Parrot S.A. - * - * Author: Ivan Djelic - * - * Description: - * - * This library provides runtime configurable encoding/decoding of binary - * Bose-Chaudhuri-Hocquenghem (BCH) codes. - * - * Call init_bch to get a pointer to a newly allocated bch_control structure for - * the given m (Galois field order), t (error correction capability) and - * (optional) primitive polynomial parameters. - * - * Call encode_bch to compute and store ecc parity bytes to a given buffer. - * Call decode_bch to detect and locate errors in received data. - * - * On systems supporting hw BCH features, intermediate results may be provided - * to decode_bch in order to skip certain steps. See decode_bch() documentation - * for details. - * - * Option CONFIG_BCH_CONST_PARAMS can be used to force fixed values of - * parameters m and t; thus allowing extra compiler optimizations and providing - * better (up to 2x) encoding performance. Using this option makes sense when - * (m,t) are fixed and known in advance, e.g. when using BCH error correction - * on a particular NAND flash device. - * - * Algorithmic details: - * - * Encoding is performed by processing 32 input bits in parallel, using 4 - * remainder lookup tables. - * - * The final stage of decoding involves the following internal steps: - * a. Syndrome computation - * b. Error locator polynomial computation using Berlekamp-Massey algorithm - * c. Error locator root finding (by far the most expensive step) - * - * In this implementation, step c is not performed using the usual Chien search. - * Instead, an alternative approach described in [1] is used. It consists in - * factoring the error locator polynomial using the Berlekamp Trace algorithm - * (BTA) down to a certain degree (4), after which ad hoc low-degree polynomial - * solving techniques [2] are used. The resulting algorithm, called BTZ, yields - * much better performance than Chien search for usual (m,t) values (typically - * m >= 13, t < 32, see [1]). - * - * [1] B. Biswas, V. Herbert. Efficient root finding of polynomials over fields - * of characteristic 2, in: Western European Workshop on Research in Cryptology - * - WEWoRC 2009, Graz, Austria, LNCS, Springer, July 2009, to appear. - * [2] [Zin96] V.A. Zinoviev. On the solution of equations of degree 10 over - * finite fields GF(2^q). In Rapport de recherche INRIA no 2829, 1996. - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#if defined(CONFIG_BCH_CONST_PARAMS) -#define GF_M(_p) (CONFIG_BCH_CONST_M) -#define GF_T(_p) (CONFIG_BCH_CONST_T) -#define GF_N(_p) ((1 << (CONFIG_BCH_CONST_M))-1) -#else -#define GF_M(_p) ((_p)->m) -#define GF_T(_p) ((_p)->t) -#define GF_N(_p) ((_p)->n) -#endif - -#define BCH_ECC_WORDS(_p) DIV_ROUND_UP(GF_M(_p)*GF_T(_p), 32) -#define BCH_ECC_BYTES(_p) DIV_ROUND_UP(GF_M(_p)*GF_T(_p), 8) - -#ifndef dbg -#define dbg(_fmt, args...) do {} while (0) -#endif - -/* - * represent a polynomial over GF(2^m) - */ -struct gf_poly { - unsigned int deg; /* polynomial degree */ - unsigned int c[0]; /* polynomial terms */ -}; - -/* given its degree, compute a polynomial size in bytes */ -#define GF_POLY_SZ(_d) (sizeof(struct gf_poly)+((_d)+1)*sizeof(unsigned int)) - -/* polynomial of degree 1 */ -struct gf_poly_deg1 { - struct gf_poly poly; - unsigned int c[2]; -}; - -/* - * same as encode_bch(), but process input data one byte at a time - */ -static void encode_bch_unaligned(struct bch_control *bch, - const unsigned char *data, unsigned int len, - uint32_t *ecc) -{ - int i; - const uint32_t *p; - const int l = BCH_ECC_WORDS(bch)-1; - - while (len--) { - p = bch->mod8_tab + (l+1)*(((ecc[0] >> 24)^(*data++)) & 0xff); - - for (i = 0; i < l; i++) - ecc[i] = ((ecc[i] << 8)|(ecc[i+1] >> 24))^(*p++); - - ecc[l] = (ecc[l] << 8)^(*p); - } -} - -/* - * convert ecc bytes to aligned, zero-padded 32-bit ecc words - */ -static void load_ecc8(struct bch_control *bch, uint32_t *dst, - const uint8_t *src) -{ - uint8_t pad[4] = {0, 0, 0, 0}; - unsigned int i, nwords = BCH_ECC_WORDS(bch)-1; - - for (i = 0; i < nwords; i++, src += 4) - dst[i] = (src[0] << 24)|(src[1] << 16)|(src[2] << 8)|src[3]; - - memcpy(pad, src, BCH_ECC_BYTES(bch)-4*nwords); - dst[nwords] = (pad[0] << 24)|(pad[1] << 16)|(pad[2] << 8)|pad[3]; -} - -/* - * convert 32-bit ecc words to ecc bytes - */ -static void store_ecc8(struct bch_control *bch, uint8_t *dst, - const uint32_t *src) -{ - uint8_t pad[4]; - unsigned int i, nwords = BCH_ECC_WORDS(bch)-1; - - for (i = 0; i < nwords; i++) { - *dst++ = (src[i] >> 24); - *dst++ = (src[i] >> 16) & 0xff; - *dst++ = (src[i] >> 8) & 0xff; - *dst++ = (src[i] >> 0) & 0xff; - } - pad[0] = (src[nwords] >> 24); - pad[1] = (src[nwords] >> 16) & 0xff; - pad[2] = (src[nwords] >> 8) & 0xff; - pad[3] = (src[nwords] >> 0) & 0xff; - memcpy(dst, pad, BCH_ECC_BYTES(bch)-4*nwords); -} - -/** - * encode_bch - calculate BCH ecc parity of data - * @bch: BCH control structure - * @data: data to encode - * @len: data length in bytes - * @ecc: ecc parity data, must be initialized by caller - * - * The @ecc parity array is used both as input and output parameter, in order to - * allow incremental computations. It should be of the size indicated by member - * @ecc_bytes of @bch, and should be initialized to 0 before the first call. - * - * The exact number of computed ecc parity bits is given by member @ecc_bits of - * @bch; it may be less than m*t for large values of t. - */ -void encode_bch(struct bch_control *bch, const uint8_t *data, - unsigned int len, uint8_t *ecc) -{ - const unsigned int l = BCH_ECC_WORDS(bch)-1; - unsigned int i, mlen; - unsigned long m; - uint32_t w, r[l+1]; - const uint32_t * const tab0 = bch->mod8_tab; - const uint32_t * const tab1 = tab0 + 256*(l+1); - const uint32_t * const tab2 = tab1 + 256*(l+1); - const uint32_t * const tab3 = tab2 + 256*(l+1); - const uint32_t *pdata, *p0, *p1, *p2, *p3; - - if (ecc) { - /* load ecc parity bytes into internal 32-bit buffer */ - load_ecc8(bch, bch->ecc_buf, ecc); - } else { - memset(bch->ecc_buf, 0, sizeof(r)); - } - - /* process first unaligned data bytes */ - m = ((unsigned long)data) & 3; - if (m) { - mlen = (len < (4-m)) ? len : 4-m; - encode_bch_unaligned(bch, data, mlen, bch->ecc_buf); - data += mlen; - len -= mlen; - } - - /* process 32-bit aligned data words */ - pdata = (uint32_t *)data; - mlen = len/4; - data += 4*mlen; - len -= 4*mlen; - memcpy(r, bch->ecc_buf, sizeof(r)); - - /* - * split each 32-bit word into 4 polynomials of weight 8 as follows: - * - * 31 ...24 23 ...16 15 ... 8 7 ... 0 - * xxxxxxxx yyyyyyyy zzzzzzzz tttttttt - * tttttttt mod g = r0 (precomputed) - * zzzzzzzz 00000000 mod g = r1 (precomputed) - * yyyyyyyy 00000000 00000000 mod g = r2 (precomputed) - * xxxxxxxx 00000000 00000000 00000000 mod g = r3 (precomputed) - * xxxxxxxx yyyyyyyy zzzzzzzz tttttttt mod g = r0^r1^r2^r3 - */ - while (mlen--) { - /* input data is read in big-endian format */ - w = r[0]^cpu_to_be32(*pdata++); - p0 = tab0 + (l+1)*((w >> 0) & 0xff); - p1 = tab1 + (l+1)*((w >> 8) & 0xff); - p2 = tab2 + (l+1)*((w >> 16) & 0xff); - p3 = tab3 + (l+1)*((w >> 24) & 0xff); - - for (i = 0; i < l; i++) - r[i] = r[i+1]^p0[i]^p1[i]^p2[i]^p3[i]; - - r[l] = p0[l]^p1[l]^p2[l]^p3[l]; - } - memcpy(bch->ecc_buf, r, sizeof(r)); - - /* process last unaligned bytes */ - if (len) - encode_bch_unaligned(bch, data, len, bch->ecc_buf); - - /* store ecc parity bytes into original parity buffer */ - if (ecc) - store_ecc8(bch, ecc, bch->ecc_buf); -} -EXPORT_SYMBOL_GPL(encode_bch); - -static inline int modulo(struct bch_control *bch, unsigned int v) -{ - const unsigned int n = GF_N(bch); - while (v >= n) { - v -= n; - v = (v & n) + (v >> GF_M(bch)); - } - return v; -} - -/* - * shorter and faster modulo function, only works when v < 2N. - */ -static inline int mod_s(struct bch_control *bch, unsigned int v) -{ - const unsigned int n = GF_N(bch); - return (v < n) ? v : v-n; -} - -static inline int deg(unsigned int poly) -{ - /* polynomial degree is the most-significant bit index */ - return fls(poly)-1; -} - -static inline int parity(unsigned int x) -{ - /* - * public domain code snippet, lifted from - * http://www-graphics.stanford.edu/~seander/bithacks.html - */ - x ^= x >> 1; - x ^= x >> 2; - x = (x & 0x11111111U) * 0x11111111U; - return (x >> 28) & 1; -} - -/* Galois field basic operations: multiply, divide, inverse, etc. */ - -static inline unsigned int gf_mul(struct bch_control *bch, unsigned int a, - unsigned int b) -{ - return (a && b) ? bch->a_pow_tab[mod_s(bch, bch->a_log_tab[a]+ - bch->a_log_tab[b])] : 0; -} - -static inline unsigned int gf_sqr(struct bch_control *bch, unsigned int a) -{ - return a ? bch->a_pow_tab[mod_s(bch, 2*bch->a_log_tab[a])] : 0; -} - -static inline unsigned int gf_div(struct bch_control *bch, unsigned int a, - unsigned int b) -{ - return a ? bch->a_pow_tab[mod_s(bch, bch->a_log_tab[a]+ - GF_N(bch)-bch->a_log_tab[b])] : 0; -} - -static inline unsigned int gf_inv(struct bch_control *bch, unsigned int a) -{ - return bch->a_pow_tab[GF_N(bch)-bch->a_log_tab[a]]; -} - -static inline unsigned int a_pow(struct bch_control *bch, int i) -{ - return bch->a_pow_tab[modulo(bch, i)]; -} - -static inline int a_log(struct bch_control *bch, unsigned int x) -{ - return bch->a_log_tab[x]; -} - -static inline int a_ilog(struct bch_control *bch, unsigned int x) -{ - return mod_s(bch, GF_N(bch)-bch->a_log_tab[x]); -} - -/* - * compute 2t syndromes of ecc polynomial, i.e. ecc(a^j) for j=1..2t - */ -static void compute_syndromes(struct bch_control *bch, uint32_t *ecc, - unsigned int *syn) -{ - int i, j, s; - unsigned int m; - uint32_t poly; - const int t = GF_T(bch); - - s = bch->ecc_bits; - - /* make sure extra bits in last ecc word are cleared */ - m = ((unsigned int)s) & 31; - if (m) - ecc[s/32] &= ~((1u << (32-m))-1); - memset(syn, 0, 2*t*sizeof(*syn)); - - /* compute v(a^j) for j=1 .. 2t-1 */ - do { - poly = *ecc++; - s -= 32; - while (poly) { - i = deg(poly); - for (j = 0; j < 2*t; j += 2) - syn[j] ^= a_pow(bch, (j+1)*(i+s)); - - poly ^= (1 << i); - } - } while (s > 0); - - /* v(a^(2j)) = v(a^j)^2 */ - for (j = 0; j < t; j++) - syn[2*j+1] = gf_sqr(bch, syn[j]); -} - -static void gf_poly_copy(struct gf_poly *dst, struct gf_poly *src) -{ - memcpy(dst, src, GF_POLY_SZ(src->deg)); -} - -static int compute_error_locator_polynomial(struct bch_control *bch, - const unsigned int *syn) -{ - const unsigned int t = GF_T(bch); - const unsigned int n = GF_N(bch); - unsigned int i, j, tmp, l, pd = 1, d = syn[0]; - struct gf_poly *elp = bch->elp; - struct gf_poly *pelp = bch->poly_2t[0]; - struct gf_poly *elp_copy = bch->poly_2t[1]; - int k, pp = -1; - - memset(pelp, 0, GF_POLY_SZ(2*t)); - memset(elp, 0, GF_POLY_SZ(2*t)); - - pelp->deg = 0; - pelp->c[0] = 1; - elp->deg = 0; - elp->c[0] = 1; - - /* use simplified binary Berlekamp-Massey algorithm */ - for (i = 0; (i < t) && (elp->deg <= t); i++) { - if (d) { - k = 2*i-pp; - gf_poly_copy(elp_copy, elp); - /* e[i+1](X) = e[i](X)+di*dp^-1*X^2(i-p)*e[p](X) */ - tmp = a_log(bch, d)+n-a_log(bch, pd); - for (j = 0; j <= pelp->deg; j++) { - if (pelp->c[j]) { - l = a_log(bch, pelp->c[j]); - elp->c[j+k] ^= a_pow(bch, tmp+l); - } - } - /* compute l[i+1] = max(l[i]->c[l[p]+2*(i-p]) */ - tmp = pelp->deg+k; - if (tmp > elp->deg) { - elp->deg = tmp; - gf_poly_copy(pelp, elp_copy); - pd = d; - pp = 2*i; - } - } - /* di+1 = S(2i+3)+elp[i+1].1*S(2i+2)+...+elp[i+1].lS(2i+3-l) */ - if (i < t-1) { - d = syn[2*i+2]; - for (j = 1; j <= elp->deg; j++) - d ^= gf_mul(bch, elp->c[j], syn[2*i+2-j]); - } - } - dbg("elp=%s\n", gf_poly_str(elp)); - return (elp->deg > t) ? -1 : (int)elp->deg; -} - -/* - * solve a m x m linear system in GF(2) with an expected number of solutions, - * and return the number of found solutions - */ -static int solve_linear_system(struct bch_control *bch, unsigned int *rows, - unsigned int *sol, int nsol) -{ - const int m = GF_M(bch); - unsigned int tmp, mask; - int rem, c, r, p, k, param[m]; - - k = 0; - mask = 1 << m; - - /* Gaussian elimination */ - for (c = 0; c < m; c++) { - rem = 0; - p = c-k; - /* find suitable row for elimination */ - for (r = p; r < m; r++) { - if (rows[r] & mask) { - if (r != p) { - tmp = rows[r]; - rows[r] = rows[p]; - rows[p] = tmp; - } - rem = r+1; - break; - } - } - if (rem) { - /* perform elimination on remaining rows */ - tmp = rows[p]; - for (r = rem; r < m; r++) { - if (rows[r] & mask) - rows[r] ^= tmp; - } - } else { - /* elimination not needed, store defective row index */ - param[k++] = c; - } - mask >>= 1; - } - /* rewrite system, inserting fake parameter rows */ - if (k > 0) { - p = k; - for (r = m-1; r >= 0; r--) { - if ((r > m-1-k) && rows[r]) - /* system has no solution */ - return 0; - - rows[r] = (p && (r == param[p-1])) ? - p--, 1u << (m-r) : rows[r-p]; - } - } - - if (nsol != (1 << k)) - /* unexpected number of solutions */ - return 0; - - for (p = 0; p < nsol; p++) { - /* set parameters for p-th solution */ - for (c = 0; c < k; c++) - rows[param[c]] = (rows[param[c]] & ~1)|((p >> c) & 1); - - /* compute unique solution */ - tmp = 0; - for (r = m-1; r >= 0; r--) { - mask = rows[r] & (tmp|1); - tmp |= parity(mask) << (m-r); - } - sol[p] = tmp >> 1; - } - return nsol; -} - -/* - * this function builds and solves a linear system for finding roots of a degree - * 4 affine monic polynomial X^4+aX^2+bX+c over GF(2^m). - */ -static int find_affine4_roots(struct bch_control *bch, unsigned int a, - unsigned int b, unsigned int c, - unsigned int *roots) -{ - int i, j, k; - const int m = GF_M(bch); - unsigned int mask = 0xff, t, rows[16] = {0,}; - - j = a_log(bch, b); - k = a_log(bch, a); - rows[0] = c; - - /* buid linear system to solve X^4+aX^2+bX+c = 0 */ - for (i = 0; i < m; i++) { - rows[i+1] = bch->a_pow_tab[4*i]^ - (a ? bch->a_pow_tab[mod_s(bch, k)] : 0)^ - (b ? bch->a_pow_tab[mod_s(bch, j)] : 0); - j++; - k += 2; - } - /* - * transpose 16x16 matrix before passing it to linear solver - * warning: this code assumes m < 16 - */ - for (j = 8; j != 0; j >>= 1, mask ^= (mask << j)) { - for (k = 0; k < 16; k = (k+j+1) & ~j) { - t = ((rows[k] >> j)^rows[k+j]) & mask; - rows[k] ^= (t << j); - rows[k+j] ^= t; - } - } - return solve_linear_system(bch, rows, roots, 4); -} - -/* - * compute root r of a degree 1 polynomial over GF(2^m) (returned as log(1/r)) - */ -static int find_poly_deg1_roots(struct bch_control *bch, struct gf_poly *poly, - unsigned int *roots) -{ - int n = 0; - - if (poly->c[0]) - /* poly[X] = bX+c with c!=0, root=c/b */ - roots[n++] = mod_s(bch, GF_N(bch)-bch->a_log_tab[poly->c[0]]+ - bch->a_log_tab[poly->c[1]]); - return n; -} - -/* - * compute roots of a degree 2 polynomial over GF(2^m) - */ -static int find_poly_deg2_roots(struct bch_control *bch, struct gf_poly *poly, - unsigned int *roots) -{ - int n = 0, i, l0, l1, l2; - unsigned int u, v, r; - - if (poly->c[0] && poly->c[1]) { - - l0 = bch->a_log_tab[poly->c[0]]; - l1 = bch->a_log_tab[poly->c[1]]; - l2 = bch->a_log_tab[poly->c[2]]; - - /* using z=a/bX, transform aX^2+bX+c into z^2+z+u (u=ac/b^2) */ - u = a_pow(bch, l0+l2+2*(GF_N(bch)-l1)); - /* - * let u = sum(li.a^i) i=0..m-1; then compute r = sum(li.xi): - * r^2+r = sum(li.(xi^2+xi)) = sum(li.(a^i+Tr(a^i).a^k)) = - * u + sum(li.Tr(a^i).a^k) = u+a^k.Tr(sum(li.a^i)) = u+a^k.Tr(u) - * i.e. r and r+1 are roots iff Tr(u)=0 - */ - r = 0; - v = u; - while (v) { - i = deg(v); - r ^= bch->xi_tab[i]; - v ^= (1 << i); - } - /* verify root */ - if ((gf_sqr(bch, r)^r) == u) { - /* reverse z=a/bX transformation and compute log(1/r) */ - roots[n++] = modulo(bch, 2*GF_N(bch)-l1- - bch->a_log_tab[r]+l2); - roots[n++] = modulo(bch, 2*GF_N(bch)-l1- - bch->a_log_tab[r^1]+l2); - } - } - return n; -} - -/* - * compute roots of a degree 3 polynomial over GF(2^m) - */ -static int find_poly_deg3_roots(struct bch_control *bch, struct gf_poly *poly, - unsigned int *roots) -{ - int i, n = 0; - unsigned int a, b, c, a2, b2, c2, e3, tmp[4]; - - if (poly->c[0]) { - /* transform polynomial into monic X^3 + a2X^2 + b2X + c2 */ - e3 = poly->c[3]; - c2 = gf_div(bch, poly->c[0], e3); - b2 = gf_div(bch, poly->c[1], e3); - a2 = gf_div(bch, poly->c[2], e3); - - /* (X+a2)(X^3+a2X^2+b2X+c2) = X^4+aX^2+bX+c (affine) */ - c = gf_mul(bch, a2, c2); /* c = a2c2 */ - b = gf_mul(bch, a2, b2)^c2; /* b = a2b2 + c2 */ - a = gf_sqr(bch, a2)^b2; /* a = a2^2 + b2 */ - - /* find the 4 roots of this affine polynomial */ - if (find_affine4_roots(bch, a, b, c, tmp) == 4) { - /* remove a2 from final list of roots */ - for (i = 0; i < 4; i++) { - if (tmp[i] != a2) - roots[n++] = a_ilog(bch, tmp[i]); - } - } - } - return n; -} - -/* - * compute roots of a degree 4 polynomial over GF(2^m) - */ -static int find_poly_deg4_roots(struct bch_control *bch, struct gf_poly *poly, - unsigned int *roots) -{ - int i, l, n = 0; - unsigned int a, b, c, d, e = 0, f, a2, b2, c2, e4; - - if (poly->c[0] == 0) - return 0; - - /* transform polynomial into monic X^4 + aX^3 + bX^2 + cX + d */ - e4 = poly->c[4]; - d = gf_div(bch, poly->c[0], e4); - c = gf_div(bch, poly->c[1], e4); - b = gf_div(bch, poly->c[2], e4); - a = gf_div(bch, poly->c[3], e4); - - /* use Y=1/X transformation to get an affine polynomial */ - if (a) { - /* first, eliminate cX by using z=X+e with ae^2+c=0 */ - if (c) { - /* compute e such that e^2 = c/a */ - f = gf_div(bch, c, a); - l = a_log(bch, f); - l += (l & 1) ? GF_N(bch) : 0; - e = a_pow(bch, l/2); - /* - * use transformation z=X+e: - * z^4+e^4 + a(z^3+ez^2+e^2z+e^3) + b(z^2+e^2) +cz+ce+d - * z^4 + az^3 + (ae+b)z^2 + (ae^2+c)z+e^4+be^2+ae^3+ce+d - * z^4 + az^3 + (ae+b)z^2 + e^4+be^2+d - * z^4 + az^3 + b'z^2 + d' - */ - d = a_pow(bch, 2*l)^gf_mul(bch, b, f)^d; - b = gf_mul(bch, a, e)^b; - } - /* now, use Y=1/X to get Y^4 + b/dY^2 + a/dY + 1/d */ - if (d == 0) - /* assume all roots have multiplicity 1 */ - return 0; - - c2 = gf_inv(bch, d); - b2 = gf_div(bch, a, d); - a2 = gf_div(bch, b, d); - } else { - /* polynomial is already affine */ - c2 = d; - b2 = c; - a2 = b; - } - /* find the 4 roots of this affine polynomial */ - if (find_affine4_roots(bch, a2, b2, c2, roots) == 4) { - for (i = 0; i < 4; i++) { - /* post-process roots (reverse transformations) */ - f = a ? gf_inv(bch, roots[i]) : roots[i]; - roots[i] = a_ilog(bch, f^e); - } - n = 4; - } - return n; -} - -/* - * build monic, log-based representation of a polynomial - */ -static void gf_poly_logrep(struct bch_control *bch, - const struct gf_poly *a, int *rep) -{ - int i, d = a->deg, l = GF_N(bch)-a_log(bch, a->c[a->deg]); - - /* represent 0 values with -1; warning, rep[d] is not set to 1 */ - for (i = 0; i < d; i++) - rep[i] = a->c[i] ? mod_s(bch, a_log(bch, a->c[i])+l) : -1; -} - -/* - * compute polynomial Euclidean division remainder in GF(2^m)[X] - */ -static void gf_poly_mod(struct bch_control *bch, struct gf_poly *a, - const struct gf_poly *b, int *rep) -{ - int la, p, m; - unsigned int i, j, *c = a->c; - const unsigned int d = b->deg; - - if (a->deg < d) - return; - - /* reuse or compute log representation of denominator */ - if (!rep) { - rep = bch->cache; - gf_poly_logrep(bch, b, rep); - } - - for (j = a->deg; j >= d; j--) { - if (c[j]) { - la = a_log(bch, c[j]); - p = j-d; - for (i = 0; i < d; i++, p++) { - m = rep[i]; - if (m >= 0) - c[p] ^= bch->a_pow_tab[mod_s(bch, - m+la)]; - } - } - } - a->deg = d-1; - while (!c[a->deg] && a->deg) - a->deg--; -} - -/* - * compute polynomial Euclidean division quotient in GF(2^m)[X] - */ -static void gf_poly_div(struct bch_control *bch, struct gf_poly *a, - const struct gf_poly *b, struct gf_poly *q) -{ - if (a->deg >= b->deg) { - q->deg = a->deg-b->deg; - /* compute a mod b (modifies a) */ - gf_poly_mod(bch, a, b, NULL); - /* quotient is stored in upper part of polynomial a */ - memcpy(q->c, &a->c[b->deg], (1+q->deg)*sizeof(unsigned int)); - } else { - q->deg = 0; - q->c[0] = 0; - } -} - -/* - * compute polynomial GCD (Greatest Common Divisor) in GF(2^m)[X] - */ -static struct gf_poly *gf_poly_gcd(struct bch_control *bch, struct gf_poly *a, - struct gf_poly *b) -{ - struct gf_poly *tmp; - - dbg("gcd(%s,%s)=", gf_poly_str(a), gf_poly_str(b)); - - if (a->deg < b->deg) { - tmp = b; - b = a; - a = tmp; - } - - while (b->deg > 0) { - gf_poly_mod(bch, a, b, NULL); - tmp = b; - b = a; - a = tmp; - } - - dbg("%s\n", gf_poly_str(a)); - - return a; -} - -/* - * Given a polynomial f and an integer k, compute Tr(a^kX) mod f - * This is used in Berlekamp Trace algorithm for splitting polynomials - */ -static void compute_trace_bk_mod(struct bch_control *bch, int k, - const struct gf_poly *f, struct gf_poly *z, - struct gf_poly *out) -{ - const int m = GF_M(bch); - int i, j; - - /* z contains z^2j mod f */ - z->deg = 1; - z->c[0] = 0; - z->c[1] = bch->a_pow_tab[k]; - - out->deg = 0; - memset(out, 0, GF_POLY_SZ(f->deg)); - - /* compute f log representation only once */ - gf_poly_logrep(bch, f, bch->cache); - - for (i = 0; i < m; i++) { - /* add a^(k*2^i)(z^(2^i) mod f) and compute (z^(2^i) mod f)^2 */ - for (j = z->deg; j >= 0; j--) { - out->c[j] ^= z->c[j]; - z->c[2*j] = gf_sqr(bch, z->c[j]); - z->c[2*j+1] = 0; - } - if (z->deg > out->deg) - out->deg = z->deg; - - if (i < m-1) { - z->deg *= 2; - /* z^(2(i+1)) mod f = (z^(2^i) mod f)^2 mod f */ - gf_poly_mod(bch, z, f, bch->cache); - } - } - while (!out->c[out->deg] && out->deg) - out->deg--; - - dbg("Tr(a^%d.X) mod f = %s\n", k, gf_poly_str(out)); -} - -/* - * factor a polynomial using Berlekamp Trace algorithm (BTA) - */ -static void factor_polynomial(struct bch_control *bch, int k, struct gf_poly *f, - struct gf_poly **g, struct gf_poly **h) -{ - struct gf_poly *f2 = bch->poly_2t[0]; - struct gf_poly *q = bch->poly_2t[1]; - struct gf_poly *tk = bch->poly_2t[2]; - struct gf_poly *z = bch->poly_2t[3]; - struct gf_poly *gcd; - - dbg("factoring %s...\n", gf_poly_str(f)); - - *g = f; - *h = NULL; - - /* tk = Tr(a^k.X) mod f */ - compute_trace_bk_mod(bch, k, f, z, tk); - - if (tk->deg > 0) { - /* compute g = gcd(f, tk) (destructive operation) */ - gf_poly_copy(f2, f); - gcd = gf_poly_gcd(bch, f2, tk); - if (gcd->deg < f->deg) { - /* compute h=f/gcd(f,tk); this will modify f and q */ - gf_poly_div(bch, f, gcd, q); - /* store g and h in-place (clobbering f) */ - *h = &((struct gf_poly_deg1 *)f)[gcd->deg].poly; - gf_poly_copy(*g, gcd); - gf_poly_copy(*h, q); - } - } -} - -/* - * find roots of a polynomial, using BTZ algorithm; see the beginning of this - * file for details - */ -static int find_poly_roots(struct bch_control *bch, unsigned int k, - struct gf_poly *poly, unsigned int *roots) -{ - int cnt; - struct gf_poly *f1, *f2; - - switch (poly->deg) { - /* handle low degree polynomials with ad hoc techniques */ - case 1: - cnt = find_poly_deg1_roots(bch, poly, roots); - break; - case 2: - cnt = find_poly_deg2_roots(bch, poly, roots); - break; - case 3: - cnt = find_poly_deg3_roots(bch, poly, roots); - break; - case 4: - cnt = find_poly_deg4_roots(bch, poly, roots); - break; - default: - /* factor polynomial using Berlekamp Trace Algorithm (BTA) */ - cnt = 0; - if (poly->deg && (k <= GF_M(bch))) { - factor_polynomial(bch, k, poly, &f1, &f2); - if (f1) - cnt += find_poly_roots(bch, k+1, f1, roots); - if (f2) - cnt += find_poly_roots(bch, k+1, f2, roots+cnt); - } - break; - } - return cnt; -} - -#if defined(USE_CHIEN_SEARCH) -/* - * exhaustive root search (Chien) implementation - not used, included only for - * reference/comparison tests - */ -static int chien_search(struct bch_control *bch, unsigned int len, - struct gf_poly *p, unsigned int *roots) -{ - int m; - unsigned int i, j, syn, syn0, count = 0; - const unsigned int k = 8*len+bch->ecc_bits; - - /* use a log-based representation of polynomial */ - gf_poly_logrep(bch, p, bch->cache); - bch->cache[p->deg] = 0; - syn0 = gf_div(bch, p->c[0], p->c[p->deg]); - - for (i = GF_N(bch)-k+1; i <= GF_N(bch); i++) { - /* compute elp(a^i) */ - for (j = 1, syn = syn0; j <= p->deg; j++) { - m = bch->cache[j]; - if (m >= 0) - syn ^= a_pow(bch, m+j*i); - } - if (syn == 0) { - roots[count++] = GF_N(bch)-i; - if (count == p->deg) - break; - } - } - return (count == p->deg) ? count : 0; -} -#define find_poly_roots(_p, _k, _elp, _loc) chien_search(_p, len, _elp, _loc) -#endif /* USE_CHIEN_SEARCH */ - -/** - * decode_bch - decode received codeword and find bit error locations - * @bch: BCH control structure - * @data: received data, ignored if @calc_ecc is provided - * @len: data length in bytes, must always be provided - * @recv_ecc: received ecc, if NULL then assume it was XORed in @calc_ecc - * @calc_ecc: calculated ecc, if NULL then calc_ecc is computed from @data - * @syn: hw computed syndrome data (if NULL, syndrome is calculated) - * @errloc: output array of error locations - * - * Returns: - * The number of errors found, or -EBADMSG if decoding failed, or -EINVAL if - * invalid parameters were provided - * - * Depending on the available hw BCH support and the need to compute @calc_ecc - * separately (using encode_bch()), this function should be called with one of - * the following parameter configurations - - * - * by providing @data and @recv_ecc only: - * decode_bch(@bch, @data, @len, @recv_ecc, NULL, NULL, @errloc) - * - * by providing @recv_ecc and @calc_ecc: - * decode_bch(@bch, NULL, @len, @recv_ecc, @calc_ecc, NULL, @errloc) - * - * by providing ecc = recv_ecc XOR calc_ecc: - * decode_bch(@bch, NULL, @len, NULL, ecc, NULL, @errloc) - * - * by providing syndrome results @syn: - * decode_bch(@bch, NULL, @len, NULL, NULL, @syn, @errloc) - * - * Once decode_bch() has successfully returned with a positive value, error - * locations returned in array @errloc should be interpreted as follows - - * - * if (errloc[n] >= 8*len), then n-th error is located in ecc (no need for - * data correction) - * - * if (errloc[n] < 8*len), then n-th error is located in data and can be - * corrected with statement data[errloc[n]/8] ^= 1 << (errloc[n] % 8); - * - * Note that this function does not perform any data correction by itself, it - * merely indicates error locations. - */ -int decode_bch(struct bch_control *bch, const uint8_t *data, unsigned int len, - const uint8_t *recv_ecc, const uint8_t *calc_ecc, - const unsigned int *syn, unsigned int *errloc) -{ - const unsigned int ecc_words = BCH_ECC_WORDS(bch); - unsigned int nbits; - int i, err, nroots; - uint32_t sum; - - /* sanity check: make sure data length can be handled */ - if (8*len > (bch->n-bch->ecc_bits)) - return -EINVAL; - - /* if caller does not provide syndromes, compute them */ - if (!syn) { - if (!calc_ecc) { - /* compute received data ecc into an internal buffer */ - if (!data || !recv_ecc) - return -EINVAL; - encode_bch(bch, data, len, NULL); - } else { - /* load provided calculated ecc */ - load_ecc8(bch, bch->ecc_buf, calc_ecc); - } - /* load received ecc or assume it was XORed in calc_ecc */ - if (recv_ecc) { - load_ecc8(bch, bch->ecc_buf2, recv_ecc); - /* XOR received and calculated ecc */ - for (i = 0, sum = 0; i < (int)ecc_words; i++) { - bch->ecc_buf[i] ^= bch->ecc_buf2[i]; - sum |= bch->ecc_buf[i]; - } - if (!sum) - /* no error found */ - return 0; - } - compute_syndromes(bch, bch->ecc_buf, bch->syn); - syn = bch->syn; - } - - err = compute_error_locator_polynomial(bch, syn); - if (err > 0) { - nroots = find_poly_roots(bch, 1, bch->elp, errloc); - if (err != nroots) - err = -1; - } - if (err > 0) { - /* post-process raw error locations for easier correction */ - nbits = (len*8)+bch->ecc_bits; - for (i = 0; i < err; i++) { - if (errloc[i] >= nbits) { - err = -1; - break; - } - errloc[i] = nbits-1-errloc[i]; - errloc[i] = (errloc[i] & ~7)|(7-(errloc[i] & 7)); - } - } - return (err >= 0) ? err : -EBADMSG; -} -EXPORT_SYMBOL_GPL(decode_bch); - -/* - * generate Galois field lookup tables - */ -static int build_gf_tables(struct bch_control *bch, unsigned int poly) -{ - unsigned int i, x = 1; - const unsigned int k = 1 << deg(poly); - - /* primitive polynomial must be of degree m */ - if (k != (1u << GF_M(bch))) - return -1; - - for (i = 0; i < GF_N(bch); i++) { - bch->a_pow_tab[i] = x; - bch->a_log_tab[x] = i; - if (i && (x == 1)) - /* polynomial is not primitive (a^i=1 with 0a_pow_tab[GF_N(bch)] = 1; - bch->a_log_tab[0] = 0; - - return 0; -} - -/* - * compute generator polynomial remainder tables for fast encoding - */ -static void build_mod8_tables(struct bch_control *bch, const uint32_t *g) -{ - int i, j, b, d; - uint32_t data, hi, lo, *tab; - const int l = BCH_ECC_WORDS(bch); - const int plen = DIV_ROUND_UP(bch->ecc_bits+1, 32); - const int ecclen = DIV_ROUND_UP(bch->ecc_bits, 32); - - memset(bch->mod8_tab, 0, 4*256*l*sizeof(*bch->mod8_tab)); - - for (i = 0; i < 256; i++) { - /* p(X)=i is a small polynomial of weight <= 8 */ - for (b = 0; b < 4; b++) { - /* we want to compute (p(X).X^(8*b+deg(g))) mod g(X) */ - tab = bch->mod8_tab + (b*256+i)*l; - data = i << (8*b); - while (data) { - d = deg(data); - /* subtract X^d.g(X) from p(X).X^(8*b+deg(g)) */ - data ^= g[0] >> (31-d); - for (j = 0; j < ecclen; j++) { - hi = (d < 31) ? g[j] << (d+1) : 0; - lo = (j+1 < plen) ? - g[j+1] >> (31-d) : 0; - tab[j] ^= hi|lo; - } - } - } - } -} - -/* - * build a base for factoring degree 2 polynomials - */ -static int build_deg2_base(struct bch_control *bch) -{ - const int m = GF_M(bch); - int i, j, r; - unsigned int sum, x, y, remaining, ak = 0, xi[m]; - - /* find k s.t. Tr(a^k) = 1 and 0 <= k < m */ - for (i = 0; i < m; i++) { - for (j = 0, sum = 0; j < m; j++) - sum ^= a_pow(bch, i*(1 << j)); - - if (sum) { - ak = bch->a_pow_tab[i]; - break; - } - } - /* find xi, i=0..m-1 such that xi^2+xi = a^i+Tr(a^i).a^k */ - remaining = m; - memset(xi, 0, sizeof(xi)); - - for (x = 0; (x <= GF_N(bch)) && remaining; x++) { - y = gf_sqr(bch, x)^x; - for (i = 0; i < 2; i++) { - r = a_log(bch, y); - if (y && (r < m) && !xi[r]) { - bch->xi_tab[r] = x; - xi[r] = 1; - remaining--; - dbg("x%d = %x\n", r, x); - break; - } - y ^= ak; - } - } - /* should not happen but check anyway */ - return remaining ? -1 : 0; -} - -static void *bch_alloc(size_t size, int *err) -{ - void *ptr; - - ptr = kmalloc(size, GFP_KERNEL); - if (ptr == NULL) - *err = 1; - return ptr; -} - -/* - * compute generator polynomial for given (m,t) parameters. - */ -static uint32_t *compute_generator_polynomial(struct bch_control *bch) -{ - const unsigned int m = GF_M(bch); - const unsigned int t = GF_T(bch); - int n, err = 0; - unsigned int i, j, nbits, r, word, *roots; - struct gf_poly *g; - uint32_t *genpoly; - - g = bch_alloc(GF_POLY_SZ(m*t), &err); - roots = bch_alloc((bch->n+1)*sizeof(*roots), &err); - genpoly = bch_alloc(DIV_ROUND_UP(m*t+1, 32)*sizeof(*genpoly), &err); - - if (err) { - kfree(genpoly); - genpoly = NULL; - goto finish; - } - - /* enumerate all roots of g(X) */ - memset(roots , 0, (bch->n+1)*sizeof(*roots)); - for (i = 0; i < t; i++) { - for (j = 0, r = 2*i+1; j < m; j++) { - roots[r] = 1; - r = mod_s(bch, 2*r); - } - } - /* build generator polynomial g(X) */ - g->deg = 0; - g->c[0] = 1; - for (i = 0; i < GF_N(bch); i++) { - if (roots[i]) { - /* multiply g(X) by (X+root) */ - r = bch->a_pow_tab[i]; - g->c[g->deg+1] = 1; - for (j = g->deg; j > 0; j--) - g->c[j] = gf_mul(bch, g->c[j], r)^g->c[j-1]; - - g->c[0] = gf_mul(bch, g->c[0], r); - g->deg++; - } - } - /* store left-justified binary representation of g(X) */ - n = g->deg+1; - i = 0; - - while (n > 0) { - nbits = (n > 32) ? 32 : n; - for (j = 0, word = 0; j < nbits; j++) { - if (g->c[n-1-j]) - word |= 1u << (31-j); - } - genpoly[i++] = word; - n -= nbits; - } - bch->ecc_bits = g->deg; - -finish: - kfree(g); - kfree(roots); - - return genpoly; -} - -/** - * init_bch - initialize a BCH encoder/decoder - * @m: Galois field order, should be in the range 5-15 - * @t: maximum error correction capability, in bits - * @prim_poly: user-provided primitive polynomial (or 0 to use default) - * - * Returns: - * a newly allocated BCH control structure if successful, NULL otherwise - * - * This initialization can take some time, as lookup tables are built for fast - * encoding/decoding; make sure not to call this function from a time critical - * path. Usually, init_bch() should be called on module/driver init and - * free_bch() should be called to release memory on exit. - * - * You may provide your own primitive polynomial of degree @m in argument - * @prim_poly, or let init_bch() use its default polynomial. - * - * Once init_bch() has successfully returned a pointer to a newly allocated - * BCH control structure, ecc length in bytes is given by member @ecc_bytes of - * the structure. - */ -struct bch_control *init_bch(int m, int t, unsigned int prim_poly) -{ - int err = 0; - unsigned int i, words; - uint32_t *genpoly; - struct bch_control *bch = NULL; - - const int min_m = 5; - const int max_m = 15; - - /* default primitive polynomials */ - static const unsigned int prim_poly_tab[] = { - 0x25, 0x43, 0x83, 0x11d, 0x211, 0x409, 0x805, 0x1053, 0x201b, - 0x402b, 0x8003, - }; - -#if defined(CONFIG_BCH_CONST_PARAMS) - if ((m != (CONFIG_BCH_CONST_M)) || (t != (CONFIG_BCH_CONST_T))) { - printk(KERN_ERR "bch encoder/decoder was configured to support " - "parameters m=%d, t=%d only!\n", - CONFIG_BCH_CONST_M, CONFIG_BCH_CONST_T); - goto fail; - } -#endif - if ((m < min_m) || (m > max_m)) - /* - * values of m greater than 15 are not currently supported; - * supporting m > 15 would require changing table base type - * (uint16_t) and a small patch in matrix transposition - */ - goto fail; - - /* sanity checks */ - if ((t < 1) || (m*t >= ((1 << m)-1))) - /* invalid t value */ - goto fail; - - /* select a primitive polynomial for generating GF(2^m) */ - if (prim_poly == 0) - prim_poly = prim_poly_tab[m-min_m]; - - bch = kzalloc(sizeof(*bch), GFP_KERNEL); - if (bch == NULL) - goto fail; - - bch->m = m; - bch->t = t; - bch->n = (1 << m)-1; - words = DIV_ROUND_UP(m*t, 32); - bch->ecc_bytes = DIV_ROUND_UP(m*t, 8); - bch->a_pow_tab = bch_alloc((1+bch->n)*sizeof(*bch->a_pow_tab), &err); - bch->a_log_tab = bch_alloc((1+bch->n)*sizeof(*bch->a_log_tab), &err); - bch->mod8_tab = bch_alloc(words*1024*sizeof(*bch->mod8_tab), &err); - bch->ecc_buf = bch_alloc(words*sizeof(*bch->ecc_buf), &err); - bch->ecc_buf2 = bch_alloc(words*sizeof(*bch->ecc_buf2), &err); - bch->xi_tab = bch_alloc(m*sizeof(*bch->xi_tab), &err); - bch->syn = bch_alloc(2*t*sizeof(*bch->syn), &err); - bch->cache = bch_alloc(2*t*sizeof(*bch->cache), &err); - bch->elp = bch_alloc((t+1)*sizeof(struct gf_poly_deg1), &err); - - for (i = 0; i < ARRAY_SIZE(bch->poly_2t); i++) - bch->poly_2t[i] = bch_alloc(GF_POLY_SZ(2*t), &err); - - if (err) - goto fail; - - err = build_gf_tables(bch, prim_poly); - if (err) - goto fail; - - /* use generator polynomial for computing encoding tables */ - genpoly = compute_generator_polynomial(bch); - if (genpoly == NULL) - goto fail; - - build_mod8_tables(bch, genpoly); - kfree(genpoly); - - err = build_deg2_base(bch); - if (err) - goto fail; - - return bch; - -fail: - free_bch(bch); - return NULL; -} -EXPORT_SYMBOL_GPL(init_bch); - -/** - * free_bch - free the BCH control structure - * @bch: BCH control structure to release - */ -void free_bch(struct bch_control *bch) -{ - unsigned int i; - - if (bch) { - kfree(bch->a_pow_tab); - kfree(bch->a_log_tab); - kfree(bch->mod8_tab); - kfree(bch->ecc_buf); - kfree(bch->ecc_buf2); - kfree(bch->xi_tab); - kfree(bch->syn); - kfree(bch->cache); - kfree(bch->elp); - - for (i = 0; i < ARRAY_SIZE(bch->poly_2t); i++) - kfree(bch->poly_2t[i]); - - kfree(bch); - } -} -EXPORT_SYMBOL_GPL(free_bch); - -MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Ivan Djelic "); -MODULE_DESCRIPTION("Binary BCH encoder/decoder"); diff --git a/trunk/mm/memory.c b/trunk/mm/memory.c index 9da8cab1b1b0..51a5c23704af 100644 --- a/trunk/mm/memory.c +++ b/trunk/mm/memory.c @@ -3715,7 +3715,7 @@ static int __access_remote_vm(struct task_struct *tsk, struct mm_struct *mm, } /** - * access_remote_vm - access another process' address space + * @access_remote_vm - access another process' address space * @mm: the mm_struct of the target address space * @addr: start address to access * @buf: source or destination buffer diff --git a/trunk/mm/percpu.c b/trunk/mm/percpu.c index 3f930018aa60..55d4d113fbd3 100644 --- a/trunk/mm/percpu.c +++ b/trunk/mm/percpu.c @@ -1008,8 +1008,7 @@ phys_addr_t per_cpu_ptr_to_phys(void *addr) } if (in_first_chunk) { - if ((unsigned long)addr < VMALLOC_START || - (unsigned long)addr >= VMALLOC_END) + if (!is_vmalloc_addr(addr)) return __pa(addr); else return page_to_phys(vmalloc_to_page(addr)); diff --git a/trunk/net/bridge/br_if.c b/trunk/net/bridge/br_if.c index 718b60366dfe..dce8f0009a12 100644 --- a/trunk/net/bridge/br_if.c +++ b/trunk/net/bridge/br_if.c @@ -389,7 +389,6 @@ int br_add_if(struct net_bridge *br, struct net_device *dev) { struct net_bridge_port *p; int err = 0; - bool changed_addr; /* Don't allow bridging non-ethernet like devices */ if ((dev->flags & IFF_LOOPBACK) || @@ -447,7 +446,7 @@ int br_add_if(struct net_bridge *br, struct net_device *dev) list_add_rcu(&p->list, &br->port_list); spin_lock_bh(&br->lock); - changed_addr = br_stp_recalculate_bridge_id(br); + br_stp_recalculate_bridge_id(br); br_features_recompute(br); if ((dev->flags & IFF_UP) && netif_carrier_ok(dev) && @@ -457,9 +456,6 @@ int br_add_if(struct net_bridge *br, struct net_device *dev) br_ifinfo_notify(RTM_NEWLINK, p); - if (changed_addr) - call_netdevice_notifiers(NETDEV_CHANGEADDR, dev); - dev_set_mtu(br->dev, br_min_mtu(br)); kobject_uevent(&p->kobj, KOBJ_ADD); diff --git a/trunk/net/bridge/br_private.h b/trunk/net/bridge/br_private.h index 387013d33745..19e2f46ed086 100644 --- a/trunk/net/bridge/br_private.h +++ b/trunk/net/bridge/br_private.h @@ -497,7 +497,7 @@ extern void br_stp_disable_bridge(struct net_bridge *br); extern void br_stp_set_enabled(struct net_bridge *br, unsigned long val); extern void br_stp_enable_port(struct net_bridge_port *p); extern void br_stp_disable_port(struct net_bridge_port *p); -extern bool br_stp_recalculate_bridge_id(struct net_bridge *br); +extern void br_stp_recalculate_bridge_id(struct net_bridge *br); extern void br_stp_change_bridge_id(struct net_bridge *br, const unsigned char *a); extern void br_stp_set_bridge_priority(struct net_bridge *br, u16 newprio); diff --git a/trunk/net/bridge/br_stp_if.c b/trunk/net/bridge/br_stp_if.c index 5593f5aec942..79372d4a4055 100644 --- a/trunk/net/bridge/br_stp_if.c +++ b/trunk/net/bridge/br_stp_if.c @@ -204,7 +204,7 @@ void br_stp_change_bridge_id(struct net_bridge *br, const unsigned char *addr) static const unsigned short br_mac_zero_aligned[ETH_ALEN >> 1]; /* called under bridge lock */ -bool br_stp_recalculate_bridge_id(struct net_bridge *br) +void br_stp_recalculate_bridge_id(struct net_bridge *br) { const unsigned char *br_mac_zero = (const unsigned char *)br_mac_zero_aligned; @@ -222,11 +222,8 @@ bool br_stp_recalculate_bridge_id(struct net_bridge *br) } - if (compare_ether_addr(br->bridge_id.addr, addr) == 0) - return false; /* no change */ - - br_stp_change_bridge_id(br, addr); - return true; + if (compare_ether_addr(br->bridge_id.addr, addr)) + br_stp_change_bridge_id(br, addr); } /* called under bridge lock */ diff --git a/trunk/net/can/af_can.c b/trunk/net/can/af_can.c index 733d66f1b05a..702be5a2c956 100644 --- a/trunk/net/can/af_can.c +++ b/trunk/net/can/af_can.c @@ -95,7 +95,7 @@ struct s_pstats can_pstats; /* receive list statistics */ * af_can socket functions */ -int can_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) +static int can_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) { struct sock *sk = sock->sk; @@ -108,7 +108,6 @@ int can_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) return -ENOIOCTLCMD; } } -EXPORT_SYMBOL(can_ioctl); static void can_sock_destruct(struct sock *sk) { @@ -699,9 +698,13 @@ int can_proto_register(struct can_proto *cp) printk(KERN_ERR "can: protocol %d already registered\n", proto); err = -EBUSY; - } else + } else { proto_tab[proto] = cp; + /* use generic ioctl function if not defined by module */ + if (!cp->ops->ioctl) + cp->ops->ioctl = can_ioctl; + } spin_unlock(&proto_tab_lock); if (err < 0) diff --git a/trunk/net/can/bcm.c b/trunk/net/can/bcm.c index 871a0ad51025..092dc88a7c64 100644 --- a/trunk/net/can/bcm.c +++ b/trunk/net/can/bcm.c @@ -1569,7 +1569,7 @@ static int bcm_recvmsg(struct kiocb *iocb, struct socket *sock, return size; } -static const struct proto_ops bcm_ops = { +static struct proto_ops bcm_ops __read_mostly = { .family = PF_CAN, .release = bcm_release, .bind = sock_no_bind, @@ -1578,7 +1578,7 @@ static const struct proto_ops bcm_ops = { .accept = sock_no_accept, .getname = sock_no_getname, .poll = datagram_poll, - .ioctl = can_ioctl, /* use can_ioctl() from af_can.c */ + .ioctl = NULL, /* use can_ioctl() from af_can.c */ .listen = sock_no_listen, .shutdown = sock_no_shutdown, .setsockopt = sock_no_setsockopt, diff --git a/trunk/net/can/raw.c b/trunk/net/can/raw.c index 649acfa7c70a..883e9d74fddf 100644 --- a/trunk/net/can/raw.c +++ b/trunk/net/can/raw.c @@ -742,7 +742,7 @@ static int raw_recvmsg(struct kiocb *iocb, struct socket *sock, return size; } -static const struct proto_ops raw_ops = { +static struct proto_ops raw_ops __read_mostly = { .family = PF_CAN, .release = raw_release, .bind = raw_bind, @@ -751,7 +751,7 @@ static const struct proto_ops raw_ops = { .accept = sock_no_accept, .getname = raw_getname, .poll = datagram_poll, - .ioctl = can_ioctl, /* use can_ioctl() from af_can.c */ + .ioctl = NULL, /* use can_ioctl() from af_can.c */ .listen = sock_no_listen, .shutdown = sock_no_shutdown, .setsockopt = raw_setsockopt, diff --git a/trunk/net/core/dev.c b/trunk/net/core/dev.c index 563ddc28139d..f453370131a0 100644 --- a/trunk/net/core/dev.c +++ b/trunk/net/core/dev.c @@ -1140,6 +1140,9 @@ static int __dev_open(struct net_device *dev) ASSERT_RTNL(); + /* + * Is it even present? + */ if (!netif_device_present(dev)) return -ENODEV; @@ -1148,6 +1151,9 @@ static int __dev_open(struct net_device *dev) if (ret) return ret; + /* + * Call device private open method + */ set_bit(__LINK_STATE_START, &dev->state); if (ops->ndo_validate_addr) @@ -1156,12 +1162,31 @@ static int __dev_open(struct net_device *dev) if (!ret && ops->ndo_open) ret = ops->ndo_open(dev); + /* + * If it went open OK then: + */ + if (ret) clear_bit(__LINK_STATE_START, &dev->state); else { + /* + * Set the flags. + */ dev->flags |= IFF_UP; + + /* + * Enable NET_DMA + */ net_dmaengine_get(); + + /* + * Initialize multicasting status + */ dev_set_rx_mode(dev); + + /* + * Wakeup transmit queue engine + */ dev_activate(dev); } @@ -1184,13 +1209,22 @@ int dev_open(struct net_device *dev) { int ret; + /* + * Is it already up? + */ if (dev->flags & IFF_UP) return 0; + /* + * Open device + */ ret = __dev_open(dev); if (ret < 0) return ret; + /* + * ... and announce new interface. + */ rtmsg_ifinfo(RTM_NEWLINK, dev, IFF_UP|IFF_RUNNING); call_netdevice_notifiers(NETDEV_UP, dev); @@ -1206,6 +1240,10 @@ static int __dev_close_many(struct list_head *head) might_sleep(); list_for_each_entry(dev, head, unreg_list) { + /* + * Tell people we are going down, so that they can + * prepare to death, when device is still operating. + */ call_netdevice_notifiers(NETDEV_GOING_DOWN, dev); clear_bit(__LINK_STATE_START, &dev->state); @@ -1234,7 +1272,15 @@ static int __dev_close_many(struct list_head *head) if (ops->ndo_stop) ops->ndo_stop(dev); + /* + * Device is now down. + */ + dev->flags &= ~IFF_UP; + + /* + * Shutdown NET_DMA + */ net_dmaengine_put(); } @@ -1263,6 +1309,9 @@ static int dev_close_many(struct list_head *head) __dev_close_many(head); + /* + * Tell people we are down + */ list_for_each_entry(dev, head, unreg_list) { rtmsg_ifinfo(RTM_NEWLINK, dev, IFF_UP|IFF_RUNNING); call_netdevice_notifiers(NETDEV_DOWN, dev); @@ -1322,6 +1371,11 @@ EXPORT_SYMBOL(dev_disable_lro); static int dev_boot_phase = 1; +/* + * Device change register/unregister. These are not inline or static + * as we export them to the world. + */ + /** * register_netdevice_notifier - register a network notifier block * @nb: notifier @@ -1423,7 +1477,6 @@ int call_netdevice_notifiers(unsigned long val, struct net_device *dev) ASSERT_RTNL(); return raw_notifier_call_chain(&netdev_chain, val, dev); } -EXPORT_SYMBOL(call_netdevice_notifiers); /* When > 0 there are consumers of rx skb time stamps */ static atomic_t netstamp_needed = ATOMIC_INIT(0); diff --git a/trunk/net/core/ethtool.c b/trunk/net/core/ethtool.c index 74ead9eca126..24bd57493c0d 100644 --- a/trunk/net/core/ethtool.c +++ b/trunk/net/core/ethtool.c @@ -141,24 +141,9 @@ u32 ethtool_op_get_flags(struct net_device *dev) } EXPORT_SYMBOL(ethtool_op_get_flags); -/* Check if device can enable (or disable) particular feature coded in "data" - * argument. Flags "supported" describe features that can be toggled by device. - * If feature can not be toggled, it state (enabled or disabled) must match - * hardcoded device features state, otherwise flags are marked as invalid. - */ -bool ethtool_invalid_flags(struct net_device *dev, u32 data, u32 supported) -{ - u32 features = dev->features & flags_dup_features; - /* "data" can contain only flags_dup_features bits, - * see __ethtool_set_flags */ - - return (features & ~supported) != (data & ~supported); -} -EXPORT_SYMBOL(ethtool_invalid_flags); - int ethtool_op_set_flags(struct net_device *dev, u32 data, u32 supported) { - if (ethtool_invalid_flags(dev, data, supported)) + if (data & ~supported) return -EINVAL; dev->features = ((dev->features & ~flags_dup_features) | diff --git a/trunk/net/ipv4/fib_trie.c b/trunk/net/ipv4/fib_trie.c index b92c86f6e9b3..90a3ff605591 100644 --- a/trunk/net/ipv4/fib_trie.c +++ b/trunk/net/ipv4/fib_trie.c @@ -1365,9 +1365,9 @@ static int check_leaf(struct fib_table *tb, struct trie *t, struct leaf *l, err = fib_props[fa->fa_type].error; if (err) { #ifdef CONFIG_IP_FIB_TRIE_STATS - t->stats.semantic_match_passed++; + t->stats.semantic_match_miss++; #endif - return err; + return 1; } if (fi->fib_flags & RTNH_F_DEAD) continue; diff --git a/trunk/net/ipv4/ip_options.c b/trunk/net/ipv4/ip_options.c index 28a736f3442f..1906fa35860c 100644 --- a/trunk/net/ipv4/ip_options.c +++ b/trunk/net/ipv4/ip_options.c @@ -140,11 +140,11 @@ int ip_options_echo(struct ip_options * dopt, struct sk_buff * skb) } else { dopt->ts_needtime = 0; - if (soffset + 7 <= optlen) { + if (soffset + 8 <= optlen) { __be32 addr; - memcpy(&addr, dptr+soffset-1, 4); - if (inet_addr_type(dev_net(skb_dst(skb)->dev), addr) != RTN_UNICAST) { + memcpy(&addr, sptr+soffset-1, 4); + if (inet_addr_type(dev_net(skb_dst(skb)->dev), addr) != RTN_LOCAL) { dopt->ts_needtime = 1; soffset += 8; } diff --git a/trunk/net/ipv4/raw.c b/trunk/net/ipv4/raw.c index 2d3c72e5bbbf..e837ffd3edc3 100644 --- a/trunk/net/ipv4/raw.c +++ b/trunk/net/ipv4/raw.c @@ -569,7 +569,6 @@ static int raw_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, rt = ip_route_output_flow(sock_net(sk), &fl4, sk); if (IS_ERR(rt)) { err = PTR_ERR(rt); - rt = NULL; goto done; } } diff --git a/trunk/net/ipv6/ip6mr.c b/trunk/net/ipv6/ip6mr.c index 29e48593bf22..7ff0343e05c7 100644 --- a/trunk/net/ipv6/ip6mr.c +++ b/trunk/net/ipv6/ip6mr.c @@ -663,7 +663,7 @@ static int pim6_rcv(struct sk_buff *skb) skb_pull(skb, (u8 *)encap - skb->data); skb_reset_network_header(skb); skb->protocol = htons(ETH_P_IPV6); - skb->ip_summed = CHECKSUM_NONE; + skb->ip_summed = 0; skb->pkt_type = PACKET_HOST; skb_tunnel_rx(skb, reg_dev); diff --git a/trunk/net/irda/iriap.c b/trunk/net/irda/iriap.c index 36477538cea8..5b743bdd89ba 100644 --- a/trunk/net/irda/iriap.c +++ b/trunk/net/irda/iriap.c @@ -656,16 +656,10 @@ static void iriap_getvaluebyclass_indication(struct iriap_cb *self, n = 1; name_len = fp[n++]; - - IRDA_ASSERT(name_len < IAS_MAX_CLASSNAME + 1, return;); - memcpy(name, fp+n, name_len); n+=name_len; name[name_len] = '\0'; attr_len = fp[n++]; - - IRDA_ASSERT(attr_len < IAS_MAX_ATTRIBNAME + 1, return;); - memcpy(attr, fp+n, attr_len); n+=attr_len; attr[attr_len] = '\0'; diff --git a/trunk/net/irda/irnet/irnet_ppp.c b/trunk/net/irda/irnet/irnet_ppp.c index 2bb2beb6a373..7c567b8aa89a 100644 --- a/trunk/net/irda/irnet/irnet_ppp.c +++ b/trunk/net/irda/irnet/irnet_ppp.c @@ -105,9 +105,6 @@ irnet_ctrl_write(irnet_socket * ap, while(isspace(start[length - 1])) length--; - DABORT(length < 5 || length > NICKNAME_MAX_LEN + 5, - -EINVAL, CTRL_ERROR, "Invalid nickname.\n"); - /* Copy the name for later reuse */ memcpy(ap->rname, start + 5, length - 5); ap->rname[length - 5] = '\0'; diff --git a/trunk/net/rose/af_rose.c b/trunk/net/rose/af_rose.c index a80aef6e3d1f..5ee0c62046a0 100644 --- a/trunk/net/rose/af_rose.c +++ b/trunk/net/rose/af_rose.c @@ -978,7 +978,7 @@ int rose_rx_call_request(struct sk_buff *skb, struct net_device *dev, struct ros struct sock *make; struct rose_sock *make_rose; struct rose_facilities_struct facilities; - int n; + int n, len; skb->sk = NULL; /* Initially we don't know who it's for */ @@ -987,9 +987,9 @@ int rose_rx_call_request(struct sk_buff *skb, struct net_device *dev, struct ros */ memset(&facilities, 0x00, sizeof(struct rose_facilities_struct)); - if (!rose_parse_facilities(skb->data + ROSE_CALL_REQ_FACILITIES_OFF, - skb->len - ROSE_CALL_REQ_FACILITIES_OFF, - &facilities)) { + len = (((skb->data[3] >> 4) & 0x0F) + 1) >> 1; + len += (((skb->data[3] >> 0) & 0x0F) + 1) >> 1; + if (!rose_parse_facilities(skb->data + len + 4, &facilities)) { rose_transmit_clear_request(neigh, lci, ROSE_INVALID_FACILITY, 76); return 0; } diff --git a/trunk/net/rose/rose_loopback.c b/trunk/net/rose/rose_loopback.c index 344456206b70..ae4a9d99aec7 100644 --- a/trunk/net/rose/rose_loopback.c +++ b/trunk/net/rose/rose_loopback.c @@ -73,20 +73,9 @@ static void rose_loopback_timer(unsigned long param) unsigned int lci_i, lci_o; while ((skb = skb_dequeue(&loopback_queue)) != NULL) { - if (skb->len < ROSE_MIN_LEN) { - kfree_skb(skb); - continue; - } lci_i = ((skb->data[0] << 8) & 0xF00) + ((skb->data[1] << 0) & 0x0FF); frametype = skb->data[2]; - if (frametype == ROSE_CALL_REQUEST && - (skb->len <= ROSE_CALL_REQ_FACILITIES_OFF || - skb->data[ROSE_CALL_REQ_ADDR_LEN_OFF] != - ROSE_CALL_REQ_ADDR_LEN_VAL)) { - kfree_skb(skb); - continue; - } - dest = (rose_address *)(skb->data + ROSE_CALL_REQ_DEST_ADDR_OFF); + dest = (rose_address *)(skb->data + 4); lci_o = ROSE_DEFAULT_MAXVC + 1 - lci_i; skb_reset_transport_header(skb); diff --git a/trunk/net/rose/rose_route.c b/trunk/net/rose/rose_route.c index 08dcd2f29cdc..88a77e90e7e8 100644 --- a/trunk/net/rose/rose_route.c +++ b/trunk/net/rose/rose_route.c @@ -861,7 +861,7 @@ int rose_route_frame(struct sk_buff *skb, ax25_cb *ax25) unsigned int lci, new_lci; unsigned char cause, diagnostic; struct net_device *dev; - int res = 0; + int len, res = 0; char buf[11]; #if 0 @@ -869,17 +869,10 @@ int rose_route_frame(struct sk_buff *skb, ax25_cb *ax25) return res; #endif - if (skb->len < ROSE_MIN_LEN) - return res; frametype = skb->data[2]; lci = ((skb->data[0] << 8) & 0xF00) + ((skb->data[1] << 0) & 0x0FF); - if (frametype == ROSE_CALL_REQUEST && - (skb->len <= ROSE_CALL_REQ_FACILITIES_OFF || - skb->data[ROSE_CALL_REQ_ADDR_LEN_OFF] != - ROSE_CALL_REQ_ADDR_LEN_VAL)) - return res; - src_addr = (rose_address *)(skb->data + ROSE_CALL_REQ_SRC_ADDR_OFF); - dest_addr = (rose_address *)(skb->data + ROSE_CALL_REQ_DEST_ADDR_OFF); + src_addr = (rose_address *)(skb->data + 9); + dest_addr = (rose_address *)(skb->data + 4); spin_lock_bh(&rose_neigh_list_lock); spin_lock_bh(&rose_route_list_lock); @@ -1017,11 +1010,12 @@ int rose_route_frame(struct sk_buff *skb, ax25_cb *ax25) goto out; } + len = (((skb->data[3] >> 4) & 0x0F) + 1) >> 1; + len += (((skb->data[3] >> 0) & 0x0F) + 1) >> 1; + memset(&facilities, 0x00, sizeof(struct rose_facilities_struct)); - if (!rose_parse_facilities(skb->data + ROSE_CALL_REQ_FACILITIES_OFF, - skb->len - ROSE_CALL_REQ_FACILITIES_OFF, - &facilities)) { + if (!rose_parse_facilities(skb->data + len + 4, &facilities)) { rose_transmit_clear_request(rose_neigh, lci, ROSE_INVALID_FACILITY, 76); goto out; } diff --git a/trunk/net/rose/rose_subr.c b/trunk/net/rose/rose_subr.c index f6c71caa94b9..1734abba26a2 100644 --- a/trunk/net/rose/rose_subr.c +++ b/trunk/net/rose/rose_subr.c @@ -142,7 +142,7 @@ void rose_write_internal(struct sock *sk, int frametype) *dptr++ = ROSE_GFI | lci1; *dptr++ = lci2; *dptr++ = frametype; - *dptr++ = ROSE_CALL_REQ_ADDR_LEN_VAL; + *dptr++ = 0xAA; memcpy(dptr, &rose->dest_addr, ROSE_ADDR_LEN); dptr += ROSE_ADDR_LEN; memcpy(dptr, &rose->source_addr, ROSE_ADDR_LEN); @@ -246,16 +246,12 @@ static int rose_parse_national(unsigned char *p, struct rose_facilities_struct * do { switch (*p & 0xC0) { case 0x00: - if (len < 2) - return -1; p += 2; n += 2; len -= 2; break; case 0x40: - if (len < 3) - return -1; if (*p == FAC_NATIONAL_RAND) facilities->rand = ((p[1] << 8) & 0xFF00) + ((p[2] << 0) & 0x00FF); p += 3; @@ -264,61 +260,40 @@ static int rose_parse_national(unsigned char *p, struct rose_facilities_struct * break; case 0x80: - if (len < 4) - return -1; p += 4; n += 4; len -= 4; break; case 0xC0: - if (len < 2) - return -1; l = p[1]; - if (len < 2 + l) - return -1; if (*p == FAC_NATIONAL_DEST_DIGI) { if (!fac_national_digis_received) { - if (l < AX25_ADDR_LEN) - return -1; memcpy(&facilities->source_digis[0], p + 2, AX25_ADDR_LEN); facilities->source_ndigis = 1; } } else if (*p == FAC_NATIONAL_SRC_DIGI) { if (!fac_national_digis_received) { - if (l < AX25_ADDR_LEN) - return -1; memcpy(&facilities->dest_digis[0], p + 2, AX25_ADDR_LEN); facilities->dest_ndigis = 1; } } else if (*p == FAC_NATIONAL_FAIL_CALL) { - if (l < AX25_ADDR_LEN) - return -1; memcpy(&facilities->fail_call, p + 2, AX25_ADDR_LEN); } else if (*p == FAC_NATIONAL_FAIL_ADD) { - if (l < 1 + ROSE_ADDR_LEN) - return -1; memcpy(&facilities->fail_addr, p + 3, ROSE_ADDR_LEN); } else if (*p == FAC_NATIONAL_DIGIS) { - if (l % AX25_ADDR_LEN) - return -1; fac_national_digis_received = 1; facilities->source_ndigis = 0; facilities->dest_ndigis = 0; for (pt = p + 2, lg = 0 ; lg < l ; pt += AX25_ADDR_LEN, lg += AX25_ADDR_LEN) { - if (pt[6] & AX25_HBIT) { - if (facilities->dest_ndigis >= ROSE_MAX_DIGIS) - return -1; + if (pt[6] & AX25_HBIT) memcpy(&facilities->dest_digis[facilities->dest_ndigis++], pt, AX25_ADDR_LEN); - } else { - if (facilities->source_ndigis >= ROSE_MAX_DIGIS) - return -1; + else memcpy(&facilities->source_digis[facilities->source_ndigis++], pt, AX25_ADDR_LEN); - } } } p += l + 2; @@ -339,38 +314,25 @@ static int rose_parse_ccitt(unsigned char *p, struct rose_facilities_struct *fac do { switch (*p & 0xC0) { case 0x00: - if (len < 2) - return -1; p += 2; n += 2; len -= 2; break; case 0x40: - if (len < 3) - return -1; p += 3; n += 3; len -= 3; break; case 0x80: - if (len < 4) - return -1; p += 4; n += 4; len -= 4; break; case 0xC0: - if (len < 2) - return -1; l = p[1]; - - /* Prevent overflows*/ - if (l < 10 || l > 20) - return -1; - if (*p == FAC_CCITT_DEST_NSAP) { memcpy(&facilities->source_addr, p + 7, ROSE_ADDR_LEN); memcpy(callsign, p + 12, l - 10); @@ -393,44 +355,45 @@ static int rose_parse_ccitt(unsigned char *p, struct rose_facilities_struct *fac return n; } -int rose_parse_facilities(unsigned char *p, unsigned packet_len, +int rose_parse_facilities(unsigned char *p, struct rose_facilities_struct *facilities) { int facilities_len, len; facilities_len = *p++; - if (facilities_len == 0 || (unsigned)facilities_len > packet_len) + if (facilities_len == 0) return 0; - while (facilities_len >= 3 && *p == 0x00) { - facilities_len--; - p++; - - switch (*p) { - case FAC_NATIONAL: /* National */ - len = rose_parse_national(p + 1, facilities, facilities_len - 1); - break; - - case FAC_CCITT: /* CCITT */ - len = rose_parse_ccitt(p + 1, facilities, facilities_len - 1); - break; - - default: - printk(KERN_DEBUG "ROSE: rose_parse_facilities - unknown facilities family %02X\n", *p); - len = 1; - break; - } - - if (len < 0) - return 0; - if (WARN_ON(len >= facilities_len)) - return 0; - facilities_len -= len + 1; - p += len + 1; + while (facilities_len > 0) { + if (*p == 0x00) { + facilities_len--; + p++; + + switch (*p) { + case FAC_NATIONAL: /* National */ + len = rose_parse_national(p + 1, facilities, facilities_len - 1); + facilities_len -= len + 1; + p += len + 1; + break; + + case FAC_CCITT: /* CCITT */ + len = rose_parse_ccitt(p + 1, facilities, facilities_len - 1); + facilities_len -= len + 1; + p += len + 1; + break; + + default: + printk(KERN_DEBUG "ROSE: rose_parse_facilities - unknown facilities family %02X\n", *p); + facilities_len--; + p++; + break; + } + } else + break; /* Error in facilities format */ } - return facilities_len == 0; + return 1; } static int rose_create_facilities(unsigned char *buffer, struct rose_sock *rose) diff --git a/trunk/net/sunrpc/sched.c b/trunk/net/sunrpc/sched.c index 6b43ee7221d5..ffb687671da0 100644 --- a/trunk/net/sunrpc/sched.c +++ b/trunk/net/sunrpc/sched.c @@ -860,10 +860,8 @@ static void rpc_release_resources_task(struct rpc_task *task) { if (task->tk_rqstp) xprt_release(task); - if (task->tk_msg.rpc_cred) { + if (task->tk_msg.rpc_cred) put_rpccred(task->tk_msg.rpc_cred); - task->tk_msg.rpc_cred = NULL; - } rpc_task_release_client(task); } diff --git a/trunk/net/xfrm/xfrm_input.c b/trunk/net/xfrm/xfrm_input.c index a026b0ef2443..872065ca7f8c 100644 --- a/trunk/net/xfrm/xfrm_input.c +++ b/trunk/net/xfrm/xfrm_input.c @@ -173,7 +173,7 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type) goto drop_unlock; } - if (x->repl->check(x, skb, seq)) { + if (x->props.replay_window && x->repl->check(x, skb, seq)) { XFRM_INC_STATS(net, LINUX_MIB_XFRMINSTATESEQERROR); goto drop_unlock; } @@ -190,8 +190,6 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type) XFRM_SKB_CB(skb)->seq.input.low = seq; XFRM_SKB_CB(skb)->seq.input.hi = seq_hi; - skb_dst_force(skb); - nexthdr = x->type->input(x, skb); if (nexthdr == -EINPROGRESS) diff --git a/trunk/net/xfrm/xfrm_output.c b/trunk/net/xfrm/xfrm_output.c index 47bacd8c0250..1aba03f449cc 100644 --- a/trunk/net/xfrm/xfrm_output.c +++ b/trunk/net/xfrm/xfrm_output.c @@ -78,8 +78,6 @@ static int xfrm_output_one(struct sk_buff *skb, int err) spin_unlock_bh(&x->lock); - skb_dst_force(skb); - err = x->type->output(x, skb); if (err == -EINPROGRESS) goto out_exit; @@ -96,7 +94,7 @@ static int xfrm_output_one(struct sk_buff *skb, int err) err = -EHOSTUNREACH; goto error_nolock; } - skb_dst_set(skb, dst); + skb_dst_set(skb, dst_clone(dst)); x = dst->xfrm; } while (x && !(x->outer_mode->flags & XFRM_MODE_FLAG_TUNNEL)); diff --git a/trunk/net/xfrm/xfrm_replay.c b/trunk/net/xfrm/xfrm_replay.c index f218385950ca..2f5be5b15740 100644 --- a/trunk/net/xfrm/xfrm_replay.c +++ b/trunk/net/xfrm/xfrm_replay.c @@ -118,9 +118,6 @@ static int xfrm_replay_check(struct xfrm_state *x, u32 diff; u32 seq = ntohl(net_seq); - if (!x->props.replay_window) - return 0; - if (unlikely(seq == 0)) goto err; @@ -196,14 +193,9 @@ static int xfrm_replay_check_bmp(struct xfrm_state *x, { unsigned int bitnr, nr; struct xfrm_replay_state_esn *replay_esn = x->replay_esn; - u32 pos; u32 seq = ntohl(net_seq); u32 diff = replay_esn->seq - seq; - - if (!replay_esn->replay_window) - return 0; - - pos = (replay_esn->seq - 1) % replay_esn->replay_window; + u32 pos = (replay_esn->seq - 1) % replay_esn->replay_window; if (unlikely(seq == 0)) goto err; @@ -381,17 +373,12 @@ static int xfrm_replay_check_esn(struct xfrm_state *x, unsigned int bitnr, nr; u32 diff; struct xfrm_replay_state_esn *replay_esn = x->replay_esn; - u32 pos; u32 seq = ntohl(net_seq); + u32 pos = (replay_esn->seq - 1) % replay_esn->replay_window; u32 wsize = replay_esn->replay_window; u32 top = replay_esn->seq; u32 bottom = top - wsize + 1; - if (!wsize) - return 0; - - pos = (replay_esn->seq - 1) % replay_esn->replay_window; - if (unlikely(seq == 0 && replay_esn->seq_hi == 0 && (replay_esn->seq < replay_esn->replay_window - 1))) goto err; diff --git a/trunk/net/xfrm/xfrm_state.c b/trunk/net/xfrm/xfrm_state.c index dd78536d40de..f83a3d1da81b 100644 --- a/trunk/net/xfrm/xfrm_state.c +++ b/trunk/net/xfrm/xfrm_state.c @@ -1181,12 +1181,6 @@ static struct xfrm_state *xfrm_state_clone(struct xfrm_state *orig, int *errp) goto error; } - if (orig->replay_esn) { - err = xfrm_replay_clone(x, orig); - if (err) - goto error; - } - memcpy(&x->mark, &orig->mark, sizeof(x->mark)); err = xfrm_init_state(x); diff --git a/trunk/net/xfrm/xfrm_user.c b/trunk/net/xfrm/xfrm_user.c index 3d15d3e1b2c4..fc152d28753c 100644 --- a/trunk/net/xfrm/xfrm_user.c +++ b/trunk/net/xfrm/xfrm_user.c @@ -127,9 +127,6 @@ static inline int verify_replay(struct xfrm_usersa_info *p, if (!rt) return 0; - if (p->id.proto != IPPROTO_ESP) - return -EINVAL; - if (p->replay_window != 0) return -EINVAL; @@ -363,23 +360,6 @@ static int attach_aead(struct xfrm_algo_aead **algpp, u8 *props, return 0; } -static inline int xfrm_replay_verify_len(struct xfrm_replay_state_esn *replay_esn, - struct nlattr *rp) -{ - struct xfrm_replay_state_esn *up; - - if (!replay_esn || !rp) - return 0; - - up = nla_data(rp); - - if (xfrm_replay_state_esn_len(replay_esn) != - xfrm_replay_state_esn_len(up)) - return -EINVAL; - - return 0; -} - static int xfrm_alloc_replay_state_esn(struct xfrm_replay_state_esn **replay_esn, struct xfrm_replay_state_esn **preplay_esn, struct nlattr *rta) @@ -1786,10 +1766,6 @@ static int xfrm_new_ae(struct sk_buff *skb, struct nlmsghdr *nlh, if (x->km.state != XFRM_STATE_VALID) goto out; - err = xfrm_replay_verify_len(x->replay_esn, rp); - if (err) - goto out; - spin_lock_bh(&x->lock); xfrm_update_ae_params(x, attrs); spin_unlock_bh(&x->lock); diff --git a/trunk/security/selinux/ss/services.c b/trunk/security/selinux/ss/services.c index ea7c01f4a2bf..3e7544d2a07b 100644 --- a/trunk/security/selinux/ss/services.c +++ b/trunk/security/selinux/ss/services.c @@ -213,7 +213,7 @@ static u16 map_class(u16 pol_value) return i; } - return SECCLASS_NULL; + return pol_value; } static void map_decision(u16 tclass, struct av_decision *avd, diff --git a/trunk/sound/core/init.c b/trunk/sound/core/init.c index a0080aa45ae9..3e65da21a08c 100644 --- a/trunk/sound/core/init.c +++ b/trunk/sound/core/init.c @@ -848,7 +848,6 @@ int snd_card_file_add(struct snd_card *card, struct file *file) return -ENOMEM; mfile->file = file; mfile->disconnected_f_op = NULL; - INIT_LIST_HEAD(&mfile->shutdown_list); spin_lock(&card->files_lock); if (card->shutdown) { spin_unlock(&card->files_lock); @@ -884,9 +883,6 @@ int snd_card_file_remove(struct snd_card *card, struct file *file) list_for_each_entry(mfile, &card->files_list, list) { if (mfile->file == file) { list_del(&mfile->list); - spin_lock(&shutdown_lock); - list_del(&mfile->shutdown_list); - spin_unlock(&shutdown_lock); if (mfile->disconnected_f_op) fops_put(mfile->disconnected_f_op); found = mfile; diff --git a/trunk/sound/core/pcm_native.c b/trunk/sound/core/pcm_native.c index fe5c8036beba..ae42b6509ce4 100644 --- a/trunk/sound/core/pcm_native.c +++ b/trunk/sound/core/pcm_native.c @@ -3201,6 +3201,15 @@ int snd_pcm_lib_mmap_iomem(struct snd_pcm_substream *substream, EXPORT_SYMBOL(snd_pcm_lib_mmap_iomem); #endif /* SNDRV_PCM_INFO_MMAP */ +/* mmap callback with pgprot_noncached */ +int snd_pcm_lib_mmap_noncached(struct snd_pcm_substream *substream, + struct vm_area_struct *area) +{ + area->vm_page_prot = pgprot_noncached(area->vm_page_prot); + return snd_pcm_default_mmap(substream, area); +} +EXPORT_SYMBOL(snd_pcm_lib_mmap_noncached); + /* * mmap DMA buffer */ diff --git a/trunk/sound/oss/dev_table.h b/trunk/sound/oss/dev_table.h index 0199a317c5a9..b7617bee6388 100644 --- a/trunk/sound/oss/dev_table.h +++ b/trunk/sound/oss/dev_table.h @@ -271,7 +271,7 @@ struct synth_operations void (*reset) (int dev); void (*hw_control) (int dev, unsigned char *event); int (*load_patch) (int dev, int format, const char __user *addr, - int count, int pmgr_flag); + int offs, int count, int pmgr_flag); void (*aftertouch) (int dev, int voice, int pressure); void (*controller) (int dev, int voice, int ctrl_num, int value); void (*panning) (int dev, int voice, int value); diff --git a/trunk/sound/oss/midi_synth.c b/trunk/sound/oss/midi_synth.c index 2292c230d7e6..3c09374ea5bf 100644 --- a/trunk/sound/oss/midi_synth.c +++ b/trunk/sound/oss/midi_synth.c @@ -476,7 +476,7 @@ EXPORT_SYMBOL(midi_synth_hw_control); int midi_synth_load_patch(int dev, int format, const char __user *addr, - int count, int pmgr_flag) + int offs, int count, int pmgr_flag) { int orig_dev = synth_devs[dev]->midi_dev; @@ -491,29 +491,33 @@ midi_synth_load_patch(int dev, int format, const char __user *addr, if (!prefix_cmd(orig_dev, 0xf0)) return 0; - /* Invalid patch format */ if (format != SYSEX_PATCH) + { +/* printk("MIDI Error: Invalid patch format (key) 0x%x\n", format);*/ return -EINVAL; - - /* Patch header too short */ + } if (count < hdr_size) + { +/* printk("MIDI Error: Patch header too short\n");*/ return -EINVAL; - + } count -= hdr_size; /* - * Copy the header from user space + * Copy the header from user space but ignore the first bytes which have + * been transferred already. */ - if (copy_from_user(&sysex, addr, hdr_size)) + if(copy_from_user(&((char *) &sysex)[offs], &(addr)[offs], hdr_size - offs)) return -EFAULT; - - /* Sysex record too short */ - if ((unsigned)count < (unsigned)sysex.len) + + if (count < sysex.len) + { +/* printk(KERN_WARNING "MIDI Warning: Sysex record too short (%d<%d)\n", count, (int) sysex.len);*/ sysex.len = count; - - left = sysex.len; - src_offs = 0; + } + left = sysex.len; + src_offs = 0; for (i = 0; i < left && !signal_pending(current); i++) { diff --git a/trunk/sound/oss/midi_synth.h b/trunk/sound/oss/midi_synth.h index b64ddd6c4abc..6bc9d00bc77c 100644 --- a/trunk/sound/oss/midi_synth.h +++ b/trunk/sound/oss/midi_synth.h @@ -8,7 +8,7 @@ int midi_synth_open (int dev, int mode); void midi_synth_close (int dev); void midi_synth_hw_control (int dev, unsigned char *event); int midi_synth_load_patch (int dev, int format, const char __user * addr, - int count, int pmgr_flag); + int offs, int count, int pmgr_flag); void midi_synth_panning (int dev, int channel, int pressure); void midi_synth_aftertouch (int dev, int channel, int pressure); void midi_synth_controller (int dev, int channel, int ctrl_num, int value); diff --git a/trunk/sound/oss/opl3.c b/trunk/sound/oss/opl3.c index 407cd677950b..938c48c43585 100644 --- a/trunk/sound/oss/opl3.c +++ b/trunk/sound/oss/opl3.c @@ -820,7 +820,7 @@ static void opl3_hw_control(int dev, unsigned char *event) } static int opl3_load_patch(int dev, int format, const char __user *addr, - int count, int pmgr_flag) + int offs, int count, int pmgr_flag) { struct sbi_instrument ins; @@ -830,7 +830,11 @@ static int opl3_load_patch(int dev, int format, const char __user *addr, return -EINVAL; } - if (copy_from_user(&ins, addr, sizeof(ins))) + /* + * What the fuck is going on here? We leave junk in the beginning + * of ins and then check the field pretty close to that beginning? + */ + if(copy_from_user(&((char *) &ins)[offs], addr + offs, sizeof(ins) - offs)) return -EFAULT; if (ins.channel < 0 || ins.channel >= SBFM_MAXINSTR) @@ -845,10 +849,6 @@ static int opl3_load_patch(int dev, int format, const char __user *addr, static void opl3_panning(int dev, int voice, int value) { - - if (voice < 0 || voice >= devc->nr_voice) - return; - devc->voc[voice].panning = value; } @@ -1066,15 +1066,8 @@ static int opl3_alloc_voice(int dev, int chn, int note, struct voice_alloc_info static void opl3_setup_voice(int dev, int voice, int chn) { - struct channel_info *info; - - if (voice < 0 || voice >= devc->nr_voice) - return; - - if (chn < 0 || chn > 15) - return; - - info = &synth_devs[dev]->chn_info[chn]; + struct channel_info *info = + &synth_devs[dev]->chn_info[chn]; opl3_set_instr(dev, voice, info->pgm_num); diff --git a/trunk/sound/oss/sequencer.c b/trunk/sound/oss/sequencer.c index 30bcfe470f83..5ea1098ac427 100644 --- a/trunk/sound/oss/sequencer.c +++ b/trunk/sound/oss/sequencer.c @@ -241,7 +241,7 @@ int sequencer_write(int dev, struct file *file, const char __user *buf, int coun return -ENXIO; fmt = (*(short *) &event_rec[0]) & 0xffff; - err = synth_devs[dev]->load_patch(dev, fmt, buf + p, c, 0); + err = synth_devs[dev]->load_patch(dev, fmt, buf, p + 4, c, 0); if (err < 0) return err; diff --git a/trunk/sound/pci/asihpi/asihpi.c b/trunk/sound/pci/asihpi/asihpi.c index f53a31e939c1..0ac1f98d91a1 100644 --- a/trunk/sound/pci/asihpi/asihpi.c +++ b/trunk/sound/pci/asihpi/asihpi.c @@ -22,6 +22,21 @@ * for any purpose including commercial applications. */ +/* >0: print Hw params, timer vars. >1: print stream write/copy sizes */ +#define REALLY_VERBOSE_LOGGING 0 + +#if REALLY_VERBOSE_LOGGING +#define VPRINTK1 snd_printd +#else +#define VPRINTK1(...) +#endif + +#if REALLY_VERBOSE_LOGGING > 1 +#define VPRINTK2 snd_printd +#else +#define VPRINTK2(...) +#endif + #include "hpi_internal.h" #include "hpimsginit.h" #include "hpioctl.h" @@ -42,25 +57,11 @@ #include #include + MODULE_LICENSE("GPL"); MODULE_AUTHOR("AudioScience inc. "); MODULE_DESCRIPTION("AudioScience ALSA ASI5000 ASI6000 ASI87xx ASI89xx"); -#if defined CONFIG_SND_DEBUG_VERBOSE -/** - * snd_printddd - very verbose debug printk - * @format: format string - * - * Works like snd_printk() for debugging purposes. - * Ignored when CONFIG_SND_DEBUG_VERBOSE is not set. - * Must set snd module debug parameter to 3 to enable at runtime. - */ -#define snd_printddd(format, args...) \ - __snd_printk(3, __FILE__, __LINE__, format, ##args) -#else -#define snd_printddd(format, args...) do { } while (0) -#endif - static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* index 0-MAX */ static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; @@ -288,6 +289,7 @@ static u16 handle_error(u16 err, int line, char *filename) #define hpi_handle_error(x) handle_error(x, __LINE__, __FILE__) /***************************** GENERAL PCM ****************/ +#if REALLY_VERBOSE_LOGGING static void print_hwparams(struct snd_pcm_hw_params *p) { snd_printd("HWPARAMS \n"); @@ -302,6 +304,9 @@ static void print_hwparams(struct snd_pcm_hw_params *p) snd_printd("periods %d \n", params_periods(p)); snd_printd("buffer_size %d \n", params_buffer_size(p)); } +#else +#define print_hwparams(x) +#endif static snd_pcm_format_t hpi_to_alsa_formats[] = { -1, /* INVALID */ @@ -376,13 +381,13 @@ static void snd_card_asihpi_pcm_samplerates(struct snd_card_asihpi *asihpi, "No local sampleclock, err %d\n", err); } - for (idx = -1; idx < 100; idx++) { - if (idx == -1) { - if (hpi_sample_clock_get_sample_rate(h_control, - &sample_rate)) - continue; - } else if (hpi_sample_clock_query_local_rate(h_control, - idx, &sample_rate)) { + for (idx = 0; idx < 100; idx++) { + if (hpi_sample_clock_query_local_rate( + h_control, idx, &sample_rate)) { + if (!idx) + snd_printk(KERN_ERR + "Local rate query failed\n"); + break; } @@ -435,6 +440,8 @@ static void snd_card_asihpi_pcm_samplerates(struct snd_card_asihpi *asihpi, } } + /* printk(KERN_INFO "Supported rates %X %d %d\n", + rates, rate_min, rate_max); */ pcmhw->rates = rates; pcmhw->rate_min = rate_min; pcmhw->rate_max = rate_max; @@ -459,7 +466,7 @@ static int snd_card_asihpi_pcm_hw_params(struct snd_pcm_substream *substream, if (err) return err; - snd_printdd("format %d, %d chans, %d_hz\n", + VPRINTK1(KERN_INFO "format %d, %d chans, %d_hz\n", format, params_channels(params), params_rate(params)); @@ -482,12 +489,13 @@ static int snd_card_asihpi_pcm_hw_params(struct snd_pcm_substream *substream, err = hpi_stream_host_buffer_attach(dpcm->h_stream, params_buffer_bytes(params), runtime->dma_addr); if (err == 0) { - snd_printdd( + VPRINTK1(KERN_INFO "stream_host_buffer_attach succeeded %u %lu\n", params_buffer_bytes(params), (unsigned long)runtime->dma_addr); } else { - snd_printd("stream_host_buffer_attach error %d\n", + snd_printd(KERN_INFO + "stream_host_buffer_attach error %d\n", err); return -ENOMEM; } @@ -496,7 +504,7 @@ static int snd_card_asihpi_pcm_hw_params(struct snd_pcm_substream *substream, &dpcm->hpi_buffer_attached, NULL, NULL, NULL); - snd_printdd("stream_host_buffer_attach status 0x%x\n", + VPRINTK1(KERN_INFO "stream_host_buffer_attach status 0x%x\n", dpcm->hpi_buffer_attached); } bytes_per_sec = params_rate(params) * params_channels(params); @@ -509,7 +517,7 @@ static int snd_card_asihpi_pcm_hw_params(struct snd_pcm_substream *substream, dpcm->bytes_per_sec = bytes_per_sec; dpcm->buffer_bytes = params_buffer_bytes(params); dpcm->period_bytes = params_period_bytes(params); - snd_printdd("buffer_bytes=%d, period_bytes=%d, bps=%d\n", + VPRINTK1(KERN_INFO "buffer_bytes=%d, period_bytes=%d, bps=%d\n", dpcm->buffer_bytes, dpcm->period_bytes, bytes_per_sec); return 0; @@ -565,7 +573,7 @@ static int snd_card_asihpi_trigger(struct snd_pcm_substream *substream, struct snd_pcm_substream *s; u16 e; - snd_printdd("%c%d trigger\n", + VPRINTK1(KERN_INFO "%c%d trigger\n", SCHR(substream->stream), substream->number); switch (cmd) { case SNDRV_PCM_TRIGGER_START: @@ -589,7 +597,7 @@ static int snd_card_asihpi_trigger(struct snd_pcm_substream *substream, * data?? */ unsigned int preload = ds->period_bytes * 1; - snd_printddd("%d preload x%x\n", s->number, preload); + VPRINTK2(KERN_INFO "%d preload x%x\n", s->number, preload); hpi_handle_error(hpi_outstream_write_buf( ds->h_stream, &runtime->dma_area[0], @@ -599,7 +607,7 @@ static int snd_card_asihpi_trigger(struct snd_pcm_substream *substream, } if (card->support_grouping) { - snd_printdd("\t%c%d group\n", + VPRINTK1(KERN_INFO "\t%c%d group\n", SCHR(s->stream), s->number); e = hpi_stream_group_add( @@ -614,7 +622,7 @@ static int snd_card_asihpi_trigger(struct snd_pcm_substream *substream, } else break; } - snd_printdd("start\n"); + VPRINTK1(KERN_INFO "start\n"); /* start the master stream */ snd_card_asihpi_pcm_timer_start(substream); if ((substream->stream == SNDRV_PCM_STREAM_CAPTURE) || @@ -636,14 +644,14 @@ static int snd_card_asihpi_trigger(struct snd_pcm_substream *substream, s->runtime->status->state = SNDRV_PCM_STATE_SETUP; if (card->support_grouping) { - snd_printdd("\t%c%d group\n", + VPRINTK1(KERN_INFO "\t%c%d group\n", SCHR(s->stream), s->number); snd_pcm_trigger_done(s, substream); } else break; } - snd_printdd("stop\n"); + VPRINTK1(KERN_INFO "stop\n"); /* _prepare and _hwparams reset the stream */ hpi_handle_error(hpi_stream_stop(dpcm->h_stream)); @@ -656,12 +664,12 @@ static int snd_card_asihpi_trigger(struct snd_pcm_substream *substream, break; case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: - snd_printdd("pause release\n"); + VPRINTK1(KERN_INFO "pause release\n"); hpi_handle_error(hpi_stream_start(dpcm->h_stream)); snd_card_asihpi_pcm_timer_start(substream); break; case SNDRV_PCM_TRIGGER_PAUSE_PUSH: - snd_printdd("pause\n"); + VPRINTK1(KERN_INFO "pause\n"); snd_card_asihpi_pcm_timer_stop(substream); hpi_handle_error(hpi_stream_stop(dpcm->h_stream)); break; @@ -733,7 +741,7 @@ static void snd_card_asihpi_timer_function(unsigned long data) u16 state; u32 buffer_size, bytes_avail, samples_played, on_card_bytes; - snd_printdd("%c%d snd_card_asihpi_timer_function\n", + VPRINTK1(KERN_INFO "%c%d snd_card_asihpi_timer_function\n", SCHR(substream->stream), substream->number); /* find minimum newdata and buffer pos in group */ @@ -762,10 +770,10 @@ static void snd_card_asihpi_timer_function(unsigned long data) if ((bytes_avail == 0) && (on_card_bytes < ds->pcm_buf_host_rw_ofs)) { hpi_handle_error(hpi_stream_start(ds->h_stream)); - snd_printdd("P%d start\n", s->number); + VPRINTK1(KERN_INFO "P%d start\n", s->number); } } else if (state == HPI_STATE_DRAINED) { - snd_printd(KERN_WARNING "P%d drained\n", + VPRINTK1(KERN_WARNING "P%d drained\n", s->number); /*snd_pcm_stop(s, SNDRV_PCM_STATE_XRUN); continue; */ @@ -786,13 +794,13 @@ static void snd_card_asihpi_timer_function(unsigned long data) newdata); } - snd_printdd("hw_ptr x%04lX, appl_ptr x%04lX\n", + VPRINTK1(KERN_INFO "PB timer hw_ptr x%04lX, appl_ptr x%04lX\n", (unsigned long)frames_to_bytes(runtime, runtime->status->hw_ptr), (unsigned long)frames_to_bytes(runtime, runtime->control->appl_ptr)); - snd_printdd("%d %c%d S=%d, rw=%04X, dma=x%04X, left=x%04X," + VPRINTK1(KERN_INFO "%d %c%d S=%d, rw=%04X, dma=x%04X, left=x%04X," " aux=x%04X space=x%04X\n", loops, SCHR(s->stream), s->number, state, ds->pcm_buf_host_rw_ofs, pcm_buf_dma_ofs, (int)bytes_avail, @@ -814,7 +822,7 @@ static void snd_card_asihpi_timer_function(unsigned long data) next_jiffies = max(next_jiffies, 1U); dpcm->timer.expires = jiffies + next_jiffies; - snd_printdd("jif %d buf pos x%04X newdata x%04X xfer x%04X\n", + VPRINTK1(KERN_INFO "jif %d buf pos x%04X newdata x%04X xfer x%04X\n", next_jiffies, pcm_buf_dma_ofs, newdata, xfercount); snd_pcm_group_for_each_entry(s, substream) { @@ -829,7 +837,7 @@ static void snd_card_asihpi_timer_function(unsigned long data) if (xfercount && (on_card_bytes <= ds->period_bytes)) { if (card->support_mmap) { if (s->stream == SNDRV_PCM_STREAM_PLAYBACK) { - snd_printddd("P%d write x%04x\n", + VPRINTK2(KERN_INFO "P%d write x%04x\n", s->number, ds->period_bytes); hpi_handle_error( @@ -840,7 +848,7 @@ static void snd_card_asihpi_timer_function(unsigned long data) xfercount, &ds->format)); } else { - snd_printddd("C%d read x%04x\n", + VPRINTK2(KERN_INFO "C%d read x%04x\n", s->number, xfercount); hpi_handle_error( @@ -863,7 +871,7 @@ static void snd_card_asihpi_timer_function(unsigned long data) static int snd_card_asihpi_playback_ioctl(struct snd_pcm_substream *substream, unsigned int cmd, void *arg) { - snd_printdd(KERN_INFO "Playback ioctl %d\n", cmd); + /* snd_printd(KERN_INFO "Playback ioctl %d\n", cmd); */ return snd_pcm_lib_ioctl(substream, cmd, arg); } @@ -873,7 +881,7 @@ static int snd_card_asihpi_playback_prepare(struct snd_pcm_substream * struct snd_pcm_runtime *runtime = substream->runtime; struct snd_card_asihpi_pcm *dpcm = runtime->private_data; - snd_printdd("playback prepare %d\n", substream->number); + VPRINTK1(KERN_INFO "playback prepare %d\n", substream->number); hpi_handle_error(hpi_outstream_reset(dpcm->h_stream)); dpcm->pcm_buf_host_rw_ofs = 0; @@ -890,7 +898,7 @@ snd_card_asihpi_playback_pointer(struct snd_pcm_substream *substream) snd_pcm_uframes_t ptr; ptr = bytes_to_frames(runtime, dpcm->pcm_buf_dma_ofs % dpcm->buffer_bytes); - snd_printddd("playback_pointer=x%04lx\n", (unsigned long)ptr); + /* VPRINTK2(KERN_INFO "playback_pointer=x%04lx\n", (unsigned long)ptr); */ return ptr; } @@ -1006,13 +1014,12 @@ static int snd_card_asihpi_playback_open(struct snd_pcm_substream *substream) snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_SIZE, card->update_interval_frames); - snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_PERIOD_SIZE, card->update_interval_frames * 2, UINT_MAX); snd_pcm_set_sync(substream); - snd_printdd("playback open\n"); + VPRINTK1(KERN_INFO "playback open\n"); return 0; } @@ -1023,7 +1030,7 @@ static int snd_card_asihpi_playback_close(struct snd_pcm_substream *substream) struct snd_card_asihpi_pcm *dpcm = runtime->private_data; hpi_handle_error(hpi_outstream_close(dpcm->h_stream)); - snd_printdd("playback close\n"); + VPRINTK1(KERN_INFO "playback close\n"); return 0; } @@ -1043,13 +1050,13 @@ static int snd_card_asihpi_playback_copy(struct snd_pcm_substream *substream, if (copy_from_user(runtime->dma_area, src, len)) return -EFAULT; - snd_printddd("playback copy%d %u bytes\n", + VPRINTK2(KERN_DEBUG "playback copy%d %u bytes\n", substream->number, len); hpi_handle_error(hpi_outstream_write_buf(dpcm->h_stream, runtime->dma_area, len, &dpcm->format)); - dpcm->pcm_buf_host_rw_ofs += len; + dpcm->pcm_buf_host_rw_ofs = dpcm->pcm_buf_host_rw_ofs + len; return 0; } @@ -1059,11 +1066,16 @@ static int snd_card_asihpi_playback_silence(struct snd_pcm_substream * snd_pcm_uframes_t pos, snd_pcm_uframes_t count) { - /* Usually writes silence to DMA buffer, which should be overwritten - by real audio later. Our fifos cannot be overwritten, and are not - free-running DMAs. Silence is output on fifo underflow. - This callback is still required to allow the copy callback to be used. - */ + unsigned int len; + struct snd_pcm_runtime *runtime = substream->runtime; + struct snd_card_asihpi_pcm *dpcm = runtime->private_data; + + len = frames_to_bytes(runtime, count); + VPRINTK1(KERN_INFO "playback silence %u bytes\n", len); + + memset(runtime->dma_area, 0, len); + hpi_handle_error(hpi_outstream_write_buf(dpcm->h_stream, + runtime->dma_area, len, &dpcm->format)); return 0; } @@ -1098,7 +1110,7 @@ snd_card_asihpi_capture_pointer(struct snd_pcm_substream *substream) struct snd_pcm_runtime *runtime = substream->runtime; struct snd_card_asihpi_pcm *dpcm = runtime->private_data; - snd_printddd("capture pointer %d=%d\n", + VPRINTK2(KERN_INFO "capture pointer %d=%d\n", substream->number, dpcm->pcm_buf_dma_ofs); /* NOTE Unlike playback can't use actual samples_played for the capture position, because those samples aren't yet in @@ -1123,7 +1135,7 @@ static int snd_card_asihpi_capture_prepare(struct snd_pcm_substream *substream) dpcm->pcm_buf_dma_ofs = 0; dpcm->pcm_buf_elapsed_dma_ofs = 0; - snd_printdd("Capture Prepare %d\n", substream->number); + VPRINTK1("Capture Prepare %d\n", substream->number); return 0; } @@ -1186,7 +1198,7 @@ static int snd_card_asihpi_capture_open(struct snd_pcm_substream *substream) if (dpcm == NULL) return -ENOMEM; - snd_printdd("capture open adapter %d stream %d\n", + VPRINTK1("hpi_instream_open adapter %d stream %d\n", card->adapter_index, substream->number); err = hpi_handle_error( @@ -1256,7 +1268,7 @@ static int snd_card_asihpi_capture_copy(struct snd_pcm_substream *substream, len = frames_to_bytes(runtime, count); - snd_printddd("capture copy%d %d bytes\n", substream->number, len); + VPRINTK2(KERN_INFO "capture copy%d %d bytes\n", substream->number, len); hpi_handle_error(hpi_instream_read_buf(dpcm->h_stream, runtime->dma_area, len)); @@ -2875,9 +2887,6 @@ static int __devinit snd_asihpi_probe(struct pci_dev *pci_dev, if (err) asihpi->update_interval_frames = 512; - if (!asihpi->support_mmap) - asihpi->update_interval_frames *= 2; - hpi_handle_error(hpi_instream_open(asihpi->adapter_index, 0, &h_stream)); @@ -2900,6 +2909,7 @@ static int __devinit snd_asihpi_probe(struct pci_dev *pci_dev, asihpi->support_mrx ); + err = snd_card_asihpi_pcm_new(asihpi, 0, pcm_substreams); if (err < 0) { snd_printk(KERN_ERR "pcm_new failed\n"); @@ -2934,7 +2944,6 @@ static int __devinit snd_asihpi_probe(struct pci_dev *pci_dev, sprintf(card->longname, "%s %i", card->shortname, asihpi->adapter_index); err = snd_card_register(card); - if (!err) { hpi_card->snd_card_asihpi = card; dev++; diff --git a/trunk/sound/pci/hda/patch_analog.c b/trunk/sound/pci/hda/patch_analog.c index 2942d2a9ea10..734c6ee55d8a 100644 --- a/trunk/sound/pci/hda/patch_analog.c +++ b/trunk/sound/pci/hda/patch_analog.c @@ -4255,84 +4255,6 @@ static int ad1984a_thinkpad_init(struct hda_codec *codec) return 0; } -/* - * Precision R5500 - * 0x12 - HP/line-out - * 0x13 - speaker (mono) - * 0x15 - mic-in - */ - -static struct hda_verb ad1984a_precision_verbs[] = { - /* Unmute main output path */ - {0x03, AC_VERB_SET_AMP_GAIN_MUTE, 0x27}, /* 0dB */ - {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE + 0x1f}, /* 0dB */ - {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5) + 0x17}, /* 0dB */ - /* Analog mixer; mute as default */ - {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, - {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, - {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, - {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, - {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, - /* Select mic as input */ - {0x0c, AC_VERB_SET_CONNECT_SEL, 0x1}, - {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE + 0x27}, /* 0dB */ - /* Configure as mic */ - {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, - {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x7002}, /* raise mic as default */ - /* HP unmute */ - {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, - /* turn on EAPD */ - {0x13, AC_VERB_SET_EAPD_BTLENABLE, 0x02}, - /* unsolicited event for pin-sense */ - {0x12, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1884A_HP_EVENT}, - { } /* end */ -}; - -static struct snd_kcontrol_new ad1984a_precision_mixers[] = { - HDA_CODEC_VOLUME("Master Playback Volume", 0x21, 0x0, HDA_OUTPUT), - HDA_CODEC_MUTE("Master Playback Switch", 0x21, 0x0, HDA_OUTPUT), - HDA_CODEC_VOLUME("PCM Playback Volume", 0x20, 0x5, HDA_INPUT), - HDA_CODEC_MUTE("PCM Playback Switch", 0x20, 0x5, HDA_INPUT), - HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x01, HDA_INPUT), - HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x01, HDA_INPUT), - HDA_CODEC_VOLUME("Mic Boost Volume", 0x15, 0x0, HDA_INPUT), - HDA_CODEC_MUTE("Front Playback Switch", 0x12, 0x0, HDA_OUTPUT), - HDA_CODEC_VOLUME("Speaker Playback Volume", 0x13, 0x0, HDA_OUTPUT), - HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT), - HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT), - { } /* end */ -}; - - -/* mute internal speaker if HP is plugged */ -static void ad1984a_precision_automute(struct hda_codec *codec) -{ - unsigned int present; - - present = snd_hda_jack_detect(codec, 0x12); - snd_hda_codec_amp_stereo(codec, 0x13, HDA_OUTPUT, 0, - HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); -} - - -/* unsolicited event for HP jack sensing */ -static void ad1984a_precision_unsol_event(struct hda_codec *codec, - unsigned int res) -{ - if ((res >> 26) != AD1884A_HP_EVENT) - return; - ad1984a_precision_automute(codec); -} - -/* initialize jack-sensing, too */ -static int ad1984a_precision_init(struct hda_codec *codec) -{ - ad198x_init(codec); - ad1984a_precision_automute(codec); - return 0; -} - - /* * HP Touchsmart * port-A (0x11) - front hp-out @@ -4462,7 +4384,6 @@ enum { AD1884A_MOBILE, AD1884A_THINKPAD, AD1984A_TOUCHSMART, - AD1984A_PRECISION, AD1884A_MODELS }; @@ -4472,11 +4393,9 @@ static const char * const ad1884a_models[AD1884A_MODELS] = { [AD1884A_MOBILE] = "mobile", [AD1884A_THINKPAD] = "thinkpad", [AD1984A_TOUCHSMART] = "touchsmart", - [AD1984A_PRECISION] = "precision", }; static struct snd_pci_quirk ad1884a_cfg_tbl[] = { - SND_PCI_QUIRK(0x1028, 0x04ac, "Precision R5500", AD1984A_PRECISION), SND_PCI_QUIRK(0x103c, 0x3030, "HP", AD1884A_MOBILE), SND_PCI_QUIRK(0x103c, 0x3037, "HP 2230s", AD1884A_LAPTOP), SND_PCI_QUIRK(0x103c, 0x3056, "HP", AD1884A_MOBILE), @@ -4570,14 +4489,6 @@ static int patch_ad1884a(struct hda_codec *codec) codec->patch_ops.unsol_event = ad1984a_thinkpad_unsol_event; codec->patch_ops.init = ad1984a_thinkpad_init; break; - case AD1984A_PRECISION: - spec->mixers[0] = ad1984a_precision_mixers; - spec->init_verbs[spec->num_init_verbs++] = - ad1984a_precision_verbs; - spec->multiout.dig_out_nid = 0; - codec->patch_ops.unsol_event = ad1984a_precision_unsol_event; - codec->patch_ops.init = ad1984a_precision_init; - break; case AD1984A_TOUCHSMART: spec->mixers[0] = ad1984a_touchsmart_mixers; spec->init_verbs[0] = ad1984a_touchsmart_verbs; diff --git a/trunk/sound/pci/hda/patch_realtek.c b/trunk/sound/pci/hda/patch_realtek.c index 0ef0035fe99f..5d582de91c19 100644 --- a/trunk/sound/pci/hda/patch_realtek.c +++ b/trunk/sound/pci/hda/patch_realtek.c @@ -1290,7 +1290,7 @@ static void alc_auto_init_amp(struct hda_codec *codec, int type) case 0x10ec0883: case 0x10ec0885: case 0x10ec0887: - /*case 0x10ec0889:*/ /* this causes an SPDIF problem */ + case 0x10ec0889: alc889_coef_init(codec); break; case 0x10ec0888: diff --git a/trunk/sound/usb/quirks-table.h b/trunk/sound/usb/quirks-table.h index c66d3f64dcf8..c0dcfca9b5b5 100644 --- a/trunk/sound/usb/quirks-table.h +++ b/trunk/sound/usb/quirks-table.h @@ -1567,46 +1567,6 @@ YAMAHA_DEVICE(0x7010, "UB99"), } } }, -{ - USB_DEVICE_VENDOR_SPEC(0x0582, 0x0104), - .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) { - /* .vendor_name = "Roland", */ - /* .product_name = "UM-1G", */ - .ifnum = 0, - .type = QUIRK_MIDI_FIXED_ENDPOINT, - .data = & (const struct snd_usb_midi_endpoint_info) { - .out_cables = 0x0001, - .in_cables = 0x0001 - } - } -}, -{ - /* Boss JS-8 Jam Station */ - USB_DEVICE(0x0582, 0x0109), - .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) { - /* .vendor_name = "BOSS", */ - /* .product_name = "JS-8", */ - .ifnum = QUIRK_ANY_INTERFACE, - .type = QUIRK_COMPOSITE, - .data = (const struct snd_usb_audio_quirk[]) { - { - .ifnum = 0, - .type = QUIRK_AUDIO_STANDARD_INTERFACE - }, - { - .ifnum = 1, - .type = QUIRK_AUDIO_STANDARD_INTERFACE - }, - { - .ifnum = 2, - .type = QUIRK_MIDI_STANDARD_INTERFACE - }, - { - .ifnum = -1 - } - } - } -}, { /* has ID 0x0110 when not in Advanced Driver mode */ USB_DEVICE_VENDOR_SPEC(0x0582, 0x010f),