summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CREDITS12
-rw-r--r--Documentation/CodingStyle34
-rw-r--r--Documentation/DocBook/kernel-api.tmpl83
-rw-r--r--Documentation/HOWTO20
-rw-r--r--Documentation/IPMI.txt19
-rw-r--r--Documentation/SubmitChecklist5
-rw-r--r--Documentation/SubmittingDrivers21
-rw-r--r--Documentation/SubmittingPatches39
-rw-r--r--Documentation/accounting/getdelays.c7
-rw-r--r--Documentation/accounting/taskstats-struct.txt161
-rw-r--r--Documentation/cpusets.txt10
-rw-r--r--Documentation/fb/intel810.txt148
-rw-r--r--Documentation/fb/intelfb.txt21
-rw-r--r--Documentation/feature-removal-schedule.txt28
-rw-r--r--Documentation/filesystems/Locking5
-rw-r--r--Documentation/filesystems/proc.txt18
-rw-r--r--Documentation/filesystems/vfs.txt4
-rw-r--r--Documentation/ia64/serial.txt7
-rw-r--r--Documentation/input/ff.txt112
-rw-r--r--Documentation/kbuild/modules.txt9
-rw-r--r--Documentation/kernel-parameters.txt9
-rw-r--r--Documentation/kprobes.txt89
-rw-r--r--Documentation/lockdep-design.txt22
-rw-r--r--Documentation/md.txt26
-rw-r--r--Documentation/networking/pktgen.txt16
-rw-r--r--Documentation/rt-mutex-design.txt14
-rw-r--r--Documentation/seclvl.txt97
-rw-r--r--Documentation/video4linux/CARDLIST.cx888
-rw-r--r--Documentation/video4linux/CARDLIST.saa71347
-rw-r--r--Documentation/video4linux/bttv/Insmod-options6
-rw-r--r--Documentation/video4linux/cx2341x/README.hm12116
-rw-r--r--Documentation/video4linux/cx2341x/README.vbi45
-rw-r--r--Documentation/x86_64/boot-options.txt5
-rw-r--r--MAINTAINERS72
-rw-r--r--arch/alpha/kernel/alpha_ksyms.c3
-rw-r--r--arch/alpha/kernel/entry.S10
-rw-r--r--arch/alpha/kernel/osf_sys.c34
-rw-r--r--arch/alpha/kernel/proto.h15
-rw-r--r--arch/alpha/kernel/srmcons.c2
-rw-r--r--arch/alpha/kernel/time.c17
-rw-r--r--arch/alpha/mm/Makefile2
-rw-r--r--arch/alpha/mm/fault.c2
-rw-r--r--arch/alpha/mm/remap.c86
-rw-r--r--arch/arm/kernel/ecard.c2
-rw-r--r--arch/arm/kernel/setup.c2
-rw-r--r--arch/arm/kernel/smp.c2
-rw-r--r--arch/arm/kernel/sys_arm.c4
-rw-r--r--arch/arm/kernel/time.c12
-rw-r--r--arch/arm/mach-omap1/board-fsample.c8
-rw-r--r--arch/arm/mach-omap1/board-h2.c11
-rw-r--r--arch/arm/mach-omap1/board-h3.c11
-rw-r--r--arch/arm/mach-omap1/board-innovator.c8
-rw-r--r--arch/arm/mach-omap1/board-nokia770.c8
-rw-r--r--arch/arm/mach-omap1/board-osk.c8
-rw-r--r--arch/arm/mach-omap1/board-perseus2.c9
-rw-r--r--arch/arm/mach-omap2/board-h4.c1
-rw-r--r--arch/arm/mach-pnx4008/clock.c11
-rw-r--r--arch/arm/mm/fault.c4
-rw-r--r--arch/arm/vfp/vfpsingle.c2
-rw-r--r--arch/arm26/kernel/setup.c2
-rw-r--r--arch/arm26/kernel/sys_arm.c4
-rw-r--r--arch/arm26/kernel/time.c14
-rw-r--r--arch/arm26/mm/fault.c4
-rw-r--r--arch/avr32/kernel/sys_avr32.c14
-rw-r--r--arch/avr32/kernel/time.c2
-rw-r--r--arch/avr32/mm/ioremap.c120
-rw-r--r--arch/cris/arch-v10/kernel/time.c2
-rw-r--r--arch/cris/arch-v32/kernel/smp.c1
-rw-r--r--arch/cris/arch-v32/kernel/time.c2
-rw-r--r--arch/cris/kernel/setup.c2
-rw-r--r--arch/cris/kernel/time.c7
-rw-r--r--arch/cris/mm/ioremap.c88
-rw-r--r--arch/frv/Kconfig8
-rw-r--r--arch/frv/kernel/Makefile2
-rw-r--r--arch/frv/kernel/kernel_execve.S33
-rw-r--r--arch/frv/kernel/setup.c1
-rw-r--r--arch/frv/kernel/time.c2
-rw-r--r--arch/h8300/kernel/sys_h8300.c24
-rw-r--r--arch/h8300/kernel/time.c2
-rw-r--r--arch/i386/Kconfig2
-rw-r--r--arch/i386/boot/video.S2
-rw-r--r--arch/i386/defconfig7
-rw-r--r--arch/i386/kernel/apm.c36
-rw-r--r--arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c7
-rw-r--r--arch/i386/kernel/cpu/cpufreq/longhaul.c56
-rw-r--r--arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c2
-rw-r--r--arch/i386/kernel/crash.c10
-rw-r--r--arch/i386/kernel/efi.c4
-rw-r--r--arch/i386/kernel/i8237.c5
-rw-r--r--arch/i386/kernel/kprobes.c41
-rw-r--r--arch/i386/kernel/nmi.c4
-rw-r--r--arch/i386/kernel/process.c11
-rw-r--r--arch/i386/kernel/setup.c10
-rw-r--r--arch/i386/kernel/smp.c27
-rw-r--r--arch/i386/kernel/smpboot.c8
-rw-r--r--arch/i386/kernel/srat.c7
-rw-r--r--arch/i386/kernel/sys_i386.c42
-rw-r--r--arch/i386/kernel/time.c3
-rw-r--r--arch/i386/kernel/traps.c8
-rw-r--r--arch/i386/lib/delay.c1
-rw-r--r--arch/i386/lib/usercopy.c2
-rw-r--r--arch/i386/mach-voyager/voyager_smp.c7
-rw-r--r--arch/i386/mm/fault.c4
-rw-r--r--arch/i386/mm/highmem.c18
-rw-r--r--arch/i386/mm/init.c1
-rw-r--r--arch/i386/mm/ioremap.c84
-rw-r--r--arch/i386/oprofile/op_model_ppro.c20
-rw-r--r--arch/i386/pci/mmconfig.c5
-rw-r--r--arch/ia64/Kconfig2
-rw-r--r--arch/ia64/hp/sim/simeth.c4
-rw-r--r--arch/ia64/hp/sim/simserial.c2
-rw-r--r--arch/ia64/ia32/sys_ia32.c23
-rw-r--r--arch/ia64/kernel/entry.S4
-rw-r--r--arch/ia64/kernel/kprobes.c98
-rw-r--r--arch/ia64/kernel/mca.c2
-rw-r--r--arch/ia64/kernel/numa.c1
-rw-r--r--arch/ia64/kernel/process.c2
-rw-r--r--arch/ia64/kernel/setup.c1
-rw-r--r--arch/ia64/kernel/time.c4
-rw-r--r--arch/ia64/mm/fault.c8
-rw-r--r--arch/ia64/mm/numa.c18
-rw-r--r--arch/ia64/sn/kernel/sn2/sn_hwperf.c2
-rw-r--r--arch/ia64/sn/pci/pcibr/pcibr_ate.c2
-rw-r--r--arch/ia64/sn/pci/pcibr/pcibr_dma.c2
-rw-r--r--arch/m32r/kernel/sys_m32r.c22
-rw-r--r--arch/m32r/kernel/time.c13
-rw-r--r--arch/m32r/mm/fault.c2
-rw-r--r--arch/m32r/mm/ioremap.c93
-rw-r--r--arch/m68k/kernel/sys_m68k.c16
-rw-r--r--arch/m68k/kernel/time.c18
-rw-r--r--arch/m68k/mm/fault.c4
-rw-r--r--arch/m68k/sun3/sun3ints.c2
-rw-r--r--arch/m68knommu/kernel/sys_m68k.c15
-rw-r--r--arch/m68knommu/kernel/time.c9
-rw-r--r--arch/mips/Kconfig9
-rw-r--r--arch/mips/au1000/common/time.c6
-rw-r--r--arch/mips/basler/excite/excite_flashtest.c294
-rw-r--r--arch/mips/cobalt/setup.c1
-rw-r--r--arch/mips/configs/atlas_defconfig3
-rw-r--r--arch/mips/configs/bigsur_defconfig3
-rw-r--r--arch/mips/configs/capcella_defconfig3
-rw-r--r--arch/mips/configs/cobalt_defconfig3
-rw-r--r--arch/mips/configs/db1000_defconfig3
-rw-r--r--arch/mips/configs/db1100_defconfig3
-rw-r--r--arch/mips/configs/db1200_defconfig3
-rw-r--r--arch/mips/configs/db1500_defconfig3
-rw-r--r--arch/mips/configs/db1550_defconfig3
-rw-r--r--arch/mips/configs/ddb5477_defconfig3
-rw-r--r--arch/mips/configs/decstation_defconfig3
-rw-r--r--arch/mips/configs/e55_defconfig2
-rw-r--r--arch/mips/configs/emma2rh_defconfig3
-rw-r--r--arch/mips/configs/ev64120_defconfig3
-rw-r--r--arch/mips/configs/excite_defconfig3
-rw-r--r--arch/mips/configs/ip22_defconfig3
-rw-r--r--arch/mips/configs/ip27_defconfig3
-rw-r--r--arch/mips/configs/ip32_defconfig3
-rw-r--r--arch/mips/configs/it8172_defconfig3
-rw-r--r--arch/mips/configs/ivr_defconfig3
-rw-r--r--arch/mips/configs/jaguar-atx_defconfig3
-rw-r--r--arch/mips/configs/jmr3927_defconfig3
-rw-r--r--arch/mips/configs/lasat200_defconfig3
-rw-r--r--arch/mips/configs/malta_defconfig3
-rw-r--r--arch/mips/configs/mipssim_defconfig3
-rw-r--r--arch/mips/configs/mpc30x_defconfig2
-rw-r--r--arch/mips/configs/ocelot_3_defconfig3
-rw-r--r--arch/mips/configs/ocelot_c_defconfig3
-rw-r--r--arch/mips/configs/ocelot_defconfig3
-rw-r--r--arch/mips/configs/ocelot_g_defconfig3
-rw-r--r--arch/mips/configs/pb1100_defconfig3
-rw-r--r--arch/mips/configs/pb1500_defconfig3
-rw-r--r--arch/mips/configs/pb1550_defconfig3
-rw-r--r--arch/mips/configs/pnx8550-jbs_defconfig3
-rw-r--r--arch/mips/configs/pnx8550-v2pci_defconfig3
-rw-r--r--arch/mips/configs/qemu_defconfig3
-rw-r--r--arch/mips/configs/rbhma4500_defconfig3
-rw-r--r--arch/mips/configs/rm200_defconfig3
-rw-r--r--arch/mips/configs/sb1250-swarm_defconfig3
-rw-r--r--arch/mips/configs/sead_defconfig3
-rw-r--r--arch/mips/configs/tb0226_defconfig3
-rw-r--r--arch/mips/configs/tb0229_defconfig3
-rw-r--r--arch/mips/configs/tb0287_defconfig3
-rw-r--r--arch/mips/configs/workpad_defconfig2
-rw-r--r--arch/mips/configs/wrppmc_defconfig3
-rw-r--r--arch/mips/configs/yosemite_defconfig3
-rw-r--r--arch/mips/defconfig3
-rw-r--r--arch/mips/gt64120/common/time.c2
-rw-r--r--arch/mips/kernel/Makefile1
-rw-r--r--arch/mips/kernel/genex.S8
-rw-r--r--arch/mips/kernel/i8259.c4
-rw-r--r--arch/mips/kernel/linux32.c4
-rw-r--r--arch/mips/kernel/process.c37
-rw-r--r--arch/mips/kernel/scall32-o32.S13
-rw-r--r--arch/mips/kernel/scall64-64.S2
-rw-r--r--arch/mips/kernel/scall64-n32.S2
-rw-r--r--arch/mips/kernel/scall64-o32.S2
-rw-r--r--arch/mips/kernel/stacktrace.c85
-rw-r--r--arch/mips/kernel/syscall.c56
-rw-r--r--arch/mips/kernel/sysirix.c22
-rw-r--r--arch/mips/kernel/time.c14
-rw-r--r--arch/mips/kernel/traps.c40
-rw-r--r--arch/mips/lasat/setup.c1
-rw-r--r--arch/mips/mm/c-r3k.c21
-rw-r--r--arch/mips/mm/c-r4k.c77
-rw-r--r--arch/mips/mm/c-sb1.c61
-rw-r--r--arch/mips/mm/c-tx39.c29
-rw-r--r--arch/mips/mm/cache.c1
-rw-r--r--arch/mips/mm/fault.c2
-rw-r--r--arch/mips/mm/tlbex-fault.S4
-rw-r--r--arch/mips/momentum/ocelot_g/gt-irq.c2
-rw-r--r--arch/mips/sgi-ip22/ip22-reset.c3
-rw-r--r--arch/mips/sgi-ip27/ip27-timer.c4
-rw-r--r--arch/mips/sgi-ip32/ip32-reset.c2
-rw-r--r--arch/parisc/hpux/fs.c6
-rw-r--r--arch/parisc/hpux/sys_hpux.c37
-rw-r--r--arch/parisc/kernel/firmware.c7
-rw-r--r--arch/parisc/kernel/module.c32
-rw-r--r--arch/parisc/kernel/process.c9
-rw-r--r--arch/parisc/kernel/sys_parisc32.c19
-rw-r--r--arch/parisc/kernel/time.c7
-rw-r--r--arch/powerpc/Kconfig2
-rw-r--r--arch/powerpc/Makefile6
-rw-r--r--arch/powerpc/boot/Makefile224
-rw-r--r--arch/powerpc/boot/dts/mpc8560ads.dts302
-rwxr-xr-xarch/powerpc/boot/wrapper204
-rw-r--r--arch/powerpc/boot/zImage.coff.lds.S (renamed from arch/powerpc/boot/zImage.coff.lds)0
-rw-r--r--arch/powerpc/boot/zImage.lds.S (renamed from arch/powerpc/boot/zImage.lds)0
-rw-r--r--arch/powerpc/configs/chrp32_defconfig2
-rw-r--r--arch/powerpc/configs/g5_defconfig28
-rw-r--r--arch/powerpc/configs/iseries_defconfig2
-rw-r--r--arch/powerpc/configs/mpc7448_hpc2_defconfig28
-rw-r--r--arch/powerpc/configs/mpc834x_itx_defconfig53
-rw-r--r--arch/powerpc/configs/mpc8560_ads_defconfig854
-rw-r--r--arch/powerpc/configs/pmac32_defconfig4
-rw-r--r--arch/powerpc/configs/ppc64_defconfig28
-rw-r--r--arch/powerpc/configs/pseries_defconfig2
-rw-r--r--arch/powerpc/kernel/irq.c19
-rw-r--r--arch/powerpc/kernel/kprobes.c33
-rw-r--r--arch/powerpc/kernel/misc_32.S2
-rw-r--r--arch/powerpc/kernel/misc_64.S2
-rw-r--r--arch/powerpc/kernel/process.c2
-rw-r--r--arch/powerpc/kernel/ptrace.c13
-rw-r--r--arch/powerpc/kernel/setup_32.c4
-rw-r--r--arch/powerpc/kernel/setup_64.c7
-rw-r--r--arch/powerpc/kernel/sys_ppc32.c15
-rw-r--r--arch/powerpc/kernel/syscalls.c14
-rw-r--r--arch/powerpc/kernel/sysfs.c4
-rw-r--r--arch/powerpc/kernel/time.c51
-rw-r--r--arch/powerpc/lib/Makefile6
-rw-r--r--arch/powerpc/lib/rheap.c24
-rw-r--r--arch/powerpc/math-emu/Makefile3
-rw-r--r--arch/powerpc/mm/fault.c4
-rw-r--r--arch/powerpc/oprofile/backtrace.c11
-rw-r--r--arch/powerpc/platforms/83xx/mpc834x_itx.c4
-rw-r--r--arch/powerpc/platforms/85xx/Kconfig21
-rw-r--r--arch/powerpc/platforms/85xx/Makefile1
-rw-r--r--arch/powerpc/platforms/85xx/mpc85xx_ads.c120
-rw-r--r--arch/powerpc/platforms/85xx/mpc85xx_ads.h61
-rw-r--r--arch/powerpc/platforms/cell/spu_base.c4
-rw-r--r--arch/powerpc/platforms/cell/spufs/file.c2
-rw-r--r--arch/powerpc/platforms/cell/spufs/hw_ops.c4
-rw-r--r--arch/powerpc/platforms/iseries/mf.c2
-rw-r--r--arch/powerpc/platforms/maple/pci.c60
-rw-r--r--arch/powerpc/platforms/powermac/cpufreq_64.c2
-rw-r--r--arch/powerpc/platforms/powermac/nvram.c4
-rw-r--r--arch/powerpc/platforms/pseries/eeh.c7
-rw-r--r--arch/powerpc/platforms/pseries/ras.c2
-rw-r--r--arch/powerpc/platforms/pseries/setup.c26
-rw-r--r--arch/powerpc/sysdev/Makefile5
-rw-r--r--arch/powerpc/sysdev/cpm2_common.c309
-rw-r--r--arch/powerpc/sysdev/cpm2_pic.c256
-rw-r--r--arch/powerpc/sysdev/cpm2_pic.h10
-rw-r--r--arch/powerpc/sysdev/fsl_soc.c281
-rw-r--r--arch/powerpc/sysdev/fsl_soc.h2
-rw-r--r--arch/ppc/4xx_io/serial_sicc.c2
-rw-r--r--arch/ppc/boot/utils/mkbugboot.c208
-rw-r--r--arch/ppc/boot/utils/mkprep.c416
-rw-r--r--arch/ppc/kernel/misc.S18
-rw-r--r--arch/ppc/kernel/setup.c4
-rw-r--r--arch/ppc/kernel/time.c13
-rw-r--r--arch/ppc/kernel/traps.c2
-rw-r--r--arch/ppc/mm/fault.c4
-rw-r--r--arch/ppc/platforms/mpc8272ads_setup.c8
-rw-r--r--arch/ppc/platforms/mpc866ads_setup.c8
-rw-r--r--arch/ppc/platforms/mpc885ads_setup.c10
-rw-r--r--arch/s390/appldata/appldata_base.c2
-rw-r--r--arch/s390/hypfs/inode.c17
-rw-r--r--arch/s390/kernel/compat_linux.c5
-rw-r--r--arch/s390/kernel/head31.S11
-rw-r--r--arch/s390/kernel/head64.S11
-rw-r--r--arch/s390/kernel/kprobes.c9
-rw-r--r--arch/s390/kernel/sys_s390.c20
-rw-r--r--arch/s390/kernel/time.c16
-rw-r--r--arch/s390/lib/spinlock.c62
-rw-r--r--arch/s390/mm/fault.c2
-rw-r--r--arch/sh/Kconfig2
-rw-r--r--arch/sh/boards/hp6xx/hp6xx_apm.c1
-rw-r--r--arch/sh/boards/hp6xx/pm.c1
-rw-r--r--arch/sh/boards/landisk/irq.c4
-rw-r--r--arch/sh/boards/landisk/landisk_pwb.c2
-rw-r--r--arch/sh/boards/landisk/rtc.c2
-rw-r--r--arch/sh/boards/landisk/setup.c1
-rw-r--r--arch/sh/boards/renesas/r7780rp/irq.c4
-rw-r--r--arch/sh/boards/renesas/r7780rp/led.c2
-rw-r--r--arch/sh/boards/renesas/systemh/setup.c2
-rw-r--r--arch/sh/boards/se/7343/io.c2
-rw-r--r--arch/sh/boards/se/7343/irq.c4
-rw-r--r--arch/sh/boards/se/7343/led.c2
-rw-r--r--arch/sh/boards/se/7343/setup.c1
-rw-r--r--arch/sh/boards/se/770x/setup.c7
-rw-r--r--arch/sh/boards/se/7751/setup.c6
-rw-r--r--arch/sh/boards/sh03/setup.c1
-rw-r--r--arch/sh/boot/.gitignore1
-rw-r--r--arch/sh/configs/adx_defconfig539
-rw-r--r--arch/sh/configs/cqreek_defconfig533
-rw-r--r--arch/sh/configs/dreamcast_defconfig572
-rw-r--r--arch/sh/configs/hp6xx_defconfig201
-rw-r--r--arch/sh/configs/hs7751rvoip_defconfig908
-rw-r--r--arch/sh/configs/landisk_defconfig417
-rw-r--r--arch/sh/configs/microdev_defconfig167
-rw-r--r--arch/sh/configs/r7780rp_defconfig232
-rw-r--r--arch/sh/configs/rts7751r2d_defconfig568
-rw-r--r--arch/sh/configs/se7300_defconfig357
-rw-r--r--arch/sh/configs/se73180_defconfig347
-rw-r--r--arch/sh/configs/se7343_defconfig101
-rw-r--r--arch/sh/configs/se7705_defconfig531
-rw-r--r--arch/sh/configs/se7750_defconfig532
-rw-r--r--arch/sh/configs/se7751_defconfig626
-rw-r--r--arch/sh/configs/sh03_defconfig568
-rw-r--r--arch/sh/configs/sh7710voipgw_defconfig78
-rw-r--r--arch/sh/configs/shmin_defconfig93
-rw-r--r--arch/sh/configs/snapgear_defconfig527
-rw-r--r--arch/sh/configs/systemh_defconfig370
-rw-r--r--arch/sh/configs/titan_defconfig619
-rw-r--r--arch/sh/drivers/dma/dma-sysfs.c8
-rw-r--r--arch/sh/drivers/pci/ops-landisk.c1
-rw-r--r--arch/sh/drivers/pci/ops-r7780rp.c2
-rw-r--r--arch/sh/drivers/pci/ops-sh03.c4
-rw-r--r--arch/sh/drivers/pci/ops-titan.c2
-rw-r--r--arch/sh/drivers/pci/pci-sh7780.c2
-rw-r--r--arch/sh/kernel/apm.c1
-rw-r--r--arch/sh/kernel/entry.S6
-rw-r--r--arch/sh/kernel/setup.c6
-rw-r--r--arch/sh/kernel/sh_ksyms.c1
-rw-r--r--arch/sh/kernel/smp.c1
-rw-r--r--arch/sh/kernel/sys_sh.c19
-rw-r--r--arch/sh/kernel/time.c12
-rw-r--r--arch/sh/kernel/vsyscall/.gitignore1
-rw-r--r--arch/sh/math-emu/math.c1
-rw-r--r--arch/sh/mm/cache-debugfs.c2
-rw-r--r--arch/sh/mm/fault.c4
-rw-r--r--arch/sh/tools/gen-mach-types2
-rw-r--r--arch/sh64/configs/cayman_defconfig456
-rw-r--r--arch/sh64/kernel/process.c270
-rw-r--r--arch/sh64/kernel/sys_sh64.c21
-rw-r--r--arch/sh64/kernel/time.c14
-rw-r--r--arch/sh64/mm/fault.c6
-rw-r--r--arch/sparc/kernel/pcic.c18
-rw-r--r--arch/sparc/kernel/sys_sparc.c27
-rw-r--r--arch/sparc/kernel/sys_sunos.c31
-rw-r--r--arch/sparc/kernel/time.c20
-rw-r--r--arch/sparc/lib/copy_user.S4
-rw-r--r--arch/sparc64/Kconfig2
-rw-r--r--arch/sparc64/defconfig23
-rw-r--r--arch/sparc64/kernel/power.c5
-rw-r--r--arch/sparc64/kernel/signal32.c1
-rw-r--r--arch/sparc64/kernel/sys_sparc.c25
-rw-r--r--arch/sparc64/kernel/sys_sparc32.c6
-rw-r--r--arch/sparc64/kernel/sys_sunos32.c23
-rw-r--r--arch/sparc64/kernel/time.c6
-rw-r--r--arch/sparc64/solaris/fs.c7
-rw-r--r--arch/sparc64/solaris/misc.c9
-rw-r--r--arch/um/drivers/line.c6
-rw-r--r--arch/um/drivers/mconsole_kern.c21
-rw-r--r--arch/um/drivers/mconsole_user.c4
-rw-r--r--arch/um/drivers/net_kern.c98
-rw-r--r--arch/um/drivers/net_user.c1
-rw-r--r--arch/um/drivers/null.c1
-rw-r--r--arch/um/drivers/random.c4
-rw-r--r--arch/um/drivers/stderr_console.c2
-rw-r--r--arch/um/drivers/stdio_console.c1
-rw-r--r--arch/um/drivers/ubd_kern.c11
-rw-r--r--arch/um/include/line.h7
-rw-r--r--arch/um/include/net_kern.h14
-rw-r--r--arch/um/include/net_user.h18
-rw-r--r--arch/um/kernel/exitcode.c8
-rw-r--r--arch/um/kernel/skas/mmu.c6
-rw-r--r--arch/um/kernel/skas/process_kern.c484
-rw-r--r--arch/um/kernel/syscall.c35
-rw-r--r--arch/um/kernel/time.c2
-rw-r--r--arch/um/kernel/trap.c2
-rw-r--r--arch/um/kernel/um_arch.c6
-rw-r--r--arch/um/os-Linux/mem.c6
-rw-r--r--arch/um/os-Linux/process.c5
-rw-r--r--arch/um/os-Linux/sys-i386/tls.c5
-rw-r--r--arch/um/os-Linux/tls.c8
-rw-r--r--arch/um/sys-i386/unmap.c11
-rw-r--r--arch/um/sys-x86_64/syscalls.c2
-rw-r--r--arch/um/sys-x86_64/sysrq.c2
-rw-r--r--arch/um/sys-x86_64/unmap.c11
-rw-r--r--arch/v850/kernel/memcons.c4
-rw-r--r--arch/v850/kernel/rte_cb_leds.c2
-rw-r--r--arch/v850/kernel/rte_mb_a_pci.c12
-rw-r--r--arch/v850/kernel/simcons.c2
-rw-r--r--arch/v850/kernel/syscalls.c20
-rw-r--r--arch/v850/kernel/time.c2
-rw-r--r--arch/x86_64/Kconfig6
-rw-r--r--arch/x86_64/defconfig8
-rw-r--r--arch/x86_64/ia32/sys_ia32.c45
-rw-r--r--arch/x86_64/kernel/apic.c54
-rw-r--r--arch/x86_64/kernel/entry.S4
-rw-r--r--arch/x86_64/kernel/kprobes.c48
-rw-r--r--arch/x86_64/kernel/mpparse.c37
-rw-r--r--arch/x86_64/kernel/nmi.c4
-rw-r--r--arch/x86_64/kernel/pci-dma.c93
-rw-r--r--arch/x86_64/kernel/pci-swiotlb.c3
-rw-r--r--arch/x86_64/kernel/process.c6
-rw-r--r--arch/x86_64/kernel/setup.c11
-rw-r--r--arch/x86_64/kernel/sys_x86_64.c2
-rw-r--r--arch/x86_64/kernel/time.c20
-rw-r--r--arch/x86_64/kernel/vmlinux.lds.S17
-rw-r--r--arch/x86_64/kernel/vsyscall.c11
-rw-r--r--arch/x86_64/mm/fault.c6
-rw-r--r--arch/x86_64/mm/init.c38
-rw-r--r--arch/x86_64/mm/ioremap.c111
-rw-r--r--arch/x86_64/mm/srat.c66
-rw-r--r--arch/xtensa/kernel/syscalls.c22
-rw-r--r--arch/xtensa/kernel/time.c15
-rw-r--r--arch/xtensa/mm/fault.c2
-rw-r--r--arch/xtensa/platform-iss/console.c2
-rw-r--r--arch/xtensa/platform-iss/network.c2
-rw-r--r--block/Kconfig20
-rw-r--r--block/Kconfig.iosched3
-rw-r--r--block/Makefile2
-rw-r--r--block/as-iosched.c674
-rw-r--r--block/blktrace.c32
-rw-r--r--block/cfq-iosched.c867
-rw-r--r--block/deadline-iosched.c464
-rw-r--r--block/elevator.c315
-rw-r--r--block/genhd.c9
-rw-r--r--block/ioctl.c5
-rw-r--r--block/ll_rw_blk.c239
-rw-r--r--block/noop-iosched.c2
-rw-r--r--block/scsi_ioctl.c6
-rw-r--r--drivers/acpi/acpi_memhotplug.c4
-rw-r--r--drivers/acpi/processor_idle.c38
-rw-r--r--drivers/ata/pata_hpt366.c2
-rw-r--r--drivers/base/Makefile2
-rw-r--r--drivers/base/class.c8
-rw-r--r--drivers/base/firmware_class.c12
-rw-r--r--drivers/block/DAC960.c4
-rw-r--r--drivers/block/DAC960.h2
-rw-r--r--drivers/block/Kconfig4
-rw-r--r--drivers/block/cciss.c238
-rw-r--r--drivers/block/cciss.h3
-rw-r--r--drivers/block/cciss_cmd.h33
-rw-r--r--drivers/block/cciss_scsi.c2
-rw-r--r--drivers/block/cpqarray.c1
-rw-r--r--drivers/block/floppy.c4
-rw-r--r--drivers/block/loop.c240
-rw-r--r--drivers/block/nbd.c8
-rw-r--r--drivers/block/paride/pd.c8
-rw-r--r--drivers/block/pktcdvd.c10
-rw-r--r--drivers/block/swim3.c4
-rw-r--r--drivers/block/swim_iop.c4
-rw-r--r--drivers/block/umem.c3
-rw-r--r--drivers/block/xd.c2
-rw-r--r--drivers/bluetooth/bfusb.c316
-rw-r--r--drivers/bluetooth/hci_ldisc.c13
-rw-r--r--drivers/bluetooth/hci_usb.c3
-rw-r--r--drivers/bluetooth/hci_vhci.c99
-rw-r--r--drivers/cdrom/Kconfig2
-rw-r--r--drivers/cdrom/cdrom.c2
-rw-r--r--drivers/cdrom/cdu31a.c4
-rw-r--r--drivers/char/Kconfig9
-rw-r--r--drivers/char/Makefile1
-rw-r--r--drivers/char/agp/amd64-agp.c8
-rw-r--r--drivers/char/agp/generic.c9
-rw-r--r--drivers/char/amiserial.c2
-rw-r--r--drivers/char/cyclades.c2
-rw-r--r--drivers/char/drm/Kconfig9
-rw-r--r--drivers/char/drm/Makefile6
-rw-r--r--drivers/char/drm/drmP.h68
-rw-r--r--drivers/char/drm/drm_auth.c64
-rw-r--r--drivers/char/drm/drm_bufs.c74
-rw-r--r--drivers/char/drm/drm_drv.c12
-rw-r--r--drivers/char/drm/drm_fops.c10
-rw-r--r--drivers/char/drm/drm_hashtab.c190
-rw-r--r--drivers/char/drm/drm_hashtab.h67
-rw-r--r--drivers/char/drm/drm_ioc32.c2
-rw-r--r--drivers/char/drm/drm_ioctl.c34
-rw-r--r--drivers/char/drm/drm_irq.c12
-rw-r--r--drivers/char/drm/drm_mm.c201
-rw-r--r--drivers/char/drm/drm_pciids.h187
-rw-r--r--drivers/char/drm/drm_proc.c2
-rw-r--r--drivers/char/drm/drm_sman.c352
-rw-r--r--drivers/char/drm/drm_sman.h176
-rw-r--r--drivers/char/drm/drm_stub.c12
-rw-r--r--drivers/char/drm/drm_vm.c45
-rw-r--r--drivers/char/drm/i810_dma.c10
-rw-r--r--drivers/char/drm/i830_dma.c4
-rw-r--r--drivers/char/drm/i915_dma.c45
-rw-r--r--drivers/char/drm/i915_drm.h6
-rw-r--r--drivers/char/drm/i915_drv.h10
-rw-r--r--drivers/char/drm/i915_irq.c16
-rw-r--r--drivers/char/drm/radeon_cp.c72
-rw-r--r--drivers/char/drm/radeon_drv.c2
-rw-r--r--drivers/char/drm/radeon_drv.h36
-rw-r--r--drivers/char/drm/radeon_state.c48
-rw-r--r--drivers/char/drm/sis_drv.c39
-rw-r--r--drivers/char/drm/sis_drv.h34
-rw-r--r--drivers/char/drm/sis_ds.c299
-rw-r--r--drivers/char/drm/sis_ds.h146
-rw-r--r--drivers/char/drm/sis_mm.c504
-rw-r--r--drivers/char/drm/via_dmablit.c68
-rw-r--r--drivers/char/drm/via_drm.h8
-rw-r--r--drivers/char/drm/via_drv.c3
-rw-r--r--drivers/char/drm/via_drv.h16
-rw-r--r--drivers/char/drm/via_ds.c273
-rw-r--r--drivers/char/drm/via_ds.h104
-rw-r--r--drivers/char/drm/via_map.c9
-rw-r--r--drivers/char/drm/via_mm.c375
-rw-r--r--drivers/char/ds1286.c15
-rw-r--r--drivers/char/epca.c2
-rw-r--r--drivers/char/esp.c2
-rw-r--r--drivers/char/generic_serial.c11
-rw-r--r--drivers/char/hvc_console.c2
-rw-r--r--drivers/char/hvc_iseries.c7
-rw-r--r--drivers/char/hvcs.c2
-rw-r--r--drivers/char/hvsi.c2
-rw-r--r--drivers/char/hw_random/intel-rng.c186
-rw-r--r--drivers/char/ip2/ip2main.c14
-rw-r--r--drivers/char/ipmi/ipmi_devintf.c34
-rw-r--r--drivers/char/ipmi/ipmi_msghandler.c75
-rw-r--r--drivers/char/ipmi/ipmi_si_intf.c26
-rw-r--r--drivers/char/isicom.c37
-rw-r--r--drivers/char/istallion.c22
-rw-r--r--drivers/char/keyboard.c25
-rw-r--r--drivers/char/lp.c4
-rw-r--r--drivers/char/mbcs.c7
-rw-r--r--drivers/char/mem.c8
-rw-r--r--drivers/char/moxa.c82
-rw-r--r--drivers/char/mwave/mwavedd.c4
-rw-r--r--drivers/char/mxser.c68
-rw-r--r--drivers/char/nwbutton.c5
-rw-r--r--drivers/char/pc8736x_gpio.c10
-rw-r--r--drivers/char/pcmcia/synclink_cs.c3
-rw-r--r--drivers/char/pty.c2
-rw-r--r--drivers/char/random.c8
-rw-r--r--drivers/char/raw.c50
-rw-r--r--drivers/char/rio/rio_linux.c2
-rw-r--r--drivers/char/riscom8.c24
-rw-r--r--drivers/char/rocket.c2
-rw-r--r--drivers/char/rtc.c4
-rw-r--r--drivers/char/s3c2410-rtc.c591
-rw-r--r--drivers/char/scx200_gpio.c4
-rw-r--r--drivers/char/selection.c2
-rw-r--r--drivers/char/ser_a2232.c2
-rw-r--r--drivers/char/serial167.c2
-rw-r--r--drivers/char/snsc_event.c2
-rw-r--r--drivers/char/specialix.c29
-rw-r--r--drivers/char/stallion.c2
-rw-r--r--drivers/char/sx.c2
-rw-r--r--drivers/char/synclink.c3
-rw-r--r--drivers/char/synclink_gt.c96
-rw-r--r--drivers/char/synclinkmp.c2
-rw-r--r--drivers/char/sysrq.c3
-rw-r--r--drivers/char/tipar.c6
-rw-r--r--drivers/char/tty_io.c107
-rw-r--r--drivers/char/tty_ioctl.c35
-rw-r--r--drivers/char/vc_screen.c5
-rw-r--r--drivers/char/viocons.c2
-rw-r--r--drivers/char/vme_scc.c2
-rw-r--r--drivers/char/vt.c146
-rw-r--r--drivers/char/vt_ioctl.c34
-rw-r--r--drivers/char/watchdog/Kconfig18
-rw-r--r--drivers/char/watchdog/Makefile2
-rw-r--r--drivers/char/watchdog/acquirewdt.c2
-rw-r--r--drivers/char/watchdog/advantechwdt.c2
-rw-r--r--drivers/char/watchdog/alim1535_wdt.c12
-rw-r--r--drivers/char/watchdog/alim7101_wdt.c17
-rw-r--r--drivers/char/watchdog/at91_wdt.c2
-rw-r--r--drivers/char/watchdog/booke_wdt.c2
-rw-r--r--drivers/char/watchdog/cpu5wdt.c2
-rw-r--r--drivers/char/watchdog/ep93xx_wdt.c2
-rw-r--r--drivers/char/watchdog/eurotechwdt.c2
-rw-r--r--drivers/char/watchdog/i6300esb.c2
-rw-r--r--drivers/char/watchdog/i8xx_tco.c35
-rw-r--r--drivers/char/watchdog/ib700wdt.c2
-rw-r--r--drivers/char/watchdog/ibmasr.c2
-rw-r--r--drivers/char/watchdog/indydog.c2
-rw-r--r--drivers/char/watchdog/ixp2000_wdt.c2
-rw-r--r--drivers/char/watchdog/ixp4xx_wdt.c2
-rw-r--r--drivers/char/watchdog/machzwd.c5
-rw-r--r--drivers/char/watchdog/mixcomwd.c2
-rw-r--r--drivers/char/watchdog/mpc83xx_wdt.c2
-rw-r--r--drivers/char/watchdog/mpc8xx_wdt.c2
-rw-r--r--drivers/char/watchdog/mpcore_wdt.c4
-rw-r--r--drivers/char/watchdog/mv64x60_wdt.c2
-rw-r--r--drivers/char/watchdog/omap_wdt.c391
-rw-r--r--drivers/char/watchdog/omap_wdt.h64
-rw-r--r--drivers/char/watchdog/pcwd.c2
-rw-r--r--drivers/char/watchdog/pcwd_pci.c2
-rw-r--r--drivers/char/watchdog/pcwd_usb.c2
-rw-r--r--drivers/char/watchdog/pnx4008_wdt.c362
-rw-r--r--drivers/char/watchdog/s3c2410_wdt.c12
-rw-r--r--drivers/char/watchdog/sa1100_wdt.c2
-rw-r--r--drivers/char/watchdog/sbc60xxwdt.c2
-rw-r--r--drivers/char/watchdog/sbc_epx_c3.c2
-rw-r--r--drivers/char/watchdog/sc1200wdt.c2
-rw-r--r--drivers/char/watchdog/sc520_wdt.c2
-rw-r--r--drivers/char/watchdog/scx200_wdt.c2
-rw-r--r--drivers/char/watchdog/shwdt.c2
-rw-r--r--drivers/char/watchdog/softdog.c2
-rw-r--r--drivers/char/watchdog/w83627hf_wdt.c2
-rw-r--r--drivers/char/watchdog/w83877f_wdt.c2
-rw-r--r--drivers/char/watchdog/w83977f_wdt.c2
-rw-r--r--drivers/char/watchdog/wafer5823wdt.c2
-rw-r--r--drivers/char/watchdog/wdrtas.c2
-rw-r--r--drivers/char/watchdog/wdt.c2
-rw-r--r--drivers/char/watchdog/wdt285.c2
-rw-r--r--drivers/char/watchdog/wdt977.c2
-rw-r--r--drivers/char/watchdog/wdt_pci.c2
-rw-r--r--drivers/cpufreq/cpufreq.c2
-rw-r--r--drivers/fc4/fc.c1
-rw-r--r--drivers/firmware/dell_rbu.c4
-rw-r--r--drivers/firmware/dmi_scan.c23
-rw-r--r--drivers/hwmon/hdaps.c1
-rw-r--r--drivers/i2c/busses/i2c-ite.c2
-rw-r--r--drivers/i2c/busses/i2c-sibyte.c4
-rw-r--r--drivers/i2c/i2c-core.c25
-rw-r--r--drivers/ide/Kconfig12
-rw-r--r--drivers/ide/ide-cd.c69
-rw-r--r--drivers/ide/ide-disk.c5
-rw-r--r--drivers/ide/ide-dma.c64
-rw-r--r--drivers/ide/ide-floppy.c17
-rw-r--r--drivers/ide/ide-io.c82
-rw-r--r--drivers/ide/ide-iops.c4
-rw-r--r--drivers/ide/ide-lib.c130
-rw-r--r--drivers/ide/ide-probe.c25
-rw-r--r--drivers/ide/ide-proc.c22
-rw-r--r--drivers/ide/ide-tape.c16
-rw-r--r--drivers/ide/ide-taskfile.c8
-rw-r--r--drivers/ide/ide.c35
-rw-r--r--drivers/ide/legacy/hd.c2
-rw-r--r--drivers/ide/legacy/ide-cs.c7
-rw-r--r--drivers/ide/pci/Makefile1
-rw-r--r--drivers/ide/pci/atiixp.c21
-rw-r--r--drivers/ide/pci/cs5530.c13
-rw-r--r--drivers/ide/pci/cy82c693.c5
-rw-r--r--drivers/ide/pci/generic.c11
-rw-r--r--drivers/ide/pci/jmicron.c269
-rw-r--r--drivers/ide/pci/pdc202xx_old.c22
-rw-r--r--drivers/ide/pci/piix.c33
-rw-r--r--drivers/ide/pci/sc1200.c4
-rw-r--r--drivers/ide/pci/serverworks.c8
-rw-r--r--drivers/ide/pci/sgiioc4.c20
-rw-r--r--drivers/ide/pci/siimage.c1
-rw-r--r--drivers/ide/pci/sis5513.c3
-rw-r--r--drivers/ide/pci/via82cxxx.c5
-rw-r--r--drivers/ide/setup-pci.c20
-rw-r--r--drivers/ieee1394/Kconfig11
-rw-r--r--drivers/ieee1394/csr.c31
-rw-r--r--drivers/ieee1394/csr.h109
-rw-r--r--drivers/ieee1394/dma.c7
-rw-r--r--drivers/ieee1394/dma.h90
-rw-r--r--drivers/ieee1394/dv1394-private.h6
-rw-r--r--drivers/ieee1394/dv1394.c47
-rw-r--r--drivers/ieee1394/eth1394.c12
-rw-r--r--drivers/ieee1394/highlevel.h201
-rw-r--r--drivers/ieee1394/hosts.c23
-rw-r--r--drivers/ieee1394/hosts.h51
-rw-r--r--drivers/ieee1394/ieee1394-ioctl.h9
-rw-r--r--drivers/ieee1394/ieee1394.h316
-rw-r--r--drivers/ieee1394/ieee1394_core.c9
-rw-r--r--drivers/ieee1394/ieee1394_core.h28
-rw-r--r--drivers/ieee1394/ieee1394_hotplug.h30
-rw-r--r--drivers/ieee1394/ieee1394_transactions.c114
-rw-r--r--drivers/ieee1394/ieee1394_transactions.h41
-rw-r--r--drivers/ieee1394/ieee1394_types.h68
-rw-r--r--drivers/ieee1394/iso.c5
-rw-r--r--drivers/ieee1394/iso.h87
-rw-r--r--drivers/ieee1394/nodemgr.c227
-rw-r--r--drivers/ieee1394/nodemgr.h27
-rw-r--r--drivers/ieee1394/ohci1394.c73
-rw-r--r--drivers/ieee1394/raw1394-private.h3
-rw-r--r--drivers/ieee1394/raw1394.c138
-rw-r--r--drivers/ieee1394/sbp2.c481
-rw-r--r--drivers/ieee1394/sbp2.h37
-rw-r--r--drivers/ieee1394/video1394.c52
-rw-r--r--drivers/infiniband/core/addr.c4
-rw-r--r--drivers/infiniband/core/cma.c47
-rw-r--r--drivers/infiniband/hw/amso1100/c2_ae.c2
-rw-r--r--drivers/infiniband/hw/amso1100/c2_alloc.c2
-rw-r--r--drivers/infiniband/hw/amso1100/c2_cm.c15
-rw-r--r--drivers/infiniband/hw/amso1100/c2_provider.c8
-rw-r--r--drivers/infiniband/hw/amso1100/c2_rnic.c4
-rw-r--r--drivers/infiniband/hw/ehca/ehca_main.c36
-rw-r--r--drivers/infiniband/hw/ehca/ehca_tools.h2
-rw-r--r--drivers/infiniband/hw/ipath/ipath_common.h54
-rw-r--r--drivers/infiniband/hw/ipath/ipath_cq.c48
-rw-r--r--drivers/infiniband/hw/ipath/ipath_driver.c359
-rw-r--r--drivers/infiniband/hw/ipath/ipath_eeprom.c17
-rw-r--r--drivers/infiniband/hw/ipath/ipath_file_ops.c974
-rw-r--r--drivers/infiniband/hw/ipath/ipath_fs.c13
-rw-r--r--drivers/infiniband/hw/ipath/ipath_iba6110.c132
-rw-r--r--drivers/infiniband/hw/ipath/ipath_iba6120.c263
-rw-r--r--drivers/infiniband/hw/ipath/ipath_init_chip.c56
-rw-r--r--drivers/infiniband/hw/ipath/ipath_intr.c280
-rw-r--r--drivers/infiniband/hw/ipath/ipath_kernel.h116
-rw-r--r--drivers/infiniband/hw/ipath/ipath_keys.c12
-rw-r--r--drivers/infiniband/hw/ipath/ipath_mad.c16
-rw-r--r--drivers/infiniband/hw/ipath/ipath_mr.c3
-rw-r--r--drivers/infiniband/hw/ipath/ipath_qp.c16
-rw-r--r--drivers/infiniband/hw/ipath/ipath_rc.c136
-rw-r--r--drivers/infiniband/hw/ipath/ipath_registers.h40
-rw-r--r--drivers/infiniband/hw/ipath/ipath_ruc.c14
-rw-r--r--drivers/infiniband/hw/ipath/ipath_srq.c23
-rw-r--r--drivers/infiniband/hw/ipath/ipath_sysfs.c21
-rw-r--r--drivers/infiniband/hw/ipath/ipath_uc.c6
-rw-r--r--drivers/infiniband/hw/ipath/ipath_ud.c6
-rw-r--r--drivers/infiniband/hw/ipath/ipath_user_pages.c56
-rw-r--r--drivers/infiniband/hw/ipath/ipath_verbs.c45
-rw-r--r--drivers/infiniband/hw/ipath/ipath_verbs.h18
-rw-r--r--drivers/infiniband/hw/ipath/ipath_wc_ppc64.c20
-rw-r--r--drivers/infiniband/hw/ipath/ipath_wc_x86_64.c13
-rw-r--r--drivers/infiniband/ulp/iser/Kconfig13
-rw-r--r--drivers/infiniband/ulp/iser/iscsi_iser.c2
-rw-r--r--drivers/infiniband/ulp/iser/iscsi_iser.h9
-rw-r--r--drivers/infiniband/ulp/iser/iser_initiator.c60
-rw-r--r--drivers/infiniband/ulp/iser/iser_memory.c42
-rw-r--r--drivers/infiniband/ulp/iser/iser_verbs.c8
-rw-r--r--drivers/input/Kconfig14
-rw-r--r--drivers/input/Makefile6
-rw-r--r--drivers/input/evbug.c11
-rw-r--r--drivers/input/evdev.c42
-rw-r--r--drivers/input/ff-core.c367
-rw-r--r--drivers/input/ff-memless.c515
-rw-r--r--drivers/input/fixp-arith.h (renamed from drivers/usb/input/fixp-arith.h)0
-rw-r--r--drivers/input/input.c46
-rw-r--r--drivers/input/joydev.c12
-rw-r--r--drivers/input/joystick/iforce/iforce-ff.c118
-rw-r--r--drivers/input/joystick/iforce/iforce-main.c226
-rw-r--r--drivers/input/joystick/iforce/iforce-packets.c15
-rw-r--r--drivers/input/joystick/iforce/iforce.h26
-rw-r--r--drivers/input/keyboard/Kconfig20
-rw-r--r--drivers/input/keyboard/Makefile2
-rw-r--r--drivers/input/keyboard/atkbd.c4
-rw-r--r--drivers/input/keyboard/omap-keypad.c492
-rw-r--r--drivers/input/keyboard/stowaway.c187
-rw-r--r--drivers/input/misc/uinput.c67
-rw-r--r--drivers/input/misc/wistron_btns.c18
-rw-r--r--drivers/input/mouse/alps.c8
-rw-r--r--drivers/input/mouse/alps.h2
-rw-r--r--drivers/input/mouse/lifebook.c8
-rw-r--r--drivers/input/mouse/logips2pp.c23
-rw-r--r--drivers/input/mouse/psmouse-base.c42
-rw-r--r--drivers/input/mouse/sermouse.c2
-rw-r--r--drivers/input/mouse/synaptics.c10
-rw-r--r--drivers/input/mousedev.c28
-rw-r--r--drivers/input/power.c7
-rw-r--r--drivers/input/serio/i8042-io.h15
-rw-r--r--drivers/input/serio/i8042-x86ia64io.h14
-rw-r--r--drivers/input/serio/i8042.c741
-rw-r--r--drivers/input/serio/i8042.h9
-rw-r--r--drivers/input/serio/libps2.c36
-rw-r--r--drivers/input/touchscreen/Kconfig36
-rw-r--r--drivers/input/touchscreen/Makefile3
-rw-r--r--drivers/input/touchscreen/elo.c167
-rw-r--r--drivers/input/touchscreen/penmount.c185
-rw-r--r--drivers/input/touchscreen/touchright.c196
-rw-r--r--drivers/input/touchscreen/touchwin.c203
-rw-r--r--drivers/input/tsdev.c12
-rw-r--r--drivers/isdn/capi/capi.c2
-rw-r--r--drivers/isdn/gigaset/interface.c2
-rw-r--r--drivers/isdn/gigaset/proc.c3
-rw-r--r--drivers/isdn/hardware/eicon/dsp_defs.h3
-rw-r--r--drivers/isdn/hisax/config.c6
-rw-r--r--drivers/isdn/hisax/hfc4s8s_l1.c7
-rw-r--r--drivers/isdn/hisax/hfc_sx.c4
-rw-r--r--drivers/isdn/hisax/hfc_usb.c4
-rw-r--r--drivers/isdn/hisax/hisax.h13
-rw-r--r--drivers/isdn/hisax/hisax_fcpcipnp.c17
-rw-r--r--drivers/isdn/hisax/st5481_b.c8
-rw-r--r--drivers/isdn/hisax/st5481_d.c4
-rw-r--r--drivers/isdn/i4l/isdn_net.c4
-rw-r--r--drivers/isdn/i4l/isdn_tty.c2
-rw-r--r--drivers/isdn/sc/command.c22
-rw-r--r--drivers/isdn/sc/event.c2
-rw-r--r--drivers/isdn/sc/interrupt.c2
-rw-r--r--drivers/isdn/sc/timer.c2
-rw-r--r--drivers/leds/led-triggers.c1
-rw-r--r--drivers/leds/leds-net48xx.c9
-rw-r--r--drivers/macintosh/smu.c4
-rw-r--r--drivers/macintosh/via-pmu-backlight.c2
-rw-r--r--drivers/macintosh/via-pmu.c21
-rw-r--r--drivers/macintosh/via-pmu68k.c6
-rw-r--r--drivers/macintosh/windfarm_smu_controls.c2
-rw-r--r--drivers/macintosh/windfarm_smu_sat.c7
-rw-r--r--drivers/macintosh/windfarm_smu_sensors.c2
-rw-r--r--drivers/md/Kconfig21
-rw-r--r--drivers/md/bitmap.c17
-rw-r--r--drivers/md/dm-crypt.c506
-rw-r--r--drivers/md/dm-emc.c3
-rw-r--r--drivers/md/dm-exception-store.c176
-rw-r--r--drivers/md/dm-linear.c19
-rw-r--r--drivers/md/dm-mpath.c83
-rw-r--r--drivers/md/dm-raid1.c4
-rw-r--r--drivers/md/dm-snap.c351
-rw-r--r--drivers/md/dm-snap.h17
-rw-r--r--drivers/md/dm-table.c109
-rw-r--r--drivers/md/dm.c113
-rw-r--r--drivers/md/dm.h7
-rw-r--r--drivers/md/linear.c15
-rw-r--r--drivers/md/md.c275
-rw-r--r--drivers/md/multipath.c27
-rw-r--r--drivers/md/raid0.c17
-rw-r--r--drivers/md/raid1.c247
-rw-r--r--drivers/md/raid10.c261
-rw-r--r--drivers/md/raid5.c74
-rw-r--r--drivers/media/common/Kconfig1
-rw-r--r--drivers/media/common/ir-keymaps.c79
-rw-r--r--drivers/media/common/saa7146_fops.c1
-rw-r--r--drivers/media/dvb/b2c2/Kconfig14
-rw-r--r--drivers/media/dvb/b2c2/flexcop-fe-tuner.c24
-rw-r--r--drivers/media/dvb/bt8xx/Kconfig14
-rw-r--r--drivers/media/dvb/bt8xx/dst.c9
-rw-r--r--drivers/media/dvb/bt8xx/dst_ca.c11
-rw-r--r--drivers/media/dvb/bt8xx/dst_common.h3
-rw-r--r--drivers/media/dvb/bt8xx/dvb-bt8xx.c37
-rw-r--r--drivers/media/dvb/dvb-core/Kconfig13
-rw-r--r--drivers/media/dvb/dvb-core/dvb_frontend.c42
-rw-r--r--drivers/media/dvb/dvb-core/dvb_frontend.h7
-rw-r--r--drivers/media/dvb/dvb-core/dvb_ringbuffer.c1
-rw-r--r--drivers/media/dvb/dvb-core/dvbdev.h22
-rw-r--r--drivers/media/dvb/dvb-usb/Kconfig17
-rw-r--r--drivers/media/dvb/dvb-usb/a800.c8
-rw-r--r--drivers/media/dvb/dvb-usb/cxusb.c11
-rw-r--r--drivers/media/dvb/dvb-usb/dibusb-common.c200
-rw-r--r--drivers/media/dvb/dvb-usb/dibusb-mb.c18
-rw-r--r--drivers/media/dvb/dvb-usb/dibusb-mc.c41
-rw-r--r--drivers/media/dvb/dvb-usb/dibusb.h3
-rw-r--r--drivers/media/dvb/dvb-usb/digitv.c86
-rw-r--r--drivers/media/dvb/dvb-usb/dtt200u.c50
-rw-r--r--drivers/media/dvb/dvb-usb/dvb-usb-dvb.c20
-rw-r--r--drivers/media/dvb/dvb-usb/dvb-usb-ids.h124
-rw-r--r--drivers/media/dvb/dvb-usb/dvb-usb-remote.c5
-rw-r--r--drivers/media/dvb/dvb-usb/nova-t-usb2.c2
-rw-r--r--drivers/media/dvb/dvb-usb/umt-010.c2
-rw-r--r--drivers/media/dvb/frontends/Kconfig71
-rw-r--r--drivers/media/dvb/frontends/Makefile8
-rw-r--r--drivers/media/dvb/frontends/bcm3510.h9
-rw-r--r--drivers/media/dvb/frontends/cx22700.h9
-rw-r--r--drivers/media/dvb/frontends/cx22702.c4
-rw-r--r--drivers/media/dvb/frontends/cx22702.h9
-rw-r--r--drivers/media/dvb/frontends/cx24110.c17
-rw-r--r--drivers/media/dvb/frontends/cx24110.h19
-rw-r--r--drivers/media/dvb/frontends/cx24123.c98
-rw-r--r--drivers/media/dvb/frontends/cx24123.h12
-rw-r--r--drivers/media/dvb/frontends/dib3000-common.c83
-rw-r--r--drivers/media/dvb/frontends/dib3000-common.h135
-rw-r--r--drivers/media/dvb/frontends/dib3000.h11
-rw-r--r--drivers/media/dvb/frontends/dib3000mb.c76
-rw-r--r--drivers/media/dvb/frontends/dib3000mb_priv.h93
-rw-r--r--drivers/media/dvb/frontends/dib3000mc.c1432
-rw-r--r--drivers/media/dvb/frontends/dib3000mc.h58
-rw-r--r--drivers/media/dvb/frontends/dib3000mc_priv.h428
-rw-r--r--drivers/media/dvb/frontends/dibx000_common.c152
-rw-r--r--drivers/media/dvb/frontends/dibx000_common.h166
-rw-r--r--drivers/media/dvb/frontends/dvb-pll.c11
-rw-r--r--drivers/media/dvb/frontends/dvb-pll.h4
-rw-r--r--drivers/media/dvb/frontends/isl6421.c30
-rw-r--r--drivers/media/dvb/frontends/isl6421.h11
-rw-r--r--drivers/media/dvb/frontends/l64781.h10
-rw-r--r--drivers/media/dvb/frontends/lgdt330x.h9
-rw-r--r--drivers/media/dvb/frontends/lnbp21.c30
-rw-r--r--drivers/media/dvb/frontends/lnbp21.h12
-rw-r--r--drivers/media/dvb/frontends/mt2060.c367
-rw-r--r--drivers/media/dvb/frontends/mt2060.h35
-rw-r--r--drivers/media/dvb/frontends/mt2060_priv.h105
-rw-r--r--drivers/media/dvb/frontends/mt312.h10
-rw-r--r--drivers/media/dvb/frontends/mt352.c16
-rw-r--r--drivers/media/dvb/frontends/mt352.h16
-rw-r--r--drivers/media/dvb/frontends/nxt200x.h9
-rw-r--r--drivers/media/dvb/frontends/nxt6000.h9
-rw-r--r--drivers/media/dvb/frontends/or51132.h9
-rw-r--r--drivers/media/dvb/frontends/or51211.h9
-rw-r--r--drivers/media/dvb/frontends/s5h1420.h9
-rw-r--r--drivers/media/dvb/frontends/sp8870.h9
-rw-r--r--drivers/media/dvb/frontends/sp887x.h9
-rw-r--r--drivers/media/dvb/frontends/stv0297.h9
-rw-r--r--drivers/media/dvb/frontends/stv0299.c9
-rw-r--r--drivers/media/dvb/frontends/stv0299.h19
-rw-r--r--drivers/media/dvb/frontends/tda10021.c63
-rw-r--r--drivers/media/dvb/frontends/tda10021.h19
-rw-r--r--drivers/media/dvb/frontends/tda1004x.c10
-rw-r--r--drivers/media/dvb/frontends/tda1004x.h25
-rw-r--r--drivers/media/dvb/frontends/tda10086.c740
-rw-r--r--drivers/media/dvb/frontends/tda10086.h41
-rw-r--r--drivers/media/dvb/frontends/tda8083.h9
-rw-r--r--drivers/media/dvb/frontends/tda826x.c173
-rw-r--r--drivers/media/dvb/frontends/tda826x.h40
-rw-r--r--drivers/media/dvb/frontends/tua6100.c205
-rw-r--r--drivers/media/dvb/frontends/tua6100.h47
-rw-r--r--drivers/media/dvb/frontends/ves1820.h9
-rw-r--r--drivers/media/dvb/frontends/ves1x93.h9
-rw-r--r--drivers/media/dvb/frontends/zl10353.c11
-rw-r--r--drivers/media/dvb/frontends/zl10353.h14
-rw-r--r--drivers/media/dvb/ttpci/Kconfig57
-rw-r--r--drivers/media/dvb/ttpci/av7110.c58
-rw-r--r--drivers/media/dvb/ttpci/av7110_av.c1
-rw-r--r--drivers/media/dvb/ttpci/av7110_ca.c1
-rw-r--r--drivers/media/dvb/ttpci/av7110_hw.c1
-rw-r--r--drivers/media/dvb/ttpci/av7110_v4l.c3
-rw-r--r--drivers/media/dvb/ttpci/budget-av.c184
-rw-r--r--drivers/media/dvb/ttpci/budget-ci.c32
-rw-r--r--drivers/media/dvb/ttpci/budget-patch.c17
-rw-r--r--drivers/media/dvb/ttpci/budget.c53
-rw-r--r--drivers/media/dvb/ttusb-budget/Kconfig14
-rw-r--r--drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c28
-rw-r--r--drivers/media/dvb/ttusb-dec/ttusb_dec.c6
-rw-r--r--drivers/media/radio/Kconfig30
-rw-r--r--drivers/media/radio/dsbr100.c198
-rw-r--r--drivers/media/radio/radio-aimslab.c151
-rw-r--r--drivers/media/radio/radio-aztech.c166
-rw-r--r--drivers/media/radio/radio-cadet.c250
-rw-r--r--drivers/media/radio/radio-gemtek-pci.c170
-rw-r--r--drivers/media/radio/radio-gemtek.c165
-rw-r--r--drivers/media/radio/radio-maestro.c197
-rw-r--r--drivers/media/radio/radio-maxiradio.c166
-rw-r--r--drivers/media/radio/radio-rtrack2.c163
-rw-r--r--drivers/media/radio/radio-sf16fmi.c158
-rw-r--r--drivers/media/radio/radio-sf16fmr2.c223
-rw-r--r--drivers/media/radio/radio-terratec.c154
-rw-r--r--drivers/media/radio/radio-trust.c188
-rw-r--r--drivers/media/radio/radio-typhoon.c171
-rw-r--r--drivers/media/radio/radio-zoltrix.c183
-rw-r--r--drivers/media/video/Kconfig476
-rw-r--r--drivers/media/video/Makefile45
-rw-r--r--drivers/media/video/bt866.c2
-rw-r--r--drivers/media/video/bt8xx/Kconfig5
-rw-r--r--drivers/media/video/bt8xx/bttv-cards.c2
-rw-r--r--drivers/media/video/bt8xx/bttv-driver.c12
-rw-r--r--drivers/media/video/bt8xx/bttv-i2c.c16
-rw-r--r--drivers/media/video/compat_ioctl32.c59
-rw-r--r--drivers/media/video/cpia2/cpia2.h4
-rw-r--r--drivers/media/video/cx2341x.c25
-rw-r--r--drivers/media/video/cx25840/Kconfig2
-rw-r--r--drivers/media/video/cx25840/cx25840-vbi.c4
-rw-r--r--drivers/media/video/cx88/Kconfig109
-rw-r--r--drivers/media/video/cx88/Makefile7
-rw-r--r--drivers/media/video/cx88/cx88-blackbird.c2
-rw-r--r--drivers/media/video/cx88/cx88-cards.c161
-rw-r--r--drivers/media/video/cx88/cx88-core.c13
-rw-r--r--drivers/media/video/cx88/cx88-dvb.c330
-rw-r--r--drivers/media/video/cx88/cx88-i2c.c13
-rw-r--r--drivers/media/video/cx88/cx88-input.c19
-rw-r--r--drivers/media/video/cx88/cx88-tvaudio.c5
-rw-r--r--drivers/media/video/cx88/cx88-video.c7
-rw-r--r--drivers/media/video/cx88/cx88.h5
-rw-r--r--drivers/media/video/em28xx/Kconfig3
-rw-r--r--drivers/media/video/em28xx/em28xx-video.c2
-rw-r--r--drivers/media/video/ks0127.c3
-rw-r--r--drivers/media/video/pvrusb2/Kconfig18
-rw-r--r--drivers/media/video/pvrusb2/Makefile6
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-ctrl.c21
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.c2
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-encoder.c4
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h31
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-hdw.c84
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-i2c-chips-v4l2.c4
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-i2c-cmd-v4l2.c2
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-i2c-core.c6
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-main.c1
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-sysfs.c3
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-v4l2.c36
-rw-r--r--drivers/media/video/saa5246a.c1
-rw-r--r--drivers/media/video/saa5249.c1
-rw-r--r--drivers/media/video/saa7115.c1250
-rw-r--r--drivers/media/video/saa711x_regs.h549
-rw-r--r--drivers/media/video/saa7134/Kconfig50
-rw-r--r--drivers/media/video/saa7134/Makefile3
-rw-r--r--drivers/media/video/saa7134/saa7134-alsa.c8
-rw-r--r--drivers/media/video/saa7134/saa7134-cards.c127
-rw-r--r--drivers/media/video/saa7134/saa7134-core.c2
-rw-r--r--drivers/media/video/saa7134/saa7134-dvb.c197
-rw-r--r--drivers/media/video/saa7134/saa7134-input.c6
-rw-r--r--drivers/media/video/saa7134/saa7134-tvaudio.c1
-rw-r--r--drivers/media/video/saa7134/saa7134.h3
-rw-r--r--drivers/media/video/tda9887.c2
-rw-r--r--drivers/media/video/tuner-simple.c6
-rw-r--r--drivers/media/video/tuner-types.c1
-rw-r--r--drivers/media/video/tvaudio.c42
-rw-r--r--drivers/media/video/tveeprom.c2
-rw-r--r--drivers/media/video/tvp5150.c7
-rw-r--r--drivers/media/video/usbvideo/konicawc.c9
-rw-r--r--drivers/media/video/usbvideo/vicam.c4
-rw-r--r--drivers/media/video/v4l1-compat.c12
-rw-r--r--drivers/media/video/v4l2-common.c1
-rw-r--r--drivers/media/video/video-buf-dvb.c2
-rw-r--r--drivers/media/video/videodev.c32
-rw-r--r--drivers/media/video/vino.c1
-rw-r--r--drivers/media/video/vivi.c5
-rw-r--r--drivers/media/video/vpx3220.c2
-rw-r--r--drivers/media/video/zoran_card.c6
-rw-r--r--drivers/media/video/zoran_driver.c7
-rw-r--r--drivers/media/video/zr36120.c6
-rw-r--r--drivers/message/i2o/Kconfig2
-rw-r--r--drivers/message/i2o/i2o_block.c7
-rw-r--r--drivers/message/i2o/pci.c7
-rw-r--r--drivers/mfd/ucb1x00-ts.c45
-rw-r--r--drivers/misc/Makefile3
-rw-r--r--drivers/misc/lkdtm.c342
-rw-r--r--drivers/mmc/Kconfig2
-rw-r--r--drivers/mmc/Makefile3
-rw-r--r--drivers/mmc/mmc_queue.c6
-rw-r--r--drivers/mmc/sdhci.c5
-rw-r--r--drivers/mmc/sdhci.h5
-rw-r--r--drivers/mmc/wbsd.c5
-rw-r--r--drivers/mmc/wbsd.h5
-rw-r--r--drivers/mtd/Kconfig12
-rw-r--r--drivers/mtd/devices/Kconfig2
-rw-r--r--drivers/mtd/maps/arctic-mtd.c6
-rw-r--r--drivers/mtd/maps/beech-mtd.c6
-rw-r--r--drivers/mtd/maps/cstm_mips_ixx.c8
-rw-r--r--drivers/mtd/maps/nettel.c2
-rw-r--r--drivers/mtd/maps/redwood.c2
-rw-r--r--drivers/mtd/mtd_blkdevs.c4
-rw-r--r--drivers/mtd/nand/edb7312.c2
-rw-r--r--drivers/mtd/nand/nand_base.c172
-rw-r--r--drivers/mtd/nand/nand_bbt.c2
-rw-r--r--drivers/mtd/nftlcore.c4
-rw-r--r--drivers/mtd/onenand/Kconfig6
-rw-r--r--drivers/mtd/onenand/onenand_base.c154
-rw-r--r--drivers/net/8390.c6
-rw-r--r--drivers/net/Kconfig5
-rw-r--r--drivers/net/Space.c2
-rw-r--r--drivers/net/appletalk/ipddp.c5
-rw-r--r--drivers/net/bnx2.c32
-rw-r--r--drivers/net/bonding/bond_main.c2
-rw-r--r--drivers/net/dgrs.c1
-rw-r--r--drivers/net/e100.c82
-rw-r--r--drivers/net/e1000/LICENSE339
-rw-r--r--drivers/net/e1000/Makefile35
-rw-r--r--drivers/net/e1000/e1000.h59
-rw-r--r--drivers/net/e1000/e1000_ethtool.c150
-rw-r--r--drivers/net/e1000/e1000_hw.c1074
-rw-r--r--drivers/net/e1000/e1000_hw.h86
-rw-r--r--drivers/net/e1000/e1000_main.c271
-rw-r--r--drivers/net/e1000/e1000_osdep.h35
-rw-r--r--drivers/net/e1000/e1000_param.c47
-rw-r--r--drivers/net/fec_8xx/fec_main.c2
-rw-r--r--drivers/net/fs_enet/fs_enet-main.c5
-rw-r--r--drivers/net/fs_enet/fs_enet.h3
-rw-r--r--drivers/net/hp100.c9
-rw-r--r--drivers/net/ifb.c4
-rw-r--r--drivers/net/irda/Kconfig1
-rw-r--r--drivers/net/irda/nsc-ircc.c2
-rw-r--r--drivers/net/irda/smsc-ircc2.c38
-rw-r--r--drivers/net/irda/stir4200.c15
-rw-r--r--drivers/net/irda/via-ircc.c7
-rw-r--r--drivers/net/ixgb/Makefile38
-rw-r--r--drivers/net/ixgb/ixgb.h38
-rw-r--r--drivers/net/ixgb/ixgb_ee.c36
-rw-r--r--drivers/net/ixgb/ixgb_ee.h36
-rw-r--r--drivers/net/ixgb/ixgb_ethtool.c36
-rw-r--r--drivers/net/ixgb/ixgb_hw.c36
-rw-r--r--drivers/net/ixgb/ixgb_hw.h36
-rw-r--r--drivers/net/ixgb/ixgb_ids.h36
-rw-r--r--drivers/net/ixgb/ixgb_main.c46
-rw-r--r--drivers/net/ixgb/ixgb_osdep.h36
-rw-r--r--drivers/net/ixgb/ixgb_param.c36
-rw-r--r--drivers/net/loopback.c31
-rw-r--r--drivers/net/phy/fixed.c6
-rw-r--r--drivers/net/phy/phy_device.c8
-rw-r--r--drivers/net/pppoe.c1
-rw-r--r--drivers/net/sky2.c548
-rw-r--r--drivers/net/sky2.h62
-rw-r--r--drivers/net/smc91x.h1
-rw-r--r--drivers/net/spider_net.c6
-rw-r--r--drivers/net/tg3.c480
-rw-r--r--drivers/net/tg3.h48
-rw-r--r--drivers/net/tun.c39
-rw-r--r--drivers/net/wan/hdlc_cisco.c2
-rw-r--r--drivers/net/wan/syncppp.c4
-rw-r--r--drivers/net/wireless/airo.c23
-rw-r--r--drivers/net/wireless/ipw2100.c22
-rw-r--r--drivers/net/wireless/strip.c4
-rw-r--r--drivers/parisc/led.c2
-rw-r--r--drivers/parisc/power.c3
-rw-r--r--drivers/parport/parport_serial.c4
-rw-r--r--drivers/pci/quirks.c17
-rw-r--r--drivers/pcmcia/cardbus.c5
-rw-r--r--drivers/pcmcia/omap_cf.c25
-rw-r--r--drivers/pcmcia/socket_sysfs.c27
-rw-r--r--drivers/pnp/isapnp/core.c4
-rw-r--r--drivers/pnp/pnpbios/core.c8
-rw-r--r--drivers/rtc/Kconfig28
-rw-r--r--drivers/rtc/Makefile4
-rw-r--r--drivers/rtc/class.c6
-rw-r--r--drivers/rtc/rtc-at91.c24
-rw-r--r--drivers/rtc/rtc-dev.c7
-rw-r--r--drivers/rtc/rtc-ds1307.c2
-rw-r--r--drivers/rtc/rtc-ds1553.c10
-rw-r--r--drivers/rtc/rtc-ds1672.c2
-rw-r--r--drivers/rtc/rtc-ds1742.c12
-rw-r--r--drivers/rtc/rtc-ep93xx.c2
-rw-r--r--drivers/rtc/rtc-isl1208.c2
-rw-r--r--drivers/rtc/rtc-lib.c8
-rw-r--r--drivers/rtc/rtc-m48t86.c2
-rw-r--r--drivers/rtc/rtc-max6902.c2
-rw-r--r--drivers/rtc/rtc-pcf8563.c6
-rw-r--r--drivers/rtc/rtc-pcf8583.c2
-rw-r--r--drivers/rtc/rtc-pl031.c2
-rw-r--r--drivers/rtc/rtc-proc.c6
-rw-r--r--drivers/rtc/rtc-rs5c348.c11
-rw-r--r--drivers/rtc/rtc-rs5c372.c2
-rw-r--r--drivers/rtc/rtc-s3c.c2
-rw-r--r--drivers/rtc/rtc-sa1100.c2
-rw-r--r--drivers/rtc/rtc-sysfs.c2
-rw-r--r--drivers/rtc/rtc-test.c2
-rw-r--r--drivers/rtc/rtc-v3020.c5
-rw-r--r--drivers/rtc/rtc-vr41xx.c2
-rw-r--r--drivers/rtc/rtc-x1205.c2
-rw-r--r--drivers/s390/block/Kconfig2
-rw-r--r--drivers/s390/block/dasd_diag.c2
-rw-r--r--drivers/s390/block/dasd_eckd.c2
-rw-r--r--drivers/s390/block/dasd_fba.c2
-rw-r--r--drivers/s390/char/con3215.c2
-rw-r--r--drivers/s390/char/fs3270.c11
-rw-r--r--drivers/s390/char/sclp_tty.c2
-rw-r--r--drivers/s390/char/sclp_vt220.c2
-rw-r--r--drivers/s390/char/tty3270.c2
-rw-r--r--drivers/s390/net/qeth_main.c2
-rw-r--r--drivers/s390/s390mach.c2
-rw-r--r--drivers/s390/scsi/zfcp_scsi.c2
-rw-r--r--drivers/sbus/char/aurora.c2
-rw-r--r--drivers/sbus/char/bbc_envctrl.c5
-rw-r--r--drivers/sbus/char/envctrl.c7
-rw-r--r--drivers/scsi/53c700.c2
-rw-r--r--drivers/scsi/BusLogic.h5
-rw-r--r--drivers/scsi/Kconfig2
-rw-r--r--drivers/scsi/aic7xxx/aic79xx_osm.c4
-rw-r--r--drivers/scsi/aic7xxx/aic7xxx_osm.c2
-rw-r--r--drivers/scsi/aic7xxx_old.c4
-rw-r--r--drivers/scsi/gdth.c4
-rw-r--r--drivers/scsi/ide-scsi.c16
-rw-r--r--drivers/scsi/libsas/sas_scsi_host.c2
-rw-r--r--drivers/scsi/lpfc/lpfc_ct.c8
-rw-r--r--drivers/scsi/pluto.c6
-rw-r--r--drivers/scsi/qla1280.c4
-rw-r--r--drivers/scsi/scsi.c13
-rw-r--r--drivers/scsi/scsi_lib.c37
-rw-r--r--drivers/scsi/sd.c5
-rw-r--r--drivers/scsi/sun3_NCR5380.c2
-rw-r--r--drivers/scsi/sun3_scsi.c2
-rw-r--r--drivers/scsi/sun3_scsi_vme.c2
-rw-r--r--drivers/serial/68328serial.c2
-rw-r--r--drivers/serial/68360serial.c2
-rw-r--r--drivers/serial/8250.c39
-rw-r--r--drivers/serial/8250_acorn.c9
-rw-r--r--drivers/serial/8250_gsc.c1
-rw-r--r--drivers/serial/8250_pci.c4
-rw-r--r--drivers/serial/8250_pnp.c13
-rw-r--r--drivers/serial/Kconfig2
-rw-r--r--drivers/serial/cpm_uart/cpm_uart_core.c24
-rw-r--r--drivers/serial/cpm_uart/cpm_uart_cpm2.c143
-rw-r--r--drivers/serial/cpm_uart/cpm_uart_cpm2.h2
-rw-r--r--drivers/serial/crisv10.c2
-rw-r--r--drivers/serial/ioc4_serial.c3
-rw-r--r--drivers/serial/ip22zilog.c16
-rw-r--r--drivers/serial/m32r_sio.c5
-rw-r--r--drivers/serial/mcfserial.c2
-rw-r--r--drivers/serial/mpc52xx_uart.c11
-rw-r--r--drivers/serial/mpsc.c12
-rw-r--r--drivers/serial/mux.c2
-rw-r--r--drivers/serial/serial_core.c20
-rw-r--r--drivers/serial/serial_cs.c292
-rw-r--r--drivers/serial/serial_txx9.c2
-rw-r--r--drivers/serial/sunsu.c3
-rw-r--r--drivers/serial/sunzilog.c2
-rw-r--r--drivers/tc/zs.c2
-rw-r--r--drivers/usb/class/cdc-acm.c2
-rw-r--r--drivers/usb/core/devio.c10
-rw-r--r--drivers/usb/core/hcd.c4
-rw-r--r--drivers/usb/core/inode.c13
-rw-r--r--drivers/usb/core/usb.h2
-rw-r--r--drivers/usb/gadget/ether.c2
-rw-r--r--drivers/usb/gadget/file_storage.c2
-rw-r--r--drivers/usb/gadget/gmidi.c2
-rw-r--r--drivers/usb/gadget/inode.c82
-rw-r--r--drivers/usb/gadget/omap_udc.c2
-rw-r--r--drivers/usb/gadget/serial.c4
-rw-r--r--drivers/usb/gadget/zero.c2
-rw-r--r--drivers/usb/host/ohci-hub.c4
-rw-r--r--drivers/usb/input/Kconfig18
-rw-r--r--drivers/usb/input/Makefile5
-rw-r--r--drivers/usb/input/hid-core.c5
-rw-r--r--drivers/usb/input/hid-ff.c49
-rw-r--r--drivers/usb/input/hid-input.c23
-rw-r--r--drivers/usb/input/hid-lgff.c523
-rw-r--r--drivers/usb/input/hid-pidff.c1330
-rw-r--r--drivers/usb/input/hid-tmff.c399
-rw-r--r--drivers/usb/input/hid-zpff.c110
-rw-r--r--drivers/usb/input/hid.h32
-rw-r--r--drivers/usb/input/pid.c295
-rw-r--r--drivers/usb/input/pid.h62
-rw-r--r--drivers/usb/serial/usb-serial.c2
-rw-r--r--drivers/usb/storage/Kconfig5
-rw-r--r--drivers/video/Kconfig39
-rw-r--r--drivers/video/Makefile1
-rw-r--r--drivers/video/aty/atyfb.h6
-rw-r--r--drivers/video/aty/atyfb_base.c11
-rw-r--r--drivers/video/aty/mach64_ct.c2
-rw-r--r--drivers/video/aty/radeon_i2c.c106
-rw-r--r--drivers/video/aty/radeon_pm.c3
-rw-r--r--drivers/video/au1100fb.c30
-rw-r--r--drivers/video/console/fbcon.c54
-rw-r--r--drivers/video/console/fbcon.h2
-rw-r--r--drivers/video/console/fbcon_ccw.c2
-rw-r--r--drivers/video/console/fbcon_cw.c2
-rw-r--r--drivers/video/console/fbcon_ud.c2
-rw-r--r--drivers/video/console/softcursor.c31
-rw-r--r--drivers/video/fb_ddc.c116
-rw-r--r--drivers/video/fbmem.c3
-rw-r--r--drivers/video/fbsysfs.c35
-rw-r--r--drivers/video/i810/i810-i2c.c42
-rw-r--r--drivers/video/i810/i810_main.c6
-rw-r--r--drivers/video/intelfb/Makefile4
-rw-r--r--drivers/video/intelfb/intelfb.h79
-rw-r--r--drivers/video/intelfb/intelfb_i2c.c200
-rw-r--r--drivers/video/intelfb/intelfbdrv.c64
-rw-r--r--drivers/video/intelfb/intelfbhw.c136
-rw-r--r--drivers/video/intelfb/intelfbhw.h25
-rw-r--r--drivers/video/matrox/matroxfb_base.c12
-rw-r--r--drivers/video/mbx/mbxfb.c21
-rw-r--r--drivers/video/nvidia/nv_i2c.c45
-rw-r--r--drivers/video/nvidia/nvidia.c16
-rw-r--r--drivers/video/riva/fbdev.c8
-rw-r--r--drivers/video/riva/rivafb-i2c.c44
-rw-r--r--drivers/video/savage/savagefb-i2c.c49
-rw-r--r--drivers/video/sis/init.h7
-rw-r--r--drivers/video/sis/init301.h7
-rw-r--r--drivers/video/sis/initextlfb.c4
-rw-r--r--drivers/video/sis/osdef.h4
-rw-r--r--drivers/video/sis/sis_accel.c26
-rw-r--r--drivers/video/sis/sis_accel.h14
-rw-r--r--drivers/video/sis/sis_main.c232
-rw-r--r--drivers/video/sis/sis_main.h65
-rw-r--r--drivers/video/sis/vgatypes.h2
-rw-r--r--drivers/video/sstfb.c170
-rw-r--r--fs/9p/v9fs.c6
-rw-r--r--fs/9p/vfs_inode.c2
-rw-r--r--fs/Kconfig48
-rw-r--r--fs/Makefile15
-rw-r--r--fs/adfs/file.c6
-rw-r--r--fs/affs/file.c6
-rw-r--r--fs/afs/dir.c4
-rw-r--r--fs/afs/file.c2
-rw-r--r--fs/afs/proc.c2
-rw-r--r--fs/aio.c170
-rw-r--r--fs/autofs/root.c4
-rw-r--r--fs/autofs4/root.c16
-rw-r--r--fs/bad_inode.c2
-rw-r--r--fs/bfs/dir.c11
-rw-r--r--fs/bfs/file.c6
-rw-r--r--fs/binfmt_aout.c14
-rw-r--r--fs/binfmt_elf.c91
-rw-r--r--fs/binfmt_elf_fdpic.c7
-rw-r--r--fs/binfmt_misc.c6
-rw-r--r--fs/bio.c4
-rw-r--r--fs/block_dev.c83
-rw-r--r--fs/buffer.c174
-rw-r--r--fs/char_dev.c88
-rw-r--r--fs/cifs/cifsfs.c22
-rw-r--r--fs/cifs/connect.c22
-rw-r--r--fs/cifs/file.c1
-rw-r--r--fs/cifs/inode.c15
-rw-r--r--fs/cifs/ioctl.c7
-rw-r--r--fs/cifs/sess.c6
-rw-r--r--fs/coda/dir.c6
-rw-r--r--fs/compat.c72
-rw-r--r--fs/compat_ioctl.c406
-rw-r--r--fs/configfs/dir.c4
-rw-r--r--fs/configfs/file.c4
-rw-r--r--fs/configfs/mount.c2
-rw-r--r--fs/cramfs/inode.c11
-rw-r--r--fs/cramfs/uncompress.c3
-rw-r--r--fs/dcache.c4
-rw-r--r--fs/debugfs/inode.c4
-rw-r--r--fs/dnotify.c2
-rw-r--r--fs/dquot.c5
-rw-r--r--fs/eventpoll.c5
-rw-r--r--fs/exec.c30
-rw-r--r--fs/exportfs/expfs.c2
-rw-r--r--fs/ext2/dir.c3
-rw-r--r--fs/ext2/ext2.h1
-rw-r--r--fs/ext2/file.c12
-rw-r--r--fs/ext2/ioctl.c32
-rw-r--r--fs/ext2/namei.c2
-rw-r--r--fs/ext3/dir.c3
-rw-r--r--fs/ext3/file.c10
-rw-r--r--fs/ext3/inode.c5
-rw-r--r--fs/ext3/ioctl.c55
-rw-r--r--fs/ext3/namei.c25
-rw-r--r--fs/fat/dir.c58
-rw-r--r--fs/fat/file.c15
-rw-r--r--fs/fat/inode.c59
-rw-r--r--fs/fcntl.c79
-rw-r--r--fs/file.c78
-rw-r--r--fs/file_table.c1
-rw-r--r--fs/filesystems.c2
-rw-r--r--fs/freevxfs/vxfs_super.c11
-rw-r--r--fs/fs-writeback.c9
-rw-r--r--fs/fuse/control.c2
-rw-r--r--fs/fuse/dev.c39
-rw-r--r--fs/fuse/dir.c6
-rw-r--r--fs/fuse/file.c6
-rw-r--r--fs/fuse/inode.c1
-rw-r--r--fs/generic_acl.c197
-rw-r--r--fs/hfs/dir.c4
-rw-r--r--fs/hfs/inode.c6
-rw-r--r--fs/hfsplus/dir.c8
-rw-r--r--fs/hfsplus/hfsplus_fs.h8
-rw-r--r--fs/hfsplus/inode.c6
-rw-r--r--fs/hfsplus/ioctl.c17
-rw-r--r--fs/hostfs/hostfs_kern.c6
-rw-r--r--fs/hpfs/file.c6
-rw-r--r--fs/hpfs/namei.c14
-rw-r--r--fs/hugetlbfs/inode.c6
-rw-r--r--fs/inode.c36
-rw-r--r--fs/internal.h55
-rw-r--r--fs/ioprio.c19
-rw-r--r--fs/isofs/inode.c48
-rw-r--r--fs/jbd/journal.c21
-rw-r--r--fs/jbd/recovery.c2
-rw-r--r--fs/jffs/inode-v23.c9
-rw-r--r--fs/jffs2/dir.c12
-rw-r--r--fs/jffs2/file.c6
-rw-r--r--fs/jffs2/fs.c6
-rw-r--r--fs/jfs/acl.c8
-rw-r--r--fs/jfs/endian24.h2
-rw-r--r--fs/jfs/file.c14
-rw-r--r--fs/jfs/inode.c10
-rw-r--r--fs/jfs/ioctl.c15
-rw-r--r--fs/jfs/jfs_acl.h8
-rw-r--r--fs/jfs/jfs_btree.h6
-rw-r--r--fs/jfs/jfs_debug.c6
-rw-r--r--fs/jfs/jfs_dinode.h8
-rw-r--r--fs/jfs/jfs_dmap.c192
-rw-r--r--fs/jfs/jfs_dmap.h28
-rw-r--r--fs/jfs/jfs_dtree.c18
-rw-r--r--fs/jfs/jfs_dtree.h10
-rw-r--r--fs/jfs/jfs_extent.c56
-rw-r--r--fs/jfs/jfs_extent.h12
-rw-r--r--fs/jfs/jfs_filsys.h24
-rw-r--r--fs/jfs/jfs_imap.c242
-rw-r--r--fs/jfs/jfs_imap.h18
-rw-r--r--fs/jfs/jfs_incore.h8
-rw-r--r--fs/jfs/jfs_inode.c15
-rw-r--r--fs/jfs/jfs_inode.h6
-rw-r--r--fs/jfs/jfs_lock.h10
-rw-r--r--fs/jfs/jfs_logmgr.c38
-rw-r--r--fs/jfs/jfs_logmgr.h76
-rw-r--r--fs/jfs/jfs_metapage.c12
-rw-r--r--fs/jfs/jfs_metapage.h12
-rw-r--r--fs/jfs/jfs_mount.c34
-rw-r--r--fs/jfs/jfs_superblock.h22
-rw-r--r--fs/jfs/jfs_txnmgr.c24
-rw-r--r--fs/jfs/jfs_txnmgr.h12
-rw-r--r--fs/jfs/jfs_types.h4
-rw-r--r--fs/jfs/jfs_umount.c24
-rw-r--r--fs/jfs/jfs_unicode.c12
-rw-r--r--fs/jfs/jfs_unicode.h10
-rw-r--r--fs/jfs/jfs_uniupr.c8
-rw-r--r--fs/jfs/jfs_xattr.h2
-rw-r--r--fs/jfs/jfs_xtree.c14
-rw-r--r--fs/jfs/jfs_xtree.h8
-rw-r--r--fs/jfs/namei.c89
-rw-r--r--fs/jfs/resize.c6
-rw-r--r--fs/jfs/super.c12
-rw-r--r--fs/jfs/symlink.c6
-rw-r--r--fs/jfs/xattr.c48
-rw-r--r--fs/libfs.c24
-rw-r--r--fs/lockd/clntlock.c2
-rw-r--r--fs/lockd/clntproc.c4
-rw-r--r--fs/lockd/mon.c2
-rw-r--r--fs/lockd/svc.c74
-rw-r--r--fs/lockd/svclock.c2
-rw-r--r--fs/lockd/xdr.c2
-rw-r--r--fs/locks.c14
-rw-r--r--fs/mbcache.c1
-rw-r--r--fs/minix/file.c6
-rw-r--r--fs/minix/namei.c2
-rw-r--r--fs/mpage.c2
-rw-r--r--fs/msdos/namei.c28
-rw-r--r--fs/namei.c209
-rw-r--r--fs/namespace.c37
-rw-r--r--fs/ncpfs/dir.c3
-rw-r--r--fs/ncpfs/file.c3
-rw-r--r--fs/ncpfs/ioctl.c239
-rw-r--r--fs/nfs/callback.c7
-rw-r--r--fs/nfs/client.c3
-rw-r--r--fs/nfs/dir.c8
-rw-r--r--fs/nfs/direct.c26
-rw-r--r--fs/nfs/file.c34
-rw-r--r--fs/nfs/nfsroot.c2
-rw-r--r--fs/nfs/write.c1
-rw-r--r--fs/nfsd/export.c12
-rw-r--r--fs/nfsd/nfs4callback.c2
-rw-r--r--fs/nfsd/nfs4proc.c2
-rw-r--r--fs/nfsd/nfs4recover.c2
-rw-r--r--fs/nfsd/nfsctl.c152
-rw-r--r--fs/nfsd/nfssvc.c318
-rw-r--r--fs/nfsd/vfs.c8
-rw-r--r--fs/nls/nls_base.c2
-rw-r--r--fs/no-block.c22
-rw-r--r--fs/ntfs/aops.c30
-rw-r--r--fs/ntfs/aops.h2
-rw-r--r--fs/ntfs/attrib.c54
-rw-r--r--fs/ntfs/attrib.h8
-rw-r--r--fs/ntfs/bitmap.c8
-rw-r--r--fs/ntfs/bitmap.h4
-rw-r--r--fs/ntfs/collate.h8
-rw-r--r--fs/ntfs/compress.c4
-rw-r--r--fs/ntfs/file.c46
-rw-r--r--fs/ntfs/index.c4
-rw-r--r--fs/ntfs/index.h12
-rw-r--r--fs/ntfs/inode.c10
-rw-r--r--fs/ntfs/layout.h6
-rw-r--r--fs/ntfs/lcnalloc.c20
-rw-r--r--fs/ntfs/lcnalloc.h8
-rw-r--r--fs/ntfs/logfile.c108
-rw-r--r--fs/ntfs/logfile.h6
-rw-r--r--fs/ntfs/mft.c58
-rw-r--r--fs/ntfs/mft.h2
-rw-r--r--fs/ntfs/ntfs.h2
-rw-r--r--fs/ntfs/quota.c12
-rw-r--r--fs/ntfs/quota.h2
-rw-r--r--fs/ntfs/runlist.c54
-rw-r--r--fs/ntfs/super.c178
-rw-r--r--fs/ntfs/types.h5
-rw-r--r--fs/ntfs/unistr.c8
-rw-r--r--fs/ntfs/usnjrnl.c8
-rw-r--r--fs/ntfs/usnjrnl.h2
-rw-r--r--fs/ocfs2/dlm/dlmfs.c6
-rw-r--r--fs/ocfs2/file.c28
-rw-r--r--fs/ocfs2/namei.c51
-rw-r--r--fs/open.c213
-rw-r--r--fs/partitions/Makefile2
-rw-r--r--fs/partitions/ldm.c267
-rw-r--r--fs/partitions/msdos.c31
-rw-r--r--fs/pipe.c214
-rw-r--r--fs/posix_acl.c6
-rw-r--r--fs/proc/array.c88
-rw-r--r--fs/proc/base.c1762
-rw-r--r--fs/proc/kcore.c4
-rw-r--r--fs/proc/proc_misc.c14
-rw-r--r--fs/proc/root.c12
-rw-r--r--fs/qnx4/file.c6
-rw-r--r--fs/qnx4/namei.c8
-rw-r--r--fs/quota.c44
-rw-r--r--fs/ramfs/file-mmu.c6
-rw-r--r--fs/ramfs/file-nommu.c6
-rw-r--r--fs/ramfs/inode.c4
-rw-r--r--fs/read_write.c253
-rw-r--r--fs/read_write.h14
-rw-r--r--fs/readdir.c18
-rw-r--r--fs/reiserfs/Makefile2
-rw-r--r--fs/reiserfs/bitmap.c216
-rw-r--r--fs/reiserfs/dir.c3
-rw-r--r--fs/reiserfs/file.c11
-rw-r--r--fs/reiserfs/inode.c14
-rw-r--r--fs/reiserfs/ioctl.c35
-rw-r--r--fs/reiserfs/journal.c54
-rw-r--r--fs/reiserfs/namei.c16
-rw-r--r--fs/reiserfs/resize.c71
-rw-r--r--fs/reiserfs/super.c161
-rw-r--r--fs/reiserfs/xattr.c6
-rw-r--r--fs/select.c8
-rw-r--r--fs/smbfs/file.c24
-rw-r--r--fs/splice.c2
-rw-r--r--fs/stat.c6
-rw-r--r--fs/super.c37
-rw-r--r--fs/sync.c113
-rw-r--r--fs/sysfs/dir.c4
-rw-r--r--fs/sysfs/file.c4
-rw-r--r--fs/sysfs/mount.c2
-rw-r--r--fs/sysv/file.c6
-rw-r--r--fs/sysv/namei.c2
-rw-r--r--fs/udf/file.c16
-rw-r--r--fs/udf/inode.c2
-rw-r--r--fs/udf/namei.c26
-rw-r--r--fs/udf/super.c4
-rw-r--r--fs/ufs/file.c6
-rw-r--r--fs/ufs/namei.c2
-rw-r--r--fs/utimes.c137
-rw-r--r--fs/vfat/namei.c17
-rw-r--r--fs/xfs/Kconfig1
-rw-r--r--fs/xfs/Makefile-linux-2.61
-rw-r--r--fs/xfs/linux-2.6/kmem.c29
-rw-r--r--fs/xfs/linux-2.6/kmem.h6
-rw-r--r--fs/xfs/linux-2.6/sema.h2
-rw-r--r--fs/xfs/linux-2.6/sv.h2
-rw-r--r--fs/xfs/linux-2.6/xfs_aops.c9
-rw-r--r--fs/xfs/linux-2.6/xfs_buf.c51
-rw-r--r--fs/xfs/linux-2.6/xfs_buf.h7
-rw-r--r--fs/xfs/linux-2.6/xfs_file.c140
-rw-r--r--fs/xfs/linux-2.6/xfs_globals.c2
-rw-r--r--fs/xfs/linux-2.6/xfs_ioctl.c19
-rw-r--r--fs/xfs/linux-2.6/xfs_iops.c25
-rw-r--r--fs/xfs/linux-2.6/xfs_linux.h14
-rw-r--r--fs/xfs/linux-2.6/xfs_lrw.c14
-rw-r--r--fs/xfs/linux-2.6/xfs_super.c2
-rw-r--r--fs/xfs/linux-2.6/xfs_vfs.h2
-rw-r--r--fs/xfs/linux-2.6/xfs_vnode.h2
-rw-r--r--fs/xfs/quota/xfs_dquot_item.c26
-rw-r--r--fs/xfs/quota/xfs_qm.c14
-rw-r--r--fs/xfs/quota/xfs_qm.h6
-rw-r--r--fs/xfs/quota/xfs_quota_priv.h2
-rw-r--r--fs/xfs/support/ktrace.c2
-rw-r--r--fs/xfs/xfs_ag.h2
-rw-r--r--fs/xfs/xfs_alloc.c10
-rw-r--r--fs/xfs/xfs_alloc_btree.c132
-rw-r--r--fs/xfs/xfs_attr.c181
-rw-r--r--fs/xfs/xfs_attr.h8
-rw-r--r--fs/xfs/xfs_attr_leaf.c351
-rw-r--r--fs/xfs/xfs_attr_leaf.h41
-rw-r--r--fs/xfs/xfs_behavior.c20
-rw-r--r--fs/xfs/xfs_behavior.h2
-rw-r--r--fs/xfs/xfs_bmap.c90
-rw-r--r--fs/xfs/xfs_bmap_btree.c113
-rw-r--r--fs/xfs/xfs_bmap_btree.h11
-rw-r--r--fs/xfs/xfs_btree.c8
-rw-r--r--fs/xfs/xfs_btree.h5
-rw-r--r--fs/xfs/xfs_buf_item.c22
-rw-r--r--fs/xfs/xfs_da_btree.c33
-rw-r--r--fs/xfs/xfs_error.h9
-rw-r--r--fs/xfs/xfs_extfree_item.c69
-rw-r--r--fs/xfs/xfs_extfree_item.h50
-rw-r--r--fs/xfs/xfs_fs.h8
-rw-r--r--fs/xfs/xfs_ialloc.c11
-rw-r--r--fs/xfs/xfs_ialloc_btree.c62
-rw-r--r--fs/xfs/xfs_ialloc_btree.h19
-rw-r--r--fs/xfs/xfs_iget.c44
-rw-r--r--fs/xfs/xfs_inode.c30
-rw-r--r--fs/xfs/xfs_inode.h12
-rw-r--r--fs/xfs/xfs_inode_item.c16
-rw-r--r--fs/xfs/xfs_inode_item.h66
-rw-r--r--fs/xfs/xfs_iomap.c89
-rw-r--r--fs/xfs/xfs_itable.c184
-rw-r--r--fs/xfs/xfs_itable.h16
-rw-r--r--fs/xfs/xfs_log.c19
-rw-r--r--fs/xfs/xfs_log.h8
-rw-r--r--fs/xfs/xfs_log_priv.h10
-rw-r--r--fs/xfs/xfs_mount.h5
-rw-r--r--fs/xfs/xfs_quota.h2
-rw-r--r--fs/xfs/xfs_rtalloc.c38
-rw-r--r--fs/xfs/xfs_sb.h22
-rw-r--r--fs/xfs/xfs_trans.h2
-rw-r--r--fs/xfs/xfs_trans_ail.c4
-rw-r--r--fs/xfs/xfs_trans_priv.h12
-rw-r--r--fs/xfs/xfs_vfsops.c2
-rw-r--r--fs/xfs/xfs_vnodeops.c26
-rw-r--r--include/asm-alpha/spinlock.h4
-rw-r--r--include/asm-alpha/unistd.h69
-rw-r--r--include/asm-arm/arch-clps711x/time.h2
-rw-r--r--include/asm-arm/arch-l7200/time.h2
-rw-r--r--include/asm-arm/arch-omap/keypad.h3
-rw-r--r--include/asm-arm/arch-pnx4008/clock.h1
-rw-r--r--include/asm-arm/spinlock.h4
-rw-r--r--include/asm-arm/unistd.h24
-rw-r--r--include/asm-arm26/unistd.h24
-rw-r--r--include/asm-avr32/unistd.h80
-rw-r--r--include/asm-cris/arch-v32/spinlock.h4
-rw-r--r--include/asm-cris/unistd.h61
-rw-r--r--include/asm-frv/pgtable.h2
-rw-r--r--include/asm-frv/timex.h5
-rw-r--r--include/asm-frv/unistd.h25
-rw-r--r--include/asm-generic/bug.h32
-rw-r--r--include/asm-generic/pgtable.h37
-rw-r--r--include/asm-h8300/keyboard.h8
-rw-r--r--include/asm-h8300/unistd.h51
-rw-r--r--include/asm-i386/bugs.h2
-rw-r--r--include/asm-i386/dma-mapping.h12
-rw-r--r--include/asm-i386/elf.h2
-rw-r--r--include/asm-i386/mach-default/do_timer.h2
-rw-r--r--include/asm-i386/mach-summit/mach_apic.h2
-rw-r--r--include/asm-i386/mach-visws/do_timer.h2
-rw-r--r--include/asm-i386/mach-voyager/do_timer.h2
-rw-r--r--include/asm-i386/mca_dma.h3
-rw-r--r--include/asm-i386/nmi.h6
-rw-r--r--include/asm-i386/pgtable-2level.h1
-rw-r--r--include/asm-i386/pgtable-3level.h16
-rw-r--r--include/asm-i386/pgtable.h80
-rw-r--r--include/asm-i386/ptrace.h3
-rw-r--r--include/asm-i386/smp.h4
-rw-r--r--include/asm-i386/spinlock.h4
-rw-r--r--include/asm-i386/topology.h1
-rw-r--r--include/asm-i386/unistd.h39
-rw-r--r--include/asm-ia64/ptrace.h3
-rw-r--r--include/asm-ia64/spinlock.h4
-rw-r--r--include/asm-ia64/topology.h2
-rw-r--r--include/asm-ia64/unistd.h72
-rw-r--r--include/asm-m32r/pgtable-2level.h2
-rw-r--r--include/asm-m32r/spinlock.h4
-rw-r--r--include/asm-m32r/timex.h3
-rw-r--r--include/asm-m32r/unistd.h37
-rw-r--r--include/asm-m68k/unistd.h6
-rw-r--r--include/asm-m68knommu/unistd.h55
-rw-r--r--include/asm-mips/cacheflush.h2
-rw-r--r--include/asm-mips/galileo-boards/ev96100.h55
-rw-r--r--include/asm-mips/galileo-boards/ev96100int.h12
-rw-r--r--include/asm-mips/irqflags.h25
-rw-r--r--include/asm-mips/mach-ev64120/mach-gt64120.h1
-rw-r--r--include/asm-mips/mach-ip27/topology.h1
-rw-r--r--include/asm-mips/serial.h17
-rw-r--r--include/asm-mips/spinlock.h4
-rw-r--r--include/asm-mips/stacktrace.h44
-rw-r--r--include/asm-mips/unistd.h39
-rw-r--r--include/asm-parisc/spinlock.h4
-rw-r--r--include/asm-parisc/unistd.h86
-rw-r--r--include/asm-powerpc/bug.h12
-rw-r--r--include/asm-powerpc/fs_pd.h45
-rw-r--r--include/asm-powerpc/io.h1
-rw-r--r--include/asm-powerpc/kprobes.h22
-rw-r--r--include/asm-powerpc/mpc85xx.h53
-rw-r--r--include/asm-powerpc/ptrace.h2
-rw-r--r--include/asm-powerpc/spinlock.h4
-rw-r--r--include/asm-powerpc/time.h6
-rw-r--r--include/asm-powerpc/topology.h1
-rw-r--r--include/asm-powerpc/unistd.h7
-rw-r--r--include/asm-ppc/cpm2.h63
-rw-r--r--include/asm-ppc/fs_pd.h36
-rw-r--r--include/asm-ppc/rheap.h4
-rw-r--r--include/asm-ppc/spinlock.h4
-rw-r--r--include/asm-s390/irq.h3
-rw-r--r--include/asm-s390/pgtable.h84
-rw-r--r--include/asm-s390/ptrace.h1
-rw-r--r--include/asm-s390/setup.h1
-rw-r--r--include/asm-s390/spinlock.h35
-rw-r--r--include/asm-s390/spinlock_types.h6
-rw-r--r--include/asm-s390/unistd.h51
-rw-r--r--include/asm-sh/.gitignore3
-rw-r--r--include/asm-sh/bugs.h2
-rw-r--r--include/asm-sh/cpu-sh3/rtc.h25
-rw-r--r--include/asm-sh/cpu-sh4/rtc.h25
-rw-r--r--include/asm-sh/ec3104/keyboard.h2
-rw-r--r--include/asm-sh/elf.h1
-rw-r--r--include/asm-sh/hs7751rvoip/io.h39
-rw-r--r--include/asm-sh/mpc1211/keyboard.h4
-rw-r--r--include/asm-sh/rts7751r2d/io.h37
-rw-r--r--include/asm-sh/rts7751r2d/rts7751r2d.h3
-rw-r--r--include/asm-sh/sfp-machine.h2
-rw-r--r--include/asm-sh/spinlock.h13
-rw-r--r--include/asm-sh/string.h15
-rw-r--r--include/asm-sh/unistd.h70
-rw-r--r--include/asm-sh64/keyboard.h4
-rw-r--r--include/asm-sh64/timex.h3
-rw-r--r--include/asm-sh64/unistd.h41
-rw-r--r--include/asm-sparc/spinlock.h4
-rw-r--r--include/asm-sparc/unistd.h47
-rw-r--r--include/asm-sparc64/compat_signal.h30
-rw-r--r--include/asm-sparc64/signal.h42
-rw-r--r--include/asm-sparc64/spinlock.h4
-rw-r--r--include/asm-sparc64/unistd.h42
-rw-r--r--include/asm-um/pgtable.h6
-rw-r--r--include/asm-um/unistd.h28
-rw-r--r--include/asm-v850/unistd.h51
-rw-r--r--include/asm-x86_64/dma-mapping.h7
-rw-r--r--include/asm-x86_64/nmi.h7
-rw-r--r--include/asm-x86_64/ptrace.h2
-rw-r--r--include/asm-x86_64/semaphore.h4
-rw-r--r--include/asm-x86_64/spinlock.h4
-rw-r--r--include/asm-x86_64/topology.h1
-rw-r--r--include/asm-x86_64/uaccess.h7
-rw-r--r--include/asm-x86_64/unistd.h93
-rw-r--r--include/asm-x86_64/vsyscall.h3
-rw-r--r--include/asm-xtensa/timex.h3
-rw-r--r--include/asm-xtensa/unistd.h5
-rw-r--r--include/linux/Kbuild4
-rw-r--r--include/linux/acct.h4
-rw-r--r--include/linux/aio.h12
-rw-r--r--include/linux/aio_abi.h2
-rw-r--r--include/linux/atalk.h40
-rw-r--r--include/linux/atmlec.h119
-rw-r--r--include/linux/audit.h5
-rw-r--r--include/linux/bio.h2
-rw-r--r--include/linux/blkdev.h337
-rw-r--r--include/linux/blktrace_api.h3
-rw-r--r--include/linux/buffer_head.h19
-rw-r--r--include/linux/compat.h2
-rw-r--r--include/linux/compat_ioctl.h22
-rw-r--r--include/linux/compiler.h12
-rw-r--r--include/linux/console.h3
-rw-r--r--include/linux/console_struct.h2
-rw-r--r--include/linux/consolemap.h1
-rw-r--r--include/linux/cpuset.h4
-rw-r--r--include/linux/cramfs_fs.h2
-rw-r--r--include/linux/device-mapper.h14
-rw-r--r--include/linux/dm-ioctl.h4
-rw-r--r--include/linux/dma-mapping.h7
-rw-r--r--include/linux/dmi.h3
-rw-r--r--include/linux/elevator.h68
-rw-r--r--include/linux/errqueue.h2
-rw-r--r--include/linux/ext2_fs.h64
-rw-r--r--include/linux/ext3_fs.h26
-rw-r--r--include/linux/fb.h3
-rw-r--r--include/linux/file.h1
-rw-r--r--include/linux/fs.h136
-rw-r--r--include/linux/fs_enet_pd.h47
-rw-r--r--include/linux/fs_uart_pd.h14
-rw-r--r--include/linux/genalloc.h1
-rw-r--r--include/linux/generic_acl.h36
-rw-r--r--include/linux/genhd.h4
-rw-r--r--include/linux/getcpu.h12
-rw-r--r--include/linux/hrtimer.h1
-rw-r--r--include/linux/i2c-id.h1
-rw-r--r--include/linux/icmp.h12
-rw-r--r--include/linux/ide.h12
-rw-r--r--include/linux/if.h130
-rw-r--r--include/linux/if_arp.h6
-rw-r--r--include/linux/if_link.h136
-rw-r--r--include/linux/igmp.h38
-rw-r--r--include/linux/in.h12
-rw-r--r--include/linux/in6.h6
-rw-r--r--include/linux/inet_diag.h10
-rw-r--r--include/linux/inetdevice.h24
-rw-r--r--include/linux/init_task.h12
-rw-r--r--include/linux/input.h272
-rw-r--r--include/linux/interrupt.h16
-rw-r--r--include/linux/io.h4
-rw-r--r--include/linux/ip.h14
-rw-r--r--include/linux/ipc.h54
-rw-r--r--include/linux/ipmi.h48
-rw-r--r--include/linux/ipv6.h16
-rw-r--r--include/linux/jbd.h1
-rw-r--r--include/linux/kallsyms.h11
-rw-r--r--include/linux/kernel.h6
-rw-r--r--include/linux/kmod.h4
-rw-r--r--include/linux/kprobes.h8
-rw-r--r--include/linux/latency.h25
-rw-r--r--include/linux/leds.h3
-rw-r--r--include/linux/libps2.h1
-rw-r--r--include/linux/list.h15
-rw-r--r--include/linux/lockd/bind.h2
-rw-r--r--include/linux/lockd/lockd.h2
-rw-r--r--include/linux/lockdep.h4
-rw-r--r--include/linux/loop.h5
-rw-r--r--include/linux/memory.h4
-rw-r--r--include/linux/memory_hotplug.h2
-rw-r--r--include/linux/mm.h6
-rw-r--r--include/linux/module.h6
-rw-r--r--include/linux/mpage.h7
-rw-r--r--include/linux/mroute.h14
-rw-r--r--include/linux/msdos_fs.h3
-rw-r--r--include/linux/mtd/nand.h25
-rw-r--r--include/linux/mtd/onenand.h6
-rw-r--r--include/linux/mtd/onenand_regs.h4
-rw-r--r--include/linux/namei.h2
-rw-r--r--include/linux/namespace.h6
-rw-r--r--include/linux/ncp_fs.h1
-rw-r--r--include/linux/netdevice.h2
-rw-r--r--include/linux/netfilter_arp/arp_tables.h6
-rw-r--r--include/linux/netfilter_ipv4/ip_conntrack.h2
-rw-r--r--include/linux/netfilter_ipv4/ip_conntrack_h323.h6
-rw-r--r--include/linux/netfilter_ipv4/ip_conntrack_tuple.h16
-rw-r--r--include/linux/netfilter_ipv4/ip_nat.h2
-rw-r--r--include/linux/netfilter_ipv4/ip_queue.h2
-rw-r--r--include/linux/netfilter_ipv4/ipt_iprange.h2
-rw-r--r--include/linux/nfs_fs.h10
-rw-r--r--include/linux/nfsd/nfsd.h5
-rw-r--r--include/linux/nfsd/nfsfh.h11
-rw-r--r--include/linux/nfsd/syscall.h17
-rw-r--r--include/linux/nmi.h3
-rw-r--r--include/linux/nodemask.h2
-rw-r--r--include/linux/nsproxy.h52
-rw-r--r--include/linux/page-flags.h11
-rw-r--r--include/linux/pci.h5
-rw-r--r--include/linux/pci_ids.h5
-rw-r--r--include/linux/percpu.h2
-rw-r--r--include/linux/pid.h49
-rw-r--r--include/linux/posix-timers.h4
-rw-r--r--include/linux/proc_fs.h10
-rw-r--r--include/linux/pspace.h23
-rw-r--r--include/linux/ptrace.h4
-rw-r--r--include/linux/raid/bitmap.h2
-rw-r--r--include/linux/raid/md.h4
-rw-r--r--include/linux/raid/md_k.h14
-rw-r--r--include/linux/raid/md_u.h2
-rw-r--r--include/linux/raid/raid1.h1
-rw-r--r--include/linux/raid/raid10.h1
-rw-r--r--include/linux/raid/raid5.h7
-rw-r--r--include/linux/ramfs.h1
-rw-r--r--include/linux/rbtree.h2
-rw-r--r--include/linux/reiserfs_acl.h17
-rw-r--r--include/linux/reiserfs_fs.h41
-rw-r--r--include/linux/reiserfs_fs_i.h5
-rw-r--r--include/linux/reiserfs_fs_sb.h2
-rw-r--r--include/linux/reiserfs_xattr.h8
-rw-r--r--include/linux/rtc.h4
-rw-r--r--include/linux/rtnetlink.h2
-rw-r--r--include/linux/sched.h96
-rw-r--r--include/linux/scx200_gpio.h1
-rw-r--r--include/linux/security.h1
-rw-r--r--include/linux/serial_core.h3
-rw-r--r--include/linux/serio.h3
-rw-r--r--include/linux/shmem_fs.h24
-rw-r--r--include/linux/spinlock.h14
-rw-r--r--include/linux/spinlock_api_smp.h50
-rw-r--r--include/linux/stat.h2
-rw-r--r--include/linux/stddef.h6
-rw-r--r--include/linux/string.h1
-rw-r--r--include/linux/sunrpc/auth.h16
-rw-r--r--include/linux/sunrpc/msg_prot.h2
-rw-r--r--include/linux/sunrpc/svc.h114
-rw-r--r--include/linux/sunrpc/svcauth.h4
-rw-r--r--include/linux/sunrpc/svcsock.h15
-rw-r--r--include/linux/sunrpc/xdr.h38
-rw-r--r--include/linux/sunrpc/xprt.h12
-rw-r--r--include/linux/synclink.h4
-rw-r--r--include/linux/syscalls.h4
-rw-r--r--include/linux/sysrq.h4
-rw-r--r--include/linux/taskstats.h64
-rw-r--r--include/linux/tcp.h23
-rw-r--r--include/linux/timex.h58
-rw-r--r--include/linux/topology.h46
-rw-r--r--include/linux/trdevice.h2
-rw-r--r--include/linux/tsacct_kern.h34
-rw-r--r--include/linux/tty.h6
-rw-r--r--include/linux/tty_driver.h3
-rw-r--r--include/linux/types.h2
-rw-r--r--include/linux/udp.h8
-rw-r--r--include/linux/uinput.h35
-rw-r--r--include/linux/unistd.h6
-rw-r--r--include/linux/unwind.h2
-rw-r--r--include/linux/utime.h2
-rw-r--r--include/linux/utsname.h55
-rw-r--r--include/linux/videodev2.h5
-rw-r--r--include/linux/vmstat.h1
-rw-r--r--include/linux/vt_kern.h10
-rw-r--r--include/linux/writeback.h3
-rw-r--r--include/linux/xfrm.h16
-rw-r--r--include/media/ir-common.h2
-rw-r--r--include/media/tuner-types.h3
-rw-r--r--include/media/tuner.h1
-rw-r--r--include/media/v4l2-common.h16
-rw-r--r--include/media/v4l2-dev.h10
-rw-r--r--include/mtd/Kbuild3
-rw-r--r--include/mtd/mtd-abi.h6
-rw-r--r--include/net/arp.h8
-rw-r--r--include/net/bluetooth/hci.h11
-rw-r--r--include/net/bluetooth/hci_core.h18
-rw-r--r--include/net/cipso_ipv4.h5
-rw-r--r--include/net/dst.h2
-rw-r--r--include/net/flow.h10
-rw-r--r--include/net/genetlink.h18
-rw-r--r--include/net/icmp.h2
-rw-r--r--include/net/inet_connection_sock.h6
-rw-r--r--include/net/inet_hashtables.h56
-rw-r--r--include/net/inet_sock.h34
-rw-r--r--include/net/inet_timewait_sock.h10
-rw-r--r--include/net/inetpeer.h4
-rw-r--r--include/net/ip.h10
-rw-r--r--include/net/ip_fib.h28
-rw-r--r--include/net/ip_mp_alg.h4
-rw-r--r--include/net/ip_vs.h68
-rw-r--r--include/net/ipv6.h6
-rw-r--r--include/net/irda/irlan_common.h10
-rw-r--r--include/net/irda/irlap_frame.h31
-rw-r--r--include/net/irda/irlmp.h2
-rw-r--r--include/net/netlabel.h8
-rw-r--r--include/net/netlink.h12
-rw-r--r--include/net/route.h24
-rw-r--r--include/net/sock.h1
-rw-r--r--include/net/xfrm.h26
-rw-r--r--include/scsi/scsi_device.h4
-rw-r--r--include/scsi/scsi_tcq.h5
-rw-r--r--include/sound/pcm.h1
-rw-r--r--include/video/sstfb.h4
-rw-r--r--init/Kconfig44
-rw-r--r--init/do_mounts.c13
-rw-r--r--init/do_mounts_initrd.c3
-rw-r--r--init/do_mounts_md.c8
-rw-r--r--init/main.c6
-rw-r--r--init/version.c23
-rw-r--r--ipc/mqueue.c31
-rw-r--r--ipc/msg.c157
-rw-r--r--ipc/sem.c206
-rw-r--r--ipc/shm.c254
-rw-r--r--ipc/util.c132
-rw-r--r--ipc/util.h24
-rw-r--r--kernel/Makefile5
-rw-r--r--kernel/acct.c36
-rw-r--r--kernel/auditsc.c5
-rw-r--r--kernel/capability.c2
-rw-r--r--kernel/compat.c33
-rw-r--r--kernel/cpuset.c114
-rw-r--r--kernel/dma.c10
-rw-r--r--kernel/exit.c52
-rw-r--r--kernel/fork.c93
-rw-r--r--kernel/futex.c12
-rw-r--r--kernel/hrtimer.c20
-rw-r--r--kernel/irq/chip.c6
-rw-r--r--kernel/kallsyms.c124
-rw-r--r--kernel/kexec.c8
-rw-r--r--kernel/kfifo.c28
-rw-r--r--kernel/kmod.c74
-rw-r--r--kernel/kprobes.c53
-rw-r--r--kernel/latency.c279
-rw-r--r--kernel/lockdep.c17
-rw-r--r--kernel/module.c66
-rw-r--r--kernel/nsproxy.c139
-rw-r--r--kernel/panic.c1
-rw-r--r--kernel/params.c15
-rw-r--r--kernel/pid.c111
-rw-r--r--kernel/posix-cpu-timers.c101
-rw-r--r--kernel/posix-timers.c21
-rw-r--r--kernel/power/snapshot.c10
-rw-r--r--kernel/ptrace.c1
-rw-r--r--kernel/rcutorture.c8
-rw-r--r--kernel/relay.c36
-rw-r--r--kernel/resource.c83
-rw-r--r--kernel/rtmutex.c51
-rw-r--r--kernel/sched.c400
-rw-r--r--kernel/signal.c71
-rw-r--r--kernel/softirq.c4
-rw-r--r--kernel/softlockup.c3
-rw-r--r--kernel/spinlock.c15
-rw-r--r--kernel/stop_machine.c3
-rw-r--r--kernel/sys.c111
-rw-r--r--kernel/sys_ni.c5
-rw-r--r--kernel/sysctl.c365
-rw-r--r--kernel/taskstats.c10
-rw-r--r--kernel/time.c173
-rw-r--r--kernel/time/Makefile2
-rw-r--r--kernel/time/ntp.c350
-rw-r--r--kernel/timer.c283
-rw-r--r--kernel/tsacct.c124
-rw-r--r--kernel/unwind.c4
-rw-r--r--kernel/utsname.c95
-rw-r--r--lib/Kconfig.debug23
-rw-r--r--lib/Makefile4
-rw-r--r--lib/cpumask.c16
-rw-r--r--lib/errno.c7
-rw-r--r--lib/genalloc.c63
-rw-r--r--lib/ioremap.c92
-rw-r--r--lib/list_debug.c76
-rw-r--r--lib/rbtree.c6
-rw-r--r--lib/rwsem.c2
-rw-r--r--lib/sort.c10
-rw-r--r--lib/spinlock_debug.c15
-rw-r--r--lib/ts_fsm.c10
-rw-r--r--mm/Kconfig7
-rw-r--r--mm/Makefile4
-rw-r--r--mm/bounce.c302
-rw-r--r--mm/filemap.c186
-rw-r--r--mm/fremap.c2
-rw-r--r--mm/highmem.c281
-rw-r--r--mm/memory.c21
-rw-r--r--mm/memory_hotplug.c71
-rw-r--r--mm/mempolicy.c3
-rw-r--r--mm/migrate.c4
-rw-r--r--mm/mprotect.c2
-rw-r--r--mm/mremap.c2
-rw-r--r--mm/nommu.c3
-rw-r--r--mm/oom_kill.c53
-rw-r--r--mm/page-writeback.c160
-rw-r--r--mm/shmem.c117
-rw-r--r--mm/shmem_acl.c197
-rw-r--r--mm/slab.c24
-rw-r--r--mm/swapfile.c7
-rw-r--r--mm/truncate.c60
-rw-r--r--mm/util.c18
-rw-r--r--net/802/tr.c12
-rw-r--r--net/Kconfig2
-rw-r--r--net/appletalk/ddp.c79
-rw-r--r--net/atm/lec.c3161
-rw-r--r--net/atm/lec.h172
-rw-r--r--net/atm/lec_arpc.h146
-rw-r--r--net/atm/mpc.c13
-rw-r--r--net/atm/mpoa_caches.c12
-rw-r--r--net/bluetooth/af_bluetooth.c2
-rw-r--r--net/bluetooth/bnep/core.c26
-rw-r--r--net/bluetooth/hci_conn.c39
-rw-r--r--net/bluetooth/hci_core.c3
-rw-r--r--net/bluetooth/hci_event.c26
-rw-r--r--net/bluetooth/hci_sysfs.c135
-rw-r--r--net/bluetooth/hidp/core.c23
-rw-r--r--net/bluetooth/rfcomm/core.c2
-rw-r--r--net/bluetooth/rfcomm/tty.c23
-rw-r--r--net/bridge/netfilter/ebt_arpreply.c2
-rw-r--r--net/core/dev.c14
-rw-r--r--net/core/ethtool.c32
-rw-r--r--net/core/neighbour.c2
-rw-r--r--net/core/pktgen.c321
-rw-r--r--net/core/rtnetlink.c2
-rw-r--r--net/core/utils.c2
-rw-r--r--net/dccp/ipv4.c2
-rw-r--r--net/ethernet/eth.c2
-rw-r--r--net/ipv4/af_inet.c8
-rw-r--r--net/ipv4/arp.c40
-rw-r--r--net/ipv4/cipso_ipv4.c8
-rw-r--r--net/ipv4/datagram.c2
-rw-r--r--net/ipv4/devinet.c42
-rw-r--r--net/ipv4/fib_frontend.c37
-rw-r--r--net/ipv4/fib_hash.c22
-rw-r--r--net/ipv4/fib_lookup.h6
-rw-r--r--net/ipv4/fib_rules.c24
-rw-r--r--net/ipv4/fib_semantics.c33
-rw-r--r--net/ipv4/fib_trie.c12
-rw-r--r--net/ipv4/icmp.c10
-rw-r--r--net/ipv4/igmp.c68
-rw-r--r--net/ipv4/inet_connection_sock.c12
-rw-r--r--net/ipv4/inet_diag.c12
-rw-r--r--net/ipv4/inet_hashtables.c12
-rw-r--r--net/ipv4/inetpeer.c4
-rw-r--r--net/ipv4/ip_fragment.c15
-rw-r--r--net/ipv4/ip_options.c26
-rw-r--r--net/ipv4/ip_output.c6
-rw-r--r--net/ipv4/ip_sockglue.c4
-rw-r--r--net/ipv4/ipcomp.c2
-rw-r--r--net/ipv4/ipconfig.c16
-rw-r--r--net/ipv4/ipmr.c4
-rw-r--r--net/ipv4/ipvs/ip_vs_conn.c24
-rw-r--r--net/ipv4/ipvs/ip_vs_core.c14
-rw-r--r--net/ipv4/ipvs/ip_vs_ctl.c26
-rw-r--r--net/ipv4/ipvs/ip_vs_dh.c4
-rw-r--r--net/ipv4/ipvs/ip_vs_ftp.c27
-rw-r--r--net/ipv4/ipvs/ip_vs_lblc.c8
-rw-r--r--net/ipv4/ipvs/ip_vs_lblcr.c8
-rw-r--r--net/ipv4/ipvs/ip_vs_proto.c2
-rw-r--r--net/ipv4/ipvs/ip_vs_proto_tcp.c10
-rw-r--r--net/ipv4/ipvs/ip_vs_proto_udp.c14
-rw-r--r--net/ipv4/ipvs/ip_vs_sh.c4
-rw-r--r--net/ipv4/ipvs/ip_vs_sync.c20
-rw-r--r--net/ipv4/ipvs/ip_vs_xmit.c2
-rw-r--r--net/ipv4/multipath_wrandom.c14
-rw-r--r--net/ipv4/netfilter.c4
-rw-r--r--net/ipv4/netfilter/arp_tables.c2
-rw-r--r--net/ipv4/netfilter/ip_conntrack_amanda.c6
-rw-r--r--net/ipv4/netfilter/ip_conntrack_core.c12
-rw-r--r--net/ipv4/netfilter/ip_conntrack_ftp.c6
-rw-r--r--net/ipv4/netfilter/ip_conntrack_helper_h323.c84
-rw-r--r--net/ipv4/netfilter/ip_conntrack_helper_pptp.c4
-rw-r--r--net/ipv4/netfilter/ip_conntrack_irc.c5
-rw-r--r--net/ipv4/netfilter/ip_conntrack_netbios_ns.c12
-rw-r--r--net/ipv4/netfilter/ip_conntrack_netlink.c82
-rw-r--r--net/ipv4/netfilter/ip_conntrack_proto_icmp.c4
-rw-r--r--net/ipv4/netfilter/ip_conntrack_proto_sctp.c2
-rw-r--r--net/ipv4/netfilter/ip_conntrack_proto_tcp.c6
-rw-r--r--net/ipv4/netfilter/ip_conntrack_sip.c16
-rw-r--r--net/ipv4/netfilter/ip_conntrack_tftp.c8
-rw-r--r--net/ipv4/netfilter/ip_nat_core.c14
-rw-r--r--net/ipv4/netfilter/ip_nat_ftp.c10
-rw-r--r--net/ipv4/netfilter/ip_nat_helper.c39
-rw-r--r--net/ipv4/netfilter/ip_nat_helper_h323.c16
-rw-r--r--net/ipv4/netfilter/ip_nat_helper_pptp.c2
-rw-r--r--net/ipv4/netfilter/ip_nat_proto_icmp.c2
-rw-r--r--net/ipv4/netfilter/ip_nat_proto_tcp.c10
-rw-r--r--net/ipv4/netfilter/ip_nat_proto_udp.c10
-rw-r--r--net/ipv4/netfilter/ip_nat_rule.c6
-rw-r--r--net/ipv4/netfilter/ip_nat_sip.c8
-rw-r--r--net/ipv4/netfilter/ip_nat_snmp_basic.c2
-rw-r--r--net/ipv4/netfilter/ip_nat_standalone.c2
-rw-r--r--net/ipv4/netfilter/ipt_CLUSTERIP.c14
-rw-r--r--net/ipv4/netfilter/ipt_ECN.c12
-rw-r--r--net/ipv4/netfilter/ipt_MASQUERADE.c2
-rw-r--r--net/ipv4/netfilter/ipt_NETMAP.c2
-rw-r--r--net/ipv4/netfilter/ipt_REDIRECT.c2
-rw-r--r--net/ipv4/netfilter/ipt_REJECT.c4
-rw-r--r--net/ipv4/netfilter/ipt_SAME.c3
-rw-r--r--net/ipv4/netfilter/ipt_TCPMSS.c17
-rw-r--r--net/ipv4/netfilter/ipt_TOS.c4
-rw-r--r--net/ipv4/netfilter/ipt_TTL.c4
-rw-r--r--net/ipv4/netfilter/ipt_addrtype.c2
-rw-r--r--net/ipv4/netfilter/ipt_hashlimit.c16
-rw-r--r--net/ipv4/netfilter/ipt_recent.c15
-rw-r--r--net/ipv4/netfilter/iptable_mangle.c2
-rw-r--r--net/ipv4/raw.c4
-rw-r--r--net/ipv4/route.c99
-rw-r--r--net/ipv4/tcp_input.c32
-rw-r--r--net/ipv4/tcp_ipv4.c8
-rw-r--r--net/ipv4/tcp_lp.c4
-rw-r--r--net/ipv4/tcp_output.c12
-rw-r--r--net/ipv4/tcp_probe.c6
-rw-r--r--net/ipv4/udp.c32
-rw-r--r--net/ipv4/xfrm4_input.c4
-rw-r--r--net/ipv4/xfrm4_policy.c6
-rw-r--r--net/ipv4/xfrm4_state.c4
-rw-r--r--net/ipv6/addrconf.c4
-rw-r--r--net/ipv6/af_inet6.c2
-rw-r--r--net/ipv6/inet6_hashtables.c8
-rw-r--r--net/ipv6/ipcomp6.c4
-rw-r--r--net/ipv6/ipv6_sockglue.c3
-rw-r--r--net/ipv6/tcp_ipv6.c2
-rw-r--r--net/ipv6/xfrm6_input.c4
-rw-r--r--net/ipv6/xfrm6_state.c4
-rw-r--r--net/ipv6/xfrm6_tunnel.c2
-rw-r--r--net/irda/af_irda.c12
-rw-r--r--net/irda/ircomm/ircomm_lmp.c4
-rw-r--r--net/irda/ircomm/ircomm_tty.c2
-rw-r--r--net/irda/iriap.c9
-rw-r--r--net/irda/iriap_event.c2
-rw-r--r--net/irda/irlan/irlan_common.c46
-rw-r--r--net/irda/irlan/irlan_provider.c12
-rw-r--r--net/irda/irlap_frame.c59
-rw-r--r--net/irda/irlmp.c2
-rw-r--r--net/irda/irttp.c14
-rw-r--r--net/key/af_key.c8
-rw-r--r--net/netlabel/netlabel_cipso_v4.c59
-rw-r--r--net/netlabel/netlabel_domainhash.c56
-rw-r--r--net/netlabel/netlabel_domainhash.h8
-rw-r--r--net/netlabel/netlabel_mgmt.c25
-rw-r--r--net/netlabel/netlabel_unlabeled.c48
-rw-r--r--net/netlabel/netlabel_user.c41
-rw-r--r--net/netlabel/netlabel_user.h18
-rw-r--r--net/rxrpc/transport.c3
-rw-r--r--net/sched/cls_api.c4
-rw-r--r--net/sched/cls_basic.c2
-rw-r--r--net/sched/sch_api.c16
-rw-r--r--net/sched/sch_generic.c66
-rw-r--r--net/sched/sch_htb.c2
-rw-r--r--net/sctp/input.c8
-rw-r--r--net/sctp/output.c10
-rw-r--r--net/sctp/outqueue.c3
-rw-r--r--net/sctp/sm_make_chunk.c10
-rw-r--r--net/sctp/socket.c4
-rw-r--r--net/socket.c87
-rw-r--r--net/sunrpc/auth.c12
-rw-r--r--net/sunrpc/auth_gss/auth_gss.c33
-rw-r--r--net/sunrpc/auth_gss/gss_krb5_seal.c2
-rw-r--r--net/sunrpc/auth_gss/gss_krb5_wrap.c4
-rw-r--r--net/sunrpc/auth_gss/svcauth_gss.c82
-rw-r--r--net/sunrpc/auth_null.c8
-rw-r--r--net/sunrpc/auth_unix.c10
-rw-r--r--net/sunrpc/clnt.c27
-rw-r--r--net/sunrpc/pmap_clnt.c6
-rw-r--r--net/sunrpc/rpc_pipe.c6
-rw-r--r--net/sunrpc/sunrpc_syms.c2
-rw-r--r--net/sunrpc/svc.c509
-rw-r--r--net/sunrpc/svcauth.c4
-rw-r--r--net/sunrpc/svcauth_unix.c43
-rw-r--r--net/sunrpc/svcsock.c391
-rw-r--r--net/sunrpc/xdr.c54
-rw-r--r--net/sunrpc/xprt.c4
-rw-r--r--net/sunrpc/xprtsock.c3
-rw-r--r--net/xfrm/xfrm_hash.h4
-rw-r--r--net/xfrm/xfrm_input.c8
-rw-r--r--net/xfrm/xfrm_state.c37
-rw-r--r--scripts/.gitignore1
-rw-r--r--scripts/Makefile2
-rw-r--r--scripts/Makefile.modpost11
-rw-r--r--scripts/basic/docproc.c1
-rw-r--r--scripts/kconfig/Makefile31
-rw-r--r--scripts/kconfig/confdata.c2
-rw-r--r--scripts/kconfig/lxdialog/Makefile21
-rw-r--r--scripts/kconfig/lxdialog/checklist.c183
-rw-r--r--scripts/kconfig/lxdialog/colors.h154
-rw-r--r--scripts/kconfig/lxdialog/dialog.h144
-rw-r--r--scripts/kconfig/lxdialog/inputbox.c48
-rw-r--r--scripts/kconfig/lxdialog/lxdialog.c204
-rw-r--r--scripts/kconfig/lxdialog/menubox.c166
-rw-r--r--scripts/kconfig/lxdialog/msgbox.c71
-rw-r--r--scripts/kconfig/lxdialog/textbox.c416
-rw-r--r--scripts/kconfig/lxdialog/util.c502
-rw-r--r--scripts/kconfig/lxdialog/yesno.c26
-rw-r--r--scripts/kconfig/mconf.c511
-rw-r--r--security/Kconfig12
-rw-r--r--security/Makefile1
-rw-r--r--security/commoncap.c2
-rw-r--r--security/inode.c4
-rw-r--r--security/seclvl.c671
-rw-r--r--security/selinux/hooks.c39
-rw-r--r--security/selinux/selinuxfs.c4
-rw-r--r--sound/Makefile3
-rw-r--r--sound/core/info_oss.c10
-rw-r--r--sound/core/pcm.c3
-rw-r--r--sound/core/pcm_native.c63
-rw-r--r--sound/mips/au1x00.c2
-rw-r--r--sound/oss/COPYING339
-rw-r--r--sound/oss/cs46xx.c15
-rw-r--r--sound/oss/cs46xxpm-24.h48
-rw-r--r--sound/oss/swarm_cs4297a.c2
-rw-r--r--sound/oss/trident.c70
-rw-r--r--sound/oss/via82cxxx_audio.c6
-rw-r--r--sound/pci/echoaudio/layla24_dsp.c4
-rw-r--r--sound/sound_core.c4
-rw-r--r--sound/sound_firmware.c6
-rw-r--r--sound/sparc/dbri.c4
-rw-r--r--sound/usb/usbaudio.c11
-rw-r--r--sound/usb/usbmidi.c3
2191 files changed, 59798 insertions, 41349 deletions
diff --git a/CREDITS b/CREDITS
index cc3453a55fb9..6c06ded9882b 100644
--- a/CREDITS
+++ b/CREDITS
@@ -951,6 +951,12 @@ S: Brevia 1043
S: S-114 79 Stockholm
S: Sweden
+N: Pekka Enberg
+E: penberg@cs.helsinki.fi
+W: http://www.cs.helsinki.fi/u/penberg/
+D: Various kernel hacks, fixes, and cleanups.
+S: Finland
+
N: David Engebretsen
E: engebret@us.ibm.com
D: Linux port to 64-bit PowerPC architecture
@@ -1620,7 +1626,8 @@ D: fbdev hacking
N: Jesper Juhl
E: jesper.juhl@gmail.com
-D: Various fixes, cleanups and minor features.
+D: Various fixes, cleanups and minor features all over the tree.
+D: Wrote initial version of the hdaps driver (since passed on to others).
S: Lemnosvej 1, 3.tv
S: 2300 Copenhagen S.
S: Denmark
@@ -2477,7 +2484,8 @@ S: Derbyshire DE4 3RL
S: United Kingdom
N: Ian S. Nelson
-E: ian.nelson@echostar.com
+E: nelsonis@earthlink.net
+P: 1024D/00D3D983 3EFD 7B86 B888 D7E2 29B6 9E97 576F 1B97 00D3 D983
D: Minor mmap and ide hacks
S: 1370 Atlantis Ave.
S: Lafayette CO, 80026
diff --git a/Documentation/CodingStyle b/Documentation/CodingStyle
index 6d2412ec91ed..29c18966b050 100644
--- a/Documentation/CodingStyle
+++ b/Documentation/CodingStyle
@@ -532,6 +532,40 @@ appears outweighs the potential value of the hint that tells gcc to do
something it would have done anyway.
+ Chapter 16: Function return values and names
+
+Functions can return values of many different kinds, and one of the
+most common is a value indicating whether the function succeeded or
+failed. Such a value can be represented as an error-code integer
+(-Exxx = failure, 0 = success) or a "succeeded" boolean (0 = failure,
+non-zero = success).
+
+Mixing up these two sorts of representations is a fertile source of
+difficult-to-find bugs. If the C language included a strong distinction
+between integers and booleans then the compiler would find these mistakes
+for us... but it doesn't. To help prevent such bugs, always follow this
+convention:
+
+ If the name of a function is an action or an imperative command,
+ the function should return an error-code integer. If the name
+ is a predicate, the function should return a "succeeded" boolean.
+
+For example, "add work" is a command, and the add_work() function returns 0
+for success or -EBUSY for failure. In the same way, "PCI device present" is
+a predicate, and the pci_dev_present() function returns 1 if it succeeds in
+finding a matching device or 0 if it doesn't.
+
+All EXPORTed functions must respect this convention, and so should all
+public functions. Private (static) functions need not, but it is
+recommended that they do.
+
+Functions whose return value is the actual result of a computation, rather
+than an indication of whether the computation succeeded, are not subject to
+this rule. Generally they indicate failure by returning some out-of-range
+result. Typical examples would be functions that return pointers; they use
+NULL or the ERR_PTR mechanism to report failure.
+
+
Appendix I: References
diff --git a/Documentation/DocBook/kernel-api.tmpl b/Documentation/DocBook/kernel-api.tmpl
index f8fe882e33dc..49c745720f47 100644
--- a/Documentation/DocBook/kernel-api.tmpl
+++ b/Documentation/DocBook/kernel-api.tmpl
@@ -181,27 +181,6 @@ X!Ilib/string.c
</sect1>
</chapter>
- <chapter id="proc">
- <title>The proc filesystem</title>
-
- <sect1><title>sysctl interface</title>
-!Ekernel/sysctl.c
- </sect1>
-
- <sect1><title>proc filesystem interface</title>
-!Ifs/proc/base.c
- </sect1>
- </chapter>
-
- <chapter id="debugfs">
- <title>The debugfs filesystem</title>
-
- <sect1><title>debugfs interface</title>
-!Efs/debugfs/inode.c
-!Efs/debugfs/file.c
- </sect1>
- </chapter>
-
<chapter id="vfs">
<title>The Linux VFS</title>
<sect1><title>The Filesystem types</title>
@@ -234,6 +213,50 @@ X!Ilib/string.c
</sect1>
</chapter>
+ <chapter id="proc">
+ <title>The proc filesystem</title>
+
+ <sect1><title>sysctl interface</title>
+!Ekernel/sysctl.c
+ </sect1>
+
+ <sect1><title>proc filesystem interface</title>
+!Ifs/proc/base.c
+ </sect1>
+ </chapter>
+
+ <chapter id="sysfs">
+ <title>The Filesystem for Exporting Kernel Objects</title>
+!Efs/sysfs/file.c
+!Efs/sysfs/symlink.c
+!Efs/sysfs/bin.c
+ </chapter>
+
+ <chapter id="debugfs">
+ <title>The debugfs filesystem</title>
+
+ <sect1><title>debugfs interface</title>
+!Efs/debugfs/inode.c
+!Efs/debugfs/file.c
+ </sect1>
+ </chapter>
+
+ <chapter id="relayfs">
+ <title>relay interface support</title>
+
+ <para>
+ Relay interface support
+ is designed to provide an efficient mechanism for tools and
+ facilities to relay large amounts of data from kernel space to
+ user space.
+ </para>
+
+ <sect1><title>relay interface</title>
+!Ekernel/relay.c
+!Ikernel/relay.c
+ </sect1>
+ </chapter>
+
<chapter id="netcore">
<title>Linux Networking</title>
<sect1><title>Networking Base Types</title>
@@ -302,8 +325,13 @@ X!Ekernel/module.c
!Ekernel/irq/manage.c
</sect1>
+ <sect1><title>DMA Channels</title>
+!Ekernel/dma.c
+ </sect1>
+
<sect1><title>Resources Management</title>
!Ikernel/resource.c
+!Ekernel/resource.c
</sect1>
<sect1><title>MTRR Handling</title>
@@ -349,13 +377,6 @@ X!Earch/i386/kernel/mca.c
</sect1>
</chapter>
- <chapter id="sysfs">
- <title>The Filesystem for Exporting Kernel Objects</title>
-!Efs/sysfs/file.c
-!Efs/sysfs/symlink.c
-!Efs/sysfs/bin.c
- </chapter>
-
<chapter id="security">
<title>Security Framework</title>
!Esecurity/security.c
@@ -386,6 +407,7 @@ X!Iinclude/linux/device.h
-->
!Edrivers/base/driver.c
!Edrivers/base/core.c
+!Edrivers/base/class.c
!Edrivers/base/firmware_class.c
!Edrivers/base/transport_class.c
!Edrivers/base/dmapool.c
@@ -437,6 +459,11 @@ X!Edrivers/pnp/system.c
!Eblock/ll_rw_blk.c
</chapter>
+ <chapter id="chrdev">
+ <title>Char devices</title>
+!Efs/char_dev.c
+ </chapter>
+
<chapter id="miscdev">
<title>Miscellaneous Devices</title>
!Edrivers/char/misc.c
diff --git a/Documentation/HOWTO b/Documentation/HOWTO
index 1d6560413cc5..d6f3dd1a3464 100644
--- a/Documentation/HOWTO
+++ b/Documentation/HOWTO
@@ -375,6 +375,26 @@ of information is needed by the kernel developers to help track down the
problem.
+Managing bug reports
+--------------------
+
+One of the best ways to put into practice your hacking skills is by fixing
+bugs reported by other people. Not only you will help to make the kernel
+more stable, you'll learn to fix real world problems and you will improve
+your skills, and other developers will be aware of your presence. Fixing
+bugs is one of the best ways to earn merit amongst the developers, because
+not many people like wasting time fixing other people's bugs.
+
+To work in the already reported bug reports, go to http://bugzilla.kernel.org.
+If you want to be advised of the future bug reports, you can subscribe to the
+bugme-new mailing list (only new bug reports are mailed here) or to the
+bugme-janitor mailing list (every change in the bugzilla is mailed here)
+
+ http://lists.osdl.org/mailman/listinfo/bugme-new
+ http://lists.osdl.org/mailman/listinfo/bugme-janitors
+
+
+
Mailing lists
-------------
diff --git a/Documentation/IPMI.txt b/Documentation/IPMI.txt
index 0256805b548f..9f08d73d90bf 100644
--- a/Documentation/IPMI.txt
+++ b/Documentation/IPMI.txt
@@ -326,9 +326,12 @@ for events, they will all receive all events that come in.
For receiving commands, you have to individually register commands you
want to receive. Call ipmi_register_for_cmd() and supply the netfn
-and command name for each command you want to receive. Only one user
-may be registered for each netfn/cmd, but different users may register
-for different commands.
+and command name for each command you want to receive. You also
+specify a bitmask of the channels you want to receive the command from
+(or use IPMI_CHAN_ALL for all channels if you don't care). Only one
+user may be registered for each netfn/cmd/channel, but different users
+may register for different commands, or the same command if the
+channel bitmasks do not overlap.
From userland, equivalent IOCTLs are provided to do these functions.
@@ -361,6 +364,7 @@ You can change this at module load time (for a module) with:
regspacings=<sp1>,<sp2>,... regsizes=<size1>,<size2>,...
regshifts=<shift1>,<shift2>,...
slave_addrs=<addr1>,<addr2>,...
+ force_kipmid=<enable1>,<enable2>,...
Each of these except si_trydefaults is a list, the first item for the
first interface, second item for the second interface, etc.
@@ -406,7 +410,13 @@ The slave_addrs specifies the IPMI address of the local BMC. This is
usually 0x20 and the driver defaults to that, but in case it's not, it
can be specified when the driver starts up.
-When compiled into the kernel, the addresses can be specified on the
+The force_ipmid parameter forcefully enables (if set to 1) or disables
+(if set to 0) the kernel IPMI daemon. Normally this is auto-detected
+by the driver, but systems with broken interrupts might need an enable,
+or users that don't want the daemon (don't need the performance, don't
+want the CPU hit) can disable it.
+
+When compiled into the kernel, the parameters can be specified on the
kernel command line as:
ipmi_si.type=<type1>,<type2>...
@@ -416,6 +426,7 @@ kernel command line as:
ipmi_si.regsizes=<size1>,<size2>,...
ipmi_si.regshifts=<shift1>,<shift2>,...
ipmi_si.slave_addrs=<addr1>,<addr2>,...
+ ipmi_si.force_kipmid=<enable1>,<enable2>,...
It works the same as the module parameters of the same names.
diff --git a/Documentation/SubmitChecklist b/Documentation/SubmitChecklist
index a10bfb6ecd9f..7ac61f60037a 100644
--- a/Documentation/SubmitChecklist
+++ b/Documentation/SubmitChecklist
@@ -61,3 +61,8 @@ kernel patches.
Documentation/kernel-parameters.txt.
18: All new module parameters are documented with MODULE_PARM_DESC()
+
+19: All new userspace interfaces are documented in Documentation/ABI/.
+ See Documentation/ABI/README for more information.
+
+20: Check that it all passes `make headers_check'.
diff --git a/Documentation/SubmittingDrivers b/Documentation/SubmittingDrivers
index 6bd30fdd0786..58bead05eabb 100644
--- a/Documentation/SubmittingDrivers
+++ b/Documentation/SubmittingDrivers
@@ -59,11 +59,11 @@ Copyright: The copyright owner must agree to use of GPL.
are the same person/entity. If not, the name of
the person/entity authorizing use of GPL should be
listed in case it's necessary to verify the will of
- the copright owner.
+ the copyright owner.
Interfaces: If your driver uses existing interfaces and behaves like
other drivers in the same class it will be much more likely
- to be accepted than if it invents gratuitous new ones.
+ to be accepted than if it invents gratuitous new ones.
If you need to implement a common API over Linux and NT
drivers do it in userspace.
@@ -88,7 +88,7 @@ Clarity: It helps if anyone can see how to fix the driver. It helps
it will go in the bitbucket.
Control: In general if there is active maintainance of a driver by
- the author then patches will be redirected to them unless
+ the author then patches will be redirected to them unless
they are totally obvious and without need of checking.
If you want to be the contact and update point for the
driver it is a good idea to state this in the comments,
@@ -100,7 +100,7 @@ What Criteria Do Not Determine Acceptance
Vendor: Being the hardware vendor and maintaining the driver is
often a good thing. If there is a stable working driver from
other people already in the tree don't expect 'we are the
- vendor' to get your driver chosen. Ideally work with the
+ vendor' to get your driver chosen. Ideally work with the
existing driver author to build a single perfect driver.
Author: It doesn't matter if a large Linux company wrote the driver,
@@ -116,17 +116,13 @@ Linux kernel master tree:
ftp.??.kernel.org:/pub/linux/kernel/...
?? == your country code, such as "us", "uk", "fr", etc.
-Linux kernel mailing list:
+Linux kernel mailing list:
linux-kernel@vger.kernel.org
[mail majordomo@vger.kernel.org to subscribe]
Linux Device Drivers, Third Edition (covers 2.6.10):
http://lwn.net/Kernel/LDD3/ (free version)
-Kernel traffic:
- Weekly summary of kernel list activity (much easier to read)
- http://www.kerneltraffic.org/kernel-traffic/
-
LWN.net:
Weekly summary of kernel development activity - http://lwn.net/
2.6 API changes:
@@ -145,11 +141,8 @@ KernelNewbies:
Linux USB project:
http://www.linux-usb.org/
-How to NOT write kernel driver by arjanv@redhat.com
- http://people.redhat.com/arjanv/olspaper.pdf
+How to NOT write kernel driver by Arjan van de Ven:
+ http://www.fenrus.org/how-to-not-write-a-device-driver-paper.pdf
Kernel Janitor:
http://janitor.kernelnewbies.org/
-
---
-Last updated on 17 Nov 2005.
diff --git a/Documentation/SubmittingPatches b/Documentation/SubmittingPatches
index d42ab4c9e893..302d148c2e18 100644
--- a/Documentation/SubmittingPatches
+++ b/Documentation/SubmittingPatches
@@ -173,15 +173,15 @@ For small patches you may want to CC the Trivial Patch Monkey
trivial@kernel.org managed by Adrian Bunk; which collects "trivial"
patches. Trivial patches must qualify for one of the following rules:
Spelling fixes in documentation
- Spelling fixes which could break grep(1).
+ Spelling fixes which could break grep(1)
Warning fixes (cluttering with useless warnings is bad)
Compilation fixes (only if they are actually correct)
Runtime fixes (only if they actually fix things)
- Removing use of deprecated functions/macros (eg. check_region).
+ Removing use of deprecated functions/macros (eg. check_region)
Contact detail and documentation fixes
Non-portable code replaced by portable code (even in arch-specific,
since people copy, as long as it's trivial)
- Any fix by the author/maintainer of the file. (ie. patch monkey
+ Any fix by the author/maintainer of the file (ie. patch monkey
in re-transmission mode)
URL: <http://www.kernel.org/pub/linux/kernel/people/bunk/trivial/>
@@ -209,6 +209,19 @@ Exception: If your mailer is mangling patches then someone may ask
you to re-send them using MIME.
+WARNING: Some mailers like Mozilla send your messages with
+---- message header ----
+Content-Type: text/plain; charset=us-ascii; format=flowed
+---- message header ----
+The problem is that "format=flowed" makes some of the mailers
+on receiving side to replace TABs with spaces and do similar
+changes. Thus the patches from you can look corrupted.
+
+To fix this just make your mozilla defaults/pref/mailnews.js file to look like:
+pref("mailnews.send_plaintext_flowed", false); // RFC 2646=======
+pref("mailnews.display.disable_format_flowed_support", true);
+
+
7) E-mail size.
@@ -245,13 +258,13 @@ updated change.
It is quite common for Linus to "drop" your patch without comment.
That's the nature of the system. If he drops your patch, it could be
due to
-* Your patch did not apply cleanly to the latest kernel version
+* Your patch did not apply cleanly to the latest kernel version.
* Your patch was not sufficiently discussed on linux-kernel.
-* A style issue (see section 2),
-* An e-mail formatting issue (re-read this section)
-* A technical problem with your change
-* He gets tons of e-mail, and yours got lost in the shuffle
-* You are being annoying (See Figure 1)
+* A style issue (see section 2).
+* An e-mail formatting issue (re-read this section).
+* A technical problem with your change.
+* He gets tons of e-mail, and yours got lost in the shuffle.
+* You are being annoying.
When in doubt, solicit comments on linux-kernel mailing list.
@@ -476,10 +489,10 @@ SECTION 3 - REFERENCES
Andrew Morton, "The perfect patch" (tpp).
<http://www.zip.com.au/~akpm/linux/patches/stuff/tpp.txt>
-Jeff Garzik, "Linux kernel patch submission format."
+Jeff Garzik, "Linux kernel patch submission format".
<http://linux.yyz.us/patch-format.html>
-Greg Kroah-Hartman "How to piss off a kernel subsystem maintainer".
+Greg Kroah-Hartman, "How to piss off a kernel subsystem maintainer".
<http://www.kroah.com/log/2005/03/31/>
<http://www.kroah.com/log/2005/07/08/>
<http://www.kroah.com/log/2005/10/19/>
@@ -488,9 +501,9 @@ Greg Kroah-Hartman "How to piss off a kernel subsystem maintainer".
NO!!!! No more huge patch bombs to linux-kernel@vger.kernel.org people!
<http://marc.theaimsgroup.com/?l=linux-kernel&m=112112749912944&w=2>
-Kernel Documentation/CodingStyle
+Kernel Documentation/CodingStyle:
<http://sosdg.org/~coywolf/lxr/source/Documentation/CodingStyle>
-Linus Torvald's mail on the canonical patch format:
+Linus Torvalds's mail on the canonical patch format:
<http://lkml.org/lkml/2005/4/7/183>
--
diff --git a/Documentation/accounting/getdelays.c b/Documentation/accounting/getdelays.c
index 795ca3911cc5..b11792abd6b6 100644
--- a/Documentation/accounting/getdelays.c
+++ b/Documentation/accounting/getdelays.c
@@ -285,7 +285,7 @@ int main(int argc, char *argv[])
if (maskset) {
rc = send_cmd(nl_sd, id, mypid, TASKSTATS_CMD_GET,
TASKSTATS_CMD_ATTR_REGISTER_CPUMASK,
- &cpumask, sizeof(cpumask));
+ &cpumask, strlen(cpumask) + 1);
PRINTF("Sent register cpumask, retval %d\n", rc);
if (rc < 0) {
printf("error sending register cpumask\n");
@@ -315,7 +315,8 @@ int main(int argc, char *argv[])
}
if (msg.n.nlmsg_type == NLMSG_ERROR ||
!NLMSG_OK((&msg.n), rep_len)) {
- printf("fatal reply error, errno %d\n", errno);
+ struct nlmsgerr *err = NLMSG_DATA(&msg);
+ printf("fatal reply error, errno %d\n", err->error);
goto done;
}
@@ -383,7 +384,7 @@ done:
if (maskset) {
rc = send_cmd(nl_sd, id, mypid, TASKSTATS_CMD_GET,
TASKSTATS_CMD_ATTR_DEREGISTER_CPUMASK,
- &cpumask, sizeof(cpumask));
+ &cpumask, strlen(cpumask) + 1);
printf("Sent deregister mask, retval %d\n", rc);
if (rc < 0)
err(rc, "error sending deregister cpumask\n");
diff --git a/Documentation/accounting/taskstats-struct.txt b/Documentation/accounting/taskstats-struct.txt
new file mode 100644
index 000000000000..661c797eaf79
--- /dev/null
+++ b/Documentation/accounting/taskstats-struct.txt
@@ -0,0 +1,161 @@
+The struct taskstats
+--------------------
+
+This document contains an explanation of the struct taskstats fields.
+
+There are three different groups of fields in the struct taskstats:
+
+1) Common and basic accounting fields
+ If CONFIG_TASKSTATS is set, the taskstats inteface is enabled and
+ the common fields and basic accounting fields are collected for
+ delivery at do_exit() of a task.
+2) Delay accounting fields
+ These fields are placed between
+ /* Delay accounting fields start */
+ and
+ /* Delay accounting fields end */
+ Their values are collected if CONFIG_TASK_DELAY_ACCT is set.
+3) Extended accounting fields
+ These fields are placed between
+ /* Extended accounting fields start */
+ and
+ /* Extended accounting fields end */
+ Their values are collected if CONFIG_TASK_XACCT is set.
+
+Future extension should add fields to the end of the taskstats struct, and
+should not change the relative position of each field within the struct.
+
+
+struct taskstats {
+
+1) Common and basic accounting fields:
+ /* The version number of this struct. This field is always set to
+ * TAKSTATS_VERSION, which is defined in <linux/taskstats.h>.
+ * Each time the struct is changed, the value should be incremented.
+ */
+ __u16 version;
+
+ /* The exit code of a task. */
+ __u32 ac_exitcode; /* Exit status */
+
+ /* The accounting flags of a task as defined in <linux/acct.h>
+ * Defined values are AFORK, ASU, ACOMPAT, ACORE, and AXSIG.
+ */
+ __u8 ac_flag; /* Record flags */
+
+ /* The value of task_nice() of a task. */
+ __u8 ac_nice; /* task_nice */
+
+ /* The name of the command that started this task. */
+ char ac_comm[TS_COMM_LEN]; /* Command name */
+
+ /* The scheduling discipline as set in task->policy field. */
+ __u8 ac_sched; /* Scheduling discipline */
+
+ __u8 ac_pad[3];
+ __u32 ac_uid; /* User ID */
+ __u32 ac_gid; /* Group ID */
+ __u32 ac_pid; /* Process ID */
+ __u32 ac_ppid; /* Parent process ID */
+
+ /* The time when a task begins, in [secs] since 1970. */
+ __u32 ac_btime; /* Begin time [sec since 1970] */
+
+ /* The elapsed time of a task, in [usec]. */
+ __u64 ac_etime; /* Elapsed time [usec] */
+
+ /* The user CPU time of a task, in [usec]. */
+ __u64 ac_utime; /* User CPU time [usec] */
+
+ /* The system CPU time of a task, in [usec]. */
+ __u64 ac_stime; /* System CPU time [usec] */
+
+ /* The minor page fault count of a task, as set in task->min_flt. */
+ __u64 ac_minflt; /* Minor Page Fault Count */
+
+ /* The major page fault count of a task, as set in task->maj_flt. */
+ __u64 ac_majflt; /* Major Page Fault Count */
+
+
+2) Delay accounting fields:
+ /* Delay accounting fields start
+ *
+ * All values, until the comment "Delay accounting fields end" are
+ * available only if delay accounting is enabled, even though the last
+ * few fields are not delays
+ *
+ * xxx_count is the number of delay values recorded
+ * xxx_delay_total is the corresponding cumulative delay in nanoseconds
+ *
+ * xxx_delay_total wraps around to zero on overflow
+ * xxx_count incremented regardless of overflow
+ */
+
+ /* Delay waiting for cpu, while runnable
+ * count, delay_total NOT updated atomically
+ */
+ __u64 cpu_count;
+ __u64 cpu_delay_total;
+
+ /* Following four fields atomically updated using task->delays->lock */
+
+ /* Delay waiting for synchronous block I/O to complete
+ * does not account for delays in I/O submission
+ */
+ __u64 blkio_count;
+ __u64 blkio_delay_total;
+
+ /* Delay waiting for page fault I/O (swap in only) */
+ __u64 swapin_count;
+ __u64 swapin_delay_total;
+
+ /* cpu "wall-clock" running time
+ * On some architectures, value will adjust for cpu time stolen
+ * from the kernel in involuntary waits due to virtualization.
+ * Value is cumulative, in nanoseconds, without a corresponding count
+ * and wraps around to zero silently on overflow
+ */
+ __u64 cpu_run_real_total;
+
+ /* cpu "virtual" running time
+ * Uses time intervals seen by the kernel i.e. no adjustment
+ * for kernel's involuntary waits due to virtualization.
+ * Value is cumulative, in nanoseconds, without a corresponding count
+ * and wraps around to zero silently on overflow
+ */
+ __u64 cpu_run_virtual_total;
+ /* Delay accounting fields end */
+ /* version 1 ends here */
+
+
+3) Extended accounting fields
+ /* Extended accounting fields start */
+
+ /* Accumulated RSS usage in duration of a task, in MBytes-usecs.
+ * The current rss usage is added to this counter every time
+ * a tick is charged to a task's system time. So, at the end we
+ * will have memory usage multiplied by system time. Thus an
+ * average usage per system time unit can be calculated.
+ */
+ __u64 coremem; /* accumulated RSS usage in MB-usec */
+
+ /* Accumulated virtual memory usage in duration of a task.
+ * Same as acct_rss_mem1 above except that we keep track of VM usage.
+ */
+ __u64 virtmem; /* accumulated VM usage in MB-usec */
+
+ /* High watermark of RSS usage in duration of a task, in KBytes. */
+ __u64 hiwater_rss; /* High-watermark of RSS usage */
+
+ /* High watermark of VM usage in duration of a task, in KBytes. */
+ __u64 hiwater_vm; /* High-water virtual memory usage */
+
+ /* The following four fields are I/O statistics of a task. */
+ __u64 read_char; /* bytes read */
+ __u64 write_char; /* bytes written */
+ __u64 read_syscalls; /* read syscalls */
+ __u64 write_syscalls; /* write syscalls */
+
+ /* Extended accounting fields end */
+
+}
diff --git a/Documentation/cpusets.txt b/Documentation/cpusets.txt
index 76b44290c154..842f0d1ab216 100644
--- a/Documentation/cpusets.txt
+++ b/Documentation/cpusets.txt
@@ -217,11 +217,11 @@ exclusive cpuset. Also, the use of a Linux virtual file system (vfs)
to represent the cpuset hierarchy provides for a familiar permission
and name space for cpusets, with a minimum of additional kernel code.
-The cpus file in the root (top_cpuset) cpuset is read-only.
-It automatically tracks the value of cpu_online_map, using a CPU
-hotplug notifier. If and when memory nodes can be hotplugged,
-we expect to make the mems file in the root cpuset read-only
-as well, and have it track the value of node_online_map.
+The cpus and mems files in the root (top_cpuset) cpuset are
+read-only. The cpus file automatically tracks the value of
+cpu_online_map using a CPU hotplug notifier, and the mems file
+automatically tracks the value of node_online_map using the
+cpuset_track_online_nodes() hook.
1.4 What are exclusive cpusets ?
diff --git a/Documentation/fb/intel810.txt b/Documentation/fb/intel810.txt
index 4f0d6bc789ef..be3e7836abef 100644
--- a/Documentation/fb/intel810.txt
+++ b/Documentation/fb/intel810.txt
@@ -9,8 +9,9 @@ Intel 810/815 Framebuffer driver
================================================================
A. Introduction
+
This is a framebuffer driver for various Intel 810/815 compatible
-graphics devices. These would include:
+ graphics devices. These include:
Intel 810
Intel 810E
@@ -21,136 +22,136 @@ graphics devices. These would include:
B. Features
- - Choice of using Discrete Video Timings, VESA Generalized Timing
+ - Choice of using Discrete Video Timings, VESA Generalized Timing
Formula, or a framebuffer specific database to set the video mode
- - Supports a variable range of horizontal and vertical resolution, and
- vertical refresh rates if the VESA Generalized Timing Formula is
+ - Supports a variable range of horizontal and vertical resolution and
+ vertical refresh rates if the VESA Generalized Timing Formula is
enabled.
- - Supports color depths of 8, 16, 24 and 32 bits per pixel
+ - Supports color depths of 8, 16, 24 and 32 bits per pixel
- Supports pseudocolor, directcolor, or truecolor visuals
- - Full and optimized hardware acceleration at 8, 16 and 24 bpp
+ - Full and optimized hardware acceleration at 8, 16 and 24 bpp
- Robust video state save and restore
- - MTRR support
+ - MTRR support
- Utilizes user-entered monitor specifications to automatically
calculate required video mode parameters.
- - Can concurrently run with xfree86 running with native i810 drivers
+ - Can concurrently run with xfree86 running with native i810 drivers
- Hardware Cursor Support
- Supports EDID probing either by DDC/I2C or through the BIOS
C. List of available options
-
- a. "video=i810fb"
+
+ a. "video=i810fb"
enables the i810 driver
Recommendation: required
-
- b. "xres:<value>"
+
+ b. "xres:<value>"
select horizontal resolution in pixels. (This parameter will be
ignored if 'mode_option' is specified. See 'o' below).
- Recommendation: user preference
+ Recommendation: user preference
(default = 640)
c. "yres:<value>"
select vertical resolution in scanlines. If Discrete Video Timings
is enabled, this will be ignored and computed as 3*xres/4. (This
parameter will be ignored if 'mode_option' is specified. See 'o'
- below)
+ below)
Recommendation: user preference
(default = 480)
-
- d. "vyres:<value>"
+
+ d. "vyres:<value>"
select virtual vertical resolution in scanlines. If (0) or none
- is specified, this will be computed against maximum available memory.
+ is specified, this will be computed against maximum available memory.
Recommendation: do not set
(default = 480)
e. "vram:<value>"
- select amount of system RAM in MB to allocate for the video memory
+ select amount of system RAM in MB to allocate for the video memory
Recommendation: 1 - 4 MB.
(default = 4)
- f. "bpp:<value>"
- select desired pixel depth
+ f. "bpp:<value>"
+ select desired pixel depth
Recommendation: 8
(default = 8)
- g. "hsync1/hsync2:<value>"
- select the minimum and maximum Horizontal Sync Frequency of the
- monitor in KHz. If a using a fixed frequency monitor, hsync1 must
+ g. "hsync1/hsync2:<value>"
+ select the minimum and maximum Horizontal Sync Frequency of the
+ monitor in kHz. If using a fixed frequency monitor, hsync1 must
be equal to hsync2. If EDID probing is successful, these will be
ignored and values will be taken from the EDID block.
Recommendation: check monitor manual for correct values
- default (29/30)
+ (default = 29/30)
- h. "vsync1/vsync2:<value>"
+ h. "vsync1/vsync2:<value>"
select the minimum and maximum Vertical Sync Frequency of the monitor
- in Hz. You can also use this option to lock your monitor's refresh
+ in Hz. You can also use this option to lock your monitor's refresh
rate. If EDID probing is successful, these will be ignored and values
will be taken from the EDID block.
Recommendation: check monitor manual for correct values
(default = 60/60)
- IMPORTANT: If you need to clamp your timings, try to give some
- leeway for computational errors (over/underflows). Example: if
+ IMPORTANT: If you need to clamp your timings, try to give some
+ leeway for computational errors (over/underflows). Example: if
using vsync1/vsync2 = 60/60, make sure hsync1/hsync2 has at least
a 1 unit difference, and vice versa.
- i. "voffset:<value>"
- select at what offset in MB of the logical memory to allocate the
+ i. "voffset:<value>"
+ select at what offset in MB of the logical memory to allocate the
framebuffer memory. The intent is to avoid the memory blocks
used by standard graphics applications (XFree86). The default
- offset (16 MB for a 64MB aperture, 8 MB for a 32MB aperture) will
- avoid XFree86's usage and allows up to 7MB/15MB of framebuffer
- memory. Depending on your usage, adjust the value up or down,
- (0 for maximum usage, 31/63 MB for the least amount). Note, an
+ offset (16 MB for a 64 MB aperture, 8 MB for a 32 MB aperture) will
+ avoid XFree86's usage and allows up to 7 MB/15 MB of framebuffer
+ memory. Depending on your usage, adjust the value up or down
+ (0 for maximum usage, 31/63 MB for the least amount). Note, an
arbitrary setting may conflict with XFree86.
Recommendation: do not set
(default = 8 or 16 MB)
-
- j. "accel"
- enable text acceleration. This can be enabled/reenabled anytime
- by using 'fbset -accel true/false'.
+
+ j. "accel"
+ enable text acceleration. This can be enabled/reenabled anytime
+ by using 'fbset -accel true/false'.
Recommendation: enable
- (default = not set)
+ (default = not set)
- k. "mtrr"
+ k. "mtrr"
enable MTRR. This allows data transfers to the framebuffer memory
to occur in bursts which can significantly increase performance.
- Not very helpful with the i810/i815 because of 'shared memory'.
+ Not very helpful with the i810/i815 because of 'shared memory'.
Recommendation: do not set
- (default = not set)
+ (default = not set)
l. "extvga"
if specified, secondary/external VGA output will always be enabled.
Useful if the BIOS turns off the VGA port when no monitor is attached.
- The external VGA monitor can then be attached without rebooting.
+ The external VGA monitor can then be attached without rebooting.
Recommendation: do not set
(default = not set)
-
- m. "sync"
+
+ m. "sync"
Forces the hardware engine to do a "sync" or wait for the hardware
- to finish before starting another instruction. This will produce a
+ to finish before starting another instruction. This will produce a
more stable setup, but will be slower.
Recommendation: do not set
@@ -162,6 +163,7 @@ C. List of available options
Recommendation: do not set
(default = not set)
+
o. <xres>x<yres>[-<bpp>][@<refresh>]
The driver will now accept specification of boot mode option. If this
is specified, the options 'xres' and 'yres' will be ignored. See
@@ -183,8 +185,8 @@ append="video=i810fb:vram:2,xres:1024,yres:768,bpp:8,hsync1:30,hsync2:55, \
vsync1:50,vsync2:85,accel,mtrr"
This will initialize the framebuffer to 1024x768 at 8bpp. The framebuffer
-will use 2 MB of System RAM. MTRR support will be enabled. The refresh rate
-will be computed based on the hsync1/hsync2 and vsync1/vsync2 values.
+will use 2 MB of System RAM. MTRR support will be enabled. The refresh rate
+will be computed based on the hsync1/hsync2 and vsync1/vsync2 values.
IMPORTANT:
You must include hsync1, hsync2, vsync1 and vsync2 to enable video modes
@@ -194,10 +196,10 @@ vsync1 and vsync2 parameters. These parameters will be taken from the EDID
block.
E. Module options
-
- The module parameters are essentially similar to the kernel
-parameters. The main difference is that you need to include a Boolean value
-(1 for TRUE, and 0 for FALSE) for those options which don't need a value.
+
+The module parameters are essentially similar to the kernel
+parameters. The main difference is that you need to include a Boolean value
+(1 for TRUE, and 0 for FALSE) for those options which don't need a value.
Example, to enable MTRR, include "mtrr=1".
@@ -214,62 +216,62 @@ Or just add the following to /etc/modprobe.conf
options i810fb vram=2 xres=1024 bpp=16 hsync1=30 hsync2=55 vsync1=50 \
vsync2=85 accel=1 mtrr=1
-and just do a
+and just do a
modprobe i810fb
F. Setup
- a. Do your usual method of configuring the kernel.
-
+ a. Do your usual method of configuring the kernel.
+
make menuconfig/xconfig/config
- b. Under "Code Maturity Options", enable "Prompt for experimental/
- incomplete code/drivers".
+ b. Under "Code maturity level options" enable "Prompt for development
+ and/or incomplete code/drivers".
c. Enable agpgart support for the Intel 810/815 on-board graphics.
- This is required. The option is under "Character Devices"
+ This is required. The option is under "Character Devices".
d. Under "Graphics Support", select "Intel 810/815" either statically
or as a module. Choose "use VESA Generalized Timing Formula" if
- you need to maximize the capability of your display. To be on the
- safe side, you can leave this unselected.
-
+ you need to maximize the capability of your display. To be on the
+ safe side, you can leave this unselected.
+
e. If you want support for DDC/I2C probing (Plug and Play Displays),
set 'Enable DDC Support' to 'y'. To make this option appear, set
'use VESA Generalized Timing Formula' to 'y'.
- f. If you want a framebuffer console, enable it under "Console
- Drivers"
+ f. If you want a framebuffer console, enable it under "Console
+ Drivers".
+
+ g. Compile your kernel.
+
+ h. Load the driver as described in sections D and E.
- g. Compile your kernel.
-
- h. Load the driver as described in section D and E.
-
i. Try the DirectFB (http://www.directfb.org) + the i810 gfxdriver
patch to see the chipset in action (or inaction :-).
G. Acknowledgment:
-
+
1. Geert Uytterhoeven - his excellent howto and the virtual
- framebuffer driver code made this possible.
+ framebuffer driver code made this possible.
- 2. Jeff Hartmann for his agpgart code.
+ 2. Jeff Hartmann for his agpgart code.
3. The X developers. Insights were provided just by reading the
XFree86 source code.
4. Intel(c). For this value-oriented chipset driver and for
- providing documentation.
+ providing documentation.
5. Matt Sottek. His inputs and ideas helped in making some
- optimizations possible.
+ optimizations possible.
H. Home Page:
A more complete, and probably updated information is provided at
-http://i810fb.sourceforge.net.
+ http://i810fb.sourceforge.net.
###########################
Tony
diff --git a/Documentation/fb/intelfb.txt b/Documentation/fb/intelfb.txt
index c12d39a23c3d..da5ee74219e8 100644
--- a/Documentation/fb/intelfb.txt
+++ b/Documentation/fb/intelfb.txt
@@ -1,16 +1,19 @@
-Intel 830M/845G/852GM/855GM/865G/915G Framebuffer driver
+Intel 830M/845G/852GM/855GM/865G/915G/945G Framebuffer driver
================================================================
A. Introduction
- This is a framebuffer driver for various Intel 810/815 compatible
+ This is a framebuffer driver for various Intel 8xx/9xx compatible
graphics devices. These would include:
Intel 830M
- Intel 810E845G
+ Intel 845G
Intel 852GM
Intel 855GM
Intel 865G
Intel 915G
+ Intel 915GM
+ Intel 945G
+ Intel 945GM
B. List of available options
@@ -78,19 +81,27 @@ C. Kernel booting
Separate each option/option-pair by commas (,) and the option from its value
with an equals sign (=) as in the following:
-video=i810fb:option1,option2=value2
+video=intelfb:option1,option2=value2
Sample Usage
------------
In /etc/lilo.conf, add the line:
-append="video=intelfb:800x600-32@75,accel,hwcursor,vram=8"
+append="video=intelfb:mode=800x600-32@75,accel,hwcursor,vram=8"
This will initialize the framebuffer to 800x600 at 32bpp and 75Hz. The
framebuffer will use 8 MB of System RAM. hw acceleration of text and cursor
will be enabled.
+Remarks
+-------
+
+If setting this parameter doesn't work (you stay in a 80x25 text-mode),
+you might need to set the "vga=<mode>" parameter too - see vesafb.txt
+in this directory.
+
+
D. Module options
The module parameters are essentially similar to the kernel
diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt
index 436697cb9388..b98f01fc14bf 100644
--- a/Documentation/feature-removal-schedule.txt
+++ b/Documentation/feature-removal-schedule.txt
@@ -46,17 +46,8 @@ Who: Jody McIntyre <scjody@modernduck.com>
---------------------------
-What: sbp2: module parameter "force_inquiry_hack"
-When: July 2006
-Why: Superceded by parameter "workarounds". Both parameters are meant to be
- used ad-hoc and for single devices only, i.e. not in modprobe.conf,
- therefore the impact of this feature replacement should be low.
-Who: Stefan Richter <stefanr@s5r6.in-berlin.de>
-
----------------------------
-
What: Video4Linux API 1 ioctls and video_decoder.h from Video devices.
-When: July 2006
+When: December 2006
Why: V4L1 AP1 was replaced by V4L2 API. during migration from 2.4 to 2.6
series. The old API have lots of drawbacks and don't provide enough
means to work with all video and audio standards. The newer API is
@@ -131,15 +122,6 @@ Who: Arjan van de Ven
---------------------------
-What: START_ARRAY ioctl for md
-When: July 2006
-Files: drivers/md/md.c
-Why: Not reliable by design - can fail when most needed.
- Alternatives exist
-Who: NeilBrown <neilb@suse.de>
-
----------------------------
-
What: eepro100 network driver
When: January 2007
Why: replaced by the e100 driver
@@ -334,3 +316,11 @@ Why: i2c-isa is a non-sense and doesn't fit in the device driver
Who: Jean Delvare <khali@linux-fr.org>
---------------------------
+
+What: ftape
+When: 2.6.20
+Why: Orphaned for ages. SMP bugs long unfixed. Few users left
+ in the world.
+Who: Jeff Garzik <jeff@garzik.org>
+
+---------------------------
diff --git a/Documentation/filesystems/Locking b/Documentation/filesystems/Locking
index 247d7f619aa2..eb1a6cad21e6 100644
--- a/Documentation/filesystems/Locking
+++ b/Documentation/filesystems/Locking
@@ -356,10 +356,9 @@ The last two are called only from check_disk_change().
prototypes:
loff_t (*llseek) (struct file *, loff_t, int);
ssize_t (*read) (struct file *, char __user *, size_t, loff_t *);
- ssize_t (*aio_read) (struct kiocb *, char __user *, size_t, loff_t);
ssize_t (*write) (struct file *, const char __user *, size_t, loff_t *);
- ssize_t (*aio_write) (struct kiocb *, const char __user *, size_t,
- loff_t);
+ ssize_t (*aio_read) (struct kiocb *, const struct iovec *, unsigned long, loff_t);
+ ssize_t (*aio_write) (struct kiocb *, const struct iovec *, unsigned long, loff_t);
int (*readdir) (struct file *, void *, filldir_t);
unsigned int (*poll) (struct file *, struct poll_table_struct *);
int (*ioctl) (struct inode *, struct file *, unsigned int,
diff --git a/Documentation/filesystems/proc.txt b/Documentation/filesystems/proc.txt
index 7db71d6fba82..7240ee7515de 100644
--- a/Documentation/filesystems/proc.txt
+++ b/Documentation/filesystems/proc.txt
@@ -39,6 +39,8 @@ Table of Contents
2.9 Appletalk
2.10 IPX
2.11 /proc/sys/fs/mqueue - POSIX message queues filesystem
+ 2.12 /proc/<pid>/oom_adj - Adjust the oom-killer score
+ 2.13 /proc/<pid>/oom_score - Display current oom-killer score
------------------------------------------------------------------------------
Preface
@@ -1962,6 +1964,22 @@ a queue must be less or equal then msg_max.
maximum message size value (it is every message queue's attribute set during
its creation).
+2.12 /proc/<pid>/oom_adj - Adjust the oom-killer score
+------------------------------------------------------
+
+This file can be used to adjust the score used to select which processes
+should be killed in an out-of-memory situation. Giving it a high score will
+increase the likelihood of this process being killed by the oom-killer. Valid
+values are in the range -16 to +15, plus the special value -17, which disables
+oom-killing altogether for this process.
+
+2.13 /proc/<pid>/oom_score - Display current oom-killer score
+-------------------------------------------------------------
+
+------------------------------------------------------------------------------
+This file can be used to check the current score used by the oom-killer is for
+any given <pid>. Use it together with /proc/<pid>/oom_adj to tune which
+process should be killed in an out-of-memory situation.
------------------------------------------------------------------------------
Summary
diff --git a/Documentation/filesystems/vfs.txt b/Documentation/filesystems/vfs.txt
index 1cb7e8be927a..cd07c21b8400 100644
--- a/Documentation/filesystems/vfs.txt
+++ b/Documentation/filesystems/vfs.txt
@@ -699,9 +699,9 @@ This describes how the VFS can manipulate an open file. As of kernel
struct file_operations {
loff_t (*llseek) (struct file *, loff_t, int);
ssize_t (*read) (struct file *, char __user *, size_t, loff_t *);
- ssize_t (*aio_read) (struct kiocb *, char __user *, size_t, loff_t);
ssize_t (*write) (struct file *, const char __user *, size_t, loff_t *);
- ssize_t (*aio_write) (struct kiocb *, const char __user *, size_t, loff_t);
+ ssize_t (*aio_read) (struct kiocb *, const struct iovec *, unsigned long, loff_t);
+ ssize_t (*aio_write) (struct kiocb *, const struct iovec *, unsigned long, loff_t);
int (*readdir) (struct file *, void *, filldir_t);
unsigned int (*poll) (struct file *, struct poll_table_struct *);
int (*ioctl) (struct inode *, struct file *, unsigned int, unsigned long);
diff --git a/Documentation/ia64/serial.txt b/Documentation/ia64/serial.txt
index f51eb4bc2ff1..040b9773209f 100644
--- a/Documentation/ia64/serial.txt
+++ b/Documentation/ia64/serial.txt
@@ -124,6 +124,13 @@ TROUBLESHOOTING SERIAL CONSOLE PROBLEMS
- Add entry to /etc/securetty for console tty.
+ No ACPI serial devices found in 2.6.17 or later:
+
+ - Turn on CONFIG_PNP and CONFIG_PNPACPI. Prior to 2.6.17, ACPI
+ serial devices were discovered by 8250_acpi. In 2.6.17,
+ 8250_acpi was replaced by the combination of 8250_pnp and
+ CONFIG_PNPACPI.
+
[1] http://www.dig64.org/specifications/DIG64_PCDPv20.pdf
diff --git a/Documentation/input/ff.txt b/Documentation/input/ff.txt
index c7e10eaff203..c53b1c11aa40 100644
--- a/Documentation/input/ff.txt
+++ b/Documentation/input/ff.txt
@@ -1,67 +1,37 @@
Force feedback for Linux.
By Johann Deneux <deneux@ifrance.com> on 2001/04/22.
+Updated by Anssi Hannula <anssi.hannula@gmail.com> on 2006/04/09.
You may redistribute this file. Please remember to include shape.fig and
interactive.fig as well.
----------------------------------------------------------------------------
-0. Introduction
+1. Introduction
~~~~~~~~~~~~~~~
This document describes how to use force feedback devices under Linux. The
goal is not to support these devices as if they were simple input-only devices
(as it is already the case), but to really enable the rendering of force
effects.
-At the moment, only I-Force devices are supported, and not officially. That
-means I had to find out how the protocol works on my own. Of course, the
-information I managed to grasp is far from being complete, and I can not
-guarranty that this driver will work for you.
-This document only describes the force feedback part of the driver for I-Force
-devices. Please read joystick.txt before reading further this document.
+This document only describes the force feedback part of the Linux input
+interface. Please read joystick.txt and input.txt before reading further this
+document.
2. Instructions to the user
~~~~~~~~~~~~~~~~~~~~~~~~~~~
-Here are instructions on how to compile and use the driver. In fact, this
-driver is the normal iforce, input and evdev drivers written by Vojtech
-Pavlik, plus additions to support force feedback.
+To enable force feedback, you have to:
+
+1. have your kernel configured with evdev and a driver that supports your
+ device.
+2. make sure evdev module is loaded and /dev/input/event* device files are
+ created.
Before you start, let me WARN you that some devices shake violently during the
initialisation phase. This happens for example with my "AVB Top Shot Pegasus".
To stop this annoying behaviour, move you joystick to its limits. Anyway, you
-should keep a hand on your device, in order to avoid it to brake down if
+should keep a hand on your device, in order to avoid it to break down if
something goes wrong.
-At the kernel's compilation:
- - Enable IForce/Serial
- - Enable Event interface
-
-Compile the modules, install them.
-
-You also need inputattach.
-
-You then need to insert the modules into the following order:
-% modprobe joydev
-% modprobe serport # Only for serial
-% modprobe iforce
-% modprobe evdev
-% ./inputattach -ifor $2 & # Only for serial
-If you are using USB, you don't need the inputattach step.
-
-Please check that you have all the /dev/input entries needed:
-cd /dev
-rm js*
-mkdir input
-mknod input/js0 c 13 0
-mknod input/js1 c 13 1
-mknod input/js2 c 13 2
-mknod input/js3 c 13 3
-ln -s input/js0 js0
-ln -s input/js1 js1
-ln -s input/js2 js2
-ln -s input/js3 js3
-
-mknod input/event0 c 13 64
-mknod input/event1 c 13 65
-mknod input/event2 c 13 66
-mknod input/event3 c 13 67
+If you have a serial iforce device, you need to start inputattach. See
+joystick.txt for details.
2.1 Does it work ?
~~~~~~~~~~~~~~~~~~
@@ -70,9 +40,9 @@ There is an utility called fftest that will allow you to test the driver.
3. Instructions to the developper
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- All interactions are done using the event API. That is, you can use ioctl()
+All interactions are done using the event API. That is, you can use ioctl()
and write() on /dev/input/eventXX.
- This information is subject to change.
+This information is subject to change.
3.1 Querying device capabilities
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -86,18 +56,29 @@ int ioctl(int file_descriptor, int request, unsigned long *features);
Returns the features supported by the device. features is a bitfield with the
following bits:
-- FF_X has an X axis (usually joysticks)
-- FF_Y has an Y axis (usually joysticks)
-- FF_WHEEL has a wheel (usually sterring wheels)
- FF_CONSTANT can render constant force effects
-- FF_PERIODIC can render periodic effects (sine, triangle, square...)
+- FF_PERIODIC can render periodic effects with the following waveforms:
+ - FF_SQUARE square waveform
+ - FF_TRIANGLE triangle waveform
+ - FF_SINE sine waveform
+ - FF_SAW_UP sawtooth up waveform
+ - FF_SAW_DOWN sawtooth down waveform
+ - FF_CUSTOM custom waveform
- FF_RAMP can render ramp effects
- FF_SPRING can simulate the presence of a spring
-- FF_FRICTION can simulate friction
+- FF_FRICTION can simulate friction
- FF_DAMPER can simulate damper effects
-- FF_RUMBLE rumble effects (normally the only effect supported by rumble
- pads)
+- FF_RUMBLE rumble effects
- FF_INERTIA can simulate inertia
+- FF_GAIN gain is adjustable
+- FF_AUTOCENTER autocenter is adjustable
+
+Note: In most cases you should use FF_PERIODIC instead of FF_RUMBLE. All
+ devices that support FF_RUMBLE support FF_PERIODIC (square, triangle,
+ sine) and the other way around.
+
+Note: The exact syntax FF_CUSTOM is undefined for the time being as no driver
+ supports it yet.
int ioctl(int fd, EVIOCGEFFECTS, int *n);
@@ -108,7 +89,7 @@ Returns the number of effects the device can keep in its memory.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#include <linux/input.h>
#include <sys/ioctl.h>
-
+
int ioctl(int file_descriptor, int request, struct ff_effect *effect);
"request" must be EVIOCSFF.
@@ -120,6 +101,9 @@ to the unique id assigned by the driver. This data is required for performing
some operations (removing an effect, controlling the playback).
This if field must be set to -1 by the user in order to tell the driver to
allocate a new effect.
+
+Effects are file descriptor specific.
+
See <linux/input.h> for a description of the ff_effect struct. You should also
find help in a few sketches, contained in files shape.fig and interactive.fig.
You need xfig to visualize these files.
@@ -128,8 +112,8 @@ You need xfig to visualize these files.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
int ioctl(int fd, EVIOCRMFF, effect.id);
-This makes room for new effects in the device's memory. Please note this won't
-stop the effect if it was playing.
+This makes room for new effects in the device's memory. Note that this also
+stops the effect if it was playing.
3.4 Controlling the playback of effects
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -149,22 +133,21 @@ Control of playing is done with write(). Below is an example:
play.type = EV_FF;
play.code = effect.id;
play.value = 3;
-
+
write(fd, (const void*) &play, sizeof(play));
...
/* Stop an effect */
stop.type = EV_FF;
stop.code = effect.id;
stop.value = 0;
-
+
write(fd, (const void*) &play, sizeof(stop));
3.5 Setting the gain
~~~~~~~~~~~~~~~~~~~~
Not all devices have the same strength. Therefore, users should set a gain
factor depending on how strong they want effects to be. This setting is
-persistent across access to the driver, so you should not care about it if
-you are writing games, as another utility probably already set this for you.
+persistent across access to the driver.
/* Set the gain of the device
int gain; /* between 0 and 100 */
@@ -204,11 +187,14 @@ type of device, not all parameters can be dynamically updated. For example,
the direction of an effect cannot be updated with iforce devices. In this
case, the driver stops the effect, up-load it, and restart it.
+Therefore it is recommended to dynamically change direction while the effect
+is playing only when it is ok to restart the effect with a replay count of 1.
3.8 Information about the status of effects
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Every time the status of an effect is changed, an event is sent. The values
and meanings of the fields of the event are as follows:
+
struct input_event {
/* When the status of the effect changed */
struct timeval time;
@@ -225,3 +211,9 @@ struct input_event {
FF_STATUS_STOPPED The effect stopped playing
FF_STATUS_PLAYING The effect started to play
+
+NOTE: Status feedback is only supported by iforce driver. If you have
+ a really good reason to use this, please contact
+ linux-joystick@atrey.karlin.mff.cuni.cz or anssi.hannula@gmail.com
+ so that support for it can be added to the rest of the drivers.
+
diff --git a/Documentation/kbuild/modules.txt b/Documentation/kbuild/modules.txt
index 2e7702e94a78..769ee05ee4d1 100644
--- a/Documentation/kbuild/modules.txt
+++ b/Documentation/kbuild/modules.txt
@@ -43,7 +43,7 @@ are not planned to be included in the kernel tree.
What is covered within this file is mainly information to authors
of modules. The author of an external module should supply
a makefile that hides most of the complexity, so one only has to type
-'make' to build the module. A complete example will be present in
+'make' to build the module. A complete example will be presented in
chapter 4, "Creating a kbuild file for an external module".
@@ -61,6 +61,7 @@ when building an external module.
make -C <path-to-kernel> M=`pwd`
For the running kernel use:
+
make -C /lib/modules/`uname -r`/build M=`pwd`
For the above command to succeed, the kernel must have been
@@ -130,10 +131,10 @@ when building an external module.
To make sure the kernel contains the information required to
build external modules the target 'modules_prepare' must be used.
- 'module_prepare' exists solely as a simple way to prepare
+ 'modules_prepare' exists solely as a simple way to prepare
a kernel source tree for building external modules.
Note: modules_prepare will not build Module.symvers even if
- CONFIG_MODULEVERSIONING is set. Therefore a full kernel build
+ CONFIG_MODVERSIONS is set. Therefore a full kernel build
needs to be executed to make module versioning work.
--- 2.5 Building separate files for a module
@@ -450,7 +451,7 @@ kernel refuses to load the module.
Module.symvers contains a list of all exported symbols from a kernel build.
---- 7.1 Symbols fron the kernel (vmlinux + modules)
+--- 7.1 Symbols from the kernel (vmlinux + modules)
During a kernel build, a file named Module.symvers will be generated.
Module.symvers contains all exported symbols from the kernel and
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
index 54983246930d..137e993f4329 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -110,6 +110,13 @@ be entered as an environment variable, whereas its absence indicates that
it will appear as a kernel argument readable via /proc/cmdline by programs
running once the system is up.
+The number of kernel parameters is not limited, but the length of the
+complete command line (parameters including spaces etc.) is limited to
+a fixed number of characters. This limit depends on the architecture
+and is between 256 and 4096 characters. It is defined in the file
+./include/asm/setup.h as COMMAND_LINE_SIZE.
+
+
53c7xx= [HW,SCSI] Amiga SCSI controllers
See header of drivers/scsi/53c7xx.c.
See also Documentation/scsi/ncr53c7xx.txt.
@@ -1324,7 +1331,7 @@ running once the system is up.
pt. [PARIDE]
See Documentation/paride.txt.
- quiet= [KNL] Disable log messages
+ quiet [KNL] Disable most log messages
r128= [HW,DRM]
diff --git a/Documentation/kprobes.txt b/Documentation/kprobes.txt
index 2c3b1eae4280..ba26201d5023 100644
--- a/Documentation/kprobes.txt
+++ b/Documentation/kprobes.txt
@@ -151,9 +151,9 @@ So that you can load and unload Kprobes-based instrumentation modules,
make sure "Loadable module support" (CONFIG_MODULES) and "Module
unloading" (CONFIG_MODULE_UNLOAD) are set to "y".
-You may also want to ensure that CONFIG_KALLSYMS and perhaps even
-CONFIG_KALLSYMS_ALL are set to "y", since kallsyms_lookup_name()
-is a handy, version-independent way to find a function's address.
+Also make sure that CONFIG_KALLSYMS and perhaps even CONFIG_KALLSYMS_ALL
+are set to "y", since kallsyms_lookup_name() is used by the in-kernel
+kprobe address resolution code.
If you need to insert a probe in the middle of a function, you may find
it useful to "Compile the kernel with debug info" (CONFIG_DEBUG_INFO),
@@ -179,6 +179,27 @@ occurs during execution of kp->pre_handler or kp->post_handler,
or during single-stepping of the probed instruction, Kprobes calls
kp->fault_handler. Any or all handlers can be NULL.
+NOTE:
+1. With the introduction of the "symbol_name" field to struct kprobe,
+the probepoint address resolution will now be taken care of by the kernel.
+The following will now work:
+
+ kp.symbol_name = "symbol_name";
+
+(64-bit powerpc intricacies such as function descriptors are handled
+transparently)
+
+2. Use the "offset" field of struct kprobe if the offset into the symbol
+to install a probepoint is known. This field is used to calculate the
+probepoint.
+
+3. Specify either the kprobe "symbol_name" OR the "addr". If both are
+specified, kprobe registration will fail with -EINVAL.
+
+4. With CISC architectures (such as i386 and x86_64), the kprobes code
+does not validate if the kprobe.addr is at an instruction boundary.
+Use "offset" with caution.
+
register_kprobe() returns 0 on success, or a negative errno otherwise.
User's pre-handler (kp->pre_handler):
@@ -225,6 +246,12 @@ control to Kprobes.) If the probed function is declared asmlinkage,
fastcall, or anything else that affects how args are passed, the
handler's declaration must match.
+NOTE: A macro JPROBE_ENTRY is provided to handle architecture-specific
+aliasing of jp->entry. In the interest of portability, it is advised
+to use:
+
+ jp->entry = JPROBE_ENTRY(handler);
+
register_jprobe() returns 0 on success, or a negative errno otherwise.
4.3 register_kretprobe
@@ -251,6 +278,11 @@ of interest:
- ret_addr: the return address
- rp: points to the corresponding kretprobe object
- task: points to the corresponding task struct
+
+The regs_return_value(regs) macro provides a simple abstraction to
+extract the return value from the appropriate register as defined by
+the architecture's ABI.
+
The handler's return value is currently ignored.
4.4 unregister_*probe
@@ -369,7 +401,6 @@ stack trace and selected i386 registers when do_fork() is called.
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/kprobes.h>
-#include <linux/kallsyms.h>
#include <linux/sched.h>
/*For each probe you need to allocate a kprobe structure*/
@@ -403,18 +434,14 @@ int handler_fault(struct kprobe *p, struct pt_regs *regs, int trapnr)
return 0;
}
-int init_module(void)
+static int __init kprobe_init(void)
{
int ret;
kp.pre_handler = handler_pre;
kp.post_handler = handler_post;
kp.fault_handler = handler_fault;
- kp.addr = (kprobe_opcode_t*) kallsyms_lookup_name("do_fork");
- /* register the kprobe now */
- if (!kp.addr) {
- printk("Couldn't find %s to plant kprobe\n", "do_fork");
- return -1;
- }
+ kp.symbol_name = "do_fork";
+
if ((ret = register_kprobe(&kp) < 0)) {
printk("register_kprobe failed, returned %d\n", ret);
return -1;
@@ -423,12 +450,14 @@ int init_module(void)
return 0;
}
-void cleanup_module(void)
+static void __exit kprobe_exit(void)
{
unregister_kprobe(&kp);
printk("kprobe unregistered\n");
}
+module_init(kprobe_init)
+module_exit(kprobe_exit)
MODULE_LICENSE("GPL");
----- cut here -----
@@ -463,7 +492,6 @@ the arguments of do_fork().
#include <linux/fs.h>
#include <linux/uio.h>
#include <linux/kprobes.h>
-#include <linux/kallsyms.h>
/*
* Jumper probe for do_fork.
@@ -485,17 +513,13 @@ long jdo_fork(unsigned long clone_flags, unsigned long stack_start,
}
static struct jprobe my_jprobe = {
- .entry = (kprobe_opcode_t *) jdo_fork
+ .entry = JPROBE_ENTRY(jdo_fork)
};
-int init_module(void)
+static int __init jprobe_init(void)
{
int ret;
- my_jprobe.kp.addr = (kprobe_opcode_t *) kallsyms_lookup_name("do_fork");
- if (!my_jprobe.kp.addr) {
- printk("Couldn't find %s to plant jprobe\n", "do_fork");
- return -1;
- }
+ my_jprobe.kp.symbol_name = "do_fork";
if ((ret = register_jprobe(&my_jprobe)) <0) {
printk("register_jprobe failed, returned %d\n", ret);
@@ -506,12 +530,14 @@ int init_module(void)
return 0;
}
-void cleanup_module(void)
+static void __exit jprobe_exit(void)
{
unregister_jprobe(&my_jprobe);
printk("jprobe unregistered\n");
}
+module_init(jprobe_init)
+module_exit(jprobe_exit)
MODULE_LICENSE("GPL");
----- cut here -----
@@ -530,16 +556,13 @@ report failed calls to sys_open().
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/kprobes.h>
-#include <linux/kallsyms.h>
static const char *probed_func = "sys_open";
/* Return-probe handler: If the probed function fails, log the return value. */
static int ret_handler(struct kretprobe_instance *ri, struct pt_regs *regs)
{
- // Substitute the appropriate register name for your architecture --
- // e.g., regs->rax for x86_64, regs->gpr[3] for ppc64.
- int retval = (int) regs->eax;
+ int retval = regs_return_value(regs);
if (retval < 0) {
printk("%s returns %d\n", probed_func, retval);
}
@@ -552,15 +575,11 @@ static struct kretprobe my_kretprobe = {
.maxactive = 20
};
-int init_module(void)
+static int __init kretprobe_init(void)
{
int ret;
- my_kretprobe.kp.addr =
- (kprobe_opcode_t *) kallsyms_lookup_name(probed_func);
- if (!my_kretprobe.kp.addr) {
- printk("Couldn't find %s to plant return probe\n", probed_func);
- return -1;
- }
+ my_kretprobe.kp.symbol_name = (char *)probed_func;
+
if ((ret = register_kretprobe(&my_kretprobe)) < 0) {
printk("register_kretprobe failed, returned %d\n", ret);
return -1;
@@ -569,7 +588,7 @@ int init_module(void)
return 0;
}
-void cleanup_module(void)
+static void __exit kretprobe_exit(void)
{
unregister_kretprobe(&my_kretprobe);
printk("kretprobe unregistered\n");
@@ -578,6 +597,8 @@ void cleanup_module(void)
my_kretprobe.nmissed, probed_func);
}
+module_init(kretprobe_init)
+module_exit(kretprobe_exit)
MODULE_LICENSE("GPL");
----- cut here -----
@@ -590,3 +611,5 @@ messages.)
For additional information on Kprobes, refer to the following URLs:
http://www-106.ibm.com/developerworks/library/l-kprobes.html?ca=dgr-lnxw42Kprobe
http://www.redhat.com/magazine/005mar05/features/kprobes/
+http://www-users.cs.umn.edu/~boutcher/kprobes/
+http://www.linuxsymposium.org/2006/linuxsymposium_procv2.pdf (pages 101-115)
diff --git a/Documentation/lockdep-design.txt b/Documentation/lockdep-design.txt
index 00d93605bfd3..55a7e4fa8cc2 100644
--- a/Documentation/lockdep-design.txt
+++ b/Documentation/lockdep-design.txt
@@ -36,6 +36,28 @@ The validator tracks lock-class usage history into 5 separate state bits:
- 'ever used' [ == !unused ]
+When locking rules are violated, these 4 state bits are presented in the
+locking error messages, inside curlies. A contrived example:
+
+ modprobe/2287 is trying to acquire lock:
+ (&sio_locks[i].lock){--..}, at: [<c02867fd>] mutex_lock+0x21/0x24
+
+ but task is already holding lock:
+ (&sio_locks[i].lock){--..}, at: [<c02867fd>] mutex_lock+0x21/0x24
+
+
+The bit position indicates hardirq, softirq, hardirq-read,
+softirq-read respectively, and the character displayed in each
+indicates:
+
+ '.' acquired while irqs enabled
+ '+' acquired in irq context
+ '-' acquired in process context with irqs disabled
+ '?' read-acquired both with irqs enabled and in irq context
+
+Unused mutexes cannot be part of the cause of an error.
+
+
Single-lock state rules:
------------------------
diff --git a/Documentation/md.txt b/Documentation/md.txt
index 0668f9dc9d29..9ae9e4078985 100644
--- a/Documentation/md.txt
+++ b/Documentation/md.txt
@@ -154,11 +154,12 @@ contains further md-specific information about the device.
All md devices contain:
level
- a text file indicating the 'raid level'. This may be a standard
- numerical level prefixed by "RAID-" - e.g. "RAID-5", or some
- other name such as "linear" or "multipath".
+ a text file indicating the 'raid level'. e.g. raid0, raid1,
+ raid5, linear, multipath, faulty.
If no raid level has been set yet (array is still being
- assembled), this file will be empty.
+ assembled), the value will reflect whatever has been written
+ to it, which may be a name like the above, or may be a number
+ such as '0', '5', etc.
raid_disks
a text file with a simple number indicating the number of devices
@@ -192,14 +193,6 @@ All md devices contain:
1.2 (newer format in varying locations) or "none" indicating that
the kernel isn't managing metadata at all.
- level
- The raid 'level' for this array. The name will often (but not
- always) be the same as the name of the module that implements the
- level. To be auto-loaded the module must have an alias
- md-$LEVEL e.g. md-raid5
- This can be written only while the array is being assembled, not
- after it is started.
-
layout
The "layout" for the array for the particular level. This is
simply a number that is interpretted differently by different
@@ -410,6 +403,15 @@ also have
than sectors, this my be larger than the number of actual errors
by a factor of the number of sectors in a page.
+ bitmap_set_bits
+ If the array has a write-intent bitmap, then writing to this
+ attribute can set bits in the bitmap, indicating that a resync
+ would need to check the corresponding blocks. Either individual
+ numbers or start-end pairs can be written. Multiple numbers
+ can be separated by a space.
+ Note that the numbers are 'bit' numbers, not 'block' numbers.
+ They should be scaled by the bitmap_chunksize.
+
Each active md device may also have attributes specific to the
personality module that manages it.
These are specific to the implementation of the module and could
diff --git a/Documentation/networking/pktgen.txt b/Documentation/networking/pktgen.txt
index 44f2f769e865..18d385c068fc 100644
--- a/Documentation/networking/pktgen.txt
+++ b/Documentation/networking/pktgen.txt
@@ -100,6 +100,7 @@ Examples:
are: IPSRC_RND #IP Source is random (between min/max),
IPDST_RND, UDPSRC_RND,
UDPDST_RND, MACSRC_RND, MACDST_RND
+ MPLS_RND, VID_RND, SVID_RND
pgset "udp_src_min 9" set UDP source port min, If < udp_src_max, then
cycle through the port range.
@@ -125,6 +126,21 @@ Examples:
pgset "mpls 0" turn off mpls (or any invalid argument works too!)
+ pgset "vlan_id 77" set VLAN ID 0-4095
+ pgset "vlan_p 3" set priority bit 0-7 (default 0)
+ pgset "vlan_cfi 0" set canonical format identifier 0-1 (default 0)
+
+ pgset "svlan_id 22" set SVLAN ID 0-4095
+ pgset "svlan_p 3" set priority bit 0-7 (default 0)
+ pgset "svlan_cfi 0" set canonical format identifier 0-1 (default 0)
+
+ pgset "vlan_id 9999" > 4095 remove vlan and svlan tags
+ pgset "svlan 9999" > 4095 remove svlan tag
+
+
+ pgset "tos XX" set former IPv4 TOS field (e.g. "tos 28" for AF11 no ECN, default 00)
+ pgset "traffic_class XX" set former IPv6 TRAFFIC CLASS (e.g. "traffic_class B8" for EF no ECN, default 00)
+
pgset stop aborts injection. Also, ^C aborts generator.
diff --git a/Documentation/rt-mutex-design.txt b/Documentation/rt-mutex-design.txt
index c472ffacc2f6..4b736d24da7a 100644
--- a/Documentation/rt-mutex-design.txt
+++ b/Documentation/rt-mutex-design.txt
@@ -333,11 +333,11 @@ cmpxchg is basically the following function performed atomically:
unsigned long _cmpxchg(unsigned long *A, unsigned long *B, unsigned long *C)
{
- unsigned long T = *A;
- if (*A == *B) {
- *A = *C;
- }
- return T;
+ unsigned long T = *A;
+ if (*A == *B) {
+ *A = *C;
+ }
+ return T;
}
#define cmpxchg(a,b,c) _cmpxchg(&a,&b,&c)
@@ -582,7 +582,7 @@ contention).
try_to_take_rt_mutex is used every time the task tries to grab a mutex in the
slow path. The first thing that is done here is an atomic setting of
the "Has Waiters" flag of the mutex's owner field. Yes, this could really
-be false, because if the the mutex has no owner, there are no waiters and
+be false, because if the mutex has no owner, there are no waiters and
the current task also won't have any waiters. But we don't have the lock
yet, so we assume we are going to be a waiter. The reason for this is to
play nice for those architectures that do have CMPXCHG. By setting this flag
@@ -735,7 +735,7 @@ do have CMPXCHG, that check is done in the fast path, but it is still needed
in the slow path too. If a waiter of a mutex woke up because of a signal
or timeout between the time the owner failed the fast path CMPXCHG check and
the grabbing of the wait_lock, the mutex may not have any waiters, thus the
-owner still needs to make this check. If there are no waiters than the mutex
+owner still needs to make this check. If there are no waiters then the mutex
owner field is set to NULL, the wait_lock is released and nothing more is
needed.
diff --git a/Documentation/seclvl.txt b/Documentation/seclvl.txt
deleted file mode 100644
index 97274d122d0e..000000000000
--- a/Documentation/seclvl.txt
+++ /dev/null
@@ -1,97 +0,0 @@
-BSD Secure Levels Linux Security Module
-Michael A. Halcrow <mike@halcrow.us>
-
-
-Introduction
-
-Under the BSD Secure Levels security model, sets of policies are
-associated with levels. Levels range from -1 to 2, with -1 being the
-weakest and 2 being the strongest. These security policies are
-enforced at the kernel level, so not even the superuser is able to
-disable or circumvent them. This hardens the machine against attackers
-who gain root access to the system.
-
-
-Levels and Policies
-
-Level -1 (Permanently Insecure):
- - Cannot increase the secure level
-
-Level 0 (Insecure):
- - Cannot ptrace the init process
-
-Level 1 (Default):
- - /dev/mem and /dev/kmem are read-only
- - IMMUTABLE and APPEND extended attributes, if set, may not be unset
- - Cannot load or unload kernel modules
- - Cannot write directly to a mounted block device
- - Cannot perform raw I/O operations
- - Cannot perform network administrative tasks
- - Cannot setuid any file
-
-Level 2 (Secure):
- - Cannot decrement the system time
- - Cannot write to any block device, whether mounted or not
- - Cannot unmount any mounted filesystems
-
-
-Compilation
-
-To compile the BSD Secure Levels LSM, seclvl.ko, enable the
-SECURITY_SECLVL configuration option. This is found under Security
-options -> BSD Secure Levels in the kernel configuration menu.
-
-
-Basic Usage
-
-Once the machine is in a running state, with all the necessary modules
-loaded and all the filesystems mounted, you can load the seclvl.ko
-module:
-
-# insmod seclvl.ko
-
-The module defaults to secure level 1, except when compiled directly
-into the kernel, in which case it defaults to secure level 0. To raise
-the secure level to 2, the administrator writes ``2'' to the
-seclvl/seclvl file under the sysfs mount point (assumed to be /sys in
-these examples):
-
-# echo -n "2" > /sys/seclvl/seclvl
-
-Alternatively, you can initialize the module at secure level 2 with
-the initlvl module parameter:
-
-# insmod seclvl.ko initlvl=2
-
-At this point, it is impossible to remove the module or reduce the
-secure level. If the administrator wishes to have the option of doing
-so, he must provide a module parameter, sha1_passwd, that specifies
-the SHA1 hash of the password that can be used to reduce the secure
-level to 0.
-
-To generate this SHA1 hash, the administrator can use OpenSSL:
-
-# echo -n "boogabooga" | openssl sha1
-abeda4e0f33defa51741217592bf595efb8d289c
-
-In order to use password-instigated secure level reduction, the SHA1
-crypto module must be loaded or compiled into the kernel:
-
-# insmod sha1.ko
-
-The administrator can then insmod the seclvl module, including the
-SHA1 hash of the password:
-
-# insmod seclvl.ko
- sha1_passwd=abeda4e0f33defa51741217592bf595efb8d289c
-
-To reduce the secure level, write the password to seclvl/passwd under
-your sysfs mount point:
-
-# echo -n "boogabooga" > /sys/seclvl/passwd
-
-The September 2004 edition of Sys Admin Magazine has an article about
-the BSD Secure Levels LSM. I encourage you to refer to that article
-for a more in-depth treatment of this security module:
-
-http://www.samag.com/documents/s=9304/sam0409a/0409a.htm
diff --git a/Documentation/video4linux/CARDLIST.cx88 b/Documentation/video4linux/CARDLIST.cx88
index 00d9a1f2a54c..669a09aa5bb4 100644
--- a/Documentation/video4linux/CARDLIST.cx88
+++ b/Documentation/video4linux/CARDLIST.cx88
@@ -7,10 +7,10 @@
6 -> AverTV Studio 303 (M126) [1461:000b]
7 -> MSI TV-@nywhere Master [1462:8606]
8 -> Leadtek Winfast DV2000 [107d:6620]
- 9 -> Leadtek PVR 2000 [107d:663b,107d:663C]
+ 9 -> Leadtek PVR 2000 [107d:663b,107d:663c,107d:6632]
10 -> IODATA GV-VCP3/PCI [10fc:d003]
11 -> Prolink PlayTV PVR
- 12 -> ASUS PVR-416 [1043:4823]
+ 12 -> ASUS PVR-416 [1043:4823,1461:c111]
13 -> MSI TV-@nywhere
14 -> KWorld/VStream XPert DVB-T [17de:08a6]
15 -> DViCO FusionHDTV DVB-T1 [18ac:db00]
@@ -51,3 +51,7 @@
50 -> NPG Tech Real TV FM Top 10 [14f1:0842]
51 -> WinFast DTV2000 H [107d:665e]
52 -> Geniatech DVB-S [14f1:0084]
+ 53 -> Hauppauge WinTV-HVR3000 TriMode Analog/DVB-S/DVB-T [0070:1404]
+ 54 -> Norwood Micro TV Tuner
+ 55 -> Shenzhen Tungsten Ages Tech TE-DTV-250 / Swann OEM [c180:c980]
+ 56 -> Hauppauge WinTV-HVR1300 DVB-T/Hybrid MPEG Encoder [0070:9600,0070:9601,0070:9602]
diff --git a/Documentation/video4linux/CARDLIST.saa7134 b/Documentation/video4linux/CARDLIST.saa7134
index 9068b669f5ee..94cf695b1378 100644
--- a/Documentation/video4linux/CARDLIST.saa7134
+++ b/Documentation/video4linux/CARDLIST.saa7134
@@ -58,7 +58,7 @@
57 -> Avermedia AVerTV GO 007 FM [1461:f31f]
58 -> ADS Tech Instant TV (saa7135) [1421:0350,1421:0351,1421:0370,1421:1370]
59 -> Kworld/Tevion V-Stream Xpert TV PVR7134
- 60 -> LifeView/Typhoon FlyDVB-T Duo Cardbus [5168:0502,4e42:0502]
+ 60 -> LifeView/Typhoon/Genius FlyDVB-T Duo Cardbus [5168:0502,4e42:0502,1489:0502]
61 -> Philips TOUGH DVB-T reference design [1131:2004]
62 -> Compro VideoMate TV Gold+II
63 -> Kworld Xpert TV PVR7134
@@ -83,7 +83,7 @@
82 -> MSI TV@Anywhere plus [1462:6231]
83 -> Terratec Cinergy 250 PCI TV [153b:1160]
84 -> LifeView FlyDVB Trio [5168:0319]
- 85 -> AverTV DVB-T 777 [1461:2c05]
+ 85 -> AverTV DVB-T 777 [1461:2c05,1461:2c05]
86 -> LifeView FlyDVB-T / Genius VideoWonder DVB-T [5168:0301,1489:0301]
87 -> ADS Instant TV Duo Cardbus PTV331 [0331:1421]
88 -> Tevion/KWorld DVB-T 220RF [17de:7201]
@@ -94,3 +94,6 @@
93 -> Medion 7134 Bridge #2 [16be:0005]
94 -> LifeView FlyDVB-T Hybrid Cardbus [5168:3306,5168:3502]
95 -> LifeView FlyVIDEO3000 (NTSC) [5169:0138]
+ 96 -> Medion Md8800 Quadro [16be:0007,16be:0008]
+ 97 -> LifeView FlyDVB-S /Acorp TV134DS [5168:0300,4e42:0300]
+ 98 -> Proteus Pro 2309 [0919:2003]
diff --git a/Documentation/video4linux/bttv/Insmod-options b/Documentation/video4linux/bttv/Insmod-options
index fc94ff235ffa..bb7c2cac7917 100644
--- a/Documentation/video4linux/bttv/Insmod-options
+++ b/Documentation/video4linux/bttv/Insmod-options
@@ -54,6 +54,12 @@ bttv.o
dropouts.
chroma_agc=0/1 AGC of chroma signal, off by default.
adc_crush=0/1 Luminance ADC crush, on by default.
+ i2c_udelay= Allow reduce I2C speed. Default is 5 usecs
+ (meaning 66,67 Kbps). The default is the
+ maximum supported speed by kernel bitbang
+ algoritm. You may use lower numbers, if I2C
+ messages are lost (16 is known to work on
+ all supported cards).
bttv_gpio=0/1
gpiomask=
diff --git a/Documentation/video4linux/cx2341x/README.hm12 b/Documentation/video4linux/cx2341x/README.hm12
new file mode 100644
index 000000000000..0e213ed095e6
--- /dev/null
+++ b/Documentation/video4linux/cx2341x/README.hm12
@@ -0,0 +1,116 @@
+The cx23416 can produce (and the cx23415 can also read) raw YUV output. The
+format of a YUV frame is specific to this chip and is called HM12. 'HM' stands
+for 'Hauppauge Macroblock', which is a misnomer as 'Conexant Macroblock' would
+be more accurate.
+
+The format is YUV 4:2:0 which uses 1 Y byte per pixel and 1 U and V byte per
+four pixels.
+
+The data is encoded as two macroblock planes, the first containing the Y
+values, the second containing UV macroblocks.
+
+The Y plane is divided into blocks of 16x16 pixels from left to right
+and from top to bottom. Each block is transmitted in turn, line-by-line.
+
+So the first 16 bytes are the first line of the top-left block, the
+second 16 bytes are the second line of the top-left block, etc. After
+transmitting this block the first line of the block on the right to the
+first block is transmitted, etc.
+
+The UV plane is divided into blocks of 16x8 UV values going from left
+to right, top to bottom. Each block is transmitted in turn, line-by-line.
+
+So the first 16 bytes are the first line of the top-left block and
+contain 8 UV value pairs (16 bytes in total). The second 16 bytes are the
+second line of 8 UV pairs of the top-left block, etc. After transmitting
+this block the first line of the block on the right to the first block is
+transmitted, etc.
+
+The code below is given as an example on how to convert HM12 to separate
+Y, U and V planes. This code assumes frames of 720x576 (PAL) pixels.
+
+The width of a frame is always 720 pixels, regardless of the actual specified
+width.
+
+--------------------------------------------------------------------------
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+static unsigned char frame[576*720*3/2];
+static unsigned char framey[576*720];
+static unsigned char frameu[576*720 / 4];
+static unsigned char framev[576*720 / 4];
+
+static void de_macro_y(unsigned char* dst, unsigned char *src, int dstride, int w, int h)
+{
+ unsigned int y, x, i;
+
+ // descramble Y plane
+ // dstride = 720 = w
+ // The Y plane is divided into blocks of 16x16 pixels
+ // Each block in transmitted in turn, line-by-line.
+ for (y = 0; y < h; y += 16) {
+ for (x = 0; x < w; x += 16) {
+ for (i = 0; i < 16; i++) {
+ memcpy(dst + x + (y + i) * dstride, src, 16);
+ src += 16;
+ }
+ }
+ }
+}
+
+static void de_macro_uv(unsigned char *dstu, unsigned char *dstv, unsigned char *src, int dstride, int w, int h)
+{
+ unsigned int y, x, i;
+
+ // descramble U/V plane
+ // dstride = 720 / 2 = w
+ // The U/V values are interlaced (UVUV...).
+ // Again, the UV plane is divided into blocks of 16x16 UV values.
+ // Each block in transmitted in turn, line-by-line.
+ for (y = 0; y < h; y += 16) {
+ for (x = 0; x < w; x += 8) {
+ for (i = 0; i < 16; i++) {
+ int idx = x + (y + i) * dstride;
+
+ dstu[idx+0] = src[0]; dstv[idx+0] = src[1];
+ dstu[idx+1] = src[2]; dstv[idx+1] = src[3];
+ dstu[idx+2] = src[4]; dstv[idx+2] = src[5];
+ dstu[idx+3] = src[6]; dstv[idx+3] = src[7];
+ dstu[idx+4] = src[8]; dstv[idx+4] = src[9];
+ dstu[idx+5] = src[10]; dstv[idx+5] = src[11];
+ dstu[idx+6] = src[12]; dstv[idx+6] = src[13];
+ dstu[idx+7] = src[14]; dstv[idx+7] = src[15];
+ src += 16;
+ }
+ }
+ }
+}
+
+/*************************************************************************/
+int main(int argc, char **argv)
+{
+ FILE *fin;
+ int i;
+
+ if (argc == 1) fin = stdin;
+ else fin = fopen(argv[1], "r");
+
+ if (fin == NULL) {
+ fprintf(stderr, "cannot open input\n");
+ exit(-1);
+ }
+ while (fread(frame, sizeof(frame), 1, fin) == 1) {
+ de_macro_y(framey, frame, 720, 720, 576);
+ de_macro_uv(frameu, framev, frame + 720 * 576, 720 / 2, 720 / 2, 576 / 2);
+ fwrite(framey, sizeof(framey), 1, stdout);
+ fwrite(framev, sizeof(framev), 1, stdout);
+ fwrite(frameu, sizeof(frameu), 1, stdout);
+ }
+ fclose(fin);
+ return 0;
+}
+
+--------------------------------------------------------------------------
diff --git a/Documentation/video4linux/cx2341x/README.vbi b/Documentation/video4linux/cx2341x/README.vbi
new file mode 100644
index 000000000000..5807cf156173
--- /dev/null
+++ b/Documentation/video4linux/cx2341x/README.vbi
@@ -0,0 +1,45 @@
+
+Format of embedded V4L2_MPEG_STREAM_VBI_FMT_IVTV VBI data
+=========================================================
+
+This document describes the V4L2_MPEG_STREAM_VBI_FMT_IVTV format of the VBI data
+embedded in an MPEG-2 program stream. This format is in part dictated by some
+hardware limitations of the ivtv driver (the driver for the Conexant cx23415/6
+chips), in particular a maximum size for the VBI data. Anything longer is cut
+off when the MPEG stream is played back through the cx23415.
+
+The advantage of this format is it is very compact and that all VBI data for
+all lines can be stored while still fitting within the maximum allowed size.
+
+The stream ID of the VBI data is 0xBD. The maximum size of the embedded data is
+4 + 43 * 36, which is 4 bytes for a header and 2 * 18 VBI lines with a 1 byte
+header and a 42 bytes payload each. Anything beyond this limit is cut off by
+the cx23415/6 firmware. Besides the data for the VBI lines we also need 36 bits
+for a bitmask determining which lines are captured and 4 bytes for a magic cookie,
+signifying that this data package contains V4L2_MPEG_STREAM_VBI_FMT_IVTV VBI data.
+If all lines are used, then there is no longer room for the bitmask. To solve this
+two different magic numbers were introduced:
+
+'itv0': After this magic number two unsigned longs follow. Bits 0-17 of the first
+unsigned long denote which lines of the first field are captured. Bits 18-31 of
+the first unsigned long and bits 0-3 of the second unsigned long are used for the
+second field.
+
+'ITV0': This magic number assumes all VBI lines are captured, i.e. it implicitly
+implies that the bitmasks are 0xffffffff and 0xf.
+
+After these magic cookies (and the 8 byte bitmask in case of cookie 'itv0') the
+captured VBI lines start:
+
+For each line the least significant 4 bits of the first byte contain the data type.
+Possible values are shown in the table below. The payload is in the following 42
+bytes.
+
+Here is the list of possible data types:
+
+#define IVTV_SLICED_TYPE_TELETEXT 0x1 // Teletext (uses lines 6-22 for PAL)
+#define IVTV_SLICED_TYPE_CC 0x4 // Closed Captions (line 21 NTSC)
+#define IVTV_SLICED_TYPE_WSS 0x5 // Wide Screen Signal (line 23 PAL)
+#define IVTV_SLICED_TYPE_VPS 0x7 // Video Programming System (PAL) (line 16)
+
+Hans Verkuil <hverkuil@xs4all.nl>
diff --git a/Documentation/x86_64/boot-options.txt b/Documentation/x86_64/boot-options.txt
index 4303e0c12476..74b77f9e91bc 100644
--- a/Documentation/x86_64/boot-options.txt
+++ b/Documentation/x86_64/boot-options.txt
@@ -199,6 +199,11 @@ IOMMU
allowed overwrite iommu off workarounds for specific chipsets.
soft Use software bounce buffering (default for Intel machines)
noaperture Don't touch the aperture for AGP.
+ allowdac Allow DMA >4GB
+ When off all DMA over >4GB is forced through an IOMMU or bounce
+ buffering.
+ nodac Forbid DMA >4GB
+ panic Always panic when IOMMU overflows
swiotlb=pages[,force]
diff --git a/MAINTAINERS b/MAINTAINERS
index 332b220f8a23..28cd70cf3e99 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -501,7 +501,7 @@ S: Maintained
BLOCK LAYER
P: Jens Axboe
-M: axboe@suse.de
+M: axboe@kernel.dk
L: linux-kernel@vger.kernel.org
T: git kernel.org:/pub/scm/linux/kernel/git/axboe/linux-2.6-block.git
S: Maintained
@@ -851,7 +851,7 @@ P: Doug Warzecha
M: Douglas_Warzecha@dell.com
S: Maintained
-DEVICE-MAPPER
+DEVICE-MAPPER (LVM)
P: Alasdair Kergon
L: dm-devel@redhat.com
W: http://sources.redhat.com/dm
@@ -1380,7 +1380,7 @@ S: Maintained
IDE/ATAPI CDROM DRIVER
P: Jens Axboe
-M: axboe@suse.de
+M: axboe@kernel.dk
L: linux-kernel@vger.kernel.org
W: http://www.kernel.dk
S: Maintained
@@ -1398,36 +1398,29 @@ M: Gadi Oxman <gadio@netvision.net.il>
L: linux-kernel@vger.kernel.org
S: Maintained
-IEEE 1394 ETHERNET (eth1394)
-L: linux1394-devel@lists.sourceforge.net
-W: http://www.linux1394.org/
-S: Orphan
-
IEEE 1394 SUBSYSTEM
P: Ben Collins
M: bcollins@debian.org
-P: Jody McIntyre
-M: scjody@modernduck.com
+P: Stefan Richter
+M: stefanr@s5r6.in-berlin.de
L: linux1394-devel@lists.sourceforge.net
W: http://www.linux1394.org/
-T: git kernel.org:/pub/scm/linux/kernel/git/scjody/ieee1394.git
+T: git kernel.org:/pub/scm/linux/kernel/git/ieee1394/linux1394-2.6.git
S: Maintained
-IEEE 1394 OHCI DRIVER
-P: Ben Collins
-M: bcollins@debian.org
-P: Jody McIntyre
-M: scjody@modernduck.com
+IEEE 1394 IPV4 DRIVER (eth1394)
+P: Stefan Richter
+M: stefanr@s5r6.in-berlin.de
L: linux1394-devel@lists.sourceforge.net
-W: http://www.linux1394.org/
-S: Maintained
+S: Odd Fixes
IEEE 1394 PCILYNX DRIVER
P: Jody McIntyre
M: scjody@modernduck.com
+P: Stefan Richter
+M: stefanr@s5r6.in-berlin.de
L: linux1394-devel@lists.sourceforge.net
-W: http://www.linux1394.org/
-S: Maintained
+S: Odd Fixes
IEEE 1394 RAW I/O DRIVER
P: Ben Collins
@@ -1435,16 +1428,6 @@ M: bcollins@debian.org
P: Dan Dennedy
M: dan@dennedy.org
L: linux1394-devel@lists.sourceforge.net
-W: http://www.linux1394.org/
-S: Maintained
-
-IEEE 1394 SBP2
-P: Ben Collins
-M: bcollins@debian.org
-P: Stefan Richter
-M: stefanr@s5r6.in-berlin.de
-L: linux1394-devel@lists.sourceforge.net
-W: http://www.linux1394.org/
S: Maintained
IMS TWINTURBO FRAMEBUFFER DRIVER
@@ -2062,7 +2045,7 @@ L: linux-hams@vger.kernel.org
W: http://www.linux-ax25.org/
S: Maintained
-NETWORK BLOCK DEVICE
+NETWORK BLOCK DEVICE (NBD)
P: Paul Clements
M: Paul.Clements@steeleye.com
S: Maintained
@@ -2548,7 +2531,7 @@ S: Maintained
SCSI CDROM DRIVER
P: Jens Axboe
-M: axboe@suse.de
+M: axboe@kernel.dk
L: linux-scsi@vger.kernel.org
W: http://www.kernel.dk
S: Maintained
@@ -2728,14 +2711,6 @@ M: chrisw@sous-sol.org
L: stable@kernel.org
S: Maintained
-STABLE BRANCH:
-P: Greg Kroah-Hartman
-M: greg@kroah.com
-P: Chris Wright
-M: chrisw@sous-sol.org
-L: stable@kernel.org
-S: Maintained
-
TPM DEVICE DRIVER
P: Kylene Hall
M: kjhall@us.ibm.com
@@ -2810,6 +2785,12 @@ M: R.E.Wolff@BitWizard.nl
L: linux-kernel@vger.kernel.org ?
S: Supported
+SPIDERNET NETWORK DRIVER for CELL
+P: Jim Lewis
+M: jim@jklewis.com
+L: netdev@vger.kernel.org
+S: Supported
+
SRM (Alpha) environment access
P: Jan-Benedict Glaw
M: jbglaw@lug-owl.de
@@ -2834,22 +2815,15 @@ S: Maintained
SUPERH (sh)
P: Paul Mundt
M: lethal@linux-sh.org
-P: Kazumoto Kojima
-M: kkojima@rr.iij4u.or.jp
-L: linuxsh-dev@lists.sourceforge.net
+L: linuxsh-dev@lists.sourceforge.net (subscribers-only)
W: http://www.linux-sh.org
-W: http://www.m17n.org/linux-sh/
-W: http://www.rr.iij4u.or.jp/~kkojima/linux-sh4.html
S: Maintained
SUPERH64 (sh64)
P: Paul Mundt
M: lethal@linux-sh.org
-P: Richard Curnow
-M: rc@rc0.org.uk
L: linuxsh-shmedia-dev@lists.sourceforge.net
W: http://www.linux-sh.org
-W: http://www.rc0.org.uk/sh64
S: Maintained
SUN3/3X
@@ -2990,7 +2964,7 @@ S: Maintained
UNIFORM CDROM DRIVER
P: Jens Axboe
-M: axboe@suse.de
+M: axboe@kernel.dk
L: linux-kernel@vger.kernel.org
W: http://www.kernel.dk
S: Maintained
diff --git a/arch/alpha/kernel/alpha_ksyms.c b/arch/alpha/kernel/alpha_ksyms.c
index f042cc42b00f..dbe327d32b6f 100644
--- a/arch/alpha/kernel/alpha_ksyms.c
+++ b/arch/alpha/kernel/alpha_ksyms.c
@@ -36,7 +36,6 @@
#include <asm/cacheflush.h>
#include <asm/vga.h>
-#define __KERNEL_SYSCALLS__
#include <asm/unistd.h>
extern struct hwrpb_struct *hwrpb;
@@ -116,7 +115,7 @@ EXPORT_SYMBOL(sys_dup);
EXPORT_SYMBOL(sys_exit);
EXPORT_SYMBOL(sys_write);
EXPORT_SYMBOL(sys_lseek);
-EXPORT_SYMBOL(execve);
+EXPORT_SYMBOL(kernel_execve);
EXPORT_SYMBOL(sys_setsid);
EXPORT_SYMBOL(sys_wait4);
diff --git a/arch/alpha/kernel/entry.S b/arch/alpha/kernel/entry.S
index 01ecd09d4a64..c95e95e1ab04 100644
--- a/arch/alpha/kernel/entry.S
+++ b/arch/alpha/kernel/entry.S
@@ -655,12 +655,12 @@ kernel_thread:
.end kernel_thread
/*
- * execve(path, argv, envp)
+ * kernel_execve(path, argv, envp)
*/
.align 4
- .globl execve
- .ent execve
-execve:
+ .globl kernel_execve
+ .ent kernel_execve
+kernel_execve:
/* We can be called from a module. */
ldgp $gp, 0($27)
lda $sp, -(32+SIZEOF_PT_REGS+8)($sp)
@@ -704,7 +704,7 @@ execve:
1: lda $sp, 32+SIZEOF_PT_REGS+8($sp)
ret
-.end execve
+.end kernel_execve
/*
diff --git a/arch/alpha/kernel/osf_sys.c b/arch/alpha/kernel/osf_sys.c
index 73c7622b5297..ad6173651995 100644
--- a/arch/alpha/kernel/osf_sys.c
+++ b/arch/alpha/kernel/osf_sys.c
@@ -111,22 +111,26 @@ struct osf_dirent_callback {
static int
osf_filldir(void *__buf, const char *name, int namlen, loff_t offset,
- ino_t ino, unsigned int d_type)
+ u64 ino, unsigned int d_type)
{
struct osf_dirent __user *dirent;
struct osf_dirent_callback *buf = (struct osf_dirent_callback *) __buf;
unsigned int reclen = ROUND_UP(NAME_OFFSET + namlen + 1);
+ unsigned int d_ino;
buf->error = -EINVAL; /* only used if we fail */
if (reclen > buf->count)
return -EINVAL;
+ d_ino = ino;
+ if (sizeof(d_ino) < sizeof(ino) && d_ino != ino)
+ return -EOVERFLOW;
if (buf->basep) {
if (put_user(offset, buf->basep))
return -EFAULT;
buf->basep = NULL;
}
dirent = buf->dirent;
- put_user(ino, &dirent->d_ino);
+ put_user(d_ino, &dirent->d_ino);
put_user(namlen, &dirent->d_namlen);
put_user(reclen, &dirent->d_reclen);
if (copy_to_user(dirent->d_name, name, namlen) ||
@@ -402,15 +406,15 @@ osf_utsname(char __user *name)
down_read(&uts_sem);
error = -EFAULT;
- if (copy_to_user(name + 0, system_utsname.sysname, 32))
+ if (copy_to_user(name + 0, utsname()->sysname, 32))
goto out;
- if (copy_to_user(name + 32, system_utsname.nodename, 32))
+ if (copy_to_user(name + 32, utsname()->nodename, 32))
goto out;
- if (copy_to_user(name + 64, system_utsname.release, 32))
+ if (copy_to_user(name + 64, utsname()->release, 32))
goto out;
- if (copy_to_user(name + 96, system_utsname.version, 32))
+ if (copy_to_user(name + 96, utsname()->version, 32))
goto out;
- if (copy_to_user(name + 128, system_utsname.machine, 32))
+ if (copy_to_user(name + 128, utsname()->machine, 32))
goto out;
error = 0;
@@ -449,8 +453,8 @@ osf_getdomainname(char __user *name, int namelen)
down_read(&uts_sem);
for (i = 0; i < len; ++i) {
- __put_user(system_utsname.domainname[i], name + i);
- if (system_utsname.domainname[i] == '\0')
+ __put_user(utsname()->domainname[i], name + i);
+ if (utsname()->domainname[i] == '\0')
break;
}
up_read(&uts_sem);
@@ -607,12 +611,12 @@ osf_sigstack(struct sigstack __user *uss, struct sigstack __user *uoss)
asmlinkage long
osf_sysinfo(int command, char __user *buf, long count)
{
- static char * sysinfo_table[] = {
- system_utsname.sysname,
- system_utsname.nodename,
- system_utsname.release,
- system_utsname.version,
- system_utsname.machine,
+ char *sysinfo_table[] = {
+ utsname()->sysname,
+ utsname()->nodename,
+ utsname()->release,
+ utsname()->version,
+ utsname()->machine,
"alpha", /* instruction set architecture */
"dummy", /* hardware serial number */
"dummy", /* hardware manufacturer */
diff --git a/arch/alpha/kernel/proto.h b/arch/alpha/kernel/proto.h
index 2a6e3da8144f..21f71287b6f5 100644
--- a/arch/alpha/kernel/proto.h
+++ b/arch/alpha/kernel/proto.h
@@ -1,5 +1,7 @@
#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <asm/pgtable.h>
/* Prototypes of functions used across modules here in this directory. */
@@ -181,9 +183,16 @@ extern void titan_dispatch_irqs(u64, struct pt_regs *);
extern void switch_to_system_map(void);
extern void srm_paging_stop(void);
-/* ../mm/remap.c */
-extern int __alpha_remap_area_pages(unsigned long, unsigned long,
- unsigned long, unsigned long);
+static inline int
+__alpha_remap_area_pages(unsigned long address, unsigned long phys_addr,
+ unsigned long size, unsigned long flags)
+{
+ pgprot_t prot;
+
+ prot = __pgprot(_PAGE_VALID | _PAGE_ASM | _PAGE_KRE
+ | _PAGE_KWE | flags);
+ return ioremap_page_range(address, address + size, phys_addr, prot);
+}
/* irq.c */
diff --git a/arch/alpha/kernel/srmcons.c b/arch/alpha/kernel/srmcons.c
index 9d7dff27f815..756923203860 100644
--- a/arch/alpha/kernel/srmcons.c
+++ b/arch/alpha/kernel/srmcons.c
@@ -229,7 +229,7 @@ srmcons_close(struct tty_struct *tty, struct file *filp)
static struct tty_driver *srmcons_driver;
-static struct tty_operations srmcons_ops = {
+static const struct tty_operations srmcons_ops = {
.open = srmcons_open,
.close = srmcons_close,
.write = srmcons_write,
diff --git a/arch/alpha/kernel/time.c b/arch/alpha/kernel/time.c
index b191cc759737..581ddcc22fc5 100644
--- a/arch/alpha/kernel/time.c
+++ b/arch/alpha/kernel/time.c
@@ -54,8 +54,6 @@
#include "proto.h"
#include "irq_impl.h"
-extern unsigned long wall_jiffies; /* kernel/timer.c */
-
static int set_rtc_mmss(unsigned long);
DEFINE_SPINLOCK(rtc_lock);
@@ -132,7 +130,7 @@ irqreturn_t timer_interrupt(int irq, void *dev, struct pt_regs * regs)
nticks = delta >> FIX_SHIFT;
while (nticks > 0) {
- do_timer(regs);
+ do_timer(1);
#ifndef CONFIG_SMP
update_process_times(user_mode(regs));
#endif
@@ -413,7 +411,7 @@ void
do_gettimeofday(struct timeval *tv)
{
unsigned long flags;
- unsigned long sec, usec, lost, seq;
+ unsigned long sec, usec, seq;
unsigned long delta_cycles, delta_usec, partial_tick;
do {
@@ -423,14 +421,13 @@ do_gettimeofday(struct timeval *tv)
sec = xtime.tv_sec;
usec = (xtime.tv_nsec / 1000);
partial_tick = state.partial_tick;
- lost = jiffies - wall_jiffies;
} while (read_seqretry_irqrestore(&xtime_lock, seq, flags));
#ifdef CONFIG_SMP
/* Until and unless we figure out how to get cpu cycle counters
in sync and keep them there, we can't use the rpcc tricks. */
- delta_usec = lost * (1000000 / HZ);
+ delta_usec = 0;
#else
/*
* usec = cycles * ticks_per_cycle * 2**48 * 1e6 / (2**48 * ticks)
@@ -446,8 +443,7 @@ do_gettimeofday(struct timeval *tv)
*/
delta_usec = (delta_cycles * state.scaled_ticks_per_cycle
- + partial_tick
- + (lost << FIX_SHIFT)) * 15625;
+ + partial_tick) * 15625;
delta_usec = ((delta_usec / ((1UL << (FIX_SHIFT-6-1)) * HZ)) + 1) / 2;
#endif
@@ -480,12 +476,11 @@ do_settimeofday(struct timespec *tv)
time. Without this, a full-tick error is possible. */
#ifdef CONFIG_SMP
- delta_nsec = (jiffies - wall_jiffies) * (NSEC_PER_SEC / HZ);
+ delta_nsec = 0;
#else
delta_nsec = rpcc() - state.last_time;
delta_nsec = (delta_nsec * state.scaled_ticks_per_cycle
- + state.partial_tick
- + ((jiffies - wall_jiffies) << FIX_SHIFT)) * 15625;
+ + state.partial_tick) * 15625;
delta_nsec = ((delta_nsec / ((1UL << (FIX_SHIFT-6-1)) * HZ)) + 1) / 2;
delta_nsec *= 1000;
#endif
diff --git a/arch/alpha/mm/Makefile b/arch/alpha/mm/Makefile
index 6edd9a09ea4f..09399c5386cb 100644
--- a/arch/alpha/mm/Makefile
+++ b/arch/alpha/mm/Makefile
@@ -4,6 +4,6 @@
EXTRA_CFLAGS := -Werror
-obj-y := init.o fault.o extable.o remap.o
+obj-y := init.o fault.o extable.o
obj-$(CONFIG_DISCONTIGMEM) += numa.o
diff --git a/arch/alpha/mm/fault.c b/arch/alpha/mm/fault.c
index 622dabd84680..8871529a34e2 100644
--- a/arch/alpha/mm/fault.c
+++ b/arch/alpha/mm/fault.c
@@ -193,7 +193,7 @@ do_page_fault(unsigned long address, unsigned long mmcsr,
/* We ran out of memory, or some other thing happened to us that
made us unable to handle the page fault gracefully. */
out_of_memory:
- if (current->pid == 1) {
+ if (is_init(current)) {
yield();
down_read(&mm->mmap_sem);
goto survive;
diff --git a/arch/alpha/mm/remap.c b/arch/alpha/mm/remap.c
deleted file mode 100644
index a78356c3ead5..000000000000
--- a/arch/alpha/mm/remap.c
+++ /dev/null
@@ -1,86 +0,0 @@
-#include <linux/vmalloc.h>
-#include <asm/pgalloc.h>
-#include <asm/cacheflush.h>
-
-static inline void
-remap_area_pte(pte_t * pte, unsigned long address, unsigned long size,
- unsigned long phys_addr, unsigned long flags)
-{
- unsigned long end;
- unsigned long pfn;
-
- address &= ~PMD_MASK;
- end = address + size;
- if (end > PMD_SIZE)
- end = PMD_SIZE;
- if (address >= end)
- BUG();
- pfn = phys_addr >> PAGE_SHIFT;
- do {
- if (!pte_none(*pte)) {
- printk("remap_area_pte: page already exists\n");
- BUG();
- }
- set_pte(pte, pfn_pte(pfn,
- __pgprot(_PAGE_VALID | _PAGE_ASM |
- _PAGE_KRE | _PAGE_KWE | flags)));
- address += PAGE_SIZE;
- pfn++;
- pte++;
- } while (address && (address < end));
-}
-
-static inline int
-remap_area_pmd(pmd_t * pmd, unsigned long address, unsigned long size,
- unsigned long phys_addr, unsigned long flags)
-{
- unsigned long end;
-
- address &= ~PGDIR_MASK;
- end = address + size;
- if (end > PGDIR_SIZE)
- end = PGDIR_SIZE;
- phys_addr -= address;
- if (address >= end)
- BUG();
- do {
- pte_t * pte = pte_alloc_kernel(pmd, address);
- if (!pte)
- return -ENOMEM;
- remap_area_pte(pte, address, end - address,
- address + phys_addr, flags);
- address = (address + PMD_SIZE) & PMD_MASK;
- pmd++;
- } while (address && (address < end));
- return 0;
-}
-
-int
-__alpha_remap_area_pages(unsigned long address, unsigned long phys_addr,
- unsigned long size, unsigned long flags)
-{
- pgd_t * dir;
- int error = 0;
- unsigned long end = address + size;
-
- phys_addr -= address;
- dir = pgd_offset(&init_mm, address);
- flush_cache_all();
- if (address >= end)
- BUG();
- do {
- pmd_t *pmd;
- pmd = pmd_alloc(&init_mm, dir, address);
- error = -ENOMEM;
- if (!pmd)
- break;
- if (remap_area_pmd(pmd, address, end - address,
- phys_addr + address, flags))
- break;
- error = 0;
- address = (address + PGDIR_SIZE) & PGDIR_MASK;
- dir++;
- } while (address && (address < end));
- return error;
-}
-
diff --git a/arch/arm/kernel/ecard.c b/arch/arm/kernel/ecard.c
index eca248d9eba4..3e14b1348c0b 100644
--- a/arch/arm/kernel/ecard.c
+++ b/arch/arm/kernel/ecard.c
@@ -295,7 +295,7 @@ ecard_task(void * unused)
*/
static void ecard_call(struct ecard_request *req)
{
- DECLARE_COMPLETION(completion);
+ DECLARE_COMPLETION_ONSTACK(completion);
req->complete = &completion;
diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c
index 0a722e77c143..6bbd93dd186a 100644
--- a/arch/arm/kernel/setup.c
+++ b/arch/arm/kernel/setup.c
@@ -348,7 +348,7 @@ static void __init setup_processor(void)
cpu_name, processor_id, (int)processor_id & 15,
proc_arch[cpu_architecture()], cr_alignment);
- sprintf(system_utsname.machine, "%s%c", list->arch_name, ENDIANNESS);
+ sprintf(init_utsname()->machine, "%s%c", list->arch_name, ENDIANNESS);
sprintf(elf_platform, "%s%c", list->elf_name, ENDIANNESS);
elf_hwcap = list->elf_hwcap;
#ifndef CONFIG_ARM_THUMB
diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c
index 68e9634d260a..421329f5e18e 100644
--- a/arch/arm/kernel/smp.c
+++ b/arch/arm/kernel/smp.c
@@ -36,7 +36,9 @@
* The online bitmask indicates that the CPU is up and running.
*/
cpumask_t cpu_possible_map;
+EXPORT_SYMBOL(cpu_possible_map);
cpumask_t cpu_online_map;
+EXPORT_SYMBOL(cpu_online_map);
/*
* as from 2.5, kernels no longer have an init_tasks structure
diff --git a/arch/arm/kernel/sys_arm.c b/arch/arm/kernel/sys_arm.c
index 8170af471439..00c18d35913c 100644
--- a/arch/arm/kernel/sys_arm.c
+++ b/arch/arm/kernel/sys_arm.c
@@ -279,7 +279,7 @@ out:
return error;
}
-long execve(const char *filename, char **argv, char **envp)
+int kernel_execve(const char *filename, char *const argv[], char *const envp[])
{
struct pt_regs regs;
int ret;
@@ -317,7 +317,7 @@ long execve(const char *filename, char **argv, char **envp)
out:
return ret;
}
-EXPORT_SYMBOL(execve);
+EXPORT_SYMBOL(kernel_execve);
/*
* Since loff_t is a 64 bit type we avoid a lot of ABI hastle
diff --git a/arch/arm/kernel/time.c b/arch/arm/kernel/time.c
index d4dceb5f06e9..b030320b17c7 100644
--- a/arch/arm/kernel/time.c
+++ b/arch/arm/kernel/time.c
@@ -37,8 +37,6 @@
*/
struct sys_timer *system_timer;
-extern unsigned long wall_jiffies;
-
/* this needs a better home */
DEFINE_SPINLOCK(rtc_lock);
@@ -237,16 +235,11 @@ void do_gettimeofday(struct timeval *tv)
{
unsigned long flags;
unsigned long seq;
- unsigned long usec, sec, lost;
+ unsigned long usec, sec;
do {
seq = read_seqbegin_irqsave(&xtime_lock, flags);
usec = system_timer->offset();
-
- lost = jiffies - wall_jiffies;
- if (lost)
- usec += lost * USECS_PER_JIFFY;
-
sec = xtime.tv_sec;
usec += xtime.tv_nsec / 1000;
} while (read_seqretry_irqrestore(&xtime_lock, seq, flags));
@@ -279,7 +272,6 @@ int do_settimeofday(struct timespec *tv)
* done, and then undo it!
*/
nsec -= system_timer->offset() * NSEC_PER_USEC;
- nsec -= (jiffies - wall_jiffies) * TICK_NSEC;
wtm_sec = wall_to_monotonic.tv_sec + (xtime.tv_sec - sec);
wtm_nsec = wall_to_monotonic.tv_nsec + (xtime.tv_nsec - nsec);
@@ -337,7 +329,7 @@ void timer_tick(struct pt_regs *regs)
profile_tick(CPU_PROFILING, regs);
do_leds();
do_set_rtc();
- do_timer(regs);
+ do_timer(1);
#ifndef CONFIG_SMP
update_process_times(user_mode(regs));
#endif
diff --git a/arch/arm/mach-omap1/board-fsample.c b/arch/arm/mach-omap1/board-fsample.c
index c753a3c5aadd..62e42c7a628e 100644
--- a/arch/arm/mach-omap1/board-fsample.c
+++ b/arch/arm/mach-omap1/board-fsample.c
@@ -172,9 +172,11 @@ static struct resource kp_resources[] = {
};
static struct omap_kp_platform_data kp_data = {
- .rows = 8,
- .cols = 8,
- .keymap = fsample_keymap,
+ .rows = 8,
+ .cols = 8,
+ .keymap = fsample_keymap,
+ .keymapsize = ARRAY_SIZE(fsample_keymap),
+ .delay = 4,
};
static struct platform_device kp_device = {
diff --git a/arch/arm/mach-omap1/board-h2.c b/arch/arm/mach-omap1/board-h2.c
index cd3a06dfc0a8..6e113078f7ab 100644
--- a/arch/arm/mach-omap1/board-h2.c
+++ b/arch/arm/mach-omap1/board-h2.c
@@ -167,10 +167,13 @@ static struct resource h2_kp_resources[] = {
};
static struct omap_kp_platform_data h2_kp_data = {
- .rows = 8,
- .cols = 8,
- .keymap = h2_keymap,
- .rep = 1,
+ .rows = 8,
+ .cols = 8,
+ .keymap = h2_keymap,
+ .keymapsize = ARRAY_SIZE(h2_keymap),
+ .rep = 1,
+ .delay = 9,
+ .dbounce = 1,
};
static struct platform_device h2_kp_device = {
diff --git a/arch/arm/mach-omap1/board-h3.c b/arch/arm/mach-omap1/board-h3.c
index 7b206116cd03..f225a083dee1 100644
--- a/arch/arm/mach-omap1/board-h3.c
+++ b/arch/arm/mach-omap1/board-h3.c
@@ -247,10 +247,13 @@ static struct resource h3_kp_resources[] = {
};
static struct omap_kp_platform_data h3_kp_data = {
- .rows = 8,
- .cols = 8,
- .keymap = h3_keymap,
- .rep = 1,
+ .rows = 8,
+ .cols = 8,
+ .keymap = h3_keymap,
+ .keymapsize = ARRAY_SIZE(h3_keymap),
+ .rep = 1,
+ .delay = 9,
+ .dbounce = 1,
};
static struct platform_device h3_kp_device = {
diff --git a/arch/arm/mach-omap1/board-innovator.c b/arch/arm/mach-omap1/board-innovator.c
index 4cbc62db5b5d..cb00530ad279 100644
--- a/arch/arm/mach-omap1/board-innovator.c
+++ b/arch/arm/mach-omap1/board-innovator.c
@@ -159,9 +159,11 @@ static struct resource innovator_kp_resources[] = {
};
static struct omap_kp_platform_data innovator_kp_data = {
- .rows = 8,
- .cols = 8,
- .keymap = innovator_keymap,
+ .rows = 8,
+ .cols = 8,
+ .keymap = innovator_keymap,
+ .keymapsize = ARRAY_SIZE(innovator_keymap),
+ .delay = 4,
};
static struct platform_device innovator_kp_device = {
diff --git a/arch/arm/mach-omap1/board-nokia770.c b/arch/arm/mach-omap1/board-nokia770.c
index 02b980d77b12..dbc555d209ff 100644
--- a/arch/arm/mach-omap1/board-nokia770.c
+++ b/arch/arm/mach-omap1/board-nokia770.c
@@ -71,9 +71,11 @@ static struct resource nokia770_kp_resources[] = {
};
static struct omap_kp_platform_data nokia770_kp_data = {
- .rows = 8,
- .cols = 8,
- .keymap = nokia770_keymap
+ .rows = 8,
+ .cols = 8,
+ .keymap = nokia770_keymap,
+ .keymapsize = ARRAY_SIZE(nokia770_keymap)
+ .delay = 4,
};
static struct platform_device nokia770_kp_device = {
diff --git a/arch/arm/mach-omap1/board-osk.c b/arch/arm/mach-omap1/board-osk.c
index b742261c97ad..6b05647a6c01 100644
--- a/arch/arm/mach-omap1/board-osk.c
+++ b/arch/arm/mach-omap1/board-osk.c
@@ -266,9 +266,11 @@ static const int osk_keymap[] = {
};
static struct omap_kp_platform_data osk_kp_data = {
- .rows = 8,
- .cols = 8,
- .keymap = (int *) osk_keymap,
+ .rows = 8,
+ .cols = 8,
+ .keymap = (int *) osk_keymap,
+ .keymapsize = ARRAY_SIZE(osk_keymap),
+ .delay = 9,
};
static struct resource osk5912_kp_resources[] = {
diff --git a/arch/arm/mach-omap1/board-perseus2.c b/arch/arm/mach-omap1/board-perseus2.c
index 64b45d8ae357..fa4be962df67 100644
--- a/arch/arm/mach-omap1/board-perseus2.c
+++ b/arch/arm/mach-omap1/board-perseus2.c
@@ -171,9 +171,12 @@ static struct resource kp_resources[] = {
};
static struct omap_kp_platform_data kp_data = {
- .rows = 8,
- .cols = 8,
- .keymap = p2_keymap,
+ .rows = 8,
+ .cols = 8,
+ .keymap = p2_keymap,
+ .keymapsize = ARRAY_SIZE(p2_keymap),
+ .delay = 4,
+ .dbounce = 1,
};
static struct platform_device kp_device = {
diff --git a/arch/arm/mach-omap2/board-h4.c b/arch/arm/mach-omap2/board-h4.c
index 4933fce766c8..996aeda1285d 100644
--- a/arch/arm/mach-omap2/board-h4.c
+++ b/arch/arm/mach-omap2/board-h4.c
@@ -245,6 +245,7 @@ static struct omap_kp_platform_data h4_kp_data = {
.rows = 6,
.cols = 7,
.keymap = h4_keymap,
+ .keymapsize = ARRAY_SIZE(h4_keymap),
.rep = 1,
.row_gpios = row_gpios,
.col_gpios = col_gpios,
diff --git a/arch/arm/mach-pnx4008/clock.c b/arch/arm/mach-pnx4008/clock.c
index f582ed2ec43c..daa8d3d98eff 100644
--- a/arch/arm/mach-pnx4008/clock.c
+++ b/arch/arm/mach-pnx4008/clock.c
@@ -735,6 +735,16 @@ static struct clk uart6_ck = {
.enable_reg = UARTCLKCTRL_REG,
};
+static struct clk wdt_ck = {
+ .name = "wdt_ck",
+ .parent = &per_ck,
+ .flags = NEEDS_INITIALIZATION,
+ .round_rate = &on_off_round_rate,
+ .set_rate = &on_off_set_rate,
+ .enable_shift = 0,
+ .enable_reg = TIMCLKCTRL_REG,
+};
+
/* These clocks are visible outside this module
* and can be initialized
*/
@@ -765,6 +775,7 @@ static struct clk *onchip_clks[] = {
&uart4_ck,
&uart5_ck,
&uart6_ck,
+ &wdt_ck,
};
static int local_clk_enable(struct clk *clk)
diff --git a/arch/arm/mm/fault.c b/arch/arm/mm/fault.c
index f0943d160ffe..5e658a874498 100644
--- a/arch/arm/mm/fault.c
+++ b/arch/arm/mm/fault.c
@@ -171,7 +171,7 @@ good_area:
if (fsr & (1 << 11)) /* write? */
mask = VM_WRITE;
else
- mask = VM_READ|VM_EXEC;
+ mask = VM_READ|VM_EXEC|VM_WRITE;
fault = VM_FAULT_BADACCESS;
if (!(vma->vm_flags & mask))
@@ -198,7 +198,7 @@ survive:
return fault;
}
- if (tsk->pid != 1)
+ if (!is_init(tsk))
goto out;
/*
diff --git a/arch/arm/vfp/vfpsingle.c b/arch/arm/vfp/vfpsingle.c
index ab5e9503bae5..0221ba3bc799 100644
--- a/arch/arm/vfp/vfpsingle.c
+++ b/arch/arm/vfp/vfpsingle.c
@@ -198,8 +198,10 @@ u32 vfp_single_normaliseround(int sd, struct vfp_single *vs, u32 fpscr, u32 exce
vfp_single_dump("pack: final", vs);
{
s32 d = vfp_single_pack(vs);
+#ifdef DEBUG
pr_debug("VFP: %s: d(s%d)=%08x exceptions=%08x\n", func,
sd, d, exceptions);
+#endif
vfp_put_float(d, sd);
}
diff --git a/arch/arm26/kernel/setup.c b/arch/arm26/kernel/setup.c
index e7eb070f794f..466ddb54b44f 100644
--- a/arch/arm26/kernel/setup.c
+++ b/arch/arm26/kernel/setup.c
@@ -143,7 +143,7 @@ static void __init setup_processor(void)
dump_cpu_info();
- sprintf(system_utsname.machine, "%s", list->arch_name);
+ sprintf(init_utsname()->machine, "%s", list->arch_name);
sprintf(elf_platform, "%s", list->elf_name);
elf_hwcap = list->elf_hwcap;
diff --git a/arch/arm26/kernel/sys_arm.c b/arch/arm26/kernel/sys_arm.c
index 85457897b8a9..dc05aba58baf 100644
--- a/arch/arm26/kernel/sys_arm.c
+++ b/arch/arm26/kernel/sys_arm.c
@@ -283,7 +283,7 @@ out:
}
/* FIXME - see if this is correct for arm26 */
-long execve(const char *filename, char **argv, char **envp)
+int kernel_execve(const char *filename, char *const argv[], char *const envp[])
{
struct pt_regs regs;
int ret;
@@ -320,4 +320,4 @@ long execve(const char *filename, char **argv, char **envp)
return ret;
}
-EXPORT_SYMBOL(execve);
+EXPORT_SYMBOL(kernel_execve);
diff --git a/arch/arm26/kernel/time.c b/arch/arm26/kernel/time.c
index db63d75d0715..1206469b2b86 100644
--- a/arch/arm26/kernel/time.c
+++ b/arch/arm26/kernel/time.c
@@ -33,8 +33,6 @@
#include <asm/irq.h>
#include <asm/ioc.h>
-extern unsigned long wall_jiffies;
-
/* this needs a better home */
DEFINE_SPINLOCK(rtc_lock);
@@ -136,16 +134,11 @@ void do_gettimeofday(struct timeval *tv)
{
unsigned long flags;
unsigned long seq;
- unsigned long usec, sec, lost;
+ unsigned long usec, sec;
do {
seq = read_seqbegin_irqsave(&xtime_lock, flags);
usec = gettimeoffset();
-
- lost = jiffies - wall_jiffies;
- if (lost)
- usec += lost * USECS_PER_JIFFY;
-
sec = xtime.tv_sec;
usec += xtime.tv_nsec / 1000;
} while (read_seqretry_irqrestore(&xtime_lock, seq, flags));
@@ -174,8 +167,7 @@ int do_settimeofday(struct timespec *tv)
* wall time. Discover what correction gettimeofday() would have
* done, and then undo it!
*/
- tv->tv_nsec -= 1000 * (gettimeoffset() +
- (jiffies - wall_jiffies) * USECS_PER_JIFFY);
+ tv->tv_nsec -= 1000 * gettimeoffset();
while (tv->tv_nsec < 0) {
tv->tv_nsec += NSEC_PER_SEC;
@@ -194,7 +186,7 @@ EXPORT_SYMBOL(do_settimeofday);
static irqreturn_t timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
- do_timer(regs);
+ do_timer(1);
#ifndef CONFIG_SMP
update_process_times(user_mode(regs));
#endif
diff --git a/arch/arm26/mm/fault.c b/arch/arm26/mm/fault.c
index 761938b56679..a1f6d8a9cc32 100644
--- a/arch/arm26/mm/fault.c
+++ b/arch/arm26/mm/fault.c
@@ -155,7 +155,7 @@ __do_page_fault(struct mm_struct *mm, unsigned long addr, unsigned int fsr,
*/
good_area:
if (READ_FAULT(fsr)) /* read? */
- mask = VM_READ|VM_EXEC;
+ mask = VM_READ|VM_EXEC|VM_WRITE;
else
mask = VM_WRITE;
@@ -185,7 +185,7 @@ survive:
}
fault = -3; /* out of memory */
- if (tsk->pid != 1)
+ if (!is_init(tsk))
goto out;
/*
diff --git a/arch/avr32/kernel/sys_avr32.c b/arch/avr32/kernel/sys_avr32.c
index 6ec5693da448..8deb6003ee62 100644
--- a/arch/avr32/kernel/sys_avr32.c
+++ b/arch/avr32/kernel/sys_avr32.c
@@ -49,3 +49,17 @@ asmlinkage long sys_mmap2(unsigned long addr, unsigned long len,
fput(file);
return error;
}
+
+int kernel_execve(const char *file, char **argv, char **envp)
+{
+ register long scno asm("r8") = __NR_execve;
+ register long sc1 asm("r12") = (long)file;
+ register long sc2 asm("r11") = (long)argv;
+ register long sc3 asm("r10") = (long)envp;
+
+ asm volatile("scall"
+ : "=r"(sc1)
+ : "r"(scno), "0"(sc1), "r"(sc2), "r"(sc3)
+ : "cc", "memory");
+ return sc1;
+}
diff --git a/arch/avr32/kernel/time.c b/arch/avr32/kernel/time.c
index b0e6b5855a38..3e56b9f4358a 100644
--- a/arch/avr32/kernel/time.c
+++ b/arch/avr32/kernel/time.c
@@ -148,7 +148,7 @@ timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
* Call the generic timer interrupt handler
*/
write_seqlock(&xtime_lock);
- do_timer(regs);
+ do_timer(1);
write_sequnlock(&xtime_lock);
/*
diff --git a/arch/avr32/mm/ioremap.c b/arch/avr32/mm/ioremap.c
index 536021877df6..8cfec65e37f7 100644
--- a/arch/avr32/mm/ioremap.c
+++ b/arch/avr32/mm/ioremap.c
@@ -7,119 +7,11 @@
*/
#include <linux/vmalloc.h>
#include <linux/module.h>
+#include <linux/io.h>
-#include <asm/io.h>
#include <asm/pgtable.h>
-#include <asm/cacheflush.h>
-#include <asm/tlbflush.h>
#include <asm/addrspace.h>
-static inline int remap_area_pte(pte_t *pte, unsigned long address,
- unsigned long end, unsigned long phys_addr,
- pgprot_t prot)
-{
- unsigned long pfn;
-
- pfn = phys_addr >> PAGE_SHIFT;
- do {
- WARN_ON(!pte_none(*pte));
-
- set_pte(pte, pfn_pte(pfn, prot));
- address += PAGE_SIZE;
- pfn++;
- pte++;
- } while (address && (address < end));
-
- return 0;
-}
-
-static inline int remap_area_pmd(pmd_t *pmd, unsigned long address,
- unsigned long end, unsigned long phys_addr,
- pgprot_t prot)
-{
- unsigned long next;
-
- phys_addr -= address;
-
- do {
- pte_t *pte = pte_alloc_kernel(pmd, address);
- if (!pte)
- return -ENOMEM;
-
- next = (address + PMD_SIZE) & PMD_MASK;
- if (remap_area_pte(pte, address, next,
- address + phys_addr, prot))
- return -ENOMEM;
-
- address = next;
- pmd++;
- } while (address && (address < end));
- return 0;
-}
-
-static int remap_area_pud(pud_t *pud, unsigned long address,
- unsigned long end, unsigned long phys_addr,
- pgprot_t prot)
-{
- unsigned long next;
-
- phys_addr -= address;
-
- do {
- pmd_t *pmd = pmd_alloc(&init_mm, pud, address);
- if (!pmd)
- return -ENOMEM;
- next = (address + PUD_SIZE) & PUD_MASK;
- if (remap_area_pmd(pmd, address, next,
- phys_addr + address, prot))
- return -ENOMEM;
-
- address = next;
- pud++;
- } while (address && address < end);
-
- return 0;
-}
-
-static int remap_area_pages(unsigned long address, unsigned long phys_addr,
- size_t size, pgprot_t prot)
-{
- unsigned long end = address + size;
- unsigned long next;
- pgd_t *pgd;
- int err = 0;
-
- phys_addr -= address;
-
- pgd = pgd_offset_k(address);
- flush_cache_all();
- BUG_ON(address >= end);
-
- spin_lock(&init_mm.page_table_lock);
- do {
- pud_t *pud = pud_alloc(&init_mm, pgd, address);
-
- err = -ENOMEM;
- if (!pud)
- break;
-
- next = (address + PGDIR_SIZE) & PGDIR_MASK;
- if (next < address || next > end)
- next = end;
- err = remap_area_pud(pud, address, next,
- phys_addr + address, prot);
- if (err)
- break;
-
- address = next;
- pgd++;
- } while (address && (address < end));
-
- spin_unlock(&init_mm.page_table_lock);
- flush_tlb_all();
- return err;
-}
-
/*
* Re-map an arbitrary physical address space into the kernel virtual
* address space. Needed when the kernel wants to access physical
@@ -128,7 +20,7 @@ static int remap_area_pages(unsigned long address, unsigned long phys_addr,
void __iomem *__ioremap(unsigned long phys_addr, size_t size,
unsigned long flags)
{
- void *addr;
+ unsigned long addr;
struct vm_struct *area;
unsigned long offset, last_addr;
pgprot_t prot;
@@ -159,7 +51,7 @@ void __iomem *__ioremap(unsigned long phys_addr, size_t size,
phys_addr &= PAGE_MASK;
size = PAGE_ALIGN(last_addr + 1) - phys_addr;
- prot = __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY
+ prot = __pgprot(_PAGE_PRESENT | _PAGE_GLOBAL | _PAGE_RW | _PAGE_DIRTY
| _PAGE_ACCESSED | _PAGE_TYPE_SMALL | flags);
/*
@@ -169,9 +61,9 @@ void __iomem *__ioremap(unsigned long phys_addr, size_t size,
if (!area)
return NULL;
area->phys_addr = phys_addr;
- addr = area->addr;
- if (remap_area_pages((unsigned long)addr, phys_addr, size, prot)) {
- vunmap(addr);
+ addr = (unsigned long )area->addr;
+ if (ioremap_page_range(addr, addr + size, phys_addr, prot)) {
+ vunmap((void *)addr);
return NULL;
}
diff --git a/arch/cris/arch-v10/kernel/time.c b/arch/cris/arch-v10/kernel/time.c
index 9c22b76e129a..ebacf1457d91 100644
--- a/arch/cris/arch-v10/kernel/time.c
+++ b/arch/cris/arch-v10/kernel/time.c
@@ -227,7 +227,7 @@ timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
/* call the real timer interrupt handler */
- do_timer(regs);
+ do_timer(1);
cris_do_profile(regs); /* Save profiling information */
diff --git a/arch/cris/arch-v32/kernel/smp.c b/arch/cris/arch-v32/kernel/smp.c
index 464ecaec3bc0..2d0023f2d49b 100644
--- a/arch/cris/arch-v32/kernel/smp.c
+++ b/arch/cris/arch-v32/kernel/smp.c
@@ -28,6 +28,7 @@ spinlock_t cris_atomic_locks[] = { [0 ... LOCK_COUNT - 1] = SPIN_LOCK_UNLOCKED};
/* CPU masks */
cpumask_t cpu_online_map = CPU_MASK_NONE;
+EXPORT_SYMBOL(cpu_online_map);
cpumask_t phys_cpu_present_map = CPU_MASK_NONE;
EXPORT_SYMBOL(phys_cpu_present_map);
diff --git a/arch/cris/arch-v32/kernel/time.c b/arch/cris/arch-v32/kernel/time.c
index 50f3f93293d6..be0a01657d4f 100644
--- a/arch/cris/arch-v32/kernel/time.c
+++ b/arch/cris/arch-v32/kernel/time.c
@@ -219,7 +219,7 @@ timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
return IRQ_HANDLED;
/* call the real timer interrupt handler */
- do_timer(regs);
+ do_timer(1);
/*
* If we have an externally synchronized Linux clock, then update
diff --git a/arch/cris/kernel/setup.c b/arch/cris/kernel/setup.c
index 7af3d5d43e43..ca8b45a0fe2e 100644
--- a/arch/cris/kernel/setup.c
+++ b/arch/cris/kernel/setup.c
@@ -160,7 +160,7 @@ setup_arch(char **cmdline_p)
show_etrax_copyright();
/* Setup utsname */
- strcpy(system_utsname.machine, cris_machine_name);
+ strcpy(init_utsname()->machine, cris_machine_name);
}
static void *c_start(struct seq_file *m, loff_t *pos)
diff --git a/arch/cris/kernel/time.c b/arch/cris/kernel/time.c
index 66ba8898db07..0f9213cbd48e 100644
--- a/arch/cris/kernel/time.c
+++ b/arch/cris/kernel/time.c
@@ -37,7 +37,6 @@ int have_rtc; /* used to remember if we have an RTC or not */;
#define TICK_SIZE tick
-extern unsigned long wall_jiffies;
extern unsigned long loops_per_jiffy; /* init/main.c */
unsigned long loops_per_usec;
@@ -58,11 +57,6 @@ void do_gettimeofday(struct timeval *tv)
local_irq_save(flags);
local_irq_disable();
usec = do_gettimeoffset();
- {
- unsigned long lost = jiffies - wall_jiffies;
- if (lost)
- usec += lost * (1000000 / HZ);
- }
/*
* If time_adjust is negative then NTP is slowing the clock
@@ -103,7 +97,6 @@ int do_settimeofday(struct timespec *tv)
* made, and then undo it!
*/
nsec -= do_gettimeoffset() * NSEC_PER_USEC;
- nsec -= (jiffies - wall_jiffies) * TICK_NSEC;
wtm_sec = wall_to_monotonic.tv_sec + (xtime.tv_sec - sec);
wtm_nsec = wall_to_monotonic.tv_nsec + (xtime.tv_nsec - nsec);
diff --git a/arch/cris/mm/ioremap.c b/arch/cris/mm/ioremap.c
index 1780df3ed9e5..8b0b9348b574 100644
--- a/arch/cris/mm/ioremap.c
+++ b/arch/cris/mm/ioremap.c
@@ -10,93 +10,10 @@
*/
#include <linux/vmalloc.h>
-#include <asm/io.h>
+#include <linux/io.h>
#include <asm/pgalloc.h>
-#include <asm/cacheflush.h>
-#include <asm/tlbflush.h>
#include <asm/arch/memmap.h>
-static inline void remap_area_pte(pte_t * pte, unsigned long address, unsigned long size,
- unsigned long phys_addr, pgprot_t prot)
-{
- unsigned long end;
-
- address &= ~PMD_MASK;
- end = address + size;
- if (end > PMD_SIZE)
- end = PMD_SIZE;
- if (address >= end)
- BUG();
- do {
- if (!pte_none(*pte)) {
- printk("remap_area_pte: page already exists\n");
- BUG();
- }
- set_pte(pte, mk_pte_phys(phys_addr, prot));
- address += PAGE_SIZE;
- phys_addr += PAGE_SIZE;
- pte++;
- } while (address && (address < end));
-}
-
-static inline int remap_area_pmd(pmd_t * pmd, unsigned long address, unsigned long size,
- unsigned long phys_addr, pgprot_t prot)
-{
- unsigned long end;
-
- address &= ~PGDIR_MASK;
- end = address + size;
- if (end > PGDIR_SIZE)
- end = PGDIR_SIZE;
- phys_addr -= address;
- if (address >= end)
- BUG();
- do {
- pte_t * pte = pte_alloc_kernel(pmd, address);
- if (!pte)
- return -ENOMEM;
- remap_area_pte(pte, address, end - address, address + phys_addr, prot);
- address = (address + PMD_SIZE) & PMD_MASK;
- pmd++;
- } while (address && (address < end));
- return 0;
-}
-
-static int remap_area_pages(unsigned long address, unsigned long phys_addr,
- unsigned long size, pgprot_t prot)
-{
- int error;
- pgd_t * dir;
- unsigned long end = address + size;
-
- phys_addr -= address;
- dir = pgd_offset(&init_mm, address);
- flush_cache_all();
- if (address >= end)
- BUG();
- do {
- pud_t *pud;
- pmd_t *pmd;
-
- error = -ENOMEM;
- pud = pud_alloc(&init_mm, dir, address);
- if (!pud)
- break;
- pmd = pmd_alloc(&init_mm, pud, address);
-
- if (!pmd)
- break;
- if (remap_area_pmd(pmd, address, end - address,
- phys_addr + address, prot))
- break;
- error = 0;
- address = (address + PGDIR_SIZE) & PGDIR_MASK;
- dir++;
- } while (address && (address < end));
- flush_tlb_all();
- return error;
-}
-
/*
* Generic mapping function (not visible outside):
*/
@@ -135,7 +52,8 @@ void __iomem * __ioremap_prot(unsigned long phys_addr, unsigned long size, pgpro
if (!area)
return NULL;
addr = (void __iomem *)area->addr;
- if (remap_area_pages((unsigned long) addr, phys_addr, size, prot)) {
+ if (ioremap_page_range((unsigned long)addr, (unsigned long)addr + size,
+ phys_addr, prot)) {
vfree((void __force *)addr);
return NULL;
}
diff --git a/arch/frv/Kconfig b/arch/frv/Kconfig
index f7b171b92ea2..cf1c446e003a 100644
--- a/arch/frv/Kconfig
+++ b/arch/frv/Kconfig
@@ -86,6 +86,14 @@ config HIGHPTE
with a lot of RAM, this can be wasteful of precious low memory.
Setting this option will put user-space page tables in high memory.
+config LARGE_ALLOCS
+ bool "Allow allocating large blocks (> 1MB) of memory"
+ help
+ Allow the slab memory allocator to keep chains for very large memory
+ sizes - up to 32MB. You may need this if your system has a lot of
+ RAM, and you need to able to allocate very large contiguous chunks.
+ If unsure, say N.
+
source "mm/Kconfig"
choice
diff --git a/arch/frv/kernel/Makefile b/arch/frv/kernel/Makefile
index 32db3499c461..e8f73ed28b52 100644
--- a/arch/frv/kernel/Makefile
+++ b/arch/frv/kernel/Makefile
@@ -8,7 +8,7 @@ heads-$(CONFIG_MMU) := head-mmu-fr451.o
extra-y:= head.o init_task.o vmlinux.lds
obj-y := $(heads-y) entry.o entry-table.o break.o switch_to.o kernel_thread.o \
- process.o traps.o ptrace.o signal.o dma.o \
+ kernel_execve.o process.o traps.o ptrace.o signal.o dma.o \
sys_frv.o time.o semaphore.o setup.o frv_ksyms.o \
debug-stub.o irq.o sleep.o uaccess.o
diff --git a/arch/frv/kernel/kernel_execve.S b/arch/frv/kernel/kernel_execve.S
new file mode 100644
index 000000000000..9b074a16a052
--- /dev/null
+++ b/arch/frv/kernel/kernel_execve.S
@@ -0,0 +1,33 @@
+/* in-kernel program execution
+ *
+ * Copyright (C) 2006 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * 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 <linux/linkage.h>
+#include <asm/unistd.h>
+
+###############################################################################
+#
+# Do a system call from kernel instead of calling sys_execve so we end up with
+# proper pt_regs.
+#
+# int kernel_execve(const char *filename, char *const argv[], char *const envp[])
+#
+# On entry: GR8/GR9/GR10: arguments to function
+# On return: GR8: syscall return.
+#
+###############################################################################
+ .globl kernel_execve
+ .type kernel_execve,@function
+kernel_execve:
+ setlos __NR_execve,gr7
+ tira gr0,#0
+ bralr
+
+ .size kernel_execve,.-kernel_execve
diff --git a/arch/frv/kernel/setup.c b/arch/frv/kernel/setup.c
index d96a57e5f030..a8c61dac1cee 100644
--- a/arch/frv/kernel/setup.c
+++ b/arch/frv/kernel/setup.c
@@ -31,7 +31,6 @@
#include <linux/serial_reg.h>
#include <asm/setup.h>
-#include <asm/serial.h>
#include <asm/irq.h>
#include <asm/sections.h>
#include <asm/pgalloc.h>
diff --git a/arch/frv/kernel/time.c b/arch/frv/kernel/time.c
index 3d0284bccb94..7e55884135ed 100644
--- a/arch/frv/kernel/time.c
+++ b/arch/frv/kernel/time.c
@@ -70,7 +70,7 @@ static irqreturn_t timer_interrupt(int irq, void *dummy, struct pt_regs * regs)
*/
write_seqlock(&xtime_lock);
- do_timer(regs);
+ do_timer(1);
update_process_times(user_mode(regs));
profile_tick(CPU_PROFILING, regs);
diff --git a/arch/h8300/kernel/sys_h8300.c b/arch/h8300/kernel/sys_h8300.c
index 0f61b7ad69ab..302a2dfe634a 100644
--- a/arch/h8300/kernel/sys_h8300.c
+++ b/arch/h8300/kernel/sys_h8300.c
@@ -25,6 +25,7 @@
#include <asm/cachectl.h>
#include <asm/traps.h>
#include <asm/ipc.h>
+#include <asm/unistd.h>
/*
* sys_pipe() is the normal C calling standard for creating
@@ -280,3 +281,26 @@ asmlinkage void syscall_print(void *dummy,...)
((regs->pc)&0xffffff)-2,regs->orig_er0,regs->er1,regs->er2,regs->er3,regs->er0);
}
#endif
+
+/*
+ * Do a system call from kernel instead of calling sys_execve so we
+ * end up with proper pt_regs.
+ */
+int kernel_execve(const char *filename, char *const argv[], char *const envp[])
+{
+ register long res __asm__("er0");
+ register const char * _a __asm__("er1") = filename;
+ register void *_b __asm__("er2") = argv;
+ register void *_c __asm__("er3") = envp;
+ __asm__ __volatile__ ("mov.l %1,er0\n\t"
+ "trapa #0\n\t"
+ : "=r" (res)
+ : "g" (__NR_execve),
+ "g" (_a),
+ "g" (_b),
+ "g" (_c)
+ : "cc", "memory");
+ return res;
+}
+
+
diff --git a/arch/h8300/kernel/time.c b/arch/h8300/kernel/time.c
index 688a5100604c..e569d17b4ae6 100644
--- a/arch/h8300/kernel/time.c
+++ b/arch/h8300/kernel/time.c
@@ -41,7 +41,7 @@ static void timer_interrupt(int irq, void *dummy, struct pt_regs * regs)
/* may need to kick the hardware timer */
platform_timer_eoi();
- do_timer(regs);
+ do_timer(1);
#ifndef CONFIG_SMP
update_process_times(user_mode(regs));
#endif
diff --git a/arch/i386/Kconfig b/arch/i386/Kconfig
index 3fd2f256f2be..af219e51734f 100644
--- a/arch/i386/Kconfig
+++ b/arch/i386/Kconfig
@@ -1142,7 +1142,7 @@ source "arch/i386/oprofile/Kconfig"
config KPROBES
bool "Kprobes (EXPERIMENTAL)"
- depends on EXPERIMENTAL && MODULES
+ depends on KALLSYMS && EXPERIMENTAL && MODULES
help
Kprobes allows you to trap at almost any kernel address and
execute a callback function. register_kprobe() establishes
diff --git a/arch/i386/boot/video.S b/arch/i386/boot/video.S
index 8c2a6faeeae5..2c5b5cc55f79 100644
--- a/arch/i386/boot/video.S
+++ b/arch/i386/boot/video.S
@@ -11,8 +11,6 @@
*
*/
-#include <linux/config.h> /* for CONFIG_VIDEO_* */
-
/* Enable autodetection of SVGA adapters and modes. */
#undef CONFIG_VIDEO_SVGA
diff --git a/arch/i386/defconfig b/arch/i386/defconfig
index 1a29bfa26d0c..ee2d79bd8af7 100644
--- a/arch/i386/defconfig
+++ b/arch/i386/defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.18-git5
-# Tue Sep 26 09:30:47 2006
+# Linux kernel version: 2.6.18-git7
+# Wed Sep 27 21:53:10 2006
#
CONFIG_X86_32=y
CONFIG_GENERIC_TIME=y
@@ -210,6 +210,7 @@ CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
CONFIG_PM=y
CONFIG_PM_LEGACY=y
# CONFIG_PM_DEBUG is not set
+CONFIG_PM_SYSFS_DEPRECATED=y
#
# ACPI (Advanced Configuration and Power Interface) Support
@@ -292,6 +293,7 @@ CONFIG_PCI_DIRECT=y
CONFIG_PCI_MMCONFIG=y
# CONFIG_PCIEPORTBUS is not set
CONFIG_PCI_MSI=y
+# CONFIG_PCI_MULTITHREAD_PROBE is not set
# CONFIG_PCI_DEBUG is not set
CONFIG_ISA_DMA_API=y
# CONFIG_ISA is not set
@@ -1427,6 +1429,7 @@ CONFIG_KPROBES=y
#
CONFIG_TRACE_IRQFLAGS_SUPPORT=y
# CONFIG_PRINTK_TIME is not set
+# CONFIG_ENABLE_MUST_CHECK is not set
CONFIG_MAGIC_SYSRQ=y
CONFIG_UNUSED_SYMBOLS=y
CONFIG_DEBUG_KERNEL=y
diff --git a/arch/i386/kernel/apm.c b/arch/i386/kernel/apm.c
index ff9ce4b5eaa8..b42f2d914af3 100644
--- a/arch/i386/kernel/apm.c
+++ b/arch/i386/kernel/apm.c
@@ -225,6 +225,7 @@
#include <linux/smp_lock.h>
#include <linux/dmi.h>
#include <linux/suspend.h>
+#include <linux/kthread.h>
#include <asm/system.h>
#include <asm/uaccess.h>
@@ -402,8 +403,6 @@ static int realmode_power_off = 1;
#else
static int realmode_power_off;
#endif
-static int exit_kapmd __read_mostly;
-static int kapmd_running __read_mostly;
#ifdef CONFIG_APM_ALLOW_INTS
static int allow_ints = 1;
#else
@@ -419,6 +418,8 @@ static const struct desc_struct bad_bios_desc = { 0, 0x00409200 };
static const char driver_version[] = "1.16ac"; /* no spaces */
+static struct task_struct *kapmd_task;
+
/*
* APM event names taken from the APM 1.2 specification. These are
* the message codes that the BIOS uses to tell us about events
@@ -1423,7 +1424,7 @@ static void apm_mainloop(void)
set_current_state(TASK_INTERRUPTIBLE);
for (;;) {
schedule_timeout(APM_CHECK_TIMEOUT);
- if (exit_kapmd)
+ if (kthread_should_stop())
break;
/*
* Ok, check all events, check for idle (and mark us sleeping
@@ -1706,12 +1707,6 @@ static int apm(void *unused)
char * power_stat;
char * bat_stat;
- kapmd_running = 1;
-
- daemonize("kapmd");
-
- current->flags |= PF_NOFREEZE;
-
#ifdef CONFIG_SMP
/* 2002/08/01 - WT
* This is to avoid random crashes at boot time during initialization
@@ -1821,7 +1816,6 @@ static int apm(void *unused)
console_blank_hook = NULL;
#endif
}
- kapmd_running = 0;
return 0;
}
@@ -2220,7 +2214,7 @@ static int __init apm_init(void)
{
struct proc_dir_entry *apm_proc;
struct desc_struct *gdt;
- int ret;
+ int err;
dmi_check_system(apm_dmi_table);
@@ -2329,12 +2323,17 @@ static int __init apm_init(void)
if (apm_proc)
apm_proc->owner = THIS_MODULE;
- ret = kernel_thread(apm, NULL, CLONE_KERNEL | SIGCHLD);
- if (ret < 0) {
- printk(KERN_ERR "apm: disabled - Unable to start kernel thread.\n");
+ kapmd_task = kthread_create(apm, NULL, "kapmd");
+ if (IS_ERR(kapmd_task)) {
+ printk(KERN_ERR "apm: disabled - Unable to start kernel "
+ "thread.\n");
+ err = PTR_ERR(kapmd_task);
+ kapmd_task = NULL;
remove_proc_entry("apm", NULL);
- return -ENOMEM;
+ return err;
}
+ kapmd_task->flags |= PF_NOFREEZE;
+ wake_up_process(kapmd_task);
if (num_online_cpus() > 1 && !smp ) {
printk(KERN_NOTICE
@@ -2384,9 +2383,10 @@ static void __exit apm_exit(void)
remove_proc_entry("apm", NULL);
if (power_off)
pm_power_off = NULL;
- exit_kapmd = 1;
- while (kapmd_running)
- schedule();
+ if (kapmd_task) {
+ kthread_stop(kapmd_task);
+ kapmd_task = NULL;
+ }
#ifdef CONFIG_PM_LEGACY
pm_active = 0;
#endif
diff --git a/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c b/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c
index ea19d091fd41..57c880bf0bd6 100644
--- a/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c
+++ b/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c
@@ -396,13 +396,13 @@ static int acpi_cpufreq_early_init_acpi(void)
*/
static int bios_with_sw_any_bug;
-static int __init sw_any_bug_found(struct dmi_system_id *d)
+static int sw_any_bug_found(struct dmi_system_id *d)
{
bios_with_sw_any_bug = 1;
return 0;
}
-static struct dmi_system_id __initdata sw_any_bug_dmi_table[] = {
+static struct dmi_system_id sw_any_bug_dmi_table[] = {
{
.callback = sw_any_bug_found,
.ident = "Supermicro Server X6DLP",
@@ -597,7 +597,6 @@ static struct cpufreq_driver acpi_cpufreq_driver = {
.name = "acpi-cpufreq",
.owner = THIS_MODULE,
.attr = acpi_cpufreq_attr,
- .flags = CPUFREQ_STICKY,
};
@@ -608,7 +607,7 @@ acpi_cpufreq_init (void)
acpi_cpufreq_early_init_acpi();
- return cpufreq_register_driver(&acpi_cpufreq_driver);
+ return cpufreq_register_driver(&acpi_cpufreq_driver);
}
diff --git a/arch/i386/kernel/cpu/cpufreq/longhaul.c b/arch/i386/kernel/cpu/cpufreq/longhaul.c
index f5cc9f5c9bab..7233abe5d695 100644
--- a/arch/i386/kernel/cpu/cpufreq/longhaul.c
+++ b/arch/i386/kernel/cpu/cpufreq/longhaul.c
@@ -178,11 +178,17 @@ static void do_powersaver(int cx_address, unsigned int clock_ratio_index)
safe_halt();
/* Change frequency on next halt or sleep */
wrmsrl(MSR_VIA_LONGHAUL, longhaul.val);
- ACPI_FLUSH_CPU_CACHE();
- /* Invoke C3 */
- inb(cx_address);
- /* Dummy op - must do something useless after P_LVL3 read */
- t = inl(acpi_fadt.xpm_tmr_blk.address);
+ if (port22_en) {
+ ACPI_FLUSH_CPU_CACHE();
+ /* Invoke C1 */
+ halt();
+ } else {
+ ACPI_FLUSH_CPU_CACHE();
+ /* Invoke C3 */
+ inb(cx_address);
+ /* Dummy op - must do something useless after P_LVL3 read */
+ t = inl(acpi_fadt.xpm_tmr_blk.address);
+ }
/* Disable bus ratio bit */
local_irq_disable();
@@ -567,16 +573,23 @@ static acpi_status longhaul_walk_callback(acpi_handle obj_handle,
static int enable_arbiter_disable(void)
{
struct pci_dev *dev;
+ int reg;
u8 pci_cmd;
/* Find PLE133 host bridge */
+ reg = 0x78;
dev = pci_find_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8601_0, NULL);
+ /* Find CLE266 host bridge */
+ if (dev == NULL) {
+ reg = 0x76;
+ dev = pci_find_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_862X_0, NULL);
+ }
if (dev != NULL) {
/* Enable access to port 0x22 */
- pci_read_config_byte(dev, 0x78, &pci_cmd);
+ pci_read_config_byte(dev, reg, &pci_cmd);
if ( !(pci_cmd & 1<<7) ) {
pci_cmd |= 1<<7;
- pci_write_config_byte(dev, 0x78, pci_cmd);
+ pci_write_config_byte(dev, reg, pci_cmd);
}
return 1;
}
@@ -680,20 +693,25 @@ static int __init longhaul_cpu_init(struct cpufreq_policy *policy)
if (longhaul_version == TYPE_POWERSAVER) {
/* Check ACPI support for C3 state */
cx = &pr->power.states[ACPI_STATE_C3];
- if (cx->address == 0 ||
- (cx->latency > 1000 && ignore_latency == 0) )
+ if (cx->address > 0 &&
+ (cx->latency <= 1000 || ignore_latency != 0) ) {
+ goto print_support_type;
+ }
+ }
+ /* Check ACPI support for bus master arbiter disable */
+ if (!pr->flags.bm_control) {
+ if (enable_arbiter_disable()) {
+ port22_en = 1;
+ } else {
goto err_acpi;
-
- } else {
- /* Check ACPI support for bus master arbiter disable */
- if (!pr->flags.bm_control) {
- if (!enable_arbiter_disable()) {
- printk(KERN_ERR PFX "No ACPI support. No VT8601 host bridge. Aborting.\n");
- return -ENODEV;
- } else
- port22_en = 1;
}
}
+print_support_type:
+ if (!port22_en) {
+ printk (KERN_INFO PFX "Using ACPI support.\n");
+ } else {
+ printk (KERN_INFO PFX "Using northbridge support.\n");
+ }
ret = longhaul_get_ranges();
if (ret != 0)
@@ -716,7 +734,7 @@ static int __init longhaul_cpu_init(struct cpufreq_policy *policy)
return 0;
err_acpi:
- printk(KERN_ERR PFX "No ACPI support for CPU frequency changes.\n");
+ printk(KERN_ERR PFX "No ACPI support. No VT8601 or VT8623 northbridge. Aborting.\n");
return -ENODEV;
}
diff --git a/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c b/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c
index 7a9325349e94..e8993baf3d14 100644
--- a/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c
+++ b/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c
@@ -386,7 +386,7 @@ static int centrino_cpu_early_init_acpi(void)
* than OS intended it to run at. Detect it and handle it cleanly.
*/
static int bios_with_sw_any_bug;
-static int __init sw_any_bug_found(struct dmi_system_id *d)
+static int sw_any_bug_found(struct dmi_system_id *d)
{
bios_with_sw_any_bug = 1;
return 0;
diff --git a/arch/i386/kernel/crash.c b/arch/i386/kernel/crash.c
index 67d297dc1003..144b43288965 100644
--- a/arch/i386/kernel/crash.c
+++ b/arch/i386/kernel/crash.c
@@ -23,6 +23,7 @@
#include <asm/hw_irq.h>
#include <asm/apic.h>
#include <asm/kdebug.h>
+#include <asm/smp.h>
#include <mach_ipi.h>
@@ -88,7 +89,7 @@ static void crash_save_self(struct pt_regs *regs)
{
int cpu;
- cpu = smp_processor_id();
+ cpu = safe_smp_processor_id();
crash_save_this_cpu(regs, cpu);
}
@@ -133,7 +134,10 @@ static int crash_nmi_callback(struct notifier_block *self,
static void smp_send_nmi_allbutself(void)
{
- send_IPI_allbutself(NMI_VECTOR);
+ cpumask_t mask = cpu_online_map;
+ cpu_clear(safe_smp_processor_id(), mask);
+ if (!cpus_empty(mask))
+ send_IPI_mask(mask, NMI_VECTOR);
}
static struct notifier_block crash_nmi_nb = {
@@ -185,7 +189,7 @@ void machine_crash_shutdown(struct pt_regs *regs)
local_irq_disable();
/* Make a note of crashing cpu. Will be used in NMI callback.*/
- crashing_cpu = smp_processor_id();
+ crashing_cpu = safe_smp_processor_id();
nmi_shootdown_cpus();
lapic_shutdown();
#if defined(CONFIG_X86_IO_APIC)
diff --git a/arch/i386/kernel/efi.c b/arch/i386/kernel/efi.c
index fe158042110b..f9436989473c 100644
--- a/arch/i386/kernel/efi.c
+++ b/arch/i386/kernel/efi.c
@@ -65,7 +65,7 @@ static unsigned long efi_rt_eflags;
static DEFINE_SPINLOCK(efi_rt_lock);
static pgd_t efi_bak_pg_dir_pointer[2];
-static void efi_call_phys_prelog(void)
+static void efi_call_phys_prelog(void) __acquires(efi_rt_lock)
{
unsigned long cr4;
unsigned long temp;
@@ -109,7 +109,7 @@ static void efi_call_phys_prelog(void)
load_gdt(cpu_gdt_descr);
}
-static void efi_call_phys_epilog(void)
+static void efi_call_phys_epilog(void) __releases(efi_rt_lock)
{
unsigned long cr4;
struct Xgt_desc_struct *cpu_gdt_descr = &per_cpu(cpu_gdt_descr, 0);
diff --git a/arch/i386/kernel/i8237.c b/arch/i386/kernel/i8237.c
index c36d1c006c2f..6f508e8d7c57 100644
--- a/arch/i386/kernel/i8237.c
+++ b/arch/i386/kernel/i8237.c
@@ -2,6 +2,11 @@
* i8237.c: 8237A DMA controller suspend functions.
*
* Written by Pierre Ossman, 2005.
+ *
+ * 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 <linux/init.h>
diff --git a/arch/i386/kernel/kprobes.c b/arch/i386/kernel/kprobes.c
index afe6505ca0b3..d98e44b16fe2 100644
--- a/arch/i386/kernel/kprobes.c
+++ b/arch/i386/kernel/kprobes.c
@@ -230,20 +230,20 @@ void __kprobes arch_prepare_kretprobe(struct kretprobe *rp,
struct pt_regs *regs)
{
unsigned long *sara = (unsigned long *)&regs->esp;
- struct kretprobe_instance *ri;
- if ((ri = get_free_rp_inst(rp)) != NULL) {
- ri->rp = rp;
- ri->task = current;
+ struct kretprobe_instance *ri;
+
+ if ((ri = get_free_rp_inst(rp)) != NULL) {
+ ri->rp = rp;
+ ri->task = current;
ri->ret_addr = (kprobe_opcode_t *) *sara;
/* Replace the return addr with trampoline addr */
*sara = (unsigned long) &kretprobe_trampoline;
-
- add_rp_inst(ri);
- } else {
- rp->nmissed++;
- }
+ add_rp_inst(ri);
+ } else {
+ rp->nmissed++;
+ }
}
/*
@@ -359,7 +359,7 @@ no_kprobe:
void __kprobes kretprobe_trampoline_holder(void)
{
asm volatile ( ".global kretprobe_trampoline\n"
- "kretprobe_trampoline: \n"
+ "kretprobe_trampoline: \n"
" pushf\n"
/* skip cs, eip, orig_eax, es, ds */
" subl $20, %esp\n"
@@ -395,14 +395,15 @@ no_kprobe:
*/
fastcall void *__kprobes trampoline_handler(struct pt_regs *regs)
{
- struct kretprobe_instance *ri = NULL;
- struct hlist_head *head;
- struct hlist_node *node, *tmp;
+ struct kretprobe_instance *ri = NULL;
+ struct hlist_head *head, empty_rp;
+ struct hlist_node *node, *tmp;
unsigned long flags, orig_ret_address = 0;
unsigned long trampoline_address =(unsigned long)&kretprobe_trampoline;
+ INIT_HLIST_HEAD(&empty_rp);
spin_lock_irqsave(&kretprobe_lock, flags);
- head = kretprobe_inst_table_head(current);
+ head = kretprobe_inst_table_head(current);
/*
* It is possible to have multiple instances associated with a given
@@ -413,14 +414,14 @@ fastcall void *__kprobes trampoline_handler(struct pt_regs *regs)
* We can handle this because:
* - instances are always inserted at the head of the list
* - when multiple return probes are registered for the same
- * function, the first instance's ret_addr will point to the
+ * function, the first instance's ret_addr will point to the
* real return address, and all the rest will point to
* kretprobe_trampoline
*/
hlist_for_each_entry_safe(ri, node, tmp, head, hlist) {
- if (ri->task != current)
+ if (ri->task != current)
/* another task is sharing our hash bucket */
- continue;
+ continue;
if (ri->rp && ri->rp->handler){
__get_cpu_var(current_kprobe) = &ri->rp->kp;
@@ -429,7 +430,7 @@ fastcall void *__kprobes trampoline_handler(struct pt_regs *regs)
}
orig_ret_address = (unsigned long)ri->ret_addr;
- recycle_rp_inst(ri);
+ recycle_rp_inst(ri, &empty_rp);
if (orig_ret_address != trampoline_address)
/*
@@ -444,6 +445,10 @@ fastcall void *__kprobes trampoline_handler(struct pt_regs *regs)
spin_unlock_irqrestore(&kretprobe_lock, flags);
+ hlist_for_each_entry_safe(ri, node, tmp, &empty_rp, hlist) {
+ hlist_del(&ri->hlist);
+ kfree(ri);
+ }
return (void*)orig_ret_address;
}
diff --git a/arch/i386/kernel/nmi.c b/arch/i386/kernel/nmi.c
index dbda706fdd14..3e8e3adb0489 100644
--- a/arch/i386/kernel/nmi.c
+++ b/arch/i386/kernel/nmi.c
@@ -13,7 +13,6 @@
* Mikael Pettersson : PM converted to driver model. Disable/enable API.
*/
-#include <linux/config.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
#include <linux/module.h>
@@ -31,6 +30,9 @@
#include "mach_traps.h"
+int unknown_nmi_panic;
+int nmi_watchdog_enabled;
+
/* perfctr_nmi_owner tracks the ownership of the perfctr registers:
* evtsel_nmi_owner tracks the ownership of the event selection
* - different performance counters/ event selection may be reserved for
diff --git a/arch/i386/kernel/process.c b/arch/i386/kernel/process.c
index 8c190ca7ae44..dad02a960e03 100644
--- a/arch/i386/kernel/process.c
+++ b/arch/i386/kernel/process.c
@@ -297,9 +297,9 @@ void show_regs(struct pt_regs * regs)
if (user_mode_vm(regs))
printk(" ESP: %04x:%08lx",0xffff & regs->xss,regs->esp);
printk(" EFLAGS: %08lx %s (%s %.*s)\n",
- regs->eflags, print_tainted(), system_utsname.release,
- (int)strcspn(system_utsname.version, " "),
- system_utsname.version);
+ regs->eflags, print_tainted(), init_utsname()->release,
+ (int)strcspn(init_utsname()->version, " "),
+ init_utsname()->version);
printk("EAX: %08lx EBX: %08lx ECX: %08lx EDX: %08lx\n",
regs->eax,regs->ebx,regs->ecx,regs->edx);
printk("ESI: %08lx EDI: %08lx EBP: %08lx",
@@ -425,13 +425,12 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long esp,
tsk = current;
if (unlikely(test_tsk_thread_flag(tsk, TIF_IO_BITMAP))) {
- p->thread.io_bitmap_ptr = kmalloc(IO_BITMAP_BYTES, GFP_KERNEL);
+ p->thread.io_bitmap_ptr = kmemdup(tsk->thread.io_bitmap_ptr,
+ IO_BITMAP_BYTES, GFP_KERNEL);
if (!p->thread.io_bitmap_ptr) {
p->thread.io_bitmap_max = 0;
return -ENOMEM;
}
- memcpy(p->thread.io_bitmap_ptr, tsk->thread.io_bitmap_ptr,
- IO_BITMAP_BYTES);
set_tsk_thread_flag(p, TIF_IO_BITMAP);
}
diff --git a/arch/i386/kernel/setup.c b/arch/i386/kernel/setup.c
index 814cdebf7377..000cf03751fe 100644
--- a/arch/i386/kernel/setup.c
+++ b/arch/i386/kernel/setup.c
@@ -209,9 +209,6 @@ static struct resource adapter_rom_resources[] = { {
.flags = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM
} };
-#define ADAPTER_ROM_RESOURCES \
- (sizeof adapter_rom_resources / sizeof adapter_rom_resources[0])
-
static struct resource video_rom_resource = {
.name = "Video ROM",
.start = 0xc0000,
@@ -273,9 +270,6 @@ static struct resource standard_io_resources[] = { {
.flags = IORESOURCE_BUSY | IORESOURCE_IO
} };
-#define STANDARD_IO_RESOURCES \
- (sizeof standard_io_resources / sizeof standard_io_resources[0])
-
#define romsignature(x) (*(unsigned short *)(x) == 0xaa55)
static int __init romchecksum(unsigned char *rom, unsigned long length)
@@ -332,7 +326,7 @@ static void __init probe_roms(void)
}
/* check for adapter roms on 2k boundaries */
- for (i = 0; i < ADAPTER_ROM_RESOURCES && start < upper; start += 2048) {
+ for (i = 0; i < ARRAY_SIZE(adapter_rom_resources) && start < upper; start += 2048) {
rom = isa_bus_to_virt(start);
if (!romsignature(rom))
continue;
@@ -1272,7 +1266,7 @@ static int __init request_standard_resources(void)
request_resource(&iomem_resource, &video_ram_resource);
/* request I/O space for devices used on all i[345]86 PCs */
- for (i = 0; i < STANDARD_IO_RESOURCES; i++)
+ for (i = 0; i < ARRAY_SIZE(standard_io_resources); i++)
request_resource(&ioport_resource, &standard_io_resources[i]);
return 0;
}
diff --git a/arch/i386/kernel/smp.c b/arch/i386/kernel/smp.c
index 465188e2d701..1b080ab8a49f 100644
--- a/arch/i386/kernel/smp.c
+++ b/arch/i386/kernel/smp.c
@@ -700,3 +700,30 @@ int smp_call_function_single(int cpu, void (*func) (void *info), void *info,
return 0;
}
EXPORT_SYMBOL(smp_call_function_single);
+
+static int convert_apicid_to_cpu(int apic_id)
+{
+ int i;
+
+ for (i = 0; i < NR_CPUS; i++) {
+ if (x86_cpu_to_apicid[i] == apic_id)
+ return i;
+ }
+ return -1;
+}
+
+int safe_smp_processor_id(void)
+{
+ int apicid, cpuid;
+
+ if (!boot_cpu_has(X86_FEATURE_APIC))
+ return 0;
+
+ apicid = hard_smp_processor_id();
+ if (apicid == BAD_APICID)
+ return 0;
+
+ cpuid = convert_apicid_to_cpu(apicid);
+
+ return cpuid >= 0 ? cpuid : 0;
+}
diff --git a/arch/i386/kernel/smpboot.c b/arch/i386/kernel/smpboot.c
index 020d873b7d21..9d93ecf6d999 100644
--- a/arch/i386/kernel/smpboot.c
+++ b/arch/i386/kernel/smpboot.c
@@ -102,6 +102,8 @@ u8 x86_cpu_to_apicid[NR_CPUS] __read_mostly =
{ [0 ... NR_CPUS-1] = 0xff };
EXPORT_SYMBOL(x86_cpu_to_apicid);
+u8 apicid_2_node[MAX_APICID];
+
/*
* Trampoline 80x86 program as an array.
*/
@@ -610,6 +612,7 @@ extern struct {
/* which logical CPUs are on which nodes */
cpumask_t node_2_cpu_mask[MAX_NUMNODES] __read_mostly =
{ [0 ... MAX_NUMNODES-1] = CPU_MASK_NONE };
+EXPORT_SYMBOL(node_2_cpu_mask);
/* which node each logical CPU is on */
int cpu_2_node[NR_CPUS] __read_mostly = { [0 ... NR_CPUS-1] = 0 };
EXPORT_SYMBOL(cpu_2_node);
@@ -645,7 +648,7 @@ static void map_cpu_to_logical_apicid(void)
{
int cpu = smp_processor_id();
int apicid = logical_smp_processor_id();
- int node = apicid_to_node(apicid);
+ int node = apicid_to_node(hard_smp_processor_id());
if (!node_online(node))
node = first_online_node;
@@ -954,6 +957,7 @@ static int __devinit do_boot_cpu(int apicid, int cpu)
irq_ctx_init(cpu);
+ x86_cpu_to_apicid[cpu] = apicid;
/*
* This grunge runs the startup process for
* the targeted processor.
@@ -1058,7 +1062,7 @@ static void __cpuinit do_warm_boot_cpu(void *p)
static int __cpuinit __smp_prepare_cpu(int cpu)
{
- DECLARE_COMPLETION(done);
+ DECLARE_COMPLETION_ONSTACK(done);
struct warm_boot_cpu_info info;
struct work_struct task;
int apicid, ret;
diff --git a/arch/i386/kernel/srat.c b/arch/i386/kernel/srat.c
index 32413122c4c2..f7e735c077c3 100644
--- a/arch/i386/kernel/srat.c
+++ b/arch/i386/kernel/srat.c
@@ -30,6 +30,7 @@
#include <linux/nodemask.h>
#include <asm/srat.h>
#include <asm/topology.h>
+#include <asm/smp.h>
/*
* proximity macros and definitions
@@ -54,6 +55,7 @@ struct node_memory_chunk_s {
static struct node_memory_chunk_s node_memory_chunk[MAXCHUNKS];
static int num_memory_chunks; /* total number of memory chunks */
+static u8 __initdata apicid_to_pxm[MAX_APICID];
extern void * boot_ioremap(unsigned long, unsigned long);
@@ -69,6 +71,8 @@ static void __init parse_cpu_affinity_structure(char *p)
/* mark this node as "seen" in node bitmap */
BMAP_SET(pxm_bitmap, cpu_affinity->proximity_domain);
+ apicid_to_pxm[cpu_affinity->apic_id] = cpu_affinity->proximity_domain;
+
printk("CPU 0x%02X in proximity domain 0x%02X\n",
cpu_affinity->apic_id, cpu_affinity->proximity_domain);
}
@@ -235,6 +239,9 @@ static int __init acpi20_parse_srat(struct acpi_table_srat *sratp)
printk("Number of logical nodes in system = %d\n", num_online_nodes());
printk("Number of memory chunks in system = %d\n", num_memory_chunks);
+ for (i = 0; i < MAX_APICID; i++)
+ apicid_2_node[i] = pxm_to_node(apicid_to_pxm[i]);
+
for (j = 0; j < num_memory_chunks; j++){
struct node_memory_chunk_s * chunk = &node_memory_chunk[j];
printk("chunk %d nid %d start_pfn %08lx end_pfn %08lx\n",
diff --git a/arch/i386/kernel/sys_i386.c b/arch/i386/kernel/sys_i386.c
index 8fdb1fb17a5f..4048397f1740 100644
--- a/arch/i386/kernel/sys_i386.c
+++ b/arch/i386/kernel/sys_i386.c
@@ -21,6 +21,7 @@
#include <linux/utsname.h>
#include <asm/uaccess.h>
+#include <asm/unistd.h>
#include <asm/ipc.h>
/*
@@ -210,7 +211,7 @@ asmlinkage int sys_uname(struct old_utsname __user * name)
if (!name)
return -EFAULT;
down_read(&uts_sem);
- err=copy_to_user(name, &system_utsname, sizeof (*name));
+ err = copy_to_user(name, utsname(), sizeof (*name));
up_read(&uts_sem);
return err?-EFAULT:0;
}
@@ -226,16 +227,21 @@ asmlinkage int sys_olduname(struct oldold_utsname __user * name)
down_read(&uts_sem);
- error = __copy_to_user(&name->sysname,&system_utsname.sysname,__OLD_UTS_LEN);
- error |= __put_user(0,name->sysname+__OLD_UTS_LEN);
- error |= __copy_to_user(&name->nodename,&system_utsname.nodename,__OLD_UTS_LEN);
- error |= __put_user(0,name->nodename+__OLD_UTS_LEN);
- error |= __copy_to_user(&name->release,&system_utsname.release,__OLD_UTS_LEN);
- error |= __put_user(0,name->release+__OLD_UTS_LEN);
- error |= __copy_to_user(&name->version,&system_utsname.version,__OLD_UTS_LEN);
- error |= __put_user(0,name->version+__OLD_UTS_LEN);
- error |= __copy_to_user(&name->machine,&system_utsname.machine,__OLD_UTS_LEN);
- error |= __put_user(0,name->machine+__OLD_UTS_LEN);
+ error = __copy_to_user(&name->sysname, &utsname()->sysname,
+ __OLD_UTS_LEN);
+ error |= __put_user(0, name->sysname + __OLD_UTS_LEN);
+ error |= __copy_to_user(&name->nodename, &utsname()->nodename,
+ __OLD_UTS_LEN);
+ error |= __put_user(0, name->nodename + __OLD_UTS_LEN);
+ error |= __copy_to_user(&name->release, &utsname()->release,
+ __OLD_UTS_LEN);
+ error |= __put_user(0, name->release + __OLD_UTS_LEN);
+ error |= __copy_to_user(&name->version, &utsname()->version,
+ __OLD_UTS_LEN);
+ error |= __put_user(0, name->version + __OLD_UTS_LEN);
+ error |= __copy_to_user(&name->machine, &utsname()->machine,
+ __OLD_UTS_LEN);
+ error |= __put_user(0, name->machine + __OLD_UTS_LEN);
up_read(&uts_sem);
@@ -243,3 +249,17 @@ asmlinkage int sys_olduname(struct oldold_utsname __user * name)
return error;
}
+
+
+/*
+ * Do a system call from kernel instead of calling sys_execve so we
+ * end up with proper pt_regs.
+ */
+int kernel_execve(const char *filename, char *const argv[], char *const envp[])
+{
+ long __res;
+ asm volatile ("push %%ebx ; movl %2,%%ebx ; int $0x80 ; pop %%ebx"
+ : "=a" (__res)
+ : "0" (__NR_execve),"ri" (filename),"c" (argv), "d" (envp) : "memory");
+ return __res;
+}
diff --git a/arch/i386/kernel/time.c b/arch/i386/kernel/time.c
index 86944acfb647..58a2d5582419 100644
--- a/arch/i386/kernel/time.c
+++ b/arch/i386/kernel/time.c
@@ -76,8 +76,6 @@ int pit_latch_buggy; /* extern */
unsigned int cpu_khz; /* Detected as we calibrate the TSC */
EXPORT_SYMBOL(cpu_khz);
-extern unsigned long wall_jiffies;
-
DEFINE_SPINLOCK(rtc_lock);
EXPORT_SYMBOL(rtc_lock);
@@ -329,7 +327,6 @@ static int timer_resume(struct sys_device *dev)
do_settimeofday(&ts);
write_seqlock_irqsave(&xtime_lock, flags);
jiffies_64 += sleep_length;
- wall_jiffies += sleep_length;
write_sequnlock_irqrestore(&xtime_lock, flags);
touch_softlockup_watchdog();
return 0;
diff --git a/arch/i386/kernel/traps.c b/arch/i386/kernel/traps.c
index a13037fe0ee3..00489b706d27 100644
--- a/arch/i386/kernel/traps.c
+++ b/arch/i386/kernel/traps.c
@@ -57,6 +57,8 @@
#include "mach_traps.h"
+int panic_on_unrecovered_nmi;
+
asmlinkage int system_call(void);
struct desc_struct default_ldt[] = { { 0, 0 }, { 0, 0 }, { 0, 0 },
@@ -355,9 +357,9 @@ void show_registers(struct pt_regs *regs)
KERN_EMERG "EIP: %04x:[<%08lx>] %s VLI\n"
KERN_EMERG "EFLAGS: %08lx (%s %.*s)\n",
smp_processor_id(), 0xffff & regs->xcs, regs->eip,
- print_tainted(), regs->eflags, system_utsname.release,
- (int)strcspn(system_utsname.version, " "),
- system_utsname.version);
+ print_tainted(), regs->eflags, init_utsname()->release,
+ (int)strcspn(init_utsname()->version, " "),
+ init_utsname()->version);
print_symbol(KERN_EMERG "EIP is at %s\n", regs->eip);
printk(KERN_EMERG "eax: %08lx ebx: %08lx ecx: %08lx edx: %08lx\n",
regs->eax, regs->ebx, regs->ecx, regs->edx);
diff --git a/arch/i386/lib/delay.c b/arch/i386/lib/delay.c
index 3c0714c4b669..f6edb11364df 100644
--- a/arch/i386/lib/delay.c
+++ b/arch/i386/lib/delay.c
@@ -11,7 +11,6 @@
*/
#include <linux/module.h>
-#include <linux/config.h>
#include <linux/sched.h>
#include <linux/delay.h>
diff --git a/arch/i386/lib/usercopy.c b/arch/i386/lib/usercopy.c
index efc7e7d5f4d0..08502fc6d0cb 100644
--- a/arch/i386/lib/usercopy.c
+++ b/arch/i386/lib/usercopy.c
@@ -739,7 +739,7 @@ survive:
retval = get_user_pages(current, current->mm,
(unsigned long )to, 1, 1, 0, &pg, NULL);
- if (retval == -ENOMEM && current->pid == 1) {
+ if (retval == -ENOMEM && is_init(current)) {
up_read(&current->mm->mmap_sem);
blk_congestion_wait(WRITE, HZ/50);
goto survive;
diff --git a/arch/i386/mach-voyager/voyager_smp.c b/arch/i386/mach-voyager/voyager_smp.c
index 6c86575ffdcb..856c73fcb7e7 100644
--- a/arch/i386/mach-voyager/voyager_smp.c
+++ b/arch/i386/mach-voyager/voyager_smp.c
@@ -99,6 +99,7 @@ static void do_boot_cpu(__u8 cpuid);
static void do_quad_bootstrap(void);
int hard_smp_processor_id(void);
+int safe_smp_processor_id(void);
/* Inline functions */
static inline void
@@ -1247,6 +1248,12 @@ hard_smp_processor_id(void)
return 0;
}
+int
+safe_smp_processor_id(void)
+{
+ return hard_smp_processor_id();
+}
+
/* broadcast a halt to all other CPUs */
void
smp_send_stop(void)
diff --git a/arch/i386/mm/fault.c b/arch/i386/mm/fault.c
index 5e17a3f43b41..2581575786c1 100644
--- a/arch/i386/mm/fault.c
+++ b/arch/i386/mm/fault.c
@@ -440,7 +440,7 @@ good_area:
case 1: /* read, present */
goto bad_area;
case 0: /* read, not present */
- if (!(vma->vm_flags & (VM_READ | VM_EXEC)))
+ if (!(vma->vm_flags & (VM_READ | VM_EXEC | VM_WRITE)))
goto bad_area;
}
@@ -589,7 +589,7 @@ no_context:
*/
out_of_memory:
up_read(&mm->mmap_sem);
- if (tsk->pid == 1) {
+ if (is_init(tsk)) {
yield();
down_read(&mm->mmap_sem);
goto survive;
diff --git a/arch/i386/mm/highmem.c b/arch/i386/mm/highmem.c
index ba44000b9069..f9f647cdbc7b 100644
--- a/arch/i386/mm/highmem.c
+++ b/arch/i386/mm/highmem.c
@@ -38,22 +38,19 @@ void *kmap_atomic(struct page *page, enum km_type type)
idx = type + KM_TYPE_NR*smp_processor_id();
vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
-#ifdef CONFIG_DEBUG_HIGHMEM
if (!pte_none(*(kmap_pte-idx)))
BUG();
-#endif
set_pte(kmap_pte-idx, mk_pte(page, kmap_prot));
- __flush_tlb_one(vaddr);
return (void*) vaddr;
}
void kunmap_atomic(void *kvaddr, enum km_type type)
{
-#ifdef CONFIG_DEBUG_HIGHMEM
unsigned long vaddr = (unsigned long) kvaddr & PAGE_MASK;
enum fixed_addresses idx = type + KM_TYPE_NR*smp_processor_id();
+#ifdef CONFIG_DEBUG_HIGHMEM
if (vaddr >= PAGE_OFFSET && vaddr < (unsigned long)high_memory) {
dec_preempt_count();
preempt_check_resched();
@@ -62,14 +59,14 @@ void kunmap_atomic(void *kvaddr, enum km_type type)
if (vaddr != __fix_to_virt(FIX_KMAP_BEGIN+idx))
BUG();
-
+#endif
/*
- * force other mappings to Oops if they'll try to access
- * this pte without first remap it
+ * Force other mappings to Oops if they'll try to access this pte
+ * without first remap it. Keeping stale mappings around is a bad idea
+ * also, in case the page changes cacheability attributes or becomes
+ * a protected page in a hypervisor.
*/
- pte_clear(&init_mm, vaddr, kmap_pte-idx);
- __flush_tlb_one(vaddr);
-#endif
+ kpte_clear_flush(kmap_pte-idx, vaddr);
dec_preempt_count();
preempt_check_resched();
@@ -88,7 +85,6 @@ void *kmap_atomic_pfn(unsigned long pfn, enum km_type type)
idx = type + KM_TYPE_NR*smp_processor_id();
vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
set_pte(kmap_pte-idx, pfn_pte(pfn, kmap_prot));
- __flush_tlb_one(vaddr);
return (void*) vaddr;
}
diff --git a/arch/i386/mm/init.c b/arch/i386/mm/init.c
index 4a5a914b3432..90089c14c23d 100644
--- a/arch/i386/mm/init.c
+++ b/arch/i386/mm/init.c
@@ -493,6 +493,7 @@ int __init set_kernel_exec(unsigned long vaddr, int enable)
pte->pte_high &= ~(1 << (_PAGE_BIT_NX - 32));
else
pte->pte_high |= 1 << (_PAGE_BIT_NX - 32);
+ pte_update_defer(&init_mm, vaddr, pte);
__flush_tlb_all();
out:
return ret;
diff --git a/arch/i386/mm/ioremap.c b/arch/i386/mm/ioremap.c
index 247fde76aaed..fff08ae7b5ed 100644
--- a/arch/i386/mm/ioremap.c
+++ b/arch/i386/mm/ioremap.c
@@ -12,7 +12,7 @@
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/module.h>
-#include <asm/io.h>
+#include <linux/io.h>
#include <asm/fixmap.h>
#include <asm/cacheflush.h>
#include <asm/tlbflush.h>
@@ -21,82 +21,6 @@
#define ISA_START_ADDRESS 0xa0000
#define ISA_END_ADDRESS 0x100000
-static int ioremap_pte_range(pmd_t *pmd, unsigned long addr,
- unsigned long end, unsigned long phys_addr, unsigned long flags)
-{
- pte_t *pte;
- unsigned long pfn;
-
- pfn = phys_addr >> PAGE_SHIFT;
- pte = pte_alloc_kernel(pmd, addr);
- if (!pte)
- return -ENOMEM;
- do {
- BUG_ON(!pte_none(*pte));
- set_pte(pte, pfn_pte(pfn, __pgprot(_PAGE_PRESENT | _PAGE_RW |
- _PAGE_DIRTY | _PAGE_ACCESSED | flags)));
- pfn++;
- } while (pte++, addr += PAGE_SIZE, addr != end);
- return 0;
-}
-
-static inline int ioremap_pmd_range(pud_t *pud, unsigned long addr,
- unsigned long end, unsigned long phys_addr, unsigned long flags)
-{
- pmd_t *pmd;
- unsigned long next;
-
- phys_addr -= addr;
- pmd = pmd_alloc(&init_mm, pud, addr);
- if (!pmd)
- return -ENOMEM;
- do {
- next = pmd_addr_end(addr, end);
- if (ioremap_pte_range(pmd, addr, next, phys_addr + addr, flags))
- return -ENOMEM;
- } while (pmd++, addr = next, addr != end);
- return 0;
-}
-
-static inline int ioremap_pud_range(pgd_t *pgd, unsigned long addr,
- unsigned long end, unsigned long phys_addr, unsigned long flags)
-{
- pud_t *pud;
- unsigned long next;
-
- phys_addr -= addr;
- pud = pud_alloc(&init_mm, pgd, addr);
- if (!pud)
- return -ENOMEM;
- do {
- next = pud_addr_end(addr, end);
- if (ioremap_pmd_range(pud, addr, next, phys_addr + addr, flags))
- return -ENOMEM;
- } while (pud++, addr = next, addr != end);
- return 0;
-}
-
-static int ioremap_page_range(unsigned long addr,
- unsigned long end, unsigned long phys_addr, unsigned long flags)
-{
- pgd_t *pgd;
- unsigned long next;
- int err;
-
- BUG_ON(addr >= end);
- flush_cache_all();
- phys_addr -= addr;
- pgd = pgd_offset_k(addr);
- do {
- next = pgd_addr_end(addr, end);
- err = ioremap_pud_range(pgd, addr, next, phys_addr+addr, flags);
- if (err)
- break;
- } while (pgd++, addr = next, addr != end);
- flush_tlb_all();
- return err;
-}
-
/*
* Generic mapping function (not visible outside):
*/
@@ -115,6 +39,7 @@ void __iomem * __ioremap(unsigned long phys_addr, unsigned long size, unsigned l
void __iomem * addr;
struct vm_struct * area;
unsigned long offset, last_addr;
+ pgprot_t prot;
/* Don't allow wraparound or zero size */
last_addr = phys_addr + size - 1;
@@ -142,6 +67,9 @@ void __iomem * __ioremap(unsigned long phys_addr, unsigned long size, unsigned l
return NULL;
}
+ prot = __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY
+ | _PAGE_ACCESSED | flags);
+
/*
* Mappings have to be page-aligned
*/
@@ -158,7 +86,7 @@ void __iomem * __ioremap(unsigned long phys_addr, unsigned long size, unsigned l
area->phys_addr = phys_addr;
addr = (void __iomem *) area->addr;
if (ioremap_page_range((unsigned long) addr,
- (unsigned long) addr + size, phys_addr, flags)) {
+ (unsigned long) addr + size, phys_addr, prot)) {
vunmap((void __force *) addr);
return NULL;
}
diff --git a/arch/i386/oprofile/op_model_ppro.c b/arch/i386/oprofile/op_model_ppro.c
index f88e05ba8eb3..ca2447e05e15 100644
--- a/arch/i386/oprofile/op_model_ppro.c
+++ b/arch/i386/oprofile/op_model_ppro.c
@@ -138,11 +138,14 @@ static int ppro_check_ctrs(struct pt_regs * const regs,
static void ppro_start(struct op_msrs const * const msrs)
{
unsigned int low,high;
+ int i;
- if (reset_value[0]) {
- CTRL_READ(low, high, msrs, 0);
- CTRL_SET_ACTIVE(low);
- CTRL_WRITE(low, high, msrs, 0);
+ for (i = 0; i < NUM_COUNTERS; ++i) {
+ if (reset_value[i]) {
+ CTRL_READ(low, high, msrs, i);
+ CTRL_SET_ACTIVE(low);
+ CTRL_WRITE(low, high, msrs, i);
+ }
}
}
@@ -150,11 +153,14 @@ static void ppro_start(struct op_msrs const * const msrs)
static void ppro_stop(struct op_msrs const * const msrs)
{
unsigned int low,high;
+ int i;
- if (reset_value[0]) {
- CTRL_READ(low, high, msrs, 0);
+ for (i = 0; i < NUM_COUNTERS; ++i) {
+ if (!reset_value[i])
+ continue;
+ CTRL_READ(low, high, msrs, i);
CTRL_SET_INACTIVE(low);
- CTRL_WRITE(low, high, msrs, 0);
+ CTRL_WRITE(low, high, msrs, i);
}
}
diff --git a/arch/i386/pci/mmconfig.c b/arch/i386/pci/mmconfig.c
index 05be8db58a8c..d0c3da3aa2aa 100644
--- a/arch/i386/pci/mmconfig.c
+++ b/arch/i386/pci/mmconfig.c
@@ -67,7 +67,10 @@ static u32 get_base_addr(unsigned int seg, int bus, unsigned devfn)
return 0;
}
-static inline void pci_exp_set_dev_base(unsigned int base, int bus, int devfn)
+/*
+ * This is always called under pci_config_lock
+ */
+static void pci_exp_set_dev_base(unsigned int base, int bus, int devfn)
{
u32 dev_base = base | (bus << 20) | (devfn << 12);
if (dev_base != mmcfg_last_accessed_device) {
diff --git a/arch/ia64/Kconfig b/arch/ia64/Kconfig
index 0b7f701d5cf7..70f7eb9fed35 100644
--- a/arch/ia64/Kconfig
+++ b/arch/ia64/Kconfig
@@ -516,7 +516,7 @@ source "arch/ia64/oprofile/Kconfig"
config KPROBES
bool "Kprobes (EXPERIMENTAL)"
- depends on EXPERIMENTAL && MODULES
+ depends on KALLSYMS && EXPERIMENTAL && MODULES
help
Kprobes allows you to trap at almost any kernel address and
execute a callback function. register_kprobe() establishes
diff --git a/arch/ia64/hp/sim/simeth.c b/arch/ia64/hp/sim/simeth.c
index b5195be62818..e1a1b11473e2 100644
--- a/arch/ia64/hp/sim/simeth.c
+++ b/arch/ia64/hp/sim/simeth.c
@@ -320,7 +320,7 @@ simeth_device_event(struct notifier_block *this,unsigned long event, void *ptr)
}
printk(KERN_INFO "simeth_device_event: %s ipaddr=0x%x\n",
- dev->name, htonl(ifa->ifa_local));
+ dev->name, ntohl(ifa->ifa_local));
/*
* XXX Fix me
@@ -331,7 +331,7 @@ simeth_device_event(struct notifier_block *this,unsigned long event, void *ptr)
local = dev->priv;
/* now do it for real */
r = event == NETDEV_UP ?
- netdev_attach(local->simfd, dev->irq, htonl(ifa->ifa_local)):
+ netdev_attach(local->simfd, dev->irq, ntohl(ifa->ifa_local)):
netdev_detach(local->simfd);
printk(KERN_INFO "simeth: netdev_attach/detach: event=%s ->%d\n",
diff --git a/arch/ia64/hp/sim/simserial.c b/arch/ia64/hp/sim/simserial.c
index 0daacc20ed36..246eb3d3757a 100644
--- a/arch/ia64/hp/sim/simserial.c
+++ b/arch/ia64/hp/sim/simserial.c
@@ -940,7 +940,7 @@ static inline void show_serial_version(void)
printk(KERN_INFO " no serial options enabled\n");
}
-static struct tty_operations hp_ops = {
+static const struct tty_operations hp_ops = {
.open = rs_open,
.close = rs_close,
.write = rs_write,
diff --git a/arch/ia64/ia32/sys_ia32.c b/arch/ia64/ia32/sys_ia32.c
index bddbd22706ed..9d6a3f210148 100644
--- a/arch/ia64/ia32/sys_ia32.c
+++ b/arch/ia64/ia32/sys_ia32.c
@@ -125,6 +125,7 @@ sys32_execve (char __user *name, compat_uptr_t __user *argv, compat_uptr_t __use
int cp_compat_stat(struct kstat *stat, struct compat_stat __user *ubuf)
{
+ compat_ino_t ino;
int err;
if ((u64) stat->size > MAX_NON_LFS ||
@@ -132,11 +133,15 @@ int cp_compat_stat(struct kstat *stat, struct compat_stat __user *ubuf)
!old_valid_dev(stat->rdev))
return -EOVERFLOW;
+ ino = stat->ino;
+ if (sizeof(ino) < sizeof(stat->ino) && ino != stat->ino)
+ return -EOVERFLOW;
+
if (clear_user(ubuf, sizeof(*ubuf)))
return -EFAULT;
err = __put_user(old_encode_dev(stat->dev), &ubuf->st_dev);
- err |= __put_user(stat->ino, &ubuf->st_ino);
+ err |= __put_user(ino, &ubuf->st_ino);
err |= __put_user(stat->mode, &ubuf->st_mode);
err |= __put_user(stat->nlink, &ubuf->st_nlink);
err |= __put_user(high2lowuid(stat->uid), &ubuf->st_uid);
@@ -1222,16 +1227,20 @@ struct readdir32_callback {
};
static int
-filldir32 (void *__buf, const char *name, int namlen, loff_t offset, ino_t ino,
+filldir32 (void *__buf, const char *name, int namlen, loff_t offset, u64 ino,
unsigned int d_type)
{
struct compat_dirent __user * dirent;
struct getdents32_callback * buf = (struct getdents32_callback *) __buf;
int reclen = ROUND_UP(offsetof(struct compat_dirent, d_name) + namlen + 1, 4);
+ u32 d_ino;
buf->error = -EINVAL; /* only used if we fail.. */
if (reclen > buf->count)
return -EINVAL;
+ d_ino = ino;
+ if (sizeof(d_ino) < sizeof(ino) && d_ino != ino)
+ return -EOVERFLOW;
buf->error = -EFAULT; /* only used if we fail.. */
dirent = buf->previous;
if (dirent)
@@ -1239,7 +1248,7 @@ filldir32 (void *__buf, const char *name, int namlen, loff_t offset, ino_t ino,
return -EFAULT;
dirent = buf->current_dir;
buf->previous = dirent;
- if (put_user(ino, &dirent->d_ino)
+ if (put_user(d_ino, &dirent->d_ino)
|| put_user(reclen, &dirent->d_reclen)
|| copy_to_user(dirent->d_name, name, namlen)
|| put_user(0, dirent->d_name + namlen))
@@ -1287,17 +1296,21 @@ out:
}
static int
-fillonedir32 (void * __buf, const char * name, int namlen, loff_t offset, ino_t ino,
+fillonedir32 (void * __buf, const char * name, int namlen, loff_t offset, u64 ino,
unsigned int d_type)
{
struct readdir32_callback * buf = (struct readdir32_callback *) __buf;
struct old_linux32_dirent __user * dirent;
+ u32 d_ino;
if (buf->count)
return -EINVAL;
+ d_ino = ino;
+ if (sizeof(d_ino) < sizeof(ino) && d_ino != ino)
+ return -EOVERFLOW;
buf->count++;
dirent = buf->dirent;
- if (put_user(ino, &dirent->d_ino)
+ if (put_user(d_ino, &dirent->d_ino)
|| put_user(offset, &dirent->d_offset)
|| put_user(namlen, &dirent->d_namlen)
|| copy_to_user(dirent->d_name, name, namlen)
diff --git a/arch/ia64/kernel/entry.S b/arch/ia64/kernel/entry.S
index 12701cf32d99..e5b1be51b197 100644
--- a/arch/ia64/kernel/entry.S
+++ b/arch/ia64/kernel/entry.S
@@ -492,11 +492,11 @@ GLOBAL_ENTRY(prefetch_stack)
br.ret.sptk.many rp
END(prefetch_stack)
-GLOBAL_ENTRY(execve)
+GLOBAL_ENTRY(kernel_execve)
mov r15=__NR_execve // put syscall number in place
break __BREAK_SYSCALL
br.ret.sptk.many rp
-END(execve)
+END(kernel_execve)
GLOBAL_ENTRY(clone)
mov r15=__NR_clone // put syscall number in place
diff --git a/arch/ia64/kernel/kprobes.c b/arch/ia64/kernel/kprobes.c
index 169ec3a7156c..51217d63285e 100644
--- a/arch/ia64/kernel/kprobes.c
+++ b/arch/ia64/kernel/kprobes.c
@@ -90,7 +90,7 @@ static void __kprobes update_kprobe_inst_flag(uint template, uint slot,
p->ainsn.target_br_reg = 0;
/* Check for Break instruction
- * Bits 37:40 Major opcode to be zero
+ * Bits 37:40 Major opcode to be zero
* Bits 27:32 X6 to be zero
* Bits 32:35 X3 to be zero
*/
@@ -104,19 +104,19 @@ static void __kprobes update_kprobe_inst_flag(uint template, uint slot,
switch (major_opcode) {
case INDIRECT_CALL_OPCODE:
p->ainsn.inst_flag |= INST_FLAG_FIX_BRANCH_REG;
- p->ainsn.target_br_reg = ((kprobe_inst >> 6) & 0x7);
- break;
+ p->ainsn.target_br_reg = ((kprobe_inst >> 6) & 0x7);
+ break;
case IP_RELATIVE_PREDICT_OPCODE:
case IP_RELATIVE_BRANCH_OPCODE:
p->ainsn.inst_flag |= INST_FLAG_FIX_RELATIVE_IP_ADDR;
- break;
+ break;
case IP_RELATIVE_CALL_OPCODE:
- p->ainsn.inst_flag |= INST_FLAG_FIX_RELATIVE_IP_ADDR;
- p->ainsn.inst_flag |= INST_FLAG_FIX_BRANCH_REG;
- p->ainsn.target_br_reg = ((kprobe_inst >> 6) & 0x7);
- break;
+ p->ainsn.inst_flag |= INST_FLAG_FIX_RELATIVE_IP_ADDR;
+ p->ainsn.inst_flag |= INST_FLAG_FIX_BRANCH_REG;
+ p->ainsn.target_br_reg = ((kprobe_inst >> 6) & 0x7);
+ break;
}
- } else if (bundle_encoding[template][slot] == X) {
+ } else if (bundle_encoding[template][slot] == X) {
switch (major_opcode) {
case LONG_CALL_OPCODE:
p->ainsn.inst_flag |= INST_FLAG_FIX_BRANCH_REG;
@@ -258,18 +258,18 @@ static void __kprobes get_kprobe_inst(bundle_t *bundle, uint slot,
switch (slot) {
case 0:
- *major_opcode = (bundle->quad0.slot0 >> SLOT0_OPCODE_SHIFT);
- *kprobe_inst = bundle->quad0.slot0;
- break;
+ *major_opcode = (bundle->quad0.slot0 >> SLOT0_OPCODE_SHIFT);
+ *kprobe_inst = bundle->quad0.slot0;
+ break;
case 1:
- *major_opcode = (bundle->quad1.slot1_p1 >> SLOT1_p1_OPCODE_SHIFT);
- kprobe_inst_p0 = bundle->quad0.slot1_p0;
- kprobe_inst_p1 = bundle->quad1.slot1_p1;
- *kprobe_inst = kprobe_inst_p0 | (kprobe_inst_p1 << (64-46));
+ *major_opcode = (bundle->quad1.slot1_p1 >> SLOT1_p1_OPCODE_SHIFT);
+ kprobe_inst_p0 = bundle->quad0.slot1_p0;
+ kprobe_inst_p1 = bundle->quad1.slot1_p1;
+ *kprobe_inst = kprobe_inst_p0 | (kprobe_inst_p1 << (64-46));
break;
case 2:
- *major_opcode = (bundle->quad1.slot2 >> SLOT2_OPCODE_SHIFT);
- *kprobe_inst = bundle->quad1.slot2;
+ *major_opcode = (bundle->quad1.slot2 >> SLOT2_OPCODE_SHIFT);
+ *kprobe_inst = bundle->quad1.slot2;
break;
}
}
@@ -290,11 +290,11 @@ static int __kprobes valid_kprobe_addr(int template, int slot,
return -EINVAL;
}
- if (in_ivt_functions(addr)) {
- printk(KERN_WARNING "Kprobes can't be inserted inside "
+ if (in_ivt_functions(addr)) {
+ printk(KERN_WARNING "Kprobes can't be inserted inside "
"IVT functions at 0x%lx\n", addr);
- return -EINVAL;
- }
+ return -EINVAL;
+ }
if (slot == 1 && bundle_encoding[template][1] != L) {
printk(KERN_WARNING "Inserting kprobes on slot #1 "
@@ -338,12 +338,13 @@ static void kretprobe_trampoline(void)
int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs)
{
struct kretprobe_instance *ri = NULL;
- struct hlist_head *head;
+ struct hlist_head *head, empty_rp;
struct hlist_node *node, *tmp;
unsigned long flags, orig_ret_address = 0;
unsigned long trampoline_address =
((struct fnptr *)kretprobe_trampoline)->ip;
+ INIT_HLIST_HEAD(&empty_rp);
spin_lock_irqsave(&kretprobe_lock, flags);
head = kretprobe_inst_table_head(current);
@@ -369,7 +370,7 @@ int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs)
ri->rp->handler(ri, regs);
orig_ret_address = (unsigned long)ri->ret_addr;
- recycle_rp_inst(ri);
+ recycle_rp_inst(ri, &empty_rp);
if (orig_ret_address != trampoline_address)
/*
@@ -387,6 +388,10 @@ int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs)
spin_unlock_irqrestore(&kretprobe_lock, flags);
preempt_enable_no_resched();
+ hlist_for_each_entry_safe(ri, node, tmp, &empty_rp, hlist) {
+ hlist_del(&ri->hlist);
+ kfree(ri);
+ }
/*
* By returning a non-zero value, we are telling
* kprobe_handler() that we don't want the post_handler
@@ -424,14 +429,14 @@ int __kprobes arch_prepare_kprobe(struct kprobe *p)
bundle_t *bundle;
bundle = &((kprobe_opcode_t *)kprobe_addr)->bundle;
- template = bundle->quad0.template;
+ template = bundle->quad0.template;
if(valid_kprobe_addr(template, slot, addr))
return -EINVAL;
/* Move to slot 2, if bundle is MLX type and kprobe slot is 1 */
- if (slot == 1 && bundle_encoding[template][1] == L)
- slot++;
+ if (slot == 1 && bundle_encoding[template][1] == L)
+ slot++;
/* Get kprobe_inst and major_opcode from the bundle */
get_kprobe_inst(bundle, slot, &kprobe_inst, &major_opcode);
@@ -489,21 +494,22 @@ void __kprobes arch_remove_kprobe(struct kprobe *p)
*/
static void __kprobes resume_execution(struct kprobe *p, struct pt_regs *regs)
{
- unsigned long bundle_addr = (unsigned long) (&p->ainsn.insn->bundle);
- unsigned long resume_addr = (unsigned long)p->addr & ~0xFULL;
- unsigned long template;
- int slot = ((unsigned long)p->addr & 0xf);
+ unsigned long bundle_addr = (unsigned long) (&p->ainsn.insn->bundle);
+ unsigned long resume_addr = (unsigned long)p->addr & ~0xFULL;
+ unsigned long template;
+ int slot = ((unsigned long)p->addr & 0xf);
template = p->ainsn.insn->bundle.quad0.template;
- if (slot == 1 && bundle_encoding[template][1] == L)
- slot = 2;
+ if (slot == 1 && bundle_encoding[template][1] == L)
+ slot = 2;
if (p->ainsn.inst_flag) {
if (p->ainsn.inst_flag & INST_FLAG_FIX_RELATIVE_IP_ADDR) {
/* Fix relative IP address */
- regs->cr_iip = (regs->cr_iip - bundle_addr) + resume_addr;
+ regs->cr_iip = (regs->cr_iip - bundle_addr) +
+ resume_addr;
}
if (p->ainsn.inst_flag & INST_FLAG_FIX_BRANCH_REG) {
@@ -540,18 +546,18 @@ static void __kprobes resume_execution(struct kprobe *p, struct pt_regs *regs)
}
if (slot == 2) {
- if (regs->cr_iip == bundle_addr + 0x10) {
- regs->cr_iip = resume_addr + 0x10;
- }
- } else {
- if (regs->cr_iip == bundle_addr) {
- regs->cr_iip = resume_addr;
- }
+ if (regs->cr_iip == bundle_addr + 0x10) {
+ regs->cr_iip = resume_addr + 0x10;
+ }
+ } else {
+ if (regs->cr_iip == bundle_addr) {
+ regs->cr_iip = resume_addr;
+ }
}
turn_ss_off:
- /* Turn off Single Step bit */
- ia64_psr(regs)->ss = 0;
+ /* Turn off Single Step bit */
+ ia64_psr(regs)->ss = 0;
}
static void __kprobes prepare_ss(struct kprobe *p, struct pt_regs *regs)
@@ -587,7 +593,7 @@ static int __kprobes is_ia64_break_inst(struct pt_regs *regs)
/* Move to slot 2, if bundle is MLX type and kprobe slot is 1 */
if (slot == 1 && bundle_encoding[template][1] == L)
- slot++;
+ slot++;
/* Get Kprobe probe instruction at given slot*/
get_kprobe_inst(&bundle, slot, &kprobe_inst, &major_opcode);
@@ -627,7 +633,7 @@ static int __kprobes pre_kprobes_handler(struct die_args *args)
if (p) {
if ((kcb->kprobe_status == KPROBE_HIT_SS) &&
(p->ainsn.inst_flag == INST_FLAG_BREAK_INST)) {
- ia64_psr(regs)->ss = 0;
+ ia64_psr(regs)->ss = 0;
goto no_kprobe;
}
/* We have reentered the pre_kprobe_handler(), since
@@ -887,7 +893,7 @@ int __kprobes setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs)
* fix the return address to our jprobe_inst_return() function
* in the jprobes.S file
*/
- regs->b0 = ((struct fnptr *)(jprobe_inst_return))->ip;
+ regs->b0 = ((struct fnptr *)(jprobe_inst_return))->ip;
return 1;
}
diff --git a/arch/ia64/kernel/mca.c b/arch/ia64/kernel/mca.c
index bfbd8986153b..663230183254 100644
--- a/arch/ia64/kernel/mca.c
+++ b/arch/ia64/kernel/mca.c
@@ -388,7 +388,7 @@ ia64_log_get(int sal_info_type, u8 **buffer, int irq_safe)
{
sal_log_record_header_t *log_buffer;
u64 total_len = 0;
- int s;
+ unsigned long s;
IA64_LOG_LOCK(sal_info_type);
diff --git a/arch/ia64/kernel/numa.c b/arch/ia64/kernel/numa.c
index 20340631179f..a78b45f5fe2f 100644
--- a/arch/ia64/kernel/numa.c
+++ b/arch/ia64/kernel/numa.c
@@ -28,6 +28,7 @@ u16 cpu_to_node_map[NR_CPUS] __cacheline_aligned;
EXPORT_SYMBOL(cpu_to_node_map);
cpumask_t node_to_cpu_mask[MAX_NUMNODES] __cacheline_aligned;
+EXPORT_SYMBOL(node_to_cpu_mask);
void __cpuinit map_cpu_to_node(int cpu, int nid)
{
diff --git a/arch/ia64/kernel/process.c b/arch/ia64/kernel/process.c
index ea914cc6812a..51922b98086a 100644
--- a/arch/ia64/kernel/process.c
+++ b/arch/ia64/kernel/process.c
@@ -8,8 +8,6 @@
* 2005-10-07 Keith Owens <kaos@sgi.com>
* Add notify_die() hooks.
*/
-#define __KERNEL_SYSCALLS__ /* see <asm/unistd.h> */
-
#include <linux/cpu.h>
#include <linux/pm.h>
#include <linux/elf.h>
diff --git a/arch/ia64/kernel/setup.c b/arch/ia64/kernel/setup.c
index 84f93c0f2c66..c4caa8003492 100644
--- a/arch/ia64/kernel/setup.c
+++ b/arch/ia64/kernel/setup.c
@@ -54,7 +54,6 @@
#include <asm/processor.h>
#include <asm/sal.h>
#include <asm/sections.h>
-#include <asm/serial.h>
#include <asm/setup.h>
#include <asm/smp.h>
#include <asm/system.h>
diff --git a/arch/ia64/kernel/time.c b/arch/ia64/kernel/time.c
index 6928ef0d64d8..62e07f906e05 100644
--- a/arch/ia64/kernel/time.c
+++ b/arch/ia64/kernel/time.c
@@ -29,8 +29,6 @@
#include <asm/sections.h>
#include <asm/system.h>
-extern unsigned long wall_jiffies;
-
volatile int time_keeper_id = 0; /* smp_processor_id() of time-keeper */
#ifdef CONFIG_IA64_DEBUG_IRQ
@@ -78,7 +76,7 @@ timer_interrupt (int irq, void *dev_id, struct pt_regs *regs)
* xtime_lock.
*/
write_seqlock(&xtime_lock);
- do_timer(regs);
+ do_timer(1);
local_cpu_data->itm_next = new_itm;
write_sequnlock(&xtime_lock);
} else
diff --git a/arch/ia64/mm/fault.c b/arch/ia64/mm/fault.c
index 14ef7cceb208..59f3ab937615 100644
--- a/arch/ia64/mm/fault.c
+++ b/arch/ia64/mm/fault.c
@@ -146,9 +146,11 @@ ia64_do_page_fault (unsigned long address, unsigned long isr, struct pt_regs *re
# error File is out of sync with <linux/mm.h>. Please update.
# endif
+ if (((isr >> IA64_ISR_R_BIT) & 1UL) && (!(vma->vm_flags & (VM_READ | VM_WRITE))))
+ goto bad_area;
+
mask = ( (((isr >> IA64_ISR_X_BIT) & 1UL) << VM_EXEC_BIT)
- | (((isr >> IA64_ISR_W_BIT) & 1UL) << VM_WRITE_BIT)
- | (((isr >> IA64_ISR_R_BIT) & 1UL) << VM_READ_BIT));
+ | (((isr >> IA64_ISR_W_BIT) & 1UL) << VM_WRITE_BIT));
if ((vma->vm_flags & mask) != mask)
goto bad_area;
@@ -278,7 +280,7 @@ ia64_do_page_fault (unsigned long address, unsigned long isr, struct pt_regs *re
out_of_memory:
up_read(&mm->mmap_sem);
- if (current->pid == 1) {
+ if (is_init(current)) {
yield();
down_read(&mm->mmap_sem);
goto survive;
diff --git a/arch/ia64/mm/numa.c b/arch/ia64/mm/numa.c
index 64e4c21f311c..7807fc5c0422 100644
--- a/arch/ia64/mm/numa.c
+++ b/arch/ia64/mm/numa.c
@@ -16,6 +16,7 @@
#include <linux/node.h>
#include <linux/init.h>
#include <linux/bootmem.h>
+#include <linux/module.h>
#include <asm/mmzone.h>
#include <asm/numa.h>
@@ -69,4 +70,21 @@ int early_pfn_to_nid(unsigned long pfn)
return 0;
}
+
+#ifdef CONFIG_MEMORY_HOTPLUG
+/*
+ * SRAT information is stored in node_memblk[], then we can use SRAT
+ * information at memory-hot-add if necessary.
+ */
+
+int memory_add_physaddr_to_nid(u64 addr)
+{
+ int nid = paddr_to_nid(addr);
+ if (nid < 0)
+ return 0;
+ return nid;
+}
+
+EXPORT_SYMBOL_GPL(memory_add_physaddr_to_nid);
+#endif
#endif
diff --git a/arch/ia64/sn/kernel/sn2/sn_hwperf.c b/arch/ia64/sn/kernel/sn2/sn_hwperf.c
index b632b9c1e3b3..462ea178f49a 100644
--- a/arch/ia64/sn/kernel/sn2/sn_hwperf.c
+++ b/arch/ia64/sn/kernel/sn2/sn_hwperf.c
@@ -423,7 +423,7 @@ static int sn_topology_show(struct seq_file *s, void *d)
"coherency_domain %d, "
"region_size %d\n",
- partid, system_utsname.nodename,
+ partid, utsname()->nodename,
shubtype ? "shub2" : "shub1",
(u64)nasid_mask << nasid_shift, nasid_msb, nasid_shift,
system_size, sharing_size, coher, region_size);
diff --git a/arch/ia64/sn/pci/pcibr/pcibr_ate.c b/arch/ia64/sn/pci/pcibr/pcibr_ate.c
index 1f0253bfe0a0..5eb1e1e078b4 100644
--- a/arch/ia64/sn/pci/pcibr/pcibr_ate.c
+++ b/arch/ia64/sn/pci/pcibr/pcibr_ate.c
@@ -160,7 +160,7 @@ void pcibr_ate_free(struct pcibus_info *pcibus_info, int index)
volatile u64 ate;
int count;
- u64 flags;
+ unsigned long flags;
if (pcibr_invalidate_ate) {
/* For debugging purposes, clear the valid bit in the ATE */
diff --git a/arch/ia64/sn/pci/pcibr/pcibr_dma.c b/arch/ia64/sn/pci/pcibr/pcibr_dma.c
index a86c7b945962..1ee977fb6ebb 100644
--- a/arch/ia64/sn/pci/pcibr/pcibr_dma.c
+++ b/arch/ia64/sn/pci/pcibr/pcibr_dma.c
@@ -237,7 +237,7 @@ void sn_dma_flush(u64 addr)
int is_tio;
int wid_num;
int i, j;
- u64 flags;
+ unsigned long flags;
u64 itte;
struct hubdev_info *hubinfo;
struct sn_flush_device_kernel *p;
diff --git a/arch/m32r/kernel/sys_m32r.c b/arch/m32r/kernel/sys_m32r.c
index a9cea32eb824..b567351f3c52 100644
--- a/arch/m32r/kernel/sys_m32r.c
+++ b/arch/m32r/kernel/sys_m32r.c
@@ -25,6 +25,8 @@
#include <asm/cachectl.h>
#include <asm/cacheflush.h>
#include <asm/ipc.h>
+#include <asm/syscall.h>
+#include <asm/unistd.h>
/*
* sys_tas() - test-and-set
@@ -205,7 +207,7 @@ asmlinkage int sys_uname(struct old_utsname * name)
if (!name)
return -EFAULT;
down_read(&uts_sem);
- err=copy_to_user(name, &system_utsname, sizeof (*name));
+ err = copy_to_user(name, utsname(), sizeof (*name));
up_read(&uts_sem);
return err?-EFAULT:0;
}
@@ -223,3 +225,21 @@ asmlinkage int sys_cachectl(char *addr, int nbytes, int op)
return -ENOSYS;
}
+/*
+ * Do a system call from kernel instead of calling sys_execve so we
+ * end up with proper pt_regs.
+ */
+int kernel_execve(const char *filename, char *const argv[], char *const envp[])
+{
+ register long __scno __asm__ ("r7") = __NR_execve;
+ register long __arg3 __asm__ ("r2") = (long)(envp);
+ register long __arg2 __asm__ ("r1") = (long)(argv);
+ register long __res __asm__ ("r0") = (long)(filename);
+ __asm__ __volatile__ (
+ "trap #" SYSCALL_VECTOR "|| nop"
+ : "=r" (__res)
+ : "r" (__scno), "0" (__res), "r" (__arg2),
+ "r" (__arg3)
+ : "memory");
+ return __res;
+}
diff --git a/arch/m32r/kernel/time.c b/arch/m32r/kernel/time.c
index ded0be07a476..d8af155db984 100644
--- a/arch/m32r/kernel/time.c
+++ b/arch/m32r/kernel/time.c
@@ -38,7 +38,6 @@ extern void send_IPI_allbutself(int, int);
extern void smp_local_timer_interrupt(struct pt_regs *);
#endif
-extern unsigned long wall_jiffies;
#define TICK_SIZE (tick_nsec / 1000)
/*
@@ -108,24 +107,17 @@ void do_gettimeofday(struct timeval *tv)
unsigned long max_ntp_tick = tick_usec - tickadj;
do {
- unsigned long lost;
-
seq = read_seqbegin(&xtime_lock);
usec = do_gettimeoffset();
- lost = jiffies - wall_jiffies;
/*
* If time_adjust is negative then NTP is slowing the clock
* so make sure not to go into next possible interval.
* Better to lose some accuracy than have time go backwards..
*/
- if (unlikely(time_adjust < 0)) {
+ if (unlikely(time_adjust < 0))
usec = min(usec, max_ntp_tick);
- if (lost)
- usec += lost * max_ntp_tick;
- } else if (unlikely(lost))
- usec += lost * tick_usec;
sec = xtime.tv_sec;
usec += (xtime.tv_nsec / 1000);
@@ -158,7 +150,6 @@ int do_settimeofday(struct timespec *tv)
* made, and then undo it!
*/
nsec -= do_gettimeoffset() * NSEC_PER_USEC;
- nsec -= (jiffies - wall_jiffies) * TICK_NSEC;
wtm_sec = wall_to_monotonic.tv_sec + (xtime.tv_sec - sec);
wtm_nsec = wall_to_monotonic.tv_nsec + (xtime.tv_nsec - nsec);
@@ -202,7 +193,7 @@ irqreturn_t timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
#ifndef CONFIG_SMP
profile_tick(CPU_PROFILING, regs);
#endif
- do_timer(regs);
+ do_timer(1);
#ifndef CONFIG_SMP
update_process_times(user_mode(regs));
diff --git a/arch/m32r/mm/fault.c b/arch/m32r/mm/fault.c
index dc18a33eefef..8d5f551b5754 100644
--- a/arch/m32r/mm/fault.c
+++ b/arch/m32r/mm/fault.c
@@ -299,7 +299,7 @@ no_context:
*/
out_of_memory:
up_read(&mm->mmap_sem);
- if (tsk->pid == 1) {
+ if (is_init(tsk)) {
yield();
down_read(&mm->mmap_sem);
goto survive;
diff --git a/arch/m32r/mm/ioremap.c b/arch/m32r/mm/ioremap.c
index a151849a605e..5152c4e6ac80 100644
--- a/arch/m32r/mm/ioremap.c
+++ b/arch/m32r/mm/ioremap.c
@@ -20,92 +20,8 @@
#include <asm/byteorder.h>
#include <linux/vmalloc.h>
-#include <asm/io.h>
+#include <linux/io.h>
#include <asm/pgalloc.h>
-#include <asm/cacheflush.h>
-#include <asm/tlbflush.h>
-
-static inline void
-remap_area_pte(pte_t * pte, unsigned long address, unsigned long size,
- unsigned long phys_addr, unsigned long flags)
-{
- unsigned long end;
- unsigned long pfn;
- pgprot_t pgprot = __pgprot(_PAGE_GLOBAL | _PAGE_PRESENT | _PAGE_READ
- | _PAGE_WRITE | flags);
-
- address &= ~PMD_MASK;
- end = address + size;
- if (end > PMD_SIZE)
- end = PMD_SIZE;
- if (address >= end)
- BUG();
- pfn = phys_addr >> PAGE_SHIFT;
- do {
- if (!pte_none(*pte)) {
- printk("remap_area_pte: page already exists\n");
- BUG();
- }
- set_pte(pte, pfn_pte(pfn, pgprot));
- address += PAGE_SIZE;
- pfn++;
- pte++;
- } while (address && (address < end));
-}
-
-static inline int
-remap_area_pmd(pmd_t * pmd, unsigned long address, unsigned long size,
- unsigned long phys_addr, unsigned long flags)
-{
- unsigned long end;
-
- address &= ~PGDIR_MASK;
- end = address + size;
- if (end > PGDIR_SIZE)
- end = PGDIR_SIZE;
- phys_addr -= address;
- if (address >= end)
- BUG();
- do {
- pte_t * pte = pte_alloc_kernel(pmd, address);
- if (!pte)
- return -ENOMEM;
- remap_area_pte(pte, address, end - address, address + phys_addr, flags);
- address = (address + PMD_SIZE) & PMD_MASK;
- pmd++;
- } while (address && (address < end));
- return 0;
-}
-
-static int
-remap_area_pages(unsigned long address, unsigned long phys_addr,
- unsigned long size, unsigned long flags)
-{
- int error;
- pgd_t * dir;
- unsigned long end = address + size;
-
- phys_addr -= address;
- dir = pgd_offset(&init_mm, address);
- flush_cache_all();
- if (address >= end)
- BUG();
- do {
- pmd_t *pmd;
- pmd = pmd_alloc(&init_mm, dir, address);
- error = -ENOMEM;
- if (!pmd)
- break;
- if (remap_area_pmd(pmd, address, end - address,
- phys_addr + address, flags))
- break;
- error = 0;
- address = (address + PGDIR_SIZE) & PGDIR_MASK;
- dir++;
- } while (address && (address < end));
- flush_tlb_all();
- return error;
-}
/*
* Generic mapping function (not visible outside):
@@ -129,6 +45,7 @@ __ioremap(unsigned long phys_addr, unsigned long size, unsigned long flags)
void __iomem * addr;
struct vm_struct * area;
unsigned long offset, last_addr;
+ pgprot_t pgprot;
/* Don't allow wraparound or zero size */
last_addr = phys_addr + size - 1;
@@ -157,6 +74,9 @@ __ioremap(unsigned long phys_addr, unsigned long size, unsigned long flags)
return NULL;
}
+ pgprot = __pgprot(_PAGE_GLOBAL | _PAGE_PRESENT | _PAGE_READ
+ | _PAGE_WRITE | flags);
+
/*
* Mappings have to be page-aligned
*/
@@ -172,7 +92,8 @@ __ioremap(unsigned long phys_addr, unsigned long size, unsigned long flags)
return NULL;
area->phys_addr = phys_addr;
addr = (void __iomem *) area->addr;
- if (remap_area_pages((unsigned long)addr, phys_addr, size, flags)) {
+ if (ioremap_page_range((unsigned long)addr, (unsigned long)addr + size,
+ phys_addr, pgprot)) {
vunmap((void __force *) addr);
return NULL;
}
diff --git a/arch/m68k/kernel/sys_m68k.c b/arch/m68k/kernel/sys_m68k.c
index 143c552d38f3..90238a8c9e14 100644
--- a/arch/m68k/kernel/sys_m68k.c
+++ b/arch/m68k/kernel/sys_m68k.c
@@ -27,6 +27,7 @@
#include <asm/traps.h>
#include <asm/ipc.h>
#include <asm/page.h>
+#include <asm/unistd.h>
/*
* sys_pipe() is the normal C calling standard for creating
@@ -663,3 +664,18 @@ asmlinkage int sys_getpagesize(void)
{
return PAGE_SIZE;
}
+
+/*
+ * Do a system call from kernel instead of calling sys_execve so we
+ * end up with proper pt_regs.
+ */
+int kernel_execve(const char *filename, char *const argv[], char *const envp[])
+{
+ register long __res asm ("%d0") = __NR_execve;
+ register long __a asm ("%d1") = (long)(filename);
+ register long __b asm ("%d2") = (long)(argv);
+ register long __c asm ("%d3") = (long)(envp);
+ asm volatile ("trap #0" : "+d" (__res)
+ : "d" (__a), "d" (__b), "d" (__c));
+ return __res;
+}
diff --git a/arch/m68k/kernel/time.c b/arch/m68k/kernel/time.c
index 98e4b1adfa29..6cfc984380d9 100644
--- a/arch/m68k/kernel/time.c
+++ b/arch/m68k/kernel/time.c
@@ -40,7 +40,7 @@ static inline int set_rtc_mmss(unsigned long nowtime)
*/
static irqreturn_t timer_interrupt(int irq, void *dummy, struct pt_regs * regs)
{
- do_timer(regs);
+ do_timer(1);
#ifndef CONFIG_SMP
update_process_times(user_mode(regs));
#endif
@@ -96,31 +96,23 @@ void time_init(void)
void do_gettimeofday(struct timeval *tv)
{
unsigned long flags;
- extern unsigned long wall_jiffies;
unsigned long seq;
- unsigned long usec, sec, lost;
+ unsigned long usec, sec;
unsigned long max_ntp_tick = tick_usec - tickadj;
do {
seq = read_seqbegin_irqsave(&xtime_lock, flags);
usec = mach_gettimeoffset();
- lost = jiffies - wall_jiffies;
/*
* If time_adjust is negative then NTP is slowing the clock
* so make sure not to go into next possible interval.
* Better to lose some accuracy than have time go backwards..
*/
- if (unlikely(time_adjust < 0)) {
+ if (unlikely(time_adjust < 0))
usec = min(usec, max_ntp_tick);
- if (lost)
- usec += lost * max_ntp_tick;
- }
- else if (unlikely(lost))
- usec += lost * tick_usec;
-
sec = xtime.tv_sec;
usec += xtime.tv_nsec/1000;
} while (read_seqretry_irqrestore(&xtime_lock, seq, flags));
@@ -141,7 +133,6 @@ int do_settimeofday(struct timespec *tv)
{
time_t wtm_sec, sec = tv->tv_sec;
long wtm_nsec, nsec = tv->tv_nsec;
- extern unsigned long wall_jiffies;
if ((unsigned long)tv->tv_nsec >= NSEC_PER_SEC)
return -EINVAL;
@@ -153,8 +144,7 @@ int do_settimeofday(struct timespec *tv)
* Discover what correction gettimeofday
* would have done, and then undo it!
*/
- nsec -= 1000 * (mach_gettimeoffset() +
- (jiffies - wall_jiffies) * (1000000 / HZ));
+ nsec -= 1000 * mach_gettimeoffset();
wtm_sec = wall_to_monotonic.tv_sec + (xtime.tv_sec - sec);
wtm_nsec = wall_to_monotonic.tv_nsec + (xtime.tv_nsec - nsec);
diff --git a/arch/m68k/mm/fault.c b/arch/m68k/mm/fault.c
index aec15270d334..911f2ce3f53e 100644
--- a/arch/m68k/mm/fault.c
+++ b/arch/m68k/mm/fault.c
@@ -144,7 +144,7 @@ good_area:
case 1: /* read, present */
goto acc_err;
case 0: /* read, not present */
- if (!(vma->vm_flags & (VM_READ | VM_EXEC)))
+ if (!(vma->vm_flags & (VM_READ | VM_EXEC | VM_WRITE)))
goto acc_err;
}
@@ -181,7 +181,7 @@ good_area:
*/
out_of_memory:
up_read(&mm->mmap_sem);
- if (current->pid == 1) {
+ if (is_init(current)) {
yield();
down_read(&mm->mmap_sem);
goto survive;
diff --git a/arch/m68k/sun3/sun3ints.c b/arch/m68k/sun3/sun3ints.c
index f18b9d3ef16d..dc4ea7e074a6 100644
--- a/arch/m68k/sun3/sun3ints.c
+++ b/arch/m68k/sun3/sun3ints.c
@@ -65,7 +65,7 @@ static irqreturn_t sun3_int5(int irq, void *dev_id, struct pt_regs *fp)
#ifdef CONFIG_SUN3
intersil_clear();
#endif
- do_timer(fp);
+ do_timer(1);
#ifndef CONFIG_SMP
update_process_times(user_mode(fp));
#endif
diff --git a/arch/m68knommu/kernel/sys_m68k.c b/arch/m68knommu/kernel/sys_m68k.c
index d87e1e0a1336..c3494b8447d1 100644
--- a/arch/m68knommu/kernel/sys_m68k.c
+++ b/arch/m68knommu/kernel/sys_m68k.c
@@ -26,6 +26,7 @@
#include <asm/traps.h>
#include <asm/ipc.h>
#include <asm/cacheflush.h>
+#include <asm/unistd.h>
/*
* sys_pipe() is the normal C calling standard for creating
@@ -206,3 +207,17 @@ asmlinkage int sys_getpagesize(void)
return PAGE_SIZE;
}
+/*
+ * Do a system call from kernel instead of calling sys_execve so we
+ * end up with proper pt_regs.
+ */
+int kernel_execve(const char *filename, char *const argv[], char *const envp[])
+{
+ register long __res asm ("%d0") = __NR_execve;
+ register long __a asm ("%d1") = (long)(filename);
+ register long __b asm ("%d2") = (long)(argv);
+ register long __c asm ("%d3") = (long)(envp);
+ asm volatile ("trap #0" : "+d" (__res)
+ : "d" (__a), "d" (__b), "d" (__c));
+ return __res;
+}
diff --git a/arch/m68knommu/kernel/time.c b/arch/m68knommu/kernel/time.c
index 1db987272220..c5667bdddd5e 100644
--- a/arch/m68knommu/kernel/time.c
+++ b/arch/m68knommu/kernel/time.c
@@ -26,8 +26,6 @@
#define TICK_SIZE (tick_nsec / 1000)
-extern unsigned long wall_jiffies;
-
static inline int set_rtc_mmss(unsigned long nowtime)
{
@@ -51,7 +49,7 @@ static irqreturn_t timer_interrupt(int irq, void *dummy, struct pt_regs * regs)
write_seqlock(&xtime_lock);
- do_timer(regs);
+ do_timer(1);
#ifndef CONFIG_SMP
update_process_times(user_mode(regs));
#endif
@@ -124,15 +122,12 @@ void time_init(void)
void do_gettimeofday(struct timeval *tv)
{
unsigned long flags;
- unsigned long lost, seq;
+ unsigned long seq;
unsigned long usec, sec;
do {
seq = read_seqbegin_irqsave(&xtime_lock, flags);
usec = mach_gettimeoffset ? mach_gettimeoffset() : 0;
- lost = jiffies - wall_jiffies;
- if (lost)
- usec += lost * (1000000 / HZ);
sec = xtime.tv_sec;
usec += (xtime.tv_nsec / 1000);
} while (read_seqretry_irqrestore(&xtime_lock, seq, flags));
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index 30750c54bdf5..87cee341eb54 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -537,6 +537,7 @@ config QEMU
select SYS_HAS_CPU_MIPS32_R1
select SYS_SUPPORTS_32BIT_KERNEL
select SYS_SUPPORTS_BIG_ENDIAN
+ select SYS_SUPPORTS_LITTLE_ENDIAN
select ARCH_SPARSEMEM_ENABLE
help
Qemu is a software emulator which among other architectures also
@@ -1841,6 +1842,14 @@ config RWSEM_GENERIC_SPINLOCK
bool
default y
+config LOCKDEP_SUPPORT
+ bool
+ default y
+
+config STACKTRACE_SUPPORT
+ bool
+ default y
+
source "init/Kconfig"
menu "Bus options (PCI, PCMCIA, EISA, ISA, TC)"
diff --git a/arch/mips/au1000/common/time.c b/arch/mips/au1000/common/time.c
index 7fbea1bf7b48..0a067f3113a5 100644
--- a/arch/mips/au1000/common/time.c
+++ b/arch/mips/au1000/common/time.c
@@ -96,7 +96,7 @@ void mips_timer_interrupt(struct pt_regs *regs)
timerlo = count;
kstat_this_cpu.irqs[irq]++;
- do_timer(regs);
+ do_timer(1);
#ifndef CONFIG_SMP
update_process_times(user_mode(regs));
#endif
@@ -137,7 +137,7 @@ irqreturn_t counter0_irq(int irq, void *dev_id, struct pt_regs *regs)
}
while (time_elapsed > 0) {
- do_timer(regs);
+ do_timer(1);
#ifndef CONFIG_SMP
update_process_times(user_mode(regs));
#endif
@@ -156,7 +156,7 @@ irqreturn_t counter0_irq(int irq, void *dev_id, struct pt_regs *regs)
if (jiffie_drift >= 999) {
jiffie_drift -= 999;
- do_timer(regs); /* increment jiffies by one */
+ do_timer(1); /* increment jiffies by one */
#ifndef CONFIG_SMP
update_process_times(user_mode(regs));
#endif
diff --git a/arch/mips/basler/excite/excite_flashtest.c b/arch/mips/basler/excite/excite_flashtest.c
deleted file mode 100644
index f0024a8e3294..000000000000
--- a/arch/mips/basler/excite/excite_flashtest.c
+++ /dev/null
@@ -1,294 +0,0 @@
-/*
-* Copyright (C) 2005 by Basler Vision Technologies AG
-* Author: Thies Moeller <thies.moeller@baslerweb.com>
-*
-* This program is free software; you can redistribute it and/or modify
-* it under the terms of the GNU General Public License as published by
-* the Free Software Foundation; either version 2 of the License, or
-* (at your option) any later version.
-*
-* This program is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-* GNU General Public License for more details.
-*
-* You should have received a copy of the GNU General Public License
-* along with this program; if not, write to the Free Software
-* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-*/
-
-#include <linux/module.h>
-#include <linux/types.h>
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/string.h>
-#include <linux/ioport.h>
-#include <linux/device.h>
-#include <linux/delay.h>
-#include <linux/err.h>
-#include <linux/kernel.h>
-
-#include <excite.h>
-
-#include <asm/io.h>
-
-#include <linux/mtd/mtd.h>
-#include <linux/mtd/nand.h>
-#include <linux/mtd/nand_ecc.h>
-#include <linux/mtd/partitions.h>
-#include <asm/rm9k-ocd.h> // for ocd_write
-#include <linux/workqueue.h> // for queue
-
-#include "excite_nandflash.h"
-#include "nandflash.h"
-
-#define PFX "excite flashtest: "
-typedef void __iomem *io_reg_t;
-
-#define io_readb(__a__) __raw_readb((__a__))
-#define io_writeb(__v__, __a__) __raw_writeb((__v__), (__a__))
-
-
-
-static inline const struct resource *excite_nandflash_get_resource(
- struct platform_device *d, unsigned long flags, const char *basename)
-{
- const char fmt[] = "%s_%u";
- char buf[80];
-
- if (unlikely(snprintf(buf, sizeof buf, fmt, basename, d->id) >= sizeof buf))
- return NULL;
-
- return platform_get_resource_byname(d, flags, buf);
-}
-
-static inline io_reg_t
-excite_nandflash_map_regs(struct platform_device *d, const char *basename)
-{
- void *result = NULL;
- const struct resource *const r =
- excite_nandflash_get_resource(d, IORESOURCE_MEM, basename);
- if (r)
- result = ioremap_nocache(r->start, r->end + 1 - r->start);
- return result;
-}
-
-/* controller and mtd information */
-
-struct excite_nandflash_drvdata {
- struct mtd_info board_mtd;
- struct nand_chip board_chip;
- io_reg_t regs;
-};
-
-
-/* command and control functions */
-static void excite_nandflash_hwcontrol(struct mtd_info *mtd, int cmd)
-{
- struct nand_chip *this = mtd->priv;
- io_reg_t regs = container_of(mtd,struct excite_nandflash_drvdata,board_mtd)->regs;
-
- switch (cmd) {
- /* Select the command latch */
- case NAND_CTL_SETCLE: this->IO_ADDR_W = regs + EXCITE_NANDFLASH_CMD;
- break;
- /* Deselect the command latch */
- case NAND_CTL_CLRCLE: this->IO_ADDR_W = regs + EXCITE_NANDFLASH_DATA;
- break;
- /* Select the address latch */
- case NAND_CTL_SETALE: this->IO_ADDR_W = regs + EXCITE_NANDFLASH_ADDR;
- break;
- /* Deselect the address latch */
- case NAND_CTL_CLRALE: this->IO_ADDR_W = regs + EXCITE_NANDFLASH_DATA;
- break;
- /* Select the chip -- not used */
- case NAND_CTL_SETNCE:
- break;
- /* Deselect the chip -- not used */
- case NAND_CTL_CLRNCE:
- break;
- }
-
- this->IO_ADDR_R = this->IO_ADDR_W;
-}
-
-/* excite_nandflash_devready()
- *
- * returns 0 if the nand is busy, 1 if it is ready
- */
-static int excite_nandflash_devready(struct mtd_info *mtd)
-{
- struct excite_nandflash_drvdata *drvdata =
- container_of(mtd, struct excite_nandflash_drvdata, board_mtd);
-
- return io_readb(drvdata->regs + EXCITE_NANDFLASH_STATUS);
-}
-
-/* device management functions */
-
-/* excite_nandflash_remove
- *
- * called by device layer to remove the driver
- * the binding to the mtd and all allocated
- * resources are released
- */
-static int excite_nandflash_remove(struct device *dev)
-{
- struct excite_nandflash_drvdata *this = dev_get_drvdata(dev);
-
- pr_info(PFX "remove");
-
- dev_set_drvdata(dev, NULL);
-
- if (this == NULL) {
- pr_debug(PFX "call remove without private data!!");
- return 0;
- }
-
-
- /* free the common resources */
- if (this->regs != NULL) {
- iounmap(this->regs);
- this->regs = NULL;
- }
-
- kfree(this);
-
- return 0;
-}
-
-static int elapsed;
-
-void my_workqueue_handler(void *arg)
-{
- elapsed = 1;
-}
-
-DECLARE_WORK(sigElapsed, my_workqueue_handler, 0);
-
-
-/* excite_nandflash_probe
- *
- * called by device layer when it finds a device matching
- * one our driver can handled. This code checks to see if
- * it can allocate all necessary resources then calls the
- * nand layer to look for devices
-*/
-static int excite_nandflash_probe(struct device *dev)
-{
- struct platform_device *pdev = to_platform_device(dev);
-
- struct excite_nandflash_drvdata *drvdata; /* private driver data */
- struct nand_chip *board_chip; /* private flash chip data */
- struct mtd_info *board_mtd; /* mtd info for this board */
-
- int err = 0;
- int count = 0;
- struct timeval tv,endtv;
- unsigned int dt;
-
- pr_info(PFX "probe dev: (%p)\n", dev);
-
- pr_info(PFX "adjust LB timing\n");
- ocd_writel(0x00000330, LDP2);
-
- drvdata = kmalloc(sizeof(*drvdata), GFP_KERNEL);
- if (unlikely(!drvdata)) {
- printk(KERN_ERR PFX "no memory for drvdata\n");
- err = -ENOMEM;
- goto mem_error;
- }
-
- /* Initialize structures */
- memset(drvdata, 0, sizeof(*drvdata));
-
- /* bind private data into driver */
- dev_set_drvdata(dev, drvdata);
-
- /* allocate and map the resource */
- drvdata->regs =
- excite_nandflash_map_regs(pdev, EXCITE_NANDFLASH_RESOURCE_REGS);
-
- if (unlikely(!drvdata->regs)) {
- printk(KERN_ERR PFX "cannot reserve register region\n");
- err = -ENXIO;
- goto io_error;
- }
-
- /* initialise our chip */
- board_chip = &drvdata->board_chip;
-
- board_chip->IO_ADDR_R = drvdata->regs + EXCITE_NANDFLASH_DATA;
- board_chip->IO_ADDR_W = drvdata->regs + EXCITE_NANDFLASH_DATA;
-
- board_chip->hwcontrol = excite_nandflash_hwcontrol;
- board_chip->dev_ready = excite_nandflash_devready;
-
- board_chip->chip_delay = 25;
- #if 0
- /* TODO: speedup the initial scan */
- board_chip->options = NAND_USE_FLASH_BBT;
- #endif
- board_chip->eccmode = NAND_ECC_SOFT;
-
- /* link chip to mtd */
- board_mtd = &drvdata->board_mtd;
- board_mtd->priv = board_chip;
-
-
- pr_info(PFX "FlashTest\n");
- elapsed = 0;
-/* schedule_delayed_work(&sigElapsed, 1*HZ);
- while (!elapsed) {
- io_readb(drvdata->regs + EXCITE_NANDFLASH_STATUS);
- count++;
- }
- pr_info(PFX "reads in 1 sec --> %d\n",count);
-*/
- do_gettimeofday(&tv);
- for (count = 0 ; count < 1000000; count ++) {
- io_readb(drvdata->regs + EXCITE_NANDFLASH_STATUS);
- }
- do_gettimeofday(&endtv);
- dt = (endtv.tv_sec - tv.tv_sec) * 1000000 + endtv.tv_usec - tv.tv_usec;
- pr_info(PFX "%8d us timeval\n",dt);
- pr_info(PFX "EndFlashTest\n");
-
-/* return with error to unload everything
-*/
-io_error:
- iounmap(drvdata->regs);
-
-mem_error:
- kfree(drvdata);
-
- if (err == 0)
- err = -EINVAL;
- return err;
-}
-
-static struct device_driver excite_nandflash_driver = {
- .name = "excite_nand",
- .bus = &platform_bus_type,
- .probe = excite_nandflash_probe,
- .remove = excite_nandflash_remove,
-};
-
-static int __init excite_nandflash_init(void)
-{
- pr_info(PFX "register Driver (Rev: $Revision:$)\n");
- return driver_register(&excite_nandflash_driver);
-}
-
-static void __exit excite_nandflash_exit(void)
-{
- driver_unregister(&excite_nandflash_driver);
- pr_info(PFX "Driver unregistered");
-}
-
-module_init(excite_nandflash_init);
-module_exit(excite_nandflash_exit);
-
-MODULE_AUTHOR("Thies Moeller <thies.moeller@baslerweb.com>");
-MODULE_DESCRIPTION("Basler eXcite NAND-Flash driver");
-MODULE_LICENSE("GPL");
diff --git a/arch/mips/cobalt/setup.c b/arch/mips/cobalt/setup.c
index c01a0170e590..0b347cffc768 100644
--- a/arch/mips/cobalt/setup.c
+++ b/arch/mips/cobalt/setup.c
@@ -23,7 +23,6 @@
#include <asm/processor.h>
#include <asm/reboot.h>
#include <asm/gt64120.h>
-#include <asm/serial.h>
#include <asm/mach-cobalt/cobalt.h>
diff --git a/arch/mips/configs/atlas_defconfig b/arch/mips/configs/atlas_defconfig
index d3705284de39..35931bedc3df 100644
--- a/arch/mips/configs/atlas_defconfig
+++ b/arch/mips/configs/atlas_defconfig
@@ -161,6 +161,8 @@ CONFIG_HZ=100
CONFIG_PREEMPT_NONE=y
# CONFIG_PREEMPT_VOLUNTARY is not set
# CONFIG_PREEMPT is not set
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
#
@@ -1304,6 +1306,7 @@ CONFIG_NLS_UTF8=m
#
# Kernel hacking
#
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
# CONFIG_PRINTK_TIME is not set
# CONFIG_MAGIC_SYSRQ is not set
# CONFIG_UNUSED_SYMBOLS is not set
diff --git a/arch/mips/configs/bigsur_defconfig b/arch/mips/configs/bigsur_defconfig
index e12a475dcbf4..c6a015940b41 100644
--- a/arch/mips/configs/bigsur_defconfig
+++ b/arch/mips/configs/bigsur_defconfig
@@ -167,6 +167,8 @@ CONFIG_PREEMPT_NONE=y
# CONFIG_PREEMPT_VOLUNTARY is not set
# CONFIG_PREEMPT is not set
# CONFIG_PREEMPT_BKL is not set
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
#
@@ -904,6 +906,7 @@ CONFIG_MSDOS_PARTITION=y
#
# Kernel hacking
#
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
CONFIG_PRINTK_TIME=y
CONFIG_MAGIC_SYSRQ=y
# CONFIG_UNUSED_SYMBOLS is not set
diff --git a/arch/mips/configs/capcella_defconfig b/arch/mips/configs/capcella_defconfig
index bfade9abb767..e5358121d2da 100644
--- a/arch/mips/configs/capcella_defconfig
+++ b/arch/mips/configs/capcella_defconfig
@@ -149,6 +149,8 @@ CONFIG_HZ=1000
CONFIG_PREEMPT_NONE=y
# CONFIG_PREEMPT_VOLUNTARY is not set
# CONFIG_PREEMPT is not set
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
#
@@ -891,6 +893,7 @@ CONFIG_MSDOS_PARTITION=y
#
# Kernel hacking
#
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
# CONFIG_PRINTK_TIME is not set
# CONFIG_MAGIC_SYSRQ is not set
# CONFIG_UNUSED_SYMBOLS is not set
diff --git a/arch/mips/configs/cobalt_defconfig b/arch/mips/configs/cobalt_defconfig
index 4baf2ff1128a..adf1e8c98c65 100644
--- a/arch/mips/configs/cobalt_defconfig
+++ b/arch/mips/configs/cobalt_defconfig
@@ -146,6 +146,8 @@ CONFIG_HZ=1000
CONFIG_PREEMPT_NONE=y
# CONFIG_PREEMPT_VOLUNTARY is not set
# CONFIG_PREEMPT is not set
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
#
@@ -889,6 +891,7 @@ CONFIG_MSDOS_PARTITION=y
#
# Kernel hacking
#
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
# CONFIG_PRINTK_TIME is not set
# CONFIG_MAGIC_SYSRQ is not set
# CONFIG_UNUSED_SYMBOLS is not set
diff --git a/arch/mips/configs/db1000_defconfig b/arch/mips/configs/db1000_defconfig
index 93cca1585bc3..4fd29ffdfb8d 100644
--- a/arch/mips/configs/db1000_defconfig
+++ b/arch/mips/configs/db1000_defconfig
@@ -147,6 +147,8 @@ CONFIG_HZ=1000
CONFIG_PREEMPT_NONE=y
# CONFIG_PREEMPT_VOLUNTARY is not set
# CONFIG_PREEMPT is not set
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
#
@@ -1006,6 +1008,7 @@ CONFIG_NLS_DEFAULT="iso8859-1"
#
# Kernel hacking
#
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
# CONFIG_PRINTK_TIME is not set
# CONFIG_MAGIC_SYSRQ is not set
# CONFIG_UNUSED_SYMBOLS is not set
diff --git a/arch/mips/configs/db1100_defconfig b/arch/mips/configs/db1100_defconfig
index ffd99252a837..025b960ba990 100644
--- a/arch/mips/configs/db1100_defconfig
+++ b/arch/mips/configs/db1100_defconfig
@@ -147,6 +147,8 @@ CONFIG_HZ=1000
CONFIG_PREEMPT_NONE=y
# CONFIG_PREEMPT_VOLUNTARY is not set
# CONFIG_PREEMPT is not set
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
#
@@ -1006,6 +1008,7 @@ CONFIG_NLS_DEFAULT="iso8859-1"
#
# Kernel hacking
#
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
# CONFIG_PRINTK_TIME is not set
# CONFIG_MAGIC_SYSRQ is not set
# CONFIG_UNUSED_SYMBOLS is not set
diff --git a/arch/mips/configs/db1200_defconfig b/arch/mips/configs/db1200_defconfig
index 63eac5e89b9c..80c9dd98f897 100644
--- a/arch/mips/configs/db1200_defconfig
+++ b/arch/mips/configs/db1200_defconfig
@@ -147,6 +147,8 @@ CONFIG_HZ=1000
CONFIG_PREEMPT_NONE=y
# CONFIG_PREEMPT_VOLUNTARY is not set
# CONFIG_PREEMPT is not set
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
#
@@ -1087,6 +1089,7 @@ CONFIG_NLS_UTF8=m
#
# Kernel hacking
#
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
# CONFIG_PRINTK_TIME is not set
# CONFIG_MAGIC_SYSRQ is not set
# CONFIG_UNUSED_SYMBOLS is not set
diff --git a/arch/mips/configs/db1500_defconfig b/arch/mips/configs/db1500_defconfig
index 25a095f7dc4e..6caa90b0e176 100644
--- a/arch/mips/configs/db1500_defconfig
+++ b/arch/mips/configs/db1500_defconfig
@@ -149,6 +149,8 @@ CONFIG_HZ=1000
CONFIG_PREEMPT_NONE=y
# CONFIG_PREEMPT_VOLUNTARY is not set
# CONFIG_PREEMPT is not set
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
#
@@ -1290,6 +1292,7 @@ CONFIG_NLS_DEFAULT="iso8859-1"
#
# Kernel hacking
#
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
# CONFIG_PRINTK_TIME is not set
# CONFIG_MAGIC_SYSRQ is not set
# CONFIG_UNUSED_SYMBOLS is not set
diff --git a/arch/mips/configs/db1550_defconfig b/arch/mips/configs/db1550_defconfig
index dda469c842b3..c6cae86c6ab7 100644
--- a/arch/mips/configs/db1550_defconfig
+++ b/arch/mips/configs/db1550_defconfig
@@ -148,6 +148,8 @@ CONFIG_HZ=1000
CONFIG_PREEMPT_NONE=y
# CONFIG_PREEMPT_VOLUNTARY is not set
# CONFIG_PREEMPT is not set
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
#
@@ -1111,6 +1113,7 @@ CONFIG_NLS_DEFAULT="iso8859-1"
#
# Kernel hacking
#
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
# CONFIG_PRINTK_TIME is not set
# CONFIG_MAGIC_SYSRQ is not set
# CONFIG_UNUSED_SYMBOLS is not set
diff --git a/arch/mips/configs/ddb5477_defconfig b/arch/mips/configs/ddb5477_defconfig
index fcd3dd19bc74..72f24001c99e 100644
--- a/arch/mips/configs/ddb5477_defconfig
+++ b/arch/mips/configs/ddb5477_defconfig
@@ -146,6 +146,8 @@ CONFIG_HZ=1000
CONFIG_PREEMPT_NONE=y
# CONFIG_PREEMPT_VOLUNTARY is not set
# CONFIG_PREEMPT is not set
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
#
@@ -852,6 +854,7 @@ CONFIG_MSDOS_PARTITION=y
#
# Kernel hacking
#
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
# CONFIG_PRINTK_TIME is not set
# CONFIG_MAGIC_SYSRQ is not set
# CONFIG_UNUSED_SYMBOLS is not set
diff --git a/arch/mips/configs/decstation_defconfig b/arch/mips/configs/decstation_defconfig
index 8683e0df12e0..be901df7fefa 100644
--- a/arch/mips/configs/decstation_defconfig
+++ b/arch/mips/configs/decstation_defconfig
@@ -147,6 +147,8 @@ CONFIG_HZ=128
CONFIG_PREEMPT_NONE=y
# CONFIG_PREEMPT_VOLUNTARY is not set
# CONFIG_PREEMPT is not set
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
#
@@ -828,6 +830,7 @@ CONFIG_ULTRIX_PARTITION=y
#
# Kernel hacking
#
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
# CONFIG_PRINTK_TIME is not set
CONFIG_MAGIC_SYSRQ=y
# CONFIG_UNUSED_SYMBOLS is not set
diff --git a/arch/mips/configs/e55_defconfig b/arch/mips/configs/e55_defconfig
index 4ace61c95778..6133c28beb8c 100644
--- a/arch/mips/configs/e55_defconfig
+++ b/arch/mips/configs/e55_defconfig
@@ -147,6 +147,8 @@ CONFIG_HZ=1000
CONFIG_PREEMPT_NONE=y
# CONFIG_PREEMPT_VOLUNTARY is not set
# CONFIG_PREEMPT is not set
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
#
diff --git a/arch/mips/configs/emma2rh_defconfig b/arch/mips/configs/emma2rh_defconfig
index 5847c916c130..a484b7d396fc 100644
--- a/arch/mips/configs/emma2rh_defconfig
+++ b/arch/mips/configs/emma2rh_defconfig
@@ -147,6 +147,8 @@ CONFIG_HZ=1000
# CONFIG_PREEMPT_VOLUNTARY is not set
CONFIG_PREEMPT=y
CONFIG_PREEMPT_BKL=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
#
@@ -1180,6 +1182,7 @@ CONFIG_NLS_UTF8=m
#
# Kernel hacking
#
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
# CONFIG_PRINTK_TIME is not set
# CONFIG_MAGIC_SYSRQ is not set
# CONFIG_UNUSED_SYMBOLS is not set
diff --git a/arch/mips/configs/ev64120_defconfig b/arch/mips/configs/ev64120_defconfig
index bc4c4f125c48..21bfcdebf8f5 100644
--- a/arch/mips/configs/ev64120_defconfig
+++ b/arch/mips/configs/ev64120_defconfig
@@ -148,6 +148,8 @@ CONFIG_HZ=1000
CONFIG_PREEMPT_NONE=y
# CONFIG_PREEMPT_VOLUNTARY is not set
# CONFIG_PREEMPT is not set
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
#
@@ -842,6 +844,7 @@ CONFIG_MSDOS_PARTITION=y
#
# Kernel hacking
#
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
# CONFIG_PRINTK_TIME is not set
# CONFIG_MAGIC_SYSRQ is not set
# CONFIG_UNUSED_SYMBOLS is not set
diff --git a/arch/mips/configs/excite_defconfig b/arch/mips/configs/excite_defconfig
index eb87cbbfd037..1a5b06cfb4d6 100644
--- a/arch/mips/configs/excite_defconfig
+++ b/arch/mips/configs/excite_defconfig
@@ -149,6 +149,8 @@ CONFIG_HZ=1000
# CONFIG_PREEMPT_VOLUNTARY is not set
CONFIG_PREEMPT=y
CONFIG_PREEMPT_BKL=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
#
@@ -1184,6 +1186,7 @@ CONFIG_NLS_ISO8859_1=m
#
# Kernel hacking
#
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
# CONFIG_PRINTK_TIME is not set
# CONFIG_MAGIC_SYSRQ is not set
# CONFIG_UNUSED_SYMBOLS is not set
diff --git a/arch/mips/configs/ip22_defconfig b/arch/mips/configs/ip22_defconfig
index cc9b24eda9e8..21d53e0c9ee8 100644
--- a/arch/mips/configs/ip22_defconfig
+++ b/arch/mips/configs/ip22_defconfig
@@ -153,6 +153,8 @@ CONFIG_HZ=1000
# CONFIG_PREEMPT_NONE is not set
CONFIG_PREEMPT_VOLUNTARY=y
# CONFIG_PREEMPT is not set
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
#
@@ -1147,6 +1149,7 @@ CONFIG_NLS_UTF8=m
#
# Kernel hacking
#
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
# CONFIG_PRINTK_TIME is not set
# CONFIG_MAGIC_SYSRQ is not set
# CONFIG_UNUSED_SYMBOLS is not set
diff --git a/arch/mips/configs/ip27_defconfig b/arch/mips/configs/ip27_defconfig
index 50092ba8aa71..e3e94c7e5ee1 100644
--- a/arch/mips/configs/ip27_defconfig
+++ b/arch/mips/configs/ip27_defconfig
@@ -162,6 +162,8 @@ CONFIG_PREEMPT_NONE=y
# CONFIG_PREEMPT is not set
CONFIG_PREEMPT_BKL=y
# CONFIG_MIPS_INSANE_LARGE is not set
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
#
@@ -980,6 +982,7 @@ CONFIG_SGI_PARTITION=y
#
# Kernel hacking
#
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
# CONFIG_PRINTK_TIME is not set
# CONFIG_MAGIC_SYSRQ is not set
# CONFIG_UNUSED_SYMBOLS is not set
diff --git a/arch/mips/configs/ip32_defconfig b/arch/mips/configs/ip32_defconfig
index dec2ba6ba03f..b4ab2bea9723 100644
--- a/arch/mips/configs/ip32_defconfig
+++ b/arch/mips/configs/ip32_defconfig
@@ -153,6 +153,8 @@ CONFIG_HZ=1000
# CONFIG_PREEMPT_NONE is not set
CONFIG_PREEMPT_VOLUNTARY=y
# CONFIG_PREEMPT is not set
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
#
@@ -922,6 +924,7 @@ CONFIG_SGI_PARTITION=y
#
# Kernel hacking
#
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
# CONFIG_PRINTK_TIME is not set
# CONFIG_MAGIC_SYSRQ is not set
# CONFIG_UNUSED_SYMBOLS is not set
diff --git a/arch/mips/configs/it8172_defconfig b/arch/mips/configs/it8172_defconfig
index 37f9dd7187b1..18d20fb7d5f0 100644
--- a/arch/mips/configs/it8172_defconfig
+++ b/arch/mips/configs/it8172_defconfig
@@ -147,6 +147,8 @@ CONFIG_HZ=1000
CONFIG_PREEMPT_NONE=y
# CONFIG_PREEMPT_VOLUNTARY is not set
# CONFIG_PREEMPT is not set
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
#
@@ -900,6 +902,7 @@ CONFIG_MSDOS_PARTITION=y
#
# Kernel hacking
#
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
# CONFIG_PRINTK_TIME is not set
# CONFIG_MAGIC_SYSRQ is not set
# CONFIG_UNUSED_SYMBOLS is not set
diff --git a/arch/mips/configs/ivr_defconfig b/arch/mips/configs/ivr_defconfig
index 18874a4c24fe..99831d0bf76b 100644
--- a/arch/mips/configs/ivr_defconfig
+++ b/arch/mips/configs/ivr_defconfig
@@ -144,6 +144,8 @@ CONFIG_HZ=1000
CONFIG_PREEMPT_NONE=y
# CONFIG_PREEMPT_VOLUNTARY is not set
# CONFIG_PREEMPT is not set
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
#
@@ -856,6 +858,7 @@ CONFIG_MSDOS_PARTITION=y
#
# Kernel hacking
#
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
# CONFIG_PRINTK_TIME is not set
# CONFIG_MAGIC_SYSRQ is not set
# CONFIG_UNUSED_SYMBOLS is not set
diff --git a/arch/mips/configs/jaguar-atx_defconfig b/arch/mips/configs/jaguar-atx_defconfig
index 9f1e3048d623..9d4d17ace123 100644
--- a/arch/mips/configs/jaguar-atx_defconfig
+++ b/arch/mips/configs/jaguar-atx_defconfig
@@ -153,6 +153,8 @@ CONFIG_HZ=1000
CONFIG_PREEMPT_NONE=y
# CONFIG_PREEMPT_VOLUNTARY is not set
# CONFIG_PREEMPT is not set
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
#
@@ -775,6 +777,7 @@ CONFIG_MSDOS_PARTITION=y
#
# Kernel hacking
#
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
# CONFIG_PRINTK_TIME is not set
# CONFIG_MAGIC_SYSRQ is not set
# CONFIG_UNUSED_SYMBOLS is not set
diff --git a/arch/mips/configs/jmr3927_defconfig b/arch/mips/configs/jmr3927_defconfig
index fded3f73815f..d03746667a96 100644
--- a/arch/mips/configs/jmr3927_defconfig
+++ b/arch/mips/configs/jmr3927_defconfig
@@ -143,6 +143,8 @@ CONFIG_PREEMPT_NONE=y
# CONFIG_PREEMPT_VOLUNTARY is not set
# CONFIG_PREEMPT is not set
CONFIG_RTC_DS1742=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
#
@@ -872,6 +874,7 @@ CONFIG_MSDOS_PARTITION=y
#
# Kernel hacking
#
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
# CONFIG_PRINTK_TIME is not set
# CONFIG_MAGIC_SYSRQ is not set
# CONFIG_UNUSED_SYMBOLS is not set
diff --git a/arch/mips/configs/lasat200_defconfig b/arch/mips/configs/lasat200_defconfig
index 320b8cdd6e58..1db8249b4c0f 100644
--- a/arch/mips/configs/lasat200_defconfig
+++ b/arch/mips/configs/lasat200_defconfig
@@ -151,6 +151,8 @@ CONFIG_HZ=1000
CONFIG_PREEMPT_NONE=y
# CONFIG_PREEMPT_VOLUNTARY is not set
# CONFIG_PREEMPT is not set
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
#
@@ -970,6 +972,7 @@ CONFIG_MSDOS_PARTITION=y
#
# Kernel hacking
#
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
# CONFIG_PRINTK_TIME is not set
# CONFIG_MAGIC_SYSRQ is not set
# CONFIG_UNUSED_SYMBOLS is not set
diff --git a/arch/mips/configs/malta_defconfig b/arch/mips/configs/malta_defconfig
index 0ba1ef5048fb..aeefe2873e38 100644
--- a/arch/mips/configs/malta_defconfig
+++ b/arch/mips/configs/malta_defconfig
@@ -170,6 +170,8 @@ CONFIG_HZ=100
CONFIG_PREEMPT_NONE=y
# CONFIG_PREEMPT_VOLUNTARY is not set
# CONFIG_PREEMPT is not set
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
#
@@ -1341,6 +1343,7 @@ CONFIG_NLS_UTF8=m
#
# Kernel hacking
#
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
# CONFIG_PRINTK_TIME is not set
# CONFIG_MAGIC_SYSRQ is not set
# CONFIG_UNUSED_SYMBOLS is not set
diff --git a/arch/mips/configs/mipssim_defconfig b/arch/mips/configs/mipssim_defconfig
index adbeeadddb8f..a3cbd23bf217 100644
--- a/arch/mips/configs/mipssim_defconfig
+++ b/arch/mips/configs/mipssim_defconfig
@@ -148,6 +148,8 @@ CONFIG_HZ=1000
CONFIG_PREEMPT_NONE=y
# CONFIG_PREEMPT_VOLUNTARY is not set
# CONFIG_PREEMPT is not set
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
#
@@ -799,6 +801,7 @@ CONFIG_MSDOS_PARTITION=y
#
# Kernel hacking
#
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
# CONFIG_PRINTK_TIME is not set
# CONFIG_MAGIC_SYSRQ is not set
# CONFIG_UNUSED_SYMBOLS is not set
diff --git a/arch/mips/configs/mpc30x_defconfig b/arch/mips/configs/mpc30x_defconfig
index 79fd544fcb2a..6570b47426ce 100644
--- a/arch/mips/configs/mpc30x_defconfig
+++ b/arch/mips/configs/mpc30x_defconfig
@@ -148,6 +148,8 @@ CONFIG_HZ=1000
CONFIG_PREEMPT_NONE=y
# CONFIG_PREEMPT_VOLUNTARY is not set
# CONFIG_PREEMPT is not set
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
#
diff --git a/arch/mips/configs/ocelot_3_defconfig b/arch/mips/configs/ocelot_3_defconfig
index 4d87da2b99fd..440d65f93a94 100644
--- a/arch/mips/configs/ocelot_3_defconfig
+++ b/arch/mips/configs/ocelot_3_defconfig
@@ -153,6 +153,8 @@ CONFIG_HZ=1000
CONFIG_PREEMPT_NONE=y
# CONFIG_PREEMPT_VOLUNTARY is not set
# CONFIG_PREEMPT is not set
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
#
@@ -1091,6 +1093,7 @@ CONFIG_NLS_DEFAULT="iso8859-1"
#
# Kernel hacking
#
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
# CONFIG_PRINTK_TIME is not set
# CONFIG_MAGIC_SYSRQ is not set
# CONFIG_UNUSED_SYMBOLS is not set
diff --git a/arch/mips/configs/ocelot_c_defconfig b/arch/mips/configs/ocelot_c_defconfig
index a7ac2b0a8273..c2c7ae77da3e 100644
--- a/arch/mips/configs/ocelot_c_defconfig
+++ b/arch/mips/configs/ocelot_c_defconfig
@@ -150,6 +150,8 @@ CONFIG_HZ=1000
CONFIG_PREEMPT_NONE=y
# CONFIG_PREEMPT_VOLUNTARY is not set
# CONFIG_PREEMPT is not set
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
#
@@ -839,6 +841,7 @@ CONFIG_MSDOS_PARTITION=y
#
# Kernel hacking
#
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
# CONFIG_PRINTK_TIME is not set
# CONFIG_MAGIC_SYSRQ is not set
# CONFIG_UNUSED_SYMBOLS is not set
diff --git a/arch/mips/configs/ocelot_defconfig b/arch/mips/configs/ocelot_defconfig
index 853e7bba5122..67efe270e0cc 100644
--- a/arch/mips/configs/ocelot_defconfig
+++ b/arch/mips/configs/ocelot_defconfig
@@ -154,6 +154,8 @@ CONFIG_HZ=1000
CONFIG_PREEMPT_NONE=y
# CONFIG_PREEMPT_VOLUNTARY is not set
# CONFIG_PREEMPT is not set
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
#
@@ -788,6 +790,7 @@ CONFIG_MSDOS_PARTITION=y
#
# Kernel hacking
#
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
# CONFIG_PRINTK_TIME is not set
# CONFIG_MAGIC_SYSRQ is not set
# CONFIG_UNUSED_SYMBOLS is not set
diff --git a/arch/mips/configs/ocelot_g_defconfig b/arch/mips/configs/ocelot_g_defconfig
index 8524efa23a49..a10f34de5f7e 100644
--- a/arch/mips/configs/ocelot_g_defconfig
+++ b/arch/mips/configs/ocelot_g_defconfig
@@ -153,6 +153,8 @@ CONFIG_HZ=1000
CONFIG_PREEMPT_NONE=y
# CONFIG_PREEMPT_VOLUNTARY is not set
# CONFIG_PREEMPT is not set
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
#
@@ -842,6 +844,7 @@ CONFIG_MSDOS_PARTITION=y
#
# Kernel hacking
#
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
# CONFIG_PRINTK_TIME is not set
# CONFIG_MAGIC_SYSRQ is not set
# CONFIG_UNUSED_SYMBOLS is not set
diff --git a/arch/mips/configs/pb1100_defconfig b/arch/mips/configs/pb1100_defconfig
index 1a16e92900cb..741f8258075c 100644
--- a/arch/mips/configs/pb1100_defconfig
+++ b/arch/mips/configs/pb1100_defconfig
@@ -149,6 +149,8 @@ CONFIG_HZ=1000
CONFIG_PREEMPT_NONE=y
# CONFIG_PREEMPT_VOLUNTARY is not set
# CONFIG_PREEMPT is not set
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
#
@@ -1000,6 +1002,7 @@ CONFIG_NLS_DEFAULT="iso8859-1"
#
# Kernel hacking
#
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
# CONFIG_PRINTK_TIME is not set
# CONFIG_MAGIC_SYSRQ is not set
# CONFIG_UNUSED_SYMBOLS is not set
diff --git a/arch/mips/configs/pb1500_defconfig b/arch/mips/configs/pb1500_defconfig
index 9ea8edea6f29..8576340714da 100644
--- a/arch/mips/configs/pb1500_defconfig
+++ b/arch/mips/configs/pb1500_defconfig
@@ -148,6 +148,8 @@ CONFIG_HZ=1000
CONFIG_PREEMPT_NONE=y
# CONFIG_PREEMPT_VOLUNTARY is not set
# CONFIG_PREEMPT is not set
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
#
@@ -1106,6 +1108,7 @@ CONFIG_NLS_DEFAULT="iso8859-1"
#
# Kernel hacking
#
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
# CONFIG_PRINTK_TIME is not set
# CONFIG_MAGIC_SYSRQ is not set
# CONFIG_UNUSED_SYMBOLS is not set
diff --git a/arch/mips/configs/pb1550_defconfig b/arch/mips/configs/pb1550_defconfig
index c4a158976f8f..3db7427d1b55 100644
--- a/arch/mips/configs/pb1550_defconfig
+++ b/arch/mips/configs/pb1550_defconfig
@@ -148,6 +148,8 @@ CONFIG_HZ=1000
CONFIG_PREEMPT_NONE=y
# CONFIG_PREEMPT_VOLUNTARY is not set
# CONFIG_PREEMPT is not set
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
#
@@ -1098,6 +1100,7 @@ CONFIG_NLS_DEFAULT="iso8859-1"
#
# Kernel hacking
#
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
# CONFIG_PRINTK_TIME is not set
# CONFIG_MAGIC_SYSRQ is not set
# CONFIG_UNUSED_SYMBOLS is not set
diff --git a/arch/mips/configs/pnx8550-jbs_defconfig b/arch/mips/configs/pnx8550-jbs_defconfig
index 1cbf270c301c..26b0b9883496 100644
--- a/arch/mips/configs/pnx8550-jbs_defconfig
+++ b/arch/mips/configs/pnx8550-jbs_defconfig
@@ -153,6 +153,8 @@ CONFIG_HZ=1000
CONFIG_PREEMPT_NONE=y
# CONFIG_PREEMPT_VOLUNTARY is not set
# CONFIG_PREEMPT is not set
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
#
@@ -876,6 +878,7 @@ CONFIG_NLS_DEFAULT="iso8859-1"
#
# Kernel hacking
#
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
# CONFIG_PRINTK_TIME is not set
CONFIG_MAGIC_SYSRQ=y
# CONFIG_UNUSED_SYMBOLS is not set
diff --git a/arch/mips/configs/pnx8550-v2pci_defconfig b/arch/mips/configs/pnx8550-v2pci_defconfig
index bec30b15b9bd..e93266b37dd9 100644
--- a/arch/mips/configs/pnx8550-v2pci_defconfig
+++ b/arch/mips/configs/pnx8550-v2pci_defconfig
@@ -153,6 +153,8 @@ CONFIG_HZ=1000
CONFIG_PREEMPT_NONE=y
# CONFIG_PREEMPT_VOLUNTARY is not set
# CONFIG_PREEMPT is not set
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
#
@@ -1057,6 +1059,7 @@ CONFIG_NLS_DEFAULT="iso8859-1"
#
# Kernel hacking
#
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
# CONFIG_PRINTK_TIME is not set
# CONFIG_MAGIC_SYSRQ is not set
# CONFIG_UNUSED_SYMBOLS is not set
diff --git a/arch/mips/configs/qemu_defconfig b/arch/mips/configs/qemu_defconfig
index f5f799e93707..9b0dab822bd0 100644
--- a/arch/mips/configs/qemu_defconfig
+++ b/arch/mips/configs/qemu_defconfig
@@ -145,6 +145,8 @@ CONFIG_HZ=100
CONFIG_PREEMPT_NONE=y
# CONFIG_PREEMPT_VOLUNTARY is not set
# CONFIG_PREEMPT is not set
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
#
@@ -733,6 +735,7 @@ CONFIG_MSDOS_PARTITION=y
#
# Kernel hacking
#
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
# CONFIG_PRINTK_TIME is not set
# CONFIG_MAGIC_SYSRQ is not set
# CONFIG_UNUSED_SYMBOLS is not set
diff --git a/arch/mips/configs/rbhma4500_defconfig b/arch/mips/configs/rbhma4500_defconfig
index 2f5650227ba3..dd0296036026 100644
--- a/arch/mips/configs/rbhma4500_defconfig
+++ b/arch/mips/configs/rbhma4500_defconfig
@@ -155,6 +155,8 @@ CONFIG_HZ=1000
CONFIG_PREEMPT_NONE=y
# CONFIG_PREEMPT_VOLUNTARY is not set
# CONFIG_PREEMPT is not set
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
#
@@ -1335,6 +1337,7 @@ CONFIG_NLS_DEFAULT="iso8859-1"
#
# Kernel hacking
#
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
# CONFIG_PRINTK_TIME is not set
# CONFIG_MAGIC_SYSRQ is not set
# CONFIG_UNUSED_SYMBOLS is not set
diff --git a/arch/mips/configs/rm200_defconfig b/arch/mips/configs/rm200_defconfig
index 4fee90b2b100..d8a498d64d62 100644
--- a/arch/mips/configs/rm200_defconfig
+++ b/arch/mips/configs/rm200_defconfig
@@ -158,6 +158,8 @@ CONFIG_HZ=1000
# CONFIG_PREEMPT_NONE is not set
CONFIG_PREEMPT_VOLUNTARY=y
# CONFIG_PREEMPT is not set
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
#
@@ -1584,6 +1586,7 @@ CONFIG_NLS_UTF8=m
#
# Kernel hacking
#
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
# CONFIG_PRINTK_TIME is not set
# CONFIG_MAGIC_SYSRQ is not set
# CONFIG_UNUSED_SYMBOLS is not set
diff --git a/arch/mips/configs/sb1250-swarm_defconfig b/arch/mips/configs/sb1250-swarm_defconfig
index 9041f095f96f..805a4fe450f5 100644
--- a/arch/mips/configs/sb1250-swarm_defconfig
+++ b/arch/mips/configs/sb1250-swarm_defconfig
@@ -171,6 +171,8 @@ CONFIG_PREEMPT_NONE=y
# CONFIG_PREEMPT_VOLUNTARY is not set
# CONFIG_PREEMPT is not set
CONFIG_PREEMPT_BKL=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
#
@@ -873,6 +875,7 @@ CONFIG_MSDOS_PARTITION=y
#
# Kernel hacking
#
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
# CONFIG_PRINTK_TIME is not set
# CONFIG_MAGIC_SYSRQ is not set
# CONFIG_UNUSED_SYMBOLS is not set
diff --git a/arch/mips/configs/sead_defconfig b/arch/mips/configs/sead_defconfig
index 02abb2f1bfaf..6fcb656d8d87 100644
--- a/arch/mips/configs/sead_defconfig
+++ b/arch/mips/configs/sead_defconfig
@@ -151,6 +151,8 @@ CONFIG_HZ=1000
CONFIG_PREEMPT_NONE=y
# CONFIG_PREEMPT_VOLUNTARY is not set
# CONFIG_PREEMPT is not set
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
#
@@ -581,6 +583,7 @@ CONFIG_PARTITION_ADVANCED=y
#
# Kernel hacking
#
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
# CONFIG_PRINTK_TIME is not set
# CONFIG_MAGIC_SYSRQ is not set
# CONFIG_UNUSED_SYMBOLS is not set
diff --git a/arch/mips/configs/tb0226_defconfig b/arch/mips/configs/tb0226_defconfig
index ca3d0c4ba15b..dc312f19ada7 100644
--- a/arch/mips/configs/tb0226_defconfig
+++ b/arch/mips/configs/tb0226_defconfig
@@ -151,6 +151,8 @@ CONFIG_HZ=1000
CONFIG_PREEMPT_NONE=y
# CONFIG_PREEMPT_VOLUNTARY is not set
# CONFIG_PREEMPT is not set
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
#
@@ -1059,6 +1061,7 @@ CONFIG_MSDOS_PARTITION=y
#
# Kernel hacking
#
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
# CONFIG_PRINTK_TIME is not set
# CONFIG_MAGIC_SYSRQ is not set
# CONFIG_UNUSED_SYMBOLS is not set
diff --git a/arch/mips/configs/tb0229_defconfig b/arch/mips/configs/tb0229_defconfig
index 4e2009ace278..85615d99b01a 100644
--- a/arch/mips/configs/tb0229_defconfig
+++ b/arch/mips/configs/tb0229_defconfig
@@ -151,6 +151,8 @@ CONFIG_HZ=1000
CONFIG_PREEMPT_NONE=y
# CONFIG_PREEMPT_VOLUNTARY is not set
# CONFIG_PREEMPT is not set
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
#
@@ -968,6 +970,7 @@ CONFIG_MSDOS_PARTITION=y
#
# Kernel hacking
#
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
# CONFIG_PRINTK_TIME is not set
# CONFIG_MAGIC_SYSRQ is not set
# CONFIG_UNUSED_SYMBOLS is not set
diff --git a/arch/mips/configs/tb0287_defconfig b/arch/mips/configs/tb0287_defconfig
index 535a813d01a9..ad7271b3f266 100644
--- a/arch/mips/configs/tb0287_defconfig
+++ b/arch/mips/configs/tb0287_defconfig
@@ -151,6 +151,8 @@ CONFIG_HZ=1000
CONFIG_PREEMPT_NONE=y
# CONFIG_PREEMPT_VOLUNTARY is not set
# CONFIG_PREEMPT is not set
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
#
@@ -1146,6 +1148,7 @@ CONFIG_MSDOS_PARTITION=y
#
# Kernel hacking
#
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
# CONFIG_PRINTK_TIME is not set
# CONFIG_MAGIC_SYSRQ is not set
# CONFIG_UNUSED_SYMBOLS is not set
diff --git a/arch/mips/configs/workpad_defconfig b/arch/mips/configs/workpad_defconfig
index 3a3ef20b21cc..863f6a7cadfd 100644
--- a/arch/mips/configs/workpad_defconfig
+++ b/arch/mips/configs/workpad_defconfig
@@ -147,6 +147,8 @@ CONFIG_HZ=1000
CONFIG_PREEMPT_NONE=y
# CONFIG_PREEMPT_VOLUNTARY is not set
# CONFIG_PREEMPT is not set
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
#
diff --git a/arch/mips/configs/wrppmc_defconfig b/arch/mips/configs/wrppmc_defconfig
index e6b1dea55842..c10267d61cc9 100644
--- a/arch/mips/configs/wrppmc_defconfig
+++ b/arch/mips/configs/wrppmc_defconfig
@@ -155,6 +155,8 @@ CONFIG_HZ=1000
CONFIG_PREEMPT_NONE=y
# CONFIG_PREEMPT_VOLUNTARY is not set
# CONFIG_PREEMPT is not set
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
#
@@ -829,6 +831,7 @@ CONFIG_MSDOS_PARTITION=y
#
# Kernel hacking
#
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
# CONFIG_PRINTK_TIME is not set
# CONFIG_MAGIC_SYSRQ is not set
# CONFIG_UNUSED_SYMBOLS is not set
diff --git a/arch/mips/configs/yosemite_defconfig b/arch/mips/configs/yosemite_defconfig
index 06a072b77b1c..4d3c1329f3cf 100644
--- a/arch/mips/configs/yosemite_defconfig
+++ b/arch/mips/configs/yosemite_defconfig
@@ -152,6 +152,8 @@ CONFIG_PREEMPT_NONE=y
# CONFIG_PREEMPT_VOLUNTARY is not set
# CONFIG_PREEMPT is not set
CONFIG_PREEMPT_BKL=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
#
@@ -760,6 +762,7 @@ CONFIG_MSDOS_PARTITION=y
#
# Kernel hacking
#
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
# CONFIG_PRINTK_TIME is not set
# CONFIG_MAGIC_SYSRQ is not set
# CONFIG_UNUSED_SYMBOLS is not set
diff --git a/arch/mips/defconfig b/arch/mips/defconfig
index cc9b24eda9e8..21d53e0c9ee8 100644
--- a/arch/mips/defconfig
+++ b/arch/mips/defconfig
@@ -153,6 +153,8 @@ CONFIG_HZ=1000
# CONFIG_PREEMPT_NONE is not set
CONFIG_PREEMPT_VOLUNTARY=y
# CONFIG_PREEMPT is not set
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
#
@@ -1147,6 +1149,7 @@ CONFIG_NLS_UTF8=m
#
# Kernel hacking
#
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
# CONFIG_PRINTK_TIME is not set
# CONFIG_MAGIC_SYSRQ is not set
# CONFIG_UNUSED_SYMBOLS is not set
diff --git a/arch/mips/gt64120/common/time.c b/arch/mips/gt64120/common/time.c
index d837b26fbe51..7feca49350d1 100644
--- a/arch/mips/gt64120/common/time.c
+++ b/arch/mips/gt64120/common/time.c
@@ -34,7 +34,7 @@ static void gt64120_irq(int irq, void *dev_id, struct pt_regs *regs)
if (irq_src & 0x00000800) { /* Check for timer interrupt */
handled = 1;
irq_src &= ~0x00000800;
- do_timer(regs);
+ do_timer(1);
#ifndef CONFIG_SMP
update_process_times(user_mode(regs));
#endif
diff --git a/arch/mips/kernel/Makefile b/arch/mips/kernel/Makefile
index 881c467c6982..cd9cec9e39e9 100644
--- a/arch/mips/kernel/Makefile
+++ b/arch/mips/kernel/Makefile
@@ -11,6 +11,7 @@ obj-y += cpu-probe.o branch.o entry.o genex.o irq.o process.o \
binfmt_irix-objs := irixelf.o irixinv.o irixioctl.o irixsig.o \
irix5sys.o sysirix.o
+obj-$(CONFIG_STACKTRACE) += stacktrace.o
obj-$(CONFIG_MODULES) += mips_ksyms.o module.o
obj-$(CONFIG_APM) += apm.o
diff --git a/arch/mips/kernel/genex.S b/arch/mips/kernel/genex.S
index 37fda3dcdfc5..af6ef2fd8300 100644
--- a/arch/mips/kernel/genex.S
+++ b/arch/mips/kernel/genex.S
@@ -220,8 +220,8 @@ NESTED(except_vec_vi_handler, 0, sp)
CLI
TRACE_IRQS_OFF
move a0, sp
- jalr v0
- j ret_from_irq
+ PTR_LA ra, ret_from_irq
+ jr v0
END(except_vec_vi_handler)
/*
@@ -349,8 +349,8 @@ NESTED(nmi_handler, PT_SIZE, sp)
.set at
__BUILD_\verbose \exception
move a0, sp
- jal do_\handler
- j ret_from_exception
+ PTR_LA ra, ret_from_exception
+ j do_\handler
END(handle_\exception)
.endm
diff --git a/arch/mips/kernel/i8259.c b/arch/mips/kernel/i8259.c
index ea36c8e8852c..48e3418c217b 100644
--- a/arch/mips/kernel/i8259.c
+++ b/arch/mips/kernel/i8259.c
@@ -302,11 +302,11 @@ static struct irqaction irq2 = {
};
static struct resource pic1_io_resource = {
- .name = "pic1", .start = 0x20, .end = 0x3f, .flags = IORESOURCE_BUSY
+ .name = "pic1", .start = 0x20, .end = 0x21, .flags = IORESOURCE_BUSY
};
static struct resource pic2_io_resource = {
- .name = "pic2", .start = 0xa0, .end = 0xbf, .flags = IORESOURCE_BUSY
+ .name = "pic2", .start = 0xa0, .end = 0xa1, .flags = IORESOURCE_BUSY
};
/*
diff --git a/arch/mips/kernel/linux32.c b/arch/mips/kernel/linux32.c
index 43b1162d714f..53f4171fc188 100644
--- a/arch/mips/kernel/linux32.c
+++ b/arch/mips/kernel/linux32.c
@@ -77,6 +77,8 @@ int cp_compat_stat(struct kstat *stat, struct compat_stat __user *statbuf)
memset(&tmp, 0, sizeof(tmp));
tmp.st_dev = new_encode_dev(stat->dev);
tmp.st_ino = stat->ino;
+ if (sizeof(tmp.st_ino) < sizeof(stat->ino) && tmp.st_ino != stat->ino)
+ return -EOVERFLOW;
tmp.st_mode = stat->mode;
tmp.st_nlink = stat->nlink;
SET_UID(tmp.st_uid, stat->uid);
@@ -1039,7 +1041,7 @@ asmlinkage long sys32_newuname(struct new_utsname __user * name)
int ret = 0;
down_read(&uts_sem);
- if (copy_to_user(name,&system_utsname,sizeof *name))
+ if (copy_to_user(name, utsname(), sizeof *name))
ret = -EFAULT;
up_read(&uts_sem);
diff --git a/arch/mips/kernel/process.c b/arch/mips/kernel/process.c
index 2613a0dd4b82..045d987bc683 100644
--- a/arch/mips/kernel/process.c
+++ b/arch/mips/kernel/process.c
@@ -40,6 +40,7 @@
#include <asm/elf.h>
#include <asm/isadep.h>
#include <asm/inst.h>
+#include <asm/stacktrace.h>
#ifdef CONFIG_MIPS_MT_SMTC
#include <asm/mipsmtregs.h>
extern void smtc_idle_loop_hook(void);
@@ -398,7 +399,7 @@ unsigned long thread_saved_pc(struct task_struct *tsk)
#ifdef CONFIG_KALLSYMS
/* used by show_backtrace() */
unsigned long unwind_stack(struct task_struct *task, unsigned long *sp,
- unsigned long pc, unsigned long ra)
+ unsigned long pc, unsigned long *ra)
{
unsigned long stack_page;
struct mips_frame_info info;
@@ -406,18 +407,42 @@ unsigned long unwind_stack(struct task_struct *task, unsigned long *sp,
char namebuf[KSYM_NAME_LEN + 1];
unsigned long size, ofs;
int leaf;
+ extern void ret_from_irq(void);
+ extern void ret_from_exception(void);
stack_page = (unsigned long)task_stack_page(task);
if (!stack_page)
return 0;
+ /*
+ * If we reached the bottom of interrupt context,
+ * return saved pc in pt_regs.
+ */
+ if (pc == (unsigned long)ret_from_irq ||
+ pc == (unsigned long)ret_from_exception) {
+ struct pt_regs *regs;
+ if (*sp >= stack_page &&
+ *sp + sizeof(*regs) <= stack_page + THREAD_SIZE - 32) {
+ regs = (struct pt_regs *)*sp;
+ pc = regs->cp0_epc;
+ if (__kernel_text_address(pc)) {
+ *sp = regs->regs[29];
+ *ra = regs->regs[31];
+ return pc;
+ }
+ }
+ return 0;
+ }
if (!kallsyms_lookup(pc, &size, &ofs, &modname, namebuf))
return 0;
/*
* Return ra if an exception occured at the first instruction
*/
- if (unlikely(ofs == 0))
- return ra;
+ if (unlikely(ofs == 0)) {
+ pc = *ra;
+ *ra = 0;
+ return pc;
+ }
info.func = (void *)(pc - ofs);
info.func_size = ofs; /* analyze from start to ofs */
@@ -436,11 +461,12 @@ unsigned long unwind_stack(struct task_struct *task, unsigned long *sp,
* one. In that cases avoid to return always the
* same value.
*/
- pc = pc != ra ? ra : 0;
+ pc = pc != *ra ? *ra : 0;
else
pc = ((unsigned long *)(*sp))[info.pc_offset];
*sp += info.frame_size;
+ *ra = 0;
return __kernel_text_address(pc) ? pc : 0;
}
#endif
@@ -453,6 +479,7 @@ unsigned long get_wchan(struct task_struct *task)
unsigned long pc = 0;
#ifdef CONFIG_KALLSYMS
unsigned long sp;
+ unsigned long ra = 0;
#endif
if (!task || task == current || task->state == TASK_RUNNING)
@@ -466,7 +493,7 @@ unsigned long get_wchan(struct task_struct *task)
sp = task->thread.reg29 + schedule_mfi.frame_size;
while (in_sched_functions(pc))
- pc = unwind_stack(task, &sp, pc, 0);
+ pc = unwind_stack(task, &sp, pc, &ra);
#endif
out:
diff --git a/arch/mips/kernel/scall32-o32.S b/arch/mips/kernel/scall32-o32.S
index e71785102206..61362e6fa9ec 100644
--- a/arch/mips/kernel/scall32-o32.S
+++ b/arch/mips/kernel/scall32-o32.S
@@ -28,18 +28,7 @@
NESTED(handle_sys, PT_SIZE, sp)
.set noat
SAVE_SOME
-#ifdef CONFIG_TRACE_IRQFLAGS
- TRACE_IRQS_ON
-#ifdef CONFIG_64BIT
- LONG_L $8, PT_R8(sp)
- LONG_L $9, PT_R9(sp)
-#endif
- LONG_L $7, PT_R7(sp)
- LONG_L $6, PT_R6(sp)
- LONG_L $5, PT_R5(sp)
- LONG_L $4, PT_R4(sp)
- LONG_L $2, PT_R2(sp)
-#endif
+ TRACE_IRQS_ON_RELOAD
STI
.set at
diff --git a/arch/mips/kernel/scall64-64.S b/arch/mips/kernel/scall64-64.S
index 4c22d0b4825d..6c7b5ed0ea6e 100644
--- a/arch/mips/kernel/scall64-64.S
+++ b/arch/mips/kernel/scall64-64.S
@@ -34,7 +34,7 @@ NESTED(handle_sys64, PT_SIZE, sp)
*/
.set noat
SAVE_SOME
- TRACE_IRQS_ON
+ TRACE_IRQS_ON_RELOAD
STI
.set at
#endif
diff --git a/arch/mips/kernel/scall64-n32.S b/arch/mips/kernel/scall64-n32.S
index f25c2a2f1038..6d9f18727ac5 100644
--- a/arch/mips/kernel/scall64-n32.S
+++ b/arch/mips/kernel/scall64-n32.S
@@ -33,7 +33,7 @@ NESTED(handle_sysn32, PT_SIZE, sp)
#ifndef CONFIG_MIPS32_O32
.set noat
SAVE_SOME
- TRACE_IRQS_ON
+ TRACE_IRQS_ON_RELOAD
STI
.set at
#endif
diff --git a/arch/mips/kernel/scall64-o32.S b/arch/mips/kernel/scall64-o32.S
index 288ee4ac4dbb..2e6d0673163e 100644
--- a/arch/mips/kernel/scall64-o32.S
+++ b/arch/mips/kernel/scall64-o32.S
@@ -28,7 +28,7 @@
NESTED(handle_sys, PT_SIZE, sp)
.set noat
SAVE_SOME
- TRACE_IRQS_ON
+ TRACE_IRQS_ON_RELOAD
STI
.set at
ld t1, PT_EPC(sp) # skip syscall on return
diff --git a/arch/mips/kernel/stacktrace.c b/arch/mips/kernel/stacktrace.c
new file mode 100644
index 000000000000..4aabe526a68e
--- /dev/null
+++ b/arch/mips/kernel/stacktrace.c
@@ -0,0 +1,85 @@
+/*
+ * arch/mips/kernel/stacktrace.c
+ *
+ * Stack trace management functions
+ *
+ * Copyright (C) 2006 Atsushi Nemoto <anemo@mba.ocn.ne.jp>
+ */
+#include <linux/sched.h>
+#include <linux/stacktrace.h>
+#include <asm/stacktrace.h>
+
+/*
+ * Save stack-backtrace addresses into a stack_trace buffer:
+ */
+static void save_raw_context_stack(struct stack_trace *trace,
+ unsigned long reg29)
+{
+ unsigned long *sp = (unsigned long *)reg29;
+ unsigned long addr;
+
+ while (!kstack_end(sp)) {
+ addr = *sp++;
+ if (__kernel_text_address(addr)) {
+ if (trace->skip > 0)
+ trace->skip--;
+ else
+ trace->entries[trace->nr_entries++] = addr;
+ if (trace->nr_entries >= trace->max_entries)
+ break;
+ }
+ }
+}
+
+static void save_context_stack(struct stack_trace *trace,
+ struct task_struct *task, struct pt_regs *regs)
+{
+ unsigned long sp = regs->regs[29];
+#ifdef CONFIG_KALLSYMS
+ unsigned long ra = regs->regs[31];
+ unsigned long pc = regs->cp0_epc;
+
+ if (raw_show_trace || !__kernel_text_address(pc)) {
+ unsigned long stack_page =
+ (unsigned long)task_stack_page(task);
+ if (stack_page && sp >= stack_page &&
+ sp <= stack_page + THREAD_SIZE - 32)
+ save_raw_context_stack(trace, sp);
+ return;
+ }
+ do {
+ if (trace->skip > 0)
+ trace->skip--;
+ else
+ trace->entries[trace->nr_entries++] = pc;
+ if (trace->nr_entries >= trace->max_entries)
+ break;
+ pc = unwind_stack(task, &sp, pc, &ra);
+ } while (pc);
+#else
+ save_raw_context_stack(sp);
+#endif
+}
+
+/*
+ * Save stack-backtrace addresses into a stack_trace buffer.
+ */
+void save_stack_trace(struct stack_trace *trace, struct task_struct *task)
+{
+ struct pt_regs dummyregs;
+ struct pt_regs *regs = &dummyregs;
+
+ WARN_ON(trace->nr_entries || !trace->max_entries);
+
+ if (task && task != current) {
+ regs->regs[29] = task->thread.reg29;
+ regs->regs[31] = 0;
+ regs->cp0_epc = task->thread.reg31;
+ } else {
+ if (!task)
+ task = current;
+ prepare_frametrace(regs);
+ }
+
+ save_context_stack(trace, task, regs);
+}
diff --git a/arch/mips/kernel/syscall.c b/arch/mips/kernel/syscall.c
index 9951240cc3fd..26e1a7e78d13 100644
--- a/arch/mips/kernel/syscall.c
+++ b/arch/mips/kernel/syscall.c
@@ -231,7 +231,7 @@ out:
*/
asmlinkage int sys_uname(struct old_utsname __user * name)
{
- if (name && !copy_to_user(name, &system_utsname, sizeof (*name)))
+ if (name && !copy_to_user(name, utsname(), sizeof (*name)))
return 0;
return -EFAULT;
}
@@ -248,16 +248,21 @@ asmlinkage int sys_olduname(struct oldold_utsname __user * name)
if (!access_ok(VERIFY_WRITE,name,sizeof(struct oldold_utsname)))
return -EFAULT;
- error = __copy_to_user(&name->sysname,&system_utsname.sysname,__OLD_UTS_LEN);
- error -= __put_user(0,name->sysname+__OLD_UTS_LEN);
- error -= __copy_to_user(&name->nodename,&system_utsname.nodename,__OLD_UTS_LEN);
- error -= __put_user(0,name->nodename+__OLD_UTS_LEN);
- error -= __copy_to_user(&name->release,&system_utsname.release,__OLD_UTS_LEN);
- error -= __put_user(0,name->release+__OLD_UTS_LEN);
- error -= __copy_to_user(&name->version,&system_utsname.version,__OLD_UTS_LEN);
- error -= __put_user(0,name->version+__OLD_UTS_LEN);
- error -= __copy_to_user(&name->machine,&system_utsname.machine,__OLD_UTS_LEN);
- error = __put_user(0,name->machine+__OLD_UTS_LEN);
+ error = __copy_to_user(&name->sysname, &utsname()->sysname,
+ __OLD_UTS_LEN);
+ error -= __put_user(0, name->sysname + __OLD_UTS_LEN);
+ error -= __copy_to_user(&name->nodename, &utsname()->nodename,
+ __OLD_UTS_LEN);
+ error -= __put_user(0, name->nodename + __OLD_UTS_LEN);
+ error -= __copy_to_user(&name->release, &utsname()->release,
+ __OLD_UTS_LEN);
+ error -= __put_user(0, name->release + __OLD_UTS_LEN);
+ error -= __copy_to_user(&name->version, &utsname()->version,
+ __OLD_UTS_LEN);
+ error -= __put_user(0, name->version + __OLD_UTS_LEN);
+ error -= __copy_to_user(&name->machine, &utsname()->machine,
+ __OLD_UTS_LEN);
+ error = __put_user(0, name->machine + __OLD_UTS_LEN);
error = error ? -EFAULT : 0;
return error;
@@ -401,3 +406,32 @@ asmlinkage void bad_stack(void)
{
do_exit(SIGSEGV);
}
+
+/*
+ * Do a system call from kernel instead of calling sys_execve so we
+ * end up with proper pt_regs.
+ */
+int kernel_execve(const char *filename, char *const argv[], char *const envp[])
+{
+ register unsigned long __a0 asm("$4") = (unsigned long) filename;
+ register unsigned long __a1 asm("$5") = (unsigned long) argv;
+ register unsigned long __a2 asm("$6") = (unsigned long) envp;
+ register unsigned long __a3 asm("$7");
+ unsigned long __v0;
+
+ __asm__ volatile (" \n"
+ " .set noreorder \n"
+ " li $2, %5 # __NR_execve \n"
+ " syscall \n"
+ " move %0, $2 \n"
+ " .set reorder \n"
+ : "=&r" (__v0), "=r" (__a3)
+ : "r" (__a0), "r" (__a1), "r" (__a2), "i" (__NR_execve)
+ : "$2", "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$24",
+ "memory");
+
+ if (__a3 == 0)
+ return __v0;
+
+ return -__v0;
+}
diff --git a/arch/mips/kernel/sysirix.c b/arch/mips/kernel/sysirix.c
index 1137dd6ea7aa..93c74fefff76 100644
--- a/arch/mips/kernel/sysirix.c
+++ b/arch/mips/kernel/sysirix.c
@@ -884,7 +884,7 @@ asmlinkage int irix_getdomainname(char __user *name, int len)
down_read(&uts_sem);
if (len > __NEW_UTS_LEN)
len = __NEW_UTS_LEN;
- err = copy_to_user(name, system_utsname.domainname, len) ? -EFAULT : 0;
+ err = copy_to_user(name, utsname()->domainname, len) ? -EFAULT : 0;
up_read(&uts_sem);
return err;
@@ -1127,11 +1127,11 @@ struct iuname {
asmlinkage int irix_uname(struct iuname __user *buf)
{
down_read(&uts_sem);
- if (copy_from_user(system_utsname.sysname, buf->sysname, 65)
- || copy_from_user(system_utsname.nodename, buf->nodename, 65)
- || copy_from_user(system_utsname.release, buf->release, 65)
- || copy_from_user(system_utsname.version, buf->version, 65)
- || copy_from_user(system_utsname.machine, buf->machine, 65)) {
+ if (copy_from_user(utsname()->sysname, buf->sysname, 65)
+ || copy_from_user(utsname()->nodename, buf->nodename, 65)
+ || copy_from_user(utsname()->release, buf->release, 65)
+ || copy_from_user(utsname()->version, buf->version, 65)
+ || copy_from_user(utsname()->machine, buf->machine, 65)) {
return -EFAULT;
}
up_read(&uts_sem);
@@ -1739,12 +1739,13 @@ struct irix_dirent32_callback {
#define ROUND_UP32(x) (((x)+sizeof(u32)-1) & ~(sizeof(u32)-1))
static int irix_filldir32(void *__buf, const char *name,
- int namlen, loff_t offset, ino_t ino, unsigned int d_type)
+ int namlen, loff_t offset, u64 ino, unsigned int d_type)
{
struct irix_dirent32 __user *dirent;
struct irix_dirent32_callback *buf = __buf;
unsigned short reclen = ROUND_UP32(NAME_OFFSET32(dirent) + namlen + 1);
int err = 0;
+ u32 d_ino;
#ifdef DEBUG_GETDENTS
printk("\nirix_filldir32[reclen<%d>namlen<%d>count<%d>]",
@@ -1753,12 +1754,15 @@ static int irix_filldir32(void *__buf, const char *name,
buf->error = -EINVAL; /* only used if we fail.. */
if (reclen > buf->count)
return -EINVAL;
+ d_ino = ino;
+ if (sizeof(d_ino) < sizeof(ino) && d_ino != ino)
+ return -EOVERFLOW;
dirent = buf->previous;
if (dirent)
err = __put_user(offset, &dirent->d_off);
dirent = buf->current_dir;
err |= __put_user(dirent, &buf->previous);
- err |= __put_user(ino, &dirent->d_ino);
+ err |= __put_user(d_ino, &dirent->d_ino);
err |= __put_user(reclen, &dirent->d_reclen);
err |= copy_to_user((char __user *)dirent->d_name, name, namlen) ? -EFAULT : 0;
err |= __put_user(0, &dirent->d_name[namlen]);
@@ -1837,7 +1841,7 @@ struct irix_dirent64_callback {
#define ROUND_UP64(x) (((x)+sizeof(u64)-1) & ~(sizeof(u64)-1))
static int irix_filldir64(void *__buf, const char *name,
- int namlen, loff_t offset, ino_t ino, unsigned int d_type)
+ int namlen, loff_t offset, u64 ino, unsigned int d_type)
{
struct irix_dirent64 __user *dirent;
struct irix_dirent64_callback * buf = __buf;
diff --git a/arch/mips/kernel/time.c b/arch/mips/kernel/time.c
index 170cb67f4ede..845c7e55505d 100644
--- a/arch/mips/kernel/time.c
+++ b/arch/mips/kernel/time.c
@@ -47,8 +47,6 @@
/*
* forward reference
*/
-extern volatile unsigned long wall_jiffies;
-
DEFINE_SPINLOCK(rtc_lock);
/*
@@ -159,7 +157,6 @@ void (*mips_hpt_init)(unsigned int);
void do_gettimeofday(struct timeval *tv)
{
unsigned long seq;
- unsigned long lost;
unsigned long usec, sec;
unsigned long max_ntp_tick;
@@ -168,8 +165,6 @@ void do_gettimeofday(struct timeval *tv)
usec = do_gettimeoffset();
- lost = jiffies - wall_jiffies;
-
/*
* If time_adjust is negative then NTP is slowing the clock
* so make sure not to go into next possible interval.
@@ -178,11 +173,7 @@ void do_gettimeofday(struct timeval *tv)
if (unlikely(time_adjust < 0)) {
max_ntp_tick = (USEC_PER_SEC / HZ) - tickadj;
usec = min(usec, max_ntp_tick);
-
- if (lost)
- usec += lost * max_ntp_tick;
- } else if (unlikely(lost))
- usec += lost * (USEC_PER_SEC / HZ);
+ }
sec = xtime.tv_sec;
usec += (xtime.tv_nsec / 1000);
@@ -217,7 +208,6 @@ int do_settimeofday(struct timespec *tv)
* made, and then undo it!
*/
nsec -= do_gettimeoffset() * NSEC_PER_USEC;
- nsec -= (jiffies - wall_jiffies) * tick_nsec;
wtm_sec = wall_to_monotonic.tv_sec + (xtime.tv_sec - sec);
wtm_nsec = wall_to_monotonic.tv_nsec + (xtime.tv_nsec - nsec);
@@ -434,7 +424,7 @@ irqreturn_t timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
/*
* call the generic timer interrupt handling
*/
- do_timer(regs);
+ do_timer(1);
/*
* If we have an externally synchronized Linux clock, then update
diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c
index e51d8fd9a152..b7292a56d4cd 100644
--- a/arch/mips/kernel/traps.c
+++ b/arch/mips/kernel/traps.c
@@ -41,6 +41,7 @@
#include <asm/mmu_context.h>
#include <asm/watch.h>
#include <asm/types.h>
+#include <asm/stacktrace.h>
extern asmlinkage void handle_int(void);
extern asmlinkage void handle_tlbm(void);
@@ -92,16 +93,14 @@ static void show_raw_backtrace(unsigned long reg29)
}
#ifdef CONFIG_KALLSYMS
-static int raw_show_trace;
+int raw_show_trace;
static int __init set_raw_show_trace(char *str)
{
raw_show_trace = 1;
return 1;
}
__setup("raw_show_trace", set_raw_show_trace);
-
-extern unsigned long unwind_stack(struct task_struct *task, unsigned long *sp,
- unsigned long pc, unsigned long ra);
+#endif
static void show_backtrace(struct task_struct *task, struct pt_regs *regs)
{
@@ -116,14 +115,10 @@ static void show_backtrace(struct task_struct *task, struct pt_regs *regs)
printk("Call Trace:\n");
do {
print_ip_sym(pc);
- pc = unwind_stack(task, &sp, pc, ra);
- ra = 0;
+ pc = unwind_stack(task, &sp, pc, &ra);
} while (pc);
printk("\n");
}
-#else
-#define show_backtrace(task, r) show_raw_backtrace((r)->regs[29]);
-#endif
/*
* This routine abuses get_user()/put_user() to reference pointers
@@ -158,28 +153,6 @@ static void show_stacktrace(struct task_struct *task, struct pt_regs *regs)
show_backtrace(task, regs);
}
-static __always_inline void prepare_frametrace(struct pt_regs *regs)
-{
- __asm__ __volatile__(
- ".set push\n\t"
- ".set noat\n\t"
-#ifdef CONFIG_64BIT
- "1: dla $1, 1b\n\t"
- "sd $1, %0\n\t"
- "sd $29, %1\n\t"
- "sd $31, %2\n\t"
-#else
- "1: la $1, 1b\n\t"
- "sw $1, %0\n\t"
- "sw $29, %1\n\t"
- "sw $31, %2\n\t"
-#endif
- ".set pop\n\t"
- : "=m" (regs->cp0_epc),
- "=m" (regs->regs[29]), "=m" (regs->regs[31])
- : : "memory");
-}
-
void show_stack(struct task_struct *task, unsigned long *sp)
{
struct pt_regs regs;
@@ -206,11 +179,6 @@ void dump_stack(void)
{
struct pt_regs regs;
- /*
- * Remove any garbage that may be in regs (specially func
- * addresses) to avoid show_raw_backtrace() to report them
- */
- memset(&regs, 0, sizeof(regs));
prepare_frametrace(&regs);
show_backtrace(current, &regs);
}
diff --git a/arch/mips/lasat/setup.c b/arch/mips/lasat/setup.c
index 0ffc43c600d9..14c55168f1ff 100644
--- a/arch/mips/lasat/setup.c
+++ b/arch/mips/lasat/setup.c
@@ -34,7 +34,6 @@
#include <asm/cpu.h>
#include <asm/bootinfo.h>
#include <asm/irq.h>
-#include <asm/serial.h>
#include <asm/lasat/lasat.h>
#include <asm/lasat/serial.h>
diff --git a/arch/mips/mm/c-r3k.c b/arch/mips/mm/c-r3k.c
index e1f35ef81145..d1af42c2a52e 100644
--- a/arch/mips/mm/c-r3k.c
+++ b/arch/mips/mm/c-r3k.c
@@ -268,26 +268,6 @@ static void r3k_flush_data_cache_page(unsigned long addr)
{
}
-static void r3k_flush_icache_page(struct vm_area_struct *vma, struct page *page)
-{
- struct mm_struct *mm = vma->vm_mm;
- unsigned long physpage;
-
- if (cpu_context(smp_processor_id(), mm) == 0)
- return;
-
- if (!(vma->vm_flags & VM_EXEC))
- return;
-
-#ifdef DEBUG_CACHE
- printk("cpage[%d,%08lx]", cpu_context(smp_processor_id(), mm), page);
-#endif
-
- physpage = (unsigned long) page_address(page);
- if (physpage)
- r3k_flush_icache_range(physpage, physpage + PAGE_SIZE);
-}
-
static void r3k_flush_cache_sigtramp(unsigned long addr)
{
unsigned long flags;
@@ -335,7 +315,6 @@ void __init r3k_cache_init(void)
flush_cache_mm = r3k_flush_cache_mm;
flush_cache_range = r3k_flush_cache_range;
flush_cache_page = r3k_flush_cache_page;
- __flush_icache_page = r3k_flush_icache_page;
flush_icache_range = r3k_flush_icache_range;
flush_cache_sigtramp = r3k_flush_cache_sigtramp;
diff --git a/arch/mips/mm/c-r4k.c b/arch/mips/mm/c-r4k.c
index 0b2da53750bd..cc895dad71d2 100644
--- a/arch/mips/mm/c-r4k.c
+++ b/arch/mips/mm/c-r4k.c
@@ -551,82 +551,6 @@ static void r4k_flush_icache_range(unsigned long start, unsigned long end)
instruction_hazard();
}
-/*
- * Ok, this seriously sucks. We use them to flush a user page but don't
- * know the virtual address, so we have to blast away the whole icache
- * which is significantly more expensive than the real thing. Otoh we at
- * least know the kernel address of the page so we can flush it
- * selectivly.
- */
-
-struct flush_icache_page_args {
- struct vm_area_struct *vma;
- struct page *page;
-};
-
-static inline void local_r4k_flush_icache_page(void *args)
-{
- struct flush_icache_page_args *fip_args = args;
- struct vm_area_struct *vma = fip_args->vma;
- struct page *page = fip_args->page;
-
- /*
- * Tricky ... Because we don't know the virtual address we've got the
- * choice of either invalidating the entire primary and secondary
- * caches or invalidating the secondary caches also. With the subset
- * enforcment on R4000SC, R4400SC, R10000 and R12000 invalidating the
- * secondary cache will result in any entries in the primary caches
- * also getting invalidated which hopefully is a bit more economical.
- */
- if (cpu_has_inclusive_pcaches) {
- unsigned long addr = (unsigned long) page_address(page);
-
- r4k_blast_scache_page(addr);
- ClearPageDcacheDirty(page);
-
- return;
- }
-
- if (!cpu_has_ic_fills_f_dc) {
- unsigned long addr = (unsigned long) page_address(page);
- r4k_blast_dcache_page(addr);
- if (!cpu_icache_snoops_remote_store)
- r4k_blast_scache_page(addr);
- ClearPageDcacheDirty(page);
- }
-
- /*
- * We're not sure of the virtual address(es) involved here, so
- * we have to flush the entire I-cache.
- */
- if (cpu_has_vtag_icache && vma->vm_mm == current->active_mm) {
- int cpu = smp_processor_id();
-
- if (cpu_context(cpu, vma->vm_mm) != 0)
- drop_mmu_context(vma->vm_mm, cpu);
- } else
- r4k_blast_icache();
-}
-
-static void r4k_flush_icache_page(struct vm_area_struct *vma,
- struct page *page)
-{
- struct flush_icache_page_args args;
-
- /*
- * If there's no context yet, or the page isn't executable, no I-cache
- * flush is needed.
- */
- if (!(vma->vm_flags & VM_EXEC))
- return;
-
- args.vma = vma;
- args.page = page;
-
- r4k_on_each_cpu(local_r4k_flush_icache_page, &args, 1, 1);
-}
-
-
#ifdef CONFIG_DMA_NONCOHERENT
static void r4k_dma_cache_wback_inv(unsigned long addr, unsigned long size)
@@ -1291,7 +1215,6 @@ void __init r4k_cache_init(void)
__flush_cache_all = r4k___flush_cache_all;
flush_cache_mm = r4k_flush_cache_mm;
flush_cache_page = r4k_flush_cache_page;
- __flush_icache_page = r4k_flush_icache_page;
flush_cache_range = r4k_flush_cache_range;
flush_cache_sigtramp = r4k_flush_cache_sigtramp;
diff --git a/arch/mips/mm/c-sb1.c b/arch/mips/mm/c-sb1.c
index 16bad7c0a63f..5537558f19f7 100644
--- a/arch/mips/mm/c-sb1.c
+++ b/arch/mips/mm/c-sb1.c
@@ -307,66 +307,6 @@ void sb1_flush_icache_range(unsigned long start, unsigned long end)
#endif
/*
- * Flush the icache for a given physical page. Need to writeback the
- * dcache first, then invalidate the icache. If the page isn't
- * executable, nothing is required.
- */
-static void local_sb1_flush_icache_page(struct vm_area_struct *vma,
- struct page *page)
-{
- unsigned long start;
- int cpu = smp_processor_id();
-
-#ifndef CONFIG_SMP
- if (!(vma->vm_flags & VM_EXEC))
- return;
-#endif
-
- /* Need to writeback any dirty data for that page, we have the PA */
- start = (unsigned long)(page-mem_map) << PAGE_SHIFT;
- __sb1_writeback_inv_dcache_phys_range(start, start + PAGE_SIZE);
- /*
- * If there's a context, bump the ASID (cheaper than a flush,
- * since we don't know VAs!)
- */
- if (vma->vm_mm == current->active_mm) {
- if (cpu_context(cpu, vma->vm_mm) != 0)
- drop_mmu_context(vma->vm_mm, cpu);
- } else
- __sb1_flush_icache_range(start, start + PAGE_SIZE);
-
-}
-
-#ifdef CONFIG_SMP
-struct flush_icache_page_args {
- struct vm_area_struct *vma;
- struct page *page;
-};
-
-static void sb1_flush_icache_page_ipi(void *info)
-{
- struct flush_icache_page_args *args = info;
- local_sb1_flush_icache_page(args->vma, args->page);
-}
-
-/* Dirty dcache could be on another CPU, so do the IPIs */
-static void sb1_flush_icache_page(struct vm_area_struct *vma,
- struct page *page)
-{
- struct flush_icache_page_args args;
-
- if (!(vma->vm_flags & VM_EXEC))
- return;
- args.vma = vma;
- args.page = page;
- on_each_cpu(sb1_flush_icache_page_ipi, (void *) &args, 1, 1);
-}
-#else
-void sb1_flush_icache_page(struct vm_area_struct *vma, struct page *page)
- __attribute__((alias("local_sb1_flush_icache_page")));
-#endif
-
-/*
* A signal trampoline must fit into a single cacheline.
*/
static void local_sb1_flush_cache_sigtramp(unsigned long addr)
@@ -526,7 +466,6 @@ void sb1_cache_init(void)
/* These routines are for Icache coherence with the Dcache */
flush_icache_range = sb1_flush_icache_range;
- __flush_icache_page = sb1_flush_icache_page;
flush_icache_all = __sb1_flush_icache_all; /* local only */
/* This implies an Icache flush too, so can't be nop'ed */
diff --git a/arch/mips/mm/c-tx39.c b/arch/mips/mm/c-tx39.c
index 932a09d7ef84..f32ebde30ccf 100644
--- a/arch/mips/mm/c-tx39.c
+++ b/arch/mips/mm/c-tx39.c
@@ -248,33 +248,6 @@ static void tx39_flush_icache_range(unsigned long start, unsigned long end)
}
}
-/*
- * Ok, this seriously sucks. We use them to flush a user page but don't
- * know the virtual address, so we have to blast away the whole icache
- * which is significantly more expensive than the real thing. Otoh we at
- * least know the kernel address of the page so we can flush it
- * selectivly.
- */
-static void tx39_flush_icache_page(struct vm_area_struct *vma, struct page *page)
-{
- unsigned long addr;
- /*
- * If there's no context yet, or the page isn't executable, no icache
- * flush is needed.
- */
- if (!(vma->vm_flags & VM_EXEC))
- return;
-
- addr = (unsigned long) page_address(page);
- tx39_blast_dcache_page(addr);
-
- /*
- * We're not sure of the virtual address(es) involved here, so
- * we have to flush the entire I-cache.
- */
- tx39_blast_icache();
-}
-
static void tx39_dma_cache_wback_inv(unsigned long addr, unsigned long size)
{
unsigned long end;
@@ -382,7 +355,6 @@ void __init tx39_cache_init(void)
flush_cache_mm = (void *) tx39h_flush_icache_all;
flush_cache_range = (void *) tx39h_flush_icache_all;
flush_cache_page = (void *) tx39h_flush_icache_all;
- __flush_icache_page = (void *) tx39h_flush_icache_all;
flush_icache_range = (void *) tx39h_flush_icache_all;
flush_cache_sigtramp = (void *) tx39h_flush_icache_all;
@@ -408,7 +380,6 @@ void __init tx39_cache_init(void)
flush_cache_mm = tx39_flush_cache_mm;
flush_cache_range = tx39_flush_cache_range;
flush_cache_page = tx39_flush_cache_page;
- __flush_icache_page = tx39_flush_icache_page;
flush_icache_range = tx39_flush_icache_range;
flush_cache_sigtramp = tx39_flush_cache_sigtramp;
diff --git a/arch/mips/mm/cache.c b/arch/mips/mm/cache.c
index 40c8b0235183..caf807ded514 100644
--- a/arch/mips/mm/cache.c
+++ b/arch/mips/mm/cache.c
@@ -25,7 +25,6 @@ void (*flush_cache_range)(struct vm_area_struct *vma, unsigned long start,
void (*flush_cache_page)(struct vm_area_struct *vma, unsigned long page,
unsigned long pfn);
void (*flush_icache_range)(unsigned long start, unsigned long end);
-void (*__flush_icache_page)(struct vm_area_struct *vma, struct page *page);
/* MIPS specific cache operations */
void (*flush_cache_sigtramp)(unsigned long addr);
diff --git a/arch/mips/mm/fault.c b/arch/mips/mm/fault.c
index a4f8c45c4e8e..8423d8590779 100644
--- a/arch/mips/mm/fault.c
+++ b/arch/mips/mm/fault.c
@@ -171,7 +171,7 @@ no_context:
*/
out_of_memory:
up_read(&mm->mmap_sem);
- if (tsk->pid == 1) {
+ if (is_init(tsk)) {
yield();
down_read(&mm->mmap_sem);
goto survive;
diff --git a/arch/mips/mm/tlbex-fault.S b/arch/mips/mm/tlbex-fault.S
index 9e7f4175b493..e99eaa1fbedc 100644
--- a/arch/mips/mm/tlbex-fault.S
+++ b/arch/mips/mm/tlbex-fault.S
@@ -19,8 +19,8 @@
move a0, sp
REG_S a2, PT_BVADDR(sp)
li a1, \write
- jal do_page_fault
- j ret_from_exception
+ PTR_LA ra, ret_from_exception
+ j do_page_fault
END(tlb_do_page_fault_\write)
.endm
diff --git a/arch/mips/momentum/ocelot_g/gt-irq.c b/arch/mips/momentum/ocelot_g/gt-irq.c
index 9fb2493fff02..6cd87cf0195a 100644
--- a/arch/mips/momentum/ocelot_g/gt-irq.c
+++ b/arch/mips/momentum/ocelot_g/gt-irq.c
@@ -133,7 +133,7 @@ static irqreturn_t gt64240_p0int_irq(int irq, void *dev, struct pt_regs *regs)
MV_WRITE(TIMER_COUNTER_0_3_INTERRUPT_CAUSE, 0x0);
/* handle the timer call */
- do_timer(regs);
+ do_timer(1);
#ifndef CONFIG_SMP
update_process_times(user_mode(regs));
#endif
diff --git a/arch/mips/sgi-ip22/ip22-reset.c b/arch/mips/sgi-ip22/ip22-reset.c
index 8134220ed600..7a941ecff3bb 100644
--- a/arch/mips/sgi-ip22/ip22-reset.c
+++ b/arch/mips/sgi-ip22/ip22-reset.c
@@ -123,7 +123,8 @@ static inline void power_button(void)
if (machine_state & MACHINE_PANICED)
return;
- if ((machine_state & MACHINE_SHUTTING_DOWN) || kill_proc(1,SIGINT,1)) {
+ if ((machine_state & MACHINE_SHUTTING_DOWN) ||
+ kill_cad_pid(SIGINT, 1)) {
/* No init process or button pressed twice. */
sgi_machine_power_off();
}
diff --git a/arch/mips/sgi-ip27/ip27-timer.c b/arch/mips/sgi-ip27/ip27-timer.c
index b029ba79c27a..257ce118e380 100644
--- a/arch/mips/sgi-ip27/ip27-timer.c
+++ b/arch/mips/sgi-ip27/ip27-timer.c
@@ -42,8 +42,6 @@
static unsigned long ct_cur[NR_CPUS]; /* What counter should be at next timer irq */
static long last_rtc_update; /* Last time the rtc clock got updated */
-extern volatile unsigned long wall_jiffies;
-
#if 0
static int set_rtc_mmss(unsigned long nowtime)
{
@@ -111,7 +109,7 @@ again:
kstat_this_cpu.irqs[irq]++; /* kstat only for bootcpu? */
if (cpu == 0)
- do_timer(regs);
+ do_timer(1);
update_process_times(user_mode(regs));
diff --git a/arch/mips/sgi-ip32/ip32-reset.c b/arch/mips/sgi-ip32/ip32-reset.c
index 79ddb4605659..fd0932b2d521 100644
--- a/arch/mips/sgi-ip32/ip32-reset.c
+++ b/arch/mips/sgi-ip32/ip32-reset.c
@@ -120,7 +120,7 @@ static inline void ip32_power_button(void)
if (has_panicked)
return;
- if (shuting_down || kill_proc(1, SIGINT, 1)) {
+ if (shuting_down || kill_cad_pid(SIGINT, 1)) {
/* No init process or button pressed twice. */
ip32_machine_power_off();
}
diff --git a/arch/parisc/hpux/fs.c b/arch/parisc/hpux/fs.c
index d7c80edf4489..6e79dbf3f6bd 100644
--- a/arch/parisc/hpux/fs.c
+++ b/arch/parisc/hpux/fs.c
@@ -77,17 +77,21 @@ static int filldir(void * __buf, const char * name, int namlen, loff_t offset,
{
struct hpux_dirent * dirent;
struct getdents_callback * buf = (struct getdents_callback *) __buf;
+ ino_t d_ino;
int reclen = ROUND_UP(NAME_OFFSET(dirent) + namlen + 1);
buf->error = -EINVAL; /* only used if we fail.. */
if (reclen > buf->count)
return -EINVAL;
+ d_ino = ino;
+ if (sizeof(d_ino) < sizeof(ino) && d_ino != ino)
+ return -EOVERFLOW;
dirent = buf->previous;
if (dirent)
put_user(offset, &dirent->d_off);
dirent = buf->current_dir;
buf->previous = dirent;
- put_user(ino, &dirent->d_ino);
+ put_user(d_ino, &dirent->d_ino);
put_user(reclen, &dirent->d_reclen);
put_user(namlen, &dirent->d_namlen);
copy_to_user(dirent->d_name, name, namlen);
diff --git a/arch/parisc/hpux/sys_hpux.c b/arch/parisc/hpux/sys_hpux.c
index cb69727027ae..2e2dc4f2c853 100644
--- a/arch/parisc/hpux/sys_hpux.c
+++ b/arch/parisc/hpux/sys_hpux.c
@@ -266,16 +266,21 @@ static int hpux_uname(struct hpux_utsname *name)
down_read(&uts_sem);
- error = __copy_to_user(&name->sysname,&system_utsname.sysname,HPUX_UTSLEN-1);
- error |= __put_user(0,name->sysname+HPUX_UTSLEN-1);
- error |= __copy_to_user(&name->nodename,&system_utsname.nodename,HPUX_UTSLEN-1);
- error |= __put_user(0,name->nodename+HPUX_UTSLEN-1);
- error |= __copy_to_user(&name->release,&system_utsname.release,HPUX_UTSLEN-1);
- error |= __put_user(0,name->release+HPUX_UTSLEN-1);
- error |= __copy_to_user(&name->version,&system_utsname.version,HPUX_UTSLEN-1);
- error |= __put_user(0,name->version+HPUX_UTSLEN-1);
- error |= __copy_to_user(&name->machine,&system_utsname.machine,HPUX_UTSLEN-1);
- error |= __put_user(0,name->machine+HPUX_UTSLEN-1);
+ error = __copy_to_user(&name->sysname, &utsname()->sysname,
+ HPUX_UTSLEN - 1);
+ error |= __put_user(0, name->sysname + HPUX_UTSLEN - 1);
+ error |= __copy_to_user(&name->nodename, &utsname()->nodename,
+ HPUX_UTSLEN - 1);
+ error |= __put_user(0, name->nodename + HPUX_UTSLEN - 1);
+ error |= __copy_to_user(&name->release, &utsname()->release,
+ HPUX_UTSLEN - 1);
+ error |= __put_user(0, name->release + HPUX_UTSLEN - 1);
+ error |= __copy_to_user(&name->version, &utsname()->version,
+ HPUX_UTSLEN - 1);
+ error |= __put_user(0, name->version + HPUX_UTSLEN - 1);
+ error |= __copy_to_user(&name->machine, &utsname()->machine,
+ HPUX_UTSLEN - 1);
+ error |= __put_user(0, name->machine + HPUX_UTSLEN - 1);
up_read(&uts_sem);
@@ -373,8 +378,8 @@ int hpux_utssys(char *ubuf, int n, int type)
/* TODO: print a warning about using this? */
down_write(&uts_sem);
error = -EFAULT;
- if (!copy_from_user(system_utsname.sysname, ubuf, len)) {
- system_utsname.sysname[len] = 0;
+ if (!copy_from_user(utsname()->sysname, ubuf, len)) {
+ utsname()->sysname[len] = 0;
error = 0;
}
up_write(&uts_sem);
@@ -400,8 +405,8 @@ int hpux_utssys(char *ubuf, int n, int type)
/* TODO: print a warning about this? */
down_write(&uts_sem);
error = -EFAULT;
- if (!copy_from_user(system_utsname.release, ubuf, len)) {
- system_utsname.release[len] = 0;
+ if (!copy_from_user(utsname()->release, ubuf, len)) {
+ utsname()->release[len] = 0;
error = 0;
}
up_write(&uts_sem);
@@ -422,13 +427,13 @@ int hpux_getdomainname(char *name, int len)
down_read(&uts_sem);
- nlen = strlen(system_utsname.domainname) + 1;
+ nlen = strlen(utsname()->domainname) + 1;
if (nlen < len)
len = nlen;
if(len > __NEW_UTS_LEN)
goto done;
- if(copy_to_user(name, system_utsname.domainname, len))
+ if(copy_to_user(name, utsname()->domainname, len))
goto done;
err = 0;
done:
diff --git a/arch/parisc/kernel/firmware.c b/arch/parisc/kernel/firmware.c
index 4398d2a95789..c2531ae032cf 100644
--- a/arch/parisc/kernel/firmware.c
+++ b/arch/parisc/kernel/firmware.c
@@ -1049,7 +1049,7 @@ void pdc_iodc_putc(unsigned char c)
static int __attribute__((aligned(8))) iodc_retbuf[32];
static char __attribute__((aligned(64))) iodc_dbuf[4096];
unsigned int n;
- unsigned int flags;
+ unsigned long flags;
switch (c) {
case '\n':
@@ -1088,7 +1088,8 @@ void pdc_iodc_putc(unsigned char c)
*/
void pdc_iodc_outc(unsigned char c)
{
- unsigned int n, flags;
+ unsigned int n;
+ unsigned long flags;
/* fill buffer with one caracter and print it */
static int __attribute__((aligned(8))) iodc_retbuf[32];
@@ -1113,7 +1114,7 @@ void pdc_iodc_outc(unsigned char c)
*/
int pdc_iodc_getc(void)
{
- unsigned int flags;
+ unsigned long flags;
static int __attribute__((aligned(8))) iodc_retbuf[32];
static char __attribute__((aligned(64))) iodc_dbuf[4096];
int ch;
diff --git a/arch/parisc/kernel/module.c b/arch/parisc/kernel/module.c
index aee311884f3f..f50b982b0834 100644
--- a/arch/parisc/kernel/module.c
+++ b/arch/parisc/kernel/module.c
@@ -27,7 +27,7 @@
* - SEGREL32 handling
* We are not doing SEGREL32 handling correctly. According to the ABI, we
* should do a value offset, like this:
- * if (is_init(me, (void *)val))
+ * if (in_init(me, (void *)val))
* val -= (uint32_t)me->module_init;
* else
* val -= (uint32_t)me->module_core;
@@ -72,27 +72,27 @@
/* three functions to determine where in the module core
* or init pieces the location is */
-static inline int is_init(struct module *me, void *loc)
+static inline int in_init(struct module *me, void *loc)
{
return (loc >= me->module_init &&
loc <= (me->module_init + me->init_size));
}
-static inline int is_core(struct module *me, void *loc)
+static inline int in_core(struct module *me, void *loc)
{
return (loc >= me->module_core &&
loc <= (me->module_core + me->core_size));
}
-static inline int is_local(struct module *me, void *loc)
+static inline int in_local(struct module *me, void *loc)
{
- return is_init(me, loc) || is_core(me, loc);
+ return in_init(me, loc) || in_core(me, loc);
}
-static inline int is_local_section(struct module *me, void *loc, void *dot)
+static inline int in_local_section(struct module *me, void *loc, void *dot)
{
- return (is_init(me, loc) && is_init(me, dot)) ||
- (is_core(me, loc) && is_core(me, dot));
+ return (in_init(me, loc) && in_init(me, dot)) ||
+ (in_core(me, loc) && in_core(me, dot));
}
@@ -566,14 +566,14 @@ int apply_relocate_add(Elf_Shdr *sechdrs,
break;
case R_PARISC_PCREL17F:
/* 17-bit PC relative address */
- val = get_stub(me, val, addend, ELF_STUB_GOT, is_init(me, loc));
+ val = get_stub(me, val, addend, ELF_STUB_GOT, in_init(me, loc));
val = (val - dot - 8)/4;
CHECK_RELOC(val, 17)
*loc = (*loc & ~0x1f1ffd) | reassemble_17(val);
break;
case R_PARISC_PCREL22F:
/* 22-bit PC relative address; only defined for pa20 */
- val = get_stub(me, val, addend, ELF_STUB_GOT, is_init(me, loc));
+ val = get_stub(me, val, addend, ELF_STUB_GOT, in_init(me, loc));
DEBUGP("STUB FOR %s loc %lx+%lx at %lx\n",
strtab + sym->st_name, (unsigned long)loc, addend,
val)
@@ -670,9 +670,9 @@ int apply_relocate_add(Elf_Shdr *sechdrs,
strtab + sym->st_name,
loc, val);
/* can we reach it locally? */
- if(!is_local_section(me, (void *)val, (void *)dot)) {
+ if(!in_local_section(me, (void *)val, (void *)dot)) {
- if (is_local(me, (void *)val))
+ if (in_local(me, (void *)val))
/* this is the case where the
* symbol is local to the
* module, but in a different
@@ -680,14 +680,14 @@ int apply_relocate_add(Elf_Shdr *sechdrs,
* in case it's more than 22
* bits away */
val = get_stub(me, val, addend, ELF_STUB_DIRECT,
- is_init(me, loc));
+ in_init(me, loc));
else if (strncmp(strtab + sym->st_name, "$$", 2)
== 0)
val = get_stub(me, val, addend, ELF_STUB_MILLI,
- is_init(me, loc));
+ in_init(me, loc));
else
val = get_stub(me, val, addend, ELF_STUB_GOT,
- is_init(me, loc));
+ in_init(me, loc));
}
DEBUGP("STUB FOR %s loc %lx, val %lx+%lx at %lx\n",
strtab + sym->st_name, loc, sym->st_value,
@@ -720,7 +720,7 @@ int apply_relocate_add(Elf_Shdr *sechdrs,
break;
case R_PARISC_FPTR64:
/* 64-bit function address */
- if(is_local(me, (void *)(val + addend))) {
+ if(in_local(me, (void *)(val + addend))) {
*loc64 = get_fdesc(me, val+addend);
DEBUGP("FDESC for %s at %p points to %lx\n",
strtab + sym->st_name, *loc64,
diff --git a/arch/parisc/kernel/process.c b/arch/parisc/kernel/process.c
index 0b485ef4be89..2f9f9dfa66f7 100644
--- a/arch/parisc/kernel/process.c
+++ b/arch/parisc/kernel/process.c
@@ -368,7 +368,14 @@ out:
return error;
}
-unsigned long
+extern int __execve(const char *filename, char *const argv[],
+ char *const envp[], struct task_struct *task);
+int kernel_execve(const char *filename, char *const argv[], char *const envp[])
+{
+ return __execve(filename, argv, envp, current);
+}
+
+unsigned long
get_wchan(struct task_struct *p)
{
struct unwind_frame_info info;
diff --git a/arch/parisc/kernel/sys_parisc32.c b/arch/parisc/kernel/sys_parisc32.c
index b74869803081..e3b30bc36453 100644
--- a/arch/parisc/kernel/sys_parisc32.c
+++ b/arch/parisc/kernel/sys_parisc32.c
@@ -237,14 +237,19 @@ int sys32_settimeofday(struct compat_timeval __user *tv, struct timezone __user
int cp_compat_stat(struct kstat *stat, struct compat_stat __user *statbuf)
{
+ compat_ino_t ino;
int err;
if (stat->size > MAX_NON_LFS || !new_valid_dev(stat->dev) ||
!new_valid_dev(stat->rdev))
return -EOVERFLOW;
+ ino = stat->ino;
+ if (sizeof(ino) < sizeof(stat->ino) && ino != stat->ino)
+ return -EOVERFLOW;
+
err = put_user(new_encode_dev(stat->dev), &statbuf->st_dev);
- err |= put_user(stat->ino, &statbuf->st_ino);
+ err |= put_user(ino, &statbuf->st_ino);
err |= put_user(stat->mode, &statbuf->st_mode);
err |= put_user(stat->nlink, &statbuf->st_nlink);
err |= put_user(0, &statbuf->st_reserved1);
@@ -312,16 +317,20 @@ filldir32 (void *__buf, const char *name, int namlen, loff_t offset, ino_t ino,
struct linux32_dirent __user * dirent;
struct getdents32_callback * buf = (struct getdents32_callback *) __buf;
int reclen = ROUND_UP(NAME_OFFSET(dirent) + namlen + 1, 4);
+ u32 d_ino;
buf->error = -EINVAL; /* only used if we fail.. */
if (reclen > buf->count)
return -EINVAL;
+ d_ino = ino;
+ if (sizeof(d_ino) < sizeof(ino) && d_ino != ino)
+ return -EOVERFLOW;
dirent = buf->previous;
if (dirent)
put_user(offset, &dirent->d_off);
dirent = buf->current_dir;
buf->previous = dirent;
- put_user(ino, &dirent->d_ino);
+ put_user(d_ino, &dirent->d_ino);
put_user(reclen, &dirent->d_reclen);
copy_to_user(dirent->d_name, name, namlen);
put_user(0, dirent->d_name + namlen);
@@ -371,12 +380,16 @@ fillonedir32 (void * __buf, const char * name, int namlen, loff_t offset, ino_t
{
struct readdir32_callback * buf = (struct readdir32_callback *) __buf;
struct old_linux32_dirent __user * dirent;
+ u32 d_ino;
if (buf->count)
return -EINVAL;
+ d_ino = ino;
+ if (sizeof(d_ino) < sizeof(ino) && d_ino != ino)
+ return -EOVERFLOW;
buf->count++;
dirent = buf->dirent;
- put_user(ino, &dirent->d_ino);
+ put_user(d_ino, &dirent->d_ino);
put_user(offset, &dirent->d_offset);
put_user(namlen, &dirent->d_namlen);
copy_to_user(dirent->d_name, name, namlen);
diff --git a/arch/parisc/kernel/time.c b/arch/parisc/kernel/time.c
index 5facc9bff4ef..ab641d67f551 100644
--- a/arch/parisc/kernel/time.c
+++ b/arch/parisc/kernel/time.c
@@ -32,9 +32,6 @@
#include <linux/timex.h>
-/* xtime and wall_jiffies keep wall-clock time */
-extern unsigned long wall_jiffies;
-
static long clocktick __read_mostly; /* timer cycles per tick */
static long halftick __read_mostly;
@@ -79,7 +76,7 @@ irqreturn_t timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
#endif
if (cpu == 0) {
write_seqlock(&xtime_lock);
- do_timer(regs);
+ do_timer(1);
write_sequnlock(&xtime_lock);
}
}
@@ -112,7 +109,7 @@ EXPORT_SYMBOL(profile_pc);
/*** converted from ia64 ***/
/*
* Return the number of micro-seconds that elapsed since the last
- * update to wall time (aka xtime aka wall_jiffies). The xtime_lock
+ * update to wall time (aka xtime). The xtime_lock
* must be at least read-locked when calling this routine.
*/
static inline unsigned long
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index a0dd1b0ee483..032e6ab5d3c4 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -1069,7 +1069,7 @@ source "arch/powerpc/oprofile/Kconfig"
config KPROBES
bool "Kprobes (EXPERIMENTAL)"
- depends on PPC64 && EXPERIMENTAL && MODULES
+ depends on PPC64 && KALLSYMS && EXPERIMENTAL && MODULES
help
Kprobes allows you to trap at almost any kernel address and
execute a callback function. register_kprobe() establishes
diff --git a/arch/powerpc/Makefile b/arch/powerpc/Makefile
index 01667d1d571d..a00fe7236555 100644
--- a/arch/powerpc/Makefile
+++ b/arch/powerpc/Makefile
@@ -20,6 +20,7 @@ CROSS32_COMPILE ?=
CROSS32CC := $(CROSS32_COMPILE)gcc
CROSS32AS := $(CROSS32_COMPILE)as
CROSS32LD := $(CROSS32_COMPILE)ld
+CROSS32AR := $(CROSS32_COMPILE)ar
CROSS32OBJCOPY := $(CROSS32_COMPILE)objcopy
ifeq ($(HAS_BIARCH),y)
@@ -28,10 +29,11 @@ CROSS32CC := $(CC) -m32
CROSS32AS := $(AS) -a32
CROSS32LD := $(LD) -m elf32ppc
CROSS32OBJCOPY := $(OBJCOPY)
+CROSS32AR := $(AR)
endif
endif
-export CROSS32CC CROSS32AS CROSS32LD CROSS32OBJCOPY
+export CROSS32CC CROSS32AS CROSS32LD CROSS32AR CROSS32OBJCOPY
KBUILD_DEFCONFIG := $(shell uname -m)_defconfig
@@ -146,7 +148,7 @@ all: $(KBUILD_IMAGE)
CPPFLAGS_vmlinux.lds := -Upowerpc
-BOOT_TARGETS = zImage zImage.initrd znetboot znetboot.initrd vmlinux.sm uImage vmlinux.bin
+BOOT_TARGETS = zImage zImage.initrd uImage
PHONY += $(BOOT_TARGETS)
diff --git a/arch/powerpc/boot/Makefile b/arch/powerpc/boot/Makefile
index e73774136b55..c383d56bbe18 100644
--- a/arch/powerpc/boot/Makefile
+++ b/arch/powerpc/boot/Makefile
@@ -20,33 +20,34 @@
# CROSS32_COMPILE is setup as a prefix just like CROSS_COMPILE
# in the toplevel makefile.
+all: $(obj)/zImage
HOSTCC := gcc
BOOTCFLAGS := $(HOSTCFLAGS) -fno-builtin -nostdinc -isystem \
$(shell $(CROSS32CC) -print-file-name=include) -fPIC
BOOTAFLAGS := -D__ASSEMBLY__ $(BOOTCFLAGS) -traditional -nostdinc
-OBJCOPYFLAGS := contents,alloc,load,readonly,data
-OBJCOPY_COFF_ARGS := -O aixcoff-rs6000 --set-start 0x500000
-OBJCOPY_MIB_ARGS := -O aixcoff-rs6000 -R .stab -R .stabstr -R .comment
+
+ifeq ($(call cc-option-yn, -fstack-protector),y)
+BOOTCFLAGS += -fno-stack-protector
+endif
+
+BOOTCFLAGS += -I$(obj) -I$(srctree)/$(obj)
zlib := inffast.c inflate.c inftrees.c
zlibheader := inffast.h inffixed.h inflate.h inftrees.h infutil.h
zliblinuxheader := zlib.h zconf.h zutil.h
-$(addprefix $(obj)/,$(zlib) main.o): $(addprefix $(obj)/,$(zliblinuxheader)) $(addprefix $(obj)/,$(zlibheader))
-#$(addprefix $(obj)/,main.o): $(addprefix $(obj)/,zlib.h)
+$(addprefix $(obj)/,$(zlib) main.o): $(addprefix $(obj)/,$(zliblinuxheader)) \
+ $(addprefix $(obj)/,$(zlibheader))
+
+src-wlib := string.S stdio.c main.c div64.S $(zlib)
+src-plat := of.c
+src-boot := crt0.S $(src-wlib) $(src-plat) empty.c
-src-boot-$(CONFIG_PPC_MULTIPLATFORM) := of.c
-src-boot := crt0.S string.S stdio.c main.c div64.S $(src-boot-y)
-src-boot += $(zlib)
src-boot := $(addprefix $(obj)/, $(src-boot))
obj-boot := $(addsuffix .o, $(basename $(src-boot)))
-
-ifeq ($(call cc-option-yn, -fstack-protector),y)
-BOOTCFLAGS += -fno-stack-protector
-endif
-
-BOOTCFLAGS += -I$(obj) -I$(srctree)/$(obj)
+obj-wlib := $(addsuffix .o, $(basename $(addprefix $(obj)/, $(src-wlib))))
+obj-plat := $(addsuffix .o, $(basename $(addprefix $(obj)/, $(src-plat))))
quiet_cmd_copy_zlib = COPY $@
cmd_copy_zlib = sed "s@__attribute_used__@@;s@<linux/\([^>]\+\).*@\"\1\"@" $< > $@
@@ -66,8 +67,14 @@ $(addprefix $(obj)/,$(zlibheader)): $(obj)/%: $(srctree)/lib/zlib_inflate/%
$(addprefix $(obj)/,$(zliblinuxheader)): $(obj)/%: $(srctree)/include/linux/%
$(call cmd,copy_zliblinuxheader)
-clean-files := $(zlib) $(zlibheader) $(zliblinuxheader)
+$(obj)/empty.c:
+ @touch $@
+
+$(obj)/zImage.lds $(obj)/zImage.coff.lds: $(obj)/%: $(srctree)/$(src)/%.S
+ @cp $< $@
+clean-files := $(zlib) $(zlibheader) $(zliblinuxheader) \
+ $(obj)/empty.c
quiet_cmd_bootcc = BOOTCC $@
cmd_bootcc = $(CROSS32CC) -Wp,-MD,$(depfile) $(BOOTCFLAGS) -c -o $@ $<
@@ -75,146 +82,97 @@ quiet_cmd_bootcc = BOOTCC $@
quiet_cmd_bootas = BOOTAS $@
cmd_bootas = $(CROSS32CC) -Wp,-MD,$(depfile) $(BOOTAFLAGS) -c -o $@ $<
-quiet_cmd_bootld = BOOTLD $@
- cmd_bootld = $(CROSS32LD) -T $(srctree)/$(src)/$(3) -o $@ $(2)
+quiet_cmd_bootar = BOOTAR $@
+ cmd_bootar = $(CROSS32AR) -cr $@.$$$$ $^; mv $@.$$$$ $@
$(patsubst %.c,%.o, $(filter %.c, $(src-boot))): %.o: %.c
$(call if_changed_dep,bootcc)
$(patsubst %.S,%.o, $(filter %.S, $(src-boot))): %.o: %.S
$(call if_changed_dep,bootas)
-#-----------------------------------------------------------
-# ELF sections within the zImage bootloader/wrapper
-#-----------------------------------------------------------
-required := vmlinux.strip
-initrd := initrd
+$(obj)/wrapper.a: $(obj-wlib)
+ $(call cmd,bootar)
-obj-sec = $(foreach section, $(1), $(patsubst %,$(obj)/kernel-%.o, $(section)))
-src-sec = $(foreach section, $(1), $(patsubst %,$(obj)/kernel-%.c, $(section)))
-gz-sec = $(foreach section, $(1), $(patsubst %,$(obj)/kernel-%.gz, $(section)))
+hostprogs-y := addnote addRamDisk hack-coff
-hostprogs-y := addnote addRamDisk hack-coff
+extra-y := $(obj)/crt0.o $(obj)/wrapper.a $(obj-plat) $(obj)/empty.o \
+ $(obj)/zImage.lds $(obj)/zImage.coff.lds
-targets += zImage.vmode zImage.initrd.vmode zImage zImage.initrd \
- zImage.coff zImage.initrd.coff miboot.image miboot.initrd.image \
- $(patsubst $(obj)/%,%, $(call obj-sec, $(required) $(initrd))) \
- $(patsubst $(obj)/%,%, $(call src-sec, $(required) $(initrd))) \
- $(patsubst $(obj)/%,%, $(call gz-sec, $(required) $(initrd))) \
- vmlinux.initrd dummy.o
-extra-y := initrd.o
+wrapper :=$(srctree)/$(src)/wrapper
+wrapperbits := $(extra-y) $(addprefix $(obj)/,addnote hack-coff)
-quiet_cmd_ramdisk = RAMDISK $@
- cmd_ramdisk = $(obj)/addRamDisk $(obj)/ramdisk.image.gz $< $@
+#############
+# Bits for building various flavours of zImage
-quiet_cmd_stripvm = STRIP $@
- cmd_stripvm = $(STRIP) -s -R .comment $< -o $@
+ifneq ($(CROSS32_COMPILE),)
+CROSSWRAP := -C $(CROSS32_COMPILE)
+else
+ifneq ($(CROSS_COMPILE),)
+CROSSWRAP := -C $(CROSS_COMPILE)
+endif
+endif
-vmlinux.strip: vmlinux
- $(call if_changed,stripvm)
-$(obj)/vmlinux.initrd: vmlinux.strip $(obj)/addRamDisk $(obj)/ramdisk.image.gz
- $(call if_changed,ramdisk)
+quiet_cmd_wrap = WRAP $@
+ cmd_wrap =$(wrapper) -c -o $@ -p $2 $(CROSSWRAP) vmlinux
+quiet_cmd_wrap_initrd = WRAP $@
+ cmd_wrap_initrd =$(wrapper) -c -o $@ -p $2 $(CROSSWRAP) \
+ -i $(obj)/ramdisk.image.gz vmlinux
-quiet_cmd_addsection = ADDSEC $@
- cmd_addsection = $(CROSS32OBJCOPY) $@ \
- --add-section=.kernel:$(strip $(patsubst $(obj)/kernel-%.o,%, $@))=$(patsubst %.o,%.gz, $@) \
- --set-section-flags=.kernel:$(strip $(patsubst $(obj)/kernel-%.o,%, $@))=$(OBJCOPYFLAGS)
+$(obj)/zImage.chrp: vmlinux $(wrapperbits)
+ $(call cmd,wrap,chrp)
-quiet_cmd_addnote = ADDNOTE $@
- cmd_addnote = $(obj)/addnote $@
+$(obj)/zImage.initrd.chrp: vmlinux $(wrapperbits)
+ $(call cmd,wrap_initrd,chrp)
-quiet_cmd_gen-miboot = GEN $@
- cmd_gen-miboot = $(OBJCOPY) $(OBJCOPY_MIB_ARGS) \
- --add-section=$1=$(word 2, $^) $< $@
+$(obj)/zImage.pseries: vmlinux $(wrapperbits)
+ $(call cmd,wrap,pseries)
-quiet_cmd_gencoff = COFF $@
- cmd_gencoff = $(OBJCOPY) $(OBJCOPY_COFF_ARGS) $@ && \
- $(obj)/hack-coff $@
+$(obj)/zImage.initrd.pseries: vmlinux $(wrapperbits)
+ $(call cmd,wrap_initrd,pseries)
-$(call gz-sec, $(required)): $(obj)/kernel-%.gz: %
- $(call if_changed,gzip)
+$(obj)/zImage.pmac: vmlinux $(wrapperbits)
+ $(call cmd,wrap,pmac)
-$(obj)/kernel-initrd.gz: $(obj)/ramdisk.image.gz
- cp -f $(obj)/ramdisk.image.gz $@
+$(obj)/zImage.initrd.pmac: vmlinux $(wrapperbits)
+ $(call cmd,wrap_initrd,pmac)
-$(call src-sec, $(required) $(initrd)): $(obj)/kernel-%.c: $(obj)/kernel-%.gz
- @touch $@
+$(obj)/zImage.coff: vmlinux $(wrapperbits)
+ $(call cmd,wrap,pmaccoff)
-$(call obj-sec, $(required) $(initrd)): $(obj)/kernel-%.o: $(obj)/kernel-%.c
- $(call if_changed_dep,bootcc)
- $(call cmd,addsection)
+$(obj)/zImage.initrd.coff: vmlinux $(wrapperbits)
+ $(call cmd,wrap_initrd,pmaccoff)
+
+$(obj)/zImage.miboot: vmlinux $(wrapperbits)
+ $(call cmd,wrap,miboot)
-$(obj)/zImage.vmode $(obj)/zImage.coff: obj-boot += $(call obj-sec, $(required))
-$(obj)/zImage.vmode: $(call obj-sec, $(required)) $(obj-boot) $(srctree)/$(src)/zImage.lds
- $(call cmd,bootld,$(obj-boot),zImage.lds)
+$(obj)/zImage.initrd.miboot: vmlinux $(wrapperbits)
+ $(call cmd,wrap_initrd,miboot)
-$(obj)/zImage.initrd.vmode $(obj)/zImage.initrd.coff: obj-boot += $(call obj-sec, $(required) $(initrd))
-$(obj)/zImage.initrd.vmode: $(call obj-sec, $(required) $(initrd)) $(obj-boot) $(srctree)/$(src)/zImage.lds
- $(call cmd,bootld,$(obj-boot),zImage.lds)
+$(obj)/uImage: vmlinux $(wrapperbits)
+ $(call cmd,wrap,uboot)
+
+image-$(CONFIG_PPC_PSERIES) += zImage.pseries
+image-$(CONFIG_PPC_MAPLE) += zImage.pseries
+image-$(CONFIG_PPC_CELL) += zImage.pseries
+image-$(CONFIG_PPC_CHRP) += zImage.chrp
+image-$(CONFIG_PPC_PMAC) += zImage.pmac
+image-$(CONFIG_DEFAULT_UIMAGE) += uImage
# For 32-bit powermacs, build the COFF and miboot images
# as well as the ELF images.
-coffimage-$(CONFIG_PPC_PMAC)-$(CONFIG_PPC32) := $(obj)/zImage.coff
-coffrdimg-$(CONFIG_PPC_PMAC)-$(CONFIG_PPC32) := $(obj)/zImage.initrd.coff
-mibootimg-$(CONFIG_PPC_PMAC)-$(CONFIG_PPC32) := $(obj)/miboot.image
-mibrdimg-$(CONFIG_PPC_PMAC)-$(CONFIG_PPC32) := $(obj)/miboot.initrd.image
-
-$(obj)/zImage: $(obj)/zImage.vmode $(obj)/addnote $(coffimage-y-y) \
- $(mibootimg-y-y)
- @cp -f $< $@
- $(call if_changed,addnote)
-
-$(obj)/zImage.initrd: $(obj)/zImage.initrd.vmode $(obj)/addnote \
- $(coffrdimg-y-y) $(mibrdimg-y-y)
- @cp -f $< $@
- $(call if_changed,addnote)
-
-$(obj)/zImage.coff: $(call obj-sec, $(required)) $(obj-boot) \
- $(srctree)/$(src)/zImage.coff.lds $(obj)/hack-coff
- $(call cmd,bootld,$(obj-boot),zImage.coff.lds)
- $(call cmd,gencoff)
-
-$(obj)/zImage.initrd.coff: $(call obj-sec, $(required) $(initrd)) $(obj-boot) \
- $(srctree)/$(src)/zImage.coff.lds $(obj)/hack-coff
- $(call cmd,bootld,$(obj-boot),zImage.coff.lds)
- $(call cmd,gencoff)
-
-$(obj)/miboot.image: $(obj)/dummy.o $(obj)/vmlinux.gz
- $(call cmd,gen-miboot,image)
-
-$(obj)/miboot.initrd.image: $(obj)/miboot.image $(images)/ramdisk.image.gz
- $(call cmd,gen-miboot,initrd)
-
-#-----------------------------------------------------------
-# build u-boot images
-#-----------------------------------------------------------
-quiet_cmd_mygzip = GZIP $@
-cmd_mygzip = gzip -f -9 < $< > $@.$$$$ && mv $@.$$$$ $@
-
-quiet_cmd_objbin = OBJCOPY $@
- cmd_objbin = $(OBJCOPY) -O binary $< $@
-
-quiet_cmd_uimage = UIMAGE $@
- cmd_uimage = $(CONFIG_SHELL) $(MKIMAGE) -A ppc -O linux -T kernel \
- -C gzip -a 00000000 -e 00000000 -n 'Linux-$(KERNELRELEASE)' \
- -d $< $@
-
-MKIMAGE := $(srctree)/scripts/mkuboot.sh
-targets += uImage
-extra-y += vmlinux.bin vmlinux.gz
-
-$(obj)/vmlinux.bin: vmlinux FORCE
- $(call if_changed,objbin)
-
-$(obj)/vmlinux.gz: $(obj)/vmlinux.bin FORCE
- $(call if_changed,mygzip)
-
-$(obj)/uImage: $(obj)/vmlinux.gz
- $(Q)rm -f $@
- $(call cmd,uimage)
- @echo -n ' Image: $@ '
- @if [ -f $@ ]; then echo 'is ready' ; else echo 'not made'; fi
-
-install: $(CONFIGURE) $(BOOTIMAGE)
- sh -x $(srctree)/$(src)/install.sh "$(KERNELRELEASE)" vmlinux System.map "$(INSTALL_PATH)" "$(BOOTIMAGE)"
-
-clean-files += $(addprefix $(objtree)/, $(obj-boot) vmlinux.strip)
+ifeq ($(CONFIG_PPC32),y)
+image-$(CONFIG_PPC_PMAC) += zImage.coff zImage.miboot
+endif
+
+initrd-y := $(patsubst zImage%, zImage.initrd%, $(image-y))
+
+$(obj)/zImage: $(addprefix $(obj)/, $(image-y))
+ @rm -f $@; ln $< $@
+$(obj)/zImage.initrd: $(addprefix $(obj)/, $(initrd-y))
+ @rm -f $@; ln $< $@
+
+install: $(CONFIGURE) $(image-y)
+ sh -x $(srctree)/$(src)/install.sh "$(KERNELRELEASE)" vmlinux System.map "$(INSTALL_PATH)" $<
+
+clean-files += $(addprefix $(objtree)/, $(obj-boot) vmlinux.strip.gz)
+clean-files += $(addprefix $(objtree)/, $(obj-boot) vmlinux.bin.gz)
diff --git a/arch/powerpc/boot/dts/mpc8560ads.dts b/arch/powerpc/boot/dts/mpc8560ads.dts
new file mode 100644
index 000000000000..2b168486aeba
--- /dev/null
+++ b/arch/powerpc/boot/dts/mpc8560ads.dts
@@ -0,0 +1,302 @@
+/*
+ * MPC8560 ADS Device Tree Source
+ *
+ * Copyright 2006 Freescale Semiconductor Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+
+/ {
+ model = "MPC8560ADS";
+ compatible = "MPC85xxADS";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ linux,phandle = <100>;
+
+ cpus {
+ #cpus = <1>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ linux,phandle = <200>;
+
+ PowerPC,8560@0 {
+ device_type = "cpu";
+ reg = <0>;
+ d-cache-line-size = <20>; // 32 bytes
+ i-cache-line-size = <20>; // 32 bytes
+ d-cache-size = <8000>; // L1, 32K
+ i-cache-size = <8000>; // L1, 32K
+ timebase-frequency = <04ead9a0>;
+ bus-frequency = <13ab6680>;
+ clock-frequency = <312c8040>;
+ 32-bit;
+ linux,phandle = <201>;
+ linux,boot-cpu;
+ };
+ };
+
+ memory {
+ device_type = "memory";
+ linux,phandle = <300>;
+ reg = <00000000 10000000>;
+ };
+
+ soc8560@e0000000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ #interrupt-cells = <2>;
+ device_type = "soc";
+ ranges = <0 e0000000 00100000>;
+ reg = <e0000000 00000200>;
+ bus-frequency = <13ab6680>;
+
+ mdio@24520 {
+ device_type = "mdio";
+ compatible = "gianfar";
+ reg = <24520 20>;
+ linux,phandle = <24520>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ ethernet-phy@0 {
+ linux,phandle = <2452000>;
+ interrupt-parent = <40000>;
+ interrupts = <35 1>;
+ reg = <0>;
+ device_type = "ethernet-phy";
+ };
+ ethernet-phy@1 {
+ linux,phandle = <2452001>;
+ interrupt-parent = <40000>;
+ interrupts = <35 1>;
+ reg = <1>;
+ device_type = "ethernet-phy";
+ };
+ ethernet-phy@2 {
+ linux,phandle = <2452002>;
+ interrupt-parent = <40000>;
+ interrupts = <37 1>;
+ reg = <2>;
+ device_type = "ethernet-phy";
+ };
+ ethernet-phy@3 {
+ linux,phandle = <2452003>;
+ interrupt-parent = <40000>;
+ interrupts = <37 1>;
+ reg = <3>;
+ device_type = "ethernet-phy";
+ };
+ };
+
+ ethernet@24000 {
+ device_type = "network";
+ model = "TSEC";
+ compatible = "gianfar";
+ reg = <24000 1000>;
+ address = [ 00 00 0C 00 00 FD ];
+ interrupts = <d 2 e 2 12 2>;
+ interrupt-parent = <40000>;
+ phy-handle = <2452000>;
+ };
+
+ ethernet@25000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ device_type = "network";
+ model = "TSEC";
+ compatible = "gianfar";
+ reg = <25000 1000>;
+ address = [ 00 00 0C 00 01 FD ];
+ interrupts = <13 2 14 2 18 2>;
+ interrupt-parent = <40000>;
+ phy-handle = <2452001>;
+ };
+
+ pci@8000 {
+ linux,phandle = <8000>;
+ #interrupt-cells = <1>;
+ #size-cells = <2>;
+ #address-cells = <3>;
+ compatible = "85xx";
+ device_type = "pci";
+ reg = <8000 400>;
+ clock-frequency = <3f940aa>;
+ interrupt-map-mask = <f800 0 0 7>;
+ interrupt-map = <
+
+ /* IDSEL 0x2 */
+ 1000 0 0 1 40000 31 1
+ 1000 0 0 2 40000 32 1
+ 1000 0 0 3 40000 33 1
+ 1000 0 0 4 40000 34 1
+
+ /* IDSEL 0x3 */
+ 1800 0 0 1 40000 34 1
+ 1800 0 0 2 40000 31 1
+ 1800 0 0 3 40000 32 1
+ 1800 0 0 4 40000 33 1
+
+ /* IDSEL 0x4 */
+ 2000 0 0 1 40000 33 1
+ 2000 0 0 2 40000 34 1
+ 2000 0 0 3 40000 31 1
+ 2000 0 0 4 40000 32 1
+
+ /* IDSEL 0x5 */
+ 2800 0 0 1 40000 32 1
+ 2800 0 0 2 40000 33 1
+ 2800 0 0 3 40000 34 1
+ 2800 0 0 4 40000 31 1
+
+ /* IDSEL 12 */
+ 6000 0 0 1 40000 31 1
+ 6000 0 0 2 40000 32 1
+ 6000 0 0 3 40000 33 1
+ 6000 0 0 4 40000 34 1
+
+ /* IDSEL 13 */
+ 6800 0 0 1 40000 34 1
+ 6800 0 0 2 40000 31 1
+ 6800 0 0 3 40000 32 1
+ 6800 0 0 4 40000 33 1
+
+ /* IDSEL 14*/
+ 7000 0 0 1 40000 33 1
+ 7000 0 0 2 40000 34 1
+ 7000 0 0 3 40000 31 1
+ 7000 0 0 4 40000 32 1
+
+ /* IDSEL 15 */
+ 7800 0 0 1 40000 32 1
+ 7800 0 0 2 40000 33 1
+ 7800 0 0 3 40000 34 1
+ 7800 0 0 4 40000 31 1
+
+ /* IDSEL 18 */
+ 9000 0 0 1 40000 31 1
+ 9000 0 0 2 40000 32 1
+ 9000 0 0 3 40000 33 1
+ 9000 0 0 4 40000 34 1
+
+ /* IDSEL 19 */
+ 9800 0 0 1 40000 34 1
+ 9800 0 0 2 40000 31 1
+ 9800 0 0 3 40000 32 1
+ 9800 0 0 4 40000 33 1
+
+ /* IDSEL 20 */
+ a000 0 0 1 40000 33 1
+ a000 0 0 2 40000 34 1
+ a000 0 0 3 40000 31 1
+ a000 0 0 4 40000 32 1
+
+ /* IDSEL 21 */
+ a800 0 0 1 40000 32 1
+ a800 0 0 2 40000 33 1
+ a800 0 0 3 40000 34 1
+ a800 0 0 4 40000 31 1>;
+
+ interrupt-parent = <40000>;
+ interrupts = <42 0>;
+ bus-range = <0 0>;
+ ranges = <02000000 0 80000000 80000000 0 20000000
+ 01000000 0 00000000 e2000000 0 01000000>;
+ };
+
+ pic@40000 {
+ linux,phandle = <40000>;
+ interrupt-controller;
+ #address-cells = <0>;
+ #interrupt-cells = <2>;
+ reg = <40000 20100>;
+ built-in;
+ device_type = "open-pic";
+ };
+
+ cpm@e0000000 {
+ linux,phandle = <e0000000>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ #interrupt-cells = <2>;
+ device_type = "cpm";
+ model = "CPM2";
+ ranges = <0 0 c0000>;
+ reg = <80000 40000>;
+ command-proc = <919c0>;
+ brg-frequency = <9d5b340>;
+
+ pic@90c00 {
+ linux,phandle = <90c00>;
+ interrupt-controller;
+ #address-cells = <0>;
+ #interrupt-cells = <2>;
+ interrupts = <1e 0>;
+ interrupt-parent = <40000>;
+ reg = <90c00 80>;
+ built-in;
+ device_type = "cpm-pic";
+ };
+
+ scc@91a00 {
+ device_type = "serial";
+ compatible = "cpm_uart";
+ model = "SCC";
+ device-id = <1>;
+ reg = <91a00 20 88000 100>;
+ clock-setup = <00ffffff 0>;
+ rx-clock = <1>;
+ tx-clock = <1>;
+ current-speed = <1c200>;
+ interrupts = <64 1>;
+ interrupt-parent = <90c00>;
+ };
+
+ scc@91a20 {
+ device_type = "serial";
+ compatible = "cpm_uart";
+ model = "SCC";
+ device-id = <2>;
+ reg = <91a20 20 88100 100>;
+ clock-setup = <ff00ffff 90000>;
+ rx-clock = <2>;
+ tx-clock = <2>;
+ current-speed = <1c200>;
+ interrupts = <65 1>;
+ interrupt-parent = <90c00>;
+ };
+
+ fcc@91320 {
+ device_type = "network";
+ compatible = "fs_enet";
+ model = "FCC";
+ device-id = <2>;
+ reg = <91320 20 88500 100 913a0 30>;
+ mac-address = [ 00 00 0C 00 02 FD ];
+ clock-setup = <ff00ffff 250000>;
+ rx-clock = <15>;
+ tx-clock = <16>;
+ interrupts = <5d 1>;
+ interrupt-parent = <90c00>;
+ phy-handle = <2452002>;
+ };
+
+ fcc@91340 {
+ device_type = "network";
+ compatible = "fs_enet";
+ model = "FCC";
+ device-id = <3>;
+ reg = <91340 20 88600 100 913d0 30>;
+ mac-address = [ 00 00 0C 00 03 FD ];
+ clock-setup = <ffff00ff 3700>;
+ rx-clock = <17>;
+ tx-clock = <18>;
+ interrupts = <5e 1>;
+ interrupt-parent = <90c00>;
+ phy-handle = <2452003>;
+ };
+ };
+ };
+};
diff --git a/arch/powerpc/boot/wrapper b/arch/powerpc/boot/wrapper
new file mode 100755
index 000000000000..eab7318729e9
--- /dev/null
+++ b/arch/powerpc/boot/wrapper
@@ -0,0 +1,204 @@
+#!/bin/sh
+
+# Copyright (C) 2006 Paul Mackerras, IBM Corporation <paulus@samba.org>
+# This program may be used under the terms of version 2 of the GNU
+# General Public License.
+
+# This script takes a kernel binary and optionally an initrd image
+# and/or a device-tree blob, and creates a bootable zImage for a
+# given platform.
+
+# Options:
+# -o zImage specify output file
+# -p platform specify platform (links in $platform.o)
+# -i initrd specify initrd file
+# -d devtree specify device-tree blob
+# -s tree.dts specify device-tree source file (needs dtc installed)
+# -c cache $kernel.strip.gz (use if present & newer, else make)
+# -C prefix specify command prefix for cross-building tools
+# (strip, objcopy, ld)
+# -D dir specify directory containing data files used by script
+# (default ./arch/powerpc/boot)
+# -W dir specify working directory for temporary files (default .)
+
+# defaults
+kernel=
+ofile=zImage
+platform=of
+initrd=
+dtb=
+dts=
+cacheit=
+
+# cross-compilation prefix
+CROSS=
+
+# directory for object and other files used by this script
+object=arch/powerpc/boot
+
+# directory for working files
+tmpdir=.
+
+usage() {
+ echo 'Usage: wrapper [-o output] [-p platform] [-i initrd]' >&2
+ echo ' [-d devtree] [-s tree.dts] [-c] [-C cross-prefix]' >&2
+ echo ' [-D datadir] [-W workingdir] [vmlinux]' >&2
+ exit 1
+}
+
+while [ "$#" -gt 0 ]; do
+ case "$1" in
+ -o)
+ shift
+ [ "$#" -gt 0 ] || usage
+ ofile="$1"
+ ;;
+ -p)
+ shift
+ [ "$#" -gt 0 ] || usage
+ platform="$1"
+ ;;
+ -i)
+ shift
+ [ "$#" -gt 0 ] || usage
+ initrd="$1"
+ ;;
+ -d)
+ shift
+ [ "$#" -gt 0 ] || usage
+ dtb="$1"
+ ;;
+ -s)
+ shift
+ [ "$#" -gt 0 ] || usage
+ dts="$1"
+ ;;
+ -c)
+ cacheit=y
+ ;;
+ -C)
+ shift
+ [ "$#" -gt 0 ] || usage
+ CROSS="$1"
+ ;;
+ -D)
+ shift
+ [ "$#" -gt 0 ] || usage
+ object="$1"
+ ;;
+ -W)
+ shift
+ [ "$#" -gt 0 ] || usage
+ tmpdir="$1"
+ ;;
+ -?)
+ usage
+ ;;
+ *)
+ [ -z "$kernel" ] || usage
+ kernel="$1"
+ ;;
+ esac
+ shift
+done
+
+if [ -n "$dts" ]; then
+ if [ -z "$dtb" ]; then
+ dtb="$platform.dtb"
+ fi
+ dtc -O dtb -o "$dtb" -b 0 -V 16 "$dts" || exit 1
+fi
+
+if [ -z "$kernel" ]; then
+ kernel=vmlinux
+fi
+
+platformo=$object/"$platform".o
+lds=$object/zImage.lds
+ext=strip
+objflags=-S
+tmp=$tmpdir/zImage.$$.o
+ksection=.kernel:vmlinux.strip
+isection=.kernel:initrd
+
+case "$platform" in
+pmac|pseries|chrp)
+ platformo=$object/of.o
+ ;;
+pmaccoff)
+ platformo=$object/of.o
+ lds=$object/zImage.coff.lds
+ ;;
+miboot|uboot)
+ # miboot and U-boot want just the bare bits, not an ELF binary
+ ext=bin
+ objflags="-O binary"
+ tmp="$ofile"
+ ksection=image
+ isection=initrd
+ ;;
+esac
+
+vmz="$tmpdir/`basename \"$kernel\"`.$ext"
+if [ -z "$cacheit" -o ! -f "$vmz.gz" -o "$vmz.gz" -ot "$kernel" ]; then
+ ${CROSS}objcopy $objflags "$kernel" "$vmz.$$"
+ gzip -f -9 "$vmz.$$"
+ if [ -n "$cacheit" ]; then
+ mv -f "$vmz.$$.gz" "$vmz.gz"
+ else
+ vmz="$vmz.$$"
+ fi
+fi
+
+case "$platform" in
+uboot)
+ rm -f "$ofile"
+ version=`${CROSS}strings "$kernel" | grep '^Linux version [-0-9.]' | \
+ cut -d' ' -f3`
+ if [ -n "$version" ]; then
+ version="-n Linux-$version"
+ fi
+ mkimage -A ppc -O linux -T kernel -C gzip -a 00000000 -e 00000000 \
+ $version -d "$vmz.gz" "$ofile"
+ if [ -z "$cacheit" ]; then
+ rm -f $vmz.gz
+ fi
+ exit 0
+ ;;
+esac
+
+addsec() {
+ ${CROSS}objcopy $4 $1 \
+ --add-section=$3="$2" \
+ --set-section-flags=$3=contents,alloc,load,readonly,data
+}
+
+addsec $tmp "$vmz.gz" $ksection $object/empty.o
+if [ -z "$cacheit" ]; then
+ rm -f "$vmz.gz"
+fi
+
+if [ -n "$initrd" ]; then
+ addsec $tmp "$initrd" initrd
+fi
+
+if [ -n "$dtb" ]; then
+ addsec $tmp "$dtb" dtb
+fi
+
+if [ "$platform" != "miboot" ]; then
+ ${CROSS}ld -m elf32ppc -T $lds -o "$ofile" \
+ $object/crt0.o $platformo $tmp $object/wrapper.a
+ rm $tmp
+fi
+
+# post-processing needed for some platforms
+case "$platform" in
+pseries|chrp)
+ $object/addnote "$ofile"
+ ;;
+pmaccoff)
+ ${CROSS}objcopy -O aixcoff-rs6000 --set-start 0x500000 "$ofile"
+ $object/hack-coff "$ofile"
+ ;;
+esac
diff --git a/arch/powerpc/boot/zImage.coff.lds b/arch/powerpc/boot/zImage.coff.lds.S
index 6016251a1a2c..6016251a1a2c 100644
--- a/arch/powerpc/boot/zImage.coff.lds
+++ b/arch/powerpc/boot/zImage.coff.lds.S
diff --git a/arch/powerpc/boot/zImage.lds b/arch/powerpc/boot/zImage.lds.S
index 4b6bb3ffe3dc..4b6bb3ffe3dc 100644
--- a/arch/powerpc/boot/zImage.lds
+++ b/arch/powerpc/boot/zImage.lds.S
diff --git a/arch/powerpc/configs/chrp32_defconfig b/arch/powerpc/configs/chrp32_defconfig
index bbf2b5f8a8cb..fee72f8a2fb7 100644
--- a/arch/powerpc/configs/chrp32_defconfig
+++ b/arch/powerpc/configs/chrp32_defconfig
@@ -492,7 +492,7 @@ CONFIG_SCSI_SPI_ATTRS=y
# CONFIG_MEGARAID_NEWGEN is not set
# CONFIG_MEGARAID_LEGACY is not set
# CONFIG_MEGARAID_SAS is not set
-# CONFIG_SCSI_SATA is not set
+# CONFIG_ATA is not set
# CONFIG_SCSI_HPTIOP is not set
# CONFIG_SCSI_BUSLOGIC is not set
# CONFIG_SCSI_DMX3191D is not set
diff --git a/arch/powerpc/configs/g5_defconfig b/arch/powerpc/configs/g5_defconfig
index 4b9c2ed925f5..92d0a9dd0b8f 100644
--- a/arch/powerpc/configs/g5_defconfig
+++ b/arch/powerpc/configs/g5_defconfig
@@ -490,23 +490,23 @@ CONFIG_SCSI_SPI_ATTRS=y
# CONFIG_MEGARAID_NEWGEN is not set
# CONFIG_MEGARAID_LEGACY is not set
# CONFIG_MEGARAID_SAS is not set
-CONFIG_SCSI_SATA=y
-# CONFIG_SCSI_SATA_AHCI is not set
-CONFIG_SCSI_SATA_SVW=y
+CONFIG_ATA=y
+# CONFIG_SATA_AHCI is not set
+CONFIG_SATA_SVW=y
# CONFIG_SCSI_ATA_PIIX is not set
-# CONFIG_SCSI_SATA_MV is not set
-# CONFIG_SCSI_SATA_NV is not set
+# CONFIG_SATA_MV is not set
+# CONFIG_SATA_NV is not set
# CONFIG_SCSI_PDC_ADMA is not set
# CONFIG_SCSI_HPTIOP is not set
-# CONFIG_SCSI_SATA_QSTOR is not set
-# CONFIG_SCSI_SATA_PROMISE is not set
-# CONFIG_SCSI_SATA_SX4 is not set
-# CONFIG_SCSI_SATA_SIL is not set
-# CONFIG_SCSI_SATA_SIL24 is not set
-# CONFIG_SCSI_SATA_SIS is not set
-# CONFIG_SCSI_SATA_ULI is not set
-# CONFIG_SCSI_SATA_VIA is not set
-# CONFIG_SCSI_SATA_VITESSE is not set
+# CONFIG_SATA_QSTOR is not set
+# CONFIG_SATA_PROMISE is not set
+# CONFIG_SATA_SX4 is not set
+# CONFIG_SATA_SIL is not set
+# CONFIG_SATA_SIL24 is not set
+# CONFIG_SATA_SIS is not set
+# CONFIG_SATA_ULI is not set
+# CONFIG_SATA_VIA is not set
+# CONFIG_SATA_VITESSE is not set
# CONFIG_SCSI_BUSLOGIC is not set
# CONFIG_SCSI_DMX3191D is not set
# CONFIG_SCSI_EATA is not set
diff --git a/arch/powerpc/configs/iseries_defconfig b/arch/powerpc/configs/iseries_defconfig
index eb0885ea0731..d58f82f836f8 100644
--- a/arch/powerpc/configs/iseries_defconfig
+++ b/arch/powerpc/configs/iseries_defconfig
@@ -475,7 +475,7 @@ CONFIG_SCSI_FC_ATTRS=y
# CONFIG_MEGARAID_NEWGEN is not set
# CONFIG_MEGARAID_LEGACY is not set
# CONFIG_MEGARAID_SAS is not set
-# CONFIG_SCSI_SATA is not set
+# CONFIG_ATA is not set
# CONFIG_SCSI_HPTIOP is not set
# CONFIG_SCSI_BUSLOGIC is not set
# CONFIG_SCSI_DMX3191D is not set
diff --git a/arch/powerpc/configs/mpc7448_hpc2_defconfig b/arch/powerpc/configs/mpc7448_hpc2_defconfig
index 719fba4eb421..d1811e754518 100644
--- a/arch/powerpc/configs/mpc7448_hpc2_defconfig
+++ b/arch/powerpc/configs/mpc7448_hpc2_defconfig
@@ -413,23 +413,23 @@ CONFIG_BLK_DEV_SD=y
# CONFIG_MEGARAID_NEWGEN is not set
# CONFIG_MEGARAID_LEGACY is not set
# CONFIG_MEGARAID_SAS is not set
-CONFIG_SCSI_SATA=y
-# CONFIG_SCSI_SATA_AHCI is not set
-# CONFIG_SCSI_SATA_SVW is not set
+CONFIG_ATA=y
+# CONFIG_SATA_AHCI is not set
+# CONFIG_SATA_SVW is not set
# CONFIG_SCSI_ATA_PIIX is not set
-CONFIG_SCSI_SATA_MV=y
-# CONFIG_SCSI_SATA_NV is not set
+CONFIG_SATA_MV=y
+# CONFIG_SATA_NV is not set
# CONFIG_SCSI_PDC_ADMA is not set
# CONFIG_SCSI_HPTIOP is not set
-# CONFIG_SCSI_SATA_QSTOR is not set
-# CONFIG_SCSI_SATA_PROMISE is not set
-# CONFIG_SCSI_SATA_SX4 is not set
-# CONFIG_SCSI_SATA_SIL is not set
-# CONFIG_SCSI_SATA_SIL24 is not set
-# CONFIG_SCSI_SATA_SIS is not set
-# CONFIG_SCSI_SATA_ULI is not set
-# CONFIG_SCSI_SATA_VIA is not set
-# CONFIG_SCSI_SATA_VITESSE is not set
+# CONFIG_SATA_QSTOR is not set
+# CONFIG_SATA_PROMISE is not set
+# CONFIG_SATA_SX4 is not set
+# CONFIG_SATA_SIL is not set
+# CONFIG_SATA_SIL24 is not set
+# CONFIG_SATA_SIS is not set
+# CONFIG_SATA_ULI is not set
+# CONFIG_SATA_VIA is not set
+# CONFIG_SATA_VITESSE is not set
# CONFIG_SCSI_BUSLOGIC is not set
# CONFIG_SCSI_DMX3191D is not set
# CONFIG_SCSI_EATA is not set
diff --git a/arch/powerpc/configs/mpc834x_itx_defconfig b/arch/powerpc/configs/mpc834x_itx_defconfig
index 8da6a47f0339..cd3535e1a095 100644
--- a/arch/powerpc/configs/mpc834x_itx_defconfig
+++ b/arch/powerpc/configs/mpc834x_itx_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.18-rc6
-# Sun Sep 10 10:28:05 2006
+# Linux kernel version: 2.6.18
+# Mon Sep 25 19:41:14 2006
#
# CONFIG_PPC64 is not set
CONFIG_PPC32=y
@@ -21,6 +21,7 @@ CONFIG_ARCH_MAY_HAVE_PC_FDC=y
CONFIG_PPC_OF=y
CONFIG_PPC_UDBG_16550=y
# CONFIG_GENERIC_TBSYNC is not set
+CONFIG_AUDIT_ARCH=y
CONFIG_DEFAULT_UIMAGE=y
#
@@ -61,25 +62,25 @@ CONFIG_SYSVIPC=y
# CONFIG_POSIX_MQUEUE is not set
# CONFIG_BSD_PROCESS_ACCT is not set
# CONFIG_TASKSTATS is not set
-CONFIG_SYSCTL=y
# CONFIG_AUDIT is not set
# CONFIG_IKCONFIG is not set
# CONFIG_RELAY is not set
CONFIG_INITRAMFS_SOURCE=""
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
CONFIG_EMBEDDED=y
+CONFIG_SYSCTL=y
# CONFIG_KALLSYMS is not set
CONFIG_HOTPLUG=y
CONFIG_PRINTK=y
CONFIG_BUG=y
CONFIG_ELF_CORE=y
CONFIG_BASE_FULL=y
-CONFIG_RT_MUTEXES=y
CONFIG_FUTEX=y
# CONFIG_EPOLL is not set
CONFIG_SHMEM=y
CONFIG_SLAB=y
CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_RT_MUTEXES=y
# CONFIG_TINY_SHMEM is not set
CONFIG_BASE_SMALL=0
# CONFIG_SLOB is not set
@@ -259,7 +260,6 @@ CONFIG_TCP_CONG_BIC=y
# CONFIG_ATALK is not set
# CONFIG_X25 is not set
# CONFIG_LAPB is not set
-# CONFIG_NET_DIVERT is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
@@ -313,6 +313,7 @@ CONFIG_MTD_CHAR=y
# CONFIG_NFTL is not set
# CONFIG_INFTL is not set
# CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
#
# RAM/ROM/Flash chip drivers
@@ -464,23 +465,23 @@ CONFIG_SCSI_SPI_ATTRS=y
# CONFIG_MEGARAID_NEWGEN is not set
# CONFIG_MEGARAID_LEGACY is not set
# CONFIG_MEGARAID_SAS is not set
-CONFIG_SCSI_SATA=y
-# CONFIG_SCSI_SATA_AHCI is not set
-# CONFIG_SCSI_SATA_SVW is not set
+CONFIG_ATA=y
+# CONFIG_SATA_AHCI is not set
+# CONFIG_SATA_SVW is not set
# CONFIG_SCSI_ATA_PIIX is not set
-# CONFIG_SCSI_SATA_MV is not set
-# CONFIG_SCSI_SATA_NV is not set
+# CONFIG_SATA_MV is not set
+# CONFIG_SATA_NV is not set
# CONFIG_SCSI_PDC_ADMA is not set
# CONFIG_SCSI_HPTIOP is not set
-# CONFIG_SCSI_SATA_QSTOR is not set
-# CONFIG_SCSI_SATA_PROMISE is not set
-# CONFIG_SCSI_SATA_SX4 is not set
-CONFIG_SCSI_SATA_SIL=y
-# CONFIG_SCSI_SATA_SIL24 is not set
-# CONFIG_SCSI_SATA_SIS is not set
-# CONFIG_SCSI_SATA_ULI is not set
-# CONFIG_SCSI_SATA_VIA is not set
-# CONFIG_SCSI_SATA_VITESSE is not set
+# CONFIG_SATA_QSTOR is not set
+# CONFIG_SATA_PROMISE is not set
+# CONFIG_SATA_SX4 is not set
+CONFIG_SATA_SIL=y
+# CONFIG_SATA_SIL24 is not set
+# CONFIG_SATA_SIS is not set
+# CONFIG_SATA_ULI is not set
+# CONFIG_SATA_VIA is not set
+# CONFIG_SATA_VITESSE is not set
# CONFIG_SCSI_BUSLOGIC is not set
# CONFIG_SCSI_DMX3191D is not set
# CONFIG_SCSI_EATA is not set
@@ -1277,11 +1278,11 @@ CONFIG_PLIST=y
#
# Kernel hacking
#
-CONFIG_PRINTK_TIME=y
+# CONFIG_PRINTK_TIME is not set
# CONFIG_MAGIC_SYSRQ is not set
# CONFIG_UNUSED_SYMBOLS is not set
CONFIG_DEBUG_KERNEL=y
-CONFIG_LOG_BUF_SHIFT=17
+CONFIG_LOG_BUF_SHIFT=14
CONFIG_DETECT_SOFTLOCKUP=y
# CONFIG_SCHEDSTATS is not set
# CONFIG_DEBUG_SLAB is not set
@@ -1293,15 +1294,15 @@ CONFIG_DETECT_SOFTLOCKUP=y
# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
# CONFIG_DEBUG_KOBJECT is not set
-CONFIG_DEBUG_INFO=y
+# CONFIG_DEBUG_INFO is not set
# CONFIG_DEBUG_FS is not set
# CONFIG_DEBUG_VM is not set
CONFIG_FORCED_INLINING=y
# CONFIG_RCU_TORTURE_TEST is not set
# CONFIG_DEBUGGER is not set
# CONFIG_BDI_SWITCH is not set
-CONFIG_BOOTX_TEXT=y
-CONFIG_SERIAL_TEXT_DEBUG=y
+# CONFIG_BOOTX_TEXT is not set
+# CONFIG_SERIAL_TEXT_DEBUG is not set
# CONFIG_PPC_EARLY_DEBUG is not set
#
@@ -1314,6 +1315,8 @@ CONFIG_SERIAL_TEXT_DEBUG=y
# Cryptographic options
#
CONFIG_CRYPTO=y
+CONFIG_CRYPTO_ALGAPI=y
+# CONFIG_CRYPTO_MANAGER is not set
# CONFIG_CRYPTO_HMAC is not set
# CONFIG_CRYPTO_NULL is not set
# CONFIG_CRYPTO_MD4 is not set
@@ -1323,6 +1326,8 @@ CONFIG_CRYPTO_MD5=y
# CONFIG_CRYPTO_SHA512 is not set
# CONFIG_CRYPTO_WP512 is not set
# CONFIG_CRYPTO_TGR192 is not set
+# CONFIG_CRYPTO_ECB is not set
+# CONFIG_CRYPTO_CBC is not set
CONFIG_CRYPTO_DES=y
# CONFIG_CRYPTO_BLOWFISH is not set
# CONFIG_CRYPTO_TWOFISH is not set
diff --git a/arch/powerpc/configs/mpc8560_ads_defconfig b/arch/powerpc/configs/mpc8560_ads_defconfig
new file mode 100644
index 000000000000..ddc2a7b07ba0
--- /dev/null
+++ b/arch/powerpc/configs/mpc8560_ads_defconfig
@@ -0,0 +1,854 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.18-rc4
+# Fri Aug 11 16:45:05 2006
+#
+# CONFIG_PPC64 is not set
+CONFIG_PPC32=y
+CONFIG_PPC_MERGE=y
+CONFIG_MMU=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_IRQ_PER_CPU=y
+CONFIG_RWSEM_XCHGADD_ALGORITHM=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+CONFIG_PPC=y
+CONFIG_EARLY_PRINTK=y
+CONFIG_GENERIC_NVRAM=y
+CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
+CONFIG_ARCH_MAY_HAVE_PC_FDC=y
+CONFIG_PPC_OF=y
+# CONFIG_PPC_UDBG_16550 is not set
+# CONFIG_GENERIC_TBSYNC is not set
+CONFIG_DEFAULT_UIMAGE=y
+
+#
+# Processor support
+#
+# CONFIG_CLASSIC32 is not set
+# CONFIG_PPC_52xx is not set
+# CONFIG_PPC_82xx is not set
+# CONFIG_PPC_83xx is not set
+CONFIG_PPC_85xx=y
+# CONFIG_PPC_86xx is not set
+# CONFIG_40x is not set
+# CONFIG_44x is not set
+# CONFIG_8xx is not set
+# CONFIG_E200 is not set
+CONFIG_85xx=y
+CONFIG_E500=y
+CONFIG_BOOKE=y
+CONFIG_FSL_BOOKE=y
+# CONFIG_PHYS_64BIT is not set
+CONFIG_SPE=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+# CONFIG_POSIX_MQUEUE is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_TASKSTATS is not set
+CONFIG_SYSCTL=y
+# CONFIG_AUDIT is not set
+# CONFIG_IKCONFIG is not set
+# CONFIG_RELAY is not set
+CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_EMBEDDED=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_ALL is not set
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
+CONFIG_RT_MUTEXES=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+CONFIG_SHMEM=y
+CONFIG_SLAB=y
+CONFIG_VM_EVENT_COUNTERS=y
+# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+# CONFIG_SLOB is not set
+
+#
+# Loadable module support
+#
+# CONFIG_MODULES is not set
+
+#
+# Block layer
+#
+# CONFIG_LBD is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_LSF is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+CONFIG_DEFAULT_AS=y
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="anticipatory"
+CONFIG_MPIC=y
+CONFIG_CPM2=y
+# CONFIG_WANT_EARLY_SERIAL is not set
+
+#
+# Platform support
+#
+# CONFIG_MPC8540_ADS is not set
+CONFIG_MPC8560_ADS=y
+# CONFIG_MPC85xx_CDS is not set
+CONFIG_MPC8560=y
+CONFIG_PPC_INDIRECT_PCI_BE=y
+
+#
+# Kernel options
+#
+# CONFIG_HIGHMEM is not set
+# CONFIG_HZ_100 is not set
+CONFIG_HZ_250=y
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=250
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
+# CONFIG_PREEMPT is not set
+CONFIG_BINFMT_ELF=y
+CONFIG_BINFMT_MISC=y
+# CONFIG_MATH_EMULATION is not set
+CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
+# CONFIG_PC_KEYBOARD is not set
+CONFIG_ARCH_FLATMEM_ENABLE=y
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+# CONFIG_SPARSEMEM_STATIC is not set
+CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_RESOURCES_64BIT is not set
+# CONFIG_PROC_DEVICETREE is not set
+# CONFIG_CMDLINE_BOOL is not set
+# CONFIG_PM is not set
+# CONFIG_SOFTWARE_SUSPEND is not set
+# CONFIG_SECCOMP is not set
+CONFIG_ISA_DMA_API=y
+
+#
+# Bus options
+#
+# CONFIG_PPC_I8259 is not set
+CONFIG_PPC_INDIRECT_PCI=y
+CONFIG_FSL_SOC=y
+CONFIG_PCI=y
+CONFIG_PCI_DOMAINS=y
+# CONFIG_PCIEPORTBUS is not set
+CONFIG_PCI_DEBUG=y
+
+#
+# PCCARD (PCMCIA/CardBus) support
+#
+# CONFIG_PCCARD is not set
+
+#
+# PCI Hotplug Support
+#
+# CONFIG_HOTPLUG_PCI is not set
+
+#
+# Advanced setup
+#
+# CONFIG_ADVANCED_OPTIONS is not set
+
+#
+# Default settings for advanced configuration options are used
+#
+CONFIG_HIGHMEM_START=0xfe000000
+CONFIG_LOWMEM_SIZE=0x30000000
+CONFIG_KERNEL_START=0xc0000000
+CONFIG_TASK_SIZE=0x80000000
+CONFIG_BOOT_LOAD=0x00800000
+
+#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+# CONFIG_NETDEBUG is not set
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+# CONFIG_XFRM_USER is not set
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_IP_MROUTE is not set
+# CONFIG_ARPD is not set
+CONFIG_SYN_COOKIES=y
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+# CONFIG_INET_TUNNEL is not set
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_BIC=y
+# CONFIG_IPV6 is not set
+# CONFIG_INET6_XFRM_TUNNEL is not set
+# CONFIG_INET6_TUNNEL is not set
+# CONFIG_NETWORK_SECMARK is not set
+# CONFIG_NETFILTER is not set
+
+#
+# DCCP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_DCCP is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP is not set
+
+#
+# TIPC Configuration (EXPERIMENTAL)
+#
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_IEEE80211 is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+# CONFIG_FW_LOADER is not set
+# CONFIG_DEBUG_DRIVER is not set
+# CONFIG_SYS_HYPERVISOR is not set
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
+# CONFIG_CONNECTOR is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+# CONFIG_MTD is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Plug and Play support
+#
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_FD is not set
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=y
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_SX8 is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=32768
+CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
+CONFIG_BLK_DEV_INITRD=y
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+
+#
+# ATA/ATAPI/MFM/RLL support
+#
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+# CONFIG_SCSI is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+
+#
+# Fusion MPT device support
+#
+# CONFIG_FUSION is not set
+
+#
+# IEEE 1394 (FireWire) support
+#
+# CONFIG_IEEE1394 is not set
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+
+#
+# Macintosh device drivers
+#
+# CONFIG_WINDFARM is not set
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+
+#
+# PHY device support
+#
+CONFIG_PHYLIB=y
+
+#
+# MII PHY device drivers
+#
+CONFIG_MARVELL_PHY=y
+CONFIG_DAVICOM_PHY=y
+# CONFIG_QSEMI_PHY is not set
+# CONFIG_LXT_PHY is not set
+# CONFIG_CICADA_PHY is not set
+# CONFIG_VITESSE_PHY is not set
+# CONFIG_SMSC_PHY is not set
+# CONFIG_FIXED_PHY is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+# CONFIG_HAPPYMEAL is not set
+# CONFIG_SUNGEM is not set
+# CONFIG_CASSINI is not set
+# CONFIG_NET_VENDOR_3COM is not set
+
+#
+# Tulip family network device support
+#
+# CONFIG_NET_TULIP is not set
+# CONFIG_HP100 is not set
+# CONFIG_NET_PCI is not set
+CONFIG_FS_ENET=y
+# CONFIG_FS_ENET_HAS_SCC is not set
+CONFIG_FS_ENET_HAS_FCC=y
+
+#
+# Ethernet (1000 Mbit)
+#
+# CONFIG_ACENIC is not set
+# CONFIG_DL2K is not set
+CONFIG_E1000=y
+CONFIG_E1000_NAPI=y
+# CONFIG_E1000_DISABLE_PACKET_SPLIT is not set
+# CONFIG_NS83820 is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
+# CONFIG_R8169 is not set
+# CONFIG_SIS190 is not set
+# CONFIG_SKGE is not set
+# CONFIG_SKY2 is not set
+# CONFIG_SK98LIN is not set
+# CONFIG_TIGON3 is not set
+# CONFIG_BNX2 is not set
+CONFIG_GIANFAR=y
+CONFIG_GFAR_NAPI=y
+
+#
+# Ethernet (10000 Mbit)
+#
+# CONFIG_CHELSIO_T1 is not set
+# CONFIG_IXGB is not set
+# CONFIG_S2IO is not set
+# CONFIG_MYRI10GE is not set
+
+#
+# Token Ring devices
+#
+# CONFIG_TR is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_SHAPER is not set
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Telephony Support
+#
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+
+#
+# Userland interfaces
+#
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_TSDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+# CONFIG_VT is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_SERIAL_CPM=y
+CONFIG_SERIAL_CPM_CONSOLE=y
+CONFIG_SERIAL_CPM_SCC1=y
+CONFIG_SERIAL_CPM_SCC2=y
+# CONFIG_SERIAL_CPM_SCC3 is not set
+# CONFIG_SERIAL_CPM_SCC4 is not set
+# CONFIG_SERIAL_CPM_SMC1 is not set
+# CONFIG_SERIAL_CPM_SMC2 is not set
+# CONFIG_SERIAL_JSM is not set
+CONFIG_UNIX98_PTYS=y
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+# CONFIG_BRIQ_PANEL is not set
+
+#
+# IPMI
+#
+# CONFIG_IPMI_HANDLER is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+CONFIG_HW_RANDOM=y
+# CONFIG_NVRAM is not set
+CONFIG_GEN_RTC=y
+# CONFIG_GEN_RTC_X is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_AGP is not set
+# CONFIG_DRM is not set
+# CONFIG_RAW_DRIVER is not set
+
+#
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
+# CONFIG_TELCLOCK is not set
+
+#
+# I2C support
+#
+# CONFIG_I2C is not set
+
+#
+# SPI support
+#
+# CONFIG_SPI is not set
+# CONFIG_SPI_MASTER is not set
+
+#
+# Dallas's 1-wire bus
+#
+
+#
+# Hardware Monitoring support
+#
+CONFIG_HWMON=y
+# CONFIG_HWMON_VID is not set
+# CONFIG_SENSORS_ABITUGURU is not set
+# CONFIG_SENSORS_F71805F is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
+
+#
+# Misc devices
+#
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+CONFIG_VIDEO_V4L2=y
+
+#
+# Digital Video Broadcasting Devices
+#
+# CONFIG_DVB is not set
+
+#
+# Graphics support
+#
+CONFIG_FIRMWARE_EDID=y
+# CONFIG_FB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# USB support
+#
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+CONFIG_USB_ARCH_HAS_EHCI=y
+# CONFIG_USB is not set
+
+#
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
+#
+
+#
+# USB Gadget Support
+#
+# CONFIG_USB_GADGET is not set
+
+#
+# MMC/SD Card support
+#
+# CONFIG_MMC is not set
+
+#
+# LED devices
+#
+# CONFIG_NEW_LEDS is not set
+
+#
+# LED drivers
+#
+
+#
+# LED Triggers
+#
+
+#
+# InfiniBand support
+#
+# CONFIG_INFINIBAND is not set
+
+#
+# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
+#
+
+#
+# Real Time Clock
+#
+# CONFIG_RTC_CLASS is not set
+
+#
+# DMA Engine support
+#
+# CONFIG_DMA_ENGINE is not set
+
+#
+# DMA Clients
+#
+
+#
+# DMA Devices
+#
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
+CONFIG_EXT3_FS=y
+CONFIG_EXT3_FS_XATTR=y
+# CONFIG_EXT3_FS_POSIX_ACL is not set
+# CONFIG_EXT3_FS_SECURITY is not set
+CONFIG_JBD=y
+# CONFIG_JBD_DEBUG is not set
+CONFIG_FS_MBCACHE=y
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_OCFS2_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+# CONFIG_QUOTA is not set
+CONFIG_DNOTIFY=y
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+# CONFIG_MSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_KCORE=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_RAMFS=y
+# CONFIG_CONFIGFS_FS is not set
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+
+#
+# Network File Systems
+#
+CONFIG_NFS_FS=y
+# CONFIG_NFS_V3 is not set
+# CONFIG_NFS_V4 is not set
+# CONFIG_NFS_DIRECTIO is not set
+# CONFIG_NFSD is not set
+CONFIG_ROOT_NFS=y
+CONFIG_LOCKD=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+# CONFIG_RPCSEC_GSS_KRB5 is not set
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+# CONFIG_9P_FS is not set
+
+#
+# Partition Types
+#
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_ACORN_PARTITION is not set
+# CONFIG_OSF_PARTITION is not set
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
+# CONFIG_MAC_PARTITION is not set
+# CONFIG_MSDOS_PARTITION is not set
+# CONFIG_LDM_PARTITION is not set
+# CONFIG_SGI_PARTITION is not set
+# CONFIG_ULTRIX_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+# CONFIG_KARMA_PARTITION is not set
+# CONFIG_EFI_PARTITION is not set
+
+#
+# Native Language Support
+#
+# CONFIG_NLS is not set
+
+#
+# Library routines
+#
+# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
+CONFIG_CRC32=y
+# CONFIG_LIBCRC32C is not set
+CONFIG_PLIST=y
+
+#
+# Instrumentation Support
+#
+# CONFIG_PROFILING is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_UNUSED_SYMBOLS is not set
+CONFIG_DEBUG_KERNEL=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_DETECT_SOFTLOCKUP=y
+# CONFIG_SCHEDSTATS is not set
+# CONFIG_DEBUG_SLAB is not set
+# CONFIG_DEBUG_RT_MUTEXES is not set
+# CONFIG_RT_MUTEX_TESTER is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+CONFIG_DEBUG_MUTEXES=y
+# CONFIG_DEBUG_RWSEMS is not set
+# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+# CONFIG_DEBUG_KOBJECT is not set
+# CONFIG_DEBUG_INFO is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_DEBUG_VM is not set
+# CONFIG_UNWIND_INFO is not set
+CONFIG_FORCED_INLINING=y
+# CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_DEBUGGER is not set
+# CONFIG_KGDB_CONSOLE is not set
+# CONFIG_BDI_SWITCH is not set
+# CONFIG_BOOTX_TEXT is not set
+# CONFIG_PPC_EARLY_DEBUG is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+
+#
+# Cryptographic options
+#
+# CONFIG_CRYPTO is not set
+
+#
+# Hardware crypto devices
+#
diff --git a/arch/powerpc/configs/pmac32_defconfig b/arch/powerpc/configs/pmac32_defconfig
index 6861dde7d77b..765c8bb90ddd 100644
--- a/arch/powerpc/configs/pmac32_defconfig
+++ b/arch/powerpc/configs/pmac32_defconfig
@@ -682,7 +682,7 @@ CONFIG_SCSI_AIC7XXX_OLD=m
# CONFIG_MEGARAID_NEWGEN is not set
# CONFIG_MEGARAID_LEGACY is not set
# CONFIG_MEGARAID_SAS is not set
-# CONFIG_SCSI_SATA is not set
+# CONFIG_ATA is not set
# CONFIG_SCSI_HPTIOP is not set
# CONFIG_SCSI_BUSLOGIC is not set
# CONFIG_SCSI_DMX3191D is not set
@@ -1826,7 +1826,7 @@ CONFIG_OPROFILE=y
# Kernel hacking
#
# CONFIG_PRINTK_TIME is not set
-# CONFIG_MAGIC_SYSRQ is not set
+CONFIG_MAGIC_SYSRQ=y
# CONFIG_UNUSED_SYMBOLS is not set
CONFIG_DEBUG_KERNEL=y
CONFIG_LOG_BUF_SHIFT=14
diff --git a/arch/powerpc/configs/ppc64_defconfig b/arch/powerpc/configs/ppc64_defconfig
index 7517d0c5303f..be11df7c11aa 100644
--- a/arch/powerpc/configs/ppc64_defconfig
+++ b/arch/powerpc/configs/ppc64_defconfig
@@ -520,23 +520,23 @@ CONFIG_SCSI_ISCSI_ATTRS=m
# CONFIG_MEGARAID_NEWGEN is not set
# CONFIG_MEGARAID_LEGACY is not set
# CONFIG_MEGARAID_SAS is not set
-CONFIG_SCSI_SATA=y
-# CONFIG_SCSI_SATA_AHCI is not set
-CONFIG_SCSI_SATA_SVW=y
+CONFIG_ATA=y
+# CONFIG_SATA_AHCI is not set
+CONFIG_SATA_SVW=y
# CONFIG_SCSI_ATA_PIIX is not set
-# CONFIG_SCSI_SATA_MV is not set
-# CONFIG_SCSI_SATA_NV is not set
+# CONFIG_SATA_MV is not set
+# CONFIG_SATA_NV is not set
# CONFIG_SCSI_PDC_ADMA is not set
# CONFIG_SCSI_HPTIOP is not set
-# CONFIG_SCSI_SATA_QSTOR is not set
-# CONFIG_SCSI_SATA_PROMISE is not set
-# CONFIG_SCSI_SATA_SX4 is not set
-# CONFIG_SCSI_SATA_SIL is not set
-# CONFIG_SCSI_SATA_SIL24 is not set
-# CONFIG_SCSI_SATA_SIS is not set
-# CONFIG_SCSI_SATA_ULI is not set
-# CONFIG_SCSI_SATA_VIA is not set
-# CONFIG_SCSI_SATA_VITESSE is not set
+# CONFIG_SATA_QSTOR is not set
+# CONFIG_SATA_PROMISE is not set
+# CONFIG_SATA_SX4 is not set
+# CONFIG_SATA_SIL is not set
+# CONFIG_SATA_SIL24 is not set
+# CONFIG_SATA_SIS is not set
+# CONFIG_SATA_ULI is not set
+# CONFIG_SATA_VIA is not set
+# CONFIG_SATA_VITESSE is not set
# CONFIG_SCSI_BUSLOGIC is not set
# CONFIG_SCSI_DMX3191D is not set
# CONFIG_SCSI_EATA is not set
diff --git a/arch/powerpc/configs/pseries_defconfig b/arch/powerpc/configs/pseries_defconfig
index a8cdf312e1b0..44175fb7adec 100644
--- a/arch/powerpc/configs/pseries_defconfig
+++ b/arch/powerpc/configs/pseries_defconfig
@@ -506,7 +506,7 @@ CONFIG_SCSI_SAS_ATTRS=m
# CONFIG_MEGARAID_NEWGEN is not set
# CONFIG_MEGARAID_LEGACY is not set
# CONFIG_MEGARAID_SAS is not set
-# CONFIG_SCSI_SATA is not set
+# CONFIG_ATA is not set
# CONFIG_SCSI_HPTIOP is not set
# CONFIG_SCSI_BUSLOGIC is not set
# CONFIG_SCSI_DMX3191D is not set
diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c
index b4432332341f..c3f58f2f9f52 100644
--- a/arch/powerpc/kernel/irq.c
+++ b/arch/powerpc/kernel/irq.c
@@ -777,7 +777,6 @@ unsigned int irq_alloc_virt(struct irq_host *host,
{
unsigned long flags;
unsigned int i, j, found = NO_IRQ;
- unsigned int limit = irq_virq_count - count;
if (count == 0 || count > (irq_virq_count - NUM_ISA_INTERRUPTS))
return NO_IRQ;
@@ -794,14 +793,16 @@ unsigned int irq_alloc_virt(struct irq_host *host,
/* Look for count consecutive numbers in the allocatable
* (non-legacy) space
*/
- for (i = NUM_ISA_INTERRUPTS; i <= limit; ) {
- for (j = i; j < (i + count); j++)
- if (irq_map[j].host != NULL) {
- i = j + 1;
- continue;
- }
- found = i;
- break;
+ for (i = NUM_ISA_INTERRUPTS, j = 0; i < irq_virq_count; i++) {
+ if (irq_map[i].host != NULL)
+ j = 0;
+ else
+ j++;
+
+ if (j == count) {
+ found = i - count + 1;
+ break;
+ }
}
if (found == NO_IRQ) {
spin_unlock_irqrestore(&irq_big_lock, flags);
diff --git a/arch/powerpc/kernel/kprobes.c b/arch/powerpc/kernel/kprobes.c
index cd65c367b8b6..7b8d12b9026c 100644
--- a/arch/powerpc/kernel/kprobes.c
+++ b/arch/powerpc/kernel/kprobes.c
@@ -259,14 +259,15 @@ void kretprobe_trampoline_holder(void)
*/
int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs)
{
- struct kretprobe_instance *ri = NULL;
- struct hlist_head *head;
- struct hlist_node *node, *tmp;
+ struct kretprobe_instance *ri = NULL;
+ struct hlist_head *head, empty_rp;
+ struct hlist_node *node, *tmp;
unsigned long flags, orig_ret_address = 0;
unsigned long trampoline_address =(unsigned long)&kretprobe_trampoline;
+ INIT_HLIST_HEAD(&empty_rp);
spin_lock_irqsave(&kretprobe_lock, flags);
- head = kretprobe_inst_table_head(current);
+ head = kretprobe_inst_table_head(current);
/*
* It is possible to have multiple instances associated with a given
@@ -277,20 +278,20 @@ int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs)
* We can handle this because:
* - instances are always inserted at the head of the list
* - when multiple return probes are registered for the same
- * function, the first instance's ret_addr will point to the
+ * function, the first instance's ret_addr will point to the
* real return address, and all the rest will point to
* kretprobe_trampoline
*/
hlist_for_each_entry_safe(ri, node, tmp, head, hlist) {
- if (ri->task != current)
+ if (ri->task != current)
/* another task is sharing our hash bucket */
- continue;
+ continue;
if (ri->rp && ri->rp->handler)
ri->rp->handler(ri, regs);
orig_ret_address = (unsigned long)ri->ret_addr;
- recycle_rp_inst(ri);
+ recycle_rp_inst(ri, &empty_rp);
if (orig_ret_address != trampoline_address)
/*
@@ -308,12 +309,16 @@ int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs)
spin_unlock_irqrestore(&kretprobe_lock, flags);
preempt_enable_no_resched();
- /*
- * By returning a non-zero value, we are telling
- * kprobe_handler() that we don't want the post_handler
- * to run (and have re-enabled preemption)
- */
- return 1;
+ hlist_for_each_entry_safe(ri, node, tmp, &empty_rp, hlist) {
+ hlist_del(&ri->hlist);
+ kfree(ri);
+ }
+ /*
+ * By returning a non-zero value, we are telling
+ * kprobe_handler() that we don't want the post_handler
+ * to run (and have re-enabled preemption)
+ */
+ return 1;
}
/*
diff --git a/arch/powerpc/kernel/misc_32.S b/arch/powerpc/kernel/misc_32.S
index 58758d883361..88fd73fdf048 100644
--- a/arch/powerpc/kernel/misc_32.S
+++ b/arch/powerpc/kernel/misc_32.S
@@ -843,7 +843,7 @@ _GLOBAL(kernel_thread)
addi r1,r1,16
blr
-_GLOBAL(execve)
+_GLOBAL(kernel_execve)
li r0,__NR_execve
sc
bnslr
diff --git a/arch/powerpc/kernel/misc_64.S b/arch/powerpc/kernel/misc_64.S
index e3ed21cd3d94..9c54eccad993 100644
--- a/arch/powerpc/kernel/misc_64.S
+++ b/arch/powerpc/kernel/misc_64.S
@@ -556,7 +556,7 @@ _GLOBAL(giveup_altivec)
#endif /* CONFIG_ALTIVEC */
-_GLOBAL(execve)
+_GLOBAL(kernel_execve)
li r0,__NR_execve
sc
bnslr
diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c
index a127a1e3c097..7b2f6452ba72 100644
--- a/arch/powerpc/kernel/process.c
+++ b/arch/powerpc/kernel/process.c
@@ -424,7 +424,7 @@ void show_regs(struct pt_regs * regs)
printk("NIP: "REG" LR: "REG" CTR: "REG"\n",
regs->nip, regs->link, regs->ctr);
printk("REGS: %p TRAP: %04lx %s (%s)\n",
- regs, regs->trap, print_tainted(), system_utsname.release);
+ regs, regs->trap, print_tainted(), init_utsname()->release);
printk("MSR: "REG" ", regs->msr);
printbits(regs->msr, msr_bits);
printk(" CR: %08lX XER: %08lX\n", regs->ccr, regs->xer);
diff --git a/arch/powerpc/kernel/ptrace.c b/arch/powerpc/kernel/ptrace.c
index dea75d73f983..975102a020d9 100644
--- a/arch/powerpc/kernel/ptrace.c
+++ b/arch/powerpc/kernel/ptrace.c
@@ -526,9 +526,7 @@ static void do_syscall_trace(void)
void do_syscall_trace_enter(struct pt_regs *regs)
{
-#ifdef CONFIG_PPC64
secure_computing(regs->gpr[0]);
-#endif
if (test_thread_flag(TIF_SYSCALL_TRACE)
&& (current->ptrace & PT_PTRACED))
@@ -548,12 +546,8 @@ void do_syscall_trace_enter(struct pt_regs *regs)
void do_syscall_trace_leave(struct pt_regs *regs)
{
-#ifdef CONFIG_PPC32
- secure_computing(regs->gpr[0]);
-#endif
-
if (unlikely(current->audit_context))
- audit_syscall_exit((regs->ccr&0x1000)?AUDITSC_FAILURE:AUDITSC_SUCCESS,
+ audit_syscall_exit((regs->ccr&0x10000000)?AUDITSC_FAILURE:AUDITSC_SUCCESS,
regs->result);
if ((test_thread_flag(TIF_SYSCALL_TRACE)
@@ -561,8 +555,3 @@ void do_syscall_trace_leave(struct pt_regs *regs)
&& (current->ptrace & PT_PTRACED))
do_syscall_trace();
}
-
-#ifdef CONFIG_PPC32
-EXPORT_SYMBOL(do_syscall_trace_enter);
-EXPORT_SYMBOL(do_syscall_trace_leave);
-#endif
diff --git a/arch/powerpc/kernel/setup_32.c b/arch/powerpc/kernel/setup_32.c
index e0df2ba1ab9f..79a17795d17b 100644
--- a/arch/powerpc/kernel/setup_32.c
+++ b/arch/powerpc/kernel/setup_32.c
@@ -67,10 +67,6 @@ int have_of = 1;
dev_t boot_dev;
#endif /* CONFIG_PPC_MULTIPLATFORM */
-#ifdef CONFIG_MAGIC_SYSRQ
-unsigned long SYSRQ_KEY = 0x54;
-#endif /* CONFIG_MAGIC_SYSRQ */
-
#ifdef CONFIG_VGA_CONSOLE
unsigned long vgacon_remap_base;
#endif
diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c
index 00d6b8addd78..cda2dbe70a76 100644
--- a/arch/powerpc/kernel/setup_64.c
+++ b/arch/powerpc/kernel/setup_64.c
@@ -93,11 +93,6 @@ int dcache_bsize;
int icache_bsize;
int ucache_bsize;
-#ifdef CONFIG_MAGIC_SYSRQ
-unsigned long SYSRQ_KEY;
-#endif /* CONFIG_MAGIC_SYSRQ */
-
-
#ifdef CONFIG_SMP
static int smt_enabled_cmdline;
@@ -419,7 +414,7 @@ void __init setup_system(void)
smp_release_cpus();
#endif
- printk("Starting Linux PPC64 %s\n", system_utsname.version);
+ printk("Starting Linux PPC64 %s\n", init_utsname()->version);
printk("-----------------------------------------------------\n");
printk("ppc64_pft_size = 0x%lx\n", ppc64_pft_size);
diff --git a/arch/powerpc/kernel/sys_ppc32.c b/arch/powerpc/kernel/sys_ppc32.c
index 5e391fc25340..d15c33e95959 100644
--- a/arch/powerpc/kernel/sys_ppc32.c
+++ b/arch/powerpc/kernel/sys_ppc32.c
@@ -69,16 +69,20 @@ struct readdir_callback32 {
};
static int fillonedir(void * __buf, const char * name, int namlen,
- off_t offset, ino_t ino, unsigned int d_type)
+ off_t offset, u64 ino, unsigned int d_type)
{
struct readdir_callback32 * buf = (struct readdir_callback32 *) __buf;
struct old_linux_dirent32 __user * dirent;
+ ino_t d_ino;
if (buf->count)
return -EINVAL;
+ d_ino = ino;
+ if (sizeof(d_ino) < sizeof(ino) && d_ino != ino)
+ return -EOVERFLOW;
buf->count++;
dirent = buf->dirent;
- put_user(ino, &dirent->d_ino);
+ put_user(d_ino, &dirent->d_ino);
put_user(offset, &dirent->d_offset);
put_user(namlen, &dirent->d_namlen);
copy_to_user(dirent->d_name, name, namlen);
@@ -120,15 +124,20 @@ asmlinkage long ppc32_select(u32 n, compat_ulong_t __user *inp,
int cp_compat_stat(struct kstat *stat, struct compat_stat __user *statbuf)
{
+ compat_ino_t ino;
long err;
if (stat->size > MAX_NON_LFS || !new_valid_dev(stat->dev) ||
!new_valid_dev(stat->rdev))
return -EOVERFLOW;
+ ino = stat->ino;
+ if (sizeof(ino) < sizeof(stat->ino) && ino != stat->ino)
+ return -EOVERFLOW;
+
err = access_ok(VERIFY_WRITE, statbuf, sizeof(*statbuf)) ? 0 : -EFAULT;
err |= __put_user(new_encode_dev(stat->dev), &statbuf->st_dev);
- err |= __put_user(stat->ino, &statbuf->st_ino);
+ err |= __put_user(ino, &statbuf->st_ino);
err |= __put_user(stat->mode, &statbuf->st_mode);
err |= __put_user(stat->nlink, &statbuf->st_nlink);
err |= __put_user(stat->uid, &statbuf->st_uid);
diff --git a/arch/powerpc/kernel/syscalls.c b/arch/powerpc/kernel/syscalls.c
index 9b69d99a9103..d358866b880f 100644
--- a/arch/powerpc/kernel/syscalls.c
+++ b/arch/powerpc/kernel/syscalls.c
@@ -260,7 +260,7 @@ long ppc_newuname(struct new_utsname __user * name)
int err = 0;
down_read(&uts_sem);
- if (copy_to_user(name, &system_utsname, sizeof(*name)))
+ if (copy_to_user(name, utsname(), sizeof(*name)))
err = -EFAULT;
up_read(&uts_sem);
if (!err)
@@ -273,7 +273,7 @@ int sys_uname(struct old_utsname __user *name)
int err = 0;
down_read(&uts_sem);
- if (copy_to_user(name, &system_utsname, sizeof(*name)))
+ if (copy_to_user(name, utsname(), sizeof(*name)))
err = -EFAULT;
up_read(&uts_sem);
if (!err)
@@ -289,19 +289,19 @@ int sys_olduname(struct oldold_utsname __user *name)
return -EFAULT;
down_read(&uts_sem);
- error = __copy_to_user(&name->sysname, &system_utsname.sysname,
+ error = __copy_to_user(&name->sysname, &utsname()->sysname,
__OLD_UTS_LEN);
error |= __put_user(0, name->sysname + __OLD_UTS_LEN);
- error |= __copy_to_user(&name->nodename, &system_utsname.nodename,
+ error |= __copy_to_user(&name->nodename, &utsname()->nodename,
__OLD_UTS_LEN);
error |= __put_user(0, name->nodename + __OLD_UTS_LEN);
- error |= __copy_to_user(&name->release, &system_utsname.release,
+ error |= __copy_to_user(&name->release, &utsname()->release,
__OLD_UTS_LEN);
error |= __put_user(0, name->release + __OLD_UTS_LEN);
- error |= __copy_to_user(&name->version, &system_utsname.version,
+ error |= __copy_to_user(&name->version, &utsname()->version,
__OLD_UTS_LEN);
error |= __put_user(0, name->version + __OLD_UTS_LEN);
- error |= __copy_to_user(&name->machine, &system_utsname.machine,
+ error |= __copy_to_user(&name->machine, &utsname()->machine,
__OLD_UTS_LEN);
error |= override_machine(name->machine);
up_read(&uts_sem);
diff --git a/arch/powerpc/kernel/sysfs.c b/arch/powerpc/kernel/sysfs.c
index 406f308ddead..d45a168bdaca 100644
--- a/arch/powerpc/kernel/sysfs.c
+++ b/arch/powerpc/kernel/sysfs.c
@@ -25,8 +25,8 @@ static DEFINE_PER_CPU(struct cpu, cpu_devices);
/* SMT stuff */
#ifdef CONFIG_PPC_MULTIPLATFORM
-/* default to snooze disabled */
-DEFINE_PER_CPU(unsigned long, smt_snooze_delay);
+/* Time in microseconds we delay before sleeping in the idle loop */
+DEFINE_PER_CPU(unsigned long, smt_snooze_delay) = { 100 };
static ssize_t store_smt_snooze_delay(struct sys_device *dev, const char *buf,
size_t count)
diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c
index 7a3c3f791ade..85b9244a098c 100644
--- a/arch/powerpc/kernel/time.c
+++ b/arch/powerpc/kernel/time.c
@@ -117,8 +117,6 @@ unsigned tb_to_ns_shift;
struct gettimeofday_struct do_gtod;
-extern unsigned long wall_jiffies;
-
extern struct timezone sys_tz;
static long timezone_offset;
@@ -693,7 +691,7 @@ void timer_interrupt(struct pt_regs * regs)
tb_next_jiffy = tb_last_jiffy + tb_ticks_per_jiffy;
if (per_cpu(last_jiffy, cpu) >= tb_next_jiffy) {
tb_last_jiffy = tb_next_jiffy;
- do_timer(regs);
+ do_timer(1);
timer_recalc_offset(tb_last_jiffy);
timer_check_rtc();
}
@@ -816,11 +814,6 @@ int do_settimeofday(struct timespec *tv)
/*
* Subtract off the number of nanoseconds since the
* beginning of the last tick.
- * Note that since we don't increment jiffies_64 anywhere other
- * than in do_timer (since we don't have a lost tick problem),
- * wall_jiffies will always be the same as jiffies,
- * and therefore the (jiffies - wall_jiffies) computation
- * has been removed.
*/
tb_delta = tb_ticks_since(tb_last_jiffy);
tb_delta = mulhdu(tb_delta, do_gtod.varp->tb_to_xs); /* in xsec */
@@ -1048,6 +1041,48 @@ void __init time_init(void)
set_dec(tb_ticks_per_jiffy);
}
+#ifdef CONFIG_RTC_CLASS
+static int set_rtc_class_time(struct rtc_time *tm)
+{
+ int err;
+ struct class_device *class_dev =
+ rtc_class_open(CONFIG_RTC_HCTOSYS_DEVICE);
+
+ if (class_dev == NULL)
+ return -ENODEV;
+
+ err = rtc_set_time(class_dev, tm);
+
+ rtc_class_close(class_dev);
+
+ return 0;
+}
+
+static void get_rtc_class_time(struct rtc_time *tm)
+{
+ int err;
+ struct class_device *class_dev =
+ rtc_class_open(CONFIG_RTC_HCTOSYS_DEVICE);
+
+ if (class_dev == NULL)
+ return;
+
+ err = rtc_read_time(class_dev, tm);
+
+ rtc_class_close(class_dev);
+
+ return;
+}
+
+int __init rtc_class_hookup(void)
+{
+ ppc_md.get_rtc_time = get_rtc_class_time;
+ ppc_md.set_rtc_time = set_rtc_class_time;
+
+ return 0;
+}
+#endif /* CONFIG_RTC_CLASS */
+
#define FEBRUARY 2
#define STARTOFTIME 1970
diff --git a/arch/powerpc/lib/Makefile b/arch/powerpc/lib/Makefile
index 336dd191f768..a0360ae10d0c 100644
--- a/arch/powerpc/lib/Makefile
+++ b/arch/powerpc/lib/Makefile
@@ -14,9 +14,15 @@ endif
obj-$(CONFIG_PPC64) += checksum_64.o copypage_64.o copyuser_64.o \
memcpy_64.o usercopy_64.o mem_64.o string.o \
strcase.o
+obj-$(CONFIG_QUICC_ENGINE) += rheap.o
obj-$(CONFIG_XMON) += sstep.o
ifeq ($(CONFIG_PPC64),y)
obj-$(CONFIG_SMP) += locks.o
obj-$(CONFIG_DEBUG_KERNEL) += sstep.o
endif
+
+# Temporary hack until we have migrated to asm-powerpc
+ifeq ($(CONFIG_PPC_MERGE),y)
+obj-$(CONFIG_CPM2) += rheap.o
+endif
diff --git a/arch/powerpc/lib/rheap.c b/arch/powerpc/lib/rheap.c
index 31e511856dc5..57bf991ccd6e 100644
--- a/arch/powerpc/lib/rheap.c
+++ b/arch/powerpc/lib/rheap.c
@@ -423,17 +423,21 @@ void *rh_detach_region(rh_info_t * info, void *start, int size)
return (void *)s;
}
-void *rh_alloc(rh_info_t * info, int size, const char *owner)
+void *rh_alloc_align(rh_info_t * info, int size, int alignment, const char *owner)
{
struct list_head *l;
rh_block_t *blk;
rh_block_t *newblk;
void *start;
- /* Validate size */
- if (size <= 0)
+ /* Validate size, (must be power of two) */
+ if (size <= 0 || (alignment & (alignment - 1)) != 0)
return ERR_PTR(-EINVAL);
+ /* given alignment larger that default rheap alignment */
+ if (alignment > info->alignment)
+ size += alignment - 1;
+
/* Align to configured alignment */
size = (size + (info->alignment - 1)) & ~(info->alignment - 1);
@@ -476,15 +480,27 @@ void *rh_alloc(rh_info_t * info, int size, const char *owner)
attach_taken_block(info, newblk);
+ /* for larger alignment return fixed up pointer */
+ /* this is no problem with the deallocator since */
+ /* we scan for pointers that lie in the blocks */
+ if (alignment > info->alignment)
+ start = (void *)(((unsigned long)start + alignment - 1) &
+ ~(alignment - 1));
+
return start;
}
+void *rh_alloc(rh_info_t * info, int size, const char *owner)
+{
+ return rh_alloc_align(info, size, info->alignment, owner);
+}
+
/* allocate at precisely the given address */
void *rh_alloc_fixed(rh_info_t * info, void *start, int size, const char *owner)
{
struct list_head *l;
rh_block_t *blk, *newblk1, *newblk2;
- unsigned long s, e, m, bs, be;
+ unsigned long s, e, m, bs = 0, be = 0;
/* Validate size */
if (size <= 0)
diff --git a/arch/powerpc/math-emu/Makefile b/arch/powerpc/math-emu/Makefile
index 754143e8936b..29bc9126241b 100644
--- a/arch/powerpc/math-emu/Makefile
+++ b/arch/powerpc/math-emu/Makefile
@@ -11,3 +11,6 @@ obj-$(CONFIG_MATH_EMULATION) += fabs.o fadd.o fadds.o fcmpo.o fcmpu.o \
mcrfs.o mffs.o mtfsb0.o mtfsb1.o \
mtfsf.o mtfsfi.o stfiwx.o stfs.o \
udivmodti4.o
+
+CFLAGS_fabs.o = -fno-builtin-fabs
+CFLAGS_math.o = -fno-builtin-fabs
diff --git a/arch/powerpc/mm/fault.c b/arch/powerpc/mm/fault.c
index 78a0d59903ee..e8fa50624b70 100644
--- a/arch/powerpc/mm/fault.c
+++ b/arch/powerpc/mm/fault.c
@@ -333,7 +333,7 @@ good_area:
/* protection fault */
if (error_code & 0x08000000)
goto bad_area;
- if (!(vma->vm_flags & (VM_READ | VM_EXEC)))
+ if (!(vma->vm_flags & (VM_READ | VM_EXEC | VM_WRITE)))
goto bad_area;
}
@@ -386,7 +386,7 @@ bad_area_nosemaphore:
*/
out_of_memory:
up_read(&mm->mmap_sem);
- if (current->pid == 1) {
+ if (is_init(current)) {
yield();
down_read(&mm->mmap_sem);
goto survive;
diff --git a/arch/powerpc/oprofile/backtrace.c b/arch/powerpc/oprofile/backtrace.c
index 75f57bc96b40..b4278cfd1f80 100644
--- a/arch/powerpc/oprofile/backtrace.c
+++ b/arch/powerpc/oprofile/backtrace.c
@@ -11,6 +11,7 @@
#include <linux/sched.h>
#include <asm/processor.h>
#include <asm/uaccess.h>
+#include <asm/compat.h>
#define STACK_SP(STACK) *(STACK)
@@ -26,8 +27,9 @@
static unsigned int user_getsp32(unsigned int sp, int is_first)
{
unsigned int stack_frame[2];
+ void __user *p = compat_ptr(sp);
- if (!access_ok(VERIFY_READ, sp, sizeof(stack_frame)))
+ if (!access_ok(VERIFY_READ, p, sizeof(stack_frame)))
return 0;
/*
@@ -35,8 +37,7 @@ static unsigned int user_getsp32(unsigned int sp, int is_first)
* which means that we've done all that we can do from
* interrupt context.
*/
- if (__copy_from_user_inatomic(stack_frame, (void *)(long)sp,
- sizeof(stack_frame)))
+ if (__copy_from_user_inatomic(stack_frame, p, sizeof(stack_frame)))
return 0;
if (!is_first)
@@ -54,10 +55,10 @@ static unsigned long user_getsp64(unsigned long sp, int is_first)
{
unsigned long stack_frame[3];
- if (!access_ok(VERIFY_READ, sp, sizeof(stack_frame)))
+ if (!access_ok(VERIFY_READ, (void __user *)sp, sizeof(stack_frame)))
return 0;
- if (__copy_from_user_inatomic(stack_frame, (void *)sp,
+ if (__copy_from_user_inatomic(stack_frame, (void __user *)sp,
sizeof(stack_frame)))
return 0;
diff --git a/arch/powerpc/platforms/83xx/mpc834x_itx.c b/arch/powerpc/platforms/83xx/mpc834x_itx.c
index 969fbb6d8c46..8c676d763bb0 100644
--- a/arch/powerpc/platforms/83xx/mpc834x_itx.c
+++ b/arch/powerpc/platforms/83xx/mpc834x_itx.c
@@ -109,6 +109,10 @@ static int __init mpc834x_itx_probe(void)
return 1;
}
+#ifdef CONFIG_RTC_CLASS
+late_initcall(rtc_class_hookup);
+#endif
+
define_machine(mpc834x_itx) {
.name = "MPC834x ITX",
.probe = mpc834x_itx_probe,
diff --git a/arch/powerpc/platforms/85xx/Kconfig b/arch/powerpc/platforms/85xx/Kconfig
index c3268d9877e4..0584f3c7e884 100644
--- a/arch/powerpc/platforms/85xx/Kconfig
+++ b/arch/powerpc/platforms/85xx/Kconfig
@@ -11,6 +11,12 @@ config MPC8540_ADS
help
This option enables support for the MPC 8540 ADS board
+config MPC8560_ADS
+ bool "Freescale MPC8560 ADS"
+ select DEFAULT_UIMAGE
+ help
+ This option enables support for the MPC 8560 ADS board
+
config MPC85xx_CDS
bool "Freescale MPC85xx CDS"
select DEFAULT_UIMAGE
@@ -25,6 +31,11 @@ config MPC8540
select PPC_INDIRECT_PCI
default y if MPC8540_ADS || MPC85xx_CDS
+config MPC8560
+ bool
+ select PPC_INDIRECT_PCI
+ default y if MPC8560_ADS
+
config PPC_INDIRECT_PCI_BE
bool
depends on PPC_85xx
@@ -34,4 +45,14 @@ config MPIC
bool
default y
+config CPM2
+ bool
+ depends on MPC8560
+ default y
+ help
+ The CPM2 (Communications Processor Module) is a coprocessor on
+ embedded CPUs made by Motorola. Selecting this option means that
+ you wish to build a kernel for a machine with a CPM2 coprocessor
+ on it.
+
endmenu
diff --git a/arch/powerpc/platforms/85xx/Makefile b/arch/powerpc/platforms/85xx/Makefile
index 7615aa59c78b..282f5d0d0152 100644
--- a/arch/powerpc/platforms/85xx/Makefile
+++ b/arch/powerpc/platforms/85xx/Makefile
@@ -3,4 +3,5 @@
#
obj-$(CONFIG_PPC_85xx) += misc.o pci.o
obj-$(CONFIG_MPC8540_ADS) += mpc85xx_ads.o
+obj-$(CONFIG_MPC8560_ADS) += mpc85xx_ads.o
obj-$(CONFIG_MPC85xx_CDS) += mpc85xx_cds.o
diff --git a/arch/powerpc/platforms/85xx/mpc85xx_ads.c b/arch/powerpc/platforms/85xx/mpc85xx_ads.c
index cae6b73357d5..28070e7ae507 100644
--- a/arch/powerpc/platforms/85xx/mpc85xx_ads.c
+++ b/arch/powerpc/platforms/85xx/mpc85xx_ads.c
@@ -32,6 +32,13 @@
#include <sysdev/fsl_soc.h>
#include "mpc85xx.h"
+#ifdef CONFIG_CPM2
+#include <linux/fs_enet_pd.h>
+#include <asm/cpm2.h>
+#include <sysdev/cpm2_pic.h>
+#include <asm/fs_pd.h>
+#endif
+
#ifndef CONFIG_PCI
unsigned long isa_io_base = 0;
unsigned long isa_mem_base = 0;
@@ -57,12 +64,29 @@ mpc85xx_pcibios_fixup(void)
}
#endif /* CONFIG_PCI */
+#ifdef CONFIG_CPM2
+
+static void cpm2_cascade(unsigned int irq, struct irq_desc *desc,
+ struct pt_regs *regs)
+{
+ int cascade_irq;
+
+ while ((cascade_irq = cpm2_get_irq(regs)) >= 0) {
+ generic_handle_irq(cascade_irq, regs);
+ }
+ desc->chip->eoi(irq);
+}
+
+#endif /* CONFIG_CPM2 */
void __init mpc85xx_ads_pic_init(void)
{
struct mpic *mpic;
struct resource r;
struct device_node *np = NULL;
+#ifdef CONFIG_CPM2
+ int irq;
+#endif
np = of_find_node_by_type(np, "open-pic");
@@ -104,11 +128,103 @@ void __init mpc85xx_ads_pic_init(void)
mpic_assign_isu(mpic, 14, r.start + 0x10100);
mpic_init(mpic);
+
+#ifdef CONFIG_CPM2
+ /* Setup CPM2 PIC */
+ np = of_find_node_by_type(NULL, "cpm-pic");
+ if (np == NULL) {
+ printk(KERN_ERR "PIC init: can not find cpm-pic node\n");
+ return;
+ }
+ irq = irq_of_parse_and_map(np, 0);
+
+ cpm2_pic_init(np);
+ set_irq_chained_handler(irq, cpm2_cascade);
+#endif
}
/*
* Setup the architecture
*/
+#ifdef CONFIG_CPM2
+void init_fcc_ioports(struct fs_platform_info *fpi)
+{
+ struct io_port *io = cpm2_map(im_ioport);
+ int fcc_no = fs_get_fcc_index(fpi->fs_no);
+ int target;
+ u32 tempval;
+
+ switch(fcc_no) {
+ case 1:
+ tempval = in_be32(&io->iop_pdirb);
+ tempval &= ~PB2_DIRB0;
+ tempval |= PB2_DIRB1;
+ out_be32(&io->iop_pdirb, tempval);
+
+ tempval = in_be32(&io->iop_psorb);
+ tempval &= ~PB2_PSORB0;
+ tempval |= PB2_PSORB1;
+ out_be32(&io->iop_psorb, tempval);
+
+ tempval = in_be32(&io->iop_pparb);
+ tempval |= (PB2_DIRB0 | PB2_DIRB1);
+ out_be32(&io->iop_pparb, tempval);
+
+ target = CPM_CLK_FCC2;
+ break;
+ case 2:
+ tempval = in_be32(&io->iop_pdirb);
+ tempval &= ~PB3_DIRB0;
+ tempval |= PB3_DIRB1;
+ out_be32(&io->iop_pdirb, tempval);
+
+ tempval = in_be32(&io->iop_psorb);
+ tempval &= ~PB3_PSORB0;
+ tempval |= PB3_PSORB1;
+ out_be32(&io->iop_psorb, tempval);
+
+ tempval = in_be32(&io->iop_pparb);
+ tempval |= (PB3_DIRB0 | PB3_DIRB1);
+ out_be32(&io->iop_pparb, tempval);
+
+ tempval = in_be32(&io->iop_pdirc);
+ tempval |= PC3_DIRC1;
+ out_be32(&io->iop_pdirc, tempval);
+
+ tempval = in_be32(&io->iop_pparc);
+ tempval |= PC3_DIRC1;
+ out_be32(&io->iop_pparc, tempval);
+
+ target = CPM_CLK_FCC3;
+ break;
+ default:
+ printk(KERN_ERR "init_fcc_ioports: invalid FCC number\n");
+ return;
+ }
+
+ /* Port C has clocks...... */
+ tempval = in_be32(&io->iop_psorc);
+ tempval &= ~(PC_CLK(fpi->clk_rx - 8) | PC_CLK(fpi->clk_tx - 8));
+ out_be32(&io->iop_psorc, tempval);
+
+ tempval = in_be32(&io->iop_pdirc);
+ tempval &= ~(PC_CLK(fpi->clk_rx - 8) | PC_CLK(fpi->clk_tx - 8));
+ out_be32(&io->iop_pdirc, tempval);
+ tempval = in_be32(&io->iop_pparc);
+ tempval |= (PC_CLK(fpi->clk_rx - 8) | PC_CLK(fpi->clk_tx - 8));
+ out_be32(&io->iop_pparc, tempval);
+
+ cpm2_unmap(io);
+
+ /* Configure Serial Interface clock routing.
+ * First, clear FCC bits to zero,
+ * then set the ones we want.
+ */
+ cpm2_clk_setup(target, fpi->clk_rx, CPM_CLK_RX);
+ cpm2_clk_setup(target, fpi->clk_tx, CPM_CLK_TX);
+}
+#endif
+
static void __init mpc85xx_ads_setup_arch(void)
{
struct device_node *cpu;
@@ -131,6 +247,10 @@ static void __init mpc85xx_ads_setup_arch(void)
of_node_put(cpu);
}
+#ifdef CONFIG_CPM2
+ cpm2_reset();
+#endif
+
#ifdef CONFIG_PCI
for (np = NULL; (np = of_find_node_by_type(np, "pci")) != NULL;)
add_bridge(np);
diff --git a/arch/powerpc/platforms/85xx/mpc85xx_ads.h b/arch/powerpc/platforms/85xx/mpc85xx_ads.h
new file mode 100644
index 000000000000..effcbf78f851
--- /dev/null
+++ b/arch/powerpc/platforms/85xx/mpc85xx_ads.h
@@ -0,0 +1,61 @@
+/*
+ * MPC85xx ADS board definitions
+ *
+ * Maintainer: Kumar Gala <galak@kernel.crashing.org>
+ *
+ * Copyright 2004 Freescale Semiconductor Inc.
+ *
+ * 2006 (c) MontaVista Software, Inc.
+ * Vitaly Bordug <vbordug@ru.mvista.com>
+ *
+ * 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.
+ *
+ */
+
+#ifndef __MACH_MPC85XXADS_H
+#define __MACH_MPC85XXADS_H
+
+#include <linux/config.h>
+#include <linux/initrd.h>
+#include <sysdev/fsl_soc.h>
+
+#define BCSR_ADDR ((uint)0xf8000000)
+#define BCSR_SIZE ((uint)(32 * 1024))
+
+#ifdef CONFIG_CPM2
+
+#define MPC85xx_CPM_OFFSET (0x80000)
+
+#define CPM_MAP_ADDR (get_immrbase() + MPC85xx_CPM_OFFSET)
+#define CPM_IRQ_OFFSET 60
+
+#define SIU_INT_SMC1 ((uint)0x04+CPM_IRQ_OFFSET)
+#define SIU_INT_SMC2 ((uint)0x05+CPM_IRQ_OFFSET)
+#define SIU_INT_SCC1 ((uint)0x28+CPM_IRQ_OFFSET)
+#define SIU_INT_SCC2 ((uint)0x29+CPM_IRQ_OFFSET)
+#define SIU_INT_SCC3 ((uint)0x2a+CPM_IRQ_OFFSET)
+#define SIU_INT_SCC4 ((uint)0x2b+CPM_IRQ_OFFSET)
+
+/* FCC1 Clock Source Configuration. These can be
+ * redefined in the board specific file.
+ * Can only choose from CLK9-12 */
+#define F1_RXCLK 12
+#define F1_TXCLK 11
+
+/* FCC2 Clock Source Configuration. These can be
+ * redefined in the board specific file.
+ * Can only choose from CLK13-16 */
+#define F2_RXCLK 13
+#define F2_TXCLK 14
+
+/* FCC3 Clock Source Configuration. These can be
+ * redefined in the board specific file.
+ * Can only choose from CLK13-16 */
+#define F3_RXCLK 15
+#define F3_TXCLK 16
+
+#endif /* CONFIG_CPM2 */
+#endif /* __MACH_MPC85XXADS_H */
diff --git a/arch/powerpc/platforms/cell/spu_base.c b/arch/powerpc/platforms/cell/spu_base.c
index 3bd36d46ab4a..0f5c8ebc7fc3 100644
--- a/arch/powerpc/platforms/cell/spu_base.c
+++ b/arch/powerpc/platforms/cell/spu_base.c
@@ -538,7 +538,7 @@ static void __iomem * __init map_spe_prop(struct spu *spu,
const void *p;
int proplen;
- void* ret = NULL;
+ void __iomem *ret = NULL;
int err = 0;
p = get_property(n, name, &proplen);
@@ -562,7 +562,7 @@ static void spu_unmap(struct spu *spu)
iounmap(spu->priv2);
iounmap(spu->priv1);
iounmap(spu->problem);
- iounmap((u8 __iomem *)spu->local_store);
+ iounmap((__force u8 __iomem *)spu->local_store);
}
/* This function shall be abstracted for HV platforms */
diff --git a/arch/powerpc/platforms/cell/spufs/file.c b/arch/powerpc/platforms/cell/spufs/file.c
index 58e794f9da1b..51fd197ab5dd 100644
--- a/arch/powerpc/platforms/cell/spufs/file.c
+++ b/arch/powerpc/platforms/cell/spufs/file.c
@@ -1342,7 +1342,7 @@ static u64 spufs_id_get(void *data)
return num;
}
-DEFINE_SIMPLE_ATTRIBUTE(spufs_id_ops, spufs_id_get, 0, "0x%llx\n")
+DEFINE_SIMPLE_ATTRIBUTE(spufs_id_ops, spufs_id_get, NULL, "0x%llx\n")
struct tree_descr spufs_dir_contents[] = {
{ "mem", &spufs_mem_fops, 0666, },
diff --git a/arch/powerpc/platforms/cell/spufs/hw_ops.c b/arch/powerpc/platforms/cell/spufs/hw_ops.c
index c8670f519734..efc452e71ab0 100644
--- a/arch/powerpc/platforms/cell/spufs/hw_ops.c
+++ b/arch/powerpc/platforms/cell/spufs/hw_ops.c
@@ -234,7 +234,7 @@ static void spu_hw_runcntl_stop(struct spu_context *ctx)
static int spu_hw_set_mfc_query(struct spu_context * ctx, u32 mask, u32 mode)
{
- struct spu_problem *prob = ctx->spu->problem;
+ struct spu_problem __iomem *prob = ctx->spu->problem;
int ret;
spin_lock_irq(&ctx->spu->register_lock);
@@ -263,7 +263,7 @@ static int spu_hw_send_mfc_command(struct spu_context *ctx,
struct mfc_dma_command *cmd)
{
u32 status;
- struct spu_problem *prob = ctx->spu->problem;
+ struct spu_problem __iomem *prob = ctx->spu->problem;
spin_lock_irq(&ctx->spu->register_lock);
out_be32(&prob->mfc_lsa_W, cmd->lsa);
diff --git a/arch/powerpc/platforms/iseries/mf.c b/arch/powerpc/platforms/iseries/mf.c
index 1a2c2a50f922..1983b640bac1 100644
--- a/arch/powerpc/platforms/iseries/mf.c
+++ b/arch/powerpc/platforms/iseries/mf.c
@@ -357,7 +357,7 @@ static int dma_and_signal_ce_msg(char *ce_msg,
*/
static int shutdown(void)
{
- int rc = kill_proc(1, SIGINT, 1);
+ int rc = kill_cad_pid(SIGINT, 1);
if (rc) {
printk(KERN_ALERT "mf.c: SIGINT to init failed (%d), "
diff --git a/arch/powerpc/platforms/maple/pci.c b/arch/powerpc/platforms/maple/pci.c
index c3aa46b8e2b9..1b827618e05f 100644
--- a/arch/powerpc/platforms/maple/pci.c
+++ b/arch/powerpc/platforms/maple/pci.c
@@ -96,14 +96,14 @@ static unsigned long u3_agp_cfa1(u8 bus, u8 devfn, u8 off)
1UL;
}
-static unsigned long u3_agp_cfg_access(struct pci_controller* hose,
+static volatile void __iomem *u3_agp_cfg_access(struct pci_controller* hose,
u8 bus, u8 dev_fn, u8 offset)
{
unsigned int caddr;
if (bus == hose->first_busno) {
if (dev_fn < (11 << 3))
- return 0;
+ return NULL;
caddr = u3_agp_cfa0(dev_fn, offset);
} else
caddr = u3_agp_cfa1(bus, dev_fn, offset);
@@ -114,14 +114,14 @@ static unsigned long u3_agp_cfg_access(struct pci_controller* hose,
} while (in_le32(hose->cfg_addr) != caddr);
offset &= 0x07;
- return ((unsigned long)hose->cfg_data) + offset;
+ return hose->cfg_data + offset;
}
static int u3_agp_read_config(struct pci_bus *bus, unsigned int devfn,
int offset, int len, u32 *val)
{
struct pci_controller *hose;
- unsigned long addr;
+ volatile void __iomem *addr;
hose = pci_bus_to_host(bus);
if (hose == NULL)
@@ -136,13 +136,13 @@ static int u3_agp_read_config(struct pci_bus *bus, unsigned int devfn,
*/
switch (len) {
case 1:
- *val = in_8((u8 *)addr);
+ *val = in_8(addr);
break;
case 2:
- *val = in_le16((u16 *)addr);
+ *val = in_le16(addr);
break;
default:
- *val = in_le32((u32 *)addr);
+ *val = in_le32(addr);
break;
}
return PCIBIOS_SUCCESSFUL;
@@ -152,7 +152,7 @@ static int u3_agp_write_config(struct pci_bus *bus, unsigned int devfn,
int offset, int len, u32 val)
{
struct pci_controller *hose;
- unsigned long addr;
+ volatile void __iomem *addr;
hose = pci_bus_to_host(bus);
if (hose == NULL)
@@ -167,16 +167,16 @@ static int u3_agp_write_config(struct pci_bus *bus, unsigned int devfn,
*/
switch (len) {
case 1:
- out_8((u8 *)addr, val);
- (void) in_8((u8 *)addr);
+ out_8(addr, val);
+ (void) in_8(addr);
break;
case 2:
- out_le16((u16 *)addr, val);
- (void) in_le16((u16 *)addr);
+ out_le16(addr, val);
+ (void) in_le16(addr);
break;
default:
- out_le32((u32 *)addr, val);
- (void) in_le32((u32 *)addr);
+ out_le32(addr, val);
+ (void) in_le32(addr);
break;
}
return PCIBIOS_SUCCESSFUL;
@@ -198,22 +198,22 @@ static unsigned long u3_ht_cfa1(u8 bus, u8 devfn, u8 off)
return u3_ht_cfa0(devfn, off) + (bus << 16) + 0x01000000UL;
}
-static unsigned long u3_ht_cfg_access(struct pci_controller* hose,
+static volatile void __iomem *u3_ht_cfg_access(struct pci_controller* hose,
u8 bus, u8 devfn, u8 offset)
{
if (bus == hose->first_busno) {
if (PCI_SLOT(devfn) == 0)
- return 0;
- return ((unsigned long)hose->cfg_data) + u3_ht_cfa0(devfn, offset);
+ return NULL;
+ return hose->cfg_data + u3_ht_cfa0(devfn, offset);
} else
- return ((unsigned long)hose->cfg_data) + u3_ht_cfa1(bus, devfn, offset);
+ return hose->cfg_data + u3_ht_cfa1(bus, devfn, offset);
}
static int u3_ht_read_config(struct pci_bus *bus, unsigned int devfn,
int offset, int len, u32 *val)
{
struct pci_controller *hose;
- unsigned long addr;
+ volatile void __iomem *addr;
hose = pci_bus_to_host(bus);
if (hose == NULL)
@@ -232,13 +232,13 @@ static int u3_ht_read_config(struct pci_bus *bus, unsigned int devfn,
*/
switch (len) {
case 1:
- *val = in_8((u8 *)addr);
+ *val = in_8(addr);
break;
case 2:
- *val = in_le16((u16 *)addr);
+ *val = in_le16(addr);
break;
default:
- *val = in_le32((u32 *)addr);
+ *val = in_le32(addr);
break;
}
return PCIBIOS_SUCCESSFUL;
@@ -248,7 +248,7 @@ static int u3_ht_write_config(struct pci_bus *bus, unsigned int devfn,
int offset, int len, u32 val)
{
struct pci_controller *hose;
- unsigned long addr;
+ volatile void __iomem *addr;
hose = pci_bus_to_host(bus);
if (hose == NULL)
@@ -266,16 +266,16 @@ static int u3_ht_write_config(struct pci_bus *bus, unsigned int devfn,
*/
switch (len) {
case 1:
- out_8((u8 *)addr, val);
- (void) in_8((u8 *)addr);
+ out_8(addr, val);
+ (void) in_8(addr);
break;
case 2:
- out_le16((u16 *)addr, val);
- (void) in_le16((u16 *)addr);
+ out_le16(addr, val);
+ (void) in_le16(addr);
break;
default:
- out_le32((u32 *)addr, val);
- (void) in_le32((u32 *)addr);
+ out_le32(addr, val);
+ (void) in_le32(addr);
break;
}
return PCIBIOS_SUCCESSFUL;
@@ -315,7 +315,7 @@ static void __init setup_u3_ht(struct pci_controller* hose)
* the reg address cell, we shall fix that by killing struct
* reg_property and using some accessor functions instead
*/
- hose->cfg_data = (volatile unsigned char *)ioremap(0xf2000000, 0x02000000);
+ hose->cfg_data = ioremap(0xf2000000, 0x02000000);
hose->first_busno = 0;
hose->last_busno = 0xef;
diff --git a/arch/powerpc/platforms/powermac/cpufreq_64.c b/arch/powerpc/platforms/powermac/cpufreq_64.c
index d30466d74194..9d22361a26d6 100644
--- a/arch/powerpc/platforms/powermac/cpufreq_64.c
+++ b/arch/powerpc/platforms/powermac/cpufreq_64.c
@@ -104,7 +104,7 @@ static void g5_smu_switch_volt(int speed_mode)
{
struct smu_simple_cmd cmd;
- DECLARE_COMPLETION(comp);
+ DECLARE_COMPLETION_ONSTACK(comp);
smu_queue_simple(&cmd, SMU_CMD_POWER_COMMAND, 8, smu_done_complete,
&comp, 'V', 'S', 'L', 'E', 'W',
0xff, g5_fvt_cur+1, speed_mode);
diff --git a/arch/powerpc/platforms/powermac/nvram.c b/arch/powerpc/platforms/powermac/nvram.c
index 6a36ea9bf673..692945c14919 100644
--- a/arch/powerpc/platforms/powermac/nvram.c
+++ b/arch/powerpc/platforms/powermac/nvram.c
@@ -195,7 +195,7 @@ static void pmu_nvram_complete(struct adb_request *req)
static unsigned char pmu_nvram_read_byte(int addr)
{
struct adb_request req;
- DECLARE_COMPLETION(req_complete);
+ DECLARE_COMPLETION_ONSTACK(req_complete);
req.arg = system_state == SYSTEM_RUNNING ? &req_complete : NULL;
if (pmu_request(&req, pmu_nvram_complete, 3, PMU_READ_NVRAM,
@@ -211,7 +211,7 @@ static unsigned char pmu_nvram_read_byte(int addr)
static void pmu_nvram_write_byte(int addr, unsigned char val)
{
struct adb_request req;
- DECLARE_COMPLETION(req_complete);
+ DECLARE_COMPLETION_ONSTACK(req_complete);
req.arg = system_state == SYSTEM_RUNNING ? &req_complete : NULL;
if (pmu_request(&req, pmu_nvram_complete, 4, PMU_WRITE_NVRAM,
diff --git a/arch/powerpc/platforms/pseries/eeh.c b/arch/powerpc/platforms/pseries/eeh.c
index 84bc8f7e17ef..3c2d63ebf787 100644
--- a/arch/powerpc/platforms/pseries/eeh.c
+++ b/arch/powerpc/platforms/pseries/eeh.c
@@ -225,6 +225,7 @@ static void __eeh_mark_slot (struct device_node *dn, int mode_flag)
void eeh_mark_slot (struct device_node *dn, int mode_flag)
{
+ struct pci_dev *dev;
dn = find_device_pe (dn);
/* Back up one, since config addrs might be shared */
@@ -232,6 +233,12 @@ void eeh_mark_slot (struct device_node *dn, int mode_flag)
dn = dn->parent;
PCI_DN(dn)->eeh_mode |= mode_flag;
+
+ /* Mark the pci device too */
+ dev = PCI_DN(dn)->pcidev;
+ if (dev)
+ dev->error_state = pci_channel_io_frozen;
+
__eeh_mark_slot (dn->child, mode_flag);
}
diff --git a/arch/powerpc/platforms/pseries/ras.c b/arch/powerpc/platforms/pseries/ras.c
index 903115d67fdc..311ed1993fc0 100644
--- a/arch/powerpc/platforms/pseries/ras.c
+++ b/arch/powerpc/platforms/pseries/ras.c
@@ -337,7 +337,7 @@ static int recover_mce(struct pt_regs *regs, struct rtas_error_log * err)
err->disposition == RTAS_DISP_NOT_RECOVERED &&
err->target == RTAS_TARGET_MEMORY &&
err->type == RTAS_TYPE_ECC_UNCORR &&
- !(current->pid == 0 || current->pid == 1)) {
+ !(current->pid == 0 || is_init(current))) {
/* Kill off a user process with an ECC error */
printk(KERN_ERR "MCE: uncorrectable ecc error for pid %d\n",
current->pid);
diff --git a/arch/powerpc/platforms/pseries/setup.c b/arch/powerpc/platforms/pseries/setup.c
index a6398fbe530d..43dbf737698c 100644
--- a/arch/powerpc/platforms/pseries/setup.c
+++ b/arch/powerpc/platforms/pseries/setup.c
@@ -342,7 +342,7 @@ static int __init pSeries_init_panel(void)
{
/* Manually leave the kernel version on the panel. */
ppc_md.progress("Linux ppc64\n", 0);
- ppc_md.progress(system_utsname.release, 0);
+ ppc_md.progress(init_utsname()->version, 0);
return 0;
}
@@ -477,7 +477,6 @@ static void pseries_dedicated_idle_sleep(void)
{
unsigned int cpu = smp_processor_id();
unsigned long start_snooze;
- unsigned long *smt_snooze_delay = &__get_cpu_var(smt_snooze_delay);
/*
* Indicate to the HV that we are idle. Now would be
@@ -490,9 +489,9 @@ static void pseries_dedicated_idle_sleep(void)
* has been checked recently. If we should poll for a little
* while, do so.
*/
- if (*smt_snooze_delay) {
+ if (__get_cpu_var(smt_snooze_delay)) {
start_snooze = get_tb() +
- *smt_snooze_delay * tb_ticks_per_usec;
+ __get_cpu_var(smt_snooze_delay) * tb_ticks_per_usec;
local_irq_enable();
set_thread_flag(TIF_POLLING_NRFLAG);
@@ -512,24 +511,7 @@ static void pseries_dedicated_idle_sleep(void)
goto out;
}
- /*
- * If not SMT, cede processor. If CPU is running SMT
- * cede if the other thread is not idle, so that it can
- * go single-threaded. If the other thread is idle,
- * we ask the hypervisor if it has pending work it
- * wants to do and cede if it does. Otherwise we keep
- * polling in order to reduce interrupt latency.
- *
- * Doing the cede when the other thread is active will
- * result in this thread going dormant, meaning the other
- * thread gets to run in single-threaded (ST) mode, which
- * is slightly faster than SMT mode with this thread at
- * very low priority. The cede enables interrupts, which
- * doesn't matter here.
- */
- if (!cpu_has_feature(CPU_FTR_SMT) || !lppaca[cpu ^ 1].idle
- || poll_pending() == H_PENDING)
- cede_processor();
+ cede_processor();
out:
HMT_medium();
diff --git a/arch/powerpc/sysdev/Makefile b/arch/powerpc/sysdev/Makefile
index e5e999ea891a..f15f4d78aee9 100644
--- a/arch/powerpc/sysdev/Makefile
+++ b/arch/powerpc/sysdev/Makefile
@@ -17,3 +17,8 @@ ifeq ($(CONFIG_PPC_MERGE),y)
obj-$(CONFIG_PPC_I8259) += i8259.o
obj-$(CONFIG_PPC_83xx) += ipic.o
endif
+
+# Temporary hack until we have migrated to asm-powerpc
+ifeq ($(ARCH),powerpc)
+obj-$(CONFIG_CPM2) += cpm2_common.o cpm2_pic.o
+endif
diff --git a/arch/powerpc/sysdev/cpm2_common.c b/arch/powerpc/sysdev/cpm2_common.c
new file mode 100644
index 000000000000..ec265995d5d8
--- /dev/null
+++ b/arch/powerpc/sysdev/cpm2_common.c
@@ -0,0 +1,309 @@
+/*
+ * General Purpose functions for the global management of the
+ * 8260 Communication Processor Module.
+ * Copyright (c) 1999-2001 Dan Malek <dan@embeddedalley.com>
+ * Copyright (c) 2000 MontaVista Software, Inc (source@mvista.com)
+ * 2.3.99 Updates
+ *
+ * 2006 (c) MontaVista Software, Inc.
+ * Vitaly Bordug <vbordug@ru.mvista.com>
+ * Merged to arch/powerpc from arch/ppc/syslib/cpm2_common.c
+ *
+ * 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.
+ */
+
+/*
+ *
+ * In addition to the individual control of the communication
+ * channels, there are a few functions that globally affect the
+ * communication processor.
+ *
+ * Buffer descriptors must be allocated from the dual ported memory
+ * space. The allocator for that is here. When the communication
+ * process is reset, we reclaim the memory available. There is
+ * currently no deallocator for this memory.
+ */
+#include <linux/errno.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/param.h>
+#include <linux/string.h>
+#include <linux/mm.h>
+#include <linux/interrupt.h>
+#include <linux/module.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/mpc8260.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <asm/cpm2.h>
+#include <asm/rheap.h>
+#include <asm/fs_pd.h>
+
+#include <sysdev/fsl_soc.h>
+
+static void cpm2_dpinit(void);
+cpm_cpm2_t *cpmp; /* Pointer to comm processor space */
+
+/* We allocate this here because it is used almost exclusively for
+ * the communication processor devices.
+ */
+cpm2_map_t *cpm2_immr;
+intctl_cpm2_t *cpm2_intctl;
+
+#define CPM_MAP_SIZE (0x40000) /* 256k - the PQ3 reserve this amount
+ of space for CPM as it is larger
+ than on PQ2 */
+
+void
+cpm2_reset(void)
+{
+ cpm2_immr = (cpm2_map_t *)ioremap(CPM_MAP_ADDR, CPM_MAP_SIZE);
+ cpm2_intctl = cpm2_map(im_intctl);
+
+ /* Reclaim the DP memory for our use.
+ */
+ cpm2_dpinit();
+
+ /* Tell everyone where the comm processor resides.
+ */
+ cpmp = &cpm2_immr->im_cpm;
+}
+
+/* Set a baud rate generator. This needs lots of work. There are
+ * eight BRGs, which can be connected to the CPM channels or output
+ * as clocks. The BRGs are in two different block of internal
+ * memory mapped space.
+ * The baud rate clock is the system clock divided by something.
+ * It was set up long ago during the initial boot phase and is
+ * is given to us.
+ * Baud rate clocks are zero-based in the driver code (as that maps
+ * to port numbers). Documentation uses 1-based numbering.
+ */
+#define BRG_INT_CLK (get_brgfreq())
+#define BRG_UART_CLK (BRG_INT_CLK/16)
+
+/* This function is used by UARTS, or anything else that uses a 16x
+ * oversampled clock.
+ */
+void
+cpm_setbrg(uint brg, uint rate)
+{
+ volatile uint *bp;
+
+ /* This is good enough to get SMCs running.....
+ */
+ if (brg < 4) {
+ bp = cpm2_map_size(im_brgc1, 16);
+ } else {
+ bp = cpm2_map_size(im_brgc5, 16);
+ brg -= 4;
+ }
+ bp += brg;
+ *bp = ((BRG_UART_CLK / rate) << 1) | CPM_BRG_EN;
+
+ cpm2_unmap(bp);
+}
+
+/* This function is used to set high speed synchronous baud rate
+ * clocks.
+ */
+void
+cpm2_fastbrg(uint brg, uint rate, int div16)
+{
+ volatile uint *bp;
+
+ if (brg < 4) {
+ bp = cpm2_map_size(im_brgc1, 16);
+ }
+ else {
+ bp = cpm2_map_size(im_brgc5, 16);
+ brg -= 4;
+ }
+ bp += brg;
+ *bp = ((BRG_INT_CLK / rate) << 1) | CPM_BRG_EN;
+ if (div16)
+ *bp |= CPM_BRG_DIV16;
+
+ cpm2_unmap(bp);
+}
+
+int cpm2_clk_setup(enum cpm_clk_target target, int clock, int mode)
+{
+ int ret = 0;
+ int shift;
+ int i, bits = 0;
+ cpmux_t *im_cpmux;
+ u32 *reg;
+ u32 mask = 7;
+ u8 clk_map [24][3] = {
+ {CPM_CLK_FCC1, CPM_BRG5, 0},
+ {CPM_CLK_FCC1, CPM_BRG6, 1},
+ {CPM_CLK_FCC1, CPM_BRG7, 2},
+ {CPM_CLK_FCC1, CPM_BRG8, 3},
+ {CPM_CLK_FCC1, CPM_CLK9, 4},
+ {CPM_CLK_FCC1, CPM_CLK10, 5},
+ {CPM_CLK_FCC1, CPM_CLK11, 6},
+ {CPM_CLK_FCC1, CPM_CLK12, 7},
+ {CPM_CLK_FCC2, CPM_BRG5, 0},
+ {CPM_CLK_FCC2, CPM_BRG6, 1},
+ {CPM_CLK_FCC2, CPM_BRG7, 2},
+ {CPM_CLK_FCC2, CPM_BRG8, 3},
+ {CPM_CLK_FCC2, CPM_CLK13, 4},
+ {CPM_CLK_FCC2, CPM_CLK14, 5},
+ {CPM_CLK_FCC2, CPM_CLK15, 6},
+ {CPM_CLK_FCC2, CPM_CLK16, 7},
+ {CPM_CLK_FCC3, CPM_BRG5, 0},
+ {CPM_CLK_FCC3, CPM_BRG6, 1},
+ {CPM_CLK_FCC3, CPM_BRG7, 2},
+ {CPM_CLK_FCC3, CPM_BRG8, 3},
+ {CPM_CLK_FCC3, CPM_CLK13, 4},
+ {CPM_CLK_FCC3, CPM_CLK14, 5},
+ {CPM_CLK_FCC3, CPM_CLK15, 6},
+ {CPM_CLK_FCC3, CPM_CLK16, 7}
+ };
+
+ im_cpmux = cpm2_map(im_cpmux);
+
+ switch (target) {
+ case CPM_CLK_SCC1:
+ reg = &im_cpmux->cmx_scr;
+ shift = 24;
+ case CPM_CLK_SCC2:
+ reg = &im_cpmux->cmx_scr;
+ shift = 16;
+ break;
+ case CPM_CLK_SCC3:
+ reg = &im_cpmux->cmx_scr;
+ shift = 8;
+ break;
+ case CPM_CLK_SCC4:
+ reg = &im_cpmux->cmx_scr;
+ shift = 0;
+ break;
+ case CPM_CLK_FCC1:
+ reg = &im_cpmux->cmx_fcr;
+ shift = 24;
+ break;
+ case CPM_CLK_FCC2:
+ reg = &im_cpmux->cmx_fcr;
+ shift = 16;
+ break;
+ case CPM_CLK_FCC3:
+ reg = &im_cpmux->cmx_fcr;
+ shift = 8;
+ break;
+ default:
+ printk(KERN_ERR "cpm2_clock_setup: invalid clock target\n");
+ return -EINVAL;
+ }
+
+ if (mode == CPM_CLK_RX)
+ shift +=3;
+
+ for (i=0; i<24; i++) {
+ if (clk_map[i][0] == target && clk_map[i][1] == clock) {
+ bits = clk_map[i][2];
+ break;
+ }
+ }
+ if (i == sizeof(clk_map)/3)
+ ret = -EINVAL;
+
+ bits <<= shift;
+ mask <<= shift;
+ out_be32(reg, (in_be32(reg) & ~mask) | bits);
+
+ cpm2_unmap(im_cpmux);
+ return ret;
+}
+
+/*
+ * dpalloc / dpfree bits.
+ */
+static spinlock_t cpm_dpmem_lock;
+/* 16 blocks should be enough to satisfy all requests
+ * until the memory subsystem goes up... */
+static rh_block_t cpm_boot_dpmem_rh_block[16];
+static rh_info_t cpm_dpmem_info;
+static u8* im_dprambase;
+
+static void cpm2_dpinit(void)
+{
+ spin_lock_init(&cpm_dpmem_lock);
+
+ im_dprambase = ioremap(CPM_MAP_ADDR, CPM_DATAONLY_BASE + CPM_DATAONLY_SIZE);
+
+ /* initialize the info header */
+ rh_init(&cpm_dpmem_info, 1,
+ sizeof(cpm_boot_dpmem_rh_block) /
+ sizeof(cpm_boot_dpmem_rh_block[0]),
+ cpm_boot_dpmem_rh_block);
+
+ /* Attach the usable dpmem area */
+ /* XXX: This is actually crap. CPM_DATAONLY_BASE and
+ * CPM_DATAONLY_SIZE is only a subset of the available dpram. It
+ * varies with the processor and the microcode patches activated.
+ * But the following should be at least safe.
+ */
+ rh_attach_region(&cpm_dpmem_info, (void *)CPM_DATAONLY_BASE,
+ CPM_DATAONLY_SIZE);
+}
+
+/* This function returns an index into the DPRAM area.
+ */
+uint cpm_dpalloc(uint size, uint align)
+{
+ void *start;
+ unsigned long flags;
+
+ spin_lock_irqsave(&cpm_dpmem_lock, flags);
+ cpm_dpmem_info.alignment = align;
+ start = rh_alloc(&cpm_dpmem_info, size, "commproc");
+ spin_unlock_irqrestore(&cpm_dpmem_lock, flags);
+
+ return (uint)start;
+}
+EXPORT_SYMBOL(cpm_dpalloc);
+
+int cpm_dpfree(uint offset)
+{
+ int ret;
+ unsigned long flags;
+
+ spin_lock_irqsave(&cpm_dpmem_lock, flags);
+ ret = rh_free(&cpm_dpmem_info, (void *)offset);
+ spin_unlock_irqrestore(&cpm_dpmem_lock, flags);
+
+ return ret;
+}
+EXPORT_SYMBOL(cpm_dpfree);
+
+/* not sure if this is ever needed */
+uint cpm_dpalloc_fixed(uint offset, uint size, uint align)
+{
+ void *start;
+ unsigned long flags;
+
+ spin_lock_irqsave(&cpm_dpmem_lock, flags);
+ cpm_dpmem_info.alignment = align;
+ start = rh_alloc_fixed(&cpm_dpmem_info, (void *)offset, size, "commproc");
+ spin_unlock_irqrestore(&cpm_dpmem_lock, flags);
+
+ return (uint)start;
+}
+EXPORT_SYMBOL(cpm_dpalloc_fixed);
+
+void cpm_dpdump(void)
+{
+ rh_dump(&cpm_dpmem_info);
+}
+EXPORT_SYMBOL(cpm_dpdump);
+
+void *cpm_dpram_addr(uint offset)
+{
+ return (void *)(im_dprambase + offset);
+}
+EXPORT_SYMBOL(cpm_dpram_addr);
diff --git a/arch/powerpc/sysdev/cpm2_pic.c b/arch/powerpc/sysdev/cpm2_pic.c
new file mode 100644
index 000000000000..51752990f7b9
--- /dev/null
+++ b/arch/powerpc/sysdev/cpm2_pic.c
@@ -0,0 +1,256 @@
+/*
+ * Platform information definitions.
+ *
+ * Copied from arch/ppc/syslib/cpm2_pic.c with minor subsequent updates
+ * to make in work in arch/powerpc/. Original (c) belongs to Dan Malek.
+ *
+ * Author: Vitaly Bordug <vbordug@ru.mvista.com>
+ *
+ * 1999-2001 (c) Dan Malek <dan@embeddedalley.com>
+ * 2006 (c) 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.
+ */
+
+/* The CPM2 internal interrupt controller. It is usually
+ * the only interrupt controller.
+ * There are two 32-bit registers (high/low) for up to 64
+ * possible interrupts.
+ *
+ * Now, the fun starts.....Interrupt Numbers DO NOT MAP
+ * in a simple arithmetic fashion to mask or pending registers.
+ * That is, interrupt 4 does not map to bit position 4.
+ * We create two tables, indexed by vector number, to indicate
+ * which register to use and which bit in the register to use.
+ */
+
+#include <linux/stddef.h>
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/signal.h>
+#include <linux/irq.h>
+
+#include <asm/immap_cpm2.h>
+#include <asm/mpc8260.h>
+#include <asm/io.h>
+#include <asm/prom.h>
+
+#include "cpm2_pic.h"
+
+static struct device_node *cpm2_pic_node;
+static struct irq_host *cpm2_pic_host;
+#define NR_MASK_WORDS ((NR_IRQS + 31) / 32)
+static unsigned long ppc_cached_irq_mask[NR_MASK_WORDS];
+
+static const u_char irq_to_siureg[] = {
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+/* bit numbers do not match the docs, these are precomputed so the bit for
+ * a given irq is (1 << irq_to_siubit[irq]) */
+static const u_char irq_to_siubit[] = {
+ 0, 15, 14, 13, 12, 11, 10, 9,
+ 8, 7, 6, 5, 4, 3, 2, 1,
+ 2, 1, 0, 14, 13, 12, 11, 10,
+ 9, 8, 7, 6, 5, 4, 3, 0,
+ 31, 30, 29, 28, 27, 26, 25, 24,
+ 23, 22, 21, 20, 19, 18, 17, 16,
+ 16, 17, 18, 19, 20, 21, 22, 23,
+ 24, 25, 26, 27, 28, 29, 30, 31,
+};
+
+static void cpm2_mask_irq(unsigned int irq_nr)
+{
+ int bit, word;
+ volatile uint *simr;
+
+ irq_nr -= CPM_IRQ_OFFSET;
+
+ bit = irq_to_siubit[irq_nr];
+ word = irq_to_siureg[irq_nr];
+
+ simr = &(cpm2_intctl->ic_simrh);
+ ppc_cached_irq_mask[word] &= ~(1 << bit);
+ simr[word] = ppc_cached_irq_mask[word];
+}
+
+static void cpm2_unmask_irq(unsigned int irq_nr)
+{
+ int bit, word;
+ volatile uint *simr;
+
+ irq_nr -= CPM_IRQ_OFFSET;
+
+ bit = irq_to_siubit[irq_nr];
+ word = irq_to_siureg[irq_nr];
+
+ simr = &(cpm2_intctl->ic_simrh);
+ ppc_cached_irq_mask[word] |= 1 << bit;
+ simr[word] = ppc_cached_irq_mask[word];
+}
+
+static void cpm2_mask_and_ack(unsigned int irq_nr)
+{
+ int bit, word;
+ volatile uint *simr, *sipnr;
+
+ irq_nr -= CPM_IRQ_OFFSET;
+
+ bit = irq_to_siubit[irq_nr];
+ word = irq_to_siureg[irq_nr];
+
+ simr = &(cpm2_intctl->ic_simrh);
+ sipnr = &(cpm2_intctl->ic_sipnrh);
+ ppc_cached_irq_mask[word] &= ~(1 << bit);
+ simr[word] = ppc_cached_irq_mask[word];
+ sipnr[word] = 1 << bit;
+}
+
+static void cpm2_end_irq(unsigned int irq_nr)
+{
+ int bit, word;
+ volatile uint *simr;
+
+ if (!(irq_desc[irq_nr].status & (IRQ_DISABLED|IRQ_INPROGRESS))
+ && irq_desc[irq_nr].action) {
+
+ irq_nr -= CPM_IRQ_OFFSET;
+ bit = irq_to_siubit[irq_nr];
+ word = irq_to_siureg[irq_nr];
+
+ simr = &(cpm2_intctl->ic_simrh);
+ ppc_cached_irq_mask[word] |= 1 << bit;
+ simr[word] = ppc_cached_irq_mask[word];
+ /*
+ * Work around large numbers of spurious IRQs on PowerPC 82xx
+ * systems.
+ */
+ mb();
+ }
+}
+
+static struct irq_chip cpm2_pic = {
+ .typename = " CPM2 SIU ",
+ .enable = cpm2_unmask_irq,
+ .disable = cpm2_mask_irq,
+ .unmask = cpm2_unmask_irq,
+ .mask_ack = cpm2_mask_and_ack,
+ .end = cpm2_end_irq,
+};
+
+int cpm2_get_irq(struct pt_regs *regs)
+{
+ int irq;
+ unsigned long bits;
+
+ /* For CPM2, read the SIVEC register and shift the bits down
+ * to get the irq number. */
+ bits = cpm2_intctl->ic_sivec;
+ irq = bits >> 26;
+
+ if (irq == 0)
+ return(-1);
+ return irq+CPM_IRQ_OFFSET;
+}
+
+static int cpm2_pic_host_match(struct irq_host *h, struct device_node *node)
+{
+ return cpm2_pic_node == NULL || cpm2_pic_node == node;
+}
+
+static int cpm2_pic_host_map(struct irq_host *h, unsigned int virq,
+ irq_hw_number_t hw)
+{
+ pr_debug("cpm2_pic_host_map(%d, 0x%lx)\n", virq, hw);
+
+ get_irq_desc(virq)->status |= IRQ_LEVEL;
+ set_irq_chip_and_handler(virq, &cpm2_pic, handle_level_irq);
+ return 0;
+}
+
+static void cpm2_host_unmap(struct irq_host *h, unsigned int virq)
+{
+ /* Make sure irq is masked in hardware */
+ cpm2_mask_irq(virq);
+
+ /* remove chip and handler */
+ set_irq_chip_and_handler(virq, NULL, NULL);
+}
+
+static int cpm2_pic_host_xlate(struct irq_host *h, struct device_node *ct,
+ u32 *intspec, unsigned int intsize,
+ irq_hw_number_t *out_hwirq, unsigned int *out_flags)
+{
+ static const unsigned char map_cpm2_senses[4] = {
+ IRQ_TYPE_LEVEL_LOW,
+ IRQ_TYPE_LEVEL_HIGH,
+ IRQ_TYPE_EDGE_FALLING,
+ IRQ_TYPE_EDGE_RISING,
+ };
+
+ *out_hwirq = intspec[0];
+ if (intsize > 1 && intspec[1] < 4)
+ *out_flags = map_cpm2_senses[intspec[1]];
+ else
+ *out_flags = IRQ_TYPE_NONE;
+
+ return 0;
+}
+
+static struct irq_host_ops cpm2_pic_host_ops = {
+ .match = cpm2_pic_host_match,
+ .map = cpm2_pic_host_map,
+ .unmap = cpm2_host_unmap,
+ .xlate = cpm2_pic_host_xlate,
+};
+
+void cpm2_pic_init(struct device_node *node)
+{
+ int i;
+
+ /* Clear the CPM IRQ controller, in case it has any bits set
+ * from the bootloader
+ */
+
+ /* Mask out everything */
+
+ cpm2_intctl->ic_simrh = 0x00000000;
+ cpm2_intctl->ic_simrl = 0x00000000;
+
+ wmb();
+
+ /* Ack everything */
+ cpm2_intctl->ic_sipnrh = 0xffffffff;
+ cpm2_intctl->ic_sipnrl = 0xffffffff;
+ wmb();
+
+ /* Dummy read of the vector */
+ i = cpm2_intctl->ic_sivec;
+ rmb();
+
+ /* Initialize the default interrupt mapping priorities,
+ * in case the boot rom changed something on us.
+ */
+ cpm2_intctl->ic_sicr = 0;
+ cpm2_intctl->ic_scprrh = 0x05309770;
+ cpm2_intctl->ic_scprrl = 0x05309770;
+
+ /* create a legacy host */
+ if (node)
+ cpm2_pic_node = of_node_get(node);
+
+ cpm2_pic_host = irq_alloc_host(IRQ_HOST_MAP_LINEAR, 64, &cpm2_pic_host_ops, 64);
+ if (cpm2_pic_host == NULL) {
+ printk(KERN_ERR "CPM2 PIC: failed to allocate irq host!\n");
+ return;
+ }
+}
diff --git a/arch/powerpc/sysdev/cpm2_pic.h b/arch/powerpc/sysdev/cpm2_pic.h
new file mode 100644
index 000000000000..d63e45d4df58
--- /dev/null
+++ b/arch/powerpc/sysdev/cpm2_pic.h
@@ -0,0 +1,10 @@
+#ifndef _PPC_KERNEL_CPM2_H
+#define _PPC_KERNEL_CPM2_H
+
+extern intctl_cpm2_t *cpm2_intctl;
+
+extern int cpm2_get_irq(struct pt_regs *regs);
+
+extern void cpm2_pic_init(struct device_node*);
+
+#endif /* _PPC_KERNEL_CPM2_H */
diff --git a/arch/powerpc/sysdev/fsl_soc.c b/arch/powerpc/sysdev/fsl_soc.c
index 92ba378b7990..022ed275ea68 100644
--- a/arch/powerpc/sysdev/fsl_soc.c
+++ b/arch/powerpc/sysdev/fsl_soc.c
@@ -3,6 +3,9 @@
*
* Maintained by Kumar Gala (see MAINTAINERS for contact information)
*
+ * 2006 (c) MontaVista Software, Inc.
+ * Vitaly Bordug <vbordug@ru.mvista.com>
+ *
* 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
@@ -20,15 +23,20 @@
#include <linux/device.h>
#include <linux/platform_device.h>
#include <linux/fsl_devices.h>
+#include <linux/fs_enet_pd.h>
+#include <linux/fs_uart_pd.h>
#include <asm/system.h>
#include <asm/atomic.h>
#include <asm/io.h>
#include <asm/irq.h>
+#include <asm/time.h>
#include <asm/prom.h>
#include <sysdev/fsl_soc.h>
#include <mm/mmu_decl.h>
+#include <asm/cpm2.h>
+extern void init_fcc_ioports(struct fs_platform_info*);
static phys_addr_t immrbase = -1;
phys_addr_t get_immrbase(void)
@@ -42,7 +50,9 @@ phys_addr_t get_immrbase(void)
if (soc) {
unsigned int size;
const void *prop = get_property(soc, "reg", &size);
- immrbase = of_translate_address(soc, prop);
+
+ if (prop)
+ immrbase = of_translate_address(soc, prop);
of_node_put(soc);
};
@@ -51,6 +61,59 @@ phys_addr_t get_immrbase(void)
EXPORT_SYMBOL(get_immrbase);
+#ifdef CONFIG_CPM2
+
+static u32 brgfreq = -1;
+
+u32 get_brgfreq(void)
+{
+ struct device_node *node;
+
+ if (brgfreq != -1)
+ return brgfreq;
+
+ node = of_find_node_by_type(NULL, "cpm");
+ if (node) {
+ unsigned int size;
+ const unsigned int *prop = get_property(node, "brg-frequency",
+ &size);
+
+ if (prop)
+ brgfreq = *prop;
+ of_node_put(node);
+ };
+
+ return brgfreq;
+}
+
+EXPORT_SYMBOL(get_brgfreq);
+
+static u32 fs_baudrate = -1;
+
+u32 get_baudrate(void)
+{
+ struct device_node *node;
+
+ if (fs_baudrate != -1)
+ return fs_baudrate;
+
+ node = of_find_node_by_type(NULL, "serial");
+ if (node) {
+ unsigned int size;
+ const unsigned int *prop = get_property(node, "current-speed",
+ &size);
+
+ if (prop)
+ fs_baudrate = *prop;
+ of_node_put(node);
+ };
+
+ return fs_baudrate;
+}
+
+EXPORT_SYMBOL(get_baudrate);
+#endif /* CONFIG_CPM2 */
+
static int __init gfar_mdio_of_init(void)
{
struct device_node *np;
@@ -85,8 +148,11 @@ static int __init gfar_mdio_of_init(void)
mdio_data.irq[k] = -1;
while ((child = of_get_next_child(np, child)) != NULL) {
- const u32 *id = get_property(child, "reg", NULL);
- mdio_data.irq[*id] = irq_of_parse_and_map(child, 0);
+ int irq = irq_of_parse_and_map(child, 0);
+ if (irq != NO_IRQ) {
+ const u32 *id = get_property(child, "reg", NULL);
+ mdio_data.irq[*id] = irq;
+ }
}
ret =
@@ -128,7 +194,7 @@ static int __init gfar_of_init(void)
const char *model;
const void *mac_addr;
const phandle *ph;
- int n_res = 1;
+ int n_res = 2;
memset(r, 0, sizeof(r));
memset(&gfar_data, 0, sizeof(gfar_data));
@@ -159,7 +225,7 @@ static int __init gfar_of_init(void)
gfar_dev =
platform_device_register_simple("fsl-gianfar", i, &r[0],
- n_res + 1);
+ n_res);
if (IS_ERR(gfar_dev)) {
ret = PTR_ERR(gfar_dev);
@@ -478,3 +544,208 @@ err:
}
arch_initcall(fsl_usb_of_init);
+
+#ifdef CONFIG_CPM2
+
+static const char fcc_regs[] = "fcc_regs";
+static const char fcc_regs_c[] = "fcc_regs_c";
+static const char fcc_pram[] = "fcc_pram";
+static char bus_id[9][BUS_ID_SIZE];
+
+static int __init fs_enet_of_init(void)
+{
+ struct device_node *np;
+ unsigned int i;
+ struct platform_device *fs_enet_dev;
+ struct resource res;
+ int ret;
+
+ for (np = NULL, i = 0;
+ (np = of_find_compatible_node(np, "network", "fs_enet")) != NULL;
+ i++) {
+ struct resource r[4];
+ struct device_node *phy, *mdio;
+ struct fs_platform_info fs_enet_data;
+ const unsigned int *id, *phy_addr;
+ const void *mac_addr;
+ const phandle *ph;
+ const char *model;
+
+ memset(r, 0, sizeof(r));
+ memset(&fs_enet_data, 0, sizeof(fs_enet_data));
+
+ ret = of_address_to_resource(np, 0, &r[0]);
+ if (ret)
+ goto err;
+ r[0].name = fcc_regs;
+
+ ret = of_address_to_resource(np, 1, &r[1]);
+ if (ret)
+ goto err;
+ r[1].name = fcc_pram;
+
+ ret = of_address_to_resource(np, 2, &r[2]);
+ if (ret)
+ goto err;
+ r[2].name = fcc_regs_c;
+
+ r[3].start = r[3].end = irq_of_parse_and_map(np, 0);
+ r[3].flags = IORESOURCE_IRQ;
+
+ fs_enet_dev =
+ platform_device_register_simple("fsl-cpm-fcc", i, &r[0], 4);
+
+ if (IS_ERR(fs_enet_dev)) {
+ ret = PTR_ERR(fs_enet_dev);
+ goto err;
+ }
+
+ model = get_property(np, "model", NULL);
+ if (model == NULL) {
+ ret = -ENODEV;
+ goto unreg;
+ }
+
+ mac_addr = get_property(np, "mac-address", NULL);
+ memcpy(fs_enet_data.macaddr, mac_addr, 6);
+
+ ph = get_property(np, "phy-handle", NULL);
+ phy = of_find_node_by_phandle(*ph);
+
+ if (phy == NULL) {
+ ret = -ENODEV;
+ goto unreg;
+ }
+
+ phy_addr = get_property(phy, "reg", NULL);
+ fs_enet_data.phy_addr = *phy_addr;
+
+ id = get_property(np, "device-id", NULL);
+ fs_enet_data.fs_no = *id;
+ strcpy(fs_enet_data.fs_type, model);
+
+ mdio = of_get_parent(phy);
+ ret = of_address_to_resource(mdio, 0, &res);
+ if (ret) {
+ of_node_put(phy);
+ of_node_put(mdio);
+ goto unreg;
+ }
+
+ fs_enet_data.clk_rx = *((u32 *) get_property(np, "rx-clock", NULL));
+ fs_enet_data.clk_tx = *((u32 *) get_property(np, "tx-clock", NULL));
+
+ if (strstr(model, "FCC")) {
+ int fcc_index = *id - 1;
+
+ fs_enet_data.dpram_offset = (u32)cpm_dpram_addr(0);
+ fs_enet_data.rx_ring = 32;
+ fs_enet_data.tx_ring = 32;
+ fs_enet_data.rx_copybreak = 240;
+ fs_enet_data.use_napi = 0;
+ fs_enet_data.napi_weight = 17;
+ fs_enet_data.mem_offset = FCC_MEM_OFFSET(fcc_index);
+ fs_enet_data.cp_page = CPM_CR_FCC_PAGE(fcc_index);
+ fs_enet_data.cp_block = CPM_CR_FCC_SBLOCK(fcc_index);
+
+ snprintf((char*)&bus_id[(*id)], BUS_ID_SIZE, "%x:%02x",
+ (u32)res.start, fs_enet_data.phy_addr);
+ fs_enet_data.bus_id = (char*)&bus_id[(*id)];
+ fs_enet_data.init_ioports = init_fcc_ioports;
+ }
+
+ of_node_put(phy);
+ of_node_put(mdio);
+
+ ret = platform_device_add_data(fs_enet_dev, &fs_enet_data,
+ sizeof(struct
+ fs_platform_info));
+ if (ret)
+ goto unreg;
+ }
+ return 0;
+
+unreg:
+ platform_device_unregister(fs_enet_dev);
+err:
+ return ret;
+}
+
+arch_initcall(fs_enet_of_init);
+
+static const char scc_regs[] = "regs";
+static const char scc_pram[] = "pram";
+
+static int __init cpm_uart_of_init(void)
+{
+ struct device_node *np;
+ unsigned int i;
+ struct platform_device *cpm_uart_dev;
+ int ret;
+
+ for (np = NULL, i = 0;
+ (np = of_find_compatible_node(np, "serial", "cpm_uart")) != NULL;
+ i++) {
+ struct resource r[3];
+ struct fs_uart_platform_info cpm_uart_data;
+ const int *id;
+ const char *model;
+
+ memset(r, 0, sizeof(r));
+ memset(&cpm_uart_data, 0, sizeof(cpm_uart_data));
+
+ ret = of_address_to_resource(np, 0, &r[0]);
+ if (ret)
+ goto err;
+
+ r[0].name = scc_regs;
+
+ ret = of_address_to_resource(np, 1, &r[1]);
+ if (ret)
+ goto err;
+ r[1].name = scc_pram;
+
+ r[2].start = r[2].end = irq_of_parse_and_map(np, 0);
+ r[2].flags = IORESOURCE_IRQ;
+
+ cpm_uart_dev =
+ platform_device_register_simple("fsl-cpm-scc:uart", i, &r[0], 3);
+
+ if (IS_ERR(cpm_uart_dev)) {
+ ret = PTR_ERR(cpm_uart_dev);
+ goto err;
+ }
+
+ id = get_property(np, "device-id", NULL);
+ cpm_uart_data.fs_no = *id;
+
+ model = (char*)get_property(np, "model", NULL);
+ strcpy(cpm_uart_data.fs_type, model);
+
+ cpm_uart_data.uart_clk = ppc_proc_freq;
+
+ cpm_uart_data.tx_num_fifo = 4;
+ cpm_uart_data.tx_buf_size = 32;
+ cpm_uart_data.rx_num_fifo = 4;
+ cpm_uart_data.rx_buf_size = 32;
+ cpm_uart_data.clk_rx = *((u32 *) get_property(np, "rx-clock", NULL));
+ cpm_uart_data.clk_tx = *((u32 *) get_property(np, "tx-clock", NULL));
+
+ ret =
+ platform_device_add_data(cpm_uart_dev, &cpm_uart_data,
+ sizeof(struct
+ fs_uart_platform_info));
+ if (ret)
+ goto unreg;
+ }
+
+ return 0;
+
+unreg:
+ platform_device_unregister(cpm_uart_dev);
+err:
+ return ret;
+}
+
+arch_initcall(cpm_uart_of_init);
+#endif /* CONFIG_CPM2 */
diff --git a/arch/powerpc/sysdev/fsl_soc.h b/arch/powerpc/sysdev/fsl_soc.h
index 5a3dd480d2fd..04e145b5fc32 100644
--- a/arch/powerpc/sysdev/fsl_soc.h
+++ b/arch/powerpc/sysdev/fsl_soc.h
@@ -5,6 +5,8 @@
#include <asm/mmu.h>
extern phys_addr_t get_immrbase(void);
+extern u32 get_brgfreq(void);
+extern u32 get_baudrate(void);
#endif
#endif
diff --git a/arch/ppc/4xx_io/serial_sicc.c b/arch/ppc/4xx_io/serial_sicc.c
index b81a367dc278..87fe9a89dba7 100644
--- a/arch/ppc/4xx_io/serial_sicc.c
+++ b/arch/ppc/4xx_io/serial_sicc.c
@@ -1720,7 +1720,7 @@ static int siccuart_open(struct tty_struct *tty, struct file *filp)
return 0;
}
-static struct tty_operations sicc_ops = {
+static const struct tty_operations sicc_ops = {
.open = siccuart_open,
.close = siccuart_close,
.write = siccuart_write,
diff --git a/arch/ppc/boot/utils/mkbugboot.c b/arch/ppc/boot/utils/mkbugboot.c
index 29115e01f60a..1640c4199ca6 100644
--- a/arch/ppc/boot/utils/mkbugboot.c
+++ b/arch/ppc/boot/utils/mkbugboot.c
@@ -19,36 +19,13 @@
#include <stdlib.h>
#include <errno.h>
#include <fcntl.h>
+#include <netinet/in.h>
#ifdef __sun__
#include <inttypes.h>
#else
#include <stdint.h>
#endif
-#ifdef __i386__
-#define cpu_to_be32(x) le32_to_cpu(x)
-#define cpu_to_be16(x) le16_to_cpu(x)
-#else
-#define cpu_to_be32(x) (x)
-#define cpu_to_be16(x) (x)
-#endif
-
-#define cpu_to_le32(x) le32_to_cpu((x))
-unsigned long le32_to_cpu(unsigned long x)
-{
- return (((x & 0x000000ffU) << 24) |
- ((x & 0x0000ff00U) << 8) |
- ((x & 0x00ff0000U) >> 8) |
- ((x & 0xff000000U) >> 24));
-}
-
-#define cpu_to_le16(x) le16_to_cpu((x))
-unsigned short le16_to_cpu(unsigned short x)
-{
- return (((x & 0x00ff) << 8) |
- ((x & 0xff00) >> 8));
-}
-
/* size of read buffer */
#define SIZE 0x1000
@@ -62,124 +39,109 @@ typedef struct bug_boot_header {
#define HEADER_SIZE sizeof(bug_boot_header_t)
-uint32_t copy_image(int32_t in_fd, int32_t out_fd)
+void update_checksum(void *buf, size_t size, uint16_t *sum)
{
- uint8_t buf[SIZE];
- int n;
- uint32_t image_size = 0;
- uint8_t zero = 0;
-
- lseek(in_fd, ELF_HEADER_SIZE, SEEK_SET);
-
- /* Copy an image while recording its size */
- while ( (n = read(in_fd, buf, SIZE)) > 0 )
- {
- image_size = image_size + n;
- write(out_fd, buf, n);
- }
-
- /* BUG romboot requires that our size is divisible by 2 */
- /* align image to 2 byte boundary */
- if (image_size % 2)
- {
- image_size++;
- write(out_fd, &zero, 1);
- }
-
- return image_size;
+ uint32_t csum = *sum;
+
+ while (size) {
+ csum += *(uint16_t *)buf;
+ if (csum > 0xffff)
+ csum -= 0xffff;
+ buf = (uint16_t *)buf + 1;
+ size -= 2;
+ }
+ *sum = csum;
}
-void write_bugboot_header(int32_t out_fd, uint32_t boot_size)
+uint32_t copy_image(int in_fd, int out_fd, uint16_t *sum)
{
- uint8_t header_block[HEADER_SIZE];
- bug_boot_header_t *bbh = (bug_boot_header_t *)&header_block[0];
-
- memset(header_block, 0, HEADER_SIZE);
-
- /* Fill in the PPCBUG ROM boot header */
- strncpy(bbh->magic_word, "BOOT", 4); /* PPCBUG magic word */
- bbh->entry_offset = cpu_to_be32(HEADER_SIZE); /* Entry address */
- bbh->routine_length= cpu_to_be32(HEADER_SIZE+boot_size+2); /* Routine length */
- strncpy(bbh->routine_name, "LINUXROM", 8); /* Routine name */
-
- /* Output the header and bootloader to the file */
- write(out_fd, header_block, HEADER_SIZE);
+ uint8_t buf[SIZE];
+ int offset = 0;
+ int n;
+ uint32_t image_size = 0;
+
+ lseek(in_fd, ELF_HEADER_SIZE, SEEK_SET);
+
+ /* Copy an image while recording its size */
+ while ( (n = read(in_fd, buf + offset, SIZE - offset)) > 0 ) {
+ n += offset;
+ offset = n & 1;
+ n -= offset;
+ image_size = image_size + n;
+ /* who's going to deal with short writes? */
+ write(out_fd, buf, n);
+ update_checksum(buf, n, sum);
+ if (offset)
+ buf[0] = buf[n];
+ }
+
+ /* BUG romboot requires that our size is divisible by 2 */
+ /* align image to 2 byte boundary */
+ if (offset) {
+ image_size += 2;
+ buf[1] = '\0';
+ write(out_fd, buf, 2);
+ update_checksum(buf, 2, sum);
+ }
+ return image_size;
}
-uint16_t calc_checksum(int32_t bug_fd)
+void write_bugboot_header(int out_fd, uint32_t boot_size, uint16_t *sum)
{
- uint32_t checksum_var = 0;
- uint8_t buf[2];
- int n;
-
- /* Checksum loop */
- while ( (n = read(bug_fd, buf, 2) ) )
- {
- checksum_var = checksum_var + *(uint16_t *)buf;
-
- /* If we carry out, mask it and add one to the checksum */
- if (checksum_var >> 16)
- checksum_var = (checksum_var & 0x0000ffff) + 1;
- }
-
- return checksum_var;
+ static bug_boot_header_t bbh = {
+ .magic_word = "BOOT",
+ .routine_name = "LINUXROM"
+ };
+
+ /* Fill in the PPCBUG ROM boot header */
+ bbh.entry_offset = htonl(HEADER_SIZE); /* Entry address */
+ bbh.routine_length= htonl(HEADER_SIZE+boot_size+2); /* Routine length */
+
+ /* Output the header and bootloader to the file */
+ write(out_fd, &bbh, sizeof(bug_boot_header_t));
+ update_checksum(&bbh, sizeof(bug_boot_header_t), sum);
}
int main(int argc, char *argv[])
{
- int32_t image_fd, bugboot_fd;
- int argptr = 1;
- uint32_t kernel_size = 0;
- uint16_t checksum = 0;
- uint8_t bugbootname[256];
-
- if ( (argc != 3) )
- {
- fprintf(stderr, "usage: %s <kernel_image> <bugboot>\n",argv[0]);
- exit(-1);
- }
-
- /* Get file args */
-
- /* kernel image file */
- if ((image_fd = open( argv[argptr] , 0)) < 0)
- exit(-1);
- argptr++;
+ int image_fd, bugboot_fd;
+ uint32_t kernel_size = 0;
+ uint16_t checksum = 0;
- /* bugboot file */
- if ( !strcmp( argv[argptr], "-" ) )
- bugboot_fd = 1; /* stdout */
- else
- if ((bugboot_fd = creat( argv[argptr] , 0755)) < 0)
- exit(-1);
- else
- strcpy(bugbootname, argv[argptr]);
- argptr++;
+ if (argc != 3) {
+ fprintf(stderr, "usage: %s <kernel_image> <bugboot>\n",argv[0]);
+ exit(-1);
+ }
- /* Set file position after ROM header block where zImage will be written */
- lseek(bugboot_fd, HEADER_SIZE, SEEK_SET);
+ /* Get file args */
- /* Copy kernel image into bugboot image */
- kernel_size = copy_image(image_fd, bugboot_fd);
- close(image_fd);
+ /* kernel image file */
+ if ((image_fd = open(argv[1] , 0)) < 0)
+ exit(-1);
- /* Set file position to beginning where header/romboot will be written */
- lseek(bugboot_fd, 0, SEEK_SET);
+ /* bugboot file */
+ if (!strcmp(argv[2], "-"))
+ bugboot_fd = 1; /* stdout */
+ else if ((bugboot_fd = creat(argv[2] , 0755)) < 0)
+ exit(-1);
- /* Write out BUG header/romboot */
- write_bugboot_header(bugboot_fd, kernel_size);
+ /* Set file position after ROM header block where zImage will be written */
+ lseek(bugboot_fd, HEADER_SIZE, SEEK_SET);
- /* Close bugboot file */
- close(bugboot_fd);
+ /* Copy kernel image into bugboot image */
+ kernel_size = copy_image(image_fd, bugboot_fd, &checksum);
- /* Reopen it as read/write */
- bugboot_fd = open(bugbootname, O_RDWR);
+ /* Set file position to beginning where header/romboot will be written */
+ lseek(bugboot_fd, 0, SEEK_SET);
- /* Calculate checksum */
- checksum = calc_checksum(bugboot_fd);
+ /* Write out BUG header/romboot */
+ write_bugboot_header(bugboot_fd, kernel_size, &checksum);
- /* Write out the calculated checksum */
- write(bugboot_fd, &checksum, 2);
+ /* Write out the calculated checksum */
+ lseek(bugboot_fd, 0, SEEK_END);
+ write(bugboot_fd, &checksum, 2);
- return 0;
+ /* Close bugboot file */
+ close(bugboot_fd);
+ return 0;
}
diff --git a/arch/ppc/boot/utils/mkprep.c b/arch/ppc/boot/utils/mkprep.c
index f6d5a2f2fcf6..192bb397126f 100644
--- a/arch/ppc/boot/utils/mkprep.c
+++ b/arch/ppc/boot/utils/mkprep.c
@@ -15,279 +15,227 @@
* Modified for Sparc hosted builds by Peter Wahl <PeterWahl@web.de>
*/
-#include <fcntl.h>
#include <stdio.h>
-#include <stdlib.h>
#include <string.h>
-#include <strings.h>
-#include <sys/stat.h>
-#include <unistd.h>
-
-#define cpu_to_le32(x) le32_to_cpu((x))
-unsigned long le32_to_cpu(unsigned long x)
-{
- return (((x & 0x000000ffU) << 24) |
- ((x & 0x0000ff00U) << 8) |
- ((x & 0x00ff0000U) >> 8) |
- ((x & 0xff000000U) >> 24));
-}
-
-
-#define cpu_to_le16(x) le16_to_cpu((x))
-unsigned short le16_to_cpu(unsigned short x)
-{
- return (((x & 0x00ff) << 8) |
- ((x & 0xff00) >> 8));
-}
-
-#define cpu_to_be32(x) (x)
-#define be32_to_cpu(x) (x)
-#define cpu_to_be16(x) (x)
-#define be16_to_cpu(x) (x)
+#include <stdlib.h>
/* size of read buffer */
#define SIZE 0x1000
-
-typedef unsigned long dword_t;
-typedef unsigned short word_t;
-typedef unsigned char byte_t;
-typedef byte_t block_t[512];
-typedef byte_t page_t[4096];
-
-
/*
* Partition table entry
* - from the PReP spec
*/
typedef struct partition_entry {
- byte_t boot_indicator;
- byte_t starting_head;
- byte_t starting_sector;
- byte_t starting_cylinder;
-
- byte_t system_indicator;
- byte_t ending_head;
- byte_t ending_sector;
- byte_t ending_cylinder;
-
- dword_t beginning_sector;
- dword_t number_of_sectors;
+ unsigned char boot_indicator;
+ unsigned char starting_head;
+ unsigned char starting_sector;
+ unsigned char starting_cylinder;
+
+ unsigned char system_indicator;
+ unsigned char ending_head;
+ unsigned char ending_sector;
+ unsigned char ending_cylinder;
+
+ unsigned char beginning_sector[4];
+ unsigned char number_of_sectors[4];
} partition_entry_t;
#define BootActive 0x80
#define SystemPrep 0x41
-void copy_image(int , int);
-void write_prep_partition(int , int );
-void write_asm_data( int in, int out );
+void copy_image(FILE *, FILE *);
+void write_prep_partition(FILE *, FILE *);
+void write_asm_data(FILE *, FILE *);
unsigned int elfhdr_size = 65536;
int main(int argc, char *argv[])
{
- int in_fd, out_fd;
- int argptr = 1;
- unsigned int prep = 0;
- unsigned int asmoutput = 0;
-
- if ( (argc < 3) || (argc > 4) )
- {
- fprintf(stderr, "usage: %s [-pbp] [-asm] <boot-file> <image>\n",argv[0]);
- exit(-1);
- }
-
- /* needs to handle args more elegantly -- but this is a small/simple program */
-
- /* check for -pbp */
- if ( !strcmp( argv[argptr], "-pbp" ) )
- {
- prep = 1;
- argptr++;
- }
-
- /* check for -asm */
- if ( !strcmp( argv[argptr], "-asm" ) )
- {
- asmoutput = 1;
- argptr++;
- }
-
- /* input file */
- if ( !strcmp( argv[argptr], "-" ) )
- in_fd = 0; /* stdin */
- else
- if ((in_fd = open( argv[argptr] , 0)) < 0)
- exit(-1);
- argptr++;
-
- /* output file */
- if ( !strcmp( argv[argptr], "-" ) )
- out_fd = 1; /* stdout */
- else
- if ((out_fd = creat( argv[argptr] , 0755)) < 0)
- exit(-1);
- argptr++;
-
- /* skip elf header in input file */
- /*if ( !prep )*/
- lseek(in_fd, elfhdr_size, SEEK_SET);
-
- /* write prep partition if necessary */
- if ( prep )
- write_prep_partition( in_fd, out_fd );
-
- /* write input image to bootimage */
- if ( asmoutput )
- write_asm_data( in_fd, out_fd );
- else
- copy_image(in_fd, out_fd);
-
- return 0;
+ FILE *in, *out;
+ int argptr = 1;
+ int prep = 0;
+ int asmoutput = 0;
+
+ if (argc < 3 || argc > 4) {
+ fprintf(stderr, "usage: %s [-pbp] [-asm] <boot-file> <image>\n",
+ argv[0]);
+ exit(-1);
+ }
+
+/* needs to handle args more elegantly -- but this is a small/simple program */
+
+ /* check for -pbp */
+ if (!strcmp(argv[argptr], "-pbp")) {
+ prep = 1;
+ argptr++;
+ }
+
+ /* check for -asm */
+ if (!strcmp(argv[argptr], "-asm")) {
+ asmoutput = 1;
+ argptr++;
+ }
+
+ /* input file */
+ if (!strcmp(argv[argptr], "-"))
+ in = stdin;
+ else if (!(in = fopen(argv[argptr], "r")))
+ exit(-1);
+ argptr++;
+
+ /* output file */
+ if (!strcmp(argv[argptr], "-"))
+ out = stdout;
+ else if (!(out = fopen(argv[argptr], "w")))
+ exit(-1);
+ argptr++;
+
+ /* skip elf header in input file */
+ /*if ( !prep )*/
+ fseek(in, elfhdr_size, SEEK_SET);
+
+ /* write prep partition if necessary */
+ if (prep)
+ write_prep_partition(in, out);
+
+ /* write input image to bootimage */
+ if (asmoutput)
+ write_asm_data(in, out);
+ else
+ copy_image(in, out);
+
+ return 0;
}
-void write_prep_partition(int in, int out)
+void store_le32(unsigned int v, unsigned char *p)
{
- unsigned char block[512];
- partition_entry_t pe;
- dword_t *entry = (dword_t *)&block[0];
- dword_t *length = (dword_t *)&block[sizeof(long)];
- struct stat info;
-
- if (fstat(in, &info) < 0)
- {
- fprintf(stderr,"info failed\n");
- exit(-1);
- }
-
- bzero( block, sizeof block );
-
- /* set entry point and boot image size skipping over elf header */
-#ifdef __i386__
- *entry = 0x400/*+65536*/;
- *length = info.st_size-elfhdr_size+0x400;
-#else
- *entry = cpu_to_le32(0x400/*+65536*/);
- *length = cpu_to_le32(info.st_size-elfhdr_size+0x400);
-#endif /* __i386__ */
-
- /* sets magic number for msdos partition (used by linux) */
- block[510] = 0x55;
- block[511] = 0xAA;
-
- /*
- * Build a "PReP" partition table entry in the boot record
- * - "PReP" may only look at the system_indicator
- */
- pe.boot_indicator = BootActive;
- pe.system_indicator = SystemPrep;
- /*
- * The first block of the diskette is used by this "boot record" which
- * actually contains the partition table. (The first block of the
- * partition contains the boot image, but I digress...) We'll set up
- * one partition on the diskette and it shall contain the rest of the
- * diskette.
- */
- pe.starting_head = 0; /* zero-based */
- pe.starting_sector = 2; /* one-based */
- pe.starting_cylinder = 0; /* zero-based */
- pe.ending_head = 1; /* assumes two heads */
- pe.ending_sector = 18; /* assumes 18 sectors/track */
- pe.ending_cylinder = 79; /* assumes 80 cylinders/diskette */
-
- /*
- * The "PReP" software ignores the above fields and just looks at
- * the next two.
- * - size of the diskette is (assumed to be)
- * (2 tracks/cylinder)(18 sectors/tracks)(80 cylinders/diskette)
- * - unlike the above sector numbers, the beginning sector is zero-based!
- */
+ p[0] = v;
+ p[1] = v >>= 8;
+ p[2] = v >>= 8;
+ p[3] = v >> 8;
+}
+
+void write_prep_partition(FILE *in, FILE *out)
+{
+ unsigned char block[512];
+ partition_entry_t pe;
+ unsigned char *entry = block;
+ unsigned char *length = block + 4;
+ long pos = ftell(in), size;
+
+ if (fseek(in, 0, SEEK_END) < 0) {
+ fprintf(stderr,"info failed\n");
+ exit(-1);
+ }
+ size = ftell(in);
+ if (fseek(in, pos, SEEK_SET) < 0) {
+ fprintf(stderr,"info failed\n");
+ exit(-1);
+ }
+
+ memset(block, '\0', sizeof(block));
+
+ /* set entry point and boot image size skipping over elf header */
+ store_le32(0x400/*+65536*/, entry);
+ store_le32(size-elfhdr_size+0x400, length);
+
+ /* sets magic number for msdos partition (used by linux) */
+ block[510] = 0x55;
+ block[511] = 0xAA;
+
+ /*
+ * Build a "PReP" partition table entry in the boot record
+ * - "PReP" may only look at the system_indicator
+ */
+ pe.boot_indicator = BootActive;
+ pe.system_indicator = SystemPrep;
+ /*
+ * The first block of the diskette is used by this "boot record" which
+ * actually contains the partition table. (The first block of the
+ * partition contains the boot image, but I digress...) We'll set up
+ * one partition on the diskette and it shall contain the rest of the
+ * diskette.
+ */
+ pe.starting_head = 0; /* zero-based */
+ pe.starting_sector = 2; /* one-based */
+ pe.starting_cylinder = 0; /* zero-based */
+ pe.ending_head = 1; /* assumes two heads */
+ pe.ending_sector = 18; /* assumes 18 sectors/track */
+ pe.ending_cylinder = 79; /* assumes 80 cylinders/diskette */
+
+ /*
+ * The "PReP" software ignores the above fields and just looks at
+ * the next two.
+ * - size of the diskette is (assumed to be)
+ * (2 tracks/cylinder)(18 sectors/tracks)(80 cylinders/diskette)
+ * - unlike the above sector numbers, the beginning sector is zero-based!
+ */
#if 0
- pe.beginning_sector = cpu_to_le32(1);
-#else
- /* This has to be 0 on the PowerStack? */
-#ifdef __i386__
- pe.beginning_sector = 0;
+ store_le32(1, pe.beginning_sector);
#else
- pe.beginning_sector = cpu_to_le32(0);
-#endif /* __i386__ */
+ /* This has to be 0 on the PowerStack? */
+ store_le32(0, pe.beginning_sector);
#endif
-#ifdef __i386__
- pe.number_of_sectors = 2*18*80-1;
-#else
- pe.number_of_sectors = cpu_to_le32(2*18*80-1);
-#endif /* __i386__ */
+ store_le32(2*18*80-1, pe.number_of_sectors);
- memcpy(&block[0x1BE], &pe, sizeof(pe));
+ memcpy(&block[0x1BE], &pe, sizeof(pe));
- write( out, block, sizeof(block) );
- write( out, entry, sizeof(*entry) );
- write( out, length, sizeof(*length) );
- /* set file position to 2nd sector where image will be written */
- lseek( out, 0x400, SEEK_SET );
+ fwrite(block, sizeof(block), 1, out);
+ fwrite(entry, 4, 1, out);
+ fwrite(length, 4, 1, out);
+ /* set file position to 2nd sector where image will be written */
+ fseek( out, 0x400, SEEK_SET );
}
-void
-copy_image(int in, int out)
+void copy_image(FILE *in, FILE *out)
{
- char buf[SIZE];
- int n;
+ char buf[SIZE];
+ int n;
- while ( (n = read(in, buf, SIZE)) > 0 )
- write(out, buf, n);
+ while ( (n = fread(buf, 1, SIZE, in)) > 0 )
+ fwrite(buf, 1, n, out);
}
void
-write_asm_data( int in, int out )
+write_asm_data(FILE *in, FILE *out)
{
- int i, cnt, pos, len;
- unsigned int cksum, val;
- unsigned char *lp;
- unsigned char buf[SIZE];
- unsigned char str[256];
-
- write( out, "\t.data\n\t.globl input_data\ninput_data:\n",
- strlen( "\t.data\n\t.globl input_data\ninput_data:\n" ) );
- pos = 0;
- cksum = 0;
- while ((len = read(in, buf, sizeof(buf))) > 0)
- {
- cnt = 0;
- lp = (unsigned char *)buf;
- len = (len + 3) & ~3; /* Round up to longwords */
- for (i = 0; i < len; i += 4)
- {
- if (cnt == 0)
- {
- write( out, "\t.long\t", strlen( "\t.long\t" ) );
- }
- sprintf( str, "0x%02X%02X%02X%02X", lp[0], lp[1], lp[2], lp[3]);
- write( out, str, strlen(str) );
- val = *(unsigned long *)lp;
- cksum ^= val;
- lp += 4;
- if (++cnt == 4)
- {
- cnt = 0;
- sprintf( str, " # %x \n", pos+i-12);
- write( out, str, strlen(str) );
- } else
- {
- write( out, ",", 1 );
- }
- }
- if (cnt)
- {
- write( out, "0\n", 2 );
- }
- pos += len;
- }
- sprintf(str, "\t.globl input_len\ninput_len:\t.long\t0x%x\n", pos);
- write( out, str, strlen(str) );
-
- fprintf(stderr, "cksum = %x\n", cksum);
+ int i, cnt, pos = 0;
+ unsigned int cksum = 0, val;
+ unsigned char *lp;
+ unsigned char buf[SIZE];
+ size_t len;
+
+ fputs("\t.data\n\t.globl input_data\ninput_data:\n", out);
+ while ((len = fread(buf, 1, sizeof(buf), in)) > 0) {
+ cnt = 0;
+ lp = buf;
+ /* Round up to longwords */
+ while (len & 3)
+ buf[len++] = '\0';
+ for (i = 0; i < len; i += 4) {
+ if (cnt == 0)
+ fputs("\t.long\t", out);
+ fprintf(out, "0x%02X%02X%02X%02X",
+ lp[0], lp[1], lp[2], lp[3]);
+ val = *(unsigned long *)lp;
+ cksum ^= val;
+ lp += 4;
+ if (++cnt == 4) {
+ cnt = 0;
+ fprintf(out, " # %x \n", pos+i-12);
+ } else {
+ fputs(",", out);
+ }
+ }
+ if (cnt)
+ fputs("0\n", out);
+ pos += len;
+ }
+ fprintf(out, "\t.globl input_len\ninput_len:\t.long\t0x%x\n", pos);
+ fprintf(stderr, "cksum = %x\n", cksum);
}
diff --git a/arch/ppc/kernel/misc.S b/arch/ppc/kernel/misc.S
index 50b4bbd06804..5f6684012ded 100644
--- a/arch/ppc/kernel/misc.S
+++ b/arch/ppc/kernel/misc.S
@@ -942,20 +942,16 @@ _GLOBAL(kernel_thread)
addi r1,r1,16
blr
+_GLOBAL(kernel_execve)
+ li r0,__NR_execve
+ sc
+ bnslr
+ neg r3,r3
+ blr
+
/*
* This routine is just here to keep GCC happy - sigh...
*/
_GLOBAL(__main)
blr
-#define SYSCALL(name) \
-_GLOBAL(name) \
- li r0,__NR_##name; \
- sc; \
- bnslr; \
- lis r4,errno@ha; \
- stw r3,errno@l(r4); \
- li r3,-1; \
- blr
-
-SYSCALL(execve)
diff --git a/arch/ppc/kernel/setup.c b/arch/ppc/kernel/setup.c
index 5458ac5da7c3..75fe13815be2 100644
--- a/arch/ppc/kernel/setup.c
+++ b/arch/ppc/kernel/setup.c
@@ -86,10 +86,6 @@ int ppc_do_canonicalize_irqs;
EXPORT_SYMBOL(ppc_do_canonicalize_irqs);
#endif
-#ifdef CONFIG_MAGIC_SYSRQ
-unsigned long SYSRQ_KEY = 0x54;
-#endif /* CONFIG_MAGIC_SYSRQ */
-
#ifdef CONFIG_VGA_CONSOLE
unsigned long vgacon_remap_base;
#endif
diff --git a/arch/ppc/kernel/time.c b/arch/ppc/kernel/time.c
index 6ab8cc7226ab..187388625a76 100644
--- a/arch/ppc/kernel/time.c
+++ b/arch/ppc/kernel/time.c
@@ -80,8 +80,6 @@ unsigned tb_to_us;
unsigned tb_last_stamp;
unsigned long tb_to_ns_scale;
-extern unsigned long wall_jiffies;
-
/* used for timezone offset */
static long timezone_offset;
@@ -153,7 +151,7 @@ void timer_interrupt(struct pt_regs * regs)
/* We are in an interrupt, no need to save/restore flags */
write_seqlock(&xtime_lock);
tb_last_stamp = jiffy_stamp;
- do_timer(regs);
+ do_timer(1);
/*
* update the rtc when needed, this should be performed on the
@@ -173,8 +171,7 @@ void timer_interrupt(struct pt_regs * regs)
*/
if ( ppc_md.set_rtc_time && ntp_synced() &&
xtime.tv_sec - last_rtc_update >= 659 &&
- abs((xtime.tv_nsec / 1000) - (1000000-1000000/HZ)) < 500000/HZ &&
- jiffies - wall_jiffies == 1) {
+ abs((xtime.tv_nsec / 1000) - (1000000-1000000/HZ)) < 500000/HZ) {
if (ppc_md.set_rtc_time(xtime.tv_sec+1 + timezone_offset) == 0)
last_rtc_update = xtime.tv_sec+1;
else
@@ -200,7 +197,7 @@ void do_gettimeofday(struct timeval *tv)
{
unsigned long flags;
unsigned long seq;
- unsigned delta, lost_ticks, usec, sec;
+ unsigned delta, usec, sec;
do {
seq = read_seqbegin_irqsave(&xtime_lock, flags);
@@ -214,10 +211,9 @@ void do_gettimeofday(struct timeval *tv)
if (!smp_tb_synchronized)
delta = 0;
#endif /* CONFIG_SMP */
- lost_ticks = jiffies - wall_jiffies;
} while (read_seqretry_irqrestore(&xtime_lock, seq, flags));
- usec += mulhwu(tb_to_us, tb_ticks_per_jiffy * lost_ticks + delta);
+ usec += mulhwu(tb_to_us, delta);
while (usec >= 1000000) {
sec++;
usec -= 1000000;
@@ -258,7 +254,6 @@ int do_settimeofday(struct timespec *tv)
* still reasonable when gettimeofday resolution is 1 jiffy.
*/
tb_delta = tb_ticks_since(last_jiffy_stamp(smp_processor_id()));
- tb_delta += (jiffies - wall_jiffies) * tb_ticks_per_jiffy;
new_nsec -= 1000 * mulhwu(tb_to_us, tb_delta);
diff --git a/arch/ppc/kernel/traps.c b/arch/ppc/kernel/traps.c
index d7a433049b48..aafc8e8893d1 100644
--- a/arch/ppc/kernel/traps.c
+++ b/arch/ppc/kernel/traps.c
@@ -119,7 +119,7 @@ void _exception(int signr, struct pt_regs *regs, int code, unsigned long addr)
* generate the same exception over and over again and we get
* nowhere. Better to kill it and let the kernel panic.
*/
- if (current->pid == 1) {
+ if (is_init(current)) {
__sighandler_t handler;
spin_lock_irq(&current->sighand->siglock);
diff --git a/arch/ppc/mm/fault.c b/arch/ppc/mm/fault.c
index 5cdfb71fcb07..465f451f3bc3 100644
--- a/arch/ppc/mm/fault.c
+++ b/arch/ppc/mm/fault.c
@@ -239,7 +239,7 @@ good_area:
/* protection fault */
if (error_code & 0x08000000)
goto bad_area;
- if (!(vma->vm_flags & (VM_READ | VM_EXEC)))
+ if (!(vma->vm_flags & (VM_READ | VM_EXEC | VM_WRITE)))
goto bad_area;
}
@@ -291,7 +291,7 @@ bad_area:
*/
out_of_memory:
up_read(&mm->mmap_sem);
- if (current->pid == 1) {
+ if (is_init(current)) {
yield();
down_read(&mm->mmap_sem);
goto survive;
diff --git a/arch/ppc/platforms/mpc8272ads_setup.c b/arch/ppc/platforms/mpc8272ads_setup.c
index 2a35fe2b9b96..d5d36c372c8e 100644
--- a/arch/ppc/platforms/mpc8272ads_setup.c
+++ b/arch/ppc/platforms/mpc8272ads_setup.c
@@ -103,7 +103,7 @@ static struct fs_platform_info mpc82xx_enet_pdata[] = {
},
};
-static void init_fcc1_ioports(void)
+static void init_fcc1_ioports(struct fs_platform_info*)
{
struct io_port *io;
u32 tempval;
@@ -144,7 +144,7 @@ static void init_fcc1_ioports(void)
iounmap(immap);
}
-static void init_fcc2_ioports(void)
+static void init_fcc2_ioports(struct fs_platform_info*)
{
cpm2_map_t* immap = ioremap(CPM_MAP_ADDR, sizeof(cpm2_map_t));
u32 *bcsr = ioremap(BCSR_ADDR+12, sizeof(u32));
@@ -229,7 +229,7 @@ static void mpc8272ads_fixup_uart_pdata(struct platform_device *pdev,
}
}
-static void init_scc1_uart_ioports(void)
+static void init_scc1_uart_ioports(struct fs_uart_platform_info*)
{
cpm2_map_t* immap = ioremap(CPM_MAP_ADDR, sizeof(cpm2_map_t));
@@ -246,7 +246,7 @@ static void init_scc1_uart_ioports(void)
iounmap(immap);
}
-static void init_scc4_uart_ioports(void)
+static void init_scc4_uart_ioports(struct fs_uart_platform_info*)
{
cpm2_map_t* immap = ioremap(CPM_MAP_ADDR, sizeof(cpm2_map_t));
diff --git a/arch/ppc/platforms/mpc866ads_setup.c b/arch/ppc/platforms/mpc866ads_setup.c
index e12cece4c9fd..5f130dca3770 100644
--- a/arch/ppc/platforms/mpc866ads_setup.c
+++ b/arch/ppc/platforms/mpc866ads_setup.c
@@ -137,7 +137,7 @@ void __init board_init(void)
iounmap(bcsr_io);
}
-static void setup_fec1_ioports(void)
+static void setup_fec1_ioports(struct fs_platform_info*)
{
immap_t *immap = (immap_t *) IMAP_ADDR;
@@ -145,7 +145,7 @@ static void setup_fec1_ioports(void)
setbits16(&immap->im_ioport.iop_pddir, 0x1fff);
}
-static void setup_scc1_ioports(void)
+static void setup_scc1_ioports(struct fs_platform_info*)
{
immap_t *immap = (immap_t *) IMAP_ADDR;
unsigned *bcsr_io;
@@ -194,7 +194,7 @@ static void setup_scc1_ioports(void)
}
-static void setup_smc1_ioports(void)
+static void setup_smc1_ioports(struct fs_uart_platform_info*)
{
immap_t *immap = (immap_t *) IMAP_ADDR;
unsigned *bcsr_io;
@@ -216,7 +216,7 @@ static void setup_smc1_ioports(void)
}
-static void setup_smc2_ioports(void)
+static void setup_smc2_ioports(struct fs_uart_platform_info*)
{
immap_t *immap = (immap_t *) IMAP_ADDR;
unsigned *bcsr_io;
diff --git a/arch/ppc/platforms/mpc885ads_setup.c b/arch/ppc/platforms/mpc885ads_setup.c
index 5dfa4e6c2af0..bf388ed04d46 100644
--- a/arch/ppc/platforms/mpc885ads_setup.c
+++ b/arch/ppc/platforms/mpc885ads_setup.c
@@ -161,7 +161,7 @@ void __init board_init(void)
#endif
}
-static void setup_fec1_ioports(void)
+static void setup_fec1_ioports(struct fs_platform_info*)
{
immap_t *immap = (immap_t *) IMAP_ADDR;
@@ -181,7 +181,7 @@ static void setup_fec1_ioports(void)
clrbits32(&immap->im_cpm.cp_cptr, 0x00000100);
}
-static void setup_fec2_ioports(void)
+static void setup_fec2_ioports(struct fs_platform_info*)
{
immap_t *immap = (immap_t *) IMAP_ADDR;
@@ -193,7 +193,7 @@ static void setup_fec2_ioports(void)
clrbits32(&immap->im_cpm.cp_cptr, 0x00000080);
}
-static void setup_scc3_ioports(void)
+static void setup_scc3_ioports(struct fs_platform_info*)
{
immap_t *immap = (immap_t *) IMAP_ADDR;
unsigned *bcsr_io;
@@ -315,7 +315,7 @@ static void __init mpc885ads_fixup_scc_enet_pdata(struct platform_device *pdev,
mpc885ads_fixup_enet_pdata(pdev, fsid_scc1 + pdev->id - 1);
}
-static void setup_smc1_ioports(void)
+static void setup_smc1_ioports(struct fs_uart_platform_info*)
{
immap_t *immap = (immap_t *) IMAP_ADDR;
unsigned *bcsr_io;
@@ -335,7 +335,7 @@ static void setup_smc1_ioports(void)
clrbits16(&immap->im_cpm.cp_pbodr, iobits);
}
-static void setup_smc2_ioports(void)
+static void setup_smc2_ioports(struct fs_uart_platform_info*)
{
immap_t *immap = (immap_t *) IMAP_ADDR;
unsigned *bcsr_io;
diff --git a/arch/s390/appldata/appldata_base.c b/arch/s390/appldata/appldata_base.c
index 9a8f6ff21652..2b1e6c9a6e0e 100644
--- a/arch/s390/appldata/appldata_base.c
+++ b/arch/s390/appldata/appldata_base.c
@@ -16,7 +16,7 @@
#include <linux/errno.h>
#include <linux/interrupt.h>
#include <linux/proc_fs.h>
-#include <linux/page-flags.h>
+#include <linux/mm.h>
#include <linux/swap.h>
#include <linux/pagemap.h>
#include <linux/sysctl.h>
diff --git a/arch/s390/hypfs/inode.c b/arch/s390/hypfs/inode.c
index 813fc21358f9..cd702ae45d6d 100644
--- a/arch/s390/hypfs/inode.c
+++ b/arch/s390/hypfs/inode.c
@@ -134,12 +134,20 @@ static int hypfs_open(struct inode *inode, struct file *filp)
return 0;
}
-static ssize_t hypfs_aio_read(struct kiocb *iocb, __user char *buf,
- size_t count, loff_t offset)
+static ssize_t hypfs_aio_read(struct kiocb *iocb, const struct iovec *iov,
+ unsigned long nr_segs, loff_t offset)
{
char *data;
size_t len;
struct file *filp = iocb->ki_filp;
+ /* XXX: temporary */
+ char __user *buf = iov[0].iov_base;
+ size_t count = iov[0].iov_len;
+
+ if (nr_segs != 1) {
+ count = -EINVAL;
+ goto out;
+ }
data = filp->private_data;
len = strlen(data);
@@ -158,12 +166,13 @@ static ssize_t hypfs_aio_read(struct kiocb *iocb, __user char *buf,
out:
return count;
}
-static ssize_t hypfs_aio_write(struct kiocb *iocb, const char __user *buf,
- size_t count, loff_t pos)
+static ssize_t hypfs_aio_write(struct kiocb *iocb, const struct iovec *iov,
+ unsigned long nr_segs, loff_t offset)
{
int rc;
struct super_block *sb;
struct hypfs_sb_info *fs_info;
+ size_t count = iov_length(iov, nr_segs);
sb = iocb->ki_filp->f_dentry->d_inode->i_sb;
fs_info = sb->s_fs_info;
diff --git a/arch/s390/kernel/compat_linux.c b/arch/s390/kernel/compat_linux.c
index c46e3d48e410..e15e1489aef5 100644
--- a/arch/s390/kernel/compat_linux.c
+++ b/arch/s390/kernel/compat_linux.c
@@ -357,11 +357,16 @@ asmlinkage long sys32_ftruncate64(unsigned int fd, unsigned long high, unsigned
int cp_compat_stat(struct kstat *stat, struct compat_stat __user *statbuf)
{
+ compat_ino_t ino;
int err;
if (!old_valid_dev(stat->dev) || !old_valid_dev(stat->rdev))
return -EOVERFLOW;
+ ino = stat->ino;
+ if (sizeof(ino) < sizeof(stat->ino) && ino != stat->ino)
+ return -EOVERFLOW;
+
err = put_user(old_encode_dev(stat->dev), &statbuf->st_dev);
err |= put_user(stat->ino, &statbuf->st_ino);
err |= put_user(stat->mode, &statbuf->st_mode);
diff --git a/arch/s390/kernel/head31.S b/arch/s390/kernel/head31.S
index 1fa9fa1ca740..1b952a3664e2 100644
--- a/arch/s390/kernel/head31.S
+++ b/arch/s390/kernel/head31.S
@@ -254,6 +254,16 @@ startup_continue:
oi 3(%r12),0x80 # set IDTE flag
.Lchkidte:
+#
+# find out if the diag 0x9c is available
+#
+ mvc __LC_PGM_NEW_PSW(8),.Lpcdiag9c-.LPG1(%r13)
+ stap __LC_CPUID+4 # store cpu address
+ lh %r1,__LC_CPUID+4
+ diag %r1,0,0x9c # test diag 0x9c
+ oi 2(%r12),1 # set diag9c flag
+.Lchkdiag9c:
+
lpsw .Lentry-.LPG1(13) # jump to _stext in primary-space,
# virtual and never return ...
.align 8
@@ -281,6 +291,7 @@ startup_continue:
.Lpccsp:.long 0x00080000,0x80000000 + .Lchkcsp
.Lpcmvpg:.long 0x00080000,0x80000000 + .Lchkmvpg
.Lpcidte:.long 0x00080000,0x80000000 + .Lchkidte
+.Lpcdiag9c:.long 0x00080000,0x80000000 + .Lchkdiag9c
.Lmemsize:.long memory_size
.Lmchunk:.long memory_chunk
.Lmflags:.long machine_flags
diff --git a/arch/s390/kernel/head64.S b/arch/s390/kernel/head64.S
index 48998d50b00a..b30e5897cdf7 100644
--- a/arch/s390/kernel/head64.S
+++ b/arch/s390/kernel/head64.S
@@ -251,6 +251,17 @@ startup_continue:
0:
#
+# find out if the diag 0x9c is available
+#
+ la %r1,0f-.LPG1(%r13) # set program check address
+ stg %r1,__LC_PGM_NEW_PSW+8
+ stap __LC_CPUID+4 # store cpu address
+ lh %r1,__LC_CPUID+4
+ diag %r1,0,0x9c # test diag 0x9c
+ oi 6(%r12),1 # set diag9c flag
+0:
+
+#
# find out if we have the MVCOS instruction
#
la %r1,0f-.LPG1(%r13) # set program check address
diff --git a/arch/s390/kernel/kprobes.c b/arch/s390/kernel/kprobes.c
index ca28fb0b3790..4d9ff5ce4cbd 100644
--- a/arch/s390/kernel/kprobes.c
+++ b/arch/s390/kernel/kprobes.c
@@ -369,11 +369,12 @@ void __kprobes kretprobe_trampoline_holder(void)
int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs)
{
struct kretprobe_instance *ri = NULL;
- struct hlist_head *head;
+ struct hlist_head *head, empty_rp;
struct hlist_node *node, *tmp;
unsigned long flags, orig_ret_address = 0;
unsigned long trampoline_address = (unsigned long)&kretprobe_trampoline;
+ INIT_HLIST_HEAD(&empty_rp);
spin_lock_irqsave(&kretprobe_lock, flags);
head = kretprobe_inst_table_head(current);
@@ -399,7 +400,7 @@ int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs)
ri->rp->handler(ri, regs);
orig_ret_address = (unsigned long)ri->ret_addr;
- recycle_rp_inst(ri);
+ recycle_rp_inst(ri, &empty_rp);
if (orig_ret_address != trampoline_address) {
/*
@@ -417,6 +418,10 @@ int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs)
spin_unlock_irqrestore(&kretprobe_lock, flags);
preempt_enable_no_resched();
+ hlist_for_each_entry_safe(ri, node, tmp, &empty_rp, hlist) {
+ hlist_del(&ri->hlist);
+ kfree(ri);
+ }
/*
* By returning a non-zero value, we are telling
* kprobe_handler() that we don't want the post_handler
diff --git a/arch/s390/kernel/sys_s390.c b/arch/s390/kernel/sys_s390.c
index e351780bb660..584ed95f3380 100644
--- a/arch/s390/kernel/sys_s390.c
+++ b/arch/s390/kernel/sys_s390.c
@@ -27,6 +27,7 @@
#include <linux/file.h>
#include <linux/utsname.h>
#include <linux/personality.h>
+#include <linux/unistd.h>
#include <asm/uaccess.h>
#include <asm/ipc.h>
@@ -266,3 +267,22 @@ s390_fadvise64_64(struct fadvise64_64_args __user *args)
return sys_fadvise64_64(a.fd, a.offset, a.len, a.advice);
}
+/*
+ * Do a system call from kernel instead of calling sys_execve so we
+ * end up with proper pt_regs.
+ */
+int kernel_execve(const char *filename, char *const argv[], char *const envp[])
+{
+ register const char *__arg1 asm("2") = filename;
+ register char *const*__arg2 asm("3") = argv;
+ register char *const*__arg3 asm("4") = envp;
+ register long __svcres asm("2");
+ asm volatile(
+ "svc %b1"
+ : "=d" (__svcres)
+ : "i" (__NR_execve),
+ "0" (__arg1),
+ "d" (__arg2),
+ "d" (__arg3) : "memory");
+ return __svcres;
+}
diff --git a/arch/s390/kernel/time.c b/arch/s390/kernel/time.c
index 1981c6199fa2..4bf66cc4a267 100644
--- a/arch/s390/kernel/time.c
+++ b/arch/s390/kernel/time.c
@@ -53,8 +53,6 @@ static u64 init_timer_cc;
static u64 jiffies_timer_cc;
static u64 xtime_cc;
-extern unsigned long wall_jiffies;
-
/*
* Scheduler clock - returns current time in nanosec units.
*/
@@ -87,9 +85,8 @@ static inline unsigned long do_gettimeoffset(void)
{
__u64 now;
- now = (get_clock() - jiffies_timer_cc) >> 12;
- /* We require the offset from the latest update of xtime */
- now -= (__u64) wall_jiffies*USECS_PER_JIFFY;
+ now = (get_clock() - jiffies_timer_cc) >> 12;
+ now -= (__u64) jiffies * USECS_PER_JIFFY;
return (unsigned long) now;
}
@@ -166,7 +163,7 @@ EXPORT_SYMBOL(do_settimeofday);
void account_ticks(struct pt_regs *regs)
{
__u64 tmp;
- __u32 ticks, xticks;
+ __u32 ticks;
/* Calculate how many ticks have passed. */
if (S390_lowcore.int_clock < S390_lowcore.jiffy_timer) {
@@ -204,6 +201,7 @@ void account_ticks(struct pt_regs *regs)
*/
write_seqlock(&xtime_lock);
if (S390_lowcore.jiffy_timer > xtime_cc) {
+ __u32 xticks;
tmp = S390_lowcore.jiffy_timer - xtime_cc;
if (tmp >= 2*CLK_TICKS_PER_JIFFY) {
xticks = __div(tmp, CLK_TICKS_PER_JIFFY);
@@ -212,13 +210,11 @@ void account_ticks(struct pt_regs *regs)
xticks = 1;
xtime_cc += CLK_TICKS_PER_JIFFY;
}
- while (xticks--)
- do_timer(regs);
+ do_timer(xticks);
}
write_sequnlock(&xtime_lock);
#else
- for (xticks = ticks; xticks > 0; xticks--)
- do_timer(regs);
+ do_timer(ticks);
#endif
#ifdef CONFIG_VIRT_CPU_ACCOUNTING
diff --git a/arch/s390/lib/spinlock.c b/arch/s390/lib/spinlock.c
index b9b7958a226a..8d76403fcf89 100644
--- a/arch/s390/lib/spinlock.c
+++ b/arch/s390/lib/spinlock.c
@@ -24,57 +24,76 @@ static int __init spin_retry_setup(char *str)
}
__setup("spin_retry=", spin_retry_setup);
-static inline void
-_diag44(void)
+static inline void _raw_yield(void)
{
-#ifdef CONFIG_64BIT
if (MACHINE_HAS_DIAG44)
-#endif
asm volatile("diag 0,0,0x44");
}
-void
-_raw_spin_lock_wait(raw_spinlock_t *lp, unsigned int pc)
+static inline void _raw_yield_cpu(int cpu)
+{
+ if (MACHINE_HAS_DIAG9C)
+ asm volatile("diag %0,0,0x9c"
+ : : "d" (__cpu_logical_map[cpu]));
+ else
+ _raw_yield();
+}
+
+void _raw_spin_lock_wait(raw_spinlock_t *lp, unsigned int pc)
{
int count = spin_retry;
+ unsigned int cpu = ~smp_processor_id();
while (1) {
if (count-- <= 0) {
- _diag44();
+ unsigned int owner = lp->owner_cpu;
+ if (owner != 0)
+ _raw_yield_cpu(~owner);
count = spin_retry;
}
if (__raw_spin_is_locked(lp))
continue;
- if (_raw_compare_and_swap(&lp->lock, 0, pc) == 0)
+ if (_raw_compare_and_swap(&lp->owner_cpu, 0, cpu) == 0) {
+ lp->owner_pc = pc;
return;
+ }
}
}
EXPORT_SYMBOL(_raw_spin_lock_wait);
-int
-_raw_spin_trylock_retry(raw_spinlock_t *lp, unsigned int pc)
+int _raw_spin_trylock_retry(raw_spinlock_t *lp, unsigned int pc)
{
- int count = spin_retry;
+ unsigned int cpu = ~smp_processor_id();
+ int count;
- while (count-- > 0) {
+ for (count = spin_retry; count > 0; count--) {
if (__raw_spin_is_locked(lp))
continue;
- if (_raw_compare_and_swap(&lp->lock, 0, pc) == 0)
+ if (_raw_compare_and_swap(&lp->owner_cpu, 0, cpu) == 0) {
+ lp->owner_pc = pc;
return 1;
+ }
}
return 0;
}
EXPORT_SYMBOL(_raw_spin_trylock_retry);
-void
-_raw_read_lock_wait(raw_rwlock_t *rw)
+void _raw_spin_relax(raw_spinlock_t *lock)
+{
+ unsigned int cpu = lock->owner_cpu;
+ if (cpu != 0)
+ _raw_yield_cpu(~cpu);
+}
+EXPORT_SYMBOL(_raw_spin_relax);
+
+void _raw_read_lock_wait(raw_rwlock_t *rw)
{
unsigned int old;
int count = spin_retry;
while (1) {
if (count-- <= 0) {
- _diag44();
+ _raw_yield();
count = spin_retry;
}
if (!__raw_read_can_lock(rw))
@@ -86,8 +105,7 @@ _raw_read_lock_wait(raw_rwlock_t *rw)
}
EXPORT_SYMBOL(_raw_read_lock_wait);
-int
-_raw_read_trylock_retry(raw_rwlock_t *rw)
+int _raw_read_trylock_retry(raw_rwlock_t *rw)
{
unsigned int old;
int count = spin_retry;
@@ -103,14 +121,13 @@ _raw_read_trylock_retry(raw_rwlock_t *rw)
}
EXPORT_SYMBOL(_raw_read_trylock_retry);
-void
-_raw_write_lock_wait(raw_rwlock_t *rw)
+void _raw_write_lock_wait(raw_rwlock_t *rw)
{
int count = spin_retry;
while (1) {
if (count-- <= 0) {
- _diag44();
+ _raw_yield();
count = spin_retry;
}
if (!__raw_write_can_lock(rw))
@@ -121,8 +138,7 @@ _raw_write_lock_wait(raw_rwlock_t *rw)
}
EXPORT_SYMBOL(_raw_write_lock_wait);
-int
-_raw_write_trylock_retry(raw_rwlock_t *rw)
+int _raw_write_trylock_retry(raw_rwlock_t *rw)
{
int count = spin_retry;
diff --git a/arch/s390/mm/fault.c b/arch/s390/mm/fault.c
index f2b9a84dc2bf..9c3c19fe62fc 100644
--- a/arch/s390/mm/fault.c
+++ b/arch/s390/mm/fault.c
@@ -353,7 +353,7 @@ no_context:
*/
out_of_memory:
up_read(&mm->mmap_sem);
- if (tsk->pid == 1) {
+ if (is_init(tsk)) {
yield();
down_read(&mm->mmap_sem);
goto survive;
diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig
index 1cc5c9b27bfd..f6a0c4436168 100644
--- a/arch/sh/Kconfig
+++ b/arch/sh/Kconfig
@@ -377,7 +377,7 @@ config SH_PCLK_FREQ
default "50000000" if CPU_SUBTYPE_SH7750 || CPU_SUBTYPE_SH7780
default "60000000" if CPU_SUBTYPE_SH7751
default "33333333" if CPU_SUBTYPE_SH7300 || CPU_SUBTYPE_SH7770 || \
- CPU_SUBTYPE_SH7760
+ CPU_SUBTYPE_SH7760 || CPU_SUBTYPE_SH7705
default "27000000" if CPU_SUBTYPE_SH73180 || CPU_SUBTYPE_SH7343
default "66000000" if CPU_SUBTYPE_SH4_202
help
diff --git a/arch/sh/boards/hp6xx/hp6xx_apm.c b/arch/sh/boards/hp6xx/hp6xx_apm.c
index ad0e712c29f6..75f91aaae077 100644
--- a/arch/sh/boards/hp6xx/hp6xx_apm.c
+++ b/arch/sh/boards/hp6xx/hp6xx_apm.c
@@ -6,7 +6,6 @@
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License.
*/
-#include <linux/config.h>
#include <linux/module.h>
#include <linux/apm_bios.h>
#include <linux/kernel.h>
diff --git a/arch/sh/boards/hp6xx/pm.c b/arch/sh/boards/hp6xx/pm.c
index 0e501bcbd7a9..83d327212064 100644
--- a/arch/sh/boards/hp6xx/pm.c
+++ b/arch/sh/boards/hp6xx/pm.c
@@ -6,7 +6,6 @@
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License.
*/
-#include <linux/config.h>
#include <linux/init.h>
#include <linux/suspend.h>
#include <linux/errno.h>
diff --git a/arch/sh/boards/landisk/irq.c b/arch/sh/boards/landisk/irq.c
index a006d6443225..8f2e1c68b90f 100644
--- a/arch/sh/boards/landisk/irq.c
+++ b/arch/sh/boards/landisk/irq.c
@@ -14,8 +14,6 @@
* modified by kogiidena
* 2005.03.03
*/
-
-#include <linux/config.h>
#include <linux/init.h>
#include <linux/irq.h>
#include <asm/io.h>
@@ -83,7 +81,7 @@ static struct hw_interrupt_type landisk_irq_type = {
static void make_landisk_irq(unsigned int irq)
{
disable_irq_nosync(irq);
- irq_desc[irq].handler = &landisk_irq_type;
+ irq_desc[irq].chip = &landisk_irq_type;
disable_landisk_irq(irq);
}
diff --git a/arch/sh/boards/landisk/landisk_pwb.c b/arch/sh/boards/landisk/landisk_pwb.c
index e75cb578a28b..0b7bee1a9ca5 100644
--- a/arch/sh/boards/landisk/landisk_pwb.c
+++ b/arch/sh/boards/landisk/landisk_pwb.c
@@ -11,8 +11,6 @@
*
* LED control drive function added by kogiidena
*/
-
-#include <linux/config.h>
#include <linux/module.h>
#include <linux/errno.h>
#include <linux/signal.h>
diff --git a/arch/sh/boards/landisk/rtc.c b/arch/sh/boards/landisk/rtc.c
index 35ba726a0979..0a9a2a2ad05b 100644
--- a/arch/sh/boards/landisk/rtc.c
+++ b/arch/sh/boards/landisk/rtc.c
@@ -8,8 +8,6 @@
* modifed by kogiidena
* 2005.09.16
*/
-
-#include <linux/config.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/sched.h>
diff --git a/arch/sh/boards/landisk/setup.c b/arch/sh/boards/landisk/setup.c
index 127b9e020e00..122d69962637 100644
--- a/arch/sh/boards/landisk/setup.c
+++ b/arch/sh/boards/landisk/setup.c
@@ -16,7 +16,6 @@
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*/
-#include <linux/config.h>
#include <linux/init.h>
#include <linux/pm.h>
#include <linux/mm.h>
diff --git a/arch/sh/boards/renesas/r7780rp/irq.c b/arch/sh/boards/renesas/r7780rp/irq.c
index 61d5e5d3c294..2d960e9a3143 100644
--- a/arch/sh/boards/renesas/r7780rp/irq.c
+++ b/arch/sh/boards/renesas/r7780rp/irq.c
@@ -8,8 +8,6 @@
* Modified for R7780RP-1 by
* Atom Create Engineering Co., Ltd. 2002.
*/
-
-#include <linux/config.h>
#include <linux/init.h>
#include <linux/irq.h>
#include <asm/io.h>
@@ -83,7 +81,7 @@ static struct hw_interrupt_type r7780rp_irq_type = {
static void make_r7780rp_irq(unsigned int irq)
{
disable_irq_nosync(irq);
- irq_desc[irq].handler = &r7780rp_irq_type;
+ irq_desc[irq].chip = &r7780rp_irq_type;
disable_r7780rp_irq(irq);
}
diff --git a/arch/sh/boards/renesas/r7780rp/led.c b/arch/sh/boards/renesas/r7780rp/led.c
index 9f02766b6f53..6a00a257afd2 100644
--- a/arch/sh/boards/renesas/r7780rp/led.c
+++ b/arch/sh/boards/renesas/r7780rp/led.c
@@ -6,8 +6,6 @@
*
* This file contains Renesas Solutions HIGHLANDER R7780RP-1 specific LED code.
*/
-
-#include <linux/config.h>
#include <linux/sched.h>
#include <asm/io.h>
#include <asm/r7780rp/r7780rp.h>
diff --git a/arch/sh/boards/renesas/systemh/setup.c b/arch/sh/boards/renesas/systemh/setup.c
index a8467bf90c25..bab7d3cdc87b 100644
--- a/arch/sh/boards/renesas/systemh/setup.c
+++ b/arch/sh/boards/renesas/systemh/setup.c
@@ -53,6 +53,6 @@ struct sh_machine_vector mv_7751systemh __initmv = {
.mv_outsw = sh7751systemh_outsw,
.mv_outsl = sh7751systemh_outsl,
- .mv_init_irq = sh7751system_init_irq,
+ .mv_init_irq = sh7751systemh_init_irq,
};
ALIAS_MV(7751systemh)
diff --git a/arch/sh/boards/se/7343/io.c b/arch/sh/boards/se/7343/io.c
index 646661a146ad..3a6d11424938 100644
--- a/arch/sh/boards/se/7343/io.c
+++ b/arch/sh/boards/se/7343/io.c
@@ -4,8 +4,6 @@
* I/O routine for SH-Mobile3AS 7343 SolutionEngine.
*
*/
-
-#include <linux/config.h>
#include <linux/kernel.h>
#include <asm/io.h>
#include <asm/mach/se7343.h>
diff --git a/arch/sh/boards/se/7343/irq.c b/arch/sh/boards/se/7343/irq.c
index b41e3d4ea37c..288b62f59419 100644
--- a/arch/sh/boards/se/7343/irq.c
+++ b/arch/sh/boards/se/7343/irq.c
@@ -2,8 +2,6 @@
* arch/sh/boards/se/7343/irq.c
*
*/
-
-#include <linux/config.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
@@ -73,7 +71,7 @@ static void
make_intreq_irq(unsigned int irq)
{
disable_irq_nosync(irq);
- irq_desc[irq].handler = &intreq_irq_type;
+ irq_desc[irq].chip = &intreq_irq_type;
disable_intreq_irq(irq);
}
diff --git a/arch/sh/boards/se/7343/led.c b/arch/sh/boards/se/7343/led.c
index 6a439cf83e46..6b39e191c420 100644
--- a/arch/sh/boards/se/7343/led.c
+++ b/arch/sh/boards/se/7343/led.c
@@ -2,8 +2,6 @@
* arch/sh/boards/se/7343/led.c
*
*/
-
-#include <linux/config.h>
#include <linux/sched.h>
#include <asm/mach/se7343.h>
diff --git a/arch/sh/boards/se/7343/setup.c b/arch/sh/boards/se/7343/setup.c
index 787322291fb3..c7d17fe7764e 100644
--- a/arch/sh/boards/se/7343/setup.c
+++ b/arch/sh/boards/se/7343/setup.c
@@ -1,4 +1,3 @@
-#include <linux/config.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <asm/machvec.h>
diff --git a/arch/sh/boards/se/770x/setup.c b/arch/sh/boards/se/770x/setup.c
index f3f82b7c8217..a1d51d5fa925 100644
--- a/arch/sh/boards/se/770x/setup.c
+++ b/arch/sh/boards/se/770x/setup.c
@@ -8,13 +8,10 @@
*
*/
#include <linux/init.h>
-#include <linux/irq.h>
-#include <linux/hdreg.h>
-#include <linux/ide.h>
-#include <asm/io.h>
+#include <asm/machvec.h>
#include <asm/se.h>
+#include <asm/io.h>
#include <asm/smc37c93x.h>
-#include <asm/machvec.h>
void heartbeat_se(void);
void init_se_IRQ(void);
diff --git a/arch/sh/boards/se/7751/setup.c b/arch/sh/boards/se/7751/setup.c
index 73e826310ba8..f7e1dd39c836 100644
--- a/arch/sh/boards/se/7751/setup.c
+++ b/arch/sh/boards/se/7751/setup.c
@@ -8,12 +8,10 @@
* Modified for 7751 Solution Engine by
* Ian da Silva and Jeremy Siegel, 2001.
*/
-
#include <linux/init.h>
-#include <linux/irq.h>
-#include <linux/ide.h>
-#include <asm/io.h>
+#include <asm/machvec.h>
#include <asm/se7751.h>
+#include <asm/io.h>
void heartbeat_7751se(void);
void init_7751se_IRQ(void);
diff --git a/arch/sh/boards/sh03/setup.c b/arch/sh/boards/sh03/setup.c
index 6c310587ddfe..137e2ba9243e 100644
--- a/arch/sh/boards/sh03/setup.c
+++ b/arch/sh/boards/sh03/setup.c
@@ -7,6 +7,7 @@
#include <linux/init.h>
#include <linux/irq.h>
+#include <linux/pci.h>
#include <asm/io.h>
#include <asm/rtc.h>
#include <asm/sh03/io.h>
diff --git a/arch/sh/boot/.gitignore b/arch/sh/boot/.gitignore
new file mode 100644
index 000000000000..b6718de23693
--- /dev/null
+++ b/arch/sh/boot/.gitignore
@@ -0,0 +1 @@
+zImage
diff --git a/arch/sh/configs/adx_defconfig b/arch/sh/configs/adx_defconfig
deleted file mode 100644
index 353bfdc457d4..000000000000
--- a/arch/sh/configs/adx_defconfig
+++ /dev/null
@@ -1,539 +0,0 @@
-#
-# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.11-sh
-# Wed Mar 2 15:09:26 2005
-#
-CONFIG_SUPERH=y
-CONFIG_UID16=y
-CONFIG_RWSEM_GENERIC_SPINLOCK=y
-CONFIG_GENERIC_HARDIRQS=y
-CONFIG_GENERIC_IRQ_PROBE=y
-CONFIG_GENERIC_CALIBRATE_DELAY=y
-
-#
-# Code maturity level options
-#
-CONFIG_EXPERIMENTAL=y
-CONFIG_CLEAN_COMPILE=y
-CONFIG_BROKEN_ON_SMP=y
-
-#
-# General setup
-#
-CONFIG_LOCALVERSION=""
-CONFIG_SWAP=y
-# CONFIG_SYSVIPC is not set
-# CONFIG_BSD_PROCESS_ACCT is not set
-# CONFIG_SYSCTL is not set
-# CONFIG_AUDIT is not set
-CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_HOTPLUG is not set
-# CONFIG_IKCONFIG is not set
-# CONFIG_EMBEDDED is not set
-CONFIG_KALLSYMS=y
-# CONFIG_KALLSYMS_EXTRA_PASS is not set
-CONFIG_FUTEX=y
-CONFIG_EPOLL=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
-CONFIG_SHMEM=y
-CONFIG_CC_ALIGN_FUNCTIONS=0
-CONFIG_CC_ALIGN_LABELS=0
-CONFIG_CC_ALIGN_LOOPS=0
-CONFIG_CC_ALIGN_JUMPS=0
-# CONFIG_TINY_SHMEM is not set
-
-#
-# Loadable module support
-#
-# CONFIG_MODULES is not set
-
-#
-# System type
-#
-# CONFIG_SH_SOLUTION_ENGINE is not set
-# CONFIG_SH_7751_SOLUTION_ENGINE is not set
-# CONFIG_SH_7300_SOLUTION_ENGINE is not set
-# CONFIG_SH_73180_SOLUTION_ENGINE is not set
-# CONFIG_SH_7751_SYSTEMH is not set
-# CONFIG_SH_STB1_HARP is not set
-# CONFIG_SH_STB1_OVERDRIVE is not set
-# CONFIG_SH_HP620 is not set
-# CONFIG_SH_HP680 is not set
-# CONFIG_SH_HP690 is not set
-# CONFIG_SH_CQREEK is not set
-# CONFIG_SH_DMIDA is not set
-# CONFIG_SH_EC3104 is not set
-# CONFIG_SH_SATURN is not set
-# CONFIG_SH_DREAMCAST is not set
-# CONFIG_SH_CAT68701 is not set
-# CONFIG_SH_BIGSUR is not set
-# CONFIG_SH_SH2000 is not set
-CONFIG_SH_ADX=y
-# CONFIG_SH_MPC1211 is not set
-# CONFIG_SH_SH03 is not set
-# CONFIG_SH_SECUREEDGE5410 is not set
-# CONFIG_SH_HS7751RVOIP is not set
-# CONFIG_SH_RTS7751R2D is not set
-# CONFIG_SH_EDOSK7705 is not set
-# CONFIG_SH_SH4202_MICRODEV is not set
-# CONFIG_SH_UNKNOWN is not set
-# CONFIG_CPU_SH2 is not set
-# CONFIG_CPU_SH3 is not set
-CONFIG_CPU_SH4=y
-# CONFIG_CPU_SUBTYPE_SH7604 is not set
-# CONFIG_CPU_SUBTYPE_SH7300 is not set
-# CONFIG_CPU_SUBTYPE_SH7705 is not set
-# CONFIG_CPU_SUBTYPE_SH7707 is not set
-# CONFIG_CPU_SUBTYPE_SH7708 is not set
-# CONFIG_CPU_SUBTYPE_SH7709 is not set
-CONFIG_CPU_SUBTYPE_SH7750=y
-# CONFIG_CPU_SUBTYPE_SH7751 is not set
-# CONFIG_CPU_SUBTYPE_SH7760 is not set
-# CONFIG_CPU_SUBTYPE_SH73180 is not set
-# CONFIG_CPU_SUBTYPE_ST40STB1 is not set
-# CONFIG_CPU_SUBTYPE_ST40GX1 is not set
-# CONFIG_CPU_SUBTYPE_SH4_202 is not set
-CONFIG_MMU=y
-# CONFIG_CMDLINE_BOOL is not set
-CONFIG_MEMORY_START=0x08000000
-CONFIG_MEMORY_SIZE=0x00400000
-CONFIG_MEMORY_SET=y
-# CONFIG_MEMORY_OVERRIDE is not set
-CONFIG_CF_ENABLER=y
-# CONFIG_CF_AREA5 is not set
-CONFIG_CF_AREA6=y
-CONFIG_CF_BASE_ADDR=0xb8000000
-CONFIG_SH_RTC=y
-CONFIG_SH_FPU=y
-CONFIG_ZERO_PAGE_OFFSET=0x00001000
-CONFIG_BOOT_LINK_OFFSET=0x00800000
-CONFIG_CPU_LITTLE_ENDIAN=y
-# CONFIG_PREEMPT is not set
-# CONFIG_UBC_WAKEUP is not set
-# CONFIG_SH_WRITETHROUGH is not set
-# CONFIG_SH_OCRAM is not set
-# CONFIG_SH_STORE_QUEUES is not set
-# CONFIG_SMP is not set
-CONFIG_SH_PCLK_CALC=y
-CONFIG_SH_PCLK_FREQ=50000000
-
-#
-# CPU Frequency scaling
-#
-# CONFIG_CPU_FREQ is not set
-
-#
-# DMA support
-#
-# CONFIG_SH_DMA is not set
-
-#
-# Companion Chips
-#
-# CONFIG_HD6446X_SERIES is not set
-
-#
-# Bus options (PCI, PCMCIA, EISA, MCA, ISA)
-#
-# CONFIG_PCI is not set
-
-#
-# PCCARD (PCMCIA/CardBus) support
-#
-# CONFIG_PCCARD is not set
-
-#
-# PC-card bridges
-#
-
-#
-# PCI Hotplug Support
-#
-
-#
-# Executable file formats
-#
-CONFIG_BINFMT_ELF=y
-# CONFIG_BINFMT_FLAT is not set
-# CONFIG_BINFMT_MISC is not set
-
-#
-# SH initrd options
-#
-# CONFIG_EMBEDDED_RAMDISK is not set
-
-#
-# Device Drivers
-#
-
-#
-# Generic Driver Options
-#
-CONFIG_STANDALONE=y
-CONFIG_PREVENT_FIRMWARE_BUILD=y
-# CONFIG_FW_LOADER is not set
-
-#
-# Memory Technology Devices (MTD)
-#
-# CONFIG_MTD is not set
-
-#
-# Parallel port support
-#
-# CONFIG_PARPORT is not set
-
-#
-# Plug and Play support
-#
-
-#
-# Block devices
-#
-# CONFIG_BLK_DEV_FD is not set
-# CONFIG_BLK_DEV_COW_COMMON is not set
-# CONFIG_BLK_DEV_LOOP is not set
-CONFIG_BLK_DEV_RAM=y
-CONFIG_BLK_DEV_RAM_COUNT=16
-CONFIG_BLK_DEV_RAM_SIZE=4096
-CONFIG_BLK_DEV_INITRD=y
-CONFIG_INITRAMFS_SOURCE=""
-# CONFIG_LBD is not set
-# CONFIG_CDROM_PKTCDVD is not set
-
-#
-# IO Schedulers
-#
-CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
-CONFIG_IOSCHED_DEADLINE=y
-CONFIG_IOSCHED_CFQ=y
-
-#
-# ATA/ATAPI/MFM/RLL support
-#
-CONFIG_IDE=y
-CONFIG_IDE_MAX_HWIFS=4
-CONFIG_BLK_DEV_IDE=y
-
-#
-# Please see Documentation/ide.txt for help/info on IDE drives
-#
-# CONFIG_BLK_DEV_IDE_SATA is not set
-CONFIG_BLK_DEV_IDEDISK=y
-# CONFIG_IDEDISK_MULTI_MODE is not set
-# CONFIG_BLK_DEV_IDECD is not set
-# CONFIG_BLK_DEV_IDETAPE is not set
-# CONFIG_BLK_DEV_IDEFLOPPY is not set
-# CONFIG_IDE_TASK_IOCTL is not set
-
-#
-# IDE chipset support/bugfixes
-#
-CONFIG_IDE_GENERIC=y
-CONFIG_IDE_SH=y
-# CONFIG_IDE_ARM is not set
-# CONFIG_BLK_DEV_IDEDMA is not set
-# CONFIG_IDEDMA_AUTO is not set
-# CONFIG_BLK_DEV_HD is not set
-
-#
-# SCSI device support
-#
-# CONFIG_SCSI is not set
-
-#
-# Multi-device support (RAID and LVM)
-#
-# CONFIG_MD is not set
-
-#
-# Fusion MPT device support
-#
-
-#
-# IEEE 1394 (FireWire) support
-#
-
-#
-# I2O device support
-#
-
-#
-# Networking support
-#
-# CONFIG_NET is not set
-# CONFIG_NETPOLL is not set
-# CONFIG_NET_POLL_CONTROLLER is not set
-
-#
-# ISDN subsystem
-#
-
-#
-# Telephony Support
-#
-# CONFIG_PHONE is not set
-
-#
-# Input device support
-#
-CONFIG_INPUT=y
-
-#
-# Userland interfaces
-#
-CONFIG_INPUT_MOUSEDEV=y
-CONFIG_INPUT_MOUSEDEV_PSAUX=y
-CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
-CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
-# CONFIG_INPUT_JOYDEV is not set
-# CONFIG_INPUT_TSDEV is not set
-# CONFIG_INPUT_EVDEV is not set
-# CONFIG_INPUT_EVBUG is not set
-
-#
-# Input I/O drivers
-#
-# CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
-CONFIG_SERIO=y
-CONFIG_SERIO_I8042=y
-CONFIG_SERIO_SERPORT=y
-# CONFIG_SERIO_CT82C710 is not set
-CONFIG_SERIO_LIBPS2=y
-# CONFIG_SERIO_RAW is not set
-
-#
-# Input Device Drivers
-#
-CONFIG_INPUT_KEYBOARD=y
-CONFIG_KEYBOARD_ATKBD=y
-# CONFIG_KEYBOARD_SUNKBD is not set
-# CONFIG_KEYBOARD_LKKBD is not set
-# CONFIG_KEYBOARD_XTKBD is not set
-# CONFIG_KEYBOARD_NEWTON is not set
-CONFIG_INPUT_MOUSE=y
-CONFIG_MOUSE_PS2=y
-# CONFIG_MOUSE_SERIAL is not set
-# CONFIG_MOUSE_VSXXXAA is not set
-# CONFIG_INPUT_JOYSTICK is not set
-# CONFIG_INPUT_TOUCHSCREEN is not set
-# CONFIG_INPUT_MISC is not set
-
-#
-# Character devices
-#
-CONFIG_VT=y
-CONFIG_VT_CONSOLE=y
-CONFIG_HW_CONSOLE=y
-# CONFIG_SERIAL_NONSTANDARD is not set
-
-#
-# Serial drivers
-#
-# CONFIG_SERIAL_8250 is not set
-
-#
-# Non-8250 serial port support
-#
-# CONFIG_SERIAL_SH_SCI is not set
-CONFIG_UNIX98_PTYS=y
-CONFIG_LEGACY_PTYS=y
-CONFIG_LEGACY_PTY_COUNT=256
-
-#
-# IPMI
-#
-# CONFIG_IPMI_HANDLER is not set
-
-#
-# Watchdog Cards
-#
-# CONFIG_WATCHDOG is not set
-# CONFIG_RTC is not set
-# CONFIG_GEN_RTC is not set
-# CONFIG_DTLK is not set
-# CONFIG_R3964 is not set
-
-#
-# Ftape, the floppy tape device driver
-#
-# CONFIG_DRM is not set
-# CONFIG_RAW_DRIVER is not set
-
-#
-# I2C support
-#
-# CONFIG_I2C is not set
-
-#
-# Dallas's 1-wire bus
-#
-# CONFIG_W1 is not set
-
-#
-# Misc devices
-#
-
-#
-# Multimedia devices
-#
-# CONFIG_VIDEO_DEV is not set
-
-#
-# Digital Video Broadcasting Devices
-#
-
-#
-# Graphics support
-#
-# CONFIG_FB is not set
-
-#
-# Console display driver support
-#
-CONFIG_VGA_CONSOLE=y
-CONFIG_DUMMY_CONSOLE=y
-
-#
-# Sound
-#
-# CONFIG_SOUND is not set
-
-#
-# USB support
-#
-# CONFIG_USB_ARCH_HAS_HCD is not set
-# CONFIG_USB_ARCH_HAS_OHCI is not set
-
-#
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
-#
-
-#
-# USB Gadget Support
-#
-# CONFIG_USB_GADGET is not set
-
-#
-# MMC/SD Card support
-#
-# CONFIG_MMC is not set
-
-#
-# InfiniBand support
-#
-# CONFIG_INFINIBAND is not set
-
-#
-# File systems
-#
-CONFIG_EXT2_FS=y
-# CONFIG_EXT2_FS_XATTR is not set
-# CONFIG_EXT3_FS is not set
-# CONFIG_JBD is not set
-# CONFIG_REISERFS_FS is not set
-# CONFIG_JFS_FS is not set
-
-#
-# XFS support
-#
-# CONFIG_XFS_FS is not set
-# CONFIG_MINIX_FS is not set
-# CONFIG_ROMFS_FS is not set
-# CONFIG_QUOTA is not set
-CONFIG_DNOTIFY=y
-# CONFIG_AUTOFS_FS is not set
-# CONFIG_AUTOFS4_FS is not set
-
-#
-# CD-ROM/DVD Filesystems
-#
-# CONFIG_ISO9660_FS is not set
-# CONFIG_UDF_FS is not set
-
-#
-# DOS/FAT/NT Filesystems
-#
-# CONFIG_MSDOS_FS is not set
-# CONFIG_VFAT_FS is not set
-# CONFIG_NTFS_FS is not set
-
-#
-# Pseudo filesystems
-#
-CONFIG_PROC_FS=y
-# CONFIG_PROC_KCORE is not set
-CONFIG_SYSFS=y
-# CONFIG_DEVFS_FS is not set
-# CONFIG_DEVPTS_FS_XATTR is not set
-# CONFIG_TMPFS is not set
-# CONFIG_HUGETLBFS is not set
-# CONFIG_HUGETLB_PAGE is not set
-CONFIG_RAMFS=y
-
-#
-# Miscellaneous filesystems
-#
-# CONFIG_ADFS_FS is not set
-# CONFIG_AFFS_FS is not set
-# CONFIG_HFS_FS is not set
-# CONFIG_HFSPLUS_FS is not set
-# CONFIG_BEFS_FS is not set
-# CONFIG_BFS_FS is not set
-# CONFIG_EFS_FS is not set
-# CONFIG_CRAMFS is not set
-# CONFIG_VXFS_FS is not set
-# CONFIG_HPFS_FS is not set
-# CONFIG_QNX4FS_FS is not set
-# CONFIG_SYSV_FS is not set
-# CONFIG_UFS_FS is not set
-
-#
-# Partition Types
-#
-# CONFIG_PARTITION_ADVANCED is not set
-CONFIG_MSDOS_PARTITION=y
-
-#
-# Native Language Support
-#
-# CONFIG_NLS is not set
-
-#
-# Profiling support
-#
-# CONFIG_PROFILING is not set
-
-#
-# Kernel hacking
-#
-# CONFIG_DEBUG_KERNEL is not set
-# CONFIG_FRAME_POINTER is not set
-CONFIG_SH_STANDARD_BIOS=y
-# CONFIG_EARLY_SCIF_CONSOLE is not set
-# CONFIG_EARLY_PRINTK is not set
-# CONFIG_KGDB is not set
-
-#
-# Security options
-#
-# CONFIG_KEYS is not set
-# CONFIG_SECURITY is not set
-
-#
-# Cryptographic options
-#
-# CONFIG_CRYPTO is not set
-
-#
-# Hardware crypto devices
-#
-
-#
-# Library routines
-#
-# CONFIG_CRC_CCITT is not set
-# CONFIG_CRC32 is not set
-# CONFIG_LIBCRC32C is not set
diff --git a/arch/sh/configs/cqreek_defconfig b/arch/sh/configs/cqreek_defconfig
deleted file mode 100644
index 614662ae5789..000000000000
--- a/arch/sh/configs/cqreek_defconfig
+++ /dev/null
@@ -1,533 +0,0 @@
-#
-# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.11-sh
-# Wed Mar 2 15:09:38 2005
-#
-CONFIG_SUPERH=y
-CONFIG_UID16=y
-CONFIG_RWSEM_GENERIC_SPINLOCK=y
-CONFIG_GENERIC_HARDIRQS=y
-CONFIG_GENERIC_IRQ_PROBE=y
-CONFIG_GENERIC_CALIBRATE_DELAY=y
-
-#
-# Code maturity level options
-#
-CONFIG_EXPERIMENTAL=y
-CONFIG_CLEAN_COMPILE=y
-CONFIG_BROKEN_ON_SMP=y
-
-#
-# General setup
-#
-CONFIG_LOCALVERSION=""
-CONFIG_SWAP=y
-# CONFIG_SYSVIPC is not set
-# CONFIG_BSD_PROCESS_ACCT is not set
-# CONFIG_SYSCTL is not set
-# CONFIG_AUDIT is not set
-CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_HOTPLUG is not set
-# CONFIG_IKCONFIG is not set
-# CONFIG_EMBEDDED is not set
-CONFIG_KALLSYMS=y
-# CONFIG_KALLSYMS_EXTRA_PASS is not set
-CONFIG_FUTEX=y
-CONFIG_EPOLL=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
-CONFIG_SHMEM=y
-CONFIG_CC_ALIGN_FUNCTIONS=0
-CONFIG_CC_ALIGN_LABELS=0
-CONFIG_CC_ALIGN_LOOPS=0
-CONFIG_CC_ALIGN_JUMPS=0
-# CONFIG_TINY_SHMEM is not set
-
-#
-# Loadable module support
-#
-# CONFIG_MODULES is not set
-
-#
-# System type
-#
-# CONFIG_SH_SOLUTION_ENGINE is not set
-# CONFIG_SH_7751_SOLUTION_ENGINE is not set
-# CONFIG_SH_7300_SOLUTION_ENGINE is not set
-# CONFIG_SH_73180_SOLUTION_ENGINE is not set
-# CONFIG_SH_7751_SYSTEMH is not set
-# CONFIG_SH_STB1_HARP is not set
-# CONFIG_SH_STB1_OVERDRIVE is not set
-# CONFIG_SH_HP620 is not set
-# CONFIG_SH_HP680 is not set
-# CONFIG_SH_HP690 is not set
-CONFIG_SH_CQREEK=y
-# CONFIG_SH_DMIDA is not set
-# CONFIG_SH_EC3104 is not set
-# CONFIG_SH_SATURN is not set
-# CONFIG_SH_DREAMCAST is not set
-# CONFIG_SH_CAT68701 is not set
-# CONFIG_SH_BIGSUR is not set
-# CONFIG_SH_SH2000 is not set
-# CONFIG_SH_ADX is not set
-# CONFIG_SH_MPC1211 is not set
-# CONFIG_SH_SH03 is not set
-# CONFIG_SH_SECUREEDGE5410 is not set
-# CONFIG_SH_HS7751RVOIP is not set
-# CONFIG_SH_RTS7751R2D is not set
-# CONFIG_SH_EDOSK7705 is not set
-# CONFIG_SH_SH4202_MICRODEV is not set
-# CONFIG_SH_UNKNOWN is not set
-# CONFIG_CPU_SH2 is not set
-CONFIG_CPU_SH3=y
-# CONFIG_CPU_SH4 is not set
-# CONFIG_CPU_SUBTYPE_SH7604 is not set
-# CONFIG_CPU_SUBTYPE_SH7300 is not set
-# CONFIG_CPU_SUBTYPE_SH7705 is not set
-# CONFIG_CPU_SUBTYPE_SH7707 is not set
-CONFIG_CPU_SUBTYPE_SH7708=y
-# CONFIG_CPU_SUBTYPE_SH7709 is not set
-# CONFIG_CPU_SUBTYPE_SH7750 is not set
-# CONFIG_CPU_SUBTYPE_SH7751 is not set
-# CONFIG_CPU_SUBTYPE_SH7760 is not set
-# CONFIG_CPU_SUBTYPE_SH73180 is not set
-# CONFIG_CPU_SUBTYPE_ST40STB1 is not set
-# CONFIG_CPU_SUBTYPE_ST40GX1 is not set
-# CONFIG_CPU_SUBTYPE_SH4_202 is not set
-CONFIG_MMU=y
-# CONFIG_CMDLINE_BOOL is not set
-CONFIG_MEMORY_START=0x0c000000
-CONFIG_MEMORY_SIZE=0x00400000
-# CONFIG_MEMORY_OVERRIDE is not set
-CONFIG_SH_RTC=y
-CONFIG_SH_DSP=y
-CONFIG_SH_ADC=y
-CONFIG_ZERO_PAGE_OFFSET=0x00001000
-CONFIG_BOOT_LINK_OFFSET=0x00800000
-CONFIG_CPU_LITTLE_ENDIAN=y
-# CONFIG_PREEMPT is not set
-# CONFIG_UBC_WAKEUP is not set
-# CONFIG_SH_WRITETHROUGH is not set
-# CONFIG_SH_OCRAM is not set
-# CONFIG_SMP is not set
-CONFIG_SH_PCLK_CALC=y
-CONFIG_SH_PCLK_FREQ=1193182
-
-#
-# CPU Frequency scaling
-#
-# CONFIG_CPU_FREQ is not set
-
-#
-# DMA support
-#
-# CONFIG_SH_DMA is not set
-
-#
-# Companion Chips
-#
-# CONFIG_HD6446X_SERIES is not set
-
-#
-# Bus options (PCI, PCMCIA, EISA, MCA, ISA)
-#
-# CONFIG_PCI is not set
-
-#
-# PCCARD (PCMCIA/CardBus) support
-#
-# CONFIG_PCCARD is not set
-
-#
-# PC-card bridges
-#
-
-#
-# PCI Hotplug Support
-#
-
-#
-# Executable file formats
-#
-CONFIG_BINFMT_ELF=y
-# CONFIG_BINFMT_FLAT is not set
-# CONFIG_BINFMT_MISC is not set
-
-#
-# SH initrd options
-#
-# CONFIG_EMBEDDED_RAMDISK is not set
-
-#
-# Device Drivers
-#
-
-#
-# Generic Driver Options
-#
-CONFIG_STANDALONE=y
-CONFIG_PREVENT_FIRMWARE_BUILD=y
-# CONFIG_FW_LOADER is not set
-
-#
-# Memory Technology Devices (MTD)
-#
-# CONFIG_MTD is not set
-
-#
-# Parallel port support
-#
-# CONFIG_PARPORT is not set
-
-#
-# Plug and Play support
-#
-
-#
-# Block devices
-#
-# CONFIG_BLK_DEV_FD is not set
-# CONFIG_BLK_DEV_COW_COMMON is not set
-# CONFIG_BLK_DEV_LOOP is not set
-CONFIG_BLK_DEV_RAM=y
-CONFIG_BLK_DEV_RAM_COUNT=16
-CONFIG_BLK_DEV_RAM_SIZE=4096
-CONFIG_BLK_DEV_INITRD=y
-CONFIG_INITRAMFS_SOURCE=""
-# CONFIG_LBD is not set
-# CONFIG_CDROM_PKTCDVD is not set
-
-#
-# IO Schedulers
-#
-CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
-CONFIG_IOSCHED_DEADLINE=y
-CONFIG_IOSCHED_CFQ=y
-
-#
-# ATA/ATAPI/MFM/RLL support
-#
-CONFIG_IDE=y
-CONFIG_IDE_MAX_HWIFS=4
-CONFIG_BLK_DEV_IDE=y
-
-#
-# Please see Documentation/ide.txt for help/info on IDE drives
-#
-# CONFIG_BLK_DEV_IDE_SATA is not set
-CONFIG_BLK_DEV_IDEDISK=y
-# CONFIG_IDEDISK_MULTI_MODE is not set
-# CONFIG_BLK_DEV_IDECD is not set
-# CONFIG_BLK_DEV_IDETAPE is not set
-# CONFIG_BLK_DEV_IDEFLOPPY is not set
-# CONFIG_IDE_TASK_IOCTL is not set
-
-#
-# IDE chipset support/bugfixes
-#
-CONFIG_IDE_GENERIC=y
-CONFIG_IDE_SH=y
-# CONFIG_IDE_ARM is not set
-# CONFIG_BLK_DEV_IDEDMA is not set
-# CONFIG_IDEDMA_AUTO is not set
-# CONFIG_BLK_DEV_HD is not set
-
-#
-# SCSI device support
-#
-# CONFIG_SCSI is not set
-
-#
-# Multi-device support (RAID and LVM)
-#
-# CONFIG_MD is not set
-
-#
-# Fusion MPT device support
-#
-
-#
-# IEEE 1394 (FireWire) support
-#
-
-#
-# I2O device support
-#
-
-#
-# Networking support
-#
-# CONFIG_NET is not set
-# CONFIG_NETPOLL is not set
-# CONFIG_NET_POLL_CONTROLLER is not set
-
-#
-# ISDN subsystem
-#
-
-#
-# Telephony Support
-#
-# CONFIG_PHONE is not set
-
-#
-# Input device support
-#
-CONFIG_INPUT=y
-
-#
-# Userland interfaces
-#
-CONFIG_INPUT_MOUSEDEV=y
-CONFIG_INPUT_MOUSEDEV_PSAUX=y
-CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
-CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
-# CONFIG_INPUT_JOYDEV is not set
-# CONFIG_INPUT_TSDEV is not set
-# CONFIG_INPUT_EVDEV is not set
-# CONFIG_INPUT_EVBUG is not set
-
-#
-# Input I/O drivers
-#
-# CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
-CONFIG_SERIO=y
-CONFIG_SERIO_I8042=y
-CONFIG_SERIO_SERPORT=y
-# CONFIG_SERIO_CT82C710 is not set
-CONFIG_SERIO_LIBPS2=y
-# CONFIG_SERIO_RAW is not set
-
-#
-# Input Device Drivers
-#
-CONFIG_INPUT_KEYBOARD=y
-CONFIG_KEYBOARD_ATKBD=y
-# CONFIG_KEYBOARD_SUNKBD is not set
-# CONFIG_KEYBOARD_LKKBD is not set
-# CONFIG_KEYBOARD_XTKBD is not set
-# CONFIG_KEYBOARD_NEWTON is not set
-CONFIG_INPUT_MOUSE=y
-CONFIG_MOUSE_PS2=y
-# CONFIG_MOUSE_SERIAL is not set
-# CONFIG_MOUSE_VSXXXAA is not set
-# CONFIG_INPUT_JOYSTICK is not set
-# CONFIG_INPUT_TOUCHSCREEN is not set
-# CONFIG_INPUT_MISC is not set
-
-#
-# Character devices
-#
-CONFIG_VT=y
-CONFIG_VT_CONSOLE=y
-CONFIG_HW_CONSOLE=y
-# CONFIG_SERIAL_NONSTANDARD is not set
-
-#
-# Serial drivers
-#
-# CONFIG_SERIAL_8250 is not set
-
-#
-# Non-8250 serial port support
-#
-# CONFIG_SERIAL_SH_SCI is not set
-CONFIG_UNIX98_PTYS=y
-CONFIG_LEGACY_PTYS=y
-CONFIG_LEGACY_PTY_COUNT=256
-
-#
-# IPMI
-#
-# CONFIG_IPMI_HANDLER is not set
-
-#
-# Watchdog Cards
-#
-# CONFIG_WATCHDOG is not set
-# CONFIG_RTC is not set
-# CONFIG_GEN_RTC is not set
-# CONFIG_DTLK is not set
-# CONFIG_R3964 is not set
-
-#
-# Ftape, the floppy tape device driver
-#
-# CONFIG_DRM is not set
-# CONFIG_RAW_DRIVER is not set
-
-#
-# I2C support
-#
-# CONFIG_I2C is not set
-
-#
-# Dallas's 1-wire bus
-#
-# CONFIG_W1 is not set
-
-#
-# Misc devices
-#
-
-#
-# Multimedia devices
-#
-# CONFIG_VIDEO_DEV is not set
-
-#
-# Digital Video Broadcasting Devices
-#
-
-#
-# Graphics support
-#
-# CONFIG_FB is not set
-
-#
-# Console display driver support
-#
-CONFIG_VGA_CONSOLE=y
-CONFIG_DUMMY_CONSOLE=y
-
-#
-# Sound
-#
-# CONFIG_SOUND is not set
-
-#
-# USB support
-#
-# CONFIG_USB_ARCH_HAS_HCD is not set
-# CONFIG_USB_ARCH_HAS_OHCI is not set
-
-#
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
-#
-
-#
-# USB Gadget Support
-#
-# CONFIG_USB_GADGET is not set
-
-#
-# MMC/SD Card support
-#
-# CONFIG_MMC is not set
-
-#
-# InfiniBand support
-#
-# CONFIG_INFINIBAND is not set
-
-#
-# File systems
-#
-CONFIG_EXT2_FS=y
-# CONFIG_EXT2_FS_XATTR is not set
-# CONFIG_EXT3_FS is not set
-# CONFIG_JBD is not set
-# CONFIG_REISERFS_FS is not set
-# CONFIG_JFS_FS is not set
-
-#
-# XFS support
-#
-# CONFIG_XFS_FS is not set
-# CONFIG_MINIX_FS is not set
-# CONFIG_ROMFS_FS is not set
-# CONFIG_QUOTA is not set
-CONFIG_DNOTIFY=y
-# CONFIG_AUTOFS_FS is not set
-# CONFIG_AUTOFS4_FS is not set
-
-#
-# CD-ROM/DVD Filesystems
-#
-# CONFIG_ISO9660_FS is not set
-# CONFIG_UDF_FS is not set
-
-#
-# DOS/FAT/NT Filesystems
-#
-# CONFIG_MSDOS_FS is not set
-# CONFIG_VFAT_FS is not set
-# CONFIG_NTFS_FS is not set
-
-#
-# Pseudo filesystems
-#
-CONFIG_PROC_FS=y
-# CONFIG_PROC_KCORE is not set
-CONFIG_SYSFS=y
-# CONFIG_DEVFS_FS is not set
-# CONFIG_DEVPTS_FS_XATTR is not set
-# CONFIG_TMPFS is not set
-# CONFIG_HUGETLBFS is not set
-# CONFIG_HUGETLB_PAGE is not set
-CONFIG_RAMFS=y
-
-#
-# Miscellaneous filesystems
-#
-# CONFIG_ADFS_FS is not set
-# CONFIG_AFFS_FS is not set
-# CONFIG_HFS_FS is not set
-# CONFIG_HFSPLUS_FS is not set
-# CONFIG_BEFS_FS is not set
-# CONFIG_BFS_FS is not set
-# CONFIG_EFS_FS is not set
-# CONFIG_CRAMFS is not set
-# CONFIG_VXFS_FS is not set
-# CONFIG_HPFS_FS is not set
-# CONFIG_QNX4FS_FS is not set
-# CONFIG_SYSV_FS is not set
-# CONFIG_UFS_FS is not set
-
-#
-# Partition Types
-#
-# CONFIG_PARTITION_ADVANCED is not set
-CONFIG_MSDOS_PARTITION=y
-
-#
-# Native Language Support
-#
-# CONFIG_NLS is not set
-
-#
-# Profiling support
-#
-# CONFIG_PROFILING is not set
-
-#
-# Kernel hacking
-#
-# CONFIG_DEBUG_KERNEL is not set
-# CONFIG_FRAME_POINTER is not set
-CONFIG_SH_STANDARD_BIOS=y
-# CONFIG_EARLY_PRINTK is not set
-# CONFIG_KGDB is not set
-
-#
-# Security options
-#
-# CONFIG_KEYS is not set
-# CONFIG_SECURITY is not set
-
-#
-# Cryptographic options
-#
-# CONFIG_CRYPTO is not set
-
-#
-# Hardware crypto devices
-#
-
-#
-# Library routines
-#
-# CONFIG_CRC_CCITT is not set
-# CONFIG_CRC32 is not set
-# CONFIG_LIBCRC32C is not set
diff --git a/arch/sh/configs/dreamcast_defconfig b/arch/sh/configs/dreamcast_defconfig
index 776c1909bee3..8b6b5a779de8 100644
--- a/arch/sh/configs/dreamcast_defconfig
+++ b/arch/sh/configs/dreamcast_defconfig
@@ -1,50 +1,63 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.11-sh
-# Wed Mar 2 15:09:40 2005
+# Linux kernel version: 2.6.18
+# Tue Oct 3 10:51:55 2006
#
CONFIG_SUPERH=y
-CONFIG_UID16=y
CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+CONFIG_GENERIC_HWEIGHT=y
CONFIG_GENERIC_HARDIRQS=y
CONFIG_GENERIC_IRQ_PROBE=y
CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
#
# Code maturity level options
#
CONFIG_EXPERIMENTAL=y
-CONFIG_CLEAN_COMPILE=y
CONFIG_BROKEN_ON_SMP=y
CONFIG_LOCK_KERNEL=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
#
# General setup
#
CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
CONFIG_SWAP=y
CONFIG_SYSVIPC=y
+# CONFIG_IPC_NS is not set
# CONFIG_POSIX_MQUEUE is not set
CONFIG_BSD_PROCESS_ACCT=y
# CONFIG_BSD_PROCESS_ACCT_V3 is not set
-CONFIG_SYSCTL=y
+# CONFIG_TASKSTATS is not set
+# CONFIG_UTS_NS is not set
# CONFIG_AUDIT is not set
-CONFIG_LOG_BUF_SHIFT=14
-CONFIG_HOTPLUG=y
-CONFIG_KOBJECT_UEVENT=y
# CONFIG_IKCONFIG is not set
+# CONFIG_RELAY is not set
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
CONFIG_EMBEDDED=y
+CONFIG_UID16=y
+# CONFIG_SYSCTL_SYSCALL is not set
CONFIG_KALLSYMS=y
# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
CONFIG_EPOLL=y
-CONFIG_CC_OPTIMIZE_FOR_SIZE=y
CONFIG_SHMEM=y
-CONFIG_CC_ALIGN_FUNCTIONS=0
-CONFIG_CC_ALIGN_LABELS=0
-CONFIG_CC_ALIGN_LOOPS=0
-CONFIG_CC_ALIGN_JUMPS=0
+CONFIG_SLAB=y
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_RT_MUTEXES=y
# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+# CONFIG_SLOB is not set
#
# Loadable module support
@@ -52,82 +65,158 @@ CONFIG_CC_ALIGN_JUMPS=0
CONFIG_MODULES=y
CONFIG_MODULE_UNLOAD=y
# CONFIG_MODULE_FORCE_UNLOAD is not set
-CONFIG_OBSOLETE_MODPARM=y
# CONFIG_MODVERSIONS is not set
# CONFIG_MODULE_SRCVERSION_ALL is not set
CONFIG_KMOD=y
#
+# Block layer
+#
+CONFIG_BLOCK=y
+# CONFIG_LBD is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_LSF is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+CONFIG_DEFAULT_AS=y
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="anticipatory"
+
+#
# System type
#
# CONFIG_SH_SOLUTION_ENGINE is not set
# CONFIG_SH_7751_SOLUTION_ENGINE is not set
# CONFIG_SH_7300_SOLUTION_ENGINE is not set
+# CONFIG_SH_7343_SOLUTION_ENGINE is not set
# CONFIG_SH_73180_SOLUTION_ENGINE is not set
# CONFIG_SH_7751_SYSTEMH is not set
-# CONFIG_SH_STB1_HARP is not set
-# CONFIG_SH_STB1_OVERDRIVE is not set
-# CONFIG_SH_HP620 is not set
-# CONFIG_SH_HP680 is not set
-# CONFIG_SH_HP690 is not set
-# CONFIG_SH_CQREEK is not set
-# CONFIG_SH_DMIDA is not set
+# CONFIG_SH_HP6XX is not set
# CONFIG_SH_EC3104 is not set
# CONFIG_SH_SATURN is not set
CONFIG_SH_DREAMCAST=y
-# CONFIG_SH_CAT68701 is not set
# CONFIG_SH_BIGSUR is not set
-# CONFIG_SH_SH2000 is not set
-# CONFIG_SH_ADX is not set
# CONFIG_SH_MPC1211 is not set
# CONFIG_SH_SH03 is not set
# CONFIG_SH_SECUREEDGE5410 is not set
# CONFIG_SH_HS7751RVOIP is not set
+# CONFIG_SH_7710VOIPGW is not set
# CONFIG_SH_RTS7751R2D is not set
+# CONFIG_SH_R7780RP is not set
# CONFIG_SH_EDOSK7705 is not set
# CONFIG_SH_SH4202_MICRODEV is not set
+# CONFIG_SH_LANDISK is not set
+# CONFIG_SH_TITAN is not set
+# CONFIG_SH_SHMIN is not set
# CONFIG_SH_UNKNOWN is not set
-# CONFIG_CPU_SH2 is not set
-# CONFIG_CPU_SH3 is not set
+
+#
+# Processor selection
+#
CONFIG_CPU_SH4=y
+
+#
+# SH-2 Processor Support
+#
# CONFIG_CPU_SUBTYPE_SH7604 is not set
+
+#
+# SH-3 Processor Support
+#
# CONFIG_CPU_SUBTYPE_SH7300 is not set
# CONFIG_CPU_SUBTYPE_SH7705 is not set
+# CONFIG_CPU_SUBTYPE_SH7706 is not set
# CONFIG_CPU_SUBTYPE_SH7707 is not set
# CONFIG_CPU_SUBTYPE_SH7708 is not set
# CONFIG_CPU_SUBTYPE_SH7709 is not set
+# CONFIG_CPU_SUBTYPE_SH7710 is not set
+
+#
+# SH-4 Processor Support
+#
CONFIG_CPU_SUBTYPE_SH7750=y
+CONFIG_CPU_SUBTYPE_SH7091=y
+CONFIG_CPU_SUBTYPE_SH7750R=y
+# CONFIG_CPU_SUBTYPE_SH7750S is not set
# CONFIG_CPU_SUBTYPE_SH7751 is not set
+# CONFIG_CPU_SUBTYPE_SH7751R is not set
# CONFIG_CPU_SUBTYPE_SH7760 is not set
-# CONFIG_CPU_SUBTYPE_SH73180 is not set
+# CONFIG_CPU_SUBTYPE_SH4_202 is not set
+
+#
+# ST40 Processor Support
+#
# CONFIG_CPU_SUBTYPE_ST40STB1 is not set
# CONFIG_CPU_SUBTYPE_ST40GX1 is not set
-# CONFIG_CPU_SUBTYPE_SH4_202 is not set
+
+#
+# SH-4A Processor Support
+#
+# CONFIG_CPU_SUBTYPE_SH7770 is not set
+# CONFIG_CPU_SUBTYPE_SH7780 is not set
+
+#
+# SH4AL-DSP Processor Support
+#
+# CONFIG_CPU_SUBTYPE_SH73180 is not set
+# CONFIG_CPU_SUBTYPE_SH7343 is not set
+
+#
+# Memory management options
+#
CONFIG_MMU=y
-CONFIG_HUGETLB_PAGE_SIZE_64K=y
-# CONFIG_HUGETLB_PAGE_SIZE_1MB is not set
-# CONFIG_CMDLINE_BOOL is not set
+CONFIG_PAGE_OFFSET=0x80000000
CONFIG_MEMORY_START=0x0c000000
CONFIG_MEMORY_SIZE=0x01000000
-CONFIG_MEMORY_SET=y
-# CONFIG_MEMORY_OVERRIDE is not set
-CONFIG_SH_FPU=y
-CONFIG_ZERO_PAGE_OFFSET=0x00001000
-CONFIG_BOOT_LINK_OFFSET=0x00800000
-CONFIG_CPU_LITTLE_ENDIAN=y
-CONFIG_PREEMPT=y
-# CONFIG_UBC_WAKEUP is not set
+CONFIG_VSYSCALL=y
+CONFIG_HUGETLB_PAGE_SIZE_64K=y
+# CONFIG_HUGETLB_PAGE_SIZE_1MB is not set
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+# CONFIG_SPARSEMEM_STATIC is not set
+CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_RESOURCES_64BIT is not set
+
+#
+# Cache configuration
+#
+# CONFIG_SH_DIRECT_MAPPED is not set
# CONFIG_SH_WRITETHROUGH is not set
-CONFIG_SH_OCRAM=y
+# CONFIG_SH_OCRAM is not set
+
+#
+# Processor features
+#
+CONFIG_CPU_LITTLE_ENDIAN=y
+CONFIG_SH_FPU=y
+# CONFIG_SH_DSP is not set
CONFIG_SH_STORE_QUEUES=y
-# CONFIG_SMP is not set
-CONFIG_SH_PCLK_CALC=y
+CONFIG_CPU_HAS_INTEVT=y
+CONFIG_CPU_HAS_SR_RB=y
+
+#
+# Timer support
+#
+CONFIG_SH_TMU=y
CONFIG_SH_PCLK_FREQ=49876504
#
# CPU Frequency scaling
#
CONFIG_CPU_FREQ=y
+CONFIG_CPU_FREQ_TABLE=y
# CONFIG_CPU_FREQ_DEBUG is not set
CONFIG_CPU_FREQ_STAT=y
# CONFIG_CPU_FREQ_STAT_DETAILS is not set
@@ -137,8 +226,8 @@ CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
CONFIG_CPU_FREQ_GOV_POWERSAVE=y
CONFIG_CPU_FREQ_GOV_USERSPACE=y
# CONFIG_CPU_FREQ_GOV_ONDEMAND is not set
-CONFIG_CPU_FREQ_TABLE=y
-CONFIG_SH_CPU_FREQ=y
+# CONFIG_CPU_FREQ_GOV_CONSERVATIVE is not set
+# CONFIG_SH_CPU_FREQ is not set
#
# DMA support
@@ -154,14 +243,35 @@ CONFIG_NR_DMA_CHANNELS=9
# CONFIG_HD6446X_SERIES is not set
#
-# Bus options (PCI, PCMCIA, EISA, MCA, ISA)
+# Kernel features
+#
+# CONFIG_HZ_100 is not set
+CONFIG_HZ_250=y
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=250
+# CONFIG_KEXEC is not set
+# CONFIG_SMP is not set
+# CONFIG_PREEMPT_NONE is not set
+# CONFIG_PREEMPT_VOLUNTARY is not set
+CONFIG_PREEMPT=y
+CONFIG_PREEMPT_BKL=y
+
+#
+# Boot options
+#
+CONFIG_ZERO_PAGE_OFFSET=0x00001000
+CONFIG_BOOT_LINK_OFFSET=0x00800000
+# CONFIG_UBC_WAKEUP is not set
+CONFIG_CMDLINE_BOOL=y
+CONFIG_CMDLINE="console=ttySC1,115200 panic=3"
+
+#
+# Bus options
#
-CONFIG_MAPLE=y
CONFIG_PCI=y
# CONFIG_SH_PCIDMA_NONCOHERENT is not set
CONFIG_PCI_AUTO=y
-CONFIG_PCI_LEGACY_PROC=y
-CONFIG_PCI_NAMES=y
+# CONFIG_PCI_MULTITHREAD_PROBE is not set
#
# PCCARD (PCMCIA/CardBus) support
@@ -169,10 +279,6 @@ CONFIG_PCI_NAMES=y
# CONFIG_PCCARD is not set
#
-# PC-card bridges
-#
-
-#
# PCI Hotplug Support
#
# CONFIG_HOTPLUG_PCI is not set
@@ -185,9 +291,92 @@ CONFIG_BINFMT_ELF=y
# CONFIG_BINFMT_MISC is not set
#
-# SH initrd options
+# Power management options (EXPERIMENTAL)
+#
+# CONFIG_PM is not set
+
+#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+# CONFIG_NETDEBUG is not set
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+# CONFIG_XFRM_USER is not set
+# CONFIG_XFRM_SUB_POLICY is not set
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+# CONFIG_IP_PNP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+# CONFIG_INET_TUNNEL is not set
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_IPV6 is not set
+# CONFIG_INET6_XFRM_TUNNEL is not set
+# CONFIG_INET6_TUNNEL is not set
+# CONFIG_NETWORK_SECMARK is not set
+# CONFIG_NETFILTER is not set
+
+#
+# DCCP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_DCCP is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP is not set
+
+#
+# TIPC Configuration (EXPERIMENTAL)
+#
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+
+#
+# Network testing
#
-# CONFIG_EMBEDDED_RAMDISK is not set
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_IEEE80211 is not set
#
# Device Drivers
@@ -199,6 +388,12 @@ CONFIG_BINFMT_ELF=y
# CONFIG_STANDALONE is not set
CONFIG_PREVENT_FIRMWARE_BUILD=y
# CONFIG_FW_LOADER is not set
+# CONFIG_SYS_HYPERVISOR is not set
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
+# CONFIG_CONNECTOR is not set
#
# Memory Technology Devices (MTD)
@@ -217,7 +412,6 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
#
# Block devices
#
-# CONFIG_BLK_DEV_FD is not set
# CONFIG_BLK_CPQ_DA is not set
# CONFIG_BLK_CPQ_CISS_DA is not set
# CONFIG_BLK_DEV_DAC960 is not set
@@ -226,21 +420,9 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
# CONFIG_BLK_DEV_LOOP is not set
# CONFIG_BLK_DEV_NBD is not set
# CONFIG_BLK_DEV_SX8 is not set
-CONFIG_BLK_DEV_RAM=y
-CONFIG_BLK_DEV_RAM_COUNT=16
-CONFIG_BLK_DEV_RAM_SIZE=1024
-CONFIG_BLK_DEV_INITRD=y
-CONFIG_INITRAMFS_SOURCE=""
-# CONFIG_LBD is not set
+# CONFIG_BLK_DEV_RAM is not set
+# CONFIG_BLK_DEV_INITRD is not set
# CONFIG_CDROM_PKTCDVD is not set
-
-#
-# IO Schedulers
-#
-CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
-CONFIG_IOSCHED_DEADLINE=y
-CONFIG_IOSCHED_CFQ=y
# CONFIG_ATA_OVER_ETH is not set
#
@@ -251,7 +433,14 @@ CONFIG_IOSCHED_CFQ=y
#
# SCSI device support
#
+# CONFIG_RAID_ATTRS is not set
# CONFIG_SCSI is not set
+# CONFIG_SCSI_NETLINK is not set
+
+#
+# Serial ATA (prod) and Parallel ATA (experimental) drivers
+#
+# CONFIG_ATA is not set
#
# Multi-device support (RAID and LVM)
@@ -261,6 +450,7 @@ CONFIG_IOSCHED_CFQ=y
#
# Fusion MPT device support
#
+# CONFIG_FUSION is not set
#
# IEEE 1394 (FireWire) support
@@ -273,70 +463,8 @@ CONFIG_IOSCHED_CFQ=y
# CONFIG_I2O is not set
#
-# Networking support
-#
-CONFIG_NET=y
-
-#
-# Networking options
+# Network device support
#
-CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
-# CONFIG_NETLINK_DEV is not set
-CONFIG_UNIX=y
-# CONFIG_NET_KEY is not set
-CONFIG_INET=y
-# CONFIG_IP_MULTICAST is not set
-# CONFIG_IP_ADVANCED_ROUTER is not set
-CONFIG_IP_PNP=y
-CONFIG_IP_PNP_DHCP=y
-# CONFIG_IP_PNP_BOOTP is not set
-# CONFIG_IP_PNP_RARP is not set
-# CONFIG_NET_IPIP is not set
-# CONFIG_NET_IPGRE is not set
-# CONFIG_ARPD is not set
-# CONFIG_SYN_COOKIES is not set
-# CONFIG_INET_AH is not set
-# CONFIG_INET_ESP is not set
-# CONFIG_INET_IPCOMP is not set
-# CONFIG_INET_TUNNEL is not set
-CONFIG_IP_TCPDIAG=y
-# CONFIG_IP_TCPDIAG_IPV6 is not set
-# CONFIG_IPV6 is not set
-# CONFIG_NETFILTER is not set
-
-#
-# SCTP Configuration (EXPERIMENTAL)
-#
-# CONFIG_IP_SCTP is not set
-# CONFIG_ATM is not set
-# CONFIG_BRIDGE is not set
-# CONFIG_VLAN_8021Q is not set
-# CONFIG_DECNET is not set
-# CONFIG_LLC2 is not set
-# CONFIG_IPX is not set
-# CONFIG_ATALK is not set
-# CONFIG_X25 is not set
-# CONFIG_LAPB is not set
-# CONFIG_NET_DIVERT is not set
-# CONFIG_ECONET is not set
-# CONFIG_WAN_ROUTER is not set
-
-#
-# QoS and/or fair queueing
-#
-# CONFIG_NET_SCHED is not set
-# CONFIG_NET_CLS_ROUTE is not set
-
-#
-# Network testing
-#
-# CONFIG_NET_PKTGEN is not set
-# CONFIG_NETPOLL is not set
-# CONFIG_NET_POLL_CONTROLLER is not set
-# CONFIG_HAMRADIO is not set
-# CONFIG_IRDA is not set
-# CONFIG_BT is not set
CONFIG_NETDEVICES=y
# CONFIG_DUMMY is not set
# CONFIG_BONDING is not set
@@ -349,6 +477,11 @@ CONFIG_NETDEVICES=y
# CONFIG_ARCNET is not set
#
+# PHY device support
+#
+# CONFIG_PHYLIB is not set
+
+#
# Ethernet (10 or 100Mbit)
#
CONFIG_NET_ETHERNET=y
@@ -356,6 +489,7 @@ CONFIG_MII=y
# CONFIG_STNIC is not set
# CONFIG_HAPPYMEAL is not set
# CONFIG_SUNGEM is not set
+# CONFIG_CASSINI is not set
# CONFIG_NET_VENDOR_3COM is not set
# CONFIG_SMC91X is not set
@@ -398,15 +532,22 @@ CONFIG_8139TOO=y
# CONFIG_HAMACHI is not set
# CONFIG_YELLOWFIN is not set
# CONFIG_R8169 is not set
+# CONFIG_SIS190 is not set
+# CONFIG_SKGE is not set
+# CONFIG_SKY2 is not set
# CONFIG_SK98LIN is not set
# CONFIG_VIA_VELOCITY is not set
# CONFIG_TIGON3 is not set
+# CONFIG_BNX2 is not set
+# CONFIG_QLA3XXX is not set
#
# Ethernet (10000 Mbit)
#
+# CONFIG_CHELSIO_T1 is not set
# CONFIG_IXGB is not set
# CONFIG_S2IO is not set
+# CONFIG_MYRI10GE is not set
#
# Token Ring devices
@@ -428,6 +569,8 @@ CONFIG_8139TOO=y
# CONFIG_SLIP is not set
# CONFIG_SHAPER is not set
# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
#
# ISDN subsystem
@@ -443,6 +586,7 @@ CONFIG_8139TOO=y
# Input device support
#
CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
#
# Userland interfaces
@@ -457,19 +601,6 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
# CONFIG_INPUT_EVBUG is not set
#
-# Input I/O drivers
-#
-# CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
-CONFIG_SERIO=y
-# CONFIG_SERIO_I8042 is not set
-# CONFIG_SERIO_SERPORT is not set
-# CONFIG_SERIO_CT82C710 is not set
-# CONFIG_SERIO_PCIPS2 is not set
-CONFIG_SERIO_LIBPS2=y
-# CONFIG_SERIO_RAW is not set
-
-#
# Input Device Drivers
#
CONFIG_INPUT_KEYBOARD=y
@@ -478,22 +609,33 @@ CONFIG_KEYBOARD_ATKBD=y
# CONFIG_KEYBOARD_LKKBD is not set
# CONFIG_KEYBOARD_XTKBD is not set
# CONFIG_KEYBOARD_NEWTON is not set
-# CONFIG_KEYBOARD_MAPLE is not set
+# CONFIG_KEYBOARD_STOWAWAY is not set
CONFIG_INPUT_MOUSE=y
CONFIG_MOUSE_PS2=y
# CONFIG_MOUSE_SERIAL is not set
-# CONFIG_MOUSE_MAPLE is not set
# CONFIG_MOUSE_VSXXXAA is not set
# CONFIG_INPUT_JOYSTICK is not set
# CONFIG_INPUT_TOUCHSCREEN is not set
# CONFIG_INPUT_MISC is not set
#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+# CONFIG_SERIO_I8042 is not set
+# CONFIG_SERIO_SERPORT is not set
+# CONFIG_SERIO_PCIPS2 is not set
+CONFIG_SERIO_LIBPS2=y
+# CONFIG_SERIO_RAW is not set
+# CONFIG_GAMEPORT is not set
+
+#
# Character devices
#
CONFIG_VT=y
CONFIG_VT_CONSOLE=y
CONFIG_HW_CONSOLE=y
+# CONFIG_VT_HW_CONSOLE_BINDING is not set
# CONFIG_SERIAL_NONSTANDARD is not set
#
@@ -505,9 +647,11 @@ CONFIG_HW_CONSOLE=y
# Non-8250 serial port support
#
CONFIG_SERIAL_SH_SCI=y
+CONFIG_SERIAL_SH_SCI_NR_UARTS=2
CONFIG_SERIAL_SH_SCI_CONSOLE=y
CONFIG_SERIAL_CORE=y
CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_JSM is not set
CONFIG_UNIX98_PTYS=y
CONFIG_LEGACY_PTYS=y
CONFIG_LEGACY_PTY_COUNT=256
@@ -528,13 +672,14 @@ CONFIG_WATCHDOG=y
#
# CONFIG_SOFT_WATCHDOG is not set
CONFIG_SH_WDT=y
+# CONFIG_SH_WDT_MMAP is not set
#
# PCI-based Watchdog Cards
#
# CONFIG_PCIPCWATCHDOG is not set
# CONFIG_WDTPCI is not set
-# CONFIG_RTC is not set
+CONFIG_HW_RANDOM=y
# CONFIG_GEN_RTC is not set
# CONFIG_DTLK is not set
# CONFIG_R3964 is not set
@@ -547,14 +692,35 @@ CONFIG_SH_WDT=y
# CONFIG_RAW_DRIVER is not set
#
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
+# CONFIG_TELCLOCK is not set
+
+#
# I2C support
#
# CONFIG_I2C is not set
#
+# SPI support
+#
+# CONFIG_SPI is not set
+# CONFIG_SPI_MASTER is not set
+
+#
# Dallas's 1-wire bus
#
-# CONFIG_W1 is not set
+
+#
+# Hardware Monitoring support
+#
+CONFIG_HWMON=y
+# CONFIG_HWMON_VID is not set
+# CONFIG_SENSORS_ABITUGURU is not set
+# CONFIG_SENSORS_F71805F is not set
+# CONFIG_SENSORS_VT1211 is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
#
# Misc devices
@@ -564,6 +730,7 @@ CONFIG_SH_WDT=y
# Multimedia devices
#
# CONFIG_VIDEO_DEV is not set
+CONFIG_VIDEO_V4L2=y
#
# Digital Video Broadcasting Devices
@@ -573,7 +740,13 @@ CONFIG_SH_WDT=y
#
# Graphics support
#
+CONFIG_FIRMWARE_EDID=y
CONFIG_FB=y
+CONFIG_FB_CFB_FILLRECT=y
+CONFIG_FB_CFB_COPYAREA=y
+CONFIG_FB_CFB_IMAGEBLIT=y
+# CONFIG_FB_MACMODES is not set
+# CONFIG_FB_BACKLIGHT is not set
# CONFIG_FB_MODE_HELPERS is not set
# CONFIG_FB_TILEBLITTING is not set
# CONFIG_FB_CIRRUS is not set
@@ -583,9 +756,10 @@ CONFIG_FB=y
# CONFIG_FB_IMSTT is not set
CONFIG_FB_PVR2=y
# CONFIG_FB_EPSON1355 is not set
+# CONFIG_FB_S1D13XXX is not set
+# CONFIG_FB_NVIDIA is not set
# CONFIG_FB_RIVA is not set
# CONFIG_FB_MATROX is not set
-# CONFIG_FB_RADEON_OLD is not set
# CONFIG_FB_RADEON is not set
# CONFIG_FB_ATY128 is not set
# CONFIG_FB_ATY is not set
@@ -601,18 +775,20 @@ CONFIG_FB_PVR2=y
#
# Console display driver support
#
-# CONFIG_VGA_CONSOLE is not set
CONFIG_DUMMY_CONSOLE=y
CONFIG_FRAMEBUFFER_CONSOLE=y
+# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
CONFIG_FONTS=y
CONFIG_FONT_8x8=y
CONFIG_FONT_8x16=y
# CONFIG_FONT_6x11 is not set
+# CONFIG_FONT_7x14 is not set
# CONFIG_FONT_PEARL_8x8 is not set
# CONFIG_FONT_ACORN_8x8 is not set
# CONFIG_FONT_MINI_4x6 is not set
# CONFIG_FONT_SUN8x16 is not set
# CONFIG_FONT_SUN12x22 is not set
+# CONFIG_FONT_10x18 is not set
#
# Logo configuration
@@ -634,12 +810,13 @@ CONFIG_LOGO_SUPERH_CLUT224=y
#
# USB support
#
-# CONFIG_USB is not set
CONFIG_USB_ARCH_HAS_HCD=y
CONFIG_USB_ARCH_HAS_OHCI=y
+CONFIG_USB_ARCH_HAS_EHCI=y
+# CONFIG_USB is not set
#
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
#
#
@@ -653,29 +830,64 @@ CONFIG_USB_ARCH_HAS_OHCI=y
# CONFIG_MMC is not set
#
+# LED devices
+#
+# CONFIG_NEW_LEDS is not set
+
+#
+# LED drivers
+#
+
+#
+# LED Triggers
+#
+
+#
# InfiniBand support
#
# CONFIG_INFINIBAND is not set
#
+# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
+#
+
+#
+# Real Time Clock
+#
+# CONFIG_RTC_CLASS is not set
+
+#
+# DMA Engine support
+#
+# CONFIG_DMA_ENGINE is not set
+
+#
+# DMA Clients
+#
+
+#
+# DMA Devices
+#
+
+#
# File systems
#
# CONFIG_EXT2_FS is not set
# CONFIG_EXT3_FS is not set
-# CONFIG_JBD is not set
# CONFIG_REISERFS_FS is not set
# CONFIG_JFS_FS is not set
-
-#
-# XFS support
-#
+# CONFIG_FS_POSIX_ACL is not set
# CONFIG_XFS_FS is not set
+# CONFIG_OCFS2_FS is not set
# CONFIG_MINIX_FS is not set
-CONFIG_ROMFS_FS=y
+# CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
# CONFIG_QUOTA is not set
-CONFIG_DNOTIFY=y
+# CONFIG_DNOTIFY is not set
# CONFIG_AUTOFS_FS is not set
# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
#
# CD-ROM/DVD Filesystems
@@ -695,16 +907,14 @@ CONFIG_DNOTIFY=y
#
CONFIG_PROC_FS=y
CONFIG_PROC_KCORE=y
+CONFIG_PROC_SYSCTL=y
CONFIG_SYSFS=y
-CONFIG_DEVFS_FS=y
-CONFIG_DEVFS_MOUNT=y
-# CONFIG_DEVFS_DEBUG is not set
-# CONFIG_DEVPTS_FS_XATTR is not set
CONFIG_TMPFS=y
-# CONFIG_TMPFS_XATTR is not set
+# CONFIG_TMPFS_POSIX_ACL is not set
CONFIG_HUGETLBFS=y
CONFIG_HUGETLB_PAGE=y
CONFIG_RAMFS=y
+# CONFIG_CONFIGFS_FS is not set
#
# Miscellaneous filesystems
@@ -716,7 +926,7 @@ CONFIG_RAMFS=y
# CONFIG_BEFS_FS is not set
# CONFIG_BFS_FS is not set
# CONFIG_EFS_FS is not set
-CONFIG_CRAMFS=y
+# CONFIG_CRAMFS is not set
# CONFIG_VXFS_FS is not set
# CONFIG_HPFS_FS is not set
# CONFIG_QNX4FS_FS is not set
@@ -726,22 +936,14 @@ CONFIG_CRAMFS=y
#
# Network File Systems
#
-CONFIG_NFS_FS=y
-CONFIG_NFS_V3=y
-# CONFIG_NFS_V4 is not set
-# CONFIG_NFS_DIRECTIO is not set
+# CONFIG_NFS_FS is not set
# CONFIG_NFSD is not set
-CONFIG_ROOT_NFS=y
-CONFIG_LOCKD=y
-CONFIG_LOCKD_V4=y
-CONFIG_SUNRPC=y
-# CONFIG_RPCSEC_GSS_KRB5 is not set
-# CONFIG_RPCSEC_GSS_SPKM3 is not set
# CONFIG_SMB_FS is not set
# CONFIG_CIFS is not set
# CONFIG_NCP_FS is not set
# CONFIG_CODA_FS is not set
# CONFIG_AFS_FS is not set
+# CONFIG_9P_FS is not set
#
# Partition Types
@@ -758,14 +960,19 @@ CONFIG_MSDOS_PARTITION=y
# Profiling support
#
CONFIG_PROFILING=y
-CONFIG_OPROFILE=y
+# CONFIG_OPROFILE is not set
#
# Kernel hacking
#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_MUST_CHECK=y
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_UNUSED_SYMBOLS is not set
# CONFIG_DEBUG_KERNEL is not set
-CONFIG_DEBUG_PREEMPT=y
-# CONFIG_FRAME_POINTER is not set
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_DEBUG_BUGVERBOSE is not set
+# CONFIG_DEBUG_FS is not set
# CONFIG_SH_STANDARD_BIOS is not set
# CONFIG_EARLY_SCIF_CONSOLE is not set
# CONFIG_KGDB is not set
@@ -782,13 +989,10 @@ CONFIG_DEBUG_PREEMPT=y
# CONFIG_CRYPTO is not set
#
-# Hardware crypto devices
-#
-
-#
# Library routines
#
# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
CONFIG_CRC32=y
# CONFIG_LIBCRC32C is not set
-CONFIG_ZLIB_INFLATE=y
+CONFIG_PLIST=y
diff --git a/arch/sh/configs/hp6xx_defconfig b/arch/sh/configs/hp6xx_defconfig
index b36f102cec81..b931d9b2d579 100644
--- a/arch/sh/configs/hp6xx_defconfig
+++ b/arch/sh/configs/hp6xx_defconfig
@@ -1,21 +1,21 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.15-sh
-# Wed Jan 4 15:32:56 2006
+# Linux kernel version: 2.6.18
+# Tue Oct 3 11:10:06 2006
#
CONFIG_SUPERH=y
-CONFIG_UID16=y
CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+CONFIG_GENERIC_HWEIGHT=y
CONFIG_GENERIC_HARDIRQS=y
CONFIG_GENERIC_IRQ_PROBE=y
CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
#
# Code maturity level options
#
CONFIG_EXPERIMENTAL=y
-# CONFIG_CLEAN_COMPILE is not set
-CONFIG_BROKEN=y
CONFIG_BROKEN_ON_SMP=y
CONFIG_INIT_ENV_ARG_LIMIT=32
@@ -27,26 +27,31 @@ CONFIG_LOCALVERSION_AUTO=y
CONFIG_SWAP=y
# CONFIG_SYSVIPC is not set
# CONFIG_BSD_PROCESS_ACCT is not set
-# CONFIG_SYSCTL is not set
-CONFIG_HOTPLUG=y
+# CONFIG_UTS_NS is not set
# CONFIG_IKCONFIG is not set
+# CONFIG_RELAY is not set
CONFIG_INITRAMFS_SOURCE=""
CONFIG_CC_OPTIMIZE_FOR_SIZE=y
-# CONFIG_EMBEDDED is not set
+CONFIG_SYSCTL=y
+CONFIG_EMBEDDED=y
+CONFIG_UID16=y
+# CONFIG_SYSCTL_SYSCALL is not set
CONFIG_KALLSYMS=y
# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
CONFIG_PRINTK=y
CONFIG_BUG=y
+CONFIG_ELF_CORE=y
CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
CONFIG_EPOLL=y
CONFIG_SHMEM=y
-CONFIG_CC_ALIGN_FUNCTIONS=0
-CONFIG_CC_ALIGN_LABELS=0
-CONFIG_CC_ALIGN_LOOPS=0
-CONFIG_CC_ALIGN_JUMPS=0
+CONFIG_SLAB=y
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_RT_MUTEXES=y
# CONFIG_TINY_SHMEM is not set
CONFIG_BASE_SMALL=0
+# CONFIG_SLOB is not set
#
# Loadable module support
@@ -56,7 +61,10 @@ CONFIG_BASE_SMALL=0
#
# Block layer
#
+CONFIG_BLOCK=y
# CONFIG_LBD is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_LSF is not set
#
# IO Schedulers
@@ -77,29 +85,26 @@ CONFIG_DEFAULT_IOSCHED="anticipatory"
# CONFIG_SH_SOLUTION_ENGINE is not set
# CONFIG_SH_7751_SOLUTION_ENGINE is not set
# CONFIG_SH_7300_SOLUTION_ENGINE is not set
+# CONFIG_SH_7343_SOLUTION_ENGINE is not set
# CONFIG_SH_73180_SOLUTION_ENGINE is not set
# CONFIG_SH_7751_SYSTEMH is not set
-# CONFIG_SH_STB1_HARP is not set
-# CONFIG_SH_STB1_OVERDRIVE is not set
CONFIG_SH_HP6XX=y
-# CONFIG_SH_CQREEK is not set
-# CONFIG_SH_DMIDA is not set
# CONFIG_SH_EC3104 is not set
# CONFIG_SH_SATURN is not set
# CONFIG_SH_DREAMCAST is not set
-# CONFIG_SH_CAT68701 is not set
# CONFIG_SH_BIGSUR is not set
-# CONFIG_SH_SH2000 is not set
-# CONFIG_SH_ADX is not set
# CONFIG_SH_MPC1211 is not set
# CONFIG_SH_SH03 is not set
# CONFIG_SH_SECUREEDGE5410 is not set
# CONFIG_SH_HS7751RVOIP is not set
+# CONFIG_SH_7710VOIPGW is not set
# CONFIG_SH_RTS7751R2D is not set
+# CONFIG_SH_R7780RP is not set
# CONFIG_SH_EDOSK7705 is not set
# CONFIG_SH_SH4202_MICRODEV is not set
# CONFIG_SH_LANDISK is not set
# CONFIG_SH_TITAN is not set
+# CONFIG_SH_SHMIN is not set
# CONFIG_SH_UNKNOWN is not set
#
@@ -117,9 +122,11 @@ CONFIG_CPU_SH3=y
#
# CONFIG_CPU_SUBTYPE_SH7300 is not set
# CONFIG_CPU_SUBTYPE_SH7705 is not set
+# CONFIG_CPU_SUBTYPE_SH7706 is not set
# CONFIG_CPU_SUBTYPE_SH7707 is not set
# CONFIG_CPU_SUBTYPE_SH7708 is not set
CONFIG_CPU_SUBTYPE_SH7709=y
+# CONFIG_CPU_SUBTYPE_SH7710 is not set
#
# SH-4 Processor Support
@@ -142,14 +149,23 @@ CONFIG_CPU_SUBTYPE_SH7709=y
#
# SH-4A Processor Support
#
-# CONFIG_CPU_SUBTYPE_SH73180 is not set
# CONFIG_CPU_SUBTYPE_SH7770 is not set
# CONFIG_CPU_SUBTYPE_SH7780 is not set
#
+# SH4AL-DSP Processor Support
+#
+# CONFIG_CPU_SUBTYPE_SH73180 is not set
+# CONFIG_CPU_SUBTYPE_SH7343 is not set
+
+#
# Memory management options
#
CONFIG_MMU=y
+CONFIG_PAGE_OFFSET=0x80000000
+CONFIG_MEMORY_START=0x0c000000
+CONFIG_MEMORY_SIZE=0x00400000
+CONFIG_VSYSCALL=y
CONFIG_SELECT_MEMORY_MODEL=y
CONFIG_FLATMEM_MANUAL=y
# CONFIG_DISCONTIGMEM_MANUAL is not set
@@ -158,6 +174,7 @@ CONFIG_FLATMEM=y
CONFIG_FLAT_NODE_MEM_MAP=y
# CONFIG_SPARSEMEM_STATIC is not set
CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_RESOURCES_64BIT is not set
#
# Cache configuration
@@ -165,22 +182,22 @@ CONFIG_SPLIT_PTLOCK_CPUS=4
# CONFIG_SH_DIRECT_MAPPED is not set
# CONFIG_SH_WRITETHROUGH is not set
# CONFIG_SH_OCRAM is not set
-CONFIG_MEMORY_START=0x0c000000
-CONFIG_MEMORY_SIZE=0x00400000
#
# Processor features
#
CONFIG_CPU_LITTLE_ENDIAN=y
-CONFIG_SH_RTC=y
+# CONFIG_SH_FPU_EMU is not set
# CONFIG_SH_DSP is not set
CONFIG_SH_ADC=y
+CONFIG_CPU_HAS_INTEVT=y
+CONFIG_CPU_HAS_PINT_IRQ=y
+CONFIG_CPU_HAS_SR_RB=y
#
# Timer support
#
CONFIG_SH_TMU=y
-CONFIG_SH_PCLK_FREQ_BOOL=y
CONFIG_SH_PCLK_FREQ=22110000
#
@@ -194,7 +211,6 @@ CONFIG_SH_PCLK_FREQ=22110000
CONFIG_SH_DMA=y
CONFIG_NR_ONCHIP_DMA_CHANNELS=4
# CONFIG_NR_DMA_CHANNELS_BOOL is not set
-# CONFIG_DMA_PAGE_OPS is not set
#
# Companion Chips
@@ -209,9 +225,15 @@ CONFIG_HD64461_ENABLER=y
#
# Kernel features
#
+# CONFIG_HZ_100 is not set
+CONFIG_HZ_250=y
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=250
# CONFIG_KEXEC is not set
-# CONFIG_PREEMPT is not set
# CONFIG_SMP is not set
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
+# CONFIG_PREEMPT is not set
#
# Boot options
@@ -241,8 +263,6 @@ CONFIG_PCMCIA_IOCTL=y
#
# CONFIG_I82365 is not set
# CONFIG_TCIC is not set
-CONFIG_HD64461_PCMCIA=y
-CONFIG_HD64461_PCMCIA_SOCKETS=1
CONFIG_PCMCIA_PROBE=y
#
@@ -257,6 +277,15 @@ CONFIG_BINFMT_ELF=y
# CONFIG_BINFMT_MISC is not set
#
+# Power management options (EXPERIMENTAL)
+#
+CONFIG_PM=y
+CONFIG_PM_LEGACY=y
+# CONFIG_PM_DEBUG is not set
+# CONFIG_PM_SYSFS_DEPRECATED is not set
+CONFIG_APM=y
+
+#
# Networking
#
# CONFIG_NET is not set
@@ -271,6 +300,7 @@ CONFIG_BINFMT_ELF=y
# CONFIG_STANDALONE is not set
CONFIG_PREVENT_FIRMWARE_BUILD=y
CONFIG_FW_LOADER=y
+# CONFIG_SYS_HYPERVISOR is not set
#
# Connector - unified userspace <-> kernelspace linker
@@ -299,6 +329,7 @@ CONFIG_FW_LOADER=y
CONFIG_BLK_DEV_RAM=y
CONFIG_BLK_DEV_RAM_COUNT=16
CONFIG_BLK_DEV_RAM_SIZE=4096
+CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
CONFIG_BLK_DEV_INITRD=y
# CONFIG_CDROM_PKTCDVD is not set
@@ -315,7 +346,7 @@ CONFIG_BLK_DEV_IDE=y
# CONFIG_BLK_DEV_IDE_SATA is not set
CONFIG_BLK_DEV_IDEDISK=y
# CONFIG_IDEDISK_MULTI_MODE is not set
-# CONFIG_BLK_DEV_IDECS is not set
+CONFIG_BLK_DEV_IDECS=y
# CONFIG_BLK_DEV_IDECD is not set
# CONFIG_BLK_DEV_IDETAPE is not set
# CONFIG_BLK_DEV_IDEFLOPPY is not set
@@ -325,7 +356,6 @@ CONFIG_BLK_DEV_IDEDISK=y
# IDE chipset support/bugfixes
#
CONFIG_IDE_GENERIC=y
-CONFIG_IDE_SH=y
# CONFIG_IDE_ARM is not set
# CONFIG_IDE_CHIPSETS is not set
# CONFIG_BLK_DEV_IDEDMA is not set
@@ -337,6 +367,12 @@ CONFIG_IDE_SH=y
#
# CONFIG_RAID_ATTRS is not set
# CONFIG_SCSI is not set
+# CONFIG_SCSI_NETLINK is not set
+
+#
+# Serial ATA (prod) and Parallel ATA (experimental) drivers
+#
+# CONFIG_ATA is not set
#
# Old CD-ROM drivers (not SCSI, not IDE)
@@ -356,19 +392,12 @@ CONFIG_IDE_SH=y
#
# IEEE 1394 (FireWire) support
#
-# CONFIG_IEEE1394 is not set
#
# I2O device support
#
#
-# Network device support
-#
-# CONFIG_NETPOLL is not set
-# CONFIG_NET_POLL_CONTROLLER is not set
-
-#
# ISDN subsystem
#
@@ -381,6 +410,7 @@ CONFIG_IDE_SH=y
# Input device support
#
CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
#
# Userland interfaces
@@ -390,17 +420,33 @@ CONFIG_INPUT_MOUSEDEV_PSAUX=y
CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
# CONFIG_INPUT_JOYDEV is not set
-# CONFIG_INPUT_TSDEV is not set
+CONFIG_INPUT_TSDEV=y
+CONFIG_INPUT_TSDEV_SCREEN_X=240
+CONFIG_INPUT_TSDEV_SCREEN_Y=320
# CONFIG_INPUT_EVDEV is not set
# CONFIG_INPUT_EVBUG is not set
#
# Input Device Drivers
#
-# CONFIG_INPUT_KEYBOARD is not set
+CONFIG_INPUT_KEYBOARD=y
+# CONFIG_KEYBOARD_ATKBD is not set
+# CONFIG_KEYBOARD_SUNKBD is not set
+# CONFIG_KEYBOARD_LKKBD is not set
+# CONFIG_KEYBOARD_XTKBD is not set
+# CONFIG_KEYBOARD_NEWTON is not set
+# CONFIG_KEYBOARD_STOWAWAY is not set
# CONFIG_INPUT_MOUSE is not set
# CONFIG_INPUT_JOYSTICK is not set
-# CONFIG_INPUT_TOUCHSCREEN is not set
+CONFIG_INPUT_TOUCHSCREEN=y
+# CONFIG_TOUCHSCREEN_GUNZE is not set
+# CONFIG_TOUCHSCREEN_ELO is not set
+# CONFIG_TOUCHSCREEN_MTOUCH is not set
+# CONFIG_TOUCHSCREEN_MK712 is not set
+CONFIG_TOUCHSCREEN_HP600=y
+# CONFIG_TOUCHSCREEN_PENMOUNT is not set
+# CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set
+# CONFIG_TOUCHSCREEN_TOUCHWIN is not set
# CONFIG_INPUT_MISC is not set
#
@@ -409,6 +455,7 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
CONFIG_SERIO=y
# CONFIG_SERIO_I8042 is not set
# CONFIG_SERIO_SERPORT is not set
+# CONFIG_SERIO_LIBPS2 is not set
# CONFIG_SERIO_RAW is not set
# CONFIG_GAMEPORT is not set
@@ -418,6 +465,7 @@ CONFIG_SERIO=y
CONFIG_VT=y
CONFIG_VT_CONSOLE=y
CONFIG_HW_CONSOLE=y
+# CONFIG_VT_HW_CONSOLE_BINDING is not set
# CONFIG_SERIAL_NONSTANDARD is not set
#
@@ -442,7 +490,7 @@ CONFIG_LEGACY_PTY_COUNT=256
# Watchdog Cards
#
# CONFIG_WATCHDOG is not set
-# CONFIG_RTC is not set
+CONFIG_HW_RANDOM=y
# CONFIG_GEN_RTC is not set
# CONFIG_DTLK is not set
# CONFIG_R3964 is not set
@@ -471,15 +519,23 @@ CONFIG_LEGACY_PTY_COUNT=256
# CONFIG_I2C is not set
#
+# SPI support
+#
+# CONFIG_SPI is not set
+# CONFIG_SPI_MASTER is not set
+
+#
# Dallas's 1-wire bus
#
-# CONFIG_W1 is not set
#
# Hardware Monitoring support
#
CONFIG_HWMON=y
# CONFIG_HWMON_VID is not set
+# CONFIG_SENSORS_ABITUGURU is not set
+# CONFIG_SENSORS_F71805F is not set
+# CONFIG_SENSORS_VT1211 is not set
# CONFIG_HWMON_DEBUG_CHIP is not set
#
@@ -487,13 +543,10 @@ CONFIG_HWMON=y
#
#
-# Multimedia Capabilities Port drivers
-#
-
-#
# Multimedia devices
#
# CONFIG_VIDEO_DEV is not set
+CONFIG_VIDEO_V4L2=y
#
# Digital Video Broadcasting Devices
@@ -502,11 +555,13 @@ CONFIG_HWMON=y
#
# Graphics support
#
+CONFIG_FIRMWARE_EDID=y
CONFIG_FB=y
CONFIG_FB_CFB_FILLRECT=y
CONFIG_FB_CFB_COPYAREA=y
CONFIG_FB_CFB_IMAGEBLIT=y
# CONFIG_FB_MACMODES is not set
+# CONFIG_FB_BACKLIGHT is not set
# CONFIG_FB_MODE_HELPERS is not set
# CONFIG_FB_TILEBLITTING is not set
# CONFIG_FB_EPSON1355 is not set
@@ -553,7 +608,7 @@ CONFIG_SOUND=y
# Open Sound System
#
CONFIG_SOUND_PRIME=y
-# CONFIG_OBSOLETE_OSS_DRIVER is not set
+# CONFIG_OSS_OBSOLETE_DRIVER is not set
# CONFIG_SOUND_MSNDCLAS is not set
# CONFIG_SOUND_MSNDPIN is not set
CONFIG_SOUND_SH_DAC_AUDIO=y
@@ -564,6 +619,7 @@ CONFIG_SOUND_SH_DAC_AUDIO_CHANNEL=1
#
# CONFIG_USB_ARCH_HAS_HCD is not set
# CONFIG_USB_ARCH_HAS_OHCI is not set
+# CONFIG_USB_ARCH_HAS_EHCI is not set
#
# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
@@ -580,12 +636,42 @@ CONFIG_SOUND_SH_DAC_AUDIO_CHANNEL=1
# CONFIG_MMC is not set
#
+# LED devices
+#
+# CONFIG_NEW_LEDS is not set
+
+#
+# LED drivers
+#
+
+#
+# LED Triggers
+#
+
+#
# InfiniBand support
#
-# CONFIG_INFINIBAND is not set
#
-# SN Devices
+# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
+#
+
+#
+# Real Time Clock
+#
+# CONFIG_RTC_CLASS is not set
+
+#
+# DMA Engine support
+#
+# CONFIG_DMA_ENGINE is not set
+
+#
+# DMA Clients
+#
+
+#
+# DMA Devices
#
#
@@ -595,7 +681,6 @@ CONFIG_EXT2_FS=y
# CONFIG_EXT2_FS_XATTR is not set
# CONFIG_EXT2_FS_XIP is not set
# CONFIG_EXT3_FS is not set
-# CONFIG_JBD is not set
# CONFIG_REISERFS_FS is not set
# CONFIG_JFS_FS is not set
# CONFIG_FS_POSIX_ACL is not set
@@ -603,6 +688,7 @@ CONFIG_EXT2_FS=y
# CONFIG_MINIX_FS is not set
# CONFIG_ROMFS_FS is not set
CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
# CONFIG_QUOTA is not set
CONFIG_DNOTIFY=y
# CONFIG_AUTOFS_FS is not set
@@ -630,12 +716,13 @@ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
#
CONFIG_PROC_FS=y
CONFIG_PROC_KCORE=y
+CONFIG_PROC_SYSCTL=y
CONFIG_SYSFS=y
# CONFIG_TMPFS is not set
# CONFIG_HUGETLBFS is not set
# CONFIG_HUGETLB_PAGE is not set
CONFIG_RAMFS=y
-# CONFIG_RELAYFS_FS is not set
+# CONFIG_CONFIGFS_FS is not set
#
# Miscellaneous filesystems
@@ -713,9 +800,14 @@ CONFIG_NLS_DEFAULT="iso8859-1"
# Kernel hacking
#
# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_MUST_CHECK=y
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_UNUSED_SYMBOLS is not set
# CONFIG_DEBUG_KERNEL is not set
CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_FRAME_POINTER is not set
+# CONFIG_DEBUG_BUGVERBOSE is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_UNWIND_INFO is not set
# CONFIG_SH_STANDARD_BIOS is not set
# CONFIG_KGDB is not set
@@ -731,13 +823,10 @@ CONFIG_LOG_BUF_SHIFT=14
# CONFIG_CRYPTO is not set
#
-# Hardware crypto devices
-#
-
-#
# Library routines
#
# CONFIG_CRC_CCITT is not set
# CONFIG_CRC16 is not set
CONFIG_CRC32=y
# CONFIG_LIBCRC32C is not set
+CONFIG_PLIST=y
diff --git a/arch/sh/configs/hs7751rvoip_defconfig b/arch/sh/configs/hs7751rvoip_defconfig
new file mode 100644
index 000000000000..e1a886d621db
--- /dev/null
+++ b/arch/sh/configs/hs7751rvoip_defconfig
@@ -0,0 +1,908 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.18
+# Tue Oct 3 13:04:52 2006
+#
+CONFIG_SUPERH=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_LOCK_KERNEL=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+# CONFIG_IPC_NS is not set
+CONFIG_POSIX_MQUEUE=y
+CONFIG_BSD_PROCESS_ACCT=y
+# CONFIG_BSD_PROCESS_ACCT_V3 is not set
+# CONFIG_TASKSTATS is not set
+# CONFIG_UTS_NS is not set
+# CONFIG_AUDIT is not set
+# CONFIG_IKCONFIG is not set
+# CONFIG_RELAY is not set
+CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SYSCTL=y
+CONFIG_EMBEDDED=y
+CONFIG_UID16=y
+# CONFIG_SYSCTL_SYSCALL is not set
+# CONFIG_KALLSYMS is not set
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+CONFIG_SHMEM=y
+CONFIG_SLAB=y
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_RT_MUTEXES=y
+# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+# CONFIG_SLOB is not set
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_KMOD=y
+
+#
+# Block layer
+#
+CONFIG_BLOCK=y
+# CONFIG_LBD is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_LSF is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+CONFIG_DEFAULT_AS=y
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="anticipatory"
+
+#
+# System type
+#
+# CONFIG_SH_SOLUTION_ENGINE is not set
+# CONFIG_SH_7751_SOLUTION_ENGINE is not set
+# CONFIG_SH_7300_SOLUTION_ENGINE is not set
+# CONFIG_SH_7343_SOLUTION_ENGINE is not set
+# CONFIG_SH_73180_SOLUTION_ENGINE is not set
+# CONFIG_SH_7751_SYSTEMH is not set
+# CONFIG_SH_HP6XX is not set
+# CONFIG_SH_EC3104 is not set
+# CONFIG_SH_SATURN is not set
+# CONFIG_SH_DREAMCAST is not set
+# CONFIG_SH_BIGSUR is not set
+# CONFIG_SH_MPC1211 is not set
+# CONFIG_SH_SH03 is not set
+# CONFIG_SH_SECUREEDGE5410 is not set
+CONFIG_SH_HS7751RVOIP=y
+# CONFIG_SH_7710VOIPGW is not set
+# CONFIG_SH_RTS7751R2D is not set
+# CONFIG_SH_R7780RP is not set
+# CONFIG_SH_EDOSK7705 is not set
+# CONFIG_SH_SH4202_MICRODEV is not set
+# CONFIG_SH_LANDISK is not set
+# CONFIG_SH_TITAN is not set
+# CONFIG_SH_SHMIN is not set
+# CONFIG_SH_UNKNOWN is not set
+
+#
+# Processor selection
+#
+CONFIG_CPU_SH4=y
+
+#
+# SH-2 Processor Support
+#
+# CONFIG_CPU_SUBTYPE_SH7604 is not set
+
+#
+# SH-3 Processor Support
+#
+# CONFIG_CPU_SUBTYPE_SH7300 is not set
+# CONFIG_CPU_SUBTYPE_SH7705 is not set
+# CONFIG_CPU_SUBTYPE_SH7706 is not set
+# CONFIG_CPU_SUBTYPE_SH7707 is not set
+# CONFIG_CPU_SUBTYPE_SH7708 is not set
+# CONFIG_CPU_SUBTYPE_SH7709 is not set
+# CONFIG_CPU_SUBTYPE_SH7710 is not set
+
+#
+# SH-4 Processor Support
+#
+# CONFIG_CPU_SUBTYPE_SH7750 is not set
+# CONFIG_CPU_SUBTYPE_SH7091 is not set
+# CONFIG_CPU_SUBTYPE_SH7750R is not set
+# CONFIG_CPU_SUBTYPE_SH7750S is not set
+CONFIG_CPU_SUBTYPE_SH7751=y
+CONFIG_CPU_SUBTYPE_SH7751R=y
+# CONFIG_CPU_SUBTYPE_SH7760 is not set
+# CONFIG_CPU_SUBTYPE_SH4_202 is not set
+
+#
+# ST40 Processor Support
+#
+# CONFIG_CPU_SUBTYPE_ST40STB1 is not set
+# CONFIG_CPU_SUBTYPE_ST40GX1 is not set
+
+#
+# SH-4A Processor Support
+#
+# CONFIG_CPU_SUBTYPE_SH7770 is not set
+# CONFIG_CPU_SUBTYPE_SH7780 is not set
+
+#
+# SH4AL-DSP Processor Support
+#
+# CONFIG_CPU_SUBTYPE_SH73180 is not set
+# CONFIG_CPU_SUBTYPE_SH7343 is not set
+
+#
+# Memory management options
+#
+CONFIG_MMU=y
+CONFIG_PAGE_OFFSET=0x80000000
+CONFIG_MEMORY_START=0x0c000000
+CONFIG_MEMORY_SIZE=0x04000000
+CONFIG_VSYSCALL=y
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+# CONFIG_SPARSEMEM_STATIC is not set
+CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_RESOURCES_64BIT is not set
+
+#
+# Cache configuration
+#
+# CONFIG_SH_DIRECT_MAPPED is not set
+# CONFIG_SH_WRITETHROUGH is not set
+# CONFIG_SH_OCRAM is not set
+
+#
+# Processor features
+#
+CONFIG_CPU_LITTLE_ENDIAN=y
+CONFIG_SH_FPU=y
+# CONFIG_SH_DSP is not set
+# CONFIG_SH_STORE_QUEUES is not set
+CONFIG_CPU_HAS_INTEVT=y
+CONFIG_CPU_HAS_SR_RB=y
+
+#
+# Timer support
+#
+CONFIG_SH_TMU=y
+
+#
+# HS7751RVoIP options
+#
+CONFIG_HS7751RVOIP_CODEC=y
+CONFIG_SH_PCLK_FREQ=60000000
+
+#
+# CPU Frequency scaling
+#
+# CONFIG_CPU_FREQ is not set
+
+#
+# DMA support
+#
+# CONFIG_SH_DMA is not set
+
+#
+# Companion Chips
+#
+# CONFIG_HD6446X_SERIES is not set
+
+#
+# Kernel features
+#
+# CONFIG_HZ_100 is not set
+CONFIG_HZ_250=y
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=250
+# CONFIG_KEXEC is not set
+# CONFIG_SMP is not set
+# CONFIG_PREEMPT_NONE is not set
+# CONFIG_PREEMPT_VOLUNTARY is not set
+CONFIG_PREEMPT=y
+CONFIG_PREEMPT_BKL=y
+
+#
+# Boot options
+#
+CONFIG_ZERO_PAGE_OFFSET=0x00001000
+CONFIG_BOOT_LINK_OFFSET=0x00800000
+# CONFIG_UBC_WAKEUP is not set
+CONFIG_CMDLINE_BOOL=y
+CONFIG_CMDLINE="mem=64M console=ttySC1,115200 root=/dev/hda1"
+
+#
+# Bus options
+#
+# CONFIG_PCI is not set
+
+#
+# PCCARD (PCMCIA/CardBus) support
+#
+# CONFIG_PCCARD is not set
+
+#
+# PCI Hotplug Support
+#
+
+#
+# Executable file formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_FLAT is not set
+# CONFIG_BINFMT_MISC is not set
+
+#
+# Power management options (EXPERIMENTAL)
+#
+# CONFIG_PM is not set
+
+#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+# CONFIG_NETDEBUG is not set
+CONFIG_PACKET=y
+CONFIG_PACKET_MMAP=y
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+# CONFIG_XFRM_USER is not set
+# CONFIG_XFRM_SUB_POLICY is not set
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_ADVANCED_ROUTER=y
+CONFIG_ASK_IP_FIB_HASH=y
+# CONFIG_IP_FIB_TRIE is not set
+CONFIG_IP_FIB_HASH=y
+# CONFIG_IP_MULTIPLE_TABLES is not set
+# CONFIG_IP_ROUTE_MULTIPATH is not set
+# CONFIG_IP_ROUTE_VERBOSE is not set
+# CONFIG_IP_PNP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_IP_MROUTE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+# CONFIG_INET_TUNNEL is not set
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_IPV6 is not set
+# CONFIG_INET6_XFRM_TUNNEL is not set
+# CONFIG_INET6_TUNNEL is not set
+# CONFIG_NETWORK_SECMARK is not set
+# CONFIG_NETFILTER is not set
+
+#
+# DCCP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_DCCP is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP is not set
+
+#
+# TIPC Configuration (EXPERIMENTAL)
+#
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_IEEE80211 is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=m
+# CONFIG_SYS_HYPERVISOR is not set
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
+# CONFIG_CONNECTOR is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+# CONFIG_MTD is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Plug and Play support
+#
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_COW_COMMON is not set
+# CONFIG_BLK_DEV_LOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_RAM is not set
+# CONFIG_BLK_DEV_INITRD is not set
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+
+#
+# ATA/ATAPI/MFM/RLL support
+#
+CONFIG_IDE=y
+CONFIG_IDE_MAX_HWIFS=1
+CONFIG_BLK_DEV_IDE=y
+
+#
+# Please see Documentation/ide.txt for help/info on IDE drives
+#
+# CONFIG_BLK_DEV_IDE_SATA is not set
+CONFIG_BLK_DEV_IDEDISK=y
+# CONFIG_IDEDISK_MULTI_MODE is not set
+# CONFIG_BLK_DEV_IDECD is not set
+# CONFIG_BLK_DEV_IDETAPE is not set
+# CONFIG_BLK_DEV_IDEFLOPPY is not set
+# CONFIG_IDE_TASK_IOCTL is not set
+
+#
+# IDE chipset support/bugfixes
+#
+CONFIG_IDE_GENERIC=y
+# CONFIG_IDE_ARM is not set
+# CONFIG_BLK_DEV_IDEDMA is not set
+# CONFIG_IDEDMA_AUTO is not set
+# CONFIG_BLK_DEV_HD is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+# CONFIG_SCSI is not set
+# CONFIG_SCSI_NETLINK is not set
+
+#
+# Serial ATA (prod) and Parallel ATA (experimental) drivers
+#
+# CONFIG_ATA is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+
+#
+# Fusion MPT device support
+#
+# CONFIG_FUSION is not set
+
+#
+# IEEE 1394 (FireWire) support
+#
+
+#
+# I2O device support
+#
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+
+#
+# PHY device support
+#
+# CONFIG_PHYLIB is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+# CONFIG_STNIC is not set
+# CONFIG_SMC91X is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+
+#
+# Ethernet (10000 Mbit)
+#
+
+#
+# Token Ring devices
+#
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_SHAPER is not set
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Telephony Support
+#
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
+
+#
+# Userland interfaces
+#
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_TSDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+CONFIG_SERIO_I8042=y
+CONFIG_SERIO_SERPORT=y
+# CONFIG_SERIO_LIBPS2 is not set
+# CONFIG_SERIO_RAW is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+# CONFIG_VT is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_SH_SCI=y
+CONFIG_SERIAL_SH_SCI_NR_UARTS=2
+CONFIG_SERIAL_SH_SCI_CONSOLE=y
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+# CONFIG_LEGACY_PTYS is not set
+
+#
+# IPMI
+#
+# CONFIG_IPMI_HANDLER is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+CONFIG_HW_RANDOM=y
+# CONFIG_GEN_RTC is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_RAW_DRIVER is not set
+
+#
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
+# CONFIG_TELCLOCK is not set
+
+#
+# I2C support
+#
+# CONFIG_I2C is not set
+
+#
+# SPI support
+#
+# CONFIG_SPI is not set
+# CONFIG_SPI_MASTER is not set
+
+#
+# Dallas's 1-wire bus
+#
+
+#
+# Hardware Monitoring support
+#
+CONFIG_HWMON=y
+# CONFIG_HWMON_VID is not set
+# CONFIG_SENSORS_ABITUGURU is not set
+# CONFIG_SENSORS_F71805F is not set
+# CONFIG_SENSORS_VT1211 is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
+
+#
+# Misc devices
+#
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+CONFIG_VIDEO_V4L2=y
+
+#
+# Digital Video Broadcasting Devices
+#
+# CONFIG_DVB is not set
+
+#
+# Graphics support
+#
+CONFIG_FIRMWARE_EDID=y
+# CONFIG_FB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# USB support
+#
+# CONFIG_USB_ARCH_HAS_HCD is not set
+# CONFIG_USB_ARCH_HAS_OHCI is not set
+# CONFIG_USB_ARCH_HAS_EHCI is not set
+
+#
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
+#
+
+#
+# USB Gadget Support
+#
+# CONFIG_USB_GADGET is not set
+
+#
+# MMC/SD Card support
+#
+# CONFIG_MMC is not set
+
+#
+# LED devices
+#
+# CONFIG_NEW_LEDS is not set
+
+#
+# LED drivers
+#
+
+#
+# LED Triggers
+#
+
+#
+# InfiniBand support
+#
+
+#
+# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
+#
+
+#
+# Real Time Clock
+#
+# CONFIG_RTC_CLASS is not set
+
+#
+# DMA Engine support
+#
+# CONFIG_DMA_ENGINE is not set
+
+#
+# DMA Clients
+#
+
+#
+# DMA Devices
+#
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_OCFS2_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+# CONFIG_QUOTA is not set
+CONFIG_DNOTIFY=y
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+# CONFIG_MSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_KCORE=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
+# CONFIG_HUGETLBFS is not set
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_RAMFS=y
+# CONFIG_CONFIGFS_FS is not set
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+
+#
+# Network File Systems
+#
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
+CONFIG_NFS_V4=y
+CONFIG_NFS_DIRECTIO=y
+# CONFIG_NFSD is not set
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+CONFIG_SUNRPC_GSS=y
+CONFIG_RPCSEC_GSS_KRB5=y
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+# CONFIG_9P_FS is not set
+
+#
+# Partition Types
+#
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_ACORN_PARTITION is not set
+# CONFIG_OSF_PARTITION is not set
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
+# CONFIG_MAC_PARTITION is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_BSD_DISKLABEL is not set
+# CONFIG_MINIX_SUBPARTITION is not set
+# CONFIG_SOLARIS_X86_PARTITION is not set
+# CONFIG_UNIXWARE_DISKLABEL is not set
+# CONFIG_LDM_PARTITION is not set
+# CONFIG_SGI_PARTITION is not set
+# CONFIG_ULTRIX_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+# CONFIG_KARMA_PARTITION is not set
+# CONFIG_EFI_PARTITION is not set
+
+#
+# Native Language Support
+#
+# CONFIG_NLS is not set
+
+#
+# Profiling support
+#
+# CONFIG_PROFILING is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_MUST_CHECK=y
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_KERNEL is not set
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_DEBUG_BUGVERBOSE is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_SH_STANDARD_BIOS is not set
+# CONFIG_EARLY_SCIF_CONSOLE is not set
+# CONFIG_KGDB is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+
+#
+# Cryptographic options
+#
+CONFIG_CRYPTO=y
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_BLKCIPHER=m
+CONFIG_CRYPTO_MANAGER=m
+# CONFIG_CRYPTO_HMAC is not set
+# CONFIG_CRYPTO_NULL is not set
+# CONFIG_CRYPTO_MD4 is not set
+CONFIG_CRYPTO_MD5=y
+# CONFIG_CRYPTO_SHA1 is not set
+# CONFIG_CRYPTO_SHA256 is not set
+# CONFIG_CRYPTO_SHA512 is not set
+# CONFIG_CRYPTO_WP512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
+CONFIG_CRYPTO_ECB=m
+CONFIG_CRYPTO_CBC=m
+CONFIG_CRYPTO_DES=y
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_AES is not set
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+# CONFIG_CRYPTO_TEA is not set
+# CONFIG_CRYPTO_ARC4 is not set
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_ANUBIS is not set
+# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# Hardware crypto devices
+#
+
+#
+# Library routines
+#
+# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
+CONFIG_CRC32=y
+# CONFIG_LIBCRC32C is not set
+CONFIG_PLIST=y
diff --git a/arch/sh/configs/landisk_defconfig b/arch/sh/configs/landisk_defconfig
index 6b43316d03cf..238c0f109907 100644
--- a/arch/sh/configs/landisk_defconfig
+++ b/arch/sh/configs/landisk_defconfig
@@ -1,21 +1,21 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.13-sh
-# Sun Sep 11 13:00:46 2005
+# Linux kernel version: 2.6.18
+# Tue Oct 3 11:14:13 2006
#
CONFIG_SUPERH=y
-CONFIG_UID16=y
CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+CONFIG_GENERIC_HWEIGHT=y
CONFIG_GENERIC_HARDIRQS=y
CONFIG_GENERIC_IRQ_PROBE=y
CONFIG_GENERIC_CALIBRATE_DELAY=y
-CONFIG_GENERIC_IOMAP=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
#
# Code maturity level options
#
CONFIG_EXPERIMENTAL=y
-CONFIG_CLEAN_COMPILE=y
CONFIG_BROKEN_ON_SMP=y
CONFIG_INIT_ENV_ARG_LIMIT=32
@@ -26,29 +26,36 @@ CONFIG_LOCALVERSION=""
CONFIG_LOCALVERSION_AUTO=y
CONFIG_SWAP=y
CONFIG_SYSVIPC=y
+# CONFIG_IPC_NS is not set
# CONFIG_POSIX_MQUEUE is not set
# CONFIG_BSD_PROCESS_ACCT is not set
-CONFIG_SYSCTL=y
+# CONFIG_TASKSTATS is not set
+# CONFIG_UTS_NS is not set
# CONFIG_AUDIT is not set
-CONFIG_HOTPLUG=y
-CONFIG_KOBJECT_UEVENT=y
# CONFIG_IKCONFIG is not set
+# CONFIG_RELAY is not set
CONFIG_INITRAMFS_SOURCE=""
-# CONFIG_EMBEDDED is not set
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
+CONFIG_EMBEDDED=y
+CONFIG_UID16=y
+# CONFIG_SYSCTL_SYSCALL is not set
CONFIG_KALLSYMS=y
CONFIG_KALLSYMS_EXTRA_PASS=y
+CONFIG_HOTPLUG=y
CONFIG_PRINTK=y
CONFIG_BUG=y
+CONFIG_ELF_CORE=y
CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
CONFIG_EPOLL=y
CONFIG_SHMEM=y
-CONFIG_CC_ALIGN_FUNCTIONS=0
-CONFIG_CC_ALIGN_LABELS=0
-CONFIG_CC_ALIGN_LOOPS=0
-CONFIG_CC_ALIGN_JUMPS=0
+CONFIG_SLAB=y
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_RT_MUTEXES=y
# CONFIG_TINY_SHMEM is not set
CONFIG_BASE_SMALL=0
+# CONFIG_SLOB is not set
#
# Loadable module support
@@ -56,40 +63,57 @@ CONFIG_BASE_SMALL=0
CONFIG_MODULES=y
CONFIG_MODULE_UNLOAD=y
CONFIG_MODULE_FORCE_UNLOAD=y
-CONFIG_OBSOLETE_MODPARM=y
# CONFIG_MODVERSIONS is not set
# CONFIG_MODULE_SRCVERSION_ALL is not set
CONFIG_KMOD=y
#
+# Block layer
+#
+CONFIG_BLOCK=y
+# CONFIG_LBD is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_LSF is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+CONFIG_DEFAULT_AS=y
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="anticipatory"
+
+#
# System type
#
# CONFIG_SH_SOLUTION_ENGINE is not set
# CONFIG_SH_7751_SOLUTION_ENGINE is not set
# CONFIG_SH_7300_SOLUTION_ENGINE is not set
+# CONFIG_SH_7343_SOLUTION_ENGINE is not set
# CONFIG_SH_73180_SOLUTION_ENGINE is not set
# CONFIG_SH_7751_SYSTEMH is not set
-# CONFIG_SH_STB1_HARP is not set
-# CONFIG_SH_STB1_OVERDRIVE is not set
# CONFIG_SH_HP6XX is not set
-# CONFIG_SH_CQREEK is not set
-# CONFIG_SH_DMIDA is not set
# CONFIG_SH_EC3104 is not set
# CONFIG_SH_SATURN is not set
# CONFIG_SH_DREAMCAST is not set
-# CONFIG_SH_CAT68701 is not set
# CONFIG_SH_BIGSUR is not set
-# CONFIG_SH_SH2000 is not set
-# CONFIG_SH_ADX is not set
# CONFIG_SH_MPC1211 is not set
# CONFIG_SH_SH03 is not set
# CONFIG_SH_SECUREEDGE5410 is not set
# CONFIG_SH_HS7751RVOIP is not set
+# CONFIG_SH_7710VOIPGW is not set
# CONFIG_SH_RTS7751R2D is not set
+# CONFIG_SH_R7780RP is not set
# CONFIG_SH_EDOSK7705 is not set
# CONFIG_SH_SH4202_MICRODEV is not set
CONFIG_SH_LANDISK=y
# CONFIG_SH_TITAN is not set
+# CONFIG_SH_SHMIN is not set
# CONFIG_SH_UNKNOWN is not set
#
@@ -107,9 +131,11 @@ CONFIG_CPU_SH4=y
#
# CONFIG_CPU_SUBTYPE_SH7300 is not set
# CONFIG_CPU_SUBTYPE_SH7705 is not set
+# CONFIG_CPU_SUBTYPE_SH7706 is not set
# CONFIG_CPU_SUBTYPE_SH7707 is not set
# CONFIG_CPU_SUBTYPE_SH7708 is not set
# CONFIG_CPU_SUBTYPE_SH7709 is not set
+# CONFIG_CPU_SUBTYPE_SH7710 is not set
#
# SH-4 Processor Support
@@ -132,14 +158,23 @@ CONFIG_CPU_SUBTYPE_SH7751R=y
#
# SH-4A Processor Support
#
-# CONFIG_CPU_SUBTYPE_SH73180 is not set
# CONFIG_CPU_SUBTYPE_SH7770 is not set
# CONFIG_CPU_SUBTYPE_SH7780 is not set
#
+# SH4AL-DSP Processor Support
+#
+# CONFIG_CPU_SUBTYPE_SH73180 is not set
+# CONFIG_CPU_SUBTYPE_SH7343 is not set
+
+#
# Memory management options
#
CONFIG_MMU=y
+CONFIG_PAGE_OFFSET=0x80000000
+CONFIG_MEMORY_START=0x0c000000
+CONFIG_MEMORY_SIZE=0x04000000
+CONFIG_VSYSCALL=y
CONFIG_SELECT_MEMORY_MODEL=y
CONFIG_FLATMEM_MANUAL=y
# CONFIG_DISCONTIGMEM_MANUAL is not set
@@ -147,6 +182,8 @@ CONFIG_FLATMEM_MANUAL=y
CONFIG_FLATMEM=y
CONFIG_FLAT_NODE_MEM_MAP=y
# CONFIG_SPARSEMEM_STATIC is not set
+CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_RESOURCES_64BIT is not set
#
# Cache configuration
@@ -154,21 +191,21 @@ CONFIG_FLAT_NODE_MEM_MAP=y
# CONFIG_SH_DIRECT_MAPPED is not set
# CONFIG_SH_WRITETHROUGH is not set
# CONFIG_SH_OCRAM is not set
-CONFIG_MEMORY_START=0x0c000000
-CONFIG_MEMORY_SIZE=0x04000000
#
# Processor features
#
CONFIG_CPU_LITTLE_ENDIAN=y
CONFIG_SH_FPU=y
+# CONFIG_SH_DSP is not set
# CONFIG_SH_STORE_QUEUES is not set
+CONFIG_CPU_HAS_INTEVT=y
+CONFIG_CPU_HAS_SR_RB=y
#
# Timer support
#
CONFIG_SH_TMU=y
-CONFIG_SH_PCLK_FREQ_BOOL=y
CONFIG_SH_PCLK_FREQ=33333333
#
@@ -192,9 +229,15 @@ CONFIG_HEARTBEAT=y
#
# Kernel features
#
+# CONFIG_HZ_100 is not set
+CONFIG_HZ_250=y
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=250
CONFIG_KEXEC=y
-# CONFIG_PREEMPT is not set
# CONFIG_SMP is not set
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
+# CONFIG_PREEMPT is not set
#
# Boot options
@@ -212,7 +255,7 @@ CONFIG_PCI=y
CONFIG_SH_PCIDMA_NONCOHERENT=y
CONFIG_PCI_AUTO=y
CONFIG_PCI_AUTO_UPDATE_RESOURCES=y
-CONFIG_PCI_LEGACY_PROC=y
+# CONFIG_PCI_MULTITHREAD_PROBE is not set
#
# PCCARD (PCMCIA/CardBus) support
@@ -228,6 +271,11 @@ CONFIG_CARDBUS=y
# PC-card bridges
#
CONFIG_YENTA=y
+CONFIG_YENTA_O2=y
+CONFIG_YENTA_RICOH=y
+CONFIG_YENTA_TI=y
+CONFIG_YENTA_ENE_TUNE=y
+CONFIG_YENTA_TOSHIBA=y
# CONFIG_PD6729 is not set
# CONFIG_I82092 is not set
# CONFIG_I82365 is not set
@@ -248,6 +296,11 @@ CONFIG_BINFMT_ELF=y
# CONFIG_BINFMT_MISC is not set
#
+# Power management options (EXPERIMENTAL)
+#
+# CONFIG_PM is not set
+
+#
# Networking
#
CONFIG_NET=y
@@ -255,9 +308,13 @@ CONFIG_NET=y
#
# Networking options
#
+# CONFIG_NETDEBUG is not set
CONFIG_PACKET=y
# CONFIG_PACKET_MMAP is not set
CONFIG_UNIX=y
+CONFIG_XFRM=y
+# CONFIG_XFRM_USER is not set
+# CONFIG_XFRM_SUB_POLICY is not set
# CONFIG_NET_KEY is not set
CONFIG_INET=y
# CONFIG_IP_MULTICAST is not set
@@ -279,20 +336,32 @@ CONFIG_IP_PNP=y
# CONFIG_INET_AH is not set
# CONFIG_INET_ESP is not set
# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
# CONFIG_INET_TUNNEL is not set
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
CONFIG_INET_DIAG=y
CONFIG_INET_TCP_DIAG=y
# CONFIG_TCP_CONG_ADVANCED is not set
-CONFIG_TCP_CONG_BIC=y
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
#
# IP: Virtual Server Configuration
#
# CONFIG_IP_VS is not set
# CONFIG_IPV6 is not set
+# CONFIG_INET6_XFRM_TUNNEL is not set
+# CONFIG_INET6_TUNNEL is not set
+# CONFIG_NETWORK_SECMARK is not set
CONFIG_NETFILTER=y
# CONFIG_NETFILTER_DEBUG is not set
+
+#
+# Core Netfilter Configuration
+#
# CONFIG_NETFILTER_NETLINK is not set
+# CONFIG_NETFILTER_XTABLES is not set
#
# IP: Netfilter Configuration
@@ -308,66 +377,9 @@ CONFIG_IP_NF_IRC=m
CONFIG_IP_NF_TFTP=m
CONFIG_IP_NF_AMANDA=m
# CONFIG_IP_NF_PPTP is not set
+# CONFIG_IP_NF_H323 is not set
+# CONFIG_IP_NF_SIP is not set
CONFIG_IP_NF_QUEUE=m
-CONFIG_IP_NF_IPTABLES=m
-CONFIG_IP_NF_MATCH_LIMIT=m
-CONFIG_IP_NF_MATCH_IPRANGE=m
-CONFIG_IP_NF_MATCH_MAC=m
-CONFIG_IP_NF_MATCH_PKTTYPE=m
-CONFIG_IP_NF_MATCH_MARK=m
-CONFIG_IP_NF_MATCH_MULTIPORT=m
-CONFIG_IP_NF_MATCH_TOS=m
-CONFIG_IP_NF_MATCH_RECENT=m
-CONFIG_IP_NF_MATCH_ECN=m
-CONFIG_IP_NF_MATCH_DSCP=m
-CONFIG_IP_NF_MATCH_AH_ESP=m
-CONFIG_IP_NF_MATCH_LENGTH=m
-CONFIG_IP_NF_MATCH_TTL=m
-CONFIG_IP_NF_MATCH_TCPMSS=m
-CONFIG_IP_NF_MATCH_HELPER=m
-CONFIG_IP_NF_MATCH_STATE=m
-CONFIG_IP_NF_MATCH_CONNTRACK=m
-CONFIG_IP_NF_MATCH_OWNER=m
-CONFIG_IP_NF_MATCH_ADDRTYPE=m
-CONFIG_IP_NF_MATCH_REALM=m
-CONFIG_IP_NF_MATCH_SCTP=m
-# CONFIG_IP_NF_MATCH_DCCP is not set
-CONFIG_IP_NF_MATCH_COMMENT=m
-CONFIG_IP_NF_MATCH_CONNMARK=m
-# CONFIG_IP_NF_MATCH_CONNBYTES is not set
-CONFIG_IP_NF_MATCH_HASHLIMIT=m
-# CONFIG_IP_NF_MATCH_STRING is not set
-CONFIG_IP_NF_FILTER=m
-CONFIG_IP_NF_TARGET_REJECT=m
-CONFIG_IP_NF_TARGET_LOG=m
-CONFIG_IP_NF_TARGET_ULOG=m
-CONFIG_IP_NF_TARGET_TCPMSS=m
-# CONFIG_IP_NF_TARGET_NFQUEUE is not set
-CONFIG_IP_NF_NAT=m
-CONFIG_IP_NF_NAT_NEEDED=y
-CONFIG_IP_NF_TARGET_MASQUERADE=m
-CONFIG_IP_NF_TARGET_REDIRECT=m
-CONFIG_IP_NF_TARGET_NETMAP=m
-CONFIG_IP_NF_TARGET_SAME=m
-# CONFIG_IP_NF_NAT_SNMP_BASIC is not set
-CONFIG_IP_NF_NAT_IRC=m
-CONFIG_IP_NF_NAT_FTP=m
-CONFIG_IP_NF_NAT_TFTP=m
-CONFIG_IP_NF_NAT_AMANDA=m
-CONFIG_IP_NF_MANGLE=m
-CONFIG_IP_NF_TARGET_TOS=m
-CONFIG_IP_NF_TARGET_ECN=m
-CONFIG_IP_NF_TARGET_DSCP=m
-CONFIG_IP_NF_TARGET_MARK=m
-CONFIG_IP_NF_TARGET_CLASSIFY=m
-# CONFIG_IP_NF_TARGET_TTL is not set
-CONFIG_IP_NF_TARGET_CONNMARK=m
-# CONFIG_IP_NF_TARGET_CLUSTERIP is not set
-CONFIG_IP_NF_RAW=m
-CONFIG_IP_NF_TARGET_NOTRACK=m
-CONFIG_IP_NF_ARPTABLES=m
-CONFIG_IP_NF_ARPFILTER=m
-CONFIG_IP_NF_ARP_MANGLE=m
#
# DCCP Configuration (EXPERIMENTAL)
@@ -378,6 +390,11 @@ CONFIG_IP_NF_ARP_MANGLE=m
# SCTP Configuration (EXPERIMENTAL)
#
# CONFIG_IP_SCTP is not set
+
+#
+# TIPC Configuration (EXPERIMENTAL)
+#
+# CONFIG_TIPC is not set
# CONFIG_ATM is not set
# CONFIG_BRIDGE is not set
# CONFIG_VLAN_8021Q is not set
@@ -389,11 +406,13 @@ CONFIG_ATALK=m
# CONFIG_DEV_APPLETALK is not set
# CONFIG_X25 is not set
# CONFIG_LAPB is not set
-# CONFIG_NET_DIVERT is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
+
+#
+# QoS and/or fair queueing
+#
# CONFIG_NET_SCHED is not set
-CONFIG_NET_CLS_ROUTE=y
#
# Network testing
@@ -414,6 +433,7 @@ CONFIG_NET_CLS_ROUTE=y
CONFIG_STANDALONE=y
CONFIG_PREVENT_FIRMWARE_BUILD=y
CONFIG_FW_LOADER=y
+# CONFIG_SYS_HYPERVISOR is not set
#
# Connector - unified userspace <-> kernelspace linker
@@ -451,17 +471,9 @@ CONFIG_BLK_DEV_LOOP=y
CONFIG_BLK_DEV_RAM=y
CONFIG_BLK_DEV_RAM_COUNT=16
CONFIG_BLK_DEV_RAM_SIZE=4096
+CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
# CONFIG_BLK_DEV_INITRD is not set
-# CONFIG_LBD is not set
# CONFIG_CDROM_PKTCDVD is not set
-
-#
-# IO Schedulers
-#
-CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
-CONFIG_IOSCHED_DEADLINE=y
-CONFIG_IOSCHED_CFQ=y
# CONFIG_ATA_OVER_ETH is not set
#
@@ -518,7 +530,6 @@ CONFIG_BLK_DEV_AEC62XX=y
# CONFIG_BLK_DEV_SLC90E66 is not set
# CONFIG_BLK_DEV_TRM290 is not set
# CONFIG_BLK_DEV_VIA82CXXX is not set
-CONFIG_IDE_SH=y
# CONFIG_IDE_ARM is not set
# CONFIG_IDE_CHIPSETS is not set
CONFIG_BLK_DEV_IDEDMA=y
@@ -531,6 +542,7 @@ CONFIG_IDEDMA_AUTO=y
#
# CONFIG_RAID_ATTRS is not set
CONFIG_SCSI=y
+# CONFIG_SCSI_NETLINK is not set
CONFIG_SCSI_PROC_FS=y
#
@@ -551,16 +563,18 @@ CONFIG_SCSI_MULTI_LUN=y
# CONFIG_SCSI_LOGGING is not set
#
-# SCSI Transport Attributes
+# SCSI Transports
#
# CONFIG_SCSI_SPI_ATTRS is not set
# CONFIG_SCSI_FC_ATTRS is not set
# CONFIG_SCSI_ISCSI_ATTRS is not set
# CONFIG_SCSI_SAS_ATTRS is not set
+# CONFIG_SCSI_SAS_LIBSAS is not set
#
# SCSI low-level drivers
#
+# CONFIG_ISCSI_TCP is not set
# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
# CONFIG_SCSI_3W_9XXX is not set
# CONFIG_SCSI_ACARD is not set
@@ -569,12 +583,14 @@ CONFIG_SCSI_MULTI_LUN=y
# CONFIG_SCSI_AIC7XXX is not set
# CONFIG_SCSI_AIC7XXX_OLD is not set
# CONFIG_SCSI_AIC79XX is not set
+# CONFIG_SCSI_AIC94XX is not set
# CONFIG_SCSI_DPT_I2O is not set
# CONFIG_SCSI_IN2000 is not set
+# CONFIG_SCSI_ARCMSR is not set
# CONFIG_MEGARAID_NEWGEN is not set
# CONFIG_MEGARAID_LEGACY is not set
# CONFIG_MEGARAID_SAS is not set
-# CONFIG_SCSI_SATA is not set
+# CONFIG_SCSI_HPTIOP is not set
# CONFIG_SCSI_DMX3191D is not set
# CONFIG_SCSI_DTC3280 is not set
# CONFIG_SCSI_FUTURE_DOMAIN is not set
@@ -584,20 +600,14 @@ CONFIG_SCSI_MULTI_LUN=y
# CONFIG_SCSI_INITIO is not set
# CONFIG_SCSI_INIA100 is not set
# CONFIG_SCSI_NCR53C406A is not set
+# CONFIG_SCSI_STEX is not set
# CONFIG_SCSI_SYM53C8XX_2 is not set
# CONFIG_SCSI_IPR is not set
# CONFIG_SCSI_PAS16 is not set
# CONFIG_SCSI_PSI240I is not set
# CONFIG_SCSI_QLOGIC_FAS is not set
-# CONFIG_SCSI_QLOGIC_FC is not set
# CONFIG_SCSI_QLOGIC_1280 is not set
-CONFIG_SCSI_QLA2XXX=y
-# CONFIG_SCSI_QLA21XX is not set
-# CONFIG_SCSI_QLA22XX is not set
-# CONFIG_SCSI_QLA2300 is not set
-# CONFIG_SCSI_QLA2322 is not set
-# CONFIG_SCSI_QLA6312 is not set
-# CONFIG_SCSI_QLA24XX is not set
+# CONFIG_SCSI_QLA_FC is not set
# CONFIG_SCSI_LPFC is not set
# CONFIG_SCSI_SYM53C416 is not set
# CONFIG_SCSI_DC395x is not set
@@ -616,6 +626,11 @@ CONFIG_SCSI_QLA2XXX=y
# CONFIG_PCMCIA_SYM53C500 is not set
#
+# Serial ATA (prod) and Parallel ATA (experimental) drivers
+#
+# CONFIG_ATA is not set
+
+#
# Old CD-ROM drivers (not SCSI, not IDE)
#
# CONFIG_CD_NO_IDESCSI is not set
@@ -629,8 +644,7 @@ CONFIG_MD_LINEAR=m
CONFIG_MD_RAID0=m
CONFIG_MD_RAID1=m
# CONFIG_MD_RAID10 is not set
-# CONFIG_MD_RAID5 is not set
-# CONFIG_MD_RAID6 is not set
+# CONFIG_MD_RAID456 is not set
# CONFIG_MD_MULTIPATH is not set
# CONFIG_MD_FAULTY is not set
# CONFIG_BLK_DEV_DM is not set
@@ -694,7 +708,6 @@ CONFIG_MII=y
# CONFIG_DEPCA is not set
# CONFIG_HP100 is not set
# CONFIG_NET_ISA is not set
-# CONFIG_NE2000 is not set
CONFIG_NET_PCI=y
# CONFIG_PCNET32 is not set
# CONFIG_AMD8111_ETH is not set
@@ -730,10 +743,12 @@ CONFIG_8139CP=y
# CONFIG_R8169 is not set
# CONFIG_SIS190 is not set
# CONFIG_SKGE is not set
+# CONFIG_SKY2 is not set
# CONFIG_SK98LIN is not set
# CONFIG_VIA_VELOCITY is not set
# CONFIG_TIGON3 is not set
# CONFIG_BNX2 is not set
+# CONFIG_QLA3XXX is not set
#
# Ethernet (10000 Mbit)
@@ -741,6 +756,7 @@ CONFIG_8139CP=y
# CONFIG_CHELSIO_T1 is not set
# CONFIG_IXGB is not set
# CONFIG_S2IO is not set
+# CONFIG_MYRI10GE is not set
#
# Token Ring devices
@@ -785,6 +801,7 @@ CONFIG_8139CP=y
# Input device support
#
CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
#
# Userland interfaces
@@ -819,6 +836,7 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
CONFIG_VT=y
CONFIG_VT_CONSOLE=y
CONFIG_HW_CONSOLE=y
+# CONFIG_VT_HW_CONSOLE_BINDING is not set
# CONFIG_SERIAL_NONSTANDARD is not set
#
@@ -830,6 +848,7 @@ CONFIG_HW_CONSOLE=y
# Non-8250 serial port support
#
CONFIG_SERIAL_SH_SCI=y
+CONFIG_SERIAL_SH_SCI_NR_UARTS=2
CONFIG_SERIAL_SH_SCI_CONSOLE=y
CONFIG_SERIAL_CORE=y
CONFIG_SERIAL_CORE_CONSOLE=y
@@ -847,8 +866,7 @@ CONFIG_LEGACY_PTY_COUNT=256
# Watchdog Cards
#
# CONFIG_WATCHDOG is not set
-# CONFIG_RTC is not set
-CONFIG_RS5C313_RTC=y
+CONFIG_HW_RANDOM=y
# CONFIG_GEN_RTC is not set
# CONFIG_DTLK is not set
# CONFIG_R3964 is not set
@@ -863,12 +881,15 @@ CONFIG_RS5C313_RTC=y
# PCMCIA character devices
#
# CONFIG_SYNCLINK_CS is not set
+# CONFIG_CARDMAN_4000 is not set
+# CONFIG_CARDMAN_4040 is not set
# CONFIG_RAW_DRIVER is not set
#
# TPM devices
#
# CONFIG_TCG_TPM is not set
+# CONFIG_TELCLOCK is not set
#
# I2C support
@@ -876,15 +897,23 @@ CONFIG_RS5C313_RTC=y
# CONFIG_I2C is not set
#
+# SPI support
+#
+# CONFIG_SPI is not set
+# CONFIG_SPI_MASTER is not set
+
+#
# Dallas's 1-wire bus
#
-# CONFIG_W1 is not set
#
# Hardware Monitoring support
#
CONFIG_HWMON=y
# CONFIG_HWMON_VID is not set
+# CONFIG_SENSORS_ABITUGURU is not set
+# CONFIG_SENSORS_F71805F is not set
+# CONFIG_SENSORS_VT1211 is not set
# CONFIG_HWMON_DEBUG_CHIP is not set
#
@@ -892,28 +921,44 @@ CONFIG_HWMON=y
#
#
-# Multimedia Capabilities Port drivers
-#
-
-#
# Multimedia devices
#
CONFIG_VIDEO_DEV=m
+CONFIG_VIDEO_V4L1=y
+CONFIG_VIDEO_V4L1_COMPAT=y
+CONFIG_VIDEO_V4L2=y
#
-# Video For Linux
+# Video Capture Adapters
#
#
-# Video Adapters
+# Video Capture Adapters
#
+# CONFIG_VIDEO_ADV_DEBUG is not set
+CONFIG_VIDEO_HELPER_CHIPS_AUTO=y
+# CONFIG_VIDEO_VIVI is not set
# CONFIG_VIDEO_PMS is not set
# CONFIG_VIDEO_CPIA is not set
+# CONFIG_VIDEO_CPIA2 is not set
# CONFIG_VIDEO_STRADIS is not set
-# CONFIG_VIDEO_MXB is not set
-# CONFIG_VIDEO_DPC is not set
-# CONFIG_VIDEO_HEXIUM_ORION is not set
-# CONFIG_VIDEO_HEXIUM_GEMINI is not set
+
+#
+# V4L USB devices
+#
+CONFIG_VIDEO_USBVIDEO=m
+CONFIG_USB_VICAM=m
+CONFIG_USB_IBMCAM=m
+CONFIG_USB_KONICAWC=m
+# CONFIG_USB_QUICKCAM_MESSENGER is not set
+# CONFIG_USB_ET61X251 is not set
+CONFIG_USB_OV511=m
+CONFIG_USB_SE401=m
+CONFIG_USB_SN9C102=m
+CONFIG_USB_STV680=m
+# CONFIG_USB_ZC0301 is not set
+CONFIG_USB_PWC=m
+# CONFIG_USB_PWC_DEBUG is not set
#
# Radio Adapters
@@ -932,15 +977,18 @@ CONFIG_VIDEO_DEV=m
# CONFIG_RADIO_TRUST is not set
# CONFIG_RADIO_TYPHOON is not set
# CONFIG_RADIO_ZOLTRIX is not set
+CONFIG_USB_DSBR=m
#
# Digital Video Broadcasting Devices
#
# CONFIG_DVB is not set
+CONFIG_USB_DABUSB=m
#
# Graphics support
#
+CONFIG_FIRMWARE_EDID=y
# CONFIG_FB is not set
#
@@ -949,6 +997,7 @@ CONFIG_VIDEO_DEV=m
# CONFIG_MDA_CONSOLE is not set
CONFIG_DUMMY_CONSOLE=y
CONFIG_FONT_8x16=y
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
#
# Sound
@@ -964,32 +1013,21 @@ CONFIG_SOUND=m
# Open Sound System
#
CONFIG_SOUND_PRIME=m
+# CONFIG_OSS_OBSOLETE_DRIVER is not set
# CONFIG_SOUND_BT878 is not set
-# CONFIG_SOUND_CMPCI is not set
-# CONFIG_SOUND_EMU10K1 is not set
-# CONFIG_SOUND_FUSION is not set
-# CONFIG_SOUND_CS4281 is not set
-# CONFIG_SOUND_ES1370 is not set
# CONFIG_SOUND_ES1371 is not set
-# CONFIG_SOUND_ESSSOLO1 is not set
-# CONFIG_SOUND_MAESTRO is not set
-# CONFIG_SOUND_MAESTRO3 is not set
# CONFIG_SOUND_ICH is not set
-# CONFIG_SOUND_SONICVIBES is not set
# CONFIG_SOUND_TRIDENT is not set
# CONFIG_SOUND_MSNDCLAS is not set
# CONFIG_SOUND_MSNDPIN is not set
# CONFIG_SOUND_VIA82CXXX is not set
-# CONFIG_SOUND_ALI5455 is not set
-# CONFIG_SOUND_FORTE is not set
-# CONFIG_SOUND_RME96XX is not set
-# CONFIG_SOUND_AD1980 is not set
#
# USB support
#
CONFIG_USB_ARCH_HAS_HCD=y
CONFIG_USB_ARCH_HAS_OHCI=y
+CONFIG_USB_ARCH_HAS_EHCI=y
CONFIG_USB=y
# CONFIG_USB_DEBUG is not set
@@ -1007,6 +1045,7 @@ CONFIG_USB_DEVICEFS=y
CONFIG_USB_EHCI_HCD=y
# CONFIG_USB_EHCI_SPLIT_ISO is not set
# CONFIG_USB_EHCI_ROOT_HUB_TT is not set
+# CONFIG_USB_EHCI_TT_NEWSCHED is not set
# CONFIG_USB_ISP116X_HCD is not set
CONFIG_USB_OHCI_HCD=y
# CONFIG_USB_OHCI_BIG_ENDIAN is not set
@@ -1017,15 +1056,15 @@ CONFIG_USB_OHCI_LITTLE_ENDIAN=y
#
# USB Device Class drivers
#
-CONFIG_OBSOLETE_OSS_USB_DRIVER=y
-CONFIG_USB_AUDIO=m
-# CONFIG_USB_BLUETOOTH_TTY is not set
-CONFIG_USB_MIDI=m
# CONFIG_USB_ACM is not set
CONFIG_USB_PRINTER=m
#
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
+#
+
+#
+# may also be needed; see USB_STORAGE Help for more information
#
CONFIG_USB_STORAGE=m
# CONFIG_USB_STORAGE_DEBUG is not set
@@ -1037,12 +1076,16 @@ CONFIG_USB_STORAGE_DPCM=y
CONFIG_USB_STORAGE_SDDR09=y
CONFIG_USB_STORAGE_SDDR55=y
CONFIG_USB_STORAGE_JUMPSHOT=y
+# CONFIG_USB_STORAGE_ALAUDA is not set
+# CONFIG_USB_STORAGE_KARMA is not set
+# CONFIG_USB_LIBUSUAL is not set
#
# USB Input Devices
#
CONFIG_USB_HID=m
CONFIG_USB_HIDINPUT=y
+# CONFIG_USB_HIDINPUT_POWERBOOK is not set
# CONFIG_HID_FF is not set
# CONFIG_USB_HIDDEV is not set
@@ -1056,14 +1099,14 @@ CONFIG_USB_HIDINPUT=y
# CONFIG_USB_ACECAD is not set
# CONFIG_USB_KBTAB is not set
# CONFIG_USB_POWERMATE is not set
-# CONFIG_USB_MTOUCH is not set
-# CONFIG_USB_ITMTOUCH is not set
-# CONFIG_USB_EGALAX is not set
+# CONFIG_USB_TOUCHSCREEN is not set
# CONFIG_USB_YEALINK is not set
# CONFIG_USB_XPAD is not set
# CONFIG_USB_ATI_REMOTE is not set
+# CONFIG_USB_ATI_REMOTE2 is not set
# CONFIG_USB_KEYSPAN_REMOTE is not set
# CONFIG_USB_APPLETOUCH is not set
+# CONFIG_USB_TRANCEVIBRATOR is not set
#
# USB Imaging devices
@@ -1072,20 +1115,6 @@ CONFIG_USB_HIDINPUT=y
# CONFIG_USB_MICROTEK is not set
#
-# USB Multimedia devices
-#
-CONFIG_USB_DABUSB=m
-CONFIG_USB_VICAM=m
-CONFIG_USB_DSBR=m
-CONFIG_USB_IBMCAM=m
-CONFIG_USB_KONICAWC=m
-CONFIG_USB_OV511=m
-CONFIG_USB_SE401=m
-CONFIG_USB_SN9C102=m
-CONFIG_USB_STV680=m
-CONFIG_USB_PWC=m
-
-#
# USB Network Adapters
#
# CONFIG_USB_CATC is not set
@@ -1104,7 +1133,9 @@ CONFIG_USB_MON=y
#
CONFIG_USB_SERIAL=m
# CONFIG_USB_SERIAL_GENERIC is not set
+# CONFIG_USB_SERIAL_AIRCABLE is not set
# CONFIG_USB_SERIAL_AIRPRIME is not set
+# CONFIG_USB_SERIAL_ARK3116 is not set
# CONFIG_USB_SERIAL_BELKIN is not set
# CONFIG_USB_SERIAL_WHITEHEAT is not set
# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set
@@ -1112,6 +1143,7 @@ CONFIG_USB_SERIAL=m
# CONFIG_USB_SERIAL_CYPRESS_M8 is not set
# CONFIG_USB_SERIAL_EMPEG is not set
CONFIG_USB_SERIAL_FTDI_SIO=m
+# CONFIG_USB_SERIAL_FUNSOFT is not set
# CONFIG_USB_SERIAL_VISOR is not set
# CONFIG_USB_SERIAL_IPAQ is not set
# CONFIG_USB_SERIAL_IR is not set
@@ -1124,9 +1156,12 @@ CONFIG_USB_SERIAL_FTDI_SIO=m
# CONFIG_USB_SERIAL_KLSI is not set
# CONFIG_USB_SERIAL_KOBIL_SCT is not set
# CONFIG_USB_SERIAL_MCT_U232 is not set
+# CONFIG_USB_SERIAL_MOS7840 is not set
+# CONFIG_USB_SERIAL_NAVMAN is not set
CONFIG_USB_SERIAL_PL2303=m
# CONFIG_USB_SERIAL_HP4X is not set
# CONFIG_USB_SERIAL_SAFE is not set
+# CONFIG_USB_SERIAL_SIERRAWIRELESS is not set
# CONFIG_USB_SERIAL_TI is not set
# CONFIG_USB_SERIAL_CYBERJACK is not set
# CONFIG_USB_SERIAL_XIRCOM is not set
@@ -1138,15 +1173,18 @@ CONFIG_USB_SERIAL_PL2303=m
#
CONFIG_USB_EMI62=m
CONFIG_USB_EMI26=m
+# CONFIG_USB_ADUTUX is not set
# CONFIG_USB_AUERSWALD is not set
# CONFIG_USB_RIO500 is not set
# CONFIG_USB_LEGOTOWER is not set
# CONFIG_USB_LCD is not set
# CONFIG_USB_LED is not set
+# CONFIG_USB_CYPRESS_CY7C63 is not set
# CONFIG_USB_CYTHERM is not set
-# CONFIG_USB_PHIDGETKIT is not set
-# CONFIG_USB_PHIDGETSERVO is not set
+# CONFIG_USB_PHIDGET is not set
# CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_FTDI_ELAN is not set
+# CONFIG_USB_APPLEDISPLAY is not set
CONFIG_USB_SISUSBVGA=m
CONFIG_USB_SISUSBVGA_CON=y
# CONFIG_USB_LD is not set
@@ -1167,12 +1205,43 @@ CONFIG_USB_SISUSBVGA_CON=y
# CONFIG_MMC is not set
#
+# LED devices
+#
+# CONFIG_NEW_LEDS is not set
+
+#
+# LED drivers
+#
+
+#
+# LED Triggers
+#
+
+#
# InfiniBand support
#
# CONFIG_INFINIBAND is not set
#
-# SN Devices
+# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
+#
+
+#
+# Real Time Clock
+#
+# CONFIG_RTC_CLASS is not set
+
+#
+# DMA Engine support
+#
+# CONFIG_DMA_ENGINE is not set
+
+#
+# DMA Clients
+#
+
+#
+# DMA Devices
#
#
@@ -1195,9 +1264,11 @@ CONFIG_REISERFS_FS=y
# CONFIG_JFS_FS is not set
# CONFIG_FS_POSIX_ACL is not set
# CONFIG_XFS_FS is not set
+# CONFIG_OCFS2_FS is not set
# CONFIG_MINIX_FS is not set
CONFIG_ROMFS_FS=y
CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
# CONFIG_QUOTA is not set
CONFIG_DNOTIFY=y
# CONFIG_AUTOFS_FS is not set
@@ -1229,12 +1300,14 @@ CONFIG_NTFS_RW=y
#
CONFIG_PROC_FS=y
# CONFIG_PROC_KCORE is not set
+CONFIG_PROC_SYSCTL=y
CONFIG_SYSFS=y
CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
# CONFIG_HUGETLBFS is not set
# CONFIG_HUGETLB_PAGE is not set
CONFIG_RAMFS=y
-# CONFIG_RELAYFS_FS is not set
+# CONFIG_CONFIGFS_FS is not set
#
# Miscellaneous filesystems
@@ -1252,7 +1325,8 @@ CONFIG_RAMFS=y
# CONFIG_QNX4FS_FS is not set
# CONFIG_SYSV_FS is not set
CONFIG_UFS_FS=m
-CONFIG_UFS_FS_WRITE=y
+# CONFIG_UFS_FS_WRITE is not set
+# CONFIG_UFS_DEBUG is not set
#
# Network File Systems
@@ -1341,9 +1415,13 @@ CONFIG_NLS_CODEPAGE_932=y
# Kernel hacking
#
# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_MUST_CHECK=y
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_UNUSED_SYMBOLS is not set
# CONFIG_DEBUG_KERNEL is not set
CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_FRAME_POINTER is not set
+# CONFIG_DEBUG_BUGVERBOSE is not set
+# CONFIG_DEBUG_FS is not set
CONFIG_SH_STANDARD_BIOS=y
# CONFIG_EARLY_SCIF_CONSOLE is not set
# CONFIG_EARLY_PRINTK is not set
@@ -1361,13 +1439,12 @@ CONFIG_SH_STANDARD_BIOS=y
# CONFIG_CRYPTO is not set
#
-# Hardware crypto devices
-#
-
-#
# Library routines
#
# CONFIG_CRC_CCITT is not set
# CONFIG_CRC16 is not set
CONFIG_CRC32=y
# CONFIG_LIBCRC32C is not set
+CONFIG_TEXTSEARCH=y
+CONFIG_TEXTSEARCH_KMP=m
+CONFIG_PLIST=y
diff --git a/arch/sh/configs/microdev_defconfig b/arch/sh/configs/microdev_defconfig
index ab3db76d1e51..e89d951c3c16 100644
--- a/arch/sh/configs/microdev_defconfig
+++ b/arch/sh/configs/microdev_defconfig
@@ -1,19 +1,21 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.16-rc1
-# Fri Jan 27 19:43:20 2006
+# Linux kernel version: 2.6.18
+# Tue Oct 3 11:27:01 2006
#
CONFIG_SUPERH=y
CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+CONFIG_GENERIC_HWEIGHT=y
CONFIG_GENERIC_HARDIRQS=y
CONFIG_GENERIC_IRQ_PROBE=y
CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
#
# Code maturity level options
#
CONFIG_EXPERIMENTAL=y
-CONFIG_CLEAN_COMPILE=y
CONFIG_BROKEN_ON_SMP=y
CONFIG_LOCK_KERNEL=y
CONFIG_INIT_ENV_ARG_LIMIT=32
@@ -28,13 +30,17 @@ CONFIG_SWAP=y
# CONFIG_POSIX_MQUEUE is not set
CONFIG_BSD_PROCESS_ACCT=y
# CONFIG_BSD_PROCESS_ACCT_V3 is not set
-CONFIG_SYSCTL=y
+# CONFIG_TASKSTATS is not set
+# CONFIG_UTS_NS is not set
# CONFIG_AUDIT is not set
# CONFIG_IKCONFIG is not set
+# CONFIG_RELAY is not set
CONFIG_INITRAMFS_SOURCE=""
-CONFIG_UID16=y
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SYSCTL=y
CONFIG_EMBEDDED=y
+CONFIG_UID16=y
+# CONFIG_SYSCTL_SYSCALL is not set
CONFIG_KALLSYMS=y
# CONFIG_KALLSYMS_EXTRA_PASS is not set
CONFIG_HOTPLUG=y
@@ -45,11 +51,9 @@ CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
CONFIG_EPOLL=y
CONFIG_SHMEM=y
-CONFIG_CC_ALIGN_FUNCTIONS=0
-CONFIG_CC_ALIGN_LABELS=0
-CONFIG_CC_ALIGN_LOOPS=0
-CONFIG_CC_ALIGN_JUMPS=0
CONFIG_SLAB=y
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_RT_MUTEXES=y
# CONFIG_TINY_SHMEM is not set
CONFIG_BASE_SMALL=0
# CONFIG_SLOB is not set
@@ -62,7 +66,10 @@ CONFIG_BASE_SMALL=0
#
# Block layer
#
+CONFIG_BLOCK=y
# CONFIG_LBD is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_LSF is not set
#
# IO Schedulers
@@ -83,30 +90,26 @@ CONFIG_DEFAULT_IOSCHED="anticipatory"
# CONFIG_SH_SOLUTION_ENGINE is not set
# CONFIG_SH_7751_SOLUTION_ENGINE is not set
# CONFIG_SH_7300_SOLUTION_ENGINE is not set
+# CONFIG_SH_7343_SOLUTION_ENGINE is not set
# CONFIG_SH_73180_SOLUTION_ENGINE is not set
# CONFIG_SH_7751_SYSTEMH is not set
-# CONFIG_SH_STB1_HARP is not set
-# CONFIG_SH_STB1_OVERDRIVE is not set
# CONFIG_SH_HP6XX is not set
-# CONFIG_SH_CQREEK is not set
-# CONFIG_SH_DMIDA is not set
# CONFIG_SH_EC3104 is not set
# CONFIG_SH_SATURN is not set
# CONFIG_SH_DREAMCAST is not set
-# CONFIG_SH_CAT68701 is not set
# CONFIG_SH_BIGSUR is not set
-# CONFIG_SH_SH2000 is not set
-# CONFIG_SH_ADX is not set
# CONFIG_SH_MPC1211 is not set
# CONFIG_SH_SH03 is not set
# CONFIG_SH_SECUREEDGE5410 is not set
# CONFIG_SH_HS7751RVOIP is not set
+# CONFIG_SH_7710VOIPGW is not set
# CONFIG_SH_RTS7751R2D is not set
# CONFIG_SH_R7780RP is not set
# CONFIG_SH_EDOSK7705 is not set
CONFIG_SH_SH4202_MICRODEV=y
# CONFIG_SH_LANDISK is not set
# CONFIG_SH_TITAN is not set
+# CONFIG_SH_SHMIN is not set
# CONFIG_SH_UNKNOWN is not set
#
@@ -124,9 +127,11 @@ CONFIG_CPU_SH4=y
#
# CONFIG_CPU_SUBTYPE_SH7300 is not set
# CONFIG_CPU_SUBTYPE_SH7705 is not set
+# CONFIG_CPU_SUBTYPE_SH7706 is not set
# CONFIG_CPU_SUBTYPE_SH7707 is not set
# CONFIG_CPU_SUBTYPE_SH7708 is not set
# CONFIG_CPU_SUBTYPE_SH7709 is not set
+# CONFIG_CPU_SUBTYPE_SH7710 is not set
#
# SH-4 Processor Support
@@ -149,14 +154,25 @@ CONFIG_CPU_SUBTYPE_SH4_202=y
#
# SH-4A Processor Support
#
-# CONFIG_CPU_SUBTYPE_SH73180 is not set
# CONFIG_CPU_SUBTYPE_SH7770 is not set
# CONFIG_CPU_SUBTYPE_SH7780 is not set
#
+# SH4AL-DSP Processor Support
+#
+# CONFIG_CPU_SUBTYPE_SH73180 is not set
+# CONFIG_CPU_SUBTYPE_SH7343 is not set
+
+#
# Memory management options
#
CONFIG_MMU=y
+CONFIG_PAGE_OFFSET=0x80000000
+CONFIG_MEMORY_START=0x08000000
+CONFIG_MEMORY_SIZE=0x04000000
+CONFIG_VSYSCALL=y
+CONFIG_HUGETLB_PAGE_SIZE_64K=y
+# CONFIG_HUGETLB_PAGE_SIZE_1MB is not set
CONFIG_SELECT_MEMORY_MODEL=y
CONFIG_FLATMEM_MANUAL=y
# CONFIG_DISCONTIGMEM_MANUAL is not set
@@ -165,22 +181,21 @@ CONFIG_FLATMEM=y
CONFIG_FLAT_NODE_MEM_MAP=y
# CONFIG_SPARSEMEM_STATIC is not set
CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_RESOURCES_64BIT is not set
#
# Cache configuration
#
# CONFIG_SH_DIRECT_MAPPED is not set
-# CONFIG_SH_WRITETHROUGH is not set
+CONFIG_SH_WRITETHROUGH=y
# CONFIG_SH_OCRAM is not set
-CONFIG_MEMORY_START=0x08000000
-CONFIG_MEMORY_SIZE=0x04000000
#
# Processor features
#
CONFIG_CPU_LITTLE_ENDIAN=y
-CONFIG_SH_RTC=y
CONFIG_SH_FPU=y
+# CONFIG_SH_DSP is not set
# CONFIG_SH_STORE_QUEUES is not set
CONFIG_CPU_HAS_INTEVT=y
CONFIG_CPU_HAS_SR_RB=y
@@ -212,9 +227,16 @@ CONFIG_HEARTBEAT=y
#
# Kernel features
#
+# CONFIG_HZ_100 is not set
+CONFIG_HZ_250=y
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=250
# CONFIG_KEXEC is not set
-CONFIG_PREEMPT=y
# CONFIG_SMP is not set
+# CONFIG_PREEMPT_NONE is not set
+# CONFIG_PREEMPT_VOLUNTARY is not set
+CONFIG_PREEMPT=y
+CONFIG_PREEMPT_BKL=y
#
# Boot options
@@ -223,12 +245,12 @@ CONFIG_ZERO_PAGE_OFFSET=0x00001000
CONFIG_BOOT_LINK_OFFSET=0x00800000
# CONFIG_UBC_WAKEUP is not set
CONFIG_CMDLINE_BOOL=y
-CONFIG_CMDLINE="console=ttySC0,115200"
+CONFIG_CMDLINE="console=ttySC0,115200 root=/dev/hda1"
#
# Bus options
#
-# CONFIG_SUPERHYWAY is not set
+CONFIG_SUPERHYWAY=y
# CONFIG_PCI is not set
#
@@ -248,6 +270,11 @@ CONFIG_BINFMT_ELF=y
# CONFIG_BINFMT_MISC is not set
#
+# Power management options (EXPERIMENTAL)
+#
+# CONFIG_PM is not set
+
+#
# Networking
#
CONFIG_NET=y
@@ -255,15 +282,19 @@ CONFIG_NET=y
#
# Networking options
#
+# CONFIG_NETDEBUG is not set
# CONFIG_PACKET is not set
# CONFIG_UNIX is not set
+CONFIG_XFRM=y
+# CONFIG_XFRM_USER is not set
+# CONFIG_XFRM_SUB_POLICY is not set
# CONFIG_NET_KEY is not set
CONFIG_INET=y
# CONFIG_IP_MULTICAST is not set
# CONFIG_IP_ADVANCED_ROUTER is not set
CONFIG_IP_FIB_HASH=y
CONFIG_IP_PNP=y
-CONFIG_IP_PNP_DHCP=y
+# CONFIG_IP_PNP_DHCP is not set
# CONFIG_IP_PNP_BOOTP is not set
# CONFIG_IP_PNP_RARP is not set
# CONFIG_NET_IPIP is not set
@@ -273,12 +304,19 @@ CONFIG_IP_PNP_DHCP=y
# CONFIG_INET_AH is not set
# CONFIG_INET_ESP is not set
# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
# CONFIG_INET_TUNNEL is not set
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
CONFIG_INET_DIAG=y
CONFIG_INET_TCP_DIAG=y
# CONFIG_TCP_CONG_ADVANCED is not set
-CONFIG_TCP_CONG_BIC=y
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_IPV6 is not set
+# CONFIG_INET6_XFRM_TUNNEL is not set
+# CONFIG_INET6_TUNNEL is not set
+# CONFIG_NETWORK_SECMARK is not set
# CONFIG_NETFILTER is not set
#
@@ -304,7 +342,6 @@ CONFIG_TCP_CONG_BIC=y
# CONFIG_ATALK is not set
# CONFIG_X25 is not set
# CONFIG_LAPB is not set
-# CONFIG_NET_DIVERT is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
@@ -332,6 +369,7 @@ CONFIG_TCP_CONG_BIC=y
CONFIG_STANDALONE=y
CONFIG_PREVENT_FIRMWARE_BUILD=y
# CONFIG_FW_LOADER is not set
+# CONFIG_SYS_HYPERVISOR is not set
#
# Connector - unified userspace <-> kernelspace linker
@@ -361,6 +399,7 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
CONFIG_BLK_DEV_RAM=y
CONFIG_BLK_DEV_RAM_COUNT=16
CONFIG_BLK_DEV_RAM_SIZE=4096
+CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
CONFIG_BLK_DEV_INITRD=y
# CONFIG_CDROM_PKTCDVD is not set
# CONFIG_ATA_OVER_ETH is not set
@@ -397,6 +436,12 @@ CONFIG_IDE_GENERIC=y
#
# CONFIG_RAID_ATTRS is not set
# CONFIG_SCSI is not set
+# CONFIG_SCSI_NETLINK is not set
+
+#
+# Serial ATA (prod) and Parallel ATA (experimental) drivers
+#
+# CONFIG_ATA is not set
#
# Multi-device support (RAID and LVM)
@@ -502,6 +547,7 @@ CONFIG_SMC91X=y
# Non-8250 serial port support
#
CONFIG_SERIAL_SH_SCI=y
+CONFIG_SERIAL_SH_SCI_NR_UARTS=2
CONFIG_SERIAL_SH_SCI_CONSOLE=y
CONFIG_SERIAL_CORE=y
CONFIG_SERIAL_CORE_CONSOLE=y
@@ -518,7 +564,8 @@ CONFIG_LEGACY_PTY_COUNT=256
# Watchdog Cards
#
# CONFIG_WATCHDOG is not set
-CONFIG_RTC=y
+CONFIG_HW_RANDOM=y
+# CONFIG_GEN_RTC is not set
# CONFIG_DTLK is not set
# CONFIG_R3964 is not set
@@ -547,13 +594,15 @@ CONFIG_RTC=y
#
# Dallas's 1-wire bus
#
-# CONFIG_W1 is not set
#
# Hardware Monitoring support
#
CONFIG_HWMON=y
# CONFIG_HWMON_VID is not set
+# CONFIG_SENSORS_ABITUGURU is not set
+# CONFIG_SENSORS_F71805F is not set
+# CONFIG_SENSORS_VT1211 is not set
# CONFIG_HWMON_DEBUG_CHIP is not set
#
@@ -561,13 +610,10 @@ CONFIG_HWMON=y
#
#
-# Multimedia Capabilities Port drivers
-#
-
-#
# Multimedia devices
#
# CONFIG_VIDEO_DEV is not set
+CONFIG_VIDEO_V4L2=y
#
# Digital Video Broadcasting Devices
@@ -577,7 +623,9 @@ CONFIG_HWMON=y
#
# Graphics support
#
+CONFIG_FIRMWARE_EDID=y
# CONFIG_FB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
#
# Sound
@@ -589,6 +637,7 @@ CONFIG_HWMON=y
#
# CONFIG_USB_ARCH_HAS_HCD is not set
# CONFIG_USB_ARCH_HAS_OHCI is not set
+# CONFIG_USB_ARCH_HAS_EHCI is not set
#
# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
@@ -605,15 +654,42 @@ CONFIG_HWMON=y
# CONFIG_MMC is not set
#
+# LED devices
+#
+# CONFIG_NEW_LEDS is not set
+
+#
+# LED drivers
+#
+
+#
+# LED Triggers
+#
+
+#
# InfiniBand support
#
#
-# SN Devices
+# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
+#
+
+#
+# Real Time Clock
+#
+# CONFIG_RTC_CLASS is not set
+
+#
+# DMA Engine support
+#
+# CONFIG_DMA_ENGINE is not set
+
+#
+# DMA Clients
#
#
-# EDAC - error detection and reporting (RAS)
+# DMA Devices
#
#
@@ -637,6 +713,7 @@ CONFIG_FS_MBCACHE=y
# CONFIG_MINIX_FS is not set
# CONFIG_ROMFS_FS is not set
CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
# CONFIG_QUOTA is not set
CONFIG_DNOTIFY=y
# CONFIG_AUTOFS_FS is not set
@@ -664,12 +741,13 @@ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
#
CONFIG_PROC_FS=y
CONFIG_PROC_KCORE=y
+CONFIG_PROC_SYSCTL=y
CONFIG_SYSFS=y
CONFIG_TMPFS=y
-# CONFIG_HUGETLBFS is not set
-# CONFIG_HUGETLB_PAGE is not set
+# CONFIG_TMPFS_POSIX_ACL is not set
+CONFIG_HUGETLBFS=y
+CONFIG_HUGETLB_PAGE=y
CONFIG_RAMFS=y
-# CONFIG_RELAYFS_FS is not set
# CONFIG_CONFIGFS_FS is not set
#
@@ -772,10 +850,14 @@ CONFIG_NLS_DEFAULT="iso8859-1"
# Kernel hacking
#
# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_MUST_CHECK=y
# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_UNUSED_SYMBOLS is not set
# CONFIG_DEBUG_KERNEL is not set
CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_FRAME_POINTER is not set
+# CONFIG_DEBUG_BUGVERBOSE is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_UNWIND_INFO is not set
# CONFIG_SH_STANDARD_BIOS is not set
# CONFIG_EARLY_SCIF_CONSOLE is not set
# CONFIG_KGDB is not set
@@ -790,6 +872,9 @@ CONFIG_LOG_BUF_SHIFT=14
# Cryptographic options
#
CONFIG_CRYPTO=y
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_BLKCIPHER=y
+CONFIG_CRYPTO_MANAGER=y
# CONFIG_CRYPTO_HMAC is not set
# CONFIG_CRYPTO_NULL is not set
# CONFIG_CRYPTO_MD4 is not set
@@ -799,6 +884,8 @@ CONFIG_CRYPTO_MD5=y
# CONFIG_CRYPTO_SHA512 is not set
# CONFIG_CRYPTO_WP512 is not set
# CONFIG_CRYPTO_TGR192 is not set
+CONFIG_CRYPTO_ECB=y
+CONFIG_CRYPTO_CBC=y
CONFIG_CRYPTO_DES=y
# CONFIG_CRYPTO_BLOWFISH is not set
# CONFIG_CRYPTO_TWOFISH is not set
@@ -813,7 +900,6 @@ CONFIG_CRYPTO_DES=y
# CONFIG_CRYPTO_DEFLATE is not set
# CONFIG_CRYPTO_MICHAEL_MIC is not set
# CONFIG_CRYPTO_CRC32C is not set
-# CONFIG_CRYPTO_TEST is not set
#
# Hardware crypto devices
@@ -826,3 +912,4 @@ CONFIG_CRYPTO_DES=y
# CONFIG_CRC16 is not set
CONFIG_CRC32=y
# CONFIG_LIBCRC32C is not set
+CONFIG_PLIST=y
diff --git a/arch/sh/configs/r7780rp_defconfig b/arch/sh/configs/r7780rp_defconfig
index d597fc571549..2470364948e7 100644
--- a/arch/sh/configs/r7780rp_defconfig
+++ b/arch/sh/configs/r7780rp_defconfig
@@ -1,20 +1,21 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.15-sh
-# Sat Jan 7 19:47:53 2006
+# Linux kernel version: 2.6.18
+# Tue Oct 3 11:32:47 2006
#
CONFIG_SUPERH=y
-CONFIG_UID16=y
CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+CONFIG_GENERIC_HWEIGHT=y
CONFIG_GENERIC_HARDIRQS=y
CONFIG_GENERIC_IRQ_PROBE=y
CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
#
# Code maturity level options
#
CONFIG_EXPERIMENTAL=y
-CONFIG_CLEAN_COMPILE=y
CONFIG_BROKEN_ON_SMP=y
CONFIG_LOCK_KERNEL=y
CONFIG_INIT_ENV_ARG_LIMIT=32
@@ -26,33 +27,38 @@ CONFIG_LOCALVERSION=""
CONFIG_LOCALVERSION_AUTO=y
CONFIG_SWAP=y
CONFIG_SYSVIPC=y
+# CONFIG_IPC_NS is not set
# CONFIG_POSIX_MQUEUE is not set
CONFIG_BSD_PROCESS_ACCT=y
# CONFIG_BSD_PROCESS_ACCT_V3 is not set
-CONFIG_SYSCTL=y
+# CONFIG_TASKSTATS is not set
+# CONFIG_UTS_NS is not set
# CONFIG_AUDIT is not set
-CONFIG_HOTPLUG=y
-CONFIG_KOBJECT_UEVENT=y
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
+# CONFIG_RELAY is not set
CONFIG_INITRAMFS_SOURCE=""
CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
CONFIG_EMBEDDED=y
+CONFIG_UID16=y
+# CONFIG_SYSCTL_SYSCALL is not set
CONFIG_KALLSYMS=y
# CONFIG_KALLSYMS_ALL is not set
# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
CONFIG_PRINTK=y
CONFIG_BUG=y
+CONFIG_ELF_CORE=y
CONFIG_BASE_FULL=y
# CONFIG_FUTEX is not set
# CONFIG_EPOLL is not set
CONFIG_SHMEM=y
-CONFIG_CC_ALIGN_FUNCTIONS=0
-CONFIG_CC_ALIGN_LABELS=0
-CONFIG_CC_ALIGN_LOOPS=0
-CONFIG_CC_ALIGN_JUMPS=0
+CONFIG_SLAB=y
+CONFIG_VM_EVENT_COUNTERS=y
# CONFIG_TINY_SHMEM is not set
CONFIG_BASE_SMALL=0
+# CONFIG_SLOB is not set
#
# Loadable module support
@@ -60,7 +66,6 @@ CONFIG_BASE_SMALL=0
CONFIG_MODULES=y
CONFIG_MODULE_UNLOAD=y
# CONFIG_MODULE_FORCE_UNLOAD is not set
-CONFIG_OBSOLETE_MODPARM=y
# CONFIG_MODVERSIONS is not set
# CONFIG_MODULE_SRCVERSION_ALL is not set
CONFIG_KMOD=y
@@ -68,7 +73,10 @@ CONFIG_KMOD=y
#
# Block layer
#
+CONFIG_BLOCK=y
# CONFIG_LBD is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_LSF is not set
#
# IO Schedulers
@@ -89,31 +97,26 @@ CONFIG_DEFAULT_IOSCHED="noop"
# CONFIG_SH_SOLUTION_ENGINE is not set
# CONFIG_SH_7751_SOLUTION_ENGINE is not set
# CONFIG_SH_7300_SOLUTION_ENGINE is not set
+# CONFIG_SH_7343_SOLUTION_ENGINE is not set
# CONFIG_SH_73180_SOLUTION_ENGINE is not set
# CONFIG_SH_7751_SYSTEMH is not set
-# CONFIG_SH_STB1_HARP is not set
-# CONFIG_SH_STB1_OVERDRIVE is not set
# CONFIG_SH_HP6XX is not set
-# CONFIG_SH_CQREEK is not set
-# CONFIG_SH_DMIDA is not set
# CONFIG_SH_EC3104 is not set
# CONFIG_SH_SATURN is not set
# CONFIG_SH_DREAMCAST is not set
-# CONFIG_SH_CAT68701 is not set
# CONFIG_SH_BIGSUR is not set
-# CONFIG_SH_SH2000 is not set
-# CONFIG_SH_ADX is not set
# CONFIG_SH_MPC1211 is not set
# CONFIG_SH_SH03 is not set
# CONFIG_SH_SECUREEDGE5410 is not set
# CONFIG_SH_HS7751RVOIP is not set
+# CONFIG_SH_7710VOIPGW is not set
# CONFIG_SH_RTS7751R2D is not set
-# CONFIG_SH_R77703DRP is not set
CONFIG_SH_R7780RP=y
# CONFIG_SH_EDOSK7705 is not set
# CONFIG_SH_SH4202_MICRODEV is not set
# CONFIG_SH_LANDISK is not set
# CONFIG_SH_TITAN is not set
+# CONFIG_SH_SHMIN is not set
# CONFIG_SH_UNKNOWN is not set
#
@@ -132,9 +135,11 @@ CONFIG_CPU_SH4A=y
#
# CONFIG_CPU_SUBTYPE_SH7300 is not set
# CONFIG_CPU_SUBTYPE_SH7705 is not set
+# CONFIG_CPU_SUBTYPE_SH7706 is not set
# CONFIG_CPU_SUBTYPE_SH7707 is not set
# CONFIG_CPU_SUBTYPE_SH7708 is not set
# CONFIG_CPU_SUBTYPE_SH7709 is not set
+# CONFIG_CPU_SUBTYPE_SH7710 is not set
#
# SH-4 Processor Support
@@ -157,15 +162,24 @@ CONFIG_CPU_SH4A=y
#
# SH-4A Processor Support
#
-# CONFIG_CPU_SUBTYPE_SH73180 is not set
# CONFIG_CPU_SUBTYPE_SH7770 is not set
CONFIG_CPU_SUBTYPE_SH7780=y
#
+# SH4AL-DSP Processor Support
+#
+# CONFIG_CPU_SUBTYPE_SH73180 is not set
+# CONFIG_CPU_SUBTYPE_SH7343 is not set
+
+#
# Memory management options
#
CONFIG_MMU=y
+CONFIG_PAGE_OFFSET=0x80000000
+CONFIG_MEMORY_START=0x08000000
+CONFIG_MEMORY_SIZE=0x08000000
CONFIG_32BIT=y
+CONFIG_VSYSCALL=y
CONFIG_HUGETLB_PAGE_SIZE_64K=y
# CONFIG_HUGETLB_PAGE_SIZE_1MB is not set
CONFIG_SELECT_MEMORY_MODEL=y
@@ -176,6 +190,7 @@ CONFIG_FLATMEM=y
CONFIG_FLAT_NODE_MEM_MAP=y
# CONFIG_SPARSEMEM_STATIC is not set
CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_RESOURCES_64BIT is not set
#
# Cache configuration
@@ -183,21 +198,27 @@ CONFIG_SPLIT_PTLOCK_CPUS=4
# CONFIG_SH_DIRECT_MAPPED is not set
# CONFIG_SH_WRITETHROUGH is not set
# CONFIG_SH_OCRAM is not set
-CONFIG_MEMORY_START=0x08000000
-CONFIG_MEMORY_SIZE=0x08000000
#
# Processor features
#
CONFIG_CPU_LITTLE_ENDIAN=y
CONFIG_SH_FPU=y
+# CONFIG_SH_DSP is not set
CONFIG_SH_STORE_QUEUES=y
+CONFIG_CPU_HAS_INTEVT=y
+CONFIG_CPU_HAS_INTC2_IRQ=y
+CONFIG_CPU_HAS_SR_RB=y
#
# Timer support
#
CONFIG_SH_TMU=y
-CONFIG_SH_PCLK_FREQ_BOOL=y
+
+#
+# R7780RP options
+#
+CONFIG_SH_R7780MP=y
CONFIG_SH_PCLK_FREQ=32000000
#
@@ -220,11 +241,16 @@ CONFIG_NR_ONCHIP_DMA_CHANNELS=6
#
# Kernel features
#
+# CONFIG_HZ_100 is not set
+CONFIG_HZ_250=y
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=250
# CONFIG_KEXEC is not set
-CONFIG_PREEMPT=y
# CONFIG_SMP is not set
-CONFIG_CPU_HAS_INTEVT=y
-CONFIG_CPU_HAS_INTC2_IRQ=y
+# CONFIG_PREEMPT_NONE is not set
+# CONFIG_PREEMPT_VOLUNTARY is not set
+CONFIG_PREEMPT=y
+CONFIG_PREEMPT_BKL=y
#
# Boot options
@@ -242,7 +268,7 @@ CONFIG_PCI=y
CONFIG_SH_PCIDMA_NONCOHERENT=y
CONFIG_PCI_AUTO=y
CONFIG_PCI_AUTO_UPDATE_RESOURCES=y
-CONFIG_PCI_LEGACY_PROC=y
+# CONFIG_PCI_MULTITHREAD_PROBE is not set
# CONFIG_PCI_DEBUG is not set
#
@@ -266,6 +292,11 @@ CONFIG_BINFMT_ELF=y
# CONFIG_BINFMT_MISC is not set
#
+# Power management options (EXPERIMENTAL)
+#
+# CONFIG_PM is not set
+
+#
# Networking
#
CONFIG_NET=y
@@ -273,9 +304,13 @@ CONFIG_NET=y
#
# Networking options
#
+# CONFIG_NETDEBUG is not set
CONFIG_PACKET=y
# CONFIG_PACKET_MMAP is not set
CONFIG_UNIX=y
+CONFIG_XFRM=y
+# CONFIG_XFRM_USER is not set
+# CONFIG_XFRM_SUB_POLICY is not set
# CONFIG_NET_KEY is not set
CONFIG_INET=y
# CONFIG_IP_MULTICAST is not set
@@ -297,12 +332,19 @@ CONFIG_IP_PNP_DHCP=y
# CONFIG_INET_AH is not set
# CONFIG_INET_ESP is not set
# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
# CONFIG_INET_TUNNEL is not set
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
CONFIG_INET_DIAG=y
CONFIG_INET_TCP_DIAG=y
# CONFIG_TCP_CONG_ADVANCED is not set
-CONFIG_TCP_CONG_BIC=y
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_IPV6 is not set
+# CONFIG_INET6_XFRM_TUNNEL is not set
+# CONFIG_INET6_TUNNEL is not set
+# CONFIG_NETWORK_SECMARK is not set
# CONFIG_NETFILTER is not set
#
@@ -314,16 +356,21 @@ CONFIG_TCP_CONG_BIC=y
# SCTP Configuration (EXPERIMENTAL)
#
# CONFIG_IP_SCTP is not set
+
+#
+# TIPC Configuration (EXPERIMENTAL)
+#
+# CONFIG_TIPC is not set
# CONFIG_ATM is not set
CONFIG_BRIDGE=m
# CONFIG_VLAN_8021Q is not set
# CONFIG_DECNET is not set
+CONFIG_LLC=m
# CONFIG_LLC2 is not set
# CONFIG_IPX is not set
# CONFIG_ATALK is not set
# CONFIG_X25 is not set
# CONFIG_LAPB is not set
-# CONFIG_NET_DIVERT is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
@@ -340,6 +387,7 @@ CONFIG_BRIDGE=m
# CONFIG_IRDA is not set
# CONFIG_BT is not set
# CONFIG_IEEE80211 is not set
+CONFIG_WIRELESS_EXT=y
#
# Device Drivers
@@ -352,6 +400,7 @@ CONFIG_STANDALONE=y
CONFIG_PREVENT_FIRMWARE_BUILD=y
CONFIG_FW_LOADER=m
# CONFIG_DEBUG_DRIVER is not set
+# CONFIG_SYS_HYPERVISOR is not set
#
# Connector - unified userspace <-> kernelspace linker
@@ -386,6 +435,7 @@ CONFIG_FW_LOADER=m
CONFIG_BLK_DEV_RAM=y
CONFIG_BLK_DEV_RAM_COUNT=16
CONFIG_BLK_DEV_RAM_SIZE=4096
+CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
# CONFIG_BLK_DEV_INITRD is not set
# CONFIG_CDROM_PKTCDVD is not set
# CONFIG_ATA_OVER_ETH is not set
@@ -438,13 +488,11 @@ CONFIG_BLK_DEV_AEC62XX=m
# CONFIG_BLK_DEV_NS87415 is not set
# CONFIG_BLK_DEV_PDC202XX_OLD is not set
CONFIG_BLK_DEV_PDC202XX_NEW=m
-# CONFIG_PDC202XX_FORCE is not set
# CONFIG_BLK_DEV_SVWKS is not set
CONFIG_BLK_DEV_SIIMAGE=m
# CONFIG_BLK_DEV_SLC90E66 is not set
# CONFIG_BLK_DEV_TRM290 is not set
# CONFIG_BLK_DEV_VIA82CXXX is not set
-CONFIG_IDE_SH=y
# CONFIG_IDE_ARM is not set
CONFIG_BLK_DEV_IDEDMA=y
# CONFIG_IDEDMA_IVB is not set
@@ -456,6 +504,7 @@ CONFIG_IDEDMA_AUTO=y
#
# CONFIG_RAID_ATTRS is not set
CONFIG_SCSI=m
+# CONFIG_SCSI_NETLINK is not set
CONFIG_SCSI_PROC_FS=y
#
@@ -476,12 +525,13 @@ CONFIG_CHR_DEV_SG=m
# CONFIG_SCSI_LOGGING is not set
#
-# SCSI Transport Attributes
+# SCSI Transports
#
# CONFIG_SCSI_SPI_ATTRS is not set
# CONFIG_SCSI_FC_ATTRS is not set
# CONFIG_SCSI_ISCSI_ATTRS is not set
# CONFIG_SCSI_SAS_ATTRS is not set
+# CONFIG_SCSI_SAS_LIBSAS is not set
#
# SCSI low-level drivers
@@ -494,27 +544,23 @@ CONFIG_CHR_DEV_SG=m
# CONFIG_SCSI_AIC7XXX is not set
# CONFIG_SCSI_AIC7XXX_OLD is not set
# CONFIG_SCSI_AIC79XX is not set
+# CONFIG_SCSI_AIC94XX is not set
# CONFIG_SCSI_DPT_I2O is not set
+# CONFIG_SCSI_ARCMSR is not set
# CONFIG_MEGARAID_NEWGEN is not set
# CONFIG_MEGARAID_LEGACY is not set
# CONFIG_MEGARAID_SAS is not set
-# CONFIG_SCSI_SATA is not set
+# CONFIG_SCSI_HPTIOP is not set
# CONFIG_SCSI_DMX3191D is not set
# CONFIG_SCSI_FUTURE_DOMAIN is not set
# CONFIG_SCSI_IPS is not set
# CONFIG_SCSI_INITIO is not set
# CONFIG_SCSI_INIA100 is not set
+# CONFIG_SCSI_STEX is not set
# CONFIG_SCSI_SYM53C8XX_2 is not set
# CONFIG_SCSI_IPR is not set
-# CONFIG_SCSI_QLOGIC_FC is not set
# CONFIG_SCSI_QLOGIC_1280 is not set
-CONFIG_SCSI_QLA2XXX=m
-# CONFIG_SCSI_QLA21XX is not set
-# CONFIG_SCSI_QLA22XX is not set
-# CONFIG_SCSI_QLA2300 is not set
-# CONFIG_SCSI_QLA2322 is not set
-# CONFIG_SCSI_QLA6312 is not set
-# CONFIG_SCSI_QLA24XX is not set
+# CONFIG_SCSI_QLA_FC is not set
# CONFIG_SCSI_LPFC is not set
# CONFIG_SCSI_DC395x is not set
# CONFIG_SCSI_DC390T is not set
@@ -522,6 +568,11 @@ CONFIG_SCSI_QLA2XXX=m
# CONFIG_SCSI_DEBUG is not set
#
+# Serial ATA (prod) and Parallel ATA (experimental) drivers
+#
+# CONFIG_ATA is not set
+
+#
# Multi-device support (RAID and LVM)
#
# CONFIG_MD is not set
@@ -580,9 +631,9 @@ CONFIG_MII=y
#
# CONFIG_NET_TULIP is not set
# CONFIG_HP100 is not set
-CONFIG_NE2000=y
CONFIG_NET_PCI=y
CONFIG_PCNET32=m
+# CONFIG_PCNET32_NAPI is not set
# CONFIG_AMD8111_ETH is not set
# CONFIG_ADAPTEC_STARFIRE is not set
# CONFIG_B44 is not set
@@ -605,6 +656,7 @@ CONFIG_8139TOO_8129=y
# CONFIG_TLAN is not set
CONFIG_VIA_RHINE=m
CONFIG_VIA_RHINE_MMIO=y
+# CONFIG_VIA_RHINE_NAPI is not set
#
# Ethernet (1000 Mbit)
@@ -613,6 +665,7 @@ CONFIG_VIA_RHINE_MMIO=y
# CONFIG_DL2K is not set
CONFIG_E1000=m
# CONFIG_E1000_NAPI is not set
+# CONFIG_E1000_DISABLE_PACKET_SPLIT is not set
# CONFIG_NS83820 is not set
# CONFIG_HAMACHI is not set
# CONFIG_YELLOWFIN is not set
@@ -620,10 +673,12 @@ CONFIG_R8169=y
# CONFIG_R8169_NAPI is not set
# CONFIG_SIS190 is not set
# CONFIG_SKGE is not set
+# CONFIG_SKY2 is not set
# CONFIG_SK98LIN is not set
# CONFIG_VIA_VELOCITY is not set
# CONFIG_TIGON3 is not set
# CONFIG_BNX2 is not set
+# CONFIG_QLA3XXX is not set
#
# Ethernet (10000 Mbit)
@@ -631,6 +686,7 @@ CONFIG_R8169=y
# CONFIG_CHELSIO_T1 is not set
# CONFIG_IXGB is not set
# CONFIG_S2IO is not set
+# CONFIG_MYRI10GE is not set
#
# Token Ring devices
@@ -641,6 +697,7 @@ CONFIG_R8169=y
# Wireless LAN (non-hamradio)
#
CONFIG_NET_RADIO=y
+# CONFIG_NET_WIRELESS_RTNETLINK is not set
#
# Obsolete Wireless cards support (pre-802.11)
@@ -650,6 +707,8 @@ CONFIG_NET_RADIO=y
#
# Wireless 802.11b ISA/PCI cards support
#
+# CONFIG_IPW2100 is not set
+# CONFIG_IPW2200 is not set
CONFIG_HERMES=m
# CONFIG_PLX_HERMES is not set
# CONFIG_TMD_HERMES is not set
@@ -692,6 +751,7 @@ CONFIG_NET_WIRELESS=y
# Input device support
#
CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
#
# Userland interfaces
@@ -714,6 +774,7 @@ CONFIG_KEYBOARD_ATKBD=y
# CONFIG_KEYBOARD_LKKBD is not set
# CONFIG_KEYBOARD_XTKBD is not set
# CONFIG_KEYBOARD_NEWTON is not set
+# CONFIG_KEYBOARD_STOWAWAY is not set
# CONFIG_INPUT_MOUSE is not set
# CONFIG_INPUT_JOYSTICK is not set
# CONFIG_INPUT_TOUCHSCREEN is not set
@@ -745,6 +806,7 @@ CONFIG_SERIO_LIBPS2=y
# Non-8250 serial port support
#
CONFIG_SERIAL_SH_SCI=y
+CONFIG_SERIAL_SH_SCI_NR_UARTS=2
CONFIG_SERIAL_SH_SCI_CONSOLE=y
CONFIG_SERIAL_CORE=y
CONFIG_SERIAL_CORE_CONSOLE=y
@@ -762,7 +824,7 @@ CONFIG_LEGACY_PTY_COUNT=256
# Watchdog Cards
#
# CONFIG_WATCHDOG is not set
-# CONFIG_RTC is not set
+CONFIG_HW_RANDOM=y
# CONFIG_GEN_RTC is not set
# CONFIG_DTLK is not set
# CONFIG_R3964 is not set
@@ -786,15 +848,23 @@ CONFIG_LEGACY_PTY_COUNT=256
# CONFIG_I2C is not set
#
+# SPI support
+#
+# CONFIG_SPI is not set
+# CONFIG_SPI_MASTER is not set
+
+#
# Dallas's 1-wire bus
#
-# CONFIG_W1 is not set
#
# Hardware Monitoring support
#
CONFIG_HWMON=y
# CONFIG_HWMON_VID is not set
+# CONFIG_SENSORS_ABITUGURU is not set
+# CONFIG_SENSORS_F71805F is not set
+# CONFIG_SENSORS_VT1211 is not set
# CONFIG_HWMON_DEBUG_CHIP is not set
#
@@ -802,13 +872,10 @@ CONFIG_HWMON=y
#
#
-# Multimedia Capabilities Port drivers
-#
-
-#
# Multimedia devices
#
# CONFIG_VIDEO_DEV is not set
+CONFIG_VIDEO_V4L2=y
#
# Digital Video Broadcasting Devices
@@ -818,7 +885,9 @@ CONFIG_HWMON=y
#
# Graphics support
#
+CONFIG_FIRMWARE_EDID=y
# CONFIG_FB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
#
# Sound
@@ -834,18 +903,21 @@ CONFIG_SOUND=m
# Open Sound System
#
CONFIG_SOUND_PRIME=m
-# CONFIG_OBSOLETE_OSS_DRIVER is not set
-# CONFIG_SOUND_FUSION is not set
+# CONFIG_OSS_OBSOLETE_DRIVER is not set
+# CONFIG_SOUND_BT878 is not set
+# CONFIG_SOUND_ES1371 is not set
# CONFIG_SOUND_ICH is not set
# CONFIG_SOUND_TRIDENT is not set
# CONFIG_SOUND_MSNDCLAS is not set
# CONFIG_SOUND_MSNDPIN is not set
+# CONFIG_SOUND_VIA82CXXX is not set
#
# USB support
#
CONFIG_USB_ARCH_HAS_HCD=y
CONFIG_USB_ARCH_HAS_OHCI=y
+CONFIG_USB_ARCH_HAS_EHCI=y
# CONFIG_USB is not set
#
@@ -863,12 +935,43 @@ CONFIG_USB_ARCH_HAS_OHCI=y
# CONFIG_MMC is not set
#
+# LED devices
+#
+# CONFIG_NEW_LEDS is not set
+
+#
+# LED drivers
+#
+
+#
+# LED Triggers
+#
+
+#
# InfiniBand support
#
# CONFIG_INFINIBAND is not set
#
-# SN Devices
+# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
+#
+
+#
+# Real Time Clock
+#
+# CONFIG_RTC_CLASS is not set
+
+#
+# DMA Engine support
+#
+# CONFIG_DMA_ENGINE is not set
+
+#
+# DMA Clients
+#
+
+#
+# DMA Devices
#
#
@@ -888,9 +991,11 @@ CONFIG_FS_MBCACHE=y
# CONFIG_JFS_FS is not set
CONFIG_FS_POSIX_ACL=y
# CONFIG_XFS_FS is not set
+# CONFIG_OCFS2_FS is not set
CONFIG_MINIX_FS=y
# CONFIG_ROMFS_FS is not set
CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
# CONFIG_QUOTA is not set
CONFIG_DNOTIFY=y
# CONFIG_AUTOFS_FS is not set
@@ -920,12 +1025,13 @@ CONFIG_NTFS_RW=y
#
CONFIG_PROC_FS=y
CONFIG_PROC_KCORE=y
+CONFIG_PROC_SYSCTL=y
CONFIG_SYSFS=y
# CONFIG_TMPFS is not set
CONFIG_HUGETLBFS=y
CONFIG_HUGETLB_PAGE=y
CONFIG_RAMFS=y
-# CONFIG_RELAYFS_FS is not set
+# CONFIG_CONFIGFS_FS is not set
#
# Miscellaneous filesystems
@@ -1032,23 +1138,33 @@ CONFIG_NLS_ISO8859_1=y
# Kernel hacking
#
# CONFIG_PRINTK_TIME is not set
-CONFIG_DEBUG_KERNEL=y
+CONFIG_ENABLE_MUST_CHECK=y
# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_UNUSED_SYMBOLS is not set
+CONFIG_DEBUG_KERNEL=y
CONFIG_LOG_BUF_SHIFT=14
CONFIG_DETECT_SOFTLOCKUP=y
# CONFIG_SCHEDSTATS is not set
# CONFIG_DEBUG_SLAB is not set
-CONFIG_DEBUG_PREEMPT=y
CONFIG_DEBUG_SPINLOCK=y
+# CONFIG_DEBUG_MUTEXES is not set
+# CONFIG_DEBUG_RWSEMS is not set
# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
# CONFIG_DEBUG_KOBJECT is not set
+# CONFIG_DEBUG_BUGVERBOSE is not set
# CONFIG_DEBUG_INFO is not set
CONFIG_DEBUG_FS=y
# CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_LIST is not set
CONFIG_FRAME_POINTER=y
+CONFIG_FORCED_INLINING=y
# CONFIG_RCU_TORTURE_TEST is not set
# CONFIG_SH_STANDARD_BIOS is not set
# CONFIG_EARLY_SCIF_CONSOLE is not set
+# CONFIG_DEBUG_STACKOVERFLOW is not set
+# CONFIG_DEBUG_STACK_USAGE is not set
+# CONFIG_4KSTACKS is not set
# CONFIG_KGDB is not set
#
@@ -1061,6 +1177,10 @@ CONFIG_FRAME_POINTER=y
# Cryptographic options
#
CONFIG_CRYPTO=y
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_BLKCIPHER=m
+CONFIG_CRYPTO_HASH=y
+CONFIG_CRYPTO_MANAGER=m
CONFIG_CRYPTO_HMAC=y
# CONFIG_CRYPTO_NULL is not set
# CONFIG_CRYPTO_MD4 is not set
@@ -1070,6 +1190,8 @@ CONFIG_CRYPTO_MD5=y
# CONFIG_CRYPTO_SHA512 is not set
# CONFIG_CRYPTO_WP512 is not set
# CONFIG_CRYPTO_TGR192 is not set
+CONFIG_CRYPTO_ECB=m
+CONFIG_CRYPTO_CBC=m
CONFIG_CRYPTO_DES=y
# CONFIG_CRYPTO_BLOWFISH is not set
# CONFIG_CRYPTO_TWOFISH is not set
diff --git a/arch/sh/configs/rts7751r2d_defconfig b/arch/sh/configs/rts7751r2d_defconfig
index e43cf57326bd..099e98f14729 100644
--- a/arch/sh/configs/rts7751r2d_defconfig
+++ b/arch/sh/configs/rts7751r2d_defconfig
@@ -1,125 +1,215 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.11-sh
-# Wed Mar 2 15:09:42 2005
+# Linux kernel version: 2.6.18
+# Tue Oct 3 11:38:36 2006
#
CONFIG_SUPERH=y
-CONFIG_UID16=y
CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+CONFIG_GENERIC_HWEIGHT=y
CONFIG_GENERIC_HARDIRQS=y
CONFIG_GENERIC_IRQ_PROBE=y
CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
#
# Code maturity level options
#
CONFIG_EXPERIMENTAL=y
-CONFIG_CLEAN_COMPILE=y
CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
#
# General setup
#
CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
CONFIG_SWAP=y
CONFIG_SYSVIPC=y
+# CONFIG_IPC_NS is not set
# CONFIG_POSIX_MQUEUE is not set
# CONFIG_BSD_PROCESS_ACCT is not set
-CONFIG_SYSCTL=y
+# CONFIG_TASKSTATS is not set
+# CONFIG_UTS_NS is not set
# CONFIG_AUDIT is not set
-CONFIG_LOG_BUF_SHIFT=14
-CONFIG_HOTPLUG=y
-CONFIG_KOBJECT_UEVENT=y
# CONFIG_IKCONFIG is not set
+# CONFIG_RELAY is not set
+CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SYSCTL=y
CONFIG_EMBEDDED=y
+CONFIG_UID16=y
+# CONFIG_SYSCTL_SYSCALL is not set
CONFIG_KALLSYMS=y
# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
CONFIG_EPOLL=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
CONFIG_SHMEM=y
-CONFIG_CC_ALIGN_FUNCTIONS=0
-CONFIG_CC_ALIGN_LABELS=0
-CONFIG_CC_ALIGN_LOOPS=0
-CONFIG_CC_ALIGN_JUMPS=0
+CONFIG_SLAB=y
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_RT_MUTEXES=y
# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+# CONFIG_SLOB is not set
#
# Loadable module support
#
CONFIG_MODULES=y
# CONFIG_MODULE_UNLOAD is not set
-CONFIG_OBSOLETE_MODPARM=y
# CONFIG_MODVERSIONS is not set
# CONFIG_MODULE_SRCVERSION_ALL is not set
# CONFIG_KMOD is not set
#
+# Block layer
+#
+CONFIG_BLOCK=y
+# CONFIG_LBD is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_LSF is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+CONFIG_DEFAULT_AS=y
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="anticipatory"
+
+#
# System type
#
# CONFIG_SH_SOLUTION_ENGINE is not set
# CONFIG_SH_7751_SOLUTION_ENGINE is not set
# CONFIG_SH_7300_SOLUTION_ENGINE is not set
+# CONFIG_SH_7343_SOLUTION_ENGINE is not set
# CONFIG_SH_73180_SOLUTION_ENGINE is not set
# CONFIG_SH_7751_SYSTEMH is not set
-# CONFIG_SH_STB1_HARP is not set
-# CONFIG_SH_STB1_OVERDRIVE is not set
-# CONFIG_SH_HP620 is not set
-# CONFIG_SH_HP680 is not set
-# CONFIG_SH_HP690 is not set
-# CONFIG_SH_CQREEK is not set
-# CONFIG_SH_DMIDA is not set
+# CONFIG_SH_HP6XX is not set
# CONFIG_SH_EC3104 is not set
# CONFIG_SH_SATURN is not set
# CONFIG_SH_DREAMCAST is not set
-# CONFIG_SH_CAT68701 is not set
# CONFIG_SH_BIGSUR is not set
-# CONFIG_SH_SH2000 is not set
-# CONFIG_SH_ADX is not set
# CONFIG_SH_MPC1211 is not set
# CONFIG_SH_SH03 is not set
# CONFIG_SH_SECUREEDGE5410 is not set
# CONFIG_SH_HS7751RVOIP is not set
+# CONFIG_SH_7710VOIPGW is not set
CONFIG_SH_RTS7751R2D=y
+# CONFIG_SH_R7780RP is not set
# CONFIG_SH_EDOSK7705 is not set
# CONFIG_SH_SH4202_MICRODEV is not set
+# CONFIG_SH_LANDISK is not set
+# CONFIG_SH_TITAN is not set
+# CONFIG_SH_SHMIN is not set
# CONFIG_SH_UNKNOWN is not set
-# CONFIG_CPU_SH2 is not set
-# CONFIG_CPU_SH3 is not set
+
+#
+# Processor selection
+#
CONFIG_CPU_SH4=y
+
+#
+# SH-2 Processor Support
+#
# CONFIG_CPU_SUBTYPE_SH7604 is not set
+
+#
+# SH-3 Processor Support
+#
# CONFIG_CPU_SUBTYPE_SH7300 is not set
# CONFIG_CPU_SUBTYPE_SH7705 is not set
+# CONFIG_CPU_SUBTYPE_SH7706 is not set
# CONFIG_CPU_SUBTYPE_SH7707 is not set
# CONFIG_CPU_SUBTYPE_SH7708 is not set
# CONFIG_CPU_SUBTYPE_SH7709 is not set
+# CONFIG_CPU_SUBTYPE_SH7710 is not set
+
+#
+# SH-4 Processor Support
+#
# CONFIG_CPU_SUBTYPE_SH7750 is not set
+# CONFIG_CPU_SUBTYPE_SH7091 is not set
+# CONFIG_CPU_SUBTYPE_SH7750R is not set
+# CONFIG_CPU_SUBTYPE_SH7750S is not set
CONFIG_CPU_SUBTYPE_SH7751=y
+CONFIG_CPU_SUBTYPE_SH7751R=y
# CONFIG_CPU_SUBTYPE_SH7760 is not set
-# CONFIG_CPU_SUBTYPE_SH73180 is not set
+# CONFIG_CPU_SUBTYPE_SH4_202 is not set
+
+#
+# ST40 Processor Support
+#
# CONFIG_CPU_SUBTYPE_ST40STB1 is not set
# CONFIG_CPU_SUBTYPE_ST40GX1 is not set
-# CONFIG_CPU_SUBTYPE_SH4_202 is not set
+
+#
+# SH-4A Processor Support
+#
+# CONFIG_CPU_SUBTYPE_SH7770 is not set
+# CONFIG_CPU_SUBTYPE_SH7780 is not set
+
+#
+# SH4AL-DSP Processor Support
+#
+# CONFIG_CPU_SUBTYPE_SH73180 is not set
+# CONFIG_CPU_SUBTYPE_SH7343 is not set
+
+#
+# Memory management options
+#
CONFIG_MMU=y
-CONFIG_CMDLINE_BOOL=y
-CONFIG_CMDLINE="mem=64M console=ttySC0,115200 root=/dev/hda1"
+CONFIG_PAGE_OFFSET=0x80000000
CONFIG_MEMORY_START=0x0c000000
CONFIG_MEMORY_SIZE=0x04000000
-CONFIG_MEMORY_SET=y
-# CONFIG_MEMORY_OVERRIDE is not set
-CONFIG_SH_RTC=y
-CONFIG_SH_FPU=y
-CONFIG_ZERO_PAGE_OFFSET=0x00010000
-CONFIG_BOOT_LINK_OFFSET=0x00800000
-CONFIG_CPU_LITTLE_ENDIAN=y
-# CONFIG_PREEMPT is not set
-# CONFIG_UBC_WAKEUP is not set
+CONFIG_VSYSCALL=y
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+# CONFIG_SPARSEMEM_STATIC is not set
+CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_RESOURCES_64BIT is not set
+
+#
+# Cache configuration
+#
+# CONFIG_SH_DIRECT_MAPPED is not set
# CONFIG_SH_WRITETHROUGH is not set
# CONFIG_SH_OCRAM is not set
+
+#
+# Processor features
+#
+CONFIG_CPU_LITTLE_ENDIAN=y
+CONFIG_SH_FPU=y
+# CONFIG_SH_DSP is not set
# CONFIG_SH_STORE_QUEUES is not set
-# CONFIG_SMP is not set
+CONFIG_CPU_HAS_INTEVT=y
+CONFIG_CPU_HAS_SR_RB=y
+
+#
+# Timer support
+#
+CONFIG_SH_TMU=y
+
+#
+# RTS7751R2D options
+#
CONFIG_RTS7751R2D_REV11=y
-CONFIG_SH_PCLK_CALC=y
CONFIG_SH_PCLK_FREQ=60000000
#
@@ -140,17 +230,37 @@ CONFIG_NR_ONCHIP_DMA_CHANNELS=8
CONFIG_VOYAGERGX=y
# CONFIG_HD6446X_SERIES is not set
CONFIG_HEARTBEAT=y
-CONFIG_RTC_9701JE=y
#
-# Bus options (PCI, PCMCIA, EISA, MCA, ISA)
+# Kernel features
+#
+# CONFIG_HZ_100 is not set
+CONFIG_HZ_250=y
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=250
+# CONFIG_KEXEC is not set
+# CONFIG_SMP is not set
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
+# CONFIG_PREEMPT is not set
+
+#
+# Boot options
+#
+CONFIG_ZERO_PAGE_OFFSET=0x00010000
+CONFIG_BOOT_LINK_OFFSET=0x00800000
+# CONFIG_UBC_WAKEUP is not set
+CONFIG_CMDLINE_BOOL=y
+CONFIG_CMDLINE="mem=64M console=ttySC0,115200 root=/dev/hda1"
+
+#
+# Bus options
#
CONFIG_PCI=y
CONFIG_SH_PCIDMA_NONCOHERENT=y
CONFIG_PCI_AUTO=y
CONFIG_PCI_AUTO_UPDATE_RESOURCES=y
-# CONFIG_PCI_LEGACY_PROC is not set
-CONFIG_PCI_NAMES=y
+# CONFIG_PCI_MULTITHREAD_PROBE is not set
#
# PCCARD (PCMCIA/CardBus) support
@@ -158,10 +268,6 @@ CONFIG_PCI_NAMES=y
# CONFIG_PCCARD is not set
#
-# PC-card bridges
-#
-
-#
# PCI Hotplug Support
#
CONFIG_HOTPLUG_PCI=y
@@ -177,6 +283,95 @@ CONFIG_BINFMT_ELF=y
# CONFIG_BINFMT_MISC is not set
#
+# Power management options (EXPERIMENTAL)
+#
+# CONFIG_PM is not set
+
+#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+# CONFIG_NETDEBUG is not set
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+# CONFIG_XFRM_USER is not set
+# CONFIG_XFRM_SUB_POLICY is not set
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+# CONFIG_IP_PNP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+# CONFIG_INET_TUNNEL is not set
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_IPV6 is not set
+# CONFIG_INET6_XFRM_TUNNEL is not set
+# CONFIG_INET6_TUNNEL is not set
+# CONFIG_NETWORK_SECMARK is not set
+# CONFIG_NETFILTER is not set
+
+#
+# DCCP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_DCCP is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP is not set
+
+#
+# TIPC Configuration (EXPERIMENTAL)
+#
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_IEEE80211 is not set
+CONFIG_WIRELESS_EXT=y
+
+#
# Device Drivers
#
@@ -186,6 +381,12 @@ CONFIG_BINFMT_ELF=y
CONFIG_STANDALONE=y
CONFIG_PREVENT_FIRMWARE_BUILD=y
# CONFIG_FW_LOADER is not set
+# CONFIG_SYS_HYPERVISOR is not set
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
+# CONFIG_CONNECTOR is not set
#
# Memory Technology Devices (MTD)
@@ -204,7 +405,6 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
#
# Block devices
#
-# CONFIG_BLK_DEV_FD is not set
# CONFIG_BLK_CPQ_DA is not set
# CONFIG_BLK_CPQ_CISS_DA is not set
# CONFIG_BLK_DEV_DAC960 is not set
@@ -216,18 +416,9 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
CONFIG_BLK_DEV_RAM=y
CONFIG_BLK_DEV_RAM_COUNT=16
CONFIG_BLK_DEV_RAM_SIZE=4096
+CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
# CONFIG_BLK_DEV_INITRD is not set
-CONFIG_INITRAMFS_SOURCE=""
-# CONFIG_LBD is not set
# CONFIG_CDROM_PKTCDVD is not set
-
-#
-# IO Schedulers
-#
-CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
-CONFIG_IOSCHED_DEADLINE=y
-CONFIG_IOSCHED_CFQ=y
# CONFIG_ATA_OVER_ETH is not set
#
@@ -253,7 +444,6 @@ CONFIG_BLK_DEV_IDEDISK=y
#
CONFIG_IDE_GENERIC=y
# CONFIG_BLK_DEV_IDEPCI is not set
-CONFIG_IDE_SH=y
# CONFIG_IDE_ARM is not set
# CONFIG_BLK_DEV_IDEDMA is not set
# CONFIG_IDEDMA_AUTO is not set
@@ -262,7 +452,14 @@ CONFIG_IDE_SH=y
#
# SCSI device support
#
+# CONFIG_RAID_ATTRS is not set
# CONFIG_SCSI is not set
+# CONFIG_SCSI_NETLINK is not set
+
+#
+# Serial ATA (prod) and Parallel ATA (experimental) drivers
+#
+# CONFIG_ATA is not set
#
# Multi-device support (RAID and LVM)
@@ -272,6 +469,7 @@ CONFIG_IDE_SH=y
#
# Fusion MPT device support
#
+# CONFIG_FUSION is not set
#
# IEEE 1394 (FireWire) support
@@ -284,67 +482,8 @@ CONFIG_IDE_SH=y
# CONFIG_I2O is not set
#
-# Networking support
+# Network device support
#
-CONFIG_NET=y
-
-#
-# Networking options
-#
-CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
-# CONFIG_NETLINK_DEV is not set
-CONFIG_UNIX=y
-# CONFIG_NET_KEY is not set
-CONFIG_INET=y
-# CONFIG_IP_MULTICAST is not set
-# CONFIG_IP_ADVANCED_ROUTER is not set
-# CONFIG_IP_PNP is not set
-# CONFIG_NET_IPIP is not set
-# CONFIG_NET_IPGRE is not set
-# CONFIG_ARPD is not set
-# CONFIG_SYN_COOKIES is not set
-# CONFIG_INET_AH is not set
-# CONFIG_INET_ESP is not set
-# CONFIG_INET_IPCOMP is not set
-# CONFIG_INET_TUNNEL is not set
-CONFIG_IP_TCPDIAG=y
-# CONFIG_IP_TCPDIAG_IPV6 is not set
-# CONFIG_IPV6 is not set
-# CONFIG_NETFILTER is not set
-
-#
-# SCTP Configuration (EXPERIMENTAL)
-#
-# CONFIG_IP_SCTP is not set
-# CONFIG_ATM is not set
-# CONFIG_BRIDGE is not set
-# CONFIG_VLAN_8021Q is not set
-# CONFIG_DECNET is not set
-# CONFIG_LLC2 is not set
-# CONFIG_IPX is not set
-# CONFIG_ATALK is not set
-# CONFIG_X25 is not set
-# CONFIG_LAPB is not set
-# CONFIG_NET_DIVERT is not set
-# CONFIG_ECONET is not set
-# CONFIG_WAN_ROUTER is not set
-
-#
-# QoS and/or fair queueing
-#
-# CONFIG_NET_SCHED is not set
-# CONFIG_NET_CLS_ROUTE is not set
-
-#
-# Network testing
-#
-# CONFIG_NET_PKTGEN is not set
-# CONFIG_NETPOLL is not set
-# CONFIG_NET_POLL_CONTROLLER is not set
-# CONFIG_HAMRADIO is not set
-# CONFIG_IRDA is not set
-# CONFIG_BT is not set
CONFIG_NETDEVICES=y
# CONFIG_DUMMY is not set
# CONFIG_BONDING is not set
@@ -357,6 +496,11 @@ CONFIG_NETDEVICES=y
# CONFIG_ARCNET is not set
#
+# PHY device support
+#
+# CONFIG_PHYLIB is not set
+
+#
# Ethernet (10 or 100Mbit)
#
CONFIG_NET_ETHERNET=y
@@ -364,6 +508,7 @@ CONFIG_MII=y
# CONFIG_STNIC is not set
# CONFIG_HAPPYMEAL is not set
# CONFIG_SUNGEM is not set
+# CONFIG_CASSINI is not set
# CONFIG_NET_VENDOR_3COM is not set
# CONFIG_SMC91X is not set
@@ -406,15 +551,22 @@ CONFIG_8139TOO=y
# CONFIG_HAMACHI is not set
# CONFIG_YELLOWFIN is not set
# CONFIG_R8169 is not set
+# CONFIG_SIS190 is not set
+# CONFIG_SKGE is not set
+# CONFIG_SKY2 is not set
# CONFIG_SK98LIN is not set
# CONFIG_VIA_VELOCITY is not set
# CONFIG_TIGON3 is not set
+# CONFIG_BNX2 is not set
+# CONFIG_QLA3XXX is not set
#
# Ethernet (10000 Mbit)
#
+# CONFIG_CHELSIO_T1 is not set
# CONFIG_IXGB is not set
# CONFIG_S2IO is not set
+# CONFIG_MYRI10GE is not set
#
# Token Ring devices
@@ -425,6 +577,7 @@ CONFIG_8139TOO=y
# Wireless LAN (non-hamradio)
#
CONFIG_NET_RADIO=y
+# CONFIG_NET_WIRELESS_RTNETLINK is not set
#
# Obsolete Wireless cards support (pre-802.11)
@@ -434,9 +587,12 @@ CONFIG_NET_RADIO=y
#
# Wireless 802.11b ISA/PCI cards support
#
+# CONFIG_IPW2100 is not set
+# CONFIG_IPW2200 is not set
CONFIG_HERMES=m
# CONFIG_PLX_HERMES is not set
# CONFIG_TMD_HERMES is not set
+# CONFIG_NORTEL_HERMES is not set
# CONFIG_PCI_HERMES is not set
# CONFIG_ATMEL is not set
@@ -444,6 +600,7 @@ CONFIG_HERMES=m
# Prism GT/Duette 802.11(a/b/g) PCI/Cardbus support
#
# CONFIG_PRISM54 is not set
+# CONFIG_HOSTAP is not set
CONFIG_NET_WIRELESS=y
#
@@ -456,6 +613,8 @@ CONFIG_NET_WIRELESS=y
# CONFIG_SLIP is not set
# CONFIG_SHAPER is not set
# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
#
# ISDN subsystem
@@ -473,20 +632,10 @@ CONFIG_NET_WIRELESS=y
# CONFIG_INPUT is not set
#
-# Userland interfaces
-#
-
+# Hardware I/O ports
#
-# Input I/O drivers
-#
-# CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
# CONFIG_SERIO is not set
-# CONFIG_SERIO_I8042 is not set
-
-#
-# Input Device Drivers
-#
+# CONFIG_GAMEPORT is not set
#
# Character devices
@@ -503,6 +652,7 @@ CONFIG_SOUND_GAMEPORT=y
# Non-8250 serial port support
#
# CONFIG_SERIAL_SH_SCI is not set
+# CONFIG_SERIAL_JSM is not set
# CONFIG_UNIX98_PTYS is not set
CONFIG_LEGACY_PTYS=y
CONFIG_LEGACY_PTY_COUNT=256
@@ -516,7 +666,7 @@ CONFIG_LEGACY_PTY_COUNT=256
# Watchdog Cards
#
# CONFIG_WATCHDOG is not set
-# CONFIG_RTC is not set
+CONFIG_HW_RANDOM=y
# CONFIG_GEN_RTC is not set
# CONFIG_DTLK is not set
# CONFIG_R3964 is not set
@@ -529,14 +679,35 @@ CONFIG_LEGACY_PTY_COUNT=256
# CONFIG_RAW_DRIVER is not set
#
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
+# CONFIG_TELCLOCK is not set
+
+#
# I2C support
#
# CONFIG_I2C is not set
#
+# SPI support
+#
+# CONFIG_SPI is not set
+# CONFIG_SPI_MASTER is not set
+
+#
# Dallas's 1-wire bus
#
-# CONFIG_W1 is not set
+
+#
+# Hardware Monitoring support
+#
+CONFIG_HWMON=y
+# CONFIG_HWMON_VID is not set
+# CONFIG_SENSORS_ABITUGURU is not set
+# CONFIG_SENSORS_F71805F is not set
+# CONFIG_SENSORS_VT1211 is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
#
# Misc devices
@@ -546,6 +717,7 @@ CONFIG_LEGACY_PTY_COUNT=256
# Multimedia devices
#
# CONFIG_VIDEO_DEV is not set
+CONFIG_VIDEO_V4L2=y
#
# Digital Video Broadcasting Devices
@@ -555,7 +727,9 @@ CONFIG_LEGACY_PTY_COUNT=256
#
# Graphics support
#
+CONFIG_FIRMWARE_EDID=y
# CONFIG_FB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
#
# Sound
@@ -573,6 +747,9 @@ CONFIG_SND_RAWMIDI=m
# CONFIG_SND_SEQUENCER is not set
# CONFIG_SND_MIXER_OSS is not set
# CONFIG_SND_PCM_OSS is not set
+# CONFIG_SND_DYNAMIC_MINORS is not set
+CONFIG_SND_SUPPORT_OLD_API=y
+CONFIG_SND_VERBOSE_PROCFS=y
# CONFIG_SND_VERBOSE_PRINTK is not set
# CONFIG_SND_DEBUG is not set
@@ -581,6 +758,8 @@ CONFIG_SND_RAWMIDI=m
#
CONFIG_SND_MPU401_UART=m
CONFIG_SND_OPL3_LIB=m
+CONFIG_SND_AC97_CODEC=m
+CONFIG_SND_AC97_BUS=m
# CONFIG_SND_DUMMY is not set
# CONFIG_SND_MTPAV is not set
# CONFIG_SND_SERIAL_U16550 is not set
@@ -589,7 +768,8 @@ CONFIG_SND_OPL3_LIB=m
#
# PCI devices
#
-CONFIG_SND_AC97_CODEC=m
+# CONFIG_SND_AD1889 is not set
+# CONFIG_SND_ALS300 is not set
# CONFIG_SND_ALI5451 is not set
# CONFIG_SND_ATIIXP is not set
# CONFIG_SND_ATIIXP_MODEM is not set
@@ -598,73 +778,63 @@ CONFIG_SND_AC97_CODEC=m
# CONFIG_SND_AU8830 is not set
# CONFIG_SND_AZT3328 is not set
# CONFIG_SND_BT87X is not set
-# CONFIG_SND_CS46XX is not set
+# CONFIG_SND_CA0106 is not set
+# CONFIG_SND_CMIPCI is not set
# CONFIG_SND_CS4281 is not set
+# CONFIG_SND_CS46XX is not set
# CONFIG_SND_EMU10K1 is not set
# CONFIG_SND_EMU10K1X is not set
-# CONFIG_SND_CA0106 is not set
-# CONFIG_SND_KORG1212 is not set
-# CONFIG_SND_MIXART is not set
-# CONFIG_SND_NM256 is not set
-# CONFIG_SND_RME32 is not set
-# CONFIG_SND_RME96 is not set
-# CONFIG_SND_RME9652 is not set
-# CONFIG_SND_HDSP is not set
-# CONFIG_SND_TRIDENT is not set
-CONFIG_SND_YMFPCI=m
-# CONFIG_SND_ALS4000 is not set
-# CONFIG_SND_CMIPCI is not set
# CONFIG_SND_ENS1370 is not set
# CONFIG_SND_ENS1371 is not set
# CONFIG_SND_ES1938 is not set
# CONFIG_SND_ES1968 is not set
-# CONFIG_SND_MAESTRO3 is not set
# CONFIG_SND_FM801 is not set
+# CONFIG_SND_HDA_INTEL is not set
+# CONFIG_SND_HDSP is not set
+# CONFIG_SND_HDSPM is not set
# CONFIG_SND_ICE1712 is not set
# CONFIG_SND_ICE1724 is not set
# CONFIG_SND_INTEL8X0 is not set
# CONFIG_SND_INTEL8X0M is not set
+# CONFIG_SND_KORG1212 is not set
+# CONFIG_SND_MAESTRO3 is not set
+# CONFIG_SND_MIXART is not set
+# CONFIG_SND_NM256 is not set
+# CONFIG_SND_PCXHR is not set
+# CONFIG_SND_RME32 is not set
+# CONFIG_SND_RME96 is not set
+# CONFIG_SND_RME9652 is not set
# CONFIG_SND_SONICVIBES is not set
+# CONFIG_SND_TRIDENT is not set
# CONFIG_SND_VIA82XX is not set
# CONFIG_SND_VIA82XX_MODEM is not set
# CONFIG_SND_VX222 is not set
+CONFIG_SND_YMFPCI=m
+# CONFIG_SND_AC97_POWER_SAVE is not set
#
# Open Sound System
#
CONFIG_SOUND_PRIME=m
+# CONFIG_OSS_OBSOLETE_DRIVER is not set
# CONFIG_SOUND_BT878 is not set
-CONFIG_SOUND_CMPCI=m
-# CONFIG_SOUND_EMU10K1 is not set
-# CONFIG_SOUND_FUSION is not set
-# CONFIG_SOUND_CS4281 is not set
-# CONFIG_SOUND_ES1370 is not set
# CONFIG_SOUND_ES1371 is not set
-# CONFIG_SOUND_ESSSOLO1 is not set
-# CONFIG_SOUND_MAESTRO is not set
-# CONFIG_SOUND_MAESTRO3 is not set
# CONFIG_SOUND_ICH is not set
-# CONFIG_SOUND_SONICVIBES is not set
# CONFIG_SOUND_TRIDENT is not set
# CONFIG_SOUND_MSNDCLAS is not set
# CONFIG_SOUND_MSNDPIN is not set
# CONFIG_SOUND_VIA82CXXX is not set
-# CONFIG_SOUND_OSS is not set
-# CONFIG_SOUND_ALI5455 is not set
-# CONFIG_SOUND_FORTE is not set
-# CONFIG_SOUND_RME96XX is not set
-# CONFIG_SOUND_AD1980 is not set
-CONFIG_SOUND_VOYAGERGX=m
#
# USB support
#
-# CONFIG_USB is not set
CONFIG_USB_ARCH_HAS_HCD=y
CONFIG_USB_ARCH_HAS_OHCI=y
+CONFIG_USB_ARCH_HAS_EHCI=y
+# CONFIG_USB is not set
#
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
#
#
@@ -678,30 +848,66 @@ CONFIG_USB_ARCH_HAS_OHCI=y
# CONFIG_MMC is not set
#
+# LED devices
+#
+# CONFIG_NEW_LEDS is not set
+
+#
+# LED drivers
+#
+
+#
+# LED Triggers
+#
+
+#
# InfiniBand support
#
# CONFIG_INFINIBAND is not set
#
+# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
+#
+
+#
+# Real Time Clock
+#
+# CONFIG_RTC_CLASS is not set
+
+#
+# DMA Engine support
+#
+# CONFIG_DMA_ENGINE is not set
+
+#
+# DMA Clients
+#
+
+#
+# DMA Devices
+#
+
+#
# File systems
#
CONFIG_EXT2_FS=y
# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
# CONFIG_EXT3_FS is not set
-# CONFIG_JBD is not set
# CONFIG_REISERFS_FS is not set
# CONFIG_JFS_FS is not set
-
-#
-# XFS support
-#
+# CONFIG_FS_POSIX_ACL is not set
# CONFIG_XFS_FS is not set
+# CONFIG_OCFS2_FS is not set
CONFIG_MINIX_FS=y
# CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
# CONFIG_QUOTA is not set
CONFIG_DNOTIFY=y
# CONFIG_AUTOFS_FS is not set
# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
#
# CD-ROM/DVD Filesystems
@@ -724,12 +930,13 @@ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
#
CONFIG_PROC_FS=y
CONFIG_PROC_KCORE=y
+CONFIG_PROC_SYSCTL=y
CONFIG_SYSFS=y
-# CONFIG_DEVFS_FS is not set
# CONFIG_TMPFS is not set
# CONFIG_HUGETLBFS is not set
# CONFIG_HUGETLB_PAGE is not set
CONFIG_RAMFS=y
+# CONFIG_CONFIGFS_FS is not set
#
# Miscellaneous filesystems
@@ -758,6 +965,7 @@ CONFIG_RAMFS=y
# CONFIG_NCP_FS is not set
# CONFIG_CODA_FS is not set
# CONFIG_AFS_FS is not set
+# CONFIG_9P_FS is not set
#
# Partition Types
@@ -818,8 +1026,14 @@ CONFIG_OPROFILE=y
#
# Kernel hacking
#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_MUST_CHECK=y
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_UNUSED_SYMBOLS is not set
# CONFIG_DEBUG_KERNEL is not set
-# CONFIG_FRAME_POINTER is not set
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_DEBUG_BUGVERBOSE is not set
+# CONFIG_DEBUG_FS is not set
# CONFIG_SH_STANDARD_BIOS is not set
# CONFIG_EARLY_SCIF_CONSOLE is not set
# CONFIG_KGDB is not set
@@ -836,12 +1050,10 @@ CONFIG_OPROFILE=y
# CONFIG_CRYPTO is not set
#
-# Hardware crypto devices
-#
-
-#
# Library routines
#
# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
CONFIG_CRC32=y
# CONFIG_LIBCRC32C is not set
+CONFIG_PLIST=y
diff --git a/arch/sh/configs/se7300_defconfig b/arch/sh/configs/se7300_defconfig
index 4b71cd692fa5..8a217908b81f 100644
--- a/arch/sh/configs/se7300_defconfig
+++ b/arch/sh/configs/se7300_defconfig
@@ -1,45 +1,55 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.11-sh
-# Wed Mar 2 15:09:43 2005
+# Linux kernel version: 2.6.18
+# Tue Oct 3 11:43:22 2006
#
CONFIG_SUPERH=y
-CONFIG_UID16=y
CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+CONFIG_GENERIC_HWEIGHT=y
CONFIG_GENERIC_HARDIRQS=y
CONFIG_GENERIC_IRQ_PROBE=y
CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
#
# Code maturity level options
#
CONFIG_EXPERIMENTAL=y
-CONFIG_CLEAN_COMPILE=y
CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
#
# General setup
#
CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
# CONFIG_SWAP is not set
# CONFIG_SYSVIPC is not set
# CONFIG_BSD_PROCESS_ACCT is not set
-CONFIG_SYSCTL=y
-# CONFIG_AUDIT is not set
-CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_HOTPLUG is not set
+# CONFIG_UTS_NS is not set
# CONFIG_IKCONFIG is not set
+# CONFIG_RELAY is not set
+CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SYSCTL=y
CONFIG_EMBEDDED=y
+CONFIG_UID16=y
+# CONFIG_SYSCTL_SYSCALL is not set
# CONFIG_KALLSYMS is not set
+# CONFIG_HOTPLUG is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
# CONFIG_FUTEX is not set
# CONFIG_EPOLL is not set
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
CONFIG_SHMEM=y
-CONFIG_CC_ALIGN_FUNCTIONS=0
-CONFIG_CC_ALIGN_LABELS=0
-CONFIG_CC_ALIGN_LOOPS=0
-CONFIG_CC_ALIGN_JUMPS=0
+CONFIG_SLAB=y
+CONFIG_VM_EVENT_COUNTERS=y
# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+# CONFIG_SLOB is not set
#
# Loadable module support
@@ -47,68 +57,145 @@ CONFIG_CC_ALIGN_JUMPS=0
# CONFIG_MODULES is not set
#
+# Block layer
+#
+CONFIG_BLOCK=y
+# CONFIG_LBD is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_LSF is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+# CONFIG_IOSCHED_AS is not set
+# CONFIG_IOSCHED_DEADLINE is not set
+# CONFIG_IOSCHED_CFQ is not set
+# CONFIG_DEFAULT_AS is not set
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+CONFIG_DEFAULT_NOOP=y
+CONFIG_DEFAULT_IOSCHED="noop"
+
+#
# System type
#
+CONFIG_SOLUTION_ENGINE=y
# CONFIG_SH_SOLUTION_ENGINE is not set
# CONFIG_SH_7751_SOLUTION_ENGINE is not set
CONFIG_SH_7300_SOLUTION_ENGINE=y
+# CONFIG_SH_7343_SOLUTION_ENGINE is not set
# CONFIG_SH_73180_SOLUTION_ENGINE is not set
# CONFIG_SH_7751_SYSTEMH is not set
-# CONFIG_SH_STB1_HARP is not set
-# CONFIG_SH_STB1_OVERDRIVE is not set
-# CONFIG_SH_HP620 is not set
-# CONFIG_SH_HP680 is not set
-# CONFIG_SH_HP690 is not set
-# CONFIG_SH_CQREEK is not set
-# CONFIG_SH_DMIDA is not set
+# CONFIG_SH_HP6XX is not set
# CONFIG_SH_EC3104 is not set
# CONFIG_SH_SATURN is not set
# CONFIG_SH_DREAMCAST is not set
-# CONFIG_SH_CAT68701 is not set
# CONFIG_SH_BIGSUR is not set
-# CONFIG_SH_SH2000 is not set
-# CONFIG_SH_ADX is not set
# CONFIG_SH_MPC1211 is not set
# CONFIG_SH_SH03 is not set
# CONFIG_SH_SECUREEDGE5410 is not set
# CONFIG_SH_HS7751RVOIP is not set
+# CONFIG_SH_7710VOIPGW is not set
# CONFIG_SH_RTS7751R2D is not set
+# CONFIG_SH_R7780RP is not set
# CONFIG_SH_EDOSK7705 is not set
# CONFIG_SH_SH4202_MICRODEV is not set
+# CONFIG_SH_LANDISK is not set
+# CONFIG_SH_TITAN is not set
+# CONFIG_SH_SHMIN is not set
# CONFIG_SH_UNKNOWN is not set
-# CONFIG_CPU_SH2 is not set
+
+#
+# Processor selection
+#
CONFIG_CPU_SH3=y
-# CONFIG_CPU_SH4 is not set
+
+#
+# SH-2 Processor Support
+#
# CONFIG_CPU_SUBTYPE_SH7604 is not set
+
+#
+# SH-3 Processor Support
+#
CONFIG_CPU_SUBTYPE_SH7300=y
# CONFIG_CPU_SUBTYPE_SH7705 is not set
+# CONFIG_CPU_SUBTYPE_SH7706 is not set
# CONFIG_CPU_SUBTYPE_SH7707 is not set
# CONFIG_CPU_SUBTYPE_SH7708 is not set
# CONFIG_CPU_SUBTYPE_SH7709 is not set
+# CONFIG_CPU_SUBTYPE_SH7710 is not set
+
+#
+# SH-4 Processor Support
+#
# CONFIG_CPU_SUBTYPE_SH7750 is not set
+# CONFIG_CPU_SUBTYPE_SH7091 is not set
+# CONFIG_CPU_SUBTYPE_SH7750R is not set
+# CONFIG_CPU_SUBTYPE_SH7750S is not set
# CONFIG_CPU_SUBTYPE_SH7751 is not set
+# CONFIG_CPU_SUBTYPE_SH7751R is not set
# CONFIG_CPU_SUBTYPE_SH7760 is not set
-# CONFIG_CPU_SUBTYPE_SH73180 is not set
+# CONFIG_CPU_SUBTYPE_SH4_202 is not set
+
+#
+# ST40 Processor Support
+#
# CONFIG_CPU_SUBTYPE_ST40STB1 is not set
# CONFIG_CPU_SUBTYPE_ST40GX1 is not set
-# CONFIG_CPU_SUBTYPE_SH4_202 is not set
+
+#
+# SH-4A Processor Support
+#
+# CONFIG_CPU_SUBTYPE_SH7770 is not set
+# CONFIG_CPU_SUBTYPE_SH7780 is not set
+
+#
+# SH4AL-DSP Processor Support
+#
+# CONFIG_CPU_SUBTYPE_SH73180 is not set
+# CONFIG_CPU_SUBTYPE_SH7343 is not set
+
+#
+# Memory management options
+#
CONFIG_MMU=y
-CONFIG_CMDLINE_BOOL=y
-CONFIG_CMDLINE="console=ttySC0,38400 root=/dev/ram0"
+CONFIG_PAGE_OFFSET=0x80000000
CONFIG_MEMORY_START=0x0c000000
CONFIG_MEMORY_SIZE=0x04000000
-# CONFIG_MEMORY_OVERRIDE is not set
-CONFIG_SH_DSP=y
-# CONFIG_SH_ADC is not set
-CONFIG_ZERO_PAGE_OFFSET=0x00001000
-CONFIG_BOOT_LINK_OFFSET=0x00210000
-CONFIG_CPU_LITTLE_ENDIAN=y
-# CONFIG_PREEMPT is not set
-# CONFIG_UBC_WAKEUP is not set
+CONFIG_VSYSCALL=y
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+# CONFIG_SPARSEMEM_STATIC is not set
+CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_RESOURCES_64BIT is not set
+
+#
+# Cache configuration
+#
+# CONFIG_SH_DIRECT_MAPPED is not set
# CONFIG_SH_WRITETHROUGH is not set
# CONFIG_SH_OCRAM is not set
-# CONFIG_SMP is not set
-# CONFIG_SH_PCLK_CALC is not set
+
+#
+# Processor features
+#
+CONFIG_CPU_LITTLE_ENDIAN=y
+# CONFIG_SH_FPU_EMU is not set
+CONFIG_SH_DSP=y
+# CONFIG_SH_ADC is not set
+CONFIG_CPU_HAS_INTEVT=y
+CONFIG_CPU_HAS_SR_RB=y
+
+#
+# Timer support
+#
+CONFIG_SH_TMU=y
CONFIG_SH_PCLK_FREQ=33333333
#
@@ -128,17 +215,34 @@ CONFIG_SH_PCLK_FREQ=33333333
CONFIG_HEARTBEAT=y
#
-# Bus options (PCI, PCMCIA, EISA, MCA, ISA)
+# Kernel features
#
-# CONFIG_PCI is not set
+# CONFIG_HZ_100 is not set
+CONFIG_HZ_250=y
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=250
+# CONFIG_KEXEC is not set
+# CONFIG_SMP is not set
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
+# CONFIG_PREEMPT is not set
#
-# PCCARD (PCMCIA/CardBus) support
+# Boot options
+#
+CONFIG_ZERO_PAGE_OFFSET=0x00001000
+CONFIG_BOOT_LINK_OFFSET=0x00210000
+# CONFIG_UBC_WAKEUP is not set
+CONFIG_CMDLINE_BOOL=y
+CONFIG_CMDLINE="console=ttySC0,38400 root=/dev/ram0"
+
+#
+# Bus options
#
-# CONFIG_PCCARD is not set
+# CONFIG_PCI is not set
#
-# PC-card bridges
+# PCCARD (PCMCIA/CardBus) support
#
#
@@ -153,10 +257,14 @@ CONFIG_BINFMT_ELF=y
# CONFIG_BINFMT_MISC is not set
#
-# SH initrd options
+# Power management options (EXPERIMENTAL)
+#
+# CONFIG_PM is not set
+
+#
+# Networking
#
-CONFIG_EMBEDDED_RAMDISK=y
-CONFIG_EMBEDDED_RAMDISK_IMAGE="ramdisk.gz"
+# CONFIG_NET is not set
#
# Device Drivers
@@ -167,7 +275,11 @@ CONFIG_EMBEDDED_RAMDISK_IMAGE="ramdisk.gz"
#
CONFIG_STANDALONE=y
CONFIG_PREVENT_FIRMWARE_BUILD=y
-# CONFIG_FW_LOADER is not set
+# CONFIG_SYS_HYPERVISOR is not set
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
#
# Memory Technology Devices (MTD)
@@ -186,26 +298,16 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
#
# Block devices
#
-# CONFIG_BLK_DEV_FD is not set
# CONFIG_BLK_DEV_COW_COMMON is not set
# CONFIG_BLK_DEV_LOOP is not set
CONFIG_BLK_DEV_RAM=y
CONFIG_BLK_DEV_RAM_COUNT=16
CONFIG_BLK_DEV_RAM_SIZE=4096
+CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
CONFIG_BLK_DEV_INITRD=y
-CONFIG_INITRAMFS_SOURCE=""
-# CONFIG_LBD is not set
# CONFIG_CDROM_PKTCDVD is not set
#
-# IO Schedulers
-#
-CONFIG_IOSCHED_NOOP=y
-# CONFIG_IOSCHED_AS is not set
-# CONFIG_IOSCHED_DEADLINE is not set
-# CONFIG_IOSCHED_CFQ is not set
-
-#
# ATA/ATAPI/MFM/RLL support
#
# CONFIG_IDE is not set
@@ -213,7 +315,14 @@ CONFIG_IOSCHED_NOOP=y
#
# SCSI device support
#
+# CONFIG_RAID_ATTRS is not set
# CONFIG_SCSI is not set
+# CONFIG_SCSI_NETLINK is not set
+
+#
+# Serial ATA (prod) and Parallel ATA (experimental) drivers
+#
+# CONFIG_ATA is not set
#
# Multi-device support (RAID and LVM)
@@ -223,6 +332,7 @@ CONFIG_IOSCHED_NOOP=y
#
# Fusion MPT device support
#
+# CONFIG_FUSION is not set
#
# IEEE 1394 (FireWire) support
@@ -233,13 +343,6 @@ CONFIG_IOSCHED_NOOP=y
#
#
-# Networking support
-#
-# CONFIG_NET is not set
-# CONFIG_NETPOLL is not set
-# CONFIG_NET_POLL_CONTROLLER is not set
-
-#
# ISDN subsystem
#
@@ -252,6 +355,7 @@ CONFIG_IOSCHED_NOOP=y
# Input device support
#
CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
#
# Userland interfaces
@@ -266,18 +370,6 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
# CONFIG_INPUT_EVBUG is not set
#
-# Input I/O drivers
-#
-# CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
-CONFIG_SERIO=y
-# CONFIG_SERIO_I8042 is not set
-# CONFIG_SERIO_SERPORT is not set
-# CONFIG_SERIO_CT82C710 is not set
-# CONFIG_SERIO_LIBPS2 is not set
-# CONFIG_SERIO_RAW is not set
-
-#
# Input Device Drivers
#
# CONFIG_INPUT_KEYBOARD is not set
@@ -287,6 +379,16 @@ CONFIG_SERIO=y
# CONFIG_INPUT_MISC is not set
#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+# CONFIG_SERIO_I8042 is not set
+# CONFIG_SERIO_SERPORT is not set
+# CONFIG_SERIO_LIBPS2 is not set
+# CONFIG_SERIO_RAW is not set
+# CONFIG_GAMEPORT is not set
+
+#
# Character devices
#
# CONFIG_VT is not set
@@ -301,6 +403,7 @@ CONFIG_SERIO=y
# Non-8250 serial port support
#
CONFIG_SERIAL_SH_SCI=y
+CONFIG_SERIAL_SH_SCI_NR_UARTS=2
CONFIG_SERIAL_SH_SCI_CONSOLE=y
CONFIG_SERIAL_CORE=y
CONFIG_SERIAL_CORE_CONSOLE=y
@@ -328,7 +431,7 @@ CONFIG_WATCHDOG=y
#
CONFIG_SOFT_WATCHDOG=y
# CONFIG_SH_WDT is not set
-# CONFIG_RTC is not set
+CONFIG_HW_RANDOM=y
# CONFIG_GEN_RTC is not set
# CONFIG_DTLK is not set
# CONFIG_R3964 is not set
@@ -336,18 +439,38 @@ CONFIG_SOFT_WATCHDOG=y
#
# Ftape, the floppy tape device driver
#
-# CONFIG_DRM is not set
# CONFIG_RAW_DRIVER is not set
#
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
+# CONFIG_TELCLOCK is not set
+
+#
# I2C support
#
# CONFIG_I2C is not set
#
+# SPI support
+#
+# CONFIG_SPI is not set
+# CONFIG_SPI_MASTER is not set
+
+#
# Dallas's 1-wire bus
#
-# CONFIG_W1 is not set
+
+#
+# Hardware Monitoring support
+#
+CONFIG_HWMON=y
+# CONFIG_HWMON_VID is not set
+# CONFIG_SENSORS_ABITUGURU is not set
+# CONFIG_SENSORS_F71805F is not set
+# CONFIG_SENSORS_VT1211 is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
#
# Misc devices
@@ -357,6 +480,7 @@ CONFIG_SOFT_WATCHDOG=y
# Multimedia devices
#
# CONFIG_VIDEO_DEV is not set
+CONFIG_VIDEO_V4L2=y
#
# Digital Video Broadcasting Devices
@@ -365,7 +489,9 @@ CONFIG_SOFT_WATCHDOG=y
#
# Graphics support
#
+CONFIG_FIRMWARE_EDID=y
# CONFIG_FB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
#
# Sound
@@ -377,9 +503,10 @@ CONFIG_SOFT_WATCHDOG=y
#
# CONFIG_USB_ARCH_HAS_HCD is not set
# CONFIG_USB_ARCH_HAS_OHCI is not set
+# CONFIG_USB_ARCH_HAS_EHCI is not set
#
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
#
#
@@ -393,30 +520,64 @@ CONFIG_SOFT_WATCHDOG=y
# CONFIG_MMC is not set
#
+# LED devices
+#
+# CONFIG_NEW_LEDS is not set
+
+#
+# LED drivers
+#
+
+#
+# LED Triggers
+#
+
+#
# InfiniBand support
#
-# CONFIG_INFINIBAND is not set
+
+#
+# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
+#
+
+#
+# Real Time Clock
+#
+# CONFIG_RTC_CLASS is not set
+
+#
+# DMA Engine support
+#
+# CONFIG_DMA_ENGINE is not set
+
+#
+# DMA Clients
+#
+
+#
+# DMA Devices
+#
#
# File systems
#
CONFIG_EXT2_FS=y
# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
# CONFIG_EXT3_FS is not set
-# CONFIG_JBD is not set
# CONFIG_REISERFS_FS is not set
# CONFIG_JFS_FS is not set
-
-#
-# XFS support
-#
+# CONFIG_FS_POSIX_ACL is not set
# CONFIG_XFS_FS is not set
# CONFIG_MINIX_FS is not set
# CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
# CONFIG_QUOTA is not set
CONFIG_DNOTIFY=y
# CONFIG_AUTOFS_FS is not set
# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
#
# CD-ROM/DVD Filesystems
@@ -436,14 +597,13 @@ CONFIG_DNOTIFY=y
#
CONFIG_PROC_FS=y
CONFIG_PROC_KCORE=y
+CONFIG_PROC_SYSCTL=y
CONFIG_SYSFS=y
-CONFIG_DEVFS_FS=y
-CONFIG_DEVFS_MOUNT=y
-# CONFIG_DEVFS_DEBUG is not set
# CONFIG_TMPFS is not set
# CONFIG_HUGETLBFS is not set
# CONFIG_HUGETLB_PAGE is not set
CONFIG_RAMFS=y
+# CONFIG_CONFIGFS_FS is not set
#
# Miscellaneous filesystems
@@ -481,8 +641,16 @@ CONFIG_MSDOS_PARTITION=y
#
# Kernel hacking
#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_MUST_CHECK=y
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_UNUSED_SYMBOLS is not set
# CONFIG_DEBUG_KERNEL is not set
-# CONFIG_FRAME_POINTER is not set
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_DEBUG_BUGVERBOSE is not set
+# CONFIG_DEBUG_FS is not set
+CONFIG_FRAME_POINTER=y
+# CONFIG_UNWIND_INFO is not set
CONFIG_SH_STANDARD_BIOS=y
CONFIG_EARLY_PRINTK=y
CONFIG_KGDB=y
@@ -520,12 +688,9 @@ CONFIG_KGDB_DEFBITS_8=y
# CONFIG_CRYPTO is not set
#
-# Hardware crypto devices
-#
-
-#
# Library routines
#
# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
CONFIG_CRC32=y
# CONFIG_LIBCRC32C is not set
diff --git a/arch/sh/configs/se73180_defconfig b/arch/sh/configs/se73180_defconfig
index fe19feb95ca9..1a766153cbb0 100644
--- a/arch/sh/configs/se73180_defconfig
+++ b/arch/sh/configs/se73180_defconfig
@@ -1,120 +1,208 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.11-sh
-# Wed Mar 2 15:09:44 2005
+# Linux kernel version: 2.6.18
+# Tue Oct 3 11:44:45 2006
#
CONFIG_SUPERH=y
-CONFIG_UID16=y
CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+CONFIG_GENERIC_HWEIGHT=y
CONFIG_GENERIC_HARDIRQS=y
CONFIG_GENERIC_IRQ_PROBE=y
CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
#
# Code maturity level options
#
CONFIG_EXPERIMENTAL=y
-CONFIG_CLEAN_COMPILE=y
CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
#
# General setup
#
CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
CONFIG_SWAP=y
# CONFIG_SYSVIPC is not set
# CONFIG_BSD_PROCESS_ACCT is not set
-# CONFIG_SYSCTL is not set
-# CONFIG_AUDIT is not set
-CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_HOTPLUG is not set
+# CONFIG_UTS_NS is not set
# CONFIG_IKCONFIG is not set
+# CONFIG_RELAY is not set
+CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SYSCTL=y
CONFIG_EMBEDDED=y
+CONFIG_UID16=y
+# CONFIG_SYSCTL_SYSCALL is not set
# CONFIG_KALLSYMS is not set
+# CONFIG_HOTPLUG is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
# CONFIG_FUTEX is not set
# CONFIG_EPOLL is not set
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
CONFIG_SHMEM=y
-CONFIG_CC_ALIGN_FUNCTIONS=0
-CONFIG_CC_ALIGN_LABELS=0
-CONFIG_CC_ALIGN_LOOPS=0
-CONFIG_CC_ALIGN_JUMPS=0
+CONFIG_SLAB=y
+CONFIG_VM_EVENT_COUNTERS=y
# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+# CONFIG_SLOB is not set
#
# Loadable module support
#
CONFIG_MODULES=y
# CONFIG_MODULE_UNLOAD is not set
-CONFIG_OBSOLETE_MODPARM=y
# CONFIG_MODVERSIONS is not set
# CONFIG_MODULE_SRCVERSION_ALL is not set
# CONFIG_KMOD is not set
#
+# Block layer
+#
+CONFIG_BLOCK=y
+# CONFIG_LBD is not set
+# CONFIG_LSF is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+# CONFIG_IOSCHED_AS is not set
+# CONFIG_IOSCHED_DEADLINE is not set
+# CONFIG_IOSCHED_CFQ is not set
+# CONFIG_DEFAULT_AS is not set
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+CONFIG_DEFAULT_NOOP=y
+CONFIG_DEFAULT_IOSCHED="noop"
+
+#
# System type
#
+CONFIG_SOLUTION_ENGINE=y
# CONFIG_SH_SOLUTION_ENGINE is not set
# CONFIG_SH_7751_SOLUTION_ENGINE is not set
# CONFIG_SH_7300_SOLUTION_ENGINE is not set
+# CONFIG_SH_7343_SOLUTION_ENGINE is not set
CONFIG_SH_73180_SOLUTION_ENGINE=y
# CONFIG_SH_7751_SYSTEMH is not set
-# CONFIG_SH_STB1_HARP is not set
-# CONFIG_SH_STB1_OVERDRIVE is not set
-# CONFIG_SH_HP620 is not set
-# CONFIG_SH_HP680 is not set
-# CONFIG_SH_HP690 is not set
-# CONFIG_SH_CQREEK is not set
-# CONFIG_SH_DMIDA is not set
+# CONFIG_SH_HP6XX is not set
# CONFIG_SH_EC3104 is not set
# CONFIG_SH_SATURN is not set
# CONFIG_SH_DREAMCAST is not set
-# CONFIG_SH_CAT68701 is not set
# CONFIG_SH_BIGSUR is not set
-# CONFIG_SH_SH2000 is not set
-# CONFIG_SH_ADX is not set
# CONFIG_SH_MPC1211 is not set
# CONFIG_SH_SH03 is not set
# CONFIG_SH_SECUREEDGE5410 is not set
# CONFIG_SH_HS7751RVOIP is not set
+# CONFIG_SH_7710VOIPGW is not set
# CONFIG_SH_RTS7751R2D is not set
# CONFIG_SH_R7780RP is not set
# CONFIG_SH_EDOSK7705 is not set
# CONFIG_SH_SH4202_MICRODEV is not set
+# CONFIG_SH_LANDISK is not set
+# CONFIG_SH_TITAN is not set
+# CONFIG_SH_SHMIN is not set
# CONFIG_SH_UNKNOWN is not set
-# CONFIG_CPU_SH2 is not set
-# CONFIG_CPU_SH3 is not set
+
+#
+# Processor selection
+#
CONFIG_CPU_SH4=y
+CONFIG_CPU_SH4A=y
+CONFIG_CPU_SH4AL_DSP=y
+
+#
+# SH-2 Processor Support
+#
# CONFIG_CPU_SUBTYPE_SH7604 is not set
+
+#
+# SH-3 Processor Support
+#
# CONFIG_CPU_SUBTYPE_SH7300 is not set
# CONFIG_CPU_SUBTYPE_SH7705 is not set
+# CONFIG_CPU_SUBTYPE_SH7706 is not set
# CONFIG_CPU_SUBTYPE_SH7707 is not set
# CONFIG_CPU_SUBTYPE_SH7708 is not set
# CONFIG_CPU_SUBTYPE_SH7709 is not set
+# CONFIG_CPU_SUBTYPE_SH7710 is not set
+
+#
+# SH-4 Processor Support
+#
# CONFIG_CPU_SUBTYPE_SH7750 is not set
+# CONFIG_CPU_SUBTYPE_SH7091 is not set
+# CONFIG_CPU_SUBTYPE_SH7750R is not set
+# CONFIG_CPU_SUBTYPE_SH7750S is not set
# CONFIG_CPU_SUBTYPE_SH7751 is not set
+# CONFIG_CPU_SUBTYPE_SH7751R is not set
# CONFIG_CPU_SUBTYPE_SH7760 is not set
-CONFIG_CPU_SUBTYPE_SH73180=y
+# CONFIG_CPU_SUBTYPE_SH4_202 is not set
+
+#
+# ST40 Processor Support
+#
# CONFIG_CPU_SUBTYPE_ST40STB1 is not set
# CONFIG_CPU_SUBTYPE_ST40GX1 is not set
-# CONFIG_CPU_SUBTYPE_SH4_202 is not set
+
+#
+# SH-4A Processor Support
+#
+# CONFIG_CPU_SUBTYPE_SH7770 is not set
+# CONFIG_CPU_SUBTYPE_SH7780 is not set
+
+#
+# SH4AL-DSP Processor Support
+#
+CONFIG_CPU_SUBTYPE_SH73180=y
+# CONFIG_CPU_SUBTYPE_SH7343 is not set
+
+#
+# Memory management options
+#
CONFIG_MMU=y
-CONFIG_CMDLINE_BOOL=y
-CONFIG_CMDLINE="console=ttySC0,38400 root=/dev/ram"
+CONFIG_PAGE_OFFSET=0x80000000
CONFIG_MEMORY_START=0x0c000000
CONFIG_MEMORY_SIZE=0x02000000
-# CONFIG_MEMORY_OVERRIDE is not set
-# CONFIG_SH_FPU is not set
-CONFIG_ZERO_PAGE_OFFSET=0x00010000
-CONFIG_BOOT_LINK_OFFSET=0x00800000
-CONFIG_CPU_LITTLE_ENDIAN=y
-# CONFIG_PREEMPT is not set
-# CONFIG_UBC_WAKEUP is not set
+CONFIG_32BIT=y
+CONFIG_VSYSCALL=y
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+# CONFIG_SPARSEMEM_STATIC is not set
+CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_RESOURCES_64BIT is not set
+
+#
+# Cache configuration
+#
+# CONFIG_SH_DIRECT_MAPPED is not set
# CONFIG_SH_WRITETHROUGH is not set
# CONFIG_SH_OCRAM is not set
+
+#
+# Processor features
+#
+CONFIG_CPU_LITTLE_ENDIAN=y
+# CONFIG_SH_FPU is not set
+# CONFIG_SH_FPU_EMU is not set
+CONFIG_SH_DSP=y
# CONFIG_SH_STORE_QUEUES is not set
-# CONFIG_SMP is not set
-# CONFIG_SH_PCLK_CALC is not set
+CONFIG_CPU_HAS_INTEVT=y
+CONFIG_CPU_HAS_SR_RB=y
+
+#
+# Timer support
+#
+CONFIG_SH_TMU=y
CONFIG_SH_PCLK_FREQ=27000000
#
@@ -134,17 +222,34 @@ CONFIG_SH_PCLK_FREQ=27000000
CONFIG_HEARTBEAT=y
#
-# Bus options (PCI, PCMCIA, EISA, MCA, ISA)
+# Kernel features
#
-# CONFIG_PCI is not set
+# CONFIG_HZ_100 is not set
+CONFIG_HZ_250=y
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=250
+# CONFIG_KEXEC is not set
+# CONFIG_SMP is not set
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
+# CONFIG_PREEMPT is not set
#
-# PCCARD (PCMCIA/CardBus) support
+# Boot options
#
-# CONFIG_PCCARD is not set
+CONFIG_ZERO_PAGE_OFFSET=0x00010000
+CONFIG_BOOT_LINK_OFFSET=0x00800000
+# CONFIG_UBC_WAKEUP is not set
+CONFIG_CMDLINE_BOOL=y
+CONFIG_CMDLINE="console=ttySC0,38400 root=/dev/ram"
#
-# PC-card bridges
+# Bus options
+#
+# CONFIG_PCI is not set
+
+#
+# PCCARD (PCMCIA/CardBus) support
#
#
@@ -159,10 +264,14 @@ CONFIG_BINFMT_ELF=y
# CONFIG_BINFMT_MISC is not set
#
-# SH initrd options
+# Power management options (EXPERIMENTAL)
+#
+# CONFIG_PM is not set
+
+#
+# Networking
#
-CONFIG_EMBEDDED_RAMDISK=y
-CONFIG_EMBEDDED_RAMDISK_IMAGE="ramdisk.gz"
+# CONFIG_NET is not set
#
# Device Drivers
@@ -173,7 +282,11 @@ CONFIG_EMBEDDED_RAMDISK_IMAGE="ramdisk.gz"
#
CONFIG_STANDALONE=y
CONFIG_PREVENT_FIRMWARE_BUILD=y
-# CONFIG_FW_LOADER is not set
+# CONFIG_SYS_HYPERVISOR is not set
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
#
# Memory Technology Devices (MTD)
@@ -192,27 +305,17 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
#
# Block devices
#
-# CONFIG_BLK_DEV_FD is not set
# CONFIG_BLK_DEV_COW_COMMON is not set
CONFIG_BLK_DEV_LOOP=y
# CONFIG_BLK_DEV_CRYPTOLOOP is not set
CONFIG_BLK_DEV_RAM=y
CONFIG_BLK_DEV_RAM_COUNT=16
CONFIG_BLK_DEV_RAM_SIZE=4096
+CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
CONFIG_BLK_DEV_INITRD=y
-CONFIG_INITRAMFS_SOURCE=""
-# CONFIG_LBD is not set
# CONFIG_CDROM_PKTCDVD is not set
#
-# IO Schedulers
-#
-CONFIG_IOSCHED_NOOP=y
-# CONFIG_IOSCHED_AS is not set
-# CONFIG_IOSCHED_DEADLINE is not set
-# CONFIG_IOSCHED_CFQ is not set
-
-#
# ATA/ATAPI/MFM/RLL support
#
# CONFIG_IDE is not set
@@ -220,7 +323,14 @@ CONFIG_IOSCHED_NOOP=y
#
# SCSI device support
#
+# CONFIG_RAID_ATTRS is not set
# CONFIG_SCSI is not set
+# CONFIG_SCSI_NETLINK is not set
+
+#
+# Serial ATA (prod) and Parallel ATA (experimental) drivers
+#
+# CONFIG_ATA is not set
#
# Multi-device support (RAID and LVM)
@@ -230,6 +340,7 @@ CONFIG_IOSCHED_NOOP=y
#
# Fusion MPT device support
#
+# CONFIG_FUSION is not set
#
# IEEE 1394 (FireWire) support
@@ -240,13 +351,6 @@ CONFIG_IOSCHED_NOOP=y
#
#
-# Networking support
-#
-# CONFIG_NET is not set
-# CONFIG_NETPOLL is not set
-# CONFIG_NET_POLL_CONTROLLER is not set
-
-#
# ISDN subsystem
#
@@ -261,20 +365,10 @@ CONFIG_IOSCHED_NOOP=y
# CONFIG_INPUT is not set
#
-# Userland interfaces
-#
-
+# Hardware I/O ports
#
-# Input I/O drivers
-#
-# CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
# CONFIG_SERIO is not set
-# CONFIG_SERIO_I8042 is not set
-
-#
-# Input Device Drivers
-#
+# CONFIG_GAMEPORT is not set
#
# Character devices
@@ -291,6 +385,7 @@ CONFIG_SOUND_GAMEPORT=y
# Non-8250 serial port support
#
CONFIG_SERIAL_SH_SCI=y
+CONFIG_SERIAL_SH_SCI_NR_UARTS=2
CONFIG_SERIAL_SH_SCI_CONSOLE=y
CONFIG_SERIAL_CORE=y
CONFIG_SERIAL_CORE_CONSOLE=y
@@ -313,7 +408,7 @@ CONFIG_WATCHDOG=y
#
# CONFIG_SOFT_WATCHDOG is not set
# CONFIG_SH_WDT is not set
-# CONFIG_RTC is not set
+CONFIG_HW_RANDOM=y
# CONFIG_GEN_RTC is not set
# CONFIG_DTLK is not set
# CONFIG_R3964 is not set
@@ -321,18 +416,38 @@ CONFIG_WATCHDOG=y
#
# Ftape, the floppy tape device driver
#
-# CONFIG_DRM is not set
# CONFIG_RAW_DRIVER is not set
#
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
+# CONFIG_TELCLOCK is not set
+
+#
# I2C support
#
# CONFIG_I2C is not set
#
+# SPI support
+#
+# CONFIG_SPI is not set
+# CONFIG_SPI_MASTER is not set
+
+#
# Dallas's 1-wire bus
#
-# CONFIG_W1 is not set
+
+#
+# Hardware Monitoring support
+#
+CONFIG_HWMON=y
+# CONFIG_HWMON_VID is not set
+# CONFIG_SENSORS_ABITUGURU is not set
+# CONFIG_SENSORS_F71805F is not set
+# CONFIG_SENSORS_VT1211 is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
#
# Misc devices
@@ -342,6 +457,7 @@ CONFIG_WATCHDOG=y
# Multimedia devices
#
# CONFIG_VIDEO_DEV is not set
+CONFIG_VIDEO_V4L2=y
#
# Digital Video Broadcasting Devices
@@ -350,6 +466,7 @@ CONFIG_WATCHDOG=y
#
# Graphics support
#
+CONFIG_FIRMWARE_EDID=y
# CONFIG_FB is not set
#
@@ -362,9 +479,10 @@ CONFIG_WATCHDOG=y
#
# CONFIG_USB_ARCH_HAS_HCD is not set
# CONFIG_USB_ARCH_HAS_OHCI is not set
+# CONFIG_USB_ARCH_HAS_EHCI is not set
#
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
#
#
@@ -378,30 +496,64 @@ CONFIG_WATCHDOG=y
# CONFIG_MMC is not set
#
+# LED devices
+#
+# CONFIG_NEW_LEDS is not set
+
+#
+# LED drivers
+#
+
+#
+# LED Triggers
+#
+
+#
# InfiniBand support
#
-# CONFIG_INFINIBAND is not set
+
+#
+# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
+#
+
+#
+# Real Time Clock
+#
+# CONFIG_RTC_CLASS is not set
+
+#
+# DMA Engine support
+#
+# CONFIG_DMA_ENGINE is not set
+
+#
+# DMA Clients
+#
+
+#
+# DMA Devices
+#
#
# File systems
#
CONFIG_EXT2_FS=y
# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
# CONFIG_EXT3_FS is not set
-# CONFIG_JBD is not set
# CONFIG_REISERFS_FS is not set
# CONFIG_JFS_FS is not set
-
-#
-# XFS support
-#
+# CONFIG_FS_POSIX_ACL is not set
# CONFIG_XFS_FS is not set
# CONFIG_MINIX_FS is not set
# CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
# CONFIG_QUOTA is not set
CONFIG_DNOTIFY=y
# CONFIG_AUTOFS_FS is not set
# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
#
# CD-ROM/DVD Filesystems
@@ -421,12 +573,10 @@ CONFIG_DNOTIFY=y
#
CONFIG_PROC_FS=y
CONFIG_PROC_KCORE=y
+CONFIG_PROC_SYSCTL=y
# CONFIG_SYSFS is not set
-CONFIG_DEVFS_FS=y
-CONFIG_DEVFS_MOUNT=y
-# CONFIG_DEVFS_DEBUG is not set
CONFIG_TMPFS=y
-# CONFIG_TMPFS_XATTR is not set
+# CONFIG_TMPFS_POSIX_ACL is not set
# CONFIG_HUGETLBFS is not set
# CONFIG_HUGETLB_PAGE is not set
CONFIG_RAMFS=y
@@ -467,8 +617,13 @@ CONFIG_MSDOS_PARTITION=y
#
# Kernel hacking
#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_MUST_CHECK=y
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_UNUSED_SYMBOLS is not set
# CONFIG_DEBUG_KERNEL is not set
-# CONFIG_FRAME_POINTER is not set
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_DEBUG_BUGVERBOSE is not set
CONFIG_SH_STANDARD_BIOS=y
# CONFIG_EARLY_SCIF_CONSOLE is not set
# CONFIG_EARLY_PRINTK is not set
@@ -478,7 +633,6 @@ CONFIG_SH_STANDARD_BIOS=y
# Security options
#
# CONFIG_KEYS is not set
-# CONFIG_SECURITY is not set
#
# Cryptographic options
@@ -486,12 +640,9 @@ CONFIG_SH_STANDARD_BIOS=y
# CONFIG_CRYPTO is not set
#
-# Hardware crypto devices
-#
-
-#
# Library routines
#
# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
CONFIG_CRC32=y
# CONFIG_LIBCRC32C is not set
diff --git a/arch/sh/configs/se7343_defconfig b/arch/sh/configs/se7343_defconfig
index 948e507b52be..84c0075e2ad4 100644
--- a/arch/sh/configs/se7343_defconfig
+++ b/arch/sh/configs/se7343_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.17
-# Mon Aug 7 20:14:44 2006
+# Linux kernel version: 2.6.18
+# Tue Oct 3 11:46:17 2006
#
CONFIG_SUPERH=y
CONFIG_RWSEM_GENERIC_SPINLOCK=y
@@ -10,6 +10,7 @@ CONFIG_GENERIC_HWEIGHT=y
CONFIG_GENERIC_HARDIRQS=y
CONFIG_GENERIC_IRQ_PROBE=y
CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
#
# Code maturity level options
@@ -25,16 +26,20 @@ CONFIG_LOCALVERSION=""
CONFIG_LOCALVERSION_AUTO=y
# CONFIG_SWAP is not set
CONFIG_SYSVIPC=y
+# CONFIG_IPC_NS is not set
CONFIG_POSIX_MQUEUE=y
# CONFIG_BSD_PROCESS_ACCT is not set
-CONFIG_SYSCTL=y
+# CONFIG_TASKSTATS is not set
+# CONFIG_UTS_NS is not set
# CONFIG_AUDIT is not set
# CONFIG_IKCONFIG is not set
# CONFIG_RELAY is not set
CONFIG_INITRAMFS_SOURCE=""
-CONFIG_UID16=y
CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
CONFIG_EMBEDDED=y
+CONFIG_UID16=y
+# CONFIG_SYSCTL_SYSCALL is not set
CONFIG_KALLSYMS=y
# CONFIG_KALLSYMS_EXTRA_PASS is not set
CONFIG_HOTPLUG=y
@@ -46,10 +51,10 @@ CONFIG_BASE_FULL=y
# CONFIG_EPOLL is not set
# CONFIG_SHMEM is not set
CONFIG_SLAB=y
+CONFIG_VM_EVENT_COUNTERS=y
CONFIG_TINY_SHMEM=y
CONFIG_BASE_SMALL=0
# CONFIG_SLOB is not set
-CONFIG_OBSOLETE_INTERMODULE=y
#
# Loadable module support
@@ -64,6 +69,7 @@ CONFIG_MODULE_FORCE_UNLOAD=y
#
# Block layer
#
+CONFIG_BLOCK=y
# CONFIG_LBD is not set
# CONFIG_BLK_DEV_IO_TRACE is not set
# CONFIG_LSF is not set
@@ -115,6 +121,7 @@ CONFIG_SH_7343_SOLUTION_ENGINE=y
#
CONFIG_CPU_SH4=y
CONFIG_CPU_SH4A=y
+CONFIG_CPU_SH4AL_DSP=y
#
# SH-2 Processor Support
@@ -153,12 +160,16 @@ CONFIG_CPU_SH4A=y
#
# SH-4A Processor Support
#
-# CONFIG_CPU_SUBTYPE_SH73180 is not set
-CONFIG_CPU_SUBTYPE_SH7343=y
# CONFIG_CPU_SUBTYPE_SH7770 is not set
# CONFIG_CPU_SUBTYPE_SH7780 is not set
#
+# SH4AL-DSP Processor Support
+#
+# CONFIG_CPU_SUBTYPE_SH73180 is not set
+CONFIG_CPU_SUBTYPE_SH7343=y
+
+#
# Memory management options
#
CONFIG_MMU=y
@@ -166,6 +177,7 @@ CONFIG_PAGE_OFFSET=0x80000000
CONFIG_MEMORY_START=0x0c000000
CONFIG_MEMORY_SIZE=0x01000000
CONFIG_32BIT=y
+CONFIG_VSYSCALL=y
CONFIG_SELECT_MEMORY_MODEL=y
CONFIG_FLATMEM_MANUAL=y
# CONFIG_DISCONTIGMEM_MANUAL is not set
@@ -174,6 +186,7 @@ CONFIG_FLATMEM=y
CONFIG_FLAT_NODE_MEM_MAP=y
# CONFIG_SPARSEMEM_STATIC is not set
CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_RESOURCES_64BIT is not set
#
# Cache configuration
@@ -274,6 +287,9 @@ CONFIG_NET=y
CONFIG_PACKET=y
CONFIG_PACKET_MMAP=y
CONFIG_UNIX=y
+CONFIG_XFRM=y
+# CONFIG_XFRM_USER is not set
+# CONFIG_XFRM_SUB_POLICY is not set
# CONFIG_NET_KEY is not set
CONFIG_INET=y
# CONFIG_IP_MULTICAST is not set
@@ -292,12 +308,16 @@ CONFIG_SYN_COOKIES=y
# CONFIG_INET_IPCOMP is not set
# CONFIG_INET_XFRM_TUNNEL is not set
# CONFIG_INET_TUNNEL is not set
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
# CONFIG_INET_DIAG is not set
# CONFIG_TCP_CONG_ADVANCED is not set
-CONFIG_TCP_CONG_BIC=y
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_IPV6 is not set
# CONFIG_INET6_XFRM_TUNNEL is not set
# CONFIG_INET6_TUNNEL is not set
+# CONFIG_NETWORK_SECMARK is not set
# CONFIG_NETFILTER is not set
#
@@ -323,7 +343,6 @@ CONFIG_TCP_CONG_BIC=y
# CONFIG_ATALK is not set
# CONFIG_X25 is not set
# CONFIG_LAPB is not set
-# CONFIG_NET_DIVERT is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
@@ -351,6 +370,7 @@ CONFIG_TCP_CONG_BIC=y
CONFIG_STANDALONE=y
CONFIG_PREVENT_FIRMWARE_BUILD=y
CONFIG_FW_LOADER=y
+# CONFIG_SYS_HYPERVISOR is not set
#
# Connector - unified userspace <-> kernelspace linker
@@ -376,6 +396,7 @@ CONFIG_MTD_BLOCK=y
# CONFIG_NFTL is not set
# CONFIG_INFTL is not set
# CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
#
# RAM/ROM/Flash chip drivers
@@ -408,7 +429,6 @@ CONFIG_MTD_RAM=y
#
# CONFIG_MTD_COMPLEX_MAPPINGS is not set
# CONFIG_MTD_PHYSMAP is not set
-# CONFIG_MTD_SOLUTIONENGINE is not set
# CONFIG_MTD_PLATRAM is not set
#
@@ -466,6 +486,12 @@ CONFIG_MTD_RAM=y
#
# CONFIG_RAID_ATTRS is not set
# CONFIG_SCSI is not set
+# CONFIG_SCSI_NETLINK is not set
+
+#
+# Serial ATA (prod) and Parallel ATA (experimental) drivers
+#
+# CONFIG_ATA is not set
#
# Multi-device support (RAID and LVM)
@@ -506,7 +532,6 @@ CONFIG_NET_ETHERNET=y
CONFIG_MII=y
# CONFIG_STNIC is not set
CONFIG_SMC91X=y
-# CONFIG_NE2000 is not set
#
# Ethernet (1000 Mbit)
@@ -550,6 +575,7 @@ CONFIG_SMC91X=y
# Input device support
#
CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
#
# Userland interfaces
@@ -581,6 +607,7 @@ CONFIG_INPUT=y
CONFIG_VT=y
CONFIG_VT_CONSOLE=y
CONFIG_HW_CONSOLE=y
+# CONFIG_VT_HW_CONSOLE_BINDING is not set
# CONFIG_SERIAL_NONSTANDARD is not set
#
@@ -609,7 +636,7 @@ CONFIG_LEGACY_PTY_COUNT=256
# Watchdog Cards
#
# CONFIG_WATCHDOG is not set
-# CONFIG_RTC is not set
+CONFIG_HW_RANDOM=y
# CONFIG_GEN_RTC is not set
# CONFIG_DTLK is not set
# CONFIG_R3964 is not set
@@ -641,10 +668,10 @@ CONFIG_I2C_CHARDEV=y
#
# I2C Hardware Bus support
#
+# CONFIG_I2C_OCORES is not set
# CONFIG_I2C_PARPORT_LIGHT is not set
# CONFIG_I2C_STUB is not set
# CONFIG_I2C_PCA_ISA is not set
-CONFIG_I2C_SH7343=y
#
# Miscellaneous I2C Chip support
@@ -670,7 +697,6 @@ CONFIG_I2C_SH7343=y
#
# Dallas's 1-wire bus
#
-# CONFIG_W1 is not set
#
# Hardware Monitoring support
@@ -698,30 +724,16 @@ CONFIG_VIDEO_V4L2=y
# Video Capture Adapters
#
# CONFIG_VIDEO_ADV_DEBUG is not set
+CONFIG_VIDEO_HELPER_CHIPS_AUTO=y
# CONFIG_VIDEO_VIVI is not set
# CONFIG_VIDEO_CPIA is not set
# CONFIG_VIDEO_SAA5246A is not set
# CONFIG_VIDEO_SAA5249 is not set
# CONFIG_TUNER_3036 is not set
-# CONFIG_VIDEO_OVCAMCHIP is not set
-
-#
-# Encoders and Decoders
-#
-# CONFIG_VIDEO_MSP3400 is not set
-# CONFIG_VIDEO_CS53L32A is not set
-# CONFIG_VIDEO_WM8775 is not set
-# CONFIG_VIDEO_WM8739 is not set
-# CONFIG_VIDEO_CX25840 is not set
-# CONFIG_VIDEO_SAA711X is not set
-# CONFIG_VIDEO_SAA7127 is not set
-# CONFIG_VIDEO_UPD64031A is not set
-# CONFIG_VIDEO_UPD64083 is not set
#
# Radio Adapters
#
-# CONFIG_RADIO_MAESTRO is not set
#
# Digital Video Broadcasting Devices
@@ -731,12 +743,13 @@ CONFIG_VIDEO_V4L2=y
#
# Graphics support
#
+CONFIG_FIRMWARE_EDID=y
CONFIG_FB=y
# CONFIG_FB_CFB_FILLRECT is not set
# CONFIG_FB_CFB_COPYAREA is not set
# CONFIG_FB_CFB_IMAGEBLIT is not set
# CONFIG_FB_MACMODES is not set
-CONFIG_FB_FIRMWARE_EDID=y
+# CONFIG_FB_BACKLIGHT is not set
# CONFIG_FB_MODE_HELPERS is not set
# CONFIG_FB_TILEBLITTING is not set
# CONFIG_FB_EPSON1355 is not set
@@ -789,12 +802,6 @@ CONFIG_SND_VERBOSE_PROCFS=y
# CONFIG_SND_MPU401 is not set
#
-# SuperH devices
-#
-CONFIG_SH7343_SIU=m
-CONFIG_AK4537_CODEC=y
-
-#
# Open Sound System
#
# CONFIG_SOUND_PRIME is not set
@@ -847,6 +854,19 @@ CONFIG_AK4537_CODEC=y
# CONFIG_RTC_CLASS is not set
#
+# DMA Engine support
+#
+# CONFIG_DMA_ENGINE is not set
+
+#
+# DMA Clients
+#
+
+#
+# DMA Devices
+#
+
+#
# File systems
#
# CONFIG_EXT2_FS is not set
@@ -883,8 +903,10 @@ CONFIG_AK4537_CODEC=y
#
CONFIG_PROC_FS=y
# CONFIG_PROC_KCORE is not set
+CONFIG_PROC_SYSCTL=y
CONFIG_SYSFS=y
CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
# CONFIG_HUGETLBFS is not set
# CONFIG_HUGETLB_PAGE is not set
CONFIG_RAMFS=y
@@ -905,6 +927,7 @@ CONFIG_JFFS2_FS=y
CONFIG_JFFS2_FS_DEBUG=0
CONFIG_JFFS2_FS_WRITEBUFFER=y
# CONFIG_JFFS2_SUMMARY is not set
+# CONFIG_JFFS2_FS_XATTR is not set
# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
CONFIG_JFFS2_ZLIB=y
CONFIG_JFFS2_RTIME=y
@@ -962,7 +985,9 @@ CONFIG_MSDOS_PARTITION=y
# Kernel hacking
#
# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_MUST_CHECK=y
# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_UNUSED_SYMBOLS is not set
# CONFIG_DEBUG_KERNEL is not set
CONFIG_LOG_BUF_SHIFT=14
# CONFIG_DEBUG_BUGVERBOSE is not set
@@ -983,10 +1008,6 @@ CONFIG_LOG_BUF_SHIFT=14
# CONFIG_CRYPTO is not set
#
-# Hardware crypto devices
-#
-
-#
# Library routines
#
# CONFIG_CRC_CCITT is not set
diff --git a/arch/sh/configs/se7705_defconfig b/arch/sh/configs/se7705_defconfig
index e4a14602b169..06ebd6ec0cdb 100644
--- a/arch/sh/configs/se7705_defconfig
+++ b/arch/sh/configs/se7705_defconfig
@@ -1,125 +1,212 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.11-sh
-# Wed Mar 2 15:09:45 2005
+# Linux kernel version: 2.6.18
+# Tue Oct 3 12:03:04 2006
#
CONFIG_SUPERH=y
-CONFIG_UID16=y
CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+CONFIG_GENERIC_HWEIGHT=y
CONFIG_GENERIC_HARDIRQS=y
CONFIG_GENERIC_IRQ_PROBE=y
CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
#
# Code maturity level options
#
CONFIG_EXPERIMENTAL=y
-CONFIG_CLEAN_COMPILE=y
CONFIG_BROKEN_ON_SMP=y
CONFIG_LOCK_KERNEL=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
#
# General setup
#
CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
# CONFIG_SWAP is not set
# CONFIG_SYSVIPC is not set
# CONFIG_POSIX_MQUEUE is not set
# CONFIG_BSD_PROCESS_ACCT is not set
-# CONFIG_SYSCTL is not set
+# CONFIG_TASKSTATS is not set
+# CONFIG_UTS_NS is not set
# CONFIG_AUDIT is not set
-CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_HOTPLUG is not set
-CONFIG_KOBJECT_UEVENT=y
# CONFIG_IKCONFIG is not set
+# CONFIG_RELAY is not set
+CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SYSCTL=y
CONFIG_EMBEDDED=y
+CONFIG_UID16=y
+# CONFIG_SYSCTL_SYSCALL is not set
# CONFIG_KALLSYMS is not set
+# CONFIG_HOTPLUG is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
CONFIG_EPOLL=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
CONFIG_SHMEM=y
-CONFIG_CC_ALIGN_FUNCTIONS=0
-CONFIG_CC_ALIGN_LABELS=0
-CONFIG_CC_ALIGN_LOOPS=0
-CONFIG_CC_ALIGN_JUMPS=0
+CONFIG_SLAB=y
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_RT_MUTEXES=y
# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+# CONFIG_SLOB is not set
#
# Loadable module support
#
CONFIG_MODULES=y
# CONFIG_MODULE_UNLOAD is not set
-CONFIG_OBSOLETE_MODPARM=y
# CONFIG_MODVERSIONS is not set
# CONFIG_MODULE_SRCVERSION_ALL is not set
CONFIG_KMOD=y
#
+# Block layer
+#
+CONFIG_BLOCK=y
+# CONFIG_LBD is not set
+# CONFIG_LSF is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+# CONFIG_IOSCHED_DEADLINE is not set
+# CONFIG_IOSCHED_CFQ is not set
+CONFIG_DEFAULT_AS=y
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="anticipatory"
+
+#
# System type
#
+CONFIG_SOLUTION_ENGINE=y
CONFIG_SH_SOLUTION_ENGINE=y
# CONFIG_SH_7751_SOLUTION_ENGINE is not set
# CONFIG_SH_7300_SOLUTION_ENGINE is not set
+# CONFIG_SH_7343_SOLUTION_ENGINE is not set
# CONFIG_SH_73180_SOLUTION_ENGINE is not set
# CONFIG_SH_7751_SYSTEMH is not set
-# CONFIG_SH_STB1_HARP is not set
-# CONFIG_SH_STB1_OVERDRIVE is not set
-# CONFIG_SH_HP620 is not set
-# CONFIG_SH_HP680 is not set
-# CONFIG_SH_HP690 is not set
-# CONFIG_SH_CQREEK is not set
-# CONFIG_SH_DMIDA is not set
+# CONFIG_SH_HP6XX is not set
# CONFIG_SH_EC3104 is not set
# CONFIG_SH_SATURN is not set
# CONFIG_SH_DREAMCAST is not set
-# CONFIG_SH_CAT68701 is not set
# CONFIG_SH_BIGSUR is not set
-# CONFIG_SH_SH2000 is not set
-# CONFIG_SH_ADX is not set
# CONFIG_SH_MPC1211 is not set
# CONFIG_SH_SH03 is not set
# CONFIG_SH_SECUREEDGE5410 is not set
# CONFIG_SH_HS7751RVOIP is not set
+# CONFIG_SH_7710VOIPGW is not set
# CONFIG_SH_RTS7751R2D is not set
+# CONFIG_SH_R7780RP is not set
# CONFIG_SH_EDOSK7705 is not set
# CONFIG_SH_SH4202_MICRODEV is not set
+# CONFIG_SH_LANDISK is not set
+# CONFIG_SH_TITAN is not set
+# CONFIG_SH_SHMIN is not set
# CONFIG_SH_UNKNOWN is not set
-# CONFIG_CPU_SH2 is not set
+
+#
+# Processor selection
+#
CONFIG_CPU_SH3=y
-# CONFIG_CPU_SH4 is not set
+
+#
+# SH-2 Processor Support
+#
# CONFIG_CPU_SUBTYPE_SH7604 is not set
+
+#
+# SH-3 Processor Support
+#
# CONFIG_CPU_SUBTYPE_SH7300 is not set
CONFIG_CPU_SUBTYPE_SH7705=y
+# CONFIG_CPU_SUBTYPE_SH7706 is not set
# CONFIG_CPU_SUBTYPE_SH7707 is not set
# CONFIG_CPU_SUBTYPE_SH7708 is not set
# CONFIG_CPU_SUBTYPE_SH7709 is not set
+# CONFIG_CPU_SUBTYPE_SH7710 is not set
+
+#
+# SH-4 Processor Support
+#
# CONFIG_CPU_SUBTYPE_SH7750 is not set
+# CONFIG_CPU_SUBTYPE_SH7091 is not set
+# CONFIG_CPU_SUBTYPE_SH7750R is not set
+# CONFIG_CPU_SUBTYPE_SH7750S is not set
# CONFIG_CPU_SUBTYPE_SH7751 is not set
+# CONFIG_CPU_SUBTYPE_SH7751R is not set
# CONFIG_CPU_SUBTYPE_SH7760 is not set
-# CONFIG_CPU_SUBTYPE_SH73180 is not set
+# CONFIG_CPU_SUBTYPE_SH4_202 is not set
+
+#
+# ST40 Processor Support
+#
# CONFIG_CPU_SUBTYPE_ST40STB1 is not set
# CONFIG_CPU_SUBTYPE_ST40GX1 is not set
-# CONFIG_CPU_SUBTYPE_SH4_202 is not set
-CONFIG_SH7705_CACHE_32KB=y
+
+#
+# SH-4A Processor Support
+#
+# CONFIG_CPU_SUBTYPE_SH7770 is not set
+# CONFIG_CPU_SUBTYPE_SH7780 is not set
+
+#
+# SH4AL-DSP Processor Support
+#
+# CONFIG_CPU_SUBTYPE_SH73180 is not set
+# CONFIG_CPU_SUBTYPE_SH7343 is not set
+
+#
+# Memory management options
+#
CONFIG_MMU=y
-# CONFIG_CMDLINE_BOOL is not set
+CONFIG_PAGE_OFFSET=0x80000000
CONFIG_MEMORY_START=0x0c000000
CONFIG_MEMORY_SIZE=0x02000000
-CONFIG_MEMORY_SET=y
-# CONFIG_MEMORY_OVERRIDE is not set
+CONFIG_VSYSCALL=y
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+# CONFIG_SPARSEMEM_STATIC is not set
+CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_RESOURCES_64BIT is not set
+
+#
+# Cache configuration
+#
+CONFIG_SH7705_CACHE_32KB=y
+# CONFIG_SH_DIRECT_MAPPED is not set
+# CONFIG_SH_WRITETHROUGH is not set
+# CONFIG_SH_OCRAM is not set
# CONFIG_CF_ENABLER is not set
-CONFIG_SH_RTC=y
+
+#
+# Processor features
+#
+CONFIG_CPU_LITTLE_ENDIAN=y
+# CONFIG_SH_FPU_EMU is not set
# CONFIG_SH_DSP is not set
# CONFIG_SH_ADC is not set
-CONFIG_ZERO_PAGE_OFFSET=0x00001000
-CONFIG_BOOT_LINK_OFFSET=0x00800000
-CONFIG_CPU_LITTLE_ENDIAN=y
-CONFIG_PREEMPT=y
-# CONFIG_UBC_WAKEUP is not set
-# CONFIG_SH_WRITETHROUGH is not set
-# CONFIG_SH_OCRAM is not set
-# CONFIG_SMP is not set
-CONFIG_SH_PCLK_CALC=y
+CONFIG_CPU_HAS_INTEVT=y
+CONFIG_CPU_HAS_PINT_IRQ=y
+CONFIG_CPU_HAS_SR_RB=y
+
+#
+# Timer support
+#
+CONFIG_SH_TMU=y
CONFIG_SH_PCLK_FREQ=33333333
#
@@ -139,17 +226,34 @@ CONFIG_SH_PCLK_FREQ=33333333
CONFIG_HEARTBEAT=y
#
-# Bus options (PCI, PCMCIA, EISA, MCA, ISA)
+# Kernel features
#
-# CONFIG_PCI is not set
+# CONFIG_HZ_100 is not set
+CONFIG_HZ_250=y
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=250
+# CONFIG_KEXEC is not set
+# CONFIG_SMP is not set
+# CONFIG_PREEMPT_NONE is not set
+# CONFIG_PREEMPT_VOLUNTARY is not set
+CONFIG_PREEMPT=y
+CONFIG_PREEMPT_BKL=y
#
-# PCCARD (PCMCIA/CardBus) support
+# Boot options
+#
+CONFIG_ZERO_PAGE_OFFSET=0x00001000
+CONFIG_BOOT_LINK_OFFSET=0x00800000
+# CONFIG_UBC_WAKEUP is not set
+# CONFIG_CMDLINE_BOOL is not set
+
+#
+# Bus options
#
-# CONFIG_PCCARD is not set
+# CONFIG_PCI is not set
#
-# PC-card bridges
+# PCCARD (PCMCIA/CardBus) support
#
#
@@ -164,9 +268,95 @@ CONFIG_BINFMT_ELF=y
# CONFIG_BINFMT_MISC is not set
#
-# SH initrd options
+# Power management options (EXPERIMENTAL)
+#
+# CONFIG_PM is not set
+
+#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+# CONFIG_NETDEBUG is not set
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+# CONFIG_XFRM_USER is not set
+# CONFIG_XFRM_SUB_POLICY is not set
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+CONFIG_IP_PNP_RARP=y
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+# CONFIG_INET_TUNNEL is not set
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_IPV6 is not set
+# CONFIG_INET6_XFRM_TUNNEL is not set
+# CONFIG_INET6_TUNNEL is not set
+# CONFIG_NETWORK_SECMARK is not set
+# CONFIG_NETFILTER is not set
+
+#
+# DCCP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_DCCP is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP is not set
+
+#
+# TIPC Configuration (EXPERIMENTAL)
+#
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+
+#
+# QoS and/or fair queueing
#
-# CONFIG_EMBEDDED_RAMDISK is not set
+# CONFIG_NET_SCHED is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_IEEE80211 is not set
#
# Device Drivers
@@ -177,15 +367,20 @@ CONFIG_BINFMT_ELF=y
#
CONFIG_STANDALONE=y
CONFIG_PREVENT_FIRMWARE_BUILD=y
-# CONFIG_FW_LOADER is not set
+# CONFIG_SYS_HYPERVISOR is not set
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
+# CONFIG_CONNECTOR is not set
#
# Memory Technology Devices (MTD)
#
CONFIG_MTD=y
# CONFIG_MTD_DEBUG is not set
-CONFIG_MTD_PARTITIONS=y
# CONFIG_MTD_CONCAT is not set
+CONFIG_MTD_PARTITIONS=y
# CONFIG_MTD_REDBOOT_PARTS is not set
# CONFIG_MTD_CMDLINE_PARTS is not set
@@ -197,6 +392,8 @@ CONFIG_MTD_BLOCK=y
# CONFIG_FTL is not set
# CONFIG_NFTL is not set
# CONFIG_INFTL is not set
+# CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
#
# RAM/ROM/Flash chip drivers
@@ -217,22 +414,19 @@ CONFIG_MTD_CFI_I2=y
# CONFIG_MTD_CFI_I8 is not set
# CONFIG_MTD_CFI_INTELEXT is not set
CONFIG_MTD_CFI_AMDSTD=y
-CONFIG_MTD_CFI_AMDSTD_RETRY=0
# CONFIG_MTD_CFI_STAA is not set
CONFIG_MTD_CFI_UTIL=y
# CONFIG_MTD_RAM is not set
# CONFIG_MTD_ROM is not set
# CONFIG_MTD_ABSENT is not set
+# CONFIG_MTD_OBSOLETE_CHIPS is not set
#
# Mapping drivers for chip access
#
# CONFIG_MTD_COMPLEX_MAPPINGS is not set
# CONFIG_MTD_PHYSMAP is not set
-CONFIG_MTD_SOLUTIONENGINE=y
-CONFIG_MTD_SUPERH_RESERVE=0x300000
-# CONFIG_MTD_MPC1211 is not set
-# CONFIG_MTD_RTS7751R2D is not set
+# CONFIG_MTD_PLATRAM is not set
#
# Self-contained MTD device drivers
@@ -240,7 +434,6 @@ CONFIG_MTD_SUPERH_RESERVE=0x300000
# CONFIG_MTD_SLRAM is not set
# CONFIG_MTD_PHRAM is not set
# CONFIG_MTD_MTDRAM is not set
-# CONFIG_MTD_BLKMTD is not set
# CONFIG_MTD_BLOCK2MTD is not set
#
@@ -256,6 +449,11 @@ CONFIG_MTD_SUPERH_RESERVE=0x300000
# CONFIG_MTD_NAND is not set
#
+# OneNAND Flash Device Drivers
+#
+# CONFIG_MTD_ONENAND is not set
+
+#
# Parallel port support
#
# CONFIG_PARPORT is not set
@@ -267,25 +465,15 @@ CONFIG_MTD_SUPERH_RESERVE=0x300000
#
# Block devices
#
-# CONFIG_BLK_DEV_FD is not set
# CONFIG_BLK_DEV_COW_COMMON is not set
# CONFIG_BLK_DEV_LOOP is not set
# CONFIG_BLK_DEV_NBD is not set
CONFIG_BLK_DEV_RAM=y
CONFIG_BLK_DEV_RAM_COUNT=16
CONFIG_BLK_DEV_RAM_SIZE=8192
+CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
CONFIG_BLK_DEV_INITRD=y
-CONFIG_INITRAMFS_SOURCE=""
-# CONFIG_LBD is not set
# CONFIG_CDROM_PKTCDVD is not set
-
-#
-# IO Schedulers
-#
-CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
-# CONFIG_IOSCHED_DEADLINE is not set
-# CONFIG_IOSCHED_CFQ is not set
# CONFIG_ATA_OVER_ETH is not set
#
@@ -296,7 +484,14 @@ CONFIG_IOSCHED_AS=y
#
# SCSI device support
#
+# CONFIG_RAID_ATTRS is not set
# CONFIG_SCSI is not set
+# CONFIG_SCSI_NETLINK is not set
+
+#
+# Serial ATA (prod) and Parallel ATA (experimental) drivers
+#
+# CONFIG_ATA is not set
#
# Multi-device support (RAID and LVM)
@@ -306,6 +501,7 @@ CONFIG_IOSCHED_AS=y
#
# Fusion MPT device support
#
+# CONFIG_FUSION is not set
#
# IEEE 1394 (FireWire) support
@@ -316,70 +512,8 @@ CONFIG_IOSCHED_AS=y
#
#
-# Networking support
-#
-CONFIG_NET=y
-
-#
-# Networking options
-#
-CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
-# CONFIG_NETLINK_DEV is not set
-CONFIG_UNIX=y
-# CONFIG_NET_KEY is not set
-CONFIG_INET=y
-# CONFIG_IP_MULTICAST is not set
-# CONFIG_IP_ADVANCED_ROUTER is not set
-CONFIG_IP_PNP=y
-CONFIG_IP_PNP_DHCP=y
-CONFIG_IP_PNP_BOOTP=y
-CONFIG_IP_PNP_RARP=y
-# CONFIG_NET_IPIP is not set
-# CONFIG_NET_IPGRE is not set
-# CONFIG_ARPD is not set
-# CONFIG_SYN_COOKIES is not set
-# CONFIG_INET_AH is not set
-# CONFIG_INET_ESP is not set
-# CONFIG_INET_IPCOMP is not set
-# CONFIG_INET_TUNNEL is not set
-CONFIG_IP_TCPDIAG=y
-# CONFIG_IP_TCPDIAG_IPV6 is not set
-# CONFIG_IPV6 is not set
-# CONFIG_NETFILTER is not set
-
-#
-# SCTP Configuration (EXPERIMENTAL)
-#
-# CONFIG_IP_SCTP is not set
-# CONFIG_ATM is not set
-# CONFIG_BRIDGE is not set
-# CONFIG_VLAN_8021Q is not set
-# CONFIG_DECNET is not set
-# CONFIG_LLC2 is not set
-# CONFIG_IPX is not set
-# CONFIG_ATALK is not set
-# CONFIG_X25 is not set
-# CONFIG_LAPB is not set
-# CONFIG_NET_DIVERT is not set
-# CONFIG_ECONET is not set
-# CONFIG_WAN_ROUTER is not set
-
-#
-# QoS and/or fair queueing
-#
-# CONFIG_NET_SCHED is not set
-# CONFIG_NET_CLS_ROUTE is not set
-
-#
-# Network testing
+# Network device support
#
-# CONFIG_NET_PKTGEN is not set
-# CONFIG_NETPOLL is not set
-# CONFIG_NET_POLL_CONTROLLER is not set
-# CONFIG_HAMRADIO is not set
-# CONFIG_IRDA is not set
-# CONFIG_BT is not set
CONFIG_NETDEVICES=y
# CONFIG_DUMMY is not set
# CONFIG_BONDING is not set
@@ -387,6 +521,11 @@ CONFIG_NETDEVICES=y
# CONFIG_TUN is not set
#
+# PHY device support
+#
+# CONFIG_PHYLIB is not set
+
+#
# Ethernet (10 or 100Mbit)
#
CONFIG_NET_ETHERNET=y
@@ -422,10 +561,14 @@ CONFIG_PPP_ASYNC=y
# CONFIG_PPP_SYNC_TTY is not set
CONFIG_PPP_DEFLATE=y
# CONFIG_PPP_BSDCOMP is not set
+# CONFIG_PPP_MPPE is not set
# CONFIG_PPPOE is not set
# CONFIG_SLIP is not set
+CONFIG_SLHC=y
# CONFIG_SHAPER is not set
# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
#
# ISDN subsystem
@@ -441,6 +584,7 @@ CONFIG_PPP_DEFLATE=y
# Input device support
#
CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
#
# Userland interfaces
@@ -452,18 +596,6 @@ CONFIG_INPUT=y
# CONFIG_INPUT_EVBUG is not set
#
-# Input I/O drivers
-#
-# CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
-CONFIG_SERIO=y
-# CONFIG_SERIO_I8042 is not set
-# CONFIG_SERIO_SERPORT is not set
-# CONFIG_SERIO_CT82C710 is not set
-# CONFIG_SERIO_LIBPS2 is not set
-# CONFIG_SERIO_RAW is not set
-
-#
# Input Device Drivers
#
# CONFIG_INPUT_KEYBOARD is not set
@@ -473,6 +605,16 @@ CONFIG_SERIO=y
# CONFIG_INPUT_MISC is not set
#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+# CONFIG_SERIO_I8042 is not set
+# CONFIG_SERIO_SERPORT is not set
+# CONFIG_SERIO_LIBPS2 is not set
+# CONFIG_SERIO_RAW is not set
+# CONFIG_GAMEPORT is not set
+
+#
# Character devices
#
# CONFIG_VT is not set
@@ -487,6 +629,7 @@ CONFIG_SERIO=y
# Non-8250 serial port support
#
CONFIG_SERIAL_SH_SCI=y
+CONFIG_SERIAL_SH_SCI_NR_UARTS=2
CONFIG_SERIAL_SH_SCI_CONSOLE=y
CONFIG_SERIAL_CORE=y
CONFIG_SERIAL_CORE_CONSOLE=y
@@ -502,7 +645,7 @@ CONFIG_UNIX98_PTYS=y
# Watchdog Cards
#
# CONFIG_WATCHDOG is not set
-# CONFIG_RTC is not set
+CONFIG_HW_RANDOM=y
# CONFIG_GEN_RTC is not set
# CONFIG_DTLK is not set
# CONFIG_R3964 is not set
@@ -510,18 +653,38 @@ CONFIG_UNIX98_PTYS=y
#
# Ftape, the floppy tape device driver
#
-# CONFIG_DRM is not set
# CONFIG_RAW_DRIVER is not set
#
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
+# CONFIG_TELCLOCK is not set
+
+#
# I2C support
#
# CONFIG_I2C is not set
#
+# SPI support
+#
+# CONFIG_SPI is not set
+# CONFIG_SPI_MASTER is not set
+
+#
# Dallas's 1-wire bus
#
-# CONFIG_W1 is not set
+
+#
+# Hardware Monitoring support
+#
+CONFIG_HWMON=y
+# CONFIG_HWMON_VID is not set
+# CONFIG_SENSORS_ABITUGURU is not set
+# CONFIG_SENSORS_F71805F is not set
+# CONFIG_SENSORS_VT1211 is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
#
# Misc devices
@@ -531,6 +694,7 @@ CONFIG_UNIX98_PTYS=y
# Multimedia devices
#
# CONFIG_VIDEO_DEV is not set
+CONFIG_VIDEO_V4L2=y
#
# Digital Video Broadcasting Devices
@@ -540,6 +704,7 @@ CONFIG_UNIX98_PTYS=y
#
# Graphics support
#
+CONFIG_FIRMWARE_EDID=y
# CONFIG_FB is not set
#
@@ -552,9 +717,10 @@ CONFIG_UNIX98_PTYS=y
#
# CONFIG_USB_ARCH_HAS_HCD is not set
# CONFIG_USB_ARCH_HAS_OHCI is not set
+# CONFIG_USB_ARCH_HAS_EHCI is not set
#
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
#
#
@@ -568,30 +734,64 @@ CONFIG_UNIX98_PTYS=y
# CONFIG_MMC is not set
#
+# LED devices
+#
+# CONFIG_NEW_LEDS is not set
+
+#
+# LED drivers
+#
+
+#
+# LED Triggers
+#
+
+#
# InfiniBand support
#
-# CONFIG_INFINIBAND is not set
+
+#
+# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
+#
+
+#
+# Real Time Clock
+#
+# CONFIG_RTC_CLASS is not set
+
+#
+# DMA Engine support
+#
+# CONFIG_DMA_ENGINE is not set
+
+#
+# DMA Clients
+#
+
+#
+# DMA Devices
+#
#
# File systems
#
CONFIG_EXT2_FS=y
# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
# CONFIG_EXT3_FS is not set
-# CONFIG_JBD is not set
# CONFIG_REISERFS_FS is not set
# CONFIG_JFS_FS is not set
-
-#
-# XFS support
-#
+# CONFIG_FS_POSIX_ACL is not set
# CONFIG_XFS_FS is not set
# CONFIG_MINIX_FS is not set
# CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
# CONFIG_QUOTA is not set
CONFIG_DNOTIFY=y
# CONFIG_AUTOFS_FS is not set
# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
#
# CD-ROM/DVD Filesystems
@@ -611,9 +811,8 @@ CONFIG_DNOTIFY=y
#
CONFIG_PROC_FS=y
CONFIG_PROC_KCORE=y
+CONFIG_PROC_SYSCTL=y
# CONFIG_SYSFS is not set
-# CONFIG_DEVFS_FS is not set
-# CONFIG_DEVPTS_FS_XATTR is not set
# CONFIG_TMPFS is not set
# CONFIG_HUGETLBFS is not set
# CONFIG_HUGETLB_PAGE is not set
@@ -632,8 +831,9 @@ CONFIG_RAMFS=y
# CONFIG_JFFS_FS is not set
CONFIG_JFFS2_FS=y
CONFIG_JFFS2_FS_DEBUG=0
-# CONFIG_JFFS2_FS_NAND is not set
-# CONFIG_JFFS2_FS_NOR_ECC is not set
+CONFIG_JFFS2_FS_WRITEBUFFER=y
+# CONFIG_JFFS2_SUMMARY is not set
+# CONFIG_JFFS2_FS_XATTR is not set
# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
CONFIG_JFFS2_ZLIB=y
CONFIG_JFFS2_RTIME=y
@@ -655,6 +855,7 @@ CONFIG_NFS_FS=y
# CONFIG_NFSD is not set
CONFIG_ROOT_NFS=y
CONFIG_LOCKD=y
+CONFIG_NFS_COMMON=y
CONFIG_SUNRPC=y
# CONFIG_RPCSEC_GSS_KRB5 is not set
# CONFIG_RPCSEC_GSS_SPKM3 is not set
@@ -663,6 +864,7 @@ CONFIG_SUNRPC=y
# CONFIG_NCP_FS is not set
# CONFIG_CODA_FS is not set
# CONFIG_AFS_FS is not set
+# CONFIG_9P_FS is not set
#
# Partition Types
@@ -683,9 +885,13 @@ CONFIG_MSDOS_PARTITION=y
#
# Kernel hacking
#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_MUST_CHECK=y
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_UNUSED_SYMBOLS is not set
# CONFIG_DEBUG_KERNEL is not set
-CONFIG_DEBUG_PREEMPT=y
-# CONFIG_FRAME_POINTER is not set
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_DEBUG_BUGVERBOSE is not set
# CONFIG_SH_STANDARD_BIOS is not set
# CONFIG_KGDB is not set
@@ -693,7 +899,6 @@ CONFIG_DEBUG_PREEMPT=y
# Security options
#
# CONFIG_KEYS is not set
-# CONFIG_SECURITY is not set
#
# Cryptographic options
@@ -701,14 +906,12 @@ CONFIG_DEBUG_PREEMPT=y
# CONFIG_CRYPTO is not set
#
-# Hardware crypto devices
-#
-
-#
# Library routines
#
CONFIG_CRC_CCITT=y
+# CONFIG_CRC16 is not set
CONFIG_CRC32=y
# CONFIG_LIBCRC32C is not set
CONFIG_ZLIB_INFLATE=y
CONFIG_ZLIB_DEFLATE=y
+CONFIG_PLIST=y
diff --git a/arch/sh/configs/se7750_defconfig b/arch/sh/configs/se7750_defconfig
index 6dc31584752a..5d357d68b234 100644
--- a/arch/sh/configs/se7750_defconfig
+++ b/arch/sh/configs/se7750_defconfig
@@ -1,131 +1,218 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.11-sh
-# Wed Mar 2 15:09:46 2005
+# Linux kernel version: 2.6.18
+# Tue Oct 3 11:49:01 2006
#
CONFIG_SUPERH=y
-CONFIG_UID16=y
CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+CONFIG_GENERIC_HWEIGHT=y
CONFIG_GENERIC_HARDIRQS=y
CONFIG_GENERIC_IRQ_PROBE=y
CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
#
# Code maturity level options
#
CONFIG_EXPERIMENTAL=y
-CONFIG_CLEAN_COMPILE=y
CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
#
# General setup
#
CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
# CONFIG_SWAP is not set
CONFIG_SYSVIPC=y
+# CONFIG_IPC_NS is not set
# CONFIG_POSIX_MQUEUE is not set
CONFIG_BSD_PROCESS_ACCT=y
# CONFIG_BSD_PROCESS_ACCT_V3 is not set
-CONFIG_SYSCTL=y
+# CONFIG_TASKSTATS is not set
+# CONFIG_UTS_NS is not set
# CONFIG_AUDIT is not set
-CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_HOTPLUG is not set
-CONFIG_KOBJECT_UEVENT=y
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
+# CONFIG_RELAY is not set
+CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SYSCTL=y
CONFIG_EMBEDDED=y
+CONFIG_UID16=y
+# CONFIG_SYSCTL_SYSCALL is not set
CONFIG_KALLSYMS=y
# CONFIG_KALLSYMS_EXTRA_PASS is not set
+# CONFIG_HOTPLUG is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
CONFIG_EPOLL=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
CONFIG_SHMEM=y
-CONFIG_CC_ALIGN_FUNCTIONS=0
-CONFIG_CC_ALIGN_LABELS=0
-CONFIG_CC_ALIGN_LOOPS=0
-CONFIG_CC_ALIGN_JUMPS=0
+CONFIG_SLAB=y
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_RT_MUTEXES=y
# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+# CONFIG_SLOB is not set
#
# Loadable module support
#
CONFIG_MODULES=y
# CONFIG_MODULE_UNLOAD is not set
-CONFIG_OBSOLETE_MODPARM=y
# CONFIG_MODVERSIONS is not set
# CONFIG_MODULE_SRCVERSION_ALL is not set
CONFIG_KMOD=y
#
+# Block layer
+#
+CONFIG_BLOCK=y
+# CONFIG_LBD is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_LSF is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+CONFIG_DEFAULT_AS=y
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="anticipatory"
+
+#
# System type
#
+CONFIG_SOLUTION_ENGINE=y
CONFIG_SH_SOLUTION_ENGINE=y
# CONFIG_SH_7751_SOLUTION_ENGINE is not set
# CONFIG_SH_7300_SOLUTION_ENGINE is not set
+# CONFIG_SH_7343_SOLUTION_ENGINE is not set
# CONFIG_SH_73180_SOLUTION_ENGINE is not set
# CONFIG_SH_7751_SYSTEMH is not set
-# CONFIG_SH_STB1_HARP is not set
-# CONFIG_SH_STB1_OVERDRIVE is not set
-# CONFIG_SH_HP620 is not set
-# CONFIG_SH_HP680 is not set
-# CONFIG_SH_HP690 is not set
-# CONFIG_SH_CQREEK is not set
-# CONFIG_SH_DMIDA is not set
+# CONFIG_SH_HP6XX is not set
# CONFIG_SH_EC3104 is not set
# CONFIG_SH_SATURN is not set
# CONFIG_SH_DREAMCAST is not set
-# CONFIG_SH_CAT68701 is not set
# CONFIG_SH_BIGSUR is not set
-# CONFIG_SH_SH2000 is not set
-# CONFIG_SH_ADX is not set
# CONFIG_SH_MPC1211 is not set
# CONFIG_SH_SH03 is not set
# CONFIG_SH_SECUREEDGE5410 is not set
# CONFIG_SH_HS7751RVOIP is not set
+# CONFIG_SH_7710VOIPGW is not set
# CONFIG_SH_RTS7751R2D is not set
+# CONFIG_SH_R7780RP is not set
# CONFIG_SH_EDOSK7705 is not set
# CONFIG_SH_SH4202_MICRODEV is not set
+# CONFIG_SH_LANDISK is not set
+# CONFIG_SH_TITAN is not set
+# CONFIG_SH_SHMIN is not set
# CONFIG_SH_UNKNOWN is not set
-# CONFIG_CPU_SH2 is not set
-# CONFIG_CPU_SH3 is not set
+
+#
+# Processor selection
+#
CONFIG_CPU_SH4=y
+
+#
+# SH-2 Processor Support
+#
# CONFIG_CPU_SUBTYPE_SH7604 is not set
+
+#
+# SH-3 Processor Support
+#
# CONFIG_CPU_SUBTYPE_SH7300 is not set
# CONFIG_CPU_SUBTYPE_SH7705 is not set
+# CONFIG_CPU_SUBTYPE_SH7706 is not set
# CONFIG_CPU_SUBTYPE_SH7707 is not set
# CONFIG_CPU_SUBTYPE_SH7708 is not set
# CONFIG_CPU_SUBTYPE_SH7709 is not set
+# CONFIG_CPU_SUBTYPE_SH7710 is not set
+
+#
+# SH-4 Processor Support
+#
CONFIG_CPU_SUBTYPE_SH7750=y
+# CONFIG_CPU_SUBTYPE_SH7091 is not set
+# CONFIG_CPU_SUBTYPE_SH7750R is not set
+# CONFIG_CPU_SUBTYPE_SH7750S is not set
# CONFIG_CPU_SUBTYPE_SH7751 is not set
+# CONFIG_CPU_SUBTYPE_SH7751R is not set
# CONFIG_CPU_SUBTYPE_SH7760 is not set
-# CONFIG_CPU_SUBTYPE_SH73180 is not set
+# CONFIG_CPU_SUBTYPE_SH4_202 is not set
+
+#
+# ST40 Processor Support
+#
# CONFIG_CPU_SUBTYPE_ST40STB1 is not set
# CONFIG_CPU_SUBTYPE_ST40GX1 is not set
-# CONFIG_CPU_SUBTYPE_SH4_202 is not set
+
+#
+# SH-4A Processor Support
+#
+# CONFIG_CPU_SUBTYPE_SH7770 is not set
+# CONFIG_CPU_SUBTYPE_SH7780 is not set
+
+#
+# SH4AL-DSP Processor Support
+#
+# CONFIG_CPU_SUBTYPE_SH73180 is not set
+# CONFIG_CPU_SUBTYPE_SH7343 is not set
+
+#
+# Memory management options
+#
CONFIG_MMU=y
-CONFIG_CMDLINE_BOOL=y
-CONFIG_CMDLINE="console=ttySC1,38400 root=/dev/nfs ip=bootp"
+CONFIG_PAGE_OFFSET=0x80000000
CONFIG_MEMORY_START=0x0c000000
CONFIG_MEMORY_SIZE=0x02000000
-CONFIG_MEMORY_SET=y
-# CONFIG_MEMORY_OVERRIDE is not set
+CONFIG_VSYSCALL=y
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+# CONFIG_SPARSEMEM_STATIC is not set
+CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_RESOURCES_64BIT is not set
+
+#
+# Cache configuration
+#
+# CONFIG_SH_DIRECT_MAPPED is not set
+# CONFIG_SH_WRITETHROUGH is not set
+# CONFIG_SH_OCRAM is not set
CONFIG_CF_ENABLER=y
# CONFIG_CF_AREA5 is not set
CONFIG_CF_AREA6=y
CONFIG_CF_BASE_ADDR=0xb8000000
-CONFIG_SH_RTC=y
-CONFIG_SH_FPU=y
-CONFIG_ZERO_PAGE_OFFSET=0x00001000
-CONFIG_BOOT_LINK_OFFSET=0x00800000
+
+#
+# Processor features
+#
CONFIG_CPU_LITTLE_ENDIAN=y
-# CONFIG_PREEMPT is not set
-# CONFIG_UBC_WAKEUP is not set
-# CONFIG_SH_WRITETHROUGH is not set
-# CONFIG_SH_OCRAM is not set
+CONFIG_SH_FPU=y
+# CONFIG_SH_DSP is not set
# CONFIG_SH_STORE_QUEUES is not set
-# CONFIG_SMP is not set
-CONFIG_SH_PCLK_CALC=y
-CONFIG_SH_PCLK_FREQ=49876504
+CONFIG_CPU_HAS_INTEVT=y
+CONFIG_CPU_HAS_SR_RB=y
+
+#
+# Timer support
+#
+CONFIG_SH_TMU=y
+CONFIG_SH_PCLK_FREQ=50000000
#
# CPU Frequency scaling
@@ -144,17 +231,34 @@ CONFIG_SH_PCLK_FREQ=49876504
CONFIG_HEARTBEAT=y
#
-# Bus options (PCI, PCMCIA, EISA, MCA, ISA)
+# Kernel features
#
-# CONFIG_PCI is not set
+# CONFIG_HZ_100 is not set
+CONFIG_HZ_250=y
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=250
+# CONFIG_KEXEC is not set
+# CONFIG_SMP is not set
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
+# CONFIG_PREEMPT is not set
#
-# PCCARD (PCMCIA/CardBus) support
+# Boot options
+#
+CONFIG_ZERO_PAGE_OFFSET=0x00001000
+CONFIG_BOOT_LINK_OFFSET=0x00800000
+# CONFIG_UBC_WAKEUP is not set
+CONFIG_CMDLINE_BOOL=y
+CONFIG_CMDLINE="console=ttySC1,38400 root=/dev/nfs ip=bootp"
+
+#
+# Bus options
#
-# CONFIG_PCCARD is not set
+# CONFIG_PCI is not set
#
-# PC-card bridges
+# PCCARD (PCMCIA/CardBus) support
#
#
@@ -169,6 +273,98 @@ CONFIG_BINFMT_ELF=y
# CONFIG_BINFMT_MISC is not set
#
+# Power management options (EXPERIMENTAL)
+#
+# CONFIG_PM is not set
+
+#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+# CONFIG_NETDEBUG is not set
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+# CONFIG_XFRM_USER is not set
+# CONFIG_XFRM_SUB_POLICY is not set
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+# CONFIG_IP_PNP_DHCP is not set
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_IP_MROUTE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+# CONFIG_INET_TUNNEL is not set
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_IPV6 is not set
+# CONFIG_INET6_XFRM_TUNNEL is not set
+# CONFIG_INET6_TUNNEL is not set
+# CONFIG_NETWORK_SECMARK is not set
+# CONFIG_NETFILTER is not set
+
+#
+# DCCP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_DCCP is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP is not set
+
+#
+# TIPC Configuration (EXPERIMENTAL)
+#
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_IEEE80211 is not set
+
+#
# Device Drivers
#
@@ -177,15 +373,20 @@ CONFIG_BINFMT_ELF=y
#
CONFIG_STANDALONE=y
CONFIG_PREVENT_FIRMWARE_BUILD=y
-# CONFIG_FW_LOADER is not set
+# CONFIG_SYS_HYPERVISOR is not set
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
+# CONFIG_CONNECTOR is not set
#
# Memory Technology Devices (MTD)
#
CONFIG_MTD=y
# CONFIG_MTD_DEBUG is not set
-CONFIG_MTD_PARTITIONS=y
# CONFIG_MTD_CONCAT is not set
+CONFIG_MTD_PARTITIONS=y
# CONFIG_MTD_REDBOOT_PARTS is not set
# CONFIG_MTD_CMDLINE_PARTS is not set
@@ -197,6 +398,8 @@ CONFIG_MTD_BLOCK=y
# CONFIG_FTL is not set
# CONFIG_NFTL is not set
# CONFIG_INFTL is not set
+# CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
#
# RAM/ROM/Flash chip drivers
@@ -217,22 +420,19 @@ CONFIG_MTD_CFI_I2=y
# CONFIG_MTD_CFI_I8 is not set
# CONFIG_MTD_CFI_INTELEXT is not set
CONFIG_MTD_CFI_AMDSTD=y
-CONFIG_MTD_CFI_AMDSTD_RETRY=0
# CONFIG_MTD_CFI_STAA is not set
CONFIG_MTD_CFI_UTIL=y
# CONFIG_MTD_RAM is not set
CONFIG_MTD_ROM=y
# CONFIG_MTD_ABSENT is not set
+# CONFIG_MTD_OBSOLETE_CHIPS is not set
#
# Mapping drivers for chip access
#
# CONFIG_MTD_COMPLEX_MAPPINGS is not set
# CONFIG_MTD_PHYSMAP is not set
-CONFIG_MTD_SOLUTIONENGINE=y
-CONFIG_MTD_SUPERH_RESERVE=0x00010000
-# CONFIG_MTD_MPC1211 is not set
-# CONFIG_MTD_RTS7751R2D is not set
+# CONFIG_MTD_PLATRAM is not set
#
# Self-contained MTD device drivers
@@ -240,7 +440,6 @@ CONFIG_MTD_SUPERH_RESERVE=0x00010000
# CONFIG_MTD_SLRAM is not set
# CONFIG_MTD_PHRAM is not set
# CONFIG_MTD_MTDRAM is not set
-# CONFIG_MTD_BLKMTD is not set
# CONFIG_MTD_BLOCK2MTD is not set
#
@@ -256,6 +455,11 @@ CONFIG_MTD_SUPERH_RESERVE=0x00010000
# CONFIG_MTD_NAND is not set
#
+# OneNAND Flash Device Drivers
+#
+# CONFIG_MTD_ONENAND is not set
+
+#
# Parallel port support
#
# CONFIG_PARPORT is not set
@@ -267,23 +471,12 @@ CONFIG_MTD_SUPERH_RESERVE=0x00010000
#
# Block devices
#
-# CONFIG_BLK_DEV_FD is not set
# CONFIG_BLK_DEV_COW_COMMON is not set
# CONFIG_BLK_DEV_LOOP is not set
# CONFIG_BLK_DEV_NBD is not set
# CONFIG_BLK_DEV_RAM is not set
-CONFIG_BLK_DEV_RAM_COUNT=16
-CONFIG_INITRAMFS_SOURCE=""
-# CONFIG_LBD is not set
+# CONFIG_BLK_DEV_INITRD is not set
# CONFIG_CDROM_PKTCDVD is not set
-
-#
-# IO Schedulers
-#
-CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
-CONFIG_IOSCHED_DEADLINE=y
-CONFIG_IOSCHED_CFQ=y
# CONFIG_ATA_OVER_ETH is not set
#
@@ -294,7 +487,14 @@ CONFIG_IOSCHED_CFQ=y
#
# SCSI device support
#
+# CONFIG_RAID_ATTRS is not set
# CONFIG_SCSI is not set
+# CONFIG_SCSI_NETLINK is not set
+
+#
+# Serial ATA (prod) and Parallel ATA (experimental) drivers
+#
+# CONFIG_ATA is not set
#
# Multi-device support (RAID and LVM)
@@ -304,6 +504,7 @@ CONFIG_IOSCHED_CFQ=y
#
# Fusion MPT device support
#
+# CONFIG_FUSION is not set
#
# IEEE 1394 (FireWire) support
@@ -314,71 +515,8 @@ CONFIG_IOSCHED_CFQ=y
#
#
-# Networking support
-#
-CONFIG_NET=y
-
-#
-# Networking options
-#
-CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
-# CONFIG_NETLINK_DEV is not set
-CONFIG_UNIX=y
-# CONFIG_NET_KEY is not set
-CONFIG_INET=y
-CONFIG_IP_MULTICAST=y
-# CONFIG_IP_ADVANCED_ROUTER is not set
-CONFIG_IP_PNP=y
-# CONFIG_IP_PNP_DHCP is not set
-CONFIG_IP_PNP_BOOTP=y
-# CONFIG_IP_PNP_RARP is not set
-# CONFIG_NET_IPIP is not set
-# CONFIG_NET_IPGRE is not set
-# CONFIG_IP_MROUTE is not set
-# CONFIG_ARPD is not set
-# CONFIG_SYN_COOKIES is not set
-# CONFIG_INET_AH is not set
-# CONFIG_INET_ESP is not set
-# CONFIG_INET_IPCOMP is not set
-# CONFIG_INET_TUNNEL is not set
-CONFIG_IP_TCPDIAG=y
-# CONFIG_IP_TCPDIAG_IPV6 is not set
-# CONFIG_IPV6 is not set
-# CONFIG_NETFILTER is not set
-
-#
-# SCTP Configuration (EXPERIMENTAL)
+# Network device support
#
-# CONFIG_IP_SCTP is not set
-# CONFIG_ATM is not set
-# CONFIG_BRIDGE is not set
-# CONFIG_VLAN_8021Q is not set
-# CONFIG_DECNET is not set
-# CONFIG_LLC2 is not set
-# CONFIG_IPX is not set
-# CONFIG_ATALK is not set
-# CONFIG_X25 is not set
-# CONFIG_LAPB is not set
-# CONFIG_NET_DIVERT is not set
-# CONFIG_ECONET is not set
-# CONFIG_WAN_ROUTER is not set
-
-#
-# QoS and/or fair queueing
-#
-# CONFIG_NET_SCHED is not set
-# CONFIG_NET_CLS_ROUTE is not set
-
-#
-# Network testing
-#
-# CONFIG_NET_PKTGEN is not set
-# CONFIG_NETPOLL is not set
-# CONFIG_NET_POLL_CONTROLLER is not set
-# CONFIG_HAMRADIO is not set
-# CONFIG_IRDA is not set
-# CONFIG_BT is not set
CONFIG_NETDEVICES=y
# CONFIG_DUMMY is not set
# CONFIG_BONDING is not set
@@ -386,6 +524,11 @@ CONFIG_NETDEVICES=y
# CONFIG_TUN is not set
#
+# PHY device support
+#
+# CONFIG_PHYLIB is not set
+
+#
# Ethernet (10 or 100Mbit)
#
CONFIG_NET_ETHERNET=y
@@ -418,6 +561,8 @@ CONFIG_STNIC=y
# CONFIG_SLIP is not set
# CONFIG_SHAPER is not set
# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
#
# ISDN subsystem
@@ -435,20 +580,10 @@ CONFIG_STNIC=y
# CONFIG_INPUT is not set
#
-# Userland interfaces
+# Hardware I/O ports
#
-
-#
-# Input I/O drivers
-#
-# CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
# CONFIG_SERIO is not set
-# CONFIG_SERIO_I8042 is not set
-
-#
-# Input Device Drivers
-#
+# CONFIG_GAMEPORT is not set
#
# Character devices
@@ -462,12 +597,14 @@ CONFIG_SOUND_GAMEPORT=y
CONFIG_SERIAL_8250=y
# CONFIG_SERIAL_8250_CONSOLE is not set
CONFIG_SERIAL_8250_NR_UARTS=2
+CONFIG_SERIAL_8250_RUNTIME_UARTS=2
# CONFIG_SERIAL_8250_EXTENDED is not set
#
# Non-8250 serial port support
#
CONFIG_SERIAL_SH_SCI=y
+CONFIG_SERIAL_SH_SCI_NR_UARTS=2
CONFIG_SERIAL_SH_SCI_CONSOLE=y
CONFIG_SERIAL_CORE=y
CONFIG_SERIAL_CORE_CONSOLE=y
@@ -491,7 +628,8 @@ CONFIG_WATCHDOG=y
#
# CONFIG_SOFT_WATCHDOG is not set
CONFIG_SH_WDT=y
-# CONFIG_RTC is not set
+# CONFIG_SH_WDT_MMAP is not set
+CONFIG_HW_RANDOM=y
# CONFIG_GEN_RTC is not set
# CONFIG_DTLK is not set
# CONFIG_R3964 is not set
@@ -499,18 +637,38 @@ CONFIG_SH_WDT=y
#
# Ftape, the floppy tape device driver
#
-# CONFIG_DRM is not set
# CONFIG_RAW_DRIVER is not set
#
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
+# CONFIG_TELCLOCK is not set
+
+#
# I2C support
#
# CONFIG_I2C is not set
#
+# SPI support
+#
+# CONFIG_SPI is not set
+# CONFIG_SPI_MASTER is not set
+
+#
# Dallas's 1-wire bus
#
-# CONFIG_W1 is not set
+
+#
+# Hardware Monitoring support
+#
+CONFIG_HWMON=y
+# CONFIG_HWMON_VID is not set
+# CONFIG_SENSORS_ABITUGURU is not set
+# CONFIG_SENSORS_F71805F is not set
+# CONFIG_SENSORS_VT1211 is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
#
# Misc devices
@@ -520,6 +678,7 @@ CONFIG_SH_WDT=y
# Multimedia devices
#
# CONFIG_VIDEO_DEV is not set
+CONFIG_VIDEO_V4L2=y
#
# Digital Video Broadcasting Devices
@@ -529,7 +688,9 @@ CONFIG_SH_WDT=y
#
# Graphics support
#
+CONFIG_FIRMWARE_EDID=y
# CONFIG_FB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
#
# Sound
@@ -541,9 +702,10 @@ CONFIG_SH_WDT=y
#
# CONFIG_USB_ARCH_HAS_HCD is not set
# CONFIG_USB_ARCH_HAS_OHCI is not set
+# CONFIG_USB_ARCH_HAS_EHCI is not set
#
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
#
#
@@ -557,29 +719,63 @@ CONFIG_SH_WDT=y
# CONFIG_MMC is not set
#
+# LED devices
+#
+# CONFIG_NEW_LEDS is not set
+
+#
+# LED drivers
+#
+
+#
+# LED Triggers
+#
+
+#
# InfiniBand support
#
-# CONFIG_INFINIBAND is not set
+
+#
+# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
+#
+
+#
+# Real Time Clock
+#
+# CONFIG_RTC_CLASS is not set
+
+#
+# DMA Engine support
+#
+# CONFIG_DMA_ENGINE is not set
+
+#
+# DMA Clients
+#
+
+#
+# DMA Devices
+#
#
# File systems
#
# CONFIG_EXT2_FS is not set
# CONFIG_EXT3_FS is not set
-# CONFIG_JBD is not set
# CONFIG_REISERFS_FS is not set
# CONFIG_JFS_FS is not set
-
-#
-# XFS support
-#
+# CONFIG_FS_POSIX_ACL is not set
# CONFIG_XFS_FS is not set
+# CONFIG_OCFS2_FS is not set
# CONFIG_MINIX_FS is not set
# CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
# CONFIG_QUOTA is not set
CONFIG_DNOTIFY=y
# CONFIG_AUTOFS_FS is not set
# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
#
# CD-ROM/DVD Filesystems
@@ -599,14 +795,14 @@ CONFIG_DNOTIFY=y
#
CONFIG_PROC_FS=y
CONFIG_PROC_KCORE=y
+CONFIG_PROC_SYSCTL=y
CONFIG_SYSFS=y
-# CONFIG_DEVFS_FS is not set
-# CONFIG_DEVPTS_FS_XATTR is not set
CONFIG_TMPFS=y
-# CONFIG_TMPFS_XATTR is not set
+# CONFIG_TMPFS_POSIX_ACL is not set
# CONFIG_HUGETLBFS is not set
# CONFIG_HUGETLB_PAGE is not set
CONFIG_RAMFS=y
+# CONFIG_CONFIGFS_FS is not set
#
# Miscellaneous filesystems
@@ -621,8 +817,9 @@ CONFIG_RAMFS=y
# CONFIG_JFFS_FS is not set
CONFIG_JFFS2_FS=y
CONFIG_JFFS2_FS_DEBUG=0
-# CONFIG_JFFS2_FS_NAND is not set
-# CONFIG_JFFS2_FS_NOR_ECC is not set
+CONFIG_JFFS2_FS_WRITEBUFFER=y
+# CONFIG_JFFS2_SUMMARY is not set
+# CONFIG_JFFS2_FS_XATTR is not set
# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
CONFIG_JFFS2_ZLIB=y
CONFIG_JFFS2_RTIME=y
@@ -644,6 +841,7 @@ CONFIG_NFS_FS=y
# CONFIG_NFSD is not set
CONFIG_ROOT_NFS=y
CONFIG_LOCKD=y
+CONFIG_NFS_COMMON=y
CONFIG_SUNRPC=y
# CONFIG_RPCSEC_GSS_KRB5 is not set
# CONFIG_RPCSEC_GSS_SPKM3 is not set
@@ -652,6 +850,7 @@ CONFIG_SUNRPC=y
# CONFIG_NCP_FS is not set
# CONFIG_CODA_FS is not set
# CONFIG_AFS_FS is not set
+# CONFIG_9P_FS is not set
#
# Partition Types
@@ -667,6 +866,7 @@ CONFIG_PARTITION_ADVANCED=y
# CONFIG_SGI_PARTITION is not set
# CONFIG_ULTRIX_PARTITION is not set
# CONFIG_SUN_PARTITION is not set
+# CONFIG_KARMA_PARTITION is not set
# CONFIG_EFI_PARTITION is not set
#
@@ -682,8 +882,14 @@ CONFIG_PARTITION_ADVANCED=y
#
# Kernel hacking
#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_MUST_CHECK=y
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_UNUSED_SYMBOLS is not set
# CONFIG_DEBUG_KERNEL is not set
-# CONFIG_FRAME_POINTER is not set
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_DEBUG_BUGVERBOSE is not set
+# CONFIG_DEBUG_FS is not set
# CONFIG_SH_STANDARD_BIOS is not set
# CONFIG_EARLY_SCIF_CONSOLE is not set
# CONFIG_KGDB is not set
@@ -700,14 +906,12 @@ CONFIG_PARTITION_ADVANCED=y
# CONFIG_CRYPTO is not set
#
-# Hardware crypto devices
-#
-
-#
# Library routines
#
# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
CONFIG_CRC32=y
# CONFIG_LIBCRC32C is not set
CONFIG_ZLIB_INFLATE=y
CONFIG_ZLIB_DEFLATE=y
+CONFIG_PLIST=y
diff --git a/arch/sh/configs/se7751_defconfig b/arch/sh/configs/se7751_defconfig
index 1ce028947459..a9095593f8f3 100644
--- a/arch/sh/configs/se7751_defconfig
+++ b/arch/sh/configs/se7751_defconfig
@@ -1,126 +1,213 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.11-sh
-# Wed Mar 2 15:09:48 2005
+# Linux kernel version: 2.6.18
+# Tue Oct 3 12:10:12 2006
#
CONFIG_SUPERH=y
-CONFIG_UID16=y
CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+CONFIG_GENERIC_HWEIGHT=y
CONFIG_GENERIC_HARDIRQS=y
CONFIG_GENERIC_IRQ_PROBE=y
CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
#
# Code maturity level options
#
CONFIG_EXPERIMENTAL=y
-CONFIG_CLEAN_COMPILE=y
CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
#
# General setup
#
CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
CONFIG_SWAP=y
CONFIG_SYSVIPC=y
+# CONFIG_IPC_NS is not set
# CONFIG_POSIX_MQUEUE is not set
CONFIG_BSD_PROCESS_ACCT=y
# CONFIG_BSD_PROCESS_ACCT_V3 is not set
-CONFIG_SYSCTL=y
+# CONFIG_TASKSTATS is not set
+# CONFIG_UTS_NS is not set
# CONFIG_AUDIT is not set
-CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_HOTPLUG is not set
-CONFIG_KOBJECT_UEVENT=y
# CONFIG_IKCONFIG is not set
+# CONFIG_RELAY is not set
+CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SYSCTL=y
CONFIG_EMBEDDED=y
+CONFIG_UID16=y
+# CONFIG_SYSCTL_SYSCALL is not set
CONFIG_KALLSYMS=y
# CONFIG_KALLSYMS_EXTRA_PASS is not set
+# CONFIG_HOTPLUG is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
CONFIG_EPOLL=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
CONFIG_SHMEM=y
-CONFIG_CC_ALIGN_FUNCTIONS=0
-CONFIG_CC_ALIGN_LABELS=0
-CONFIG_CC_ALIGN_LOOPS=0
-CONFIG_CC_ALIGN_JUMPS=0
+CONFIG_SLAB=y
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_RT_MUTEXES=y
# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+# CONFIG_SLOB is not set
#
# Loadable module support
#
CONFIG_MODULES=y
# CONFIG_MODULE_UNLOAD is not set
-CONFIG_OBSOLETE_MODPARM=y
# CONFIG_MODVERSIONS is not set
# CONFIG_MODULE_SRCVERSION_ALL is not set
# CONFIG_KMOD is not set
#
+# Block layer
+#
+CONFIG_BLOCK=y
+# CONFIG_LBD is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_LSF is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+CONFIG_DEFAULT_AS=y
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="anticipatory"
+
+#
# System type
#
+CONFIG_SOLUTION_ENGINE=y
# CONFIG_SH_SOLUTION_ENGINE is not set
CONFIG_SH_7751_SOLUTION_ENGINE=y
# CONFIG_SH_7300_SOLUTION_ENGINE is not set
+# CONFIG_SH_7343_SOLUTION_ENGINE is not set
# CONFIG_SH_73180_SOLUTION_ENGINE is not set
# CONFIG_SH_7751_SYSTEMH is not set
-# CONFIG_SH_STB1_HARP is not set
-# CONFIG_SH_STB1_OVERDRIVE is not set
-# CONFIG_SH_HP620 is not set
-# CONFIG_SH_HP680 is not set
-# CONFIG_SH_HP690 is not set
-# CONFIG_SH_CQREEK is not set
-# CONFIG_SH_DMIDA is not set
+# CONFIG_SH_HP6XX is not set
# CONFIG_SH_EC3104 is not set
# CONFIG_SH_SATURN is not set
# CONFIG_SH_DREAMCAST is not set
-# CONFIG_SH_CAT68701 is not set
# CONFIG_SH_BIGSUR is not set
-# CONFIG_SH_SH2000 is not set
-# CONFIG_SH_ADX is not set
# CONFIG_SH_MPC1211 is not set
# CONFIG_SH_SH03 is not set
# CONFIG_SH_SECUREEDGE5410 is not set
# CONFIG_SH_HS7751RVOIP is not set
+# CONFIG_SH_7710VOIPGW is not set
# CONFIG_SH_RTS7751R2D is not set
+# CONFIG_SH_R7780RP is not set
# CONFIG_SH_EDOSK7705 is not set
# CONFIG_SH_SH4202_MICRODEV is not set
+# CONFIG_SH_LANDISK is not set
+# CONFIG_SH_TITAN is not set
+# CONFIG_SH_SHMIN is not set
# CONFIG_SH_UNKNOWN is not set
-# CONFIG_CPU_SH2 is not set
-# CONFIG_CPU_SH3 is not set
+
+#
+# Processor selection
+#
CONFIG_CPU_SH4=y
+
+#
+# SH-2 Processor Support
+#
# CONFIG_CPU_SUBTYPE_SH7604 is not set
+
+#
+# SH-3 Processor Support
+#
# CONFIG_CPU_SUBTYPE_SH7300 is not set
# CONFIG_CPU_SUBTYPE_SH7705 is not set
+# CONFIG_CPU_SUBTYPE_SH7706 is not set
# CONFIG_CPU_SUBTYPE_SH7707 is not set
# CONFIG_CPU_SUBTYPE_SH7708 is not set
# CONFIG_CPU_SUBTYPE_SH7709 is not set
+# CONFIG_CPU_SUBTYPE_SH7710 is not set
+
+#
+# SH-4 Processor Support
+#
# CONFIG_CPU_SUBTYPE_SH7750 is not set
+# CONFIG_CPU_SUBTYPE_SH7091 is not set
+# CONFIG_CPU_SUBTYPE_SH7750R is not set
+# CONFIG_CPU_SUBTYPE_SH7750S is not set
CONFIG_CPU_SUBTYPE_SH7751=y
+# CONFIG_CPU_SUBTYPE_SH7751R is not set
# CONFIG_CPU_SUBTYPE_SH7760 is not set
-# CONFIG_CPU_SUBTYPE_SH73180 is not set
+# CONFIG_CPU_SUBTYPE_SH4_202 is not set
+
+#
+# ST40 Processor Support
+#
# CONFIG_CPU_SUBTYPE_ST40STB1 is not set
# CONFIG_CPU_SUBTYPE_ST40GX1 is not set
-# CONFIG_CPU_SUBTYPE_SH4_202 is not set
+
+#
+# SH-4A Processor Support
+#
+# CONFIG_CPU_SUBTYPE_SH7770 is not set
+# CONFIG_CPU_SUBTYPE_SH7780 is not set
+
+#
+# SH4AL-DSP Processor Support
+#
+# CONFIG_CPU_SUBTYPE_SH73180 is not set
+# CONFIG_CPU_SUBTYPE_SH7343 is not set
+
+#
+# Memory management options
+#
CONFIG_MMU=y
-CONFIG_CMDLINE_BOOL=y
-CONFIG_CMDLINE="console=ttySC1,38400"
+CONFIG_PAGE_OFFSET=0x80000000
CONFIG_MEMORY_START=0x0c000000
CONFIG_MEMORY_SIZE=0x04000000
-CONFIG_MEMORY_SET=y
-# CONFIG_MEMORY_OVERRIDE is not set
-CONFIG_SH_RTC=y
-CONFIG_SH_FPU=y
-CONFIG_ZERO_PAGE_OFFSET=0x00010000
-CONFIG_BOOT_LINK_OFFSET=0x00800000
-CONFIG_CPU_LITTLE_ENDIAN=y
-# CONFIG_PREEMPT is not set
-# CONFIG_UBC_WAKEUP is not set
+CONFIG_VSYSCALL=y
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+# CONFIG_SPARSEMEM_STATIC is not set
+CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_RESOURCES_64BIT is not set
+
+#
+# Cache configuration
+#
+# CONFIG_SH_DIRECT_MAPPED is not set
# CONFIG_SH_WRITETHROUGH is not set
# CONFIG_SH_OCRAM is not set
+
+#
+# Processor features
+#
+CONFIG_CPU_LITTLE_ENDIAN=y
+CONFIG_SH_FPU=y
+# CONFIG_SH_DSP is not set
# CONFIG_SH_STORE_QUEUES is not set
-# CONFIG_SMP is not set
-CONFIG_SH_PCLK_CALC=y
-CONFIG_SH_PCLK_FREQ=60013568
+CONFIG_CPU_HAS_INTEVT=y
+CONFIG_CPU_HAS_SR_RB=y
+
+#
+# Timer support
+#
+CONFIG_SH_TMU=y
+CONFIG_SH_PCLK_FREQ=60000000
#
# CPU Frequency scaling
@@ -139,28 +226,39 @@ CONFIG_SH_PCLK_FREQ=60013568
CONFIG_HEARTBEAT=y
#
-# Bus options (PCI, PCMCIA, EISA, MCA, ISA)
+# Kernel features
#
-CONFIG_PCI=y
-# CONFIG_SH_PCIDMA_NONCOHERENT is not set
-CONFIG_PCI_AUTO=y
-CONFIG_PCI_AUTO_UPDATE_RESOURCES=y
-# CONFIG_PCI_LEGACY_PROC is not set
-# CONFIG_PCI_NAMES is not set
+# CONFIG_HZ_100 is not set
+CONFIG_HZ_250=y
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=250
+# CONFIG_KEXEC is not set
+# CONFIG_SMP is not set
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
+# CONFIG_PREEMPT is not set
#
-# PCCARD (PCMCIA/CardBus) support
+# Boot options
+#
+CONFIG_ZERO_PAGE_OFFSET=0x00010000
+CONFIG_BOOT_LINK_OFFSET=0x00800000
+# CONFIG_UBC_WAKEUP is not set
+CONFIG_CMDLINE_BOOL=y
+CONFIG_CMDLINE="console=ttySC1,38400"
+
#
-# CONFIG_PCCARD is not set
+# Bus options
+#
+# CONFIG_PCI is not set
#
-# PC-card bridges
+# PCCARD (PCMCIA/CardBus) support
#
#
# PCI Hotplug Support
#
-# CONFIG_HOTPLUG_PCI is not set
#
# Executable file formats
@@ -170,9 +268,115 @@ CONFIG_BINFMT_ELF=y
# CONFIG_BINFMT_MISC is not set
#
-# SH initrd options
+# Power management options (EXPERIMENTAL)
+#
+# CONFIG_PM is not set
+
+#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+# CONFIG_NETDEBUG is not set
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+# CONFIG_XFRM_USER is not set
+# CONFIG_XFRM_SUB_POLICY is not set
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+CONFIG_IP_PNP_RARP=y
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_IP_MROUTE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+# CONFIG_INET_TUNNEL is not set
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+
+#
+# IP: Virtual Server Configuration
+#
+# CONFIG_IP_VS is not set
+# CONFIG_IPV6 is not set
+# CONFIG_INET6_XFRM_TUNNEL is not set
+# CONFIG_INET6_TUNNEL is not set
+# CONFIG_NETWORK_SECMARK is not set
+CONFIG_NETFILTER=y
+CONFIG_NETFILTER_DEBUG=y
+
+#
+# Core Netfilter Configuration
+#
+# CONFIG_NETFILTER_NETLINK is not set
+# CONFIG_NF_CONNTRACK is not set
+# CONFIG_NETFILTER_XTABLES is not set
+
+#
+# IP: Netfilter Configuration
+#
+# CONFIG_IP_NF_CONNTRACK is not set
+CONFIG_IP_NF_QUEUE=y
+
+#
+# DCCP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_DCCP is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP is not set
+
+#
+# TIPC Configuration (EXPERIMENTAL)
+#
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+
+#
+# Network testing
#
-# CONFIG_EMBEDDED_RAMDISK is not set
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_IEEE80211 is not set
#
# Device Drivers
@@ -183,15 +387,20 @@ CONFIG_BINFMT_ELF=y
#
CONFIG_STANDALONE=y
CONFIG_PREVENT_FIRMWARE_BUILD=y
-# CONFIG_FW_LOADER is not set
+# CONFIG_SYS_HYPERVISOR is not set
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
+# CONFIG_CONNECTOR is not set
#
# Memory Technology Devices (MTD)
#
CONFIG_MTD=y
# CONFIG_MTD_DEBUG is not set
-CONFIG_MTD_PARTITIONS=y
# CONFIG_MTD_CONCAT is not set
+CONFIG_MTD_PARTITIONS=y
# CONFIG_MTD_REDBOOT_PARTS is not set
# CONFIG_MTD_CMDLINE_PARTS is not set
@@ -203,6 +412,8 @@ CONFIG_MTD_BLOCK=y
# CONFIG_FTL is not set
# CONFIG_NFTL is not set
# CONFIG_INFTL is not set
+# CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
#
# RAM/ROM/Flash chip drivers
@@ -223,30 +434,26 @@ CONFIG_MTD_CFI_I2=y
# CONFIG_MTD_CFI_I8 is not set
# CONFIG_MTD_CFI_INTELEXT is not set
CONFIG_MTD_CFI_AMDSTD=y
-CONFIG_MTD_CFI_AMDSTD_RETRY=0
# CONFIG_MTD_CFI_STAA is not set
CONFIG_MTD_CFI_UTIL=y
CONFIG_MTD_RAM=y
# CONFIG_MTD_ROM is not set
# CONFIG_MTD_ABSENT is not set
+# CONFIG_MTD_OBSOLETE_CHIPS is not set
#
# Mapping drivers for chip access
#
# CONFIG_MTD_COMPLEX_MAPPINGS is not set
# CONFIG_MTD_PHYSMAP is not set
-# CONFIG_MTD_SOLUTIONENGINE is not set
-# CONFIG_MTD_MPC1211 is not set
-# CONFIG_MTD_RTS7751R2D is not set
+# CONFIG_MTD_PLATRAM is not set
#
# Self-contained MTD device drivers
#
-# CONFIG_MTD_PMC551 is not set
# CONFIG_MTD_SLRAM is not set
# CONFIG_MTD_PHRAM is not set
# CONFIG_MTD_MTDRAM is not set
-# CONFIG_MTD_BLKMTD is not set
# CONFIG_MTD_BLOCK2MTD is not set
#
@@ -262,6 +469,11 @@ CONFIG_MTD_RAM=y
# CONFIG_MTD_NAND is not set
#
+# OneNAND Flash Device Drivers
+#
+# CONFIG_MTD_ONENAND is not set
+
+#
# Parallel port support
#
# CONFIG_PARPORT is not set
@@ -273,30 +485,15 @@ CONFIG_MTD_RAM=y
#
# Block devices
#
-# CONFIG_BLK_DEV_FD is not set
-# CONFIG_BLK_CPQ_DA is not set
-# CONFIG_BLK_CPQ_CISS_DA is not set
-# CONFIG_BLK_DEV_DAC960 is not set
-# CONFIG_BLK_DEV_UMEM is not set
# CONFIG_BLK_DEV_COW_COMMON is not set
# CONFIG_BLK_DEV_LOOP is not set
# CONFIG_BLK_DEV_NBD is not set
-# CONFIG_BLK_DEV_SX8 is not set
CONFIG_BLK_DEV_RAM=y
CONFIG_BLK_DEV_RAM_COUNT=16
CONFIG_BLK_DEV_RAM_SIZE=4096
+CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
CONFIG_BLK_DEV_INITRD=y
-CONFIG_INITRAMFS_SOURCE=""
-# CONFIG_LBD is not set
# CONFIG_CDROM_PKTCDVD is not set
-
-#
-# IO Schedulers
-#
-CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
-CONFIG_IOSCHED_DEADLINE=y
-CONFIG_IOSCHED_CFQ=y
# CONFIG_ATA_OVER_ETH is not set
#
@@ -307,7 +504,14 @@ CONFIG_IOSCHED_CFQ=y
#
# SCSI device support
#
+# CONFIG_RAID_ATTRS is not set
# CONFIG_SCSI is not set
+# CONFIG_SCSI_NETLINK is not set
+
+#
+# Serial ATA (prod) and Parallel ATA (experimental) drivers
+#
+# CONFIG_ATA is not set
#
# Multi-device support (RAID and LVM)
@@ -317,109 +521,29 @@ CONFIG_IOSCHED_CFQ=y
#
# Fusion MPT device support
#
+# CONFIG_FUSION is not set
#
# IEEE 1394 (FireWire) support
#
-# CONFIG_IEEE1394 is not set
#
# I2O device support
#
-# CONFIG_I2O is not set
-
-#
-# Networking support
-#
-CONFIG_NET=y
-
-#
-# Networking options
-#
-CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
-CONFIG_NETLINK_DEV=y
-CONFIG_UNIX=y
-# CONFIG_NET_KEY is not set
-CONFIG_INET=y
-CONFIG_IP_MULTICAST=y
-# CONFIG_IP_ADVANCED_ROUTER is not set
-CONFIG_IP_PNP=y
-CONFIG_IP_PNP_DHCP=y
-CONFIG_IP_PNP_BOOTP=y
-CONFIG_IP_PNP_RARP=y
-# CONFIG_NET_IPIP is not set
-# CONFIG_NET_IPGRE is not set
-# CONFIG_IP_MROUTE is not set
-# CONFIG_ARPD is not set
-# CONFIG_SYN_COOKIES is not set
-# CONFIG_INET_AH is not set
-# CONFIG_INET_ESP is not set
-# CONFIG_INET_IPCOMP is not set
-# CONFIG_INET_TUNNEL is not set
-CONFIG_IP_TCPDIAG=y
-# CONFIG_IP_TCPDIAG_IPV6 is not set
-
-#
-# IP: Virtual Server Configuration
-#
-# CONFIG_IP_VS is not set
-# CONFIG_IPV6 is not set
-CONFIG_NETFILTER=y
-CONFIG_NETFILTER_DEBUG=y
-
-#
-# IP: Netfilter Configuration
-#
-# CONFIG_IP_NF_CONNTRACK is not set
-# CONFIG_IP_NF_CONNTRACK_MARK is not set
-CONFIG_IP_NF_QUEUE=y
-# CONFIG_IP_NF_IPTABLES is not set
-# CONFIG_IP_NF_ARPTABLES is not set
-
-#
-# SCTP Configuration (EXPERIMENTAL)
-#
-# CONFIG_IP_SCTP is not set
-# CONFIG_ATM is not set
-# CONFIG_BRIDGE is not set
-# CONFIG_VLAN_8021Q is not set
-# CONFIG_DECNET is not set
-# CONFIG_LLC2 is not set
-# CONFIG_IPX is not set
-# CONFIG_ATALK is not set
-# CONFIG_X25 is not set
-# CONFIG_LAPB is not set
-# CONFIG_NET_DIVERT is not set
-# CONFIG_ECONET is not set
-# CONFIG_WAN_ROUTER is not set
-
-#
-# QoS and/or fair queueing
-#
-# CONFIG_NET_SCHED is not set
-# CONFIG_NET_CLS_ROUTE is not set
#
-# Network testing
+# Network device support
#
-# CONFIG_NET_PKTGEN is not set
-# CONFIG_NETPOLL is not set
-# CONFIG_NET_POLL_CONTROLLER is not set
-# CONFIG_HAMRADIO is not set
-# CONFIG_IRDA is not set
-# CONFIG_BT is not set
CONFIG_NETDEVICES=y
# CONFIG_DUMMY is not set
# CONFIG_BONDING is not set
# CONFIG_EQUALIZER is not set
# CONFIG_TUN is not set
-# CONFIG_ETHERTAP is not set
#
-# ARCnet devices
+# PHY device support
#
-# CONFIG_ARCNET is not set
+# CONFIG_PHYLIB is not set
#
# Ethernet (10 or 100Mbit)
@@ -427,60 +551,19 @@ CONFIG_NETDEVICES=y
CONFIG_NET_ETHERNET=y
CONFIG_MII=y
# CONFIG_STNIC is not set
-# CONFIG_HAPPYMEAL is not set
-# CONFIG_SUNGEM is not set
-# CONFIG_NET_VENDOR_3COM is not set
# CONFIG_SMC91X is not set
#
-# Tulip family network device support
-#
-# CONFIG_NET_TULIP is not set
-# CONFIG_HP100 is not set
-CONFIG_NET_PCI=y
-CONFIG_PCNET32=y
-# CONFIG_AMD8111_ETH is not set
-# CONFIG_ADAPTEC_STARFIRE is not set
-# CONFIG_B44 is not set
-# CONFIG_FORCEDETH is not set
-# CONFIG_DGRS is not set
-# CONFIG_EEPRO100 is not set
-# CONFIG_E100 is not set
-# CONFIG_FEALNX is not set
-# CONFIG_NATSEMI is not set
-# CONFIG_NE2K_PCI is not set
-# CONFIG_8139CP is not set
-# CONFIG_8139TOO is not set
-# CONFIG_SIS900 is not set
-# CONFIG_EPIC100 is not set
-# CONFIG_SUNDANCE is not set
-# CONFIG_TLAN is not set
-# CONFIG_VIA_RHINE is not set
-
-#
# Ethernet (1000 Mbit)
#
-# CONFIG_ACENIC is not set
-# CONFIG_DL2K is not set
-# CONFIG_E1000 is not set
-# CONFIG_NS83820 is not set
-# CONFIG_HAMACHI is not set
-# CONFIG_YELLOWFIN is not set
-# CONFIG_R8169 is not set
-# CONFIG_SK98LIN is not set
-# CONFIG_VIA_VELOCITY is not set
-# CONFIG_TIGON3 is not set
#
# Ethernet (10000 Mbit)
#
-# CONFIG_IXGB is not set
-# CONFIG_S2IO is not set
#
# Token Ring devices
#
-# CONFIG_TR is not set
#
# Wireless LAN (non-hamradio)
@@ -491,12 +574,12 @@ CONFIG_PCNET32=y
# Wan interfaces
#
# CONFIG_WAN is not set
-# CONFIG_FDDI is not set
-# CONFIG_HIPPI is not set
# CONFIG_PPP is not set
# CONFIG_SLIP is not set
# CONFIG_SHAPER is not set
# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
#
# ISDN subsystem
@@ -514,20 +597,10 @@ CONFIG_PCNET32=y
# CONFIG_INPUT is not set
#
-# Userland interfaces
-#
-
+# Hardware I/O ports
#
-# Input I/O drivers
-#
-# CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
# CONFIG_SERIO is not set
-# CONFIG_SERIO_I8042 is not set
-
-#
-# Input Device Drivers
-#
+# CONFIG_GAMEPORT is not set
#
# Character devices
@@ -564,33 +637,46 @@ CONFIG_WATCHDOG=y
#
# CONFIG_SOFT_WATCHDOG is not set
# CONFIG_SH_WDT is not set
-
-#
-# PCI-based Watchdog Cards
-#
-# CONFIG_PCIPCWATCHDOG is not set
-# CONFIG_WDTPCI is not set
-# CONFIG_RTC is not set
+CONFIG_HW_RANDOM=y
# CONFIG_GEN_RTC is not set
# CONFIG_DTLK is not set
# CONFIG_R3964 is not set
-# CONFIG_APPLICOM is not set
#
# Ftape, the floppy tape device driver
#
-# CONFIG_DRM is not set
# CONFIG_RAW_DRIVER is not set
#
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
+# CONFIG_TELCLOCK is not set
+
+#
# I2C support
#
# CONFIG_I2C is not set
#
+# SPI support
+#
+# CONFIG_SPI is not set
+# CONFIG_SPI_MASTER is not set
+
+#
# Dallas's 1-wire bus
#
-# CONFIG_W1 is not set
+
+#
+# Hardware Monitoring support
+#
+CONFIG_HWMON=y
+# CONFIG_HWMON_VID is not set
+# CONFIG_SENSORS_ABITUGURU is not set
+# CONFIG_SENSORS_F71805F is not set
+# CONFIG_SENSORS_VT1211 is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
#
# Misc devices
@@ -600,6 +686,7 @@ CONFIG_WATCHDOG=y
# Multimedia devices
#
# CONFIG_VIDEO_DEV is not set
+CONFIG_VIDEO_V4L2=y
#
# Digital Video Broadcasting Devices
@@ -609,7 +696,9 @@ CONFIG_WATCHDOG=y
#
# Graphics support
#
+CONFIG_FIRMWARE_EDID=y
# CONFIG_FB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
#
# Sound
@@ -619,12 +708,12 @@ CONFIG_WATCHDOG=y
#
# USB support
#
-# CONFIG_USB is not set
-CONFIG_USB_ARCH_HAS_HCD=y
-CONFIG_USB_ARCH_HAS_OHCI=y
+# CONFIG_USB_ARCH_HAS_HCD is not set
+# CONFIG_USB_ARCH_HAS_OHCI is not set
+# CONFIG_USB_ARCH_HAS_EHCI is not set
#
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
#
#
@@ -638,30 +727,65 @@ CONFIG_USB_ARCH_HAS_OHCI=y
# CONFIG_MMC is not set
#
+# LED devices
+#
+# CONFIG_NEW_LEDS is not set
+
+#
+# LED drivers
+#
+
+#
+# LED Triggers
+#
+
+#
# InfiniBand support
#
-# CONFIG_INFINIBAND is not set
+
+#
+# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
+#
+
+#
+# Real Time Clock
+#
+# CONFIG_RTC_CLASS is not set
+
+#
+# DMA Engine support
+#
+# CONFIG_DMA_ENGINE is not set
+
+#
+# DMA Clients
+#
+
+#
+# DMA Devices
+#
#
# File systems
#
CONFIG_EXT2_FS=y
# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
# CONFIG_EXT3_FS is not set
-# CONFIG_JBD is not set
# CONFIG_REISERFS_FS is not set
# CONFIG_JFS_FS is not set
-
-#
-# XFS support
-#
+# CONFIG_FS_POSIX_ACL is not set
# CONFIG_XFS_FS is not set
+# CONFIG_OCFS2_FS is not set
# CONFIG_MINIX_FS is not set
# CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
# CONFIG_QUOTA is not set
CONFIG_DNOTIFY=y
# CONFIG_AUTOFS_FS is not set
# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
#
# CD-ROM/DVD Filesystems
@@ -681,14 +805,14 @@ CONFIG_DNOTIFY=y
#
CONFIG_PROC_FS=y
CONFIG_PROC_KCORE=y
+CONFIG_PROC_SYSCTL=y
CONFIG_SYSFS=y
-# CONFIG_DEVFS_FS is not set
-# CONFIG_DEVPTS_FS_XATTR is not set
CONFIG_TMPFS=y
-# CONFIG_TMPFS_XATTR is not set
+# CONFIG_TMPFS_POSIX_ACL is not set
# CONFIG_HUGETLBFS is not set
# CONFIG_HUGETLB_PAGE is not set
CONFIG_RAMFS=y
+# CONFIG_CONFIGFS_FS is not set
#
# Miscellaneous filesystems
@@ -703,8 +827,9 @@ CONFIG_RAMFS=y
# CONFIG_JFFS_FS is not set
CONFIG_JFFS2_FS=y
CONFIG_JFFS2_FS_DEBUG=0
-# CONFIG_JFFS2_FS_NAND is not set
-# CONFIG_JFFS2_FS_NOR_ECC is not set
+CONFIG_JFFS2_FS_WRITEBUFFER=y
+# CONFIG_JFFS2_SUMMARY is not set
+# CONFIG_JFFS2_FS_XATTR is not set
# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
CONFIG_JFFS2_ZLIB=y
CONFIG_JFFS2_RTIME=y
@@ -726,6 +851,7 @@ CONFIG_JFFS2_RTIME=y
# CONFIG_NCP_FS is not set
# CONFIG_CODA_FS is not set
# CONFIG_AFS_FS is not set
+# CONFIG_9P_FS is not set
#
# Partition Types
@@ -746,8 +872,14 @@ CONFIG_MSDOS_PARTITION=y
#
# Kernel hacking
#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_MUST_CHECK=y
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_UNUSED_SYMBOLS is not set
# CONFIG_DEBUG_KERNEL is not set
-# CONFIG_FRAME_POINTER is not set
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_DEBUG_BUGVERBOSE is not set
+# CONFIG_DEBUG_FS is not set
# CONFIG_SH_STANDARD_BIOS is not set
# CONFIG_EARLY_SCIF_CONSOLE is not set
# CONFIG_KGDB is not set
@@ -764,14 +896,12 @@ CONFIG_MSDOS_PARTITION=y
# CONFIG_CRYPTO is not set
#
-# Hardware crypto devices
-#
-
-#
# Library routines
#
# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
CONFIG_CRC32=y
# CONFIG_LIBCRC32C is not set
CONFIG_ZLIB_INFLATE=y
CONFIG_ZLIB_DEFLATE=y
+CONFIG_PLIST=y
diff --git a/arch/sh/configs/sh03_defconfig b/arch/sh/configs/sh03_defconfig
index 078f78c7fe53..9fd5ea7304e5 100644
--- a/arch/sh/configs/sh03_defconfig
+++ b/arch/sh/configs/sh03_defconfig
@@ -1,51 +1,63 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.11-sh
-# Wed Mar 2 15:09:49 2005
+# Linux kernel version: 2.6.18
+# Tue Oct 3 12:13:26 2006
#
CONFIG_SUPERH=y
-CONFIG_UID16=y
CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+CONFIG_GENERIC_HWEIGHT=y
CONFIG_GENERIC_HARDIRQS=y
CONFIG_GENERIC_IRQ_PROBE=y
CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
#
# Code maturity level options
#
CONFIG_EXPERIMENTAL=y
-# CONFIG_CLEAN_COMPILE is not set
-CONFIG_BROKEN=y
CONFIG_BROKEN_ON_SMP=y
CONFIG_LOCK_KERNEL=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
#
# General setup
#
CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
CONFIG_SWAP=y
CONFIG_SYSVIPC=y
+# CONFIG_IPC_NS is not set
CONFIG_POSIX_MQUEUE=y
CONFIG_BSD_PROCESS_ACCT=y
# CONFIG_BSD_PROCESS_ACCT_V3 is not set
-CONFIG_SYSCTL=y
+# CONFIG_TASKSTATS is not set
+# CONFIG_UTS_NS is not set
# CONFIG_AUDIT is not set
-CONFIG_LOG_BUF_SHIFT=14
-CONFIG_HOTPLUG=y
-CONFIG_KOBJECT_UEVENT=y
# CONFIG_IKCONFIG is not set
-# CONFIG_EMBEDDED is not set
+# CONFIG_RELAY is not set
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
+CONFIG_EMBEDDED=y
+CONFIG_UID16=y
+# CONFIG_SYSCTL_SYSCALL is not set
CONFIG_KALLSYMS=y
# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
CONFIG_EPOLL=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
CONFIG_SHMEM=y
-CONFIG_CC_ALIGN_FUNCTIONS=0
-CONFIG_CC_ALIGN_LABELS=0
-CONFIG_CC_ALIGN_LOOPS=0
-CONFIG_CC_ALIGN_JUMPS=0
+CONFIG_SLAB=y
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_RT_MUTEXES=y
# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+# CONFIG_SLOB is not set
#
# Loadable module support
@@ -53,81 +65,154 @@ CONFIG_CC_ALIGN_JUMPS=0
CONFIG_MODULES=y
CONFIG_MODULE_UNLOAD=y
CONFIG_MODULE_FORCE_UNLOAD=y
-CONFIG_OBSOLETE_MODPARM=y
CONFIG_MODVERSIONS=y
# CONFIG_MODULE_SRCVERSION_ALL is not set
CONFIG_KMOD=y
#
+# Block layer
+#
+CONFIG_BLOCK=y
+# CONFIG_LBD is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_LSF is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+CONFIG_DEFAULT_AS=y
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="anticipatory"
+
+#
# System type
#
# CONFIG_SH_SOLUTION_ENGINE is not set
# CONFIG_SH_7751_SOLUTION_ENGINE is not set
# CONFIG_SH_7300_SOLUTION_ENGINE is not set
+# CONFIG_SH_7343_SOLUTION_ENGINE is not set
# CONFIG_SH_73180_SOLUTION_ENGINE is not set
# CONFIG_SH_7751_SYSTEMH is not set
-# CONFIG_SH_STB1_HARP is not set
-# CONFIG_SH_STB1_OVERDRIVE is not set
-# CONFIG_SH_HP620 is not set
-# CONFIG_SH_HP680 is not set
-# CONFIG_SH_HP690 is not set
-# CONFIG_SH_CQREEK is not set
-# CONFIG_SH_DMIDA is not set
+# CONFIG_SH_HP6XX is not set
# CONFIG_SH_EC3104 is not set
# CONFIG_SH_SATURN is not set
# CONFIG_SH_DREAMCAST is not set
-# CONFIG_SH_CAT68701 is not set
# CONFIG_SH_BIGSUR is not set
-# CONFIG_SH_SH2000 is not set
-# CONFIG_SH_ADX is not set
# CONFIG_SH_MPC1211 is not set
CONFIG_SH_SH03=y
# CONFIG_SH_SECUREEDGE5410 is not set
# CONFIG_SH_HS7751RVOIP is not set
+# CONFIG_SH_7710VOIPGW is not set
# CONFIG_SH_RTS7751R2D is not set
+# CONFIG_SH_R7780RP is not set
# CONFIG_SH_EDOSK7705 is not set
# CONFIG_SH_SH4202_MICRODEV is not set
+# CONFIG_SH_LANDISK is not set
+# CONFIG_SH_TITAN is not set
+# CONFIG_SH_SHMIN is not set
# CONFIG_SH_UNKNOWN is not set
-# CONFIG_CPU_SH2 is not set
-# CONFIG_CPU_SH3 is not set
+
+#
+# Processor selection
+#
CONFIG_CPU_SH4=y
+
+#
+# SH-2 Processor Support
+#
# CONFIG_CPU_SUBTYPE_SH7604 is not set
+
+#
+# SH-3 Processor Support
+#
# CONFIG_CPU_SUBTYPE_SH7300 is not set
# CONFIG_CPU_SUBTYPE_SH7705 is not set
+# CONFIG_CPU_SUBTYPE_SH7706 is not set
# CONFIG_CPU_SUBTYPE_SH7707 is not set
# CONFIG_CPU_SUBTYPE_SH7708 is not set
# CONFIG_CPU_SUBTYPE_SH7709 is not set
+# CONFIG_CPU_SUBTYPE_SH7710 is not set
+
+#
+# SH-4 Processor Support
+#
# CONFIG_CPU_SUBTYPE_SH7750 is not set
+# CONFIG_CPU_SUBTYPE_SH7091 is not set
+# CONFIG_CPU_SUBTYPE_SH7750R is not set
+# CONFIG_CPU_SUBTYPE_SH7750S is not set
CONFIG_CPU_SUBTYPE_SH7751=y
+# CONFIG_CPU_SUBTYPE_SH7751R is not set
# CONFIG_CPU_SUBTYPE_SH7760 is not set
-# CONFIG_CPU_SUBTYPE_SH73180 is not set
+# CONFIG_CPU_SUBTYPE_SH4_202 is not set
+
+#
+# ST40 Processor Support
+#
# CONFIG_CPU_SUBTYPE_ST40STB1 is not set
# CONFIG_CPU_SUBTYPE_ST40GX1 is not set
-# CONFIG_CPU_SUBTYPE_SH4_202 is not set
+
+#
+# SH-4A Processor Support
+#
+# CONFIG_CPU_SUBTYPE_SH7770 is not set
+# CONFIG_CPU_SUBTYPE_SH7780 is not set
+
+#
+# SH4AL-DSP Processor Support
+#
+# CONFIG_CPU_SUBTYPE_SH73180 is not set
+# CONFIG_CPU_SUBTYPE_SH7343 is not set
+
+#
+# Memory management options
+#
CONFIG_MMU=y
-CONFIG_CMDLINE_BOOL=y
-CONFIG_CMDLINE="console=ttySC1,115200 mem=64M root=/dev/nfs"
+CONFIG_PAGE_OFFSET=0x80000000
CONFIG_MEMORY_START=0x08000000
CONFIG_MEMORY_SIZE=0x08000000
-CONFIG_MEMORY_SET=y
-# CONFIG_MEMORY_OVERRIDE is not set
+CONFIG_VSYSCALL=y
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+# CONFIG_SPARSEMEM_STATIC is not set
+CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_RESOURCES_64BIT is not set
+
+#
+# Cache configuration
+#
+# CONFIG_SH_DIRECT_MAPPED is not set
+# CONFIG_SH_WRITETHROUGH is not set
+# CONFIG_SH_OCRAM is not set
CONFIG_CF_ENABLER=y
CONFIG_CF_AREA5=y
# CONFIG_CF_AREA6 is not set
CONFIG_CF_BASE_ADDR=0xb4000000
-CONFIG_SH_RTC=y
-CONFIG_SH_FPU=y
-CONFIG_ZERO_PAGE_OFFSET=0x00004000
-CONFIG_BOOT_LINK_OFFSET=0x00800000
+
+#
+# Processor features
+#
CONFIG_CPU_LITTLE_ENDIAN=y
-CONFIG_PREEMPT=y
-# CONFIG_UBC_WAKEUP is not set
-# CONFIG_SH_WRITETHROUGH is not set
-# CONFIG_SH_OCRAM is not set
+CONFIG_SH_FPU=y
+# CONFIG_SH_DSP is not set
# CONFIG_SH_STORE_QUEUES is not set
-# CONFIG_SMP is not set
-CONFIG_SH_PCLK_CALC=y
-CONFIG_SH_PCLK_FREQ=49876504
+CONFIG_CPU_HAS_INTEVT=y
+CONFIG_CPU_HAS_SR_RB=y
+
+#
+# Timer support
+#
+CONFIG_SH_TMU=y
+CONFIG_SH_PCLK_FREQ=60000000
#
# CPU Frequency scaling
@@ -146,14 +231,36 @@ CONFIG_SH_PCLK_FREQ=49876504
CONFIG_HEARTBEAT=y
#
-# Bus options (PCI, PCMCIA, EISA, MCA, ISA)
+# Kernel features
+#
+# CONFIG_HZ_100 is not set
+CONFIG_HZ_250=y
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=250
+# CONFIG_KEXEC is not set
+# CONFIG_SMP is not set
+# CONFIG_PREEMPT_NONE is not set
+# CONFIG_PREEMPT_VOLUNTARY is not set
+CONFIG_PREEMPT=y
+CONFIG_PREEMPT_BKL=y
+
+#
+# Boot options
+#
+CONFIG_ZERO_PAGE_OFFSET=0x00004000
+CONFIG_BOOT_LINK_OFFSET=0x00800000
+# CONFIG_UBC_WAKEUP is not set
+CONFIG_CMDLINE_BOOL=y
+CONFIG_CMDLINE="console=ttySC1,115200 mem=64M root=/dev/nfs"
+
+#
+# Bus options
#
CONFIG_PCI=y
CONFIG_SH_PCIDMA_NONCOHERENT=y
CONFIG_PCI_AUTO=y
CONFIG_PCI_AUTO_UPDATE_RESOURCES=y
-CONFIG_PCI_LEGACY_PROC=y
-CONFIG_PCI_NAMES=y
+# CONFIG_PCI_MULTITHREAD_PROBE is not set
#
# PCCARD (PCMCIA/CardBus) support
@@ -161,10 +268,6 @@ CONFIG_PCI_NAMES=y
# CONFIG_PCCARD is not set
#
-# PC-card bridges
-#
-
-#
# PCI Hotplug Support
#
CONFIG_HOTPLUG_PCI=m
@@ -180,9 +283,96 @@ CONFIG_BINFMT_ELF=y
CONFIG_BINFMT_MISC=y
#
-# SH initrd options
+# Power management options (EXPERIMENTAL)
+#
+# CONFIG_PM is not set
+
+#
+# Networking
#
-# CONFIG_EMBEDDED_RAMDISK is not set
+CONFIG_NET=y
+
+#
+# Networking options
+#
+# CONFIG_NETDEBUG is not set
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+# CONFIG_XFRM_USER is not set
+# CONFIG_XFRM_SUB_POLICY is not set
+CONFIG_NET_KEY=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+CONFIG_IP_PNP_RARP=y
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_IP_MROUTE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+# CONFIG_INET_TUNNEL is not set
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_IPV6 is not set
+# CONFIG_INET6_XFRM_TUNNEL is not set
+# CONFIG_INET6_TUNNEL is not set
+# CONFIG_NETWORK_SECMARK is not set
+# CONFIG_NETFILTER is not set
+
+#
+# DCCP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_DCCP is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP is not set
+
+#
+# TIPC Configuration (EXPERIMENTAL)
+#
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_IEEE80211 is not set
#
# Device Drivers
@@ -194,6 +384,12 @@ CONFIG_BINFMT_MISC=y
# CONFIG_STANDALONE is not set
# CONFIG_PREVENT_FIRMWARE_BUILD is not set
# CONFIG_FW_LOADER is not set
+# CONFIG_SYS_HYPERVISOR is not set
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
+# CONFIG_CONNECTOR is not set
#
# Memory Technology Devices (MTD)
@@ -212,7 +408,6 @@ CONFIG_BINFMT_MISC=y
#
# Block devices
#
-# CONFIG_BLK_DEV_FD is not set
# CONFIG_BLK_CPQ_DA is not set
# CONFIG_BLK_CPQ_CISS_DA is not set
# CONFIG_BLK_DEV_DAC960 is not set
@@ -225,18 +420,9 @@ CONFIG_BLK_DEV_NBD=y
CONFIG_BLK_DEV_RAM=y
CONFIG_BLK_DEV_RAM_COUNT=16
CONFIG_BLK_DEV_RAM_SIZE=4096
+CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
CONFIG_BLK_DEV_INITRD=y
-CONFIG_INITRAMFS_SOURCE=""
-# CONFIG_LBD is not set
# CONFIG_CDROM_PKTCDVD is not set
-
-#
-# IO Schedulers
-#
-CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
-CONFIG_IOSCHED_DEADLINE=y
-CONFIG_IOSCHED_CFQ=y
# CONFIG_ATA_OVER_ETH is not set
#
@@ -263,7 +449,6 @@ CONFIG_BLK_DEV_IDEFLOPPY=m
#
CONFIG_IDE_GENERIC=y
# CONFIG_BLK_DEV_IDEPCI is not set
-CONFIG_IDE_SH=y
# CONFIG_IDE_ARM is not set
# CONFIG_BLK_DEV_IDEDMA is not set
# CONFIG_IDEDMA_AUTO is not set
@@ -272,7 +457,9 @@ CONFIG_IDE_SH=y
#
# SCSI device support
#
+# CONFIG_RAID_ATTRS is not set
CONFIG_SCSI=m
+# CONFIG_SCSI_NETLINK is not set
CONFIG_SCSI_PROC_FS=y
#
@@ -284,6 +471,7 @@ CONFIG_BLK_DEV_SD=m
CONFIG_BLK_DEV_SR=m
CONFIG_BLK_DEV_SR_VENDOR=y
CONFIG_CHR_DEV_SG=m
+# CONFIG_CHR_DEV_SCH is not set
#
# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
@@ -293,15 +481,18 @@ CONFIG_CHR_DEV_SG=m
# CONFIG_SCSI_LOGGING is not set
#
-# SCSI Transport Attributes
+# SCSI Transports
#
# CONFIG_SCSI_SPI_ATTRS is not set
# CONFIG_SCSI_FC_ATTRS is not set
# CONFIG_SCSI_ISCSI_ATTRS is not set
+# CONFIG_SCSI_SAS_ATTRS is not set
+# CONFIG_SCSI_SAS_LIBSAS is not set
#
# SCSI low-level drivers
#
+# CONFIG_ISCSI_TCP is not set
# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
# CONFIG_SCSI_3W_9XXX is not set
# CONFIG_SCSI_ACARD is not set
@@ -309,40 +500,35 @@ CONFIG_CHR_DEV_SG=m
# CONFIG_SCSI_AIC7XXX is not set
# CONFIG_SCSI_AIC7XXX_OLD is not set
# CONFIG_SCSI_AIC79XX is not set
+# CONFIG_SCSI_AIC94XX is not set
# CONFIG_SCSI_DPT_I2O is not set
-# CONFIG_SCSI_ADVANSYS is not set
+# CONFIG_SCSI_ARCMSR is not set
# CONFIG_MEGARAID_NEWGEN is not set
# CONFIG_MEGARAID_LEGACY is not set
-# CONFIG_SCSI_SATA is not set
-# CONFIG_SCSI_BUSLOGIC is not set
-# CONFIG_SCSI_CPQFCTS is not set
+# CONFIG_MEGARAID_SAS is not set
+# CONFIG_SCSI_HPTIOP is not set
# CONFIG_SCSI_DMX3191D is not set
-# CONFIG_SCSI_EATA is not set
-# CONFIG_SCSI_EATA_PIO is not set
# CONFIG_SCSI_FUTURE_DOMAIN is not set
-# CONFIG_SCSI_GDTH is not set
# CONFIG_SCSI_IPS is not set
# CONFIG_SCSI_INITIO is not set
# CONFIG_SCSI_INIA100 is not set
+# CONFIG_SCSI_STEX is not set
# CONFIG_SCSI_SYM53C8XX_2 is not set
# CONFIG_SCSI_IPR is not set
-# CONFIG_SCSI_PCI2000 is not set
-# CONFIG_SCSI_PCI2220I is not set
-# CONFIG_SCSI_QLOGIC_ISP is not set
-# CONFIG_SCSI_QLOGIC_FC is not set
# CONFIG_SCSI_QLOGIC_1280 is not set
-CONFIG_SCSI_QLA2XXX=m
-# CONFIG_SCSI_QLA21XX is not set
-# CONFIG_SCSI_QLA22XX is not set
-# CONFIG_SCSI_QLA2300 is not set
-# CONFIG_SCSI_QLA2322 is not set
-# CONFIG_SCSI_QLA6312 is not set
+# CONFIG_SCSI_QLA_FC is not set
+# CONFIG_SCSI_LPFC is not set
# CONFIG_SCSI_DC395x is not set
# CONFIG_SCSI_DC390T is not set
# CONFIG_SCSI_NSP32 is not set
# CONFIG_SCSI_DEBUG is not set
#
+# Serial ATA (prod) and Parallel ATA (experimental) drivers
+#
+# CONFIG_ATA is not set
+
+#
# Multi-device support (RAID and LVM)
#
# CONFIG_MD is not set
@@ -351,6 +537,9 @@ CONFIG_SCSI_QLA2XXX=m
# Fusion MPT device support
#
# CONFIG_FUSION is not set
+# CONFIG_FUSION_SPI is not set
+# CONFIG_FUSION_FC is not set
+# CONFIG_FUSION_SAS is not set
#
# IEEE 1394 (FireWire) support
@@ -363,73 +552,8 @@ CONFIG_SCSI_QLA2XXX=m
# CONFIG_I2O is not set
#
-# Networking support
+# Network device support
#
-CONFIG_NET=y
-
-#
-# Networking options
-#
-CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
-# CONFIG_NETLINK_DEV is not set
-CONFIG_UNIX=y
-CONFIG_NET_KEY=y
-CONFIG_INET=y
-CONFIG_IP_MULTICAST=y
-# CONFIG_IP_ADVANCED_ROUTER is not set
-CONFIG_IP_PNP=y
-CONFIG_IP_PNP_DHCP=y
-CONFIG_IP_PNP_BOOTP=y
-CONFIG_IP_PNP_RARP=y
-# CONFIG_NET_IPIP is not set
-# CONFIG_NET_IPGRE is not set
-# CONFIG_IP_MROUTE is not set
-# CONFIG_ARPD is not set
-# CONFIG_SYN_COOKIES is not set
-# CONFIG_INET_AH is not set
-# CONFIG_INET_ESP is not set
-# CONFIG_INET_IPCOMP is not set
-# CONFIG_INET_TUNNEL is not set
-CONFIG_IP_TCPDIAG=y
-# CONFIG_IP_TCPDIAG_IPV6 is not set
-# CONFIG_IPV6 is not set
-# CONFIG_NETFILTER is not set
-CONFIG_XFRM=y
-# CONFIG_XFRM_USER is not set
-
-#
-# SCTP Configuration (EXPERIMENTAL)
-#
-# CONFIG_IP_SCTP is not set
-# CONFIG_ATM is not set
-# CONFIG_BRIDGE is not set
-# CONFIG_VLAN_8021Q is not set
-# CONFIG_DECNET is not set
-# CONFIG_LLC2 is not set
-# CONFIG_IPX is not set
-# CONFIG_ATALK is not set
-# CONFIG_X25 is not set
-# CONFIG_LAPB is not set
-# CONFIG_NET_DIVERT is not set
-# CONFIG_ECONET is not set
-# CONFIG_WAN_ROUTER is not set
-
-#
-# QoS and/or fair queueing
-#
-# CONFIG_NET_SCHED is not set
-# CONFIG_NET_CLS_ROUTE is not set
-
-#
-# Network testing
-#
-# CONFIG_NET_PKTGEN is not set
-# CONFIG_NETPOLL is not set
-# CONFIG_NET_POLL_CONTROLLER is not set
-# CONFIG_HAMRADIO is not set
-# CONFIG_IRDA is not set
-# CONFIG_BT is not set
CONFIG_NETDEVICES=y
# CONFIG_DUMMY is not set
# CONFIG_BONDING is not set
@@ -442,6 +566,11 @@ CONFIG_NETDEVICES=y
# CONFIG_ARCNET is not set
#
+# PHY device support
+#
+# CONFIG_PHYLIB is not set
+
+#
# Ethernet (10 or 100Mbit)
#
CONFIG_NET_ETHERNET=y
@@ -449,6 +578,7 @@ CONFIG_MII=y
# CONFIG_STNIC is not set
# CONFIG_HAPPYMEAL is not set
# CONFIG_SUNGEM is not set
+# CONFIG_CASSINI is not set
# CONFIG_NET_VENDOR_3COM is not set
# CONFIG_SMC91X is not set
@@ -487,15 +617,22 @@ CONFIG_8139CP=y
# CONFIG_HAMACHI is not set
# CONFIG_YELLOWFIN is not set
# CONFIG_R8169 is not set
+# CONFIG_SIS190 is not set
+# CONFIG_SKGE is not set
+# CONFIG_SKY2 is not set
# CONFIG_SK98LIN is not set
# CONFIG_VIA_VELOCITY is not set
# CONFIG_TIGON3 is not set
+# CONFIG_BNX2 is not set
+# CONFIG_QLA3XXX is not set
#
# Ethernet (10000 Mbit)
#
+# CONFIG_CHELSIO_T1 is not set
# CONFIG_IXGB is not set
# CONFIG_S2IO is not set
+# CONFIG_MYRI10GE is not set
#
# Token Ring devices
@@ -518,6 +655,8 @@ CONFIG_8139CP=y
# CONFIG_NET_FC is not set
# CONFIG_SHAPER is not set
# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
#
# ISDN subsystem
@@ -533,6 +672,7 @@ CONFIG_8139CP=y
# Input device support
#
CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
#
# Userland interfaces
@@ -547,14 +687,6 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
# CONFIG_INPUT_EVBUG is not set
#
-# Input I/O drivers
-#
-# CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
-# CONFIG_SERIO is not set
-# CONFIG_SERIO_I8042 is not set
-
-#
# Input Device Drivers
#
# CONFIG_INPUT_KEYBOARD is not set
@@ -564,27 +696,38 @@ CONFIG_SOUND_GAMEPORT=y
# CONFIG_INPUT_MISC is not set
#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
+#
# Character devices
#
CONFIG_VT=y
CONFIG_VT_CONSOLE=y
CONFIG_HW_CONSOLE=y
+# CONFIG_VT_HW_CONSOLE_BINDING is not set
# CONFIG_SERIAL_NONSTANDARD is not set
#
# Serial drivers
#
CONFIG_SERIAL_8250=m
+CONFIG_SERIAL_8250_PCI=m
CONFIG_SERIAL_8250_NR_UARTS=4
+CONFIG_SERIAL_8250_RUNTIME_UARTS=4
# CONFIG_SERIAL_8250_EXTENDED is not set
#
# Non-8250 serial port support
#
CONFIG_SERIAL_SH_SCI=y
+CONFIG_SERIAL_SH_SCI_NR_UARTS=2
CONFIG_SERIAL_SH_SCI_CONSOLE=y
CONFIG_SERIAL_CORE=y
CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_JSM is not set
CONFIG_UNIX98_PTYS=y
CONFIG_LEGACY_PTYS=y
CONFIG_LEGACY_PTY_COUNT=256
@@ -605,14 +748,14 @@ CONFIG_WATCHDOG=y
#
# CONFIG_SOFT_WATCHDOG is not set
CONFIG_SH_WDT=m
+# CONFIG_SH_WDT_MMAP is not set
#
# PCI-based Watchdog Cards
#
# CONFIG_PCIPCWATCHDOG is not set
# CONFIG_WDTPCI is not set
-# CONFIG_RTC is not set
-CONFIG_SH03_RTC=y
+CONFIG_HW_RANDOM=y
# CONFIG_GEN_RTC is not set
# CONFIG_DTLK is not set
# CONFIG_R3964 is not set
@@ -625,14 +768,35 @@ CONFIG_SH03_RTC=y
# CONFIG_RAW_DRIVER is not set
#
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
+# CONFIG_TELCLOCK is not set
+
+#
# I2C support
#
# CONFIG_I2C is not set
#
+# SPI support
+#
+# CONFIG_SPI is not set
+# CONFIG_SPI_MASTER is not set
+
+#
# Dallas's 1-wire bus
#
-# CONFIG_W1 is not set
+
+#
+# Hardware Monitoring support
+#
+CONFIG_HWMON=y
+# CONFIG_HWMON_VID is not set
+# CONFIG_SENSORS_ABITUGURU is not set
+# CONFIG_SENSORS_F71805F is not set
+# CONFIG_SENSORS_VT1211 is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
#
# Misc devices
@@ -642,6 +806,7 @@ CONFIG_SH03_RTC=y
# Multimedia devices
#
# CONFIG_VIDEO_DEV is not set
+CONFIG_VIDEO_V4L2=y
#
# Digital Video Broadcasting Devices
@@ -651,13 +816,14 @@ CONFIG_SH03_RTC=y
#
# Graphics support
#
+CONFIG_FIRMWARE_EDID=y
# CONFIG_FB is not set
#
# Console display driver support
#
-# CONFIG_VGA_CONSOLE is not set
CONFIG_DUMMY_CONSOLE=y
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
#
# Sound
@@ -667,12 +833,13 @@ CONFIG_DUMMY_CONSOLE=y
#
# USB support
#
-# CONFIG_USB is not set
CONFIG_USB_ARCH_HAS_HCD=y
CONFIG_USB_ARCH_HAS_OHCI=y
+CONFIG_USB_ARCH_HAS_EHCI=y
+# CONFIG_USB is not set
#
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
#
#
@@ -686,17 +853,53 @@ CONFIG_USB_ARCH_HAS_OHCI=y
# CONFIG_MMC is not set
#
+# LED devices
+#
+# CONFIG_NEW_LEDS is not set
+
+#
+# LED drivers
+#
+
+#
+# LED Triggers
+#
+
+#
# InfiniBand support
#
# CONFIG_INFINIBAND is not set
#
+# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
+#
+
+#
+# Real Time Clock
+#
+# CONFIG_RTC_CLASS is not set
+
+#
+# DMA Engine support
+#
+# CONFIG_DMA_ENGINE is not set
+
+#
+# DMA Clients
+#
+
+#
+# DMA Devices
+#
+
+#
# File systems
#
CONFIG_EXT2_FS=y
CONFIG_EXT2_FS_XATTR=y
# CONFIG_EXT2_FS_POSIX_ACL is not set
# CONFIG_EXT2_FS_SECURITY is not set
+# CONFIG_EXT2_FS_XIP is not set
CONFIG_EXT3_FS=y
CONFIG_EXT3_FS_XATTR=y
CONFIG_EXT3_FS_POSIX_ACL=y
@@ -707,17 +910,17 @@ CONFIG_FS_MBCACHE=y
# CONFIG_REISERFS_FS is not set
# CONFIG_JFS_FS is not set
CONFIG_FS_POSIX_ACL=y
-
-#
-# XFS support
-#
# CONFIG_XFS_FS is not set
+# CONFIG_OCFS2_FS is not set
# CONFIG_MINIX_FS is not set
# CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
# CONFIG_QUOTA is not set
CONFIG_DNOTIFY=y
CONFIG_AUTOFS_FS=y
CONFIG_AUTOFS4_FS=y
+# CONFIG_FUSE_FS is not set
#
# CD-ROM/DVD Filesystems
@@ -744,14 +947,14 @@ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
#
CONFIG_PROC_FS=y
CONFIG_PROC_KCORE=y
+CONFIG_PROC_SYSCTL=y
CONFIG_SYSFS=y
-# CONFIG_DEVFS_FS is not set
-# CONFIG_DEVPTS_FS_XATTR is not set
CONFIG_TMPFS=y
-# CONFIG_TMPFS_XATTR is not set
+# CONFIG_TMPFS_POSIX_ACL is not set
# CONFIG_HUGETLBFS is not set
# CONFIG_HUGETLB_PAGE is not set
CONFIG_RAMFS=y
+# CONFIG_CONFIGFS_FS is not set
#
# Miscellaneous filesystems
@@ -775,16 +978,19 @@ CONFIG_RAMFS=y
#
CONFIG_NFS_FS=y
CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
CONFIG_NFS_V4=y
# CONFIG_NFS_DIRECTIO is not set
CONFIG_NFSD=y
CONFIG_NFSD_V3=y
+# CONFIG_NFSD_V3_ACL is not set
# CONFIG_NFSD_V4 is not set
CONFIG_NFSD_TCP=y
CONFIG_ROOT_NFS=y
CONFIG_LOCKD=y
CONFIG_LOCKD_V4=y
CONFIG_EXPORTFS=y
+CONFIG_NFS_COMMON=y
CONFIG_SUNRPC=y
CONFIG_SUNRPC_GSS=y
CONFIG_RPCSEC_GSS_KRB5=y
@@ -794,6 +1000,7 @@ CONFIG_RPCSEC_GSS_KRB5=y
# CONFIG_NCP_FS is not set
# CONFIG_CODA_FS is not set
# CONFIG_AFS_FS is not set
+# CONFIG_9P_FS is not set
#
# Partition Types
@@ -813,6 +1020,7 @@ CONFIG_MSDOS_PARTITION=y
# CONFIG_SGI_PARTITION is not set
# CONFIG_ULTRIX_PARTITION is not set
# CONFIG_SUN_PARTITION is not set
+# CONFIG_KARMA_PARTITION is not set
# CONFIG_EFI_PARTITION is not set
#
@@ -868,9 +1076,14 @@ CONFIG_OPROFILE=m
#
# Kernel hacking
#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_MUST_CHECK=y
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_UNUSED_SYMBOLS is not set
# CONFIG_DEBUG_KERNEL is not set
-CONFIG_DEBUG_PREEMPT=y
-# CONFIG_FRAME_POINTER is not set
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_DEBUG_BUGVERBOSE is not set
+# CONFIG_DEBUG_FS is not set
CONFIG_SH_STANDARD_BIOS=y
# CONFIG_EARLY_SCIF_CONSOLE is not set
# CONFIG_EARLY_PRINTK is not set
@@ -886,6 +1099,10 @@ CONFIG_SH_STANDARD_BIOS=y
# Cryptographic options
#
CONFIG_CRYPTO=y
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_BLKCIPHER=m
+CONFIG_CRYPTO_HASH=y
+CONFIG_CRYPTO_MANAGER=m
CONFIG_CRYPTO_HMAC=y
# CONFIG_CRYPTO_NULL is not set
# CONFIG_CRYPTO_MD4 is not set
@@ -894,6 +1111,9 @@ CONFIG_CRYPTO_SHA1=y
# CONFIG_CRYPTO_SHA256 is not set
# CONFIG_CRYPTO_SHA512 is not set
# CONFIG_CRYPTO_WP512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
+CONFIG_CRYPTO_ECB=m
+CONFIG_CRYPTO_CBC=m
CONFIG_CRYPTO_DES=y
# CONFIG_CRYPTO_BLOWFISH is not set
# CONFIG_CRYPTO_TWOFISH is not set
@@ -918,7 +1138,9 @@ CONFIG_CRYPTO_DEFLATE=y
# Library routines
#
CONFIG_CRC_CCITT=y
+# CONFIG_CRC16 is not set
CONFIG_CRC32=y
# CONFIG_LIBCRC32C is not set
CONFIG_ZLIB_INFLATE=y
CONFIG_ZLIB_DEFLATE=y
+CONFIG_PLIST=y
diff --git a/arch/sh/configs/sh7710voipgw_defconfig b/arch/sh/configs/sh7710voipgw_defconfig
index ec9a3034daa5..9380c321169a 100644
--- a/arch/sh/configs/sh7710voipgw_defconfig
+++ b/arch/sh/configs/sh7710voipgw_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.17
-# Mon Aug 7 17:07:06 2006
+# Linux kernel version: 2.6.18
+# Tue Oct 3 12:48:56 2006
#
CONFIG_SUPERH=y
CONFIG_RWSEM_GENERIC_SPINLOCK=y
@@ -10,6 +10,7 @@ CONFIG_GENERIC_HWEIGHT=y
CONFIG_GENERIC_HARDIRQS=y
CONFIG_GENERIC_IRQ_PROBE=y
CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
#
# Code maturity level options
@@ -25,16 +26,20 @@ CONFIG_LOCALVERSION=""
CONFIG_LOCALVERSION_AUTO=y
# CONFIG_SWAP is not set
CONFIG_SYSVIPC=y
+# CONFIG_IPC_NS is not set
CONFIG_POSIX_MQUEUE=y
# CONFIG_BSD_PROCESS_ACCT is not set
-CONFIG_SYSCTL=y
+# CONFIG_TASKSTATS is not set
+# CONFIG_UTS_NS is not set
# CONFIG_AUDIT is not set
# CONFIG_IKCONFIG is not set
# CONFIG_RELAY is not set
CONFIG_INITRAMFS_SOURCE=""
-CONFIG_UID16=y
CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
CONFIG_EMBEDDED=y
+CONFIG_UID16=y
+# CONFIG_SYSCTL_SYSCALL is not set
CONFIG_KALLSYMS=y
# CONFIG_KALLSYMS_EXTRA_PASS is not set
CONFIG_HOTPLUG=y
@@ -46,10 +51,10 @@ CONFIG_BASE_FULL=y
# CONFIG_EPOLL is not set
# CONFIG_SHMEM is not set
CONFIG_SLAB=y
+CONFIG_VM_EVENT_COUNTERS=y
CONFIG_TINY_SHMEM=y
CONFIG_BASE_SMALL=0
# CONFIG_SLOB is not set
-CONFIG_OBSOLETE_INTERMODULE=y
#
# Loadable module support
@@ -64,6 +69,7 @@ CONFIG_MODULE_FORCE_UNLOAD=y
#
# Block layer
#
+CONFIG_BLOCK=y
# CONFIG_LBD is not set
# CONFIG_BLK_DEV_IO_TRACE is not set
# CONFIG_LSF is not set
@@ -87,6 +93,7 @@ CONFIG_DEFAULT_IOSCHED="deadline"
# CONFIG_SH_SOLUTION_ENGINE is not set
# CONFIG_SH_7751_SOLUTION_ENGINE is not set
# CONFIG_SH_7300_SOLUTION_ENGINE is not set
+# CONFIG_SH_7343_SOLUTION_ENGINE is not set
# CONFIG_SH_73180_SOLUTION_ENGINE is not set
# CONFIG_SH_7751_SYSTEMH is not set
# CONFIG_SH_HP6XX is not set
@@ -150,17 +157,23 @@ CONFIG_CPU_SUBTYPE_SH7710=y
#
# SH-4A Processor Support
#
-# CONFIG_CPU_SUBTYPE_SH73180 is not set
# CONFIG_CPU_SUBTYPE_SH7770 is not set
# CONFIG_CPU_SUBTYPE_SH7780 is not set
#
+# SH4AL-DSP Processor Support
+#
+# CONFIG_CPU_SUBTYPE_SH73180 is not set
+# CONFIG_CPU_SUBTYPE_SH7343 is not set
+
+#
# Memory management options
#
CONFIG_MMU=y
CONFIG_PAGE_OFFSET=0x80000000
CONFIG_MEMORY_START=0x0c000000
CONFIG_MEMORY_SIZE=0x00800000
+CONFIG_VSYSCALL=y
CONFIG_SELECT_MEMORY_MODEL=y
CONFIG_FLATMEM_MANUAL=y
# CONFIG_DISCONTIGMEM_MANUAL is not set
@@ -169,6 +182,7 @@ CONFIG_FLATMEM=y
CONFIG_FLAT_NODE_MEM_MAP=y
# CONFIG_SPARSEMEM_STATIC is not set
CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_RESOURCES_64BIT is not set
#
# Cache configuration
@@ -216,10 +230,10 @@ CONFIG_HZ_250=y
# CONFIG_HZ_1000 is not set
CONFIG_HZ=250
# CONFIG_KEXEC is not set
-# CONFIG_PREEMPT is not set
# CONFIG_SMP is not set
CONFIG_PREEMPT_NONE=y
# CONFIG_PREEMPT_VOLUNTARY is not set
+# CONFIG_PREEMPT is not set
#
# Boot options
@@ -267,6 +281,9 @@ CONFIG_NET=y
CONFIG_PACKET=y
# CONFIG_PACKET_MMAP is not set
CONFIG_UNIX=y
+CONFIG_XFRM=y
+# CONFIG_XFRM_USER is not set
+# CONFIG_XFRM_SUB_POLICY is not set
# CONFIG_NET_KEY is not set
CONFIG_INET=y
# CONFIG_IP_MULTICAST is not set
@@ -282,9 +299,12 @@ CONFIG_SYN_COOKIES=y
# CONFIG_INET_IPCOMP is not set
# CONFIG_INET_XFRM_TUNNEL is not set
# CONFIG_INET_TUNNEL is not set
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
# CONFIG_INET_DIAG is not set
# CONFIG_TCP_CONG_ADVANCED is not set
-CONFIG_TCP_CONG_BIC=y
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
#
# IP: Virtual Server Configuration
@@ -293,6 +313,7 @@ CONFIG_TCP_CONG_BIC=y
# CONFIG_IPV6 is not set
# CONFIG_INET6_XFRM_TUNNEL is not set
# CONFIG_INET6_TUNNEL is not set
+# CONFIG_NETWORK_SECMARK is not set
CONFIG_NETFILTER=y
# CONFIG_NETFILTER_DEBUG is not set
@@ -317,6 +338,7 @@ CONFIG_IP_NF_FTP=m
# CONFIG_IP_NF_AMANDA is not set
CONFIG_IP_NF_PPTP=m
# CONFIG_IP_NF_H323 is not set
+# CONFIG_IP_NF_SIP is not set
# CONFIG_IP_NF_QUEUE is not set
#
@@ -342,7 +364,6 @@ CONFIG_IP_NF_PPTP=m
# CONFIG_ATALK is not set
# CONFIG_X25 is not set
# CONFIG_LAPB is not set
-# CONFIG_NET_DIVERT is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
@@ -409,6 +430,7 @@ CONFIG_NET_ESTIMATOR=y
CONFIG_STANDALONE=y
CONFIG_PREVENT_FIRMWARE_BUILD=y
CONFIG_FW_LOADER=y
+# CONFIG_SYS_HYPERVISOR is not set
#
# Connector - unified userspace <-> kernelspace linker
@@ -434,6 +456,7 @@ CONFIG_MTD_BLOCK=y
# CONFIG_NFTL is not set
# CONFIG_INFTL is not set
# CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
#
# RAM/ROM/Flash chip drivers
@@ -466,8 +489,6 @@ CONFIG_MTD_RAM=y
#
# CONFIG_MTD_COMPLEX_MAPPINGS is not set
# CONFIG_MTD_PHYSMAP is not set
-# CONFIG_MTD_SOLUTIONENGINE is not set
-CONFIG_MTD_SH7710VOIPGW=y
# CONFIG_MTD_PLATRAM is not set
#
@@ -525,6 +546,12 @@ CONFIG_MTD_SH7710VOIPGW=y
#
# CONFIG_RAID_ATTRS is not set
# CONFIG_SCSI is not set
+# CONFIG_SCSI_NETLINK is not set
+
+#
+# Serial ATA (prod) and Parallel ATA (experimental) drivers
+#
+# CONFIG_ATA is not set
#
# Multi-device support (RAID and LVM)
@@ -565,7 +592,6 @@ CONFIG_NET_ETHERNET=y
# CONFIG_MII is not set
# CONFIG_STNIC is not set
# CONFIG_SMC91X is not set
-# CONFIG_NE2000 is not set
#
# Ethernet (1000 Mbit)
@@ -610,6 +636,7 @@ CONFIG_PHONE=y
# Input device support
#
CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
#
# Userland interfaces
@@ -667,7 +694,7 @@ CONFIG_LEGACY_PTY_COUNT=256
# Watchdog Cards
#
# CONFIG_WATCHDOG is not set
-# CONFIG_RTC is not set
+CONFIG_HW_RANDOM=y
# CONFIG_GEN_RTC is not set
# CONFIG_DTLK is not set
# CONFIG_R3964 is not set
@@ -697,7 +724,6 @@ CONFIG_LEGACY_PTY_COUNT=256
#
# Dallas's 1-wire bus
#
-# CONFIG_W1 is not set
#
# Hardware Monitoring support
@@ -723,7 +749,9 @@ CONFIG_VIDEO_V4L2=y
#
# Graphics support
#
+CONFIG_FIRMWARE_EDID=y
# CONFIG_FB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
#
# Sound
@@ -778,6 +806,19 @@ CONFIG_VIDEO_V4L2=y
# CONFIG_RTC_CLASS is not set
#
+# DMA Engine support
+#
+# CONFIG_DMA_ENGINE is not set
+
+#
+# DMA Clients
+#
+
+#
+# DMA Devices
+#
+
+#
# File systems
#
# CONFIG_EXT2_FS is not set
@@ -814,8 +855,10 @@ CONFIG_VIDEO_V4L2=y
#
CONFIG_PROC_FS=y
# CONFIG_PROC_KCORE is not set
+CONFIG_PROC_SYSCTL=y
CONFIG_SYSFS=y
CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
# CONFIG_HUGETLBFS is not set
# CONFIG_HUGETLB_PAGE is not set
CONFIG_RAMFS=y
@@ -836,6 +879,7 @@ CONFIG_JFFS2_FS=y
CONFIG_JFFS2_FS_DEBUG=0
CONFIG_JFFS2_FS_WRITEBUFFER=y
# CONFIG_JFFS2_SUMMARY is not set
+# CONFIG_JFFS2_FS_XATTR is not set
# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
CONFIG_JFFS2_ZLIB=y
CONFIG_JFFS2_RTIME=y
@@ -879,7 +923,9 @@ CONFIG_MSDOS_PARTITION=y
# Kernel hacking
#
# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_MUST_CHECK=y
# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_UNUSED_SYMBOLS is not set
# CONFIG_DEBUG_KERNEL is not set
CONFIG_LOG_BUF_SHIFT=14
# CONFIG_DEBUG_BUGVERBOSE is not set
@@ -899,10 +945,6 @@ CONFIG_LOG_BUF_SHIFT=14
# CONFIG_CRYPTO is not set
#
-# Hardware crypto devices
-#
-
-#
# Library routines
#
# CONFIG_CRC_CCITT is not set
diff --git a/arch/sh/configs/shmin_defconfig b/arch/sh/configs/shmin_defconfig
index 382b3bd3963b..8800fefcbaf0 100644
--- a/arch/sh/configs/shmin_defconfig
+++ b/arch/sh/configs/shmin_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.17
-# Wed Aug 2 01:45:03 2006
+# Linux kernel version: 2.6.18
+# Tue Oct 3 12:52:49 2006
#
CONFIG_SUPERH=y
CONFIG_RWSEM_GENERIC_SPINLOCK=y
@@ -10,7 +10,7 @@ CONFIG_GENERIC_HWEIGHT=y
CONFIG_GENERIC_HARDIRQS=y
CONFIG_GENERIC_IRQ_PROBE=y
CONFIG_GENERIC_CALIBRATE_DELAY=y
-CONFIG_PTRACE=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
#
# Code maturity level options
@@ -28,14 +28,17 @@ CONFIG_LOCALVERSION_AUTO=y
# CONFIG_SYSVIPC is not set
# CONFIG_POSIX_MQUEUE is not set
# CONFIG_BSD_PROCESS_ACCT is not set
-# CONFIG_SYSCTL is not set
+# CONFIG_TASKSTATS is not set
+# CONFIG_UTS_NS is not set
# CONFIG_AUDIT is not set
# CONFIG_IKCONFIG is not set
# CONFIG_RELAY is not set
CONFIG_INITRAMFS_SOURCE=""
-# CONFIG_UID16 is not set
CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
CONFIG_EMBEDDED=y
+# CONFIG_UID16 is not set
+# CONFIG_SYSCTL_SYSCALL is not set
# CONFIG_KALLSYMS is not set
# CONFIG_HOTPLUG is not set
CONFIG_PRINTK=y
@@ -46,10 +49,10 @@ CONFIG_PRINTK=y
# CONFIG_EPOLL is not set
# CONFIG_SHMEM is not set
# CONFIG_SLAB is not set
+CONFIG_VM_EVENT_COUNTERS=y
CONFIG_TINY_SHMEM=y
CONFIG_BASE_SMALL=1
CONFIG_SLOB=y
-CONFIG_OBSOLETE_INTERMODULE=y
#
# Loadable module support
@@ -59,6 +62,7 @@ CONFIG_OBSOLETE_INTERMODULE=y
#
# Block layer
#
+CONFIG_BLOCK=y
# CONFIG_LBD is not set
# CONFIG_LSF is not set
@@ -79,27 +83,21 @@ CONFIG_DEFAULT_IOSCHED="noop"
# System type
#
# CONFIG_SH_SOLUTION_ENGINE is not set
-# CONFIG_SH_7709_SOLUTION_ENGINE is not set
# CONFIG_SH_7751_SOLUTION_ENGINE is not set
# CONFIG_SH_7300_SOLUTION_ENGINE is not set
+# CONFIG_SH_7343_SOLUTION_ENGINE is not set
# CONFIG_SH_73180_SOLUTION_ENGINE is not set
# CONFIG_SH_7751_SYSTEMH is not set
-# CONFIG_SH_STB1_HARP is not set
-# CONFIG_SH_STB1_OVERDRIVE is not set
# CONFIG_SH_HP6XX is not set
-# CONFIG_SH_CQREEK is not set
-# CONFIG_SH_DMIDA is not set
# CONFIG_SH_EC3104 is not set
# CONFIG_SH_SATURN is not set
# CONFIG_SH_DREAMCAST is not set
-# CONFIG_SH_CAT68701 is not set
# CONFIG_SH_BIGSUR is not set
-# CONFIG_SH_SH2000 is not set
-# CONFIG_SH_ADX is not set
# CONFIG_SH_MPC1211 is not set
# CONFIG_SH_SH03 is not set
# CONFIG_SH_SECUREEDGE5410 is not set
# CONFIG_SH_HS7751RVOIP is not set
+# CONFIG_SH_7710VOIPGW is not set
# CONFIG_SH_RTS7751R2D is not set
# CONFIG_SH_R7780RP is not set
# CONFIG_SH_EDOSK7705 is not set
@@ -128,6 +126,7 @@ CONFIG_CPU_SUBTYPE_SH7706=y
# CONFIG_CPU_SUBTYPE_SH7707 is not set
# CONFIG_CPU_SUBTYPE_SH7708 is not set
# CONFIG_CPU_SUBTYPE_SH7709 is not set
+# CONFIG_CPU_SUBTYPE_SH7710 is not set
#
# SH-4 Processor Support
@@ -150,17 +149,23 @@ CONFIG_CPU_SUBTYPE_SH7706=y
#
# SH-4A Processor Support
#
-# CONFIG_CPU_SUBTYPE_SH73180 is not set
# CONFIG_CPU_SUBTYPE_SH7770 is not set
# CONFIG_CPU_SUBTYPE_SH7780 is not set
#
+# SH4AL-DSP Processor Support
+#
+# CONFIG_CPU_SUBTYPE_SH73180 is not set
+# CONFIG_CPU_SUBTYPE_SH7343 is not set
+
+#
# Memory management options
#
CONFIG_MMU=y
CONFIG_PAGE_OFFSET=0x80000000
CONFIG_MEMORY_START=0x0c000000
CONFIG_MEMORY_SIZE=0x00800000
+CONFIG_VSYSCALL=y
CONFIG_SELECT_MEMORY_MODEL=y
CONFIG_FLATMEM_MANUAL=y
# CONFIG_DISCONTIGMEM_MANUAL is not set
@@ -169,6 +174,7 @@ CONFIG_FLATMEM=y
CONFIG_FLAT_NODE_MEM_MAP=y
# CONFIG_SPARSEMEM_STATIC is not set
CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_RESOURCES_64BIT is not set
#
# Cache configuration
@@ -211,9 +217,15 @@ CONFIG_SH_PCLK_FREQ=32000000
#
# Kernel features
#
+# CONFIG_HZ_100 is not set
+CONFIG_HZ_250=y
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=250
# CONFIG_KEXEC is not set
-# CONFIG_PREEMPT is not set
# CONFIG_SMP is not set
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
+# CONFIG_PREEMPT is not set
#
# Boot options
@@ -232,7 +244,6 @@ CONFIG_CMDLINE="console=ttySC1,115200 root=1f01 mtdparts=phys_mapped_flash:64k(f
#
# PCCARD (PCMCIA/CardBus) support
#
-# CONFIG_PCCARD is not set
#
# PCI Hotplug Support
@@ -261,6 +272,9 @@ CONFIG_NET=y
# CONFIG_NETDEBUG is not set
# CONFIG_PACKET is not set
CONFIG_UNIX=y
+CONFIG_XFRM=y
+# CONFIG_XFRM_USER is not set
+# CONFIG_XFRM_SUB_POLICY is not set
# CONFIG_NET_KEY is not set
CONFIG_INET=y
# CONFIG_IP_MULTICAST is not set
@@ -279,13 +293,17 @@ CONFIG_IP_PNP=y
# CONFIG_INET_IPCOMP is not set
# CONFIG_INET_XFRM_TUNNEL is not set
# CONFIG_INET_TUNNEL is not set
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
CONFIG_INET_DIAG=y
CONFIG_INET_TCP_DIAG=y
# CONFIG_TCP_CONG_ADVANCED is not set
-CONFIG_TCP_CONG_BIC=y
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_IPV6 is not set
# CONFIG_INET6_XFRM_TUNNEL is not set
# CONFIG_INET6_TUNNEL is not set
+# CONFIG_NETWORK_SECMARK is not set
# CONFIG_NETFILTER is not set
#
@@ -311,7 +329,6 @@ CONFIG_TCP_CONG_BIC=y
# CONFIG_ATALK is not set
# CONFIG_X25 is not set
# CONFIG_LAPB is not set
-# CONFIG_NET_DIVERT is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
@@ -338,7 +355,7 @@ CONFIG_TCP_CONG_BIC=y
#
CONFIG_STANDALONE=y
CONFIG_PREVENT_FIRMWARE_BUILD=y
-# CONFIG_FW_LOADER is not set
+# CONFIG_SYS_HYPERVISOR is not set
#
# Connector - unified userspace <-> kernelspace linker
@@ -364,11 +381,12 @@ CONFIG_MTD_BLOCK=y
# CONFIG_NFTL is not set
# CONFIG_INFTL is not set
# CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
#
# RAM/ROM/Flash chip drivers
#
-# CONFIG_MTD_CFI is not set
+CONFIG_MTD_CFI=y
CONFIG_MTD_JEDECPROBE=y
CONFIG_MTD_GEN_PROBE=y
# CONFIG_MTD_CFI_ADV_OPTIONS is not set
@@ -457,6 +475,12 @@ CONFIG_BLK_DEV_LOOP=y
#
# CONFIG_RAID_ATTRS is not set
# CONFIG_SCSI is not set
+# CONFIG_SCSI_NETLINK is not set
+
+#
+# Serial ATA (prod) and Parallel ATA (experimental) drivers
+#
+# CONFIG_ATA is not set
#
# Multi-device support (RAID and LVM)
@@ -497,7 +521,6 @@ CONFIG_NET_ETHERNET=y
# CONFIG_MII is not set
# CONFIG_STNIC is not set
# CONFIG_SMC91X is not set
-CONFIG_NE2000=y
#
# Ethernet (1000 Mbit)
@@ -580,7 +603,7 @@ CONFIG_LEGACY_PTY_COUNT=256
# Watchdog Cards
#
# CONFIG_WATCHDOG is not set
-# CONFIG_RTC is not set
+CONFIG_HW_RANDOM=y
# CONFIG_GEN_RTC is not set
# CONFIG_DTLK is not set
# CONFIG_R3964 is not set
@@ -610,7 +633,6 @@ CONFIG_LEGACY_PTY_COUNT=256
#
# Dallas's 1-wire bus
#
-# CONFIG_W1 is not set
#
# Hardware Monitoring support
@@ -636,6 +658,7 @@ CONFIG_VIDEO_V4L2=y
#
# Graphics support
#
+CONFIG_FIRMWARE_EDID=y
# CONFIG_FB is not set
#
@@ -691,6 +714,19 @@ CONFIG_VIDEO_V4L2=y
# CONFIG_RTC_CLASS is not set
#
+# DMA Engine support
+#
+# CONFIG_DMA_ENGINE is not set
+
+#
+# DMA Clients
+#
+
+#
+# DMA Devices
+#
+
+#
# File systems
#
# CONFIG_EXT2_FS is not set
@@ -699,7 +735,6 @@ CONFIG_VIDEO_V4L2=y
# CONFIG_JFS_FS is not set
# CONFIG_FS_POSIX_ACL is not set
# CONFIG_XFS_FS is not set
-# CONFIG_OCFS2_FS is not set
# CONFIG_MINIX_FS is not set
# CONFIG_ROMFS_FS is not set
# CONFIG_INOTIFY is not set
@@ -727,8 +762,10 @@ CONFIG_VIDEO_V4L2=y
#
CONFIG_PROC_FS=y
# CONFIG_PROC_KCORE is not set
+CONFIG_PROC_SYSCTL=y
# CONFIG_SYSFS is not set
CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
# CONFIG_HUGETLBFS is not set
# CONFIG_HUGETLB_PAGE is not set
CONFIG_RAMFS=y
@@ -795,7 +832,9 @@ CONFIG_MSDOS_PARTITION=y
# Kernel hacking
#
# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_MUST_CHECK=y
# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_UNUSED_SYMBOLS is not set
# CONFIG_DEBUG_KERNEL is not set
CONFIG_LOG_BUF_SHIFT=14
# CONFIG_UNWIND_INFO is not set
@@ -814,10 +853,6 @@ CONFIG_EARLY_PRINTK=y
# CONFIG_CRYPTO is not set
#
-# Hardware crypto devices
-#
-
-#
# Library routines
#
# CONFIG_CRC_CCITT is not set
diff --git a/arch/sh/configs/snapgear_defconfig b/arch/sh/configs/snapgear_defconfig
index 69cf02a24761..98503f16f3f5 100644
--- a/arch/sh/configs/snapgear_defconfig
+++ b/arch/sh/configs/snapgear_defconfig
@@ -1,48 +1,60 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.11-sh
-# Wed Mar 2 15:09:51 2005
+# Linux kernel version: 2.6.18
+# Tue Oct 3 12:55:47 2006
#
CONFIG_SUPERH=y
-CONFIG_UID16=y
CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+CONFIG_GENERIC_HWEIGHT=y
CONFIG_GENERIC_HARDIRQS=y
CONFIG_GENERIC_IRQ_PROBE=y
CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
#
# Code maturity level options
#
CONFIG_EXPERIMENTAL=y
-CONFIG_CLEAN_COMPILE=y
CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
#
# General setup
#
CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
CONFIG_SWAP=y
# CONFIG_SYSVIPC is not set
# CONFIG_POSIX_MQUEUE is not set
# CONFIG_BSD_PROCESS_ACCT is not set
-# CONFIG_SYSCTL is not set
+# CONFIG_TASKSTATS is not set
+# CONFIG_UTS_NS is not set
# CONFIG_AUDIT is not set
-CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_HOTPLUG is not set
-CONFIG_KOBJECT_UEVENT=y
# CONFIG_IKCONFIG is not set
-# CONFIG_EMBEDDED is not set
+# CONFIG_RELAY is not set
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
+CONFIG_EMBEDDED=y
+CONFIG_UID16=y
+# CONFIG_SYSCTL_SYSCALL is not set
CONFIG_KALLSYMS=y
# CONFIG_KALLSYMS_EXTRA_PASS is not set
+# CONFIG_HOTPLUG is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
CONFIG_EPOLL=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
CONFIG_SHMEM=y
-CONFIG_CC_ALIGN_FUNCTIONS=0
-CONFIG_CC_ALIGN_LABELS=0
-CONFIG_CC_ALIGN_LOOPS=0
-CONFIG_CC_ALIGN_JUMPS=0
+CONFIG_SLAB=y
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_RT_MUTEXES=y
# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+# CONFIG_SLOB is not set
#
# Loadable module support
@@ -50,70 +62,145 @@ CONFIG_CC_ALIGN_JUMPS=0
# CONFIG_MODULES is not set
#
+# Block layer
+#
+CONFIG_BLOCK=y
+# CONFIG_LBD is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_LSF is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+CONFIG_DEFAULT_AS=y
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="anticipatory"
+
+#
# System type
#
# CONFIG_SH_SOLUTION_ENGINE is not set
# CONFIG_SH_7751_SOLUTION_ENGINE is not set
# CONFIG_SH_7300_SOLUTION_ENGINE is not set
+# CONFIG_SH_7343_SOLUTION_ENGINE is not set
# CONFIG_SH_73180_SOLUTION_ENGINE is not set
# CONFIG_SH_7751_SYSTEMH is not set
-# CONFIG_SH_STB1_HARP is not set
-# CONFIG_SH_STB1_OVERDRIVE is not set
-# CONFIG_SH_HP620 is not set
-# CONFIG_SH_HP680 is not set
-# CONFIG_SH_HP690 is not set
-# CONFIG_SH_CQREEK is not set
-# CONFIG_SH_DMIDA is not set
+# CONFIG_SH_HP6XX is not set
# CONFIG_SH_EC3104 is not set
# CONFIG_SH_SATURN is not set
# CONFIG_SH_DREAMCAST is not set
-# CONFIG_SH_CAT68701 is not set
# CONFIG_SH_BIGSUR is not set
-# CONFIG_SH_SH2000 is not set
-# CONFIG_SH_ADX is not set
# CONFIG_SH_MPC1211 is not set
# CONFIG_SH_SH03 is not set
CONFIG_SH_SECUREEDGE5410=y
# CONFIG_SH_HS7751RVOIP is not set
+# CONFIG_SH_7710VOIPGW is not set
# CONFIG_SH_RTS7751R2D is not set
+# CONFIG_SH_R7780RP is not set
# CONFIG_SH_EDOSK7705 is not set
# CONFIG_SH_SH4202_MICRODEV is not set
+# CONFIG_SH_LANDISK is not set
+# CONFIG_SH_TITAN is not set
+# CONFIG_SH_SHMIN is not set
# CONFIG_SH_UNKNOWN is not set
-# CONFIG_CPU_SH2 is not set
-# CONFIG_CPU_SH3 is not set
+
+#
+# Processor selection
+#
CONFIG_CPU_SH4=y
+
+#
+# SH-2 Processor Support
+#
# CONFIG_CPU_SUBTYPE_SH7604 is not set
+
+#
+# SH-3 Processor Support
+#
# CONFIG_CPU_SUBTYPE_SH7300 is not set
# CONFIG_CPU_SUBTYPE_SH7705 is not set
+# CONFIG_CPU_SUBTYPE_SH7706 is not set
# CONFIG_CPU_SUBTYPE_SH7707 is not set
# CONFIG_CPU_SUBTYPE_SH7708 is not set
# CONFIG_CPU_SUBTYPE_SH7709 is not set
+# CONFIG_CPU_SUBTYPE_SH7710 is not set
+
+#
+# SH-4 Processor Support
+#
# CONFIG_CPU_SUBTYPE_SH7750 is not set
+# CONFIG_CPU_SUBTYPE_SH7091 is not set
+# CONFIG_CPU_SUBTYPE_SH7750R is not set
+# CONFIG_CPU_SUBTYPE_SH7750S is not set
CONFIG_CPU_SUBTYPE_SH7751=y
+CONFIG_CPU_SUBTYPE_SH7751R=y
# CONFIG_CPU_SUBTYPE_SH7760 is not set
-# CONFIG_CPU_SUBTYPE_SH73180 is not set
+# CONFIG_CPU_SUBTYPE_SH4_202 is not set
+
+#
+# ST40 Processor Support
+#
# CONFIG_CPU_SUBTYPE_ST40STB1 is not set
# CONFIG_CPU_SUBTYPE_ST40GX1 is not set
-# CONFIG_CPU_SUBTYPE_SH4_202 is not set
+
+#
+# SH-4A Processor Support
+#
+# CONFIG_CPU_SUBTYPE_SH7770 is not set
+# CONFIG_CPU_SUBTYPE_SH7780 is not set
+
+#
+# SH4AL-DSP Processor Support
+#
+# CONFIG_CPU_SUBTYPE_SH73180 is not set
+# CONFIG_CPU_SUBTYPE_SH7343 is not set
+
+#
+# Memory management options
+#
CONFIG_MMU=y
-# CONFIG_CMDLINE_BOOL is not set
+CONFIG_PAGE_OFFSET=0x80000000
CONFIG_MEMORY_START=0x08000000
CONFIG_MEMORY_SIZE=0x01000000
-CONFIG_MEMORY_SET=y
-# CONFIG_MEMORY_OVERRIDE is not set
-CONFIG_SH_RTC=y
-CONFIG_SH_FPU=y
-CONFIG_ZERO_PAGE_OFFSET=0x00001000
-CONFIG_BOOT_LINK_OFFSET=0x00800000
-CONFIG_CPU_LITTLE_ENDIAN=y
-# CONFIG_PREEMPT is not set
-# CONFIG_UBC_WAKEUP is not set
+CONFIG_VSYSCALL=y
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+# CONFIG_SPARSEMEM_STATIC is not set
+CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_RESOURCES_64BIT is not set
+
+#
+# Cache configuration
+#
+# CONFIG_SH_DIRECT_MAPPED is not set
# CONFIG_SH_WRITETHROUGH is not set
# CONFIG_SH_OCRAM is not set
+
+#
+# Processor features
+#
+CONFIG_CPU_LITTLE_ENDIAN=y
+CONFIG_SH_FPU=y
+# CONFIG_SH_DSP is not set
# CONFIG_SH_STORE_QUEUES is not set
-# CONFIG_SMP is not set
-CONFIG_SH_PCLK_CALC=y
-CONFIG_SH_PCLK_FREQ=60013568
+CONFIG_CPU_HAS_INTEVT=y
+CONFIG_CPU_HAS_SR_RB=y
+
+#
+# Timer support
+#
+CONFIG_SH_TMU=y
+CONFIG_SH_PCLK_FREQ=60000000
#
# CPU Frequency scaling
@@ -133,28 +220,42 @@ CONFIG_NR_ONCHIP_DMA_CHANNELS=4
# CONFIG_HD6446X_SERIES is not set
#
-# Bus options (PCI, PCMCIA, EISA, MCA, ISA)
+# Kernel features
+#
+# CONFIG_HZ_100 is not set
+CONFIG_HZ_250=y
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=250
+# CONFIG_KEXEC is not set
+# CONFIG_SMP is not set
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
+# CONFIG_PREEMPT is not set
+
+#
+# Boot options
+#
+CONFIG_ZERO_PAGE_OFFSET=0x00001000
+CONFIG_BOOT_LINK_OFFSET=0x00800000
+# CONFIG_UBC_WAKEUP is not set
+# CONFIG_CMDLINE_BOOL is not set
+
+#
+# Bus options
#
CONFIG_PCI=y
# CONFIG_SH_PCIDMA_NONCOHERENT is not set
CONFIG_PCI_AUTO=y
CONFIG_PCI_AUTO_UPDATE_RESOURCES=y
-# CONFIG_PCI_LEGACY_PROC is not set
-CONFIG_PCI_NAMES=y
+# CONFIG_PCI_MULTITHREAD_PROBE is not set
#
# PCCARD (PCMCIA/CardBus) support
#
-# CONFIG_PCCARD is not set
-
-#
-# PC-card bridges
-#
#
# PCI Hotplug Support
#
-# CONFIG_HOTPLUG_PCI is not set
#
# Executable file formats
@@ -164,9 +265,94 @@ CONFIG_BINFMT_ELF=y
# CONFIG_BINFMT_MISC is not set
#
-# SH initrd options
+# Power management options (EXPERIMENTAL)
+#
+# CONFIG_PM is not set
+
+#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+# CONFIG_NETDEBUG is not set
+# CONFIG_PACKET is not set
+# CONFIG_UNIX is not set
+CONFIG_XFRM=y
+# CONFIG_XFRM_USER is not set
+# CONFIG_XFRM_SUB_POLICY is not set
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+# CONFIG_IP_PNP_BOOTP is not set
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+# CONFIG_INET_TUNNEL is not set
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_IPV6 is not set
+# CONFIG_INET6_XFRM_TUNNEL is not set
+# CONFIG_INET6_TUNNEL is not set
+# CONFIG_NETWORK_SECMARK is not set
+# CONFIG_NETFILTER is not set
+
+#
+# DCCP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_DCCP is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP is not set
+
+#
+# TIPC Configuration (EXPERIMENTAL)
#
-# CONFIG_EMBEDDED_RAMDISK is not set
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_IEEE80211 is not set
#
# Device Drivers
@@ -177,7 +363,12 @@ CONFIG_BINFMT_ELF=y
#
CONFIG_STANDALONE=y
CONFIG_PREVENT_FIRMWARE_BUILD=y
-# CONFIG_FW_LOADER is not set
+# CONFIG_SYS_HYPERVISOR is not set
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
+# CONFIG_CONNECTOR is not set
#
# Memory Technology Devices (MTD)
@@ -196,7 +387,6 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
#
# Block devices
#
-# CONFIG_BLK_DEV_FD is not set
# CONFIG_BLK_CPQ_DA is not set
# CONFIG_BLK_CPQ_CISS_DA is not set
# CONFIG_BLK_DEV_DAC960 is not set
@@ -208,18 +398,9 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
CONFIG_BLK_DEV_RAM=y
CONFIG_BLK_DEV_RAM_COUNT=16
CONFIG_BLK_DEV_RAM_SIZE=4096
+CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
CONFIG_BLK_DEV_INITRD=y
-CONFIG_INITRAMFS_SOURCE=""
-# CONFIG_LBD is not set
# CONFIG_CDROM_PKTCDVD is not set
-
-#
-# IO Schedulers
-#
-CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
-CONFIG_IOSCHED_DEADLINE=y
-CONFIG_IOSCHED_CFQ=y
# CONFIG_ATA_OVER_ETH is not set
#
@@ -230,7 +411,14 @@ CONFIG_IOSCHED_CFQ=y
#
# SCSI device support
#
+# CONFIG_RAID_ATTRS is not set
# CONFIG_SCSI is not set
+# CONFIG_SCSI_NETLINK is not set
+
+#
+# Serial ATA (prod) and Parallel ATA (experimental) drivers
+#
+# CONFIG_ATA is not set
#
# Multi-device support (RAID and LVM)
@@ -240,6 +428,7 @@ CONFIG_IOSCHED_CFQ=y
#
# Fusion MPT device support
#
+# CONFIG_FUSION is not set
#
# IEEE 1394 (FireWire) support
@@ -252,69 +441,8 @@ CONFIG_IOSCHED_CFQ=y
# CONFIG_I2O is not set
#
-# Networking support
-#
-CONFIG_NET=y
-
-#
-# Networking options
-#
-# CONFIG_PACKET is not set
-# CONFIG_NETLINK_DEV is not set
-# CONFIG_UNIX is not set
-# CONFIG_NET_KEY is not set
-CONFIG_INET=y
-# CONFIG_IP_MULTICAST is not set
-# CONFIG_IP_ADVANCED_ROUTER is not set
-CONFIG_IP_PNP=y
-CONFIG_IP_PNP_DHCP=y
-# CONFIG_IP_PNP_BOOTP is not set
-# CONFIG_IP_PNP_RARP is not set
-# CONFIG_NET_IPIP is not set
-# CONFIG_NET_IPGRE is not set
-# CONFIG_ARPD is not set
-# CONFIG_SYN_COOKIES is not set
-# CONFIG_INET_AH is not set
-# CONFIG_INET_ESP is not set
-# CONFIG_INET_IPCOMP is not set
-# CONFIG_INET_TUNNEL is not set
-CONFIG_IP_TCPDIAG=y
-# CONFIG_IP_TCPDIAG_IPV6 is not set
-# CONFIG_IPV6 is not set
-# CONFIG_NETFILTER is not set
-
-#
-# SCTP Configuration (EXPERIMENTAL)
+# Network device support
#
-# CONFIG_IP_SCTP is not set
-# CONFIG_ATM is not set
-# CONFIG_BRIDGE is not set
-# CONFIG_VLAN_8021Q is not set
-# CONFIG_DECNET is not set
-# CONFIG_LLC2 is not set
-# CONFIG_IPX is not set
-# CONFIG_ATALK is not set
-# CONFIG_X25 is not set
-# CONFIG_LAPB is not set
-# CONFIG_NET_DIVERT is not set
-# CONFIG_ECONET is not set
-# CONFIG_WAN_ROUTER is not set
-
-#
-# QoS and/or fair queueing
-#
-# CONFIG_NET_SCHED is not set
-# CONFIG_NET_CLS_ROUTE is not set
-
-#
-# Network testing
-#
-# CONFIG_NET_PKTGEN is not set
-# CONFIG_NETPOLL is not set
-# CONFIG_NET_POLL_CONTROLLER is not set
-# CONFIG_HAMRADIO is not set
-# CONFIG_IRDA is not set
-# CONFIG_BT is not set
CONFIG_NETDEVICES=y
# CONFIG_DUMMY is not set
# CONFIG_BONDING is not set
@@ -327,6 +455,11 @@ CONFIG_NETDEVICES=y
# CONFIG_ARCNET is not set
#
+# PHY device support
+#
+# CONFIG_PHYLIB is not set
+
+#
# Ethernet (10 or 100Mbit)
#
CONFIG_NET_ETHERNET=y
@@ -334,6 +467,7 @@ CONFIG_MII=y
# CONFIG_STNIC is not set
# CONFIG_HAPPYMEAL is not set
# CONFIG_SUNGEM is not set
+# CONFIG_CASSINI is not set
# CONFIG_NET_VENDOR_3COM is not set
# CONFIG_SMC91X is not set
@@ -376,15 +510,22 @@ CONFIG_8139TOO=y
# CONFIG_HAMACHI is not set
# CONFIG_YELLOWFIN is not set
# CONFIG_R8169 is not set
+# CONFIG_SIS190 is not set
+# CONFIG_SKGE is not set
+# CONFIG_SKY2 is not set
# CONFIG_SK98LIN is not set
# CONFIG_VIA_VELOCITY is not set
# CONFIG_TIGON3 is not set
+# CONFIG_BNX2 is not set
+# CONFIG_QLA3XXX is not set
#
# Ethernet (10000 Mbit)
#
+# CONFIG_CHELSIO_T1 is not set
# CONFIG_IXGB is not set
# CONFIG_S2IO is not set
+# CONFIG_MYRI10GE is not set
#
# Token Ring devices
@@ -406,6 +547,8 @@ CONFIG_8139TOO=y
# CONFIG_SLIP is not set
# CONFIG_SHAPER is not set
# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
#
# ISDN subsystem
@@ -421,6 +564,7 @@ CONFIG_8139TOO=y
# Input device support
#
CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
#
# Userland interfaces
@@ -435,18 +579,6 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
# CONFIG_INPUT_EVBUG is not set
#
-# Input I/O drivers
-#
-# CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
-CONFIG_SERIO=y
-CONFIG_SERIO_I8042=y
-CONFIG_SERIO_SERPORT=y
-# CONFIG_SERIO_CT82C710 is not set
-# CONFIG_SERIO_PCIPS2 is not set
-# CONFIG_SERIO_RAW is not set
-
-#
# Input Device Drivers
#
# CONFIG_INPUT_KEYBOARD is not set
@@ -456,11 +588,23 @@ CONFIG_SERIO_SERPORT=y
# CONFIG_INPUT_MISC is not set
#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+CONFIG_SERIO_I8042=y
+CONFIG_SERIO_SERPORT=y
+# CONFIG_SERIO_PCIPS2 is not set
+# CONFIG_SERIO_LIBPS2 is not set
+# CONFIG_SERIO_RAW is not set
+# CONFIG_GAMEPORT is not set
+
+#
# Character devices
#
CONFIG_VT=y
CONFIG_VT_CONSOLE=y
CONFIG_HW_CONSOLE=y
+# CONFIG_VT_HW_CONSOLE_BINDING is not set
# CONFIG_SERIAL_NONSTANDARD is not set
#
@@ -472,6 +616,7 @@ CONFIG_HW_CONSOLE=y
# Non-8250 serial port support
#
# CONFIG_SERIAL_SH_SCI is not set
+# CONFIG_SERIAL_JSM is not set
CONFIG_UNIX98_PTYS=y
CONFIG_LEGACY_PTYS=y
CONFIG_LEGACY_PTY_COUNT=256
@@ -485,7 +630,7 @@ CONFIG_LEGACY_PTY_COUNT=256
# Watchdog Cards
#
# CONFIG_WATCHDOG is not set
-# CONFIG_RTC is not set
+CONFIG_HW_RANDOM=y
# CONFIG_GEN_RTC is not set
# CONFIG_DTLK is not set
# CONFIG_R3964 is not set
@@ -498,14 +643,35 @@ CONFIG_LEGACY_PTY_COUNT=256
# CONFIG_RAW_DRIVER is not set
#
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
+# CONFIG_TELCLOCK is not set
+
+#
# I2C support
#
# CONFIG_I2C is not set
#
+# SPI support
+#
+# CONFIG_SPI is not set
+# CONFIG_SPI_MASTER is not set
+
+#
# Dallas's 1-wire bus
#
-# CONFIG_W1 is not set
+
+#
+# Hardware Monitoring support
+#
+CONFIG_HWMON=y
+# CONFIG_HWMON_VID is not set
+# CONFIG_SENSORS_ABITUGURU is not set
+# CONFIG_SENSORS_F71805F is not set
+# CONFIG_SENSORS_VT1211 is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
#
# Misc devices
@@ -515,6 +681,7 @@ CONFIG_LEGACY_PTY_COUNT=256
# Multimedia devices
#
# CONFIG_VIDEO_DEV is not set
+CONFIG_VIDEO_V4L2=y
#
# Digital Video Broadcasting Devices
@@ -524,13 +691,14 @@ CONFIG_LEGACY_PTY_COUNT=256
#
# Graphics support
#
+CONFIG_FIRMWARE_EDID=y
# CONFIG_FB is not set
#
# Console display driver support
#
-CONFIG_VGA_CONSOLE=y
CONFIG_DUMMY_CONSOLE=y
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
#
# Sound
@@ -540,12 +708,13 @@ CONFIG_DUMMY_CONSOLE=y
#
# USB support
#
-# CONFIG_USB is not set
CONFIG_USB_ARCH_HAS_HCD=y
CONFIG_USB_ARCH_HAS_OHCI=y
+CONFIG_USB_ARCH_HAS_EHCI=y
+# CONFIG_USB is not set
#
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
#
#
@@ -559,30 +728,66 @@ CONFIG_USB_ARCH_HAS_OHCI=y
# CONFIG_MMC is not set
#
+# LED devices
+#
+# CONFIG_NEW_LEDS is not set
+
+#
+# LED drivers
+#
+
+#
+# LED Triggers
+#
+
+#
# InfiniBand support
#
# CONFIG_INFINIBAND is not set
#
+# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
+#
+
+#
+# Real Time Clock
+#
+# CONFIG_RTC_CLASS is not set
+
+#
+# DMA Engine support
+#
+# CONFIG_DMA_ENGINE is not set
+
+#
+# DMA Clients
+#
+
+#
+# DMA Devices
+#
+
+#
# File systems
#
CONFIG_EXT2_FS=y
# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
# CONFIG_EXT3_FS is not set
-# CONFIG_JBD is not set
# CONFIG_REISERFS_FS is not set
# CONFIG_JFS_FS is not set
-
-#
-# XFS support
-#
+# CONFIG_FS_POSIX_ACL is not set
# CONFIG_XFS_FS is not set
+# CONFIG_OCFS2_FS is not set
# CONFIG_MINIX_FS is not set
CONFIG_ROMFS_FS=y
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
# CONFIG_QUOTA is not set
CONFIG_DNOTIFY=y
# CONFIG_AUTOFS_FS is not set
# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
#
# CD-ROM/DVD Filesystems
@@ -602,16 +807,14 @@ CONFIG_DNOTIFY=y
#
CONFIG_PROC_FS=y
# CONFIG_PROC_KCORE is not set
+CONFIG_PROC_SYSCTL=y
CONFIG_SYSFS=y
-CONFIG_DEVFS_FS=y
-CONFIG_DEVFS_MOUNT=y
-# CONFIG_DEVFS_DEBUG is not set
-# CONFIG_DEVPTS_FS_XATTR is not set
CONFIG_TMPFS=y
-# CONFIG_TMPFS_XATTR is not set
+# CONFIG_TMPFS_POSIX_ACL is not set
# CONFIG_HUGETLBFS is not set
# CONFIG_HUGETLB_PAGE is not set
CONFIG_RAMFS=y
+# CONFIG_CONFIGFS_FS is not set
#
# Miscellaneous filesystems
@@ -635,12 +838,14 @@ CONFIG_CRAMFS=y
#
CONFIG_NFS_FS=y
CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
# CONFIG_NFS_V4 is not set
# CONFIG_NFS_DIRECTIO is not set
# CONFIG_NFSD is not set
CONFIG_ROOT_NFS=y
CONFIG_LOCKD=y
CONFIG_LOCKD_V4=y
+CONFIG_NFS_COMMON=y
CONFIG_SUNRPC=y
# CONFIG_RPCSEC_GSS_KRB5 is not set
# CONFIG_RPCSEC_GSS_SPKM3 is not set
@@ -649,6 +854,7 @@ CONFIG_SUNRPC=y
# CONFIG_NCP_FS is not set
# CONFIG_CODA_FS is not set
# CONFIG_AFS_FS is not set
+# CONFIG_9P_FS is not set
#
# Partition Types
@@ -669,8 +875,15 @@ CONFIG_MSDOS_PARTITION=y
#
# Kernel hacking
#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_MUST_CHECK=y
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_UNUSED_SYMBOLS is not set
# CONFIG_DEBUG_KERNEL is not set
-# CONFIG_FRAME_POINTER is not set
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_DEBUG_BUGVERBOSE is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_UNWIND_INFO is not set
# CONFIG_SH_STANDARD_BIOS is not set
# CONFIG_EARLY_SCIF_CONSOLE is not set
# CONFIG_KGDB is not set
@@ -687,13 +900,11 @@ CONFIG_MSDOS_PARTITION=y
# CONFIG_CRYPTO is not set
#
-# Hardware crypto devices
-#
-
-#
# Library routines
#
# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
CONFIG_CRC32=y
# CONFIG_LIBCRC32C is not set
CONFIG_ZLIB_INFLATE=y
+CONFIG_PLIST=y
diff --git a/arch/sh/configs/systemh_defconfig b/arch/sh/configs/systemh_defconfig
index 431c9c9da165..c16350dac01b 100644
--- a/arch/sh/configs/systemh_defconfig
+++ b/arch/sh/configs/systemh_defconfig
@@ -1,48 +1,58 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.11-sh
-# Wed Mar 2 15:09:53 2005
+# Linux kernel version: 2.6.18
+# Tue Oct 3 12:57:29 2006
#
CONFIG_SUPERH=y
-CONFIG_UID16=y
CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+CONFIG_GENERIC_HWEIGHT=y
CONFIG_GENERIC_HARDIRQS=y
CONFIG_GENERIC_IRQ_PROBE=y
CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
#
# Code maturity level options
#
CONFIG_EXPERIMENTAL=y
-# CONFIG_CLEAN_COMPILE is not set
-CONFIG_BROKEN=y
CONFIG_BROKEN_ON_SMP=y
CONFIG_LOCK_KERNEL=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
#
# General setup
#
CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
CONFIG_SWAP=y
# CONFIG_SYSVIPC is not set
# CONFIG_BSD_PROCESS_ACCT is not set
-# CONFIG_SYSCTL is not set
-# CONFIG_AUDIT is not set
-CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_HOTPLUG is not set
+# CONFIG_UTS_NS is not set
# CONFIG_IKCONFIG is not set
+# CONFIG_RELAY is not set
+CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SYSCTL=y
CONFIG_EMBEDDED=y
+CONFIG_UID16=y
+# CONFIG_SYSCTL_SYSCALL is not set
CONFIG_KALLSYMS=y
# CONFIG_KALLSYMS_EXTRA_PASS is not set
+# CONFIG_HOTPLUG is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
CONFIG_EPOLL=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
CONFIG_SHMEM=y
-CONFIG_CC_ALIGN_FUNCTIONS=0
-CONFIG_CC_ALIGN_LABELS=0
-CONFIG_CC_ALIGN_LOOPS=0
-CONFIG_CC_ALIGN_JUMPS=0
+CONFIG_SLAB=y
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_RT_MUTEXES=y
# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+# CONFIG_SLOB is not set
#
# Loadable module support
@@ -50,75 +60,150 @@ CONFIG_CC_ALIGN_JUMPS=0
CONFIG_MODULES=y
CONFIG_MODULE_UNLOAD=y
# CONFIG_MODULE_FORCE_UNLOAD is not set
-CONFIG_OBSOLETE_MODPARM=y
# CONFIG_MODVERSIONS is not set
# CONFIG_MODULE_SRCVERSION_ALL is not set
# CONFIG_KMOD is not set
#
+# Block layer
+#
+CONFIG_BLOCK=y
+# CONFIG_LBD is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_LSF is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+CONFIG_DEFAULT_AS=y
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="anticipatory"
+
+#
# System type
#
# CONFIG_SH_SOLUTION_ENGINE is not set
# CONFIG_SH_7751_SOLUTION_ENGINE is not set
# CONFIG_SH_7300_SOLUTION_ENGINE is not set
+# CONFIG_SH_7343_SOLUTION_ENGINE is not set
# CONFIG_SH_73180_SOLUTION_ENGINE is not set
CONFIG_SH_7751_SYSTEMH=y
-# CONFIG_SH_STB1_HARP is not set
-# CONFIG_SH_STB1_OVERDRIVE is not set
-# CONFIG_SH_HP620 is not set
-# CONFIG_SH_HP680 is not set
-# CONFIG_SH_HP690 is not set
-# CONFIG_SH_CQREEK is not set
-# CONFIG_SH_DMIDA is not set
+# CONFIG_SH_HP6XX is not set
# CONFIG_SH_EC3104 is not set
# CONFIG_SH_SATURN is not set
# CONFIG_SH_DREAMCAST is not set
-# CONFIG_SH_CAT68701 is not set
# CONFIG_SH_BIGSUR is not set
-# CONFIG_SH_SH2000 is not set
-# CONFIG_SH_ADX is not set
# CONFIG_SH_MPC1211 is not set
# CONFIG_SH_SH03 is not set
# CONFIG_SH_SECUREEDGE5410 is not set
# CONFIG_SH_HS7751RVOIP is not set
+# CONFIG_SH_7710VOIPGW is not set
# CONFIG_SH_RTS7751R2D is not set
+# CONFIG_SH_R7780RP is not set
# CONFIG_SH_EDOSK7705 is not set
# CONFIG_SH_SH4202_MICRODEV is not set
+# CONFIG_SH_LANDISK is not set
+# CONFIG_SH_TITAN is not set
+# CONFIG_SH_SHMIN is not set
# CONFIG_SH_UNKNOWN is not set
-# CONFIG_CPU_SH2 is not set
-# CONFIG_CPU_SH3 is not set
+
+#
+# Processor selection
+#
CONFIG_CPU_SH4=y
+
+#
+# SH-2 Processor Support
+#
# CONFIG_CPU_SUBTYPE_SH7604 is not set
+
+#
+# SH-3 Processor Support
+#
# CONFIG_CPU_SUBTYPE_SH7300 is not set
# CONFIG_CPU_SUBTYPE_SH7705 is not set
+# CONFIG_CPU_SUBTYPE_SH7706 is not set
# CONFIG_CPU_SUBTYPE_SH7707 is not set
# CONFIG_CPU_SUBTYPE_SH7708 is not set
# CONFIG_CPU_SUBTYPE_SH7709 is not set
+# CONFIG_CPU_SUBTYPE_SH7710 is not set
+
+#
+# SH-4 Processor Support
+#
# CONFIG_CPU_SUBTYPE_SH7750 is not set
+# CONFIG_CPU_SUBTYPE_SH7091 is not set
+# CONFIG_CPU_SUBTYPE_SH7750R is not set
+# CONFIG_CPU_SUBTYPE_SH7750S is not set
CONFIG_CPU_SUBTYPE_SH7751=y
+CONFIG_CPU_SUBTYPE_SH7751R=y
# CONFIG_CPU_SUBTYPE_SH7760 is not set
-# CONFIG_CPU_SUBTYPE_SH73180 is not set
+# CONFIG_CPU_SUBTYPE_SH4_202 is not set
+
+#
+# ST40 Processor Support
+#
# CONFIG_CPU_SUBTYPE_ST40STB1 is not set
# CONFIG_CPU_SUBTYPE_ST40GX1 is not set
-# CONFIG_CPU_SUBTYPE_SH4_202 is not set
+
+#
+# SH-4A Processor Support
+#
+# CONFIG_CPU_SUBTYPE_SH7770 is not set
+# CONFIG_CPU_SUBTYPE_SH7780 is not set
+
+#
+# SH4AL-DSP Processor Support
+#
+# CONFIG_CPU_SUBTYPE_SH73180 is not set
+# CONFIG_CPU_SUBTYPE_SH7343 is not set
+
+#
+# Memory management options
+#
CONFIG_MMU=y
-# CONFIG_CMDLINE_BOOL is not set
+CONFIG_PAGE_OFFSET=0x80000000
CONFIG_MEMORY_START=0x0c000000
CONFIG_MEMORY_SIZE=0x00400000
-# CONFIG_MEMORY_OVERRIDE is not set
-CONFIG_SH_RTC=y
-CONFIG_SH_FPU=y
-CONFIG_ZERO_PAGE_OFFSET=0x00001000
-CONFIG_BOOT_LINK_OFFSET=0x00800000
-CONFIG_CPU_LITTLE_ENDIAN=y
-CONFIG_PREEMPT=y
-# CONFIG_UBC_WAKEUP is not set
+CONFIG_VSYSCALL=y
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+# CONFIG_SPARSEMEM_STATIC is not set
+CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_RESOURCES_64BIT is not set
+
+#
+# Cache configuration
+#
+# CONFIG_SH_DIRECT_MAPPED is not set
# CONFIG_SH_WRITETHROUGH is not set
# CONFIG_SH_OCRAM is not set
+
+#
+# Processor features
+#
+CONFIG_CPU_LITTLE_ENDIAN=y
+CONFIG_SH_FPU=y
+# CONFIG_SH_DSP is not set
# CONFIG_SH_STORE_QUEUES is not set
-# CONFIG_SMP is not set
-CONFIG_SH_PCLK_CALC=y
-CONFIG_SH_PCLK_FREQ=49876504
+CONFIG_CPU_HAS_INTEVT=y
+CONFIG_CPU_HAS_SR_RB=y
+
+#
+# Timer support
+#
+CONFIG_SH_TMU=y
+CONFIG_SH_PCLK_FREQ=60000000
#
# CPU Frequency scaling
@@ -136,28 +221,39 @@ CONFIG_SH_PCLK_FREQ=49876504
# CONFIG_HD6446X_SERIES is not set
#
-# Bus options (PCI, PCMCIA, EISA, MCA, ISA)
+# Kernel features
#
-CONFIG_PCI=y
-# CONFIG_SH_PCIDMA_NONCOHERENT is not set
-CONFIG_PCI_AUTO=y
-CONFIG_PCI_AUTO_UPDATE_RESOURCES=y
-CONFIG_PCI_LEGACY_PROC=y
-CONFIG_PCI_NAMES=y
+# CONFIG_HZ_100 is not set
+CONFIG_HZ_250=y
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=250
+# CONFIG_KEXEC is not set
+# CONFIG_SMP is not set
+# CONFIG_PREEMPT_NONE is not set
+# CONFIG_PREEMPT_VOLUNTARY is not set
+CONFIG_PREEMPT=y
+CONFIG_PREEMPT_BKL=y
#
-# PCCARD (PCMCIA/CardBus) support
+# Boot options
+#
+CONFIG_ZERO_PAGE_OFFSET=0x00001000
+CONFIG_BOOT_LINK_OFFSET=0x00800000
+# CONFIG_UBC_WAKEUP is not set
+# CONFIG_CMDLINE_BOOL is not set
+
+#
+# Bus options
#
-# CONFIG_PCCARD is not set
+# CONFIG_PCI is not set
#
-# PC-card bridges
+# PCCARD (PCMCIA/CardBus) support
#
#
# PCI Hotplug Support
#
-# CONFIG_HOTPLUG_PCI is not set
#
# Executable file formats
@@ -167,9 +263,14 @@ CONFIG_BINFMT_ELF=y
# CONFIG_BINFMT_MISC is not set
#
-# SH initrd options
+# Power management options (EXPERIMENTAL)
+#
+# CONFIG_PM is not set
+
+#
+# Networking
#
-# CONFIG_EMBEDDED_RAMDISK is not set
+# CONFIG_NET is not set
#
# Device Drivers
@@ -180,7 +281,11 @@ CONFIG_BINFMT_ELF=y
#
# CONFIG_STANDALONE is not set
CONFIG_PREVENT_FIRMWARE_BUILD=y
-# CONFIG_FW_LOADER is not set
+# CONFIG_SYS_HYPERVISOR is not set
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
#
# Memory Technology Devices (MTD)
@@ -199,31 +304,16 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
#
# Block devices
#
-# CONFIG_BLK_DEV_FD is not set
-# CONFIG_BLK_CPQ_DA is not set
-# CONFIG_BLK_CPQ_CISS_DA is not set
-# CONFIG_BLK_DEV_DAC960 is not set
-# CONFIG_BLK_DEV_UMEM is not set
# CONFIG_BLK_DEV_COW_COMMON is not set
# CONFIG_BLK_DEV_LOOP is not set
-# CONFIG_BLK_DEV_SX8 is not set
CONFIG_BLK_DEV_RAM=y
CONFIG_BLK_DEV_RAM_COUNT=16
CONFIG_BLK_DEV_RAM_SIZE=1024
+CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
CONFIG_BLK_DEV_INITRD=y
-CONFIG_INITRAMFS_SOURCE=""
-# CONFIG_LBD is not set
# CONFIG_CDROM_PKTCDVD is not set
#
-# IO Schedulers
-#
-CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
-CONFIG_IOSCHED_DEADLINE=y
-CONFIG_IOSCHED_CFQ=y
-
-#
# ATA/ATAPI/MFM/RLL support
#
# CONFIG_IDE is not set
@@ -231,7 +321,14 @@ CONFIG_IOSCHED_CFQ=y
#
# SCSI device support
#
+# CONFIG_RAID_ATTRS is not set
# CONFIG_SCSI is not set
+# CONFIG_SCSI_NETLINK is not set
+
+#
+# Serial ATA (prod) and Parallel ATA (experimental) drivers
+#
+# CONFIG_ATA is not set
#
# Multi-device support (RAID and LVM)
@@ -241,23 +338,15 @@ CONFIG_IOSCHED_CFQ=y
#
# Fusion MPT device support
#
+# CONFIG_FUSION is not set
#
# IEEE 1394 (FireWire) support
#
-# CONFIG_IEEE1394 is not set
#
# I2O device support
#
-# CONFIG_I2O is not set
-
-#
-# Networking support
-#
-# CONFIG_NET is not set
-# CONFIG_NETPOLL is not set
-# CONFIG_NET_POLL_CONTROLLER is not set
#
# ISDN subsystem
@@ -274,25 +363,14 @@ CONFIG_IOSCHED_CFQ=y
# CONFIG_INPUT is not set
#
-# Userland interfaces
-#
-
+# Hardware I/O ports
#
-# Input I/O drivers
-#
-# CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
CONFIG_SERIO=y
# CONFIG_SERIO_I8042 is not set
# CONFIG_SERIO_SERPORT is not set
-# CONFIG_SERIO_CT82C710 is not set
-# CONFIG_SERIO_PCIPS2 is not set
# CONFIG_SERIO_LIBPS2 is not set
# CONFIG_SERIO_RAW is not set
-
-#
-# Input Device Drivers
-#
+# CONFIG_GAMEPORT is not set
#
# Character devices
@@ -322,27 +400,46 @@ CONFIG_LEGACY_PTY_COUNT=256
# Watchdog Cards
#
# CONFIG_WATCHDOG is not set
-# CONFIG_RTC is not set
+CONFIG_HW_RANDOM=y
# CONFIG_GEN_RTC is not set
# CONFIG_DTLK is not set
# CONFIG_R3964 is not set
-# CONFIG_APPLICOM is not set
#
# Ftape, the floppy tape device driver
#
-# CONFIG_DRM is not set
# CONFIG_RAW_DRIVER is not set
#
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
+# CONFIG_TELCLOCK is not set
+
+#
# I2C support
#
# CONFIG_I2C is not set
#
+# SPI support
+#
+# CONFIG_SPI is not set
+# CONFIG_SPI_MASTER is not set
+
+#
# Dallas's 1-wire bus
#
-# CONFIG_W1 is not set
+
+#
+# Hardware Monitoring support
+#
+CONFIG_HWMON=y
+# CONFIG_HWMON_VID is not set
+# CONFIG_SENSORS_ABITUGURU is not set
+# CONFIG_SENSORS_F71805F is not set
+# CONFIG_SENSORS_VT1211 is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
#
# Misc devices
@@ -352,6 +449,7 @@ CONFIG_LEGACY_PTY_COUNT=256
# Multimedia devices
#
# CONFIG_VIDEO_DEV is not set
+CONFIG_VIDEO_V4L2=y
#
# Digital Video Broadcasting Devices
@@ -360,7 +458,9 @@ CONFIG_LEGACY_PTY_COUNT=256
#
# Graphics support
#
+CONFIG_FIRMWARE_EDID=y
# CONFIG_FB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
#
# Sound
@@ -370,12 +470,12 @@ CONFIG_LEGACY_PTY_COUNT=256
#
# USB support
#
-# CONFIG_USB is not set
-CONFIG_USB_ARCH_HAS_HCD=y
-CONFIG_USB_ARCH_HAS_OHCI=y
+# CONFIG_USB_ARCH_HAS_HCD is not set
+# CONFIG_USB_ARCH_HAS_OHCI is not set
+# CONFIG_USB_ARCH_HAS_EHCI is not set
#
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
#
#
@@ -389,29 +489,62 @@ CONFIG_USB_ARCH_HAS_OHCI=y
# CONFIG_MMC is not set
#
+# LED devices
+#
+# CONFIG_NEW_LEDS is not set
+
+#
+# LED drivers
+#
+
+#
+# LED Triggers
+#
+
+#
# InfiniBand support
#
-# CONFIG_INFINIBAND is not set
+
+#
+# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
+#
+
+#
+# Real Time Clock
+#
+# CONFIG_RTC_CLASS is not set
+
+#
+# DMA Engine support
+#
+# CONFIG_DMA_ENGINE is not set
+
+#
+# DMA Clients
+#
+
+#
+# DMA Devices
+#
#
# File systems
#
# CONFIG_EXT2_FS is not set
# CONFIG_EXT3_FS is not set
-# CONFIG_JBD is not set
# CONFIG_REISERFS_FS is not set
# CONFIG_JFS_FS is not set
-
-#
-# XFS support
-#
+# CONFIG_FS_POSIX_ACL is not set
# CONFIG_XFS_FS is not set
# CONFIG_MINIX_FS is not set
CONFIG_ROMFS_FS=y
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
# CONFIG_QUOTA is not set
CONFIG_DNOTIFY=y
# CONFIG_AUTOFS_FS is not set
# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
#
# CD-ROM/DVD Filesystems
@@ -431,16 +564,14 @@ CONFIG_DNOTIFY=y
#
CONFIG_PROC_FS=y
CONFIG_PROC_KCORE=y
+CONFIG_PROC_SYSCTL=y
CONFIG_SYSFS=y
-CONFIG_DEVFS_FS=y
-CONFIG_DEVFS_MOUNT=y
-# CONFIG_DEVFS_DEBUG is not set
-# CONFIG_DEVPTS_FS_XATTR is not set
CONFIG_TMPFS=y
-# CONFIG_TMPFS_XATTR is not set
+# CONFIG_TMPFS_POSIX_ACL is not set
# CONFIG_HUGETLBFS is not set
# CONFIG_HUGETLB_PAGE is not set
CONFIG_RAMFS=y
+# CONFIG_CONFIGFS_FS is not set
#
# Miscellaneous filesystems
@@ -478,9 +609,14 @@ CONFIG_MSDOS_PARTITION=y
#
# Kernel hacking
#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_MUST_CHECK=y
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_UNUSED_SYMBOLS is not set
# CONFIG_DEBUG_KERNEL is not set
-CONFIG_DEBUG_PREEMPT=y
-# CONFIG_FRAME_POINTER is not set
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_DEBUG_BUGVERBOSE is not set
+# CONFIG_DEBUG_FS is not set
# CONFIG_SH_STANDARD_BIOS is not set
# CONFIG_EARLY_SCIF_CONSOLE is not set
# CONFIG_KGDB is not set
@@ -497,13 +633,11 @@ CONFIG_DEBUG_PREEMPT=y
# CONFIG_CRYPTO is not set
#
-# Hardware crypto devices
-#
-
-#
# Library routines
#
# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
CONFIG_CRC32=y
# CONFIG_LIBCRC32C is not set
CONFIG_ZLIB_INFLATE=y
+CONFIG_PLIST=y
diff --git a/arch/sh/configs/titan_defconfig b/arch/sh/configs/titan_defconfig
index 1db2904de9e5..5e8175461138 100644
--- a/arch/sh/configs/titan_defconfig
+++ b/arch/sh/configs/titan_defconfig
@@ -1,21 +1,21 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.14-sh
-# Wed Nov 9 00:35:56 2005
+# Linux kernel version: 2.6.18
+# Tue Oct 3 12:59:14 2006
#
CONFIG_SUPERH=y
-CONFIG_UID16=y
CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+CONFIG_GENERIC_HWEIGHT=y
CONFIG_GENERIC_HARDIRQS=y
CONFIG_GENERIC_IRQ_PROBE=y
CONFIG_GENERIC_CALIBRATE_DELAY=y
-CONFIG_GENERIC_IOMAP=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
#
# Code maturity level options
#
CONFIG_EXPERIMENTAL=y
-CONFIG_CLEAN_COMPILE=y
CONFIG_BROKEN_ON_SMP=y
CONFIG_INIT_ENV_ARG_LIMIT=32
@@ -26,31 +26,38 @@ CONFIG_LOCALVERSION=""
CONFIG_LOCALVERSION_AUTO=y
CONFIG_SWAP=y
CONFIG_SYSVIPC=y
-# CONFIG_POSIX_MQUEUE is not set
+# CONFIG_IPC_NS is not set
+CONFIG_POSIX_MQUEUE=y
# CONFIG_BSD_PROCESS_ACCT is not set
-CONFIG_SYSCTL=y
+# CONFIG_TASKSTATS is not set
+# CONFIG_UTS_NS is not set
# CONFIG_AUDIT is not set
-CONFIG_HOTPLUG=y
-CONFIG_KOBJECT_UEVENT=y
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
+# CONFIG_RELAY is not set
CONFIG_INITRAMFS_SOURCE=""
-# CONFIG_EMBEDDED is not set
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SYSCTL=y
+CONFIG_EMBEDDED=y
+CONFIG_UID16=y
+# CONFIG_SYSCTL_SYSCALL is not set
CONFIG_KALLSYMS=y
# CONFIG_KALLSYMS_ALL is not set
# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
CONFIG_PRINTK=y
CONFIG_BUG=y
+CONFIG_ELF_CORE=y
CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
CONFIG_EPOLL=y
CONFIG_SHMEM=y
-CONFIG_CC_ALIGN_FUNCTIONS=0
-CONFIG_CC_ALIGN_LABELS=0
-CONFIG_CC_ALIGN_LOOPS=0
-CONFIG_CC_ALIGN_JUMPS=0
+CONFIG_SLAB=y
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_RT_MUTEXES=y
# CONFIG_TINY_SHMEM is not set
CONFIG_BASE_SMALL=0
+# CONFIG_SLOB is not set
#
# Loadable module support
@@ -58,40 +65,57 @@ CONFIG_BASE_SMALL=0
CONFIG_MODULES=y
CONFIG_MODULE_UNLOAD=y
CONFIG_MODULE_FORCE_UNLOAD=y
-CONFIG_OBSOLETE_MODPARM=y
# CONFIG_MODVERSIONS is not set
# CONFIG_MODULE_SRCVERSION_ALL is not set
CONFIG_KMOD=y
#
+# Block layer
+#
+CONFIG_BLOCK=y
+# CONFIG_LBD is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_LSF is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+CONFIG_DEFAULT_AS=y
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="anticipatory"
+
+#
# System type
#
# CONFIG_SH_SOLUTION_ENGINE is not set
# CONFIG_SH_7751_SOLUTION_ENGINE is not set
# CONFIG_SH_7300_SOLUTION_ENGINE is not set
+# CONFIG_SH_7343_SOLUTION_ENGINE is not set
# CONFIG_SH_73180_SOLUTION_ENGINE is not set
# CONFIG_SH_7751_SYSTEMH is not set
-CONFIG_SH_TITAN=y
-# CONFIG_SH_STB1_HARP is not set
-# CONFIG_SH_STB1_OVERDRIVE is not set
# CONFIG_SH_HP6XX is not set
-# CONFIG_SH_CQREEK is not set
-# CONFIG_SH_DMIDA is not set
# CONFIG_SH_EC3104 is not set
# CONFIG_SH_SATURN is not set
# CONFIG_SH_DREAMCAST is not set
-# CONFIG_SH_CAT68701 is not set
# CONFIG_SH_BIGSUR is not set
-# CONFIG_SH_SH2000 is not set
-# CONFIG_SH_ADX is not set
# CONFIG_SH_MPC1211 is not set
# CONFIG_SH_SH03 is not set
# CONFIG_SH_SECUREEDGE5410 is not set
# CONFIG_SH_HS7751RVOIP is not set
+# CONFIG_SH_7710VOIPGW is not set
# CONFIG_SH_RTS7751R2D is not set
+# CONFIG_SH_R7780RP is not set
# CONFIG_SH_EDOSK7705 is not set
# CONFIG_SH_SH4202_MICRODEV is not set
# CONFIG_SH_LANDISK is not set
+CONFIG_SH_TITAN=y
+# CONFIG_SH_SHMIN is not set
# CONFIG_SH_UNKNOWN is not set
#
@@ -109,9 +133,11 @@ CONFIG_CPU_SH4=y
#
# CONFIG_CPU_SUBTYPE_SH7300 is not set
# CONFIG_CPU_SUBTYPE_SH7705 is not set
+# CONFIG_CPU_SUBTYPE_SH7706 is not set
# CONFIG_CPU_SUBTYPE_SH7707 is not set
# CONFIG_CPU_SUBTYPE_SH7708 is not set
# CONFIG_CPU_SUBTYPE_SH7709 is not set
+# CONFIG_CPU_SUBTYPE_SH7710 is not set
#
# SH-4 Processor Support
@@ -134,14 +160,23 @@ CONFIG_CPU_SUBTYPE_SH7751R=y
#
# SH-4A Processor Support
#
-# CONFIG_CPU_SUBTYPE_SH73180 is not set
# CONFIG_CPU_SUBTYPE_SH7770 is not set
# CONFIG_CPU_SUBTYPE_SH7780 is not set
#
+# SH4AL-DSP Processor Support
+#
+# CONFIG_CPU_SUBTYPE_SH73180 is not set
+# CONFIG_CPU_SUBTYPE_SH7343 is not set
+
+#
# Memory management options
#
CONFIG_MMU=y
+CONFIG_PAGE_OFFSET=0x80000000
+CONFIG_MEMORY_START=0x08030000
+CONFIG_MEMORY_SIZE=0x7fd0000
+CONFIG_VSYSCALL=y
CONFIG_SELECT_MEMORY_MODEL=y
CONFIG_FLATMEM_MANUAL=y
# CONFIG_DISCONTIGMEM_MANUAL is not set
@@ -149,6 +184,8 @@ CONFIG_FLATMEM_MANUAL=y
CONFIG_FLATMEM=y
CONFIG_FLAT_NODE_MEM_MAP=y
# CONFIG_SPARSEMEM_STATIC is not set
+CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_RESOURCES_64BIT is not set
#
# Cache configuration
@@ -156,22 +193,21 @@ CONFIG_FLAT_NODE_MEM_MAP=y
# CONFIG_SH_DIRECT_MAPPED is not set
# CONFIG_SH_WRITETHROUGH is not set
# CONFIG_SH_OCRAM is not set
-CONFIG_MEMORY_START=0x08030000
-CONFIG_MEMORY_SIZE=0x7fd0000
#
# Processor features
#
CONFIG_CPU_LITTLE_ENDIAN=y
-CONFIG_SH_RTC=y
CONFIG_SH_FPU=y
+# CONFIG_SH_DSP is not set
# CONFIG_SH_STORE_QUEUES is not set
+CONFIG_CPU_HAS_INTEVT=y
+CONFIG_CPU_HAS_SR_RB=y
#
# Timer support
#
CONFIG_SH_TMU=y
-CONFIG_SH_PCLK_FREQ_BOOL=y
CONFIG_SH_PCLK_FREQ=30000000
#
@@ -194,9 +230,15 @@ CONFIG_NR_ONCHIP_DMA_CHANNELS=8
#
# Kernel features
#
+# CONFIG_HZ_100 is not set
+CONFIG_HZ_250=y
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=250
# CONFIG_KEXEC is not set
-# CONFIG_PREEMPT is not set
# CONFIG_SMP is not set
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
+# CONFIG_PREEMPT is not set
#
# Boot options
@@ -214,8 +256,8 @@ CONFIG_PCI=y
CONFIG_SH_PCIDMA_NONCOHERENT=y
CONFIG_PCI_AUTO=y
CONFIG_PCI_AUTO_UPDATE_RESOURCES=y
-CONFIG_PCI_LEGACY_PROC=y
-#CONFIG_PCI_DEBUG is not set
+# CONFIG_PCI_MULTITHREAD_PROBE is not set
+# CONFIG_PCI_DEBUG is not set
#
# PCCARD (PCMCIA/CardBus) support
@@ -238,6 +280,11 @@ CONFIG_BINFMT_ELF=y
# CONFIG_BINFMT_MISC is not set
#
+# Power management options (EXPERIMENTAL)
+#
+# CONFIG_PM is not set
+
+#
# Networking
#
CONFIG_NET=y
@@ -245,11 +292,13 @@ CONFIG_NET=y
#
# Networking options
#
+# CONFIG_NETDEBUG is not set
CONFIG_PACKET=y
CONFIG_PACKET_MMAP=y
CONFIG_UNIX=y
CONFIG_XFRM=y
# CONFIG_XFRM_USER is not set
+# CONFIG_XFRM_SUB_POLICY is not set
CONFIG_NET_KEY=y
CONFIG_INET=y
CONFIG_IP_MULTICAST=y
@@ -270,40 +319,87 @@ CONFIG_IP_PNP=y
CONFIG_IP_PNP_DHCP=y
CONFIG_IP_PNP_BOOTP=y
CONFIG_IP_PNP_RARP=y
-CONFIG_NET_IPIP=m
-CONFIG_NET_IPGRE=m
+CONFIG_NET_IPIP=y
+CONFIG_NET_IPGRE=y
CONFIG_NET_IPGRE_BROADCAST=y
CONFIG_IP_MROUTE=y
CONFIG_IP_PIMSM_V1=y
CONFIG_IP_PIMSM_V2=y
# CONFIG_ARPD is not set
CONFIG_SYN_COOKIES=y
-CONFIG_INET_AH=m
-CONFIG_INET_ESP=m
-CONFIG_INET_IPCOMP=m
-CONFIG_INET_TUNNEL=m
+CONFIG_INET_AH=y
+CONFIG_INET_ESP=y
+CONFIG_INET_IPCOMP=y
+CONFIG_INET_XFRM_TUNNEL=y
+CONFIG_INET_TUNNEL=y
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
CONFIG_INET_DIAG=m
CONFIG_INET_TCP_DIAG=m
# CONFIG_TCP_CONG_ADVANCED is not set
-CONFIG_TCP_CONG_BIC=y
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
#
# IP: Virtual Server Configuration
#
# CONFIG_IP_VS is not set
-CONFIG_IPV6=m
+CONFIG_IPV6=y
CONFIG_IPV6_PRIVACY=y
-CONFIG_INET6_AH=m
-CONFIG_INET6_ESP=m
-CONFIG_INET6_IPCOMP=m
-CONFIG_INET6_TUNNEL=m
-CONFIG_IPV6_TUNNEL=m
+# CONFIG_IPV6_ROUTER_PREF is not set
+CONFIG_INET6_AH=y
+CONFIG_INET6_ESP=y
+CONFIG_INET6_IPCOMP=y
+# CONFIG_IPV6_MIP6 is not set
+CONFIG_INET6_XFRM_TUNNEL=y
+CONFIG_INET6_TUNNEL=y
+CONFIG_INET6_XFRM_MODE_TRANSPORT=y
+CONFIG_INET6_XFRM_MODE_TUNNEL=y
+# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set
+CONFIG_IPV6_TUNNEL=y
+# CONFIG_IPV6_SUBTREES is not set
+# CONFIG_IPV6_MULTIPLE_TABLES is not set
+# CONFIG_NETWORK_SECMARK is not set
CONFIG_NETFILTER=y
# CONFIG_NETFILTER_DEBUG is not set
CONFIG_BRIDGE_NETFILTER=y
+
+#
+# Core Netfilter Configuration
+#
CONFIG_NETFILTER_NETLINK=m
CONFIG_NETFILTER_NETLINK_QUEUE=m
CONFIG_NETFILTER_NETLINK_LOG=m
+CONFIG_NETFILTER_XTABLES=m
+CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
+CONFIG_NETFILTER_XT_TARGET_CONNMARK=m
+# CONFIG_NETFILTER_XT_TARGET_DSCP is not set
+CONFIG_NETFILTER_XT_TARGET_MARK=m
+CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
+CONFIG_NETFILTER_XT_TARGET_NOTRACK=m
+CONFIG_NETFILTER_XT_MATCH_COMMENT=m
+CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m
+CONFIG_NETFILTER_XT_MATCH_CONNMARK=m
+CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m
+CONFIG_NETFILTER_XT_MATCH_DCCP=m
+# CONFIG_NETFILTER_XT_MATCH_DSCP is not set
+CONFIG_NETFILTER_XT_MATCH_ESP=m
+CONFIG_NETFILTER_XT_MATCH_HELPER=m
+CONFIG_NETFILTER_XT_MATCH_LENGTH=m
+CONFIG_NETFILTER_XT_MATCH_LIMIT=m
+CONFIG_NETFILTER_XT_MATCH_MAC=m
+CONFIG_NETFILTER_XT_MATCH_MARK=m
+CONFIG_NETFILTER_XT_MATCH_POLICY=m
+CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m
+CONFIG_NETFILTER_XT_MATCH_PHYSDEV=m
+CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m
+# CONFIG_NETFILTER_XT_MATCH_QUOTA is not set
+CONFIG_NETFILTER_XT_MATCH_REALM=m
+CONFIG_NETFILTER_XT_MATCH_SCTP=m
+CONFIG_NETFILTER_XT_MATCH_STATE=m
+# CONFIG_NETFILTER_XT_MATCH_STATISTIC is not set
+CONFIG_NETFILTER_XT_MATCH_STRING=m
+CONFIG_NETFILTER_XT_MATCH_TCPMSS=m
#
# IP: Netfilter Configuration
@@ -320,42 +416,24 @@ CONFIG_IP_NF_NETBIOS_NS=m
CONFIG_IP_NF_TFTP=m
# CONFIG_IP_NF_AMANDA is not set
CONFIG_IP_NF_PPTP=m
+CONFIG_IP_NF_H323=m
+# CONFIG_IP_NF_SIP is not set
CONFIG_IP_NF_QUEUE=m
CONFIG_IP_NF_IPTABLES=m
-CONFIG_IP_NF_MATCH_LIMIT=m
CONFIG_IP_NF_MATCH_IPRANGE=m
-CONFIG_IP_NF_MATCH_MAC=m
-CONFIG_IP_NF_MATCH_PKTTYPE=m
-CONFIG_IP_NF_MATCH_MARK=m
-CONFIG_IP_NF_MATCH_MULTIPORT=m
CONFIG_IP_NF_MATCH_TOS=m
CONFIG_IP_NF_MATCH_RECENT=m
CONFIG_IP_NF_MATCH_ECN=m
-CONFIG_IP_NF_MATCH_DSCP=m
-CONFIG_IP_NF_MATCH_AH_ESP=m
-CONFIG_IP_NF_MATCH_LENGTH=m
+CONFIG_IP_NF_MATCH_AH=m
CONFIG_IP_NF_MATCH_TTL=m
-CONFIG_IP_NF_MATCH_TCPMSS=m
-CONFIG_IP_NF_MATCH_HELPER=m
-CONFIG_IP_NF_MATCH_STATE=m
-CONFIG_IP_NF_MATCH_CONNTRACK=m
CONFIG_IP_NF_MATCH_OWNER=m
-# CONFIG_IP_NF_MATCH_PHYSDEV is not set
CONFIG_IP_NF_MATCH_ADDRTYPE=m
-CONFIG_IP_NF_MATCH_REALM=m
-# CONFIG_IP_NF_MATCH_SCTP is not set
-# CONFIG_IP_NF_MATCH_DCCP is not set
-CONFIG_IP_NF_MATCH_COMMENT=m
-CONFIG_IP_NF_MATCH_CONNMARK=m
-CONFIG_IP_NF_MATCH_CONNBYTES=m
CONFIG_IP_NF_MATCH_HASHLIMIT=m
-CONFIG_IP_NF_MATCH_STRING=m
CONFIG_IP_NF_FILTER=m
CONFIG_IP_NF_TARGET_REJECT=m
CONFIG_IP_NF_TARGET_LOG=m
CONFIG_IP_NF_TARGET_ULOG=m
CONFIG_IP_NF_TARGET_TCPMSS=m
-CONFIG_IP_NF_TARGET_NFQUEUE=m
CONFIG_IP_NF_NAT=m
CONFIG_IP_NF_NAT_NEEDED=y
CONFIG_IP_NF_TARGET_MASQUERADE=m
@@ -367,17 +445,13 @@ CONFIG_IP_NF_NAT_IRC=m
CONFIG_IP_NF_NAT_FTP=m
CONFIG_IP_NF_NAT_TFTP=m
CONFIG_IP_NF_NAT_PPTP=m
+CONFIG_IP_NF_NAT_H323=m
CONFIG_IP_NF_MANGLE=m
CONFIG_IP_NF_TARGET_TOS=m
CONFIG_IP_NF_TARGET_ECN=m
-CONFIG_IP_NF_TARGET_DSCP=m
-CONFIG_IP_NF_TARGET_MARK=m
-CONFIG_IP_NF_TARGET_CLASSIFY=m
CONFIG_IP_NF_TARGET_TTL=m
-CONFIG_IP_NF_TARGET_CONNMARK=m
CONFIG_IP_NF_TARGET_CLUSTERIP=m
CONFIG_IP_NF_RAW=m
-CONFIG_IP_NF_TARGET_NOTRACK=m
CONFIG_IP_NF_ARPTABLES=m
CONFIG_IP_NF_ARPFILTER=m
CONFIG_IP_NF_ARP_MANGLE=m
@@ -387,26 +461,18 @@ CONFIG_IP_NF_ARP_MANGLE=m
#
CONFIG_IP6_NF_QUEUE=m
CONFIG_IP6_NF_IPTABLES=m
-CONFIG_IP6_NF_MATCH_LIMIT=m
-CONFIG_IP6_NF_MATCH_MAC=m
CONFIG_IP6_NF_MATCH_RT=m
CONFIG_IP6_NF_MATCH_OPTS=m
CONFIG_IP6_NF_MATCH_FRAG=m
CONFIG_IP6_NF_MATCH_HL=m
-CONFIG_IP6_NF_MATCH_MULTIPORT=m
CONFIG_IP6_NF_MATCH_OWNER=m
-CONFIG_IP6_NF_MATCH_MARK=m
CONFIG_IP6_NF_MATCH_IPV6HEADER=m
-CONFIG_IP6_NF_MATCH_AHESP=m
-CONFIG_IP6_NF_MATCH_LENGTH=m
+CONFIG_IP6_NF_MATCH_AH=m
CONFIG_IP6_NF_MATCH_EUI64=m
-# CONFIG_IP6_NF_MATCH_PHYSDEV is not set
CONFIG_IP6_NF_FILTER=m
CONFIG_IP6_NF_TARGET_LOG=m
CONFIG_IP6_NF_TARGET_REJECT=m
-CONFIG_IP6_NF_TARGET_NFQUEUE=m
CONFIG_IP6_NF_MANGLE=m
-CONFIG_IP6_NF_TARGET_MARK=m
CONFIG_IP6_NF_TARGET_HL=m
CONFIG_IP6_NF_RAW=m
@@ -424,22 +490,35 @@ CONFIG_IP6_NF_RAW=m
# SCTP Configuration (EXPERIMENTAL)
#
# CONFIG_IP_SCTP is not set
+
+#
+# TIPC Configuration (EXPERIMENTAL)
+#
+# CONFIG_TIPC is not set
# CONFIG_ATM is not set
-CONFIG_BRIDGE=m
-CONFIG_VLAN_8021Q=m
+CONFIG_BRIDGE=y
+CONFIG_VLAN_8021Q=y
# CONFIG_DECNET is not set
+CONFIG_LLC=y
# CONFIG_LLC2 is not set
# CONFIG_IPX is not set
# CONFIG_ATALK is not set
# CONFIG_X25 is not set
# CONFIG_LAPB is not set
-# CONFIG_NET_DIVERT is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
+
+#
+# QoS and/or fair queueing
+#
CONFIG_NET_SCHED=y
CONFIG_NET_SCH_CLK_JIFFIES=y
# CONFIG_NET_SCH_CLK_GETTIMEOFDAY is not set
# CONFIG_NET_SCH_CLK_CPU is not set
+
+#
+# Queueing/Scheduling
+#
CONFIG_NET_SCH_CBQ=m
CONFIG_NET_SCH_HTB=m
CONFIG_NET_SCH_HFSC=m
@@ -452,8 +531,10 @@ CONFIG_NET_SCH_GRED=m
CONFIG_NET_SCH_DSMARK=m
CONFIG_NET_SCH_NETEM=m
CONFIG_NET_SCH_INGRESS=m
-CONFIG_NET_QOS=y
-CONFIG_NET_ESTIMATOR=y
+
+#
+# Classification
+#
CONFIG_NET_CLS=y
CONFIG_NET_CLS_BASIC=m
CONFIG_NET_CLS_TCINDEX=m
@@ -462,7 +543,6 @@ CONFIG_NET_CLS_ROUTE=y
CONFIG_NET_CLS_FW=m
CONFIG_NET_CLS_U32=m
CONFIG_CLS_U32_PERF=y
-CONFIG_NET_CLS_IND=y
CONFIG_CLS_U32_MARK=y
CONFIG_NET_CLS_RSVP=m
CONFIG_NET_CLS_RSVP6=m
@@ -481,6 +561,8 @@ CONFIG_NET_ACT_MIRRED=m
CONFIG_NET_ACT_IPT=m
CONFIG_NET_ACT_PEDIT=m
# CONFIG_NET_ACT_SIMP is not set
+CONFIG_NET_CLS_IND=y
+CONFIG_NET_ESTIMATOR=y
#
# Network testing
@@ -489,7 +571,15 @@ CONFIG_NET_ACT_PEDIT=m
# CONFIG_HAMRADIO is not set
# CONFIG_IRDA is not set
# CONFIG_BT is not set
-# CONFIG_IEEE80211 is not set
+CONFIG_IEEE80211=y
+# CONFIG_IEEE80211_DEBUG is not set
+CONFIG_IEEE80211_CRYPT_WEP=y
+CONFIG_IEEE80211_CRYPT_CCMP=y
+CONFIG_IEEE80211_CRYPT_TKIP=y
+CONFIG_IEEE80211_SOFTMAC=m
+# CONFIG_IEEE80211_SOFTMAC_DEBUG is not set
+CONFIG_WIRELESS_EXT=y
+CONFIG_FIB_RULES=y
#
# Device Drivers
@@ -502,6 +592,7 @@ CONFIG_STANDALONE=y
CONFIG_PREVENT_FIRMWARE_BUILD=y
CONFIG_FW_LOADER=m
# CONFIG_DEBUG_DRIVER is not set
+# CONFIG_SYS_HYPERVISOR is not set
#
# Connector - unified userspace <-> kernelspace linker
@@ -511,7 +602,86 @@ CONFIG_CONNECTOR=m
#
# Memory Technology Devices (MTD)
#
-# CONFIG_MTD is not set
+CONFIG_MTD=m
+CONFIG_MTD_DEBUG=y
+CONFIG_MTD_DEBUG_VERBOSE=0
+# CONFIG_MTD_CONCAT is not set
+# CONFIG_MTD_PARTITIONS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=m
+CONFIG_MTD_BLOCK=m
+# CONFIG_MTD_BLOCK_RO is not set
+CONFIG_FTL=m
+CONFIG_NFTL=m
+# CONFIG_NFTL_RW is not set
+CONFIG_INFTL=m
+CONFIG_RFD_FTL=m
+# CONFIG_SSFDC is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+CONFIG_MTD_CFI=m
+CONFIG_MTD_JEDECPROBE=m
+CONFIG_MTD_GEN_PROBE=m
+# CONFIG_MTD_CFI_ADV_OPTIONS is not set
+CONFIG_MTD_MAP_BANK_WIDTH_1=y
+CONFIG_MTD_MAP_BANK_WIDTH_2=y
+CONFIG_MTD_MAP_BANK_WIDTH_4=y
+# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
+CONFIG_MTD_CFI_I1=y
+CONFIG_MTD_CFI_I2=y
+# CONFIG_MTD_CFI_I4 is not set
+# CONFIG_MTD_CFI_I8 is not set
+# CONFIG_MTD_CFI_INTELEXT is not set
+# CONFIG_MTD_CFI_AMDSTD is not set
+# CONFIG_MTD_CFI_STAA is not set
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+# CONFIG_MTD_OBSOLETE_CHIPS is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+# CONFIG_MTD_PHYSMAP is not set
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_PMC551 is not set
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLOCK2MTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOC2001PLUS is not set
+
+#
+# NAND Flash Device Drivers
+#
+CONFIG_MTD_NAND=m
+# CONFIG_MTD_NAND_VERIFY_WRITE is not set
+# CONFIG_MTD_NAND_ECC_SMC is not set
+CONFIG_MTD_NAND_IDS=m
+# CONFIG_MTD_NAND_DISKONCHIP is not set
+
+#
+# OneNAND Flash Device Drivers
+#
+# CONFIG_MTD_ONENAND is not set
#
# Parallel port support
@@ -528,29 +698,20 @@ CONFIG_CONNECTOR=m
# CONFIG_BLK_CPQ_DA is not set
# CONFIG_BLK_CPQ_CISS_DA is not set
# CONFIG_BLK_DEV_DAC960 is not set
-CONFIG_BLK_SSFDC=y
# CONFIG_BLK_DEV_UMEM is not set
# CONFIG_BLK_DEV_COW_COMMON is not set
CONFIG_BLK_DEV_LOOP=m
-# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+CONFIG_BLK_DEV_CRYPTOLOOP=m
# CONFIG_BLK_DEV_NBD is not set
# CONFIG_BLK_DEV_SX8 is not set
# CONFIG_BLK_DEV_UB is not set
CONFIG_BLK_DEV_RAM=y
CONFIG_BLK_DEV_RAM_COUNT=16
CONFIG_BLK_DEV_RAM_SIZE=4096
+CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
CONFIG_BLK_DEV_INITRD=y
-# CONFIG_LBD is not set
# CONFIG_CDROM_PKTCDVD is not set
-
-#
-# IO Schedulers
-#
-CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
-CONFIG_IOSCHED_DEADLINE=y
-CONFIG_IOSCHED_CFQ=y
-# CONFIG_ATA_OVER_ETH is not set
+CONFIG_ATA_OVER_ETH=m
#
# ATA/ATAPI/MFM/RLL support
@@ -561,7 +722,8 @@ CONFIG_IOSCHED_CFQ=y
# SCSI device support
#
# CONFIG_RAID_ATTRS is not set
-CONFIG_SCSI=m
+CONFIG_SCSI=y
+# CONFIG_SCSI_NETLINK is not set
CONFIG_SCSI_PROC_FS=y
#
@@ -583,16 +745,18 @@ CONFIG_CHR_DEV_SG=m
# CONFIG_SCSI_LOGGING is not set
#
-# SCSI Transport Attributes
+# SCSI Transports
#
# CONFIG_SCSI_SPI_ATTRS is not set
# CONFIG_SCSI_FC_ATTRS is not set
# CONFIG_SCSI_ISCSI_ATTRS is not set
# CONFIG_SCSI_SAS_ATTRS is not set
+# CONFIG_SCSI_SAS_LIBSAS is not set
#
# SCSI low-level drivers
#
+# CONFIG_ISCSI_TCP is not set
# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
# CONFIG_SCSI_3W_9XXX is not set
# CONFIG_SCSI_ACARD is not set
@@ -600,27 +764,23 @@ CONFIG_CHR_DEV_SG=m
# CONFIG_SCSI_AIC7XXX is not set
# CONFIG_SCSI_AIC7XXX_OLD is not set
# CONFIG_SCSI_AIC79XX is not set
+# CONFIG_SCSI_AIC94XX is not set
# CONFIG_SCSI_DPT_I2O is not set
+# CONFIG_SCSI_ARCMSR is not set
# CONFIG_MEGARAID_NEWGEN is not set
# CONFIG_MEGARAID_LEGACY is not set
# CONFIG_MEGARAID_SAS is not set
-# CONFIG_SCSI_SATA is not set
+# CONFIG_SCSI_HPTIOP is not set
# CONFIG_SCSI_DMX3191D is not set
# CONFIG_SCSI_FUTURE_DOMAIN is not set
# CONFIG_SCSI_IPS is not set
# CONFIG_SCSI_INITIO is not set
# CONFIG_SCSI_INIA100 is not set
+# CONFIG_SCSI_STEX is not set
# CONFIG_SCSI_SYM53C8XX_2 is not set
# CONFIG_SCSI_IPR is not set
-# CONFIG_SCSI_QLOGIC_FC is not set
# CONFIG_SCSI_QLOGIC_1280 is not set
-CONFIG_SCSI_QLA2XXX=m
-# CONFIG_SCSI_QLA21XX is not set
-# CONFIG_SCSI_QLA22XX is not set
-# CONFIG_SCSI_QLA2300 is not set
-# CONFIG_SCSI_QLA2322 is not set
-# CONFIG_SCSI_QLA6312 is not set
-# CONFIG_SCSI_QLA24XX is not set
+# CONFIG_SCSI_QLA_FC is not set
# CONFIG_SCSI_LPFC is not set
# CONFIG_SCSI_DC395x is not set
# CONFIG_SCSI_DC390T is not set
@@ -628,6 +788,11 @@ CONFIG_SCSI_QLA2XXX=m
# CONFIG_SCSI_DEBUG is not set
#
+# Serial ATA (prod) and Parallel ATA (experimental) drivers
+#
+# CONFIG_ATA is not set
+
+#
# Multi-device support (RAID and LVM)
#
# CONFIG_MD is not set
@@ -654,6 +819,7 @@ CONFIG_SCSI_QLA2XXX=m
# Network device support
#
CONFIG_NETDEVICES=y
+# CONFIG_IFB is not set
# CONFIG_DUMMY is not set
# CONFIG_BONDING is not set
# CONFIG_EQUALIZER is not set
@@ -668,7 +834,6 @@ CONFIG_TUN=m
# PHY device support
#
CONFIG_PHYLIB=m
-CONFIG_PHYCONTROL=y
#
# MII PHY device drivers
@@ -678,6 +843,9 @@ CONFIG_DAVICOM_PHY=m
CONFIG_QSEMI_PHY=m
CONFIG_LXT_PHY=m
CONFIG_CICADA_PHY=m
+# CONFIG_VITESSE_PHY is not set
+# CONFIG_SMSC_PHY is not set
+# CONFIG_FIXED_PHY is not set
#
# Ethernet (10 or 100Mbit)
@@ -687,7 +855,7 @@ CONFIG_MII=y
# CONFIG_STNIC is not set
# CONFIG_HAPPYMEAL is not set
# CONFIG_SUNGEM is not set
-CONFIG_CASSINI=m
+# CONFIG_CASSINI is not set
# CONFIG_NET_VENDOR_3COM is not set
# CONFIG_SMC91X is not set
@@ -696,7 +864,6 @@ CONFIG_CASSINI=m
#
# CONFIG_NET_TULIP is not set
# CONFIG_HP100 is not set
-# CONFIG_NE2000 is not set
CONFIG_NET_PCI=y
# CONFIG_PCNET32 is not set
# CONFIG_AMD8111_ETH is not set
@@ -733,10 +900,12 @@ CONFIG_8139_OLD_RX_RESET=y
# CONFIG_R8169 is not set
# CONFIG_SIS190 is not set
# CONFIG_SKGE is not set
+# CONFIG_SKY2 is not set
# CONFIG_SK98LIN is not set
# CONFIG_VIA_VELOCITY is not set
# CONFIG_TIGON3 is not set
# CONFIG_BNX2 is not set
+# CONFIG_QLA3XXX is not set
#
# Ethernet (10000 Mbit)
@@ -744,6 +913,7 @@ CONFIG_8139_OLD_RX_RESET=y
# CONFIG_CHELSIO_T1 is not set
# CONFIG_IXGB is not set
# CONFIG_S2IO is not set
+# CONFIG_MYRI10GE is not set
#
# Token Ring devices
@@ -754,6 +924,7 @@ CONFIG_8139_OLD_RX_RESET=y
# Wireless LAN (non-hamradio)
#
CONFIG_NET_RADIO=y
+CONFIG_NET_WIRELESS_RTNETLINK=y
#
# Obsolete Wireless cards support (pre-802.11)
@@ -763,6 +934,8 @@ CONFIG_NET_RADIO=y
#
# Wireless 802.11b ISA/PCI cards support
#
+# CONFIG_IPW2100 is not set
+# CONFIG_IPW2200 is not set
# CONFIG_HERMES is not set
# CONFIG_ATMEL is not set
@@ -770,7 +943,16 @@ CONFIG_NET_RADIO=y
# Prism GT/Duette 802.11(a/b/g) PCI/Cardbus support
#
CONFIG_PRISM54=m
+# CONFIG_USB_ZD1201 is not set
# CONFIG_HOSTAP is not set
+CONFIG_BCM43XX=m
+CONFIG_BCM43XX_DEBUG=y
+CONFIG_BCM43XX_DMA=y
+CONFIG_BCM43XX_PIO=y
+CONFIG_BCM43XX_DMA_AND_PIO_MODE=y
+# CONFIG_BCM43XX_DMA_MODE is not set
+# CONFIG_BCM43XX_PIO_MODE is not set
+# CONFIG_ZD1211RW is not set
CONFIG_NET_WIRELESS=y
#
@@ -786,8 +968,13 @@ CONFIG_PPP_ASYNC=m
CONFIG_PPP_SYNC_TTY=m
CONFIG_PPP_DEFLATE=m
CONFIG_PPP_BSDCOMP=m
+CONFIG_PPP_MPPE=m
CONFIG_PPPOE=m
-# CONFIG_SLIP is not set
+CONFIG_SLIP=m
+CONFIG_SLIP_COMPRESSED=y
+CONFIG_SLHC=m
+CONFIG_SLIP_SMART=y
+# CONFIG_SLIP_MODE_SLIP6 is not set
# CONFIG_NET_FC is not set
# CONFIG_SHAPER is not set
# CONFIG_NETCONSOLE is not set
@@ -808,6 +995,7 @@ CONFIG_PPPOE=m
# Input device support
#
CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
#
# Userland interfaces
@@ -842,6 +1030,7 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
CONFIG_VT=y
CONFIG_VT_CONSOLE=y
CONFIG_HW_CONSOLE=y
+# CONFIG_VT_HW_CONSOLE_BINDING is not set
# CONFIG_SERIAL_NONSTANDARD is not set
#
@@ -853,6 +1042,7 @@ CONFIG_HW_CONSOLE=y
# Non-8250 serial port support
#
CONFIG_SERIAL_SH_SCI=y
+CONFIG_SERIAL_SH_SCI_NR_UARTS=2
CONFIG_SERIAL_SH_SCI_CONSOLE=y
CONFIG_SERIAL_CORE=y
CONFIG_SERIAL_CORE_CONSOLE=y
@@ -869,8 +1059,27 @@ CONFIG_LEGACY_PTY_COUNT=256
#
# Watchdog Cards
#
-# CONFIG_WATCHDOG is not set
-# CONFIG_RTC is not set
+CONFIG_WATCHDOG=y
+# CONFIG_WATCHDOG_NOWAYOUT is not set
+
+#
+# Watchdog Device Drivers
+#
+# CONFIG_SOFT_WATCHDOG is not set
+CONFIG_SH_WDT=m
+# CONFIG_SH_WDT_MMAP is not set
+
+#
+# PCI-based Watchdog Cards
+#
+# CONFIG_PCIPCWATCHDOG is not set
+# CONFIG_WDTPCI is not set
+
+#
+# USB-based Watchdog Cards
+#
+# CONFIG_USBPCWATCHDOG is not set
+CONFIG_HW_RANDOM=y
# CONFIG_GEN_RTC is not set
# CONFIG_DTLK is not set
# CONFIG_R3964 is not set
@@ -886,6 +1095,7 @@ CONFIG_LEGACY_PTY_COUNT=256
# TPM devices
#
# CONFIG_TCG_TPM is not set
+# CONFIG_TELCLOCK is not set
#
# I2C support
@@ -893,6 +1103,12 @@ CONFIG_LEGACY_PTY_COUNT=256
# CONFIG_I2C is not set
#
+# SPI support
+#
+# CONFIG_SPI is not set
+# CONFIG_SPI_MASTER is not set
+
+#
# Dallas's 1-wire bus
#
# CONFIG_W1 is not set
@@ -902,6 +1118,9 @@ CONFIG_LEGACY_PTY_COUNT=256
#
CONFIG_HWMON=y
# CONFIG_HWMON_VID is not set
+# CONFIG_SENSORS_ABITUGURU is not set
+# CONFIG_SENSORS_F71805F is not set
+# CONFIG_SENSORS_VT1211 is not set
# CONFIG_HWMON_DEBUG_CHIP is not set
#
@@ -909,28 +1128,28 @@ CONFIG_HWMON=y
#
#
-# Multimedia Capabilities Port drivers
-#
-
-#
# Multimedia devices
#
# CONFIG_VIDEO_DEV is not set
+CONFIG_VIDEO_V4L2=y
#
# Digital Video Broadcasting Devices
#
# CONFIG_DVB is not set
+# CONFIG_USB_DABUSB is not set
#
# Graphics support
#
+CONFIG_FIRMWARE_EDID=y
# CONFIG_FB is not set
#
# Console display driver support
#
CONFIG_DUMMY_CONSOLE=y
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
#
# Sound
@@ -942,7 +1161,8 @@ CONFIG_DUMMY_CONSOLE=y
#
CONFIG_USB_ARCH_HAS_HCD=y
CONFIG_USB_ARCH_HAS_OHCI=y
-CONFIG_USB=m
+CONFIG_USB_ARCH_HAS_EHCI=y
+CONFIG_USB=y
# CONFIG_USB_DEBUG is not set
#
@@ -956,11 +1176,12 @@ CONFIG_USB_DEVICEFS=y
#
# USB Host Controller Drivers
#
-CONFIG_USB_EHCI_HCD=m
+CONFIG_USB_EHCI_HCD=y
# CONFIG_USB_EHCI_SPLIT_ISO is not set
# CONFIG_USB_EHCI_ROOT_HUB_TT is not set
+# CONFIG_USB_EHCI_TT_NEWSCHED is not set
# CONFIG_USB_ISP116X_HCD is not set
-CONFIG_USB_OHCI_HCD=m
+CONFIG_USB_OHCI_HCD=y
# CONFIG_USB_OHCI_BIG_ENDIAN is not set
CONFIG_USB_OHCI_LITTLE_ENDIAN=y
# CONFIG_USB_UHCI_HCD is not set
@@ -969,14 +1190,17 @@ CONFIG_USB_OHCI_LITTLE_ENDIAN=y
#
# USB Device Class drivers
#
-# CONFIG_USB_BLUETOOTH_TTY is not set
-# CONFIG_USB_ACM is not set
-# CONFIG_USB_PRINTER is not set
+CONFIG_USB_ACM=m
+CONFIG_USB_PRINTER=m
#
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
#
-CONFIG_USB_STORAGE=m
+
+#
+# may also be needed; see USB_STORAGE Help for more information
+#
+CONFIG_USB_STORAGE=y
# CONFIG_USB_STORAGE_DEBUG is not set
# CONFIG_USB_STORAGE_DATAFAB is not set
# CONFIG_USB_STORAGE_FREECOM is not set
@@ -985,6 +1209,9 @@ CONFIG_USB_STORAGE=m
# CONFIG_USB_STORAGE_SDDR09 is not set
# CONFIG_USB_STORAGE_SDDR55 is not set
# CONFIG_USB_STORAGE_JUMPSHOT is not set
+# CONFIG_USB_STORAGE_ALAUDA is not set
+# CONFIG_USB_STORAGE_KARMA is not set
+# CONFIG_USB_LIBUSUAL is not set
#
# USB Input Devices
@@ -1001,14 +1228,14 @@ CONFIG_USB_STORAGE=m
# CONFIG_USB_ACECAD is not set
# CONFIG_USB_KBTAB is not set
# CONFIG_USB_POWERMATE is not set
-# CONFIG_USB_MTOUCH is not set
-# CONFIG_USB_ITMTOUCH is not set
-# CONFIG_USB_EGALAX is not set
+# CONFIG_USB_TOUCHSCREEN is not set
# CONFIG_USB_YEALINK is not set
# CONFIG_USB_XPAD is not set
# CONFIG_USB_ATI_REMOTE is not set
+# CONFIG_USB_ATI_REMOTE2 is not set
# CONFIG_USB_KEYSPAN_REMOTE is not set
# CONFIG_USB_APPLETOUCH is not set
+# CONFIG_USB_TRANCEVIBRATOR is not set
#
# USB Imaging devices
@@ -1017,15 +1244,6 @@ CONFIG_USB_STORAGE=m
# CONFIG_USB_MICROTEK is not set
#
-# USB Multimedia devices
-#
-# CONFIG_USB_DABUSB is not set
-
-#
-# Video4Linux support is needed for USB Multimedia device support
-#
-
-#
# USB Network Adapters
#
# CONFIG_USB_CATC is not set
@@ -1033,7 +1251,6 @@ CONFIG_USB_STORAGE=m
# CONFIG_USB_PEGASUS is not set
# CONFIG_USB_RTL8150 is not set
# CONFIG_USB_USBNET is not set
-# CONFIG_USB_ZD1201 is not set
CONFIG_USB_MON=y
#
@@ -1045,7 +1262,9 @@ CONFIG_USB_MON=y
#
CONFIG_USB_SERIAL=m
CONFIG_USB_SERIAL_GENERIC=y
+# CONFIG_USB_SERIAL_AIRCABLE is not set
# CONFIG_USB_SERIAL_AIRPRIME is not set
+CONFIG_USB_SERIAL_ARK3116=m
# CONFIG_USB_SERIAL_BELKIN is not set
# CONFIG_USB_SERIAL_WHITEHEAT is not set
# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set
@@ -1053,6 +1272,7 @@ CONFIG_USB_SERIAL_GENERIC=y
# CONFIG_USB_SERIAL_CYPRESS_M8 is not set
# CONFIG_USB_SERIAL_EMPEG is not set
# CONFIG_USB_SERIAL_FTDI_SIO is not set
+# CONFIG_USB_SERIAL_FUNSOFT is not set
# CONFIG_USB_SERIAL_VISOR is not set
# CONFIG_USB_SERIAL_IPAQ is not set
# CONFIG_USB_SERIAL_IR is not set
@@ -1065,12 +1285,16 @@ CONFIG_USB_SERIAL_GENERIC=y
# CONFIG_USB_SERIAL_KLSI is not set
# CONFIG_USB_SERIAL_KOBIL_SCT is not set
# CONFIG_USB_SERIAL_MCT_U232 is not set
+# CONFIG_USB_SERIAL_MOS7840 is not set
+# CONFIG_USB_SERIAL_NAVMAN is not set
CONFIG_USB_SERIAL_PL2303=m
# CONFIG_USB_SERIAL_HP4X is not set
# CONFIG_USB_SERIAL_SAFE is not set
+# CONFIG_USB_SERIAL_SIERRAWIRELESS is not set
# CONFIG_USB_SERIAL_TI is not set
# CONFIG_USB_SERIAL_CYBERJACK is not set
# CONFIG_USB_SERIAL_XIRCOM is not set
+# CONFIG_USB_SERIAL_OPTION is not set
# CONFIG_USB_SERIAL_OMNINET is not set
#
@@ -1078,15 +1302,18 @@ CONFIG_USB_SERIAL_PL2303=m
#
# CONFIG_USB_EMI62 is not set
# CONFIG_USB_EMI26 is not set
+# CONFIG_USB_ADUTUX is not set
# CONFIG_USB_AUERSWALD is not set
# CONFIG_USB_RIO500 is not set
# CONFIG_USB_LEGOTOWER is not set
# CONFIG_USB_LCD is not set
# CONFIG_USB_LED is not set
+# CONFIG_USB_CYPRESS_CY7C63 is not set
# CONFIG_USB_CYTHERM is not set
-# CONFIG_USB_PHIDGETKIT is not set
-# CONFIG_USB_PHIDGETSERVO is not set
+# CONFIG_USB_PHIDGET is not set
# CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_FTDI_ELAN is not set
+# CONFIG_USB_APPLEDISPLAY is not set
# CONFIG_USB_SISUSBVGA is not set
# CONFIG_USB_LD is not set
# CONFIG_USB_TEST is not set
@@ -1106,39 +1333,71 @@ CONFIG_USB_SERIAL_PL2303=m
# CONFIG_MMC is not set
#
+# LED devices
+#
+# CONFIG_NEW_LEDS is not set
+
+#
+# LED drivers
+#
+
+#
+# LED Triggers
+#
+
+#
# InfiniBand support
#
# CONFIG_INFINIBAND is not set
#
-# SN Devices
+# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
+#
+
+#
+# Real Time Clock
+#
+# CONFIG_RTC_CLASS is not set
+
+#
+# DMA Engine support
+#
+# CONFIG_DMA_ENGINE is not set
+
+#
+# DMA Clients
+#
+
+#
+# DMA Devices
#
#
# File systems
#
CONFIG_EXT2_FS=y
-CONFIG_EXT2_FS_XATTR=y
-CONFIG_EXT2_FS_POSIX_ACL=y
-CONFIG_EXT2_FS_SECURITY=y
+# CONFIG_EXT2_FS_XATTR is not set
# CONFIG_EXT2_FS_XIP is not set
CONFIG_EXT3_FS=y
-CONFIG_EXT3_FS_XATTR=y
-CONFIG_EXT3_FS_POSIX_ACL=y
-CONFIG_EXT3_FS_SECURITY=y
+# CONFIG_EXT3_FS_XATTR is not set
CONFIG_JBD=y
# CONFIG_JBD_DEBUG is not set
-CONFIG_FS_MBCACHE=y
CONFIG_REISERFS_FS=m
# CONFIG_REISERFS_CHECK is not set
# CONFIG_REISERFS_PROC_INFO is not set
# CONFIG_REISERFS_FS_XATTR is not set
# CONFIG_JFS_FS is not set
-CONFIG_FS_POSIX_ACL=y
-# CONFIG_XFS_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
+CONFIG_XFS_FS=m
+# CONFIG_XFS_QUOTA is not set
+# CONFIG_XFS_SECURITY is not set
+# CONFIG_XFS_POSIX_ACL is not set
+# CONFIG_XFS_RT is not set
+# CONFIG_OCFS2_FS is not set
# CONFIG_MINIX_FS is not set
# CONFIG_ROMFS_FS is not set
CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
# CONFIG_QUOTA is not set
CONFIG_DNOTIFY=y
# CONFIG_AUTOFS_FS is not set
@@ -1170,12 +1429,14 @@ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
#
CONFIG_PROC_FS=y
CONFIG_PROC_KCORE=y
+CONFIG_PROC_SYSCTL=y
CONFIG_SYSFS=y
CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
# CONFIG_HUGETLBFS is not set
# CONFIG_HUGETLB_PAGE is not set
CONFIG_RAMFS=y
-CONFIG_RELAYFS_FS=m
+CONFIG_CONFIGFS_FS=m
#
# Miscellaneous filesystems
@@ -1187,6 +1448,8 @@ CONFIG_RELAYFS_FS=m
# CONFIG_BEFS_FS is not set
# CONFIG_BFS_FS is not set
# CONFIG_EFS_FS is not set
+# CONFIG_JFFS_FS is not set
+# CONFIG_JFFS2_FS is not set
# CONFIG_CRAMFS is not set
# CONFIG_VXFS_FS is not set
# CONFIG_HPFS_FS is not set
@@ -1241,6 +1504,7 @@ CONFIG_MSDOS_PARTITION=y
# CONFIG_SGI_PARTITION is not set
# CONFIG_ULTRIX_PARTITION is not set
# CONFIG_SUN_PARTITION is not set
+# CONFIG_KARMA_PARTITION is not set
# CONFIG_EFI_PARTITION is not set
#
@@ -1296,21 +1560,36 @@ CONFIG_NLS_UTF8=m
# Kernel hacking
#
# CONFIG_PRINTK_TIME is not set
-CONFIG_DEBUG_KERNEL=y
+CONFIG_ENABLE_MUST_CHECK=y
CONFIG_MAGIC_SYSRQ=y
+# CONFIG_UNUSED_SYMBOLS is not set
+CONFIG_DEBUG_KERNEL=y
CONFIG_LOG_BUF_SHIFT=16
# CONFIG_DETECT_SOFTLOCKUP is not set
# CONFIG_SCHEDSTATS is not set
-CONFIG_DEBUG_SLAB=y
+# CONFIG_DEBUG_SLAB is not set
+# CONFIG_DEBUG_RT_MUTEXES is not set
+# CONFIG_RT_MUTEX_TESTER is not set
# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_MUTEXES is not set
+# CONFIG_DEBUG_RWSEMS is not set
# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
# CONFIG_DEBUG_KOBJECT is not set
+# CONFIG_DEBUG_BUGVERBOSE is not set
# CONFIG_DEBUG_INFO is not set
# CONFIG_DEBUG_FS is not set
+# CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_LIST is not set
# CONFIG_FRAME_POINTER is not set
+# CONFIG_FORCED_INLINING is not set
+# CONFIG_RCU_TORTURE_TEST is not set
# CONFIG_SH_STANDARD_BIOS is not set
CONFIG_EARLY_SCIF_CONSOLE=y
# CONFIG_EARLY_PRINTK is not set
+# CONFIG_DEBUG_STACKOVERFLOW is not set
+# CONFIG_DEBUG_STACK_USAGE is not set
+# CONFIG_4KSTACKS is not set
# CONFIG_KGDB is not set
#
@@ -1323,28 +1602,35 @@ CONFIG_EARLY_SCIF_CONSOLE=y
# Cryptographic options
#
CONFIG_CRYPTO=y
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_BLKCIPHER=y
+CONFIG_CRYPTO_HASH=y
+CONFIG_CRYPTO_MANAGER=m
CONFIG_CRYPTO_HMAC=y
-# CONFIG_CRYPTO_NULL is not set
+CONFIG_CRYPTO_NULL=m
CONFIG_CRYPTO_MD4=m
-CONFIG_CRYPTO_MD5=m
-CONFIG_CRYPTO_SHA1=m
+CONFIG_CRYPTO_MD5=y
+CONFIG_CRYPTO_SHA1=y
CONFIG_CRYPTO_SHA256=m
CONFIG_CRYPTO_SHA512=m
CONFIG_CRYPTO_WP512=m
CONFIG_CRYPTO_TGR192=m
-CONFIG_CRYPTO_DES=m
+CONFIG_CRYPTO_ECB=m
+CONFIG_CRYPTO_CBC=y
+CONFIG_CRYPTO_DES=y
CONFIG_CRYPTO_BLOWFISH=m
CONFIG_CRYPTO_TWOFISH=m
+CONFIG_CRYPTO_TWOFISH_COMMON=m
CONFIG_CRYPTO_SERPENT=m
-CONFIG_CRYPTO_AES=m
+CONFIG_CRYPTO_AES=y
CONFIG_CRYPTO_CAST5=m
CONFIG_CRYPTO_CAST6=m
CONFIG_CRYPTO_TEA=m
-CONFIG_CRYPTO_ARC4=m
+CONFIG_CRYPTO_ARC4=y
CONFIG_CRYPTO_KHAZAD=m
CONFIG_CRYPTO_ANUBIS=m
-CONFIG_CRYPTO_DEFLATE=m
-CONFIG_CRYPTO_MICHAEL_MIC=m
+CONFIG_CRYPTO_DEFLATE=y
+CONFIG_CRYPTO_MICHAEL_MIC=y
CONFIG_CRYPTO_CRC32C=m
# CONFIG_CRYPTO_TEST is not set
@@ -1359,9 +1645,10 @@ CONFIG_CRC_CCITT=m
CONFIG_CRC16=m
CONFIG_CRC32=y
CONFIG_LIBCRC32C=m
-CONFIG_ZLIB_INFLATE=m
-CONFIG_ZLIB_DEFLATE=m
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
CONFIG_TEXTSEARCH=y
CONFIG_TEXTSEARCH_KMP=m
CONFIG_TEXTSEARCH_BM=m
CONFIG_TEXTSEARCH_FSM=m
+CONFIG_PLIST=y
diff --git a/arch/sh/drivers/dma/dma-sysfs.c b/arch/sh/drivers/dma/dma-sysfs.c
index 70a5d82eb2f8..29b8ef9873d1 100644
--- a/arch/sh/drivers/dma/dma-sysfs.c
+++ b/arch/sh/drivers/dma/dma-sysfs.c
@@ -48,12 +48,11 @@ static int __init dma_sysclass_init(void)
int ret;
ret = sysdev_class_register(&dma_sysclass);
- if (ret == 0)
- sysfs_create_file(&dma_sysclass.kset.kobj, &attr_devices.attr);
+ if (unlikely(ret))
+ return ret;
- return ret;
+ return sysfs_create_file(&dma_sysclass.kset.kobj, &attr_devices.attr);
}
-
postcore_initcall(dma_sysclass_init);
static ssize_t dma_show_dev_id(struct sys_device *dev, char *buf)
@@ -152,4 +151,3 @@ void dma_remove_sysfs_files(struct dma_channel *chan, struct dma_info *info)
sysdev_unregister(dev);
}
-
diff --git a/arch/sh/drivers/pci/ops-landisk.c b/arch/sh/drivers/pci/ops-landisk.c
index ada301c21fe7..d06030815a96 100644
--- a/arch/sh/drivers/pci/ops-landisk.c
+++ b/arch/sh/drivers/pci/ops-landisk.c
@@ -8,7 +8,6 @@
* May be copied or modified under the terms of the GNU General Public
* License. See linux/COPYING for more information.
*/
-#include <linux/config.h>
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/init.h>
diff --git a/arch/sh/drivers/pci/ops-r7780rp.c b/arch/sh/drivers/pci/ops-r7780rp.c
index 554d5ed2c586..6e3ba9c65b40 100644
--- a/arch/sh/drivers/pci/ops-r7780rp.c
+++ b/arch/sh/drivers/pci/ops-r7780rp.c
@@ -8,8 +8,6 @@
*
* PCI initialization for the Renesas SH7780 Highlander R7780RP-1 board
*/
-
-#include <linux/config.h>
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/init.h>
diff --git a/arch/sh/drivers/pci/ops-sh03.c b/arch/sh/drivers/pci/ops-sh03.c
index e58d556e5f94..ebb58e605d9d 100644
--- a/arch/sh/drivers/pci/ops-sh03.c
+++ b/arch/sh/drivers/pci/ops-sh03.c
@@ -35,10 +35,10 @@ static struct resource sh7751_mem_resource = {
.flags = IORESOURCE_MEM
};
-extern struct pci_ops sh7751_pci_ops;
+extern struct pci_ops sh4_pci_ops;
struct pci_channel board_pci_channels[] = {
- { &sh7751_pci_ops, &sh7751_io_resource, &sh7751_mem_resource, 0, 0xff },
+ { &sh4_pci_ops, &sh7751_io_resource, &sh7751_mem_resource, 0, 0xff },
{ NULL, NULL, NULL, 0, 0 },
};
diff --git a/arch/sh/drivers/pci/ops-titan.c b/arch/sh/drivers/pci/ops-titan.c
index c6097bcd97fd..cd56d53375e7 100644
--- a/arch/sh/drivers/pci/ops-titan.c
+++ b/arch/sh/drivers/pci/ops-titan.c
@@ -11,8 +11,6 @@
*
* PCI initialization for the Titan boards
*/
-
-#include <linux/config.h>
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/init.h>
diff --git a/arch/sh/drivers/pci/pci-sh7780.c b/arch/sh/drivers/pci/pci-sh7780.c
index bd3064a82087..d6e635296534 100644
--- a/arch/sh/drivers/pci/pci-sh7780.c
+++ b/arch/sh/drivers/pci/pci-sh7780.c
@@ -12,10 +12,8 @@
* License. See linux/COPYING for more information.
*
*/
-
#undef DEBUG
-#include <linux/config.h>
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/init.h>
diff --git a/arch/sh/kernel/apm.c b/arch/sh/kernel/apm.c
index 871e7d640002..4f66f91b1006 100644
--- a/arch/sh/kernel/apm.c
+++ b/arch/sh/kernel/apm.c
@@ -16,7 +16,6 @@
* [This document is available from Microsoft at:
* http://www.microsoft.com/hwdev/busbios/amp_12.htm]
*/
-#include <linux/config.h>
#include <linux/module.h>
#include <linux/poll.h>
#include <linux/timer.h>
diff --git a/arch/sh/kernel/entry.S b/arch/sh/kernel/entry.S
index fe8221855b28..97c571fbcdf1 100644
--- a/arch/sh/kernel/entry.S
+++ b/arch/sh/kernel/entry.S
@@ -10,8 +10,8 @@
* for more details.
*
*/
-
#include <linux/sys.h>
+#include <linux/errno.h>
#include <linux/linkage.h>
#include <asm/asm-offsets.h>
#include <asm/thread_info.h>
@@ -53,10 +53,6 @@
* syscall #
*
*/
-
-ENOSYS = 38
-EINVAL = 22
-
#if defined(CONFIG_KGDB_NMI)
NMI_VEC = 0x1c0 ! Must catch early for debounce
#endif
diff --git a/arch/sh/kernel/setup.c b/arch/sh/kernel/setup.c
index 5f587332234a..36d86f9ac38a 100644
--- a/arch/sh/kernel/setup.c
+++ b/arch/sh/kernel/setup.c
@@ -1,5 +1,4 @@
-/* $Id: setup.c,v 1.30 2003/10/13 07:21:19 lethal Exp $
- *
+/*
* linux/arch/sh/kernel/setup.c
*
* Copyright (C) 1999 Niibe Yutaka
@@ -21,6 +20,7 @@
#include <linux/utsname.h>
#include <linux/cpu.h>
#include <linux/pfn.h>
+#include <linux/fs.h>
#include <asm/uaccess.h>
#include <asm/io.h>
#include <asm/sections.h>
@@ -459,7 +459,7 @@ static int show_cpuinfo(struct seq_file *m, void *v)
seq_printf(m, "machine\t\t: %s\n", get_system_type());
seq_printf(m, "processor\t: %d\n", cpu);
- seq_printf(m, "cpu family\t: %s\n", system_utsname.machine);
+ seq_printf(m, "cpu family\t: %s\n", init_utsname()->machine);
seq_printf(m, "cpu type\t: %s\n", get_cpu_subtype());
show_cpuflags(m);
diff --git a/arch/sh/kernel/sh_ksyms.c b/arch/sh/kernel/sh_ksyms.c
index d3cbfa2ad4a7..9daad70bc305 100644
--- a/arch/sh/kernel/sh_ksyms.c
+++ b/arch/sh/kernel/sh_ksyms.c
@@ -72,6 +72,7 @@ DECLARE_EXPORT(__ashrdi3);
DECLARE_EXPORT(__ashldi3);
DECLARE_EXPORT(__lshrdi3);
DECLARE_EXPORT(__movstr);
+DECLARE_EXPORT(__movstrSI16);
EXPORT_SYMBOL(strcpy);
diff --git a/arch/sh/kernel/smp.c b/arch/sh/kernel/smp.c
index 6c0fb7c4af11..dbebaddcfe39 100644
--- a/arch/sh/kernel/smp.c
+++ b/arch/sh/kernel/smp.c
@@ -42,6 +42,7 @@ cpumask_t cpu_possible_map;
EXPORT_SYMBOL(cpu_possible_map);
cpumask_t cpu_online_map;
+EXPORT_SYMBOL(cpu_online_map);
static atomic_t cpus_booted = ATOMIC_INIT(0);
/* These are defined by the board-specific code. */
diff --git a/arch/sh/kernel/sys_sh.c b/arch/sh/kernel/sys_sh.c
index b68ff705f067..8fde95001c34 100644
--- a/arch/sh/kernel/sys_sh.c
+++ b/arch/sh/kernel/sys_sh.c
@@ -25,6 +25,7 @@
#include <asm/cacheflush.h>
#include <asm/uaccess.h>
#include <asm/ipc.h>
+#include <asm/unistd.h>
/*
* sys_pipe() is the normal C calling standard for creating
@@ -281,7 +282,7 @@ asmlinkage int sys_uname(struct old_utsname * name)
if (!name)
return -EFAULT;
down_read(&uts_sem);
- err=copy_to_user(name, &system_utsname, sizeof (*name));
+ err = copy_to_user(name, utsname(), sizeof (*name));
up_read(&uts_sem);
return err?-EFAULT:0;
}
@@ -309,3 +310,19 @@ asmlinkage int sys_fadvise64_64_wrapper(int fd, u32 offset0, u32 offset1,
(u64)len0 << 32 | len1, advice);
#endif
}
+
+/*
+ * Do a system call from kernel instead of calling sys_execve so we
+ * end up with proper pt_regs.
+ */
+int kernel_execve(const char *filename, char *const argv[], char *const envp[])
+{
+ register long __sc0 __asm__ ("r3") = __NR_execve;
+ register long __sc4 __asm__ ("r4") = (long) filename;
+ register long __sc5 __asm__ ("r5") = (long) argv;
+ register long __sc6 __asm__ ("r6") = (long) envp;
+ __asm__ __volatile__ ("trapa #0x13" : "=z" (__sc0)
+ : "0" (__sc0), "r" (__sc4), "r" (__sc5), "r" (__sc6)
+ : "memory");
+ return __sc0;
+}
diff --git a/arch/sh/kernel/time.c b/arch/sh/kernel/time.c
index 149d9713eddf..450c68f1df05 100644
--- a/arch/sh/kernel/time.c
+++ b/arch/sh/kernel/time.c
@@ -18,7 +18,6 @@
#include <asm/timer.h>
#include <asm/kgdb.h>
-extern unsigned long wall_jiffies;
struct sys_timer *sys_timer;
/* Move this somewhere more sensible.. */
@@ -52,16 +51,10 @@ void do_gettimeofday(struct timeval *tv)
{
unsigned long seq;
unsigned long usec, sec;
- unsigned long lost;
do {
seq = read_seqbegin(&xtime_lock);
usec = get_timer_offset();
-
- lost = jiffies - wall_jiffies;
- if (lost)
- usec += lost * (1000000 / HZ);
-
sec = xtime.tv_sec;
usec += xtime.tv_nsec / 1000;
} while (read_seqretry(&xtime_lock, seq));
@@ -91,8 +84,7 @@ int do_settimeofday(struct timespec *tv)
* wall time. Discover what correction gettimeofday() would have
* made, and then undo it!
*/
- nsec -= 1000 * (get_timer_offset() +
- (jiffies - wall_jiffies) * (1000000 / HZ));
+ nsec -= 1000 * get_timer_offset();
wtm_sec = wall_to_monotonic.tv_sec + (xtime.tv_sec - sec);
wtm_nsec = wall_to_monotonic.tv_nsec + (xtime.tv_nsec - nsec);
@@ -117,7 +109,7 @@ static long last_rtc_update;
*/
void handle_timer_tick(struct pt_regs *regs)
{
- do_timer(regs);
+ do_timer(1);
#ifndef CONFIG_SMP
update_process_times(user_mode(regs));
#endif
diff --git a/arch/sh/kernel/vsyscall/.gitignore b/arch/sh/kernel/vsyscall/.gitignore
new file mode 100644
index 000000000000..40836ad9079c
--- /dev/null
+++ b/arch/sh/kernel/vsyscall/.gitignore
@@ -0,0 +1 @@
+vsyscall.lds
diff --git a/arch/sh/math-emu/math.c b/arch/sh/math-emu/math.c
index 26b6046814fd..1efbac15ff4e 100644
--- a/arch/sh/math-emu/math.c
+++ b/arch/sh/math-emu/math.c
@@ -7,7 +7,6 @@
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*/
-#include <linux/config.h>
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/types.h>
diff --git a/arch/sh/mm/cache-debugfs.c b/arch/sh/mm/cache-debugfs.c
index a22d914e4d15..e0122bd33ddb 100644
--- a/arch/sh/mm/cache-debugfs.c
+++ b/arch/sh/mm/cache-debugfs.c
@@ -111,7 +111,7 @@ static int cache_seq_show(struct seq_file *file, void *iter)
static int cache_debugfs_open(struct inode *inode, struct file *file)
{
- return single_open(file, cache_seq_show, inode->u.generic_ip);
+ return single_open(file, cache_seq_show, inode->i_private);
}
static struct file_operations cache_debugfs_fops = {
diff --git a/arch/sh/mm/fault.c b/arch/sh/mm/fault.c
index c69fd603226a..68663b8f99ae 100644
--- a/arch/sh/mm/fault.c
+++ b/arch/sh/mm/fault.c
@@ -69,7 +69,7 @@ good_area:
if (!(vma->vm_flags & VM_WRITE))
goto bad_area;
} else {
- if (!(vma->vm_flags & (VM_READ | VM_EXEC)))
+ if (!(vma->vm_flags & (VM_READ | VM_EXEC | VM_WRITE)))
goto bad_area;
}
@@ -149,7 +149,7 @@ no_context:
*/
out_of_memory:
up_read(&mm->mmap_sem);
- if (current->pid == 1) {
+ if (is_init(current)) {
yield();
down_read(&mm->mmap_sem);
goto survive;
diff --git a/arch/sh/tools/gen-mach-types b/arch/sh/tools/gen-mach-types
index bb2b82234e83..65161e368353 100644
--- a/arch/sh/tools/gen-mach-types
+++ b/arch/sh/tools/gen-mach-types
@@ -20,8 +20,6 @@ END {
printf("#ifndef __ASM_SH_MACHTYPES_H\n");
printf("#define __ASM_SH_MACHTYPES_H\n");
printf("\n");
- printf("#include <linux/config.h>\n");
- printf("\n");
printf("/*\n");
printf(" * We'll use the following MACH_xxx defs for placeholders for the time\n");
printf(" * being .. these will all go away once sh_machtype is assigned per-board.\n");
diff --git a/arch/sh64/configs/cayman_defconfig b/arch/sh64/configs/cayman_defconfig
index 48f27407d5e4..d81df574a7f7 100644
--- a/arch/sh64/configs/cayman_defconfig
+++ b/arch/sh64/configs/cayman_defconfig
@@ -1,49 +1,62 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.11
-# Fri Feb 25 18:14:31 2005
+# Linux kernel version: 2.6.18
+# Tue Oct 3 13:30:51 2006
#
CONFIG_SUPERH=y
CONFIG_SUPERH64=y
CONFIG_MMU=y
-CONFIG_UID16=y
CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+CONFIG_GENERIC_HWEIGHT=y
CONFIG_GENERIC_CALIBRATE_DELAY=y
-CONFIG_LOG_BUF_SHIFT=14
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
#
# Code maturity level options
#
CONFIG_EXPERIMENTAL=y
-CONFIG_CLEAN_COMPILE=y
CONFIG_BROKEN_ON_SMP=y
+CONFIG_LOCK_KERNEL=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
#
# General setup
#
CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
CONFIG_SWAP=y
# CONFIG_SYSVIPC is not set
CONFIG_POSIX_MQUEUE=y
# CONFIG_BSD_PROCESS_ACCT is not set
-CONFIG_SYSCTL=y
+# CONFIG_TASKSTATS is not set
+# CONFIG_UTS_NS is not set
# CONFIG_AUDIT is not set
-# CONFIG_HOTPLUG is not set
-CONFIG_KOBJECT_UEVENT=y
# CONFIG_IKCONFIG is not set
+# CONFIG_RELAY is not set
+CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SYSCTL=y
# CONFIG_EMBEDDED is not set
+CONFIG_UID16=y
+# CONFIG_SYSCTL_SYSCALL is not set
CONFIG_KALLSYMS=y
# CONFIG_KALLSYMS_ALL is not set
# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
CONFIG_EPOLL=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
CONFIG_SHMEM=y
-CONFIG_CC_ALIGN_FUNCTIONS=0
-CONFIG_CC_ALIGN_LABELS=0
-CONFIG_CC_ALIGN_LOOPS=0
-CONFIG_CC_ALIGN_JUMPS=0
+CONFIG_SLAB=y
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_RT_MUTEXES=y
# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+# CONFIG_SLOB is not set
#
# Loadable module support
@@ -51,6 +64,27 @@ CONFIG_CC_ALIGN_JUMPS=0
# CONFIG_MODULES is not set
#
+# Block layer
+#
+CONFIG_BLOCK=y
+# CONFIG_LBD is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_LSF is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+# CONFIG_DEFAULT_AS is not set
+# CONFIG_DEFAULT_DEADLINE is not set
+CONFIG_DEFAULT_CFQ=y
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="cfq"
+
+#
# System type
#
# CONFIG_SH_GENERIC is not set
@@ -103,15 +137,23 @@ CONFIG_HEARTBEAT=y
CONFIG_HDSP253_LED=y
CONFIG_SH_DMA=y
CONFIG_PREEMPT=y
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+# CONFIG_SPARSEMEM_STATIC is not set
+CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_RESOURCES_64BIT is not set
#
# Bus options (PCI, PCMCIA, EISA, MCA, ISA)
#
-CONFIG_SUPERHYWAY=y
CONFIG_PCI=y
CONFIG_SH_PCIDMA_NONCOHERENT=y
-CONFIG_PCI_LEGACY_PROC=y
-CONFIG_PCI_NAMES=y
+# CONFIG_PCI_MULTITHREAD_PROBE is not set
+# CONFIG_PCI_DEBUG is not set
#
# PCCARD (PCMCIA/CardBus) support
@@ -119,10 +161,6 @@ CONFIG_PCI_NAMES=y
# CONFIG_PCCARD is not set
#
-# PC-card bridges
-#
-
-#
# PCI Hotplug Support
#
# CONFIG_HOTPLUG_PCI is not set
@@ -135,6 +173,92 @@ CONFIG_BINFMT_ELF=y
# CONFIG_BINFMT_MISC is not set
#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+# CONFIG_NETDEBUG is not set
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+# CONFIG_XFRM_USER is not set
+# CONFIG_XFRM_SUB_POLICY is not set
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+# CONFIG_IP_PNP_DHCP is not set
+# CONFIG_IP_PNP_BOOTP is not set
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+# CONFIG_INET_TUNNEL is not set
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_IPV6 is not set
+# CONFIG_INET6_XFRM_TUNNEL is not set
+# CONFIG_INET6_TUNNEL is not set
+# CONFIG_NETWORK_SECMARK is not set
+# CONFIG_NETFILTER is not set
+
+#
+# DCCP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_DCCP is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP is not set
+
+#
+# TIPC Configuration (EXPERIMENTAL)
+#
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_IEEE80211 is not set
+
+#
# Device Drivers
#
@@ -145,6 +269,12 @@ CONFIG_STANDALONE=y
CONFIG_PREVENT_FIRMWARE_BUILD=y
# CONFIG_FW_LOADER is not set
# CONFIG_DEBUG_DRIVER is not set
+# CONFIG_SYS_HYPERVISOR is not set
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
+# CONFIG_CONNECTOR is not set
#
# Memory Technology Devices (MTD)
@@ -163,7 +293,6 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
#
# Block devices
#
-# CONFIG_BLK_DEV_FD is not set
# CONFIG_BLK_CPQ_DA is not set
# CONFIG_BLK_CPQ_CISS_DA is not set
# CONFIG_BLK_DEV_DAC960 is not set
@@ -176,18 +305,9 @@ CONFIG_BLK_DEV_LOOP=y
CONFIG_BLK_DEV_RAM=y
CONFIG_BLK_DEV_RAM_COUNT=16
CONFIG_BLK_DEV_RAM_SIZE=4096
+CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
# CONFIG_BLK_DEV_INITRD is not set
-CONFIG_INITRAMFS_SOURCE=""
-# CONFIG_LBD is not set
# CONFIG_CDROM_PKTCDVD is not set
-
-#
-# IO Schedulers
-#
-CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
-CONFIG_IOSCHED_DEADLINE=y
-CONFIG_IOSCHED_CFQ=y
# CONFIG_ATA_OVER_ETH is not set
#
@@ -198,7 +318,9 @@ CONFIG_IOSCHED_CFQ=y
#
# SCSI device support
#
+# CONFIG_RAID_ATTRS is not set
CONFIG_SCSI=y
+# CONFIG_SCSI_NETLINK is not set
CONFIG_SCSI_PROC_FS=y
#
@@ -209,6 +331,7 @@ CONFIG_BLK_DEV_SD=y
# CONFIG_CHR_DEV_OSST is not set
# CONFIG_BLK_DEV_SR is not set
# CONFIG_CHR_DEV_SG is not set
+# CONFIG_CHR_DEV_SCH is not set
#
# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
@@ -218,15 +341,18 @@ CONFIG_SCSI_MULTI_LUN=y
# CONFIG_SCSI_LOGGING is not set
#
-# SCSI Transport Attributes
+# SCSI Transports
#
CONFIG_SCSI_SPI_ATTRS=y
# CONFIG_SCSI_FC_ATTRS is not set
# CONFIG_SCSI_ISCSI_ATTRS is not set
+# CONFIG_SCSI_SAS_ATTRS is not set
+# CONFIG_SCSI_SAS_LIBSAS is not set
#
# SCSI low-level drivers
#
+# CONFIG_ISCSI_TCP is not set
# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
# CONFIG_SCSI_3W_9XXX is not set
# CONFIG_SCSI_ACARD is not set
@@ -234,40 +360,39 @@ CONFIG_SCSI_SPI_ATTRS=y
# CONFIG_SCSI_AIC7XXX is not set
# CONFIG_SCSI_AIC7XXX_OLD is not set
# CONFIG_SCSI_AIC79XX is not set
+# CONFIG_SCSI_AIC94XX is not set
# CONFIG_SCSI_DPT_I2O is not set
+# CONFIG_SCSI_ARCMSR is not set
# CONFIG_MEGARAID_NEWGEN is not set
# CONFIG_MEGARAID_LEGACY is not set
-# CONFIG_SCSI_SATA is not set
-# CONFIG_SCSI_BUSLOGIC is not set
+# CONFIG_MEGARAID_SAS is not set
+# CONFIG_SCSI_HPTIOP is not set
# CONFIG_SCSI_DMX3191D is not set
-# CONFIG_SCSI_EATA is not set
-# CONFIG_SCSI_EATA_PIO is not set
# CONFIG_SCSI_FUTURE_DOMAIN is not set
-# CONFIG_SCSI_GDTH is not set
# CONFIG_SCSI_IPS is not set
# CONFIG_SCSI_INITIO is not set
# CONFIG_SCSI_INIA100 is not set
+# CONFIG_SCSI_STEX is not set
CONFIG_SCSI_SYM53C8XX_2=y
CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=0
CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16
CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64
-# CONFIG_SCSI_SYM53C8XX_IOMAPPED is not set
+CONFIG_SCSI_SYM53C8XX_MMIO=y
# CONFIG_SCSI_IPR is not set
-# CONFIG_SCSI_QLOGIC_ISP is not set
-# CONFIG_SCSI_QLOGIC_FC is not set
# CONFIG_SCSI_QLOGIC_1280 is not set
-CONFIG_SCSI_QLA2XXX=y
-# CONFIG_SCSI_QLA21XX is not set
-# CONFIG_SCSI_QLA22XX is not set
-# CONFIG_SCSI_QLA2300 is not set
-# CONFIG_SCSI_QLA2322 is not set
-# CONFIG_SCSI_QLA6312 is not set
+# CONFIG_SCSI_QLA_FC is not set
+# CONFIG_SCSI_LPFC is not set
# CONFIG_SCSI_DC395x is not set
# CONFIG_SCSI_DC390T is not set
# CONFIG_SCSI_NSP32 is not set
# CONFIG_SCSI_DEBUG is not set
#
+# Serial ATA (prod) and Parallel ATA (experimental) drivers
+#
+# CONFIG_ATA is not set
+
+#
# Multi-device support (RAID and LVM)
#
# CONFIG_MD is not set
@@ -276,6 +401,9 @@ CONFIG_SCSI_QLA2XXX=y
# Fusion MPT device support
#
# CONFIG_FUSION is not set
+# CONFIG_FUSION_SPI is not set
+# CONFIG_FUSION_FC is not set
+# CONFIG_FUSION_SAS is not set
#
# IEEE 1394 (FireWire) support
@@ -288,70 +416,8 @@ CONFIG_SCSI_QLA2XXX=y
# CONFIG_I2O is not set
#
-# Networking support
-#
-CONFIG_NET=y
-
-#
-# Networking options
+# Network device support
#
-CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
-# CONFIG_NETLINK_DEV is not set
-CONFIG_UNIX=y
-# CONFIG_NET_KEY is not set
-CONFIG_INET=y
-# CONFIG_IP_MULTICAST is not set
-# CONFIG_IP_ADVANCED_ROUTER is not set
-CONFIG_IP_PNP=y
-# CONFIG_IP_PNP_DHCP is not set
-# CONFIG_IP_PNP_BOOTP is not set
-# CONFIG_IP_PNP_RARP is not set
-# CONFIG_NET_IPIP is not set
-# CONFIG_NET_IPGRE is not set
-# CONFIG_ARPD is not set
-# CONFIG_SYN_COOKIES is not set
-# CONFIG_INET_AH is not set
-# CONFIG_INET_ESP is not set
-# CONFIG_INET_IPCOMP is not set
-# CONFIG_INET_TUNNEL is not set
-CONFIG_IP_TCPDIAG=y
-# CONFIG_IP_TCPDIAG_IPV6 is not set
-# CONFIG_IPV6 is not set
-# CONFIG_NETFILTER is not set
-
-#
-# SCTP Configuration (EXPERIMENTAL)
-#
-# CONFIG_IP_SCTP is not set
-# CONFIG_ATM is not set
-# CONFIG_BRIDGE is not set
-# CONFIG_VLAN_8021Q is not set
-# CONFIG_DECNET is not set
-# CONFIG_LLC2 is not set
-# CONFIG_IPX is not set
-# CONFIG_ATALK is not set
-# CONFIG_X25 is not set
-# CONFIG_LAPB is not set
-# CONFIG_NET_DIVERT is not set
-# CONFIG_ECONET is not set
-# CONFIG_WAN_ROUTER is not set
-
-#
-# QoS and/or fair queueing
-#
-# CONFIG_NET_SCHED is not set
-# CONFIG_NET_CLS_ROUTE is not set
-
-#
-# Network testing
-#
-# CONFIG_NET_PKTGEN is not set
-# CONFIG_NETPOLL is not set
-# CONFIG_NET_POLL_CONTROLLER is not set
-# CONFIG_HAMRADIO is not set
-# CONFIG_IRDA is not set
-# CONFIG_BT is not set
CONFIG_NETDEVICES=y
# CONFIG_DUMMY is not set
# CONFIG_BONDING is not set
@@ -364,6 +430,11 @@ CONFIG_NETDEVICES=y
# CONFIG_ARCNET is not set
#
+# PHY device support
+#
+# CONFIG_PHYLIB is not set
+
+#
# Ethernet (10 or 100Mbit)
#
CONFIG_NET_ETHERNET=y
@@ -371,7 +442,9 @@ CONFIG_NET_ETHERNET=y
# CONFIG_STNIC is not set
# CONFIG_HAPPYMEAL is not set
# CONFIG_SUNGEM is not set
+# CONFIG_CASSINI is not set
# CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_SMC91X is not set
#
# Tulip family network device support
@@ -385,6 +458,7 @@ CONFIG_TULIP=y
# CONFIG_DE4X5 is not set
# CONFIG_WINBOND_840 is not set
# CONFIG_DM9102 is not set
+# CONFIG_ULI526X is not set
# CONFIG_HP100 is not set
CONFIG_NET_PCI=y
# CONFIG_PCNET32 is not set
@@ -416,15 +490,22 @@ CONFIG_NET_PCI=y
# CONFIG_HAMACHI is not set
# CONFIG_YELLOWFIN is not set
# CONFIG_R8169 is not set
+# CONFIG_SIS190 is not set
+# CONFIG_SKGE is not set
+# CONFIG_SKY2 is not set
# CONFIG_SK98LIN is not set
# CONFIG_VIA_VELOCITY is not set
# CONFIG_TIGON3 is not set
+# CONFIG_BNX2 is not set
+# CONFIG_QLA3XXX is not set
#
# Ethernet (10000 Mbit)
#
+# CONFIG_CHELSIO_T1 is not set
# CONFIG_IXGB is not set
# CONFIG_S2IO is not set
+# CONFIG_MYRI10GE is not set
#
# Token Ring devices
@@ -447,6 +528,8 @@ CONFIG_NET_PCI=y
# CONFIG_NET_FC is not set
# CONFIG_SHAPER is not set
# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
#
# ISDN subsystem
@@ -462,6 +545,7 @@ CONFIG_NET_PCI=y
# Input device support
#
CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
#
# Userland interfaces
@@ -476,19 +560,6 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
# CONFIG_INPUT_EVBUG is not set
#
-# Input I/O drivers
-#
-# CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
-CONFIG_SERIO=y
-CONFIG_SERIO_I8042=y
-CONFIG_SERIO_SERPORT=y
-# CONFIG_SERIO_CT82C710 is not set
-# CONFIG_SERIO_PCIPS2 is not set
-CONFIG_SERIO_LIBPS2=y
-# CONFIG_SERIO_RAW is not set
-
-#
# Input Device Drivers
#
CONFIG_INPUT_KEYBOARD=y
@@ -497,6 +568,7 @@ CONFIG_KEYBOARD_ATKBD=y
# CONFIG_KEYBOARD_LKKBD is not set
# CONFIG_KEYBOARD_XTKBD is not set
# CONFIG_KEYBOARD_NEWTON is not set
+# CONFIG_KEYBOARD_STOWAWAY is not set
CONFIG_INPUT_MOUSE=y
CONFIG_MOUSE_PS2=y
# CONFIG_MOUSE_SERIAL is not set
@@ -506,11 +578,23 @@ CONFIG_MOUSE_PS2=y
# CONFIG_INPUT_MISC is not set
#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+CONFIG_SERIO_I8042=y
+CONFIG_SERIO_SERPORT=y
+# CONFIG_SERIO_PCIPS2 is not set
+CONFIG_SERIO_LIBPS2=y
+# CONFIG_SERIO_RAW is not set
+# CONFIG_GAMEPORT is not set
+
+#
# Character devices
#
CONFIG_VT=y
CONFIG_VT_CONSOLE=y
CONFIG_HW_CONSOLE=y
+# CONFIG_VT_HW_CONSOLE_BINDING is not set
# CONFIG_SERIAL_NONSTANDARD is not set
#
@@ -522,9 +606,11 @@ CONFIG_HW_CONSOLE=y
# Non-8250 serial port support
#
CONFIG_SERIAL_SH_SCI=y
+CONFIG_SERIAL_SH_SCI_NR_UARTS=2
CONFIG_SERIAL_SH_SCI_CONSOLE=y
CONFIG_SERIAL_CORE=y
CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_JSM is not set
CONFIG_UNIX98_PTYS=y
CONFIG_LEGACY_PTYS=y
CONFIG_LEGACY_PTY_COUNT=256
@@ -551,7 +637,7 @@ CONFIG_WATCHDOG=y
#
# CONFIG_PCIPCWATCHDOG is not set
# CONFIG_WDTPCI is not set
-# CONFIG_RTC is not set
+CONFIG_HW_RANDOM=y
# CONFIG_GEN_RTC is not set
# CONFIG_DTLK is not set
# CONFIG_R3964 is not set
@@ -564,14 +650,35 @@ CONFIG_WATCHDOG=y
# CONFIG_RAW_DRIVER is not set
#
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
+# CONFIG_TELCLOCK is not set
+
+#
# I2C support
#
# CONFIG_I2C is not set
#
+# SPI support
+#
+# CONFIG_SPI is not set
+# CONFIG_SPI_MASTER is not set
+
+#
# Dallas's 1-wire bus
#
-# CONFIG_W1 is not set
+
+#
+# Hardware Monitoring support
+#
+CONFIG_HWMON=y
+# CONFIG_HWMON_VID is not set
+# CONFIG_SENSORS_ABITUGURU is not set
+# CONFIG_SENSORS_F71805F is not set
+# CONFIG_SENSORS_VT1211 is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
#
# Misc devices
@@ -581,6 +688,7 @@ CONFIG_WATCHDOG=y
# Multimedia devices
#
# CONFIG_VIDEO_DEV is not set
+CONFIG_VIDEO_V4L2=y
#
# Digital Video Broadcasting Devices
@@ -590,7 +698,13 @@ CONFIG_WATCHDOG=y
#
# Graphics support
#
+CONFIG_FIRMWARE_EDID=y
CONFIG_FB=y
+CONFIG_FB_CFB_FILLRECT=y
+CONFIG_FB_CFB_COPYAREA=y
+CONFIG_FB_CFB_IMAGEBLIT=y
+# CONFIG_FB_MACMODES is not set
+# CONFIG_FB_BACKLIGHT is not set
CONFIG_FB_MODE_HELPERS=y
# CONFIG_FB_TILEBLITTING is not set
# CONFIG_FB_CIRRUS is not set
@@ -599,9 +713,10 @@ CONFIG_FB_MODE_HELPERS=y
# CONFIG_FB_ASILIANT is not set
# CONFIG_FB_IMSTT is not set
# CONFIG_FB_EPSON1355 is not set
+# CONFIG_FB_S1D13XXX is not set
+# CONFIG_FB_NVIDIA is not set
# CONFIG_FB_RIVA is not set
# CONFIG_FB_MATROX is not set
-# CONFIG_FB_RADEON_OLD is not set
# CONFIG_FB_RADEON is not set
# CONFIG_FB_ATY128 is not set
# CONFIG_FB_ATY is not set
@@ -617,18 +732,20 @@ CONFIG_FB_KYRO=y
#
# Console display driver support
#
-# CONFIG_VGA_CONSOLE is not set
CONFIG_DUMMY_CONSOLE=y
CONFIG_FRAMEBUFFER_CONSOLE=y
+# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
CONFIG_FONTS=y
# CONFIG_FONT_8x8 is not set
CONFIG_FONT_8x16=y
# CONFIG_FONT_6x11 is not set
+# CONFIG_FONT_7x14 is not set
# CONFIG_FONT_PEARL_8x8 is not set
# CONFIG_FONT_ACORN_8x8 is not set
# CONFIG_FONT_MINI_4x6 is not set
# CONFIG_FONT_SUN8x16 is not set
# CONFIG_FONT_SUN12x22 is not set
+# CONFIG_FONT_10x18 is not set
#
# Logo configuration
@@ -650,12 +767,13 @@ CONFIG_LOGO_SUPERH_CLUT224=y
#
# USB support
#
-# CONFIG_USB is not set
CONFIG_USB_ARCH_HAS_HCD=y
CONFIG_USB_ARCH_HAS_OHCI=y
+CONFIG_USB_ARCH_HAS_EHCI=y
+# CONFIG_USB is not set
#
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
#
#
@@ -669,15 +787,51 @@ CONFIG_USB_ARCH_HAS_OHCI=y
# CONFIG_MMC is not set
#
+# LED devices
+#
+# CONFIG_NEW_LEDS is not set
+
+#
+# LED drivers
+#
+
+#
+# LED Triggers
+#
+
+#
# InfiniBand support
#
# CONFIG_INFINIBAND is not set
#
+# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
+#
+
+#
+# Real Time Clock
+#
+# CONFIG_RTC_CLASS is not set
+
+#
+# DMA Engine support
+#
+# CONFIG_DMA_ENGINE is not set
+
+#
+# DMA Clients
+#
+
+#
+# DMA Devices
+#
+
+#
# File systems
#
CONFIG_EXT2_FS=y
# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
CONFIG_EXT3_FS=y
CONFIG_EXT3_FS_XATTR=y
# CONFIG_EXT3_FS_POSIX_ACL is not set
@@ -687,17 +841,18 @@ CONFIG_JBD=y
CONFIG_FS_MBCACHE=y
# CONFIG_REISERFS_FS is not set
# CONFIG_JFS_FS is not set
-
-#
-# XFS support
-#
+# CONFIG_FS_POSIX_ACL is not set
# CONFIG_XFS_FS is not set
+# CONFIG_OCFS2_FS is not set
CONFIG_MINIX_FS=y
CONFIG_ROMFS_FS=y
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
# CONFIG_QUOTA is not set
CONFIG_DNOTIFY=y
# CONFIG_AUTOFS_FS is not set
# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
#
# CD-ROM/DVD Filesystems
@@ -717,14 +872,14 @@ CONFIG_DNOTIFY=y
#
CONFIG_PROC_FS=y
CONFIG_PROC_KCORE=y
+CONFIG_PROC_SYSCTL=y
CONFIG_SYSFS=y
-# CONFIG_DEVFS_FS is not set
-# CONFIG_DEVPTS_FS_XATTR is not set
CONFIG_TMPFS=y
-# CONFIG_TMPFS_XATTR is not set
+# CONFIG_TMPFS_POSIX_ACL is not set
CONFIG_HUGETLBFS=y
CONFIG_HUGETLB_PAGE=y
CONFIG_RAMFS=y
+# CONFIG_CONFIGFS_FS is not set
#
# Miscellaneous filesystems
@@ -748,12 +903,14 @@ CONFIG_RAMFS=y
#
CONFIG_NFS_FS=y
CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
# CONFIG_NFS_V4 is not set
# CONFIG_NFS_DIRECTIO is not set
# CONFIG_NFSD is not set
CONFIG_ROOT_NFS=y
CONFIG_LOCKD=y
CONFIG_LOCKD_V4=y
+CONFIG_NFS_COMMON=y
CONFIG_SUNRPC=y
# CONFIG_RPCSEC_GSS_KRB5 is not set
# CONFIG_RPCSEC_GSS_SPKM3 is not set
@@ -762,6 +919,7 @@ CONFIG_SUNRPC=y
# CONFIG_NCP_FS is not set
# CONFIG_CODA_FS is not set
# CONFIG_AFS_FS is not set
+# CONFIG_9P_FS is not set
#
# Partition Types
@@ -781,6 +939,7 @@ CONFIG_MSDOS_PARTITION=y
# CONFIG_SGI_PARTITION is not set
# CONFIG_ULTRIX_PARTITION is not set
# CONFIG_SUN_PARTITION is not set
+# CONFIG_KARMA_PARTITION is not set
# CONFIG_EFI_PARTITION is not set
#
@@ -796,13 +955,32 @@ CONFIG_MSDOS_PARTITION=y
#
# Kernel hacking
#
-CONFIG_DEBUG_KERNEL=y
+# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_MUST_CHECK=y
CONFIG_MAGIC_SYSRQ=y
+# CONFIG_UNUSED_SYMBOLS is not set
+CONFIG_DEBUG_KERNEL=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_DETECT_SOFTLOCKUP=y
CONFIG_SCHEDSTATS=y
+# CONFIG_DEBUG_SLAB is not set
+# CONFIG_DEBUG_RT_MUTEXES is not set
+# CONFIG_RT_MUTEX_TESTER is not set
# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_MUTEXES is not set
+# CONFIG_DEBUG_RWSEMS is not set
+# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
# CONFIG_DEBUG_KOBJECT is not set
+CONFIG_DEBUG_BUGVERBOSE=y
+# CONFIG_DEBUG_INFO is not set
CONFIG_DEBUG_FS=y
+# CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_LIST is not set
CONFIG_FRAME_POINTER=y
+# CONFIG_UNWIND_INFO is not set
+CONFIG_FORCED_INLINING=y
+# CONFIG_RCU_TORTURE_TEST is not set
# CONFIG_EARLY_PRINTK is not set
# CONFIG_DEBUG_KERNEL_WITH_GDB_STUB is not set
CONFIG_SH64_PROC_TLB=y
@@ -824,14 +1002,12 @@ CONFIG_SH64_SR_WATCH=y
# CONFIG_CRYPTO is not set
#
-# Hardware crypto devices
-#
-
-#
# Library routines
#
# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
CONFIG_CRC32=y
# CONFIG_LIBCRC32C is not set
+CONFIG_PLIST=y
CONFIG_GENERIC_HARDIRQS=y
CONFIG_GENERIC_IRQ_PROBE=y
diff --git a/arch/sh64/kernel/process.c b/arch/sh64/kernel/process.c
index db475b7833fb..525d0ec19b78 100644
--- a/arch/sh64/kernel/process.c
+++ b/arch/sh64/kernel/process.c
@@ -20,261 +20,16 @@
/*
* This file handles the architecture-dependent parts of process handling..
*/
-
-/* Temporary flags/tests. All to be removed/undefined. BEGIN */
-#define IDLE_TRACE
-#define VM_SHOW_TABLES
-#define VM_TEST_FAULT
-#define VM_TEST_RTLBMISS
-#define VM_TEST_WTLBMISS
-
-#undef VM_SHOW_TABLES
-#undef IDLE_TRACE
-/* Temporary flags/tests. All to be removed/undefined. END */
-
-#define __KERNEL_SYSCALLS__
-#include <stdarg.h>
-
-#include <linux/kernel.h>
-#include <linux/rwsem.h>
#include <linux/mm.h>
-#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/ptrace.h>
-#include <linux/slab.h>
-#include <linux/vmalloc.h>
-#include <linux/user.h>
-#include <linux/a.out.h>
-#include <linux/interrupt.h>
-#include <linux/unistd.h>
-#include <linux/delay.h>
#include <linux/reboot.h>
#include <linux/init.h>
-
+#include <linux/module.h>
#include <asm/uaccess.h>
#include <asm/pgtable.h>
-#include <asm/system.h>
-#include <asm/io.h>
-#include <asm/processor.h> /* includes also <asm/registers.h> */
-#include <asm/mmu_context.h>
-#include <asm/elf.h>
-#include <asm/page.h>
-
-#include <linux/irq.h>
struct task_struct *last_task_used_math = NULL;
-#ifdef IDLE_TRACE
-#ifdef VM_SHOW_TABLES
-/* For testing */
-static void print_PTE(long base)
-{
- int i, skip=0;
- long long x, y, *p = (long long *) base;
-
- for (i=0; i< 512; i++, p++){
- if (*p == 0) {
- if (!skip) {
- skip++;
- printk("(0s) ");
- }
- } else {
- skip=0;
- x = (*p) >> 32;
- y = (*p) & 0xffffffff;
- printk("%08Lx%08Lx ", x, y);
- if (!((i+1)&0x3)) printk("\n");
- }
- }
-}
-
-/* For testing */
-static void print_DIR(long base)
-{
- int i, skip=0;
- long *p = (long *) base;
-
- for (i=0; i< 512; i++, p++){
- if (*p == 0) {
- if (!skip) {
- skip++;
- printk("(0s) ");
- }
- } else {
- skip=0;
- printk("%08lx ", *p);
- if (!((i+1)&0x7)) printk("\n");
- }
- }
-}
-
-/* For testing */
-static void print_vmalloc_first_tables(void)
-{
-
-#define PRESENT 0x800 /* Bit 11 */
-
- /*
- * Do it really dirty by looking at raw addresses,
- * raw offsets, no types. If we used pgtable/pgalloc
- * macros/definitions we could hide potential bugs.
- *
- * Note that pointers are 32-bit for CDC.
- */
- long pgdt, pmdt, ptet;
-
- pgdt = (long) &swapper_pg_dir;
- printk("-->PGD (0x%08lx):\n", pgdt);
- print_DIR(pgdt);
- printk("\n");
-
- /* VMALLOC pool is mapped at 0xc0000000, second (pointer) entry in PGD */
- pgdt += 4;
- pmdt = (long) (* (long *) pgdt);
- if (!(pmdt & PRESENT)) {
- printk("No PMD\n");
- return;
- } else pmdt &= 0xfffff000;
-
- printk("-->PMD (0x%08lx):\n", pmdt);
- print_DIR(pmdt);
- printk("\n");
-
- /* Get the pmdt displacement for 0xc0000000 */
- pmdt += 2048;
-
- /* just look at first two address ranges ... */
- /* ... 0xc0000000 ... */
- ptet = (long) (* (long *) pmdt);
- if (!(ptet & PRESENT)) {
- printk("No PTE0\n");
- return;
- } else ptet &= 0xfffff000;
-
- printk("-->PTE0 (0x%08lx):\n", ptet);
- print_PTE(ptet);
- printk("\n");
-
- /* ... 0xc0001000 ... */
- ptet += 4;
- if (!(ptet & PRESENT)) {
- printk("No PTE1\n");
- return;
- } else ptet &= 0xfffff000;
- printk("-->PTE1 (0x%08lx):\n", ptet);
- print_PTE(ptet);
- printk("\n");
-}
-#else
-#define print_vmalloc_first_tables()
-#endif /* VM_SHOW_TABLES */
-
-static void test_VM(void)
-{
- void *a, *b, *c;
-
-#ifdef VM_SHOW_TABLES
- printk("Initial PGD/PMD/PTE\n");
-#endif
- print_vmalloc_first_tables();
-
- printk("Allocating 2 bytes\n");
- a = vmalloc(2);
- print_vmalloc_first_tables();
-
- printk("Allocating 4100 bytes\n");
- b = vmalloc(4100);
- print_vmalloc_first_tables();
-
- printk("Allocating 20234 bytes\n");
- c = vmalloc(20234);
- print_vmalloc_first_tables();
-
-#ifdef VM_TEST_FAULT
- /* Here you may want to fault ! */
-
-#ifdef VM_TEST_RTLBMISS
- printk("Ready to fault upon read.\n");
- if (* (char *) a) {
- printk("RTLBMISSed on area a !\n");
- }
- printk("RTLBMISSed on area a !\n");
-#endif
-
-#ifdef VM_TEST_WTLBMISS
- printk("Ready to fault upon write.\n");
- *((char *) b) = 'L';
- printk("WTLBMISSed on area b !\n");
-#endif
-
-#endif /* VM_TEST_FAULT */
-
- printk("Deallocating the 4100 byte chunk\n");
- vfree(b);
- print_vmalloc_first_tables();
-
- printk("Deallocating the 2 byte chunk\n");
- vfree(a);
- print_vmalloc_first_tables();
-
- printk("Deallocating the last chunk\n");
- vfree(c);
- print_vmalloc_first_tables();
-}
-
-extern unsigned long volatile jiffies;
-int once = 0;
-unsigned long old_jiffies;
-int pid = -1, pgid = -1;
-
-void idle_trace(void)
-{
-
- _syscall0(int, getpid)
- _syscall1(int, getpgid, int, pid)
-
- if (!once) {
- /* VM allocation/deallocation simple test */
- test_VM();
- pid = getpid();
-
- printk("Got all through to Idle !!\n");
- printk("I'm now going to loop forever ...\n");
- printk("Any ! below is a timer tick.\n");
- printk("Any . below is a getpgid system call from pid = %d.\n", pid);
-
-
- old_jiffies = jiffies;
- once++;
- }
-
- if (old_jiffies != jiffies) {
- old_jiffies = jiffies - old_jiffies;
- switch (old_jiffies) {
- case 1:
- printk("!");
- break;
- case 2:
- printk("!!");
- break;
- case 3:
- printk("!!!");
- break;
- case 4:
- printk("!!!!");
- break;
- default:
- printk("(%d!)", (int) old_jiffies);
- }
- old_jiffies = jiffies;
- }
- pgid = getpgid(pid);
- printk(".");
-}
-#else
-#define idle_trace() do { } while (0)
-#endif /* IDLE_TRACE */
-
static int hlt_counter = 1;
#define HARD_IDLE_TIMEOUT (HZ / 3)
@@ -323,7 +78,6 @@ void cpu_idle(void)
local_irq_disable();
while (!need_resched()) {
local_irq_enable();
- idle_trace();
hlt();
local_irq_disable();
}
@@ -622,6 +376,10 @@ void free_task_struct(struct task_struct *p)
/*
* Create a kernel thread
*/
+ATTRIB_NORET void kernel_thread_helper(void *arg, int (*fn)(void *))
+{
+ do_exit(fn(arg));
+}
/*
* This is the mechanism for creating a new kernel thread.
@@ -633,19 +391,17 @@ void free_task_struct(struct task_struct *p)
*/
int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
{
- /* A bit less processor dependent than older sh ... */
- unsigned int reply;
+ struct pt_regs regs;
-static __inline__ _syscall2(int,clone,unsigned long,flags,unsigned long,newsp)
-static __inline__ _syscall1(int,exit,int,ret)
+ memset(&regs, 0, sizeof(regs));
+ regs.regs[2] = (unsigned long)arg;
+ regs.regs[3] = (unsigned long)fn;
- reply = clone(flags | CLONE_VM, 0);
- if (!reply) {
- /* Child */
- reply = exit(fn(arg));
- }
+ regs.pc = (unsigned long)kernel_thread_helper;
+ regs.sr = (1 << 30);
- return reply;
+ return do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0,
+ &regs, 0, NULL, NULL);
}
/*
diff --git a/arch/sh64/kernel/sys_sh64.c b/arch/sh64/kernel/sys_sh64.c
index 58ff7d522d81..ad0fa4e003e7 100644
--- a/arch/sh64/kernel/sys_sh64.c
+++ b/arch/sh64/kernel/sys_sh64.c
@@ -32,6 +32,7 @@
#include <asm/uaccess.h>
#include <asm/ipc.h>
#include <asm/ptrace.h>
+#include <asm/unistd.h>
#define REG_3 3
@@ -279,7 +280,25 @@ asmlinkage int sys_uname(struct old_utsname * name)
if (!name)
return -EFAULT;
down_read(&uts_sem);
- err=copy_to_user(name, &system_utsname, sizeof (*name));
+ err = copy_to_user(name, utsname(), sizeof (*name));
up_read(&uts_sem);
return err?-EFAULT:0;
}
+
+/*
+ * Do a system call from kernel instead of calling sys_execve so we
+ * end up with proper pt_regs.
+ */
+int kernel_execve(const char *filename, char *const argv[], char *const envp[])
+{
+ register unsigned long __sc0 __asm__ ("r9") = ((0x13 << 16) | __NR_execve);
+ register unsigned long __sc2 __asm__ ("r2") = (unsigned long) filename;
+ register unsigned long __sc3 __asm__ ("r3") = (unsigned long) argv;
+ register unsigned long __sc4 __asm__ ("r4") = (unsigned long) envp;
+ __asm__ __volatile__ ("trapa %1 !\t\t\t execve(%2,%3,%4)"
+ : "=r" (__sc0)
+ : "r" (__sc0), "r" (__sc2), "r" (__sc3), "r" (__sc4) );
+ __asm__ __volatile__ ("!dummy %0 %1 %2 %3"
+ : : "r" (__sc0), "r" (__sc2), "r" (__sc3), "r" (__sc4) : "memory");
+ return __sc0;
+}
diff --git a/arch/sh64/kernel/time.c b/arch/sh64/kernel/time.c
index b8162e59030e..9c4a38a8698c 100644
--- a/arch/sh64/kernel/time.c
+++ b/arch/sh64/kernel/time.c
@@ -107,8 +107,6 @@
#define TICK_SIZE (tick_nsec / 1000)
-extern unsigned long wall_jiffies;
-
static unsigned long tmu_base, rtc_base;
unsigned long cprc_base;
@@ -194,13 +192,6 @@ void do_gettimeofday(struct timeval *tv)
do {
seq = read_seqbegin_irqsave(&xtime_lock, flags);
usec = usecs_since_tick();
- {
- unsigned long lost = jiffies - wall_jiffies;
-
- if (lost)
- usec += lost * (1000000 / HZ);
- }
-
sec = xtime.tv_sec;
usec += xtime.tv_nsec / 1000;
} while (read_seqretry_irqrestore(&xtime_lock, seq, flags));
@@ -229,8 +220,7 @@ int do_settimeofday(struct timespec *tv)
* wall time. Discover what correction gettimeofday() would have
* made, and then undo it!
*/
- nsec -= 1000 * (usecs_since_tick() +
- (jiffies - wall_jiffies) * (1000000 / HZ));
+ nsec -= 1000 * usecs_since_tick();
wtm_sec = wall_to_monotonic.tv_sec + (xtime.tv_sec - sec);
wtm_nsec = wall_to_monotonic.tv_nsec + (xtime.tv_nsec - nsec);
@@ -298,7 +288,7 @@ static inline void do_timer_interrupt(int irq, struct pt_regs *regs)
asm ("getcon cr62, %0" : "=r" (current_ctc));
ctc_last_interrupt = (unsigned long) current_ctc;
- do_timer(regs);
+ do_timer(1);
#ifndef CONFIG_SMP
update_process_times(user_mode(regs));
#endif
diff --git a/arch/sh64/mm/fault.c b/arch/sh64/mm/fault.c
index f08d0eaf6497..8e2f6c28b739 100644
--- a/arch/sh64/mm/fault.c
+++ b/arch/sh64/mm/fault.c
@@ -277,7 +277,7 @@ bad_area:
show_regs(regs);
#endif
}
- if (tsk->pid == 1) {
+ if (is_init(tsk)) {
panic("INIT had user mode bad_area\n");
}
tsk->thread.address = address;
@@ -319,14 +319,14 @@ no_context:
* us unable to handle the page fault gracefully.
*/
out_of_memory:
- if (current->pid == 1) {
+ if (is_init(current)) {
panic("INIT out of memory\n");
yield();
goto survive;
}
printk("fault:Out of memory\n");
up_read(&mm->mmap_sem);
- if (current->pid == 1) {
+ if (is_init(current)) {
yield();
down_read(&mm->mmap_sem);
goto survive;
diff --git a/arch/sparc/kernel/pcic.c b/arch/sparc/kernel/pcic.c
index bfd31aac2df3..edb6cc665f56 100644
--- a/arch/sparc/kernel/pcic.c
+++ b/arch/sparc/kernel/pcic.c
@@ -712,7 +712,7 @@ static irqreturn_t pcic_timer_handler (int irq, void *h, struct pt_regs *regs)
{
write_seqlock(&xtime_lock); /* Dummy, to show that we remember */
pcic_clear_clock_irq();
- do_timer(regs);
+ do_timer(1);
#ifndef CONFIG_SMP
update_process_times(user_mode(regs));
#endif
@@ -765,8 +765,6 @@ static __inline__ unsigned long do_gettimeoffset(void)
return count;
}
-extern unsigned long wall_jiffies;
-
static void pci_do_gettimeofday(struct timeval *tv)
{
unsigned long flags;
@@ -775,26 +773,17 @@ static void pci_do_gettimeofday(struct timeval *tv)
unsigned long max_ntp_tick = tick_usec - tickadj;
do {
- unsigned long lost;
-
seq = read_seqbegin_irqsave(&xtime_lock, flags);
usec = do_gettimeoffset();
- lost = jiffies - wall_jiffies;
/*
* If time_adjust is negative then NTP is slowing the clock
* so make sure not to go into next possible interval.
* Better to lose some accuracy than have time go backwards..
*/
- if (unlikely(time_adjust < 0)) {
+ if (unlikely(time_adjust < 0))
usec = min(usec, max_ntp_tick);
- if (lost)
- usec += lost * max_ntp_tick;
- }
- else if (unlikely(lost))
- usec += lost * tick_usec;
-
sec = xtime.tv_sec;
usec += (xtime.tv_nsec / 1000);
} while (read_seqretry_irqrestore(&xtime_lock, seq, flags));
@@ -819,8 +808,7 @@ static int pci_do_settimeofday(struct timespec *tv)
* wall time. Discover what correction gettimeofday() would have
* made, and then undo it!
*/
- tv->tv_nsec -= 1000 * (do_gettimeoffset() +
- (jiffies - wall_jiffies) * (USEC_PER_SEC / HZ));
+ tv->tv_nsec -= 1000 * do_gettimeoffset();
while (tv->tv_nsec < 0) {
tv->tv_nsec += NSEC_PER_SEC;
tv->tv_sec--;
diff --git a/arch/sparc/kernel/sys_sparc.c b/arch/sparc/kernel/sys_sparc.c
index 896863fb208a..a954a0c00000 100644
--- a/arch/sparc/kernel/sys_sparc.c
+++ b/arch/sparc/kernel/sys_sparc.c
@@ -24,6 +24,7 @@
#include <asm/uaccess.h>
#include <asm/ipc.h>
+#include <asm/unistd.h>
/* #define DEBUG_UNIMP_SYSCALL */
@@ -475,16 +476,38 @@ asmlinkage int sys_getdomainname(char __user *name, int len)
down_read(&uts_sem);
- nlen = strlen(system_utsname.domainname) + 1;
+ nlen = strlen(utsname()->domainname) + 1;
err = -EINVAL;
if (nlen > len)
goto out;
err = -EFAULT;
- if (!copy_to_user(name, system_utsname.domainname, nlen))
+ if (!copy_to_user(name, utsname()->domainname, nlen))
err = 0;
out:
up_read(&uts_sem);
return err;
}
+
+/*
+ * Do a system call from kernel instead of calling sys_execve so we
+ * end up with proper pt_regs.
+ */
+int kernel_execve(const char *filename, char *const argv[], char *const envp[])
+{
+ long __res;
+ register long __g1 __asm__ ("g1") = __NR_execve;
+ register long __o0 __asm__ ("o0") = (long)(filename);
+ register long __o1 __asm__ ("o1") = (long)(argv);
+ register long __o2 __asm__ ("o2") = (long)(envp);
+ asm volatile ("t 0x10\n\t"
+ "bcc 1f\n\t"
+ "mov %%o0, %0\n\t"
+ "sub %%g0, %%o0, %0\n\t"
+ "1:\n\t"
+ : "=r" (__res), "=&r" (__o0)
+ : "1" (__o0), "r" (__o1), "r" (__o2), "r" (__g1)
+ : "cc");
+ return __res;
+}
diff --git a/arch/sparc/kernel/sys_sunos.c b/arch/sparc/kernel/sys_sunos.c
index aa0fb2efb615..6f3ac548ee66 100644
--- a/arch/sparc/kernel/sys_sunos.c
+++ b/arch/sparc/kernel/sys_sunos.c
@@ -325,21 +325,25 @@ struct sunos_dirent_callback {
#define ROUND_UP(x) (((x)+sizeof(long)-1) & ~(sizeof(long)-1))
static int sunos_filldir(void * __buf, const char * name, int namlen,
- loff_t offset, ino_t ino, unsigned int d_type)
+ loff_t offset, u64 ino, unsigned int d_type)
{
struct sunos_dirent __user *dirent;
struct sunos_dirent_callback * buf = __buf;
+ unsigned long d_ino;
int reclen = ROUND_UP(NAME_OFFSET(dirent) + namlen + 1);
buf->error = -EINVAL; /* only used if we fail.. */
if (reclen > buf->count)
return -EINVAL;
+ d_ino = ino;
+ if (sizeof(d_ino) < sizeof(ino) && d_ino != ino)
+ return -EOVERFLOW;
dirent = buf->previous;
if (dirent)
put_user(offset, &dirent->d_off);
dirent = buf->curr;
buf->previous = dirent;
- put_user(ino, &dirent->d_ino);
+ put_user(d_ino, &dirent->d_ino);
put_user(namlen, &dirent->d_namlen);
put_user(reclen, &dirent->d_reclen);
copy_to_user(dirent->d_name, name, namlen);
@@ -406,19 +410,23 @@ struct sunos_direntry_callback {
};
static int sunos_filldirentry(void * __buf, const char * name, int namlen,
- loff_t offset, ino_t ino, unsigned int d_type)
+ loff_t offset, u64 ino, unsigned int d_type)
{
struct sunos_direntry __user *dirent;
struct sunos_direntry_callback *buf = __buf;
+ unsigned long d_ino;
int reclen = ROUND_UP(NAME_OFFSET(dirent) + namlen + 1);
buf->error = -EINVAL; /* only used if we fail.. */
if (reclen > buf->count)
return -EINVAL;
+ d_ino = ino;
+ if (sizeof(d_ino) < sizeof(ino) && d_ino != ino)
+ return -EOVERFLOW;
dirent = buf->previous;
dirent = buf->curr;
buf->previous = dirent;
- put_user(ino, &dirent->d_ino);
+ put_user(d_ino, &dirent->d_ino);
put_user(namlen, &dirent->d_namlen);
put_user(reclen, &dirent->d_reclen);
copy_to_user(dirent->d_name, name, namlen);
@@ -483,13 +491,18 @@ asmlinkage int sunos_uname(struct sunos_utsname __user *name)
{
int ret;
down_read(&uts_sem);
- ret = copy_to_user(&name->sname[0], &system_utsname.sysname[0], sizeof(name->sname) - 1);
+ ret = copy_to_user(&name->sname[0], &utsname()->sysname[0],
+ sizeof(name->sname) - 1);
if (!ret) {
- ret |= __copy_to_user(&name->nname[0], &system_utsname.nodename[0], sizeof(name->nname) - 1);
+ ret |= __copy_to_user(&name->nname[0], &utsname()->nodename[0],
+ sizeof(name->nname) - 1);
ret |= __put_user('\0', &name->nname[8]);
- ret |= __copy_to_user(&name->rel[0], &system_utsname.release[0], sizeof(name->rel) - 1);
- ret |= __copy_to_user(&name->ver[0], &system_utsname.version[0], sizeof(name->ver) - 1);
- ret |= __copy_to_user(&name->mach[0], &system_utsname.machine[0], sizeof(name->mach) - 1);
+ ret |= __copy_to_user(&name->rel[0], &utsname()->release[0],
+ sizeof(name->rel) - 1);
+ ret |= __copy_to_user(&name->ver[0], &utsname()->version[0],
+ sizeof(name->ver) - 1);
+ ret |= __copy_to_user(&name->mach[0], &utsname()->machine[0],
+ sizeof(name->mach) - 1);
}
up_read(&uts_sem);
return ret ? -EFAULT : 0;
diff --git a/arch/sparc/kernel/time.c b/arch/sparc/kernel/time.c
index 845081b01267..e10dc831944d 100644
--- a/arch/sparc/kernel/time.c
+++ b/arch/sparc/kernel/time.c
@@ -43,8 +43,6 @@
#include <asm/pcic.h>
#include <asm/of_device.h>
-extern unsigned long wall_jiffies;
-
DEFINE_SPINLOCK(rtc_lock);
enum sparc_clock_type sp_clock_typ;
DEFINE_SPINLOCK(mostek_lock);
@@ -128,7 +126,7 @@ irqreturn_t timer_interrupt(int irq, void *dev_id, struct pt_regs * regs)
#endif
clear_clock_irq();
- do_timer(regs);
+ do_timer(1);
#ifndef CONFIG_SMP
update_process_times(user_mode(regs));
#endif
@@ -449,7 +447,7 @@ unsigned long long sched_clock(void)
/* Ok, my cute asm atomicity trick doesn't work anymore.
* There are just too many variables that need to be protected
- * now (both members of xtime, wall_jiffies, et al.)
+ * now (both members of xtime, et al.)
*/
void do_gettimeofday(struct timeval *tv)
{
@@ -459,26 +457,17 @@ void do_gettimeofday(struct timeval *tv)
unsigned long max_ntp_tick = tick_usec - tickadj;
do {
- unsigned long lost;
-
seq = read_seqbegin_irqsave(&xtime_lock, flags);
usec = do_gettimeoffset();
- lost = jiffies - wall_jiffies;
/*
* If time_adjust is negative then NTP is slowing the clock
* so make sure not to go into next possible interval.
* Better to lose some accuracy than have time go backwards..
*/
- if (unlikely(time_adjust < 0)) {
+ if (unlikely(time_adjust < 0))
usec = min(usec, max_ntp_tick);
- if (lost)
- usec += lost * max_ntp_tick;
- }
- else if (unlikely(lost))
- usec += lost * tick_usec;
-
sec = xtime.tv_sec;
usec += (xtime.tv_nsec / 1000);
} while (read_seqretry_irqrestore(&xtime_lock, seq, flags));
@@ -521,8 +510,7 @@ static int sbus_do_settimeofday(struct timespec *tv)
* wall time. Discover what correction gettimeofday() would have
* made, and then undo it!
*/
- nsec -= 1000 * (do_gettimeoffset() +
- (jiffies - wall_jiffies) * (USEC_PER_SEC / HZ));
+ nsec -= 1000 * do_gettimeoffset();
wtm_sec = wall_to_monotonic.tv_sec + (xtime.tv_sec - sec);
wtm_nsec = wall_to_monotonic.tv_nsec + (xtime.tv_nsec - nsec);
diff --git a/arch/sparc/lib/copy_user.S b/arch/sparc/lib/copy_user.S
index 577505b692ae..ef095b6c43b1 100644
--- a/arch/sparc/lib/copy_user.S
+++ b/arch/sparc/lib/copy_user.S
@@ -14,6 +14,7 @@
#include <asm/ptrace.h>
#include <asm/asmmacro.h>
#include <asm/page.h>
+#include <asm/thread_info.h>
/* Work around cpp -rob */
#define ALLOC #alloc
@@ -366,6 +367,9 @@ fixupretl:
blu 1f
cmp %o1, %g1
bgeu 1f
+ ld [%g6 + TI_PREEMPT], %g1
+ cmp %g1, 0
+ bne 1f
nop
save %sp, -64, %sp
mov %i0, %o0
diff --git a/arch/sparc64/Kconfig b/arch/sparc64/Kconfig
index 8d8ca716f7a7..b627f8dbcaad 100644
--- a/arch/sparc64/Kconfig
+++ b/arch/sparc64/Kconfig
@@ -420,7 +420,7 @@ source "arch/sparc64/oprofile/Kconfig"
config KPROBES
bool "Kprobes (EXPERIMENTAL)"
- depends on EXPERIMENTAL && MODULES
+ depends on KALLSYMS && EXPERIMENTAL && MODULES
help
Kprobes allows you to trap at almost any kernel address and
execute a callback function. register_kprobe() establishes
diff --git a/arch/sparc64/defconfig b/arch/sparc64/defconfig
index 0fbdaa5daa8c..f54ab375464b 100644
--- a/arch/sparc64/defconfig
+++ b/arch/sparc64/defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
# Linux kernel version: 2.6.18
-# Tue Sep 26 23:09:35 2006
+# Mon Oct 2 14:24:40 2006
#
CONFIG_SPARC=y
CONFIG_SPARC64=y
@@ -35,17 +35,20 @@ CONFIG_LOCALVERSION=""
# CONFIG_LOCALVERSION_AUTO is not set
CONFIG_SWAP=y
CONFIG_SYSVIPC=y
+# CONFIG_IPC_NS is not set
CONFIG_POSIX_MQUEUE=y
# CONFIG_BSD_PROCESS_ACCT is not set
# CONFIG_TASKSTATS is not set
+# CONFIG_UTS_NS is not set
# CONFIG_AUDIT is not set
# CONFIG_IKCONFIG is not set
CONFIG_RELAY=y
CONFIG_INITRAMFS_SOURCE=""
CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
# CONFIG_EMBEDDED is not set
CONFIG_UID16=y
-CONFIG_SYSCTL=y
+# CONFIG_SYSCTL_SYSCALL is not set
CONFIG_KALLSYMS=y
# CONFIG_KALLSYMS_ALL is not set
# CONFIG_KALLSYMS_EXTRA_PASS is not set
@@ -77,6 +80,7 @@ CONFIG_KMOD=y
#
# Block layer
#
+CONFIG_BLOCK=y
CONFIG_BLK_DEV_IO_TRACE=y
#
@@ -154,7 +158,7 @@ CONFIG_BINFMT_ELF32=y
#
CONFIG_BINFMT_ELF=y
CONFIG_BINFMT_MISC=m
-# CONFIG_SOLARIS_EMUL is not set
+CONFIG_SOLARIS_EMUL=y
# CONFIG_CMDLINE_BOOL is not set
#
@@ -622,6 +626,7 @@ CONFIG_BNX2=m
# Input device support
#
CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
#
# Userland interfaces
@@ -644,6 +649,7 @@ CONFIG_KEYBOARD_SUNKBD=y
CONFIG_KEYBOARD_LKKBD=m
# CONFIG_KEYBOARD_XTKBD is not set
# CONFIG_KEYBOARD_NEWTON is not set
+# CONFIG_KEYBOARD_STOWAWAY is not set
CONFIG_INPUT_MOUSE=y
CONFIG_MOUSE_PS2=y
CONFIG_MOUSE_SERIAL=y
@@ -821,6 +827,7 @@ CONFIG_HWMON=y
# CONFIG_SENSORS_SMSC47M192 is not set
# CONFIG_SENSORS_SMSC47B397 is not set
# CONFIG_SENSORS_VIA686A is not set
+# CONFIG_SENSORS_VT1211 is not set
# CONFIG_SENSORS_VT8231 is not set
# CONFIG_SENSORS_W83781D is not set
# CONFIG_SENSORS_W83791D is not set
@@ -1092,6 +1099,7 @@ CONFIG_USB_HIDDEV=y
# CONFIG_USB_ATI_REMOTE2 is not set
# CONFIG_USB_KEYSPAN_REMOTE is not set
# CONFIG_USB_APPLETOUCH is not set
+# CONFIG_USB_TRANCEVIBRATOR is not set
#
# USB Imaging devices
@@ -1123,6 +1131,7 @@ CONFIG_USB_HIDDEV=y
#
# CONFIG_USB_EMI62 is not set
# CONFIG_USB_EMI26 is not set
+# CONFIG_USB_ADUTUX is not set
# CONFIG_USB_AUERSWALD is not set
# CONFIG_USB_RIO500 is not set
# CONFIG_USB_LEGOTOWER is not set
@@ -1130,9 +1139,9 @@ CONFIG_USB_HIDDEV=y
# CONFIG_USB_LED is not set
# CONFIG_USB_CYPRESS_CY7C63 is not set
# CONFIG_USB_CYTHERM is not set
-# CONFIG_USB_PHIDGETKIT is not set
-# CONFIG_USB_PHIDGETSERVO is not set
+# CONFIG_USB_PHIDGET is not set
# CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_FTDI_ELAN is not set
# CONFIG_USB_APPLEDISPLAY is not set
# CONFIG_USB_SISUSBVGA is not set
# CONFIG_USB_LD is not set
@@ -1256,8 +1265,10 @@ CONFIG_DNOTIFY=y
#
CONFIG_PROC_FS=y
CONFIG_PROC_KCORE=y
+CONFIG_PROC_SYSCTL=y
CONFIG_SYSFS=y
CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
CONFIG_HUGETLBFS=y
CONFIG_HUGETLB_PAGE=y
CONFIG_RAMFS=y
@@ -1374,9 +1385,11 @@ CONFIG_DEBUG_BUGVERBOSE=y
# CONFIG_DEBUG_INFO is not set
CONFIG_DEBUG_FS=y
# CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_LIST is not set
# CONFIG_UNWIND_INFO is not set
CONFIG_FORCED_INLINING=y
# CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_LKDTM is not set
# CONFIG_DEBUG_STACK_USAGE is not set
# CONFIG_DEBUG_DCFLUSH is not set
# CONFIG_STACK_DEBUG is not set
diff --git a/arch/sparc64/kernel/power.c b/arch/sparc64/kernel/power.c
index e55466c77b61..0b9c70627ce4 100644
--- a/arch/sparc64/kernel/power.c
+++ b/arch/sparc64/kernel/power.c
@@ -4,8 +4,6 @@
* Copyright (C) 1999 David S. Miller (davem@redhat.com)
*/
-#define __KERNEL_SYSCALLS__
-
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
@@ -14,6 +12,7 @@
#include <linux/delay.h>
#include <linux/interrupt.h>
#include <linux/pm.h>
+#include <linux/syscalls.h>
#include <asm/system.h>
#include <asm/auxio.h>
@@ -98,7 +97,7 @@ again:
/* Ok, down we go... */
button_pressed = 0;
- if (execve("/sbin/shutdown", argv, envp) < 0) {
+ if (kernel_execve("/sbin/shutdown", argv, envp) < 0) {
printk("powerd: shutdown execution failed\n");
add_wait_queue(&powerd_wait, &wait);
goto again;
diff --git a/arch/sparc64/kernel/signal32.c b/arch/sparc64/kernel/signal32.c
index 708ba9b42cda..c45f21b881d5 100644
--- a/arch/sparc64/kernel/signal32.c
+++ b/arch/sparc64/kernel/signal32.c
@@ -29,6 +29,7 @@
#include <asm/psrcompat.h>
#include <asm/fpumacro.h>
#include <asm/visasm.h>
+#include <asm/compat_signal.h>
#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
diff --git a/arch/sparc64/kernel/sys_sparc.c b/arch/sparc64/kernel/sys_sparc.c
index c608c947e6c3..a53d4abb4b49 100644
--- a/arch/sparc64/kernel/sys_sparc.c
+++ b/arch/sparc64/kernel/sys_sparc.c
@@ -31,6 +31,7 @@
#include <asm/utrap.h>
#include <asm/perfctr.h>
#include <asm/a.out.h>
+#include <asm/unistd.h>
/* #define DEBUG_UNIMP_SYSCALL */
@@ -712,13 +713,13 @@ asmlinkage long sys_getdomainname(char __user *name, int len)
down_read(&uts_sem);
- nlen = strlen(system_utsname.domainname) + 1;
+ nlen = strlen(utsname()->domainname) + 1;
err = -EINVAL;
if (nlen > len)
goto out;
err = -EFAULT;
- if (!copy_to_user(name, system_utsname.domainname, nlen))
+ if (!copy_to_user(name, utsname()->domainname, nlen))
err = 0;
out:
@@ -963,3 +964,23 @@ asmlinkage long sys_perfctr(int opcode, unsigned long arg0, unsigned long arg1,
};
return err;
}
+
+/*
+ * Do a system call from kernel instead of calling sys_execve so we
+ * end up with proper pt_regs.
+ */
+int kernel_execve(const char *filename, char *const argv[], char *const envp[])
+{
+ long __res;
+ register long __g1 __asm__ ("g1") = __NR_execve;
+ register long __o0 __asm__ ("o0") = (long)(filename);
+ register long __o1 __asm__ ("o1") = (long)(argv);
+ register long __o2 __asm__ ("o2") = (long)(envp);
+ asm volatile ("t 0x6d\n\t"
+ "sub %%g0, %%o0, %0\n\t"
+ "movcc %%xcc, %%o0, %0\n\t"
+ : "=r" (__res), "=&r" (__o0)
+ : "1" (__o0), "r" (__o1), "r" (__o2), "r" (__g1)
+ : "cc");
+ return __res;
+}
diff --git a/arch/sparc64/kernel/sys_sparc32.c b/arch/sparc64/kernel/sys_sparc32.c
index 69444f266e2d..e27cb71bd8e2 100644
--- a/arch/sparc64/kernel/sys_sparc32.c
+++ b/arch/sparc64/kernel/sys_sparc32.c
@@ -61,6 +61,7 @@
#include <asm/semaphore.h>
#include <asm/mmu_context.h>
#include <asm/a.out.h>
+#include <asm/compat_signal.h>
asmlinkage long sys32_chown16(const char __user * filename, u16 user, u16 group)
{
@@ -337,12 +338,17 @@ asmlinkage long sys32_ftruncate64(unsigned int fd, unsigned long high, unsigned
int cp_compat_stat(struct kstat *stat, struct compat_stat __user *statbuf)
{
+ compat_ino_t ino;
int err;
if (stat->size > MAX_NON_LFS || !old_valid_dev(stat->dev) ||
!old_valid_dev(stat->rdev))
return -EOVERFLOW;
+ ino = stat->ino;
+ if (sizeof(ino) < sizeof(stat->ino) && ino != stat->ino)
+ return -EOVERFLOW;
+
err = put_user(old_encode_dev(stat->dev), &statbuf->st_dev);
err |= put_user(stat->ino, &statbuf->st_ino);
err |= put_user(stat->mode, &statbuf->st_mode);
diff --git a/arch/sparc64/kernel/sys_sunos32.c b/arch/sparc64/kernel/sys_sunos32.c
index 87ebdf858a3a..7da72d3b322a 100644
--- a/arch/sparc64/kernel/sys_sunos32.c
+++ b/arch/sparc64/kernel/sys_sunos32.c
@@ -43,6 +43,7 @@
#include <asm/idprom.h> /* for gethostid() */
#include <asm/unistd.h>
#include <asm/system.h>
+#include <asm/compat_signal.h>
/* For the nfs mount emulation */
#include <linux/socket.h>
@@ -280,16 +281,20 @@ static int sunos_filldir(void * __buf, const char * name, int namlen,
struct sunos_dirent __user *dirent;
struct sunos_dirent_callback * buf = (struct sunos_dirent_callback *) __buf;
int reclen = ROUND_UP(NAME_OFFSET(dirent) + namlen + 1);
+ u32 d_ino;
buf->error = -EINVAL; /* only used if we fail.. */
if (reclen > buf->count)
return -EINVAL;
+ d_ino = ino;
+ if (sizeof(d_ino) < sizeof(ino) && d_ino != ino)
+ return -EOVERFLOW;
dirent = buf->previous;
if (dirent)
put_user(offset, &dirent->d_off);
dirent = buf->curr;
buf->previous = dirent;
- put_user(ino, &dirent->d_ino);
+ put_user(d_ino, &dirent->d_ino);
put_user(namlen, &dirent->d_namlen);
put_user(reclen, &dirent->d_reclen);
if (copy_to_user(dirent->d_name, name, namlen))
@@ -363,14 +368,18 @@ static int sunos_filldirentry(void * __buf, const char * name, int namlen,
struct sunos_direntry_callback * buf =
(struct sunos_direntry_callback *) __buf;
int reclen = ROUND_UP(NAME_OFFSET(dirent) + namlen + 1);
+ u32 d_ino;
buf->error = -EINVAL; /* only used if we fail.. */
if (reclen > buf->count)
return -EINVAL;
+ d_ino = ino;
+ if (sizeof(d_ino) < sizeof(ino) && d_ino != ino)
+ return -EOVERFLOW;
dirent = buf->previous;
dirent = buf->curr;
buf->previous = dirent;
- put_user(ino, &dirent->d_ino);
+ put_user(d_ino, &dirent->d_ino);
put_user(namlen, &dirent->d_namlen);
put_user(reclen, &dirent->d_reclen);
if (copy_to_user(dirent->d_name, name, namlen))
@@ -439,16 +448,16 @@ asmlinkage int sunos_uname(struct sunos_utsname __user *name)
int ret;
down_read(&uts_sem);
- ret = copy_to_user(&name->sname[0], &system_utsname.sysname[0],
+ ret = copy_to_user(&name->sname[0], &utsname()->sysname[0],
sizeof(name->sname) - 1);
- ret |= copy_to_user(&name->nname[0], &system_utsname.nodename[0],
+ ret |= copy_to_user(&name->nname[0], &utsname()->nodename[0],
sizeof(name->nname) - 1);
ret |= put_user('\0', &name->nname[8]);
- ret |= copy_to_user(&name->rel[0], &system_utsname.release[0],
+ ret |= copy_to_user(&name->rel[0], &utsname()->release[0],
sizeof(name->rel) - 1);
- ret |= copy_to_user(&name->ver[0], &system_utsname.version[0],
+ ret |= copy_to_user(&name->ver[0], &utsname()->version[0],
sizeof(name->ver) - 1);
- ret |= copy_to_user(&name->mach[0], &system_utsname.machine[0],
+ ret |= copy_to_user(&name->mach[0], &utsname()->machine[0],
sizeof(name->mach) - 1);
up_read(&uts_sem);
return (ret ? -EFAULT : 0);
diff --git a/arch/sparc64/kernel/time.c b/arch/sparc64/kernel/time.c
index b0b4feeec098..00f6fc4aaaff 100644
--- a/arch/sparc64/kernel/time.c
+++ b/arch/sparc64/kernel/time.c
@@ -53,8 +53,6 @@ void __iomem *mstk48t02_regs = NULL;
unsigned long ds1287_regs = 0UL;
#endif
-extern unsigned long wall_jiffies;
-
static void __iomem *mstk48t08_regs;
static void __iomem *mstk48t59_regs;
@@ -465,7 +463,7 @@ irqreturn_t timer_interrupt(int irq, void *dev_id, struct pt_regs * regs)
profile_tick(CPU_PROFILING, regs);
update_process_times(user_mode(regs));
#endif
- do_timer(regs);
+ do_timer(1);
/* Guarantee that the following sequences execute
* uninterrupted.
@@ -496,7 +494,7 @@ void timer_tick_interrupt(struct pt_regs *regs)
{
write_seqlock(&xtime_lock);
- do_timer(regs);
+ do_timer(1);
timer_check_rtc();
diff --git a/arch/sparc64/solaris/fs.c b/arch/sparc64/solaris/fs.c
index 0f0eb6aa1c40..12a940cc791f 100644
--- a/arch/sparc64/solaris/fs.c
+++ b/arch/sparc64/solaris/fs.c
@@ -82,12 +82,17 @@ struct sol_stat64 {
static inline int putstat(struct sol_stat __user *ubuf, struct kstat *kbuf)
{
+ u32 ino;
+
if (kbuf->size > MAX_NON_LFS ||
!sysv_valid_dev(kbuf->dev) ||
!sysv_valid_dev(kbuf->rdev))
return -EOVERFLOW;
+ ino = kbuf->ino;
+ if (sizeof(ino) < sizeof(kbuf->ino) && ino != kbuf->ino)
+ return -EOVERFLOW;
if (put_user (sysv_encode_dev(kbuf->dev), &ubuf->st_dev) ||
- __put_user (kbuf->ino, &ubuf->st_ino) ||
+ __put_user (ino, &ubuf->st_ino) ||
__put_user (kbuf->mode, &ubuf->st_mode) ||
__put_user (kbuf->nlink, &ubuf->st_nlink) ||
__put_user (kbuf->uid, &ubuf->st_uid) ||
diff --git a/arch/sparc64/solaris/misc.c b/arch/sparc64/solaris/misc.c
index 642541769a17..9ed997982f8d 100644
--- a/arch/sparc64/solaris/misc.c
+++ b/arch/sparc64/solaris/misc.c
@@ -11,6 +11,7 @@
#include <linux/limits.h>
#include <linux/mm.h>
#include <linux/smp.h>
+#include <linux/tty.h>
#include <linux/mman.h>
#include <linux/file.h>
#include <linux/timex.h>
@@ -248,7 +249,7 @@ asmlinkage int solaris_utssys(u32 buf, u32 flags, int which, u32 buf2)
/* Let's cheat */
err = set_utsfield(v->sysname, "SunOS", 1, 0);
down_read(&uts_sem);
- err |= set_utsfield(v->nodename, system_utsname.nodename,
+ err |= set_utsfield(v->nodename, utsname()->nodename,
1, 1);
up_read(&uts_sem);
err |= set_utsfield(v->release, "2.6", 0, 0);
@@ -272,7 +273,7 @@ asmlinkage int solaris_utsname(u32 buf)
/* Why should we not lie a bit? */
down_read(&uts_sem);
err = set_utsfield(v->sysname, "SunOS", 0, 0);
- err |= set_utsfield(v->nodename, system_utsname.nodename, 1, 1);
+ err |= set_utsfield(v->nodename, utsname()->nodename, 1, 1);
err |= set_utsfield(v->release, "5.6", 0, 0);
err |= set_utsfield(v->version, "Generic", 0, 0);
err |= set_utsfield(v->machine, machine(), 0, 0);
@@ -304,7 +305,7 @@ asmlinkage int solaris_sysinfo(int cmd, u32 buf, s32 count)
case SI_HOSTNAME:
r = buffer + 256;
down_read(&uts_sem);
- for (p = system_utsname.nodename, q = buffer;
+ for (p = utsname()->nodename, q = buffer;
q < r && *p && *p != '.'; *q++ = *p++);
up_read(&uts_sem);
*q = 0;
@@ -422,7 +423,9 @@ asmlinkage int solaris_procids(int cmd, s32 pid, s32 pgid)
Solaris setpgrp and setsid? */
ret = sys_setpgid(0, 0);
if (ret) return ret;
+ mutex_lock(&tty_mutex);
current->signal->tty = NULL;
+ mutex_unlock(&tty_mutex);
return process_group(current);
}
case 2: /* getsid */
diff --git a/arch/um/drivers/line.c b/arch/um/drivers/line.c
index 563ce7690a1e..24747a413785 100644
--- a/arch/um/drivers/line.c
+++ b/arch/um/drivers/line.c
@@ -642,9 +642,9 @@ int line_remove(struct line *lines, unsigned int num, int n)
}
struct tty_driver *line_register_devfs(struct lines *set,
- struct line_driver *line_driver,
- struct tty_operations *ops, struct line *lines,
- int nlines)
+ struct line_driver *line_driver,
+ const struct tty_operations *ops,
+ struct line *lines, int nlines)
{
int i;
struct tty_driver *driver = alloc_tty_driver(nlines);
diff --git a/arch/um/drivers/mconsole_kern.c b/arch/um/drivers/mconsole_kern.c
index 79610b5ce67e..a67dcbd78de4 100644
--- a/arch/um/drivers/mconsole_kern.c
+++ b/arch/um/drivers/mconsole_kern.c
@@ -106,9 +106,9 @@ void mconsole_version(struct mc_request *req)
{
char version[256];
- sprintf(version, "%s %s %s %s %s", system_utsname.sysname,
- system_utsname.nodename, system_utsname.release,
- system_utsname.version, system_utsname.machine);
+ sprintf(version, "%s %s %s %s %s", utsname()->sysname,
+ utsname()->nodename, utsname()->release,
+ utsname()->version, utsname()->machine);
mconsole_reply(req, version, 0, 0);
}
@@ -598,6 +598,11 @@ out:
mconsole_reply(req, err_msg, err, 0);
}
+struct mconsole_output {
+ struct list_head list;
+ struct mc_request *req;
+};
+
static DEFINE_SPINLOCK(console_lock);
static LIST_HEAD(clients);
static char console_buf[MCONSOLE_MAX_DATA];
@@ -622,10 +627,10 @@ static void console_write(struct console *console, const char *string,
return;
list_for_each(ele, &clients){
- struct mconsole_entry *entry;
+ struct mconsole_output *entry;
- entry = list_entry(ele, struct mconsole_entry, list);
- mconsole_reply_len(&entry->request, console_buf,
+ entry = list_entry(ele, struct mconsole_output, list);
+ mconsole_reply_len(entry->req, console_buf,
console_index, 0, 1);
}
@@ -649,10 +654,10 @@ late_initcall(mc_add_console);
static void with_console(struct mc_request *req, void (*proc)(void *),
void *arg)
{
- struct mconsole_entry entry;
+ struct mconsole_output entry;
unsigned long flags;
- entry.request = *req;
+ entry.req = req;
list_add(&entry.list, &clients);
spin_lock_irqsave(&console_lock, flags);
diff --git a/arch/um/drivers/mconsole_user.c b/arch/um/drivers/mconsole_user.c
index 5b2f5fe9e426..17068eb746c0 100644
--- a/arch/um/drivers/mconsole_user.c
+++ b/arch/um/drivers/mconsole_user.c
@@ -131,6 +131,10 @@ int mconsole_get_request(int fd, struct mc_request *req)
int mconsole_reply_len(struct mc_request *req, const char *str, int total,
int err, int more)
{
+ /* XXX This is a stack consumption problem. It'd be nice to
+ * make it global and serialize access to it, but there are a
+ * ton of callers to this function.
+ */
struct mconsole_reply reply;
int len, n;
diff --git a/arch/um/drivers/net_kern.c b/arch/um/drivers/net_kern.c
index 664c2e2fb820..300a54a6523e 100644
--- a/arch/um/drivers/net_kern.c
+++ b/arch/um/drivers/net_kern.c
@@ -119,11 +119,6 @@ static int uml_net_open(struct net_device *dev)
goto out;
}
- if(!lp->have_mac){
- dev_ip_addr(dev, &lp->mac[2]);
- set_ether_mac(dev, lp->mac);
- }
-
lp->fd = (*lp->open)(&lp->user);
if(lp->fd < 0){
err = lp->fd;
@@ -287,6 +282,37 @@ void uml_net_user_timer_expire(unsigned long _conn)
#endif
}
+static void setup_etheraddr(char *str, unsigned char *addr)
+{
+ char *end;
+ int i;
+
+ if(str == NULL)
+ goto random;
+
+ for(i=0;i<6;i++){
+ addr[i] = simple_strtoul(str, &end, 16);
+ if((end == str) ||
+ ((*end != ':') && (*end != ',') && (*end != '\0'))){
+ printk(KERN_ERR
+ "setup_etheraddr: failed to parse '%s' "
+ "as an ethernet address\n", str);
+ goto random;
+ }
+ str = end + 1;
+ }
+ if(addr[0] & 1){
+ printk(KERN_ERR
+ "Attempt to assign a broadcast ethernet address to a "
+ "device disallowed\n");
+ goto random;
+ }
+ return;
+
+random:
+ random_ether_addr(addr);
+}
+
static DEFINE_SPINLOCK(devices_lock);
static LIST_HEAD(devices);
@@ -322,15 +348,13 @@ static int eth_configure(int n, void *init, char *mac,
list_add(&device->list, &devices);
spin_unlock(&devices_lock);
- if (setup_etheraddr(mac, device->mac))
- device->have_mac = 1;
+ setup_etheraddr(mac, device->mac);
printk(KERN_INFO "Netdevice %d ", n);
- if (device->have_mac)
- printk("(%02x:%02x:%02x:%02x:%02x:%02x) ",
- device->mac[0], device->mac[1],
- device->mac[2], device->mac[3],
- device->mac[4], device->mac[5]);
+ printk("(%02x:%02x:%02x:%02x:%02x:%02x) ",
+ device->mac[0], device->mac[1],
+ device->mac[2], device->mac[3],
+ device->mac[4], device->mac[5]);
printk(": ");
dev = alloc_etherdev(size);
if (dev == NULL) {
@@ -396,7 +420,6 @@ static int eth_configure(int n, void *init, char *mac,
.dev = dev,
.fd = -1,
.mac = { 0xfe, 0xfd, 0x0, 0x0, 0x0, 0x0},
- .have_mac = device->have_mac,
.protocol = transport->kern->protocol,
.open = transport->user->open,
.close = transport->user->close,
@@ -411,14 +434,12 @@ static int eth_configure(int n, void *init, char *mac,
init_timer(&lp->tl);
spin_lock_init(&lp->lock);
lp->tl.function = uml_net_user_timer_expire;
- if (lp->have_mac)
- memcpy(lp->mac, device->mac, sizeof(lp->mac));
+ memcpy(lp->mac, device->mac, sizeof(lp->mac));
if (transport->user->init)
(*transport->user->init)(&lp->user, dev);
- if (device->have_mac)
- set_ether_mac(dev, device->mac);
+ set_ether_mac(dev, device->mac);
return 0;
}
@@ -747,47 +768,6 @@ static void close_devices(void)
__uml_exitcall(close_devices);
-int setup_etheraddr(char *str, unsigned char *addr)
-{
- char *end;
- int i;
-
- if(str == NULL)
- return(0);
- for(i=0;i<6;i++){
- addr[i] = simple_strtoul(str, &end, 16);
- if((end == str) ||
- ((*end != ':') && (*end != ',') && (*end != '\0'))){
- printk(KERN_ERR
- "setup_etheraddr: failed to parse '%s' "
- "as an ethernet address\n", str);
- return(0);
- }
- str = end + 1;
- }
- if(addr[0] & 1){
- printk(KERN_ERR
- "Attempt to assign a broadcast ethernet address to a "
- "device disallowed\n");
- return(0);
- }
- return(1);
-}
-
-void dev_ip_addr(void *d, unsigned char *bin_buf)
-{
- struct net_device *dev = d;
- struct in_device *ip = dev->ip_ptr;
- struct in_ifaddr *in;
-
- if((ip == NULL) || ((in = ip->ifa_list) == NULL)){
- printk(KERN_WARNING "dev_ip_addr - device not assigned an "
- "IP address\n");
- return;
- }
- memcpy(bin_buf, &in->ifa_address, sizeof(in->ifa_address));
-}
-
struct sk_buff *ether_adjust_skb(struct sk_buff *skb, int extra)
{
if((skb != NULL) && (skb_tailroom(skb) < extra)){
@@ -825,7 +805,7 @@ int dev_netmask(void *d, void *m)
struct net_device *dev = d;
struct in_device *ip = dev->ip_ptr;
struct in_ifaddr *in;
- __u32 *mask_out = m;
+ __be32 *mask_out = m;
if(ip == NULL)
return(1);
diff --git a/arch/um/drivers/net_user.c b/arch/um/drivers/net_user.c
index 107c5e43fa00..f3a3f8a29c7a 100644
--- a/arch/um/drivers/net_user.c
+++ b/arch/um/drivers/net_user.c
@@ -12,6 +12,7 @@
#include <string.h>
#include <sys/socket.h>
#include <sys/wait.h>
+#include <sys/time.h>
#include "user.h"
#include "user_util.h"
#include "kern_util.h"
diff --git a/arch/um/drivers/null.c b/arch/um/drivers/null.c
index 3683ed44315d..9016c68beee8 100644
--- a/arch/um/drivers/null.c
+++ b/arch/um/drivers/null.c
@@ -8,6 +8,7 @@
#include "chan_user.h"
#include "os.h"
+/* This address is used only as a unique identifer */
static int null_chan;
static void *null_init(char *str, int device, const struct chan_opts *opts)
diff --git a/arch/um/drivers/random.c b/arch/um/drivers/random.c
index ae9909415b9c..73b2bdd6d2d3 100644
--- a/arch/um/drivers/random.c
+++ b/arch/um/drivers/random.c
@@ -20,6 +20,10 @@
#define RNG_MISCDEV_MINOR 183 /* official */
+/* Changed at init time, in the non-modular case, and at module load
+ * time, in the module case. Presumably, the module subsystem
+ * protects against a module being loaded twice at the same time.
+ */
static int random_fd = -1;
static int rng_dev_open (struct inode *inode, struct file *filp)
diff --git a/arch/um/drivers/stderr_console.c b/arch/um/drivers/stderr_console.c
index 6d2cf32a9e8f..911539293871 100644
--- a/arch/um/drivers/stderr_console.c
+++ b/arch/um/drivers/stderr_console.c
@@ -9,6 +9,8 @@
/*
* Don't register by default -- as this registeres very early in the
* boot process it becomes the default console.
+ *
+ * Initialized at init time.
*/
static int use_stderr_console = 0;
diff --git a/arch/um/drivers/stdio_console.c b/arch/um/drivers/stdio_console.c
index 5e44adb07051..e4bfcfe8550b 100644
--- a/arch/um/drivers/stdio_console.c
+++ b/arch/um/drivers/stdio_console.c
@@ -108,6 +108,7 @@ static int con_open(struct tty_struct *tty, struct file *filp)
return line_open(vts, tty);
}
+/* Set in an initcall, checked in an exitcall */
static int con_init_done = 0;
static const struct tty_operations console_ops = {
diff --git a/arch/um/drivers/ubd_kern.c b/arch/um/drivers/ubd_kern.c
index 34085315aa57..fda4a3940698 100644
--- a/arch/um/drivers/ubd_kern.c
+++ b/arch/um/drivers/ubd_kern.c
@@ -668,18 +668,15 @@ static int ubd_add(int n)
if(dev->file == NULL)
goto out;
- if (ubd_open_dev(dev))
- goto out;
-
err = ubd_file_size(dev, &dev->size);
if(err < 0)
- goto out_close;
+ goto out;
dev->size = ROUND_BLOCK(dev->size);
err = ubd_new_disk(MAJOR_NR, dev->size, n, &ubd_gendisk[n]);
if(err)
- goto out_close;
+ goto out;
if(fake_major != MAJOR_NR)
ubd_new_disk(fake_major, dev->size, n,
@@ -691,8 +688,6 @@ static int ubd_add(int n)
make_ide_entries(ubd_gendisk[n]->disk_name);
err = 0;
-out_close:
- ubd_close(dev);
out:
return err;
}
@@ -986,8 +981,6 @@ static int prepare_request(struct request *req, struct io_thread_req *io_req)
__u64 offset;
int len;
- if(req->rq_status == RQ_INACTIVE) return(1);
-
/* This should be impossible now */
if((rq_data_dir(req) == WRITE) && !dev->openflags.w){
printk("Write attempted on readonly ubd device %s\n",
diff --git a/arch/um/include/line.h b/arch/um/include/line.h
index 642c9a0320f9..7be24811bb30 100644
--- a/arch/um/include/line.h
+++ b/arch/um/include/line.h
@@ -91,10 +91,9 @@ extern int line_setup_irq(int fd, int input, int output, struct line *line,
void *data);
extern void line_close_chan(struct line *line);
extern struct tty_driver * line_register_devfs(struct lines *set,
- struct line_driver *line_driver,
- struct tty_operations *driver,
- struct line *lines,
- int nlines);
+ struct line_driver *line_driver,
+ const struct tty_operations *driver,
+ struct line *lines, int nlines);
extern void lines_init(struct line *lines, int nlines, struct chan_opts *opts);
extern void close_lines(struct line *lines, int nlines);
diff --git a/arch/um/include/net_kern.h b/arch/um/include/net_kern.h
index 769fba43ee03..280459fb0b26 100644
--- a/arch/um/include/net_kern.h
+++ b/arch/um/include/net_kern.h
@@ -18,7 +18,6 @@ struct uml_net {
struct platform_device pdev;
int index;
unsigned char mac[ETH_ALEN];
- int have_mac;
};
struct uml_net_private {
@@ -29,7 +28,6 @@ struct uml_net_private {
struct net_device_stats stats;
int fd;
unsigned char mac[ETH_ALEN];
- int have_mac;
unsigned short (*protocol)(struct sk_buff *);
int (*open)(void *);
void (*close)(int, void *);
@@ -62,7 +60,6 @@ struct transport {
extern struct net_device *ether_init(int);
extern unsigned short ether_protocol(struct sk_buff *);
-extern int setup_etheraddr(char *str, unsigned char *addr);
extern struct sk_buff *ether_adjust_skb(struct sk_buff *skb, int extra);
extern int tap_setup_common(char *str, char *type, char **dev_name,
char **mac_out, char **gate_addr);
@@ -70,14 +67,3 @@ extern void register_transport(struct transport *new);
extern unsigned short eth_protocol(struct sk_buff *skb);
#endif
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only. This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/arch/um/include/net_user.h b/arch/um/include/net_user.h
index 47ef7cb49a8e..19f207cd70fe 100644
--- a/arch/um/include/net_user.h
+++ b/arch/um/include/net_user.h
@@ -1,4 +1,4 @@
-/*
+/*
* Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
* Licensed under the GPL
*/
@@ -25,9 +25,8 @@ struct net_user_info {
};
extern void ether_user_init(void *data, void *dev);
-extern void dev_ip_addr(void *d, unsigned char *bin_buf);
-extern void iter_addresses(void *d, void (*cb)(unsigned char *,
- unsigned char *, void *),
+extern void iter_addresses(void *d, void (*cb)(unsigned char *,
+ unsigned char *, void *),
void *arg);
extern void *get_output_buffer(int *len_out);
@@ -52,14 +51,3 @@ extern char *split_if_spec(char *str, ...);
extern int dev_netmask(void *d, void *m);
#endif
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only. This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/arch/um/kernel/exitcode.c b/arch/um/kernel/exitcode.c
index d21ebad666b4..8b7f2cdedf94 100644
--- a/arch/um/kernel/exitcode.c
+++ b/arch/um/kernel/exitcode.c
@@ -16,9 +16,13 @@ int uml_exitcode = 0;
static int read_proc_exitcode(char *page, char **start, off_t off,
int count, int *eof, void *data)
{
- int len;
+ int len, val;
- len = sprintf(page, "%d\n", uml_exitcode);
+ /* Save uml_exitcode in a local so that we don't need to guarantee
+ * that sprintf accesses it atomically.
+ */
+ val = uml_exitcode;
+ len = sprintf(page, "%d\n", val);
len -= off;
if(len <= off+count) *eof = 1;
*start = page + off;
diff --git a/arch/um/kernel/skas/mmu.c b/arch/um/kernel/skas/mmu.c
index 79c22707a637..4cd2ff546ef6 100644
--- a/arch/um/kernel/skas/mmu.c
+++ b/arch/um/kernel/skas/mmu.c
@@ -61,8 +61,10 @@ static int init_stub_pte(struct mm_struct *mm, unsigned long proc,
#endif
*pte = mk_pte(virt_to_page(kernel), __pgprot(_PAGE_PRESENT));
- *pte = pte_mkexec(*pte);
- *pte = pte_wrprotect(*pte);
+ /* This is wrong for the code page, but it doesn't matter since the
+ * stub is mapped by hand with the correct permissions.
+ */
+ *pte = pte_mkwrite(*pte);
return(0);
out_pmd:
diff --git a/arch/um/kernel/skas/process_kern.c b/arch/um/kernel/skas/process_kern.c
deleted file mode 100644
index 0f3d5d084dc7..000000000000
--- a/arch/um/kernel/skas/process_kern.c
+++ /dev/null
@@ -1,484 +0,0 @@
-/*
- * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
- * Copyright 2003 PathScale, Inc.
- * Licensed under the GPL
- */
-
-#include "linux/config.h"
-#include "linux/kernel.h"
-#include "linux/sched.h"
-#include "linux/interrupt.h"
-#include "linux/string.h"
-#include "linux/mm.h"
-#include "linux/slab.h"
-#include "linux/utsname.h"
-#include "linux/fs.h"
-#include "linux/utime.h"
-#include "linux/smp_lock.h"
-#include "linux/module.h"
-#include "linux/init.h"
-#include "linux/capability.h"
-#include "linux/vmalloc.h"
-#include "linux/spinlock.h"
-#include "linux/proc_fs.h"
-#include "linux/ptrace.h"
-#include "linux/random.h"
-#include "linux/personality.h"
-#include "asm/unistd.h"
-#include "asm/mman.h"
-#include "asm/segment.h"
-#include "asm/stat.h"
-#include "asm/pgtable.h"
-#include "asm/processor.h"
-#include "asm/tlbflush.h"
-#include "asm/uaccess.h"
-#include "asm/user.h"
-#include "user_util.h"
-#include "kern_util.h"
-#include "kern.h"
-#include "signal_kern.h"
-#include "init.h"
-#include "irq_user.h"
-#include "mem_user.h"
-#include "tlb.h"
-#include "frame_kern.h"
-#include "sigcontext.h"
-#include "os.h"
-#include "mode.h"
-#include "mode_kern.h"
-#include "choose-mode.h"
-
-/* This is a per-cpu array. A processor only modifies its entry and it only
- * cares about its entry, so it's OK if another processor is modifying its
- * entry.
- */
-struct cpu_task cpu_tasks[NR_CPUS] = { [0 ... NR_CPUS - 1] = { -1, NULL } };
-
-int external_pid(void *t)
-{
- struct task_struct *task = t ? t : current;
-
- return(CHOOSE_MODE_PROC(external_pid_tt, external_pid_skas, task));
-}
-
-int pid_to_processor_id(int pid)
-{
- int i;
-
- for(i = 0; i < ncpus; i++){
- if(cpu_tasks[i].pid == pid) return(i);
- }
- return(-1);
-}
-
-void free_stack(unsigned long stack, int order)
-{
- free_pages(stack, order);
-}
-
-unsigned long alloc_stack(int order, int atomic)
-{
- unsigned long page;
- gfp_t flags = GFP_KERNEL;
-
- if (atomic)
- flags = GFP_ATOMIC;
- page = __get_free_pages(flags, order);
- if(page == 0)
- return(0);
- stack_protections(page);
- return(page);
-}
-
-int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
-{
- int pid;
-
- current->thread.request.u.thread.proc = fn;
- current->thread.request.u.thread.arg = arg;
- pid = do_fork(CLONE_VM | CLONE_UNTRACED | flags, 0,
- &current->thread.regs, 0, NULL, NULL);
- if(pid < 0)
- panic("do_fork failed in kernel_thread, errno = %d", pid);
- return(pid);
-}
-
-void set_current(void *t)
-{
- struct task_struct *task = t;
-
- cpu_tasks[task_thread_info(task)->cpu] = ((struct cpu_task)
- { external_pid(task), task });
-}
-
-void *_switch_to(void *prev, void *next, void *last)
-{
- struct task_struct *from = prev;
- struct task_struct *to= next;
-
- to->thread.prev_sched = from;
- set_current(to);
-
- do {
- current->thread.saved_task = NULL ;
- CHOOSE_MODE_PROC(switch_to_tt, switch_to_skas, prev, next);
- if(current->thread.saved_task)
- show_regs(&(current->thread.regs));
- next= current->thread.saved_task;
- prev= current;
- } while(current->thread.saved_task);
-
- return(current->thread.prev_sched);
-
-}
-
-void interrupt_end(void)
-{
- if(need_resched()) schedule();
- if(test_tsk_thread_flag(current, TIF_SIGPENDING)) do_signal();
-}
-
-void release_thread(struct task_struct *task)
-{
- CHOOSE_MODE(release_thread_tt(task), release_thread_skas(task));
-}
-
-void exit_thread(void)
-{
- unprotect_stack((unsigned long) current_thread);
-}
-
-void *get_current(void)
-{
- return(current);
-}
-
-int copy_thread(int nr, unsigned long clone_flags, unsigned long sp,
- unsigned long stack_top, struct task_struct * p,
- struct pt_regs *regs)
-{
- int ret;
-
- p->thread = (struct thread_struct) INIT_THREAD;
- ret = CHOOSE_MODE_PROC(copy_thread_tt, copy_thread_skas, nr,
- clone_flags, sp, stack_top, p, regs);
-
- if (ret || !current->thread.forking)
- goto out;
-
- clear_flushed_tls(p);
-
- /*
- * Set a new TLS for the child thread?
- */
- if (clone_flags & CLONE_SETTLS)
- ret = arch_copy_tls(p);
-
-out:
- return ret;
-}
-
-void initial_thread_cb(void (*proc)(void *), void *arg)
-{
- int save_kmalloc_ok = kmalloc_ok;
-
- kmalloc_ok = 0;
- CHOOSE_MODE_PROC(initial_thread_cb_tt, initial_thread_cb_skas, proc,
- arg);
- kmalloc_ok = save_kmalloc_ok;
-}
-
-unsigned long stack_sp(unsigned long page)
-{
- return(page + PAGE_SIZE - sizeof(void *));
-}
-
-int current_pid(void)
-{
- return(current->pid);
-}
-
-void default_idle(void)
-{
- CHOOSE_MODE(uml_idle_timer(), (void) 0);
-
- while(1){
- /* endless idle loop with no priority at all */
-
- /*
- * although we are an idle CPU, we do not want to
- * get into the scheduler unnecessarily.
- */
- if(need_resched())
- schedule();
-
- idle_sleep(10);
- }
-}
-
-void cpu_idle(void)
-{
- CHOOSE_MODE(init_idle_tt(), init_idle_skas());
-}
-
-int page_size(void)
-{
- return(PAGE_SIZE);
-}
-
-void *um_virt_to_phys(struct task_struct *task, unsigned long addr,
- pte_t *pte_out)
-{
- pgd_t *pgd;
- pud_t *pud;
- pmd_t *pmd;
- pte_t *pte;
- pte_t ptent;
-
- if(task->mm == NULL)
- return(ERR_PTR(-EINVAL));
- pgd = pgd_offset(task->mm, addr);
- if(!pgd_present(*pgd))
- return(ERR_PTR(-EINVAL));
-
- pud = pud_offset(pgd, addr);
- if(!pud_present(*pud))
- return(ERR_PTR(-EINVAL));
-
- pmd = pmd_offset(pud, addr);
- if(!pmd_present(*pmd))
- return(ERR_PTR(-EINVAL));
-
- pte = pte_offset_kernel(pmd, addr);
- ptent = *pte;
- if(!pte_present(ptent))
- return(ERR_PTR(-EINVAL));
-
- if(pte_out != NULL)
- *pte_out = ptent;
- return((void *) (pte_val(ptent) & PAGE_MASK) + (addr & ~PAGE_MASK));
-}
-
-char *current_cmd(void)
-{
-#if defined(CONFIG_SMP) || defined(CONFIG_HIGHMEM)
- return("(Unknown)");
-#else
- void *addr = um_virt_to_phys(current, current->mm->arg_start, NULL);
- return IS_ERR(addr) ? "(Unknown)": __va((unsigned long) addr);
-#endif
-}
-
-void force_sigbus(void)
-{
- printk(KERN_ERR "Killing pid %d because of a lack of memory\n",
- current->pid);
- lock_kernel();
- sigaddset(&current->pending.signal, SIGBUS);
- recalc_sigpending();
- current->flags |= PF_SIGNALED;
- do_exit(SIGBUS | 0x80);
-}
-
-void dump_thread(struct pt_regs *regs, struct user *u)
-{
-}
-
-void enable_hlt(void)
-{
- panic("enable_hlt");
-}
-
-EXPORT_SYMBOL(enable_hlt);
-
-void disable_hlt(void)
-{
- panic("disable_hlt");
-}
-
-EXPORT_SYMBOL(disable_hlt);
-
-void *um_kmalloc(int size)
-{
- return kmalloc(size, GFP_KERNEL);
-}
-
-void *um_kmalloc_atomic(int size)
-{
- return kmalloc(size, GFP_ATOMIC);
-}
-
-void *um_vmalloc(int size)
-{
- return vmalloc(size);
-}
-
-void *um_vmalloc_atomic(int size)
-{
- return __vmalloc(size, GFP_ATOMIC | __GFP_HIGHMEM, PAGE_KERNEL);
-}
-
-int __cant_sleep(void) {
- return in_atomic() || irqs_disabled() || in_interrupt();
- /* Is in_interrupt() really needed? */
-}
-
-unsigned long get_fault_addr(void)
-{
- return((unsigned long) current->thread.fault_addr);
-}
-
-EXPORT_SYMBOL(get_fault_addr);
-
-void not_implemented(void)
-{
- printk(KERN_DEBUG "Something isn't implemented in here\n");
-}
-
-EXPORT_SYMBOL(not_implemented);
-
-int user_context(unsigned long sp)
-{
- unsigned long stack;
-
- stack = sp & (PAGE_MASK << CONFIG_KERNEL_STACK_ORDER);
- return(stack != (unsigned long) current_thread);
-}
-
-extern exitcall_t __uml_exitcall_begin, __uml_exitcall_end;
-
-void do_uml_exitcalls(void)
-{
- exitcall_t *call;
-
- call = &__uml_exitcall_end;
- while (--call >= &__uml_exitcall_begin)
- (*call)();
-}
-
-char *uml_strdup(char *string)
-{
- return kstrdup(string, GFP_KERNEL);
-}
-
-int copy_to_user_proc(void __user *to, void *from, int size)
-{
- return(copy_to_user(to, from, size));
-}
-
-int copy_from_user_proc(void *to, void __user *from, int size)
-{
- return(copy_from_user(to, from, size));
-}
-
-int clear_user_proc(void __user *buf, int size)
-{
- return(clear_user(buf, size));
-}
-
-int strlen_user_proc(char __user *str)
-{
- return(strlen_user(str));
-}
-
-int smp_sigio_handler(void)
-{
-#ifdef CONFIG_SMP
- int cpu = current_thread->cpu;
- IPI_handler(cpu);
- if(cpu != 0)
- return(1);
-#endif
- return(0);
-}
-
-int cpu(void)
-{
- return(current_thread->cpu);
-}
-
-static atomic_t using_sysemu = ATOMIC_INIT(0);
-int sysemu_supported;
-
-void set_using_sysemu(int value)
-{
- if (value > sysemu_supported)
- return;
- atomic_set(&using_sysemu, value);
-}
-
-int get_using_sysemu(void)
-{
- return atomic_read(&using_sysemu);
-}
-
-static int proc_read_sysemu(char *buf, char **start, off_t offset, int size,int *eof, void *data)
-{
- if (snprintf(buf, size, "%d\n", get_using_sysemu()) < size) /*No overflow*/
- *eof = 1;
-
- return strlen(buf);
-}
-
-static int proc_write_sysemu(struct file *file,const char __user *buf, unsigned long count,void *data)
-{
- char tmp[2];
-
- if (copy_from_user(tmp, buf, 1))
- return -EFAULT;
-
- if (tmp[0] >= '0' && tmp[0] <= '2')
- set_using_sysemu(tmp[0] - '0');
- return count; /*We use the first char, but pretend to write everything*/
-}
-
-int __init make_proc_sysemu(void)
-{
- struct proc_dir_entry *ent;
- if (!sysemu_supported)
- return 0;
-
- ent = create_proc_entry("sysemu", 0600, &proc_root);
-
- if (ent == NULL)
- {
- printk(KERN_WARNING "Failed to register /proc/sysemu\n");
- return(0);
- }
-
- ent->read_proc = proc_read_sysemu;
- ent->write_proc = proc_write_sysemu;
-
- return 0;
-}
-
-late_initcall(make_proc_sysemu);
-
-int singlestepping(void * t)
-{
- struct task_struct *task = t ? t : current;
-
- if ( ! (task->ptrace & PT_DTRACE) )
- return(0);
-
- if (task->thread.singlestep_syscall)
- return(1);
-
- return 2;
-}
-
-/*
- * Only x86 and x86_64 have an arch_align_stack().
- * All other arches have "#define arch_align_stack(x) (x)"
- * in their asm/system.h
- * As this is included in UML from asm-um/system-generic.h,
- * we can use it to behave as the subarch does.
- */
-#ifndef arch_align_stack
-unsigned long arch_align_stack(unsigned long sp)
-{
- if (!(current->personality & ADDR_NO_RANDOMIZE) && randomize_va_space)
- sp -= get_random_int() % 8192;
- return sp & ~0xf;
-}
-#endif
diff --git a/arch/um/kernel/syscall.c b/arch/um/kernel/syscall.c
index 48cf88dd02d4..f5ed8624648b 100644
--- a/arch/um/kernel/syscall.c
+++ b/arch/um/kernel/syscall.c
@@ -110,7 +110,7 @@ long sys_uname(struct old_utsname __user * name)
if (!name)
return -EFAULT;
down_read(&uts_sem);
- err = copy_to_user(name, &system_utsname, sizeof (*name));
+ err = copy_to_user(name, utsname(), sizeof (*name));
up_read(&uts_sem);
return err?-EFAULT:0;
}
@@ -126,21 +126,21 @@ long sys_olduname(struct oldold_utsname __user * name)
down_read(&uts_sem);
- error = __copy_to_user(&name->sysname,&system_utsname.sysname,
+ error = __copy_to_user(&name->sysname, &utsname()->sysname,
__OLD_UTS_LEN);
- error |= __put_user(0,name->sysname+__OLD_UTS_LEN);
- error |= __copy_to_user(&name->nodename,&system_utsname.nodename,
+ error |= __put_user(0, name->sysname + __OLD_UTS_LEN);
+ error |= __copy_to_user(&name->nodename, &utsname()->nodename,
__OLD_UTS_LEN);
- error |= __put_user(0,name->nodename+__OLD_UTS_LEN);
- error |= __copy_to_user(&name->release,&system_utsname.release,
+ error |= __put_user(0, name->nodename + __OLD_UTS_LEN);
+ error |= __copy_to_user(&name->release, &utsname()->release,
__OLD_UTS_LEN);
- error |= __put_user(0,name->release+__OLD_UTS_LEN);
- error |= __copy_to_user(&name->version,&system_utsname.version,
+ error |= __put_user(0, name->release + __OLD_UTS_LEN);
+ error |= __copy_to_user(&name->version, &utsname()->version,
__OLD_UTS_LEN);
- error |= __put_user(0,name->version+__OLD_UTS_LEN);
- error |= __copy_to_user(&name->machine,&system_utsname.machine,
+ error |= __put_user(0, name->version + __OLD_UTS_LEN);
+ error |= __copy_to_user(&name->machine, &utsname()->machine,
__OLD_UTS_LEN);
- error |= __put_user(0,name->machine+__OLD_UTS_LEN);
+ error |= __put_user(0, name->machine + __OLD_UTS_LEN);
up_read(&uts_sem);
@@ -164,3 +164,16 @@ int next_syscall_index(int limit)
spin_unlock(&syscall_lock);
return(ret);
}
+
+int kernel_execve(const char *filename, char *const argv[], char *const envp[])
+{
+ mm_segment_t fs;
+ int ret;
+
+ fs = get_fs();
+ set_fs(KERNEL_DS);
+ ret = um_execve(filename, argv, envp);
+ set_fs(fs);
+
+ return ret;
+}
diff --git a/arch/um/kernel/time.c b/arch/um/kernel/time.c
index 820affbf3e16..a92965f8f9cd 100644
--- a/arch/um/kernel/time.c
+++ b/arch/um/kernel/time.c
@@ -93,7 +93,7 @@ irqreturn_t um_timer(int irq, void *dev, struct pt_regs *regs)
write_seqlock_irqsave(&xtime_lock, flags);
- do_timer(regs);
+ do_timer(1);
nsecs = get_time();
xtime.tv_sec = nsecs / NSEC_PER_SEC;
diff --git a/arch/um/kernel/trap.c b/arch/um/kernel/trap.c
index 61a23fff4395..c7b195c7e51f 100644
--- a/arch/um/kernel/trap.c
+++ b/arch/um/kernel/trap.c
@@ -120,7 +120,7 @@ out_nosemaphore:
* us unable to handle the page fault gracefully.
*/
out_of_memory:
- if (current->pid == 1) {
+ if (is_init(current)) {
up_read(&mm->mmap_sem);
yield();
down_read(&mm->mmap_sem);
diff --git a/arch/um/kernel/um_arch.c b/arch/um/kernel/um_arch.c
index 55005710dcbb..97d88e7902f7 100644
--- a/arch/um/kernel/um_arch.c
+++ b/arch/um/kernel/um_arch.c
@@ -167,7 +167,7 @@ static char *usage_string =
static int __init uml_version_setup(char *line, int *add)
{
- printf("%s\n", system_utsname.release);
+ printf("%s\n", init_utsname()->release);
exit(0);
return 0;
@@ -278,7 +278,7 @@ static int __init Usage(char *line, int *add)
{
const char **p;
- printf(usage_string, system_utsname.release);
+ printf(usage_string, init_utsname()->release);
p = &__uml_help_start;
while (p < &__uml_help_end) {
printf("%s", *p);
@@ -403,7 +403,7 @@ int linux_main(int argc, char **argv)
/* Reserve up to 4M after the current brk */
uml_reserved = ROUND_4M(brk_start) + (1 << 22);
- setup_machinename(system_utsname.machine);
+ setup_machinename(init_utsname()->machine);
#ifdef CONFIG_CMDLINE_ON_HOST
argv1_begin = argv[1];
diff --git a/arch/um/os-Linux/mem.c b/arch/um/os-Linux/mem.c
index b170b4704dc4..4203681e508d 100644
--- a/arch/um/os-Linux/mem.c
+++ b/arch/um/os-Linux/mem.c
@@ -132,6 +132,9 @@ err:
else if(found < 0)
printf("read returned errno %d\n", -found);
+out:
+ close(fd);
+
return;
found:
@@ -141,11 +144,12 @@ found:
if(strncmp(buf, "tmpfs", strlen("tmpfs"))){
printf("not tmpfs\n");
- return;
+ goto out;
}
printf("OK\n");
default_tmpdir = "/dev/shm";
+ goto out;
}
/*
diff --git a/arch/um/os-Linux/process.c b/arch/um/os-Linux/process.c
index ff203625a4bd..51f0893640a6 100644
--- a/arch/um/os-Linux/process.c
+++ b/arch/um/os-Linux/process.c
@@ -11,6 +11,7 @@
#include <sys/mman.h>
#include <sys/wait.h>
#include <sys/mman.h>
+#include <sys/syscall.h>
#include "ptrace_user.h"
#include "os.h"
#include "user.h"
@@ -140,11 +141,9 @@ void os_usr1_process(int pid)
* syscalls, and also breaks with clone(), which does not unshare the TLS.
*/
-inline _syscall0(pid_t, getpid)
-
int os_getpid(void)
{
- return(getpid());
+ return(syscall(__NR_getpid));
}
int os_getpgrp(void)
diff --git a/arch/um/os-Linux/sys-i386/tls.c b/arch/um/os-Linux/sys-i386/tls.c
index 120abbe4e3ce..6e945ab45843 100644
--- a/arch/um/os-Linux/sys-i386/tls.c
+++ b/arch/um/os-Linux/sys-i386/tls.c
@@ -1,10 +1,9 @@
#include <errno.h>
#include <linux/unistd.h>
+#include <sys/syscall.h>
#include "sysdep/tls.h"
#include "user_util.h"
-static _syscall1(int, get_thread_area, user_desc_t *, u_info);
-
/* Checks whether host supports TLS, and sets *tls_min according to the value
* valid on the host.
* i386 host have it == 6; x86_64 host have it == 12, for i386 emulation. */
@@ -17,7 +16,7 @@ void check_host_supports_tls(int *supports_tls, int *tls_min) {
user_desc_t info;
info.entry_number = val[i];
- if (get_thread_area(&info) == 0) {
+ if (syscall(__NR_get_thread_area, &info) == 0) {
*tls_min = val[i];
*supports_tls = 1;
return;
diff --git a/arch/um/os-Linux/tls.c b/arch/um/os-Linux/tls.c
index 9cb09a45546b..a2de2580b8af 100644
--- a/arch/um/os-Linux/tls.c
+++ b/arch/um/os-Linux/tls.c
@@ -1,5 +1,6 @@
#include <errno.h>
#include <sys/ptrace.h>
+#include <sys/syscall.h>
#include <asm/ldt.h>
#include "sysdep/tls.h"
#include "uml-config.h"
@@ -48,14 +49,11 @@ int os_get_thread_area(user_desc_t *info, int pid)
#ifdef UML_CONFIG_MODE_TT
#include "linux/unistd.h"
-static _syscall1(int, get_thread_area, user_desc_t *, u_info);
-static _syscall1(int, set_thread_area, user_desc_t *, u_info);
-
int do_set_thread_area_tt(user_desc_t *info)
{
int ret;
- ret = set_thread_area(info);
+ ret = syscall(__NR_set_thread_area,info);
if (ret < 0) {
ret = -errno;
}
@@ -66,7 +64,7 @@ int do_get_thread_area_tt(user_desc_t *info)
{
int ret;
- ret = get_thread_area(info);
+ ret = syscall(__NR_get_thread_area,info);
if (ret < 0) {
ret = -errno;
}
diff --git a/arch/um/sys-i386/unmap.c b/arch/um/sys-i386/unmap.c
index 1b0ad0e4adcd..8e55cd5d3d07 100644
--- a/arch/um/sys-i386/unmap.c
+++ b/arch/um/sys-i386/unmap.c
@@ -5,20 +5,17 @@
#include <linux/mman.h>
#include <asm/unistd.h>
+#include <sys/syscall.h>
-static int errno;
-
-static inline _syscall2(int,munmap,void *,start,size_t,len)
-static inline _syscall6(void *,mmap2,void *,addr,size_t,len,int,prot,int,flags,int,fd,off_t,offset)
int switcheroo(int fd, int prot, void *from, void *to, int size)
{
- if(munmap(to, size) < 0){
+ if (syscall(__NR_munmap, to, size) < 0){
return(-1);
}
- if(mmap2(to, size, prot, MAP_SHARED | MAP_FIXED, fd, 0) == (void*) -1 ){
+ if (syscall(__NR_mmap2, to, size, prot, MAP_SHARED | MAP_FIXED, fd, 0) == (void*) -1 ){
return(-1);
}
- if(munmap(from, size) < 0){
+ if (syscall(__NR_munmap, from, size) < 0){
return(-1);
}
return(0);
diff --git a/arch/um/sys-x86_64/syscalls.c b/arch/um/sys-x86_64/syscalls.c
index 6fce9f45dfdc..73ce4463f70c 100644
--- a/arch/um/sys-x86_64/syscalls.c
+++ b/arch/um/sys-x86_64/syscalls.c
@@ -21,7 +21,7 @@ asmlinkage long sys_uname64(struct new_utsname __user * name)
{
int err;
down_read(&uts_sem);
- err = copy_to_user(name, &system_utsname, sizeof (*name));
+ err = copy_to_user(name, utsname(), sizeof (*name));
up_read(&uts_sem);
if (personality(current->personality) == PER_LINUX32)
err |= copy_to_user(&name->machine, "i686", 5);
diff --git a/arch/um/sys-x86_64/sysrq.c b/arch/um/sys-x86_64/sysrq.c
index d0a25af19a5b..ce3e07fcf283 100644
--- a/arch/um/sys-x86_64/sysrq.c
+++ b/arch/um/sys-x86_64/sysrq.c
@@ -16,7 +16,7 @@ void __show_regs(struct pt_regs * regs)
printk("\n");
print_modules();
printk("Pid: %d, comm: %.20s %s %s\n",
- current->pid, current->comm, print_tainted(), system_utsname.release);
+ current->pid, current->comm, print_tainted(), init_utsname()->release);
printk("RIP: %04lx:[<%016lx>] ", PT_REGS_CS(regs) & 0xffff,
PT_REGS_RIP(regs));
printk("\nRSP: %016lx EFLAGS: %08lx\n", PT_REGS_RSP(regs),
diff --git a/arch/um/sys-x86_64/unmap.c b/arch/um/sys-x86_64/unmap.c
index f4a4bffd8a18..57c9286a701b 100644
--- a/arch/um/sys-x86_64/unmap.c
+++ b/arch/um/sys-x86_64/unmap.c
@@ -5,20 +5,17 @@
#include <linux/mman.h>
#include <asm/unistd.h>
+#include <sys/syscall.h>
-static int errno;
-
-static inline _syscall2(int,munmap,void *,start,size_t,len)
-static inline _syscall6(void *,mmap,void *,addr,size_t,len,int,prot,int,flags,int,fd,off_t,offset)
int switcheroo(int fd, int prot, void *from, void *to, int size)
{
- if(munmap(to, size) < 0){
+ if (syscall(__NR_munmap, to, size) < 0){
return(-1);
}
- if(mmap(to, size, prot, MAP_SHARED | MAP_FIXED, fd, 0) == (void*) -1){
+ if (syscall(__NR_mmap, to, size, prot, MAP_SHARED | MAP_FIXED, fd, 0) == (void*) -1){
return(-1);
}
- if(munmap(from, size) < 0){
+ if (syscall(__NR_munmap, from, size) < 0){
return(-1);
}
return(0);
diff --git a/arch/v850/kernel/memcons.c b/arch/v850/kernel/memcons.c
index 491614c435cd..92f514fdcc79 100644
--- a/arch/v850/kernel/memcons.c
+++ b/arch/v850/kernel/memcons.c
@@ -30,7 +30,7 @@ static DEFINE_SPINLOCK(memcons_lock);
static size_t write (const char *buf, size_t len)
{
- int flags;
+ unsigned long flags;
char *point;
spin_lock_irqsave (memcons_lock, flags);
@@ -104,7 +104,7 @@ int memcons_tty_chars_in_buffer (struct tty_struct *tty)
return 0;
}
-static struct tty_operations ops = {
+static const struct tty_operations ops = {
.open = memcons_tty_open,
.write = memcons_tty_write,
.write_room = memcons_tty_write_room,
diff --git a/arch/v850/kernel/rte_cb_leds.c b/arch/v850/kernel/rte_cb_leds.c
index f654088b2760..996bd4f33ecb 100644
--- a/arch/v850/kernel/rte_cb_leds.c
+++ b/arch/v850/kernel/rte_cb_leds.c
@@ -42,7 +42,7 @@ do { \
len = LED_NUM_DIGITS - pos; \
\
if (len > 0) { \
- int _flags; \
+ unsigned long _flags; \
const char *_end = buf + len; \
img_decl = &leds_image[pos]; \
\
diff --git a/arch/v850/kernel/rte_mb_a_pci.c b/arch/v850/kernel/rte_mb_a_pci.c
index f36b778f1432..35213fa9f7d8 100644
--- a/arch/v850/kernel/rte_mb_a_pci.c
+++ b/arch/v850/kernel/rte_mb_a_pci.c
@@ -365,7 +365,7 @@ static DEFINE_SPINLOCK(mb_sram_lock);
static void *alloc_mb_sram (size_t size)
{
struct mb_sram_free_area *prev, *fa;
- int flags;
+ unsigned long flags;
void *mem = 0;
spin_lock_irqsave (mb_sram_lock, flags);
@@ -406,7 +406,7 @@ static void *alloc_mb_sram (size_t size)
static void free_mb_sram (void *mem, size_t size)
{
struct mb_sram_free_area *prev, *fa, *new_fa;
- int flags;
+ unsigned long flags;
void *end = mem + size;
spin_lock_irqsave (mb_sram_lock, flags);
@@ -517,7 +517,7 @@ static DEFINE_SPINLOCK(dma_mappings_lock);
static struct dma_mapping *new_dma_mapping (size_t size)
{
- int flags;
+ unsigned long flags;
struct dma_mapping *mapping;
void *mb_sram_block = alloc_mb_sram (size);
@@ -575,7 +575,7 @@ static struct dma_mapping *new_dma_mapping (size_t size)
static struct dma_mapping *find_dma_mapping (void *mb_sram_addr)
{
- int flags;
+ unsigned long flags;
struct dma_mapping *mapping;
spin_lock_irqsave (dma_mappings_lock, flags);
@@ -592,7 +592,7 @@ static struct dma_mapping *find_dma_mapping (void *mb_sram_addr)
static struct dma_mapping *deactivate_dma_mapping (void *mb_sram_addr)
{
- int flags;
+ unsigned long flags;
struct dma_mapping *mapping, *prev;
spin_lock_irqsave (dma_mappings_lock, flags);
@@ -622,7 +622,7 @@ static struct dma_mapping *deactivate_dma_mapping (void *mb_sram_addr)
static inline void
free_dma_mapping (struct dma_mapping *mapping)
{
- int flags;
+ unsigned long flags;
free_mb_sram (mapping->mb_sram_addr, mapping->size);
diff --git a/arch/v850/kernel/simcons.c b/arch/v850/kernel/simcons.c
index 3975aa02cef8..9973596ae304 100644
--- a/arch/v850/kernel/simcons.c
+++ b/arch/v850/kernel/simcons.c
@@ -77,7 +77,7 @@ int simcons_tty_chars_in_buffer (struct tty_struct *tty)
return 0;
}
-static struct tty_operations ops = {
+static const struct tty_operations ops = {
.open = simcons_tty_open,
.write = simcons_tty_write,
.write_room = simcons_tty_write_room,
diff --git a/arch/v850/kernel/syscalls.c b/arch/v850/kernel/syscalls.c
index 2ec0700fc46b..d2b1fb19d243 100644
--- a/arch/v850/kernel/syscalls.c
+++ b/arch/v850/kernel/syscalls.c
@@ -33,6 +33,7 @@
#include <asm/uaccess.h>
#include <asm/ipc.h>
#include <asm/semaphore.h>
+#include <asm/unistd.h>
/*
* sys_ipc() is the de-multiplexer for the SysV IPC calls..
@@ -194,3 +195,22 @@ unsigned long sys_mmap (unsigned long addr, size_t len,
out:
return err;
}
+
+/*
+ * Do a system call from kernel instead of calling sys_execve so we
+ * end up with proper pt_regs.
+ */
+int kernel_execve(const char *filename, char *const argv[], char *const envp[])
+{
+ register char *__a __asm__ ("r6") = filename;
+ register void *__b __asm__ ("r7") = argv;
+ register void *__c __asm__ ("r8") = envp;
+ register unsigned long __syscall __asm__ ("r12") = __NR_execve;
+ register unsigned long __ret __asm__ ("r10");
+ __asm__ __volatile__ ("trap 0"
+ : "=r" (__ret), "=r" (__syscall)
+ : "1" (__syscall), "r" (__a), "r" (__b), "r" (__c)
+ : "r1", "r5", "r11", "r13", "r14",
+ "r15", "r16", "r17", "r18", "r19");
+ return __ret;
+}
diff --git a/arch/v850/kernel/time.c b/arch/v850/kernel/time.c
index a0b46695f186..f4d1a4d3cdc2 100644
--- a/arch/v850/kernel/time.c
+++ b/arch/v850/kernel/time.c
@@ -51,7 +51,7 @@ static irqreturn_t timer_interrupt (int irq, void *dummy, struct pt_regs *regs)
if (mach_tick)
mach_tick ();
- do_timer (regs);
+ do_timer (1);
#ifndef CONFIG_SMP
update_process_times(user_mode(regs));
#endif
diff --git a/arch/x86_64/Kconfig b/arch/x86_64/Kconfig
index 32ae1378f35c..0a5d8e659aa4 100644
--- a/arch/x86_64/Kconfig
+++ b/arch/x86_64/Kconfig
@@ -367,6 +367,10 @@ config ARCH_FLATMEM_ENABLE
source "mm/Kconfig"
+config MEMORY_HOTPLUG_RESERVE
+ def_bool y
+ depends on (MEMORY_HOTPLUG && DISCONTIGMEM)
+
config HAVE_ARCH_EARLY_PFN_TO_NID
def_bool y
depends on NUMA
@@ -686,7 +690,7 @@ source "arch/x86_64/oprofile/Kconfig"
config KPROBES
bool "Kprobes (EXPERIMENTAL)"
- depends on EXPERIMENTAL && MODULES
+ depends on KALLSYMS && EXPERIMENTAL && MODULES
help
Kprobes allows you to trap at almost any kernel address and
execute a callback function. register_kprobe() establishes
diff --git a/arch/x86_64/defconfig b/arch/x86_64/defconfig
index 647610ecb580..4844b543bed0 100644
--- a/arch/x86_64/defconfig
+++ b/arch/x86_64/defconfig
@@ -1,11 +1,12 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.18-git5
-# Tue Sep 26 09:30:47 2006
+# Linux kernel version: 2.6.18-git7
+# Wed Sep 27 21:53:10 2006
#
CONFIG_X86_64=y
CONFIG_64BIT=y
CONFIG_X86=y
+CONFIG_ZONE_DMA32=y
CONFIG_LOCKDEP_SUPPORT=y
CONFIG_STACKTRACE_SUPPORT=y
CONFIG_SEMAPHORE_SLEEPERS=y
@@ -179,6 +180,7 @@ CONFIG_GENERIC_PENDING_IRQ=y
CONFIG_PM=y
# CONFIG_PM_LEGACY is not set
# CONFIG_PM_DEBUG is not set
+# CONFIG_PM_SYSFS_DEPRECATED is not set
CONFIG_SOFTWARE_SUSPEND=y
CONFIG_PM_STD_PARTITION=""
CONFIG_SUSPEND_SMP=y
@@ -251,6 +253,7 @@ CONFIG_PCI_DIRECT=y
CONFIG_PCI_MMCONFIG=y
CONFIG_PCIEPORTBUS=y
CONFIG_PCI_MSI=y
+# CONFIG_PCI_MULTITHREAD_PROBE is not set
# CONFIG_PCI_DEBUG is not set
#
@@ -1458,6 +1461,7 @@ CONFIG_KPROBES=y
#
CONFIG_TRACE_IRQFLAGS_SUPPORT=y
# CONFIG_PRINTK_TIME is not set
+# CONFIG_ENABLE_MUST_CHECK is not set
CONFIG_MAGIC_SYSRQ=y
CONFIG_UNUSED_SYMBOLS=y
CONFIG_DEBUG_KERNEL=y
diff --git a/arch/x86_64/ia32/sys_ia32.c b/arch/x86_64/ia32/sys_ia32.c
index f280d3665f4b..c9bac3af29d6 100644
--- a/arch/x86_64/ia32/sys_ia32.c
+++ b/arch/x86_64/ia32/sys_ia32.c
@@ -76,6 +76,8 @@
int cp_compat_stat(struct kstat *kbuf, struct compat_stat __user *ubuf)
{
+ compat_ino_t ino;
+
typeof(ubuf->st_uid) uid = 0;
typeof(ubuf->st_gid) gid = 0;
SET_UID(uid, kbuf->uid);
@@ -84,9 +86,12 @@ int cp_compat_stat(struct kstat *kbuf, struct compat_stat __user *ubuf)
return -EOVERFLOW;
if (kbuf->size >= 0x7fffffff)
return -EOVERFLOW;
+ ino = kbuf->ino;
+ if (sizeof(ino) < sizeof(kbuf->ino) && ino != kbuf->ino)
+ return -EOVERFLOW;
if (!access_ok(VERIFY_WRITE, ubuf, sizeof(struct compat_stat)) ||
__put_user (old_encode_dev(kbuf->dev), &ubuf->st_dev) ||
- __put_user (kbuf->ino, &ubuf->st_ino) ||
+ __put_user (ino, &ubuf->st_ino) ||
__put_user (kbuf->mode, &ubuf->st_mode) ||
__put_user (kbuf->nlink, &ubuf->st_nlink) ||
__put_user (uid, &ubuf->st_uid) ||
@@ -784,36 +789,36 @@ asmlinkage long sys32_olduname(struct oldold_utsname __user * name)
if (!name)
return -EFAULT;
- if (!access_ok(VERIFY_WRITE,name,sizeof(struct oldold_utsname)))
+ if (!access_ok(VERIFY_WRITE, name, sizeof(struct oldold_utsname)))
return -EFAULT;
down_read(&uts_sem);
-
- err = __copy_to_user(&name->sysname,&system_utsname.sysname,
+
+ err = __copy_to_user(&name->sysname,&utsname()->sysname,
__OLD_UTS_LEN);
err |= __put_user(0,name->sysname+__OLD_UTS_LEN);
- err |= __copy_to_user(&name->nodename,&system_utsname.nodename,
+ err |= __copy_to_user(&name->nodename,&utsname()->nodename,
__OLD_UTS_LEN);
err |= __put_user(0,name->nodename+__OLD_UTS_LEN);
- err |= __copy_to_user(&name->release,&system_utsname.release,
+ err |= __copy_to_user(&name->release,&utsname()->release,
__OLD_UTS_LEN);
err |= __put_user(0,name->release+__OLD_UTS_LEN);
- err |= __copy_to_user(&name->version,&system_utsname.version,
+ err |= __copy_to_user(&name->version,&utsname()->version,
__OLD_UTS_LEN);
err |= __put_user(0,name->version+__OLD_UTS_LEN);
- {
- char *arch = "x86_64";
- if (personality(current->personality) == PER_LINUX32)
- arch = "i686";
+ {
+ char *arch = "x86_64";
+ if (personality(current->personality) == PER_LINUX32)
+ arch = "i686";
- err |= __copy_to_user(&name->machine,arch,strlen(arch)+1);
- }
-
- up_read(&uts_sem);
-
- err = err ? -EFAULT : 0;
-
- return err;
+ err |= __copy_to_user(&name->machine, arch, strlen(arch)+1);
+ }
+
+ up_read(&uts_sem);
+
+ err = err ? -EFAULT : 0;
+
+ return err;
}
long sys32_uname(struct old_utsname __user * name)
@@ -822,7 +827,7 @@ long sys32_uname(struct old_utsname __user * name)
if (!name)
return -EFAULT;
down_read(&uts_sem);
- err=copy_to_user(name, &system_utsname, sizeof (*name));
+ err = copy_to_user(name, utsname(), sizeof (*name));
up_read(&uts_sem);
if (personality(current->personality) == PER_LINUX32)
err |= copy_to_user(&name->machine, "i686", 5);
diff --git a/arch/x86_64/kernel/apic.c b/arch/x86_64/kernel/apic.c
index 135ff25e6b44..6472e321cad7 100644
--- a/arch/x86_64/kernel/apic.c
+++ b/arch/x86_64/kernel/apic.c
@@ -25,7 +25,6 @@
#include <linux/kernel_stat.h>
#include <linux/sysdev.h>
#include <linux/module.h>
-#include <linux/ioport.h>
#include <asm/atomic.h>
#include <asm/smp.h>
@@ -46,11 +45,6 @@ int apic_calibrate_pmtmr __initdata;
int disable_apic_timer __initdata;
-static struct resource lapic_resource = {
- .name = "Local APIC",
- .flags = IORESOURCE_MEM | IORESOURCE_BUSY,
-};
-
/*
* cpu_mask that denotes the CPUs that needs timer interrupt coming in as
* IPIs in place of local APIC timers
@@ -591,40 +585,6 @@ static int __init detect_init_APIC (void)
return 0;
}
-#ifdef CONFIG_X86_IO_APIC
-static struct resource * __init ioapic_setup_resources(void)
-{
-#define IOAPIC_RESOURCE_NAME_SIZE 11
- unsigned long n;
- struct resource *res;
- char *mem;
- int i;
-
- if (nr_ioapics <= 0)
- return NULL;
-
- n = IOAPIC_RESOURCE_NAME_SIZE + sizeof(struct resource);
- n *= nr_ioapics;
-
- res = alloc_bootmem(n);
-
- if (!res)
- return NULL;
-
- memset(res, 0, n);
- mem = (void *)&res[nr_ioapics];
-
- for (i = 0; i < nr_ioapics; i++) {
- res[i].name = mem;
- res[i].flags = IORESOURCE_MEM | IORESOURCE_BUSY;
- snprintf(mem, IOAPIC_RESOURCE_NAME_SIZE, "IOAPIC %u", i);
- mem += IOAPIC_RESOURCE_NAME_SIZE;
- }
-
- return res;
-}
-#endif
-
void __init init_apic_mappings(void)
{
unsigned long apic_phys;
@@ -644,11 +604,6 @@ void __init init_apic_mappings(void)
apic_mapped = 1;
apic_printk(APIC_VERBOSE,"mapped APIC to %16lx (%16lx)\n", APIC_BASE, apic_phys);
- /* Put local APIC into the resource map. */
- lapic_resource.start = apic_phys;
- lapic_resource.end = lapic_resource.start + PAGE_SIZE - 1;
- insert_resource(&iomem_resource, &lapic_resource);
-
/*
* Fetch the APIC ID of the BSP in case we have a
* default configuration (or the MP table is broken).
@@ -658,9 +613,7 @@ void __init init_apic_mappings(void)
{
unsigned long ioapic_phys, idx = FIX_IO_APIC_BASE_0;
int i;
- struct resource *ioapic_res;
- ioapic_res = ioapic_setup_resources();
for (i = 0; i < nr_ioapics; i++) {
if (smp_found_config) {
ioapic_phys = mp_ioapics[i].mpc_apicaddr;
@@ -672,13 +625,6 @@ void __init init_apic_mappings(void)
apic_printk(APIC_VERBOSE,"mapped IOAPIC to %016lx (%016lx)\n",
__fix_to_virt(idx), ioapic_phys);
idx++;
-
- if (ioapic_res) {
- ioapic_res->start = ioapic_phys;
- ioapic_res->end = ioapic_phys + (4 * 1024) - 1;
- insert_resource(&iomem_resource, ioapic_res);
- ioapic_res++;
- }
}
}
}
diff --git a/arch/x86_64/kernel/entry.S b/arch/x86_64/kernel/entry.S
index 2802524104f3..b8285cf1a9c3 100644
--- a/arch/x86_64/kernel/entry.S
+++ b/arch/x86_64/kernel/entry.S
@@ -1023,7 +1023,7 @@ ENDPROC(child_rip)
* do_sys_execve asm fallback arguments:
* rdi: name, rsi: argv, rdx: envp, fake frame on the stack
*/
-ENTRY(execve)
+ENTRY(kernel_execve)
CFI_STARTPROC
FAKE_STACK_FRAME $0
SAVE_ALL
@@ -1036,7 +1036,7 @@ ENTRY(execve)
UNFAKE_STACK_FRAME
ret
CFI_ENDPROC
-ENDPROC(execve)
+ENDPROC(kernel_execve)
KPROBE_ENTRY(page_fault)
errorentry do_page_fault
diff --git a/arch/x86_64/kernel/kprobes.c b/arch/x86_64/kernel/kprobes.c
index ffc73ac72485..ac241567e682 100644
--- a/arch/x86_64/kernel/kprobes.c
+++ b/arch/x86_64/kernel/kprobes.c
@@ -270,20 +270,19 @@ void __kprobes arch_prepare_kretprobe(struct kretprobe *rp,
struct pt_regs *regs)
{
unsigned long *sara = (unsigned long *)regs->rsp;
- struct kretprobe_instance *ri;
+ struct kretprobe_instance *ri;
- if ((ri = get_free_rp_inst(rp)) != NULL) {
- ri->rp = rp;
- ri->task = current;
+ if ((ri = get_free_rp_inst(rp)) != NULL) {
+ ri->rp = rp;
+ ri->task = current;
ri->ret_addr = (kprobe_opcode_t *) *sara;
/* Replace the return addr with trampoline addr */
*sara = (unsigned long) &kretprobe_trampoline;
-
- add_rp_inst(ri);
- } else {
- rp->nmissed++;
- }
+ add_rp_inst(ri);
+ } else {
+ rp->nmissed++;
+ }
}
int __kprobes kprobe_handler(struct pt_regs *regs)
@@ -405,14 +404,15 @@ no_kprobe:
*/
int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs)
{
- struct kretprobe_instance *ri = NULL;
- struct hlist_head *head;
- struct hlist_node *node, *tmp;
+ struct kretprobe_instance *ri = NULL;
+ struct hlist_head *head, empty_rp;
+ struct hlist_node *node, *tmp;
unsigned long flags, orig_ret_address = 0;
unsigned long trampoline_address =(unsigned long)&kretprobe_trampoline;
+ INIT_HLIST_HEAD(&empty_rp);
spin_lock_irqsave(&kretprobe_lock, flags);
- head = kretprobe_inst_table_head(current);
+ head = kretprobe_inst_table_head(current);
/*
* It is possible to have multiple instances associated with a given
@@ -423,20 +423,20 @@ int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs)
* We can handle this because:
* - instances are always inserted at the head of the list
* - when multiple return probes are registered for the same
- * function, the first instance's ret_addr will point to the
+ * function, the first instance's ret_addr will point to the
* real return address, and all the rest will point to
* kretprobe_trampoline
*/
hlist_for_each_entry_safe(ri, node, tmp, head, hlist) {
- if (ri->task != current)
+ if (ri->task != current)
/* another task is sharing our hash bucket */
- continue;
+ continue;
if (ri->rp && ri->rp->handler)
ri->rp->handler(ri, regs);
orig_ret_address = (unsigned long)ri->ret_addr;
- recycle_rp_inst(ri);
+ recycle_rp_inst(ri, &empty_rp);
if (orig_ret_address != trampoline_address)
/*
@@ -454,12 +454,16 @@ int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs)
spin_unlock_irqrestore(&kretprobe_lock, flags);
preempt_enable_no_resched();
- /*
- * By returning a non-zero value, we are telling
- * kprobe_handler() that we don't want the post_handler
+ hlist_for_each_entry_safe(ri, node, tmp, &empty_rp, hlist) {
+ hlist_del(&ri->hlist);
+ kfree(ri);
+ }
+ /*
+ * By returning a non-zero value, we are telling
+ * kprobe_handler() that we don't want the post_handler
* to run (and have re-enabled preemption)
- */
- return 1;
+ */
+ return 1;
}
/*
diff --git a/arch/x86_64/kernel/mpparse.c b/arch/x86_64/kernel/mpparse.c
index 20e88f4b564b..b8d53dfa9931 100644
--- a/arch/x86_64/kernel/mpparse.c
+++ b/arch/x86_64/kernel/mpparse.c
@@ -152,6 +152,21 @@ static void __init MP_bus_info (struct mpc_config_bus *m)
}
}
+static int bad_ioapic(unsigned long address)
+{
+ if (nr_ioapics >= MAX_IO_APICS) {
+ printk(KERN_ERR "ERROR: Max # of I/O APICs (%d) exceeded "
+ "(found %d)\n", MAX_IO_APICS, nr_ioapics);
+ panic("Recompile kernel with bigger MAX_IO_APICS!\n");
+ }
+ if (!address) {
+ printk(KERN_ERR "WARNING: Bogus (zero) I/O APIC address"
+ " found in table, skipping!\n");
+ return 1;
+ }
+ return 0;
+}
+
static void __init MP_ioapic_info (struct mpc_config_ioapic *m)
{
if (!(m->mpc_flags & MPC_APIC_USABLE))
@@ -159,16 +174,10 @@ static void __init MP_ioapic_info (struct mpc_config_ioapic *m)
printk("I/O APIC #%d at 0x%X.\n",
m->mpc_apicid, m->mpc_apicaddr);
- if (nr_ioapics >= MAX_IO_APICS) {
- printk(KERN_ERR "Max # of I/O APICs (%d) exceeded (found %d).\n",
- MAX_IO_APICS, nr_ioapics);
- panic("Recompile kernel with bigger MAX_IO_APICS!.\n");
- }
- if (!m->mpc_apicaddr) {
- printk(KERN_ERR "WARNING: bogus zero I/O APIC address"
- " found in MP table, skipping!\n");
+
+ if (bad_ioapic(m->mpc_apicaddr))
return;
- }
+
mp_ioapics[nr_ioapics] = *m;
nr_ioapics++;
}
@@ -647,16 +656,8 @@ void __init mp_register_ioapic(u8 id, u32 address, u32 gsi_base)
{
int idx = 0;
- if (nr_ioapics >= MAX_IO_APICS) {
- printk(KERN_ERR "ERROR: Max # of I/O APICs (%d) exceeded "
- "(found %d)\n", MAX_IO_APICS, nr_ioapics);
- panic("Recompile kernel with bigger MAX_IO_APICS!\n");
- }
- if (!address) {
- printk(KERN_ERR "WARNING: Bogus (zero) I/O APIC address"
- " found in MADT table, skipping!\n");
+ if (bad_ioapic(address))
return;
- }
idx = nr_ioapics++;
diff --git a/arch/x86_64/kernel/nmi.c b/arch/x86_64/kernel/nmi.c
index 4d6fb047952e..7af9cb3e2d99 100644
--- a/arch/x86_64/kernel/nmi.c
+++ b/arch/x86_64/kernel/nmi.c
@@ -28,6 +28,10 @@
#include <asm/mce.h>
#include <asm/intel_arch_perfmon.h>
+int unknown_nmi_panic;
+int nmi_watchdog_enabled;
+int panic_on_unrecovered_nmi;
+
/* perfctr_nmi_owner tracks the ownership of the perfctr registers:
* evtsel_nmi_owner tracks the ownership of the event selection
* - different performance counters/ event selection may be reserved for
diff --git a/arch/x86_64/kernel/pci-dma.c b/arch/x86_64/kernel/pci-dma.c
index 4dcb671bd19f..f8d857453f8a 100644
--- a/arch/x86_64/kernel/pci-dma.c
+++ b/arch/x86_64/kernel/pci-dma.c
@@ -170,8 +170,20 @@ void dma_free_coherent(struct device *dev, size_t size,
}
EXPORT_SYMBOL(dma_free_coherent);
+static int forbid_dac __read_mostly;
+
int dma_supported(struct device *dev, u64 mask)
{
+#ifdef CONFIG_PCI
+ if (mask > 0xffffffff && forbid_dac > 0) {
+
+
+
+ printk(KERN_INFO "PCI: Disallowing DAC for device %s\n", dev->bus_id);
+ return 0;
+ }
+#endif
+
if (dma_ops->dma_supported)
return dma_ops->dma_supported(dev, mask);
@@ -231,57 +243,64 @@ EXPORT_SYMBOL(dma_set_mask);
allowed overwrite iommu off workarounds for specific chipsets.
soft Use software bounce buffering (default for Intel machines)
noaperture Don't touch the aperture for AGP.
+ allowdac Allow DMA >4GB
+ nodac Forbid DMA >4GB
+ panic Force panic when IOMMU overflows
*/
__init int iommu_setup(char *p)
{
- iommu_merge = 1;
+ iommu_merge = 1;
if (!p)
return -EINVAL;
- while (*p) {
- if (!strncmp(p,"off",3))
- no_iommu = 1;
- /* gart_parse_options has more force support */
- if (!strncmp(p,"force",5))
- force_iommu = 1;
- if (!strncmp(p,"noforce",7)) {
- iommu_merge = 0;
- force_iommu = 0;
- }
-
- if (!strncmp(p, "biomerge",8)) {
- iommu_bio_merge = 4096;
- iommu_merge = 1;
- force_iommu = 1;
- }
- if (!strncmp(p, "panic",5))
- panic_on_overflow = 1;
- if (!strncmp(p, "nopanic",7))
- panic_on_overflow = 0;
- if (!strncmp(p, "merge",5)) {
- iommu_merge = 1;
- force_iommu = 1;
- }
- if (!strncmp(p, "nomerge",7))
- iommu_merge = 0;
- if (!strncmp(p, "forcesac",8))
- iommu_sac_force = 1;
+ while (*p) {
+ if (!strncmp(p,"off",3))
+ no_iommu = 1;
+ /* gart_parse_options has more force support */
+ if (!strncmp(p,"force",5))
+ force_iommu = 1;
+ if (!strncmp(p,"noforce",7)) {
+ iommu_merge = 0;
+ force_iommu = 0;
+ }
+
+ if (!strncmp(p, "biomerge",8)) {
+ iommu_bio_merge = 4096;
+ iommu_merge = 1;
+ force_iommu = 1;
+ }
+ if (!strncmp(p, "panic",5))
+ panic_on_overflow = 1;
+ if (!strncmp(p, "nopanic",7))
+ panic_on_overflow = 0;
+ if (!strncmp(p, "merge",5)) {
+ iommu_merge = 1;
+ force_iommu = 1;
+ }
+ if (!strncmp(p, "nomerge",7))
+ iommu_merge = 0;
+ if (!strncmp(p, "forcesac",8))
+ iommu_sac_force = 1;
+ if (!strncmp(p, "allowdac", 8))
+ forbid_dac = 0;
+ if (!strncmp(p, "nodac", 5))
+ forbid_dac = -1;
#ifdef CONFIG_SWIOTLB
- if (!strncmp(p, "soft",4))
- swiotlb = 1;
+ if (!strncmp(p, "soft",4))
+ swiotlb = 1;
#endif
#ifdef CONFIG_IOMMU
- gart_parse_options(p);
+ gart_parse_options(p);
#endif
- p += strcspn(p, ",");
- if (*p == ',')
- ++p;
- }
- return 0;
+ p += strcspn(p, ",");
+ if (*p == ',')
+ ++p;
+ }
+ return 0;
}
early_param("iommu", iommu_setup);
diff --git a/arch/x86_64/kernel/pci-swiotlb.c b/arch/x86_64/kernel/pci-swiotlb.c
index 6a55f87ba97f..697f0aa794b9 100644
--- a/arch/x86_64/kernel/pci-swiotlb.c
+++ b/arch/x86_64/kernel/pci-swiotlb.c
@@ -3,7 +3,8 @@
#include <linux/pci.h>
#include <linux/cache.h>
#include <linux/module.h>
-#include <asm/dma-mapping.h>
+#include <linux/dma-mapping.h>
+
#include <asm/proto.h>
#include <asm/swiotlb.h>
#include <asm/dma.h>
diff --git a/arch/x86_64/kernel/process.c b/arch/x86_64/kernel/process.c
index 458006ae19f3..de10cb8a2c97 100644
--- a/arch/x86_64/kernel/process.c
+++ b/arch/x86_64/kernel/process.c
@@ -294,9 +294,9 @@ void __show_regs(struct pt_regs * regs)
print_modules();
printk("Pid: %d, comm: %.20s %s %s %.*s\n",
current->pid, current->comm, print_tainted(),
- system_utsname.release,
- (int)strcspn(system_utsname.version, " "),
- system_utsname.version);
+ init_utsname()->release,
+ (int)strcspn(init_utsname()->version, " "),
+ init_utsname()->version);
printk("RIP: %04lx:[<%016lx>] ", regs->cs & 0xffff, regs->rip);
printk_address(regs->rip);
printk("RSP: %04lx:%016lx EFLAGS: %08lx\n", regs->ss, regs->rsp,
diff --git a/arch/x86_64/kernel/setup.c b/arch/x86_64/kernel/setup.c
index 0b00bb2ea576..fc944b5e8f4a 100644
--- a/arch/x86_64/kernel/setup.c
+++ b/arch/x86_64/kernel/setup.c
@@ -123,9 +123,6 @@ struct resource standard_io_resources[] = {
.flags = IORESOURCE_BUSY | IORESOURCE_IO }
};
-#define STANDARD_IO_RESOURCES \
- (sizeof standard_io_resources / sizeof standard_io_resources[0])
-
#define IORESOURCE_RAM (IORESOURCE_BUSY | IORESOURCE_MEM)
struct resource data_resource = {
@@ -172,9 +169,6 @@ static struct resource adapter_rom_resources[] = {
.flags = IORESOURCE_ROM }
};
-#define ADAPTER_ROM_RESOURCES \
- (sizeof adapter_rom_resources / sizeof adapter_rom_resources[0])
-
static struct resource video_rom_resource = {
.name = "Video ROM",
.start = 0xc0000,
@@ -245,7 +239,8 @@ static void __init probe_roms(void)
}
/* check for adapter roms on 2k boundaries */
- for (i = 0; i < ADAPTER_ROM_RESOURCES && start < upper; start += 2048) {
+ for (i = 0; i < ARRAY_SIZE(adapter_rom_resources) && start < upper;
+ start += 2048) {
rom = isa_bus_to_virt(start);
if (!romsignature(rom))
continue;
@@ -537,7 +532,7 @@ void __init setup_arch(char **cmdline_p)
{
unsigned i;
/* request I/O space for devices used on all i[345]86 PCs */
- for (i = 0; i < STANDARD_IO_RESOURCES; i++)
+ for (i = 0; i < ARRAY_SIZE(standard_io_resources); i++)
request_resource(&ioport_resource, &standard_io_resources[i]);
}
diff --git a/arch/x86_64/kernel/sys_x86_64.c b/arch/x86_64/kernel/sys_x86_64.c
index 6449ea8fe756..76bf7c241fe4 100644
--- a/arch/x86_64/kernel/sys_x86_64.c
+++ b/arch/x86_64/kernel/sys_x86_64.c
@@ -148,7 +148,7 @@ asmlinkage long sys_uname(struct new_utsname __user * name)
{
int err;
down_read(&uts_sem);
- err = copy_to_user(name, &system_utsname, sizeof (*name));
+ err = copy_to_user(name, utsname(), sizeof (*name));
up_read(&uts_sem);
if (personality(current->personality) == PER_LINUX32)
err |= copy_to_user(&name->machine, "i686", 5);
diff --git a/arch/x86_64/kernel/time.c b/arch/x86_64/kernel/time.c
index 1c255ee76e7c..557e92af7bea 100644
--- a/arch/x86_64/kernel/time.c
+++ b/arch/x86_64/kernel/time.c
@@ -77,7 +77,6 @@ unsigned long long monotonic_base;
struct vxtime_data __vxtime __section_vxtime; /* for vsyscalls */
volatile unsigned long __jiffies __section_jiffies = INITIAL_JIFFIES;
-unsigned long __wall_jiffies __section_wall_jiffies = INITIAL_JIFFIES;
struct timespec __xtime __section_xtime;
struct timezone __sys_tz __section_sys_tz;
@@ -119,7 +118,7 @@ unsigned int (*do_gettimeoffset)(void) = do_gettimeoffset_tsc;
void do_gettimeofday(struct timeval *tv)
{
- unsigned long seq, t;
+ unsigned long seq;
unsigned int sec, usec;
do {
@@ -136,10 +135,7 @@ void do_gettimeofday(struct timeval *tv)
be found. Note when you fix it here you need to do the same
in arch/x86_64/kernel/vsyscall.c and export all needed
variables in vmlinux.lds. -AK */
-
- t = (jiffies - wall_jiffies) * USEC_PER_TICK +
- do_gettimeoffset();
- usec += t;
+ usec += do_gettimeoffset();
} while (read_seqretry(&xtime_lock, seq));
@@ -165,8 +161,7 @@ int do_settimeofday(struct timespec *tv)
write_seqlock_irq(&xtime_lock);
- nsec -= do_gettimeoffset() * NSEC_PER_USEC +
- (jiffies - wall_jiffies) * NSEC_PER_TICK;
+ nsec -= do_gettimeoffset() * NSEC_PER_USEC;
wtm_sec = wall_to_monotonic.tv_sec + (xtime.tv_sec - sec);
wtm_nsec = wall_to_monotonic.tv_nsec + (xtime.tv_nsec - nsec);
@@ -415,16 +410,16 @@ void main_timer_handler(struct pt_regs *regs)
(((long) offset << US_SCALE) / vxtime.tsc_quot) - 1;
}
- if (lost > 0) {
+ if (lost > 0)
handle_lost_ticks(lost, regs);
- jiffies += lost;
- }
+ else
+ lost = 0;
/*
* Do the timer stuff.
*/
- do_timer(regs);
+ do_timer(lost + 1);
#ifndef CONFIG_SMP
update_process_times(user_mode(regs));
#endif
@@ -1071,7 +1066,6 @@ static int timer_resume(struct sys_device *dev)
vxtime.last_tsc = get_cycles_sync();
write_sequnlock_irqrestore(&xtime_lock,flags);
jiffies += sleep_length;
- wall_jiffies += sleep_length;
monotonic_base += sleep_length * (NSEC_PER_SEC/HZ);
touch_softlockup_watchdog();
return 0;
diff --git a/arch/x86_64/kernel/vmlinux.lds.S b/arch/x86_64/kernel/vmlinux.lds.S
index d0564f1bcb0b..b9df2ab6529f 100644
--- a/arch/x86_64/kernel/vmlinux.lds.S
+++ b/arch/x86_64/kernel/vmlinux.lds.S
@@ -67,13 +67,6 @@ SECTIONS
_edata = .; /* End of data section */
- __bss_start = .; /* BSS */
- .bss : AT(ADDR(.bss) - LOAD_OFFSET) {
- *(.bss.page_aligned)
- *(.bss)
- }
- __bss_stop = .;
-
. = ALIGN(PAGE_SIZE);
. = ALIGN(CONFIG_X86_L1_CACHE_BYTES);
.data.cacheline_aligned : AT(ADDR(.data.cacheline_aligned) - LOAD_OFFSET) {
@@ -108,9 +101,6 @@ SECTIONS
.vgetcpu_mode : AT(VLOAD(.vgetcpu_mode)) { *(.vgetcpu_mode) }
vgetcpu_mode = VVIRT(.vgetcpu_mode);
- .wall_jiffies : AT(VLOAD(.wall_jiffies)) { *(.wall_jiffies) }
- wall_jiffies = VVIRT(.wall_jiffies);
-
.sys_tz : AT(VLOAD(.sys_tz)) { *(.sys_tz) }
sys_tz = VVIRT(.sys_tz);
@@ -229,6 +219,13 @@ SECTIONS
. = ALIGN(4096);
__nosave_end = .;
+ __bss_start = .; /* BSS */
+ .bss : AT(ADDR(.bss) - LOAD_OFFSET) {
+ *(.bss.page_aligned)
+ *(.bss)
+ }
+ __bss_stop = .;
+
_end = . ;
/* Sections to be discarded */
diff --git a/arch/x86_64/kernel/vsyscall.c b/arch/x86_64/kernel/vsyscall.c
index ac48c3857ddb..a98b460af6a1 100644
--- a/arch/x86_64/kernel/vsyscall.c
+++ b/arch/x86_64/kernel/vsyscall.c
@@ -66,8 +66,7 @@ static __always_inline void do_vgettimeofday(struct timeval * tv)
sequence = read_seqbegin(&__xtime_lock);
sec = __xtime.tv_sec;
- usec = (__xtime.tv_nsec / 1000) +
- (__jiffies - __wall_jiffies) * (1000000 / HZ);
+ usec = __xtime.tv_nsec / 1000;
if (__vxtime.mode != VXTIME_HPET) {
t = get_cycles_sync();
@@ -155,8 +154,8 @@ vgetcpu(unsigned *cpu, unsigned *node, struct getcpu_cache *tcache)
We do this here because otherwise user space would do it on
its own in a likely inferior way (no access to jiffies).
If you don't like it pass NULL. */
- if (tcache && tcache->t0 == (j = __jiffies)) {
- p = tcache->t1;
+ if (tcache && tcache->blob[0] == (j = __jiffies)) {
+ p = tcache->blob[1];
} else if (__vgetcpu_mode == VGETCPU_RDTSCP) {
/* Load per CPU data from RDTSCP */
rdtscp(dummy, dummy, p);
@@ -165,8 +164,8 @@ vgetcpu(unsigned *cpu, unsigned *node, struct getcpu_cache *tcache)
asm("lsl %1,%0" : "=r" (p) : "r" (__PER_CPU_SEG));
}
if (tcache) {
- tcache->t0 = j;
- tcache->t1 = p;
+ tcache->blob[0] = j;
+ tcache->blob[1] = p;
}
if (cpu)
*cpu = p & 0xfff;
diff --git a/arch/x86_64/mm/fault.c b/arch/x86_64/mm/fault.c
index 1a17b0733ab5..3751b4788e28 100644
--- a/arch/x86_64/mm/fault.c
+++ b/arch/x86_64/mm/fault.c
@@ -244,7 +244,7 @@ static int is_errata93(struct pt_regs *regs, unsigned long address)
int unhandled_signal(struct task_struct *tsk, int sig)
{
- if (tsk->pid == 1)
+ if (is_init(tsk))
return 1;
if (tsk->ptrace & PT_PTRACED)
return 0;
@@ -464,7 +464,7 @@ good_area:
case PF_PROT: /* read, present */
goto bad_area;
case 0: /* read, not present */
- if (!(vma->vm_flags & (VM_READ | VM_EXEC)))
+ if (!(vma->vm_flags & (VM_READ | VM_EXEC | VM_WRITE)))
goto bad_area;
}
@@ -580,7 +580,7 @@ no_context:
*/
out_of_memory:
up_read(&mm->mmap_sem);
- if (current->pid == 1) {
+ if (is_init(current)) {
yield();
goto again;
}
diff --git a/arch/x86_64/mm/init.c b/arch/x86_64/mm/init.c
index 3e16fe08150e..19c72520a868 100644
--- a/arch/x86_64/mm/init.c
+++ b/arch/x86_64/mm/init.c
@@ -463,19 +463,6 @@ void online_page(struct page *page)
#ifdef CONFIG_MEMORY_HOTPLUG
/*
- * XXX: memory_add_physaddr_to_nid() is to find node id from physical address
- * via probe interface of sysfs. If acpi notifies hot-add event, then it
- * can tell node id by searching dsdt. But, probe interface doesn't have
- * node id. So, return 0 as node id at this time.
- */
-#ifdef CONFIG_NUMA
-int memory_add_physaddr_to_nid(u64 start)
-{
- return 0;
-}
-#endif
-
-/*
* Memory is added always to NORMAL zone. This means you will never get
* additional DMA/DMA32 memory.
*/
@@ -487,12 +474,12 @@ int arch_add_memory(int nid, u64 start, u64 size)
unsigned long nr_pages = size >> PAGE_SHIFT;
int ret;
+ init_memory_mapping(start, (start + size -1));
+
ret = __add_pages(zone, start_pfn, nr_pages);
if (ret)
goto error;
- init_memory_mapping(start, (start + size -1));
-
return ret;
error:
printk("%s: Problem encountered in __add_pages!\n", __func__);
@@ -506,7 +493,24 @@ int remove_memory(u64 start, u64 size)
}
EXPORT_SYMBOL_GPL(remove_memory);
-#else /* CONFIG_MEMORY_HOTPLUG */
+#ifndef CONFIG_ACPI_NUMA
+int memory_add_physaddr_to_nid(u64 start)
+{
+ return 0;
+}
+EXPORT_SYMBOL_GPL(memory_add_physaddr_to_nid);
+#endif
+
+#ifndef CONFIG_ACPI_NUMA
+int memory_add_physaddr_to_nid(u64 start)
+{
+ return 0;
+}
+#endif
+
+#endif /* CONFIG_MEMORY_HOTPLUG */
+
+#ifdef CONFIG_MEMORY_HOTPLUG_RESERVE
/*
* Memory Hotadd without sparsemem. The mem_maps have been allocated in advance,
* just online the pages.
@@ -532,7 +536,7 @@ int __add_pages(struct zone *z, unsigned long start_pfn, unsigned long nr_pages)
}
return err;
}
-#endif /* CONFIG_MEMORY_HOTPLUG */
+#endif
static struct kcore_list kcore_mem, kcore_vmalloc, kcore_kernel, kcore_modules,
kcore_vsyscall;
diff --git a/arch/x86_64/mm/ioremap.c b/arch/x86_64/mm/ioremap.c
index 45d7d823c3b8..c6e5e8d401a4 100644
--- a/arch/x86_64/mm/ioremap.c
+++ b/arch/x86_64/mm/ioremap.c
@@ -12,117 +12,16 @@
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/module.h>
-#include <asm/io.h>
+#include <linux/io.h>
#include <asm/pgalloc.h>
#include <asm/fixmap.h>
-#include <asm/cacheflush.h>
#include <asm/tlbflush.h>
+#include <asm/cacheflush.h>
#include <asm/proto.h>
#define ISA_START_ADDRESS 0xa0000
#define ISA_END_ADDRESS 0x100000
-static inline void remap_area_pte(pte_t * pte, unsigned long address, unsigned long size,
- unsigned long phys_addr, unsigned long flags)
-{
- unsigned long end;
- unsigned long pfn;
-
- address &= ~PMD_MASK;
- end = address + size;
- if (end > PMD_SIZE)
- end = PMD_SIZE;
- if (address >= end)
- BUG();
- pfn = phys_addr >> PAGE_SHIFT;
- do {
- if (!pte_none(*pte)) {
- printk("remap_area_pte: page already exists\n");
- BUG();
- }
- set_pte(pte, pfn_pte(pfn, __pgprot(_PAGE_PRESENT | _PAGE_RW |
- _PAGE_GLOBAL | _PAGE_DIRTY | _PAGE_ACCESSED | flags)));
- address += PAGE_SIZE;
- pfn++;
- pte++;
- } while (address && (address < end));
-}
-
-static inline int remap_area_pmd(pmd_t * pmd, unsigned long address, unsigned long size,
- unsigned long phys_addr, unsigned long flags)
-{
- unsigned long end;
-
- address &= ~PUD_MASK;
- end = address + size;
- if (end > PUD_SIZE)
- end = PUD_SIZE;
- phys_addr -= address;
- if (address >= end)
- BUG();
- do {
- pte_t * pte = pte_alloc_kernel(pmd, address);
- if (!pte)
- return -ENOMEM;
- remap_area_pte(pte, address, end - address, address + phys_addr, flags);
- address = (address + PMD_SIZE) & PMD_MASK;
- pmd++;
- } while (address && (address < end));
- return 0;
-}
-
-static inline int remap_area_pud(pud_t * pud, unsigned long address, unsigned long size,
- unsigned long phys_addr, unsigned long flags)
-{
- unsigned long end;
-
- address &= ~PGDIR_MASK;
- end = address + size;
- if (end > PGDIR_SIZE)
- end = PGDIR_SIZE;
- phys_addr -= address;
- if (address >= end)
- BUG();
- do {
- pmd_t * pmd = pmd_alloc(&init_mm, pud, address);
- if (!pmd)
- return -ENOMEM;
- remap_area_pmd(pmd, address, end - address, address + phys_addr, flags);
- address = (address + PUD_SIZE) & PUD_MASK;
- pud++;
- } while (address && (address < end));
- return 0;
-}
-
-static int remap_area_pages(unsigned long address, unsigned long phys_addr,
- unsigned long size, unsigned long flags)
-{
- int error;
- pgd_t *pgd;
- unsigned long end = address + size;
-
- phys_addr -= address;
- pgd = pgd_offset_k(address);
- flush_cache_all();
- if (address >= end)
- BUG();
- do {
- pud_t *pud;
- pud = pud_alloc(&init_mm, pgd, address);
- error = -ENOMEM;
- if (!pud)
- break;
- if (remap_area_pud(pud, address, end - address,
- phys_addr + address, flags))
- break;
- error = 0;
- address = (address + PGDIR_SIZE) & PGDIR_MASK;
- pgd++;
- } while (address && (address < end));
- flush_tlb_all();
- return error;
-}
-
/*
* Fix up the linear direct mapping of the kernel to avoid cache attribute
* conflicts.
@@ -165,6 +64,7 @@ void __iomem * __ioremap(unsigned long phys_addr, unsigned long size, unsigned l
void * addr;
struct vm_struct * area;
unsigned long offset, last_addr;
+ pgprot_t pgprot;
/* Don't allow wraparound or zero size */
last_addr = phys_addr + size - 1;
@@ -194,6 +94,8 @@ void __iomem * __ioremap(unsigned long phys_addr, unsigned long size, unsigned l
}
#endif
+ pgprot = __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_GLOBAL
+ | _PAGE_DIRTY | _PAGE_ACCESSED | flags);
/*
* Mappings have to be page-aligned
*/
@@ -209,7 +111,8 @@ void __iomem * __ioremap(unsigned long phys_addr, unsigned long size, unsigned l
return NULL;
area->phys_addr = phys_addr;
addr = area->addr;
- if (remap_area_pages((unsigned long) addr, phys_addr, size, flags)) {
+ if (ioremap_page_range((unsigned long)addr, (unsigned long)addr + size,
+ phys_addr, pgprot)) {
remove_vm_area((void *)(PAGE_MASK & (unsigned long) addr));
return NULL;
}
diff --git a/arch/x86_64/mm/srat.c b/arch/x86_64/mm/srat.c
index f8c04d6935c9..3cc0544e25f5 100644
--- a/arch/x86_64/mm/srat.c
+++ b/arch/x86_64/mm/srat.c
@@ -23,22 +23,13 @@
int acpi_numa __initdata;
-#if (defined(CONFIG_ACPI_HOTPLUG_MEMORY) || \
- defined(CONFIG_ACPI_HOTPLUG_MEMORY_MODULE)) \
- && !defined(CONFIG_MEMORY_HOTPLUG)
-#define RESERVE_HOTADD 1
-#endif
-
static struct acpi_table_slit *acpi_slit;
static nodemask_t nodes_parsed __initdata;
static struct bootnode nodes[MAX_NUMNODES] __initdata;
-static struct bootnode nodes_add[MAX_NUMNODES] __initdata;
+static struct bootnode nodes_add[MAX_NUMNODES];
static int found_add_area __initdata;
int hotadd_percent __initdata = 0;
-#ifndef RESERVE_HOTADD
-#define hotadd_percent 0 /* Ignore all settings */
-#endif
/* Too small nodes confuse the VM badly. Usually they result
from BIOS bugs. */
@@ -160,7 +151,7 @@ acpi_numa_processor_affinity_init(struct acpi_table_processor_affinity *pa)
pxm, pa->apic_id, node);
}
-#ifdef RESERVE_HOTADD
+#ifdef CONFIG_MEMORY_HOTPLUG_RESERVE
/*
* Protect against too large hotadd areas that would fill up memory.
*/
@@ -203,15 +194,37 @@ static int hotadd_enough_memory(struct bootnode *nd)
return 1;
}
+static int update_end_of_memory(unsigned long end)
+{
+ found_add_area = 1;
+ if ((end >> PAGE_SHIFT) > end_pfn)
+ end_pfn = end >> PAGE_SHIFT;
+ return 1;
+}
+
+static inline int save_add_info(void)
+{
+ return hotadd_percent > 0;
+}
+#else
+int update_end_of_memory(unsigned long end) {return 0;}
+static int hotadd_enough_memory(struct bootnode *nd) {return 1;}
+#ifdef CONFIG_MEMORY_HOTPLUG_SPARSE
+static inline int save_add_info(void) {return 1;}
+#else
+static inline int save_add_info(void) {return 0;}
+#endif
+#endif
/*
- * It is fine to add this area to the nodes data it will be used later
+ * Update nodes_add and decide if to include add are in the zone.
+ * Both SPARSE and RESERVE need nodes_add infomation.
* This code supports one contigious hot add area per node.
*/
static int reserve_hotadd(int node, unsigned long start, unsigned long end)
{
unsigned long s_pfn = start >> PAGE_SHIFT;
unsigned long e_pfn = end >> PAGE_SHIFT;
- int changed = 0;
+ int ret = 0, changed = 0;
struct bootnode *nd = &nodes_add[node];
/* I had some trouble with strange memory hotadd regions breaking
@@ -240,7 +253,6 @@ static int reserve_hotadd(int node, unsigned long start, unsigned long end)
/* Looks good */
- found_add_area = 1;
if (nd->start == nd->end) {
nd->start = start;
nd->end = end;
@@ -258,14 +270,12 @@ static int reserve_hotadd(int node, unsigned long start, unsigned long end)
printk(KERN_ERR "SRAT: Hotplug zone not continuous. Partly ignored\n");
}
- if ((nd->end >> PAGE_SHIFT) > end_pfn)
- end_pfn = nd->end >> PAGE_SHIFT;
+ ret = update_end_of_memory(nd->end);
if (changed)
printk(KERN_INFO "SRAT: hot plug zone found %Lx - %Lx\n", nd->start, nd->end);
- return 0;
+ return ret;
}
-#endif
/* Callback for parsing of the Proximity Domain <-> Memory Area mappings */
void __init
@@ -284,7 +294,7 @@ acpi_numa_memory_affinity_init(struct acpi_table_memory_affinity *ma)
}
if (ma->flags.enabled == 0)
return;
- if (ma->flags.hot_pluggable && hotadd_percent == 0)
+ if (ma->flags.hot_pluggable && !save_add_info())
return;
start = ma->base_addr_lo | ((u64)ma->base_addr_hi << 32);
end = start + (ma->length_lo | ((u64)ma->length_hi << 32));
@@ -327,15 +337,13 @@ acpi_numa_memory_affinity_init(struct acpi_table_memory_affinity *ma)
push_node_boundaries(node, nd->start >> PAGE_SHIFT,
nd->end >> PAGE_SHIFT);
-#ifdef RESERVE_HOTADD
- if (ma->flags.hot_pluggable && reserve_hotadd(node, start, end) < 0) {
+ if (ma->flags.hot_pluggable && !reserve_hotadd(node, start, end) < 0) {
/* Ignore hotadd region. Undo damage */
printk(KERN_NOTICE "SRAT: Hotplug region ignored\n");
*nd = oldnode;
if ((nd->start | nd->end) == 0)
node_clear(node, nodes_parsed);
}
-#endif
}
/* Sanity check to catch more bad SRATs (they are amazingly common).
@@ -351,7 +359,6 @@ static int nodes_cover_memory(void)
unsigned long e = nodes[i].end >> PAGE_SHIFT;
pxmram += e - s;
pxmram -= absent_pages_in_range(s, e);
- pxmram -= nodes_add[i].end - nodes_add[i].start;
if ((long)pxmram < 0)
pxmram = 0;
}
@@ -459,3 +466,16 @@ int __node_distance(int a, int b)
}
EXPORT_SYMBOL(__node_distance);
+
+int memory_add_physaddr_to_nid(u64 start)
+{
+ int i, ret = 0;
+
+ for_each_node(i)
+ if (nodes_add[i].start <= start && nodes_add[i].end > start)
+ ret = i;
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(memory_add_physaddr_to_nid);
+
diff --git a/arch/xtensa/kernel/syscalls.c b/arch/xtensa/kernel/syscalls.c
index 4688ba2db84d..d9285d4d5565 100644
--- a/arch/xtensa/kernel/syscalls.c
+++ b/arch/xtensa/kernel/syscalls.c
@@ -128,7 +128,7 @@ out:
int sys_uname(struct old_utsname * name)
{
- if (name && !copy_to_user(name, &system_utsname, sizeof (*name)))
+ if (name && !copy_to_user(name, utsname(), sizeof (*name)))
return 0;
return -EFAULT;
}
@@ -266,3 +266,23 @@ void system_call (struct pt_regs *regs)
regs->areg[2] = res;
do_syscall_trace();
}
+
+/*
+ * Do a system call from kernel instead of calling sys_execve so we
+ * end up with proper pt_regs.
+ */
+int kernel_execve(const char *filename, char *const argv[], char *const envp[])
+{
+ long __res;
+ asm volatile (
+ " mov a5, %2 \n"
+ " mov a4, %4 \n"
+ " mov a3, %3 \n"
+ " movi a2, %1 \n"
+ " syscall \n"
+ " mov %0, a2 \n"
+ : "=a" (__res)
+ : "i" (__NR_execve), "a" (filename), "a" (argv), "a" (envp)
+ : "a2", "a3", "a4", "a5");
+ return __res;
+}
diff --git a/arch/xtensa/kernel/time.c b/arch/xtensa/kernel/time.c
index 412ab32de391..37347e369987 100644
--- a/arch/xtensa/kernel/time.c
+++ b/arch/xtensa/kernel/time.c
@@ -26,8 +26,6 @@
#include <asm/platform.h>
-extern volatile unsigned long wall_jiffies;
-
DEFINE_SPINLOCK(rtc_lock);
EXPORT_SYMBOL(rtc_lock);
@@ -110,7 +108,6 @@ int do_settimeofday(struct timespec *tv)
*/
ccount = get_ccount();
nsec -= (ccount - last_ccount_stamp) * CCOUNT_NSEC;
- nsec -= (jiffies - wall_jiffies) * CCOUNT_PER_JIFFY * CCOUNT_NSEC;
wtm_sec = wall_to_monotonic.tv_sec + (xtime.tv_sec - sec);
wtm_nsec = wall_to_monotonic.tv_nsec + (xtime.tv_nsec - nsec);
@@ -129,7 +126,7 @@ EXPORT_SYMBOL(do_settimeofday);
void do_gettimeofday(struct timeval *tv)
{
unsigned long flags;
- unsigned long sec, usec, delta, lost, seq;
+ unsigned long sec, usec, delta, seq;
do {
seq = read_seqbegin_irqsave(&xtime_lock, flags);
@@ -137,12 +134,9 @@ void do_gettimeofday(struct timeval *tv)
delta = get_ccount() - last_ccount_stamp;
sec = xtime.tv_sec;
usec = (xtime.tv_nsec / NSEC_PER_USEC);
-
- lost = jiffies - wall_jiffies;
-
} while (read_seqretry_irqrestore(&xtime_lock, seq, flags));
- usec += lost * (1000000UL/HZ) + (delta * CCOUNT_NSEC) / NSEC_PER_USEC;
+ usec += (delta * CCOUNT_NSEC) / NSEC_PER_USEC;
for (; usec >= 1000000; sec++, usec -= 1000000)
;
@@ -175,12 +169,11 @@ again:
last_ccount_stamp = next;
next += CCOUNT_PER_JIFFY;
- do_timer (regs); /* Linux handler in kernel/timer.c */
+ do_timer (1); /* Linux handler in kernel/timer.c */
if (ntp_synced() &&
xtime.tv_sec - last_rtc_update >= 659 &&
- abs((xtime.tv_nsec/1000)-(1000000-1000000/HZ))<5000000/HZ &&
- jiffies - wall_jiffies == 1) {
+ abs((xtime.tv_nsec/1000)-(1000000-1000000/HZ))<5000000/HZ) {
if (platform_set_rtc_time(xtime.tv_sec+1) == 0)
last_rtc_update = xtime.tv_sec+1;
diff --git a/arch/xtensa/mm/fault.c b/arch/xtensa/mm/fault.c
index a945a33e85a1..dd0dbec2e57e 100644
--- a/arch/xtensa/mm/fault.c
+++ b/arch/xtensa/mm/fault.c
@@ -144,7 +144,7 @@ bad_area:
*/
out_of_memory:
up_read(&mm->mmap_sem);
- if (current->pid == 1) {
+ if (is_init(current)) {
yield();
down_read(&mm->mmap_sem);
goto survive;
diff --git a/arch/xtensa/platform-iss/console.c b/arch/xtensa/platform-iss/console.c
index 22d3c571a7bc..5c947cae7520 100644
--- a/arch/xtensa/platform-iss/console.c
+++ b/arch/xtensa/platform-iss/console.c
@@ -191,7 +191,7 @@ static int rs_read_proc(char *page, char **start, off_t off, int count,
}
-static struct tty_operations serial_ops = {
+static const struct tty_operations serial_ops = {
.open = rs_open,
.close = rs_close,
.write = rs_write,
diff --git a/arch/xtensa/platform-iss/network.c b/arch/xtensa/platform-iss/network.c
index d96164e602fe..15d64414bd60 100644
--- a/arch/xtensa/platform-iss/network.c
+++ b/arch/xtensa/platform-iss/network.c
@@ -201,7 +201,7 @@ static void dev_ip_addr(void *d, char *buf, char *bin_buf)
struct net_device *dev = d;
struct in_device *ip = dev->ip_ptr;
struct in_ifaddr *in;
- u32 addr;
+ __be32 addr;
if ((ip == NULL) || ((in = ip->ifa_list) == NULL)) {
printk(KERN_WARNING "Device not assigned an IP address!\n");
diff --git a/block/Kconfig b/block/Kconfig
index b6f5f0a79655..83766a6bdee2 100644
--- a/block/Kconfig
+++ b/block/Kconfig
@@ -1,6 +1,24 @@
#
# Block layer core configuration
#
+config BLOCK
+ bool "Enable the block layer" if EMBEDDED
+ default y
+ help
+ This permits the block layer to be removed from the kernel if it's not
+ needed (on some embedded devices for example). If this option is
+ disabled, then blockdev files will become unusable and some
+ filesystems (such as ext3) will become unavailable.
+
+ This option will also disable SCSI character devices and USB storage
+ since they make use of various block layer definitions and
+ facilities.
+
+ Say Y here unless you know you really don't want to mount disks and
+ suchlike.
+
+if BLOCK
+
#XXX - it makes sense to enable this only for 32-bit subarch's, not for x86_64
#for instance.
config LBD
@@ -33,4 +51,6 @@ config LSF
If unsure, say Y.
+endif
+
source block/Kconfig.iosched
diff --git a/block/Kconfig.iosched b/block/Kconfig.iosched
index 48d090e266fc..903f0d3b6852 100644
--- a/block/Kconfig.iosched
+++ b/block/Kconfig.iosched
@@ -1,3 +1,4 @@
+if BLOCK
menu "IO Schedulers"
@@ -67,3 +68,5 @@ config DEFAULT_IOSCHED
default "noop" if DEFAULT_NOOP
endmenu
+
+endif
diff --git a/block/Makefile b/block/Makefile
index c05de0e0037f..4b84d0d5947b 100644
--- a/block/Makefile
+++ b/block/Makefile
@@ -2,7 +2,7 @@
# Makefile for the kernel block layer
#
-obj-y := elevator.o ll_rw_blk.o ioctl.o genhd.o scsi_ioctl.o
+obj-$(CONFIG_BLOCK) := elevator.o ll_rw_blk.o ioctl.o genhd.o scsi_ioctl.o
obj-$(CONFIG_IOSCHED_NOOP) += noop-iosched.o
obj-$(CONFIG_IOSCHED_AS) += as-iosched.o
diff --git a/block/as-iosched.c b/block/as-iosched.c
index 5da56d48fbd3..50b95e4c1425 100644
--- a/block/as-iosched.c
+++ b/block/as-iosched.c
@@ -1,7 +1,7 @@
/*
* Anticipatory & deadline i/o scheduler.
*
- * Copyright (C) 2002 Jens Axboe <axboe@suse.de>
+ * Copyright (C) 2002 Jens Axboe <axboe@kernel.dk>
* Nick Piggin <nickpiggin@yahoo.com.au>
*
*/
@@ -14,7 +14,6 @@
#include <linux/slab.h>
#include <linux/init.h>
#include <linux/compiler.h>
-#include <linux/hash.h>
#include <linux/rbtree.h>
#include <linux/interrupt.h>
@@ -93,9 +92,8 @@ struct as_data {
struct rb_root sort_list[2];
struct list_head fifo_list[2];
- struct as_rq *next_arq[2]; /* next in sort order */
+ struct request *next_rq[2]; /* next in sort order */
sector_t last_sector[2]; /* last REQ_SYNC & REQ_ASYNC sectors */
- struct hlist_head *hash; /* request hash */
unsigned long exit_prob; /* probability a task will exit while
being waited on */
@@ -115,7 +113,6 @@ struct as_data {
int write_batch_count; /* max # of reqs in a write batch */
int current_write_count; /* how many requests left this batch */
int write_batch_idled; /* has the write batch gone idle? */
- mempool_t *arq_pool;
enum anticipation_status antic_status;
unsigned long antic_start; /* jiffies: when it started */
@@ -133,8 +130,6 @@ struct as_data {
unsigned long antic_expire;
};
-#define list_entry_fifo(ptr) list_entry((ptr), struct as_rq, fifo)
-
/*
* per-request data.
*/
@@ -150,40 +145,14 @@ enum arq_state {
AS_RQ_POSTSCHED, /* when they shouldn't be */
};
-struct as_rq {
- /*
- * rbtree index, key is the starting offset
- */
- struct rb_node rb_node;
- sector_t rb_key;
-
- struct request *request;
-
- struct io_context *io_context; /* The submitting task */
-
- /*
- * request hash, key is the ending offset (for back merge lookup)
- */
- struct hlist_node hash;
-
- /*
- * expire fifo
- */
- struct list_head fifo;
- unsigned long expires;
+#define RQ_IOC(rq) ((struct io_context *) (rq)->elevator_private)
+#define RQ_STATE(rq) ((enum arq_state)(rq)->elevator_private2)
+#define RQ_SET_STATE(rq, state) ((rq)->elevator_private2 = (void *) state)
- unsigned int is_sync;
- enum arq_state state;
-};
-
-#define RQ_DATA(rq) ((struct as_rq *) (rq)->elevator_private)
-
-static kmem_cache_t *arq_pool;
-
-static atomic_t ioc_count = ATOMIC_INIT(0);
+static DEFINE_PER_CPU(unsigned long, ioc_count);
static struct completion *ioc_gone;
-static void as_move_to_dispatch(struct as_data *ad, struct as_rq *arq);
+static void as_move_to_dispatch(struct as_data *ad, struct request *rq);
static void as_antic_stop(struct as_data *ad);
/*
@@ -194,7 +163,8 @@ static void as_antic_stop(struct as_data *ad);
static void free_as_io_context(struct as_io_context *aic)
{
kfree(aic);
- if (atomic_dec_and_test(&ioc_count) && ioc_gone)
+ elv_ioc_count_dec(ioc_count);
+ if (ioc_gone && !elv_ioc_count_read(ioc_count))
complete(ioc_gone);
}
@@ -230,7 +200,7 @@ static struct as_io_context *alloc_as_io_context(void)
ret->seek_total = 0;
ret->seek_samples = 0;
ret->seek_mean = 0;
- atomic_inc(&ioc_count);
+ elv_ioc_count_inc(ioc_count);
}
return ret;
@@ -240,9 +210,9 @@ static struct as_io_context *alloc_as_io_context(void)
* If the current task has no AS IO context then create one and initialise it.
* Then take a ref on the task's io context and return it.
*/
-static struct io_context *as_get_io_context(void)
+static struct io_context *as_get_io_context(int node)
{
- struct io_context *ioc = get_io_context(GFP_ATOMIC);
+ struct io_context *ioc = get_io_context(GFP_ATOMIC, node);
if (ioc && !ioc->aic) {
ioc->aic = alloc_as_io_context();
if (!ioc->aic) {
@@ -253,194 +223,43 @@ static struct io_context *as_get_io_context(void)
return ioc;
}
-static void as_put_io_context(struct as_rq *arq)
+static void as_put_io_context(struct request *rq)
{
struct as_io_context *aic;
- if (unlikely(!arq->io_context))
+ if (unlikely(!RQ_IOC(rq)))
return;
- aic = arq->io_context->aic;
+ aic = RQ_IOC(rq)->aic;
- if (arq->is_sync == REQ_SYNC && aic) {
+ if (rq_is_sync(rq) && aic) {
spin_lock(&aic->lock);
set_bit(AS_TASK_IORUNNING, &aic->state);
aic->last_end_request = jiffies;
spin_unlock(&aic->lock);
}
- put_io_context(arq->io_context);
-}
-
-/*
- * the back merge hash support functions
- */
-static const int as_hash_shift = 6;
-#define AS_HASH_BLOCK(sec) ((sec) >> 3)
-#define AS_HASH_FN(sec) (hash_long(AS_HASH_BLOCK((sec)), as_hash_shift))
-#define AS_HASH_ENTRIES (1 << as_hash_shift)
-#define rq_hash_key(rq) ((rq)->sector + (rq)->nr_sectors)
-
-static inline void __as_del_arq_hash(struct as_rq *arq)
-{
- hlist_del_init(&arq->hash);
-}
-
-static inline void as_del_arq_hash(struct as_rq *arq)
-{
- if (!hlist_unhashed(&arq->hash))
- __as_del_arq_hash(arq);
-}
-
-static void as_add_arq_hash(struct as_data *ad, struct as_rq *arq)
-{
- struct request *rq = arq->request;
-
- BUG_ON(!hlist_unhashed(&arq->hash));
-
- hlist_add_head(&arq->hash, &ad->hash[AS_HASH_FN(rq_hash_key(rq))]);
-}
-
-/*
- * move hot entry to front of chain
- */
-static inline void as_hot_arq_hash(struct as_data *ad, struct as_rq *arq)
-{
- struct request *rq = arq->request;
- struct hlist_head *head = &ad->hash[AS_HASH_FN(rq_hash_key(rq))];
-
- if (hlist_unhashed(&arq->hash)) {
- WARN_ON(1);
- return;
- }
-
- if (&arq->hash != head->first) {
- hlist_del(&arq->hash);
- hlist_add_head(&arq->hash, head);
- }
-}
-
-static struct request *as_find_arq_hash(struct as_data *ad, sector_t offset)
-{
- struct hlist_head *hash_list = &ad->hash[AS_HASH_FN(offset)];
- struct hlist_node *entry, *next;
- struct as_rq *arq;
-
- hlist_for_each_entry_safe(arq, entry, next, hash_list, hash) {
- struct request *__rq = arq->request;
-
- BUG_ON(hlist_unhashed(&arq->hash));
-
- if (!rq_mergeable(__rq)) {
- as_del_arq_hash(arq);
- continue;
- }
-
- if (rq_hash_key(__rq) == offset)
- return __rq;
- }
-
- return NULL;
+ put_io_context(RQ_IOC(rq));
}
/*
* rb tree support functions
*/
-#define rb_entry_arq(node) rb_entry((node), struct as_rq, rb_node)
-#define ARQ_RB_ROOT(ad, arq) (&(ad)->sort_list[(arq)->is_sync])
-#define rq_rb_key(rq) (rq)->sector
-
-/*
- * as_find_first_arq finds the first (lowest sector numbered) request
- * for the specified data_dir. Used to sweep back to the start of the disk
- * (1-way elevator) after we process the last (highest sector) request.
- */
-static struct as_rq *as_find_first_arq(struct as_data *ad, int data_dir)
-{
- struct rb_node *n = ad->sort_list[data_dir].rb_node;
-
- if (n == NULL)
- return NULL;
-
- for (;;) {
- if (n->rb_left == NULL)
- return rb_entry_arq(n);
-
- n = n->rb_left;
- }
-}
-
-/*
- * Add the request to the rb tree if it is unique. If there is an alias (an
- * existing request against the same sector), which can happen when using
- * direct IO, then return the alias.
- */
-static struct as_rq *__as_add_arq_rb(struct as_data *ad, struct as_rq *arq)
-{
- struct rb_node **p = &ARQ_RB_ROOT(ad, arq)->rb_node;
- struct rb_node *parent = NULL;
- struct as_rq *__arq;
- struct request *rq = arq->request;
-
- arq->rb_key = rq_rb_key(rq);
-
- while (*p) {
- parent = *p;
- __arq = rb_entry_arq(parent);
-
- if (arq->rb_key < __arq->rb_key)
- p = &(*p)->rb_left;
- else if (arq->rb_key > __arq->rb_key)
- p = &(*p)->rb_right;
- else
- return __arq;
- }
-
- rb_link_node(&arq->rb_node, parent, p);
- rb_insert_color(&arq->rb_node, ARQ_RB_ROOT(ad, arq));
-
- return NULL;
-}
+#define RQ_RB_ROOT(ad, rq) (&(ad)->sort_list[rq_is_sync((rq))])
-static void as_add_arq_rb(struct as_data *ad, struct as_rq *arq)
+static void as_add_rq_rb(struct as_data *ad, struct request *rq)
{
- struct as_rq *alias;
+ struct request *alias;
- while ((unlikely(alias = __as_add_arq_rb(ad, arq)))) {
+ while ((unlikely(alias = elv_rb_add(RQ_RB_ROOT(ad, rq), rq)))) {
as_move_to_dispatch(ad, alias);
as_antic_stop(ad);
}
}
-static inline void as_del_arq_rb(struct as_data *ad, struct as_rq *arq)
-{
- if (!RB_EMPTY_NODE(&arq->rb_node)) {
- WARN_ON(1);
- return;
- }
-
- rb_erase(&arq->rb_node, ARQ_RB_ROOT(ad, arq));
- RB_CLEAR_NODE(&arq->rb_node);
-}
-
-static struct request *
-as_find_arq_rb(struct as_data *ad, sector_t sector, int data_dir)
+static inline void as_del_rq_rb(struct as_data *ad, struct request *rq)
{
- struct rb_node *n = ad->sort_list[data_dir].rb_node;
- struct as_rq *arq;
-
- while (n) {
- arq = rb_entry_arq(n);
-
- if (sector < arq->rb_key)
- n = n->rb_left;
- else if (sector > arq->rb_key)
- n = n->rb_right;
- else
- return arq->request;
- }
-
- return NULL;
+ elv_rb_del(RQ_RB_ROOT(ad, rq), rq);
}
/*
@@ -458,26 +277,26 @@ as_find_arq_rb(struct as_data *ad, sector_t sector, int data_dir)
* as_choose_req selects the preferred one of two requests of the same data_dir
* ignoring time - eg. timeouts, which is the job of as_dispatch_request
*/
-static struct as_rq *
-as_choose_req(struct as_data *ad, struct as_rq *arq1, struct as_rq *arq2)
+static struct request *
+as_choose_req(struct as_data *ad, struct request *rq1, struct request *rq2)
{
int data_dir;
sector_t last, s1, s2, d1, d2;
int r1_wrap=0, r2_wrap=0; /* requests are behind the disk head */
const sector_t maxback = MAXBACK;
- if (arq1 == NULL || arq1 == arq2)
- return arq2;
- if (arq2 == NULL)
- return arq1;
+ if (rq1 == NULL || rq1 == rq2)
+ return rq2;
+ if (rq2 == NULL)
+ return rq1;
- data_dir = arq1->is_sync;
+ data_dir = rq_is_sync(rq1);
last = ad->last_sector[data_dir];
- s1 = arq1->request->sector;
- s2 = arq2->request->sector;
+ s1 = rq1->sector;
+ s2 = rq2->sector;
- BUG_ON(data_dir != arq2->is_sync);
+ BUG_ON(data_dir != rq_is_sync(rq2));
/*
* Strict one way elevator _except_ in the case where we allow
@@ -504,61 +323,58 @@ as_choose_req(struct as_data *ad, struct as_rq *arq1, struct as_rq *arq2)
/* Found required data */
if (!r1_wrap && r2_wrap)
- return arq1;
+ return rq1;
else if (!r2_wrap && r1_wrap)
- return arq2;
+ return rq2;
else if (r1_wrap && r2_wrap) {
/* both behind the head */
if (s1 <= s2)
- return arq1;
+ return rq1;
else
- return arq2;
+ return rq2;
}
/* Both requests in front of the head */
if (d1 < d2)
- return arq1;
+ return rq1;
else if (d2 < d1)
- return arq2;
+ return rq2;
else {
if (s1 >= s2)
- return arq1;
+ return rq1;
else
- return arq2;
+ return rq2;
}
}
/*
- * as_find_next_arq finds the next request after @prev in elevator order.
+ * as_find_next_rq finds the next request after @prev in elevator order.
* this with as_choose_req form the basis for how the scheduler chooses
* what request to process next. Anticipation works on top of this.
*/
-static struct as_rq *as_find_next_arq(struct as_data *ad, struct as_rq *last)
+static struct request *
+as_find_next_rq(struct as_data *ad, struct request *last)
{
- const int data_dir = last->is_sync;
- struct as_rq *ret;
struct rb_node *rbnext = rb_next(&last->rb_node);
struct rb_node *rbprev = rb_prev(&last->rb_node);
- struct as_rq *arq_next, *arq_prev;
+ struct request *next = NULL, *prev = NULL;
- BUG_ON(!RB_EMPTY_NODE(&last->rb_node));
+ BUG_ON(RB_EMPTY_NODE(&last->rb_node));
if (rbprev)
- arq_prev = rb_entry_arq(rbprev);
- else
- arq_prev = NULL;
+ prev = rb_entry_rq(rbprev);
if (rbnext)
- arq_next = rb_entry_arq(rbnext);
+ next = rb_entry_rq(rbnext);
else {
- arq_next = as_find_first_arq(ad, data_dir);
- if (arq_next == last)
- arq_next = NULL;
- }
+ const int data_dir = rq_is_sync(last);
- ret = as_choose_req(ad, arq_next, arq_prev);
+ rbnext = rb_first(&ad->sort_list[data_dir]);
+ if (rbnext && rbnext != &last->rb_node)
+ next = rb_entry_rq(rbnext);
+ }
- return ret;
+ return as_choose_req(ad, next, prev);
}
/*
@@ -712,8 +528,7 @@ static void as_update_seekdist(struct as_data *ad, struct as_io_context *aic,
static void as_update_iohist(struct as_data *ad, struct as_io_context *aic,
struct request *rq)
{
- struct as_rq *arq = RQ_DATA(rq);
- int data_dir = arq->is_sync;
+ int data_dir = rq_is_sync(rq);
unsigned long thinktime = 0;
sector_t seek_dist;
@@ -752,11 +567,11 @@ static void as_update_iohist(struct as_data *ad, struct as_io_context *aic,
* previous one issued.
*/
static int as_close_req(struct as_data *ad, struct as_io_context *aic,
- struct as_rq *arq)
+ struct request *rq)
{
unsigned long delay; /* milliseconds */
sector_t last = ad->last_sector[ad->batch_data_dir];
- sector_t next = arq->request->sector;
+ sector_t next = rq->sector;
sector_t delta; /* acceptable close offset (in sectors) */
sector_t s;
@@ -813,7 +628,7 @@ static int as_close_req(struct as_data *ad, struct as_io_context *aic,
*
* If this task has queued some other IO, do not enter enticipation.
*/
-static int as_can_break_anticipation(struct as_data *ad, struct as_rq *arq)
+static int as_can_break_anticipation(struct as_data *ad, struct request *rq)
{
struct io_context *ioc;
struct as_io_context *aic;
@@ -821,7 +636,7 @@ static int as_can_break_anticipation(struct as_data *ad, struct as_rq *arq)
ioc = ad->io_context;
BUG_ON(!ioc);
- if (arq && ioc == arq->io_context) {
+ if (rq && ioc == RQ_IOC(rq)) {
/* request from same process */
return 1;
}
@@ -848,7 +663,7 @@ static int as_can_break_anticipation(struct as_data *ad, struct as_rq *arq)
return 1;
}
- if (arq && arq->is_sync == REQ_SYNC && as_close_req(ad, aic, arq)) {
+ if (rq && rq_is_sync(rq) && as_close_req(ad, aic, rq)) {
/*
* Found a close request that is not one of ours.
*
@@ -864,7 +679,7 @@ static int as_can_break_anticipation(struct as_data *ad, struct as_rq *arq)
ad->exit_no_coop = (7*ad->exit_no_coop)/8;
}
- as_update_iohist(ad, aic, arq->request);
+ as_update_iohist(ad, aic, rq);
return 1;
}
@@ -891,10 +706,10 @@ static int as_can_break_anticipation(struct as_data *ad, struct as_rq *arq)
}
/*
- * as_can_anticipate indicates whether we should either run arq
+ * as_can_anticipate indicates whether we should either run rq
* or keep anticipating a better request.
*/
-static int as_can_anticipate(struct as_data *ad, struct as_rq *arq)
+static int as_can_anticipate(struct as_data *ad, struct request *rq)
{
if (!ad->io_context)
/*
@@ -908,7 +723,7 @@ static int as_can_anticipate(struct as_data *ad, struct as_rq *arq)
*/
return 0;
- if (as_can_break_anticipation(ad, arq))
+ if (as_can_break_anticipation(ad, rq))
/*
* This request is a good candidate. Don't keep anticipating,
* run it.
@@ -926,16 +741,16 @@ static int as_can_anticipate(struct as_data *ad, struct as_rq *arq)
}
/*
- * as_update_arq must be called whenever a request (arq) is added to
+ * as_update_rq must be called whenever a request (rq) is added to
* the sort_list. This function keeps caches up to date, and checks if the
* request might be one we are "anticipating"
*/
-static void as_update_arq(struct as_data *ad, struct as_rq *arq)
+static void as_update_rq(struct as_data *ad, struct request *rq)
{
- const int data_dir = arq->is_sync;
+ const int data_dir = rq_is_sync(rq);
- /* keep the next_arq cache up to date */
- ad->next_arq[data_dir] = as_choose_req(ad, arq, ad->next_arq[data_dir]);
+ /* keep the next_rq cache up to date */
+ ad->next_rq[data_dir] = as_choose_req(ad, rq, ad->next_rq[data_dir]);
/*
* have we been anticipating this request?
@@ -944,7 +759,7 @@ static void as_update_arq(struct as_data *ad, struct as_rq *arq)
*/
if (ad->antic_status == ANTIC_WAIT_REQ
|| ad->antic_status == ANTIC_WAIT_NEXT) {
- if (as_can_break_anticipation(ad, arq))
+ if (as_can_break_anticipation(ad, rq))
as_antic_stop(ad);
}
}
@@ -984,12 +799,11 @@ static void update_write_batch(struct as_data *ad)
static void as_completed_request(request_queue_t *q, struct request *rq)
{
struct as_data *ad = q->elevator->elevator_data;
- struct as_rq *arq = RQ_DATA(rq);
WARN_ON(!list_empty(&rq->queuelist));
- if (arq->state != AS_RQ_REMOVED) {
- printk("arq->state %d\n", arq->state);
+ if (RQ_STATE(rq) != AS_RQ_REMOVED) {
+ printk("rq->state %d\n", RQ_STATE(rq));
WARN_ON(1);
goto out;
}
@@ -1009,14 +823,14 @@ static void as_completed_request(request_queue_t *q, struct request *rq)
* actually serviced. This should help devices with big TCQ windows
* and writeback caches
*/
- if (ad->new_batch && ad->batch_data_dir == arq->is_sync) {
+ if (ad->new_batch && ad->batch_data_dir == rq_is_sync(rq)) {
update_write_batch(ad);
ad->current_batch_expires = jiffies +
ad->batch_expire[REQ_SYNC];
ad->new_batch = 0;
}
- if (ad->io_context == arq->io_context && ad->io_context) {
+ if (ad->io_context == RQ_IOC(rq) && ad->io_context) {
ad->antic_start = jiffies;
ad->ioc_finished = 1;
if (ad->antic_status == ANTIC_WAIT_REQ) {
@@ -1028,9 +842,9 @@ static void as_completed_request(request_queue_t *q, struct request *rq)
}
}
- as_put_io_context(arq);
+ as_put_io_context(rq);
out:
- arq->state = AS_RQ_POSTSCHED;
+ RQ_SET_STATE(rq, AS_RQ_POSTSCHED);
}
/*
@@ -1041,27 +855,27 @@ out:
*/
static void as_remove_queued_request(request_queue_t *q, struct request *rq)
{
- struct as_rq *arq = RQ_DATA(rq);
- const int data_dir = arq->is_sync;
+ const int data_dir = rq_is_sync(rq);
struct as_data *ad = q->elevator->elevator_data;
+ struct io_context *ioc;
- WARN_ON(arq->state != AS_RQ_QUEUED);
+ WARN_ON(RQ_STATE(rq) != AS_RQ_QUEUED);
- if (arq->io_context && arq->io_context->aic) {
- BUG_ON(!atomic_read(&arq->io_context->aic->nr_queued));
- atomic_dec(&arq->io_context->aic->nr_queued);
+ ioc = RQ_IOC(rq);
+ if (ioc && ioc->aic) {
+ BUG_ON(!atomic_read(&ioc->aic->nr_queued));
+ atomic_dec(&ioc->aic->nr_queued);
}
/*
- * Update the "next_arq" cache if we are about to remove its
+ * Update the "next_rq" cache if we are about to remove its
* entry
*/
- if (ad->next_arq[data_dir] == arq)
- ad->next_arq[data_dir] = as_find_next_arq(ad, arq);
+ if (ad->next_rq[data_dir] == rq)
+ ad->next_rq[data_dir] = as_find_next_rq(ad, rq);
- list_del_init(&arq->fifo);
- as_del_arq_hash(arq);
- as_del_arq_rb(ad, arq);
+ rq_fifo_clear(rq);
+ as_del_rq_rb(ad, rq);
}
/*
@@ -1074,7 +888,7 @@ static void as_remove_queued_request(request_queue_t *q, struct request *rq)
*/
static int as_fifo_expired(struct as_data *ad, int adir)
{
- struct as_rq *arq;
+ struct request *rq;
long delta_jif;
delta_jif = jiffies - ad->last_check_fifo[adir];
@@ -1088,9 +902,9 @@ static int as_fifo_expired(struct as_data *ad, int adir)
if (list_empty(&ad->fifo_list[adir]))
return 0;
- arq = list_entry_fifo(ad->fifo_list[adir].next);
+ rq = rq_entry_fifo(ad->fifo_list[adir].next);
- return time_after(jiffies, arq->expires);
+ return time_after(jiffies, rq_fifo_time(rq));
}
/*
@@ -1113,25 +927,25 @@ static inline int as_batch_expired(struct as_data *ad)
/*
* move an entry to dispatch queue
*/
-static void as_move_to_dispatch(struct as_data *ad, struct as_rq *arq)
+static void as_move_to_dispatch(struct as_data *ad, struct request *rq)
{
- struct request *rq = arq->request;
- const int data_dir = arq->is_sync;
+ const int data_dir = rq_is_sync(rq);
- BUG_ON(!RB_EMPTY_NODE(&arq->rb_node));
+ BUG_ON(RB_EMPTY_NODE(&rq->rb_node));
as_antic_stop(ad);
ad->antic_status = ANTIC_OFF;
/*
* This has to be set in order to be correctly updated by
- * as_find_next_arq
+ * as_find_next_rq
*/
ad->last_sector[data_dir] = rq->sector + rq->nr_sectors;
if (data_dir == REQ_SYNC) {
+ struct io_context *ioc = RQ_IOC(rq);
/* In case we have to anticipate after this */
- copy_io_context(&ad->io_context, &arq->io_context);
+ copy_io_context(&ad->io_context, &ioc);
} else {
if (ad->io_context) {
put_io_context(ad->io_context);
@@ -1143,19 +957,19 @@ static void as_move_to_dispatch(struct as_data *ad, struct as_rq *arq)
}
ad->ioc_finished = 0;
- ad->next_arq[data_dir] = as_find_next_arq(ad, arq);
+ ad->next_rq[data_dir] = as_find_next_rq(ad, rq);
/*
* take it off the sort and fifo list, add to dispatch queue
*/
as_remove_queued_request(ad->q, rq);
- WARN_ON(arq->state != AS_RQ_QUEUED);
+ WARN_ON(RQ_STATE(rq) != AS_RQ_QUEUED);
elv_dispatch_sort(ad->q, rq);
- arq->state = AS_RQ_DISPATCHED;
- if (arq->io_context && arq->io_context->aic)
- atomic_inc(&arq->io_context->aic->nr_dispatched);
+ RQ_SET_STATE(rq, AS_RQ_DISPATCHED);
+ if (RQ_IOC(rq) && RQ_IOC(rq)->aic)
+ atomic_inc(&RQ_IOC(rq)->aic->nr_dispatched);
ad->nr_dispatched++;
}
@@ -1167,9 +981,9 @@ static void as_move_to_dispatch(struct as_data *ad, struct as_rq *arq)
static int as_dispatch_request(request_queue_t *q, int force)
{
struct as_data *ad = q->elevator->elevator_data;
- struct as_rq *arq;
const int reads = !list_empty(&ad->fifo_list[REQ_SYNC]);
const int writes = !list_empty(&ad->fifo_list[REQ_ASYNC]);
+ struct request *rq;
if (unlikely(force)) {
/*
@@ -1185,14 +999,14 @@ static int as_dispatch_request(request_queue_t *q, int force)
ad->changed_batch = 0;
ad->new_batch = 0;
- while (ad->next_arq[REQ_SYNC]) {
- as_move_to_dispatch(ad, ad->next_arq[REQ_SYNC]);
+ while (ad->next_rq[REQ_SYNC]) {
+ as_move_to_dispatch(ad, ad->next_rq[REQ_SYNC]);
dispatched++;
}
ad->last_check_fifo[REQ_SYNC] = jiffies;
- while (ad->next_arq[REQ_ASYNC]) {
- as_move_to_dispatch(ad, ad->next_arq[REQ_ASYNC]);
+ while (ad->next_rq[REQ_ASYNC]) {
+ as_move_to_dispatch(ad, ad->next_rq[REQ_ASYNC]);
dispatched++;
}
ad->last_check_fifo[REQ_ASYNC] = jiffies;
@@ -1216,19 +1030,19 @@ static int as_dispatch_request(request_queue_t *q, int force)
/*
* batch is still running or no reads or no writes
*/
- arq = ad->next_arq[ad->batch_data_dir];
+ rq = ad->next_rq[ad->batch_data_dir];
if (ad->batch_data_dir == REQ_SYNC && ad->antic_expire) {
if (as_fifo_expired(ad, REQ_SYNC))
goto fifo_expired;
- if (as_can_anticipate(ad, arq)) {
+ if (as_can_anticipate(ad, rq)) {
as_antic_waitreq(ad);
return 0;
}
}
- if (arq) {
+ if (rq) {
/* we have a "next request" */
if (reads && !writes)
ad->current_batch_expires =
@@ -1256,7 +1070,7 @@ static int as_dispatch_request(request_queue_t *q, int force)
ad->changed_batch = 1;
}
ad->batch_data_dir = REQ_SYNC;
- arq = list_entry_fifo(ad->fifo_list[ad->batch_data_dir].next);
+ rq = rq_entry_fifo(ad->fifo_list[REQ_SYNC].next);
ad->last_check_fifo[ad->batch_data_dir] = jiffies;
goto dispatch_request;
}
@@ -1282,7 +1096,7 @@ dispatch_writes:
ad->batch_data_dir = REQ_ASYNC;
ad->current_write_count = ad->write_batch_count;
ad->write_batch_idled = 0;
- arq = ad->next_arq[ad->batch_data_dir];
+ rq = ad->next_rq[ad->batch_data_dir];
goto dispatch_request;
}
@@ -1296,8 +1110,7 @@ dispatch_request:
if (as_fifo_expired(ad, ad->batch_data_dir)) {
fifo_expired:
- arq = list_entry_fifo(ad->fifo_list[ad->batch_data_dir].next);
- BUG_ON(arq == NULL);
+ rq = rq_entry_fifo(ad->fifo_list[ad->batch_data_dir].next);
}
if (ad->changed_batch) {
@@ -1316,70 +1129,58 @@ fifo_expired:
}
/*
- * arq is the selected appropriate request.
+ * rq is the selected appropriate request.
*/
- as_move_to_dispatch(ad, arq);
+ as_move_to_dispatch(ad, rq);
return 1;
}
/*
- * add arq to rbtree and fifo
+ * add rq to rbtree and fifo
*/
static void as_add_request(request_queue_t *q, struct request *rq)
{
struct as_data *ad = q->elevator->elevator_data;
- struct as_rq *arq = RQ_DATA(rq);
int data_dir;
- arq->state = AS_RQ_NEW;
+ RQ_SET_STATE(rq, AS_RQ_NEW);
- if (rq_data_dir(arq->request) == READ
- || (arq->request->flags & REQ_RW_SYNC))
- arq->is_sync = 1;
- else
- arq->is_sync = 0;
- data_dir = arq->is_sync;
+ data_dir = rq_is_sync(rq);
- arq->io_context = as_get_io_context();
+ rq->elevator_private = as_get_io_context(q->node);
- if (arq->io_context) {
- as_update_iohist(ad, arq->io_context->aic, arq->request);
- atomic_inc(&arq->io_context->aic->nr_queued);
+ if (RQ_IOC(rq)) {
+ as_update_iohist(ad, RQ_IOC(rq)->aic, rq);
+ atomic_inc(&RQ_IOC(rq)->aic->nr_queued);
}
- as_add_arq_rb(ad, arq);
- if (rq_mergeable(arq->request))
- as_add_arq_hash(ad, arq);
+ as_add_rq_rb(ad, rq);
/*
* set expire time (only used for reads) and add to fifo list
*/
- arq->expires = jiffies + ad->fifo_expire[data_dir];
- list_add_tail(&arq->fifo, &ad->fifo_list[data_dir]);
+ rq_set_fifo_time(rq, jiffies + ad->fifo_expire[data_dir]);
+ list_add_tail(&rq->queuelist, &ad->fifo_list[data_dir]);
- as_update_arq(ad, arq); /* keep state machine up to date */
- arq->state = AS_RQ_QUEUED;
+ as_update_rq(ad, rq); /* keep state machine up to date */
+ RQ_SET_STATE(rq, AS_RQ_QUEUED);
}
static void as_activate_request(request_queue_t *q, struct request *rq)
{
- struct as_rq *arq = RQ_DATA(rq);
-
- WARN_ON(arq->state != AS_RQ_DISPATCHED);
- arq->state = AS_RQ_REMOVED;
- if (arq->io_context && arq->io_context->aic)
- atomic_dec(&arq->io_context->aic->nr_dispatched);
+ WARN_ON(RQ_STATE(rq) != AS_RQ_DISPATCHED);
+ RQ_SET_STATE(rq, AS_RQ_REMOVED);
+ if (RQ_IOC(rq) && RQ_IOC(rq)->aic)
+ atomic_dec(&RQ_IOC(rq)->aic->nr_dispatched);
}
static void as_deactivate_request(request_queue_t *q, struct request *rq)
{
- struct as_rq *arq = RQ_DATA(rq);
-
- WARN_ON(arq->state != AS_RQ_REMOVED);
- arq->state = AS_RQ_DISPATCHED;
- if (arq->io_context && arq->io_context->aic)
- atomic_inc(&arq->io_context->aic->nr_dispatched);
+ WARN_ON(RQ_STATE(rq) != AS_RQ_REMOVED);
+ RQ_SET_STATE(rq, AS_RQ_DISPATCHED);
+ if (RQ_IOC(rq) && RQ_IOC(rq)->aic)
+ atomic_inc(&RQ_IOC(rq)->aic->nr_dispatched);
}
/*
@@ -1396,93 +1197,35 @@ static int as_queue_empty(request_queue_t *q)
&& list_empty(&ad->fifo_list[REQ_SYNC]);
}
-static struct request *as_former_request(request_queue_t *q,
- struct request *rq)
-{
- struct as_rq *arq = RQ_DATA(rq);
- struct rb_node *rbprev = rb_prev(&arq->rb_node);
- struct request *ret = NULL;
-
- if (rbprev)
- ret = rb_entry_arq(rbprev)->request;
-
- return ret;
-}
-
-static struct request *as_latter_request(request_queue_t *q,
- struct request *rq)
-{
- struct as_rq *arq = RQ_DATA(rq);
- struct rb_node *rbnext = rb_next(&arq->rb_node);
- struct request *ret = NULL;
-
- if (rbnext)
- ret = rb_entry_arq(rbnext)->request;
-
- return ret;
-}
-
static int
as_merge(request_queue_t *q, struct request **req, struct bio *bio)
{
struct as_data *ad = q->elevator->elevator_data;
sector_t rb_key = bio->bi_sector + bio_sectors(bio);
struct request *__rq;
- int ret;
-
- /*
- * see if the merge hash can satisfy a back merge
- */
- __rq = as_find_arq_hash(ad, bio->bi_sector);
- if (__rq) {
- BUG_ON(__rq->sector + __rq->nr_sectors != bio->bi_sector);
-
- if (elv_rq_merge_ok(__rq, bio)) {
- ret = ELEVATOR_BACK_MERGE;
- goto out;
- }
- }
/*
* check for front merge
*/
- __rq = as_find_arq_rb(ad, rb_key, bio_data_dir(bio));
- if (__rq) {
- BUG_ON(rb_key != rq_rb_key(__rq));
-
- if (elv_rq_merge_ok(__rq, bio)) {
- ret = ELEVATOR_FRONT_MERGE;
- goto out;
- }
+ __rq = elv_rb_find(&ad->sort_list[bio_data_dir(bio)], rb_key);
+ if (__rq && elv_rq_merge_ok(__rq, bio)) {
+ *req = __rq;
+ return ELEVATOR_FRONT_MERGE;
}
return ELEVATOR_NO_MERGE;
-out:
- if (ret) {
- if (rq_mergeable(__rq))
- as_hot_arq_hash(ad, RQ_DATA(__rq));
- }
- *req = __rq;
- return ret;
}
-static void as_merged_request(request_queue_t *q, struct request *req)
+static void as_merged_request(request_queue_t *q, struct request *req, int type)
{
struct as_data *ad = q->elevator->elevator_data;
- struct as_rq *arq = RQ_DATA(req);
-
- /*
- * hash always needs to be repositioned, key is end sector
- */
- as_del_arq_hash(arq);
- as_add_arq_hash(ad, arq);
/*
* if the merge was a front merge, we need to reposition request
*/
- if (rq_rb_key(req) != arq->rb_key) {
- as_del_arq_rb(ad, arq);
- as_add_arq_rb(ad, arq);
+ if (type == ELEVATOR_FRONT_MERGE) {
+ as_del_rq_rb(ad, req);
+ as_add_rq_rb(ad, req);
/*
* Note! At this stage of this and the next function, our next
* request may not be optimal - eg the request may have "grown"
@@ -1494,38 +1237,22 @@ static void as_merged_request(request_queue_t *q, struct request *req)
static void as_merged_requests(request_queue_t *q, struct request *req,
struct request *next)
{
- struct as_data *ad = q->elevator->elevator_data;
- struct as_rq *arq = RQ_DATA(req);
- struct as_rq *anext = RQ_DATA(next);
-
- BUG_ON(!arq);
- BUG_ON(!anext);
-
/*
- * reposition arq (this is the merged request) in hash, and in rbtree
- * in case of a front merge
+ * if next expires before rq, assign its expire time to arq
+ * and move into next position (next will be deleted) in fifo
*/
- as_del_arq_hash(arq);
- as_add_arq_hash(ad, arq);
-
- if (rq_rb_key(req) != arq->rb_key) {
- as_del_arq_rb(ad, arq);
- as_add_arq_rb(ad, arq);
- }
+ if (!list_empty(&req->queuelist) && !list_empty(&next->queuelist)) {
+ if (time_before(rq_fifo_time(next), rq_fifo_time(req))) {
+ struct io_context *rioc = RQ_IOC(req);
+ struct io_context *nioc = RQ_IOC(next);
- /*
- * if anext expires before arq, assign its expire time to arq
- * and move into anext position (anext will be deleted) in fifo
- */
- if (!list_empty(&arq->fifo) && !list_empty(&anext->fifo)) {
- if (time_before(anext->expires, arq->expires)) {
- list_move(&arq->fifo, &anext->fifo);
- arq->expires = anext->expires;
+ list_move(&req->queuelist, &next->queuelist);
+ rq_set_fifo_time(req, rq_fifo_time(next));
/*
* Don't copy here but swap, because when anext is
* removed below, it must contain the unused context
*/
- swap_io_context(&arq->io_context, &anext->io_context);
+ swap_io_context(&rioc, &nioc);
}
}
@@ -1533,9 +1260,9 @@ static void as_merged_requests(request_queue_t *q, struct request *req,
* kill knowledge of next, this one is a goner
*/
as_remove_queued_request(q, next);
- as_put_io_context(anext);
+ as_put_io_context(next);
- anext->state = AS_RQ_MERGED;
+ RQ_SET_STATE(next, AS_RQ_MERGED);
}
/*
@@ -1553,61 +1280,18 @@ static void as_work_handler(void *data)
unsigned long flags;
spin_lock_irqsave(q->queue_lock, flags);
- if (!as_queue_empty(q))
- q->request_fn(q);
+ blk_start_queueing(q);
spin_unlock_irqrestore(q->queue_lock, flags);
}
-static void as_put_request(request_queue_t *q, struct request *rq)
-{
- struct as_data *ad = q->elevator->elevator_data;
- struct as_rq *arq = RQ_DATA(rq);
-
- if (!arq) {
- WARN_ON(1);
- return;
- }
-
- if (unlikely(arq->state != AS_RQ_POSTSCHED &&
- arq->state != AS_RQ_PRESCHED &&
- arq->state != AS_RQ_MERGED)) {
- printk("arq->state %d\n", arq->state);
- WARN_ON(1);
- }
-
- mempool_free(arq, ad->arq_pool);
- rq->elevator_private = NULL;
-}
-
-static int as_set_request(request_queue_t *q, struct request *rq,
- struct bio *bio, gfp_t gfp_mask)
-{
- struct as_data *ad = q->elevator->elevator_data;
- struct as_rq *arq = mempool_alloc(ad->arq_pool, gfp_mask);
-
- if (arq) {
- memset(arq, 0, sizeof(*arq));
- RB_CLEAR_NODE(&arq->rb_node);
- arq->request = rq;
- arq->state = AS_RQ_PRESCHED;
- arq->io_context = NULL;
- INIT_HLIST_NODE(&arq->hash);
- INIT_LIST_HEAD(&arq->fifo);
- rq->elevator_private = arq;
- return 0;
- }
-
- return 1;
-}
-
-static int as_may_queue(request_queue_t *q, int rw, struct bio *bio)
+static int as_may_queue(request_queue_t *q, int rw)
{
int ret = ELV_MQUEUE_MAY;
struct as_data *ad = q->elevator->elevator_data;
struct io_context *ioc;
if (ad->antic_status == ANTIC_WAIT_REQ ||
ad->antic_status == ANTIC_WAIT_NEXT) {
- ioc = as_get_io_context();
+ ioc = as_get_io_context(q->node);
if (ad->io_context == ioc)
ret = ELV_MQUEUE_MUST;
put_io_context(ioc);
@@ -1626,23 +1310,16 @@ static void as_exit_queue(elevator_t *e)
BUG_ON(!list_empty(&ad->fifo_list[REQ_SYNC]));
BUG_ON(!list_empty(&ad->fifo_list[REQ_ASYNC]));
- mempool_destroy(ad->arq_pool);
put_io_context(ad->io_context);
- kfree(ad->hash);
kfree(ad);
}
/*
- * initialize elevator private data (as_data), and alloc a arq for
- * each request on the free lists
+ * initialize elevator private data (as_data).
*/
static void *as_init_queue(request_queue_t *q, elevator_t *e)
{
struct as_data *ad;
- int i;
-
- if (!arq_pool)
- return NULL;
ad = kmalloc_node(sizeof(*ad), GFP_KERNEL, q->node);
if (!ad)
@@ -1651,30 +1328,12 @@ static void *as_init_queue(request_queue_t *q, elevator_t *e)
ad->q = q; /* Identify what queue the data belongs to */
- ad->hash = kmalloc_node(sizeof(struct hlist_head)*AS_HASH_ENTRIES,
- GFP_KERNEL, q->node);
- if (!ad->hash) {
- kfree(ad);
- return NULL;
- }
-
- ad->arq_pool = mempool_create_node(BLKDEV_MIN_RQ, mempool_alloc_slab,
- mempool_free_slab, arq_pool, q->node);
- if (!ad->arq_pool) {
- kfree(ad->hash);
- kfree(ad);
- return NULL;
- }
-
/* anticipatory scheduling helpers */
ad->antic_timer.function = as_antic_timeout;
ad->antic_timer.data = (unsigned long)q;
init_timer(&ad->antic_timer);
INIT_WORK(&ad->antic_work, as_work_handler, q);
- for (i = 0; i < AS_HASH_ENTRIES; i++)
- INIT_HLIST_HEAD(&ad->hash[i]);
-
INIT_LIST_HEAD(&ad->fifo_list[REQ_SYNC]);
INIT_LIST_HEAD(&ad->fifo_list[REQ_ASYNC]);
ad->sort_list[REQ_SYNC] = RB_ROOT;
@@ -1787,10 +1446,8 @@ static struct elevator_type iosched_as = {
.elevator_deactivate_req_fn = as_deactivate_request,
.elevator_queue_empty_fn = as_queue_empty,
.elevator_completed_req_fn = as_completed_request,
- .elevator_former_req_fn = as_former_request,
- .elevator_latter_req_fn = as_latter_request,
- .elevator_set_req_fn = as_set_request,
- .elevator_put_req_fn = as_put_request,
+ .elevator_former_req_fn = elv_rb_former_request,
+ .elevator_latter_req_fn = elv_rb_latter_request,
.elevator_may_queue_fn = as_may_queue,
.elevator_init_fn = as_init_queue,
.elevator_exit_fn = as_exit_queue,
@@ -1806,11 +1463,6 @@ static int __init as_init(void)
{
int ret;
- arq_pool = kmem_cache_create("as_arq", sizeof(struct as_rq),
- 0, 0, NULL, NULL);
- if (!arq_pool)
- return -ENOMEM;
-
ret = elv_register(&iosched_as);
if (!ret) {
/*
@@ -1822,21 +1474,19 @@ static int __init as_init(void)
return 0;
}
- kmem_cache_destroy(arq_pool);
return ret;
}
static void __exit as_exit(void)
{
- DECLARE_COMPLETION(all_gone);
+ DECLARE_COMPLETION_ONSTACK(all_gone);
elv_unregister(&iosched_as);
ioc_gone = &all_gone;
/* ioc_gone's update must be visible before reading ioc_count */
smp_wmb();
- if (atomic_read(&ioc_count))
+ if (elv_ioc_count_read(ioc_count))
wait_for_completion(ioc_gone);
synchronize_rcu();
- kmem_cache_destroy(arq_pool);
}
module_init(as_init);
diff --git a/block/blktrace.c b/block/blktrace.c
index 2b4ef2b89b8d..135593c8e45b 100644
--- a/block/blktrace.c
+++ b/block/blktrace.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2006 Jens Axboe <axboe@suse.de>
+ * Copyright (C) 2006 Jens Axboe <axboe@kernel.dk>
*
* 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
@@ -69,7 +69,7 @@ static u32 ddir_act[2] __read_mostly = { BLK_TC_ACT(BLK_TC_READ), BLK_TC_ACT(BLK
/*
* Bio action bits of interest
*/
-static u32 bio_act[5] __read_mostly = { 0, BLK_TC_ACT(BLK_TC_BARRIER), BLK_TC_ACT(BLK_TC_SYNC), 0, BLK_TC_ACT(BLK_TC_AHEAD) };
+static u32 bio_act[9] __read_mostly = { 0, BLK_TC_ACT(BLK_TC_BARRIER), BLK_TC_ACT(BLK_TC_SYNC), 0, BLK_TC_ACT(BLK_TC_AHEAD), 0, 0, 0, BLK_TC_ACT(BLK_TC_META) };
/*
* More could be added as needed, taking care to increment the decrementer
@@ -81,6 +81,8 @@ static u32 bio_act[5] __read_mostly = { 0, BLK_TC_ACT(BLK_TC_BARRIER), BLK_TC_AC
(((rw) & (1 << BIO_RW_SYNC)) >> (BIO_RW_SYNC - 1))
#define trace_ahead_bit(rw) \
(((rw) & (1 << BIO_RW_AHEAD)) << (2 - BIO_RW_AHEAD))
+#define trace_meta_bit(rw) \
+ (((rw) & (1 << BIO_RW_META)) >> (BIO_RW_META - 3))
/*
* The worker for the various blk_add_trace*() types. Fills out a
@@ -103,6 +105,7 @@ void __blk_add_trace(struct blk_trace *bt, sector_t sector, int bytes,
what |= bio_act[trace_barrier_bit(rw)];
what |= bio_act[trace_sync_bit(rw)];
what |= bio_act[trace_ahead_bit(rw)];
+ what |= bio_act[trace_meta_bit(rw)];
pid = tsk->pid;
if (unlikely(act_log_check(bt, what, sector, pid)))
@@ -450,8 +453,10 @@ int blk_trace_ioctl(struct block_device *bdev, unsigned cmd, char __user *arg)
**/
void blk_trace_shutdown(request_queue_t *q)
{
- blk_trace_startstop(q, 0);
- blk_trace_remove(q);
+ if (q->blk_trace) {
+ blk_trace_startstop(q, 0);
+ blk_trace_remove(q);
+ }
}
/*
@@ -471,6 +476,9 @@ static void blk_check_time(unsigned long long *t)
*t -= (a + b) / 2;
}
+/*
+ * calibrate our inter-CPU timings
+ */
static void blk_trace_check_cpu_time(void *data)
{
unsigned long long *t;
@@ -488,20 +496,6 @@ static void blk_trace_check_cpu_time(void *data)
put_cpu();
}
-/*
- * Call blk_trace_check_cpu_time() on each CPU to calibrate our inter-CPU
- * timings
- */
-static void blk_trace_calibrate_offsets(void)
-{
- unsigned long flags;
-
- smp_call_function(blk_trace_check_cpu_time, NULL, 1, 1);
- local_irq_save(flags);
- blk_trace_check_cpu_time(NULL);
- local_irq_restore(flags);
-}
-
static void blk_trace_set_ht_offsets(void)
{
#if defined(CONFIG_SCHED_SMT)
@@ -530,7 +524,7 @@ static void blk_trace_set_ht_offsets(void)
static __init int blk_trace_init(void)
{
mutex_init(&blk_tree_mutex);
- blk_trace_calibrate_offsets();
+ on_each_cpu(blk_trace_check_cpu_time, NULL, 1, 1);
blk_trace_set_ht_offsets();
return 0;
diff --git a/block/cfq-iosched.c b/block/cfq-iosched.c
index 3a3aee08ec5f..d3d76136f53a 100644
--- a/block/cfq-iosched.c
+++ b/block/cfq-iosched.c
@@ -4,7 +4,7 @@
* Based on ideas from a previously unfinished io
* scheduler (round robin per-process disk scheduling) and Andrea Arcangeli.
*
- * Copyright (C) 2003 Jens Axboe <axboe@suse.de>
+ * Copyright (C) 2003 Jens Axboe <axboe@kernel.dk>
*/
#include <linux/module.h>
#include <linux/blkdev.h>
@@ -17,7 +17,6 @@
* tunables
*/
static const int cfq_quantum = 4; /* max queue in one round of service */
-static const int cfq_queued = 8; /* minimum rq allocate limit per-queue*/
static const int cfq_fifo_expire[2] = { HZ / 4, HZ / 8 };
static const int cfq_back_max = 16 * 1024; /* maximum backwards seek, in KiB */
static const int cfq_back_penalty = 2; /* penalty of a backwards seek */
@@ -32,8 +31,6 @@ static int cfq_slice_idle = HZ / 125;
#define CFQ_KEY_ASYNC (0)
-static DEFINE_SPINLOCK(cfq_exit_lock);
-
/*
* for the hash of cfqq inside the cfqd
*/
@@ -41,37 +38,19 @@ static DEFINE_SPINLOCK(cfq_exit_lock);
#define CFQ_QHASH_ENTRIES (1 << CFQ_QHASH_SHIFT)
#define list_entry_qhash(entry) hlist_entry((entry), struct cfq_queue, cfq_hash)
-/*
- * for the hash of crq inside the cfqq
- */
-#define CFQ_MHASH_SHIFT 6
-#define CFQ_MHASH_BLOCK(sec) ((sec) >> 3)
-#define CFQ_MHASH_ENTRIES (1 << CFQ_MHASH_SHIFT)
-#define CFQ_MHASH_FN(sec) hash_long(CFQ_MHASH_BLOCK(sec), CFQ_MHASH_SHIFT)
-#define rq_hash_key(rq) ((rq)->sector + (rq)->nr_sectors)
-#define list_entry_hash(ptr) hlist_entry((ptr), struct cfq_rq, hash)
-
#define list_entry_cfqq(ptr) list_entry((ptr), struct cfq_queue, cfq_list)
-#define list_entry_fifo(ptr) list_entry((ptr), struct request, queuelist)
-#define RQ_DATA(rq) (rq)->elevator_private
+#define RQ_CIC(rq) ((struct cfq_io_context*)(rq)->elevator_private)
+#define RQ_CFQQ(rq) ((rq)->elevator_private2)
-/*
- * rb-tree defines
- */
-#define rb_entry_crq(node) rb_entry((node), struct cfq_rq, rb_node)
-#define rq_rb_key(rq) (rq)->sector
-
-static kmem_cache_t *crq_pool;
static kmem_cache_t *cfq_pool;
static kmem_cache_t *cfq_ioc_pool;
-static atomic_t ioc_count = ATOMIC_INIT(0);
+static DEFINE_PER_CPU(unsigned long, ioc_count);
static struct completion *ioc_gone;
#define CFQ_PRIO_LISTS IOPRIO_BE_NR
#define cfq_class_idle(cfqq) ((cfqq)->ioprio_class == IOPRIO_CLASS_IDLE)
-#define cfq_class_be(cfqq) ((cfqq)->ioprio_class == IOPRIO_CLASS_BE)
#define cfq_class_rt(cfqq) ((cfqq)->ioprio_class == IOPRIO_CLASS_RT)
#define ASYNC (0)
@@ -103,29 +82,14 @@ struct cfq_data {
unsigned int busy_queues;
/*
- * non-ordered list of empty cfqq's
- */
- struct list_head empty_list;
-
- /*
* cfqq lookup hash
*/
struct hlist_head *cfq_hash;
- /*
- * global crq hash for all queues
- */
- struct hlist_head *crq_hash;
-
- mempool_t *crq_pool;
-
int rq_in_driver;
int hw_tag;
/*
- * schedule slice state info
- */
- /*
* idle window management
*/
struct timer_list idle_slice_timer;
@@ -141,13 +105,10 @@ struct cfq_data {
sector_t last_sector;
unsigned long last_end_request;
- unsigned int rq_starved;
-
/*
* tunables, see top of file
*/
unsigned int cfq_quantum;
- unsigned int cfq_queued;
unsigned int cfq_fifo_expire[2];
unsigned int cfq_back_penalty;
unsigned int cfq_back_max;
@@ -170,23 +131,24 @@ struct cfq_queue {
struct hlist_node cfq_hash;
/* hash key */
unsigned int key;
- /* on either rr or empty list of cfqd */
+ /* member of the rr/busy/cur/idle cfqd list */
struct list_head cfq_list;
/* sorted list of pending requests */
struct rb_root sort_list;
/* if fifo isn't expired, next request to serve */
- struct cfq_rq *next_crq;
+ struct request *next_rq;
/* requests queued in sort_list */
int queued[2];
/* currently allocated requests */
int allocated[2];
+ /* pending metadata requests */
+ int meta_pending;
/* fifo list of requests in sort_list */
struct list_head fifo;
unsigned long slice_start;
unsigned long slice_end;
unsigned long slice_left;
- unsigned long service_last;
/* number of requests that are on the dispatch list */
int on_dispatch[2];
@@ -199,18 +161,6 @@ struct cfq_queue {
unsigned int flags;
};
-struct cfq_rq {
- struct rb_node rb_node;
- sector_t rb_key;
- struct request *request;
- struct hlist_node hash;
-
- struct cfq_queue *cfq_queue;
- struct cfq_io_context *io_context;
-
- unsigned int crq_flags;
-};
-
enum cfqq_state_flags {
CFQ_CFQQ_FLAG_on_rr = 0,
CFQ_CFQQ_FLAG_wait_request,
@@ -220,6 +170,7 @@ enum cfqq_state_flags {
CFQ_CFQQ_FLAG_fifo_expire,
CFQ_CFQQ_FLAG_idle_window,
CFQ_CFQQ_FLAG_prio_changed,
+ CFQ_CFQQ_FLAG_queue_new,
};
#define CFQ_CFQQ_FNS(name) \
@@ -244,70 +195,14 @@ CFQ_CFQQ_FNS(must_dispatch);
CFQ_CFQQ_FNS(fifo_expire);
CFQ_CFQQ_FNS(idle_window);
CFQ_CFQQ_FNS(prio_changed);
+CFQ_CFQQ_FNS(queue_new);
#undef CFQ_CFQQ_FNS
-enum cfq_rq_state_flags {
- CFQ_CRQ_FLAG_is_sync = 0,
-};
-
-#define CFQ_CRQ_FNS(name) \
-static inline void cfq_mark_crq_##name(struct cfq_rq *crq) \
-{ \
- crq->crq_flags |= (1 << CFQ_CRQ_FLAG_##name); \
-} \
-static inline void cfq_clear_crq_##name(struct cfq_rq *crq) \
-{ \
- crq->crq_flags &= ~(1 << CFQ_CRQ_FLAG_##name); \
-} \
-static inline int cfq_crq_##name(const struct cfq_rq *crq) \
-{ \
- return (crq->crq_flags & (1 << CFQ_CRQ_FLAG_##name)) != 0; \
-}
-
-CFQ_CRQ_FNS(is_sync);
-#undef CFQ_CRQ_FNS
-
static struct cfq_queue *cfq_find_cfq_hash(struct cfq_data *, unsigned int, unsigned short);
-static void cfq_dispatch_insert(request_queue_t *, struct cfq_rq *);
+static void cfq_dispatch_insert(request_queue_t *, struct request *);
static struct cfq_queue *cfq_get_queue(struct cfq_data *cfqd, unsigned int key, struct task_struct *tsk, gfp_t gfp_mask);
/*
- * lots of deadline iosched dupes, can be abstracted later...
- */
-static inline void cfq_del_crq_hash(struct cfq_rq *crq)
-{
- hlist_del_init(&crq->hash);
-}
-
-static inline void cfq_add_crq_hash(struct cfq_data *cfqd, struct cfq_rq *crq)
-{
- const int hash_idx = CFQ_MHASH_FN(rq_hash_key(crq->request));
-
- hlist_add_head(&crq->hash, &cfqd->crq_hash[hash_idx]);
-}
-
-static struct request *cfq_find_rq_hash(struct cfq_data *cfqd, sector_t offset)
-{
- struct hlist_head *hash_list = &cfqd->crq_hash[CFQ_MHASH_FN(offset)];
- struct hlist_node *entry, *next;
-
- hlist_for_each_safe(entry, next, hash_list) {
- struct cfq_rq *crq = list_entry_hash(entry);
- struct request *__rq = crq->request;
-
- if (!rq_mergeable(__rq)) {
- cfq_del_crq_hash(crq);
- continue;
- }
-
- if (rq_hash_key(__rq) == offset)
- return __rq;
- }
-
- return NULL;
-}
-
-/*
* scheduler run of queue, if there are requests pending and no one in the
* driver that will restart queueing
*/
@@ -333,12 +228,12 @@ static inline pid_t cfq_queue_pid(struct task_struct *task, int rw)
}
/*
- * Lifted from AS - choose which of crq1 and crq2 that is best served now.
+ * Lifted from AS - choose which of rq1 and rq2 that is best served now.
* We choose the request that is closest to the head right now. Distance
* behind the head is penalized and only allowed to a certain extent.
*/
-static struct cfq_rq *
-cfq_choose_req(struct cfq_data *cfqd, struct cfq_rq *crq1, struct cfq_rq *crq2)
+static struct request *
+cfq_choose_req(struct cfq_data *cfqd, struct request *rq1, struct request *rq2)
{
sector_t last, s1, s2, d1 = 0, d2 = 0;
unsigned long back_max;
@@ -346,18 +241,22 @@ cfq_choose_req(struct cfq_data *cfqd, struct cfq_rq *crq1, struct cfq_rq *crq2)
#define CFQ_RQ2_WRAP 0x02 /* request 2 wraps */
unsigned wrap = 0; /* bit mask: requests behind the disk head? */
- if (crq1 == NULL || crq1 == crq2)
- return crq2;
- if (crq2 == NULL)
- return crq1;
+ if (rq1 == NULL || rq1 == rq2)
+ return rq2;
+ if (rq2 == NULL)
+ return rq1;
- if (cfq_crq_is_sync(crq1) && !cfq_crq_is_sync(crq2))
- return crq1;
- else if (cfq_crq_is_sync(crq2) && !cfq_crq_is_sync(crq1))
- return crq2;
+ if (rq_is_sync(rq1) && !rq_is_sync(rq2))
+ return rq1;
+ else if (rq_is_sync(rq2) && !rq_is_sync(rq1))
+ return rq2;
+ if (rq_is_meta(rq1) && !rq_is_meta(rq2))
+ return rq1;
+ else if (rq_is_meta(rq2) && !rq_is_meta(rq1))
+ return rq2;
- s1 = crq1->request->sector;
- s2 = crq2->request->sector;
+ s1 = rq1->sector;
+ s2 = rq2->sector;
last = cfqd->last_sector;
@@ -392,23 +291,23 @@ cfq_choose_req(struct cfq_data *cfqd, struct cfq_rq *crq1, struct cfq_rq *crq2)
* check two variables for all permutations: --> faster!
*/
switch (wrap) {
- case 0: /* common case for CFQ: crq1 and crq2 not wrapped */
+ case 0: /* common case for CFQ: rq1 and rq2 not wrapped */
if (d1 < d2)
- return crq1;
+ return rq1;
else if (d2 < d1)
- return crq2;
+ return rq2;
else {
if (s1 >= s2)
- return crq1;
+ return rq1;
else
- return crq2;
+ return rq2;
}
case CFQ_RQ2_WRAP:
- return crq1;
+ return rq1;
case CFQ_RQ1_WRAP:
- return crq2;
- case (CFQ_RQ1_WRAP|CFQ_RQ2_WRAP): /* both crqs wrapped */
+ return rq2;
+ case (CFQ_RQ1_WRAP|CFQ_RQ2_WRAP): /* both rqs wrapped */
default:
/*
* Since both rqs are wrapped,
@@ -417,50 +316,43 @@ cfq_choose_req(struct cfq_data *cfqd, struct cfq_rq *crq1, struct cfq_rq *crq2)
* since back seek takes more time than forward.
*/
if (s1 <= s2)
- return crq1;
+ return rq1;
else
- return crq2;
+ return rq2;
}
}
/*
* would be nice to take fifo expire time into account as well
*/
-static struct cfq_rq *
-cfq_find_next_crq(struct cfq_data *cfqd, struct cfq_queue *cfqq,
- struct cfq_rq *last)
+static struct request *
+cfq_find_next_rq(struct cfq_data *cfqd, struct cfq_queue *cfqq,
+ struct request *last)
{
- struct cfq_rq *crq_next = NULL, *crq_prev = NULL;
- struct rb_node *rbnext, *rbprev;
-
- if (!(rbnext = rb_next(&last->rb_node))) {
- rbnext = rb_first(&cfqq->sort_list);
- if (rbnext == &last->rb_node)
- rbnext = NULL;
- }
+ struct rb_node *rbnext = rb_next(&last->rb_node);
+ struct rb_node *rbprev = rb_prev(&last->rb_node);
+ struct request *next = NULL, *prev = NULL;
- rbprev = rb_prev(&last->rb_node);
+ BUG_ON(RB_EMPTY_NODE(&last->rb_node));
if (rbprev)
- crq_prev = rb_entry_crq(rbprev);
- if (rbnext)
- crq_next = rb_entry_crq(rbnext);
-
- return cfq_choose_req(cfqd, crq_next, crq_prev);
-}
+ prev = rb_entry_rq(rbprev);
-static void cfq_update_next_crq(struct cfq_rq *crq)
-{
- struct cfq_queue *cfqq = crq->cfq_queue;
+ if (rbnext)
+ next = rb_entry_rq(rbnext);
+ else {
+ rbnext = rb_first(&cfqq->sort_list);
+ if (rbnext && rbnext != &last->rb_node)
+ next = rb_entry_rq(rbnext);
+ }
- if (cfqq->next_crq == crq)
- cfqq->next_crq = cfq_find_next_crq(cfqq->cfqd, cfqq, crq);
+ return cfq_choose_req(cfqd, next, prev);
}
static void cfq_resort_rr_list(struct cfq_queue *cfqq, int preempted)
{
struct cfq_data *cfqd = cfqq->cfqd;
- struct list_head *list, *entry;
+ struct list_head *list;
BUG_ON(!cfq_cfqq_on_rr(cfqq));
@@ -485,31 +377,26 @@ static void cfq_resort_rr_list(struct cfq_queue *cfqq, int preempted)
}
/*
- * if queue was preempted, just add to front to be fair. busy_rr
- * isn't sorted, but insert at the back for fairness.
+ * If this queue was preempted or is new (never been serviced), let
+ * it be added first for fairness but beind other new queues.
+ * Otherwise, just add to the back of the list.
*/
- if (preempted || list == &cfqd->busy_rr) {
- if (preempted)
- list = list->prev;
+ if (preempted || cfq_cfqq_queue_new(cfqq)) {
+ struct list_head *n = list;
+ struct cfq_queue *__cfqq;
- list_add_tail(&cfqq->cfq_list, list);
- return;
- }
+ while (n->next != list) {
+ __cfqq = list_entry_cfqq(n->next);
+ if (!cfq_cfqq_queue_new(__cfqq))
+ break;
- /*
- * sort by when queue was last serviced
- */
- entry = list;
- while ((entry = entry->prev) != list) {
- struct cfq_queue *__cfqq = list_entry_cfqq(entry);
+ n = n->next;
+ }
- if (!__cfqq->service_last)
- break;
- if (time_before(__cfqq->service_last, cfqq->service_last))
- break;
+ list = n;
}
- list_add(&cfqq->cfq_list, entry);
+ list_add_tail(&cfqq->cfq_list, list);
}
/*
@@ -531,7 +418,7 @@ cfq_del_cfqq_rr(struct cfq_data *cfqd, struct cfq_queue *cfqq)
{
BUG_ON(!cfq_cfqq_on_rr(cfqq));
cfq_clear_cfqq_on_rr(cfqq);
- list_move(&cfqq->cfq_list, &cfqd->empty_list);
+ list_del_init(&cfqq->cfq_list);
BUG_ON(!cfqd->busy_queues);
cfqd->busy_queues--;
@@ -540,81 +427,43 @@ cfq_del_cfqq_rr(struct cfq_data *cfqd, struct cfq_queue *cfqq)
/*
* rb tree support functions
*/
-static inline void cfq_del_crq_rb(struct cfq_rq *crq)
+static inline void cfq_del_rq_rb(struct request *rq)
{
- struct cfq_queue *cfqq = crq->cfq_queue;
+ struct cfq_queue *cfqq = RQ_CFQQ(rq);
struct cfq_data *cfqd = cfqq->cfqd;
- const int sync = cfq_crq_is_sync(crq);
+ const int sync = rq_is_sync(rq);
BUG_ON(!cfqq->queued[sync]);
cfqq->queued[sync]--;
- cfq_update_next_crq(crq);
-
- rb_erase(&crq->rb_node, &cfqq->sort_list);
+ elv_rb_del(&cfqq->sort_list, rq);
if (cfq_cfqq_on_rr(cfqq) && RB_EMPTY_ROOT(&cfqq->sort_list))
cfq_del_cfqq_rr(cfqd, cfqq);
}
-static struct cfq_rq *
-__cfq_add_crq_rb(struct cfq_rq *crq)
+static void cfq_add_rq_rb(struct request *rq)
{
- struct rb_node **p = &crq->cfq_queue->sort_list.rb_node;
- struct rb_node *parent = NULL;
- struct cfq_rq *__crq;
-
- while (*p) {
- parent = *p;
- __crq = rb_entry_crq(parent);
-
- if (crq->rb_key < __crq->rb_key)
- p = &(*p)->rb_left;
- else if (crq->rb_key > __crq->rb_key)
- p = &(*p)->rb_right;
- else
- return __crq;
- }
-
- rb_link_node(&crq->rb_node, parent, p);
- return NULL;
-}
-
-static void cfq_add_crq_rb(struct cfq_rq *crq)
-{
- struct cfq_queue *cfqq = crq->cfq_queue;
+ struct cfq_queue *cfqq = RQ_CFQQ(rq);
struct cfq_data *cfqd = cfqq->cfqd;
- struct request *rq = crq->request;
- struct cfq_rq *__alias;
+ struct request *__alias;
- crq->rb_key = rq_rb_key(rq);
- cfqq->queued[cfq_crq_is_sync(crq)]++;
+ cfqq->queued[rq_is_sync(rq)]++;
/*
* looks a little odd, but the first insert might return an alias.
* if that happens, put the alias on the dispatch list
*/
- while ((__alias = __cfq_add_crq_rb(crq)) != NULL)
+ while ((__alias = elv_rb_add(&cfqq->sort_list, rq)) != NULL)
cfq_dispatch_insert(cfqd->queue, __alias);
-
- rb_insert_color(&crq->rb_node, &cfqq->sort_list);
-
- if (!cfq_cfqq_on_rr(cfqq))
- cfq_add_cfqq_rr(cfqd, cfqq);
-
- /*
- * check if this request is a better next-serve candidate
- */
- cfqq->next_crq = cfq_choose_req(cfqd, cfqq->next_crq, crq);
}
static inline void
-cfq_reposition_crq_rb(struct cfq_queue *cfqq, struct cfq_rq *crq)
+cfq_reposition_rq_rb(struct cfq_queue *cfqq, struct request *rq)
{
- rb_erase(&crq->rb_node, &cfqq->sort_list);
- cfqq->queued[cfq_crq_is_sync(crq)]--;
-
- cfq_add_crq_rb(crq);
+ elv_rb_del(&cfqq->sort_list, rq);
+ cfqq->queued[rq_is_sync(rq)]--;
+ cfq_add_rq_rb(rq);
}
static struct request *
@@ -623,27 +472,14 @@ cfq_find_rq_fmerge(struct cfq_data *cfqd, struct bio *bio)
struct task_struct *tsk = current;
pid_t key = cfq_queue_pid(tsk, bio_data_dir(bio));
struct cfq_queue *cfqq;
- struct rb_node *n;
- sector_t sector;
cfqq = cfq_find_cfq_hash(cfqd, key, tsk->ioprio);
- if (!cfqq)
- goto out;
-
- sector = bio->bi_sector + bio_sectors(bio);
- n = cfqq->sort_list.rb_node;
- while (n) {
- struct cfq_rq *crq = rb_entry_crq(n);
+ if (cfqq) {
+ sector_t sector = bio->bi_sector + bio_sectors(bio);
- if (sector < crq->rb_key)
- n = n->rb_left;
- else if (sector > crq->rb_key)
- n = n->rb_right;
- else
- return crq->request;
+ return elv_rb_find(&cfqq->sort_list, sector);
}
-out:
return NULL;
}
@@ -673,11 +509,18 @@ static void cfq_deactivate_request(request_queue_t *q, struct request *rq)
static void cfq_remove_request(struct request *rq)
{
- struct cfq_rq *crq = RQ_DATA(rq);
+ struct cfq_queue *cfqq = RQ_CFQQ(rq);
+
+ if (cfqq->next_rq == rq)
+ cfqq->next_rq = cfq_find_next_rq(cfqq->cfqd, cfqq, rq);
list_del_init(&rq->queuelist);
- cfq_del_crq_rb(crq);
- cfq_del_crq_hash(crq);
+ cfq_del_rq_rb(rq);
+
+ if (rq_is_meta(rq)) {
+ WARN_ON(!cfqq->meta_pending);
+ cfqq->meta_pending--;
+ }
}
static int
@@ -685,39 +528,23 @@ cfq_merge(request_queue_t *q, struct request **req, struct bio *bio)
{
struct cfq_data *cfqd = q->elevator->elevator_data;
struct request *__rq;
- int ret;
-
- __rq = cfq_find_rq_hash(cfqd, bio->bi_sector);
- if (__rq && elv_rq_merge_ok(__rq, bio)) {
- ret = ELEVATOR_BACK_MERGE;
- goto out;
- }
__rq = cfq_find_rq_fmerge(cfqd, bio);
if (__rq && elv_rq_merge_ok(__rq, bio)) {
- ret = ELEVATOR_FRONT_MERGE;
- goto out;
+ *req = __rq;
+ return ELEVATOR_FRONT_MERGE;
}
return ELEVATOR_NO_MERGE;
-out:
- *req = __rq;
- return ret;
}
-static void cfq_merged_request(request_queue_t *q, struct request *req)
+static void cfq_merged_request(request_queue_t *q, struct request *req,
+ int type)
{
- struct cfq_data *cfqd = q->elevator->elevator_data;
- struct cfq_rq *crq = RQ_DATA(req);
-
- cfq_del_crq_hash(crq);
- cfq_add_crq_hash(cfqd, crq);
-
- if (rq_rb_key(req) != crq->rb_key) {
- struct cfq_queue *cfqq = crq->cfq_queue;
+ if (type == ELEVATOR_FRONT_MERGE) {
+ struct cfq_queue *cfqq = RQ_CFQQ(req);
- cfq_update_next_crq(crq);
- cfq_reposition_crq_rb(cfqq, crq);
+ cfq_reposition_rq_rb(cfqq, req);
}
}
@@ -725,8 +552,6 @@ static void
cfq_merged_requests(request_queue_t *q, struct request *rq,
struct request *next)
{
- cfq_merged_request(q, rq);
-
/*
* reposition in fifo if next is older than rq
*/
@@ -768,13 +593,12 @@ __cfq_slice_expired(struct cfq_data *cfqd, struct cfq_queue *cfqq,
if (cfq_cfqq_wait_request(cfqq))
del_timer(&cfqd->idle_slice_timer);
- if (!preempted && !cfq_cfqq_dispatched(cfqq)) {
- cfqq->service_last = now;
+ if (!preempted && !cfq_cfqq_dispatched(cfqq))
cfq_schedule_dispatch(cfqd);
- }
cfq_clear_cfqq_must_dispatch(cfqq);
cfq_clear_cfqq_wait_request(cfqq);
+ cfq_clear_cfqq_queue_new(cfqq);
/*
* store what was left of this slice, if the queue idled out
@@ -868,26 +692,25 @@ static struct cfq_queue *cfq_set_active_queue(struct cfq_data *cfqd)
{
struct cfq_queue *cfqq = NULL;
- /*
- * if current list is non-empty, grab first entry. if it is empty,
- * get next prio level and grab first entry then if any are spliced
- */
- if (!list_empty(&cfqd->cur_rr) || cfq_get_next_prio_level(cfqd) != -1)
+ if (!list_empty(&cfqd->cur_rr) || cfq_get_next_prio_level(cfqd) != -1) {
+ /*
+ * if current list is non-empty, grab first entry. if it is
+ * empty, get next prio level and grab first entry then if any
+ * are spliced
+ */
cfqq = list_entry_cfqq(cfqd->cur_rr.next);
-
- /*
- * If no new queues are available, check if the busy list has some
- * before falling back to idle io.
- */
- if (!cfqq && !list_empty(&cfqd->busy_rr))
+ } else if (!list_empty(&cfqd->busy_rr)) {
+ /*
+ * If no new queues are available, check if the busy list has
+ * some before falling back to idle io.
+ */
cfqq = list_entry_cfqq(cfqd->busy_rr.next);
-
- /*
- * if we have idle queues and no rt or be queues had pending
- * requests, either allow immediate service if the grace period
- * has passed or arm the idle grace timer
- */
- if (!cfqq && !list_empty(&cfqd->idle_rr)) {
+ } else if (!list_empty(&cfqd->idle_rr)) {
+ /*
+ * if we have idle queues and no rt or be queues had pending
+ * requests, either allow immediate service if the grace period
+ * has passed or arm the idle grace timer
+ */
unsigned long end = cfqd->last_end_request + CFQ_IDLE_GRACE;
if (time_after_eq(jiffies, end))
@@ -942,16 +765,14 @@ static int cfq_arm_slice_timer(struct cfq_data *cfqd, struct cfq_queue *cfqq)
return 1;
}
-static void cfq_dispatch_insert(request_queue_t *q, struct cfq_rq *crq)
+static void cfq_dispatch_insert(request_queue_t *q, struct request *rq)
{
struct cfq_data *cfqd = q->elevator->elevator_data;
- struct cfq_queue *cfqq = crq->cfq_queue;
- struct request *rq;
+ struct cfq_queue *cfqq = RQ_CFQQ(rq);
- cfqq->next_crq = cfq_find_next_crq(cfqd, cfqq, crq);
- cfq_remove_request(crq->request);
- cfqq->on_dispatch[cfq_crq_is_sync(crq)]++;
- elv_dispatch_sort(q, crq->request);
+ cfq_remove_request(rq);
+ cfqq->on_dispatch[rq_is_sync(rq)]++;
+ elv_dispatch_sort(q, rq);
rq = list_entry(q->queue_head.prev, struct request, queuelist);
cfqd->last_sector = rq->sector + rq->nr_sectors;
@@ -960,24 +781,23 @@ static void cfq_dispatch_insert(request_queue_t *q, struct cfq_rq *crq)
/*
* return expired entry, or NULL to just start from scratch in rbtree
*/
-static inline struct cfq_rq *cfq_check_fifo(struct cfq_queue *cfqq)
+static inline struct request *cfq_check_fifo(struct cfq_queue *cfqq)
{
struct cfq_data *cfqd = cfqq->cfqd;
struct request *rq;
- struct cfq_rq *crq;
+ int fifo;
if (cfq_cfqq_fifo_expire(cfqq))
return NULL;
+ if (list_empty(&cfqq->fifo))
+ return NULL;
- if (!list_empty(&cfqq->fifo)) {
- int fifo = cfq_cfqq_class_sync(cfqq);
+ fifo = cfq_cfqq_class_sync(cfqq);
+ rq = rq_entry_fifo(cfqq->fifo.next);
- crq = RQ_DATA(list_entry_fifo(cfqq->fifo.next));
- rq = crq->request;
- if (time_after(jiffies, rq->start_time + cfqd->cfq_fifo_expire[fifo])) {
- cfq_mark_cfqq_fifo_expire(cfqq);
- return crq;
- }
+ if (time_after(jiffies, rq->start_time + cfqd->cfq_fifo_expire[fifo])) {
+ cfq_mark_cfqq_fifo_expire(cfqq);
+ return rq;
}
return NULL;
@@ -1063,25 +883,25 @@ __cfq_dispatch_requests(struct cfq_data *cfqd, struct cfq_queue *cfqq,
BUG_ON(RB_EMPTY_ROOT(&cfqq->sort_list));
do {
- struct cfq_rq *crq;
+ struct request *rq;
/*
* follow expired path, else get first next available
*/
- if ((crq = cfq_check_fifo(cfqq)) == NULL)
- crq = cfqq->next_crq;
+ if ((rq = cfq_check_fifo(cfqq)) == NULL)
+ rq = cfqq->next_rq;
/*
* finally, insert request into driver dispatch list
*/
- cfq_dispatch_insert(cfqd->queue, crq);
+ cfq_dispatch_insert(cfqd->queue, rq);
cfqd->dispatch_slice++;
dispatched++;
if (!cfqd->active_cic) {
- atomic_inc(&crq->io_context->ioc->refcount);
- cfqd->active_cic = crq->io_context;
+ atomic_inc(&RQ_CIC(rq)->ioc->refcount);
+ cfqd->active_cic = RQ_CIC(rq);
}
if (RB_EMPTY_ROOT(&cfqq->sort_list))
@@ -1112,13 +932,12 @@ static int
cfq_forced_dispatch_cfqqs(struct list_head *list)
{
struct cfq_queue *cfqq, *next;
- struct cfq_rq *crq;
int dispatched;
dispatched = 0;
list_for_each_entry_safe(cfqq, next, list, cfq_list) {
- while ((crq = cfqq->next_crq)) {
- cfq_dispatch_insert(cfqq->cfqd->queue, crq);
+ while (cfqq->next_rq) {
+ cfq_dispatch_insert(cfqq->cfqd->queue, cfqq->next_rq);
dispatched++;
}
BUG_ON(!list_empty(&cfqq->fifo));
@@ -1194,8 +1013,8 @@ cfq_dispatch_requests(request_queue_t *q, int force)
}
/*
- * task holds one reference to the queue, dropped when task exits. each crq
- * in-flight on this queue also holds a reference, dropped when crq is freed.
+ * task holds one reference to the queue, dropped when task exits. each rq
+ * in-flight on this queue also holds a reference, dropped when rq is freed.
*
* queue lock must be held here.
*/
@@ -1223,7 +1042,7 @@ static void cfq_put_queue(struct cfq_queue *cfqq)
kmem_cache_free(cfq_pool, cfqq);
}
-static inline struct cfq_queue *
+static struct cfq_queue *
__cfq_find_cfq_hash(struct cfq_data *cfqd, unsigned int key, unsigned int prio,
const int hashval)
{
@@ -1260,62 +1079,63 @@ static void cfq_free_io_context(struct io_context *ioc)
freed++;
}
- if (atomic_sub_and_test(freed, &ioc_count) && ioc_gone)
+ elv_ioc_count_mod(ioc_count, -freed);
+
+ if (ioc_gone && !elv_ioc_count_read(ioc_count))
complete(ioc_gone);
}
-static void cfq_trim(struct io_context *ioc)
+static void cfq_exit_cfqq(struct cfq_data *cfqd, struct cfq_queue *cfqq)
{
- ioc->set_ioprio = NULL;
- cfq_free_io_context(ioc);
+ if (unlikely(cfqq == cfqd->active_queue))
+ __cfq_slice_expired(cfqd, cfqq, 0);
+
+ cfq_put_queue(cfqq);
}
-/*
- * Called with interrupts disabled
- */
-static void cfq_exit_single_io_context(struct cfq_io_context *cic)
+static void __cfq_exit_single_io_context(struct cfq_data *cfqd,
+ struct cfq_io_context *cic)
{
- struct cfq_data *cfqd = cic->key;
- request_queue_t *q;
-
- if (!cfqd)
- return;
-
- q = cfqd->queue;
-
- WARN_ON(!irqs_disabled());
-
- spin_lock(q->queue_lock);
+ list_del_init(&cic->queue_list);
+ smp_wmb();
+ cic->key = NULL;
if (cic->cfqq[ASYNC]) {
- if (unlikely(cic->cfqq[ASYNC] == cfqd->active_queue))
- __cfq_slice_expired(cfqd, cic->cfqq[ASYNC], 0);
- cfq_put_queue(cic->cfqq[ASYNC]);
+ cfq_exit_cfqq(cfqd, cic->cfqq[ASYNC]);
cic->cfqq[ASYNC] = NULL;
}
if (cic->cfqq[SYNC]) {
- if (unlikely(cic->cfqq[SYNC] == cfqd->active_queue))
- __cfq_slice_expired(cfqd, cic->cfqq[SYNC], 0);
- cfq_put_queue(cic->cfqq[SYNC]);
+ cfq_exit_cfqq(cfqd, cic->cfqq[SYNC]);
cic->cfqq[SYNC] = NULL;
}
+}
- cic->key = NULL;
- list_del_init(&cic->queue_list);
- spin_unlock(q->queue_lock);
+
+/*
+ * Called with interrupts disabled
+ */
+static void cfq_exit_single_io_context(struct cfq_io_context *cic)
+{
+ struct cfq_data *cfqd = cic->key;
+
+ if (cfqd) {
+ request_queue_t *q = cfqd->queue;
+
+ spin_lock_irq(q->queue_lock);
+ __cfq_exit_single_io_context(cfqd, cic);
+ spin_unlock_irq(q->queue_lock);
+ }
}
static void cfq_exit_io_context(struct io_context *ioc)
{
struct cfq_io_context *__cic;
- unsigned long flags;
struct rb_node *n;
/*
* put the reference this task is holding to the various queues
*/
- spin_lock_irqsave(&cfq_exit_lock, flags);
n = rb_first(&ioc->cic_root);
while (n != NULL) {
@@ -1324,22 +1144,21 @@ static void cfq_exit_io_context(struct io_context *ioc)
cfq_exit_single_io_context(__cic);
n = rb_next(n);
}
-
- spin_unlock_irqrestore(&cfq_exit_lock, flags);
}
static struct cfq_io_context *
cfq_alloc_io_context(struct cfq_data *cfqd, gfp_t gfp_mask)
{
- struct cfq_io_context *cic = kmem_cache_alloc(cfq_ioc_pool, gfp_mask);
+ struct cfq_io_context *cic;
+ cic = kmem_cache_alloc_node(cfq_ioc_pool, gfp_mask, cfqd->queue->node);
if (cic) {
memset(cic, 0, sizeof(*cic));
cic->last_end_request = jiffies;
INIT_LIST_HEAD(&cic->queue_list);
cic->dtor = cfq_free_io_context;
cic->exit = cfq_exit_io_context;
- atomic_inc(&ioc_count);
+ elv_ioc_count_inc(ioc_count);
}
return cic;
@@ -1420,15 +1239,12 @@ static inline void changed_ioprio(struct cfq_io_context *cic)
spin_unlock(cfqd->queue->queue_lock);
}
-/*
- * callback from sys_ioprio_set, irqs are disabled
- */
-static int cfq_ioc_set_ioprio(struct io_context *ioc, unsigned int ioprio)
+static void cfq_ioc_set_ioprio(struct io_context *ioc)
{
struct cfq_io_context *cic;
struct rb_node *n;
- spin_lock(&cfq_exit_lock);
+ ioc->ioprio_changed = 0;
n = rb_first(&ioc->cic_root);
while (n != NULL) {
@@ -1437,10 +1253,6 @@ static int cfq_ioc_set_ioprio(struct io_context *ioc, unsigned int ioprio)
changed_ioprio(cic);
n = rb_next(n);
}
-
- spin_unlock(&cfq_exit_lock);
-
- return 0;
}
static struct cfq_queue *
@@ -1460,12 +1272,18 @@ retry:
cfqq = new_cfqq;
new_cfqq = NULL;
} else if (gfp_mask & __GFP_WAIT) {
+ /*
+ * Inform the allocator of the fact that we will
+ * just repeat this allocation if it fails, to allow
+ * the allocator to do whatever it needs to attempt to
+ * free memory.
+ */
spin_unlock_irq(cfqd->queue->queue_lock);
- new_cfqq = kmem_cache_alloc(cfq_pool, gfp_mask);
+ new_cfqq = kmem_cache_alloc_node(cfq_pool, gfp_mask|__GFP_NOFAIL, cfqd->queue->node);
spin_lock_irq(cfqd->queue->queue_lock);
goto retry;
} else {
- cfqq = kmem_cache_alloc(cfq_pool, gfp_mask);
+ cfqq = kmem_cache_alloc_node(cfq_pool, gfp_mask, cfqd->queue->node);
if (!cfqq)
goto out;
}
@@ -1480,13 +1298,13 @@ retry:
hlist_add_head(&cfqq->cfq_hash, &cfqd->cfq_hash[hashval]);
atomic_set(&cfqq->ref, 0);
cfqq->cfqd = cfqd;
- cfqq->service_last = 0;
/*
* set ->slice_left to allow preemption for a new process
*/
cfqq->slice_left = 2 * cfqd->cfq_slice_idle;
cfq_mark_cfqq_idle_window(cfqq);
cfq_mark_cfqq_prio_changed(cfqq);
+ cfq_mark_cfqq_queue_new(cfqq);
cfq_init_prio_data(cfqq);
}
@@ -1502,12 +1320,10 @@ out:
static void
cfq_drop_dead_cic(struct io_context *ioc, struct cfq_io_context *cic)
{
- spin_lock(&cfq_exit_lock);
+ WARN_ON(!list_empty(&cic->queue_list));
rb_erase(&cic->rb_node, &ioc->cic_root);
- list_del_init(&cic->queue_list);
- spin_unlock(&cfq_exit_lock);
kmem_cache_free(cfq_ioc_pool, cic);
- atomic_dec(&ioc_count);
+ elv_ioc_count_dec(ioc_count);
}
static struct cfq_io_context *
@@ -1551,7 +1367,6 @@ cfq_cic_link(struct cfq_data *cfqd, struct io_context *ioc,
cic->ioc = ioc;
cic->key = cfqd;
- ioc->set_ioprio = cfq_ioc_set_ioprio;
restart:
parent = NULL;
p = &ioc->cic_root.rb_node;
@@ -1573,11 +1388,12 @@ restart:
BUG();
}
- spin_lock(&cfq_exit_lock);
rb_link_node(&cic->rb_node, parent, p);
rb_insert_color(&cic->rb_node, &ioc->cic_root);
+
+ spin_lock_irq(cfqd->queue->queue_lock);
list_add(&cic->queue_list, &cfqd->cic_list);
- spin_unlock(&cfq_exit_lock);
+ spin_unlock_irq(cfqd->queue->queue_lock);
}
/*
@@ -1593,7 +1409,7 @@ cfq_get_io_context(struct cfq_data *cfqd, gfp_t gfp_mask)
might_sleep_if(gfp_mask & __GFP_WAIT);
- ioc = get_io_context(gfp_mask);
+ ioc = get_io_context(gfp_mask, cfqd->queue->node);
if (!ioc)
return NULL;
@@ -1607,6 +1423,10 @@ cfq_get_io_context(struct cfq_data *cfqd, gfp_t gfp_mask)
cfq_cic_link(cfqd, ioc, cic);
out:
+ smp_read_barrier_depends();
+ if (unlikely(ioc->ioprio_changed))
+ cfq_ioc_set_ioprio(ioc);
+
return cic;
err:
put_io_context(ioc);
@@ -1640,15 +1460,15 @@ cfq_update_io_thinktime(struct cfq_data *cfqd, struct cfq_io_context *cic)
static void
cfq_update_io_seektime(struct cfq_data *cfqd, struct cfq_io_context *cic,
- struct cfq_rq *crq)
+ struct request *rq)
{
sector_t sdist;
u64 total;
- if (cic->last_request_pos < crq->request->sector)
- sdist = crq->request->sector - cic->last_request_pos;
+ if (cic->last_request_pos < rq->sector)
+ sdist = rq->sector - cic->last_request_pos;
else
- sdist = cic->last_request_pos - crq->request->sector;
+ sdist = cic->last_request_pos - rq->sector;
/*
* Don't allow the seek distance to get too large from the
@@ -1699,7 +1519,7 @@ cfq_update_idle_window(struct cfq_data *cfqd, struct cfq_queue *cfqq,
*/
static int
cfq_should_preempt(struct cfq_data *cfqd, struct cfq_queue *new_cfqq,
- struct cfq_rq *crq)
+ struct request *rq)
{
struct cfq_queue *cfqq = cfqd->active_queue;
@@ -1718,7 +1538,17 @@ cfq_should_preempt(struct cfq_data *cfqd, struct cfq_queue *new_cfqq,
*/
if (new_cfqq->slice_left < cfqd->cfq_slice_idle)
return 0;
- if (cfq_crq_is_sync(crq) && !cfq_cfqq_sync(cfqq))
+ /*
+ * if the new request is sync, but the currently running queue is
+ * not, let the sync request have priority.
+ */
+ if (rq_is_sync(rq) && !cfq_cfqq_sync(cfqq))
+ return 1;
+ /*
+ * So both queues are sync. Let the new request get disk time if
+ * it's a metadata request and the current queue is doing regular IO.
+ */
+ if (rq_is_meta(rq) && !cfqq->meta_pending)
return 1;
return 0;
@@ -1730,47 +1560,45 @@ cfq_should_preempt(struct cfq_data *cfqd, struct cfq_queue *new_cfqq,
*/
static void cfq_preempt_queue(struct cfq_data *cfqd, struct cfq_queue *cfqq)
{
- struct cfq_queue *__cfqq, *next;
-
- list_for_each_entry_safe(__cfqq, next, &cfqd->cur_rr, cfq_list)
- cfq_resort_rr_list(__cfqq, 1);
+ cfq_slice_expired(cfqd, 1);
if (!cfqq->slice_left)
cfqq->slice_left = cfq_prio_to_slice(cfqd, cfqq) / 2;
- cfqq->slice_end = cfqq->slice_left + jiffies;
- cfq_slice_expired(cfqd, 1);
- __cfq_set_active_queue(cfqd, cfqq);
-}
-
-/*
- * should really be a ll_rw_blk.c helper
- */
-static void cfq_start_queueing(struct cfq_data *cfqd, struct cfq_queue *cfqq)
-{
- request_queue_t *q = cfqd->queue;
+ /*
+ * Put the new queue at the front of the of the current list,
+ * so we know that it will be selected next.
+ */
+ BUG_ON(!cfq_cfqq_on_rr(cfqq));
+ list_move(&cfqq->cfq_list, &cfqd->cur_rr);
- if (!blk_queue_plugged(q))
- q->request_fn(q);
- else
- __generic_unplug_device(q);
+ cfqq->slice_end = cfqq->slice_left + jiffies;
}
/*
- * Called when a new fs request (crq) is added (to cfqq). Check if there's
+ * Called when a new fs request (rq) is added (to cfqq). Check if there's
* something we should do about it
*/
static void
-cfq_crq_enqueued(struct cfq_data *cfqd, struct cfq_queue *cfqq,
- struct cfq_rq *crq)
+cfq_rq_enqueued(struct cfq_data *cfqd, struct cfq_queue *cfqq,
+ struct request *rq)
{
- struct cfq_io_context *cic = crq->io_context;
+ struct cfq_io_context *cic = RQ_CIC(rq);
+
+ if (rq_is_meta(rq))
+ cfqq->meta_pending++;
+
+ /*
+ * check if this request is a better next-serve candidate)) {
+ */
+ cfqq->next_rq = cfq_choose_req(cfqd, cfqq->next_rq, rq);
+ BUG_ON(!cfqq->next_rq);
/*
* we never wait for an async request and we don't allow preemption
* of an async request. so just return early
*/
- if (!cfq_crq_is_sync(crq)) {
+ if (!rq_is_sync(rq)) {
/*
* sync process issued an async request, if it's waiting
* then expire it and kick rq handling.
@@ -1778,17 +1606,17 @@ cfq_crq_enqueued(struct cfq_data *cfqd, struct cfq_queue *cfqq,
if (cic == cfqd->active_cic &&
del_timer(&cfqd->idle_slice_timer)) {
cfq_slice_expired(cfqd, 0);
- cfq_start_queueing(cfqd, cfqq);
+ blk_start_queueing(cfqd->queue);
}
return;
}
cfq_update_io_thinktime(cfqd, cic);
- cfq_update_io_seektime(cfqd, cic, crq);
+ cfq_update_io_seektime(cfqd, cic, rq);
cfq_update_idle_window(cfqd, cfqq, cic);
cic->last_queue = jiffies;
- cic->last_request_pos = crq->request->sector + crq->request->nr_sectors;
+ cic->last_request_pos = rq->sector + rq->nr_sectors;
if (cfqq == cfqd->active_queue) {
/*
@@ -1799,9 +1627,9 @@ cfq_crq_enqueued(struct cfq_data *cfqd, struct cfq_queue *cfqq,
if (cfq_cfqq_wait_request(cfqq)) {
cfq_mark_cfqq_must_dispatch(cfqq);
del_timer(&cfqd->idle_slice_timer);
- cfq_start_queueing(cfqd, cfqq);
+ blk_start_queueing(cfqd->queue);
}
- } else if (cfq_should_preempt(cfqd, cfqq, crq)) {
+ } else if (cfq_should_preempt(cfqd, cfqq, rq)) {
/*
* not the active queue - expire current slice if it is
* idle and has expired it's mean thinktime or this new queue
@@ -1809,34 +1637,32 @@ cfq_crq_enqueued(struct cfq_data *cfqd, struct cfq_queue *cfqq,
*/
cfq_preempt_queue(cfqd, cfqq);
cfq_mark_cfqq_must_dispatch(cfqq);
- cfq_start_queueing(cfqd, cfqq);
+ blk_start_queueing(cfqd->queue);
}
}
static void cfq_insert_request(request_queue_t *q, struct request *rq)
{
struct cfq_data *cfqd = q->elevator->elevator_data;
- struct cfq_rq *crq = RQ_DATA(rq);
- struct cfq_queue *cfqq = crq->cfq_queue;
+ struct cfq_queue *cfqq = RQ_CFQQ(rq);
cfq_init_prio_data(cfqq);
- cfq_add_crq_rb(crq);
+ cfq_add_rq_rb(rq);
- list_add_tail(&rq->queuelist, &cfqq->fifo);
+ if (!cfq_cfqq_on_rr(cfqq))
+ cfq_add_cfqq_rr(cfqd, cfqq);
- if (rq_mergeable(rq))
- cfq_add_crq_hash(cfqd, crq);
+ list_add_tail(&rq->queuelist, &cfqq->fifo);
- cfq_crq_enqueued(cfqd, cfqq, crq);
+ cfq_rq_enqueued(cfqd, cfqq, rq);
}
static void cfq_completed_request(request_queue_t *q, struct request *rq)
{
- struct cfq_rq *crq = RQ_DATA(rq);
- struct cfq_queue *cfqq = crq->cfq_queue;
+ struct cfq_queue *cfqq = RQ_CFQQ(rq);
struct cfq_data *cfqd = cfqq->cfqd;
- const int sync = cfq_crq_is_sync(crq);
+ const int sync = rq_is_sync(rq);
unsigned long now;
now = jiffies;
@@ -1849,15 +1675,11 @@ static void cfq_completed_request(request_queue_t *q, struct request *rq)
if (!cfq_class_idle(cfqq))
cfqd->last_end_request = now;
- if (!cfq_cfqq_dispatched(cfqq)) {
- if (cfq_cfqq_on_rr(cfqq)) {
- cfqq->service_last = now;
- cfq_resort_rr_list(cfqq, 0);
- }
- }
+ if (!cfq_cfqq_dispatched(cfqq) && cfq_cfqq_on_rr(cfqq))
+ cfq_resort_rr_list(cfqq, 0);
if (sync)
- crq->io_context->last_end_request = now;
+ RQ_CIC(rq)->last_end_request = now;
/*
* If this is the active queue, check if it needs to be expired,
@@ -1873,30 +1695,6 @@ static void cfq_completed_request(request_queue_t *q, struct request *rq)
}
}
-static struct request *
-cfq_former_request(request_queue_t *q, struct request *rq)
-{
- struct cfq_rq *crq = RQ_DATA(rq);
- struct rb_node *rbprev = rb_prev(&crq->rb_node);
-
- if (rbprev)
- return rb_entry_crq(rbprev)->request;
-
- return NULL;
-}
-
-static struct request *
-cfq_latter_request(request_queue_t *q, struct request *rq)
-{
- struct cfq_rq *crq = RQ_DATA(rq);
- struct rb_node *rbnext = rb_next(&crq->rb_node);
-
- if (rbnext)
- return rb_entry_crq(rbnext)->request;
-
- return NULL;
-}
-
/*
* we temporarily boost lower priority queues if they are holding fs exclusive
* resources. they are boosted to normal prio (CLASS_BE/4)
@@ -1933,9 +1731,7 @@ static void cfq_prio_boost(struct cfq_queue *cfqq)
cfq_resort_rr_list(cfqq, 0);
}
-static inline int
-__cfq_may_queue(struct cfq_data *cfqd, struct cfq_queue *cfqq,
- struct task_struct *task, int rw)
+static inline int __cfq_may_queue(struct cfq_queue *cfqq)
{
if ((cfq_cfqq_wait_request(cfqq) || cfq_cfqq_must_alloc(cfqq)) &&
!cfq_cfqq_must_alloc_slice(cfqq)) {
@@ -1946,7 +1742,7 @@ __cfq_may_queue(struct cfq_data *cfqd, struct cfq_queue *cfqq,
return ELV_MQUEUE_MAY;
}
-static int cfq_may_queue(request_queue_t *q, int rw, struct bio *bio)
+static int cfq_may_queue(request_queue_t *q, int rw)
{
struct cfq_data *cfqd = q->elevator->elevator_data;
struct task_struct *tsk = current;
@@ -1963,48 +1759,30 @@ static int cfq_may_queue(request_queue_t *q, int rw, struct bio *bio)
cfq_init_prio_data(cfqq);
cfq_prio_boost(cfqq);
- return __cfq_may_queue(cfqd, cfqq, tsk, rw);
+ return __cfq_may_queue(cfqq);
}
return ELV_MQUEUE_MAY;
}
-static void cfq_check_waiters(request_queue_t *q, struct cfq_queue *cfqq)
-{
- struct cfq_data *cfqd = q->elevator->elevator_data;
-
- if (unlikely(cfqd->rq_starved)) {
- struct request_list *rl = &q->rq;
-
- smp_mb();
- if (waitqueue_active(&rl->wait[READ]))
- wake_up(&rl->wait[READ]);
- if (waitqueue_active(&rl->wait[WRITE]))
- wake_up(&rl->wait[WRITE]);
- }
-}
-
/*
* queue lock held here
*/
static void cfq_put_request(request_queue_t *q, struct request *rq)
{
- struct cfq_data *cfqd = q->elevator->elevator_data;
- struct cfq_rq *crq = RQ_DATA(rq);
+ struct cfq_queue *cfqq = RQ_CFQQ(rq);
- if (crq) {
- struct cfq_queue *cfqq = crq->cfq_queue;
+ if (cfqq) {
const int rw = rq_data_dir(rq);
BUG_ON(!cfqq->allocated[rw]);
cfqq->allocated[rw]--;
- put_io_context(crq->io_context->ioc);
+ put_io_context(RQ_CIC(rq)->ioc);
- mempool_free(crq, cfqd->crq_pool);
rq->elevator_private = NULL;
+ rq->elevator_private2 = NULL;
- cfq_check_waiters(q, cfqq);
cfq_put_queue(cfqq);
}
}
@@ -2013,8 +1791,7 @@ static void cfq_put_request(request_queue_t *q, struct request *rq)
* Allocate cfq data structures associated with this request.
*/
static int
-cfq_set_request(request_queue_t *q, struct request *rq, struct bio *bio,
- gfp_t gfp_mask)
+cfq_set_request(request_queue_t *q, struct request *rq, gfp_t gfp_mask)
{
struct cfq_data *cfqd = q->elevator->elevator_data;
struct task_struct *tsk = current;
@@ -2022,7 +1799,6 @@ cfq_set_request(request_queue_t *q, struct request *rq, struct bio *bio,
const int rw = rq_data_dir(rq);
pid_t key = cfq_queue_pid(tsk, rw);
struct cfq_queue *cfqq;
- struct cfq_rq *crq;
unsigned long flags;
int is_sync = key != CFQ_KEY_ASYNC;
@@ -2046,42 +1822,18 @@ cfq_set_request(request_queue_t *q, struct request *rq, struct bio *bio,
cfqq->allocated[rw]++;
cfq_clear_cfqq_must_alloc(cfqq);
- cfqd->rq_starved = 0;
atomic_inc(&cfqq->ref);
- spin_unlock_irqrestore(q->queue_lock, flags);
- crq = mempool_alloc(cfqd->crq_pool, gfp_mask);
- if (crq) {
- RB_CLEAR_NODE(&crq->rb_node);
- crq->rb_key = 0;
- crq->request = rq;
- INIT_HLIST_NODE(&crq->hash);
- crq->cfq_queue = cfqq;
- crq->io_context = cic;
-
- if (is_sync)
- cfq_mark_crq_is_sync(crq);
- else
- cfq_clear_crq_is_sync(crq);
+ spin_unlock_irqrestore(q->queue_lock, flags);
- rq->elevator_private = crq;
- return 0;
- }
+ rq->elevator_private = cic;
+ rq->elevator_private2 = cfqq;
+ return 0;
- spin_lock_irqsave(q->queue_lock, flags);
- cfqq->allocated[rw]--;
- if (!(cfqq->allocated[0] + cfqq->allocated[1]))
- cfq_mark_cfqq_must_alloc(cfqq);
- cfq_put_queue(cfqq);
queue_fail:
if (cic)
put_io_context(cic->ioc);
- /*
- * mark us rq allocation starved. we need to kickstart the process
- * ourselves if there are no pending requests that can do it for us.
- * that would be an extremely rare OOM situation
- */
- cfqd->rq_starved = 1;
+
cfq_schedule_dispatch(cfqd);
spin_unlock_irqrestore(q->queue_lock, flags);
return 1;
@@ -2090,27 +1842,10 @@ queue_fail:
static void cfq_kick_queue(void *data)
{
request_queue_t *q = data;
- struct cfq_data *cfqd = q->elevator->elevator_data;
unsigned long flags;
spin_lock_irqsave(q->queue_lock, flags);
-
- if (cfqd->rq_starved) {
- struct request_list *rl = &q->rq;
-
- /*
- * we aren't guaranteed to get a request after this, but we
- * have to be opportunistic
- */
- smp_mb();
- if (waitqueue_active(&rl->wait[READ]))
- wake_up(&rl->wait[READ]);
- if (waitqueue_active(&rl->wait[WRITE]))
- wake_up(&rl->wait[WRITE]);
- }
-
- blk_remove_plug(q);
- q->request_fn(q);
+ blk_start_queueing(q);
spin_unlock_irqrestore(q->queue_lock, flags);
}
@@ -2193,7 +1928,6 @@ static void cfq_exit_queue(elevator_t *e)
cfq_shutdown_timer_wq(cfqd);
- spin_lock(&cfq_exit_lock);
spin_lock_irq(q->queue_lock);
if (cfqd->active_queue)
@@ -2203,25 +1937,14 @@ static void cfq_exit_queue(elevator_t *e)
struct cfq_io_context *cic = list_entry(cfqd->cic_list.next,
struct cfq_io_context,
queue_list);
- if (cic->cfqq[ASYNC]) {
- cfq_put_queue(cic->cfqq[ASYNC]);
- cic->cfqq[ASYNC] = NULL;
- }
- if (cic->cfqq[SYNC]) {
- cfq_put_queue(cic->cfqq[SYNC]);
- cic->cfqq[SYNC] = NULL;
- }
- cic->key = NULL;
- list_del_init(&cic->queue_list);
+
+ __cfq_exit_single_io_context(cfqd, cic);
}
spin_unlock_irq(q->queue_lock);
- spin_unlock(&cfq_exit_lock);
cfq_shutdown_timer_wq(cfqd);
- mempool_destroy(cfqd->crq_pool);
- kfree(cfqd->crq_hash);
kfree(cfqd->cfq_hash);
kfree(cfqd);
}
@@ -2231,7 +1954,7 @@ static void *cfq_init_queue(request_queue_t *q, elevator_t *e)
struct cfq_data *cfqd;
int i;
- cfqd = kmalloc(sizeof(*cfqd), GFP_KERNEL);
+ cfqd = kmalloc_node(sizeof(*cfqd), GFP_KERNEL, q->node);
if (!cfqd)
return NULL;
@@ -2243,23 +1966,12 @@ static void *cfq_init_queue(request_queue_t *q, elevator_t *e)
INIT_LIST_HEAD(&cfqd->busy_rr);
INIT_LIST_HEAD(&cfqd->cur_rr);
INIT_LIST_HEAD(&cfqd->idle_rr);
- INIT_LIST_HEAD(&cfqd->empty_list);
INIT_LIST_HEAD(&cfqd->cic_list);
- cfqd->crq_hash = kmalloc(sizeof(struct hlist_head) * CFQ_MHASH_ENTRIES, GFP_KERNEL);
- if (!cfqd->crq_hash)
- goto out_crqhash;
-
- cfqd->cfq_hash = kmalloc(sizeof(struct hlist_head) * CFQ_QHASH_ENTRIES, GFP_KERNEL);
+ cfqd->cfq_hash = kmalloc_node(sizeof(struct hlist_head) * CFQ_QHASH_ENTRIES, GFP_KERNEL, q->node);
if (!cfqd->cfq_hash)
- goto out_cfqhash;
-
- cfqd->crq_pool = mempool_create_slab_pool(BLKDEV_MIN_RQ, crq_pool);
- if (!cfqd->crq_pool)
- goto out_crqpool;
+ goto out_free;
- for (i = 0; i < CFQ_MHASH_ENTRIES; i++)
- INIT_HLIST_HEAD(&cfqd->crq_hash[i]);
for (i = 0; i < CFQ_QHASH_ENTRIES; i++)
INIT_HLIST_HEAD(&cfqd->cfq_hash[i]);
@@ -2275,7 +1987,6 @@ static void *cfq_init_queue(request_queue_t *q, elevator_t *e)
INIT_WORK(&cfqd->unplug_work, cfq_kick_queue, q);
- cfqd->cfq_queued = cfq_queued;
cfqd->cfq_quantum = cfq_quantum;
cfqd->cfq_fifo_expire[0] = cfq_fifo_expire[0];
cfqd->cfq_fifo_expire[1] = cfq_fifo_expire[1];
@@ -2287,19 +1998,13 @@ static void *cfq_init_queue(request_queue_t *q, elevator_t *e)
cfqd->cfq_slice_idle = cfq_slice_idle;
return cfqd;
-out_crqpool:
- kfree(cfqd->cfq_hash);
-out_cfqhash:
- kfree(cfqd->crq_hash);
-out_crqhash:
+out_free:
kfree(cfqd);
return NULL;
}
static void cfq_slab_kill(void)
{
- if (crq_pool)
- kmem_cache_destroy(crq_pool);
if (cfq_pool)
kmem_cache_destroy(cfq_pool);
if (cfq_ioc_pool)
@@ -2308,11 +2013,6 @@ static void cfq_slab_kill(void)
static int __init cfq_slab_setup(void)
{
- crq_pool = kmem_cache_create("crq_pool", sizeof(struct cfq_rq), 0, 0,
- NULL, NULL);
- if (!crq_pool)
- goto fail;
-
cfq_pool = kmem_cache_create("cfq_pool", sizeof(struct cfq_queue), 0, 0,
NULL, NULL);
if (!cfq_pool)
@@ -2358,7 +2058,6 @@ static ssize_t __FUNC(elevator_t *e, char *page) \
return cfq_var_show(__data, (page)); \
}
SHOW_FUNCTION(cfq_quantum_show, cfqd->cfq_quantum, 0);
-SHOW_FUNCTION(cfq_queued_show, cfqd->cfq_queued, 0);
SHOW_FUNCTION(cfq_fifo_expire_sync_show, cfqd->cfq_fifo_expire[1], 1);
SHOW_FUNCTION(cfq_fifo_expire_async_show, cfqd->cfq_fifo_expire[0], 1);
SHOW_FUNCTION(cfq_back_seek_max_show, cfqd->cfq_back_max, 0);
@@ -2386,7 +2085,6 @@ static ssize_t __FUNC(elevator_t *e, const char *page, size_t count) \
return ret; \
}
STORE_FUNCTION(cfq_quantum_store, &cfqd->cfq_quantum, 1, UINT_MAX, 0);
-STORE_FUNCTION(cfq_queued_store, &cfqd->cfq_queued, 1, UINT_MAX, 0);
STORE_FUNCTION(cfq_fifo_expire_sync_store, &cfqd->cfq_fifo_expire[1], 1, UINT_MAX, 1);
STORE_FUNCTION(cfq_fifo_expire_async_store, &cfqd->cfq_fifo_expire[0], 1, UINT_MAX, 1);
STORE_FUNCTION(cfq_back_seek_max_store, &cfqd->cfq_back_max, 0, UINT_MAX, 0);
@@ -2402,7 +2100,6 @@ STORE_FUNCTION(cfq_slice_async_rq_store, &cfqd->cfq_slice_async_rq, 1, UINT_MAX,
static struct elv_fs_entry cfq_attrs[] = {
CFQ_ATTR(quantum),
- CFQ_ATTR(queued),
CFQ_ATTR(fifo_expire_sync),
CFQ_ATTR(fifo_expire_async),
CFQ_ATTR(back_seek_max),
@@ -2425,14 +2122,14 @@ static struct elevator_type iosched_cfq = {
.elevator_deactivate_req_fn = cfq_deactivate_request,
.elevator_queue_empty_fn = cfq_queue_empty,
.elevator_completed_req_fn = cfq_completed_request,
- .elevator_former_req_fn = cfq_former_request,
- .elevator_latter_req_fn = cfq_latter_request,
+ .elevator_former_req_fn = elv_rb_former_request,
+ .elevator_latter_req_fn = elv_rb_latter_request,
.elevator_set_req_fn = cfq_set_request,
.elevator_put_req_fn = cfq_put_request,
.elevator_may_queue_fn = cfq_may_queue,
.elevator_init_fn = cfq_init_queue,
.elevator_exit_fn = cfq_exit_queue,
- .trim = cfq_trim,
+ .trim = cfq_free_io_context,
},
.elevator_attrs = cfq_attrs,
.elevator_name = "cfq",
@@ -2463,12 +2160,12 @@ static int __init cfq_init(void)
static void __exit cfq_exit(void)
{
- DECLARE_COMPLETION(all_gone);
+ DECLARE_COMPLETION_ONSTACK(all_gone);
elv_unregister(&iosched_cfq);
ioc_gone = &all_gone;
/* ioc_gone's update must be visible before reading ioc_count */
smp_wmb();
- if (atomic_read(&ioc_count))
+ if (elv_ioc_count_read(ioc_count))
wait_for_completion(ioc_gone);
synchronize_rcu();
cfq_slab_kill();
diff --git a/block/deadline-iosched.c b/block/deadline-iosched.c
index c7ca9f0b6498..b7c5b34cb7b4 100644
--- a/block/deadline-iosched.c
+++ b/block/deadline-iosched.c
@@ -1,7 +1,7 @@
/*
* Deadline i/o scheduler.
*
- * Copyright (C) 2002 Jens Axboe <axboe@suse.de>
+ * Copyright (C) 2002 Jens Axboe <axboe@kernel.dk>
*/
#include <linux/kernel.h>
#include <linux/fs.h>
@@ -12,7 +12,6 @@
#include <linux/slab.h>
#include <linux/init.h>
#include <linux/compiler.h>
-#include <linux/hash.h>
#include <linux/rbtree.h>
/*
@@ -24,13 +23,6 @@ static const int writes_starved = 2; /* max times reads can starve a write */
static const int fifo_batch = 16; /* # of sequential requests treated as one
by the above parameters. For throughput. */
-static const int deadline_hash_shift = 5;
-#define DL_HASH_BLOCK(sec) ((sec) >> 3)
-#define DL_HASH_FN(sec) (hash_long(DL_HASH_BLOCK((sec)), deadline_hash_shift))
-#define DL_HASH_ENTRIES (1 << deadline_hash_shift)
-#define rq_hash_key(rq) ((rq)->sector + (rq)->nr_sectors)
-#define ON_HASH(drq) (!hlist_unhashed(&(drq)->hash))
-
struct deadline_data {
/*
* run time data
@@ -45,8 +37,7 @@ struct deadline_data {
/*
* next in sort order. read, write or both are NULL
*/
- struct deadline_rq *next_drq[2];
- struct hlist_head *hash; /* request hash */
+ struct request *next_rq[2];
unsigned int batching; /* number of sequential requests made */
sector_t last_sector; /* head position */
unsigned int starved; /* times reads have starved writes */
@@ -58,240 +49,69 @@ struct deadline_data {
int fifo_batch;
int writes_starved;
int front_merges;
-
- mempool_t *drq_pool;
};
-/*
- * pre-request data.
- */
-struct deadline_rq {
- /*
- * rbtree index, key is the starting offset
- */
- struct rb_node rb_node;
- sector_t rb_key;
-
- struct request *request;
-
- /*
- * request hash, key is the ending offset (for back merge lookup)
- */
- struct hlist_node hash;
-
- /*
- * expire fifo
- */
- struct list_head fifo;
- unsigned long expires;
-};
-
-static void deadline_move_request(struct deadline_data *dd, struct deadline_rq *drq);
-
-static kmem_cache_t *drq_pool;
-
-#define RQ_DATA(rq) ((struct deadline_rq *) (rq)->elevator_private)
+static void deadline_move_request(struct deadline_data *, struct request *);
-/*
- * the back merge hash support functions
- */
-static inline void __deadline_del_drq_hash(struct deadline_rq *drq)
-{
- hlist_del_init(&drq->hash);
-}
-
-static inline void deadline_del_drq_hash(struct deadline_rq *drq)
-{
- if (ON_HASH(drq))
- __deadline_del_drq_hash(drq);
-}
-
-static inline void
-deadline_add_drq_hash(struct deadline_data *dd, struct deadline_rq *drq)
-{
- struct request *rq = drq->request;
-
- BUG_ON(ON_HASH(drq));
-
- hlist_add_head(&drq->hash, &dd->hash[DL_HASH_FN(rq_hash_key(rq))]);
-}
-
-/*
- * move hot entry to front of chain
- */
-static inline void
-deadline_hot_drq_hash(struct deadline_data *dd, struct deadline_rq *drq)
-{
- struct request *rq = drq->request;
- struct hlist_head *head = &dd->hash[DL_HASH_FN(rq_hash_key(rq))];
-
- if (ON_HASH(drq) && &drq->hash != head->first) {
- hlist_del(&drq->hash);
- hlist_add_head(&drq->hash, head);
- }
-}
-
-static struct request *
-deadline_find_drq_hash(struct deadline_data *dd, sector_t offset)
-{
- struct hlist_head *hash_list = &dd->hash[DL_HASH_FN(offset)];
- struct hlist_node *entry, *next;
- struct deadline_rq *drq;
-
- hlist_for_each_entry_safe(drq, entry, next, hash_list, hash) {
- struct request *__rq = drq->request;
-
- BUG_ON(!ON_HASH(drq));
-
- if (!rq_mergeable(__rq)) {
- __deadline_del_drq_hash(drq);
- continue;
- }
-
- if (rq_hash_key(__rq) == offset)
- return __rq;
- }
-
- return NULL;
-}
-
-/*
- * rb tree support functions
- */
-#define rb_entry_drq(node) rb_entry((node), struct deadline_rq, rb_node)
-#define DRQ_RB_ROOT(dd, drq) (&(dd)->sort_list[rq_data_dir((drq)->request)])
-#define rq_rb_key(rq) (rq)->sector
-
-static struct deadline_rq *
-__deadline_add_drq_rb(struct deadline_data *dd, struct deadline_rq *drq)
-{
- struct rb_node **p = &DRQ_RB_ROOT(dd, drq)->rb_node;
- struct rb_node *parent = NULL;
- struct deadline_rq *__drq;
-
- while (*p) {
- parent = *p;
- __drq = rb_entry_drq(parent);
-
- if (drq->rb_key < __drq->rb_key)
- p = &(*p)->rb_left;
- else if (drq->rb_key > __drq->rb_key)
- p = &(*p)->rb_right;
- else
- return __drq;
- }
-
- rb_link_node(&drq->rb_node, parent, p);
- return NULL;
-}
+#define RQ_RB_ROOT(dd, rq) (&(dd)->sort_list[rq_data_dir((rq))])
static void
-deadline_add_drq_rb(struct deadline_data *dd, struct deadline_rq *drq)
+deadline_add_rq_rb(struct deadline_data *dd, struct request *rq)
{
- struct deadline_rq *__alias;
-
- drq->rb_key = rq_rb_key(drq->request);
+ struct rb_root *root = RQ_RB_ROOT(dd, rq);
+ struct request *__alias;
retry:
- __alias = __deadline_add_drq_rb(dd, drq);
- if (!__alias) {
- rb_insert_color(&drq->rb_node, DRQ_RB_ROOT(dd, drq));
- return;
+ __alias = elv_rb_add(root, rq);
+ if (unlikely(__alias)) {
+ deadline_move_request(dd, __alias);
+ goto retry;
}
-
- deadline_move_request(dd, __alias);
- goto retry;
}
static inline void
-deadline_del_drq_rb(struct deadline_data *dd, struct deadline_rq *drq)
+deadline_del_rq_rb(struct deadline_data *dd, struct request *rq)
{
- const int data_dir = rq_data_dir(drq->request);
+ const int data_dir = rq_data_dir(rq);
- if (dd->next_drq[data_dir] == drq) {
- struct rb_node *rbnext = rb_next(&drq->rb_node);
+ if (dd->next_rq[data_dir] == rq) {
+ struct rb_node *rbnext = rb_next(&rq->rb_node);
- dd->next_drq[data_dir] = NULL;
+ dd->next_rq[data_dir] = NULL;
if (rbnext)
- dd->next_drq[data_dir] = rb_entry_drq(rbnext);
- }
-
- BUG_ON(!RB_EMPTY_NODE(&drq->rb_node));
- rb_erase(&drq->rb_node, DRQ_RB_ROOT(dd, drq));
- RB_CLEAR_NODE(&drq->rb_node);
-}
-
-static struct request *
-deadline_find_drq_rb(struct deadline_data *dd, sector_t sector, int data_dir)
-{
- struct rb_node *n = dd->sort_list[data_dir].rb_node;
- struct deadline_rq *drq;
-
- while (n) {
- drq = rb_entry_drq(n);
-
- if (sector < drq->rb_key)
- n = n->rb_left;
- else if (sector > drq->rb_key)
- n = n->rb_right;
- else
- return drq->request;
+ dd->next_rq[data_dir] = rb_entry_rq(rbnext);
}
- return NULL;
+ elv_rb_del(RQ_RB_ROOT(dd, rq), rq);
}
/*
- * deadline_find_first_drq finds the first (lowest sector numbered) request
- * for the specified data_dir. Used to sweep back to the start of the disk
- * (1-way elevator) after we process the last (highest sector) request.
- */
-static struct deadline_rq *
-deadline_find_first_drq(struct deadline_data *dd, int data_dir)
-{
- struct rb_node *n = dd->sort_list[data_dir].rb_node;
-
- for (;;) {
- if (n->rb_left == NULL)
- return rb_entry_drq(n);
-
- n = n->rb_left;
- }
-}
-
-/*
- * add drq to rbtree and fifo
+ * add rq to rbtree and fifo
*/
static void
deadline_add_request(struct request_queue *q, struct request *rq)
{
struct deadline_data *dd = q->elevator->elevator_data;
- struct deadline_rq *drq = RQ_DATA(rq);
+ const int data_dir = rq_data_dir(rq);
- const int data_dir = rq_data_dir(drq->request);
+ deadline_add_rq_rb(dd, rq);
- deadline_add_drq_rb(dd, drq);
/*
* set expire time (only used for reads) and add to fifo list
*/
- drq->expires = jiffies + dd->fifo_expire[data_dir];
- list_add_tail(&drq->fifo, &dd->fifo_list[data_dir]);
-
- if (rq_mergeable(rq))
- deadline_add_drq_hash(dd, drq);
+ rq_set_fifo_time(rq, jiffies + dd->fifo_expire[data_dir]);
+ list_add_tail(&rq->queuelist, &dd->fifo_list[data_dir]);
}
/*
- * remove rq from rbtree, fifo, and hash
+ * remove rq from rbtree and fifo.
*/
static void deadline_remove_request(request_queue_t *q, struct request *rq)
{
- struct deadline_rq *drq = RQ_DATA(rq);
struct deadline_data *dd = q->elevator->elevator_data;
- list_del_init(&drq->fifo);
- deadline_del_drq_rb(dd, drq);
- deadline_del_drq_hash(drq);
+ rq_fifo_clear(rq);
+ deadline_del_rq_rb(dd, rq);
}
static int
@@ -302,27 +122,14 @@ deadline_merge(request_queue_t *q, struct request **req, struct bio *bio)
int ret;
/*
- * see if the merge hash can satisfy a back merge
- */
- __rq = deadline_find_drq_hash(dd, bio->bi_sector);
- if (__rq) {
- BUG_ON(__rq->sector + __rq->nr_sectors != bio->bi_sector);
-
- if (elv_rq_merge_ok(__rq, bio)) {
- ret = ELEVATOR_BACK_MERGE;
- goto out;
- }
- }
-
- /*
* check for front merge
*/
if (dd->front_merges) {
- sector_t rb_key = bio->bi_sector + bio_sectors(bio);
+ sector_t sector = bio->bi_sector + bio_sectors(bio);
- __rq = deadline_find_drq_rb(dd, rb_key, bio_data_dir(bio));
+ __rq = elv_rb_find(&dd->sort_list[bio_data_dir(bio)], sector);
if (__rq) {
- BUG_ON(rb_key != rq_rb_key(__rq));
+ BUG_ON(sector != __rq->sector);
if (elv_rq_merge_ok(__rq, bio)) {
ret = ELEVATOR_FRONT_MERGE;
@@ -333,29 +140,21 @@ deadline_merge(request_queue_t *q, struct request **req, struct bio *bio)
return ELEVATOR_NO_MERGE;
out:
- if (ret)
- deadline_hot_drq_hash(dd, RQ_DATA(__rq));
*req = __rq;
return ret;
}
-static void deadline_merged_request(request_queue_t *q, struct request *req)
+static void deadline_merged_request(request_queue_t *q, struct request *req,
+ int type)
{
struct deadline_data *dd = q->elevator->elevator_data;
- struct deadline_rq *drq = RQ_DATA(req);
-
- /*
- * hash always needs to be repositioned, key is end sector
- */
- deadline_del_drq_hash(drq);
- deadline_add_drq_hash(dd, drq);
/*
* if the merge was a front merge, we need to reposition request
*/
- if (rq_rb_key(req) != drq->rb_key) {
- deadline_del_drq_rb(dd, drq);
- deadline_add_drq_rb(dd, drq);
+ if (type == ELEVATOR_FRONT_MERGE) {
+ elv_rb_del(RQ_RB_ROOT(dd, req), req);
+ deadline_add_rq_rb(dd, req);
}
}
@@ -363,33 +162,14 @@ static void
deadline_merged_requests(request_queue_t *q, struct request *req,
struct request *next)
{
- struct deadline_data *dd = q->elevator->elevator_data;
- struct deadline_rq *drq = RQ_DATA(req);
- struct deadline_rq *dnext = RQ_DATA(next);
-
- BUG_ON(!drq);
- BUG_ON(!dnext);
-
/*
- * reposition drq (this is the merged request) in hash, and in rbtree
- * in case of a front merge
+ * if next expires before rq, assign its expire time to rq
+ * and move into next position (next will be deleted) in fifo
*/
- deadline_del_drq_hash(drq);
- deadline_add_drq_hash(dd, drq);
-
- if (rq_rb_key(req) != drq->rb_key) {
- deadline_del_drq_rb(dd, drq);
- deadline_add_drq_rb(dd, drq);
- }
-
- /*
- * if dnext expires before drq, assign its expire time to drq
- * and move into dnext position (dnext will be deleted) in fifo
- */
- if (!list_empty(&drq->fifo) && !list_empty(&dnext->fifo)) {
- if (time_before(dnext->expires, drq->expires)) {
- list_move(&drq->fifo, &dnext->fifo);
- drq->expires = dnext->expires;
+ if (!list_empty(&req->queuelist) && !list_empty(&next->queuelist)) {
+ if (time_before(rq_fifo_time(next), rq_fifo_time(req))) {
+ list_move(&req->queuelist, &next->queuelist);
+ rq_set_fifo_time(req, rq_fifo_time(next));
}
}
@@ -403,52 +183,50 @@ deadline_merged_requests(request_queue_t *q, struct request *req,
* move request from sort list to dispatch queue.
*/
static inline void
-deadline_move_to_dispatch(struct deadline_data *dd, struct deadline_rq *drq)
+deadline_move_to_dispatch(struct deadline_data *dd, struct request *rq)
{
- request_queue_t *q = drq->request->q;
+ request_queue_t *q = rq->q;
- deadline_remove_request(q, drq->request);
- elv_dispatch_add_tail(q, drq->request);
+ deadline_remove_request(q, rq);
+ elv_dispatch_add_tail(q, rq);
}
/*
* move an entry to dispatch queue
*/
static void
-deadline_move_request(struct deadline_data *dd, struct deadline_rq *drq)
+deadline_move_request(struct deadline_data *dd, struct request *rq)
{
- const int data_dir = rq_data_dir(drq->request);
- struct rb_node *rbnext = rb_next(&drq->rb_node);
+ const int data_dir = rq_data_dir(rq);
+ struct rb_node *rbnext = rb_next(&rq->rb_node);
- dd->next_drq[READ] = NULL;
- dd->next_drq[WRITE] = NULL;
+ dd->next_rq[READ] = NULL;
+ dd->next_rq[WRITE] = NULL;
if (rbnext)
- dd->next_drq[data_dir] = rb_entry_drq(rbnext);
+ dd->next_rq[data_dir] = rb_entry_rq(rbnext);
- dd->last_sector = drq->request->sector + drq->request->nr_sectors;
+ dd->last_sector = rq->sector + rq->nr_sectors;
/*
* take it off the sort and fifo list, move
* to dispatch queue
*/
- deadline_move_to_dispatch(dd, drq);
+ deadline_move_to_dispatch(dd, rq);
}
-#define list_entry_fifo(ptr) list_entry((ptr), struct deadline_rq, fifo)
-
/*
* deadline_check_fifo returns 0 if there are no expired reads on the fifo,
* 1 otherwise. Requires !list_empty(&dd->fifo_list[data_dir])
*/
static inline int deadline_check_fifo(struct deadline_data *dd, int ddir)
{
- struct deadline_rq *drq = list_entry_fifo(dd->fifo_list[ddir].next);
+ struct request *rq = rq_entry_fifo(dd->fifo_list[ddir].next);
/*
- * drq is expired!
+ * rq is expired!
*/
- if (time_after(jiffies, drq->expires))
+ if (time_after(jiffies, rq_fifo_time(rq)))
return 1;
return 0;
@@ -463,21 +241,21 @@ static int deadline_dispatch_requests(request_queue_t *q, int force)
struct deadline_data *dd = q->elevator->elevator_data;
const int reads = !list_empty(&dd->fifo_list[READ]);
const int writes = !list_empty(&dd->fifo_list[WRITE]);
- struct deadline_rq *drq;
+ struct request *rq;
int data_dir;
/*
* batches are currently reads XOR writes
*/
- if (dd->next_drq[WRITE])
- drq = dd->next_drq[WRITE];
+ if (dd->next_rq[WRITE])
+ rq = dd->next_rq[WRITE];
else
- drq = dd->next_drq[READ];
+ rq = dd->next_rq[READ];
- if (drq) {
+ if (rq) {
/* we have a "next request" */
- if (dd->last_sector != drq->request->sector)
+ if (dd->last_sector != rq->sector)
/* end the batch on a non sequential request */
dd->batching += dd->fifo_batch;
@@ -526,30 +304,33 @@ dispatch_find_request:
if (deadline_check_fifo(dd, data_dir)) {
/* An expired request exists - satisfy it */
dd->batching = 0;
- drq = list_entry_fifo(dd->fifo_list[data_dir].next);
+ rq = rq_entry_fifo(dd->fifo_list[data_dir].next);
- } else if (dd->next_drq[data_dir]) {
+ } else if (dd->next_rq[data_dir]) {
/*
* The last req was the same dir and we have a next request in
* sort order. No expired requests so continue on from here.
*/
- drq = dd->next_drq[data_dir];
+ rq = dd->next_rq[data_dir];
} else {
+ struct rb_node *node;
/*
* The last req was the other direction or we have run out of
* higher-sectored requests. Go back to the lowest sectored
* request (1 way elevator) and start a new batch.
*/
dd->batching = 0;
- drq = deadline_find_first_drq(dd, data_dir);
+ node = rb_first(&dd->sort_list[data_dir]);
+ if (node)
+ rq = rb_entry_rq(node);
}
dispatch_request:
/*
- * drq is the selected appropriate request.
+ * rq is the selected appropriate request.
*/
dd->batching++;
- deadline_move_request(dd, drq);
+ deadline_move_request(dd, rq);
return 1;
}
@@ -562,30 +343,6 @@ static int deadline_queue_empty(request_queue_t *q)
&& list_empty(&dd->fifo_list[READ]);
}
-static struct request *
-deadline_former_request(request_queue_t *q, struct request *rq)
-{
- struct deadline_rq *drq = RQ_DATA(rq);
- struct rb_node *rbprev = rb_prev(&drq->rb_node);
-
- if (rbprev)
- return rb_entry_drq(rbprev)->request;
-
- return NULL;
-}
-
-static struct request *
-deadline_latter_request(request_queue_t *q, struct request *rq)
-{
- struct deadline_rq *drq = RQ_DATA(rq);
- struct rb_node *rbnext = rb_next(&drq->rb_node);
-
- if (rbnext)
- return rb_entry_drq(rbnext)->request;
-
- return NULL;
-}
-
static void deadline_exit_queue(elevator_t *e)
{
struct deadline_data *dd = e->elevator_data;
@@ -593,46 +350,21 @@ static void deadline_exit_queue(elevator_t *e)
BUG_ON(!list_empty(&dd->fifo_list[READ]));
BUG_ON(!list_empty(&dd->fifo_list[WRITE]));
- mempool_destroy(dd->drq_pool);
- kfree(dd->hash);
kfree(dd);
}
/*
- * initialize elevator private data (deadline_data), and alloc a drq for
- * each request on the free lists
+ * initialize elevator private data (deadline_data).
*/
static void *deadline_init_queue(request_queue_t *q, elevator_t *e)
{
struct deadline_data *dd;
- int i;
-
- if (!drq_pool)
- return NULL;
dd = kmalloc_node(sizeof(*dd), GFP_KERNEL, q->node);
if (!dd)
return NULL;
memset(dd, 0, sizeof(*dd));
- dd->hash = kmalloc_node(sizeof(struct hlist_head)*DL_HASH_ENTRIES,
- GFP_KERNEL, q->node);
- if (!dd->hash) {
- kfree(dd);
- return NULL;
- }
-
- dd->drq_pool = mempool_create_node(BLKDEV_MIN_RQ, mempool_alloc_slab,
- mempool_free_slab, drq_pool, q->node);
- if (!dd->drq_pool) {
- kfree(dd->hash);
- kfree(dd);
- return NULL;
- }
-
- for (i = 0; i < DL_HASH_ENTRIES; i++)
- INIT_HLIST_HEAD(&dd->hash[i]);
-
INIT_LIST_HEAD(&dd->fifo_list[READ]);
INIT_LIST_HEAD(&dd->fifo_list[WRITE]);
dd->sort_list[READ] = RB_ROOT;
@@ -645,39 +377,6 @@ static void *deadline_init_queue(request_queue_t *q, elevator_t *e)
return dd;
}
-static void deadline_put_request(request_queue_t *q, struct request *rq)
-{
- struct deadline_data *dd = q->elevator->elevator_data;
- struct deadline_rq *drq = RQ_DATA(rq);
-
- mempool_free(drq, dd->drq_pool);
- rq->elevator_private = NULL;
-}
-
-static int
-deadline_set_request(request_queue_t *q, struct request *rq, struct bio *bio,
- gfp_t gfp_mask)
-{
- struct deadline_data *dd = q->elevator->elevator_data;
- struct deadline_rq *drq;
-
- drq = mempool_alloc(dd->drq_pool, gfp_mask);
- if (drq) {
- memset(drq, 0, sizeof(*drq));
- RB_CLEAR_NODE(&drq->rb_node);
- drq->request = rq;
-
- INIT_HLIST_NODE(&drq->hash);
-
- INIT_LIST_HEAD(&drq->fifo);
-
- rq->elevator_private = drq;
- return 0;
- }
-
- return 1;
-}
-
/*
* sysfs parts below
*/
@@ -757,10 +456,8 @@ static struct elevator_type iosched_deadline = {
.elevator_dispatch_fn = deadline_dispatch_requests,
.elevator_add_req_fn = deadline_add_request,
.elevator_queue_empty_fn = deadline_queue_empty,
- .elevator_former_req_fn = deadline_former_request,
- .elevator_latter_req_fn = deadline_latter_request,
- .elevator_set_req_fn = deadline_set_request,
- .elevator_put_req_fn = deadline_put_request,
+ .elevator_former_req_fn = elv_rb_former_request,
+ .elevator_latter_req_fn = elv_rb_latter_request,
.elevator_init_fn = deadline_init_queue,
.elevator_exit_fn = deadline_exit_queue,
},
@@ -772,24 +469,11 @@ static struct elevator_type iosched_deadline = {
static int __init deadline_init(void)
{
- int ret;
-
- drq_pool = kmem_cache_create("deadline_drq", sizeof(struct deadline_rq),
- 0, 0, NULL, NULL);
-
- if (!drq_pool)
- return -ENOMEM;
-
- ret = elv_register(&iosched_deadline);
- if (ret)
- kmem_cache_destroy(drq_pool);
-
- return ret;
+ return elv_register(&iosched_deadline);
}
static void __exit deadline_exit(void)
{
- kmem_cache_destroy(drq_pool);
elv_unregister(&iosched_deadline);
}
diff --git a/block/elevator.c b/block/elevator.c
index 9b72dc7c8a5c..487dd3da8853 100644
--- a/block/elevator.c
+++ b/block/elevator.c
@@ -3,7 +3,7 @@
*
* Copyright (C) 2000 Andrea Arcangeli <andrea@suse.de> SuSE
*
- * 30042000 Jens Axboe <axboe@suse.de> :
+ * 30042000 Jens Axboe <axboe@kernel.dk> :
*
* Split the elevator a bit so that it is possible to choose a different
* one or even write a new "plug in". There are three pieces:
@@ -33,6 +33,7 @@
#include <linux/compiler.h>
#include <linux/delay.h>
#include <linux/blktrace_api.h>
+#include <linux/hash.h>
#include <asm/uaccess.h>
@@ -40,6 +41,16 @@ static DEFINE_SPINLOCK(elv_list_lock);
static LIST_HEAD(elv_list);
/*
+ * Merge hash stuff.
+ */
+static const int elv_hash_shift = 6;
+#define ELV_HASH_BLOCK(sec) ((sec) >> 3)
+#define ELV_HASH_FN(sec) (hash_long(ELV_HASH_BLOCK((sec)), elv_hash_shift))
+#define ELV_HASH_ENTRIES (1 << elv_hash_shift)
+#define rq_hash_key(rq) ((rq)->sector + (rq)->nr_sectors)
+#define ELV_ON_HASH(rq) (!hlist_unhashed(&(rq)->hash))
+
+/*
* can we safely merge with this request?
*/
inline int elv_rq_merge_ok(struct request *rq, struct bio *bio)
@@ -56,8 +67,7 @@ inline int elv_rq_merge_ok(struct request *rq, struct bio *bio)
/*
* same device and no special stuff set, merge is ok
*/
- if (rq->rq_disk == bio->bi_bdev->bd_disk &&
- !rq->waiting && !rq->special)
+ if (rq->rq_disk == bio->bi_bdev->bd_disk && !rq->special)
return 1;
return 0;
@@ -151,27 +161,44 @@ __setup("elevator=", elevator_setup);
static struct kobj_type elv_ktype;
-static elevator_t *elevator_alloc(struct elevator_type *e)
-{
- elevator_t *eq = kmalloc(sizeof(elevator_t), GFP_KERNEL);
- if (eq) {
- memset(eq, 0, sizeof(*eq));
- eq->ops = &e->ops;
- eq->elevator_type = e;
- kobject_init(&eq->kobj);
- snprintf(eq->kobj.name, KOBJ_NAME_LEN, "%s", "iosched");
- eq->kobj.ktype = &elv_ktype;
- mutex_init(&eq->sysfs_lock);
- } else {
- elevator_put(e);
- }
+static elevator_t *elevator_alloc(request_queue_t *q, struct elevator_type *e)
+{
+ elevator_t *eq;
+ int i;
+
+ eq = kmalloc_node(sizeof(elevator_t), GFP_KERNEL, q->node);
+ if (unlikely(!eq))
+ goto err;
+
+ memset(eq, 0, sizeof(*eq));
+ eq->ops = &e->ops;
+ eq->elevator_type = e;
+ kobject_init(&eq->kobj);
+ snprintf(eq->kobj.name, KOBJ_NAME_LEN, "%s", "iosched");
+ eq->kobj.ktype = &elv_ktype;
+ mutex_init(&eq->sysfs_lock);
+
+ eq->hash = kmalloc_node(sizeof(struct hlist_head) * ELV_HASH_ENTRIES,
+ GFP_KERNEL, q->node);
+ if (!eq->hash)
+ goto err;
+
+ for (i = 0; i < ELV_HASH_ENTRIES; i++)
+ INIT_HLIST_HEAD(&eq->hash[i]);
+
return eq;
+err:
+ kfree(eq);
+ elevator_put(e);
+ return NULL;
}
static void elevator_release(struct kobject *kobj)
{
elevator_t *e = container_of(kobj, elevator_t, kobj);
+
elevator_put(e->elevator_type);
+ kfree(e->hash);
kfree(e);
}
@@ -198,7 +225,7 @@ int elevator_init(request_queue_t *q, char *name)
e = elevator_get("noop");
}
- eq = elevator_alloc(e);
+ eq = elevator_alloc(q, e);
if (!eq)
return -ENOMEM;
@@ -212,6 +239,8 @@ int elevator_init(request_queue_t *q, char *name)
return ret;
}
+EXPORT_SYMBOL(elevator_init);
+
void elevator_exit(elevator_t *e)
{
mutex_lock(&e->sysfs_lock);
@@ -223,10 +252,118 @@ void elevator_exit(elevator_t *e)
kobject_put(&e->kobj);
}
+EXPORT_SYMBOL(elevator_exit);
+
+static inline void __elv_rqhash_del(struct request *rq)
+{
+ hlist_del_init(&rq->hash);
+}
+
+static void elv_rqhash_del(request_queue_t *q, struct request *rq)
+{
+ if (ELV_ON_HASH(rq))
+ __elv_rqhash_del(rq);
+}
+
+static void elv_rqhash_add(request_queue_t *q, struct request *rq)
+{
+ elevator_t *e = q->elevator;
+
+ BUG_ON(ELV_ON_HASH(rq));
+ hlist_add_head(&rq->hash, &e->hash[ELV_HASH_FN(rq_hash_key(rq))]);
+}
+
+static void elv_rqhash_reposition(request_queue_t *q, struct request *rq)
+{
+ __elv_rqhash_del(rq);
+ elv_rqhash_add(q, rq);
+}
+
+static struct request *elv_rqhash_find(request_queue_t *q, sector_t offset)
+{
+ elevator_t *e = q->elevator;
+ struct hlist_head *hash_list = &e->hash[ELV_HASH_FN(offset)];
+ struct hlist_node *entry, *next;
+ struct request *rq;
+
+ hlist_for_each_entry_safe(rq, entry, next, hash_list, hash) {
+ BUG_ON(!ELV_ON_HASH(rq));
+
+ if (unlikely(!rq_mergeable(rq))) {
+ __elv_rqhash_del(rq);
+ continue;
+ }
+
+ if (rq_hash_key(rq) == offset)
+ return rq;
+ }
+
+ return NULL;
+}
+
+/*
+ * RB-tree support functions for inserting/lookup/removal of requests
+ * in a sorted RB tree.
+ */
+struct request *elv_rb_add(struct rb_root *root, struct request *rq)
+{
+ struct rb_node **p = &root->rb_node;
+ struct rb_node *parent = NULL;
+ struct request *__rq;
+
+ while (*p) {
+ parent = *p;
+ __rq = rb_entry(parent, struct request, rb_node);
+
+ if (rq->sector < __rq->sector)
+ p = &(*p)->rb_left;
+ else if (rq->sector > __rq->sector)
+ p = &(*p)->rb_right;
+ else
+ return __rq;
+ }
+
+ rb_link_node(&rq->rb_node, parent, p);
+ rb_insert_color(&rq->rb_node, root);
+ return NULL;
+}
+
+EXPORT_SYMBOL(elv_rb_add);
+
+void elv_rb_del(struct rb_root *root, struct request *rq)
+{
+ BUG_ON(RB_EMPTY_NODE(&rq->rb_node));
+ rb_erase(&rq->rb_node, root);
+ RB_CLEAR_NODE(&rq->rb_node);
+}
+
+EXPORT_SYMBOL(elv_rb_del);
+
+struct request *elv_rb_find(struct rb_root *root, sector_t sector)
+{
+ struct rb_node *n = root->rb_node;
+ struct request *rq;
+
+ while (n) {
+ rq = rb_entry(n, struct request, rb_node);
+
+ if (sector < rq->sector)
+ n = n->rb_left;
+ else if (sector > rq->sector)
+ n = n->rb_right;
+ else
+ return rq;
+ }
+
+ return NULL;
+}
+
+EXPORT_SYMBOL(elv_rb_find);
+
/*
* Insert rq into dispatch queue of q. Queue lock must be held on
- * entry. If sort != 0, rq is sort-inserted; otherwise, rq will be
- * appended to the dispatch queue. To be used by specific elevators.
+ * entry. rq is sort insted into the dispatch queue. To be used by
+ * specific elevators.
*/
void elv_dispatch_sort(request_queue_t *q, struct request *rq)
{
@@ -235,6 +372,9 @@ void elv_dispatch_sort(request_queue_t *q, struct request *rq)
if (q->last_merge == rq)
q->last_merge = NULL;
+
+ elv_rqhash_del(q, rq);
+
q->nr_sorted--;
boundary = q->end_sector;
@@ -242,7 +382,7 @@ void elv_dispatch_sort(request_queue_t *q, struct request *rq)
list_for_each_prev(entry, &q->queue_head) {
struct request *pos = list_entry_rq(entry);
- if (pos->flags & (REQ_SOFTBARRIER|REQ_HARDBARRIER|REQ_STARTED))
+ if (pos->cmd_flags & (REQ_SOFTBARRIER|REQ_HARDBARRIER|REQ_STARTED))
break;
if (rq->sector >= boundary) {
if (pos->sector < boundary)
@@ -258,11 +398,38 @@ void elv_dispatch_sort(request_queue_t *q, struct request *rq)
list_add(&rq->queuelist, entry);
}
+EXPORT_SYMBOL(elv_dispatch_sort);
+
+/*
+ * Insert rq into dispatch queue of q. Queue lock must be held on
+ * entry. rq is added to the back of the dispatch queue. To be used by
+ * specific elevators.
+ */
+void elv_dispatch_add_tail(struct request_queue *q, struct request *rq)
+{
+ if (q->last_merge == rq)
+ q->last_merge = NULL;
+
+ elv_rqhash_del(q, rq);
+
+ q->nr_sorted--;
+
+ q->end_sector = rq_end_sector(rq);
+ q->boundary_rq = rq;
+ list_add_tail(&rq->queuelist, &q->queue_head);
+}
+
+EXPORT_SYMBOL(elv_dispatch_add_tail);
+
int elv_merge(request_queue_t *q, struct request **req, struct bio *bio)
{
elevator_t *e = q->elevator;
+ struct request *__rq;
int ret;
+ /*
+ * First try one-hit cache.
+ */
if (q->last_merge) {
ret = elv_try_merge(q->last_merge, bio);
if (ret != ELEVATOR_NO_MERGE) {
@@ -271,18 +438,30 @@ int elv_merge(request_queue_t *q, struct request **req, struct bio *bio)
}
}
+ /*
+ * See if our hash lookup can find a potential backmerge.
+ */
+ __rq = elv_rqhash_find(q, bio->bi_sector);
+ if (__rq && elv_rq_merge_ok(__rq, bio)) {
+ *req = __rq;
+ return ELEVATOR_BACK_MERGE;
+ }
+
if (e->ops->elevator_merge_fn)
return e->ops->elevator_merge_fn(q, req, bio);
return ELEVATOR_NO_MERGE;
}
-void elv_merged_request(request_queue_t *q, struct request *rq)
+void elv_merged_request(request_queue_t *q, struct request *rq, int type)
{
elevator_t *e = q->elevator;
if (e->ops->elevator_merged_fn)
- e->ops->elevator_merged_fn(q, rq);
+ e->ops->elevator_merged_fn(q, rq, type);
+
+ if (type == ELEVATOR_BACK_MERGE)
+ elv_rqhash_reposition(q, rq);
q->last_merge = rq;
}
@@ -294,8 +473,11 @@ void elv_merge_requests(request_queue_t *q, struct request *rq,
if (e->ops->elevator_merge_req_fn)
e->ops->elevator_merge_req_fn(q, rq, next);
- q->nr_sorted--;
+ elv_rqhash_reposition(q, rq);
+ elv_rqhash_del(q, next);
+
+ q->nr_sorted--;
q->last_merge = rq;
}
@@ -313,7 +495,7 @@ void elv_requeue_request(request_queue_t *q, struct request *rq)
e->ops->elevator_deactivate_req_fn(q, rq);
}
- rq->flags &= ~REQ_STARTED;
+ rq->cmd_flags &= ~REQ_STARTED;
elv_insert(q, rq, ELEVATOR_INSERT_REQUEUE);
}
@@ -344,13 +526,13 @@ void elv_insert(request_queue_t *q, struct request *rq, int where)
switch (where) {
case ELEVATOR_INSERT_FRONT:
- rq->flags |= REQ_SOFTBARRIER;
+ rq->cmd_flags |= REQ_SOFTBARRIER;
list_add(&rq->queuelist, &q->queue_head);
break;
case ELEVATOR_INSERT_BACK:
- rq->flags |= REQ_SOFTBARRIER;
+ rq->cmd_flags |= REQ_SOFTBARRIER;
elv_drain_elevator(q);
list_add_tail(&rq->queuelist, &q->queue_head);
/*
@@ -369,10 +551,14 @@ void elv_insert(request_queue_t *q, struct request *rq, int where)
case ELEVATOR_INSERT_SORT:
BUG_ON(!blk_fs_request(rq));
- rq->flags |= REQ_SORTED;
+ rq->cmd_flags |= REQ_SORTED;
q->nr_sorted++;
- if (q->last_merge == NULL && rq_mergeable(rq))
- q->last_merge = rq;
+ if (rq_mergeable(rq)) {
+ elv_rqhash_add(q, rq);
+ if (!q->last_merge)
+ q->last_merge = rq;
+ }
+
/*
* Some ioscheds (cfq) run q->request_fn directly, so
* rq cannot be accessed after calling
@@ -387,7 +573,7 @@ void elv_insert(request_queue_t *q, struct request *rq, int where)
* insertion; otherwise, requests should be requeued
* in ordseq order.
*/
- rq->flags |= REQ_SOFTBARRIER;
+ rq->cmd_flags |= REQ_SOFTBARRIER;
if (q->ordseq == 0) {
list_add(&rq->queuelist, &q->queue_head);
@@ -429,9 +615,9 @@ void __elv_add_request(request_queue_t *q, struct request *rq, int where,
int plug)
{
if (q->ordcolor)
- rq->flags |= REQ_ORDERED_COLOR;
+ rq->cmd_flags |= REQ_ORDERED_COLOR;
- if (rq->flags & (REQ_SOFTBARRIER | REQ_HARDBARRIER)) {
+ if (rq->cmd_flags & (REQ_SOFTBARRIER | REQ_HARDBARRIER)) {
/*
* toggle ordered color
*/
@@ -452,7 +638,7 @@ void __elv_add_request(request_queue_t *q, struct request *rq, int where,
q->end_sector = rq_end_sector(rq);
q->boundary_rq = rq;
}
- } else if (!(rq->flags & REQ_ELVPRIV) && where == ELEVATOR_INSERT_SORT)
+ } else if (!(rq->cmd_flags & REQ_ELVPRIV) && where == ELEVATOR_INSERT_SORT)
where = ELEVATOR_INSERT_BACK;
if (plug)
@@ -461,6 +647,8 @@ void __elv_add_request(request_queue_t *q, struct request *rq, int where,
elv_insert(q, rq, where);
}
+EXPORT_SYMBOL(__elv_add_request);
+
void elv_add_request(request_queue_t *q, struct request *rq, int where,
int plug)
{
@@ -471,6 +659,8 @@ void elv_add_request(request_queue_t *q, struct request *rq, int where,
spin_unlock_irqrestore(q->queue_lock, flags);
}
+EXPORT_SYMBOL(elv_add_request);
+
static inline struct request *__elv_next_request(request_queue_t *q)
{
struct request *rq;
@@ -493,7 +683,7 @@ struct request *elv_next_request(request_queue_t *q)
int ret;
while ((rq = __elv_next_request(q)) != NULL) {
- if (!(rq->flags & REQ_STARTED)) {
+ if (!(rq->cmd_flags & REQ_STARTED)) {
elevator_t *e = q->elevator;
/*
@@ -510,7 +700,7 @@ struct request *elv_next_request(request_queue_t *q)
* it, a request that has been delayed should
* not be passed by new incoming requests
*/
- rq->flags |= REQ_STARTED;
+ rq->cmd_flags |= REQ_STARTED;
blk_add_trace_rq(q, rq, BLK_TA_ISSUE);
}
@@ -519,7 +709,7 @@ struct request *elv_next_request(request_queue_t *q)
q->boundary_rq = NULL;
}
- if ((rq->flags & REQ_DONTPREP) || !q->prep_rq_fn)
+ if ((rq->cmd_flags & REQ_DONTPREP) || !q->prep_rq_fn)
break;
ret = q->prep_rq_fn(q, rq);
@@ -541,7 +731,7 @@ struct request *elv_next_request(request_queue_t *q)
nr_bytes = rq->data_len;
blkdev_dequeue_request(rq);
- rq->flags |= REQ_QUIET;
+ rq->cmd_flags |= REQ_QUIET;
end_that_request_chunk(rq, 0, nr_bytes);
end_that_request_last(rq, 0);
} else {
@@ -554,9 +744,12 @@ struct request *elv_next_request(request_queue_t *q)
return rq;
}
+EXPORT_SYMBOL(elv_next_request);
+
void elv_dequeue_request(request_queue_t *q, struct request *rq)
{
BUG_ON(list_empty(&rq->queuelist));
+ BUG_ON(ELV_ON_HASH(rq));
list_del_init(&rq->queuelist);
@@ -569,6 +762,8 @@ void elv_dequeue_request(request_queue_t *q, struct request *rq)
q->in_flight++;
}
+EXPORT_SYMBOL(elv_dequeue_request);
+
int elv_queue_empty(request_queue_t *q)
{
elevator_t *e = q->elevator;
@@ -582,6 +777,8 @@ int elv_queue_empty(request_queue_t *q)
return 1;
}
+EXPORT_SYMBOL(elv_queue_empty);
+
struct request *elv_latter_request(request_queue_t *q, struct request *rq)
{
elevator_t *e = q->elevator;
@@ -600,13 +797,12 @@ struct request *elv_former_request(request_queue_t *q, struct request *rq)
return NULL;
}
-int elv_set_request(request_queue_t *q, struct request *rq, struct bio *bio,
- gfp_t gfp_mask)
+int elv_set_request(request_queue_t *q, struct request *rq, gfp_t gfp_mask)
{
elevator_t *e = q->elevator;
if (e->ops->elevator_set_req_fn)
- return e->ops->elevator_set_req_fn(q, rq, bio, gfp_mask);
+ return e->ops->elevator_set_req_fn(q, rq, gfp_mask);
rq->elevator_private = NULL;
return 0;
@@ -620,12 +816,12 @@ void elv_put_request(request_queue_t *q, struct request *rq)
e->ops->elevator_put_req_fn(q, rq);
}
-int elv_may_queue(request_queue_t *q, int rw, struct bio *bio)
+int elv_may_queue(request_queue_t *q, int rw)
{
elevator_t *e = q->elevator;
if (e->ops->elevator_may_queue_fn)
- return e->ops->elevator_may_queue_fn(q, rw, bio);
+ return e->ops->elevator_may_queue_fn(q, rw);
return ELV_MQUEUE_MAY;
}
@@ -792,7 +988,7 @@ static int elevator_switch(request_queue_t *q, struct elevator_type *new_e)
/*
* Allocate new elevator
*/
- e = elevator_alloc(new_e);
+ e = elevator_alloc(q, new_e);
if (!e)
return 0;
@@ -908,11 +1104,26 @@ ssize_t elv_iosched_show(request_queue_t *q, char *name)
return len;
}
-EXPORT_SYMBOL(elv_dispatch_sort);
-EXPORT_SYMBOL(elv_add_request);
-EXPORT_SYMBOL(__elv_add_request);
-EXPORT_SYMBOL(elv_next_request);
-EXPORT_SYMBOL(elv_dequeue_request);
-EXPORT_SYMBOL(elv_queue_empty);
-EXPORT_SYMBOL(elevator_exit);
-EXPORT_SYMBOL(elevator_init);
+struct request *elv_rb_former_request(request_queue_t *q, struct request *rq)
+{
+ struct rb_node *rbprev = rb_prev(&rq->rb_node);
+
+ if (rbprev)
+ return rb_entry_rq(rbprev);
+
+ return NULL;
+}
+
+EXPORT_SYMBOL(elv_rb_former_request);
+
+struct request *elv_rb_latter_request(request_queue_t *q, struct request *rq)
+{
+ struct rb_node *rbnext = rb_next(&rq->rb_node);
+
+ if (rbnext)
+ return rb_entry_rq(rbnext);
+
+ return NULL;
+}
+
+EXPORT_SYMBOL(elv_rb_latter_request);
diff --git a/block/genhd.c b/block/genhd.c
index 25d1f42568cc..653919d50cd4 100644
--- a/block/genhd.c
+++ b/block/genhd.c
@@ -295,10 +295,15 @@ static struct kobject *base_probe(dev_t dev, int *part, void *data)
static int __init genhd_device_init(void)
{
+ int err;
+
bdev_map = kobj_map_init(base_probe, &block_subsys_lock);
blk_dev_init();
- subsystem_register(&block_subsys);
- return 0;
+ err = subsystem_register(&block_subsys);
+ if (err < 0)
+ printk(KERN_WARNING "%s: subsystem_register error: %d\n",
+ __FUNCTION__, err);
+ return err;
}
subsys_initcall(genhd_device_init);
diff --git a/block/ioctl.c b/block/ioctl.c
index 309760b7e37f..58aab630dfc1 100644
--- a/block/ioctl.c
+++ b/block/ioctl.c
@@ -199,8 +199,8 @@ static int blkdev_locked_ioctl(struct file *file, struct block_device *bdev,
return -ENOIOCTLCMD;
}
-static int blkdev_driver_ioctl(struct inode *inode, struct file *file,
- struct gendisk *disk, unsigned cmd, unsigned long arg)
+int blkdev_driver_ioctl(struct inode *inode, struct file *file,
+ struct gendisk *disk, unsigned cmd, unsigned long arg)
{
int ret;
if (disk->fops->unlocked_ioctl)
@@ -215,6 +215,7 @@ static int blkdev_driver_ioctl(struct inode *inode, struct file *file,
return -ENOTTY;
}
+EXPORT_SYMBOL_GPL(blkdev_driver_ioctl);
int blkdev_ioctl(struct inode *inode, struct file *file, unsigned cmd,
unsigned long arg)
diff --git a/block/ll_rw_blk.c b/block/ll_rw_blk.c
index 9c3a06bcb7ba..83425fb3c8db 100644
--- a/block/ll_rw_blk.c
+++ b/block/ll_rw_blk.c
@@ -39,6 +39,7 @@ static void blk_unplug_timeout(unsigned long data);
static void drive_stat_acct(struct request *rq, int nr_sectors, int new_io);
static void init_request_from_bio(struct request *req, struct bio *bio);
static int __make_request(request_queue_t *q, struct bio *bio);
+static struct io_context *current_io_context(gfp_t gfp_flags, int node);
/*
* For the allocated request tables
@@ -277,19 +278,19 @@ void blk_queue_make_request(request_queue_t * q, make_request_fn * mfn)
EXPORT_SYMBOL(blk_queue_make_request);
-static inline void rq_init(request_queue_t *q, struct request *rq)
+static void rq_init(request_queue_t *q, struct request *rq)
{
INIT_LIST_HEAD(&rq->queuelist);
INIT_LIST_HEAD(&rq->donelist);
rq->errors = 0;
- rq->rq_status = RQ_ACTIVE;
rq->bio = rq->biotail = NULL;
+ INIT_HLIST_NODE(&rq->hash);
+ RB_CLEAR_NODE(&rq->rb_node);
rq->ioprio = 0;
rq->buffer = NULL;
rq->ref_count = 1;
rq->q = q;
- rq->waiting = NULL;
rq->special = NULL;
rq->data_len = 0;
rq->data = NULL;
@@ -382,8 +383,8 @@ unsigned blk_ordered_req_seq(struct request *rq)
if (rq == &q->post_flush_rq)
return QUEUE_ORDSEQ_POSTFLUSH;
- if ((rq->flags & REQ_ORDERED_COLOR) ==
- (q->orig_bar_rq->flags & REQ_ORDERED_COLOR))
+ if ((rq->cmd_flags & REQ_ORDERED_COLOR) ==
+ (q->orig_bar_rq->cmd_flags & REQ_ORDERED_COLOR))
return QUEUE_ORDSEQ_DRAIN;
else
return QUEUE_ORDSEQ_DONE;
@@ -446,11 +447,11 @@ static void queue_flush(request_queue_t *q, unsigned which)
end_io = post_flush_end_io;
}
+ rq->cmd_flags = REQ_HARDBARRIER;
rq_init(q, rq);
- rq->flags = REQ_HARDBARRIER;
rq->elevator_private = NULL;
+ rq->elevator_private2 = NULL;
rq->rq_disk = q->bar_rq.rq_disk;
- rq->rl = NULL;
rq->end_io = end_io;
q->prepare_flush_fn(q, rq);
@@ -471,11 +472,13 @@ static inline struct request *start_ordered(request_queue_t *q,
blkdev_dequeue_request(rq);
q->orig_bar_rq = rq;
rq = &q->bar_rq;
+ rq->cmd_flags = 0;
rq_init(q, rq);
- rq->flags = bio_data_dir(q->orig_bar_rq->bio);
- rq->flags |= q->ordered & QUEUE_ORDERED_FUA ? REQ_FUA : 0;
+ if (bio_data_dir(q->orig_bar_rq->bio) == WRITE)
+ rq->cmd_flags |= REQ_RW;
+ rq->cmd_flags |= q->ordered & QUEUE_ORDERED_FUA ? REQ_FUA : 0;
rq->elevator_private = NULL;
- rq->rl = NULL;
+ rq->elevator_private2 = NULL;
init_request_from_bio(rq, q->orig_bar_rq->bio);
rq->end_io = bar_end_io;
@@ -587,8 +590,8 @@ static int flush_dry_bio_endio(struct bio *bio, unsigned int bytes, int error)
return 0;
}
-static inline int ordered_bio_endio(struct request *rq, struct bio *bio,
- unsigned int nbytes, int error)
+static int ordered_bio_endio(struct request *rq, struct bio *bio,
+ unsigned int nbytes, int error)
{
request_queue_t *q = rq->q;
bio_end_io_t *endio;
@@ -1124,7 +1127,7 @@ void blk_queue_end_tag(request_queue_t *q, struct request *rq)
}
list_del_init(&rq->queuelist);
- rq->flags &= ~REQ_QUEUED;
+ rq->cmd_flags &= ~REQ_QUEUED;
rq->tag = -1;
if (unlikely(bqt->tag_index[tag] == NULL))
@@ -1160,7 +1163,7 @@ int blk_queue_start_tag(request_queue_t *q, struct request *rq)
struct blk_queue_tag *bqt = q->queue_tags;
int tag;
- if (unlikely((rq->flags & REQ_QUEUED))) {
+ if (unlikely((rq->cmd_flags & REQ_QUEUED))) {
printk(KERN_ERR
"%s: request %p for device [%s] already tagged %d",
__FUNCTION__, rq,
@@ -1168,13 +1171,18 @@ int blk_queue_start_tag(request_queue_t *q, struct request *rq)
BUG();
}
- tag = find_first_zero_bit(bqt->tag_map, bqt->max_depth);
- if (tag >= bqt->max_depth)
- return 1;
+ /*
+ * Protect against shared tag maps, as we may not have exclusive
+ * access to the tag map.
+ */
+ do {
+ tag = find_first_zero_bit(bqt->tag_map, bqt->max_depth);
+ if (tag >= bqt->max_depth)
+ return 1;
- __set_bit(tag, bqt->tag_map);
+ } while (test_and_set_bit(tag, bqt->tag_map));
- rq->flags |= REQ_QUEUED;
+ rq->cmd_flags |= REQ_QUEUED;
rq->tag = tag;
bqt->tag_index[tag] = rq;
blkdev_dequeue_request(rq);
@@ -1210,65 +1218,31 @@ void blk_queue_invalidate_tags(request_queue_t *q)
printk(KERN_ERR
"%s: bad tag found on list\n", __FUNCTION__);
list_del_init(&rq->queuelist);
- rq->flags &= ~REQ_QUEUED;
+ rq->cmd_flags &= ~REQ_QUEUED;
} else
blk_queue_end_tag(q, rq);
- rq->flags &= ~REQ_STARTED;
+ rq->cmd_flags &= ~REQ_STARTED;
__elv_add_request(q, rq, ELEVATOR_INSERT_BACK, 0);
}
}
EXPORT_SYMBOL(blk_queue_invalidate_tags);
-static const char * const rq_flags[] = {
- "REQ_RW",
- "REQ_FAILFAST",
- "REQ_SORTED",
- "REQ_SOFTBARRIER",
- "REQ_HARDBARRIER",
- "REQ_FUA",
- "REQ_CMD",
- "REQ_NOMERGE",
- "REQ_STARTED",
- "REQ_DONTPREP",
- "REQ_QUEUED",
- "REQ_ELVPRIV",
- "REQ_PC",
- "REQ_BLOCK_PC",
- "REQ_SENSE",
- "REQ_FAILED",
- "REQ_QUIET",
- "REQ_SPECIAL",
- "REQ_DRIVE_CMD",
- "REQ_DRIVE_TASK",
- "REQ_DRIVE_TASKFILE",
- "REQ_PREEMPT",
- "REQ_PM_SUSPEND",
- "REQ_PM_RESUME",
- "REQ_PM_SHUTDOWN",
- "REQ_ORDERED_COLOR",
-};
-
void blk_dump_rq_flags(struct request *rq, char *msg)
{
int bit;
- printk("%s: dev %s: flags = ", msg,
- rq->rq_disk ? rq->rq_disk->disk_name : "?");
- bit = 0;
- do {
- if (rq->flags & (1 << bit))
- printk("%s ", rq_flags[bit]);
- bit++;
- } while (bit < __REQ_NR_BITS);
+ printk("%s: dev %s: type=%x, flags=%x\n", msg,
+ rq->rq_disk ? rq->rq_disk->disk_name : "?", rq->cmd_type,
+ rq->cmd_flags);
printk("\nsector %llu, nr/cnr %lu/%u\n", (unsigned long long)rq->sector,
rq->nr_sectors,
rq->current_nr_sectors);
printk("bio %p, biotail %p, buffer %p, data %p, len %u\n", rq->bio, rq->biotail, rq->buffer, rq->data, rq->data_len);
- if (rq->flags & (REQ_BLOCK_PC | REQ_PC)) {
+ if (blk_pc_request(rq)) {
printk("cdb: ");
for (bit = 0; bit < sizeof(rq->cmd); bit++)
printk("%02x ", rq->cmd[bit]);
@@ -1441,7 +1415,7 @@ static inline int ll_new_mergeable(request_queue_t *q,
int nr_phys_segs = bio_phys_segments(q, bio);
if (req->nr_phys_segments + nr_phys_segs > q->max_phys_segments) {
- req->flags |= REQ_NOMERGE;
+ req->cmd_flags |= REQ_NOMERGE;
if (req == q->last_merge)
q->last_merge = NULL;
return 0;
@@ -1464,7 +1438,7 @@ static inline int ll_new_hw_segment(request_queue_t *q,
if (req->nr_hw_segments + nr_hw_segs > q->max_hw_segments
|| req->nr_phys_segments + nr_phys_segs > q->max_phys_segments) {
- req->flags |= REQ_NOMERGE;
+ req->cmd_flags |= REQ_NOMERGE;
if (req == q->last_merge)
q->last_merge = NULL;
return 0;
@@ -1491,7 +1465,7 @@ static int ll_back_merge_fn(request_queue_t *q, struct request *req,
max_sectors = q->max_sectors;
if (req->nr_sectors + bio_sectors(bio) > max_sectors) {
- req->flags |= REQ_NOMERGE;
+ req->cmd_flags |= REQ_NOMERGE;
if (req == q->last_merge)
q->last_merge = NULL;
return 0;
@@ -1530,7 +1504,7 @@ static int ll_front_merge_fn(request_queue_t *q, struct request *req,
if (req->nr_sectors + bio_sectors(bio) > max_sectors) {
- req->flags |= REQ_NOMERGE;
+ req->cmd_flags |= REQ_NOMERGE;
if (req == q->last_merge)
q->last_merge = NULL;
return 0;
@@ -1847,8 +1821,7 @@ static void blk_release_queue(struct kobject *kobj)
if (q->queue_tags)
__blk_queue_free_tags(q);
- if (q->blk_trace)
- blk_trace_shutdown(q);
+ blk_trace_shutdown(q);
kmem_cache_free(requestq_cachep, q);
}
@@ -2030,14 +2003,13 @@ EXPORT_SYMBOL(blk_get_queue);
static inline void blk_free_request(request_queue_t *q, struct request *rq)
{
- if (rq->flags & REQ_ELVPRIV)
+ if (rq->cmd_flags & REQ_ELVPRIV)
elv_put_request(q, rq);
mempool_free(rq, q->rq.rq_pool);
}
-static inline struct request *
-blk_alloc_request(request_queue_t *q, int rw, struct bio *bio,
- int priv, gfp_t gfp_mask)
+static struct request *
+blk_alloc_request(request_queue_t *q, int rw, int priv, gfp_t gfp_mask)
{
struct request *rq = mempool_alloc(q->rq.rq_pool, gfp_mask);
@@ -2045,17 +2017,17 @@ blk_alloc_request(request_queue_t *q, int rw, struct bio *bio,
return NULL;
/*
- * first three bits are identical in rq->flags and bio->bi_rw,
+ * first three bits are identical in rq->cmd_flags and bio->bi_rw,
* see bio.h and blkdev.h
*/
- rq->flags = rw;
+ rq->cmd_flags = rw | REQ_ALLOCED;
if (priv) {
- if (unlikely(elv_set_request(q, rq, bio, gfp_mask))) {
+ if (unlikely(elv_set_request(q, rq, gfp_mask))) {
mempool_free(rq, q->rq.rq_pool);
return NULL;
}
- rq->flags |= REQ_ELVPRIV;
+ rq->cmd_flags |= REQ_ELVPRIV;
}
return rq;
@@ -2142,13 +2114,13 @@ static struct request *get_request(request_queue_t *q, int rw, struct bio *bio,
struct io_context *ioc = NULL;
int may_queue, priv;
- may_queue = elv_may_queue(q, rw, bio);
+ may_queue = elv_may_queue(q, rw);
if (may_queue == ELV_MQUEUE_NO)
goto rq_starved;
if (rl->count[rw]+1 >= queue_congestion_on_threshold(q)) {
if (rl->count[rw]+1 >= q->nr_requests) {
- ioc = current_io_context(GFP_ATOMIC);
+ ioc = current_io_context(GFP_ATOMIC, q->node);
/*
* The queue will fill after this allocation, so set
* it as full, and mark this process as "batching".
@@ -2190,7 +2162,7 @@ static struct request *get_request(request_queue_t *q, int rw, struct bio *bio,
spin_unlock_irq(q->queue_lock);
- rq = blk_alloc_request(q, rw, bio, priv, gfp_mask);
+ rq = blk_alloc_request(q, rw, priv, gfp_mask);
if (unlikely(!rq)) {
/*
* Allocation failed presumably due to memory. Undo anything
@@ -2226,7 +2198,6 @@ rq_starved:
ioc->nr_batch_requests--;
rq_init(q, rq);
- rq->rl = rl;
blk_add_trace_generic(q, bio, rw, BLK_TA_GETRQ);
out:
@@ -2269,7 +2240,7 @@ static struct request *get_request_wait(request_queue_t *q, int rw,
* up to a big batch of them for a small period time.
* See ioc_batching, ioc_set_batching
*/
- ioc = current_io_context(GFP_NOIO);
+ ioc = current_io_context(GFP_NOIO, q->node);
ioc_set_batching(q, ioc);
spin_lock_irq(q->queue_lock);
@@ -2301,6 +2272,25 @@ struct request *blk_get_request(request_queue_t *q, int rw, gfp_t gfp_mask)
EXPORT_SYMBOL(blk_get_request);
/**
+ * blk_start_queueing - initiate dispatch of requests to device
+ * @q: request queue to kick into gear
+ *
+ * This is basically a helper to remove the need to know whether a queue
+ * is plugged or not if someone just wants to initiate dispatch of requests
+ * for this queue.
+ *
+ * The queue lock must be held with interrupts disabled.
+ */
+void blk_start_queueing(request_queue_t *q)
+{
+ if (!blk_queue_plugged(q))
+ q->request_fn(q);
+ else
+ __generic_unplug_device(q);
+}
+EXPORT_SYMBOL(blk_start_queueing);
+
+/**
* blk_requeue_request - put a request back on queue
* @q: request queue where request should be inserted
* @rq: request to be inserted
@@ -2352,7 +2342,8 @@ void blk_insert_request(request_queue_t *q, struct request *rq,
* must not attempt merges on this) and that it acts as a soft
* barrier
*/
- rq->flags |= REQ_SPECIAL | REQ_SOFTBARRIER;
+ rq->cmd_type = REQ_TYPE_SPECIAL;
+ rq->cmd_flags |= REQ_SOFTBARRIER;
rq->special = data;
@@ -2366,11 +2357,7 @@ void blk_insert_request(request_queue_t *q, struct request *rq,
drive_stat_acct(rq, rq->nr_sectors, 1);
__elv_add_request(q, rq, where, 0);
-
- if (blk_queue_plugged(q))
- __generic_unplug_device(q);
- else
- q->request_fn(q);
+ blk_start_queueing(q);
spin_unlock_irqrestore(q->queue_lock, flags);
}
@@ -2559,7 +2546,7 @@ void blk_execute_rq_nowait(request_queue_t *q, struct gendisk *bd_disk,
int where = at_head ? ELEVATOR_INSERT_FRONT : ELEVATOR_INSERT_BACK;
rq->rq_disk = bd_disk;
- rq->flags |= REQ_NOMERGE;
+ rq->cmd_flags |= REQ_NOMERGE;
rq->end_io = done;
WARN_ON(irqs_disabled());
spin_lock_irq(q->queue_lock);
@@ -2599,10 +2586,9 @@ int blk_execute_rq(request_queue_t *q, struct gendisk *bd_disk,
rq->sense_len = 0;
}
- rq->waiting = &wait;
+ rq->end_io_data = &wait;
blk_execute_rq_nowait(q, bd_disk, rq, at_head, blk_end_sync_rq);
wait_for_completion(&wait);
- rq->waiting = NULL;
if (rq->errors)
err = -EIO;
@@ -2711,8 +2697,6 @@ EXPORT_SYMBOL_GPL(disk_round_stats);
*/
void __blk_put_request(request_queue_t *q, struct request *req)
{
- struct request_list *rl = req->rl;
-
if (unlikely(!q))
return;
if (unlikely(--req->ref_count))
@@ -2720,18 +2704,16 @@ void __blk_put_request(request_queue_t *q, struct request *req)
elv_completed_request(q, req);
- req->rq_status = RQ_INACTIVE;
- req->rl = NULL;
-
/*
* Request may not have originated from ll_rw_blk. if not,
* it didn't come out of our reserved rq pools
*/
- if (rl) {
+ if (req->cmd_flags & REQ_ALLOCED) {
int rw = rq_data_dir(req);
- int priv = req->flags & REQ_ELVPRIV;
+ int priv = req->cmd_flags & REQ_ELVPRIV;
BUG_ON(!list_empty(&req->queuelist));
+ BUG_ON(!hlist_unhashed(&req->hash));
blk_free_request(q, req);
freed_request(q, rw, priv);
@@ -2765,9 +2747,9 @@ EXPORT_SYMBOL(blk_put_request);
*/
void blk_end_sync_rq(struct request *rq, int error)
{
- struct completion *waiting = rq->waiting;
+ struct completion *waiting = rq->end_io_data;
- rq->waiting = NULL;
+ rq->end_io_data = NULL;
__blk_put_request(rq->q, rq);
/*
@@ -2830,7 +2812,7 @@ static int attempt_merge(request_queue_t *q, struct request *req,
if (rq_data_dir(req) != rq_data_dir(next)
|| req->rq_disk != next->rq_disk
- || next->waiting || next->special)
+ || next->special)
return 0;
/*
@@ -2891,22 +2873,24 @@ static inline int attempt_front_merge(request_queue_t *q, struct request *rq)
static void init_request_from_bio(struct request *req, struct bio *bio)
{
- req->flags |= REQ_CMD;
+ req->cmd_type = REQ_TYPE_FS;
/*
* inherit FAILFAST from bio (for read-ahead, and explicit FAILFAST)
*/
if (bio_rw_ahead(bio) || bio_failfast(bio))
- req->flags |= REQ_FAILFAST;
+ req->cmd_flags |= REQ_FAILFAST;
/*
* REQ_BARRIER implies no merging, but lets make it explicit
*/
if (unlikely(bio_barrier(bio)))
- req->flags |= (REQ_HARDBARRIER | REQ_NOMERGE);
+ req->cmd_flags |= (REQ_HARDBARRIER | REQ_NOMERGE);
if (bio_sync(bio))
- req->flags |= REQ_RW_SYNC;
+ req->cmd_flags |= REQ_RW_SYNC;
+ if (bio_rw_meta(bio))
+ req->cmd_flags |= REQ_RW_META;
req->errors = 0;
req->hard_sector = req->sector = bio->bi_sector;
@@ -2915,7 +2899,6 @@ static void init_request_from_bio(struct request *req, struct bio *bio)
req->nr_phys_segments = bio_phys_segments(req->q, bio);
req->nr_hw_segments = bio_hw_segments(req->q, bio);
req->buffer = bio_data(bio); /* see ->buffer comment above */
- req->waiting = NULL;
req->bio = req->biotail = bio;
req->ioprio = bio_prio(bio);
req->rq_disk = bio->bi_bdev->bd_disk;
@@ -2925,17 +2908,11 @@ static void init_request_from_bio(struct request *req, struct bio *bio)
static int __make_request(request_queue_t *q, struct bio *bio)
{
struct request *req;
- int el_ret, rw, nr_sectors, cur_nr_sectors, barrier, err, sync;
- unsigned short prio;
- sector_t sector;
+ int el_ret, nr_sectors, barrier, err;
+ const unsigned short prio = bio_prio(bio);
+ const int sync = bio_sync(bio);
- sector = bio->bi_sector;
nr_sectors = bio_sectors(bio);
- cur_nr_sectors = bio_cur_sectors(bio);
- prio = bio_prio(bio);
-
- rw = bio_data_dir(bio);
- sync = bio_sync(bio);
/*
* low level driver can indicate that it wants pages above a
@@ -2944,8 +2921,6 @@ static int __make_request(request_queue_t *q, struct bio *bio)
*/
blk_queue_bounce(q, &bio);
- spin_lock_prefetch(q->queue_lock);
-
barrier = bio_barrier(bio);
if (unlikely(barrier) && (q->next_ordered == QUEUE_ORDERED_NONE)) {
err = -EOPNOTSUPP;
@@ -2973,7 +2948,7 @@ static int __make_request(request_queue_t *q, struct bio *bio)
req->ioprio = ioprio_best(req->ioprio, prio);
drive_stat_acct(req, nr_sectors, 0);
if (!attempt_back_merge(q, req))
- elv_merged_request(q, req);
+ elv_merged_request(q, req, el_ret);
goto out;
case ELEVATOR_FRONT_MERGE:
@@ -2993,14 +2968,14 @@ static int __make_request(request_queue_t *q, struct bio *bio)
* not touch req->buffer either...
*/
req->buffer = bio_data(bio);
- req->current_nr_sectors = cur_nr_sectors;
- req->hard_cur_sectors = cur_nr_sectors;
- req->sector = req->hard_sector = sector;
+ req->current_nr_sectors = bio_cur_sectors(bio);
+ req->hard_cur_sectors = req->current_nr_sectors;
+ req->sector = req->hard_sector = bio->bi_sector;
req->nr_sectors = req->hard_nr_sectors += nr_sectors;
req->ioprio = ioprio_best(req->ioprio, prio);
drive_stat_acct(req, nr_sectors, 0);
if (!attempt_front_merge(q, req))
- elv_merged_request(q, req);
+ elv_merged_request(q, req, el_ret);
goto out;
/* ELV_NO_MERGE: elevator says don't/can't merge. */
@@ -3013,7 +2988,7 @@ get_rq:
* Grab a free request. This is might sleep but can not fail.
* Returns with the queue unlocked.
*/
- req = get_request_wait(q, rw, bio);
+ req = get_request_wait(q, bio_data_dir(bio), bio);
/*
* After dropping the lock and possibly sleeping here, our request
@@ -3307,7 +3282,7 @@ static int __end_that_request_first(struct request *req, int uptodate,
req->errors = 0;
if (!uptodate) {
- if (blk_fs_request(req) && !(req->flags & REQ_QUIET))
+ if (blk_fs_request(req) && !(req->cmd_flags & REQ_QUIET))
printk("end_request: I/O error, dev %s, sector %llu\n",
req->rq_disk ? req->rq_disk->disk_name : "?",
(unsigned long long)req->sector);
@@ -3570,8 +3545,8 @@ EXPORT_SYMBOL(end_request);
void blk_rq_bio_prep(request_queue_t *q, struct request *rq, struct bio *bio)
{
- /* first two bits are identical in rq->flags and bio->bi_rw */
- rq->flags |= (bio->bi_rw & 3);
+ /* first two bits are identical in rq->cmd_flags and bio->bi_rw */
+ rq->cmd_flags |= (bio->bi_rw & 3);
rq->nr_phys_segments = bio_phys_segments(q, bio);
rq->nr_hw_segments = bio_hw_segments(q, bio);
@@ -3659,25 +3634,22 @@ EXPORT_SYMBOL(put_io_context);
/* Called by the exitting task */
void exit_io_context(void)
{
- unsigned long flags;
struct io_context *ioc;
struct cfq_io_context *cic;
- local_irq_save(flags);
task_lock(current);
ioc = current->io_context;
current->io_context = NULL;
- ioc->task = NULL;
task_unlock(current);
- local_irq_restore(flags);
+ ioc->task = NULL;
if (ioc->aic && ioc->aic->exit)
ioc->aic->exit(ioc->aic);
if (ioc->cic_root.rb_node != NULL) {
cic = rb_entry(rb_first(&ioc->cic_root), struct cfq_io_context, rb_node);
cic->exit(ioc);
}
-
+
put_io_context(ioc);
}
@@ -3689,7 +3661,7 @@ void exit_io_context(void)
* but since the current task itself holds a reference, the context can be
* used in general code, so long as it stays within `current` context.
*/
-struct io_context *current_io_context(gfp_t gfp_flags)
+static struct io_context *current_io_context(gfp_t gfp_flags, int node)
{
struct task_struct *tsk = current;
struct io_context *ret;
@@ -3698,11 +3670,11 @@ struct io_context *current_io_context(gfp_t gfp_flags)
if (likely(ret))
return ret;
- ret = kmem_cache_alloc(iocontext_cachep, gfp_flags);
+ ret = kmem_cache_alloc_node(iocontext_cachep, gfp_flags, node);
if (ret) {
atomic_set(&ret->refcount, 1);
ret->task = current;
- ret->set_ioprio = NULL;
+ ret->ioprio_changed = 0;
ret->last_waited = jiffies; /* doesn't matter... */
ret->nr_batch_requests = 0; /* because this is 0 */
ret->aic = NULL;
@@ -3722,10 +3694,10 @@ EXPORT_SYMBOL(current_io_context);
*
* This is always called in the context of the task which submitted the I/O.
*/
-struct io_context *get_io_context(gfp_t gfp_flags)
+struct io_context *get_io_context(gfp_t gfp_flags, int node)
{
struct io_context *ret;
- ret = current_io_context(gfp_flags);
+ ret = current_io_context(gfp_flags, node);
if (likely(ret))
atomic_inc(&ret->refcount);
return ret;
@@ -3838,9 +3810,6 @@ queue_ra_store(struct request_queue *q, const char *page, size_t count)
ssize_t ret = queue_var_store(&ra_kb, page, count);
spin_lock_irq(q->queue_lock);
- if (ra_kb > (q->max_sectors >> 1))
- ra_kb = (q->max_sectors >> 1);
-
q->backing_dev_info.ra_pages = ra_kb >> (PAGE_CACHE_SHIFT - 10);
spin_unlock_irq(q->queue_lock);
diff --git a/block/noop-iosched.c b/block/noop-iosched.c
index 56a7c620574f..79af43179421 100644
--- a/block/noop-iosched.c
+++ b/block/noop-iosched.c
@@ -69,7 +69,7 @@ static void *noop_init_queue(request_queue_t *q, elevator_t *e)
{
struct noop_data *nd;
- nd = kmalloc(sizeof(*nd), GFP_KERNEL);
+ nd = kmalloc_node(sizeof(*nd), GFP_KERNEL, q->node);
if (!nd)
return NULL;
INIT_LIST_HEAD(&nd->queue);
diff --git a/block/scsi_ioctl.c b/block/scsi_ioctl.c
index b33eda26e205..2dc326421a24 100644
--- a/block/scsi_ioctl.c
+++ b/block/scsi_ioctl.c
@@ -294,7 +294,7 @@ static int sg_io(struct file *file, request_queue_t *q,
rq->sense = sense;
rq->sense_len = 0;
- rq->flags |= REQ_BLOCK_PC;
+ rq->cmd_type = REQ_TYPE_BLOCK_PC;
bio = rq->bio;
/*
@@ -470,7 +470,7 @@ int sg_scsi_ioctl(struct file *file, struct request_queue *q,
memset(sense, 0, sizeof(sense));
rq->sense = sense;
rq->sense_len = 0;
- rq->flags |= REQ_BLOCK_PC;
+ rq->cmd_type = REQ_TYPE_BLOCK_PC;
blk_execute_rq(q, disk, rq, 0);
@@ -502,7 +502,7 @@ static int __blk_send_generic(request_queue_t *q, struct gendisk *bd_disk, int c
int err;
rq = blk_get_request(q, WRITE, __GFP_WAIT);
- rq->flags |= REQ_BLOCK_PC;
+ rq->cmd_type = REQ_TYPE_BLOCK_PC;
rq->data = NULL;
rq->data_len = 0;
rq->timeout = BLK_DEFAULT_TIMEOUT;
diff --git a/drivers/acpi/acpi_memhotplug.c b/drivers/acpi/acpi_memhotplug.c
index 1dda370f402b..98099de59b45 100644
--- a/drivers/acpi/acpi_memhotplug.c
+++ b/drivers/acpi/acpi_memhotplug.c
@@ -238,6 +238,10 @@ static int acpi_memory_enable_device(struct acpi_memory_device *mem_device)
num_enabled++;
continue;
}
+
+ if (node < 0)
+ node = memory_add_physaddr_to_nid(info->start_addr);
+
result = add_memory(node, info->start_addr, info->length);
if (result)
continue;
diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c
index 71066066d626..0a395fca843b 100644
--- a/drivers/acpi/processor_idle.c
+++ b/drivers/acpi/processor_idle.c
@@ -38,6 +38,7 @@
#include <linux/dmi.h>
#include <linux/moduleparam.h>
#include <linux/sched.h> /* need_resched() */
+#include <linux/latency.h>
#include <asm/io.h>
#include <asm/uaccess.h>
@@ -453,7 +454,8 @@ static void acpi_processor_idle(void)
*/
if (cx->promotion.state &&
((cx->promotion.state - pr->power.states) <= max_cstate)) {
- if (sleep_ticks > cx->promotion.threshold.ticks) {
+ if (sleep_ticks > cx->promotion.threshold.ticks &&
+ cx->promotion.state->latency <= system_latency_constraint()) {
cx->promotion.count++;
cx->demotion.count = 0;
if (cx->promotion.count >=
@@ -494,8 +496,10 @@ static void acpi_processor_idle(void)
end:
/*
* Demote if current state exceeds max_cstate
+ * or if the latency of the current state is unacceptable
*/
- if ((pr->power.state - pr->power.states) > max_cstate) {
+ if ((pr->power.state - pr->power.states) > max_cstate ||
+ pr->power.state->latency > system_latency_constraint()) {
if (cx->demotion.state)
next_state = cx->demotion.state;
}
@@ -1009,9 +1013,11 @@ static int acpi_processor_power_seq_show(struct seq_file *seq, void *offset)
seq_printf(seq, "active state: C%zd\n"
"max_cstate: C%d\n"
- "bus master activity: %08x\n",
+ "bus master activity: %08x\n"
+ "maximum allowed latency: %d usec\n",
pr->power.state ? pr->power.state - pr->power.states : 0,
- max_cstate, (unsigned)pr->power.bm_activity);
+ max_cstate, (unsigned)pr->power.bm_activity,
+ system_latency_constraint());
seq_puts(seq, "states:\n");
@@ -1077,6 +1083,28 @@ static const struct file_operations acpi_processor_power_fops = {
.release = single_release,
};
+static void smp_callback(void *v)
+{
+ /* we already woke the CPU up, nothing more to do */
+}
+
+/*
+ * This function gets called when a part of the kernel has a new latency
+ * requirement. This means we need to get all processors out of their C-state,
+ * and then recalculate a new suitable C-state. Just do a cross-cpu IPI; that
+ * wakes them all right up.
+ */
+static int acpi_processor_latency_notify(struct notifier_block *b,
+ unsigned long l, void *v)
+{
+ smp_call_function(smp_callback, NULL, 0, 1);
+ return NOTIFY_OK;
+}
+
+static struct notifier_block acpi_processor_latency_notifier = {
+ .notifier_call = acpi_processor_latency_notify,
+};
+
int acpi_processor_power_init(struct acpi_processor *pr,
struct acpi_device *device)
{
@@ -1093,6 +1121,7 @@ int acpi_processor_power_init(struct acpi_processor *pr,
"ACPI: processor limited to max C-state %d\n",
max_cstate);
first_run++;
+ register_latency_notifier(&acpi_processor_latency_notifier);
}
if (!pr)
@@ -1164,6 +1193,7 @@ int acpi_processor_power_exit(struct acpi_processor *pr,
* copies of pm_idle before proceeding.
*/
cpu_idle_wait();
+ unregister_latency_notifier(&acpi_processor_latency_notifier);
}
return 0;
diff --git a/drivers/ata/pata_hpt366.c b/drivers/ata/pata_hpt366.c
index cf656ecbe507..8c757438f350 100644
--- a/drivers/ata/pata_hpt366.c
+++ b/drivers/ata/pata_hpt366.c
@@ -429,7 +429,7 @@ static int hpt36x_init_one(struct pci_dev *dev, const struct pci_device_id *id)
/* PCI clocking determines the ATA timing values to use */
/* info_hpt366 is safe against re-entry so we can scribble on it */
- switch(reg1 & 0x700) {
+ switch((reg1 & 0x700) >> 8) {
case 5:
info_hpt366.private_data = &hpt366_40;
break;
diff --git a/drivers/base/Makefile b/drivers/base/Makefile
index b539e5e75b56..7bbb9eeda235 100644
--- a/drivers/base/Makefile
+++ b/drivers/base/Makefile
@@ -8,7 +8,7 @@ obj-y += power/
obj-$(CONFIG_ISA) += isa.o
obj-$(CONFIG_FW_LOADER) += firmware_class.o
obj-$(CONFIG_NUMA) += node.o
-obj-$(CONFIG_MEMORY_HOTPLUG) += memory.o
+obj-$(CONFIG_MEMORY_HOTPLUG_SPARSE) += memory.o
obj-$(CONFIG_SMP) += topology.o
obj-$(CONFIG_SYS_HYPERVISOR) += hypervisor.o
diff --git a/drivers/base/class.c b/drivers/base/class.c
index b06b0e2b9c62..b32b77ff2dcd 100644
--- a/drivers/base/class.c
+++ b/drivers/base/class.c
@@ -228,7 +228,7 @@ error:
/**
* class_destroy - destroys a struct class structure
- * @cs: pointer to the struct class that is to be destroyed
+ * @cls: pointer to the struct class that is to be destroyed
*
* Note, the pointer to be destroyed must have been created with a call
* to class_create().
@@ -658,9 +658,9 @@ int class_device_register(struct class_device *class_dev)
/**
* class_device_create - creates a class device and registers it with sysfs
- * @cs: pointer to the struct class that this device should be registered to.
+ * @cls: pointer to the struct class that this device should be registered to.
* @parent: pointer to the parent struct class_device of this new device, if any.
- * @dev: the dev_t for the char device to be added.
+ * @devt: the dev_t for the char device to be added.
* @device: a pointer to a struct device that is assiociated with this class device.
* @fmt: string for the class device's name
*
@@ -766,7 +766,7 @@ void class_device_unregister(struct class_device *class_dev)
/**
* class_device_destroy - removes a class device that was created with class_device_create()
* @cls: the pointer to the struct class that this device was registered * with.
- * @dev: the dev_t of the device that was previously registered.
+ * @devt: the dev_t of the device that was previously registered.
*
* This call unregisters and cleans up a class device that was created with a
* call to class_device_create()
diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c
index 77bf8826e2f9..14615694ae9a 100644
--- a/drivers/base/firmware_class.c
+++ b/drivers/base/firmware_class.c
@@ -16,6 +16,7 @@
#include <linux/interrupt.h>
#include <linux/bitops.h>
#include <linux/mutex.h>
+#include <linux/kthread.h>
#include <linux/firmware.h>
#include "base.h"
@@ -511,7 +512,6 @@ request_firmware_work_func(void *arg)
WARN_ON(1);
return 0;
}
- daemonize("%s/%s", "firmware", fw_work->name);
ret = _request_firmware(&fw, fw_work->name, fw_work->device,
fw_work->uevent);
if (ret < 0)
@@ -546,9 +546,9 @@ request_firmware_nowait(
const char *name, struct device *device, void *context,
void (*cont)(const struct firmware *fw, void *context))
{
+ struct task_struct *task;
struct firmware_work *fw_work = kmalloc(sizeof (struct firmware_work),
GFP_ATOMIC);
- int ret;
if (!fw_work)
return -ENOMEM;
@@ -566,14 +566,14 @@ request_firmware_nowait(
.uevent = uevent,
};
- ret = kernel_thread(request_firmware_work_func, fw_work,
- CLONE_FS | CLONE_FILES);
+ task = kthread_run(request_firmware_work_func, fw_work,
+ "firmware/%s", name);
- if (ret < 0) {
+ if (IS_ERR(task)) {
fw_work->cont(NULL, fw_work->context);
module_put(fw_work->module);
kfree(fw_work);
- return ret;
+ return PTR_ERR(task);
}
return 0;
}
diff --git a/drivers/block/DAC960.c b/drivers/block/DAC960.c
index a360215dbce7..b3f639fbf220 100644
--- a/drivers/block/DAC960.c
+++ b/drivers/block/DAC960.c
@@ -770,7 +770,7 @@ static void DAC960_P_QueueCommand(DAC960_Command_T *Command)
static void DAC960_ExecuteCommand(DAC960_Command_T *Command)
{
DAC960_Controller_T *Controller = Command->Controller;
- DECLARE_COMPLETION(Completion);
+ DECLARE_COMPLETION_ONSTACK(Completion);
unsigned long flags;
Command->Completion = &Completion;
@@ -3331,7 +3331,7 @@ static int DAC960_process_queue(DAC960_Controller_T *Controller, struct request_
Command->DmaDirection = PCI_DMA_TODEVICE;
Command->CommandType = DAC960_WriteCommand;
}
- Command->Completion = Request->waiting;
+ Command->Completion = Request->end_io_data;
Command->LogicalDriveNumber = (long)Request->rq_disk->private_data;
Command->BlockNumber = Request->sector;
Command->BlockCount = Request->nr_sectors;
diff --git a/drivers/block/DAC960.h b/drivers/block/DAC960.h
index a82f37f749a5..f9217c34bc2b 100644
--- a/drivers/block/DAC960.h
+++ b/drivers/block/DAC960.h
@@ -71,7 +71,7 @@
Define a Boolean data type.
*/
-typedef enum { false, true } __attribute__ ((packed)) boolean;
+typedef bool boolean;
/*
diff --git a/drivers/block/Kconfig b/drivers/block/Kconfig
index b5382cedf0c0..422e31d5f8e5 100644
--- a/drivers/block/Kconfig
+++ b/drivers/block/Kconfig
@@ -2,6 +2,8 @@
# Block device driver configuration
#
+if BLOCK
+
menu "Block devices"
config BLK_DEV_FD
@@ -468,3 +470,5 @@ config ATA_OVER_ETH
devices like the Coraid EtherDrive (R) Storage Blade.
endmenu
+
+endif
diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c
index 2cd3391ff878..99f87efe0f58 100644
--- a/drivers/block/cciss.c
+++ b/drivers/block/cciss.c
@@ -144,13 +144,13 @@ static int rebuild_lun_table(ctlr_info_t *h, struct gendisk *del_disk);
static int deregister_disk(struct gendisk *disk, drive_info_struct *drv,
int clear_all);
-static void cciss_read_capacity(int ctlr, int logvol, ReadCapdata_struct *buf,
- int withirq, unsigned int *total_size,
- unsigned int *block_size);
-static void cciss_geometry_inquiry(int ctlr, int logvol, int withirq,
- unsigned int total_size,
- unsigned int block_size,
- InquiryData_struct *inq_buff,
+static void cciss_read_capacity(int ctlr, int logvol, int withirq,
+ sector_t *total_size, unsigned int *block_size);
+static void cciss_read_capacity_16(int ctlr, int logvol, int withirq,
+ sector_t *total_size, unsigned int *block_size);
+static void cciss_geometry_inquiry(int ctlr, int logvol,
+ int withirq, sector_t total_size,
+ unsigned int block_size, InquiryData_struct *inq_buff,
drive_info_struct *drv);
static void cciss_getgeometry(int cntl_num);
static void __devinit cciss_interrupt_mode(ctlr_info_t *, struct pci_dev *,
@@ -879,7 +879,7 @@ static int cciss_ioctl(struct inode *inode, struct file *filep,
char *buff = NULL;
u64bit temp64;
unsigned long flags;
- DECLARE_COMPLETION(wait);
+ DECLARE_COMPLETION_ONSTACK(wait);
if (!arg)
return -EINVAL;
@@ -997,7 +997,7 @@ static int cciss_ioctl(struct inode *inode, struct file *filep,
BYTE sg_used = 0;
int status = 0;
int i;
- DECLARE_COMPLETION(wait);
+ DECLARE_COMPLETION_ONSTACK(wait);
__u32 left;
__u32 sz;
BYTE __user *data_ptr;
@@ -1229,7 +1229,6 @@ static inline void complete_buffers(struct bio *bio, int status)
int nr_sectors = bio_sectors(bio);
bio->bi_next = NULL;
- blk_finished_io(len);
bio_endio(bio, nr_sectors << 9, status ? 0 : -EIO);
bio = xbh;
}
@@ -1326,10 +1325,9 @@ static void cciss_update_drive_info(int ctlr, int drv_index)
{
ctlr_info_t *h = hba[ctlr];
struct gendisk *disk;
- ReadCapdata_struct *size_buff = NULL;
InquiryData_struct *inq_buff = NULL;
unsigned int block_size;
- unsigned int total_size;
+ sector_t total_size;
unsigned long flags = 0;
int ret = 0;
@@ -1348,15 +1346,25 @@ static void cciss_update_drive_info(int ctlr, int drv_index)
return;
/* Get information about the disk and modify the driver structure */
- size_buff = kmalloc(sizeof(ReadCapdata_struct), GFP_KERNEL);
- if (size_buff == NULL)
- goto mem_msg;
inq_buff = kmalloc(sizeof(InquiryData_struct), GFP_KERNEL);
if (inq_buff == NULL)
goto mem_msg;
- cciss_read_capacity(ctlr, drv_index, size_buff, 1,
+ cciss_read_capacity(ctlr, drv_index, 1,
&total_size, &block_size);
+
+ /* total size = last LBA + 1 */
+ /* FFFFFFFF + 1 = 0, cannot have a logical volume of size 0 */
+ /* so we assume this volume this must be >2TB in size */
+ if (total_size == (__u32) 0) {
+ cciss_read_capacity_16(ctlr, drv_index, 1,
+ &total_size, &block_size);
+ h->cciss_read = CCISS_READ_16;
+ h->cciss_write = CCISS_WRITE_16;
+ } else {
+ h->cciss_read = CCISS_READ_10;
+ h->cciss_write = CCISS_WRITE_10;
+ }
cciss_geometry_inquiry(ctlr, drv_index, 1, total_size, block_size,
inq_buff, &h->drv[drv_index]);
@@ -1392,7 +1400,6 @@ static void cciss_update_drive_info(int ctlr, int drv_index)
}
freeret:
- kfree(size_buff);
kfree(inq_buff);
return;
mem_msg:
@@ -1717,6 +1724,22 @@ static int fill_cmd(CommandList_struct *c, __u8 cmd, int ctlr, void *buff, size_
c->Request.Timeout = 0;
c->Request.CDB[0] = cmd;
break;
+ case CCISS_READ_CAPACITY_16:
+ c->Header.LUN.LogDev.VolId = h->drv[log_unit].LunID;
+ c->Header.LUN.LogDev.Mode = 1;
+ c->Request.CDBLen = 16;
+ c->Request.Type.Attribute = ATTR_SIMPLE;
+ c->Request.Type.Direction = XFER_READ;
+ c->Request.Timeout = 0;
+ c->Request.CDB[0] = cmd;
+ c->Request.CDB[1] = 0x10;
+ c->Request.CDB[10] = (size >> 24) & 0xFF;
+ c->Request.CDB[11] = (size >> 16) & 0xFF;
+ c->Request.CDB[12] = (size >> 8) & 0xFF;
+ c->Request.CDB[13] = size & 0xFF;
+ c->Request.Timeout = 0;
+ c->Request.CDB[0] = cmd;
+ break;
case CCISS_CACHE_FLUSH:
c->Request.CDBLen = 12;
c->Request.Type.Attribute = ATTR_SIMPLE;
@@ -1750,6 +1773,7 @@ static int fill_cmd(CommandList_struct *c, __u8 cmd, int ctlr, void *buff, size_
memset(&c->Request.CDB[0], 0, sizeof(c->Request.CDB));
c->Request.CDB[0] = cmd; /* reset */
c->Request.CDB[1] = 0x04; /* reset a LUN */
+ break;
case 3: /* No-Op message */
c->Request.CDBLen = 1;
c->Request.Type.Attribute = ATTR_SIMPLE;
@@ -1792,7 +1816,7 @@ static int sendcmd_withirq(__u8 cmd,
u64bit buff_dma_handle;
unsigned long flags;
int return_status;
- DECLARE_COMPLETION(wait);
+ DECLARE_COMPLETION_ONSTACK(wait);
if ((c = cmd_alloc(h, 0)) == NULL)
return -ENOMEM;
@@ -1893,12 +1917,15 @@ static int sendcmd_withirq(__u8 cmd,
}
static void cciss_geometry_inquiry(int ctlr, int logvol,
- int withirq, unsigned int total_size,
+ int withirq, sector_t total_size,
unsigned int block_size,
InquiryData_struct *inq_buff,
drive_info_struct *drv)
{
int return_code;
+ unsigned long t;
+ unsigned long rem;
+
memset(inq_buff, 0, sizeof(InquiryData_struct));
if (withirq)
return_code = sendcmd_withirq(CISS_INQUIRY, ctlr,
@@ -1917,10 +1944,10 @@ static void cciss_geometry_inquiry(int ctlr, int logvol,
drv->nr_blocks = total_size;
drv->heads = 255;
drv->sectors = 32; // Sectors per track
- drv->cylinders = total_size / 255 / 32;
+ t = drv->heads * drv->sectors;
+ drv->cylinders = total_size;
+ rem = do_div(drv->cylinders, t);
} else {
- unsigned int t;
-
drv->block_size = block_size;
drv->nr_blocks = total_size;
drv->heads = inq_buff->data_byte[6];
@@ -1930,42 +1957,84 @@ static void cciss_geometry_inquiry(int ctlr, int logvol,
drv->raid_level = inq_buff->data_byte[8];
t = drv->heads * drv->sectors;
if (t > 1) {
- drv->cylinders = total_size / t;
+ drv->cylinders = total_size;
+ rem = do_div(drv->cylinders, t);
}
}
} else { /* Get geometry failed */
printk(KERN_WARNING "cciss: reading geometry failed\n");
}
- printk(KERN_INFO " heads= %d, sectors= %d, cylinders= %d\n\n",
+ printk(KERN_INFO " heads=%d, sectors=%d, cylinders=%d\n\n",
drv->heads, drv->sectors, drv->cylinders);
}
static void
-cciss_read_capacity(int ctlr, int logvol, ReadCapdata_struct *buf,
- int withirq, unsigned int *total_size,
+cciss_read_capacity(int ctlr, int logvol, int withirq, sector_t *total_size,
unsigned int *block_size)
{
+ ReadCapdata_struct *buf;
int return_code;
- memset(buf, 0, sizeof(*buf));
+ buf = kmalloc(sizeof(ReadCapdata_struct), GFP_KERNEL);
+ if (buf == NULL) {
+ printk(KERN_WARNING "cciss: out of memory\n");
+ return;
+ }
+ memset(buf, 0, sizeof(ReadCapdata_struct));
if (withirq)
return_code = sendcmd_withirq(CCISS_READ_CAPACITY,
- ctlr, buf, sizeof(*buf), 1,
- logvol, 0, TYPE_CMD);
+ ctlr, buf, sizeof(ReadCapdata_struct),
+ 1, logvol, 0, TYPE_CMD);
else
return_code = sendcmd(CCISS_READ_CAPACITY,
- ctlr, buf, sizeof(*buf), 1, logvol, 0,
- NULL, TYPE_CMD);
+ ctlr, buf, sizeof(ReadCapdata_struct),
+ 1, logvol, 0, NULL, TYPE_CMD);
if (return_code == IO_OK) {
- *total_size =
- be32_to_cpu(*((__be32 *) & buf->total_size[0])) + 1;
- *block_size = be32_to_cpu(*((__be32 *) & buf->block_size[0]));
+ *total_size = be32_to_cpu(*(__u32 *) buf->total_size)+1;
+ *block_size = be32_to_cpu(*(__u32 *) buf->block_size);
} else { /* read capacity command failed */
printk(KERN_WARNING "cciss: read capacity failed\n");
*total_size = 0;
*block_size = BLOCK_SIZE;
}
- printk(KERN_INFO " blocks= %u block_size= %d\n",
+ if (*total_size != (__u32) 0)
+ printk(KERN_INFO " blocks= %lld block_size= %d\n",
+ *total_size, *block_size);
+ kfree(buf);
+ return;
+}
+
+static void
+cciss_read_capacity_16(int ctlr, int logvol, int withirq, sector_t *total_size, unsigned int *block_size)
+{
+ ReadCapdata_struct_16 *buf;
+ int return_code;
+ buf = kmalloc(sizeof(ReadCapdata_struct_16), GFP_KERNEL);
+ if (buf == NULL) {
+ printk(KERN_WARNING "cciss: out of memory\n");
+ return;
+ }
+ memset(buf, 0, sizeof(ReadCapdata_struct_16));
+ if (withirq) {
+ return_code = sendcmd_withirq(CCISS_READ_CAPACITY_16,
+ ctlr, buf, sizeof(ReadCapdata_struct_16),
+ 1, logvol, 0, TYPE_CMD);
+ }
+ else {
+ return_code = sendcmd(CCISS_READ_CAPACITY_16,
+ ctlr, buf, sizeof(ReadCapdata_struct_16),
+ 1, logvol, 0, NULL, TYPE_CMD);
+ }
+ if (return_code == IO_OK) {
+ *total_size = be64_to_cpu(*(__u64 *) buf->total_size)+1;
+ *block_size = be32_to_cpu(*(__u32 *) buf->block_size);
+ } else { /* read capacity command failed */
+ printk(KERN_WARNING "cciss: read capacity failed\n");
+ *total_size = 0;
+ *block_size = BLOCK_SIZE;
+ }
+ printk(KERN_INFO " blocks= %lld block_size= %d\n",
*total_size, *block_size);
+ kfree(buf);
return;
}
@@ -1976,8 +2045,7 @@ static int cciss_revalidate(struct gendisk *disk)
int logvol;
int FOUND = 0;
unsigned int block_size;
- unsigned int total_size;
- ReadCapdata_struct *size_buff = NULL;
+ sector_t total_size;
InquiryData_struct *inq_buff = NULL;
for (logvol = 0; logvol < CISS_MAX_LUN; logvol++) {
@@ -1990,27 +2058,24 @@ static int cciss_revalidate(struct gendisk *disk)
if (!FOUND)
return 1;
- size_buff = kmalloc(sizeof(ReadCapdata_struct), GFP_KERNEL);
- if (size_buff == NULL) {
- printk(KERN_WARNING "cciss: out of memory\n");
- return 1;
- }
inq_buff = kmalloc(sizeof(InquiryData_struct), GFP_KERNEL);
if (inq_buff == NULL) {
printk(KERN_WARNING "cciss: out of memory\n");
- kfree(size_buff);
return 1;
}
-
- cciss_read_capacity(h->ctlr, logvol, size_buff, 1, &total_size,
- &block_size);
+ if (h->cciss_read == CCISS_READ_10) {
+ cciss_read_capacity(h->ctlr, logvol, 1,
+ &total_size, &block_size);
+ } else {
+ cciss_read_capacity_16(h->ctlr, logvol, 1,
+ &total_size, &block_size);
+ }
cciss_geometry_inquiry(h->ctlr, logvol, 1, total_size, block_size,
inq_buff, drv);
blk_queue_hardsect_size(drv->queue, drv->block_size);
set_capacity(disk, drv->nr_blocks);
- kfree(size_buff);
kfree(inq_buff);
return 0;
}
@@ -2419,7 +2484,8 @@ static void do_cciss_request(request_queue_t *q)
{
ctlr_info_t *h = q->queuedata;
CommandList_struct *c;
- int start_blk, seg;
+ sector_t start_blk;
+ int seg;
struct request *creq;
u64bit temp64;
struct scatterlist tmp_sg[MAXSGENTRIES];
@@ -2463,10 +2529,10 @@ static void do_cciss_request(request_queue_t *q)
c->Request.Type.Type = TYPE_CMD; // It is a command.
c->Request.Type.Attribute = ATTR_SIMPLE;
c->Request.Type.Direction =
- (rq_data_dir(creq) == READ) ? XFER_READ : XFER_WRITE;
+ (rq_data_dir(creq) == READ) ? h->cciss_read : h->cciss_write;
c->Request.Timeout = 0; // Don't time out
c->Request.CDB[0] =
- (rq_data_dir(creq) == READ) ? CCISS_READ : CCISS_WRITE;
+ (rq_data_dir(creq) == READ) ? h->cciss_read : h->cciss_write;
start_blk = creq->sector;
#ifdef CCISS_DEBUG
printk(KERN_DEBUG "ciss: sector =%d nr_sectors=%d\n", (int)creq->sector,
@@ -2500,15 +2566,33 @@ static void do_cciss_request(request_queue_t *q)
#endif /* CCISS_DEBUG */
c->Header.SGList = c->Header.SGTotal = seg;
- c->Request.CDB[1] = 0;
- c->Request.CDB[2] = (start_blk >> 24) & 0xff; //MSB
- c->Request.CDB[3] = (start_blk >> 16) & 0xff;
- c->Request.CDB[4] = (start_blk >> 8) & 0xff;
- c->Request.CDB[5] = start_blk & 0xff;
- c->Request.CDB[6] = 0; // (sect >> 24) & 0xff; MSB
- c->Request.CDB[7] = (creq->nr_sectors >> 8) & 0xff;
- c->Request.CDB[8] = creq->nr_sectors & 0xff;
- c->Request.CDB[9] = c->Request.CDB[11] = c->Request.CDB[12] = 0;
+ if(h->cciss_read == CCISS_READ_10) {
+ c->Request.CDB[1] = 0;
+ c->Request.CDB[2] = (start_blk >> 24) & 0xff; //MSB
+ c->Request.CDB[3] = (start_blk >> 16) & 0xff;
+ c->Request.CDB[4] = (start_blk >> 8) & 0xff;
+ c->Request.CDB[5] = start_blk & 0xff;
+ c->Request.CDB[6] = 0; // (sect >> 24) & 0xff; MSB
+ c->Request.CDB[7] = (creq->nr_sectors >> 8) & 0xff;
+ c->Request.CDB[8] = creq->nr_sectors & 0xff;
+ c->Request.CDB[9] = c->Request.CDB[11] = c->Request.CDB[12] = 0;
+ } else {
+ c->Request.CDBLen = 16;
+ c->Request.CDB[1]= 0;
+ c->Request.CDB[2]= (start_blk >> 56) & 0xff; //MSB
+ c->Request.CDB[3]= (start_blk >> 48) & 0xff;
+ c->Request.CDB[4]= (start_blk >> 40) & 0xff;
+ c->Request.CDB[5]= (start_blk >> 32) & 0xff;
+ c->Request.CDB[6]= (start_blk >> 24) & 0xff;
+ c->Request.CDB[7]= (start_blk >> 16) & 0xff;
+ c->Request.CDB[8]= (start_blk >> 8) & 0xff;
+ c->Request.CDB[9]= start_blk & 0xff;
+ c->Request.CDB[10]= (creq->nr_sectors >> 24) & 0xff;
+ c->Request.CDB[11]= (creq->nr_sectors >> 16) & 0xff;
+ c->Request.CDB[12]= (creq->nr_sectors >> 8) & 0xff;
+ c->Request.CDB[13]= creq->nr_sectors & 0xff;
+ c->Request.CDB[14] = c->Request.CDB[15] = 0;
+ }
spin_lock_irq(q->queue_lock);
@@ -2518,9 +2602,9 @@ static void do_cciss_request(request_queue_t *q)
h->maxQsinceinit = h->Qdepth;
goto queue;
- full:
+full:
blk_stop_queue(q);
- startio:
+startio:
/* We will already have the driver lock here so not need
* to lock it.
*/
@@ -2948,31 +3032,23 @@ static int cciss_pci_init(ctlr_info_t *c, struct pci_dev *pdev)
static void cciss_getgeometry(int cntl_num)
{
ReportLunData_struct *ld_buff;
- ReadCapdata_struct *size_buff;
InquiryData_struct *inq_buff;
int return_code;
int i;
int listlength = 0;
__u32 lunid = 0;
int block_size;
- int total_size;
+ sector_t total_size;
ld_buff = kzalloc(sizeof(ReportLunData_struct), GFP_KERNEL);
if (ld_buff == NULL) {
printk(KERN_ERR "cciss: out of memory\n");
return;
}
- size_buff = kmalloc(sizeof(ReadCapdata_struct), GFP_KERNEL);
- if (size_buff == NULL) {
- printk(KERN_ERR "cciss: out of memory\n");
- kfree(ld_buff);
- return;
- }
inq_buff = kmalloc(sizeof(InquiryData_struct), GFP_KERNEL);
if (inq_buff == NULL) {
printk(KERN_ERR "cciss: out of memory\n");
kfree(ld_buff);
- kfree(size_buff);
return;
}
/* Get the firmware version */
@@ -3027,7 +3103,6 @@ static void cciss_getgeometry(int cntl_num)
#endif /* CCISS_DEBUG */
hba[cntl_num]->highest_lun = hba[cntl_num]->num_luns - 1;
-// for(i=0; i< hba[cntl_num]->num_luns; i++)
for (i = 0; i < CISS_MAX_LUN; i++) {
if (i < hba[cntl_num]->num_luns) {
lunid = (0xff & (unsigned int)(ld_buff->LUN[i][3]))
@@ -3046,8 +3121,26 @@ static void cciss_getgeometry(int cntl_num)
ld_buff->LUN[i][2], ld_buff->LUN[i][3],
hba[cntl_num]->drv[i].LunID);
#endif /* CCISS_DEBUG */
- cciss_read_capacity(cntl_num, i, size_buff, 0,
+
+ /* testing to see if 16-byte CDBs are already being used */
+ if(hba[cntl_num]->cciss_read == CCISS_READ_16) {
+ cciss_read_capacity_16(cntl_num, i, 0,
&total_size, &block_size);
+ goto geo_inq;
+ }
+ cciss_read_capacity(cntl_num, i, 0, &total_size, &block_size);
+
+ /* total_size = last LBA + 1 */
+ if(total_size == (__u32) 0) {
+ cciss_read_capacity_16(cntl_num, i, 0,
+ &total_size, &block_size);
+ hba[cntl_num]->cciss_read = CCISS_READ_16;
+ hba[cntl_num]->cciss_write = CCISS_WRITE_16;
+ } else {
+ hba[cntl_num]->cciss_read = CCISS_READ_10;
+ hba[cntl_num]->cciss_write = CCISS_WRITE_10;
+ }
+geo_inq:
cciss_geometry_inquiry(cntl_num, i, 0, total_size,
block_size, inq_buff,
&hba[cntl_num]->drv[i]);
@@ -3057,7 +3150,6 @@ static void cciss_getgeometry(int cntl_num)
}
}
kfree(ld_buff);
- kfree(size_buff);
kfree(inq_buff);
}
diff --git a/drivers/block/cciss.h b/drivers/block/cciss.h
index 868e0d862b0d..562235c1445a 100644
--- a/drivers/block/cciss.h
+++ b/drivers/block/cciss.h
@@ -76,6 +76,9 @@ struct ctlr_info
unsigned int intr[4];
unsigned int msix_vector;
unsigned int msi_vector;
+ BYTE cciss_read;
+ BYTE cciss_write;
+ BYTE cciss_read_capacity;
// information about each logical volume
drive_info_struct drv[CISS_MAX_LUN];
diff --git a/drivers/block/cciss_cmd.h b/drivers/block/cciss_cmd.h
index 53fea549ba8b..4af7c4c0c7af 100644
--- a/drivers/block/cciss_cmd.h
+++ b/drivers/block/cciss_cmd.h
@@ -118,11 +118,34 @@ typedef struct _ReadCapdata_struct
BYTE block_size[4]; // Size of blocks in bytes
} ReadCapdata_struct;
-// 12 byte commands not implemented in firmware yet.
-// #define CCISS_READ 0xa8 // Read(12)
-// #define CCISS_WRITE 0xaa // Write(12)
- #define CCISS_READ 0x28 // Read(10)
- #define CCISS_WRITE 0x2a // Write(10)
+#define CCISS_READ_CAPACITY_16 0x9e /* Read Capacity 16 */
+
+/* service action to differentiate a 16 byte read capacity from
+ other commands that use the 0x9e SCSI op code */
+
+#define CCISS_READ_CAPACITY_16_SERVICE_ACT 0x10
+
+typedef struct _ReadCapdata_struct_16
+{
+ BYTE total_size[8]; /* Total size in blocks */
+ BYTE block_size[4]; /* Size of blocks in bytes */
+ BYTE prot_en:1; /* protection enable bit */
+ BYTE rto_en:1; /* reference tag own enable bit */
+ BYTE reserved:6; /* reserved bits */
+ BYTE reserved2[18]; /* reserved bytes per spec */
+} ReadCapdata_struct_16;
+
+/* Define the supported read/write commands for cciss based controllers */
+
+#define CCISS_READ_10 0x28 /* Read(10) */
+#define CCISS_WRITE_10 0x2a /* Write(10) */
+#define CCISS_READ_16 0x88 /* Read(16) */
+#define CCISS_WRITE_16 0x8a /* Write(16) */
+
+/* Define the CDB lengths supported by cciss based controllers */
+
+#define CDB_LEN10 10
+#define CDB_LEN16 16
// BMIC commands
#define BMIC_READ 0x26
diff --git a/drivers/block/cciss_scsi.c b/drivers/block/cciss_scsi.c
index 05f79d7393f7..bb15051ffbe0 100644
--- a/drivers/block/cciss_scsi.c
+++ b/drivers/block/cciss_scsi.c
@@ -766,7 +766,7 @@ cciss_scsi_do_simple_cmd(ctlr_info_t *c,
int direction)
{
unsigned long flags;
- DECLARE_COMPLETION(wait);
+ DECLARE_COMPLETION_ONSTACK(wait);
cp->cmd_type = CMD_IOCTL_PEND; // treat this like an ioctl
cp->scsi_cmd = NULL;
diff --git a/drivers/block/cpqarray.c b/drivers/block/cpqarray.c
index 78082edc14b4..4abc193314ee 100644
--- a/drivers/block/cpqarray.c
+++ b/drivers/block/cpqarray.c
@@ -989,7 +989,6 @@ static inline void complete_buffers(struct bio *bio, int ok)
xbh = bio->bi_next;
bio->bi_next = NULL;
- blk_finished_io(nr_sectors);
bio_endio(bio, nr_sectors << 9, ok ? 0 : -EIO);
bio = xbh;
diff --git a/drivers/block/floppy.c b/drivers/block/floppy.c
index ad1d7065a1b2..629c5769d994 100644
--- a/drivers/block/floppy.c
+++ b/drivers/block/floppy.c
@@ -2991,8 +2991,8 @@ static void do_fd_request(request_queue_t * q)
if (usage_count == 0) {
printk("warning: usage count=0, current_req=%p exiting\n",
current_req);
- printk("sect=%ld flags=%lx\n", (long)current_req->sector,
- current_req->flags);
+ printk("sect=%ld type=%x flags=%x\n", (long)current_req->sector,
+ current_req->cmd_type, current_req->cmd_flags);
return;
}
if (test_bit(0, &fdc_busy)) {
diff --git a/drivers/block/loop.c b/drivers/block/loop.c
index c774121684d7..d6bb8da955a2 100644
--- a/drivers/block/loop.c
+++ b/drivers/block/loop.c
@@ -66,12 +66,14 @@
#include <linux/swap.h>
#include <linux/slab.h>
#include <linux/loop.h>
+#include <linux/compat.h>
#include <linux/suspend.h>
#include <linux/writeback.h>
#include <linux/buffer_head.h> /* for invalidate_bdev() */
#include <linux/completion.h>
#include <linux/highmem.h>
#include <linux/gfp.h>
+#include <linux/kthread.h>
#include <asm/uaccess.h>
@@ -522,15 +524,12 @@ static int loop_make_request(request_queue_t *q, struct bio *old_bio)
goto out;
if (unlikely(rw == WRITE && (lo->lo_flags & LO_FLAGS_READ_ONLY)))
goto out;
- lo->lo_pending++;
loop_add_bio(lo, old_bio);
+ wake_up(&lo->lo_event);
spin_unlock_irq(&lo->lo_lock);
- complete(&lo->lo_bh_done);
return 0;
out:
- if (lo->lo_pending == 0)
- complete(&lo->lo_bh_done);
spin_unlock_irq(&lo->lo_lock);
bio_io_error(old_bio, old_bio->bi_size);
return 0;
@@ -570,14 +569,18 @@ static inline void loop_handle_bio(struct loop_device *lo, struct bio *bio)
* to avoid blocking in our make_request_fn. it also does loop decrypting
* on reads for block backed loop, as that is too heavy to do from
* b_end_io context where irqs may be disabled.
+ *
+ * Loop explanation: loop_clr_fd() sets lo_state to Lo_rundown before
+ * calling kthread_stop(). Therefore once kthread_should_stop() is
+ * true, make_request will not place any more requests. Therefore
+ * once kthread_should_stop() is true and lo_bio is NULL, we are
+ * done with the loop.
*/
static int loop_thread(void *data)
{
struct loop_device *lo = data;
struct bio *bio;
- daemonize("loop%d", lo->lo_number);
-
/*
* loop can be used in an encrypted device,
* hence, it mustn't be stopped at all
@@ -587,47 +590,21 @@ static int loop_thread(void *data)
set_user_nice(current, -20);
- lo->lo_state = Lo_bound;
- lo->lo_pending = 1;
+ while (!kthread_should_stop() || lo->lo_bio) {
- /*
- * complete it, we are running
- */
- complete(&lo->lo_done);
-
- for (;;) {
- int pending;
+ wait_event_interruptible(lo->lo_event,
+ lo->lo_bio || kthread_should_stop());
- if (wait_for_completion_interruptible(&lo->lo_bh_done))
+ if (!lo->lo_bio)
continue;
-
spin_lock_irq(&lo->lo_lock);
-
- /*
- * could be completed because of tear-down, not pending work
- */
- if (unlikely(!lo->lo_pending)) {
- spin_unlock_irq(&lo->lo_lock);
- break;
- }
-
bio = loop_get_bio(lo);
- lo->lo_pending--;
- pending = lo->lo_pending;
spin_unlock_irq(&lo->lo_lock);
BUG_ON(!bio);
loop_handle_bio(lo, bio);
-
- /*
- * upped both for pending work and tear-down, lo_pending
- * will hit zero then
- */
- if (unlikely(!pending))
- break;
}
- complete(&lo->lo_done);
return 0;
}
@@ -840,12 +817,26 @@ static int loop_set_fd(struct loop_device *lo, struct file *lo_file,
set_blocksize(bdev, lo_blocksize);
- error = kernel_thread(loop_thread, lo, CLONE_KERNEL);
- if (error < 0)
- goto out_putf;
- wait_for_completion(&lo->lo_done);
+ lo->lo_thread = kthread_create(loop_thread, lo, "loop%d",
+ lo->lo_number);
+ if (IS_ERR(lo->lo_thread)) {
+ error = PTR_ERR(lo->lo_thread);
+ goto out_clr;
+ }
+ lo->lo_state = Lo_bound;
+ wake_up_process(lo->lo_thread);
return 0;
+out_clr:
+ lo->lo_thread = NULL;
+ lo->lo_device = NULL;
+ lo->lo_backing_file = NULL;
+ lo->lo_flags = 0;
+ set_capacity(disks[lo->lo_number], 0);
+ invalidate_bdev(bdev, 0);
+ bd_set_size(bdev, 0);
+ mapping_set_gfp_mask(mapping, lo->old_gfp_mask);
+ lo->lo_state = Lo_unbound;
out_putf:
fput(file);
out:
@@ -907,12 +898,9 @@ static int loop_clr_fd(struct loop_device *lo, struct block_device *bdev)
spin_lock_irq(&lo->lo_lock);
lo->lo_state = Lo_rundown;
- lo->lo_pending--;
- if (!lo->lo_pending)
- complete(&lo->lo_bh_done);
spin_unlock_irq(&lo->lo_lock);
- wait_for_completion(&lo->lo_done);
+ kthread_stop(lo->lo_thread);
lo->lo_backing_file = NULL;
@@ -925,6 +913,7 @@ static int loop_clr_fd(struct loop_device *lo, struct block_device *bdev)
lo->lo_sizelimit = 0;
lo->lo_encrypt_key_size = 0;
lo->lo_flags = 0;
+ lo->lo_thread = NULL;
memset(lo->lo_encrypt_key, 0, LO_KEY_SIZE);
memset(lo->lo_crypt_name, 0, LO_NAME_SIZE);
memset(lo->lo_file_name, 0, LO_NAME_SIZE);
@@ -1177,6 +1166,162 @@ static int lo_ioctl(struct inode * inode, struct file * file,
return err;
}
+#ifdef CONFIG_COMPAT
+struct compat_loop_info {
+ compat_int_t lo_number; /* ioctl r/o */
+ compat_dev_t lo_device; /* ioctl r/o */
+ compat_ulong_t lo_inode; /* ioctl r/o */
+ compat_dev_t lo_rdevice; /* ioctl r/o */
+ compat_int_t lo_offset;
+ compat_int_t lo_encrypt_type;
+ compat_int_t lo_encrypt_key_size; /* ioctl w/o */
+ compat_int_t lo_flags; /* ioctl r/o */
+ char lo_name[LO_NAME_SIZE];
+ unsigned char lo_encrypt_key[LO_KEY_SIZE]; /* ioctl w/o */
+ compat_ulong_t lo_init[2];
+ char reserved[4];
+};
+
+/*
+ * Transfer 32-bit compatibility structure in userspace to 64-bit loop info
+ * - noinlined to reduce stack space usage in main part of driver
+ */
+static noinline int
+loop_info64_from_compat(const struct compat_loop_info *arg,
+ struct loop_info64 *info64)
+{
+ struct compat_loop_info info;
+
+ if (copy_from_user(&info, arg, sizeof(info)))
+ return -EFAULT;
+
+ memset(info64, 0, sizeof(*info64));
+ info64->lo_number = info.lo_number;
+ info64->lo_device = info.lo_device;
+ info64->lo_inode = info.lo_inode;
+ info64->lo_rdevice = info.lo_rdevice;
+ info64->lo_offset = info.lo_offset;
+ info64->lo_sizelimit = 0;
+ info64->lo_encrypt_type = info.lo_encrypt_type;
+ info64->lo_encrypt_key_size = info.lo_encrypt_key_size;
+ info64->lo_flags = info.lo_flags;
+ info64->lo_init[0] = info.lo_init[0];
+ info64->lo_init[1] = info.lo_init[1];
+ if (info.lo_encrypt_type == LO_CRYPT_CRYPTOAPI)
+ memcpy(info64->lo_crypt_name, info.lo_name, LO_NAME_SIZE);
+ else
+ memcpy(info64->lo_file_name, info.lo_name, LO_NAME_SIZE);
+ memcpy(info64->lo_encrypt_key, info.lo_encrypt_key, LO_KEY_SIZE);
+ return 0;
+}
+
+/*
+ * Transfer 64-bit loop info to 32-bit compatibility structure in userspace
+ * - noinlined to reduce stack space usage in main part of driver
+ */
+static noinline int
+loop_info64_to_compat(const struct loop_info64 *info64,
+ struct compat_loop_info __user *arg)
+{
+ struct compat_loop_info info;
+
+ memset(&info, 0, sizeof(info));
+ info.lo_number = info64->lo_number;
+ info.lo_device = info64->lo_device;
+ info.lo_inode = info64->lo_inode;
+ info.lo_rdevice = info64->lo_rdevice;
+ info.lo_offset = info64->lo_offset;
+ info.lo_encrypt_type = info64->lo_encrypt_type;
+ info.lo_encrypt_key_size = info64->lo_encrypt_key_size;
+ info.lo_flags = info64->lo_flags;
+ info.lo_init[0] = info64->lo_init[0];
+ info.lo_init[1] = info64->lo_init[1];
+ if (info.lo_encrypt_type == LO_CRYPT_CRYPTOAPI)
+ memcpy(info.lo_name, info64->lo_crypt_name, LO_NAME_SIZE);
+ else
+ memcpy(info.lo_name, info64->lo_file_name, LO_NAME_SIZE);
+ memcpy(info.lo_encrypt_key, info64->lo_encrypt_key, LO_KEY_SIZE);
+
+ /* error in case values were truncated */
+ if (info.lo_device != info64->lo_device ||
+ info.lo_rdevice != info64->lo_rdevice ||
+ info.lo_inode != info64->lo_inode ||
+ info.lo_offset != info64->lo_offset ||
+ info.lo_init[0] != info64->lo_init[0] ||
+ info.lo_init[1] != info64->lo_init[1])
+ return -EOVERFLOW;
+
+ if (copy_to_user(arg, &info, sizeof(info)))
+ return -EFAULT;
+ return 0;
+}
+
+static int
+loop_set_status_compat(struct loop_device *lo,
+ const struct compat_loop_info __user *arg)
+{
+ struct loop_info64 info64;
+ int ret;
+
+ ret = loop_info64_from_compat(arg, &info64);
+ if (ret < 0)
+ return ret;
+ return loop_set_status(lo, &info64);
+}
+
+static int
+loop_get_status_compat(struct loop_device *lo,
+ struct compat_loop_info __user *arg)
+{
+ struct loop_info64 info64;
+ int err = 0;
+
+ if (!arg)
+ err = -EINVAL;
+ if (!err)
+ err = loop_get_status(lo, &info64);
+ if (!err)
+ err = loop_info64_to_compat(&info64, arg);
+ return err;
+}
+
+static long lo_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+{
+ struct inode *inode = file->f_dentry->d_inode;
+ struct loop_device *lo = inode->i_bdev->bd_disk->private_data;
+ int err;
+
+ lock_kernel();
+ switch(cmd) {
+ case LOOP_SET_STATUS:
+ mutex_lock(&lo->lo_ctl_mutex);
+ err = loop_set_status_compat(
+ lo, (const struct compat_loop_info __user *) arg);
+ mutex_unlock(&lo->lo_ctl_mutex);
+ break;
+ case LOOP_GET_STATUS:
+ mutex_lock(&lo->lo_ctl_mutex);
+ err = loop_get_status_compat(
+ lo, (struct compat_loop_info __user *) arg);
+ mutex_unlock(&lo->lo_ctl_mutex);
+ break;
+ case LOOP_CLR_FD:
+ case LOOP_GET_STATUS64:
+ case LOOP_SET_STATUS64:
+ arg = (unsigned long) compat_ptr(arg);
+ case LOOP_SET_FD:
+ case LOOP_CHANGE_FD:
+ err = lo_ioctl(inode, file, cmd, arg);
+ break;
+ default:
+ err = -ENOIOCTLCMD;
+ break;
+ }
+ unlock_kernel();
+ return err;
+}
+#endif
+
static int lo_open(struct inode *inode, struct file *file)
{
struct loop_device *lo = inode->i_bdev->bd_disk->private_data;
@@ -1204,6 +1349,9 @@ static struct block_device_operations lo_fops = {
.open = lo_open,
.release = lo_release,
.ioctl = lo_ioctl,
+#ifdef CONFIG_COMPAT
+ .compat_ioctl = lo_compat_ioctl,
+#endif
};
/*
@@ -1287,9 +1435,9 @@ static int __init loop_init(void)
if (!lo->lo_queue)
goto out_mem4;
mutex_init(&lo->lo_ctl_mutex);
- init_completion(&lo->lo_done);
- init_completion(&lo->lo_bh_done);
lo->lo_number = i;
+ lo->lo_thread = NULL;
+ init_waitqueue_head(&lo->lo_event);
spin_lock_init(&lo->lo_lock);
disk->major = LOOP_MAJOR;
disk->first_minor = i;
diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c
index bdbade9a5cf5..9d1035e8d9d8 100644
--- a/drivers/block/nbd.c
+++ b/drivers/block/nbd.c
@@ -407,10 +407,10 @@ static void do_nbd_request(request_queue_t * q)
struct nbd_device *lo;
blkdev_dequeue_request(req);
- dprintk(DBG_BLKDEV, "%s: request %p: dequeued (flags=%lx)\n",
- req->rq_disk->disk_name, req, req->flags);
+ dprintk(DBG_BLKDEV, "%s: request %p: dequeued (flags=%x)\n",
+ req->rq_disk->disk_name, req, req->cmd_type);
- if (!(req->flags & REQ_CMD))
+ if (!blk_fs_request(req))
goto error_out;
lo = req->rq_disk->private_data;
@@ -489,7 +489,7 @@ static int nbd_ioctl(struct inode *inode, struct file *file,
switch (cmd) {
case NBD_DISCONNECT:
printk(KERN_INFO "%s: NBD_DISCONNECT\n", lo->disk->disk_name);
- sreq.flags = REQ_SPECIAL;
+ sreq.cmd_type = REQ_TYPE_SPECIAL;
nbd_cmd(&sreq) = NBD_CMD_DISC;
/*
* Set these to sane values in case server implementation
diff --git a/drivers/block/paride/pd.c b/drivers/block/paride/pd.c
index 2403721f9db1..40a11e567970 100644
--- a/drivers/block/paride/pd.c
+++ b/drivers/block/paride/pd.c
@@ -437,7 +437,7 @@ static char *pd_buf; /* buffer for request in progress */
static enum action do_pd_io_start(void)
{
- if (pd_req->flags & REQ_SPECIAL) {
+ if (blk_special_request(pd_req)) {
phase = pd_special;
return pd_special();
}
@@ -713,20 +713,18 @@ static void do_pd_request(request_queue_t * q)
static int pd_special_command(struct pd_unit *disk,
enum action (*func)(struct pd_unit *disk))
{
- DECLARE_COMPLETION(wait);
+ DECLARE_COMPLETION_ONSTACK(wait);
struct request rq;
int err = 0;
memset(&rq, 0, sizeof(rq));
rq.errors = 0;
- rq.rq_status = RQ_ACTIVE;
rq.rq_disk = disk->gd;
rq.ref_count = 1;
- rq.waiting = &wait;
+ rq.end_io_data = &wait;
rq.end_io = blk_end_sync_rq;
blk_insert_request(disk->gd->queue, &rq, 0, func);
wait_for_completion(&wait);
- rq.waiting = NULL;
if (rq.errors)
err = -EIO;
blk_put_request(&rq);
diff --git a/drivers/block/pktcdvd.c b/drivers/block/pktcdvd.c
index 451b996bba91..a6b2aa67c9b2 100644
--- a/drivers/block/pktcdvd.c
+++ b/drivers/block/pktcdvd.c
@@ -348,7 +348,7 @@ static int pkt_generic_packet(struct pktcdvd_device *pd, struct packet_command *
char sense[SCSI_SENSE_BUFFERSIZE];
request_queue_t *q;
struct request *rq;
- DECLARE_COMPLETION(wait);
+ DECLARE_COMPLETION_ONSTACK(wait);
int err = 0;
q = bdev_get_queue(pd->bdev);
@@ -365,17 +365,17 @@ static int pkt_generic_packet(struct pktcdvd_device *pd, struct packet_command *
rq->sense = sense;
memset(sense, 0, sizeof(sense));
rq->sense_len = 0;
- rq->flags |= REQ_BLOCK_PC | REQ_HARDBARRIER;
+ rq->cmd_type = REQ_TYPE_BLOCK_PC;
+ rq->cmd_flags |= REQ_HARDBARRIER;
if (cgc->quiet)
- rq->flags |= REQ_QUIET;
+ rq->cmd_flags |= REQ_QUIET;
memcpy(rq->cmd, cgc->cmd, CDROM_PACKET_SIZE);
if (sizeof(rq->cmd) > CDROM_PACKET_SIZE)
memset(rq->cmd + CDROM_PACKET_SIZE, 0, sizeof(rq->cmd) - CDROM_PACKET_SIZE);
rq->cmd_len = COMMAND_SIZE(rq->cmd[0]);
rq->ref_count++;
- rq->flags |= REQ_NOMERGE;
- rq->waiting = &wait;
+ rq->end_io_data = &wait;
rq->end_io = blk_end_sync_rq;
elv_add_request(q, rq, ELEVATOR_INSERT_BACK, 1);
generic_unplug_device(q);
diff --git a/drivers/block/swim3.c b/drivers/block/swim3.c
index cc42e762396f..f2305ee792a1 100644
--- a/drivers/block/swim3.c
+++ b/drivers/block/swim3.c
@@ -319,8 +319,8 @@ static void start_request(struct floppy_state *fs)
printk("do_fd_req: dev=%s cmd=%d sec=%ld nr_sec=%ld buf=%p\n",
req->rq_disk->disk_name, req->cmd,
(long)req->sector, req->nr_sectors, req->buffer);
- printk(" rq_status=%d errors=%d current_nr_sectors=%ld\n",
- req->rq_status, req->errors, req->current_nr_sectors);
+ printk(" errors=%d current_nr_sectors=%ld\n",
+ req->errors, req->current_nr_sectors);
#endif
if (req->sector < 0 || req->sector >= fs->total_secs) {
diff --git a/drivers/block/swim_iop.c b/drivers/block/swim_iop.c
index 89e3c2f8b776..dfda796eba56 100644
--- a/drivers/block/swim_iop.c
+++ b/drivers/block/swim_iop.c
@@ -529,8 +529,8 @@ static void start_request(struct floppy_state *fs)
printk("do_fd_req: dev=%s cmd=%d sec=%ld nr_sec=%ld buf=%p\n",
CURRENT->rq_disk->disk_name, CURRENT->cmd,
CURRENT->sector, CURRENT->nr_sectors, CURRENT->buffer);
- printk(" rq_status=%d errors=%d current_nr_sectors=%ld\n",
- CURRENT->rq_status, CURRENT->errors, CURRENT->current_nr_sectors);
+ printk(" errors=%d current_nr_sectors=%ld\n",
+ CURRENT->errors, CURRENT->current_nr_sectors);
#endif
if (CURRENT->sector < 0 || CURRENT->sector >= fs->total_secs) {
diff --git a/drivers/block/umem.c b/drivers/block/umem.c
index 5d8925bd9045..cbb9d0f21acc 100644
--- a/drivers/block/umem.c
+++ b/drivers/block/umem.c
@@ -552,7 +552,8 @@ static void process_page(unsigned long data)
static int mm_make_request(request_queue_t *q, struct bio *bio)
{
struct cardinfo *card = q->queuedata;
- pr_debug("mm_make_request %ld %d\n", bh->b_rsector, bh->b_size);
+ pr_debug("mm_make_request %llu %u\n",
+ (unsigned long long)bio->bi_sector, bio->bi_size);
bio->bi_phys_segments = bio->bi_idx; /* count of completed segments*/
spin_lock_irq(&card->lock);
diff --git a/drivers/block/xd.c b/drivers/block/xd.c
index e828e4cbd3e1..ebf3025721d1 100644
--- a/drivers/block/xd.c
+++ b/drivers/block/xd.c
@@ -313,7 +313,7 @@ static void do_xd_request (request_queue_t * q)
int res = 0;
int retry;
- if (!(req->flags & REQ_CMD)) {
+ if (!blk_fs_request(req)) {
end_request(req, 0);
continue;
}
diff --git a/drivers/bluetooth/bfusb.c b/drivers/bluetooth/bfusb.c
index 23f96213f4ac..efcc28ec9d9a 100644
--- a/drivers/bluetooth/bfusb.c
+++ b/drivers/bluetooth/bfusb.c
@@ -2,7 +2,7 @@
*
* AVM BlueFRITZ! USB driver
*
- * Copyright (C) 2003 Marcel Holtmann <marcel@holtmann.org>
+ * Copyright (C) 2003-2006 Marcel Holtmann <marcel@holtmann.org>
*
*
* This program is free software; you can redistribute it and/or modify
@@ -59,7 +59,6 @@ static struct usb_device_id bfusb_table[] = {
MODULE_DEVICE_TABLE(usb, bfusb_table);
-
#define BFUSB_MAX_BLOCK_SIZE 256
#define BFUSB_BLOCK_TIMEOUT 3000
@@ -70,7 +69,7 @@ MODULE_DEVICE_TABLE(usb, bfusb_table);
#define BFUSB_MAX_BULK_TX 2
#define BFUSB_MAX_BULK_RX 2
-struct bfusb {
+struct bfusb_data {
struct hci_dev *hdev;
unsigned long state;
@@ -92,137 +91,136 @@ struct bfusb {
struct sk_buff_head completed_q;
};
-struct bfusb_scb {
+struct bfusb_data_scb {
struct urb *urb;
};
static void bfusb_tx_complete(struct urb *urb, struct pt_regs *regs);
static void bfusb_rx_complete(struct urb *urb, struct pt_regs *regs);
-static struct urb *bfusb_get_completed(struct bfusb *bfusb)
+static struct urb *bfusb_get_completed(struct bfusb_data *data)
{
struct sk_buff *skb;
struct urb *urb = NULL;
- BT_DBG("bfusb %p", bfusb);
+ BT_DBG("bfusb %p", data);
- skb = skb_dequeue(&bfusb->completed_q);
+ skb = skb_dequeue(&data->completed_q);
if (skb) {
- urb = ((struct bfusb_scb *) skb->cb)->urb;
+ urb = ((struct bfusb_data_scb *) skb->cb)->urb;
kfree_skb(skb);
}
return urb;
}
-static void bfusb_unlink_urbs(struct bfusb *bfusb)
+static void bfusb_unlink_urbs(struct bfusb_data *data)
{
struct sk_buff *skb;
struct urb *urb;
- BT_DBG("bfusb %p", bfusb);
+ BT_DBG("bfusb %p", data);
- while ((skb = skb_dequeue(&bfusb->pending_q))) {
- urb = ((struct bfusb_scb *) skb->cb)->urb;
+ while ((skb = skb_dequeue(&data->pending_q))) {
+ urb = ((struct bfusb_data_scb *) skb->cb)->urb;
usb_kill_urb(urb);
- skb_queue_tail(&bfusb->completed_q, skb);
+ skb_queue_tail(&data->completed_q, skb);
}
- while ((urb = bfusb_get_completed(bfusb)))
+ while ((urb = bfusb_get_completed(data)))
usb_free_urb(urb);
}
-
-static int bfusb_send_bulk(struct bfusb *bfusb, struct sk_buff *skb)
+static int bfusb_send_bulk(struct bfusb_data *data, struct sk_buff *skb)
{
- struct bfusb_scb *scb = (void *) skb->cb;
- struct urb *urb = bfusb_get_completed(bfusb);
+ struct bfusb_data_scb *scb = (void *) skb->cb;
+ struct urb *urb = bfusb_get_completed(data);
int err, pipe;
- BT_DBG("bfusb %p skb %p len %d", bfusb, skb, skb->len);
+ BT_DBG("bfusb %p skb %p len %d", data, skb, skb->len);
if (!urb && !(urb = usb_alloc_urb(0, GFP_ATOMIC)))
return -ENOMEM;
- pipe = usb_sndbulkpipe(bfusb->udev, bfusb->bulk_out_ep);
+ pipe = usb_sndbulkpipe(data->udev, data->bulk_out_ep);
- usb_fill_bulk_urb(urb, bfusb->udev, pipe, skb->data, skb->len,
+ usb_fill_bulk_urb(urb, data->udev, pipe, skb->data, skb->len,
bfusb_tx_complete, skb);
scb->urb = urb;
- skb_queue_tail(&bfusb->pending_q, skb);
+ skb_queue_tail(&data->pending_q, skb);
err = usb_submit_urb(urb, GFP_ATOMIC);
if (err) {
BT_ERR("%s bulk tx submit failed urb %p err %d",
- bfusb->hdev->name, urb, err);
- skb_unlink(skb, &bfusb->pending_q);
+ data->hdev->name, urb, err);
+ skb_unlink(skb, &data->pending_q);
usb_free_urb(urb);
} else
- atomic_inc(&bfusb->pending_tx);
+ atomic_inc(&data->pending_tx);
return err;
}
-static void bfusb_tx_wakeup(struct bfusb *bfusb)
+static void bfusb_tx_wakeup(struct bfusb_data *data)
{
struct sk_buff *skb;
- BT_DBG("bfusb %p", bfusb);
+ BT_DBG("bfusb %p", data);
- if (test_and_set_bit(BFUSB_TX_PROCESS, &bfusb->state)) {
- set_bit(BFUSB_TX_WAKEUP, &bfusb->state);
+ if (test_and_set_bit(BFUSB_TX_PROCESS, &data->state)) {
+ set_bit(BFUSB_TX_WAKEUP, &data->state);
return;
}
do {
- clear_bit(BFUSB_TX_WAKEUP, &bfusb->state);
+ clear_bit(BFUSB_TX_WAKEUP, &data->state);
- while ((atomic_read(&bfusb->pending_tx) < BFUSB_MAX_BULK_TX) &&
- (skb = skb_dequeue(&bfusb->transmit_q))) {
- if (bfusb_send_bulk(bfusb, skb) < 0) {
- skb_queue_head(&bfusb->transmit_q, skb);
+ while ((atomic_read(&data->pending_tx) < BFUSB_MAX_BULK_TX) &&
+ (skb = skb_dequeue(&data->transmit_q))) {
+ if (bfusb_send_bulk(data, skb) < 0) {
+ skb_queue_head(&data->transmit_q, skb);
break;
}
}
- } while (test_bit(BFUSB_TX_WAKEUP, &bfusb->state));
+ } while (test_bit(BFUSB_TX_WAKEUP, &data->state));
- clear_bit(BFUSB_TX_PROCESS, &bfusb->state);
+ clear_bit(BFUSB_TX_PROCESS, &data->state);
}
static void bfusb_tx_complete(struct urb *urb, struct pt_regs *regs)
{
struct sk_buff *skb = (struct sk_buff *) urb->context;
- struct bfusb *bfusb = (struct bfusb *) skb->dev;
+ struct bfusb_data *data = (struct bfusb_data *) skb->dev;
- BT_DBG("bfusb %p urb %p skb %p len %d", bfusb, urb, skb, skb->len);
+ BT_DBG("bfusb %p urb %p skb %p len %d", data, urb, skb, skb->len);
- atomic_dec(&bfusb->pending_tx);
+ atomic_dec(&data->pending_tx);
- if (!test_bit(HCI_RUNNING, &bfusb->hdev->flags))
+ if (!test_bit(HCI_RUNNING, &data->hdev->flags))
return;
if (!urb->status)
- bfusb->hdev->stat.byte_tx += skb->len;
+ data->hdev->stat.byte_tx += skb->len;
else
- bfusb->hdev->stat.err_tx++;
+ data->hdev->stat.err_tx++;
- read_lock(&bfusb->lock);
+ read_lock(&data->lock);
- skb_unlink(skb, &bfusb->pending_q);
- skb_queue_tail(&bfusb->completed_q, skb);
+ skb_unlink(skb, &data->pending_q);
+ skb_queue_tail(&data->completed_q, skb);
- bfusb_tx_wakeup(bfusb);
+ bfusb_tx_wakeup(data);
- read_unlock(&bfusb->lock);
+ read_unlock(&data->lock);
}
-static int bfusb_rx_submit(struct bfusb *bfusb, struct urb *urb)
+static int bfusb_rx_submit(struct bfusb_data *data, struct urb *urb)
{
- struct bfusb_scb *scb;
+ struct bfusb_data_scb *scb;
struct sk_buff *skb;
int err, pipe, size = HCI_MAX_FRAME_SIZE + 32;
@@ -231,28 +229,29 @@ static int bfusb_rx_submit(struct bfusb *bfusb, struct urb *urb)
if (!urb && !(urb = usb_alloc_urb(0, GFP_ATOMIC)))
return -ENOMEM;
- if (!(skb = bt_skb_alloc(size, GFP_ATOMIC))) {
+ skb = bt_skb_alloc(size, GFP_ATOMIC);
+ if (!skb) {
usb_free_urb(urb);
return -ENOMEM;
}
- skb->dev = (void *) bfusb;
+ skb->dev = (void *) data;
- scb = (struct bfusb_scb *) skb->cb;
+ scb = (struct bfusb_data_scb *) skb->cb;
scb->urb = urb;
- pipe = usb_rcvbulkpipe(bfusb->udev, bfusb->bulk_in_ep);
+ pipe = usb_rcvbulkpipe(data->udev, data->bulk_in_ep);
- usb_fill_bulk_urb(urb, bfusb->udev, pipe, skb->data, size,
+ usb_fill_bulk_urb(urb, data->udev, pipe, skb->data, size,
bfusb_rx_complete, skb);
- skb_queue_tail(&bfusb->pending_q, skb);
+ skb_queue_tail(&data->pending_q, skb);
err = usb_submit_urb(urb, GFP_ATOMIC);
if (err) {
BT_ERR("%s bulk rx submit failed urb %p err %d",
- bfusb->hdev->name, urb, err);
- skb_unlink(skb, &bfusb->pending_q);
+ data->hdev->name, urb, err);
+ skb_unlink(skb, &data->pending_q);
kfree_skb(skb);
usb_free_urb(urb);
}
@@ -260,15 +259,15 @@ static int bfusb_rx_submit(struct bfusb *bfusb, struct urb *urb)
return err;
}
-static inline int bfusb_recv_block(struct bfusb *bfusb, int hdr, unsigned char *data, int len)
+static inline int bfusb_recv_block(struct bfusb_data *data, int hdr, unsigned char *buf, int len)
{
- BT_DBG("bfusb %p hdr 0x%02x data %p len %d", bfusb, hdr, data, len);
+ BT_DBG("bfusb %p hdr 0x%02x data %p len %d", data, hdr, buf, len);
if (hdr & 0x10) {
- BT_ERR("%s error in block", bfusb->hdev->name);
- if (bfusb->reassembly)
- kfree_skb(bfusb->reassembly);
- bfusb->reassembly = NULL;
+ BT_ERR("%s error in block", data->hdev->name);
+ if (data->reassembly)
+ kfree_skb(data->reassembly);
+ data->reassembly = NULL;
return -EIO;
}
@@ -277,46 +276,46 @@ static inline int bfusb_recv_block(struct bfusb *bfusb, int hdr, unsigned char *
unsigned char pkt_type;
int pkt_len = 0;
- if (bfusb->reassembly) {
- BT_ERR("%s unexpected start block", bfusb->hdev->name);
- kfree_skb(bfusb->reassembly);
- bfusb->reassembly = NULL;
+ if (data->reassembly) {
+ BT_ERR("%s unexpected start block", data->hdev->name);
+ kfree_skb(data->reassembly);
+ data->reassembly = NULL;
}
if (len < 1) {
- BT_ERR("%s no packet type found", bfusb->hdev->name);
+ BT_ERR("%s no packet type found", data->hdev->name);
return -EPROTO;
}
- pkt_type = *data++; len--;
+ pkt_type = *buf++; len--;
switch (pkt_type) {
case HCI_EVENT_PKT:
if (len >= HCI_EVENT_HDR_SIZE) {
- struct hci_event_hdr *hdr = (struct hci_event_hdr *) data;
+ struct hci_event_hdr *hdr = (struct hci_event_hdr *) buf;
pkt_len = HCI_EVENT_HDR_SIZE + hdr->plen;
} else {
- BT_ERR("%s event block is too short", bfusb->hdev->name);
+ BT_ERR("%s event block is too short", data->hdev->name);
return -EILSEQ;
}
break;
case HCI_ACLDATA_PKT:
if (len >= HCI_ACL_HDR_SIZE) {
- struct hci_acl_hdr *hdr = (struct hci_acl_hdr *) data;
+ struct hci_acl_hdr *hdr = (struct hci_acl_hdr *) buf;
pkt_len = HCI_ACL_HDR_SIZE + __le16_to_cpu(hdr->dlen);
} else {
- BT_ERR("%s data block is too short", bfusb->hdev->name);
+ BT_ERR("%s data block is too short", data->hdev->name);
return -EILSEQ;
}
break;
case HCI_SCODATA_PKT:
if (len >= HCI_SCO_HDR_SIZE) {
- struct hci_sco_hdr *hdr = (struct hci_sco_hdr *) data;
+ struct hci_sco_hdr *hdr = (struct hci_sco_hdr *) buf;
pkt_len = HCI_SCO_HDR_SIZE + hdr->dlen;
} else {
- BT_ERR("%s audio block is too short", bfusb->hdev->name);
+ BT_ERR("%s audio block is too short", data->hdev->name);
return -EILSEQ;
}
break;
@@ -324,27 +323,27 @@ static inline int bfusb_recv_block(struct bfusb *bfusb, int hdr, unsigned char *
skb = bt_skb_alloc(pkt_len, GFP_ATOMIC);
if (!skb) {
- BT_ERR("%s no memory for the packet", bfusb->hdev->name);
+ BT_ERR("%s no memory for the packet", data->hdev->name);
return -ENOMEM;
}
- skb->dev = (void *) bfusb->hdev;
+ skb->dev = (void *) data->hdev;
bt_cb(skb)->pkt_type = pkt_type;
- bfusb->reassembly = skb;
+ data->reassembly = skb;
} else {
- if (!bfusb->reassembly) {
- BT_ERR("%s unexpected continuation block", bfusb->hdev->name);
+ if (!data->reassembly) {
+ BT_ERR("%s unexpected continuation block", data->hdev->name);
return -EIO;
}
}
if (len > 0)
- memcpy(skb_put(bfusb->reassembly, len), data, len);
+ memcpy(skb_put(data->reassembly, len), buf, len);
if (hdr & 0x08) {
- hci_recv_frame(bfusb->reassembly);
- bfusb->reassembly = NULL;
+ hci_recv_frame(data->reassembly);
+ data->reassembly = NULL;
}
return 0;
@@ -353,22 +352,22 @@ static inline int bfusb_recv_block(struct bfusb *bfusb, int hdr, unsigned char *
static void bfusb_rx_complete(struct urb *urb, struct pt_regs *regs)
{
struct sk_buff *skb = (struct sk_buff *) urb->context;
- struct bfusb *bfusb = (struct bfusb *) skb->dev;
+ struct bfusb_data *data = (struct bfusb_data *) skb->dev;
unsigned char *buf = urb->transfer_buffer;
int count = urb->actual_length;
int err, hdr, len;
BT_DBG("bfusb %p urb %p skb %p len %d", bfusb, urb, skb, skb->len);
- read_lock(&bfusb->lock);
+ read_lock(&data->lock);
- if (!test_bit(HCI_RUNNING, &bfusb->hdev->flags))
+ if (!test_bit(HCI_RUNNING, &data->hdev->flags))
goto unlock;
if (urb->status || !count)
goto resubmit;
- bfusb->hdev->stat.byte_rx += count;
+ data->hdev->stat.byte_rx += count;
skb_put(skb, count);
@@ -387,90 +386,89 @@ static void bfusb_rx_complete(struct urb *urb, struct pt_regs *regs)
if (count < len) {
BT_ERR("%s block extends over URB buffer ranges",
- bfusb->hdev->name);
+ data->hdev->name);
}
if ((hdr & 0xe1) == 0xc1)
- bfusb_recv_block(bfusb, hdr, buf, len);
+ bfusb_recv_block(data, hdr, buf, len);
count -= len;
buf += len;
}
- skb_unlink(skb, &bfusb->pending_q);
+ skb_unlink(skb, &data->pending_q);
kfree_skb(skb);
- bfusb_rx_submit(bfusb, urb);
+ bfusb_rx_submit(data, urb);
- read_unlock(&bfusb->lock);
+ read_unlock(&data->lock);
return;
resubmit:
- urb->dev = bfusb->udev;
+ urb->dev = data->udev;
err = usb_submit_urb(urb, GFP_ATOMIC);
if (err) {
BT_ERR("%s bulk resubmit failed urb %p err %d",
- bfusb->hdev->name, urb, err);
+ data->hdev->name, urb, err);
}
unlock:
- read_unlock(&bfusb->lock);
+ read_unlock(&data->lock);
}
-
static int bfusb_open(struct hci_dev *hdev)
{
- struct bfusb *bfusb = (struct bfusb *) hdev->driver_data;
+ struct bfusb_data *data = hdev->driver_data;
unsigned long flags;
int i, err;
- BT_DBG("hdev %p bfusb %p", hdev, bfusb);
+ BT_DBG("hdev %p bfusb %p", hdev, data);
if (test_and_set_bit(HCI_RUNNING, &hdev->flags))
return 0;
- write_lock_irqsave(&bfusb->lock, flags);
+ write_lock_irqsave(&data->lock, flags);
- err = bfusb_rx_submit(bfusb, NULL);
+ err = bfusb_rx_submit(data, NULL);
if (!err) {
for (i = 1; i < BFUSB_MAX_BULK_RX; i++)
- bfusb_rx_submit(bfusb, NULL);
+ bfusb_rx_submit(data, NULL);
} else {
clear_bit(HCI_RUNNING, &hdev->flags);
}
- write_unlock_irqrestore(&bfusb->lock, flags);
+ write_unlock_irqrestore(&data->lock, flags);
return err;
}
static int bfusb_flush(struct hci_dev *hdev)
{
- struct bfusb *bfusb = (struct bfusb *) hdev->driver_data;
+ struct bfusb_data *data = hdev->driver_data;
- BT_DBG("hdev %p bfusb %p", hdev, bfusb);
+ BT_DBG("hdev %p bfusb %p", hdev, data);
- skb_queue_purge(&bfusb->transmit_q);
+ skb_queue_purge(&data->transmit_q);
return 0;
}
static int bfusb_close(struct hci_dev *hdev)
{
- struct bfusb *bfusb = (struct bfusb *) hdev->driver_data;
+ struct bfusb_data *data = hdev->driver_data;
unsigned long flags;
- BT_DBG("hdev %p bfusb %p", hdev, bfusb);
+ BT_DBG("hdev %p bfusb %p", hdev, data);
if (!test_and_clear_bit(HCI_RUNNING, &hdev->flags))
return 0;
- write_lock_irqsave(&bfusb->lock, flags);
- write_unlock_irqrestore(&bfusb->lock, flags);
+ write_lock_irqsave(&data->lock, flags);
+ write_unlock_irqrestore(&data->lock, flags);
- bfusb_unlink_urbs(bfusb);
+ bfusb_unlink_urbs(data);
bfusb_flush(hdev);
return 0;
@@ -479,7 +477,7 @@ static int bfusb_close(struct hci_dev *hdev)
static int bfusb_send_frame(struct sk_buff *skb)
{
struct hci_dev *hdev = (struct hci_dev *) skb->dev;
- struct bfusb *bfusb;
+ struct bfusb_data *data;
struct sk_buff *nskb;
unsigned char buf[3];
int sent = 0, size, count;
@@ -494,7 +492,7 @@ static int bfusb_send_frame(struct sk_buff *skb)
if (!test_bit(HCI_RUNNING, &hdev->flags))
return -EBUSY;
- bfusb = (struct bfusb *) hdev->driver_data;
+ data = hdev->driver_data;
switch (bt_cb(skb)->pkt_type) {
case HCI_COMMAND_PKT:
@@ -514,12 +512,13 @@ static int bfusb_send_frame(struct sk_buff *skb)
count = skb->len;
/* Max HCI frame size seems to be 1511 + 1 */
- if (!(nskb = bt_skb_alloc(count + 32, GFP_ATOMIC))) {
+ nskb = bt_skb_alloc(count + 32, GFP_ATOMIC);
+ if (!nskb) {
BT_ERR("Can't allocate memory for new packet");
return -ENOMEM;
}
- nskb->dev = (void *) bfusb;
+ nskb->dev = (void *) data;
while (count) {
size = min_t(uint, count, BFUSB_MAX_BLOCK_SIZE);
@@ -536,18 +535,18 @@ static int bfusb_send_frame(struct sk_buff *skb)
}
/* Don't send frame with multiple size of bulk max packet */
- if ((nskb->len % bfusb->bulk_pkt_size) == 0) {
+ if ((nskb->len % data->bulk_pkt_size) == 0) {
buf[0] = 0xdd;
buf[1] = 0x00;
memcpy(skb_put(nskb, 2), buf, 2);
}
- read_lock(&bfusb->lock);
+ read_lock(&data->lock);
- skb_queue_tail(&bfusb->transmit_q, nskb);
- bfusb_tx_wakeup(bfusb);
+ skb_queue_tail(&data->transmit_q, nskb);
+ bfusb_tx_wakeup(data);
- read_unlock(&bfusb->lock);
+ read_unlock(&data->lock);
kfree_skb(skb);
@@ -556,11 +555,11 @@ static int bfusb_send_frame(struct sk_buff *skb)
static void bfusb_destruct(struct hci_dev *hdev)
{
- struct bfusb *bfusb = (struct bfusb *) hdev->driver_data;
+ struct bfusb_data *data = hdev->driver_data;
- BT_DBG("hdev %p bfusb %p", hdev, bfusb);
+ BT_DBG("hdev %p bfusb %p", hdev, data);
- kfree(bfusb);
+ kfree(data);
}
static int bfusb_ioctl(struct hci_dev *hdev, unsigned int cmd, unsigned long arg)
@@ -568,25 +567,24 @@ static int bfusb_ioctl(struct hci_dev *hdev, unsigned int cmd, unsigned long arg
return -ENOIOCTLCMD;
}
-
-static int bfusb_load_firmware(struct bfusb *bfusb, unsigned char *firmware, int count)
+static int bfusb_load_firmware(struct bfusb_data *data, unsigned char *firmware, int count)
{
unsigned char *buf;
int err, pipe, len, size, sent = 0;
- BT_DBG("bfusb %p udev %p", bfusb, bfusb->udev);
+ BT_DBG("bfusb %p udev %p", data, data->udev);
BT_INFO("BlueFRITZ! USB loading firmware");
- pipe = usb_sndctrlpipe(bfusb->udev, 0);
+ pipe = usb_sndctrlpipe(data->udev, 0);
- if (usb_control_msg(bfusb->udev, pipe, USB_REQ_SET_CONFIGURATION,
+ if (usb_control_msg(data->udev, pipe, USB_REQ_SET_CONFIGURATION,
0, 1, 0, NULL, 0, USB_CTRL_SET_TIMEOUT) < 0) {
BT_ERR("Can't change to loading configuration");
return -EBUSY;
}
- bfusb->udev->toggle[0] = bfusb->udev->toggle[1] = 0;
+ data->udev->toggle[0] = data->udev->toggle[1] = 0;
buf = kmalloc(BFUSB_MAX_BLOCK_SIZE + 3, GFP_ATOMIC);
if (!buf) {
@@ -594,14 +592,14 @@ static int bfusb_load_firmware(struct bfusb *bfusb, unsigned char *firmware, int
return -ENOMEM;
}
- pipe = usb_sndbulkpipe(bfusb->udev, bfusb->bulk_out_ep);
+ pipe = usb_sndbulkpipe(data->udev, data->bulk_out_ep);
while (count) {
size = min_t(uint, count, BFUSB_MAX_BLOCK_SIZE + 3);
memcpy(buf, firmware + sent, size);
- err = usb_bulk_msg(bfusb->udev, pipe, buf, size,
+ err = usb_bulk_msg(data->udev, pipe, buf, size,
&len, BFUSB_BLOCK_TIMEOUT);
if (err || (len != size)) {
@@ -613,21 +611,23 @@ static int bfusb_load_firmware(struct bfusb *bfusb, unsigned char *firmware, int
count -= size;
}
- if ((err = usb_bulk_msg(bfusb->udev, pipe, NULL, 0,
- &len, BFUSB_BLOCK_TIMEOUT)) < 0) {
+ err = usb_bulk_msg(data->udev, pipe, NULL, 0,
+ &len, BFUSB_BLOCK_TIMEOUT);
+ if (err < 0) {
BT_ERR("Error in null packet request");
goto error;
}
- pipe = usb_sndctrlpipe(bfusb->udev, 0);
+ pipe = usb_sndctrlpipe(data->udev, 0);
- if ((err = usb_control_msg(bfusb->udev, pipe, USB_REQ_SET_CONFIGURATION,
- 0, 2, 0, NULL, 0, USB_CTRL_SET_TIMEOUT)) < 0) {
+ err = usb_control_msg(data->udev, pipe, USB_REQ_SET_CONFIGURATION,
+ 0, 2, 0, NULL, 0, USB_CTRL_SET_TIMEOUT);
+ if (err < 0) {
BT_ERR("Can't change to running configuration");
goto error;
}
- bfusb->udev->toggle[0] = bfusb->udev->toggle[1] = 0;
+ data->udev->toggle[0] = data->udev->toggle[1] = 0;
BT_INFO("BlueFRITZ! USB device ready");
@@ -637,9 +637,9 @@ static int bfusb_load_firmware(struct bfusb *bfusb, unsigned char *firmware, int
error:
kfree(buf);
- pipe = usb_sndctrlpipe(bfusb->udev, 0);
+ pipe = usb_sndctrlpipe(data->udev, 0);
- usb_control_msg(bfusb->udev, pipe, USB_REQ_SET_CONFIGURATION,
+ usb_control_msg(data->udev, pipe, USB_REQ_SET_CONFIGURATION,
0, 0, 0, NULL, 0, USB_CTRL_SET_TIMEOUT);
return err;
@@ -652,7 +652,7 @@ static int bfusb_probe(struct usb_interface *intf, const struct usb_device_id *i
struct usb_host_endpoint *bulk_out_ep;
struct usb_host_endpoint *bulk_in_ep;
struct hci_dev *hdev;
- struct bfusb *bfusb;
+ struct bfusb_data *data;
BT_DBG("intf %p id %p", intf, id);
@@ -672,23 +672,24 @@ static int bfusb_probe(struct usb_interface *intf, const struct usb_device_id *i
}
/* Initialize control structure and load firmware */
- if (!(bfusb = kzalloc(sizeof(struct bfusb), GFP_KERNEL))) {
+ data = kzalloc(sizeof(struct bfusb_data), GFP_KERNEL);
+ if (!data) {
BT_ERR("Can't allocate memory for control structure");
goto done;
}
- bfusb->udev = udev;
- bfusb->bulk_in_ep = bulk_in_ep->desc.bEndpointAddress;
- bfusb->bulk_out_ep = bulk_out_ep->desc.bEndpointAddress;
- bfusb->bulk_pkt_size = le16_to_cpu(bulk_out_ep->desc.wMaxPacketSize);
+ data->udev = udev;
+ data->bulk_in_ep = bulk_in_ep->desc.bEndpointAddress;
+ data->bulk_out_ep = bulk_out_ep->desc.bEndpointAddress;
+ data->bulk_pkt_size = le16_to_cpu(bulk_out_ep->desc.wMaxPacketSize);
- rwlock_init(&bfusb->lock);
+ rwlock_init(&data->lock);
- bfusb->reassembly = NULL;
+ data->reassembly = NULL;
- skb_queue_head_init(&bfusb->transmit_q);
- skb_queue_head_init(&bfusb->pending_q);
- skb_queue_head_init(&bfusb->completed_q);
+ skb_queue_head_init(&data->transmit_q);
+ skb_queue_head_init(&data->pending_q);
+ skb_queue_head_init(&data->completed_q);
if (request_firmware(&firmware, "bfubase.frm", &udev->dev) < 0) {
BT_ERR("Firmware request failed");
@@ -697,7 +698,7 @@ static int bfusb_probe(struct usb_interface *intf, const struct usb_device_id *i
BT_DBG("firmware data %p size %d", firmware->data, firmware->size);
- if (bfusb_load_firmware(bfusb, firmware->data, firmware->size) < 0) {
+ if (bfusb_load_firmware(data, firmware->data, firmware->size) < 0) {
BT_ERR("Firmware loading failed");
goto release;
}
@@ -711,10 +712,10 @@ static int bfusb_probe(struct usb_interface *intf, const struct usb_device_id *i
goto error;
}
- bfusb->hdev = hdev;
+ data->hdev = hdev;
hdev->type = HCI_USB;
- hdev->driver_data = bfusb;
+ hdev->driver_data = data;
SET_HCIDEV_DEV(hdev, &intf->dev);
hdev->open = bfusb_open;
@@ -732,7 +733,7 @@ static int bfusb_probe(struct usb_interface *intf, const struct usb_device_id *i
goto error;
}
- usb_set_intfdata(intf, bfusb);
+ usb_set_intfdata(intf, data);
return 0;
@@ -740,7 +741,7 @@ release:
release_firmware(firmware);
error:
- kfree(bfusb);
+ kfree(data);
done:
return -EIO;
@@ -748,8 +749,8 @@ done:
static void bfusb_disconnect(struct usb_interface *intf)
{
- struct bfusb *bfusb = usb_get_intfdata(intf);
- struct hci_dev *hdev = bfusb->hdev;
+ struct bfusb_data *data = usb_get_intfdata(intf);
+ struct hci_dev *hdev = data->hdev;
BT_DBG("intf %p", intf);
@@ -779,7 +780,8 @@ static int __init bfusb_init(void)
BT_INFO("BlueFRITZ! USB driver ver %s", VERSION);
- if ((err = usb_register(&bfusb_driver)) < 0)
+ err = usb_register(&bfusb_driver);
+ if (err < 0)
BT_ERR("Failed to register BlueFRITZ! USB driver");
return err;
diff --git a/drivers/bluetooth/hci_ldisc.c b/drivers/bluetooth/hci_ldisc.c
index 93ba25b7ea32..420b645c4c9f 100644
--- a/drivers/bluetooth/hci_ldisc.c
+++ b/drivers/bluetooth/hci_ldisc.c
@@ -241,15 +241,11 @@ static int hci_uart_send_frame(struct sk_buff *skb)
static void hci_uart_destruct(struct hci_dev *hdev)
{
- struct hci_uart *hu;
-
if (!hdev)
return;
BT_DBG("%s", hdev->name);
-
- hu = (struct hci_uart *) hdev->driver_data;
- kfree(hu);
+ kfree(hdev->driver_data);
}
/* ------ LDISC part ------ */
@@ -272,7 +268,7 @@ static int hci_uart_tty_open(struct tty_struct *tty)
return -EEXIST;
if (!(hu = kzalloc(sizeof(struct hci_uart), GFP_KERNEL))) {
- BT_ERR("Can't allocate controll structure");
+ BT_ERR("Can't allocate control structure");
return -ENFILE;
}
@@ -360,7 +356,7 @@ static void hci_uart_tty_wakeup(struct tty_struct *tty)
*
* Return Value: None
*/
-static void hci_uart_tty_receive(struct tty_struct *tty, const __u8 *data, char *flags, int count)
+static void hci_uart_tty_receive(struct tty_struct *tty, const u8 *data, char *flags, int count)
{
struct hci_uart *hu = (void *)tty->disc_data;
@@ -375,7 +371,8 @@ static void hci_uart_tty_receive(struct tty_struct *tty, const __u8 *data, char
hu->hdev->stat.byte_rx += count;
spin_unlock(&hu->rx_lock);
- if (test_and_clear_bit(TTY_THROTTLED,&tty->flags) && tty->driver->unthrottle)
+ if (test_and_clear_bit(TTY_THROTTLED, &tty->flags) &&
+ tty->driver->unthrottle)
tty->driver->unthrottle(tty);
}
diff --git a/drivers/bluetooth/hci_usb.c b/drivers/bluetooth/hci_usb.c
index e2d4beac7420..0801af4ad2b9 100644
--- a/drivers/bluetooth/hci_usb.c
+++ b/drivers/bluetooth/hci_usb.c
@@ -96,6 +96,9 @@ static struct usb_device_id bluetooth_ids[] = {
/* Ericsson with non-standard id */
{ USB_DEVICE(0x0bdb, 0x1002) },
+ /* Canyon CN-BTU1 with HID interfaces */
+ { USB_DEVICE(0x0c10, 0x0000), .driver_info = HCI_RESET },
+
{ } /* Terminating entry */
};
diff --git a/drivers/bluetooth/hci_vhci.c b/drivers/bluetooth/hci_vhci.c
index aac67a3a6019..a278d98a9151 100644
--- a/drivers/bluetooth/hci_vhci.c
+++ b/drivers/bluetooth/hci_vhci.c
@@ -2,9 +2,9 @@
*
* Bluetooth virtual HCI driver
*
- * Copyright (C) 2000-2001 Qualcomm Incorporated
- * Copyright (C) 2002-2003 Maxim Krasnyansky <maxk@qualcomm.com>
- * Copyright (C) 2004-2005 Marcel Holtmann <marcel@holtmann.org>
+ * Copyright (C) 2000-2001 Qualcomm Incorporated
+ * Copyright (C) 2002-2003 Maxim Krasnyansky <maxk@qualcomm.com>
+ * Copyright (C) 2004-2006 Marcel Holtmann <marcel@holtmann.org>
*
*
* This program is free software; you can redistribute it and/or modify
@@ -72,21 +72,21 @@ static int vhci_open_dev(struct hci_dev *hdev)
static int vhci_close_dev(struct hci_dev *hdev)
{
- struct vhci_data *vhci = hdev->driver_data;
+ struct vhci_data *data = hdev->driver_data;
if (!test_and_clear_bit(HCI_RUNNING, &hdev->flags))
return 0;
- skb_queue_purge(&vhci->readq);
+ skb_queue_purge(&data->readq);
return 0;
}
static int vhci_flush(struct hci_dev *hdev)
{
- struct vhci_data *vhci = hdev->driver_data;
+ struct vhci_data *data = hdev->driver_data;
- skb_queue_purge(&vhci->readq);
+ skb_queue_purge(&data->readq);
return 0;
}
@@ -94,7 +94,7 @@ static int vhci_flush(struct hci_dev *hdev)
static int vhci_send_frame(struct sk_buff *skb)
{
struct hci_dev* hdev = (struct hci_dev *) skb->dev;
- struct vhci_data *vhci;
+ struct vhci_data *data;
if (!hdev) {
BT_ERR("Frame for unknown HCI device (hdev=NULL)");
@@ -104,15 +104,15 @@ static int vhci_send_frame(struct sk_buff *skb)
if (!test_bit(HCI_RUNNING, &hdev->flags))
return -EBUSY;
- vhci = hdev->driver_data;
+ data = hdev->driver_data;
memcpy(skb_push(skb, 1), &bt_cb(skb)->pkt_type, 1);
- skb_queue_tail(&vhci->readq, skb);
+ skb_queue_tail(&data->readq, skb);
- if (vhci->flags & VHCI_FASYNC)
- kill_fasync(&vhci->fasync, SIGIO, POLL_IN);
+ if (data->flags & VHCI_FASYNC)
+ kill_fasync(&data->fasync, SIGIO, POLL_IN);
- wake_up_interruptible(&vhci->read_wait);
+ wake_up_interruptible(&data->read_wait);
return 0;
}
@@ -122,7 +122,7 @@ static void vhci_destruct(struct hci_dev *hdev)
kfree(hdev->driver_data);
}
-static inline ssize_t vhci_get_user(struct vhci_data *vhci,
+static inline ssize_t vhci_get_user(struct vhci_data *data,
const char __user *buf, size_t count)
{
struct sk_buff *skb;
@@ -139,7 +139,7 @@ static inline ssize_t vhci_get_user(struct vhci_data *vhci,
return -EFAULT;
}
- skb->dev = (void *) vhci->hdev;
+ skb->dev = (void *) data->hdev;
bt_cb(skb)->pkt_type = *((__u8 *) skb->data);
skb_pull(skb, 1);
@@ -148,7 +148,7 @@ static inline ssize_t vhci_get_user(struct vhci_data *vhci,
return count;
}
-static inline ssize_t vhci_put_user(struct vhci_data *vhci,
+static inline ssize_t vhci_put_user(struct vhci_data *data,
struct sk_buff *skb, char __user *buf, int count)
{
char __user *ptr = buf;
@@ -161,42 +161,43 @@ static inline ssize_t vhci_put_user(struct vhci_data *vhci,
total += len;
- vhci->hdev->stat.byte_tx += len;
+ data->hdev->stat.byte_tx += len;
switch (bt_cb(skb)->pkt_type) {
case HCI_COMMAND_PKT:
- vhci->hdev->stat.cmd_tx++;
+ data->hdev->stat.cmd_tx++;
break;
case HCI_ACLDATA_PKT:
- vhci->hdev->stat.acl_tx++;
+ data->hdev->stat.acl_tx++;
break;
case HCI_SCODATA_PKT:
- vhci->hdev->stat.cmd_tx++;
+ data->hdev->stat.cmd_tx++;
break;
};
return total;
}
-static loff_t vhci_llseek(struct file * file, loff_t offset, int origin)
+static loff_t vhci_llseek(struct file *file, loff_t offset, int origin)
{
return -ESPIPE;
}
-static ssize_t vhci_read(struct file * file, char __user * buf, size_t count, loff_t *pos)
+static ssize_t vhci_read(struct file *file,
+ char __user *buf, size_t count, loff_t *pos)
{
DECLARE_WAITQUEUE(wait, current);
- struct vhci_data *vhci = file->private_data;
+ struct vhci_data *data = file->private_data;
struct sk_buff *skb;
ssize_t ret = 0;
- add_wait_queue(&vhci->read_wait, &wait);
+ add_wait_queue(&data->read_wait, &wait);
while (count) {
set_current_state(TASK_INTERRUPTIBLE);
- skb = skb_dequeue(&vhci->readq);
+ skb = skb_dequeue(&data->readq);
if (!skb) {
if (file->f_flags & O_NONBLOCK) {
ret = -EAGAIN;
@@ -213,7 +214,7 @@ static ssize_t vhci_read(struct file * file, char __user * buf, size_t count, lo
}
if (access_ok(VERIFY_WRITE, buf, count))
- ret = vhci_put_user(vhci, skb, buf, count);
+ ret = vhci_put_user(data, skb, buf, count);
else
ret = -EFAULT;
@@ -221,7 +222,7 @@ static ssize_t vhci_read(struct file * file, char __user * buf, size_t count, lo
break;
}
set_current_state(TASK_RUNNING);
- remove_wait_queue(&vhci->read_wait, &wait);
+ remove_wait_queue(&data->read_wait, &wait);
return ret;
}
@@ -229,21 +230,21 @@ static ssize_t vhci_read(struct file * file, char __user * buf, size_t count, lo
static ssize_t vhci_write(struct file *file,
const char __user *buf, size_t count, loff_t *pos)
{
- struct vhci_data *vhci = file->private_data;
+ struct vhci_data *data = file->private_data;
if (!access_ok(VERIFY_READ, buf, count))
return -EFAULT;
- return vhci_get_user(vhci, buf, count);
+ return vhci_get_user(data, buf, count);
}
static unsigned int vhci_poll(struct file *file, poll_table *wait)
{
- struct vhci_data *vhci = file->private_data;
+ struct vhci_data *data = file->private_data;
- poll_wait(file, &vhci->read_wait, wait);
+ poll_wait(file, &data->read_wait, wait);
- if (!skb_queue_empty(&vhci->readq))
+ if (!skb_queue_empty(&data->readq))
return POLLIN | POLLRDNORM;
return POLLOUT | POLLWRNORM;
@@ -257,26 +258,26 @@ static int vhci_ioctl(struct inode *inode, struct file *file,
static int vhci_open(struct inode *inode, struct file *file)
{
- struct vhci_data *vhci;
+ struct vhci_data *data;
struct hci_dev *hdev;
- vhci = kzalloc(sizeof(struct vhci_data), GFP_KERNEL);
- if (!vhci)
+ data = kzalloc(sizeof(struct vhci_data), GFP_KERNEL);
+ if (!data)
return -ENOMEM;
- skb_queue_head_init(&vhci->readq);
- init_waitqueue_head(&vhci->read_wait);
+ skb_queue_head_init(&data->readq);
+ init_waitqueue_head(&data->read_wait);
hdev = hci_alloc_dev();
if (!hdev) {
- kfree(vhci);
+ kfree(data);
return -ENOMEM;
}
- vhci->hdev = hdev;
+ data->hdev = hdev;
- hdev->type = HCI_VHCI;
- hdev->driver_data = vhci;
+ hdev->type = HCI_VIRTUAL;
+ hdev->driver_data = data;
hdev->open = vhci_open_dev;
hdev->close = vhci_close_dev;
@@ -288,20 +289,20 @@ static int vhci_open(struct inode *inode, struct file *file)
if (hci_register_dev(hdev) < 0) {
BT_ERR("Can't register HCI device");
- kfree(vhci);
+ kfree(data);
hci_free_dev(hdev);
return -EBUSY;
}
- file->private_data = vhci;
+ file->private_data = data;
return nonseekable_open(inode, file);
}
static int vhci_release(struct inode *inode, struct file *file)
{
- struct vhci_data *vhci = file->private_data;
- struct hci_dev *hdev = vhci->hdev;
+ struct vhci_data *data = file->private_data;
+ struct hci_dev *hdev = data->hdev;
if (hci_unregister_dev(hdev) < 0) {
BT_ERR("Can't unregister HCI device %s", hdev->name);
@@ -316,17 +317,17 @@ static int vhci_release(struct inode *inode, struct file *file)
static int vhci_fasync(int fd, struct file *file, int on)
{
- struct vhci_data *vhci = file->private_data;
+ struct vhci_data *data = file->private_data;
int err;
- err = fasync_helper(fd, file, on, &vhci->fasync);
+ err = fasync_helper(fd, file, on, &data->fasync);
if (err < 0)
return err;
if (on)
- vhci->flags |= VHCI_FASYNC;
+ data->flags |= VHCI_FASYNC;
else
- vhci->flags &= ~VHCI_FASYNC;
+ data->flags &= ~VHCI_FASYNC;
return 0;
}
diff --git a/drivers/cdrom/Kconfig b/drivers/cdrom/Kconfig
index ff5652d40619..4b12e9031fb3 100644
--- a/drivers/cdrom/Kconfig
+++ b/drivers/cdrom/Kconfig
@@ -3,7 +3,7 @@
#
menu "Old CD-ROM drivers (not SCSI, not IDE)"
- depends on ISA
+ depends on ISA && BLOCK
config CD_NO_IDESCSI
bool "Support non-SCSI/IDE/ATAPI CDROM drives"
diff --git a/drivers/cdrom/cdrom.c b/drivers/cdrom/cdrom.c
index d239cf8b20bd..b38c84a7a8e3 100644
--- a/drivers/cdrom/cdrom.c
+++ b/drivers/cdrom/cdrom.c
@@ -2129,7 +2129,7 @@ static int cdrom_read_cdda_bpc(struct cdrom_device_info *cdi, __u8 __user *ubuf,
rq->cmd[9] = 0xf8;
rq->cmd_len = 12;
- rq->flags |= REQ_BLOCK_PC;
+ rq->cmd_type = REQ_TYPE_BLOCK_PC;
rq->timeout = 60 * HZ;
bio = rq->bio;
diff --git a/drivers/cdrom/cdu31a.c b/drivers/cdrom/cdu31a.c
index 37bdb0163f0d..ccd91c1a84bd 100644
--- a/drivers/cdrom/cdu31a.c
+++ b/drivers/cdrom/cdu31a.c
@@ -1338,8 +1338,10 @@ static void do_cdu31a_request(request_queue_t * q)
}
/* WTF??? */
- if (!(req->flags & REQ_CMD))
+ if (!blk_fs_request(req)) {
+ end_request(req, 0);
continue;
+ }
if (rq_data_dir(req) == WRITE) {
end_request(req, 0);
continue;
diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig
index 1b21c3a911d9..bde1c665d9f4 100644
--- a/drivers/char/Kconfig
+++ b/drivers/char/Kconfig
@@ -831,14 +831,6 @@ config DS1302
will get access to the real time clock (or hardware clock) built
into your computer.
-config S3C2410_RTC
- bool "S3C2410 RTC Driver"
- depends on ARCH_S3C2410
- help
- RTC (Realtime Clock) driver for the clock inbuilt into the
- Samsung S3C2410. This can provide periodic interrupt rates
- from 1Hz to 64Hz for user programs, and wakeup from Alarm.
-
config COBALT_LCD
bool "Support for Cobalt LCD"
depends on MIPS_COBALT
@@ -1014,6 +1006,7 @@ config GPIO_VR41XX
config RAW_DRIVER
tristate "RAW driver (/dev/raw/rawN) (OBSOLETE)"
+ depends on BLOCK
help
The raw driver permits block devices to be bound to /dev/raw/rawN.
Once bound, I/O against /dev/raw/rawN uses efficient zero-copy I/O.
diff --git a/drivers/char/Makefile b/drivers/char/Makefile
index b583d0cd9fbe..19114df59bbd 100644
--- a/drivers/char/Makefile
+++ b/drivers/char/Makefile
@@ -69,7 +69,6 @@ obj-$(CONFIG_EFI_RTC) += efirtc.o
obj-$(CONFIG_SGI_DS1286) += ds1286.o
obj-$(CONFIG_SGI_IP27_RTC) += ip27-rtc.o
obj-$(CONFIG_DS1302) += ds1302.o
-obj-$(CONFIG_S3C2410_RTC) += s3c2410-rtc.o
ifeq ($(CONFIG_GENERIC_NVRAM),y)
obj-$(CONFIG_NVRAM) += generic_nvram.o
else
diff --git a/drivers/char/agp/amd64-agp.c b/drivers/char/agp/amd64-agp.c
index 8cd52984cda5..00b17ae39736 100644
--- a/drivers/char/agp/amd64-agp.c
+++ b/drivers/char/agp/amd64-agp.c
@@ -409,7 +409,7 @@ static int __devinit uli_agp_init(struct pci_dev *pdev)
int i;
unsigned size = amd64_fetch_size();
printk(KERN_INFO "Setting up ULi AGP.\n");
- dev1 = pci_find_slot ((unsigned int)pdev->bus->number,PCI_DEVFN(0,0));
+ dev1 = pci_get_slot (pdev->bus,PCI_DEVFN(0,0));
if (dev1 == NULL) {
printk(KERN_INFO PFX "Detected a ULi chipset, "
"but could not fine the secondary device.\n");
@@ -442,6 +442,8 @@ static int __devinit uli_agp_init(struct pci_dev *pdev)
enuscr= httfea+ (size * 1024 * 1024) - 1;
pci_write_config_dword(dev1, ULI_X86_64_HTT_FEA_REG, httfea);
pci_write_config_dword(dev1, ULI_X86_64_ENU_SCR_REG, enuscr);
+
+ pci_dev_put(dev1);
return 0;
}
@@ -466,7 +468,7 @@ static int __devinit nforce3_agp_init(struct pci_dev *pdev)
printk(KERN_INFO PFX "Setting up Nforce3 AGP.\n");
- dev1 = pci_find_slot((unsigned int)pdev->bus->number, PCI_DEVFN(11, 0));
+ dev1 = pci_get_slot(pdev->bus, PCI_DEVFN(11, 0));
if (dev1 == NULL) {
printk(KERN_INFO PFX "agpgart: Detected an NVIDIA "
"nForce3 chipset, but could not find "
@@ -510,6 +512,8 @@ static int __devinit nforce3_agp_init(struct pci_dev *pdev)
pci_write_config_dword(dev1, NVIDIA_X86_64_1_APBASE2, apbase);
pci_write_config_dword(dev1, NVIDIA_X86_64_1_APLIMIT2, aplimit);
+ pci_dev_put(dev1);
+
return 0;
}
diff --git a/drivers/char/agp/generic.c b/drivers/char/agp/generic.c
index 0dcdb363923f..c39200161688 100644
--- a/drivers/char/agp/generic.c
+++ b/drivers/char/agp/generic.c
@@ -581,18 +581,21 @@ static void agp_v3_parse_one(u32 *requested_mode, u32 *bridge_agpstat, u32 *vga_
* If not, we fall back to x4 mode.
*/
if ((*bridge_agpstat & AGPSTAT3_8X) && (*vga_agpstat & AGPSTAT3_8X)) {
- printk(KERN_INFO PFX "No AGP mode specified. Setting to highest mode supported by bridge & card (x8).\n");
+ printk(KERN_INFO PFX "No AGP mode specified. Setting to highest mode "
+ "supported by bridge & card (x8).\n");
*bridge_agpstat &= ~(AGPSTAT3_4X | AGPSTAT3_RSVD);
*vga_agpstat &= ~(AGPSTAT3_4X | AGPSTAT3_RSVD);
} else {
printk(KERN_INFO PFX "Fell back to AGPx4 mode because");
if (!(*bridge_agpstat & AGPSTAT3_8X)) {
- printk("bridge couldn't do x8. bridge_agpstat:%x (orig=%x)\n", *bridge_agpstat, origbridge);
+ printk(KERN_INFO PFX "bridge couldn't do x8. bridge_agpstat:%x (orig=%x)\n",
+ *bridge_agpstat, origbridge);
*bridge_agpstat &= ~(AGPSTAT3_8X | AGPSTAT3_RSVD);
*bridge_agpstat |= AGPSTAT3_4X;
}
if (!(*vga_agpstat & AGPSTAT3_8X)) {
- printk("graphics card couldn't do x8. vga_agpstat:%x (orig=%x)\n", *vga_agpstat, origvga);
+ printk(KERN_INFO PFX "graphics card couldn't do x8. vga_agpstat:%x (orig=%x)\n",
+ *vga_agpstat, origvga);
*vga_agpstat &= ~(AGPSTAT3_8X | AGPSTAT3_RSVD);
*vga_agpstat |= AGPSTAT3_4X;
}
diff --git a/drivers/char/amiserial.c b/drivers/char/amiserial.c
index 9d6713a93ed7..d0e92ed0a367 100644
--- a/drivers/char/amiserial.c
+++ b/drivers/char/amiserial.c
@@ -1958,7 +1958,7 @@ static void show_serial_version(void)
}
-static struct tty_operations serial_ops = {
+static const struct tty_operations serial_ops = {
.open = rs_open,
.close = rs_close,
.write = rs_write,
diff --git a/drivers/char/cyclades.c b/drivers/char/cyclades.c
index c1c67281750d..f85b4eb16618 100644
--- a/drivers/char/cyclades.c
+++ b/drivers/char/cyclades.c
@@ -5205,7 +5205,7 @@ done:
extra ports are ignored.
*/
-static struct tty_operations cy_ops = {
+static const struct tty_operations cy_ops = {
.open = cy_open,
.close = cy_close,
.write = cy_write,
diff --git a/drivers/char/drm/Kconfig b/drivers/char/drm/Kconfig
index 5278c388d3e7..ef833a1c27eb 100644
--- a/drivers/char/drm/Kconfig
+++ b/drivers/char/drm/Kconfig
@@ -60,7 +60,9 @@ config DRM_I830
Choose this option if you have a system that has Intel 830M, 845G,
852GM, 855GM or 865G integrated graphics. If M is selected, the
module will be called i830. AGP support is required for this driver
- to work. This driver will eventually be replaced by the i915 one.
+ to work. This driver is used by the older X releases X.org 6.7 and
+ XFree86 4.3. If unsure, build this and i915 as modules and the X server
+ will load the correct one.
config DRM_I915
tristate "i915 driver"
@@ -68,8 +70,9 @@ config DRM_I915
Choose this option if you have a system that has Intel 830M, 845G,
852GM, 855GM 865G or 915G integrated graphics. If M is selected, the
module will be called i915. AGP support is required for this driver
- to work. This driver will eventually replace the I830 driver, when
- later release of X start to use the new DDX and DRI.
+ to work. This driver is used by the Intel driver in X.org 6.8 and
+ XFree86 4.4 and above. If unsure, build this and i830 as modules and
+ the X server will load the correct one.
endchoice
diff --git a/drivers/char/drm/Makefile b/drivers/char/drm/Makefile
index 9d180c42816c..3ad0f648c6b2 100644
--- a/drivers/char/drm/Makefile
+++ b/drivers/char/drm/Makefile
@@ -6,7 +6,7 @@ drm-objs := drm_auth.o drm_bufs.o drm_context.o drm_dma.o drm_drawable.o \
drm_drv.o drm_fops.o drm_ioctl.o drm_irq.o \
drm_lock.o drm_memory.o drm_proc.o drm_stub.o drm_vm.o \
drm_agpsupport.o drm_scatter.o ati_pcigart.o drm_pci.o \
- drm_sysfs.o
+ drm_sysfs.o drm_hashtab.o drm_sman.o drm_mm.o
tdfx-objs := tdfx_drv.o
r128-objs := r128_drv.o r128_cce.o r128_state.o r128_irq.o
@@ -16,9 +16,9 @@ i830-objs := i830_drv.o i830_dma.o i830_irq.o
i915-objs := i915_drv.o i915_dma.o i915_irq.o i915_mem.o
radeon-objs := radeon_drv.o radeon_cp.o radeon_state.o radeon_mem.o radeon_irq.o r300_cmdbuf.o
ffb-objs := ffb_drv.o ffb_context.o
-sis-objs := sis_drv.o sis_ds.o sis_mm.o
+sis-objs := sis_drv.o sis_mm.o
savage-objs := savage_drv.o savage_bci.o savage_state.o
-via-objs := via_irq.o via_drv.o via_ds.o via_map.o via_mm.o via_dma.o via_verifier.o via_video.o via_dmablit.o
+via-objs := via_irq.o via_drv.o via_map.o via_mm.o via_dma.o via_verifier.o via_video.o via_dmablit.o
ifeq ($(CONFIG_COMPAT),y)
drm-objs += drm_ioc32.o
diff --git a/drivers/char/drm/drmP.h b/drivers/char/drm/drmP.h
index d2a56182bc35..7690a59ace04 100644
--- a/drivers/char/drm/drmP.h
+++ b/drivers/char/drm/drmP.h
@@ -79,6 +79,7 @@
#define __OS_HAS_MTRR (defined(CONFIG_MTRR))
#include "drm_os_linux.h"
+#include "drm_hashtab.h"
/***********************************************************************/
/** \name DRM template customization defaults */
@@ -104,7 +105,7 @@
#define DRM_DEBUG_CODE 2 /**< Include debugging code if > 1, then
also include looping detection. */
-#define DRM_HASH_SIZE 16 /**< Size of key hash table. Must be power of 2. */
+#define DRM_MAGIC_HASH_ORDER 4 /**< Size of key hash table. Must be power of 2. */
#define DRM_KERNEL_CONTEXT 0 /**< Change drm_resctx if changed */
#define DRM_RESERVED_CONTEXTS 1 /**< Change drm_resctx if changed */
#define DRM_LOOPING_LIMIT 5000000
@@ -134,19 +135,12 @@
#define DRM_MEM_CTXBITMAP 18
#define DRM_MEM_STUB 19
#define DRM_MEM_SGLISTS 20
-#define DRM_MEM_CTXLIST 21
+#define DRM_MEM_CTXLIST 21
+#define DRM_MEM_MM 22
+#define DRM_MEM_HASHTAB 23
#define DRM_MAX_CTXBITMAP (PAGE_SIZE * 8)
-
-/*@}*/
-
-/***********************************************************************/
-/** \name Backward compatibility section */
-/*@{*/
-
-#define DRM_RPR_ARG(vma) vma,
-
-#define VM_OFFSET(vma) ((vma)->vm_pgoff << PAGE_SHIFT)
+#define DRM_MAP_HASH_OFFSET 0x10000000
/*@}*/
@@ -211,8 +205,6 @@
/*@{*/
#define DRM_ARRAY_SIZE(x) ARRAY_SIZE(x)
-#define DRM_MIN(a,b) min(a,b)
-#define DRM_MAX(a,b) max(a,b)
#define DRM_LEFTCOUNT(x) (((x)->rp + (x)->count - (x)->wp) % ((x)->count + 1))
#define DRM_BUFCOUNT(x) ((x)->count - DRM_LEFTCOUNT(x))
@@ -286,7 +278,8 @@ typedef struct drm_devstate {
} drm_devstate_t;
typedef struct drm_magic_entry {
- drm_magic_t magic;
+ drm_hash_item_t hash_item;
+ struct list_head head;
struct drm_file *priv;
struct drm_magic_entry *next;
} drm_magic_entry_t;
@@ -493,6 +486,7 @@ typedef struct drm_sigdata {
*/
typedef struct drm_map_list {
struct list_head head; /**< list head */
+ drm_hash_item_t hash;
drm_map_t *map; /**< mapping */
unsigned int user_token;
} drm_map_list_t;
@@ -527,6 +521,22 @@ typedef struct ati_pcigart_info {
drm_local_map_t mapping;
} drm_ati_pcigart_info;
+/*
+ * Generic memory manager structs
+ */
+typedef struct drm_mm_node {
+ struct list_head fl_entry;
+ struct list_head ml_entry;
+ int free;
+ unsigned long start;
+ unsigned long size;
+ void *private;
+} drm_mm_node_t;
+
+typedef struct drm_mm {
+ drm_mm_node_t root_node;
+} drm_mm_t;
+
/**
* DRM driver structure. This structure represent the common code for
* a family of cards. There will one drm_device for each card present
@@ -646,13 +656,15 @@ typedef struct drm_device {
/*@{ */
drm_file_t *file_first; /**< file list head */
drm_file_t *file_last; /**< file list tail */
- drm_magic_head_t magiclist[DRM_HASH_SIZE]; /**< magic hash table */
+ drm_open_hash_t magiclist; /**< magic hash table */
+ struct list_head magicfree;
/*@} */
/** \name Memory management */
/*@{ */
drm_map_list_t *maplist; /**< Linked list of regions */
int map_count; /**< Number of mappable regions */
+ drm_open_hash_t map_hash; /**< User token hash table for maps */
/** \name Context handle management */
/*@{ */
@@ -711,10 +723,8 @@ typedef struct drm_device {
drm_agp_head_t *agp; /**< AGP data */
struct pci_dev *pdev; /**< PCI device structure */
- int pci_domain; /**< PCI bus domain number */
- int pci_bus; /**< PCI bus number */
- int pci_slot; /**< PCI slot number */
- int pci_func; /**< PCI function number */
+ int pci_vendor; /**< PCI vendor id */
+ int pci_device; /**< PCI device id */
#ifdef __alpha__
struct pci_controller *hose;
#endif
@@ -736,6 +746,12 @@ static __inline__ int drm_core_check_feature(struct drm_device *dev,
return ((dev->driver->driver_features & feature) ? 1 : 0);
}
+#ifdef __alpha__
+#define drm_get_pci_domain(dev) dev->hose->bus->number
+#else
+#define drm_get_pci_domain(dev) 0
+#endif
+
#if __OS_HAS_AGP
static inline int drm_core_has_AGP(struct drm_device *dev)
{
@@ -1011,6 +1027,18 @@ extern struct class_device *drm_sysfs_device_add(struct class *cs,
drm_head_t *head);
extern void drm_sysfs_device_remove(struct class_device *class_dev);
+/*
+ * Basic memory manager support (drm_mm.c)
+ */
+extern drm_mm_node_t *drm_mm_get_block(drm_mm_node_t * parent,
+ unsigned long size,
+ unsigned alignment);
+extern void drm_mm_put_block(drm_mm_t *mm, drm_mm_node_t *cur);
+extern drm_mm_node_t *drm_mm_search_free(const drm_mm_t *mm, unsigned long size,
+ unsigned alignment, int best_match);
+extern int drm_mm_init(drm_mm_t *mm, unsigned long start, unsigned long size);
+extern void drm_mm_takedown(drm_mm_t *mm);
+
/* Inline replacements for DRM_IOREMAP macros */
static __inline__ void drm_core_ioremap(struct drm_map *map,
struct drm_device *dev)
diff --git a/drivers/char/drm/drm_auth.c b/drivers/char/drm/drm_auth.c
index 2a37586a7ee8..c7b19d35bcd6 100644
--- a/drivers/char/drm/drm_auth.c
+++ b/drivers/char/drm/drm_auth.c
@@ -36,20 +36,6 @@
#include "drmP.h"
/**
- * Generate a hash key from a magic.
- *
- * \param magic magic.
- * \return hash key.
- *
- * The key is the modulus of the hash table size, #DRM_HASH_SIZE, which must be
- * a power of 2.
- */
-static int drm_hash_magic(drm_magic_t magic)
-{
- return magic & (DRM_HASH_SIZE - 1);
-}
-
-/**
* Find the file with the given magic number.
*
* \param dev DRM device.
@@ -63,14 +49,12 @@ static drm_file_t *drm_find_file(drm_device_t * dev, drm_magic_t magic)
{
drm_file_t *retval = NULL;
drm_magic_entry_t *pt;
- int hash = drm_hash_magic(magic);
+ drm_hash_item_t *hash;
mutex_lock(&dev->struct_mutex);
- for (pt = dev->magiclist[hash].head; pt; pt = pt->next) {
- if (pt->magic == magic) {
- retval = pt->priv;
- break;
- }
+ if (!drm_ht_find_item(&dev->magiclist, (unsigned long)magic, &hash)) {
+ pt = drm_hash_entry(hash, drm_magic_entry_t, hash_item);
+ retval = pt->priv;
}
mutex_unlock(&dev->struct_mutex);
return retval;
@@ -90,28 +74,20 @@ static drm_file_t *drm_find_file(drm_device_t * dev, drm_magic_t magic)
static int drm_add_magic(drm_device_t * dev, drm_file_t * priv,
drm_magic_t magic)
{
- int hash;
drm_magic_entry_t *entry;
DRM_DEBUG("%d\n", magic);
- hash = drm_hash_magic(magic);
entry = drm_alloc(sizeof(*entry), DRM_MEM_MAGIC);
if (!entry)
return -ENOMEM;
memset(entry, 0, sizeof(*entry));
- entry->magic = magic;
entry->priv = priv;
- entry->next = NULL;
+ entry->hash_item.key = (unsigned long)magic;
mutex_lock(&dev->struct_mutex);
- if (dev->magiclist[hash].tail) {
- dev->magiclist[hash].tail->next = entry;
- dev->magiclist[hash].tail = entry;
- } else {
- dev->magiclist[hash].head = entry;
- dev->magiclist[hash].tail = entry;
- }
+ drm_ht_insert_item(&dev->magiclist, &entry->hash_item);
+ list_add_tail(&entry->head, &dev->magicfree);
mutex_unlock(&dev->struct_mutex);
return 0;
@@ -128,34 +104,24 @@ static int drm_add_magic(drm_device_t * dev, drm_file_t * priv,
*/
static int drm_remove_magic(drm_device_t * dev, drm_magic_t magic)
{
- drm_magic_entry_t *prev = NULL;
drm_magic_entry_t *pt;
- int hash;
+ drm_hash_item_t *hash;
DRM_DEBUG("%d\n", magic);
- hash = drm_hash_magic(magic);
mutex_lock(&dev->struct_mutex);
- for (pt = dev->magiclist[hash].head; pt; prev = pt, pt = pt->next) {
- if (pt->magic == magic) {
- if (dev->magiclist[hash].head == pt) {
- dev->magiclist[hash].head = pt->next;
- }
- if (dev->magiclist[hash].tail == pt) {
- dev->magiclist[hash].tail = prev;
- }
- if (prev) {
- prev->next = pt->next;
- }
- mutex_unlock(&dev->struct_mutex);
- return 0;
- }
+ if (drm_ht_find_item(&dev->magiclist, (unsigned long)magic, &hash)) {
+ mutex_unlock(&dev->struct_mutex);
+ return -EINVAL;
}
+ pt = drm_hash_entry(hash, drm_magic_entry_t, hash_item);
+ drm_ht_remove_item(&dev->magiclist, hash);
+ list_del(&pt->head);
mutex_unlock(&dev->struct_mutex);
drm_free(pt, sizeof(*pt), DRM_MEM_MAGIC);
- return -EINVAL;
+ return 0;
}
/**
diff --git a/drivers/char/drm/drm_bufs.c b/drivers/char/drm/drm_bufs.c
index 006b06d29727..029baea33b62 100644
--- a/drivers/char/drm/drm_bufs.c
+++ b/drivers/char/drm/drm_bufs.c
@@ -65,43 +65,29 @@ static drm_map_list_t *drm_find_matching_map(drm_device_t *dev,
return NULL;
}
-/*
- * Used to allocate 32-bit handles for mappings.
- */
-#define START_RANGE 0x10000000
-#define END_RANGE 0x40000000
-
-#ifdef _LP64
-static __inline__ unsigned int HandleID(unsigned long lhandle,
- drm_device_t *dev)
+static int drm_map_handle(drm_device_t *dev, drm_hash_item_t *hash,
+ unsigned long user_token, int hashed_handle)
{
- static unsigned int map32_handle = START_RANGE;
- unsigned int hash;
-
- if (lhandle & 0xffffffff00000000) {
- hash = map32_handle;
- map32_handle += PAGE_SIZE;
- if (map32_handle > END_RANGE)
- map32_handle = START_RANGE;
- } else
- hash = lhandle;
-
- while (1) {
- drm_map_list_t *_entry;
- list_for_each_entry(_entry, &dev->maplist->head, head) {
- if (_entry->user_token == hash)
- break;
- }
- if (&_entry->head == &dev->maplist->head)
- return hash;
+ int use_hashed_handle;
+#if (BITS_PER_LONG == 64)
+ use_hashed_handle = ((user_token & 0xFFFFFFFF00000000UL) || hashed_handle);
+#elif (BITS_PER_LONG == 32)
+ use_hashed_handle = hashed_handle;
+#else
+#error Unsupported long size. Neither 64 nor 32 bits.
+#endif
- hash += PAGE_SIZE;
- map32_handle += PAGE_SIZE;
+ if (!use_hashed_handle) {
+ int ret;
+ hash->key = user_token;
+ ret = drm_ht_insert_item(&dev->map_hash, hash);
+ if (ret != -EINVAL)
+ return ret;
}
+ return drm_ht_just_insert_please(&dev->map_hash, hash,
+ user_token, 32 - PAGE_SHIFT - 3,
+ PAGE_SHIFT, DRM_MAP_HASH_OFFSET);
}
-#else
-# define HandleID(x,dev) (unsigned int)(x)
-#endif
/**
* Ioctl to specify a range of memory that is available for mapping by a non-root process.
@@ -123,6 +109,8 @@ static int drm_addmap_core(drm_device_t * dev, unsigned int offset,
drm_map_t *map;
drm_map_list_t *list;
drm_dma_handle_t *dmah;
+ unsigned long user_token;
+ int ret;
map = drm_alloc(sizeof(*map), DRM_MEM_MAPS);
if (!map)
@@ -257,11 +245,20 @@ static int drm_addmap_core(drm_device_t * dev, unsigned int offset,
mutex_lock(&dev->struct_mutex);
list_add(&list->head, &dev->maplist->head);
+
/* Assign a 32-bit handle */
/* We do it here so that dev->struct_mutex protects the increment */
- list->user_token = HandleID(map->type == _DRM_SHM
- ? (unsigned long)map->handle
- : map->offset, dev);
+ user_token = (map->type == _DRM_SHM) ? (unsigned long)map->handle :
+ map->offset;
+ ret = drm_map_handle(dev, &list->hash, user_token, 0);
+ if (ret) {
+ drm_free(map, sizeof(*map), DRM_MEM_MAPS);
+ drm_free(list, sizeof(*list), DRM_MEM_MAPS);
+ mutex_unlock(&dev->struct_mutex);
+ return ret;
+ }
+
+ list->user_token = list->hash.key;
mutex_unlock(&dev->struct_mutex);
*maplist = list;
@@ -346,6 +343,7 @@ int drm_rmmap_locked(drm_device_t *dev, drm_local_map_t *map)
if (r_list->map == map) {
list_del(list);
+ drm_ht_remove_key(&dev->map_hash, r_list->user_token);
drm_free(list, sizeof(*list), DRM_MEM_MAPS);
break;
}
@@ -441,8 +439,10 @@ int drm_rmmap_ioctl(struct inode *inode, struct file *filp,
return -EINVAL;
}
- if (!map)
+ if (!map) {
+ mutex_unlock(&dev->struct_mutex);
return -EINVAL;
+ }
/* Register and framebuffer maps are permanent */
if ((map->type == _DRM_REGISTERS) || (map->type == _DRM_FRAME_BUFFER)) {
diff --git a/drivers/char/drm/drm_drv.c b/drivers/char/drm/drm_drv.c
index 3c0b882a8e72..b366c5b1bd16 100644
--- a/drivers/char/drm/drm_drv.c
+++ b/drivers/char/drm/drm_drv.c
@@ -118,7 +118,7 @@ static drm_ioctl_desc_t drm_ioctls[] = {
[DRM_IOCTL_NR(DRM_IOCTL_WAIT_VBLANK)] = {drm_wait_vblank, 0},
};
-#define DRIVER_IOCTL_COUNT DRM_ARRAY_SIZE( drm_ioctls )
+#define DRIVER_IOCTL_COUNT ARRAY_SIZE( drm_ioctls )
/**
* Take down the DRM device.
@@ -155,12 +155,13 @@ int drm_lastclose(drm_device_t * dev)
del_timer(&dev->timer);
/* Clear pid list */
- for (i = 0; i < DRM_HASH_SIZE; i++) {
- for (pt = dev->magiclist[i].head; pt; pt = next) {
- next = pt->next;
+ if (dev->magicfree.next) {
+ list_for_each_entry_safe(pt, next, &dev->magicfree, head) {
+ list_del(&pt->head);
+ drm_ht_remove_item(&dev->magiclist, &pt->hash_item);
drm_free(pt, sizeof(*pt), DRM_MEM_MAGIC);
}
- dev->magiclist[i].head = dev->magiclist[i].tail = NULL;
+ drm_ht_remove(&dev->magiclist);
}
/* Clear AGP information */
@@ -299,6 +300,7 @@ static void drm_cleanup(drm_device_t * dev)
if (dev->maplist) {
drm_free(dev->maplist, sizeof(*dev->maplist), DRM_MEM_MAPS);
dev->maplist = NULL;
+ drm_ht_remove(&dev->map_hash);
}
drm_ctxbitmap_cleanup(dev);
diff --git a/drivers/char/drm/drm_fops.c b/drivers/char/drm/drm_fops.c
index b7f7951c4587..898f47dafec0 100644
--- a/drivers/char/drm/drm_fops.c
+++ b/drivers/char/drm/drm_fops.c
@@ -53,6 +53,8 @@ static int drm_setup(drm_device_t * dev)
return ret;
}
+ dev->magicfree.next = NULL;
+
/* prebuild the SAREA */
i = drm_addmap(dev, 0, SAREA_MAX, _DRM_SHM, _DRM_CONTAINS_LOCK, &map);
if (i != 0)
@@ -69,13 +71,11 @@ static int drm_setup(drm_device_t * dev)
return i;
}
- for (i = 0; i < DRM_ARRAY_SIZE(dev->counts); i++)
+ for (i = 0; i < ARRAY_SIZE(dev->counts); i++)
atomic_set(&dev->counts[i], 0);
- for (i = 0; i < DRM_HASH_SIZE; i++) {
- dev->magiclist[i].head = NULL;
- dev->magiclist[i].tail = NULL;
- }
+ drm_ht_create(&dev->magiclist, DRM_MAGIC_HASH_ORDER);
+ INIT_LIST_HEAD(&dev->magicfree);
dev->ctxlist = drm_alloc(sizeof(*dev->ctxlist), DRM_MEM_CTXLIST);
if (dev->ctxlist == NULL)
diff --git a/drivers/char/drm/drm_hashtab.c b/drivers/char/drm/drm_hashtab.c
new file mode 100644
index 000000000000..a0b2d6802ae4
--- /dev/null
+++ b/drivers/char/drm/drm_hashtab.c
@@ -0,0 +1,190 @@
+/**************************************************************************
+ *
+ * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND. USA.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ * USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ *
+ **************************************************************************/
+/*
+ * Simple open hash tab implementation.
+ *
+ * Authors:
+ * Thomas Hellström <thomas-at-tungstengraphics-dot-com>
+ */
+
+#include "drmP.h"
+#include "drm_hashtab.h"
+#include <linux/hash.h>
+
+int drm_ht_create(drm_open_hash_t *ht, unsigned int order)
+{
+ unsigned int i;
+
+ ht->size = 1 << order;
+ ht->order = order;
+ ht->fill = 0;
+ ht->table = vmalloc(ht->size*sizeof(*ht->table));
+ if (!ht->table) {
+ DRM_ERROR("Out of memory for hash table\n");
+ return -ENOMEM;
+ }
+ for (i=0; i< ht->size; ++i) {
+ INIT_HLIST_HEAD(&ht->table[i]);
+ }
+ return 0;
+}
+
+void drm_ht_verbose_list(drm_open_hash_t *ht, unsigned long key)
+{
+ drm_hash_item_t *entry;
+ struct hlist_head *h_list;
+ struct hlist_node *list;
+ unsigned int hashed_key;
+ int count = 0;
+
+ hashed_key = hash_long(key, ht->order);
+ DRM_DEBUG("Key is 0x%08lx, Hashed key is 0x%08x\n", key, hashed_key);
+ h_list = &ht->table[hashed_key];
+ hlist_for_each(list, h_list) {
+ entry = hlist_entry(list, drm_hash_item_t, head);
+ DRM_DEBUG("count %d, key: 0x%08lx\n", count++, entry->key);
+ }
+}
+
+static struct hlist_node *drm_ht_find_key(drm_open_hash_t *ht,
+ unsigned long key)
+{
+ drm_hash_item_t *entry;
+ struct hlist_head *h_list;
+ struct hlist_node *list;
+ unsigned int hashed_key;
+
+ hashed_key = hash_long(key, ht->order);
+ h_list = &ht->table[hashed_key];
+ hlist_for_each(list, h_list) {
+ entry = hlist_entry(list, drm_hash_item_t, head);
+ if (entry->key == key)
+ return list;
+ if (entry->key > key)
+ break;
+ }
+ return NULL;
+}
+
+
+int drm_ht_insert_item(drm_open_hash_t *ht, drm_hash_item_t *item)
+{
+ drm_hash_item_t *entry;
+ struct hlist_head *h_list;
+ struct hlist_node *list, *parent;
+ unsigned int hashed_key;
+ unsigned long key = item->key;
+
+ hashed_key = hash_long(key, ht->order);
+ h_list = &ht->table[hashed_key];
+ parent = NULL;
+ hlist_for_each(list, h_list) {
+ entry = hlist_entry(list, drm_hash_item_t, head);
+ if (entry->key == key)
+ return -EINVAL;
+ if (entry->key > key)
+ break;
+ parent = list;
+ }
+ if (parent) {
+ hlist_add_after(parent, &item->head);
+ } else {
+ hlist_add_head(&item->head, h_list);
+ }
+ return 0;
+}
+
+/*
+ * Just insert an item and return any "bits" bit key that hasn't been
+ * used before.
+ */
+int drm_ht_just_insert_please(drm_open_hash_t *ht, drm_hash_item_t *item,
+ unsigned long seed, int bits, int shift,
+ unsigned long add)
+{
+ int ret;
+ unsigned long mask = (1 << bits) - 1;
+ unsigned long first, unshifted_key;
+
+ unshifted_key = hash_long(seed, bits);
+ first = unshifted_key;
+ do {
+ item->key = (unshifted_key << shift) + add;
+ ret = drm_ht_insert_item(ht, item);
+ if (ret)
+ unshifted_key = (unshifted_key + 1) & mask;
+ } while(ret && (unshifted_key != first));
+
+ if (ret) {
+ DRM_ERROR("Available key bit space exhausted\n");
+ return -EINVAL;
+ }
+ return 0;
+}
+
+int drm_ht_find_item(drm_open_hash_t *ht, unsigned long key,
+ drm_hash_item_t **item)
+{
+ struct hlist_node *list;
+
+ list = drm_ht_find_key(ht, key);
+ if (!list)
+ return -EINVAL;
+
+ *item = hlist_entry(list, drm_hash_item_t, head);
+ return 0;
+}
+
+int drm_ht_remove_key(drm_open_hash_t *ht, unsigned long key)
+{
+ struct hlist_node *list;
+
+ list = drm_ht_find_key(ht, key);
+ if (list) {
+ hlist_del_init(list);
+ ht->fill--;
+ return 0;
+ }
+ return -EINVAL;
+}
+
+int drm_ht_remove_item(drm_open_hash_t *ht, drm_hash_item_t *item)
+{
+ hlist_del_init(&item->head);
+ ht->fill--;
+ return 0;
+}
+
+void drm_ht_remove(drm_open_hash_t *ht)
+{
+ if (ht->table) {
+ vfree(ht->table);
+ ht->table = NULL;
+ }
+}
+
diff --git a/drivers/char/drm/drm_hashtab.h b/drivers/char/drm/drm_hashtab.h
new file mode 100644
index 000000000000..40afec05bff8
--- /dev/null
+++ b/drivers/char/drm/drm_hashtab.h
@@ -0,0 +1,67 @@
+/**************************************************************************
+ *
+ * Copyright 2006 Tungsten Graphics, Inc., Bismack, ND. USA.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ * USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ *
+ **************************************************************************/
+/*
+ * Simple open hash tab implementation.
+ *
+ * Authors:
+ * Thomas Hellström <thomas-at-tungstengraphics-dot-com>
+ */
+
+#ifndef DRM_HASHTAB_H
+#define DRM_HASHTAB_H
+
+#define drm_hash_entry(_ptr, _type, _member) container_of(_ptr, _type, _member)
+
+typedef struct drm_hash_item{
+ struct hlist_node head;
+ unsigned long key;
+} drm_hash_item_t;
+
+typedef struct drm_open_hash{
+ unsigned int size;
+ unsigned int order;
+ unsigned int fill;
+ struct hlist_head *table;
+} drm_open_hash_t;
+
+
+extern int drm_ht_create(drm_open_hash_t *ht, unsigned int order);
+extern int drm_ht_insert_item(drm_open_hash_t *ht, drm_hash_item_t *item);
+extern int drm_ht_just_insert_please(drm_open_hash_t *ht, drm_hash_item_t *item,
+ unsigned long seed, int bits, int shift,
+ unsigned long add);
+extern int drm_ht_find_item(drm_open_hash_t *ht, unsigned long key, drm_hash_item_t **item);
+
+extern void drm_ht_verbose_list(drm_open_hash_t *ht, unsigned long key);
+extern int drm_ht_remove_key(drm_open_hash_t *ht, unsigned long key);
+extern int drm_ht_remove_item(drm_open_hash_t *ht, drm_hash_item_t *item);
+extern void drm_ht_remove(drm_open_hash_t *ht);
+
+
+#endif
+
diff --git a/drivers/char/drm/drm_ioc32.c b/drivers/char/drm/drm_ioc32.c
index e9e2db18952d..d4f874520082 100644
--- a/drivers/char/drm/drm_ioc32.c
+++ b/drivers/char/drm/drm_ioc32.c
@@ -1051,7 +1051,7 @@ long drm_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
drm_ioctl_compat_t *fn;
int ret;
- if (nr >= DRM_ARRAY_SIZE(drm_compat_ioctls))
+ if (nr >= ARRAY_SIZE(drm_compat_ioctls))
return -ENOTTY;
fn = drm_compat_ioctls[nr];
diff --git a/drivers/char/drm/drm_ioctl.c b/drivers/char/drm/drm_ioctl.c
index 555f323b8a32..565895547d75 100644
--- a/drivers/char/drm/drm_ioctl.c
+++ b/drivers/char/drm/drm_ioctl.c
@@ -127,9 +127,10 @@ int drm_setunique(struct inode *inode, struct file *filp,
domain = bus >> 8;
bus &= 0xff;
- if ((domain != dev->pci_domain) ||
- (bus != dev->pci_bus) ||
- (slot != dev->pci_slot) || (func != dev->pci_func))
+ if ((domain != drm_get_pci_domain(dev)) ||
+ (bus != dev->pdev->bus->number) ||
+ (slot != PCI_SLOT(dev->pdev->devfn)) ||
+ (func != PCI_FUNC(dev->pdev->devfn)))
return -EINVAL;
return 0;
@@ -140,15 +141,17 @@ static int drm_set_busid(drm_device_t * dev)
int len;
if (dev->unique != NULL)
- return EBUSY;
+ return 0;
dev->unique_len = 40;
dev->unique = drm_alloc(dev->unique_len + 1, DRM_MEM_DRIVER);
if (dev->unique == NULL)
- return ENOMEM;
+ return -ENOMEM;
len = snprintf(dev->unique, dev->unique_len, "pci:%04x:%02x:%02x.%d",
- dev->pci_domain, dev->pci_bus, dev->pci_slot, dev->pci_func);
+ drm_get_pci_domain(dev), dev->pdev->bus->number,
+ PCI_SLOT(dev->pdev->devfn),
+ PCI_FUNC(dev->pdev->devfn));
if (len > dev->unique_len)
DRM_ERROR("Unique buffer overflowed\n");
@@ -157,7 +160,7 @@ static int drm_set_busid(drm_device_t * dev)
drm_alloc(strlen(dev->driver->pci_driver.name) + dev->unique_len +
2, DRM_MEM_DRIVER);
if (dev->devname == NULL)
- return ENOMEM;
+ return -ENOMEM;
sprintf(dev->devname, "%s@%s", dev->driver->pci_driver.name,
dev->unique);
@@ -330,27 +333,32 @@ int drm_setversion(DRM_IOCTL_ARGS)
drm_set_version_t retv;
int if_version;
drm_set_version_t __user *argp = (void __user *)data;
+ int ret;
- DRM_COPY_FROM_USER_IOCTL(sv, argp, sizeof(sv));
+ if (copy_from_user(&sv, argp, sizeof(sv)))
+ return -EFAULT;
retv.drm_di_major = DRM_IF_MAJOR;
retv.drm_di_minor = DRM_IF_MINOR;
retv.drm_dd_major = dev->driver->major;
retv.drm_dd_minor = dev->driver->minor;
- DRM_COPY_TO_USER_IOCTL(argp, retv, sizeof(sv));
+ if (copy_to_user(argp, &retv, sizeof(retv)))
+ return -EFAULT;
if (sv.drm_di_major != -1) {
if (sv.drm_di_major != DRM_IF_MAJOR ||
sv.drm_di_minor < 0 || sv.drm_di_minor > DRM_IF_MINOR)
- return EINVAL;
+ return -EINVAL;
if_version = DRM_IF_VERSION(sv.drm_di_major, sv.drm_di_minor);
- dev->if_version = DRM_MAX(if_version, dev->if_version);
+ dev->if_version = max(if_version, dev->if_version);
if (sv.drm_di_minor >= 1) {
/*
* Version 1.1 includes tying of DRM to specific device
*/
- drm_set_busid(dev);
+ ret = drm_set_busid(dev);
+ if (ret)
+ return ret;
}
}
@@ -358,7 +366,7 @@ int drm_setversion(DRM_IOCTL_ARGS)
if (sv.drm_dd_major != dev->driver->major ||
sv.drm_dd_minor < 0
|| sv.drm_dd_minor > dev->driver->minor)
- return EINVAL;
+ return -EINVAL;
if (dev->driver->set_version)
dev->driver->set_version(dev, &sv);
diff --git a/drivers/char/drm/drm_irq.c b/drivers/char/drm/drm_irq.c
index ebdb7182c4fd..4553a3a1e496 100644
--- a/drivers/char/drm/drm_irq.c
+++ b/drivers/char/drm/drm_irq.c
@@ -64,9 +64,9 @@ int drm_irq_by_busid(struct inode *inode, struct file *filp,
if (copy_from_user(&p, argp, sizeof(p)))
return -EFAULT;
- if ((p.busnum >> 8) != dev->pci_domain ||
- (p.busnum & 0xff) != dev->pci_bus ||
- p.devnum != dev->pci_slot || p.funcnum != dev->pci_func)
+ if ((p.busnum >> 8) != drm_get_pci_domain(dev) ||
+ (p.busnum & 0xff) != dev->pdev->bus->number ||
+ p.devnum != PCI_SLOT(dev->pdev->devfn) || p.funcnum != PCI_FUNC(dev->pdev->devfn))
return -EINVAL;
p.irq = dev->irq;
@@ -255,7 +255,8 @@ int drm_wait_vblank(DRM_IOCTL_ARGS)
if (!dev->irq)
return -EINVAL;
- DRM_COPY_FROM_USER_IOCTL(vblwait, argp, sizeof(vblwait));
+ if (copy_from_user(&vblwait, argp, sizeof(vblwait)))
+ return -EFAULT;
switch (vblwait.request.type & ~_DRM_VBLANK_FLAGS_MASK) {
case _DRM_VBLANK_RELATIVE:
@@ -329,7 +330,8 @@ int drm_wait_vblank(DRM_IOCTL_ARGS)
}
done:
- DRM_COPY_TO_USER_IOCTL(argp, vblwait, sizeof(vblwait));
+ if (copy_to_user(argp, &vblwait, sizeof(vblwait)))
+ return -EFAULT;
return ret;
}
diff --git a/drivers/char/drm/drm_mm.c b/drivers/char/drm/drm_mm.c
new file mode 100644
index 000000000000..617526bd5b0c
--- /dev/null
+++ b/drivers/char/drm/drm_mm.c
@@ -0,0 +1,201 @@
+/**************************************************************************
+ *
+ * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND., USA.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ * USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ *
+ **************************************************************************/
+
+/*
+ * Generic simple memory manager implementation. Intended to be used as a base
+ * class implementation for more advanced memory managers.
+ *
+ * Note that the algorithm used is quite simple and there might be substantial
+ * performance gains if a smarter free list is implemented. Currently it is just an
+ * unordered stack of free regions. This could easily be improved if an RB-tree
+ * is used instead. At least if we expect heavy fragmentation.
+ *
+ * Aligned allocations can also see improvement.
+ *
+ * Authors:
+ * Thomas Hellström <thomas-at-tungstengraphics-dot-com>
+ */
+
+#include "drmP.h"
+
+drm_mm_node_t *drm_mm_get_block(drm_mm_node_t * parent,
+ unsigned long size, unsigned alignment)
+{
+
+ drm_mm_node_t *child;
+
+ if (alignment)
+ size += alignment - 1;
+
+ if (parent->size == size) {
+ list_del_init(&parent->fl_entry);
+ parent->free = 0;
+ return parent;
+ } else {
+ child = (drm_mm_node_t *) drm_alloc(sizeof(*child), DRM_MEM_MM);
+ if (!child)
+ return NULL;
+
+ INIT_LIST_HEAD(&child->ml_entry);
+ INIT_LIST_HEAD(&child->fl_entry);
+
+ child->free = 0;
+ child->size = size;
+ child->start = parent->start;
+
+ list_add_tail(&child->ml_entry, &parent->ml_entry);
+ parent->size -= size;
+ parent->start += size;
+ }
+ return child;
+}
+
+/*
+ * Put a block. Merge with the previous and / or next block if they are free.
+ * Otherwise add to the free stack.
+ */
+
+void drm_mm_put_block(drm_mm_t * mm, drm_mm_node_t * cur)
+{
+
+ drm_mm_node_t *list_root = &mm->root_node;
+ struct list_head *cur_head = &cur->ml_entry;
+ struct list_head *root_head = &list_root->ml_entry;
+ drm_mm_node_t *prev_node = NULL;
+ drm_mm_node_t *next_node;
+
+ int merged = 0;
+
+ if (cur_head->prev != root_head) {
+ prev_node = list_entry(cur_head->prev, drm_mm_node_t, ml_entry);
+ if (prev_node->free) {
+ prev_node->size += cur->size;
+ merged = 1;
+ }
+ }
+ if (cur_head->next != root_head) {
+ next_node = list_entry(cur_head->next, drm_mm_node_t, ml_entry);
+ if (next_node->free) {
+ if (merged) {
+ prev_node->size += next_node->size;
+ list_del(&next_node->ml_entry);
+ list_del(&next_node->fl_entry);
+ drm_free(next_node, sizeof(*next_node),
+ DRM_MEM_MM);
+ } else {
+ next_node->size += cur->size;
+ next_node->start = cur->start;
+ merged = 1;
+ }
+ }
+ }
+ if (!merged) {
+ cur->free = 1;
+ list_add(&cur->fl_entry, &list_root->fl_entry);
+ } else {
+ list_del(&cur->ml_entry);
+ drm_free(cur, sizeof(*cur), DRM_MEM_MM);
+ }
+}
+
+drm_mm_node_t *drm_mm_search_free(const drm_mm_t * mm,
+ unsigned long size,
+ unsigned alignment, int best_match)
+{
+ struct list_head *list;
+ const struct list_head *free_stack = &mm->root_node.fl_entry;
+ drm_mm_node_t *entry;
+ drm_mm_node_t *best;
+ unsigned long best_size;
+
+ best = NULL;
+ best_size = ~0UL;
+
+ if (alignment)
+ size += alignment - 1;
+
+ list_for_each(list, free_stack) {
+ entry = list_entry(list, drm_mm_node_t, fl_entry);
+ if (entry->size >= size) {
+ if (!best_match)
+ return entry;
+ if (size < best_size) {
+ best = entry;
+ best_size = entry->size;
+ }
+ }
+ }
+
+ return best;
+}
+
+int drm_mm_init(drm_mm_t * mm, unsigned long start, unsigned long size)
+{
+ drm_mm_node_t *child;
+
+ INIT_LIST_HEAD(&mm->root_node.ml_entry);
+ INIT_LIST_HEAD(&mm->root_node.fl_entry);
+ child = (drm_mm_node_t *) drm_alloc(sizeof(*child), DRM_MEM_MM);
+ if (!child)
+ return -ENOMEM;
+
+ INIT_LIST_HEAD(&child->ml_entry);
+ INIT_LIST_HEAD(&child->fl_entry);
+
+ child->start = start;
+ child->size = size;
+ child->free = 1;
+
+ list_add(&child->fl_entry, &mm->root_node.fl_entry);
+ list_add(&child->ml_entry, &mm->root_node.ml_entry);
+
+ return 0;
+}
+
+EXPORT_SYMBOL(drm_mm_init);
+
+void drm_mm_takedown(drm_mm_t * mm)
+{
+ struct list_head *bnode = mm->root_node.fl_entry.next;
+ drm_mm_node_t *entry;
+
+ entry = list_entry(bnode, drm_mm_node_t, fl_entry);
+
+ if (entry->ml_entry.next != &mm->root_node.ml_entry ||
+ entry->fl_entry.next != &mm->root_node.fl_entry) {
+ DRM_ERROR("Memory manager not clean. Delaying takedown\n");
+ return;
+ }
+
+ list_del(&entry->fl_entry);
+ list_del(&entry->ml_entry);
+
+ drm_free(entry, sizeof(*entry), DRM_MEM_MM);
+}
+
+EXPORT_SYMBOL(drm_mm_takedown);
diff --git a/drivers/char/drm/drm_pciids.h b/drivers/char/drm/drm_pciids.h
index b1bb3c7b568d..09398d5fbd3f 100644
--- a/drivers/char/drm/drm_pciids.h
+++ b/drivers/char/drm/drm_pciids.h
@@ -3,13 +3,13 @@
Please contact dri-devel@lists.sf.net to add new cards to this list
*/
#define radeon_PCI_IDS \
- {0x1002, 0x3150, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|CHIP_IS_MOBILITY}, \
- {0x1002, 0x3152, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|CHIP_IS_MOBILITY|CHIP_NEW_MEMMAP}, \
- {0x1002, 0x3154, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|CHIP_IS_MOBILITY|CHIP_NEW_MEMMAP}, \
- {0x1002, 0x3E50, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|CHIP_NEW_MEMMAP}, \
- {0x1002, 0x3E54, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|CHIP_NEW_MEMMAP}, \
- {0x1002, 0x4136, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS100|CHIP_IS_IGP}, \
- {0x1002, 0x4137, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS200|CHIP_IS_IGP}, \
+ {0x1002, 0x3150, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_IS_MOBILITY}, \
+ {0x1002, 0x3152, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \
+ {0x1002, 0x3154, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \
+ {0x1002, 0x3E50, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_NEW_MEMMAP}, \
+ {0x1002, 0x3E54, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_NEW_MEMMAP}, \
+ {0x1002, 0x4136, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS100|RADEON_IS_IGP}, \
+ {0x1002, 0x4137, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS200|RADEON_IS_IGP}, \
{0x1002, 0x4144, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R300}, \
{0x1002, 0x4145, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R300}, \
{0x1002, 0x4146, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R300}, \
@@ -25,35 +25,35 @@
{0x1002, 0x4154, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350}, \
{0x1002, 0x4155, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350}, \
{0x1002, 0x4156, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350}, \
- {0x1002, 0x4237, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS200|CHIP_IS_IGP}, \
+ {0x1002, 0x4237, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS200|RADEON_IS_IGP}, \
{0x1002, 0x4242, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R200}, \
{0x1002, 0x4243, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R200}, \
- {0x1002, 0x4336, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS100|CHIP_IS_IGP|CHIP_IS_MOBILITY}, \
- {0x1002, 0x4337, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS200|CHIP_IS_IGP|CHIP_IS_MOBILITY}, \
- {0x1002, 0x4437, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS200|CHIP_IS_IGP|CHIP_IS_MOBILITY}, \
+ {0x1002, 0x4336, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS100|RADEON_IS_IGP|RADEON_IS_MOBILITY}, \
+ {0x1002, 0x4337, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS200|RADEON_IS_IGP|RADEON_IS_MOBILITY}, \
+ {0x1002, 0x4437, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS200|RADEON_IS_IGP|RADEON_IS_MOBILITY}, \
{0x1002, 0x4966, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV250}, \
{0x1002, 0x4967, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV250}, \
- {0x1002, 0x4A48, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \
- {0x1002, 0x4A49, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \
- {0x1002, 0x4A4A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \
- {0x1002, 0x4A4B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \
- {0x1002, 0x4A4C, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \
- {0x1002, 0x4A4D, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \
- {0x1002, 0x4A4E, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_IS_MOBILITY|CHIP_NEW_MEMMAP}, \
- {0x1002, 0x4A4F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \
- {0x1002, 0x4A50, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \
- {0x1002, 0x4A54, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \
- {0x1002, 0x4B49, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \
- {0x1002, 0x4B4A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \
- {0x1002, 0x4B4B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \
- {0x1002, 0x4B4C, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \
- {0x1002, 0x4C57, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV200|CHIP_IS_MOBILITY}, \
- {0x1002, 0x4C58, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV200|CHIP_IS_MOBILITY}, \
- {0x1002, 0x4C59, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV100|CHIP_IS_MOBILITY}, \
- {0x1002, 0x4C5A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV100|CHIP_IS_MOBILITY}, \
- {0x1002, 0x4C64, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV250|CHIP_IS_MOBILITY}, \
- {0x1002, 0x4C66, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV250|CHIP_IS_MOBILITY}, \
- {0x1002, 0x4C67, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV250|CHIP_IS_MOBILITY}, \
+ {0x1002, 0x4A48, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \
+ {0x1002, 0x4A49, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \
+ {0x1002, 0x4A4A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \
+ {0x1002, 0x4A4B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \
+ {0x1002, 0x4A4C, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \
+ {0x1002, 0x4A4D, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \
+ {0x1002, 0x4A4E, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \
+ {0x1002, 0x4A4F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \
+ {0x1002, 0x4A50, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \
+ {0x1002, 0x4A54, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \
+ {0x1002, 0x4B49, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \
+ {0x1002, 0x4B4A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \
+ {0x1002, 0x4B4B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \
+ {0x1002, 0x4B4C, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \
+ {0x1002, 0x4C57, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV200|RADEON_IS_MOBILITY}, \
+ {0x1002, 0x4C58, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV200|RADEON_IS_MOBILITY}, \
+ {0x1002, 0x4C59, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV100|RADEON_IS_MOBILITY}, \
+ {0x1002, 0x4C5A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV100|RADEON_IS_MOBILITY}, \
+ {0x1002, 0x4C64, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV250|RADEON_IS_MOBILITY}, \
+ {0x1002, 0x4C66, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV250|RADEON_IS_MOBILITY}, \
+ {0x1002, 0x4C67, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV250|RADEON_IS_MOBILITY}, \
{0x1002, 0x4E44, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R300}, \
{0x1002, 0x4E45, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R300}, \
{0x1002, 0x4E46, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R300}, \
@@ -62,16 +62,16 @@
{0x1002, 0x4E49, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R350}, \
{0x1002, 0x4E4A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R350}, \
{0x1002, 0x4E4B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R350}, \
- {0x1002, 0x4E50, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350|CHIP_IS_MOBILITY}, \
- {0x1002, 0x4E51, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350|CHIP_IS_MOBILITY}, \
- {0x1002, 0x4E52, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350|CHIP_IS_MOBILITY}, \
- {0x1002, 0x4E53, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350|CHIP_IS_MOBILITY}, \
- {0x1002, 0x4E54, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350|CHIP_IS_MOBILITY}, \
- {0x1002, 0x4E56, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350|CHIP_IS_MOBILITY}, \
- {0x1002, 0x5144, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R100|CHIP_SINGLE_CRTC}, \
- {0x1002, 0x5145, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R100|CHIP_SINGLE_CRTC}, \
- {0x1002, 0x5146, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R100|CHIP_SINGLE_CRTC}, \
- {0x1002, 0x5147, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R100|CHIP_SINGLE_CRTC}, \
+ {0x1002, 0x4E50, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350|RADEON_IS_MOBILITY}, \
+ {0x1002, 0x4E51, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350|RADEON_IS_MOBILITY}, \
+ {0x1002, 0x4E52, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350|RADEON_IS_MOBILITY}, \
+ {0x1002, 0x4E53, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350|RADEON_IS_MOBILITY}, \
+ {0x1002, 0x4E54, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350|RADEON_IS_MOBILITY}, \
+ {0x1002, 0x4E56, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350|RADEON_IS_MOBILITY}, \
+ {0x1002, 0x5144, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R100|RADEON_SINGLE_CRTC}, \
+ {0x1002, 0x5145, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R100|RADEON_SINGLE_CRTC}, \
+ {0x1002, 0x5146, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R100|RADEON_SINGLE_CRTC}, \
+ {0x1002, 0x5147, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R100|RADEON_SINGLE_CRTC}, \
{0x1002, 0x5148, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R200}, \
{0x1002, 0x514C, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R200}, \
{0x1002, 0x514D, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R200}, \
@@ -80,59 +80,59 @@
{0x1002, 0x5159, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV100}, \
{0x1002, 0x515A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV100}, \
{0x1002, 0x515E, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV100}, \
- {0x1002, 0x5460, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|CHIP_IS_MOBILITY}, \
- {0x1002, 0x5462, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|CHIP_IS_MOBILITY}, \
- {0x1002, 0x5464, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|CHIP_IS_MOBILITY}, \
- {0x1002, 0x5548, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \
- {0x1002, 0x5549, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \
- {0x1002, 0x554A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \
- {0x1002, 0x554B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \
- {0x1002, 0x554C, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \
- {0x1002, 0x554D, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \
- {0x1002, 0x554E, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \
- {0x1002, 0x554F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \
- {0x1002, 0x5550, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \
- {0x1002, 0x5551, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \
- {0x1002, 0x5552, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \
- {0x1002, 0x5554, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \
- {0x1002, 0x564A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV410|CHIP_IS_MOBILITY|CHIP_NEW_MEMMAP}, \
- {0x1002, 0x564B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV410|CHIP_IS_MOBILITY|CHIP_NEW_MEMMAP}, \
- {0x1002, 0x564F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV410|CHIP_IS_MOBILITY|CHIP_NEW_MEMMAP}, \
- {0x1002, 0x5652, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV410|CHIP_IS_MOBILITY|CHIP_NEW_MEMMAP}, \
- {0x1002, 0x5653, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV410|CHIP_IS_MOBILITY|CHIP_NEW_MEMMAP}, \
- {0x1002, 0x5834, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS300|CHIP_IS_IGP}, \
- {0x1002, 0x5835, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS300|CHIP_IS_IGP|CHIP_IS_MOBILITY}, \
+ {0x1002, 0x5460, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_IS_MOBILITY}, \
+ {0x1002, 0x5462, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_IS_MOBILITY}, \
+ {0x1002, 0x5464, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_IS_MOBILITY}, \
+ {0x1002, 0x5548, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \
+ {0x1002, 0x5549, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \
+ {0x1002, 0x554A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \
+ {0x1002, 0x554B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \
+ {0x1002, 0x554C, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \
+ {0x1002, 0x554D, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \
+ {0x1002, 0x554E, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \
+ {0x1002, 0x554F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \
+ {0x1002, 0x5550, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \
+ {0x1002, 0x5551, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \
+ {0x1002, 0x5552, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \
+ {0x1002, 0x5554, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \
+ {0x1002, 0x564A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV410|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \
+ {0x1002, 0x564B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV410|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \
+ {0x1002, 0x564F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV410|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \
+ {0x1002, 0x5652, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV410|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \
+ {0x1002, 0x5653, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV410|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \
+ {0x1002, 0x5834, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS300|RADEON_IS_IGP}, \
+ {0x1002, 0x5835, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS300|RADEON_IS_IGP|RADEON_IS_MOBILITY}, \
{0x1002, 0x5960, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \
{0x1002, 0x5961, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \
{0x1002, 0x5962, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \
{0x1002, 0x5964, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \
{0x1002, 0x5965, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \
{0x1002, 0x5969, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV100}, \
- {0x1002, 0x5b60, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|CHIP_NEW_MEMMAP}, \
- {0x1002, 0x5b62, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|CHIP_NEW_MEMMAP}, \
- {0x1002, 0x5b63, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|CHIP_NEW_MEMMAP}, \
- {0x1002, 0x5b64, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|CHIP_NEW_MEMMAP}, \
- {0x1002, 0x5b65, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|CHIP_NEW_MEMMAP}, \
- {0x1002, 0x5c61, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280|CHIP_IS_MOBILITY}, \
- {0x1002, 0x5c63, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280|CHIP_IS_MOBILITY}, \
- {0x1002, 0x5d48, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_IS_MOBILITY|CHIP_NEW_MEMMAP}, \
- {0x1002, 0x5d49, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_IS_MOBILITY|CHIP_NEW_MEMMAP}, \
- {0x1002, 0x5d4a, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_IS_MOBILITY|CHIP_NEW_MEMMAP}, \
- {0x1002, 0x5d4c, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \
- {0x1002, 0x5d4d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \
- {0x1002, 0x5d4e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \
- {0x1002, 0x5d4f, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \
- {0x1002, 0x5d50, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \
- {0x1002, 0x5d52, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \
- {0x1002, 0x5d57, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \
- {0x1002, 0x5e48, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV410|CHIP_NEW_MEMMAP}, \
- {0x1002, 0x5e4a, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV410|CHIP_NEW_MEMMAP}, \
- {0x1002, 0x5e4b, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV410|CHIP_NEW_MEMMAP}, \
- {0x1002, 0x5e4c, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV410|CHIP_NEW_MEMMAP}, \
- {0x1002, 0x5e4d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV410|CHIP_NEW_MEMMAP}, \
- {0x1002, 0x5e4f, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV410|CHIP_NEW_MEMMAP}, \
- {0x1002, 0x7834, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS300|CHIP_IS_IGP|CHIP_NEW_MEMMAP}, \
- {0x1002, 0x7835, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS300|CHIP_IS_IGP|CHIP_IS_MOBILITY|CHIP_NEW_MEMMAP}, \
+ {0x1002, 0x5b60, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_NEW_MEMMAP}, \
+ {0x1002, 0x5b62, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_NEW_MEMMAP}, \
+ {0x1002, 0x5b63, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_NEW_MEMMAP}, \
+ {0x1002, 0x5b64, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_NEW_MEMMAP}, \
+ {0x1002, 0x5b65, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_NEW_MEMMAP}, \
+ {0x1002, 0x5c61, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280|RADEON_IS_MOBILITY}, \
+ {0x1002, 0x5c63, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280|RADEON_IS_MOBILITY}, \
+ {0x1002, 0x5d48, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \
+ {0x1002, 0x5d49, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \
+ {0x1002, 0x5d4a, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \
+ {0x1002, 0x5d4c, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \
+ {0x1002, 0x5d4d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \
+ {0x1002, 0x5d4e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \
+ {0x1002, 0x5d4f, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \
+ {0x1002, 0x5d50, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \
+ {0x1002, 0x5d52, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \
+ {0x1002, 0x5d57, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \
+ {0x1002, 0x5e48, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV410|RADEON_NEW_MEMMAP}, \
+ {0x1002, 0x5e4a, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV410|RADEON_NEW_MEMMAP}, \
+ {0x1002, 0x5e4b, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV410|RADEON_NEW_MEMMAP}, \
+ {0x1002, 0x5e4c, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV410|RADEON_NEW_MEMMAP}, \
+ {0x1002, 0x5e4d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV410|RADEON_NEW_MEMMAP}, \
+ {0x1002, 0x5e4f, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV410|RADEON_NEW_MEMMAP}, \
+ {0x1002, 0x7834, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS300|RADEON_IS_IGP|RADEON_NEW_MEMMAP}, \
+ {0x1002, 0x7835, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS300|RADEON_IS_IGP|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \
{0, 0, 0}
#define r128_PCI_IDS \
@@ -209,6 +209,7 @@
{0x1039, 0x0300, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1039, 0x5300, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1039, 0x6300, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
+ {0x1039, 0x6330, PCI_ANY_ID, PCI_ANY_ID, 0, 0, SIS_CHIP_315}, \
{0x1039, 0x7300, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0, 0, 0}
@@ -227,6 +228,10 @@
{0x1106, 0x3122, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1106, 0x7205, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1106, 0x3108, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
+ {0x1106, 0x3304, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
+ {0x1106, 0x3157, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
+ {0x1106, 0x3344, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
+ {0x1106, 0x7204, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0, 0, 0}
#define i810_PCI_IDS \
@@ -285,5 +290,9 @@
{0x8086, 0x2592, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x8086, 0x2772, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x8086, 0x27a2, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
+ {0x8086, 0x2972, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
+ {0x8086, 0x2982, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
+ {0x8086, 0x2992, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
+ {0x8086, 0x29a2, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0, 0, 0}
diff --git a/drivers/char/drm/drm_proc.c b/drivers/char/drm/drm_proc.c
index 362a270af0f1..62d5fe15f046 100644
--- a/drivers/char/drm/drm_proc.c
+++ b/drivers/char/drm/drm_proc.c
@@ -510,7 +510,7 @@ static int drm__vma_info(char *buf, char **start, off_t offset, int request,
vma->vm_flags & VM_MAYSHARE ? 's' : 'p',
vma->vm_flags & VM_LOCKED ? 'l' : '-',
vma->vm_flags & VM_IO ? 'i' : '-',
- VM_OFFSET(vma));
+ vma->vm_pgoff << PAGE_SHIFT);
#if defined(__i386__)
pgprot = pgprot_val(vma->vm_page_prot);
diff --git a/drivers/char/drm/drm_sman.c b/drivers/char/drm/drm_sman.c
new file mode 100644
index 000000000000..425c82336ee0
--- /dev/null
+++ b/drivers/char/drm/drm_sman.c
@@ -0,0 +1,352 @@
+/**************************************************************************
+ *
+ * Copyright 2006 Tungsten Graphics, Inc., Bismarck., ND., USA.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ * USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ *
+ **************************************************************************/
+/*
+ * Simple memory manager interface that keeps track on allocate regions on a
+ * per "owner" basis. All regions associated with an "owner" can be released
+ * with a simple call. Typically if the "owner" exists. The owner is any
+ * "unsigned long" identifier. Can typically be a pointer to a file private
+ * struct or a context identifier.
+ *
+ * Authors:
+ * Thomas Hellström <thomas-at-tungstengraphics-dot-com>
+ */
+
+#include "drm_sman.h"
+
+typedef struct drm_owner_item {
+ drm_hash_item_t owner_hash;
+ struct list_head sman_list;
+ struct list_head mem_blocks;
+} drm_owner_item_t;
+
+void drm_sman_takedown(drm_sman_t * sman)
+{
+ drm_ht_remove(&sman->user_hash_tab);
+ drm_ht_remove(&sman->owner_hash_tab);
+ if (sman->mm)
+ drm_free(sman->mm, sman->num_managers * sizeof(*sman->mm),
+ DRM_MEM_MM);
+}
+
+EXPORT_SYMBOL(drm_sman_takedown);
+
+int
+drm_sman_init(drm_sman_t * sman, unsigned int num_managers,
+ unsigned int user_order, unsigned int owner_order)
+{
+ int ret = 0;
+
+ sman->mm = (drm_sman_mm_t *) drm_calloc(num_managers, sizeof(*sman->mm),
+ DRM_MEM_MM);
+ if (!sman->mm) {
+ ret = -ENOMEM;
+ goto out;
+ }
+ sman->num_managers = num_managers;
+ INIT_LIST_HEAD(&sman->owner_items);
+ ret = drm_ht_create(&sman->owner_hash_tab, owner_order);
+ if (ret)
+ goto out1;
+ ret = drm_ht_create(&sman->user_hash_tab, user_order);
+ if (!ret)
+ goto out;
+
+ drm_ht_remove(&sman->owner_hash_tab);
+out1:
+ drm_free(sman->mm, num_managers * sizeof(*sman->mm), DRM_MEM_MM);
+out:
+ return ret;
+}
+
+EXPORT_SYMBOL(drm_sman_init);
+
+static void *drm_sman_mm_allocate(void *private, unsigned long size,
+ unsigned alignment)
+{
+ drm_mm_t *mm = (drm_mm_t *) private;
+ drm_mm_node_t *tmp;
+
+ tmp = drm_mm_search_free(mm, size, alignment, 1);
+ if (!tmp) {
+ return NULL;
+ }
+ tmp = drm_mm_get_block(tmp, size, alignment);
+ return tmp;
+}
+
+static void drm_sman_mm_free(void *private, void *ref)
+{
+ drm_mm_t *mm = (drm_mm_t *) private;
+ drm_mm_node_t *node = (drm_mm_node_t *) ref;
+
+ drm_mm_put_block(mm, node);
+}
+
+static void drm_sman_mm_destroy(void *private)
+{
+ drm_mm_t *mm = (drm_mm_t *) private;
+ drm_mm_takedown(mm);
+ drm_free(mm, sizeof(*mm), DRM_MEM_MM);
+}
+
+static unsigned long drm_sman_mm_offset(void *private, void *ref)
+{
+ drm_mm_node_t *node = (drm_mm_node_t *) ref;
+ return node->start;
+}
+
+int
+drm_sman_set_range(drm_sman_t * sman, unsigned int manager,
+ unsigned long start, unsigned long size)
+{
+ drm_sman_mm_t *sman_mm;
+ drm_mm_t *mm;
+ int ret;
+
+ BUG_ON(manager >= sman->num_managers);
+
+ sman_mm = &sman->mm[manager];
+ mm = drm_calloc(1, sizeof(*mm), DRM_MEM_MM);
+ if (!mm) {
+ return -ENOMEM;
+ }
+ sman_mm->private = mm;
+ ret = drm_mm_init(mm, start, size);
+
+ if (ret) {
+ drm_free(mm, sizeof(*mm), DRM_MEM_MM);
+ return ret;
+ }
+
+ sman_mm->allocate = drm_sman_mm_allocate;
+ sman_mm->free = drm_sman_mm_free;
+ sman_mm->destroy = drm_sman_mm_destroy;
+ sman_mm->offset = drm_sman_mm_offset;
+
+ return 0;
+}
+
+EXPORT_SYMBOL(drm_sman_set_range);
+
+int
+drm_sman_set_manager(drm_sman_t * sman, unsigned int manager,
+ drm_sman_mm_t * allocator)
+{
+ BUG_ON(manager >= sman->num_managers);
+ sman->mm[manager] = *allocator;
+
+ return 0;
+}
+
+static drm_owner_item_t *drm_sman_get_owner_item(drm_sman_t * sman,
+ unsigned long owner)
+{
+ int ret;
+ drm_hash_item_t *owner_hash_item;
+ drm_owner_item_t *owner_item;
+
+ ret = drm_ht_find_item(&sman->owner_hash_tab, owner, &owner_hash_item);
+ if (!ret) {
+ return drm_hash_entry(owner_hash_item, drm_owner_item_t,
+ owner_hash);
+ }
+
+ owner_item = drm_calloc(1, sizeof(*owner_item), DRM_MEM_MM);
+ if (!owner_item)
+ goto out;
+
+ INIT_LIST_HEAD(&owner_item->mem_blocks);
+ owner_item->owner_hash.key = owner;
+ if (drm_ht_insert_item(&sman->owner_hash_tab, &owner_item->owner_hash))
+ goto out1;
+
+ list_add_tail(&owner_item->sman_list, &sman->owner_items);
+ return owner_item;
+
+out1:
+ drm_free(owner_item, sizeof(*owner_item), DRM_MEM_MM);
+out:
+ return NULL;
+}
+
+drm_memblock_item_t *drm_sman_alloc(drm_sman_t *sman, unsigned int manager,
+ unsigned long size, unsigned alignment,
+ unsigned long owner)
+{
+ void *tmp;
+ drm_sman_mm_t *sman_mm;
+ drm_owner_item_t *owner_item;
+ drm_memblock_item_t *memblock;
+
+ BUG_ON(manager >= sman->num_managers);
+
+ sman_mm = &sman->mm[manager];
+ tmp = sman_mm->allocate(sman_mm->private, size, alignment);
+
+ if (!tmp) {
+ return NULL;
+ }
+
+ memblock = drm_calloc(1, sizeof(*memblock), DRM_MEM_MM);
+
+ if (!memblock)
+ goto out;
+
+ memblock->mm_info = tmp;
+ memblock->mm = sman_mm;
+ memblock->sman = sman;
+
+ if (drm_ht_just_insert_please
+ (&sman->user_hash_tab, &memblock->user_hash,
+ (unsigned long)memblock, 32, 0, 0))
+ goto out1;
+
+ owner_item = drm_sman_get_owner_item(sman, owner);
+ if (!owner_item)
+ goto out2;
+
+ list_add_tail(&memblock->owner_list, &owner_item->mem_blocks);
+
+ return memblock;
+
+out2:
+ drm_ht_remove_item(&sman->user_hash_tab, &memblock->user_hash);
+out1:
+ drm_free(memblock, sizeof(*memblock), DRM_MEM_MM);
+out:
+ sman_mm->free(sman_mm->private, tmp);
+
+ return NULL;
+}
+
+EXPORT_SYMBOL(drm_sman_alloc);
+
+static void drm_sman_free(drm_memblock_item_t *item)
+{
+ drm_sman_t *sman = item->sman;
+
+ list_del(&item->owner_list);
+ drm_ht_remove_item(&sman->user_hash_tab, &item->user_hash);
+ item->mm->free(item->mm->private, item->mm_info);
+ drm_free(item, sizeof(*item), DRM_MEM_MM);
+}
+
+int drm_sman_free_key(drm_sman_t *sman, unsigned int key)
+{
+ drm_hash_item_t *hash_item;
+ drm_memblock_item_t *memblock_item;
+
+ if (drm_ht_find_item(&sman->user_hash_tab, key, &hash_item))
+ return -EINVAL;
+
+ memblock_item = drm_hash_entry(hash_item, drm_memblock_item_t, user_hash);
+ drm_sman_free(memblock_item);
+ return 0;
+}
+
+EXPORT_SYMBOL(drm_sman_free_key);
+
+static void drm_sman_remove_owner(drm_sman_t *sman,
+ drm_owner_item_t *owner_item)
+{
+ list_del(&owner_item->sman_list);
+ drm_ht_remove_item(&sman->owner_hash_tab, &owner_item->owner_hash);
+ drm_free(owner_item, sizeof(*owner_item), DRM_MEM_MM);
+}
+
+int drm_sman_owner_clean(drm_sman_t *sman, unsigned long owner)
+{
+
+ drm_hash_item_t *hash_item;
+ drm_owner_item_t *owner_item;
+
+ if (drm_ht_find_item(&sman->owner_hash_tab, owner, &hash_item)) {
+ return -1;
+ }
+
+ owner_item = drm_hash_entry(hash_item, drm_owner_item_t, owner_hash);
+ if (owner_item->mem_blocks.next == &owner_item->mem_blocks) {
+ drm_sman_remove_owner(sman, owner_item);
+ return -1;
+ }
+
+ return 0;
+}
+
+EXPORT_SYMBOL(drm_sman_owner_clean);
+
+static void drm_sman_do_owner_cleanup(drm_sman_t *sman,
+ drm_owner_item_t *owner_item)
+{
+ drm_memblock_item_t *entry, *next;
+
+ list_for_each_entry_safe(entry, next, &owner_item->mem_blocks,
+ owner_list) {
+ drm_sman_free(entry);
+ }
+ drm_sman_remove_owner(sman, owner_item);
+}
+
+void drm_sman_owner_cleanup(drm_sman_t *sman, unsigned long owner)
+{
+
+ drm_hash_item_t *hash_item;
+ drm_owner_item_t *owner_item;
+
+ if (drm_ht_find_item(&sman->owner_hash_tab, owner, &hash_item)) {
+
+ return;
+ }
+
+ owner_item = drm_hash_entry(hash_item, drm_owner_item_t, owner_hash);
+ drm_sman_do_owner_cleanup(sman, owner_item);
+}
+
+EXPORT_SYMBOL(drm_sman_owner_cleanup);
+
+void drm_sman_cleanup(drm_sman_t *sman)
+{
+ drm_owner_item_t *entry, *next;
+ unsigned int i;
+ drm_sman_mm_t *sman_mm;
+
+ list_for_each_entry_safe(entry, next, &sman->owner_items, sman_list) {
+ drm_sman_do_owner_cleanup(sman, entry);
+ }
+ if (sman->mm) {
+ for (i = 0; i < sman->num_managers; ++i) {
+ sman_mm = &sman->mm[i];
+ if (sman_mm->private) {
+ sman_mm->destroy(sman_mm->private);
+ sman_mm->private = NULL;
+ }
+ }
+ }
+}
+
+EXPORT_SYMBOL(drm_sman_cleanup);
diff --git a/drivers/char/drm/drm_sman.h b/drivers/char/drm/drm_sman.h
new file mode 100644
index 000000000000..ddc732a1bf27
--- /dev/null
+++ b/drivers/char/drm/drm_sman.h
@@ -0,0 +1,176 @@
+/**************************************************************************
+ *
+ * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND., USA.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ * USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ *
+ **************************************************************************/
+/*
+ * Simple memory MANager interface that keeps track on allocate regions on a
+ * per "owner" basis. All regions associated with an "owner" can be released
+ * with a simple call. Typically if the "owner" exists. The owner is any
+ * "unsigned long" identifier. Can typically be a pointer to a file private
+ * struct or a context identifier.
+ *
+ * Authors:
+ * Thomas Hellström <thomas-at-tungstengraphics-dot-com>
+ */
+
+#ifndef DRM_SMAN_H
+#define DRM_SMAN_H
+
+#include "drmP.h"
+#include "drm_hashtab.h"
+
+/*
+ * A class that is an abstration of a simple memory allocator.
+ * The sman implementation provides a default such allocator
+ * using the drm_mm.c implementation. But the user can replace it.
+ * See the SiS implementation, which may use the SiS FB kernel module
+ * for memory management.
+ */
+
+typedef struct drm_sman_mm {
+ /* private info. If allocated, needs to be destroyed by the destroy
+ function */
+ void *private;
+
+ /* Allocate a memory block with given size and alignment.
+ Return an opaque reference to the memory block */
+
+ void *(*allocate) (void *private, unsigned long size,
+ unsigned alignment);
+
+ /* Free a memory block. "ref" is the opaque reference that we got from
+ the "alloc" function */
+
+ void (*free) (void *private, void *ref);
+
+ /* Free all resources associated with this allocator */
+
+ void (*destroy) (void *private);
+
+ /* Return a memory offset from the opaque reference returned from the
+ "alloc" function */
+
+ unsigned long (*offset) (void *private, void *ref);
+} drm_sman_mm_t;
+
+typedef struct drm_memblock_item {
+ struct list_head owner_list;
+ drm_hash_item_t user_hash;
+ void *mm_info;
+ drm_sman_mm_t *mm;
+ struct drm_sman *sman;
+} drm_memblock_item_t;
+
+typedef struct drm_sman {
+ drm_sman_mm_t *mm;
+ int num_managers;
+ drm_open_hash_t owner_hash_tab;
+ drm_open_hash_t user_hash_tab;
+ struct list_head owner_items;
+} drm_sman_t;
+
+/*
+ * Take down a memory manager. This function should only be called after a
+ * successful init and after a call to drm_sman_cleanup.
+ */
+
+extern void drm_sman_takedown(drm_sman_t * sman);
+
+/*
+ * Allocate structures for a manager.
+ * num_managers are the number of memory pools to manage. (VRAM, AGP, ....)
+ * user_order is the log2 of the number of buckets in the user hash table.
+ * set this to approximately log2 of the max number of memory regions
+ * that will be allocated for _all_ pools together.
+ * owner_order is the log2 of the number of buckets in the owner hash table.
+ * set this to approximately log2 of
+ * the number of client file connections that will
+ * be using the manager.
+ *
+ */
+
+extern int drm_sman_init(drm_sman_t * sman, unsigned int num_managers,
+ unsigned int user_order, unsigned int owner_order);
+
+/*
+ * Initialize a drm_mm.c allocator. Should be called only once for each
+ * manager unless a customized allogator is used.
+ */
+
+extern int drm_sman_set_range(drm_sman_t * sman, unsigned int manager,
+ unsigned long start, unsigned long size);
+
+/*
+ * Initialize a customized allocator for one of the managers.
+ * (See the SiS module). The object pointed to by "allocator" is copied,
+ * so it can be destroyed after this call.
+ */
+
+extern int drm_sman_set_manager(drm_sman_t * sman, unsigned int mananger,
+ drm_sman_mm_t * allocator);
+
+/*
+ * Allocate a memory block. Aligment is not implemented yet.
+ */
+
+extern drm_memblock_item_t *drm_sman_alloc(drm_sman_t * sman,
+ unsigned int manager,
+ unsigned long size,
+ unsigned alignment,
+ unsigned long owner);
+/*
+ * Free a memory block identified by its user hash key.
+ */
+
+extern int drm_sman_free_key(drm_sman_t * sman, unsigned int key);
+
+/*
+ * returns 1 iff there are no stale memory blocks associated with this owner.
+ * Typically called to determine if we need to idle the hardware and call
+ * drm_sman_owner_cleanup. If there are no stale memory blocks, it removes all
+ * resources associated with owner.
+ */
+
+extern int drm_sman_owner_clean(drm_sman_t * sman, unsigned long owner);
+
+/*
+ * Frees all stale memory blocks associated with this owner. Note that this
+ * requires that the hardware is finished with all blocks, so the graphics engine
+ * should be idled before this call is made. This function also frees
+ * any resources associated with "owner" and should be called when owner
+ * is not going to be referenced anymore.
+ */
+
+extern void drm_sman_owner_cleanup(drm_sman_t * sman, unsigned long owner);
+
+/*
+ * Frees all stale memory blocks associated with the memory manager.
+ * See idling above.
+ */
+
+extern void drm_sman_cleanup(drm_sman_t * sman);
+
+#endif
diff --git a/drivers/char/drm/drm_stub.c b/drivers/char/drm/drm_stub.c
index 9a842a36bb27..7b1d4e8659ba 100644
--- a/drivers/char/drm/drm_stub.c
+++ b/drivers/char/drm/drm_stub.c
@@ -65,22 +65,22 @@ static int drm_fill_in_dev(drm_device_t * dev, struct pci_dev *pdev,
mutex_init(&dev->ctxlist_mutex);
dev->pdev = pdev;
+ dev->pci_device = pdev->device;
+ dev->pci_vendor = pdev->vendor;
#ifdef __alpha__
dev->hose = pdev->sysdata;
- dev->pci_domain = dev->hose->bus->number;
-#else
- dev->pci_domain = 0;
#endif
- dev->pci_bus = pdev->bus->number;
- dev->pci_slot = PCI_SLOT(pdev->devfn);
- dev->pci_func = PCI_FUNC(pdev->devfn);
dev->irq = pdev->irq;
dev->maplist = drm_calloc(1, sizeof(*dev->maplist), DRM_MEM_MAPS);
if (dev->maplist == NULL)
return -ENOMEM;
INIT_LIST_HEAD(&dev->maplist->head);
+ if (drm_ht_create(&dev->map_hash, 12)) {
+ drm_free(dev->maplist, sizeof(*dev->maplist), DRM_MEM_MAPS);
+ return -ENOMEM;
+ }
/* the DRM has 6 basic counters */
dev->counters = 6;
diff --git a/drivers/char/drm/drm_vm.c b/drivers/char/drm/drm_vm.c
index ffd0800ed601..b40ae438f531 100644
--- a/drivers/char/drm/drm_vm.c
+++ b/drivers/char/drm/drm_vm.c
@@ -59,7 +59,7 @@ static __inline__ struct page *drm_do_vm_nopage(struct vm_area_struct *vma,
drm_device_t *dev = priv->head->dev;
drm_map_t *map = NULL;
drm_map_list_t *r_list;
- struct list_head *list;
+ drm_hash_item_t *hash;
/*
* Find the right map
@@ -70,14 +70,11 @@ static __inline__ struct page *drm_do_vm_nopage(struct vm_area_struct *vma,
if (!dev->agp || !dev->agp->cant_use_aperture)
goto vm_nopage_error;
- list_for_each(list, &dev->maplist->head) {
- r_list = list_entry(list, drm_map_list_t, head);
- map = r_list->map;
- if (!map)
- continue;
- if (r_list->user_token == VM_OFFSET(vma))
- break;
- }
+ if (drm_ht_find_item(&dev->map_hash, vma->vm_pgoff << PAGE_SHIFT, &hash))
+ goto vm_nopage_error;
+
+ r_list = drm_hash_entry(hash, drm_map_list_t, hash);
+ map = r_list->map;
if (map && map->type == _DRM_AGP) {
unsigned long offset = address - vma->vm_start;
@@ -467,7 +464,7 @@ static int drm_mmap_dma(struct file *filp, struct vm_area_struct *vma)
dev = priv->head->dev;
dma = dev->dma;
DRM_DEBUG("start = 0x%lx, end = 0x%lx, offset = 0x%lx\n",
- vma->vm_start, vma->vm_end, VM_OFFSET(vma));
+ vma->vm_start, vma->vm_end, vma->vm_pgoff << PAGE_SHIFT);
/* Length must match exact page count */
if (!dma || (length >> PAGE_SHIFT) != dma->page_count) {
@@ -521,12 +518,11 @@ int drm_mmap(struct file *filp, struct vm_area_struct *vma)
drm_file_t *priv = filp->private_data;
drm_device_t *dev = priv->head->dev;
drm_map_t *map = NULL;
- drm_map_list_t *r_list;
unsigned long offset = 0;
- struct list_head *list;
+ drm_hash_item_t *hash;
DRM_DEBUG("start = 0x%lx, end = 0x%lx, offset = 0x%lx\n",
- vma->vm_start, vma->vm_end, VM_OFFSET(vma));
+ vma->vm_start, vma->vm_end, vma->vm_pgoff << PAGE_SHIFT);
if (!priv->authenticated)
return -EACCES;
@@ -535,7 +531,7 @@ int drm_mmap(struct file *filp, struct vm_area_struct *vma)
* the AGP mapped at physical address 0
* --BenH.
*/
- if (!VM_OFFSET(vma)
+ if (!(vma->vm_pgoff << PAGE_SHIFT)
#if __OS_HAS_AGP
&& (!dev->agp
|| dev->agp->agp_info.device->vendor != PCI_VENDOR_ID_APPLE)
@@ -543,23 +539,12 @@ int drm_mmap(struct file *filp, struct vm_area_struct *vma)
)
return drm_mmap_dma(filp, vma);
- /* A sequential search of a linked list is
- fine here because: 1) there will only be
- about 5-10 entries in the list and, 2) a
- DRI client only has to do this mapping
- once, so it doesn't have to be optimized
- for performance, even if the list was a
- bit longer. */
- list_for_each(list, &dev->maplist->head) {
-
- r_list = list_entry(list, drm_map_list_t, head);
- map = r_list->map;
- if (!map)
- continue;
- if (r_list->user_token == VM_OFFSET(vma))
- break;
+ if (drm_ht_find_item(&dev->map_hash, vma->vm_pgoff << PAGE_SHIFT, &hash)) {
+ DRM_ERROR("Could not find map\n");
+ return -EINVAL;
}
+ map = drm_hash_entry(hash, drm_map_list_t, hash)->map;
if (!map || ((map->flags & _DRM_RESTRICTED) && !capable(CAP_SYS_ADMIN)))
return -EPERM;
@@ -620,7 +605,7 @@ int drm_mmap(struct file *filp, struct vm_area_struct *vma)
offset = dev->driver->get_reg_ofs(dev);
#ifdef __sparc__
vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
- if (io_remap_pfn_range(DRM_RPR_ARG(vma) vma->vm_start,
+ if (io_remap_pfn_range(vma, vma->vm_start,
(map->offset + offset) >> PAGE_SHIFT,
vma->vm_end - vma->vm_start,
vma->vm_page_prot))
diff --git a/drivers/char/drm/i810_dma.c b/drivers/char/drm/i810_dma.c
index c658dde3633b..fa2de70f7401 100644
--- a/drivers/char/drm/i810_dma.c
+++ b/drivers/char/drm/i810_dma.c
@@ -106,7 +106,7 @@ static int i810_mmap_buffers(struct file *filp, struct vm_area_struct *vma)
unlock_kernel();
if (io_remap_pfn_range(vma, vma->vm_start,
- VM_OFFSET(vma) >> PAGE_SHIFT,
+ vma->vm_pgoff,
vma->vm_end - vma->vm_start, vma->vm_page_prot))
return -EAGAIN;
return 0;
@@ -141,10 +141,10 @@ static int i810_map_buffer(drm_buf_t * buf, struct file *filp)
MAP_SHARED, buf->bus_address);
dev_priv->mmap_buffer = NULL;
filp->f_op = old_fops;
- if ((unsigned long)buf_priv->virtual > -1024UL) {
+ if (IS_ERR(buf_priv->virtual)) {
/* Real error */
DRM_ERROR("mmap error\n");
- retcode = (signed int)buf_priv->virtual;
+ retcode = PTR_ERR(buf_priv->virtual);
buf_priv->virtual = NULL;
}
up_write(&current->mm->mmap_sem);
@@ -808,7 +808,7 @@ static void i810_dma_dispatch_vertex(drm_device_t * dev,
((GFX_OP_PRIMITIVE | prim | ((used / 4) - 2)));
if (used & 4) {
- *(u32 *) ((u32) buf_priv->kernel_virtual + used) = 0;
+ *(u32 *) ((char *) buf_priv->kernel_virtual + used) = 0;
used += 4;
}
@@ -1166,7 +1166,7 @@ static void i810_dma_dispatch_mc(drm_device_t * dev, drm_buf_t * buf, int used,
if (buf_priv->currently_mapped == I810_BUF_MAPPED) {
if (used & 4) {
- *(u32 *) ((u32) buf_priv->virtual + used) = 0;
+ *(u32 *) ((char *) buf_priv->virtual + used) = 0;
used += 4;
}
diff --git a/drivers/char/drm/i830_dma.c b/drivers/char/drm/i830_dma.c
index b0f815d8cea8..4f0e5746ab33 100644
--- a/drivers/char/drm/i830_dma.c
+++ b/drivers/char/drm/i830_dma.c
@@ -108,7 +108,7 @@ static int i830_mmap_buffers(struct file *filp, struct vm_area_struct *vma)
unlock_kernel();
if (io_remap_pfn_range(vma, vma->vm_start,
- VM_OFFSET(vma) >> PAGE_SHIFT,
+ vma->vm_pgoff,
vma->vm_end - vma->vm_start, vma->vm_page_prot))
return -EAGAIN;
return 0;
@@ -146,7 +146,7 @@ static int i830_map_buffer(drm_buf_t * buf, struct file *filp)
if (IS_ERR((void *)virtual)) { /* ugh */
/* Real error */
DRM_ERROR("mmap error\n");
- retcode = virtual;
+ retcode = PTR_ERR((void *)virtual);
buf_priv->virtual = NULL;
} else {
buf_priv->virtual = (void __user *)virtual;
diff --git a/drivers/char/drm/i915_dma.c b/drivers/char/drm/i915_dma.c
index a94233bdbc0e..fb7913ff5286 100644
--- a/drivers/char/drm/i915_dma.c
+++ b/drivers/char/drm/i915_dma.c
@@ -31,6 +31,11 @@
#include "i915_drm.h"
#include "i915_drv.h"
+#define IS_I965G(dev) (dev->pci_device == 0x2972 || \
+ dev->pci_device == 0x2982 || \
+ dev->pci_device == 0x2992 || \
+ dev->pci_device == 0x29A2)
+
/* Really want an OS-independent resettable timer. Would like to have
* this loop run for (eg) 3 sec, but have the timer reset every time
* the head pointer changes, so that EBUSY only happens if the ring
@@ -255,7 +260,7 @@ static int i915_dma_init(DRM_IOCTL_ARGS)
retcode = i915_dma_resume(dev);
break;
default:
- retcode = -EINVAL;
+ retcode = DRM_ERR(EINVAL);
break;
}
@@ -347,7 +352,7 @@ static int i915_emit_cmds(drm_device_t * dev, int __user * buffer, int dwords)
if ((dwords+1) * sizeof(int) >= dev_priv->ring.Size - 8)
return DRM_ERR(EINVAL);
- BEGIN_LP_RING(((dwords+1)&~1));
+ BEGIN_LP_RING((dwords+1)&~1);
for (i = 0; i < dwords;) {
int cmd, sz;
@@ -386,7 +391,7 @@ static int i915_emit_box(drm_device_t * dev,
RING_LOCALS;
if (DRM_COPY_FROM_USER_UNCHECKED(&box, &boxes[i], sizeof(box))) {
- return EFAULT;
+ return DRM_ERR(EFAULT);
}
if (box.y2 <= box.y1 || box.x2 <= box.x1 || box.y2 <= 0 || box.x2 <= 0) {
@@ -395,24 +400,40 @@ static int i915_emit_box(drm_device_t * dev,
return DRM_ERR(EINVAL);
}
- BEGIN_LP_RING(6);
- OUT_RING(GFX_OP_DRAWRECT_INFO);
- OUT_RING(DR1);
- OUT_RING((box.x1 & 0xffff) | (box.y1 << 16));
- OUT_RING(((box.x2 - 1) & 0xffff) | ((box.y2 - 1) << 16));
- OUT_RING(DR4);
- OUT_RING(0);
- ADVANCE_LP_RING();
+ if (IS_I965G(dev)) {
+ BEGIN_LP_RING(4);
+ OUT_RING(GFX_OP_DRAWRECT_INFO_I965);
+ OUT_RING((box.x1 & 0xffff) | (box.y1 << 16));
+ OUT_RING(((box.x2 - 1) & 0xffff) | ((box.y2 - 1) << 16));
+ OUT_RING(DR4);
+ ADVANCE_LP_RING();
+ } else {
+ BEGIN_LP_RING(6);
+ OUT_RING(GFX_OP_DRAWRECT_INFO);
+ OUT_RING(DR1);
+ OUT_RING((box.x1 & 0xffff) | (box.y1 << 16));
+ OUT_RING(((box.x2 - 1) & 0xffff) | ((box.y2 - 1) << 16));
+ OUT_RING(DR4);
+ OUT_RING(0);
+ ADVANCE_LP_RING();
+ }
return 0;
}
+/* XXX: Emitting the counter should really be moved to part of the IRQ
+ * emit. For now, do it in both places:
+ */
+
static void i915_emit_breadcrumb(drm_device_t *dev)
{
drm_i915_private_t *dev_priv = dev->dev_private;
RING_LOCALS;
- dev_priv->sarea_priv->last_enqueue = dev_priv->counter++;
+ dev_priv->sarea_priv->last_enqueue = ++dev_priv->counter;
+
+ if (dev_priv->counter > 0x7FFFFFFFUL)
+ dev_priv->sarea_priv->last_enqueue = dev_priv->counter = 1;
BEGIN_LP_RING(4);
OUT_RING(CMD_STORE_DWORD_IDX);
diff --git a/drivers/char/drm/i915_drm.h b/drivers/char/drm/i915_drm.h
index 5aa3e0e3bb45..6af83e613f27 100644
--- a/drivers/char/drm/i915_drm.h
+++ b/drivers/char/drm/i915_drm.h
@@ -98,6 +98,12 @@ typedef struct _drm_i915_sarea {
int rotated_size;
int rotated_pitch;
int virtualX, virtualY;
+
+ unsigned int front_tiled;
+ unsigned int back_tiled;
+ unsigned int depth_tiled;
+ unsigned int rotated_tiled;
+ unsigned int rotated2_tiled;
} drm_i915_sarea_t;
/* Flags for perf_boxes
diff --git a/drivers/char/drm/i915_drv.h b/drivers/char/drm/i915_drv.h
index 2d565031c002..fdc2bf192714 100644
--- a/drivers/char/drm/i915_drv.h
+++ b/drivers/char/drm/i915_drv.h
@@ -146,9 +146,9 @@ extern void i915_mem_release(drm_device_t * dev,
#define BEGIN_LP_RING(n) do { \
if (I915_VERBOSE) \
DRM_DEBUG("BEGIN_LP_RING(%d) in %s\n", \
- n, __FUNCTION__); \
- if (dev_priv->ring.space < n*4) \
- i915_wait_ring(dev, n*4, __FUNCTION__); \
+ (n), __FUNCTION__); \
+ if (dev_priv->ring.space < (n)*4) \
+ i915_wait_ring(dev, (n)*4, __FUNCTION__); \
outcount = 0; \
outring = dev_priv->ring.tail; \
ringmask = dev_priv->ring.tail_mask; \
@@ -157,7 +157,7 @@ extern void i915_mem_release(drm_device_t * dev,
#define OUT_RING(n) do { \
if (I915_VERBOSE) DRM_DEBUG(" OUT_RING %x\n", (int)(n)); \
- *(volatile unsigned int *)(virt + outring) = n; \
+ *(volatile unsigned int *)(virt + outring) = (n); \
outcount++; \
outring += 4; \
outring &= ringmask; \
@@ -254,6 +254,8 @@ extern int i915_wait_ring(drm_device_t * dev, int n, const char *caller);
#define GFX_OP_DESTBUFFER_VARS ((0x3<<29)|(0x1d<<24)|(0x85<<16)|0x0)
#define GFX_OP_DRAWRECT_INFO ((0x3<<29)|(0x1d<<24)|(0x80<<16)|(0x3))
+#define GFX_OP_DRAWRECT_INFO_I965 ((0x7900<<16)|0x2)
+
#define MI_BATCH_BUFFER ((0x30<<23)|1)
#define MI_BATCH_BUFFER_START (0x31<<23)
#define MI_BATCH_BUFFER_END (0xA<<23)
diff --git a/drivers/char/drm/i915_irq.c b/drivers/char/drm/i915_irq.c
index cd96cfa430db..0d4a162aa385 100644
--- a/drivers/char/drm/i915_irq.c
+++ b/drivers/char/drm/i915_irq.c
@@ -71,21 +71,27 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
static int i915_emit_irq(drm_device_t * dev)
{
drm_i915_private_t *dev_priv = dev->dev_private;
- u32 ret;
RING_LOCALS;
i915_kernel_lost_context(dev);
DRM_DEBUG("%s\n", __FUNCTION__);
- ret = dev_priv->counter;
+ dev_priv->sarea_priv->last_enqueue = ++dev_priv->counter;
- BEGIN_LP_RING(2);
+ if (dev_priv->counter > 0x7FFFFFFFUL)
+ dev_priv->sarea_priv->last_enqueue = dev_priv->counter = 1;
+
+ BEGIN_LP_RING(6);
+ OUT_RING(CMD_STORE_DWORD_IDX);
+ OUT_RING(20);
+ OUT_RING(dev_priv->counter);
+ OUT_RING(0);
OUT_RING(0);
OUT_RING(GFX_OP_USER_INTERRUPT);
ADVANCE_LP_RING();
-
- return ret;
+
+ return dev_priv->counter;
}
static int i915_wait_irq(drm_device_t * dev, int irq_nr)
diff --git a/drivers/char/drm/radeon_cp.c b/drivers/char/drm/radeon_cp.c
index 5ad43ba7b5aa..5ed965688293 100644
--- a/drivers/char/drm/radeon_cp.c
+++ b/drivers/char/drm/radeon_cp.c
@@ -864,13 +864,13 @@ static int radeon_do_pixcache_flush(drm_radeon_private_t * dev_priv)
dev_priv->stats.boxes |= RADEON_BOX_WAIT_IDLE;
- tmp = RADEON_READ(RADEON_RB2D_DSTCACHE_CTLSTAT);
- tmp |= RADEON_RB2D_DC_FLUSH_ALL;
- RADEON_WRITE(RADEON_RB2D_DSTCACHE_CTLSTAT, tmp);
+ tmp = RADEON_READ(RADEON_RB3D_DSTCACHE_CTLSTAT);
+ tmp |= RADEON_RB3D_DC_FLUSH_ALL;
+ RADEON_WRITE(RADEON_RB3D_DSTCACHE_CTLSTAT, tmp);
for (i = 0; i < dev_priv->usec_timeout; i++) {
- if (!(RADEON_READ(RADEON_RB2D_DSTCACHE_CTLSTAT)
- & RADEON_RB2D_DC_BUSY)) {
+ if (!(RADEON_READ(RADEON_RB3D_DSTCACHE_CTLSTAT)
+ & RADEON_RB3D_DC_BUSY)) {
return 0;
}
DRM_UDELAY(1);
@@ -1130,7 +1130,7 @@ static void radeon_cp_init_ring_buffer(drm_device_t * dev,
| (dev_priv->fb_location >> 16));
#if __OS_HAS_AGP
- if (dev_priv->flags & CHIP_IS_AGP) {
+ if (dev_priv->flags & RADEON_IS_AGP) {
RADEON_WRITE(RADEON_AGP_BASE, (unsigned int)dev->agp->base);
RADEON_WRITE(RADEON_MC_AGP_LOCATION,
(((dev_priv->gart_vm_start - 1 +
@@ -1158,7 +1158,7 @@ static void radeon_cp_init_ring_buffer(drm_device_t * dev,
dev_priv->ring.tail = cur_read_ptr;
#if __OS_HAS_AGP
- if (dev_priv->flags & CHIP_IS_AGP) {
+ if (dev_priv->flags & RADEON_IS_AGP) {
RADEON_WRITE(RADEON_CP_RB_RPTR_ADDR,
dev_priv->ring_rptr->offset
- dev->agp->base + dev_priv->gart_vm_start);
@@ -1258,6 +1258,13 @@ static void radeon_test_writeback(drm_radeon_private_t * dev_priv)
dev_priv->writeback_works = 0;
DRM_INFO("writeback forced off\n");
}
+
+ if (!dev_priv->writeback_works) {
+ /* Disable writeback to avoid unnecessary bus master transfer */
+ RADEON_WRITE(RADEON_CP_RB_CNTL, RADEON_READ(RADEON_CP_RB_CNTL) |
+ RADEON_RB_NO_UPDATE);
+ RADEON_WRITE(RADEON_SCRATCH_UMSK, 0);
+ }
}
/* Enable or disable PCI-E GART on the chip */
@@ -1295,7 +1302,7 @@ static void radeon_set_pcigart(drm_radeon_private_t * dev_priv, int on)
{
u32 tmp;
- if (dev_priv->flags & CHIP_IS_PCIE) {
+ if (dev_priv->flags & RADEON_IS_PCIE) {
radeon_set_pciegart(dev_priv, on);
return;
}
@@ -1333,20 +1340,22 @@ static int radeon_do_init_cp(drm_device_t * dev, drm_radeon_init_t * init)
DRM_DEBUG("\n");
/* if we require new memory map but we don't have it fail */
- if ((dev_priv->flags & CHIP_NEW_MEMMAP) && !dev_priv->new_memmap)
- {
- DRM_ERROR("Cannot initialise DRM on this card\nThis card requires a new X.org DDX\n");
+ if ((dev_priv->flags & RADEON_NEW_MEMMAP) && !dev_priv->new_memmap) {
+ DRM_ERROR("Cannot initialise DRM on this card\nThis card requires a new X.org DDX for 3D\n");
radeon_do_cleanup_cp(dev);
return DRM_ERR(EINVAL);
}
- if (init->is_pci && (dev_priv->flags & CHIP_IS_AGP))
- {
+ if (init->is_pci && (dev_priv->flags & RADEON_IS_AGP)) {
DRM_DEBUG("Forcing AGP card to PCI mode\n");
- dev_priv->flags &= ~CHIP_IS_AGP;
+ dev_priv->flags &= ~RADEON_IS_AGP;
+ } else if (!(dev_priv->flags & (RADEON_IS_AGP | RADEON_IS_PCI | RADEON_IS_PCIE))
+ && !init->is_pci) {
+ DRM_DEBUG("Restoring AGP flag\n");
+ dev_priv->flags |= RADEON_IS_AGP;
}
- if ((!(dev_priv->flags & CHIP_IS_AGP)) && !dev->sg) {
+ if ((!(dev_priv->flags & RADEON_IS_AGP)) && !dev->sg) {
DRM_ERROR("PCI GART memory not allocated!\n");
radeon_do_cleanup_cp(dev);
return DRM_ERR(EINVAL);
@@ -1489,7 +1498,7 @@ static int radeon_do_init_cp(drm_device_t * dev, drm_radeon_init_t * init)
init->sarea_priv_offset);
#if __OS_HAS_AGP
- if (dev_priv->flags & CHIP_IS_AGP) {
+ if (dev_priv->flags & RADEON_IS_AGP) {
drm_core_ioremap(dev_priv->cp_ring, dev);
drm_core_ioremap(dev_priv->ring_rptr, dev);
drm_core_ioremap(dev->agp_buffer_map, dev);
@@ -1548,7 +1557,7 @@ static int radeon_do_init_cp(drm_device_t * dev, drm_radeon_init_t * init)
* align it down.
*/
#if __OS_HAS_AGP
- if (dev_priv->flags & CHIP_IS_AGP) {
+ if (dev_priv->flags & RADEON_IS_AGP) {
base = dev->agp->base;
/* Check if valid */
if ((base + dev_priv->gart_size) > dev_priv->fb_location &&
@@ -1578,7 +1587,7 @@ static int radeon_do_init_cp(drm_device_t * dev, drm_radeon_init_t * init)
}
#if __OS_HAS_AGP
- if (dev_priv->flags & CHIP_IS_AGP)
+ if (dev_priv->flags & RADEON_IS_AGP)
dev_priv->gart_buffers_offset = (dev->agp_buffer_map->offset
- dev->agp->base
+ dev_priv->gart_vm_start);
@@ -1604,7 +1613,7 @@ static int radeon_do_init_cp(drm_device_t * dev, drm_radeon_init_t * init)
dev_priv->ring.high_mark = RADEON_RING_HIGH_MARK;
#if __OS_HAS_AGP
- if (dev_priv->flags & CHIP_IS_AGP) {
+ if (dev_priv->flags & RADEON_IS_AGP) {
/* Turn off PCI GART */
radeon_set_pcigart(dev_priv, 0);
} else
@@ -1624,7 +1633,7 @@ static int radeon_do_init_cp(drm_device_t * dev, drm_radeon_init_t * init)
dev_priv->gart_info.mapping.handle;
dev_priv->gart_info.is_pcie =
- !!(dev_priv->flags & CHIP_IS_PCIE);
+ !!(dev_priv->flags & RADEON_IS_PCIE);
dev_priv->gart_info.gart_table_location =
DRM_ATI_GART_FB;
@@ -1636,7 +1645,7 @@ static int radeon_do_init_cp(drm_device_t * dev, drm_radeon_init_t * init)
DRM_ATI_GART_MAIN;
dev_priv->gart_info.addr = NULL;
dev_priv->gart_info.bus_addr = 0;
- if (dev_priv->flags & CHIP_IS_PCIE) {
+ if (dev_priv->flags & RADEON_IS_PCIE) {
DRM_ERROR
("Cannot use PCI Express without GART in FB memory\n");
radeon_do_cleanup_cp(dev);
@@ -1678,7 +1687,7 @@ static int radeon_do_cleanup_cp(drm_device_t * dev)
drm_irq_uninstall(dev);
#if __OS_HAS_AGP
- if (dev_priv->flags & CHIP_IS_AGP) {
+ if (dev_priv->flags & RADEON_IS_AGP) {
if (dev_priv->cp_ring != NULL) {
drm_core_ioremapfree(dev_priv->cp_ring, dev);
dev_priv->cp_ring = NULL;
@@ -1733,7 +1742,7 @@ static int radeon_do_resume_cp(drm_device_t * dev)
DRM_DEBUG("Starting radeon_do_resume_cp()\n");
#if __OS_HAS_AGP
- if (dev_priv->flags & CHIP_IS_AGP) {
+ if (dev_priv->flags & RADEON_IS_AGP) {
/* Turn off PCI GART */
radeon_set_pcigart(dev_priv, 0);
} else
@@ -2177,13 +2186,15 @@ int radeon_driver_load(struct drm_device *dev, unsigned long flags)
dev->dev_private = (void *)dev_priv;
dev_priv->flags = flags;
- switch (flags & CHIP_FAMILY_MASK) {
+ switch (flags & RADEON_FAMILY_MASK) {
case CHIP_R100:
case CHIP_RV200:
case CHIP_R200:
case CHIP_R300:
+ case CHIP_R350:
case CHIP_R420:
- dev_priv->flags |= CHIP_HAS_HIERZ;
+ case CHIP_RV410:
+ dev_priv->flags |= RADEON_HAS_HIERZ;
break;
default:
/* all other chips have no hierarchical z buffer */
@@ -2191,13 +2202,14 @@ int radeon_driver_load(struct drm_device *dev, unsigned long flags)
}
if (drm_device_is_agp(dev))
- dev_priv->flags |= CHIP_IS_AGP;
-
- if (drm_device_is_pcie(dev))
- dev_priv->flags |= CHIP_IS_PCIE;
+ dev_priv->flags |= RADEON_IS_AGP;
+ else if (drm_device_is_pcie(dev))
+ dev_priv->flags |= RADEON_IS_PCIE;
+ else
+ dev_priv->flags |= RADEON_IS_PCI;
DRM_DEBUG("%s card detected\n",
- ((dev_priv->flags & CHIP_IS_AGP) ? "AGP" : (((dev_priv->flags & CHIP_IS_PCIE) ? "PCIE" : "PCI"))));
+ ((dev_priv->flags & RADEON_IS_AGP) ? "AGP" : (((dev_priv->flags & RADEON_IS_PCIE) ? "PCIE" : "PCI"))));
return ret;
}
diff --git a/drivers/char/drm/radeon_drv.c b/drivers/char/drm/radeon_drv.c
index eb985c2a31e9..2eb652ec6745 100644
--- a/drivers/char/drm/radeon_drv.c
+++ b/drivers/char/drm/radeon_drv.c
@@ -44,7 +44,7 @@ module_param_named(no_wb, radeon_no_wb, int, 0444);
static int dri_library_name(struct drm_device *dev, char *buf)
{
drm_radeon_private_t *dev_priv = dev->dev_private;
- int family = dev_priv->flags & CHIP_FAMILY_MASK;
+ int family = dev_priv->flags & RADEON_FAMILY_MASK;
return snprintf(buf, PAGE_SIZE, "%s\n",
(family < CHIP_R200) ? "radeon" :
diff --git a/drivers/char/drm/radeon_drv.h b/drivers/char/drm/radeon_drv.h
index e5a256f5429c..f45cd7f147a5 100644
--- a/drivers/char/drm/radeon_drv.h
+++ b/drivers/char/drm/radeon_drv.h
@@ -133,15 +133,16 @@ enum radeon_cp_microcode_version {
* Chip flags
*/
enum radeon_chip_flags {
- CHIP_FAMILY_MASK = 0x0000ffffUL,
- CHIP_FLAGS_MASK = 0xffff0000UL,
- CHIP_IS_MOBILITY = 0x00010000UL,
- CHIP_IS_IGP = 0x00020000UL,
- CHIP_SINGLE_CRTC = 0x00040000UL,
- CHIP_IS_AGP = 0x00080000UL,
- CHIP_HAS_HIERZ = 0x00100000UL,
- CHIP_IS_PCIE = 0x00200000UL,
- CHIP_NEW_MEMMAP = 0x00400000UL,
+ RADEON_FAMILY_MASK = 0x0000ffffUL,
+ RADEON_FLAGS_MASK = 0xffff0000UL,
+ RADEON_IS_MOBILITY = 0x00010000UL,
+ RADEON_IS_IGP = 0x00020000UL,
+ RADEON_SINGLE_CRTC = 0x00040000UL,
+ RADEON_IS_AGP = 0x00080000UL,
+ RADEON_HAS_HIERZ = 0x00100000UL,
+ RADEON_IS_PCIE = 0x00200000UL,
+ RADEON_NEW_MEMMAP = 0x00400000UL,
+ RADEON_IS_PCI = 0x00800000UL,
};
#define GET_RING_HEAD(dev_priv) (dev_priv->writeback_works ? \
@@ -424,6 +425,8 @@ extern int r300_do_cp_cmdbuf(drm_device_t * dev, DRMFILE filp,
#define RADEON_RB3D_COLOROFFSET 0x1c40
#define RADEON_RB3D_COLORPITCH 0x1c48
+#define RADEON_SRC_X_Y 0x1590
+
#define RADEON_DP_GUI_MASTER_CNTL 0x146c
# define RADEON_GMC_SRC_PITCH_OFFSET_CNTL (1 << 0)
# define RADEON_GMC_DST_PITCH_OFFSET_CNTL (1 << 1)
@@ -441,6 +444,7 @@ extern int r300_do_cp_cmdbuf(drm_device_t * dev, DRMFILE filp,
# define RADEON_ROP3_S 0x00cc0000
# define RADEON_ROP3_P 0x00f00000
#define RADEON_DP_WRITE_MASK 0x16cc
+#define RADEON_SRC_PITCH_OFFSET 0x1428
#define RADEON_DST_PITCH_OFFSET 0x142c
#define RADEON_DST_PITCH_OFFSET_C 0x1c80
# define RADEON_DST_TILE_LINEAR (0 << 30)
@@ -545,6 +549,11 @@ extern int r300_do_cp_cmdbuf(drm_device_t * dev, DRMFILE filp,
# define RADEON_RB3D_ZC_FREE (1 << 2)
# define RADEON_RB3D_ZC_FLUSH_ALL 0x5
# define RADEON_RB3D_ZC_BUSY (1 << 31)
+#define RADEON_RB3D_DSTCACHE_CTLSTAT 0x325c
+# define RADEON_RB3D_DC_FLUSH (3 << 0)
+# define RADEON_RB3D_DC_FREE (3 << 2)
+# define RADEON_RB3D_DC_FLUSH_ALL 0xf
+# define RADEON_RB3D_DC_BUSY (1 << 31)
#define RADEON_RB3D_ZSTENCILCNTL 0x1c2c
# define RADEON_Z_TEST_MASK (7 << 4)
# define RADEON_Z_TEST_ALWAYS (7 << 4)
@@ -681,6 +690,7 @@ extern int r300_do_cp_cmdbuf(drm_device_t * dev, DRMFILE filp,
#define RADEON_CP_RB_BASE 0x0700
#define RADEON_CP_RB_CNTL 0x0704
# define RADEON_BUF_SWAP_32BIT (2 << 16)
+# define RADEON_RB_NO_UPDATE (1 << 27)
#define RADEON_CP_RB_RPTR_ADDR 0x070c
#define RADEON_CP_RB_RPTR 0x0710
#define RADEON_CP_RB_WPTR 0x0714
@@ -986,13 +996,13 @@ do { \
} while (0)
#define RADEON_FLUSH_CACHE() do { \
- OUT_RING( CP_PACKET0( RADEON_RB2D_DSTCACHE_CTLSTAT, 0 ) ); \
- OUT_RING( RADEON_RB2D_DC_FLUSH ); \
+ OUT_RING( CP_PACKET0( RADEON_RB3D_DSTCACHE_CTLSTAT, 0 ) ); \
+ OUT_RING( RADEON_RB3D_DC_FLUSH ); \
} while (0)
#define RADEON_PURGE_CACHE() do { \
- OUT_RING( CP_PACKET0( RADEON_RB2D_DSTCACHE_CTLSTAT, 0 ) ); \
- OUT_RING( RADEON_RB2D_DC_FLUSH_ALL ); \
+ OUT_RING( CP_PACKET0( RADEON_RB3D_DSTCACHE_CTLSTAT, 0 ) ); \
+ OUT_RING( RADEON_RB3D_DC_FLUSH_ALL ); \
} while (0)
#define RADEON_FLUSH_ZCACHE() do { \
diff --git a/drivers/char/drm/radeon_state.c b/drivers/char/drm/radeon_state.c
index 39a7f685e3fd..feac5f005d47 100644
--- a/drivers/char/drm/radeon_state.c
+++ b/drivers/char/drm/radeon_state.c
@@ -42,7 +42,11 @@ static __inline__ int radeon_check_and_fixup_offset(drm_radeon_private_t *
drm_file_t * filp_priv,
u32 *offset)
{
- u32 off = *offset;
+ u64 off = *offset;
+ u32 fb_start = dev_priv->fb_location;
+ u32 fb_end = fb_start + dev_priv->fb_size - 1;
+ u32 gart_start = dev_priv->gart_vm_start;
+ u32 gart_end = gart_start + dev_priv->gart_size - 1;
struct drm_radeon_driver_file_fields *radeon_priv;
/* Hrm ... the story of the offset ... So this function converts
@@ -62,10 +66,8 @@ static __inline__ int radeon_check_and_fixup_offset(drm_radeon_private_t *
/* First, the best case, the offset already lands in either the
* framebuffer or the GART mapped space
*/
- if ((off >= dev_priv->fb_location &&
- off < (dev_priv->fb_location + dev_priv->fb_size)) ||
- (off >= dev_priv->gart_vm_start &&
- off < (dev_priv->gart_vm_start + dev_priv->gart_size)))
+ if ((off >= fb_start && off <= fb_end) ||
+ (off >= gart_start && off <= gart_end))
return 0;
/* Ok, that didn't happen... now check if we have a zero based
@@ -78,16 +80,13 @@ static __inline__ int radeon_check_and_fixup_offset(drm_radeon_private_t *
}
/* Finally, assume we aimed at a GART offset if beyond the fb */
- if (off > (dev_priv->fb_location + dev_priv->fb_size))
- off = off - (dev_priv->fb_location + dev_priv->fb_size) +
- dev_priv->gart_vm_start;
+ if (off > fb_end)
+ off = off - fb_end - 1 + gart_start;
/* Now recheck and fail if out of bounds */
- if ((off >= dev_priv->fb_location &&
- off < (dev_priv->fb_location + dev_priv->fb_size)) ||
- (off >= dev_priv->gart_vm_start &&
- off < (dev_priv->gart_vm_start + dev_priv->gart_size))) {
- DRM_DEBUG("offset fixed up to 0x%x\n", off);
+ if ((off >= fb_start && off <= fb_end) ||
+ (off >= gart_start && off <= gart_end)) {
+ DRM_DEBUG("offset fixed up to 0x%x\n", (unsigned int)off);
*offset = off;
return 0;
}
@@ -869,7 +868,7 @@ static void radeon_cp_dispatch_clear(drm_device_t * dev,
*/
dev_priv->sarea_priv->ctx_owner = 0;
- if ((dev_priv->flags & CHIP_HAS_HIERZ)
+ if ((dev_priv->flags & RADEON_HAS_HIERZ)
&& (flags & RADEON_USE_HIERZ)) {
/* FIXME : reverse engineer that for Rx00 cards */
/* FIXME : the mask supposedly contains low-res z values. So can't set
@@ -914,7 +913,7 @@ static void radeon_cp_dispatch_clear(drm_device_t * dev,
for (i = 0; i < nbox; i++) {
int tileoffset, nrtilesx, nrtilesy, j;
/* it looks like r200 needs rv-style clears, at least if hierz is not enabled? */
- if ((dev_priv->flags & CHIP_HAS_HIERZ)
+ if ((dev_priv->flags & RADEON_HAS_HIERZ)
&& !(dev_priv->microcode_version == UCODE_R200)) {
/* FIXME : figure this out for r200 (when hierz is enabled). Or
maybe r200 actually doesn't need to put the low-res z value into
@@ -998,7 +997,7 @@ static void radeon_cp_dispatch_clear(drm_device_t * dev,
}
/* TODO don't always clear all hi-level z tiles */
- if ((dev_priv->flags & CHIP_HAS_HIERZ)
+ if ((dev_priv->flags & RADEON_HAS_HIERZ)
&& (dev_priv->microcode_version == UCODE_R200)
&& (flags & RADEON_USE_HIERZ))
/* r100 and cards without hierarchical z-buffer have no high-level z-buffer */
@@ -1270,9 +1269,9 @@ static void radeon_cp_dispatch_swap(drm_device_t * dev)
DRM_DEBUG("dispatch swap %d,%d-%d,%d\n", x, y, w, h);
- BEGIN_RING(7);
+ BEGIN_RING(9);
- OUT_RING(CP_PACKET3(RADEON_CNTL_BITBLT_MULTI, 5));
+ OUT_RING(CP_PACKET0(RADEON_DP_GUI_MASTER_CNTL, 0));
OUT_RING(RADEON_GMC_SRC_PITCH_OFFSET_CNTL |
RADEON_GMC_DST_PITCH_OFFSET_CNTL |
RADEON_GMC_BRUSH_NONE |
@@ -1284,6 +1283,7 @@ static void radeon_cp_dispatch_swap(drm_device_t * dev)
/* Make this work even if front & back are flipped:
*/
+ OUT_RING(CP_PACKET0(RADEON_SRC_PITCH_OFFSET, 1));
if (dev_priv->current_page == 0) {
OUT_RING(dev_priv->back_pitch_offset);
OUT_RING(dev_priv->front_pitch_offset);
@@ -1292,6 +1292,7 @@ static void radeon_cp_dispatch_swap(drm_device_t * dev)
OUT_RING(dev_priv->back_pitch_offset);
}
+ OUT_RING(CP_PACKET0(RADEON_SRC_X_Y, 2));
OUT_RING((x << 16) | y);
OUT_RING((x << 16) | y);
OUT_RING((w << 16) | h);
@@ -2987,16 +2988,21 @@ static int radeon_cp_getparam(DRM_IOCTL_ARGS)
case RADEON_PARAM_GART_TEX_HANDLE:
value = dev_priv->gart_textures_offset;
break;
-
+ case RADEON_PARAM_SCRATCH_OFFSET:
+ if (!dev_priv->writeback_works)
+ return DRM_ERR(EINVAL);
+ value = RADEON_SCRATCH_REG_OFFSET;
+ break;
case RADEON_PARAM_CARD_TYPE:
- if (dev_priv->flags & CHIP_IS_PCIE)
+ if (dev_priv->flags & RADEON_IS_PCIE)
value = RADEON_CARD_PCIE;
- else if (dev_priv->flags & CHIP_IS_AGP)
+ else if (dev_priv->flags & RADEON_IS_AGP)
value = RADEON_CARD_AGP;
else
value = RADEON_CARD_PCI;
break;
default:
+ DRM_DEBUG("Invalid parameter %d\n", param.param);
return DRM_ERR(EINVAL);
}
diff --git a/drivers/char/drm/sis_drv.c b/drivers/char/drm/sis_drv.c
index 5e9dc86f2956..3d5b3218b6ff 100644
--- a/drivers/char/drm/sis_drv.c
+++ b/drivers/char/drm/sis_drv.c
@@ -35,11 +35,44 @@ static struct pci_device_id pciidlist[] = {
sisdrv_PCI_IDS
};
+static int sis_driver_load(drm_device_t *dev, unsigned long chipset)
+{
+ drm_sis_private_t *dev_priv;
+ int ret;
+
+ dev_priv = drm_calloc(1, sizeof(drm_sis_private_t), DRM_MEM_DRIVER);
+ if (dev_priv == NULL)
+ return DRM_ERR(ENOMEM);
+
+ dev->dev_private = (void *)dev_priv;
+ dev_priv->chipset = chipset;
+ ret = drm_sman_init(&dev_priv->sman, 2, 12, 8);
+ if (ret) {
+ drm_free(dev_priv, sizeof(dev_priv), DRM_MEM_DRIVER);
+ }
+
+ return ret;
+}
+
+static int sis_driver_unload(drm_device_t *dev)
+{
+ drm_sis_private_t *dev_priv = dev->dev_private;
+
+ drm_sman_takedown(&dev_priv->sman);
+ drm_free(dev_priv, sizeof(*dev_priv), DRM_MEM_DRIVER);
+
+ return 0;
+}
+
static struct drm_driver driver = {
.driver_features = DRIVER_USE_AGP | DRIVER_USE_MTRR,
- .context_ctor = sis_init_context,
- .context_dtor = sis_final_context,
- .reclaim_buffers = drm_core_reclaim_buffers,
+ .load = sis_driver_load,
+ .unload = sis_driver_unload,
+ .context_dtor = NULL,
+ .dma_quiescent = sis_idle,
+ .reclaim_buffers = NULL,
+ .reclaim_buffers_locked = sis_reclaim_buffers_locked,
+ .lastclose = sis_lastclose,
.get_map_ofs = drm_core_get_map_ofs,
.get_reg_ofs = drm_core_get_reg_ofs,
.ioctls = sis_ioctls,
diff --git a/drivers/char/drm/sis_drv.h b/drivers/char/drm/sis_drv.h
index e218e5269503..2b8d6f6ed7c0 100644
--- a/drivers/char/drm/sis_drv.h
+++ b/drivers/char/drm/sis_drv.h
@@ -31,23 +31,39 @@
/* General customization:
*/
-#define DRIVER_AUTHOR "SIS"
+#define DRIVER_AUTHOR "SIS, Tungsten Graphics"
#define DRIVER_NAME "sis"
#define DRIVER_DESC "SIS 300/630/540"
-#define DRIVER_DATE "20030826"
+#define DRIVER_DATE "20060704"
#define DRIVER_MAJOR 1
-#define DRIVER_MINOR 1
-#define DRIVER_PATCHLEVEL 0
+#define DRIVER_MINOR 2
+#define DRIVER_PATCHLEVEL 1
-#include "sis_ds.h"
+enum sis_family {
+ SIS_OTHER = 0,
+ SIS_CHIP_315 = 1,
+};
+
+#include "drm_sman.h"
+
+#define SIS_BASE (dev_priv->mmio)
+#define SIS_READ(reg) DRM_READ32(SIS_BASE, reg);
+#define SIS_WRITE(reg, val) DRM_WRITE32(SIS_BASE, reg, val);
typedef struct drm_sis_private {
- memHeap_t *AGPHeap;
- memHeap_t *FBHeap;
+ drm_local_map_t *mmio;
+ unsigned int idle_fault;
+ drm_sman_t sman;
+ unsigned int chipset;
+ int vram_initialized;
+ int agp_initialized;
+ unsigned long vram_offset;
+ unsigned long agp_offset;
} drm_sis_private_t;
-extern int sis_init_context(drm_device_t * dev, int context);
-extern int sis_final_context(drm_device_t * dev, int context);
+extern int sis_idle(drm_device_t *dev);
+extern void sis_reclaim_buffers_locked(drm_device_t *dev, struct file *filp);
+extern void sis_lastclose(drm_device_t *dev);
extern drm_ioctl_desc_t sis_ioctls[];
extern int sis_max_ioctl;
diff --git a/drivers/char/drm/sis_ds.c b/drivers/char/drm/sis_ds.c
deleted file mode 100644
index 2e485d482943..000000000000
--- a/drivers/char/drm/sis_ds.c
+++ /dev/null
@@ -1,299 +0,0 @@
-/* sis_ds.c -- Private header for Direct Rendering Manager -*- linux-c -*-
- * Created: Mon Jan 4 10:05:05 1999 by sclin@sis.com.tw
- *
- * Copyright 2000 Silicon Integrated Systems Corp, Inc., HsinChu, Taiwan.
- * All rights reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- * Authors:
- * Sung-Ching Lin <sclin@sis.com.tw>
- *
- */
-
-#include "drmP.h"
-#include "drm.h"
-#include "sis_ds.h"
-
-/* Set Data Structure, not check repeated value
- * temporarily used
- */
-
-set_t *setInit(void)
-{
- int i;
- set_t *set;
-
- set = (set_t *) drm_alloc(sizeof(set_t), DRM_MEM_DRIVER);
- if (set != NULL) {
- for (i = 0; i < SET_SIZE; i++) {
- set->list[i].free_next = i + 1;
- set->list[i].alloc_next = -1;
- }
- set->list[SET_SIZE - 1].free_next = -1;
- set->free = 0;
- set->alloc = -1;
- set->trace = -1;
- }
- return set;
-}
-
-int setAdd(set_t * set, ITEM_TYPE item)
-{
- int free = set->free;
-
- if (free != -1) {
- set->list[free].val = item;
- set->free = set->list[free].free_next;
- } else {
- return 0;
- }
-
- set->list[free].alloc_next = set->alloc;
- set->alloc = free;
- set->list[free].free_next = -1;
-
- return 1;
-}
-
-int setDel(set_t * set, ITEM_TYPE item)
-{
- int alloc = set->alloc;
- int prev = -1;
-
- while (alloc != -1) {
- if (set->list[alloc].val == item) {
- if (prev != -1)
- set->list[prev].alloc_next =
- set->list[alloc].alloc_next;
- else
- set->alloc = set->list[alloc].alloc_next;
- break;
- }
- prev = alloc;
- alloc = set->list[alloc].alloc_next;
- }
-
- if (alloc == -1)
- return 0;
-
- set->list[alloc].free_next = set->free;
- set->free = alloc;
- set->list[alloc].alloc_next = -1;
-
- return 1;
-}
-
-/* setFirst -> setAdd -> setNext is wrong */
-
-int setFirst(set_t * set, ITEM_TYPE * item)
-{
- if (set->alloc == -1)
- return 0;
-
- *item = set->list[set->alloc].val;
- set->trace = set->list[set->alloc].alloc_next;
-
- return 1;
-}
-
-int setNext(set_t * set, ITEM_TYPE * item)
-{
- if (set->trace == -1)
- return 0;
-
- *item = set->list[set->trace].val;
- set->trace = set->list[set->trace].alloc_next;
-
- return 1;
-}
-
-int setDestroy(set_t * set)
-{
- drm_free(set, sizeof(set_t), DRM_MEM_DRIVER);
-
- return 1;
-}
-
-/*
- * GLX Hardware Device Driver common code
- * Copyright (C) 1999 Wittawat Yamwong
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * WITTAWAT YAMWONG, OR ANY OTHER CONTRIBUTORS BE LIABLE FOR ANY CLAIM,
- * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
- * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
- * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- */
-
-#define ISFREE(bptr) ((bptr)->free)
-
-memHeap_t *mmInit(int ofs, int size)
-{
- PMemBlock blocks;
-
- if (size <= 0)
- return NULL;
-
- blocks = (TMemBlock *) drm_calloc(1, sizeof(TMemBlock), DRM_MEM_DRIVER);
- if (blocks != NULL) {
- blocks->ofs = ofs;
- blocks->size = size;
- blocks->free = 1;
- return (memHeap_t *) blocks;
- } else
- return NULL;
-}
-
-/* Checks if a pointer 'b' is part of the heap 'heap' */
-int mmBlockInHeap(memHeap_t * heap, PMemBlock b)
-{
- TMemBlock *p;
-
- if (heap == NULL || b == NULL)
- return 0;
-
- p = heap;
- while (p != NULL && p != b) {
- p = p->next;
- }
- if (p == b)
- return 1;
- else
- return 0;
-}
-
-static TMemBlock *SliceBlock(TMemBlock * p,
- int startofs, int size,
- int reserved, int alignment)
-{
- TMemBlock *newblock;
-
- /* break left */
- if (startofs > p->ofs) {
- newblock = (TMemBlock *) drm_calloc(1, sizeof(TMemBlock),
- DRM_MEM_DRIVER);
- newblock->ofs = startofs;
- newblock->size = p->size - (startofs - p->ofs);
- newblock->free = 1;
- newblock->next = p->next;
- p->size -= newblock->size;
- p->next = newblock;
- p = newblock;
- }
-
- /* break right */
- if (size < p->size) {
- newblock = (TMemBlock *) drm_calloc(1, sizeof(TMemBlock),
- DRM_MEM_DRIVER);
- newblock->ofs = startofs + size;
- newblock->size = p->size - size;
- newblock->free = 1;
- newblock->next = p->next;
- p->size = size;
- p->next = newblock;
- }
-
- /* p = middle block */
- p->align = alignment;
- p->free = 0;
- p->reserved = reserved;
- return p;
-}
-
-PMemBlock mmAllocMem(memHeap_t * heap, int size, int align2, int startSearch)
-{
- int mask, startofs, endofs;
- TMemBlock *p;
-
- if (heap == NULL || align2 < 0 || size <= 0)
- return NULL;
-
- mask = (1 << align2) - 1;
- startofs = 0;
- p = (TMemBlock *) heap;
- while (p != NULL) {
- if (ISFREE(p)) {
- startofs = (p->ofs + mask) & ~mask;
- if (startofs < startSearch) {
- startofs = startSearch;
- }
- endofs = startofs + size;
- if (endofs <= (p->ofs + p->size))
- break;
- }
- p = p->next;
- }
- if (p == NULL)
- return NULL;
- p = SliceBlock(p, startofs, size, 0, mask + 1);
- p->heap = heap;
- return p;
-}
-
-static __inline__ int Join2Blocks(TMemBlock * p)
-{
- if (p->free && p->next && p->next->free) {
- TMemBlock *q = p->next;
- p->size += q->size;
- p->next = q->next;
- drm_free(q, sizeof(TMemBlock), DRM_MEM_DRIVER);
- return 1;
- }
- return 0;
-}
-
-int mmFreeMem(PMemBlock b)
-{
- TMemBlock *p, *prev;
-
- if (b == NULL)
- return 0;
- if (b->heap == NULL)
- return -1;
-
- p = b->heap;
- prev = NULL;
- while (p != NULL && p != b) {
- prev = p;
- p = p->next;
- }
- if (p == NULL || p->free || p->reserved)
- return -1;
-
- p->free = 1;
- Join2Blocks(p);
- if (prev)
- Join2Blocks(prev);
- return 0;
-}
diff --git a/drivers/char/drm/sis_ds.h b/drivers/char/drm/sis_ds.h
deleted file mode 100644
index 94f2b4728b63..000000000000
--- a/drivers/char/drm/sis_ds.h
+++ /dev/null
@@ -1,146 +0,0 @@
-/* sis_ds.h -- Private header for Direct Rendering Manager -*- linux-c -*-
- * Created: Mon Jan 4 10:05:05 1999 by sclin@sis.com.tw
- */
-/*
- * Copyright 2000 Silicon Integrated Systems Corp, Inc., HsinChu, Taiwan.
- * All rights reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- * Authors:
- * Sung-Ching Lin <sclin@sis.com.tw>
- *
- */
-
-#ifndef __SIS_DS_H__
-#define __SIS_DS_H__
-
-/* Set Data Structure */
-
-#define SET_SIZE 5000
-
-typedef unsigned long ITEM_TYPE;
-
-typedef struct {
- ITEM_TYPE val;
- int alloc_next, free_next;
-} list_item_t;
-
-typedef struct {
- int alloc;
- int free;
- int trace;
- list_item_t list[SET_SIZE];
-} set_t;
-
-set_t *setInit(void);
-int setAdd(set_t * set, ITEM_TYPE item);
-int setDel(set_t * set, ITEM_TYPE item);
-int setFirst(set_t * set, ITEM_TYPE * item);
-int setNext(set_t * set, ITEM_TYPE * item);
-int setDestroy(set_t * set);
-
-/*
- * GLX Hardware Device Driver common code
- * Copyright (C) 1999 Wittawat Yamwong
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * WITTAWAT YAMWONG, OR ANY OTHER CONTRIBUTORS BE LIABLE FOR ANY CLAIM,
- * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
- * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
- * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- */
-
-struct mem_block_t {
- struct mem_block_t *next;
- struct mem_block_t *heap;
- int ofs, size;
- int align;
- unsigned int free:1;
- unsigned int reserved:1;
-};
-typedef struct mem_block_t TMemBlock;
-typedef struct mem_block_t *PMemBlock;
-
-/* a heap is just the first block in a chain */
-typedef struct mem_block_t memHeap_t;
-
-static __inline__ int mmBlockSize(PMemBlock b)
-{
- return b->size;
-}
-
-static __inline__ int mmOffset(PMemBlock b)
-{
- return b->ofs;
-}
-
-static __inline__ void mmMarkReserved(PMemBlock b)
-{
- b->reserved = 1;
-}
-
-/*
- * input: total size in bytes
- * return: a heap pointer if OK, NULL if error
- */
-memHeap_t *mmInit(int ofs, int size);
-
-/*
- * Allocate 'size' bytes with 2^align2 bytes alignment,
- * restrict the search to free memory after 'startSearch'
- * depth and back buffers should be in different 4mb banks
- * to get better page hits if possible
- * input: size = size of block
- * align2 = 2^align2 bytes alignment
- * startSearch = linear offset from start of heap to begin search
- * return: pointer to the allocated block, 0 if error
- */
-PMemBlock mmAllocMem(memHeap_t * heap, int size, int align2, int startSearch);
-
-/*
- * Returns 1 if the block 'b' is part of the heap 'heap'
- */
-int mmBlockInHeap(PMemBlock heap, PMemBlock b);
-
-/*
- * Free block starts at offset
- * input: pointer to a block
- * return: 0 if OK, -1 if error
- */
-int mmFreeMem(PMemBlock b);
-
-/* For debuging purpose. */
-void mmDumpMemInfo(memHeap_t * mmInit);
-
-#endif /* __SIS_DS_H__ */
diff --git a/drivers/char/drm/sis_mm.c b/drivers/char/drm/sis_mm.c
index 5e9936bc307f..d26f5dbb7853 100644
--- a/drivers/char/drm/sis_mm.c
+++ b/drivers/char/drm/sis_mm.c
@@ -1,414 +1,348 @@
-/* sis_mm.c -- Private header for Direct Rendering Manager -*- linux-c -*-
- * Created: Mon Jan 4 10:05:05 1999 by sclin@sis.com.tw
+/**************************************************************************
*
- * Copyright 2000 Silicon Integrated Systems Corp, Inc., HsinChu, Taiwan.
- * All rights reserved.
+ * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND., USA.
+ * All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
*
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ * USE OR OTHER DEALINGS IN THE SOFTWARE.
*
- * Authors:
- * Sung-Ching Lin <sclin@sis.com.tw>
*
+ **************************************************************************/
+
+/*
+ * Authors:
+ * Thomas Hellström <thomas-at-tungstengraphics-dot-com>
*/
#include "drmP.h"
#include "sis_drm.h"
#include "sis_drv.h"
-#include "sis_ds.h"
-#if defined(__linux__) && defined(CONFIG_FB_SIS)
+
#include <video/sisfb.h>
-#endif
-#define MAX_CONTEXT 100
#define VIDEO_TYPE 0
#define AGP_TYPE 1
-typedef struct {
- int used;
- int context;
- set_t *sets[2]; /* 0 for video, 1 for AGP */
-} sis_context_t;
-static sis_context_t global_ppriv[MAX_CONTEXT];
+#if defined(CONFIG_FB_SIS)
+/* fb management via fb device */
-static int add_alloc_set(int context, int type, unsigned int val)
-{
- int i, retval = 0;
+#define SIS_MM_ALIGN_SHIFT 0
+#define SIS_MM_ALIGN_MASK 0
- for (i = 0; i < MAX_CONTEXT; i++) {
- if (global_ppriv[i].used && global_ppriv[i].context == context) {
- retval = setAdd(global_ppriv[i].sets[type], val);
- break;
- }
- }
- return retval;
-}
-
-static int del_alloc_set(int context, int type, unsigned int val)
+static void *sis_sman_mm_allocate(void *private, unsigned long size,
+ unsigned alignment)
{
- int i, retval = 0;
+ struct sis_memreq req;
- for (i = 0; i < MAX_CONTEXT; i++) {
- if (global_ppriv[i].used && global_ppriv[i].context == context) {
- retval = setDel(global_ppriv[i].sets[type], val);
- break;
- }
- }
- return retval;
+ req.size = size;
+ sis_malloc(&req);
+ if (req.size == 0)
+ return NULL;
+ else
+ return (void *)~req.offset;
}
-/* fb management via fb device */
-#if defined(__linux__) && defined(CONFIG_FB_SIS)
-
-static int sis_fb_init(DRM_IOCTL_ARGS)
+static void sis_sman_mm_free(void *private, void *ref)
{
- return 0;
+ sis_free(~((unsigned long)ref));
}
-static int sis_fb_alloc(DRM_IOCTL_ARGS)
+static void sis_sman_mm_destroy(void *private)
{
- drm_sis_mem_t fb;
- struct sis_memreq req;
- drm_sis_mem_t __user *argp = (drm_sis_mem_t __user *)data;
- int retval = 0;
-
- DRM_COPY_FROM_USER_IOCTL(fb, argp, sizeof(fb));
-
- req.size = fb.size;
- sis_malloc(&req);
- if (req.offset) {
- /* TODO */
- fb.offset = req.offset;
- fb.free = req.offset;
- if (!add_alloc_set(fb.context, VIDEO_TYPE, fb.free)) {
- DRM_DEBUG("adding to allocation set fails\n");
- sis_free(req.offset);
- retval = DRM_ERR(EINVAL);
- }
- } else {
- fb.offset = 0;
- fb.size = 0;
- fb.free = 0;
- }
-
- DRM_COPY_TO_USER_IOCTL(argp, fb, sizeof(fb));
-
- DRM_DEBUG("alloc fb, size = %d, offset = %d\n", fb.size, req.offset);
-
- return retval;
+ ;
}
-static int sis_fb_free(DRM_IOCTL_ARGS)
+static unsigned long sis_sman_mm_offset(void *private, void *ref)
{
- drm_sis_mem_t fb;
- int retval = 0;
-
- DRM_COPY_FROM_USER_IOCTL(fb, (drm_sis_mem_t __user *) data, sizeof(fb));
-
- if (!fb.free)
- return DRM_ERR(EINVAL);
+ return ~((unsigned long)ref);
+}
- if (!del_alloc_set(fb.context, VIDEO_TYPE, fb.free))
- retval = DRM_ERR(EINVAL);
- sis_free(fb.free);
+#else /* CONFIG_FB_SIS */
- DRM_DEBUG("free fb, offset = 0x%lx\n", fb.free);
+#define SIS_MM_ALIGN_SHIFT 4
+#define SIS_MM_ALIGN_MASK ( (1 << SIS_MM_ALIGN_SHIFT) - 1)
- return retval;
-}
+#endif /* CONFIG_FB_SIS */
-#else
-
-/* Called by the X Server to initialize the FB heap. Allocations will fail
- * unless this is called. Offset is the beginning of the heap from the
- * framebuffer offset (MaxXFBMem in XFree86).
- *
- * Memory layout according to Thomas Winischofer:
- * |------------------|DDDDDDDDDDDDDDDDDDDDDDDDDDDDD|HHHH|CCCCCCCCCCC|
- *
- * X driver/sisfb HW- Command-
- * framebuffer memory DRI heap Cursor queue
- */
static int sis_fb_init(DRM_IOCTL_ARGS)
{
DRM_DEVICE;
drm_sis_private_t *dev_priv = dev->dev_private;
drm_sis_fb_t fb;
+ int ret;
DRM_COPY_FROM_USER_IOCTL(fb, (drm_sis_fb_t __user *) data, sizeof(fb));
- if (dev_priv == NULL) {
- dev->dev_private = drm_calloc(1, sizeof(drm_sis_private_t),
- DRM_MEM_DRIVER);
- dev_priv = dev->dev_private;
- if (dev_priv == NULL)
- return ENOMEM;
+ mutex_lock(&dev->struct_mutex);
+#if defined(CONFIG_FB_SIS)
+ {
+ drm_sman_mm_t sman_mm;
+ sman_mm.private = (void *)0xFFFFFFFF;
+ sman_mm.allocate = sis_sman_mm_allocate;
+ sman_mm.free = sis_sman_mm_free;
+ sman_mm.destroy = sis_sman_mm_destroy;
+ sman_mm.offset = sis_sman_mm_offset;
+ ret =
+ drm_sman_set_manager(&dev_priv->sman, VIDEO_TYPE, &sman_mm);
}
+#else
+ ret = drm_sman_set_range(&dev_priv->sman, VIDEO_TYPE, 0,
+ fb.size >> SIS_MM_ALIGN_SHIFT);
+#endif
- if (dev_priv->FBHeap != NULL)
- return DRM_ERR(EINVAL);
+ if (ret) {
+ DRM_ERROR("VRAM memory manager initialisation error\n");
+ mutex_unlock(&dev->struct_mutex);
+ return ret;
+ }
- dev_priv->FBHeap = mmInit(fb.offset, fb.size);
+ dev_priv->vram_initialized = 1;
+ dev_priv->vram_offset = fb.offset;
+ mutex_unlock(&dev->struct_mutex);
DRM_DEBUG("offset = %u, size = %u", fb.offset, fb.size);
return 0;
}
-static int sis_fb_alloc(DRM_IOCTL_ARGS)
+static int sis_drm_alloc(drm_device_t * dev, drm_file_t * priv,
+ unsigned long data, int pool)
{
- DRM_DEVICE;
drm_sis_private_t *dev_priv = dev->dev_private;
- drm_sis_mem_t __user *argp = (drm_sis_mem_t __user *)data;
- drm_sis_mem_t fb;
- PMemBlock block;
+ drm_sis_mem_t __user *argp = (drm_sis_mem_t __user *) data;
+ drm_sis_mem_t mem;
int retval = 0;
+ drm_memblock_item_t *item;
+
+ DRM_COPY_FROM_USER_IOCTL(mem, argp, sizeof(mem));
- if (dev_priv == NULL || dev_priv->FBHeap == NULL)
+ mutex_lock(&dev->struct_mutex);
+
+ if (0 == ((pool == 0) ? dev_priv->vram_initialized :
+ dev_priv->agp_initialized)) {
+ DRM_ERROR
+ ("Attempt to allocate from uninitialized memory manager.\n");
return DRM_ERR(EINVAL);
+ }
- DRM_COPY_FROM_USER_IOCTL(fb, argp, sizeof(fb));
-
- block = mmAllocMem(dev_priv->FBHeap, fb.size, 0, 0);
- if (block) {
- /* TODO */
- fb.offset = block->ofs;
- fb.free = (unsigned long)block;
- if (!add_alloc_set(fb.context, VIDEO_TYPE, fb.free)) {
- DRM_DEBUG("adding to allocation set fails\n");
- mmFreeMem((PMemBlock) fb.free);
- retval = DRM_ERR(EINVAL);
- }
+ mem.size = (mem.size + SIS_MM_ALIGN_MASK) >> SIS_MM_ALIGN_SHIFT;
+ item = drm_sman_alloc(&dev_priv->sman, pool, mem.size, 0,
+ (unsigned long)priv);
+
+ mutex_unlock(&dev->struct_mutex);
+ if (item) {
+ mem.offset = ((pool == 0) ?
+ dev_priv->vram_offset : dev_priv->agp_offset) +
+ (item->mm->
+ offset(item->mm, item->mm_info) << SIS_MM_ALIGN_SHIFT);
+ mem.free = item->user_hash.key;
+ mem.size = mem.size << SIS_MM_ALIGN_SHIFT;
} else {
- fb.offset = 0;
- fb.size = 0;
- fb.free = 0;
+ mem.offset = 0;
+ mem.size = 0;
+ mem.free = 0;
+ retval = DRM_ERR(ENOMEM);
}
- DRM_COPY_TO_USER_IOCTL(argp, fb, sizeof(fb));
+ DRM_COPY_TO_USER_IOCTL(argp, mem, sizeof(mem));
- DRM_DEBUG("alloc fb, size = %d, offset = %d\n", fb.size, fb.offset);
+ DRM_DEBUG("alloc %d, size = %d, offset = %d\n", pool, mem.size,
+ mem.offset);
return retval;
}
-static int sis_fb_free(DRM_IOCTL_ARGS)
+static int sis_drm_free(DRM_IOCTL_ARGS)
{
DRM_DEVICE;
drm_sis_private_t *dev_priv = dev->dev_private;
- drm_sis_mem_t fb;
+ drm_sis_mem_t mem;
+ int ret;
- if (dev_priv == NULL || dev_priv->FBHeap == NULL)
- return DRM_ERR(EINVAL);
+ DRM_COPY_FROM_USER_IOCTL(mem, (drm_sis_mem_t __user *) data,
+ sizeof(mem));
- DRM_COPY_FROM_USER_IOCTL(fb, (drm_sis_mem_t __user *) data, sizeof(fb));
+ mutex_lock(&dev->struct_mutex);
+ ret = drm_sman_free_key(&dev_priv->sman, mem.free);
+ mutex_unlock(&dev->struct_mutex);
+ DRM_DEBUG("free = 0x%lx\n", mem.free);
- if (!mmBlockInHeap(dev_priv->FBHeap, (PMemBlock) fb.free))
- return DRM_ERR(EINVAL);
-
- if (!del_alloc_set(fb.context, VIDEO_TYPE, fb.free))
- return DRM_ERR(EINVAL);
- mmFreeMem((PMemBlock) fb.free);
-
- DRM_DEBUG("free fb, free = 0x%lx\n", fb.free);
-
- return 0;
+ return ret;
}
-#endif
-
-/* agp memory management */
+static int sis_fb_alloc(DRM_IOCTL_ARGS)
+{
+ DRM_DEVICE;
+ return sis_drm_alloc(dev, priv, data, VIDEO_TYPE);
+}
static int sis_ioctl_agp_init(DRM_IOCTL_ARGS)
{
DRM_DEVICE;
drm_sis_private_t *dev_priv = dev->dev_private;
drm_sis_agp_t agp;
-
- if (dev_priv == NULL) {
- dev->dev_private = drm_calloc(1, sizeof(drm_sis_private_t),
- DRM_MEM_DRIVER);
- dev_priv = dev->dev_private;
- if (dev_priv == NULL)
- return ENOMEM;
- }
-
- if (dev_priv->AGPHeap != NULL)
- return DRM_ERR(EINVAL);
+ int ret;
+ dev_priv = dev->dev_private;
DRM_COPY_FROM_USER_IOCTL(agp, (drm_sis_agp_t __user *) data,
sizeof(agp));
+ mutex_lock(&dev->struct_mutex);
+ ret = drm_sman_set_range(&dev_priv->sman, AGP_TYPE, 0,
+ agp.size >> SIS_MM_ALIGN_SHIFT);
+
+ if (ret) {
+ DRM_ERROR("AGP memory manager initialisation error\n");
+ mutex_unlock(&dev->struct_mutex);
+ return ret;
+ }
- dev_priv->AGPHeap = mmInit(agp.offset, agp.size);
+ dev_priv->agp_initialized = 1;
+ dev_priv->agp_offset = agp.offset;
+ mutex_unlock(&dev->struct_mutex);
DRM_DEBUG("offset = %u, size = %u", agp.offset, agp.size);
-
return 0;
}
static int sis_ioctl_agp_alloc(DRM_IOCTL_ARGS)
{
DRM_DEVICE;
- drm_sis_private_t *dev_priv = dev->dev_private;
- drm_sis_mem_t __user *argp = (drm_sis_mem_t __user *)data;
- drm_sis_mem_t agp;
- PMemBlock block;
- int retval = 0;
- if (dev_priv == NULL || dev_priv->AGPHeap == NULL)
- return DRM_ERR(EINVAL);
+ return sis_drm_alloc(dev, priv, data, AGP_TYPE);
+}
- DRM_COPY_FROM_USER_IOCTL(agp, argp, sizeof(agp));
-
- block = mmAllocMem(dev_priv->AGPHeap, agp.size, 0, 0);
- if (block) {
- /* TODO */
- agp.offset = block->ofs;
- agp.free = (unsigned long)block;
- if (!add_alloc_set(agp.context, AGP_TYPE, agp.free)) {
- DRM_DEBUG("adding to allocation set fails\n");
- mmFreeMem((PMemBlock) agp.free);
- retval = -1;
+static drm_local_map_t *sis_reg_init(drm_device_t *dev)
+{
+ drm_map_list_t *entry;
+ drm_local_map_t *map;
+
+ list_for_each_entry(entry, &dev->maplist->head, head) {
+ map = entry->map;
+ if (!map)
+ continue;
+ if (map->type == _DRM_REGISTERS) {
+ return map;
}
- } else {
- agp.offset = 0;
- agp.size = 0;
- agp.free = 0;
}
-
- DRM_COPY_TO_USER_IOCTL(argp, agp, sizeof(agp));
-
- DRM_DEBUG("alloc agp, size = %d, offset = %d\n", agp.size, agp.offset);
-
- return retval;
+ return NULL;
}
-static int sis_ioctl_agp_free(DRM_IOCTL_ARGS)
+int sis_idle(drm_device_t *dev)
{
- DRM_DEVICE;
drm_sis_private_t *dev_priv = dev->dev_private;
- drm_sis_mem_t agp;
-
- if (dev_priv == NULL || dev_priv->AGPHeap == NULL)
- return DRM_ERR(EINVAL);
+ uint32_t idle_reg;
+ unsigned long end;
+ int i;
- DRM_COPY_FROM_USER_IOCTL(agp, (drm_sis_mem_t __user *) data,
- sizeof(agp));
+ if (dev_priv->idle_fault)
+ return 0;
- if (!mmBlockInHeap(dev_priv->AGPHeap, (PMemBlock) agp.free))
- return DRM_ERR(EINVAL);
+ if (dev_priv->mmio == NULL) {
+ dev_priv->mmio = sis_reg_init(dev);
+ if (dev_priv->mmio == NULL) {
+ DRM_ERROR("Could not find register map.\n");
+ return 0;
+ }
+ }
+
+ /*
+ * Implement a device switch here if needed
+ */
+
+ if (dev_priv->chipset != SIS_CHIP_315)
+ return 0;
+
+ /*
+ * Timeout after 3 seconds. We cannot use DRM_WAIT_ON here
+ * because its polling frequency is too low.
+ */
+
+ end = jiffies + (DRM_HZ * 3);
+
+ for (i=0; i<4; ++i) {
+ do {
+ idle_reg = SIS_READ(0x85cc);
+ } while ( !time_after_eq(jiffies, end) &&
+ ((idle_reg & 0x80000000) != 0x80000000));
+ }
- mmFreeMem((PMemBlock) agp.free);
- if (!del_alloc_set(agp.context, AGP_TYPE, agp.free))
- return DRM_ERR(EINVAL);
+ if (time_after_eq(jiffies, end)) {
+ DRM_ERROR("Graphics engine idle timeout. "
+ "Disabling idle check\n");
+ dev_priv->idle_fault = 1;
+ }
- DRM_DEBUG("free agp, free = 0x%lx\n", agp.free);
+ /*
+ * The caller never sees an error code. It gets trapped
+ * in libdrm.
+ */
return 0;
}
-int sis_init_context(struct drm_device *dev, int context)
-{
- int i;
- for (i = 0; i < MAX_CONTEXT; i++) {
- if (global_ppriv[i].used &&
- (global_ppriv[i].context == context))
- break;
- }
+void sis_lastclose(struct drm_device *dev)
+{
+ drm_sis_private_t *dev_priv = dev->dev_private;
- if (i >= MAX_CONTEXT) {
- for (i = 0; i < MAX_CONTEXT; i++) {
- if (!global_ppriv[i].used) {
- global_ppriv[i].context = context;
- global_ppriv[i].used = 1;
- global_ppriv[i].sets[0] = setInit();
- global_ppriv[i].sets[1] = setInit();
- DRM_DEBUG("init allocation set, socket=%d, "
- "context = %d\n", i, context);
- break;
- }
- }
- if ((i >= MAX_CONTEXT) || (global_ppriv[i].sets[0] == NULL) ||
- (global_ppriv[i].sets[1] == NULL)) {
- return 0;
- }
- }
+ if (!dev_priv)
+ return;
- return 1;
+ mutex_lock(&dev->struct_mutex);
+ drm_sman_cleanup(&dev_priv->sman);
+ dev_priv->vram_initialized = 0;
+ dev_priv->agp_initialized = 0;
+ dev_priv->mmio = NULL;
+ mutex_unlock(&dev->struct_mutex);
}
-int sis_final_context(struct drm_device *dev, int context)
+void sis_reclaim_buffers_locked(drm_device_t * dev, struct file *filp)
{
- int i;
+ drm_sis_private_t *dev_priv = dev->dev_private;
+ drm_file_t *priv = filp->private_data;
- for (i = 0; i < MAX_CONTEXT; i++) {
- if (global_ppriv[i].used &&
- (global_ppriv[i].context == context))
- break;
+ mutex_lock(&dev->struct_mutex);
+ if (drm_sman_owner_clean(&dev_priv->sman, (unsigned long)priv)) {
+ mutex_unlock(&dev->struct_mutex);
+ return;
}
- if (i < MAX_CONTEXT) {
- set_t *set;
- ITEM_TYPE item;
- int retval;
-
- DRM_DEBUG("find socket %d, context = %d\n", i, context);
-
- /* Video Memory */
- set = global_ppriv[i].sets[0];
- retval = setFirst(set, &item);
- while (retval) {
- DRM_DEBUG("free video memory 0x%lx\n", item);
-#if defined(__linux__) && defined(CONFIG_FB_SIS)
- sis_free(item);
-#else
- mmFreeMem((PMemBlock) item);
-#endif
- retval = setNext(set, &item);
- }
- setDestroy(set);
-
- /* AGP Memory */
- set = global_ppriv[i].sets[1];
- retval = setFirst(set, &item);
- while (retval) {
- DRM_DEBUG("free agp memory 0x%lx\n", item);
- mmFreeMem((PMemBlock) item);
- retval = setNext(set, &item);
- }
- setDestroy(set);
-
- global_ppriv[i].used = 0;
+ if (dev->driver->dma_quiescent) {
+ dev->driver->dma_quiescent(dev);
}
- return 1;
+ drm_sman_owner_cleanup(&dev_priv->sman, (unsigned long)priv);
+ mutex_unlock(&dev->struct_mutex);
+ return;
}
drm_ioctl_desc_t sis_ioctls[] = {
[DRM_IOCTL_NR(DRM_SIS_FB_ALLOC)] = {sis_fb_alloc, DRM_AUTH},
- [DRM_IOCTL_NR(DRM_SIS_FB_FREE)] = {sis_fb_free, DRM_AUTH},
- [DRM_IOCTL_NR(DRM_SIS_AGP_INIT)] = {sis_ioctl_agp_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
+ [DRM_IOCTL_NR(DRM_SIS_FB_FREE)] = {sis_drm_free, DRM_AUTH},
+ [DRM_IOCTL_NR(DRM_SIS_AGP_INIT)] =
+ {sis_ioctl_agp_init, DRM_AUTH | DRM_MASTER | DRM_ROOT_ONLY},
[DRM_IOCTL_NR(DRM_SIS_AGP_ALLOC)] = {sis_ioctl_agp_alloc, DRM_AUTH},
- [DRM_IOCTL_NR(DRM_SIS_AGP_FREE)] = {sis_ioctl_agp_free, DRM_AUTH},
- [DRM_IOCTL_NR(DRM_SIS_FB_INIT)] = {sis_fb_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY}
+ [DRM_IOCTL_NR(DRM_SIS_AGP_FREE)] = {sis_drm_free, DRM_AUTH},
+ [DRM_IOCTL_NR(DRM_SIS_FB_INIT)] =
+ {sis_fb_init, DRM_AUTH | DRM_MASTER | DRM_ROOT_ONLY}
};
int sis_max_ioctl = DRM_ARRAY_SIZE(sis_ioctls);
diff --git a/drivers/char/drm/via_dmablit.c b/drivers/char/drm/via_dmablit.c
index 78a81a4a99c5..60c1695db300 100644
--- a/drivers/char/drm/via_dmablit.c
+++ b/drivers/char/drm/via_dmablit.c
@@ -41,9 +41,9 @@
#include <linux/pagemap.h>
-#define VIA_PGDN(x) (((unsigned long)(x)) & PAGE_MASK)
-#define VIA_PGOFF(x) (((unsigned long)(x)) & ~PAGE_MASK)
-#define VIA_PFN(x) ((unsigned long)(x) >> PAGE_SHIFT)
+#define VIA_PGDN(x) (((unsigned long)(x)) & PAGE_MASK)
+#define VIA_PGOFF(x) (((unsigned long)(x)) & ~PAGE_MASK)
+#define VIA_PFN(x) ((unsigned long)(x) >> PAGE_SHIFT)
typedef struct _drm_via_descriptor {
uint32_t mem_addr;
@@ -121,19 +121,19 @@ via_map_blit_for_device(struct pci_dev *pdev,
while (line_len > 0) {
- remaining_len = min(PAGE_SIZE-VIA_PGOFF(cur_mem), line_len);
+ remaining_len = min(PAGE_SIZE-VIA_PGOFF(cur_mem), line_len);
line_len -= remaining_len;
if (mode == 1) {
- desc_ptr->mem_addr =
+ desc_ptr->mem_addr =
dma_map_page(&pdev->dev,
vsg->pages[VIA_PFN(cur_mem) -
VIA_PFN(first_addr)],
VIA_PGOFF(cur_mem), remaining_len,
vsg->direction);
- desc_ptr->dev_addr = cur_fb;
+ desc_ptr->dev_addr = cur_fb;
- desc_ptr->size = remaining_len;
+ desc_ptr->size = remaining_len;
desc_ptr->next = (uint32_t) next;
next = dma_map_single(&pdev->dev, desc_ptr, sizeof(*desc_ptr),
DMA_TO_DEVICE);
@@ -162,7 +162,7 @@ via_map_blit_for_device(struct pci_dev *pdev,
/*
* Function that frees up all resources for a blit. It is usable even if the
- * blit info has only be partially built as long as the status enum is consistent
+ * blit info has only been partially built as long as the status enum is consistent
* with the actual status of the used resources.
*/
@@ -238,8 +238,11 @@ via_lock_all_dma_pages(drm_via_sg_info_t *vsg, drm_via_dmablit_t *xfer)
return DRM_ERR(ENOMEM);
memset(vsg->pages, 0, sizeof(struct page *) * vsg->num_pages);
down_read(&current->mm->mmap_sem);
- ret = get_user_pages(current, current->mm, (unsigned long) xfer->mem_addr,
- vsg->num_pages, vsg->direction, 0, vsg->pages, NULL);
+ ret = get_user_pages(current, current->mm,
+ (unsigned long)xfer->mem_addr,
+ vsg->num_pages,
+ (vsg->direction == DMA_FROM_DEVICE),
+ 0, vsg->pages, NULL);
up_read(&current->mm->mmap_sem);
if (ret != vsg->num_pages) {
@@ -475,9 +478,15 @@ via_dmablit_timer(unsigned long data)
if (!timer_pending(&blitq->poll_timer)) {
blitq->poll_timer.expires = jiffies+1;
add_timer(&blitq->poll_timer);
- }
- via_dmablit_handler(dev, engine, 0);
+ /*
+ * Rerun handler to delete timer if engines are off, and
+ * to shorten abort latency. This is a little nasty.
+ */
+
+ via_dmablit_handler(dev, engine, 0);
+
+ }
}
@@ -597,15 +606,27 @@ via_build_sg_info(drm_device_t *dev, drm_via_sg_info_t *vsg, drm_via_dmablit_t *
* (Not a big limitation anyway.)
*/
- if (((xfer->mem_stride - xfer->line_length) >= PAGE_SIZE) ||
- (xfer->mem_stride > 2048*4)) {
+ if ((xfer->mem_stride - xfer->line_length) >= PAGE_SIZE) {
DRM_ERROR("Too large system memory stride. Stride: %d, "
"Length: %d\n", xfer->mem_stride, xfer->line_length);
return DRM_ERR(EINVAL);
}
- if (xfer->num_lines > 2048) {
- DRM_ERROR("Too many PCI DMA bitblt lines.\n");
+ if ((xfer->mem_stride == xfer->line_length) &&
+ (xfer->fb_stride == xfer->line_length)) {
+ xfer->mem_stride *= xfer->num_lines;
+ xfer->line_length = xfer->mem_stride;
+ xfer->fb_stride = xfer->mem_stride;
+ xfer->num_lines = 1;
+ }
+
+ /*
+ * Don't lock an arbitrary large number of pages, since that causes a
+ * DOS security hole.
+ */
+
+ if (xfer->num_lines > 2048 || (xfer->num_lines*xfer->mem_stride > (2048*2048*4))) {
+ DRM_ERROR("Too large PCI DMA bitblt.\n");
return DRM_ERR(EINVAL);
}
@@ -628,16 +649,17 @@ via_build_sg_info(drm_device_t *dev, drm_via_sg_info_t *vsg, drm_via_dmablit_t *
#ifdef VIA_BUGFREE
if ((((unsigned long)xfer->mem_addr & 3) != ((unsigned long)xfer->fb_addr & 3)) ||
- ((xfer->mem_stride & 3) != (xfer->fb_stride & 3))) {
+ ((xfer->num_lines > 1) && ((xfer->mem_stride & 3) != (xfer->fb_stride & 3)))) {
DRM_ERROR("Invalid DRM bitblt alignment.\n");
- return DRM_ERR(EINVAL);
+ return DRM_ERR(EINVAL);
}
#else
if ((((unsigned long)xfer->mem_addr & 15) ||
- ((unsigned long)xfer->fb_addr & 3)) || (xfer->mem_stride & 15) ||
- (xfer->fb_stride & 3)) {
+ ((unsigned long)xfer->fb_addr & 3)) ||
+ ((xfer->num_lines > 1) &&
+ ((xfer->mem_stride & 15) || (xfer->fb_stride & 3)))) {
DRM_ERROR("Invalid DRM bitblt alignment.\n");
- return DRM_ERR(EINVAL);
+ return DRM_ERR(EINVAL);
}
#endif
@@ -715,7 +737,7 @@ via_dmablit(drm_device_t *dev, drm_via_dmablit_t *xfer)
drm_via_private_t *dev_priv = (drm_via_private_t *)dev->dev_private;
drm_via_sg_info_t *vsg;
drm_via_blitq_t *blitq;
- int ret;
+ int ret;
int engine;
unsigned long irqsave;
@@ -756,7 +778,7 @@ via_dmablit(drm_device_t *dev, drm_via_dmablit_t *xfer)
/*
* Sync on a previously submitted blit. Note that the X server use signals extensively, and
- * that there is a very big proability that this IOCTL will be interrupted by a signal. In that
+ * that there is a very big probability that this IOCTL will be interrupted by a signal. In that
* case it returns with -EAGAIN for the signal to be delivered.
* The caller should then reissue the IOCTL. This is similar to what is being done for drmGetLock().
*/
diff --git a/drivers/char/drm/via_drm.h b/drivers/char/drm/via_drm.h
index 47f0b5b26379..e4ee97d7156f 100644
--- a/drivers/char/drm/via_drm.h
+++ b/drivers/char/drm/via_drm.h
@@ -250,6 +250,12 @@ typedef struct drm_via_blitsync {
unsigned engine;
} drm_via_blitsync_t;
+/* - * Below,"flags" is currently unused but will be used for possible future
+ * extensions like kernel space bounce buffers for bad alignments and
+ * blit engine busy-wait polling for better latency in the absence of
+ * interrupts.
+ */
+
typedef struct drm_via_dmablit {
uint32_t num_lines;
uint32_t line_length;
@@ -260,7 +266,7 @@ typedef struct drm_via_dmablit {
unsigned char *mem_addr;
uint32_t mem_stride;
- int bounce_buffer;
+ uint32_t flags;
int to_fb;
drm_via_blitsync_t sync;
diff --git a/drivers/char/drm/via_drv.c b/drivers/char/drm/via_drv.c
index b3d364d793d7..bb9dde8b1911 100644
--- a/drivers/char/drm/via_drv.c
+++ b/drivers/char/drm/via_drv.c
@@ -43,7 +43,6 @@ static struct drm_driver driver = {
DRIVER_IRQ_SHARED | DRIVER_IRQ_VBL,
.load = via_driver_load,
.unload = via_driver_unload,
- .context_ctor = via_init_context,
.context_dtor = via_final_context,
.vblank_wait = via_driver_vblank_wait,
.irq_preinstall = via_driver_irq_preinstall,
@@ -53,6 +52,8 @@ static struct drm_driver driver = {
.dma_quiescent = via_driver_dma_quiescent,
.dri_library_name = dri_library_name,
.reclaim_buffers = drm_core_reclaim_buffers,
+ .reclaim_buffers_locked = via_reclaim_buffers_locked,
+ .lastclose = via_lastclose,
.get_map_ofs = drm_core_get_map_ofs,
.get_reg_ofs = drm_core_get_reg_ofs,
.ioctls = via_ioctls,
diff --git a/drivers/char/drm/via_drv.h b/drivers/char/drm/via_drv.h
index 52bcc7b1ba45..d21b5b75da0f 100644
--- a/drivers/char/drm/via_drv.h
+++ b/drivers/char/drm/via_drv.h
@@ -24,15 +24,16 @@
#ifndef _VIA_DRV_H_
#define _VIA_DRV_H_
+#include "drm_sman.h"
#define DRIVER_AUTHOR "Various"
#define DRIVER_NAME "via"
#define DRIVER_DESC "VIA Unichrome / Pro"
-#define DRIVER_DATE "20051116"
+#define DRIVER_DATE "20060529"
#define DRIVER_MAJOR 2
-#define DRIVER_MINOR 7
-#define DRIVER_PATCHLEVEL 4
+#define DRIVER_MINOR 10
+#define DRIVER_PATCHLEVEL 0
#include "via_verifier.h"
@@ -85,6 +86,12 @@ typedef struct drm_via_private {
uint32_t irq_enable_mask;
uint32_t irq_pending_mask;
int *irq_map;
+ unsigned int idle_fault;
+ drm_sman_t sman;
+ int vram_initialized;
+ int agp_initialized;
+ unsigned long vram_offset;
+ unsigned long agp_offset;
drm_via_blitq_t blit_queues[VIA_NUM_BLIT_ENGINES];
} drm_via_private_t;
@@ -135,6 +142,9 @@ extern void via_init_futex(drm_via_private_t * dev_priv);
extern void via_cleanup_futex(drm_via_private_t * dev_priv);
extern void via_release_futex(drm_via_private_t * dev_priv, int context);
+extern void via_reclaim_buffers_locked(drm_device_t *dev, struct file *filp);
+extern void via_lastclose(drm_device_t *dev);
+
extern void via_dmablit_handler(drm_device_t *dev, int engine, int from_irq);
extern void via_init_dmablit(drm_device_t *dev);
diff --git a/drivers/char/drm/via_ds.c b/drivers/char/drm/via_ds.c
deleted file mode 100644
index 9429736b3b96..000000000000
--- a/drivers/char/drm/via_ds.c
+++ /dev/null
@@ -1,273 +0,0 @@
-/*
- * Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved.
- * Copyright 2001-2003 S3 Graphics, Inc. All Rights Reserved.
- * Copyright 2000 Silicon Integrated Systems Corp, Inc., HsinChu, Taiwan.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sub license,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial portions
- * of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
- * VIA, S3 GRAPHICS, AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- */
-#include "drmP.h"
-
-#include "via_ds.h"
-extern unsigned int VIA_DEBUG;
-
-set_t *via_setInit(void)
-{
- int i;
- set_t *set;
- set = (set_t *) drm_alloc(sizeof(set_t), DRM_MEM_DRIVER);
- for (i = 0; i < SET_SIZE; i++) {
- set->list[i].free_next = i + 1;
- set->list[i].alloc_next = -1;
- }
- set->list[SET_SIZE - 1].free_next = -1;
- set->free = 0;
- set->alloc = -1;
- set->trace = -1;
- return set;
-}
-
-int via_setAdd(set_t * set, ITEM_TYPE item)
-{
- int free = set->free;
- if (free != -1) {
- set->list[free].val = item;
- set->free = set->list[free].free_next;
- } else {
- return 0;
- }
- set->list[free].alloc_next = set->alloc;
- set->alloc = free;
- set->list[free].free_next = -1;
- return 1;
-}
-
-int via_setDel(set_t * set, ITEM_TYPE item)
-{
- int alloc = set->alloc;
- int prev = -1;
-
- while (alloc != -1) {
- if (set->list[alloc].val == item) {
- if (prev != -1)
- set->list[prev].alloc_next =
- set->list[alloc].alloc_next;
- else
- set->alloc = set->list[alloc].alloc_next;
- break;
- }
- prev = alloc;
- alloc = set->list[alloc].alloc_next;
- }
-
- if (alloc == -1)
- return 0;
-
- set->list[alloc].free_next = set->free;
- set->free = alloc;
- set->list[alloc].alloc_next = -1;
-
- return 1;
-}
-
-/* setFirst -> setAdd -> setNext is wrong */
-
-int via_setFirst(set_t * set, ITEM_TYPE * item)
-{
- if (set->alloc == -1)
- return 0;
-
- *item = set->list[set->alloc].val;
- set->trace = set->list[set->alloc].alloc_next;
-
- return 1;
-}
-
-int via_setNext(set_t * set, ITEM_TYPE * item)
-{
- if (set->trace == -1)
- return 0;
-
- *item = set->list[set->trace].val;
- set->trace = set->list[set->trace].alloc_next;
-
- return 1;
-}
-
-int via_setDestroy(set_t * set)
-{
- drm_free(set, sizeof(set_t), DRM_MEM_DRIVER);
-
- return 1;
-}
-
-#define ISFREE(bptr) ((bptr)->free)
-
-#define fprintf(fmt, arg...) do{}while(0)
-
-memHeap_t *via_mmInit(int ofs, int size)
-{
- PMemBlock blocks;
-
- if (size <= 0)
- return NULL;
-
- blocks = (TMemBlock *) drm_calloc(1, sizeof(TMemBlock), DRM_MEM_DRIVER);
-
- if (blocks) {
- blocks->ofs = ofs;
- blocks->size = size;
- blocks->free = 1;
- return (memHeap_t *) blocks;
- } else
- return NULL;
-}
-
-static TMemBlock *SliceBlock(TMemBlock * p,
- int startofs, int size,
- int reserved, int alignment)
-{
- TMemBlock *newblock;
-
- /* break left */
- if (startofs > p->ofs) {
- newblock =
- (TMemBlock *) drm_calloc(1, sizeof(TMemBlock),
- DRM_MEM_DRIVER);
- newblock->ofs = startofs;
- newblock->size = p->size - (startofs - p->ofs);
- newblock->free = 1;
- newblock->next = p->next;
- p->size -= newblock->size;
- p->next = newblock;
- p = newblock;
- }
-
- /* break right */
- if (size < p->size) {
- newblock =
- (TMemBlock *) drm_calloc(1, sizeof(TMemBlock),
- DRM_MEM_DRIVER);
- newblock->ofs = startofs + size;
- newblock->size = p->size - size;
- newblock->free = 1;
- newblock->next = p->next;
- p->size = size;
- p->next = newblock;
- }
-
- /* p = middle block */
- p->align = alignment;
- p->free = 0;
- p->reserved = reserved;
- return p;
-}
-
-PMemBlock via_mmAllocMem(memHeap_t * heap, int size, int align2,
- int startSearch)
-{
- int mask, startofs, endofs;
- TMemBlock *p;
-
- if (!heap || align2 < 0 || size <= 0)
- return NULL;
-
- mask = (1 << align2) - 1;
- startofs = 0;
- p = (TMemBlock *) heap;
-
- while (p) {
- if (ISFREE(p)) {
- startofs = (p->ofs + mask) & ~mask;
-
- if (startofs < startSearch)
- startofs = startSearch;
-
- endofs = startofs + size;
-
- if (endofs <= (p->ofs + p->size))
- break;
- }
-
- p = p->next;
- }
-
- if (!p)
- return NULL;
-
- p = SliceBlock(p, startofs, size, 0, mask + 1);
- p->heap = heap;
-
- return p;
-}
-
-static __inline__ int Join2Blocks(TMemBlock * p)
-{
- if (p->free && p->next && p->next->free) {
- TMemBlock *q = p->next;
- p->size += q->size;
- p->next = q->next;
- drm_free(q, sizeof(TMemBlock), DRM_MEM_DRIVER);
-
- return 1;
- }
-
- return 0;
-}
-
-int via_mmFreeMem(PMemBlock b)
-{
- TMemBlock *p, *prev;
-
- if (!b)
- return 0;
-
- if (!b->heap) {
- fprintf(stderr, "no heap\n");
-
- return -1;
- }
-
- p = b->heap;
- prev = NULL;
-
- while (p && p != b) {
- prev = p;
- p = p->next;
- }
-
- if (!p || p->free || p->reserved) {
- if (!p)
- fprintf(stderr, "block not found in heap\n");
- else if (p->free)
- fprintf(stderr, "block already free\n");
- else
- fprintf(stderr, "block is reserved\n");
-
- return -1;
- }
-
- p->free = 1;
- Join2Blocks(p);
-
- if (prev)
- Join2Blocks(prev);
-
- return 0;
-}
diff --git a/drivers/char/drm/via_ds.h b/drivers/char/drm/via_ds.h
deleted file mode 100644
index d2bb9f37ca38..000000000000
--- a/drivers/char/drm/via_ds.h
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- * Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved.
- * Copyright 2001-2003 S3 Graphics, Inc. All Rights Reserved.
- * Copyright 2000 Silicon Integrated Systems Corp, Inc., HsinChu, Taiwan.
- * All rights reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sub license,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial portions
- * of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
- * VIA, S3 GRAPHICS, AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- */
-#ifndef _via_ds_h_
-#define _via_ds_h_
-
-#include "drmP.h"
-
-/* Set Data Structure */
-#define SET_SIZE 5000
-typedef unsigned long ITEM_TYPE;
-
-typedef struct {
- ITEM_TYPE val;
- int alloc_next, free_next;
-} list_item_t;
-
-typedef struct {
- int alloc;
- int free;
- int trace;
- list_item_t list[SET_SIZE];
-} set_t;
-
-set_t *via_setInit(void);
-int via_setAdd(set_t * set, ITEM_TYPE item);
-int via_setDel(set_t * set, ITEM_TYPE item);
-int via_setFirst(set_t * set, ITEM_TYPE * item);
-int via_setNext(set_t * set, ITEM_TYPE * item);
-int via_setDestroy(set_t * set);
-
-#endif
-
-#ifndef MM_INC
-#define MM_INC
-
-struct mem_block_t {
- struct mem_block_t *next;
- struct mem_block_t *heap;
- int ofs, size;
- int align;
- unsigned int free:1;
- unsigned int reserved:1;
-};
-typedef struct mem_block_t TMemBlock;
-typedef struct mem_block_t *PMemBlock;
-
-/* a heap is just the first block in a chain */
-typedef struct mem_block_t memHeap_t;
-
-static __inline__ int mmBlockSize(PMemBlock b)
-{
- return b->size;
-}
-
-static __inline__ int mmOffset(PMemBlock b)
-{
- return b->ofs;
-}
-
-static __inline__ void mmMarkReserved(PMemBlock b)
-{
- b->reserved = 1;
-}
-
-/*
- * input: total size in bytes
- * return: a heap pointer if OK, NULL if error
- */
-memHeap_t *via_mmInit(int ofs, int size);
-
-PMemBlock via_mmAllocMem(memHeap_t * heap, int size, int align2,
- int startSearch);
-
-/*
- * Free block starts at offset
- * input: pointer to a block
- * return: 0 if OK, -1 if error
- */
-int via_mmFreeMem(PMemBlock b);
-
-#endif
diff --git a/drivers/char/drm/via_map.c b/drivers/char/drm/via_map.c
index c6a08e96285b..782011e0a58d 100644
--- a/drivers/char/drm/via_map.c
+++ b/drivers/char/drm/via_map.c
@@ -98,6 +98,7 @@ int via_map_init(DRM_IOCTL_ARGS)
int via_driver_load(drm_device_t *dev, unsigned long chipset)
{
drm_via_private_t *dev_priv;
+ int ret = 0;
dev_priv = drm_calloc(1, sizeof(drm_via_private_t), DRM_MEM_DRIVER);
if (dev_priv == NULL)
@@ -108,13 +109,19 @@ int via_driver_load(drm_device_t *dev, unsigned long chipset)
if (chipset == VIA_PRO_GROUP_A)
dev_priv->pro_group_a = 1;
- return 0;
+ ret = drm_sman_init(&dev_priv->sman, 2, 12, 8);
+ if (ret) {
+ drm_free(dev_priv, sizeof(*dev_priv), DRM_MEM_DRIVER);
+ }
+ return ret;
}
int via_driver_unload(drm_device_t *dev)
{
drm_via_private_t *dev_priv = dev->dev_private;
+ drm_sman_takedown(&dev_priv->sman);
+
drm_free(dev_priv, sizeof(drm_via_private_t), DRM_MEM_DRIVER);
return 0;
diff --git a/drivers/char/drm/via_mm.c b/drivers/char/drm/via_mm.c
index 33e0cb12e4c3..2fcf0577a7aa 100644
--- a/drivers/char/drm/via_mm.c
+++ b/drivers/char/drm/via_mm.c
@@ -1,6 +1,6 @@
/*
- * Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved.
- * Copyright 2001-2003 S3 Graphics, Inc. All Rights Reserved.
+ * Copyright 2006 Tungsten Graphics Inc., Bismarck, ND., USA.
+ * All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
@@ -16,347 +16,194 @@
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
- * VIA, S3 GRAPHICS, AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * THE AUTHORS OR COPYRIGHT HOLDERS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
+/*
+ * Authors: Thomas Hellström <thomas-at-tungstengraphics-dot-com>
+ */
+
#include "drmP.h"
#include "via_drm.h"
#include "via_drv.h"
-#include "via_ds.h"
-#include "via_mm.h"
-
-#define MAX_CONTEXT 100
-
-typedef struct {
- int used;
- int context;
- set_t *sets[2]; /* 0 for frame buffer, 1 for AGP , 2 for System */
-} via_context_t;
-
-static via_context_t global_ppriv[MAX_CONTEXT];
+#include "drm_sman.h"
-static int via_agp_alloc(drm_via_mem_t * mem);
-static int via_agp_free(drm_via_mem_t * mem);
-static int via_fb_alloc(drm_via_mem_t * mem);
-static int via_fb_free(drm_via_mem_t * mem);
-
-static int add_alloc_set(int context, int type, unsigned long val)
-{
- int i, retval = 0;
-
- for (i = 0; i < MAX_CONTEXT; i++) {
- if (global_ppriv[i].used && global_ppriv[i].context == context) {
- retval = via_setAdd(global_ppriv[i].sets[type], val);
- break;
- }
- }
-
- return retval;
-}
-
-static int del_alloc_set(int context, int type, unsigned long val)
-{
- int i, retval = 0;
-
- for (i = 0; i < MAX_CONTEXT; i++)
- if (global_ppriv[i].used && global_ppriv[i].context == context) {
- retval = via_setDel(global_ppriv[i].sets[type], val);
- break;
- }
-
- return retval;
-}
-
-/* agp memory management */
-static memHeap_t *AgpHeap = NULL;
+#define VIA_MM_ALIGN_SHIFT 4
+#define VIA_MM_ALIGN_MASK ( (1 << VIA_MM_ALIGN_SHIFT) - 1)
int via_agp_init(DRM_IOCTL_ARGS)
{
+ DRM_DEVICE;
drm_via_agp_t agp;
+ drm_via_private_t *dev_priv = (drm_via_private_t *) dev->dev_private;
+ int ret;
DRM_COPY_FROM_USER_IOCTL(agp, (drm_via_agp_t __user *) data,
sizeof(agp));
+ mutex_lock(&dev->struct_mutex);
+ ret = drm_sman_set_range(&dev_priv->sman, VIA_MEM_AGP, 0,
+ agp.size >> VIA_MM_ALIGN_SHIFT);
+
+ if (ret) {
+ DRM_ERROR("AGP memory manager initialisation error\n");
+ mutex_unlock(&dev->struct_mutex);
+ return ret;
+ }
- AgpHeap = via_mmInit(agp.offset, agp.size);
-
- DRM_DEBUG("offset = %lu, size = %lu", (unsigned long)agp.offset,
- (unsigned long)agp.size);
+ dev_priv->agp_initialized = 1;
+ dev_priv->agp_offset = agp.offset;
+ mutex_unlock(&dev->struct_mutex);
+ DRM_DEBUG("offset = %u, size = %u", agp.offset, agp.size);
return 0;
}
-/* fb memory management */
-static memHeap_t *FBHeap = NULL;
-
int via_fb_init(DRM_IOCTL_ARGS)
{
+ DRM_DEVICE;
drm_via_fb_t fb;
+ drm_via_private_t *dev_priv = (drm_via_private_t *) dev->dev_private;
+ int ret;
DRM_COPY_FROM_USER_IOCTL(fb, (drm_via_fb_t __user *) data, sizeof(fb));
- FBHeap = via_mmInit(fb.offset, fb.size);
+ mutex_lock(&dev->struct_mutex);
+ ret = drm_sman_set_range(&dev_priv->sman, VIA_MEM_VIDEO, 0,
+ fb.size >> VIA_MM_ALIGN_SHIFT);
- DRM_DEBUG("offset = %lu, size = %lu", (unsigned long)fb.offset,
- (unsigned long)fb.size);
+ if (ret) {
+ DRM_ERROR("VRAM memory manager initialisation error\n");
+ mutex_unlock(&dev->struct_mutex);
+ return ret;
+ }
- return 0;
-}
+ dev_priv->vram_initialized = 1;
+ dev_priv->vram_offset = fb.offset;
-int via_init_context(struct drm_device *dev, int context)
-{
- int i;
-
- for (i = 0; i < MAX_CONTEXT; i++)
- if (global_ppriv[i].used &&
- (global_ppriv[i].context == context))
- break;
-
- if (i >= MAX_CONTEXT) {
- for (i = 0; i < MAX_CONTEXT; i++) {
- if (!global_ppriv[i].used) {
- global_ppriv[i].context = context;
- global_ppriv[i].used = 1;
- global_ppriv[i].sets[0] = via_setInit();
- global_ppriv[i].sets[1] = via_setInit();
- DRM_DEBUG("init allocation set, socket=%d,"
- " context = %d\n", i, context);
- break;
- }
- }
-
- if ((i >= MAX_CONTEXT) || (global_ppriv[i].sets[0] == NULL) ||
- (global_ppriv[i].sets[1] == NULL)) {
- return 0;
- }
- }
+ mutex_unlock(&dev->struct_mutex);
+ DRM_DEBUG("offset = %u, size = %u", fb.offset, fb.size);
+
+ return 0;
- return 1;
}
int via_final_context(struct drm_device *dev, int context)
{
- int i;
drm_via_private_t *dev_priv = (drm_via_private_t *) dev->dev_private;
- for (i = 0; i < MAX_CONTEXT; i++)
- if (global_ppriv[i].used &&
- (global_ppriv[i].context == context))
- break;
-
- if (i < MAX_CONTEXT) {
- set_t *set;
- ITEM_TYPE item;
- int retval;
-
- DRM_DEBUG("find socket %d, context = %d\n", i, context);
-
- /* Video Memory */
- set = global_ppriv[i].sets[0];
- retval = via_setFirst(set, &item);
- while (retval) {
- DRM_DEBUG("free video memory 0x%lx\n", item);
- via_mmFreeMem((PMemBlock) item);
- retval = via_setNext(set, &item);
- }
- via_setDestroy(set);
-
- /* AGP Memory */
- set = global_ppriv[i].sets[1];
- retval = via_setFirst(set, &item);
- while (retval) {
- DRM_DEBUG("free agp memory 0x%lx\n", item);
- via_mmFreeMem((PMemBlock) item);
- retval = via_setNext(set, &item);
- }
- via_setDestroy(set);
- global_ppriv[i].used = 0;
- }
via_release_futex(dev_priv, context);
-#if defined(__linux__)
/* Linux specific until context tracking code gets ported to BSD */
/* Last context, perform cleanup */
if (dev->ctx_count == 1 && dev->dev_private) {
DRM_DEBUG("Last Context\n");
if (dev->irq)
drm_irq_uninstall(dev);
-
via_cleanup_futex(dev_priv);
via_do_cleanup_map(dev);
}
-#endif
-
return 1;
}
+void via_lastclose(struct drm_device *dev)
+{
+ drm_via_private_t *dev_priv = (drm_via_private_t *) dev->dev_private;
+
+ if (!dev_priv)
+ return;
+
+ mutex_lock(&dev->struct_mutex);
+ drm_sman_cleanup(&dev_priv->sman);
+ dev_priv->vram_initialized = 0;
+ dev_priv->agp_initialized = 0;
+ mutex_unlock(&dev->struct_mutex);
+}
+
int via_mem_alloc(DRM_IOCTL_ARGS)
{
+ DRM_DEVICE;
+
drm_via_mem_t mem;
+ int retval = 0;
+ drm_memblock_item_t *item;
+ drm_via_private_t *dev_priv = (drm_via_private_t *) dev->dev_private;
+ unsigned long tmpSize;
DRM_COPY_FROM_USER_IOCTL(mem, (drm_via_mem_t __user *) data,
sizeof(mem));
- switch (mem.type) {
- case VIA_MEM_VIDEO:
- if (via_fb_alloc(&mem) < 0)
- return -EFAULT;
- DRM_COPY_TO_USER_IOCTL((drm_via_mem_t __user *) data, mem,
- sizeof(mem));
- return 0;
- case VIA_MEM_AGP:
- if (via_agp_alloc(&mem) < 0)
- return -EFAULT;
- DRM_COPY_TO_USER_IOCTL((drm_via_mem_t __user *) data, mem,
- sizeof(mem));
- return 0;
+ if (mem.type > VIA_MEM_AGP) {
+ DRM_ERROR("Unknown memory type allocation\n");
+ return DRM_ERR(EINVAL);
}
-
- return -EFAULT;
-}
-
-static int via_fb_alloc(drm_via_mem_t * mem)
-{
- drm_via_mm_t fb;
- PMemBlock block;
- int retval = 0;
-
- if (!FBHeap)
- return -1;
-
- fb.size = mem->size;
- fb.context = mem->context;
-
- block = via_mmAllocMem(FBHeap, fb.size, 5, 0);
- if (block) {
- fb.offset = block->ofs;
- fb.free = (unsigned long)block;
- if (!add_alloc_set(fb.context, VIA_MEM_VIDEO, fb.free)) {
- DRM_DEBUG("adding to allocation set fails\n");
- via_mmFreeMem((PMemBlock) fb.free);
- retval = -1;
- }
- } else {
- fb.offset = 0;
- fb.size = 0;
- fb.free = 0;
- retval = -1;
+ mutex_lock(&dev->struct_mutex);
+ if (0 == ((mem.type == VIA_MEM_VIDEO) ? dev_priv->vram_initialized :
+ dev_priv->agp_initialized)) {
+ DRM_ERROR
+ ("Attempt to allocate from uninitialized memory manager.\n");
+ mutex_unlock(&dev->struct_mutex);
+ return DRM_ERR(EINVAL);
}
- mem->offset = fb.offset;
- mem->index = fb.free;
-
- DRM_DEBUG("alloc fb, size = %d, offset = %d\n", fb.size,
- (int)fb.offset);
-
- return retval;
-}
-
-static int via_agp_alloc(drm_via_mem_t * mem)
-{
- drm_via_mm_t agp;
- PMemBlock block;
- int retval = 0;
-
- if (!AgpHeap)
- return -1;
-
- agp.size = mem->size;
- agp.context = mem->context;
-
- block = via_mmAllocMem(AgpHeap, agp.size, 5, 0);
- if (block) {
- agp.offset = block->ofs;
- agp.free = (unsigned long)block;
- if (!add_alloc_set(agp.context, VIA_MEM_AGP, agp.free)) {
- DRM_DEBUG("adding to allocation set fails\n");
- via_mmFreeMem((PMemBlock) agp.free);
- retval = -1;
- }
+ tmpSize = (mem.size + VIA_MM_ALIGN_MASK) >> VIA_MM_ALIGN_SHIFT;
+ item = drm_sman_alloc(&dev_priv->sman, mem.type, tmpSize, 0,
+ (unsigned long)priv);
+ mutex_unlock(&dev->struct_mutex);
+ if (item) {
+ mem.offset = ((mem.type == VIA_MEM_VIDEO) ?
+ dev_priv->vram_offset : dev_priv->agp_offset) +
+ (item->mm->
+ offset(item->mm, item->mm_info) << VIA_MM_ALIGN_SHIFT);
+ mem.index = item->user_hash.key;
} else {
- agp.offset = 0;
- agp.size = 0;
- agp.free = 0;
+ mem.offset = 0;
+ mem.size = 0;
+ mem.index = 0;
+ DRM_DEBUG("Video memory allocation failed\n");
+ retval = DRM_ERR(ENOMEM);
}
+ DRM_COPY_TO_USER_IOCTL((drm_via_mem_t __user *) data, mem, sizeof(mem));
- mem->offset = agp.offset;
- mem->index = agp.free;
-
- DRM_DEBUG("alloc agp, size = %d, offset = %d\n", agp.size,
- (unsigned int)agp.offset);
return retval;
}
int via_mem_free(DRM_IOCTL_ARGS)
{
+ DRM_DEVICE;
+ drm_via_private_t *dev_priv = dev->dev_private;
drm_via_mem_t mem;
+ int ret;
DRM_COPY_FROM_USER_IOCTL(mem, (drm_via_mem_t __user *) data,
sizeof(mem));
- switch (mem.type) {
+ mutex_lock(&dev->struct_mutex);
+ ret = drm_sman_free_key(&dev_priv->sman, mem.index);
+ mutex_unlock(&dev->struct_mutex);
+ DRM_DEBUG("free = 0x%lx\n", mem.index);
- case VIA_MEM_VIDEO:
- if (via_fb_free(&mem) == 0)
- return 0;
- break;
- case VIA_MEM_AGP:
- if (via_agp_free(&mem) == 0)
- return 0;
- break;
- }
-
- return -EFAULT;
+ return ret;
}
-static int via_fb_free(drm_via_mem_t * mem)
-{
- drm_via_mm_t fb;
- int retval = 0;
-
- if (!FBHeap) {
- return -1;
- }
-
- fb.free = mem->index;
- fb.context = mem->context;
-
- if (!fb.free) {
- return -1;
-
- }
-
- via_mmFreeMem((PMemBlock) fb.free);
-
- if (!del_alloc_set(fb.context, VIA_MEM_VIDEO, fb.free)) {
- retval = -1;
- }
-
- DRM_DEBUG("free fb, free = %ld\n", fb.free);
- return retval;
-}
-
-static int via_agp_free(drm_via_mem_t * mem)
+void via_reclaim_buffers_locked(drm_device_t * dev, struct file *filp)
{
- drm_via_mm_t agp;
-
- int retval = 0;
+ drm_via_private_t *dev_priv = dev->dev_private;
+ drm_file_t *priv = filp->private_data;
- agp.free = mem->index;
- agp.context = mem->context;
-
- if (!agp.free)
- return -1;
-
- via_mmFreeMem((PMemBlock) agp.free);
-
- if (!del_alloc_set(agp.context, VIA_MEM_AGP, agp.free)) {
- retval = -1;
+ mutex_lock(&dev->struct_mutex);
+ if (drm_sman_owner_clean(&dev_priv->sman, (unsigned long)priv)) {
+ mutex_unlock(&dev->struct_mutex);
+ return;
}
- DRM_DEBUG("free agp, free = %ld\n", agp.free);
+ if (dev->driver->dma_quiescent) {
+ dev->driver->dma_quiescent(dev);
+ }
- return retval;
+ drm_sman_owner_cleanup(&dev_priv->sman, (unsigned long)priv);
+ mutex_unlock(&dev->struct_mutex);
+ return;
}
diff --git a/drivers/char/ds1286.c b/drivers/char/ds1286.c
index 21c8229f5443..6d58b0370802 100644
--- a/drivers/char/ds1286.c
+++ b/drivers/char/ds1286.c
@@ -104,7 +104,7 @@ static int ds1286_ioctl(struct inode *inode, struct file *file,
switch (cmd) {
case RTC_AIE_OFF: /* Mask alarm int. enab. bit */
{
- unsigned int flags;
+ unsigned long flags;
unsigned char val;
if (!capable(CAP_SYS_TIME))
@@ -120,7 +120,7 @@ static int ds1286_ioctl(struct inode *inode, struct file *file,
}
case RTC_AIE_ON: /* Allow alarm interrupts. */
{
- unsigned int flags;
+ unsigned long flags;
unsigned char val;
if (!capable(CAP_SYS_TIME))
@@ -136,7 +136,7 @@ static int ds1286_ioctl(struct inode *inode, struct file *file,
}
case RTC_WIE_OFF: /* Mask watchdog int. enab. bit */
{
- unsigned int flags;
+ unsigned long flags;
unsigned char val;
if (!capable(CAP_SYS_TIME))
@@ -152,7 +152,7 @@ static int ds1286_ioctl(struct inode *inode, struct file *file,
}
case RTC_WIE_ON: /* Allow watchdog interrupts. */
{
- unsigned int flags;
+ unsigned long flags;
unsigned char val;
if (!capable(CAP_SYS_TIME))
@@ -434,7 +434,7 @@ static inline unsigned char ds1286_is_updating(void)
static void ds1286_get_time(struct rtc_time *rtc_tm)
{
unsigned char save_control;
- unsigned int flags;
+ unsigned long flags;
unsigned long uip_watchdog = jiffies;
/*
@@ -494,7 +494,8 @@ static int ds1286_set_time(struct rtc_time *rtc_tm)
{
unsigned char mon, day, hrs, min, sec, leap_yr;
unsigned char save_control;
- unsigned int yrs, flags;
+ unsigned int yrs;
+ unsigned long flags;
yrs = rtc_tm->tm_year + 1900;
@@ -552,7 +553,7 @@ static int ds1286_set_time(struct rtc_time *rtc_tm)
static void ds1286_get_alm_time(struct rtc_time *alm_tm)
{
unsigned char cmd;
- unsigned int flags;
+ unsigned long flags;
/*
* Only the values that we read from the RTC are set. That
diff --git a/drivers/char/epca.c b/drivers/char/epca.c
index 86d290e9f307..3baa2ab8cbd4 100644
--- a/drivers/char/epca.c
+++ b/drivers/char/epca.c
@@ -1125,7 +1125,7 @@ static void __exit epca_module_exit(void)
module_exit(epca_module_exit);
-static struct tty_operations pc_ops = {
+static const struct tty_operations pc_ops = {
.open = pc_open,
.close = pc_close,
.write = pc_write,
diff --git a/drivers/char/esp.c b/drivers/char/esp.c
index afcd83d9984b..05788c75d7fc 100644
--- a/drivers/char/esp.c
+++ b/drivers/char/esp.c
@@ -2376,7 +2376,7 @@ static inline int autoconfig(struct esp_struct * info)
return (port_detected);
}
-static struct tty_operations esp_ops = {
+static const struct tty_operations esp_ops = {
.open = esp_open,
.close = rs_close,
.write = rs_write,
diff --git a/drivers/char/generic_serial.c b/drivers/char/generic_serial.c
index 5e59c0b42731..4711d9b3a595 100644
--- a/drivers/char/generic_serial.c
+++ b/drivers/char/generic_serial.c
@@ -746,11 +746,9 @@ void gs_set_termios (struct tty_struct * tty,
gs_dprintk (GS_DEBUG_TERMIOS, "termios structure (%p):\n", tiosp);
}
-#if 0
/* This is an optimization that is only allowed for dumb cards */
/* Smart cards require knowledge of iflags and oflags too: that
might change hardware cooking mode.... */
-#endif
if (old_termios) {
if( (tiosp->c_iflag == old_termios->c_iflag)
&& (tiosp->c_oflag == old_termios->c_oflag)
@@ -774,14 +772,7 @@ void gs_set_termios (struct tty_struct * tty,
if(!memcmp(tiosp->c_cc, old_termios->c_cc, NCC)) printk("c_cc changed\n");
}
- baudrate = tiosp->c_cflag & CBAUD;
- if (baudrate & CBAUDEX) {
- baudrate &= ~CBAUDEX;
- if ((baudrate < 1) || (baudrate > 4))
- tiosp->c_cflag &= ~CBAUDEX;
- else
- baudrate += 15;
- }
+ baudrate = tty_get_baud_rate(tty);
baudrate = gs_baudrates[baudrate];
if ((tiosp->c_cflag & CBAUD) == B38400) {
diff --git a/drivers/char/hvc_console.c b/drivers/char/hvc_console.c
index a76d2c40dd5e..4053d1cd393f 100644
--- a/drivers/char/hvc_console.c
+++ b/drivers/char/hvc_console.c
@@ -696,7 +696,7 @@ int khvcd(void *unused)
return 0;
}
-static struct tty_operations hvc_ops = {
+static const struct tty_operations hvc_ops = {
.open = hvc_open,
.close = hvc_close,
.write = hvc_write,
diff --git a/drivers/char/hvc_iseries.c b/drivers/char/hvc_iseries.c
index 4747729459c7..8b6f197e5f8c 100644
--- a/drivers/char/hvc_iseries.c
+++ b/drivers/char/hvc_iseries.c
@@ -153,9 +153,7 @@ static int put_chars(uint32_t vtermno, const char *buf, int count)
spin_lock_irqsave(&consolelock, flags);
if (viochar_is_console(pi) && !viopath_isactive(pi->lp)) {
- spin_lock_irqsave(&consoleloglock, flags);
HvCall_writeLogBuffer(buf, count);
- spin_unlock_irqrestore(&consoleloglock, flags);
sent = count;
goto done;
}
@@ -171,11 +169,8 @@ static int put_chars(uint32_t vtermno, const char *buf, int count)
len = (count > VIOCHAR_MAX_DATA) ? VIOCHAR_MAX_DATA : count;
- if (viochar_is_console(pi)) {
- spin_lock_irqsave(&consoleloglock, flags);
+ if (viochar_is_console(pi))
HvCall_writeLogBuffer(buf, len);
- spin_unlock_irqrestore(&consoleloglock, flags);
- }
init_data_event(viochar, pi->lp);
diff --git a/drivers/char/hvcs.c b/drivers/char/hvcs.c
index 4589ff302b07..0b89bcde8c52 100644
--- a/drivers/char/hvcs.c
+++ b/drivers/char/hvcs.c
@@ -1306,7 +1306,7 @@ static int hvcs_chars_in_buffer(struct tty_struct *tty)
return hvcsd->chars_in_buffer;
}
-static struct tty_operations hvcs_ops = {
+static const struct tty_operations hvcs_ops = {
.open = hvcs_open,
.close = hvcs_close,
.hangup = hvcs_hangup,
diff --git a/drivers/char/hvsi.c b/drivers/char/hvsi.c
index a89a95fb5e40..c07dc58d5c1d 100644
--- a/drivers/char/hvsi.c
+++ b/drivers/char/hvsi.c
@@ -1130,7 +1130,7 @@ static int hvsi_tiocmset(struct tty_struct *tty, struct file *file,
}
-static struct tty_operations hvsi_ops = {
+static const struct tty_operations hvsi_ops = {
.open = hvsi_open,
.close = hvsi_close,
.write = hvsi_write,
diff --git a/drivers/char/hw_random/intel-rng.c b/drivers/char/hw_random/intel-rng.c
index ccd7e7102234..8efbc9c0e545 100644
--- a/drivers/char/hw_random/intel-rng.c
+++ b/drivers/char/hw_random/intel-rng.c
@@ -50,6 +50,43 @@
#define INTEL_RNG_ADDR_LEN 3
/*
+ * LPC bridge PCI config space registers
+ */
+#define FWH_DEC_EN1_REG_OLD 0xe3
+#define FWH_DEC_EN1_REG_NEW 0xd9 /* high byte of 16-bit register */
+#define FWH_F8_EN_MASK 0x80
+
+#define BIOS_CNTL_REG_OLD 0x4e
+#define BIOS_CNTL_REG_NEW 0xdc
+#define BIOS_CNTL_WRITE_ENABLE_MASK 0x01
+#define BIOS_CNTL_LOCK_ENABLE_MASK 0x02
+
+/*
+ * Magic address at which Intel Firmware Hubs get accessed
+ */
+#define INTEL_FWH_ADDR 0xffff0000
+#define INTEL_FWH_ADDR_LEN 2
+
+/*
+ * Intel Firmware Hub command codes (write to any address inside the device)
+ */
+#define INTEL_FWH_RESET_CMD 0xff /* aka READ_ARRAY */
+#define INTEL_FWH_READ_ID_CMD 0x90
+
+/*
+ * Intel Firmware Hub Read ID command result addresses
+ */
+#define INTEL_FWH_MANUFACTURER_CODE_ADDRESS 0x000000
+#define INTEL_FWH_DEVICE_CODE_ADDRESS 0x000001
+
+/*
+ * Intel Firmware Hub Read ID command result values
+ */
+#define INTEL_FWH_MANUFACTURER_CODE 0x89
+#define INTEL_FWH_DEVICE_CODE_8M 0xac
+#define INTEL_FWH_DEVICE_CODE_4M 0xad
+
+/*
* Data for PCI driver interface
*
* This data only exists for exporting the supported
@@ -58,12 +95,50 @@
* want to register another driver on the same PCI id.
*/
static const struct pci_device_id pci_tbl[] = {
- { 0x8086, 0x2418, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, },
- { 0x8086, 0x2428, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, },
- { 0x8086, 0x2430, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, },
- { 0x8086, 0x2448, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, },
- { 0x8086, 0x244e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, },
- { 0x8086, 0x245e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, },
+/* AA
+ { 0x8086, 0x2418, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, */
+ { 0x8086, 0x2410, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* AA */
+/* AB
+ { 0x8086, 0x2428, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, */
+ { 0x8086, 0x2420, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* AB */
+/* ??
+ { 0x8086, 0x2430, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, */
+/* BAM, CAM, DBM, FBM, GxM
+ { 0x8086, 0x2448, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, */
+ { 0x8086, 0x244c, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* BAM */
+ { 0x8086, 0x248c, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* CAM */
+ { 0x8086, 0x24cc, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* DBM */
+ { 0x8086, 0x2641, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* FBM */
+ { 0x8086, 0x27b9, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* GxM */
+ { 0x8086, 0x27bd, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* GxM DH */
+/* BA, CA, DB, Ex, 6300, Fx, 631x/632x, Gx
+ { 0x8086, 0x244e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, */
+ { 0x8086, 0x2440, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* BA */
+ { 0x8086, 0x2480, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* CA */
+ { 0x8086, 0x24c0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* DB */
+ { 0x8086, 0x24d0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* Ex */
+ { 0x8086, 0x25a1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* 6300 */
+ { 0x8086, 0x2640, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* Fx */
+ { 0x8086, 0x2670, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* 631x/632x */
+ { 0x8086, 0x2671, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* 631x/632x */
+ { 0x8086, 0x2672, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* 631x/632x */
+ { 0x8086, 0x2673, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* 631x/632x */
+ { 0x8086, 0x2674, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* 631x/632x */
+ { 0x8086, 0x2675, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* 631x/632x */
+ { 0x8086, 0x2676, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* 631x/632x */
+ { 0x8086, 0x2677, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* 631x/632x */
+ { 0x8086, 0x2678, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* 631x/632x */
+ { 0x8086, 0x2679, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* 631x/632x */
+ { 0x8086, 0x267a, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* 631x/632x */
+ { 0x8086, 0x267b, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* 631x/632x */
+ { 0x8086, 0x267c, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* 631x/632x */
+ { 0x8086, 0x267d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* 631x/632x */
+ { 0x8086, 0x267e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* 631x/632x */
+ { 0x8086, 0x267f, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* 631x/632x */
+ { 0x8086, 0x27b8, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* Gx */
+/* E
+ { 0x8086, 0x245e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, */
+ { 0x8086, 0x2450, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* E */
{ 0, }, /* terminate list */
};
MODULE_DEVICE_TABLE(pci, pci_tbl);
@@ -138,22 +213,115 @@ static struct hwrng intel_rng = {
};
+#ifdef CONFIG_SMP
+static char __initdata waitflag;
+
+static void __init intel_init_wait(void *unused)
+{
+ while (waitflag)
+ cpu_relax();
+}
+#endif
+
static int __init mod_init(void)
{
int err = -ENODEV;
+ unsigned i;
+ struct pci_dev *dev = NULL;
void __iomem *mem;
- u8 hw_status;
+ unsigned long flags;
+ u8 bios_cntl_off, fwh_dec_en1_off;
+ u8 bios_cntl_val = 0xff, fwh_dec_en1_val = 0xff;
+ u8 hw_status, mfc, dvc;
- if (!pci_dev_present(pci_tbl))
+ for (i = 0; !dev && pci_tbl[i].vendor; ++i)
+ dev = pci_get_device(pci_tbl[i].vendor, pci_tbl[i].device, NULL);
+
+ if (!dev)
goto out; /* Device not found. */
+ /* Check for Intel 82802 */
+ if (dev->device < 0x2640) {
+ fwh_dec_en1_off = FWH_DEC_EN1_REG_OLD;
+ bios_cntl_off = BIOS_CNTL_REG_OLD;
+ } else {
+ fwh_dec_en1_off = FWH_DEC_EN1_REG_NEW;
+ bios_cntl_off = BIOS_CNTL_REG_NEW;
+ }
+
+ pci_read_config_byte(dev, fwh_dec_en1_off, &fwh_dec_en1_val);
+ pci_read_config_byte(dev, bios_cntl_off, &bios_cntl_val);
+
+ mem = ioremap_nocache(INTEL_FWH_ADDR, INTEL_FWH_ADDR_LEN);
+ if (mem == NULL) {
+ pci_dev_put(dev);
+ err = -EBUSY;
+ goto out;
+ }
+
+ /*
+ * Since the BIOS code/data is going to disappear from its normal
+ * location with the Read ID command, all activity on the system
+ * must be stopped until the state is back to normal.
+ */
+#ifdef CONFIG_SMP
+ set_mb(waitflag, 1);
+ if (smp_call_function(intel_init_wait, NULL, 1, 0) != 0) {
+ set_mb(waitflag, 0);
+ pci_dev_put(dev);
+ printk(KERN_ERR PFX "cannot run on all processors\n");
+ err = -EAGAIN;
+ goto err_unmap;
+ }
+#endif
+ local_irq_save(flags);
+
+ if (!(fwh_dec_en1_val & FWH_F8_EN_MASK))
+ pci_write_config_byte(dev,
+ fwh_dec_en1_off,
+ fwh_dec_en1_val | FWH_F8_EN_MASK);
+ if (!(bios_cntl_val &
+ (BIOS_CNTL_LOCK_ENABLE_MASK|BIOS_CNTL_WRITE_ENABLE_MASK)))
+ pci_write_config_byte(dev,
+ bios_cntl_off,
+ bios_cntl_val | BIOS_CNTL_WRITE_ENABLE_MASK);
+
+ writeb(INTEL_FWH_RESET_CMD, mem);
+ writeb(INTEL_FWH_READ_ID_CMD, mem);
+ mfc = readb(mem + INTEL_FWH_MANUFACTURER_CODE_ADDRESS);
+ dvc = readb(mem + INTEL_FWH_DEVICE_CODE_ADDRESS);
+ writeb(INTEL_FWH_RESET_CMD, mem);
+
+ if (!(bios_cntl_val &
+ (BIOS_CNTL_LOCK_ENABLE_MASK|BIOS_CNTL_WRITE_ENABLE_MASK)))
+ pci_write_config_byte(dev, bios_cntl_off, bios_cntl_val);
+ if (!(fwh_dec_en1_val & FWH_F8_EN_MASK))
+ pci_write_config_byte(dev, fwh_dec_en1_off, fwh_dec_en1_val);
+
+ local_irq_restore(flags);
+#ifdef CONFIG_SMP
+ /* Tell other CPUs to resume. */
+ set_mb(waitflag, 0);
+#endif
+
+ iounmap(mem);
+ pci_dev_put(dev);
+
+ if (mfc != INTEL_FWH_MANUFACTURER_CODE ||
+ (dvc != INTEL_FWH_DEVICE_CODE_8M &&
+ dvc != INTEL_FWH_DEVICE_CODE_4M)) {
+ printk(KERN_ERR PFX "FWH not detected\n");
+ err = -ENODEV;
+ goto out;
+ }
+
err = -ENOMEM;
mem = ioremap(INTEL_RNG_ADDR, INTEL_RNG_ADDR_LEN);
if (!mem)
goto out;
intel_rng.priv = (unsigned long)mem;
- /* Check for Intel 82802 */
+ /* Check for Random Number Generator */
err = -ENODEV;
hw_status = hwstatus_get(mem);
if ((hw_status & INTEL_RNG_PRESENT) == 0)
diff --git a/drivers/char/ip2/ip2main.c b/drivers/char/ip2/ip2main.c
index 7907ae88c2f4..62ef511d143b 100644
--- a/drivers/char/ip2/ip2main.c
+++ b/drivers/char/ip2/ip2main.c
@@ -436,6 +436,7 @@ cleanup_module(void)
#ifdef CONFIG_PCI
if (ip2config.type[i] == PCI && ip2config.pci_dev[i]) {
pci_disable_device(ip2config.pci_dev[i]);
+ pci_dev_put(ip2config.pci_dev[i]);
ip2config.pci_dev[i] = NULL;
}
#endif
@@ -457,7 +458,7 @@ cleanup_module(void)
}
#endif /* MODULE */
-static struct tty_operations ip2_ops = {
+static const struct tty_operations ip2_ops = {
.open = ip2_open,
.close = ip2_close,
.write = ip2_write,
@@ -505,6 +506,7 @@ ip2_loadmain(int *iop, int *irqp, unsigned char *firmware, int firmsize)
static int loaded;
i2eBordStrPtr pB = NULL;
int rc = -1;
+ static struct pci_dev *pci_dev_i = NULL;
ip2trace (ITRC_NO_PORT, ITRC_INIT, ITRC_ENTER, 0 );
@@ -588,8 +590,7 @@ ip2_loadmain(int *iop, int *irqp, unsigned char *firmware, int firmsize)
case PCI:
#ifdef CONFIG_PCI
{
- struct pci_dev *pci_dev_i = NULL;
- pci_dev_i = pci_find_device(PCI_VENDOR_ID_COMPUTONE,
+ pci_dev_i = pci_get_device(PCI_VENDOR_ID_COMPUTONE,
PCI_DEVICE_ID_COMPUTONE_IP2EX, pci_dev_i);
if (pci_dev_i != NULL) {
unsigned int addr;
@@ -600,7 +601,7 @@ ip2_loadmain(int *iop, int *irqp, unsigned char *firmware, int firmsize)
break;
}
ip2config.type[i] = PCI;
- ip2config.pci_dev[i] = pci_dev_i;
+ ip2config.pci_dev[i] = pci_dev_get(pci_dev_i);
status =
pci_read_config_dword(pci_dev_i, PCI_BASE_ADDRESS_1, &addr);
if ( addr & 1 ) {
@@ -641,6 +642,9 @@ ip2_loadmain(int *iop, int *irqp, unsigned char *firmware, int firmsize)
break;
} /* switch */
} /* for */
+ if (pci_dev_i)
+ pci_dev_put(pci_dev_i);
+
for ( i = 0; i < IP2_MAX_BOARDS; ++i ) {
if ( ip2config.addr[i] ) {
pB = kmalloc( sizeof(i2eBordStr), GFP_KERNEL);
@@ -775,8 +779,6 @@ retry:
ip2trace (ITRC_NO_PORT, ITRC_INIT, ITRC_RETURN, 0 );
goto out;
-out_class:
- class_destroy(ip2_class);
out_chrdev:
unregister_chrdev(IP2_IPL_MAJOR, "ip2");
out:
diff --git a/drivers/char/ipmi/ipmi_devintf.c b/drivers/char/ipmi/ipmi_devintf.c
index 68d7c61a864e..81fcf0ce21d1 100644
--- a/drivers/char/ipmi/ipmi_devintf.c
+++ b/drivers/char/ipmi/ipmi_devintf.c
@@ -377,7 +377,8 @@ static int ipmi_ioctl(struct inode *inode,
break;
}
- rv = ipmi_register_for_cmd(priv->user, val.netfn, val.cmd);
+ rv = ipmi_register_for_cmd(priv->user, val.netfn, val.cmd,
+ IPMI_CHAN_ALL);
break;
}
@@ -390,7 +391,36 @@ static int ipmi_ioctl(struct inode *inode,
break;
}
- rv = ipmi_unregister_for_cmd(priv->user, val.netfn, val.cmd);
+ rv = ipmi_unregister_for_cmd(priv->user, val.netfn, val.cmd,
+ IPMI_CHAN_ALL);
+ break;
+ }
+
+ case IPMICTL_REGISTER_FOR_CMD_CHANS:
+ {
+ struct ipmi_cmdspec_chans val;
+
+ if (copy_from_user(&val, arg, sizeof(val))) {
+ rv = -EFAULT;
+ break;
+ }
+
+ rv = ipmi_register_for_cmd(priv->user, val.netfn, val.cmd,
+ val.chans);
+ break;
+ }
+
+ case IPMICTL_UNREGISTER_FOR_CMD_CHANS:
+ {
+ struct ipmi_cmdspec_chans val;
+
+ if (copy_from_user(&val, arg, sizeof(val))) {
+ rv = -EFAULT;
+ break;
+ }
+
+ rv = ipmi_unregister_for_cmd(priv->user, val.netfn, val.cmd,
+ val.chans);
break;
}
diff --git a/drivers/char/ipmi/ipmi_msghandler.c b/drivers/char/ipmi/ipmi_msghandler.c
index 843d34c8627c..2455e8d478ac 100644
--- a/drivers/char/ipmi/ipmi_msghandler.c
+++ b/drivers/char/ipmi/ipmi_msghandler.c
@@ -96,6 +96,7 @@ struct cmd_rcvr
ipmi_user_t user;
unsigned char netfn;
unsigned char cmd;
+ unsigned int chans;
/*
* This is used to form a linked lised during mass deletion.
@@ -953,24 +954,41 @@ int ipmi_set_gets_events(ipmi_user_t user, int val)
static struct cmd_rcvr *find_cmd_rcvr(ipmi_smi_t intf,
unsigned char netfn,
- unsigned char cmd)
+ unsigned char cmd,
+ unsigned char chan)
{
struct cmd_rcvr *rcvr;
list_for_each_entry_rcu(rcvr, &intf->cmd_rcvrs, link) {
- if ((rcvr->netfn == netfn) && (rcvr->cmd == cmd))
+ if ((rcvr->netfn == netfn) && (rcvr->cmd == cmd)
+ && (rcvr->chans & (1 << chan)))
return rcvr;
}
return NULL;
}
+static int is_cmd_rcvr_exclusive(ipmi_smi_t intf,
+ unsigned char netfn,
+ unsigned char cmd,
+ unsigned int chans)
+{
+ struct cmd_rcvr *rcvr;
+
+ list_for_each_entry_rcu(rcvr, &intf->cmd_rcvrs, link) {
+ if ((rcvr->netfn == netfn) && (rcvr->cmd == cmd)
+ && (rcvr->chans & chans))
+ return 0;
+ }
+ return 1;
+}
+
int ipmi_register_for_cmd(ipmi_user_t user,
unsigned char netfn,
- unsigned char cmd)
+ unsigned char cmd,
+ unsigned int chans)
{
ipmi_smi_t intf = user->intf;
struct cmd_rcvr *rcvr;
- struct cmd_rcvr *entry;
int rv = 0;
@@ -979,12 +997,12 @@ int ipmi_register_for_cmd(ipmi_user_t user,
return -ENOMEM;
rcvr->cmd = cmd;
rcvr->netfn = netfn;
+ rcvr->chans = chans;
rcvr->user = user;
mutex_lock(&intf->cmd_rcvrs_mutex);
/* Make sure the command/netfn is not already registered. */
- entry = find_cmd_rcvr(intf, netfn, cmd);
- if (entry) {
+ if (!is_cmd_rcvr_exclusive(intf, netfn, cmd, chans)) {
rv = -EBUSY;
goto out_unlock;
}
@@ -1001,24 +1019,39 @@ int ipmi_register_for_cmd(ipmi_user_t user,
int ipmi_unregister_for_cmd(ipmi_user_t user,
unsigned char netfn,
- unsigned char cmd)
+ unsigned char cmd,
+ unsigned int chans)
{
ipmi_smi_t intf = user->intf;
struct cmd_rcvr *rcvr;
+ struct cmd_rcvr *rcvrs = NULL;
+ int i, rv = -ENOENT;
mutex_lock(&intf->cmd_rcvrs_mutex);
- /* Make sure the command/netfn is not already registered. */
- rcvr = find_cmd_rcvr(intf, netfn, cmd);
- if ((rcvr) && (rcvr->user == user)) {
- list_del_rcu(&rcvr->link);
- mutex_unlock(&intf->cmd_rcvrs_mutex);
- synchronize_rcu();
+ for (i = 0; i < IPMI_NUM_CHANNELS; i++) {
+ if (((1 << i) & chans) == 0)
+ continue;
+ rcvr = find_cmd_rcvr(intf, netfn, cmd, i);
+ if (rcvr == NULL)
+ continue;
+ if (rcvr->user == user) {
+ rv = 0;
+ rcvr->chans &= ~chans;
+ if (rcvr->chans == 0) {
+ list_del_rcu(&rcvr->link);
+ rcvr->next = rcvrs;
+ rcvrs = rcvr;
+ }
+ }
+ }
+ mutex_unlock(&intf->cmd_rcvrs_mutex);
+ synchronize_rcu();
+ while (rcvrs) {
+ rcvr = rcvrs;
+ rcvrs = rcvr->next;
kfree(rcvr);
- return 0;
- } else {
- mutex_unlock(&intf->cmd_rcvrs_mutex);
- return -ENOENT;
}
+ return rv;
}
void ipmi_user_set_run_to_completion(ipmi_user_t user, int val)
@@ -2548,6 +2581,7 @@ static int handle_ipmb_get_msg_cmd(ipmi_smi_t intf,
int rv = 0;
unsigned char netfn;
unsigned char cmd;
+ unsigned char chan;
ipmi_user_t user = NULL;
struct ipmi_ipmb_addr *ipmb_addr;
struct ipmi_recv_msg *recv_msg;
@@ -2568,9 +2602,10 @@ static int handle_ipmb_get_msg_cmd(ipmi_smi_t intf,
netfn = msg->rsp[4] >> 2;
cmd = msg->rsp[8];
+ chan = msg->rsp[3] & 0xf;
rcu_read_lock();
- rcvr = find_cmd_rcvr(intf, netfn, cmd);
+ rcvr = find_cmd_rcvr(intf, netfn, cmd, chan);
if (rcvr) {
user = rcvr->user;
kref_get(&user->refcount);
@@ -2728,6 +2763,7 @@ static int handle_lan_get_msg_cmd(ipmi_smi_t intf,
int rv = 0;
unsigned char netfn;
unsigned char cmd;
+ unsigned char chan;
ipmi_user_t user = NULL;
struct ipmi_lan_addr *lan_addr;
struct ipmi_recv_msg *recv_msg;
@@ -2748,9 +2784,10 @@ static int handle_lan_get_msg_cmd(ipmi_smi_t intf,
netfn = msg->rsp[6] >> 2;
cmd = msg->rsp[10];
+ chan = msg->rsp[3] & 0xf;
rcu_read_lock();
- rcvr = find_cmd_rcvr(intf, netfn, cmd);
+ rcvr = find_cmd_rcvr(intf, netfn, cmd, chan);
if (rcvr) {
user = rcvr->user;
kref_get(&user->refcount);
diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c
index abca98beac14..b106c45abfc9 100644
--- a/drivers/char/ipmi/ipmi_si_intf.c
+++ b/drivers/char/ipmi/ipmi_si_intf.c
@@ -217,6 +217,11 @@ struct smi_info
struct list_head link;
};
+#define SI_MAX_PARMS 4
+
+static int force_kipmid[SI_MAX_PARMS];
+static int num_force_kipmid;
+
static int try_smi_init(struct smi_info *smi);
static ATOMIC_NOTIFIER_HEAD(xaction_notifier_list);
@@ -908,6 +913,7 @@ static int smi_start_processing(void *send_info,
ipmi_smi_t intf)
{
struct smi_info *new_smi = send_info;
+ int enable = 0;
new_smi->intf = intf;
@@ -916,7 +922,19 @@ static int smi_start_processing(void *send_info,
new_smi->last_timeout_jiffies = jiffies;
mod_timer(&new_smi->si_timer, jiffies + SI_TIMEOUT_JIFFIES);
- if (new_smi->si_type != SI_BT) {
+ /*
+ * Check if the user forcefully enabled the daemon.
+ */
+ if (new_smi->intf_num < num_force_kipmid)
+ enable = force_kipmid[new_smi->intf_num];
+ /*
+ * The BT interface is efficient enough to not need a thread,
+ * and there is no need for a thread if we have interrupts.
+ */
+ else if ((new_smi->si_type != SI_BT) && (!new_smi->irq))
+ enable = 1;
+
+ if (enable) {
new_smi->thread = kthread_run(ipmi_thread, new_smi,
"kipmi%d", new_smi->intf_num);
if (IS_ERR(new_smi->thread)) {
@@ -944,7 +962,6 @@ static struct ipmi_smi_handlers handlers =
/* There can be 4 IO ports passed in (with or without IRQs), 4 addresses,
a default IO port, and 1 ACPI/SPMI address. That sets SI_MAX_DRIVERS */
-#define SI_MAX_PARMS 4
static LIST_HEAD(smi_infos);
static DEFINE_MUTEX(smi_infos_lock);
static int smi_num; /* Used to sequence the SMIs */
@@ -1017,6 +1034,10 @@ MODULE_PARM_DESC(slave_addrs, "Set the default IPMB slave address for"
" the controller. Normally this is 0x20, but can be"
" overridden by this parm. This is an array indexed"
" by interface number.");
+module_param_array(force_kipmid, int, &num_force_kipmid, 0);
+MODULE_PARM_DESC(force_kipmid, "Force the kipmi daemon to be enabled (1) or"
+ " disabled(0). Normally the IPMI driver auto-detects"
+ " this, but the value may be overridden by this parm.");
#define IPMI_IO_ADDR_SPACE 0
@@ -1730,6 +1751,7 @@ static void __devinit dmi_find_bmc(void)
int rv;
while ((dev = dmi_find_device(DMI_DEV_TYPE_IPMI, NULL, dev))) {
+ memset(&data, 0, sizeof(data));
rv = decode_dmi((struct dmi_header *) dev->device_data, &data);
if (!rv)
try_init_dmi(&data);
diff --git a/drivers/char/isicom.c b/drivers/char/isicom.c
index 913be23e0a24..ea2bbf80ad33 100644
--- a/drivers/char/isicom.c
+++ b/drivers/char/isicom.c
@@ -1550,7 +1550,7 @@ static void isicom_unregister_ioregion(struct pci_dev *pdev)
board->base = 0;
}
-static struct tty_operations isicom_ops = {
+static const struct tty_operations isicom_ops = {
.open = isicom_open,
.close = isicom_close,
.write = isicom_write,
@@ -1756,9 +1756,12 @@ static int __devinit load_firmware(struct pci_dev *pdev,
if (retval)
goto end;
+ retval = -EIO;
+
for (frame = (struct stframe *)fw->data;
frame < (struct stframe *)(fw->data + fw->size);
- frame++) {
+ frame = (struct stframe *)((u8 *)(frame + 1) +
+ frame->count)) {
if (WaitTillCardIsFree(base))
goto errrelfw;
@@ -1797,23 +1800,12 @@ static int __devinit load_firmware(struct pci_dev *pdev,
}
}
- retval = -EIO;
-
- if (WaitTillCardIsFree(base))
- goto errrelfw;
-
- outw(0xf2, base);
- outw(0x800, base);
- outw(0x0, base);
- outw(0x0, base);
- InterruptTheCard(base);
- outw(0x0, base + 0x4); /* for ISI4608 cards */
-
/* XXX: should we test it by reading it back and comparing with original like
* in load firmware package? */
- for (frame = (struct stframe*)fw->data;
- frame < (struct stframe*)(fw->data + fw->size);
- frame++) {
+ for (frame = (struct stframe *)fw->data;
+ frame < (struct stframe *)(fw->data + fw->size);
+ frame = (struct stframe *)((u8 *)(frame + 1) +
+ frame->count)) {
if (WaitTillCardIsFree(base))
goto errrelfw;
@@ -1863,6 +1855,17 @@ static int __devinit load_firmware(struct pci_dev *pdev,
}
}
+ /* xfer ctrl */
+ if (WaitTillCardIsFree(base))
+ goto errrelfw;
+
+ outw(0xf2, base);
+ outw(0x800, base);
+ outw(0x0, base);
+ outw(0x0, base);
+ InterruptTheCard(base);
+ outw(0x0, base + 0x4); /* for ISI4608 cards */
+
board->status |= FIRMWARE_LOADED;
retval = 0;
diff --git a/drivers/char/istallion.c b/drivers/char/istallion.c
index 8c09997cc3d6..d6e031542c6b 100644
--- a/drivers/char/istallion.c
+++ b/drivers/char/istallion.c
@@ -612,16 +612,6 @@ MODULE_DEVICE_TABLE(pci, istallion_pci_tbl);
#define MINOR2BRD(min) (((min) & 0xc0) >> 6)
#define MINOR2PORT(min) ((min) & 0x3f)
-/*
- * Define a baud rate table that converts termios baud rate selector
- * into the actual baud rate value. All baud rate calculations are based
- * on the actual baud rate required.
- */
-static unsigned int stli_baudrates[] = {
- 0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800,
- 9600, 19200, 38400, 57600, 115200, 230400, 460800, 921600
-};
-
/*****************************************************************************/
/*
@@ -2747,15 +2737,7 @@ static void stli_mkasyport(stliport_t *portp, asyport_t *pp, struct termios *tio
/*
* Start of by setting the baud, char size, parity and stop bit info.
*/
- pp->baudout = tiosp->c_cflag & CBAUD;
- if (pp->baudout & CBAUDEX) {
- pp->baudout &= ~CBAUDEX;
- if ((pp->baudout < 1) || (pp->baudout > 4))
- tiosp->c_cflag &= ~CBAUDEX;
- else
- pp->baudout += 15;
- }
- pp->baudout = stli_baudrates[pp->baudout];
+ pp->baudout = tty_get_baud_rate(portp->tty);
if ((tiosp->c_cflag & CBAUD) == B38400) {
if ((portp->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI)
pp->baudout = 57600;
@@ -4654,7 +4636,7 @@ static int stli_memioctl(struct inode *ip, struct file *fp, unsigned int cmd, un
return rc;
}
-static struct tty_operations stli_ops = {
+static const struct tty_operations stli_ops = {
.open = stli_open,
.close = stli_close,
.write = stli_write,
diff --git a/drivers/char/keyboard.c b/drivers/char/keyboard.c
index 3e90aac37510..e2011669c7bb 100644
--- a/drivers/char/keyboard.c
+++ b/drivers/char/keyboard.c
@@ -108,7 +108,11 @@ const int NR_TYPES = ARRAY_SIZE(max_vals);
struct kbd_struct kbd_table[MAX_NR_CONSOLES];
static struct kbd_struct *kbd = kbd_table;
-int spawnpid, spawnsig;
+struct vt_spawn_console vt_spawn_con = {
+ .lock = SPIN_LOCK_UNLOCKED,
+ .pid = NULL,
+ .sig = 0,
+};
/*
* Variables exported for vt.c
@@ -578,9 +582,13 @@ static void fn_compose(struct vc_data *vc, struct pt_regs *regs)
static void fn_spawn_con(struct vc_data *vc, struct pt_regs *regs)
{
- if (spawnpid)
- if (kill_proc(spawnpid, spawnsig, 1))
- spawnpid = 0;
+ spin_lock(&vt_spawn_con.lock);
+ if (vt_spawn_con.pid)
+ if (kill_pid(vt_spawn_con.pid, vt_spawn_con.sig, 1)) {
+ put_pid(vt_spawn_con.pid);
+ vt_spawn_con.pid = NULL;
+ }
+ spin_unlock(&vt_spawn_con.lock);
}
static void fn_SAK(struct vc_data *vc, struct pt_regs *regs)
@@ -1285,7 +1293,7 @@ static void kbd_event(struct input_handle *handle, unsigned int event_type,
*/
static struct input_handle *kbd_connect(struct input_handler *handler,
struct input_dev *dev,
- struct input_device_id *id)
+ const struct input_device_id *id)
{
struct input_handle *handle;
int i;
@@ -1334,7 +1342,7 @@ static void kbd_start(struct input_handle *handle)
tasklet_enable(&keyboard_tasklet);
}
-static struct input_device_id kbd_ids[] = {
+static const struct input_device_id kbd_ids[] = {
{
.flags = INPUT_DEVICE_ID_MATCH_EVBIT,
.evbit = { BIT(EV_KEY) },
@@ -1362,6 +1370,7 @@ static struct input_handler kbd_handler = {
int __init kbd_init(void)
{
int i;
+ int error;
for (i = 0; i < MAX_NR_CONSOLES; i++) {
kbd_table[i].ledflagstate = KBD_DEFLEDS;
@@ -1373,7 +1382,9 @@ int __init kbd_init(void)
kbd_table[i].kbdmode = VC_XLATE;
}
- input_register_handler(&kbd_handler);
+ error = input_register_handler(&kbd_handler);
+ if (error)
+ return error;
tasklet_enable(&keyboard_tasklet);
tasklet_schedule(&keyboard_tasklet);
diff --git a/drivers/char/lp.c b/drivers/char/lp.c
index f875fda3b089..1ecea7d448f1 100644
--- a/drivers/char/lp.c
+++ b/drivers/char/lp.c
@@ -906,7 +906,7 @@ static int __init lp_init (void)
lp_class = class_create(THIS_MODULE, "printer");
if (IS_ERR(lp_class)) {
err = PTR_ERR(lp_class);
- goto out_devfs;
+ goto out_reg;
}
if (parport_register_driver (&lp_driver)) {
@@ -927,7 +927,7 @@ static int __init lp_init (void)
out_class:
class_destroy(lp_class);
-out_devfs:
+out_reg:
unregister_chrdev(LP_MAJOR, "lp");
return err;
}
diff --git a/drivers/char/mbcs.c b/drivers/char/mbcs.c
index 0385650f6077..636354722658 100644
--- a/drivers/char/mbcs.c
+++ b/drivers/char/mbcs.c
@@ -22,6 +22,7 @@
#include <linux/delay.h>
#include <linux/device.h>
#include <linux/mm.h>
+#include <linux/fs.h>
#include <linux/uio.h>
#include <asm/io.h>
#include <asm/uaccess.h>
@@ -447,15 +448,15 @@ loff_t mbcs_sram_llseek(struct file * filp, loff_t off, int whence)
loff_t newpos;
switch (whence) {
- case 0: /* SEEK_SET */
+ case SEEK_SET:
newpos = off;
break;
- case 1: /* SEEK_CUR */
+ case SEEK_CUR:
newpos = filp->f_pos + off;
break;
- case 2: /* SEEK_END */
+ case SEEK_END:
newpos = MBCS_SRAM_SIZE + off;
break;
diff --git a/drivers/char/mem.c b/drivers/char/mem.c
index 4ac70ec697f0..6511012cbdcd 100644
--- a/drivers/char/mem.c
+++ b/drivers/char/mem.c
@@ -551,7 +551,7 @@ static ssize_t write_kmem(struct file * file, const char __user * buf,
return virtr + wrote;
}
-#if defined(CONFIG_ISA) || !defined(__mc68000__)
+#if (defined(CONFIG_ISA) || defined(CONFIG_PCI)) && !defined(__mc68000__)
static ssize_t read_port(struct file * file, char __user * buf,
size_t count, loff_t *ppos)
{
@@ -830,7 +830,7 @@ static const struct file_operations null_fops = {
.splice_write = splice_write_null,
};
-#if defined(CONFIG_ISA) || !defined(__mc68000__)
+#if (defined(CONFIG_ISA) || defined(CONFIG_PCI)) && !defined(__mc68000__)
static const struct file_operations port_fops = {
.llseek = memory_lseek,
.read = read_port,
@@ -908,7 +908,7 @@ static int memory_open(struct inode * inode, struct file * filp)
case 3:
filp->f_op = &null_fops;
break;
-#if defined(CONFIG_ISA) || !defined(__mc68000__)
+#if (defined(CONFIG_ISA) || defined(CONFIG_PCI)) && !defined(__mc68000__)
case 4:
filp->f_op = &port_fops;
break;
@@ -955,7 +955,7 @@ static const struct {
{1, "mem", S_IRUSR | S_IWUSR | S_IRGRP, &mem_fops},
{2, "kmem", S_IRUSR | S_IWUSR | S_IRGRP, &kmem_fops},
{3, "null", S_IRUGO | S_IWUGO, &null_fops},
-#if defined(CONFIG_ISA) || !defined(__mc68000__)
+#if (defined(CONFIG_ISA) || defined(CONFIG_PCI)) && !defined(__mc68000__)
{4, "port", S_IRUSR | S_IWUSR | S_IRGRP, &port_fops},
#endif
{5, "zero", S_IRUGO | S_IWUGO, &zero_fops},
diff --git a/drivers/char/moxa.c b/drivers/char/moxa.c
index a369dd6877d8..b401383808c2 100644
--- a/drivers/char/moxa.c
+++ b/drivers/char/moxa.c
@@ -260,7 +260,7 @@ static void MoxaPortEnable(int);
static void MoxaPortDisable(int);
static long MoxaPortGetMaxBaud(int);
static long MoxaPortSetBaud(int, long);
-static int MoxaPortSetTermio(int, struct termios *);
+static int MoxaPortSetTermio(int, struct termios *, speed_t);
static int MoxaPortGetLineOut(int, int *, int *);
static void MoxaPortLineCtrl(int, int, int);
static void MoxaPortFlowCtrl(int, int, int, int, int, int);
@@ -281,7 +281,7 @@ static int moxa_get_serial_info(struct moxa_str *, struct serial_struct __user *
static int moxa_set_serial_info(struct moxa_str *, struct serial_struct __user *);
static void MoxaSetFifo(int port, int enable);
-static struct tty_operations moxa_ops = {
+static const struct tty_operations moxa_ops = {
.open = moxa_open,
.close = moxa_close,
.write = moxa_write,
@@ -986,7 +986,7 @@ static void set_tty_param(struct tty_struct *tty)
if (ts->c_iflag & IXANY)
xany = 1;
MoxaPortFlowCtrl(ch->port, rts, cts, txflow, rxflow, xany);
- MoxaPortSetTermio(ch->port, ts);
+ MoxaPortSetTermio(ch->port, ts, tty_get_baud_rate(tty));
}
static int block_till_ready(struct tty_struct *tty, struct file *filp,
@@ -1900,9 +1900,10 @@ int MoxaPortsOfCard(int cardno)
*
* Function 12: Configure the port.
* Syntax:
- * int MoxaPortSetTermio(int port, struct termios *termio);
+ * int MoxaPortSetTermio(int port, struct termios *termio, speed_t baud);
* int port : port number (0 - 127)
* struct termios * termio : termio structure pointer
+ * speed_t baud : baud rate
*
* return: -1 : this port is invalid or termio == NULL
* 0 : setting O.K.
@@ -2182,11 +2183,10 @@ long MoxaPortSetBaud(int port, long baud)
return (baud);
}
-int MoxaPortSetTermio(int port, struct termios *termio)
+int MoxaPortSetTermio(int port, struct termios *termio, speed_t baud)
{
void __iomem *ofsAddr;
tcflag_t cflag;
- long baud;
tcflag_t mode = 0;
if (moxaChkPort[port] == 0 || termio == 0)
@@ -2222,77 +2222,9 @@ int MoxaPortSetTermio(int port, struct termios *termio)
moxafunc(ofsAddr, FC_SetDataMode, (ushort) mode);
- cflag &= (CBAUD | CBAUDEX);
-#ifndef B921600
-#define B921600 (B460800+1)
-#endif
- switch (cflag) {
- case B921600:
- baud = 921600L;
- break;
- case B460800:
- baud = 460800L;
- break;
- case B230400:
- baud = 230400L;
- break;
- case B115200:
- baud = 115200L;
- break;
- case B57600:
- baud = 57600L;
- break;
- case B38400:
- baud = 38400L;
- break;
- case B19200:
- baud = 19200L;
- break;
- case B9600:
- baud = 9600L;
- break;
- case B4800:
- baud = 4800L;
- break;
- case B2400:
- baud = 2400L;
- break;
- case B1800:
- baud = 1800L;
- break;
- case B1200:
- baud = 1200L;
- break;
- case B600:
- baud = 600L;
- break;
- case B300:
- baud = 300L;
- break;
- case B200:
- baud = 200L;
- break;
- case B150:
- baud = 150L;
- break;
- case B134:
- baud = 134L;
- break;
- case B110:
- baud = 110L;
- break;
- case B75:
- baud = 75L;
- break;
- case B50:
- baud = 50L;
- break;
- default:
- baud = 0;
- }
if ((moxa_boards[port / MAX_PORTS_PER_BOARD].boardType == MOXA_BOARD_C320_ISA) ||
(moxa_boards[port / MAX_PORTS_PER_BOARD].boardType == MOXA_BOARD_C320_PCI)) {
- if (baud == 921600L)
+ if (baud >= 921600L)
return (-1);
}
MoxaPortSetBaud(port, baud);
diff --git a/drivers/char/mwave/mwavedd.c b/drivers/char/mwave/mwavedd.c
index 39a2e661ff55..8d14823b0514 100644
--- a/drivers/char/mwave/mwavedd.c
+++ b/drivers/char/mwave/mwavedd.c
@@ -297,7 +297,7 @@ static int mwave_ioctl(struct inode *inode, struct file *file,
" ipcnum %x, usIntCount %x\n",
ipcnum,
pDrvData->IPCs[ipcnum].usIntCount);
- if (ipcnum > ARRAY_SIZE(pDrvData->IPCs)) {
+ if (ipcnum >= ARRAY_SIZE(pDrvData->IPCs)) {
PRINTK_ERROR(KERN_ERR_MWAVE
"mwavedd::mwave_ioctl:"
" IOCTL_MW_GET_IPC: Error:"
@@ -355,7 +355,7 @@ static int mwave_ioctl(struct inode *inode, struct file *file,
"mwavedd::mwave_ioctl IOCTL_MW_UNREGISTER_IPC"
" ipcnum %x\n",
ipcnum);
- if (ipcnum > ARRAY_SIZE(pDrvData->IPCs)) {
+ if (ipcnum >= ARRAY_SIZE(pDrvData->IPCs)) {
PRINTK_ERROR(KERN_ERR_MWAVE
"mwavedd::mwave_ioctl:"
" IOCTL_MW_UNREGISTER_IPC:"
diff --git a/drivers/char/mxser.c b/drivers/char/mxser.c
index 556abd3e0d07..8253fca8efd5 100644
--- a/drivers/char/mxser.c
+++ b/drivers/char/mxser.c
@@ -453,7 +453,7 @@ static int CheckIsMoxaMust(int io)
/* above is modified by Victor Yu. 08-15-2002 */
-static struct tty_operations mxser_ops = {
+static const struct tty_operations mxser_ops = {
.open = mxser_open,
.close = mxser_close,
.write = mxser_write,
@@ -2554,71 +2554,7 @@ static int mxser_change_speed(struct mxser_struct *info, struct termios *old_ter
#define B921600 (B460800 +1)
#endif
if (mxser_set_baud_method[info->port] == 0) {
- switch (cflag & (CBAUD | CBAUDEX)) {
- case B921600:
- baud = 921600;
- break;
- case B460800:
- baud = 460800;
- break;
- case B230400:
- baud = 230400;
- break;
- case B115200:
- baud = 115200;
- break;
- case B57600:
- baud = 57600;
- break;
- case B38400:
- baud = 38400;
- break;
- case B19200:
- baud = 19200;
- break;
- case B9600:
- baud = 9600;
- break;
- case B4800:
- baud = 4800;
- break;
- case B2400:
- baud = 2400;
- break;
- case B1800:
- baud = 1800;
- break;
- case B1200:
- baud = 1200;
- break;
- case B600:
- baud = 600;
- break;
- case B300:
- baud = 300;
- break;
- case B200:
- baud = 200;
- break;
- case B150:
- baud = 150;
- break;
- case B134:
- baud = 134;
- break;
- case B110:
- baud = 110;
- break;
- case B75:
- baud = 75;
- break;
- case B50:
- baud = 50;
- break;
- default:
- baud = 0;
- break;
- }
+ baud = tty_get_baud_rate(info->tty);
mxser_set_baud(info, baud);
}
diff --git a/drivers/char/nwbutton.c b/drivers/char/nwbutton.c
index 7c57ebfa8640..ea1aa7764f8e 100644
--- a/drivers/char/nwbutton.c
+++ b/drivers/char/nwbutton.c
@@ -127,9 +127,8 @@ static void button_consume_callbacks (int bpcount)
static void button_sequence_finished (unsigned long parameters)
{
#ifdef CONFIG_NWBUTTON_REBOOT /* Reboot using button is enabled */
- if (button_press_count == reboot_count) {
- kill_proc (1, SIGINT, 1); /* Ask init to reboot us */
- }
+ if (button_press_count == reboot_count)
+ kill_cad_pid(SIGINT, 1); /* Ask init to reboot us */
#endif /* CONFIG_NWBUTTON_REBOOT */
button_consume_callbacks (button_press_count);
bcount = sprintf (button_output_buffer, "%d\n", button_press_count);
diff --git a/drivers/char/pc8736x_gpio.c b/drivers/char/pc8736x_gpio.c
index 84e5a68635f1..ecfaf180e5bd 100644
--- a/drivers/char/pc8736x_gpio.c
+++ b/drivers/char/pc8736x_gpio.c
@@ -188,16 +188,6 @@ static void pc8736x_gpio_set(unsigned minor, int val)
pc8736x_gpio_shadow[port] = val;
}
-static void pc8736x_gpio_set_high(unsigned index)
-{
- pc8736x_gpio_set(index, 1);
-}
-
-static void pc8736x_gpio_set_low(unsigned index)
-{
- pc8736x_gpio_set(index, 0);
-}
-
static int pc8736x_gpio_current(unsigned minor)
{
int port, bit;
diff --git a/drivers/char/pcmcia/synclink_cs.c b/drivers/char/pcmcia/synclink_cs.c
index 00f574cbb0d4..d1ecb2c6de98 100644
--- a/drivers/char/pcmcia/synclink_cs.c
+++ b/drivers/char/pcmcia/synclink_cs.c
@@ -57,7 +57,6 @@
#include <linux/netdevice.h>
#include <linux/vmalloc.h>
#include <linux/init.h>
-#include <asm/serial.h>
#include <linux/delay.h>
#include <linux/ioctl.h>
@@ -3010,7 +3009,7 @@ static struct pcmcia_driver mgslpc_driver = {
.resume = mgslpc_resume,
};
-static struct tty_operations mgslpc_ops = {
+static const struct tty_operations mgslpc_ops = {
.open = mgslpc_open,
.close = mgslpc_close,
.write = mgslpc_write,
diff --git a/drivers/char/pty.c b/drivers/char/pty.c
index 34dd4c38110e..80d3eedd7f96 100644
--- a/drivers/char/pty.c
+++ b/drivers/char/pty.c
@@ -224,7 +224,7 @@ static void pty_set_termios(struct tty_struct *tty, struct termios *old_termios)
tty->termios->c_cflag |= (CS8 | CREAD);
}
-static struct tty_operations pty_ops = {
+static const struct tty_operations pty_ops = {
.open = pty_open,
.close = pty_close,
.write = pty_write,
diff --git a/drivers/char/random.c b/drivers/char/random.c
index 4c3a5ca9d8f7..07f47a0208a7 100644
--- a/drivers/char/random.c
+++ b/drivers/char/random.c
@@ -655,6 +655,7 @@ void add_interrupt_randomness(int irq)
add_timer_randomness(irq_timer_state[irq], 0x100 + irq);
}
+#ifdef CONFIG_BLOCK
void add_disk_randomness(struct gendisk *disk)
{
if (!disk || !disk->random)
@@ -667,6 +668,7 @@ void add_disk_randomness(struct gendisk *disk)
}
EXPORT_SYMBOL(add_disk_randomness);
+#endif
#define EXTRACT_SIZE 10
@@ -887,8 +889,8 @@ static void init_std_data(struct entropy_store *r)
do_gettimeofday(&tv);
add_entropy_words(r, (__u32 *)&tv, sizeof(tv)/4);
- add_entropy_words(r, (__u32 *)&system_utsname,
- sizeof(system_utsname)/4);
+ add_entropy_words(r, (__u32 *)utsname(),
+ sizeof(*(utsname()))/4);
}
static int __init rand_initialize(void)
@@ -918,6 +920,7 @@ void rand_initialize_irq(int irq)
}
}
+#ifdef CONFIG_BLOCK
void rand_initialize_disk(struct gendisk *disk)
{
struct timer_rand_state *state;
@@ -932,6 +935,7 @@ void rand_initialize_disk(struct gendisk *disk)
disk->random = state;
}
}
+#endif
static ssize_t
random_read(struct file * file, char __user * buf, size_t nbytes, loff_t *ppos)
diff --git a/drivers/char/raw.c b/drivers/char/raw.c
index 579868af4a54..89b718e326e5 100644
--- a/drivers/char/raw.c
+++ b/drivers/char/raw.c
@@ -238,39 +238,14 @@ out:
return err;
}
-static ssize_t raw_file_write(struct file *file, const char __user *buf,
- size_t count, loff_t *ppos)
-{
- struct iovec local_iov = {
- .iov_base = (char __user *)buf,
- .iov_len = count
- };
-
- return generic_file_write_nolock(file, &local_iov, 1, ppos);
-}
-
-static ssize_t raw_file_aio_write(struct kiocb *iocb, const char __user *buf,
- size_t count, loff_t pos)
-{
- struct iovec local_iov = {
- .iov_base = (char __user *)buf,
- .iov_len = count
- };
-
- return generic_file_aio_write_nolock(iocb, &local_iov, 1, &iocb->ki_pos);
-}
-
-
static const struct file_operations raw_fops = {
- .read = generic_file_read,
+ .read = do_sync_read,
.aio_read = generic_file_aio_read,
- .write = raw_file_write,
- .aio_write = raw_file_aio_write,
+ .write = do_sync_write,
+ .aio_write = generic_file_aio_write_nolock,
.open = raw_open,
.release= raw_release,
.ioctl = raw_ioctl,
- .readv = generic_file_readv,
- .writev = generic_file_writev,
.owner = THIS_MODULE,
};
@@ -288,31 +263,34 @@ static struct cdev raw_cdev = {
static int __init raw_init(void)
{
dev_t dev = MKDEV(RAW_MAJOR, 0);
+ int ret;
- if (register_chrdev_region(dev, MAX_RAW_MINORS, "raw"))
+ ret = register_chrdev_region(dev, MAX_RAW_MINORS, "raw");
+ if (ret)
goto error;
cdev_init(&raw_cdev, &raw_fops);
- if (cdev_add(&raw_cdev, dev, MAX_RAW_MINORS)) {
+ ret = cdev_add(&raw_cdev, dev, MAX_RAW_MINORS);
+ if (ret) {
kobject_put(&raw_cdev.kobj);
- unregister_chrdev_region(dev, MAX_RAW_MINORS);
- goto error;
+ goto error_region;
}
raw_class = class_create(THIS_MODULE, "raw");
if (IS_ERR(raw_class)) {
printk(KERN_ERR "Error creating raw class.\n");
cdev_del(&raw_cdev);
- unregister_chrdev_region(dev, MAX_RAW_MINORS);
- goto error;
+ ret = PTR_ERR(raw_class);
+ goto error_region;
}
class_device_create(raw_class, NULL, MKDEV(RAW_MAJOR, 0), NULL, "rawctl");
return 0;
+error_region:
+ unregister_chrdev_region(dev, MAX_RAW_MINORS);
error:
- printk(KERN_ERR "error register raw device\n");
- return 1;
+ return ret;
}
static void __exit raw_exit(void)
diff --git a/drivers/char/rio/rio_linux.c b/drivers/char/rio/rio_linux.c
index 3fa80aaf4527..202a3b0945b7 100644
--- a/drivers/char/rio/rio_linux.c
+++ b/drivers/char/rio/rio_linux.c
@@ -727,7 +727,7 @@ static struct vpd_prom *get_VPD_PROM(struct Host *hp)
return &vpdp;
}
-static struct tty_operations rio_ops = {
+static const struct tty_operations rio_ops = {
.open = riotopen,
.close = gs_close,
.write = gs_write,
diff --git a/drivers/char/riscom8.c b/drivers/char/riscom8.c
index f1c94f771af5..214d850112fd 100644
--- a/drivers/char/riscom8.c
+++ b/drivers/char/riscom8.c
@@ -675,26 +675,12 @@ static void rc_change_speed(struct riscom_board *bp, struct riscom_port *port)
port->COR2 = 0;
port->MSVR = MSVR_RTS;
- baud = C_BAUD(tty);
-
- if (baud & CBAUDEX) {
- baud &= ~CBAUDEX;
- if (baud < 1 || baud > 2)
- port->tty->termios->c_cflag &= ~CBAUDEX;
- else
- baud += 15;
- }
- if (baud == 15) {
- if ((port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI)
- baud ++;
- if ((port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI)
- baud += 2;
- }
+ baud = tty_get_baud_rate(tty);
/* Select port on the board */
rc_out(bp, CD180_CAR, port_No(port));
- if (!baud_table[baud]) {
+ if (!baud) {
/* Drop DTR & exit */
bp->DTR |= (1u << port_No(port));
rc_out(bp, RC_DTR, bp->DTR);
@@ -710,7 +696,7 @@ static void rc_change_speed(struct riscom_board *bp, struct riscom_port *port)
*/
/* Set baud rate for port */
- tmp = (((RC_OSCFREQ + baud_table[baud]/2) / baud_table[baud] +
+ tmp = (((RC_OSCFREQ + baud/2) / baud +
CD180_TPC/2) / CD180_TPC);
rc_out(bp, CD180_RBPRH, (tmp >> 8) & 0xff);
@@ -718,7 +704,7 @@ static void rc_change_speed(struct riscom_board *bp, struct riscom_port *port)
rc_out(bp, CD180_RBPRL, tmp & 0xff);
rc_out(bp, CD180_TBPRL, tmp & 0xff);
- baud = (baud_table[baud] + 5) / 10; /* Estimated CPS */
+ baud = (baud + 5) / 10; /* Estimated CPS */
/* Two timer ticks seems enough to wakeup something like SLIP driver */
tmp = ((baud + HZ/2) / HZ) * 2 - CD180_NFIFO;
@@ -1597,7 +1583,7 @@ static void do_softint(void *private_)
}
}
-static struct tty_operations riscom_ops = {
+static const struct tty_operations riscom_ops = {
.open = rc_open,
.close = rc_close,
.write = rc_write,
diff --git a/drivers/char/rocket.c b/drivers/char/rocket.c
index 0ac131881322..bac80056f7e0 100644
--- a/drivers/char/rocket.c
+++ b/drivers/char/rocket.c
@@ -2334,7 +2334,7 @@ static int __init init_ISA(int i)
return (1);
}
-static struct tty_operations rocket_ops = {
+static const struct tty_operations rocket_ops = {
.open = rp_open,
.close = rp_close,
.write = rp_write,
diff --git a/drivers/char/rtc.c b/drivers/char/rtc.c
index ab6429b4a84e..656f8c0ca52e 100644
--- a/drivers/char/rtc.c
+++ b/drivers/char/rtc.c
@@ -1262,10 +1262,8 @@ void rtc_get_rtc_time(struct rtc_time *rtc_tm)
* Once the read clears, read the RTC time (again via ioctl). Easy.
*/
- while (rtc_is_updating() != 0 && jiffies - uip_watchdog < 2*HZ/100) {
- barrier();
+ while (rtc_is_updating() != 0 && jiffies - uip_watchdog < 2*HZ/100)
cpu_relax();
- }
/*
* Only the values that we read from the RTC are set. We leave
diff --git a/drivers/char/s3c2410-rtc.c b/drivers/char/s3c2410-rtc.c
deleted file mode 100644
index 5458ef1634e5..000000000000
--- a/drivers/char/s3c2410-rtc.c
+++ /dev/null
@@ -1,591 +0,0 @@
-/* drivers/char/s3c2410_rtc.c
- *
- * Copyright (c) 2004 Simtec Electronics <linux@simtec.co.uk>
- * http://www.simtec.co.uk/products/SWLINUX/
- *
- * 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.
- *
- * S3C2410 Internal RTC Driver
- *
- * Changelog:
- * 08-Nov-2004 BJD Initial creation
- * 12-Nov-2004 BJD Added periodic IRQ and PM code
- * 22-Nov-2004 BJD Sign-test on alarm code to check for <0
- * 10-Mar-2005 LCVR Changed S3C2410_VA_RTC to S3C24XX_VA_RTC
-*/
-
-#include <linux/module.h>
-#include <linux/fs.h>
-#include <linux/string.h>
-#include <linux/init.h>
-#include <linux/platform_device.h>
-#include <linux/interrupt.h>
-#include <linux/rtc.h>
-#include <linux/bcd.h>
-#include <linux/clk.h>
-
-#include <asm/hardware.h>
-#include <asm/uaccess.h>
-#include <asm/io.h>
-#include <asm/irq.h>
-#include <asm/rtc.h>
-
-#include <asm/mach/time.h>
-
-#include <asm/arch/regs-rtc.h>
-
-/* need this for the RTC_AF definitions */
-#include <linux/mc146818rtc.h>
-
-#undef S3C24XX_VA_RTC
-#define S3C24XX_VA_RTC s3c2410_rtc_base
-
-static struct resource *s3c2410_rtc_mem;
-
-static void __iomem *s3c2410_rtc_base;
-static int s3c2410_rtc_alarmno = NO_IRQ;
-static int s3c2410_rtc_tickno = NO_IRQ;
-static int s3c2410_rtc_freq = 1;
-
-static DEFINE_SPINLOCK(s3c2410_rtc_pie_lock);
-
-/* IRQ Handlers */
-
-static irqreturn_t s3c2410_rtc_alarmirq(int irq, void *id, struct pt_regs *r)
-{
- rtc_update(1, RTC_AF | RTC_IRQF);
- return IRQ_HANDLED;
-}
-
-static irqreturn_t s3c2410_rtc_tickirq(int irq, void *id, struct pt_regs *r)
-{
- rtc_update(1, RTC_PF | RTC_IRQF);
- return IRQ_HANDLED;
-}
-
-/* Update control registers */
-static void s3c2410_rtc_setaie(int to)
-{
- unsigned int tmp;
-
- pr_debug("%s: aie=%d\n", __FUNCTION__, to);
-
- tmp = readb(S3C2410_RTCALM);
-
- if (to)
- tmp |= S3C2410_RTCALM_ALMEN;
- else
- tmp &= ~S3C2410_RTCALM_ALMEN;
-
-
- writeb(tmp, S3C2410_RTCALM);
-}
-
-static void s3c2410_rtc_setpie(int to)
-{
- unsigned int tmp;
-
- pr_debug("%s: pie=%d\n", __FUNCTION__, to);
-
- spin_lock_irq(&s3c2410_rtc_pie_lock);
- tmp = readb(S3C2410_TICNT) & ~S3C2410_TICNT_ENABLE;
-
- if (to)
- tmp |= S3C2410_TICNT_ENABLE;
-
- writeb(tmp, S3C2410_TICNT);
- spin_unlock_irq(&s3c2410_rtc_pie_lock);
-}
-
-static void s3c2410_rtc_setfreq(int freq)
-{
- unsigned int tmp;
-
- spin_lock_irq(&s3c2410_rtc_pie_lock);
- tmp = readb(S3C2410_TICNT) & S3C2410_TICNT_ENABLE;
-
- s3c2410_rtc_freq = freq;
-
- tmp |= (128 / freq)-1;
-
- writeb(tmp, S3C2410_TICNT);
- spin_unlock_irq(&s3c2410_rtc_pie_lock);
-}
-
-/* Time read/write */
-
-static int s3c2410_rtc_gettime(struct rtc_time *rtc_tm)
-{
- unsigned int have_retried = 0;
-
- retry_get_time:
- rtc_tm->tm_min = readb(S3C2410_RTCMIN);
- rtc_tm->tm_hour = readb(S3C2410_RTCHOUR);
- rtc_tm->tm_mday = readb(S3C2410_RTCDATE);
- rtc_tm->tm_mon = readb(S3C2410_RTCMON);
- rtc_tm->tm_year = readb(S3C2410_RTCYEAR);
- rtc_tm->tm_sec = readb(S3C2410_RTCSEC);
-
- /* the only way to work out wether the system was mid-update
- * when we read it is to check the second counter, and if it
- * is zero, then we re-try the entire read
- */
-
- if (rtc_tm->tm_sec == 0 && !have_retried) {
- have_retried = 1;
- goto retry_get_time;
- }
-
- pr_debug("read time %02x.%02x.%02x %02x/%02x/%02x\n",
- rtc_tm->tm_year, rtc_tm->tm_mon, rtc_tm->tm_mday,
- rtc_tm->tm_hour, rtc_tm->tm_min, rtc_tm->tm_sec);
-
- BCD_TO_BIN(rtc_tm->tm_sec);
- BCD_TO_BIN(rtc_tm->tm_min);
- BCD_TO_BIN(rtc_tm->tm_hour);
- BCD_TO_BIN(rtc_tm->tm_mday);
- BCD_TO_BIN(rtc_tm->tm_mon);
- BCD_TO_BIN(rtc_tm->tm_year);
-
- rtc_tm->tm_year += 100;
- rtc_tm->tm_mon -= 1;
-
- return 0;
-}
-
-
-static int s3c2410_rtc_settime(struct rtc_time *tm)
-{
- /* the rtc gets round the y2k problem by just not supporting it */
-
- if (tm->tm_year < 100)
- return -EINVAL;
-
- writeb(BIN2BCD(tm->tm_sec), S3C2410_RTCSEC);
- writeb(BIN2BCD(tm->tm_min), S3C2410_RTCMIN);
- writeb(BIN2BCD(tm->tm_hour), S3C2410_RTCHOUR);
- writeb(BIN2BCD(tm->tm_mday), S3C2410_RTCDATE);
- writeb(BIN2BCD(tm->tm_mon + 1), S3C2410_RTCMON);
- writeb(BIN2BCD(tm->tm_year - 100), S3C2410_RTCYEAR);
-
- return 0;
-}
-
-static int s3c2410_rtc_getalarm(struct rtc_wkalrm *alrm)
-{
- struct rtc_time *alm_tm = &alrm->time;
- unsigned int alm_en;
-
- alm_tm->tm_sec = readb(S3C2410_ALMSEC);
- alm_tm->tm_min = readb(S3C2410_ALMMIN);
- alm_tm->tm_hour = readb(S3C2410_ALMHOUR);
- alm_tm->tm_mon = readb(S3C2410_ALMMON);
- alm_tm->tm_mday = readb(S3C2410_ALMDATE);
- alm_tm->tm_year = readb(S3C2410_ALMYEAR);
-
- alm_en = readb(S3C2410_RTCALM);
-
- pr_debug("read alarm %02x %02x.%02x.%02x %02x/%02x/%02x\n",
- alm_en,
- alm_tm->tm_year, alm_tm->tm_mon, alm_tm->tm_mday,
- alm_tm->tm_hour, alm_tm->tm_min, alm_tm->tm_sec);
-
-
- /* decode the alarm enable field */
-
- if (alm_en & S3C2410_RTCALM_SECEN) {
- BCD_TO_BIN(alm_tm->tm_sec);
- } else {
- alm_tm->tm_sec = 0xff;
- }
-
- if (alm_en & S3C2410_RTCALM_MINEN) {
- BCD_TO_BIN(alm_tm->tm_min);
- } else {
- alm_tm->tm_min = 0xff;
- }
-
- if (alm_en & S3C2410_RTCALM_HOUREN) {
- BCD_TO_BIN(alm_tm->tm_hour);
- } else {
- alm_tm->tm_hour = 0xff;
- }
-
- if (alm_en & S3C2410_RTCALM_DAYEN) {
- BCD_TO_BIN(alm_tm->tm_mday);
- } else {
- alm_tm->tm_mday = 0xff;
- }
-
- if (alm_en & S3C2410_RTCALM_MONEN) {
- BCD_TO_BIN(alm_tm->tm_mon);
- alm_tm->tm_mon -= 1;
- } else {
- alm_tm->tm_mon = 0xff;
- }
-
- if (alm_en & S3C2410_RTCALM_YEAREN) {
- BCD_TO_BIN(alm_tm->tm_year);
- } else {
- alm_tm->tm_year = 0xffff;
- }
-
- /* todo - set alrm->enabled ? */
-
- return 0;
-}
-
-static int s3c2410_rtc_setalarm(struct rtc_wkalrm *alrm)
-{
- struct rtc_time *tm = &alrm->time;
- unsigned int alrm_en;
-
- pr_debug("s3c2410_rtc_setalarm: %d, %02x/%02x/%02x %02x.%02x.%02x\n",
- alrm->enabled,
- tm->tm_mday & 0xff, tm->tm_mon & 0xff, tm->tm_year & 0xff,
- tm->tm_hour & 0xff, tm->tm_min & 0xff, tm->tm_sec);
-
- if (alrm->enabled || 1) {
- alrm_en = readb(S3C2410_RTCALM) & S3C2410_RTCALM_ALMEN;
- writeb(0x00, S3C2410_RTCALM);
-
- if (tm->tm_sec < 60 && tm->tm_sec >= 0) {
- alrm_en |= S3C2410_RTCALM_SECEN;
- writeb(BIN2BCD(tm->tm_sec), S3C2410_ALMSEC);
- }
-
- if (tm->tm_min < 60 && tm->tm_min >= 0) {
- alrm_en |= S3C2410_RTCALM_MINEN;
- writeb(BIN2BCD(tm->tm_min), S3C2410_ALMMIN);
- }
-
- if (tm->tm_hour < 24 && tm->tm_hour >= 0) {
- alrm_en |= S3C2410_RTCALM_HOUREN;
- writeb(BIN2BCD(tm->tm_hour), S3C2410_ALMHOUR);
- }
-
- pr_debug("setting S3C2410_RTCALM to %08x\n", alrm_en);
-
- writeb(alrm_en, S3C2410_RTCALM);
- enable_irq_wake(s3c2410_rtc_alarmno);
- } else {
- alrm_en = readb(S3C2410_RTCALM);
- alrm_en &= ~S3C2410_RTCALM_ALMEN;
- writeb(alrm_en, S3C2410_RTCALM);
- disable_irq_wake(s3c2410_rtc_alarmno);
- }
-
- return 0;
-}
-
-static int s3c2410_rtc_ioctl(unsigned int cmd, unsigned long arg)
-{
- switch (cmd) {
- case RTC_AIE_OFF:
- case RTC_AIE_ON:
- s3c2410_rtc_setaie((cmd == RTC_AIE_ON) ? 1 : 0);
- return 0;
-
- case RTC_PIE_OFF:
- case RTC_PIE_ON:
- s3c2410_rtc_setpie((cmd == RTC_PIE_ON) ? 1 : 0);
- return 0;
-
- case RTC_IRQP_READ:
- return put_user(s3c2410_rtc_freq, (unsigned long __user *)arg);
-
- case RTC_IRQP_SET:
- if (arg < 1 || arg > 64)
- return -EINVAL;
-
- if (!capable(CAP_SYS_RESOURCE))
- return -EACCES;
-
- /* check for power of 2 */
-
- if ((arg & (arg-1)) != 0)
- return -EINVAL;
-
- pr_debug("s3c2410_rtc: setting frequency %ld\n", arg);
-
- s3c2410_rtc_setfreq(arg);
- return 0;
-
- case RTC_UIE_ON:
- case RTC_UIE_OFF:
- return -EINVAL;
- }
-
- return -EINVAL;
-}
-
-static int s3c2410_rtc_proc(char *buf)
-{
- unsigned int rtcalm = readb(S3C2410_RTCALM);
- unsigned int ticnt = readb (S3C2410_TICNT);
- char *p = buf;
-
- p += sprintf(p, "alarm_IRQ\t: %s\n",
- (rtcalm & S3C2410_RTCALM_ALMEN) ? "yes" : "no" );
- p += sprintf(p, "periodic_IRQ\t: %s\n",
- (ticnt & S3C2410_TICNT_ENABLE) ? "yes" : "no" );
- p += sprintf(p, "periodic_freq\t: %d\n", s3c2410_rtc_freq);
-
- return p - buf;
-}
-
-static int s3c2410_rtc_open(void)
-{
- int ret;
-
- ret = request_irq(s3c2410_rtc_alarmno, s3c2410_rtc_alarmirq,
- IRQF_DISABLED, "s3c2410-rtc alarm", NULL);
-
- if (ret)
- printk(KERN_ERR "IRQ%d already in use\n", s3c2410_rtc_alarmno);
-
- ret = request_irq(s3c2410_rtc_tickno, s3c2410_rtc_tickirq,
- IRQF_DISABLED, "s3c2410-rtc tick", NULL);
-
- if (ret) {
- printk(KERN_ERR "IRQ%d already in use\n", s3c2410_rtc_tickno);
- goto tick_err;
- }
-
- return ret;
-
- tick_err:
- free_irq(s3c2410_rtc_alarmno, NULL);
- return ret;
-}
-
-static void s3c2410_rtc_release(void)
-{
- /* do not clear AIE here, it may be needed for wake */
-
- s3c2410_rtc_setpie(0);
- free_irq(s3c2410_rtc_alarmno, NULL);
- free_irq(s3c2410_rtc_tickno, NULL);
-}
-
-static struct rtc_ops s3c2410_rtcops = {
- .owner = THIS_MODULE,
- .open = s3c2410_rtc_open,
- .release = s3c2410_rtc_release,
- .ioctl = s3c2410_rtc_ioctl,
- .read_time = s3c2410_rtc_gettime,
- .set_time = s3c2410_rtc_settime,
- .read_alarm = s3c2410_rtc_getalarm,
- .set_alarm = s3c2410_rtc_setalarm,
- .proc = s3c2410_rtc_proc,
-};
-
-static void s3c2410_rtc_enable(struct platform_device *pdev, int en)
-{
- unsigned int tmp;
-
- if (s3c2410_rtc_base == NULL)
- return;
-
- if (!en) {
- tmp = readb(S3C2410_RTCCON);
- writeb(tmp & ~S3C2410_RTCCON_RTCEN, S3C2410_RTCCON);
-
- tmp = readb(S3C2410_TICNT);
- writeb(tmp & ~S3C2410_TICNT_ENABLE, S3C2410_TICNT);
- } else {
- /* re-enable the device, and check it is ok */
-
- if ((readb(S3C2410_RTCCON) & S3C2410_RTCCON_RTCEN) == 0){
- dev_info(&pdev->dev, "rtc disabled, re-enabling\n");
-
- tmp = readb(S3C2410_RTCCON);
- writeb(tmp | S3C2410_RTCCON_RTCEN , S3C2410_RTCCON);
- }
-
- if ((readb(S3C2410_RTCCON) & S3C2410_RTCCON_CNTSEL)){
- dev_info(&pdev->dev, "removing S3C2410_RTCCON_CNTSEL\n");
-
- tmp = readb(S3C2410_RTCCON);
- writeb(tmp& ~S3C2410_RTCCON_CNTSEL , S3C2410_RTCCON);
- }
-
- if ((readb(S3C2410_RTCCON) & S3C2410_RTCCON_CLKRST)){
- dev_info(&pdev->dev, "removing S3C2410_RTCCON_CLKRST\n");
-
- tmp = readb(S3C2410_RTCCON);
- writeb(tmp & ~S3C2410_RTCCON_CLKRST, S3C2410_RTCCON);
- }
- }
-}
-
-static int s3c2410_rtc_remove(struct platform_device *dev)
-{
- unregister_rtc(&s3c2410_rtcops);
-
- s3c2410_rtc_setpie(0);
- s3c2410_rtc_setaie(0);
-
- if (s3c2410_rtc_mem != NULL) {
- pr_debug("s3c2410_rtc: releasing s3c2410_rtc_mem\n");
- iounmap(s3c2410_rtc_base);
- release_resource(s3c2410_rtc_mem);
- kfree(s3c2410_rtc_mem);
- }
-
- return 0;
-}
-
-static int s3c2410_rtc_probe(struct platform_device *pdev)
-{
- struct resource *res;
- int ret;
-
- pr_debug("%s: probe=%p\n", __FUNCTION__, pdev);
-
- /* find the IRQs */
-
- s3c2410_rtc_tickno = platform_get_irq(pdev, 1);
- if (s3c2410_rtc_tickno < 0) {
- dev_err(&pdev->dev, "no irq for rtc tick\n");
- return -ENOENT;
- }
-
- s3c2410_rtc_alarmno = platform_get_irq(pdev, 0);
- if (s3c2410_rtc_alarmno < 0) {
- dev_err(&pdev->dev, "no irq for alarm\n");
- return -ENOENT;
- }
-
- pr_debug("s3c2410_rtc: tick irq %d, alarm irq %d\n",
- s3c2410_rtc_tickno, s3c2410_rtc_alarmno);
-
- /* get the memory region */
-
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (res == NULL) {
- dev_err(&pdev->dev, "failed to get memory region resource\n");
- return -ENOENT;
- }
-
- s3c2410_rtc_mem = request_mem_region(res->start, res->end-res->start+1,
- pdev->name);
-
- if (s3c2410_rtc_mem == NULL) {
- dev_err(&pdev->dev, "failed to reserve memory region\n");
- ret = -ENOENT;
- goto exit_err;
- }
-
- s3c2410_rtc_base = ioremap(res->start, res->end - res->start + 1);
- if (s3c2410_rtc_base == NULL) {
- dev_err(&pdev->dev, "failed ioremap()\n");
- ret = -EINVAL;
- goto exit_err;
- }
-
- s3c2410_rtc_mem = res;
- pr_debug("s3c2410_rtc_base=%p\n", s3c2410_rtc_base);
-
- pr_debug("s3c2410_rtc: RTCCON=%02x\n", readb(S3C2410_RTCCON));
-
- /* check to see if everything is setup correctly */
-
- s3c2410_rtc_enable(pdev, 1);
-
- pr_debug("s3c2410_rtc: RTCCON=%02x\n", readb(S3C2410_RTCCON));
-
- s3c2410_rtc_setfreq(s3c2410_rtc_freq);
-
- /* register RTC and exit */
-
- register_rtc(&s3c2410_rtcops);
- return 0;
-
- exit_err:
- dev_err(&pdev->dev, "error %d during initialisation\n", ret);
-
- return ret;
-}
-
-#ifdef CONFIG_PM
-
-/* S3C2410 RTC Power management control */
-
-static struct timespec s3c2410_rtc_delta;
-
-static int ticnt_save;
-
-static int s3c2410_rtc_suspend(struct platform_device *pdev, pm_message_t state)
-{
- struct rtc_time tm;
- struct timespec time;
-
- time.tv_nsec = 0;
-
- /* save TICNT for anyone using periodic interrupts */
-
- ticnt_save = readb(S3C2410_TICNT);
-
- /* calculate time delta for suspend */
-
- s3c2410_rtc_gettime(&tm);
- rtc_tm_to_time(&tm, &time.tv_sec);
- save_time_delta(&s3c2410_rtc_delta, &time);
- s3c2410_rtc_enable(pdev, 0);
-
- return 0;
-}
-
-static int s3c2410_rtc_resume(struct platform_device *pdev)
-{
- struct rtc_time tm;
- struct timespec time;
-
- time.tv_nsec = 0;
-
- s3c2410_rtc_enable(pdev, 1);
- s3c2410_rtc_gettime(&tm);
- rtc_tm_to_time(&tm, &time.tv_sec);
- restore_time_delta(&s3c2410_rtc_delta, &time);
-
- writeb(ticnt_save, S3C2410_TICNT);
- return 0;
-}
-#else
-#define s3c2410_rtc_suspend NULL
-#define s3c2410_rtc_resume NULL
-#endif
-
-static struct platform_driver s3c2410_rtcdrv = {
- .probe = s3c2410_rtc_probe,
- .remove = s3c2410_rtc_remove,
- .suspend = s3c2410_rtc_suspend,
- .resume = s3c2410_rtc_resume,
- .driver = {
- .name = "s3c2410-rtc",
- .owner = THIS_MODULE,
- },
-};
-
-static char __initdata banner[] = "S3C2410 RTC, (c) 2004 Simtec Electronics\n";
-
-static int __init s3c2410_rtc_init(void)
-{
- printk(banner);
- return platform_driver_register(&s3c2410_rtcdrv);
-}
-
-static void __exit s3c2410_rtc_exit(void)
-{
- platform_driver_unregister(&s3c2410_rtcdrv);
-}
-
-module_init(s3c2410_rtc_init);
-module_exit(s3c2410_rtc_exit);
-
-MODULE_DESCRIPTION("S3C24XX RTC Driver");
-MODULE_AUTHOR("Ben Dooks, <ben@simtec.co.uk>");
-MODULE_LICENSE("GPL");
diff --git a/drivers/char/scx200_gpio.c b/drivers/char/scx200_gpio.c
index b956c7babd18..99e5272e3c53 100644
--- a/drivers/char/scx200_gpio.c
+++ b/drivers/char/scx200_gpio.c
@@ -44,7 +44,7 @@ struct nsc_gpio_ops scx200_gpio_ops = {
.gpio_change = scx200_gpio_change,
.gpio_current = scx200_gpio_current
};
-EXPORT_SYMBOL(scx200_gpio_ops);
+EXPORT_SYMBOL_GPL(scx200_gpio_ops);
static int scx200_gpio_open(struct inode *inode, struct file *file)
{
@@ -69,7 +69,7 @@ static const struct file_operations scx200_gpio_fileops = {
.release = scx200_gpio_release,
};
-struct cdev scx200_gpio_cdev; /* use 1 cdev for all pins */
+static struct cdev scx200_gpio_cdev; /* use 1 cdev for all pins */
static int __init scx200_gpio_init(void)
{
diff --git a/drivers/char/selection.c b/drivers/char/selection.c
index 71093a9fc462..74cff839c857 100644
--- a/drivers/char/selection.c
+++ b/drivers/char/selection.c
@@ -33,7 +33,7 @@ extern void poke_blanked_console(void);
/* Variables for selection control. */
/* Use a dynamic buffer, instead of static (Dec 1994) */
-struct vc_data *sel_cons; /* must not be disallocated */
+struct vc_data *sel_cons; /* must not be deallocated */
static volatile int sel_start = -1; /* cleared by clear_selection */
static int sel_end;
static int sel_buffer_lth;
diff --git a/drivers/char/ser_a2232.c b/drivers/char/ser_a2232.c
index 510bd3e0e88b..65c751d0d643 100644
--- a/drivers/char/ser_a2232.c
+++ b/drivers/char/ser_a2232.c
@@ -661,7 +661,7 @@ static void a2232_init_portstructs(void)
}
}
-static struct tty_operations a2232_ops = {
+static const struct tty_operations a2232_ops = {
.open = a2232_open,
.close = gs_close,
.write = gs_write,
diff --git a/drivers/char/serial167.c b/drivers/char/serial167.c
index 21a710cb4bba..b4ea1266b663 100644
--- a/drivers/char/serial167.c
+++ b/drivers/char/serial167.c
@@ -2158,7 +2158,7 @@ mvme167_serial_console_setup(int cflag)
rcor >> 5, rbpr);
} /* serial_console_init */
-static struct tty_operations cy_ops = {
+static const struct tty_operations cy_ops = {
.open = cy_open,
.close = cy_close,
.write = cy_write,
diff --git a/drivers/char/snsc_event.c b/drivers/char/snsc_event.c
index d12d4f629cec..864854c58866 100644
--- a/drivers/char/snsc_event.c
+++ b/drivers/char/snsc_event.c
@@ -220,7 +220,7 @@ scdrv_dispatch_event(char *event, int len)
" Sending SIGPWR to init...\n");
/* give a SIGPWR signal to init proc */
- kill_proc(1, SIGPWR, 0);
+ kill_cad_pid(SIGPWR, 0);
} else {
/* print to system log */
printk("%s|$(0x%x)%s\n", severity, esp_code, desc);
diff --git a/drivers/char/specialix.c b/drivers/char/specialix.c
index a1d303f9a33d..902c48dca3bc 100644
--- a/drivers/char/specialix.c
+++ b/drivers/char/specialix.c
@@ -182,7 +182,6 @@ static int sx_poll = HZ;
#define RS_EVENT_WRITE_WAKEUP 0
static struct tty_driver *specialix_driver;
-static unsigned char * tmp_buf;
static unsigned long baud_table[] = {
0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800,
@@ -1087,24 +1086,16 @@ static void sx_change_speed(struct specialix_board *bp, struct specialix_port *p
port->MSVR = (sx_in(bp, CD186x_MSVR) & MSVR_RTS);
spin_unlock_irqrestore(&bp->lock, flags);
dprintk (SX_DEBUG_TERMIOS, "sx: got MSVR=%02x.\n", port->MSVR);
- baud = C_BAUD(tty);
+ baud = tty_get_baud_rate(tty);
- if (baud & CBAUDEX) {
- baud &= ~CBAUDEX;
- if (baud < 1 || baud > 2)
- port->tty->termios->c_cflag &= ~CBAUDEX;
- else
- baud += 15;
- }
- if (baud == 15) {
+ if (baud == 38400) {
if ((port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI)
baud ++;
if ((port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI)
baud += 2;
}
-
- if (!baud_table[baud]) {
+ if (!baud) {
/* Drop DTR & exit */
dprintk (SX_DEBUG_TERMIOS, "Dropping DTR... Hmm....\n");
if (!SX_CRTSCTS (tty)) {
@@ -1134,7 +1125,7 @@ static void sx_change_speed(struct specialix_board *bp, struct specialix_port *p
"This is an untested option, please be carefull.\n",
port_No (port), tmp);
else
- tmp = (((SX_OSCFREQ + baud_table[baud]/2) / baud_table[baud] +
+ tmp = (((SX_OSCFREQ + baud/2) / baud +
CD186x_TPC/2) / CD186x_TPC);
if ((tmp < 0x10) && time_before(again, jiffies)) {
@@ -1682,7 +1673,7 @@ static int sx_write(struct tty_struct * tty,
bp = port_Board(port);
- if (!port->xmit_buf || !tmp_buf) {
+ if (!port->xmit_buf) {
func_exit();
return 0;
}
@@ -2372,7 +2363,7 @@ static void do_softint(void *private_)
func_exit();
}
-static struct tty_operations sx_ops = {
+static const struct tty_operations sx_ops = {
.open = sx_open,
.close = sx_close,
.write = sx_write,
@@ -2406,12 +2397,6 @@ static int sx_init_drivers(void)
return 1;
}
- if (!(tmp_buf = (unsigned char *) get_zeroed_page(GFP_KERNEL))) {
- printk(KERN_ERR "sx: Couldn't get free page.\n");
- put_tty_driver(specialix_driver);
- func_exit();
- return 1;
- }
specialix_driver->owner = THIS_MODULE;
specialix_driver->name = "ttyW";
specialix_driver->major = SPECIALIX_NORMAL_MAJOR;
@@ -2425,7 +2410,6 @@ static int sx_init_drivers(void)
if ((error = tty_register_driver(specialix_driver))) {
put_tty_driver(specialix_driver);
- free_page((unsigned long)tmp_buf);
printk(KERN_ERR "sx: Couldn't register specialix IO8+ driver, error = %d\n",
error);
func_exit();
@@ -2451,7 +2435,6 @@ static void sx_release_drivers(void)
{
func_enter();
- free_page((unsigned long)tmp_buf);
tty_unregister_driver(specialix_driver);
put_tty_driver(specialix_driver);
func_exit();
diff --git a/drivers/char/stallion.c b/drivers/char/stallion.c
index 3beb2203d24b..bd711537ec4e 100644
--- a/drivers/char/stallion.c
+++ b/drivers/char/stallion.c
@@ -2993,7 +2993,7 @@ static int stl_memioctl(struct inode *ip, struct file *fp, unsigned int cmd, uns
return(rc);
}
-static struct tty_operations stl_ops = {
+static const struct tty_operations stl_ops = {
.open = stl_open,
.close = stl_close,
.write = stl_write,
diff --git a/drivers/char/sx.c b/drivers/char/sx.c
index e1cd2bc4b1e4..57e31e5eaedb 100644
--- a/drivers/char/sx.c
+++ b/drivers/char/sx.c
@@ -2226,7 +2226,7 @@ static int probe_si (struct sx_board *board)
return 1;
}
-static struct tty_operations sx_ops = {
+static const struct tty_operations sx_ops = {
.break_ctl = sx_break,
.open = sx_open,
.close = gs_close,
diff --git a/drivers/char/synclink.c b/drivers/char/synclink.c
index 78b1b1a2732b..38d94987de83 100644
--- a/drivers/char/synclink.c
+++ b/drivers/char/synclink.c
@@ -87,7 +87,6 @@
#include <linux/vmalloc.h>
#include <linux/init.h>
-#include <asm/serial.h>
#include <linux/delay.h>
#include <linux/ioctl.h>
@@ -4360,7 +4359,7 @@ static struct mgsl_struct* mgsl_allocate_device(void)
} /* end of mgsl_allocate_device()*/
-static struct tty_operations mgsl_ops = {
+static const struct tty_operations mgsl_ops = {
.open = mgsl_open,
.close = mgsl_close,
.write = mgsl_write,
diff --git a/drivers/char/synclink_gt.c b/drivers/char/synclink_gt.c
index 2f07b085536b..bdc7cb248b8f 100644
--- a/drivers/char/synclink_gt.c
+++ b/drivers/char/synclink_gt.c
@@ -1,5 +1,5 @@
/*
- * $Id: synclink_gt.c,v 4.25 2006/02/06 21:20:33 paulkf Exp $
+ * $Id: synclink_gt.c,v 4.36 2006/08/28 20:47:14 paulkf Exp $
*
* Device driver for Microgate SyncLink GT serial adapters.
*
@@ -91,12 +91,12 @@
* module identification
*/
static char *driver_name = "SyncLink GT";
-static char *driver_version = "$Revision: 4.25 $";
+static char *driver_version = "$Revision: 4.36 $";
static char *tty_driver_name = "synclink_gt";
static char *tty_dev_prefix = "ttySLG";
MODULE_LICENSE("GPL");
#define MGSL_MAGIC 0x5401
-#define MAX_DEVICES 12
+#define MAX_DEVICES 32
static struct pci_device_id pci_table[] = {
{PCI_VENDOR_ID_MICROGATE, SYNCLINK_GT_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID,},
@@ -461,7 +461,7 @@ static int adapter_test(struct slgt_info *info);
static void reset_adapter(struct slgt_info *info);
static void reset_port(struct slgt_info *info);
static void async_mode(struct slgt_info *info);
-static void hdlc_mode(struct slgt_info *info);
+static void sync_mode(struct slgt_info *info);
static void rx_stop(struct slgt_info *info);
static void rx_start(struct slgt_info *info);
@@ -881,7 +881,9 @@ static int write(struct tty_struct *tty,
if (!count)
goto cleanup;
- if (info->params.mode == MGSL_MODE_RAW) {
+ if (info->params.mode == MGSL_MODE_RAW ||
+ info->params.mode == MGSL_MODE_MONOSYNC ||
+ info->params.mode == MGSL_MODE_BISYNC) {
unsigned int bufs_needed = (count/DMABUFSIZE);
unsigned int bufs_free = free_tbuf_count(info);
if (count % DMABUFSIZE)
@@ -1897,6 +1899,8 @@ static void bh_handler(void* context)
while(rx_get_frame(info));
break;
case MGSL_MODE_RAW:
+ case MGSL_MODE_MONOSYNC:
+ case MGSL_MODE_BISYNC:
while(rx_get_buf(info));
break;
}
@@ -2362,10 +2366,9 @@ static void program_hw(struct slgt_info *info)
rx_stop(info);
tx_stop(info);
- if (info->params.mode == MGSL_MODE_HDLC ||
- info->params.mode == MGSL_MODE_RAW ||
+ if (info->params.mode != MGSL_MODE_ASYNC ||
info->netcount)
- hdlc_mode(info);
+ sync_mode(info);
else
async_mode(info);
@@ -2564,6 +2567,10 @@ static int rx_enable(struct slgt_info *info, int enable)
if (enable) {
if (!info->rx_enabled)
rx_start(info);
+ else if (enable == 2) {
+ /* force hunt mode (write 1 to RCR[3]) */
+ wr_reg16(info, RCR, rd_reg16(info, RCR) | BIT3);
+ }
} else {
if (info->rx_enabled)
rx_stop(info);
@@ -3434,7 +3441,7 @@ static void __devexit remove_one(struct pci_dev *dev)
{
}
-static struct tty_operations ops = {
+static const struct tty_operations ops = {
.open = open,
.close = close,
.write = write,
@@ -3748,7 +3755,7 @@ static void tx_start(struct slgt_info *info)
{
if (!info->tx_enabled) {
wr_reg16(info, TCR,
- (unsigned short)(rd_reg16(info, TCR) | BIT1));
+ (unsigned short)((rd_reg16(info, TCR) | BIT1) & ~BIT2));
info->tx_enabled = TRUE;
}
@@ -3775,13 +3782,18 @@ static void tx_start(struct slgt_info *info)
tdma_reset(info);
/* set 1st descriptor address */
wr_reg32(info, TDDAR, info->tbufs[info->tbuf_start].pdesc);
- if (info->params.mode == MGSL_MODE_RAW)
+ switch(info->params.mode) {
+ case MGSL_MODE_RAW:
+ case MGSL_MODE_MONOSYNC:
+ case MGSL_MODE_BISYNC:
wr_reg32(info, TDCSR, BIT2 + BIT0); /* IRQ + DMA enable */
- else
+ break;
+ default:
wr_reg32(info, TDCSR, BIT0); /* DMA enable */
+ }
}
- if (info->params.mode != MGSL_MODE_RAW) {
+ if (info->params.mode == MGSL_MODE_HDLC) {
info->tx_timer.expires = jiffies + msecs_to_jiffies(5000);
add_timer(&info->tx_timer);
}
@@ -3814,7 +3826,6 @@ static void tx_stop(struct slgt_info *info)
/* reset and disable transmitter */
val = rd_reg16(info, TCR) & ~BIT1; /* clear enable bit */
wr_reg16(info, TCR, (unsigned short)(val | BIT2)); /* set reset bit */
- wr_reg16(info, TCR, val); /* clear reset */
slgt_irq_off(info, IRQ_TXDATA + IRQ_TXIDLE + IRQ_TXUNDER);
@@ -3982,7 +3993,7 @@ static void async_mode(struct slgt_info *info)
enable_loopback(info);
}
-static void hdlc_mode(struct slgt_info *info)
+static void sync_mode(struct slgt_info *info)
{
unsigned short val;
@@ -3992,7 +4003,7 @@ static void hdlc_mode(struct slgt_info *info)
/* TCR (tx control)
*
- * 15..13 mode, 000=HDLC 001=raw sync
+ * 15..13 mode, 000=HDLC 001=raw 010=async 011=monosync 100=bisync
* 12..10 encoding
* 09 CRC enable
* 08 CRC32
@@ -4006,8 +4017,11 @@ static void hdlc_mode(struct slgt_info *info)
*/
val = 0;
- if (info->params.mode == MGSL_MODE_RAW)
- val |= BIT13;
+ switch(info->params.mode) {
+ case MGSL_MODE_MONOSYNC: val |= BIT14 + BIT13; break;
+ case MGSL_MODE_BISYNC: val |= BIT15; break;
+ case MGSL_MODE_RAW: val |= BIT13; break;
+ }
if (info->if_mode & MGSL_INTERFACE_RTS_EN)
val |= BIT7;
@@ -4058,7 +4072,7 @@ static void hdlc_mode(struct slgt_info *info)
/* RCR (rx control)
*
- * 15..13 mode, 000=HDLC 001=raw sync
+ * 15..13 mode, 000=HDLC 001=raw 010=async 011=monosync 100=bisync
* 12..10 encoding
* 09 CRC enable
* 08 CRC32
@@ -4069,8 +4083,11 @@ static void hdlc_mode(struct slgt_info *info)
*/
val = 0;
- if (info->params.mode == MGSL_MODE_RAW)
- val |= BIT13;
+ switch(info->params.mode) {
+ case MGSL_MODE_MONOSYNC: val |= BIT14 + BIT13; break;
+ case MGSL_MODE_BISYNC: val |= BIT15; break;
+ case MGSL_MODE_RAW: val |= BIT13; break;
+ }
switch(info->params.encoding)
{
@@ -4309,10 +4326,15 @@ static void free_rbufs(struct slgt_info *info, unsigned int i, unsigned int last
while(!done) {
/* reset current buffer for reuse */
info->rbufs[i].status = 0;
- if (info->params.mode == MGSL_MODE_RAW)
+ switch(info->params.mode) {
+ case MGSL_MODE_RAW:
+ case MGSL_MODE_MONOSYNC:
+ case MGSL_MODE_BISYNC:
set_desc_count(info->rbufs[i], info->raw_rx_size);
- else
+ break;
+ default:
set_desc_count(info->rbufs[i], DMABUFSIZE);
+ }
if (i == last)
done = 1;
@@ -4477,13 +4499,24 @@ cleanup:
static int rx_get_buf(struct slgt_info *info)
{
unsigned int i = info->rbuf_current;
+ unsigned int count;
if (!desc_complete(info->rbufs[i]))
return 0;
- DBGDATA(info, info->rbufs[i].buf, desc_count(info->rbufs[i]), "rx");
- DBGINFO(("rx_get_buf size=%d\n", desc_count(info->rbufs[i])));
- ldisc_receive_buf(info->tty, info->rbufs[i].buf,
- info->flag_buf, desc_count(info->rbufs[i]));
+ count = desc_count(info->rbufs[i]);
+ switch(info->params.mode) {
+ case MGSL_MODE_MONOSYNC:
+ case MGSL_MODE_BISYNC:
+ /* ignore residue in byte synchronous modes */
+ if (desc_residue(info->rbufs[i]))
+ count--;
+ break;
+ }
+ DBGDATA(info, info->rbufs[i].buf, count, "rx");
+ DBGINFO(("rx_get_buf size=%d\n", count));
+ if (count)
+ ldisc_receive_buf(info->tty, info->rbufs[i].buf,
+ info->flag_buf, count);
free_rbufs(info, i, i);
return 1;
}
@@ -4549,8 +4582,13 @@ static void tx_load(struct slgt_info *info, const char *buf, unsigned int size)
size -= count;
buf += count;
- if (!size && info->params.mode != MGSL_MODE_RAW)
- set_desc_eof(*d, 1); /* HDLC: set EOF of last desc */
+ /*
+ * set EOF bit for last buffer of HDLC frame or
+ * for every buffer in raw mode
+ */
+ if ((!size && info->params.mode == MGSL_MODE_HDLC) ||
+ info->params.mode == MGSL_MODE_RAW)
+ set_desc_eof(*d, 1);
else
set_desc_eof(*d, 0);
diff --git a/drivers/char/synclinkmp.c b/drivers/char/synclinkmp.c
index 66f3754fbbdf..6eb75dcd7961 100644
--- a/drivers/char/synclinkmp.c
+++ b/drivers/char/synclinkmp.c
@@ -3929,7 +3929,7 @@ void device_init(int adapter_num, struct pci_dev *pdev)
}
}
-static struct tty_operations ops = {
+static const struct tty_operations ops = {
.open = open,
.close = close,
.write = write,
diff --git a/drivers/char/sysrq.c b/drivers/char/sysrq.c
index ee3ca8f1768e..6b4d4d1e343d 100644
--- a/drivers/char/sysrq.c
+++ b/drivers/char/sysrq.c
@@ -113,6 +113,7 @@ static struct sysrq_key_op sysrq_crashdump_op = {
static void sysrq_handle_reboot(int key, struct pt_regs *pt_regs,
struct tty_struct *tty)
{
+ lockdep_off();
local_irq_enable();
emergency_restart();
}
@@ -208,7 +209,7 @@ static void send_sig_all(int sig)
struct task_struct *p;
for_each_process(p) {
- if (p->mm && p->pid != 1)
+ if (p->mm && !is_init(p))
/* Not swapper, init nor kernel thread */
force_sig(sig, p);
}
diff --git a/drivers/char/tipar.c b/drivers/char/tipar.c
index d30dc09dbbc9..9df0ca1be0e3 100644
--- a/drivers/char/tipar.c
+++ b/drivers/char/tipar.c
@@ -224,14 +224,16 @@ probe_ti_parallel(int minor)
{
int i;
int seq[] = { 0x00, 0x20, 0x10, 0x30 };
+ int data;
for (i = 3; i >= 0; i--) {
outbyte(3, minor);
outbyte(i, minor);
udelay(delay);
+ data = inbyte(minor) & 0x30;
pr_debug("tipar: Probing -> %i: 0x%02x 0x%02x\n", i,
- data & 0x30, seq[i]);
- if ((inbyte(minor) & 0x30) != seq[i]) {
+ data, seq[i]);
+ if (data != seq[i]) {
outbyte(3, minor);
return -1;
}
diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c
index bb0d9199e994..e90ea39c7c4b 100644
--- a/drivers/char/tty_io.c
+++ b/drivers/char/tty_io.c
@@ -129,6 +129,7 @@ LIST_HEAD(tty_drivers); /* linked list of tty drivers */
/* Semaphore to protect creating and releasing a tty. This is shared with
vt.c for deeply disgusting hack reasons */
DEFINE_MUTEX(tty_mutex);
+EXPORT_SYMBOL(tty_mutex);
#ifdef CONFIG_UNIX98_PTYS
extern struct tty_driver *ptm_driver; /* Unix98 pty masters; for /dev/ptmx */
@@ -160,17 +161,11 @@ static void release_mem(struct tty_struct *tty, int idx);
* been initialized in any way but has been zeroed
*
* Locking: none
- * FIXME: use kzalloc
*/
static struct tty_struct *alloc_tty_struct(void)
{
- struct tty_struct *tty;
-
- tty = kmalloc(sizeof(struct tty_struct), GFP_KERNEL);
- if (tty)
- memset(tty, 0, sizeof(struct tty_struct));
- return tty;
+ return kzalloc(sizeof(struct tty_struct), GFP_KERNEL);
}
static void tty_buffer_free_all(struct tty_struct *);
@@ -483,10 +478,9 @@ int tty_insert_flip_string(struct tty_struct *tty, const unsigned char *chars,
tb->used += space;
copied += space;
chars += space;
- }
- /* There is a small chance that we need to split the data over
- several buffers. If this is the case we must loop */
- while (unlikely(size > copied));
+ /* There is a small chance that we need to split the data over
+ several buffers. If this is the case we must loop */
+ } while (unlikely(size > copied));
return copied;
}
EXPORT_SYMBOL(tty_insert_flip_string);
@@ -521,10 +515,9 @@ int tty_insert_flip_string_flags(struct tty_struct *tty,
copied += space;
chars += space;
flags += space;
- }
- /* There is a small chance that we need to split the data over
- several buffers. If this is the case we must loop */
- while (unlikely(size > copied));
+ /* There is a small chance that we need to split the data over
+ several buffers. If this is the case we must loop */
+ } while (unlikely(size > copied));
return copied;
}
EXPORT_SYMBOL(tty_insert_flip_string_flags);
@@ -626,9 +619,9 @@ EXPORT_SYMBOL_GPL(tty_prepare_flip_string_flags);
static void tty_set_termios_ldisc(struct tty_struct *tty, int num)
{
- down(&tty->termios_sem);
+ mutex_lock(&tty->termios_mutex);
tty->termios->c_line = num;
- up(&tty->termios_sem);
+ mutex_unlock(&tty->termios_mutex);
}
/*
@@ -1346,9 +1339,9 @@ static void do_tty_hangup(void *data)
*/
if (tty->driver->flags & TTY_DRIVER_RESET_TERMIOS)
{
- down(&tty->termios_sem);
+ mutex_lock(&tty->termios_mutex);
*tty->termios = tty->driver->init_termios;
- up(&tty->termios_sem);
+ mutex_unlock(&tty->termios_mutex);
}
/* Defer ldisc switch */
@@ -2072,8 +2065,9 @@ fail_no_mem:
/* call the tty release_mem routine to clean out this slot */
release_mem_out:
- printk(KERN_INFO "init_dev: ldisc open failed, "
- "clearing slot %d\n", idx);
+ if (printk_ratelimit())
+ printk(KERN_INFO "init_dev: ldisc open failed, "
+ "clearing slot %d\n", idx);
release_mem(tty, idx);
goto end_init;
}
@@ -2726,6 +2720,8 @@ static int tty_fasync(int fd, struct file * filp, int on)
* Locking:
* Called functions take tty_ldisc_lock
* current->signal->tty check is safe without locks
+ *
+ * FIXME: may race normal receive processing
*/
static int tiocsti(struct tty_struct *tty, char __user *p)
@@ -2748,18 +2744,21 @@ static int tiocsti(struct tty_struct *tty, char __user *p)
* @tty; tty
* @arg: user buffer for result
*
- * Copies the kernel idea of the window size into the user buffer. No
- * locking is done.
+ * Copies the kernel idea of the window size into the user buffer.
*
- * FIXME: Returning random values racing a window size set is wrong
- * should lock here against that
+ * Locking: tty->termios_sem is taken to ensure the winsize data
+ * is consistent.
*/
static int tiocgwinsz(struct tty_struct *tty, struct winsize __user * arg)
{
- if (copy_to_user(arg, &tty->winsize, sizeof(*arg)))
- return -EFAULT;
- return 0;
+ int err;
+
+ mutex_lock(&tty->termios_mutex);
+ err = copy_to_user(arg, &tty->winsize, sizeof(*arg));
+ mutex_unlock(&tty->termios_mutex);
+
+ return err ? -EFAULT: 0;
}
/**
@@ -2772,12 +2771,11 @@ static int tiocgwinsz(struct tty_struct *tty, struct winsize __user * arg)
* actually has driver level meaning and triggers a VC resize.
*
* Locking:
- * The console_sem is used to ensure we do not try and resize
- * the console twice at once.
- * FIXME: Two racing size sets may leave the console and kernel
- * parameters disagreeing. Is this exploitable ?
- * FIXME: Random values racing a window size get is wrong
- * should lock here against that
+ * Called function use the console_sem is used to ensure we do
+ * not try and resize the console twice at once.
+ * The tty->termios_sem is used to ensure we don't double
+ * resize and get confused. Lock order - tty->termios.sem before
+ * console sem
*/
static int tiocswinsz(struct tty_struct *tty, struct tty_struct *real_tty,
@@ -2787,17 +2785,18 @@ static int tiocswinsz(struct tty_struct *tty, struct tty_struct *real_tty,
if (copy_from_user(&tmp_ws, arg, sizeof(*arg)))
return -EFAULT;
+
+ mutex_lock(&tty->termios_mutex);
if (!memcmp(&tmp_ws, &tty->winsize, sizeof(*arg)))
- return 0;
+ goto done;
+
#ifdef CONFIG_VT
if (tty->driver->type == TTY_DRIVER_TYPE_CONSOLE) {
- int rc;
-
- acquire_console_sem();
- rc = vc_resize(tty->driver_data, tmp_ws.ws_col, tmp_ws.ws_row);
- release_console_sem();
- if (rc)
- return -ENXIO;
+ if (vc_lock_resize(tty->driver_data, tmp_ws.ws_col,
+ tmp_ws.ws_row)) {
+ mutex_unlock(&tty->termios_mutex);
+ return -ENXIO;
+ }
}
#endif
if (tty->pgrp > 0)
@@ -2806,6 +2805,8 @@ static int tiocswinsz(struct tty_struct *tty, struct tty_struct *real_tty,
kill_pg(real_tty->pgrp, SIGWINCH, 1);
tty->winsize = tmp_ws;
real_tty->winsize = tmp_ws;
+done:
+ mutex_unlock(&tty->termios_mutex);
return 0;
}
@@ -2880,9 +2881,7 @@ static int fionbio(struct file *file, int __user *p)
* Locking:
* Takes tasklist lock internally to walk sessions
* Takes task_lock() when updating signal->tty
- *
- * FIXME: tty_mutex is needed to protect signal->tty references.
- * FIXME: why task_lock on the signal->tty reference ??
+ * Takes tty_mutex() to protect tty instance
*
*/
@@ -2917,9 +2916,11 @@ static int tiocsctty(struct tty_struct *tty, int arg)
} else
return -EPERM;
}
+ mutex_lock(&tty_mutex);
task_lock(current);
current->signal->tty = tty;
task_unlock(current);
+ mutex_unlock(&tty_mutex);
current->signal->tty_old_pgrp = 0;
tty->session = current->signal->session;
tty->pgrp = process_group(current);
@@ -2959,8 +2960,6 @@ static int tiocgpgrp(struct tty_struct *tty, struct tty_struct *real_tty, pid_t
* permitted where the tty session is our session.
*
* Locking: None
- *
- * FIXME: current->signal->tty referencing is unsafe.
*/
static int tiocspgrp(struct tty_struct *tty, struct tty_struct *real_tty, pid_t __user *p)
@@ -3039,19 +3038,20 @@ static int tiocsetd(struct tty_struct *tty, int __user *p)
* timed break functionality.
*
* Locking:
- * None
+ * atomic_write_lock serializes
*
- * FIXME:
- * What if two overlap
*/
static int send_break(struct tty_struct *tty, unsigned int duration)
{
+ if (mutex_lock_interruptible(&tty->atomic_write_lock))
+ return -EINTR;
tty->driver->break_ctl(tty, -1);
if (!signal_pending(current)) {
msleep_interruptible(duration);
}
tty->driver->break_ctl(tty, 0);
+ mutex_unlock(&tty->atomic_write_lock);
if (signal_pending(current))
return -EINTR;
return 0;
@@ -3144,6 +3144,8 @@ int tty_ioctl(struct inode * inode, struct file * file,
if (tty_paranoia_check(tty, inode, "tty_ioctl"))
return -EINVAL;
+ /* CHECKME: is this safe as one end closes ? */
+
real_tty = tty;
if (tty->driver->type == TTY_DRIVER_TYPE_PTY &&
tty->driver->subtype == PTY_TYPE_MASTER)
@@ -3580,7 +3582,7 @@ static void initialize_tty_struct(struct tty_struct *tty)
tty_buffer_init(tty);
INIT_WORK(&tty->buf.work, flush_to_ldisc, tty);
init_MUTEX(&tty->buf.pty_sem);
- init_MUTEX(&tty->termios_sem);
+ mutex_init(&tty->termios_mutex);
init_waitqueue_head(&tty->write_wait);
init_waitqueue_head(&tty->read_wait);
INIT_WORK(&tty->hangup_work, do_tty_hangup, tty);
@@ -3678,7 +3680,8 @@ void put_tty_driver(struct tty_driver *driver)
kfree(driver);
}
-void tty_set_operations(struct tty_driver *driver, struct tty_operations *op)
+void tty_set_operations(struct tty_driver *driver,
+ const struct tty_operations *op)
{
driver->open = op->open;
driver->close = op->close;
diff --git a/drivers/char/tty_ioctl.c b/drivers/char/tty_ioctl.c
index 4ad47d321bd4..3b6fa7b0be8b 100644
--- a/drivers/char/tty_ioctl.c
+++ b/drivers/char/tty_ioctl.c
@@ -20,6 +20,7 @@
#include <linux/mm.h>
#include <linux/module.h>
#include <linux/bitops.h>
+#include <linux/mutex.h>
#include <asm/io.h>
#include <asm/uaccess.h>
@@ -131,7 +132,7 @@ static void change_termios(struct tty_struct * tty, struct termios * new_termios
/* FIXME: we need to decide on some locking/ordering semantics
for the set_termios notification eventually */
- down(&tty->termios_sem);
+ mutex_lock(&tty->termios_mutex);
*tty->termios = *new_termios;
unset_locked_termios(tty->termios, &old_termios, tty->termios_locked);
@@ -176,7 +177,7 @@ static void change_termios(struct tty_struct * tty, struct termios * new_termios
(ld->set_termios)(tty, &old_termios);
tty_ldisc_deref(ld);
}
- up(&tty->termios_sem);
+ mutex_unlock(&tty->termios_mutex);
}
/**
@@ -284,13 +285,13 @@ static int get_sgttyb(struct tty_struct * tty, struct sgttyb __user * sgttyb)
{
struct sgttyb tmp;
- down(&tty->termios_sem);
+ mutex_lock(&tty->termios_mutex);
tmp.sg_ispeed = 0;
tmp.sg_ospeed = 0;
tmp.sg_erase = tty->termios->c_cc[VERASE];
tmp.sg_kill = tty->termios->c_cc[VKILL];
tmp.sg_flags = get_sgflags(tty);
- up(&tty->termios_sem);
+ mutex_unlock(&tty->termios_mutex);
return copy_to_user(sgttyb, &tmp, sizeof(tmp)) ? -EFAULT : 0;
}
@@ -345,12 +346,12 @@ static int set_sgttyb(struct tty_struct * tty, struct sgttyb __user * sgttyb)
if (copy_from_user(&tmp, sgttyb, sizeof(tmp)))
return -EFAULT;
- down(&tty->termios_sem);
+ mutex_lock(&tty->termios_mutex);
termios = *tty->termios;
termios.c_cc[VERASE] = tmp.sg_erase;
termios.c_cc[VKILL] = tmp.sg_kill;
set_sgflags(&termios, tmp.sg_flags);
- up(&tty->termios_sem);
+ mutex_unlock(&tty->termios_mutex);
change_termios(tty, &termios);
return 0;
}
@@ -422,24 +423,28 @@ static int set_ltchars(struct tty_struct * tty, struct ltchars __user * ltchars)
*
* Send a high priority character to the tty even if stopped
*
- * Locking: none
- *
- * FIXME: overlapping calls with start/stop tty lose state of tty
+ * Locking: none for xchar method, write ordering for write method.
*/
-static void send_prio_char(struct tty_struct *tty, char ch)
+static int send_prio_char(struct tty_struct *tty, char ch)
{
int was_stopped = tty->stopped;
if (tty->driver->send_xchar) {
tty->driver->send_xchar(tty, ch);
- return;
+ return 0;
}
+
+ if (mutex_lock_interruptible(&tty->atomic_write_lock))
+ return -ERESTARTSYS;
+
if (was_stopped)
start_tty(tty);
tty->driver->write(tty, &ch, 1);
if (was_stopped)
stop_tty(tty);
+ mutex_unlock(&tty->atomic_write_lock);
+ return 0;
}
int n_tty_ioctl(struct tty_struct * tty, struct file * file,
@@ -513,11 +518,11 @@ int n_tty_ioctl(struct tty_struct * tty, struct file * file,
break;
case TCIOFF:
if (STOP_CHAR(tty) != __DISABLED_CHAR)
- send_prio_char(tty, STOP_CHAR(tty));
+ return send_prio_char(tty, STOP_CHAR(tty));
break;
case TCION:
if (START_CHAR(tty) != __DISABLED_CHAR)
- send_prio_char(tty, START_CHAR(tty));
+ return send_prio_char(tty, START_CHAR(tty));
break;
default:
return -EINVAL;
@@ -592,11 +597,11 @@ int n_tty_ioctl(struct tty_struct * tty, struct file * file,
case TIOCSSOFTCAR:
if (get_user(arg, (unsigned int __user *) arg))
return -EFAULT;
- down(&tty->termios_sem);
+ mutex_lock(&tty->termios_mutex);
tty->termios->c_cflag =
((tty->termios->c_cflag & ~CLOCAL) |
(arg ? CLOCAL : 0));
- up(&tty->termios_sem);
+ mutex_unlock(&tty->termios_mutex);
return 0;
default:
return -ENOIOCTLCMD;
diff --git a/drivers/char/vc_screen.c b/drivers/char/vc_screen.c
index a9247b5213d5..bd7a98c6ea7a 100644
--- a/drivers/char/vc_screen.c
+++ b/drivers/char/vc_screen.c
@@ -474,14 +474,15 @@ static const struct file_operations vcs_fops = {
static struct class *vc_class;
-void vcs_make_devfs(struct tty_struct *tty)
+void vcs_make_sysfs(struct tty_struct *tty)
{
class_device_create(vc_class, NULL, MKDEV(VCS_MAJOR, tty->index + 1),
NULL, "vcs%u", tty->index + 1);
class_device_create(vc_class, NULL, MKDEV(VCS_MAJOR, tty->index + 129),
NULL, "vcsa%u", tty->index + 1);
}
-void vcs_remove_devfs(struct tty_struct *tty)
+
+void vcs_remove_sysfs(struct tty_struct *tty)
{
class_device_destroy(vc_class, MKDEV(VCS_MAJOR, tty->index + 1));
class_device_destroy(vc_class, MKDEV(VCS_MAJOR, tty->index + 129));
diff --git a/drivers/char/viocons.c b/drivers/char/viocons.c
index f3efeaf2826e..a362ee9c92dd 100644
--- a/drivers/char/viocons.c
+++ b/drivers/char/viocons.c
@@ -1047,7 +1047,7 @@ static int send_open(HvLpIndex remoteLp, void *sem)
0, 0, 0, 0);
}
-static struct tty_operations serial_ops = {
+static const struct tty_operations serial_ops = {
.open = viotty_open,
.close = viotty_close,
.write = viotty_write,
diff --git a/drivers/char/vme_scc.c b/drivers/char/vme_scc.c
index bfe5ea948f6a..c2ca31eb850b 100644
--- a/drivers/char/vme_scc.c
+++ b/drivers/char/vme_scc.c
@@ -113,7 +113,7 @@ static struct real_driver scc_real_driver = {
};
-static struct tty_operations scc_ops = {
+static const struct tty_operations scc_ops = {
.open = scc_open,
.close = gs_close,
.write = gs_write,
diff --git a/drivers/char/vt.c b/drivers/char/vt.c
index da7e66a2a38b..8e4413f6fbaf 100644
--- a/drivers/char/vt.c
+++ b/drivers/char/vt.c
@@ -63,6 +63,13 @@
*
* Removed console_lock, enabled interrupts across all console operations
* 13 March 2001, Andrew Morton
+ *
+ * Fixed UTF-8 mode so alternate charset modes always work according
+ * to control sequences interpreted in do_con_trol function
+ * preserving backward VT100 semigraphics compatibility,
+ * malformed UTF sequences represented as sequences of replacement glyphs,
+ * original codes or '?' as a last resort if replacement glyph is undefined
+ * by Adam Tla/lka <atlka@pg.gda.pl>, Aug 2006
*/
#include <linux/module.h>
@@ -99,7 +106,8 @@
#define MAX_NR_CON_DRIVER 16
#define CON_DRIVER_FLAG_MODULE 1
-#define CON_DRIVER_FLAG_INIT 2
+#define CON_DRIVER_FLAG_INIT 2
+#define CON_DRIVER_FLAG_ATTR 4
struct con_driver {
const struct consw *con;
@@ -128,16 +136,8 @@ const struct consw *conswitchp;
#define DEFAULT_BELL_PITCH 750
#define DEFAULT_BELL_DURATION (HZ/8)
-extern void vcs_make_devfs(struct tty_struct *tty);
-extern void vcs_remove_devfs(struct tty_struct *tty);
-
-extern void console_map_init(void);
-#ifdef CONFIG_PROM_CONSOLE
-extern void prom_con_init(void);
-#endif
-#ifdef CONFIG_MDA_CONSOLE
-extern int mda_console_init(void);
-#endif
+extern void vcs_make_sysfs(struct tty_struct *tty);
+extern void vcs_remove_sysfs(struct tty_struct *tty);
struct vc vc_cons [MAX_NR_CONSOLES];
@@ -730,7 +730,8 @@ int vc_allocate(unsigned int currcons) /* return 0 on success */
visual_init(vc, currcons, 1);
if (!*vc->vc_uni_pagedir_loc)
con_set_default_unimap(vc);
- vc->vc_screenbuf = kmalloc(vc->vc_screenbuf_size, GFP_KERNEL);
+ if (!vc->vc_kmalloced)
+ vc->vc_screenbuf = kmalloc(vc->vc_screenbuf_size, GFP_KERNEL);
if (!vc->vc_screenbuf) {
kfree(vc);
vc_cons[currcons].d = NULL;
@@ -878,14 +879,24 @@ int vc_resize(struct vc_data *vc, unsigned int cols, unsigned int lines)
return err;
}
+int vc_lock_resize(struct vc_data *vc, unsigned int cols, unsigned int lines)
+{
+ int rc;
+
+ acquire_console_sem();
+ rc = vc_resize(vc, cols, lines);
+ release_console_sem();
+ return rc;
+}
-void vc_disallocate(unsigned int currcons)
+void vc_deallocate(unsigned int currcons)
{
WARN_CONSOLE_UNLOCKED();
if (vc_cons_allocated(currcons)) {
struct vc_data *vc = vc_cons[currcons].d;
vc->vc_sw->con_deinit(vc);
+ put_pid(vc->vt_pid);
module_put(vc->vc_sw->owner);
if (vc->vc_kmalloced)
kfree(vc->vc_screenbuf);
@@ -2005,17 +2016,23 @@ static int do_con_write(struct tty_struct *tty, const unsigned char *buf, int co
/* Do no translation at all in control states */
if (vc->vc_state != ESnormal) {
tc = c;
- } else if (vc->vc_utf) {
+ } else if (vc->vc_utf && !vc->vc_disp_ctrl) {
/* Combine UTF-8 into Unicode */
- /* Incomplete characters silently ignored */
+ /* Malformed sequences as sequences of replacement glyphs */
+rescan_last_byte:
if(c > 0x7f) {
- if (vc->vc_utf_count > 0 && (c & 0xc0) == 0x80) {
- vc->vc_utf_char = (vc->vc_utf_char << 6) | (c & 0x3f);
- vc->vc_utf_count--;
- if (vc->vc_utf_count == 0)
- tc = c = vc->vc_utf_char;
- else continue;
+ if (vc->vc_utf_count) {
+ if ((c & 0xc0) == 0x80) {
+ vc->vc_utf_char = (vc->vc_utf_char << 6) | (c & 0x3f);
+ if (--vc->vc_utf_count) {
+ vc->vc_npar++;
+ continue;
+ }
+ tc = c = vc->vc_utf_char;
+ } else
+ goto replacement_glyph;
} else {
+ vc->vc_npar = 0;
if ((c & 0xe0) == 0xc0) {
vc->vc_utf_count = 1;
vc->vc_utf_char = (c & 0x1f);
@@ -2032,14 +2049,15 @@ static int do_con_write(struct tty_struct *tty, const unsigned char *buf, int co
vc->vc_utf_count = 5;
vc->vc_utf_char = (c & 0x01);
} else
- vc->vc_utf_count = 0;
+ goto replacement_glyph;
continue;
}
} else {
+ if (vc->vc_utf_count)
+ goto replacement_glyph;
tc = c;
- vc->vc_utf_count = 0;
}
- } else { /* no utf */
+ } else { /* no utf or alternate charset mode */
tc = vc->vc_translate[vc->vc_toggle_meta ? (c | 0x80) : c];
}
@@ -2054,31 +2072,33 @@ static int do_con_write(struct tty_struct *tty, const unsigned char *buf, int co
* direct-to-font zone in UTF-8 mode.
*/
ok = tc && (c >= 32 ||
- (!vc->vc_utf && !(((vc->vc_disp_ctrl ? CTRL_ALWAYS
- : CTRL_ACTION) >> c) & 1)))
+ !(vc->vc_disp_ctrl ? (CTRL_ALWAYS >> c) & 1 :
+ vc->vc_utf || ((CTRL_ACTION >> c) & 1)))
&& (c != 127 || vc->vc_disp_ctrl)
&& (c != 128+27);
if (vc->vc_state == ESnormal && ok) {
/* Now try to find out how to display it */
tc = conv_uni_to_pc(vc, tc);
- if ( tc == -4 ) {
+ if (tc & ~charmask) {
+ if ( tc == -4 ) {
/* If we got -4 (not found) then see if we have
defined a replacement character (U+FFFD) */
- tc = conv_uni_to_pc(vc, 0xfffd);
-
- /* One reason for the -4 can be that we just
- did a clear_unimap();
- try at least to show something. */
- if (tc == -4)
- tc = c;
- } else if ( tc == -3 ) {
- /* Bad hash table -- hope for the best */
- tc = c;
- }
- if (tc & ~charmask)
- continue; /* Conversion failed */
+replacement_glyph:
+ tc = conv_uni_to_pc(vc, 0xfffd);
+ if (!(tc & ~charmask))
+ goto display_glyph;
+ } else if ( tc != -3 )
+ continue; /* nothing to display */
+ /* no hash table or no replacement --
+ * hope for the best */
+ if ( c & ~charmask )
+ tc = '?';
+ else
+ tc = c;
+ }
+display_glyph:
if (vc->vc_need_wrap || vc->vc_decim)
FLUSH
if (vc->vc_need_wrap) {
@@ -2102,6 +2122,15 @@ static int do_con_write(struct tty_struct *tty, const unsigned char *buf, int co
vc->vc_x++;
draw_to = (vc->vc_pos += 2);
}
+ if (vc->vc_utf_count) {
+ if (vc->vc_npar) {
+ vc->vc_npar--;
+ goto display_glyph;
+ }
+ vc->vc_utf_count = 0;
+ c = orig;
+ goto rescan_last_byte;
+ }
continue;
}
FLUSH
@@ -2498,7 +2527,7 @@ static int con_open(struct tty_struct *tty, struct file *filp)
tty->winsize.ws_col = vc_cons[currcons].d->vc_cols;
}
release_console_sem();
- vcs_make_devfs(tty);
+ vcs_make_sysfs(tty);
return ret;
}
}
@@ -2511,7 +2540,7 @@ static int con_open(struct tty_struct *tty, struct file *filp)
* and taking a ref against the tty while we're in the process of forgetting
* about it and cleaning things up.
*
- * This is because vcs_remove_devfs() can sleep and will drop the BKL.
+ * This is because vcs_remove_sysfs() can sleep and will drop the BKL.
*/
static void con_close(struct tty_struct *tty, struct file *filp)
{
@@ -2524,7 +2553,7 @@ static void con_close(struct tty_struct *tty, struct file *filp)
vc->vc_tty = NULL;
tty->driver_data = NULL;
release_console_sem();
- vcs_remove_devfs(tty);
+ vcs_remove_sysfs(tty);
mutex_unlock(&tty_mutex);
/*
* tty_mutex is released, but we still hold BKL, so there is
@@ -2639,7 +2668,7 @@ static int __init con_init(void)
}
console_initcall(con_init);
-static struct tty_operations con_ops = {
+static const struct tty_operations con_ops = {
.open = con_open,
.close = con_close,
.write = con_write,
@@ -3034,22 +3063,37 @@ static struct class_device_attribute class_device_attrs[] = {
static int vtconsole_init_class_device(struct con_driver *con)
{
int i;
+ int error = 0;
+ con->flag |= CON_DRIVER_FLAG_ATTR;
class_set_devdata(con->class_dev, con);
- for (i = 0; i < ARRAY_SIZE(class_device_attrs); i++)
- class_device_create_file(con->class_dev,
+ for (i = 0; i < ARRAY_SIZE(class_device_attrs); i++) {
+ error = class_device_create_file(con->class_dev,
&class_device_attrs[i]);
+ if (error)
+ break;
+ }
- return 0;
+ if (error) {
+ while (--i >= 0)
+ class_device_remove_file(con->class_dev,
+ &class_device_attrs[i]);
+ con->flag &= ~CON_DRIVER_FLAG_ATTR;
+ }
+
+ return error;
}
static void vtconsole_deinit_class_device(struct con_driver *con)
{
int i;
- for (i = 0; i < ARRAY_SIZE(class_device_attrs); i++)
- class_device_remove_file(con->class_dev,
- &class_device_attrs[i]);
+ if (con->flag & CON_DRIVER_FLAG_ATTR) {
+ for (i = 0; i < ARRAY_SIZE(class_device_attrs); i++)
+ class_device_remove_file(con->class_dev,
+ &class_device_attrs[i]);
+ con->flag &= ~CON_DRIVER_FLAG_ATTR;
+ }
}
/**
@@ -3148,6 +3192,7 @@ int register_con_driver(const struct consw *csw, int first, int last)
} else {
vtconsole_init_class_device(con_driver);
}
+
err:
release_console_sem();
module_put(owner);
@@ -3765,6 +3810,7 @@ EXPORT_SYMBOL(default_blu);
EXPORT_SYMBOL(update_region);
EXPORT_SYMBOL(redraw_screen);
EXPORT_SYMBOL(vc_resize);
+EXPORT_SYMBOL(vc_lock_resize);
EXPORT_SYMBOL(fg_console);
EXPORT_SYMBOL(console_blank_hook);
EXPORT_SYMBOL(console_blanked);
diff --git a/drivers/char/vt_ioctl.c b/drivers/char/vt_ioctl.c
index a5628a8b6620..ac5d60edbafa 100644
--- a/drivers/char/vt_ioctl.c
+++ b/drivers/char/vt_ioctl.c
@@ -96,7 +96,7 @@ do_kdsk_ioctl(int cmd, struct kbentry __user *user_kbe, int perm, struct kbd_str
if (!perm)
return -EPERM;
if (!i && v == K_NOSUCHMAP) {
- /* disallocate map */
+ /* deallocate map */
key_map = key_maps[s];
if (s && key_map) {
key_maps[s] = NULL;
@@ -645,13 +645,16 @@ int vt_ioctl(struct tty_struct *tty, struct file * file,
*/
case KDSIGACCEPT:
{
- extern int spawnpid, spawnsig;
if (!perm || !capable(CAP_KILL))
return -EPERM;
if (!valid_signal(arg) || arg < 1 || arg == SIGKILL)
return -EINVAL;
- spawnpid = current->pid;
- spawnsig = arg;
+
+ spin_lock_irq(&vt_spawn_con.lock);
+ put_pid(vt_spawn_con.pid);
+ vt_spawn_con.pid = get_pid(task_pid(current));
+ vt_spawn_con.sig = arg;
+ spin_unlock_irq(&vt_spawn_con.lock);
return 0;
}
@@ -669,7 +672,7 @@ int vt_ioctl(struct tty_struct *tty, struct file * file,
vc->vt_mode = tmp;
/* the frsig is ignored, so we set it to 0 */
vc->vt_mode.frsig = 0;
- vc->vt_pid = current->pid;
+ put_pid(xchg(&vc->vt_pid, get_pid(task_pid(current))));
/* no switch is required -- saw@shade.msu.ru */
vc->vt_newvt = -1;
release_console_sem();
@@ -819,20 +822,20 @@ int vt_ioctl(struct tty_struct *tty, struct file * file,
if (arg > MAX_NR_CONSOLES)
return -ENXIO;
if (arg == 0) {
- /* disallocate all unused consoles, but leave 0 */
+ /* deallocate all unused consoles, but leave 0 */
acquire_console_sem();
for (i=1; i<MAX_NR_CONSOLES; i++)
if (! VT_BUSY(i))
- vc_disallocate(i);
+ vc_deallocate(i);
release_console_sem();
} else {
- /* disallocate a single console, if possible */
+ /* deallocate a single console, if possible */
arg--;
if (VT_BUSY(arg))
return -EBUSY;
if (arg) { /* leave 0 */
acquire_console_sem();
- vc_disallocate(arg);
+ vc_deallocate(arg);
release_console_sem();
}
}
@@ -847,11 +850,8 @@ int vt_ioctl(struct tty_struct *tty, struct file * file,
if (get_user(ll, &vtsizes->v_rows) ||
get_user(cc, &vtsizes->v_cols))
return -EFAULT;
- for (i = 0; i < MAX_NR_CONSOLES; i++) {
- acquire_console_sem();
- vc_resize(vc_cons[i].d, cc, ll);
- release_console_sem();
- }
+ for (i = 0; i < MAX_NR_CONSOLES; i++)
+ vc_lock_resize(vc_cons[i].d, cc, ll);
return 0;
}
@@ -1063,7 +1063,7 @@ void reset_vc(struct vc_data *vc)
vc->vt_mode.relsig = 0;
vc->vt_mode.acqsig = 0;
vc->vt_mode.frsig = 0;
- vc->vt_pid = -1;
+ put_pid(xchg(&vc->vt_pid, NULL));
vc->vt_newvt = -1;
if (!in_interrupt()) /* Via keyboard.c:SAK() - akpm */
reset_palette(vc);
@@ -1114,7 +1114,7 @@ static void complete_change_console(struct vc_data *vc)
* tell us if the process has gone or something else
* is awry
*/
- if (kill_proc(vc->vt_pid, vc->vt_mode.acqsig, 1) != 0) {
+ if (kill_pid(vc->vt_pid, vc->vt_mode.acqsig, 1) != 0) {
/*
* The controlling process has died, so we revert back to
* normal operation. In this case, we'll also change back
@@ -1174,7 +1174,7 @@ void change_console(struct vc_data *new_vc)
* tell us if the process has gone or something else
* is awry
*/
- if (kill_proc(vc->vt_pid, vc->vt_mode.relsig, 1) == 0) {
+ if (kill_pid(vc->vt_pid, vc->vt_mode.relsig, 1) == 0) {
/*
* It worked. Mark the vt to switch to and
* return. The process needs to send us a
diff --git a/drivers/char/watchdog/Kconfig b/drivers/char/watchdog/Kconfig
index f114d7b5bb2a..06f3fa2fe877 100644
--- a/drivers/char/watchdog/Kconfig
+++ b/drivers/char/watchdog/Kconfig
@@ -165,6 +165,24 @@ config EP93XX_WATCHDOG
To compile this driver as a module, choose M here: the
module will be called ep93xx_wdt.
+config OMAP_WATCHDOG
+ tristate "OMAP Watchdog"
+ depends on WATCHDOG && (ARCH_OMAP16XX || ARCH_OMAP24XX)
+ help
+ Support for TI OMAP1610/OMAP1710/OMAP2420 watchdog. Say 'Y' here to
+ enable the OMAP1610/OMAP1710 watchdog timer.
+
+config PNX4008_WATCHDOG
+ tristate "PNX4008 Watchdog"
+ depends on WATCHDOG && ARCH_PNX4008
+ help
+ Say Y here if to include support for the watchdog timer
+ in the PNX4008 processor.
+ This driver can be built as a module by choosing M. The module
+ will be called pnx4008_wdt.
+
+ Say N if you are unsure.
+
# X86 (i386 + ia64 + x86_64) Architecture
config ACQUIRE_WDT
diff --git a/drivers/char/watchdog/Makefile b/drivers/char/watchdog/Makefile
index 6ab77b61a643..6ffca7cb56ab 100644
--- a/drivers/char/watchdog/Makefile
+++ b/drivers/char/watchdog/Makefile
@@ -24,6 +24,7 @@ obj-$(CONFIG_USBPCWATCHDOG) += pcwd_usb.o
# ARM Architecture
obj-$(CONFIG_AT91_WATCHDOG) += at91_wdt.o
+obj-$(CONFIG_OMAP_WATCHDOG) += omap_wdt.o
obj-$(CONFIG_21285_WATCHDOG) += wdt285.o
obj-$(CONFIG_977_WATCHDOG) += wdt977.o
obj-$(CONFIG_IXP2000_WATCHDOG) += ixp2000_wdt.o
@@ -32,6 +33,7 @@ obj-$(CONFIG_S3C2410_WATCHDOG) += s3c2410_wdt.o
obj-$(CONFIG_SA1100_WATCHDOG) += sa1100_wdt.o
obj-$(CONFIG_MPCORE_WATCHDOG) += mpcore_wdt.o
obj-$(CONFIG_EP93XX_WATCHDOG) += ep93xx_wdt.o
+obj-$(CONFIG_PNX4008_WATCHDOG) += pnx4008_wdt.o
# X86 (i386 + ia64 + x86_64) Architecture
obj-$(CONFIG_ACQUIRE_WDT) += acquirewdt.o
diff --git a/drivers/char/watchdog/acquirewdt.c b/drivers/char/watchdog/acquirewdt.c
index c77fe3cf2852..154d67e591e5 100644
--- a/drivers/char/watchdog/acquirewdt.c
+++ b/drivers/char/watchdog/acquirewdt.c
@@ -183,7 +183,7 @@ static int acq_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
}
default:
- return -ENOIOCTLCMD;
+ return -ENOTTY;
}
}
diff --git a/drivers/char/watchdog/advantechwdt.c b/drivers/char/watchdog/advantechwdt.c
index 8069be445edc..9d732769ba01 100644
--- a/drivers/char/watchdog/advantechwdt.c
+++ b/drivers/char/watchdog/advantechwdt.c
@@ -176,7 +176,7 @@ advwdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
}
default:
- return -ENOIOCTLCMD;
+ return -ENOTTY;
}
return 0;
}
diff --git a/drivers/char/watchdog/alim1535_wdt.c b/drivers/char/watchdog/alim1535_wdt.c
index c5c94e4c9495..01b0d132ee41 100644
--- a/drivers/char/watchdog/alim1535_wdt.c
+++ b/drivers/char/watchdog/alim1535_wdt.c
@@ -236,7 +236,7 @@ static int ali_ioctl(struct inode *inode, struct file *file,
return put_user(timeout, p);
default:
- return -ENOIOCTLCMD;
+ return -ENOTTY;
}
}
@@ -330,17 +330,20 @@ static int __init ali_find_watchdog(void)
u32 wdog;
/* Check for a 1535 series bridge */
- pdev = pci_find_device(PCI_VENDOR_ID_AL, 0x1535, NULL);
+ pdev = pci_get_device(PCI_VENDOR_ID_AL, 0x1535, NULL);
if(pdev == NULL)
return -ENODEV;
+ pci_dev_put(pdev);
/* Check for the a 7101 PMU */
- pdev = pci_find_device(PCI_VENDOR_ID_AL, 0x7101, NULL);
+ pdev = pci_get_device(PCI_VENDOR_ID_AL, 0x7101, NULL);
if(pdev == NULL)
return -ENODEV;
- if(pci_enable_device(pdev))
+ if(pci_enable_device(pdev)) {
+ pci_dev_put(pdev);
return -EIO;
+ }
ali_pci = pdev;
@@ -447,6 +450,7 @@ static void __exit watchdog_exit(void)
/* Deregister */
unregister_reboot_notifier(&ali_notifier);
misc_deregister(&ali_miscdev);
+ pci_dev_put(ali_pci);
}
module_init(watchdog_init);
diff --git a/drivers/char/watchdog/alim7101_wdt.c b/drivers/char/watchdog/alim7101_wdt.c
index ffd7684f999b..5948863b592b 100644
--- a/drivers/char/watchdog/alim7101_wdt.c
+++ b/drivers/char/watchdog/alim7101_wdt.c
@@ -277,7 +277,7 @@ static int fop_ioctl(struct inode *inode, struct file *file, unsigned int cmd, u
case WDIOC_GETTIMEOUT:
return put_user(timeout, p);
default:
- return -ENOIOCTLCMD;
+ return -ENOTTY;
}
}
@@ -333,6 +333,7 @@ static void __exit alim7101_wdt_unload(void)
/* Deregister */
misc_deregister(&wdt_miscdev);
unregister_reboot_notifier(&wdt_notifier);
+ pci_dev_put(alim7101_pmu);
}
static int __init alim7101_wdt_init(void)
@@ -342,7 +343,8 @@ static int __init alim7101_wdt_init(void)
char tmp;
printk(KERN_INFO PFX "Steve Hill <steve@navaho.co.uk>.\n");
- alim7101_pmu = pci_find_device(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M7101,NULL);
+ alim7101_pmu = pci_get_device(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M7101,
+ NULL);
if (!alim7101_pmu) {
printk(KERN_INFO PFX "ALi M7101 PMU not present - WDT not set\n");
return -EBUSY;
@@ -351,21 +353,23 @@ static int __init alim7101_wdt_init(void)
/* Set the WDT in the PMU to 1 second */
pci_write_config_byte(alim7101_pmu, ALI_7101_WDT, 0x02);
- ali1543_south = pci_find_device(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M1533, NULL);
+ ali1543_south = pci_get_device(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M1533,
+ NULL);
if (!ali1543_south) {
printk(KERN_INFO PFX "ALi 1543 South-Bridge not present - WDT not set\n");
- return -EBUSY;
+ goto err_out;
}
pci_read_config_byte(ali1543_south, 0x5e, &tmp);
+ pci_dev_put(ali1543_south);
if ((tmp & 0x1e) == 0x00) {
if (!use_gpio) {
printk(KERN_INFO PFX "Detected old alim7101 revision 'a1d'. If this is a cobalt board, set the 'use_gpio' module parameter.\n");
- return -EBUSY;
+ goto err_out;
}
nowayout = 1;
} else if ((tmp & 0x1e) != 0x12 && (tmp & 0x1e) != 0x00) {
printk(KERN_INFO PFX "ALi 1543 South-Bridge does not have the correct revision number (???1001?) - WDT not set\n");
- return -EBUSY;
+ goto err_out;
}
if(timeout < 1 || timeout > 3600) /* arbitrary upper limit */
@@ -404,6 +408,7 @@ static int __init alim7101_wdt_init(void)
err_out_miscdev:
misc_deregister(&wdt_miscdev);
err_out:
+ pci_dev_put(alim7101_pmu);
return rc;
}
diff --git a/drivers/char/watchdog/at91_wdt.c b/drivers/char/watchdog/at91_wdt.c
index cc266715ea32..4e7a1145e78f 100644
--- a/drivers/char/watchdog/at91_wdt.c
+++ b/drivers/char/watchdog/at91_wdt.c
@@ -168,7 +168,7 @@ static int at91_wdt_ioctl(struct inode *inode, struct file *file,
return 0;
default:
- return -ENOIOCTLCMD;
+ return -ENOTTY;
}
}
diff --git a/drivers/char/watchdog/booke_wdt.c b/drivers/char/watchdog/booke_wdt.c
index e3cefc538b40..488902231cc2 100644
--- a/drivers/char/watchdog/booke_wdt.c
+++ b/drivers/char/watchdog/booke_wdt.c
@@ -125,7 +125,7 @@ static int booke_wdt_ioctl (struct inode *inode, struct file *file,
return -EINVAL;
return 0;
default:
- return -ENOIOCTLCMD;
+ return -ENOTTY;
}
return 0;
diff --git a/drivers/char/watchdog/cpu5wdt.c b/drivers/char/watchdog/cpu5wdt.c
index 04c7e49918db..00bdabb90f27 100644
--- a/drivers/char/watchdog/cpu5wdt.c
+++ b/drivers/char/watchdog/cpu5wdt.c
@@ -183,7 +183,7 @@ static int cpu5wdt_ioctl(struct inode *inode, struct file *file, unsigned int cm
}
break;
default:
- return -ENOIOCTLCMD;
+ return -ENOTTY;
}
return 0;
}
diff --git a/drivers/char/watchdog/ep93xx_wdt.c b/drivers/char/watchdog/ep93xx_wdt.c
index 77c8a955ae9e..01cf123b1616 100644
--- a/drivers/char/watchdog/ep93xx_wdt.c
+++ b/drivers/char/watchdog/ep93xx_wdt.c
@@ -144,7 +144,7 @@ static int
ep93xx_wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
unsigned long arg)
{
- int ret = -ENOIOCTLCMD;
+ int ret = -ENOTTY;
switch (cmd) {
case WDIOC_GETSUPPORT:
diff --git a/drivers/char/watchdog/eurotechwdt.c b/drivers/char/watchdog/eurotechwdt.c
index 62dbccb2f6df..4f4269754c46 100644
--- a/drivers/char/watchdog/eurotechwdt.c
+++ b/drivers/char/watchdog/eurotechwdt.c
@@ -240,7 +240,7 @@ static int eurwdt_ioctl(struct inode *inode, struct file *file,
switch(cmd) {
default:
- return -ENOIOCTLCMD;
+ return -ENOTTY;
case WDIOC_GETSUPPORT:
return copy_to_user(argp, &ident, sizeof(ident)) ? -EFAULT : 0;
diff --git a/drivers/char/watchdog/i6300esb.c b/drivers/char/watchdog/i6300esb.c
index 870539eabbf3..fb64df4d7c87 100644
--- a/drivers/char/watchdog/i6300esb.c
+++ b/drivers/char/watchdog/i6300esb.c
@@ -315,7 +315,7 @@ static int esb_ioctl (struct inode *inode, struct file *file,
return put_user(heartbeat, p);
default:
- return -ENOIOCTLCMD;
+ return -ENOTTY;
}
}
diff --git a/drivers/char/watchdog/i8xx_tco.c b/drivers/char/watchdog/i8xx_tco.c
index 8385dd36eefe..e0627d79707b 100644
--- a/drivers/char/watchdog/i8xx_tco.c
+++ b/drivers/char/watchdog/i8xx_tco.c
@@ -356,7 +356,7 @@ static int i8xx_tco_ioctl (struct inode *inode, struct file *file,
}
default:
- return -ENOIOCTLCMD;
+ return -ENOTTY;
}
}
@@ -406,18 +406,18 @@ static struct notifier_block i8xx_tco_notifier = {
* want to register another driver on the same PCI id.
*/
static struct pci_device_id i8xx_tco_pci_tbl[] = {
- { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801AA_0, PCI_ANY_ID, PCI_ANY_ID, },
- { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801AB_0, PCI_ANY_ID, PCI_ANY_ID, },
- { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_0, PCI_ANY_ID, PCI_ANY_ID, },
- { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_10, PCI_ANY_ID, PCI_ANY_ID, },
- { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_0, PCI_ANY_ID, PCI_ANY_ID, },
- { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_12, PCI_ANY_ID, PCI_ANY_ID, },
- { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_0, PCI_ANY_ID, PCI_ANY_ID, },
- { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_12, PCI_ANY_ID, PCI_ANY_ID, },
- { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801E_0, PCI_ANY_ID, PCI_ANY_ID, },
- { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801EB_0, PCI_ANY_ID, PCI_ANY_ID, },
- { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ESB_1, PCI_ANY_ID, PCI_ANY_ID, },
- { 0, }, /* End of list */
+ { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801AA_0) },
+ { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801AB_0) },
+ { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_0) },
+ { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_10) },
+ { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_0) },
+ { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_12) },
+ { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_0) },
+ { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_12) },
+ { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801E_0) },
+ { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801EB_0) },
+ { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ESB_1) },
+ { }, /* End of list */
};
MODULE_DEVICE_TABLE (pci, i8xx_tco_pci_tbl);
@@ -434,12 +434,11 @@ static unsigned char __init i8xx_tco_getdevice (void)
* Find the PCI device
*/
- while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
+ for_each_pci_dev(dev)
if (pci_match_id(i8xx_tco_pci_tbl, dev)) {
i8xx_tco_pci = dev;
break;
}
- }
if (i8xx_tco_pci) {
/*
@@ -454,6 +453,7 @@ static unsigned char __init i8xx_tco_getdevice (void)
/* Something's wrong here, ACPIBASE has to be set */
if (badr == 0x0001 || badr == 0x0000) {
printk (KERN_ERR PFX "failed to get TCOBASE address\n");
+ pci_dev_put(i8xx_tco_pci);
return 0;
}
@@ -465,6 +465,7 @@ static unsigned char __init i8xx_tco_getdevice (void)
pci_read_config_byte (i8xx_tco_pci, 0xd4, &val1);
if (val1 & 0x02) {
printk (KERN_ERR PFX "failed to reset NO_REBOOT flag, reboot disabled by hardware\n");
+ pci_dev_put(i8xx_tco_pci);
return 0; /* Cannot reset NO_REBOOT bit */
}
}
@@ -476,6 +477,7 @@ static unsigned char __init i8xx_tco_getdevice (void)
if (!request_region (SMI_EN + 1, 1, "i8xx TCO")) {
printk (KERN_ERR PFX "I/O address 0x%04x already in use\n",
SMI_EN + 1);
+ pci_dev_put(i8xx_tco_pci);
return 0;
}
val1 = inb (SMI_EN + 1);
@@ -542,6 +544,7 @@ unreg_notifier:
unreg_region:
release_region (TCOBASE, 0x10);
out:
+ pci_dev_put(i8xx_tco_pci);
return ret;
}
@@ -555,6 +558,8 @@ static void __exit watchdog_cleanup (void)
misc_deregister (&i8xx_tco_miscdev);
unregister_reboot_notifier(&i8xx_tco_notifier);
release_region (TCOBASE, 0x10);
+
+ pci_dev_put(i8xx_tco_pci);
}
module_init(watchdog_init);
diff --git a/drivers/char/watchdog/ib700wdt.c b/drivers/char/watchdog/ib700wdt.c
index fd95f7327798..c1ed209a138c 100644
--- a/drivers/char/watchdog/ib700wdt.c
+++ b/drivers/char/watchdog/ib700wdt.c
@@ -199,7 +199,7 @@ ibwdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
break;
default:
- return -ENOIOCTLCMD;
+ return -ENOTTY;
}
return 0;
}
diff --git a/drivers/char/watchdog/ibmasr.c b/drivers/char/watchdog/ibmasr.c
index 26ceee7a4df0..dd6760f1a23b 100644
--- a/drivers/char/watchdog/ibmasr.c
+++ b/drivers/char/watchdog/ibmasr.c
@@ -295,7 +295,7 @@ static int asr_ioctl(struct inode *inode, struct file *file,
}
}
- return -ENOIOCTLCMD;
+ return -ENOTTY;
}
static int asr_open(struct inode *inode, struct file *file)
diff --git a/drivers/char/watchdog/indydog.c b/drivers/char/watchdog/indydog.c
index dacc1c20a310..0bc239308989 100644
--- a/drivers/char/watchdog/indydog.c
+++ b/drivers/char/watchdog/indydog.c
@@ -112,7 +112,7 @@ static int indydog_ioctl(struct inode *inode, struct file *file,
switch (cmd) {
default:
- return -ENOIOCTLCMD;
+ return -ENOTTY;
case WDIOC_GETSUPPORT:
if (copy_to_user((struct watchdog_info *)arg,
&ident, sizeof(ident)))
diff --git a/drivers/char/watchdog/ixp2000_wdt.c b/drivers/char/watchdog/ixp2000_wdt.c
index 692908819e26..c91d9a660ec0 100644
--- a/drivers/char/watchdog/ixp2000_wdt.c
+++ b/drivers/char/watchdog/ixp2000_wdt.c
@@ -107,7 +107,7 @@ static int
ixp2000_wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
unsigned long arg)
{
- int ret = -ENOIOCTLCMD;
+ int ret = -ENOTTY;
int time;
switch (cmd) {
diff --git a/drivers/char/watchdog/ixp4xx_wdt.c b/drivers/char/watchdog/ixp4xx_wdt.c
index 9db5cf2c38c3..db477f712388 100644
--- a/drivers/char/watchdog/ixp4xx_wdt.c
+++ b/drivers/char/watchdog/ixp4xx_wdt.c
@@ -102,7 +102,7 @@ static int
ixp4xx_wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
unsigned long arg)
{
- int ret = -ENOIOCTLCMD;
+ int ret = -ENOTTY;
int time;
switch (cmd) {
diff --git a/drivers/char/watchdog/machzwd.c b/drivers/char/watchdog/machzwd.c
index 23734e07fb22..276577d08fba 100644
--- a/drivers/char/watchdog/machzwd.c
+++ b/drivers/char/watchdog/machzwd.c
@@ -329,7 +329,7 @@ static int zf_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
break;
default:
- return -ENOIOCTLCMD;
+ return -ENOTTY;
}
return 0;
@@ -426,8 +426,7 @@ static int __init zf_init(void)
printk(KERN_INFO PFX ": MachZ ZF-Logic Watchdog driver initializing.\n");
ret = zf_get_ZFL_version();
- printk("%#x\n", ret);
- if((!ret) || (ret != 0xffff)){
+ if ((!ret) || (ret == 0xffff)) {
printk(KERN_WARNING PFX ": no ZF-Logic found\n");
return -ENODEV;
}
diff --git a/drivers/char/watchdog/mixcomwd.c b/drivers/char/watchdog/mixcomwd.c
index ae943324d251..c2dac0aa1d62 100644
--- a/drivers/char/watchdog/mixcomwd.c
+++ b/drivers/char/watchdog/mixcomwd.c
@@ -185,7 +185,7 @@ static int mixcomwd_ioctl(struct inode *inode, struct file *file,
mixcomwd_ping();
break;
default:
- return -ENOIOCTLCMD;
+ return -ENOTTY;
}
return 0;
}
diff --git a/drivers/char/watchdog/mpc83xx_wdt.c b/drivers/char/watchdog/mpc83xx_wdt.c
index a480903ee1a5..18ca752e2f90 100644
--- a/drivers/char/watchdog/mpc83xx_wdt.c
+++ b/drivers/char/watchdog/mpc83xx_wdt.c
@@ -125,7 +125,7 @@ static int mpc83xx_wdt_ioctl(struct inode *inode, struct file *file,
case WDIOC_GETTIMEOUT:
return put_user(timeout_sec, p);
default:
- return -ENOIOCTLCMD;
+ return -ENOTTY;
}
}
diff --git a/drivers/char/watchdog/mpc8xx_wdt.c b/drivers/char/watchdog/mpc8xx_wdt.c
index 35dd9e6e1140..8aaed10dd499 100644
--- a/drivers/char/watchdog/mpc8xx_wdt.c
+++ b/drivers/char/watchdog/mpc8xx_wdt.c
@@ -126,7 +126,7 @@ static int mpc8xx_wdt_ioctl(struct inode *inode, struct file *file,
break;
default:
- return -ENOIOCTLCMD;
+ return -ENOTTY;
}
return 0;
diff --git a/drivers/char/watchdog/mpcore_wdt.c b/drivers/char/watchdog/mpcore_wdt.c
index 54b3c56ead0d..02d336ace504 100644
--- a/drivers/char/watchdog/mpcore_wdt.c
+++ b/drivers/char/watchdog/mpcore_wdt.c
@@ -221,7 +221,7 @@ static int mpcore_wdt_ioctl(struct inode *inode, struct file *file,
} uarg;
if (_IOC_DIR(cmd) && _IOC_SIZE(cmd) > sizeof(uarg))
- return -ENOIOCTLCMD;
+ return -ENOTTY;
if (_IOC_DIR(cmd) & _IOC_WRITE) {
ret = copy_from_user(&uarg, (void __user *)arg, _IOC_SIZE(cmd));
@@ -271,7 +271,7 @@ static int mpcore_wdt_ioctl(struct inode *inode, struct file *file,
break;
default:
- return -ENOIOCTLCMD;
+ return -ENOTTY;
}
if (ret == 0 && _IOC_DIR(cmd) & _IOC_READ) {
diff --git a/drivers/char/watchdog/mv64x60_wdt.c b/drivers/char/watchdog/mv64x60_wdt.c
index 5c8fab345b40..b887cdb01334 100644
--- a/drivers/char/watchdog/mv64x60_wdt.c
+++ b/drivers/char/watchdog/mv64x60_wdt.c
@@ -160,7 +160,7 @@ static int mv64x60_wdt_ioctl(struct inode *inode, struct file *file,
break;
default:
- return -ENOIOCTLCMD;
+ return -ENOTTY;
}
return 0;
diff --git a/drivers/char/watchdog/omap_wdt.c b/drivers/char/watchdog/omap_wdt.c
new file mode 100644
index 000000000000..8f90b90a5021
--- /dev/null
+++ b/drivers/char/watchdog/omap_wdt.c
@@ -0,0 +1,391 @@
+/*
+ * linux/drivers/char/watchdog/omap_wdt.c
+ *
+ * Watchdog driver for the TI OMAP 16xx & 24xx 32KHz (non-secure) watchdog
+ *
+ * Author: MontaVista Software, Inc.
+ * <gdavis@mvista.com> or <source@mvista.com>
+ *
+ * 2003 (c) 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.
+ *
+ * History:
+ *
+ * 20030527: George G. Davis <gdavis@mvista.com>
+ * Initially based on linux-2.4.19-rmk7-pxa1/drivers/char/sa1100_wdt.c
+ * (c) Copyright 2000 Oleg Drokin <green@crimea.edu>
+ * Based on SoftDog driver by Alan Cox <alan@redhat.com>
+ *
+ * Copyright (c) 2004 Texas Instruments.
+ * 1. Modified to support OMAP1610 32-KHz watchdog timer
+ * 2. Ported to 2.6 kernel
+ *
+ * Copyright (c) 2005 David Brownell
+ * Use the driver model and standard identifiers; handle bigger timeouts.
+ */
+
+#include <linux/module.h>
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/fs.h>
+#include <linux/mm.h>
+#include <linux/miscdevice.h>
+#include <linux/watchdog.h>
+#include <linux/reboot.h>
+#include <linux/smp_lock.h>
+#include <linux/init.h>
+#include <linux/err.h>
+#include <linux/platform_device.h>
+#include <linux/moduleparam.h>
+#include <linux/clk.h>
+
+#include <asm/io.h>
+#include <asm/uaccess.h>
+#include <asm/hardware.h>
+#include <asm/bitops.h>
+
+#include <asm/arch/prcm.h>
+
+#include "omap_wdt.h"
+
+static unsigned timer_margin;
+module_param(timer_margin, uint, 0);
+MODULE_PARM_DESC(timer_margin, "initial watchdog timeout (in seconds)");
+
+static int omap_wdt_users;
+static struct clk *armwdt_ck = NULL;
+static struct clk *mpu_wdt_ick = NULL;
+static struct clk *mpu_wdt_fck = NULL;
+
+static unsigned int wdt_trgr_pattern = 0x1234;
+
+static void omap_wdt_ping(void)
+{
+ /* wait for posted write to complete */
+ while ((omap_readl(OMAP_WATCHDOG_WPS)) & 0x08)
+ cpu_relax();
+ wdt_trgr_pattern = ~wdt_trgr_pattern;
+ omap_writel(wdt_trgr_pattern, (OMAP_WATCHDOG_TGR));
+ /* wait for posted write to complete */
+ while ((omap_readl(OMAP_WATCHDOG_WPS)) & 0x08)
+ cpu_relax();
+ /* reloaded WCRR from WLDR */
+}
+
+static void omap_wdt_enable(void)
+{
+ /* Sequence to enable the watchdog */
+ omap_writel(0xBBBB, OMAP_WATCHDOG_SPR);
+ while ((omap_readl(OMAP_WATCHDOG_WPS)) & 0x10)
+ cpu_relax();
+ omap_writel(0x4444, OMAP_WATCHDOG_SPR);
+ while ((omap_readl(OMAP_WATCHDOG_WPS)) & 0x10)
+ cpu_relax();
+}
+
+static void omap_wdt_disable(void)
+{
+ /* sequence required to disable watchdog */
+ omap_writel(0xAAAA, OMAP_WATCHDOG_SPR); /* TIMER_MODE */
+ while (omap_readl(OMAP_WATCHDOG_WPS) & 0x10)
+ cpu_relax();
+ omap_writel(0x5555, OMAP_WATCHDOG_SPR); /* TIMER_MODE */
+ while (omap_readl(OMAP_WATCHDOG_WPS) & 0x10)
+ cpu_relax();
+}
+
+static void omap_wdt_adjust_timeout(unsigned new_timeout)
+{
+ if (new_timeout < TIMER_MARGIN_MIN)
+ new_timeout = TIMER_MARGIN_DEFAULT;
+ if (new_timeout > TIMER_MARGIN_MAX)
+ new_timeout = TIMER_MARGIN_MAX;
+ timer_margin = new_timeout;
+}
+
+static void omap_wdt_set_timeout(void)
+{
+ u32 pre_margin = GET_WLDR_VAL(timer_margin);
+
+ /* just count up at 32 KHz */
+ while (omap_readl(OMAP_WATCHDOG_WPS) & 0x04)
+ cpu_relax();
+ omap_writel(pre_margin, OMAP_WATCHDOG_LDR);
+ while (omap_readl(OMAP_WATCHDOG_WPS) & 0x04)
+ cpu_relax();
+}
+
+/*
+ * Allow only one task to hold it open
+ */
+
+static int omap_wdt_open(struct inode *inode, struct file *file)
+{
+ if (test_and_set_bit(1, (unsigned long *)&omap_wdt_users))
+ return -EBUSY;
+
+ if (cpu_is_omap16xx())
+ clk_enable(armwdt_ck); /* Enable the clock */
+
+ if (cpu_is_omap24xx()) {
+ clk_enable(mpu_wdt_ick); /* Enable the interface clock */
+ clk_enable(mpu_wdt_fck); /* Enable the functional clock */
+ }
+
+ /* initialize prescaler */
+ while (omap_readl(OMAP_WATCHDOG_WPS) & 0x01)
+ cpu_relax();
+ omap_writel((1 << 5) | (PTV << 2), OMAP_WATCHDOG_CNTRL);
+ while (omap_readl(OMAP_WATCHDOG_WPS) & 0x01)
+ cpu_relax();
+
+ omap_wdt_set_timeout();
+ omap_wdt_enable();
+ return 0;
+}
+
+static int omap_wdt_release(struct inode *inode, struct file *file)
+{
+ /*
+ * Shut off the timer unless NOWAYOUT is defined.
+ */
+#ifndef CONFIG_WATCHDOG_NOWAYOUT
+ omap_wdt_disable();
+
+ if (cpu_is_omap16xx()) {
+ clk_disable(armwdt_ck); /* Disable the clock */
+ clk_put(armwdt_ck);
+ armwdt_ck = NULL;
+ }
+
+ if (cpu_is_omap24xx()) {
+ clk_disable(mpu_wdt_ick); /* Disable the clock */
+ clk_disable(mpu_wdt_fck); /* Disable the clock */
+ clk_put(mpu_wdt_ick);
+ clk_put(mpu_wdt_fck);
+ mpu_wdt_ick = NULL;
+ mpu_wdt_fck = NULL;
+ }
+#else
+ printk(KERN_CRIT "omap_wdt: Unexpected close, not stopping!\n");
+#endif
+ omap_wdt_users = 0;
+ return 0;
+}
+
+static ssize_t
+omap_wdt_write(struct file *file, const char __user *data,
+ size_t len, loff_t *ppos)
+{
+ /* Refresh LOAD_TIME. */
+ if (len)
+ omap_wdt_ping();
+ return len;
+}
+
+static int
+omap_wdt_ioctl(struct inode *inode, struct file *file,
+ unsigned int cmd, unsigned long arg)
+{
+ int new_margin;
+ static struct watchdog_info ident = {
+ .identity = "OMAP Watchdog",
+ .options = WDIOF_SETTIMEOUT,
+ .firmware_version = 0,
+ };
+
+ switch (cmd) {
+ default:
+ return -ENOIOCTLCMD;
+ case WDIOC_GETSUPPORT:
+ return copy_to_user((struct watchdog_info __user *)arg, &ident,
+ sizeof(ident));
+ case WDIOC_GETSTATUS:
+ return put_user(0, (int __user *)arg);
+ case WDIOC_GETBOOTSTATUS:
+ if (cpu_is_omap16xx())
+ return put_user(omap_readw(ARM_SYSST),
+ (int __user *)arg);
+ if (cpu_is_omap24xx())
+ return put_user(omap_prcm_get_reset_sources(),
+ (int __user *)arg);
+ case WDIOC_KEEPALIVE:
+ omap_wdt_ping();
+ return 0;
+ case WDIOC_SETTIMEOUT:
+ if (get_user(new_margin, (int __user *)arg))
+ return -EFAULT;
+ omap_wdt_adjust_timeout(new_margin);
+
+ omap_wdt_disable();
+ omap_wdt_set_timeout();
+ omap_wdt_enable();
+
+ omap_wdt_ping();
+ /* Fall */
+ case WDIOC_GETTIMEOUT:
+ return put_user(timer_margin, (int __user *)arg);
+ }
+}
+
+static struct file_operations omap_wdt_fops = {
+ .owner = THIS_MODULE,
+ .write = omap_wdt_write,
+ .ioctl = omap_wdt_ioctl,
+ .open = omap_wdt_open,
+ .release = omap_wdt_release,
+};
+
+static struct miscdevice omap_wdt_miscdev = {
+ .minor = WATCHDOG_MINOR,
+ .name = "watchdog",
+ .fops = &omap_wdt_fops
+};
+
+static int __init omap_wdt_probe(struct platform_device *pdev)
+{
+ struct resource *res, *mem;
+ int ret;
+
+ /* reserve static register mappings */
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!res)
+ return -ENOENT;
+
+ mem = request_mem_region(res->start, res->end - res->start + 1,
+ pdev->name);
+ if (mem == NULL)
+ return -EBUSY;
+
+ platform_set_drvdata(pdev, mem);
+
+ omap_wdt_users = 0;
+
+ if (cpu_is_omap16xx()) {
+ armwdt_ck = clk_get(&pdev->dev, "armwdt_ck");
+ if (IS_ERR(armwdt_ck)) {
+ ret = PTR_ERR(armwdt_ck);
+ armwdt_ck = NULL;
+ goto fail;
+ }
+ }
+
+ if (cpu_is_omap24xx()) {
+ mpu_wdt_ick = clk_get(&pdev->dev, "mpu_wdt_ick");
+ if (IS_ERR(mpu_wdt_ick)) {
+ ret = PTR_ERR(mpu_wdt_ick);
+ mpu_wdt_ick = NULL;
+ goto fail;
+ }
+ mpu_wdt_fck = clk_get(&pdev->dev, "mpu_wdt_fck");
+ if (IS_ERR(mpu_wdt_fck)) {
+ ret = PTR_ERR(mpu_wdt_fck);
+ mpu_wdt_fck = NULL;
+ goto fail;
+ }
+ }
+
+ omap_wdt_disable();
+ omap_wdt_adjust_timeout(timer_margin);
+
+ omap_wdt_miscdev.dev = &pdev->dev;
+ ret = misc_register(&omap_wdt_miscdev);
+ if (ret)
+ goto fail;
+
+ pr_info("OMAP Watchdog Timer: initial timeout %d sec\n", timer_margin);
+
+ /* autogate OCP interface clock */
+ omap_writel(0x01, OMAP_WATCHDOG_SYS_CONFIG);
+ return 0;
+
+fail:
+ if (armwdt_ck)
+ clk_put(armwdt_ck);
+ if (mpu_wdt_ick)
+ clk_put(mpu_wdt_ick);
+ if (mpu_wdt_fck)
+ clk_put(mpu_wdt_fck);
+ release_resource(mem);
+ return ret;
+}
+
+static void omap_wdt_shutdown(struct platform_device *pdev)
+{
+ omap_wdt_disable();
+}
+
+static int omap_wdt_remove(struct platform_device *pdev)
+{
+ struct resource *mem = platform_get_drvdata(pdev);
+ misc_deregister(&omap_wdt_miscdev);
+ release_resource(mem);
+ if (armwdt_ck)
+ clk_put(armwdt_ck);
+ if (mpu_wdt_ick)
+ clk_put(mpu_wdt_ick);
+ if (mpu_wdt_fck)
+ clk_put(mpu_wdt_fck);
+ return 0;
+}
+
+#ifdef CONFIG_PM
+
+/* REVISIT ... not clear this is the best way to handle system suspend; and
+ * it's very inappropriate for selective device suspend (e.g. suspending this
+ * through sysfs rather than by stopping the watchdog daemon). Also, this
+ * may not play well enough with NOWAYOUT...
+ */
+
+static int omap_wdt_suspend(struct platform_device *pdev, pm_message_t state)
+{
+ if (omap_wdt_users)
+ omap_wdt_disable();
+ return 0;
+}
+
+static int omap_wdt_resume(struct platform_device *pdev)
+{
+ if (omap_wdt_users) {
+ omap_wdt_enable();
+ omap_wdt_ping();
+ }
+ return 0;
+}
+
+#else
+#define omap_wdt_suspend NULL
+#define omap_wdt_resume NULL
+#endif
+
+static struct platform_driver omap_wdt_driver = {
+ .probe = omap_wdt_probe,
+ .remove = omap_wdt_remove,
+ .shutdown = omap_wdt_shutdown,
+ .suspend = omap_wdt_suspend,
+ .resume = omap_wdt_resume,
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = "omap_wdt",
+ },
+};
+
+static int __init omap_wdt_init(void)
+{
+ return platform_driver_register(&omap_wdt_driver);
+}
+
+static void __exit omap_wdt_exit(void)
+{
+ platform_driver_unregister(&omap_wdt_driver);
+}
+
+module_init(omap_wdt_init);
+module_exit(omap_wdt_exit);
+
+MODULE_AUTHOR("George G. Davis");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
diff --git a/drivers/char/watchdog/omap_wdt.h b/drivers/char/watchdog/omap_wdt.h
new file mode 100644
index 000000000000..52a532a5114a
--- /dev/null
+++ b/drivers/char/watchdog/omap_wdt.h
@@ -0,0 +1,64 @@
+/*
+ * linux/drivers/char/watchdog/omap_wdt.h
+ *
+ * BRIEF MODULE DESCRIPTION
+ * OMAP Watchdog timer register definitions
+ *
+ * Copyright (C) 2004 Texas Instruments.
+ *
+ * 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 SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * 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.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef _OMAP_WATCHDOG_H
+#define _OMAP_WATCHDOG_H
+
+#define OMAP1610_WATCHDOG_BASE 0xfffeb000
+#define OMAP2420_WATCHDOG_BASE 0x48022000 /*WDT Timer 2 */
+
+#ifdef CONFIG_ARCH_OMAP24XX
+#define OMAP_WATCHDOG_BASE OMAP2420_WATCHDOG_BASE
+#else
+#define OMAP_WATCHDOG_BASE OMAP1610_WATCHDOG_BASE
+#define RM_RSTST_WKUP 0
+#endif
+
+#define OMAP_WATCHDOG_REV (OMAP_WATCHDOG_BASE + 0x00)
+#define OMAP_WATCHDOG_SYS_CONFIG (OMAP_WATCHDOG_BASE + 0x10)
+#define OMAP_WATCHDOG_STATUS (OMAP_WATCHDOG_BASE + 0x14)
+#define OMAP_WATCHDOG_CNTRL (OMAP_WATCHDOG_BASE + 0x24)
+#define OMAP_WATCHDOG_CRR (OMAP_WATCHDOG_BASE + 0x28)
+#define OMAP_WATCHDOG_LDR (OMAP_WATCHDOG_BASE + 0x2c)
+#define OMAP_WATCHDOG_TGR (OMAP_WATCHDOG_BASE + 0x30)
+#define OMAP_WATCHDOG_WPS (OMAP_WATCHDOG_BASE + 0x34)
+#define OMAP_WATCHDOG_SPR (OMAP_WATCHDOG_BASE + 0x48)
+
+/* Using the prescaler, the OMAP watchdog could go for many
+ * months before firing. These limits work without scaling,
+ * with the 60 second default assumed by most tools and docs.
+ */
+#define TIMER_MARGIN_MAX (24 * 60 * 60) /* 1 day */
+#define TIMER_MARGIN_DEFAULT 60 /* 60 secs */
+#define TIMER_MARGIN_MIN 1
+
+#define PTV 0 /* prescale */
+#define GET_WLDR_VAL(secs) (0xffffffff - ((secs) * (32768/(1<<PTV))) + 1)
+
+#endif /* _OMAP_WATCHDOG_H */
diff --git a/drivers/char/watchdog/pcwd.c b/drivers/char/watchdog/pcwd.c
index cd7d1b6a5d9f..6f8515db5b07 100644
--- a/drivers/char/watchdog/pcwd.c
+++ b/drivers/char/watchdog/pcwd.c
@@ -572,7 +572,7 @@ static int pcwd_ioctl(struct inode *inode, struct file *file,
switch(cmd) {
default:
- return -ENOIOCTLCMD;
+ return -ENOTTY;
case WDIOC_GETSUPPORT:
if(copy_to_user(argp, &ident, sizeof(ident)))
diff --git a/drivers/char/watchdog/pcwd_pci.c b/drivers/char/watchdog/pcwd_pci.c
index c7cfd6dbfe1b..2de6e497c140 100644
--- a/drivers/char/watchdog/pcwd_pci.c
+++ b/drivers/char/watchdog/pcwd_pci.c
@@ -541,7 +541,7 @@ static int pcipcwd_ioctl(struct inode *inode, struct file *file,
}
default:
- return -ENOIOCTLCMD;
+ return -ENOTTY;
}
}
diff --git a/drivers/char/watchdog/pcwd_usb.c b/drivers/char/watchdog/pcwd_usb.c
index b7ae73dcdd08..77662cb0ac46 100644
--- a/drivers/char/watchdog/pcwd_usb.c
+++ b/drivers/char/watchdog/pcwd_usb.c
@@ -445,7 +445,7 @@ static int usb_pcwd_ioctl(struct inode *inode, struct file *file,
}
default:
- return -ENOIOCTLCMD;
+ return -ENOTTY;
}
}
diff --git a/drivers/char/watchdog/pnx4008_wdt.c b/drivers/char/watchdog/pnx4008_wdt.c
new file mode 100644
index 000000000000..e7f0450a939d
--- /dev/null
+++ b/drivers/char/watchdog/pnx4008_wdt.c
@@ -0,0 +1,362 @@
+/*
+ * drivers/char/watchdog/pnx4008_wdt.c
+ *
+ * Watchdog driver for PNX4008 board
+ *
+ * Authors: Dmitry Chigirev <source@mvista.com>,
+ * Vitaly Wool <vitalywool@gmail.com>
+ * Based on sa1100 driver,
+ * Copyright (C) 2000 Oleg Drokin <green@crimea.edu>
+ *
+ * 2005-2006 (c) 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 <linux/config.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/fs.h>
+#include <linux/miscdevice.h>
+#include <linux/watchdog.h>
+#include <linux/init.h>
+#include <linux/bitops.h>
+#include <linux/ioport.h>
+#include <linux/device.h>
+#include <linux/platform_device.h>
+#include <linux/clk.h>
+#include <linux/spinlock.h>
+
+#include <asm/hardware.h>
+#include <asm/uaccess.h>
+#include <asm/io.h>
+
+#define MODULE_NAME "PNX4008-WDT: "
+
+/* WatchDog Timer - Chapter 23 Page 207 */
+
+#define DEFAULT_HEARTBEAT 19
+#define MAX_HEARTBEAT 60
+
+/* Watchdog timer register set definition */
+#define WDTIM_INT(p) ((p) + 0x0)
+#define WDTIM_CTRL(p) ((p) + 0x4)
+#define WDTIM_COUNTER(p) ((p) + 0x8)
+#define WDTIM_MCTRL(p) ((p) + 0xC)
+#define WDTIM_MATCH0(p) ((p) + 0x10)
+#define WDTIM_EMR(p) ((p) + 0x14)
+#define WDTIM_PULSE(p) ((p) + 0x18)
+#define WDTIM_RES(p) ((p) + 0x1C)
+
+/* WDTIM_INT bit definitions */
+#define MATCH_INT 1
+
+/* WDTIM_CTRL bit definitions */
+#define COUNT_ENAB 1
+#define RESET_COUNT (1<<1)
+#define DEBUG_EN (1<<2)
+
+/* WDTIM_MCTRL bit definitions */
+#define MR0_INT 1
+#undef RESET_COUNT0
+#define RESET_COUNT0 (1<<2)
+#define STOP_COUNT0 (1<<2)
+#define M_RES1 (1<<3)
+#define M_RES2 (1<<4)
+#define RESFRC1 (1<<5)
+#define RESFRC2 (1<<6)
+
+/* WDTIM_EMR bit definitions */
+#define EXT_MATCH0 1
+#define MATCH_OUTPUT_HIGH (2<<4) /*a MATCH_CTRL setting */
+
+/* WDTIM_RES bit definitions */
+#define WDOG_RESET 1 /* read only */
+
+#define WDOG_COUNTER_RATE 13000000 /*the counter clock is 13 MHz fixed */
+
+static int nowayout = WATCHDOG_NOWAYOUT;
+static int heartbeat = DEFAULT_HEARTBEAT;
+
+static spinlock_t io_lock;
+static unsigned long wdt_status;
+#define WDT_IN_USE 0
+#define WDT_OK_TO_CLOSE 1
+#define WDT_REGION_INITED 2
+#define WDT_DEVICE_INITED 3
+
+static unsigned long boot_status;
+
+static struct resource *wdt_mem;
+static void __iomem *wdt_base;
+struct clk *wdt_clk;
+
+static void wdt_enable(void)
+{
+ spin_lock(&io_lock);
+
+ if (wdt_clk)
+ clk_set_rate(wdt_clk, 1);
+
+ /* stop counter, initiate counter reset */
+ __raw_writel(RESET_COUNT, WDTIM_CTRL(wdt_base));
+ /*wait for reset to complete. 100% guarantee event */
+ while (__raw_readl(WDTIM_COUNTER(wdt_base)))
+ cpu_relax();
+ /* internal and external reset, stop after that */
+ __raw_writel(M_RES2 | STOP_COUNT0 | RESET_COUNT0,
+ WDTIM_MCTRL(wdt_base));
+ /* configure match output */
+ __raw_writel(MATCH_OUTPUT_HIGH, WDTIM_EMR(wdt_base));
+ /* clear interrupt, just in case */
+ __raw_writel(MATCH_INT, WDTIM_INT(wdt_base));
+ /* the longest pulse period 65541/(13*10^6) seconds ~ 5 ms. */
+ __raw_writel(0xFFFF, WDTIM_PULSE(wdt_base));
+ __raw_writel(heartbeat * WDOG_COUNTER_RATE, WDTIM_MATCH0(wdt_base));
+ /*enable counter, stop when debugger active */
+ __raw_writel(COUNT_ENAB | DEBUG_EN, WDTIM_CTRL(wdt_base));
+
+ spin_unlock(&io_lock);
+}
+
+static void wdt_disable(void)
+{
+ spin_lock(&io_lock);
+
+ __raw_writel(0, WDTIM_CTRL(wdt_base)); /*stop counter */
+ if (wdt_clk)
+ clk_set_rate(wdt_clk, 0);
+
+ spin_unlock(&io_lock);
+}
+
+static int pnx4008_wdt_open(struct inode *inode, struct file *file)
+{
+ if (test_and_set_bit(WDT_IN_USE, &wdt_status))
+ return -EBUSY;
+
+ clear_bit(WDT_OK_TO_CLOSE, &wdt_status);
+
+ wdt_enable();
+
+ return nonseekable_open(inode, file);
+}
+
+static ssize_t
+pnx4008_wdt_write(struct file *file, const char *data, size_t len,
+ loff_t * ppos)
+{
+ /* Can't seek (pwrite) on this device */
+ if (ppos != &file->f_pos)
+ return -ESPIPE;
+
+ if (len) {
+ if (!nowayout) {
+ size_t i;
+
+ clear_bit(WDT_OK_TO_CLOSE, &wdt_status);
+
+ for (i = 0; i != len; i++) {
+ char c;
+
+ if (get_user(c, data + i))
+ return -EFAULT;
+ if (c == 'V')
+ set_bit(WDT_OK_TO_CLOSE, &wdt_status);
+ }
+ }
+ wdt_enable();
+ }
+
+ return len;
+}
+
+static struct watchdog_info ident = {
+ .options = WDIOF_CARDRESET | WDIOF_MAGICCLOSE |
+ WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING,
+ .identity = "PNX4008 Watchdog",
+};
+
+static int
+pnx4008_wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
+ unsigned long arg)
+{
+ int ret = -ENOIOCTLCMD;
+ int time;
+
+ switch (cmd) {
+ case WDIOC_GETSUPPORT:
+ ret = copy_to_user((struct watchdog_info *)arg, &ident,
+ sizeof(ident)) ? -EFAULT : 0;
+ break;
+
+ case WDIOC_GETSTATUS:
+ ret = put_user(0, (int *)arg);
+ break;
+
+ case WDIOC_GETBOOTSTATUS:
+ ret = put_user(boot_status, (int *)arg);
+ break;
+
+ case WDIOC_SETTIMEOUT:
+ ret = get_user(time, (int *)arg);
+ if (ret)
+ break;
+
+ if (time <= 0 || time > MAX_HEARTBEAT) {
+ ret = -EINVAL;
+ break;
+ }
+
+ heartbeat = time;
+ wdt_enable();
+ /* Fall through */
+
+ case WDIOC_GETTIMEOUT:
+ ret = put_user(heartbeat, (int *)arg);
+ break;
+
+ case WDIOC_KEEPALIVE:
+ wdt_enable();
+ ret = 0;
+ break;
+ }
+ return ret;
+}
+
+static int pnx4008_wdt_release(struct inode *inode, struct file *file)
+{
+ if (!test_bit(WDT_OK_TO_CLOSE, &wdt_status))
+ printk(KERN_WARNING "WATCHDOG: Device closed unexpectdly\n");
+
+ wdt_disable();
+ clear_bit(WDT_IN_USE, &wdt_status);
+ clear_bit(WDT_OK_TO_CLOSE, &wdt_status);
+
+ return 0;
+}
+
+static struct file_operations pnx4008_wdt_fops = {
+ .owner = THIS_MODULE,
+ .llseek = no_llseek,
+ .write = pnx4008_wdt_write,
+ .ioctl = pnx4008_wdt_ioctl,
+ .open = pnx4008_wdt_open,
+ .release = pnx4008_wdt_release,
+};
+
+static struct miscdevice pnx4008_wdt_miscdev = {
+ .minor = WATCHDOG_MINOR,
+ .name = "watchdog",
+ .fops = &pnx4008_wdt_fops,
+};
+
+static int pnx4008_wdt_probe(struct platform_device *pdev)
+{
+ int ret = 0, size;
+ struct resource *res;
+
+ spin_lock_init(&io_lock);
+
+ if (heartbeat < 1 || heartbeat > MAX_HEARTBEAT)
+ heartbeat = DEFAULT_HEARTBEAT;
+
+ printk(KERN_INFO MODULE_NAME
+ "PNX4008 Watchdog Timer: heartbeat %d sec\n", heartbeat);
+
+ 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 = res->end - res->start + 1;
+ wdt_mem = request_mem_region(res->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(res->start);
+
+ wdt_clk = clk_get(&pdev->dev, "wdt_ck");
+ if (!wdt_clk) {
+ release_resource(wdt_mem);
+ kfree(wdt_mem);
+ goto out;
+ } else
+ clk_set_rate(wdt_clk, 1);
+
+ ret = misc_register(&pnx4008_wdt_miscdev);
+ if (ret < 0) {
+ printk(KERN_ERR MODULE_NAME "cannot register misc device\n");
+ release_resource(wdt_mem);
+ kfree(wdt_mem);
+ clk_set_rate(wdt_clk, 0);
+ } else {
+ boot_status = (__raw_readl(WDTIM_RES(wdt_base)) & WDOG_RESET) ?
+ WDIOF_CARDRESET : 0;
+ wdt_disable(); /*disable for now */
+ set_bit(WDT_DEVICE_INITED, &wdt_status);
+ }
+
+out:
+ return ret;
+}
+
+static int pnx4008_wdt_remove(struct platform_device *pdev)
+{
+ misc_deregister(&pnx4008_wdt_miscdev);
+ if (wdt_clk) {
+ clk_set_rate(wdt_clk, 0);
+ clk_put(wdt_clk);
+ wdt_clk = NULL;
+ }
+ if (wdt_mem) {
+ release_resource(wdt_mem);
+ kfree(wdt_mem);
+ wdt_mem = NULL;
+ }
+ return 0;
+}
+
+static struct platform_driver platform_wdt_driver = {
+ .driver = {
+ .name = "watchdog",
+ },
+ .probe = pnx4008_wdt_probe,
+ .remove = pnx4008_wdt_remove,
+};
+
+static int __init pnx4008_wdt_init(void)
+{
+ return platform_driver_register(&platform_wdt_driver);
+}
+
+static void __exit pnx4008_wdt_exit(void)
+{
+ return platform_driver_unregister(&platform_wdt_driver);
+}
+
+module_init(pnx4008_wdt_init);
+module_exit(pnx4008_wdt_exit);
+
+MODULE_AUTHOR("MontaVista Software, Inc. <source@mvista.com>");
+MODULE_DESCRIPTION("PNX4008 Watchdog Driver");
+
+module_param(heartbeat, int, 0);
+MODULE_PARM_DESC(heartbeat,
+ "Watchdog heartbeat period in seconds from 1 to "
+ __MODULE_STRING(MAX_HEARTBEAT) ", default "
+ __MODULE_STRING(DEFAULT_HEARTBEAT));
+
+module_param(nowayout, int, 0);
+MODULE_PARM_DESC(nowayout,
+ "Set to 1 to keep watchdog running after device release");
+
+MODULE_LICENSE("GPL");
+MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
diff --git a/drivers/char/watchdog/s3c2410_wdt.c b/drivers/char/watchdog/s3c2410_wdt.c
index be978e8ed754..b36a04ae9ab8 100644
--- a/drivers/char/watchdog/s3c2410_wdt.c
+++ b/drivers/char/watchdog/s3c2410_wdt.c
@@ -62,7 +62,7 @@
#define CONFIG_S3C2410_WATCHDOG_ATBOOT (0)
#define CONFIG_S3C2410_WATCHDOG_DEFAULT_TIME (15)
-static int nowayout = WATCHDOG_NOWAYOUT;
+static int nowayout = WATCHDOG_NOWAYOUT;
static int tmr_margin = CONFIG_S3C2410_WATCHDOG_DEFAULT_TIME;
static int tmr_atboot = CONFIG_S3C2410_WATCHDOG_ATBOOT;
static int soft_noboot = 0;
@@ -213,11 +213,10 @@ static int s3c2410wdt_open(struct inode *inode, struct file *file)
if(down_trylock(&open_lock))
return -EBUSY;
- if (nowayout) {
+ if (nowayout)
__module_get(THIS_MODULE);
- } else {
- allow_close = CLOSE_STATE_ALLOW;
- }
+
+ allow_close = CLOSE_STATE_NOT;
/* start the timer */
s3c2410wdt_start();
@@ -230,6 +229,7 @@ static int s3c2410wdt_release(struct inode *inode, struct file *file)
* Shut off the timer.
* Lock it in if it's a module and we set nowayout
*/
+
if (allow_close == CLOSE_STATE_ALLOW) {
s3c2410wdt_stop();
} else {
@@ -288,7 +288,7 @@ static int s3c2410wdt_ioctl(struct inode *inode, struct file *file,
switch (cmd) {
default:
- return -ENOIOCTLCMD;
+ return -ENOTTY;
case WDIOC_GETSUPPORT:
return copy_to_user(argp, &s3c2410_wdt_ident,
diff --git a/drivers/char/watchdog/sa1100_wdt.c b/drivers/char/watchdog/sa1100_wdt.c
index 1fc16d995788..33c1137f17d6 100644
--- a/drivers/char/watchdog/sa1100_wdt.c
+++ b/drivers/char/watchdog/sa1100_wdt.c
@@ -90,7 +90,7 @@ static struct watchdog_info ident = {
static int sa1100dog_ioctl(struct inode *inode, struct file *file,
unsigned int cmd, unsigned long arg)
{
- int ret = -ENOIOCTLCMD;
+ int ret = -ENOTTY;
int time;
void __user *argp = (void __user *)arg;
int __user *p = argp;
diff --git a/drivers/char/watchdog/sbc60xxwdt.c b/drivers/char/watchdog/sbc60xxwdt.c
index 4663c2fd53cd..c7b2045bc76b 100644
--- a/drivers/char/watchdog/sbc60xxwdt.c
+++ b/drivers/char/watchdog/sbc60xxwdt.c
@@ -235,7 +235,7 @@ static int fop_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
switch(cmd)
{
default:
- return -ENOIOCTLCMD;
+ return -ENOTTY;
case WDIOC_GETSUPPORT:
return copy_to_user(argp, &ident, sizeof(ident))?-EFAULT:0;
case WDIOC_GETSTATUS:
diff --git a/drivers/char/watchdog/sbc_epx_c3.c b/drivers/char/watchdog/sbc_epx_c3.c
index bfc475dabe6d..8882b427d24f 100644
--- a/drivers/char/watchdog/sbc_epx_c3.c
+++ b/drivers/char/watchdog/sbc_epx_c3.c
@@ -141,7 +141,7 @@ static int epx_c3_ioctl(struct inode *inode, struct file *file,
return retval;
default:
- return -ENOIOCTLCMD;
+ return -ENOTTY;
}
}
diff --git a/drivers/char/watchdog/sc1200wdt.c b/drivers/char/watchdog/sc1200wdt.c
index 7c3cf293a5af..d8d0f28e0acf 100644
--- a/drivers/char/watchdog/sc1200wdt.c
+++ b/drivers/char/watchdog/sc1200wdt.c
@@ -180,7 +180,7 @@ static int sc1200wdt_ioctl(struct inode *inode, struct file *file, unsigned int
switch (cmd) {
default:
- return -ENOIOCTLCMD; /* Keep Pavel Machek amused ;) */
+ return -ENOTTY;
case WDIOC_GETSUPPORT:
if (copy_to_user(argp, &ident, sizeof ident))
diff --git a/drivers/char/watchdog/sc520_wdt.c b/drivers/char/watchdog/sc520_wdt.c
index 2c7c9db71be8..caec37ba750a 100644
--- a/drivers/char/watchdog/sc520_wdt.c
+++ b/drivers/char/watchdog/sc520_wdt.c
@@ -290,7 +290,7 @@ static int fop_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
switch(cmd)
{
default:
- return -ENOIOCTLCMD;
+ return -ENOTTY;
case WDIOC_GETSUPPORT:
return copy_to_user(argp, &ident, sizeof(ident))?-EFAULT:0;
case WDIOC_GETSTATUS:
diff --git a/drivers/char/watchdog/scx200_wdt.c b/drivers/char/watchdog/scx200_wdt.c
index c561299a5537..fc0e0347f9d2 100644
--- a/drivers/char/watchdog/scx200_wdt.c
+++ b/drivers/char/watchdog/scx200_wdt.c
@@ -166,7 +166,7 @@ static int scx200_wdt_ioctl(struct inode *inode, struct file *file,
switch (cmd) {
default:
- return -ENOIOCTLCMD;
+ return -ENOTTY;
case WDIOC_GETSUPPORT:
if(copy_to_user(argp, &ident, sizeof(ident)))
return -EFAULT;
diff --git a/drivers/char/watchdog/shwdt.c b/drivers/char/watchdog/shwdt.c
index e5b8c64f1d65..dc403629aeb3 100644
--- a/drivers/char/watchdog/shwdt.c
+++ b/drivers/char/watchdog/shwdt.c
@@ -360,7 +360,7 @@ static int sh_wdt_ioctl(struct inode *inode, struct file *file,
return retval;
default:
- return -ENOIOCTLCMD;
+ return -ENOTTY;
}
return 0;
diff --git a/drivers/char/watchdog/softdog.c b/drivers/char/watchdog/softdog.c
index ef8da517545a..4067e1f8a368 100644
--- a/drivers/char/watchdog/softdog.c
+++ b/drivers/char/watchdog/softdog.c
@@ -203,7 +203,7 @@ static int softdog_ioctl(struct inode *inode, struct file *file,
};
switch (cmd) {
default:
- return -ENOIOCTLCMD;
+ return -ENOTTY;
case WDIOC_GETSUPPORT:
return copy_to_user(argp, &ident,
sizeof(ident)) ? -EFAULT : 0;
diff --git a/drivers/char/watchdog/w83627hf_wdt.c b/drivers/char/watchdog/w83627hf_wdt.c
index 13f16d41c2fd..b4adc527e687 100644
--- a/drivers/char/watchdog/w83627hf_wdt.c
+++ b/drivers/char/watchdog/w83627hf_wdt.c
@@ -223,7 +223,7 @@ wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
}
default:
- return -ENOIOCTLCMD;
+ return -ENOTTY;
}
return 0;
}
diff --git a/drivers/char/watchdog/w83877f_wdt.c b/drivers/char/watchdog/w83877f_wdt.c
index ccf6c0915945..b0e5f84d6baf 100644
--- a/drivers/char/watchdog/w83877f_wdt.c
+++ b/drivers/char/watchdog/w83877f_wdt.c
@@ -252,7 +252,7 @@ static int fop_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
switch(cmd)
{
default:
- return -ENOIOCTLCMD;
+ return -ENOTTY;
case WDIOC_GETSUPPORT:
return copy_to_user(argp, &ident, sizeof(ident))?-EFAULT:0;
case WDIOC_GETSTATUS:
diff --git a/drivers/char/watchdog/w83977f_wdt.c b/drivers/char/watchdog/w83977f_wdt.c
index 98f4e17db70a..2c8d5d8bd4e8 100644
--- a/drivers/char/watchdog/w83977f_wdt.c
+++ b/drivers/char/watchdog/w83977f_wdt.c
@@ -393,7 +393,7 @@ static int wdt_ioctl(struct inode *inode, struct file *file,
switch(cmd)
{
default:
- return -ENOIOCTLCMD;
+ return -ENOTTY;
case WDIOC_GETSUPPORT:
return copy_to_user(uarg.ident, &ident, sizeof(ident)) ? -EFAULT : 0;
diff --git a/drivers/char/watchdog/wafer5823wdt.c b/drivers/char/watchdog/wafer5823wdt.c
index 2bb6a9d6ad28..163e028ef9ed 100644
--- a/drivers/char/watchdog/wafer5823wdt.c
+++ b/drivers/char/watchdog/wafer5823wdt.c
@@ -174,7 +174,7 @@ static int wafwdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd
}
default:
- return -ENOIOCTLCMD;
+ return -ENOTTY;
}
return 0;
}
diff --git a/drivers/char/watchdog/wdrtas.c b/drivers/char/watchdog/wdrtas.c
index 5c38cdf41731..1d64e277567d 100644
--- a/drivers/char/watchdog/wdrtas.c
+++ b/drivers/char/watchdog/wdrtas.c
@@ -385,7 +385,7 @@ wdrtas_ioctl(struct inode *inode, struct file *file,
return put_user(wdrtas_interval, argp);
default:
- return -ENOIOCTLCMD;
+ return -ENOTTY;
}
}
diff --git a/drivers/char/watchdog/wdt.c b/drivers/char/watchdog/wdt.c
index 70be81e39a61..13f23f4a2233 100644
--- a/drivers/char/watchdog/wdt.c
+++ b/drivers/char/watchdog/wdt.c
@@ -341,7 +341,7 @@ static int wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
switch(cmd)
{
default:
- return -ENOIOCTLCMD;
+ return -ENOTTY;
case WDIOC_GETSUPPORT:
return copy_to_user(argp, &ident, sizeof(ident))?-EFAULT:0;
diff --git a/drivers/char/watchdog/wdt285.c b/drivers/char/watchdog/wdt285.c
index 6555fb844f23..89a249e23fde 100644
--- a/drivers/char/watchdog/wdt285.c
+++ b/drivers/char/watchdog/wdt285.c
@@ -137,7 +137,7 @@ watchdog_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
unsigned long arg)
{
unsigned int new_margin;
- int ret = -ENOIOCTLCMD;
+ int ret = -ENOTTY;
switch(cmd) {
case WDIOC_GETSUPPORT:
diff --git a/drivers/char/watchdog/wdt977.c b/drivers/char/watchdog/wdt977.c
index a0935bc775f8..6253041b235b 100644
--- a/drivers/char/watchdog/wdt977.c
+++ b/drivers/char/watchdog/wdt977.c
@@ -361,7 +361,7 @@ static int wdt977_ioctl(struct inode *inode, struct file *file,
switch(cmd)
{
default:
- return -ENOIOCTLCMD;
+ return -ENOTTY;
case WDIOC_GETSUPPORT:
return copy_to_user(uarg.ident, &ident,
diff --git a/drivers/char/watchdog/wdt_pci.c b/drivers/char/watchdog/wdt_pci.c
index 5918ca2c9c35..74d8cf836e13 100644
--- a/drivers/char/watchdog/wdt_pci.c
+++ b/drivers/char/watchdog/wdt_pci.c
@@ -386,7 +386,7 @@ static int wdtpci_ioctl(struct inode *inode, struct file *file, unsigned int cmd
switch(cmd)
{
default:
- return -ENOIOCTLCMD;
+ return -ENOTTY;
case WDIOC_GETSUPPORT:
return copy_to_user(argp, &ident, sizeof(ident))?-EFAULT:0;
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
index d35a9f06ab7b..2caaf71d80c8 100644
--- a/drivers/cpufreq/cpufreq.c
+++ b/drivers/cpufreq/cpufreq.c
@@ -994,7 +994,7 @@ static int cpufreq_suspend(struct sys_device * sysdev, pm_message_t pmsg)
unsigned int cur_freq = 0;
struct cpufreq_policy *cpu_policy;
- dprintk("resuming cpu %u\n", cpu);
+ dprintk("suspending cpu %u\n", cpu);
if (!cpu_online(cpu))
return 0;
diff --git a/drivers/fc4/fc.c b/drivers/fc4/fc.c
index 1a159e8843ca..22d17474755f 100644
--- a/drivers/fc4/fc.c
+++ b/drivers/fc4/fc.c
@@ -974,7 +974,6 @@ int fcp_scsi_dev_reset(Scsi_Cmnd *SCpnt)
*/
fc->rst_pkt->device->host->eh_action = &sem;
- fc->rst_pkt->request->rq_status = RQ_SCSI_BUSY;
fc->rst_pkt->done = fcp_scsi_reset_done;
diff --git a/drivers/firmware/dell_rbu.c b/drivers/firmware/dell_rbu.c
index 23b086685453..fc17599c905e 100644
--- a/drivers/firmware/dell_rbu.c
+++ b/drivers/firmware/dell_rbu.c
@@ -227,7 +227,7 @@ static int packetize_data(void *data, size_t length)
int packet_length;
u8 *temp;
u8 *end = (u8 *) data + length;
- pr_debug("packetize_data: data length %d\n", length);
+ pr_debug("packetize_data: data length %zd\n", length);
if (!rbu_data.packetsize) {
printk(KERN_WARNING
"dell_rbu: packetsize not specified\n");
@@ -249,7 +249,7 @@ static int packetize_data(void *data, size_t length)
if ((rc = create_packet(temp, packet_length)))
return rc;
- pr_debug("%lu:%lu\n", temp, (end - temp));
+ pr_debug("%p:%lu\n", temp, (end - temp));
temp += packet_length;
}
diff --git a/drivers/firmware/dmi_scan.c b/drivers/firmware/dmi_scan.c
index b9e3886d9e16..b8b596d5778d 100644
--- a/drivers/firmware/dmi_scan.c
+++ b/drivers/firmware/dmi_scan.c
@@ -123,6 +123,26 @@ static void __init dmi_save_devices(struct dmi_header *dm)
dev->type = *d++ & 0x7f;
dev->name = dmi_string(dm, *d);
dev->device_data = NULL;
+ list_add(&dev->list, &dmi_devices);
+ }
+}
+
+static void __init dmi_save_oem_strings_devices(struct dmi_header *dm)
+{
+ int i, count = *(u8 *)(dm + 1);
+ struct dmi_device *dev;
+
+ for (i = 1; i <= count; i++) {
+ dev = dmi_alloc(sizeof(*dev));
+ if (!dev) {
+ printk(KERN_ERR
+ "dmi_save_oem_strings_devices: out of memory.\n");
+ break;
+ }
+
+ dev->type = DMI_DEV_TYPE_OEM_STRING;
+ dev->name = dmi_string(dm, i);
+ dev->device_data = NULL;
list_add(&dev->list, &dmi_devices);
}
@@ -181,6 +201,9 @@ static void __init dmi_decode(struct dmi_header *dm)
case 10: /* Onboard Devices Information */
dmi_save_devices(dm);
break;
+ case 11: /* OEM Strings */
+ dmi_save_oem_strings_devices(dm);
+ break;
case 38: /* IPMI Device Information */
dmi_save_ipmi_device(dm);
}
diff --git a/drivers/hwmon/hdaps.c b/drivers/hwmon/hdaps.c
index 8e7b5607f5a1..26be4ea8a38a 100644
--- a/drivers/hwmon/hdaps.c
+++ b/drivers/hwmon/hdaps.c
@@ -537,6 +537,7 @@ static int __init hdaps_init(void)
HDAPS_DMI_MATCH_NORMAL("ThinkPad T42"),
HDAPS_DMI_MATCH_NORMAL("ThinkPad T43"),
HDAPS_DMI_MATCH_LENOVO("ThinkPad T60p"),
+ HDAPS_DMI_MATCH_LENOVO("ThinkPad T60"),
HDAPS_DMI_MATCH_NORMAL("ThinkPad X40"),
HDAPS_DMI_MATCH_NORMAL("ThinkPad X41"),
HDAPS_DMI_MATCH_LENOVO("ThinkPad X60"),
diff --git a/drivers/i2c/busses/i2c-ite.c b/drivers/i2c/busses/i2c-ite.c
index d82e6dae8407..559a62b04ee9 100644
--- a/drivers/i2c/busses/i2c-ite.c
+++ b/drivers/i2c/busses/i2c-ite.c
@@ -109,7 +109,7 @@ static int iic_ite_getclock(void *data)
static void iic_ite_waitforpin(void) {
DEFINE_WAIT(wait);
int timeout = 2;
- long flags;
+ unsigned long flags;
/* If interrupts are enabled (which they are), then put the process to
* sleep. This process will be awakened by two events -- either the
diff --git a/drivers/i2c/busses/i2c-sibyte.c b/drivers/i2c/busses/i2c-sibyte.c
index 8f2b1f0deb81..0ca599d3b402 100644
--- a/drivers/i2c/busses/i2c-sibyte.c
+++ b/drivers/i2c/busses/i2c-sibyte.c
@@ -210,8 +210,8 @@ static int __init i2c_sibyte_init(void)
static void __exit i2c_sibyte_exit(void)
{
- i2c_del_bus(&sibyte_board_adapter[0]);
- i2c_del_bus(&sibyte_board_adapter[1]);
+ i2c_del_adapter(&sibyte_board_adapter[0]);
+ i2c_del_adapter(&sibyte_board_adapter[1]);
}
module_init(i2c_sibyte_init);
diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c
index 01233f0f7771..7ca81f42d14b 100644
--- a/drivers/i2c/i2c-core.c
+++ b/drivers/i2c/i2c-core.c
@@ -420,14 +420,6 @@ int i2c_attach_client(struct i2c_client *client)
}
list_add_tail(&client->list,&adapter->clients);
- if (adapter->client_register) {
- if (adapter->client_register(client)) {
- dev_dbg(&adapter->dev, "client_register "
- "failed for client [%s] at 0x%02x\n",
- client->name, client->addr);
- }
- }
-
client->usage_count = 0;
client->dev.parent = &client->adapter->dev;
@@ -445,10 +437,17 @@ int i2c_attach_client(struct i2c_client *client)
res = device_create_file(&client->dev, &dev_attr_client_name);
if (res)
goto out_unregister;
-
-out_unlock:
mutex_unlock(&adapter->clist_lock);
- return res;
+
+ if (adapter->client_register) {
+ if (adapter->client_register(client)) {
+ dev_dbg(&adapter->dev, "client_register "
+ "failed for client [%s] at 0x%02x\n",
+ client->name, client->addr);
+ }
+ }
+
+ return 0;
out_unregister:
init_completion(&client->released); /* Needed? */
@@ -458,7 +457,9 @@ out_list:
list_del(&client->list);
dev_err(&adapter->dev, "Failed to attach i2c client %s at 0x%02x "
"(%d)\n", client->name, client->addr, res);
- goto out_unlock;
+out_unlock:
+ mutex_unlock(&adapter->clist_lock);
+ return res;
}
diff --git a/drivers/ide/Kconfig b/drivers/ide/Kconfig
index b6fb167e20f6..abcabb295592 100644
--- a/drivers/ide/Kconfig
+++ b/drivers/ide/Kconfig
@@ -4,6 +4,8 @@
# Andre Hedrick <andre@linux-ide.org>
#
+if BLOCK
+
menu "ATA/ATAPI/MFM/RLL support"
config IDE
@@ -54,7 +56,7 @@ if IDE
config IDE_MAX_HWIFS
int "Max IDE interfaces"
- depends on ALPHA || SUPERH || IA64
+ depends on ALPHA || SUPERH || IA64 || EMBEDDED
default 4
help
This is the maximum number of IDE hardware interfaces that will
@@ -592,6 +594,12 @@ config BLK_DEV_HPT366
ide-probe at boot. It is reported to support DVD II drives, by the
manufacturer.
+config BLK_DEV_JMICRON
+ tristate "JMicron JMB36x support"
+ help
+ Basic support for the JMicron ATA controllers. For full support
+ use the libata drivers.
+
config BLK_DEV_SC1200
tristate "National SCx200 chipset support"
help
@@ -1082,3 +1090,5 @@ config BLK_DEV_HD
endif
endmenu
+
+endif
diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c
index 654d4cd09847..69bbb6206a00 100644
--- a/drivers/ide/ide-cd.c
+++ b/drivers/ide/ide-cd.c
@@ -372,7 +372,7 @@ static int cdrom_log_sense(ide_drive_t *drive, struct request *rq,
{
int log = 0;
- if (!sense || !rq || (rq->flags & REQ_QUIET))
+ if (!sense || !rq || (rq->cmd_flags & REQ_QUIET))
return 0;
switch (sense->sense_key) {
@@ -597,7 +597,7 @@ static void cdrom_prepare_request(ide_drive_t *drive, struct request *rq)
struct cdrom_info *cd = drive->driver_data;
ide_init_drive_cmd(rq);
- rq->flags = REQ_PC;
+ rq->cmd_type = REQ_TYPE_BLOCK_PC;
rq->rq_disk = cd->disk;
}
@@ -617,7 +617,7 @@ static void cdrom_queue_request_sense(ide_drive_t *drive, void *sense,
rq->cmd[0] = GPCMD_REQUEST_SENSE;
rq->cmd[4] = rq->data_len = 18;
- rq->flags = REQ_SENSE;
+ rq->cmd_type = REQ_TYPE_SENSE;
/* NOTE! Save the failed command in "rq->buffer" */
rq->buffer = (void *) failed_command;
@@ -630,10 +630,10 @@ static void cdrom_end_request (ide_drive_t *drive, int uptodate)
struct request *rq = HWGROUP(drive)->rq;
int nsectors = rq->hard_cur_sectors;
- if ((rq->flags & REQ_SENSE) && uptodate) {
+ if (blk_sense_request(rq) && uptodate) {
/*
- * For REQ_SENSE, "rq->buffer" points to the original failed
- * request
+ * For REQ_TYPE_SENSE, "rq->buffer" points to the original
+ * failed request
*/
struct request *failed = (struct request *) rq->buffer;
struct cdrom_info *info = drive->driver_data;
@@ -706,17 +706,17 @@ static int cdrom_decode_status(ide_drive_t *drive, int good_stat, int *stat_ret)
return 1;
}
- if (rq->flags & REQ_SENSE) {
+ if (blk_sense_request(rq)) {
/* We got an error trying to get sense info
from the drive (probably while trying
to recover from a former error). Just give up. */
- rq->flags |= REQ_FAILED;
+ rq->cmd_flags |= REQ_FAILED;
cdrom_end_request(drive, 0);
ide_error(drive, "request sense failure", stat);
return 1;
- } else if (rq->flags & (REQ_PC | REQ_BLOCK_PC)) {
+ } else if (blk_pc_request(rq)) {
/* All other functions, except for READ. */
unsigned long flags;
@@ -724,7 +724,7 @@ static int cdrom_decode_status(ide_drive_t *drive, int good_stat, int *stat_ret)
* if we have an error, pass back CHECK_CONDITION as the
* scsi status byte
*/
- if ((rq->flags & REQ_BLOCK_PC) && !rq->errors)
+ if (!rq->errors)
rq->errors = SAM_STAT_CHECK_CONDITION;
/* Check for tray open. */
@@ -735,12 +735,12 @@ static int cdrom_decode_status(ide_drive_t *drive, int good_stat, int *stat_ret)
cdrom_saw_media_change (drive);
/*printk("%s: media changed\n",drive->name);*/
return 0;
- } else if (!(rq->flags & REQ_QUIET)) {
+ } else if (!(rq->cmd_flags & REQ_QUIET)) {
/* Otherwise, print an error. */
ide_dump_status(drive, "packet command error", stat);
}
- rq->flags |= REQ_FAILED;
+ rq->cmd_flags |= REQ_FAILED;
/*
* instead of playing games with moving completions around,
@@ -881,7 +881,7 @@ static int cdrom_timer_expiry(ide_drive_t *drive)
wait = ATAPI_WAIT_PC;
break;
default:
- if (!(rq->flags & REQ_QUIET))
+ if (!(rq->cmd_flags & REQ_QUIET))
printk(KERN_INFO "ide-cd: cmd 0x%x timed out\n", rq->cmd[0]);
wait = 0;
break;
@@ -1124,7 +1124,7 @@ static ide_startstop_t cdrom_read_intr (ide_drive_t *drive)
if (rq->current_nr_sectors > 0) {
printk (KERN_ERR "%s: cdrom_read_intr: data underrun (%d blocks)\n",
drive->name, rq->current_nr_sectors);
- rq->flags |= REQ_FAILED;
+ rq->cmd_flags |= REQ_FAILED;
cdrom_end_request(drive, 0);
} else
cdrom_end_request(drive, 1);
@@ -1456,7 +1456,7 @@ static ide_startstop_t cdrom_pc_intr (ide_drive_t *drive)
printk ("%s: cdrom_pc_intr: data underrun %d\n",
drive->name, pc->buflen);
*/
- rq->flags |= REQ_FAILED;
+ rq->cmd_flags |= REQ_FAILED;
cdrom_end_request(drive, 0);
}
return ide_stopped;
@@ -1509,7 +1509,7 @@ static ide_startstop_t cdrom_pc_intr (ide_drive_t *drive)
rq->data += thislen;
rq->data_len -= thislen;
- if (rq->flags & REQ_SENSE)
+ if (blk_sense_request(rq))
rq->sense_len += thislen;
} else {
confused:
@@ -1517,7 +1517,7 @@ confused:
"appears confused (ireason = 0x%02x). "
"Trying to recover by ending request.\n",
drive->name, ireason);
- rq->flags |= REQ_FAILED;
+ rq->cmd_flags |= REQ_FAILED;
cdrom_end_request(drive, 0);
return ide_stopped;
}
@@ -1546,7 +1546,7 @@ static ide_startstop_t cdrom_do_packet_command (ide_drive_t *drive)
struct cdrom_info *info = drive->driver_data;
info->dma = 0;
- rq->flags &= ~REQ_FAILED;
+ rq->cmd_flags &= ~REQ_FAILED;
len = rq->data_len;
/* Start sending the command to the drive. */
@@ -1558,7 +1558,7 @@ static int cdrom_queue_packet_command(ide_drive_t *drive, struct request *rq)
{
struct request_sense sense;
int retries = 10;
- unsigned int flags = rq->flags;
+ unsigned int flags = rq->cmd_flags;
if (rq->sense == NULL)
rq->sense = &sense;
@@ -1567,14 +1567,14 @@ static int cdrom_queue_packet_command(ide_drive_t *drive, struct request *rq)
do {
int error;
unsigned long time = jiffies;
- rq->flags = flags;
+ rq->cmd_flags = flags;
error = ide_do_drive_cmd(drive, rq, ide_wait);
time = jiffies - time;
/* FIXME: we should probably abort/retry or something
* in case of failure */
- if (rq->flags & REQ_FAILED) {
+ if (rq->cmd_flags & REQ_FAILED) {
/* The request failed. Retry if it was due to a unit
attention status
(usually means media was changed). */
@@ -1596,10 +1596,10 @@ static int cdrom_queue_packet_command(ide_drive_t *drive, struct request *rq)
}
/* End of retry loop. */
- } while ((rq->flags & REQ_FAILED) && retries >= 0);
+ } while ((rq->cmd_flags & REQ_FAILED) && retries >= 0);
/* Return an error if the command failed. */
- return (rq->flags & REQ_FAILED) ? -EIO : 0;
+ return (rq->cmd_flags & REQ_FAILED) ? -EIO : 0;
}
/*
@@ -1963,7 +1963,7 @@ static ide_startstop_t cdrom_do_block_pc(ide_drive_t *drive, struct request *rq)
{
struct cdrom_info *info = drive->driver_data;
- rq->flags |= REQ_QUIET;
+ rq->cmd_flags |= REQ_QUIET;
info->dma = 0;
@@ -2023,11 +2023,11 @@ ide_do_rw_cdrom (ide_drive_t *drive, struct request *rq, sector_t block)
}
info->last_block = block;
return action;
- } else if (rq->flags & (REQ_PC | REQ_SENSE)) {
+ } else if (rq->cmd_type == REQ_TYPE_SENSE) {
return cdrom_do_packet_command(drive);
- } else if (rq->flags & REQ_BLOCK_PC) {
+ } else if (blk_pc_request(rq)) {
return cdrom_do_block_pc(drive, rq);
- } else if (rq->flags & REQ_SPECIAL) {
+ } else if (blk_special_request(rq)) {
/*
* right now this can only be a reset...
*/
@@ -2105,7 +2105,7 @@ static int cdrom_check_status(ide_drive_t *drive, struct request_sense *sense)
req.sense = sense;
req.cmd[0] = GPCMD_TEST_UNIT_READY;
- req.flags |= REQ_QUIET;
+ req.cmd_flags |= REQ_QUIET;
#if ! STANDARD_ATAPI
/* the Sanyo 3 CD changer uses byte 7 of TEST_UNIT_READY to
@@ -2207,7 +2207,7 @@ static int cdrom_read_capacity(ide_drive_t *drive, unsigned long *capacity,
req.cmd[0] = GPCMD_READ_CDVD_CAPACITY;
req.data = (char *)&capbuf;
req.data_len = sizeof(capbuf);
- req.flags |= REQ_QUIET;
+ req.cmd_flags |= REQ_QUIET;
stat = cdrom_queue_packet_command(drive, &req);
if (stat == 0) {
@@ -2230,7 +2230,7 @@ static int cdrom_read_tocentry(ide_drive_t *drive, int trackno, int msf_flag,
req.sense = sense;
req.data = buf;
req.data_len = buflen;
- req.flags |= REQ_QUIET;
+ req.cmd_flags |= REQ_QUIET;
req.cmd[0] = GPCMD_READ_TOC_PMA_ATIP;
req.cmd[6] = trackno;
req.cmd[7] = (buflen >> 8);
@@ -2531,7 +2531,7 @@ static int ide_cdrom_packet(struct cdrom_device_info *cdi,
req.timeout = cgc->timeout;
if (cgc->quiet)
- req.flags |= REQ_QUIET;
+ req.cmd_flags |= REQ_QUIET;
req.sense = cgc->sense;
cgc->stat = cdrom_queue_packet_command(drive, &req);
@@ -2629,7 +2629,8 @@ int ide_cdrom_reset (struct cdrom_device_info *cdi)
int ret;
cdrom_prepare_request(drive, &req);
- req.flags = REQ_SPECIAL | REQ_QUIET;
+ req.cmd_type = REQ_TYPE_SPECIAL;
+ req.cmd_flags = REQ_QUIET;
ret = ide_do_drive_cmd(drive, &req, ide_wait);
/*
@@ -3116,9 +3117,9 @@ static int ide_cdrom_prep_pc(struct request *rq)
static int ide_cdrom_prep_fn(request_queue_t *q, struct request *rq)
{
- if (rq->flags & REQ_CMD)
+ if (blk_fs_request(rq))
return ide_cdrom_prep_fs(q, rq);
- else if (rq->flags & REQ_BLOCK_PC)
+ else if (blk_pc_request(rq))
return ide_cdrom_prep_pc(rq);
return 0;
diff --git a/drivers/ide/ide-disk.c b/drivers/ide/ide-disk.c
index 7cf3eb023521..0a05a377d66a 100644
--- a/drivers/ide/ide-disk.c
+++ b/drivers/ide/ide-disk.c
@@ -699,7 +699,8 @@ static void idedisk_prepare_flush(request_queue_t *q, struct request *rq)
rq->cmd[0] = WIN_FLUSH_CACHE;
- rq->flags |= REQ_DRIVE_TASK;
+ rq->cmd_type = REQ_TYPE_ATA_TASK;
+ rq->cmd_flags |= REQ_SOFTBARRIER;
rq->buffer = rq->cmd;
}
@@ -740,7 +741,7 @@ static int set_multcount(ide_drive_t *drive, int arg)
if (drive->special.b.set_multmode)
return -EBUSY;
ide_init_drive_cmd (&rq);
- rq.flags = REQ_DRIVE_CMD;
+ rq.cmd_type = REQ_TYPE_ATA_CMD;
drive->mult_req = arg;
drive->special.b.set_multmode = 1;
(void) ide_do_drive_cmd (drive, &rq, ide_wait);
diff --git a/drivers/ide/ide-dma.c b/drivers/ide/ide-dma.c
index 7c3a13e1cf64..56efed6742d4 100644
--- a/drivers/ide/ide-dma.c
+++ b/drivers/ide/ide-dma.c
@@ -145,14 +145,12 @@ int ide_in_drive_list(struct hd_driveid *id, const struct drive_list_entry *driv
{
for ( ; drive_table->id_model ; drive_table++)
if ((!strcmp(drive_table->id_model, id->model)) &&
- ((strstr(drive_table->id_firmware, id->fw_rev)) ||
+ ((strstr(id->fw_rev, drive_table->id_firmware)) ||
(!strcmp(drive_table->id_firmware, "ALL"))))
return 1;
return 0;
}
-EXPORT_SYMBOL_GPL(ide_in_drive_list);
-
/**
* ide_dma_intr - IDE DMA interrupt handler
* @drive: the drive the interrupt is for
@@ -205,7 +203,7 @@ int ide_build_sglist(ide_drive_t *drive, struct request *rq)
ide_hwif_t *hwif = HWIF(drive);
struct scatterlist *sg = hwif->sg_table;
- BUG_ON((rq->flags & REQ_DRIVE_TASKFILE) && rq->nr_sectors > 256);
+ BUG_ON((rq->cmd_type == REQ_TYPE_ATA_TASKFILE) && rq->nr_sectors > 256);
ide_map_sg(drive, rq);
@@ -798,26 +796,23 @@ static int ide_release_dma_engine(ide_hwif_t *hwif)
static int ide_release_iomio_dma(ide_hwif_t *hwif)
{
- if ((hwif->dma_extra) && (hwif->channel == 0))
- release_region((hwif->dma_base + 16), hwif->dma_extra);
release_region(hwif->dma_base, 8);
- if (hwif->dma_base2)
- release_region(hwif->dma_base, 8);
+ if (hwif->extra_ports)
+ release_region(hwif->extra_base, hwif->extra_ports);
return 1;
}
/*
* Needed for allowing full modular support of ide-driver
*/
-int ide_release_dma (ide_hwif_t *hwif)
+int ide_release_dma(ide_hwif_t *hwif)
{
+ ide_release_dma_engine(hwif);
+
if (hwif->mmio == 2)
return 1;
- if (hwif->chipset == ide_etrax100)
- return 1;
-
- ide_release_dma_engine(hwif);
- return ide_release_iomio_dma(hwif);
+ else
+ return ide_release_iomio_dma(hwif);
}
static int ide_allocate_dma_engine(ide_hwif_t *hwif)
@@ -829,10 +824,9 @@ static int ide_allocate_dma_engine(ide_hwif_t *hwif)
if (hwif->dmatable_cpu)
return 0;
- printk(KERN_ERR "%s: -- Error, unable to allocate%s DMA table(s).\n",
- hwif->cds->name, !hwif->dmatable_cpu ? " CPU" : "");
+ printk(KERN_ERR "%s: -- Error, unable to allocate DMA table.\n",
+ hwif->cds->name);
- ide_release_dma_engine(hwif);
return 1;
}
@@ -840,9 +834,7 @@ static int ide_mapped_mmio_dma(ide_hwif_t *hwif, unsigned long base, unsigned in
{
printk(KERN_INFO " %s: MMIO-DMA ", hwif->name);
- hwif->dma_base = base;
- if (hwif->cds->extra && hwif->channel == 0)
- hwif->dma_extra = hwif->cds->extra;
+ hwif->dma_base = base;
if(hwif->mate)
hwif->dma_master = (hwif->channel) ? hwif->mate->dma_base : base;
@@ -854,29 +846,33 @@ static int ide_mapped_mmio_dma(ide_hwif_t *hwif, unsigned long base, unsigned in
static int ide_iomio_dma(ide_hwif_t *hwif, unsigned long base, unsigned int ports)
{
printk(KERN_INFO " %s: BM-DMA at 0x%04lx-0x%04lx",
- hwif->name, base, base + ports - 1);
+ hwif->name, base, base + ports - 1);
+
if (!request_region(base, ports, hwif->name)) {
printk(" -- Error, ports in use.\n");
return 1;
}
+
hwif->dma_base = base;
- if ((hwif->cds->extra) && (hwif->channel == 0)) {
- request_region(base+16, hwif->cds->extra, hwif->cds->name);
- hwif->dma_extra = hwif->cds->extra;
+
+ if (hwif->cds->extra) {
+ hwif->extra_base = base + (hwif->channel ? 8 : 16);
+
+ if (!hwif->mate || !hwif->mate->extra_ports) {
+ if (!request_region(hwif->extra_base,
+ hwif->cds->extra, hwif->cds->name)) {
+ printk(" -- Error, extra ports in use.\n");
+ release_region(base, ports);
+ return 1;
+ }
+ hwif->extra_ports = hwif->cds->extra;
+ }
}
-
+
if(hwif->mate)
- hwif->dma_master = (hwif->channel) ? hwif->mate->dma_base : base;
+ hwif->dma_master = (hwif->channel) ? hwif->mate->dma_base:base;
else
hwif->dma_master = base;
- if (hwif->dma_base2) {
- if (!request_region(hwif->dma_base2, ports, hwif->name))
- {
- printk(" -- Error, secondary ports in use.\n");
- release_region(base, ports);
- return 1;
- }
- }
return 0;
}
diff --git a/drivers/ide/ide-floppy.c b/drivers/ide/ide-floppy.c
index adbe9f76a505..8ccee9c769f8 100644
--- a/drivers/ide/ide-floppy.c
+++ b/drivers/ide/ide-floppy.c
@@ -588,7 +588,7 @@ static int idefloppy_do_end_request(ide_drive_t *drive, int uptodate, int nsecs)
/* Why does this happen? */
if (!rq)
return 0;
- if (!(rq->flags & REQ_SPECIAL)) { //if (!IDEFLOPPY_RQ_CMD (rq->cmd)) {
+ if (!blk_special_request(rq)) {
/* our real local end request function */
ide_end_request(drive, uptodate, nsecs);
return 0;
@@ -689,7 +689,7 @@ static void idefloppy_queue_pc_head (ide_drive_t *drive,idefloppy_pc_t *pc,struc
ide_init_drive_cmd(rq);
rq->buffer = (char *) pc;
- rq->flags = REQ_SPECIAL; //rq->cmd = IDEFLOPPY_PC_RQ;
+ rq->cmd_type = REQ_TYPE_SPECIAL;
rq->rq_disk = floppy->disk;
(void) ide_do_drive_cmd(drive, rq, ide_preempt);
}
@@ -1250,7 +1250,7 @@ static void idefloppy_create_rw_cmd (idefloppy_floppy_t *floppy, idefloppy_pc_t
pc->callback = &idefloppy_rw_callback;
pc->rq = rq;
pc->b_count = cmd == READ ? 0 : rq->bio->bi_size;
- if (rq->flags & REQ_RW)
+ if (rq->cmd_flags & REQ_RW)
set_bit(PC_WRITING, &pc->flags);
pc->buffer = NULL;
pc->request_transfer = pc->buffer_size = blocks * floppy->block_size;
@@ -1281,8 +1281,7 @@ static ide_startstop_t idefloppy_do_request (ide_drive_t *drive, struct request
idefloppy_pc_t *pc;
unsigned long block = (unsigned long)block_s;
- debug_log(KERN_INFO "rq_status: %d, dev: %s, flags: %lx, errors: %d\n",
- rq->rq_status,
+ debug_log(KERN_INFO "dev: %s, flags: %lx, errors: %d\n",
rq->rq_disk ? rq->rq_disk->disk_name : "?",
rq->flags, rq->errors);
debug_log(KERN_INFO "sector: %ld, nr_sectors: %ld, "
@@ -1303,7 +1302,7 @@ static ide_startstop_t idefloppy_do_request (ide_drive_t *drive, struct request
idefloppy_do_end_request(drive, 0, 0);
return ide_stopped;
}
- if (rq->flags & REQ_CMD) {
+ if (blk_fs_request(rq)) {
if (((long)rq->sector % floppy->bs_factor) ||
(rq->nr_sectors % floppy->bs_factor)) {
printk("%s: unsupported r/w request size\n",
@@ -1313,9 +1312,9 @@ static ide_startstop_t idefloppy_do_request (ide_drive_t *drive, struct request
}
pc = idefloppy_next_pc_storage(drive);
idefloppy_create_rw_cmd(floppy, pc, rq, block);
- } else if (rq->flags & REQ_SPECIAL) {
+ } else if (blk_special_request(rq)) {
pc = (idefloppy_pc_t *) rq->buffer;
- } else if (rq->flags & REQ_BLOCK_PC) {
+ } else if (blk_pc_request(rq)) {
pc = idefloppy_next_pc_storage(drive);
if (idefloppy_blockpc_cmd(floppy, pc, rq)) {
idefloppy_do_end_request(drive, 0, 0);
@@ -1343,7 +1342,7 @@ static int idefloppy_queue_pc_tail (ide_drive_t *drive,idefloppy_pc_t *pc)
ide_init_drive_cmd (&rq);
rq.buffer = (char *) pc;
- rq.flags = REQ_SPECIAL; // rq.cmd = IDEFLOPPY_PC_RQ;
+ rq.cmd_type = REQ_TYPE_SPECIAL;
rq.rq_disk = floppy->disk;
return ide_do_drive_cmd(drive, &rq, ide_wait);
diff --git a/drivers/ide/ide-io.c b/drivers/ide/ide-io.c
index fb6795236e76..ba6039b55b41 100644
--- a/drivers/ide/ide-io.c
+++ b/drivers/ide/ide-io.c
@@ -59,8 +59,6 @@ static int __ide_end_request(ide_drive_t *drive, struct request *rq,
{
int ret = 1;
- BUG_ON(!(rq->flags & REQ_STARTED));
-
/*
* if failfast is set on a request, override number of sectors and
* complete the whole request right now
@@ -82,7 +80,8 @@ static int __ide_end_request(ide_drive_t *drive, struct request *rq,
if (!end_that_request_first(rq, uptodate, nr_sectors)) {
add_disk_randomness(rq->rq_disk);
- blkdev_dequeue_request(rq);
+ if (!list_empty(&rq->queuelist))
+ blkdev_dequeue_request(rq);
HWGROUP(drive)->rq = NULL;
end_that_request_last(rq, uptodate);
ret = 0;
@@ -135,13 +134,14 @@ enum {
ide_pm_flush_cache = ide_pm_state_start_suspend,
idedisk_pm_standby,
- idedisk_pm_idle = ide_pm_state_start_resume,
+ idedisk_pm_restore_pio = ide_pm_state_start_resume,
+ idedisk_pm_idle,
ide_pm_restore_dma,
};
static void ide_complete_power_step(ide_drive_t *drive, struct request *rq, u8 stat, u8 error)
{
- struct request_pm_state *pm = rq->end_io_data;
+ struct request_pm_state *pm = rq->data;
if (drive->media != ide_disk)
return;
@@ -156,7 +156,10 @@ static void ide_complete_power_step(ide_drive_t *drive, struct request *rq, u8 s
case idedisk_pm_standby: /* Suspend step 2 (standby) complete */
pm->pm_step = ide_pm_state_completed;
break;
- case idedisk_pm_idle: /* Resume step 1 (idle) complete */
+ case idedisk_pm_restore_pio: /* Resume step 1 complete */
+ pm->pm_step = idedisk_pm_idle;
+ break;
+ case idedisk_pm_idle: /* Resume step 2 (idle) complete */
pm->pm_step = ide_pm_restore_dma;
break;
}
@@ -164,14 +167,17 @@ static void ide_complete_power_step(ide_drive_t *drive, struct request *rq, u8 s
static ide_startstop_t ide_start_power_step(ide_drive_t *drive, struct request *rq)
{
- struct request_pm_state *pm = rq->end_io_data;
+ struct request_pm_state *pm = rq->data;
ide_task_t *args = rq->special;
memset(args, 0, sizeof(*args));
if (drive->media != ide_disk) {
- /* skip idedisk_pm_idle for ATAPI devices */
- if (pm->pm_step == idedisk_pm_idle)
+ /*
+ * skip idedisk_pm_restore_pio and idedisk_pm_idle for ATAPI
+ * devices
+ */
+ if (pm->pm_step == idedisk_pm_restore_pio)
pm->pm_step = ide_pm_restore_dma;
}
@@ -198,13 +204,19 @@ static ide_startstop_t ide_start_power_step(ide_drive_t *drive, struct request *
args->handler = &task_no_data_intr;
return do_rw_taskfile(drive, args);
- case idedisk_pm_idle: /* Resume step 1 (idle) */
+ case idedisk_pm_restore_pio: /* Resume step 1 (restore PIO) */
+ if (drive->hwif->tuneproc != NULL)
+ drive->hwif->tuneproc(drive, 255);
+ ide_complete_power_step(drive, rq, 0, 0);
+ return ide_stopped;
+
+ case idedisk_pm_idle: /* Resume step 2 (idle) */
args->tfRegister[IDE_COMMAND_OFFSET] = WIN_IDLEIMMEDIATE;
args->command_type = IDE_DRIVE_TASK_NO_DATA;
args->handler = task_no_data_intr;
return do_rw_taskfile(drive, args);
- case ide_pm_restore_dma: /* Resume step 2 (restore DMA) */
+ case ide_pm_restore_dma: /* Resume step 3 (restore DMA) */
/*
* Right now, all we do is call hwif->ide_dma_check(drive),
* we could be smarter and check for current xfer_speed
@@ -244,7 +256,7 @@ int ide_end_dequeued_request(ide_drive_t *drive, struct request *rq,
spin_lock_irqsave(&ide_lock, flags);
- BUG_ON(!(rq->flags & REQ_STARTED));
+ BUG_ON(!blk_rq_started(rq));
/*
* if failfast is set on a request, override number of sectors and
@@ -366,7 +378,7 @@ void ide_end_drive_cmd (ide_drive_t *drive, u8 stat, u8 err)
rq = HWGROUP(drive)->rq;
spin_unlock_irqrestore(&ide_lock, flags);
- if (rq->flags & REQ_DRIVE_CMD) {
+ if (rq->cmd_type == REQ_TYPE_ATA_CMD) {
u8 *args = (u8 *) rq->buffer;
if (rq->errors == 0)
rq->errors = !OK_STAT(stat,READY_STAT,BAD_STAT);
@@ -376,7 +388,7 @@ void ide_end_drive_cmd (ide_drive_t *drive, u8 stat, u8 err)
args[1] = err;
args[2] = hwif->INB(IDE_NSECTOR_REG);
}
- } else if (rq->flags & REQ_DRIVE_TASK) {
+ } else if (rq->cmd_type == REQ_TYPE_ATA_TASK) {
u8 *args = (u8 *) rq->buffer;
if (rq->errors == 0)
rq->errors = !OK_STAT(stat,READY_STAT,BAD_STAT);
@@ -390,7 +402,7 @@ void ide_end_drive_cmd (ide_drive_t *drive, u8 stat, u8 err)
args[5] = hwif->INB(IDE_HCYL_REG);
args[6] = hwif->INB(IDE_SELECT_REG);
}
- } else if (rq->flags & REQ_DRIVE_TASKFILE) {
+ } else if (rq->cmd_type == REQ_TYPE_ATA_TASKFILE) {
ide_task_t *args = (ide_task_t *) rq->special;
if (rq->errors == 0)
rq->errors = !OK_STAT(stat,READY_STAT,BAD_STAT);
@@ -421,7 +433,7 @@ void ide_end_drive_cmd (ide_drive_t *drive, u8 stat, u8 err)
}
}
} else if (blk_pm_request(rq)) {
- struct request_pm_state *pm = rq->end_io_data;
+ struct request_pm_state *pm = rq->data;
#ifdef DEBUG_PM
printk("%s: complete_power_step(step: %d, stat: %x, err: %x)\n",
drive->name, rq->pm->pm_step, stat, err);
@@ -587,7 +599,7 @@ ide_startstop_t ide_error (ide_drive_t *drive, const char *msg, u8 stat)
return ide_stopped;
/* retry only "normal" I/O: */
- if (rq->flags & (REQ_DRIVE_CMD | REQ_DRIVE_TASK | REQ_DRIVE_TASKFILE)) {
+ if (!blk_fs_request(rq)) {
rq->errors = 1;
ide_end_drive_cmd(drive, stat, err);
return ide_stopped;
@@ -638,7 +650,7 @@ ide_startstop_t ide_abort(ide_drive_t *drive, const char *msg)
return ide_stopped;
/* retry only "normal" I/O: */
- if (rq->flags & (REQ_DRIVE_CMD | REQ_DRIVE_TASK | REQ_DRIVE_TASKFILE)) {
+ if (!blk_fs_request(rq)) {
rq->errors = 1;
ide_end_drive_cmd(drive, BUSY_STAT, 0);
return ide_stopped;
@@ -808,7 +820,7 @@ void ide_map_sg(ide_drive_t *drive, struct request *rq)
if (hwif->sg_mapped) /* needed by ide-scsi */
return;
- if ((rq->flags & REQ_DRIVE_TASKFILE) == 0) {
+ if (rq->cmd_type != REQ_TYPE_ATA_TASKFILE) {
hwif->sg_nents = blk_rq_map_sg(drive->queue, rq, sg);
} else {
sg_init_one(sg, rq->buffer, rq->nr_sectors * SECTOR_SIZE);
@@ -844,7 +856,7 @@ static ide_startstop_t execute_drive_cmd (ide_drive_t *drive,
struct request *rq)
{
ide_hwif_t *hwif = HWIF(drive);
- if (rq->flags & REQ_DRIVE_TASKFILE) {
+ if (rq->cmd_type == REQ_TYPE_ATA_TASKFILE) {
ide_task_t *args = rq->special;
if (!args)
@@ -866,7 +878,7 @@ static ide_startstop_t execute_drive_cmd (ide_drive_t *drive,
if (args->tf_out_flags.all != 0)
return flagged_taskfile(drive, args);
return do_rw_taskfile(drive, args);
- } else if (rq->flags & REQ_DRIVE_TASK) {
+ } else if (rq->cmd_type == REQ_TYPE_ATA_TASK) {
u8 *args = rq->buffer;
u8 sel;
@@ -892,7 +904,7 @@ static ide_startstop_t execute_drive_cmd (ide_drive_t *drive,
hwif->OUTB(sel, IDE_SELECT_REG);
ide_cmd(drive, args[0], args[2], &drive_cmd_intr);
return ide_started;
- } else if (rq->flags & REQ_DRIVE_CMD) {
+ } else if (rq->cmd_type == REQ_TYPE_ATA_CMD) {
u8 *args = rq->buffer;
if (!args)
@@ -933,7 +945,7 @@ done:
static void ide_check_pm_state(ide_drive_t *drive, struct request *rq)
{
- struct request_pm_state *pm = rq->end_io_data;
+ struct request_pm_state *pm = rq->data;
if (blk_pm_suspend_request(rq) &&
pm->pm_step == ide_pm_state_start_suspend)
@@ -980,7 +992,7 @@ static ide_startstop_t start_request (ide_drive_t *drive, struct request *rq)
ide_startstop_t startstop;
sector_t block;
- BUG_ON(!(rq->flags & REQ_STARTED));
+ BUG_ON(!blk_rq_started(rq));
#ifdef DEBUG
printk("%s: start_request: current=0x%08lx\n",
@@ -1013,12 +1025,12 @@ static ide_startstop_t start_request (ide_drive_t *drive, struct request *rq)
if (!drive->special.all) {
ide_driver_t *drv;
- if (rq->flags & (REQ_DRIVE_CMD | REQ_DRIVE_TASK))
- return execute_drive_cmd(drive, rq);
- else if (rq->flags & REQ_DRIVE_TASKFILE)
+ if (rq->cmd_type == REQ_TYPE_ATA_CMD ||
+ rq->cmd_type == REQ_TYPE_ATA_TASK ||
+ rq->cmd_type == REQ_TYPE_ATA_TASKFILE)
return execute_drive_cmd(drive, rq);
else if (blk_pm_request(rq)) {
- struct request_pm_state *pm = rq->end_io_data;
+ struct request_pm_state *pm = rq->data;
#ifdef DEBUG_PM
printk("%s: start_power_step(step: %d)\n",
drive->name, rq->pm->pm_step);
@@ -1264,7 +1276,7 @@ static void ide_do_request (ide_hwgroup_t *hwgroup, int masked_irq)
* We count how many times we loop here to make sure we service
* all drives in the hwgroup without looping for ever
*/
- if (drive->blocked && !blk_pm_request(rq) && !(rq->flags & REQ_PREEMPT)) {
+ if (drive->blocked && !blk_pm_request(rq) && !(rq->cmd_flags & REQ_PREEMPT)) {
drive = drive->next ? drive->next : hwgroup->drive;
if (loops++ < 4 && !blk_queue_plugged(drive->queue))
goto again;
@@ -1346,6 +1358,10 @@ static ide_startstop_t ide_dma_timeout_retry(ide_drive_t *drive, int error)
* make sure request is sane
*/
rq = HWGROUP(drive)->rq;
+
+ if (!rq)
+ goto out;
+
HWGROUP(drive)->rq = NULL;
rq->errors = 0;
@@ -1670,7 +1686,7 @@ irqreturn_t ide_intr (int irq, void *dev_id, struct pt_regs *regs)
void ide_init_drive_cmd (struct request *rq)
{
memset(rq, 0, sizeof(*rq));
- rq->flags = REQ_DRIVE_CMD;
+ rq->cmd_type = REQ_TYPE_ATA_CMD;
rq->ref_count = 1;
}
@@ -1710,7 +1726,6 @@ int ide_do_drive_cmd (ide_drive_t *drive, struct request *rq, ide_action_t actio
int must_wait = (action == ide_wait || action == ide_head_wait);
rq->errors = 0;
- rq->rq_status = RQ_ACTIVE;
/*
* we need to hold an extra reference to request for safe inspection
@@ -1718,7 +1733,7 @@ int ide_do_drive_cmd (ide_drive_t *drive, struct request *rq, ide_action_t actio
*/
if (must_wait) {
rq->ref_count++;
- rq->waiting = &wait;
+ rq->end_io_data = &wait;
rq->end_io = blk_end_sync_rq;
}
@@ -1727,7 +1742,7 @@ int ide_do_drive_cmd (ide_drive_t *drive, struct request *rq, ide_action_t actio
hwgroup->rq = NULL;
if (action == ide_preempt || action == ide_head_wait) {
where = ELEVATOR_INSERT_FRONT;
- rq->flags |= REQ_PREEMPT;
+ rq->cmd_flags |= REQ_PREEMPT;
}
__elv_add_request(drive->queue, rq, where, 0);
ide_do_request(hwgroup, IDE_NO_IRQ);
@@ -1736,7 +1751,6 @@ int ide_do_drive_cmd (ide_drive_t *drive, struct request *rq, ide_action_t actio
err = 0;
if (must_wait) {
wait_for_completion(&wait);
- rq->waiting = NULL;
if (rq->errors)
err = -EIO;
diff --git a/drivers/ide/ide-iops.c b/drivers/ide/ide-iops.c
index 77703acaec17..badde6331775 100644
--- a/drivers/ide/ide-iops.c
+++ b/drivers/ide/ide-iops.c
@@ -998,6 +998,7 @@ static ide_startstop_t atapi_reset_pollfunc (ide_drive_t *drive)
}
/* done polling */
hwgroup->polling = 0;
+ hwgroup->resetting = 0;
return ide_stopped;
}
@@ -1057,6 +1058,7 @@ static ide_startstop_t reset_pollfunc (ide_drive_t *drive)
}
}
hwgroup->polling = 0; /* done polling */
+ hwgroup->resetting = 0; /* done reset attempt */
return ide_stopped;
}
@@ -1143,6 +1145,7 @@ static ide_startstop_t do_reset1 (ide_drive_t *drive, int do_not_try_atapi)
/* For an ATAPI device, first try an ATAPI SRST. */
if (drive->media != ide_disk && !do_not_try_atapi) {
+ hwgroup->resetting = 1;
pre_reset(drive);
SELECT_DRIVE(drive);
udelay (20);
@@ -1168,6 +1171,7 @@ static ide_startstop_t do_reset1 (ide_drive_t *drive, int do_not_try_atapi)
return ide_stopped;
}
+ hwgroup->resetting = 1;
/*
* Note that we also set nIEN while resetting the device,
* to mask unwanted interrupts from the interface during the reset.
diff --git a/drivers/ide/ide-lib.c b/drivers/ide/ide-lib.c
index 1feff23487d4..8237d89eec6e 100644
--- a/drivers/ide/ide-lib.c
+++ b/drivers/ide/ide-lib.c
@@ -71,75 +71,96 @@ EXPORT_SYMBOL(ide_xfer_verbose);
/**
* ide_dma_speed - compute DMA speed
* @drive: drive
- * @mode; intended mode
+ * @mode: modes available
*
* Checks the drive capabilities and returns the speed to use
- * for the transfer. Returns -1 if the requested mode is unknown
- * (eg PIO)
+ * for the DMA transfer. Returns 0 if the drive is incapable
+ * of DMA transfers.
*/
u8 ide_dma_speed(ide_drive_t *drive, u8 mode)
{
struct hd_driveid *id = drive->id;
ide_hwif_t *hwif = HWIF(drive);
+ u8 ultra_mask, mwdma_mask, swdma_mask;
u8 speed = 0;
if (drive->media != ide_disk && hwif->atapi_dma == 0)
return 0;
- switch(mode) {
- case 0x04:
- if ((id->dma_ultra & 0x0040) &&
- (id->dma_ultra & hwif->ultra_mask))
- { speed = XFER_UDMA_6; break; }
- case 0x03:
- if ((id->dma_ultra & 0x0020) &&
- (id->dma_ultra & hwif->ultra_mask))
- { speed = XFER_UDMA_5; break; }
- case 0x02:
- if ((id->dma_ultra & 0x0010) &&
- (id->dma_ultra & hwif->ultra_mask))
- { speed = XFER_UDMA_4; break; }
- if ((id->dma_ultra & 0x0008) &&
- (id->dma_ultra & hwif->ultra_mask))
- { speed = XFER_UDMA_3; break; }
- case 0x01:
- if ((id->dma_ultra & 0x0004) &&
- (id->dma_ultra & hwif->ultra_mask))
- { speed = XFER_UDMA_2; break; }
- if ((id->dma_ultra & 0x0002) &&
- (id->dma_ultra & hwif->ultra_mask))
- { speed = XFER_UDMA_1; break; }
- if ((id->dma_ultra & 0x0001) &&
- (id->dma_ultra & hwif->ultra_mask))
- { speed = XFER_UDMA_0; break; }
- case 0x00:
- if ((id->dma_mword & 0x0004) &&
- (id->dma_mword & hwif->mwdma_mask))
- { speed = XFER_MW_DMA_2; break; }
- if ((id->dma_mword & 0x0002) &&
- (id->dma_mword & hwif->mwdma_mask))
- { speed = XFER_MW_DMA_1; break; }
- if ((id->dma_mword & 0x0001) &&
- (id->dma_mword & hwif->mwdma_mask))
- { speed = XFER_MW_DMA_0; break; }
- if ((id->dma_1word & 0x0004) &&
- (id->dma_1word & hwif->swdma_mask))
- { speed = XFER_SW_DMA_2; break; }
- if ((id->dma_1word & 0x0002) &&
- (id->dma_1word & hwif->swdma_mask))
- { speed = XFER_SW_DMA_1; break; }
- if ((id->dma_1word & 0x0001) &&
- (id->dma_1word & hwif->swdma_mask))
- { speed = XFER_SW_DMA_0; break; }
- }
+ /* Capable of UltraDMA modes? */
+ ultra_mask = id->dma_ultra & hwif->ultra_mask;
+
+ if (!(id->field_valid & 4))
+ mode = 0; /* fallback to MW/SW DMA if no UltraDMA */
+
+ switch (mode) {
+ case 4:
+ if (ultra_mask & 0x40) {
+ speed = XFER_UDMA_6;
+ break;
+ }
+ case 3:
+ if (ultra_mask & 0x20) {
+ speed = XFER_UDMA_5;
+ break;
+ }
+ case 2:
+ if (ultra_mask & 0x10) {
+ speed = XFER_UDMA_4;
+ break;
+ }
+ if (ultra_mask & 0x08) {
+ speed = XFER_UDMA_3;
+ break;
+ }
+ case 1:
+ if (ultra_mask & 0x04) {
+ speed = XFER_UDMA_2;
+ break;
+ }
+ if (ultra_mask & 0x02) {
+ speed = XFER_UDMA_1;
+ break;
+ }
+ if (ultra_mask & 0x01) {
+ speed = XFER_UDMA_0;
+ break;
+ }
+ case 0:
+ mwdma_mask = id->dma_mword & hwif->mwdma_mask;
-// printk("%s: %s: mode 0x%02x, speed 0x%02x\n",
-// __FUNCTION__, drive->name, mode, speed);
+ if (mwdma_mask & 0x04) {
+ speed = XFER_MW_DMA_2;
+ break;
+ }
+ if (mwdma_mask & 0x02) {
+ speed = XFER_MW_DMA_1;
+ break;
+ }
+ if (mwdma_mask & 0x01) {
+ speed = XFER_MW_DMA_0;
+ break;
+ }
+
+ swdma_mask = id->dma_1word & hwif->swdma_mask;
+
+ if (swdma_mask & 0x04) {
+ speed = XFER_SW_DMA_2;
+ break;
+ }
+ if (swdma_mask & 0x02) {
+ speed = XFER_SW_DMA_1;
+ break;
+ }
+ if (swdma_mask & 0x01) {
+ speed = XFER_SW_DMA_0;
+ break;
+ }
+ }
return speed;
}
-
EXPORT_SYMBOL(ide_dma_speed);
@@ -456,13 +477,14 @@ static void ide_dump_opcode(ide_drive_t *drive)
spin_unlock(&ide_lock);
if (!rq)
return;
- if (rq->flags & (REQ_DRIVE_CMD | REQ_DRIVE_TASK)) {
+ if (rq->cmd_type == REQ_TYPE_ATA_CMD ||
+ rq->cmd_type == REQ_TYPE_ATA_TASK) {
char *args = rq->buffer;
if (args) {
opcode = args[0];
found = 1;
}
- } else if (rq->flags & REQ_DRIVE_TASKFILE) {
+ } else if (rq->cmd_type == REQ_TYPE_ATA_TASKFILE) {
ide_task_t *args = rq->special;
if (args) {
task_struct_t *tf = (task_struct_t *) args->tfRegister;
diff --git a/drivers/ide/ide-probe.c b/drivers/ide/ide-probe.c
index 9cadf0106c6c..dad9c47ebb69 100644
--- a/drivers/ide/ide-probe.c
+++ b/drivers/ide/ide-probe.c
@@ -623,6 +623,8 @@ static void hwif_release_dev (struct device *dev)
static void hwif_register (ide_hwif_t *hwif)
{
+ int ret;
+
/* register with global device tree */
strlcpy(hwif->gendev.bus_id,hwif->name,BUS_ID_SIZE);
hwif->gendev.driver_data = hwif;
@@ -634,7 +636,10 @@ static void hwif_register (ide_hwif_t *hwif)
hwif->gendev.parent = NULL;
}
hwif->gendev.release = hwif_release_dev;
- device_register(&hwif->gendev);
+ ret = device_register(&hwif->gendev);
+ if (ret < 0)
+ printk(KERN_WARNING "IDE: %s: device_register error: %d\n",
+ __FUNCTION__, ret);
}
static int wait_hwif_ready(ide_hwif_t *hwif)
@@ -884,13 +889,19 @@ int probe_hwif_init_with_fixup(ide_hwif_t *hwif, void (*fixup)(ide_hwif_t *hwif)
if (hwif->present) {
u16 unit = 0;
+ int ret;
+
for (unit = 0; unit < MAX_DRIVES; ++unit) {
ide_drive_t *drive = &hwif->drives[unit];
/* For now don't attach absent drives, we may
want them on default or a new "empty" class
for hotplug reprobing ? */
if (drive->present) {
- device_register(&drive->gendev);
+ ret = device_register(&drive->gendev);
+ if (ret < 0)
+ printk(KERN_WARNING "IDE: %s: "
+ "device_register error: %d\n",
+ __FUNCTION__, ret);
}
}
}
@@ -1409,8 +1420,14 @@ int ideprobe_init (void)
if (hwif->chipset == ide_unknown || hwif->chipset == ide_forced)
hwif->chipset = ide_generic;
for (unit = 0; unit < MAX_DRIVES; ++unit)
- if (hwif->drives[unit].present)
- device_register(&hwif->drives[unit].gendev);
+ if (hwif->drives[unit].present) {
+ int ret = device_register(
+ &hwif->drives[unit].gendev);
+ if (ret < 0)
+ printk(KERN_WARNING "IDE: %s: "
+ "device_register error: %d\n",
+ __FUNCTION__, ret);
+ }
}
}
return 0;
diff --git a/drivers/ide/ide-proc.c b/drivers/ide/ide-proc.c
index 41b74b13a00c..aa049dab3d95 100644
--- a/drivers/ide/ide-proc.c
+++ b/drivers/ide/ide-proc.c
@@ -326,15 +326,24 @@ static int ide_replace_subdriver(ide_drive_t *drive, const char *driver)
{
struct device *dev = &drive->gendev;
int ret = 1;
+ int err;
down_write(&dev->bus->subsys.rwsem);
device_release_driver(dev);
/* FIXME: device can still be in use by previous driver */
strlcpy(drive->driver_req, driver, sizeof(drive->driver_req));
- device_attach(dev);
+ err = device_attach(dev);
+ if (err < 0)
+ printk(KERN_WARNING "IDE: %s: device_attach error: %d\n",
+ __FUNCTION__, err);
drive->driver_req[0] = 0;
- if (dev->driver == NULL)
- device_attach(dev);
+ if (dev->driver == NULL) {
+ err = device_attach(dev);
+ if (err < 0)
+ printk(KERN_WARNING
+ "IDE: %s: device_attach(2) error: %d\n",
+ __FUNCTION__, err);
+ }
if (dev->driver && !strcmp(dev->driver->name, driver))
ret = 0;
up_write(&dev->bus->subsys.rwsem);
@@ -526,7 +535,12 @@ static int proc_print_driver(struct device_driver *drv, void *data)
static int ide_drivers_show(struct seq_file *s, void *p)
{
- bus_for_each_drv(&ide_bus_type, NULL, s, proc_print_driver);
+ int err;
+
+ err = bus_for_each_drv(&ide_bus_type, NULL, s, proc_print_driver);
+ if (err < 0)
+ printk(KERN_WARNING "IDE: %s: bus_for_each_drv error: %d\n",
+ __FUNCTION__, err);
return 0;
}
diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c
index 7067ab997927..e2f4bb549063 100644
--- a/drivers/ide/ide-tape.c
+++ b/drivers/ide/ide-tape.c
@@ -1776,7 +1776,7 @@ static void idetape_create_request_sense_cmd (idetape_pc_t *pc)
static void idetape_init_rq(struct request *rq, u8 cmd)
{
memset(rq, 0, sizeof(*rq));
- rq->flags = REQ_SPECIAL;
+ rq->cmd_type = REQ_TYPE_SPECIAL;
rq->cmd[0] = cmd;
}
@@ -2423,8 +2423,8 @@ static ide_startstop_t idetape_do_request(ide_drive_t *drive,
#if IDETAPE_DEBUG_LOG
#if 0
if (tape->debug_level >= 5)
- printk(KERN_INFO "ide-tape: rq_status: %d, "
- "dev: %s, cmd: %ld, errors: %d\n", rq->rq_status,
+ printk(KERN_INFO "ide-tape: %d, "
+ "dev: %s, cmd: %ld, errors: %d\n",
rq->rq_disk->disk_name, rq->cmd[0], rq->errors);
#endif
if (tape->debug_level >= 2)
@@ -2433,12 +2433,12 @@ static ide_startstop_t idetape_do_request(ide_drive_t *drive,
rq->sector, rq->nr_sectors, rq->current_nr_sectors);
#endif /* IDETAPE_DEBUG_LOG */
- if ((rq->flags & REQ_SPECIAL) == 0) {
+ if (!blk_special_request(rq)) {
/*
* We do not support buffer cache originated requests.
*/
printk(KERN_NOTICE "ide-tape: %s: Unsupported request in "
- "request queue (%ld)\n", drive->name, rq->flags);
+ "request queue (%d)\n", drive->name, rq->cmd_type);
ide_end_request(drive, 0, 0);
return ide_stopped;
}
@@ -2764,16 +2764,16 @@ static void idetape_add_stage_tail (ide_drive_t *drive,idetape_stage_t *stage)
*/
static void idetape_wait_for_request (ide_drive_t *drive, struct request *rq)
{
- DECLARE_COMPLETION(wait);
+ DECLARE_COMPLETION_ONSTACK(wait);
idetape_tape_t *tape = drive->driver_data;
#if IDETAPE_DEBUG_BUGS
- if (rq == NULL || (rq->flags & REQ_SPECIAL) == 0) {
+ if (rq == NULL || !blk_special_request(rq)) {
printk (KERN_ERR "ide-tape: bug: Trying to sleep on non-valid request\n");
return;
}
#endif /* IDETAPE_DEBUG_BUGS */
- rq->waiting = &wait;
+ rq->end_io_data = &wait;
rq->end_io = blk_end_sync_rq;
spin_unlock_irq(&tape->spinlock);
wait_for_completion(&wait);
diff --git a/drivers/ide/ide-taskfile.c b/drivers/ide/ide-taskfile.c
index 97a9244312fc..1d0470c1f957 100644
--- a/drivers/ide/ide-taskfile.c
+++ b/drivers/ide/ide-taskfile.c
@@ -363,7 +363,7 @@ static ide_startstop_t task_error(ide_drive_t *drive, struct request *rq,
static void task_end_request(ide_drive_t *drive, struct request *rq, u8 stat)
{
- if (rq->flags & REQ_DRIVE_TASKFILE) {
+ if (rq->cmd_type == REQ_TYPE_ATA_TASKFILE) {
ide_task_t *task = rq->special;
if (task->tf_out_flags.all) {
@@ -474,7 +474,7 @@ static int ide_diag_taskfile(ide_drive_t *drive, ide_task_t *args, unsigned long
struct request rq;
memset(&rq, 0, sizeof(rq));
- rq.flags = REQ_DRIVE_TASKFILE;
+ rq.cmd_type = REQ_TYPE_ATA_TASKFILE;
rq.buffer = buf;
/*
@@ -499,7 +499,7 @@ static int ide_diag_taskfile(ide_drive_t *drive, ide_task_t *args, unsigned long
rq.hard_cur_sectors = rq.current_nr_sectors = rq.nr_sectors;
if (args->command_type == IDE_DRIVE_TASK_RAW_WRITE)
- rq.flags |= REQ_RW;
+ rq.cmd_flags |= REQ_RW;
}
rq.special = args;
@@ -737,7 +737,7 @@ static int ide_wait_cmd_task(ide_drive_t *drive, u8 *buf)
struct request rq;
ide_init_drive_cmd(&rq);
- rq.flags = REQ_DRIVE_TASK;
+ rq.cmd_type = REQ_TYPE_ATA_TASK;
rq.buffer = buf;
return ide_do_drive_cmd(drive, &rq, ide_wait);
}
diff --git a/drivers/ide/ide.c b/drivers/ide/ide.c
index 9c8468de1a75..287a66201150 100644
--- a/drivers/ide/ide.c
+++ b/drivers/ide/ide.c
@@ -450,7 +450,7 @@ void ide_hwif_release_regions(ide_hwif_t *hwif)
* @hwif: hwif to update
* @tmp_hwif: template
*
- * Restore hwif to a previous state by copying most settngs
+ * Restore hwif to a previous state by copying most settings
* from the template.
*/
@@ -539,9 +539,10 @@ static void ide_hwif_restore(ide_hwif_t *hwif, ide_hwif_t *tmp_hwif)
hwif->dma_vendor3 = tmp_hwif->dma_vendor3;
hwif->dma_prdtable = tmp_hwif->dma_prdtable;
- hwif->dma_extra = tmp_hwif->dma_extra;
hwif->config_data = tmp_hwif->config_data;
hwif->select_data = tmp_hwif->select_data;
+ hwif->extra_base = tmp_hwif->extra_base;
+ hwif->extra_ports = tmp_hwif->extra_ports;
hwif->autodma = tmp_hwif->autodma;
hwif->udma_four = tmp_hwif->udma_four;
hwif->no_dsc = tmp_hwif->no_dsc;
@@ -550,7 +551,7 @@ static void ide_hwif_restore(ide_hwif_t *hwif, ide_hwif_t *tmp_hwif)
}
/**
- * ide_unregister - free an ide interface
+ * ide_unregister - free an IDE interface
* @index: index of interface (will change soon to a pointer)
*
* Perform the final unregister of an IDE interface. At the moment
@@ -563,8 +564,8 @@ static void ide_hwif_restore(ide_hwif_t *hwif, ide_hwif_t *tmp_hwif)
* deadlocking the IDE layer. The shutdown callback is called
* before we take the lock and free resources. It is up to the
* caller to be sure there is no pending I/O here, and that
- * the interfce will not be reopened (present/vanishing locking
- * isnt yet done btw). After we commit to the final kill we
+ * the interface will not be reopened (present/vanishing locking
+ * isn't yet done BTW). After we commit to the final kill we
* call the cleanup callback with the ide locks held.
*
* Unregister restores the hwif structures to the default state.
@@ -674,6 +675,9 @@ void ide_unregister(unsigned int index)
hwif->dma_status = 0;
hwif->dma_vendor3 = 0;
hwif->dma_prdtable = 0;
+
+ hwif->extra_base = 0;
+ hwif->extra_ports = 0;
}
/* copy original settings */
@@ -1217,9 +1221,9 @@ static int generic_ide_suspend(struct device *dev, pm_message_t mesg)
memset(&rq, 0, sizeof(rq));
memset(&rqpm, 0, sizeof(rqpm));
memset(&args, 0, sizeof(args));
- rq.flags = REQ_PM_SUSPEND;
+ rq.cmd_type = REQ_TYPE_PM_SUSPEND;
rq.special = &args;
- rq.end_io_data = &rqpm;
+ rq.data = &rqpm;
rqpm.pm_step = ide_pm_state_start_suspend;
if (mesg.event == PM_EVENT_PRETHAW)
mesg.event = PM_EVENT_FREEZE;
@@ -1238,9 +1242,9 @@ static int generic_ide_resume(struct device *dev)
memset(&rq, 0, sizeof(rq));
memset(&rqpm, 0, sizeof(rqpm));
memset(&args, 0, sizeof(args));
- rq.flags = REQ_PM_RESUME;
+ rq.cmd_type = REQ_TYPE_PM_RESUME;
rq.special = &args;
- rq.end_io_data = &rqpm;
+ rq.data = &rqpm;
rqpm.pm_step = ide_pm_state_start_resume;
rqpm.pm_state = PM_EVENT_ON;
@@ -1360,6 +1364,11 @@ int generic_ide_ioctl(ide_drive_t *drive, struct file *file, struct block_device
spin_lock_irqsave(&ide_lock, flags);
+ if (HWGROUP(drive)->resetting) {
+ spin_unlock_irqrestore(&ide_lock, flags);
+ return -EBUSY;
+ }
+
ide_abort(drive, "drive reset");
BUG_ON(HWGROUP(drive)->handler);
@@ -1993,10 +2002,16 @@ EXPORT_SYMBOL_GPL(ide_bus_type);
*/
static int __init ide_init(void)
{
+ int ret;
+
printk(KERN_INFO "Uniform Multi-Platform E-IDE driver " REVISION "\n");
system_bus_speed = ide_system_bus_speed();
- bus_register(&ide_bus_type);
+ ret = bus_register(&ide_bus_type);
+ if (ret < 0) {
+ printk(KERN_WARNING "IDE: bus_register error: %d\n", ret);
+ return ret;
+ }
init_ide_data();
diff --git a/drivers/ide/legacy/hd.c b/drivers/ide/legacy/hd.c
index aebecd8f51cc..4ab931145673 100644
--- a/drivers/ide/legacy/hd.c
+++ b/drivers/ide/legacy/hd.c
@@ -626,7 +626,7 @@ repeat:
req->rq_disk->disk_name, (req->cmd == READ)?"read":"writ",
cyl, head, sec, nsect, req->buffer);
#endif
- if (req->flags & REQ_CMD) {
+ if (blk_fs_request(req)) {
switch (rq_data_dir(req)) {
case READ:
hd_out(disk,nsect,sec,head,cyl,WIN_READ,&read_intr);
diff --git a/drivers/ide/legacy/ide-cs.c b/drivers/ide/legacy/ide-cs.c
index 602797a44208..bef4759f70e5 100644
--- a/drivers/ide/legacy/ide-cs.c
+++ b/drivers/ide/legacy/ide-cs.c
@@ -120,7 +120,7 @@ static int ide_probe(struct pcmcia_device *link)
link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
link->io.Attributes2 = IO_DATA_PATH_WIDTH_8;
link->io.IOAddrLines = 3;
- link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
+ link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
link->irq.IRQInfo1 = IRQ_LEVEL_ID;
link->conf.Attributes = CONF_ENABLE_IRQ;
link->conf.IntType = INT_MEMORY_AND_IO;
@@ -398,12 +398,17 @@ static struct pcmcia_device_id ide_ids[] = {
PCMCIA_DEVICE_PROD_ID12("IO DATA", "PCIDE", 0x547e66dc, 0x5c5ab149),
PCMCIA_DEVICE_PROD_ID12("IO DATA", "PCIDEII", 0x547e66dc, 0xb3662674),
PCMCIA_DEVICE_PROD_ID12("LOOKMEET", "CBIDE2 ", 0xe37be2b5, 0x8671043b),
+ PCMCIA_DEVICE_PROD_ID12("M-Systems", "CF500", 0x7ed2ad87, 0x7a13045c),
PCMCIA_DEVICE_PROD_ID2("NinjaATA-", 0xebe0bd79),
PCMCIA_DEVICE_PROD_ID12("PCMCIA", "CD-ROM", 0x281f1c5d, 0x66536591),
PCMCIA_DEVICE_PROD_ID12("PCMCIA", "PnPIDE", 0x281f1c5d, 0x0c694728),
PCMCIA_DEVICE_PROD_ID12("SHUTTLE TECHNOLOGY LTD.", "PCCARD-IDE/ATAPI Adapter", 0x4a3f0ba0, 0x322560e1),
+ PCMCIA_DEVICE_PROD_ID12("SEAGATE", "ST1", 0x87c1b330, 0xe1f30883),
+ PCMCIA_DEVICE_PROD_ID12("SAMSUNG", "04/05/06", 0x43d74cb4, 0x6a22777d),
+ PCMCIA_DEVICE_PROD_ID12("SMI VENDOR", "SMI PRODUCT", 0x30896c92, 0x703cc5f6),
PCMCIA_DEVICE_PROD_ID12("TOSHIBA", "MK2001MPL", 0xb4585a1a, 0x3489e003),
PCMCIA_DEVICE_PROD_ID1("TRANSCEND 512M ", 0xd0909443),
+ PCMCIA_DEVICE_PROD_ID12("TRANSCEND", "TS4GCF120", 0x709b1bf1, 0xf54a91c8),
PCMCIA_DEVICE_PROD_ID12("WIT", "IDE16", 0x244e5994, 0x3e232852),
PCMCIA_DEVICE_PROD_ID1("STI Flash", 0xe4a13209),
PCMCIA_DEVICE_PROD_ID12("STI", "Flash 5.0", 0xbf2df18d, 0x8cb57a0e),
diff --git a/drivers/ide/pci/Makefile b/drivers/ide/pci/Makefile
index f35d684edc25..640a54b09b5a 100644
--- a/drivers/ide/pci/Makefile
+++ b/drivers/ide/pci/Makefile
@@ -14,6 +14,7 @@ obj-$(CONFIG_BLK_DEV_HPT366) += hpt366.o
#obj-$(CONFIG_BLK_DEV_HPT37X) += hpt37x.o
obj-$(CONFIG_BLK_DEV_IT8172) += it8172.o
obj-$(CONFIG_BLK_DEV_IT821X) += it821x.o
+obj-$(CONFIG_BLK_DEV_JMICRON) += jmicron.o
obj-$(CONFIG_BLK_DEV_NS87415) += ns87415.o
obj-$(CONFIG_BLK_DEV_OPTI621) += opti621.o
obj-$(CONFIG_BLK_DEV_PDC202XX_OLD) += pdc202xx_old.o
diff --git a/drivers/ide/pci/atiixp.c b/drivers/ide/pci/atiixp.c
index a574de5f0835..d55b938b1aeb 100644
--- a/drivers/ide/pci/atiixp.c
+++ b/drivers/ide/pci/atiixp.c
@@ -318,6 +318,20 @@ static void __devinit init_hwif_atiixp(ide_hwif_t *hwif)
hwif->drives[0].autodma = hwif->autodma;
}
+static void __devinit init_hwif_sb600_legacy(ide_hwif_t *hwif)
+{
+
+ hwif->atapi_dma = 1;
+ hwif->ultra_mask = 0x7f;
+ hwif->mwdma_mask = 0x07;
+ hwif->swdma_mask = 0x07;
+
+ if (!noautodma)
+ hwif->autodma = 1;
+ hwif->drives[0].autodma = hwif->autodma;
+ hwif->drives[1].autodma = hwif->autodma;
+}
+
static ide_pci_device_t atiixp_pci_info[] __devinitdata = {
{ /* 0 */
.name = "ATIIXP",
@@ -326,6 +340,12 @@ static ide_pci_device_t atiixp_pci_info[] __devinitdata = {
.autodma = AUTODMA,
.enablebits = {{0x48,0x01,0x00}, {0x48,0x08,0x00}},
.bootable = ON_BOARD,
+ },{ /* 1 */
+ .name = "ATI SB600 SATA Legacy IDE",
+ .init_hwif = init_hwif_sb600_legacy,
+ .channels = 2,
+ .autodma = AUTODMA,
+ .bootable = ON_BOARD,
}
};
@@ -348,6 +368,7 @@ static struct pci_device_id atiixp_pci_tbl[] = {
{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP300_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP400_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP600_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP600_SATA, PCI_ANY_ID, PCI_ANY_ID, (PCI_CLASS_STORAGE_IDE<<8)|0x8a, 0xffff05, 1},
{ 0, },
};
MODULE_DEVICE_TABLE(pci, atiixp_pci_tbl);
diff --git a/drivers/ide/pci/cs5530.c b/drivers/ide/pci/cs5530.c
index 380bb28c7c54..ae405fa32236 100644
--- a/drivers/ide/pci/cs5530.c
+++ b/drivers/ide/pci/cs5530.c
@@ -222,23 +222,23 @@ static unsigned int __devinit init_chipset_cs5530 (struct pci_dev *dev, const ch
unsigned long flags;
dev = NULL;
- while ((dev = pci_find_device(PCI_VENDOR_ID_CYRIX, PCI_ANY_ID, dev)) != NULL) {
+ while ((dev = pci_get_device(PCI_VENDOR_ID_CYRIX, PCI_ANY_ID, dev)) != NULL) {
switch (dev->device) {
case PCI_DEVICE_ID_CYRIX_PCI_MASTER:
- master_0 = dev;
+ master_0 = pci_dev_get(dev);
break;
case PCI_DEVICE_ID_CYRIX_5530_LEGACY:
- cs5530_0 = dev;
+ cs5530_0 = pci_dev_get(dev);
break;
}
}
if (!master_0) {
printk(KERN_ERR "%s: unable to locate PCI MASTER function\n", name);
- return 0;
+ goto out;
}
if (!cs5530_0) {
printk(KERN_ERR "%s: unable to locate CS5530 LEGACY function\n", name);
- return 0;
+ goto out;
}
spin_lock_irqsave(&ide_lock, flags);
@@ -296,6 +296,9 @@ static unsigned int __devinit init_chipset_cs5530 (struct pci_dev *dev, const ch
spin_unlock_irqrestore(&ide_lock, flags);
+out:
+ pci_dev_put(master_0);
+ pci_dev_put(cs5530_0);
return 0;
}
diff --git a/drivers/ide/pci/cy82c693.c b/drivers/ide/pci/cy82c693.c
index 120929fbe7a3..64330c459bd4 100644
--- a/drivers/ide/pci/cy82c693.c
+++ b/drivers/ide/pci/cy82c693.c
@@ -281,7 +281,7 @@ static void cy82c693_tune_drive (ide_drive_t *drive, u8 pio)
/* select primary or secondary channel */
if (hwif->index > 0) { /* drive is on the secondary channel */
- dev = pci_find_slot(dev->bus->number, dev->devfn+1);
+ dev = pci_get_slot(dev->bus, dev->devfn+1);
if (!dev) {
printk(KERN_ERR "%s: tune_drive: "
"Cannot find secondary interface!\n",
@@ -500,8 +500,9 @@ static int __devinit cy82c693_init_one(struct pci_dev *dev, const struct pci_dev
Function 1 is primary IDE channel, function 2 - secondary. */
if ((dev->class >> 8) == PCI_CLASS_STORAGE_IDE &&
PCI_FUNC(dev->devfn) == 1) {
- dev2 = pci_find_slot(dev->bus->number, dev->devfn + 1);
+ dev2 = pci_get_slot(dev->bus, dev->devfn + 1);
ret = ide_setup_pci_devices(dev, dev2, d);
+ /* We leak pci refs here but thats ok - we can't be unloaded */
}
return ret;
}
diff --git a/drivers/ide/pci/generic.c b/drivers/ide/pci/generic.c
index 78810ba982e9..0cb7b9b520ea 100644
--- a/drivers/ide/pci/generic.c
+++ b/drivers/ide/pci/generic.c
@@ -41,15 +41,8 @@
static int ide_generic_all; /* Set to claim all devices */
-#ifndef MODULE
-static int __init ide_generic_all_on(char *unused)
-{
- ide_generic_all = 1;
- printk(KERN_INFO "IDE generic will claim all unknown PCI IDE storage controllers.\n");
- return 1;
-}
-__setup("all-generic-ide", ide_generic_all_on);
-#endif
+module_param_named(all_generic_ide, ide_generic_all, bool, 0444);
+MODULE_PARM_DESC(all_generic_ide, "IDE generic will claim all unknown PCI IDE storage controllers.");
static void __devinit init_hwif_generic (ide_hwif_t *hwif)
{
diff --git a/drivers/ide/pci/jmicron.c b/drivers/ide/pci/jmicron.c
new file mode 100644
index 000000000000..68c74bbf8b06
--- /dev/null
+++ b/drivers/ide/pci/jmicron.c
@@ -0,0 +1,269 @@
+
+/*
+ * Copyright (C) 2006 Red Hat <alan@redhat.com>
+ *
+ * May be copied or modified under the terms of the GNU General Public License
+ */
+
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/delay.h>
+#include <linux/hdreg.h>
+#include <linux/ide.h>
+#include <linux/init.h>
+
+#include <asm/io.h>
+
+typedef enum {
+ PORT_PATA0 = 0,
+ PORT_PATA1 = 1,
+ PORT_SATA = 2,
+} port_type;
+
+/**
+ * jmicron_ratemask - Compute available modes
+ * @drive: IDE drive
+ *
+ * Compute the available speeds for the devices on the interface. This
+ * is all modes to ATA133 clipped by drive cable setup.
+ */
+
+static u8 jmicron_ratemask(ide_drive_t *drive)
+{
+ u8 mode = 4;
+ if (!eighty_ninty_three(drive))
+ mode = min(mode, (u8)1);
+ return mode;
+}
+
+/**
+ * ata66_jmicron - Cable check
+ * @hwif: IDE port
+ *
+ * Return 1 if the cable is 80pin
+ */
+
+static int __devinit ata66_jmicron(ide_hwif_t *hwif)
+{
+ struct pci_dev *pdev = hwif->pci_dev;
+
+ u32 control;
+ u32 control5;
+
+ int port = hwif->channel;
+ port_type port_map[2];
+
+ pci_read_config_dword(pdev, 0x40, &control);
+
+ /* There are two basic mappings. One has the two SATA ports merged
+ as master/slave and the secondary as PATA, the other has only the
+ SATA port mapped */
+ if (control & (1 << 23)) {
+ port_map[0] = PORT_SATA;
+ port_map[1] = PORT_PATA0;
+ } else {
+ port_map[0] = PORT_SATA;
+ port_map[1] = PORT_SATA;
+ }
+
+ /* The 365/366 may have this bit set to map the second PATA port
+ as the internal primary channel */
+ pci_read_config_dword(pdev, 0x80, &control5);
+ if (control5 & (1<<24))
+ port_map[0] = PORT_PATA1;
+
+ /* The two ports may then be logically swapped by the firmware */
+ if (control & (1 << 22))
+ port = port ^ 1;
+
+ /*
+ * Now we know which physical port we are talking about we can
+ * actually do our cable checking etc. Thankfully we don't need
+ * to do the plumbing for other cases.
+ */
+ switch (port_map[port])
+ {
+ case PORT_PATA0:
+ if (control & (1 << 3)) /* 40/80 pin primary */
+ return 1;
+ return 0;
+ case PORT_PATA1:
+ if (control5 & (1 << 19)) /* 40/80 pin secondary */
+ return 0;
+ return 1;
+ case PORT_SATA:
+ return 1;
+ }
+}
+
+static void jmicron_tuneproc (ide_drive_t *drive, byte mode_wanted)
+{
+ return;
+}
+
+/**
+ * config_jmicron_chipset_for_pio - set drive timings
+ * @drive: drive to tune
+ * @speed we want
+ *
+ */
+
+static void config_jmicron_chipset_for_pio (ide_drive_t *drive, byte set_speed)
+{
+ u8 speed = XFER_PIO_0 + ide_get_best_pio_mode(drive, 255, 5, NULL);
+ if (set_speed)
+ (void) ide_config_drive_speed(drive, speed);
+}
+
+/**
+ * jmicron_tune_chipset - set controller timings
+ * @drive: Drive to set up
+ * @xferspeed: speed we want to achieve
+ *
+ * As the JMicron snoops for timings all we actually need to do is
+ * make sure we don't set an invalid mode. We do need to honour
+ * the cable detect here.
+ */
+
+static int jmicron_tune_chipset (ide_drive_t *drive, byte xferspeed)
+{
+
+ u8 speed = ide_rate_filter(jmicron_ratemask(drive), xferspeed);
+
+ return ide_config_drive_speed(drive, speed);
+}
+
+/**
+ * config_chipset_for_dma - configure for DMA
+ * @drive: drive to configure
+ *
+ * As the JMicron snoops for timings all we actually need to do is
+ * make sure we don't set an invalid mode.
+ */
+
+static int config_chipset_for_dma (ide_drive_t *drive)
+{
+ u8 speed = ide_dma_speed(drive, jmicron_ratemask(drive));
+
+ config_jmicron_chipset_for_pio(drive, !speed);
+ jmicron_tune_chipset(drive, speed);
+ return ide_dma_enable(drive);
+}
+
+/**
+ * jmicron_configure_drive_for_dma - set up for DMA transfers
+ * @drive: drive we are going to set up
+ *
+ * As the JMicron snoops for timings all we actually need to do is
+ * make sure we don't set an invalid mode.
+ */
+
+static int jmicron_config_drive_for_dma (ide_drive_t *drive)
+{
+ ide_hwif_t *hwif = drive->hwif;
+
+ if (ide_use_dma(drive)) {
+ if (config_chipset_for_dma(drive))
+ return hwif->ide_dma_on(drive);
+ }
+ config_jmicron_chipset_for_pio(drive, 1);
+ return hwif->ide_dma_off_quietly(drive);
+}
+
+/**
+ * init_hwif_jmicron - set up hwif structs
+ * @hwif: interface to set up
+ *
+ * Minimal set up is required for the Jmicron hardware.
+ */
+
+static void __devinit init_hwif_jmicron(ide_hwif_t *hwif)
+{
+ hwif->speedproc = &jmicron_tune_chipset;
+ hwif->tuneproc = &jmicron_tuneproc;
+
+ hwif->drives[0].autotune = 1;
+ hwif->drives[1].autotune = 1;
+
+ if (!hwif->dma_base)
+ goto fallback;
+
+ hwif->atapi_dma = 1;
+ hwif->ultra_mask = 0x7f;
+ hwif->mwdma_mask = 0x07;
+
+ hwif->ide_dma_check = &jmicron_config_drive_for_dma;
+ if (!(hwif->udma_four))
+ hwif->udma_four = ata66_jmicron(hwif);
+
+ hwif->autodma = 1;
+ hwif->drives[0].autodma = hwif->autodma;
+ hwif->drives[1].autodma = hwif->autodma;
+ return;
+fallback:
+ hwif->autodma = 0;
+ return;
+}
+
+#define DECLARE_JMB_DEV(name_str) \
+ { \
+ .name = name_str, \
+ .init_hwif = init_hwif_jmicron, \
+ .channels = 2, \
+ .autodma = AUTODMA, \
+ .bootable = ON_BOARD, \
+ .enablebits = { {0x40, 1, 1}, {0x40, 0x10, 0x10} }, \
+ }
+
+static ide_pci_device_t jmicron_chipsets[] __devinitdata = {
+ /* 0 */ DECLARE_JMB_DEV("JMB361"),
+ /* 1 */ DECLARE_JMB_DEV("JMB363"),
+ /* 2 */ DECLARE_JMB_DEV("JMB365"),
+ /* 3 */ DECLARE_JMB_DEV("JMB366"),
+ /* 4 */ DECLARE_JMB_DEV("JMB368"),
+};
+
+/**
+ * jmicron_init_one - pci layer discovery entry
+ * @dev: PCI device
+ * @id: ident table entry
+ *
+ * Called by the PCI code when it finds a Jmicron controller.
+ * We then use the IDE PCI generic helper to do most of the work.
+ */
+
+static int __devinit jmicron_init_one(struct pci_dev *dev, const struct pci_device_id *id)
+{
+ ide_setup_pci_device(dev, &jmicron_chipsets[id->driver_data]);
+ return 0;
+}
+
+static struct pci_device_id jmicron_pci_tbl[] = {
+ { PCI_DEVICE(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB361), 0},
+ { PCI_DEVICE(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB363), 1},
+ { PCI_DEVICE(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB365), 2},
+ { PCI_DEVICE(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB366), 3},
+ { PCI_DEVICE(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB368), 4},
+ { 0, },
+};
+
+MODULE_DEVICE_TABLE(pci, jmicron_pci_tbl);
+
+static struct pci_driver driver = {
+ .name = "JMicron IDE",
+ .id_table = jmicron_pci_tbl,
+ .probe = jmicron_init_one,
+};
+
+static int __init jmicron_ide_init(void)
+{
+ return ide_pci_register_driver(&driver);
+}
+
+module_init(jmicron_ide_init);
+
+MODULE_AUTHOR("Alan Cox");
+MODULE_DESCRIPTION("PCI driver module for the JMicron in legacy modes");
+MODULE_LICENSE("GPL");
diff --git a/drivers/ide/pci/pdc202xx_old.c b/drivers/ide/pci/pdc202xx_old.c
index b46022a11bef..184cdacddeb6 100644
--- a/drivers/ide/pci/pdc202xx_old.c
+++ b/drivers/ide/pci/pdc202xx_old.c
@@ -154,7 +154,8 @@ static int pdc202xx_tune_chipset (ide_drive_t *drive, u8 xferspeed)
u8 AP, BP, CP, DP;
u8 TA = 0, TB = 0, TC = 0;
- if ((drive->media != ide_disk) && (speed < XFER_SW_DMA_0))
+ if (drive->media != ide_disk &&
+ drive->media != ide_cdrom && speed < XFER_SW_DMA_0)
return -1;
pci_read_config_dword(dev, drive_pci, &drive_conf);
@@ -330,14 +331,12 @@ static int config_chipset_for_dma (ide_drive_t *drive)
chipset_is_set:
- if (drive->media == ide_disk) {
- pci_read_config_byte(dev, (drive_pci), &AP);
- if (id->capability & 4) /* IORDY_EN */
- pci_write_config_byte(dev, (drive_pci), AP|IORDY_EN);
- pci_read_config_byte(dev, (drive_pci), &AP);
- if (drive->media == ide_disk) /* PREFETCH_EN */
- pci_write_config_byte(dev, (drive_pci), AP|PREFETCH_EN);
- }
+ pci_read_config_byte(dev, (drive_pci), &AP);
+ if (id->capability & 4) /* IORDY_EN */
+ pci_write_config_byte(dev, (drive_pci), AP|IORDY_EN);
+ pci_read_config_byte(dev, (drive_pci), &AP);
+ if (drive->media == ide_disk) /* PREFETCH_EN */
+ pci_write_config_byte(dev, (drive_pci), AP|PREFETCH_EN);
speed = ide_dma_speed(drive, pdc202xx_ratemask(drive));
@@ -385,7 +384,7 @@ static void pdc202xx_old_ide_dma_start(ide_drive_t *drive)
{
if (drive->current_speed > XFER_UDMA_2)
pdc_old_enable_66MHz_clock(drive->hwif);
- if (drive->addressing == 1) {
+ if (drive->media != ide_disk || drive->addressing == 1) {
struct request *rq = HWGROUP(drive)->rq;
ide_hwif_t *hwif = HWIF(drive);
unsigned long high_16 = hwif->dma_master;
@@ -405,7 +404,7 @@ static void pdc202xx_old_ide_dma_start(ide_drive_t *drive)
static int pdc202xx_old_ide_dma_end(ide_drive_t *drive)
{
- if (drive->addressing == 1) {
+ if (drive->media != ide_disk || drive->addressing == 1) {
ide_hwif_t *hwif = HWIF(drive);
unsigned long high_16 = hwif->dma_master;
unsigned long atapi_reg = high_16 + (hwif->channel ? 0x24 : 0x20);
@@ -519,6 +518,7 @@ static void __devinit init_hwif_pdc202xx(ide_hwif_t *hwif)
hwif->ultra_mask = 0x3f;
hwif->mwdma_mask = 0x07;
hwif->swdma_mask = 0x07;
+ hwif->atapi_dma = 1;
hwif->err_stops_fifo = 1;
diff --git a/drivers/ide/pci/piix.c b/drivers/ide/pci/piix.c
index 50332ddd5ddb..cdc3aab9ebcb 100644
--- a/drivers/ide/pci/piix.c
+++ b/drivers/ide/pci/piix.c
@@ -222,13 +222,15 @@ static void piix_tune_drive (ide_drive_t *drive, u8 pio)
u16 master_data;
u8 slave_data;
static DEFINE_SPINLOCK(tune_lock);
+ int control = 0;
/* ISP RTC */
- u8 timings[][2] = { { 0, 0 },
- { 0, 0 },
- { 1, 0 },
- { 2, 1 },
- { 2, 3 }, };
+ static const u8 timings[][2]= {
+ { 0, 0 },
+ { 0, 0 },
+ { 1, 0 },
+ { 2, 1 },
+ { 2, 3 }, };
pio = ide_get_best_pio_mode(drive, pio, 5, NULL);
@@ -239,19 +241,30 @@ static void piix_tune_drive (ide_drive_t *drive, u8 pio)
*/
spin_lock_irqsave(&tune_lock, flags);
pci_read_config_word(dev, master_port, &master_data);
+
+ if (pio >= 2)
+ control |= 1; /* Programmable timing on */
+ if (drive->media == ide_disk)
+ control |= 4; /* Prefetch, post write */
+ if (pio >= 3)
+ control |= 2; /* IORDY */
if (is_slave) {
master_data = master_data | 0x4000;
- if (pio > 1)
+ if (pio > 1) {
/* enable PPE, IE and TIME */
- master_data = master_data | 0x0070;
+ master_data = master_data | (control << 4);
+ } else {
+ master_data &= ~0x0070;
+ }
pci_read_config_byte(dev, slave_port, &slave_data);
slave_data = slave_data & (hwif->channel ? 0x0f : 0xf0);
slave_data = slave_data | (((timings[pio][0] << 2) | timings[pio][1]) << (hwif->channel ? 4 : 0));
} else {
master_data = master_data & 0xccf8;
- if (pio > 1)
+ if (pio > 1) {
/* enable PPE, IE and TIME */
- master_data = master_data | 0x0007;
+ master_data = master_data | control;
+ }
master_data = master_data | (timings[pio][0] << 12) | (timings[pio][1] << 8);
}
pci_write_config_word(dev, master_port, master_data);
@@ -615,7 +628,7 @@ static void __devinit piix_check_450nx(void)
struct pci_dev *pdev = NULL;
u16 cfg;
u8 rev;
- while((pdev=pci_find_device(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82454NX, pdev))!=NULL)
+ while((pdev=pci_get_device(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82454NX, pdev))!=NULL)
{
/* Look for 450NX PXB. Check for problem configurations
A PCI quirk checks bit 6 already */
diff --git a/drivers/ide/pci/sc1200.c b/drivers/ide/pci/sc1200.c
index fc2b5496b6d2..ff80937d94dd 100644
--- a/drivers/ide/pci/sc1200.c
+++ b/drivers/ide/pci/sc1200.c
@@ -323,6 +323,7 @@ static void sc1200_tuneproc (ide_drive_t *drive, byte pio) /* mode=255 means "au
}
}
+#ifdef CONFIG_PM
static ide_hwif_t *lookup_pci_dev (ide_hwif_t *prev, struct pci_dev *dev)
{
int h;
@@ -451,6 +452,7 @@ static int sc1200_resume (struct pci_dev *dev)
}
return 0;
}
+#endif
/*
* This gets invoked by the IDE driver once for each channel,
@@ -499,8 +501,10 @@ static struct pci_driver driver = {
.name = "SC1200_IDE",
.id_table = sc1200_pci_tbl,
.probe = sc1200_init_one,
+#ifdef CONFIG_PM
.suspend = sc1200_suspend,
.resume = sc1200_resume,
+#endif
};
static int sc1200_ide_init(void)
diff --git a/drivers/ide/pci/serverworks.c b/drivers/ide/pci/serverworks.c
index f063d954236c..057548d07205 100644
--- a/drivers/ide/pci/serverworks.c
+++ b/drivers/ide/pci/serverworks.c
@@ -359,7 +359,7 @@ static unsigned int __devinit init_chipset_svwks (struct pci_dev *dev, const cha
/* OSB4 : South Bridge and IDE */
if (dev->device == PCI_DEVICE_ID_SERVERWORKS_OSB4IDE) {
- isa_dev = pci_find_device(PCI_VENDOR_ID_SERVERWORKS,
+ isa_dev = pci_get_device(PCI_VENDOR_ID_SERVERWORKS,
PCI_DEVICE_ID_SERVERWORKS_OSB4, NULL);
if (isa_dev) {
pci_read_config_dword(isa_dev, 0x64, &reg);
@@ -380,7 +380,7 @@ static unsigned int __devinit init_chipset_svwks (struct pci_dev *dev, const cha
if (!(PCI_FUNC(dev->devfn) & 1)) {
struct pci_dev * findev = NULL;
u32 reg4c = 0;
- findev = pci_find_device(PCI_VENDOR_ID_SERVERWORKS,
+ findev = pci_get_device(PCI_VENDOR_ID_SERVERWORKS,
PCI_DEVICE_ID_SERVERWORKS_CSB5, NULL);
if (findev) {
pci_read_config_dword(findev, 0x4C, &reg4c);
@@ -388,6 +388,7 @@ static unsigned int __devinit init_chipset_svwks (struct pci_dev *dev, const cha
reg4c |= 0x00000040;
reg4c |= 0x00000020;
pci_write_config_dword(findev, 0x4C, reg4c);
+ pci_dev_put(findev);
}
outb_p(0x06, 0x0c00);
dev->irq = inb_p(0x0c01);
@@ -395,12 +396,13 @@ static unsigned int __devinit init_chipset_svwks (struct pci_dev *dev, const cha
struct pci_dev * findev = NULL;
u8 reg41 = 0;
- findev = pci_find_device(PCI_VENDOR_ID_SERVERWORKS,
+ findev = pci_get_device(PCI_VENDOR_ID_SERVERWORKS,
PCI_DEVICE_ID_SERVERWORKS_CSB6, NULL);
if (findev) {
pci_read_config_byte(findev, 0x41, &reg41);
reg41 &= ~0x40;
pci_write_config_byte(findev, 0x41, reg41);
+ pci_dev_put(findev);
}
/*
* This is a device pin issue on CSB6.
diff --git a/drivers/ide/pci/sgiioc4.c b/drivers/ide/pci/sgiioc4.c
index d8a0d87df734..f3fe287fbd89 100644
--- a/drivers/ide/pci/sgiioc4.c
+++ b/drivers/ide/pci/sgiioc4.c
@@ -220,7 +220,7 @@ sgiioc4_ide_dma_end(ide_drive_t * drive)
ide_hwif_t *hwif = HWIF(drive);
u64 dma_base = hwif->dma_base;
int dma_stat = 0;
- unsigned long *ending_dma = (unsigned long *) hwif->dma_base2;
+ unsigned long *ending_dma = ide_get_hwifdata(hwif);
hwif->OUTL(IOC4_S_DMA_STOP, dma_base + IOC4_DMA_CTRL * 4);
@@ -369,6 +369,7 @@ ide_dma_sgiioc4(ide_hwif_t * hwif, unsigned long dma_base)
{
void __iomem *virt_dma_base;
int num_ports = sizeof (ioc4_dma_regs_t);
+ void *pad;
printk(KERN_INFO "%s: BM-DMA at 0x%04lx-0x%04lx\n", hwif->name,
dma_base, dma_base + num_ports - 1);
@@ -400,17 +401,14 @@ ide_dma_sgiioc4(ide_hwif_t * hwif, unsigned long dma_base)
hwif->sg_max_nents = IOC4_PRD_ENTRIES;
- hwif->dma_base2 = (unsigned long)
- pci_alloc_consistent(hwif->pci_dev,
- IOC4_IDE_CACHELINE_SIZE,
- (dma_addr_t *) &(hwif->dma_status));
+ pad = pci_alloc_consistent(hwif->pci_dev, IOC4_IDE_CACHELINE_SIZE,
+ (dma_addr_t *) &(hwif->dma_status));
- if (!hwif->dma_base2)
- goto dma_base2alloc_failure;
-
- return;
+ if (pad) {
+ ide_set_hwifdata(hwif, pad);
+ return;
+ }
-dma_base2alloc_failure:
pci_free_consistent(hwif->pci_dev,
IOC4_PRD_ENTRIES * IOC4_PRD_BYTES,
hwif->dmatable_cpu, hwif->dmatable_dma);
@@ -476,7 +474,7 @@ sgiioc4_configure_for_dma(int dma_direction, ide_drive_t * drive)
hwif->OUTL(dma_addr, dma_base + IOC4_DMA_PTR_L * 4);
/* Address of the Ending DMA */
- memset((unsigned int *) hwif->dma_base2, 0, IOC4_IDE_CACHELINE_SIZE);
+ memset(ide_get_hwifdata(hwif), 0, IOC4_IDE_CACHELINE_SIZE);
ending_dma_addr = cpu_to_le32(hwif->dma_status);
hwif->OUTL(ending_dma_addr, dma_base + IOC4_DMA_END_ADDR * 4);
diff --git a/drivers/ide/pci/siimage.c b/drivers/ide/pci/siimage.c
index 20b392948f36..697f566fb90a 100644
--- a/drivers/ide/pci/siimage.c
+++ b/drivers/ide/pci/siimage.c
@@ -898,7 +898,6 @@ static void __devinit init_mmio_iops_siimage(ide_hwif_t *hwif)
base = (unsigned long) addr;
hwif->dma_base = base + (ch ? 0x08 : 0x00);
- hwif->dma_base2 = base + (ch ? 0x18 : 0x10);
hwif->mmio = 2;
}
diff --git a/drivers/ide/pci/sis5513.c b/drivers/ide/pci/sis5513.c
index f03196c5db37..92edf76bd7ad 100644
--- a/drivers/ide/pci/sis5513.c
+++ b/drivers/ide/pci/sis5513.c
@@ -739,7 +739,7 @@ static unsigned int __devinit init_chipset_sis5513 (struct pci_dev *dev, const c
for (i = 0; i < ARRAY_SIZE(SiSHostChipInfo) && !chipset_family; i++) {
- host = pci_find_device(PCI_VENDOR_ID_SI, SiSHostChipInfo[i].host_id, NULL);
+ host = pci_get_device(PCI_VENDOR_ID_SI, SiSHostChipInfo[i].host_id, NULL);
if (!host)
continue;
@@ -753,6 +753,7 @@ static unsigned int __devinit init_chipset_sis5513 (struct pci_dev *dev, const c
if (hostrev >= 0x30)
chipset_family = ATA_100a;
}
+ pci_dev_put(host);
printk(KERN_INFO "SIS5513: %s %s controller\n",
SiSHostChipInfo[i].name, chipset_capability[chipset_family]);
diff --git a/drivers/ide/pci/via82cxxx.c b/drivers/ide/pci/via82cxxx.c
index 9b7589e8e93e..2af634d7acf4 100644
--- a/drivers/ide/pci/via82cxxx.c
+++ b/drivers/ide/pci/via82cxxx.c
@@ -248,7 +248,7 @@ static struct via_isa_bridge *via_config_find(struct pci_dev **isa)
u8 t;
for (via_config = via_isa_bridges; via_config->id; via_config++)
- if ((*isa = pci_find_device(PCI_VENDOR_ID_VIA +
+ if ((*isa = pci_get_device(PCI_VENDOR_ID_VIA +
!!(via_config->flags & VIA_BAD_ID),
via_config->id, NULL))) {
@@ -256,6 +256,7 @@ static struct via_isa_bridge *via_config_find(struct pci_dev **isa)
if (t >= via_config->rev_min &&
t <= via_config->rev_max)
break;
+ pci_dev_put(*isa);
}
return via_config;
@@ -283,6 +284,7 @@ static unsigned int __devinit init_chipset_via82cxxx(struct pci_dev *dev, const
via_config = via_config_find(&isa);
if (!via_config->id) {
printk(KERN_WARNING "VP_IDE: Unknown VIA SouthBridge, disabling DMA.\n");
+ pci_dev_put(isa);
return -ENODEV;
}
@@ -361,6 +363,7 @@ static unsigned int __devinit init_chipset_via82cxxx(struct pci_dev *dev, const
via_dma[via_config->flags & VIA_UDMA],
pci_name(dev));
+ pci_dev_put(isa);
return 0;
}
diff --git a/drivers/ide/setup-pci.c b/drivers/ide/setup-pci.c
index eb0945284acc..0719b6484824 100644
--- a/drivers/ide/setup-pci.c
+++ b/drivers/ide/setup-pci.c
@@ -101,7 +101,7 @@ static ide_hwif_t *ide_match_hwif(unsigned long io_base, u8 bootable, const char
return hwif; /* pick an unused entry */
}
}
- for (h = 0; h < 2; ++h) {
+ for (h = 0; h < 2 && h < MAX_HWIFS; ++h) {
hwif = ide_hwifs + h;
if (hwif->chipset == ide_unknown)
return hwif; /* pick an unused entry */
@@ -795,24 +795,6 @@ int __ide_pci_register_driver(struct pci_driver *driver, struct module *module)
EXPORT_SYMBOL_GPL(__ide_pci_register_driver);
/**
- * ide_unregister_pci_driver - unregister an IDE driver
- * @driver: driver to remove
- *
- * Unregister a currently installed IDE driver. Returns are the same
- * as for pci_unregister_driver
- */
-
-void ide_pci_unregister_driver(struct pci_driver *driver)
-{
- if(!pre_init)
- pci_unregister_driver(driver);
- else
- list_del(&driver->node);
-}
-
-EXPORT_SYMBOL_GPL(ide_pci_unregister_driver);
-
-/**
* ide_scan_pcidev - find an IDE driver for a device
* @dev: PCI device to check
*
diff --git a/drivers/ieee1394/Kconfig b/drivers/ieee1394/Kconfig
index 186737539cf5..2769e505f051 100644
--- a/drivers/ieee1394/Kconfig
+++ b/drivers/ieee1394/Kconfig
@@ -120,12 +120,19 @@ config IEEE1394_VIDEO1394
this option only if you have an IEEE 1394 video device connected to
an OHCI-1394 card.
+comment "SBP-2 support (for storage devices) requires SCSI"
+ depends on IEEE1394 && SCSI=n
+
config IEEE1394_SBP2
tristate "SBP-2 support (Harddisks etc.)"
depends on IEEE1394 && SCSI && (PCI || BROKEN)
help
- This option enables you to use SBP-2 devices connected to your IEEE
- 1394 bus. SBP-2 devices include harddrives and DVD devices.
+ This option enables you to use SBP-2 devices connected to an IEEE
+ 1394 bus. SBP-2 devices include storage devices like harddisks and
+ DVD drives, also some other FireWire devices like scanners.
+
+ You should also enable support for disks, CD-ROMs, etc. in the SCSI
+ configuration section.
config IEEE1394_SBP2_PHYS_DMA
bool "Enable replacement for physical DMA in SBP2"
diff --git a/drivers/ieee1394/csr.c b/drivers/ieee1394/csr.c
index 149573db91c5..ab0c80f61b9d 100644
--- a/drivers/ieee1394/csr.c
+++ b/drivers/ieee1394/csr.c
@@ -17,11 +17,13 @@
*
*/
-#include <linux/string.h>
+#include <linux/jiffies.h>
+#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/param.h>
#include <linux/spinlock.h>
+#include <linux/string.h>
#include "csr1212.h"
#include "ieee1394_types.h"
@@ -149,31 +151,18 @@ static void host_reset(struct hpsb_host *host)
/*
* HI == seconds (bits 0:2)
- * LO == fraction units of 1/8000 of a second, as per 1394 (bits 19:31)
- *
- * Convert to units and then to HZ, for comparison to jiffies.
- *
- * By default this will end up being 800 units, or 100ms (125usec per
- * unit).
+ * LO == fractions of a second in units of 125usec (bits 19:31)
*
- * NOTE: The spec says 1/8000, but also says we can compute based on 1/8192
- * like CSR specifies. Should make our math less complex.
+ * Convert SPLIT_TIMEOUT to jiffies.
+ * The default and minimum as per 1394a-2000 clause 8.3.2.2.6 is 100ms.
*/
static inline void calculate_expire(struct csr_control *csr)
{
- unsigned long units;
-
- /* Take the seconds, and convert to units */
- units = (unsigned long)(csr->split_timeout_hi & 0x07) << 13;
-
- /* Add in the fractional units */
- units += (unsigned long)(csr->split_timeout_lo >> 19);
-
- /* Convert to jiffies */
- csr->expire = (unsigned long)(units * HZ) >> 13UL;
+ unsigned long usecs =
+ (csr->split_timeout_hi & 0x07) * USEC_PER_SEC +
+ (csr->split_timeout_lo >> 19) * 125L;
- /* Just to keep from rounding low */
- csr->expire++;
+ csr->expire = usecs_to_jiffies(usecs > 100000L ? usecs : 100000L);
HPSB_VERBOSE("CSR: setting expire to %lu, HZ=%u", csr->expire, HZ);
}
diff --git a/drivers/ieee1394/csr.h b/drivers/ieee1394/csr.h
index ea9aa4f53ab6..f11546550d84 100644
--- a/drivers/ieee1394/csr.h
+++ b/drivers/ieee1394/csr.h
@@ -1,75 +1,73 @@
-
#ifndef _IEEE1394_CSR_H
#define _IEEE1394_CSR_H
-#ifdef CONFIG_PREEMPT
-#include <linux/sched.h>
-#endif
+#include <linux/spinlock_types.h>
#include "csr1212.h"
+#include "ieee1394_types.h"
-#define CSR_REGISTER_BASE 0xfffff0000000ULL
+#define CSR_REGISTER_BASE 0xfffff0000000ULL
/* register offsets relative to CSR_REGISTER_BASE */
-#define CSR_STATE_CLEAR 0x0
-#define CSR_STATE_SET 0x4
-#define CSR_NODE_IDS 0x8
-#define CSR_RESET_START 0xc
-#define CSR_SPLIT_TIMEOUT_HI 0x18
-#define CSR_SPLIT_TIMEOUT_LO 0x1c
-#define CSR_CYCLE_TIME 0x200
-#define CSR_BUS_TIME 0x204
-#define CSR_BUSY_TIMEOUT 0x210
-#define CSR_BUS_MANAGER_ID 0x21c
-#define CSR_BANDWIDTH_AVAILABLE 0x220
-#define CSR_CHANNELS_AVAILABLE 0x224
-#define CSR_CHANNELS_AVAILABLE_HI 0x224
-#define CSR_CHANNELS_AVAILABLE_LO 0x228
-#define CSR_BROADCAST_CHANNEL 0x234
-#define CSR_CONFIG_ROM 0x400
-#define CSR_CONFIG_ROM_END 0x800
-#define CSR_FCP_COMMAND 0xB00
-#define CSR_FCP_RESPONSE 0xD00
-#define CSR_FCP_END 0xF00
-#define CSR_TOPOLOGY_MAP 0x1000
-#define CSR_TOPOLOGY_MAP_END 0x1400
-#define CSR_SPEED_MAP 0x2000
-#define CSR_SPEED_MAP_END 0x3000
+#define CSR_STATE_CLEAR 0x0
+#define CSR_STATE_SET 0x4
+#define CSR_NODE_IDS 0x8
+#define CSR_RESET_START 0xc
+#define CSR_SPLIT_TIMEOUT_HI 0x18
+#define CSR_SPLIT_TIMEOUT_LO 0x1c
+#define CSR_CYCLE_TIME 0x200
+#define CSR_BUS_TIME 0x204
+#define CSR_BUSY_TIMEOUT 0x210
+#define CSR_BUS_MANAGER_ID 0x21c
+#define CSR_BANDWIDTH_AVAILABLE 0x220
+#define CSR_CHANNELS_AVAILABLE 0x224
+#define CSR_CHANNELS_AVAILABLE_HI 0x224
+#define CSR_CHANNELS_AVAILABLE_LO 0x228
+#define CSR_BROADCAST_CHANNEL 0x234
+#define CSR_CONFIG_ROM 0x400
+#define CSR_CONFIG_ROM_END 0x800
+#define CSR_FCP_COMMAND 0xB00
+#define CSR_FCP_RESPONSE 0xD00
+#define CSR_FCP_END 0xF00
+#define CSR_TOPOLOGY_MAP 0x1000
+#define CSR_TOPOLOGY_MAP_END 0x1400
+#define CSR_SPEED_MAP 0x2000
+#define CSR_SPEED_MAP_END 0x3000
/* IEEE 1394 bus specific Configuration ROM Key IDs */
#define IEEE1394_KV_ID_POWER_REQUIREMENTS (0x30)
-/* IEEE 1394 Bus Inforamation Block specifics */
+/* IEEE 1394 Bus Information Block specifics */
#define CSR_BUS_INFO_SIZE (5 * sizeof(quadlet_t))
-#define CSR_IRMC_SHIFT 31
-#define CSR_CMC_SHIFT 30
-#define CSR_ISC_SHIFT 29
-#define CSR_BMC_SHIFT 28
-#define CSR_PMC_SHIFT 27
-#define CSR_CYC_CLK_ACC_SHIFT 16
-#define CSR_MAX_REC_SHIFT 12
-#define CSR_MAX_ROM_SHIFT 8
-#define CSR_GENERATION_SHIFT 4
+#define CSR_IRMC_SHIFT 31
+#define CSR_CMC_SHIFT 30
+#define CSR_ISC_SHIFT 29
+#define CSR_BMC_SHIFT 28
+#define CSR_PMC_SHIFT 27
+#define CSR_CYC_CLK_ACC_SHIFT 16
+#define CSR_MAX_REC_SHIFT 12
+#define CSR_MAX_ROM_SHIFT 8
+#define CSR_GENERATION_SHIFT 4
#define CSR_SET_BUS_INFO_GENERATION(csr, gen) \
((csr)->bus_info_data[2] = \
cpu_to_be32((be32_to_cpu((csr)->bus_info_data[2]) & \
- ~(0xf << CSR_GENERATION_SHIFT)) | \
+ ~(0xf << CSR_GENERATION_SHIFT)) | \
(gen) << CSR_GENERATION_SHIFT))
struct csr_control {
- spinlock_t lock;
-
- quadlet_t state;
- quadlet_t node_ids;
- quadlet_t split_timeout_hi, split_timeout_lo;
- unsigned long expire; // Calculated from split_timeout
- quadlet_t cycle_time;
- quadlet_t bus_time;
- quadlet_t bus_manager_id;
- quadlet_t bandwidth_available;
- quadlet_t channels_available_hi, channels_available_lo;
+ spinlock_t lock;
+
+ quadlet_t state;
+ quadlet_t node_ids;
+ quadlet_t split_timeout_hi, split_timeout_lo;
+ unsigned long expire; /* Calculated from split_timeout */
+ quadlet_t cycle_time;
+ quadlet_t bus_time;
+ quadlet_t bus_manager_id;
+ quadlet_t bandwidth_available;
+ quadlet_t channels_available_hi, channels_available_lo;
quadlet_t broadcast_channel;
/* Bus Info */
@@ -84,8 +82,8 @@ struct csr_control {
struct csr1212_csr *rom;
- quadlet_t topology_map[256];
- quadlet_t speed_map[1024];
+ quadlet_t topology_map[256];
+ quadlet_t speed_map[1024];
};
extern struct csr1212_bus_ops csr_bus_ops;
@@ -93,4 +91,9 @@ extern struct csr1212_bus_ops csr_bus_ops;
int init_csr(void);
void cleanup_csr(void);
+/* hpsb_update_config_rom() is deprecated */
+struct hpsb_host;
+int hpsb_update_config_rom(struct hpsb_host *host, const quadlet_t *new_rom,
+ size_t size, unsigned char rom_version);
+
#endif /* _IEEE1394_CSR_H */
diff --git a/drivers/ieee1394/dma.c b/drivers/ieee1394/dma.c
index ca5167de707d..c68f328e1a29 100644
--- a/drivers/ieee1394/dma.c
+++ b/drivers/ieee1394/dma.c
@@ -7,10 +7,13 @@
* directory of the kernel sources for details.
*/
+#include <linux/mm.h>
#include <linux/module.h>
-#include <linux/vmalloc.h>
+#include <linux/pci.h>
#include <linux/slab.h>
-#include <linux/mm.h>
+#include <linux/vmalloc.h>
+#include <asm/scatterlist.h>
+
#include "dma.h"
/* dma_prog_region */
diff --git a/drivers/ieee1394/dma.h b/drivers/ieee1394/dma.h
index 061550a6fb99..a1682aba71c7 100644
--- a/drivers/ieee1394/dma.h
+++ b/drivers/ieee1394/dma.h
@@ -10,69 +10,91 @@
#ifndef IEEE1394_DMA_H
#define IEEE1394_DMA_H
-#include <linux/pci.h>
-#include <asm/scatterlist.h>
-
-/* struct dma_prog_region
-
- a small, physically-contiguous DMA buffer with random-access,
- synchronous usage characteristics
-*/
-
+#include <asm/types.h>
+
+struct pci_dev;
+struct scatterlist;
+struct vm_area_struct;
+
+/**
+ * struct dma_prog_region - small contiguous DMA buffer
+ * @kvirt: kernel virtual address
+ * @dev: PCI device
+ * @n_pages: number of kernel pages
+ * @bus_addr: base bus address
+ *
+ * a small, physically contiguous DMA buffer with random-access, synchronous
+ * usage characteristics
+ */
struct dma_prog_region {
- unsigned char *kvirt; /* kernel virtual address */
- struct pci_dev *dev; /* PCI device */
- unsigned int n_pages; /* # of kernel pages */
- dma_addr_t bus_addr; /* base bus address */
+ unsigned char *kvirt;
+ struct pci_dev *dev;
+ unsigned int n_pages;
+ dma_addr_t bus_addr;
};
/* clear out all fields but do not allocate any memory */
void dma_prog_region_init(struct dma_prog_region *prog);
-int dma_prog_region_alloc(struct dma_prog_region *prog, unsigned long n_bytes, struct pci_dev *dev);
+int dma_prog_region_alloc(struct dma_prog_region *prog, unsigned long n_bytes,
+ struct pci_dev *dev);
void dma_prog_region_free(struct dma_prog_region *prog);
-static inline dma_addr_t dma_prog_region_offset_to_bus(struct dma_prog_region *prog, unsigned long offset)
+static inline dma_addr_t dma_prog_region_offset_to_bus(
+ struct dma_prog_region *prog, unsigned long offset)
{
return prog->bus_addr + offset;
}
-/* struct dma_region
-
- a large, non-physically-contiguous DMA buffer with streaming,
- asynchronous usage characteristics
-*/
-
+/**
+ * struct dma_region - large non-contiguous DMA buffer
+ * @virt: kernel virtual address
+ * @dev: PCI device
+ * @n_pages: number of kernel pages
+ * @n_dma_pages: number of IOMMU pages
+ * @sglist: IOMMU mapping
+ * @direction: PCI_DMA_TODEVICE, etc.
+ *
+ * a large, non-physically-contiguous DMA buffer with streaming, asynchronous
+ * usage characteristics
+ */
struct dma_region {
- unsigned char *kvirt; /* kernel virtual address */
- struct pci_dev *dev; /* PCI device */
- unsigned int n_pages; /* # of kernel pages */
- unsigned int n_dma_pages; /* # of IOMMU pages */
- struct scatterlist *sglist; /* IOMMU mapping */
- int direction; /* PCI_DMA_TODEVICE, etc */
+ unsigned char *kvirt;
+ struct pci_dev *dev;
+ unsigned int n_pages;
+ unsigned int n_dma_pages;
+ struct scatterlist *sglist;
+ int direction;
};
/* clear out all fields but do not allocate anything */
void dma_region_init(struct dma_region *dma);
/* allocate the buffer and map it to the IOMMU */
-int dma_region_alloc(struct dma_region *dma, unsigned long n_bytes, struct pci_dev *dev, int direction);
+int dma_region_alloc(struct dma_region *dma, unsigned long n_bytes,
+ struct pci_dev *dev, int direction);
/* unmap and free the buffer */
void dma_region_free(struct dma_region *dma);
/* sync the CPU's view of the buffer */
-void dma_region_sync_for_cpu(struct dma_region *dma, unsigned long offset, unsigned long len);
+void dma_region_sync_for_cpu(struct dma_region *dma, unsigned long offset,
+ unsigned long len);
+
/* sync the IO bus' view of the buffer */
-void dma_region_sync_for_device(struct dma_region *dma, unsigned long offset, unsigned long len);
+void dma_region_sync_for_device(struct dma_region *dma, unsigned long offset,
+ unsigned long len);
/* map the buffer into a user space process */
-int dma_region_mmap(struct dma_region *dma, struct file *file, struct vm_area_struct *vma);
+int dma_region_mmap(struct dma_region *dma, struct file *file,
+ struct vm_area_struct *vma);
/* macro to index into a DMA region (or dma_prog_region) */
-#define dma_region_i(_dma, _type, _index) ( ((_type*) ((_dma)->kvirt)) + (_index) )
+#define dma_region_i(_dma, _type, _index) \
+ ( ((_type*) ((_dma)->kvirt)) + (_index) )
/* return the DMA bus address of the byte with the given offset
- relative to the beginning of the dma_region */
-dma_addr_t dma_region_offset_to_bus(struct dma_region *dma, unsigned long offset);
+ * relative to the beginning of the dma_region */
+dma_addr_t dma_region_offset_to_bus(struct dma_region *dma,
+ unsigned long offset);
#endif /* IEEE1394_DMA_H */
diff --git a/drivers/ieee1394/dv1394-private.h b/drivers/ieee1394/dv1394-private.h
index 80b5ac7fe383..7d1d2845b420 100644
--- a/drivers/ieee1394/dv1394-private.h
+++ b/drivers/ieee1394/dv1394-private.h
@@ -460,7 +460,7 @@ struct video_card {
int dma_running;
/*
- 3) the sleeping semaphore 'sem' - this is used from process context only,
+ 3) the sleeping mutex 'mtx' - this is used from process context only,
to serialize various operations on the video_card. Even though only one
open() is allowed, we still need to prevent multiple threads of execution
from entering calls like read, write, ioctl, etc.
@@ -468,9 +468,9 @@ struct video_card {
I honestly can't think of a good reason to use dv1394 from several threads
at once, but we need to serialize anyway to prevent oopses =).
- NOTE: if you need both spinlock and sem, take sem first to avoid deadlock!
+ NOTE: if you need both spinlock and mtx, take mtx first to avoid deadlock!
*/
- struct semaphore sem;
+ struct mutex mtx;
/* people waiting for buffer space, please form a line here... */
wait_queue_head_t waitq;
diff --git a/drivers/ieee1394/dv1394.c b/drivers/ieee1394/dv1394.c
index 87532dd43374..6c72f04b2b5d 100644
--- a/drivers/ieee1394/dv1394.c
+++ b/drivers/ieee1394/dv1394.c
@@ -95,6 +95,7 @@
#include <linux/fs.h>
#include <linux/poll.h>
#include <linux/smp_lock.h>
+#include <linux/mutex.h>
#include <linux/bitops.h>
#include <asm/byteorder.h>
#include <asm/atomic.h>
@@ -110,15 +111,15 @@
#include <linux/compat.h>
#include <linux/cdev.h>
+#include "dv1394.h"
+#include "dv1394-private.h"
+#include "highlevel.h"
+#include "hosts.h"
#include "ieee1394.h"
+#include "ieee1394_core.h"
+#include "ieee1394_hotplug.h"
#include "ieee1394_types.h"
#include "nodemgr.h"
-#include "hosts.h"
-#include "ieee1394_core.h"
-#include "highlevel.h"
-#include "dv1394.h"
-#include "dv1394-private.h"
-
#include "ohci1394.h"
/* DEBUG LEVELS:
@@ -136,13 +137,13 @@
#if DV1394_DEBUG_LEVEL >= 2
#define irq_printk( args... ) printk( args )
#else
-#define irq_printk( args... )
+#define irq_printk( args... ) do {} while (0)
#endif
#if DV1394_DEBUG_LEVEL >= 1
#define debug_printk( args... ) printk( args)
#else
-#define debug_printk( args... )
+#define debug_printk( args... ) do {} while (0)
#endif
/* issue a dummy PCI read to force the preceding write
@@ -247,7 +248,7 @@ static void frame_delete(struct frame *f)
Frame_prepare() must be called OUTSIDE the video->spinlock.
However, frame_prepare() must still be serialized, so
- it should be called WITH the video->sem taken.
+ it should be called WITH the video->mtx taken.
*/
static void frame_prepare(struct video_card *video, unsigned int this_frame)
@@ -1271,7 +1272,7 @@ static int dv1394_mmap(struct file *file, struct vm_area_struct *vma)
int retval = -EINVAL;
/* serialize mmap */
- down(&video->sem);
+ mutex_lock(&video->mtx);
if ( ! video_card_initialized(video) ) {
retval = do_dv1394_init_default(video);
@@ -1281,7 +1282,7 @@ static int dv1394_mmap(struct file *file, struct vm_area_struct *vma)
retval = dma_region_mmap(&video->dv_buf, file, vma);
out:
- up(&video->sem);
+ mutex_unlock(&video->mtx);
return retval;
}
@@ -1337,17 +1338,17 @@ static ssize_t dv1394_write(struct file *file, const char __user *buffer, size_t
/* serialize this to prevent multi-threaded mayhem */
if (file->f_flags & O_NONBLOCK) {
- if (down_trylock(&video->sem))
+ if (!mutex_trylock(&video->mtx))
return -EAGAIN;
} else {
- if (down_interruptible(&video->sem))
+ if (mutex_lock_interruptible(&video->mtx))
return -ERESTARTSYS;
}
if ( !video_card_initialized(video) ) {
ret = do_dv1394_init_default(video);
if (ret) {
- up(&video->sem);
+ mutex_unlock(&video->mtx);
return ret;
}
}
@@ -1418,7 +1419,7 @@ static ssize_t dv1394_write(struct file *file, const char __user *buffer, size_t
remove_wait_queue(&video->waitq, &wait);
set_current_state(TASK_RUNNING);
- up(&video->sem);
+ mutex_unlock(&video->mtx);
return ret;
}
@@ -1434,17 +1435,17 @@ static ssize_t dv1394_read(struct file *file, char __user *buffer, size_t count
/* serialize this to prevent multi-threaded mayhem */
if (file->f_flags & O_NONBLOCK) {
- if (down_trylock(&video->sem))
+ if (!mutex_trylock(&video->mtx))
return -EAGAIN;
} else {
- if (down_interruptible(&video->sem))
+ if (mutex_lock_interruptible(&video->mtx))
return -ERESTARTSYS;
}
if ( !video_card_initialized(video) ) {
ret = do_dv1394_init_default(video);
if (ret) {
- up(&video->sem);
+ mutex_unlock(&video->mtx);
return ret;
}
video->continuity_counter = -1;
@@ -1526,7 +1527,7 @@ static ssize_t dv1394_read(struct file *file, char __user *buffer, size_t count
remove_wait_queue(&video->waitq, &wait);
set_current_state(TASK_RUNNING);
- up(&video->sem);
+ mutex_unlock(&video->mtx);
return ret;
}
@@ -1547,12 +1548,12 @@ static long dv1394_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
/* serialize this to prevent multi-threaded mayhem */
if (file->f_flags & O_NONBLOCK) {
- if (down_trylock(&video->sem)) {
+ if (!mutex_trylock(&video->mtx)) {
unlock_kernel();
return -EAGAIN;
}
} else {
- if (down_interruptible(&video->sem)) {
+ if (mutex_lock_interruptible(&video->mtx)) {
unlock_kernel();
return -ERESTARTSYS;
}
@@ -1778,7 +1779,7 @@ static long dv1394_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
}
out:
- up(&video->sem);
+ mutex_unlock(&video->mtx);
unlock_kernel();
return ret;
}
@@ -2253,7 +2254,7 @@ static int dv1394_init(struct ti_ohci *ohci, enum pal_or_ntsc format, enum modes
clear_bit(0, &video->open);
spin_lock_init(&video->spinlock);
video->dma_running = 0;
- init_MUTEX(&video->sem);
+ mutex_init(&video->mtx);
init_waitqueue_head(&video->waitq);
video->fasync = NULL;
diff --git a/drivers/ieee1394/eth1394.c b/drivers/ieee1394/eth1394.c
index 2d5b57be98c3..8a7b8fab6238 100644
--- a/drivers/ieee1394/eth1394.c
+++ b/drivers/ieee1394/eth1394.c
@@ -64,19 +64,19 @@
#include <linux/ethtool.h>
#include <asm/uaccess.h>
#include <asm/delay.h>
-#include <asm/semaphore.h>
#include <net/arp.h>
+#include "config_roms.h"
#include "csr1212.h"
-#include "ieee1394_types.h"
+#include "eth1394.h"
+#include "highlevel.h"
+#include "ieee1394.h"
#include "ieee1394_core.h"
+#include "ieee1394_hotplug.h"
#include "ieee1394_transactions.h"
-#include "ieee1394.h"
-#include "highlevel.h"
+#include "ieee1394_types.h"
#include "iso.h"
#include "nodemgr.h"
-#include "eth1394.h"
-#include "config_roms.h"
#define ETH1394_PRINT_G(level, fmt, args...) \
printk(level "%s: " fmt, driver_name, ## args)
diff --git a/drivers/ieee1394/highlevel.h b/drivers/ieee1394/highlevel.h
index e119fb87e5b5..50f2dd2c7e20 100644
--- a/drivers/ieee1394/highlevel.h
+++ b/drivers/ieee1394/highlevel.h
@@ -1,60 +1,61 @@
-
#ifndef IEEE1394_HIGHLEVEL_H
#define IEEE1394_HIGHLEVEL_H
+#include <linux/list.h>
+#include <linux/spinlock_types.h>
+#include <linux/types.h>
-struct hpsb_address_serve {
- struct list_head host_list; /* per host list */
+struct module;
- struct list_head hl_list; /* hpsb_highlevel list */
+#include "ieee1394_types.h"
- struct hpsb_address_ops *op;
+struct hpsb_host;
+/* internal to ieee1394 core */
+struct hpsb_address_serve {
+ struct list_head host_list; /* per host list */
+ struct list_head hl_list; /* hpsb_highlevel list */
+ struct hpsb_address_ops *op;
struct hpsb_host *host;
-
- /* first address handled and first address behind, quadlet aligned */
- u64 start, end;
+ u64 start; /* first address handled, quadlet aligned */
+ u64 end; /* first address behind, quadlet aligned */
};
-
-/*
- * The above structs are internal to highlevel driver handling. Only the
- * following structures are of interest to actual highlevel drivers.
- */
+/* Only the following structures are of interest to actual highlevel drivers. */
struct hpsb_highlevel {
struct module *owner;
const char *name;
- /* Any of the following pointers can legally be NULL, except for
- * iso_receive which can only be NULL when you don't request
- * channels. */
+ /* Any of the following pointers can legally be NULL, except for
+ * iso_receive which can only be NULL when you don't request
+ * channels. */
- /* New host initialized. Will also be called during
- * hpsb_register_highlevel for all hosts already installed. */
- void (*add_host) (struct hpsb_host *host);
+ /* New host initialized. Will also be called during
+ * hpsb_register_highlevel for all hosts already installed. */
+ void (*add_host)(struct hpsb_host *host);
- /* Host about to be removed. Will also be called during
- * hpsb_unregister_highlevel once for each host. */
- void (*remove_host) (struct hpsb_host *host);
+ /* Host about to be removed. Will also be called during
+ * hpsb_unregister_highlevel once for each host. */
+ void (*remove_host)(struct hpsb_host *host);
- /* Host experienced bus reset with possible configuration changes.
+ /* Host experienced bus reset with possible configuration changes.
* Note that this one may occur during interrupt/bottom half handling.
* You can not expect to be able to do stock hpsb_reads. */
- void (*host_reset) (struct hpsb_host *host);
+ void (*host_reset)(struct hpsb_host *host);
- /* An isochronous packet was received. Channel contains the channel
- * number for your convenience, it is also contained in the included
- * packet header (first quadlet, CRCs are missing). You may get called
- * for channel/host combinations you did not request. */
- void (*iso_receive) (struct hpsb_host *host, int channel,
- quadlet_t *data, size_t length);
+ /* An isochronous packet was received. Channel contains the channel
+ * number for your convenience, it is also contained in the included
+ * packet header (first quadlet, CRCs are missing). You may get called
+ * for channel/host combinations you did not request. */
+ void (*iso_receive)(struct hpsb_host *host, int channel,
+ quadlet_t *data, size_t length);
- /* A write request was received on either the FCP_COMMAND (direction =
- * 0) or the FCP_RESPONSE (direction = 1) register. The cts arg
- * contains the cts field (first byte of data). */
- void (*fcp_request) (struct hpsb_host *host, int nodeid, int direction,
- int cts, u8 *data, size_t length);
+ /* A write request was received on either the FCP_COMMAND (direction =
+ * 0) or the FCP_RESPONSE (direction = 1) register. The cts arg
+ * contains the cts field (first byte of data). */
+ void (*fcp_request)(struct hpsb_host *host, int nodeid, int direction,
+ int cts, u8 *data, size_t length);
/* These are initialized by the subsystem when the
* hpsb_higlevel is registered. */
@@ -67,61 +68,62 @@ struct hpsb_highlevel {
};
struct hpsb_address_ops {
- /*
- * Null function pointers will make the respective operation complete
- * with RCODE_TYPE_ERROR. Makes for easy to implement read-only
- * registers (just leave everything but read NULL).
- *
- * All functions shall return appropriate IEEE 1394 rcodes.
- */
-
- /* These functions have to implement block reads for themselves. */
- /* These functions either return a response code
- or a negative number. In the first case a response will be generated; in the
- later case, no response will be sent and the driver, that handled the request
- will send the response itself
- */
- int (*read) (struct hpsb_host *host, int nodeid, quadlet_t *buffer,
- u64 addr, size_t length, u16 flags);
- int (*write) (struct hpsb_host *host, int nodeid, int destid,
- quadlet_t *data, u64 addr, size_t length, u16 flags);
-
- /* Lock transactions: write results of ext_tcode operation into
- * *store. */
- int (*lock) (struct hpsb_host *host, int nodeid, quadlet_t *store,
- u64 addr, quadlet_t data, quadlet_t arg, int ext_tcode, u16 flags);
- int (*lock64) (struct hpsb_host *host, int nodeid, octlet_t *store,
- u64 addr, octlet_t data, octlet_t arg, int ext_tcode, u16 flags);
+ /*
+ * Null function pointers will make the respective operation complete
+ * with RCODE_TYPE_ERROR. Makes for easy to implement read-only
+ * registers (just leave everything but read NULL).
+ *
+ * All functions shall return appropriate IEEE 1394 rcodes.
+ */
+
+ /* These functions have to implement block reads for themselves.
+ *
+ * These functions either return a response code or a negative number.
+ * In the first case a response will be generated. In the latter case,
+ * no response will be sent and the driver which handled the request
+ * will send the response itself. */
+ int (*read)(struct hpsb_host *host, int nodeid, quadlet_t *buffer,
+ u64 addr, size_t length, u16 flags);
+ int (*write)(struct hpsb_host *host, int nodeid, int destid,
+ quadlet_t *data, u64 addr, size_t length, u16 flags);
+
+ /* Lock transactions: write results of ext_tcode operation into
+ * *store. */
+ int (*lock)(struct hpsb_host *host, int nodeid, quadlet_t *store,
+ u64 addr, quadlet_t data, quadlet_t arg, int ext_tcode,
+ u16 flags);
+ int (*lock64)(struct hpsb_host *host, int nodeid, octlet_t *store,
+ u64 addr, octlet_t data, octlet_t arg, int ext_tcode,
+ u16 flags);
};
-
void highlevel_add_host(struct hpsb_host *host);
void highlevel_remove_host(struct hpsb_host *host);
void highlevel_host_reset(struct hpsb_host *host);
-
-/* these functions are called to handle transactions. They are called, when
- a packet arrives. The flags argument contains the second word of the first header
- quadlet of the incoming packet (containing transaction label, retry code,
- transaction code and priority). These functions either return a response code
- or a negative number. In the first case a response will be generated; in the
- later case, no response will be sent and the driver, that handled the request
- will send the response itself.
-*/
-int highlevel_read(struct hpsb_host *host, int nodeid, void *data,
- u64 addr, unsigned int length, u16 flags);
-int highlevel_write(struct hpsb_host *host, int nodeid, int destid,
- void *data, u64 addr, unsigned int length, u16 flags);
+/*
+ * These functions are called to handle transactions. They are called when a
+ * packet arrives. The flags argument contains the second word of the first
+ * header quadlet of the incoming packet (containing transaction label, retry
+ * code, transaction code and priority). These functions either return a
+ * response code or a negative number. In the first case a response will be
+ * generated. In the latter case, no response will be sent and the driver which
+ * handled the request will send the response itself.
+ */
+int highlevel_read(struct hpsb_host *host, int nodeid, void *data, u64 addr,
+ unsigned int length, u16 flags);
+int highlevel_write(struct hpsb_host *host, int nodeid, int destid, void *data,
+ u64 addr, unsigned int length, u16 flags);
int highlevel_lock(struct hpsb_host *host, int nodeid, quadlet_t *store,
- u64 addr, quadlet_t data, quadlet_t arg, int ext_tcode, u16 flags);
+ u64 addr, quadlet_t data, quadlet_t arg, int ext_tcode,
+ u16 flags);
int highlevel_lock64(struct hpsb_host *host, int nodeid, octlet_t *store,
- u64 addr, octlet_t data, octlet_t arg, int ext_tcode, u16 flags);
+ u64 addr, octlet_t data, octlet_t arg, int ext_tcode,
+ u16 flags);
-void highlevel_iso_receive(struct hpsb_host *host, void *data,
- size_t length);
+void highlevel_iso_receive(struct hpsb_host *host, void *data, size_t length);
void highlevel_fcp_request(struct hpsb_host *host, int nodeid, int direction,
- void *data, size_t length);
-
+ void *data, size_t length);
/*
* Register highlevel driver. The name pointer has to stay valid at all times
@@ -132,13 +134,15 @@ void hpsb_unregister_highlevel(struct hpsb_highlevel *hl);
/*
* Register handlers for host address spaces. Start and end are 48 bit pointers
- * and have to be quadlet aligned (end points to the first address behind the
- * handled addresses. This function can be called multiple times for a single
- * hpsb_highlevel to implement sparse register sets. The requested region must
- * not overlap any previously allocated region, otherwise registering will fail.
+ * and have to be quadlet aligned. Argument "end" points to the first address
+ * behind the handled addresses. This function can be called multiple times for
+ * a single hpsb_highlevel to implement sparse register sets. The requested
+ * region must not overlap any previously allocated region, otherwise
+ * registering will fail.
*
- * It returns true for successful allocation. There is no unregister function,
- * all address spaces are deallocated together with the hpsb_highlevel.
+ * It returns true for successful allocation. Address spaces can be
+ * unregistered with hpsb_unregister_addrspace. All remaining address spaces
+ * are automatically deallocated together with the hpsb_highlevel.
*/
u64 hpsb_allocate_and_register_addrspace(struct hpsb_highlevel *hl,
struct hpsb_host *host,
@@ -146,20 +150,18 @@ u64 hpsb_allocate_and_register_addrspace(struct hpsb_highlevel *hl,
u64 size, u64 alignment,
u64 start, u64 end);
int hpsb_register_addrspace(struct hpsb_highlevel *hl, struct hpsb_host *host,
- struct hpsb_address_ops *ops, u64 start, u64 end);
-
+ struct hpsb_address_ops *ops, u64 start, u64 end);
int hpsb_unregister_addrspace(struct hpsb_highlevel *hl, struct hpsb_host *host,
- u64 start);
+ u64 start);
/*
* Enable or disable receving a certain isochronous channel through the
* iso_receive op.
*/
int hpsb_listen_channel(struct hpsb_highlevel *hl, struct hpsb_host *host,
- unsigned int channel);
+ unsigned int channel);
void hpsb_unlisten_channel(struct hpsb_highlevel *hl, struct hpsb_host *host,
- unsigned int channel);
-
+ unsigned int channel);
/* Retrieve a hostinfo pointer bound to this driver/host */
void *hpsb_get_hostinfo(struct hpsb_highlevel *hl, struct hpsb_host *host);
@@ -172,19 +174,24 @@ void *hpsb_create_hostinfo(struct hpsb_highlevel *hl, struct hpsb_host *host,
void hpsb_destroy_hostinfo(struct hpsb_highlevel *hl, struct hpsb_host *host);
/* Set an alternate lookup key for the hostinfo bound to this driver/host */
-void hpsb_set_hostinfo_key(struct hpsb_highlevel *hl, struct hpsb_host *host, unsigned long key);
+void hpsb_set_hostinfo_key(struct hpsb_highlevel *hl, struct hpsb_host *host,
+ unsigned long key);
-/* Retrieve the alternate lookup key for the hostinfo bound to this driver/host */
-unsigned long hpsb_get_hostinfo_key(struct hpsb_highlevel *hl, struct hpsb_host *host);
+/* Retrieve the alternate lookup key for the hostinfo bound to this
+ * driver/host */
+unsigned long hpsb_get_hostinfo_key(struct hpsb_highlevel *hl,
+ struct hpsb_host *host);
/* Retrieve a hostinfo pointer bound to this driver using its alternate key */
void *hpsb_get_hostinfo_bykey(struct hpsb_highlevel *hl, unsigned long key);
/* Set the hostinfo pointer to something useful. Usually follows a call to
* hpsb_create_hostinfo, where the size is 0. */
-int hpsb_set_hostinfo(struct hpsb_highlevel *hl, struct hpsb_host *host, void *data);
+int hpsb_set_hostinfo(struct hpsb_highlevel *hl, struct hpsb_host *host,
+ void *data);
/* Retrieve hpsb_host using a highlevel handle and a key */
-struct hpsb_host *hpsb_get_host_bykey(struct hpsb_highlevel *hl, unsigned long key);
+struct hpsb_host *hpsb_get_host_bykey(struct hpsb_highlevel *hl,
+ unsigned long key);
#endif /* IEEE1394_HIGHLEVEL_H */
diff --git a/drivers/ieee1394/hosts.c b/drivers/ieee1394/hosts.c
index 4feead4a35c5..d90a3a1898c0 100644
--- a/drivers/ieee1394/hosts.c
+++ b/drivers/ieee1394/hosts.c
@@ -90,6 +90,16 @@ static int alloc_hostnum_cb(struct hpsb_host *host, void *__data)
return 0;
}
+/*
+ * The pending_packet_queue is special in that it's processed
+ * from hardirq context too (such as hpsb_bus_reset()). Hence
+ * split the lock class from the usual networking skb-head
+ * lock class by using a separate key for it:
+ */
+static struct lock_class_key pending_packet_queue_key;
+
+static DEFINE_MUTEX(host_num_alloc);
+
/**
* hpsb_alloc_host - allocate a new host controller.
* @drv: the driver that will manage the host controller
@@ -105,16 +115,6 @@ static int alloc_hostnum_cb(struct hpsb_host *host, void *__data)
* Return Value: a pointer to the &hpsb_host if successful, %NULL if
* no memory was available.
*/
-static DEFINE_MUTEX(host_num_alloc);
-
-/*
- * The pending_packet_queue is special in that it's processed
- * from hardirq context too (such as hpsb_bus_reset()). Hence
- * split the lock class from the usual networking skb-head
- * lock class by using a separate key for it:
- */
-static struct lock_class_key pending_packet_queue_key;
-
struct hpsb_host *hpsb_alloc_host(struct hpsb_host_driver *drv, size_t extra,
struct device *dev)
{
@@ -143,9 +143,6 @@ struct hpsb_host *hpsb_alloc_host(struct hpsb_host_driver *drv, size_t extra,
for (i = 2; i < 16; i++)
h->csr.gen_timestamp[i] = jiffies - 60 * HZ;
- for (i = 0; i < ARRAY_SIZE(h->tpool); i++)
- HPSB_TPOOL_INIT(&h->tpool[i]);
-
atomic_set(&h->generation, 0);
INIT_WORK(&h->delayed_reset, delayed_reset_bus, h);
diff --git a/drivers/ieee1394/hosts.h b/drivers/ieee1394/hosts.h
index 9ad4b2463077..bc6dbfadb891 100644
--- a/drivers/ieee1394/hosts.h
+++ b/drivers/ieee1394/hosts.h
@@ -2,17 +2,19 @@
#define _IEEE1394_HOSTS_H
#include <linux/device.h>
-#include <linux/wait.h>
#include <linux/list.h>
-#include <linux/timer.h>
#include <linux/skbuff.h>
+#include <linux/timer.h>
+#include <linux/types.h>
+#include <linux/workqueue.h>
+#include <asm/atomic.h>
-#include <asm/semaphore.h>
+struct pci_dev;
+struct module;
#include "ieee1394_types.h"
#include "csr.h"
-
struct hpsb_packet;
struct hpsb_iso;
@@ -33,7 +35,6 @@ struct hpsb_host {
int node_count; /* number of identified nodes on this bus */
int selfid_count; /* total number of SelfIDs received */
int nodes_active; /* number of nodes with active link layer */
- u8 speed[ALL_NODES]; /* speed between each node and local node */
nodeid_t node_id; /* node ID of this host */
nodeid_t irm_id; /* ID of this bus' isochronous resource manager */
@@ -53,31 +54,29 @@ struct hpsb_host {
int reset_retries;
quadlet_t *topology_map;
u8 *speed_map;
- struct csr_control csr;
-
- /* Per node tlabel pool allocation */
- struct hpsb_tlabel_pool tpool[ALL_NODES];
+ int id;
struct hpsb_host_driver *driver;
-
struct pci_dev *pdev;
-
- int id;
-
struct device device;
struct class_device class_dev;
int update_config_rom;
struct work_struct delayed_reset;
-
unsigned int config_roms;
struct list_head addr_space;
u64 low_addr_space; /* upper bound of physical DMA area */
u64 middle_addr_space; /* upper bound of posted write area */
-};
+ u8 speed[ALL_NODES]; /* speed between each node and local node */
+
+ /* per node tlabel allocation */
+ u8 next_tl[ALL_NODES];
+ struct { DECLARE_BITMAP(map, 64); } tl_pool[ALL_NODES];
+ struct csr_control csr;
+};
enum devctl_cmd {
/* Host is requested to reset its bus and cancel all outstanding async
@@ -112,7 +111,7 @@ enum devctl_cmd {
enum isoctl_cmd {
/* rawiso API - see iso.h for the meanings of these commands
- (they correspond exactly to the hpsb_iso_* API functions)
+ * (they correspond exactly to the hpsb_iso_* API functions)
* INIT = allocate resources
* START = begin transmission/reception
* STOP = halt transmission/reception
@@ -160,7 +159,8 @@ struct hpsb_host_driver {
/* The hardware driver may optionally support a function that is used
* to set the hardware ConfigROM if the hardware supports handling
* reads to the ConfigROM on its own. */
- void (*set_hw_config_rom) (struct hpsb_host *host, quadlet_t *config_rom);
+ void (*set_hw_config_rom)(struct hpsb_host *host,
+ quadlet_t *config_rom);
/* This function shall implement packet transmission based on
* packet->type. It shall CRC both parts of the packet (unless
@@ -170,20 +170,21 @@ struct hpsb_host_driver {
* called. Return 0 on success, negative errno on failure.
* NOTE: The function must be callable in interrupt context.
*/
- int (*transmit_packet) (struct hpsb_host *host,
- struct hpsb_packet *packet);
+ int (*transmit_packet)(struct hpsb_host *host,
+ struct hpsb_packet *packet);
/* This function requests miscellanous services from the driver, see
* above for command codes and expected actions. Return -1 for unknown
* command, though that should never happen.
*/
- int (*devctl) (struct hpsb_host *host, enum devctl_cmd command, int arg);
+ int (*devctl)(struct hpsb_host *host, enum devctl_cmd command, int arg);
/* ISO transmission/reception functions. Return 0 on success, -1
* (or -EXXX errno code) on failure. If the low-level driver does not
* support the new ISO API, set isoctl to NULL.
*/
- int (*isoctl) (struct hpsb_iso *iso, enum isoctl_cmd command, unsigned long arg);
+ int (*isoctl)(struct hpsb_iso *iso, enum isoctl_cmd command,
+ unsigned long arg);
/* This function is mainly to redirect local CSR reads/locks to the iso
* management registers (bus manager id, bandwidth available, channels
@@ -196,19 +197,11 @@ struct hpsb_host_driver {
quadlet_t data, quadlet_t compare);
};
-
struct hpsb_host *hpsb_alloc_host(struct hpsb_host_driver *drv, size_t extra,
struct device *dev);
int hpsb_add_host(struct hpsb_host *host);
void hpsb_remove_host(struct hpsb_host *h);
-/* The following 2 functions are deprecated and will be removed when the
- * raw1394/libraw1394 update is complete. */
-int hpsb_update_config_rom(struct hpsb_host *host,
- const quadlet_t *new_rom, size_t size, unsigned char rom_version);
-int hpsb_get_config_rom(struct hpsb_host *host, quadlet_t *buffer,
- size_t buffersize, size_t *rom_size, unsigned char *rom_version);
-
/* Updates the configuration rom image of a host. rom_version must be the
* current version, otherwise it will fail with return value -1. If this
* host does not support config-rom-update, it will return -EINVAL.
diff --git a/drivers/ieee1394/ieee1394-ioctl.h b/drivers/ieee1394/ieee1394-ioctl.h
index 156703986348..8f207508ed1d 100644
--- a/drivers/ieee1394/ieee1394-ioctl.h
+++ b/drivers/ieee1394/ieee1394-ioctl.h
@@ -1,5 +1,7 @@
-/* Base file for all ieee1394 ioctl's. Linux-1394 has allocated base '#'
- * with a range of 0x00-0x3f. */
+/*
+ * Base file for all ieee1394 ioctl's.
+ * Linux-1394 has allocated base '#' with a range of 0x00-0x3f.
+ */
#ifndef __IEEE1394_IOCTL_H
#define __IEEE1394_IOCTL_H
@@ -96,8 +98,7 @@
_IOW ('#', 0x27, struct raw1394_iso_packets)
#define RAW1394_IOC_ISO_XMIT_SYNC \
_IO ('#', 0x28)
-#define RAW1394_IOC_ISO_RECV_FLUSH \
+#define RAW1394_IOC_ISO_RECV_FLUSH \
_IO ('#', 0x29)
-
#endif /* __IEEE1394_IOCTL_H */
diff --git a/drivers/ieee1394/ieee1394.h b/drivers/ieee1394/ieee1394.h
index 936d776de00a..40492074c013 100644
--- a/drivers/ieee1394/ieee1394.h
+++ b/drivers/ieee1394/ieee1394.h
@@ -5,77 +5,78 @@
#ifndef _IEEE1394_IEEE1394_H
#define _IEEE1394_IEEE1394_H
-#define TCODE_WRITEQ 0x0
-#define TCODE_WRITEB 0x1
-#define TCODE_WRITE_RESPONSE 0x2
-#define TCODE_READQ 0x4
-#define TCODE_READB 0x5
-#define TCODE_READQ_RESPONSE 0x6
-#define TCODE_READB_RESPONSE 0x7
-#define TCODE_CYCLE_START 0x8
-#define TCODE_LOCK_REQUEST 0x9
-#define TCODE_ISO_DATA 0xa
-#define TCODE_STREAM_DATA 0xa
-#define TCODE_LOCK_RESPONSE 0xb
-
-#define RCODE_COMPLETE 0x0
-#define RCODE_CONFLICT_ERROR 0x4
-#define RCODE_DATA_ERROR 0x5
-#define RCODE_TYPE_ERROR 0x6
-#define RCODE_ADDRESS_ERROR 0x7
-
-#define EXTCODE_MASK_SWAP 0x1
-#define EXTCODE_COMPARE_SWAP 0x2
-#define EXTCODE_FETCH_ADD 0x3
-#define EXTCODE_LITTLE_ADD 0x4
-#define EXTCODE_BOUNDED_ADD 0x5
-#define EXTCODE_WRAP_ADD 0x6
-
-#define ACK_COMPLETE 0x1
-#define ACK_PENDING 0x2
-#define ACK_BUSY_X 0x4
-#define ACK_BUSY_A 0x5
-#define ACK_BUSY_B 0x6
-#define ACK_TARDY 0xb
-#define ACK_CONFLICT_ERROR 0xc
-#define ACK_DATA_ERROR 0xd
-#define ACK_TYPE_ERROR 0xe
-#define ACK_ADDRESS_ERROR 0xf
+#define TCODE_WRITEQ 0x0
+#define TCODE_WRITEB 0x1
+#define TCODE_WRITE_RESPONSE 0x2
+#define TCODE_READQ 0x4
+#define TCODE_READB 0x5
+#define TCODE_READQ_RESPONSE 0x6
+#define TCODE_READB_RESPONSE 0x7
+#define TCODE_CYCLE_START 0x8
+#define TCODE_LOCK_REQUEST 0x9
+#define TCODE_ISO_DATA 0xa
+#define TCODE_STREAM_DATA 0xa
+#define TCODE_LOCK_RESPONSE 0xb
+
+#define RCODE_COMPLETE 0x0
+#define RCODE_CONFLICT_ERROR 0x4
+#define RCODE_DATA_ERROR 0x5
+#define RCODE_TYPE_ERROR 0x6
+#define RCODE_ADDRESS_ERROR 0x7
+
+#define EXTCODE_MASK_SWAP 0x1
+#define EXTCODE_COMPARE_SWAP 0x2
+#define EXTCODE_FETCH_ADD 0x3
+#define EXTCODE_LITTLE_ADD 0x4
+#define EXTCODE_BOUNDED_ADD 0x5
+#define EXTCODE_WRAP_ADD 0x6
+
+#define ACK_COMPLETE 0x1
+#define ACK_PENDING 0x2
+#define ACK_BUSY_X 0x4
+#define ACK_BUSY_A 0x5
+#define ACK_BUSY_B 0x6
+#define ACK_TARDY 0xb
+#define ACK_CONFLICT_ERROR 0xc
+#define ACK_DATA_ERROR 0xd
+#define ACK_TYPE_ERROR 0xe
+#define ACK_ADDRESS_ERROR 0xf
/* Non-standard "ACK codes" for internal use */
-#define ACKX_NONE (-1)
-#define ACKX_SEND_ERROR (-2)
-#define ACKX_ABORTED (-3)
-#define ACKX_TIMEOUT (-4)
-
-
-#define IEEE1394_SPEED_100 0x00
-#define IEEE1394_SPEED_200 0x01
-#define IEEE1394_SPEED_400 0x02
-#define IEEE1394_SPEED_800 0x03
-#define IEEE1394_SPEED_1600 0x04
-#define IEEE1394_SPEED_3200 0x05
+#define ACKX_NONE (-1)
+#define ACKX_SEND_ERROR (-2)
+#define ACKX_ABORTED (-3)
+#define ACKX_TIMEOUT (-4)
+
+#define IEEE1394_SPEED_100 0x00
+#define IEEE1394_SPEED_200 0x01
+#define IEEE1394_SPEED_400 0x02
+#define IEEE1394_SPEED_800 0x03
+#define IEEE1394_SPEED_1600 0x04
+#define IEEE1394_SPEED_3200 0x05
+
/* The current highest tested speed supported by the subsystem */
-#define IEEE1394_SPEED_MAX IEEE1394_SPEED_800
+#define IEEE1394_SPEED_MAX IEEE1394_SPEED_800
/* Maps speed values above to a string representation */
extern const char *hpsb_speedto_str[];
-
/* 1394a cable PHY packets */
-#define SELFID_PWRCL_NO_POWER 0x0
-#define SELFID_PWRCL_PROVIDE_15W 0x1
-#define SELFID_PWRCL_PROVIDE_30W 0x2
-#define SELFID_PWRCL_PROVIDE_45W 0x3
-#define SELFID_PWRCL_USE_1W 0x4
-#define SELFID_PWRCL_USE_3W 0x5
-#define SELFID_PWRCL_USE_6W 0x6
-#define SELFID_PWRCL_USE_10W 0x7
-
-#define SELFID_PORT_CHILD 0x3
-#define SELFID_PORT_PARENT 0x2
-#define SELFID_PORT_NCONN 0x1
-#define SELFID_PORT_NONE 0x0
+#define SELFID_PWRCL_NO_POWER 0x0
+#define SELFID_PWRCL_PROVIDE_15W 0x1
+#define SELFID_PWRCL_PROVIDE_30W 0x2
+#define SELFID_PWRCL_PROVIDE_45W 0x3
+#define SELFID_PWRCL_USE_1W 0x4
+#define SELFID_PWRCL_USE_3W 0x5
+#define SELFID_PWRCL_USE_6W 0x6
+#define SELFID_PWRCL_USE_10W 0x7
+
+#define SELFID_PORT_CHILD 0x3
+#define SELFID_PORT_PARENT 0x2
+#define SELFID_PORT_NCONN 0x1
+#define SELFID_PORT_NONE 0x0
+
+#define SELFID_SPEED_UNKNOWN 0x3 /* 1394b PHY */
#define PHYPACKET_LINKON 0x40000000
#define PHYPACKET_PHYCONFIG_R 0x00800000
@@ -91,76 +92,76 @@ extern const char *hpsb_speedto_str[];
#define EXTPHYPACKET_TYPEMASK 0xC0FC0000
-#define PHYPACKET_PORT_SHIFT 24
-#define PHYPACKET_GAPCOUNT_SHIFT 16
+#define PHYPACKET_PORT_SHIFT 24
+#define PHYPACKET_GAPCOUNT_SHIFT 16
/* 1394a PHY register map bitmasks */
-#define PHY_00_PHYSICAL_ID 0xFC
-#define PHY_00_R 0x02 /* Root */
-#define PHY_00_PS 0x01 /* Power Status*/
-#define PHY_01_RHB 0x80 /* Root Hold-Off */
-#define PHY_01_IBR 0x80 /* Initiate Bus Reset */
-#define PHY_01_GAP_COUNT 0x3F
-#define PHY_02_EXTENDED 0xE0 /* 0x7 for 1394a-compliant PHY */
-#define PHY_02_TOTAL_PORTS 0x1F
-#define PHY_03_MAX_SPEED 0xE0
-#define PHY_03_DELAY 0x0F
-#define PHY_04_LCTRL 0x80 /* Link Active Report Control */
-#define PHY_04_CONTENDER 0x40
-#define PHY_04_JITTER 0x38
-#define PHY_04_PWR_CLASS 0x07 /* Power Class */
-#define PHY_05_WATCHDOG 0x80
-#define PHY_05_ISBR 0x40 /* Initiate Short Bus Reset */
-#define PHY_05_LOOP 0x20 /* Loop Detect */
-#define PHY_05_PWR_FAIL 0x10 /* Cable Power Failure Detect */
-#define PHY_05_TIMEOUT 0x08 /* Arbitration State Machine Timeout */
-#define PHY_05_PORT_EVENT 0x04 /* Port Event Detect */
-#define PHY_05_ENAB_ACCEL 0x02 /* Enable Arbitration Acceleration */
-#define PHY_05_ENAB_MULTI 0x01 /* Ena. Multispeed Packet Concatenation */
+#define PHY_00_PHYSICAL_ID 0xFC
+#define PHY_00_R 0x02 /* Root */
+#define PHY_00_PS 0x01 /* Power Status*/
+#define PHY_01_RHB 0x80 /* Root Hold-Off */
+#define PHY_01_IBR 0x80 /* Initiate Bus Reset */
+#define PHY_01_GAP_COUNT 0x3F
+#define PHY_02_EXTENDED 0xE0 /* 0x7 for 1394a-compliant PHY */
+#define PHY_02_TOTAL_PORTS 0x1F
+#define PHY_03_MAX_SPEED 0xE0
+#define PHY_03_DELAY 0x0F
+#define PHY_04_LCTRL 0x80 /* Link Active Report Control */
+#define PHY_04_CONTENDER 0x40
+#define PHY_04_JITTER 0x38
+#define PHY_04_PWR_CLASS 0x07 /* Power Class */
+#define PHY_05_WATCHDOG 0x80
+#define PHY_05_ISBR 0x40 /* Initiate Short Bus Reset */
+#define PHY_05_LOOP 0x20 /* Loop Detect */
+#define PHY_05_PWR_FAIL 0x10 /* Cable Power Failure Detect */
+#define PHY_05_TIMEOUT 0x08 /* Arbitration State Machine Timeout */
+#define PHY_05_PORT_EVENT 0x04 /* Port Event Detect */
+#define PHY_05_ENAB_ACCEL 0x02 /* Enable Arbitration Acceleration */
+#define PHY_05_ENAB_MULTI 0x01 /* Ena. Multispeed Packet Concatenation */
#include <asm/byteorder.h>
#ifdef __BIG_ENDIAN_BITFIELD
struct selfid {
- u32 packet_identifier:2; /* always binary 10 */
- u32 phy_id:6;
- /* byte */
- u32 extended:1; /* if true is struct ext_selfid */
- u32 link_active:1;
- u32 gap_count:6;
- /* byte */
- u32 speed:2;
- u32 phy_delay:2;
- u32 contender:1;
- u32 power_class:3;
- /* byte */
- u32 port0:2;
- u32 port1:2;
- u32 port2:2;
- u32 initiated_reset:1;
- u32 more_packets:1;
+ u32 packet_identifier:2; /* always binary 10 */
+ u32 phy_id:6;
+ /* byte */
+ u32 extended:1; /* if true is struct ext_selfid */
+ u32 link_active:1;
+ u32 gap_count:6;
+ /* byte */
+ u32 speed:2;
+ u32 phy_delay:2;
+ u32 contender:1;
+ u32 power_class:3;
+ /* byte */
+ u32 port0:2;
+ u32 port1:2;
+ u32 port2:2;
+ u32 initiated_reset:1;
+ u32 more_packets:1;
} __attribute__((packed));
struct ext_selfid {
- u32 packet_identifier:2; /* always binary 10 */
- u32 phy_id:6;
- /* byte */
- u32 extended:1; /* if false is struct selfid */
- u32 seq_nr:3;
- u32 reserved:2;
- u32 porta:2;
- /* byte */
- u32 portb:2;
- u32 portc:2;
- u32 portd:2;
- u32 porte:2;
- /* byte */
- u32 portf:2;
- u32 portg:2;
- u32 porth:2;
- u32 reserved2:1;
- u32 more_packets:1;
+ u32 packet_identifier:2; /* always binary 10 */
+ u32 phy_id:6;
+ /* byte */
+ u32 extended:1; /* if false is struct selfid */
+ u32 seq_nr:3;
+ u32 reserved:2;
+ u32 porta:2;
+ /* byte */
+ u32 portb:2;
+ u32 portc:2;
+ u32 portd:2;
+ u32 porte:2;
+ /* byte */
+ u32 portf:2;
+ u32 portg:2;
+ u32 porth:2;
+ u32 reserved2:1;
+ u32 more_packets:1;
} __attribute__((packed));
#elif defined __LITTLE_ENDIAN_BITFIELD /* __BIG_ENDIAN_BITFIELD */
@@ -171,49 +172,48 @@ struct ext_selfid {
*/
struct selfid {
- u32 phy_id:6;
- u32 packet_identifier:2; /* always binary 10 */
- /* byte */
- u32 gap_count:6;
- u32 link_active:1;
- u32 extended:1; /* if true is struct ext_selfid */
- /* byte */
- u32 power_class:3;
- u32 contender:1;
- u32 phy_delay:2;
- u32 speed:2;
- /* byte */
- u32 more_packets:1;
- u32 initiated_reset:1;
- u32 port2:2;
- u32 port1:2;
- u32 port0:2;
+ u32 phy_id:6;
+ u32 packet_identifier:2; /* always binary 10 */
+ /* byte */
+ u32 gap_count:6;
+ u32 link_active:1;
+ u32 extended:1; /* if true is struct ext_selfid */
+ /* byte */
+ u32 power_class:3;
+ u32 contender:1;
+ u32 phy_delay:2;
+ u32 speed:2;
+ /* byte */
+ u32 more_packets:1;
+ u32 initiated_reset:1;
+ u32 port2:2;
+ u32 port1:2;
+ u32 port0:2;
} __attribute__((packed));
struct ext_selfid {
- u32 phy_id:6;
- u32 packet_identifier:2; /* always binary 10 */
- /* byte */
- u32 porta:2;
- u32 reserved:2;
- u32 seq_nr:3;
- u32 extended:1; /* if false is struct selfid */
- /* byte */
- u32 porte:2;
- u32 portd:2;
- u32 portc:2;
- u32 portb:2;
- /* byte */
- u32 more_packets:1;
- u32 reserved2:1;
- u32 porth:2;
- u32 portg:2;
- u32 portf:2;
+ u32 phy_id:6;
+ u32 packet_identifier:2; /* always binary 10 */
+ /* byte */
+ u32 porta:2;
+ u32 reserved:2;
+ u32 seq_nr:3;
+ u32 extended:1; /* if false is struct selfid */
+ /* byte */
+ u32 porte:2;
+ u32 portd:2;
+ u32 portc:2;
+ u32 portb:2;
+ /* byte */
+ u32 more_packets:1;
+ u32 reserved2:1;
+ u32 porth:2;
+ u32 portg:2;
+ u32 portf:2;
} __attribute__((packed));
#else
#error What? PDP endian?
#endif /* __BIG_ENDIAN_BITFIELD */
-
#endif /* _IEEE1394_IEEE1394_H */
diff --git a/drivers/ieee1394/ieee1394_core.c b/drivers/ieee1394/ieee1394_core.c
index f43739c5cab2..5fccf9f7a1d2 100644
--- a/drivers/ieee1394/ieee1394_core.c
+++ b/drivers/ieee1394/ieee1394_core.c
@@ -35,7 +35,6 @@
#include <linux/kthread.h>
#include <asm/byteorder.h>
-#include <asm/semaphore.h>
#include "ieee1394_types.h"
#include "ieee1394.h"
@@ -86,7 +85,7 @@ static void dump_packet(const char *text, quadlet_t *data, int size, int speed)
printk("\n");
}
#else
-#define dump_packet(a,b,c,d)
+#define dump_packet(a,b,c,d) do {} while (0)
#endif
static void abort_requests(struct hpsb_host *host);
@@ -355,10 +354,12 @@ static void build_speed_map(struct hpsb_host *host, int nodecount)
}
}
+#if SELFID_SPEED_UNKNOWN != IEEE1394_SPEED_MAX
/* assume maximum speed for 1394b PHYs, nodemgr will correct it */
for (n = 0; n < nodecount; n++)
- if (speedcap[n] == 3)
+ if (speedcap[n] == SELFID_SPEED_UNKNOWN)
speedcap[n] = IEEE1394_SPEED_MAX;
+#endif
}
@@ -1169,7 +1170,7 @@ static void __exit ieee1394_cleanup(void)
unregister_chrdev_region(IEEE1394_CORE_DEV, 256);
}
-module_init(ieee1394_init);
+fs_initcall(ieee1394_init); /* same as ohci1394 */
module_exit(ieee1394_cleanup);
/* Exported symbols */
diff --git a/drivers/ieee1394/ieee1394_core.h b/drivers/ieee1394/ieee1394_core.h
index 0ecbf335c64f..af4a78a8ef3b 100644
--- a/drivers/ieee1394/ieee1394_core.h
+++ b/drivers/ieee1394/ieee1394_core.h
@@ -1,12 +1,15 @@
-
#ifndef _IEEE1394_CORE_H
#define _IEEE1394_CORE_H
-#include <linux/slab.h>
+#include <linux/device.h>
+#include <linux/fs.h>
+#include <linux/list.h>
+#include <linux/skbuff.h>
+#include <linux/types.h>
#include <asm/atomic.h>
-#include <asm/semaphore.h>
-#include "hosts.h"
+#include "hosts.h"
+#include "ieee1394_types.h"
struct hpsb_packet {
/* This struct is basically read-only for hosts with the exception of
@@ -58,7 +61,6 @@ struct hpsb_packet {
size_t header_size;
size_t data_size;
-
struct hpsb_host *host;
unsigned int generation;
@@ -80,7 +82,7 @@ struct hpsb_packet {
/* Set a task for when a packet completes */
void hpsb_set_packet_complete_task(struct hpsb_packet *packet,
- void (*routine)(void *), void *data);
+ void (*routine)(void *), void *data);
static inline struct hpsb_packet *driver_packet(struct list_head *l)
{
@@ -92,7 +94,6 @@ void abort_timedouts(unsigned long __opaque);
struct hpsb_packet *hpsb_alloc_packet(size_t data_size);
void hpsb_free_packet(struct hpsb_packet *packet);
-
/*
* Generation counter for the complete 1394 subsystem. Generation gets
* incremented on every change in the subsystem (e.g. bus reset).
@@ -204,10 +205,14 @@ void hpsb_packet_received(struct hpsb_host *host, quadlet_t *data, size_t size,
#define IEEE1394_MINOR_BLOCK_EXPERIMENTAL 15
#define IEEE1394_CORE_DEV MKDEV(IEEE1394_MAJOR, 0)
-#define IEEE1394_RAW1394_DEV MKDEV(IEEE1394_MAJOR, IEEE1394_MINOR_BLOCK_RAW1394 * 16)
-#define IEEE1394_VIDEO1394_DEV MKDEV(IEEE1394_MAJOR, IEEE1394_MINOR_BLOCK_VIDEO1394 * 16)
-#define IEEE1394_DV1394_DEV MKDEV(IEEE1394_MAJOR, IEEE1394_MINOR_BLOCK_DV1394 * 16)
-#define IEEE1394_EXPERIMENTAL_DEV MKDEV(IEEE1394_MAJOR, IEEE1394_MINOR_BLOCK_EXPERIMENTAL * 16)
+#define IEEE1394_RAW1394_DEV MKDEV(IEEE1394_MAJOR, \
+ IEEE1394_MINOR_BLOCK_RAW1394 * 16)
+#define IEEE1394_VIDEO1394_DEV MKDEV(IEEE1394_MAJOR, \
+ IEEE1394_MINOR_BLOCK_VIDEO1394 * 16)
+#define IEEE1394_DV1394_DEV MKDEV(IEEE1394_MAJOR, \
+ IEEE1394_MINOR_BLOCK_DV1394 * 16)
+#define IEEE1394_EXPERIMENTAL_DEV MKDEV(IEEE1394_MAJOR, \
+ IEEE1394_MINOR_BLOCK_EXPERIMENTAL * 16)
/* return the index (within a minor number block) of a file */
static inline unsigned char ieee1394_file_to_instance(struct file *file)
@@ -223,4 +228,3 @@ extern struct class hpsb_host_class;
extern struct class *hpsb_protocol_class;
#endif /* _IEEE1394_CORE_H */
-
diff --git a/drivers/ieee1394/ieee1394_hotplug.h b/drivers/ieee1394/ieee1394_hotplug.h
index 5be70d31b007..dd5500ed8322 100644
--- a/drivers/ieee1394/ieee1394_hotplug.h
+++ b/drivers/ieee1394/ieee1394_hotplug.h
@@ -1,33 +1,19 @@
#ifndef _IEEE1394_HOTPLUG_H
#define _IEEE1394_HOTPLUG_H
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/mod_devicetable.h>
-
/* Unit spec id and sw version entry for some protocols */
#define AVC_UNIT_SPEC_ID_ENTRY 0x0000A02D
#define AVC_SW_VERSION_ENTRY 0x00010001
#define CAMERA_UNIT_SPEC_ID_ENTRY 0x0000A02D
#define CAMERA_SW_VERSION_ENTRY 0x00000100
-/* Check to make sure this all isn't already defined */
-#ifndef IEEE1394_MATCH_VENDOR_ID
-
-#define IEEE1394_MATCH_VENDOR_ID 0x0001
-#define IEEE1394_MATCH_MODEL_ID 0x0002
-#define IEEE1394_MATCH_SPECIFIER_ID 0x0004
-#define IEEE1394_MATCH_VERSION 0x0008
-
-struct ieee1394_device_id {
- u32 match_flags;
- u32 vendor_id;
- u32 model_id;
- u32 specifier_id;
- u32 version;
- void *driver_data;
-};
-
-#endif
+/* /include/linux/mod_devicetable.h defines:
+ * IEEE1394_MATCH_VENDOR_ID
+ * IEEE1394_MATCH_MODEL_ID
+ * IEEE1394_MATCH_SPECIFIER_ID
+ * IEEE1394_MATCH_VERSION
+ * struct ieee1394_device_id
+ */
+#include <linux/mod_devicetable.h>
#endif /* _IEEE1394_HOTPLUG_H */
diff --git a/drivers/ieee1394/ieee1394_transactions.c b/drivers/ieee1394/ieee1394_transactions.c
index a114b91d606d..0833fc9f50c4 100644
--- a/drivers/ieee1394/ieee1394_transactions.c
+++ b/drivers/ieee1394/ieee1394_transactions.c
@@ -9,19 +9,17 @@
* directory of the kernel sources for details.
*/
-#include <linux/sched.h>
#include <linux/bitops.h>
-#include <linux/smp_lock.h>
-#include <linux/interrupt.h>
+#include <linux/spinlock.h>
+#include <linux/wait.h>
+#include <asm/bug.h>
#include <asm/errno.h>
#include "ieee1394.h"
#include "ieee1394_types.h"
#include "hosts.h"
#include "ieee1394_core.h"
-#include "highlevel.h"
-#include "nodemgr.h"
#include "ieee1394_transactions.h"
#define PREP_ASYNC_HEAD_ADDRESS(tc) \
@@ -31,6 +29,13 @@
packet->header[1] = (packet->host->node_id << 16) | (addr >> 32); \
packet->header[2] = addr & 0xffffffff
+#ifndef HPSB_DEBUG_TLABELS
+static
+#endif
+spinlock_t hpsb_tlabel_lock = SPIN_LOCK_UNLOCKED;
+
+static DECLARE_WAIT_QUEUE_HEAD(tlabel_wq);
+
static void fill_async_readquad(struct hpsb_packet *packet, u64 addr)
{
PREP_ASYNC_HEAD_ADDRESS(TCODE_READQ);
@@ -114,9 +119,41 @@ static void fill_async_stream_packet(struct hpsb_packet *packet, int length,
packet->tcode = TCODE_ISO_DATA;
}
+/* same as hpsb_get_tlabel, except that it returns immediately */
+static int hpsb_get_tlabel_atomic(struct hpsb_packet *packet)
+{
+ unsigned long flags, *tp;
+ u8 *next;
+ int tlabel, n = NODEID_TO_NODE(packet->node_id);
+
+ /* Broadcast transactions are complete once the request has been sent.
+ * Use the same transaction label for all broadcast transactions. */
+ if (unlikely(n == ALL_NODES)) {
+ packet->tlabel = 0;
+ return 0;
+ }
+ tp = packet->host->tl_pool[n].map;
+ next = &packet->host->next_tl[n];
+
+ spin_lock_irqsave(&hpsb_tlabel_lock, flags);
+ tlabel = find_next_zero_bit(tp, 64, *next);
+ if (tlabel > 63)
+ tlabel = find_first_zero_bit(tp, 64);
+ if (tlabel > 63) {
+ spin_unlock_irqrestore(&hpsb_tlabel_lock, flags);
+ return -EAGAIN;
+ }
+ __set_bit(tlabel, tp);
+ *next = (tlabel + 1) & 63;
+ spin_unlock_irqrestore(&hpsb_tlabel_lock, flags);
+
+ packet->tlabel = tlabel;
+ return 0;
+}
+
/**
* hpsb_get_tlabel - allocate a transaction label
- * @packet: the packet who's tlabel/tpool we set
+ * @packet: the packet whose tlabel and tl_pool we set
*
* Every asynchronous transaction on the 1394 bus needs a transaction
* label to match the response to the request. This label has to be
@@ -130,42 +167,25 @@ static void fill_async_stream_packet(struct hpsb_packet *packet, int length,
* Return value: Zero on success, otherwise non-zero. A non-zero return
* generally means there are no available tlabels. If this is called out
* of interrupt or atomic context, then it will sleep until can return a
- * tlabel.
+ * tlabel or a signal is received.
*/
int hpsb_get_tlabel(struct hpsb_packet *packet)
{
- unsigned long flags;
- struct hpsb_tlabel_pool *tp;
- int n = NODEID_TO_NODE(packet->node_id);
-
- if (unlikely(n == ALL_NODES))
- return 0;
- tp = &packet->host->tpool[n];
-
- if (irqs_disabled() || in_atomic()) {
- if (down_trylock(&tp->count))
- return 1;
- } else {
- down(&tp->count);
- }
-
- spin_lock_irqsave(&tp->lock, flags);
-
- packet->tlabel = find_next_zero_bit(tp->pool, 64, tp->next);
- if (packet->tlabel > 63)
- packet->tlabel = find_first_zero_bit(tp->pool, 64);
- tp->next = (packet->tlabel + 1) % 64;
- /* Should _never_ happen */
- BUG_ON(test_and_set_bit(packet->tlabel, tp->pool));
- tp->allocations++;
- spin_unlock_irqrestore(&tp->lock, flags);
-
- return 0;
+ if (irqs_disabled() || in_atomic())
+ return hpsb_get_tlabel_atomic(packet);
+
+ /* NB: The macro wait_event_interruptible() is called with a condition
+ * argument with side effect. This is only possible because the side
+ * effect does not occur until the condition became true, and
+ * wait_event_interruptible() won't evaluate the condition again after
+ * that. */
+ return wait_event_interruptible(tlabel_wq,
+ !hpsb_get_tlabel_atomic(packet));
}
/**
* hpsb_free_tlabel - free an allocated transaction label
- * @packet: packet whos tlabel/tpool needs to be cleared
+ * @packet: packet whose tlabel and tl_pool needs to be cleared
*
* Frees the transaction label allocated with hpsb_get_tlabel(). The
* tlabel has to be freed after the transaction is complete (i.e. response
@@ -176,21 +196,20 @@ int hpsb_get_tlabel(struct hpsb_packet *packet)
*/
void hpsb_free_tlabel(struct hpsb_packet *packet)
{
- unsigned long flags;
- struct hpsb_tlabel_pool *tp;
- int n = NODEID_TO_NODE(packet->node_id);
+ unsigned long flags, *tp;
+ int tlabel, n = NODEID_TO_NODE(packet->node_id);
if (unlikely(n == ALL_NODES))
return;
- tp = &packet->host->tpool[n];
+ tp = packet->host->tl_pool[n].map;
+ tlabel = packet->tlabel;
+ BUG_ON(tlabel > 63 || tlabel < 0);
- BUG_ON(packet->tlabel > 63 || packet->tlabel < 0);
+ spin_lock_irqsave(&hpsb_tlabel_lock, flags);
+ BUG_ON(!__test_and_clear_bit(tlabel, tp));
+ spin_unlock_irqrestore(&hpsb_tlabel_lock, flags);
- spin_lock_irqsave(&tp->lock, flags);
- BUG_ON(!test_and_clear_bit(packet->tlabel, tp->pool));
- spin_unlock_irqrestore(&tp->lock, flags);
-
- up(&tp->count);
+ wake_up_interruptible(&tlabel_wq);
}
int hpsb_packet_success(struct hpsb_packet *packet)
@@ -214,7 +233,7 @@ int hpsb_packet_success(struct hpsb_packet *packet)
packet->node_id);
return -EAGAIN;
}
- HPSB_PANIC("reached unreachable code 1 in %s", __FUNCTION__);
+ BUG();
case ACK_BUSY_X:
case ACK_BUSY_A:
@@ -261,8 +280,7 @@ int hpsb_packet_success(struct hpsb_packet *packet)
packet->ack_code, packet->node_id, packet->tcode);
return -EAGAIN;
}
-
- HPSB_PANIC("reached unreachable code 2 in %s", __FUNCTION__);
+ BUG();
}
struct hpsb_packet *hpsb_make_readpacket(struct hpsb_host *host, nodeid_t node,
diff --git a/drivers/ieee1394/ieee1394_transactions.h b/drivers/ieee1394/ieee1394_transactions.h
index 45ba784fe6da..c1369c41469b 100644
--- a/drivers/ieee1394/ieee1394_transactions.h
+++ b/drivers/ieee1394/ieee1394_transactions.h
@@ -1,32 +1,32 @@
#ifndef _IEEE1394_TRANSACTIONS_H
#define _IEEE1394_TRANSACTIONS_H
-#include "ieee1394_core.h"
+#include <linux/types.h>
+#include "ieee1394_types.h"
+
+struct hpsb_packet;
+struct hpsb_host;
-/*
- * Get and free transaction labels.
- */
int hpsb_get_tlabel(struct hpsb_packet *packet);
void hpsb_free_tlabel(struct hpsb_packet *packet);
-
struct hpsb_packet *hpsb_make_readpacket(struct hpsb_host *host, nodeid_t node,
u64 addr, size_t length);
struct hpsb_packet *hpsb_make_lockpacket(struct hpsb_host *host, nodeid_t node,
- u64 addr, int extcode, quadlet_t *data,
+ u64 addr, int extcode, quadlet_t *data,
quadlet_t arg);
-struct hpsb_packet *hpsb_make_lock64packet(struct hpsb_host *host, nodeid_t node,
- u64 addr, int extcode, octlet_t *data,
- octlet_t arg);
-struct hpsb_packet *hpsb_make_phypacket(struct hpsb_host *host,
- quadlet_t data) ;
-struct hpsb_packet *hpsb_make_isopacket(struct hpsb_host *host,
- int length, int channel,
- int tag, int sync);
-struct hpsb_packet *hpsb_make_writepacket (struct hpsb_host *host, nodeid_t node,
- u64 addr, quadlet_t *buffer, size_t length);
+struct hpsb_packet *hpsb_make_lock64packet(struct hpsb_host *host,
+ nodeid_t node, u64 addr, int extcode,
+ octlet_t *data, octlet_t arg);
+struct hpsb_packet *hpsb_make_phypacket(struct hpsb_host *host, quadlet_t data);
+struct hpsb_packet *hpsb_make_isopacket(struct hpsb_host *host, int length,
+ int channel, int tag, int sync);
+struct hpsb_packet *hpsb_make_writepacket(struct hpsb_host *host,
+ nodeid_t node, u64 addr,
+ quadlet_t *buffer, size_t length);
struct hpsb_packet *hpsb_make_streampacket(struct hpsb_host *host, u8 *buffer,
- int length, int channel, int tag, int sync);
+ int length, int channel, int tag,
+ int sync);
/*
* hpsb_packet_success - Make sense of the ack and reply codes and
@@ -40,9 +40,8 @@ struct hpsb_packet *hpsb_make_streampacket(struct hpsb_host *host, u8 *buffer,
*/
int hpsb_packet_success(struct hpsb_packet *packet);
-
/*
- * The generic read, write and lock functions. All recognize the local node ID
+ * The generic read and write functions. All recognize the local node ID
* and act accordingly. Read and write automatically use quadlet commands if
* length == 4 and and block commands otherwise (however, they do not yet
* support lengths that are not a multiple of 4). You must explicitly specifiy
@@ -54,4 +53,8 @@ int hpsb_read(struct hpsb_host *host, nodeid_t node, unsigned int generation,
int hpsb_write(struct hpsb_host *host, nodeid_t node, unsigned int generation,
u64 addr, quadlet_t *buffer, size_t length);
+#ifdef HPSB_DEBUG_TLABELS
+extern spinlock_t hpsb_tlabel_lock;
+#endif
+
#endif /* _IEEE1394_TRANSACTIONS_H */
diff --git a/drivers/ieee1394/ieee1394_types.h b/drivers/ieee1394/ieee1394_types.h
index 3165609ec1ec..9803aaa15be0 100644
--- a/drivers/ieee1394/ieee1394_types.h
+++ b/drivers/ieee1394/ieee1394_types.h
@@ -1,37 +1,11 @@
-
#ifndef _IEEE1394_TYPES_H
#define _IEEE1394_TYPES_H
#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/list.h>
-#include <linux/init.h>
-#include <linux/spinlock.h>
#include <linux/string.h>
-
-#include <asm/semaphore.h>
+#include <linux/types.h>
#include <asm/byteorder.h>
-
-/* Transaction Label handling */
-struct hpsb_tlabel_pool {
- DECLARE_BITMAP(pool, 64);
- spinlock_t lock;
- u8 next;
- u32 allocations;
- struct semaphore count;
-};
-
-#define HPSB_TPOOL_INIT(_tp) \
-do { \
- bitmap_zero((_tp)->pool, 64); \
- spin_lock_init(&(_tp)->lock); \
- (_tp)->next = 0; \
- (_tp)->allocations = 0; \
- sema_init(&(_tp)->count, 63); \
-} while (0)
-
-
typedef u32 quadlet_t;
typedef u64 octlet_t;
typedef u16 nodeid_t;
@@ -54,46 +28,40 @@ typedef u16 arm_length_t;
#define NODE_BUS_ARGS(__host, __nodeid) \
__host->id, NODEID_TO_NODE(__nodeid), NODEID_TO_BUS(__nodeid)
-#define HPSB_PRINT(level, fmt, args...) printk(level "ieee1394: " fmt "\n" , ## args)
+#define HPSB_PRINT(level, fmt, args...) \
+ printk(level "ieee1394: " fmt "\n" , ## args)
-#define HPSB_DEBUG(fmt, args...) HPSB_PRINT(KERN_DEBUG, fmt , ## args)
-#define HPSB_INFO(fmt, args...) HPSB_PRINT(KERN_INFO, fmt , ## args)
-#define HPSB_NOTICE(fmt, args...) HPSB_PRINT(KERN_NOTICE, fmt , ## args)
-#define HPSB_WARN(fmt, args...) HPSB_PRINT(KERN_WARNING, fmt , ## args)
-#define HPSB_ERR(fmt, args...) HPSB_PRINT(KERN_ERR, fmt , ## args)
+#define HPSB_DEBUG(fmt, args...) HPSB_PRINT(KERN_DEBUG, fmt , ## args)
+#define HPSB_INFO(fmt, args...) HPSB_PRINT(KERN_INFO, fmt , ## args)
+#define HPSB_NOTICE(fmt, args...) HPSB_PRINT(KERN_NOTICE, fmt , ## args)
+#define HPSB_WARN(fmt, args...) HPSB_PRINT(KERN_WARNING, fmt , ## args)
+#define HPSB_ERR(fmt, args...) HPSB_PRINT(KERN_ERR, fmt , ## args)
#ifdef CONFIG_IEEE1394_VERBOSEDEBUG
-#define HPSB_VERBOSE(fmt, args...) HPSB_PRINT(KERN_DEBUG, fmt , ## args)
+#define HPSB_VERBOSE(fmt, args...) HPSB_PRINT(KERN_DEBUG, fmt , ## args)
+#define HPSB_DEBUG_TLABELS
#else
-#define HPSB_VERBOSE(fmt, args...)
+#define HPSB_VERBOSE(fmt, args...) do {} while (0)
#endif
-#define HPSB_PANIC(fmt, args...) panic("ieee1394: " fmt "\n" , ## args)
-
-#define HPSB_TRACE() HPSB_PRINT(KERN_INFO, "TRACE - %s, %s(), line %d", __FILE__, __FUNCTION__, __LINE__)
-
-
#ifdef __BIG_ENDIAN
-static __inline__ void *memcpy_le32(u32 *dest, const u32 *__src, size_t count)
+static inline void *memcpy_le32(u32 *dest, const u32 *__src, size_t count)
{
- void *tmp = dest;
+ void *tmp = dest;
u32 *src = (u32 *)__src;
- count /= 4;
-
- while (count--) {
- *dest++ = swab32p(src++);
- }
-
- return tmp;
+ count /= 4;
+ while (count--)
+ *dest++ = swab32p(src++);
+ return tmp;
}
#else
static __inline__ void *memcpy_le32(u32 *dest, const u32 *src, size_t count)
{
- return memcpy(dest, src, count);
+ return memcpy(dest, src, count);
}
#endif /* __BIG_ENDIAN */
diff --git a/drivers/ieee1394/iso.c b/drivers/ieee1394/iso.c
index f26680ebef7c..08bd15d2a7b6 100644
--- a/drivers/ieee1394/iso.c
+++ b/drivers/ieee1394/iso.c
@@ -9,8 +9,11 @@
* directory of the kernel sources for details.
*/
-#include <linux/slab.h>
+#include <linux/pci.h>
#include <linux/sched.h>
+#include <linux/slab.h>
+
+#include "hosts.h"
#include "iso.h"
void hpsb_iso_stop(struct hpsb_iso *iso)
diff --git a/drivers/ieee1394/iso.h b/drivers/ieee1394/iso.h
index 3efc60b33a88..1210a97e8685 100644
--- a/drivers/ieee1394/iso.h
+++ b/drivers/ieee1394/iso.h
@@ -12,33 +12,40 @@
#ifndef IEEE1394_ISO_H
#define IEEE1394_ISO_H
-#include "hosts.h"
+#include <linux/spinlock_types.h>
+#include <asm/atomic.h>
+#include <asm/types.h>
+
#include "dma.h"
-/* high-level ISO interface */
+struct hpsb_host;
-/* This API sends and receives isochronous packets on a large,
- virtually-contiguous kernel memory buffer. The buffer may be mapped
- into a user-space process for zero-copy transmission and reception.
+/* high-level ISO interface */
- There are no explicit boundaries between packets in the buffer. A
- packet may be transmitted or received at any location. However,
- low-level drivers may impose certain restrictions on alignment or
- size of packets. (e.g. in OHCI no packet may cross a page boundary,
- and packets should be quadlet-aligned)
-*/
+/*
+ * This API sends and receives isochronous packets on a large,
+ * virtually-contiguous kernel memory buffer. The buffer may be mapped
+ * into a user-space process for zero-copy transmission and reception.
+ *
+ * There are no explicit boundaries between packets in the buffer. A
+ * packet may be transmitted or received at any location. However,
+ * low-level drivers may impose certain restrictions on alignment or
+ * size of packets. (e.g. in OHCI no packet may cross a page boundary,
+ * and packets should be quadlet-aligned)
+ */
/* Packet descriptor - the API maintains a ring buffer of these packet
- descriptors in kernel memory (hpsb_iso.infos[]). */
-
+ * descriptors in kernel memory (hpsb_iso.infos[]). */
struct hpsb_iso_packet_info {
/* offset of data payload relative to the first byte of the buffer */
__u32 offset;
- /* length of the data payload, in bytes (not including the isochronous header) */
+ /* length of the data payload, in bytes (not including the isochronous
+ * header) */
__u16 len;
- /* (recv only) the cycle number (mod 8000) on which the packet was received */
+ /* (recv only) the cycle number (mod 8000) on which the packet was
+ * received */
__u16 cycle;
/* (recv only) channel on which the packet was received */
@@ -48,12 +55,10 @@ struct hpsb_iso_packet_info {
__u8 tag;
__u8 sy;
- /*
- * length in bytes of the packet including header/trailer.
- * MUST be at structure end, since the first part of this structure is also
- * defined in raw1394.h (i.e. struct raw1394_iso_packet_info), is copied to
- * userspace and is accessed there through libraw1394.
- */
+ /* length in bytes of the packet including header/trailer.
+ * MUST be at structure end, since the first part of this structure is
+ * also defined in raw1394.h (i.e. struct raw1394_iso_packet_info), is
+ * copied to userspace and is accessed there through libraw1394. */
__u16 total_len;
};
@@ -75,8 +80,8 @@ struct hpsb_iso {
void *hostdata;
/* a function to be called (from interrupt context) after
- outgoing packets have been sent, or incoming packets have
- arrived */
+ * outgoing packets have been sent, or incoming packets have
+ * arrived */
void (*callback)(struct hpsb_iso*);
/* wait for buffer space */
@@ -88,7 +93,7 @@ struct hpsb_iso {
/* greatest # of packets between interrupts - controls
- the maximum latency of the buffer */
+ * the maximum latency of the buffer */
int irq_interval;
/* the buffer for packet data payloads */
@@ -112,8 +117,8 @@ struct hpsb_iso {
int pkt_dma;
/* how many packets, starting at first_packet:
- (transmit) are ready to be filled with data
- (receive) contain received data */
+ * (transmit) are ready to be filled with data
+ * (receive) contain received data */
int n_ready_packets;
/* how many times the buffer has overflowed or underflowed */
@@ -134,7 +139,7 @@ struct hpsb_iso {
int start_cycle;
/* cycle at which next packet will be transmitted,
- -1 if not known */
+ * -1 if not known */
int xmit_cycle;
/* ringbuffer of packet descriptors in regular kernel memory
@@ -170,25 +175,30 @@ int hpsb_iso_recv_unlisten_channel(struct hpsb_iso *iso, unsigned char channel);
int hpsb_iso_recv_set_channel_mask(struct hpsb_iso *iso, u64 mask);
/* start/stop DMA */
-int hpsb_iso_xmit_start(struct hpsb_iso *iso, int start_on_cycle, int prebuffer);
-int hpsb_iso_recv_start(struct hpsb_iso *iso, int start_on_cycle, int tag_mask, int sync);
+int hpsb_iso_xmit_start(struct hpsb_iso *iso, int start_on_cycle,
+ int prebuffer);
+int hpsb_iso_recv_start(struct hpsb_iso *iso, int start_on_cycle,
+ int tag_mask, int sync);
void hpsb_iso_stop(struct hpsb_iso *iso);
/* deallocate buffer and DMA context */
void hpsb_iso_shutdown(struct hpsb_iso *iso);
-/* queue a packet for transmission. 'offset' is relative to the beginning of the
- DMA buffer, where the packet's data payload should already have been placed */
-int hpsb_iso_xmit_queue_packet(struct hpsb_iso *iso, u32 offset, u16 len, u8 tag, u8 sy);
+/* queue a packet for transmission.
+ * 'offset' is relative to the beginning of the DMA buffer, where the packet's
+ * data payload should already have been placed. */
+int hpsb_iso_xmit_queue_packet(struct hpsb_iso *iso, u32 offset, u16 len,
+ u8 tag, u8 sy);
/* wait until all queued packets have been transmitted to the bus */
int hpsb_iso_xmit_sync(struct hpsb_iso *iso);
/* N packets have been read out of the buffer, re-use the buffer space */
-int hpsb_iso_recv_release_packets(struct hpsb_iso *recv, unsigned int n_packets);
+int hpsb_iso_recv_release_packets(struct hpsb_iso *recv,
+ unsigned int n_packets);
/* check for arrival of new packets immediately (even if irq_interval
- has not yet been reached) */
+ * has not yet been reached) */
int hpsb_iso_recv_flush(struct hpsb_iso *iso);
/* returns # of packets ready to send or receive */
@@ -197,14 +207,15 @@ int hpsb_iso_n_ready(struct hpsb_iso *iso);
/* the following are callbacks available to low-level drivers */
/* call after a packet has been transmitted to the bus (interrupt context is OK)
- 'cycle' is the _exact_ cycle the packet was sent on
- 'error' should be non-zero if some sort of error occurred when sending the packet
-*/
+ * 'cycle' is the _exact_ cycle the packet was sent on
+ * 'error' should be non-zero if some sort of error occurred when sending the
+ * packet */
void hpsb_iso_packet_sent(struct hpsb_iso *iso, int cycle, int error);
/* call after a packet has been received (interrupt context OK) */
void hpsb_iso_packet_received(struct hpsb_iso *iso, u32 offset, u16 len,
- u16 total_len, u16 cycle, u8 channel, u8 tag, u8 sy);
+ u16 total_len, u16 cycle, u8 channel, u8 tag,
+ u8 sy);
/* call to wake waiting processes after buffer space has opened up. */
void hpsb_iso_wake(struct hpsb_iso *iso);
diff --git a/drivers/ieee1394/nodemgr.c b/drivers/ieee1394/nodemgr.c
index d541b508a159..3e7974c57443 100644
--- a/drivers/ieee1394/nodemgr.c
+++ b/drivers/ieee1394/nodemgr.c
@@ -12,26 +12,23 @@
#include <linux/kernel.h>
#include <linux/list.h>
#include <linux/slab.h>
-#include <linux/smp_lock.h>
-#include <linux/interrupt.h>
-#include <linux/kmod.h>
-#include <linux/completion.h>
#include <linux/delay.h>
-#include <linux/pci.h>
+#include <linux/kthread.h>
#include <linux/moduleparam.h>
#include <asm/atomic.h>
-#include "ieee1394_types.h"
+#include "csr.h"
+#include "highlevel.h"
+#include "hosts.h"
#include "ieee1394.h"
#include "ieee1394_core.h"
-#include "hosts.h"
+#include "ieee1394_hotplug.h"
+#include "ieee1394_types.h"
#include "ieee1394_transactions.h"
-#include "highlevel.h"
-#include "csr.h"
#include "nodemgr.h"
static int ignore_drivers;
-module_param(ignore_drivers, int, 0444);
+module_param(ignore_drivers, int, S_IRUGO | S_IWUSR);
MODULE_PARM_DESC(ignore_drivers, "Disable automatic probing for drivers.");
struct nodemgr_csr_info {
@@ -71,7 +68,7 @@ static int nodemgr_check_speed(struct nodemgr_csr_info *ci, u64 addr,
u8 i, *speed, old_speed, good_speed;
int ret;
- speed = ci->host->speed + NODEID_TO_NODE(ci->nodeid);
+ speed = &(ci->host->speed[NODEID_TO_NODE(ci->nodeid)]);
old_speed = *speed;
good_speed = IEEE1394_SPEED_MAX + 1;
@@ -161,16 +158,12 @@ static struct csr1212_bus_ops nodemgr_csr_ops = {
* but now we are much simpler because of the LDM.
*/
-static DECLARE_MUTEX(nodemgr_serialize);
+static DEFINE_MUTEX(nodemgr_serialize);
struct host_info {
struct hpsb_host *host;
struct list_head list;
- struct completion exited;
- struct semaphore reset_sem;
- int pid;
- char daemon_name[15];
- int kill_me;
+ struct task_struct *thread;
};
static int nodemgr_bus_match(struct device * dev, struct device_driver * drv);
@@ -334,34 +327,44 @@ static ssize_t fw_show_ne_bus_options(struct device *dev, struct device_attribut
static DEVICE_ATTR(bus_options,S_IRUGO,fw_show_ne_bus_options,NULL);
-/* tlabels_free, tlabels_allocations, tlabels_mask are read non-atomically
- * here, therefore displayed values may be occasionally wrong. */
-static ssize_t fw_show_ne_tlabels_free(struct device *dev, struct device_attribute *attr, char *buf)
+#ifdef HPSB_DEBUG_TLABELS
+static ssize_t fw_show_ne_tlabels_free(struct device *dev,
+ struct device_attribute *attr, char *buf)
{
struct node_entry *ne = container_of(dev, struct node_entry, device);
- return sprintf(buf, "%d\n", 64 - bitmap_weight(ne->tpool->pool, 64));
-}
-static DEVICE_ATTR(tlabels_free,S_IRUGO,fw_show_ne_tlabels_free,NULL);
+ unsigned long flags;
+ unsigned long *tp = ne->host->tl_pool[NODEID_TO_NODE(ne->nodeid)].map;
+ int tf;
+ spin_lock_irqsave(&hpsb_tlabel_lock, flags);
+ tf = 64 - bitmap_weight(tp, 64);
+ spin_unlock_irqrestore(&hpsb_tlabel_lock, flags);
-static ssize_t fw_show_ne_tlabels_allocations(struct device *dev, struct device_attribute *attr, char *buf)
-{
- struct node_entry *ne = container_of(dev, struct node_entry, device);
- return sprintf(buf, "%u\n", ne->tpool->allocations);
+ return sprintf(buf, "%d\n", tf);
}
-static DEVICE_ATTR(tlabels_allocations,S_IRUGO,fw_show_ne_tlabels_allocations,NULL);
+static DEVICE_ATTR(tlabels_free,S_IRUGO,fw_show_ne_tlabels_free,NULL);
-static ssize_t fw_show_ne_tlabels_mask(struct device *dev, struct device_attribute *attr, char *buf)
+static ssize_t fw_show_ne_tlabels_mask(struct device *dev,
+ struct device_attribute *attr, char *buf)
{
struct node_entry *ne = container_of(dev, struct node_entry, device);
+ unsigned long flags;
+ unsigned long *tp = ne->host->tl_pool[NODEID_TO_NODE(ne->nodeid)].map;
+ u64 tm;
+
+ spin_lock_irqsave(&hpsb_tlabel_lock, flags);
#if (BITS_PER_LONG <= 32)
- return sprintf(buf, "0x%08lx%08lx\n", ne->tpool->pool[0], ne->tpool->pool[1]);
+ tm = ((u64)tp[0] << 32) + tp[1];
#else
- return sprintf(buf, "0x%016lx\n", ne->tpool->pool[0]);
+ tm = tp[0];
#endif
+ spin_unlock_irqrestore(&hpsb_tlabel_lock, flags);
+
+ return sprintf(buf, "0x%016llx\n", tm);
}
static DEVICE_ATTR(tlabels_mask, S_IRUGO, fw_show_ne_tlabels_mask, NULL);
+#endif /* HPSB_DEBUG_TLABELS */
static ssize_t fw_set_ignore_driver(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
@@ -408,26 +411,11 @@ static ssize_t fw_get_destroy_node(struct bus_type *bus, char *buf)
}
static BUS_ATTR(destroy_node, S_IWUSR | S_IRUGO, fw_get_destroy_node, fw_set_destroy_node);
-static int nodemgr_rescan_bus_thread(void *__unused)
-{
- /* No userlevel access needed */
- daemonize("kfwrescan");
-
- bus_rescan_devices(&ieee1394_bus_type);
-
- return 0;
-}
static ssize_t fw_set_rescan(struct bus_type *bus, const char *buf, size_t count)
{
- int state = simple_strtoul(buf, NULL, 10);
-
- /* Don't wait for this, or care about errors. Root could do
- * something stupid and spawn this a lot of times, but that's
- * root's fault. */
- if (state == 1)
- kernel_thread(nodemgr_rescan_bus_thread, NULL, CLONE_KERNEL);
-
+ if (simple_strtoul(buf, NULL, 10) == 1)
+ bus_rescan_devices(&ieee1394_bus_type);
return count;
}
static ssize_t fw_get_rescan(struct bus_type *bus, char *buf)
@@ -483,9 +471,10 @@ static struct device_attribute *const fw_ne_attrs[] = {
&dev_attr_ne_vendor_id,
&dev_attr_ne_nodeid,
&dev_attr_bus_options,
+#ifdef HPSB_DEBUG_TLABELS
&dev_attr_tlabels_free,
- &dev_attr_tlabels_allocations,
&dev_attr_tlabels_mask,
+#endif
};
@@ -804,8 +793,6 @@ static struct node_entry *nodemgr_create_node(octlet_t guid, struct csr1212_csr
if (!ne)
return NULL;
- ne->tpool = &host->tpool[nodeid & NODE_MASK];
-
ne->host = host;
ne->nodeid = nodeid;
ne->generation = generation;
@@ -1251,6 +1238,7 @@ static void nodemgr_node_scan_one(struct host_info *hi,
octlet_t guid;
struct csr1212_csr *csr;
struct nodemgr_csr_info *ci;
+ u8 *speed;
ci = kmalloc(sizeof(*ci), GFP_KERNEL);
if (!ci)
@@ -1259,8 +1247,12 @@ static void nodemgr_node_scan_one(struct host_info *hi,
ci->host = host;
ci->nodeid = nodeid;
ci->generation = generation;
- ci->speed_unverified =
- host->speed[NODEID_TO_NODE(nodeid)] > IEEE1394_SPEED_100;
+
+ /* Prepare for speed probe which occurs when reading the ROM */
+ speed = &(host->speed[NODEID_TO_NODE(nodeid)]);
+ if (*speed > host->csr.lnk_spd)
+ *speed = host->csr.lnk_spd;
+ ci->speed_unverified = *speed > IEEE1394_SPEED_100;
/* We need to detect when the ConfigROM's generation has changed,
* so we only update the node's info when it needs to be. */
@@ -1300,8 +1292,6 @@ static void nodemgr_node_scan_one(struct host_info *hi,
nodemgr_create_node(guid, csr, hi, nodeid, generation);
else
nodemgr_update_node(ne, csr, hi, nodeid, generation);
-
- return;
}
@@ -1326,6 +1316,7 @@ static void nodemgr_node_scan(struct host_info *hi, int generation)
}
+/* Caller needs to hold nodemgr_ud_class.subsys.rwsem as reader. */
static void nodemgr_suspend_ne(struct node_entry *ne)
{
struct class_device *cdev;
@@ -1361,6 +1352,7 @@ static void nodemgr_resume_ne(struct node_entry *ne)
ne->in_limbo = 0;
device_remove_file(&ne->device, &dev_attr_ne_in_limbo);
+ down_read(&nodemgr_ud_class.subsys.rwsem);
down_read(&ne->device.bus->subsys.rwsem);
list_for_each_entry(cdev, &nodemgr_ud_class.children, node) {
ud = container_of(cdev, struct unit_directory, class_dev);
@@ -1372,21 +1364,21 @@ static void nodemgr_resume_ne(struct node_entry *ne)
ud->device.driver->resume(&ud->device);
}
up_read(&ne->device.bus->subsys.rwsem);
+ up_read(&nodemgr_ud_class.subsys.rwsem);
HPSB_DEBUG("Node resumed: ID:BUS[" NODE_BUS_FMT "] GUID[%016Lx]",
NODE_BUS_ARGS(ne->host, ne->nodeid), (unsigned long long)ne->guid);
}
+/* Caller needs to hold nodemgr_ud_class.subsys.rwsem as reader. */
static void nodemgr_update_pdrv(struct node_entry *ne)
{
struct unit_directory *ud;
struct hpsb_protocol_driver *pdrv;
- struct class *class = &nodemgr_ud_class;
struct class_device *cdev;
- down_read(&class->subsys.rwsem);
- list_for_each_entry(cdev, &class->children, node) {
+ list_for_each_entry(cdev, &nodemgr_ud_class.children, node) {
ud = container_of(cdev, struct unit_directory, class_dev);
if (ud->ne != ne || !ud->device.driver)
continue;
@@ -1399,7 +1391,6 @@ static void nodemgr_update_pdrv(struct node_entry *ne)
up_write(&ud->device.bus->subsys.rwsem);
}
}
- up_read(&class->subsys.rwsem);
}
@@ -1430,6 +1421,8 @@ static void nodemgr_irm_write_bc(struct node_entry *ne, int generation)
}
+/* Caller needs to hold nodemgr_ud_class.subsys.rwsem as reader because the
+ * calls to nodemgr_update_pdrv() and nodemgr_suspend_ne() here require it. */
static void nodemgr_probe_ne(struct host_info *hi, struct node_entry *ne, int generation)
{
struct device *dev;
@@ -1492,9 +1485,8 @@ static void nodemgr_node_probe(struct host_info *hi, int generation)
/* If we had a bus reset while we were scanning the bus, it is
* possible that we did not probe all nodes. In that case, we
* skip the clean up for now, since we could remove nodes that
- * were still on the bus. The bus reset increased hi->reset_sem,
- * so there's a bus scan pending which will do the clean up
- * eventually.
+ * were still on the bus. Another bus scan is pending which will
+ * do the clean up eventually.
*
* Now let's tell the bus to rescan our devices. This may seem
* like overhead, but the driver-model core will only scan a
@@ -1622,41 +1614,37 @@ static int nodemgr_host_thread(void *__hi)
{
struct host_info *hi = (struct host_info *)__hi;
struct hpsb_host *host = hi->host;
- int reset_cycles = 0;
-
- /* No userlevel access needed */
- daemonize(hi->daemon_name);
+ unsigned int g, generation = get_hpsb_generation(host) - 1;
+ int i, reset_cycles = 0;
/* Setup our device-model entries */
nodemgr_create_host_dev_files(host);
- /* Sit and wait for a signal to probe the nodes on the bus. This
- * happens when we get a bus reset. */
- while (1) {
- unsigned int generation = 0;
- int i;
+ for (;;) {
+ /* Sleep until next bus reset */
+ set_current_state(TASK_INTERRUPTIBLE);
+ if (get_hpsb_generation(host) == generation)
+ schedule();
+ __set_current_state(TASK_RUNNING);
+
+ /* Thread may have been woken up to freeze or to exit */
+ if (try_to_freeze())
+ continue;
+ if (kthread_should_stop())
+ goto exit;
- if (down_interruptible(&hi->reset_sem) ||
- down_interruptible(&nodemgr_serialize)) {
+ if (mutex_lock_interruptible(&nodemgr_serialize)) {
if (try_to_freeze())
continue;
- printk("NodeMgr: received unexpected signal?!\n" );
- break;
- }
-
- if (hi->kill_me) {
- up(&nodemgr_serialize);
- break;
+ goto exit;
}
/* Pause for 1/4 second in 1/16 second intervals,
* to make sure things settle down. */
+ g = get_hpsb_generation(host);
for (i = 0; i < 4 ; i++) {
- set_current_state(TASK_INTERRUPTIBLE);
- if (msleep_interruptible(63)) {
- up(&nodemgr_serialize);
- goto caught_signal;
- }
+ if (msleep_interruptible(63) || kthread_should_stop())
+ goto unlock_exit;
/* Now get the generation in which the node ID's we collect
* are valid. During the bus scan we will use this generation
@@ -1667,20 +1655,14 @@ static int nodemgr_host_thread(void *__hi)
/* If we get a reset before we are done waiting, then
* start the the waiting over again */
- while (!down_trylock(&hi->reset_sem))
- i = 0;
-
- /* Check the kill_me again */
- if (hi->kill_me) {
- up(&nodemgr_serialize);
- goto caught_signal;
- }
+ if (generation != g)
+ g = generation, i = 0;
}
if (!nodemgr_check_irm_capability(host, reset_cycles) ||
!nodemgr_do_irm_duties(host, reset_cycles)) {
reset_cycles++;
- up(&nodemgr_serialize);
+ mutex_unlock(&nodemgr_serialize);
continue;
}
reset_cycles = 0;
@@ -1698,13 +1680,13 @@ static int nodemgr_host_thread(void *__hi)
/* Update some of our sysfs symlinks */
nodemgr_update_host_dev_links(host);
- up(&nodemgr_serialize);
+ mutex_unlock(&nodemgr_serialize);
}
-
-caught_signal:
+unlock_exit:
+ mutex_unlock(&nodemgr_serialize);
+exit:
HPSB_VERBOSE("NodeMgr: Exiting thread");
-
- complete_and_exit(&hi->exited, 0);
+ return 0;
}
int nodemgr_for_each_host(void *__data, int (*cb)(struct hpsb_host *, void *))
@@ -1764,41 +1746,27 @@ static void nodemgr_add_host(struct hpsb_host *host)
struct host_info *hi;
hi = hpsb_create_hostinfo(&nodemgr_highlevel, host, sizeof(*hi));
-
if (!hi) {
- HPSB_ERR ("NodeMgr: out of memory in add host");
+ HPSB_ERR("NodeMgr: out of memory in add host");
return;
}
-
hi->host = host;
- init_completion(&hi->exited);
- sema_init(&hi->reset_sem, 0);
-
- sprintf(hi->daemon_name, "knodemgrd_%d", host->id);
-
- hi->pid = kernel_thread(nodemgr_host_thread, hi, CLONE_KERNEL);
-
- if (hi->pid < 0) {
- HPSB_ERR ("NodeMgr: failed to start %s thread for %s",
- hi->daemon_name, host->driver->name);
+ hi->thread = kthread_run(nodemgr_host_thread, hi, "knodemgrd_%d",
+ host->id);
+ if (IS_ERR(hi->thread)) {
+ HPSB_ERR("NodeMgr: cannot start thread for host %d", host->id);
hpsb_destroy_hostinfo(&nodemgr_highlevel, host);
- return;
}
-
- return;
}
static void nodemgr_host_reset(struct hpsb_host *host)
{
struct host_info *hi = hpsb_get_hostinfo(&nodemgr_highlevel, host);
- if (hi != NULL) {
- HPSB_VERBOSE("NodeMgr: Processing host reset for %s", hi->daemon_name);
- up(&hi->reset_sem);
- } else
- HPSB_ERR ("NodeMgr: could not process reset of unused host");
-
- return;
+ if (hi) {
+ HPSB_VERBOSE("NodeMgr: Processing reset for host %d", host->id);
+ wake_up_process(hi->thread);
+ }
}
static void nodemgr_remove_host(struct hpsb_host *host)
@@ -1806,18 +1774,9 @@ static void nodemgr_remove_host(struct hpsb_host *host)
struct host_info *hi = hpsb_get_hostinfo(&nodemgr_highlevel, host);
if (hi) {
- if (hi->pid >= 0) {
- hi->kill_me = 1;
- mb();
- up(&hi->reset_sem);
- wait_for_completion(&hi->exited);
- nodemgr_remove_host_dev(&host->device);
- }
- } else
- HPSB_ERR("NodeMgr: host %s does not exist, cannot remove",
- host->driver->name);
-
- return;
+ kthread_stop(hi->thread);
+ nodemgr_remove_host_dev(&host->device);
+ }
}
static struct hpsb_highlevel nodemgr_highlevel = {
diff --git a/drivers/ieee1394/nodemgr.h b/drivers/ieee1394/nodemgr.h
index 0b26616e16c3..0e1e7d930783 100644
--- a/drivers/ieee1394/nodemgr.h
+++ b/drivers/ieee1394/nodemgr.h
@@ -21,9 +21,15 @@
#define _IEEE1394_NODEMGR_H
#include <linux/device.h>
-#include "csr1212.h"
+#include <asm/types.h>
+
#include "ieee1394_core.h"
-#include "ieee1394_hotplug.h"
+#include "ieee1394_types.h"
+
+struct csr1212_csr;
+struct csr1212_keyval;
+struct hpsb_host;
+struct ieee1394_device_id;
/* '1' '3' '9' '4' in ASCII */
#define IEEE1394_BUSID_MAGIC __constant_cpu_to_be32(0x31333934)
@@ -44,7 +50,6 @@ struct bus_options {
u16 max_rec; /* Maximum packet size node can receive */
};
-
#define UNIT_DIRECTORY_VENDOR_ID 0x01
#define UNIT_DIRECTORY_MODEL_ID 0x02
#define UNIT_DIRECTORY_SPECIFIER_ID 0x04
@@ -59,8 +64,8 @@ struct bus_options {
* unit directory for each of these protocols.
*/
struct unit_directory {
- struct node_entry *ne; /* The node which this directory belongs to */
- octlet_t address; /* Address of the unit directory on the node */
+ struct node_entry *ne; /* The node which this directory belongs to */
+ octlet_t address; /* Address of the unit directory on the node */
u8 flags; /* Indicates which entries were read */
quadlet_t vendor_id;
@@ -79,11 +84,10 @@ struct unit_directory {
int length; /* Number of quadlets */
struct device device;
-
struct class_device class_dev;
struct csr1212_keyval *ud_kv;
- u32 lun; /* logical unit number immediate value */
+ u32 lun; /* logical unit number immediate value */
};
struct node_entry {
@@ -103,10 +107,8 @@ struct node_entry {
const char *vendor_oui;
u32 capabilities;
- struct hpsb_tlabel_pool *tpool;
struct device device;
-
struct class_device class_dev;
/* Means this node is not attached anymore */
@@ -153,8 +155,8 @@ static inline int hpsb_node_entry_valid(struct node_entry *ne)
/*
* This will fill in the given, pre-initialised hpsb_packet with the current
* information from the node entry (host, node ID, generation number). It will
- * return false if the node owning the GUID is not accessible (and not modify the
- * hpsb_packet) and return true otherwise.
+ * return false if the node owning the GUID is not accessible (and not modify
+ * the hpsb_packet) and return true otherwise.
*
* Note that packet sending may still fail in hpsb_send_packet if a bus reset
* happens while you are trying to set up the packet (due to obsolete generation
@@ -170,16 +172,13 @@ int hpsb_node_write(struct node_entry *ne, u64 addr,
int hpsb_node_lock(struct node_entry *ne, u64 addr,
int extcode, quadlet_t *data, quadlet_t arg);
-
/* Iterate the hosts, calling a given function with supplied data for each
* host. */
int nodemgr_for_each_host(void *__data, int (*cb)(struct hpsb_host *, void *));
-
int init_ieee1394_nodemgr(void);
void cleanup_ieee1394_nodemgr(void);
-
/* The template for a host device */
extern struct device nodemgr_dev_template_host;
diff --git a/drivers/ieee1394/ohci1394.c b/drivers/ieee1394/ohci1394.c
index 448df2773377..8fd0030475ba 100644
--- a/drivers/ieee1394/ohci1394.c
+++ b/drivers/ieee1394/ohci1394.c
@@ -136,7 +136,7 @@
#define DBGMSG(fmt, args...) \
printk(KERN_INFO "%s: fw-host%d: " fmt "\n" , OHCI1394_DRIVER_NAME, ohci->host->id , ## args)
#else
-#define DBGMSG(fmt, args...)
+#define DBGMSG(fmt, args...) do {} while (0)
#endif
#ifdef CONFIG_IEEE1394_OHCI_DMA_DEBUG
@@ -148,8 +148,8 @@ printk(KERN_INFO "%s: fw-host%d: " fmt "\n" , OHCI1394_DRIVER_NAME, ohci->host->
--global_outstanding_dmas, ## args)
static int global_outstanding_dmas = 0;
#else
-#define OHCI_DMA_ALLOC(fmt, args...)
-#define OHCI_DMA_FREE(fmt, args...)
+#define OHCI_DMA_ALLOC(fmt, args...) do {} while (0)
+#define OHCI_DMA_FREE(fmt, args...) do {} while (0)
#endif
/* print general (card independent) information */
@@ -181,36 +181,35 @@ static int alloc_dma_trm_ctx(struct ti_ohci *ohci, struct dma_trm_ctx *d,
static void ohci1394_pci_remove(struct pci_dev *pdev);
#ifndef __LITTLE_ENDIAN
-static unsigned hdr_sizes[] =
-{
+const static size_t hdr_sizes[] = {
3, /* TCODE_WRITEQ */
4, /* TCODE_WRITEB */
3, /* TCODE_WRITE_RESPONSE */
- 0, /* ??? */
+ 0, /* reserved */
3, /* TCODE_READQ */
4, /* TCODE_READB */
3, /* TCODE_READQ_RESPONSE */
4, /* TCODE_READB_RESPONSE */
- 1, /* TCODE_CYCLE_START (???) */
+ 1, /* TCODE_CYCLE_START */
4, /* TCODE_LOCK_REQUEST */
2, /* TCODE_ISO_DATA */
4, /* TCODE_LOCK_RESPONSE */
+ /* rest is reserved or link-internal */
};
-/* Swap headers */
-static inline void packet_swab(quadlet_t *data, int tcode)
+static inline void header_le32_to_cpu(quadlet_t *data, unsigned char tcode)
{
- size_t size = hdr_sizes[tcode];
+ size_t size;
- if (tcode > TCODE_LOCK_RESPONSE || hdr_sizes[tcode] == 0)
+ if (unlikely(tcode >= ARRAY_SIZE(hdr_sizes)))
return;
+ size = hdr_sizes[tcode];
while (size--)
- data[size] = swab32(data[size]);
+ data[size] = le32_to_cpu(data[size]);
}
#else
-/* Don't waste cycles on same sex byte swaps */
-#define packet_swab(w,x)
+#define header_le32_to_cpu(w,x) do {} while (0)
#endif /* !LITTLE_ENDIAN */
/***********************************
@@ -701,7 +700,7 @@ static void insert_packet(struct ti_ohci *ohci,
d->prg_cpu[idx]->data[2] = packet->header[2];
d->prg_cpu[idx]->data[3] = packet->header[3];
}
- packet_swab(d->prg_cpu[idx]->data, packet->tcode);
+ header_le32_to_cpu(d->prg_cpu[idx]->data, packet->tcode);
}
if (packet->data_size) { /* block transmit */
@@ -777,7 +776,7 @@ static void insert_packet(struct ti_ohci *ohci,
d->prg_cpu[idx]->data[0] = packet->speed_code<<16 |
(packet->header[0] & 0xFFFF);
d->prg_cpu[idx]->data[1] = packet->header[0] & 0xFFFF0000;
- packet_swab(d->prg_cpu[idx]->data, packet->tcode);
+ header_le32_to_cpu(d->prg_cpu[idx]->data, packet->tcode);
d->prg_cpu[idx]->begin.control =
cpu_to_le32(DMA_CTL_OUTPUT_MORE |
@@ -2598,8 +2597,9 @@ static const int TCODE_SIZE[16] = {20, 0, 16, -1, 16, 20, 20, 0,
* Determine the length of a packet in the buffer
* Optimization suggested by Pascal Drolet <pascal.drolet@informission.ca>
*/
-static __inline__ int packet_length(struct dma_rcv_ctx *d, int idx, quadlet_t *buf_ptr,
- int offset, unsigned char tcode, int noswap)
+static inline int packet_length(struct dma_rcv_ctx *d, int idx,
+ quadlet_t *buf_ptr, int offset,
+ unsigned char tcode, int noswap)
{
int length = -1;
@@ -2730,7 +2730,7 @@ static void dma_rcv_tasklet (unsigned long data)
* bus reset. We always ignore it. */
if (tcode != OHCI1394_TCODE_PHY) {
if (!ohci->no_swap_incoming)
- packet_swab(d->spb, tcode);
+ header_le32_to_cpu(d->spb, tcode);
DBGMSG("Packet received from node"
" %d ack=0x%02X spd=%d tcode=0x%X"
" length=%d ctx=%d tlabel=%d",
@@ -2738,7 +2738,7 @@ static void dma_rcv_tasklet (unsigned long data)
(cond_le32_to_cpu(d->spb[length/4-1], ohci->no_swap_incoming)>>16)&0x1f,
(cond_le32_to_cpu(d->spb[length/4-1], ohci->no_swap_incoming)>>21)&0x3,
tcode, length, d->ctx,
- (cond_le32_to_cpu(d->spb[0], ohci->no_swap_incoming)>>10)&0x3f);
+ (d->spb[0]>>10)&0x3f);
ack = (((cond_le32_to_cpu(d->spb[length/4-1], ohci->no_swap_incoming)>>16)&0x1f)
== 0x11) ? 1 : 0;
@@ -3529,9 +3529,10 @@ static void ohci1394_pci_remove(struct pci_dev *pdev)
put_device(dev);
}
-
+#ifdef CONFIG_PM
static int ohci1394_pci_resume (struct pci_dev *pdev)
{
+/* PowerMac resume code comes first */
#ifdef CONFIG_PPC_PMAC
if (machine_is(powermac)) {
struct device_node *of_node;
@@ -3543,17 +3544,23 @@ static int ohci1394_pci_resume (struct pci_dev *pdev)
}
#endif /* CONFIG_PPC_PMAC */
+ pci_set_power_state(pdev, PCI_D0);
pci_restore_state(pdev);
- pci_enable_device(pdev);
-
- return 0;
+ return pci_enable_device(pdev);
}
-
static int ohci1394_pci_suspend (struct pci_dev *pdev, pm_message_t state)
{
- pci_save_state(pdev);
+ int err;
+
+ err = pci_save_state(pdev);
+ if (err)
+ goto out;
+ err = pci_set_power_state(pdev, pci_choose_state(pdev, state));
+ if (err)
+ goto out;
+/* PowerMac suspend code comes last */
#ifdef CONFIG_PPC_PMAC
if (machine_is(powermac)) {
struct device_node *of_node;
@@ -3563,11 +3570,11 @@ static int ohci1394_pci_suspend (struct pci_dev *pdev, pm_message_t state)
if (of_node)
pmac_call_feature(PMAC_FTR_1394_ENABLE, of_node, 0, 0);
}
-#endif
-
- return 0;
+#endif /* CONFIG_PPC_PMAC */
+out:
+ return err;
}
-
+#endif /* CONFIG_PM */
#define PCI_CLASS_FIREWIRE_OHCI ((PCI_CLASS_SERIAL_FIREWIRE << 8) | 0x10)
@@ -3590,8 +3597,10 @@ static struct pci_driver ohci1394_pci_driver = {
.id_table = ohci1394_pci_tbl,
.probe = ohci1394_pci_probe,
.remove = ohci1394_pci_remove,
+#ifdef CONFIG_PM
.resume = ohci1394_pci_resume,
.suspend = ohci1394_pci_suspend,
+#endif
};
/***********************************
@@ -3718,5 +3727,7 @@ static int __init ohci1394_init(void)
return pci_register_driver(&ohci1394_pci_driver);
}
-module_init(ohci1394_init);
+/* Register before most other device drivers.
+ * Useful for remote debugging via physical DMA, e.g. using firescope. */
+fs_initcall(ohci1394_init);
module_exit(ohci1394_cleanup);
diff --git a/drivers/ieee1394/raw1394-private.h b/drivers/ieee1394/raw1394-private.h
index c93587be9cab..c7731d1bcd89 100644
--- a/drivers/ieee1394/raw1394-private.h
+++ b/drivers/ieee1394/raw1394-private.h
@@ -29,9 +29,8 @@ struct file_info {
struct list_head req_pending;
struct list_head req_complete;
- struct semaphore complete_sem;
spinlock_t reqlists_lock;
- wait_queue_head_t poll_wait_complete;
+ wait_queue_head_t wait_complete;
struct list_head addr_list;
diff --git a/drivers/ieee1394/raw1394.c b/drivers/ieee1394/raw1394.c
index 571ea68c0cf2..5ec4f5eb6b19 100644
--- a/drivers/ieee1394/raw1394.c
+++ b/drivers/ieee1394/raw1394.c
@@ -44,14 +44,15 @@
#include <linux/compat.h>
#include "csr1212.h"
+#include "highlevel.h"
+#include "hosts.h"
#include "ieee1394.h"
-#include "ieee1394_types.h"
#include "ieee1394_core.h"
-#include "nodemgr.h"
-#include "hosts.h"
-#include "highlevel.h"
-#include "iso.h"
+#include "ieee1394_hotplug.h"
#include "ieee1394_transactions.h"
+#include "ieee1394_types.h"
+#include "iso.h"
+#include "nodemgr.h"
#include "raw1394.h"
#include "raw1394-private.h"
@@ -66,7 +67,7 @@
#define DBGMSG(fmt, args...) \
printk(KERN_INFO "raw1394:" fmt "\n" , ## args)
#else
-#define DBGMSG(fmt, args...)
+#define DBGMSG(fmt, args...) do {} while (0)
#endif
static LIST_HEAD(host_info_list);
@@ -132,10 +133,9 @@ static void free_pending_request(struct pending_request *req)
static void __queue_complete_req(struct pending_request *req)
{
struct file_info *fi = req->file_info;
- list_move_tail(&req->list, &fi->req_complete);
- up(&fi->complete_sem);
- wake_up_interruptible(&fi->poll_wait_complete);
+ list_move_tail(&req->list, &fi->req_complete);
+ wake_up(&fi->wait_complete);
}
static void queue_complete_req(struct pending_request *req)
@@ -463,13 +463,36 @@ raw1394_compat_read(const char __user *buf, struct raw1394_request *r)
#endif
+/* get next completed request (caller must hold fi->reqlists_lock) */
+static inline struct pending_request *__next_complete_req(struct file_info *fi)
+{
+ struct list_head *lh;
+ struct pending_request *req = NULL;
+
+ if (!list_empty(&fi->req_complete)) {
+ lh = fi->req_complete.next;
+ list_del(lh);
+ req = list_entry(lh, struct pending_request, list);
+ }
+ return req;
+}
+
+/* atomically get next completed request */
+static struct pending_request *next_complete_req(struct file_info *fi)
+{
+ unsigned long flags;
+ struct pending_request *req;
+
+ spin_lock_irqsave(&fi->reqlists_lock, flags);
+ req = __next_complete_req(fi);
+ spin_unlock_irqrestore(&fi->reqlists_lock, flags);
+ return req;
+}
static ssize_t raw1394_read(struct file *file, char __user * buffer,
size_t count, loff_t * offset_is_ignored)
{
- unsigned long flags;
struct file_info *fi = (struct file_info *)file->private_data;
- struct list_head *lh;
struct pending_request *req;
ssize_t ret;
@@ -487,22 +510,21 @@ static ssize_t raw1394_read(struct file *file, char __user * buffer,
}
if (file->f_flags & O_NONBLOCK) {
- if (down_trylock(&fi->complete_sem)) {
+ if (!(req = next_complete_req(fi)))
return -EAGAIN;
- }
} else {
- if (down_interruptible(&fi->complete_sem)) {
+ /*
+ * NB: We call the macro wait_event_interruptible() with a
+ * condition argument with side effect. This is only possible
+ * because the side effect does not occur until the condition
+ * became true, and wait_event_interruptible() won't evaluate
+ * the condition again after that.
+ */
+ if (wait_event_interruptible(fi->wait_complete,
+ (req = next_complete_req(fi))))
return -ERESTARTSYS;
- }
}
- spin_lock_irqsave(&fi->reqlists_lock, flags);
- lh = fi->req_complete.next;
- list_del(lh);
- spin_unlock_irqrestore(&fi->reqlists_lock, flags);
-
- req = list_entry(lh, struct pending_request, list);
-
if (req->req.length) {
if (copy_to_user(int2ptr(req->req.recvb), req->data,
req->req.length)) {
@@ -1752,6 +1774,7 @@ static int arm_register(struct file_info *fi, struct pending_request *req)
addr->notification_options |= addr->client_transactions;
addr->recvb = req->req.recvb;
addr->rec_length = (u16) ((req->req.misc >> 16) & 0xFFFF);
+
spin_lock_irqsave(&host_info_lock, flags);
hi = find_host_info(fi->host);
same_host = 0;
@@ -1777,9 +1800,9 @@ static int arm_register(struct file_info *fi, struct pending_request *req)
}
if (same_host) {
/* addressrange occupied by same host */
+ spin_unlock_irqrestore(&host_info_lock, flags);
vfree(addr->addr_space_buffer);
kfree(addr);
- spin_unlock_irqrestore(&host_info_lock, flags);
return (-EALREADY);
}
/* another host with valid address-entry containing same addressrange */
@@ -1807,6 +1830,8 @@ static int arm_register(struct file_info *fi, struct pending_request *req)
}
}
}
+ spin_unlock_irqrestore(&host_info_lock, flags);
+
if (another_host) {
DBGMSG("another hosts entry is valid -> SUCCESS");
if (copy_to_user(int2ptr(req->req.recvb),
@@ -1815,11 +1840,11 @@ static int arm_register(struct file_info *fi, struct pending_request *req)
" address-range-entry is invalid -> EFAULT !!!\n");
vfree(addr->addr_space_buffer);
kfree(addr);
- spin_unlock_irqrestore(&host_info_lock, flags);
return (-EFAULT);
}
free_pending_request(req); /* immediate success or fail */
/* INSERT ENTRY */
+ spin_lock_irqsave(&host_info_lock, flags);
list_add_tail(&addr->addr_list, &fi->addr_list);
spin_unlock_irqrestore(&host_info_lock, flags);
return sizeof(struct raw1394_request);
@@ -1830,15 +1855,15 @@ static int arm_register(struct file_info *fi, struct pending_request *req)
req->req.address + req->req.length);
if (retval) {
/* INSERT ENTRY */
+ spin_lock_irqsave(&host_info_lock, flags);
list_add_tail(&addr->addr_list, &fi->addr_list);
+ spin_unlock_irqrestore(&host_info_lock, flags);
} else {
DBGMSG("arm_register failed errno: %d \n", retval);
vfree(addr->addr_space_buffer);
kfree(addr);
- spin_unlock_irqrestore(&host_info_lock, flags);
return (-EALREADY);
}
- spin_unlock_irqrestore(&host_info_lock, flags);
free_pending_request(req); /* immediate success or fail */
return sizeof(struct raw1394_request);
}
@@ -1904,10 +1929,10 @@ static int arm_unregister(struct file_info *fi, struct pending_request *req)
if (another_host) {
DBGMSG("delete entry from list -> success");
list_del(&addr->addr_list);
+ spin_unlock_irqrestore(&host_info_lock, flags);
vfree(addr->addr_space_buffer);
kfree(addr);
free_pending_request(req); /* immediate success or fail */
- spin_unlock_irqrestore(&host_info_lock, flags);
return sizeof(struct raw1394_request);
}
retval =
@@ -1949,23 +1974,19 @@ static int arm_get_buf(struct file_info *fi, struct pending_request *req)
(arm_addr->end > req->req.address)) {
if (req->req.address + req->req.length <= arm_addr->end) {
offset = req->req.address - arm_addr->start;
+ spin_unlock_irqrestore(&host_info_lock, flags);
DBGMSG
("arm_get_buf copy_to_user( %08X, %p, %u )",
(u32) req->req.recvb,
arm_addr->addr_space_buffer + offset,
(u32) req->req.length);
-
if (copy_to_user
(int2ptr(req->req.recvb),
arm_addr->addr_space_buffer + offset,
- req->req.length)) {
- spin_unlock_irqrestore(&host_info_lock,
- flags);
+ req->req.length))
return (-EFAULT);
- }
- spin_unlock_irqrestore(&host_info_lock, flags);
/* We have to free the request, because we
* queue no response, and therefore nobody
* will free it. */
@@ -2005,24 +2026,23 @@ static int arm_set_buf(struct file_info *fi, struct pending_request *req)
(arm_addr->end > req->req.address)) {
if (req->req.address + req->req.length <= arm_addr->end) {
offset = req->req.address - arm_addr->start;
+ spin_unlock_irqrestore(&host_info_lock, flags);
DBGMSG
("arm_set_buf copy_from_user( %p, %08X, %u )",
arm_addr->addr_space_buffer + offset,
(u32) req->req.sendb,
(u32) req->req.length);
-
if (copy_from_user
(arm_addr->addr_space_buffer + offset,
int2ptr(req->req.sendb),
- req->req.length)) {
- spin_unlock_irqrestore(&host_info_lock,
- flags);
+ req->req.length))
return (-EFAULT);
- }
- spin_unlock_irqrestore(&host_info_lock, flags);
- free_pending_request(req); /* we have to free the request, because we queue no response, and therefore nobody will free it */
+ /* We have to free the request, because we
+ * queue no response, and therefore nobody
+ * will free it. */
+ free_pending_request(req);
return sizeof(struct raw1394_request);
} else {
DBGMSG("arm_set_buf request exceeded mapping");
@@ -2744,7 +2764,7 @@ static unsigned int raw1394_poll(struct file *file, poll_table * pt)
unsigned int mask = POLLOUT | POLLWRNORM;
unsigned long flags;
- poll_wait(file, &fi->poll_wait_complete, pt);
+ poll_wait(file, &fi->wait_complete, pt);
spin_lock_irqsave(&fi->reqlists_lock, flags);
if (!list_empty(&fi->req_complete)) {
@@ -2769,9 +2789,8 @@ static int raw1394_open(struct inode *inode, struct file *file)
fi->state = opened;
INIT_LIST_HEAD(&fi->req_pending);
INIT_LIST_HEAD(&fi->req_complete);
- sema_init(&fi->complete_sem, 0);
spin_lock_init(&fi->reqlists_lock);
- init_waitqueue_head(&fi->poll_wait_complete);
+ init_waitqueue_head(&fi->wait_complete);
INIT_LIST_HEAD(&fi->addr_list);
file->private_data = fi;
@@ -2784,7 +2803,7 @@ static int raw1394_release(struct inode *inode, struct file *file)
struct file_info *fi = file->private_data;
struct list_head *lh;
struct pending_request *req;
- int done = 0, i, fail = 0;
+ int i, fail;
int retval = 0;
struct list_head *entry;
struct arm_addr *addr = NULL;
@@ -2864,25 +2883,28 @@ static int raw1394_release(struct inode *inode, struct file *file)
"error(s) occurred \n");
}
- while (!done) {
+ for (;;) {
+ /* This locked section guarantees that neither
+ * complete nor pending requests exist once i!=0 */
spin_lock_irqsave(&fi->reqlists_lock, flags);
-
- while (!list_empty(&fi->req_complete)) {
- lh = fi->req_complete.next;
- list_del(lh);
-
- req = list_entry(lh, struct pending_request, list);
-
+ while ((req = __next_complete_req(fi)))
free_pending_request(req);
- }
-
- if (list_empty(&fi->req_pending))
- done = 1;
+ i = list_empty(&fi->req_pending);
spin_unlock_irqrestore(&fi->reqlists_lock, flags);
- if (!done)
- down_interruptible(&fi->complete_sem);
+ if (i)
+ break;
+ /*
+ * Sleep until more requests can be freed.
+ *
+ * NB: We call the macro wait_event() with a condition argument
+ * with side effect. This is only possible because the side
+ * effect does not occur until the condition became true, and
+ * wait_event() won't evaluate the condition again after that.
+ */
+ wait_event(fi->wait_complete, (req = next_complete_req(fi)));
+ free_pending_request(req);
}
/* Remove any sub-trees left by user space programs */
diff --git a/drivers/ieee1394/sbp2.c b/drivers/ieee1394/sbp2.c
index b08755e2e68f..6986ac188281 100644
--- a/drivers/ieee1394/sbp2.c
+++ b/drivers/ieee1394/sbp2.c
@@ -38,31 +38,36 @@
* but the code needs additional debugging.
*/
+#include <linux/blkdev.h>
+#include <linux/compiler.h>
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/dma-mapping.h>
+#include <linux/gfp.h>
+#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/list.h>
-#include <linux/string.h>
-#include <linux/stringify.h>
-#include <linux/slab.h>
-#include <linux/interrupt.h>
-#include <linux/fs.h>
-#include <linux/poll.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
-#include <linux/types.h>
-#include <linux/delay.h>
-#include <linux/sched.h>
-#include <linux/blkdev.h>
-#include <linux/smp_lock.h>
-#include <linux/init.h>
#include <linux/pci.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+#include <linux/stat.h>
+#include <linux/string.h>
+#include <linux/stringify.h>
+#include <linux/types.h>
+#include <linux/wait.h>
-#include <asm/current.h>
-#include <asm/uaccess.h>
-#include <asm/io.h>
#include <asm/byteorder.h>
-#include <asm/atomic.h>
-#include <asm/system.h>
+#include <asm/errno.h>
+#include <asm/param.h>
#include <asm/scatterlist.h>
+#include <asm/system.h>
+#include <asm/types.h>
+
+#ifdef CONFIG_IEEE1394_SBP2_PHYS_DMA
+#include <asm/io.h> /* for bus_to_virt */
+#endif
#include <scsi/scsi.h>
#include <scsi/scsi_cmnd.h>
@@ -71,13 +76,14 @@
#include <scsi/scsi_host.h>
#include "csr1212.h"
+#include "highlevel.h"
+#include "hosts.h"
#include "ieee1394.h"
-#include "ieee1394_types.h"
#include "ieee1394_core.h"
-#include "nodemgr.h"
-#include "hosts.h"
-#include "highlevel.h"
+#include "ieee1394_hotplug.h"
#include "ieee1394_transactions.h"
+#include "ieee1394_types.h"
+#include "nodemgr.h"
#include "sbp2.h"
/*
@@ -173,11 +179,6 @@ MODULE_PARM_DESC(workarounds, "Work around device bugs (default = 0"
", override internal blacklist = " __stringify(SBP2_WORKAROUND_OVERRIDE)
", or a combination)");
-/* legacy parameter */
-static int force_inquiry_hack;
-module_param(force_inquiry_hack, int, 0644);
-MODULE_PARM_DESC(force_inquiry_hack, "Deprecated, use 'workarounds'");
-
/*
* Export information about protocols/devices supported by this driver.
*/
@@ -208,9 +209,9 @@ static u32 global_outstanding_command_orbs = 0;
#define outstanding_orb_incr global_outstanding_command_orbs++
#define outstanding_orb_decr global_outstanding_command_orbs--
#else
-#define SBP2_ORB_DEBUG(fmt, args...)
-#define outstanding_orb_incr
-#define outstanding_orb_decr
+#define SBP2_ORB_DEBUG(fmt, args...) do {} while (0)
+#define outstanding_orb_incr do {} while (0)
+#define outstanding_orb_decr do {} while (0)
#endif
#ifdef CONFIG_IEEE1394_SBP2_DEBUG_DMA
@@ -222,8 +223,8 @@ static u32 global_outstanding_command_orbs = 0;
--global_outstanding_dmas, ## args)
static u32 global_outstanding_dmas = 0;
#else
-#define SBP2_DMA_ALLOC(fmt, args...)
-#define SBP2_DMA_FREE(fmt, args...)
+#define SBP2_DMA_ALLOC(fmt, args...) do {} while (0)
+#define SBP2_DMA_FREE(fmt, args...) do {} while (0)
#endif
#if CONFIG_IEEE1394_SBP2_DEBUG >= 2
@@ -237,7 +238,7 @@ static u32 global_outstanding_dmas = 0;
#define SBP2_NOTICE(fmt, args...) HPSB_NOTICE("sbp2: "fmt, ## args)
#define SBP2_WARN(fmt, args...) HPSB_WARN("sbp2: "fmt, ## args)
#else
-#define SBP2_DEBUG(fmt, args...)
+#define SBP2_DEBUG(fmt, args...) do {} while (0)
#define SBP2_INFO(fmt, args...) HPSB_INFO("sbp2: "fmt, ## args)
#define SBP2_NOTICE(fmt, args...) HPSB_NOTICE("sbp2: "fmt, ## args)
#define SBP2_WARN(fmt, args...) HPSB_WARN("sbp2: "fmt, ## args)
@@ -356,7 +357,7 @@ static const struct {
/*
* Converts a buffer from be32 to cpu byte ordering. Length is in bytes.
*/
-static __inline__ void sbp2util_be32_to_cpu_buffer(void *buffer, int length)
+static inline void sbp2util_be32_to_cpu_buffer(void *buffer, int length)
{
u32 *temp = buffer;
@@ -369,7 +370,7 @@ static __inline__ void sbp2util_be32_to_cpu_buffer(void *buffer, int length)
/*
* Converts a buffer from cpu to be32 byte ordering. Length is in bytes.
*/
-static __inline__ void sbp2util_cpu_to_be32_buffer(void *buffer, int length)
+static inline void sbp2util_cpu_to_be32_buffer(void *buffer, int length)
{
u32 *temp = buffer;
@@ -380,8 +381,8 @@ static __inline__ void sbp2util_cpu_to_be32_buffer(void *buffer, int length)
}
#else /* BIG_ENDIAN */
/* Why waste the cpu cycles? */
-#define sbp2util_be32_to_cpu_buffer(x,y)
-#define sbp2util_cpu_to_be32_buffer(x,y)
+#define sbp2util_be32_to_cpu_buffer(x,y) do {} while (0)
+#define sbp2util_cpu_to_be32_buffer(x,y) do {} while (0)
#endif
#ifdef CONFIG_IEEE1394_SBP2_PACKET_DUMP
@@ -417,24 +418,26 @@ static void sbp2util_packet_dump(void *buffer, int length, char *dump_name,
return;
}
#else
-#define sbp2util_packet_dump(w,x,y,z)
+#define sbp2util_packet_dump(w,x,y,z) do {} while (0)
#endif
+static DECLARE_WAIT_QUEUE_HEAD(access_wq);
+
/*
- * Goofy routine that basically does a down_timeout function.
+ * Waits for completion of an SBP-2 access request.
+ * Returns nonzero if timed out or prematurely interrupted.
*/
-static int sbp2util_down_timeout(atomic_t *done, int timeout)
+static int sbp2util_access_timeout(struct scsi_id_instance_data *scsi_id,
+ int timeout)
{
- int i;
+ long leftover = wait_event_interruptible_timeout(
+ access_wq, scsi_id->access_complete, timeout);
- for (i = timeout; (i > 0 && atomic_read(done) == 0); i-= HZ/10) {
- if (msleep_interruptible(100)) /* 100ms */
- return 1;
- }
- return (i > 0) ? 0 : 1;
+ scsi_id->access_complete = 0;
+ return leftover <= 0;
}
-/* Free's an allocated packet */
+/* Frees an allocated packet */
static void sbp2_free_packet(struct hpsb_packet *packet)
{
hpsb_free_tlabel(packet);
@@ -468,6 +471,44 @@ static int sbp2util_node_write_no_wait(struct node_entry *ne, u64 addr,
return 0;
}
+static void sbp2util_notify_fetch_agent(struct scsi_id_instance_data *scsi_id,
+ u64 offset, quadlet_t *data, size_t len)
+{
+ /*
+ * There is a small window after a bus reset within which the node
+ * entry's generation is current but the reconnect wasn't completed.
+ */
+ if (unlikely(atomic_read(&scsi_id->state) == SBP2LU_STATE_IN_RESET))
+ return;
+
+ if (hpsb_node_write(scsi_id->ne,
+ scsi_id->sbp2_command_block_agent_addr + offset,
+ data, len))
+ SBP2_ERR("sbp2util_notify_fetch_agent failed.");
+ /*
+ * Now accept new SCSI commands, unless a bus reset happended during
+ * hpsb_node_write.
+ */
+ if (likely(atomic_read(&scsi_id->state) != SBP2LU_STATE_IN_RESET))
+ scsi_unblock_requests(scsi_id->scsi_host);
+}
+
+static void sbp2util_write_orb_pointer(void *p)
+{
+ quadlet_t data[2];
+
+ data[0] = ORB_SET_NODE_ID(
+ ((struct scsi_id_instance_data *)p)->hi->host->node_id);
+ data[1] = ((struct scsi_id_instance_data *)p)->last_orb_dma;
+ sbp2util_cpu_to_be32_buffer(data, 8);
+ sbp2util_notify_fetch_agent(p, SBP2_ORB_POINTER_OFFSET, data, 8);
+}
+
+static void sbp2util_write_doorbell(void *p)
+{
+ sbp2util_notify_fetch_agent(p, SBP2_DOORBELL_OFFSET, NULL, 4);
+}
+
/*
* This function is called to create a pool of command orbs used for
* command processing. It is called when a new sbp2 device is detected.
@@ -492,7 +533,7 @@ static int sbp2util_create_command_orb_pool(struct scsi_id_instance_data *scsi_i
command->command_orb_dma =
pci_map_single(hi->host->pdev, &command->command_orb,
sizeof(struct sbp2_command_orb),
- PCI_DMA_BIDIRECTIONAL);
+ PCI_DMA_TODEVICE);
SBP2_DMA_ALLOC("single command orb DMA");
command->sge_dma =
pci_map_single(hi->host->pdev,
@@ -525,7 +566,7 @@ static void sbp2util_remove_command_orb_pool(struct scsi_id_instance_data *scsi_
/* Release our generic DMA's */
pci_unmap_single(host->pdev, command->command_orb_dma,
sizeof(struct sbp2_command_orb),
- PCI_DMA_BIDIRECTIONAL);
+ PCI_DMA_TODEVICE);
SBP2_DMA_FREE("single command orb DMA");
pci_unmap_single(host->pdev, command->sge_dma,
sizeof(command->scatter_gather_element),
@@ -715,6 +756,7 @@ static int sbp2_remove(struct device *dev)
sbp2scsi_complete_all_commands(scsi_id, DID_NO_CONNECT);
/* scsi_remove_device() will trigger shutdown functions of SCSI
* highlevel drivers which would deadlock if blocked. */
+ atomic_set(&scsi_id->state, SBP2LU_STATE_IN_SHUTDOWN);
scsi_unblock_requests(scsi_id->scsi_host);
}
sdev = scsi_id->sdev;
@@ -766,10 +808,12 @@ static int sbp2_update(struct unit_directory *ud)
*/
sbp2scsi_complete_all_commands(scsi_id, DID_BUS_BUSY);
- /* Make sure we unblock requests (since this is likely after a bus
- * reset). */
- scsi_unblock_requests(scsi_id->scsi_host);
-
+ /* Accept new commands unless there was another bus reset in the
+ * meantime. */
+ if (hpsb_node_entry_valid(scsi_id->ne)) {
+ atomic_set(&scsi_id->state, SBP2LU_STATE_RUNNING);
+ scsi_unblock_requests(scsi_id->scsi_host);
+ }
return 0;
}
@@ -794,11 +838,12 @@ static struct scsi_id_instance_data *sbp2_alloc_device(struct unit_directory *ud
scsi_id->speed_code = IEEE1394_SPEED_100;
scsi_id->max_payload_size = sbp2_speedto_max_payload[IEEE1394_SPEED_100];
scsi_id->status_fifo_addr = CSR1212_INVALID_ADDR_SPACE;
- atomic_set(&scsi_id->sbp2_login_complete, 0);
INIT_LIST_HEAD(&scsi_id->sbp2_command_orb_inuse);
INIT_LIST_HEAD(&scsi_id->sbp2_command_orb_completed);
INIT_LIST_HEAD(&scsi_id->scsi_list);
spin_lock_init(&scsi_id->sbp2_command_orb_lock);
+ atomic_set(&scsi_id->state, SBP2LU_STATE_RUNNING);
+ INIT_WORK(&scsi_id->protocol_work, NULL, NULL);
ud->device.driver_data = scsi_id;
@@ -881,11 +926,14 @@ static void sbp2_host_reset(struct hpsb_host *host)
struct scsi_id_instance_data *scsi_id;
hi = hpsb_get_hostinfo(&sbp2_highlevel, host);
-
- if (hi) {
- list_for_each_entry(scsi_id, &hi->scsi_ids, scsi_list)
+ if (!hi)
+ return;
+ list_for_each_entry(scsi_id, &hi->scsi_ids, scsi_list)
+ if (likely(atomic_read(&scsi_id->state) !=
+ SBP2LU_STATE_IN_SHUTDOWN)) {
+ atomic_set(&scsi_id->state, SBP2LU_STATE_IN_RESET);
scsi_block_requests(scsi_id->scsi_host);
- }
+ }
}
/*
@@ -970,8 +1018,7 @@ static int sbp2_start_device(struct scsi_id_instance_data *scsi_id)
* connected to the sbp2 device being removed. That host would
* have a certain amount of time to relogin before the sbp2 device
* allows someone else to login instead. One second makes sense. */
- msleep_interruptible(1000);
- if (signal_pending(current)) {
+ if (msleep_interruptible(1000)) {
sbp2_remove_device(scsi_id);
return -EINTR;
}
@@ -1036,7 +1083,7 @@ static void sbp2_remove_device(struct scsi_id_instance_data *scsi_id)
scsi_remove_host(scsi_id->scsi_host);
scsi_host_put(scsi_id->scsi_host);
}
-
+ flush_scheduled_work();
sbp2util_remove_command_orb_pool(scsi_id);
list_del(&scsi_id->scsi_list);
@@ -1182,17 +1229,14 @@ static int sbp2_query_logins(struct scsi_id_instance_data *scsi_id)
"sbp2 query logins orb", scsi_id->query_logins_orb_dma);
memset(scsi_id->query_logins_response, 0, sizeof(struct sbp2_query_logins_response));
- memset(&scsi_id->status_block, 0, sizeof(struct sbp2_status_block));
data[0] = ORB_SET_NODE_ID(hi->host->node_id);
data[1] = scsi_id->query_logins_orb_dma;
sbp2util_cpu_to_be32_buffer(data, 8);
- atomic_set(&scsi_id->sbp2_login_complete, 0);
-
hpsb_node_write(scsi_id->ne, scsi_id->sbp2_management_agent_addr, data, 8);
- if (sbp2util_down_timeout(&scsi_id->sbp2_login_complete, 2*HZ)) {
+ if (sbp2util_access_timeout(scsi_id, 2*HZ)) {
SBP2_INFO("Error querying logins to SBP-2 device - timed out");
return -EIO;
}
@@ -1202,11 +1246,8 @@ static int sbp2_query_logins(struct scsi_id_instance_data *scsi_id)
return -EIO;
}
- if (STATUS_GET_RESP(scsi_id->status_block.ORB_offset_hi_misc) ||
- STATUS_GET_DEAD_BIT(scsi_id->status_block.ORB_offset_hi_misc) ||
- STATUS_GET_SBP_STATUS(scsi_id->status_block.ORB_offset_hi_misc)) {
-
- SBP2_INFO("Error querying logins to SBP-2 device - timed out");
+ if (STATUS_TEST_RDS(scsi_id->status_block.ORB_offset_hi_misc)) {
+ SBP2_INFO("Error querying logins to SBP-2 device - failed");
return -EIO;
}
@@ -1278,21 +1319,18 @@ static int sbp2_login_device(struct scsi_id_instance_data *scsi_id)
"sbp2 login orb", scsi_id->login_orb_dma);
memset(scsi_id->login_response, 0, sizeof(struct sbp2_login_response));
- memset(&scsi_id->status_block, 0, sizeof(struct sbp2_status_block));
data[0] = ORB_SET_NODE_ID(hi->host->node_id);
data[1] = scsi_id->login_orb_dma;
sbp2util_cpu_to_be32_buffer(data, 8);
- atomic_set(&scsi_id->sbp2_login_complete, 0);
-
hpsb_node_write(scsi_id->ne, scsi_id->sbp2_management_agent_addr, data, 8);
/*
* Wait for login status (up to 20 seconds)...
*/
- if (sbp2util_down_timeout(&scsi_id->sbp2_login_complete, 20*HZ)) {
- SBP2_ERR("Error logging into SBP-2 device - login timed-out");
+ if (sbp2util_access_timeout(scsi_id, 20*HZ)) {
+ SBP2_ERR("Error logging into SBP-2 device - timed out");
return -EIO;
}
@@ -1300,18 +1338,12 @@ static int sbp2_login_device(struct scsi_id_instance_data *scsi_id)
* Sanity. Make sure status returned matches login orb.
*/
if (scsi_id->status_block.ORB_offset_lo != scsi_id->login_orb_dma) {
- SBP2_ERR("Error logging into SBP-2 device - login timed-out");
+ SBP2_ERR("Error logging into SBP-2 device - timed out");
return -EIO;
}
- /*
- * Check status
- */
- if (STATUS_GET_RESP(scsi_id->status_block.ORB_offset_hi_misc) ||
- STATUS_GET_DEAD_BIT(scsi_id->status_block.ORB_offset_hi_misc) ||
- STATUS_GET_SBP_STATUS(scsi_id->status_block.ORB_offset_hi_misc)) {
-
- SBP2_ERR("Error logging into SBP-2 device - login failed");
+ if (STATUS_TEST_RDS(scsi_id->status_block.ORB_offset_hi_misc)) {
+ SBP2_ERR("Error logging into SBP-2 device - failed");
return -EIO;
}
@@ -1335,9 +1367,7 @@ static int sbp2_login_device(struct scsi_id_instance_data *scsi_id)
scsi_id->sbp2_command_block_agent_addr &= 0x0000ffffffffffffULL;
SBP2_INFO("Logged into SBP-2 device");
-
return 0;
-
}
/*
@@ -1387,21 +1417,17 @@ static int sbp2_logout_device(struct scsi_id_instance_data *scsi_id)
data[1] = scsi_id->logout_orb_dma;
sbp2util_cpu_to_be32_buffer(data, 8);
- atomic_set(&scsi_id->sbp2_login_complete, 0);
-
error = hpsb_node_write(scsi_id->ne,
scsi_id->sbp2_management_agent_addr, data, 8);
if (error)
return error;
/* Wait for device to logout...1 second. */
- if (sbp2util_down_timeout(&scsi_id->sbp2_login_complete, HZ))
+ if (sbp2util_access_timeout(scsi_id, HZ))
return -EIO;
SBP2_INFO("Logged out of SBP-2 device");
-
return 0;
-
}
/*
@@ -1445,20 +1471,10 @@ static int sbp2_reconnect_device(struct scsi_id_instance_data *scsi_id)
sbp2util_packet_dump(scsi_id->reconnect_orb, sizeof(struct sbp2_reconnect_orb),
"sbp2 reconnect orb", scsi_id->reconnect_orb_dma);
- /*
- * Initialize status fifo
- */
- memset(&scsi_id->status_block, 0, sizeof(struct sbp2_status_block));
-
- /*
- * Ok, let's write to the target's management agent register
- */
data[0] = ORB_SET_NODE_ID(hi->host->node_id);
data[1] = scsi_id->reconnect_orb_dma;
sbp2util_cpu_to_be32_buffer(data, 8);
- atomic_set(&scsi_id->sbp2_login_complete, 0);
-
error = hpsb_node_write(scsi_id->ne,
scsi_id->sbp2_management_agent_addr, data, 8);
if (error)
@@ -1467,8 +1483,8 @@ static int sbp2_reconnect_device(struct scsi_id_instance_data *scsi_id)
/*
* Wait for reconnect status (up to 1 second)...
*/
- if (sbp2util_down_timeout(&scsi_id->sbp2_login_complete, HZ)) {
- SBP2_ERR("Error reconnecting to SBP-2 device - reconnect timed-out");
+ if (sbp2util_access_timeout(scsi_id, HZ)) {
+ SBP2_ERR("Error reconnecting to SBP-2 device - timed out");
return -EIO;
}
@@ -1476,25 +1492,17 @@ static int sbp2_reconnect_device(struct scsi_id_instance_data *scsi_id)
* Sanity. Make sure status returned matches reconnect orb.
*/
if (scsi_id->status_block.ORB_offset_lo != scsi_id->reconnect_orb_dma) {
- SBP2_ERR("Error reconnecting to SBP-2 device - reconnect timed-out");
+ SBP2_ERR("Error reconnecting to SBP-2 device - timed out");
return -EIO;
}
- /*
- * Check status
- */
- if (STATUS_GET_RESP(scsi_id->status_block.ORB_offset_hi_misc) ||
- STATUS_GET_DEAD_BIT(scsi_id->status_block.ORB_offset_hi_misc) ||
- STATUS_GET_SBP_STATUS(scsi_id->status_block.ORB_offset_hi_misc)) {
-
- SBP2_ERR("Error reconnecting to SBP-2 device - reconnect failed");
+ if (STATUS_TEST_RDS(scsi_id->status_block.ORB_offset_hi_misc)) {
+ SBP2_ERR("Error reconnecting to SBP-2 device - failed");
return -EIO;
}
HPSB_DEBUG("Reconnected to SBP-2 device");
-
return 0;
-
}
/*
@@ -1592,11 +1600,6 @@ static void sbp2_parse_unit_directory(struct scsi_id_instance_data *scsi_id,
}
workarounds = sbp2_default_workarounds;
- if (force_inquiry_hack) {
- SBP2_WARN("force_inquiry_hack is deprecated. "
- "Use parameter 'workarounds' instead.");
- workarounds |= SBP2_WORKAROUND_INQUIRY_36;
- }
if (!(workarounds & SBP2_WORKAROUND_OVERRIDE))
for (i = 0; i < ARRAY_SIZE(sbp2_workarounds_table); i++) {
@@ -1705,9 +1708,14 @@ static int sbp2_agent_reset(struct scsi_id_instance_data *scsi_id, int wait)
quadlet_t data;
u64 addr;
int retval;
+ unsigned long flags;
SBP2_DEBUG_ENTER();
+ cancel_delayed_work(&scsi_id->protocol_work);
+ if (wait)
+ flush_scheduled_work();
+
data = ntohl(SBP2_AGENT_RESET_DATA);
addr = scsi_id->sbp2_command_block_agent_addr + SBP2_AGENT_RESET_OFFSET;
@@ -1724,7 +1732,9 @@ static int sbp2_agent_reset(struct scsi_id_instance_data *scsi_id, int wait)
/*
* Need to make sure orb pointer is written on next command
*/
+ spin_lock_irqsave(&scsi_id->sbp2_command_orb_lock, flags);
scsi_id->last_orb = NULL;
+ spin_unlock_irqrestore(&scsi_id->sbp2_command_orb_lock, flags);
return 0;
}
@@ -1961,13 +1971,17 @@ static void sbp2_create_command_orb(struct scsi_id_instance_data *scsi_id,
/*
* This function is called in order to begin a regular SBP-2 command.
*/
-static int sbp2_link_orb_command(struct scsi_id_instance_data *scsi_id,
+static void sbp2_link_orb_command(struct scsi_id_instance_data *scsi_id,
struct sbp2_command_info *command)
{
struct sbp2scsi_host_info *hi = scsi_id->hi;
struct sbp2_command_orb *command_orb = &command->command_orb;
- struct node_entry *ne = scsi_id->ne;
- u64 addr;
+ struct sbp2_command_orb *last_orb;
+ dma_addr_t last_orb_dma;
+ u64 addr = scsi_id->sbp2_command_block_agent_addr;
+ quadlet_t data[2];
+ size_t length;
+ unsigned long flags;
outstanding_orb_incr;
SBP2_ORB_DEBUG("sending command orb %p, total orbs = %x",
@@ -1975,73 +1989,70 @@ static int sbp2_link_orb_command(struct scsi_id_instance_data *scsi_id,
pci_dma_sync_single_for_device(hi->host->pdev, command->command_orb_dma,
sizeof(struct sbp2_command_orb),
- PCI_DMA_BIDIRECTIONAL);
+ PCI_DMA_TODEVICE);
pci_dma_sync_single_for_device(hi->host->pdev, command->sge_dma,
sizeof(command->scatter_gather_element),
PCI_DMA_BIDIRECTIONAL);
/*
* Check to see if there are any previous orbs to use
*/
- if (scsi_id->last_orb == NULL) {
- quadlet_t data[2];
-
+ spin_lock_irqsave(&scsi_id->sbp2_command_orb_lock, flags);
+ last_orb = scsi_id->last_orb;
+ last_orb_dma = scsi_id->last_orb_dma;
+ if (!last_orb) {
/*
- * Ok, let's write to the target's management agent register
+ * last_orb == NULL means: We know that the target's fetch agent
+ * is not active right now.
*/
- addr = scsi_id->sbp2_command_block_agent_addr + SBP2_ORB_POINTER_OFFSET;
+ addr += SBP2_ORB_POINTER_OFFSET;
data[0] = ORB_SET_NODE_ID(hi->host->node_id);
data[1] = command->command_orb_dma;
sbp2util_cpu_to_be32_buffer(data, 8);
-
- SBP2_ORB_DEBUG("write command agent, command orb %p", command_orb);
-
- if (sbp2util_node_write_no_wait(ne, addr, data, 8) < 0) {
- SBP2_ERR("sbp2util_node_write_no_wait failed.\n");
- return -EIO;
- }
-
- SBP2_ORB_DEBUG("write command agent complete");
-
- scsi_id->last_orb = command_orb;
- scsi_id->last_orb_dma = command->command_orb_dma;
-
+ length = 8;
} else {
- quadlet_t data;
-
/*
- * We have an orb already sent (maybe or maybe not
- * processed) that we can append this orb to. So do so,
- * and ring the doorbell. Have to be very careful
- * modifying these next orb pointers, as they are accessed
- * both by the sbp2 device and us.
+ * last_orb != NULL means: We know that the target's fetch agent
+ * is (very probably) not dead or in reset state right now.
+ * We have an ORB already sent that we can append a new one to.
+ * The target's fetch agent may or may not have read this
+ * previous ORB yet.
*/
- scsi_id->last_orb->next_ORB_lo =
- cpu_to_be32(command->command_orb_dma);
+ pci_dma_sync_single_for_cpu(hi->host->pdev, last_orb_dma,
+ sizeof(struct sbp2_command_orb),
+ PCI_DMA_TODEVICE);
+ last_orb->next_ORB_lo = cpu_to_be32(command->command_orb_dma);
+ wmb();
/* Tells hardware that this pointer is valid */
- scsi_id->last_orb->next_ORB_hi = 0x0;
- pci_dma_sync_single_for_device(hi->host->pdev,
- scsi_id->last_orb_dma,
+ last_orb->next_ORB_hi = 0;
+ pci_dma_sync_single_for_device(hi->host->pdev, last_orb_dma,
sizeof(struct sbp2_command_orb),
- PCI_DMA_BIDIRECTIONAL);
+ PCI_DMA_TODEVICE);
+ addr += SBP2_DOORBELL_OFFSET;
+ data[0] = 0;
+ length = 4;
+ }
+ scsi_id->last_orb = command_orb;
+ scsi_id->last_orb_dma = command->command_orb_dma;
+ spin_unlock_irqrestore(&scsi_id->sbp2_command_orb_lock, flags);
+ SBP2_ORB_DEBUG("write to %s register, command orb %p",
+ last_orb ? "DOORBELL" : "ORB_POINTER", command_orb);
+ if (sbp2util_node_write_no_wait(scsi_id->ne, addr, data, length)) {
/*
- * Ring the doorbell
+ * sbp2util_node_write_no_wait failed. We certainly ran out
+ * of transaction labels, perhaps just because there were no
+ * context switches which gave khpsbpkt a chance to collect
+ * free tlabels. Try again in non-atomic context. If necessary,
+ * the workqueue job will sleep to guaranteedly get a tlabel.
+ * We do not accept new commands until the job is over.
*/
- data = cpu_to_be32(command->command_orb_dma);
- addr = scsi_id->sbp2_command_block_agent_addr + SBP2_DOORBELL_OFFSET;
-
- SBP2_ORB_DEBUG("ring doorbell, command orb %p", command_orb);
-
- if (sbp2util_node_write_no_wait(ne, addr, &data, 4) < 0) {
- SBP2_ERR("sbp2util_node_write_no_wait failed");
- return -EIO;
- }
-
- scsi_id->last_orb = command_orb;
- scsi_id->last_orb_dma = command->command_orb_dma;
-
+ scsi_block_requests(scsi_id->scsi_host);
+ PREPARE_WORK(&scsi_id->protocol_work,
+ last_orb ? sbp2util_write_doorbell:
+ sbp2util_write_orb_pointer,
+ scsi_id);
+ schedule_work(&scsi_id->protocol_work);
}
- return 0;
}
/*
@@ -2078,11 +2089,6 @@ static int sbp2_send_command(struct scsi_id_instance_data *scsi_id,
"sbp2 command orb", command->command_orb_dma);
/*
- * Initialize status fifo
- */
- memset(&scsi_id->status_block, 0, sizeof(struct sbp2_status_block));
-
- /*
* Link up the orb, and ring the doorbell if needed
*/
sbp2_link_orb_command(scsi_id, command);
@@ -2123,12 +2129,14 @@ static unsigned int sbp2_status_to_sense_data(unchar *sbp2_status, unchar *sense
/*
* This function deals with status writes from the SBP-2 device
*/
-static int sbp2_handle_status_write(struct hpsb_host *host, int nodeid, int destid,
- quadlet_t *data, u64 addr, size_t length, u16 fl)
+static int sbp2_handle_status_write(struct hpsb_host *host, int nodeid,
+ int destid, quadlet_t *data, u64 addr,
+ size_t length, u16 fl)
{
struct sbp2scsi_host_info *hi;
struct scsi_id_instance_data *scsi_id = NULL, *scsi_id_tmp;
struct scsi_cmnd *SCpnt = NULL;
+ struct sbp2_status_block *sb;
u32 scsi_status = SBP2_SCSI_STATUS_GOOD;
struct sbp2_command_info *command;
unsigned long flags;
@@ -2137,18 +2145,19 @@ static int sbp2_handle_status_write(struct hpsb_host *host, int nodeid, int dest
sbp2util_packet_dump(data, length, "sbp2 status write by device", (u32)addr);
- if (!host) {
+ if (unlikely(length < 8 || length > sizeof(struct sbp2_status_block))) {
+ SBP2_ERR("Wrong size of status block");
+ return RCODE_ADDRESS_ERROR;
+ }
+ if (unlikely(!host)) {
SBP2_ERR("host is NULL - this is bad!");
return RCODE_ADDRESS_ERROR;
}
-
hi = hpsb_get_hostinfo(&sbp2_highlevel, host);
-
- if (!hi) {
+ if (unlikely(!hi)) {
SBP2_ERR("host info is NULL - this is bad!");
return RCODE_ADDRESS_ERROR;
}
-
/*
* Find our scsi_id structure by looking at the status fifo address
* written to by the sbp2 device.
@@ -2160,32 +2169,35 @@ static int sbp2_handle_status_write(struct hpsb_host *host, int nodeid, int dest
break;
}
}
-
- if (!scsi_id) {
+ if (unlikely(!scsi_id)) {
SBP2_ERR("scsi_id is NULL - device is gone?");
return RCODE_ADDRESS_ERROR;
}
/*
- * Put response into scsi_id status fifo...
+ * Put response into scsi_id status fifo buffer. The first two bytes
+ * come in big endian bit order. Often the target writes only a
+ * truncated status block, minimally the first two quadlets. The rest
+ * is implied to be zeros.
*/
- memcpy(&scsi_id->status_block, data, length);
+ sb = &scsi_id->status_block;
+ memset(sb->command_set_dependent, 0, sizeof(sb->command_set_dependent));
+ memcpy(sb, data, length);
+ sbp2util_be32_to_cpu_buffer(sb, 8);
/*
- * Byte swap first two quadlets (8 bytes) of status for processing
+ * Ignore unsolicited status. Handle command ORB status.
*/
- sbp2util_be32_to_cpu_buffer(&scsi_id->status_block, 8);
-
- /*
- * Handle command ORB status here if necessary. First, need to match status with command.
- */
- command = sbp2util_find_command_for_orb(scsi_id, scsi_id->status_block.ORB_offset_lo);
+ if (unlikely(STATUS_GET_SRC(sb->ORB_offset_hi_misc) == 2))
+ command = NULL;
+ else
+ command = sbp2util_find_command_for_orb(scsi_id,
+ sb->ORB_offset_lo);
if (command) {
-
SBP2_DEBUG("Found status for command ORB");
pci_dma_sync_single_for_cpu(hi->host->pdev, command->command_orb_dma,
sizeof(struct sbp2_command_orb),
- PCI_DMA_BIDIRECTIONAL);
+ PCI_DMA_TODEVICE);
pci_dma_sync_single_for_cpu(hi->host->pdev, command->sge_dma,
sizeof(command->scatter_gather_element),
PCI_DMA_BIDIRECTIONAL);
@@ -2194,7 +2206,12 @@ static int sbp2_handle_status_write(struct hpsb_host *host, int nodeid, int dest
outstanding_orb_decr;
/*
- * Matched status with command, now grab scsi command pointers and check status
+ * Matched status with command, now grab scsi command pointers
+ * and check status.
+ */
+ /*
+ * FIXME: If the src field in the status is 1, the ORB DMA must
+ * not be reused until status for a subsequent ORB is received.
*/
SCpnt = command->Current_SCpnt;
spin_lock_irqsave(&scsi_id->sbp2_command_orb_lock, flags);
@@ -2202,61 +2219,64 @@ static int sbp2_handle_status_write(struct hpsb_host *host, int nodeid, int dest
spin_unlock_irqrestore(&scsi_id->sbp2_command_orb_lock, flags);
if (SCpnt) {
-
+ u32 h = sb->ORB_offset_hi_misc;
+ u32 r = STATUS_GET_RESP(h);
+
+ if (r != RESP_STATUS_REQUEST_COMPLETE) {
+ SBP2_WARN("resp 0x%x, sbp_status 0x%x",
+ r, STATUS_GET_SBP_STATUS(h));
+ scsi_status =
+ r == RESP_STATUS_TRANSPORT_FAILURE ?
+ SBP2_SCSI_STATUS_BUSY :
+ SBP2_SCSI_STATUS_COMMAND_TERMINATED;
+ }
/*
- * See if the target stored any scsi status information
+ * See if the target stored any scsi status information.
*/
- if (STATUS_GET_LENGTH(scsi_id->status_block.ORB_offset_hi_misc) > 1) {
- /*
- * Translate SBP-2 status to SCSI sense data
- */
+ if (STATUS_GET_LEN(h) > 1) {
SBP2_DEBUG("CHECK CONDITION");
- scsi_status = sbp2_status_to_sense_data((unchar *)&scsi_id->status_block, SCpnt->sense_buffer);
+ scsi_status = sbp2_status_to_sense_data(
+ (unchar *)sb, SCpnt->sense_buffer);
}
-
/*
- * Check to see if the dead bit is set. If so, we'll have to initiate
- * a fetch agent reset.
+ * Check to see if the dead bit is set. If so, we'll
+ * have to initiate a fetch agent reset.
*/
- if (STATUS_GET_DEAD_BIT(scsi_id->status_block.ORB_offset_hi_misc)) {
-
- /*
- * Initiate a fetch agent reset.
- */
- SBP2_DEBUG("Dead bit set - initiating fetch agent reset");
+ if (STATUS_TEST_DEAD(h)) {
+ SBP2_DEBUG("Dead bit set - "
+ "initiating fetch agent reset");
sbp2_agent_reset(scsi_id, 0);
}
-
SBP2_ORB_DEBUG("completing command orb %p", &command->command_orb);
}
/*
- * Check here to see if there are no commands in-use. If there are none, we can
- * null out last orb so that next time around we write directly to the orb pointer...
- * Quick start saves one 1394 bus transaction.
+ * Check here to see if there are no commands in-use. If there
+ * are none, we know that the fetch agent left the active state
+ * _and_ that we did not reactivate it yet. Therefore clear
+ * last_orb so that next time we write directly to the
+ * ORB_POINTER register. That way the fetch agent does not need
+ * to refetch the next_ORB.
*/
spin_lock_irqsave(&scsi_id->sbp2_command_orb_lock, flags);
- if (list_empty(&scsi_id->sbp2_command_orb_inuse)) {
+ if (list_empty(&scsi_id->sbp2_command_orb_inuse))
scsi_id->last_orb = NULL;
- }
spin_unlock_irqrestore(&scsi_id->sbp2_command_orb_lock, flags);
} else {
-
/*
* It's probably a login/logout/reconnect status.
*/
- if ((scsi_id->login_orb_dma == scsi_id->status_block.ORB_offset_lo) ||
- (scsi_id->query_logins_orb_dma == scsi_id->status_block.ORB_offset_lo) ||
- (scsi_id->reconnect_orb_dma == scsi_id->status_block.ORB_offset_lo) ||
- (scsi_id->logout_orb_dma == scsi_id->status_block.ORB_offset_lo)) {
- atomic_set(&scsi_id->sbp2_login_complete, 1);
+ if ((sb->ORB_offset_lo == scsi_id->reconnect_orb_dma) ||
+ (sb->ORB_offset_lo == scsi_id->login_orb_dma) ||
+ (sb->ORB_offset_lo == scsi_id->query_logins_orb_dma) ||
+ (sb->ORB_offset_lo == scsi_id->logout_orb_dma)) {
+ scsi_id->access_complete = 1;
+ wake_up_interruptible(&access_wq);
}
}
if (SCpnt) {
-
- /* Complete the SCSI command. */
SBP2_DEBUG("Completing SCSI command");
sbp2scsi_complete_command(scsi_id, scsi_status, SCpnt,
command->Current_done);
@@ -2372,7 +2392,7 @@ static void sbp2scsi_complete_all_commands(struct scsi_id_instance_data *scsi_id
command = list_entry(lh, struct sbp2_command_info, list);
pci_dma_sync_single_for_cpu(hi->host->pdev, command->command_orb_dma,
sizeof(struct sbp2_command_orb),
- PCI_DMA_BIDIRECTIONAL);
+ PCI_DMA_TODEVICE);
pci_dma_sync_single_for_cpu(hi->host->pdev, command->sge_dma,
sizeof(command->scatter_gather_element),
PCI_DMA_BIDIRECTIONAL);
@@ -2495,6 +2515,7 @@ static int sbp2scsi_slave_alloc(struct scsi_device *sdev)
(struct scsi_id_instance_data *)sdev->host->hostdata[0];
scsi_id->sdev = sdev;
+ sdev->allow_restart = 1;
if (scsi_id->workarounds & SBP2_WORKAROUND_INQUIRY_36)
sdev->inquiry_len = 36;
@@ -2508,16 +2529,12 @@ static int sbp2scsi_slave_configure(struct scsi_device *sdev)
blk_queue_dma_alignment(sdev->request_queue, (512 - 1));
sdev->use_10_for_rw = 1;
- sdev->use_10_for_ms = 1;
if (sdev->type == TYPE_DISK &&
scsi_id->workarounds & SBP2_WORKAROUND_MODE_SENSE_8)
sdev->skip_ms_page_8 = 1;
if (scsi_id->workarounds & SBP2_WORKAROUND_FIX_CAPACITY)
sdev->fix_capacity = 1;
- if (scsi_id->ne->guid_vendor_id == 0x0010b9 && /* Maxtor's OUI */
- (sdev->type == TYPE_DISK || sdev->type == TYPE_RBC))
- sdev->allow_restart = 1;
return 0;
}
@@ -2555,7 +2572,7 @@ static int sbp2scsi_abort(struct scsi_cmnd *SCpnt)
pci_dma_sync_single_for_cpu(hi->host->pdev,
command->command_orb_dma,
sizeof(struct sbp2_command_orb),
- PCI_DMA_BIDIRECTIONAL);
+ PCI_DMA_TODEVICE);
pci_dma_sync_single_for_cpu(hi->host->pdev,
command->sge_dma,
sizeof(command->scatter_gather_element),
@@ -2571,7 +2588,7 @@ static int sbp2scsi_abort(struct scsi_cmnd *SCpnt)
/*
* Initiate a fetch agent reset.
*/
- sbp2_agent_reset(scsi_id, 0);
+ sbp2_agent_reset(scsi_id, 1);
sbp2scsi_complete_all_commands(scsi_id, DID_BUS_BUSY);
}
@@ -2590,7 +2607,7 @@ static int sbp2scsi_reset(struct scsi_cmnd *SCpnt)
if (sbp2util_node_is_available(scsi_id)) {
SBP2_ERR("Generating sbp2 fetch agent reset");
- sbp2_agent_reset(scsi_id, 0);
+ sbp2_agent_reset(scsi_id, 1);
}
return SUCCESS;
diff --git a/drivers/ieee1394/sbp2.h b/drivers/ieee1394/sbp2.h
index b22ce1aa8fe4..abbe48e646c3 100644
--- a/drivers/ieee1394/sbp2.h
+++ b/drivers/ieee1394/sbp2.h
@@ -46,8 +46,8 @@
#define ORB_SET_DIRECTION(value) ((value & 0x1) << 27)
struct sbp2_command_orb {
- volatile u32 next_ORB_hi;
- volatile u32 next_ORB_lo;
+ u32 next_ORB_hi;
+ u32 next_ORB_lo;
u32 data_descriptor_hi;
u32 data_descriptor_lo;
u32 misc;
@@ -180,12 +180,14 @@ struct sbp2_unrestricted_page_table {
#define SBP2_SCSI_STATUS_SELECTION_TIMEOUT 0xff
-#define STATUS_GET_ORB_OFFSET_HI(value) (value & 0xffff)
-#define STATUS_GET_SBP_STATUS(value) ((value >> 16) & 0xff)
-#define STATUS_GET_LENGTH(value) ((value >> 24) & 0x7)
-#define STATUS_GET_DEAD_BIT(value) ((value >> 27) & 0x1)
-#define STATUS_GET_RESP(value) ((value >> 28) & 0x3)
-#define STATUS_GET_SRC(value) ((value >> 30) & 0x3)
+#define STATUS_GET_SRC(value) (((value) >> 30) & 0x3)
+#define STATUS_GET_RESP(value) (((value) >> 28) & 0x3)
+#define STATUS_GET_LEN(value) (((value) >> 24) & 0x7)
+#define STATUS_GET_SBP_STATUS(value) (((value) >> 16) & 0xff)
+#define STATUS_GET_ORB_OFFSET_HI(value) ((value) & 0x0000ffff)
+#define STATUS_TEST_DEAD(value) ((value) & 0x08000000)
+/* test 'resp' | 'dead' | 'sbp2_status' */
+#define STATUS_TEST_RDS(value) ((value) & 0x38ff0000)
struct sbp2_status_block {
u32 ORB_offset_hi_misc;
@@ -318,9 +320,9 @@ struct scsi_id_instance_data {
u64 status_fifo_addr;
/*
- * Variable used for logins, reconnects, logouts, query logins
+ * Waitqueue flag for logins, reconnects, logouts, query logins
*/
- atomic_t sbp2_login_complete;
+ int access_complete:1;
/*
* Pool of command orbs, so we can have more than overlapped command per id
@@ -344,6 +346,16 @@ struct scsi_id_instance_data {
/* Device specific workarounds/brokeness */
unsigned workarounds;
+
+ atomic_t state;
+ struct work_struct protocol_work;
+};
+
+/* For use in scsi_id_instance_data.state */
+enum sbp2lu_state_types {
+ SBP2LU_STATE_RUNNING, /* all normal */
+ SBP2LU_STATE_IN_RESET, /* between bus reset and reconnect */
+ SBP2LU_STATE_IN_SHUTDOWN /* when sbp2_remove was called */
};
/* Sbp2 host data structure (one per IEEE1394 host) */
@@ -390,11 +402,6 @@ static int sbp2_logout_device(struct scsi_id_instance_data *scsi_id);
static int sbp2_handle_status_write(struct hpsb_host *host, int nodeid, int destid,
quadlet_t *data, u64 addr, size_t length, u16 flags);
static int sbp2_agent_reset(struct scsi_id_instance_data *scsi_id, int wait);
-static int sbp2_link_orb_command(struct scsi_id_instance_data *scsi_id,
- struct sbp2_command_info *command);
-static int sbp2_send_command(struct scsi_id_instance_data *scsi_id,
- struct scsi_cmnd *SCpnt,
- void (*done)(struct scsi_cmnd *));
static unsigned int sbp2_status_to_sense_data(unchar *sbp2_status,
unchar *sense_data);
static void sbp2_parse_unit_directory(struct scsi_id_instance_data *scsi_id,
diff --git a/drivers/ieee1394/video1394.c b/drivers/ieee1394/video1394.c
index c6e3f02bc6d7..9bc65059cc69 100644
--- a/drivers/ieee1394/video1394.c
+++ b/drivers/ieee1394/video1394.c
@@ -49,16 +49,16 @@
#include <linux/compat.h>
#include <linux/cdev.h>
-#include "ieee1394.h"
-#include "ieee1394_types.h"
+#include "dma.h"
+#include "highlevel.h"
#include "hosts.h"
+#include "ieee1394.h"
#include "ieee1394_core.h"
-#include "highlevel.h"
-#include "video1394.h"
+#include "ieee1394_hotplug.h"
+#include "ieee1394_types.h"
#include "nodemgr.h"
-#include "dma.h"
-
#include "ohci1394.h"
+#include "video1394.h"
#define ISO_CHANNELS 64
@@ -129,7 +129,7 @@ struct file_ctx {
#define DBGMSG(card, fmt, args...) \
printk(KERN_INFO "video1394_%d: " fmt "\n" , card , ## args)
#else
-#define DBGMSG(card, fmt, args...)
+#define DBGMSG(card, fmt, args...) do {} while (0)
#endif
/* print general (card independent) information */
@@ -1181,7 +1181,8 @@ static int video1394_mmap(struct file *file, struct vm_area_struct *vma)
lock_kernel();
if (ctx->current_ctx == NULL) {
- PRINT(KERN_ERR, ctx->ohci->host->id, "Current iso context not set");
+ PRINT(KERN_ERR, ctx->ohci->host->id,
+ "Current iso context not set");
} else
res = dma_region_mmap(&ctx->current_ctx->dma, file, vma);
unlock_kernel();
@@ -1189,6 +1190,40 @@ static int video1394_mmap(struct file *file, struct vm_area_struct *vma)
return res;
}
+static unsigned int video1394_poll(struct file *file, poll_table *pt)
+{
+ struct file_ctx *ctx;
+ unsigned int mask = 0;
+ unsigned long flags;
+ struct dma_iso_ctx *d;
+ int i;
+
+ lock_kernel();
+ ctx = file->private_data;
+ d = ctx->current_ctx;
+ if (d == NULL) {
+ PRINT(KERN_ERR, ctx->ohci->host->id,
+ "Current iso context not set");
+ mask = POLLERR;
+ goto done;
+ }
+
+ poll_wait(file, &d->waitq, pt);
+
+ spin_lock_irqsave(&d->lock, flags);
+ for (i = 0; i < d->num_desc; i++) {
+ if (d->buffer_status[i] == VIDEO1394_BUFFER_READY) {
+ mask |= POLLIN | POLLRDNORM;
+ break;
+ }
+ }
+ spin_unlock_irqrestore(&d->lock, flags);
+done:
+ unlock_kernel();
+
+ return mask;
+}
+
static int video1394_open(struct inode *inode, struct file *file)
{
int i = ieee1394_file_to_instance(file);
@@ -1257,6 +1292,7 @@ static struct file_operations video1394_fops=
#ifdef CONFIG_COMPAT
.compat_ioctl = video1394_compat_ioctl,
#endif
+ .poll = video1394_poll,
.mmap = video1394_mmap,
.open = video1394_open,
.release = video1394_release
diff --git a/drivers/infiniband/core/addr.c b/drivers/infiniband/core/addr.c
index 9cbf09e2052f..60d3fbdd216c 100644
--- a/drivers/infiniband/core/addr.c
+++ b/drivers/infiniband/core/addr.c
@@ -86,7 +86,7 @@ EXPORT_SYMBOL(rdma_copy_addr);
int rdma_translate_ip(struct sockaddr *addr, struct rdma_dev_addr *dev_addr)
{
struct net_device *dev;
- u32 ip = ((struct sockaddr_in *) addr)->sin_addr.s_addr;
+ __be32 ip = ((struct sockaddr_in *) addr)->sin_addr.s_addr;
int ret;
dev = ip_dev_find(ip);
@@ -239,7 +239,7 @@ static int addr_resolve_local(struct sockaddr_in *src_in,
{
struct net_device *dev;
u32 src_ip = src_in->sin_addr.s_addr;
- u32 dst_ip = dst_in->sin_addr.s_addr;
+ __be32 dst_ip = dst_in->sin_addr.s_addr;
int ret;
dev = ip_dev_find(dst_ip);
diff --git a/drivers/infiniband/core/cma.c b/drivers/infiniband/core/cma.c
index 1178bd434d1b..9ae4f3a67c70 100644
--- a/drivers/infiniband/core/cma.c
+++ b/drivers/infiniband/core/cma.c
@@ -874,23 +874,25 @@ static struct rdma_id_private *cma_new_id(struct rdma_cm_id *listen_id,
__u16 port;
u8 ip_ver;
+ if (cma_get_net_info(ib_event->private_data, listen_id->ps,
+ &ip_ver, &port, &src, &dst))
+ goto err;
+
id = rdma_create_id(listen_id->event_handler, listen_id->context,
listen_id->ps);
if (IS_ERR(id))
- return NULL;
+ goto err;
+
+ cma_save_net_info(&id->route.addr, &listen_id->route.addr,
+ ip_ver, port, src, dst);
rt = &id->route;
rt->num_paths = ib_event->param.req_rcvd.alternate_path ? 2 : 1;
- rt->path_rec = kmalloc(sizeof *rt->path_rec * rt->num_paths, GFP_KERNEL);
+ rt->path_rec = kmalloc(sizeof *rt->path_rec * rt->num_paths,
+ GFP_KERNEL);
if (!rt->path_rec)
- goto err;
+ goto destroy_id;
- if (cma_get_net_info(ib_event->private_data, listen_id->ps,
- &ip_ver, &port, &src, &dst))
- goto err;
-
- cma_save_net_info(&id->route.addr, &listen_id->route.addr,
- ip_ver, port, src, dst);
rt->path_rec[0] = *ib_event->param.req_rcvd.primary_path;
if (rt->num_paths == 2)
rt->path_rec[1] = *ib_event->param.req_rcvd.alternate_path;
@@ -903,8 +905,10 @@ static struct rdma_id_private *cma_new_id(struct rdma_cm_id *listen_id,
id_priv = container_of(id, struct rdma_id_private, id);
id_priv->state = CMA_CONNECT;
return id_priv;
-err:
+
+destroy_id:
rdma_destroy_id(id);
+err:
return NULL;
}
@@ -932,6 +936,7 @@ static int cma_req_handler(struct ib_cm_id *cm_id, struct ib_cm_event *ib_event)
mutex_unlock(&lock);
if (ret) {
ret = -ENODEV;
+ cma_exch(conn_id, CMA_DESTROYING);
cma_release_remove(conn_id);
rdma_destroy_id(&conn_id->id);
goto out;
@@ -1307,6 +1312,7 @@ static void cma_query_handler(int status, struct ib_sa_path_rec *path_rec,
work->old_state = CMA_ROUTE_QUERY;
work->new_state = CMA_ADDR_RESOLVED;
work->event.event = RDMA_CM_EVENT_ROUTE_ERROR;
+ work->event.status = status;
}
queue_work(cma_wq, &work->work);
@@ -1862,6 +1868,11 @@ static int cma_connect_ib(struct rdma_id_private *id_priv,
ret = ib_send_cm_req(id_priv->cm_id.ib, &req);
out:
+ if (ret && !IS_ERR(id_priv->cm_id.ib)) {
+ ib_destroy_cm_id(id_priv->cm_id.ib);
+ id_priv->cm_id.ib = NULL;
+ }
+
kfree(private_data);
return ret;
}
@@ -1889,10 +1900,8 @@ static int cma_connect_iw(struct rdma_id_private *id_priv,
cm_id->remote_addr = *sin;
ret = cma_modify_qp_rtr(&id_priv->id);
- if (ret) {
- iw_destroy_cm_id(cm_id);
- return ret;
- }
+ if (ret)
+ goto out;
iw_param.ord = conn_param->initiator_depth;
iw_param.ird = conn_param->responder_resources;
@@ -1904,6 +1913,10 @@ static int cma_connect_iw(struct rdma_id_private *id_priv,
iw_param.qpn = conn_param->qp_num;
ret = iw_cm_connect(cm_id, &iw_param);
out:
+ if (ret && !IS_ERR(cm_id)) {
+ iw_destroy_cm_id(cm_id);
+ id_priv->cm_id.iw = NULL;
+ }
return ret;
}
@@ -2142,12 +2155,9 @@ static int cma_remove_id_dev(struct rdma_id_private *id_priv)
static void cma_process_remove(struct cma_device *cma_dev)
{
- struct list_head remove_list;
struct rdma_id_private *id_priv;
int ret;
- INIT_LIST_HEAD(&remove_list);
-
mutex_lock(&lock);
while (!list_empty(&cma_dev->id_list)) {
id_priv = list_entry(cma_dev->id_list.next,
@@ -2158,8 +2168,7 @@ static void cma_process_remove(struct cma_device *cma_dev)
continue;
}
- list_del(&id_priv->list);
- list_add_tail(&id_priv->list, &remove_list);
+ list_del_init(&id_priv->list);
atomic_inc(&id_priv->refcount);
mutex_unlock(&lock);
diff --git a/drivers/infiniband/hw/amso1100/c2_ae.c b/drivers/infiniband/hw/amso1100/c2_ae.c
index 08f46c83a3a4..3aae4978e1cb 100644
--- a/drivers/infiniband/hw/amso1100/c2_ae.c
+++ b/drivers/infiniband/hw/amso1100/c2_ae.c
@@ -197,7 +197,7 @@ void c2_ae_event(struct c2_dev *c2dev, u32 mq_index)
"resource=%x, qp_state=%s\n",
__FUNCTION__,
to_event_str(event_id),
- be64_to_cpu(wr->ae.ae_generic.user_context),
+ (unsigned long long) be64_to_cpu(wr->ae.ae_generic.user_context),
be32_to_cpu(wr->ae.ae_generic.resource_type),
be32_to_cpu(wr->ae.ae_generic.resource),
to_qp_state_str(be32_to_cpu(wr->ae.ae_generic.qp_state)));
diff --git a/drivers/infiniband/hw/amso1100/c2_alloc.c b/drivers/infiniband/hw/amso1100/c2_alloc.c
index 1d2529992c0c..028a60bbfca9 100644
--- a/drivers/infiniband/hw/amso1100/c2_alloc.c
+++ b/drivers/infiniband/hw/amso1100/c2_alloc.c
@@ -115,7 +115,7 @@ u16 *c2_alloc_mqsp(struct c2_dev *c2dev, struct sp_chunk *head,
((unsigned long) &(head->shared_ptr[mqsp]) -
(unsigned long) head);
pr_debug("%s addr %p dma_addr %llx\n", __FUNCTION__,
- &(head->shared_ptr[mqsp]), (u64)*dma_addr);
+ &(head->shared_ptr[mqsp]), (unsigned long long) *dma_addr);
return &(head->shared_ptr[mqsp]);
}
return NULL;
diff --git a/drivers/infiniband/hw/amso1100/c2_cm.c b/drivers/infiniband/hw/amso1100/c2_cm.c
index 485254efdd1e..75b93e9b8810 100644
--- a/drivers/infiniband/hw/amso1100/c2_cm.c
+++ b/drivers/infiniband/hw/amso1100/c2_cm.c
@@ -302,7 +302,7 @@ int c2_llp_accept(struct iw_cm_id *cm_id, struct iw_cm_conn_param *iw_param)
vq_req = vq_req_alloc(c2dev);
if (!vq_req) {
err = -ENOMEM;
- goto bail1;
+ goto bail0;
}
vq_req->qp = qp;
vq_req->cm_id = cm_id;
@@ -311,7 +311,7 @@ int c2_llp_accept(struct iw_cm_id *cm_id, struct iw_cm_conn_param *iw_param)
wr = kmalloc(c2dev->req_vq.msg_size, GFP_KERNEL);
if (!wr) {
err = -ENOMEM;
- goto bail2;
+ goto bail1;
}
/* Build the WR */
@@ -331,7 +331,7 @@ int c2_llp_accept(struct iw_cm_id *cm_id, struct iw_cm_conn_param *iw_param)
/* Validate private_data length */
if (iw_param->private_data_len > C2_MAX_PRIVATE_DATA_SIZE) {
err = -EINVAL;
- goto bail2;
+ goto bail1;
}
if (iw_param->private_data) {
@@ -348,19 +348,19 @@ int c2_llp_accept(struct iw_cm_id *cm_id, struct iw_cm_conn_param *iw_param)
err = vq_send_wr(c2dev, (union c2wr *) wr);
if (err) {
vq_req_put(c2dev, vq_req);
- goto bail2;
+ goto bail1;
}
/* Wait for reply from adapter */
err = vq_wait_for_reply(c2dev, vq_req);
if (err)
- goto bail2;
+ goto bail1;
/* Check that reply is present */
reply = (struct c2wr_cr_accept_rep *) (unsigned long) vq_req->reply_msg;
if (!reply) {
err = -ENOMEM;
- goto bail2;
+ goto bail1;
}
err = c2_errno(reply);
@@ -368,9 +368,8 @@ int c2_llp_accept(struct iw_cm_id *cm_id, struct iw_cm_conn_param *iw_param)
if (!err)
c2_set_qp_state(qp, C2_QP_STATE_RTS);
- bail2:
- kfree(wr);
bail1:
+ kfree(wr);
vq_req_free(c2dev, vq_req);
bail0:
if (err) {
diff --git a/drivers/infiniband/hw/amso1100/c2_provider.c b/drivers/infiniband/hw/amso1100/c2_provider.c
index dd6af551108b..da98d9f71429 100644
--- a/drivers/infiniband/hw/amso1100/c2_provider.c
+++ b/drivers/infiniband/hw/amso1100/c2_provider.c
@@ -390,14 +390,18 @@ static struct ib_mr *c2_reg_phys_mr(struct ib_pd *ib_pd,
}
mr = kmalloc(sizeof(*mr), GFP_KERNEL);
- if (!mr)
+ if (!mr) {
+ vfree(page_list);
return ERR_PTR(-ENOMEM);
+ }
mr->pd = to_c2pd(ib_pd);
pr_debug("%s - page shift %d, pbl_depth %d, total_len %u, "
"*iova_start %llx, first pa %llx, last pa %llx\n",
__FUNCTION__, page_shift, pbl_depth, total_len,
- *iova_start, page_list[0], page_list[pbl_depth-1]);
+ (unsigned long long) *iova_start,
+ (unsigned long long) page_list[0],
+ (unsigned long long) page_list[pbl_depth-1]);
err = c2_nsmr_register_phys_kern(to_c2dev(ib_pd->device), page_list,
(1 << page_shift), pbl_depth,
total_len, 0, iova_start,
diff --git a/drivers/infiniband/hw/amso1100/c2_rnic.c b/drivers/infiniband/hw/amso1100/c2_rnic.c
index f49a32b7a8f6..e37c5688c214 100644
--- a/drivers/infiniband/hw/amso1100/c2_rnic.c
+++ b/drivers/infiniband/hw/amso1100/c2_rnic.c
@@ -527,7 +527,7 @@ int c2_rnic_init(struct c2_dev *c2dev)
DMA_FROM_DEVICE);
pci_unmap_addr_set(&c2dev->rep_vq, mapping, c2dev->rep_vq.host_dma);
pr_debug("%s rep_vq va %p dma %llx\n", __FUNCTION__, q1_pages,
- (u64)c2dev->rep_vq.host_dma);
+ (unsigned long long) c2dev->rep_vq.host_dma);
c2_mq_rep_init(&c2dev->rep_vq,
1,
qsize,
@@ -550,7 +550,7 @@ int c2_rnic_init(struct c2_dev *c2dev)
DMA_FROM_DEVICE);
pci_unmap_addr_set(&c2dev->aeq, mapping, c2dev->aeq.host_dma);
pr_debug("%s aeq va %p dma %llx\n", __FUNCTION__, q1_pages,
- (u64)c2dev->rep_vq.host_dma);
+ (unsigned long long) c2dev->rep_vq.host_dma);
c2_mq_rep_init(&c2dev->aeq,
2,
qsize,
diff --git a/drivers/infiniband/hw/ehca/ehca_main.c b/drivers/infiniband/hw/ehca/ehca_main.c
index 2380994418a5..024d511c4b58 100644
--- a/drivers/infiniband/hw/ehca/ehca_main.c
+++ b/drivers/infiniband/hw/ehca/ehca_main.c
@@ -49,7 +49,7 @@
MODULE_LICENSE("Dual BSD/GPL");
MODULE_AUTHOR("Christoph Raisch <raisch@de.ibm.com>");
MODULE_DESCRIPTION("IBM eServer HCA InfiniBand Device Driver");
-MODULE_VERSION("SVNEHCA_0016");
+MODULE_VERSION("SVNEHCA_0017");
int ehca_open_aqp1 = 0;
int ehca_debug_level = 0;
@@ -239,7 +239,7 @@ init_node_guid1:
return ret;
}
-int ehca_register_device(struct ehca_shca *shca)
+int ehca_init_device(struct ehca_shca *shca)
{
int ret;
@@ -317,11 +317,6 @@ int ehca_register_device(struct ehca_shca *shca)
/* shca->ib_device.process_mad = ehca_process_mad; */
shca->ib_device.mmap = ehca_mmap;
- ret = ib_register_device(&shca->ib_device);
- if (ret)
- ehca_err(&shca->ib_device,
- "ib_register_device() failed ret=%x", ret);
-
return ret;
}
@@ -561,9 +556,9 @@ static int __devinit ehca_probe(struct ibmebus_dev *dev,
goto probe1;
}
- ret = ehca_register_device(shca);
+ ret = ehca_init_device(shca);
if (ret) {
- ehca_gen_err("Cannot register Infiniband device");
+ ehca_gen_err("Cannot init ehca device struct");
goto probe1;
}
@@ -571,7 +566,7 @@ static int __devinit ehca_probe(struct ibmebus_dev *dev,
ret = ehca_create_eq(shca, &shca->eq, EHCA_EQ, 2048);
if (ret) {
ehca_err(&shca->ib_device, "Cannot create EQ.");
- goto probe2;
+ goto probe1;
}
ret = ehca_create_eq(shca, &shca->neq, EHCA_NEQ, 513);
@@ -600,6 +595,13 @@ static int __devinit ehca_probe(struct ibmebus_dev *dev,
goto probe5;
}
+ ret = ib_register_device(&shca->ib_device);
+ if (ret) {
+ ehca_err(&shca->ib_device,
+ "ib_register_device() failed ret=%x", ret);
+ goto probe6;
+ }
+
/* create AQP1 for port 1 */
if (ehca_open_aqp1 == 1) {
shca->sport[0].port_state = IB_PORT_DOWN;
@@ -607,7 +609,7 @@ static int __devinit ehca_probe(struct ibmebus_dev *dev,
if (ret) {
ehca_err(&shca->ib_device,
"Cannot create AQP1 for port 1.");
- goto probe6;
+ goto probe7;
}
}
@@ -618,7 +620,7 @@ static int __devinit ehca_probe(struct ibmebus_dev *dev,
if (ret) {
ehca_err(&shca->ib_device,
"Cannot create AQP1 for port 2.");
- goto probe7;
+ goto probe8;
}
}
@@ -630,12 +632,15 @@ static int __devinit ehca_probe(struct ibmebus_dev *dev,
return 0;
-probe7:
+probe8:
ret = ehca_destroy_aqp1(&shca->sport[0]);
if (ret)
ehca_err(&shca->ib_device,
"Cannot destroy AQP1 for port 1. ret=%x", ret);
+probe7:
+ ib_unregister_device(&shca->ib_device);
+
probe6:
ret = ehca_dereg_internal_maxmr(shca);
if (ret)
@@ -660,9 +665,6 @@ probe3:
ehca_err(&shca->ib_device,
"Cannot destroy EQ. ret=%x", ret);
-probe2:
- ib_unregister_device(&shca->ib_device);
-
probe1:
ib_dealloc_device(&shca->ib_device);
@@ -750,7 +752,7 @@ int __init ehca_module_init(void)
int ret;
printk(KERN_INFO "eHCA Infiniband Device Driver "
- "(Rel.: SVNEHCA_0016)\n");
+ "(Rel.: SVNEHCA_0017)\n");
idr_init(&ehca_qp_idr);
idr_init(&ehca_cq_idr);
spin_lock_init(&ehca_qp_idr_lock);
diff --git a/drivers/infiniband/hw/ehca/ehca_tools.h b/drivers/infiniband/hw/ehca/ehca_tools.h
index 9f56bb846d93..809da3ef706b 100644
--- a/drivers/infiniband/hw/ehca/ehca_tools.h
+++ b/drivers/infiniband/hw/ehca/ehca_tools.h
@@ -117,7 +117,7 @@ extern int ehca_debug_level;
unsigned int l = (unsigned int)(len); \
unsigned char *deb = (unsigned char*)(adr); \
for (x = 0; x < l; x += 16) { \
- printk("EHCA_DMP:%s" format \
+ printk("EHCA_DMP:%s " format \
" adr=%p ofs=%04x %016lx %016lx\n", \
__FUNCTION__, ##args, deb, x, \
*((u64 *)&deb[0]), *((u64 *)&deb[8])); \
diff --git a/drivers/infiniband/hw/ipath/ipath_common.h b/drivers/infiniband/hw/ipath/ipath_common.h
index f577905e3aca..54139d398181 100644
--- a/drivers/infiniband/hw/ipath/ipath_common.h
+++ b/drivers/infiniband/hw/ipath/ipath_common.h
@@ -141,8 +141,9 @@ struct infinipath_stats {
* packets if ipath not configured, etc.)
*/
__u64 sps_krdrops;
+ __u64 sps_txeparity; /* PIO buffer parity error, recovered */
/* pad for future growth */
- __u64 __sps_pad[46];
+ __u64 __sps_pad[45];
};
/*
@@ -185,6 +186,9 @@ typedef enum _ipath_ureg {
#define IPATH_RUNTIME_PCIE 0x2
#define IPATH_RUNTIME_FORCE_WC_ORDER 0x4
#define IPATH_RUNTIME_RCVHDR_COPY 0x8
+#define IPATH_RUNTIME_MASTER 0x10
+#define IPATH_RUNTIME_PBC_REWRITE 0x20
+#define IPATH_RUNTIME_LOOSE_DMA_ALIGN 0x40
/*
* This structure is returned by ipath_userinit() immediately after
@@ -202,7 +206,8 @@ struct ipath_base_info {
/* version of software, for feature checking. */
__u32 spi_sw_version;
/* InfiniPath port assigned, goes into sent packets */
- __u32 spi_port;
+ __u16 spi_port;
+ __u16 spi_subport;
/*
* IB MTU, packets IB data must be less than this.
* The MTU is in bytes, and will be a multiple of 4 bytes.
@@ -218,7 +223,7 @@ struct ipath_base_info {
__u32 spi_tidcnt;
/* size of the TID Eager list in infinipath, in entries */
__u32 spi_tidegrcnt;
- /* size of a single receive header queue entry. */
+ /* size of a single receive header queue entry in words. */
__u32 spi_rcvhdrent_size;
/*
* Count of receive header queue entries allocated.
@@ -310,6 +315,12 @@ struct ipath_base_info {
__u32 spi_filler_for_align;
/* address of readonly memory copy of the rcvhdrq tail register. */
__u64 spi_rcvhdr_tailaddr;
+
+ /* shared memory pages for subports if IPATH_RUNTIME_MASTER is set */
+ __u64 spi_subport_uregbase;
+ __u64 spi_subport_rcvegrbuf;
+ __u64 spi_subport_rcvhdr_base;
+
} __attribute__ ((aligned(8)));
@@ -328,12 +339,12 @@ struct ipath_base_info {
/*
* Minor version differences are always compatible
- * a within a major version, however if if user software is larger
+ * a within a major version, however if user software is larger
* than driver software, some new features and/or structure fields
* may not be implemented; the user code must deal with this if it
- * cares, or it must abort after initialization reports the difference
+ * cares, or it must abort after initialization reports the difference.
*/
-#define IPATH_USER_SWMINOR 2
+#define IPATH_USER_SWMINOR 3
#define IPATH_USER_SWVERSION ((IPATH_USER_SWMAJOR<<16) | IPATH_USER_SWMINOR)
@@ -379,7 +390,16 @@ struct ipath_user_info {
*/
__u32 spu_rcvhdrsize;
- __u64 spu_unused; /* kept for compatible layout */
+ /*
+ * If two or more processes wish to share a port, each process
+ * must set the spu_subport_cnt and spu_subport_id to the same
+ * values. The only restriction on the spu_subport_id is that
+ * it be unique for a given node.
+ */
+ __u16 spu_subport_cnt;
+ __u16 spu_subport_id;
+
+ __u32 spu_unused; /* kept for compatible layout */
/*
* address of struct base_info to write to
@@ -392,19 +412,25 @@ struct ipath_user_info {
#define IPATH_CMD_MIN 16
-#define IPATH_CMD_USER_INIT 16 /* set up userspace */
+#define __IPATH_CMD_USER_INIT 16 /* old set up userspace (for old user code) */
#define IPATH_CMD_PORT_INFO 17 /* find out what resources we got */
#define IPATH_CMD_RECV_CTRL 18 /* control receipt of packets */
#define IPATH_CMD_TID_UPDATE 19 /* update expected TID entries */
#define IPATH_CMD_TID_FREE 20 /* free expected TID entries */
#define IPATH_CMD_SET_PART_KEY 21 /* add partition key */
+#define IPATH_CMD_SLAVE_INFO 22 /* return info on slave processes */
+#define IPATH_CMD_ASSIGN_PORT 23 /* allocate HCA and port */
+#define IPATH_CMD_USER_INIT 24 /* set up userspace */
-#define IPATH_CMD_MAX 21
+#define IPATH_CMD_MAX 24
struct ipath_port_info {
__u32 num_active; /* number of active units */
__u32 unit; /* unit (chip) assigned to caller */
- __u32 port; /* port on unit assigned to caller */
+ __u16 port; /* port on unit assigned to caller */
+ __u16 subport; /* subport on unit assigned to caller */
+ __u16 num_ports; /* number of ports available on unit */
+ __u16 num_subports; /* number of subport slaves opened on port */
};
struct ipath_tid_info {
@@ -435,6 +461,8 @@ struct ipath_cmd {
__u32 recv_ctrl;
/* partition key to set */
__u16 part_key;
+ /* user address of __u32 bitmask of active slaves */
+ __u64 slave_mask_addr;
} cmd;
};
@@ -596,6 +624,10 @@ struct infinipath_counters {
/* K_PktFlags bits */
#define INFINIPATH_KPF_INTR 0x1
+#define INFINIPATH_KPF_SUBPORT_MASK 0x3
+#define INFINIPATH_KPF_SUBPORT_SHIFT 1
+
+#define INFINIPATH_MAX_SUBPORT 4
/* SendPIO per-buffer control */
#define INFINIPATH_SP_TEST 0x40
@@ -610,7 +642,7 @@ struct ipath_header {
/*
* Version - 4 bits, Port - 4 bits, TID - 10 bits and Offset -
* 14 bits before ECO change ~28 Dec 03. After that, Vers 4,
- * Port 3, TID 11, offset 14.
+ * Port 4, TID 11, offset 13.
*/
__le32 ver_port_tid_offset;
__le16 chksum;
diff --git a/drivers/infiniband/hw/ipath/ipath_cq.c b/drivers/infiniband/hw/ipath/ipath_cq.c
index 049221bc590e..87462e0cb4d2 100644
--- a/drivers/infiniband/hw/ipath/ipath_cq.c
+++ b/drivers/infiniband/hw/ipath/ipath_cq.c
@@ -46,7 +46,7 @@
*/
void ipath_cq_enter(struct ipath_cq *cq, struct ib_wc *entry, int solicited)
{
- struct ipath_cq_wc *wc = cq->queue;
+ struct ipath_cq_wc *wc;
unsigned long flags;
u32 head;
u32 next;
@@ -57,6 +57,7 @@ void ipath_cq_enter(struct ipath_cq *cq, struct ib_wc *entry, int solicited)
* Note that the head pointer might be writable by user processes.
* Take care to verify it is a sane value.
*/
+ wc = cq->queue;
head = wc->head;
if (head >= (unsigned) cq->ibcq.cqe) {
head = cq->ibcq.cqe;
@@ -109,21 +110,27 @@ void ipath_cq_enter(struct ipath_cq *cq, struct ib_wc *entry, int solicited)
int ipath_poll_cq(struct ib_cq *ibcq, int num_entries, struct ib_wc *entry)
{
struct ipath_cq *cq = to_icq(ibcq);
- struct ipath_cq_wc *wc = cq->queue;
+ struct ipath_cq_wc *wc;
unsigned long flags;
int npolled;
+ u32 tail;
spin_lock_irqsave(&cq->lock, flags);
+ wc = cq->queue;
+ tail = wc->tail;
+ if (tail > (u32) cq->ibcq.cqe)
+ tail = (u32) cq->ibcq.cqe;
for (npolled = 0; npolled < num_entries; ++npolled, ++entry) {
- if (wc->tail == wc->head)
+ if (tail == wc->head)
break;
- *entry = wc->queue[wc->tail];
- if (wc->tail >= cq->ibcq.cqe)
- wc->tail = 0;
+ *entry = wc->queue[tail];
+ if (tail >= cq->ibcq.cqe)
+ tail = 0;
else
- wc->tail++;
+ tail++;
}
+ wc->tail = tail;
spin_unlock_irqrestore(&cq->lock, flags);
@@ -177,11 +184,6 @@ struct ib_cq *ipath_create_cq(struct ib_device *ibdev, int entries,
goto done;
}
- if (dev->n_cqs_allocated == ib_ipath_max_cqs) {
- ret = ERR_PTR(-ENOMEM);
- goto done;
- }
-
/* Allocate the completion queue structure. */
cq = kmalloc(sizeof(*cq), GFP_KERNEL);
if (!cq) {
@@ -237,6 +239,16 @@ struct ib_cq *ipath_create_cq(struct ib_device *ibdev, int entries,
} else
cq->ip = NULL;
+ spin_lock(&dev->n_cqs_lock);
+ if (dev->n_cqs_allocated == ib_ipath_max_cqs) {
+ spin_unlock(&dev->n_cqs_lock);
+ ret = ERR_PTR(-ENOMEM);
+ goto bail_wc;
+ }
+
+ dev->n_cqs_allocated++;
+ spin_unlock(&dev->n_cqs_lock);
+
/*
* ib_create_cq() will initialize cq->ibcq except for cq->ibcq.cqe.
* The number of entries should be >= the number requested or return
@@ -253,7 +265,6 @@ struct ib_cq *ipath_create_cq(struct ib_device *ibdev, int entries,
ret = &cq->ibcq;
- dev->n_cqs_allocated++;
goto done;
bail_wc:
@@ -280,7 +291,9 @@ int ipath_destroy_cq(struct ib_cq *ibcq)
struct ipath_cq *cq = to_icq(ibcq);
tasklet_kill(&cq->comptask);
+ spin_lock(&dev->n_cqs_lock);
dev->n_cqs_allocated--;
+ spin_unlock(&dev->n_cqs_lock);
if (cq->ip)
kref_put(&cq->ip->ref, ipath_release_mmap_info);
else
@@ -316,10 +329,16 @@ int ipath_req_notify_cq(struct ib_cq *ibcq, enum ib_cq_notify notify)
return 0;
}
+/**
+ * ipath_resize_cq - change the size of the CQ
+ * @ibcq: the completion queue
+ *
+ * Returns 0 for success.
+ */
int ipath_resize_cq(struct ib_cq *ibcq, int cqe, struct ib_udata *udata)
{
struct ipath_cq *cq = to_icq(ibcq);
- struct ipath_cq_wc *old_wc = cq->queue;
+ struct ipath_cq_wc *old_wc;
struct ipath_cq_wc *wc;
u32 head, tail, n;
int ret;
@@ -355,6 +374,7 @@ int ipath_resize_cq(struct ib_cq *ibcq, int cqe, struct ib_udata *udata)
* Make sure head and tail are sane since they
* might be user writable.
*/
+ old_wc = cq->queue;
head = old_wc->head;
if (head > (u32) cq->ibcq.cqe)
head = (u32) cq->ibcq.cqe;
diff --git a/drivers/infiniband/hw/ipath/ipath_driver.c b/drivers/infiniband/hw/ipath/ipath_driver.c
index 2108466c7e33..12cefa658f3b 100644
--- a/drivers/infiniband/hw/ipath/ipath_driver.c
+++ b/drivers/infiniband/hw/ipath/ipath_driver.c
@@ -95,16 +95,6 @@ const char *ipath_ibcstatus_str[] = {
"RecovIdle",
};
-/*
- * These variables are initialized in the chip-specific files
- * but are defined here.
- */
-u16 ipath_gpio_sda_num, ipath_gpio_scl_num;
-u64 ipath_gpio_sda, ipath_gpio_scl;
-u64 infinipath_i_bitsextant;
-ipath_err_t infinipath_e_bitsextant, infinipath_hwe_bitsextant;
-u32 infinipath_i_rcvavail_mask, infinipath_i_rcvurg_mask;
-
static void __devexit ipath_remove_one(struct pci_dev *);
static int __devinit ipath_init_one(struct pci_dev *,
const struct pci_device_id *);
@@ -527,28 +517,146 @@ bail:
return ret;
}
+static void __devexit cleanup_device(struct ipath_devdata *dd)
+{
+ int port;
+
+ ipath_shutdown_device(dd);
+
+ if (*dd->ipath_statusp & IPATH_STATUS_CHIP_PRESENT) {
+ /* can't do anything more with chip; needs re-init */
+ *dd->ipath_statusp &= ~IPATH_STATUS_CHIP_PRESENT;
+ if (dd->ipath_kregbase) {
+ /*
+ * if we haven't already cleaned up before these are
+ * to ensure any register reads/writes "fail" until
+ * re-init
+ */
+ dd->ipath_kregbase = NULL;
+ dd->ipath_uregbase = 0;
+ dd->ipath_sregbase = 0;
+ dd->ipath_cregbase = 0;
+ dd->ipath_kregsize = 0;
+ }
+ ipath_disable_wc(dd);
+ }
+
+ if (dd->ipath_pioavailregs_dma) {
+ dma_free_coherent(&dd->pcidev->dev, PAGE_SIZE,
+ (void *) dd->ipath_pioavailregs_dma,
+ dd->ipath_pioavailregs_phys);
+ dd->ipath_pioavailregs_dma = NULL;
+ }
+ if (dd->ipath_dummy_hdrq) {
+ dma_free_coherent(&dd->pcidev->dev,
+ dd->ipath_pd[0]->port_rcvhdrq_size,
+ dd->ipath_dummy_hdrq, dd->ipath_dummy_hdrq_phys);
+ dd->ipath_dummy_hdrq = NULL;
+ }
+
+ if (dd->ipath_pageshadow) {
+ struct page **tmpp = dd->ipath_pageshadow;
+ dma_addr_t *tmpd = dd->ipath_physshadow;
+ int i, cnt = 0;
+
+ ipath_cdbg(VERBOSE, "Unlocking any expTID pages still "
+ "locked\n");
+ for (port = 0; port < dd->ipath_cfgports; port++) {
+ int port_tidbase = port * dd->ipath_rcvtidcnt;
+ int maxtid = port_tidbase + dd->ipath_rcvtidcnt;
+ for (i = port_tidbase; i < maxtid; i++) {
+ if (!tmpp[i])
+ continue;
+ pci_unmap_page(dd->pcidev, tmpd[i],
+ PAGE_SIZE, PCI_DMA_FROMDEVICE);
+ ipath_release_user_pages(&tmpp[i], 1);
+ tmpp[i] = NULL;
+ cnt++;
+ }
+ }
+ if (cnt) {
+ ipath_stats.sps_pageunlocks += cnt;
+ ipath_cdbg(VERBOSE, "There were still %u expTID "
+ "entries locked\n", cnt);
+ }
+ if (ipath_stats.sps_pagelocks ||
+ ipath_stats.sps_pageunlocks)
+ ipath_cdbg(VERBOSE, "%llu pages locked, %llu "
+ "unlocked via ipath_m{un}lock\n",
+ (unsigned long long)
+ ipath_stats.sps_pagelocks,
+ (unsigned long long)
+ ipath_stats.sps_pageunlocks);
+
+ ipath_cdbg(VERBOSE, "Free shadow page tid array at %p\n",
+ dd->ipath_pageshadow);
+ vfree(dd->ipath_pageshadow);
+ dd->ipath_pageshadow = NULL;
+ }
+
+ /*
+ * free any resources still in use (usually just kernel ports)
+ * at unload; we do for portcnt, not cfgports, because cfgports
+ * could have changed while we were loaded.
+ */
+ for (port = 0; port < dd->ipath_portcnt; port++) {
+ struct ipath_portdata *pd = dd->ipath_pd[port];
+ dd->ipath_pd[port] = NULL;
+ ipath_free_pddata(dd, pd);
+ }
+ kfree(dd->ipath_pd);
+ /*
+ * debuggability, in case some cleanup path tries to use it
+ * after this
+ */
+ dd->ipath_pd = NULL;
+}
+
static void __devexit ipath_remove_one(struct pci_dev *pdev)
{
- struct ipath_devdata *dd;
+ struct ipath_devdata *dd = pci_get_drvdata(pdev);
- ipath_cdbg(VERBOSE, "removing, pdev=%p\n", pdev);
- if (!pdev)
- return;
+ ipath_cdbg(VERBOSE, "removing, pdev=%p, dd=%p\n", pdev, dd);
+
+ if (dd->verbs_dev)
+ ipath_unregister_ib_device(dd->verbs_dev);
- dd = pci_get_drvdata(pdev);
- ipath_unregister_ib_device(dd->verbs_dev);
ipath_diag_remove(dd);
ipath_user_remove(dd);
ipathfs_remove_device(dd);
ipath_device_remove_group(&pdev->dev, dd);
+
ipath_cdbg(VERBOSE, "Releasing pci memory regions, dd %p, "
"unit %u\n", dd, (u32) dd->ipath_unit);
- if (dd->ipath_kregbase) {
- ipath_cdbg(VERBOSE, "Unmapping kregbase %p\n",
- dd->ipath_kregbase);
- iounmap((volatile void __iomem *) dd->ipath_kregbase);
- dd->ipath_kregbase = NULL;
- }
+
+ cleanup_device(dd);
+
+ /*
+ * turn off rcv, send, and interrupts for all ports, all drivers
+ * should also hard reset the chip here?
+ * free up port 0 (kernel) rcvhdr, egr bufs, and eventually tid bufs
+ * for all versions of the driver, if they were allocated
+ */
+ if (pdev->irq) {
+ ipath_cdbg(VERBOSE,
+ "unit %u free_irq of irq %x\n",
+ dd->ipath_unit, pdev->irq);
+ free_irq(pdev->irq, dd);
+ } else
+ ipath_dbg("irq is 0, not doing free_irq "
+ "for unit %u\n", dd->ipath_unit);
+ /*
+ * we check for NULL here, because it's outside
+ * the kregbase check, and we need to call it
+ * after the free_irq. Thus it's possible that
+ * the function pointers were never initialized.
+ */
+ if (dd->ipath_f_cleanup)
+ /* clean up chip-specific stuff */
+ dd->ipath_f_cleanup(dd);
+
+ ipath_cdbg(VERBOSE, "Unmapping kregbase %p\n", dd->ipath_kregbase);
+ iounmap((volatile void __iomem *) dd->ipath_kregbase);
pci_release_regions(pdev);
ipath_cdbg(VERBOSE, "calling pci_disable_device\n");
pci_disable_device(pdev);
@@ -760,8 +868,8 @@ static void get_rhf_errstring(u32 err, char *msg, size_t len)
static inline void *ipath_get_egrbuf(struct ipath_devdata *dd, u32 bufnum,
int err)
{
- return dd->ipath_port0_skbs ?
- (void *)dd->ipath_port0_skbs[bufnum]->data : NULL;
+ return dd->ipath_port0_skbinfo ?
+ (void *) dd->ipath_port0_skbinfo[bufnum].skb->data : NULL;
}
/**
@@ -783,31 +891,34 @@ struct sk_buff *ipath_alloc_skb(struct ipath_devdata *dd,
*/
/*
- * We need 4 extra bytes for unaligned transfer copying
+ * We need 2 extra bytes for ipath_ether data sent in the
+ * key header. In order to keep everything dword aligned,
+ * we'll reserve 4 bytes.
*/
+ len = dd->ipath_ibmaxlen + 4;
+
if (dd->ipath_flags & IPATH_4BYTE_TID) {
- /* we need a 4KB multiple alignment, and there is no way
+ /* We need a 2KB multiple alignment, and there is no way
* to do it except to allocate extra and then skb_reserve
* enough to bring it up to the right alignment.
*/
- len = dd->ipath_ibmaxlen + 4 + (1 << 11) - 1;
+ len += 2047;
}
- else
- len = dd->ipath_ibmaxlen + 4;
+
skb = __dev_alloc_skb(len, gfp_mask);
if (!skb) {
ipath_dev_err(dd, "Failed to allocate skbuff, length %u\n",
len);
goto bail;
}
+
+ skb_reserve(skb, 4);
+
if (dd->ipath_flags & IPATH_4BYTE_TID) {
- u32 una = ((1 << 11) - 1) & (unsigned long)(skb->data + 4);
+ u32 una = (unsigned long)skb->data & 2047;
if (una)
- skb_reserve(skb, 4 + (1 << 11) - una);
- else
- skb_reserve(skb, 4);
- } else
- skb_reserve(skb, 4);
+ skb_reserve(skb, 2048 - una);
+ }
bail:
return skb;
@@ -1326,6 +1437,9 @@ int ipath_create_rcvhdrq(struct ipath_devdata *dd,
"for port %u rcvhdrqtailaddr failed\n",
pd->port_port);
ret = -ENOMEM;
+ dma_free_coherent(&dd->pcidev->dev, amt,
+ pd->port_rcvhdrq, pd->port_rcvhdrq_phys);
+ pd->port_rcvhdrq = NULL;
goto bail;
}
pd->port_rcvhdrqtailaddr_phys = phys_hdrqtail;
@@ -1347,12 +1461,13 @@ int ipath_create_rcvhdrq(struct ipath_devdata *dd,
ipath_cdbg(VERBOSE, "reuse port %d rcvhdrq @%p %llx phys; "
"hdrtailaddr@%p %llx physical\n",
pd->port_port, pd->port_rcvhdrq,
- pd->port_rcvhdrq_phys, pd->port_rcvhdrtail_kvaddr,
- (unsigned long long)pd->port_rcvhdrqtailaddr_phys);
+ (unsigned long long) pd->port_rcvhdrq_phys,
+ pd->port_rcvhdrtail_kvaddr, (unsigned long long)
+ pd->port_rcvhdrqtailaddr_phys);
/* clear for security and sanity on each use */
memset(pd->port_rcvhdrq, 0, pd->port_rcvhdrq_size);
- memset((void *)pd->port_rcvhdrtail_kvaddr, 0, PAGE_SIZE);
+ memset(pd->port_rcvhdrtail_kvaddr, 0, PAGE_SIZE);
/*
* tell chip each time we init it, even if we are re-using previous
@@ -1805,7 +1920,7 @@ void ipath_free_pddata(struct ipath_devdata *dd, struct ipath_portdata *pd)
pd->port_rcvhdrq = NULL;
if (pd->port_rcvhdrtail_kvaddr) {
dma_free_coherent(&dd->pcidev->dev, PAGE_SIZE,
- (void *)pd->port_rcvhdrtail_kvaddr,
+ pd->port_rcvhdrtail_kvaddr,
pd->port_rcvhdrqtailaddr_phys);
pd->port_rcvhdrtail_kvaddr = NULL;
}
@@ -1824,24 +1939,32 @@ void ipath_free_pddata(struct ipath_devdata *dd, struct ipath_portdata *pd)
dma_free_coherent(&dd->pcidev->dev, size,
base, pd->port_rcvegrbuf_phys[e]);
}
- vfree(pd->port_rcvegrbuf);
+ kfree(pd->port_rcvegrbuf);
pd->port_rcvegrbuf = NULL;
- vfree(pd->port_rcvegrbuf_phys);
+ kfree(pd->port_rcvegrbuf_phys);
pd->port_rcvegrbuf_phys = NULL;
pd->port_rcvegrbuf_chunks = 0;
- } else if (pd->port_port == 0 && dd->ipath_port0_skbs) {
+ } else if (pd->port_port == 0 && dd->ipath_port0_skbinfo) {
unsigned e;
- struct sk_buff **skbs = dd->ipath_port0_skbs;
+ struct ipath_skbinfo *skbinfo = dd->ipath_port0_skbinfo;
- dd->ipath_port0_skbs = NULL;
- ipath_cdbg(VERBOSE, "free closed port %d ipath_port0_skbs "
- "@ %p\n", pd->port_port, skbs);
+ dd->ipath_port0_skbinfo = NULL;
+ ipath_cdbg(VERBOSE, "free closed port %d "
+ "ipath_port0_skbinfo @ %p\n", pd->port_port,
+ skbinfo);
for (e = 0; e < dd->ipath_rcvegrcnt; e++)
- if (skbs[e])
- dev_kfree_skb(skbs[e]);
- vfree(skbs);
+ if (skbinfo[e].skb) {
+ pci_unmap_single(dd->pcidev, skbinfo[e].phys,
+ dd->ipath_ibmaxlen,
+ PCI_DMA_FROMDEVICE);
+ dev_kfree_skb(skbinfo[e].skb);
+ }
+ vfree(skbinfo);
}
kfree(pd->port_tid_pg_list);
+ vfree(pd->subport_uregbase);
+ vfree(pd->subport_rcvegrbuf);
+ vfree(pd->subport_rcvhdr_base);
kfree(pd);
}
@@ -1907,150 +2030,12 @@ bail:
return ret;
}
-static void cleanup_device(struct ipath_devdata *dd)
-{
- int port;
-
- ipath_shutdown_device(dd);
-
- if (*dd->ipath_statusp & IPATH_STATUS_CHIP_PRESENT) {
- /* can't do anything more with chip; needs re-init */
- *dd->ipath_statusp &= ~IPATH_STATUS_CHIP_PRESENT;
- if (dd->ipath_kregbase) {
- /*
- * if we haven't already cleaned up before these are
- * to ensure any register reads/writes "fail" until
- * re-init
- */
- dd->ipath_kregbase = NULL;
- dd->ipath_uregbase = 0;
- dd->ipath_sregbase = 0;
- dd->ipath_cregbase = 0;
- dd->ipath_kregsize = 0;
- }
- ipath_disable_wc(dd);
- }
-
- if (dd->ipath_pioavailregs_dma) {
- dma_free_coherent(&dd->pcidev->dev, PAGE_SIZE,
- (void *) dd->ipath_pioavailregs_dma,
- dd->ipath_pioavailregs_phys);
- dd->ipath_pioavailregs_dma = NULL;
- }
- if (dd->ipath_dummy_hdrq) {
- dma_free_coherent(&dd->pcidev->dev,
- dd->ipath_pd[0]->port_rcvhdrq_size,
- dd->ipath_dummy_hdrq, dd->ipath_dummy_hdrq_phys);
- dd->ipath_dummy_hdrq = NULL;
- }
-
- if (dd->ipath_pageshadow) {
- struct page **tmpp = dd->ipath_pageshadow;
- int i, cnt = 0;
-
- ipath_cdbg(VERBOSE, "Unlocking any expTID pages still "
- "locked\n");
- for (port = 0; port < dd->ipath_cfgports; port++) {
- int port_tidbase = port * dd->ipath_rcvtidcnt;
- int maxtid = port_tidbase + dd->ipath_rcvtidcnt;
- for (i = port_tidbase; i < maxtid; i++) {
- if (!tmpp[i])
- continue;
- ipath_release_user_pages(&tmpp[i], 1);
- tmpp[i] = NULL;
- cnt++;
- }
- }
- if (cnt) {
- ipath_stats.sps_pageunlocks += cnt;
- ipath_cdbg(VERBOSE, "There were still %u expTID "
- "entries locked\n", cnt);
- }
- if (ipath_stats.sps_pagelocks ||
- ipath_stats.sps_pageunlocks)
- ipath_cdbg(VERBOSE, "%llu pages locked, %llu "
- "unlocked via ipath_m{un}lock\n",
- (unsigned long long)
- ipath_stats.sps_pagelocks,
- (unsigned long long)
- ipath_stats.sps_pageunlocks);
-
- ipath_cdbg(VERBOSE, "Free shadow page tid array at %p\n",
- dd->ipath_pageshadow);
- vfree(dd->ipath_pageshadow);
- dd->ipath_pageshadow = NULL;
- }
-
- /*
- * free any resources still in use (usually just kernel ports)
- * at unload; we do for portcnt, not cfgports, because cfgports
- * could have changed while we were loaded.
- */
- for (port = 0; port < dd->ipath_portcnt; port++) {
- struct ipath_portdata *pd = dd->ipath_pd[port];
- dd->ipath_pd[port] = NULL;
- ipath_free_pddata(dd, pd);
- }
- kfree(dd->ipath_pd);
- /*
- * debuggability, in case some cleanup path tries to use it
- * after this
- */
- dd->ipath_pd = NULL;
-}
-
static void __exit infinipath_cleanup(void)
{
- struct ipath_devdata *dd, *tmp;
- unsigned long flags;
-
- ipath_diagpkt_remove();
-
ipath_exit_ipathfs();
ipath_driver_remove_group(&ipath_driver.driver);
- spin_lock_irqsave(&ipath_devs_lock, flags);
-
- /*
- * turn off rcv, send, and interrupts for all ports, all drivers
- * should also hard reset the chip here?
- * free up port 0 (kernel) rcvhdr, egr bufs, and eventually tid bufs
- * for all versions of the driver, if they were allocated
- */
- list_for_each_entry_safe(dd, tmp, &ipath_dev_list, ipath_list) {
- spin_unlock_irqrestore(&ipath_devs_lock, flags);
-
- if (dd->ipath_kregbase)
- cleanup_device(dd);
-
- if (dd->pcidev) {
- if (dd->pcidev->irq) {
- ipath_cdbg(VERBOSE,
- "unit %u free_irq of irq %x\n",
- dd->ipath_unit, dd->pcidev->irq);
- free_irq(dd->pcidev->irq, dd);
- } else
- ipath_dbg("irq is 0, not doing free_irq "
- "for unit %u\n", dd->ipath_unit);
-
- /*
- * we check for NULL here, because it's outside
- * the kregbase check, and we need to call it
- * after the free_irq. Thus it's possible that
- * the function pointers were never initialized.
- */
- if (dd->ipath_f_cleanup)
- /* clean up chip-specific stuff */
- dd->ipath_f_cleanup(dd);
-
- dd->pcidev = NULL;
- }
- spin_lock_irqsave(&ipath_devs_lock, flags);
- }
-
- spin_unlock_irqrestore(&ipath_devs_lock, flags);
-
ipath_cdbg(VERBOSE, "Unregistering pci driver\n");
pci_unregister_driver(&ipath_driver);
diff --git a/drivers/infiniband/hw/ipath/ipath_eeprom.c b/drivers/infiniband/hw/ipath/ipath_eeprom.c
index 3313356ab93a..a4019a6b7560 100644
--- a/drivers/infiniband/hw/ipath/ipath_eeprom.c
+++ b/drivers/infiniband/hw/ipath/ipath_eeprom.c
@@ -100,9 +100,9 @@ static int i2c_gpio_set(struct ipath_devdata *dd,
gpioval = &dd->ipath_gpio_out;
read_val = ipath_read_kreg64(dd, dd->ipath_kregs->kr_extctrl);
if (line == i2c_line_scl)
- mask = ipath_gpio_scl;
+ mask = dd->ipath_gpio_scl;
else
- mask = ipath_gpio_sda;
+ mask = dd->ipath_gpio_sda;
if (new_line_state == i2c_line_high)
/* tri-state the output rather than force high */
@@ -119,12 +119,12 @@ static int i2c_gpio_set(struct ipath_devdata *dd,
write_val = 0x0UL;
if (line == i2c_line_scl) {
- write_val <<= ipath_gpio_scl_num;
- *gpioval = *gpioval & ~(1UL << ipath_gpio_scl_num);
+ write_val <<= dd->ipath_gpio_scl_num;
+ *gpioval = *gpioval & ~(1UL << dd->ipath_gpio_scl_num);
*gpioval |= write_val;
} else {
- write_val <<= ipath_gpio_sda_num;
- *gpioval = *gpioval & ~(1UL << ipath_gpio_sda_num);
+ write_val <<= dd->ipath_gpio_sda_num;
+ *gpioval = *gpioval & ~(1UL << dd->ipath_gpio_sda_num);
*gpioval |= write_val;
}
ipath_write_kreg(dd, dd->ipath_kregs->kr_gpio_out, *gpioval);
@@ -157,9 +157,9 @@ static int i2c_gpio_get(struct ipath_devdata *dd,
read_val = ipath_read_kreg64(dd, dd->ipath_kregs->kr_extctrl);
/* config line to be an input */
if (line == i2c_line_scl)
- mask = ipath_gpio_scl;
+ mask = dd->ipath_gpio_scl;
else
- mask = ipath_gpio_sda;
+ mask = dd->ipath_gpio_sda;
write_val = read_val & ~mask;
ipath_write_kreg(dd, dd->ipath_kregs->kr_extctrl, write_val);
read_val = ipath_read_kreg64(dd, dd->ipath_kregs->kr_extstatus);
@@ -187,6 +187,7 @@ bail:
static void i2c_wait_for_writes(struct ipath_devdata *dd)
{
(void)ipath_read_kreg32(dd, dd->ipath_kregs->kr_scratch);
+ rmb();
}
static void scl_out(struct ipath_devdata *dd, u8 bit)
diff --git a/drivers/infiniband/hw/ipath/ipath_file_ops.c b/drivers/infiniband/hw/ipath/ipath_file_ops.c
index 29930e22318e..a9ddc6911f66 100644
--- a/drivers/infiniband/hw/ipath/ipath_file_ops.c
+++ b/drivers/infiniband/hw/ipath/ipath_file_ops.c
@@ -41,6 +41,12 @@
#include "ipath_kernel.h"
#include "ipath_common.h"
+/*
+ * mmap64 doesn't allow all 64 bits for 32-bit applications
+ * so only use the low 43 bits.
+ */
+#define MMAP64_MASK 0x7FFFFFFFFFFUL
+
static int ipath_open(struct inode *, struct file *);
static int ipath_close(struct inode *, struct file *);
static ssize_t ipath_write(struct file *, const char __user *, size_t,
@@ -57,18 +63,35 @@ static struct file_operations ipath_file_ops = {
.mmap = ipath_mmap
};
-static int ipath_get_base_info(struct ipath_portdata *pd,
+static int ipath_get_base_info(struct file *fp,
void __user *ubase, size_t ubase_size)
{
+ struct ipath_portdata *pd = port_fp(fp);
int ret = 0;
struct ipath_base_info *kinfo = NULL;
struct ipath_devdata *dd = pd->port_dd;
+ unsigned subport_cnt;
+ int shared, master;
+ size_t sz;
+
+ subport_cnt = pd->port_subport_cnt;
+ if (!subport_cnt) {
+ shared = 0;
+ master = 0;
+ subport_cnt = 1;
+ } else {
+ shared = 1;
+ master = !subport_fp(fp);
+ }
- if (ubase_size < sizeof(*kinfo)) {
+ sz = sizeof(*kinfo);
+ /* If port sharing is not requested, allow the old size structure */
+ if (!shared)
+ sz -= 3 * sizeof(u64);
+ if (ubase_size < sz) {
ipath_cdbg(PROC,
- "Base size %lu, need %lu (version mismatch?)\n",
- (unsigned long) ubase_size,
- (unsigned long) sizeof(*kinfo));
+ "Base size %zu, need %zu (version mismatch?)\n",
+ ubase_size, sz);
ret = -EINVAL;
goto bail;
}
@@ -95,7 +118,9 @@ static int ipath_get_base_info(struct ipath_portdata *pd,
kinfo->spi_rcv_egrperchunk = pd->port_rcvegrbufs_perchunk;
kinfo->spi_rcv_egrchunksize = kinfo->spi_rcv_egrbuftotlen /
pd->port_rcvegrbuf_chunks;
- kinfo->spi_tidcnt = dd->ipath_rcvtidcnt;
+ kinfo->spi_tidcnt = dd->ipath_rcvtidcnt / subport_cnt;
+ if (master)
+ kinfo->spi_tidcnt += dd->ipath_rcvtidcnt % subport_cnt;
/*
* for this use, may be ipath_cfgports summed over all chips that
* are are configured and present
@@ -118,31 +143,75 @@ static int ipath_get_base_info(struct ipath_portdata *pd,
* page_address() macro worked, but in 2.6.11, even that returns the
* full 64 bit address (upper bits all 1's). So far, using the
* physical addresses (or chip offsets, for chip mapping) works, but
- * no doubt some future kernel release will chang that, and we'll be
- * on to yet another method of dealing with this
+ * no doubt some future kernel release will change that, and we'll be
+ * on to yet another method of dealing with this.
*/
kinfo->spi_rcvhdr_base = (u64) pd->port_rcvhdrq_phys;
- kinfo->spi_rcvhdr_tailaddr = (u64)pd->port_rcvhdrqtailaddr_phys;
+ kinfo->spi_rcvhdr_tailaddr = (u64) pd->port_rcvhdrqtailaddr_phys;
kinfo->spi_rcv_egrbufs = (u64) pd->port_rcvegr_phys;
kinfo->spi_pioavailaddr = (u64) dd->ipath_pioavailregs_phys;
kinfo->spi_status = (u64) kinfo->spi_pioavailaddr +
(void *) dd->ipath_statusp -
(void *) dd->ipath_pioavailregs_dma;
- kinfo->spi_piobufbase = (u64) pd->port_piobufs;
- kinfo->__spi_uregbase =
- dd->ipath_uregbase + dd->ipath_palign * pd->port_port;
+ if (!shared) {
+ kinfo->spi_piocnt = dd->ipath_pbufsport;
+ kinfo->spi_piobufbase = (u64) pd->port_piobufs;
+ kinfo->__spi_uregbase = (u64) dd->ipath_uregbase +
+ dd->ipath_palign * pd->port_port;
+ } else if (master) {
+ kinfo->spi_piocnt = (dd->ipath_pbufsport / subport_cnt) +
+ (dd->ipath_pbufsport % subport_cnt);
+ /* Master's PIO buffers are after all the slave's */
+ kinfo->spi_piobufbase = (u64) pd->port_piobufs +
+ dd->ipath_palign *
+ (dd->ipath_pbufsport - kinfo->spi_piocnt);
+ kinfo->__spi_uregbase = (u64) dd->ipath_uregbase +
+ dd->ipath_palign * pd->port_port;
+ } else {
+ unsigned slave = subport_fp(fp) - 1;
+
+ kinfo->spi_piocnt = dd->ipath_pbufsport / subport_cnt;
+ kinfo->spi_piobufbase = (u64) pd->port_piobufs +
+ dd->ipath_palign * kinfo->spi_piocnt * slave;
+ kinfo->__spi_uregbase = ((u64) pd->subport_uregbase +
+ PAGE_SIZE * slave) & MMAP64_MASK;
- kinfo->spi_pioindex = dd->ipath_pbufsport * (pd->port_port - 1);
- kinfo->spi_piocnt = dd->ipath_pbufsport;
+ kinfo->spi_rcvhdr_base = ((u64) pd->subport_rcvhdr_base +
+ pd->port_rcvhdrq_size * slave) & MMAP64_MASK;
+ kinfo->spi_rcvhdr_tailaddr =
+ (u64) pd->port_rcvhdrqtailaddr_phys & MMAP64_MASK;
+ kinfo->spi_rcv_egrbufs = ((u64) pd->subport_rcvegrbuf +
+ dd->ipath_rcvegrcnt * dd->ipath_rcvegrbufsize * slave) &
+ MMAP64_MASK;
+ }
+
+ kinfo->spi_pioindex = (kinfo->spi_piobufbase - dd->ipath_piobufbase) /
+ dd->ipath_palign;
kinfo->spi_pioalign = dd->ipath_palign;
kinfo->spi_qpair = IPATH_KD_QP;
kinfo->spi_piosize = dd->ipath_ibmaxlen;
kinfo->spi_mtu = dd->ipath_ibmaxlen; /* maxlen, not ibmtu */
kinfo->spi_port = pd->port_port;
+ kinfo->spi_subport = subport_fp(fp);
kinfo->spi_sw_version = IPATH_KERN_SWVERSION;
kinfo->spi_hw_version = dd->ipath_revision;
+ if (master) {
+ kinfo->spi_runtime_flags |= IPATH_RUNTIME_MASTER;
+ kinfo->spi_subport_uregbase =
+ (u64) pd->subport_uregbase & MMAP64_MASK;
+ kinfo->spi_subport_rcvegrbuf =
+ (u64) pd->subport_rcvegrbuf & MMAP64_MASK;
+ kinfo->spi_subport_rcvhdr_base =
+ (u64) pd->subport_rcvhdr_base & MMAP64_MASK;
+ ipath_cdbg(PROC, "port %u flags %x %llx %llx %llx\n",
+ kinfo->spi_port, kinfo->spi_runtime_flags,
+ (unsigned long long) kinfo->spi_subport_uregbase,
+ (unsigned long long) kinfo->spi_subport_rcvegrbuf,
+ (unsigned long long) kinfo->spi_subport_rcvhdr_base);
+ }
+
if (copy_to_user(ubase, kinfo, sizeof(*kinfo)))
ret = -EFAULT;
@@ -154,6 +223,7 @@ bail:
/**
* ipath_tid_update - update a port TID
* @pd: the port
+ * @fp: the ipath device file
* @ti: the TID information
*
* The new implementation as of Oct 2004 is that the driver assigns
@@ -176,11 +246,11 @@ bail:
* virtually contiguous pages, that should change to improve
* performance.
*/
-static int ipath_tid_update(struct ipath_portdata *pd,
+static int ipath_tid_update(struct ipath_portdata *pd, struct file *fp,
const struct ipath_tid_info *ti)
{
int ret = 0, ntids;
- u32 tid, porttid, cnt, i, tidcnt;
+ u32 tid, porttid, cnt, i, tidcnt, tidoff;
u16 *tidlist;
struct ipath_devdata *dd = pd->port_dd;
u64 physaddr;
@@ -188,6 +258,7 @@ static int ipath_tid_update(struct ipath_portdata *pd,
u64 __iomem *tidbase;
unsigned long tidmap[8];
struct page **pagep = NULL;
+ unsigned subport = subport_fp(fp);
if (!dd->ipath_pageshadow) {
ret = -ENOMEM;
@@ -204,20 +275,34 @@ static int ipath_tid_update(struct ipath_portdata *pd,
ret = -EFAULT;
goto done;
}
- tidcnt = dd->ipath_rcvtidcnt;
- if (cnt >= tidcnt) {
+ porttid = pd->port_port * dd->ipath_rcvtidcnt;
+ if (!pd->port_subport_cnt) {
+ tidcnt = dd->ipath_rcvtidcnt;
+ tid = pd->port_tidcursor;
+ tidoff = 0;
+ } else if (!subport) {
+ tidcnt = (dd->ipath_rcvtidcnt / pd->port_subport_cnt) +
+ (dd->ipath_rcvtidcnt % pd->port_subport_cnt);
+ tidoff = dd->ipath_rcvtidcnt - tidcnt;
+ porttid += tidoff;
+ tid = tidcursor_fp(fp);
+ } else {
+ tidcnt = dd->ipath_rcvtidcnt / pd->port_subport_cnt;
+ tidoff = tidcnt * (subport - 1);
+ porttid += tidoff;
+ tid = tidcursor_fp(fp);
+ }
+ if (cnt > tidcnt) {
/* make sure it all fits in port_tid_pg_list */
dev_info(&dd->pcidev->dev, "Process tried to allocate %u "
"TIDs, only trying max (%u)\n", cnt, tidcnt);
cnt = tidcnt;
}
- pagep = (struct page **)pd->port_tid_pg_list;
- tidlist = (u16 *) (&pagep[cnt]);
+ pagep = &((struct page **) pd->port_tid_pg_list)[tidoff];
+ tidlist = &((u16 *) &pagep[dd->ipath_rcvtidcnt])[tidoff];
memset(tidmap, 0, sizeof(tidmap));
- tid = pd->port_tidcursor;
/* before decrement; chip actual # */
- porttid = pd->port_port * tidcnt;
ntids = tidcnt;
tidbase = (u64 __iomem *) (((char __iomem *) dd->ipath_kregbase) +
dd->ipath_rcvtidbase +
@@ -274,16 +359,19 @@ static int ipath_tid_update(struct ipath_portdata *pd,
ret = -ENOMEM;
break;
}
- tidlist[i] = tid;
+ tidlist[i] = tid + tidoff;
ipath_cdbg(VERBOSE, "Updating idx %u to TID %u, "
- "vaddr %lx\n", i, tid, vaddr);
+ "vaddr %lx\n", i, tid + tidoff, vaddr);
/* we "know" system pages and TID pages are same size */
dd->ipath_pageshadow[porttid + tid] = pagep[i];
+ dd->ipath_physshadow[porttid + tid] = ipath_map_page(
+ dd->pcidev, pagep[i], 0, PAGE_SIZE,
+ PCI_DMA_FROMDEVICE);
/*
* don't need atomic or it's overhead
*/
__set_bit(tid, tidmap);
- physaddr = page_to_phys(pagep[i]);
+ physaddr = dd->ipath_physshadow[porttid + tid];
ipath_stats.sps_pagelocks++;
ipath_cdbg(VERBOSE,
"TID %u, vaddr %lx, physaddr %llx pgp %p\n",
@@ -317,6 +405,9 @@ static int ipath_tid_update(struct ipath_portdata *pd,
tid);
dd->ipath_f_put_tid(dd, &tidbase[tid], 1,
dd->ipath_tidinvalid);
+ pci_unmap_page(dd->pcidev,
+ dd->ipath_physshadow[porttid + tid],
+ PAGE_SIZE, PCI_DMA_FROMDEVICE);
dd->ipath_pageshadow[porttid + tid] = NULL;
ipath_stats.sps_pageunlocks++;
}
@@ -341,7 +432,10 @@ static int ipath_tid_update(struct ipath_portdata *pd,
}
if (tid == tidcnt)
tid = 0;
- pd->port_tidcursor = tid;
+ if (!pd->port_subport_cnt)
+ pd->port_tidcursor = tid;
+ else
+ tidcursor_fp(fp) = tid;
}
done:
@@ -354,6 +448,7 @@ done:
/**
* ipath_tid_free - free a port TID
* @pd: the port
+ * @subport: the subport
* @ti: the TID info
*
* right now we are unlocking one page at a time, but since
@@ -367,7 +462,7 @@ done:
* they pass in to us.
*/
-static int ipath_tid_free(struct ipath_portdata *pd,
+static int ipath_tid_free(struct ipath_portdata *pd, unsigned subport,
const struct ipath_tid_info *ti)
{
int ret = 0;
@@ -388,11 +483,20 @@ static int ipath_tid_free(struct ipath_portdata *pd,
}
porttid = pd->port_port * dd->ipath_rcvtidcnt;
+ if (!pd->port_subport_cnt)
+ tidcnt = dd->ipath_rcvtidcnt;
+ else if (!subport) {
+ tidcnt = (dd->ipath_rcvtidcnt / pd->port_subport_cnt) +
+ (dd->ipath_rcvtidcnt % pd->port_subport_cnt);
+ porttid += dd->ipath_rcvtidcnt - tidcnt;
+ } else {
+ tidcnt = dd->ipath_rcvtidcnt / pd->port_subport_cnt;
+ porttid += tidcnt * (subport - 1);
+ }
tidbase = (u64 __iomem *) ((char __iomem *)(dd->ipath_kregbase) +
dd->ipath_rcvtidbase +
porttid * sizeof(*tidbase));
- tidcnt = dd->ipath_rcvtidcnt;
limit = sizeof(tidmap) * BITS_PER_BYTE;
if (limit > tidcnt)
/* just in case size changes in future */
@@ -417,6 +521,9 @@ static int ipath_tid_free(struct ipath_portdata *pd,
pd->port_pid, tid);
dd->ipath_f_put_tid(dd, &tidbase[tid], 1,
dd->ipath_tidinvalid);
+ pci_unmap_page(dd->pcidev,
+ dd->ipath_physshadow[porttid + tid],
+ PAGE_SIZE, PCI_DMA_FROMDEVICE);
ipath_release_user_pages(
&dd->ipath_pageshadow[porttid + tid], 1);
dd->ipath_pageshadow[porttid + tid] = NULL;
@@ -581,20 +688,24 @@ bail:
/**
* ipath_manage_rcvq - manage a port's receive queue
* @pd: the port
+ * @subport: the subport
* @start_stop: action to carry out
*
* start_stop == 0 disables receive on the port, for use in queue
* overflow conditions. start_stop==1 re-enables, to be used to
* re-init the software copy of the head register
*/
-static int ipath_manage_rcvq(struct ipath_portdata *pd, int start_stop)
+static int ipath_manage_rcvq(struct ipath_portdata *pd, unsigned subport,
+ int start_stop)
{
struct ipath_devdata *dd = pd->port_dd;
u64 tval;
- ipath_cdbg(PROC, "%sabling rcv for unit %u port %u\n",
+ ipath_cdbg(PROC, "%sabling rcv for unit %u port %u:%u\n",
start_stop ? "en" : "dis", dd->ipath_unit,
- pd->port_port);
+ pd->port_port, subport);
+ if (subport)
+ goto bail;
/* atomically clear receive enable port. */
if (start_stop) {
/*
@@ -609,7 +720,7 @@ static int ipath_manage_rcvq(struct ipath_portdata *pd, int start_stop)
* updated and correct itself, even in the face of software
* bugs.
*/
- *pd->port_rcvhdrtail_kvaddr = 0;
+ *(volatile u64 *)pd->port_rcvhdrtail_kvaddr = 0;
set_bit(INFINIPATH_R_PORTENABLE_SHIFT + pd->port_port,
&dd->ipath_rcvctrl);
} else
@@ -630,6 +741,7 @@ static int ipath_manage_rcvq(struct ipath_portdata *pd, int start_stop)
tval = ipath_read_ureg32(dd, ur_rcvhdrtail, pd->port_port);
}
/* always; new head should be equal to new tail; see above */
+bail:
return 0;
}
@@ -687,6 +799,36 @@ static void ipath_clean_part_key(struct ipath_portdata *pd,
}
}
+/*
+ * Initialize the port data with the receive buffer sizes
+ * so this can be done while the master port is locked.
+ * Otherwise, there is a race with a slave opening the port
+ * and seeing these fields uninitialized.
+ */
+static void init_user_egr_sizes(struct ipath_portdata *pd)
+{
+ struct ipath_devdata *dd = pd->port_dd;
+ unsigned egrperchunk, egrcnt, size;
+
+ /*
+ * to avoid wasting a lot of memory, we allocate 32KB chunks of
+ * physically contiguous memory, advance through it until used up
+ * and then allocate more. Of course, we need memory to store those
+ * extra pointers, now. Started out with 256KB, but under heavy
+ * memory pressure (creating large files and then copying them over
+ * NFS while doing lots of MPI jobs), we hit some allocation
+ * failures, even though we can sleep... (2.6.10) Still get
+ * failures at 64K. 32K is the lowest we can go without wasting
+ * additional memory.
+ */
+ size = 0x8000;
+ egrperchunk = size / dd->ipath_rcvegrbufsize;
+ egrcnt = dd->ipath_rcvegrcnt;
+ pd->port_rcvegrbuf_chunks = (egrcnt + egrperchunk - 1) / egrperchunk;
+ pd->port_rcvegrbufs_perchunk = egrperchunk;
+ pd->port_rcvegrbuf_size = size;
+}
+
/**
* ipath_create_user_egr - allocate eager TID buffers
* @pd: the port to allocate TID buffers for
@@ -702,7 +844,7 @@ static void ipath_clean_part_key(struct ipath_portdata *pd,
static int ipath_create_user_egr(struct ipath_portdata *pd)
{
struct ipath_devdata *dd = pd->port_dd;
- unsigned e, egrcnt, alloced, egrperchunk, chunk, egrsize, egroff;
+ unsigned e, egrcnt, egrperchunk, chunk, egrsize, egroff;
size_t size;
int ret;
gfp_t gfp_flags;
@@ -722,31 +864,18 @@ static int ipath_create_user_egr(struct ipath_portdata *pd)
ipath_cdbg(VERBOSE, "Allocating %d egr buffers, at egrtid "
"offset %x, egrsize %u\n", egrcnt, egroff, egrsize);
- /*
- * to avoid wasting a lot of memory, we allocate 32KB chunks of
- * physically contiguous memory, advance through it until used up
- * and then allocate more. Of course, we need memory to store those
- * extra pointers, now. Started out with 256KB, but under heavy
- * memory pressure (creating large files and then copying them over
- * NFS while doing lots of MPI jobs), we hit some allocation
- * failures, even though we can sleep... (2.6.10) Still get
- * failures at 64K. 32K is the lowest we can go without wasting
- * additional memory.
- */
- size = 0x8000;
- alloced = ALIGN(egrsize * egrcnt, size);
- egrperchunk = size / egrsize;
- chunk = (egrcnt + egrperchunk - 1) / egrperchunk;
- pd->port_rcvegrbuf_chunks = chunk;
- pd->port_rcvegrbufs_perchunk = egrperchunk;
- pd->port_rcvegrbuf_size = size;
- pd->port_rcvegrbuf = vmalloc(chunk * sizeof(pd->port_rcvegrbuf[0]));
+ chunk = pd->port_rcvegrbuf_chunks;
+ egrperchunk = pd->port_rcvegrbufs_perchunk;
+ size = pd->port_rcvegrbuf_size;
+ pd->port_rcvegrbuf = kmalloc(chunk * sizeof(pd->port_rcvegrbuf[0]),
+ GFP_KERNEL);
if (!pd->port_rcvegrbuf) {
ret = -ENOMEM;
goto bail;
}
pd->port_rcvegrbuf_phys =
- vmalloc(chunk * sizeof(pd->port_rcvegrbuf_phys[0]));
+ kmalloc(chunk * sizeof(pd->port_rcvegrbuf_phys[0]),
+ GFP_KERNEL);
if (!pd->port_rcvegrbuf_phys) {
ret = -ENOMEM;
goto bail_rcvegrbuf;
@@ -791,105 +920,23 @@ bail_rcvegrbuf_phys:
pd->port_rcvegrbuf_phys[e]);
}
- vfree(pd->port_rcvegrbuf_phys);
+ kfree(pd->port_rcvegrbuf_phys);
pd->port_rcvegrbuf_phys = NULL;
bail_rcvegrbuf:
- vfree(pd->port_rcvegrbuf);
+ kfree(pd->port_rcvegrbuf);
pd->port_rcvegrbuf = NULL;
bail:
return ret;
}
-static int ipath_do_user_init(struct ipath_portdata *pd,
- const struct ipath_user_info *uinfo)
-{
- int ret = 0;
- struct ipath_devdata *dd = pd->port_dd;
- u32 head32;
-
- /* for now, if major version is different, bail */
- if ((uinfo->spu_userversion >> 16) != IPATH_USER_SWMAJOR) {
- dev_info(&dd->pcidev->dev,
- "User major version %d not same as driver "
- "major %d\n", uinfo->spu_userversion >> 16,
- IPATH_USER_SWMAJOR);
- ret = -ENODEV;
- goto done;
- }
-
- if ((uinfo->spu_userversion & 0xffff) != IPATH_USER_SWMINOR)
- ipath_dbg("User minor version %d not same as driver "
- "minor %d\n", uinfo->spu_userversion & 0xffff,
- IPATH_USER_SWMINOR);
-
- if (uinfo->spu_rcvhdrsize) {
- ret = ipath_setrcvhdrsize(dd, uinfo->spu_rcvhdrsize);
- if (ret)
- goto done;
- }
-
- /* for now we do nothing with rcvhdrcnt: uinfo->spu_rcvhdrcnt */
-
- /* for right now, kernel piobufs are at end, so port 1 is at 0 */
- pd->port_piobufs = dd->ipath_piobufbase +
- dd->ipath_pbufsport * (pd->port_port -
- 1) * dd->ipath_palign;
- ipath_cdbg(VERBOSE, "Set base of piobufs for port %u to 0x%x\n",
- pd->port_port, pd->port_piobufs);
-
- /*
- * Now allocate the rcvhdr Q and eager TIDs; skip the TID
- * array for time being. If pd->port_port > chip-supported,
- * we need to do extra stuff here to handle by handling overflow
- * through port 0, someday
- */
- ret = ipath_create_rcvhdrq(dd, pd);
- if (!ret)
- ret = ipath_create_user_egr(pd);
- if (ret)
- goto done;
-
- /*
- * set the eager head register for this port to the current values
- * of the tail pointers, since we don't know if they were
- * updated on last use of the port.
- */
- head32 = ipath_read_ureg32(dd, ur_rcvegrindextail, pd->port_port);
- ipath_write_ureg(dd, ur_rcvegrindexhead, head32, pd->port_port);
- dd->ipath_lastegrheads[pd->port_port] = -1;
- dd->ipath_lastrcvhdrqtails[pd->port_port] = -1;
- ipath_cdbg(VERBOSE, "Wrote port%d egrhead %x from tail regs\n",
- pd->port_port, head32);
- pd->port_tidcursor = 0; /* start at beginning after open */
- /*
- * now enable the port; the tail registers will be written to memory
- * by the chip as soon as it sees the write to
- * dd->ipath_kregs->kr_rcvctrl. The update only happens on
- * transition from 0 to 1, so clear it first, then set it as part of
- * enabling the port. This will (very briefly) affect any other
- * open ports, but it shouldn't be long enough to be an issue.
- * We explictly set the in-memory copy to 0 beforehand, so we don't
- * have to wait to be sure the DMA update has happened.
- */
- *pd->port_rcvhdrtail_kvaddr = 0ULL;
- set_bit(INFINIPATH_R_PORTENABLE_SHIFT + pd->port_port,
- &dd->ipath_rcvctrl);
- ipath_write_kreg(dd, dd->ipath_kregs->kr_rcvctrl,
- dd->ipath_rcvctrl & ~INFINIPATH_R_TAILUPD);
- ipath_write_kreg(dd, dd->ipath_kregs->kr_rcvctrl,
- dd->ipath_rcvctrl);
-done:
- return ret;
-}
-
/* common code for the mappings on dma_alloc_coherent mem */
static int ipath_mmap_mem(struct vm_area_struct *vma,
- struct ipath_portdata *pd, unsigned len,
- int write_ok, dma_addr_t addr, char *what)
+ struct ipath_portdata *pd, unsigned len, int write_ok,
+ void *kvaddr, char *what)
{
struct ipath_devdata *dd = pd->port_dd;
- unsigned pfn = (unsigned long)addr >> PAGE_SHIFT;
+ unsigned long pfn;
int ret;
if ((vma->vm_end - vma->vm_start) > len) {
@@ -912,17 +959,17 @@ static int ipath_mmap_mem(struct vm_area_struct *vma,
vma->vm_flags &= ~VM_MAYWRITE;
}
+ pfn = virt_to_phys(kvaddr) >> PAGE_SHIFT;
ret = remap_pfn_range(vma, vma->vm_start, pfn,
len, vma->vm_page_prot);
if (ret)
- dev_info(&dd->pcidev->dev,
- "%s port%u mmap of %lx, %x bytes r%c failed: %d\n",
- what, pd->port_port, (unsigned long)addr, len,
- write_ok?'w':'o', ret);
+ dev_info(&dd->pcidev->dev, "%s port%u mmap of %lx, %x "
+ "bytes r%c failed: %d\n", what, pd->port_port,
+ pfn, len, write_ok?'w':'o', ret);
else
- ipath_cdbg(VERBOSE, "%s port%u mmaped %lx, %x bytes r%c\n",
- what, pd->port_port, (unsigned long)addr, len,
- write_ok?'w':'o');
+ ipath_cdbg(VERBOSE, "%s port%u mmaped %lx, %x bytes "
+ "r%c\n", what, pd->port_port, pfn, len,
+ write_ok?'w':'o');
bail:
return ret;
}
@@ -957,7 +1004,8 @@ static int mmap_ureg(struct vm_area_struct *vma, struct ipath_devdata *dd,
static int mmap_piobufs(struct vm_area_struct *vma,
struct ipath_devdata *dd,
- struct ipath_portdata *pd)
+ struct ipath_portdata *pd,
+ unsigned piobufs, unsigned piocnt)
{
unsigned long phys;
int ret;
@@ -968,16 +1016,15 @@ static int mmap_piobufs(struct vm_area_struct *vma,
* process data, and catches users who might try to read the i/o
* space due to a bug.
*/
- if ((vma->vm_end - vma->vm_start) >
- (dd->ipath_pbufsport * dd->ipath_palign)) {
+ if ((vma->vm_end - vma->vm_start) > (piocnt * dd->ipath_palign)) {
dev_info(&dd->pcidev->dev, "FAIL mmap piobufs: "
"reqlen %lx > PAGE\n",
vma->vm_end - vma->vm_start);
- ret = -EFAULT;
+ ret = -EINVAL;
goto bail;
}
- phys = dd->ipath_physaddr + pd->port_piobufs;
+ phys = dd->ipath_physaddr + piobufs;
/*
* Don't mark this as non-cached, or we don't get the
@@ -1011,7 +1058,7 @@ static int mmap_rcvegrbufs(struct vm_area_struct *vma,
struct ipath_devdata *dd = pd->port_dd;
unsigned long start, size;
size_t total_size, i;
- dma_addr_t *phys;
+ unsigned long pfn;
int ret;
size = pd->port_rcvegrbuf_size;
@@ -1021,7 +1068,7 @@ static int mmap_rcvegrbufs(struct vm_area_struct *vma,
"reqlen %lx > actual %lx\n",
vma->vm_end - vma->vm_start,
(unsigned long) total_size);
- ret = -EFAULT;
+ ret = -EINVAL;
goto bail;
}
@@ -1035,11 +1082,11 @@ static int mmap_rcvegrbufs(struct vm_area_struct *vma,
vma->vm_flags &= ~VM_MAYWRITE;
start = vma->vm_start;
- phys = pd->port_rcvegrbuf_phys;
for (i = 0; i < pd->port_rcvegrbuf_chunks; i++, start += size) {
- ret = remap_pfn_range(vma, start, phys[i] >> PAGE_SHIFT,
- size, vma->vm_page_prot);
+ pfn = virt_to_phys(pd->port_rcvegrbuf[i]) >> PAGE_SHIFT;
+ ret = remap_pfn_range(vma, start, pfn, size,
+ vma->vm_page_prot);
if (ret < 0)
goto bail;
}
@@ -1049,6 +1096,122 @@ bail:
return ret;
}
+/*
+ * ipath_file_vma_nopage - handle a VMA page fault.
+ */
+static struct page *ipath_file_vma_nopage(struct vm_area_struct *vma,
+ unsigned long address, int *type)
+{
+ unsigned long offset = address - vma->vm_start;
+ struct page *page = NOPAGE_SIGBUS;
+ void *pageptr;
+
+ /*
+ * Convert the vmalloc address into a struct page.
+ */
+ pageptr = (void *)(offset + (vma->vm_pgoff << PAGE_SHIFT));
+ page = vmalloc_to_page(pageptr);
+ if (!page)
+ goto out;
+
+ /* Increment the reference count. */
+ get_page(page);
+ if (type)
+ *type = VM_FAULT_MINOR;
+out:
+ return page;
+}
+
+static struct vm_operations_struct ipath_file_vm_ops = {
+ .nopage = ipath_file_vma_nopage,
+};
+
+static int mmap_kvaddr(struct vm_area_struct *vma, u64 pgaddr,
+ struct ipath_portdata *pd, unsigned subport)
+{
+ unsigned long len;
+ struct ipath_devdata *dd;
+ void *addr;
+ size_t size;
+ int ret;
+
+ /* If the port is not shared, all addresses should be physical */
+ if (!pd->port_subport_cnt) {
+ ret = -EINVAL;
+ goto bail;
+ }
+
+ dd = pd->port_dd;
+ size = pd->port_rcvegrbuf_chunks * pd->port_rcvegrbuf_size;
+
+ /*
+ * Master has all the slave uregbase, rcvhdrq, and
+ * rcvegrbufs mmapped.
+ */
+ if (subport == 0) {
+ unsigned num_slaves = pd->port_subport_cnt - 1;
+
+ if (pgaddr == ((u64) pd->subport_uregbase & MMAP64_MASK)) {
+ addr = pd->subport_uregbase;
+ size = PAGE_SIZE * num_slaves;
+ } else if (pgaddr == ((u64) pd->subport_rcvhdr_base &
+ MMAP64_MASK)) {
+ addr = pd->subport_rcvhdr_base;
+ size = pd->port_rcvhdrq_size * num_slaves;
+ } else if (pgaddr == ((u64) pd->subport_rcvegrbuf &
+ MMAP64_MASK)) {
+ addr = pd->subport_rcvegrbuf;
+ size *= num_slaves;
+ } else {
+ ret = -EINVAL;
+ goto bail;
+ }
+ } else if (pgaddr == (((u64) pd->subport_uregbase +
+ PAGE_SIZE * (subport - 1)) & MMAP64_MASK)) {
+ addr = pd->subport_uregbase + PAGE_SIZE * (subport - 1);
+ size = PAGE_SIZE;
+ } else if (pgaddr == (((u64) pd->subport_rcvhdr_base +
+ pd->port_rcvhdrq_size * (subport - 1)) &
+ MMAP64_MASK)) {
+ addr = pd->subport_rcvhdr_base +
+ pd->port_rcvhdrq_size * (subport - 1);
+ size = pd->port_rcvhdrq_size;
+ } else if (pgaddr == (((u64) pd->subport_rcvegrbuf +
+ size * (subport - 1)) & MMAP64_MASK)) {
+ addr = pd->subport_rcvegrbuf + size * (subport - 1);
+ /* rcvegrbufs are read-only on the slave */
+ if (vma->vm_flags & VM_WRITE) {
+ dev_info(&dd->pcidev->dev,
+ "Can't map eager buffers as "
+ "writable (flags=%lx)\n", vma->vm_flags);
+ ret = -EPERM;
+ goto bail;
+ }
+ /*
+ * Don't allow permission to later change to writeable
+ * with mprotect.
+ */
+ vma->vm_flags &= ~VM_MAYWRITE;
+ } else {
+ ret = -EINVAL;
+ goto bail;
+ }
+ len = vma->vm_end - vma->vm_start;
+ if (len > size) {
+ ipath_cdbg(MM, "FAIL: reqlen %lx > %zx\n", len, size);
+ ret = -EINVAL;
+ goto bail;
+ }
+
+ vma->vm_pgoff = (unsigned long) addr >> PAGE_SHIFT;
+ vma->vm_ops = &ipath_file_vm_ops;
+ vma->vm_flags |= VM_RESERVED | VM_DONTEXPAND;
+ ret = 0;
+
+bail:
+ return ret;
+}
+
/**
* ipath_mmap - mmap various structures into user space
* @fp: the file pointer
@@ -1064,73 +1227,99 @@ static int ipath_mmap(struct file *fp, struct vm_area_struct *vma)
struct ipath_portdata *pd;
struct ipath_devdata *dd;
u64 pgaddr, ureg;
+ unsigned piobufs, piocnt;
int ret;
pd = port_fp(fp);
+ if (!pd) {
+ ret = -EINVAL;
+ goto bail;
+ }
dd = pd->port_dd;
/*
* This is the ipath_do_user_init() code, mapping the shared buffers
* into the user process. The address referred to by vm_pgoff is the
- * virtual, not physical, address; we only do one mmap for each
- * space mapped.
+ * file offset passed via mmap(). For shared ports, this is the
+ * kernel vmalloc() address of the pages to share with the master.
+ * For non-shared or master ports, this is a physical address.
+ * We only do one mmap for each space mapped.
*/
pgaddr = vma->vm_pgoff << PAGE_SHIFT;
/*
- * Must fit in 40 bits for our hardware; some checked elsewhere,
- * but we'll be paranoid. Check for 0 is mostly in case one of the
- * allocations failed, but user called mmap anyway. We want to catch
- * that before it can match.
+ * Check for 0 in case one of the allocations failed, but user
+ * called mmap anyway.
*/
- if (!pgaddr || pgaddr >= (1ULL<<40)) {
- ipath_dev_err(dd, "Bad phys addr %llx, start %lx, end %lx\n",
- (unsigned long long)pgaddr, vma->vm_start, vma->vm_end);
- return -EINVAL;
+ if (!pgaddr) {
+ ret = -EINVAL;
+ goto bail;
}
- /* just the offset of the port user registers, not physical addr */
- ureg = dd->ipath_uregbase + dd->ipath_palign * pd->port_port;
-
- ipath_cdbg(MM, "ushare: pgaddr %llx vm_start=%lx, vmlen %lx\n",
+ ipath_cdbg(MM, "pgaddr %llx vm_start=%lx len %lx port %u:%u:%u\n",
(unsigned long long) pgaddr, vma->vm_start,
- vma->vm_end - vma->vm_start);
+ vma->vm_end - vma->vm_start, dd->ipath_unit,
+ pd->port_port, subport_fp(fp));
- if (vma->vm_start & (PAGE_SIZE-1)) {
- ipath_dev_err(dd,
- "vm_start not aligned: %lx, end=%lx phys %lx\n",
- vma->vm_start, vma->vm_end, (unsigned long)pgaddr);
- ret = -EINVAL;
+ /*
+ * Physical addresses must fit in 40 bits for our hardware.
+ * Check for kernel virtual addresses first, anything else must
+ * match a HW or memory address.
+ */
+ if (pgaddr >= (1ULL<<40)) {
+ ret = mmap_kvaddr(vma, pgaddr, pd, subport_fp(fp));
+ goto bail;
}
- else if (pgaddr == ureg)
+
+ if (!pd->port_subport_cnt) {
+ /* port is not shared */
+ ureg = dd->ipath_uregbase + dd->ipath_palign * pd->port_port;
+ piocnt = dd->ipath_pbufsport;
+ piobufs = pd->port_piobufs;
+ } else if (!subport_fp(fp)) {
+ /* caller is the master */
+ ureg = dd->ipath_uregbase + dd->ipath_palign * pd->port_port;
+ piocnt = (dd->ipath_pbufsport / pd->port_subport_cnt) +
+ (dd->ipath_pbufsport % pd->port_subport_cnt);
+ piobufs = pd->port_piobufs +
+ dd->ipath_palign * (dd->ipath_pbufsport - piocnt);
+ } else {
+ unsigned slave = subport_fp(fp) - 1;
+
+ /* caller is a slave */
+ ureg = 0;
+ piocnt = dd->ipath_pbufsport / pd->port_subport_cnt;
+ piobufs = pd->port_piobufs + dd->ipath_palign * piocnt * slave;
+ }
+
+ if (pgaddr == ureg)
ret = mmap_ureg(vma, dd, ureg);
- else if (pgaddr == pd->port_piobufs)
- ret = mmap_piobufs(vma, dd, pd);
- else if (pgaddr == (u64) pd->port_rcvegr_phys)
+ else if (pgaddr == piobufs)
+ ret = mmap_piobufs(vma, dd, pd, piobufs, piocnt);
+ else if (pgaddr == dd->ipath_pioavailregs_phys)
+ /* in-memory copy of pioavail registers */
+ ret = ipath_mmap_mem(vma, pd, PAGE_SIZE, 0,
+ (void *) dd->ipath_pioavailregs_dma,
+ "pioavail registers");
+ else if (subport_fp(fp))
+ /* Subports don't mmap the physical receive buffers */
+ ret = -EINVAL;
+ else if (pgaddr == pd->port_rcvegr_phys)
ret = mmap_rcvegrbufs(vma, pd);
- else if (pgaddr == (u64) pd->port_rcvhdrq_phys) {
+ else if (pgaddr == (u64) pd->port_rcvhdrq_phys)
/*
* The rcvhdrq itself; readonly except on HT (so have
* to allow writable mapping), multiple pages, contiguous
* from an i/o perspective.
*/
- unsigned total_size =
- ALIGN(dd->ipath_rcvhdrcnt * dd->ipath_rcvhdrentsize
- * sizeof(u32), PAGE_SIZE);
- ret = ipath_mmap_mem(vma, pd, total_size, 1,
- pd->port_rcvhdrq_phys,
+ ret = ipath_mmap_mem(vma, pd, pd->port_rcvhdrq_size, 1,
+ pd->port_rcvhdrq,
"rcvhdrq");
- }
- else if (pgaddr == (u64)pd->port_rcvhdrqtailaddr_phys)
+ else if (pgaddr == (u64) pd->port_rcvhdrqtailaddr_phys)
/* in-memory copy of rcvhdrq tail register */
ret = ipath_mmap_mem(vma, pd, PAGE_SIZE, 0,
- pd->port_rcvhdrqtailaddr_phys,
+ pd->port_rcvhdrtail_kvaddr,
"rcvhdrq tail");
- else if (pgaddr == dd->ipath_pioavailregs_phys)
- /* in-memory copy of pioavail registers */
- ret = ipath_mmap_mem(vma, pd, PAGE_SIZE, 0,
- dd->ipath_pioavailregs_phys,
- "pioavail registers");
else
ret = -EINVAL;
@@ -1138,9 +1327,10 @@ static int ipath_mmap(struct file *fp, struct vm_area_struct *vma)
if (ret < 0)
dev_info(&dd->pcidev->dev,
- "Failure %d on addr %lx, off %lx\n",
- -ret, vma->vm_start, vma->vm_pgoff);
-
+ "Failure %d on off %llx len %lx\n",
+ -ret, (unsigned long long)pgaddr,
+ vma->vm_end - vma->vm_start);
+bail:
return ret;
}
@@ -1154,6 +1344,8 @@ static unsigned int ipath_poll(struct file *fp,
struct ipath_devdata *dd;
pd = port_fp(fp);
+ if (!pd)
+ goto bail;
dd = pd->port_dd;
bit = pd->port_port + INFINIPATH_R_INTRAVAIL_SHIFT;
@@ -1176,7 +1368,7 @@ static unsigned int ipath_poll(struct file *fp,
if (tail == head) {
set_bit(IPATH_PORT_WAITING_RCV, &pd->port_flag);
- if(dd->ipath_rhdrhead_intr_off) /* arm rcv interrupt */
+ if (dd->ipath_rhdrhead_intr_off) /* arm rcv interrupt */
(void)ipath_write_ureg(dd, ur_rcvhdrhead,
dd->ipath_rhdrhead_intr_off
| head, pd->port_port);
@@ -1200,18 +1392,80 @@ static unsigned int ipath_poll(struct file *fp,
ipath_write_kreg(dd, dd->ipath_kregs->kr_rcvctrl,
dd->ipath_rcvctrl);
+bail:
return pollflag;
}
+static int init_subports(struct ipath_devdata *dd,
+ struct ipath_portdata *pd,
+ const struct ipath_user_info *uinfo)
+{
+ int ret = 0;
+ unsigned num_slaves;
+ size_t size;
+
+ /* Old user binaries don't know about subports */
+ if ((uinfo->spu_userversion & 0xffff) != IPATH_USER_SWMINOR)
+ goto bail;
+ /*
+ * If the user is requesting zero or one port,
+ * skip the subport allocation.
+ */
+ if (uinfo->spu_subport_cnt <= 1)
+ goto bail;
+ if (uinfo->spu_subport_cnt > 4) {
+ ret = -EINVAL;
+ goto bail;
+ }
+
+ num_slaves = uinfo->spu_subport_cnt - 1;
+ pd->subport_uregbase = vmalloc(PAGE_SIZE * num_slaves);
+ if (!pd->subport_uregbase) {
+ ret = -ENOMEM;
+ goto bail;
+ }
+ /* Note: pd->port_rcvhdrq_size isn't initialized yet. */
+ size = ALIGN(dd->ipath_rcvhdrcnt * dd->ipath_rcvhdrentsize *
+ sizeof(u32), PAGE_SIZE) * num_slaves;
+ pd->subport_rcvhdr_base = vmalloc(size);
+ if (!pd->subport_rcvhdr_base) {
+ ret = -ENOMEM;
+ goto bail_ureg;
+ }
+
+ pd->subport_rcvegrbuf = vmalloc(pd->port_rcvegrbuf_chunks *
+ pd->port_rcvegrbuf_size *
+ num_slaves);
+ if (!pd->subport_rcvegrbuf) {
+ ret = -ENOMEM;
+ goto bail_rhdr;
+ }
+
+ pd->port_subport_cnt = uinfo->spu_subport_cnt;
+ pd->port_subport_id = uinfo->spu_subport_id;
+ pd->active_slaves = 1;
+ goto bail;
+
+bail_rhdr:
+ vfree(pd->subport_rcvhdr_base);
+bail_ureg:
+ vfree(pd->subport_uregbase);
+ pd->subport_uregbase = NULL;
+bail:
+ return ret;
+}
+
static int try_alloc_port(struct ipath_devdata *dd, int port,
- struct file *fp)
+ struct file *fp,
+ const struct ipath_user_info *uinfo)
{
+ struct ipath_portdata *pd;
int ret;
- if (!dd->ipath_pd[port]) {
- void *p, *ptmp;
+ if (!(pd = dd->ipath_pd[port])) {
+ void *ptmp;
- p = kzalloc(sizeof(struct ipath_portdata), GFP_KERNEL);
+ pd = kzalloc(sizeof(struct ipath_portdata), GFP_KERNEL);
/*
* Allocate memory for use in ipath_tid_update() just once
@@ -1221,34 +1475,36 @@ static int try_alloc_port(struct ipath_devdata *dd, int port,
ptmp = kmalloc(dd->ipath_rcvtidcnt * sizeof(u16) +
dd->ipath_rcvtidcnt * sizeof(struct page **),
GFP_KERNEL);
- if (!p || !ptmp) {
+ if (!pd || !ptmp) {
ipath_dev_err(dd, "Unable to allocate portdata "
"memory, failing open\n");
ret = -ENOMEM;
- kfree(p);
+ kfree(pd);
kfree(ptmp);
goto bail;
}
- dd->ipath_pd[port] = p;
+ dd->ipath_pd[port] = pd;
dd->ipath_pd[port]->port_port = port;
dd->ipath_pd[port]->port_dd = dd;
dd->ipath_pd[port]->port_tid_pg_list = ptmp;
init_waitqueue_head(&dd->ipath_pd[port]->port_wait);
}
- if (!dd->ipath_pd[port]->port_cnt) {
- dd->ipath_pd[port]->port_cnt = 1;
- fp->private_data = (void *) dd->ipath_pd[port];
+ if (!pd->port_cnt) {
+ pd->userversion = uinfo->spu_userversion;
+ init_user_egr_sizes(pd);
+ if ((ret = init_subports(dd, pd, uinfo)) != 0)
+ goto bail;
ipath_cdbg(PROC, "%s[%u] opened unit:port %u:%u\n",
current->comm, current->pid, dd->ipath_unit,
port);
- dd->ipath_pd[port]->port_pid = current->pid;
- strncpy(dd->ipath_pd[port]->port_comm, current->comm,
- sizeof(dd->ipath_pd[port]->port_comm));
+ pd->port_cnt = 1;
+ port_fp(fp) = pd;
+ pd->port_pid = current->pid;
+ strncpy(pd->port_comm, current->comm, sizeof(pd->port_comm));
ipath_stats.sps_ports++;
ret = 0;
- goto bail;
- }
- ret = -EBUSY;
+ } else
+ ret = -EBUSY;
bail:
return ret;
@@ -1264,7 +1520,8 @@ static inline int usable(struct ipath_devdata *dd)
| IPATH_LINKUNK));
}
-static int find_free_port(int unit, struct file *fp)
+static int find_free_port(int unit, struct file *fp,
+ const struct ipath_user_info *uinfo)
{
struct ipath_devdata *dd = ipath_lookup(unit);
int ret, i;
@@ -1279,8 +1536,8 @@ static int find_free_port(int unit, struct file *fp)
goto bail;
}
- for (i = 0; i < dd->ipath_cfgports; i++) {
- ret = try_alloc_port(dd, i, fp);
+ for (i = 1; i < dd->ipath_cfgports; i++) {
+ ret = try_alloc_port(dd, i, fp, uinfo);
if (ret != -EBUSY)
goto bail;
}
@@ -1290,13 +1547,14 @@ bail:
return ret;
}
-static int find_best_unit(struct file *fp)
+static int find_best_unit(struct file *fp,
+ const struct ipath_user_info *uinfo)
{
int ret = 0, i, prefunit = -1, devmax;
int maxofallports, npresent, nup;
int ndev;
- (void) ipath_count_units(&npresent, &nup, &maxofallports);
+ devmax = ipath_count_units(&npresent, &nup, &maxofallports);
/*
* This code is present to allow a knowledgeable person to
@@ -1343,8 +1601,6 @@ static int find_best_unit(struct file *fp)
if (prefunit != -1)
devmax = prefunit + 1;
- else
- devmax = ipath_count_units(NULL, NULL, NULL);
recheck:
for (i = 1; i < maxofallports; i++) {
for (ndev = prefunit != -1 ? prefunit : 0; ndev < devmax;
@@ -1359,7 +1615,7 @@ recheck:
* next.
*/
continue;
- ret = try_alloc_port(dd, i, fp);
+ ret = try_alloc_port(dd, i, fp, uinfo);
if (!ret)
goto done;
}
@@ -1395,22 +1651,183 @@ done:
return ret;
}
+static int find_shared_port(struct file *fp,
+ const struct ipath_user_info *uinfo)
+{
+ int devmax, ndev, i;
+ int ret = 0;
+
+ devmax = ipath_count_units(NULL, NULL, NULL);
+
+ for (ndev = 0; ndev < devmax; ndev++) {
+ struct ipath_devdata *dd = ipath_lookup(ndev);
+
+ if (!dd)
+ continue;
+ for (i = 1; i < dd->ipath_cfgports; i++) {
+ struct ipath_portdata *pd = dd->ipath_pd[i];
+
+ /* Skip ports which are not yet open */
+ if (!pd || !pd->port_cnt)
+ continue;
+ /* Skip port if it doesn't match the requested one */
+ if (pd->port_subport_id != uinfo->spu_subport_id)
+ continue;
+ /* Verify the sharing process matches the master */
+ if (pd->port_subport_cnt != uinfo->spu_subport_cnt ||
+ pd->userversion != uinfo->spu_userversion ||
+ pd->port_cnt >= pd->port_subport_cnt) {
+ ret = -EINVAL;
+ goto done;
+ }
+ port_fp(fp) = pd;
+ subport_fp(fp) = pd->port_cnt++;
+ tidcursor_fp(fp) = 0;
+ pd->active_slaves |= 1 << subport_fp(fp);
+ ipath_cdbg(PROC,
+ "%s[%u] %u sharing %s[%u] unit:port %u:%u\n",
+ current->comm, current->pid,
+ subport_fp(fp),
+ pd->port_comm, pd->port_pid,
+ dd->ipath_unit, pd->port_port);
+ ret = 1;
+ goto done;
+ }
+ }
+
+done:
+ return ret;
+}
+
static int ipath_open(struct inode *in, struct file *fp)
{
- int ret, user_minor;
+ /* The real work is performed later in ipath_assign_port() */
+ fp->private_data = kzalloc(sizeof(struct ipath_filedata), GFP_KERNEL);
+ return fp->private_data ? 0 : -ENOMEM;
+}
+
+
+/* Get port early, so can set affinity prior to memory allocation */
+static int ipath_assign_port(struct file *fp,
+ const struct ipath_user_info *uinfo)
+{
+ int ret;
+ int i_minor;
+ unsigned swminor;
+
+ /* Check to be sure we haven't already initialized this file */
+ if (port_fp(fp)) {
+ ret = -EINVAL;
+ goto done;
+ }
+
+ /* for now, if major version is different, bail */
+ if ((uinfo->spu_userversion >> 16) != IPATH_USER_SWMAJOR) {
+ ipath_dbg("User major version %d not same as driver "
+ "major %d\n", uinfo->spu_userversion >> 16,
+ IPATH_USER_SWMAJOR);
+ ret = -ENODEV;
+ goto done;
+ }
+
+ swminor = uinfo->spu_userversion & 0xffff;
+ if (swminor != IPATH_USER_SWMINOR)
+ ipath_dbg("User minor version %d not same as driver "
+ "minor %d\n", swminor, IPATH_USER_SWMINOR);
mutex_lock(&ipath_mutex);
- user_minor = iminor(in) - IPATH_USER_MINOR_BASE;
+ if (swminor == IPATH_USER_SWMINOR && uinfo->spu_subport_cnt &&
+ (ret = find_shared_port(fp, uinfo))) {
+ mutex_unlock(&ipath_mutex);
+ if (ret > 0)
+ ret = 0;
+ goto done;
+ }
+
+ i_minor = iminor(fp->f_dentry->d_inode) - IPATH_USER_MINOR_BASE;
ipath_cdbg(VERBOSE, "open on dev %lx (minor %d)\n",
- (long)in->i_rdev, user_minor);
+ (long)fp->f_dentry->d_inode->i_rdev, i_minor);
- if (user_minor)
- ret = find_free_port(user_minor - 1, fp);
+ if (i_minor)
+ ret = find_free_port(i_minor - 1, fp, uinfo);
else
- ret = find_best_unit(fp);
+ ret = find_best_unit(fp, uinfo);
mutex_unlock(&ipath_mutex);
+
+done:
+ return ret;
+}
+
+
+static int ipath_do_user_init(struct file *fp,
+ const struct ipath_user_info *uinfo)
+{
+ int ret;
+ struct ipath_portdata *pd;
+ struct ipath_devdata *dd;
+ u32 head32;
+
+ pd = port_fp(fp);
+ dd = pd->port_dd;
+
+ if (uinfo->spu_rcvhdrsize) {
+ ret = ipath_setrcvhdrsize(dd, uinfo->spu_rcvhdrsize);
+ if (ret)
+ goto done;
+ }
+
+ /* for now we do nothing with rcvhdrcnt: uinfo->spu_rcvhdrcnt */
+
+ /* for right now, kernel piobufs are at end, so port 1 is at 0 */
+ pd->port_piobufs = dd->ipath_piobufbase +
+ dd->ipath_pbufsport * (pd->port_port - 1) * dd->ipath_palign;
+ ipath_cdbg(VERBOSE, "Set base of piobufs for port %u to 0x%x\n",
+ pd->port_port, pd->port_piobufs);
+
+ /*
+ * Now allocate the rcvhdr Q and eager TIDs; skip the TID
+ * array for time being. If pd->port_port > chip-supported,
+ * we need to do extra stuff here to handle by handling overflow
+ * through port 0, someday
+ */
+ ret = ipath_create_rcvhdrq(dd, pd);
+ if (!ret)
+ ret = ipath_create_user_egr(pd);
+ if (ret)
+ goto done;
+
+ /*
+ * set the eager head register for this port to the current values
+ * of the tail pointers, since we don't know if they were
+ * updated on last use of the port.
+ */
+ head32 = ipath_read_ureg32(dd, ur_rcvegrindextail, pd->port_port);
+ ipath_write_ureg(dd, ur_rcvegrindexhead, head32, pd->port_port);
+ dd->ipath_lastegrheads[pd->port_port] = -1;
+ dd->ipath_lastrcvhdrqtails[pd->port_port] = -1;
+ ipath_cdbg(VERBOSE, "Wrote port%d egrhead %x from tail regs\n",
+ pd->port_port, head32);
+ pd->port_tidcursor = 0; /* start at beginning after open */
+ /*
+ * now enable the port; the tail registers will be written to memory
+ * by the chip as soon as it sees the write to
+ * dd->ipath_kregs->kr_rcvctrl. The update only happens on
+ * transition from 0 to 1, so clear it first, then set it as part of
+ * enabling the port. This will (very briefly) affect any other
+ * open ports, but it shouldn't be long enough to be an issue.
+ * We explictly set the in-memory copy to 0 beforehand, so we don't
+ * have to wait to be sure the DMA update has happened.
+ */
+ *(volatile u64 *)pd->port_rcvhdrtail_kvaddr = 0ULL;
+ set_bit(INFINIPATH_R_PORTENABLE_SHIFT + pd->port_port,
+ &dd->ipath_rcvctrl);
+ ipath_write_kreg(dd, dd->ipath_kregs->kr_rcvctrl,
+ dd->ipath_rcvctrl & ~INFINIPATH_R_TAILUPD);
+ ipath_write_kreg(dd, dd->ipath_kregs->kr_rcvctrl,
+ dd->ipath_rcvctrl);
+done:
return ret;
}
@@ -1433,6 +1850,8 @@ static void unlock_expected_tids(struct ipath_portdata *pd)
if (!dd->ipath_pageshadow[i])
continue;
+ pci_unmap_page(dd->pcidev, dd->ipath_physshadow[i],
+ PAGE_SIZE, PCI_DMA_FROMDEVICE);
ipath_release_user_pages_on_close(&dd->ipath_pageshadow[i],
1);
dd->ipath_pageshadow[i] = NULL;
@@ -1453,6 +1872,7 @@ static void unlock_expected_tids(struct ipath_portdata *pd)
static int ipath_close(struct inode *in, struct file *fp)
{
int ret = 0;
+ struct ipath_filedata *fd;
struct ipath_portdata *pd;
struct ipath_devdata *dd;
unsigned port;
@@ -1462,9 +1882,24 @@ static int ipath_close(struct inode *in, struct file *fp)
mutex_lock(&ipath_mutex);
- pd = port_fp(fp);
- port = pd->port_port;
+ fd = (struct ipath_filedata *) fp->private_data;
fp->private_data = NULL;
+ pd = fd->pd;
+ if (!pd) {
+ mutex_unlock(&ipath_mutex);
+ goto bail;
+ }
+ if (--pd->port_cnt) {
+ /*
+ * XXX If the master closes the port before the slave(s),
+ * revoke the mmap for the eager receive queue so
+ * the slave(s) don't wait for receive data forever.
+ */
+ pd->active_slaves &= ~(1 << fd->subport);
+ mutex_unlock(&ipath_mutex);
+ goto bail;
+ }
+ port = pd->port_port;
dd = pd->port_dd;
if (pd->port_hdrqfull) {
@@ -1503,8 +1938,6 @@ static int ipath_close(struct inode *in, struct file *fp)
/* clean up the pkeys for this port user */
ipath_clean_part_key(pd, dd);
-
-
/*
* be paranoid, and never write 0's to these, just use an
* unused part of the port 0 tail page. Of course,
@@ -1523,39 +1956,49 @@ static int ipath_close(struct inode *in, struct file *fp)
i = dd->ipath_pbufsport * (port - 1);
ipath_disarm_piobufs(dd, i, dd->ipath_pbufsport);
+ dd->ipath_f_clear_tids(dd, pd->port_port);
+
if (dd->ipath_pageshadow)
unlock_expected_tids(pd);
ipath_stats.sps_ports--;
ipath_cdbg(PROC, "%s[%u] closed port %u:%u\n",
pd->port_comm, pd->port_pid,
dd->ipath_unit, port);
-
- dd->ipath_f_clear_tids(dd, pd->port_port);
}
- pd->port_cnt = 0;
pd->port_pid = 0;
-
dd->ipath_pd[pd->port_port] = NULL; /* before releasing mutex */
mutex_unlock(&ipath_mutex);
ipath_free_pddata(dd, pd); /* after releasing the mutex */
+bail:
+ kfree(fd);
return ret;
}
-static int ipath_port_info(struct ipath_portdata *pd,
+static int ipath_port_info(struct ipath_portdata *pd, u16 subport,
struct ipath_port_info __user *uinfo)
{
struct ipath_port_info info;
int nup;
int ret;
+ size_t sz;
(void) ipath_count_units(NULL, &nup, NULL);
info.num_active = nup;
info.unit = pd->port_dd->ipath_unit;
info.port = pd->port_port;
+ info.subport = subport;
+ /* Don't return new fields if old library opened the port. */
+ if ((pd->userversion & 0xffff) == IPATH_USER_SWMINOR) {
+ /* Number of user ports available for this device. */
+ info.num_ports = pd->port_dd->ipath_cfgports - 1;
+ info.num_subports = pd->port_subport_cnt;
+ sz = sizeof(info);
+ } else
+ sz = sizeof(info) - 2 * sizeof(u16);
- if (copy_to_user(uinfo, &info, sizeof(info))) {
+ if (copy_to_user(uinfo, &info, sz)) {
ret = -EFAULT;
goto bail;
}
@@ -1565,6 +2008,16 @@ bail:
return ret;
}
+static int ipath_get_slave_info(struct ipath_portdata *pd,
+ void __user *slave_mask_addr)
+{
+ int ret = 0;
+
+ if (copy_to_user(slave_mask_addr, &pd->active_slaves, sizeof(u32)))
+ ret = -EFAULT;
+ return ret;
+}
+
static ssize_t ipath_write(struct file *fp, const char __user *data,
size_t count, loff_t *off)
{
@@ -1591,6 +2044,8 @@ static ssize_t ipath_write(struct file *fp, const char __user *data,
consumed = sizeof(cmd.type);
switch (cmd.type) {
+ case IPATH_CMD_ASSIGN_PORT:
+ case __IPATH_CMD_USER_INIT:
case IPATH_CMD_USER_INIT:
copy = sizeof(cmd.cmd.user_info);
dest = &cmd.cmd.user_info;
@@ -1617,6 +2072,11 @@ static ssize_t ipath_write(struct file *fp, const char __user *data,
dest = &cmd.cmd.part_key;
src = &ucmd->cmd.part_key;
break;
+ case IPATH_CMD_SLAVE_INFO:
+ copy = sizeof(cmd.cmd.slave_mask_addr);
+ dest = &cmd.cmd.slave_mask_addr;
+ src = &ucmd->cmd.slave_mask_addr;
+ break;
default:
ret = -EINVAL;
goto bail;
@@ -1634,34 +2094,55 @@ static ssize_t ipath_write(struct file *fp, const char __user *data,
consumed += copy;
pd = port_fp(fp);
+ if (!pd && cmd.type != __IPATH_CMD_USER_INIT &&
+ cmd.type != IPATH_CMD_ASSIGN_PORT) {
+ ret = -EINVAL;
+ goto bail;
+ }
switch (cmd.type) {
+ case IPATH_CMD_ASSIGN_PORT:
+ ret = ipath_assign_port(fp, &cmd.cmd.user_info);
+ if (ret)
+ goto bail;
+ break;
+ case __IPATH_CMD_USER_INIT:
+ /* backwards compatibility, get port first */
+ ret = ipath_assign_port(fp, &cmd.cmd.user_info);
+ if (ret)
+ goto bail;
+ /* and fall through to current version. */
case IPATH_CMD_USER_INIT:
- ret = ipath_do_user_init(pd, &cmd.cmd.user_info);
- if (ret < 0)
+ ret = ipath_do_user_init(fp, &cmd.cmd.user_info);
+ if (ret)
goto bail;
ret = ipath_get_base_info(
- pd, (void __user *) (unsigned long)
+ fp, (void __user *) (unsigned long)
cmd.cmd.user_info.spu_base_info,
cmd.cmd.user_info.spu_base_info_size);
break;
case IPATH_CMD_RECV_CTRL:
- ret = ipath_manage_rcvq(pd, cmd.cmd.recv_ctrl);
+ ret = ipath_manage_rcvq(pd, subport_fp(fp), cmd.cmd.recv_ctrl);
break;
case IPATH_CMD_PORT_INFO:
- ret = ipath_port_info(pd,
+ ret = ipath_port_info(pd, subport_fp(fp),
(struct ipath_port_info __user *)
(unsigned long) cmd.cmd.port_info);
break;
case IPATH_CMD_TID_UPDATE:
- ret = ipath_tid_update(pd, &cmd.cmd.tid_info);
+ ret = ipath_tid_update(pd, fp, &cmd.cmd.tid_info);
break;
case IPATH_CMD_TID_FREE:
- ret = ipath_tid_free(pd, &cmd.cmd.tid_info);
+ ret = ipath_tid_free(pd, subport_fp(fp), &cmd.cmd.tid_info);
break;
case IPATH_CMD_SET_PART_KEY:
ret = ipath_set_part_key(pd, cmd.cmd.part_key);
break;
+ case IPATH_CMD_SLAVE_INFO:
+ ret = ipath_get_slave_info(pd,
+ (void __user *) (unsigned long)
+ cmd.cmd.slave_mask_addr);
+ break;
}
if (ret >= 0)
@@ -1858,4 +2339,3 @@ void ipath_user_remove(struct ipath_devdata *dd)
bail:
return;
}
-
diff --git a/drivers/infiniband/hw/ipath/ipath_fs.c b/drivers/infiniband/hw/ipath/ipath_fs.c
index c8a8af0fe471..d9ff283f725e 100644
--- a/drivers/infiniband/hw/ipath/ipath_fs.c
+++ b/drivers/infiniband/hw/ipath/ipath_fs.c
@@ -66,8 +66,8 @@ static int ipathfs_mknod(struct inode *dir, struct dentry *dentry,
inode->i_private = data;
if ((mode & S_IFMT) == S_IFDIR) {
inode->i_op = &simple_dir_inode_operations;
- inode->i_nlink++;
- dir->i_nlink++;
+ inc_nlink(inode);
+ inc_nlink(dir);
}
inode->i_fop = fops;
@@ -356,19 +356,16 @@ static ssize_t flash_write(struct file *file, const char __user *buf,
pos = *ppos;
- if ( pos < 0) {
+ if (pos != 0) {
ret = -EINVAL;
goto bail;
}
- if (pos >= sizeof(struct ipath_flash)) {
- ret = 0;
+ if (count != sizeof(struct ipath_flash)) {
+ ret = -EINVAL;
goto bail;
}
- if (count > sizeof(struct ipath_flash) - pos)
- count = sizeof(struct ipath_flash) - pos;
-
tmp = kmalloc(count, GFP_KERNEL);
if (!tmp) {
ret = -ENOMEM;
diff --git a/drivers/infiniband/hw/ipath/ipath_iba6110.c b/drivers/infiniband/hw/ipath/ipath_iba6110.c
index 5c9b509e40e4..9e4e8d4c6e20 100644
--- a/drivers/infiniband/hw/ipath/ipath_iba6110.c
+++ b/drivers/infiniband/hw/ipath/ipath_iba6110.c
@@ -252,8 +252,8 @@ static const struct ipath_cregs ipath_ht_cregs = {
};
/* kr_intstatus, kr_intclear, kr_intmask bits */
-#define INFINIPATH_I_RCVURG_MASK 0x1FF
-#define INFINIPATH_I_RCVAVAIL_MASK 0x1FF
+#define INFINIPATH_I_RCVURG_MASK ((1U<<9)-1)
+#define INFINIPATH_I_RCVAVAIL_MASK ((1U<<9)-1)
/* kr_hwerrclear, kr_hwerrmask, kr_hwerrstatus, bits */
#define INFINIPATH_HWE_HTCMEMPARITYERR_SHIFT 0
@@ -338,7 +338,7 @@ static void hwerr_crcbits(struct ipath_devdata *dd, ipath_err_t hwerrs,
if (crcbits) {
u16 ctrl0, ctrl1;
snprintf(bitsmsg, sizeof bitsmsg,
- "[HT%s lane %s CRC (%llx); ignore till reload]",
+ "[HT%s lane %s CRC (%llx); powercycle to completely clear]",
!(crcbits & _IPATH_HTLINK1_CRCBITS) ?
"0 (A)" : (!(crcbits & _IPATH_HTLINK0_CRCBITS)
? "1 (B)" : "0+1 (A+B)"),
@@ -389,17 +389,28 @@ static void hwerr_crcbits(struct ipath_devdata *dd, ipath_err_t hwerrs,
_IPATH_HTLINK1_CRCBITS)));
}
+/* 6110 specific hardware errors... */
+static const struct ipath_hwerror_msgs ipath_6110_hwerror_msgs[] = {
+ INFINIPATH_HWE_MSG(HTCBUSIREQPARITYERR, "HTC Ireq Parity"),
+ INFINIPATH_HWE_MSG(HTCBUSTREQPARITYERR, "HTC Treq Parity"),
+ INFINIPATH_HWE_MSG(HTCBUSTRESPPARITYERR, "HTC Tresp Parity"),
+ INFINIPATH_HWE_MSG(HTCMISCERR5, "HT core Misc5"),
+ INFINIPATH_HWE_MSG(HTCMISCERR6, "HT core Misc6"),
+ INFINIPATH_HWE_MSG(HTCMISCERR7, "HT core Misc7"),
+ INFINIPATH_HWE_MSG(RXDSYNCMEMPARITYERR, "Rx Dsync"),
+ INFINIPATH_HWE_MSG(SERDESPLLFAILED, "SerDes PLL"),
+};
+
/**
- * ipath_ht_handle_hwerrors - display hardware errors
+ * ipath_ht_handle_hwerrors - display hardware errors.
* @dd: the infinipath device
* @msg: the output buffer
* @msgl: the size of the output buffer
*
- * Use same msg buffer as regular errors to avoid
- * excessive stack use. Most hardware errors are catastrophic, but for
- * right now, we'll print them and continue.
- * We reuse the same message buffer as ipath_handle_errors() to avoid
- * excessive stack usage.
+ * Use same msg buffer as regular errors to avoid excessive stack
+ * use. Most hardware errors are catastrophic, but for right now,
+ * we'll print them and continue. We reuse the same message buffer as
+ * ipath_handle_errors() to avoid excessive stack usage.
*/
static void ipath_ht_handle_hwerrors(struct ipath_devdata *dd, char *msg,
size_t msgl)
@@ -440,19 +451,49 @@ static void ipath_ht_handle_hwerrors(struct ipath_devdata *dd, char *msg,
* make sure we get this much out, unless told to be quiet,
* or it's occurred within the last 5 seconds
*/
- if ((hwerrs & ~dd->ipath_lasthwerror) ||
+ if ((hwerrs & ~(dd->ipath_lasthwerror |
+ ((INFINIPATH_HWE_TXEMEMPARITYERR_PIOBUF |
+ INFINIPATH_HWE_TXEMEMPARITYERR_PIOPBC)
+ << INFINIPATH_HWE_TXEMEMPARITYERR_SHIFT))) ||
(ipath_debug & __IPATH_VERBDBG))
dev_info(&dd->pcidev->dev, "Hardware error: hwerr=0x%llx "
"(cleared)\n", (unsigned long long) hwerrs);
dd->ipath_lasthwerror |= hwerrs;
- if (hwerrs & ~infinipath_hwe_bitsextant)
+ if (hwerrs & ~dd->ipath_hwe_bitsextant)
ipath_dev_err(dd, "hwerror interrupt with unknown errors "
"%llx set\n", (unsigned long long)
- (hwerrs & ~infinipath_hwe_bitsextant));
+ (hwerrs & ~dd->ipath_hwe_bitsextant));
ctrl = ipath_read_kreg32(dd, dd->ipath_kregs->kr_control);
if (ctrl & INFINIPATH_C_FREEZEMODE) {
+ /*
+ * parity errors in send memory are recoverable,
+ * just cancel the send (if indicated in * sendbuffererror),
+ * count the occurrence, unfreeze (if no other handled
+ * hardware error bits are set), and continue. They can
+ * occur if a processor speculative read is done to the PIO
+ * buffer while we are sending a packet, for example.
+ */
+ if (hwerrs & ((INFINIPATH_HWE_TXEMEMPARITYERR_PIOBUF |
+ INFINIPATH_HWE_TXEMEMPARITYERR_PIOPBC)
+ << INFINIPATH_HWE_TXEMEMPARITYERR_SHIFT)) {
+ ipath_stats.sps_txeparity++;
+ ipath_dbg("Recovering from TXE parity error (%llu), "
+ "hwerrstatus=%llx\n",
+ (unsigned long long) ipath_stats.sps_txeparity,
+ (unsigned long long) hwerrs);
+ ipath_disarm_senderrbufs(dd);
+ hwerrs &= ~((INFINIPATH_HWE_TXEMEMPARITYERR_PIOBUF |
+ INFINIPATH_HWE_TXEMEMPARITYERR_PIOPBC)
+ << INFINIPATH_HWE_TXEMEMPARITYERR_SHIFT);
+ if (!hwerrs) { /* else leave in freeze mode */
+ ipath_write_kreg(dd,
+ dd->ipath_kregs->kr_control,
+ dd->ipath_control);
+ return;
+ }
+ }
if (hwerrs) {
/*
* if any set that we aren't ignoring; only
@@ -499,44 +540,16 @@ static void ipath_ht_handle_hwerrors(struct ipath_devdata *dd, char *msg,
bits);
strlcat(msg, bitsmsg, msgl);
}
- if (hwerrs & (INFINIPATH_HWE_RXEMEMPARITYERR_MASK
- << INFINIPATH_HWE_RXEMEMPARITYERR_SHIFT)) {
- bits = (u32) ((hwerrs >>
- INFINIPATH_HWE_RXEMEMPARITYERR_SHIFT) &
- INFINIPATH_HWE_RXEMEMPARITYERR_MASK);
- snprintf(bitsmsg, sizeof bitsmsg, "[RXE Parity Errs %x] ",
- bits);
- strlcat(msg, bitsmsg, msgl);
- }
- if (hwerrs & (INFINIPATH_HWE_TXEMEMPARITYERR_MASK
- << INFINIPATH_HWE_TXEMEMPARITYERR_SHIFT)) {
- bits = (u32) ((hwerrs >>
- INFINIPATH_HWE_TXEMEMPARITYERR_SHIFT) &
- INFINIPATH_HWE_TXEMEMPARITYERR_MASK);
- snprintf(bitsmsg, sizeof bitsmsg, "[TXE Parity Errs %x] ",
- bits);
- strlcat(msg, bitsmsg, msgl);
- }
- if (hwerrs & INFINIPATH_HWE_IBCBUSTOSPCPARITYERR)
- strlcat(msg, "[IB2IPATH Parity]", msgl);
- if (hwerrs & INFINIPATH_HWE_IBCBUSFRSPCPARITYERR)
- strlcat(msg, "[IPATH2IB Parity]", msgl);
- if (hwerrs & INFINIPATH_HWE_HTCBUSIREQPARITYERR)
- strlcat(msg, "[HTC Ireq Parity]", msgl);
- if (hwerrs & INFINIPATH_HWE_HTCBUSTREQPARITYERR)
- strlcat(msg, "[HTC Treq Parity]", msgl);
- if (hwerrs & INFINIPATH_HWE_HTCBUSTRESPPARITYERR)
- strlcat(msg, "[HTC Tresp Parity]", msgl);
+
+ ipath_format_hwerrors(hwerrs,
+ ipath_6110_hwerror_msgs,
+ sizeof(ipath_6110_hwerror_msgs) /
+ sizeof(ipath_6110_hwerror_msgs[0]),
+ msg, msgl);
if (hwerrs & (_IPATH_HTLINK0_CRCBITS | _IPATH_HTLINK1_CRCBITS))
hwerr_crcbits(dd, hwerrs, msg, msgl);
- if (hwerrs & INFINIPATH_HWE_HTCMISCERR5)
- strlcat(msg, "[HT core Misc5]", msgl);
- if (hwerrs & INFINIPATH_HWE_HTCMISCERR6)
- strlcat(msg, "[HT core Misc6]", msgl);
- if (hwerrs & INFINIPATH_HWE_HTCMISCERR7)
- strlcat(msg, "[HT core Misc7]", msgl);
if (hwerrs & INFINIPATH_HWE_MEMBISTFAILED) {
strlcat(msg, "[Memory BIST test failed, InfiniPath hardware unusable]",
msgl);
@@ -573,11 +586,6 @@ static void ipath_ht_handle_hwerrors(struct ipath_devdata *dd, char *msg,
dd->ipath_hwerrmask);
}
- if (hwerrs & INFINIPATH_HWE_RXDSYNCMEMPARITYERR)
- strlcat(msg, "[Rx Dsync]", msgl);
- if (hwerrs & INFINIPATH_HWE_SERDESPLLFAILED)
- strlcat(msg, "[SerDes PLL]", msgl);
-
ipath_dev_err(dd, "%s hardware error\n", msg);
if (isfatal && !ipath_diag_inuse && dd->ipath_freezemsg)
/*
@@ -1080,21 +1088,21 @@ static void ipath_setup_ht_setextled(struct ipath_devdata *dd,
ipath_write_kreg(dd, dd->ipath_kregs->kr_extctrl, extctl);
}
-static void ipath_init_ht_variables(void)
+static void ipath_init_ht_variables(struct ipath_devdata *dd)
{
- ipath_gpio_sda_num = _IPATH_GPIO_SDA_NUM;
- ipath_gpio_scl_num = _IPATH_GPIO_SCL_NUM;
- ipath_gpio_sda = IPATH_GPIO_SDA;
- ipath_gpio_scl = IPATH_GPIO_SCL;
+ dd->ipath_gpio_sda_num = _IPATH_GPIO_SDA_NUM;
+ dd->ipath_gpio_scl_num = _IPATH_GPIO_SCL_NUM;
+ dd->ipath_gpio_sda = IPATH_GPIO_SDA;
+ dd->ipath_gpio_scl = IPATH_GPIO_SCL;
- infinipath_i_bitsextant =
+ dd->ipath_i_bitsextant =
(INFINIPATH_I_RCVURG_MASK << INFINIPATH_I_RCVURG_SHIFT) |
(INFINIPATH_I_RCVAVAIL_MASK <<
INFINIPATH_I_RCVAVAIL_SHIFT) |
INFINIPATH_I_ERROR | INFINIPATH_I_SPIOSENT |
INFINIPATH_I_SPIOBUFAVAIL | INFINIPATH_I_GPIO;
- infinipath_e_bitsextant =
+ dd->ipath_e_bitsextant =
INFINIPATH_E_RFORMATERR | INFINIPATH_E_RVCRC |
INFINIPATH_E_RICRC | INFINIPATH_E_RMINPKTLEN |
INFINIPATH_E_RMAXPKTLEN | INFINIPATH_E_RLONGPKTLEN |
@@ -1112,7 +1120,7 @@ static void ipath_init_ht_variables(void)
INFINIPATH_E_INVALIDADDR | INFINIPATH_E_RESET |
INFINIPATH_E_HARDWARE;
- infinipath_hwe_bitsextant =
+ dd->ipath_hwe_bitsextant =
(INFINIPATH_HWE_HTCMEMPARITYERR_MASK <<
INFINIPATH_HWE_HTCMEMPARITYERR_SHIFT) |
(INFINIPATH_HWE_TXEMEMPARITYERR_MASK <<
@@ -1141,8 +1149,8 @@ static void ipath_init_ht_variables(void)
INFINIPATH_HWE_IBCBUSTOSPCPARITYERR |
INFINIPATH_HWE_IBCBUSFRSPCPARITYERR;
- infinipath_i_rcvavail_mask = INFINIPATH_I_RCVAVAIL_MASK;
- infinipath_i_rcvurg_mask = INFINIPATH_I_RCVURG_MASK;
+ dd->ipath_i_rcvavail_mask = INFINIPATH_I_RCVAVAIL_MASK;
+ dd->ipath_i_rcvurg_mask = INFINIPATH_I_RCVURG_MASK;
}
/**
@@ -1607,5 +1615,5 @@ void ipath_init_iba6110_funcs(struct ipath_devdata *dd)
* do very early init that is needed before ipath_f_bus is
* called
*/
- ipath_init_ht_variables();
+ ipath_init_ht_variables(dd);
}
diff --git a/drivers/infiniband/hw/ipath/ipath_iba6120.c b/drivers/infiniband/hw/ipath/ipath_iba6120.c
index d86516d23df6..a72ab9de386a 100644
--- a/drivers/infiniband/hw/ipath/ipath_iba6120.c
+++ b/drivers/infiniband/hw/ipath/ipath_iba6120.c
@@ -263,8 +263,8 @@ static const struct ipath_cregs ipath_pe_cregs = {
};
/* kr_intstatus, kr_intclear, kr_intmask bits */
-#define INFINIPATH_I_RCVURG_MASK 0x1F
-#define INFINIPATH_I_RCVAVAIL_MASK 0x1F
+#define INFINIPATH_I_RCVURG_MASK ((1U<<5)-1)
+#define INFINIPATH_I_RCVAVAIL_MASK ((1U<<5)-1)
/* kr_hwerrclear, kr_hwerrmask, kr_hwerrstatus, bits */
#define INFINIPATH_HWE_PCIEMEMPARITYERR_MASK 0x000000000000003fULL
@@ -294,6 +294,33 @@ static const struct ipath_cregs ipath_pe_cregs = {
#define IPATH_GPIO_SCL (1ULL << \
(_IPATH_GPIO_SCL_NUM+INFINIPATH_EXTC_GPIOOE_SHIFT))
+/*
+ * Rev2 silicon allows suppressing check for ArmLaunch errors.
+ * this can speed up short packet sends on systems that do
+ * not guaranteee write-order.
+ */
+#define INFINIPATH_XGXS_SUPPRESS_ARMLAUNCH_ERR (1ULL<<63)
+
+/* 6120 specific hardware errors... */
+static const struct ipath_hwerror_msgs ipath_6120_hwerror_msgs[] = {
+ INFINIPATH_HWE_MSG(PCIEPOISONEDTLP, "PCIe Poisoned TLP"),
+ INFINIPATH_HWE_MSG(PCIECPLTIMEOUT, "PCIe completion timeout"),
+ /*
+ * In practice, it's unlikely wthat we'll see PCIe PLL, or bus
+ * parity or memory parity error failures, because most likely we
+ * won't be able to talk to the core of the chip. Nonetheless, we
+ * might see them, if they are in parts of the PCIe core that aren't
+ * essential.
+ */
+ INFINIPATH_HWE_MSG(PCIE1PLLFAILED, "PCIePLL1"),
+ INFINIPATH_HWE_MSG(PCIE0PLLFAILED, "PCIePLL0"),
+ INFINIPATH_HWE_MSG(PCIEBUSPARITYXTLH, "PCIe XTLH core parity"),
+ INFINIPATH_HWE_MSG(PCIEBUSPARITYXADM, "PCIe ADM TX core parity"),
+ INFINIPATH_HWE_MSG(PCIEBUSPARITYRADM, "PCIe ADM RX core parity"),
+ INFINIPATH_HWE_MSG(RXDSYNCMEMPARITYERR, "Rx Dsync"),
+ INFINIPATH_HWE_MSG(SERDESPLLFAILED, "SerDes PLL"),
+};
+
/**
* ipath_pe_handle_hwerrors - display hardware errors.
* @dd: the infinipath device
@@ -343,19 +370,49 @@ static void ipath_pe_handle_hwerrors(struct ipath_devdata *dd, char *msg,
* make sure we get this much out, unless told to be quiet,
* or it's occurred within the last 5 seconds
*/
- if ((hwerrs & ~dd->ipath_lasthwerror) ||
+ if ((hwerrs & ~(dd->ipath_lasthwerror |
+ ((INFINIPATH_HWE_TXEMEMPARITYERR_PIOBUF |
+ INFINIPATH_HWE_TXEMEMPARITYERR_PIOPBC)
+ << INFINIPATH_HWE_TXEMEMPARITYERR_SHIFT))) ||
(ipath_debug & __IPATH_VERBDBG))
dev_info(&dd->pcidev->dev, "Hardware error: hwerr=0x%llx "
"(cleared)\n", (unsigned long long) hwerrs);
dd->ipath_lasthwerror |= hwerrs;
- if (hwerrs & ~infinipath_hwe_bitsextant)
+ if (hwerrs & ~dd->ipath_hwe_bitsextant)
ipath_dev_err(dd, "hwerror interrupt with unknown errors "
"%llx set\n", (unsigned long long)
- (hwerrs & ~infinipath_hwe_bitsextant));
+ (hwerrs & ~dd->ipath_hwe_bitsextant));
ctrl = ipath_read_kreg32(dd, dd->ipath_kregs->kr_control);
if (ctrl & INFINIPATH_C_FREEZEMODE) {
+ /*
+ * parity errors in send memory are recoverable,
+ * just cancel the send (if indicated in * sendbuffererror),
+ * count the occurrence, unfreeze (if no other handled
+ * hardware error bits are set), and continue. They can
+ * occur if a processor speculative read is done to the PIO
+ * buffer while we are sending a packet, for example.
+ */
+ if (hwerrs & ((INFINIPATH_HWE_TXEMEMPARITYERR_PIOBUF |
+ INFINIPATH_HWE_TXEMEMPARITYERR_PIOPBC)
+ << INFINIPATH_HWE_TXEMEMPARITYERR_SHIFT)) {
+ ipath_stats.sps_txeparity++;
+ ipath_dbg("Recovering from TXE parity error (%llu), "
+ "hwerrstatus=%llx\n",
+ (unsigned long long) ipath_stats.sps_txeparity,
+ (unsigned long long) hwerrs);
+ ipath_disarm_senderrbufs(dd);
+ hwerrs &= ~((INFINIPATH_HWE_TXEMEMPARITYERR_PIOBUF |
+ INFINIPATH_HWE_TXEMEMPARITYERR_PIOPBC)
+ << INFINIPATH_HWE_TXEMEMPARITYERR_SHIFT);
+ if (!hwerrs) { /* else leave in freeze mode */
+ ipath_write_kreg(dd,
+ dd->ipath_kregs->kr_control,
+ dd->ipath_control);
+ return;
+ }
+ }
if (hwerrs) {
/*
* if any set that we aren't ignoring only make the
@@ -379,9 +436,8 @@ static void ipath_pe_handle_hwerrors(struct ipath_devdata *dd, char *msg,
} else {
ipath_dbg("Clearing freezemode on ignored hardware "
"error\n");
- ctrl &= ~INFINIPATH_C_FREEZEMODE;
ipath_write_kreg(dd, dd->ipath_kregs->kr_control,
- ctrl);
+ dd->ipath_control);
}
}
@@ -396,24 +452,13 @@ static void ipath_pe_handle_hwerrors(struct ipath_devdata *dd, char *msg,
ipath_write_kreg(dd, dd->ipath_kregs->kr_hwerrmask,
dd->ipath_hwerrmask);
}
- if (hwerrs & (INFINIPATH_HWE_RXEMEMPARITYERR_MASK
- << INFINIPATH_HWE_RXEMEMPARITYERR_SHIFT)) {
- bits = (u32) ((hwerrs >>
- INFINIPATH_HWE_RXEMEMPARITYERR_SHIFT) &
- INFINIPATH_HWE_RXEMEMPARITYERR_MASK);
- snprintf(bitsmsg, sizeof bitsmsg, "[RXE Parity Errs %x] ",
- bits);
- strlcat(msg, bitsmsg, msgl);
- }
- if (hwerrs & (INFINIPATH_HWE_TXEMEMPARITYERR_MASK
- << INFINIPATH_HWE_TXEMEMPARITYERR_SHIFT)) {
- bits = (u32) ((hwerrs >>
- INFINIPATH_HWE_TXEMEMPARITYERR_SHIFT) &
- INFINIPATH_HWE_TXEMEMPARITYERR_MASK);
- snprintf(bitsmsg, sizeof bitsmsg, "[TXE Parity Errs %x] ",
- bits);
- strlcat(msg, bitsmsg, msgl);
- }
+
+ ipath_format_hwerrors(hwerrs,
+ ipath_6120_hwerror_msgs,
+ sizeof(ipath_6120_hwerror_msgs)/
+ sizeof(ipath_6120_hwerror_msgs[0]),
+ msg, msgl);
+
if (hwerrs & (INFINIPATH_HWE_PCIEMEMPARITYERR_MASK
<< INFINIPATH_HWE_PCIEMEMPARITYERR_SHIFT)) {
bits = (u32) ((hwerrs >>
@@ -423,10 +468,6 @@ static void ipath_pe_handle_hwerrors(struct ipath_devdata *dd, char *msg,
"[PCIe Mem Parity Errs %x] ", bits);
strlcat(msg, bitsmsg, msgl);
}
- if (hwerrs & INFINIPATH_HWE_IBCBUSTOSPCPARITYERR)
- strlcat(msg, "[IB2IPATH Parity]", msgl);
- if (hwerrs & INFINIPATH_HWE_IBCBUSFRSPCPARITYERR)
- strlcat(msg, "[IPATH2IB Parity]", msgl);
#define _IPATH_PLL_FAIL (INFINIPATH_HWE_COREPLL_FBSLIP | \
INFINIPATH_HWE_COREPLL_RFSLIP )
@@ -452,34 +493,6 @@ static void ipath_pe_handle_hwerrors(struct ipath_devdata *dd, char *msg,
dd->ipath_hwerrmask);
}
- if (hwerrs & INFINIPATH_HWE_PCIEPOISONEDTLP)
- strlcat(msg, "[PCIe Poisoned TLP]", msgl);
- if (hwerrs & INFINIPATH_HWE_PCIECPLTIMEOUT)
- strlcat(msg, "[PCIe completion timeout]", msgl);
-
- /*
- * In practice, it's unlikely wthat we'll see PCIe PLL, or bus
- * parity or memory parity error failures, because most likely we
- * won't be able to talk to the core of the chip. Nonetheless, we
- * might see them, if they are in parts of the PCIe core that aren't
- * essential.
- */
- if (hwerrs & INFINIPATH_HWE_PCIE1PLLFAILED)
- strlcat(msg, "[PCIePLL1]", msgl);
- if (hwerrs & INFINIPATH_HWE_PCIE0PLLFAILED)
- strlcat(msg, "[PCIePLL0]", msgl);
- if (hwerrs & INFINIPATH_HWE_PCIEBUSPARITYXTLH)
- strlcat(msg, "[PCIe XTLH core parity]", msgl);
- if (hwerrs & INFINIPATH_HWE_PCIEBUSPARITYXADM)
- strlcat(msg, "[PCIe ADM TX core parity]", msgl);
- if (hwerrs & INFINIPATH_HWE_PCIEBUSPARITYRADM)
- strlcat(msg, "[PCIe ADM RX core parity]", msgl);
-
- if (hwerrs & INFINIPATH_HWE_RXDSYNCMEMPARITYERR)
- strlcat(msg, "[Rx Dsync]", msgl);
- if (hwerrs & INFINIPATH_HWE_SERDESPLLFAILED)
- strlcat(msg, "[SerDes PLL]", msgl);
-
ipath_dev_err(dd, "%s hardware error\n", msg);
if (isfatal && !ipath_diag_inuse && dd->ipath_freezemsg) {
/*
@@ -525,6 +538,9 @@ static int ipath_pe_boardname(struct ipath_devdata *dd, char *name,
case 5:
n = "InfiniPath_QMH7140";
break;
+ case 6:
+ n = "InfiniPath_QLE7142";
+ break;
default:
ipath_dev_err(dd,
"Don't yet know about board with ID %u\n",
@@ -571,9 +587,12 @@ static void ipath_pe_init_hwerrors(struct ipath_devdata *dd)
if (!dd->ipath_boardrev) // no PLL for Emulator
val &= ~INFINIPATH_HWE_SERDESPLLFAILED;
- /* workaround bug 9460 in internal interface bus parity checking */
- val &= ~INFINIPATH_HWE_PCIEBUSPARITYRADM;
-
+ if (dd->ipath_minrev < 2) {
+ /* workaround bug 9460 in internal interface bus parity
+ * checking. Fixed (HW bug 9490) in Rev2.
+ */
+ val &= ~INFINIPATH_HWE_PCIEBUSPARITYRADM;
+ }
dd->ipath_hwerrmask = val;
}
@@ -583,8 +602,8 @@ static void ipath_pe_init_hwerrors(struct ipath_devdata *dd)
*/
static int ipath_pe_bringup_serdes(struct ipath_devdata *dd)
{
- u64 val, tmp, config1;
- int ret = 0, change = 0;
+ u64 val, tmp, config1, prev_val;
+ int ret = 0;
ipath_dbg("Trying to bringup serdes\n");
@@ -641,6 +660,7 @@ static int ipath_pe_bringup_serdes(struct ipath_devdata *dd)
val = ipath_read_kreg64(dd, dd->ipath_kregs->kr_scratch);
val = ipath_read_kreg64(dd, dd->ipath_kregs->kr_xgxsconfig);
+ prev_val = val;
if (((val >> INFINIPATH_XGXS_MDIOADDR_SHIFT) &
INFINIPATH_XGXS_MDIOADDR_MASK) != 3) {
val &=
@@ -648,11 +668,9 @@ static int ipath_pe_bringup_serdes(struct ipath_devdata *dd)
INFINIPATH_XGXS_MDIOADDR_SHIFT);
/* MDIO address 3 */
val |= 3ULL << INFINIPATH_XGXS_MDIOADDR_SHIFT;
- change = 1;
}
if (val & INFINIPATH_XGXS_RESET) {
val &= ~INFINIPATH_XGXS_RESET;
- change = 1;
}
if (((val >> INFINIPATH_XGXS_RX_POL_SHIFT) &
INFINIPATH_XGXS_RX_POL_MASK) != dd->ipath_rx_pol_inv ) {
@@ -661,9 +679,19 @@ static int ipath_pe_bringup_serdes(struct ipath_devdata *dd)
INFINIPATH_XGXS_RX_POL_SHIFT);
val |= dd->ipath_rx_pol_inv <<
INFINIPATH_XGXS_RX_POL_SHIFT;
- change = 1;
}
- if (change)
+ if (dd->ipath_minrev >= 2) {
+ /* Rev 2. can tolerate multiple writes to PBC, and
+ * allowing them can provide lower latency on some
+ * CPUs, but this feature is off by default, only
+ * turned on by setting D63 of XGXSconfig reg.
+ * May want to make this conditional more
+ * fine-grained in future. This is not exactly
+ * related to XGXS, but where the bit ended up.
+ */
+ val |= INFINIPATH_XGXS_SUPPRESS_ARMLAUNCH_ERR;
+ }
+ if (val != prev_val)
ipath_write_kreg(dd, dd->ipath_kregs->kr_xgxsconfig, val);
val = ipath_read_kreg64(dd, dd->ipath_kregs->kr_serdesconfig0);
@@ -717,9 +745,25 @@ static void ipath_pe_quiet_serdes(struct ipath_devdata *dd)
ipath_write_kreg(dd, dd->ipath_kregs->kr_serdesconfig0, val);
}
-/* this is not yet needed on this chip, so just return 0. */
static int ipath_pe_intconfig(struct ipath_devdata *dd)
{
+ u64 val;
+ u32 chiprev;
+
+ /*
+ * If the chip supports added error indication via GPIO pins,
+ * enable interrupts on those bits so the interrupt routine
+ * can count the events. Also set flag so interrupt routine
+ * can know they are expected.
+ */
+ chiprev = dd->ipath_revision >> INFINIPATH_R_CHIPREVMINOR_SHIFT;
+ if ((chiprev & INFINIPATH_R_CHIPREVMINOR_MASK) > 1) {
+ /* Rev2+ reports extra errors via internal GPIO pins */
+ dd->ipath_flags |= IPATH_GPIO_ERRINTRS;
+ val = ipath_read_kreg64(dd, dd->ipath_kregs->kr_gpio_mask);
+ val |= IPATH_GPIO_ERRINTR_MASK;
+ ipath_write_kreg( dd, dd->ipath_kregs->kr_gpio_mask, val);
+ }
return 0;
}
@@ -853,21 +897,23 @@ static int ipath_setup_pe_config(struct ipath_devdata *dd,
return 0;
}
-static void ipath_init_pe_variables(void)
+static void ipath_init_pe_variables(struct ipath_devdata *dd)
{
/*
* bits for selecting i2c direction and values,
* used for I2C serial flash
*/
- ipath_gpio_sda_num = _IPATH_GPIO_SDA_NUM;
- ipath_gpio_scl_num = _IPATH_GPIO_SCL_NUM;
- ipath_gpio_sda = IPATH_GPIO_SDA;
- ipath_gpio_scl = IPATH_GPIO_SCL;
+ dd->ipath_gpio_sda_num = _IPATH_GPIO_SDA_NUM;
+ dd->ipath_gpio_scl_num = _IPATH_GPIO_SCL_NUM;
+ dd->ipath_gpio_sda = IPATH_GPIO_SDA;
+ dd->ipath_gpio_scl = IPATH_GPIO_SCL;
/* variables for sanity checking interrupt and errors */
- infinipath_hwe_bitsextant =
+ dd->ipath_hwe_bitsextant =
(INFINIPATH_HWE_RXEMEMPARITYERR_MASK <<
INFINIPATH_HWE_RXEMEMPARITYERR_SHIFT) |
+ (INFINIPATH_HWE_TXEMEMPARITYERR_MASK <<
+ INFINIPATH_HWE_TXEMEMPARITYERR_SHIFT) |
(INFINIPATH_HWE_PCIEMEMPARITYERR_MASK <<
INFINIPATH_HWE_PCIEMEMPARITYERR_SHIFT) |
INFINIPATH_HWE_PCIE1PLLFAILED |
@@ -883,13 +929,13 @@ static void ipath_init_pe_variables(void)
INFINIPATH_HWE_SERDESPLLFAILED |
INFINIPATH_HWE_IBCBUSTOSPCPARITYERR |
INFINIPATH_HWE_IBCBUSFRSPCPARITYERR;
- infinipath_i_bitsextant =
+ dd->ipath_i_bitsextant =
(INFINIPATH_I_RCVURG_MASK << INFINIPATH_I_RCVURG_SHIFT) |
(INFINIPATH_I_RCVAVAIL_MASK <<
INFINIPATH_I_RCVAVAIL_SHIFT) |
INFINIPATH_I_ERROR | INFINIPATH_I_SPIOSENT |
INFINIPATH_I_SPIOBUFAVAIL | INFINIPATH_I_GPIO;
- infinipath_e_bitsextant =
+ dd->ipath_e_bitsextant =
INFINIPATH_E_RFORMATERR | INFINIPATH_E_RVCRC |
INFINIPATH_E_RICRC | INFINIPATH_E_RMINPKTLEN |
INFINIPATH_E_RMAXPKTLEN | INFINIPATH_E_RLONGPKTLEN |
@@ -907,8 +953,8 @@ static void ipath_init_pe_variables(void)
INFINIPATH_E_INVALIDADDR | INFINIPATH_E_RESET |
INFINIPATH_E_HARDWARE;
- infinipath_i_rcvavail_mask = INFINIPATH_I_RCVAVAIL_MASK;
- infinipath_i_rcvurg_mask = INFINIPATH_I_RCVURG_MASK;
+ dd->ipath_i_rcvavail_mask = INFINIPATH_I_RCVAVAIL_MASK;
+ dd->ipath_i_rcvurg_mask = INFINIPATH_I_RCVURG_MASK;
}
/* setup the MSI stuff again after a reset. I'd like to just call
@@ -1082,6 +1128,45 @@ static void ipath_pe_put_tid(struct ipath_devdata *dd, u64 __iomem *tidptr,
mmiowb();
spin_unlock_irqrestore(&dd->ipath_tid_lock, flags);
}
+/**
+ * ipath_pe_put_tid_2 - write a TID in chip, Revision 2 or higher
+ * @dd: the infinipath device
+ * @tidptr: pointer to the expected TID (in chip) to udpate
+ * @tidtype: 0 for eager, 1 for expected
+ * @pa: physical address of in memory buffer; ipath_tidinvalid if freeing
+ *
+ * This exists as a separate routine to allow for selection of the
+ * appropriate "flavor". The static calls in cleanup just use the
+ * revision-agnostic form, as they are not performance critical.
+ */
+static void ipath_pe_put_tid_2(struct ipath_devdata *dd, u64 __iomem *tidptr,
+ u32 type, unsigned long pa)
+{
+ u32 __iomem *tidp32 = (u32 __iomem *)tidptr;
+
+ if (pa != dd->ipath_tidinvalid) {
+ if (pa & ((1U << 11) - 1)) {
+ dev_info(&dd->pcidev->dev, "BUG: physaddr %lx "
+ "not 2KB aligned!\n", pa);
+ return;
+ }
+ pa >>= 11;
+ /* paranoia check */
+ if (pa & (7<<29))
+ ipath_dev_err(dd,
+ "BUG: Physical page address 0x%lx "
+ "has bits set in 31-29\n", pa);
+
+ if (type == 0)
+ pa |= dd->ipath_tidtemplate;
+ else /* for now, always full 4KB page */
+ pa |= 2 << 29;
+ }
+ if (dd->ipath_kregbase)
+ writel(pa, tidp32);
+ mmiowb();
+}
+
/**
* ipath_pe_clear_tid - clear all TID entries for a port, expected and eager
@@ -1203,7 +1288,7 @@ int __attribute__((weak)) ipath_unordered_wc(void)
/**
* ipath_init_pe_get_base_info - set chip-specific flags for user code
- * @dd: the infinipath device
+ * @pd: the infinipath port
* @kbase: ipath_base_info pointer
*
* We set the PCIE flag because the lower bandwidth on PCIe vs
@@ -1212,6 +1297,7 @@ int __attribute__((weak)) ipath_unordered_wc(void)
static int ipath_pe_get_base_info(struct ipath_portdata *pd, void *kbase)
{
struct ipath_base_info *kinfo = kbase;
+ struct ipath_devdata *dd;
if (ipath_unordered_wc()) {
kinfo->spi_runtime_flags |= IPATH_RUNTIME_FORCE_WC_ORDER;
@@ -1220,8 +1306,20 @@ static int ipath_pe_get_base_info(struct ipath_portdata *pd, void *kbase)
else
ipath_cdbg(PROC, "Not Intel processor, WC ordered\n");
- kinfo->spi_runtime_flags |= IPATH_RUNTIME_PCIE;
+ if (pd == NULL)
+ goto done;
+ dd = pd->port_dd;
+
+ if (dd != NULL && dd->ipath_minrev >= 2) {
+ ipath_cdbg(PROC, "IBA6120 Rev2, allow multiple PBC write\n");
+ kinfo->spi_runtime_flags |= IPATH_RUNTIME_PBC_REWRITE;
+ ipath_cdbg(PROC, "IBA6120 Rev2, allow loose DMA alignment\n");
+ kinfo->spi_runtime_flags |= IPATH_RUNTIME_LOOSE_DMA_ALIGN;
+ }
+
+done:
+ kinfo->spi_runtime_flags |= IPATH_RUNTIME_PCIE;
return 0;
}
@@ -1244,7 +1342,10 @@ void ipath_init_iba6120_funcs(struct ipath_devdata *dd)
dd->ipath_f_quiet_serdes = ipath_pe_quiet_serdes;
dd->ipath_f_bringup_serdes = ipath_pe_bringup_serdes;
dd->ipath_f_clear_tids = ipath_pe_clear_tids;
- dd->ipath_f_put_tid = ipath_pe_put_tid;
+ if (dd->ipath_minrev >= 2)
+ dd->ipath_f_put_tid = ipath_pe_put_tid_2;
+ else
+ dd->ipath_f_put_tid = ipath_pe_put_tid;
dd->ipath_f_cleanup = ipath_setup_pe_cleanup;
dd->ipath_f_setextled = ipath_setup_pe_setextled;
dd->ipath_f_get_base_info = ipath_pe_get_base_info;
@@ -1259,6 +1360,6 @@ void ipath_init_iba6120_funcs(struct ipath_devdata *dd)
dd->ipath_kregs = &ipath_pe_kregs;
dd->ipath_cregs = &ipath_pe_cregs;
- ipath_init_pe_variables();
+ ipath_init_pe_variables(dd);
}
diff --git a/drivers/infiniband/hw/ipath/ipath_init_chip.c b/drivers/infiniband/hw/ipath/ipath_init_chip.c
index 44669dc2e22d..d819cca524cd 100644
--- a/drivers/infiniband/hw/ipath/ipath_init_chip.c
+++ b/drivers/infiniband/hw/ipath/ipath_init_chip.c
@@ -88,13 +88,13 @@ MODULE_PARM_DESC(kpiobufs, "Set number of PIO buffers for driver");
static int create_port0_egr(struct ipath_devdata *dd)
{
unsigned e, egrcnt;
- struct sk_buff **skbs;
+ struct ipath_skbinfo *skbinfo;
int ret;
egrcnt = dd->ipath_rcvegrcnt;
- skbs = vmalloc(sizeof(*dd->ipath_port0_skbs) * egrcnt);
- if (skbs == NULL) {
+ skbinfo = vmalloc(sizeof(*dd->ipath_port0_skbinfo) * egrcnt);
+ if (skbinfo == NULL) {
ipath_dev_err(dd, "allocation error for eager TID "
"skb array\n");
ret = -ENOMEM;
@@ -109,13 +109,13 @@ static int create_port0_egr(struct ipath_devdata *dd)
* 4 bytes so that the data buffer stays word aligned.
* See ipath_kreceive() for more details.
*/
- skbs[e] = ipath_alloc_skb(dd, GFP_KERNEL);
- if (!skbs[e]) {
+ skbinfo[e].skb = ipath_alloc_skb(dd, GFP_KERNEL);
+ if (!skbinfo[e].skb) {
ipath_dev_err(dd, "SKB allocation error for "
"eager TID %u\n", e);
while (e != 0)
- dev_kfree_skb(skbs[--e]);
- vfree(skbs);
+ dev_kfree_skb(skbinfo[--e].skb);
+ vfree(skbinfo);
ret = -ENOMEM;
goto bail;
}
@@ -124,14 +124,17 @@ static int create_port0_egr(struct ipath_devdata *dd)
* After loop above, so we can test non-NULL to see if ready
* to use at receive, etc.
*/
- dd->ipath_port0_skbs = skbs;
+ dd->ipath_port0_skbinfo = skbinfo;
for (e = 0; e < egrcnt; e++) {
- unsigned long phys =
- virt_to_phys(dd->ipath_port0_skbs[e]->data);
+ dd->ipath_port0_skbinfo[e].phys =
+ ipath_map_single(dd->pcidev,
+ dd->ipath_port0_skbinfo[e].skb->data,
+ dd->ipath_ibmaxlen, PCI_DMA_FROMDEVICE);
dd->ipath_f_put_tid(dd, e + (u64 __iomem *)
((char __iomem *) dd->ipath_kregbase +
- dd->ipath_rcvegrbase), 0, phys);
+ dd->ipath_rcvegrbase), 0,
+ dd->ipath_port0_skbinfo[e].phys);
}
ret = 0;
@@ -432,16 +435,33 @@ done:
*/
static void init_shadow_tids(struct ipath_devdata *dd)
{
- dd->ipath_pageshadow = (struct page **)
- vmalloc(dd->ipath_cfgports * dd->ipath_rcvtidcnt *
+ struct page **pages;
+ dma_addr_t *addrs;
+
+ pages = vmalloc(dd->ipath_cfgports * dd->ipath_rcvtidcnt *
sizeof(struct page *));
- if (!dd->ipath_pageshadow)
+ if (!pages) {
ipath_dev_err(dd, "failed to allocate shadow page * "
"array, no expected sends!\n");
- else
- memset(dd->ipath_pageshadow, 0,
- dd->ipath_cfgports * dd->ipath_rcvtidcnt *
- sizeof(struct page *));
+ dd->ipath_pageshadow = NULL;
+ return;
+ }
+
+ addrs = vmalloc(dd->ipath_cfgports * dd->ipath_rcvtidcnt *
+ sizeof(dma_addr_t));
+ if (!addrs) {
+ ipath_dev_err(dd, "failed to allocate shadow dma handle "
+ "array, no expected sends!\n");
+ vfree(dd->ipath_pageshadow);
+ dd->ipath_pageshadow = NULL;
+ return;
+ }
+
+ memset(pages, 0, dd->ipath_cfgports * dd->ipath_rcvtidcnt *
+ sizeof(struct page *));
+
+ dd->ipath_pageshadow = pages;
+ dd->ipath_physshadow = addrs;
}
static void enable_chip(struct ipath_devdata *dd,
diff --git a/drivers/infiniband/hw/ipath/ipath_intr.c b/drivers/infiniband/hw/ipath/ipath_intr.c
index 49bf7bb15b04..6bee53ce5f33 100644
--- a/drivers/infiniband/hw/ipath/ipath_intr.c
+++ b/drivers/infiniband/hw/ipath/ipath_intr.c
@@ -37,6 +37,50 @@
#include "ipath_verbs.h"
#include "ipath_common.h"
+/*
+ * Called when we might have an error that is specific to a particular
+ * PIO buffer, and may need to cancel that buffer, so it can be re-used.
+ */
+void ipath_disarm_senderrbufs(struct ipath_devdata *dd)
+{
+ u32 piobcnt;
+ unsigned long sbuf[4];
+ /*
+ * it's possible that sendbuffererror could have bits set; might
+ * have already done this as a result of hardware error handling
+ */
+ piobcnt = dd->ipath_piobcnt2k + dd->ipath_piobcnt4k;
+ /* read these before writing errorclear */
+ sbuf[0] = ipath_read_kreg64(
+ dd, dd->ipath_kregs->kr_sendbuffererror);
+ sbuf[1] = ipath_read_kreg64(
+ dd, dd->ipath_kregs->kr_sendbuffererror + 1);
+ if (piobcnt > 128) {
+ sbuf[2] = ipath_read_kreg64(
+ dd, dd->ipath_kregs->kr_sendbuffererror + 2);
+ sbuf[3] = ipath_read_kreg64(
+ dd, dd->ipath_kregs->kr_sendbuffererror + 3);
+ }
+
+ if (sbuf[0] || sbuf[1] || (piobcnt > 128 && (sbuf[2] || sbuf[3]))) {
+ int i;
+ if (ipath_debug & (__IPATH_PKTDBG|__IPATH_DBG)) {
+ __IPATH_DBG_WHICH(__IPATH_PKTDBG|__IPATH_DBG,
+ "SendbufErrs %lx %lx", sbuf[0],
+ sbuf[1]);
+ if (ipath_debug & __IPATH_PKTDBG && piobcnt > 128)
+ printk(" %lx %lx ", sbuf[2], sbuf[3]);
+ printk("\n");
+ }
+
+ for (i = 0; i < piobcnt; i++)
+ if (test_bit(i, sbuf))
+ ipath_disarm_piobufs(dd, i, 1);
+ dd->ipath_lastcancel = jiffies+3; /* no armlaunch for a bit */
+ }
+}
+
+
/* These are all rcv-related errors which we want to count for stats */
#define E_SUM_PKTERRS \
(INFINIPATH_E_RHDRLEN | INFINIPATH_E_RBADTID | \
@@ -68,53 +112,9 @@
static u64 handle_e_sum_errs(struct ipath_devdata *dd, ipath_err_t errs)
{
- unsigned long sbuf[4];
u64 ignore_this_time = 0;
- u32 piobcnt;
- /* if possible that sendbuffererror could be valid */
- piobcnt = dd->ipath_piobcnt2k + dd->ipath_piobcnt4k;
- /* read these before writing errorclear */
- sbuf[0] = ipath_read_kreg64(
- dd, dd->ipath_kregs->kr_sendbuffererror);
- sbuf[1] = ipath_read_kreg64(
- dd, dd->ipath_kregs->kr_sendbuffererror + 1);
- if (piobcnt > 128) {
- sbuf[2] = ipath_read_kreg64(
- dd, dd->ipath_kregs->kr_sendbuffererror + 2);
- sbuf[3] = ipath_read_kreg64(
- dd, dd->ipath_kregs->kr_sendbuffererror + 3);
- }
-
- if (sbuf[0] || sbuf[1] || (piobcnt > 128 && (sbuf[2] || sbuf[3]))) {
- int i;
-
- ipath_cdbg(PKT, "SendbufErrs %lx %lx ", sbuf[0], sbuf[1]);
- if (ipath_debug & __IPATH_PKTDBG && piobcnt > 128)
- printk("%lx %lx ", sbuf[2], sbuf[3]);
- for (i = 0; i < piobcnt; i++) {
- if (test_bit(i, sbuf)) {
- u32 __iomem *piobuf;
- if (i < dd->ipath_piobcnt2k)
- piobuf = (u32 __iomem *)
- (dd->ipath_pio2kbase +
- i * dd->ipath_palign);
- else
- piobuf = (u32 __iomem *)
- (dd->ipath_pio4kbase +
- (i - dd->ipath_piobcnt2k) *
- dd->ipath_4kalign);
-
- ipath_cdbg(PKT,
- "PIObuf[%u] @%p pbc is %x; ",
- i, piobuf, readl(piobuf));
-
- ipath_disarm_piobufs(dd, i, 1);
- }
- }
- if (ipath_debug & __IPATH_PKTDBG)
- printk("\n");
- }
+ ipath_disarm_senderrbufs(dd);
if ((errs & E_SUM_LINK_PKTERRS) &&
!(dd->ipath_flags & IPATH_LINKACTIVE)) {
/*
@@ -132,6 +132,82 @@ static u64 handle_e_sum_errs(struct ipath_devdata *dd, ipath_err_t errs)
return ignore_this_time;
}
+/* generic hw error messages... */
+#define INFINIPATH_HWE_TXEMEMPARITYERR_MSG(a) \
+ { \
+ .mask = ( INFINIPATH_HWE_TXEMEMPARITYERR_##a << \
+ INFINIPATH_HWE_TXEMEMPARITYERR_SHIFT ), \
+ .msg = "TXE " #a " Memory Parity" \
+ }
+#define INFINIPATH_HWE_RXEMEMPARITYERR_MSG(a) \
+ { \
+ .mask = ( INFINIPATH_HWE_RXEMEMPARITYERR_##a << \
+ INFINIPATH_HWE_RXEMEMPARITYERR_SHIFT ), \
+ .msg = "RXE " #a " Memory Parity" \
+ }
+
+static const struct ipath_hwerror_msgs ipath_generic_hwerror_msgs[] = {
+ INFINIPATH_HWE_MSG(IBCBUSFRSPCPARITYERR, "IPATH2IB Parity"),
+ INFINIPATH_HWE_MSG(IBCBUSTOSPCPARITYERR, "IB2IPATH Parity"),
+
+ INFINIPATH_HWE_TXEMEMPARITYERR_MSG(PIOBUF),
+ INFINIPATH_HWE_TXEMEMPARITYERR_MSG(PIOPBC),
+ INFINIPATH_HWE_TXEMEMPARITYERR_MSG(PIOLAUNCHFIFO),
+
+ INFINIPATH_HWE_RXEMEMPARITYERR_MSG(RCVBUF),
+ INFINIPATH_HWE_RXEMEMPARITYERR_MSG(LOOKUPQ),
+ INFINIPATH_HWE_RXEMEMPARITYERR_MSG(EAGERTID),
+ INFINIPATH_HWE_RXEMEMPARITYERR_MSG(EXPTID),
+ INFINIPATH_HWE_RXEMEMPARITYERR_MSG(FLAGBUF),
+ INFINIPATH_HWE_RXEMEMPARITYERR_MSG(DATAINFO),
+ INFINIPATH_HWE_RXEMEMPARITYERR_MSG(HDRINFO),
+};
+
+/**
+ * ipath_format_hwmsg - format a single hwerror message
+ * @msg message buffer
+ * @msgl length of message buffer
+ * @hwmsg message to add to message buffer
+ */
+static void ipath_format_hwmsg(char *msg, size_t msgl, const char *hwmsg)
+{
+ strlcat(msg, "[", msgl);
+ strlcat(msg, hwmsg, msgl);
+ strlcat(msg, "]", msgl);
+}
+
+/**
+ * ipath_format_hwerrors - format hardware error messages for display
+ * @hwerrs hardware errors bit vector
+ * @hwerrmsgs hardware error descriptions
+ * @nhwerrmsgs number of hwerrmsgs
+ * @msg message buffer
+ * @msgl message buffer length
+ */
+void ipath_format_hwerrors(u64 hwerrs,
+ const struct ipath_hwerror_msgs *hwerrmsgs,
+ size_t nhwerrmsgs,
+ char *msg, size_t msgl)
+{
+ int i;
+ const int glen =
+ sizeof(ipath_generic_hwerror_msgs) /
+ sizeof(ipath_generic_hwerror_msgs[0]);
+
+ for (i=0; i<glen; i++) {
+ if (hwerrs & ipath_generic_hwerror_msgs[i].mask) {
+ ipath_format_hwmsg(msg, msgl,
+ ipath_generic_hwerror_msgs[i].msg);
+ }
+ }
+
+ for (i=0; i<nhwerrmsgs; i++) {
+ if (hwerrs & hwerrmsgs[i].mask) {
+ ipath_format_hwmsg(msg, msgl, hwerrmsgs[i].msg);
+ }
+ }
+}
+
/* return the strings for the most common link states */
static char *ib_linkstate(u32 linkstate)
{
@@ -404,10 +480,10 @@ static int handle_errors(struct ipath_devdata *dd, ipath_err_t errs)
dd->ipath_f_handle_hwerrors(dd, msg, sizeof msg);
}
- if (!noprint && (errs & ~infinipath_e_bitsextant))
+ if (!noprint && (errs & ~dd->ipath_e_bitsextant))
ipath_dev_err(dd, "error interrupt with unknown errors "
"%llx set\n", (unsigned long long)
- (errs & ~infinipath_e_bitsextant));
+ (errs & ~dd->ipath_e_bitsextant));
if (errs & E_SUM_ERRS)
ignore_this_time = handle_e_sum_errs(dd, errs);
@@ -478,6 +554,14 @@ static int handle_errors(struct ipath_devdata *dd, ipath_err_t errs)
~(INFINIPATH_E_HARDWARE |
INFINIPATH_E_IBSTATUSCHANGED);
}
+
+ /* likely due to cancel, so suppress */
+ if ((errs & (INFINIPATH_E_SPKTLEN | INFINIPATH_E_SPIOARMLAUNCH)) &&
+ dd->ipath_lastcancel > jiffies) {
+ ipath_dbg("Suppressed armlaunch/spktlen after error send cancel\n");
+ errs &= ~(INFINIPATH_E_SPIOARMLAUNCH | INFINIPATH_E_SPKTLEN);
+ }
+
if (!errs)
return 0;
@@ -529,7 +613,7 @@ static int handle_errors(struct ipath_devdata *dd, ipath_err_t errs)
* don't report same point multiple times,
* except kernel
*/
- tl = (u32) * pd->port_rcvhdrtail_kvaddr;
+ tl = *(u64 *) pd->port_rcvhdrtail_kvaddr;
if (tl == dd->ipath_lastrcvhdrqtails[i])
continue;
hd = ipath_read_ureg32(dd, ur_rcvhdrhead,
@@ -729,9 +813,9 @@ static void handle_urcv(struct ipath_devdata *dd, u32 istat)
int rcvdint = 0;
portr = ((istat >> INFINIPATH_I_RCVAVAIL_SHIFT) &
- infinipath_i_rcvavail_mask)
+ dd->ipath_i_rcvavail_mask)
| ((istat >> INFINIPATH_I_RCVURG_SHIFT) &
- infinipath_i_rcvurg_mask);
+ dd->ipath_i_rcvurg_mask);
for (i = 1; i < dd->ipath_cfgports; i++) {
struct ipath_portdata *pd = dd->ipath_pd[i];
if (portr & (1 << i) && pd && pd->port_cnt &&
@@ -808,7 +892,7 @@ irqreturn_t ipath_intr(int irq, void *data, struct pt_regs *regs)
if (oldhead != curtail) {
if (dd->ipath_flags & IPATH_GPIO_INTR) {
ipath_write_kreg(dd, dd->ipath_kregs->kr_gpio_clear,
- (u64) (1 << 2));
+ (u64) (1 << IPATH_GPIO_PORT0_BIT));
istat = port0rbits | INFINIPATH_I_GPIO;
}
else
@@ -838,10 +922,10 @@ irqreturn_t ipath_intr(int irq, void *data, struct pt_regs *regs)
if (unexpected)
unexpected = 0;
- if (unlikely(istat & ~infinipath_i_bitsextant))
+ if (unlikely(istat & ~dd->ipath_i_bitsextant))
ipath_dev_err(dd,
"interrupt with unknown interrupts %x set\n",
- istat & (u32) ~ infinipath_i_bitsextant);
+ istat & (u32) ~ dd->ipath_i_bitsextant);
else
ipath_cdbg(VERBOSE, "intr stat=0x%x\n", istat);
@@ -867,26 +951,80 @@ irqreturn_t ipath_intr(int irq, void *data, struct pt_regs *regs)
if (istat & INFINIPATH_I_GPIO) {
/*
- * Packets are available in the port 0 rcv queue.
- * Eventually this needs to be generalized to check
- * IPATH_GPIO_INTR, and the specific GPIO bit, if
- * GPIO interrupts are used for anything else.
+ * GPIO interrupts fall in two broad classes:
+ * GPIO_2 indicates (on some HT4xx boards) that a packet
+ * has arrived for Port 0. Checking for this
+ * is controlled by flag IPATH_GPIO_INTR.
+ * GPIO_3..5 on IBA6120 Rev2 chips indicate errors
+ * that we need to count. Checking for this
+ * is controlled by flag IPATH_GPIO_ERRINTRS.
*/
- if (unlikely(!(dd->ipath_flags & IPATH_GPIO_INTR))) {
- u32 gpiostatus;
- gpiostatus = ipath_read_kreg32(
- dd, dd->ipath_kregs->kr_gpio_status);
- ipath_dbg("Unexpected GPIO interrupt bits %x\n",
- gpiostatus);
- ipath_write_kreg(dd, dd->ipath_kregs->kr_gpio_clear,
- gpiostatus);
+ u32 gpiostatus;
+ u32 to_clear = 0;
+
+ gpiostatus = ipath_read_kreg32(
+ dd, dd->ipath_kregs->kr_gpio_status);
+ /* First the error-counter case.
+ */
+ if ((gpiostatus & IPATH_GPIO_ERRINTR_MASK) &&
+ (dd->ipath_flags & IPATH_GPIO_ERRINTRS)) {
+ /* want to clear the bits we see asserted. */
+ to_clear |= (gpiostatus & IPATH_GPIO_ERRINTR_MASK);
+
+ /*
+ * Count appropriately, clear bits out of our copy,
+ * as they have been "handled".
+ */
+ if (gpiostatus & (1 << IPATH_GPIO_RXUVL_BIT)) {
+ ipath_dbg("FlowCtl on UnsupVL\n");
+ dd->ipath_rxfc_unsupvl_errs++;
+ }
+ if (gpiostatus & (1 << IPATH_GPIO_OVRUN_BIT)) {
+ ipath_dbg("Overrun Threshold exceeded\n");
+ dd->ipath_overrun_thresh_errs++;
+ }
+ if (gpiostatus & (1 << IPATH_GPIO_LLI_BIT)) {
+ ipath_dbg("Local Link Integrity error\n");
+ dd->ipath_lli_errs++;
+ }
+ gpiostatus &= ~IPATH_GPIO_ERRINTR_MASK;
}
- else {
- /* Clear GPIO status bit 2 */
- ipath_write_kreg(dd, dd->ipath_kregs->kr_gpio_clear,
- (u64) (1 << 2));
+ /* Now the Port0 Receive case */
+ if ((gpiostatus & (1 << IPATH_GPIO_PORT0_BIT)) &&
+ (dd->ipath_flags & IPATH_GPIO_INTR)) {
+ /*
+ * GPIO status bit 2 is set, and we expected it.
+ * clear it and indicate in p0bits.
+ * This probably only happens if a Port0 pkt
+ * arrives at _just_ the wrong time, and we
+ * handle that by seting chk0rcv;
+ */
+ to_clear |= (1 << IPATH_GPIO_PORT0_BIT);
+ gpiostatus &= ~(1 << IPATH_GPIO_PORT0_BIT);
chk0rcv = 1;
}
+ if (unlikely(gpiostatus)) {
+ /*
+ * Some unexpected bits remain. If they could have
+ * caused the interrupt, complain and clear.
+ * MEA: this is almost certainly non-ideal.
+ * we should look into auto-disable of unexpected
+ * GPIO interrupts, possibly on a "three strikes"
+ * basis.
+ */
+ u32 mask;
+ mask = ipath_read_kreg32(
+ dd, dd->ipath_kregs->kr_gpio_mask);
+ if (mask & gpiostatus) {
+ ipath_dbg("Unexpected GPIO IRQ bits %x\n",
+ gpiostatus & mask);
+ to_clear |= (gpiostatus & mask);
+ }
+ }
+ if (to_clear) {
+ ipath_write_kreg(dd, dd->ipath_kregs->kr_gpio_clear,
+ (u64) to_clear);
+ }
}
chk0rcv |= istat & port0rbits;
@@ -911,9 +1049,9 @@ irqreturn_t ipath_intr(int irq, void *data, struct pt_regs *regs)
istat &= ~port0rbits;
}
- if (istat & ((infinipath_i_rcvavail_mask <<
+ if (istat & ((dd->ipath_i_rcvavail_mask <<
INFINIPATH_I_RCVAVAIL_SHIFT)
- | (infinipath_i_rcvurg_mask <<
+ | (dd->ipath_i_rcvurg_mask <<
INFINIPATH_I_RCVURG_SHIFT)))
handle_urcv(dd, istat);
diff --git a/drivers/infiniband/hw/ipath/ipath_kernel.h b/drivers/infiniband/hw/ipath/ipath_kernel.h
index a8a56276ff1d..d7540b71b451 100644
--- a/drivers/infiniband/hw/ipath/ipath_kernel.h
+++ b/drivers/infiniband/hw/ipath/ipath_kernel.h
@@ -39,6 +39,8 @@
*/
#include <linux/interrupt.h>
+#include <linux/pci.h>
+#include <linux/dma-mapping.h>
#include <asm/io.h>
#include "ipath_common.h"
@@ -62,7 +64,7 @@ struct ipath_portdata {
/* rcvhdrq base, needs mmap before useful */
void *port_rcvhdrq;
/* kernel virtual address where hdrqtail is updated */
- volatile __le64 *port_rcvhdrtail_kvaddr;
+ void *port_rcvhdrtail_kvaddr;
/*
* temp buffer for expected send setup, allocated at open, instead
* of each setup call
@@ -79,8 +81,8 @@ struct ipath_portdata {
dma_addr_t port_rcvhdrq_phys;
dma_addr_t port_rcvhdrqtailaddr_phys;
/*
- * number of opens on this instance (0 or 1; ignoring forks, dup,
- * etc. for now)
+ * number of opens (including slave subports) on this instance
+ * (ignoring forks, dup, etc. for now)
*/
int port_cnt;
/*
@@ -89,6 +91,10 @@ struct ipath_portdata {
*/
/* instead of calculating it */
unsigned port_port;
+ /* non-zero if port is being shared. */
+ u16 port_subport_cnt;
+ /* non-zero if port is being shared. */
+ u16 port_subport_id;
/* chip offset of PIO buffers for this port */
u32 port_piobufs;
/* how many alloc_pages() chunks in port_rcvegrbuf_pages */
@@ -121,6 +127,16 @@ struct ipath_portdata {
u16 port_pkeys[4];
/* so file ops can get at unit */
struct ipath_devdata *port_dd;
+ /* A page of memory for rcvhdrhead, rcvegrhead, rcvegrtail * N */
+ void *subport_uregbase;
+ /* An array of pages for the eager receive buffers * N */
+ void *subport_rcvegrbuf;
+ /* An array of pages for the eager header queue entries * N */
+ void *subport_rcvhdr_base;
+ /* The version of the library which opened this port */
+ u32 userversion;
+ /* Bitmask of active slaves */
+ u32 active_slaves;
};
struct sk_buff;
@@ -132,6 +148,11 @@ struct _ipath_layer {
void *l_arg;
};
+struct ipath_skbinfo {
+ struct sk_buff *skb;
+ dma_addr_t phys;
+};
+
struct ipath_devdata {
struct list_head ipath_list;
@@ -154,7 +175,7 @@ struct ipath_devdata {
/* ipath_cfgports pointers */
struct ipath_portdata **ipath_pd;
/* sk_buffs used by port 0 eager receive queue */
- struct sk_buff **ipath_port0_skbs;
+ struct ipath_skbinfo *ipath_port0_skbinfo;
/* kvirt address of 1st 2k pio buffer */
void __iomem *ipath_pio2kbase;
/* kvirt address of 1st 4k pio buffer */
@@ -315,12 +336,16 @@ struct ipath_devdata {
u8 ipath_ht_slave_off;
/* for write combining settings */
unsigned long ipath_wc_cookie;
+ unsigned long ipath_wc_base;
+ unsigned long ipath_wc_len;
/* ref count for each pkey */
atomic_t ipath_pkeyrefs[4];
/* shadow copy of all exptids physaddr; used only by funcsim */
u64 *ipath_tidsimshadow;
/* shadow copy of struct page *'s for exp tid pages */
struct page **ipath_pageshadow;
+ /* shadow copy of dma handles for exp tid pages */
+ dma_addr_t *ipath_physshadow;
/* lock to workaround chip bug 9437 */
spinlock_t ipath_tid_lock;
@@ -402,6 +427,9 @@ struct ipath_devdata {
unsigned long ipath_rcvctrl;
/* shadow kr_sendctrl */
unsigned long ipath_sendctrl;
+ /* ports waiting for PIOavail intr */
+ unsigned long ipath_portpiowait;
+ unsigned long ipath_lastcancel; /* to not count armlaunch after cancel */
/* value we put in kr_rcvhdrcnt */
u32 ipath_rcvhdrcnt;
@@ -465,8 +493,6 @@ struct ipath_devdata {
u32 ipath_htwidth;
/* HT speed (200,400,800,1000) from HT config */
u32 ipath_htspeed;
- /* ports waiting for PIOavail intr */
- unsigned long ipath_portpiowait;
/*
* number of sequential ibcstatus change for polling active/quiet
* (i.e., link not coming up).
@@ -510,8 +536,47 @@ struct ipath_devdata {
u32 ipath_lli_counter;
/* local link integrity errors */
u32 ipath_lli_errors;
+ /*
+ * Above counts only cases where _successive_ LocalLinkIntegrity
+ * errors were seen in the receive headers of kern-packets.
+ * Below are the three (monotonically increasing) counters
+ * maintained via GPIO interrupts on iba6120-rev2.
+ */
+ u32 ipath_rxfc_unsupvl_errs;
+ u32 ipath_overrun_thresh_errs;
+ u32 ipath_lli_errs;
+
+ /*
+ * Not all devices managed by a driver instance are the same
+ * type, so these fields must be per-device.
+ */
+ u64 ipath_i_bitsextant;
+ ipath_err_t ipath_e_bitsextant;
+ ipath_err_t ipath_hwe_bitsextant;
+
+ /*
+ * Below should be computable from number of ports,
+ * since they are never modified.
+ */
+ u32 ipath_i_rcvavail_mask;
+ u32 ipath_i_rcvurg_mask;
+
+ /*
+ * Register bits for selecting i2c direction and values, used for
+ * I2C serial flash.
+ */
+ u16 ipath_gpio_sda_num;
+ u16 ipath_gpio_scl_num;
+ u64 ipath_gpio_sda;
+ u64 ipath_gpio_scl;
};
+/* Private data for file operations */
+struct ipath_filedata {
+ struct ipath_portdata *pd;
+ unsigned subport;
+ unsigned tidcursor;
+};
extern struct list_head ipath_dev_list;
extern spinlock_t ipath_devs_lock;
extern struct ipath_devdata *ipath_lookup(int unit);
@@ -521,6 +586,7 @@ int ipath_enable_wc(struct ipath_devdata *dd);
void ipath_disable_wc(struct ipath_devdata *dd);
int ipath_count_units(int *npresentp, int *nupp, u32 *maxportsp);
void ipath_shutdown_device(struct ipath_devdata *);
+void ipath_disarm_senderrbufs(struct ipath_devdata *);
struct file_operations;
int ipath_cdev_init(int minor, char *name, struct file_operations *fops,
@@ -572,7 +638,11 @@ int ipath_set_lid(struct ipath_devdata *, u32, u8);
int ipath_set_rx_pol_inv(struct ipath_devdata *dd, u8 new_pol_inv);
/* for use in system calls, where we want to know device type, etc. */
-#define port_fp(fp) ((struct ipath_portdata *) (fp)->private_data)
+#define port_fp(fp) ((struct ipath_filedata *)(fp)->private_data)->pd
+#define subport_fp(fp) \
+ ((struct ipath_filedata *)(fp)->private_data)->subport
+#define tidcursor_fp(fp) \
+ ((struct ipath_filedata *)(fp)->private_data)->tidcursor
/*
* values for ipath_flags
@@ -612,6 +682,15 @@ int ipath_set_rx_pol_inv(struct ipath_devdata *dd, u8 new_pol_inv);
/* can miss port0 rx interrupts */
#define IPATH_POLL_RX_INTR 0x40000
#define IPATH_DISABLED 0x80000 /* administratively disabled */
+ /* Use GPIO interrupts for new counters */
+#define IPATH_GPIO_ERRINTRS 0x100000
+
+/* Bits in GPIO for the added interrupts */
+#define IPATH_GPIO_PORT0_BIT 2
+#define IPATH_GPIO_RXUVL_BIT 3
+#define IPATH_GPIO_OVRUN_BIT 4
+#define IPATH_GPIO_LLI_BIT 5
+#define IPATH_GPIO_ERRINTR_MASK 0x38
/* portdata flag bit offsets */
/* waiting for a packet to arrive */
@@ -799,6 +878,13 @@ int ipathfs_add_device(struct ipath_devdata *);
int ipathfs_remove_device(struct ipath_devdata *);
/*
+ * dma_addr wrappers - all 0's invalid for hw
+ */
+dma_addr_t ipath_map_page(struct pci_dev *, struct page *, unsigned long,
+ size_t, int);
+dma_addr_t ipath_map_single(struct pci_dev *, void *, size_t, int);
+
+/*
* Flush write combining store buffers (if present) and perform a write
* barrier.
*/
@@ -855,4 +941,20 @@ extern struct mutex ipath_mutex;
#endif /* _IPATH_DEBUGGING */
+/*
+ * this is used for formatting hw error messages...
+ */
+struct ipath_hwerror_msgs {
+ u64 mask;
+ const char *msg;
+};
+
+#define INFINIPATH_HWE_MSG(a, b) { .mask = INFINIPATH_HWE_##a, .msg = b }
+
+/* in ipath_intr.c... */
+void ipath_format_hwerrors(u64 hwerrs,
+ const struct ipath_hwerror_msgs *hwerrmsgs,
+ size_t nhwerrmsgs,
+ char *msg, size_t lmsg);
+
#endif /* _IPATH_KERNEL_H */
diff --git a/drivers/infiniband/hw/ipath/ipath_keys.c b/drivers/infiniband/hw/ipath/ipath_keys.c
index ba1b93226caa..9a6cbd05adcd 100644
--- a/drivers/infiniband/hw/ipath/ipath_keys.c
+++ b/drivers/infiniband/hw/ipath/ipath_keys.c
@@ -118,9 +118,10 @@ void ipath_free_lkey(struct ipath_lkey_table *rkt, u32 lkey)
* Check the IB SGE for validity and initialize our internal version
* of it.
*/
-int ipath_lkey_ok(struct ipath_lkey_table *rkt, struct ipath_sge *isge,
+int ipath_lkey_ok(struct ipath_qp *qp, struct ipath_sge *isge,
struct ib_sge *sge, int acc)
{
+ struct ipath_lkey_table *rkt = &to_idev(qp->ibqp.device)->lk_table;
struct ipath_mregion *mr;
unsigned n, m;
size_t off;
@@ -140,7 +141,8 @@ int ipath_lkey_ok(struct ipath_lkey_table *rkt, struct ipath_sge *isge,
goto bail;
}
mr = rkt->table[(sge->lkey >> (32 - ib_ipath_lkey_table_size))];
- if (unlikely(mr == NULL || mr->lkey != sge->lkey)) {
+ if (unlikely(mr == NULL || mr->lkey != sge->lkey ||
+ qp->ibqp.pd != mr->pd)) {
ret = 0;
goto bail;
}
@@ -188,9 +190,10 @@ bail:
*
* Return 1 if successful, otherwise 0.
*/
-int ipath_rkey_ok(struct ipath_ibdev *dev, struct ipath_sge_state *ss,
+int ipath_rkey_ok(struct ipath_qp *qp, struct ipath_sge_state *ss,
u32 len, u64 vaddr, u32 rkey, int acc)
{
+ struct ipath_ibdev *dev = to_idev(qp->ibqp.device);
struct ipath_lkey_table *rkt = &dev->lk_table;
struct ipath_sge *sge = &ss->sge;
struct ipath_mregion *mr;
@@ -214,7 +217,8 @@ int ipath_rkey_ok(struct ipath_ibdev *dev, struct ipath_sge_state *ss,
}
mr = rkt->table[(rkey >> (32 - ib_ipath_lkey_table_size))];
- if (unlikely(mr == NULL || mr->lkey != rkey)) {
+ if (unlikely(mr == NULL || mr->lkey != rkey ||
+ qp->ibqp.pd != mr->pd)) {
ret = 0;
goto bail;
}
diff --git a/drivers/infiniband/hw/ipath/ipath_mad.c b/drivers/infiniband/hw/ipath/ipath_mad.c
index 72d1db89db8f..25908b02fbe5 100644
--- a/drivers/infiniband/hw/ipath/ipath_mad.c
+++ b/drivers/infiniband/hw/ipath/ipath_mad.c
@@ -87,7 +87,8 @@ static int recv_subn_get_nodeinfo(struct ib_smp *smp,
struct ipath_devdata *dd = to_idev(ibdev)->dd;
u32 vendor, majrev, minrev;
- if (smp->attr_mod)
+ /* GUID 0 is illegal */
+ if (smp->attr_mod || (dd->ipath_guid == 0))
smp->status |= IB_SMP_INVALID_FIELD;
nip->base_version = 1;
@@ -131,10 +132,15 @@ static int recv_subn_get_guidinfo(struct ib_smp *smp,
* We only support one GUID for now. If this changes, the
* portinfo.guid_cap field needs to be updated too.
*/
- if (startgx == 0)
- /* The first is a copy of the read-only HW GUID. */
- *p = to_idev(ibdev)->dd->ipath_guid;
- else
+ if (startgx == 0) {
+ __be64 g = to_idev(ibdev)->dd->ipath_guid;
+ if (g == 0)
+ /* GUID 0 is illegal */
+ smp->status |= IB_SMP_INVALID_FIELD;
+ else
+ /* The first is a copy of the read-only HW GUID. */
+ *p = g;
+ } else
smp->status |= IB_SMP_INVALID_FIELD;
return reply(smp);
diff --git a/drivers/infiniband/hw/ipath/ipath_mr.c b/drivers/infiniband/hw/ipath/ipath_mr.c
index b36f6fb3e37a..a0673c1eef71 100644
--- a/drivers/infiniband/hw/ipath/ipath_mr.c
+++ b/drivers/infiniband/hw/ipath/ipath_mr.c
@@ -138,6 +138,7 @@ struct ib_mr *ipath_reg_phys_mr(struct ib_pd *pd,
goto bail;
}
+ mr->mr.pd = pd;
mr->mr.user_base = *iova_start;
mr->mr.iova = *iova_start;
mr->mr.length = 0;
@@ -197,6 +198,7 @@ struct ib_mr *ipath_reg_user_mr(struct ib_pd *pd, struct ib_umem *region,
goto bail;
}
+ mr->mr.pd = pd;
mr->mr.user_base = region->user_base;
mr->mr.iova = region->virt_base;
mr->mr.length = region->length;
@@ -289,6 +291,7 @@ struct ib_fmr *ipath_alloc_fmr(struct ib_pd *pd, int mr_access_flags,
* Resources are allocated but no valid mapping (RKEY can't be
* used).
*/
+ fmr->mr.pd = pd;
fmr->mr.user_base = 0;
fmr->mr.iova = 0;
fmr->mr.length = 0;
diff --git a/drivers/infiniband/hw/ipath/ipath_qp.c b/drivers/infiniband/hw/ipath/ipath_qp.c
index 224b0f40767f..46c1c89bf6ae 100644
--- a/drivers/infiniband/hw/ipath/ipath_qp.c
+++ b/drivers/infiniband/hw/ipath/ipath_qp.c
@@ -335,6 +335,7 @@ static void ipath_reset_qp(struct ipath_qp *qp)
qp->s_ack_state = IB_OPCODE_RC_ACKNOWLEDGE;
qp->r_ack_state = IB_OPCODE_RC_ACKNOWLEDGE;
qp->r_nak_state = 0;
+ qp->r_wrid_valid = 0;
qp->s_rnr_timeout = 0;
qp->s_head = 0;
qp->s_tail = 0;
@@ -342,6 +343,7 @@ static void ipath_reset_qp(struct ipath_qp *qp)
qp->s_last = 0;
qp->s_ssn = 1;
qp->s_lsn = 0;
+ qp->s_wait_credit = 0;
if (qp->r_rq.wq) {
qp->r_rq.wq->head = 0;
qp->r_rq.wq->tail = 0;
@@ -352,12 +354,13 @@ static void ipath_reset_qp(struct ipath_qp *qp)
/**
* ipath_error_qp - put a QP into an error state
* @qp: the QP to put into an error state
+ * @err: the receive completion error to signal if a RWQE is active
*
* Flushes both send and receive work queues.
* QP s_lock should be held and interrupts disabled.
*/
-void ipath_error_qp(struct ipath_qp *qp)
+void ipath_error_qp(struct ipath_qp *qp, enum ib_wc_status err)
{
struct ipath_ibdev *dev = to_idev(qp->ibqp.device);
struct ib_wc wc;
@@ -373,7 +376,6 @@ void ipath_error_qp(struct ipath_qp *qp)
list_del_init(&qp->piowait);
spin_unlock(&dev->pending_lock);
- wc.status = IB_WC_WR_FLUSH_ERR;
wc.vendor_err = 0;
wc.byte_len = 0;
wc.imm_data = 0;
@@ -385,6 +387,12 @@ void ipath_error_qp(struct ipath_qp *qp)
wc.sl = 0;
wc.dlid_path_bits = 0;
wc.port_num = 0;
+ if (qp->r_wrid_valid) {
+ qp->r_wrid_valid = 0;
+ wc.status = err;
+ ipath_cq_enter(to_icq(qp->ibqp.send_cq), &wc, 1);
+ }
+ wc.status = IB_WC_WR_FLUSH_ERR;
while (qp->s_last != qp->s_head) {
struct ipath_swqe *wqe = get_swqe_ptr(qp, qp->s_last);
@@ -501,7 +509,7 @@ int ipath_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr,
break;
case IB_QPS_ERR:
- ipath_error_qp(qp);
+ ipath_error_qp(qp, IB_WC_GENERAL_ERR);
break;
default:
@@ -516,7 +524,7 @@ int ipath_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr,
qp->remote_qpn = attr->dest_qp_num;
if (attr_mask & IB_QP_SQ_PSN) {
- qp->s_next_psn = attr->sq_psn;
+ qp->s_psn = qp->s_next_psn = attr->sq_psn;
qp->s_last_psn = qp->s_next_psn - 1;
}
diff --git a/drivers/infiniband/hw/ipath/ipath_rc.c b/drivers/infiniband/hw/ipath/ipath_rc.c
index a08654042c03..ce6038743c5c 100644
--- a/drivers/infiniband/hw/ipath/ipath_rc.c
+++ b/drivers/infiniband/hw/ipath/ipath_rc.c
@@ -201,6 +201,18 @@ int ipath_make_rc_req(struct ipath_qp *qp,
qp->s_rnr_timeout)
goto done;
+ /* Limit the number of packets sent without an ACK. */
+ if (ipath_cmp24(qp->s_psn, qp->s_last_psn + IPATH_PSN_CREDIT) > 0) {
+ qp->s_wait_credit = 1;
+ dev->n_rc_stalls++;
+ spin_lock(&dev->pending_lock);
+ if (list_empty(&qp->timerwait))
+ list_add_tail(&qp->timerwait,
+ &dev->pending[dev->pending_index]);
+ spin_unlock(&dev->pending_lock);
+ goto done;
+ }
+
/* header size in 32-bit words LRH+BTH = (8+12)/4. */
hwords = 5;
bth0 = 0;
@@ -221,7 +233,7 @@ int ipath_make_rc_req(struct ipath_qp *qp,
/* Check if send work queue is empty. */
if (qp->s_tail == qp->s_head)
goto done;
- qp->s_psn = wqe->psn = qp->s_next_psn;
+ wqe->psn = qp->s_next_psn;
newreq = 1;
}
/*
@@ -229,10 +241,7 @@ int ipath_make_rc_req(struct ipath_qp *qp,
* original work request since we may need to resend
* it.
*/
- qp->s_sge.sge = wqe->sg_list[0];
- qp->s_sge.sg_list = wqe->sg_list + 1;
- qp->s_sge.num_sge = wqe->wr.num_sge;
- qp->s_len = len = wqe->length;
+ len = wqe->length;
ss = &qp->s_sge;
bth2 = 0;
switch (wqe->wr.opcode) {
@@ -356,14 +365,23 @@ int ipath_make_rc_req(struct ipath_qp *qp,
default:
goto done;
}
+ qp->s_sge.sge = wqe->sg_list[0];
+ qp->s_sge.sg_list = wqe->sg_list + 1;
+ qp->s_sge.num_sge = wqe->wr.num_sge;
+ qp->s_len = wqe->length;
if (newreq) {
qp->s_tail++;
if (qp->s_tail >= qp->s_size)
qp->s_tail = 0;
}
- bth2 |= qp->s_psn++ & IPATH_PSN_MASK;
- if ((int)(qp->s_psn - qp->s_next_psn) > 0)
- qp->s_next_psn = qp->s_psn;
+ bth2 |= qp->s_psn & IPATH_PSN_MASK;
+ if (wqe->wr.opcode == IB_WR_RDMA_READ)
+ qp->s_psn = wqe->lpsn + 1;
+ else {
+ qp->s_psn++;
+ if ((int)(qp->s_psn - qp->s_next_psn) > 0)
+ qp->s_next_psn = qp->s_psn;
+ }
/*
* Put the QP on the pending list so lost ACKs will cause
* a retry. More than one request can be pending so the
@@ -393,12 +411,6 @@ int ipath_make_rc_req(struct ipath_qp *qp,
ss = &qp->s_sge;
len = qp->s_len;
if (len > pmtu) {
- /*
- * Request an ACK every 1/2 MB to avoid retransmit
- * timeouts.
- */
- if (((wqe->length - len) % (512 * 1024)) == 0)
- bth2 |= 1 << 31;
len = pmtu;
break;
}
@@ -435,12 +447,6 @@ int ipath_make_rc_req(struct ipath_qp *qp,
ss = &qp->s_sge;
len = qp->s_len;
if (len > pmtu) {
- /*
- * Request an ACK every 1/2 MB to avoid retransmit
- * timeouts.
- */
- if (((wqe->length - len) % (512 * 1024)) == 0)
- bth2 |= 1 << 31;
len = pmtu;
break;
}
@@ -498,6 +504,8 @@ int ipath_make_rc_req(struct ipath_qp *qp,
*/
goto done;
}
+ if (ipath_cmp24(qp->s_psn, qp->s_last_psn + IPATH_PSN_CREDIT - 1) >= 0)
+ bth2 |= 1 << 31; /* Request ACK. */
qp->s_len -= len;
qp->s_hdrwords = hwords;
qp->s_cur_sge = ss;
@@ -688,13 +696,6 @@ void ipath_restart_rc(struct ipath_qp *qp, u32 psn, struct ib_wc *wc)
struct ipath_swqe *wqe = get_swqe_ptr(qp, qp->s_last);
struct ipath_ibdev *dev;
- /*
- * If there are no requests pending, we are done.
- */
- if (ipath_cmp24(psn, qp->s_next_psn) >= 0 ||
- qp->s_last == qp->s_tail)
- goto done;
-
if (qp->s_retry == 0) {
wc->wr_id = wqe->wr.wr_id;
wc->status = IB_WC_RETRY_EXC_ERR;
@@ -729,14 +730,21 @@ void ipath_restart_rc(struct ipath_qp *qp, u32 psn, struct ib_wc *wc)
dev->n_rc_resends += (int)qp->s_psn - (int)psn;
reset_psn(qp, psn);
-
-done:
tasklet_hi_schedule(&qp->s_task);
bail:
return;
}
+static inline void update_last_psn(struct ipath_qp *qp, u32 psn)
+{
+ if (qp->s_wait_credit) {
+ qp->s_wait_credit = 0;
+ tasklet_hi_schedule(&qp->s_task);
+ }
+ qp->s_last_psn = psn;
+}
+
/**
* do_rc_ack - process an incoming RC ACK
* @qp: the QP the ACK came in on
@@ -754,6 +762,7 @@ static int do_rc_ack(struct ipath_qp *qp, u32 aeth, u32 psn, int opcode)
struct ib_wc wc;
struct ipath_swqe *wqe;
int ret = 0;
+ u32 ack_psn;
/*
* Remove the QP from the timeout queue (or RNR timeout queue).
@@ -766,26 +775,26 @@ static int do_rc_ack(struct ipath_qp *qp, u32 aeth, u32 psn, int opcode)
list_del_init(&qp->timerwait);
spin_unlock(&dev->pending_lock);
+ /* Nothing is pending to ACK/NAK. */
+ if (unlikely(qp->s_last == qp->s_tail))
+ goto bail;
+
/*
* Note that NAKs implicitly ACK outstanding SEND and RDMA write
* requests and implicitly NAK RDMA read and atomic requests issued
* before the NAK'ed request. The MSN won't include the NAK'ed
* request but will include an ACK'ed request(s).
*/
+ ack_psn = psn;
+ if (aeth >> 29)
+ ack_psn--;
wqe = get_swqe_ptr(qp, qp->s_last);
- /* Nothing is pending to ACK/NAK. */
- if (qp->s_last == qp->s_tail)
- goto bail;
-
/*
* The MSN might be for a later WQE than the PSN indicates so
* only complete WQEs that the PSN finishes.
*/
- while (ipath_cmp24(psn, wqe->lpsn) >= 0) {
- /* If we are ACKing a WQE, the MSN should be >= the SSN. */
- if (ipath_cmp24(aeth, wqe->ssn) < 0)
- break;
+ while (ipath_cmp24(ack_psn, wqe->lpsn) >= 0) {
/*
* If this request is a RDMA read or atomic, and the ACK is
* for a later operation, this ACK NAKs the RDMA read or
@@ -796,7 +805,8 @@ static int do_rc_ack(struct ipath_qp *qp, u32 aeth, u32 psn, int opcode)
* is sent but before the response is received.
*/
if ((wqe->wr.opcode == IB_WR_RDMA_READ &&
- opcode != OP(RDMA_READ_RESPONSE_LAST)) ||
+ (opcode != OP(RDMA_READ_RESPONSE_LAST) ||
+ ipath_cmp24(ack_psn, wqe->lpsn) != 0)) ||
((wqe->wr.opcode == IB_WR_ATOMIC_CMP_AND_SWP ||
wqe->wr.opcode == IB_WR_ATOMIC_FETCH_AND_ADD) &&
(opcode != OP(ATOMIC_ACKNOWLEDGE) ||
@@ -805,7 +815,7 @@ static int do_rc_ack(struct ipath_qp *qp, u32 aeth, u32 psn, int opcode)
* The last valid PSN seen is the previous
* request's.
*/
- qp->s_last_psn = wqe->psn - 1;
+ update_last_psn(qp, wqe->psn - 1);
/* Retry this request. */
ipath_restart_rc(qp, wqe->psn, &wc);
/*
@@ -814,6 +824,10 @@ static int do_rc_ack(struct ipath_qp *qp, u32 aeth, u32 psn, int opcode)
*/
goto bail;
}
+ if (wqe->wr.opcode == IB_WR_RDMA_READ ||
+ wqe->wr.opcode == IB_WR_ATOMIC_CMP_AND_SWP ||
+ wqe->wr.opcode == IB_WR_ATOMIC_FETCH_AND_ADD)
+ tasklet_hi_schedule(&qp->s_task);
/* Post a send completion queue entry if requested. */
if (!test_bit(IPATH_S_SIGNAL_REQ_WR, &qp->s_flags) ||
(wqe->wr.send_flags & IB_SEND_SIGNALED)) {
@@ -864,7 +878,7 @@ static int do_rc_ack(struct ipath_qp *qp, u32 aeth, u32 psn, int opcode)
ipath_get_credit(qp, aeth);
qp->s_rnr_retry = qp->s_rnr_retry_cnt;
qp->s_retry = qp->s_retry_cnt;
- qp->s_last_psn = psn;
+ update_last_psn(qp, psn);
ret = 1;
goto bail;
@@ -883,7 +897,7 @@ static int do_rc_ack(struct ipath_qp *qp, u32 aeth, u32 psn, int opcode)
goto bail;
/* The last valid PSN is the previous PSN. */
- qp->s_last_psn = psn - 1;
+ update_last_psn(qp, psn - 1);
dev->n_rc_resends += (int)qp->s_psn - (int)psn;
@@ -898,7 +912,7 @@ static int do_rc_ack(struct ipath_qp *qp, u32 aeth, u32 psn, int opcode)
case 3: /* NAK */
/* The last valid PSN seen is the previous request's. */
if (qp->s_last != qp->s_tail)
- qp->s_last_psn = wqe->psn - 1;
+ update_last_psn(qp, wqe->psn - 1);
switch ((aeth >> IPATH_AETH_CREDIT_SHIFT) &
IPATH_AETH_CREDIT_MASK) {
case 0: /* PSN sequence error */
@@ -1044,7 +1058,8 @@ static inline void ipath_rc_rcv_resp(struct ipath_ibdev *dev,
/* no AETH, no ACK */
if (unlikely(ipath_cmp24(psn, qp->s_last_psn + 1))) {
dev->n_rdma_seq++;
- ipath_restart_rc(qp, qp->s_last_psn + 1, &wc);
+ if (qp->s_last != qp->s_tail)
+ ipath_restart_rc(qp, qp->s_last_psn + 1, &wc);
goto ack_done;
}
rdma_read:
@@ -1071,7 +1086,7 @@ static inline void ipath_rc_rcv_resp(struct ipath_ibdev *dev,
* since we don't want s_sge modified.
*/
qp->s_len -= pmtu;
- qp->s_last_psn = psn;
+ update_last_psn(qp, psn);
spin_unlock_irqrestore(&qp->s_lock, flags);
ipath_copy_sge(&qp->s_sge, data, pmtu);
goto bail;
@@ -1080,7 +1095,8 @@ static inline void ipath_rc_rcv_resp(struct ipath_ibdev *dev,
/* ACKs READ req. */
if (unlikely(ipath_cmp24(psn, qp->s_last_psn + 1))) {
dev->n_rdma_seq++;
- ipath_restart_rc(qp, qp->s_last_psn + 1, &wc);
+ if (qp->s_last != qp->s_tail)
+ ipath_restart_rc(qp, qp->s_last_psn + 1, &wc);
goto ack_done;
}
/* FALLTHROUGH */
@@ -1223,7 +1239,7 @@ static inline int ipath_rc_rcv_error(struct ipath_ibdev *dev,
* Address range must be a subset of the original
* request and start on pmtu boundaries.
*/
- ok = ipath_rkey_ok(dev, &qp->s_rdma_sge,
+ ok = ipath_rkey_ok(qp, &qp->s_rdma_sge,
qp->s_rdma_len, vaddr, rkey,
IB_ACCESS_REMOTE_READ);
if (unlikely(!ok)) {
@@ -1282,6 +1298,14 @@ done:
return 1;
}
+static void ipath_rc_error(struct ipath_qp *qp, enum ib_wc_status err)
+{
+ spin_lock_irq(&qp->s_lock);
+ qp->state = IB_QPS_ERR;
+ ipath_error_qp(qp, err);
+ spin_unlock_irq(&qp->s_lock);
+}
+
/**
* ipath_rc_rcv - process an incoming RC packet
* @dev: the device this packet came in on
@@ -1309,6 +1333,10 @@ void ipath_rc_rcv(struct ipath_ibdev *dev, struct ipath_ib_header *hdr,
struct ib_reth *reth;
int header_in_data;
+ /* Validate the SLID. See Ch. 9.6.1.5 */
+ if (unlikely(be16_to_cpu(hdr->lrh[3]) != qp->remote_ah_attr.dlid))
+ goto done;
+
/* Check for GRH */
if (!has_grh) {
ohdr = &hdr->u.oth;
@@ -1370,8 +1398,7 @@ void ipath_rc_rcv(struct ipath_ibdev *dev, struct ipath_ib_header *hdr,
*/
if (qp->r_ack_state >= OP(COMPARE_SWAP))
goto send_ack;
- /* XXX Flush WQEs */
- qp->state = IB_QPS_ERR;
+ ipath_rc_error(qp, IB_WC_REM_INV_REQ_ERR);
qp->r_ack_state = OP(SEND_ONLY);
qp->r_nak_state = IB_NAK_INVALID_REQUEST;
qp->r_ack_psn = qp->r_psn;
@@ -1477,9 +1504,9 @@ void ipath_rc_rcv(struct ipath_ibdev *dev, struct ipath_ib_header *hdr,
goto nack_inv;
ipath_copy_sge(&qp->r_sge, data, tlen);
qp->r_msn++;
- if (opcode == OP(RDMA_WRITE_LAST) ||
- opcode == OP(RDMA_WRITE_ONLY))
+ if (!qp->r_wrid_valid)
break;
+ qp->r_wrid_valid = 0;
wc.wr_id = qp->r_wr_id;
wc.status = IB_WC_SUCCESS;
wc.opcode = IB_WC_RECV;
@@ -1517,7 +1544,7 @@ void ipath_rc_rcv(struct ipath_ibdev *dev, struct ipath_ib_header *hdr,
int ok;
/* Check rkey & NAK */
- ok = ipath_rkey_ok(dev, &qp->r_sge,
+ ok = ipath_rkey_ok(qp, &qp->r_sge,
qp->r_len, vaddr, rkey,
IB_ACCESS_REMOTE_WRITE);
if (unlikely(!ok))
@@ -1559,7 +1586,7 @@ void ipath_rc_rcv(struct ipath_ibdev *dev, struct ipath_ib_header *hdr,
int ok;
/* Check rkey & NAK */
- ok = ipath_rkey_ok(dev, &qp->s_rdma_sge,
+ ok = ipath_rkey_ok(qp, &qp->s_rdma_sge,
qp->s_rdma_len, vaddr, rkey,
IB_ACCESS_REMOTE_READ);
if (unlikely(!ok)) {
@@ -1618,7 +1645,7 @@ void ipath_rc_rcv(struct ipath_ibdev *dev, struct ipath_ib_header *hdr,
goto nack_inv;
rkey = be32_to_cpu(ateth->rkey);
/* Check rkey & NAK */
- if (unlikely(!ipath_rkey_ok(dev, &qp->r_sge,
+ if (unlikely(!ipath_rkey_ok(qp, &qp->r_sge,
sizeof(u64), vaddr, rkey,
IB_ACCESS_REMOTE_ATOMIC)))
goto nack_acc;
@@ -1670,8 +1697,7 @@ nack_acc:
* is pending though.
*/
if (qp->r_ack_state < OP(COMPARE_SWAP)) {
- /* XXX Flush WQEs */
- qp->state = IB_QPS_ERR;
+ ipath_rc_error(qp, IB_WC_REM_ACCESS_ERR);
qp->r_ack_state = OP(RDMA_WRITE_ONLY);
qp->r_nak_state = IB_NAK_REMOTE_ACCESS_ERROR;
qp->r_ack_psn = qp->r_psn;
diff --git a/drivers/infiniband/hw/ipath/ipath_registers.h b/drivers/infiniband/hw/ipath/ipath_registers.h
index 6e23b3d632b8..dffc76016d3c 100644
--- a/drivers/infiniband/hw/ipath/ipath_registers.h
+++ b/drivers/infiniband/hw/ipath/ipath_registers.h
@@ -134,10 +134,24 @@
#define INFINIPATH_HWE_TXEMEMPARITYERR_SHIFT 40
#define INFINIPATH_HWE_RXEMEMPARITYERR_MASK 0x7FULL
#define INFINIPATH_HWE_RXEMEMPARITYERR_SHIFT 44
-#define INFINIPATH_HWE_RXDSYNCMEMPARITYERR 0x0000000400000000ULL
-#define INFINIPATH_HWE_MEMBISTFAILED 0x0040000000000000ULL
#define INFINIPATH_HWE_IBCBUSTOSPCPARITYERR 0x4000000000000000ULL
#define INFINIPATH_HWE_IBCBUSFRSPCPARITYERR 0x8000000000000000ULL
+/* txe mem parity errors (shift by INFINIPATH_HWE_TXEMEMPARITYERR_SHIFT) */
+#define INFINIPATH_HWE_TXEMEMPARITYERR_PIOBUF 0x1ULL
+#define INFINIPATH_HWE_TXEMEMPARITYERR_PIOPBC 0x2ULL
+#define INFINIPATH_HWE_TXEMEMPARITYERR_PIOLAUNCHFIFO 0x4ULL
+/* rxe mem parity errors (shift by INFINIPATH_HWE_RXEMEMPARITYERR_SHIFT) */
+#define INFINIPATH_HWE_RXEMEMPARITYERR_RCVBUF 0x01ULL
+#define INFINIPATH_HWE_RXEMEMPARITYERR_LOOKUPQ 0x02ULL
+#define INFINIPATH_HWE_RXEMEMPARITYERR_EAGERTID 0x04ULL
+#define INFINIPATH_HWE_RXEMEMPARITYERR_EXPTID 0x08ULL
+#define INFINIPATH_HWE_RXEMEMPARITYERR_FLAGBUF 0x10ULL
+#define INFINIPATH_HWE_RXEMEMPARITYERR_DATAINFO 0x20ULL
+#define INFINIPATH_HWE_RXEMEMPARITYERR_HDRINFO 0x40ULL
+/* waldo specific -- find the rest in ipath_6110.c */
+#define INFINIPATH_HWE_RXDSYNCMEMPARITYERR 0x0000000400000000ULL
+/* monty specific -- find the rest in ipath_6120.c */
+#define INFINIPATH_HWE_MEMBISTFAILED 0x0040000000000000ULL
/* kr_hwdiagctrl bits */
#define INFINIPATH_DC_FORCETXEMEMPARITYERR_MASK 0xFULL
@@ -209,9 +223,9 @@
/* combination link status states that we use with some frequency */
#define IPATH_IBSTATE_MASK ((INFINIPATH_IBCS_LINKTRAININGSTATE_MASK \
- << INFINIPATH_IBCS_LINKSTATE_SHIFT) | \
+ << INFINIPATH_IBCS_LINKTRAININGSTATE_SHIFT) | \
(INFINIPATH_IBCS_LINKSTATE_MASK \
- <<INFINIPATH_IBCS_LINKTRAININGSTATE_SHIFT))
+ <<INFINIPATH_IBCS_LINKSTATE_SHIFT))
#define IPATH_IBSTATE_INIT ((INFINIPATH_IBCS_L_STATE_INIT \
<< INFINIPATH_IBCS_LINKSTATE_SHIFT) | \
(INFINIPATH_IBCS_LT_STATE_LINKUP \
@@ -302,6 +316,17 @@
typedef u64 ipath_err_t;
+/* The following change with the type of device, so
+ * need to be part of the ipath_devdata struct, or
+ * we could have problems plugging in devices of
+ * different types (e.g. one HT, one PCIE)
+ * in one system, to be managed by one driver.
+ * On the other hand, this file is may also be included
+ * by other code, so leave the declarations here
+ * temporarily. Minor footprint issue if common-model
+ * linker used, none if C89+ linker used.
+ */
+
/* mask of defined bits for various registers */
extern u64 infinipath_i_bitsextant;
extern ipath_err_t infinipath_e_bitsextant, infinipath_hwe_bitsextant;
@@ -310,13 +335,6 @@ extern ipath_err_t infinipath_e_bitsextant, infinipath_hwe_bitsextant;
extern u32 infinipath_i_rcvavail_mask, infinipath_i_rcvurg_mask;
/*
- * register bits for selecting i2c direction and values, used for I2C serial
- * flash
- */
-extern u16 ipath_gpio_sda_num, ipath_gpio_scl_num;
-extern u64 ipath_gpio_sda, ipath_gpio_scl;
-
-/*
* These are the infinipath general register numbers (not offsets).
* The kernel registers are used directly, those beyond the kernel
* registers are calculated from one of the base registers. The use of
diff --git a/drivers/infiniband/hw/ipath/ipath_ruc.c b/drivers/infiniband/hw/ipath/ipath_ruc.c
index 5c1da2d25e03..f7530512045d 100644
--- a/drivers/infiniband/hw/ipath/ipath_ruc.c
+++ b/drivers/infiniband/hw/ipath/ipath_ruc.c
@@ -108,7 +108,6 @@ void ipath_insert_rnr_queue(struct ipath_qp *qp)
static int init_sge(struct ipath_qp *qp, struct ipath_rwqe *wqe)
{
- struct ipath_ibdev *dev = to_idev(qp->ibqp.device);
int user = to_ipd(qp->ibqp.pd)->user;
int i, j, ret;
struct ib_wc wc;
@@ -119,8 +118,7 @@ static int init_sge(struct ipath_qp *qp, struct ipath_rwqe *wqe)
continue;
/* Check LKEY */
if ((user && wqe->sg_list[i].lkey == 0) ||
- !ipath_lkey_ok(&dev->lk_table,
- &qp->r_sg_list[j], &wqe->sg_list[i],
+ !ipath_lkey_ok(qp, &qp->r_sg_list[j], &wqe->sg_list[i],
IB_ACCESS_LOCAL_WRITE))
goto bad_lkey;
qp->r_len += wqe->sg_list[i].length;
@@ -231,6 +229,7 @@ int ipath_get_rwqe(struct ipath_qp *qp, int wr_id_only)
}
}
spin_unlock_irqrestore(&rq->lock, flags);
+ qp->r_wrid_valid = 1;
bail:
return ret;
@@ -326,7 +325,7 @@ again:
case IB_WR_RDMA_WRITE:
if (wqe->length == 0)
break;
- if (unlikely(!ipath_rkey_ok(dev, &qp->r_sge, wqe->length,
+ if (unlikely(!ipath_rkey_ok(qp, &qp->r_sge, wqe->length,
wqe->wr.wr.rdma.remote_addr,
wqe->wr.wr.rdma.rkey,
IB_ACCESS_REMOTE_WRITE))) {
@@ -350,7 +349,7 @@ again:
break;
case IB_WR_RDMA_READ:
- if (unlikely(!ipath_rkey_ok(dev, &sqp->s_sge, wqe->length,
+ if (unlikely(!ipath_rkey_ok(qp, &sqp->s_sge, wqe->length,
wqe->wr.wr.rdma.remote_addr,
wqe->wr.wr.rdma.rkey,
IB_ACCESS_REMOTE_READ)))
@@ -365,7 +364,7 @@ again:
case IB_WR_ATOMIC_CMP_AND_SWP:
case IB_WR_ATOMIC_FETCH_AND_ADD:
- if (unlikely(!ipath_rkey_ok(dev, &qp->r_sge, sizeof(u64),
+ if (unlikely(!ipath_rkey_ok(qp, &qp->r_sge, sizeof(u64),
wqe->wr.wr.rdma.remote_addr,
wqe->wr.wr.rdma.rkey,
IB_ACCESS_REMOTE_ATOMIC)))
@@ -575,8 +574,7 @@ int ipath_post_ruc_send(struct ipath_qp *qp, struct ib_send_wr *wr)
}
if (wr->sg_list[i].length == 0)
continue;
- if (!ipath_lkey_ok(&to_idev(qp->ibqp.device)->lk_table,
- &wqe->sg_list[j], &wr->sg_list[i],
+ if (!ipath_lkey_ok(qp, &wqe->sg_list[j], &wr->sg_list[i],
acc)) {
spin_unlock_irqrestore(&qp->s_lock, flags);
ret = -EINVAL;
diff --git a/drivers/infiniband/hw/ipath/ipath_srq.c b/drivers/infiniband/hw/ipath/ipath_srq.c
index 941e866d9517..94033503400c 100644
--- a/drivers/infiniband/hw/ipath/ipath_srq.c
+++ b/drivers/infiniband/hw/ipath/ipath_srq.c
@@ -104,11 +104,6 @@ struct ib_srq *ipath_create_srq(struct ib_pd *ibpd,
u32 sz;
struct ib_srq *ret;
- if (dev->n_srqs_allocated == ib_ipath_max_srqs) {
- ret = ERR_PTR(-ENOMEM);
- goto done;
- }
-
if (srq_init_attr->attr.max_wr == 0) {
ret = ERR_PTR(-EINVAL);
goto done;
@@ -180,10 +175,17 @@ struct ib_srq *ipath_create_srq(struct ib_pd *ibpd,
spin_lock_init(&srq->rq.lock);
srq->rq.wq->head = 0;
srq->rq.wq->tail = 0;
- srq->rq.max_sge = srq_init_attr->attr.max_sge;
srq->limit = srq_init_attr->attr.srq_limit;
- dev->n_srqs_allocated++;
+ spin_lock(&dev->n_srqs_lock);
+ if (dev->n_srqs_allocated == ib_ipath_max_srqs) {
+ spin_unlock(&dev->n_srqs_lock);
+ ret = ERR_PTR(-ENOMEM);
+ goto bail_wq;
+ }
+
+ dev->n_srqs_allocated++;
+ spin_unlock(&dev->n_srqs_lock);
ret = &srq->ibsrq;
goto done;
@@ -351,8 +353,13 @@ int ipath_destroy_srq(struct ib_srq *ibsrq)
struct ipath_srq *srq = to_isrq(ibsrq);
struct ipath_ibdev *dev = to_idev(ibsrq->device);
+ spin_lock(&dev->n_srqs_lock);
dev->n_srqs_allocated--;
- vfree(srq->rq.wq);
+ spin_unlock(&dev->n_srqs_lock);
+ if (srq->ip)
+ kref_put(&srq->ip->ref, ipath_release_mmap_info);
+ else
+ vfree(srq->rq.wq);
kfree(srq);
return 0;
diff --git a/drivers/infiniband/hw/ipath/ipath_sysfs.c b/drivers/infiniband/hw/ipath/ipath_sysfs.c
index e299148c4b68..182de34f9f47 100644
--- a/drivers/infiniband/hw/ipath/ipath_sysfs.c
+++ b/drivers/infiniband/hw/ipath/ipath_sysfs.c
@@ -257,7 +257,7 @@ static ssize_t store_guid(struct device *dev,
struct ipath_devdata *dd = dev_get_drvdata(dev);
ssize_t ret;
unsigned short guid[8];
- __be64 nguid;
+ __be64 new_guid;
u8 *ng;
int i;
@@ -266,7 +266,7 @@ static ssize_t store_guid(struct device *dev,
&guid[4], &guid[5], &guid[6], &guid[7]) != 8)
goto invalid;
- ng = (u8 *) &nguid;
+ ng = (u8 *) &new_guid;
for (i = 0; i < 8; i++) {
if (guid[i] > 0xff)
@@ -274,7 +274,10 @@ static ssize_t store_guid(struct device *dev,
ng[i] = guid[i];
}
- dd->ipath_guid = nguid;
+ if (new_guid == 0)
+ goto invalid;
+
+ dd->ipath_guid = new_guid;
dd->ipath_nguid = 1;
ret = strlen(buf);
@@ -297,6 +300,16 @@ static ssize_t show_nguid(struct device *dev,
return scnprintf(buf, PAGE_SIZE, "%u\n", dd->ipath_nguid);
}
+static ssize_t show_nports(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct ipath_devdata *dd = dev_get_drvdata(dev);
+
+ /* Return the number of user ports available. */
+ return scnprintf(buf, PAGE_SIZE, "%u\n", dd->ipath_cfgports - 1);
+}
+
static ssize_t show_serial(struct device *dev,
struct device_attribute *attr,
char *buf)
@@ -608,6 +621,7 @@ static DEVICE_ATTR(mlid, S_IWUSR | S_IRUGO, show_mlid, store_mlid);
static DEVICE_ATTR(mtu, S_IWUSR | S_IRUGO, show_mtu, store_mtu);
static DEVICE_ATTR(enabled, S_IWUSR | S_IRUGO, show_enabled, store_enabled);
static DEVICE_ATTR(nguid, S_IRUGO, show_nguid, NULL);
+static DEVICE_ATTR(nports, S_IRUGO, show_nports, NULL);
static DEVICE_ATTR(reset, S_IWUSR, NULL, store_reset);
static DEVICE_ATTR(serial, S_IRUGO, show_serial, NULL);
static DEVICE_ATTR(status, S_IRUGO, show_status, NULL);
@@ -623,6 +637,7 @@ static struct attribute *dev_attributes[] = {
&dev_attr_mlid.attr,
&dev_attr_mtu.attr,
&dev_attr_nguid.attr,
+ &dev_attr_nports.attr,
&dev_attr_serial.attr,
&dev_attr_status.attr,
&dev_attr_status_str.attr,
diff --git a/drivers/infiniband/hw/ipath/ipath_uc.c b/drivers/infiniband/hw/ipath/ipath_uc.c
index 0fd3cded16ba..e636cfd67a82 100644
--- a/drivers/infiniband/hw/ipath/ipath_uc.c
+++ b/drivers/infiniband/hw/ipath/ipath_uc.c
@@ -246,6 +246,10 @@ void ipath_uc_rcv(struct ipath_ibdev *dev, struct ipath_ib_header *hdr,
struct ib_reth *reth;
int header_in_data;
+ /* Validate the SLID. See Ch. 9.6.1.5 */
+ if (unlikely(be16_to_cpu(hdr->lrh[3]) != qp->remote_ah_attr.dlid))
+ goto done;
+
/* Check for GRH */
if (!has_grh) {
ohdr = &hdr->u.oth;
@@ -440,7 +444,7 @@ void ipath_uc_rcv(struct ipath_ibdev *dev, struct ipath_ib_header *hdr,
int ok;
/* Check rkey */
- ok = ipath_rkey_ok(dev, &qp->r_sge, qp->r_len,
+ ok = ipath_rkey_ok(qp, &qp->r_sge, qp->r_len,
vaddr, rkey,
IB_ACCESS_REMOTE_WRITE);
if (unlikely(!ok)) {
diff --git a/drivers/infiniband/hw/ipath/ipath_ud.c b/drivers/infiniband/hw/ipath/ipath_ud.c
index 6991d1d74e3c..49f1102af8b3 100644
--- a/drivers/infiniband/hw/ipath/ipath_ud.c
+++ b/drivers/infiniband/hw/ipath/ipath_ud.c
@@ -39,7 +39,6 @@
static int init_sge(struct ipath_qp *qp, struct ipath_rwqe *wqe,
u32 *lengthp, struct ipath_sge_state *ss)
{
- struct ipath_ibdev *dev = to_idev(qp->ibqp.device);
int user = to_ipd(qp->ibqp.pd)->user;
int i, j, ret;
struct ib_wc wc;
@@ -50,8 +49,7 @@ static int init_sge(struct ipath_qp *qp, struct ipath_rwqe *wqe,
continue;
/* Check LKEY */
if ((user && wqe->sg_list[i].lkey == 0) ||
- !ipath_lkey_ok(&dev->lk_table,
- j ? &ss->sg_list[j - 1] : &ss->sge,
+ !ipath_lkey_ok(qp, j ? &ss->sg_list[j - 1] : &ss->sge,
&wqe->sg_list[i], IB_ACCESS_LOCAL_WRITE))
goto bad_lkey;
*lengthp += wqe->sg_list[i].length;
@@ -343,7 +341,7 @@ int ipath_post_ud_send(struct ipath_qp *qp, struct ib_send_wr *wr)
if (wr->sg_list[i].length == 0)
continue;
- if (!ipath_lkey_ok(&dev->lk_table, ss.num_sge ?
+ if (!ipath_lkey_ok(qp, ss.num_sge ?
sg_list + ss.num_sge - 1 : &ss.sge,
&wr->sg_list[i], 0)) {
ret = -EINVAL;
diff --git a/drivers/infiniband/hw/ipath/ipath_user_pages.c b/drivers/infiniband/hw/ipath/ipath_user_pages.c
index e32fca9faf80..413754b1d8a2 100644
--- a/drivers/infiniband/hw/ipath/ipath_user_pages.c
+++ b/drivers/infiniband/hw/ipath/ipath_user_pages.c
@@ -90,6 +90,62 @@ bail:
}
/**
+ * ipath_map_page - a safety wrapper around pci_map_page()
+ *
+ * A dma_addr of all 0's is interpreted by the chip as "disabled".
+ * Unfortunately, it can also be a valid dma_addr returned on some
+ * architectures.
+ *
+ * The powerpc iommu assigns dma_addrs in ascending order, so we don't
+ * have to bother with retries or mapping a dummy page to insure we
+ * don't just get the same mapping again.
+ *
+ * I'm sure we won't be so lucky with other iommu's, so FIXME.
+ */
+dma_addr_t ipath_map_page(struct pci_dev *hwdev, struct page *page,
+ unsigned long offset, size_t size, int direction)
+{
+ dma_addr_t phys;
+
+ phys = pci_map_page(hwdev, page, offset, size, direction);
+
+ if (phys == 0) {
+ pci_unmap_page(hwdev, phys, size, direction);
+ phys = pci_map_page(hwdev, page, offset, size, direction);
+ /*
+ * FIXME: If we get 0 again, we should keep this page,
+ * map another, then free the 0 page.
+ */
+ }
+
+ return phys;
+}
+
+/**
+ * ipath_map_single - a safety wrapper around pci_map_single()
+ *
+ * Same idea as ipath_map_page().
+ */
+dma_addr_t ipath_map_single(struct pci_dev *hwdev, void *ptr, size_t size,
+ int direction)
+{
+ dma_addr_t phys;
+
+ phys = pci_map_single(hwdev, ptr, size, direction);
+
+ if (phys == 0) {
+ pci_unmap_single(hwdev, phys, size, direction);
+ phys = pci_map_single(hwdev, ptr, size, direction);
+ /*
+ * FIXME: If we get 0 again, we should keep this page,
+ * map another, then free the 0 page.
+ */
+ }
+
+ return phys;
+}
+
+/**
* ipath_get_user_pages - lock user pages into memory
* @start_page: the start page
* @num_pages: the number of pages
diff --git a/drivers/infiniband/hw/ipath/ipath_verbs.c b/drivers/infiniband/hw/ipath/ipath_verbs.c
index b8381c5e72bd..a5456108dbad 100644
--- a/drivers/infiniband/hw/ipath/ipath_verbs.c
+++ b/drivers/infiniband/hw/ipath/ipath_verbs.c
@@ -898,7 +898,8 @@ int ipath_get_counters(struct ipath_devdata *dd,
ipath_snap_cntr(dd, dd->ipath_cregs->cr_erricrccnt) +
ipath_snap_cntr(dd, dd->ipath_cregs->cr_errvcrccnt) +
ipath_snap_cntr(dd, dd->ipath_cregs->cr_errlpcrccnt) +
- ipath_snap_cntr(dd, dd->ipath_cregs->cr_badformatcnt);
+ ipath_snap_cntr(dd, dd->ipath_cregs->cr_badformatcnt) +
+ dd->ipath_rxfc_unsupvl_errs;
cntrs->port_rcv_remphys_errors =
ipath_snap_cntr(dd, dd->ipath_cregs->cr_rcvebpcnt);
cntrs->port_xmit_discards =
@@ -911,8 +912,10 @@ int ipath_get_counters(struct ipath_devdata *dd,
ipath_snap_cntr(dd, dd->ipath_cregs->cr_pktsendcnt);
cntrs->port_rcv_packets =
ipath_snap_cntr(dd, dd->ipath_cregs->cr_pktrcvcnt);
- cntrs->local_link_integrity_errors = dd->ipath_lli_errors;
- cntrs->excessive_buffer_overrun_errors = 0; /* XXX */
+ cntrs->local_link_integrity_errors =
+ (dd->ipath_flags & IPATH_GPIO_ERRINTRS) ?
+ dd->ipath_lli_errs : dd->ipath_lli_errors;
+ cntrs->excessive_buffer_overrun_errors = dd->ipath_overrun_thresh_errs;
ret = 0;
@@ -1199,6 +1202,7 @@ static struct ib_ah *ipath_create_ah(struct ib_pd *pd,
struct ipath_ah *ah;
struct ib_ah *ret;
struct ipath_ibdev *dev = to_idev(pd->device);
+ unsigned long flags;
/* A multicast address requires a GRH (see ch. 8.4.1). */
if (ah_attr->dlid >= IPATH_MULTICAST_LID_BASE &&
@@ -1225,16 +1229,16 @@ static struct ib_ah *ipath_create_ah(struct ib_pd *pd,
goto bail;
}
- spin_lock(&dev->n_ahs_lock);
+ spin_lock_irqsave(&dev->n_ahs_lock, flags);
if (dev->n_ahs_allocated == ib_ipath_max_ahs) {
- spin_unlock(&dev->n_ahs_lock);
+ spin_unlock_irqrestore(&dev->n_ahs_lock, flags);
kfree(ah);
ret = ERR_PTR(-ENOMEM);
goto bail;
}
dev->n_ahs_allocated++;
- spin_unlock(&dev->n_ahs_lock);
+ spin_unlock_irqrestore(&dev->n_ahs_lock, flags);
/* ib_create_ah() will initialize ah->ibah. */
ah->attr = *ah_attr;
@@ -1255,10 +1259,11 @@ static int ipath_destroy_ah(struct ib_ah *ibah)
{
struct ipath_ibdev *dev = to_idev(ibah->device);
struct ipath_ah *ah = to_iah(ibah);
+ unsigned long flags;
- spin_lock(&dev->n_ahs_lock);
+ spin_lock_irqsave(&dev->n_ahs_lock, flags);
dev->n_ahs_allocated--;
- spin_unlock(&dev->n_ahs_lock);
+ spin_unlock_irqrestore(&dev->n_ahs_lock, flags);
kfree(ah);
@@ -1380,11 +1385,13 @@ static int enable_timer(struct ipath_devdata *dd)
* processing.
*/
if (dd->ipath_flags & IPATH_GPIO_INTR) {
+ u64 val;
ipath_write_kreg(dd, dd->ipath_kregs->kr_debugportselect,
0x2074076542310ULL);
/* Enable GPIO bit 2 interrupt */
- ipath_write_kreg(dd, dd->ipath_kregs->kr_gpio_mask,
- (u64) (1 << 2));
+ val = ipath_read_kreg64(dd, dd->ipath_kregs->kr_gpio_mask);
+ val |= (u64) (1 << IPATH_GPIO_PORT0_BIT);
+ ipath_write_kreg( dd, dd->ipath_kregs->kr_gpio_mask, val);
}
init_timer(&dd->verbs_timer);
@@ -1399,8 +1406,17 @@ static int enable_timer(struct ipath_devdata *dd)
static int disable_timer(struct ipath_devdata *dd)
{
/* Disable GPIO bit 2 interrupt */
- if (dd->ipath_flags & IPATH_GPIO_INTR)
- ipath_write_kreg(dd, dd->ipath_kregs->kr_gpio_mask, 0);
+ if (dd->ipath_flags & IPATH_GPIO_INTR) {
+ u64 val;
+ /* Disable GPIO bit 2 interrupt */
+ val = ipath_read_kreg64(dd, dd->ipath_kregs->kr_gpio_mask);
+ val &= ~((u64) (1 << IPATH_GPIO_PORT0_BIT));
+ ipath_write_kreg( dd, dd->ipath_kregs->kr_gpio_mask, val);
+ /*
+ * We might want to undo changes to debugportselect,
+ * but how?
+ */
+ }
del_timer_sync(&dd->verbs_timer);
@@ -1585,7 +1601,7 @@ int ipath_register_ib_device(struct ipath_devdata *dd)
dev->mmap = ipath_mmap;
snprintf(dev->node_desc, sizeof(dev->node_desc),
- IPATH_IDSTR " %s", system_utsname.nodename);
+ IPATH_IDSTR " %s", init_utsname()->nodename);
ret = ib_register_device(dev);
if (ret)
@@ -1683,6 +1699,7 @@ static ssize_t show_stats(struct class_device *cdev, char *buf)
"RC OTH NAKs %d\n"
"RC timeouts %d\n"
"RC RDMA dup %d\n"
+ "RC stalls %d\n"
"piobuf wait %d\n"
"no piobuf %d\n"
"PKT drops %d\n"
@@ -1690,7 +1707,7 @@ static ssize_t show_stats(struct class_device *cdev, char *buf)
dev->n_rc_resends, dev->n_rc_qacks, dev->n_rc_acks,
dev->n_seq_naks, dev->n_rdma_seq, dev->n_rnr_naks,
dev->n_other_naks, dev->n_timeouts,
- dev->n_rdma_dup_busy, dev->n_piowait,
+ dev->n_rdma_dup_busy, dev->n_rc_stalls, dev->n_piowait,
dev->n_no_piobuf, dev->n_pkt_drops, dev->n_wqe_errs);
for (i = 0; i < ARRAY_SIZE(dev->opstats); i++) {
const struct ipath_opcode_stats *si = &dev->opstats[i];
diff --git a/drivers/infiniband/hw/ipath/ipath_verbs.h b/drivers/infiniband/hw/ipath/ipath_verbs.h
index 09bbb3f9a217..8039f6e5f0c8 100644
--- a/drivers/infiniband/hw/ipath/ipath_verbs.h
+++ b/drivers/infiniband/hw/ipath/ipath_verbs.h
@@ -220,6 +220,7 @@ struct ipath_segarray {
};
struct ipath_mregion {
+ struct ib_pd *pd; /* shares refcnt of ibmr.pd */
u64 user_base; /* User's address for this region */
u64 iova; /* IB start address of this region */
size_t length;
@@ -364,12 +365,14 @@ struct ipath_qp {
u8 r_min_rnr_timer; /* retry timeout value for RNR NAKs */
u8 r_reuse_sge; /* for UC receive errors */
u8 r_sge_inx; /* current index into sg_list */
+ u8 r_wrid_valid; /* r_wrid set but CQ entry not yet made */
u8 qp_access_flags;
u8 s_max_sge; /* size of s_wq->sg_list */
u8 s_retry_cnt; /* number of times to retry */
u8 s_rnr_retry_cnt;
u8 s_retry; /* requester retry counter */
u8 s_rnr_retry; /* requester RNR retry counter */
+ u8 s_wait_credit; /* limit number of unacked packets sent */
u8 s_pkey_index; /* PKEY index to use */
u8 timeout; /* Timeout for this QP */
enum ib_mtu path_mtu;
@@ -393,6 +396,8 @@ struct ipath_qp {
#define IPATH_S_BUSY 0
#define IPATH_S_SIGNAL_REQ_WR 1
+#define IPATH_PSN_CREDIT 2048
+
/*
* Since struct ipath_swqe is not a fixed size, we can't simply index into
* struct ipath_qp.s_wq. This function does the array index computation.
@@ -521,6 +526,7 @@ struct ipath_ibdev {
u32 n_rnr_naks;
u32 n_other_naks;
u32 n_timeouts;
+ u32 n_rc_stalls;
u32 n_pkt_drops;
u32 n_vl15_dropped;
u32 n_wqe_errs;
@@ -634,6 +640,8 @@ struct ib_qp *ipath_create_qp(struct ib_pd *ibpd,
int ipath_destroy_qp(struct ib_qp *ibqp);
+void ipath_error_qp(struct ipath_qp *qp, enum ib_wc_status err);
+
int ipath_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr,
int attr_mask, struct ib_udata *udata);
@@ -653,12 +661,6 @@ int ipath_verbs_send(struct ipath_devdata *dd, u32 hdrwords,
void ipath_cq_enter(struct ipath_cq *cq, struct ib_wc *entry, int sig);
-int ipath_rkey_ok(struct ipath_ibdev *dev, struct ipath_sge_state *ss,
- u32 len, u64 vaddr, u32 rkey, int acc);
-
-int ipath_lkey_ok(struct ipath_lkey_table *rkt, struct ipath_sge *isge,
- struct ib_sge *sge, int acc);
-
void ipath_copy_sge(struct ipath_sge_state *ss, void *data, u32 length);
void ipath_skip_sge(struct ipath_sge_state *ss, u32 length);
@@ -683,10 +685,10 @@ int ipath_alloc_lkey(struct ipath_lkey_table *rkt,
void ipath_free_lkey(struct ipath_lkey_table *rkt, u32 lkey);
-int ipath_lkey_ok(struct ipath_lkey_table *rkt, struct ipath_sge *isge,
+int ipath_lkey_ok(struct ipath_qp *qp, struct ipath_sge *isge,
struct ib_sge *sge, int acc);
-int ipath_rkey_ok(struct ipath_ibdev *dev, struct ipath_sge_state *ss,
+int ipath_rkey_ok(struct ipath_qp *qp, struct ipath_sge_state *ss,
u32 len, u64 vaddr, u32 rkey, int acc);
int ipath_post_srq_receive(struct ib_srq *ibsrq, struct ib_recv_wr *wr,
diff --git a/drivers/infiniband/hw/ipath/ipath_wc_ppc64.c b/drivers/infiniband/hw/ipath/ipath_wc_ppc64.c
index 036fde662aa9..0095bb70f34e 100644
--- a/drivers/infiniband/hw/ipath/ipath_wc_ppc64.c
+++ b/drivers/infiniband/hw/ipath/ipath_wc_ppc64.c
@@ -38,13 +38,23 @@
#include "ipath_kernel.h"
/**
- * ipath_unordered_wc - indicate whether write combining is ordered
+ * ipath_enable_wc - enable write combining for MMIO writes to the device
+ * @dd: infinipath device
*
- * PowerPC systems (at least those in the 970 processor family)
- * write partially filled store buffers in address order, but will write
- * completely filled store buffers in "random" order, and therefore must
- * have serialization for correctness with current InfiniPath chips.
+ * Nothing to do on PowerPC, so just return without error.
+ */
+int ipath_enable_wc(struct ipath_devdata *dd)
+{
+ return 0;
+}
+
+/**
+ * ipath_unordered_wc - indicate whether write combining is unordered
*
+ * Because our performance depends on our ability to do write
+ * combining mmio writes in the most efficient way, we need to
+ * know if we are on a processor that may reorder stores when
+ * write combining.
*/
int ipath_unordered_wc(void)
{
diff --git a/drivers/infiniband/hw/ipath/ipath_wc_x86_64.c b/drivers/infiniband/hw/ipath/ipath_wc_x86_64.c
index f8f9e2e8cbdd..04696e62da87 100644
--- a/drivers/infiniband/hw/ipath/ipath_wc_x86_64.c
+++ b/drivers/infiniband/hw/ipath/ipath_wc_x86_64.c
@@ -123,6 +123,8 @@ int ipath_enable_wc(struct ipath_devdata *dd)
ipath_cdbg(VERBOSE, "Set mtrr for chip to WC, "
"cookie is %d\n", cookie);
dd->ipath_wc_cookie = cookie;
+ dd->ipath_wc_base = (unsigned long) pioaddr;
+ dd->ipath_wc_len = (unsigned long) piolen;
}
}
@@ -136,9 +138,16 @@ int ipath_enable_wc(struct ipath_devdata *dd)
void ipath_disable_wc(struct ipath_devdata *dd)
{
if (dd->ipath_wc_cookie) {
+ int r;
ipath_cdbg(VERBOSE, "undoing WCCOMB on pio buffers\n");
- mtrr_del(dd->ipath_wc_cookie, 0, 0);
- dd->ipath_wc_cookie = 0;
+ r = mtrr_del(dd->ipath_wc_cookie, dd->ipath_wc_base,
+ dd->ipath_wc_len);
+ if (r < 0)
+ dev_info(&dd->pcidev->dev,
+ "mtrr_del(%lx, %lx, %lx) failed: %d\n",
+ dd->ipath_wc_cookie, dd->ipath_wc_base,
+ dd->ipath_wc_len, r);
+ dd->ipath_wc_cookie = 0; /* even on failure */
}
}
diff --git a/drivers/infiniband/ulp/iser/Kconfig b/drivers/infiniband/ulp/iser/Kconfig
index 365a1b5f19e0..aecbb9083f0c 100644
--- a/drivers/infiniband/ulp/iser/Kconfig
+++ b/drivers/infiniband/ulp/iser/Kconfig
@@ -1,11 +1,12 @@
config INFINIBAND_ISER
- tristate "ISCSI RDMA Protocol"
+ tristate "iSCSI Extensions for RDMA (iSER)"
depends on INFINIBAND && SCSI && INET
select SCSI_ISCSI_ATTRS
---help---
- Support for the ISCSI RDMA Protocol over InfiniBand. This
- allows you to access storage devices that speak ISER/ISCSI
- over InfiniBand.
+ Support for the iSCSI Extensions for RDMA (iSER) Protocol
+ over InfiniBand. This allows you to access storage devices
+ that speak iSCSI over iSER over InfiniBand.
- The ISER protocol is defined by IETF.
- See <http://www.ietf.org/>.
+ The iSER protocol is defined by IETF.
+ See <http://www.ietf.org/internet-drafts/draft-ietf-ips-iser-05.txt>
+ and <http://www.infinibandta.org/members/spec/iser_annex_060418.pdf>
diff --git a/drivers/infiniband/ulp/iser/iscsi_iser.c b/drivers/infiniband/ulp/iser/iscsi_iser.c
index 2a14fe2e3226..eb6f98d82289 100644
--- a/drivers/infiniband/ulp/iser/iscsi_iser.c
+++ b/drivers/infiniband/ulp/iser/iscsi_iser.c
@@ -317,6 +317,8 @@ iscsi_iser_conn_destroy(struct iscsi_cls_conn *cls_conn)
struct iscsi_iser_conn *iser_conn = conn->dd_data;
iscsi_conn_teardown(cls_conn);
+ if (iser_conn->ib_conn)
+ iser_conn->ib_conn->iser_conn = NULL;
kfree(iser_conn);
}
diff --git a/drivers/infiniband/ulp/iser/iscsi_iser.h b/drivers/infiniband/ulp/iser/iscsi_iser.h
index 2cf9ae0def1c..9c53916f28c2 100644
--- a/drivers/infiniband/ulp/iser/iscsi_iser.h
+++ b/drivers/infiniband/ulp/iser/iscsi_iser.h
@@ -192,7 +192,7 @@ struct iser_regd_buf {
struct iser_dto {
struct iscsi_iser_cmd_task *ctask;
- struct iscsi_iser_conn *conn;
+ struct iser_conn *ib_conn;
int notify_enable;
/* vector of registered buffers */
@@ -355,4 +355,11 @@ int iser_post_send(struct iser_desc *tx_desc);
int iser_conn_state_comp(struct iser_conn *ib_conn,
enum iser_ib_conn_state comp);
+
+int iser_dma_map_task_data(struct iscsi_iser_cmd_task *iser_ctask,
+ struct iser_data_buf *data,
+ enum iser_data_dir iser_dir,
+ enum dma_data_direction dma_dir);
+
+void iser_dma_unmap_task_data(struct iscsi_iser_cmd_task *iser_ctask);
#endif
diff --git a/drivers/infiniband/ulp/iser/iser_initiator.c b/drivers/infiniband/ulp/iser/iser_initiator.c
index ccf56f6f7236..9b3d79c796c8 100644
--- a/drivers/infiniband/ulp/iser/iser_initiator.c
+++ b/drivers/infiniband/ulp/iser/iser_initiator.c
@@ -66,42 +66,6 @@ static void iser_dto_add_regd_buff(struct iser_dto *dto,
dto->regd_vector_len++;
}
-static int iser_dma_map_task_data(struct iscsi_iser_cmd_task *iser_ctask,
- struct iser_data_buf *data,
- enum iser_data_dir iser_dir,
- enum dma_data_direction dma_dir)
-{
- struct device *dma_device;
-
- iser_ctask->dir[iser_dir] = 1;
- dma_device = iser_ctask->iser_conn->ib_conn->device->ib_device->dma_device;
-
- data->dma_nents = dma_map_sg(dma_device, data->buf, data->size, dma_dir);
- if (data->dma_nents == 0) {
- iser_err("dma_map_sg failed!!!\n");
- return -EINVAL;
- }
- return 0;
-}
-
-static void iser_dma_unmap_task_data(struct iscsi_iser_cmd_task *iser_ctask)
-{
- struct device *dma_device;
- struct iser_data_buf *data;
-
- dma_device = iser_ctask->iser_conn->ib_conn->device->ib_device->dma_device;
-
- if (iser_ctask->dir[ISER_DIR_IN]) {
- data = &iser_ctask->data[ISER_DIR_IN];
- dma_unmap_sg(dma_device, data->buf, data->size, DMA_FROM_DEVICE);
- }
-
- if (iser_ctask->dir[ISER_DIR_OUT]) {
- data = &iser_ctask->data[ISER_DIR_OUT];
- dma_unmap_sg(dma_device, data->buf, data->size, DMA_TO_DEVICE);
- }
-}
-
/* Register user buffer memory and initialize passive rdma
* dto descriptor. Total data size is stored in
* iser_ctask->data[ISER_DIR_IN].data_len
@@ -249,7 +213,7 @@ static int iser_post_receive_control(struct iscsi_conn *conn)
}
recv_dto = &rx_desc->dto;
- recv_dto->conn = iser_conn;
+ recv_dto->ib_conn = iser_conn->ib_conn;
recv_dto->regd_vector_len = 0;
regd_hdr = &rx_desc->hdr_regd_buf;
@@ -296,7 +260,7 @@ static void iser_create_send_desc(struct iscsi_iser_conn *iser_conn,
regd_hdr->virt_addr = tx_desc; /* == &tx_desc->iser_header */
regd_hdr->data_size = ISER_TOTAL_HEADERS_LEN;
- send_dto->conn = iser_conn;
+ send_dto->ib_conn = iser_conn->ib_conn;
send_dto->notify_enable = 1;
send_dto->regd_vector_len = 0;
@@ -588,7 +552,7 @@ void iser_rcv_completion(struct iser_desc *rx_desc,
unsigned long dto_xfer_len)
{
struct iser_dto *dto = &rx_desc->dto;
- struct iscsi_iser_conn *conn = dto->conn;
+ struct iscsi_iser_conn *conn = dto->ib_conn->iser_conn;
struct iscsi_session *session = conn->iscsi_conn->session;
struct iscsi_cmd_task *ctask;
struct iscsi_iser_cmd_task *iser_ctask;
@@ -641,7 +605,8 @@ void iser_rcv_completion(struct iser_desc *rx_desc,
void iser_snd_completion(struct iser_desc *tx_desc)
{
struct iser_dto *dto = &tx_desc->dto;
- struct iscsi_iser_conn *iser_conn = dto->conn;
+ struct iser_conn *ib_conn = dto->ib_conn;
+ struct iscsi_iser_conn *iser_conn = ib_conn->iser_conn;
struct iscsi_conn *conn = iser_conn->iscsi_conn;
struct iscsi_mgmt_task *mtask;
@@ -652,7 +617,7 @@ void iser_snd_completion(struct iser_desc *tx_desc)
if (tx_desc->type == ISCSI_TX_DATAOUT)
kmem_cache_free(ig.desc_cache, tx_desc);
- atomic_dec(&iser_conn->ib_conn->post_send_buf_count);
+ atomic_dec(&ib_conn->post_send_buf_count);
write_lock(conn->recv_lock);
if (conn->suspend_tx) {
@@ -698,14 +663,19 @@ void iser_ctask_rdma_init(struct iscsi_iser_cmd_task *iser_ctask)
void iser_ctask_rdma_finalize(struct iscsi_iser_cmd_task *iser_ctask)
{
int deferred;
+ int is_rdma_aligned = 1;
/* if we were reading, copy back to unaligned sglist,
* anyway dma_unmap and free the copy
*/
- if (iser_ctask->data_copy[ISER_DIR_IN].copy_buf != NULL)
+ if (iser_ctask->data_copy[ISER_DIR_IN].copy_buf != NULL) {
+ is_rdma_aligned = 0;
iser_finalize_rdma_unaligned_sg(iser_ctask, ISER_DIR_IN);
- if (iser_ctask->data_copy[ISER_DIR_OUT].copy_buf != NULL)
+ }
+ if (iser_ctask->data_copy[ISER_DIR_OUT].copy_buf != NULL) {
+ is_rdma_aligned = 0;
iser_finalize_rdma_unaligned_sg(iser_ctask, ISER_DIR_OUT);
+ }
if (iser_ctask->dir[ISER_DIR_IN]) {
deferred = iser_regd_buff_release
@@ -725,7 +695,9 @@ void iser_ctask_rdma_finalize(struct iscsi_iser_cmd_task *iser_ctask)
}
}
- iser_dma_unmap_task_data(iser_ctask);
+ /* if the data was unaligned, it was already unmapped and then copied */
+ if (is_rdma_aligned)
+ iser_dma_unmap_task_data(iser_ctask);
}
void iser_dto_buffs_release(struct iser_dto *dto)
diff --git a/drivers/infiniband/ulp/iser/iser_memory.c b/drivers/infiniband/ulp/iser/iser_memory.c
index d0b03f426581..0606744c3f84 100644
--- a/drivers/infiniband/ulp/iser/iser_memory.c
+++ b/drivers/infiniband/ulp/iser/iser_memory.c
@@ -369,6 +369,44 @@ static void iser_page_vec_build(struct iser_data_buf *data,
}
}
+int iser_dma_map_task_data(struct iscsi_iser_cmd_task *iser_ctask,
+ struct iser_data_buf *data,
+ enum iser_data_dir iser_dir,
+ enum dma_data_direction dma_dir)
+{
+ struct device *dma_device;
+
+ iser_ctask->dir[iser_dir] = 1;
+ dma_device =
+ iser_ctask->iser_conn->ib_conn->device->ib_device->dma_device;
+
+ data->dma_nents = dma_map_sg(dma_device, data->buf, data->size, dma_dir);
+ if (data->dma_nents == 0) {
+ iser_err("dma_map_sg failed!!!\n");
+ return -EINVAL;
+ }
+ return 0;
+}
+
+void iser_dma_unmap_task_data(struct iscsi_iser_cmd_task *iser_ctask)
+{
+ struct device *dma_device;
+ struct iser_data_buf *data;
+
+ dma_device =
+ iser_ctask->iser_conn->ib_conn->device->ib_device->dma_device;
+
+ if (iser_ctask->dir[ISER_DIR_IN]) {
+ data = &iser_ctask->data[ISER_DIR_IN];
+ dma_unmap_sg(dma_device, data->buf, data->size, DMA_FROM_DEVICE);
+ }
+
+ if (iser_ctask->dir[ISER_DIR_OUT]) {
+ data = &iser_ctask->data[ISER_DIR_OUT];
+ dma_unmap_sg(dma_device, data->buf, data->size, DMA_TO_DEVICE);
+ }
+}
+
/**
* iser_reg_rdma_mem - Registers memory intended for RDMA,
* obtaining rkey and va
@@ -394,6 +432,10 @@ int iser_reg_rdma_mem(struct iscsi_iser_cmd_task *iser_ctask,
iser_err("rdma alignment violation %d/%d aligned\n",
aligned_len, mem->size);
iser_data_buf_dump(mem);
+
+ /* unmap the command data before accessing it */
+ iser_dma_unmap_task_data(iser_ctask);
+
/* allocate copy buf, if we are writing, copy the */
/* unaligned scatterlist, dma map the copy */
if (iser_start_rdma_unaligned_sg(iser_ctask, cmd_dir) != 0)
diff --git a/drivers/infiniband/ulp/iser/iser_verbs.c b/drivers/infiniband/ulp/iser/iser_verbs.c
index ecdca7fc1e4c..18a000034996 100644
--- a/drivers/infiniband/ulp/iser/iser_verbs.c
+++ b/drivers/infiniband/ulp/iser/iser_verbs.c
@@ -571,6 +571,8 @@ void iser_conn_release(struct iser_conn *ib_conn)
/* on EVENT_ADDR_ERROR there's no device yet for this conn */
if (device != NULL)
iser_device_try_release(device);
+ if (ib_conn->iser_conn)
+ ib_conn->iser_conn->ib_conn = NULL;
kfree(ib_conn);
}
@@ -694,7 +696,7 @@ int iser_post_recv(struct iser_desc *rx_desc)
struct iser_dto *recv_dto = &rx_desc->dto;
/* Retrieve conn */
- ib_conn = recv_dto->conn->ib_conn;
+ ib_conn = recv_dto->ib_conn;
iser_dto_to_iov(recv_dto, iov, 2);
@@ -727,7 +729,7 @@ int iser_post_send(struct iser_desc *tx_desc)
struct iser_conn *ib_conn;
struct iser_dto *dto = &tx_desc->dto;
- ib_conn = dto->conn->ib_conn;
+ ib_conn = dto->ib_conn;
iser_dto_to_iov(dto, iov, MAX_REGD_BUF_VECTOR_LEN);
@@ -774,7 +776,7 @@ static void iser_comp_error_worker(void *data)
static void iser_handle_comp_error(struct iser_desc *desc)
{
struct iser_dto *dto = &desc->dto;
- struct iser_conn *ib_conn = dto->conn->ib_conn;
+ struct iser_conn *ib_conn = dto->ib_conn;
iser_dto_buffs_release(dto);
diff --git a/drivers/input/Kconfig b/drivers/input/Kconfig
index 58223b5d842a..96232313b1b9 100644
--- a/drivers/input/Kconfig
+++ b/drivers/input/Kconfig
@@ -24,6 +24,20 @@ config INPUT
if INPUT
+config INPUT_FF_MEMLESS
+ tristate "Support for memoryless force-feedback devices"
+ default n
+ ---help---
+ Say Y here if you have memoryless force-feedback input device
+ such as Logitech WingMan Force 3D, ThrustMaster FireStorm Dual
+ Power 2, or similar. You will also need to enable hardware-specific
+ driver.
+
+ If unsure, say N.
+
+ To compile this driver as a module, choose M here: the
+ module will be called ff-memless.
+
comment "Userland interfaces"
config INPUT_MOUSEDEV
diff --git a/drivers/input/Makefile b/drivers/input/Makefile
index 1a6ff4982f30..a005b1df5f1a 100644
--- a/drivers/input/Makefile
+++ b/drivers/input/Makefile
@@ -4,7 +4,11 @@
# Each configuration option enables a list of files.
-obj-$(CONFIG_INPUT) += input.o
+obj-$(CONFIG_INPUT) += input-core.o
+input-core-objs := input.o ff-core.o
+
+obj-$(CONFIG_INPUT_FF_MEMLESS) += ff-memless.o
+
obj-$(CONFIG_INPUT_MOUSEDEV) += mousedev.o
obj-$(CONFIG_INPUT_JOYDEV) += joydev.o
obj-$(CONFIG_INPUT_EVDEV) += evdev.o
diff --git a/drivers/input/evbug.c b/drivers/input/evbug.c
index 07358fb51b82..5a9653c3128a 100644
--- a/drivers/input/evbug.c
+++ b/drivers/input/evbug.c
@@ -42,10 +42,12 @@ static char evbug_name[] = "evbug";
static void evbug_event(struct input_handle *handle, unsigned int type, unsigned int code, int value)
{
- printk(KERN_DEBUG "evbug.c: Event. Dev: %s, Type: %d, Code: %d, Value: %d\n", handle->dev->phys, type, code, value);
+ printk(KERN_DEBUG "evbug.c: Event. Dev: %s, Type: %d, Code: %d, Value: %d\n",
+ handle->dev->phys, type, code, value);
}
-static struct input_handle *evbug_connect(struct input_handler *handler, struct input_dev *dev, struct input_device_id *id)
+static struct input_handle *evbug_connect(struct input_handler *handler, struct input_dev *dev,
+ const struct input_device_id *id)
{
struct input_handle *handle;
@@ -72,7 +74,7 @@ static void evbug_disconnect(struct input_handle *handle)
kfree(handle);
}
-static struct input_device_id evbug_ids[] = {
+static const struct input_device_id evbug_ids[] = {
{ .driver_info = 1 }, /* Matches all devices */
{ }, /* Terminating zero entry */
};
@@ -89,8 +91,7 @@ static struct input_handler evbug_handler = {
static int __init evbug_init(void)
{
- input_register_handler(&evbug_handler);
- return 0;
+ return input_register_handler(&evbug_handler);
}
static void __exit evbug_exit(void)
diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c
index 4bf48188cc91..6439f378f6cc 100644
--- a/drivers/input/evdev.c
+++ b/drivers/input/evdev.c
@@ -391,8 +391,10 @@ static long evdev_ioctl_handler(struct file *file, unsigned int cmd,
struct evdev *evdev = list->evdev;
struct input_dev *dev = evdev->handle.dev;
struct input_absinfo abs;
+ struct ff_effect effect;
int __user *ip = (int __user *)p;
int i, t, u, v;
+ int error;
if (!evdev->exist)
return -ENODEV;
@@ -460,27 +462,22 @@ static long evdev_ioctl_handler(struct file *file, unsigned int cmd,
return 0;
case EVIOCSFF:
- if (dev->upload_effect) {
- struct ff_effect effect;
- int err;
-
- if (copy_from_user(&effect, p, sizeof(effect)))
- return -EFAULT;
- err = dev->upload_effect(dev, &effect);
- if (put_user(effect.id, &(((struct ff_effect __user *)p)->id)))
- return -EFAULT;
- return err;
- } else
- return -ENOSYS;
+ if (copy_from_user(&effect, p, sizeof(effect)))
+ return -EFAULT;
- case EVIOCRMFF:
- if (!dev->erase_effect)
- return -ENOSYS;
+ error = input_ff_upload(dev, &effect, file);
- return dev->erase_effect(dev, (int)(unsigned long) p);
+ if (put_user(effect.id, &(((struct ff_effect __user *)p)->id)))
+ return -EFAULT;
+
+ return error;
+
+ case EVIOCRMFF:
+ return input_ff_erase(dev, (int)(unsigned long) p, file);
case EVIOCGEFFECTS:
- if (put_user(dev->ff_effects_max, ip))
+ i = test_bit(EV_FF, dev->evbit) ? dev->ff->max_effects : 0;
+ if (put_user(i, ip))
return -EFAULT;
return 0;
@@ -604,7 +601,7 @@ static long evdev_ioctl_compat(struct file *file, unsigned int cmd, unsigned lon
}
#endif
-static struct file_operations evdev_fops = {
+static const struct file_operations evdev_fops = {
.owner = THIS_MODULE,
.read = evdev_read,
.write = evdev_write,
@@ -619,7 +616,8 @@ static struct file_operations evdev_fops = {
.flush = evdev_flush
};
-static struct input_handle *evdev_connect(struct input_handler *handler, struct input_dev *dev, struct input_device_id *id)
+static struct input_handle *evdev_connect(struct input_handler *handler, struct input_dev *dev,
+ const struct input_device_id *id)
{
struct evdev *evdev;
struct class_device *cdev;
@@ -669,6 +667,7 @@ static void evdev_disconnect(struct input_handle *handle)
evdev->exist = 0;
if (evdev->open) {
+ input_flush_device(handle, NULL);
input_close_device(handle);
wake_up_interruptible(&evdev->wait);
list_for_each_entry(list, &evdev->list, node)
@@ -677,7 +676,7 @@ static void evdev_disconnect(struct input_handle *handle)
evdev_free(evdev);
}
-static struct input_device_id evdev_ids[] = {
+static const struct input_device_id evdev_ids[] = {
{ .driver_info = 1 }, /* Matches all devices */
{ }, /* Terminating zero entry */
};
@@ -696,8 +695,7 @@ static struct input_handler evdev_handler = {
static int __init evdev_init(void)
{
- input_register_handler(&evdev_handler);
- return 0;
+ return input_register_handler(&evdev_handler);
}
static void __exit evdev_exit(void)
diff --git a/drivers/input/ff-core.c b/drivers/input/ff-core.c
new file mode 100644
index 000000000000..35656cadc914
--- /dev/null
+++ b/drivers/input/ff-core.c
@@ -0,0 +1,367 @@
+/*
+ * Force feedback support for Linux input subsystem
+ *
+ * Copyright (c) 2006 Anssi Hannula <anssi.hannula@gmail.com>
+ * Copyright (c) 2006 Dmitry Torokhov <dtor@mail.ru>
+ */
+
+/*
+ * 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 DEBUG */
+
+#define debug(format, arg...) pr_debug("ff-core: " format "\n", ## arg)
+
+#include <linux/input.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+
+/*
+ * Check that the effect_id is a valid effect and whether the user
+ * is the owner
+ */
+static int check_effect_access(struct ff_device *ff, int effect_id,
+ struct file *file)
+{
+ if (effect_id < 0 || effect_id >= ff->max_effects ||
+ !ff->effect_owners[effect_id])
+ return -EINVAL;
+
+ if (file && ff->effect_owners[effect_id] != file)
+ return -EACCES;
+
+ return 0;
+}
+
+/*
+ * Checks whether 2 effects can be combined together
+ */
+static inline int check_effects_compatible(struct ff_effect *e1,
+ struct ff_effect *e2)
+{
+ return e1->type == e2->type &&
+ (e1->type != FF_PERIODIC ||
+ e1->u.periodic.waveform == e2->u.periodic.waveform);
+}
+
+/*
+ * Convert an effect into compatible one
+ */
+static int compat_effect(struct ff_device *ff, struct ff_effect *effect)
+{
+ int magnitude;
+
+ switch (effect->type) {
+ case FF_RUMBLE:
+ if (!test_bit(FF_PERIODIC, ff->ffbit))
+ return -EINVAL;
+
+ /*
+ * calculate manginude of sine wave as average of rumble's
+ * 2/3 of strong magnitude and 1/3 of weak magnitude
+ */
+ magnitude = effect->u.rumble.strong_magnitude / 3 +
+ effect->u.rumble.weak_magnitude / 6;
+
+ effect->type = FF_PERIODIC;
+ effect->u.periodic.waveform = FF_SINE;
+ effect->u.periodic.period = 50;
+ effect->u.periodic.magnitude = max(magnitude, 0x7fff);
+ effect->u.periodic.offset = 0;
+ effect->u.periodic.phase = 0;
+ effect->u.periodic.envelope.attack_length = 0;
+ effect->u.periodic.envelope.attack_level = 0;
+ effect->u.periodic.envelope.fade_length = 0;
+ effect->u.periodic.envelope.fade_level = 0;
+
+ return 0;
+
+ default:
+ /* Let driver handle conversion */
+ return 0;
+ }
+}
+
+/**
+ * input_ff_upload() - upload effect into force-feedback device
+ * @dev: input device
+ * @effect: effect to be uploaded
+ * @file: owner of the effect
+ */
+int input_ff_upload(struct input_dev *dev, struct ff_effect *effect,
+ struct file *file)
+{
+ struct ff_device *ff = dev->ff;
+ struct ff_effect *old;
+ int ret = 0;
+ int id;
+
+ if (!test_bit(EV_FF, dev->evbit))
+ return -ENOSYS;
+
+ if (effect->type < FF_EFFECT_MIN || effect->type > FF_EFFECT_MAX ||
+ !test_bit(effect->type, dev->ffbit)) {
+ debug("invalid or not supported effect type in upload");
+ return -EINVAL;
+ }
+
+ if (effect->type == FF_PERIODIC &&
+ (effect->u.periodic.waveform < FF_WAVEFORM_MIN ||
+ effect->u.periodic.waveform > FF_WAVEFORM_MAX ||
+ !test_bit(effect->u.periodic.waveform, dev->ffbit))) {
+ debug("invalid or not supported wave form in upload");
+ return -EINVAL;
+ }
+
+ if (!test_bit(effect->type, ff->ffbit)) {
+ ret = compat_effect(ff, effect);
+ if (ret)
+ return ret;
+ }
+
+ mutex_lock(&ff->mutex);
+
+ if (effect->id == -1) {
+ for (id = 0; id < ff->max_effects; id++)
+ if (!ff->effect_owners[id])
+ break;
+
+ if (id >= ff->max_effects) {
+ ret = -ENOSPC;
+ goto out;
+ }
+
+ effect->id = id;
+ old = NULL;
+
+ } else {
+ id = effect->id;
+
+ ret = check_effect_access(ff, id, file);
+ if (ret)
+ goto out;
+
+ old = &ff->effects[id];
+
+ if (!check_effects_compatible(effect, old)) {
+ ret = -EINVAL;
+ goto out;
+ }
+ }
+
+ ret = ff->upload(dev, effect, old);
+ if (ret)
+ goto out;
+
+ ff->effects[id] = *effect;
+ ff->effect_owners[id] = file;
+
+ out:
+ mutex_unlock(&ff->mutex);
+ return ret;
+}
+EXPORT_SYMBOL_GPL(input_ff_upload);
+
+/*
+ * Erases the effect if the requester is also the effect owner. The mutex
+ * should already be locked before calling this function.
+ */
+static int erase_effect(struct input_dev *dev, int effect_id,
+ struct file *file)
+{
+ struct ff_device *ff = dev->ff;
+ int error;
+
+ error = check_effect_access(ff, effect_id, file);
+ if (error)
+ return error;
+
+ ff->playback(dev, effect_id, 0);
+
+ if (ff->erase) {
+ error = ff->erase(dev, effect_id);
+ if (error)
+ return error;
+ }
+
+ ff->effect_owners[effect_id] = NULL;
+
+ return 0;
+}
+
+/**
+ * input_ff_erase - erase an effect from device
+ * @dev: input device to erase effect from
+ * @effect_id: id of the ffect to be erased
+ * @file: purported owner of the request
+ *
+ * This function erases a force-feedback effect from specified device.
+ * The effect will only be erased if it was uploaded through the same
+ * file handle that is requesting erase.
+ */
+int input_ff_erase(struct input_dev *dev, int effect_id, struct file *file)
+{
+ struct ff_device *ff = dev->ff;
+ int ret;
+
+ if (!test_bit(EV_FF, dev->evbit))
+ return -ENOSYS;
+
+ mutex_lock(&ff->mutex);
+ ret = erase_effect(dev, effect_id, file);
+ mutex_unlock(&ff->mutex);
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(input_ff_erase);
+
+/*
+ * flush_effects - erase all effects owned by a file handle
+ */
+static int flush_effects(struct input_dev *dev, struct file *file)
+{
+ struct ff_device *ff = dev->ff;
+ int i;
+
+ debug("flushing now");
+
+ mutex_lock(&ff->mutex);
+
+ for (i = 0; i < ff->max_effects; i++)
+ erase_effect(dev, i, file);
+
+ mutex_unlock(&ff->mutex);
+
+ return 0;
+}
+
+/**
+ * input_ff_event() - generic handler for force-feedback events
+ * @dev: input device to send the effect to
+ * @type: event type (anything but EV_FF is ignored)
+ * @code: event code
+ * @value: event value
+ */
+int input_ff_event(struct input_dev *dev, unsigned int type,
+ unsigned int code, int value)
+{
+ struct ff_device *ff = dev->ff;
+
+ if (type != EV_FF)
+ return 0;
+
+ mutex_lock(&ff->mutex);
+
+ switch (code) {
+ case FF_GAIN:
+ if (!test_bit(FF_GAIN, dev->ffbit) || value > 0xffff)
+ break;
+
+ ff->set_gain(dev, value);
+ break;
+
+ case FF_AUTOCENTER:
+ if (!test_bit(FF_AUTOCENTER, dev->ffbit) || value > 0xffff)
+ break;
+
+ ff->set_autocenter(dev, value);
+ break;
+
+ default:
+ ff->playback(dev, code, value);
+ break;
+ }
+
+ mutex_unlock(&ff->mutex);
+ return 0;
+}
+EXPORT_SYMBOL_GPL(input_ff_event);
+
+/**
+ * input_ff_create() - create force-feedback device
+ * @dev: input device supporting force-feedback
+ * @max_effects: maximum number of effects supported by the device
+ *
+ * This function allocates all necessary memory for a force feedback
+ * portion of an input device and installs all default handlers.
+ * @dev->ffbit should be already set up before calling this function.
+ * Once ff device is created you need to setup its upload, erase,
+ * playback and other handlers before registering input device
+ */
+int input_ff_create(struct input_dev *dev, int max_effects)
+{
+ struct ff_device *ff;
+ int i;
+
+ if (!max_effects) {
+ printk(KERN_ERR
+ "ff-core: cannot allocate device without any effects\n");
+ return -EINVAL;
+ }
+
+ ff = kzalloc(sizeof(struct ff_device) +
+ max_effects * sizeof(struct file *), GFP_KERNEL);
+ if (!ff)
+ return -ENOMEM;
+
+ ff->effects = kcalloc(max_effects, sizeof(struct ff_effect),
+ GFP_KERNEL);
+ if (!ff->effects) {
+ kfree(ff);
+ return -ENOMEM;
+ }
+
+ ff->max_effects = max_effects;
+ mutex_init(&ff->mutex);
+
+ dev->ff = ff;
+ dev->flush = flush_effects;
+ dev->event = input_ff_event;
+ set_bit(EV_FF, dev->evbit);
+
+ /* Copy "true" bits into ff device bitmap */
+ for (i = 0; i <= FF_MAX; i++)
+ if (test_bit(i, dev->ffbit))
+ set_bit(i, ff->ffbit);
+
+ /* we can emulate RUMBLE with periodic effects */
+ if (test_bit(FF_PERIODIC, ff->ffbit))
+ set_bit(FF_RUMBLE, dev->ffbit);
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(input_ff_create);
+
+/**
+ * input_ff_free() - frees force feedback portion of input device
+ * @dev: input device supporintg force feedback
+ *
+ * This function is only needed in error path as input core will
+ * automatically free force feedback structures when device is
+ * destroyed.
+ */
+void input_ff_destroy(struct input_dev *dev)
+{
+ clear_bit(EV_FF, dev->evbit);
+ if (dev->ff) {
+ if (dev->ff->destroy)
+ dev->ff->destroy(dev->ff);
+ kfree(dev->ff->private);
+ kfree(dev->ff);
+ dev->ff = NULL;
+ }
+}
+EXPORT_SYMBOL_GPL(input_ff_destroy);
diff --git a/drivers/input/ff-memless.c b/drivers/input/ff-memless.c
new file mode 100644
index 000000000000..cd8b7297e6df
--- /dev/null
+++ b/drivers/input/ff-memless.c
@@ -0,0 +1,515 @@
+/*
+ * Force feedback support for memoryless devices
+ *
+ * Copyright (c) 2006 Anssi Hannula <anssi.hannula@gmail.com>
+ * Copyright (c) 2006 Dmitry Torokhov <dtor@mail.ru>
+ */
+
+/*
+ * 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 DEBUG */
+
+#define debug(format, arg...) pr_debug("ff-memless: " format "\n", ## arg)
+
+#include <linux/input.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/spinlock.h>
+#include <linux/sched.h>
+
+#include "fixp-arith.h"
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Anssi Hannula <anssi.hannula@gmail.com>");
+MODULE_DESCRIPTION("Force feedback support for memoryless devices");
+
+/* Number of effects handled with memoryless devices */
+#define FF_MEMLESS_EFFECTS 16
+
+/* Envelope update interval in ms */
+#define FF_ENVELOPE_INTERVAL 50
+
+#define FF_EFFECT_STARTED 0
+#define FF_EFFECT_PLAYING 1
+#define FF_EFFECT_ABORTING 2
+
+struct ml_effect_state {
+ struct ff_effect *effect;
+ unsigned long flags; /* effect state (STARTED, PLAYING, etc) */
+ int count; /* loop count of the effect */
+ unsigned long play_at; /* start time */
+ unsigned long stop_at; /* stop time */
+ unsigned long adj_at; /* last time the effect was sent */
+};
+
+struct ml_device {
+ void *private;
+ struct ml_effect_state states[FF_MEMLESS_EFFECTS];
+ int gain;
+ struct timer_list timer;
+ spinlock_t timer_lock;
+ struct input_dev *dev;
+
+ int (*play_effect)(struct input_dev *dev, void *data,
+ struct ff_effect *effect);
+};
+
+static const struct ff_envelope *get_envelope(const struct ff_effect *effect)
+{
+ static const struct ff_envelope empty_envelope;
+
+ switch (effect->type) {
+ case FF_PERIODIC:
+ return &effect->u.periodic.envelope;
+ case FF_CONSTANT:
+ return &effect->u.constant.envelope;
+ default:
+ return &empty_envelope;
+ }
+}
+
+/*
+ * Check for the next time envelope requires an update on memoryless devices
+ */
+static unsigned long calculate_next_time(struct ml_effect_state *state)
+{
+ const struct ff_envelope *envelope = get_envelope(state->effect);
+ unsigned long attack_stop, fade_start, next_fade;
+
+ if (envelope->attack_length) {
+ attack_stop = state->play_at +
+ msecs_to_jiffies(envelope->attack_length);
+ if (time_before(state->adj_at, attack_stop))
+ return state->adj_at +
+ msecs_to_jiffies(FF_ENVELOPE_INTERVAL);
+ }
+
+ if (state->effect->replay.length) {
+ if (envelope->fade_length) {
+ /* check when fading should start */
+ fade_start = state->stop_at -
+ msecs_to_jiffies(envelope->fade_length);
+
+ if (time_before(state->adj_at, fade_start))
+ return fade_start;
+
+ /* already fading, advance to next checkpoint */
+ next_fade = state->adj_at +
+ msecs_to_jiffies(FF_ENVELOPE_INTERVAL);
+ if (time_before(next_fade, state->stop_at))
+ return next_fade;
+ }
+
+ return state->stop_at;
+ }
+
+ return state->play_at;
+}
+
+static void ml_schedule_timer(struct ml_device *ml)
+{
+ struct ml_effect_state *state;
+ unsigned long now = jiffies;
+ unsigned long earliest = 0;
+ unsigned long next_at;
+ int events = 0;
+ int i;
+
+ debug("calculating next timer");
+
+ for (i = 0; i < FF_MEMLESS_EFFECTS; i++) {
+
+ state = &ml->states[i];
+
+ if (!test_bit(FF_EFFECT_STARTED, &state->flags))
+ continue;
+
+ if (test_bit(FF_EFFECT_PLAYING, &state->flags))
+ next_at = calculate_next_time(state);
+ else
+ next_at = state->play_at;
+
+ if (time_before_eq(now, next_at) &&
+ (++events == 1 || time_before(next_at, earliest)))
+ earliest = next_at;
+ }
+
+ if (!events) {
+ debug("no actions");
+ del_timer(&ml->timer);
+ } else {
+ debug("timer set");
+ mod_timer(&ml->timer, earliest);
+ }
+}
+
+/*
+ * Apply an envelope to a value
+ */
+static int apply_envelope(struct ml_effect_state *state, int value,
+ struct ff_envelope *envelope)
+{
+ struct ff_effect *effect = state->effect;
+ unsigned long now = jiffies;
+ int time_from_level;
+ int time_of_envelope;
+ int envelope_level;
+ int difference;
+
+ if (envelope->attack_length &&
+ time_before(now,
+ state->play_at + msecs_to_jiffies(envelope->attack_length))) {
+ debug("value = 0x%x, attack_level = 0x%x", value,
+ envelope->attack_level);
+ time_from_level = jiffies_to_msecs(now - state->play_at);
+ time_of_envelope = envelope->attack_length;
+ envelope_level = min_t(__s16, envelope->attack_level, 0x7fff);
+
+ } else if (envelope->fade_length && effect->replay.length &&
+ time_after(now,
+ state->stop_at - msecs_to_jiffies(envelope->fade_length)) &&
+ time_before(now, state->stop_at)) {
+ time_from_level = jiffies_to_msecs(state->stop_at - now);
+ time_of_envelope = envelope->fade_length;
+ envelope_level = min_t(__s16, envelope->fade_level, 0x7fff);
+ } else
+ return value;
+
+ difference = abs(value) - envelope_level;
+
+ debug("difference = %d", difference);
+ debug("time_from_level = 0x%x", time_from_level);
+ debug("time_of_envelope = 0x%x", time_of_envelope);
+
+ difference = difference * time_from_level / time_of_envelope;
+
+ debug("difference = %d", difference);
+
+ return value < 0 ?
+ -(difference + envelope_level) : (difference + envelope_level);
+}
+
+/*
+ * Return the type the effect has to be converted into (memless devices)
+ */
+static int get_compatible_type(struct ff_device *ff, int effect_type)
+{
+
+ if (test_bit(effect_type, ff->ffbit))
+ return effect_type;
+
+ if (effect_type == FF_PERIODIC && test_bit(FF_RUMBLE, ff->ffbit))
+ return FF_RUMBLE;
+
+ printk(KERN_ERR
+ "ff-memless: invalid type in get_compatible_type()\n");
+
+ return 0;
+}
+
+/*
+ * Combine two effects and apply gain.
+ */
+static void ml_combine_effects(struct ff_effect *effect,
+ struct ml_effect_state *state,
+ int gain)
+{
+ struct ff_effect *new = state->effect;
+ unsigned int strong, weak, i;
+ int x, y;
+ fixp_t level;
+
+ switch (new->type) {
+ case FF_CONSTANT:
+ i = new->direction * 360 / 0xffff;
+ level = fixp_new16(apply_envelope(state,
+ new->u.constant.level,
+ &new->u.constant.envelope));
+ x = fixp_mult(fixp_sin(i), level) * gain / 0xffff;
+ y = fixp_mult(-fixp_cos(i), level) * gain / 0xffff;
+ /*
+ * here we abuse ff_ramp to hold x and y of constant force
+ * If in future any driver wants something else than x and y
+ * in s8, this should be changed to something more generic
+ */
+ effect->u.ramp.start_level =
+ max(min(effect->u.ramp.start_level + x, 0x7f), -0x80);
+ effect->u.ramp.end_level =
+ max(min(effect->u.ramp.end_level + y, 0x7f), -0x80);
+ break;
+
+ case FF_RUMBLE:
+ strong = new->u.rumble.strong_magnitude * gain / 0xffff;
+ weak = new->u.rumble.weak_magnitude * gain / 0xffff;
+ effect->u.rumble.strong_magnitude =
+ min(strong + effect->u.rumble.strong_magnitude,
+ 0xffffU);
+ effect->u.rumble.weak_magnitude =
+ min(weak + effect->u.rumble.weak_magnitude, 0xffffU);
+ break;
+
+ case FF_PERIODIC:
+ i = apply_envelope(state, abs(new->u.periodic.magnitude),
+ &new->u.periodic.envelope);
+
+ /* here we also scale it 0x7fff => 0xffff */
+ i = i * gain / 0x7fff;
+
+ effect->u.rumble.strong_magnitude =
+ min(i + effect->u.rumble.strong_magnitude, 0xffffU);
+ effect->u.rumble.weak_magnitude =
+ min(i + effect->u.rumble.weak_magnitude, 0xffffU);
+ break;
+
+ default:
+ printk(KERN_ERR "ff-memless: invalid type in ml_combine_effects()\n");
+ break;
+ }
+
+}
+
+
+/*
+ * Because memoryless devices have only one effect per effect type active
+ * at one time we have to combine multiple effects into one
+ */
+static int ml_get_combo_effect(struct ml_device *ml,
+ unsigned long *effect_handled,
+ struct ff_effect *combo_effect)
+{
+ struct ff_effect *effect;
+ struct ml_effect_state *state;
+ int effect_type;
+ int i;
+
+ memset(combo_effect, 0, sizeof(struct ff_effect));
+
+ for (i = 0; i < FF_MEMLESS_EFFECTS; i++) {
+ if (__test_and_set_bit(i, effect_handled))
+ continue;
+
+ state = &ml->states[i];
+ effect = state->effect;
+
+ if (!test_bit(FF_EFFECT_STARTED, &state->flags))
+ continue;
+
+ if (time_before(jiffies, state->play_at))
+ continue;
+
+ /*
+ * here we have started effects that are either
+ * currently playing (and may need be aborted)
+ * or need to start playing.
+ */
+ effect_type = get_compatible_type(ml->dev->ff, effect->type);
+ if (combo_effect->type != effect_type) {
+ if (combo_effect->type != 0) {
+ __clear_bit(i, effect_handled);
+ continue;
+ }
+ combo_effect->type = effect_type;
+ }
+
+ if (__test_and_clear_bit(FF_EFFECT_ABORTING, &state->flags)) {
+ __clear_bit(FF_EFFECT_PLAYING, &state->flags);
+ __clear_bit(FF_EFFECT_STARTED, &state->flags);
+ } else if (effect->replay.length &&
+ time_after_eq(jiffies, state->stop_at)) {
+
+ __clear_bit(FF_EFFECT_PLAYING, &state->flags);
+
+ if (--state->count <= 0) {
+ __clear_bit(FF_EFFECT_STARTED, &state->flags);
+ } else {
+ state->play_at = jiffies +
+ msecs_to_jiffies(effect->replay.delay);
+ state->stop_at = state->play_at +
+ msecs_to_jiffies(effect->replay.length);
+ }
+ } else {
+ __set_bit(FF_EFFECT_PLAYING, &state->flags);
+ state->adj_at = jiffies;
+ ml_combine_effects(combo_effect, state, ml->gain);
+ }
+ }
+
+ return combo_effect->type != 0;
+}
+
+static void ml_play_effects(struct ml_device *ml)
+{
+ struct ff_effect effect;
+ DECLARE_BITMAP(handled_bm, FF_MEMLESS_EFFECTS);
+
+ memset(handled_bm, 0, sizeof(handled_bm));
+
+ while (ml_get_combo_effect(ml, handled_bm, &effect))
+ ml->play_effect(ml->dev, ml->private, &effect);
+
+ ml_schedule_timer(ml);
+}
+
+static void ml_effect_timer(unsigned long timer_data)
+{
+ struct input_dev *dev = (struct input_dev *)timer_data;
+ struct ml_device *ml = dev->ff->private;
+
+ debug("timer: updating effects");
+
+ spin_lock(&ml->timer_lock);
+ ml_play_effects(ml);
+ spin_unlock(&ml->timer_lock);
+}
+
+static void ml_ff_set_gain(struct input_dev *dev, u16 gain)
+{
+ struct ml_device *ml = dev->ff->private;
+ int i;
+
+ spin_lock_bh(&ml->timer_lock);
+
+ ml->gain = gain;
+
+ for (i = 0; i < FF_MEMLESS_EFFECTS; i++)
+ __clear_bit(FF_EFFECT_PLAYING, &ml->states[i].flags);
+
+ ml_play_effects(ml);
+
+ spin_unlock_bh(&ml->timer_lock);
+}
+
+static int ml_ff_playback(struct input_dev *dev, int effect_id, int value)
+{
+ struct ml_device *ml = dev->ff->private;
+ struct ml_effect_state *state = &ml->states[effect_id];
+
+ spin_lock_bh(&ml->timer_lock);
+
+ if (value > 0) {
+ debug("initiated play");
+
+ __set_bit(FF_EFFECT_STARTED, &state->flags);
+ state->count = value;
+ state->play_at = jiffies +
+ msecs_to_jiffies(state->effect->replay.delay);
+ state->stop_at = state->play_at +
+ msecs_to_jiffies(state->effect->replay.length);
+ state->adj_at = state->play_at;
+
+ ml_schedule_timer(ml);
+
+ } else {
+ debug("initiated stop");
+
+ if (test_bit(FF_EFFECT_PLAYING, &state->flags))
+ __set_bit(FF_EFFECT_ABORTING, &state->flags);
+ else
+ __clear_bit(FF_EFFECT_STARTED, &state->flags);
+
+ ml_play_effects(ml);
+ }
+
+ spin_unlock_bh(&ml->timer_lock);
+
+ return 0;
+}
+
+static int ml_ff_upload(struct input_dev *dev,
+ struct ff_effect *effect, struct ff_effect *old)
+{
+ struct ml_device *ml = dev->ff->private;
+ struct ml_effect_state *state = &ml->states[effect->id];
+
+ spin_lock_bh(&ml->timer_lock);
+
+ if (test_bit(FF_EFFECT_STARTED, &state->flags)) {
+ __clear_bit(FF_EFFECT_PLAYING, &state->flags);
+ state->play_at = jiffies +
+ msecs_to_jiffies(state->effect->replay.delay);
+ state->stop_at = state->play_at +
+ msecs_to_jiffies(state->effect->replay.length);
+ state->adj_at = state->play_at;
+ ml_schedule_timer(ml);
+ }
+
+ spin_unlock_bh(&ml->timer_lock);
+
+ return 0;
+}
+
+static void ml_ff_destroy(struct ff_device *ff)
+{
+ struct ml_device *ml = ff->private;
+
+ kfree(ml->private);
+}
+
+/**
+ * input_ff_create_memless() - create memoryless FF device
+ * @dev: input device supporting force-feedback
+ * @data: driver-specific data to be passed into @play_effect
+ * @play_effect: driver-specific method for playing FF effect
+ */
+int input_ff_create_memless(struct input_dev *dev, void *data,
+ int (*play_effect)(struct input_dev *, void *, struct ff_effect *))
+{
+ struct ml_device *ml;
+ struct ff_device *ff;
+ int error;
+ int i;
+
+ ml = kzalloc(sizeof(struct ml_device), GFP_KERNEL);
+ if (!ml)
+ return -ENOMEM;
+
+ ml->dev = dev;
+ ml->private = data;
+ ml->play_effect = play_effect;
+ ml->gain = 0xffff;
+ spin_lock_init(&ml->timer_lock);
+ setup_timer(&ml->timer, ml_effect_timer, (unsigned long)dev);
+
+ set_bit(FF_GAIN, dev->ffbit);
+
+ error = input_ff_create(dev, FF_MEMLESS_EFFECTS);
+ if (error) {
+ kfree(ml);
+ return error;
+ }
+
+ ff = dev->ff;
+ ff->private = ml;
+ ff->upload = ml_ff_upload;
+ ff->playback = ml_ff_playback;
+ ff->set_gain = ml_ff_set_gain;
+ ff->destroy = ml_ff_destroy;
+
+ /* we can emulate periodic effects with RUMBLE */
+ if (test_bit(FF_RUMBLE, ff->ffbit)) {
+ set_bit(FF_PERIODIC, dev->ffbit);
+ set_bit(FF_SINE, dev->ffbit);
+ set_bit(FF_TRIANGLE, dev->ffbit);
+ set_bit(FF_SQUARE, dev->ffbit);
+ }
+
+ for (i = 0; i < FF_MEMLESS_EFFECTS; i++)
+ ml->states[i].effect = &ff->effects[i];
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(input_ff_create_memless);
diff --git a/drivers/usb/input/fixp-arith.h b/drivers/input/fixp-arith.h
index ed3d2da0c485..ed3d2da0c485 100644
--- a/drivers/usb/input/fixp-arith.h
+++ b/drivers/input/fixp-arith.h
diff --git a/drivers/input/input.c b/drivers/input/input.c
index 9cb4b9a54f01..1c8c8a5bc4a9 100644
--- a/drivers/input/input.c
+++ b/drivers/input/input.c
@@ -176,6 +176,10 @@ void input_event(struct input_dev *dev, unsigned int type, unsigned int code, in
break;
case EV_FF:
+
+ if (value < 0)
+ return;
+
if (dev->event)
dev->event(dev, type, code, value);
break;
@@ -309,7 +313,8 @@ static void input_link_handle(struct input_handle *handle)
if (i != NBITS(max)) \
continue;
-static struct input_device_id *input_match_device(struct input_device_id *id, struct input_dev *dev)
+static const struct input_device_id *input_match_device(const struct input_device_id *id,
+ struct input_dev *dev)
{
int i;
@@ -762,7 +767,9 @@ static void input_dev_release(struct class_device *class_dev)
{
struct input_dev *dev = to_input_dev(class_dev);
+ input_ff_destroy(dev);
kfree(dev);
+
module_put(THIS_MODULE);
}
@@ -899,12 +906,13 @@ struct input_dev *input_allocate_device(void)
dev = kzalloc(sizeof(struct input_dev), GFP_KERNEL);
if (dev) {
- dev->dynalloc = 1;
dev->cdev.class = &input_class;
class_device_initialize(&dev->cdev);
mutex_init(&dev->mutex);
INIT_LIST_HEAD(&dev->h_list);
INIT_LIST_HEAD(&dev->node);
+
+ __module_get(THIS_MODULE);
}
return dev;
@@ -929,17 +937,10 @@ int input_register_device(struct input_dev *dev)
static atomic_t input_no = ATOMIC_INIT(0);
struct input_handle *handle;
struct input_handler *handler;
- struct input_device_id *id;
+ const struct input_device_id *id;
const char *path;
int error;
- if (!dev->dynalloc) {
- printk(KERN_WARNING "input: device %s is statically allocated, will not register\n"
- "Please convert to input_allocate_device() or contact dtor_core@ameritech.net\n",
- dev->name ? dev->name : "<Unknown>");
- return -EINVAL;
- }
-
set_bit(EV_SYN, dev->evbit);
/*
@@ -955,10 +956,8 @@ int input_register_device(struct input_dev *dev)
dev->rep[REP_PERIOD] = 33;
}
- INIT_LIST_HEAD(&dev->h_list);
list_add_tail(&dev->node, &input_dev_list);
- dev->cdev.class = &input_class;
snprintf(dev->cdev.class_id, sizeof(dev->cdev.class_id),
"input%ld", (unsigned long) atomic_inc_return(&input_no) - 1);
@@ -978,8 +977,6 @@ int input_register_device(struct input_dev *dev)
if (error)
goto fail3;
- __module_get(THIS_MODULE);
-
path = kobject_get_path(&dev->cdev.kobj, GFP_KERNEL);
printk(KERN_INFO "input: %s as %s\n",
dev->name ? dev->name : "Unspecified device", path ? path : "N/A");
@@ -1008,9 +1005,12 @@ EXPORT_SYMBOL(input_register_device);
void input_unregister_device(struct input_dev *dev)
{
struct list_head *node, *next;
+ int code;
- if (!dev)
- return;
+ for (code = 0; code <= KEY_MAX; code++)
+ if (test_bit(code, dev->key))
+ input_report_key(dev, code, 0);
+ input_sync(dev);
del_timer_sync(&dev->timer);
@@ -1037,19 +1037,20 @@ void input_unregister_device(struct input_dev *dev)
}
EXPORT_SYMBOL(input_unregister_device);
-void input_register_handler(struct input_handler *handler)
+int input_register_handler(struct input_handler *handler)
{
struct input_dev *dev;
struct input_handle *handle;
- struct input_device_id *id;
-
- if (!handler)
- return;
+ const struct input_device_id *id;
INIT_LIST_HEAD(&handler->h_list);
- if (handler->fops != NULL)
+ if (handler->fops != NULL) {
+ if (input_table[handler->minor >> 5])
+ return -EBUSY;
+
input_table[handler->minor >> 5] = handler;
+ }
list_add_tail(&handler->node, &input_handler_list);
@@ -1063,6 +1064,7 @@ void input_register_handler(struct input_handler *handler)
}
input_wakeup_procfs_readers();
+ return 0;
}
EXPORT_SYMBOL(input_register_handler);
diff --git a/drivers/input/joydev.c b/drivers/input/joydev.c
index d67157513bf7..9f3529ad3fda 100644
--- a/drivers/input/joydev.c
+++ b/drivers/input/joydev.c
@@ -451,7 +451,7 @@ static int joydev_ioctl(struct inode *inode, struct file *file, unsigned int cmd
}
}
-static struct file_operations joydev_fops = {
+static const struct file_operations joydev_fops = {
.owner = THIS_MODULE,
.read = joydev_read,
.write = joydev_write,
@@ -465,7 +465,8 @@ static struct file_operations joydev_fops = {
.fasync = joydev_fasync,
};
-static struct input_handle *joydev_connect(struct input_handler *handler, struct input_dev *dev, struct input_device_id *id)
+static struct input_handle *joydev_connect(struct input_handler *handler, struct input_dev *dev,
+ const struct input_device_id *id)
{
struct joydev *joydev;
struct class_device *cdev;
@@ -562,7 +563,7 @@ static void joydev_disconnect(struct input_handle *handle)
joydev_free(joydev);
}
-static struct input_device_id joydev_blacklist[] = {
+static const struct input_device_id joydev_blacklist[] = {
{
.flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_KEYBIT,
.evbit = { BIT(EV_KEY) },
@@ -571,7 +572,7 @@ static struct input_device_id joydev_blacklist[] = {
{ } /* Terminating entry */
};
-static struct input_device_id joydev_ids[] = {
+static const struct input_device_id joydev_ids[] = {
{
.flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_ABSBIT,
.evbit = { BIT(EV_ABS) },
@@ -605,8 +606,7 @@ static struct input_handler joydev_handler = {
static int __init joydev_init(void)
{
- input_register_handler(&joydev_handler);
- return 0;
+ return input_register_handler(&joydev_handler);
}
static void __exit joydev_exit(void)
diff --git a/drivers/input/joystick/iforce/iforce-ff.c b/drivers/input/joystick/iforce/iforce-ff.c
index 50c90765aee1..8fb0c19cc60e 100644
--- a/drivers/input/joystick/iforce/iforce-ff.c
+++ b/drivers/input/joystick/iforce/iforce-ff.c
@@ -165,19 +165,19 @@ static int make_condition_modifier(struct iforce* iforce,
data[0] = LO(mod_chunk->start);
data[1] = HI(mod_chunk->start);
- data[2] = (100*rk)>>15; /* Dangerous: the sign is extended by gcc on plateforms providing an arith shift */
- data[3] = (100*lk)>>15; /* This code is incorrect on cpus lacking arith shift */
+ data[2] = (100 * rk) >> 15; /* Dangerous: the sign is extended by gcc on plateforms providing an arith shift */
+ data[3] = (100 * lk) >> 15; /* This code is incorrect on cpus lacking arith shift */
- center = (500*center)>>15;
+ center = (500 * center) >> 15;
data[4] = LO(center);
data[5] = HI(center);
- db = (1000*db)>>16;
+ db = (1000 * db) >> 16;
data[6] = LO(db);
data[7] = HI(db);
- data[8] = (100*rsat)>>16;
- data[9] = (100*lsat)>>16;
+ data[8] = (100 * rsat) >> 16;
+ data[9] = (100 * lsat) >> 16;
iforce_send_packet(iforce, FF_CMD_CONDITION, data);
iforce_dump_packet("condition", FF_CMD_CONDITION, data);
@@ -188,6 +188,7 @@ static int make_condition_modifier(struct iforce* iforce,
static unsigned char find_button(struct iforce *iforce, signed short button)
{
int i;
+
for (i = 1; iforce->type->btn[i] >= 0; i++)
if (iforce->type->btn[i] == button)
return i + 1;
@@ -198,19 +199,17 @@ static unsigned char find_button(struct iforce *iforce, signed short button)
* Analyse the changes in an effect, and tell if we need to send an condition
* parameter packet
*/
-static int need_condition_modifier(struct iforce* iforce, struct ff_effect* new)
+static int need_condition_modifier(struct ff_effect *old, struct ff_effect *new)
{
- int id = new->id;
- struct ff_effect* old = &iforce->core_effects[id].effect;
- int ret=0;
+ int ret = 0;
int i;
if (new->type != FF_SPRING && new->type != FF_FRICTION) {
printk(KERN_WARNING "iforce.c: bad effect type in need_condition_modifier\n");
- return FALSE;
+ return 0;
}
- for(i=0; i<2; i++) {
+ for (i = 0; i < 2; i++) {
ret |= old->u.condition[i].right_saturation != new->u.condition[i].right_saturation
|| old->u.condition[i].left_saturation != new->u.condition[i].left_saturation
|| old->u.condition[i].right_coeff != new->u.condition[i].right_coeff
@@ -225,35 +224,29 @@ static int need_condition_modifier(struct iforce* iforce, struct ff_effect* new)
* Analyse the changes in an effect, and tell if we need to send a magnitude
* parameter packet
*/
-static int need_magnitude_modifier(struct iforce* iforce, struct ff_effect* effect)
+static int need_magnitude_modifier(struct ff_effect *old, struct ff_effect *effect)
{
- int id = effect->id;
- struct ff_effect* old = &iforce->core_effects[id].effect;
-
if (effect->type != FF_CONSTANT) {
printk(KERN_WARNING "iforce.c: bad effect type in need_envelope_modifier\n");
- return FALSE;
+ return 0;
}
- return (old->u.constant.level != effect->u.constant.level);
+ return old->u.constant.level != effect->u.constant.level;
}
/*
* Analyse the changes in an effect, and tell if we need to send an envelope
* parameter packet
*/
-static int need_envelope_modifier(struct iforce* iforce, struct ff_effect* effect)
+static int need_envelope_modifier(struct ff_effect *old, struct ff_effect *effect)
{
- int id = effect->id;
- struct ff_effect* old = &iforce->core_effects[id].effect;
-
switch (effect->type) {
case FF_CONSTANT:
if (old->u.constant.envelope.attack_length != effect->u.constant.envelope.attack_length
|| old->u.constant.envelope.attack_level != effect->u.constant.envelope.attack_level
|| old->u.constant.envelope.fade_length != effect->u.constant.envelope.fade_length
|| old->u.constant.envelope.fade_level != effect->u.constant.envelope.fade_level)
- return TRUE;
+ return 1;
break;
case FF_PERIODIC:
@@ -261,30 +254,26 @@ static int need_envelope_modifier(struct iforce* iforce, struct ff_effect* effec
|| old->u.periodic.envelope.attack_level != effect->u.periodic.envelope.attack_level
|| old->u.periodic.envelope.fade_length != effect->u.periodic.envelope.fade_length
|| old->u.periodic.envelope.fade_level != effect->u.periodic.envelope.fade_level)
- return TRUE;
+ return 1;
break;
default:
printk(KERN_WARNING "iforce.c: bad effect type in need_envelope_modifier\n");
}
- return FALSE;
+ return 0;
}
/*
* Analyse the changes in an effect, and tell if we need to send a periodic
* parameter effect
*/
-static int need_period_modifier(struct iforce* iforce, struct ff_effect* new)
+static int need_period_modifier(struct ff_effect *old, struct ff_effect *new)
{
- int id = new->id;
- struct ff_effect* old = &iforce->core_effects[id].effect;
-
if (new->type != FF_PERIODIC) {
- printk(KERN_WARNING "iforce.c: bad effect type in need_periodic_modifier\n");
- return FALSE;
+ printk(KERN_WARNING "iforce.c: bad effect type in need_period_modifier\n");
+ return 0;
}
-
return (old->u.periodic.period != new->u.periodic.period
|| old->u.periodic.magnitude != new->u.periodic.magnitude
|| old->u.periodic.offset != new->u.periodic.offset
@@ -295,19 +284,16 @@ static int need_period_modifier(struct iforce* iforce, struct ff_effect* new)
* Analyse the changes in an effect, and tell if we need to send an effect
* packet
*/
-static int need_core(struct iforce* iforce, struct ff_effect* new)
+static int need_core(struct ff_effect *old, struct ff_effect *new)
{
- int id = new->id;
- struct ff_effect* old = &iforce->core_effects[id].effect;
-
if (old->direction != new->direction
|| old->trigger.button != new->trigger.button
|| old->trigger.interval != new->trigger.interval
|| old->replay.length != new->replay.length
|| old->replay.delay != new->replay.delay)
- return TRUE;
+ return 1;
- return FALSE;
+ return 0;
}
/*
* Send the part common to all effects to the device
@@ -360,7 +346,7 @@ static int make_core(struct iforce* iforce, u16 id, u16 mod_id1, u16 mod_id2,
* Upload a periodic effect to the device
* See also iforce_upload_constant.
*/
-int iforce_upload_periodic(struct iforce* iforce, struct ff_effect* effect, int is_update)
+int iforce_upload_periodic(struct iforce *iforce, struct ff_effect *effect, struct ff_effect *old)
{
u8 wave_code;
int core_id = effect->id;
@@ -371,23 +357,25 @@ int iforce_upload_periodic(struct iforce* iforce, struct ff_effect* effect, int
int param2_err = 1;
int core_err = 0;
- if (!is_update || need_period_modifier(iforce, effect)) {
+ if (!old || need_period_modifier(old, effect)) {
param1_err = make_period_modifier(iforce, mod1_chunk,
- is_update,
+ old != NULL,
effect->u.periodic.magnitude, effect->u.periodic.offset,
effect->u.periodic.period, effect->u.periodic.phase);
- if (param1_err) return param1_err;
+ if (param1_err)
+ return param1_err;
set_bit(FF_MOD1_IS_USED, core_effect->flags);
}
- if (!is_update || need_envelope_modifier(iforce, effect)) {
+ if (!old || need_envelope_modifier(old, effect)) {
param2_err = make_envelope_modifier(iforce, mod2_chunk,
- is_update,
+ old !=NULL,
effect->u.periodic.envelope.attack_length,
effect->u.periodic.envelope.attack_level,
effect->u.periodic.envelope.fade_length,
effect->u.periodic.envelope.fade_level);
- if (param2_err) return param2_err;
+ if (param2_err)
+ return param2_err;
set_bit(FF_MOD2_IS_USED, core_effect->flags);
}
@@ -400,7 +388,7 @@ int iforce_upload_periodic(struct iforce* iforce, struct ff_effect* effect, int
default: wave_code = 0x20; break;
}
- if (!is_update || need_core(iforce, effect)) {
+ if (!old || need_core(old, effect)) {
core_err = make_core(iforce, effect->id,
mod1_chunk->start,
mod2_chunk->start,
@@ -429,7 +417,7 @@ int iforce_upload_periodic(struct iforce* iforce, struct ff_effect* effect, int
* 0 Ok, effect created or updated
* 1 effect did not change since last upload, and no packet was therefore sent
*/
-int iforce_upload_constant(struct iforce* iforce, struct ff_effect* effect, int is_update)
+int iforce_upload_constant(struct iforce *iforce, struct ff_effect *effect, struct ff_effect *old)
{
int core_id = effect->id;
struct iforce_core_effect* core_effect = iforce->core_effects + core_id;
@@ -439,26 +427,28 @@ int iforce_upload_constant(struct iforce* iforce, struct ff_effect* effect, int
int param2_err = 1;
int core_err = 0;
- if (!is_update || need_magnitude_modifier(iforce, effect)) {
+ if (!old || need_magnitude_modifier(old, effect)) {
param1_err = make_magnitude_modifier(iforce, mod1_chunk,
- is_update,
+ old != NULL,
effect->u.constant.level);
- if (param1_err) return param1_err;
+ if (param1_err)
+ return param1_err;
set_bit(FF_MOD1_IS_USED, core_effect->flags);
}
- if (!is_update || need_envelope_modifier(iforce, effect)) {
+ if (!old || need_envelope_modifier(old, effect)) {
param2_err = make_envelope_modifier(iforce, mod2_chunk,
- is_update,
+ old != NULL,
effect->u.constant.envelope.attack_length,
effect->u.constant.envelope.attack_level,
effect->u.constant.envelope.fade_length,
effect->u.constant.envelope.fade_level);
- if (param2_err) return param2_err;
+ if (param2_err)
+ return param2_err;
set_bit(FF_MOD2_IS_USED, core_effect->flags);
}
- if (!is_update || need_core(iforce, effect)) {
+ if (!old || need_core(old, effect)) {
core_err = make_core(iforce, effect->id,
mod1_chunk->start,
mod2_chunk->start,
@@ -483,7 +473,7 @@ int iforce_upload_constant(struct iforce* iforce, struct ff_effect* effect, int
/*
* Upload an condition effect. Those are for example friction, inertia, springs...
*/
-int iforce_upload_condition(struct iforce* iforce, struct ff_effect* effect, int is_update)
+int iforce_upload_condition(struct iforce *iforce, struct ff_effect *effect, struct ff_effect *old)
{
int core_id = effect->id;
struct iforce_core_effect* core_effect = iforce->core_effects + core_id;
@@ -494,37 +484,39 @@ int iforce_upload_condition(struct iforce* iforce, struct ff_effect* effect, int
int core_err = 0;
switch (effect->type) {
- case FF_SPRING: type = 0x40; break;
- case FF_DAMPER: type = 0x41; break;
+ case FF_SPRING: type = 0x40; break;
+ case FF_DAMPER: type = 0x41; break;
default: return -1;
}
- if (!is_update || need_condition_modifier(iforce, effect)) {
+ if (!old || need_condition_modifier(old, effect)) {
param_err = make_condition_modifier(iforce, mod1_chunk,
- is_update,
+ old != NULL,
effect->u.condition[0].right_saturation,
effect->u.condition[0].left_saturation,
effect->u.condition[0].right_coeff,
effect->u.condition[0].left_coeff,
effect->u.condition[0].deadband,
effect->u.condition[0].center);
- if (param_err) return param_err;
+ if (param_err)
+ return param_err;
set_bit(FF_MOD1_IS_USED, core_effect->flags);
param_err = make_condition_modifier(iforce, mod2_chunk,
- is_update,
+ old != NULL,
effect->u.condition[1].right_saturation,
effect->u.condition[1].left_saturation,
effect->u.condition[1].right_coeff,
effect->u.condition[1].left_coeff,
effect->u.condition[1].deadband,
effect->u.condition[1].center);
- if (param_err) return param_err;
+ if (param_err)
+ return param_err;
set_bit(FF_MOD2_IS_USED, core_effect->flags);
}
- if (!is_update || need_core(iforce, effect)) {
+ if (!old || need_core(old, effect)) {
core_err = make_core(iforce, effect->id,
mod1_chunk->start, mod2_chunk->start,
type, 0xc0,
diff --git a/drivers/input/joystick/iforce/iforce-main.c b/drivers/input/joystick/iforce/iforce-main.c
index b4914e7231f8..24c684bc6337 100644
--- a/drivers/input/joystick/iforce/iforce-main.c
+++ b/drivers/input/joystick/iforce/iforce-main.c
@@ -83,103 +83,57 @@ static struct iforce_device iforce_device[] = {
{ 0x0000, 0x0000, "Unknown I-Force Device [%04x:%04x]", btn_joystick, abs_joystick, ff_iforce }
};
-
-
-static int iforce_input_event(struct input_dev *dev, unsigned int type, unsigned int code, int value)
+static int iforce_playback(struct input_dev *dev, int effect_id, int value)
{
struct iforce* iforce = dev->private;
- unsigned char data[3];
-
- if (type != EV_FF)
- return -1;
-
- switch (code) {
-
- case FF_GAIN:
-
- data[0] = value >> 9;
- iforce_send_packet(iforce, FF_CMD_GAIN, data);
-
- return 0;
-
- case FF_AUTOCENTER:
+ struct iforce_core_effect *core_effect = &iforce->core_effects[effect_id];
- data[0] = 0x03;
- data[1] = value >> 9;
- iforce_send_packet(iforce, FF_CMD_AUTOCENTER, data);
+ if (value > 0)
+ set_bit(FF_CORE_SHOULD_PLAY, core_effect->flags);
+ else
+ clear_bit(FF_CORE_SHOULD_PLAY, core_effect->flags);
- data[0] = 0x04;
- data[1] = 0x01;
- iforce_send_packet(iforce, FF_CMD_AUTOCENTER, data);
+ iforce_control_playback(iforce, effect_id, value);
+ return 0;
+}
- return 0;
+static void iforce_set_gain(struct input_dev *dev, u16 gain)
+{
+ struct iforce* iforce = dev->private;
+ unsigned char data[3];
- default: /* Play or stop an effect */
+ data[0] = gain >> 9;
+ iforce_send_packet(iforce, FF_CMD_GAIN, data);
+}
- if (!CHECK_OWNERSHIP(code, iforce)) {
- return -1;
- }
- if (value > 0) {
- set_bit(FF_CORE_SHOULD_PLAY, iforce->core_effects[code].flags);
- }
- else {
- clear_bit(FF_CORE_SHOULD_PLAY, iforce->core_effects[code].flags);
- }
+static void iforce_set_autocenter(struct input_dev *dev, u16 magnitude)
+{
+ struct iforce* iforce = dev->private;
+ unsigned char data[3];
- iforce_control_playback(iforce, code, value);
- return 0;
- }
+ data[0] = 0x03;
+ data[1] = magnitude >> 9;
+ iforce_send_packet(iforce, FF_CMD_AUTOCENTER, data);
- return -1;
+ data[0] = 0x04;
+ data[1] = 0x01;
+ iforce_send_packet(iforce, FF_CMD_AUTOCENTER, data);
}
/*
* Function called when an ioctl is performed on the event dev entry.
* It uploads an effect to the device
*/
-static int iforce_upload_effect(struct input_dev *dev, struct ff_effect *effect)
+static int iforce_upload_effect(struct input_dev *dev, struct ff_effect *effect, struct ff_effect *old)
{
struct iforce* iforce = dev->private;
- int id;
+ struct iforce_core_effect *core_effect = &iforce->core_effects[effect->id];
int ret;
- int is_update;
-
-/* Check this effect type is supported by this device */
- if (!test_bit(effect->type, iforce->dev->ffbit))
- return -EINVAL;
-
-/*
- * If we want to create a new effect, get a free id
- */
- if (effect->id == -1) {
-
- for (id = 0; id < FF_EFFECTS_MAX; ++id)
- if (!test_and_set_bit(FF_CORE_IS_USED, iforce->core_effects[id].flags))
- break;
-
- if (id == FF_EFFECTS_MAX || id >= iforce->dev->ff_effects_max)
- return -ENOMEM;
-
- effect->id = id;
- iforce->core_effects[id].owner = current->pid;
- iforce->core_effects[id].flags[0] = (1 << FF_CORE_IS_USED); /* Only IS_USED bit must be set */
-
- is_update = FALSE;
- }
- else {
- /* We want to update an effect */
- if (!CHECK_OWNERSHIP(effect->id, iforce))
- return -EACCES;
-
- /* Parameter type cannot be updated */
- if (effect->type != iforce->core_effects[effect->id].effect.type)
- return -EINVAL;
+ if (__test_and_set_bit(FF_CORE_IS_USED, core_effect->flags)) {
/* Check the effect is not already being updated */
- if (test_bit(FF_CORE_UPDATE, iforce->core_effects[effect->id].flags))
+ if (test_bit(FF_CORE_UPDATE, core_effect->flags))
return -EAGAIN;
-
- is_update = TRUE;
}
/*
@@ -188,28 +142,28 @@ static int iforce_upload_effect(struct input_dev *dev, struct ff_effect *effect)
switch (effect->type) {
case FF_PERIODIC:
- ret = iforce_upload_periodic(iforce, effect, is_update);
+ ret = iforce_upload_periodic(iforce, effect, old);
break;
case FF_CONSTANT:
- ret = iforce_upload_constant(iforce, effect, is_update);
+ ret = iforce_upload_constant(iforce, effect, old);
break;
case FF_SPRING:
case FF_DAMPER:
- ret = iforce_upload_condition(iforce, effect, is_update);
+ ret = iforce_upload_condition(iforce, effect, old);
break;
default:
return -EINVAL;
}
+
if (ret == 0) {
/* A packet was sent, forbid new updates until we are notified
* that the packet was updated
*/
- set_bit(FF_CORE_UPDATE, iforce->core_effects[effect->id].flags);
+ set_bit(FF_CORE_UPDATE, core_effect->flags);
}
- iforce->core_effects[effect->id].effect = *effect;
return ret;
}
@@ -219,20 +173,9 @@ static int iforce_upload_effect(struct input_dev *dev, struct ff_effect *effect)
*/
static int iforce_erase_effect(struct input_dev *dev, int effect_id)
{
- struct iforce* iforce = dev->private;
+ struct iforce *iforce = dev->private;
+ struct iforce_core_effect *core_effect = &iforce->core_effects[effect_id];
int err = 0;
- struct iforce_core_effect* core_effect;
-
- if (effect_id < 0 || effect_id >= FF_EFFECTS_MAX)
- return -EINVAL;
-
- core_effect = &iforce->core_effects[effect_id];
-
- /* Check who is trying to erase this effect */
- if (core_effect->owner != current->pid) {
- printk(KERN_WARNING "iforce-main.c: %d tried to erase an effect belonging to %d\n", current->pid, core_effect->owner);
- return -EACCES;
- }
if (test_bit(FF_MOD1_IS_USED, core_effect->flags))
err = release_resource(&core_effect->mod1_chunk);
@@ -240,7 +183,7 @@ static int iforce_erase_effect(struct input_dev *dev, int effect_id)
if (!err && test_bit(FF_MOD2_IS_USED, core_effect->flags))
err = release_resource(&core_effect->mod2_chunk);
- /*TODO: remember to change that if more FF_MOD* bits are added */
+ /* TODO: remember to change that if more FF_MOD* bits are added */
core_effect->flags[0] = 0;
return err;
@@ -260,52 +203,31 @@ static int iforce_open(struct input_dev *dev)
#endif
}
- /* Enable force feedback */
- iforce_send_packet(iforce, FF_CMD_ENABLE, "\004");
+ if (test_bit(EV_FF, dev->evbit)) {
+ /* Enable force feedback */
+ iforce_send_packet(iforce, FF_CMD_ENABLE, "\004");
+ }
return 0;
}
-static int iforce_flush(struct input_dev *dev, struct file *file)
+static void iforce_release(struct input_dev *dev)
{
struct iforce *iforce = dev->private;
int i;
- /* Erase all effects this process owns */
- for (i=0; i<dev->ff_effects_max; ++i) {
-
- if (test_bit(FF_CORE_IS_USED, iforce->core_effects[i].flags) &&
- current->pid == iforce->core_effects[i].owner) {
-
- /* Stop effect */
- input_report_ff(dev, i, 0);
-
- /* Free ressources assigned to effect */
- if (iforce_erase_effect(dev, i)) {
- printk(KERN_WARNING "iforce_flush: erase effect %d failed\n", i);
+ if (test_bit(EV_FF, dev->evbit)) {
+ /* Check: no effects should be present in memory */
+ for (i = 0; i < dev->ff->max_effects; i++) {
+ if (test_bit(FF_CORE_IS_USED, iforce->core_effects[i].flags)) {
+ printk(KERN_WARNING "iforce_release: Device still owns effects\n");
+ break;
}
}
+ /* Disable force feedback playback */
+ iforce_send_packet(iforce, FF_CMD_ENABLE, "\001");
}
- return 0;
-}
-
-static void iforce_release(struct input_dev *dev)
-{
- struct iforce *iforce = dev->private;
- int i;
-
- /* Check: no effect should be present in memory */
- for (i=0; i<dev->ff_effects_max; ++i) {
- if (test_bit(FF_CORE_IS_USED, iforce->core_effects[i].flags))
- break;
- }
- if (i<dev->ff_effects_max) {
- printk(KERN_WARNING "iforce_release: Device still owns effects\n");
- }
-
- /* Disable force feedback playback */
- iforce_send_packet(iforce, FF_CMD_ENABLE, "\001");
switch (iforce->bus) {
#ifdef CONFIG_JOYSTICK_IFORCE_USB
@@ -342,8 +264,10 @@ void iforce_delete_device(struct iforce *iforce)
int iforce_init_device(struct iforce *iforce)
{
struct input_dev *input_dev;
+ struct ff_device *ff;
unsigned char c[] = "CEOV";
- int i;
+ int i, error;
+ int ff_effects = 0;
input_dev = input_allocate_device();
if (!input_dev)
@@ -378,11 +302,6 @@ int iforce_init_device(struct iforce *iforce)
input_dev->name = "Unknown I-Force device";
input_dev->open = iforce_open;
input_dev->close = iforce_release;
- input_dev->flush = iforce_flush;
- input_dev->event = iforce_input_event;
- input_dev->upload_effect = iforce_upload_effect;
- input_dev->erase_effect = iforce_erase_effect;
- input_dev->ff_effects_max = 10;
/*
* On-device memory allocation.
@@ -430,15 +349,15 @@ int iforce_init_device(struct iforce *iforce)
printk(KERN_WARNING "iforce-main.c: Device does not respond to id packet B\n");
if (!iforce_get_id_packet(iforce, "N"))
- iforce->dev->ff_effects_max = iforce->edata[1];
+ ff_effects = iforce->edata[1];
else
printk(KERN_WARNING "iforce-main.c: Device does not respond to id packet N\n");
/* Check if the device can store more effects than the driver can really handle */
- if (iforce->dev->ff_effects_max > FF_EFFECTS_MAX) {
- printk(KERN_WARNING "input??: Device can handle %d effects, but N_EFFECTS_MAX is set to %d in iforce.h\n",
- iforce->dev->ff_effects_max, FF_EFFECTS_MAX);
- iforce->dev->ff_effects_max = FF_EFFECTS_MAX;
+ if (ff_effects > IFORCE_EFFECTS_MAX) {
+ printk(KERN_WARNING "iforce: Limiting number of effects to %d (device reports %d)\n",
+ IFORCE_EFFECTS_MAX, ff_effects);
+ ff_effects = IFORCE_EFFECTS_MAX;
}
/*
@@ -472,12 +391,10 @@ int iforce_init_device(struct iforce *iforce)
* Set input device bitfields and ranges.
*/
- input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS) | BIT(EV_FF) | BIT(EV_FF_STATUS);
+ input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS) | BIT(EV_FF_STATUS);
- for (i = 0; iforce->type->btn[i] >= 0; i++) {
- signed short t = iforce->type->btn[i];
- set_bit(t, input_dev->keybit);
- }
+ for (i = 0; iforce->type->btn[i] >= 0; i++)
+ set_bit(iforce->type->btn[i], input_dev->keybit);
set_bit(BTN_DEAD, input_dev->keybit);
for (i = 0; iforce->type->abs[i] >= 0; i++) {
@@ -516,9 +433,24 @@ int iforce_init_device(struct iforce *iforce)
}
}
- for (i = 0; iforce->type->ff[i] >= 0; i++)
- set_bit(iforce->type->ff[i], input_dev->ffbit);
+ if (ff_effects) {
+ for (i = 0; iforce->type->ff[i] >= 0; i++)
+ set_bit(iforce->type->ff[i], input_dev->ffbit);
+
+ error = input_ff_create(input_dev, ff_effects);
+ if (error) {
+ input_free_device(input_dev);
+ return error;
+ }
+
+ ff = input_dev->ff;
+ ff->upload = iforce_upload_effect;
+ ff->erase = iforce_erase_effect;
+ ff->set_gain = iforce_set_gain;
+ ff->set_autocenter = iforce_set_autocenter;
+ ff->playback = iforce_playback;
+ }
/*
* Register input device.
*/
diff --git a/drivers/input/joystick/iforce/iforce-packets.c b/drivers/input/joystick/iforce/iforce-packets.c
index 76cb1f88f4e8..8632d47a7fbe 100644
--- a/drivers/input/joystick/iforce/iforce-packets.c
+++ b/drivers/input/joystick/iforce/iforce-packets.c
@@ -140,7 +140,10 @@ static int mark_core_as_ready(struct iforce *iforce, unsigned short addr)
{
int i;
- for (i = 0; i < iforce->dev->ff_effects_max; ++i) {
+ if (!iforce->dev->ff)
+ return 0;
+
+ for (i = 0; i < iforce->dev->ff->max_effects; ++i) {
if (test_bit(FF_CORE_IS_USED, iforce->core_effects[i].flags) &&
(iforce->core_effects[i].mod1_chunk.start == addr ||
iforce->core_effects[i].mod2_chunk.start == addr)) {
@@ -229,19 +232,17 @@ void iforce_process_packet(struct iforce *iforce, u16 cmd, unsigned char *data,
i = data[1] & 0x7f;
if (data[1] & 0x80) {
if (!test_and_set_bit(FF_CORE_IS_PLAYED, iforce->core_effects[i].flags)) {
- /* Report play event */
- input_report_ff_status(dev, i, FF_STATUS_PLAYING);
+ /* Report play event */
+ input_report_ff_status(dev, i, FF_STATUS_PLAYING);
}
- }
- else if (test_and_clear_bit(FF_CORE_IS_PLAYED, iforce->core_effects[i].flags)) {
+ } else if (test_and_clear_bit(FF_CORE_IS_PLAYED, iforce->core_effects[i].flags)) {
/* Report stop event */
input_report_ff_status(dev, i, FF_STATUS_STOPPED);
}
if (LO(cmd) > 3) {
int j;
- for (j=3; j<LO(cmd); j+=2) {
+ for (j = 3; j < LO(cmd); j += 2)
mark_core_as_ready(iforce, data[j] | (data[j+1]<<8));
- }
}
break;
}
diff --git a/drivers/input/joystick/iforce/iforce.h b/drivers/input/joystick/iforce/iforce.h
index e9924d6f01b3..947df2739843 100644
--- a/drivers/input/joystick/iforce/iforce.h
+++ b/drivers/input/joystick/iforce/iforce.h
@@ -51,10 +51,7 @@
#define IFORCE_232 1
#define IFORCE_USB 2
-#define FALSE 0
-#define TRUE 1
-
-#define FF_EFFECTS_MAX 32
+#define IFORCE_EFFECTS_MAX 32
/* Each force feedback effect is made of one core effect, which can be
* associated to at most to effect modifiers
@@ -67,24 +64,11 @@
#define FF_CORE_UPDATE 5 /* Effect is being updated */
#define FF_MODCORE_MAX 5
-#define CHECK_OWNERSHIP(i, iforce) \
- ((i) < FF_EFFECTS_MAX && i >= 0 && \
- test_bit(FF_CORE_IS_USED, (iforce)->core_effects[(i)].flags) && \
- (current->pid == 0 || \
- (iforce)->core_effects[(i)].owner == current->pid))
-
struct iforce_core_effect {
/* Information about where modifiers are stored in the device's memory */
struct resource mod1_chunk;
struct resource mod2_chunk;
unsigned long flags[NBITS(FF_MODCORE_MAX)];
- pid_t owner;
- /* Used to keep track of parameters of an effect. They are needed
- * to know what parts of an effect changed in an update operation.
- * We try to send only parameter packets if possible, as sending
- * effect parameter requires the effect to be stoped and restarted
- */
- struct ff_effect effect;
};
#define FF_CMD_EFFECT 0x010e
@@ -145,7 +129,7 @@ struct iforce {
/* Force Feedback */
wait_queue_head_t wait;
struct resource device_memory;
- struct iforce_core_effect core_effects[FF_EFFECTS_MAX];
+ struct iforce_core_effect core_effects[IFORCE_EFFECTS_MAX];
struct mutex mem_mutex;
};
@@ -182,9 +166,9 @@ void iforce_dump_packet(char *msg, u16 cmd, unsigned char *data) ;
int iforce_get_id_packet(struct iforce *iforce, char *packet);
/* iforce-ff.c */
-int iforce_upload_periodic(struct iforce*, struct ff_effect*, int is_update);
-int iforce_upload_constant(struct iforce*, struct ff_effect*, int is_update);
-int iforce_upload_condition(struct iforce*, struct ff_effect*, int is_update);
+int iforce_upload_periodic(struct iforce *, struct ff_effect *, struct ff_effect *);
+int iforce_upload_constant(struct iforce *, struct ff_effect *, struct ff_effect *);
+int iforce_upload_condition(struct iforce *, struct ff_effect *, struct ff_effect *);
/* Public variables */
extern struct serio_driver iforce_serio_drv;
diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig
index a9dda56f62c4..c62e00c79dec 100644
--- a/drivers/input/keyboard/Kconfig
+++ b/drivers/input/keyboard/Kconfig
@@ -121,6 +121,17 @@ config KEYBOARD_NEWTON
To compile this driver as a module, choose M here: the
module will be called newtonkbd.
+config KEYBOARD_STOWAWAY
+ tristate "Stowaway keyboard"
+ select SERIO
+ help
+ Say Y here if you have a Stowaway keyboard on a serial port.
+ Stowaway compatible keyboards like Dicota Input-PDA keyboard
+ are also supported by this driver.
+
+ To compile this driver as a module, choose M here: the
+ module will be called stowaway.
+
config KEYBOARD_CORGI
tristate "Corgi keyboard"
depends on PXA_SHARPSL
@@ -183,4 +194,13 @@ config KEYBOARD_HIL
This driver implements support for HIL-keyboards attached
to your machine, so normally you should say Y here.
+config KEYBOARD_OMAP
+ tristate "TI OMAP keypad support"
+ depends on (ARCH_OMAP1 || ARCH_OMAP2)
+ help
+ Say Y here if you want to use the OMAP keypad.
+
+ To compile this driver as a module, choose M here: the
+ module will be called omap-keypad.
+
endif
diff --git a/drivers/input/keyboard/Makefile b/drivers/input/keyboard/Makefile
index 2708167ba175..4c79e7bc9d06 100644
--- a/drivers/input/keyboard/Makefile
+++ b/drivers/input/keyboard/Makefile
@@ -11,8 +11,10 @@ obj-$(CONFIG_KEYBOARD_XTKBD) += xtkbd.o
obj-$(CONFIG_KEYBOARD_AMIGA) += amikbd.o
obj-$(CONFIG_KEYBOARD_LOCOMO) += locomokbd.o
obj-$(CONFIG_KEYBOARD_NEWTON) += newtonkbd.o
+obj-$(CONFIG_KEYBOARD_STOWAWAY) += stowaway.o
obj-$(CONFIG_KEYBOARD_CORGI) += corgikbd.o
obj-$(CONFIG_KEYBOARD_SPITZ) += spitzkbd.o
obj-$(CONFIG_KEYBOARD_HIL) += hil_kbd.o
obj-$(CONFIG_KEYBOARD_HIL_OLD) += hilkbd.o
+obj-$(CONFIG_KEYBOARD_OMAP) += omap-keypad.o
diff --git a/drivers/input/keyboard/atkbd.c b/drivers/input/keyboard/atkbd.c
index a86afd0a5ef1..40244d4ce0f1 100644
--- a/drivers/input/keyboard/atkbd.c
+++ b/drivers/input/keyboard/atkbd.c
@@ -652,9 +652,7 @@ static int atkbd_probe(struct atkbd *atkbd)
return 0;
}
- if (param[0] != 0xab && param[0] != 0xac && /* Regular and NCD Sun keyboards */
- param[0] != 0x2b && param[0] != 0x5d && /* Trust keyboard, raw and translated */
- param[0] != 0x60 && param[0] != 0x47) /* NMB SGI keyboard, raw and translated */
+ if (!ps2_is_keyboard_id(param[0]))
return -1;
atkbd->id = (param[0] << 8) | param[1];
diff --git a/drivers/input/keyboard/omap-keypad.c b/drivers/input/keyboard/omap-keypad.c
new file mode 100644
index 000000000000..d436287d1d2e
--- /dev/null
+++ b/drivers/input/keyboard/omap-keypad.c
@@ -0,0 +1,492 @@
+/*
+ * linux/drivers/input/keyboard/omap-keypad.c
+ *
+ * OMAP Keypad Driver
+ *
+ * Copyright (C) 2003 Nokia Corporation
+ * Written by Timo Teräs <ext-timo.teras@nokia.com>
+ *
+ * Added support for H2 & H3 Keypad
+ * Copyright (C) 2004 Texas Instruments
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/types.h>
+#include <linux/input.h>
+#include <linux/kernel.h>
+#include <linux/delay.h>
+#include <linux/platform_device.h>
+#include <linux/mutex.h>
+#include <linux/errno.h>
+#include <asm/arch/gpio.h>
+#include <asm/arch/keypad.h>
+#include <asm/arch/menelaus.h>
+#include <asm/irq.h>
+#include <asm/hardware.h>
+#include <asm/io.h>
+#include <asm/mach-types.h>
+#include <asm/arch/mux.h>
+
+#undef NEW_BOARD_LEARNING_MODE
+
+static void omap_kp_tasklet(unsigned long);
+static void omap_kp_timer(unsigned long);
+
+static unsigned char keypad_state[8];
+static DEFINE_MUTEX(kp_enable_mutex);
+static int kp_enable = 1;
+static int kp_cur_group = -1;
+
+struct omap_kp {
+ struct input_dev *input;
+ struct timer_list timer;
+ int irq;
+ unsigned int rows;
+ unsigned int cols;
+ unsigned long delay;
+ unsigned int debounce;
+};
+
+DECLARE_TASKLET_DISABLED(kp_tasklet, omap_kp_tasklet, 0);
+
+static int *keymap;
+static unsigned int *row_gpios;
+static unsigned int *col_gpios;
+
+#ifdef CONFIG_ARCH_OMAP2
+static void set_col_gpio_val(struct omap_kp *omap_kp, u8 value)
+{
+ int col;
+ for (col = 0; col < omap_kp->cols; col++) {
+ if (value & (1 << col))
+ omap_set_gpio_dataout(col_gpios[col], 1);
+ else
+ omap_set_gpio_dataout(col_gpios[col], 0);
+ }
+}
+
+static u8 get_row_gpio_val(struct omap_kp *omap_kp)
+{
+ int row;
+ u8 value = 0;
+
+ for (row = 0; row < omap_kp->rows; row++) {
+ if (omap_get_gpio_datain(row_gpios[row]))
+ value |= (1 << row);
+ }
+ return value;
+}
+#else
+#define set_col_gpio_val(x, y) do {} while (0)
+#define get_row_gpio_val(x) 0
+#endif
+
+static irqreturn_t omap_kp_interrupt(int irq, void *dev_id,
+ struct pt_regs *regs)
+{
+ struct omap_kp *omap_kp = dev_id;
+
+ /* disable keyboard interrupt and schedule for handling */
+ if (cpu_is_omap24xx()) {
+ int i;
+ for (i = 0; i < omap_kp->rows; i++)
+ disable_irq(OMAP_GPIO_IRQ(row_gpios[i]));
+ } else
+ /* disable keyboard interrupt and schedule for handling */
+ omap_writew(1, OMAP_MPUIO_BASE + OMAP_MPUIO_KBD_MASKIT);
+
+ tasklet_schedule(&kp_tasklet);
+
+ return IRQ_HANDLED;
+}
+
+static void omap_kp_timer(unsigned long data)
+{
+ tasklet_schedule(&kp_tasklet);
+}
+
+static void omap_kp_scan_keypad(struct omap_kp *omap_kp, unsigned char *state)
+{
+ int col = 0;
+
+ /* read the keypad status */
+ if (cpu_is_omap24xx()) {
+ int i;
+ for (i = 0; i < omap_kp->rows; i++)
+ disable_irq(OMAP_GPIO_IRQ(row_gpios[i]));
+
+ /* read the keypad status */
+ for (col = 0; col < omap_kp->cols; col++) {
+ set_col_gpio_val(omap_kp, ~(1 << col));
+ state[col] = ~(get_row_gpio_val(omap_kp)) & 0x3f;
+ }
+ set_col_gpio_val(omap_kp, 0);
+
+ } else {
+ /* disable keyboard interrupt and schedule for handling */
+ omap_writew(1, OMAP_MPUIO_BASE + OMAP_MPUIO_KBD_MASKIT);
+
+ /* read the keypad status */
+ omap_writew(0xff, OMAP_MPUIO_BASE + OMAP_MPUIO_KBC);
+ for (col = 0; col < omap_kp->cols; col++) {
+ omap_writew(~(1 << col) & 0xff,
+ OMAP_MPUIO_BASE + OMAP_MPUIO_KBC);
+
+ udelay(omap_kp->delay);
+
+ state[col] = ~omap_readw(OMAP_MPUIO_BASE +
+ OMAP_MPUIO_KBR_LATCH) & 0xff;
+ }
+ omap_writew(0x00, OMAP_MPUIO_BASE + OMAP_MPUIO_KBC);
+ udelay(2);
+ }
+}
+
+static inline int omap_kp_find_key(int col, int row)
+{
+ int i, key;
+
+ key = KEY(col, row, 0);
+ for (i = 0; keymap[i] != 0; i++)
+ if ((keymap[i] & 0xff000000) == key)
+ return keymap[i] & 0x00ffffff;
+ return -1;
+}
+
+static void omap_kp_tasklet(unsigned long data)
+{
+ struct omap_kp *omap_kp_data = (struct omap_kp *) data;
+ unsigned char new_state[8], changed, key_down = 0;
+ int col, row;
+ int spurious = 0;
+
+ /* check for any changes */
+ omap_kp_scan_keypad(omap_kp_data, new_state);
+
+ /* check for changes and print those */
+ for (col = 0; col < omap_kp_data->cols; col++) {
+ changed = new_state[col] ^ keypad_state[col];
+ key_down |= new_state[col];
+ if (changed == 0)
+ continue;
+
+ for (row = 0; row < omap_kp_data->rows; row++) {
+ int key;
+ if (!(changed & (1 << row)))
+ continue;
+#ifdef NEW_BOARD_LEARNING_MODE
+ printk(KERN_INFO "omap-keypad: key %d-%d %s\n", col,
+ row, (new_state[col] & (1 << row)) ?
+ "pressed" : "released");
+#else
+ key = omap_kp_find_key(col, row);
+ if (key < 0) {
+ printk(KERN_WARNING
+ "omap-keypad: Spurious key event %d-%d\n",
+ col, row);
+ /* We scan again after a couple of seconds */
+ spurious = 1;
+ continue;
+ }
+
+ if (!(kp_cur_group == (key & GROUP_MASK) ||
+ kp_cur_group == -1))
+ continue;
+
+ kp_cur_group = key & GROUP_MASK;
+ input_report_key(omap_kp_data->input, key & ~GROUP_MASK,
+ new_state[col] & (1 << row));
+#endif
+ }
+ }
+ memcpy(keypad_state, new_state, sizeof(keypad_state));
+
+ if (key_down) {
+ int delay = HZ / 20;
+ /* some key is pressed - keep irq disabled and use timer
+ * to poll the keypad */
+ if (spurious)
+ delay = 2 * HZ;
+ mod_timer(&omap_kp_data->timer, jiffies + delay);
+ } else {
+ /* enable interrupts */
+ if (cpu_is_omap24xx()) {
+ int i;
+ for (i = 0; i < omap_kp_data->rows; i++)
+ enable_irq(OMAP_GPIO_IRQ(row_gpios[i]));
+ } else {
+ omap_writew(0, OMAP_MPUIO_BASE + OMAP_MPUIO_KBD_MASKIT);
+ kp_cur_group = -1;
+ }
+ }
+}
+
+static ssize_t omap_kp_enable_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ return sprintf(buf, "%u\n", kp_enable);
+}
+
+static ssize_t omap_kp_enable_store(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ int state;
+
+ if (sscanf(buf, "%u", &state) != 1)
+ return -EINVAL;
+
+ if ((state != 1) && (state != 0))
+ return -EINVAL;
+
+ mutex_lock(&kp_enable_mutex);
+ if (state != kp_enable) {
+ if (state)
+ enable_irq(INT_KEYBOARD);
+ else
+ disable_irq(INT_KEYBOARD);
+ kp_enable = state;
+ }
+ mutex_unlock(&kp_enable_mutex);
+
+ return strnlen(buf, count);
+}
+
+static DEVICE_ATTR(enable, S_IRUGO | S_IWUSR, omap_kp_enable_show, omap_kp_enable_store);
+
+#ifdef CONFIG_PM
+static int omap_kp_suspend(struct platform_device *dev, pm_message_t state)
+{
+ /* Nothing yet */
+
+ return 0;
+}
+
+static int omap_kp_resume(struct platform_device *dev)
+{
+ /* Nothing yet */
+
+ return 0;
+}
+#else
+#define omap_kp_suspend NULL
+#define omap_kp_resume NULL
+#endif
+
+static int __init omap_kp_probe(struct platform_device *pdev)
+{
+ struct omap_kp *omap_kp;
+ struct input_dev *input_dev;
+ struct omap_kp_platform_data *pdata = pdev->dev.platform_data;
+ int i, col_idx, row_idx, irq_idx, ret;
+
+ if (!pdata->rows || !pdata->cols || !pdata->keymap) {
+ printk(KERN_ERR "No rows, cols or keymap from pdata\n");
+ return -EINVAL;
+ }
+
+ omap_kp = kzalloc(sizeof(struct omap_kp), GFP_KERNEL);
+ input_dev = input_allocate_device();
+ if (!omap_kp || !input_dev) {
+ kfree(omap_kp);
+ input_free_device(input_dev);
+ return -ENOMEM;
+ }
+
+ platform_set_drvdata(pdev, omap_kp);
+
+ omap_kp->input = input_dev;
+
+ /* Disable the interrupt for the MPUIO keyboard */
+ if (!cpu_is_omap24xx())
+ omap_writew(1, OMAP_MPUIO_BASE + OMAP_MPUIO_KBD_MASKIT);
+
+ keymap = pdata->keymap;
+
+ if (pdata->rep)
+ set_bit(EV_REP, input_dev->evbit);
+
+ if (pdata->delay)
+ omap_kp->delay = pdata->delay;
+
+ if (pdata->row_gpios && pdata->col_gpios) {
+ row_gpios = pdata->row_gpios;
+ col_gpios = pdata->col_gpios;
+ }
+
+ omap_kp->rows = pdata->rows;
+ omap_kp->cols = pdata->cols;
+
+ if (cpu_is_omap24xx()) {
+ /* Cols: outputs */
+ for (col_idx = 0; col_idx < omap_kp->cols; col_idx++) {
+ if (omap_request_gpio(col_gpios[col_idx]) < 0) {
+ printk(KERN_ERR "Failed to request"
+ "GPIO%d for keypad\n",
+ col_gpios[col_idx]);
+ goto err1;
+ }
+ omap_set_gpio_direction(col_gpios[col_idx], 0);
+ }
+ /* Rows: inputs */
+ for (row_idx = 0; row_idx < omap_kp->rows; row_idx++) {
+ if (omap_request_gpio(row_gpios[row_idx]) < 0) {
+ printk(KERN_ERR "Failed to request"
+ "GPIO%d for keypad\n",
+ row_gpios[row_idx]);
+ goto err2;
+ }
+ omap_set_gpio_direction(row_gpios[row_idx], 1);
+ }
+ }
+
+ setup_timer(&omap_kp->timer, omap_kp_timer, (unsigned long)omap_kp);
+
+ /* get the irq and init timer*/
+ tasklet_enable(&kp_tasklet);
+ kp_tasklet.data = (unsigned long) omap_kp;
+
+ ret = device_create_file(&pdev->dev, &dev_attr_enable);
+ if (ret < 0)
+ goto err2;
+
+ /* setup input device */
+ set_bit(EV_KEY, input_dev->evbit);
+ for (i = 0; keymap[i] != 0; i++)
+ set_bit(keymap[i] & KEY_MAX, input_dev->keybit);
+ input_dev->name = "omap-keypad";
+ input_dev->phys = "omap-keypad/input0";
+ input_dev->cdev.dev = &pdev->dev;
+ input_dev->private = omap_kp;
+
+ input_dev->id.bustype = BUS_HOST;
+ input_dev->id.vendor = 0x0001;
+ input_dev->id.product = 0x0001;
+ input_dev->id.version = 0x0100;
+
+ input_dev->keycode = keymap;
+ input_dev->keycodesize = sizeof(unsigned int);
+ input_dev->keycodemax = pdata->keymapsize;
+
+ ret = input_register_device(omap_kp->input);
+ if (ret < 0) {
+ printk(KERN_ERR "Unable to register omap-keypad input device\n");
+ goto err3;
+ }
+
+ if (pdata->dbounce)
+ omap_writew(0xff, OMAP_MPUIO_BASE + OMAP_MPUIO_GPIO_DEBOUNCING);
+
+ /* scan current status and enable interrupt */
+ omap_kp_scan_keypad(omap_kp, keypad_state);
+ if (!cpu_is_omap24xx()) {
+ omap_kp->irq = platform_get_irq(pdev, 0);
+ if (omap_kp->irq >= 0) {
+ if (request_irq(omap_kp->irq, omap_kp_interrupt, 0,
+ "omap-keypad", omap_kp) < 0)
+ goto err4;
+ }
+ omap_writew(0, OMAP_MPUIO_BASE + OMAP_MPUIO_KBD_MASKIT);
+ } else {
+ for (irq_idx = 0; irq_idx < omap_kp->rows; irq_idx++) {
+ if (request_irq(OMAP_GPIO_IRQ(row_gpios[irq_idx]),
+ omap_kp_interrupt,
+ IRQF_TRIGGER_FALLING,
+ "omap-keypad", omap_kp) < 0)
+ goto err5;
+ }
+ }
+ return 0;
+err5:
+ for (i = irq_idx-1; i >=0; i--)
+ free_irq(row_gpios[i], 0);
+err4:
+ input_unregister_device(omap_kp->input);
+ input_dev = NULL;
+err3:
+ device_remove_file(&pdev->dev, &dev_attr_enable);
+err2:
+ for (i = row_idx-1; i >=0; i--)
+ omap_free_gpio(row_gpios[i]);
+err1:
+ for (i = col_idx-1; i >=0; i--)
+ omap_free_gpio(col_gpios[i]);
+
+ kfree(omap_kp);
+ input_free_device(input_dev);
+
+ return -EINVAL;
+}
+
+static int omap_kp_remove(struct platform_device *pdev)
+{
+ struct omap_kp *omap_kp = platform_get_drvdata(pdev);
+
+ /* disable keypad interrupt handling */
+ tasklet_disable(&kp_tasklet);
+ if (cpu_is_omap24xx()) {
+ int i;
+ for (i = 0; i < omap_kp->cols; i++)
+ omap_free_gpio(col_gpios[i]);
+ for (i = 0; i < omap_kp->rows; i++) {
+ omap_free_gpio(row_gpios[i]);
+ free_irq(OMAP_GPIO_IRQ(row_gpios[i]), 0);
+ }
+ } else {
+ omap_writew(1, OMAP_MPUIO_BASE + OMAP_MPUIO_KBD_MASKIT);
+ free_irq(omap_kp->irq, 0);
+ }
+
+ del_timer_sync(&omap_kp->timer);
+ tasklet_kill(&kp_tasklet);
+
+ /* unregister everything */
+ input_unregister_device(omap_kp->input);
+
+ kfree(omap_kp);
+
+ return 0;
+}
+
+static struct platform_driver omap_kp_driver = {
+ .probe = omap_kp_probe,
+ .remove = omap_kp_remove,
+ .suspend = omap_kp_suspend,
+ .resume = omap_kp_resume,
+ .driver = {
+ .name = "omap-keypad",
+ },
+};
+
+static int __devinit omap_kp_init(void)
+{
+ printk(KERN_INFO "OMAP Keypad Driver\n");
+ return platform_driver_register(&omap_kp_driver);
+}
+
+static void __exit omap_kp_exit(void)
+{
+ platform_driver_unregister(&omap_kp_driver);
+}
+
+module_init(omap_kp_init);
+module_exit(omap_kp_exit);
+
+MODULE_AUTHOR("Timo Teräs");
+MODULE_DESCRIPTION("OMAP Keypad Driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/input/keyboard/stowaway.c b/drivers/input/keyboard/stowaway.c
new file mode 100644
index 000000000000..04c54c57f25c
--- /dev/null
+++ b/drivers/input/keyboard/stowaway.c
@@ -0,0 +1,187 @@
+/*
+ * Stowaway keyboard driver for Linux
+ */
+
+/*
+ * Copyright (c) 2006 Marek Vasut
+ *
+ * Based on Newton keyboard driver for Linux
+ * by Justin Cormack
+ */
+
+/*
+ * 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
+ *
+ * Should you need to contact me, the author, you can do so either by
+ * e-mail - mail your message to <marek.vasut@gmail.com>, or by paper mail:
+ * Marek Vasut, Liskovecka 559, Frydek-Mistek, 738 01 Czech Republic
+ */
+
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <linux/input.h>
+#include <linux/init.h>
+#include <linux/serio.h>
+
+#define DRIVER_DESC "Stowaway keyboard driver"
+
+MODULE_AUTHOR("Marek Vasut <marek.vasut@gmail.com>");
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_LICENSE("GPL");
+
+#define SKBD_KEY_MASK 0x7f
+#define SKBD_RELEASE 0x80
+
+static unsigned char skbd_keycode[128] = {
+ KEY_1, KEY_2, KEY_3, KEY_Z, KEY_4, KEY_5, KEY_6, KEY_7,
+ 0, KEY_Q, KEY_W, KEY_E, KEY_R, KEY_T, KEY_Y, KEY_GRAVE,
+ KEY_X, KEY_A, KEY_S, KEY_D, KEY_F, KEY_G, KEY_H, KEY_SPACE,
+ KEY_CAPSLOCK, KEY_TAB, KEY_LEFTCTRL, 0, 0, 0, 0, 0,
+ 0, 0, 0, KEY_LEFTALT, 0, 0, 0, 0,
+ 0, 0, 0, 0, KEY_C, KEY_V, KEY_B, KEY_N,
+ KEY_MINUS, KEY_EQUAL, KEY_BACKSPACE, KEY_HOME, KEY_8, KEY_9, KEY_0, KEY_ESC,
+ KEY_LEFTBRACE, KEY_RIGHTBRACE, KEY_BACKSLASH, KEY_END, KEY_U, KEY_I, KEY_O, KEY_P,
+ KEY_APOSTROPHE, KEY_ENTER, KEY_PAGEUP,0, KEY_J, KEY_K, KEY_L, KEY_SEMICOLON,
+ KEY_SLASH, KEY_UP, KEY_PAGEDOWN, 0,KEY_M, KEY_COMMA, KEY_DOT, KEY_INSERT,
+ KEY_DELETE, KEY_LEFT, KEY_DOWN, KEY_RIGHT, 0, 0, 0,
+ KEY_LEFTSHIFT, KEY_RIGHTSHIFT, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, KEY_F1, KEY_F2, KEY_F3, KEY_F4, KEY_F5, KEY_F6, KEY_F7,
+ KEY_F8, KEY_F9, KEY_F10, KEY_F11, KEY_F12, 0, 0, 0
+};
+
+struct skbd {
+ unsigned char keycode[128];
+ struct input_dev *dev;
+ struct serio *serio;
+ char phys[32];
+};
+
+static irqreturn_t skbd_interrupt(struct serio *serio, unsigned char data,
+ unsigned int flags, struct pt_regs *regs)
+{
+ struct skbd *skbd = serio_get_drvdata(serio);
+ struct input_dev *dev = skbd->dev;
+
+ if (skbd->keycode[data & SKBD_KEY_MASK]) {
+ input_regs(dev, regs);
+ input_report_key(dev, skbd->keycode[data & SKBD_KEY_MASK],
+ !(data & SKBD_RELEASE));
+ input_sync(dev);
+ }
+
+ return IRQ_HANDLED;
+}
+
+static int skbd_connect(struct serio *serio, struct serio_driver *drv)
+{
+ struct skbd *skbd;
+ struct input_dev *input_dev;
+ int err = -ENOMEM;
+ int i;
+
+ skbd = kzalloc(sizeof(struct skbd), GFP_KERNEL);
+ input_dev = input_allocate_device();
+ if (!skbd || !input_dev)
+ goto fail1;
+
+ skbd->serio = serio;
+ skbd->dev = input_dev;
+ snprintf(skbd->phys, sizeof(skbd->phys), "%s/input0", serio->phys);
+ memcpy(skbd->keycode, skbd_keycode, sizeof(skbd->keycode));
+
+ input_dev->name = "Stowaway Keyboard";
+ input_dev->phys = skbd->phys;
+ input_dev->id.bustype = BUS_RS232;
+ input_dev->id.vendor = SERIO_STOWAWAY;
+ input_dev->id.product = 0x0001;
+ input_dev->id.version = 0x0100;
+ input_dev->cdev.dev = &serio->dev;
+ input_dev->private = skbd;
+
+ input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP);
+ input_dev->keycode = skbd->keycode;
+ input_dev->keycodesize = sizeof(unsigned char);
+ input_dev->keycodemax = ARRAY_SIZE(skbd_keycode);
+ for (i = 0; i < ARRAY_SIZE(skbd_keycode); i++)
+ set_bit(skbd_keycode[i], input_dev->keybit);
+ clear_bit(0, input_dev->keybit);
+
+ serio_set_drvdata(serio, skbd);
+
+ err = serio_open(serio, drv);
+ if (err)
+ goto fail2;
+
+ err = input_register_device(skbd->dev);
+ if (err)
+ goto fail3;
+
+ return 0;
+
+ fail3: serio_close(serio);
+ fail2: serio_set_drvdata(serio, NULL);
+ fail1: input_free_device(input_dev);
+ kfree(skbd);
+ return err;
+}
+
+static void skbd_disconnect(struct serio *serio)
+{
+ struct skbd *skbd = serio_get_drvdata(serio);
+
+ serio_close(serio);
+ serio_set_drvdata(serio, NULL);
+ input_unregister_device(skbd->dev);
+ kfree(skbd);
+}
+
+static struct serio_device_id skbd_serio_ids[] = {
+ {
+ .type = SERIO_RS232,
+ .proto = SERIO_STOWAWAY,
+ .id = SERIO_ANY,
+ .extra = SERIO_ANY,
+ },
+ { 0 }
+};
+
+MODULE_DEVICE_TABLE(serio, skbd_serio_ids);
+
+static struct serio_driver skbd_drv = {
+ .driver = {
+ .name = "stowaway",
+ },
+ .description = DRIVER_DESC,
+ .id_table = skbd_serio_ids,
+ .interrupt = skbd_interrupt,
+ .connect = skbd_connect,
+ .disconnect = skbd_disconnect,
+};
+
+static int __init skbd_init(void)
+{
+ serio_register_driver(&skbd_drv);
+ return 0;
+}
+
+static void __exit skbd_exit(void)
+{
+ serio_unregister_driver(&skbd_drv);
+}
+
+module_init(skbd_init);
+module_exit(skbd_exit);
diff --git a/drivers/input/misc/uinput.c b/drivers/input/misc/uinput.c
index d723e9ad7c41..9516439b7c78 100644
--- a/drivers/input/misc/uinput.c
+++ b/drivers/input/misc/uinput.c
@@ -20,6 +20,9 @@
* Author: Aristeu Sergio Rozanski Filho <aris@cathedrallabs.org>
*
* Changes/Revisions:
+ * 0.3 09/04/2006 (Anssi Hannula <anssi.hannula@gmail.com>)
+ * - updated ff support for the changes in kernel interface
+ * - added MODULE_VERSION
* 0.2 16/10/2004 (Micah Dowty <micah@navi.cx>)
* - added force feedback support
* - added UI_SET_PHYS
@@ -107,18 +110,31 @@ static int uinput_request_submit(struct input_dev *dev, struct uinput_request *r
return request->retval;
}
-static int uinput_dev_upload_effect(struct input_dev *dev, struct ff_effect *effect)
+static void uinput_dev_set_gain(struct input_dev *dev, u16 gain)
+{
+ uinput_dev_event(dev, EV_FF, FF_GAIN, gain);
+}
+
+static void uinput_dev_set_autocenter(struct input_dev *dev, u16 magnitude)
+{
+ uinput_dev_event(dev, EV_FF, FF_AUTOCENTER, magnitude);
+}
+
+static int uinput_dev_playback(struct input_dev *dev, int effect_id, int value)
+{
+ return uinput_dev_event(dev, EV_FF, effect_id, value);
+}
+
+static int uinput_dev_upload_effect(struct input_dev *dev, struct ff_effect *effect, struct ff_effect *old)
{
struct uinput_request request;
int retval;
- if (!test_bit(EV_FF, dev->evbit))
- return -ENOSYS;
-
request.id = -1;
init_completion(&request.done);
request.code = UI_FF_UPLOAD;
- request.u.effect = effect;
+ request.u.upload.effect = effect;
+ request.u.upload.old = old;
retval = uinput_request_reserve_slot(dev->private, &request);
if (!retval)
@@ -168,6 +184,7 @@ static void uinput_destroy_device(struct uinput_device *udev)
static int uinput_create_device(struct uinput_device *udev)
{
+ struct input_dev *dev = udev->dev;
int error;
if (udev->state != UIST_SETUP_COMPLETE) {
@@ -175,15 +192,29 @@ static int uinput_create_device(struct uinput_device *udev)
return -EINVAL;
}
- error = input_register_device(udev->dev);
- if (error) {
- uinput_destroy_device(udev);
- return error;
+ if (udev->ff_effects_max) {
+ error = input_ff_create(dev, udev->ff_effects_max);
+ if (error)
+ goto fail1;
+
+ dev->ff->upload = uinput_dev_upload_effect;
+ dev->ff->erase = uinput_dev_erase_effect;
+ dev->ff->playback = uinput_dev_playback;
+ dev->ff->set_gain = uinput_dev_set_gain;
+ dev->ff->set_autocenter = uinput_dev_set_autocenter;
}
+ error = input_register_device(udev->dev);
+ if (error)
+ goto fail2;
+
udev->state = UIST_CREATED;
return 0;
+
+ fail2: input_ff_destroy(dev);
+ fail1: uinput_destroy_device(udev);
+ return error;
}
static int uinput_open(struct inode *inode, struct file *file)
@@ -243,8 +274,6 @@ static int uinput_allocate_device(struct uinput_device *udev)
return -ENOMEM;
udev->dev->event = uinput_dev_event;
- udev->dev->upload_effect = uinput_dev_upload_effect;
- udev->dev->erase_effect = uinput_dev_erase_effect;
udev->dev->private = udev;
return 0;
@@ -278,6 +307,8 @@ static int uinput_setup_device(struct uinput_device *udev, const char __user *bu
goto exit;
}
+ udev->ff_effects_max = user_dev->ff_effects_max;
+
size = strnlen(user_dev->name, UINPUT_MAX_NAME_SIZE) + 1;
if (!size) {
retval = -EINVAL;
@@ -296,7 +327,6 @@ static int uinput_setup_device(struct uinput_device *udev, const char __user *bu
dev->id.vendor = user_dev->id.vendor;
dev->id.product = user_dev->id.product;
dev->id.version = user_dev->id.version;
- dev->ff_effects_max = user_dev->ff_effects_max;
size = sizeof(int) * (ABS_MAX + 1);
memcpy(dev->absmax, user_dev->absmax, size);
@@ -525,12 +555,17 @@ static long uinput_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
break;
}
req = uinput_request_find(udev, ff_up.request_id);
- if (!(req && req->code == UI_FF_UPLOAD && req->u.effect)) {
+ if (!(req && req->code == UI_FF_UPLOAD && req->u.upload.effect)) {
retval = -EINVAL;
break;
}
ff_up.retval = 0;
- memcpy(&ff_up.effect, req->u.effect, sizeof(struct ff_effect));
+ memcpy(&ff_up.effect, req->u.upload.effect, sizeof(struct ff_effect));
+ if (req->u.upload.old)
+ memcpy(&ff_up.old, req->u.upload.old, sizeof(struct ff_effect));
+ else
+ memset(&ff_up.old, 0, sizeof(struct ff_effect));
+
if (copy_to_user(p, &ff_up, sizeof(ff_up))) {
retval = -EFAULT;
break;
@@ -561,12 +596,11 @@ static long uinput_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
break;
}
req = uinput_request_find(udev, ff_up.request_id);
- if (!(req && req->code == UI_FF_UPLOAD && req->u.effect)) {
+ if (!(req && req->code == UI_FF_UPLOAD && req->u.upload.effect)) {
retval = -EINVAL;
break;
}
req->retval = ff_up.retval;
- memcpy(req->u.effect, &ff_up.effect, sizeof(struct ff_effect));
uinput_request_done(udev, req);
break;
@@ -622,6 +656,7 @@ static void __exit uinput_exit(void)
MODULE_AUTHOR("Aristeu Sergio Rozanski Filho");
MODULE_DESCRIPTION("User level driver support for input subsystem");
MODULE_LICENSE("GPL");
+MODULE_VERSION("0.3");
module_init(uinput_init);
module_exit(uinput_exit);
diff --git a/drivers/input/misc/wistron_btns.c b/drivers/input/misc/wistron_btns.c
index de0f46dd9692..4639537336fc 100644
--- a/drivers/input/misc/wistron_btns.c
+++ b/drivers/input/misc/wistron_btns.c
@@ -248,13 +248,10 @@ static int __init dmi_matched(struct dmi_system_id *dmi)
keymap = dmi->driver_data;
for (key = keymap; key->type != KE_END; key++) {
- if (key->type == KE_WIFI) {
+ if (key->type == KE_WIFI)
have_wifi = 1;
- break;
- } else if (key->type == KE_BLUETOOTH) {
+ else if (key->type == KE_BLUETOOTH)
have_bluetooth = 1;
- break;
- }
}
return 1;
}
@@ -389,7 +386,16 @@ static struct dmi_system_id dmi_ids[] __initdata = {
},
.driver_data = keymap_acer_travelmate_240
},
- {
+ {
+ .callback = dmi_matched,
+ .ident = "Acer TravelMate 2424NWXCi",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 2420"),
+ },
+ .driver_data = keymap_acer_travelmate_240
+ },
+ {
.callback = dmi_matched,
.ident = "AOpen 1559AS",
.matches = {
diff --git a/drivers/input/mouse/alps.c b/drivers/input/mouse/alps.c
index 070d75330afd..450b68a619fd 100644
--- a/drivers/input/mouse/alps.c
+++ b/drivers/input/mouse/alps.c
@@ -36,7 +36,7 @@
#define ALPS_PASS 0x20
#define ALPS_FW_BK_2 0x40
-static struct alps_model_info alps_model_data[] = {
+static const struct alps_model_info alps_model_data[] = {
{ { 0x33, 0x02, 0x0a }, 0x88, 0xf8, ALPS_OLDPROTO }, /* UMAX-530T */
{ { 0x53, 0x02, 0x0a }, 0xf8, 0xf8, 0 },
{ { 0x53, 0x02, 0x14 }, 0xf8, 0xf8, 0 },
@@ -209,10 +209,10 @@ static psmouse_ret_t alps_process_byte(struct psmouse *psmouse, struct pt_regs *
return PSMOUSE_GOOD_DATA;
}
-static struct alps_model_info *alps_get_model(struct psmouse *psmouse, int *version)
+static const struct alps_model_info *alps_get_model(struct psmouse *psmouse, int *version)
{
struct ps2dev *ps2dev = &psmouse->ps2dev;
- unsigned char rates[] = { 0, 10, 20, 40, 60, 80, 100, 200 };
+ static const unsigned char rates[] = { 0, 10, 20, 40, 60, 80, 100, 200 };
unsigned char param[4];
int i;
@@ -504,7 +504,7 @@ init_fail:
int alps_detect(struct psmouse *psmouse, int set_properties)
{
int version;
- struct alps_model_info *model;
+ const struct alps_model_info *model;
if (!(model = alps_get_model(psmouse, &version)))
return -1;
diff --git a/drivers/input/mouse/alps.h b/drivers/input/mouse/alps.h
index e428f8d5d12e..69db7325a494 100644
--- a/drivers/input/mouse/alps.h
+++ b/drivers/input/mouse/alps.h
@@ -25,7 +25,7 @@ struct alps_data {
struct input_dev *dev2; /* Relative device */
char name[32]; /* Name */
char phys[32]; /* Phys */
- struct alps_model_info *i; /* Info */
+ const struct alps_model_info *i;/* Info */
int prev_fin; /* Finger bit from previous packet */
};
diff --git a/drivers/input/mouse/lifebook.c b/drivers/input/mouse/lifebook.c
index c14395ba7980..5e9d25067513 100644
--- a/drivers/input/mouse/lifebook.c
+++ b/drivers/input/mouse/lifebook.c
@@ -115,13 +115,15 @@ static int lifebook_absolute_mode(struct psmouse *psmouse)
static void lifebook_set_resolution(struct psmouse *psmouse, unsigned int resolution)
{
- unsigned char params[] = { 0, 1, 2, 2, 3 };
+ static const unsigned char params[] = { 0, 1, 2, 2, 3 };
+ unsigned char p;
if (resolution == 0 || resolution > 400)
resolution = 400;
- ps2_command(&psmouse->ps2dev, &params[resolution / 100], PSMOUSE_CMD_SETRES);
- psmouse->resolution = 50 << params[resolution / 100];
+ p = params[resolution / 100];
+ ps2_command(&psmouse->ps2dev, &p, PSMOUSE_CMD_SETRES);
+ psmouse->resolution = 50 << p;
}
static void lifebook_disconnect(struct psmouse *psmouse)
diff --git a/drivers/input/mouse/logips2pp.c b/drivers/input/mouse/logips2pp.c
index 54b696cfe1e3..7972eecbcfe4 100644
--- a/drivers/input/mouse/logips2pp.c
+++ b/drivers/input/mouse/logips2pp.c
@@ -30,9 +30,9 @@
#define PS2PP_NAV_BTN 0x20
struct ps2pp_info {
- const int model;
- unsigned const int kind;
- unsigned const int features;
+ u8 model;
+ u8 kind;
+ u16 features;
};
/*
@@ -199,9 +199,9 @@ static void ps2pp_disconnect(struct psmouse *psmouse)
device_remove_file(&psmouse->ps2dev.serio->dev, &psmouse_attr_smartscroll.dattr);
}
-static struct ps2pp_info *get_model_info(unsigned char model)
+static const struct ps2pp_info *get_model_info(unsigned char model)
{
- static struct ps2pp_info ps2pp_list[] = {
+ static const struct ps2pp_info ps2pp_list[] = {
{ 12, 0, PS2PP_SIDE_BTN},
{ 13, 0, 0 },
{ 15, PS2PP_KIND_MX, /* MX1000 */
@@ -215,6 +215,7 @@ static struct ps2pp_info *get_model_info(unsigned char model)
{ 51, 0, 0 },
{ 52, PS2PP_KIND_WHEEL, PS2PP_SIDE_BTN | PS2PP_WHEEL },
{ 53, PS2PP_KIND_WHEEL, PS2PP_WHEEL },
+ { 56, PS2PP_KIND_WHEEL, PS2PP_SIDE_BTN | PS2PP_WHEEL }, /* Cordless MouseMan Wheel */
{ 61, PS2PP_KIND_MX, /* MX700 */
PS2PP_WHEEL | PS2PP_SIDE_BTN | PS2PP_TASK_BTN |
PS2PP_EXTRA_BTN | PS2PP_NAV_BTN },
@@ -244,12 +245,11 @@ static struct ps2pp_info *get_model_info(unsigned char model)
PS2PP_EXTRA_BTN | PS2PP_NAV_BTN },
{ 114, PS2PP_KIND_MX, /* MX310 */
PS2PP_WHEEL | PS2PP_SIDE_BTN |
- PS2PP_TASK_BTN | PS2PP_EXTRA_BTN },
- { }
+ PS2PP_TASK_BTN | PS2PP_EXTRA_BTN }
};
int i;
- for (i = 0; ps2pp_list[i].model; i++)
+ for (i = 0; i < ARRAY_SIZE(ps2pp_list); i++)
if (model == ps2pp_list[i].model)
return &ps2pp_list[i];
@@ -261,7 +261,8 @@ static struct ps2pp_info *get_model_info(unsigned char model)
* Set up input device's properties based on the detected mouse model.
*/
-static void ps2pp_set_model_properties(struct psmouse *psmouse, struct ps2pp_info *model_info,
+static void ps2pp_set_model_properties(struct psmouse *psmouse,
+ const struct ps2pp_info *model_info,
int using_ps2pp)
{
struct input_dev *input_dev = psmouse->dev;
@@ -327,7 +328,7 @@ int ps2pp_init(struct psmouse *psmouse, int set_properties)
struct ps2dev *ps2dev = &psmouse->ps2dev;
unsigned char param[4];
unsigned char model, buttons;
- struct ps2pp_info *model_info;
+ const struct ps2pp_info *model_info;
int use_ps2pp = 0;
param[0] = 0;
@@ -349,7 +350,7 @@ int ps2pp_init(struct psmouse *psmouse, int set_properties)
/*
* Do Logitech PS2++ / PS2T++ magic init.
*/
- if (model == 97) { /* Touch Pad 3 */
+ if (model_info->kind == PS2PP_KIND_TP3) { /* Touch Pad 3 */
/* Unprotect RAM */
param[0] = 0x11; param[1] = 0x04; param[2] = 0x68;
diff --git a/drivers/input/mouse/psmouse-base.c b/drivers/input/mouse/psmouse-base.c
index 343afa38f4c2..9fb7eb6b0f71 100644
--- a/drivers/input/mouse/psmouse-base.c
+++ b/drivers/input/mouse/psmouse-base.c
@@ -112,8 +112,8 @@ static struct workqueue_struct *kpsmoused_wq;
struct psmouse_protocol {
enum psmouse_type type;
- char *name;
- char *alias;
+ const char *name;
+ const char *alias;
int maxproto;
int (*detect)(struct psmouse *, int);
int (*init)(struct psmouse *);
@@ -507,15 +507,17 @@ static int thinking_detect(struct psmouse *psmouse, int set_properties)
{
struct ps2dev *ps2dev = &psmouse->ps2dev;
unsigned char param[2];
- unsigned char seq[] = { 20, 60, 40, 20, 20, 60, 40, 20, 20, 0 };
+ static const unsigned char seq[] = { 20, 60, 40, 20, 20, 60, 40, 20, 20 };
int i;
param[0] = 10;
ps2_command(ps2dev, param, PSMOUSE_CMD_SETRATE);
param[0] = 0;
ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES);
- for (i = 0; seq[i]; i++)
- ps2_command(ps2dev, seq + i, PSMOUSE_CMD_SETRATE);
+ for (i = 0; i < ARRAY_SIZE(seq); i++) {
+ param[0] = seq[i];
+ ps2_command(ps2dev, param, PSMOUSE_CMD_SETRATE);
+ }
ps2_command(ps2dev, param, PSMOUSE_CMD_GETID);
if (param[0] != 2)
@@ -652,7 +654,7 @@ static int psmouse_extensions(struct psmouse *psmouse,
return PSMOUSE_PS2;
}
-static struct psmouse_protocol psmouse_protocols[] = {
+static const struct psmouse_protocol psmouse_protocols[] = {
{
.type = PSMOUSE_PS2,
.name = "PS/2",
@@ -726,7 +728,7 @@ static struct psmouse_protocol psmouse_protocols[] = {
},
};
-static struct psmouse_protocol *psmouse_protocol_by_type(enum psmouse_type type)
+static const struct psmouse_protocol *psmouse_protocol_by_type(enum psmouse_type type)
{
int i;
@@ -738,9 +740,9 @@ static struct psmouse_protocol *psmouse_protocol_by_type(enum psmouse_type type)
return &psmouse_protocols[0];
}
-static struct psmouse_protocol *psmouse_protocol_by_name(const char *name, size_t len)
+static const struct psmouse_protocol *psmouse_protocol_by_name(const char *name, size_t len)
{
- struct psmouse_protocol *p;
+ const struct psmouse_protocol *p;
int i;
for (i = 0; i < ARRAY_SIZE(psmouse_protocols); i++) {
@@ -795,13 +797,15 @@ static int psmouse_probe(struct psmouse *psmouse)
void psmouse_set_resolution(struct psmouse *psmouse, unsigned int resolution)
{
- unsigned char params[] = { 0, 1, 2, 2, 3 };
+ static const unsigned char params[] = { 0, 1, 2, 2, 3 };
+ unsigned char p;
if (resolution == 0 || resolution > 200)
resolution = 200;
- ps2_command(&psmouse->ps2dev, &params[resolution / 50], PSMOUSE_CMD_SETRES);
- psmouse->resolution = 25 << params[resolution / 50];
+ p = params[resolution / 50];
+ ps2_command(&psmouse->ps2dev, &p, PSMOUSE_CMD_SETRES);
+ psmouse->resolution = 25 << p;
}
/*
@@ -810,12 +814,14 @@ void psmouse_set_resolution(struct psmouse *psmouse, unsigned int resolution)
static void psmouse_set_rate(struct psmouse *psmouse, unsigned int rate)
{
- unsigned char rates[] = { 200, 100, 80, 60, 40, 20, 10, 0 };
+ static const unsigned char rates[] = { 200, 100, 80, 60, 40, 20, 10, 0 };
+ unsigned char r;
int i = 0;
while (rates[i] > rate) i++;
- ps2_command(&psmouse->ps2dev, &rates[i], PSMOUSE_CMD_SETRATE);
- psmouse->rate = rates[i];
+ r = rates[i];
+ ps2_command(&psmouse->ps2dev, &r, PSMOUSE_CMD_SETRATE);
+ psmouse->rate = r;
}
/*
@@ -1031,7 +1037,7 @@ static void psmouse_disconnect(struct serio *serio)
mutex_unlock(&psmouse_mutex);
}
-static int psmouse_switch_protocol(struct psmouse *psmouse, struct psmouse_protocol *proto)
+static int psmouse_switch_protocol(struct psmouse *psmouse, const struct psmouse_protocol *proto)
{
struct input_dev *input_dev = psmouse->dev;
@@ -1362,7 +1368,7 @@ static ssize_t psmouse_attr_set_protocol(struct psmouse *psmouse, void *data, co
struct serio *serio = psmouse->ps2dev.serio;
struct psmouse *parent = NULL;
struct input_dev *new_dev;
- struct psmouse_protocol *proto;
+ const struct psmouse_protocol *proto;
int retry = 0;
if (!(proto = psmouse_protocol_by_name(buf, count)))
@@ -1459,7 +1465,7 @@ static ssize_t psmouse_attr_set_resolution(struct psmouse *psmouse, void *data,
static int psmouse_set_maxproto(const char *val, struct kernel_param *kp)
{
- struct psmouse_protocol *proto;
+ const struct psmouse_protocol *proto;
if (!val)
return -EINVAL;
diff --git a/drivers/input/mouse/sermouse.c b/drivers/input/mouse/sermouse.c
index 0023501a5b63..680b32353884 100644
--- a/drivers/input/mouse/sermouse.c
+++ b/drivers/input/mouse/sermouse.c
@@ -42,7 +42,7 @@ MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>");
MODULE_DESCRIPTION(DRIVER_DESC);
MODULE_LICENSE("GPL");
-static char *sermouse_protocols[] = { "None", "Mouse Systems Mouse", "Sun Mouse", "Microsoft Mouse",
+static const char *sermouse_protocols[] = { "None", "Mouse Systems Mouse", "Sun Mouse", "Microsoft Mouse",
"Logitech M+ Mouse", "Microsoft MZ Mouse", "Logitech MZ+ Mouse",
"Logitech MZ++ Mouse"};
diff --git a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c
index ad5d0a85e960..392108c436ba 100644
--- a/drivers/input/mouse/synaptics.c
+++ b/drivers/input/mouse/synaptics.c
@@ -430,11 +430,11 @@ static void synaptics_process_packet(struct psmouse *psmouse)
static int synaptics_validate_byte(unsigned char packet[], int idx, unsigned char pkt_type)
{
- static unsigned char newabs_mask[] = { 0xC8, 0x00, 0x00, 0xC8, 0x00 };
- static unsigned char newabs_rel_mask[] = { 0xC0, 0x00, 0x00, 0xC0, 0x00 };
- static unsigned char newabs_rslt[] = { 0x80, 0x00, 0x00, 0xC0, 0x00 };
- static unsigned char oldabs_mask[] = { 0xC0, 0x60, 0x00, 0xC0, 0x60 };
- static unsigned char oldabs_rslt[] = { 0xC0, 0x00, 0x00, 0x80, 0x00 };
+ static const unsigned char newabs_mask[] = { 0xC8, 0x00, 0x00, 0xC8, 0x00 };
+ static const unsigned char newabs_rel_mask[] = { 0xC0, 0x00, 0x00, 0xC0, 0x00 };
+ static const unsigned char newabs_rslt[] = { 0x80, 0x00, 0x00, 0xC0, 0x00 };
+ static const unsigned char oldabs_mask[] = { 0xC0, 0x60, 0x00, 0xC0, 0x60 };
+ static const unsigned char oldabs_rslt[] = { 0xC0, 0x00, 0x00, 0x80, 0x00 };
if (idx < 0 || idx > 4)
return 0;
diff --git a/drivers/input/mousedev.c b/drivers/input/mousedev.c
index 1f851acab30d..a22a74a2a3dc 100644
--- a/drivers/input/mousedev.c
+++ b/drivers/input/mousedev.c
@@ -614,7 +614,7 @@ static unsigned int mousedev_poll(struct file *file, poll_table *wait)
(list->mousedev->exist ? 0 : (POLLHUP | POLLERR));
}
-static struct file_operations mousedev_fops = {
+static const struct file_operations mousedev_fops = {
.owner = THIS_MODULE,
.read = mousedev_read,
.write = mousedev_write,
@@ -624,7 +624,8 @@ static struct file_operations mousedev_fops = {
.fasync = mousedev_fasync,
};
-static struct input_handle *mousedev_connect(struct input_handler *handler, struct input_dev *dev, struct input_device_id *id)
+static struct input_handle *mousedev_connect(struct input_handler *handler, struct input_dev *dev,
+ const struct input_device_id *id)
{
struct mousedev *mousedev;
struct class_device *cdev;
@@ -688,7 +689,7 @@ static void mousedev_disconnect(struct input_handle *handle)
}
}
-static struct input_device_id mousedev_ids[] = {
+static const struct input_device_id mousedev_ids[] = {
{
.flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_KEYBIT | INPUT_DEVICE_ID_MATCH_RELBIT,
.evbit = { BIT(EV_KEY) | BIT(EV_REL) },
@@ -737,7 +738,12 @@ static int psaux_registered;
static int __init mousedev_init(void)
{
- input_register_handler(&mousedev_handler);
+ struct class_device *cdev;
+ int error;
+
+ error = input_register_handler(&mousedev_handler);
+ if (error)
+ return error;
memset(&mousedev_mix, 0, sizeof(struct mousedev));
INIT_LIST_HEAD(&mousedev_mix.list);
@@ -746,12 +752,20 @@ static int __init mousedev_init(void)
mousedev_mix.exist = 1;
mousedev_mix.minor = MOUSEDEV_MIX;
- class_device_create(&input_class, NULL,
+ cdev = class_device_create(&input_class, NULL,
MKDEV(INPUT_MAJOR, MOUSEDEV_MINOR_BASE + MOUSEDEV_MIX), NULL, "mice");
+ if (IS_ERR(cdev)) {
+ input_unregister_handler(&mousedev_handler);
+ return PTR_ERR(cdev);
+ }
#ifdef CONFIG_INPUT_MOUSEDEV_PSAUX
- if (!(psaux_registered = !misc_register(&psaux_mouse)))
- printk(KERN_WARNING "mice: could not misc_register the device\n");
+ error = misc_register(&psaux_mouse);
+ if (error)
+ printk(KERN_WARNING "mice: could not register psaux device, "
+ "error: %d\n", error);
+ else
+ psaux_registered = 1;
#endif
printk(KERN_INFO "mice: PS/2 mouse device common for all mice\n");
diff --git a/drivers/input/power.c b/drivers/input/power.c
index 51a519e24b6d..ee82464a2fa7 100644
--- a/drivers/input/power.c
+++ b/drivers/input/power.c
@@ -98,7 +98,7 @@ static void power_event(struct input_handle *handle, unsigned int type,
static struct input_handle *power_connect(struct input_handler *handler,
struct input_dev *dev,
- struct input_device_id *id)
+ const struct input_device_id *id)
{
struct input_handle *handle;
@@ -120,7 +120,7 @@ static void power_disconnect(struct input_handle *handle)
kfree(handle);
}
-static struct input_device_id power_ids[] = {
+static const struct input_device_id power_ids[] = {
{
.flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_KEYBIT,
.evbit = { BIT(EV_KEY) },
@@ -150,8 +150,7 @@ static struct input_handler power_handler = {
static int __init power_init(void)
{
- input_register_handler(&power_handler);
- return 0;
+ return input_register_handler(&power_handler);
}
static void __exit power_exit(void)
diff --git a/drivers/input/serio/i8042-io.h b/drivers/input/serio/i8042-io.h
index cc21914fbc72..3b4e13b9ce1b 100644
--- a/drivers/input/serio/i8042-io.h
+++ b/drivers/input/serio/i8042-io.h
@@ -67,25 +67,22 @@ static inline int i8042_platform_init(void)
* On some platforms touching the i8042 data register region can do really
* bad things. Because of this the region is always reserved on such boxes.
*/
-#if !defined(__sh__) && !defined(__alpha__) && !defined(__mips__) && !defined(CONFIG_PPC_MERGE)
- if (!request_region(I8042_DATA_REG, 16, "i8042"))
- return -EBUSY;
-#endif
-
- i8042_reset = 1;
-
#if defined(CONFIG_PPC_MERGE)
if (check_legacy_ioport(I8042_DATA_REG))
- return -EBUSY;
+ return -ENODEV;
+#endif
+#if !defined(__sh__) && !defined(__alpha__) && !defined(__mips__)
if (!request_region(I8042_DATA_REG, 16, "i8042"))
return -EBUSY;
#endif
+
+ i8042_reset = 1;
return 0;
}
static inline void i8042_platform_exit(void)
{
-#if !defined(__sh__) && !defined(__alpha__) && !defined(CONFIG_PPC64)
+#if !defined(__sh__) && !defined(__alpha__)
release_region(I8042_DATA_REG, 16);
#endif
}
diff --git a/drivers/input/serio/i8042-x86ia64io.h b/drivers/input/serio/i8042-x86ia64io.h
index f606e96bc2f4..8738edda6610 100644
--- a/drivers/input/serio/i8042-x86ia64io.h
+++ b/drivers/input/serio/i8042-x86ia64io.h
@@ -160,6 +160,13 @@ static struct dmi_system_id __initdata i8042_dmi_nomux_table[] = {
},
},
{
+ .ident = "Toshiba Equium A110",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "EQUIUM A110"),
+ },
+ },
+ {
.ident = "Alienware Sentia",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "ALIENWARE"),
@@ -180,6 +187,13 @@ static struct dmi_system_id __initdata i8042_dmi_nomux_table[] = {
DMI_MATCH(DMI_PRODUCT_NAME, "VGN-FS115B"),
},
},
+ {
+ .ident = "Amoi M636/A737",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Amoi Electronics CO.,LTD."),
+ DMI_MATCH(DMI_PRODUCT_NAME, "M636/A737 platform"),
+ },
+ },
{ }
};
diff --git a/drivers/input/serio/i8042.c b/drivers/input/serio/i8042.c
index 06a3f25657dd..1bb0c76a9259 100644
--- a/drivers/input/serio/i8042.c
+++ b/drivers/input/serio/i8042.c
@@ -90,46 +90,24 @@ static DEFINE_SPINLOCK(i8042_lock);
struct i8042_port {
struct serio *serio;
int irq;
- unsigned char disable;
- unsigned char irqen;
unsigned char exists;
signed char mux;
- char name[8];
};
#define I8042_KBD_PORT_NO 0
#define I8042_AUX_PORT_NO 1
#define I8042_MUX_PORT_NO 2
#define I8042_NUM_PORTS (I8042_NUM_MUX_PORTS + 2)
-static struct i8042_port i8042_ports[I8042_NUM_PORTS] = {
- {
- .disable = I8042_CTR_KBDDIS,
- .irqen = I8042_CTR_KBDINT,
- .mux = -1,
- .name = "KBD",
- },
- {
- .disable = I8042_CTR_AUXDIS,
- .irqen = I8042_CTR_AUXINT,
- .mux = -1,
- .name = "AUX",
- }
-};
+
+static struct i8042_port i8042_ports[I8042_NUM_PORTS];
static unsigned char i8042_initial_ctr;
static unsigned char i8042_ctr;
-static unsigned char i8042_mux_open;
static unsigned char i8042_mux_present;
-static struct timer_list i8042_timer;
+static unsigned char i8042_kbd_irq_registered;
+static unsigned char i8042_aux_irq_registered;
static struct platform_device *i8042_platform_device;
-
-/*
- * Shared IRQ's require a device pointer, but this driver doesn't support
- * multiple devices
- */
-#define i8042_request_irq_cookie (&i8042_timer)
-
static irqreturn_t i8042_interrupt(int irq, void *dev_id, struct pt_regs *regs);
/*
@@ -141,6 +119,7 @@ static irqreturn_t i8042_interrupt(int irq, void *dev_id, struct pt_regs *regs);
static int i8042_wait_read(void)
{
int i = 0;
+
while ((~i8042_read_status() & I8042_STR_OBF) && (i < I8042_CTL_TIMEOUT)) {
udelay(50);
i++;
@@ -151,6 +130,7 @@ static int i8042_wait_read(void)
static int i8042_wait_write(void)
{
int i = 0;
+
while ((i8042_read_status() & I8042_STR_IBF) && (i < I8042_CTL_TIMEOUT)) {
udelay(50);
i++;
@@ -192,48 +172,57 @@ static int i8042_flush(void)
* encoded in bits 8-11 of the command number.
*/
-static int i8042_command(unsigned char *param, int command)
+static int __i8042_command(unsigned char *param, int command)
{
- unsigned long flags;
- int i, retval, auxerr = 0;
+ int i, error;
if (i8042_noloop && command == I8042_CMD_AUX_LOOP)
return -1;
- spin_lock_irqsave(&i8042_lock, flags);
-
- if ((retval = i8042_wait_write()))
- goto out;
+ error = i8042_wait_write();
+ if (error)
+ return error;
dbg("%02x -> i8042 (command)", command & 0xff);
i8042_write_command(command & 0xff);
for (i = 0; i < ((command >> 12) & 0xf); i++) {
- if ((retval = i8042_wait_write()))
- goto out;
+ error = i8042_wait_write();
+ if (error)
+ return error;
dbg("%02x -> i8042 (parameter)", param[i]);
i8042_write_data(param[i]);
}
for (i = 0; i < ((command >> 8) & 0xf); i++) {
- if ((retval = i8042_wait_read()))
- goto out;
+ error = i8042_wait_read();
+ if (error) {
+ dbg(" -- i8042 (timeout)");
+ return error;
+ }
if (command == I8042_CMD_AUX_LOOP &&
!(i8042_read_status() & I8042_STR_AUXDATA)) {
- retval = auxerr = -1;
- goto out;
+ dbg(" -- i8042 (auxerr)");
+ return -1;
}
param[i] = i8042_read_data();
dbg("%02x <- i8042 (return)", param[i]);
}
- if (retval)
- dbg(" -- i8042 (%s)", auxerr ? "auxerr" : "timeout");
+ return 0;
+}
- out:
+static int i8042_command(unsigned char *param, int command)
+{
+ unsigned long flags;
+ int retval;
+
+ spin_lock_irqsave(&i8042_lock, flags);
+ retval = __i8042_command(param, command);
spin_unlock_irqrestore(&i8042_lock, flags);
+
return retval;
}
@@ -248,7 +237,7 @@ static int i8042_kbd_write(struct serio *port, unsigned char c)
spin_lock_irqsave(&i8042_lock, flags);
- if(!(retval = i8042_wait_write())) {
+ if (!(retval = i8042_wait_write())) {
dbg("%02x -> i8042 (kbd-data)", c);
i8042_write_data(c);
}
@@ -287,100 +276,6 @@ static int i8042_aux_write(struct serio *serio, unsigned char c)
}
/*
- * i8042_activate_port() enables port on a chip.
- */
-
-static int i8042_activate_port(struct i8042_port *port)
-{
- if (!port->serio)
- return -1;
-
- i8042_flush();
-
- /*
- * Enable port again here because it is disabled if we are
- * resuming (normally it is enabled already).
- */
- i8042_ctr &= ~port->disable;
-
- i8042_ctr |= port->irqen;
-
- if (i8042_command(&i8042_ctr, I8042_CMD_CTL_WCTR)) {
- i8042_ctr &= ~port->irqen;
- return -1;
- }
-
- return 0;
-}
-
-
-/*
- * i8042_open() is called when a port is open by the higher layer.
- * It allocates the interrupt and calls i8042_enable_port.
- */
-
-static int i8042_open(struct serio *serio)
-{
- struct i8042_port *port = serio->port_data;
-
- if (port->mux != -1)
- if (i8042_mux_open++)
- return 0;
-
- if (request_irq(port->irq, i8042_interrupt,
- IRQF_SHARED, "i8042", i8042_request_irq_cookie)) {
- printk(KERN_ERR "i8042.c: Can't get irq %d for %s, unregistering the port.\n", port->irq, port->name);
- goto irq_fail;
- }
-
- if (i8042_activate_port(port)) {
- printk(KERN_ERR "i8042.c: Can't activate %s, unregistering the port\n", port->name);
- goto activate_fail;
- }
-
- i8042_interrupt(0, NULL, NULL);
-
- return 0;
-
- activate_fail:
- free_irq(port->irq, i8042_request_irq_cookie);
-
- irq_fail:
- serio_unregister_port_delayed(serio);
-
- return -1;
-}
-
-/*
- * i8042_close() frees the interrupt, so that it can possibly be used
- * by another driver. We never know - if the user doesn't have a mouse,
- * the BIOS could have used the AUX interrupt for PCI.
- */
-
-static void i8042_close(struct serio *serio)
-{
- struct i8042_port *port = serio->port_data;
-
- if (port->mux != -1)
- if (--i8042_mux_open)
- return;
-
- i8042_ctr &= ~port->irqen;
-
- if (i8042_command(&i8042_ctr, I8042_CMD_CTL_WCTR)) {
- printk(KERN_WARNING "i8042.c: Can't write CTR while closing %s.\n", port->name);
-/*
- * We still want to continue and free IRQ so if more data keeps coming in
- * kernel will just ignore the irq.
- */
- }
-
- free_irq(port->irq, i8042_request_irq_cookie);
-
- i8042_flush();
-}
-
-/*
* i8042_start() is called by serio core when port is about to finish
* registering. It will mark port as existing so i8042_interrupt can
* start sending data through it.
@@ -423,8 +318,6 @@ static irqreturn_t i8042_interrupt(int irq, void *dev_id, struct pt_regs *regs)
unsigned int port_no;
int ret;
- mod_timer(&i8042_timer, jiffies + I8042_POLL_PERIOD);
-
spin_lock_irqsave(&i8042_lock, flags);
str = i8042_read_status();
if (unlikely(~str & I8042_STR_OBF)) {
@@ -480,8 +373,8 @@ static irqreturn_t i8042_interrupt(int irq, void *dev_id, struct pt_regs *regs)
port = &i8042_ports[port_no];
- dbg("%02x <- i8042 (interrupt, %s, %d%s%s)",
- data, port->name, irq,
+ dbg("%02x <- i8042 (interrupt, %d, %d%s%s)",
+ data, port_no, irq,
dfl & SERIO_PARITY ? ", bad parity" : "",
dfl & SERIO_TIMEOUT ? ", timeout" : "");
@@ -494,6 +387,58 @@ static irqreturn_t i8042_interrupt(int irq, void *dev_id, struct pt_regs *regs)
}
/*
+ * i8042_enable_kbd_port enables keybaord port on chip
+ */
+
+static int i8042_enable_kbd_port(void)
+{
+ i8042_ctr &= ~I8042_CTR_KBDDIS;
+ i8042_ctr |= I8042_CTR_KBDINT;
+
+ if (i8042_command(&i8042_ctr, I8042_CMD_CTL_WCTR)) {
+ printk(KERN_ERR "i8042.c: Failed to enable KBD port.\n");
+ return -EIO;
+ }
+
+ return 0;
+}
+
+/*
+ * i8042_enable_aux_port enables AUX (mouse) port on chip
+ */
+
+static int i8042_enable_aux_port(void)
+{
+ i8042_ctr &= ~I8042_CTR_AUXDIS;
+ i8042_ctr |= I8042_CTR_AUXINT;
+
+ if (i8042_command(&i8042_ctr, I8042_CMD_CTL_WCTR)) {
+ printk(KERN_ERR "i8042.c: Failed to enable AUX port.\n");
+ return -EIO;
+ }
+
+ return 0;
+}
+
+/*
+ * i8042_enable_mux_ports enables 4 individual AUX ports after
+ * the controller has been switched into Multiplexed mode
+ */
+
+static int i8042_enable_mux_ports(void)
+{
+ unsigned char param;
+ int i;
+
+ for (i = 0; i < I8042_NUM_MUX_PORTS; i++) {
+ i8042_command(&param, I8042_CMD_MUX_PFX + i);
+ i8042_command(&param, I8042_CMD_AUX_ENABLE);
+ }
+
+ return i8042_enable_aux_port();
+}
+
+/*
* i8042_set_mux_mode checks whether the controller has an active
* multiplexor and puts the chip into Multiplexed (1) or Legacy (0) mode.
*/
@@ -510,8 +455,7 @@ static int i8042_set_mux_mode(unsigned int mode, unsigned char *mux_version)
/*
* Internal loopback test - send three bytes, they should come back from the
- * mouse interface, the last should be version. Note that we negate mouseport
- * command responses for the i8042_check_aux() routine.
+ * mouse interface, the last should be version.
*/
param = 0xf0;
@@ -530,67 +474,67 @@ static int i8042_set_mux_mode(unsigned int mode, unsigned char *mux_version)
return 0;
}
-
/*
- * i8042_enable_mux_ports enables 4 individual AUX ports after
- * the controller has been switched into Multiplexed mode
+ * i8042_check_mux() checks whether the controller supports the PS/2 Active
+ * Multiplexing specification by Synaptics, Phoenix, Insyde and
+ * LCS/Telegraphics.
*/
-static int i8042_enable_mux_ports(void)
+static int __devinit i8042_check_mux(void)
{
- unsigned char param;
- int i;
+ unsigned char mux_version;
+
+ if (i8042_set_mux_mode(1, &mux_version))
+ return -1;
+
/*
- * Disable all muxed ports by disabling AUX.
+ * Workaround for interference with USB Legacy emulation
+ * that causes a v10.12 MUX to be found.
*/
+ if (mux_version == 0xAC)
+ return -1;
+
+ printk(KERN_INFO "i8042.c: Detected active multiplexing controller, rev %d.%d.\n",
+ (mux_version >> 4) & 0xf, mux_version & 0xf);
+/*
+ * Disable all muxed ports by disabling AUX.
+ */
i8042_ctr |= I8042_CTR_AUXDIS;
i8042_ctr &= ~I8042_CTR_AUXINT;
if (i8042_command(&i8042_ctr, I8042_CMD_CTL_WCTR)) {
printk(KERN_ERR "i8042.c: Failed to disable AUX port, can't use MUX.\n");
- return -1;
+ return -EIO;
}
-/*
- * Enable all muxed ports.
- */
-
- for (i = 0; i < I8042_NUM_MUX_PORTS; i++) {
- i8042_command(&param, I8042_CMD_MUX_PFX + i);
- i8042_command(&param, I8042_CMD_AUX_ENABLE);
- }
+ i8042_mux_present = 1;
return 0;
}
-
/*
- * i8042_check_mux() checks whether the controller supports the PS/2 Active
- * Multiplexing specification by Synaptics, Phoenix, Insyde and
- * LCS/Telegraphics.
+ * The following is used to test AUX IRQ delivery.
*/
+static struct completion i8042_aux_irq_delivered __devinitdata;
+static int i8042_irq_being_tested __devinitdata;
-static int __devinit i8042_check_mux(void)
+static irqreturn_t __devinit i8042_aux_test_irq(int irq, void *dev_id, struct pt_regs *regs)
{
- unsigned char mux_version;
-
- if (i8042_set_mux_mode(1, &mux_version))
- return -1;
-
- /* Workaround for interference with USB Legacy emulation */
- /* that causes a v10.12 MUX to be found. */
- if (mux_version == 0xAC)
- return -1;
-
- printk(KERN_INFO "i8042.c: Detected active multiplexing controller, rev %d.%d.\n",
- (mux_version >> 4) & 0xf, mux_version & 0xf);
+ unsigned long flags;
+ unsigned char str, data;
- if (i8042_enable_mux_ports())
- return -1;
+ spin_lock_irqsave(&i8042_lock, flags);
+ str = i8042_read_status();
+ if (str & I8042_STR_OBF) {
+ data = i8042_read_data();
+ if (i8042_irq_being_tested &&
+ data == 0xa5 && (str & I8042_STR_AUXDATA))
+ complete(&i8042_aux_irq_delivered);
+ }
+ spin_unlock_irqrestore(&i8042_lock, flags);
- i8042_mux_present = 1;
- return 0;
+ return IRQ_HANDLED;
}
@@ -601,18 +545,10 @@ static int __devinit i8042_check_mux(void)
static int __devinit i8042_check_aux(void)
{
+ int retval = -1;
+ int irq_registered = 0;
+ unsigned long flags;
unsigned char param;
- static int i8042_check_aux_cookie;
-
-/*
- * Check if AUX irq is available. If it isn't, then there is no point
- * in trying to detect AUX presence.
- */
-
- if (request_irq(i8042_ports[I8042_AUX_PORT_NO].irq, i8042_interrupt,
- IRQF_SHARED, "i8042", &i8042_check_aux_cookie))
- return -1;
- free_irq(i8042_ports[I8042_AUX_PORT_NO].irq, &i8042_check_aux_cookie);
/*
* Get rid of bytes in the queue.
@@ -637,9 +573,9 @@ static int __devinit i8042_check_aux(void)
* AUX ports, we test for this only when the LOOP command failed.
*/
- if (i8042_command(&param, I8042_CMD_AUX_TEST)
- || (param && param != 0xfa && param != 0xff))
- return -1;
+ if (i8042_command(&param, I8042_CMD_AUX_TEST) ||
+ (param && param != 0xfa && param != 0xff))
+ return -1;
}
/*
@@ -659,54 +595,80 @@ static int __devinit i8042_check_aux(void)
return -1;
/*
- * Disable the interface.
+ * Test AUX IRQ delivery to make sure BIOS did not grab the IRQ and
+ * used it for a PCI card or somethig else.
*/
- i8042_ctr |= I8042_CTR_AUXDIS;
- i8042_ctr &= ~I8042_CTR_AUXINT;
+ if (i8042_noloop) {
+/*
+ * Without LOOP command we can't test AUX IRQ delivery. Assume the port
+ * is working and hope we are right.
+ */
+ retval = 0;
+ goto out;
+ }
- if (i8042_command(&i8042_ctr, I8042_CMD_CTL_WCTR))
- return -1;
+ if (request_irq(I8042_AUX_IRQ, i8042_aux_test_irq, IRQF_SHARED,
+ "i8042", i8042_platform_device))
+ goto out;
- return 0;
-}
+ irq_registered = 1;
+
+ if (i8042_enable_aux_port())
+ goto out;
+
+ spin_lock_irqsave(&i8042_lock, flags);
+ init_completion(&i8042_aux_irq_delivered);
+ i8042_irq_being_tested = 1;
+
+ param = 0xa5;
+ retval = __i8042_command(&param, I8042_CMD_AUX_LOOP & 0xf0ff);
+
+ spin_unlock_irqrestore(&i8042_lock, flags);
+
+ if (retval)
+ goto out;
+ if (wait_for_completion_timeout(&i8042_aux_irq_delivered,
+ msecs_to_jiffies(250)) == 0) {
/*
- * i8042_port_register() marks the device as existing,
- * registers it, and reports to the user.
+ * AUX IRQ was never delivered so we need to flush the controller to
+ * get rid of the byte we put there; otherwise keyboard may not work.
*/
+ i8042_flush();
+ retval = -1;
+ }
-static int __devinit i8042_port_register(struct i8042_port *port)
-{
- i8042_ctr &= ~port->disable;
+ out:
- if (i8042_command(&i8042_ctr, I8042_CMD_CTL_WCTR)) {
- printk(KERN_WARNING "i8042.c: Can't write CTR while registering.\n");
- kfree(port->serio);
- port->serio = NULL;
- i8042_ctr |= port->disable;
- return -EIO;
- }
+/*
+ * Disable the interface.
+ */
- printk(KERN_INFO "serio: i8042 %s port at %#lx,%#lx irq %d\n",
- port->name,
- (unsigned long) I8042_DATA_REG,
- (unsigned long) I8042_COMMAND_REG,
- port->irq);
+ i8042_ctr |= I8042_CTR_AUXDIS;
+ i8042_ctr &= ~I8042_CTR_AUXINT;
- serio_register_port(port->serio);
+ if (i8042_command(&i8042_ctr, I8042_CMD_CTL_WCTR))
+ retval = -1;
- return 0;
-}
+ if (irq_registered)
+ free_irq(I8042_AUX_IRQ, i8042_platform_device);
+ return retval;
+}
-static void i8042_timer_func(unsigned long data)
+static int i8042_controller_check(void)
{
- i8042_interrupt(0, NULL, NULL);
+ if (i8042_flush() == I8042_BUFFER_SIZE) {
+ printk(KERN_ERR "i8042.c: No controller found.\n");
+ return -ENODEV;
+ }
+
+ return 0;
}
-static int i8042_ctl_test(void)
+static int i8042_controller_selftest(void)
{
unsigned char param;
@@ -715,13 +677,13 @@ static int i8042_ctl_test(void)
if (i8042_command(&param, I8042_CMD_CTL_TEST)) {
printk(KERN_ERR "i8042.c: i8042 controller self test timeout.\n");
- return -1;
+ return -ENODEV;
}
if (param != I8042_RET_CTL_TEST) {
printk(KERN_ERR "i8042.c: i8042 controller selftest failed. (%#x != %#x)\n",
param, I8042_RET_CTL_TEST);
- return -1;
+ return -EIO;
}
return 0;
@@ -738,25 +700,12 @@ static int i8042_controller_init(void)
unsigned long flags;
/*
- * Test the i8042. We need to know if it thinks it's working correctly
- * before doing anything else.
- */
-
- if (i8042_flush() == I8042_BUFFER_SIZE) {
- printk(KERN_ERR "i8042.c: No controller found.\n");
- return -1;
- }
-
- if (i8042_ctl_test())
- return -1;
-
-/*
* Save the CTR for restoral on unload / reboot.
*/
if (i8042_command(&i8042_ctr, I8042_CMD_CTL_RCTR)) {
printk(KERN_ERR "i8042.c: Can't read CTR while initializing i8042.\n");
- return -1;
+ return -EIO;
}
i8042_initial_ctr = i8042_ctr;
@@ -805,7 +754,7 @@ static int i8042_controller_init(void)
if (i8042_command(&i8042_ctr, I8042_CMD_CTL_WCTR)) {
printk(KERN_ERR "i8042.c: Can't write CTR while initializing i8042.\n");
- return -1;
+ return -EIO;
}
return 0;
@@ -813,15 +762,12 @@ static int i8042_controller_init(void)
/*
- * Reset the controller.
+ * Reset the controller and reset CRT to the original value set by BIOS.
*/
+
static void i8042_controller_reset(void)
{
-/*
- * Reset the controller if requested.
- */
-
- i8042_ctl_test();
+ i8042_flush();
/*
* Disable MUX mode if present.
@@ -831,12 +777,16 @@ static void i8042_controller_reset(void)
i8042_set_mux_mode(0, NULL);
/*
- * Restore the original control register setting.
+ * Reset the controller if requested.
*/
- i8042_ctr = i8042_initial_ctr;
+ i8042_controller_selftest();
- if (i8042_command(&i8042_ctr, I8042_CMD_CTL_WCTR))
+/*
+ * Restore the original control register setting.
+ */
+
+ if (i8042_command(&i8042_initial_ctr, I8042_CMD_CTL_WCTR))
printk(KERN_WARNING "i8042.c: Can't restore CTR.\n");
}
@@ -850,14 +800,12 @@ static void i8042_controller_cleanup(void)
{
int i;
- i8042_flush();
-
/*
* Reset anything that is connected to the ports.
*/
for (i = 0; i < I8042_NUM_PORTS; i++)
- if (i8042_ports[i].exists)
+ if (i8042_ports[i].serio)
serio_cleanup(i8042_ports[i].serio);
i8042_controller_reset();
@@ -913,8 +861,7 @@ static long i8042_panic_blink(long count)
static int i8042_suspend(struct platform_device *dev, pm_message_t state)
{
- del_timer_sync(&i8042_timer);
- i8042_controller_reset();
+ i8042_controller_cleanup();
return 0;
}
@@ -926,33 +873,39 @@ static int i8042_suspend(struct platform_device *dev, pm_message_t state)
static int i8042_resume(struct platform_device *dev)
{
- int i;
+ int error;
- if (i8042_ctl_test())
- return -1;
+ error = i8042_controller_check();
+ if (error)
+ return error;
- if (i8042_command(&i8042_ctr, I8042_CMD_CTL_WCTR)) {
- printk(KERN_ERR "i8042: Can't write CTR\n");
- return -1;
- }
-
- if (i8042_mux_present)
- if (i8042_set_mux_mode(1, NULL) || i8042_enable_mux_ports())
- printk(KERN_WARNING "i8042: failed to resume active multiplexor, mouse won't work.\n");
+ error = i8042_controller_selftest();
+ if (error)
+ return error;
/*
- * Activate all ports.
+ * Restore pre-resume CTR value and disable all ports
*/
- for (i = 0; i < I8042_NUM_PORTS; i++)
- i8042_activate_port(&i8042_ports[i]);
+ i8042_ctr |= I8042_CTR_AUXDIS | I8042_CTR_KBDDIS;
+ i8042_ctr &= ~(I8042_CTR_AUXINT | I8042_CTR_KBDINT);
+ if (i8042_command(&i8042_ctr, I8042_CMD_CTL_WCTR)) {
+ printk(KERN_ERR "i8042: Can't write CTR to resume\n");
+ return -EIO;
+ }
-/*
- * Restart timer (for polling "stuck" data)
- */
- mod_timer(&i8042_timer, jiffies + I8042_POLL_PERIOD);
+ if (i8042_mux_present) {
+ if (i8042_set_mux_mode(1, NULL) || i8042_enable_mux_ports())
+ printk(KERN_WARNING
+ "i8042: failed to resume active multiplexor, "
+ "mouse won't work.\n");
+ } else if (i8042_ports[I8042_AUX_PORT_NO].serio)
+ i8042_enable_aux_port();
- panic_blink = i8042_panic_blink;
+ if (i8042_ports[I8042_KBD_PORT_NO].serio)
+ i8042_enable_kbd_port();
+
+ i8042_interrupt(0, NULL, NULL);
return 0;
}
@@ -978,24 +931,24 @@ static int __devinit i8042_create_kbd_port(void)
serio->id.type = i8042_direct ? SERIO_8042 : SERIO_8042_XL;
serio->write = i8042_dumbkbd ? NULL : i8042_kbd_write;
- serio->open = i8042_open;
- serio->close = i8042_close;
serio->start = i8042_start;
serio->stop = i8042_stop;
serio->port_data = port;
serio->dev.parent = &i8042_platform_device->dev;
- strlcpy(serio->name, "i8042 Kbd Port", sizeof(serio->name));
+ strlcpy(serio->name, "i8042 KBD port", sizeof(serio->name));
strlcpy(serio->phys, I8042_KBD_PHYS_DESC, sizeof(serio->phys));
port->serio = serio;
+ port->irq = I8042_KBD_IRQ;
- return i8042_port_register(port);
+ return 0;
}
-static int __devinit i8042_create_aux_port(void)
+static int __devinit i8042_create_aux_port(int idx)
{
struct serio *serio;
- struct i8042_port *port = &i8042_ports[I8042_AUX_PORT_NO];
+ int port_no = idx < 0 ? I8042_AUX_PORT_NO : I8042_MUX_PORT_NO + idx;
+ struct i8042_port *port = &i8042_ports[port_no];
serio = kzalloc(sizeof(struct serio), GFP_KERNEL);
if (!serio)
@@ -1003,111 +956,191 @@ static int __devinit i8042_create_aux_port(void)
serio->id.type = SERIO_8042;
serio->write = i8042_aux_write;
- serio->open = i8042_open;
- serio->close = i8042_close;
serio->start = i8042_start;
serio->stop = i8042_stop;
serio->port_data = port;
serio->dev.parent = &i8042_platform_device->dev;
- strlcpy(serio->name, "i8042 Aux Port", sizeof(serio->name));
- strlcpy(serio->phys, I8042_AUX_PHYS_DESC, sizeof(serio->phys));
+ if (idx < 0) {
+ strlcpy(serio->name, "i8042 AUX port", sizeof(serio->name));
+ strlcpy(serio->phys, I8042_AUX_PHYS_DESC, sizeof(serio->phys));
+ } else {
+ snprintf(serio->name, sizeof(serio->name), "i8042 AUX%d port", idx);
+ snprintf(serio->phys, sizeof(serio->phys), I8042_MUX_PHYS_DESC, idx + 1);
+ }
port->serio = serio;
+ port->mux = idx;
+ port->irq = I8042_AUX_IRQ;
- return i8042_port_register(port);
+ return 0;
}
-static int __devinit i8042_create_mux_port(int index)
+static void __devinit i8042_free_kbd_port(void)
{
- struct serio *serio;
- struct i8042_port *port = &i8042_ports[I8042_MUX_PORT_NO + index];
+ kfree(i8042_ports[I8042_KBD_PORT_NO].serio);
+ i8042_ports[I8042_KBD_PORT_NO].serio = NULL;
+}
- serio = kzalloc(sizeof(struct serio), GFP_KERNEL);
- if (!serio)
- return -ENOMEM;
+static void __devinit i8042_free_aux_ports(void)
+{
+ int i;
- serio->id.type = SERIO_8042;
- serio->write = i8042_aux_write;
- serio->open = i8042_open;
- serio->close = i8042_close;
- serio->start = i8042_start;
- serio->stop = i8042_stop;
- serio->port_data = port;
- serio->dev.parent = &i8042_platform_device->dev;
- snprintf(serio->name, sizeof(serio->name), "i8042 Aux-%d Port", index);
- snprintf(serio->phys, sizeof(serio->phys), I8042_MUX_PHYS_DESC, index + 1);
+ for (i = I8042_AUX_PORT_NO; i < I8042_NUM_PORTS; i++) {
+ kfree(i8042_ports[i].serio);
+ i8042_ports[i].serio = NULL;
+ }
+}
- *port = i8042_ports[I8042_AUX_PORT_NO];
- port->exists = 0;
- snprintf(port->name, sizeof(port->name), "AUX%d", index);
- port->mux = index;
- port->serio = serio;
+static void __devinit i8042_register_ports(void)
+{
+ int i;
- return i8042_port_register(port);
+ for (i = 0; i < I8042_NUM_PORTS; i++) {
+ if (i8042_ports[i].serio) {
+ printk(KERN_INFO "serio: %s at %#lx,%#lx irq %d\n",
+ i8042_ports[i].serio->name,
+ (unsigned long) I8042_DATA_REG,
+ (unsigned long) I8042_COMMAND_REG,
+ i8042_ports[i].irq);
+ serio_register_port(i8042_ports[i].serio);
+ }
+ }
}
-static int __devinit i8042_probe(struct platform_device *dev)
+static void __devinit i8042_unregister_ports(void)
{
- int i, have_ports = 0;
- int err;
+ int i;
- init_timer(&i8042_timer);
- i8042_timer.function = i8042_timer_func;
+ for (i = 0; i < I8042_NUM_PORTS; i++) {
+ if (i8042_ports[i].serio) {
+ serio_unregister_port(i8042_ports[i].serio);
+ i8042_ports[i].serio = NULL;
+ }
+ }
+}
+
+static void i8042_free_irqs(void)
+{
+ if (i8042_aux_irq_registered)
+ free_irq(I8042_AUX_IRQ, i8042_platform_device);
+ if (i8042_kbd_irq_registered)
+ free_irq(I8042_KBD_IRQ, i8042_platform_device);
+
+ i8042_aux_irq_registered = i8042_kbd_irq_registered = 0;
+}
+
+static int __devinit i8042_setup_aux(void)
+{
+ int (*aux_enable)(void);
+ int error;
+ int i;
- if (i8042_controller_init())
+ if (i8042_check_aux())
return -ENODEV;
- if (!i8042_noaux && !i8042_check_aux()) {
- if (!i8042_nomux && !i8042_check_mux()) {
- for (i = 0; i < I8042_NUM_MUX_PORTS; i++) {
- err = i8042_create_mux_port(i);
- if (err)
- goto err_unregister_ports;
- }
- } else {
- err = i8042_create_aux_port();
- if (err)
- goto err_unregister_ports;
+ if (i8042_nomux || i8042_check_mux()) {
+ error = i8042_create_aux_port(-1);
+ if (error)
+ goto err_free_ports;
+ aux_enable = i8042_enable_aux_port;
+ } else {
+ for (i = 0; i < I8042_NUM_MUX_PORTS; i++) {
+ error = i8042_create_aux_port(i);
+ if (error)
+ goto err_free_ports;
}
- have_ports = 1;
+ aux_enable = i8042_enable_mux_ports;
}
- if (!i8042_nokbd) {
- err = i8042_create_kbd_port();
- if (err)
- goto err_unregister_ports;
- have_ports = 1;
- }
+ error = request_irq(I8042_AUX_IRQ, i8042_interrupt, IRQF_SHARED,
+ "i8042", i8042_platform_device);
+ if (error)
+ goto err_free_ports;
- if (!have_ports) {
- err = -ENODEV;
- goto err_controller_cleanup;
- }
+ if (aux_enable())
+ goto err_free_irq;
- mod_timer(&i8042_timer, jiffies + I8042_POLL_PERIOD);
+ i8042_aux_irq_registered = 1;
return 0;
- err_unregister_ports:
- for (i = 0; i < I8042_NUM_PORTS; i++)
- if (i8042_ports[i].serio)
- serio_unregister_port(i8042_ports[i].serio);
- err_controller_cleanup:
- i8042_controller_cleanup();
+ err_free_irq:
+ free_irq(I8042_AUX_IRQ, i8042_platform_device);
+ err_free_ports:
+ i8042_free_aux_ports();
+ return error;
+}
- return err;
+static int __devinit i8042_setup_kbd(void)
+{
+ int error;
+
+ error = i8042_create_kbd_port();
+ if (error)
+ return error;
+
+ error = request_irq(I8042_KBD_IRQ, i8042_interrupt, IRQF_SHARED,
+ "i8042", i8042_platform_device);
+ if (error)
+ goto err_free_port;
+
+ error = i8042_enable_kbd_port();
+ if (error)
+ goto err_free_irq;
+
+ i8042_kbd_irq_registered = 1;
+ return 0;
+
+ err_free_irq:
+ free_irq(I8042_KBD_IRQ, i8042_platform_device);
+ err_free_port:
+ i8042_free_kbd_port();
+ return error;
}
-static int __devexit i8042_remove(struct platform_device *dev)
+static int __devinit i8042_probe(struct platform_device *dev)
{
- int i;
+ int error;
- i8042_controller_cleanup();
+ error = i8042_controller_selftest();
+ if (error)
+ return error;
- for (i = 0; i < I8042_NUM_PORTS; i++)
- if (i8042_ports[i].exists)
- serio_unregister_port(i8042_ports[i].serio);
+ error = i8042_controller_init();
+ if (error)
+ return error;
+
+ if (!i8042_noaux) {
+ error = i8042_setup_aux();
+ if (error && error != -ENODEV && error != -EBUSY)
+ goto out_fail;
+ }
+
+ if (!i8042_nokbd) {
+ error = i8042_setup_kbd();
+ if (error)
+ goto out_fail;
+ }
- del_timer_sync(&i8042_timer);
+/*
+ * Ok, everything is ready, let's register all serio ports
+ */
+ i8042_register_ports();
+
+ return 0;
+
+ out_fail:
+ i8042_free_aux_ports(); /* in case KBD failed but AUX not */
+ i8042_free_irqs();
+ i8042_controller_reset();
+
+ return error;
+}
+
+static int __devexit i8042_remove(struct platform_device *dev)
+{
+ i8042_unregister_ports();
+ i8042_free_irqs();
+ i8042_controller_reset();
return 0;
}
@@ -1134,8 +1167,9 @@ static int __init i8042_init(void)
if (err)
return err;
- i8042_ports[I8042_AUX_PORT_NO].irq = I8042_AUX_IRQ;
- i8042_ports[I8042_KBD_PORT_NO].irq = I8042_KBD_IRQ;
+ err = i8042_controller_check();
+ if (err)
+ goto err_platform_exit;
err = platform_driver_register(&i8042_driver);
if (err)
@@ -1151,6 +1185,8 @@ static int __init i8042_init(void)
if (err)
goto err_free_device;
+ panic_blink = i8042_panic_blink;
+
return 0;
err_free_device:
@@ -1167,7 +1203,6 @@ static void __exit i8042_exit(void)
{
platform_device_unregister(i8042_platform_device);
platform_driver_unregister(&i8042_driver);
-
i8042_platform_exit();
panic_blink = NULL;
diff --git a/drivers/input/serio/i8042.h b/drivers/input/serio/i8042.h
index af526ab9ec04..b3eb7a72d961 100644
--- a/drivers/input/serio/i8042.h
+++ b/drivers/input/serio/i8042.h
@@ -37,15 +37,6 @@
#define I8042_CTL_TIMEOUT 10000
/*
- * When the device isn't opened and it's interrupts aren't used, we poll it at
- * regular intervals to see if any characters arrived. If yes, we can start
- * probing for any mouse / keyboard connected. This is the period of the
- * polling.
- */
-
-#define I8042_POLL_PERIOD HZ/20
-
-/*
* Status register bits.
*/
diff --git a/drivers/input/serio/libps2.c b/drivers/input/serio/libps2.c
index ed202f2f251a..dcb16b5cbec0 100644
--- a/drivers/input/serio/libps2.c
+++ b/drivers/input/serio/libps2.c
@@ -27,15 +27,6 @@ MODULE_AUTHOR("Dmitry Torokhov <dtor@mail.ru>");
MODULE_DESCRIPTION("PS/2 driver library");
MODULE_LICENSE("GPL");
-EXPORT_SYMBOL(ps2_init);
-EXPORT_SYMBOL(ps2_sendbyte);
-EXPORT_SYMBOL(ps2_drain);
-EXPORT_SYMBOL(ps2_command);
-EXPORT_SYMBOL(ps2_schedule_command);
-EXPORT_SYMBOL(ps2_handle_ack);
-EXPORT_SYMBOL(ps2_handle_response);
-EXPORT_SYMBOL(ps2_cmd_aborted);
-
/* Work structure to schedule execution of a command */
struct ps2work {
struct work_struct work;
@@ -71,6 +62,7 @@ int ps2_sendbyte(struct ps2dev *ps2dev, unsigned char byte, int timeout)
return -ps2dev->nak;
}
+EXPORT_SYMBOL(ps2_sendbyte);
/*
* ps2_drain() waits for device to transmit requested number of bytes
@@ -96,15 +88,16 @@ void ps2_drain(struct ps2dev *ps2dev, int maxbytes, int timeout)
msecs_to_jiffies(timeout));
mutex_unlock(&ps2dev->cmd_mutex);
}
+EXPORT_SYMBOL(ps2_drain);
/*
* ps2_is_keyboard_id() checks received ID byte against the list of
* known keyboard IDs.
*/
-static inline int ps2_is_keyboard_id(char id_byte)
+int ps2_is_keyboard_id(char id_byte)
{
- static char keyboard_ids[] = {
+ const static char keyboard_ids[] = {
0xab, /* Regular keyboards */
0xac, /* NCD Sun keyboard */
0x2b, /* Trust keyboard, translated */
@@ -115,6 +108,7 @@ static inline int ps2_is_keyboard_id(char id_byte)
return memchr(keyboard_ids, id_byte, sizeof(keyboard_ids)) != NULL;
}
+EXPORT_SYMBOL(ps2_is_keyboard_id);
/*
* ps2_adjust_timeout() is called after receiving 1st byte of command
@@ -139,6 +133,19 @@ static int ps2_adjust_timeout(struct ps2dev *ps2dev, int command, int timeout)
case PS2_CMD_GETID:
/*
+ * Microsoft Natural Elite keyboard responds to
+ * the GET ID command as it were a mouse, with
+ * a single byte. Fail the command so atkbd will
+ * use alternative probe to detect it.
+ */
+ if (ps2dev->cmdbuf[1] == 0xaa) {
+ serio_pause_rx(ps2dev->serio);
+ ps2dev->flags = 0;
+ serio_continue_rx(ps2dev->serio);
+ timeout = 0;
+ }
+
+ /*
* If device behind the port is not a keyboard there
* won't be 2nd byte of ID response.
*/
@@ -237,6 +244,7 @@ int ps2_command(struct ps2dev *ps2dev, unsigned char *param, int command)
mutex_unlock(&ps2dev->cmd_mutex);
return rc;
}
+EXPORT_SYMBOL(ps2_command);
/*
* ps2_execute_scheduled_command() sends a command, previously scheduled by
@@ -279,6 +287,7 @@ int ps2_schedule_command(struct ps2dev *ps2dev, unsigned char *param, int comman
return 0;
}
+EXPORT_SYMBOL(ps2_schedule_command);
/*
* ps2_init() initializes ps2dev structure
@@ -290,6 +299,7 @@ void ps2_init(struct ps2dev *ps2dev, struct serio *serio)
init_waitqueue_head(&ps2dev->wait);
ps2dev->serio = serio;
}
+EXPORT_SYMBOL(ps2_init);
/*
* ps2_handle_ack() is supposed to be used in interrupt handler
@@ -335,6 +345,7 @@ int ps2_handle_ack(struct ps2dev *ps2dev, unsigned char data)
return 1;
}
+EXPORT_SYMBOL(ps2_handle_ack);
/*
* ps2_handle_response() is supposed to be used in interrupt handler
@@ -360,6 +371,7 @@ int ps2_handle_response(struct ps2dev *ps2dev, unsigned char data)
return 1;
}
+EXPORT_SYMBOL(ps2_handle_response);
void ps2_cmd_aborted(struct ps2dev *ps2dev)
{
@@ -371,4 +383,4 @@ void ps2_cmd_aborted(struct ps2dev *ps2dev)
ps2dev->flags = 0;
}
-
+EXPORT_SYMBOL(ps2_cmd_aborted);
diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig
index b1b14f8d4dd6..9418bbe47072 100644
--- a/drivers/input/touchscreen/Kconfig
+++ b/drivers/input/touchscreen/Kconfig
@@ -108,4 +108,40 @@ config TOUCHSCREEN_HP600
To compile this driver as a module, choose M here: the
module will be called hp680_ts_input.
+config TOUCHSCREEN_PENMOUNT
+ tristate "Penmount serial touchscreen"
+ select SERIO
+ help
+ Say Y here if you have a Penmount serial touchscreen connected to
+ your system.
+
+ If unsure, say N.
+
+ To compile this driver as a module, choose M here: the
+ module will be called penmount.
+
+config TOUCHSCREEN_TOUCHRIGHT
+ tristate "Touchright serial touchscreen"
+ select SERIO
+ help
+ Say Y here if you have a Touchright serial touchscreen connected to
+ your system.
+
+ If unsure, say N.
+
+ To compile this driver as a module, choose M here: the
+ module will be called touchright.
+
+config TOUCHSCREEN_TOUCHWIN
+ tristate "Touchwin serial touchscreen"
+ select SERIO
+ help
+ Say Y here if you have a Touchwin serial touchscreen connected to
+ your system.
+
+ If unsure, say N.
+
+ To compile this driver as a module, choose M here: the
+ module will be called touchwin.
+
endif
diff --git a/drivers/input/touchscreen/Makefile b/drivers/input/touchscreen/Makefile
index 5e5557c43121..1abb8f10d608 100644
--- a/drivers/input/touchscreen/Makefile
+++ b/drivers/input/touchscreen/Makefile
@@ -12,3 +12,6 @@ obj-$(CONFIG_TOUCHSCREEN_ELO) += elo.o
obj-$(CONFIG_TOUCHSCREEN_MTOUCH) += mtouch.o
obj-$(CONFIG_TOUCHSCREEN_MK712) += mk712.o
obj-$(CONFIG_TOUCHSCREEN_HP600) += hp680_ts_input.o
+obj-$(CONFIG_TOUCHSCREEN_PENMOUNT) += penmount.o
+obj-$(CONFIG_TOUCHSCREEN_TOUCHRIGHT) += touchright.o
+obj-$(CONFIG_TOUCHSCREEN_TOUCHWIN) += touchwin.o
diff --git a/drivers/input/touchscreen/elo.c b/drivers/input/touchscreen/elo.c
index c86a2eb310fd..ab565335ee44 100644
--- a/drivers/input/touchscreen/elo.c
+++ b/drivers/input/touchscreen/elo.c
@@ -23,6 +23,7 @@
#include <linux/input.h>
#include <linux/serio.h>
#include <linux/init.h>
+#include <linux/ctype.h>
#define DRIVER_DESC "Elo serial touchscreen driver"
@@ -34,7 +35,19 @@ MODULE_LICENSE("GPL");
* Definitions & global arrays.
*/
-#define ELO_MAX_LENGTH 10
+#define ELO_MAX_LENGTH 10
+
+#define ELO10_PACKET_LEN 8
+#define ELO10_TOUCH 0x03
+#define ELO10_PRESSURE 0x80
+
+#define ELO10_LEAD_BYTE 'U'
+
+#define ELO10_ID_CMD 'i'
+
+#define ELO10_TOUCH_PACKET 'T'
+#define ELO10_ACK_PACKET 'A'
+#define ELI10_ID_PACKET 'I'
/*
* Per-touchscreen data.
@@ -43,51 +56,67 @@ MODULE_LICENSE("GPL");
struct elo {
struct input_dev *dev;
struct serio *serio;
+ struct mutex cmd_mutex;
+ struct completion cmd_done;
int id;
int idx;
+ unsigned char expected_packet;
unsigned char csum;
unsigned char data[ELO_MAX_LENGTH];
+ unsigned char response[ELO10_PACKET_LEN];
char phys[32];
};
-static void elo_process_data_10(struct elo* elo, unsigned char data, struct pt_regs *regs)
+static void elo_process_data_10(struct elo *elo, unsigned char data, struct pt_regs *regs)
{
struct input_dev *dev = elo->dev;
- elo->csum += elo->data[elo->idx] = data;
-
+ elo->data[elo->idx] = data;
switch (elo->idx++) {
-
case 0:
- if (data != 'U') {
+ elo->csum = 0xaa;
+ if (data != ELO10_LEAD_BYTE) {
+ pr_debug("elo: unsynchronized data: 0x%02x\n", data);
elo->idx = 0;
- elo->csum = 0;
- }
- break;
-
- case 1:
- if (data != 'T') {
- elo->idx = 0;
- elo->csum = 0;
}
break;
case 9:
- if (elo->csum) {
+ elo->idx = 0;
+ if (data != elo->csum) {
+ pr_debug("elo: bad checksum: 0x%02x, expected 0x%02x\n",
+ data, elo->csum);
+ break;
+ }
+ if (elo->data[1] != elo->expected_packet) {
+ if (elo->data[1] != ELO10_TOUCH_PACKET)
+ pr_debug("elo: unexpected packet: 0x%02x\n",
+ elo->data[1]);
+ break;
+ }
+ if (likely(elo->data[1] == ELO10_TOUCH_PACKET)) {
input_regs(dev, regs);
input_report_abs(dev, ABS_X, (elo->data[4] << 8) | elo->data[3]);
input_report_abs(dev, ABS_Y, (elo->data[6] << 8) | elo->data[5]);
- input_report_abs(dev, ABS_PRESSURE, (elo->data[8] << 8) | elo->data[7]);
- input_report_key(dev, BTN_TOUCH, elo->data[8] || elo->data[7]);
+ if (elo->data[2] & ELO10_PRESSURE)
+ input_report_abs(dev, ABS_PRESSURE,
+ (elo->data[8] << 8) | elo->data[7]);
+ input_report_key(dev, BTN_TOUCH, elo->data[2] & ELO10_TOUCH);
input_sync(dev);
+ } else if (elo->data[1] == ELO10_ACK_PACKET) {
+ if (elo->data[2] == '0')
+ elo->expected_packet = ELO10_TOUCH_PACKET;
+ complete(&elo->cmd_done);
+ } else {
+ memcpy(elo->response, &elo->data[1], ELO10_PACKET_LEN);
+ elo->expected_packet = ELO10_ACK_PACKET;
}
- elo->idx = 0;
- elo->csum = 0;
break;
}
+ elo->csum += data;
}
-static void elo_process_data_6(struct elo* elo, unsigned char data, struct pt_regs *regs)
+static void elo_process_data_6(struct elo *elo, unsigned char data, struct pt_regs *regs)
{
struct input_dev *dev = elo->dev;
@@ -135,7 +164,7 @@ static void elo_process_data_6(struct elo* elo, unsigned char data, struct pt_re
}
}
-static void elo_process_data_3(struct elo* elo, unsigned char data, struct pt_regs *regs)
+static void elo_process_data_3(struct elo *elo, unsigned char data, struct pt_regs *regs)
{
struct input_dev *dev = elo->dev;
@@ -161,7 +190,7 @@ static void elo_process_data_3(struct elo* elo, unsigned char data, struct pt_re
static irqreturn_t elo_interrupt(struct serio *serio,
unsigned char data, unsigned int flags, struct pt_regs *regs)
{
- struct elo* elo = serio_get_drvdata(serio);
+ struct elo *elo = serio_get_drvdata(serio);
switch(elo->id) {
case 0:
@@ -181,17 +210,81 @@ static irqreturn_t elo_interrupt(struct serio *serio,
return IRQ_HANDLED;
}
+static int elo_command_10(struct elo *elo, unsigned char *packet)
+{
+ int rc = -1;
+ int i;
+ unsigned char csum = 0xaa + ELO10_LEAD_BYTE;
+
+ mutex_lock(&elo->cmd_mutex);
+
+ serio_pause_rx(elo->serio);
+ elo->expected_packet = toupper(packet[0]);
+ init_completion(&elo->cmd_done);
+ serio_continue_rx(elo->serio);
+
+ if (serio_write(elo->serio, ELO10_LEAD_BYTE))
+ goto out;
+
+ for (i = 0; i < ELO10_PACKET_LEN; i++) {
+ csum += packet[i];
+ if (serio_write(elo->serio, packet[i]))
+ goto out;
+ }
+
+ if (serio_write(elo->serio, csum))
+ goto out;
+
+ wait_for_completion_timeout(&elo->cmd_done, HZ);
+
+ if (elo->expected_packet == ELO10_TOUCH_PACKET) {
+ /* We are back in reporting mode, the command was ACKed */
+ memcpy(packet, elo->response, ELO10_PACKET_LEN);
+ rc = 0;
+ }
+
+ out:
+ mutex_unlock(&elo->cmd_mutex);
+ return rc;
+}
+
+static int elo_setup_10(struct elo *elo)
+{
+ static const char *elo_types[] = { "Accu", "Dura", "Intelli", "Carroll" };
+ struct input_dev *dev = elo->dev;
+ unsigned char packet[ELO10_PACKET_LEN] = { ELO10_ID_CMD };
+
+ if (elo_command_10(elo, packet))
+ return -1;
+
+ dev->id.version = (packet[5] << 8) | packet[4];
+
+ input_set_abs_params(dev, ABS_X, 96, 4000, 0, 0);
+ input_set_abs_params(dev, ABS_Y, 96, 4000, 0, 0);
+ if (packet[3] & ELO10_PRESSURE)
+ input_set_abs_params(dev, ABS_PRESSURE, 0, 255, 0, 0);
+
+ printk(KERN_INFO "elo: %sTouch touchscreen, fw: %02x.%02x, "
+ "features: %x02x, controller: 0x%02x\n",
+ elo_types[(packet[1] -'0') & 0x03],
+ packet[5], packet[4], packet[3], packet[7]);
+
+ return 0;
+}
+
/*
* elo_disconnect() is the opposite of elo_connect()
*/
static void elo_disconnect(struct serio *serio)
{
- struct elo* elo = serio_get_drvdata(serio);
+ struct elo *elo = serio_get_drvdata(serio);
+ input_get_device(elo->dev);
input_unregister_device(elo->dev);
serio_close(serio);
serio_set_drvdata(serio, NULL);
+ input_put_device(elo->dev);
kfree(elo);
}
@@ -211,12 +304,15 @@ static int elo_connect(struct serio *serio, struct serio_driver *drv)
input_dev = input_allocate_device();
if (!elo || !input_dev) {
err = -ENOMEM;
- goto fail;
+ goto fail1;
}
elo->serio = serio;
elo->id = serio->id.id;
elo->dev = input_dev;
+ elo->expected_packet = ELO10_TOUCH_PACKET;
+ mutex_init(&elo->cmd_mutex);
+ init_completion(&elo->cmd_done);
snprintf(elo->phys, sizeof(elo->phys), "%s/input0", serio->phys);
input_dev->private = elo;
@@ -231,12 +327,17 @@ static int elo_connect(struct serio *serio, struct serio_driver *drv)
input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
input_dev->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH);
+ serio_set_drvdata(serio, elo);
+ err = serio_open(serio, drv);
+ if (err)
+ goto fail2;
+
switch (elo->id) {
case 0: /* 10-byte protocol */
- input_set_abs_params(input_dev, ABS_X, 96, 4000, 0, 0);
- input_set_abs_params(input_dev, ABS_Y, 96, 4000, 0, 0);
- input_set_abs_params(input_dev, ABS_PRESSURE, 0, 255, 0, 0);
+ if (elo_setup_10(elo))
+ goto fail3;
+
break;
case 1: /* 6-byte protocol */
@@ -253,17 +354,15 @@ static int elo_connect(struct serio *serio, struct serio_driver *drv)
break;
}
- serio_set_drvdata(serio, elo);
-
- err = serio_open(serio, drv);
+ err = input_register_device(elo->dev);
if (err)
- goto fail;
+ goto fail3;
- input_register_device(elo->dev);
return 0;
- fail: serio_set_drvdata(serio, NULL);
- input_free_device(input_dev);
+ fail3: serio_close(serio);
+ fail2: serio_set_drvdata(serio, NULL);
+ fail1: input_free_device(input_dev);
kfree(elo);
return err;
}
diff --git a/drivers/input/touchscreen/penmount.c b/drivers/input/touchscreen/penmount.c
new file mode 100644
index 000000000000..f7370109d43e
--- /dev/null
+++ b/drivers/input/touchscreen/penmount.c
@@ -0,0 +1,185 @@
+/*
+ * Penmount serial touchscreen driver
+ *
+ * Copyright (c) 2006 Rick Koch <n1gp@hotmail.com>
+ *
+ * Based on ELO driver (drivers/input/touchscreen/elo.c)
+ * Copyright (c) 2004 Vojtech Pavlik
+ */
+
+/*
+ * 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 <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/input.h>
+#include <linux/serio.h>
+#include <linux/init.h>
+
+#define DRIVER_DESC "Penmount serial touchscreen driver"
+
+MODULE_AUTHOR("Rick Koch <n1gp@hotmail.com>");
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_LICENSE("GPL");
+
+/*
+ * Definitions & global arrays.
+ */
+
+#define PM_MAX_LENGTH 5
+
+/*
+ * Per-touchscreen data.
+ */
+
+struct pm {
+ struct input_dev *dev;
+ struct serio *serio;
+ int idx;
+ unsigned char data[PM_MAX_LENGTH];
+ char phys[32];
+};
+
+static irqreturn_t pm_interrupt(struct serio *serio,
+ unsigned char data, unsigned int flags, struct pt_regs *regs)
+{
+ struct pm *pm = serio_get_drvdata(serio);
+ struct input_dev *dev = pm->dev;
+
+ pm->data[pm->idx] = data;
+
+ if (pm->data[0] & 0x80) {
+ if (PM_MAX_LENGTH == ++pm->idx) {
+ input_regs(dev, regs);
+ input_report_abs(dev, ABS_X, pm->data[2] * 128 + pm->data[1]);
+ input_report_abs(dev, ABS_Y, pm->data[4] * 128 + pm->data[3]);
+ input_report_key(dev, BTN_TOUCH, !!(pm->data[0] & 0x40));
+ input_sync(dev);
+ pm->idx = 0;
+ }
+ }
+
+ return IRQ_HANDLED;
+}
+
+/*
+ * pm_disconnect() is the opposite of pm_connect()
+ */
+
+static void pm_disconnect(struct serio *serio)
+{
+ struct pm *pm = serio_get_drvdata(serio);
+
+ input_get_device(pm->dev);
+ input_unregister_device(pm->dev);
+ serio_close(serio);
+ serio_set_drvdata(serio, NULL);
+ input_put_device(pm->dev);
+ kfree(pm);
+}
+
+/*
+ * pm_connect() is the routine that is called when someone adds a
+ * new serio device that supports Gunze protocol and registers it as
+ * an input device.
+ */
+
+static int pm_connect(struct serio *serio, struct serio_driver *drv)
+{
+ struct pm *pm;
+ struct input_dev *input_dev;
+ int err;
+
+ pm = kzalloc(sizeof(struct pm), GFP_KERNEL);
+ input_dev = input_allocate_device();
+ if (!pm || !input_dev) {
+ err = -ENOMEM;
+ goto fail1;
+ }
+
+ pm->serio = serio;
+ pm->dev = input_dev;
+ snprintf(pm->phys, sizeof(pm->phys), "%s/input0", serio->phys);
+
+ input_dev->private = pm;
+ input_dev->name = "Penmount Serial TouchScreen";
+ input_dev->phys = pm->phys;
+ input_dev->id.bustype = BUS_RS232;
+ input_dev->id.vendor = SERIO_PENMOUNT;
+ input_dev->id.product = 0;
+ input_dev->id.version = 0x0100;
+ input_dev->cdev.dev = &serio->dev;
+
+ input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
+ input_dev->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH);
+ input_set_abs_params(pm->dev, ABS_X, 0, 0x3ff, 0, 0);
+ input_set_abs_params(pm->dev, ABS_Y, 0, 0x3ff, 0, 0);
+
+ serio_set_drvdata(serio, pm);
+
+ err = serio_open(serio, drv);
+ if (err)
+ goto fail2;
+
+ err = input_register_device(pm->dev);
+ if (err)
+ goto fail3;
+
+ return 0;
+
+ fail3: serio_close(serio);
+ fail2: serio_set_drvdata(serio, NULL);
+ fail1: input_free_device(input_dev);
+ kfree(pm);
+ return err;
+}
+
+/*
+ * The serio driver structure.
+ */
+
+static struct serio_device_id pm_serio_ids[] = {
+ {
+ .type = SERIO_RS232,
+ .proto = SERIO_PENMOUNT,
+ .id = SERIO_ANY,
+ .extra = SERIO_ANY,
+ },
+ { 0 }
+};
+
+MODULE_DEVICE_TABLE(serio, pm_serio_ids);
+
+static struct serio_driver pm_drv = {
+ .driver = {
+ .name = "penmountlpc",
+ },
+ .description = DRIVER_DESC,
+ .id_table = pm_serio_ids,
+ .interrupt = pm_interrupt,
+ .connect = pm_connect,
+ .disconnect = pm_disconnect,
+};
+
+/*
+ * The functions for inserting/removing us as a module.
+ */
+
+static int __init pm_init(void)
+{
+ serio_register_driver(&pm_drv);
+ return 0;
+}
+
+static void __exit pm_exit(void)
+{
+ serio_unregister_driver(&pm_drv);
+}
+
+module_init(pm_init);
+module_exit(pm_exit);
diff --git a/drivers/input/touchscreen/touchright.c b/drivers/input/touchscreen/touchright.c
new file mode 100644
index 000000000000..1c89fa538651
--- /dev/null
+++ b/drivers/input/touchscreen/touchright.c
@@ -0,0 +1,196 @@
+/*
+ * Touchright serial touchscreen driver
+ *
+ * Copyright (c) 2006 Rick Koch <n1gp@hotmail.com>
+ *
+ * Based on MicroTouch driver (drivers/input/touchscreen/mtouch.c)
+ * Copyright (c) 2004 Vojtech Pavlik
+ * and Dan Streetman <ddstreet@ieee.org>
+ */
+
+/*
+ * 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 <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/input.h>
+#include <linux/serio.h>
+#include <linux/init.h>
+
+#define DRIVER_DESC "Touchright serial touchscreen driver"
+
+MODULE_AUTHOR("Rick Koch <n1gp@hotmail.com>");
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_LICENSE("GPL");
+
+/*
+ * Definitions & global arrays.
+ */
+
+#define TR_FORMAT_TOUCH_BIT 0x01
+#define TR_FORMAT_STATUS_BYTE 0x40
+#define TR_FORMAT_STATUS_MASK ~TR_FORMAT_TOUCH_BIT
+
+#define TR_LENGTH 5
+
+#define TR_MIN_XC 0
+#define TR_MAX_XC 0x1ff
+#define TR_MIN_YC 0
+#define TR_MAX_YC 0x1ff
+
+/*
+ * Per-touchscreen data.
+ */
+
+struct tr {
+ struct input_dev *dev;
+ struct serio *serio;
+ int idx;
+ unsigned char data[TR_LENGTH];
+ char phys[32];
+};
+
+static irqreturn_t tr_interrupt(struct serio *serio,
+ unsigned char data, unsigned int flags, struct pt_regs *regs)
+{
+ struct tr *tr = serio_get_drvdata(serio);
+ struct input_dev *dev = tr->dev;
+
+ tr->data[tr->idx] = data;
+
+ if ((tr->data[0] & TR_FORMAT_STATUS_MASK) == TR_FORMAT_STATUS_BYTE) {
+ if (++tr->idx == TR_LENGTH) {
+ input_regs(dev, regs);
+ input_report_abs(dev, ABS_X,
+ (tr->data[1] << 5) | (tr->data[2] >> 1));
+ input_report_abs(dev, ABS_Y,
+ (tr->data[3] << 5) | (tr->data[4] >> 1));
+ input_report_key(dev, BTN_TOUCH,
+ tr->data[0] & TR_FORMAT_TOUCH_BIT);
+ input_sync(dev);
+ tr->idx = 0;
+ }
+ }
+
+ return IRQ_HANDLED;
+}
+
+/*
+ * tr_disconnect() is the opposite of tr_connect()
+ */
+
+static void tr_disconnect(struct serio *serio)
+{
+ struct tr *tr = serio_get_drvdata(serio);
+
+ input_get_device(tr->dev);
+ input_unregister_device(tr->dev);
+ serio_close(serio);
+ serio_set_drvdata(serio, NULL);
+ input_put_device(tr->dev);
+ kfree(tr);
+}
+
+/*
+ * tr_connect() is the routine that is called when someone adds a
+ * new serio device that supports the Touchright protocol and registers it as
+ * an input device.
+ */
+
+static int tr_connect(struct serio *serio, struct serio_driver *drv)
+{
+ struct tr *tr;
+ struct input_dev *input_dev;
+ int err;
+
+ tr = kzalloc(sizeof(struct tr), GFP_KERNEL);
+ input_dev = input_allocate_device();
+ if (!tr || !input_dev) {
+ err = -ENOMEM;
+ goto fail1;
+ }
+
+ tr->serio = serio;
+ tr->dev = input_dev;
+ snprintf(tr->phys, sizeof(tr->phys), "%s/input0", serio->phys);
+
+ input_dev->private = tr;
+ input_dev->name = "Touchright Serial TouchScreen";
+ input_dev->phys = tr->phys;
+ input_dev->id.bustype = BUS_RS232;
+ input_dev->id.vendor = SERIO_TOUCHRIGHT;
+ input_dev->id.product = 0;
+ input_dev->id.version = 0x0100;
+ input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
+ input_dev->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH);
+ input_set_abs_params(tr->dev, ABS_X, TR_MIN_XC, TR_MAX_XC, 0, 0);
+ input_set_abs_params(tr->dev, ABS_Y, TR_MIN_YC, TR_MAX_YC, 0, 0);
+
+ serio_set_drvdata(serio, tr);
+
+ err = serio_open(serio, drv);
+ if (err)
+ goto fail2;
+
+ err = input_register_device(tr->dev);
+ if (err)
+ goto fail3;
+
+ return 0;
+
+ fail3: serio_close(serio);
+ fail2: serio_set_drvdata(serio, NULL);
+ fail1: input_free_device(input_dev);
+ kfree(tr);
+ return err;
+}
+
+/*
+ * The serio driver structure.
+ */
+
+static struct serio_device_id tr_serio_ids[] = {
+ {
+ .type = SERIO_RS232,
+ .proto = SERIO_TOUCHRIGHT,
+ .id = SERIO_ANY,
+ .extra = SERIO_ANY,
+ },
+ { 0 }
+};
+
+MODULE_DEVICE_TABLE(serio, tr_serio_ids);
+
+static struct serio_driver tr_drv = {
+ .driver = {
+ .name = "touchright",
+ },
+ .description = DRIVER_DESC,
+ .id_table = tr_serio_ids,
+ .interrupt = tr_interrupt,
+ .connect = tr_connect,
+ .disconnect = tr_disconnect,
+};
+
+/*
+ * The functions for inserting/removing us as a module.
+ */
+
+static int __init tr_init(void)
+{
+ serio_register_driver(&tr_drv);
+ return 0;
+}
+
+static void __exit tr_exit(void)
+{
+ serio_unregister_driver(&tr_drv);
+}
+
+module_init(tr_init);
+module_exit(tr_exit);
diff --git a/drivers/input/touchscreen/touchwin.c b/drivers/input/touchscreen/touchwin.c
new file mode 100644
index 000000000000..a7b4c755958e
--- /dev/null
+++ b/drivers/input/touchscreen/touchwin.c
@@ -0,0 +1,203 @@
+/*
+ * Touchwindow serial touchscreen driver
+ *
+ * Copyright (c) 2006 Rick Koch <n1gp@hotmail.com>
+ *
+ * Based on MicroTouch driver (drivers/input/touchscreen/mtouch.c)
+ * Copyright (c) 2004 Vojtech Pavlik
+ * and Dan Streetman <ddstreet@ieee.org>
+ */
+
+/*
+ * 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.
+ */
+
+/*
+ * 2005/02/19 Rick Koch:
+ * The Touchwindow I used is made by Edmark Corp. and
+ * constantly outputs a stream of 0's unless it is touched.
+ * It then outputs 3 bytes: X, Y, and a copy of Y.
+ */
+
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/input.h>
+#include <linux/serio.h>
+#include <linux/init.h>
+
+#define DRIVER_DESC "Touchwindow serial touchscreen driver"
+
+MODULE_AUTHOR("Rick Koch <n1gp@hotmail.com>");
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_LICENSE("GPL");
+
+/*
+ * Definitions & global arrays.
+ */
+
+#define TW_LENGTH 3
+
+#define TW_MIN_XC 0
+#define TW_MAX_XC 0xff
+#define TW_MIN_YC 0
+#define TW_MAX_YC 0xff
+
+/*
+ * Per-touchscreen data.
+ */
+
+struct tw {
+ struct input_dev *dev;
+ struct serio *serio;
+ int idx;
+ int touched;
+ unsigned char data[TW_LENGTH];
+ char phys[32];
+};
+
+static irqreturn_t tw_interrupt(struct serio *serio,
+ unsigned char data, unsigned int flags, struct pt_regs *regs)
+{
+ struct tw *tw = serio_get_drvdata(serio);
+ struct input_dev *dev = tw->dev;
+
+ if (data) { /* touch */
+ tw->touched = 1;
+ tw->data[tw->idx++] = data;
+ /* verify length and that the two Y's are the same */
+ if (tw->idx == TW_LENGTH && tw->data[1] == tw->data[2]) {
+ input_regs(dev, regs);
+ input_report_abs(dev, ABS_X, tw->data[0]);
+ input_report_abs(dev, ABS_Y, tw->data[1]);
+ input_report_key(dev, BTN_TOUCH, 1);
+ input_sync(dev);
+ tw->idx = 0;
+ }
+ } else if (tw->touched) { /* untouch */
+ input_report_key(dev, BTN_TOUCH, 0);
+ input_sync(dev);
+ tw->idx = 0;
+ tw->touched = 0;
+ }
+
+ return IRQ_HANDLED;
+}
+
+/*
+ * tw_disconnect() is the opposite of tw_connect()
+ */
+
+static void tw_disconnect(struct serio *serio)
+{
+ struct tw *tw = serio_get_drvdata(serio);
+
+ input_get_device(tw->dev);
+ input_unregister_device(tw->dev);
+ serio_close(serio);
+ serio_set_drvdata(serio, NULL);
+ input_put_device(tw->dev);
+ kfree(tw);
+}
+
+/*
+ * tw_connect() is the routine that is called when someone adds a
+ * new serio device that supports the Touchwin protocol and registers it as
+ * an input device.
+ */
+
+static int tw_connect(struct serio *serio, struct serio_driver *drv)
+{
+ struct tw *tw;
+ struct input_dev *input_dev;
+ int err;
+
+ tw = kzalloc(sizeof(struct tw), GFP_KERNEL);
+ input_dev = input_allocate_device();
+ if (!tw || !input_dev) {
+ err = -ENOMEM;
+ goto fail1;
+ }
+
+ tw->serio = serio;
+ tw->dev = input_dev;
+ snprintf(tw->phys, sizeof(tw->phys), "%s/input0", serio->phys);
+
+ input_dev->private = tw;
+ input_dev->name = "Touchwindow Serial TouchScreen";
+ input_dev->phys = tw->phys;
+ input_dev->id.bustype = BUS_RS232;
+ input_dev->id.vendor = SERIO_TOUCHWIN;
+ input_dev->id.product = 0;
+ input_dev->id.version = 0x0100;
+ input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
+ input_dev->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH);
+ input_set_abs_params(tw->dev, ABS_X, TW_MIN_XC, TW_MAX_XC, 0, 0);
+ input_set_abs_params(tw->dev, ABS_Y, TW_MIN_YC, TW_MAX_YC, 0, 0);
+
+ serio_set_drvdata(serio, tw);
+
+ err = serio_open(serio, drv);
+ if (err)
+ goto fail2;
+
+ err = input_register_device(tw->dev);
+ if (err)
+ goto fail3;
+
+ return 0;
+
+ fail3: serio_close(serio);
+ fail2: serio_set_drvdata(serio, NULL);
+ fail1: input_free_device(input_dev);
+ kfree(tw);
+ return err;
+}
+
+/*
+ * The serio driver structure.
+ */
+
+static struct serio_device_id tw_serio_ids[] = {
+ {
+ .type = SERIO_RS232,
+ .proto = SERIO_TOUCHWIN,
+ .id = SERIO_ANY,
+ .extra = SERIO_ANY,
+ },
+ { 0 }
+};
+
+MODULE_DEVICE_TABLE(serio, tw_serio_ids);
+
+static struct serio_driver tw_drv = {
+ .driver = {
+ .name = "touchwin",
+ },
+ .description = DRIVER_DESC,
+ .id_table = tw_serio_ids,
+ .interrupt = tw_interrupt,
+ .connect = tw_connect,
+ .disconnect = tw_disconnect,
+};
+
+/*
+ * The functions for inserting/removing us as a module.
+ */
+
+static int __init tw_init(void)
+{
+ serio_register_driver(&tw_drv);
+ return 0;
+}
+
+static void __exit tw_exit(void)
+{
+ serio_unregister_driver(&tw_drv);
+}
+
+module_init(tw_init);
+module_exit(tw_exit);
diff --git a/drivers/input/tsdev.c b/drivers/input/tsdev.c
index 00e3929c6288..a730c461227f 100644
--- a/drivers/input/tsdev.c
+++ b/drivers/input/tsdev.c
@@ -135,8 +135,6 @@ struct tsdev_list {
#define TS_GET_CAL _IOR(IOC_H3600_TS_MAGIC, 10, struct ts_calibration)
#define TS_SET_CAL _IOW(IOC_H3600_TS_MAGIC, 11, struct ts_calibration)
-static struct input_handler tsdev_handler;
-
static struct tsdev *tsdev_table[TSDEV_MINORS/2];
static int tsdev_fasync(int fd, struct file *file, int on)
@@ -263,7 +261,7 @@ static int tsdev_ioctl(struct inode *inode, struct file *file,
return retval;
}
-static struct file_operations tsdev_fops = {
+static const struct file_operations tsdev_fops = {
.owner = THIS_MODULE,
.open = tsdev_open,
.release = tsdev_release,
@@ -370,7 +368,7 @@ static void tsdev_event(struct input_handle *handle, unsigned int type,
static struct input_handle *tsdev_connect(struct input_handler *handler,
struct input_dev *dev,
- struct input_device_id *id)
+ const struct input_device_id *id)
{
struct tsdev *tsdev;
struct class_device *cdev;
@@ -443,7 +441,7 @@ static void tsdev_disconnect(struct input_handle *handle)
tsdev_free(tsdev);
}
-static struct input_device_id tsdev_ids[] = {
+static const struct input_device_id tsdev_ids[] = {
{
.flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_KEYBIT | INPUT_DEVICE_ID_MATCH_RELBIT,
.evbit = { BIT(EV_KEY) | BIT(EV_REL) },
@@ -481,9 +479,7 @@ static struct input_handler tsdev_handler = {
static int __init tsdev_init(void)
{
- input_register_handler(&tsdev_handler);
- printk(KERN_INFO "ts: Compaq touchscreen protocol output\n");
- return 0;
+ return input_register_handler(&tsdev_handler);
}
static void __exit tsdev_exit(void)
diff --git a/drivers/isdn/capi/capi.c b/drivers/isdn/capi/capi.c
index 669f76393b5a..11844bbfe933 100644
--- a/drivers/isdn/capi/capi.c
+++ b/drivers/isdn/capi/capi.c
@@ -1298,7 +1298,7 @@ static int capinc_tty_read_proc(char *page, char **start, off_t off,
static struct tty_driver *capinc_tty_driver;
-static struct tty_operations capinc_ops = {
+static const struct tty_operations capinc_ops = {
.open = capinc_tty_open,
.close = capinc_tty_close,
.write = capinc_tty_write,
diff --git a/drivers/isdn/gigaset/interface.c b/drivers/isdn/gigaset/interface.c
index bd2e4267528e..596f3aebe2f7 100644
--- a/drivers/isdn/gigaset/interface.c
+++ b/drivers/isdn/gigaset/interface.c
@@ -134,7 +134,7 @@ static int if_tiocmset(struct tty_struct *tty, struct file *file,
static int if_write(struct tty_struct *tty,
const unsigned char *buf, int count);
-static struct tty_operations if_ops = {
+static const struct tty_operations if_ops = {
.open = if_open,
.close = if_close,
.ioctl = if_ioctl,
diff --git a/drivers/isdn/gigaset/proc.c b/drivers/isdn/gigaset/proc.c
index 9ae3a7f3e7b3..9ad840e95dbe 100644
--- a/drivers/isdn/gigaset/proc.c
+++ b/drivers/isdn/gigaset/proc.c
@@ -83,5 +83,6 @@ void gigaset_init_dev_sysfs(struct cardstate *cs)
return;
gig_dbg(DEBUG_INIT, "setting up sysfs");
- class_device_create_file(cs->class, &class_device_attr_cidmode);
+ if (class_device_create_file(cs->class, &class_device_attr_cidmode))
+ dev_err(cs->dev, "could not create sysfs attribute\n");
}
diff --git a/drivers/isdn/hardware/eicon/dsp_defs.h b/drivers/isdn/hardware/eicon/dsp_defs.h
index b44950e06f32..fec1e381a688 100644
--- a/drivers/isdn/hardware/eicon/dsp_defs.h
+++ b/drivers/isdn/hardware/eicon/dsp_defs.h
@@ -34,9 +34,6 @@
*
* I/O functions returns -1 on error, 0 on EOF
*/
-#define OS_SEEK_SET 0
-#define OS_SEEK_CUR 1
-#define OS_SEEK_END 2
struct _OsFileHandle_;
typedef long ( * OsFileIo) (struct _OsFileHandle_ *handle,
void *buffer,
diff --git a/drivers/isdn/hisax/config.c b/drivers/isdn/hisax/config.c
index e10350360f2f..e4823ab2b127 100644
--- a/drivers/isdn/hisax/config.c
+++ b/drivers/isdn/hisax/config.c
@@ -1721,11 +1721,11 @@ static void hisax_b_l1l2(struct hisax_if *ifc, int pr, void *arg)
hisax_b_sched_event(bcs, B_RCVBUFREADY);
break;
case PH_DATA | CONFIRM:
- bcs->tx_cnt -= (int) arg;
+ bcs->tx_cnt -= (long)arg;
if (test_bit(FLG_LLI_L1WAKEUP,&bcs->st->lli.flag)) {
u_long flags;
spin_lock_irqsave(&bcs->aclock, flags);
- bcs->ackcnt += (int) arg;
+ bcs->ackcnt += (long)arg;
spin_unlock_irqrestore(&bcs->aclock, flags);
schedule_event(bcs, B_ACKPENDING);
}
@@ -1789,7 +1789,7 @@ static void hisax_b_l2l1(struct PStack *st, int pr, void *arg)
switch (pr) {
case PH_ACTIVATE | REQUEST:
- B_L2L1(b_if, pr, (void *) st->l1.mode);
+ B_L2L1(b_if, pr, (void *)(unsigned long)st->l1.mode);
break;
case PH_DATA | REQUEST:
case PH_PULL | INDICATION:
diff --git a/drivers/isdn/hisax/hfc4s8s_l1.c b/drivers/isdn/hisax/hfc4s8s_l1.c
index 3a5ca8a68fc4..0ca5e66d2f5a 100644
--- a/drivers/isdn/hisax/hfc4s8s_l1.c
+++ b/drivers/isdn/hisax/hfc4s8s_l1.c
@@ -424,7 +424,7 @@ bch_l2l1(struct hisax_if *ifc, int pr, void *arg)
struct hfc4s8s_btype *bch = ifc->priv;
struct hfc4s8s_l1 *l1 = bch->l1p;
struct sk_buff *skb = (struct sk_buff *) arg;
- int mode = (int) arg;
+ long mode = (long) arg;
u_long flags;
switch (pr) {
@@ -914,7 +914,7 @@ tx_d_frame(struct hfc4s8s_l1 *l1p)
struct sk_buff *skb;
u_char f1, f2;
u_char *cp;
- int cnt;
+ long cnt;
if (l1p->l1_state != 7)
return;
@@ -980,7 +980,8 @@ tx_b_frame(struct hfc4s8s_btype *bch)
struct sk_buff *skb;
struct hfc4s8s_l1 *l1 = bch->l1p;
u_char *cp;
- int cnt, max, hdlc_num, ack_len = 0;
+ int cnt, max, hdlc_num;
+ long ack_len = 0;
if (!l1->enabled || (bch->mode == L1_MODE_NULL))
return;
diff --git a/drivers/isdn/hisax/hfc_sx.c b/drivers/isdn/hisax/hfc_sx.c
index f27c1608a3a7..b7e8e23be337 100644
--- a/drivers/isdn/hisax/hfc_sx.c
+++ b/drivers/isdn/hisax/hfc_sx.c
@@ -970,7 +970,7 @@ HFCSX_l1hw(struct PStack *st, int pr, void *arg)
break;
case (HW_TESTLOOP | REQUEST):
spin_lock_irqsave(&cs->lock, flags);
- switch ((int) arg) {
+ switch ((long) arg) {
case (1):
Write_hfc(cs, HFCSX_B1_SSL, 0x80); /* tx slot */
Write_hfc(cs, HFCSX_B1_RSL, 0x80); /* rx slot */
@@ -986,7 +986,7 @@ HFCSX_l1hw(struct PStack *st, int pr, void *arg)
default:
spin_unlock_irqrestore(&cs->lock, flags);
if (cs->debug & L1_DEB_WARN)
- debugl1(cs, "hfcsx_l1hw loop invalid %4x", (int) arg);
+ debugl1(cs, "hfcsx_l1hw loop invalid %4lx", arg);
return;
}
cs->hw.hfcsx.trm |= 0x80; /* enable IOM-loop */
diff --git a/drivers/isdn/hisax/hfc_usb.c b/drivers/isdn/hisax/hfc_usb.c
index b5e571a52694..6b88ecb5047d 100644
--- a/drivers/isdn/hisax/hfc_usb.c
+++ b/drivers/isdn/hisax/hfc_usb.c
@@ -696,7 +696,7 @@ tx_iso_complete(struct urb *urb, struct pt_regs *regs)
fifo->delete_flg = TRUE;
fifo->hif->l1l2(fifo->hif,
PH_DATA | CONFIRM,
- (void *) fifo->skbuff->
+ (void *) (unsigned long) fifo->skbuff->
truesize);
if (fifo->skbuff && fifo->delete_flg) {
dev_kfree_skb_any(fifo->skbuff);
@@ -1144,7 +1144,7 @@ hfc_usb_l2l1(struct hisax_if *my_hisax_if, int pr, void *arg)
set_hfcmode(hfc,
(fifo->fifonum ==
HFCUSB_B1_TX) ? 0 : 1,
- (int) arg);
+ (long) arg);
fifo->hif->l1l2(fifo->hif,
PH_ACTIVATE | INDICATION,
NULL);
diff --git a/drivers/isdn/hisax/hisax.h b/drivers/isdn/hisax/hisax.h
index 75920aa0a3c5..2f9d5118ceaf 100644
--- a/drivers/isdn/hisax/hisax.h
+++ b/drivers/isdn/hisax/hisax.h
@@ -1316,7 +1316,18 @@ void dlogframe(struct IsdnCardState *cs, struct sk_buff *skb, int dir);
void iecpy(u_char * dest, u_char * iestart, int ieoffset);
#endif /* __KERNEL__ */
-#define HZDELAY(jiffs) {int tout = jiffs; while (tout--) udelay(1000000/HZ);}
+/*
+ * Busywait delay for `jiffs' jiffies
+ */
+#define HZDELAY(jiffs) do { \
+ int tout = jiffs; \
+ \
+ while (tout--) { \
+ int loops = USEC_PER_SEC / HZ; \
+ while (loops--) \
+ udelay(1); \
+ } \
+ } while (0)
int ll_run(struct IsdnCardState *cs, int addfeatures);
int CallcNew(void);
diff --git a/drivers/isdn/hisax/hisax_fcpcipnp.c b/drivers/isdn/hisax/hisax_fcpcipnp.c
index 1d7cf3bd6aa3..881a4165cfb4 100644
--- a/drivers/isdn/hisax/hisax_fcpcipnp.c
+++ b/drivers/isdn/hisax/hisax_fcpcipnp.c
@@ -546,7 +546,7 @@ static inline void hdlc_xpr_irq(struct fritz_bcs *bcs)
}
bcs->tx_cnt = 0;
bcs->tx_skb = NULL;
- B_L1L2(bcs, PH_DATA | CONFIRM, (void *) skb->truesize);
+ B_L1L2(bcs, PH_DATA | CONFIRM, (void *)(unsigned long)skb->truesize);
dev_kfree_skb_irq(skb);
}
@@ -635,7 +635,7 @@ static void fritz_b_l2l1(struct hisax_if *ifc, int pr, void *arg)
hdlc_fill_fifo(bcs);
break;
case PH_ACTIVATE | REQUEST:
- mode = (int) arg;
+ mode = (long) arg;
DBG(4,"B%d,PH_ACTIVATE_REQUEST %d", bcs->channel + 1, mode);
modehdlc(bcs, mode);
B_L1L2(bcs, PH_ACTIVATE | INDICATION, NULL);
@@ -998,18 +998,15 @@ static int __init hisax_fcpcipnp_init(void)
retval = pci_register_driver(&fcpci_driver);
if (retval)
- goto out;
+ return retval;
#ifdef __ISAPNP__
retval = pnp_register_driver(&fcpnp_driver);
- if (retval < 0)
- goto out_unregister_pci;
+ if (retval < 0) {
+ pci_unregister_driver(&fcpci_driver);
+ return retval;
+ }
#endif
return 0;
-
- out_unregister_pci:
- pci_unregister_driver(&fcpci_driver);
- out:
- return retval;
}
static void __exit hisax_fcpcipnp_exit(void)
diff --git a/drivers/isdn/hisax/st5481_b.c b/drivers/isdn/hisax/st5481_b.c
index 22fd5db18d48..aca2a3954b14 100644
--- a/drivers/isdn/hisax/st5481_b.c
+++ b/drivers/isdn/hisax/st5481_b.c
@@ -86,7 +86,7 @@ static void usb_b_out(struct st5481_bcs *bcs,int buf_nr)
if (!skb->len) {
// Frame sent
b_out->tx_skb = NULL;
- B_L1L2(bcs, PH_DATA | CONFIRM, (void *) skb->truesize);
+ B_L1L2(bcs, PH_DATA | CONFIRM, (void *)(unsigned long) skb->truesize);
dev_kfree_skb_any(skb);
/* if (!(bcs->tx_skb = skb_dequeue(&bcs->sq))) { */
@@ -350,7 +350,7 @@ void st5481_b_l2l1(struct hisax_if *ifc, int pr, void *arg)
{
struct st5481_bcs *bcs = ifc->priv;
struct sk_buff *skb = arg;
- int mode;
+ long mode;
DBG(4, "");
@@ -360,8 +360,8 @@ void st5481_b_l2l1(struct hisax_if *ifc, int pr, void *arg)
bcs->b_out.tx_skb = skb;
break;
case PH_ACTIVATE | REQUEST:
- mode = (int) arg;
- DBG(4,"B%d,PH_ACTIVATE_REQUEST %d", bcs->channel + 1, mode);
+ mode = (long) arg;
+ DBG(4,"B%d,PH_ACTIVATE_REQUEST %ld", bcs->channel + 1, mode);
st5481B_mode(bcs, mode);
B_L1L2(bcs, PH_ACTIVATE | INDICATION, NULL);
break;
diff --git a/drivers/isdn/hisax/st5481_d.c b/drivers/isdn/hisax/st5481_d.c
index 493dc94992e5..98adec440590 100644
--- a/drivers/isdn/hisax/st5481_d.c
+++ b/drivers/isdn/hisax/st5481_d.c
@@ -374,7 +374,7 @@ static void usb_d_out_complete(struct urb *urb, struct pt_regs *regs)
{
struct st5481_adapter *adapter = urb->context;
struct st5481_d_out *d_out = &adapter->d_out;
- int buf_nr;
+ long buf_nr;
DBG(2, "");
@@ -546,7 +546,7 @@ static void dout_reseted(struct FsmInst *fsm, int event, void *arg)
static void dout_complete(struct FsmInst *fsm, int event, void *arg)
{
struct st5481_adapter *adapter = fsm->userdata;
- int buf_nr = (int) arg;
+ long buf_nr = (long) arg;
usb_d_out(adapter, buf_nr);
}
diff --git a/drivers/isdn/i4l/isdn_net.c b/drivers/isdn/i4l/isdn_net.c
index 43da8ae1b2ad..1f8d6ae66b41 100644
--- a/drivers/isdn/i4l/isdn_net.c
+++ b/drivers/isdn/i4l/isdn_net.c
@@ -1614,8 +1614,8 @@ isdn_net_ciscohdlck_slarp_send_reply(isdn_net_local *lp)
struct sk_buff *skb;
unsigned char *p;
struct in_device *in_dev = NULL;
- u32 addr = 0; /* local ipv4 address */
- u32 mask = 0; /* local netmask */
+ __be32 addr = 0; /* local ipv4 address */
+ __be32 mask = 0; /* local netmask */
if ((in_dev = lp->netdev->dev.ip_ptr) != NULL) {
/* take primary(first) address of interface */
diff --git a/drivers/isdn/i4l/isdn_tty.c b/drivers/isdn/i4l/isdn_tty.c
index 9ab66e8960d5..2b91bb07fc7f 100644
--- a/drivers/isdn/i4l/isdn_tty.c
+++ b/drivers/isdn/i4l/isdn_tty.c
@@ -1860,7 +1860,7 @@ modem_write_profile(atemu * m)
send_sig(SIGIO, dev->profd, 1);
}
-static struct tty_operations modem_ops = {
+static const struct tty_operations modem_ops = {
.open = isdn_tty_open,
.close = isdn_tty_close,
.write = isdn_tty_write,
diff --git a/drivers/isdn/sc/command.c b/drivers/isdn/sc/command.c
index b4b24335f716..04b8a58f03b5 100644
--- a/drivers/isdn/sc/command.c
+++ b/drivers/isdn/sc/command.c
@@ -103,9 +103,6 @@ int command(isdn_ctrl *cmd)
return -ENODEV;
}
- pr_debug("%s: Received %s command from Link Layer\n",
- sc_adapter[card]->devicename, commands[cmd->command]);
-
/*
* Dispatch the command
*/
@@ -118,7 +115,7 @@ int command(isdn_ctrl *cmd)
memcpy(&cmdptr, cmd->parm.num, sizeof(unsigned long));
if (copy_from_user(&ioc, (scs_ioctl __user *)cmdptr,
sizeof(scs_ioctl))) {
- pr_debug("%s: Failed to verify user space 0x%x\n",
+ pr_debug("%s: Failed to verify user space 0x%lx\n",
sc_adapter[card]->devicename, cmdptr);
return -EFAULT;
}
@@ -195,7 +192,7 @@ static int dial(int card, unsigned long channel, setup_parm setup)
strlen(Phone),
(unsigned int *) Phone);
- pr_debug("%s: Dialing %s on channel %d\n",
+ pr_debug("%s: Dialing %s on channel %lu\n",
sc_adapter[card]->devicename, Phone, channel+1);
return status;
@@ -217,7 +214,7 @@ static int answer(int card, unsigned long channel)
}
indicate_status(card, ISDN_STAT_BCONN,channel,NULL);
- pr_debug("%s: Answered incoming call on channel %s\n",
+ pr_debug("%s: Answered incoming call on channel %lu\n",
sc_adapter[card]->devicename, channel+1);
return 0;
}
@@ -240,7 +237,7 @@ static int hangup(int card, unsigned long channel)
(unsigned char) channel+1,
0,
NULL);
- pr_debug("%s: Sent HANGUP message to channel %d\n",
+ pr_debug("%s: Sent HANGUP message to channel %lu\n",
sc_adapter[card]->devicename, channel+1);
return status;
}
@@ -260,9 +257,6 @@ static int setl2(int card, unsigned long arg)
protocol = arg >> 8;
channel = arg & 0xff;
sc_adapter[card]->channel[channel].l2_proto = protocol;
- pr_debug("%s: Level 2 protocol for channel %d set to %s from %d\n",
- sc_adapter[card]->devicename, channel+1,
- l2protos[sc_adapter[card]->channel[channel].l2_proto],protocol);
/*
* check that the adapter is also set to the correct protocol
@@ -293,8 +287,6 @@ static int setl3(int card, unsigned long channel)
}
sc_adapter[card]->channel[channel].l3_proto = protocol;
- pr_debug("%s: Level 3 protocol for channel %d set to %s\n",
- sc_adapter[card]->devicename, channel+1, l3protos[protocol]);
return 0;
}
@@ -311,7 +303,7 @@ static int acceptb(int card, unsigned long channel)
return -ENOBUFS;
}
- pr_debug("%s: B-Channel connection accepted on channel %d\n",
+ pr_debug("%s: B-Channel connection accepted on channel %lu\n",
sc_adapter[card]->devicename, channel+1);
indicate_status(card, ISDN_STAT_BCONN, channel, NULL);
return 0;
@@ -326,7 +318,7 @@ static int clreaz(int card, unsigned long arg)
strcpy(sc_adapter[card]->channel[arg].eazlist, "");
sc_adapter[card]->channel[arg].eazclear = 1;
- pr_debug("%s: EAZ List cleared for channel %d\n",
+ pr_debug("%s: EAZ List cleared for channel %lu\n",
sc_adapter[card]->devicename, arg+1);
return 0;
}
@@ -340,7 +332,7 @@ static int seteaz(int card, unsigned long arg, char *num)
strcpy(sc_adapter[card]->channel[arg].eazlist, num);
sc_adapter[card]->channel[arg].eazclear = 0;
- pr_debug("%s: EAZ list for channel %d set to: %s\n",
+ pr_debug("%s: EAZ list for channel %lu set to: %s\n",
sc_adapter[card]->devicename, arg+1,
sc_adapter[card]->channel[arg].eazlist);
return 0;
diff --git a/drivers/isdn/sc/event.c b/drivers/isdn/sc/event.c
index 5b8c7c1a7663..57367325ef04 100644
--- a/drivers/isdn/sc/event.c
+++ b/drivers/isdn/sc/event.c
@@ -45,8 +45,10 @@ int indicate_status(int card, int event,ulong Channel,char *Data)
{
isdn_ctrl cmd;
+#ifdef DEBUG
pr_debug("%s: Indicating event %s on Channel %d\n",
sc_adapter[card]->devicename, events[event-256], Channel);
+#endif
if (Data != NULL){
pr_debug("%s: Event data: %s\n", sc_adapter[card]->devicename,
Data);
diff --git a/drivers/isdn/sc/interrupt.c b/drivers/isdn/sc/interrupt.c
index 8631d338d69a..ae6263125ac2 100644
--- a/drivers/isdn/sc/interrupt.c
+++ b/drivers/isdn/sc/interrupt.c
@@ -91,7 +91,7 @@ irqreturn_t interrupt_handler(int interrupt, void *cardptr, struct pt_regs *regs
*/
if (IS_CE_MESSAGE(rcvmsg, Lnk, 1, Read))
{
- pr_debug("%s: Received packet 0x%x bytes long at 0x%x\n",
+ pr_debug("%s: Received packet 0x%x bytes long at 0x%lx\n",
sc_adapter[card]->devicename,
rcvmsg.msg_data.response.msg_len,
rcvmsg.msg_data.response.buff_offset);
diff --git a/drivers/isdn/sc/timer.c b/drivers/isdn/sc/timer.c
index aced19aac5a2..f43282be0ada 100644
--- a/drivers/isdn/sc/timer.c
+++ b/drivers/isdn/sc/timer.c
@@ -76,7 +76,7 @@ void check_reset(unsigned long data)
if (sc_adapter[card]->StartOnReset)
startproc(card);
} else {
- pr_debug("%s: No signature yet, waiting another %d jiffies.\n",
+ pr_debug("%s: No signature yet, waiting another %lu jiffies.\n",
sc_adapter[card]->devicename, CHECKRESET_TIME);
mod_timer(&sc_adapter[card]->reset_timer, jiffies+CHECKRESET_TIME);
spin_unlock_irqrestore(&sc_adapter[card]->lock, flags);
diff --git a/drivers/leds/led-triggers.c b/drivers/leds/led-triggers.c
index 47f0ff196328..454fb0901f82 100644
--- a/drivers/leds/led-triggers.c
+++ b/drivers/leds/led-triggers.c
@@ -125,6 +125,7 @@ void led_trigger_set(struct led_classdev *led_cdev, struct led_trigger *trigger)
write_unlock_irqrestore(&led_cdev->trigger->leddev_list_lock, flags);
if (led_cdev->trigger->deactivate)
led_cdev->trigger->deactivate(led_cdev);
+ led_set_brightness(led_cdev, LED_OFF);
}
if (trigger) {
write_lock_irqsave(&trigger->leddev_list_lock, flags);
diff --git a/drivers/leds/leds-net48xx.c b/drivers/leds/leds-net48xx.c
index 713c4a8aa77d..45ba3d45bcb8 100644
--- a/drivers/leds/leds-net48xx.c
+++ b/drivers/leds/leds-net48xx.c
@@ -16,6 +16,7 @@
#include <linux/leds.h>
#include <linux/err.h>
#include <asm/io.h>
+#include <linux/nsc_gpio.h>
#include <linux/scx200_gpio.h>
#define DRVNAME "net48xx-led"
@@ -26,10 +27,7 @@ static struct platform_device *pdev;
static void net48xx_error_led_set(struct led_classdev *led_cdev,
enum led_brightness value)
{
- if (value)
- scx200_gpio_set_high(NET48XX_ERROR_LED_GPIO);
- else
- scx200_gpio_set_low(NET48XX_ERROR_LED_GPIO);
+ scx200_gpio_ops.gpio_set(NET48XX_ERROR_LED_GPIO, value ? 1 : 0);
}
static struct led_classdev net48xx_error_led = {
@@ -81,7 +79,8 @@ static int __init net48xx_led_init(void)
{
int ret;
- if (!scx200_gpio_present()) {
+ /* small hack, but scx200_gpio doesn't set .dev if the probe fails */
+ if (!scx200_gpio_ops.dev) {
ret = -ENODEV;
goto out;
}
diff --git a/drivers/macintosh/smu.c b/drivers/macintosh/smu.c
index 090e40fc5013..c0f9d82e4662 100644
--- a/drivers/macintosh/smu.c
+++ b/drivers/macintosh/smu.c
@@ -870,7 +870,7 @@ int smu_queue_i2c(struct smu_i2c_cmd *cmd)
static int smu_read_datablock(u8 *dest, unsigned int addr, unsigned int len)
{
- DECLARE_COMPLETION(comp);
+ DECLARE_COMPLETION_ONSTACK(comp);
unsigned int chunk;
struct smu_cmd cmd;
int rc;
@@ -917,7 +917,7 @@ static int smu_read_datablock(u8 *dest, unsigned int addr, unsigned int len)
static struct smu_sdbp_header *smu_create_sdb_partition(int id)
{
- DECLARE_COMPLETION(comp);
+ DECLARE_COMPLETION_ONSTACK(comp);
struct smu_simple_cmd cmd;
unsigned int addr, len, tlen;
struct smu_sdbp_header *hdr;
diff --git a/drivers/macintosh/via-pmu-backlight.c b/drivers/macintosh/via-pmu-backlight.c
index a82f313d9dc9..6c29fe727c0f 100644
--- a/drivers/macintosh/via-pmu-backlight.c
+++ b/drivers/macintosh/via-pmu-backlight.c
@@ -16,7 +16,7 @@
#define MAX_PMU_LEVEL 0xFF
static struct backlight_properties pmu_backlight_data;
-static spinlock_t pmu_backlight_lock;
+static DEFINE_SPINLOCK(pmu_backlight_lock);
static int sleeping;
static u8 bl_curve[FB_BACKLIGHT_LEVELS];
diff --git a/drivers/macintosh/via-pmu.c b/drivers/macintosh/via-pmu.c
index dda03985dcf5..4f04fd0956a0 100644
--- a/drivers/macintosh/via-pmu.c
+++ b/drivers/macintosh/via-pmu.c
@@ -336,8 +336,10 @@ int __init find_via_pmu(void)
if (gaddr != OF_BAD_ADDR)
gpio_reg = ioremap(gaddr, 0x10);
}
- if (gpio_reg == NULL)
+ if (gpio_reg == NULL) {
printk(KERN_ERR "via-pmu: Can't find GPIO reg !\n");
+ goto fail_gpio;
+ }
} else
pmu_kind = PMU_UNKNOWN;
@@ -365,6 +367,9 @@ int __init find_via_pmu(void)
return 1;
fail:
of_node_put(vias);
+ iounmap(gpio_reg);
+ gpio_reg = NULL;
+ fail_gpio:
vias = NULL;
return 0;
}
@@ -1827,7 +1832,7 @@ pbook_alloc_pci_save(void)
struct pci_dev *pd = NULL;
npci = 0;
- while ((pd = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, pd)) != NULL) {
+ while ((pd = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pd)) != NULL) {
++npci;
}
if (npci == 0)
@@ -1857,9 +1862,11 @@ pbook_pci_save(void)
if (ps == NULL)
return;
- while ((pd = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, pd)) != NULL) {
- if (npci-- == 0)
+ while ((pd = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pd)) != NULL) {
+ if (npci-- == 0) {
+ pci_dev_put(pd);
return;
+ }
#ifndef HACKED_PCI_SAVE
pci_read_config_word(pd, PCI_COMMAND, &ps->command);
pci_read_config_word(pd, PCI_CACHE_LINE_SIZE, &ps->cache_lat);
@@ -1887,11 +1894,13 @@ pbook_pci_restore(void)
int npci = pbook_npci_saves;
int j;
- while ((pd = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, pd)) != NULL) {
+ while ((pd = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pd)) != NULL) {
#ifdef HACKED_PCI_SAVE
int i;
- if (npci-- == 0)
+ if (npci-- == 0) {
+ pci_dev_put(pd);
return;
+ }
ps++;
for (i=2;i<16;i++)
pci_write_config_dword(pd, i<<4, ps->config[i]);
diff --git a/drivers/macintosh/via-pmu68k.c b/drivers/macintosh/via-pmu68k.c
index 35b70323e7e3..9f4eff1d1a0f 100644
--- a/drivers/macintosh/via-pmu68k.c
+++ b/drivers/macintosh/via-pmu68k.c
@@ -843,7 +843,7 @@ pbook_pci_save(void)
struct pci_save *ps;
npci = 0;
- while ((pd = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, pd)) != NULL)
+ while ((pd = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pd)) != NULL)
++npci;
n_pbook_pci_saves = npci;
if (npci == 0)
@@ -854,7 +854,7 @@ pbook_pci_save(void)
return;
pd = NULL;
- while ((pd = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, pd)) != NULL) {
+ while ((pd = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pd)) != NULL) {
pci_read_config_word(pd, PCI_COMMAND, &ps->command);
pci_read_config_word(pd, PCI_CACHE_LINE_SIZE, &ps->cache_lat);
pci_read_config_word(pd, PCI_INTERRUPT_LINE, &ps->intr);
@@ -871,7 +871,7 @@ pbook_pci_restore(void)
struct pci_dev *pd = NULL;
int j;
- while ((pd = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, pd)) != NULL) {
+ while ((pd = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pd)) != NULL) {
if (ps->command == 0)
continue;
pci_read_config_word(pd, PCI_COMMAND, &cmd);
diff --git a/drivers/macintosh/windfarm_smu_controls.c b/drivers/macintosh/windfarm_smu_controls.c
index bff1f372f188..31b750d61206 100644
--- a/drivers/macintosh/windfarm_smu_controls.c
+++ b/drivers/macintosh/windfarm_smu_controls.c
@@ -56,7 +56,7 @@ static int smu_set_fan(int pwm, u8 id, u16 value)
{
struct smu_cmd cmd;
u8 buffer[16];
- DECLARE_COMPLETION(comp);
+ DECLARE_COMPLETION_ONSTACK(comp);
int rc;
/* Fill SMU command structure */
diff --git a/drivers/macintosh/windfarm_smu_sat.c b/drivers/macintosh/windfarm_smu_sat.c
index aceb61d9fbc8..83f79de7174b 100644
--- a/drivers/macintosh/windfarm_smu_sat.c
+++ b/drivers/macintosh/windfarm_smu_sat.c
@@ -397,12 +397,7 @@ static int wf_sat_detach(struct i2c_client *client)
static int __init sat_sensors_init(void)
{
- int err;
-
- err = i2c_add_driver(&wf_sat_driver);
- if (err < 0)
- return err;
- return 0;
+ return i2c_add_driver(&wf_sat_driver);
}
static void __exit sat_sensors_exit(void)
diff --git a/drivers/macintosh/windfarm_smu_sensors.c b/drivers/macintosh/windfarm_smu_sensors.c
index defe9922ebd1..01b4c50143dd 100644
--- a/drivers/macintosh/windfarm_smu_sensors.c
+++ b/drivers/macintosh/windfarm_smu_sensors.c
@@ -67,7 +67,7 @@ static void smu_ads_release(struct wf_sensor *sr)
static int smu_read_adc(u8 id, s32 *value)
{
struct smu_simple_cmd cmd;
- DECLARE_COMPLETION(comp);
+ DECLARE_COMPLETION_ONSTACK(comp);
int rc;
rc = smu_queue_simple(&cmd, SMU_CMD_READ_ADC, 1,
diff --git a/drivers/md/Kconfig b/drivers/md/Kconfig
index bf869ed03eed..c92c1521546d 100644
--- a/drivers/md/Kconfig
+++ b/drivers/md/Kconfig
@@ -2,6 +2,8 @@
# Block device driver configuration
#
+if BLOCK
+
menu "Multi-device support (RAID and LVM)"
config MD
@@ -136,16 +138,16 @@ config MD_RAID456
If unsure, say Y.
config MD_RAID5_RESHAPE
- bool "Support adding drives to a raid-5 array (experimental)"
- depends on MD_RAID456 && EXPERIMENTAL
+ bool "Support adding drives to a raid-5 array"
+ depends on MD_RAID456
+ default y
---help---
A RAID-5 set can be expanded by adding extra drives. This
requires "restriping" the array which means (almost) every
block must be written to a different place.
This option allows such restriping to be done while the array
- is online. However it is still EXPERIMENTAL code. It should
- work, but please be sure that you have backups.
+ is online.
You will need mdadm version 2.4.1 or later to use this
feature safely. During the early stage of reshape there is
@@ -162,6 +164,8 @@ config MD_RAID5_RESHAPE
There should be enough spares already present to make the new
array workable.
+ If unsure, say Y.
+
config MD_MULTIPATH
tristate "Multipath I/O support"
depends on BLK_DEV_MD
@@ -199,6 +203,14 @@ config BLK_DEV_DM
If unsure, say N.
+config DM_DEBUG
+ boolean "Device mapper debugging support"
+ depends on BLK_DEV_DM && EXPERIMENTAL
+ ---help---
+ Enable this for messages that may help debug device-mapper problems.
+
+ If unsure, say N.
+
config DM_CRYPT
tristate "Crypt target support"
depends on BLK_DEV_DM && EXPERIMENTAL
@@ -251,3 +263,4 @@ config DM_MULTIPATH_EMC
endmenu
+endif
diff --git a/drivers/md/bitmap.c b/drivers/md/bitmap.c
index ecc56765d949..8e67634e79a0 100644
--- a/drivers/md/bitmap.c
+++ b/drivers/md/bitmap.c
@@ -613,6 +613,7 @@ static inline unsigned long file_page_offset(unsigned long chunk)
static inline struct page *filemap_get_page(struct bitmap *bitmap,
unsigned long chunk)
{
+ if (file_page_index(chunk) >= bitmap->file_pages) return NULL;
return bitmap->filemap[file_page_index(chunk) - file_page_index(0)];
}
@@ -739,6 +740,7 @@ static void bitmap_file_set_bit(struct bitmap *bitmap, sector_t block)
}
page = filemap_get_page(bitmap, chunk);
+ if (!page) return;
bit = file_page_offset(chunk);
/* set the bit */
@@ -1322,6 +1324,18 @@ static void bitmap_set_memory_bits(struct bitmap *bitmap, sector_t offset, int n
}
+/* dirty the memory and file bits for bitmap chunks "s" to "e" */
+void bitmap_dirty_bits(struct bitmap *bitmap, unsigned long s, unsigned long e)
+{
+ unsigned long chunk;
+
+ for (chunk = s; chunk <= e; chunk++) {
+ sector_t sec = chunk << CHUNK_BLOCK_SHIFT(bitmap);
+ bitmap_set_memory_bits(bitmap, sec, 1);
+ bitmap_file_set_bit(bitmap, sec);
+ }
+}
+
/*
* flush out any pending updates
*/
@@ -1430,8 +1444,7 @@ int bitmap_create(mddev_t *mddev)
if (err)
goto error;
- bitmap->chunkshift = find_first_bit(&bitmap->chunksize,
- sizeof(bitmap->chunksize));
+ bitmap->chunkshift = ffz(~bitmap->chunksize);
/* now that chunksize and chunkshift are set, we can use these macros */
chunks = (blocks + CHUNK_BLOCK_RATIO(bitmap) - 1) /
diff --git a/drivers/md/dm-crypt.c b/drivers/md/dm-crypt.c
index bdbd34993a80..655d816760e5 100644
--- a/drivers/md/dm-crypt.c
+++ b/drivers/md/dm-crypt.c
@@ -1,6 +1,7 @@
/*
* Copyright (C) 2003 Christophe Saout <christophe@saout.de>
* Copyright (C) 2004 Clemens Fruhwirth <clemens@endorphin.org>
+ * Copyright (C) 2006 Red Hat, Inc. All rights reserved.
*
* This file is released under the GPL.
*/
@@ -22,17 +23,19 @@
#include "dm.h"
#define DM_MSG_PREFIX "crypt"
+#define MESG_STR(x) x, sizeof(x)
/*
* per bio private data
*/
struct crypt_io {
struct dm_target *target;
- struct bio *bio;
+ struct bio *base_bio;
struct bio *first_clone;
struct work_struct work;
atomic_t pending;
int error;
+ int post_process;
};
/*
@@ -63,6 +66,7 @@ struct crypt_iv_operations {
* Crypt: maps a linear range of a block device
* and encrypts / decrypts at the same time.
*/
+enum flags { DM_CRYPT_SUSPENDED, DM_CRYPT_KEY_VALID };
struct crypt_config {
struct dm_dev *dev;
sector_t start;
@@ -73,6 +77,7 @@ struct crypt_config {
*/
mempool_t *io_pool;
mempool_t *page_pool;
+ struct bio_set *bs;
/*
* crypto related data
@@ -86,11 +91,12 @@ struct crypt_config {
char cipher[CRYPTO_MAX_ALG_NAME];
char chainmode[CRYPTO_MAX_ALG_NAME];
struct crypto_blkcipher *tfm;
+ unsigned long flags;
unsigned int key_size;
u8 key[0];
};
-#define MIN_IOS 256
+#define MIN_IOS 16
#define MIN_POOL_PAGES 32
#define MIN_BIO_PAGES 8
@@ -306,6 +312,14 @@ static int crypt_convert(struct crypt_config *cc,
return r;
}
+ static void dm_crypt_bio_destructor(struct bio *bio)
+ {
+ struct crypt_io *io = bio->bi_private;
+ struct crypt_config *cc = io->target->private;
+
+ bio_free(bio, cc->bs);
+ }
+
/*
* Generate a new unfragmented bio with the given size
* This should never violate the device limitations
@@ -315,34 +329,33 @@ static struct bio *
crypt_alloc_buffer(struct crypt_config *cc, unsigned int size,
struct bio *base_bio, unsigned int *bio_vec_idx)
{
- struct bio *bio;
+ struct bio *clone;
unsigned int nr_iovecs = (size + PAGE_SIZE - 1) >> PAGE_SHIFT;
gfp_t gfp_mask = GFP_NOIO | __GFP_HIGHMEM;
unsigned int i;
- /*
- * Use __GFP_NOMEMALLOC to tell the VM to act less aggressively and
- * to fail earlier. This is not necessary but increases throughput.
- * FIXME: Is this really intelligent?
- */
- if (base_bio)
- bio = bio_clone(base_bio, GFP_NOIO|__GFP_NOMEMALLOC);
- else
- bio = bio_alloc(GFP_NOIO|__GFP_NOMEMALLOC, nr_iovecs);
- if (!bio)
+ if (base_bio) {
+ clone = bio_alloc_bioset(GFP_NOIO, base_bio->bi_max_vecs, cc->bs);
+ __bio_clone(clone, base_bio);
+ } else
+ clone = bio_alloc_bioset(GFP_NOIO, nr_iovecs, cc->bs);
+
+ if (!clone)
return NULL;
+ clone->bi_destructor = dm_crypt_bio_destructor;
+
/* if the last bio was not complete, continue where that one ended */
- bio->bi_idx = *bio_vec_idx;
- bio->bi_vcnt = *bio_vec_idx;
- bio->bi_size = 0;
- bio->bi_flags &= ~(1 << BIO_SEG_VALID);
+ clone->bi_idx = *bio_vec_idx;
+ clone->bi_vcnt = *bio_vec_idx;
+ clone->bi_size = 0;
+ clone->bi_flags &= ~(1 << BIO_SEG_VALID);
- /* bio->bi_idx pages have already been allocated */
- size -= bio->bi_idx * PAGE_SIZE;
+ /* clone->bi_idx pages have already been allocated */
+ size -= clone->bi_idx * PAGE_SIZE;
- for(i = bio->bi_idx; i < nr_iovecs; i++) {
- struct bio_vec *bv = bio_iovec_idx(bio, i);
+ for (i = clone->bi_idx; i < nr_iovecs; i++) {
+ struct bio_vec *bv = bio_iovec_idx(clone, i);
bv->bv_page = mempool_alloc(cc->page_pool, gfp_mask);
if (!bv->bv_page)
@@ -353,7 +366,7 @@ crypt_alloc_buffer(struct crypt_config *cc, unsigned int size,
* return a partially allocated bio, the caller will then try
* to allocate additional bios while submitting this partial bio
*/
- if ((i - bio->bi_idx) == (MIN_BIO_PAGES - 1))
+ if ((i - clone->bi_idx) == (MIN_BIO_PAGES - 1))
gfp_mask = (gfp_mask | __GFP_NOWARN) & ~__GFP_WAIT;
bv->bv_offset = 0;
@@ -362,13 +375,13 @@ crypt_alloc_buffer(struct crypt_config *cc, unsigned int size,
else
bv->bv_len = size;
- bio->bi_size += bv->bv_len;
- bio->bi_vcnt++;
+ clone->bi_size += bv->bv_len;
+ clone->bi_vcnt++;
size -= bv->bv_len;
}
- if (!bio->bi_size) {
- bio_put(bio);
+ if (!clone->bi_size) {
+ bio_put(clone);
return NULL;
}
@@ -376,13 +389,13 @@ crypt_alloc_buffer(struct crypt_config *cc, unsigned int size,
* Remember the last bio_vec allocated to be able
* to correctly continue after the splitting.
*/
- *bio_vec_idx = bio->bi_vcnt;
+ *bio_vec_idx = clone->bi_vcnt;
- return bio;
+ return clone;
}
static void crypt_free_buffer_pages(struct crypt_config *cc,
- struct bio *bio, unsigned int bytes)
+ struct bio *clone, unsigned int bytes)
{
unsigned int i, start, end;
struct bio_vec *bv;
@@ -396,19 +409,19 @@ static void crypt_free_buffer_pages(struct crypt_config *cc,
* A fix to the bi_idx issue in the kernel is in the works, so
* we will hopefully be able to revert to the cleaner solution soon.
*/
- i = bio->bi_vcnt - 1;
- bv = bio_iovec_idx(bio, i);
- end = (i << PAGE_SHIFT) + (bv->bv_offset + bv->bv_len) - bio->bi_size;
+ i = clone->bi_vcnt - 1;
+ bv = bio_iovec_idx(clone, i);
+ end = (i << PAGE_SHIFT) + (bv->bv_offset + bv->bv_len) - clone->bi_size;
start = end - bytes;
start >>= PAGE_SHIFT;
- if (!bio->bi_size)
- end = bio->bi_vcnt;
+ if (!clone->bi_size)
+ end = clone->bi_vcnt;
else
end >>= PAGE_SHIFT;
- for(i = start; i < end; i++) {
- bv = bio_iovec_idx(bio, i);
+ for (i = start; i < end; i++) {
+ bv = bio_iovec_idx(clone, i);
BUG_ON(!bv->bv_page);
mempool_free(bv->bv_page, cc->page_pool);
bv->bv_page = NULL;
@@ -432,7 +445,7 @@ static void dec_pending(struct crypt_io *io, int error)
if (io->first_clone)
bio_put(io->first_clone);
- bio_endio(io->bio, io->bio->bi_size, io->error);
+ bio_endio(io->base_bio, io->base_bio->bi_size, io->error);
mempool_free(io, cc->io_pool);
}
@@ -441,29 +454,179 @@ static void dec_pending(struct crypt_io *io, int error)
* kcryptd:
*
* Needed because it would be very unwise to do decryption in an
- * interrupt context, so bios returning from read requests get
- * queued here.
+ * interrupt context.
*/
static struct workqueue_struct *_kcryptd_workqueue;
+static void kcryptd_do_work(void *data);
-static void kcryptd_do_work(void *data)
+static void kcryptd_queue_io(struct crypt_io *io)
{
- struct crypt_io *io = (struct crypt_io *) data;
- struct crypt_config *cc = (struct crypt_config *) io->target->private;
+ INIT_WORK(&io->work, kcryptd_do_work, io);
+ queue_work(_kcryptd_workqueue, &io->work);
+}
+
+static int crypt_endio(struct bio *clone, unsigned int done, int error)
+{
+ struct crypt_io *io = clone->bi_private;
+ struct crypt_config *cc = io->target->private;
+ unsigned read_io = bio_data_dir(clone) == READ;
+
+ /*
+ * free the processed pages, even if
+ * it's only a partially completed write
+ */
+ if (!read_io)
+ crypt_free_buffer_pages(cc, clone, done);
+
+ /* keep going - not finished yet */
+ if (unlikely(clone->bi_size))
+ return 1;
+
+ if (!read_io)
+ goto out;
+
+ if (unlikely(!bio_flagged(clone, BIO_UPTODATE))) {
+ error = -EIO;
+ goto out;
+ }
+
+ bio_put(clone);
+ io->post_process = 1;
+ kcryptd_queue_io(io);
+ return 0;
+
+out:
+ bio_put(clone);
+ dec_pending(io, error);
+ return error;
+}
+
+static void clone_init(struct crypt_io *io, struct bio *clone)
+{
+ struct crypt_config *cc = io->target->private;
+
+ clone->bi_private = io;
+ clone->bi_end_io = crypt_endio;
+ clone->bi_bdev = cc->dev->bdev;
+ clone->bi_rw = io->base_bio->bi_rw;
+}
+
+static void process_read(struct crypt_io *io)
+{
+ struct crypt_config *cc = io->target->private;
+ struct bio *base_bio = io->base_bio;
+ struct bio *clone;
+ sector_t sector = base_bio->bi_sector - io->target->begin;
+
+ atomic_inc(&io->pending);
+
+ /*
+ * The block layer might modify the bvec array, so always
+ * copy the required bvecs because we need the original
+ * one in order to decrypt the whole bio data *afterwards*.
+ */
+ clone = bio_alloc_bioset(GFP_NOIO, bio_segments(base_bio), cc->bs);
+ if (unlikely(!clone)) {
+ dec_pending(io, -ENOMEM);
+ return;
+ }
+
+ clone_init(io, clone);
+ clone->bi_destructor = dm_crypt_bio_destructor;
+ clone->bi_idx = 0;
+ clone->bi_vcnt = bio_segments(base_bio);
+ clone->bi_size = base_bio->bi_size;
+ clone->bi_sector = cc->start + sector;
+ memcpy(clone->bi_io_vec, bio_iovec(base_bio),
+ sizeof(struct bio_vec) * clone->bi_vcnt);
+
+ generic_make_request(clone);
+}
+
+static void process_write(struct crypt_io *io)
+{
+ struct crypt_config *cc = io->target->private;
+ struct bio *base_bio = io->base_bio;
+ struct bio *clone;
struct convert_context ctx;
- int r;
+ unsigned remaining = base_bio->bi_size;
+ sector_t sector = base_bio->bi_sector - io->target->begin;
+ unsigned bvec_idx = 0;
+
+ atomic_inc(&io->pending);
+
+ crypt_convert_init(cc, &ctx, NULL, base_bio, sector, 1);
+
+ /*
+ * The allocated buffers can be smaller than the whole bio,
+ * so repeat the whole process until all the data can be handled.
+ */
+ while (remaining) {
+ clone = crypt_alloc_buffer(cc, base_bio->bi_size,
+ io->first_clone, &bvec_idx);
+ if (unlikely(!clone)) {
+ dec_pending(io, -ENOMEM);
+ return;
+ }
+
+ ctx.bio_out = clone;
+
+ if (unlikely(crypt_convert(cc, &ctx) < 0)) {
+ crypt_free_buffer_pages(cc, clone, clone->bi_size);
+ bio_put(clone);
+ dec_pending(io, -EIO);
+ return;
+ }
+
+ clone_init(io, clone);
+ clone->bi_sector = cc->start + sector;
+
+ if (!io->first_clone) {
+ /*
+ * hold a reference to the first clone, because it
+ * holds the bio_vec array and that can't be freed
+ * before all other clones are released
+ */
+ bio_get(clone);
+ io->first_clone = clone;
+ }
+
+ remaining -= clone->bi_size;
+ sector += bio_sectors(clone);
+
+ /* prevent bio_put of first_clone */
+ if (remaining)
+ atomic_inc(&io->pending);
- crypt_convert_init(cc, &ctx, io->bio, io->bio,
- io->bio->bi_sector - io->target->begin, 0);
- r = crypt_convert(cc, &ctx);
+ generic_make_request(clone);
- dec_pending(io, r);
+ /* out of memory -> run queues */
+ if (remaining)
+ blk_congestion_wait(bio_data_dir(clone), HZ/100);
+ }
}
-static void kcryptd_queue_io(struct crypt_io *io)
+static void process_read_endio(struct crypt_io *io)
{
- INIT_WORK(&io->work, kcryptd_do_work, io);
- queue_work(_kcryptd_workqueue, &io->work);
+ struct crypt_config *cc = io->target->private;
+ struct convert_context ctx;
+
+ crypt_convert_init(cc, &ctx, io->base_bio, io->base_bio,
+ io->base_bio->bi_sector - io->target->begin, 0);
+
+ dec_pending(io, crypt_convert(cc, &ctx));
+}
+
+static void kcryptd_do_work(void *data)
+{
+ struct crypt_io *io = data;
+
+ if (io->post_process)
+ process_read_endio(io);
+ else if (bio_data_dir(io->base_bio) == READ)
+ process_read(io);
+ else
+ process_write(io);
}
/*
@@ -477,7 +640,7 @@ static int crypt_decode_key(u8 *key, char *hex, unsigned int size)
buffer[2] = '\0';
- for(i = 0; i < size; i++) {
+ for (i = 0; i < size; i++) {
buffer[0] = *hex++;
buffer[1] = *hex++;
@@ -500,13 +663,38 @@ static void crypt_encode_key(char *hex, u8 *key, unsigned int size)
{
unsigned int i;
- for(i = 0; i < size; i++) {
+ for (i = 0; i < size; i++) {
sprintf(hex, "%02x", *key);
hex += 2;
key++;
}
}
+static int crypt_set_key(struct crypt_config *cc, char *key)
+{
+ unsigned key_size = strlen(key) >> 1;
+
+ if (cc->key_size && cc->key_size != key_size)
+ return -EINVAL;
+
+ cc->key_size = key_size; /* initial settings */
+
+ if ((!key_size && strcmp(key, "-")) ||
+ (key_size && crypt_decode_key(cc->key, key, key_size) < 0))
+ return -EINVAL;
+
+ set_bit(DM_CRYPT_KEY_VALID, &cc->flags);
+
+ return 0;
+}
+
+static int crypt_wipe_key(struct crypt_config *cc)
+{
+ clear_bit(DM_CRYPT_KEY_VALID, &cc->flags);
+ memset(&cc->key, 0, cc->key_size * sizeof(u8));
+ return 0;
+}
+
/*
* Construct an encryption mapping:
* <cipher> <key> <iv_offset> <dev_path> <start>
@@ -539,16 +727,14 @@ static int crypt_ctr(struct dm_target *ti, unsigned int argc, char **argv)
key_size = strlen(argv[1]) >> 1;
- cc = kmalloc(sizeof(*cc) + key_size * sizeof(u8), GFP_KERNEL);
+ cc = kzalloc(sizeof(*cc) + key_size * sizeof(u8), GFP_KERNEL);
if (cc == NULL) {
ti->error =
"Cannot allocate transparent encryption context";
return -ENOMEM;
}
- cc->key_size = key_size;
- if ((!key_size && strcmp(argv[1], "-") != 0) ||
- (key_size && crypt_decode_key(cc->key, argv[1], key_size) < 0)) {
+ if (crypt_set_key(cc, argv[1])) {
ti->error = "Error decoding key";
goto bad1;
}
@@ -626,6 +812,12 @@ static int crypt_ctr(struct dm_target *ti, unsigned int argc, char **argv)
goto bad4;
}
+ cc->bs = bioset_create(MIN_IOS, MIN_IOS, 4);
+ if (!cc->bs) {
+ ti->error = "Cannot allocate crypt bioset";
+ goto bad_bs;
+ }
+
if (crypto_blkcipher_setkey(tfm, cc->key, key_size) < 0) {
ti->error = "Error setting key";
goto bad5;
@@ -665,6 +857,8 @@ static int crypt_ctr(struct dm_target *ti, unsigned int argc, char **argv)
return 0;
bad5:
+ bioset_free(cc->bs);
+bad_bs:
mempool_destroy(cc->page_pool);
bad4:
mempool_destroy(cc->io_pool);
@@ -684,6 +878,7 @@ static void crypt_dtr(struct dm_target *ti)
{
struct crypt_config *cc = (struct crypt_config *) ti->private;
+ bioset_free(cc->bs);
mempool_destroy(cc->page_pool);
mempool_destroy(cc->io_pool);
@@ -698,147 +893,21 @@ static void crypt_dtr(struct dm_target *ti)
kfree(cc);
}
-static int crypt_endio(struct bio *bio, unsigned int done, int error)
-{
- struct crypt_io *io = (struct crypt_io *) bio->bi_private;
- struct crypt_config *cc = (struct crypt_config *) io->target->private;
-
- if (bio_data_dir(bio) == WRITE) {
- /*
- * free the processed pages, even if
- * it's only a partially completed write
- */
- crypt_free_buffer_pages(cc, bio, done);
- }
-
- if (bio->bi_size)
- return 1;
-
- bio_put(bio);
-
- /*
- * successful reads are decrypted by the worker thread
- */
- if ((bio_data_dir(bio) == READ)
- && bio_flagged(bio, BIO_UPTODATE)) {
- kcryptd_queue_io(io);
- return 0;
- }
-
- dec_pending(io, error);
- return error;
-}
-
-static inline struct bio *
-crypt_clone(struct crypt_config *cc, struct crypt_io *io, struct bio *bio,
- sector_t sector, unsigned int *bvec_idx,
- struct convert_context *ctx)
-{
- struct bio *clone;
-
- if (bio_data_dir(bio) == WRITE) {
- clone = crypt_alloc_buffer(cc, bio->bi_size,
- io->first_clone, bvec_idx);
- if (clone) {
- ctx->bio_out = clone;
- if (crypt_convert(cc, ctx) < 0) {
- crypt_free_buffer_pages(cc, clone,
- clone->bi_size);
- bio_put(clone);
- return NULL;
- }
- }
- } else {
- /*
- * The block layer might modify the bvec array, so always
- * copy the required bvecs because we need the original
- * one in order to decrypt the whole bio data *afterwards*.
- */
- clone = bio_alloc(GFP_NOIO, bio_segments(bio));
- if (clone) {
- clone->bi_idx = 0;
- clone->bi_vcnt = bio_segments(bio);
- clone->bi_size = bio->bi_size;
- memcpy(clone->bi_io_vec, bio_iovec(bio),
- sizeof(struct bio_vec) * clone->bi_vcnt);
- }
- }
-
- if (!clone)
- return NULL;
-
- clone->bi_private = io;
- clone->bi_end_io = crypt_endio;
- clone->bi_bdev = cc->dev->bdev;
- clone->bi_sector = cc->start + sector;
- clone->bi_rw = bio->bi_rw;
-
- return clone;
-}
-
static int crypt_map(struct dm_target *ti, struct bio *bio,
union map_info *map_context)
{
- struct crypt_config *cc = (struct crypt_config *) ti->private;
- struct crypt_io *io = mempool_alloc(cc->io_pool, GFP_NOIO);
- struct convert_context ctx;
- struct bio *clone;
- unsigned int remaining = bio->bi_size;
- sector_t sector = bio->bi_sector - ti->begin;
- unsigned int bvec_idx = 0;
+ struct crypt_config *cc = ti->private;
+ struct crypt_io *io;
+ io = mempool_alloc(cc->io_pool, GFP_NOIO);
io->target = ti;
- io->bio = bio;
+ io->base_bio = bio;
io->first_clone = NULL;
- io->error = 0;
- atomic_set(&io->pending, 1); /* hold a reference */
-
- if (bio_data_dir(bio) == WRITE)
- crypt_convert_init(cc, &ctx, NULL, bio, sector, 1);
-
- /*
- * The allocated buffers can be smaller than the whole bio,
- * so repeat the whole process until all the data can be handled.
- */
- while (remaining) {
- clone = crypt_clone(cc, io, bio, sector, &bvec_idx, &ctx);
- if (!clone)
- goto cleanup;
-
- if (!io->first_clone) {
- /*
- * hold a reference to the first clone, because it
- * holds the bio_vec array and that can't be freed
- * before all other clones are released
- */
- bio_get(clone);
- io->first_clone = clone;
- }
- atomic_inc(&io->pending);
+ io->error = io->post_process = 0;
+ atomic_set(&io->pending, 0);
+ kcryptd_queue_io(io);
- remaining -= clone->bi_size;
- sector += bio_sectors(clone);
-
- generic_make_request(clone);
-
- /* out of memory -> run queues */
- if (remaining)
- blk_congestion_wait(bio_data_dir(clone), HZ/100);
- }
-
- /* drop reference, clones could have returned before we reach this */
- dec_pending(io, 0);
return 0;
-
-cleanup:
- if (io->first_clone) {
- dec_pending(io, -ENOMEM);
- return 0;
- }
-
- /* if no bio has been dispatched yet, we can directly return the error */
- mempool_free(io, cc->io_pool);
- return -ENOMEM;
}
static int crypt_status(struct dm_target *ti, status_type_t type,
@@ -883,14 +952,71 @@ static int crypt_status(struct dm_target *ti, status_type_t type,
return 0;
}
+static void crypt_postsuspend(struct dm_target *ti)
+{
+ struct crypt_config *cc = ti->private;
+
+ set_bit(DM_CRYPT_SUSPENDED, &cc->flags);
+}
+
+static int crypt_preresume(struct dm_target *ti)
+{
+ struct crypt_config *cc = ti->private;
+
+ if (!test_bit(DM_CRYPT_KEY_VALID, &cc->flags)) {
+ DMERR("aborting resume - crypt key is not set.");
+ return -EAGAIN;
+ }
+
+ return 0;
+}
+
+static void crypt_resume(struct dm_target *ti)
+{
+ struct crypt_config *cc = ti->private;
+
+ clear_bit(DM_CRYPT_SUSPENDED, &cc->flags);
+}
+
+/* Message interface
+ * key set <key>
+ * key wipe
+ */
+static int crypt_message(struct dm_target *ti, unsigned argc, char **argv)
+{
+ struct crypt_config *cc = ti->private;
+
+ if (argc < 2)
+ goto error;
+
+ if (!strnicmp(argv[0], MESG_STR("key"))) {
+ if (!test_bit(DM_CRYPT_SUSPENDED, &cc->flags)) {
+ DMWARN("not suspended during key manipulation.");
+ return -EINVAL;
+ }
+ if (argc == 3 && !strnicmp(argv[1], MESG_STR("set")))
+ return crypt_set_key(cc, argv[2]);
+ if (argc == 2 && !strnicmp(argv[1], MESG_STR("wipe")))
+ return crypt_wipe_key(cc);
+ }
+
+error:
+ DMWARN("unrecognised message received.");
+ return -EINVAL;
+}
+
static struct target_type crypt_target = {
.name = "crypt",
- .version= {1, 1, 0},
+ .version= {1, 3, 0},
.module = THIS_MODULE,
.ctr = crypt_ctr,
.dtr = crypt_dtr,
.map = crypt_map,
.status = crypt_status,
+ .postsuspend = crypt_postsuspend,
+ .preresume = crypt_preresume,
+ .resume = crypt_resume,
+ .message = crypt_message,
};
static int __init dm_crypt_init(void)
diff --git a/drivers/md/dm-emc.c b/drivers/md/dm-emc.c
index 2a374ccb30dd..2b2d45d7baaa 100644
--- a/drivers/md/dm-emc.c
+++ b/drivers/md/dm-emc.c
@@ -126,7 +126,8 @@ static struct request *get_failover_req(struct emc_handler *h,
memset(&rq->cmd, 0, BLK_MAX_CDB);
rq->timeout = EMC_FAILOVER_TIMEOUT;
- rq->flags |= (REQ_BLOCK_PC | REQ_FAILFAST | REQ_NOMERGE);
+ rq->cmd_type = REQ_TYPE_BLOCK_PC;
+ rq->cmd_flags |= REQ_FAILFAST | REQ_NOMERGE;
return rq;
}
diff --git a/drivers/md/dm-exception-store.c b/drivers/md/dm-exception-store.c
index d12379b5cdb5..99cdffa7fbfe 100644
--- a/drivers/md/dm-exception-store.c
+++ b/drivers/md/dm-exception-store.c
@@ -17,6 +17,7 @@
#include <linux/slab.h>
#define DM_MSG_PREFIX "snapshots"
+#define DM_CHUNK_SIZE_DEFAULT_SECTORS 32 /* 16KB */
/*-----------------------------------------------------------------
* Persistent snapshots, by persistent we mean that the snapshot
@@ -150,6 +151,7 @@ static int alloc_area(struct pstore *ps)
static void free_area(struct pstore *ps)
{
vfree(ps->area);
+ ps->area = NULL;
}
/*
@@ -198,48 +200,79 @@ static int read_header(struct pstore *ps, int *new_snapshot)
int r;
struct disk_header *dh;
chunk_t chunk_size;
+ int chunk_size_supplied = 1;
- r = chunk_io(ps, 0, READ);
+ /*
+ * Use default chunk size (or hardsect_size, if larger) if none supplied
+ */
+ if (!ps->snap->chunk_size) {
+ ps->snap->chunk_size = max(DM_CHUNK_SIZE_DEFAULT_SECTORS,
+ bdev_hardsect_size(ps->snap->cow->bdev) >> 9);
+ ps->snap->chunk_mask = ps->snap->chunk_size - 1;
+ ps->snap->chunk_shift = ffs(ps->snap->chunk_size) - 1;
+ chunk_size_supplied = 0;
+ }
+
+ r = dm_io_get(sectors_to_pages(ps->snap->chunk_size));
if (r)
return r;
+ r = alloc_area(ps);
+ if (r)
+ goto bad1;
+
+ r = chunk_io(ps, 0, READ);
+ if (r)
+ goto bad2;
+
dh = (struct disk_header *) ps->area;
if (le32_to_cpu(dh->magic) == 0) {
*new_snapshot = 1;
+ return 0;
+ }
- } else if (le32_to_cpu(dh->magic) == SNAP_MAGIC) {
- *new_snapshot = 0;
- ps->valid = le32_to_cpu(dh->valid);
- ps->version = le32_to_cpu(dh->version);
- chunk_size = le32_to_cpu(dh->chunk_size);
- if (ps->snap->chunk_size != chunk_size) {
- DMWARN("chunk size %llu in device metadata overrides "
- "table chunk size of %llu.",
- (unsigned long long)chunk_size,
- (unsigned long long)ps->snap->chunk_size);
-
- /* We had a bogus chunk_size. Fix stuff up. */
- dm_io_put(sectors_to_pages(ps->snap->chunk_size));
- free_area(ps);
-
- ps->snap->chunk_size = chunk_size;
- ps->snap->chunk_mask = chunk_size - 1;
- ps->snap->chunk_shift = ffs(chunk_size) - 1;
-
- r = alloc_area(ps);
- if (r)
- return r;
-
- r = dm_io_get(sectors_to_pages(chunk_size));
- if (r)
- return r;
- }
- } else {
- DMWARN("Invalid/corrupt snapshot");
+ if (le32_to_cpu(dh->magic) != SNAP_MAGIC) {
+ DMWARN("Invalid or corrupt snapshot");
r = -ENXIO;
+ goto bad2;
}
+ *new_snapshot = 0;
+ ps->valid = le32_to_cpu(dh->valid);
+ ps->version = le32_to_cpu(dh->version);
+ chunk_size = le32_to_cpu(dh->chunk_size);
+
+ if (!chunk_size_supplied || ps->snap->chunk_size == chunk_size)
+ return 0;
+
+ DMWARN("chunk size %llu in device metadata overrides "
+ "table chunk size of %llu.",
+ (unsigned long long)chunk_size,
+ (unsigned long long)ps->snap->chunk_size);
+
+ /* We had a bogus chunk_size. Fix stuff up. */
+ dm_io_put(sectors_to_pages(ps->snap->chunk_size));
+ free_area(ps);
+
+ ps->snap->chunk_size = chunk_size;
+ ps->snap->chunk_mask = chunk_size - 1;
+ ps->snap->chunk_shift = ffs(chunk_size) - 1;
+
+ r = dm_io_get(sectors_to_pages(chunk_size));
+ if (r)
+ return r;
+
+ r = alloc_area(ps);
+ if (r)
+ goto bad1;
+
+ return 0;
+
+bad2:
+ free_area(ps);
+bad1:
+ dm_io_put(sectors_to_pages(ps->snap->chunk_size));
return r;
}
@@ -263,42 +296,29 @@ static int write_header(struct pstore *ps)
*/
static struct disk_exception *get_exception(struct pstore *ps, uint32_t index)
{
- if (index >= ps->exceptions_per_area)
- return NULL;
+ BUG_ON(index >= ps->exceptions_per_area);
return ((struct disk_exception *) ps->area) + index;
}
-static int read_exception(struct pstore *ps,
- uint32_t index, struct disk_exception *result)
+static void read_exception(struct pstore *ps,
+ uint32_t index, struct disk_exception *result)
{
- struct disk_exception *e;
-
- e = get_exception(ps, index);
- if (!e)
- return -EINVAL;
+ struct disk_exception *e = get_exception(ps, index);
/* copy it */
result->old_chunk = le64_to_cpu(e->old_chunk);
result->new_chunk = le64_to_cpu(e->new_chunk);
-
- return 0;
}
-static int write_exception(struct pstore *ps,
- uint32_t index, struct disk_exception *de)
+static void write_exception(struct pstore *ps,
+ uint32_t index, struct disk_exception *de)
{
- struct disk_exception *e;
-
- e = get_exception(ps, index);
- if (!e)
- return -EINVAL;
+ struct disk_exception *e = get_exception(ps, index);
/* copy it */
e->old_chunk = cpu_to_le64(de->old_chunk);
e->new_chunk = cpu_to_le64(de->new_chunk);
-
- return 0;
}
/*
@@ -316,10 +336,7 @@ static int insert_exceptions(struct pstore *ps, int *full)
*full = 1;
for (i = 0; i < ps->exceptions_per_area; i++) {
- r = read_exception(ps, i, &de);
-
- if (r)
- return r;
+ read_exception(ps, i, &de);
/*
* If the new_chunk is pointing at the start of
@@ -519,6 +536,16 @@ static void persistent_commit(struct exception_store *store,
if (r)
ps->valid = 0;
+ /*
+ * Have we completely filled the current area ?
+ */
+ if (ps->current_committed == ps->exceptions_per_area) {
+ ps->current_committed = 0;
+ r = zero_area(ps, ps->current_area + 1);
+ if (r)
+ ps->valid = 0;
+ }
+
for (i = 0; i < ps->callback_count; i++) {
cb = ps->callbacks + i;
cb->callback(cb->context, r == 0 ? 1 : 0);
@@ -526,16 +553,6 @@ static void persistent_commit(struct exception_store *store,
ps->callback_count = 0;
}
-
- /*
- * Have we completely filled the current area ?
- */
- if (ps->current_committed == ps->exceptions_per_area) {
- ps->current_committed = 0;
- r = zero_area(ps, ps->current_area + 1);
- if (r)
- ps->valid = 0;
- }
}
static void persistent_drop(struct exception_store *store)
@@ -547,32 +564,22 @@ static void persistent_drop(struct exception_store *store)
DMWARN("write header failed");
}
-int dm_create_persistent(struct exception_store *store, uint32_t chunk_size)
+int dm_create_persistent(struct exception_store *store)
{
- int r;
struct pstore *ps;
- r = dm_io_get(sectors_to_pages(chunk_size));
- if (r)
- return r;
-
/* allocate the pstore */
ps = kmalloc(sizeof(*ps), GFP_KERNEL);
- if (!ps) {
- r = -ENOMEM;
- goto bad;
- }
+ if (!ps)
+ return -ENOMEM;
ps->snap = store->snap;
ps->valid = 1;
ps->version = SNAPSHOT_DISK_VERSION;
+ ps->area = NULL;
ps->next_free = 2; /* skipping the header and first area */
ps->current_committed = 0;
- r = alloc_area(ps);
- if (r)
- goto bad;
-
ps->callback_count = 0;
atomic_set(&ps->pending_count, 0);
ps->callbacks = NULL;
@@ -586,13 +593,6 @@ int dm_create_persistent(struct exception_store *store, uint32_t chunk_size)
store->context = ps;
return 0;
-
- bad:
- dm_io_put(sectors_to_pages(chunk_size));
- if (ps && ps->area)
- free_area(ps);
- kfree(ps);
- return r;
}
/*-----------------------------------------------------------------
@@ -642,18 +642,16 @@ static void transient_fraction_full(struct exception_store *store,
*denominator = get_dev_size(store->snap->cow->bdev);
}
-int dm_create_transient(struct exception_store *store,
- struct dm_snapshot *s, int blocksize)
+int dm_create_transient(struct exception_store *store)
{
struct transient_c *tc;
- memset(store, 0, sizeof(*store));
store->destroy = transient_destroy;
store->read_metadata = transient_read_metadata;
store->prepare_exception = transient_prepare;
store->commit_exception = transient_commit;
+ store->drop_snapshot = NULL;
store->fraction_full = transient_fraction_full;
- store->snap = s;
tc = kmalloc(sizeof(struct transient_c), GFP_KERNEL);
if (!tc)
diff --git a/drivers/md/dm-linear.c b/drivers/md/dm-linear.c
index 47b3c62bbdb8..00234909b3db 100644
--- a/drivers/md/dm-linear.c
+++ b/drivers/md/dm-linear.c
@@ -98,14 +98,31 @@ static int linear_status(struct dm_target *ti, status_type_t type,
return 0;
}
+static int linear_ioctl(struct dm_target *ti, struct inode *inode,
+ struct file *filp, unsigned int cmd,
+ unsigned long arg)
+{
+ struct linear_c *lc = (struct linear_c *) ti->private;
+ struct block_device *bdev = lc->dev->bdev;
+ struct file fake_file = {};
+ struct dentry fake_dentry = {};
+
+ fake_file.f_mode = lc->dev->mode;
+ fake_file.f_dentry = &fake_dentry;
+ fake_dentry.d_inode = bdev->bd_inode;
+
+ return blkdev_driver_ioctl(bdev->bd_inode, &fake_file, bdev->bd_disk, cmd, arg);
+}
+
static struct target_type linear_target = {
.name = "linear",
- .version= {1, 0, 1},
+ .version= {1, 0, 2},
.module = THIS_MODULE,
.ctr = linear_ctr,
.dtr = linear_dtr,
.map = linear_map,
.status = linear_status,
+ .ioctl = linear_ioctl,
};
int __init dm_linear_init(void)
diff --git a/drivers/md/dm-mpath.c b/drivers/md/dm-mpath.c
index 93f701ea87bc..d754e0bc6e90 100644
--- a/drivers/md/dm-mpath.c
+++ b/drivers/md/dm-mpath.c
@@ -114,12 +114,10 @@ static void trigger_event(void *data);
static struct pgpath *alloc_pgpath(void)
{
- struct pgpath *pgpath = kmalloc(sizeof(*pgpath), GFP_KERNEL);
+ struct pgpath *pgpath = kzalloc(sizeof(*pgpath), GFP_KERNEL);
- if (pgpath) {
- memset(pgpath, 0, sizeof(*pgpath));
+ if (pgpath)
pgpath->path.is_active = 1;
- }
return pgpath;
}
@@ -133,12 +131,10 @@ static struct priority_group *alloc_priority_group(void)
{
struct priority_group *pg;
- pg = kmalloc(sizeof(*pg), GFP_KERNEL);
- if (!pg)
- return NULL;
+ pg = kzalloc(sizeof(*pg), GFP_KERNEL);
- memset(pg, 0, sizeof(*pg));
- INIT_LIST_HEAD(&pg->pgpaths);
+ if (pg)
+ INIT_LIST_HEAD(&pg->pgpaths);
return pg;
}
@@ -168,13 +164,12 @@ static void free_priority_group(struct priority_group *pg,
kfree(pg);
}
-static struct multipath *alloc_multipath(void)
+static struct multipath *alloc_multipath(struct dm_target *ti)
{
struct multipath *m;
- m = kmalloc(sizeof(*m), GFP_KERNEL);
+ m = kzalloc(sizeof(*m), GFP_KERNEL);
if (m) {
- memset(m, 0, sizeof(*m));
INIT_LIST_HEAD(&m->priority_groups);
spin_lock_init(&m->lock);
m->queue_io = 1;
@@ -185,6 +180,8 @@ static struct multipath *alloc_multipath(void)
kfree(m);
return NULL;
}
+ m->ti = ti;
+ ti->private = m;
}
return m;
@@ -557,8 +554,7 @@ static struct pgpath *parse_path(struct arg_set *as, struct path_selector *ps,
}
static struct priority_group *parse_priority_group(struct arg_set *as,
- struct multipath *m,
- struct dm_target *ti)
+ struct multipath *m)
{
static struct param _params[] = {
{1, 1024, "invalid number of paths"},
@@ -568,6 +564,7 @@ static struct priority_group *parse_priority_group(struct arg_set *as,
int r;
unsigned i, nr_selector_args, nr_params;
struct priority_group *pg;
+ struct dm_target *ti = m->ti;
if (as->argc < 2) {
as->argc = 0;
@@ -624,12 +621,12 @@ static struct priority_group *parse_priority_group(struct arg_set *as,
return NULL;
}
-static int parse_hw_handler(struct arg_set *as, struct multipath *m,
- struct dm_target *ti)
+static int parse_hw_handler(struct arg_set *as, struct multipath *m)
{
int r;
struct hw_handler_type *hwht;
unsigned hw_argc;
+ struct dm_target *ti = m->ti;
static struct param _params[] = {
{0, 1024, "invalid number of hardware handler args"},
@@ -661,11 +658,11 @@ static int parse_hw_handler(struct arg_set *as, struct multipath *m,
return 0;
}
-static int parse_features(struct arg_set *as, struct multipath *m,
- struct dm_target *ti)
+static int parse_features(struct arg_set *as, struct multipath *m)
{
int r;
unsigned argc;
+ struct dm_target *ti = m->ti;
static struct param _params[] = {
{0, 1, "invalid number of feature args"},
@@ -704,19 +701,17 @@ static int multipath_ctr(struct dm_target *ti, unsigned int argc,
as.argc = argc;
as.argv = argv;
- m = alloc_multipath();
+ m = alloc_multipath(ti);
if (!m) {
ti->error = "can't allocate multipath";
return -EINVAL;
}
- m->ti = ti;
-
- r = parse_features(&as, m, ti);
+ r = parse_features(&as, m);
if (r)
goto bad;
- r = parse_hw_handler(&as, m, ti);
+ r = parse_hw_handler(&as, m);
if (r)
goto bad;
@@ -732,7 +727,7 @@ static int multipath_ctr(struct dm_target *ti, unsigned int argc,
while (as.argc) {
struct priority_group *pg;
- pg = parse_priority_group(&as, m, ti);
+ pg = parse_priority_group(&as, m);
if (!pg) {
r = -EINVAL;
goto bad;
@@ -752,8 +747,6 @@ static int multipath_ctr(struct dm_target *ti, unsigned int argc,
goto bad;
}
- ti->private = m;
-
return 0;
bad:
@@ -1266,12 +1259,47 @@ error:
return -EINVAL;
}
+static int multipath_ioctl(struct dm_target *ti, struct inode *inode,
+ struct file *filp, unsigned int cmd,
+ unsigned long arg)
+{
+ struct multipath *m = (struct multipath *) ti->private;
+ struct block_device *bdev = NULL;
+ unsigned long flags;
+ struct file fake_file = {};
+ struct dentry fake_dentry = {};
+ int r = 0;
+
+ fake_file.f_dentry = &fake_dentry;
+
+ spin_lock_irqsave(&m->lock, flags);
+
+ if (!m->current_pgpath)
+ __choose_pgpath(m);
+
+ if (m->current_pgpath) {
+ bdev = m->current_pgpath->path.dev->bdev;
+ fake_dentry.d_inode = bdev->bd_inode;
+ fake_file.f_mode = m->current_pgpath->path.dev->mode;
+ }
+
+ if (m->queue_io)
+ r = -EAGAIN;
+ else if (!bdev)
+ r = -EIO;
+
+ spin_unlock_irqrestore(&m->lock, flags);
+
+ return r ? : blkdev_driver_ioctl(bdev->bd_inode, &fake_file,
+ bdev->bd_disk, cmd, arg);
+}
+
/*-----------------------------------------------------------------
* Module setup
*---------------------------------------------------------------*/
static struct target_type multipath_target = {
.name = "multipath",
- .version = {1, 0, 4},
+ .version = {1, 0, 5},
.module = THIS_MODULE,
.ctr = multipath_ctr,
.dtr = multipath_dtr,
@@ -1281,6 +1309,7 @@ static struct target_type multipath_target = {
.resume = multipath_resume,
.status = multipath_status,
.message = multipath_message,
+ .ioctl = multipath_ioctl,
};
static int __init dm_multipath_init(void)
diff --git a/drivers/md/dm-raid1.c b/drivers/md/dm-raid1.c
index c54de989eb00..659224cb7c53 100644
--- a/drivers/md/dm-raid1.c
+++ b/drivers/md/dm-raid1.c
@@ -1213,9 +1213,9 @@ static int mirror_status(struct dm_target *ti, status_type_t type,
break;
case STATUSTYPE_TABLE:
- DMEMIT("%d ", ms->nr_mirrors);
+ DMEMIT("%d", ms->nr_mirrors);
for (m = 0; m < ms->nr_mirrors; m++)
- DMEMIT("%s %llu ", ms->mirror[m].dev->name,
+ DMEMIT(" %s %llu", ms->mirror[m].dev->name,
(unsigned long long)ms->mirror[m].offset);
}
diff --git a/drivers/md/dm-snap.c b/drivers/md/dm-snap.c
index 1d0fafda0f76..5281e0094072 100644
--- a/drivers/md/dm-snap.c
+++ b/drivers/md/dm-snap.c
@@ -39,6 +39,9 @@
*/
#define SNAPSHOT_PAGES 256
+struct workqueue_struct *ksnapd;
+static void flush_queued_bios(void *data);
+
struct pending_exception {
struct exception e;
@@ -56,7 +59,7 @@ struct pending_exception {
/*
* The primary pending_exception is the one that holds
- * the sibling_count and the list of origin_bios for a
+ * the ref_count and the list of origin_bios for a
* group of pending_exceptions. It is always last to get freed.
* These fields get set up when writing to the origin.
*/
@@ -69,7 +72,7 @@ struct pending_exception {
* the sibling concerned and not pe->primary_pe->snap->lock unless
* they are the same.
*/
- atomic_t sibling_count;
+ atomic_t ref_count;
/* Pointer back to snapshot context */
struct dm_snapshot *snap;
@@ -387,15 +390,46 @@ static inline ulong round_up(ulong n, ulong size)
return (n + size) & ~size;
}
-static void read_snapshot_metadata(struct dm_snapshot *s)
+static int set_chunk_size(struct dm_snapshot *s, const char *chunk_size_arg,
+ char **error)
{
- if (s->store.read_metadata(&s->store)) {
- down_write(&s->lock);
- s->valid = 0;
- up_write(&s->lock);
+ unsigned long chunk_size;
+ char *value;
+
+ chunk_size = simple_strtoul(chunk_size_arg, &value, 10);
+ if (*chunk_size_arg == '\0' || *value != '\0') {
+ *error = "Invalid chunk size";
+ return -EINVAL;
+ }
+
+ if (!chunk_size) {
+ s->chunk_size = s->chunk_mask = s->chunk_shift = 0;
+ return 0;
+ }
+
+ /*
+ * Chunk size must be multiple of page size. Silently
+ * round up if it's not.
+ */
+ chunk_size = round_up(chunk_size, PAGE_SIZE >> 9);
+
+ /* Check chunk_size is a power of 2 */
+ if (chunk_size & (chunk_size - 1)) {
+ *error = "Chunk size is not a power of 2";
+ return -EINVAL;
+ }
- dm_table_event(s->table);
+ /* Validate the chunk size against the device block size */
+ if (chunk_size % (bdev_hardsect_size(s->cow->bdev) >> 9)) {
+ *error = "Chunk size is not a multiple of device blocksize";
+ return -EINVAL;
}
+
+ s->chunk_size = chunk_size;
+ s->chunk_mask = chunk_size - 1;
+ s->chunk_shift = ffs(chunk_size) - 1;
+
+ return 0;
}
/*
@@ -404,15 +438,12 @@ static void read_snapshot_metadata(struct dm_snapshot *s)
static int snapshot_ctr(struct dm_target *ti, unsigned int argc, char **argv)
{
struct dm_snapshot *s;
- unsigned long chunk_size;
int r = -EINVAL;
char persistent;
char *origin_path;
char *cow_path;
- char *value;
- int blocksize;
- if (argc < 4) {
+ if (argc != 4) {
ti->error = "requires exactly 4 arguments";
r = -EINVAL;
goto bad1;
@@ -428,13 +459,6 @@ static int snapshot_ctr(struct dm_target *ti, unsigned int argc, char **argv)
goto bad1;
}
- chunk_size = simple_strtoul(argv[3], &value, 10);
- if (chunk_size == 0 || value == NULL) {
- ti->error = "Invalid chunk size";
- r = -EINVAL;
- goto bad1;
- }
-
s = kmalloc(sizeof(*s), GFP_KERNEL);
if (s == NULL) {
ti->error = "Cannot allocate snapshot context private "
@@ -457,36 +481,17 @@ static int snapshot_ctr(struct dm_target *ti, unsigned int argc, char **argv)
goto bad2;
}
- /*
- * Chunk size must be multiple of page size. Silently
- * round up if it's not.
- */
- chunk_size = round_up(chunk_size, PAGE_SIZE >> 9);
-
- /* Validate the chunk size against the device block size */
- blocksize = s->cow->bdev->bd_disk->queue->hardsect_size;
- if (chunk_size % (blocksize >> 9)) {
- ti->error = "Chunk size is not a multiple of device blocksize";
- r = -EINVAL;
- goto bad3;
- }
-
- /* Check chunk_size is a power of 2 */
- if (chunk_size & (chunk_size - 1)) {
- ti->error = "Chunk size is not a power of 2";
- r = -EINVAL;
+ r = set_chunk_size(s, argv[3], &ti->error);
+ if (r)
goto bad3;
- }
- s->chunk_size = chunk_size;
- s->chunk_mask = chunk_size - 1;
s->type = persistent;
- s->chunk_shift = ffs(chunk_size) - 1;
s->valid = 1;
s->active = 0;
s->last_percent = 0;
init_rwsem(&s->lock);
+ spin_lock_init(&s->pe_lock);
s->table = ti->table;
/* Allocate hash table for COW data */
@@ -496,16 +501,12 @@ static int snapshot_ctr(struct dm_target *ti, unsigned int argc, char **argv)
goto bad3;
}
- /*
- * Check the persistent flag - done here because we need the iobuf
- * to check the LV header
- */
s->store.snap = s;
if (persistent == 'P')
- r = dm_create_persistent(&s->store, chunk_size);
+ r = dm_create_persistent(&s->store);
else
- r = dm_create_transient(&s->store, s, blocksize);
+ r = dm_create_transient(&s->store);
if (r) {
ti->error = "Couldn't create exception store";
@@ -520,7 +521,14 @@ static int snapshot_ctr(struct dm_target *ti, unsigned int argc, char **argv)
}
/* Metadata must only be loaded into one table at once */
- read_snapshot_metadata(s);
+ r = s->store.read_metadata(&s->store);
+ if (r) {
+ ti->error = "Failed to read snapshot metadata";
+ goto bad6;
+ }
+
+ bio_list_init(&s->queued_bios);
+ INIT_WORK(&s->queued_bios_work, flush_queued_bios, s);
/* Add snapshot to the list of snapshots for this origin */
/* Exceptions aren't triggered till snapshot_resume() is called */
@@ -560,6 +568,8 @@ static void snapshot_dtr(struct dm_target *ti)
{
struct dm_snapshot *s = (struct dm_snapshot *) ti->private;
+ flush_workqueue(ksnapd);
+
/* Prevent further origin writes from using this snapshot. */
/* After this returns there can be no new kcopyd jobs. */
unregister_snapshot(s);
@@ -593,6 +603,19 @@ static void flush_bios(struct bio *bio)
}
}
+static void flush_queued_bios(void *data)
+{
+ struct dm_snapshot *s = (struct dm_snapshot *) data;
+ struct bio *queued_bios;
+ unsigned long flags;
+
+ spin_lock_irqsave(&s->pe_lock, flags);
+ queued_bios = bio_list_get(&s->queued_bios);
+ spin_unlock_irqrestore(&s->pe_lock, flags);
+
+ flush_bios(queued_bios);
+}
+
/*
* Error a list of buffers.
*/
@@ -608,28 +631,7 @@ static void error_bios(struct bio *bio)
}
}
-static inline void error_snapshot_bios(struct pending_exception *pe)
-{
- error_bios(bio_list_get(&pe->snapshot_bios));
-}
-
-static struct bio *__flush_bios(struct pending_exception *pe)
-{
- /*
- * If this pe is involved in a write to the origin and
- * it is the last sibling to complete then release
- * the bios for the original write to the origin.
- */
-
- if (pe->primary_pe &&
- atomic_dec_and_test(&pe->primary_pe->sibling_count))
- return bio_list_get(&pe->primary_pe->origin_bios);
-
- return NULL;
-}
-
-static void __invalidate_snapshot(struct dm_snapshot *s,
- struct pending_exception *pe, int err)
+static void __invalidate_snapshot(struct dm_snapshot *s, int err)
{
if (!s->valid)
return;
@@ -639,9 +641,6 @@ static void __invalidate_snapshot(struct dm_snapshot *s,
else if (err == -ENOMEM)
DMERR("Invalidating snapshot: Unable to allocate exception.");
- if (pe)
- remove_exception(&pe->e);
-
if (s->store.drop_snapshot)
s->store.drop_snapshot(&s->store);
@@ -650,78 +649,95 @@ static void __invalidate_snapshot(struct dm_snapshot *s,
dm_table_event(s->table);
}
+static void get_pending_exception(struct pending_exception *pe)
+{
+ atomic_inc(&pe->ref_count);
+}
+
+static struct bio *put_pending_exception(struct pending_exception *pe)
+{
+ struct pending_exception *primary_pe;
+ struct bio *origin_bios = NULL;
+
+ primary_pe = pe->primary_pe;
+
+ /*
+ * If this pe is involved in a write to the origin and
+ * it is the last sibling to complete then release
+ * the bios for the original write to the origin.
+ */
+ if (primary_pe &&
+ atomic_dec_and_test(&primary_pe->ref_count))
+ origin_bios = bio_list_get(&primary_pe->origin_bios);
+
+ /*
+ * Free the pe if it's not linked to an origin write or if
+ * it's not itself a primary pe.
+ */
+ if (!primary_pe || primary_pe != pe)
+ free_pending_exception(pe);
+
+ /*
+ * Free the primary pe if nothing references it.
+ */
+ if (primary_pe && !atomic_read(&primary_pe->ref_count))
+ free_pending_exception(primary_pe);
+
+ return origin_bios;
+}
+
static void pending_complete(struct pending_exception *pe, int success)
{
struct exception *e;
- struct pending_exception *primary_pe;
struct dm_snapshot *s = pe->snap;
- struct bio *flush = NULL;
+ struct bio *origin_bios = NULL;
+ struct bio *snapshot_bios = NULL;
+ int error = 0;
if (!success) {
/* Read/write error - snapshot is unusable */
down_write(&s->lock);
- __invalidate_snapshot(s, pe, -EIO);
- flush = __flush_bios(pe);
- up_write(&s->lock);
-
- error_snapshot_bios(pe);
+ __invalidate_snapshot(s, -EIO);
+ error = 1;
goto out;
}
e = alloc_exception();
if (!e) {
down_write(&s->lock);
- __invalidate_snapshot(s, pe, -ENOMEM);
- flush = __flush_bios(pe);
- up_write(&s->lock);
-
- error_snapshot_bios(pe);
+ __invalidate_snapshot(s, -ENOMEM);
+ error = 1;
goto out;
}
*e = pe->e;
- /*
- * Add a proper exception, and remove the
- * in-flight exception from the list.
- */
down_write(&s->lock);
if (!s->valid) {
- flush = __flush_bios(pe);
- up_write(&s->lock);
-
free_exception(e);
-
- error_snapshot_bios(pe);
+ error = 1;
goto out;
}
+ /*
+ * Add a proper exception, and remove the
+ * in-flight exception from the list.
+ */
insert_exception(&s->complete, e);
+
+ out:
remove_exception(&pe->e);
- flush = __flush_bios(pe);
+ snapshot_bios = bio_list_get(&pe->snapshot_bios);
+ origin_bios = put_pending_exception(pe);
up_write(&s->lock);
/* Submit any pending write bios */
- flush_bios(bio_list_get(&pe->snapshot_bios));
-
- out:
- primary_pe = pe->primary_pe;
-
- /*
- * Free the pe if it's not linked to an origin write or if
- * it's not itself a primary pe.
- */
- if (!primary_pe || primary_pe != pe)
- free_pending_exception(pe);
-
- /*
- * Free the primary pe if nothing references it.
- */
- if (primary_pe && !atomic_read(&primary_pe->sibling_count))
- free_pending_exception(primary_pe);
+ if (error)
+ error_bios(snapshot_bios);
+ else
+ flush_bios(snapshot_bios);
- if (flush)
- flush_bios(flush);
+ flush_bios(origin_bios);
}
static void commit_callback(void *context, int success)
@@ -822,7 +838,7 @@ __find_pending_exception(struct dm_snapshot *s, struct bio *bio)
bio_list_init(&pe->origin_bios);
bio_list_init(&pe->snapshot_bios);
pe->primary_pe = NULL;
- atomic_set(&pe->sibling_count, 1);
+ atomic_set(&pe->ref_count, 0);
pe->snap = s;
pe->started = 0;
@@ -831,6 +847,7 @@ __find_pending_exception(struct dm_snapshot *s, struct bio *bio)
return NULL;
}
+ get_pending_exception(pe);
insert_exception(&s->pending, &pe->e);
out:
@@ -850,7 +867,6 @@ static int snapshot_map(struct dm_target *ti, struct bio *bio,
{
struct exception *e;
struct dm_snapshot *s = (struct dm_snapshot *) ti->private;
- int copy_needed = 0;
int r = 1;
chunk_t chunk;
struct pending_exception *pe = NULL;
@@ -865,32 +881,31 @@ static int snapshot_map(struct dm_target *ti, struct bio *bio,
if (unlikely(bio_barrier(bio)))
return -EOPNOTSUPP;
+ /* FIXME: should only take write lock if we need
+ * to copy an exception */
+ down_write(&s->lock);
+
+ if (!s->valid) {
+ r = -EIO;
+ goto out_unlock;
+ }
+
+ /* If the block is already remapped - use that, else remap it */
+ e = lookup_exception(&s->complete, chunk);
+ if (e) {
+ remap_exception(s, e, bio);
+ goto out_unlock;
+ }
+
/*
* Write to snapshot - higher level takes care of RW/RO
* flags so we should only get this if we are
* writeable.
*/
if (bio_rw(bio) == WRITE) {
-
- /* FIXME: should only take write lock if we need
- * to copy an exception */
- down_write(&s->lock);
-
- if (!s->valid) {
- r = -EIO;
- goto out_unlock;
- }
-
- /* If the block is already remapped - use that, else remap it */
- e = lookup_exception(&s->complete, chunk);
- if (e) {
- remap_exception(s, e, bio);
- goto out_unlock;
- }
-
pe = __find_pending_exception(s, bio);
if (!pe) {
- __invalidate_snapshot(s, pe, -ENOMEM);
+ __invalidate_snapshot(s, -ENOMEM);
r = -EIO;
goto out_unlock;
}
@@ -898,45 +913,27 @@ static int snapshot_map(struct dm_target *ti, struct bio *bio,
remap_exception(s, &pe->e, bio);
bio_list_add(&pe->snapshot_bios, bio);
+ r = 0;
+
if (!pe->started) {
/* this is protected by snap->lock */
pe->started = 1;
- copy_needed = 1;
- }
-
- r = 0;
-
- out_unlock:
- up_write(&s->lock);
-
- if (copy_needed)
+ up_write(&s->lock);
start_copy(pe);
- } else {
+ goto out;
+ }
+ } else
/*
* FIXME: this read path scares me because we
* always use the origin when we have a pending
* exception. However I can't think of a
* situation where this is wrong - ejt.
*/
+ bio->bi_bdev = s->origin->bdev;
- /* Do reads */
- down_read(&s->lock);
-
- if (!s->valid) {
- up_read(&s->lock);
- return -EIO;
- }
-
- /* See if it it has been remapped */
- e = lookup_exception(&s->complete, chunk);
- if (e)
- remap_exception(s, e, bio);
- else
- bio->bi_bdev = s->origin->bdev;
-
- up_read(&s->lock);
- }
-
+ out_unlock:
+ up_write(&s->lock);
+ out:
return r;
}
@@ -1025,7 +1022,7 @@ static int __origin_write(struct list_head *snapshots, struct bio *bio)
* is already remapped in this snapshot
* and trigger an exception if not.
*
- * sibling_count is initialised to 1 so pending_complete()
+ * ref_count is initialised to 1 so pending_complete()
* won't destroy the primary_pe while we're inside this loop.
*/
e = lookup_exception(&snap->complete, chunk);
@@ -1034,7 +1031,7 @@ static int __origin_write(struct list_head *snapshots, struct bio *bio)
pe = __find_pending_exception(snap, bio);
if (!pe) {
- __invalidate_snapshot(snap, pe, ENOMEM);
+ __invalidate_snapshot(snap, -ENOMEM);
goto next_snapshot;
}
@@ -1056,8 +1053,8 @@ static int __origin_write(struct list_head *snapshots, struct bio *bio)
}
if (!pe->primary_pe) {
- atomic_inc(&primary_pe->sibling_count);
pe->primary_pe = primary_pe;
+ get_pending_exception(primary_pe);
}
if (!pe->started) {
@@ -1070,20 +1067,20 @@ static int __origin_write(struct list_head *snapshots, struct bio *bio)
}
if (!primary_pe)
- goto out;
+ return r;
/*
* If this is the first time we're processing this chunk and
- * sibling_count is now 1 it means all the pending exceptions
+ * ref_count is now 1 it means all the pending exceptions
* got completed while we were in the loop above, so it falls to
* us here to remove the primary_pe and submit any origin_bios.
*/
- if (first && atomic_dec_and_test(&primary_pe->sibling_count)) {
+ if (first && atomic_dec_and_test(&primary_pe->ref_count)) {
flush_bios(bio_list_get(&primary_pe->origin_bios));
free_pending_exception(primary_pe);
/* If we got here, pe_queue is necessarily empty. */
- goto out;
+ return r;
}
/*
@@ -1092,7 +1089,6 @@ static int __origin_write(struct list_head *snapshots, struct bio *bio)
list_for_each_entry_safe(pe, next_pe, &pe_queue, list)
start_copy(pe);
- out:
return r;
}
@@ -1205,7 +1201,7 @@ static int origin_status(struct dm_target *ti, status_type_t type, char *result,
static struct target_type origin_target = {
.name = "snapshot-origin",
- .version = {1, 4, 0},
+ .version = {1, 5, 0},
.module = THIS_MODULE,
.ctr = origin_ctr,
.dtr = origin_dtr,
@@ -1216,7 +1212,7 @@ static struct target_type origin_target = {
static struct target_type snapshot_target = {
.name = "snapshot",
- .version = {1, 4, 0},
+ .version = {1, 5, 0},
.module = THIS_MODULE,
.ctr = snapshot_ctr,
.dtr = snapshot_dtr,
@@ -1275,8 +1271,17 @@ static int __init dm_snapshot_init(void)
goto bad5;
}
+ ksnapd = create_singlethread_workqueue("ksnapd");
+ if (!ksnapd) {
+ DMERR("Failed to create ksnapd workqueue.");
+ r = -ENOMEM;
+ goto bad6;
+ }
+
return 0;
+ bad6:
+ mempool_destroy(pending_pool);
bad5:
kmem_cache_destroy(pending_cache);
bad4:
@@ -1294,6 +1299,8 @@ static void __exit dm_snapshot_exit(void)
{
int r;
+ destroy_workqueue(ksnapd);
+
r = dm_unregister_target(&snapshot_target);
if (r)
DMERR("snapshot unregister failed %d", r);
diff --git a/drivers/md/dm-snap.h b/drivers/md/dm-snap.h
index fdec1e2dc871..15fa2ae6cdc2 100644
--- a/drivers/md/dm-snap.h
+++ b/drivers/md/dm-snap.h
@@ -10,7 +10,9 @@
#define DM_SNAPSHOT_H
#include "dm.h"
+#include "dm-bio-list.h"
#include <linux/blkdev.h>
+#include <linux/workqueue.h>
struct exception_table {
uint32_t hash_mask;
@@ -112,10 +114,20 @@ struct dm_snapshot {
struct exception_table pending;
struct exception_table complete;
+ /*
+ * pe_lock protects all pending_exception operations and access
+ * as well as the snapshot_bios list.
+ */
+ spinlock_t pe_lock;
+
/* The on disk metadata handler */
struct exception_store store;
struct kcopyd_client *kcopyd_client;
+
+ /* Queue of snapshot writes for ksnapd to flush */
+ struct bio_list queued_bios;
+ struct work_struct queued_bios_work;
};
/*
@@ -128,10 +140,9 @@ int dm_add_exception(struct dm_snapshot *s, chunk_t old, chunk_t new);
* Constructor and destructor for the default persistent
* store.
*/
-int dm_create_persistent(struct exception_store *store, uint32_t chunk_size);
+int dm_create_persistent(struct exception_store *store);
-int dm_create_transient(struct exception_store *store,
- struct dm_snapshot *s, int blocksize);
+int dm_create_transient(struct exception_store *store);
/*
* Return the number of sectors in the device.
diff --git a/drivers/md/dm-table.c b/drivers/md/dm-table.c
index 75fe9493e6af..05befa91807a 100644
--- a/drivers/md/dm-table.c
+++ b/drivers/md/dm-table.c
@@ -522,56 +522,61 @@ static int __table_get_device(struct dm_table *t, struct dm_target *ti,
return 0;
}
-
-int dm_get_device(struct dm_target *ti, const char *path, sector_t start,
- sector_t len, int mode, struct dm_dev **result)
+void dm_set_device_limits(struct dm_target *ti, struct block_device *bdev)
{
- int r = __table_get_device(ti->table, ti, path,
- start, len, mode, result);
- if (!r) {
- request_queue_t *q = bdev_get_queue((*result)->bdev);
- struct io_restrictions *rs = &ti->limits;
-
- /*
- * Combine the device limits low.
- *
- * FIXME: if we move an io_restriction struct
- * into q this would just be a call to
- * combine_restrictions_low()
- */
+ request_queue_t *q = bdev_get_queue(bdev);
+ struct io_restrictions *rs = &ti->limits;
+
+ /*
+ * Combine the device limits low.
+ *
+ * FIXME: if we move an io_restriction struct
+ * into q this would just be a call to
+ * combine_restrictions_low()
+ */
+ rs->max_sectors =
+ min_not_zero(rs->max_sectors, q->max_sectors);
+
+ /* FIXME: Device-Mapper on top of RAID-0 breaks because DM
+ * currently doesn't honor MD's merge_bvec_fn routine.
+ * In this case, we'll force DM to use PAGE_SIZE or
+ * smaller I/O, just to be safe. A better fix is in the
+ * works, but add this for the time being so it will at
+ * least operate correctly.
+ */
+ if (q->merge_bvec_fn)
rs->max_sectors =
- min_not_zero(rs->max_sectors, q->max_sectors);
+ min_not_zero(rs->max_sectors,
+ (unsigned int) (PAGE_SIZE >> 9));
- /* FIXME: Device-Mapper on top of RAID-0 breaks because DM
- * currently doesn't honor MD's merge_bvec_fn routine.
- * In this case, we'll force DM to use PAGE_SIZE or
- * smaller I/O, just to be safe. A better fix is in the
- * works, but add this for the time being so it will at
- * least operate correctly.
- */
- if (q->merge_bvec_fn)
- rs->max_sectors =
- min_not_zero(rs->max_sectors,
- (unsigned int) (PAGE_SIZE >> 9));
+ rs->max_phys_segments =
+ min_not_zero(rs->max_phys_segments,
+ q->max_phys_segments);
- rs->max_phys_segments =
- min_not_zero(rs->max_phys_segments,
- q->max_phys_segments);
+ rs->max_hw_segments =
+ min_not_zero(rs->max_hw_segments, q->max_hw_segments);
- rs->max_hw_segments =
- min_not_zero(rs->max_hw_segments, q->max_hw_segments);
+ rs->hardsect_size = max(rs->hardsect_size, q->hardsect_size);
- rs->hardsect_size = max(rs->hardsect_size, q->hardsect_size);
+ rs->max_segment_size =
+ min_not_zero(rs->max_segment_size, q->max_segment_size);
- rs->max_segment_size =
- min_not_zero(rs->max_segment_size, q->max_segment_size);
+ rs->seg_boundary_mask =
+ min_not_zero(rs->seg_boundary_mask,
+ q->seg_boundary_mask);
- rs->seg_boundary_mask =
- min_not_zero(rs->seg_boundary_mask,
- q->seg_boundary_mask);
+ rs->no_cluster |= !test_bit(QUEUE_FLAG_CLUSTER, &q->queue_flags);
+}
+EXPORT_SYMBOL_GPL(dm_set_device_limits);
- rs->no_cluster |= !test_bit(QUEUE_FLAG_CLUSTER, &q->queue_flags);
- }
+int dm_get_device(struct dm_target *ti, const char *path, sector_t start,
+ sector_t len, int mode, struct dm_dev **result)
+{
+ int r = __table_get_device(ti->table, ti, path,
+ start, len, mode, result);
+
+ if (!r)
+ dm_set_device_limits(ti, (*result)->bdev);
return r;
}
@@ -939,9 +944,20 @@ void dm_table_postsuspend_targets(struct dm_table *t)
return suspend_targets(t, 1);
}
-void dm_table_resume_targets(struct dm_table *t)
+int dm_table_resume_targets(struct dm_table *t)
{
- int i;
+ int i, r = 0;
+
+ for (i = 0; i < t->num_targets; i++) {
+ struct dm_target *ti = t->targets + i;
+
+ if (!ti->type->preresume)
+ continue;
+
+ r = ti->type->preresume(ti);
+ if (r)
+ return r;
+ }
for (i = 0; i < t->num_targets; i++) {
struct dm_target *ti = t->targets + i;
@@ -949,6 +965,8 @@ void dm_table_resume_targets(struct dm_table *t)
if (ti->type->resume)
ti->type->resume(ti);
}
+
+ return 0;
}
int dm_table_any_congested(struct dm_table *t, int bdi_bits)
@@ -983,6 +1001,11 @@ int dm_table_flush_all(struct dm_table *t)
{
struct list_head *d, *devices = dm_table_get_devices(t);
int ret = 0;
+ unsigned i;
+
+ for (i = 0; i < t->num_targets; i++)
+ if (t->targets[i].type->flush)
+ t->targets[i].type->flush(&t->targets[i]);
for (d = devices->next; d != devices; d = d->next) {
struct dm_dev *dd = list_entry(d, struct dm_dev, list);
diff --git a/drivers/md/dm.c b/drivers/md/dm.c
index c99bf9f01759..b5764a86c8b5 100644
--- a/drivers/md/dm.c
+++ b/drivers/md/dm.c
@@ -20,6 +20,7 @@
#include <linux/idr.h>
#include <linux/hdreg.h>
#include <linux/blktrace_api.h>
+#include <linux/smp_lock.h>
#define DM_MSG_PREFIX "core"
@@ -101,6 +102,8 @@ struct mapped_device {
mempool_t *io_pool;
mempool_t *tio_pool;
+ struct bio_set *bs;
+
/*
* Event handling.
*/
@@ -121,16 +124,10 @@ struct mapped_device {
static kmem_cache_t *_io_cache;
static kmem_cache_t *_tio_cache;
-static struct bio_set *dm_set;
-
static int __init local_init(void)
{
int r;
- dm_set = bioset_create(16, 16, 4);
- if (!dm_set)
- return -ENOMEM;
-
/* allocate a slab for the dm_ios */
_io_cache = kmem_cache_create("dm_io",
sizeof(struct dm_io), 0, 0, NULL, NULL);
@@ -164,8 +161,6 @@ static void local_exit(void)
kmem_cache_destroy(_tio_cache);
kmem_cache_destroy(_io_cache);
- bioset_free(dm_set);
-
if (unregister_blkdev(_major, _name) < 0)
DMERR("unregister_blkdev failed");
@@ -288,6 +283,45 @@ static int dm_blk_getgeo(struct block_device *bdev, struct hd_geometry *geo)
return dm_get_geometry(md, geo);
}
+static int dm_blk_ioctl(struct inode *inode, struct file *file,
+ unsigned int cmd, unsigned long arg)
+{
+ struct mapped_device *md;
+ struct dm_table *map;
+ struct dm_target *tgt;
+ int r = -ENOTTY;
+
+ /* We don't really need this lock, but we do need 'inode'. */
+ unlock_kernel();
+
+ md = inode->i_bdev->bd_disk->private_data;
+
+ map = dm_get_table(md);
+
+ if (!map || !dm_table_get_size(map))
+ goto out;
+
+ /* We only support devices that have a single target */
+ if (dm_table_get_num_targets(map) != 1)
+ goto out;
+
+ tgt = dm_table_get_target(map, 0);
+
+ if (dm_suspended(md)) {
+ r = -EAGAIN;
+ goto out;
+ }
+
+ if (tgt->type->ioctl)
+ r = tgt->type->ioctl(tgt, inode, file, cmd, arg);
+
+out:
+ dm_table_put(map);
+
+ lock_kernel();
+ return r;
+}
+
static inline struct dm_io *alloc_io(struct mapped_device *md)
{
return mempool_alloc(md->io_pool, GFP_NOIO);
@@ -435,7 +469,7 @@ static int clone_endio(struct bio *bio, unsigned int done, int error)
{
int r = 0;
struct target_io *tio = bio->bi_private;
- struct dm_io *io = tio->io;
+ struct mapped_device *md = tio->io->md;
dm_endio_fn endio = tio->ti->type->end_io;
if (bio->bi_size)
@@ -454,9 +488,15 @@ static int clone_endio(struct bio *bio, unsigned int done, int error)
return 1;
}
- free_tio(io->md, tio);
- dec_pending(io, error);
+ dec_pending(tio->io, error);
+
+ /*
+ * Store md for cleanup instead of tio which is about to get freed.
+ */
+ bio->bi_private = md->bs;
+
bio_put(bio);
+ free_tio(md, tio);
return r;
}
@@ -485,6 +525,7 @@ static void __map_bio(struct dm_target *ti, struct bio *clone,
{
int r;
sector_t sector;
+ struct mapped_device *md;
/*
* Sanity checks.
@@ -514,10 +555,14 @@ static void __map_bio(struct dm_target *ti, struct bio *clone,
else if (r < 0) {
/* error the io and bail out */
- struct dm_io *io = tio->io;
- free_tio(tio->io->md, tio);
- dec_pending(io, r);
+ md = tio->io->md;
+ dec_pending(tio->io, r);
+ /*
+ * Store bio_set for cleanup.
+ */
+ clone->bi_private = md->bs;
bio_put(clone);
+ free_tio(md, tio);
}
}
@@ -533,7 +578,9 @@ struct clone_info {
static void dm_bio_destructor(struct bio *bio)
{
- bio_free(bio, dm_set);
+ struct bio_set *bs = bio->bi_private;
+
+ bio_free(bio, bs);
}
/*
@@ -541,12 +588,12 @@ static void dm_bio_destructor(struct bio *bio)
*/
static struct bio *split_bvec(struct bio *bio, sector_t sector,
unsigned short idx, unsigned int offset,
- unsigned int len)
+ unsigned int len, struct bio_set *bs)
{
struct bio *clone;
struct bio_vec *bv = bio->bi_io_vec + idx;
- clone = bio_alloc_bioset(GFP_NOIO, 1, dm_set);
+ clone = bio_alloc_bioset(GFP_NOIO, 1, bs);
clone->bi_destructor = dm_bio_destructor;
*clone->bi_io_vec = *bv;
@@ -566,11 +613,13 @@ static struct bio *split_bvec(struct bio *bio, sector_t sector,
*/
static struct bio *clone_bio(struct bio *bio, sector_t sector,
unsigned short idx, unsigned short bv_count,
- unsigned int len)
+ unsigned int len, struct bio_set *bs)
{
struct bio *clone;
- clone = bio_clone(bio, GFP_NOIO);
+ clone = bio_alloc_bioset(GFP_NOIO, bio->bi_max_vecs, bs);
+ __bio_clone(clone, bio);
+ clone->bi_destructor = dm_bio_destructor;
clone->bi_sector = sector;
clone->bi_idx = idx;
clone->bi_vcnt = idx + bv_count;
@@ -601,7 +650,8 @@ static void __clone_and_map(struct clone_info *ci)
* the remaining io with a single clone.
*/
clone = clone_bio(bio, ci->sector, ci->idx,
- bio->bi_vcnt - ci->idx, ci->sector_count);
+ bio->bi_vcnt - ci->idx, ci->sector_count,
+ ci->md->bs);
__map_bio(ti, clone, tio);
ci->sector_count = 0;
@@ -624,7 +674,8 @@ static void __clone_and_map(struct clone_info *ci)
len += bv_len;
}
- clone = clone_bio(bio, ci->sector, ci->idx, i - ci->idx, len);
+ clone = clone_bio(bio, ci->sector, ci->idx, i - ci->idx, len,
+ ci->md->bs);
__map_bio(ti, clone, tio);
ci->sector += len;
@@ -653,7 +704,8 @@ static void __clone_and_map(struct clone_info *ci)
len = min(remaining, max);
clone = split_bvec(bio, ci->sector, ci->idx,
- bv->bv_offset + offset, len);
+ bv->bv_offset + offset, len,
+ ci->md->bs);
__map_bio(ti, clone, tio);
@@ -903,7 +955,7 @@ static struct mapped_device *alloc_dev(int minor)
md->queue = blk_alloc_queue(GFP_KERNEL);
if (!md->queue)
- goto bad1;
+ goto bad1_free_minor;
md->queue->queuedata = md;
md->queue->backing_dev_info.congested_fn = dm_any_congested;
@@ -921,6 +973,10 @@ static struct mapped_device *alloc_dev(int minor)
if (!md->tio_pool)
goto bad3;
+ md->bs = bioset_create(16, 16, 4);
+ if (!md->bs)
+ goto bad_no_bioset;
+
md->disk = alloc_disk(1);
if (!md->disk)
goto bad4;
@@ -948,11 +1004,14 @@ static struct mapped_device *alloc_dev(int minor)
return md;
bad4:
+ bioset_free(md->bs);
+ bad_no_bioset:
mempool_destroy(md->tio_pool);
bad3:
mempool_destroy(md->io_pool);
bad2:
blk_cleanup_queue(md->queue);
+ bad1_free_minor:
free_minor(minor);
bad1:
module_put(THIS_MODULE);
@@ -971,6 +1030,7 @@ static void free_dev(struct mapped_device *md)
}
mempool_destroy(md->tio_pool);
mempool_destroy(md->io_pool);
+ bioset_free(md->bs);
del_gendisk(md->disk);
free_minor(minor);
@@ -1319,7 +1379,9 @@ int dm_resume(struct mapped_device *md)
if (!map || !dm_table_get_size(map))
goto out;
- dm_table_resume_targets(map);
+ r = dm_table_resume_targets(map);
+ if (r)
+ goto out;
down_write(&md->io_lock);
clear_bit(DMF_BLOCK_IO, &md->flags);
@@ -1337,6 +1399,8 @@ int dm_resume(struct mapped_device *md)
dm_table_unplug_all(map);
+ kobject_uevent(&md->disk->kobj, KOBJ_CHANGE);
+
r = 0;
out:
@@ -1377,6 +1441,7 @@ int dm_suspended(struct mapped_device *md)
static struct block_device_operations dm_blk_dops = {
.open = dm_blk_open,
.release = dm_blk_close,
+ .ioctl = dm_blk_ioctl,
.getgeo = dm_blk_getgeo,
.owner = THIS_MODULE
};
diff --git a/drivers/md/dm.h b/drivers/md/dm.h
index 3c03c0ecab7e..a48ec5e3c1f4 100644
--- a/drivers/md/dm.h
+++ b/drivers/md/dm.h
@@ -21,6 +21,11 @@
#define DMERR(f, arg...) printk(KERN_ERR DM_NAME ": " DM_MSG_PREFIX ": " f "\n", ## arg)
#define DMWARN(f, arg...) printk(KERN_WARNING DM_NAME ": " DM_MSG_PREFIX ": " f "\n", ## arg)
#define DMINFO(f, arg...) printk(KERN_INFO DM_NAME ": " DM_MSG_PREFIX ": " f "\n", ## arg)
+#ifdef CONFIG_DM_DEBUG
+# define DMDEBUG(f, arg...) printk(KERN_DEBUG DM_NAME ": " DM_MSG_PREFIX " DEBUG: " f "\n", ## arg)
+#else
+# define DMDEBUG(f, arg...) do {} while (0)
+#endif
#define DMEMIT(x...) sz += ((sz >= maxlen) ? \
0 : scnprintf(result + sz, maxlen - sz, x))
@@ -52,7 +57,7 @@ void dm_table_set_restrictions(struct dm_table *t, struct request_queue *q);
struct list_head *dm_table_get_devices(struct dm_table *t);
void dm_table_presuspend_targets(struct dm_table *t);
void dm_table_postsuspend_targets(struct dm_table *t);
-void dm_table_resume_targets(struct dm_table *t);
+int dm_table_resume_targets(struct dm_table *t);
int dm_table_any_congested(struct dm_table *t, int bdi_bits);
void dm_table_unplug_all(struct dm_table *t);
int dm_table_flush_all(struct dm_table *t);
diff --git a/drivers/md/linear.c b/drivers/md/linear.c
index b99c19c7eb22..c625ddb8833d 100644
--- a/drivers/md/linear.c
+++ b/drivers/md/linear.c
@@ -111,6 +111,19 @@ static int linear_issue_flush(request_queue_t *q, struct gendisk *disk,
return ret;
}
+static int linear_congested(void *data, int bits)
+{
+ mddev_t *mddev = data;
+ linear_conf_t *conf = mddev_to_conf(mddev);
+ int i, ret = 0;
+
+ for (i = 0; i < mddev->raid_disks && !ret ; i++) {
+ request_queue_t *q = bdev_get_queue(conf->disks[i].rdev->bdev);
+ ret |= bdi_congested(&q->backing_dev_info, bits);
+ }
+ return ret;
+}
+
static linear_conf_t *linear_conf(mddev_t *mddev, int raid_disks)
{
linear_conf_t *conf;
@@ -269,6 +282,8 @@ static int linear_run (mddev_t *mddev)
blk_queue_merge_bvec(mddev->queue, linear_mergeable_bvec);
mddev->queue->unplug_fn = linear_unplug;
mddev->queue->issue_flush_fn = linear_issue_flush;
+ mddev->queue->backing_dev_info.congested_fn = linear_congested;
+ mddev->queue->backing_dev_info.congested_data = mddev;
return 0;
}
diff --git a/drivers/md/md.c b/drivers/md/md.c
index 8dbab2ef3885..38a0a5741d52 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -389,8 +389,12 @@ static int super_written(struct bio *bio, unsigned int bytes_done, int error)
if (bio->bi_size)
return 1;
- if (error || !test_bit(BIO_UPTODATE, &bio->bi_flags))
+ if (error || !test_bit(BIO_UPTODATE, &bio->bi_flags)) {
+ printk("md: super_written gets error=%d, uptodate=%d\n",
+ error, test_bit(BIO_UPTODATE, &bio->bi_flags));
+ WARN_ON(test_bit(BIO_UPTODATE, &bio->bi_flags));
md_error(mddev, rdev);
+ }
if (atomic_dec_and_test(&mddev->pending_writes))
wake_up(&mddev->sb_wait);
@@ -1587,7 +1591,7 @@ static void sync_sbs(mddev_t * mddev, int nospares)
}
}
-void md_update_sb(mddev_t * mddev)
+static void md_update_sb(mddev_t * mddev, int force_change)
{
int err;
struct list_head *tmp;
@@ -1598,7 +1602,18 @@ void md_update_sb(mddev_t * mddev)
repeat:
spin_lock_irq(&mddev->write_lock);
- if (mddev->degraded && mddev->sb_dirty == 3)
+ set_bit(MD_CHANGE_PENDING, &mddev->flags);
+ if (test_and_clear_bit(MD_CHANGE_DEVS, &mddev->flags))
+ force_change = 1;
+ if (test_and_clear_bit(MD_CHANGE_CLEAN, &mddev->flags))
+ /* just a clean<-> dirty transition, possibly leave spares alone,
+ * though if events isn't the right even/odd, we will have to do
+ * spares after all
+ */
+ nospares = 1;
+ if (force_change)
+ nospares = 0;
+ if (mddev->degraded)
/* If the array is degraded, then skipping spares is both
* dangerous and fairly pointless.
* Dangerous because a device that was removed from the array
@@ -1608,20 +1623,14 @@ repeat:
* then a recovery will happen and soon that array won't
* be degraded any more and the spare can go back to sleep then.
*/
- mddev->sb_dirty = 1;
+ nospares = 0;
sync_req = mddev->in_sync;
mddev->utime = get_seconds();
- if (mddev->sb_dirty == 3)
- /* just a clean<-> dirty transition, possibly leave spares alone,
- * though if events isn't the right even/odd, we will have to do
- * spares after all
- */
- nospares = 1;
/* If this is just a dirty<->clean transition, and the array is clean
* and 'events' is odd, we can roll back to the previous clean state */
- if (mddev->sb_dirty == 3
+ if (nospares
&& (mddev->in_sync && mddev->recovery_cp == MaxSector)
&& (mddev->events & 1))
mddev->events--;
@@ -1652,7 +1661,6 @@ repeat:
MD_BUG();
mddev->events --;
}
- mddev->sb_dirty = 2;
sync_sbs(mddev, nospares);
/*
@@ -1660,7 +1668,7 @@ repeat:
* nonpersistent superblocks
*/
if (!mddev->persistent) {
- mddev->sb_dirty = 0;
+ clear_bit(MD_CHANGE_PENDING, &mddev->flags);
spin_unlock_irq(&mddev->write_lock);
wake_up(&mddev->sb_wait);
return;
@@ -1697,20 +1705,20 @@ repeat:
break;
}
md_super_wait(mddev);
- /* if there was a failure, sb_dirty was set to 1, and we re-write super */
+ /* if there was a failure, MD_CHANGE_DEVS was set, and we re-write super */
spin_lock_irq(&mddev->write_lock);
- if (mddev->in_sync != sync_req|| mddev->sb_dirty == 1) {
+ if (mddev->in_sync != sync_req ||
+ test_bit(MD_CHANGE_DEVS, &mddev->flags)) {
/* have to write it out again */
spin_unlock_irq(&mddev->write_lock);
goto repeat;
}
- mddev->sb_dirty = 0;
+ clear_bit(MD_CHANGE_PENDING, &mddev->flags);
spin_unlock_irq(&mddev->write_lock);
wake_up(&mddev->sb_wait);
}
-EXPORT_SYMBOL_GPL(md_update_sb);
/* words written to sysfs files may, or my not, be \n terminated.
* We want to accept with case. For this we use cmd_match.
@@ -1783,7 +1791,7 @@ state_store(mdk_rdev_t *rdev, const char *buf, size_t len)
else {
mddev_t *mddev = rdev->mddev;
kick_rdev_from_array(rdev);
- md_update_sb(mddev);
+ md_update_sb(mddev, 1);
md_new_event(mddev);
err = 0;
}
@@ -2426,7 +2434,7 @@ array_state_store(mddev_t *mddev, const char *buf, size_t len)
spin_lock_irq(&mddev->write_lock);
if (atomic_read(&mddev->writes_pending) == 0) {
mddev->in_sync = 1;
- mddev->sb_dirty = 1;
+ set_bit(MD_CHANGE_CLEAN, &mddev->flags);
}
spin_unlock_irq(&mddev->write_lock);
} else {
@@ -2438,7 +2446,7 @@ array_state_store(mddev_t *mddev, const char *buf, size_t len)
case active:
if (mddev->pers) {
restart_array(mddev);
- mddev->sb_dirty = 0;
+ clear_bit(MD_CHANGE_CLEAN, &mddev->flags);
wake_up(&mddev->sb_wait);
err = 0;
} else {
@@ -2520,6 +2528,36 @@ static struct md_sysfs_entry md_new_device =
__ATTR(new_dev, S_IWUSR, null_show, new_dev_store);
static ssize_t
+bitmap_store(mddev_t *mddev, const char *buf, size_t len)
+{
+ char *end;
+ unsigned long chunk, end_chunk;
+
+ if (!mddev->bitmap)
+ goto out;
+ /* buf should be <chunk> <chunk> ... or <chunk>-<chunk> ... (range) */
+ while (*buf) {
+ chunk = end_chunk = simple_strtoul(buf, &end, 0);
+ if (buf == end) break;
+ if (*end == '-') { /* range */
+ buf = end + 1;
+ end_chunk = simple_strtoul(buf, &end, 0);
+ if (buf == end) break;
+ }
+ if (*end && !isspace(*end)) break;
+ bitmap_dirty_bits(mddev->bitmap, chunk, end_chunk);
+ buf = end;
+ while (isspace(*buf)) buf++;
+ }
+ bitmap_unplug(mddev->bitmap); /* flush the bits to disk */
+out:
+ return len;
+}
+
+static struct md_sysfs_entry md_bitmap =
+__ATTR(bitmap_set_bits, S_IWUSR, null_show, bitmap_store);
+
+static ssize_t
size_show(mddev_t *mddev, char *page)
{
return sprintf(page, "%llu\n", (unsigned long long)mddev->size);
@@ -2543,7 +2581,7 @@ size_store(mddev_t *mddev, const char *buf, size_t len)
if (mddev->pers) {
err = update_size(mddev, size);
- md_update_sb(mddev);
+ md_update_sb(mddev, 1);
} else {
if (mddev->size == 0 ||
mddev->size > size)
@@ -2839,6 +2877,7 @@ static struct attribute *md_redundancy_attrs[] = {
&md_sync_completed.attr,
&md_suspend_lo.attr,
&md_suspend_hi.attr,
+ &md_bitmap.attr,
NULL,
};
static struct attribute_group md_redundancy_group = {
@@ -3111,8 +3150,8 @@ static int do_md_run(mddev_t * mddev)
set_bit(MD_RECOVERY_NEEDED, &mddev->recovery);
- if (mddev->sb_dirty)
- md_update_sb(mddev);
+ if (mddev->flags)
+ md_update_sb(mddev, 0);
set_capacity(disk, mddev->array_size<<1);
@@ -3275,10 +3314,10 @@ static int do_md_stop(mddev_t * mddev, int mode)
if (mddev->ro)
mddev->ro = 0;
}
- if (!mddev->in_sync || mddev->sb_dirty) {
+ if (!mddev->in_sync || mddev->flags) {
/* mark array as shutdown cleanly */
mddev->in_sync = 1;
- md_update_sb(mddev);
+ md_update_sb(mddev, 1);
}
if (mode == 1)
set_disk_ro(disk, 1);
@@ -3374,6 +3413,7 @@ static void autorun_devices(int part)
printk(KERN_INFO "md: autorun ...\n");
while (!list_empty(&pending_raid_disks)) {
+ int unit;
dev_t dev;
LIST_HEAD(candidates);
rdev0 = list_entry(pending_raid_disks.next,
@@ -3393,16 +3433,19 @@ static void autorun_devices(int part)
* mostly sane superblocks. It's time to allocate the
* mddev.
*/
- if (rdev0->preferred_minor < 0 || rdev0->preferred_minor >= MAX_MD_DEVS) {
+ if (part) {
+ dev = MKDEV(mdp_major,
+ rdev0->preferred_minor << MdpMinorShift);
+ unit = MINOR(dev) >> MdpMinorShift;
+ } else {
+ dev = MKDEV(MD_MAJOR, rdev0->preferred_minor);
+ unit = MINOR(dev);
+ }
+ if (rdev0->preferred_minor != unit) {
printk(KERN_INFO "md: unit number in %s is bad: %d\n",
bdevname(rdev0->bdev, b), rdev0->preferred_minor);
break;
}
- if (part)
- dev = MKDEV(mdp_major,
- rdev0->preferred_minor << MdpMinorShift);
- else
- dev = MKDEV(MD_MAJOR, rdev0->preferred_minor);
md_probe(dev, NULL, NULL);
mddev = mddev_find(dev);
@@ -3440,67 +3483,6 @@ static void autorun_devices(int part)
printk(KERN_INFO "md: ... autorun DONE.\n");
}
-/*
- * import RAID devices based on one partition
- * if possible, the array gets run as well.
- */
-
-static int autostart_array(dev_t startdev)
-{
- char b[BDEVNAME_SIZE];
- int err = -EINVAL, i;
- mdp_super_t *sb = NULL;
- mdk_rdev_t *start_rdev = NULL, *rdev;
-
- start_rdev = md_import_device(startdev, 0, 0);
- if (IS_ERR(start_rdev))
- return err;
-
-
- /* NOTE: this can only work for 0.90.0 superblocks */
- sb = (mdp_super_t*)page_address(start_rdev->sb_page);
- if (sb->major_version != 0 ||
- sb->minor_version != 90 ) {
- printk(KERN_WARNING "md: can only autostart 0.90.0 arrays\n");
- export_rdev(start_rdev);
- return err;
- }
-
- if (test_bit(Faulty, &start_rdev->flags)) {
- printk(KERN_WARNING
- "md: can not autostart based on faulty %s!\n",
- bdevname(start_rdev->bdev,b));
- export_rdev(start_rdev);
- return err;
- }
- list_add(&start_rdev->same_set, &pending_raid_disks);
-
- for (i = 0; i < MD_SB_DISKS; i++) {
- mdp_disk_t *desc = sb->disks + i;
- dev_t dev = MKDEV(desc->major, desc->minor);
-
- if (!dev)
- continue;
- if (dev == startdev)
- continue;
- if (MAJOR(dev) != desc->major || MINOR(dev) != desc->minor)
- continue;
- rdev = md_import_device(dev, 0, 0);
- if (IS_ERR(rdev))
- continue;
-
- list_add(&rdev->same_set, &pending_raid_disks);
- }
-
- /*
- * possibly return codes
- */
- autorun_devices(0);
- return 0;
-
-}
-
-
static int get_version(void __user * arg)
{
mdu_version_t ver;
@@ -3808,7 +3790,7 @@ static int hot_remove_disk(mddev_t * mddev, dev_t dev)
goto busy;
kick_rdev_from_array(rdev);
- md_update_sb(mddev);
+ md_update_sb(mddev, 1);
md_new_event(mddev);
return 0;
@@ -3885,7 +3867,7 @@ static int hot_add_disk(mddev_t * mddev, dev_t dev)
rdev->raid_disk = -1;
- md_update_sb(mddev);
+ md_update_sb(mddev, 1);
/*
* Kick recovery, maybe this spare has to be added to the
@@ -4016,7 +3998,8 @@ static int set_array_info(mddev_t * mddev, mdu_array_info_t *info)
mddev->max_disks = MD_SB_DISKS;
- mddev->sb_dirty = 1;
+ mddev->flags = 0;
+ set_bit(MD_CHANGE_DEVS, &mddev->flags);
mddev->default_bitmap_offset = MD_SB_BYTES >> 9;
mddev->bitmap_offset = 0;
@@ -4185,7 +4168,7 @@ static int update_array_info(mddev_t *mddev, mdu_array_info_t *info)
mddev->bitmap_offset = 0;
}
}
- md_update_sb(mddev);
+ md_update_sb(mddev, 1);
return rv;
}
@@ -4259,27 +4242,6 @@ static int md_ioctl(struct inode *inode, struct file *file,
goto abort;
}
-
- if (cmd == START_ARRAY) {
- /* START_ARRAY doesn't need to lock the array as autostart_array
- * does the locking, and it could even be a different array
- */
- static int cnt = 3;
- if (cnt > 0 ) {
- printk(KERN_WARNING
- "md: %s(pid %d) used deprecated START_ARRAY ioctl. "
- "This will not be supported beyond July 2006\n",
- current->comm, current->pid);
- cnt--;
- }
- err = autostart_array(new_decode_dev(arg));
- if (err) {
- printk(KERN_WARNING "md: autostart failed!\n");
- goto abort;
- }
- goto done;
- }
-
err = mddev_lock(mddev);
if (err) {
printk(KERN_INFO
@@ -4687,9 +4649,11 @@ static void status_resync(struct seq_file *seq, mddev_t * mddev)
seq_printf(seq, " %s =%3u.%u%% (%llu/%llu)",
(test_bit(MD_RECOVERY_RESHAPE, &mddev->recovery)?
"reshape" :
- (test_bit(MD_RECOVERY_SYNC, &mddev->recovery) ?
- "resync" : "recovery")),
- per_milli/10, per_milli % 10,
+ (test_bit(MD_RECOVERY_CHECK, &mddev->recovery)?
+ "check" :
+ (test_bit(MD_RECOVERY_SYNC, &mddev->recovery) ?
+ "resync" : "recovery"))),
+ per_milli/10, per_milli % 10,
(unsigned long long) resync,
(unsigned long long) max_blocks);
@@ -5042,12 +5006,12 @@ void md_write_start(mddev_t *mddev, struct bio *bi)
spin_lock_irq(&mddev->write_lock);
if (mddev->in_sync) {
mddev->in_sync = 0;
- mddev->sb_dirty = 3;
+ set_bit(MD_CHANGE_CLEAN, &mddev->flags);
md_wakeup_thread(mddev->thread);
}
spin_unlock_irq(&mddev->write_lock);
}
- wait_event(mddev->sb_wait, mddev->sb_dirty==0);
+ wait_event(mddev->sb_wait, mddev->flags==0);
}
void md_write_end(mddev_t *mddev)
@@ -5078,6 +5042,7 @@ void md_do_sync(mddev_t *mddev)
int skipped = 0;
struct list_head *rtmp;
mdk_rdev_t *rdev;
+ char *desc;
/* just incase thread restarts... */
if (test_bit(MD_RECOVERY_DONE, &mddev->recovery))
@@ -5085,6 +5050,18 @@ void md_do_sync(mddev_t *mddev)
if (mddev->ro) /* never try to sync a read-only array */
return;
+ if (test_bit(MD_RECOVERY_SYNC, &mddev->recovery)) {
+ if (test_bit(MD_RECOVERY_CHECK, &mddev->recovery))
+ desc = "data-check";
+ else if (test_bit(MD_RECOVERY_REQUESTED, &mddev->recovery))
+ desc = "requested-resync";
+ else
+ desc = "resync";
+ } else if (test_bit(MD_RECOVERY_RESHAPE, &mddev->recovery))
+ desc = "reshape";
+ else
+ desc = "recovery";
+
/* we overload curr_resync somewhat here.
* 0 == not engaged in resync at all
* 2 == checking that there is no conflict with another sync
@@ -5128,10 +5105,10 @@ void md_do_sync(mddev_t *mddev)
prepare_to_wait(&resync_wait, &wq, TASK_UNINTERRUPTIBLE);
if (!kthread_should_stop() &&
mddev2->curr_resync >= mddev->curr_resync) {
- printk(KERN_INFO "md: delaying resync of %s"
- " until %s has finished resync (they"
+ printk(KERN_INFO "md: delaying %s of %s"
+ " until %s has finished (they"
" share one or more physical units)\n",
- mdname(mddev), mdname(mddev2));
+ desc, mdname(mddev), mdname(mddev2));
mddev_put(mddev2);
schedule();
finish_wait(&resync_wait, &wq);
@@ -5167,12 +5144,12 @@ void md_do_sync(mddev_t *mddev)
j = rdev->recovery_offset;
}
- printk(KERN_INFO "md: syncing RAID array %s\n", mdname(mddev));
- printk(KERN_INFO "md: minimum _guaranteed_ reconstruction speed:"
- " %d KB/sec/disc.\n", speed_min(mddev));
+ printk(KERN_INFO "md: %s of RAID array %s\n", desc, mdname(mddev));
+ printk(KERN_INFO "md: minimum _guaranteed_ speed:"
+ " %d KB/sec/disk.\n", speed_min(mddev));
printk(KERN_INFO "md: using maximum available idle IO bandwidth "
- "(but not more than %d KB/sec) for reconstruction.\n",
- speed_max(mddev));
+ "(but not more than %d KB/sec) for %s.\n",
+ speed_max(mddev), desc);
is_mddev_idle(mddev); /* this also initializes IO event counters */
@@ -5198,8 +5175,8 @@ void md_do_sync(mddev_t *mddev)
if (j>2) {
printk(KERN_INFO
- "md: resuming recovery of %s from checkpoint.\n",
- mdname(mddev));
+ "md: resuming %s of %s from checkpoint.\n",
+ desc, mdname(mddev));
mddev->curr_resync = j;
}
@@ -5282,7 +5259,7 @@ void md_do_sync(mddev_t *mddev)
}
}
}
- printk(KERN_INFO "md: %s: sync done.\n",mdname(mddev));
+ printk(KERN_INFO "md: %s: %s done.\n",mdname(mddev), desc);
/*
* this also signals 'finished resyncing' to md_stop
*/
@@ -5302,8 +5279,8 @@ void md_do_sync(mddev_t *mddev)
if (test_bit(MD_RECOVERY_INTR, &mddev->recovery)) {
if (mddev->curr_resync >= mddev->recovery_cp) {
printk(KERN_INFO
- "md: checkpointing recovery of %s.\n",
- mdname(mddev));
+ "md: checkpointing %s of %s.\n",
+ desc, mdname(mddev));
mddev->recovery_cp = mddev->curr_resync;
}
} else
@@ -5317,7 +5294,6 @@ void md_do_sync(mddev_t *mddev)
!test_bit(In_sync, &rdev->flags) &&
rdev->recovery_offset < mddev->curr_resync)
rdev->recovery_offset = mddev->curr_resync;
- mddev->sb_dirty = 1;
}
}
@@ -5374,7 +5350,7 @@ void md_check_recovery(mddev_t *mddev)
}
if ( ! (
- mddev->sb_dirty ||
+ mddev->flags ||
test_bit(MD_RECOVERY_NEEDED, &mddev->recovery) ||
test_bit(MD_RECOVERY_DONE, &mddev->recovery) ||
(mddev->safemode == 1) ||
@@ -5390,14 +5366,14 @@ void md_check_recovery(mddev_t *mddev)
if (mddev->safemode && !atomic_read(&mddev->writes_pending) &&
!mddev->in_sync && mddev->recovery_cp == MaxSector) {
mddev->in_sync = 1;
- mddev->sb_dirty = 3;
+ set_bit(MD_CHANGE_CLEAN, &mddev->flags);
}
if (mddev->safemode == 1)
mddev->safemode = 0;
spin_unlock_irq(&mddev->write_lock);
- if (mddev->sb_dirty)
- md_update_sb(mddev);
+ if (mddev->flags)
+ md_update_sb(mddev, 0);
if (test_bit(MD_RECOVERY_RUNNING, &mddev->recovery) &&
@@ -5416,7 +5392,7 @@ void md_check_recovery(mddev_t *mddev)
/* activate any spares */
mddev->pers->spare_active(mddev);
}
- md_update_sb(mddev);
+ md_update_sb(mddev, 1);
/* if array is no-longer degraded, then any saved_raid_disk
* information must be scrapped
@@ -5556,22 +5532,15 @@ static void md_geninit(void)
static int __init md_init(void)
{
- printk(KERN_INFO "md: md driver %d.%d.%d MAX_MD_DEVS=%d,"
- " MD_SB_DISKS=%d\n",
- MD_MAJOR_VERSION, MD_MINOR_VERSION,
- MD_PATCHLEVEL_VERSION, MAX_MD_DEVS, MD_SB_DISKS);
- printk(KERN_INFO "md: bitmap version %d.%d\n", BITMAP_MAJOR_HI,
- BITMAP_MINOR);
-
if (register_blkdev(MAJOR_NR, "md"))
return -1;
if ((mdp_major=register_blkdev(0, "mdp"))<=0) {
unregister_blkdev(MAJOR_NR, "md");
return -1;
}
- blk_register_region(MKDEV(MAJOR_NR, 0), MAX_MD_DEVS, THIS_MODULE,
- md_probe, NULL, NULL);
- blk_register_region(MKDEV(mdp_major, 0), MAX_MD_DEVS<<MdpMinorShift, THIS_MODULE,
+ blk_register_region(MKDEV(MAJOR_NR, 0), 1UL<<MINORBITS, THIS_MODULE,
+ md_probe, NULL, NULL);
+ blk_register_region(MKDEV(mdp_major, 0), 1UL<<MINORBITS, THIS_MODULE,
md_probe, NULL, NULL);
register_reboot_notifier(&md_notifier);
@@ -5630,8 +5599,8 @@ static __exit void md_exit(void)
mddev_t *mddev;
struct list_head *tmp;
- blk_unregister_region(MKDEV(MAJOR_NR,0), MAX_MD_DEVS);
- blk_unregister_region(MKDEV(mdp_major,0), MAX_MD_DEVS << MdpMinorShift);
+ blk_unregister_region(MKDEV(MAJOR_NR,0), 1U << MINORBITS);
+ blk_unregister_region(MKDEV(mdp_major,0), 1U << MINORBITS);
unregister_blkdev(MAJOR_NR,"md");
unregister_blkdev(mdp_major, "mdp");
diff --git a/drivers/md/multipath.c b/drivers/md/multipath.c
index 1cc9de44ce86..171ff41b52b0 100644
--- a/drivers/md/multipath.c
+++ b/drivers/md/multipath.c
@@ -228,6 +228,28 @@ static int multipath_issue_flush(request_queue_t *q, struct gendisk *disk,
rcu_read_unlock();
return ret;
}
+static int multipath_congested(void *data, int bits)
+{
+ mddev_t *mddev = data;
+ multipath_conf_t *conf = mddev_to_conf(mddev);
+ int i, ret = 0;
+
+ rcu_read_lock();
+ for (i = 0; i < mddev->raid_disks ; i++) {
+ mdk_rdev_t *rdev = rcu_dereference(conf->multipaths[i].rdev);
+ if (rdev && !test_bit(Faulty, &rdev->flags)) {
+ request_queue_t *q = bdev_get_queue(rdev->bdev);
+
+ ret |= bdi_congested(&q->backing_dev_info, bits);
+ /* Just like multipath_map, we just check the
+ * first available device
+ */
+ break;
+ }
+ }
+ rcu_read_unlock();
+ return ret;
+}
/*
* Careful, this can execute in IRQ contexts as well!
@@ -253,7 +275,7 @@ static void multipath_error (mddev_t *mddev, mdk_rdev_t *rdev)
char b[BDEVNAME_SIZE];
clear_bit(In_sync, &rdev->flags);
set_bit(Faulty, &rdev->flags);
- mddev->sb_dirty = 1;
+ set_bit(MD_CHANGE_DEVS, &mddev->flags);
conf->working_disks--;
printk(KERN_ALERT "multipath: IO failure on %s,"
" disabling IO path. \n Operation continuing"
@@ -470,7 +492,6 @@ static int multipath_run (mddev_t *mddev)
}
conf->raid_disks = mddev->raid_disks;
- mddev->sb_dirty = 1;
conf->mddev = mddev;
spin_lock_init(&conf->device_lock);
INIT_LIST_HEAD(&conf->retry_list);
@@ -510,6 +531,8 @@ static int multipath_run (mddev_t *mddev)
mddev->queue->unplug_fn = multipath_unplug;
mddev->queue->issue_flush_fn = multipath_issue_flush;
+ mddev->queue->backing_dev_info.congested_fn = multipath_congested;
+ mddev->queue->backing_dev_info.congested_data = mddev;
return 0;
diff --git a/drivers/md/raid0.c b/drivers/md/raid0.c
index cb8c6317e4e5..dfe32149ad3a 100644
--- a/drivers/md/raid0.c
+++ b/drivers/md/raid0.c
@@ -60,6 +60,21 @@ static int raid0_issue_flush(request_queue_t *q, struct gendisk *disk,
return ret;
}
+static int raid0_congested(void *data, int bits)
+{
+ mddev_t *mddev = data;
+ raid0_conf_t *conf = mddev_to_conf(mddev);
+ mdk_rdev_t **devlist = conf->strip_zone[0].dev;
+ int i, ret = 0;
+
+ for (i = 0; i < mddev->raid_disks && !ret ; i++) {
+ request_queue_t *q = bdev_get_queue(devlist[i]->bdev);
+
+ ret |= bdi_congested(&q->backing_dev_info, bits);
+ }
+ return ret;
+}
+
static int create_strip_zones (mddev_t *mddev)
{
@@ -236,6 +251,8 @@ static int create_strip_zones (mddev_t *mddev)
mddev->queue->unplug_fn = raid0_unplug;
mddev->queue->issue_flush_fn = raid0_issue_flush;
+ mddev->queue->backing_dev_info.congested_fn = raid0_congested;
+ mddev->queue->backing_dev_info.congested_data = mddev;
printk("raid0: done.\n");
return 0;
diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c
index 3b4d69c05623..dc9d2def0270 100644
--- a/drivers/md/raid1.c
+++ b/drivers/md/raid1.c
@@ -271,7 +271,7 @@ static int raid1_end_read_request(struct bio *bio, unsigned int bytes_done, int
*/
update_head_pos(mirror, r1_bio);
- if (uptodate || conf->working_disks <= 1) {
+ if (uptodate || (conf->raid_disks - conf->mddev->degraded) <= 1) {
/*
* Set R1BIO_Uptodate in our master bio, so that
* we will return a good error code for to the higher
@@ -601,6 +601,32 @@ static int raid1_issue_flush(request_queue_t *q, struct gendisk *disk,
return ret;
}
+static int raid1_congested(void *data, int bits)
+{
+ mddev_t *mddev = data;
+ conf_t *conf = mddev_to_conf(mddev);
+ int i, ret = 0;
+
+ rcu_read_lock();
+ for (i = 0; i < mddev->raid_disks; i++) {
+ mdk_rdev_t *rdev = rcu_dereference(conf->mirrors[i].rdev);
+ if (rdev && !test_bit(Faulty, &rdev->flags)) {
+ request_queue_t *q = bdev_get_queue(rdev->bdev);
+
+ /* Note the '|| 1' - when read_balance prefers
+ * non-congested targets, it can be removed
+ */
+ if ((bits & (1<<BDI_write_congested)) || 1)
+ ret |= bdi_congested(&q->backing_dev_info, bits);
+ else
+ ret &= bdi_congested(&q->backing_dev_info, bits);
+ }
+ }
+ rcu_read_unlock();
+ return ret;
+}
+
+
/* Barriers....
* Sometimes we need to suspend IO while we do something else,
* either some resync/recovery, or reconfigure the array.
@@ -929,7 +955,7 @@ static void status(struct seq_file *seq, mddev_t *mddev)
int i;
seq_printf(seq, " [%d/%d] [", conf->raid_disks,
- conf->working_disks);
+ conf->raid_disks - mddev->degraded);
rcu_read_lock();
for (i = 0; i < conf->raid_disks; i++) {
mdk_rdev_t *rdev = rcu_dereference(conf->mirrors[i].rdev);
@@ -953,26 +979,27 @@ static void error(mddev_t *mddev, mdk_rdev_t *rdev)
* else mark the drive as failed
*/
if (test_bit(In_sync, &rdev->flags)
- && conf->working_disks == 1)
+ && (conf->raid_disks - mddev->degraded) == 1)
/*
* Don't fail the drive, act as though we were just a
* normal single drive
*/
return;
- if (test_bit(In_sync, &rdev->flags)) {
+ if (test_and_clear_bit(In_sync, &rdev->flags)) {
+ unsigned long flags;
+ spin_lock_irqsave(&conf->device_lock, flags);
mddev->degraded++;
- conf->working_disks--;
+ spin_unlock_irqrestore(&conf->device_lock, flags);
/*
* if recovery is running, make sure it aborts.
*/
set_bit(MD_RECOVERY_ERR, &mddev->recovery);
}
- clear_bit(In_sync, &rdev->flags);
set_bit(Faulty, &rdev->flags);
- mddev->sb_dirty = 1;
+ set_bit(MD_CHANGE_DEVS, &mddev->flags);
printk(KERN_ALERT "raid1: Disk failure on %s, disabling device. \n"
" Operation continuing on %d devices\n",
- bdevname(rdev->bdev,b), conf->working_disks);
+ bdevname(rdev->bdev,b), conf->raid_disks - mddev->degraded);
}
static void print_conf(conf_t *conf)
@@ -984,7 +1011,7 @@ static void print_conf(conf_t *conf)
printk("(!conf)\n");
return;
}
- printk(" --- wd:%d rd:%d\n", conf->working_disks,
+ printk(" --- wd:%d rd:%d\n", conf->raid_disks - conf->mddev->degraded,
conf->raid_disks);
rcu_read_lock();
@@ -1023,10 +1050,11 @@ static int raid1_spare_active(mddev_t *mddev)
mdk_rdev_t *rdev = conf->mirrors[i].rdev;
if (rdev
&& !test_bit(Faulty, &rdev->flags)
- && !test_bit(In_sync, &rdev->flags)) {
- conf->working_disks++;
+ && !test_and_set_bit(In_sync, &rdev->flags)) {
+ unsigned long flags;
+ spin_lock_irqsave(&conf->device_lock, flags);
mddev->degraded--;
- set_bit(In_sync, &rdev->flags);
+ spin_unlock_irqrestore(&conf->device_lock, flags);
}
}
@@ -1368,6 +1396,95 @@ static void sync_request_write(mddev_t *mddev, r1bio_t *r1_bio)
* 3. Performs writes following reads for array syncronising.
*/
+static void fix_read_error(conf_t *conf, int read_disk,
+ sector_t sect, int sectors)
+{
+ mddev_t *mddev = conf->mddev;
+ while(sectors) {
+ int s = sectors;
+ int d = read_disk;
+ int success = 0;
+ int start;
+ mdk_rdev_t *rdev;
+
+ if (s > (PAGE_SIZE>>9))
+ s = PAGE_SIZE >> 9;
+
+ do {
+ /* Note: no rcu protection needed here
+ * as this is synchronous in the raid1d thread
+ * which is the thread that might remove
+ * a device. If raid1d ever becomes multi-threaded....
+ */
+ rdev = conf->mirrors[d].rdev;
+ if (rdev &&
+ test_bit(In_sync, &rdev->flags) &&
+ sync_page_io(rdev->bdev,
+ sect + rdev->data_offset,
+ s<<9,
+ conf->tmppage, READ))
+ success = 1;
+ else {
+ d++;
+ if (d == conf->raid_disks)
+ d = 0;
+ }
+ } while (!success && d != read_disk);
+
+ if (!success) {
+ /* Cannot read from anywhere -- bye bye array */
+ md_error(mddev, conf->mirrors[read_disk].rdev);
+ break;
+ }
+ /* write it back and re-read */
+ start = d;
+ while (d != read_disk) {
+ if (d==0)
+ d = conf->raid_disks;
+ d--;
+ rdev = conf->mirrors[d].rdev;
+ if (rdev &&
+ test_bit(In_sync, &rdev->flags)) {
+ if (sync_page_io(rdev->bdev,
+ sect + rdev->data_offset,
+ s<<9, conf->tmppage, WRITE)
+ == 0)
+ /* Well, this device is dead */
+ md_error(mddev, rdev);
+ }
+ }
+ d = start;
+ while (d != read_disk) {
+ char b[BDEVNAME_SIZE];
+ if (d==0)
+ d = conf->raid_disks;
+ d--;
+ rdev = conf->mirrors[d].rdev;
+ if (rdev &&
+ test_bit(In_sync, &rdev->flags)) {
+ if (sync_page_io(rdev->bdev,
+ sect + rdev->data_offset,
+ s<<9, conf->tmppage, READ)
+ == 0)
+ /* Well, this device is dead */
+ md_error(mddev, rdev);
+ else {
+ atomic_add(s, &rdev->corrected_errors);
+ printk(KERN_INFO
+ "raid1:%s: read error corrected "
+ "(%d sectors at %llu on %s)\n",
+ mdname(mddev), s,
+ (unsigned long long)sect +
+ rdev->data_offset,
+ bdevname(rdev->bdev, b));
+ }
+ }
+ }
+ sectors -= s;
+ sect += s;
+ }
+}
+
static void raid1d(mddev_t *mddev)
{
r1bio_t *r1_bio;
@@ -1460,86 +1577,14 @@ static void raid1d(mddev_t *mddev)
* This is all done synchronously while the array is
* frozen
*/
- sector_t sect = r1_bio->sector;
- int sectors = r1_bio->sectors;
- freeze_array(conf);
- if (mddev->ro == 0) while(sectors) {
- int s = sectors;
- int d = r1_bio->read_disk;
- int success = 0;
-
- if (s > (PAGE_SIZE>>9))
- s = PAGE_SIZE >> 9;
-
- do {
- /* Note: no rcu protection needed here
- * as this is synchronous in the raid1d thread
- * which is the thread that might remove
- * a device. If raid1d ever becomes multi-threaded....
- */
- rdev = conf->mirrors[d].rdev;
- if (rdev &&
- test_bit(In_sync, &rdev->flags) &&
- sync_page_io(rdev->bdev,
- sect + rdev->data_offset,
- s<<9,
- conf->tmppage, READ))
- success = 1;
- else {
- d++;
- if (d == conf->raid_disks)
- d = 0;
- }
- } while (!success && d != r1_bio->read_disk);
-
- if (success) {
- /* write it back and re-read */
- int start = d;
- while (d != r1_bio->read_disk) {
- if (d==0)
- d = conf->raid_disks;
- d--;
- rdev = conf->mirrors[d].rdev;
- if (rdev &&
- test_bit(In_sync, &rdev->flags)) {
- if (sync_page_io(rdev->bdev,
- sect + rdev->data_offset,
- s<<9, conf->tmppage, WRITE) == 0)
- /* Well, this device is dead */
- md_error(mddev, rdev);
- }
- }
- d = start;
- while (d != r1_bio->read_disk) {
- if (d==0)
- d = conf->raid_disks;
- d--;
- rdev = conf->mirrors[d].rdev;
- if (rdev &&
- test_bit(In_sync, &rdev->flags)) {
- if (sync_page_io(rdev->bdev,
- sect + rdev->data_offset,
- s<<9, conf->tmppage, READ) == 0)
- /* Well, this device is dead */
- md_error(mddev, rdev);
- else {
- atomic_add(s, &rdev->corrected_errors);
- printk(KERN_INFO "raid1:%s: read error corrected (%d sectors at %llu on %s)\n",
- mdname(mddev), s, (unsigned long long)(sect + rdev->data_offset), bdevname(rdev->bdev, b));
- }
- }
- }
- } else {
- /* Cannot read from anywhere -- bye bye array */
- md_error(mddev, conf->mirrors[r1_bio->read_disk].rdev);
- break;
- }
- sectors -= s;
- sect += s;
+ if (mddev->ro == 0) {
+ freeze_array(conf);
+ fix_read_error(conf, r1_bio->read_disk,
+ r1_bio->sector,
+ r1_bio->sectors);
+ unfreeze_array(conf);
}
- unfreeze_array(conf);
-
bio = r1_bio->bios[r1_bio->read_disk];
if ((disk=read_balance(conf, r1_bio)) == -1) {
printk(KERN_ALERT "raid1: %s: unrecoverable I/O"
@@ -1884,15 +1929,11 @@ static int run(mddev_t *mddev)
blk_queue_max_sectors(mddev->queue, PAGE_SIZE>>9);
disk->head_position = 0;
- if (!test_bit(Faulty, &rdev->flags) && test_bit(In_sync, &rdev->flags))
- conf->working_disks++;
}
conf->raid_disks = mddev->raid_disks;
conf->mddev = mddev;
spin_lock_init(&conf->device_lock);
INIT_LIST_HEAD(&conf->retry_list);
- if (conf->working_disks == 1)
- mddev->recovery_cp = MaxSector;
spin_lock_init(&conf->resync_lock);
init_waitqueue_head(&conf->wait_barrier);
@@ -1900,11 +1941,6 @@ static int run(mddev_t *mddev)
bio_list_init(&conf->pending_bio_list);
bio_list_init(&conf->flushing_bio_list);
- if (!conf->working_disks) {
- printk(KERN_ERR "raid1: no operational mirrors for %s\n",
- mdname(mddev));
- goto out_free_conf;
- }
mddev->degraded = 0;
for (i = 0; i < conf->raid_disks; i++) {
@@ -1917,6 +1953,13 @@ static int run(mddev_t *mddev)
mddev->degraded++;
}
}
+ if (mddev->degraded == conf->raid_disks) {
+ printk(KERN_ERR "raid1: no operational mirrors for %s\n",
+ mdname(mddev));
+ goto out_free_conf;
+ }
+ if (conf->raid_disks - mddev->degraded == 1)
+ mddev->recovery_cp = MaxSector;
/*
* find the first working one and use it as a starting point
@@ -1948,6 +1991,8 @@ static int run(mddev_t *mddev)
mddev->queue->unplug_fn = raid1_unplug;
mddev->queue->issue_flush_fn = raid1_issue_flush;
+ mddev->queue->backing_dev_info.congested_fn = raid1_congested;
+ mddev->queue->backing_dev_info.congested_data = mddev;
return 0;
@@ -2035,7 +2080,7 @@ static int raid1_reshape(mddev_t *mddev)
mirror_info_t *newmirrors;
conf_t *conf = mddev_to_conf(mddev);
int cnt, raid_disks;
-
+ unsigned long flags;
int d, d2;
/* Cannot change chunk_size, layout, or level */
@@ -2094,7 +2139,9 @@ static int raid1_reshape(mddev_t *mddev)
kfree(conf->poolinfo);
conf->poolinfo = newpoolinfo;
+ spin_lock_irqsave(&conf->device_lock, flags);
mddev->degraded += (raid_disks - conf->raid_disks);
+ spin_unlock_irqrestore(&conf->device_lock, flags);
conf->raid_disks = mddev->raid_disks = raid_disks;
mddev->delta_disks = 0;
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c
index 016ddb831c9b..1250f0eab4af 100644
--- a/drivers/md/raid10.c
+++ b/drivers/md/raid10.c
@@ -648,6 +648,26 @@ static int raid10_issue_flush(request_queue_t *q, struct gendisk *disk,
return ret;
}
+static int raid10_congested(void *data, int bits)
+{
+ mddev_t *mddev = data;
+ conf_t *conf = mddev_to_conf(mddev);
+ int i, ret = 0;
+
+ rcu_read_lock();
+ for (i = 0; i < mddev->raid_disks && ret == 0; i++) {
+ mdk_rdev_t *rdev = rcu_dereference(conf->mirrors[i].rdev);
+ if (rdev && !test_bit(Faulty, &rdev->flags)) {
+ request_queue_t *q = bdev_get_queue(rdev->bdev);
+
+ ret |= bdi_congested(&q->backing_dev_info, bits);
+ }
+ }
+ rcu_read_unlock();
+ return ret;
+}
+
+
/* Barriers....
* Sometimes we need to suspend IO while we do something else,
* either some resync/recovery, or reconfigure the array.
@@ -921,7 +941,7 @@ static void status(struct seq_file *seq, mddev_t *mddev)
seq_printf(seq, " %d far-copies", conf->far_copies);
}
seq_printf(seq, " [%d/%d] [", conf->raid_disks,
- conf->working_disks);
+ conf->raid_disks - mddev->degraded);
for (i = 0; i < conf->raid_disks; i++)
seq_printf(seq, "%s",
conf->mirrors[i].rdev &&
@@ -941,7 +961,7 @@ static void error(mddev_t *mddev, mdk_rdev_t *rdev)
* else mark the drive as failed
*/
if (test_bit(In_sync, &rdev->flags)
- && conf->working_disks == 1)
+ && conf->raid_disks-mddev->degraded == 1)
/*
* Don't fail the drive, just return an IO error.
* The test should really be more sophisticated than
@@ -950,20 +970,21 @@ static void error(mddev_t *mddev, mdk_rdev_t *rdev)
* really dead" tests...
*/
return;
- if (test_bit(In_sync, &rdev->flags)) {
+ if (test_and_clear_bit(In_sync, &rdev->flags)) {
+ unsigned long flags;
+ spin_lock_irqsave(&conf->device_lock, flags);
mddev->degraded++;
- conf->working_disks--;
+ spin_unlock_irqrestore(&conf->device_lock, flags);
/*
* if recovery is running, make sure it aborts.
*/
set_bit(MD_RECOVERY_ERR, &mddev->recovery);
}
- clear_bit(In_sync, &rdev->flags);
set_bit(Faulty, &rdev->flags);
- mddev->sb_dirty = 1;
+ set_bit(MD_CHANGE_DEVS, &mddev->flags);
printk(KERN_ALERT "raid10: Disk failure on %s, disabling device. \n"
" Operation continuing on %d devices\n",
- bdevname(rdev->bdev,b), conf->working_disks);
+ bdevname(rdev->bdev,b), conf->raid_disks - mddev->degraded);
}
static void print_conf(conf_t *conf)
@@ -976,7 +997,7 @@ static void print_conf(conf_t *conf)
printk("(!conf)\n");
return;
}
- printk(" --- wd:%d rd:%d\n", conf->working_disks,
+ printk(" --- wd:%d rd:%d\n", conf->raid_disks - conf->mddev->degraded,
conf->raid_disks);
for (i = 0; i < conf->raid_disks; i++) {
@@ -1034,10 +1055,11 @@ static int raid10_spare_active(mddev_t *mddev)
tmp = conf->mirrors + i;
if (tmp->rdev
&& !test_bit(Faulty, &tmp->rdev->flags)
- && !test_bit(In_sync, &tmp->rdev->flags)) {
- conf->working_disks++;
+ && !test_and_set_bit(In_sync, &tmp->rdev->flags)) {
+ unsigned long flags;
+ spin_lock_irqsave(&conf->device_lock, flags);
mddev->degraded--;
- set_bit(In_sync, &tmp->rdev->flags);
+ spin_unlock_irqrestore(&conf->device_lock, flags);
}
}
@@ -1350,9 +1372,119 @@ static void recovery_request_write(mddev_t *mddev, r10bio_t *r10_bio)
*
* 1. Retries failed read operations on working mirrors.
* 2. Updates the raid superblock when problems encounter.
- * 3. Performs writes following reads for array syncronising.
+ * 3. Performs writes following reads for array synchronising.
*/
+static void fix_read_error(conf_t *conf, mddev_t *mddev, r10bio_t *r10_bio)
+{
+ int sect = 0; /* Offset from r10_bio->sector */
+ int sectors = r10_bio->sectors;
+ mdk_rdev_t*rdev;
+ while(sectors) {
+ int s = sectors;
+ int sl = r10_bio->read_slot;
+ int success = 0;
+ int start;
+
+ if (s > (PAGE_SIZE>>9))
+ s = PAGE_SIZE >> 9;
+
+ rcu_read_lock();
+ do {
+ int d = r10_bio->devs[sl].devnum;
+ rdev = rcu_dereference(conf->mirrors[d].rdev);
+ if (rdev &&
+ test_bit(In_sync, &rdev->flags)) {
+ atomic_inc(&rdev->nr_pending);
+ rcu_read_unlock();
+ success = sync_page_io(rdev->bdev,
+ r10_bio->devs[sl].addr +
+ sect + rdev->data_offset,
+ s<<9,
+ conf->tmppage, READ);
+ rdev_dec_pending(rdev, mddev);
+ rcu_read_lock();
+ if (success)
+ break;
+ }
+ sl++;
+ if (sl == conf->copies)
+ sl = 0;
+ } while (!success && sl != r10_bio->read_slot);
+ rcu_read_unlock();
+
+ if (!success) {
+ /* Cannot read from anywhere -- bye bye array */
+ int dn = r10_bio->devs[r10_bio->read_slot].devnum;
+ md_error(mddev, conf->mirrors[dn].rdev);
+ break;
+ }
+
+ start = sl;
+ /* write it back and re-read */
+ rcu_read_lock();
+ while (sl != r10_bio->read_slot) {
+ int d;
+ if (sl==0)
+ sl = conf->copies;
+ sl--;
+ d = r10_bio->devs[sl].devnum;
+ rdev = rcu_dereference(conf->mirrors[d].rdev);
+ if (rdev &&
+ test_bit(In_sync, &rdev->flags)) {
+ atomic_inc(&rdev->nr_pending);
+ rcu_read_unlock();
+ atomic_add(s, &rdev->corrected_errors);
+ if (sync_page_io(rdev->bdev,
+ r10_bio->devs[sl].addr +
+ sect + rdev->data_offset,
+ s<<9, conf->tmppage, WRITE)
+ == 0)
+ /* Well, this device is dead */
+ md_error(mddev, rdev);
+ rdev_dec_pending(rdev, mddev);
+ rcu_read_lock();
+ }
+ }
+ sl = start;
+ while (sl != r10_bio->read_slot) {
+ int d;
+ if (sl==0)
+ sl = conf->copies;
+ sl--;
+ d = r10_bio->devs[sl].devnum;
+ rdev = rcu_dereference(conf->mirrors[d].rdev);
+ if (rdev &&
+ test_bit(In_sync, &rdev->flags)) {
+ char b[BDEVNAME_SIZE];
+ atomic_inc(&rdev->nr_pending);
+ rcu_read_unlock();
+ if (sync_page_io(rdev->bdev,
+ r10_bio->devs[sl].addr +
+ sect + rdev->data_offset,
+ s<<9, conf->tmppage, READ) == 0)
+ /* Well, this device is dead */
+ md_error(mddev, rdev);
+ else
+ printk(KERN_INFO
+ "raid10:%s: read error corrected"
+ " (%d sectors at %llu on %s)\n",
+ mdname(mddev), s,
+ (unsigned long long)sect+
+ rdev->data_offset,
+ bdevname(rdev->bdev, b));
+
+ rdev_dec_pending(rdev, mddev);
+ rcu_read_lock();
+ }
+ }
+ rcu_read_unlock();
+
+ sectors -= s;
+ sect += s;
+ }
+}
+
static void raid10d(mddev_t *mddev)
{
r10bio_t *r10_bio;
@@ -1413,105 +1545,12 @@ static void raid10d(mddev_t *mddev)
* This is all done synchronously while the array is
* frozen.
*/
- int sect = 0; /* Offset from r10_bio->sector */
- int sectors = r10_bio->sectors;
- freeze_array(conf);
- if (mddev->ro == 0) while(sectors) {
- int s = sectors;
- int sl = r10_bio->read_slot;
- int success = 0;
-
- if (s > (PAGE_SIZE>>9))
- s = PAGE_SIZE >> 9;
-
- rcu_read_lock();
- do {
- int d = r10_bio->devs[sl].devnum;
- rdev = rcu_dereference(conf->mirrors[d].rdev);
- if (rdev &&
- test_bit(In_sync, &rdev->flags)) {
- atomic_inc(&rdev->nr_pending);
- rcu_read_unlock();
- success = sync_page_io(rdev->bdev,
- r10_bio->devs[sl].addr +
- sect + rdev->data_offset,
- s<<9,
- conf->tmppage, READ);
- rdev_dec_pending(rdev, mddev);
- rcu_read_lock();
- if (success)
- break;
- }
- sl++;
- if (sl == conf->copies)
- sl = 0;
- } while (!success && sl != r10_bio->read_slot);
- rcu_read_unlock();
-
- if (success) {
- int start = sl;
- /* write it back and re-read */
- rcu_read_lock();
- while (sl != r10_bio->read_slot) {
- int d;
- if (sl==0)
- sl = conf->copies;
- sl--;
- d = r10_bio->devs[sl].devnum;
- rdev = rcu_dereference(conf->mirrors[d].rdev);
- if (rdev &&
- test_bit(In_sync, &rdev->flags)) {
- atomic_inc(&rdev->nr_pending);
- rcu_read_unlock();
- atomic_add(s, &rdev->corrected_errors);
- if (sync_page_io(rdev->bdev,
- r10_bio->devs[sl].addr +
- sect + rdev->data_offset,
- s<<9, conf->tmppage, WRITE) == 0)
- /* Well, this device is dead */
- md_error(mddev, rdev);
- rdev_dec_pending(rdev, mddev);
- rcu_read_lock();
- }
- }
- sl = start;
- while (sl != r10_bio->read_slot) {
- int d;
- if (sl==0)
- sl = conf->copies;
- sl--;
- d = r10_bio->devs[sl].devnum;
- rdev = rcu_dereference(conf->mirrors[d].rdev);
- if (rdev &&
- test_bit(In_sync, &rdev->flags)) {
- atomic_inc(&rdev->nr_pending);
- rcu_read_unlock();
- if (sync_page_io(rdev->bdev,
- r10_bio->devs[sl].addr +
- sect + rdev->data_offset,
- s<<9, conf->tmppage, READ) == 0)
- /* Well, this device is dead */
- md_error(mddev, rdev);
- else
- printk(KERN_INFO "raid10:%s: read error corrected (%d sectors at %llu on %s)\n",
- mdname(mddev), s, (unsigned long long)(sect+rdev->data_offset), bdevname(rdev->bdev, b));
-
- rdev_dec_pending(rdev, mddev);
- rcu_read_lock();
- }
- }
- rcu_read_unlock();
- } else {
- /* Cannot read from anywhere -- bye bye array */
- md_error(mddev, conf->mirrors[r10_bio->devs[r10_bio->read_slot].devnum].rdev);
- break;
- }
- sectors -= s;
- sect += s;
+ if (mddev->ro == 0) {
+ freeze_array(conf);
+ fix_read_error(conf, mddev, r10_bio);
+ unfreeze_array(conf);
}
- unfreeze_array(conf);
-
bio = r10_bio->devs[r10_bio->read_slot].bio;
r10_bio->devs[r10_bio->read_slot].bio =
mddev->ro ? IO_BLOCKED : NULL;
@@ -2018,8 +2057,6 @@ static int run(mddev_t *mddev)
mddev->queue->max_sectors = (PAGE_SIZE>>9);
disk->head_position = 0;
- if (!test_bit(Faulty, &rdev->flags) && test_bit(In_sync, &rdev->flags))
- conf->working_disks++;
}
conf->raid_disks = mddev->raid_disks;
conf->mddev = mddev;
@@ -2077,6 +2114,8 @@ static int run(mddev_t *mddev)
mddev->queue->unplug_fn = raid10_unplug;
mddev->queue->issue_flush_fn = raid10_issue_flush;
+ mddev->queue->backing_dev_info.congested_fn = raid10_congested;
+ mddev->queue->backing_dev_info.congested_data = mddev;
/* Calculate max read-ahead size.
* We need to readahead at least twice a whole stripe....
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c
index 450066007160..37e4ff661b6c 100644
--- a/drivers/md/raid5.c
+++ b/drivers/md/raid5.c
@@ -636,7 +636,6 @@ static int raid5_end_write_request (struct bio *bi, unsigned int bytes_done,
struct stripe_head *sh = bi->bi_private;
raid5_conf_t *conf = sh->raid_conf;
int disks = sh->disks, i;
- unsigned long flags;
int uptodate = test_bit(BIO_UPTODATE, &bi->bi_flags);
if (bi->bi_size)
@@ -654,7 +653,6 @@ static int raid5_end_write_request (struct bio *bi, unsigned int bytes_done,
return 0;
}
- spin_lock_irqsave(&conf->device_lock, flags);
if (!uptodate)
md_error(conf->mddev, conf->disks[i].rdev);
@@ -662,8 +660,7 @@ static int raid5_end_write_request (struct bio *bi, unsigned int bytes_done,
clear_bit(R5_LOCKED, &sh->dev[i].flags);
set_bit(STRIPE_HANDLE, &sh->state);
- __release_stripe(conf, sh);
- spin_unlock_irqrestore(&conf->device_lock, flags);
+ release_stripe(sh);
return 0;
}
@@ -696,12 +693,12 @@ static void error(mddev_t *mddev, mdk_rdev_t *rdev)
PRINTK("raid5: error called\n");
if (!test_bit(Faulty, &rdev->flags)) {
- mddev->sb_dirty = 1;
- if (test_bit(In_sync, &rdev->flags)) {
- conf->working_disks--;
+ set_bit(MD_CHANGE_DEVS, &mddev->flags);
+ if (test_and_clear_bit(In_sync, &rdev->flags)) {
+ unsigned long flags;
+ spin_lock_irqsave(&conf->device_lock, flags);
mddev->degraded++;
- conf->failed_disks++;
- clear_bit(In_sync, &rdev->flags);
+ spin_unlock_irqrestore(&conf->device_lock, flags);
/*
* if recovery was running, make sure it aborts.
*/
@@ -711,7 +708,7 @@ static void error(mddev_t *mddev, mdk_rdev_t *rdev)
printk (KERN_ALERT
"raid5: Disk failure on %s, disabling device."
" Operation continuing on %d devices\n",
- bdevname(rdev->bdev,b), conf->working_disks);
+ bdevname(rdev->bdev,b), conf->raid_disks - mddev->degraded);
}
}
@@ -1353,10 +1350,9 @@ static int page_is_zero(struct page *p)
static int stripe_to_pdidx(sector_t stripe, raid5_conf_t *conf, int disks)
{
int sectors_per_chunk = conf->chunk_size >> 9;
- sector_t x = stripe;
int pd_idx, dd_idx;
- int chunk_offset = sector_div(x, sectors_per_chunk);
- stripe = x;
+ int chunk_offset = sector_div(stripe, sectors_per_chunk);
+
raid5_compute_sector(stripe*(disks-1)*sectors_per_chunk
+ chunk_offset, disks, disks-1, &dd_idx, &pd_idx, conf);
return pd_idx;
@@ -2597,6 +2593,24 @@ static int raid5_issue_flush(request_queue_t *q, struct gendisk *disk,
return ret;
}
+static int raid5_congested(void *data, int bits)
+{
+ mddev_t *mddev = data;
+ raid5_conf_t *conf = mddev_to_conf(mddev);
+
+ /* No difference between reads and writes. Just check
+ * how busy the stripe_cache is
+ */
+ if (conf->inactive_blocked)
+ return 1;
+ if (conf->quiesce)
+ return 1;
+ if (list_empty_careful(&conf->inactive_list))
+ return 1;
+
+ return 0;
+}
+
static int make_request(request_queue_t *q, struct bio * bi)
{
mddev_t *mddev = q->queuedata;
@@ -2781,9 +2795,9 @@ static sector_t reshape_request(mddev_t *mddev, sector_t sector_nr, int *skipped
wait_event(conf->wait_for_overlap,
atomic_read(&conf->reshape_stripes)==0);
mddev->reshape_position = conf->expand_progress;
- mddev->sb_dirty = 1;
+ set_bit(MD_CHANGE_DEVS, &mddev->flags);
md_wakeup_thread(mddev->thread);
- wait_event(mddev->sb_wait, mddev->sb_dirty == 0 ||
+ wait_event(mddev->sb_wait, mddev->flags == 0 ||
kthread_should_stop());
spin_lock_irq(&conf->device_lock);
conf->expand_lo = mddev->reshape_position;
@@ -3074,6 +3088,7 @@ static int run(mddev_t *mddev)
mdk_rdev_t *rdev;
struct disk_info *disk;
struct list_head *tmp;
+ int working_disks = 0;
if (mddev->level != 5 && mddev->level != 4 && mddev->level != 6) {
printk(KERN_ERR "raid5: %s: raid level not set to 4/5/6 (%d)\n",
@@ -3176,14 +3191,14 @@ static int run(mddev_t *mddev)
printk(KERN_INFO "raid5: device %s operational as raid"
" disk %d\n", bdevname(rdev->bdev,b),
raid_disk);
- conf->working_disks++;
+ working_disks++;
}
}
/*
* 0 for a fully functional array, 1 or 2 for a degraded array.
*/
- mddev->degraded = conf->failed_disks = conf->raid_disks - conf->working_disks;
+ mddev->degraded = conf->raid_disks - working_disks;
conf->mddev = mddev;
conf->chunk_size = mddev->chunk_size;
conf->level = mddev->level;
@@ -3218,7 +3233,7 @@ static int run(mddev_t *mddev)
if (mddev->degraded > conf->max_degraded) {
printk(KERN_ERR "raid5: not enough operational devices for %s"
" (%d/%d failed)\n",
- mdname(mddev), conf->failed_disks, conf->raid_disks);
+ mdname(mddev), mddev->degraded, conf->raid_disks);
goto abort;
}
@@ -3299,6 +3314,9 @@ static int run(mddev_t *mddev)
mddev->queue->unplug_fn = raid5_unplug_device;
mddev->queue->issue_flush_fn = raid5_issue_flush;
+ mddev->queue->backing_dev_info.congested_fn = raid5_congested;
+ mddev->queue->backing_dev_info.congested_data = mddev;
+
mddev->array_size = mddev->size * (conf->previous_raid_disks -
conf->max_degraded);
@@ -3375,7 +3393,7 @@ static void status (struct seq_file *seq, mddev_t *mddev)
int i;
seq_printf (seq, " level %d, %dk chunk, algorithm %d", mddev->level, mddev->chunk_size >> 10, mddev->layout);
- seq_printf (seq, " [%d/%d] [", conf->raid_disks, conf->working_disks);
+ seq_printf (seq, " [%d/%d] [", conf->raid_disks, conf->raid_disks - mddev->degraded);
for (i = 0; i < conf->raid_disks; i++)
seq_printf (seq, "%s",
conf->disks[i].rdev &&
@@ -3397,8 +3415,8 @@ static void print_raid5_conf (raid5_conf_t *conf)
printk("(conf==NULL)\n");
return;
}
- printk(" --- rd:%d wd:%d fd:%d\n", conf->raid_disks,
- conf->working_disks, conf->failed_disks);
+ printk(" --- rd:%d wd:%d\n", conf->raid_disks,
+ conf->raid_disks - conf->mddev->degraded);
for (i = 0; i < conf->raid_disks; i++) {
char b[BDEVNAME_SIZE];
@@ -3420,11 +3438,11 @@ static int raid5_spare_active(mddev_t *mddev)
tmp = conf->disks + i;
if (tmp->rdev
&& !test_bit(Faulty, &tmp->rdev->flags)
- && !test_bit(In_sync, &tmp->rdev->flags)) {
+ && !test_and_set_bit(In_sync, &tmp->rdev->flags)) {
+ unsigned long flags;
+ spin_lock_irqsave(&conf->device_lock, flags);
mddev->degraded--;
- conf->failed_disks--;
- conf->working_disks++;
- set_bit(In_sync, &tmp->rdev->flags);
+ spin_unlock_irqrestore(&conf->device_lock, flags);
}
}
print_raid5_conf(conf);
@@ -3560,6 +3578,7 @@ static int raid5_start_reshape(mddev_t *mddev)
struct list_head *rtmp;
int spares = 0;
int added_devices = 0;
+ unsigned long flags;
if (mddev->degraded ||
test_bit(MD_RECOVERY_RUNNING, &mddev->recovery))
@@ -3593,7 +3612,6 @@ static int raid5_start_reshape(mddev_t *mddev)
if (raid5_add_disk(mddev, rdev)) {
char nm[20];
set_bit(In_sync, &rdev->flags);
- conf->working_disks++;
added_devices++;
rdev->recovery_offset = 0;
sprintf(nm, "rd%d", rdev->raid_disk);
@@ -3602,10 +3620,12 @@ static int raid5_start_reshape(mddev_t *mddev)
break;
}
+ spin_lock_irqsave(&conf->device_lock, flags);
mddev->degraded = (conf->raid_disks - conf->previous_raid_disks) - added_devices;
+ spin_unlock_irqrestore(&conf->device_lock, flags);
mddev->raid_disks = conf->raid_disks;
mddev->reshape_position = 0;
- mddev->sb_dirty = 1;
+ set_bit(MD_CHANGE_DEVS, &mddev->flags);
clear_bit(MD_RECOVERY_SYNC, &mddev->recovery);
clear_bit(MD_RECOVERY_CHECK, &mddev->recovery);
diff --git a/drivers/media/common/Kconfig b/drivers/media/common/Kconfig
index 1a04db4552da..f33e5d973413 100644
--- a/drivers/media/common/Kconfig
+++ b/drivers/media/common/Kconfig
@@ -4,7 +4,6 @@ config VIDEO_SAA7146
config VIDEO_SAA7146_VV
tristate
- select VIDEO_V4L2
select VIDEO_BUF
select VIDEO_VIDEOBUF
select VIDEO_SAA7146
diff --git a/drivers/media/common/ir-keymaps.c b/drivers/media/common/ir-keymaps.c
index ca98d9478947..db753443587a 100644
--- a/drivers/media/common/ir-keymaps.c
+++ b/drivers/media/common/ir-keymaps.c
@@ -32,6 +32,37 @@ IR_KEYTAB_TYPE ir_codes_empty[IR_KEYTAB_SIZE] = {
EXPORT_SYMBOL_GPL(ir_codes_empty);
+/* Michal Majchrowicz <mmajchrowicz@gmail.com> */
+IR_KEYTAB_TYPE ir_codes_proteus_2309[IR_KEYTAB_SIZE] = {
+ /* numeric */
+ [ 0x00 ] = KEY_0,
+ [ 0x01 ] = KEY_1,
+ [ 0x02 ] = KEY_2,
+ [ 0x03 ] = KEY_3,
+ [ 0x04 ] = KEY_4,
+ [ 0x05 ] = KEY_5,
+ [ 0x06 ] = KEY_6,
+ [ 0x07 ] = KEY_7,
+ [ 0x08 ] = KEY_8,
+ [ 0x09 ] = KEY_9,
+
+ [ 0x5c ] = KEY_POWER, /* power */
+ [ 0x20 ] = KEY_F, /* full screen */
+ [ 0x0f ] = KEY_BACKSPACE, /* recall */
+ [ 0x1b ] = KEY_ENTER, /* mute */
+ [ 0x41 ] = KEY_RECORD, /* record */
+ [ 0x43 ] = KEY_STOP, /* stop */
+ [ 0x16 ] = KEY_S,
+ [ 0x1a ] = KEY_Q, /* off */
+ [ 0x2e ] = KEY_RED,
+ [ 0x1f ] = KEY_DOWN, /* channel - */
+ [ 0x1c ] = KEY_UP, /* channel + */
+ [ 0x10 ] = KEY_LEFT, /* volume - */
+ [ 0x1e ] = KEY_RIGHT, /* volume + */
+ [ 0x14 ] = KEY_F1,
+};
+
+EXPORT_SYMBOL_GPL(ir_codes_proteus_2309);
/* Matt Jesson <dvb@jesson.eclipse.co.uk */
IR_KEYTAB_TYPE ir_codes_avermedia_dvbt[IR_KEYTAB_SIZE] = {
[ 0x28 ] = KEY_0, //'0' / 'enter'
@@ -1473,3 +1504,51 @@ IR_KEYTAB_TYPE ir_codes_npgtech[IR_KEYTAB_SIZE] = {
};
EXPORT_SYMBOL_GPL(ir_codes_npgtech);
+
+/* Norwood Micro (non-Pro) TV Tuner
+ By Peter Naulls <peter@chocky.org>
+ Key comments are the functions given in the manual */
+IR_KEYTAB_TYPE ir_codes_norwood[IR_KEYTAB_SIZE] = {
+ /* Keys 0 to 9 */
+ [ 0x20 ] = KEY_0,
+ [ 0x21 ] = KEY_1,
+ [ 0x22 ] = KEY_2,
+ [ 0x23 ] = KEY_3,
+ [ 0x24 ] = KEY_4,
+ [ 0x25 ] = KEY_5,
+ [ 0x26 ] = KEY_6,
+ [ 0x27 ] = KEY_7,
+ [ 0x28 ] = KEY_8,
+ [ 0x29 ] = KEY_9,
+
+ [ 0x78 ] = KEY_TUNER, /* Video Source */
+ [ 0x2c ] = KEY_EXIT, /* Open/Close software */
+ [ 0x2a ] = KEY_SELECT, /* 2 Digit Select */
+ [ 0x69 ] = KEY_AGAIN, /* Recall */
+
+ [ 0x32 ] = KEY_BRIGHTNESSUP, /* Brightness increase */
+ [ 0x33 ] = KEY_BRIGHTNESSDOWN, /* Brightness decrease */
+ [ 0x6b ] = KEY_KPPLUS, /* (not named >>>>>) */
+ [ 0x6c ] = KEY_KPMINUS, /* (not named <<<<<) */
+
+ [ 0x2d ] = KEY_MUTE, /* Mute */
+ [ 0x30 ] = KEY_VOLUMEUP, /* Volume up */
+ [ 0x31 ] = KEY_VOLUMEDOWN, /* Volume down */
+ [ 0x60 ] = KEY_CHANNELUP, /* Channel up */
+ [ 0x61 ] = KEY_CHANNELDOWN, /* Channel down */
+
+ [ 0x3f ] = KEY_RECORD, /* Record */
+ [ 0x37 ] = KEY_PLAY, /* Play */
+ [ 0x36 ] = KEY_PAUSE, /* Pause */
+ [ 0x2b ] = KEY_STOP, /* Stop */
+ [ 0x67 ] = KEY_FASTFORWARD, /* Foward */
+ [ 0x66 ] = KEY_REWIND, /* Rewind */
+ [ 0x3e ] = KEY_SEARCH, /* Auto Scan */
+ [ 0x2e ] = KEY_CAMERA, /* Capture Video */
+ [ 0x6d ] = KEY_MENU, /* Show/Hide Control */
+ [ 0x2f ] = KEY_ZOOM, /* Full Screen */
+ [ 0x34 ] = KEY_RADIO, /* FM */
+ [ 0x65 ] = KEY_POWER, /* Computer power */
+};
+
+EXPORT_SYMBOL_GPL(ir_codes_norwood);
diff --git a/drivers/media/common/saa7146_fops.c b/drivers/media/common/saa7146_fops.c
index 0027acc5b8e9..d867a6a9e430 100644
--- a/drivers/media/common/saa7146_fops.c
+++ b/drivers/media/common/saa7146_fops.c
@@ -455,7 +455,6 @@ static void vv_callback(struct saa7146_dev *dev, unsigned long status)
static struct video_device device_template =
{
- .hardware = VID_HARDWARE_SAA7146,
.fops = &video_fops,
.minor = -1,
};
diff --git a/drivers/media/dvb/b2c2/Kconfig b/drivers/media/dvb/b2c2/Kconfig
index 49a06fc54c51..a0dcd59da76e 100644
--- a/drivers/media/dvb/b2c2/Kconfig
+++ b/drivers/media/dvb/b2c2/Kconfig
@@ -2,13 +2,13 @@ config DVB_B2C2_FLEXCOP
tristate "Technisat/B2C2 FlexCopII(b) and FlexCopIII adapters"
depends on DVB_CORE && I2C
select DVB_PLL
- select DVB_STV0299
- select DVB_MT352
- select DVB_MT312
- select DVB_NXT200X
- select DVB_STV0297
- select DVB_BCM3510
- select DVB_LGDT330X
+ select DVB_STV0299 if !DVB_FE_CUSTOMISE
+ select DVB_MT352 if !DVB_FE_CUSTOMISE
+ select DVB_MT312 if !DVB_FE_CUSTOMISE
+ select DVB_NXT200X if !DVB_FE_CUSTOMISE
+ select DVB_STV0297 if !DVB_FE_CUSTOMISE
+ select DVB_BCM3510 if !DVB_FE_CUSTOMISE
+ select DVB_LGDT330X if !DVB_FE_CUSTOMISE
help
Support for the digital TV receiver chip made by B2C2 Inc. included in
Technisats PCI cards and USB boxes.
diff --git a/drivers/media/dvb/b2c2/flexcop-fe-tuner.c b/drivers/media/dvb/b2c2/flexcop-fe-tuner.c
index 3be87c72e37b..b8ba87863457 100644
--- a/drivers/media/dvb/b2c2/flexcop-fe-tuner.c
+++ b/drivers/media/dvb/b2c2/flexcop-fe-tuner.c
@@ -505,7 +505,7 @@ int flexcop_frontend_init(struct flexcop_device *fc)
struct dvb_frontend_ops *ops;
/* try the sky v2.6 (stv0299/Samsung tbmu24112(sl1935)) */
- if ((fc->fe = stv0299_attach(&samsung_tbmu24112_config, &fc->i2c_adap)) != NULL) {
+ if ((fc->fe = dvb_attach(stv0299_attach, &samsung_tbmu24112_config, &fc->i2c_adap)) != NULL) {
ops = &fc->fe->ops;
ops->tuner_ops.set_params = samsung_tbmu24112_tuner_set_params;
@@ -519,36 +519,36 @@ int flexcop_frontend_init(struct flexcop_device *fc)
info("found the stv0299 at i2c address: 0x%02x",samsung_tbmu24112_config.demod_address);
} else
/* try the air dvb-t (mt352/Samsung tdtc9251dh0(??)) */
- if ((fc->fe = mt352_attach(&samsung_tdtc9251dh0_config, &fc->i2c_adap)) != NULL ) {
+ if ((fc->fe = dvb_attach(mt352_attach, &samsung_tdtc9251dh0_config, &fc->i2c_adap)) != NULL ) {
fc->dev_type = FC_AIR_DVB;
fc->fe->ops.tuner_ops.calc_regs = samsung_tdtc9251dh0_calc_regs;
info("found the mt352 at i2c address: 0x%02x",samsung_tdtc9251dh0_config.demod_address);
} else
/* try the air atsc 2nd generation (nxt2002) */
- if ((fc->fe = nxt200x_attach(&samsung_tbmv_config, &fc->i2c_adap)) != NULL) {
+ if ((fc->fe = dvb_attach(nxt200x_attach, &samsung_tbmv_config, &fc->i2c_adap)) != NULL) {
fc->dev_type = FC_AIR_ATSC2;
- dvb_pll_attach(fc->fe, 0x61, &fc->i2c_adap, &dvb_pll_samsung_tbmv);
+ dvb_attach(dvb_pll_attach, fc->fe, 0x61, NULL, &dvb_pll_samsung_tbmv);
info("found the nxt2002 at i2c address: 0x%02x",samsung_tbmv_config.demod_address);
} else
/* try the air atsc 3nd generation (lgdt3303) */
- if ((fc->fe = lgdt330x_attach(&air2pc_atsc_hd5000_config, &fc->i2c_adap)) != NULL) {
+ if ((fc->fe = dvb_attach(lgdt330x_attach, &air2pc_atsc_hd5000_config, &fc->i2c_adap)) != NULL) {
fc->dev_type = FC_AIR_ATSC3;
fc->fe->ops.tuner_ops.set_params = lgdt3303_tuner_set_params;
info("found the lgdt3303 at i2c address: 0x%02x",air2pc_atsc_hd5000_config.demod_address);
} else
/* try the air atsc 1nd generation (bcm3510)/panasonic ct10s */
- if ((fc->fe = bcm3510_attach(&air2pc_atsc_first_gen_config, &fc->i2c_adap)) != NULL) {
+ if ((fc->fe = dvb_attach(bcm3510_attach, &air2pc_atsc_first_gen_config, &fc->i2c_adap)) != NULL) {
fc->dev_type = FC_AIR_ATSC1;
info("found the bcm3510 at i2c address: 0x%02x",air2pc_atsc_first_gen_config.demod_address);
} else
/* try the cable dvb (stv0297) */
- if ((fc->fe = stv0297_attach(&alps_tdee4_stv0297_config, &fc->i2c_adap)) != NULL) {
+ if ((fc->fe = dvb_attach(stv0297_attach, &alps_tdee4_stv0297_config, &fc->i2c_adap)) != NULL) {
fc->dev_type = FC_CABLE;
fc->fe->ops.tuner_ops.set_params = alps_tdee4_stv0297_tuner_set_params;
info("found the stv0297 at i2c address: 0x%02x",alps_tdee4_stv0297_config.demod_address);
} else
/* try the sky v2.3 (vp310/Samsung tbdu18132(tsa5059)) */
- if ((fc->fe = vp310_mt312_attach(&skystar23_samsung_tbdu18132_config, &fc->i2c_adap)) != NULL) {
+ if ((fc->fe = dvb_attach(vp310_mt312_attach, &skystar23_samsung_tbdu18132_config, &fc->i2c_adap)) != NULL) {
ops = &fc->fe->ops;
ops->tuner_ops.set_params = skystar23_samsung_tbdu18132_tuner_set_params;
@@ -571,9 +571,7 @@ int flexcop_frontend_init(struct flexcop_device *fc)
} else {
if (dvb_register_frontend(&fc->dvb_adapter, fc->fe)) {
err("frontend registration failed!");
- ops = &fc->fe->ops;
- if (ops->release != NULL)
- ops->release(fc->fe);
+ dvb_frontend_detach(fc->fe);
fc->fe = NULL;
return -EINVAL;
}
@@ -584,8 +582,10 @@ int flexcop_frontend_init(struct flexcop_device *fc)
void flexcop_frontend_exit(struct flexcop_device *fc)
{
- if (fc->init_state & FC_STATE_FE_INIT)
+ if (fc->init_state & FC_STATE_FE_INIT) {
dvb_unregister_frontend(fc->fe);
+ dvb_frontend_detach(fc->fe);
+ }
fc->init_state &= ~FC_STATE_FE_INIT;
}
diff --git a/drivers/media/dvb/bt8xx/Kconfig b/drivers/media/dvb/bt8xx/Kconfig
index 7d0ee1ab2903..ae2ff5dc238d 100644
--- a/drivers/media/dvb/bt8xx/Kconfig
+++ b/drivers/media/dvb/bt8xx/Kconfig
@@ -2,13 +2,13 @@ config DVB_BT8XX
tristate "BT8xx based PCI cards"
depends on DVB_CORE && PCI && I2C && VIDEO_BT848
select DVB_PLL
- select DVB_MT352
- select DVB_SP887X
- select DVB_NXT6000
- select DVB_CX24110
- select DVB_OR51211
- select DVB_LGDT330X
- select DVB_ZL10353
+ select DVB_MT352 if !DVB_FE_CUSTOMISE
+ select DVB_SP887X if !DVB_FE_CUSTOMISE
+ select DVB_NXT6000 if !DVB_FE_CUSTOMISE
+ select DVB_CX24110 if !DVB_FE_CUSTOMISE
+ select DVB_OR51211 if !DVB_FE_CUSTOMISE
+ select DVB_LGDT330X if !DVB_FE_CUSTOMISE
+ select DVB_ZL10353 if !DVB_FE_CUSTOMISE
select FW_LOADER
help
Support for PCI cards based on the Bt8xx PCI bridge. Examples are
diff --git a/drivers/media/dvb/bt8xx/dst.c b/drivers/media/dvb/bt8xx/dst.c
index 06ac899a9a26..9f72b7000c08 100644
--- a/drivers/media/dvb/bt8xx/dst.c
+++ b/drivers/media/dvb/bt8xx/dst.c
@@ -1715,6 +1715,15 @@ static int dst_get_frontend(struct dvb_frontend *fe, struct dvb_frontend_paramet
static void dst_release(struct dvb_frontend *fe)
{
struct dst_state *state = fe->demodulator_priv;
+ if (state->dst_ca) {
+ dvb_unregister_device(state->dst_ca);
+#ifdef CONFIG_DVB_CORE_ATTACH
+ symbol_put(dst_ca_attach);
+#endif
+ }
+#ifdef CONFIG_DVB_CORE_ATTACH
+ symbol_put(dst_attach);
+#endif
kfree(state);
}
diff --git a/drivers/media/dvb/bt8xx/dst_ca.c b/drivers/media/dvb/bt8xx/dst_ca.c
index fa923b9b346e..240ad084fa78 100644
--- a/drivers/media/dvb/bt8xx/dst_ca.c
+++ b/drivers/media/dvb/bt8xx/dst_ca.c
@@ -699,12 +699,17 @@ static struct dvb_device dvbdev_ca = {
.fops = &dst_ca_fops
};
-int dst_ca_attach(struct dst_state *dst, struct dvb_adapter *dvb_adapter)
+struct dvb_device *dst_ca_attach(struct dst_state *dst, struct dvb_adapter *dvb_adapter)
{
struct dvb_device *dvbdev;
+
dprintk(verbose, DST_CA_ERROR, 1, "registering DST-CA device");
- dvb_register_device(dvb_adapter, &dvbdev, &dvbdev_ca, dst, DVB_DEVICE_CA);
- return 0;
+ if (dvb_register_device(dvb_adapter, &dvbdev, &dvbdev_ca, dst, DVB_DEVICE_CA) == 0) {
+ dst->dst_ca = dvbdev;
+ return dst->dst_ca;
+ }
+
+ return NULL;
}
EXPORT_SYMBOL(dst_ca_attach);
diff --git a/drivers/media/dvb/bt8xx/dst_common.h b/drivers/media/dvb/bt8xx/dst_common.h
index 0677b047b3a7..3bf084f2e522 100644
--- a/drivers/media/dvb/bt8xx/dst_common.h
+++ b/drivers/media/dvb/bt8xx/dst_common.h
@@ -140,6 +140,7 @@ struct dst_state {
char *tuner_name;
struct mutex dst_mutex;
u8 fw_name[8];
+ struct dvb_device *dst_ca;
};
struct tuner_types {
@@ -178,7 +179,7 @@ int write_dst(struct dst_state *state, u8 * data, u8 len);
int read_dst(struct dst_state *state, u8 * ret, u8 len);
u8 dst_check_sum(u8 * buf, u32 len);
struct dst_state* dst_attach(struct dst_state* state, struct dvb_adapter *dvb_adapter);
-int dst_ca_attach(struct dst_state *state, struct dvb_adapter *dvb_adapter);
+struct dvb_device *dst_ca_attach(struct dst_state *state, struct dvb_adapter *dvb_adapter);
int dst_gpio_outb(struct dst_state* state, u32 mask, u32 enbb, u32 outhigh, int delay);
int dst_command(struct dst_state* state, u8 * data, u8 len);
diff --git a/drivers/media/dvb/bt8xx/dvb-bt8xx.c b/drivers/media/dvb/bt8xx/dvb-bt8xx.c
index b715b972d2fc..fb6c4cc8477d 100644
--- a/drivers/media/dvb/bt8xx/dvb-bt8xx.c
+++ b/drivers/media/dvb/bt8xx/dvb-bt8xx.c
@@ -67,7 +67,7 @@ static void dvb_bt8xx_task(unsigned long data)
static int dvb_bt8xx_start_feed(struct dvb_demux_feed *dvbdmxfeed)
{
- struct dvb_demux *dvbdmx = dvbdmxfeed->demux;
+ struct dvb_demux*dvbdmx = dvbdmxfeed->demux;
struct dvb_bt8xx_card *card = dvbdmx->priv;
int rc;
@@ -595,15 +595,14 @@ static void lgdt330x_reset(struct dvb_bt8xx_card *bt)
static void frontend_init(struct dvb_bt8xx_card *card, u32 type)
{
- int ret;
struct dst_state* state = NULL;
switch(type) {
case BTTV_BOARD_DVICO_DVBT_LITE:
- card->fe = mt352_attach(&thomson_dtt7579_config, card->i2c_adapter);
+ card->fe = dvb_attach(mt352_attach, &thomson_dtt7579_config, card->i2c_adapter);
if (card->fe == NULL)
- card->fe = zl10353_attach(&thomson_dtt7579_zl10353_config,
+ card->fe = dvb_attach(zl10353_attach, &thomson_dtt7579_zl10353_config,
card->i2c_adapter);
if (card->fe != NULL) {
@@ -615,7 +614,7 @@ static void frontend_init(struct dvb_bt8xx_card *card, u32 type)
case BTTV_BOARD_DVICO_FUSIONHDTV_5_LITE:
lgdt330x_reset(card);
- card->fe = lgdt330x_attach(&tdvs_tua6034_config, card->i2c_adapter);
+ card->fe = dvb_attach(lgdt330x_attach, &tdvs_tua6034_config, card->i2c_adapter);
if (card->fe != NULL) {
card->fe->ops.tuner_ops.set_params = tdvs_tua6034_tuner_set_params;
dprintk ("dvb_bt8xx: lgdt330x detected\n");
@@ -630,7 +629,7 @@ static void frontend_init(struct dvb_bt8xx_card *card, u32 type)
/* Old Nebula (marked (c)2003 on high profile pci card) has nxt6000 demod */
digitv_alps_tded4_reset(card);
- card->fe = nxt6000_attach(&vp3021_alps_tded4_config, card->i2c_adapter);
+ card->fe = dvb_attach(nxt6000_attach, &vp3021_alps_tded4_config, card->i2c_adapter);
if (card->fe != NULL) {
card->fe->ops.tuner_ops.set_params = vp3021_alps_tded4_tuner_set_params;
dprintk ("dvb_bt8xx: an nxt6000 was detected on your digitv card\n");
@@ -639,7 +638,7 @@ static void frontend_init(struct dvb_bt8xx_card *card, u32 type)
/* New Nebula (marked (c)2005 on low profile pci card) has mt352 demod */
digitv_alps_tded4_reset(card);
- card->fe = mt352_attach(&digitv_alps_tded4_config, card->i2c_adapter);
+ card->fe = dvb_attach(mt352_attach, &digitv_alps_tded4_config, card->i2c_adapter);
if (card->fe != NULL) {
card->fe->ops.tuner_ops.calc_regs = digitv_alps_tded4_tuner_calc_regs;
@@ -648,14 +647,14 @@ static void frontend_init(struct dvb_bt8xx_card *card, u32 type)
break;
case BTTV_BOARD_AVDVBT_761:
- card->fe = sp887x_attach(&microtune_mt7202dtf_config, card->i2c_adapter);
+ card->fe = dvb_attach(sp887x_attach, &microtune_mt7202dtf_config, card->i2c_adapter);
if (card->fe) {
card->fe->ops.tuner_ops.set_params = microtune_mt7202dtf_tuner_set_params;
}
break;
case BTTV_BOARD_AVDVBT_771:
- card->fe = mt352_attach(&advbt771_samsung_tdtc9251dh0_config, card->i2c_adapter);
+ card->fe = dvb_attach(mt352_attach, &advbt771_samsung_tdtc9251dh0_config, card->i2c_adapter);
if (card->fe != NULL) {
card->fe->ops.tuner_ops.calc_regs = advbt771_samsung_tdtc9251dh0_tuner_calc_regs;
card->fe->ops.info.frequency_min = 174000000;
@@ -670,22 +669,21 @@ static void frontend_init(struct dvb_bt8xx_card *card, u32 type)
state->config = &dst_config;
state->i2c = card->i2c_adapter;
state->bt = card->bt;
-
+ state->dst_ca = NULL;
/* DST is not a frontend, attaching the ASIC */
- if ((dst_attach(state, &card->dvb_adapter)) == NULL) {
+ if (dvb_attach(dst_attach, state, &card->dvb_adapter) == NULL) {
printk("%s: Could not find a Twinhan DST.\n", __FUNCTION__);
break;
}
- card->fe = &state->frontend;
-
/* Attach other DST peripherals if any */
/* Conditional Access device */
+ card->fe = &state->frontend;
if (state->dst_hw_cap & DST_TYPE_HAS_CA)
- ret = dst_ca_attach(state, &card->dvb_adapter);
+ dvb_attach(dst_ca_attach, state, &card->dvb_adapter);
break;
case BTTV_BOARD_PINNACLESAT:
- card->fe = cx24110_attach(&pctvsat_config, card->i2c_adapter);
+ card->fe = dvb_attach(cx24110_attach, &pctvsat_config, card->i2c_adapter);
if (card->fe) {
card->fe->ops.tuner_ops.init = pinnsat_tuner_init;
card->fe->ops.tuner_ops.sleep = pinnsat_tuner_sleep;
@@ -694,7 +692,7 @@ static void frontend_init(struct dvb_bt8xx_card *card, u32 type)
break;
case BTTV_BOARD_PC_HDTV:
- card->fe = or51211_attach(&or51211_config, card->i2c_adapter);
+ card->fe = dvb_attach(or51211_attach, &or51211_config, card->i2c_adapter);
break;
}
@@ -707,8 +705,7 @@ static void frontend_init(struct dvb_bt8xx_card *card, u32 type)
else
if (dvb_register_frontend(&card->dvb_adapter, card->fe)) {
printk("dvb-bt8xx: Frontend registration failed!\n");
- if (card->fe->ops.release)
- card->fe->ops.release(card->fe);
+ dvb_frontend_detach(card->fe);
card->fe = NULL;
}
}
@@ -925,8 +922,10 @@ static void dvb_bt8xx_remove(struct bttv_sub_device *sub)
card->demux.dmx.remove_frontend(&card->demux.dmx, &card->fe_hw);
dvb_dmxdev_release(&card->dmxdev);
dvb_dmx_release(&card->demux);
- if (card->fe)
+ if (card->fe) {
dvb_unregister_frontend(card->fe);
+ dvb_frontend_detach(card->fe);
+ }
dvb_unregister_adapter(&card->dvb_adapter);
kfree(card);
diff --git a/drivers/media/dvb/dvb-core/Kconfig b/drivers/media/dvb/dvb-core/Kconfig
index 12ee912a5705..e46eae3b9be2 100644
--- a/drivers/media/dvb/dvb-core/Kconfig
+++ b/drivers/media/dvb/dvb-core/Kconfig
@@ -9,3 +9,16 @@ config DVB_CORE
in-kernel drivers will select this automatically if needed.
If unsure say N.
+config DVB_CORE_ATTACH
+ bool "Load and attach frontend modules as needed"
+ depends on DVB_CORE
+ depends on MODULES
+ help
+ Remove the static dependency of DVB card drivers on all
+ frontend modules for all possible card variants. Instead,
+ allow the card drivers to only load the frontend modules
+ they require. This saves several KBytes of memory.
+
+ Note: You will need moudule-init-tools v3.2 or later for this feature.
+
+ If unsure say Y.
diff --git a/drivers/media/dvb/dvb-core/dvb_frontend.c b/drivers/media/dvb/dvb-core/dvb_frontend.c
index 57b34cda99f5..3dd5dbafb330 100644
--- a/drivers/media/dvb/dvb-core/dvb_frontend.c
+++ b/drivers/media/dvb/dvb-core/dvb_frontend.c
@@ -1105,18 +1105,42 @@ int dvb_unregister_frontend(struct dvb_frontend* fe)
mutex_lock(&frontend_mutex);
dvb_unregister_device (fepriv->dvbdev);
dvb_frontend_stop (fe);
- if (fe->ops.tuner_ops.release) {
- fe->ops.tuner_ops.release(fe);
- if (fe->ops.i2c_gate_ctrl)
- fe->ops.i2c_gate_ctrl(fe, 0);
- }
- if (fe->ops.release)
- fe->ops.release(fe);
- else
- printk("dvb_frontend: Demodulator (%s) does not have a release callback!\n", fe->ops.info.name);
+
/* fe is invalid now */
kfree(fepriv);
mutex_unlock(&frontend_mutex);
return 0;
}
EXPORT_SYMBOL(dvb_unregister_frontend);
+
+#ifdef CONFIG_DVB_CORE_ATTACH
+void dvb_frontend_detach(struct dvb_frontend* fe)
+{
+ void *ptr;
+
+ if (fe->ops.release_sec) {
+ fe->ops.release_sec(fe);
+ symbol_put_addr(fe->ops.release_sec);
+ }
+ if (fe->ops.tuner_ops.release) {
+ fe->ops.tuner_ops.release(fe);
+ symbol_put_addr(fe->ops.tuner_ops.release);
+ }
+ ptr = (void*)fe->ops.release;
+ if (ptr) {
+ fe->ops.release(fe);
+ symbol_put_addr(ptr);
+ }
+}
+#else
+void dvb_frontend_detach(struct dvb_frontend* fe)
+{
+ if (fe->ops.release_sec)
+ fe->ops.release_sec(fe);
+ if (fe->ops.tuner_ops.release)
+ fe->ops.tuner_ops.release(fe);
+ if (fe->ops.release)
+ fe->ops.release(fe);
+}
+#endif
+EXPORT_SYMBOL(dvb_frontend_detach);
diff --git a/drivers/media/dvb/dvb-core/dvb_frontend.h b/drivers/media/dvb/dvb-core/dvb_frontend.h
index 2887e2b862a4..e5d5028b3694 100644
--- a/drivers/media/dvb/dvb-core/dvb_frontend.h
+++ b/drivers/media/dvb/dvb-core/dvb_frontend.h
@@ -92,10 +92,13 @@ struct dvb_frontend_ops {
struct dvb_frontend_info info;
void (*release)(struct dvb_frontend* fe);
+ void (*release_sec)(struct dvb_frontend* fe);
int (*init)(struct dvb_frontend* fe);
int (*sleep)(struct dvb_frontend* fe);
+ int (*write)(struct dvb_frontend* fe, u8* buf, int len);
+
/* if this is set, it overrides the default swzigzag */
int (*tune)(struct dvb_frontend* fe,
struct dvb_frontend_parameters* params,
@@ -147,7 +150,7 @@ struct dvb_frontend {
void* demodulator_priv;
void* tuner_priv;
void* frontend_priv;
- void* misc_priv;
+ void* sec_priv;
};
extern int dvb_register_frontend(struct dvb_adapter* dvb,
@@ -155,6 +158,8 @@ extern int dvb_register_frontend(struct dvb_adapter* dvb,
extern int dvb_unregister_frontend(struct dvb_frontend* fe);
+extern void dvb_frontend_detach(struct dvb_frontend* fe);
+
extern void dvb_frontend_reinitialise(struct dvb_frontend *fe);
extern void dvb_frontend_sleep_until(struct timeval *waketime, u32 add_usec);
diff --git a/drivers/media/dvb/dvb-core/dvb_ringbuffer.c b/drivers/media/dvb/dvb-core/dvb_ringbuffer.c
index c972fe014c58..9878183ba3f0 100644
--- a/drivers/media/dvb/dvb-core/dvb_ringbuffer.c
+++ b/drivers/media/dvb/dvb-core/dvb_ringbuffer.c
@@ -26,7 +26,6 @@
-#define __KERNEL_SYSCALLS__
#include <linux/errno.h>
#include <linux/kernel.h>
#include <linux/module.h>
diff --git a/drivers/media/dvb/dvb-core/dvbdev.h b/drivers/media/dvb/dvb-core/dvbdev.h
index 7a7f75fd168c..620e7887b3d3 100644
--- a/drivers/media/dvb/dvb-core/dvbdev.h
+++ b/drivers/media/dvb/dvb-core/dvbdev.h
@@ -102,4 +102,26 @@ extern int dvb_usercopy(struct inode *inode, struct file *file,
int (*func)(struct inode *inode, struct file *file,
unsigned int cmd, void *arg));
+/** generic DVB attach function. */
+#ifdef CONFIG_DVB_CORE_ATTACH
+#define dvb_attach(FUNCTION, ARGS...) ({ \
+ void *__r = NULL; \
+ typeof(&FUNCTION) __a = symbol_request(FUNCTION); \
+ if (__a) { \
+ __r = (void *) __a(ARGS); \
+ if (__r == NULL) \
+ symbol_put(FUNCTION); \
+ } else { \
+ printk(KERN_ERR "DVB: Unable to find symbol "#FUNCTION"()\n"); \
+ } \
+ __r; \
+})
+
+#else
+#define dvb_attach(FUNCTION, ARGS...) ({ \
+ FUNCTION(ARGS); \
+})
+
+#endif
+
#endif /* #ifndef _DVBDEV_H_ */
diff --git a/drivers/media/dvb/dvb-usb/Kconfig b/drivers/media/dvb/dvb-usb/Kconfig
index 75824b77198a..0a3c35399bea 100644
--- a/drivers/media/dvb/dvb-usb/Kconfig
+++ b/drivers/media/dvb/dvb-usb/Kconfig
@@ -26,6 +26,7 @@ config DVB_USB_A800
tristate "AVerMedia AverTV DVB-T USB 2.0 (A800)"
depends on DVB_USB
select DVB_DIB3000MC
+ select DVB_TUNER_MT2060
help
Say Y here to support the AVerMedia AverTV DVB-T USB 2.0 (A800) receiver.
@@ -33,6 +34,7 @@ config DVB_USB_DIBUSB_MB
tristate "DiBcom USB DVB-T devices (based on the DiB3000M-B) (see help for device list)"
depends on DVB_USB
select DVB_DIB3000MB
+ select DVB_TUNER_MT2060
help
Support for USB 1.1 and 2.0 DVB-T receivers based on reference designs made by
DiBcom (<http://www.dibcom.fr>) equipped with a DiB3000M-B demodulator.
@@ -65,6 +67,7 @@ config DVB_USB_DIBUSB_MC
tristate "DiBcom USB DVB-T devices (based on the DiB3000M-C/P) (see help for device list)"
depends on DVB_USB
select DVB_DIB3000MC
+ select DVB_TUNER_MT2060
help
Support for 2.0 DVB-T receivers based on reference designs made by
DiBcom (<http://www.dibcom.fr>) equipped with a DiB3000M-C/P demodulator.
@@ -80,16 +83,17 @@ config DVB_USB_UMT_010
tristate "HanfTek UMT-010 DVB-T USB2.0 support"
depends on DVB_USB
select DVB_DIB3000MC
+ select DVB_TUNER_MT2060
help
Say Y here to support the HanfTek UMT-010 USB2.0 stick-sized DVB-T receiver.
config DVB_USB_CXUSB
tristate "Conexant USB2.0 hybrid reference design support"
depends on DVB_USB
- select DVB_CX22702
- select DVB_LGDT330X
- select DVB_MT352
- select DVB_ZL10353
+ select DVB_CX22702 if !DVB_FE_CUSTOMISE
+ select DVB_LGDT330X if !DVB_FE_CUSTOMISE
+ select DVB_MT352 if !DVB_FE_CUSTOMISE
+ select DVB_ZL10353 if !DVB_FE_CUSTOMISE
help
Say Y here to support the Conexant USB2.0 hybrid reference design.
Currently, only DVB and ATSC modes are supported, analog mode
@@ -101,8 +105,8 @@ config DVB_USB_CXUSB
config DVB_USB_DIGITV
tristate "Nebula Electronics uDigiTV DVB-T USB2.0 support"
depends on DVB_USB
- select DVB_NXT6000
- select DVB_MT352
+ select DVB_NXT6000 if !DVB_FE_CUSTOMISE
+ select DVB_MT352 if !DVB_FE_CUSTOMISE
help
Say Y here to support the Nebula Electronics uDigitV USB2.0 DVB-T receiver.
@@ -145,6 +149,7 @@ config DVB_USB_NOVA_T_USB2
tristate "Hauppauge WinTV-NOVA-T usb2 DVB-T USB2.0 support"
depends on DVB_USB
select DVB_DIB3000MC
+ select DVB_TUNER_MT2060
help
Say Y here to support the Hauppauge WinTV-NOVA-T usb2 DVB-T USB2.0 receiver.
diff --git a/drivers/media/dvb/dvb-usb/a800.c b/drivers/media/dvb/dvb-usb/a800.c
index ce44aa6bbb83..df0c384bd4ca 100644
--- a/drivers/media/dvb/dvb-usb/a800.c
+++ b/drivers/media/dvb/dvb-usb/a800.c
@@ -26,6 +26,13 @@ static int a800_power_ctrl(struct dvb_usb_device *d, int onoff)
return 0;
}
+/* assure to put cold to 0 for iManufacturer == 1 */
+static int a800_identify_state(struct usb_device *udev, struct dvb_usb_properties *props,struct dvb_usb_device_description **desc, int *cold)
+{
+ *cold = udev->descriptor.iManufacturer != 1;
+ return 0;
+}
+
static struct dvb_usb_rc_key a800_rc_keys[] = {
{ 0x02, 0x01, KEY_PROG1 }, /* SOURCE */
{ 0x02, 0x00, KEY_POWER }, /* POWER */
@@ -113,6 +120,7 @@ static struct dvb_usb_properties a800_properties = {
.power_ctrl = a800_power_ctrl,
.frontend_attach = dibusb_dib3000mc_frontend_attach,
.tuner_attach = dibusb_dib3000mc_tuner_attach,
+ .identify_state = a800_identify_state,
.rc_interval = DEFAULT_RC_INTERVAL,
.rc_key_map = a800_rc_keys,
diff --git a/drivers/media/dvb/dvb-usb/cxusb.c b/drivers/media/dvb/dvb-usb/cxusb.c
index ae23bdde42a8..c710c0176e07 100644
--- a/drivers/media/dvb/dvb-usb/cxusb.c
+++ b/drivers/media/dvb/dvb-usb/cxusb.c
@@ -349,6 +349,7 @@ static struct mt352_config cxusb_dee1601_config = {
static struct zl10353_config cxusb_zl10353_dee1601_config = {
.demod_address = 0x0f,
+ .parallel_ts = 1,
};
static struct mt352_config cxusb_mt352_config = {
@@ -409,7 +410,7 @@ static int cxusb_cx22702_frontend_attach(struct dvb_usb_device *d)
cxusb_ctrl_msg(d,CMD_DIGITAL, NULL, 0, &b, 1);
- if ((d->fe = cx22702_attach(&cxusb_cx22702_config, &d->i2c_adap)) != NULL)
+ if ((d->fe = dvb_attach(cx22702_attach, &cxusb_cx22702_config, &d->i2c_adap)) != NULL)
return 0;
return -EIO;
@@ -422,7 +423,7 @@ static int cxusb_lgdt3303_frontend_attach(struct dvb_usb_device *d)
cxusb_ctrl_msg(d,CMD_DIGITAL, NULL, 0, NULL, 0);
- if ((d->fe = lgdt330x_attach(&cxusb_lgdt3303_config, &d->i2c_adap)) != NULL)
+ if ((d->fe = dvb_attach(lgdt330x_attach, &cxusb_lgdt3303_config, &d->i2c_adap)) != NULL)
return 0;
return -EIO;
@@ -435,7 +436,7 @@ static int cxusb_mt352_frontend_attach(struct dvb_usb_device *d)
cxusb_ctrl_msg(d,CMD_DIGITAL, NULL, 0, NULL, 0);
- if ((d->fe = mt352_attach(&cxusb_mt352_config, &d->i2c_adap)) != NULL)
+ if ((d->fe = dvb_attach(mt352_attach, &cxusb_mt352_config, &d->i2c_adap)) != NULL)
return 0;
return -EIO;
@@ -448,8 +449,8 @@ static int cxusb_dee1601_frontend_attach(struct dvb_usb_device *d)
cxusb_ctrl_msg(d,CMD_DIGITAL, NULL, 0, NULL, 0);
- if (((d->fe = mt352_attach(&cxusb_dee1601_config, &d->i2c_adap)) != NULL) ||
- ((d->fe = zl10353_attach(&cxusb_zl10353_dee1601_config, &d->i2c_adap)) != NULL))
+ if (((d->fe = dvb_attach(mt352_attach, &cxusb_dee1601_config, &d->i2c_adap)) != NULL) ||
+ ((d->fe = dvb_attach(zl10353_attach, &cxusb_zl10353_dee1601_config, &d->i2c_adap)) != NULL))
return 0;
return -EIO;
diff --git a/drivers/media/dvb/dvb-usb/dibusb-common.c b/drivers/media/dvb/dvb-usb/dibusb-common.c
index abd75b4a350d..124e25ac53b3 100644
--- a/drivers/media/dvb/dvb-usb/dibusb-common.c
+++ b/drivers/media/dvb/dvb-usb/dibusb-common.c
@@ -131,9 +131,6 @@ static int dibusb_i2c_xfer(struct i2c_adapter *adap,struct i2c_msg msg[],int num
if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
return -EAGAIN;
- if (num > 2)
- warn("more than 2 i2c messages at a time is not handled yet. TODO.");
-
for (i = 0; i < num; i++) {
/* write/read request */
if (i+1 < num && (msg[i+1].flags & I2C_M_RD)) {
@@ -168,31 +165,137 @@ int dibusb_read_eeprom_byte(struct dvb_usb_device *d, u8 offs, u8 *val)
}
EXPORT_SYMBOL(dibusb_read_eeprom_byte);
+/* 3000MC/P stuff */
+// Config Adjacent channels Perf -cal22
+static struct dibx000_agc_config dib3000p_mt2060_agc_config = {
+ .band_caps = BAND_VHF | BAND_UHF,
+ .setup = (0 << 15) | (0 << 14) | (1 << 13) | (1 << 12) | (29 << 0),
+
+ .agc1_max = 48497,
+ .agc1_min = 23593,
+ .agc2_max = 46531,
+ .agc2_min = 24904,
+
+ .agc1_pt1 = 0x65,
+ .agc1_pt2 = 0x69,
+
+ .agc1_slope1 = 0x51,
+ .agc1_slope2 = 0x27,
+
+ .agc2_pt1 = 0,
+ .agc2_pt2 = 0x33,
+
+ .agc2_slope1 = 0x35,
+ .agc2_slope2 = 0x37,
+};
+
+static struct dib3000mc_config stk3000p_dib3000p_config = {
+ &dib3000p_mt2060_agc_config,
+
+ .max_time = 0x196,
+ .ln_adc_level = 0x1cc7,
+
+ .output_mpeg2_in_188_bytes = 1,
+};
+
+static struct dibx000_agc_config dib3000p_panasonic_agc_config = {
+ .setup = (0 << 15) | (0 << 14) | (1 << 13) | (1 << 12) | (29 << 0),
+
+ .agc1_max = 56361,
+ .agc1_min = 22282,
+ .agc2_max = 47841,
+ .agc2_min = 36045,
+
+ .agc1_pt1 = 0x3b,
+ .agc1_pt2 = 0x6b,
+
+ .agc1_slope1 = 0x55,
+ .agc1_slope2 = 0x1d,
+
+ .agc2_pt1 = 0,
+ .agc2_pt2 = 0x0a,
+
+ .agc2_slope1 = 0x95,
+ .agc2_slope2 = 0x1e,
+};
+
+static struct dib3000mc_config mod3000p_dib3000p_config = {
+ &dib3000p_panasonic_agc_config,
+
+ .max_time = 0x51,
+ .ln_adc_level = 0x1cc7,
+
+ .output_mpeg2_in_188_bytes = 1,
+};
+
int dibusb_dib3000mc_frontend_attach(struct dvb_usb_device *d)
{
- struct dib3000_config demod_cfg;
- struct dibusb_state *st = d->priv;
-
- for (demod_cfg.demod_address = 0x8; demod_cfg.demod_address < 0xd; demod_cfg.demod_address++)
- if ((d->fe = dib3000mc_attach(&demod_cfg,&d->i2c_adap,&st->ops)) != NULL) {
- d->fe->ops.tuner_ops.init = dvb_usb_tuner_init_i2c;
- d->fe->ops.tuner_ops.set_params = dvb_usb_tuner_set_params_i2c;
- d->tuner_pass_ctrl = st->ops.tuner_pass_ctrl;
- return 0;
+ if (dib3000mc_attach(&d->i2c_adap, 1, DEFAULT_DIB3000P_I2C_ADDRESS, 0, &mod3000p_dib3000p_config, &d->fe) == 0 ||
+ dib3000mc_attach(&d->i2c_adap, 1, DEFAULT_DIB3000MC_I2C_ADDRESS, 0, &mod3000p_dib3000p_config, &d->fe) == 0) {
+ if (d->priv != NULL) {
+ struct dibusb_state *st = d->priv;
+ st->ops.pid_parse = dib3000mc_pid_parse;
+ st->ops.pid_ctrl = dib3000mc_pid_control;
}
-
+ return 0;
+ }
return -ENODEV;
}
EXPORT_SYMBOL(dibusb_dib3000mc_frontend_attach);
+static struct mt2060_config stk3000p_mt2060_config = {
+ 0x60
+};
+
int dibusb_dib3000mc_tuner_attach (struct dvb_usb_device *d)
{
- d->pll_addr = 0x60;
- d->pll_desc = &dvb_pll_env57h1xd5;
-
- d->fe->ops.tuner_ops.init = dvb_usb_tuner_init_i2c;
- d->fe->ops.tuner_ops.set_params = dvb_usb_tuner_set_params_i2c;
+ struct dibusb_state *st = d->priv;
+ int ret;
+ u8 a,b;
+ u16 if1 = 1220;
+ struct i2c_adapter *tun_i2c;
+
+ // First IF calibration for Liteon Sticks
+ if (d->udev->descriptor.idVendor == USB_VID_LITEON &&
+ d->udev->descriptor.idProduct == USB_PID_LITEON_DVB_T_WARM) {
+
+ dibusb_read_eeprom_byte(d,0x7E,&a);
+ dibusb_read_eeprom_byte(d,0x7F,&b);
+
+ if (a == 0x00)
+ if1 += b;
+ else if (a == 0x80)
+ if1 -= b;
+ else
+ warn("LITE-ON DVB-T: Strange IF1 calibration :%2X %2X\n", a, b);
+
+ } else if (d->udev->descriptor.idVendor == USB_VID_DIBCOM &&
+ d->udev->descriptor.idProduct == USB_PID_DIBCOM_MOD3001_WARM) {
+ u8 desc;
+ dibusb_read_eeprom_byte(d, 7, &desc);
+ if (desc == 2) {
+ a = 127;
+ do {
+ dibusb_read_eeprom_byte(d, a, &desc);
+ a--;
+ } while (a > 7 && (desc == 0xff || desc == 0x00));
+ if (desc & 0x80)
+ if1 -= (0xff - desc);
+ else
+ if1 += desc;
+ }
+ }
+ tun_i2c = dib3000mc_get_tuner_i2c_master(d->fe, 1);
+ if ((ret = mt2060_attach(d->fe, tun_i2c, &stk3000p_mt2060_config, if1)) != 0) {
+ /* not found - use panasonic pll parameters */
+ if (dvb_pll_attach(d->fe, 0x60, tun_i2c, &dvb_pll_env57h1xd5) == NULL)
+ return -ENOMEM;
+ } else {
+ st->mt2060_present = 1;
+ /* set the correct parameters for the dib3000p */
+ dib3000mc_set_config(d->fe, &stk3000p_dib3000p_config);
+ }
return 0;
}
EXPORT_SYMBOL(dibusb_dib3000mc_tuner_attach);
@@ -267,6 +370,67 @@ struct dvb_usb_rc_key dibusb_rc_keys[] = {
{ 0x86, 0x1e, KEY_DOWN },
{ 0x86, 0x1f, KEY_LEFT },
{ 0x86, 0x1b, KEY_RIGHT },
+
+ /* Key codes for the DiBcom MOD3000 remote. */
+ { 0x80, 0x00, KEY_MUTE },
+ { 0x80, 0x01, KEY_TEXT },
+ { 0x80, 0x02, KEY_HOME },
+ { 0x80, 0x03, KEY_POWER },
+
+ { 0x80, 0x04, KEY_RED },
+ { 0x80, 0x05, KEY_GREEN },
+ { 0x80, 0x06, KEY_YELLOW },
+ { 0x80, 0x07, KEY_BLUE },
+
+ { 0x80, 0x08, KEY_DVD },
+ { 0x80, 0x09, KEY_AUDIO },
+ { 0x80, 0x0a, KEY_MEDIA }, /* Pictures */
+ { 0x80, 0x0b, KEY_VIDEO },
+
+ { 0x80, 0x0c, KEY_BACK },
+ { 0x80, 0x0d, KEY_UP },
+ { 0x80, 0x0e, KEY_RADIO },
+ { 0x80, 0x0f, KEY_EPG },
+
+ { 0x80, 0x10, KEY_LEFT },
+ { 0x80, 0x11, KEY_OK },
+ { 0x80, 0x12, KEY_RIGHT },
+ { 0x80, 0x13, KEY_UNKNOWN }, /* SAP */
+
+ { 0x80, 0x14, KEY_TV },
+ { 0x80, 0x15, KEY_DOWN },
+ { 0x80, 0x16, KEY_MENU }, /* DVD Menu */
+ { 0x80, 0x17, KEY_LAST },
+
+ { 0x80, 0x18, KEY_RECORD },
+ { 0x80, 0x19, KEY_STOP },
+ { 0x80, 0x1a, KEY_PAUSE },
+ { 0x80, 0x1b, KEY_PLAY },
+
+ { 0x80, 0x1c, KEY_PREVIOUS },
+ { 0x80, 0x1d, KEY_REWIND },
+ { 0x80, 0x1e, KEY_FASTFORWARD },
+ { 0x80, 0x1f, KEY_NEXT},
+
+ { 0x80, 0x40, KEY_1 },
+ { 0x80, 0x41, KEY_2 },
+ { 0x80, 0x42, KEY_3 },
+ { 0x80, 0x43, KEY_CHANNELUP },
+
+ { 0x80, 0x44, KEY_4 },
+ { 0x80, 0x45, KEY_5 },
+ { 0x80, 0x46, KEY_6 },
+ { 0x80, 0x47, KEY_CHANNELDOWN },
+
+ { 0x80, 0x48, KEY_7 },
+ { 0x80, 0x49, KEY_8 },
+ { 0x80, 0x4a, KEY_9 },
+ { 0x80, 0x4b, KEY_VOLUMEUP },
+
+ { 0x80, 0x4c, KEY_CLEAR },
+ { 0x80, 0x4d, KEY_0 },
+ { 0x80, 0x4e, KEY_ENTER },
+ { 0x80, 0x4f, KEY_VOLUMEDOWN },
};
EXPORT_SYMBOL(dibusb_rc_keys);
diff --git a/drivers/media/dvb/dvb-usb/dibusb-mb.c b/drivers/media/dvb/dvb-usb/dibusb-mb.c
index f4c45f386ebc..effd34cc4b02 100644
--- a/drivers/media/dvb/dvb-usb/dibusb-mb.c
+++ b/drivers/media/dvb/dvb-usb/dibusb-mb.c
@@ -21,11 +21,11 @@ static int dibusb_dib3000mb_frontend_attach(struct dvb_usb_device *d)
demod_cfg.demod_address = 0x8;
- if ((d->fe = dib3000mb_attach(&demod_cfg,&d->i2c_adap,&st->ops)) == NULL) {
- d->fe->ops.tuner_ops.init = dvb_usb_tuner_init_i2c;
- d->fe->ops.tuner_ops.set_params = dvb_usb_tuner_set_params_i2c;
+ if ((d->fe = dib3000mb_attach(&demod_cfg,&d->i2c_adap,&st->ops)) == NULL)
return -ENODEV;
- }
+
+ d->fe->ops.tuner_ops.init = dvb_usb_tuner_init_i2c;
+ d->fe->ops.tuner_ops.set_params = dvb_usb_tuner_set_params_i2c;
d->tuner_pass_ctrl = st->ops.tuner_pass_ctrl;
@@ -169,7 +169,7 @@ static struct dvb_usb_properties dibusb1_1_properties = {
.rc_interval = DEFAULT_RC_INTERVAL,
.rc_key_map = dibusb_rc_keys,
- .rc_key_map_size = 63, /* wow, that is ugly ... I want to load it to the driver dynamically */
+ .rc_key_map_size = 111, /* wow, that is ugly ... I want to load it to the driver dynamically */
.rc_query = dibusb_rc_query,
.i2c_algo = &dibusb_i2c_algo,
@@ -247,7 +247,7 @@ static struct dvb_usb_properties dibusb1_1_an2235_properties = {
.rc_interval = DEFAULT_RC_INTERVAL,
.rc_key_map = dibusb_rc_keys,
- .rc_key_map_size = 63, /* wow, that is ugly ... I want to load it to the driver dynamically */
+ .rc_key_map_size = 111, /* wow, that is ugly ... I want to load it to the driver dynamically */
.rc_query = dibusb_rc_query,
.i2c_algo = &dibusb_i2c_algo,
@@ -272,8 +272,8 @@ static struct dvb_usb_properties dibusb1_1_an2235_properties = {
#endif
.devices = {
{ "Artec T1 USB1.1 TVBOX with AN2235",
- { &dibusb_dib3000mb_table[20], NULL },
{ &dibusb_dib3000mb_table[21], NULL },
+ { &dibusb_dib3000mb_table[22], NULL },
},
#ifdef CONFIG_DVB_USB_DIBUSB_MB_FAULTY
{ "Artec T1 USB1.1 TVBOX with AN2235 (faulty USB IDs)",
@@ -304,7 +304,7 @@ static struct dvb_usb_properties dibusb2_0b_properties = {
.rc_interval = DEFAULT_RC_INTERVAL,
.rc_key_map = dibusb_rc_keys,
- .rc_key_map_size = 63, /* wow, that is ugly ... I want to load it to the driver dynamically */
+ .rc_key_map_size = 111, /* wow, that is ugly ... I want to load it to the driver dynamically */
.rc_query = dibusb_rc_query,
.i2c_algo = &dibusb_i2c_algo,
@@ -355,7 +355,7 @@ static struct dvb_usb_properties artec_t1_usb2_properties = {
.rc_interval = DEFAULT_RC_INTERVAL,
.rc_key_map = dibusb_rc_keys,
- .rc_key_map_size = 63, /* wow, that is ugly ... I want to load it to the driver dynamically */
+ .rc_key_map_size = 111, /* wow, that is ugly ... I want to load it to the driver dynamically */
.rc_query = dibusb_rc_query,
.i2c_algo = &dibusb_i2c_algo,
diff --git a/drivers/media/dvb/dvb-usb/dibusb-mc.c b/drivers/media/dvb/dvb-usb/dibusb-mc.c
index 55802fba3c29..eca4082a61ae 100644
--- a/drivers/media/dvb/dvb-usb/dibusb-mc.c
+++ b/drivers/media/dvb/dvb-usb/dibusb-mc.c
@@ -28,6 +28,17 @@ static struct usb_device_id dibusb_dib3000mc_table [] = {
/* 00 */ { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_MOD3001_COLD) },
/* 01 */ { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_MOD3001_WARM) },
/* 02 */ { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_USB2_COLD) },
+/* 03 */ { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_USB2_WARM) }, // ( ? )
+/* 04 */ { USB_DEVICE(USB_VID_LITEON, USB_PID_LITEON_DVB_T_COLD) },
+/* 05 */ { USB_DEVICE(USB_VID_LITEON, USB_PID_LITEON_DVB_T_WARM) },
+/* 06 */ { USB_DEVICE(USB_VID_EMPIA, USB_PID_DIGIVOX_MINI_SL_COLD) },
+/* 07 */ { USB_DEVICE(USB_VID_EMPIA, USB_PID_DIGIVOX_MINI_SL_WARM) },
+/* 08 */ { USB_DEVICE(USB_VID_GRANDTEC, USB_PID_GRANDTEC_DVBT_USB2_COLD) },
+/* 09 */ { USB_DEVICE(USB_VID_GRANDTEC, USB_PID_GRANDTEC_DVBT_USB2_WARM) },
+/* 10 */ { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ARTEC_T14_COLD) },
+/* 11 */ { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ARTEC_T14_WARM) },
+/* 12 */ { USB_DEVICE(USB_VID_LEADTEK, USB_PID_WINFAST_DTV_DONGLE_COLD) },
+/* 13 */ { USB_DEVICE(USB_VID_LEADTEK, USB_PID_WINFAST_DTV_DONGLE_WARM) },
{ } /* Terminating entry */
};
MODULE_DEVICE_TABLE (usb, dibusb_dib3000mc_table);
@@ -50,7 +61,7 @@ static struct dvb_usb_properties dibusb_mc_properties = {
.rc_interval = DEFAULT_RC_INTERVAL,
.rc_key_map = dibusb_rc_keys,
- .rc_key_map_size = 63, /* FIXME */
+ .rc_key_map_size = 111, /* FIXME */
.rc_query = dibusb_rc_query,
.i2c_algo = &dibusb_i2c_algo,
@@ -68,16 +79,38 @@ static struct dvb_usb_properties dibusb_mc_properties = {
}
},
- .num_device_descs = 2,
+ .num_device_descs = 7,
.devices = {
{ "DiBcom USB2.0 DVB-T reference design (MOD3000P)",
{ &dibusb_dib3000mc_table[0], NULL },
{ &dibusb_dib3000mc_table[1], NULL },
},
- { "Artec T1 USB2.0 TVBOX (please report the warm ID)",
+ { "Artec T1 USB2.0 TVBOX (please check the warm ID)",
{ &dibusb_dib3000mc_table[2], NULL },
- { NULL },
+ { &dibusb_dib3000mc_table[3], NULL },
},
+ { "LITE-ON USB2.0 DVB-T Tuner",
+ /* Also rebranded as Intuix S800, Toshiba */
+ { &dibusb_dib3000mc_table[4], NULL },
+ { &dibusb_dib3000mc_table[5], NULL },
+ },
+ { "MSI Digivox Mini SL",
+ { &dibusb_dib3000mc_table[6], NULL },
+ { &dibusb_dib3000mc_table[7], NULL },
+ },
+ { "GRAND - USB2.0 DVB-T adapter",
+ { &dibusb_dib3000mc_table[8], NULL },
+ { &dibusb_dib3000mc_table[9], NULL },
+ },
+ { "Artec T14 - USB2.0 DVB-T",
+ { &dibusb_dib3000mc_table[10], NULL },
+ { &dibusb_dib3000mc_table[11], NULL },
+ },
+ { "Leadtek - USB2.0 Winfast DTV dongle",
+ { &dibusb_dib3000mc_table[12], NULL },
+ { &dibusb_dib3000mc_table[13], NULL },
+ },
+ { NULL },
}
};
diff --git a/drivers/media/dvb/dvb-usb/dibusb.h b/drivers/media/dvb/dvb-usb/dibusb.h
index 2d99d05c7eab..a43f87480cf6 100644
--- a/drivers/media/dvb/dvb-usb/dibusb.h
+++ b/drivers/media/dvb/dvb-usb/dibusb.h
@@ -17,6 +17,8 @@
#include "dvb-usb.h"
#include "dib3000.h"
+#include "dib3000mc.h"
+#include "mt2060.h"
/*
* protocol of all dibusb related devices
@@ -96,6 +98,7 @@
struct dibusb_state {
struct dib_fe_xfer_ops ops;
+ int mt2060_present;
/* for RC5 remote control */
int old_toggle;
diff --git a/drivers/media/dvb/dvb-usb/digitv.c b/drivers/media/dvb/dvb-usb/digitv.c
index c14d9efb48fd..015854487308 100644
--- a/drivers/media/dvb/dvb-usb/digitv.c
+++ b/drivers/media/dvb/dvb-usb/digitv.c
@@ -128,11 +128,11 @@ static struct nxt6000_config digitv_nxt6000_config = {
static int digitv_frontend_attach(struct dvb_usb_device *d)
{
- if ((d->fe = mt352_attach(&digitv_mt352_config, &d->i2c_adap)) != NULL) {
+ if ((d->fe = dvb_attach(mt352_attach, &digitv_mt352_config, &d->i2c_adap)) != NULL) {
d->fe->ops.tuner_ops.calc_regs = dvb_usb_tuner_calc_regs;
return 0;
}
- if ((d->fe = nxt6000_attach(&digitv_nxt6000_config, &d->i2c_adap)) != NULL) {
+ if ((d->fe = dvb_attach(nxt6000_attach, &digitv_nxt6000_config, &d->i2c_adap)) != NULL) {
d->fe->ops.tuner_ops.set_params = digitv_nxt6000_tuner_set_params;
return 0;
}
@@ -147,21 +147,91 @@ static int digitv_tuner_attach(struct dvb_usb_device *d)
}
static struct dvb_usb_rc_key digitv_rc_keys[] = {
- { 0x00, 0x16, KEY_POWER }, /* dummy key */
+ { 0x5f, 0x55, KEY_0 },
+ { 0x6f, 0x55, KEY_1 },
+ { 0x9f, 0x55, KEY_2 },
+ { 0xaf, 0x55, KEY_3 },
+ { 0x5f, 0x56, KEY_4 },
+ { 0x6f, 0x56, KEY_5 },
+ { 0x9f, 0x56, KEY_6 },
+ { 0xaf, 0x56, KEY_7 },
+ { 0x5f, 0x59, KEY_8 },
+ { 0x6f, 0x59, KEY_9 },
+ { 0x9f, 0x59, KEY_TV },
+ { 0xaf, 0x59, KEY_AUX },
+ { 0x5f, 0x5a, KEY_DVD },
+ { 0x6f, 0x5a, KEY_POWER },
+ { 0x9f, 0x5a, KEY_MHP }, /* labelled 'Picture' */
+ { 0xaf, 0x5a, KEY_AUDIO },
+ { 0x5f, 0x65, KEY_INFO },
+ { 0x6f, 0x65, KEY_F13 }, /* 16:9 */
+ { 0x9f, 0x65, KEY_F14 }, /* 14:9 */
+ { 0xaf, 0x65, KEY_EPG },
+ { 0x5f, 0x66, KEY_EXIT },
+ { 0x6f, 0x66, KEY_MENU },
+ { 0x9f, 0x66, KEY_UP },
+ { 0xaf, 0x66, KEY_DOWN },
+ { 0x5f, 0x69, KEY_LEFT },
+ { 0x6f, 0x69, KEY_RIGHT },
+ { 0x9f, 0x69, KEY_ENTER },
+ { 0xaf, 0x69, KEY_CHANNELUP },
+ { 0x5f, 0x6a, KEY_CHANNELDOWN },
+ { 0x6f, 0x6a, KEY_VOLUMEUP },
+ { 0x9f, 0x6a, KEY_VOLUMEDOWN },
+ { 0xaf, 0x6a, KEY_RED },
+ { 0x5f, 0x95, KEY_GREEN },
+ { 0x6f, 0x95, KEY_YELLOW },
+ { 0x9f, 0x95, KEY_BLUE },
+ { 0xaf, 0x95, KEY_SUBTITLE },
+ { 0x5f, 0x96, KEY_F15 }, /* AD */
+ { 0x6f, 0x96, KEY_TEXT },
+ { 0x9f, 0x96, KEY_MUTE },
+ { 0xaf, 0x96, KEY_REWIND },
+ { 0x5f, 0x99, KEY_STOP },
+ { 0x6f, 0x99, KEY_PLAY },
+ { 0x9f, 0x99, KEY_FASTFORWARD },
+ { 0xaf, 0x99, KEY_F16 }, /* chapter */
+ { 0x5f, 0x9a, KEY_PAUSE },
+ { 0x6f, 0x9a, KEY_PLAY },
+ { 0x9f, 0x9a, KEY_RECORD },
+ { 0xaf, 0x9a, KEY_F17 }, /* picture in picture */
+ { 0x5f, 0xa5, KEY_KPPLUS }, /* zoom in */
+ { 0x6f, 0xa5, KEY_KPMINUS }, /* zoom out */
+ { 0x9f, 0xa5, KEY_F18 }, /* capture */
+ { 0xaf, 0xa5, KEY_F19 }, /* web */
+ { 0x5f, 0xa6, KEY_EMAIL },
+ { 0x6f, 0xa6, KEY_PHONE },
+ { 0x9f, 0xa6, KEY_PC },
};
-/* TODO is it really the NEC protocol ? */
static int digitv_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
{
+ int i;
u8 key[5];
+ u8 b[4] = { 0 };
+
+ *event = 0;
+ *state = REMOTE_NO_KEY_PRESSED;
digitv_ctrl_msg(d,USB_READ_REMOTE,0,NULL,0,&key[1],4);
- /* TODO state, maybe it is VV ? */
+
+ /* Tell the device we've read the remote. Not sure how necessary
+ this is, but the Nebula SDK does it. */
+ digitv_ctrl_msg(d,USB_WRITE_REMOTE,0,b,4,NULL,0);
+
+ /* if something is inside the buffer, simulate key press */
if (key[1] != 0)
- key[0] = 0x01; /* if something is inside the buffer, simulate key press */
+ {
+ for (i = 0; i < d->props.rc_key_map_size; i++) {
+ if (d->props.rc_key_map[i].custom == key[1] &&
+ d->props.rc_key_map[i].data == key[2]) {
+ *event = d->props.rc_key_map[i].event;
+ *state = REMOTE_KEY_PRESSED;
+ return 0;
+ }
+ }
+ }
- /* call the universal NEC remote processor, to find out the key's state and event */
- dvb_usb_nec_rc_key_to_event(d,key,event,state);
if (key[0] != 0)
deb_rc("key: %x %x %x %x %x\n",key[0],key[1],key[2],key[3],key[4]);
return 0;
diff --git a/drivers/media/dvb/dvb-usb/dtt200u.c b/drivers/media/dvb/dvb-usb/dtt200u.c
index 70afcfd141ca..27af4e436479 100644
--- a/drivers/media/dvb/dvb-usb/dtt200u.c
+++ b/drivers/media/dvb/dvb-usb/dtt200u.c
@@ -93,6 +93,7 @@ static int dtt200u_frontend_attach(struct dvb_usb_device *d)
}
static struct dvb_usb_properties dtt200u_properties;
+static struct dvb_usb_properties wt220u_fc_properties;
static struct dvb_usb_properties wt220u_properties;
static struct dvb_usb_properties wt220u_zl0353_properties;
@@ -101,6 +102,7 @@ static int dtt200u_usb_probe(struct usb_interface *intf,
{
if (dvb_usb_device_init(intf,&dtt200u_properties,THIS_MODULE,NULL) == 0 ||
dvb_usb_device_init(intf,&wt220u_properties,THIS_MODULE,NULL) == 0 ||
+ dvb_usb_device_init(intf,&wt220u_fc_properties,THIS_MODULE,NULL) == 0 ||
dvb_usb_device_init(intf,&wt220u_zl0353_properties,THIS_MODULE,NULL) == 0)
return 0;
@@ -114,6 +116,9 @@ static struct usb_device_id dtt200u_usb_table [] = {
{ USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_WT220U_WARM) },
{ USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_WT220U_ZL0353_COLD) },
{ USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_WT220U_ZL0353_WARM) },
+ { USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_WT220U_FC_COLD) },
+ { USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_WT220U_FC_WARM) },
+ { USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_WT220U_ZAP250_COLD) },
{ 0 },
};
MODULE_DEVICE_TABLE(usb, dtt200u_usb_table);
@@ -193,13 +198,54 @@ static struct dvb_usb_properties wt220u_properties = {
.num_device_descs = 1,
.devices = {
{ .name = "WideView WT-220U PenType Receiver (Typhoon/Freecom)",
- .cold_ids = { &dtt200u_usb_table[2], NULL },
+ .cold_ids = { &dtt200u_usb_table[2], &dtt200u_usb_table[8], NULL },
.warm_ids = { &dtt200u_usb_table[3], NULL },
},
{ NULL },
}
};
+static struct dvb_usb_properties wt220u_fc_properties = {
+ .caps = DVB_USB_HAS_PID_FILTER | DVB_USB_NEED_PID_FILTERING,
+ .pid_filter_count = 15,
+
+ .usb_ctrl = CYPRESS_FX2,
+ .firmware = "dvb-usb-wt220u-fc03.fw",
+
+ .power_ctrl = dtt200u_power_ctrl,
+ .streaming_ctrl = dtt200u_streaming_ctrl,
+ .pid_filter = dtt200u_pid_filter,
+ .frontend_attach = dtt200u_frontend_attach,
+
+ .rc_interval = 300,
+ .rc_key_map = dtt200u_rc_keys,
+ .rc_key_map_size = ARRAY_SIZE(dtt200u_rc_keys),
+ .rc_query = dtt200u_rc_query,
+
+ .generic_bulk_ctrl_endpoint = 0x01,
+
+ /* parameter for the MPEG2-data transfer */
+ .urb = {
+ .type = DVB_USB_BULK,
+ .count = 7,
+ .endpoint = 0x86,
+ .u = {
+ .bulk = {
+ .buffersize = 4096,
+ }
+ }
+ },
+
+ .num_device_descs = 1,
+ .devices = {
+ { .name = "WideView WT-220U PenType Receiver (Typhoon/Freecom)",
+ .cold_ids = { &dtt200u_usb_table[6], NULL },
+ .warm_ids = { &dtt200u_usb_table[7], NULL },
+ },
+ { NULL },
+ }
+};
+
static struct dvb_usb_properties wt220u_zl0353_properties = {
.caps = DVB_USB_HAS_PID_FILTER | DVB_USB_NEED_PID_FILTERING,
.pid_filter_count = 15,
@@ -271,6 +317,6 @@ module_init(dtt200u_usb_module_init);
module_exit(dtt200u_usb_module_exit);
MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@desy.de>");
-MODULE_DESCRIPTION("Driver for the WideView/Yakumo/Hama/Typhoon DVB-T USB2.0 devices");
+MODULE_DESCRIPTION("Driver for the WideView/Yakumo/Hama/Typhoon/Club3D DVB-T USB2.0 devices");
MODULE_VERSION("1.0");
MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-dvb.c b/drivers/media/dvb/dvb-usb/dvb-usb-dvb.c
index ec631708c394..fe6208ada903 100644
--- a/drivers/media/dvb/dvb-usb/dvb-usb-dvb.c
+++ b/drivers/media/dvb/dvb-usb/dvb-usb-dvb.c
@@ -175,36 +175,36 @@ static int dvb_usb_fe_sleep(struct dvb_frontend *fe)
int dvb_usb_fe_init(struct dvb_usb_device* d)
{
if (d->props.frontend_attach == NULL) {
- err("strange '%s' doesn't want to attach a frontend.",d->desc->name);
+ err("strange: '%s' doesn't want to attach a frontend.",d->desc->name);
return 0;
}
- d->props.frontend_attach(d);
-
/* re-assign sleep and wakeup functions */
- if (d->fe != NULL) {
+ if (d->props.frontend_attach(d) == 0 && d->fe != NULL) {
d->fe_init = d->fe->ops.init; d->fe->ops.init = dvb_usb_fe_wakeup;
d->fe_sleep = d->fe->ops.sleep; d->fe->ops.sleep = dvb_usb_fe_sleep;
if (dvb_register_frontend(&d->dvb_adap, d->fe)) {
err("Frontend registration failed.");
- if (d->fe->ops.release)
- d->fe->ops.release(d->fe);
+ dvb_frontend_detach(d->fe);
d->fe = NULL;
return -ENODEV;
}
+
+ /* only attach the tuner if the demod is there */
+ if (d->props.tuner_attach != NULL)
+ d->props.tuner_attach(d);
} else
err("no frontend was attached by '%s'",d->desc->name);
- if (d->props.tuner_attach != NULL)
- d->props.tuner_attach(d);
-
return 0;
}
int dvb_usb_fe_exit(struct dvb_usb_device *d)
{
- if (d->fe != NULL)
+ if (d->fe != NULL) {
dvb_unregister_frontend(d->fe);
+ dvb_frontend_detach(d->fe);
+ }
return 0;
}
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
index 95698918bc11..57a10de1d3dd 100644
--- a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
+++ b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
@@ -10,51 +10,53 @@
#define _DVB_USB_IDS_H_
/* Vendor IDs */
-#define USB_VID_ADSTECH 0x06e1
-#define USB_VID_ANCHOR 0x0547
-#define USB_VID_WIDEVIEW 0x14aa
-#define USB_VID_AVERMEDIA 0x07ca
-#define USB_VID_COMPRO 0x185b
-#define USB_VID_COMPRO_UNK 0x145f
-#define USB_VID_CYPRESS 0x04b4
-#define USB_VID_DIBCOM 0x10b8
-#define USB_VID_DVICO 0x0fe9
-#define USB_VID_EMPIA 0xeb1a
-#define USB_VID_GRANDTEC 0x5032
-#define USB_VID_HANFTEK 0x15f4
-#define USB_VID_HAUPPAUGE 0x2040
-#define USB_VID_HYPER_PALTEK 0x1025
-#define USB_VID_KWORLD 0xeb2a
-#define USB_VID_KYE 0x0458
-#define USB_VID_MEDION 0x1660
-#define USB_VID_PINNACLE 0x2304
-#define USB_VID_VISIONPLUS 0x13d3
-#define USB_VID_TWINHAN 0x1822
-#define USB_VID_ULTIMA_ELECTRONIC 0x05d8
-#define USB_VID_GENPIX 0x09c0
+#define USB_VID_ADSTECH 0x06e1
+#define USB_VID_ANCHOR 0x0547
+#define USB_VID_AVERMEDIA 0x07ca
+#define USB_VID_COMPRO 0x185b
+#define USB_VID_COMPRO_UNK 0x145f
+#define USB_VID_CYPRESS 0x04b4
+#define USB_VID_DIBCOM 0x10b8
+#define USB_VID_DVICO 0x0fe9
+#define USB_VID_EMPIA 0xeb1a
+#define USB_VID_GENPIX 0x09c0
+#define USB_VID_GRANDTEC 0x5032
+#define USB_VID_HANFTEK 0x15f4
+#define USB_VID_HAUPPAUGE 0x2040
+#define USB_VID_HYPER_PALTEK 0x1025
+#define USB_VID_KWORLD 0xeb2a
+#define USB_VID_KYE 0x0458
+#define USB_VID_LEADTEK 0x0413
+#define USB_VID_LITEON 0x04ca
+#define USB_VID_MEDION 0x1660
+#define USB_VID_PINNACLE 0x2304
+#define USB_VID_VISIONPLUS 0x13d3
+#define USB_VID_TWINHAN 0x1822
+#define USB_VID_ULTIMA_ELECTRONIC 0x05d8
+#define USB_VID_WIDEVIEW 0x14aa
/* Product IDs */
#define USB_PID_ADSTECH_USB2_COLD 0xa333
#define USB_PID_ADSTECH_USB2_WARM 0xa334
-#define USB_PID_AVERMEDIA_DVBT_USB_COLD 0x0001
-#define USB_PID_AVERMEDIA_DVBT_USB_WARM 0x0002
-#define USB_PID_AVERMEDIA_DVBT_USB2_COLD 0xa800
-#define USB_PID_AVERMEDIA_DVBT_USB2_WARM 0xa801
-#define USB_PID_COMPRO_DVBU2000_COLD 0xd000
-#define USB_PID_COMPRO_DVBU2000_WARM 0xd001
-#define USB_PID_COMPRO_DVBU2000_UNK_COLD 0x010c
-#define USB_PID_COMPRO_DVBU2000_UNK_WARM 0x010d
+#define USB_PID_AVERMEDIA_DVBT_USB_COLD 0x0001
+#define USB_PID_AVERMEDIA_DVBT_USB_WARM 0x0002
+#define USB_PID_AVERMEDIA_DVBT_USB2_COLD 0xa800
+#define USB_PID_AVERMEDIA_DVBT_USB2_WARM 0xa801
+#define USB_PID_COMPRO_DVBU2000_COLD 0xd000
+#define USB_PID_COMPRO_DVBU2000_WARM 0xd001
+#define USB_PID_COMPRO_DVBU2000_UNK_COLD 0x010c
+#define USB_PID_COMPRO_DVBU2000_UNK_WARM 0x010d
#define USB_PID_DIBCOM_HOOK_DEFAULT 0x0064
-#define USB_PID_DIBCOM_HOOK_DEFAULT_REENUM 0x0065
+#define USB_PID_DIBCOM_HOOK_DEFAULT_REENUM 0x0065
#define USB_PID_DIBCOM_MOD3000_COLD 0x0bb8
#define USB_PID_DIBCOM_MOD3000_WARM 0x0bb9
#define USB_PID_DIBCOM_MOD3001_COLD 0x0bc6
#define USB_PID_DIBCOM_MOD3001_WARM 0x0bc7
#define USB_PID_DIBCOM_STK7700 0x1e14
-#define USB_PID_DIBCOM_STK7700_REENUM 0x1e15
-#define USB_PID_DIBCOM_ANCHOR_2135_COLD 0x2131
-#define USB_PID_GRANDTEC_DVBT_USB_COLD 0x0fa0
-#define USB_PID_GRANDTEC_DVBT_USB_WARM 0x0fa1
+#define USB_PID_DIBCOM_STK7700_REENUM 0x1e15
+#define USB_PID_DIBCOM_ANCHOR_2135_COLD 0x2131
+#define USB_PID_GRANDTEC_DVBT_USB_COLD 0x0fa0
+#define USB_PID_GRANDTEC_DVBT_USB_WARM 0x0fa1
#define USB_PID_KWORLD_VSTREAM_COLD 0x17de
#define USB_PID_KWORLD_VSTREAM_WARM 0x17df
#define USB_PID_TWINHAN_VP7041_COLD 0x3201
@@ -69,25 +71,30 @@
#define USB_PID_DNTV_TINYUSB2_WARM 0x3224
#define USB_PID_ULTIMA_TVBOX_COLD 0x8105
#define USB_PID_ULTIMA_TVBOX_WARM 0x8106
-#define USB_PID_ULTIMA_TVBOX_AN2235_COLD 0x8107
-#define USB_PID_ULTIMA_TVBOX_AN2235_WARM 0x8108
-#define USB_PID_ULTIMA_TVBOX_ANCHOR_COLD 0x2235
-#define USB_PID_ULTIMA_TVBOX_USB2_COLD 0x8109
-#define USB_PID_ULTIMA_TVBOX_USB2_WARM 0x810a
-#define USB_PID_ULTIMA_TVBOX_USB2_FX_COLD 0x8613
-#define USB_PID_ULTIMA_TVBOX_USB2_FX_WARM 0x1002
-#define USB_PID_UNK_HYPER_PALTEK_COLD 0x005e
-#define USB_PID_UNK_HYPER_PALTEK_WARM 0x005f
-#define USB_PID_HANFTEK_UMT_010_COLD 0x0001
-#define USB_PID_HANFTEK_UMT_010_WARM 0x0015
+#define USB_PID_ULTIMA_TVBOX_AN2235_COLD 0x8107
+#define USB_PID_ULTIMA_TVBOX_AN2235_WARM 0x8108
+#define USB_PID_ULTIMA_TVBOX_ANCHOR_COLD 0x2235
+#define USB_PID_ULTIMA_TVBOX_USB2_COLD 0x8109
+#define USB_PID_ULTIMA_TVBOX_USB2_WARM 0x810a
+#define USB_PID_ARTEC_T14_COLD 0x810b
+#define USB_PID_ARTEC_T14_WARM 0x810c
+#define USB_PID_ULTIMA_TVBOX_USB2_FX_COLD 0x8613
+#define USB_PID_ULTIMA_TVBOX_USB2_FX_WARM 0x1002
+#define USB_PID_UNK_HYPER_PALTEK_COLD 0x005e
+#define USB_PID_UNK_HYPER_PALTEK_WARM 0x005f
+#define USB_PID_HANFTEK_UMT_010_COLD 0x0001
+#define USB_PID_HANFTEK_UMT_010_WARM 0x0015
#define USB_PID_DTT200U_COLD 0x0201
#define USB_PID_DTT200U_WARM 0x0301
-#define USB_PID_WT220U_COLD 0x0222
-#define USB_PID_WT220U_WARM 0x0221
+#define USB_PID_WT220U_ZAP250_COLD 0x0220
+#define USB_PID_WT220U_COLD 0x0222
+#define USB_PID_WT220U_WARM 0x0221
+#define USB_PID_WT220U_FC_COLD 0x0225
+#define USB_PID_WT220U_FC_WARM 0x0226
#define USB_PID_WT220U_ZL0353_COLD 0x022a
#define USB_PID_WT220U_ZL0353_WARM 0x022b
-#define USB_PID_WINTV_NOVA_T_USB2_COLD 0x9300
-#define USB_PID_WINTV_NOVA_T_USB2_WARM 0x9301
+#define USB_PID_WINTV_NOVA_T_USB2_COLD 0x9300
+#define USB_PID_WINTV_NOVA_T_USB2_WARM 0x9301
#define USB_PID_NEBULA_DIGITV 0x0201
#define USB_PID_DVICO_BLUEBIRD_LGDT 0xd820
#define USB_PID_DVICO_BLUEBIRD_LG064F_COLD 0xd500
@@ -103,8 +110,17 @@
#define USB_PID_MEDION_MD95700 0x0932
#define USB_PID_KYE_DVB_T_COLD 0x701e
#define USB_PID_KYE_DVB_T_WARM 0x701f
-#define USB_PID_PCTV_200E 0x020e
-#define USB_PID_PCTV_400E 0x020f
-#define USB_PID_GENPIX_8PSK_COLD 0x0200
-#define USB_PID_GENPIX_8PSK_WARM 0x0201
+#define USB_PID_PCTV_200E 0x020e
+#define USB_PID_PCTV_400E 0x020f
+#define USB_PID_LITEON_DVB_T_COLD 0xf000
+#define USB_PID_LITEON_DVB_T_WARM 0xf001
+#define USB_PID_DIGIVOX_MINI_SL_COLD 0xe360
+#define USB_PID_DIGIVOX_MINI_SL_WARM 0xe361
+#define USB_PID_GRANDTEC_DVBT_USB2_COLD 0x0bc6
+#define USB_PID_GRANDTEC_DVBT_USB2_WARM 0x0bc7
+#define USB_PID_WINFAST_DTV_DONGLE_COLD 0x6025
+#define USB_PID_WINFAST_DTV_DONGLE_WARM 0x6026
+#define USB_PID_GENPIX_8PSK_COLD 0x0200
+#define USB_PID_GENPIX_8PSK_WARM 0x0201
+
#endif
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-remote.c b/drivers/media/dvb/dvb-usb/dvb-usb-remote.c
index e5c6d9835e06..380b2a45ee4c 100644
--- a/drivers/media/dvb/dvb-usb/dvb-usb-remote.c
+++ b/drivers/media/dvb/dvb-usb/dvb-usb-remote.c
@@ -6,6 +6,7 @@
* This file contains functions for initializing the the input-device and for handling remote-control-queries.
*/
#include "dvb-usb-common.h"
+#include <linux/usb/input.h>
/* Remote-control poll function - called every dib->rc_query_interval ms to see
* whether the remote control has received anything.
@@ -96,7 +97,7 @@ int dvb_usb_remote_init(struct dvb_usb_device *d)
return 0;
usb_make_path(d->udev, d->rc_phys, sizeof(d->rc_phys));
- strlcpy(d->rc_phys, "/ir0", sizeof(d->rc_phys));
+ strlcat(d->rc_phys, "/ir0", sizeof(d->rc_phys));
d->rc_input_dev = input_allocate_device();
if (!d->rc_input_dev)
@@ -107,6 +108,8 @@ int dvb_usb_remote_init(struct dvb_usb_device *d)
d->rc_input_dev->keycodemax = KEY_MAX;
d->rc_input_dev->name = "IR-receiver inside an USB DVB receiver";
d->rc_input_dev->phys = d->rc_phys;
+ usb_to_input_id(d->udev, &d->rc_input_dev->id);
+ d->rc_input_dev->cdev.dev = &d->udev->dev;
/* set the bits for the keys */
deb_rc("key map size: %d\n", d->props.rc_key_map_size);
diff --git a/drivers/media/dvb/dvb-usb/nova-t-usb2.c b/drivers/media/dvb/dvb-usb/nova-t-usb2.c
index 412039d8dbae..79f0a02ce987 100644
--- a/drivers/media/dvb/dvb-usb/nova-t-usb2.c
+++ b/drivers/media/dvb/dvb-usb/nova-t-usb2.c
@@ -156,7 +156,7 @@ static struct dvb_usb_properties nova_t_properties = {
.pid_filter_count = 32,
.usb_ctrl = CYPRESS_FX2,
- .firmware = "dvb-usb-nova-t-usb2-01.fw",
+ .firmware = "dvb-usb-nova-t-usb2-02.fw",
.size_of_priv = sizeof(struct dibusb_state),
diff --git a/drivers/media/dvb/dvb-usb/umt-010.c b/drivers/media/dvb/dvb-usb/umt-010.c
index 97d74da0dad8..418a0b707151 100644
--- a/drivers/media/dvb/dvb-usb/umt-010.c
+++ b/drivers/media/dvb/dvb-usb/umt-010.c
@@ -58,7 +58,7 @@ static int umt_mt352_frontend_attach(struct dvb_usb_device *d)
umt_config.demod_init = umt_mt352_demod_init;
umt_config.demod_address = 0xf;
- d->fe = mt352_attach(&umt_config, &d->i2c_adap);
+ d->fe = dvb_attach(mt352_attach, &umt_config, &d->i2c_adap);
return 0;
}
diff --git a/drivers/media/dvb/frontends/Kconfig b/drivers/media/dvb/frontends/Kconfig
index db978555b1eb..080fa257a0bc 100644
--- a/drivers/media/dvb/frontends/Kconfig
+++ b/drivers/media/dvb/frontends/Kconfig
@@ -1,48 +1,73 @@
menu "Customise DVB Frontends"
depends on DVB_CORE
+config DVB_FE_CUSTOMISE
+ bool "Customise the frontend modules to build"
+ default N
+ help
+ This allows the user to deselect frontend drivers unnecessary
+ for their hardware from the build. Use this option with care
+ as deselecting frontends which are in fact necessary will result
+ in DVB devices which cannot be tuned due to lack of driver support.
+
+ If unsure say N.
+
comment "DVB-S (satellite) frontends"
depends on DVB_CORE
config DVB_STV0299
tristate "ST STV0299 based"
depends on DVB_CORE && I2C
+ default m if DVB_FE_CUSTOMISE
help
A DVB-S tuner module. Say Y when you want to support this frontend.
config DVB_CX24110
tristate "Conexant CX24110 based"
depends on DVB_CORE && I2C
+ default m if DVB_FE_CUSTOMISE
help
A DVB-S tuner module. Say Y when you want to support this frontend.
config DVB_CX24123
tristate "Conexant CX24123 based"
depends on DVB_CORE && I2C
+ default m if DVB_FE_CUSTOMISE
help
A DVB-S tuner module. Say Y when you want to support this frontend.
config DVB_TDA8083
tristate "Philips TDA8083 based"
depends on DVB_CORE && I2C
+ default m if DVB_FE_CUSTOMISE
help
A DVB-S tuner module. Say Y when you want to support this frontend.
config DVB_MT312
tristate "Zarlink VP310/MT312 based"
depends on DVB_CORE && I2C
+ default m if DVB_FE_CUSTOMISE
help
A DVB-S tuner module. Say Y when you want to support this frontend.
config DVB_VES1X93
tristate "VLSI VES1893 or VES1993 based"
depends on DVB_CORE && I2C
+ default m if DVB_FE_CUSTOMISE
help
A DVB-S tuner module. Say Y when you want to support this frontend.
config DVB_S5H1420
tristate "Samsung S5H1420 based"
depends on DVB_CORE && I2C
+ default m if DVB_FE_CUSTOMISE
+ help
+ A DVB-S tuner module. Say Y when you want to support this frontend.
+
+config DVB_TDA10086
+ tristate "Philips TDA10086 based"
+ depends on DVB_CORE && I2C
+ default m if DVB_FE_CUSTOMISE
help
A DVB-S tuner module. Say Y when you want to support this frontend.
@@ -52,6 +77,7 @@ comment "DVB-T (terrestrial) frontends"
config DVB_SP8870
tristate "Spase sp8870 based"
depends on DVB_CORE && I2C
+ default m if DVB_FE_CUSTOMISE
select FW_LOADER
help
A DVB-T tuner module. Say Y when you want to support this frontend.
@@ -64,6 +90,7 @@ config DVB_SP8870
config DVB_SP887X
tristate "Spase sp887x based"
depends on DVB_CORE && I2C
+ default m if DVB_FE_CUSTOMISE
select FW_LOADER
help
A DVB-T tuner module. Say Y when you want to support this frontend.
@@ -76,24 +103,28 @@ config DVB_SP887X
config DVB_CX22700
tristate "Conexant CX22700 based"
depends on DVB_CORE && I2C
+ default m if DVB_FE_CUSTOMISE
help
A DVB-T tuner module. Say Y when you want to support this frontend.
config DVB_CX22702
tristate "Conexant cx22702 demodulator (OFDM)"
depends on DVB_CORE && I2C
+ default m if DVB_FE_CUSTOMISE
help
A DVB-T tuner module. Say Y when you want to support this frontend.
config DVB_L64781
tristate "LSI L64781"
depends on DVB_CORE && I2C
+ default m if DVB_FE_CUSTOMISE
help
A DVB-T tuner module. Say Y when you want to support this frontend.
config DVB_TDA1004X
tristate "Philips TDA10045H/TDA10046H based"
depends on DVB_CORE && I2C
+ default m if DVB_FE_CUSTOMISE
select FW_LOADER
help
A DVB-T tuner module. Say Y when you want to support this frontend.
@@ -107,24 +138,28 @@ config DVB_TDA1004X
config DVB_NXT6000
tristate "NxtWave Communications NXT6000 based"
depends on DVB_CORE && I2C
+ default m if DVB_FE_CUSTOMISE
help
A DVB-T tuner module. Say Y when you want to support this frontend.
config DVB_MT352
tristate "Zarlink MT352 based"
depends on DVB_CORE && I2C
+ default m if DVB_FE_CUSTOMISE
help
A DVB-T tuner module. Say Y when you want to support this frontend.
config DVB_ZL10353
tristate "Zarlink ZL10353 based"
depends on DVB_CORE && I2C
+ default m if DVB_FE_CUSTOMISE
help
A DVB-T tuner module. Say Y when you want to support this frontend.
config DVB_DIB3000MB
tristate "DiBcom 3000M-B"
depends on DVB_CORE && I2C
+ default m if DVB_FE_CUSTOMISE
help
A DVB-T tuner module. Designed for mobile usage. Say Y when you want
to support this frontend.
@@ -132,6 +167,7 @@ config DVB_DIB3000MB
config DVB_DIB3000MC
tristate "DiBcom 3000P/M-C"
depends on DVB_CORE && I2C
+ default m if DVB_FE_CUSTOMISE
help
A DVB-T tuner module. Designed for mobile usage. Say Y when you want
to support this frontend.
@@ -142,18 +178,21 @@ comment "DVB-C (cable) frontends"
config DVB_VES1820
tristate "VLSI VES1820 based"
depends on DVB_CORE && I2C
+ default m if DVB_FE_CUSTOMISE
help
A DVB-C tuner module. Say Y when you want to support this frontend.
config DVB_TDA10021
tristate "Philips TDA10021 based"
depends on DVB_CORE && I2C
+ default m if DVB_FE_CUSTOMISE
help
A DVB-C tuner module. Say Y when you want to support this frontend.
config DVB_STV0297
tristate "ST STV0297 based"
depends on DVB_CORE && I2C
+ default m if DVB_FE_CUSTOMISE
help
A DVB-C tuner module. Say Y when you want to support this frontend.
@@ -163,6 +202,7 @@ comment "ATSC (North American/Korean Terrestrial/Cable DTV) frontends"
config DVB_NXT200X
tristate "NxtWave Communications NXT2002/NXT2004 based"
depends on DVB_CORE && I2C
+ default m if DVB_FE_CUSTOMISE
select FW_LOADER
help
An ATSC 8VSB and QAM64/256 tuner module. Say Y when you want
@@ -177,6 +217,7 @@ config DVB_NXT200X
config DVB_OR51211
tristate "Oren OR51211 based"
depends on DVB_CORE && I2C
+ default m if DVB_FE_CUSTOMISE
select FW_LOADER
help
An ATSC 8VSB tuner module. Say Y when you want to support this frontend.
@@ -189,6 +230,7 @@ config DVB_OR51211
config DVB_OR51132
tristate "Oren OR51132 based"
depends on DVB_CORE && I2C
+ default m if DVB_FE_CUSTOMISE
select FW_LOADER
help
An ATSC 8VSB and QAM64/256 tuner module. Say Y when you want
@@ -204,6 +246,7 @@ config DVB_OR51132
config DVB_BCM3510
tristate "Broadcom BCM3510"
depends on DVB_CORE && I2C
+ default m if DVB_FE_CUSTOMISE
select FW_LOADER
help
An ATSC 8VSB/16VSB and QAM64/256 tuner module. Say Y when you want to
@@ -212,28 +255,52 @@ config DVB_BCM3510
config DVB_LGDT330X
tristate "LG Electronics LGDT3302/LGDT3303 based"
depends on DVB_CORE && I2C
+ default m if DVB_FE_CUSTOMISE
help
An ATSC 8VSB and QAM64/256 tuner module. Say Y when you want
to support this frontend.
-
-comment "Miscellaneous devices"
+comment "Tuners/PLL support"
depends on DVB_CORE
config DVB_PLL
tristate
depends on DVB_CORE && I2C
+config DVB_TDA826X
+ tristate "Philips TDA826X silicon tuner"
+ depends on DVB_CORE && I2C
+ default m if DVB_FE_CUSTOMISE
+ help
+ A DVB-S silicon tuner module. Say Y when you want to support this tuner.
+
+config DVB_TUNER_MT2060
+ tristate "Microtune MT2060 silicon IF tuner"
+ help
+ A driver for the silicon IF tuner MT2060 from Microtune.
+
+comment "Miscellaneous devices"
+ depends on DVB_CORE
+
config DVB_LNBP21
tristate "LNBP21 SEC controller"
depends on DVB_CORE && I2C
+ default m if DVB_FE_CUSTOMISE
help
An SEC control chip.
config DVB_ISL6421
tristate "ISL6421 SEC controller"
depends on DVB_CORE && I2C
+ default m if DVB_FE_CUSTOMISE
help
An SEC control chip.
+config DVB_TUA6100
+ tristate "TUA6100 PLL"
+ depends on DVB_CORE && I2C
+ default m if DVB_FE_CUSTOMISE
+ help
+ A DVBS PLL chip.
+
endmenu
diff --git a/drivers/media/dvb/frontends/Makefile b/drivers/media/dvb/frontends/Makefile
index 0e4880b6db14..dce9cf0c75c0 100644
--- a/drivers/media/dvb/frontends/Makefile
+++ b/drivers/media/dvb/frontends/Makefile
@@ -11,8 +11,8 @@ obj-$(CONFIG_DVB_CX22700) += cx22700.o
obj-$(CONFIG_DVB_CX24110) += cx24110.o
obj-$(CONFIG_DVB_TDA8083) += tda8083.o
obj-$(CONFIG_DVB_L64781) += l64781.o
-obj-$(CONFIG_DVB_DIB3000MB) += dib3000mb.o dib3000-common.o
-obj-$(CONFIG_DVB_DIB3000MC) += dib3000mc.o dib3000-common.o
+obj-$(CONFIG_DVB_DIB3000MB) += dib3000mb.o
+obj-$(CONFIG_DVB_DIB3000MC) += dib3000mc.o dibx000_common.o
obj-$(CONFIG_DVB_MT312) += mt312.o
obj-$(CONFIG_DVB_VES1820) += ves1820.o
obj-$(CONFIG_DVB_VES1X93) += ves1x93.o
@@ -33,3 +33,7 @@ obj-$(CONFIG_DVB_LGDT330X) += lgdt330x.o
obj-$(CONFIG_DVB_CX24123) += cx24123.o
obj-$(CONFIG_DVB_LNBP21) += lnbp21.o
obj-$(CONFIG_DVB_ISL6421) += isl6421.o
+obj-$(CONFIG_DVB_TDA10086) += tda10086.o
+obj-$(CONFIG_DVB_TDA826X) += tda826x.o
+obj-$(CONFIG_DVB_TUNER_MT2060) += mt2060.o
+obj-$(CONFIG_DVB_TUA6100) += tua6100.o
diff --git a/drivers/media/dvb/frontends/bcm3510.h b/drivers/media/dvb/frontends/bcm3510.h
index 80f5d0953d02..6dfa839a7022 100644
--- a/drivers/media/dvb/frontends/bcm3510.h
+++ b/drivers/media/dvb/frontends/bcm3510.h
@@ -34,7 +34,16 @@ struct bcm3510_config
int (*request_firmware)(struct dvb_frontend* fe, const struct firmware **fw, char* name);
};
+#if defined(CONFIG_DVB_BCM3510) || defined(CONFIG_DVB_BCM3510_MODULE)
extern struct dvb_frontend* bcm3510_attach(const struct bcm3510_config* config,
struct i2c_adapter* i2c);
+#else
+static inline struct dvb_frontend* bcm3510_attach(const struct bcm3510_config* config,
+ struct i2c_adapter* i2c)
+{
+ printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__);
+ return NULL;
+}
+#endif // CONFIG_DVB_BCM3510
#endif
diff --git a/drivers/media/dvb/frontends/cx22700.h b/drivers/media/dvb/frontends/cx22700.h
index dcd8979c1a15..10286cc29fb4 100644
--- a/drivers/media/dvb/frontends/cx22700.h
+++ b/drivers/media/dvb/frontends/cx22700.h
@@ -31,7 +31,16 @@ struct cx22700_config
u8 demod_address;
};
+#if defined(CONFIG_DVB_CX22700) || defined(CONFIG_DVB_CX22700_MODULE)
extern struct dvb_frontend* cx22700_attach(const struct cx22700_config* config,
struct i2c_adapter* i2c);
+#else
+static inline struct dvb_frontend* cx22700_attach(const struct cx22700_config* config,
+ struct i2c_adapter* i2c)
+{
+ printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__);
+ return NULL;
+}
+#endif // CONFIG_DVB_CX22700
#endif // CX22700_H
diff --git a/drivers/media/dvb/frontends/cx22702.c b/drivers/media/dvb/frontends/cx22702.c
index 4106d46c957f..335219ebce2d 100644
--- a/drivers/media/dvb/frontends/cx22702.c
+++ b/drivers/media/dvb/frontends/cx22702.c
@@ -399,7 +399,9 @@ static int cx22702_read_signal_strength(struct dvb_frontend* fe, u16* signal_str
{
struct cx22702_state* state = fe->demodulator_priv;
- *signal_strength = cx22702_readreg (state, 0x23);
+ u16 rs_ber = 0;
+ rs_ber = cx22702_readreg (state, 0x23);
+ *signal_strength = (rs_ber << 8) | rs_ber;
return 0;
}
diff --git a/drivers/media/dvb/frontends/cx22702.h b/drivers/media/dvb/frontends/cx22702.h
index 7f2f241e5d44..bc217ddf02c0 100644
--- a/drivers/media/dvb/frontends/cx22702.h
+++ b/drivers/media/dvb/frontends/cx22702.h
@@ -41,7 +41,16 @@ struct cx22702_config
u8 output_mode;
};
+#if defined(CONFIG_DVB_CX22702) || defined(CONFIG_DVB_CX22702_MODULE)
extern struct dvb_frontend* cx22702_attach(const struct cx22702_config* config,
struct i2c_adapter* i2c);
+#else
+static inline struct dvb_frontend* cx22702_attach(const struct cx22702_config* config,
+ struct i2c_adapter* i2c)
+{
+ printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__);
+ return NULL;
+}
+#endif // CONFIG_DVB_CX22702
#endif // CX22702_H
diff --git a/drivers/media/dvb/frontends/cx24110.c b/drivers/media/dvb/frontends/cx24110.c
index ce3c7398bac9..ae96395217a2 100644
--- a/drivers/media/dvb/frontends/cx24110.c
+++ b/drivers/media/dvb/frontends/cx24110.c
@@ -1,4 +1,4 @@
-/*
+ /*
cx24110 - Single Chip Satellite Channel Receiver driver module
Copyright (C) 2002 Peter Hettkamp <peter.hettkamp@htp-tel.de> based on
@@ -311,16 +311,17 @@ static int cx24110_set_symbolrate (struct cx24110_state* state, u32 srate)
}
-int cx24110_pll_write (struct dvb_frontend* fe, u32 data)
+static int _cx24110_pll_write (struct dvb_frontend* fe, u8 *buf, int len)
{
struct cx24110_state *state = fe->demodulator_priv;
+ if (len != 3)
+ return -EINVAL;
+
/* tuner data is 21 bits long, must be left-aligned in data */
/* tuner cx24108 is written through a dedicated 3wire interface on the demod chip */
/* FIXME (low): add error handling, avoid infinite loops if HW fails... */
- dprintk("cx24110 debug: cx24108_write(%8.8x)\n",data);
-
cx24110_writereg(state,0x6d,0x30); /* auto mode at 62kHz */
cx24110_writereg(state,0x70,0x15); /* auto mode 21 bits */
@@ -329,19 +330,19 @@ int cx24110_pll_write (struct dvb_frontend* fe, u32 data)
cx24110_writereg(state,0x72,0);
/* write the topmost 8 bits */
- cx24110_writereg(state,0x72,(data>>24)&0xff);
+ cx24110_writereg(state,0x72,buf[0]);
/* wait for the send to be completed */
while ((cx24110_readreg(state,0x6d)&0xc0)==0x80)
;
/* send another 8 bytes */
- cx24110_writereg(state,0x72,(data>>16)&0xff);
+ cx24110_writereg(state,0x72,buf[1]);
while ((cx24110_readreg(state,0x6d)&0xc0)==0x80)
;
/* and the topmost 5 bits of this byte */
- cx24110_writereg(state,0x72,(data>>8)&0xff);
+ cx24110_writereg(state,0x72,buf[2]);
while ((cx24110_readreg(state,0x6d)&0xc0)==0x80)
;
@@ -642,6 +643,7 @@ static struct dvb_frontend_ops cx24110_ops = {
.release = cx24110_release,
.init = cx24110_initfe,
+ .write = _cx24110_pll_write,
.set_frontend = cx24110_set_frontend,
.get_frontend = cx24110_get_frontend,
.read_status = cx24110_read_status,
@@ -664,4 +666,3 @@ MODULE_AUTHOR("Peter Hettkamp");
MODULE_LICENSE("GPL");
EXPORT_SYMBOL(cx24110_attach);
-EXPORT_SYMBOL(cx24110_pll_write);
diff --git a/drivers/media/dvb/frontends/cx24110.h b/drivers/media/dvb/frontends/cx24110.h
index b354a64e0e74..c9d5ae250ebb 100644
--- a/drivers/media/dvb/frontends/cx24110.h
+++ b/drivers/media/dvb/frontends/cx24110.h
@@ -33,9 +33,24 @@ struct cx24110_config
u8 demod_address;
};
+static inline int cx24110_pll_write(struct dvb_frontend *fe, u32 val) {
+ int r = 0;
+ u8 buf[] = {(u8) (val>>24), (u8) (val>>16), (u8) (val>>8)};
+ if (fe->ops.write)
+ r = fe->ops.write(fe, buf, 3);
+ return r;
+}
+
+#if defined(CONFIG_DVB_CX24110) || defined(CONFIG_DVB_CX24110_MODULE)
extern struct dvb_frontend* cx24110_attach(const struct cx24110_config* config,
struct i2c_adapter* i2c);
-
-extern int cx24110_pll_write(struct dvb_frontend* fe, u32 data);
+#else
+static inline struct dvb_frontend* cx24110_attach(const struct cx24110_config* config,
+ struct i2c_adapter* i2c)
+{
+ printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__);
+ return NULL;
+}
+#endif // CONFIG_DVB_CX24110
#endif // CX24110_H
diff --git a/drivers/media/dvb/frontends/cx24123.c b/drivers/media/dvb/frontends/cx24123.c
index 274a87b7a5d5..62d69a6ea699 100644
--- a/drivers/media/dvb/frontends/cx24123.c
+++ b/drivers/media/dvb/frontends/cx24123.c
@@ -45,9 +45,6 @@ struct cx24123_state
struct dvb_frontend frontend;
- u32 lastber;
- u16 snr;
-
/* Some PLL specifics for tuning */
u32 VCAarg;
u32 VGAarg;
@@ -194,7 +191,7 @@ static struct {
{0x06, 0x31}, /* MPEG (default) */
{0x0b, 0x00}, /* Freq search start point (default) */
{0x0c, 0x00}, /* Demodulator sample gain (default) */
- {0x0d, 0x02}, /* Frequency search range = Fsymbol / 4 (default) */
+ {0x0d, 0x7f}, /* Force driver to shift until the maximum (+-10 MHz) */
{0x0e, 0x03}, /* Default non-inverted, FEC 3/4 (default) */
{0x0f, 0xfe}, /* FEC search mask (all supported codes) */
{0x10, 0x01}, /* Default search inversion, no repeat (default) */
@@ -223,8 +220,9 @@ static struct {
{0x44, 0x00}, /* Constellation (default) */
{0x45, 0x00}, /* Symbol count (default) */
{0x46, 0x0d}, /* Symbol rate estimator on (default) */
- {0x56, 0x41}, /* Various (default) */
+ {0x56, 0xc1}, /* Error Counter = Viterbi BER */
{0x57, 0xff}, /* Error Counter Window (default) */
+ {0x5c, 0x20}, /* Acquisition AFC Expiration window (default is 0x10) */
{0x67, 0x83}, /* Non-DCII symbol clock */
};
@@ -321,6 +319,12 @@ static int cx24123_set_fec(struct cx24123_state* state, fe_code_rate_t fec)
if ( (fec < FEC_NONE) || (fec > FEC_AUTO) )
fec = FEC_AUTO;
+ /* Set the soft decision threshold */
+ if(fec == FEC_1_2)
+ cx24123_writereg(state, 0x43, cx24123_readreg(state, 0x43) | 0x01);
+ else
+ cx24123_writereg(state, 0x43, cx24123_readreg(state, 0x43) & ~0x01);
+
switch (fec) {
case FEC_1_2:
dprintk("%s: set FEC to 1/2\n",__FUNCTION__);
@@ -657,6 +661,10 @@ static int cx24123_initfe(struct dvb_frontend* fe)
for (i = 0; i < sizeof(cx24123_regdata) / sizeof(cx24123_regdata[0]); i++)
cx24123_writereg(state, cx24123_regdata[i].reg, cx24123_regdata[i].data);
+ /* Set the LNB polarity */
+ if(state->config->lnb_polarity)
+ cx24123_writereg(state, 0x32, cx24123_readreg(state, 0x32) | 0x02);
+
return 0;
}
@@ -674,6 +682,9 @@ static int cx24123_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage
case SEC_VOLTAGE_18:
dprintk("%s: setting voltage 18V\n", __FUNCTION__);
return cx24123_writereg(state, 0x29, val | 0x80);
+ case SEC_VOLTAGE_OFF:
+ /* already handled in cx88-dvb */
+ return 0;
default:
return -EINVAL;
};
@@ -776,13 +787,15 @@ static int cx24123_read_status(struct dvb_frontend* fe, fe_status_t* status)
if (lock & 0x01)
*status |= FE_HAS_SIGNAL;
if (sync & 0x02)
- *status |= FE_HAS_CARRIER;
+ *status |= FE_HAS_CARRIER; /* Phase locked */
if (sync & 0x04)
*status |= FE_HAS_VITERBI;
+
+ /* Reed-Solomon Status */
if (sync & 0x08)
*status |= FE_HAS_SYNC;
if (sync & 0x80)
- *status |= FE_HAS_LOCK;
+ *status |= FE_HAS_LOCK; /*Full Sync */
return 0;
}
@@ -795,29 +808,13 @@ static int cx24123_read_ber(struct dvb_frontend* fe, u32* ber)
{
struct cx24123_state *state = fe->demodulator_priv;
- state->lastber =
- ((cx24123_readreg(state, 0x1c) & 0x3f) << 16) |
+ /* The true bit error rate is this value divided by
+ the window size (set as 256 * 255) */
+ *ber = ((cx24123_readreg(state, 0x1c) & 0x3f) << 16) |
(cx24123_readreg(state, 0x1d) << 8 |
- cx24123_readreg(state, 0x1e));
-
- /* Do the signal quality processing here, it's derived from the BER. */
- /* Scale the BER from a 24bit to a SNR 16 bit where higher = better */
- if (state->lastber < 5000)
- state->snr = 655*100;
- else if ( (state->lastber >= 5000) && (state->lastber < 55000) )
- state->snr = 655*90;
- else if ( (state->lastber >= 55000) && (state->lastber < 150000) )
- state->snr = 655*80;
- else if ( (state->lastber >= 150000) && (state->lastber < 250000) )
- state->snr = 655*70;
- else if ( (state->lastber >= 250000) && (state->lastber < 450000) )
- state->snr = 655*65;
- else
- state->snr = 0;
-
- dprintk("%s: BER = %d, S/N index = %d\n",__FUNCTION__,state->lastber, state->snr);
+ cx24123_readreg(state, 0x1e));
- *ber = state->lastber;
+ dprintk("%s: BER = %d\n",__FUNCTION__,*ber);
return 0;
}
@@ -825,6 +822,7 @@ static int cx24123_read_ber(struct dvb_frontend* fe, u32* ber)
static int cx24123_read_signal_strength(struct dvb_frontend* fe, u16* signal_strength)
{
struct cx24123_state *state = fe->demodulator_priv;
+
*signal_strength = cx24123_readreg(state, 0x3b) << 8; /* larger = better */
dprintk("%s: Signal strength = %d\n",__FUNCTION__,*signal_strength);
@@ -835,19 +833,13 @@ static int cx24123_read_signal_strength(struct dvb_frontend* fe, u16* signal_str
static int cx24123_read_snr(struct dvb_frontend* fe, u16* snr)
{
struct cx24123_state *state = fe->demodulator_priv;
- *snr = state->snr;
-
- dprintk("%s: read S/N index = %d\n",__FUNCTION__,*snr);
- return 0;
-}
+ /* Inverted raw Es/N0 count, totally bogus but better than the
+ BER threshold. */
+ *snr = 65535 - (((u16)cx24123_readreg(state, 0x18) << 8) |
+ (u16)cx24123_readreg(state, 0x19));
-static int cx24123_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
-{
- struct cx24123_state *state = fe->demodulator_priv;
- *ucblocks = state->lastber;
-
- dprintk("%s: ucblocks (ber) = %d\n",__FUNCTION__,*ucblocks);
+ dprintk("%s: read S/N index = %d\n",__FUNCTION__,*snr);
return 0;
}
@@ -922,6 +914,29 @@ static int cx24123_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone)
return 0;
}
+static int cx24123_tune(struct dvb_frontend* fe,
+ struct dvb_frontend_parameters* params,
+ unsigned int mode_flags,
+ int *delay,
+ fe_status_t *status)
+{
+ int retval = 0;
+
+ if (params != NULL)
+ retval = cx24123_set_frontend(fe, params);
+
+ if (!(mode_flags & FE_TUNE_MODE_ONESHOT))
+ cx24123_read_status(fe, status);
+ *delay = HZ/10;
+
+ return retval;
+}
+
+static int cx24123_get_algo(struct dvb_frontend *fe)
+{
+ return 1; //FE_ALGO_HW
+}
+
static void cx24123_release(struct dvb_frontend* fe)
{
struct cx24123_state* state = fe->demodulator_priv;
@@ -949,8 +964,6 @@ struct dvb_frontend* cx24123_attach(const struct cx24123_config* config,
/* setup the state */
state->config = config;
state->i2c = i2c;
- state->lastber = 0;
- state->snr = 0;
state->VCAarg = 0;
state->VGAarg = 0;
state->bandselectarg = 0;
@@ -1003,11 +1016,12 @@ static struct dvb_frontend_ops cx24123_ops = {
.read_ber = cx24123_read_ber,
.read_signal_strength = cx24123_read_signal_strength,
.read_snr = cx24123_read_snr,
- .read_ucblocks = cx24123_read_ucblocks,
.diseqc_send_master_cmd = cx24123_send_diseqc_msg,
.diseqc_send_burst = cx24123_diseqc_send_burst,
.set_tone = cx24123_set_tone,
.set_voltage = cx24123_set_voltage,
+ .tune = cx24123_tune,
+ .get_frontend_algo = cx24123_get_algo,
};
module_param(debug, int, 0644);
diff --git a/drivers/media/dvb/frontends/cx24123.h b/drivers/media/dvb/frontends/cx24123.h
index 9606f825935c..57a1dae1dc40 100644
--- a/drivers/media/dvb/frontends/cx24123.h
+++ b/drivers/media/dvb/frontends/cx24123.h
@@ -30,9 +30,21 @@ struct cx24123_config
/* Need to set device param for start_dma */
int (*set_ts_params)(struct dvb_frontend* fe, int is_punctured);
+
+ /* 0 = LNB voltage normal, 1 = LNB voltage inverted */
+ int lnb_polarity;
};
+#if defined(CONFIG_DVB_CX24123) || defined(CONFIG_DVB_CX24123_MODULE)
extern struct dvb_frontend* cx24123_attach(const struct cx24123_config* config,
struct i2c_adapter* i2c);
+#else
+static inline struct dvb_frontend* cx24123_attach(const struct cx24123_config* config,
+ struct i2c_adapter* i2c)
+{
+ printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__);
+ return NULL;
+}
+#endif // CONFIG_DVB_CX24123
#endif /* CX24123_H */
diff --git a/drivers/media/dvb/frontends/dib3000-common.c b/drivers/media/dvb/frontends/dib3000-common.c
deleted file mode 100644
index 1a4f1f7c228a..000000000000
--- a/drivers/media/dvb/frontends/dib3000-common.c
+++ /dev/null
@@ -1,83 +0,0 @@
-#include "dib3000-common.h"
-
-#ifdef CONFIG_DVB_DIBCOM_DEBUG
-static int debug;
-module_param(debug, int, 0644);
-MODULE_PARM_DESC(debug, "set debugging level (1=info,2=i2c,4=srch (|-able)).");
-#endif
-#define deb_info(args...) dprintk(0x01,args)
-#define deb_i2c(args...) dprintk(0x02,args)
-#define deb_srch(args...) dprintk(0x04,args)
-
-
-int dib3000_read_reg(struct dib3000_state *state, u16 reg)
-{
- u8 wb[] = { ((reg >> 8) | 0x80) & 0xff, reg & 0xff };
- u8 rb[2];
- struct i2c_msg msg[] = {
- { .addr = state->config.demod_address, .flags = 0, .buf = wb, .len = 2 },
- { .addr = state->config.demod_address, .flags = I2C_M_RD, .buf = rb, .len = 2 },
- };
-
- if (i2c_transfer(state->i2c, msg, 2) != 2)
- deb_i2c("i2c read error\n");
-
- deb_i2c("reading i2c bus (reg: %5d 0x%04x, val: %5d 0x%04x)\n",reg,reg,
- (rb[0] << 8) | rb[1],(rb[0] << 8) | rb[1]);
-
- return (rb[0] << 8) | rb[1];
-}
-
-int dib3000_write_reg(struct dib3000_state *state, u16 reg, u16 val)
-{
- u8 b[] = {
- (reg >> 8) & 0xff, reg & 0xff,
- (val >> 8) & 0xff, val & 0xff,
- };
- struct i2c_msg msg[] = {
- { .addr = state->config.demod_address, .flags = 0, .buf = b, .len = 4 }
- };
- deb_i2c("writing i2c bus (reg: %5d 0x%04x, val: %5d 0x%04x)\n",reg,reg,val,val);
-
- return i2c_transfer(state->i2c,msg, 1) != 1 ? -EREMOTEIO : 0;
-}
-
-int dib3000_search_status(u16 irq,u16 lock)
-{
- if (irq & 0x02) {
- if (lock & 0x01) {
- deb_srch("auto search succeeded\n");
- return 1; // auto search succeeded
- } else {
- deb_srch("auto search not successful\n");
- return 0; // auto search failed
- }
- } else if (irq & 0x01) {
- deb_srch("auto search failed\n");
- return 0; // auto search failed
- }
- return -1; // try again
-}
-
-/* for auto search */
-u16 dib3000_seq[2][2][2] = /* fft,gua, inv */
- { /* fft */
- { /* gua */
- { 0, 1 }, /* 0 0 { 0,1 } */
- { 3, 9 }, /* 0 1 { 0,1 } */
- },
- {
- { 2, 5 }, /* 1 0 { 0,1 } */
- { 6, 11 }, /* 1 1 { 0,1 } */
- }
- };
-
-MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@desy.de");
-MODULE_DESCRIPTION("Common functions for the dib3000mb/dib3000mc dvb frontend drivers");
-MODULE_LICENSE("GPL");
-
-EXPORT_SYMBOL(dib3000_seq);
-
-EXPORT_SYMBOL(dib3000_read_reg);
-EXPORT_SYMBOL(dib3000_write_reg);
-EXPORT_SYMBOL(dib3000_search_status);
diff --git a/drivers/media/dvb/frontends/dib3000-common.h b/drivers/media/dvb/frontends/dib3000-common.h
deleted file mode 100644
index be1c0d3e1389..000000000000
--- a/drivers/media/dvb/frontends/dib3000-common.h
+++ /dev/null
@@ -1,135 +0,0 @@
-/*
- * .h-files for the common use of the frontend drivers made by DiBcom
- * DiBcom 3000M-B/C, 3000P
- *
- * DiBcom (http://www.dibcom.fr/)
- *
- * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
- *
- * based on GPL code from DibCom, which has
- *
- * Copyright (C) 2004 Amaury Demol for DiBcom (ademol@dibcom.fr)
- *
- * 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.
- *
- * Acknowledgements
- *
- * Amaury Demol (ademol@dibcom.fr) from DiBcom for providing specs and driver
- * sources, on which this driver (and the dvb-dibusb) are based.
- *
- * see Documentation/dvb/README.dibusb for more information
- *
- */
-
-#ifndef DIB3000_COMMON_H
-#define DIB3000_COMMON_H
-
-#include "dvb_frontend.h"
-#include "dib3000.h"
-
-/* info and err, taken from usb.h, if there is anything available like by default. */
-#define err(format, arg...) printk(KERN_ERR "dib3000: " format "\n" , ## arg)
-#define info(format, arg...) printk(KERN_INFO "dib3000: " format "\n" , ## arg)
-#define warn(format, arg...) printk(KERN_WARNING "dib3000: " format "\n" , ## arg)
-
-/* frontend state */
-struct dib3000_state {
- struct i2c_adapter* i2c;
-
-/* configuration settings */
- struct dib3000_config config;
-
- struct dvb_frontend frontend;
- int timing_offset;
- int timing_offset_comp_done;
-
- fe_bandwidth_t last_tuned_bw;
- u32 last_tuned_freq;
-};
-
-/* commonly used methods by the dib3000mb/mc/p frontend */
-extern int dib3000_read_reg(struct dib3000_state *state, u16 reg);
-extern int dib3000_write_reg(struct dib3000_state *state, u16 reg, u16 val);
-
-extern int dib3000_search_status(u16 irq,u16 lock);
-
-/* handy shortcuts */
-#define rd(reg) dib3000_read_reg(state,reg)
-
-#define wr(reg,val) if (dib3000_write_reg(state,reg,val)) \
- { err("while sending 0x%04x to 0x%04x.",val,reg); return -EREMOTEIO; }
-
-#define wr_foreach(a,v) { int i; \
- if (sizeof(a) != sizeof(v)) \
- err("sizeof: %zu %zu is different",sizeof(a),sizeof(v));\
- for (i=0; i < sizeof(a)/sizeof(u16); i++) \
- wr(a[i],v[i]); \
- }
-
-#define set_or(reg,val) wr(reg,rd(reg) | val)
-
-#define set_and(reg,val) wr(reg,rd(reg) & val)
-
-
-/* debug */
-
-#ifdef CONFIG_DVB_DIBCOM_DEBUG
-#define dprintk(level,args...) \
- do { if ((debug & level)) { printk(args); } } while (0)
-#else
-#define dprintk(args...) do { } while (0)
-#endif
-
-/* mask for enabling a specific pid for the pid_filter */
-#define DIB3000_ACTIVATE_PID_FILTERING (0x2000)
-
-/* common values for tuning */
-#define DIB3000_ALPHA_0 ( 0)
-#define DIB3000_ALPHA_1 ( 1)
-#define DIB3000_ALPHA_2 ( 2)
-#define DIB3000_ALPHA_4 ( 4)
-
-#define DIB3000_CONSTELLATION_QPSK ( 0)
-#define DIB3000_CONSTELLATION_16QAM ( 1)
-#define DIB3000_CONSTELLATION_64QAM ( 2)
-
-#define DIB3000_GUARD_TIME_1_32 ( 0)
-#define DIB3000_GUARD_TIME_1_16 ( 1)
-#define DIB3000_GUARD_TIME_1_8 ( 2)
-#define DIB3000_GUARD_TIME_1_4 ( 3)
-
-#define DIB3000_TRANSMISSION_MODE_2K ( 0)
-#define DIB3000_TRANSMISSION_MODE_8K ( 1)
-
-#define DIB3000_SELECT_LP ( 0)
-#define DIB3000_SELECT_HP ( 1)
-
-#define DIB3000_FEC_1_2 ( 1)
-#define DIB3000_FEC_2_3 ( 2)
-#define DIB3000_FEC_3_4 ( 3)
-#define DIB3000_FEC_5_6 ( 5)
-#define DIB3000_FEC_7_8 ( 7)
-
-#define DIB3000_HRCH_OFF ( 0)
-#define DIB3000_HRCH_ON ( 1)
-
-#define DIB3000_DDS_INVERSION_OFF ( 0)
-#define DIB3000_DDS_INVERSION_ON ( 1)
-
-#define DIB3000_TUNER_WRITE_ENABLE(a) (0xffff & (a << 8))
-#define DIB3000_TUNER_WRITE_DISABLE(a) (0xffff & ((a << 8) | (1 << 7)))
-
-/* for auto search */
-extern u16 dib3000_seq[2][2][2];
-
-#define DIB3000_REG_MANUFACTOR_ID ( 1025)
-#define DIB3000_I2C_ID_DIBCOM (0x01b3)
-
-#define DIB3000_REG_DEVICE_ID ( 1026)
-#define DIB3000MB_DEVICE_ID (0x3000)
-#define DIB3000MC_DEVICE_ID (0x3001)
-#define DIB3000P_DEVICE_ID (0x3002)
-
-#endif // DIB3000_COMMON_H
diff --git a/drivers/media/dvb/frontends/dib3000.h b/drivers/media/dvb/frontends/dib3000.h
index ec927628d273..0caac3f0f279 100644
--- a/drivers/media/dvb/frontends/dib3000.h
+++ b/drivers/media/dvb/frontends/dib3000.h
@@ -41,9 +41,16 @@ struct dib_fe_xfer_ops
int (*tuner_pass_ctrl)(struct dvb_frontend *fe, int onoff, u8 pll_ctrl);
};
+#if defined(CONFIG_DVB_DIB3000MB) || defined(CONFIG_DVB_DIB3000MB_MODULE)
extern struct dvb_frontend* dib3000mb_attach(const struct dib3000_config* config,
struct i2c_adapter* i2c, struct dib_fe_xfer_ops *xfer_ops);
+#else
+static inline struct dvb_frontend* dib3000mb_attach(const struct dib3000_config* config,
+ struct i2c_adapter* i2c, struct dib_fe_xfer_ops *xfer_ops)
+{
+ printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__);
+ return NULL;
+}
+#endif // CONFIG_DVB_DIB3000MB
-extern struct dvb_frontend* dib3000mc_attach(const struct dib3000_config* config,
- struct i2c_adapter* i2c, struct dib_fe_xfer_ops *xfer_ops);
#endif // DIB3000_H
diff --git a/drivers/media/dvb/frontends/dib3000mb.c b/drivers/media/dvb/frontends/dib3000mb.c
index 5302e11883a2..adbabfdb04a9 100644
--- a/drivers/media/dvb/frontends/dib3000mb.c
+++ b/drivers/media/dvb/frontends/dib3000mb.c
@@ -29,9 +29,10 @@
#include <linux/string.h>
#include <linux/slab.h>
-#include "dib3000-common.h"
-#include "dib3000mb_priv.h"
+#include "dvb_frontend.h"
+
#include "dib3000.h"
+#include "dib3000mb_priv.h"
/* Version information */
#define DRIVER_VERSION "0.1"
@@ -44,10 +45,81 @@ module_param(debug, int, 0644);
MODULE_PARM_DESC(debug, "set debugging level (1=info,2=xfer,4=setfe,8=getfe (|-able)).");
#endif
#define deb_info(args...) dprintk(0x01,args)
+#define deb_i2c(args...) dprintk(0x02,args)
+#define deb_srch(args...) dprintk(0x04,args)
+#define deb_info(args...) dprintk(0x01,args)
#define deb_xfer(args...) dprintk(0x02,args)
#define deb_setf(args...) dprintk(0x04,args)
#define deb_getf(args...) dprintk(0x08,args)
+#ifdef CONFIG_DVB_DIBCOM_DEBUG
+static int debug;
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "set debugging level (1=info,2=i2c,4=srch (|-able)).");
+#endif
+
+static int dib3000_read_reg(struct dib3000_state *state, u16 reg)
+{
+ u8 wb[] = { ((reg >> 8) | 0x80) & 0xff, reg & 0xff };
+ u8 rb[2];
+ struct i2c_msg msg[] = {
+ { .addr = state->config.demod_address, .flags = 0, .buf = wb, .len = 2 },
+ { .addr = state->config.demod_address, .flags = I2C_M_RD, .buf = rb, .len = 2 },
+ };
+
+ if (i2c_transfer(state->i2c, msg, 2) != 2)
+ deb_i2c("i2c read error\n");
+
+ deb_i2c("reading i2c bus (reg: %5d 0x%04x, val: %5d 0x%04x)\n",reg,reg,
+ (rb[0] << 8) | rb[1],(rb[0] << 8) | rb[1]);
+
+ return (rb[0] << 8) | rb[1];
+}
+
+static int dib3000_write_reg(struct dib3000_state *state, u16 reg, u16 val)
+{
+ u8 b[] = {
+ (reg >> 8) & 0xff, reg & 0xff,
+ (val >> 8) & 0xff, val & 0xff,
+ };
+ struct i2c_msg msg[] = {
+ { .addr = state->config.demod_address, .flags = 0, .buf = b, .len = 4 }
+ };
+ deb_i2c("writing i2c bus (reg: %5d 0x%04x, val: %5d 0x%04x)\n",reg,reg,val,val);
+
+ return i2c_transfer(state->i2c,msg, 1) != 1 ? -EREMOTEIO : 0;
+}
+
+static int dib3000_search_status(u16 irq,u16 lock)
+{
+ if (irq & 0x02) {
+ if (lock & 0x01) {
+ deb_srch("auto search succeeded\n");
+ return 1; // auto search succeeded
+ } else {
+ deb_srch("auto search not successful\n");
+ return 0; // auto search failed
+ }
+ } else if (irq & 0x01) {
+ deb_srch("auto search failed\n");
+ return 0; // auto search failed
+ }
+ return -1; // try again
+}
+
+/* for auto search */
+static u16 dib3000_seq[2][2][2] = /* fft,gua, inv */
+ { /* fft */
+ { /* gua */
+ { 0, 1 }, /* 0 0 { 0,1 } */
+ { 3, 9 }, /* 0 1 { 0,1 } */
+ },
+ {
+ { 2, 5 }, /* 1 0 { 0,1 } */
+ { 6, 11 }, /* 1 1 { 0,1 } */
+ }
+ };
+
static int dib3000mb_get_frontend(struct dvb_frontend* fe,
struct dvb_frontend_parameters *fep);
diff --git a/drivers/media/dvb/frontends/dib3000mb_priv.h b/drivers/media/dvb/frontends/dib3000mb_priv.h
index 999b19047816..1a12747fdc91 100644
--- a/drivers/media/dvb/frontends/dib3000mb_priv.h
+++ b/drivers/media/dvb/frontends/dib3000mb_priv.h
@@ -13,6 +13,99 @@
#ifndef __DIB3000MB_PRIV_H_INCLUDED__
#define __DIB3000MB_PRIV_H_INCLUDED__
+/* info and err, taken from usb.h, if there is anything available like by default. */
+#define err(format, arg...) printk(KERN_ERR "dib3000: " format "\n" , ## arg)
+#define info(format, arg...) printk(KERN_INFO "dib3000: " format "\n" , ## arg)
+#define warn(format, arg...) printk(KERN_WARNING "dib3000: " format "\n" , ## arg)
+
+/* handy shortcuts */
+#define rd(reg) dib3000_read_reg(state,reg)
+
+#define wr(reg,val) if (dib3000_write_reg(state,reg,val)) \
+ { err("while sending 0x%04x to 0x%04x.",val,reg); return -EREMOTEIO; }
+
+#define wr_foreach(a,v) { int i; \
+ if (sizeof(a) != sizeof(v)) \
+ err("sizeof: %zu %zu is different",sizeof(a),sizeof(v));\
+ for (i=0; i < sizeof(a)/sizeof(u16); i++) \
+ wr(a[i],v[i]); \
+ }
+
+#define set_or(reg,val) wr(reg,rd(reg) | val)
+
+#define set_and(reg,val) wr(reg,rd(reg) & val)
+
+/* debug */
+
+#ifdef CONFIG_DVB_DIBCOM_DEBUG
+#define dprintk(level,args...) \
+ do { if ((debug & level)) { printk(args); } } while (0)
+#else
+#define dprintk(args...) do { } while (0)
+#endif
+
+/* mask for enabling a specific pid for the pid_filter */
+#define DIB3000_ACTIVATE_PID_FILTERING (0x2000)
+
+/* common values for tuning */
+#define DIB3000_ALPHA_0 ( 0)
+#define DIB3000_ALPHA_1 ( 1)
+#define DIB3000_ALPHA_2 ( 2)
+#define DIB3000_ALPHA_4 ( 4)
+
+#define DIB3000_CONSTELLATION_QPSK ( 0)
+#define DIB3000_CONSTELLATION_16QAM ( 1)
+#define DIB3000_CONSTELLATION_64QAM ( 2)
+
+#define DIB3000_GUARD_TIME_1_32 ( 0)
+#define DIB3000_GUARD_TIME_1_16 ( 1)
+#define DIB3000_GUARD_TIME_1_8 ( 2)
+#define DIB3000_GUARD_TIME_1_4 ( 3)
+
+#define DIB3000_TRANSMISSION_MODE_2K ( 0)
+#define DIB3000_TRANSMISSION_MODE_8K ( 1)
+
+#define DIB3000_SELECT_LP ( 0)
+#define DIB3000_SELECT_HP ( 1)
+
+#define DIB3000_FEC_1_2 ( 1)
+#define DIB3000_FEC_2_3 ( 2)
+#define DIB3000_FEC_3_4 ( 3)
+#define DIB3000_FEC_5_6 ( 5)
+#define DIB3000_FEC_7_8 ( 7)
+
+#define DIB3000_HRCH_OFF ( 0)
+#define DIB3000_HRCH_ON ( 1)
+
+#define DIB3000_DDS_INVERSION_OFF ( 0)
+#define DIB3000_DDS_INVERSION_ON ( 1)
+
+#define DIB3000_TUNER_WRITE_ENABLE(a) (0xffff & (a << 8))
+#define DIB3000_TUNER_WRITE_DISABLE(a) (0xffff & ((a << 8) | (1 << 7)))
+
+#define DIB3000_REG_MANUFACTOR_ID ( 1025)
+#define DIB3000_I2C_ID_DIBCOM (0x01b3)
+
+#define DIB3000_REG_DEVICE_ID ( 1026)
+#define DIB3000MB_DEVICE_ID (0x3000)
+#define DIB3000MC_DEVICE_ID (0x3001)
+#define DIB3000P_DEVICE_ID (0x3002)
+
+/* frontend state */
+struct dib3000_state {
+ struct i2c_adapter* i2c;
+
+/* configuration settings */
+ struct dib3000_config config;
+
+ struct dvb_frontend frontend;
+ int timing_offset;
+ int timing_offset_comp_done;
+
+ fe_bandwidth_t last_tuned_bw;
+ u32 last_tuned_freq;
+};
+
/* register addresses and some of their default values */
/* restart subsystems */
diff --git a/drivers/media/dvb/frontends/dib3000mc.c b/drivers/media/dvb/frontends/dib3000mc.c
index 98673474a140..cc28417fa33a 100644
--- a/drivers/media/dvb/frontends/dib3000mc.c
+++ b/drivers/media/dvb/frontends/dib3000mc.c
@@ -1,913 +1,921 @@
/*
- * Frontend driver for mobile DVB-T demodulator DiBcom 3000P/M-C
- * DiBcom (http://www.dibcom.fr/)
+ * Driver for DiBcom DiB3000MC/P-demodulator.
*
+ * Copyright (C) 2004-6 DiBcom (http://www.dibcom.fr/)
* Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
*
- * based on GPL code from DiBCom, which has
+ * This code is partially based on the previous dib3000mc.c .
*
- * Copyright (C) 2004 Amaury Demol for DiBcom (ademol@dibcom.fr)
- *
- * This program is free software; you can redistribute it and/or
+ * 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.
- *
- * Acknowledgements
- *
- * Amaury Demol (ademol@dibcom.fr) from DiBcom for providing specs and driver
- * sources, on which this driver (and the dvb-dibusb) are based.
- *
- * see Documentation/dvb/README.dibusb for more information
- *
*/
+
#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/string.h>
-#include <linux/slab.h>
-
-#include "dib3000-common.h"
-#include "dib3000mc_priv.h"
-#include "dib3000.h"
-
-/* Version information */
-#define DRIVER_VERSION "0.1"
-#define DRIVER_DESC "DiBcom 3000M-C DVB-T demodulator"
-#define DRIVER_AUTHOR "Patrick Boettcher, patrick.boettcher@desy.de"
-
-#ifdef CONFIG_DVB_DIBCOM_DEBUG
+#include <linux/i2c.h>
+//#include <linux/init.h>
+//#include <linux/delay.h>
+//#include <linux/string.h>
+//#include <linux/slab.h>
+
+#include "dvb_frontend.h"
+
+#include "dib3000mc.h"
+
static int debug;
module_param(debug, int, 0644);
-MODULE_PARM_DESC(debug, "set debugging level (1=info,2=xfer,4=setfe,8=getfe,16=stat (|-able)).");
-#endif
-#define deb_info(args...) dprintk(0x01,args)
-#define deb_xfer(args...) dprintk(0x02,args)
-#define deb_setf(args...) dprintk(0x04,args)
-#define deb_getf(args...) dprintk(0x08,args)
-#define deb_stat(args...) dprintk(0x10,args)
-
-static int dib3000mc_set_impulse_noise(struct dib3000_state * state, int mode,
- fe_transmit_mode_t transmission_mode, fe_bandwidth_t bandwidth)
-{
- switch (transmission_mode) {
- case TRANSMISSION_MODE_2K:
- wr_foreach(dib3000mc_reg_fft,dib3000mc_fft_modes[0]);
- break;
- case TRANSMISSION_MODE_8K:
- wr_foreach(dib3000mc_reg_fft,dib3000mc_fft_modes[1]);
- break;
- default:
- break;
- }
+MODULE_PARM_DESC(debug, "turn on debugging (default: 0)");
- switch (bandwidth) {
-/* case BANDWIDTH_5_MHZ:
- wr_foreach(dib3000mc_reg_impulse_noise,dib3000mc_impluse_noise[0]);
- break; */
- case BANDWIDTH_6_MHZ:
- wr_foreach(dib3000mc_reg_impulse_noise,dib3000mc_impluse_noise[1]);
- break;
- case BANDWIDTH_7_MHZ:
- wr_foreach(dib3000mc_reg_impulse_noise,dib3000mc_impluse_noise[2]);
- break;
- case BANDWIDTH_8_MHZ:
- wr_foreach(dib3000mc_reg_impulse_noise,dib3000mc_impluse_noise[3]);
- break;
- default:
- break;
+#define dprintk(args...) do { if (debug) { printk(KERN_DEBUG "DiB3000MC/P:"); printk(args); } } while (0)
+
+struct dib3000mc_state {
+ struct dvb_frontend demod;
+ struct dib3000mc_config *cfg;
+
+ u8 i2c_addr;
+ struct i2c_adapter *i2c_adap;
+
+ struct dibx000_i2c_master i2c_master;
+
+ fe_bandwidth_t current_bandwidth;
+
+ u16 dev_id;
+};
+
+static u16 dib3000mc_read_word(struct dib3000mc_state *state, u16 reg)
+{
+ u8 wb[2] = { (reg >> 8) | 0x80, reg & 0xff };
+ u8 rb[2];
+ struct i2c_msg msg[2] = {
+ { .addr = state->i2c_addr >> 1, .flags = 0, .buf = wb, .len = 2 },
+ { .addr = state->i2c_addr >> 1, .flags = I2C_M_RD, .buf = rb, .len = 2 },
+ };
+
+ if (i2c_transfer(state->i2c_adap, msg, 2) != 2)
+ dprintk("i2c read error on %d\n",reg);
+
+ return (rb[0] << 8) | rb[1];
+}
+
+static int dib3000mc_write_word(struct dib3000mc_state *state, u16 reg, u16 val)
+{
+ u8 b[4] = {
+ (reg >> 8) & 0xff, reg & 0xff,
+ (val >> 8) & 0xff, val & 0xff,
+ };
+ struct i2c_msg msg = {
+ .addr = state->i2c_addr >> 1, .flags = 0, .buf = b, .len = 4
+ };
+ return i2c_transfer(state->i2c_adap, &msg, 1) != 1 ? -EREMOTEIO : 0;
+}
+
+
+static int dib3000mc_identify(struct dib3000mc_state *state)
+{
+ u16 value;
+ if ((value = dib3000mc_read_word(state, 1025)) != 0x01b3) {
+ dprintk("-E- DiB3000MC/P: wrong Vendor ID (read=0x%x)\n",value);
+ return -EREMOTEIO;
}
- switch (mode) {
- case 0: /* no impulse */ /* fall through */
- wr_foreach(dib3000mc_reg_imp_noise_ctl,dib3000mc_imp_noise_ctl[0]);
- break;
- case 1: /* new algo */
- wr_foreach(dib3000mc_reg_imp_noise_ctl,dib3000mc_imp_noise_ctl[1]);
- set_or(DIB3000MC_REG_IMP_NOISE_55,DIB3000MC_IMP_NEW_ALGO(0)); /* gives 1<<10 */
- break;
- default: /* old algo */
- wr_foreach(dib3000mc_reg_imp_noise_ctl,dib3000mc_imp_noise_ctl[3]);
- break;
+ value = dib3000mc_read_word(state, 1026);
+ if (value != 0x3001 && value != 0x3002) {
+ dprintk("-E- DiB3000MC/P: wrong Device ID (%x)\n",value);
+ return -EREMOTEIO;
}
+ state->dev_id = value;
+
+ dprintk("-I- found DiB3000MC/P: %x\n",state->dev_id);
+
return 0;
}
-static int dib3000mc_set_timing(struct dib3000_state *state, int upd_offset,
- fe_transmit_mode_t fft, fe_bandwidth_t bw)
+static int dib3000mc_set_timing(struct dib3000mc_state *state, s16 nfft, u8 bw, u8 update_offset)
{
- u16 timf_msb,timf_lsb;
- s32 tim_offset,tim_sgn;
- u64 comp1,comp2,comp=0;
-
- switch (bw) {
- case BANDWIDTH_8_MHZ: comp = DIB3000MC_CLOCK_REF*8; break;
- case BANDWIDTH_7_MHZ: comp = DIB3000MC_CLOCK_REF*7; break;
- case BANDWIDTH_6_MHZ: comp = DIB3000MC_CLOCK_REF*6; break;
- default: err("unknown bandwidth (%d)",bw); break;
- }
- timf_msb = (comp >> 16) & 0xff;
- timf_lsb = (comp & 0xffff);
+/*
+ u32 timf_msb, timf_lsb, i;
+ int tim_sgn ;
+ LUInt comp1, comp2, comp ;
+// u32 tim_offset ;
+ comp = 27700 * BW_INDEX_TO_KHZ(bw) / 1000;
+ timf_msb = (comp >> 16) & 0x00FF;
+ timf_lsb = comp & 0xFFFF;
// Update the timing offset ;
- if (upd_offset > 0) {
- if (!state->timing_offset_comp_done) {
- msleep(200);
+ if (update_offset) {
+ if (state->timing_offset_comp_done == 0) {
+ usleep(200000);
state->timing_offset_comp_done = 1;
}
- tim_offset = rd(DIB3000MC_REG_TIMING_OFFS_MSB);
+ tim_offset = dib3000mc_read_word(state, 416);
if ((tim_offset & 0x2000) == 0x2000)
- tim_offset |= 0xC000;
- if (fft == TRANSMISSION_MODE_2K)
- tim_offset <<= 2;
+ tim_offset |= 0xC000; // PB: This only works if tim_offset is s16 - weird
+
+ if (nfft == 0)
+ tim_offset = tim_offset << 2; // PB: Do not store the offset for different things in one variable
state->timing_offset += tim_offset;
}
-
tim_offset = state->timing_offset;
+
if (tim_offset < 0) {
tim_sgn = 1;
tim_offset = -tim_offset;
} else
tim_sgn = 0;
- comp1 = (u32)tim_offset * (u32)timf_lsb ;
- comp2 = (u32)tim_offset * (u32)timf_msb ;
+ comp1 = tim_offset * timf_lsb;
+ comp2 = tim_offset * timf_msb;
comp = ((comp1 >> 16) + comp2) >> 7;
if (tim_sgn == 0)
- comp = (u32)(timf_msb << 16) + (u32) timf_lsb + comp;
+ comp = timf_msb * (1<<16) + timf_lsb + comp;
else
- comp = (u32)(timf_msb << 16) + (u32) timf_lsb - comp ;
+ comp = timf_msb * (1<<16) + timf_lsb - comp;
+
+ timf_msb = (comp>>16)&0xFF ;
+ timf_lsb = comp&0xFFFF;
+*/
+ u32 timf = 1384402 * (BW_INDEX_TO_KHZ(bw) / 1000);
- timf_msb = (comp >> 16) & 0xff;
- timf_lsb = comp & 0xffff;
+ dib3000mc_write_word(state, 23, timf >> 16);
+ dib3000mc_write_word(state, 24, timf & 0xffff);
- wr(DIB3000MC_REG_TIMING_FREQ_MSB,timf_msb);
- wr(DIB3000MC_REG_TIMING_FREQ_LSB,timf_lsb);
return 0;
}
-static int dib3000mc_init_auto_scan(struct dib3000_state *state, fe_bandwidth_t bw, int boost)
+static int dib3000mc_setup_pwm3_state(struct dib3000mc_state *state)
{
- if (boost) {
- wr(DIB3000MC_REG_SCAN_BOOST,DIB3000MC_SCAN_BOOST_ON);
+ if (state->cfg->pwm3_inversion) {
+ dib3000mc_write_word(state, 51, (2 << 14) | (0 << 10) | (7 << 6) | (2 << 2) | (2 << 0));
+ dib3000mc_write_word(state, 52, (0 << 8) | (5 << 5) | (1 << 4) | (1 << 3) | (1 << 2) | (2 << 0));
} else {
- wr(DIB3000MC_REG_SCAN_BOOST,DIB3000MC_SCAN_BOOST_OFF);
- }
- switch (bw) {
- case BANDWIDTH_8_MHZ:
- wr_foreach(dib3000mc_reg_bandwidth,dib3000mc_bandwidth_8mhz);
- break;
- case BANDWIDTH_7_MHZ:
- wr_foreach(dib3000mc_reg_bandwidth,dib3000mc_bandwidth_7mhz);
- break;
- case BANDWIDTH_6_MHZ:
- wr_foreach(dib3000mc_reg_bandwidth,dib3000mc_bandwidth_6mhz);
- break;
-/* case BANDWIDTH_5_MHZ:
- wr_foreach(dib3000mc_reg_bandwidth,dib3000mc_bandwidth_5mhz);
- break;*/
- case BANDWIDTH_AUTO:
- return -EOPNOTSUPP;
- default:
- err("unknown bandwidth value (%d).",bw);
- return -EINVAL;
- }
- if (boost) {
- u32 timeout = (rd(DIB3000MC_REG_BW_TIMOUT_MSB) << 16) +
- rd(DIB3000MC_REG_BW_TIMOUT_LSB);
- timeout *= 85; timeout >>= 7;
- wr(DIB3000MC_REG_BW_TIMOUT_MSB,(timeout >> 16) & 0xffff);
- wr(DIB3000MC_REG_BW_TIMOUT_LSB,timeout & 0xffff);
+ dib3000mc_write_word(state, 51, (2 << 14) | (4 << 10) | (7 << 6) | (2 << 2) | (2 << 0));
+ dib3000mc_write_word(state, 52, (1 << 8) | (5 << 5) | (1 << 4) | (1 << 3) | (0 << 2) | (2 << 0));
}
+
+ if (state->cfg->use_pwm3)
+ dib3000mc_write_word(state, 245, (1 << 3) | (1 << 0));
+ else
+ dib3000mc_write_word(state, 245, 0);
+
+ dib3000mc_write_word(state, 1040, 0x3);
return 0;
}
-static int dib3000mc_set_adp_cfg(struct dib3000_state *state, fe_modulation_t con)
+static int dib3000mc_set_output_mode(struct dib3000mc_state *state, int mode)
{
- switch (con) {
- case QAM_64:
- wr_foreach(dib3000mc_reg_adp_cfg,dib3000mc_adp_cfg[2]);
- break;
- case QAM_16:
- wr_foreach(dib3000mc_reg_adp_cfg,dib3000mc_adp_cfg[1]);
- break;
- case QPSK:
- wr_foreach(dib3000mc_reg_adp_cfg,dib3000mc_adp_cfg[0]);
- break;
- case QAM_AUTO:
+ int ret = 0;
+ u16 fifo_threshold = 1792;
+ u16 outreg = 0;
+ u16 outmode = 0;
+ u16 elecout = 1;
+ u16 smo_reg = dib3000mc_read_word(state, 206) & 0x0010; /* keep the pid_parse bit */
+
+ dprintk("-I- Setting output mode for demod %p to %d\n",
+ &state->demod, mode);
+
+ switch (mode) {
+ case OUTMODE_HIGH_Z: // disable
+ elecout = 0;
+ break;
+ case OUTMODE_MPEG2_PAR_GATED_CLK: // STBs with parallel gated clock
+ outmode = 0;
+ break;
+ case OUTMODE_MPEG2_PAR_CONT_CLK: // STBs with parallel continues clock
+ outmode = 1;
+ break;
+ case OUTMODE_MPEG2_SERIAL: // STBs with serial input
+ outmode = 2;
+ break;
+ case OUTMODE_MPEG2_FIFO: // e.g. USB feeding
+ elecout = 3;
+ /*ADDR @ 206 :
+ P_smo_error_discard [1;6:6] = 0
+ P_smo_rs_discard [1;5:5] = 0
+ P_smo_pid_parse [1;4:4] = 0
+ P_smo_fifo_flush [1;3:3] = 0
+ P_smo_mode [2;2:1] = 11
+ P_smo_ovf_prot [1;0:0] = 0
+ */
+ smo_reg |= 3 << 1;
+ fifo_threshold = 512;
+ outmode = 5;
+ break;
+ case OUTMODE_DIVERSITY:
+ outmode = 4;
+ elecout = 1;
break;
default:
- warn("unkown constellation.");
+ dprintk("Unhandled output_mode passed to be set for demod %p\n",&state->demod);
+ outmode = 0;
break;
}
- return 0;
+
+ if ((state->cfg->output_mpeg2_in_188_bytes))
+ smo_reg |= (1 << 5); // P_smo_rs_discard [1;5:5] = 1
+
+ outreg = dib3000mc_read_word(state, 244) & 0x07FF;
+ outreg |= (outmode << 11);
+ ret |= dib3000mc_write_word(state, 244, outreg);
+ ret |= dib3000mc_write_word(state, 206, smo_reg); /*smo_ mode*/
+ ret |= dib3000mc_write_word(state, 207, fifo_threshold); /* synchronous fread */
+ ret |= dib3000mc_write_word(state, 1040, elecout); /* P_out_cfg */
+ return ret;
}
-static int dib3000mc_set_general_cfg(struct dib3000_state *state, struct dvb_frontend_parameters *fep, int *auto_val)
+static int dib3000mc_set_bandwidth(struct dvb_frontend *demod, u8 bw)
{
- struct dvb_ofdm_parameters *ofdm = &fep->u.ofdm;
- fe_code_rate_t fe_cr = FEC_NONE;
- u8 fft=0, guard=0, qam=0, alpha=0, sel_hp=0, cr=0, hrch=0;
- int seq;
+ struct dib3000mc_state *state = demod->demodulator_priv;
+ u16 bw_cfg[6] = { 0 };
+ u16 imp_bw_cfg[3] = { 0 };
+ u16 reg;
- switch (ofdm->transmission_mode) {
- case TRANSMISSION_MODE_2K: fft = DIB3000_TRANSMISSION_MODE_2K; break;
- case TRANSMISSION_MODE_8K: fft = DIB3000_TRANSMISSION_MODE_8K; break;
- case TRANSMISSION_MODE_AUTO: break;
- default: return -EINVAL;
- }
- switch (ofdm->guard_interval) {
- case GUARD_INTERVAL_1_32: guard = DIB3000_GUARD_TIME_1_32; break;
- case GUARD_INTERVAL_1_16: guard = DIB3000_GUARD_TIME_1_16; break;
- case GUARD_INTERVAL_1_8: guard = DIB3000_GUARD_TIME_1_8; break;
- case GUARD_INTERVAL_1_4: guard = DIB3000_GUARD_TIME_1_4; break;
- case GUARD_INTERVAL_AUTO: break;
- default: return -EINVAL;
- }
- switch (ofdm->constellation) {
- case QPSK: qam = DIB3000_CONSTELLATION_QPSK; break;
- case QAM_16: qam = DIB3000_CONSTELLATION_16QAM; break;
- case QAM_64: qam = DIB3000_CONSTELLATION_64QAM; break;
- case QAM_AUTO: break;
- default: return -EINVAL;
- }
- switch (ofdm->hierarchy_information) {
- case HIERARCHY_NONE: /* fall through */
- case HIERARCHY_1: alpha = DIB3000_ALPHA_1; break;
- case HIERARCHY_2: alpha = DIB3000_ALPHA_2; break;
- case HIERARCHY_4: alpha = DIB3000_ALPHA_4; break;
- case HIERARCHY_AUTO: break;
- default: return -EINVAL;
- }
- if (ofdm->hierarchy_information == HIERARCHY_NONE) {
- hrch = DIB3000_HRCH_OFF;
- sel_hp = DIB3000_SELECT_HP;
- fe_cr = ofdm->code_rate_HP;
- } else if (ofdm->hierarchy_information != HIERARCHY_AUTO) {
- hrch = DIB3000_HRCH_ON;
- sel_hp = DIB3000_SELECT_LP;
- fe_cr = ofdm->code_rate_LP;
- }
- switch (fe_cr) {
- case FEC_1_2: cr = DIB3000_FEC_1_2; break;
- case FEC_2_3: cr = DIB3000_FEC_2_3; break;
- case FEC_3_4: cr = DIB3000_FEC_3_4; break;
- case FEC_5_6: cr = DIB3000_FEC_5_6; break;
- case FEC_7_8: cr = DIB3000_FEC_7_8; break;
- case FEC_NONE: break;
- case FEC_AUTO: break;
- default: return -EINVAL;
- }
+/* settings here are for 27.7MHz */
+ switch (bw) {
+ case BANDWIDTH_8_MHZ:
+ bw_cfg[0] = 0x0019; bw_cfg[1] = 0x5c30; bw_cfg[2] = 0x0054; bw_cfg[3] = 0x88a0; bw_cfg[4] = 0x01a6; bw_cfg[5] = 0xab20;
+ imp_bw_cfg[0] = 0x04db; imp_bw_cfg[1] = 0x00db; imp_bw_cfg[2] = 0x00b7;
+ break;
- wr(DIB3000MC_REG_DEMOD_PARM,DIB3000MC_DEMOD_PARM(alpha,qam,guard,fft));
- wr(DIB3000MC_REG_HRCH_PARM,DIB3000MC_HRCH_PARM(sel_hp,cr,hrch));
+ case BANDWIDTH_7_MHZ:
+ bw_cfg[0] = 0x001c; bw_cfg[1] = 0xfba5; bw_cfg[2] = 0x0060; bw_cfg[3] = 0x9c25; bw_cfg[4] = 0x01e3; bw_cfg[5] = 0x0cb7;
+ imp_bw_cfg[0] = 0x04c0; imp_bw_cfg[1] = 0x00c0; imp_bw_cfg[2] = 0x00a0;
+ break;
- switch (fep->inversion) {
- case INVERSION_OFF:
- wr(DIB3000MC_REG_SET_DDS_FREQ_MSB,DIB3000MC_DDS_FREQ_MSB_INV_OFF);
+ case BANDWIDTH_6_MHZ:
+ bw_cfg[0] = 0x0021; bw_cfg[1] = 0xd040; bw_cfg[2] = 0x0070; bw_cfg[3] = 0xb62b; bw_cfg[4] = 0x0233; bw_cfg[5] = 0x8ed5;
+ imp_bw_cfg[0] = 0x04a5; imp_bw_cfg[1] = 0x00a5; imp_bw_cfg[2] = 0x0089;
break;
- case INVERSION_AUTO: /* fall through */
- case INVERSION_ON:
- wr(DIB3000MC_REG_SET_DDS_FREQ_MSB,DIB3000MC_DDS_FREQ_MSB_INV_ON);
+
+ case 255 /* BANDWIDTH_5_MHZ */:
+ bw_cfg[0] = 0x0028; bw_cfg[1] = 0x9380; bw_cfg[2] = 0x0087; bw_cfg[3] = 0x4100; bw_cfg[4] = 0x02a4; bw_cfg[5] = 0x4500;
+ imp_bw_cfg[0] = 0x0489; imp_bw_cfg[1] = 0x0089; imp_bw_cfg[2] = 0x0072;
break;
- default:
- return -EINVAL;
+
+ default: return -EINVAL;
}
- seq = dib3000_seq
- [ofdm->transmission_mode == TRANSMISSION_MODE_AUTO]
- [ofdm->guard_interval == GUARD_INTERVAL_AUTO]
- [fep->inversion == INVERSION_AUTO];
-
- deb_setf("seq? %d\n", seq);
- wr(DIB3000MC_REG_SEQ_TPS,DIB3000MC_SEQ_TPS(seq,1));
- *auto_val = ofdm->constellation == QAM_AUTO ||
- ofdm->hierarchy_information == HIERARCHY_AUTO ||
- ofdm->guard_interval == GUARD_INTERVAL_AUTO ||
- ofdm->transmission_mode == TRANSMISSION_MODE_AUTO ||
- fe_cr == FEC_AUTO ||
- fep->inversion == INVERSION_AUTO;
- return 0;
-}
+ for (reg = 6; reg < 12; reg++)
+ dib3000mc_write_word(state, reg, bw_cfg[reg - 6]);
+ dib3000mc_write_word(state, 12, 0x0000);
+ dib3000mc_write_word(state, 13, 0x03e8);
+ dib3000mc_write_word(state, 14, 0x0000);
+ dib3000mc_write_word(state, 15, 0x03f2);
+ dib3000mc_write_word(state, 16, 0x0001);
+ dib3000mc_write_word(state, 17, 0xb0d0);
+ // P_sec_len
+ dib3000mc_write_word(state, 18, 0x0393);
+ dib3000mc_write_word(state, 19, 0x8700);
-static int dib3000mc_get_frontend(struct dvb_frontend* fe,
- struct dvb_frontend_parameters *fep)
-{
- struct dib3000_state* state = fe->demodulator_priv;
- struct dvb_ofdm_parameters *ofdm = &fep->u.ofdm;
- fe_code_rate_t *cr;
- u16 tps_val,cr_val;
- int inv_test1,inv_test2;
- u32 dds_val, threshold = 0x1000000;
-
- if (!(rd(DIB3000MC_REG_LOCK_507) & DIB3000MC_LOCK_507))
- return 0;
-
- dds_val = (rd(DIB3000MC_REG_DDS_FREQ_MSB) << 16) + rd(DIB3000MC_REG_DDS_FREQ_LSB);
- deb_getf("DDS_FREQ: %6x\n",dds_val);
- if (dds_val < threshold)
- inv_test1 = 0;
- else if (dds_val == threshold)
- inv_test1 = 1;
- else
- inv_test1 = 2;
-
- dds_val = (rd(DIB3000MC_REG_SET_DDS_FREQ_MSB) << 16) + rd(DIB3000MC_REG_SET_DDS_FREQ_LSB);
- deb_getf("DDS_SET_FREQ: %6x\n",dds_val);
- if (dds_val < threshold)
- inv_test2 = 0;
- else if (dds_val == threshold)
- inv_test2 = 1;
- else
- inv_test2 = 2;
+ for (reg = 55; reg < 58; reg++)
+ dib3000mc_write_word(state, reg, imp_bw_cfg[reg - 55]);
- fep->inversion =
- ((inv_test2 == 2) && (inv_test1==1 || inv_test1==0)) ||
- ((inv_test2 == 0) && (inv_test1==1 || inv_test1==2)) ?
- INVERSION_ON : INVERSION_OFF;
+ // Timing configuration
+ dib3000mc_set_timing(state, 0, bw, 0);
- deb_getf("inversion %d %d, %d\n", inv_test2, inv_test1, fep->inversion);
+ return 0;
+}
- fep->frequency = state->last_tuned_freq;
- fep->u.ofdm.bandwidth= state->last_tuned_bw;
+static u16 impulse_noise_val[29] =
- tps_val = rd(DIB3000MC_REG_TUNING_PARM);
+{
+ 0x38, 0x6d9, 0x3f28, 0x7a7, 0x3a74, 0x196, 0x32a, 0x48c, 0x3ffe, 0x7f3,
+ 0x2d94, 0x76, 0x53d, 0x3ff8, 0x7e3, 0x3320, 0x76, 0x5b3, 0x3feb, 0x7d2,
+ 0x365e, 0x76, 0x48c, 0x3ffe, 0x5b3, 0x3feb, 0x76, 0x0000, 0xd
+};
- switch (DIB3000MC_TP_QAM(tps_val)) {
- case DIB3000_CONSTELLATION_QPSK:
- deb_getf("QPSK ");
- ofdm->constellation = QPSK;
- break;
- case DIB3000_CONSTELLATION_16QAM:
- deb_getf("QAM16 ");
- ofdm->constellation = QAM_16;
- break;
- case DIB3000_CONSTELLATION_64QAM:
- deb_getf("QAM64 ");
- ofdm->constellation = QAM_64;
- break;
- default:
- err("Unexpected constellation returned by TPS (%d)", tps_val);
- break;
+static void dib3000mc_set_impulse_noise(struct dib3000mc_state *state, u8 mode, s16 nfft)
+{
+ u16 i;
+ for (i = 58; i < 87; i++)
+ dib3000mc_write_word(state, i, impulse_noise_val[i-58]);
+
+ if (nfft == 1) {
+ dib3000mc_write_word(state, 58, 0x3b);
+ dib3000mc_write_word(state, 84, 0x00);
+ dib3000mc_write_word(state, 85, 0x8200);
}
- if (DIB3000MC_TP_HRCH(tps_val)) {
- deb_getf("HRCH ON ");
- cr = &ofdm->code_rate_LP;
- ofdm->code_rate_HP = FEC_NONE;
- switch (DIB3000MC_TP_ALPHA(tps_val)) {
- case DIB3000_ALPHA_0:
- deb_getf("HIERARCHY_NONE ");
- ofdm->hierarchy_information = HIERARCHY_NONE;
- break;
- case DIB3000_ALPHA_1:
- deb_getf("HIERARCHY_1 ");
- ofdm->hierarchy_information = HIERARCHY_1;
- break;
- case DIB3000_ALPHA_2:
- deb_getf("HIERARCHY_2 ");
- ofdm->hierarchy_information = HIERARCHY_2;
- break;
- case DIB3000_ALPHA_4:
- deb_getf("HIERARCHY_4 ");
- ofdm->hierarchy_information = HIERARCHY_4;
- break;
- default:
- err("Unexpected ALPHA value returned by TPS (%d)", tps_val);
- break;
- }
- cr_val = DIB3000MC_TP_FEC_CR_LP(tps_val);
+ dib3000mc_write_word(state, 34, 0x1294);
+ dib3000mc_write_word(state, 35, 0x1ff8);
+ if (mode == 1)
+ dib3000mc_write_word(state, 55, dib3000mc_read_word(state, 55) | (1 << 10));
+}
+
+static int dib3000mc_init(struct dvb_frontend *demod)
+{
+ struct dib3000mc_state *state = demod->demodulator_priv;
+ struct dibx000_agc_config *agc = state->cfg->agc;
+
+ // Restart Configuration
+ dib3000mc_write_word(state, 1027, 0x8000);
+ dib3000mc_write_word(state, 1027, 0x0000);
+
+ // power up the demod + mobility configuration
+ dib3000mc_write_word(state, 140, 0x0000);
+ dib3000mc_write_word(state, 1031, 0);
+
+ if (state->cfg->mobile_mode) {
+ dib3000mc_write_word(state, 139, 0x0000);
+ dib3000mc_write_word(state, 141, 0x0000);
+ dib3000mc_write_word(state, 175, 0x0002);
+ dib3000mc_write_word(state, 1032, 0x0000);
} else {
- deb_getf("HRCH OFF ");
- cr = &ofdm->code_rate_HP;
- ofdm->code_rate_LP = FEC_NONE;
- ofdm->hierarchy_information = HIERARCHY_NONE;
- cr_val = DIB3000MC_TP_FEC_CR_HP(tps_val);
+ dib3000mc_write_word(state, 139, 0x0001);
+ dib3000mc_write_word(state, 141, 0x0000);
+ dib3000mc_write_word(state, 175, 0x0000);
+ dib3000mc_write_word(state, 1032, 0x012C);
}
+ dib3000mc_write_word(state, 1033, 0);
- switch (cr_val) {
- case DIB3000_FEC_1_2:
- deb_getf("FEC_1_2 ");
- *cr = FEC_1_2;
- break;
- case DIB3000_FEC_2_3:
- deb_getf("FEC_2_3 ");
- *cr = FEC_2_3;
- break;
- case DIB3000_FEC_3_4:
- deb_getf("FEC_3_4 ");
- *cr = FEC_3_4;
- break;
- case DIB3000_FEC_5_6:
- deb_getf("FEC_5_6 ");
- *cr = FEC_4_5;
- break;
- case DIB3000_FEC_7_8:
- deb_getf("FEC_7_8 ");
- *cr = FEC_7_8;
- break;
- default:
- err("Unexpected FEC returned by TPS (%d)", tps_val);
- break;
- }
+ // P_clk_cfg
+ dib3000mc_write_word(state, 1037, 12592);
- switch (DIB3000MC_TP_GUARD(tps_val)) {
- case DIB3000_GUARD_TIME_1_32:
- deb_getf("GUARD_INTERVAL_1_32 ");
- ofdm->guard_interval = GUARD_INTERVAL_1_32;
- break;
- case DIB3000_GUARD_TIME_1_16:
- deb_getf("GUARD_INTERVAL_1_16 ");
- ofdm->guard_interval = GUARD_INTERVAL_1_16;
- break;
- case DIB3000_GUARD_TIME_1_8:
- deb_getf("GUARD_INTERVAL_1_8 ");
- ofdm->guard_interval = GUARD_INTERVAL_1_8;
- break;
- case DIB3000_GUARD_TIME_1_4:
- deb_getf("GUARD_INTERVAL_1_4 ");
- ofdm->guard_interval = GUARD_INTERVAL_1_4;
- break;
- default:
- err("Unexpected Guard Time returned by TPS (%d)", tps_val);
- break;
- }
+ // other configurations
- switch (DIB3000MC_TP_FFT(tps_val)) {
- case DIB3000_TRANSMISSION_MODE_2K:
- deb_getf("TRANSMISSION_MODE_2K ");
- ofdm->transmission_mode = TRANSMISSION_MODE_2K;
- break;
- case DIB3000_TRANSMISSION_MODE_8K:
- deb_getf("TRANSMISSION_MODE_8K ");
- ofdm->transmission_mode = TRANSMISSION_MODE_8K;
- break;
- default:
- err("unexpected transmission mode return by TPS (%d)", tps_val);
- break;
- }
- deb_getf("\n");
+ // P_ctrl_sfreq
+ dib3000mc_write_word(state, 33, (5 << 0));
+ dib3000mc_write_word(state, 88, (1 << 10) | (0x10 << 0));
+
+ // Phase noise control
+ // P_fft_phacor_inh, P_fft_phacor_cpe, P_fft_powrange
+ dib3000mc_write_word(state, 99, (1 << 9) | (0x20 << 0));
+
+ if (state->cfg->phase_noise_mode == 0)
+ dib3000mc_write_word(state, 111, 0x00);
+ else
+ dib3000mc_write_word(state, 111, 0x02);
+
+ // P_agc_global
+ dib3000mc_write_word(state, 50, 0x8000);
+
+ // agc setup misc
+ dib3000mc_setup_pwm3_state(state);
+
+ // P_agc_counter_lock
+ dib3000mc_write_word(state, 53, 0x87);
+ // P_agc_counter_unlock
+ dib3000mc_write_word(state, 54, 0x87);
+
+ /* agc */
+ dib3000mc_write_word(state, 36, state->cfg->max_time);
+ dib3000mc_write_word(state, 37, agc->setup);
+ dib3000mc_write_word(state, 38, state->cfg->pwm3_value);
+ dib3000mc_write_word(state, 39, state->cfg->ln_adc_level);
+
+ // set_agc_loop_Bw
+ dib3000mc_write_word(state, 40, 0x0179);
+ dib3000mc_write_word(state, 41, 0x03f0);
+
+ dib3000mc_write_word(state, 42, agc->agc1_max);
+ dib3000mc_write_word(state, 43, agc->agc1_min);
+ dib3000mc_write_word(state, 44, agc->agc2_max);
+ dib3000mc_write_word(state, 45, agc->agc2_min);
+ dib3000mc_write_word(state, 46, (agc->agc1_pt1 << 8) | agc->agc1_pt2);
+ dib3000mc_write_word(state, 47, (agc->agc1_slope1 << 8) | agc->agc1_slope2);
+ dib3000mc_write_word(state, 48, (agc->agc2_pt1 << 8) | agc->agc2_pt2);
+ dib3000mc_write_word(state, 49, (agc->agc2_slope1 << 8) | agc->agc2_slope2);
+
+// Begin: TimeOut registers
+ // P_pha3_thres
+ dib3000mc_write_word(state, 110, 3277);
+ // P_timf_alpha = 6, P_corm_alpha = 6, P_corm_thres = 0x80
+ dib3000mc_write_word(state, 26, 0x6680);
+ // lock_mask0
+ dib3000mc_write_word(state, 1, 4);
+ // lock_mask1
+ dib3000mc_write_word(state, 2, 4);
+ // lock_mask2
+ dib3000mc_write_word(state, 3, 0x1000);
+ // P_search_maxtrial=1
+ dib3000mc_write_word(state, 5, 1);
+
+ dib3000mc_set_bandwidth(&state->demod, BANDWIDTH_8_MHZ);
+
+ // div_lock_mask
+ dib3000mc_write_word(state, 4, 0x814);
+
+ dib3000mc_write_word(state, 21, (1 << 9) | 0x164);
+ dib3000mc_write_word(state, 22, 0x463d);
+
+ // Spurious rm cfg
+ // P_cspu_regul, P_cspu_win_cut
+ dib3000mc_write_word(state, 120, 0x200f);
+ // P_adp_selec_monit
+ dib3000mc_write_word(state, 134, 0);
+
+ // Fec cfg
+ dib3000mc_write_word(state, 195, 0x10);
+
+ // diversity register: P_dvsy_sync_wait..
+ dib3000mc_write_word(state, 180, 0x2FF0);
+
+ // Impulse noise configuration
+ dib3000mc_set_impulse_noise(state, 0, 1);
+
+ // output mode set-up
+ dib3000mc_set_output_mode(state, OUTMODE_HIGH_Z);
+
+ /* close the i2c-gate */
+ dib3000mc_write_word(state, 769, (1 << 7) );
return 0;
}
-static int dib3000mc_set_frontend(struct dvb_frontend* fe,
- struct dvb_frontend_parameters *fep, int tuner)
+static int dib3000mc_sleep(struct dvb_frontend *demod)
{
- struct dib3000_state* state = fe->demodulator_priv;
- struct dvb_ofdm_parameters *ofdm = &fep->u.ofdm;
- int search_state,auto_val;
- u16 val;
+ struct dib3000mc_state *state = demod->demodulator_priv;
- if (tuner && fe->ops.tuner_ops.set_params) { /* initial call from dvb */
- fe->ops.tuner_ops.set_params(fe, fep);
- if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0);
-
- state->last_tuned_freq = fep->frequency;
- // if (!scanboost) {
- dib3000mc_set_timing(state,0,ofdm->transmission_mode,ofdm->bandwidth);
- dib3000mc_init_auto_scan(state, ofdm->bandwidth, 0);
- state->last_tuned_bw = ofdm->bandwidth;
-
- wr_foreach(dib3000mc_reg_agc_bandwidth,dib3000mc_agc_bandwidth);
- wr(DIB3000MC_REG_RESTART,DIB3000MC_RESTART_AGC);
- wr(DIB3000MC_REG_RESTART,DIB3000MC_RESTART_OFF);
-
- /* Default cfg isi offset adp */
- wr_foreach(dib3000mc_reg_offset,dib3000mc_offset[0]);
-
- wr(DIB3000MC_REG_ISI,DIB3000MC_ISI_DEFAULT | DIB3000MC_ISI_INHIBIT);
- dib3000mc_set_adp_cfg(state,ofdm->constellation);
- wr(DIB3000MC_REG_UNK_133,DIB3000MC_UNK_133);
-
- wr_foreach(dib3000mc_reg_bandwidth_general,dib3000mc_bandwidth_general);
- /* power smoothing */
- if (ofdm->bandwidth != BANDWIDTH_8_MHZ) {
- wr_foreach(dib3000mc_reg_bw,dib3000mc_bw[0]);
- } else {
- wr_foreach(dib3000mc_reg_bw,dib3000mc_bw[3]);
- }
- auto_val = 0;
- dib3000mc_set_general_cfg(state,fep,&auto_val);
- dib3000mc_set_impulse_noise(state,0,ofdm->constellation,ofdm->bandwidth);
-
- val = rd(DIB3000MC_REG_DEMOD_PARM);
- wr(DIB3000MC_REG_DEMOD_PARM,val|DIB3000MC_DEMOD_RST_DEMOD_ON);
- wr(DIB3000MC_REG_DEMOD_PARM,val);
- // }
- msleep(70);
-
- /* something has to be auto searched */
- if (auto_val) {
- int as_count=0;
-
- deb_setf("autosearch enabled.\n");
-
- val = rd(DIB3000MC_REG_DEMOD_PARM);
- wr(DIB3000MC_REG_DEMOD_PARM,val | DIB3000MC_DEMOD_RST_AUTO_SRCH_ON);
- wr(DIB3000MC_REG_DEMOD_PARM,val);
-
- while ((search_state = dib3000_search_status(
- rd(DIB3000MC_REG_AS_IRQ),1)) < 0 && as_count++ < 100)
- msleep(10);
-
- deb_info("search_state after autosearch %d after %d checks\n",search_state,as_count);
-
- if (search_state == 1) {
- struct dvb_frontend_parameters feps;
- if (dib3000mc_get_frontend(fe, &feps) == 0) {
- deb_setf("reading tuning data from frontend succeeded.\n");
- return dib3000mc_set_frontend(fe, &feps, 0);
- }
- }
- } else {
- dib3000mc_set_impulse_noise(state,0,ofdm->transmission_mode,ofdm->bandwidth);
- wr(DIB3000MC_REG_ISI,DIB3000MC_ISI_DEFAULT|DIB3000MC_ISI_ACTIVATE);
- dib3000mc_set_adp_cfg(state,ofdm->constellation);
-
- /* set_offset_cfg */
- wr_foreach(dib3000mc_reg_offset,
- dib3000mc_offset[(ofdm->transmission_mode == TRANSMISSION_MODE_8K)+1]);
- }
- } else { /* second call, after autosearch (fka: set_WithKnownParams) */
-// dib3000mc_set_timing(state,1,ofdm->transmission_mode,ofdm->bandwidth);
-
- auto_val = 0;
- dib3000mc_set_general_cfg(state,fep,&auto_val);
- if (auto_val)
- deb_info("auto_val is true, even though an auto search was already performed.\n");
-
- dib3000mc_set_impulse_noise(state,0,ofdm->constellation,ofdm->bandwidth);
-
- val = rd(DIB3000MC_REG_DEMOD_PARM);
- wr(DIB3000MC_REG_DEMOD_PARM,val | DIB3000MC_DEMOD_RST_AUTO_SRCH_ON);
- wr(DIB3000MC_REG_DEMOD_PARM,val);
+ dib3000mc_write_word(state, 1037, dib3000mc_read_word(state, 1037) | 0x0003);
+ dib3000mc_write_word(state, 1031, 0xFFFF);
+ dib3000mc_write_word(state, 1032, 0xFFFF);
+ dib3000mc_write_word(state, 1033, 0xFFF4); // **** Bin2
- msleep(30);
+ return 0;
+}
- wr(DIB3000MC_REG_ISI,DIB3000MC_ISI_DEFAULT|DIB3000MC_ISI_ACTIVATE);
- dib3000mc_set_adp_cfg(state,ofdm->constellation);
- wr_foreach(dib3000mc_reg_offset,
- dib3000mc_offset[(ofdm->transmission_mode == TRANSMISSION_MODE_8K)+1]);
+static void dib3000mc_set_adp_cfg(struct dib3000mc_state *state, s16 qam)
+{
+ u16 cfg[4] = { 0 },reg;
+ switch (qam) {
+ case 0:
+ cfg[0] = 0x099a; cfg[1] = 0x7fae; cfg[2] = 0x0333; cfg[3] = 0x7ff0;
+ break;
+ case 1:
+ cfg[0] = 0x023d; cfg[1] = 0x7fdf; cfg[2] = 0x00a4; cfg[3] = 0x7ff0;
+ break;
+ case 2:
+ cfg[0] = 0x0148; cfg[1] = 0x7ff0; cfg[2] = 0x00a4; cfg[3] = 0x7ff8;
+ break;
}
- return 0;
+ for (reg = 129; reg < 133; reg++)
+ dib3000mc_write_word(state, reg, cfg[reg - 129]);
}
-static int dib3000mc_fe_init(struct dvb_frontend* fe, int mobile_mode)
+static void dib3000mc_set_channel_cfg(struct dib3000mc_state *state, struct dibx000_ofdm_channel *chan, u16 seq)
{
- struct dib3000_state *state = fe->demodulator_priv;
- deb_info("init start\n");
-
- state->timing_offset = 0;
- state->timing_offset_comp_done = 0;
+ u16 tmp;
- wr(DIB3000MC_REG_RESTART,DIB3000MC_RESTART_CONFIG);
- wr(DIB3000MC_REG_RESTART,DIB3000MC_RESTART_OFF);
- wr(DIB3000MC_REG_CLK_CFG_1,DIB3000MC_CLK_CFG_1_POWER_UP);
- wr(DIB3000MC_REG_CLK_CFG_2,DIB3000MC_CLK_CFG_2_PUP_MOBILE);
- wr(DIB3000MC_REG_CLK_CFG_3,DIB3000MC_CLK_CFG_3_POWER_UP);
- wr(DIB3000MC_REG_CLK_CFG_7,DIB3000MC_CLK_CFG_7_INIT);
+ dib3000mc_set_timing(state, chan->nfft, chan->Bw, 0);
- wr(DIB3000MC_REG_RST_UNC,DIB3000MC_RST_UNC_OFF);
- wr(DIB3000MC_REG_UNK_19,DIB3000MC_UNK_19);
+// if (boost)
+// dib3000mc_write_word(state, 100, (11 << 6) + 6);
+// else
+ dib3000mc_write_word(state, 100, (16 << 6) + 9);
- wr(33,5);
- wr(36,81);
- wr(DIB3000MC_REG_UNK_88,DIB3000MC_UNK_88);
+ dib3000mc_write_word(state, 1027, 0x0800);
+ dib3000mc_write_word(state, 1027, 0x0000);
- wr(DIB3000MC_REG_UNK_99,DIB3000MC_UNK_99);
- wr(DIB3000MC_REG_UNK_111,DIB3000MC_UNK_111_PH_N_MODE_0); /* phase noise algo off */
+ //Default cfg isi offset adp
+ dib3000mc_write_word(state, 26, 0x6680);
+ dib3000mc_write_word(state, 29, 0x1273);
+ dib3000mc_write_word(state, 33, 5);
+ dib3000mc_set_adp_cfg(state, 1);
+ dib3000mc_write_word(state, 133, 15564);
- /* mobile mode - portable reception */
- wr_foreach(dib3000mc_reg_mobile_mode,dib3000mc_mobile_mode[1]);
+ dib3000mc_write_word(state, 12 , 0x0);
+ dib3000mc_write_word(state, 13 , 0x3e8);
+ dib3000mc_write_word(state, 14 , 0x0);
+ dib3000mc_write_word(state, 15 , 0x3f2);
-/* TUNER_PANASONIC_ENV57H12D5: */
- wr_foreach(dib3000mc_reg_agc_bandwidth,dib3000mc_agc_bandwidth);
- wr_foreach(dib3000mc_reg_agc_bandwidth_general,dib3000mc_agc_bandwidth_general);
- wr_foreach(dib3000mc_reg_agc,dib3000mc_agc_tuner[1]);
+ dib3000mc_write_word(state, 93,0);
+ dib3000mc_write_word(state, 94,0);
+ dib3000mc_write_word(state, 95,0);
+ dib3000mc_write_word(state, 96,0);
+ dib3000mc_write_word(state, 97,0);
+ dib3000mc_write_word(state, 98,0);
- wr(DIB3000MC_REG_UNK_110,DIB3000MC_UNK_110);
- wr(26,0x6680);
- wr(DIB3000MC_REG_UNK_1,DIB3000MC_UNK_1);
- wr(DIB3000MC_REG_UNK_2,DIB3000MC_UNK_2);
- wr(DIB3000MC_REG_UNK_3,DIB3000MC_UNK_3);
- wr(DIB3000MC_REG_SEQ_TPS,DIB3000MC_SEQ_TPS_DEFAULT);
+ dib3000mc_set_impulse_noise(state, 0, chan->nfft);
- wr_foreach(dib3000mc_reg_bandwidth,dib3000mc_bandwidth_8mhz);
- wr_foreach(dib3000mc_reg_bandwidth_general,dib3000mc_bandwidth_general);
+ tmp = ((chan->nfft & 0x1) << 7) | (chan->guard << 5) | (chan->nqam << 3) | chan->vit_alpha;
+ dib3000mc_write_word(state, 0, tmp);
- wr(DIB3000MC_REG_UNK_4,DIB3000MC_UNK_4);
+ dib3000mc_write_word(state, 5, seq);
- wr(DIB3000MC_REG_SET_DDS_FREQ_MSB,DIB3000MC_DDS_FREQ_MSB_INV_OFF);
- wr(DIB3000MC_REG_SET_DDS_FREQ_LSB,DIB3000MC_DDS_FREQ_LSB);
+ tmp = (chan->vit_hrch << 4) | (chan->vit_select_hp);
+ if (!chan->vit_hrch || (chan->vit_hrch && chan->vit_select_hp))
+ tmp |= chan->vit_code_rate_hp << 1;
+ else
+ tmp |= chan->vit_code_rate_lp << 1;
+ dib3000mc_write_word(state, 181, tmp);
- dib3000mc_set_timing(state,0,TRANSMISSION_MODE_8K,BANDWIDTH_8_MHZ);
-// wr_foreach(dib3000mc_reg_timing_freq,dib3000mc_timing_freq[3]);
+ // diversity synchro delay
+ tmp = dib3000mc_read_word(state, 180) & 0x000f;
+ tmp |= ((chan->nfft == 0) ? 64 : 256) * ((1 << (chan->guard)) * 3 / 2) << 4; // add 50% SFN margin
+ dib3000mc_write_word(state, 180, tmp);
- wr(DIB3000MC_REG_UNK_120,DIB3000MC_UNK_120);
- wr(DIB3000MC_REG_UNK_134,DIB3000MC_UNK_134);
- wr(DIB3000MC_REG_FEC_CFG,DIB3000MC_FEC_CFG);
+ // restart demod
+ tmp = dib3000mc_read_word(state, 0);
+ dib3000mc_write_word(state, 0, tmp | (1 << 9));
+ dib3000mc_write_word(state, 0, tmp);
- wr(DIB3000MC_REG_DIVERSITY3,DIB3000MC_DIVERSITY3_IN_OFF);
+ msleep(30);
- dib3000mc_set_impulse_noise(state,0,TRANSMISSION_MODE_8K,BANDWIDTH_8_MHZ);
+ dib3000mc_set_impulse_noise(state, state->cfg->impulse_noise_mode, chan->nfft);
+}
-/* output mode control, just the MPEG2_SLAVE */
-// set_or(DIB3000MC_REG_OUTMODE,DIB3000MC_OM_SLAVE);
- wr(DIB3000MC_REG_OUTMODE,DIB3000MC_OM_SLAVE);
- wr(DIB3000MC_REG_SMO_MODE,DIB3000MC_SMO_MODE_SLAVE);
- wr(DIB3000MC_REG_FIFO_THRESHOLD,DIB3000MC_FIFO_THRESHOLD_SLAVE);
- wr(DIB3000MC_REG_ELEC_OUT,DIB3000MC_ELEC_OUT_SLAVE);
+static int dib3000mc_autosearch_start(struct dvb_frontend *demod, struct dibx000_ofdm_channel *chan)
+{
+ struct dib3000mc_state *state = demod->demodulator_priv;
+ u16 reg;
+// u32 val;
+ struct dibx000_ofdm_channel fchan;
-/* MPEG2_PARALLEL_CONTINUOUS_CLOCK
- wr(DIB3000MC_REG_OUTMODE,
- DIB3000MC_SET_OUTMODE(DIB3000MC_OM_PAR_CONT_CLK,
- rd(DIB3000MC_REG_OUTMODE)));
+ INIT_OFDM_CHANNEL(&fchan);
+ fchan = *chan;
- wr(DIB3000MC_REG_SMO_MODE,
- DIB3000MC_SMO_MODE_DEFAULT |
- DIB3000MC_SMO_MODE_188);
- wr(DIB3000MC_REG_FIFO_THRESHOLD,DIB3000MC_FIFO_THRESHOLD_DEFAULT);
- wr(DIB3000MC_REG_ELEC_OUT,DIB3000MC_ELEC_OUT_DIV_OUT_ON);
-*/
+ /* a channel for autosearch */
+ reg = 0;
+ if (chan->nfft == -1 && chan->guard == -1) reg = 7;
+ if (chan->nfft == -1 && chan->guard != -1) reg = 2;
+ if (chan->nfft != -1 && chan->guard == -1) reg = 3;
-/* diversity */
- wr(DIB3000MC_REG_DIVERSITY1,DIB3000MC_DIVERSITY1_DEFAULT);
- wr(DIB3000MC_REG_DIVERSITY2,DIB3000MC_DIVERSITY2_DEFAULT);
+ fchan.nfft = 1; fchan.guard = 0; fchan.nqam = 2;
+ fchan.vit_alpha = 1; fchan.vit_code_rate_hp = 2; fchan.vit_code_rate_lp = 2;
+ fchan.vit_hrch = 0; fchan.vit_select_hp = 1;
- set_and(DIB3000MC_REG_DIVERSITY3,DIB3000MC_DIVERSITY3_IN_OFF);
+ dib3000mc_set_channel_cfg(state, &fchan, reg);
- set_or(DIB3000MC_REG_CLK_CFG_7,DIB3000MC_CLK_CFG_7_DIV_IN_OFF);
+ reg = dib3000mc_read_word(state, 0);
+ dib3000mc_write_word(state, 0, reg | (1 << 8));
+ dib3000mc_write_word(state, 0, reg);
- deb_info("init end\n");
return 0;
}
-static int dib3000mc_read_status(struct dvb_frontend* fe, fe_status_t *stat)
+
+static int dib3000mc_autosearch_is_irq(struct dvb_frontend *demod)
{
- struct dib3000_state* state = fe->demodulator_priv;
- u16 lock = rd(DIB3000MC_REG_LOCKING);
+ struct dib3000mc_state *state = demod->demodulator_priv;
+ u16 irq_pending = dib3000mc_read_word(state, 511);
- *stat = 0;
- if (DIB3000MC_AGC_LOCK(lock))
- *stat |= FE_HAS_SIGNAL;
- if (DIB3000MC_CARRIER_LOCK(lock))
- *stat |= FE_HAS_CARRIER;
- if (DIB3000MC_TPS_LOCK(lock))
- *stat |= FE_HAS_VITERBI;
- if (DIB3000MC_MPEG_SYNC_LOCK(lock))
- *stat |= (FE_HAS_SYNC | FE_HAS_LOCK);
+ if (irq_pending & 0x1) // failed
+ return 1;
- deb_stat("actual status is %2x fifo_level: %x,244: %x, 206: %x, 207: %x, 1040: %x\n",*stat,rd(510),rd(244),rd(206),rd(207),rd(1040));
+ if (irq_pending & 0x2) // succeeded
+ return 2;
- return 0;
+ return 0; // still pending
}
-static int dib3000mc_read_ber(struct dvb_frontend* fe, u32 *ber)
+static int dib3000mc_tune(struct dvb_frontend *demod, struct dibx000_ofdm_channel *ch)
{
- struct dib3000_state* state = fe->demodulator_priv;
- *ber = ((rd(DIB3000MC_REG_BER_MSB) << 16) | rd(DIB3000MC_REG_BER_LSB));
+ struct dib3000mc_state *state = demod->demodulator_priv;
+
+ // ** configure demod **
+ dib3000mc_set_channel_cfg(state, ch, 0);
+
+ // activates isi
+ dib3000mc_write_word(state, 29, 0x1073);
+
+ dib3000mc_set_adp_cfg(state, (u8)ch->nqam);
+
+ if (ch->nfft == 1) {
+ dib3000mc_write_word(state, 26, 38528);
+ dib3000mc_write_word(state, 33, 8);
+ } else {
+ dib3000mc_write_word(state, 26, 30336);
+ dib3000mc_write_word(state, 33, 6);
+ }
+
+ // if (lock)
+ // dib3000mc_set_timing(state, ch->nfft, ch->Bw, 1);
+
return 0;
}
-static int dib3000mc_read_unc_blocks(struct dvb_frontend* fe, u32 *unc)
+static int dib3000mc_demod_output_mode(struct dvb_frontend *demod, int mode)
{
- struct dib3000_state* state = fe->demodulator_priv;
-
- *unc = rd(DIB3000MC_REG_PACKET_ERRORS);
- return 0;
+ struct dib3000mc_state *state = demod->demodulator_priv;
+ return dib3000mc_set_output_mode(state, mode);
}
-/* see dib3000mb.c for calculation comments */
-static int dib3000mc_read_signal_strength(struct dvb_frontend* fe, u16 *strength)
+static int dib3000mc_i2c_enumeration(struct dvb_frontend *demod[], int no_of_demods, u8 default_addr)
{
- struct dib3000_state* state = fe->demodulator_priv;
- u16 val = rd(DIB3000MC_REG_SIGNAL_NOISE_LSB);
- *strength = (((val >> 6) & 0xff) << 8) + (val & 0x3f);
+ struct dib3000mc_state *st;
+ int k,ret=0;
+ u8 new_addr;
+
+ static u8 DIB3000MC_I2C_ADDRESS[] = {20,22,24,26};
+
+ for (k = no_of_demods-1; k >= 0; k--) {
+ st = demod[k]->demodulator_priv;
+
+ /* designated i2c address */
+ new_addr = DIB3000MC_I2C_ADDRESS[k];
+
+ st->i2c_addr = new_addr;
+ if (dib3000mc_identify(st) != 0) {
+ st->i2c_addr = default_addr;
+ if (dib3000mc_identify(st) != 0) {
+ dprintk("-E- DiB3000P/MC #%d: not identified\n", k);
+ return -EINVAL;
+ }
+ }
+
+ /* turn on div_out */
+ dib3000mc_demod_output_mode(demod[k], OUTMODE_MPEG2_PAR_CONT_CLK);
+
+ // set new i2c address and force divstr (Bit 1) to value 0 (Bit 0)
+ ret |= dib3000mc_write_word(st, 1024, (new_addr << 3) | 0x1);
+ st->i2c_addr = new_addr;
+ }
+
+ for (k = 0; k < no_of_demods; k++) {
+ st = demod[k]->demodulator_priv;
+
+ ret |= dib3000mc_write_word(st, 1024, st->i2c_addr << 3);
- deb_stat("signal: mantisse = %d, exponent = %d\n",(*strength >> 8) & 0xff, *strength & 0xff);
+ /* turn off data output */
+ dib3000mc_demod_output_mode(demod[k],OUTMODE_HIGH_Z);
+ dib3000mc_write_word(st, 769, (1 << 7) );
+
+ }
return 0;
}
-/* see dib3000mb.c for calculation comments */
-static int dib3000mc_read_snr(struct dvb_frontend* fe, u16 *snr)
+struct i2c_adapter * dib3000mc_get_tuner_i2c_master(struct dvb_frontend *demod, int gating)
{
- struct dib3000_state* state = fe->demodulator_priv;
- u16 val = rd(DIB3000MC_REG_SIGNAL_NOISE_LSB),
- val2 = rd(DIB3000MC_REG_SIGNAL_NOISE_MSB);
- u16 sig,noise;
+ struct dib3000mc_state *st = demod->demodulator_priv;
+ return dibx000_get_i2c_adapter(&st->i2c_master, DIBX000_I2C_INTERFACE_TUNER, gating);
+}
- sig = (((val >> 6) & 0xff) << 8) + (val & 0x3f);
- noise = (((val >> 4) & 0xff) << 8) + ((val & 0xf) << 2) + ((val2 >> 14) & 0x3);
- if (noise == 0)
- *snr = 0xffff;
- else
- *snr = (u16) sig/noise;
+EXPORT_SYMBOL(dib3000mc_get_tuner_i2c_master);
+
+static int dib3000mc_get_frontend(struct dvb_frontend* fe,
+ struct dvb_frontend_parameters *fep)
+{
+ struct dib3000mc_state *state = fe->demodulator_priv;
+ u16 tps = dib3000mc_read_word(state,458);
+
+ fep->inversion = INVERSION_AUTO;
+
+ fep->u.ofdm.bandwidth = state->current_bandwidth;
+
+ switch ((tps >> 8) & 0x1) {
+ case 0: fep->u.ofdm.transmission_mode = TRANSMISSION_MODE_2K; break;
+ case 1: fep->u.ofdm.transmission_mode = TRANSMISSION_MODE_8K; break;
+ }
+
+ switch (tps & 0x3) {
+ case 0: fep->u.ofdm.guard_interval = GUARD_INTERVAL_1_32; break;
+ case 1: fep->u.ofdm.guard_interval = GUARD_INTERVAL_1_16; break;
+ case 2: fep->u.ofdm.guard_interval = GUARD_INTERVAL_1_8; break;
+ case 3: fep->u.ofdm.guard_interval = GUARD_INTERVAL_1_4; break;
+ }
+
+ switch ((tps >> 13) & 0x3) {
+ case 0: fep->u.ofdm.constellation = QPSK; break;
+ case 1: fep->u.ofdm.constellation = QAM_16; break;
+ case 2:
+ default: fep->u.ofdm.constellation = QAM_64; break;
+ }
+
+ /* as long as the frontend_param structure is fixed for hierarchical transmission I refuse to use it */
+ /* (tps >> 12) & 0x1 == hrch is used, (tps >> 9) & 0x7 == alpha */
+
+ fep->u.ofdm.hierarchy_information = HIERARCHY_NONE;
+ switch ((tps >> 5) & 0x7) {
+ case 1: fep->u.ofdm.code_rate_HP = FEC_1_2; break;
+ case 2: fep->u.ofdm.code_rate_HP = FEC_2_3; break;
+ case 3: fep->u.ofdm.code_rate_HP = FEC_3_4; break;
+ case 5: fep->u.ofdm.code_rate_HP = FEC_5_6; break;
+ case 7:
+ default: fep->u.ofdm.code_rate_HP = FEC_7_8; break;
+
+ }
+
+ switch ((tps >> 2) & 0x7) {
+ case 1: fep->u.ofdm.code_rate_LP = FEC_1_2; break;
+ case 2: fep->u.ofdm.code_rate_LP = FEC_2_3; break;
+ case 3: fep->u.ofdm.code_rate_LP = FEC_3_4; break;
+ case 5: fep->u.ofdm.code_rate_LP = FEC_5_6; break;
+ case 7:
+ default: fep->u.ofdm.code_rate_LP = FEC_7_8; break;
+ }
- deb_stat("signal: mantisse = %d, exponent = %d\n",(sig >> 8) & 0xff, sig & 0xff);
- deb_stat("noise: mantisse = %d, exponent = %d\n",(noise >> 8) & 0xff, noise & 0xff);
- deb_stat("snr: %d\n",*snr);
return 0;
}
-static int dib3000mc_sleep(struct dvb_frontend* fe)
+static int dib3000mc_set_frontend(struct dvb_frontend* fe,
+ struct dvb_frontend_parameters *fep)
{
- struct dib3000_state* state = fe->demodulator_priv;
+ struct dib3000mc_state *state = fe->demodulator_priv;
+ struct dibx000_ofdm_channel ch;
- set_or(DIB3000MC_REG_CLK_CFG_7,DIB3000MC_CLK_CFG_7_PWR_DOWN);
- wr(DIB3000MC_REG_CLK_CFG_1,DIB3000MC_CLK_CFG_1_POWER_DOWN);
- wr(DIB3000MC_REG_CLK_CFG_2,DIB3000MC_CLK_CFG_2_POWER_DOWN);
- wr(DIB3000MC_REG_CLK_CFG_3,DIB3000MC_CLK_CFG_3_POWER_DOWN);
- return 0;
+ INIT_OFDM_CHANNEL(&ch);
+ FEP2DIB(fep,&ch);
+
+ state->current_bandwidth = fep->u.ofdm.bandwidth;
+ dib3000mc_set_bandwidth(fe, fep->u.ofdm.bandwidth);
+
+ if (fe->ops.tuner_ops.set_params) {
+ fe->ops.tuner_ops.set_params(fe, fep);
+ msleep(100);
+ }
+
+ if (fep->u.ofdm.transmission_mode == TRANSMISSION_MODE_AUTO ||
+ fep->u.ofdm.guard_interval == GUARD_INTERVAL_AUTO ||
+ fep->u.ofdm.constellation == QAM_AUTO ||
+ fep->u.ofdm.code_rate_HP == FEC_AUTO) {
+ int i = 100, found;
+
+ dib3000mc_autosearch_start(fe, &ch);
+ do {
+ msleep(1);
+ found = dib3000mc_autosearch_is_irq(fe);
+ } while (found == 0 && i--);
+
+ dprintk("autosearch returns: %d\n",found);
+ if (found == 0 || found == 1)
+ return 0; // no channel found
+
+ dib3000mc_get_frontend(fe, fep);
+ FEP2DIB(fep,&ch);
+ }
+
+ /* make this a config parameter */
+ dib3000mc_set_output_mode(state, OUTMODE_MPEG2_FIFO);
+
+ return dib3000mc_tune(fe, &ch);
}
-static int dib3000mc_fe_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings *tune)
+static int dib3000mc_read_status(struct dvb_frontend *fe, fe_status_t *stat)
{
- tune->min_delay_ms = 1000;
+ struct dib3000mc_state *state = fe->demodulator_priv;
+ u16 lock = dib3000mc_read_word(state, 509);
+
+ *stat = 0;
+
+ if (lock & 0x8000)
+ *stat |= FE_HAS_SIGNAL;
+ if (lock & 0x3000)
+ *stat |= FE_HAS_CARRIER;
+ if (lock & 0x0100)
+ *stat |= FE_HAS_VITERBI;
+ if (lock & 0x0010)
+ *stat |= FE_HAS_SYNC;
+ if (lock & 0x0008)
+ *stat |= FE_HAS_LOCK;
+
return 0;
}
-static int dib3000mc_fe_init_nonmobile(struct dvb_frontend* fe)
+static int dib3000mc_read_ber(struct dvb_frontend *fe, u32 *ber)
{
- return dib3000mc_fe_init(fe, 0);
+ struct dib3000mc_state *state = fe->demodulator_priv;
+ *ber = (dib3000mc_read_word(state, 500) << 16) | dib3000mc_read_word(state, 501);
+ return 0;
}
-static int dib3000mc_set_frontend_and_tuner(struct dvb_frontend* fe, struct dvb_frontend_parameters *fep)
+static int dib3000mc_read_unc_blocks(struct dvb_frontend *fe, u32 *unc)
{
- return dib3000mc_set_frontend(fe, fep, 1);
+ struct dib3000mc_state *state = fe->demodulator_priv;
+ *unc = dib3000mc_read_word(state, 508);
+ return 0;
}
-static void dib3000mc_release(struct dvb_frontend* fe)
+static int dib3000mc_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
{
- struct dib3000_state *state = fe->demodulator_priv;
- kfree(state);
+ struct dib3000mc_state *state = fe->demodulator_priv;
+ u16 val = dib3000mc_read_word(state, 392);
+ *strength = 65535 - val;
+ return 0;
}
-/* pid filter and transfer stuff */
-static int dib3000mc_pid_control(struct dvb_frontend *fe,int index, int pid,int onoff)
+static int dib3000mc_read_snr(struct dvb_frontend* fe, u16 *snr)
{
- struct dib3000_state *state = fe->demodulator_priv;
- pid = (onoff ? pid | DIB3000_ACTIVATE_PID_FILTERING : 0);
- wr(index+DIB3000MC_REG_FIRST_PID,pid);
+ *snr = 0x0000;
return 0;
}
-static int dib3000mc_fifo_control(struct dvb_frontend *fe, int onoff)
+static int dib3000mc_fe_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings *tune)
{
- struct dib3000_state *state = fe->demodulator_priv;
- u16 tmp = rd(DIB3000MC_REG_SMO_MODE);
-
- deb_xfer("%s fifo\n",onoff ? "enabling" : "disabling");
-
- if (onoff) {
- deb_xfer("%d %x\n",tmp & DIB3000MC_SMO_MODE_FIFO_UNFLUSH,tmp & DIB3000MC_SMO_MODE_FIFO_UNFLUSH);
- wr(DIB3000MC_REG_SMO_MODE,tmp & DIB3000MC_SMO_MODE_FIFO_UNFLUSH);
- } else {
- deb_xfer("%d %x\n",tmp | DIB3000MC_SMO_MODE_FIFO_FLUSH,tmp | DIB3000MC_SMO_MODE_FIFO_FLUSH);
- wr(DIB3000MC_REG_SMO_MODE,tmp | DIB3000MC_SMO_MODE_FIFO_FLUSH);
- }
+ tune->min_delay_ms = 1000;
return 0;
}
-static int dib3000mc_pid_parse(struct dvb_frontend *fe, int onoff)
+static void dib3000mc_release(struct dvb_frontend *fe)
{
- struct dib3000_state *state = fe->demodulator_priv;
- u16 tmp = rd(DIB3000MC_REG_SMO_MODE);
-
- deb_xfer("%s pid parsing\n",onoff ? "enabling" : "disabling");
-
- if (onoff) {
- wr(DIB3000MC_REG_SMO_MODE,tmp | DIB3000MC_SMO_MODE_PID_PARSE);
- } else {
- wr(DIB3000MC_REG_SMO_MODE,tmp & DIB3000MC_SMO_MODE_NO_PID_PARSE);
- }
- return 0;
+ struct dib3000mc_state *state = fe->demodulator_priv;
+ dibx000_exit_i2c_master(&state->i2c_master);
+ kfree(state);
}
-static int dib3000mc_tuner_pass_ctrl(struct dvb_frontend *fe, int onoff, u8 pll_addr)
+int dib3000mc_pid_control(struct dvb_frontend *fe, int index, int pid,int onoff)
{
- struct dib3000_state *state = fe->demodulator_priv;
- if (onoff) {
- wr(DIB3000MC_REG_TUNER, DIB3000_TUNER_WRITE_ENABLE(pll_addr));
- } else {
- wr(DIB3000MC_REG_TUNER, DIB3000_TUNER_WRITE_DISABLE(pll_addr));
- }
+ struct dib3000mc_state *state = fe->demodulator_priv;
+ dib3000mc_write_word(state, 212 + index, onoff ? (1 << 13) | pid : 0);
return 0;
}
+EXPORT_SYMBOL(dib3000mc_pid_control);
-static int dib3000mc_demod_init(struct dib3000_state *state)
+int dib3000mc_pid_parse(struct dvb_frontend *fe, int onoff)
{
- u16 default_addr = 0x0a;
- /* first init */
- if (state->config.demod_address != default_addr) {
- deb_info("initializing the demod the first time. Setting demod addr to 0x%x\n",default_addr);
- wr(DIB3000MC_REG_ELEC_OUT,DIB3000MC_ELEC_OUT_DIV_OUT_ON);
- wr(DIB3000MC_REG_OUTMODE,DIB3000MC_OM_PAR_CONT_CLK);
-
- wr(DIB3000MC_REG_RST_I2C_ADDR,
- DIB3000MC_DEMOD_ADDR(default_addr) |
- DIB3000MC_DEMOD_ADDR_ON);
-
- state->config.demod_address = default_addr;
-
- wr(DIB3000MC_REG_RST_I2C_ADDR,
- DIB3000MC_DEMOD_ADDR(default_addr));
- } else
- deb_info("demod is already initialized. Demod addr: 0x%x\n",state->config.demod_address);
- return 0;
+ struct dib3000mc_state *state = fe->demodulator_priv;
+ u16 tmp = dib3000mc_read_word(state, 206) & ~(1 << 4);
+ tmp |= (onoff << 4);
+ return dib3000mc_write_word(state, 206, tmp);
}
+EXPORT_SYMBOL(dib3000mc_pid_parse);
+void dib3000mc_set_config(struct dvb_frontend *fe, struct dib3000mc_config *cfg)
+{
+ struct dib3000mc_state *state = fe->demodulator_priv;
+ state->cfg = cfg;
+}
+EXPORT_SYMBOL(dib3000mc_set_config);
static struct dvb_frontend_ops dib3000mc_ops;
-struct dvb_frontend* dib3000mc_attach(const struct dib3000_config* config,
- struct i2c_adapter* i2c, struct dib_fe_xfer_ops *xfer_ops)
+int dib3000mc_attach(struct i2c_adapter *i2c_adap, int no_of_demods, u8 default_addr, u8 do_i2c_enum, struct dib3000mc_config cfg[], struct dvb_frontend *demod[])
{
- struct dib3000_state* state = NULL;
- u16 devid;
+ struct dib3000mc_state *st;
+ int k, num=0;
- /* allocate memory for the internal state */
- state = kzalloc(sizeof(struct dib3000_state), GFP_KERNEL);
- if (state == NULL)
- goto error;
+ if (no_of_demods < 1)
+ return -EINVAL;
- /* setup the state */
- state->i2c = i2c;
- memcpy(&state->config,config,sizeof(struct dib3000_config));
+ for (k = 0; k < no_of_demods; k++) {
+ st = kzalloc(sizeof(struct dib3000mc_state), GFP_KERNEL);
+ if (st == NULL)
+ goto error;
- /* check for the correct demod */
- if (rd(DIB3000_REG_MANUFACTOR_ID) != DIB3000_I2C_ID_DIBCOM)
- goto error;
+ num++;
- devid = rd(DIB3000_REG_DEVICE_ID);
- if (devid != DIB3000MC_DEVICE_ID && devid != DIB3000P_DEVICE_ID)
- goto error;
+ st->cfg = &cfg[k];
+ // st->gpio_val = cfg[k].gpio_val;
+ // st->gpio_dir = cfg[k].gpio_dir;
+ st->i2c_adap = i2c_adap;
- switch (devid) {
- case DIB3000MC_DEVICE_ID:
- info("Found a DiBcom 3000M-C, interesting...");
- break;
- case DIB3000P_DEVICE_ID:
- info("Found a DiBcom 3000P.");
- break;
- }
+ demod[k] = &st->demod;
+ demod[k]->demodulator_priv = st;
+ memcpy(&st->demod.ops, &dib3000mc_ops, sizeof(struct dvb_frontend_ops));
- /* create dvb_frontend */
- memcpy(&state->frontend.ops, &dib3000mc_ops, sizeof(struct dvb_frontend_ops));
- state->frontend.demodulator_priv = state;
+// INIT_COMPONENT_REGISTER_ACCESS(&st->register_access, 12, 16, dib7000p_register_read, dib7000p_register_write, st);
+// demod[k]->register_access = &st->register_access;
+ }
- /* set the xfer operations */
- xfer_ops->pid_parse = dib3000mc_pid_parse;
- xfer_ops->fifo_ctrl = dib3000mc_fifo_control;
- xfer_ops->pid_ctrl = dib3000mc_pid_control;
- xfer_ops->tuner_pass_ctrl = dib3000mc_tuner_pass_ctrl;
+ if (do_i2c_enum) {
+ if (dib3000mc_i2c_enumeration(demod,no_of_demods,default_addr) != 0)
+ goto error;
+ } else {
+ st = demod[0]->demodulator_priv;
+ st->i2c_addr = default_addr;
+ if (dib3000mc_identify(st) != 0)
+ goto error;
+ }
- dib3000mc_demod_init(state);
+ for (k = 0; k < num; k++) {
+ st = demod[k]->demodulator_priv;
+ dibx000_init_i2c_master(&st->i2c_master, DIB3000MC, st->i2c_adap, st->i2c_addr);
+ }
- return &state->frontend;
+ return 0;
error:
- kfree(state);
- return NULL;
+ for (k = 0; k < num; k++) {
+ kfree(demod[k]->demodulator_priv);
+ demod[k] = NULL;
+ }
+ return -EINVAL;
}
+
EXPORT_SYMBOL(dib3000mc_attach);
static struct dvb_frontend_ops dib3000mc_ops = {
-
.info = {
- .name = "DiBcom 3000P/M-C DVB-T",
- .type = FE_OFDM,
- .frequency_min = 44250000,
- .frequency_max = 867250000,
- .frequency_stepsize = 62500,
+ .name = "DiBcom 3000MC/P",
+ .type = FE_OFDM,
+ .frequency_min = 44250000,
+ .frequency_max = 867250000,
+ .frequency_stepsize = 62500,
.caps = FE_CAN_INVERSION_AUTO |
- FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
- FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
- FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
- FE_CAN_TRANSMISSION_MODE_AUTO |
- FE_CAN_GUARD_INTERVAL_AUTO |
- FE_CAN_RECOVER |
- FE_CAN_HIERARCHY_AUTO,
+ FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
+ FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
+ FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
+ FE_CAN_TRANSMISSION_MODE_AUTO |
+ FE_CAN_GUARD_INTERVAL_AUTO |
+ FE_CAN_RECOVER |
+ FE_CAN_HIERARCHY_AUTO,
},
- .release = dib3000mc_release,
+ .release = dib3000mc_release,
- .init = dib3000mc_fe_init_nonmobile,
- .sleep = dib3000mc_sleep,
+ .init = dib3000mc_init,
+ .sleep = dib3000mc_sleep,
- .set_frontend = dib3000mc_set_frontend_and_tuner,
- .get_frontend = dib3000mc_get_frontend,
- .get_tune_settings = dib3000mc_fe_get_tune_settings,
+ .set_frontend = dib3000mc_set_frontend,
+ .get_tune_settings = dib3000mc_fe_get_tune_settings,
+ .get_frontend = dib3000mc_get_frontend,
- .read_status = dib3000mc_read_status,
- .read_ber = dib3000mc_read_ber,
+ .read_status = dib3000mc_read_status,
+ .read_ber = dib3000mc_read_ber,
.read_signal_strength = dib3000mc_read_signal_strength,
- .read_snr = dib3000mc_read_snr,
- .read_ucblocks = dib3000mc_read_unc_blocks,
+ .read_snr = dib3000mc_read_snr,
+ .read_ucblocks = dib3000mc_read_unc_blocks,
};
-MODULE_AUTHOR(DRIVER_AUTHOR);
-MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_AUTHOR("Patrick Boettcher <pboettcher@dibcom.fr>");
+MODULE_DESCRIPTION("Driver for the DiBcom 3000MC/P COFDM demodulator");
MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/frontends/dib3000mc.h b/drivers/media/dvb/frontends/dib3000mc.h
new file mode 100644
index 000000000000..fd0b2e755993
--- /dev/null
+++ b/drivers/media/dvb/frontends/dib3000mc.h
@@ -0,0 +1,58 @@
+/*
+ * Driver for DiBcom DiB3000MC/P-demodulator.
+ *
+ * Copyright (C) 2004-6 DiBcom (http://www.dibcom.fr/)
+ * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher\@desy.de)
+ *
+ * This code is partially based on the previous dib3000mc.c .
+ *
+ * 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.
+ */
+#ifndef DIB3000MC_H
+#define DIB3000MC_H
+
+#include "dibx000_common.h"
+
+struct dib3000mc_config {
+ struct dibx000_agc_config *agc;
+
+ u8 phase_noise_mode;
+ u8 impulse_noise_mode;
+
+ u8 pwm3_inversion;
+ u8 use_pwm3;
+ u16 pwm3_value;
+
+ u16 max_time;
+ u16 ln_adc_level;
+
+ u8 mobile_mode;
+
+ u8 output_mpeg2_in_188_bytes;
+};
+
+#define DEFAULT_DIB3000MC_I2C_ADDRESS 16
+#define DEFAULT_DIB3000P_I2C_ADDRESS 24
+
+#if defined(CONFIG_DVB_DIB3000MC) || defined(CONFIG_DVB_DIB3000MC_MODULE)
+extern int dib3000mc_attach(struct i2c_adapter *i2c_adap, int no_of_demods, u8 default_addr,
+ u8 do_i2c_enum, struct dib3000mc_config cfg[], struct dvb_frontend *demod[]);
+#else
+static inline struct dvb_frontend* dib3000mc_attach(const struct dib3000_config* config,
+ struct i2c_adapter* i2c, struct dib_fe_xfer_ops *xfer_ops)
+{
+ printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__);
+ return NULL;
+}
+#endif // CONFIG_DVB_DIB3000MC
+
+extern struct i2c_adapter * dib3000mc_get_tuner_i2c_master(struct dvb_frontend *demod, int gating);
+
+extern int dib3000mc_pid_control(struct dvb_frontend *fe, int index, int pid,int onoff);
+extern int dib3000mc_pid_parse(struct dvb_frontend *fe, int onoff);
+
+extern void dib3000mc_set_config(struct dvb_frontend *, struct dib3000mc_config *);
+
+#endif
diff --git a/drivers/media/dvb/frontends/dib3000mc_priv.h b/drivers/media/dvb/frontends/dib3000mc_priv.h
deleted file mode 100644
index 2930aac7591b..000000000000
--- a/drivers/media/dvb/frontends/dib3000mc_priv.h
+++ /dev/null
@@ -1,428 +0,0 @@
-/*
- * dib3000mc_priv.h
- *
- * Copyright (C) 2004 Patrick Boettcher (patrick.boettcher@desy.de)
- *
- * 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.
- *
- * for more information see dib3000mc.c .
- */
-
-#ifndef __DIB3000MC_PRIV_H__
-#define __DIB3000MC_PRIV_H__
-
-/*
- * Demodulator parameters
- * reg: 0 1 1 1 11 11 111
- * | | | | | |
- * | | | | | +-- alpha (000=0, 001=1, 010=2, 100=4)
- * | | | | +----- constellation (00=QPSK, 01=16QAM, 10=64QAM)
- * | | | +-------- guard (00=1/32, 01=1/16, 10=1/8, 11=1/4)
- * | | +----------- transmission mode (0=2k, 1=8k)
- * | |
- * | +-------------- restart autosearch for parameters
- * +---------------- restart the demodulator
- * reg: 181 1 111 1
- * | | |
- * | | +- FEC applies for HP or LP (0=LP, 1=HP)
- * | +---- FEC rate (001=1/2, 010=2/3, 011=3/4, 101=5/6, 111=7/8)
- * +------- hierarchy on (0=no, 1=yes)
- */
-
-/* demodulator tuning parameter and restart options */
-#define DIB3000MC_REG_DEMOD_PARM ( 0)
-#define DIB3000MC_DEMOD_PARM(a,c,g,t) ( \
- (0x7 & a) | \
- ((0x3 & c) << 3) | \
- ((0x3 & g) << 5) | \
- ((0x1 & t) << 7) )
-#define DIB3000MC_DEMOD_RST_AUTO_SRCH_ON (1 << 8)
-#define DIB3000MC_DEMOD_RST_AUTO_SRCH_OFF (0 << 8)
-#define DIB3000MC_DEMOD_RST_DEMOD_ON (1 << 9)
-#define DIB3000MC_DEMOD_RST_DEMOD_OFF (0 << 9)
-
-/* register for hierarchy parameters */
-#define DIB3000MC_REG_HRCH_PARM ( 181)
-#define DIB3000MC_HRCH_PARM(s,f,h) ( \
- (0x1 & s) | \
- ((0x7 & f) << 1) | \
- ((0x1 & h) << 4) )
-
-/* timeout ??? */
-#define DIB3000MC_REG_UNK_1 ( 1)
-#define DIB3000MC_UNK_1 ( 0x04)
-
-/* timeout ??? */
-#define DIB3000MC_REG_UNK_2 ( 2)
-#define DIB3000MC_UNK_2 ( 0x04)
-
-/* timeout ??? */
-#define DIB3000MC_REG_UNK_3 ( 3)
-#define DIB3000MC_UNK_3 (0x1000)
-
-#define DIB3000MC_REG_UNK_4 ( 4)
-#define DIB3000MC_UNK_4 (0x0814)
-
-/* timeout ??? */
-#define DIB3000MC_REG_SEQ_TPS ( 5)
-#define DIB3000MC_SEQ_TPS_DEFAULT ( 1)
-#define DIB3000MC_SEQ_TPS(s,t) ( \
- ((s & 0x0f) << 4) | \
- ((t & 0x01) << 8) )
-#define DIB3000MC_IS_TPS(v) ((v << 8) & 0x1)
-#define DIB3000MC_IS_AS(v) ((v >> 4) & 0xf)
-
-/* parameters for the bandwidth */
-#define DIB3000MC_REG_BW_TIMOUT_MSB ( 6)
-#define DIB3000MC_REG_BW_TIMOUT_LSB ( 7)
-
-static u16 dib3000mc_reg_bandwidth[] = { 6,7,8,9,10,11,16,17 };
-
-/*static u16 dib3000mc_bandwidth_5mhz[] =
- { 0x28, 0x9380, 0x87, 0x4100, 0x2a4, 0x4500, 0x1, 0xb0d0 };*/
-
-static u16 dib3000mc_bandwidth_6mhz[] =
- { 0x21, 0xd040, 0x70, 0xb62b, 0x233, 0x8ed5, 0x1, 0xb0d0 };
-
-static u16 dib3000mc_bandwidth_7mhz[] =
- { 0x1c, 0xfba5, 0x60, 0x9c25, 0x1e3, 0x0cb7, 0x1, 0xb0d0 };
-
-static u16 dib3000mc_bandwidth_8mhz[] =
- { 0x19, 0x5c30, 0x54, 0x88a0, 0x1a6, 0xab20, 0x1, 0xb0d0 };
-
-static u16 dib3000mc_reg_bandwidth_general[] = { 12,13,14,15 };
-static u16 dib3000mc_bandwidth_general[] = { 0x0000, 0x03e8, 0x0000, 0x03f2 };
-
-/* lock mask */
-#define DIB3000MC_REG_LOCK_MASK ( 15)
-#define DIB3000MC_ACTIVATE_LOCK_MASK (0x0800)
-
-/* reset the uncorrected packet count (??? do it 5 times) */
-#define DIB3000MC_REG_RST_UNC ( 18)
-#define DIB3000MC_RST_UNC_ON ( 1)
-#define DIB3000MC_RST_UNC_OFF ( 0)
-
-#define DIB3000MC_REG_UNK_19 ( 19)
-#define DIB3000MC_UNK_19 ( 0)
-
-/* DDS frequency value (IF position) and inversion bit */
-#define DIB3000MC_REG_INVERSION ( 21)
-#define DIB3000MC_REG_SET_DDS_FREQ_MSB ( 21)
-#define DIB3000MC_DDS_FREQ_MSB_INV_OFF (0x0164)
-#define DIB3000MC_DDS_FREQ_MSB_INV_ON (0x0364)
-
-#define DIB3000MC_REG_SET_DDS_FREQ_LSB ( 22)
-#define DIB3000MC_DDS_FREQ_LSB (0x463d)
-
-/* timing frequencies setting */
-#define DIB3000MC_REG_TIMING_FREQ_MSB ( 23)
-#define DIB3000MC_REG_TIMING_FREQ_LSB ( 24)
-#define DIB3000MC_CLOCK_REF (0x151fd1)
-
-//static u16 dib3000mc_reg_timing_freq[] = { 23,24 };
-
-//static u16 dib3000mc_timing_freq[][2] = {
-// { 0x69, 0x9f18 }, /* 5 MHz */
-// { 0x7e ,0xbee9 }, /* 6 MHz */
-// { 0x93 ,0xdebb }, /* 7 MHz */
-// { 0xa8 ,0xfe8c }, /* 8 MHz */
-//};
-
-/* timeout ??? */
-static u16 dib3000mc_reg_offset[] = { 26,33 };
-
-static u16 dib3000mc_offset[][2] = {
- { 26240, 5 }, /* default */
- { 30336, 6 }, /* 8K */
- { 38528, 8 }, /* 2K */
-};
-
-#define DIB3000MC_REG_ISI ( 29)
-#define DIB3000MC_ISI_DEFAULT (0x1073)
-#define DIB3000MC_ISI_ACTIVATE (0x0000)
-#define DIB3000MC_ISI_INHIBIT (0x0200)
-
-/* impulse noise control */
-static u16 dib3000mc_reg_imp_noise_ctl[] = { 34,35 };
-
-static u16 dib3000mc_imp_noise_ctl[][2] = {
- { 0x1294, 0x1ff8 }, /* mode 0 */
- { 0x1294, 0x1ff8 }, /* mode 1 */
- { 0x1294, 0x1ff8 }, /* mode 2 */
- { 0x1294, 0x1ff8 }, /* mode 3 */
- { 0x1294, 0x1ff8 }, /* mode 4 */
-};
-
-/* AGC registers */
-static u16 dib3000mc_reg_agc[] = {
- 36,37,38,39,42,43,44,45,46,47,48,49
-};
-
-static u16 dib3000mc_agc_tuner[][12] = {
- { 0x0051, 0x301d, 0x0000, 0x1cc7, 0xcf5c, 0x6666,
- 0xbae1, 0xa148, 0x3b5e, 0x3c1c, 0x001a, 0x2019
- }, /* TUNER_PANASONIC_ENV77H04D5, */
-
- { 0x0051, 0x301d, 0x0000, 0x1cc7, 0xdc29, 0x570a,
- 0xbae1, 0x8ccd, 0x3b6d, 0x551d, 0x000a, 0x951e
- }, /* TUNER_PANASONIC_ENV57H13D5, TUNER_PANASONIC_ENV57H12D5 */
-
- { 0x0051, 0x301d, 0x0000, 0x1cc7, 0xffff, 0xffff,
- 0xffff, 0x0000, 0xfdfd, 0x4040, 0x00fd, 0x4040
- }, /* TUNER_SAMSUNG_DTOS333IH102, TUNER_RFAGCIN_UNKNOWN */
-
- { 0x0196, 0x301d, 0x0000, 0x1cc7, 0xbd71, 0x5c29,
- 0xb5c3, 0x6148, 0x6569, 0x5127, 0x0033, 0x3537
- }, /* TUNER_PROVIDER_X */
- /* TODO TUNER_PANASONIC_ENV57H10D8, TUNER_PANASONIC_ENV57H11D8 */
-};
-
-/* AGC loop bandwidth */
-static u16 dib3000mc_reg_agc_bandwidth[] = { 40,41 };
-static u16 dib3000mc_agc_bandwidth[] = { 0x119,0x330 };
-
-static u16 dib3000mc_reg_agc_bandwidth_general[] = { 50,51,52,53,54 };
-static u16 dib3000mc_agc_bandwidth_general[] =
- { 0x8000, 0x91ca, 0x01ba, 0x0087, 0x0087 };
-
-#define DIB3000MC_REG_IMP_NOISE_55 ( 55)
-#define DIB3000MC_IMP_NEW_ALGO(w) (w | (1<<10))
-
-/* Impulse noise params */
-static u16 dib3000mc_reg_impulse_noise[] = { 55,56,57 };
-static u16 dib3000mc_impluse_noise[][3] = {
- { 0x489, 0x89, 0x72 }, /* 5 MHz */
- { 0x4a5, 0xa5, 0x89 }, /* 6 MHz */
- { 0x4c0, 0xc0, 0xa0 }, /* 7 MHz */
- { 0x4db, 0xdb, 0xb7 }, /* 8 Mhz */
-};
-
-static u16 dib3000mc_reg_fft[] = {
- 58,59,60,61,62,63,64,65,66,67,68,69,
- 70,71,72,73,74,75,76,77,78,79,80,81,
- 82,83,84,85,86
-};
-
-static u16 dib3000mc_fft_modes[][29] = {
- { 0x38, 0x6d9, 0x3f28, 0x7a7, 0x3a74, 0x196, 0x32a, 0x48c,
- 0x3ffe, 0x7f3, 0x2d94, 0x76, 0x53d,
- 0x3ff8, 0x7e3, 0x3320, 0x76, 0x5b3,
- 0x3feb, 0x7d2, 0x365e, 0x76, 0x48c,
- 0x3ffe, 0x5b3, 0x3feb, 0x76, 0x0, 0xd
- }, /* fft mode 0 */
- { 0x3b, 0x6d9, 0x3f28, 0x7a7, 0x3a74, 0x196, 0x32a, 0x48c,
- 0x3ffe, 0x7f3, 0x2d94, 0x76, 0x53d,
- 0x3ff8, 0x7e3, 0x3320, 0x76, 0x5b3,
- 0x3feb, 0x7d2, 0x365e, 0x76, 0x48c,
- 0x3ffe, 0x5b3, 0x3feb, 0x0, 0x8200, 0xd
- }, /* fft mode 1 */
-};
-
-#define DIB3000MC_REG_UNK_88 ( 88)
-#define DIB3000MC_UNK_88 (0x0410)
-
-static u16 dib3000mc_reg_bw[] = { 93,94,95,96,97,98 };
-static u16 dib3000mc_bw[][6] = {
- { 0,0,0,0,0,0 }, /* 5 MHz */
- { 0,0,0,0,0,0 }, /* 6 MHz */
- { 0,0,0,0,0,0 }, /* 7 MHz */
- { 0x20, 0x21, 0x20, 0x23, 0x20, 0x27 }, /* 8 MHz */
-};
-
-
-/* phase noise control */
-#define DIB3000MC_REG_UNK_99 ( 99)
-#define DIB3000MC_UNK_99 (0x0220)
-
-#define DIB3000MC_REG_SCAN_BOOST ( 100)
-#define DIB3000MC_SCAN_BOOST_ON ((11 << 6) + 6)
-#define DIB3000MC_SCAN_BOOST_OFF ((16 << 6) + 9)
-
-/* timeout ??? */
-#define DIB3000MC_REG_UNK_110 ( 110)
-#define DIB3000MC_UNK_110 ( 3277)
-
-#define DIB3000MC_REG_UNK_111 ( 111)
-#define DIB3000MC_UNK_111_PH_N_MODE_0 ( 0)
-#define DIB3000MC_UNK_111_PH_N_MODE_1 (1 << 1)
-
-/* superious rm config */
-#define DIB3000MC_REG_UNK_120 ( 120)
-#define DIB3000MC_UNK_120 ( 8207)
-
-#define DIB3000MC_REG_UNK_133 ( 133)
-#define DIB3000MC_UNK_133 ( 15564)
-
-#define DIB3000MC_REG_UNK_134 ( 134)
-#define DIB3000MC_UNK_134 ( 0)
-
-/* adapter config for constellation */
-static u16 dib3000mc_reg_adp_cfg[] = { 129, 130, 131, 132 };
-
-static u16 dib3000mc_adp_cfg[][4] = {
- { 0x99a, 0x7fae, 0x333, 0x7ff0 }, /* QPSK */
- { 0x23d, 0x7fdf, 0x0a4, 0x7ff0 }, /* 16-QAM */
- { 0x148, 0x7ff0, 0x0a4, 0x7ff8 }, /* 64-QAM */
-};
-
-static u16 dib3000mc_reg_mobile_mode[] = { 139, 140, 141, 175, 1032 };
-
-static u16 dib3000mc_mobile_mode[][5] = {
- { 0x01, 0x0, 0x0, 0x00, 0x12c }, /* fixed */
- { 0x01, 0x0, 0x0, 0x00, 0x12c }, /* portable */
- { 0x00, 0x0, 0x0, 0x02, 0x000 }, /* mobile */
- { 0x00, 0x0, 0x0, 0x02, 0x000 }, /* auto */
-};
-
-#define DIB3000MC_REG_DIVERSITY1 ( 177)
-#define DIB3000MC_DIVERSITY1_DEFAULT ( 1)
-
-#define DIB3000MC_REG_DIVERSITY2 ( 178)
-#define DIB3000MC_DIVERSITY2_DEFAULT ( 1)
-
-#define DIB3000MC_REG_DIVERSITY3 ( 180)
-#define DIB3000MC_DIVERSITY3_IN_OFF (0xfff0)
-#define DIB3000MC_DIVERSITY3_IN_ON (0xfff6)
-
-#define DIB3000MC_REG_FEC_CFG ( 195)
-#define DIB3000MC_FEC_CFG ( 0x10)
-
-/*
- * reg 206, output mode
- * 1111 1111
- * |||| ||||
- * |||| |||+- unk
- * |||| ||+-- unk
- * |||| |+--- unk (on by default)
- * |||| +---- fifo_ctrl (1 = inhibit (flushed), 0 = active (unflushed))
- * |||+------ pid_parse (1 = enabled, 0 = disabled)
- * ||+------- outp_188 (1 = TS packet size 188, 0 = packet size 204)
- * |+-------- unk
- * +--------- unk
- */
-
-#define DIB3000MC_REG_SMO_MODE ( 206)
-#define DIB3000MC_SMO_MODE_DEFAULT (1 << 2)
-#define DIB3000MC_SMO_MODE_FIFO_FLUSH (1 << 3)
-#define DIB3000MC_SMO_MODE_FIFO_UNFLUSH (0xfff7)
-#define DIB3000MC_SMO_MODE_PID_PARSE (1 << 4)
-#define DIB3000MC_SMO_MODE_NO_PID_PARSE (0xffef)
-#define DIB3000MC_SMO_MODE_188 (1 << 5)
-#define DIB3000MC_SMO_MODE_SLAVE (DIB3000MC_SMO_MODE_DEFAULT | \
- DIB3000MC_SMO_MODE_188 | DIB3000MC_SMO_MODE_PID_PARSE | (1<<1))
-
-#define DIB3000MC_REG_FIFO_THRESHOLD ( 207)
-#define DIB3000MC_FIFO_THRESHOLD_DEFAULT ( 1792)
-#define DIB3000MC_FIFO_THRESHOLD_SLAVE ( 512)
-/*
- * pidfilter
- * it is not a hardware pidfilter but a filter which drops all pids
- * except the ones set. When connected to USB1.1 bandwidth this is important.
- * DiB3000P/M-C can filter up to 32 PIDs
- */
-#define DIB3000MC_REG_FIRST_PID ( 212)
-#define DIB3000MC_NUM_PIDS ( 32)
-
-#define DIB3000MC_REG_OUTMODE ( 244)
-#define DIB3000MC_OM_PARALLEL_GATED_CLK ( 0)
-#define DIB3000MC_OM_PAR_CONT_CLK (1 << 11)
-#define DIB3000MC_OM_SERIAL (2 << 11)
-#define DIB3000MC_OM_DIVOUT_ON (4 << 11)
-#define DIB3000MC_OM_SLAVE (DIB3000MC_OM_DIVOUT_ON | DIB3000MC_OM_PAR_CONT_CLK)
-
-#define DIB3000MC_REG_RF_POWER ( 392)
-
-#define DIB3000MC_REG_FFT_POSITION ( 407)
-
-#define DIB3000MC_REG_DDS_FREQ_MSB ( 414)
-#define DIB3000MC_REG_DDS_FREQ_LSB ( 415)
-
-#define DIB3000MC_REG_TIMING_OFFS_MSB ( 416)
-#define DIB3000MC_REG_TIMING_OFFS_LSB ( 417)
-
-#define DIB3000MC_REG_TUNING_PARM ( 458)
-#define DIB3000MC_TP_QAM(v) ((v >> 13) & 0x03)
-#define DIB3000MC_TP_HRCH(v) ((v >> 12) & 0x01)
-#define DIB3000MC_TP_ALPHA(v) ((v >> 9) & 0x07)
-#define DIB3000MC_TP_FFT(v) ((v >> 8) & 0x01)
-#define DIB3000MC_TP_FEC_CR_HP(v) ((v >> 5) & 0x07)
-#define DIB3000MC_TP_FEC_CR_LP(v) ((v >> 2) & 0x07)
-#define DIB3000MC_TP_GUARD(v) (v & 0x03)
-
-#define DIB3000MC_REG_SIGNAL_NOISE_MSB ( 483)
-#define DIB3000MC_REG_SIGNAL_NOISE_LSB ( 484)
-
-#define DIB3000MC_REG_MER ( 485)
-
-#define DIB3000MC_REG_BER_MSB ( 500)
-#define DIB3000MC_REG_BER_LSB ( 501)
-
-#define DIB3000MC_REG_PACKET_ERRORS ( 503)
-
-#define DIB3000MC_REG_PACKET_ERROR_COUNT ( 506)
-
-#define DIB3000MC_REG_LOCK_507 ( 507)
-#define DIB3000MC_LOCK_507 (0x0002) // ? name correct ?
-
-#define DIB3000MC_REG_LOCKING ( 509)
-#define DIB3000MC_AGC_LOCK(v) (v & 0x8000)
-#define DIB3000MC_CARRIER_LOCK(v) (v & 0x2000)
-#define DIB3000MC_MPEG_SYNC_LOCK(v) (v & 0x0080)
-#define DIB3000MC_MPEG_DATA_LOCK(v) (v & 0x0040)
-#define DIB3000MC_TPS_LOCK(v) (v & 0x0004)
-
-#define DIB3000MC_REG_AS_IRQ ( 511)
-#define DIB3000MC_AS_IRQ_SUCCESS (1 << 1)
-#define DIB3000MC_AS_IRQ_FAIL ( 1)
-
-#define DIB3000MC_REG_TUNER ( 769)
-
-#define DIB3000MC_REG_RST_I2C_ADDR ( 1024)
-#define DIB3000MC_DEMOD_ADDR_ON ( 1)
-#define DIB3000MC_DEMOD_ADDR(a) ((a << 4) & 0x03F0)
-
-#define DIB3000MC_REG_RESTART ( 1027)
-#define DIB3000MC_RESTART_OFF (0x0000)
-#define DIB3000MC_RESTART_AGC (0x0800)
-#define DIB3000MC_RESTART_CONFIG (0x8000)
-
-#define DIB3000MC_REG_RESTART_VIT ( 1028)
-#define DIB3000MC_RESTART_VIT_OFF ( 0)
-#define DIB3000MC_RESTART_VIT_ON ( 1)
-
-#define DIB3000MC_REG_CLK_CFG_1 ( 1031)
-#define DIB3000MC_CLK_CFG_1_POWER_UP ( 0)
-#define DIB3000MC_CLK_CFG_1_POWER_DOWN (0xffff)
-
-#define DIB3000MC_REG_CLK_CFG_2 ( 1032)
-#define DIB3000MC_CLK_CFG_2_PUP_FIXED (0x012c)
-#define DIB3000MC_CLK_CFG_2_PUP_PORT (0x0104)
-#define DIB3000MC_CLK_CFG_2_PUP_MOBILE (0x0000)
-#define DIB3000MC_CLK_CFG_2_POWER_DOWN (0xffff)
-
-#define DIB3000MC_REG_CLK_CFG_3 ( 1033)
-#define DIB3000MC_CLK_CFG_3_POWER_UP ( 0)
-#define DIB3000MC_CLK_CFG_3_POWER_DOWN (0xfff5)
-
-#define DIB3000MC_REG_CLK_CFG_7 ( 1037)
-#define DIB3000MC_CLK_CFG_7_INIT ( 12592)
-#define DIB3000MC_CLK_CFG_7_POWER_UP (~0x0003)
-#define DIB3000MC_CLK_CFG_7_PWR_DOWN (0x0003)
-#define DIB3000MC_CLK_CFG_7_DIV_IN_OFF (1 << 8)
-
-/* was commented out ??? */
-#define DIB3000MC_REG_CLK_CFG_8 ( 1038)
-#define DIB3000MC_CLK_CFG_8_POWER_UP (0x160c)
-
-#define DIB3000MC_REG_CLK_CFG_9 ( 1039)
-#define DIB3000MC_CLK_CFG_9_POWER_UP ( 0)
-
-/* also clock ??? */
-#define DIB3000MC_REG_ELEC_OUT ( 1040)
-#define DIB3000MC_ELEC_OUT_HIGH_Z ( 0)
-#define DIB3000MC_ELEC_OUT_DIV_OUT_ON ( 1)
-#define DIB3000MC_ELEC_OUT_SLAVE ( 3)
-
-#endif
diff --git a/drivers/media/dvb/frontends/dibx000_common.c b/drivers/media/dvb/frontends/dibx000_common.c
new file mode 100644
index 000000000000..a18c8f45a2ee
--- /dev/null
+++ b/drivers/media/dvb/frontends/dibx000_common.c
@@ -0,0 +1,152 @@
+#include <linux/i2c.h>
+
+#include "dibx000_common.h"
+
+static int debug;
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "turn on debugging (default: 0)");
+
+#define dprintk(args...) do { if (debug) { printk(KERN_DEBUG "DiBX000: "); printk(args); } } while (0)
+
+static int dibx000_write_word(struct dibx000_i2c_master *mst, u16 reg, u16 val)
+{
+ u8 b[4] = {
+ (reg >> 8) & 0xff, reg & 0xff,
+ (val >> 8) & 0xff, val & 0xff,
+ };
+ struct i2c_msg msg = {
+ .addr = mst->i2c_addr, .flags = 0, .buf = b, .len = 4
+ };
+ return i2c_transfer(mst->i2c_adap, &msg, 1) != 1 ? -EREMOTEIO : 0;
+}
+
+
+static int dibx000_i2c_select_interface(struct dibx000_i2c_master *mst, enum dibx000_i2c_interface intf)
+{
+ if (mst->device_rev > DIB3000MC && mst->selected_interface != intf) {
+ dprintk("selecting interface: %d\n",intf);
+ mst->selected_interface = intf;
+ return dibx000_write_word(mst, mst->base_reg + 4, intf);
+ }
+ return 0;
+}
+
+static int dibx000_i2c_gate_ctrl(struct dibx000_i2c_master *mst, u8 tx[4], u8 addr, int onoff)
+{
+ u16 val;
+
+
+ if (onoff)
+ val = addr << 8; // bit 7 = use master or not, if 0, the gate is open
+ else
+ val = 1 << 7;
+
+ if (mst->device_rev > DIB7000)
+ val <<= 1;
+
+ tx[0] = (((mst->base_reg + 1) >> 8) & 0xff);
+ tx[1] = ( (mst->base_reg + 1) & 0xff);
+ tx[2] = val >> 8;
+ tx[3] = val & 0xff;
+
+ return 0;
+}
+
+static u32 dibx000_i2c_func(struct i2c_adapter *adapter)
+{
+ return I2C_FUNC_I2C;
+}
+
+static int dibx000_i2c_gated_tuner_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg msg[], int num)
+{
+ struct dibx000_i2c_master *mst = i2c_get_adapdata(i2c_adap);
+ struct i2c_msg m[2 + num];
+ u8 tx_open[4], tx_close[4];
+
+ memset(m,0, sizeof(struct i2c_msg) * (2 + num));
+
+ dibx000_i2c_select_interface(mst, DIBX000_I2C_INTERFACE_TUNER);
+
+ dibx000_i2c_gate_ctrl(mst, tx_open, msg[0].addr, 1);
+ m[0].addr = mst->i2c_addr;
+ m[0].buf = tx_open;
+ m[0].len = 4;
+
+ memcpy(&m[1], msg, sizeof(struct i2c_msg) * num);
+
+ dibx000_i2c_gate_ctrl(mst, tx_close, 0, 0);
+ m[num+1].addr = mst->i2c_addr;
+ m[num+1].buf = tx_close;
+ m[num+1].len = 4;
+
+ return i2c_transfer(mst->i2c_adap, m, 2+num) == 2 + num ? num : -EIO;
+}
+
+static struct i2c_algorithm dibx000_i2c_gated_tuner_algo = {
+ .master_xfer = dibx000_i2c_gated_tuner_xfer,
+ .functionality = dibx000_i2c_func,
+};
+
+struct i2c_adapter * dibx000_get_i2c_adapter(struct dibx000_i2c_master *mst, enum dibx000_i2c_interface intf, int gating)
+{
+ struct i2c_adapter *i2c = NULL;
+
+ switch (intf) {
+ case DIBX000_I2C_INTERFACE_TUNER:
+ if (gating)
+ i2c = &mst->gated_tuner_i2c_adap;
+ break;
+ default:
+ printk(KERN_ERR "DiBX000: incorrect I2C interface selected\n");
+ break;
+ }
+
+ return i2c;
+}
+EXPORT_SYMBOL(dibx000_get_i2c_adapter);
+
+static int i2c_adapter_init(struct i2c_adapter *i2c_adap, struct i2c_algorithm *algo, const char name[I2C_NAME_SIZE], struct dibx000_i2c_master *mst)
+{
+ strncpy(i2c_adap->name, name, I2C_NAME_SIZE);
+ i2c_adap->class = I2C_CLASS_TV_DIGITAL,
+ i2c_adap->algo = algo;
+ i2c_adap->algo_data = NULL;
+ i2c_set_adapdata(i2c_adap, mst);
+ if (i2c_add_adapter(i2c_adap) < 0)
+ return -ENODEV;
+ return 0;
+}
+
+int dibx000_init_i2c_master(struct dibx000_i2c_master *mst, u16 device_rev, struct i2c_adapter *i2c_adap, u8 i2c_addr)
+{
+ u8 tx[4];
+ struct i2c_msg m = { .addr = i2c_addr >> 1, .buf = tx, .len = 4 };
+
+ mst->device_rev = device_rev;
+ mst->i2c_adap = i2c_adap;
+ mst->i2c_addr = i2c_addr >> 1;
+
+ if (device_rev == DIB7000P)
+ mst->base_reg = 1024;
+ else
+ mst->base_reg = 768;
+
+ if (i2c_adapter_init(&mst->gated_tuner_i2c_adap, &dibx000_i2c_gated_tuner_algo, "DiBX000 tuner I2C bus", mst) != 0)
+ printk(KERN_ERR "DiBX000: could not initialize the tuner i2c_adapter\n");
+
+ /* initialize the i2c-master by closing the gate */
+ dibx000_i2c_gate_ctrl(mst, tx, 0, 0);
+
+ return i2c_transfer(i2c_adap, &m, 1) == 1;
+}
+EXPORT_SYMBOL(dibx000_init_i2c_master);
+
+void dibx000_exit_i2c_master(struct dibx000_i2c_master *mst)
+{
+ i2c_del_adapter(&mst->gated_tuner_i2c_adap);
+}
+EXPORT_SYMBOL(dibx000_exit_i2c_master);
+
+MODULE_AUTHOR("Patrick Boettcher <pboettcher@dibcom.fr>");
+MODULE_DESCRIPTION("Common function the DiBcom demodulator family");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/frontends/dibx000_common.h b/drivers/media/dvb/frontends/dibx000_common.h
new file mode 100644
index 000000000000..bb0c65f8aee8
--- /dev/null
+++ b/drivers/media/dvb/frontends/dibx000_common.h
@@ -0,0 +1,166 @@
+#ifndef DIBX000_COMMON_H
+#define DIBX000_COMMON_H
+
+enum dibx000_i2c_interface {
+ DIBX000_I2C_INTERFACE_TUNER = 0,
+ DIBX000_I2C_INTERFACE_GPIO_1_2 = 1,
+ DIBX000_I2C_INTERFACE_GPIO_3_4 = 2
+};
+
+struct dibx000_i2c_master {
+#define DIB3000MC 1
+#define DIB7000 2
+#define DIB7000P 11
+#define DIB7000MC 12
+ u16 device_rev;
+
+ enum dibx000_i2c_interface selected_interface;
+
+// struct i2c_adapter tuner_i2c_adap;
+ struct i2c_adapter gated_tuner_i2c_adap;
+
+ struct i2c_adapter *i2c_adap;
+ u8 i2c_addr;
+
+ u16 base_reg;
+};
+
+extern int dibx000_init_i2c_master(struct dibx000_i2c_master *mst, u16 device_rev, struct i2c_adapter *i2c_adap, u8 i2c_addr);
+extern struct i2c_adapter * dibx000_get_i2c_adapter(struct dibx000_i2c_master *mst, enum dibx000_i2c_interface intf, int gating);
+extern void dibx000_exit_i2c_master(struct dibx000_i2c_master *mst);
+
+#define BAND_LBAND 0x01
+#define BAND_UHF 0x02
+#define BAND_VHF 0x04
+
+struct dibx000_agc_config {
+ /* defines the capabilities of this AGC-setting - using the BAND_-defines*/
+ u8 band_caps;
+
+ u16 setup;
+
+ u16 inv_gain;
+ u16 time_stabiliz;
+
+ u8 alpha_level;
+ u16 thlock;
+
+ u8 wbd_inv;
+ u16 wbd_ref;
+ u8 wbd_sel;
+ u8 wbd_alpha;
+
+ u16 agc1_max;
+ u16 agc1_min;
+ u16 agc2_max;
+ u16 agc2_min;
+
+ u8 agc1_pt1;
+ u8 agc1_pt2;
+ u8 agc1_pt3;
+
+ u8 agc1_slope1;
+ u8 agc1_slope2;
+
+ u8 agc2_pt1;
+ u8 agc2_pt2;
+
+ u8 agc2_slope1;
+ u8 agc2_slope2;
+
+ u8 alpha_mant;
+ u8 alpha_exp;
+
+ u8 beta_mant;
+ u8 beta_exp;
+
+ u8 perform_agc_softsplit;
+
+ struct {
+ u16 min;
+ u16 max;
+ u16 min_thres;
+ u16 max_thres;
+ } split;
+};
+
+struct dibx000_bandwidth_config {
+ u32 internal;
+ u32 sampling;
+
+ u8 pll_prediv;
+ u8 pll_ratio;
+ u8 pll_range;
+ u8 pll_reset;
+ u8 pll_bypass;
+
+ u8 enable_refdiv;
+ u8 bypclk_div;
+ u8 IO_CLK_en_core;
+ u8 ADClkSrc;
+ u8 modulo;
+
+ u16 sad_cfg;
+
+ u32 ifreq;
+ u32 timf;
+};
+
+enum dibx000_adc_states {
+ DIBX000_SLOW_ADC_ON = 0,
+ DIBX000_SLOW_ADC_OFF,
+ DIBX000_ADC_ON,
+ DIBX000_ADC_OFF,
+ DIBX000_VBG_ENABLE,
+ DIBX000_VBG_DISABLE,
+};
+
+#define BW_INDEX_TO_KHZ(v) ( (v) == BANDWIDTH_8_MHZ ? 8000 : \
+ (v) == BANDWIDTH_7_MHZ ? 7000 : \
+ (v) == BANDWIDTH_6_MHZ ? 6000 : 8000 )
+
+/* Chip output mode. */
+#define OUTMODE_HIGH_Z 0
+#define OUTMODE_MPEG2_PAR_GATED_CLK 1
+#define OUTMODE_MPEG2_PAR_CONT_CLK 2
+#define OUTMODE_MPEG2_SERIAL 7
+#define OUTMODE_DIVERSITY 4
+#define OUTMODE_MPEG2_FIFO 5
+
+/* I hope I can get rid of the following kludge in the near future */
+struct dibx000_ofdm_channel {
+ u8 Bw;
+ s16 nfft;
+ s16 guard;
+ s16 nqam;
+ s16 vit_hrch;
+ s16 vit_select_hp;
+ s16 vit_alpha;
+ s16 vit_code_rate_hp;
+ s16 vit_code_rate_lp;
+};
+
+#define FEP2DIB(fep,ch) \
+ (ch)->Bw = (fep)->u.ofdm.bandwidth; \
+ (ch)->nfft = (fep)->u.ofdm.transmission_mode == TRANSMISSION_MODE_AUTO ? -1 : (fep)->u.ofdm.transmission_mode; \
+ (ch)->guard = (fep)->u.ofdm.guard_interval == GUARD_INTERVAL_AUTO ? -1 : (fep)->u.ofdm.guard_interval; \
+ (ch)->nqam = (fep)->u.ofdm.constellation == QAM_AUTO ? -1 : (fep)->u.ofdm.constellation == QAM_64 ? 2 : (fep)->u.ofdm.constellation; \
+ (ch)->vit_hrch = 0; /* linux-dvb is not prepared for HIERARCHICAL TRANSMISSION */ \
+ (ch)->vit_select_hp = 1; \
+ (ch)->vit_alpha = 1; \
+ (ch)->vit_code_rate_hp = (fep)->u.ofdm.code_rate_HP == FEC_AUTO ? -1 : (fep)->u.ofdm.code_rate_HP; \
+ (ch)->vit_code_rate_lp = (fep)->u.ofdm.code_rate_LP == FEC_AUTO ? -1 : (fep)->u.ofdm.code_rate_LP;
+
+#define INIT_OFDM_CHANNEL(ch) do {\
+ (ch)->Bw = 0; \
+ (ch)->nfft = -1; \
+ (ch)->guard = -1; \
+ (ch)->nqam = -1; \
+ (ch)->vit_hrch = -1; \
+ (ch)->vit_select_hp = -1; \
+ (ch)->vit_alpha = -1; \
+ (ch)->vit_code_rate_hp = -1; \
+ (ch)->vit_code_rate_lp = -1; \
+} while (0)
+
+#endif
diff --git a/drivers/media/dvb/frontends/dvb-pll.c b/drivers/media/dvb/frontends/dvb-pll.c
index 2be33f27c69f..b7e7108ee5b3 100644
--- a/drivers/media/dvb/frontends/dvb-pll.c
+++ b/drivers/media/dvb/frontends/dvb-pll.c
@@ -493,6 +493,9 @@ static int dvb_pll_sleep(struct dvb_frontend *fe)
int i;
int result;
+ if (priv->i2c == NULL)
+ return -EINVAL;
+
for (i = 0; i < priv->pll_desc->count; i++) {
if (priv->pll_desc->entries[i].limit == 0)
break;
@@ -611,7 +614,7 @@ static struct dvb_tuner_ops dvb_pll_tuner_ops = {
.get_bandwidth = dvb_pll_get_bandwidth,
};
-int dvb_pll_attach(struct dvb_frontend *fe, int pll_addr, struct i2c_adapter *i2c, struct dvb_pll_desc *desc)
+struct dvb_frontend *dvb_pll_attach(struct dvb_frontend *fe, int pll_addr, struct i2c_adapter *i2c, struct dvb_pll_desc *desc)
{
u8 b1 [] = { 0 };
struct i2c_msg msg = { .addr = pll_addr, .flags = I2C_M_RD, .buf = b1, .len = 1 };
@@ -624,14 +627,14 @@ int dvb_pll_attach(struct dvb_frontend *fe, int pll_addr, struct i2c_adapter *i2
ret = i2c_transfer (i2c, &msg, 1);
if (ret != 1)
- return -1;
+ return NULL;
if (fe->ops.i2c_gate_ctrl)
fe->ops.i2c_gate_ctrl(fe, 0);
}
priv = kzalloc(sizeof(struct dvb_pll_priv), GFP_KERNEL);
if (priv == NULL)
- return -ENOMEM;
+ return NULL;
priv->pll_i2c_address = pll_addr;
priv->i2c = i2c;
@@ -643,7 +646,7 @@ int dvb_pll_attach(struct dvb_frontend *fe, int pll_addr, struct i2c_adapter *i2
fe->ops.tuner_ops.info.frequency_min = desc->max;
fe->tuner_priv = priv;
- return 0;
+ return fe;
}
EXPORT_SYMBOL(dvb_pll_attach);
diff --git a/drivers/media/dvb/frontends/dvb-pll.h b/drivers/media/dvb/frontends/dvb-pll.h
index 66361cd18807..ed5ac5a361ae 100644
--- a/drivers/media/dvb/frontends/dvb-pll.h
+++ b/drivers/media/dvb/frontends/dvb-pll.h
@@ -57,8 +57,8 @@ extern int dvb_pll_configure(struct dvb_pll_desc *desc, u8 *buf,
* @param pll_addr i2c address of the PLL (if used).
* @param i2c i2c adapter to use (set to NULL if not used).
* @param desc dvb_pll_desc to use.
- * @return 0 on success, nonzero on failure.
+ * @return Frontend pointer on success, NULL on failure
*/
-extern int dvb_pll_attach(struct dvb_frontend *fe, int pll_addr, struct i2c_adapter *i2c, struct dvb_pll_desc *desc);
+extern struct dvb_frontend *dvb_pll_attach(struct dvb_frontend *fe, int pll_addr, struct i2c_adapter *i2c, struct dvb_pll_desc *desc);
#endif
diff --git a/drivers/media/dvb/frontends/isl6421.c b/drivers/media/dvb/frontends/isl6421.c
index 58c34db31071..ef319369ec26 100644
--- a/drivers/media/dvb/frontends/isl6421.c
+++ b/drivers/media/dvb/frontends/isl6421.c
@@ -42,12 +42,11 @@ struct isl6421 {
u8 override_and;
struct i2c_adapter *i2c;
u8 i2c_addr;
- void (*release_chain)(struct dvb_frontend* fe);
};
static int isl6421_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage)
{
- struct isl6421 *isl6421 = (struct isl6421 *) fe->misc_priv;
+ struct isl6421 *isl6421 = (struct isl6421 *) fe->sec_priv;
struct i2c_msg msg = { .addr = isl6421->i2c_addr, .flags = 0,
.buf = &isl6421->config,
.len = sizeof(isl6421->config) };
@@ -75,7 +74,7 @@ static int isl6421_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage
static int isl6421_enable_high_lnb_voltage(struct dvb_frontend *fe, long arg)
{
- struct isl6421 *isl6421 = (struct isl6421 *) fe->misc_priv;
+ struct isl6421 *isl6421 = (struct isl6421 *) fe->sec_priv;
struct i2c_msg msg = { .addr = isl6421->i2c_addr, .flags = 0,
.buf = &isl6421->config,
.len = sizeof(isl6421->config) };
@@ -93,31 +92,26 @@ static int isl6421_enable_high_lnb_voltage(struct dvb_frontend *fe, long arg)
static void isl6421_release(struct dvb_frontend *fe)
{
- struct isl6421 *isl6421 = (struct isl6421 *) fe->misc_priv;
-
/* power off */
isl6421_set_voltage(fe, SEC_VOLTAGE_OFF);
- /* free data & call next release routine */
- fe->ops.release = isl6421->release_chain;
- kfree(fe->misc_priv);
- fe->misc_priv = NULL;
- if (fe->ops.release)
- fe->ops.release(fe);
+ /* free */
+ kfree(fe->sec_priv);
+ fe->sec_priv = NULL;
}
-int isl6421_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, u8 i2c_addr,
+struct dvb_frontend *isl6421_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, u8 i2c_addr,
u8 override_set, u8 override_clear)
{
struct isl6421 *isl6421 = kmalloc(sizeof(struct isl6421), GFP_KERNEL);
if (!isl6421)
- return -ENOMEM;
+ return NULL;
/* default configuration */
isl6421->config = ISL6421_ISEL1;
isl6421->i2c = i2c;
isl6421->i2c_addr = i2c_addr;
- fe->misc_priv = isl6421;
+ fe->sec_priv = isl6421;
/* bits which should be forced to '1' */
isl6421->override_or = override_set;
@@ -128,19 +122,17 @@ int isl6421_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, u8 i2c_addr
/* detect if it is present or not */
if (isl6421_set_voltage(fe, SEC_VOLTAGE_OFF)) {
kfree(isl6421);
- fe->misc_priv = NULL;
- return -EIO;
+ return NULL;
}
/* install release callback */
- isl6421->release_chain = fe->ops.release;
- fe->ops.release = isl6421_release;
+ fe->ops.release_sec = isl6421_release;
/* override frontend ops */
fe->ops.set_voltage = isl6421_set_voltage;
fe->ops.enable_high_lnb_voltage = isl6421_enable_high_lnb_voltage;
- return 0;
+ return fe;
}
EXPORT_SYMBOL(isl6421_attach);
diff --git a/drivers/media/dvb/frontends/isl6421.h b/drivers/media/dvb/frontends/isl6421.h
index 675f80a19b99..1916e3eb2df3 100644
--- a/drivers/media/dvb/frontends/isl6421.h
+++ b/drivers/media/dvb/frontends/isl6421.h
@@ -39,8 +39,17 @@
#define ISL6421_ISEL1 0x20
#define ISL6421_DCL 0x40
+#if defined(CONFIG_DVB_ISL6421) || defined(CONFIG_DVB_ISL6421_MODULE)
/* override_set and override_clear control which system register bits (above) to always set & clear */
-extern int isl6421_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, u8 i2c_addr,
+extern struct dvb_frontend *isl6421_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, u8 i2c_addr,
u8 override_set, u8 override_clear);
+#else
+static inline struct dvb_frontend *isl6421_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, u8 i2c_addr,
+ u8 override_set, u8 override_clear)
+{
+ printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__);
+ return NULL;
+}
+#endif // CONFIG_DVB_ISL6421
#endif
diff --git a/drivers/media/dvb/frontends/l64781.h b/drivers/media/dvb/frontends/l64781.h
index 83b8bc210274..21ba4a230760 100644
--- a/drivers/media/dvb/frontends/l64781.h
+++ b/drivers/media/dvb/frontends/l64781.h
@@ -31,8 +31,16 @@ struct l64781_config
u8 demod_address;
};
-
+#if defined(CONFIG_DVB_L64781) || defined(CONFIG_DVB_L64781_MODULE)
extern struct dvb_frontend* l64781_attach(const struct l64781_config* config,
struct i2c_adapter* i2c);
+#else
+static inline struct dvb_frontend* l64781_attach(const struct l64781_config* config,
+ struct i2c_adapter* i2c)
+{
+ printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__);
+ return NULL;
+}
+#endif // CONFIG_DVB_L64781
#endif // L64781_H
diff --git a/drivers/media/dvb/frontends/lgdt330x.h b/drivers/media/dvb/frontends/lgdt330x.h
index bad903c6f0f8..3f96b485584c 100644
--- a/drivers/media/dvb/frontends/lgdt330x.h
+++ b/drivers/media/dvb/frontends/lgdt330x.h
@@ -52,8 +52,17 @@ struct lgdt330x_config
int clock_polarity_flip;
};
+#if defined(CONFIG_DVB_LGDT330X) || defined(CONFIG_DVB_LGDT330X_MODULE)
extern struct dvb_frontend* lgdt330x_attach(const struct lgdt330x_config* config,
struct i2c_adapter* i2c);
+#else
+static inline struct dvb_frontend* lgdt330x_attach(const struct lgdt330x_config* config,
+ struct i2c_adapter* i2c)
+{
+ printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__);
+ return NULL;
+}
+#endif // CONFIG_DVB_LGDT330X
#endif /* LGDT330X_H */
diff --git a/drivers/media/dvb/frontends/lnbp21.c b/drivers/media/dvb/frontends/lnbp21.c
index e933edc8dd29..2d2f58c26226 100644
--- a/drivers/media/dvb/frontends/lnbp21.c
+++ b/drivers/media/dvb/frontends/lnbp21.c
@@ -40,12 +40,11 @@ struct lnbp21 {
u8 override_or;
u8 override_and;
struct i2c_adapter *i2c;
- void (*release_chain)(struct dvb_frontend* fe);
};
static int lnbp21_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage)
{
- struct lnbp21 *lnbp21 = (struct lnbp21 *) fe->misc_priv;
+ struct lnbp21 *lnbp21 = (struct lnbp21 *) fe->sec_priv;
struct i2c_msg msg = { .addr = 0x08, .flags = 0,
.buf = &lnbp21->config,
.len = sizeof(lnbp21->config) };
@@ -73,7 +72,7 @@ static int lnbp21_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage)
static int lnbp21_enable_high_lnb_voltage(struct dvb_frontend *fe, long arg)
{
- struct lnbp21 *lnbp21 = (struct lnbp21 *) fe->misc_priv;
+ struct lnbp21 *lnbp21 = (struct lnbp21 *) fe->sec_priv;
struct i2c_msg msg = { .addr = 0x08, .flags = 0,
.buf = &lnbp21->config,
.len = sizeof(lnbp21->config) };
@@ -91,29 +90,24 @@ static int lnbp21_enable_high_lnb_voltage(struct dvb_frontend *fe, long arg)
static void lnbp21_release(struct dvb_frontend *fe)
{
- struct lnbp21 *lnbp21 = (struct lnbp21 *) fe->misc_priv;
-
/* LNBP power off */
lnbp21_set_voltage(fe, SEC_VOLTAGE_OFF);
- /* free data & call next release routine */
- fe->ops.release = lnbp21->release_chain;
- kfree(fe->misc_priv);
- fe->misc_priv = NULL;
- if (fe->ops.release)
- fe->ops.release(fe);
+ /* free data */
+ kfree(fe->sec_priv);
+ fe->sec_priv = NULL;
}
-int lnbp21_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, u8 override_set, u8 override_clear)
+struct dvb_frontend *lnbp21_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, u8 override_set, u8 override_clear)
{
struct lnbp21 *lnbp21 = kmalloc(sizeof(struct lnbp21), GFP_KERNEL);
if (!lnbp21)
- return -ENOMEM;
+ return NULL;
/* default configuration */
lnbp21->config = LNBP21_ISEL;
lnbp21->i2c = i2c;
- fe->misc_priv = lnbp21;
+ fe->sec_priv = lnbp21;
/* bits which should be forced to '1' */
lnbp21->override_or = override_set;
@@ -124,19 +118,17 @@ int lnbp21_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, u8 override_
/* detect if it is present or not */
if (lnbp21_set_voltage(fe, SEC_VOLTAGE_OFF)) {
kfree(lnbp21);
- fe->misc_priv = NULL;
- return -EIO;
+ return NULL;
}
/* install release callback */
- lnbp21->release_chain = fe->ops.release;
- fe->ops.release = lnbp21_release;
+ fe->ops.release_sec = lnbp21_release;
/* override frontend ops */
fe->ops.set_voltage = lnbp21_set_voltage;
fe->ops.enable_high_lnb_voltage = lnbp21_enable_high_lnb_voltage;
- return 0;
+ return fe;
}
EXPORT_SYMBOL(lnbp21_attach);
diff --git a/drivers/media/dvb/frontends/lnbp21.h b/drivers/media/dvb/frontends/lnbp21.h
index 047a4ab68c01..1fe1dd179312 100644
--- a/drivers/media/dvb/frontends/lnbp21.h
+++ b/drivers/media/dvb/frontends/lnbp21.h
@@ -39,7 +39,15 @@
#include <linux/dvb/frontend.h>
+#if defined(CONFIG_DVB_LNBP21) || defined(CONFIG_DVB_LNBP21_MODULE)
/* override_set and override_clear control which system register bits (above) to always set & clear */
-extern int lnbp21_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, u8 override_set, u8 override_clear);
+extern struct dvb_frontend *lnbp21_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, u8 override_set, u8 override_clear);
+#else
+static inline struct dvb_frontend *lnbp21_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, u8 override_set, u8 override_clear)
+{
+ printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__);
+ return NULL;
+}
+#endif // CONFIG_DVB_LNBP21
-#endif
+#endif // _LNBP21_H
diff --git a/drivers/media/dvb/frontends/mt2060.c b/drivers/media/dvb/frontends/mt2060.c
new file mode 100644
index 000000000000..508ec1b6d1fb
--- /dev/null
+++ b/drivers/media/dvb/frontends/mt2060.c
@@ -0,0 +1,367 @@
+/*
+ * Driver for Microtune MT2060 "Single chip dual conversion broadband tuner"
+ *
+ * Copyright (c) 2006 Olivier DANET <odanet@caramail.com>
+ *
+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.=
+ */
+
+/* In that file, frequencies are expressed in kiloHertz to avoid 32 bits overflows */
+
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/delay.h>
+#include <linux/dvb/frontend.h>
+#include <linux/i2c.h>
+
+#include "dvb_frontend.h"
+
+#include "mt2060.h"
+#include "mt2060_priv.h"
+
+static int debug;
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "Turn on/off debugging (default:off).");
+
+#define dprintk(args...) do { if (debug) {printk(KERN_DEBUG "MT2060: " args); printk("\n"); }} while (0)
+
+// Reads a single register
+static int mt2060_readreg(struct mt2060_priv *priv, u8 reg, u8 *val)
+{
+ struct i2c_msg msg[2] = {
+ { .addr = priv->cfg->i2c_address, .flags = 0, .buf = &reg, .len = 1 },
+ { .addr = priv->cfg->i2c_address, .flags = I2C_M_RD, .buf = val, .len = 1 },
+ };
+
+ if (i2c_transfer(priv->i2c, msg, 2) != 2) {
+ printk(KERN_WARNING "mt2060 I2C read failed\n");
+ return -EREMOTEIO;
+ }
+ return 0;
+}
+
+// Writes a single register
+static int mt2060_writereg(struct mt2060_priv *priv, u8 reg, u8 val)
+{
+ u8 buf[2] = { reg, val };
+ struct i2c_msg msg = {
+ .addr = priv->cfg->i2c_address, .flags = 0, .buf = buf, .len = 2
+ };
+
+ if (i2c_transfer(priv->i2c, &msg, 1) != 1) {
+ printk(KERN_WARNING "mt2060 I2C write failed\n");
+ return -EREMOTEIO;
+ }
+ return 0;
+}
+
+// Writes a set of consecutive registers
+static int mt2060_writeregs(struct mt2060_priv *priv,u8 *buf, u8 len)
+{
+ struct i2c_msg msg = {
+ .addr = priv->cfg->i2c_address, .flags = 0, .buf = buf, .len = len
+ };
+ if (i2c_transfer(priv->i2c, &msg, 1) != 1) {
+ printk(KERN_WARNING "mt2060 I2C write failed (len=%i)\n",(int)len);
+ return -EREMOTEIO;
+ }
+ return 0;
+}
+
+// Initialisation sequences
+// LNABAND=3, NUM1=0x3C, DIV1=0x74, NUM2=0x1080, DIV2=0x49
+static u8 mt2060_config1[] = {
+ REG_LO1C1,
+ 0x3F, 0x74, 0x00, 0x08, 0x93
+};
+
+// FMCG=2, GP2=0, GP1=0
+static u8 mt2060_config2[] = {
+ REG_MISC_CTRL,
+ 0x20, 0x1E, 0x30, 0xff, 0x80, 0xff, 0x00, 0x2c, 0x42
+};
+
+// VGAG=3, V1CSE=1
+
+#ifdef MT2060_SPURCHECK
+/* The function below calculates the frequency offset between the output frequency if2
+ and the closer cross modulation subcarrier between lo1 and lo2 up to the tenth harmonic */
+static int mt2060_spurcalc(u32 lo1,u32 lo2,u32 if2)
+{
+ int I,J;
+ int dia,diamin,diff;
+ diamin=1000000;
+ for (I = 1; I < 10; I++) {
+ J = ((2*I*lo1)/lo2+1)/2;
+ diff = I*(int)lo1-J*(int)lo2;
+ if (diff < 0) diff=-diff;
+ dia = (diff-(int)if2);
+ if (dia < 0) dia=-dia;
+ if (diamin > dia) diamin=dia;
+ }
+ return diamin;
+}
+
+#define BANDWIDTH 4000 // kHz
+
+/* Calculates the frequency offset to add to avoid spurs. Returns 0 if no offset is needed */
+static int mt2060_spurcheck(u32 lo1,u32 lo2,u32 if2)
+{
+ u32 Spur,Sp1,Sp2;
+ int I,J;
+ I=0;
+ J=1000;
+
+ Spur=mt2060_spurcalc(lo1,lo2,if2);
+ if (Spur < BANDWIDTH) {
+ /* Potential spurs detected */
+ dprintk("Spurs before : f_lo1: %d f_lo2: %d (kHz)",
+ (int)lo1,(int)lo2);
+ I=1000;
+ Sp1 = mt2060_spurcalc(lo1+I,lo2+I,if2);
+ Sp2 = mt2060_spurcalc(lo1-I,lo2-I,if2);
+
+ if (Sp1 < Sp2) {
+ J=-J; I=-I; Spur=Sp2;
+ } else
+ Spur=Sp1;
+
+ while (Spur < BANDWIDTH) {
+ I += J;
+ Spur = mt2060_spurcalc(lo1+I,lo2+I,if2);
+ }
+ dprintk("Spurs after : f_lo1: %d f_lo2: %d (kHz)",
+ (int)(lo1+I),(int)(lo2+I));
+ }
+ return I;
+}
+#endif
+
+#define IF2 36150 // IF2 frequency = 36.150 MHz
+#define FREF 16000 // Quartz oscillator 16 MHz
+
+static int mt2060_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *params)
+{
+ struct mt2060_priv *priv;
+ int ret=0;
+ int i=0;
+ u32 freq;
+ u8 lnaband;
+ u32 f_lo1,f_lo2;
+ u32 div1,num1,div2,num2;
+ u8 b[8];
+ u32 if1;
+
+ priv = fe->tuner_priv;
+
+ if1 = priv->if1_freq;
+ b[0] = REG_LO1B1;
+ b[1] = 0xFF;
+
+ mt2060_writeregs(priv,b,2);
+
+ freq = params->frequency / 1000; // Hz -> kHz
+ priv->bandwidth = (fe->ops.info.type == FE_OFDM) ? params->u.ofdm.bandwidth : 0;
+
+ f_lo1 = freq + if1 * 1000;
+ f_lo1 = (f_lo1 / 250) * 250;
+ f_lo2 = f_lo1 - freq - IF2;
+ // From the Comtech datasheet, the step used is 50kHz. The tuner chip could be more precise
+ f_lo2 = ((f_lo2 + 25) / 50) * 50;
+ priv->frequency = (f_lo1 - f_lo2 - IF2) * 1000,
+
+#ifdef MT2060_SPURCHECK
+ // LO-related spurs detection and correction
+ num1 = mt2060_spurcheck(f_lo1,f_lo2,IF2);
+ f_lo1 += num1;
+ f_lo2 += num1;
+#endif
+ //Frequency LO1 = 16MHz * (DIV1 + NUM1/64 )
+ num1 = f_lo1 / (FREF / 64);
+ div1 = num1 / 64;
+ num1 &= 0x3f;
+
+ // Frequency LO2 = 16MHz * (DIV2 + NUM2/8192 )
+ num2 = f_lo2 * 64 / (FREF / 128);
+ div2 = num2 / 8192;
+ num2 &= 0x1fff;
+
+ if (freq <= 95000) lnaband = 0xB0; else
+ if (freq <= 180000) lnaband = 0xA0; else
+ if (freq <= 260000) lnaband = 0x90; else
+ if (freq <= 335000) lnaband = 0x80; else
+ if (freq <= 425000) lnaband = 0x70; else
+ if (freq <= 480000) lnaband = 0x60; else
+ if (freq <= 570000) lnaband = 0x50; else
+ if (freq <= 645000) lnaband = 0x40; else
+ if (freq <= 730000) lnaband = 0x30; else
+ if (freq <= 810000) lnaband = 0x20; else lnaband = 0x10;
+
+ b[0] = REG_LO1C1;
+ b[1] = lnaband | ((num1 >>2) & 0x0F);
+ b[2] = div1;
+ b[3] = (num2 & 0x0F) | ((num1 & 3) << 4);
+ b[4] = num2 >> 4;
+ b[5] = ((num2 >>12) & 1) | (div2 << 1);
+
+ dprintk("IF1: %dMHz",(int)if1);
+ dprintk("PLL freq=%dkHz f_lo1=%dkHz f_lo2=%dkHz",(int)freq,(int)f_lo1,(int)f_lo2);
+ dprintk("PLL div1=%d num1=%d div2=%d num2=%d",(int)div1,(int)num1,(int)div2,(int)num2);
+ dprintk("PLL [1..5]: %2x %2x %2x %2x %2x",(int)b[1],(int)b[2],(int)b[3],(int)b[4],(int)b[5]);
+
+ mt2060_writeregs(priv,b,6);
+
+ //Waits for pll lock or timeout
+ i = 0;
+ do {
+ mt2060_readreg(priv,REG_LO_STATUS,b);
+ if ((b[0] & 0x88)==0x88)
+ break;
+ msleep(4);
+ i++;
+ } while (i<10);
+
+ return ret;
+}
+
+static void mt2060_calibrate(struct mt2060_priv *priv)
+{
+ u8 b = 0;
+ int i = 0;
+
+ if (mt2060_writeregs(priv,mt2060_config1,sizeof(mt2060_config1)))
+ return;
+ if (mt2060_writeregs(priv,mt2060_config2,sizeof(mt2060_config2)))
+ return;
+
+ do {
+ b |= (1 << 6); // FM1SS;
+ mt2060_writereg(priv, REG_LO2C1,b);
+ msleep(20);
+
+ if (i == 0) {
+ b |= (1 << 7); // FM1CA;
+ mt2060_writereg(priv, REG_LO2C1,b);
+ b &= ~(1 << 7); // FM1CA;
+ msleep(20);
+ }
+
+ b &= ~(1 << 6); // FM1SS
+ mt2060_writereg(priv, REG_LO2C1,b);
+
+ msleep(20);
+ i++;
+ } while (i < 9);
+
+ i = 0;
+ while (i++ < 10 && mt2060_readreg(priv, REG_MISC_STAT, &b) == 0 && (b & (1 << 6)) == 0)
+ msleep(20);
+
+ if (i < 10) {
+ mt2060_readreg(priv, REG_FM_FREQ, &priv->fmfreq); // now find out, what is fmreq used for :)
+ dprintk("calibration was successful: %d", (int)priv->fmfreq);
+ } else
+ dprintk("FMCAL timed out");
+}
+
+static int mt2060_get_frequency(struct dvb_frontend *fe, u32 *frequency)
+{
+ struct mt2060_priv *priv = fe->tuner_priv;
+ *frequency = priv->frequency;
+ return 0;
+}
+
+static int mt2060_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth)
+{
+ struct mt2060_priv *priv = fe->tuner_priv;
+ *bandwidth = priv->bandwidth;
+ return 0;
+}
+
+static int mt2060_init(struct dvb_frontend *fe)
+{
+ struct mt2060_priv *priv = fe->tuner_priv;
+ return mt2060_writereg(priv, REG_VGAG,0x33);
+}
+
+static int mt2060_sleep(struct dvb_frontend *fe)
+{
+ struct mt2060_priv *priv = fe->tuner_priv;
+ return mt2060_writereg(priv, REG_VGAG,0x30);
+}
+
+static int mt2060_release(struct dvb_frontend *fe)
+{
+ kfree(fe->tuner_priv);
+ fe->tuner_priv = NULL;
+ return 0;
+}
+
+static const struct dvb_tuner_ops mt2060_tuner_ops = {
+ .info = {
+ .name = "Microtune MT2060",
+ .frequency_min = 48000000,
+ .frequency_max = 860000000,
+ .frequency_step = 50000,
+ },
+
+ .release = mt2060_release,
+
+ .init = mt2060_init,
+ .sleep = mt2060_sleep,
+
+ .set_params = mt2060_set_params,
+ .get_frequency = mt2060_get_frequency,
+ .get_bandwidth = mt2060_get_bandwidth
+};
+
+/* This functions tries to identify a MT2060 tuner by reading the PART/REV register. This is hasty. */
+int mt2060_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct mt2060_config *cfg, u16 if1)
+{
+ struct mt2060_priv *priv = NULL;
+ u8 id = 0;
+
+ priv = kzalloc(sizeof(struct mt2060_priv), GFP_KERNEL);
+ if (priv == NULL)
+ return -ENOMEM;
+
+ priv->cfg = cfg;
+ priv->i2c = i2c;
+ priv->if1_freq = if1;
+
+ if (mt2060_readreg(priv,REG_PART_REV,&id) != 0) {
+ kfree(priv);
+ return -ENODEV;
+ }
+
+ if (id != PART_REV) {
+ kfree(priv);
+ return -ENODEV;
+ }
+ printk(KERN_INFO "MT2060: successfully identified (IF1 = %d)\n", if1);
+ memcpy(&fe->ops.tuner_ops, &mt2060_tuner_ops, sizeof(struct dvb_tuner_ops));
+
+ fe->tuner_priv = priv;
+
+ mt2060_calibrate(priv);
+
+ return 0;
+}
+EXPORT_SYMBOL(mt2060_attach);
+
+MODULE_AUTHOR("Olivier DANET");
+MODULE_DESCRIPTION("Microtune MT2060 silicon tuner driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/frontends/mt2060.h b/drivers/media/dvb/frontends/mt2060.h
new file mode 100644
index 000000000000..c58b03e82345
--- /dev/null
+++ b/drivers/media/dvb/frontends/mt2060.h
@@ -0,0 +1,35 @@
+/*
+ * Driver for Microtune MT2060 "Single chip dual conversion broadband tuner"
+ *
+ * Copyright (c) 2006 Olivier DANET <odanet@caramail.com>
+ *
+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.=
+ */
+
+#ifndef MT2060_H
+#define MT2060_H
+
+struct dvb_frontend;
+struct i2c_adapter;
+
+struct mt2060_config {
+ u8 i2c_address;
+ /* Shall we add settings for the discrete outputs ? */
+};
+
+extern int mt2060_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct mt2060_config *cfg, u16 if1);
+
+#endif
diff --git a/drivers/media/dvb/frontends/mt2060_priv.h b/drivers/media/dvb/frontends/mt2060_priv.h
new file mode 100644
index 000000000000..5eaccdefd0b0
--- /dev/null
+++ b/drivers/media/dvb/frontends/mt2060_priv.h
@@ -0,0 +1,105 @@
+/*
+ * Driver for Microtune MT2060 "Single chip dual conversion broadband tuner"
+ *
+ * Copyright (c) 2006 Olivier DANET <odanet@caramail.com>
+ *
+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.=
+ */
+
+#ifndef MT2060_PRIV_H
+#define MT2060_PRIV_H
+
+// Uncomment the #define below to enable spurs checking. The results where quite unconvincing.
+// #define MT2060_SPURCHECK
+
+/* This driver is based on the information available in the datasheet of the
+ "Comtech SDVBT-3K6M" tuner ( K1000737843.pdf ) which features the MT2060 register map :
+
+ I2C Address : 0x60
+
+ Reg.No | B7 | B6 | B5 | B4 | B3 | B2 | B1 | B0 | ( defaults )
+ --------------------------------------------------------------------------------
+ 00 | [ PART ] | [ REV ] | R = 0x63
+ 01 | [ LNABAND ] | [ NUM1(5:2) ] | RW = 0x3F
+ 02 | [ DIV1 ] | RW = 0x74
+ 03 | FM1CA | FM1SS | [ NUM1(1:0) ] | [ NUM2(3:0) ] | RW = 0x00
+ 04 | NUM2(11:4) ] | RW = 0x08
+ 05 | [ DIV2 ] |NUM2(12)| RW = 0x93
+ 06 | L1LK | [ TAD1 ] | L2LK | [ TAD2 ] | R
+ 07 | [ FMF ] | R
+ 08 | ? | FMCAL | ? | ? | ? | ? | ? | TEMP | R
+ 09 | 0 | 0 | [ FMGC ] | 0 | GP02 | GP01 | 0 | RW = 0x20
+ 0A | ??
+ 0B | 0 | 0 | 1 | 1 | 0 | 0 | [ VGAG ] | RW = 0x30
+ 0C | V1CSE | 1 | 1 | 1 | 1 | 1 | 1 | 1 | RW = 0xFF
+ 0D | 1 | 0 | [ V1CS ] | RW = 0xB0
+ 0E | ??
+ 0F | ??
+ 10 | ??
+ 11 | [ LOTO ] | 0 | 0 | 1 | 0 | RW = 0x42
+
+ PART : Part code : 6 for MT2060
+ REV : Revision code : 3 for current revision
+ LNABAND : Input frequency range : ( See code for details )
+ NUM1 / DIV1 / NUM2 / DIV2 : Frequencies programming ( See code for details )
+ FM1CA : Calibration Start Bit
+ FM1SS : Calibration Single Step bit
+ L1LK : LO1 Lock Detect
+ TAD1 : Tune Line ADC ( ? )
+ L2LK : LO2 Lock Detect
+ TAD2 : Tune Line ADC ( ? )
+ FMF : Estimated first IF Center frequency Offset ( ? )
+ FM1CAL : Calibration done bit
+ TEMP : On chip temperature sensor
+ FMCG : Mixer 1 Cap Gain ( ? )
+ GP01 / GP02 : Programmable digital outputs. Unconnected pins ?
+ V1CSE : LO1 VCO Automatic Capacitor Select Enable ( ? )
+ V1CS : LO1 Capacitor Selection Value ( ? )
+ LOTO : LO Timeout ( ? )
+ VGAG : Tuner Output gain
+*/
+
+#define I2C_ADDRESS 0x60
+
+#define REG_PART_REV 0
+#define REG_LO1C1 1
+#define REG_LO1C2 2
+#define REG_LO2C1 3
+#define REG_LO2C2 4
+#define REG_LO2C3 5
+#define REG_LO_STATUS 6
+#define REG_FM_FREQ 7
+#define REG_MISC_STAT 8
+#define REG_MISC_CTRL 9
+#define REG_RESERVED_A 0x0A
+#define REG_VGAG 0x0B
+#define REG_LO1B1 0x0C
+#define REG_LO1B2 0x0D
+#define REG_LOTO 0x11
+
+#define PART_REV 0x63 // The current driver works only with PART=6 and REV=3 chips
+
+struct mt2060_priv {
+ struct mt2060_config *cfg;
+ struct i2c_adapter *i2c;
+
+ u32 frequency;
+ u32 bandwidth;
+ u16 if1_freq;
+ u8 fmfreq;
+};
+
+#endif
diff --git a/drivers/media/dvb/frontends/mt312.h b/drivers/media/dvb/frontends/mt312.h
index 666a1bd1c244..7112fb4d58ac 100644
--- a/drivers/media/dvb/frontends/mt312.h
+++ b/drivers/media/dvb/frontends/mt312.h
@@ -34,8 +34,16 @@ struct mt312_config
u8 demod_address;
};
+#if defined(CONFIG_DVB_MT312) || defined(CONFIG_DVB_MT312_MODULE)
struct dvb_frontend* vp310_mt312_attach(const struct mt312_config* config,
struct i2c_adapter* i2c);
-
+#else
+static inline struct dvb_frontend* vp310_mt312_attach(const struct mt312_config* config,
+ struct i2c_adapter* i2c)
+{
+ printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__);
+ return NULL;
+}
+#endif // CONFIG_DVB_MT312
#endif // MT312_H
diff --git a/drivers/media/dvb/frontends/mt352.c b/drivers/media/dvb/frontends/mt352.c
index 5de7376c94ce..87e31ca7e108 100644
--- a/drivers/media/dvb/frontends/mt352.c
+++ b/drivers/media/dvb/frontends/mt352.c
@@ -70,7 +70,7 @@ static int mt352_single_write(struct dvb_frontend *fe, u8 reg, u8 val)
return 0;
}
-int mt352_write(struct dvb_frontend* fe, u8* ibuf, int ilen)
+static int _mt352_write(struct dvb_frontend* fe, u8* ibuf, int ilen)
{
int err,i;
for (i=0; i < ilen-1; i++)
@@ -107,7 +107,7 @@ static int mt352_sleep(struct dvb_frontend* fe)
{
static u8 mt352_softdown[] = { CLOCK_CTL, 0x20, 0x08 };
- mt352_write(fe, mt352_softdown, sizeof(mt352_softdown));
+ _mt352_write(fe, mt352_softdown, sizeof(mt352_softdown));
return 0;
}
@@ -293,14 +293,14 @@ static int mt352_set_parameters(struct dvb_frontend* fe,
fe->ops.i2c_gate_ctrl(fe, 0);
}
- mt352_write(fe, buf, 8);
- mt352_write(fe, fsm_go, 2);
+ _mt352_write(fe, buf, 8);
+ _mt352_write(fe, fsm_go, 2);
} else {
if (fe->ops.tuner_ops.calc_regs) {
fe->ops.tuner_ops.calc_regs(fe, param, buf+8, 5);
buf[8] <<= 1;
- mt352_write(fe, buf, sizeof(buf));
- mt352_write(fe, tuner_go, 2);
+ _mt352_write(fe, buf, sizeof(buf));
+ _mt352_write(fe, tuner_go, 2);
}
}
@@ -522,7 +522,7 @@ static int mt352_init(struct dvb_frontend* fe)
(mt352_read_register(state, CONFIG) & 0x20) == 0) {
/* Do a "hard" reset */
- mt352_write(fe, mt352_reset_attach, sizeof(mt352_reset_attach));
+ _mt352_write(fe, mt352_reset_attach, sizeof(mt352_reset_attach));
return state->config.demod_init(fe);
}
@@ -585,6 +585,7 @@ static struct dvb_frontend_ops mt352_ops = {
.init = mt352_init,
.sleep = mt352_sleep,
+ .write = _mt352_write,
.set_frontend = mt352_set_parameters,
.get_frontend = mt352_get_parameters,
@@ -605,4 +606,3 @@ MODULE_AUTHOR("Holger Waechtler, Daniel Mack, Antonio Mancuso");
MODULE_LICENSE("GPL");
EXPORT_SYMBOL(mt352_attach);
-EXPORT_SYMBOL(mt352_write);
diff --git a/drivers/media/dvb/frontends/mt352.h b/drivers/media/dvb/frontends/mt352.h
index 9e7ff4b8fe5f..0035c2e2d7c2 100644
--- a/drivers/media/dvb/frontends/mt352.h
+++ b/drivers/media/dvb/frontends/mt352.h
@@ -51,9 +51,23 @@ struct mt352_config
int (*demod_init)(struct dvb_frontend* fe);
};
+#if defined(CONFIG_DVB_MT352) || defined(CONFIG_DVB_MT352_MODULE)
extern struct dvb_frontend* mt352_attach(const struct mt352_config* config,
struct i2c_adapter* i2c);
+#else
+static inline struct dvb_frontend* mt352_attach(const struct mt352_config* config,
+ struct i2c_adapter* i2c)
+{
+ printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__);
+ return NULL;
+}
+#endif // CONFIG_DVB_MT352
-extern int mt352_write(struct dvb_frontend* fe, u8* ibuf, int ilen);
+static inline int mt352_write(struct dvb_frontend *fe, u8 *buf, int len) {
+ int r = 0;
+ if (fe->ops.write)
+ r = fe->ops.write(fe, buf, len);
+ return r;
+}
#endif // MT352_H
diff --git a/drivers/media/dvb/frontends/nxt200x.h b/drivers/media/dvb/frontends/nxt200x.h
index 34d61735845b..2eb220e98062 100644
--- a/drivers/media/dvb/frontends/nxt200x.h
+++ b/drivers/media/dvb/frontends/nxt200x.h
@@ -45,8 +45,17 @@ struct nxt200x_config
int (*set_ts_params)(struct dvb_frontend* fe, int is_punctured);
};
+#if defined(CONFIG_DVB_NXT200X) || defined(CONFIG_DVB_NXT200X_MODULE)
extern struct dvb_frontend* nxt200x_attach(const struct nxt200x_config* config,
struct i2c_adapter* i2c);
+#else
+static inline struct dvb_frontend* nxt200x_attach(const struct nxt200x_config* config,
+ struct i2c_adapter* i2c)
+{
+ printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__);
+ return NULL;
+}
+#endif // CONFIG_DVB_NXT200X
#endif /* NXT200X_H */
diff --git a/drivers/media/dvb/frontends/nxt6000.h b/drivers/media/dvb/frontends/nxt6000.h
index 117031d11708..9397393a6bd1 100644
--- a/drivers/media/dvb/frontends/nxt6000.h
+++ b/drivers/media/dvb/frontends/nxt6000.h
@@ -33,7 +33,16 @@ struct nxt6000_config
u8 clock_inversion:1;
};
+#if defined(CONFIG_DVB_NXT6000) || defined(CONFIG_DVB_NXT6000_MODULE)
extern struct dvb_frontend* nxt6000_attach(const struct nxt6000_config* config,
struct i2c_adapter* i2c);
+#else
+static inline struct dvb_frontend* nxt6000_attach(const struct nxt6000_config* config,
+ struct i2c_adapter* i2c)
+{
+ printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__);
+ return NULL;
+}
+#endif // CONFIG_DVB_NXT6000
#endif // NXT6000_H
diff --git a/drivers/media/dvb/frontends/or51132.h b/drivers/media/dvb/frontends/or51132.h
index 89658883abf5..9718be4fb835 100644
--- a/drivers/media/dvb/frontends/or51132.h
+++ b/drivers/media/dvb/frontends/or51132.h
@@ -34,8 +34,17 @@ struct or51132_config
int (*set_ts_params)(struct dvb_frontend* fe, int is_punctured);
};
+#if defined(CONFIG_DVB_OR51132) || defined(CONFIG_DVB_OR51132_MODULE)
extern struct dvb_frontend* or51132_attach(const struct or51132_config* config,
struct i2c_adapter* i2c);
+#else
+static inline struct dvb_frontend* or51132_attach(const struct or51132_config* config,
+ struct i2c_adapter* i2c)
+{
+ printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__);
+ return NULL;
+}
+#endif // CONFIG_DVB_OR51132
#endif // OR51132_H
diff --git a/drivers/media/dvb/frontends/or51211.h b/drivers/media/dvb/frontends/or51211.h
index 13a5a3afbf8b..10a5419f9e00 100644
--- a/drivers/media/dvb/frontends/or51211.h
+++ b/drivers/media/dvb/frontends/or51211.h
@@ -37,8 +37,17 @@ struct or51211_config
void (*sleep)(struct dvb_frontend * fe);
};
+#if defined(CONFIG_DVB_OR51211) || defined(CONFIG_DVB_OR51211_MODULE)
extern struct dvb_frontend* or51211_attach(const struct or51211_config* config,
struct i2c_adapter* i2c);
+#else
+static inline struct dvb_frontend* or51211_attach(const struct or51211_config* config,
+ struct i2c_adapter* i2c)
+{
+ printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__);
+ return NULL;
+}
+#endif // CONFIG_DVB_OR51211
#endif // OR51211_H
diff --git a/drivers/media/dvb/frontends/s5h1420.h b/drivers/media/dvb/frontends/s5h1420.h
index 4e39015fa67e..efc54d7f3c55 100644
--- a/drivers/media/dvb/frontends/s5h1420.h
+++ b/drivers/media/dvb/frontends/s5h1420.h
@@ -34,7 +34,16 @@ struct s5h1420_config
u8 invert:1;
};
+#if defined(CONFIG_DVB_S5H1420) || defined(CONFIG_DVB_S5H1420_MODULE)
extern struct dvb_frontend* s5h1420_attach(const struct s5h1420_config* config,
struct i2c_adapter* i2c);
+#else
+static inline struct dvb_frontend* s5h1420_attach(const struct s5h1420_config* config,
+ struct i2c_adapter* i2c)
+{
+ printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__);
+ return NULL;
+}
+#endif // CONFIG_DVB_S5H1420
#endif // S5H1420_H
diff --git a/drivers/media/dvb/frontends/sp8870.h b/drivers/media/dvb/frontends/sp8870.h
index 93afbb969d6b..4cf27d3b10f2 100644
--- a/drivers/media/dvb/frontends/sp8870.h
+++ b/drivers/media/dvb/frontends/sp8870.h
@@ -35,7 +35,16 @@ struct sp8870_config
int (*request_firmware)(struct dvb_frontend* fe, const struct firmware **fw, char* name);
};
+#if defined(CONFIG_DVB_SP8870) || defined(CONFIG_DVB_SP8870_MODULE)
extern struct dvb_frontend* sp8870_attach(const struct sp8870_config* config,
struct i2c_adapter* i2c);
+#else
+static inline struct dvb_frontend* sp8870_attach(const struct sp8870_config* config,
+ struct i2c_adapter* i2c)
+{
+ printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__);
+ return NULL;
+}
+#endif // CONFIG_DVB_SP8870
#endif // SP8870_H
diff --git a/drivers/media/dvb/frontends/sp887x.h b/drivers/media/dvb/frontends/sp887x.h
index c44b0ebdf1e2..cab7ea644dfa 100644
--- a/drivers/media/dvb/frontends/sp887x.h
+++ b/drivers/media/dvb/frontends/sp887x.h
@@ -17,7 +17,16 @@ struct sp887x_config
int (*request_firmware)(struct dvb_frontend* fe, const struct firmware **fw, char* name);
};
+#if defined(CONFIG_DVB_SP887X) || defined(CONFIG_DVB_SP887X_MODULE)
extern struct dvb_frontend* sp887x_attach(const struct sp887x_config* config,
struct i2c_adapter* i2c);
+#else
+static inline struct dvb_frontend* sp887x_attach(const struct sp887x_config* config,
+ struct i2c_adapter* i2c)
+{
+ printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__);
+ return NULL;
+}
+#endif // CONFIG_DVB_SP887X
#endif // SP887X_H
diff --git a/drivers/media/dvb/frontends/stv0297.h b/drivers/media/dvb/frontends/stv0297.h
index 1da5384fb985..760b80db43a5 100644
--- a/drivers/media/dvb/frontends/stv0297.h
+++ b/drivers/media/dvb/frontends/stv0297.h
@@ -42,7 +42,16 @@ struct stv0297_config
u8 stop_during_read:1;
};
+#if defined(CONFIG_DVB_STV0297) || defined(CONFIG_DVB_STV0297_MODULE)
extern struct dvb_frontend* stv0297_attach(const struct stv0297_config* config,
struct i2c_adapter* i2c);
+#else
+static inline struct dvb_frontend* stv0297_attach(const struct stv0297_config* config,
+ struct i2c_adapter* i2c)
+{
+ printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__);
+ return NULL;
+}
+#endif // CONFIG_DVB_STV0297
#endif // STV0297_H
diff --git a/drivers/media/dvb/frontends/stv0299.c b/drivers/media/dvb/frontends/stv0299.c
index 96648a75440d..93483769eca8 100644
--- a/drivers/media/dvb/frontends/stv0299.c
+++ b/drivers/media/dvb/frontends/stv0299.c
@@ -92,11 +92,14 @@ static int stv0299_writeregI (struct stv0299_state* state, u8 reg, u8 data)
return (ret != 1) ? -EREMOTEIO : 0;
}
-int stv0299_writereg (struct dvb_frontend* fe, u8 reg, u8 data)
+int stv0299_write(struct dvb_frontend* fe, u8 *buf, int len)
{
struct stv0299_state* state = fe->demodulator_priv;
- return stv0299_writeregI(state, reg, data);
+ if (len != 2)
+ return -EINVAL;
+
+ return stv0299_writeregI(state, buf[0], buf[1]);
}
static u8 stv0299_readreg (struct stv0299_state* state, u8 reg)
@@ -694,6 +697,7 @@ static struct dvb_frontend_ops stv0299_ops = {
.init = stv0299_init,
.sleep = stv0299_sleep,
+ .write = stv0299_write,
.i2c_gate_ctrl = stv0299_i2c_gate_ctrl,
.set_frontend = stv0299_set_frontend,
@@ -724,5 +728,4 @@ MODULE_AUTHOR("Ralph Metzler, Holger Waechtler, Peter Schildmann, Felix Domke, "
"Andreas Oberritter, Andrew de Quincey, Kenneth Aafly");
MODULE_LICENSE("GPL");
-EXPORT_SYMBOL(stv0299_writereg);
EXPORT_SYMBOL(stv0299_attach);
diff --git a/drivers/media/dvb/frontends/stv0299.h b/drivers/media/dvb/frontends/stv0299.h
index 1504828e4232..7ef25207081d 100644
--- a/drivers/media/dvb/frontends/stv0299.h
+++ b/drivers/media/dvb/frontends/stv0299.h
@@ -89,9 +89,24 @@ struct stv0299_config
int (*set_symbol_rate)(struct dvb_frontend* fe, u32 srate, u32 ratio);
};
-extern int stv0299_writereg (struct dvb_frontend* fe, u8 reg, u8 data);
-
+#if defined(CONFIG_DVB_STV0299) || defined(CONFIG_DVB_STV0299_MODULE)
extern struct dvb_frontend* stv0299_attach(const struct stv0299_config* config,
struct i2c_adapter* i2c);
+#else
+static inline struct dvb_frontend* stv0299_attach(const struct stv0299_config* config,
+ struct i2c_adapter* i2c)
+{
+ printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__);
+ return NULL;
+}
+#endif // CONFIG_DVB_STV0299
+
+static inline int stv0299_writereg(struct dvb_frontend *fe, u8 reg, u8 val) {
+ int r = 0;
+ u8 buf[] = {reg, val};
+ if (fe->ops.write)
+ r = fe->ops.write(fe, buf, 2);
+ return r;
+}
#endif // STV0299_H
diff --git a/drivers/media/dvb/frontends/tda10021.c b/drivers/media/dvb/frontends/tda10021.c
index 9cbd164aa281..dca89171be1f 100644
--- a/drivers/media/dvb/frontends/tda10021.c
+++ b/drivers/media/dvb/frontends/tda10021.c
@@ -72,7 +72,7 @@ static u8 tda10021_inittab[0x40]=
0x04, 0x2d, 0x2f, 0xff, 0x00, 0x00, 0x00, 0x00,
};
-static int tda10021_writereg (struct tda10021_state* state, u8 reg, u8 data)
+static int _tda10021_writereg (struct tda10021_state* state, u8 reg, u8 data)
{
u8 buf[] = { reg, data };
struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = buf, .len = 2 };
@@ -88,14 +88,6 @@ static int tda10021_writereg (struct tda10021_state* state, u8 reg, u8 data)
return (ret != 1) ? -EREMOTEIO : 0;
}
-int tda10021_write_byte(struct dvb_frontend* fe, int reg, int data)
-{
- struct tda10021_state* state = fe->demodulator_priv;
-
- return tda10021_writereg(state, reg, data);
-}
-EXPORT_SYMBOL(tda10021_write_byte);
-
static u8 tda10021_readreg (struct tda10021_state* state, u8 reg)
{
u8 b0 [] = { reg };
@@ -149,8 +141,8 @@ static int tda10021_setup_reg0 (struct tda10021_state* state, u8 reg0,
else if (INVERSION_OFF == inversion)
DISABLE_INVERSION(reg0);
- tda10021_writereg (state, 0x00, reg0 & 0xfe);
- tda10021_writereg (state, 0x00, reg0 | 0x01);
+ _tda10021_writereg (state, 0x00, reg0 & 0xfe);
+ _tda10021_writereg (state, 0x00, reg0 | 0x01);
state->reg0 = reg0;
return 0;
@@ -198,17 +190,27 @@ static int tda10021_set_symbolrate (struct tda10021_state* state, u32 symbolrate
NDEC = (NDEC << 6) | tda10021_inittab[0x03];
- tda10021_writereg (state, 0x03, NDEC);
- tda10021_writereg (state, 0x0a, BDR&0xff);
- tda10021_writereg (state, 0x0b, (BDR>> 8)&0xff);
- tda10021_writereg (state, 0x0c, (BDR>>16)&0x3f);
+ _tda10021_writereg (state, 0x03, NDEC);
+ _tda10021_writereg (state, 0x0a, BDR&0xff);
+ _tda10021_writereg (state, 0x0b, (BDR>> 8)&0xff);
+ _tda10021_writereg (state, 0x0c, (BDR>>16)&0x3f);
- tda10021_writereg (state, 0x0d, BDRI);
- tda10021_writereg (state, 0x0e, SFIL);
+ _tda10021_writereg (state, 0x0d, BDRI);
+ _tda10021_writereg (state, 0x0e, SFIL);
return 0;
}
+int tda10021_write(struct dvb_frontend* fe, u8 *buf, int len)
+{
+ struct tda10021_state* state = fe->demodulator_priv;
+
+ if (len != 2)
+ return -EINVAL;
+
+ return _tda10021_writereg(state, buf[0], buf[1]);
+}
+
static int tda10021_init (struct dvb_frontend *fe)
{
struct tda10021_state* state = fe->demodulator_priv;
@@ -216,12 +218,12 @@ static int tda10021_init (struct dvb_frontend *fe)
dprintk("DVB: TDA10021(%d): init chip\n", fe->adapter->num);
- //tda10021_writereg (fe, 0, 0);
+ //_tda10021_writereg (fe, 0, 0);
for (i=0; i<tda10021_inittab_size; i++)
- tda10021_writereg (state, i, tda10021_inittab[i]);
+ _tda10021_writereg (state, i, tda10021_inittab[i]);
- tda10021_writereg (state, 0x34, state->pwm);
+ _tda10021_writereg (state, 0x34, state->pwm);
//Comment by markus
//0x2A[3-0] == PDIV -> P multiplaying factor (P=PDIV+1)(default 0)
@@ -230,7 +232,7 @@ static int tda10021_init (struct dvb_frontend *fe)
//0x2A[6] == POLAXIN -> Polarity of the input reference clock (default 0)
//Activate PLL
- tda10021_writereg(state, 0x2a, tda10021_inittab[0x2a] & 0xef);
+ _tda10021_writereg(state, 0x2a, tda10021_inittab[0x2a] & 0xef);
return 0;
}
@@ -264,12 +266,12 @@ static int tda10021_set_parameters (struct dvb_frontend *fe,
}
tda10021_set_symbolrate (state, p->u.qam.symbol_rate);
- tda10021_writereg (state, 0x34, state->pwm);
+ _tda10021_writereg (state, 0x34, state->pwm);
- tda10021_writereg (state, 0x01, reg0x01[qam]);
- tda10021_writereg (state, 0x05, reg0x05[qam]);
- tda10021_writereg (state, 0x08, reg0x08[qam]);
- tda10021_writereg (state, 0x09, reg0x09[qam]);
+ _tda10021_writereg (state, 0x01, reg0x01[qam]);
+ _tda10021_writereg (state, 0x05, reg0x05[qam]);
+ _tda10021_writereg (state, 0x08, reg0x08[qam]);
+ _tda10021_writereg (state, 0x09, reg0x09[qam]);
tda10021_setup_reg0 (state, reg0x00[qam], p->inversion);
@@ -342,8 +344,8 @@ static int tda10021_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
*ucblocks = 0xffffffff;
/* reset uncorrected block counter */
- tda10021_writereg (state, 0x10, tda10021_inittab[0x10] & 0xdf);
- tda10021_writereg (state, 0x10, tda10021_inittab[0x10]);
+ _tda10021_writereg (state, 0x10, tda10021_inittab[0x10] & 0xdf);
+ _tda10021_writereg (state, 0x10, tda10021_inittab[0x10]);
return 0;
}
@@ -392,8 +394,8 @@ static int tda10021_sleep(struct dvb_frontend* fe)
{
struct tda10021_state* state = fe->demodulator_priv;
- tda10021_writereg (state, 0x1b, 0x02); /* pdown ADC */
- tda10021_writereg (state, 0x00, 0x80); /* standby */
+ _tda10021_writereg (state, 0x1b, 0x02); /* pdown ADC */
+ _tda10021_writereg (state, 0x00, 0x80); /* standby */
return 0;
}
@@ -459,6 +461,7 @@ static struct dvb_frontend_ops tda10021_ops = {
.init = tda10021_init,
.sleep = tda10021_sleep,
+ .write = tda10021_write,
.i2c_gate_ctrl = tda10021_i2c_gate_ctrl,
.set_frontend = tda10021_set_parameters,
diff --git a/drivers/media/dvb/frontends/tda10021.h b/drivers/media/dvb/frontends/tda10021.h
index b1df4259bee9..d68ae20c8412 100644
--- a/drivers/media/dvb/frontends/tda10021.h
+++ b/drivers/media/dvb/frontends/tda10021.h
@@ -32,9 +32,24 @@ struct tda10021_config
u8 demod_address;
};
+#if defined(CONFIG_DVB_TDA10021) || defined(CONFIG_DVB_TDA10021_MODULE)
extern struct dvb_frontend* tda10021_attach(const struct tda10021_config* config,
struct i2c_adapter* i2c, u8 pwm);
-
-extern int tda10021_write_byte(struct dvb_frontend* fe, int reg, int data);
+#else
+static inline struct dvb_frontend* tda10021_attach(const struct tda10021_config* config,
+ struct i2c_adapter* i2c, u8 pwm)
+{
+ printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__);
+ return NULL;
+}
+#endif // CONFIG_DVB_TDA10021
+
+static inline int tda10021_writereg(struct dvb_frontend *fe, u8 reg, u8 val) {
+ int r = 0;
+ u8 buf[] = {reg, val};
+ if (fe->ops.write)
+ r = fe->ops.write(fe, buf, 2);
+ return r;
+}
#endif // TDA10021_H
diff --git a/drivers/media/dvb/frontends/tda1004x.c b/drivers/media/dvb/frontends/tda1004x.c
index 59a2ed614fca..11e0dca9a2d7 100644
--- a/drivers/media/dvb/frontends/tda1004x.c
+++ b/drivers/media/dvb/frontends/tda1004x.c
@@ -579,11 +579,14 @@ static int tda1004x_decode_fec(int tdafec)
return -1;
}
-int tda1004x_write_byte(struct dvb_frontend* fe, int reg, int data)
+int tda1004x_write(struct dvb_frontend* fe, u8 *buf, int len)
{
struct tda1004x_state* state = fe->demodulator_priv;
- return tda1004x_write_byteI(state, reg, data);
+ if (len != 2)
+ return -EINVAL;
+
+ return tda1004x_write_byteI(state, buf[0], buf[1]);
}
static int tda10045_init(struct dvb_frontend* fe)
@@ -1216,6 +1219,7 @@ static struct dvb_frontend_ops tda10045_ops = {
.init = tda10045_init,
.sleep = tda1004x_sleep,
+ .write = tda1004x_write,
.i2c_gate_ctrl = tda1004x_i2c_gate_ctrl,
.set_frontend = tda1004x_set_fe,
@@ -1274,6 +1278,7 @@ static struct dvb_frontend_ops tda10046_ops = {
.init = tda10046_init,
.sleep = tda1004x_sleep,
+ .write = tda1004x_write,
.i2c_gate_ctrl = tda1004x_i2c_gate_ctrl,
.set_frontend = tda1004x_set_fe,
@@ -1323,4 +1328,3 @@ MODULE_LICENSE("GPL");
EXPORT_SYMBOL(tda10045_attach);
EXPORT_SYMBOL(tda10046_attach);
-EXPORT_SYMBOL(tda1004x_write_byte);
diff --git a/drivers/media/dvb/frontends/tda1004x.h b/drivers/media/dvb/frontends/tda1004x.h
index b877b23ed734..e28fca05734c 100644
--- a/drivers/media/dvb/frontends/tda1004x.h
+++ b/drivers/media/dvb/frontends/tda1004x.h
@@ -71,12 +71,33 @@ struct tda1004x_config
int (*request_firmware)(struct dvb_frontend* fe, const struct firmware **fw, char* name);
};
+#if defined(CONFIG_DVB_TDA1004X) || defined(CONFIG_DVB_TDA1004X_MODULE)
extern struct dvb_frontend* tda10045_attach(const struct tda1004x_config* config,
struct i2c_adapter* i2c);
extern struct dvb_frontend* tda10046_attach(const struct tda1004x_config* config,
struct i2c_adapter* i2c);
-
-extern int tda1004x_write_byte(struct dvb_frontend* fe, int reg, int data);
+#else
+static inline struct dvb_frontend* tda10045_attach(const struct tda1004x_config* config,
+ struct i2c_adapter* i2c)
+{
+ printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__);
+ return NULL;
+}
+static inline struct dvb_frontend* tda10046_attach(const struct tda1004x_config* config,
+ struct i2c_adapter* i2c)
+{
+ printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__);
+ return NULL;
+}
+#endif // CONFIG_DVB_TDA1004X
+
+static inline int tda1004x_writereg(struct dvb_frontend *fe, u8 reg, u8 val) {
+ int r = 0;
+ u8 buf[] = {reg, val};
+ if (fe->ops.write)
+ r = fe->ops.write(fe, buf, 2);
+ return r;
+}
#endif // TDA1004X_H
diff --git a/drivers/media/dvb/frontends/tda10086.c b/drivers/media/dvb/frontends/tda10086.c
new file mode 100644
index 000000000000..7456b0b9976b
--- /dev/null
+++ b/drivers/media/dvb/frontends/tda10086.c
@@ -0,0 +1,740 @@
+ /*
+ Driver for Philips tda10086 DVBS Demodulator
+
+ (c) 2006 Andrew de Quincey
+
+ 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/device.h>
+#include <linux/jiffies.h>
+#include <linux/string.h>
+#include <linux/slab.h>
+
+#include "dvb_frontend.h"
+#include "tda10086.h"
+
+#define SACLK 96000000
+
+struct tda10086_state {
+ struct i2c_adapter* i2c;
+ const struct tda10086_config* config;
+ struct dvb_frontend frontend;
+
+ /* private demod data */
+ u32 frequency;
+ u32 symbol_rate;
+};
+
+static int debug = 0;
+#define dprintk(args...) \
+ do { \
+ if (debug) printk(KERN_DEBUG "tda10086: " args); \
+ } while (0)
+
+static int tda10086_write_byte(struct tda10086_state *state, int reg, int data)
+{
+ int ret;
+ u8 b0[] = { reg, data };
+ struct i2c_msg msg = { .flags = 0, .buf = b0, .len = 2 };
+
+ msg.addr = state->config->demod_address;
+ ret = i2c_transfer(state->i2c, &msg, 1);
+
+ if (ret != 1)
+ dprintk("%s: error reg=0x%x, data=0x%x, ret=%i\n",
+ __FUNCTION__, reg, data, ret);
+
+ return (ret != 1) ? ret : 0;
+}
+
+static int tda10086_read_byte(struct tda10086_state *state, int reg)
+{
+ int ret;
+ u8 b0[] = { reg };
+ u8 b1[] = { 0 };
+ struct i2c_msg msg[] = {{ .flags = 0, .buf = b0, .len = 1 },
+ { .flags = I2C_M_RD, .buf = b1, .len = 1 }};
+
+ msg[0].addr = state->config->demod_address;
+ msg[1].addr = state->config->demod_address;
+ ret = i2c_transfer(state->i2c, msg, 2);
+
+ if (ret != 2) {
+ dprintk("%s: error reg=0x%x, ret=%i\n", __FUNCTION__, reg,
+ ret);
+ return ret;
+ }
+
+ return b1[0];
+}
+
+static int tda10086_write_mask(struct tda10086_state *state, int reg, int mask, int data)
+{
+ int val;
+
+ // read a byte and check
+ val = tda10086_read_byte(state, reg);
+ if (val < 0)
+ return val;
+
+ // mask if off
+ val = val & ~mask;
+ val |= data & 0xff;
+
+ // write it out again
+ return tda10086_write_byte(state, reg, val);
+}
+
+static int tda10086_init(struct dvb_frontend* fe)
+{
+ struct tda10086_state* state = fe->demodulator_priv;
+
+ dprintk ("%s\n", __FUNCTION__);
+
+ // reset
+ tda10086_write_byte(state, 0x00, 0x00);
+ msleep(10);
+
+ // misc setup
+ tda10086_write_byte(state, 0x01, 0x94);
+ tda10086_write_byte(state, 0x02, 0x35); // NOTE: TT drivers appear to disable CSWP
+ tda10086_write_byte(state, 0x03, 0x64);
+ tda10086_write_byte(state, 0x04, 0x43);
+ tda10086_write_byte(state, 0x0c, 0x0c);
+ tda10086_write_byte(state, 0x1b, 0xb0); // noise threshold
+ tda10086_write_byte(state, 0x20, 0x89); // misc
+ tda10086_write_byte(state, 0x30, 0x04); // acquisition period length
+ tda10086_write_byte(state, 0x32, 0x00); // irq off
+ tda10086_write_byte(state, 0x31, 0x56); // setup AFC
+
+ // setup PLL (assumes 16Mhz XIN)
+ tda10086_write_byte(state, 0x55, 0x2c); // misc PLL setup
+ tda10086_write_byte(state, 0x3a, 0x0b); // M=12
+ tda10086_write_byte(state, 0x3b, 0x01); // P=2
+ tda10086_write_mask(state, 0x55, 0x20, 0x00); // powerup PLL
+
+ // setup TS interface
+ tda10086_write_byte(state, 0x11, 0x81);
+ tda10086_write_byte(state, 0x12, 0x81);
+ tda10086_write_byte(state, 0x19, 0x40); // parallel mode A + MSBFIRST
+ tda10086_write_byte(state, 0x56, 0x80); // powerdown WPLL - unused in the mode we use
+ tda10086_write_byte(state, 0x57, 0x08); // bypass WPLL - unused in the mode we use
+ tda10086_write_byte(state, 0x10, 0x2a);
+
+ // setup ADC
+ tda10086_write_byte(state, 0x58, 0x61); // ADC setup
+ tda10086_write_mask(state, 0x58, 0x01, 0x00); // powerup ADC
+
+ // setup AGC
+ tda10086_write_byte(state, 0x05, 0x0B);
+ tda10086_write_byte(state, 0x37, 0x63);
+ tda10086_write_byte(state, 0x3f, 0x03); // NOTE: flydvb uses 0x0a and varies it
+ tda10086_write_byte(state, 0x40, 0x64);
+ tda10086_write_byte(state, 0x41, 0x4f);
+ tda10086_write_byte(state, 0x42, 0x43);
+
+ // setup viterbi
+ tda10086_write_byte(state, 0x1a, 0x11); // VBER 10^6, DVB, QPSK
+
+ // setup carrier recovery
+ tda10086_write_byte(state, 0x3d, 0x80);
+
+ // setup SEC
+ tda10086_write_byte(state, 0x36, 0x00); // all SEC off
+ tda10086_write_byte(state, 0x34, (((1<<19) * (22000/1000)) / (SACLK/1000))); // } tone frequency
+ tda10086_write_byte(state, 0x35, (((1<<19) * (22000/1000)) / (SACLK/1000)) >> 8); // }
+
+ return 0;
+}
+
+static void tda10086_diseqc_wait(struct tda10086_state *state)
+{
+ unsigned long timeout = jiffies + msecs_to_jiffies(200);
+ while (!(tda10086_read_byte(state, 0x50) & 0x01)) {
+ if(time_after(jiffies, timeout)) {
+ printk("%s: diseqc queue not ready, command may be lost.\n", __FUNCTION__);
+ break;
+ }
+ msleep(10);
+ }
+}
+
+static int tda10086_set_tone (struct dvb_frontend* fe, fe_sec_tone_mode_t tone)
+{
+ struct tda10086_state* state = fe->demodulator_priv;
+
+ dprintk ("%s\n", __FUNCTION__);
+
+ switch(tone) {
+ case SEC_TONE_OFF:
+ tda10086_write_byte(state, 0x36, 0x00);
+ break;
+
+ case SEC_TONE_ON:
+ tda10086_write_byte(state, 0x36, 0x01);
+ break;
+ }
+
+ return 0;
+}
+
+static int tda10086_send_master_cmd (struct dvb_frontend* fe,
+ struct dvb_diseqc_master_cmd* cmd)
+{
+ struct tda10086_state* state = fe->demodulator_priv;
+ int i;
+ u8 oldval;
+
+ dprintk ("%s\n", __FUNCTION__);
+
+ if (cmd->msg_len > 6)
+ return -EINVAL;
+ oldval = tda10086_read_byte(state, 0x36);
+
+ for(i=0; i< cmd->msg_len; i++) {
+ tda10086_write_byte(state, 0x48+i, cmd->msg[i]);
+ }
+ tda10086_write_byte(state, 0x36, 0x08 | ((cmd->msg_len + 1) << 4));
+
+ tda10086_diseqc_wait(state);
+
+ tda10086_write_byte(state, 0x36, oldval);
+
+ return 0;
+}
+
+static int tda10086_send_burst (struct dvb_frontend* fe, fe_sec_mini_cmd_t minicmd)
+{
+ struct tda10086_state* state = fe->demodulator_priv;
+ u8 oldval = tda10086_read_byte(state, 0x36);
+
+ dprintk ("%s\n", __FUNCTION__);
+
+ switch(minicmd) {
+ case SEC_MINI_A:
+ tda10086_write_byte(state, 0x36, 0x04);
+ break;
+
+ case SEC_MINI_B:
+ tda10086_write_byte(state, 0x36, 0x06);
+ break;
+ }
+
+ tda10086_diseqc_wait(state);
+
+ tda10086_write_byte(state, 0x36, oldval);
+
+ return 0;
+}
+
+static int tda10086_set_inversion(struct tda10086_state *state,
+ struct dvb_frontend_parameters *fe_params)
+{
+ u8 invval = 0x80;
+
+ dprintk ("%s %i %i\n", __FUNCTION__, fe_params->inversion, state->config->invert);
+
+ switch(fe_params->inversion) {
+ case INVERSION_OFF:
+ if (state->config->invert)
+ invval = 0x40;
+ break;
+ case INVERSION_ON:
+ if (!state->config->invert)
+ invval = 0x40;
+ break;
+ case INVERSION_AUTO:
+ invval = 0x00;
+ break;
+ }
+ tda10086_write_mask(state, 0x0c, 0xc0, invval);
+
+ return 0;
+}
+
+static int tda10086_set_symbol_rate(struct tda10086_state *state,
+ struct dvb_frontend_parameters *fe_params)
+{
+ u8 dfn = 0;
+ u8 afs = 0;
+ u8 byp = 0;
+ u8 reg37 = 0x43;
+ u8 reg42 = 0x43;
+ u64 big;
+ u32 tmp;
+ u32 bdr;
+ u32 bdri;
+ u32 symbol_rate = fe_params->u.qpsk.symbol_rate;
+
+ dprintk ("%s %i\n", __FUNCTION__, symbol_rate);
+
+ // setup the decimation and anti-aliasing filters..
+ if (symbol_rate < (u32) (SACLK * 0.0137)) {
+ dfn=4;
+ afs=1;
+ } else if (symbol_rate < (u32) (SACLK * 0.0208)) {
+ dfn=4;
+ afs=0;
+ } else if (symbol_rate < (u32) (SACLK * 0.0270)) {
+ dfn=3;
+ afs=1;
+ } else if (symbol_rate < (u32) (SACLK * 0.0416)) {
+ dfn=3;
+ afs=0;
+ } else if (symbol_rate < (u32) (SACLK * 0.0550)) {
+ dfn=2;
+ afs=1;
+ } else if (symbol_rate < (u32) (SACLK * 0.0833)) {
+ dfn=2;
+ afs=0;
+ } else if (symbol_rate < (u32) (SACLK * 0.1100)) {
+ dfn=1;
+ afs=1;
+ } else if (symbol_rate < (u32) (SACLK * 0.1666)) {
+ dfn=1;
+ afs=0;
+ } else if (symbol_rate < (u32) (SACLK * 0.2200)) {
+ dfn=0;
+ afs=1;
+ } else if (symbol_rate < (u32) (SACLK * 0.3333)) {
+ dfn=0;
+ afs=0;
+ } else {
+ reg37 = 0x63;
+ reg42 = 0x4f;
+ byp=1;
+ }
+
+ // calculate BDR
+ big = (1ULL<<21) * ((u64) symbol_rate/1000ULL) * (1ULL<<dfn);
+ big += ((SACLK/1000ULL)-1ULL);
+ do_div(big, (SACLK/1000ULL));
+ bdr = big & 0xfffff;
+
+ // calculate BDRI
+ tmp = (1<<dfn)*(symbol_rate/1000);
+ bdri = ((32 * (SACLK/1000)) + (tmp-1)) / tmp;
+
+ tda10086_write_byte(state, 0x21, (afs << 7) | dfn);
+ tda10086_write_mask(state, 0x20, 0x08, byp << 3);
+ tda10086_write_byte(state, 0x06, bdr);
+ tda10086_write_byte(state, 0x07, bdr >> 8);
+ tda10086_write_byte(state, 0x08, bdr >> 16);
+ tda10086_write_byte(state, 0x09, bdri);
+ tda10086_write_byte(state, 0x37, reg37);
+ tda10086_write_byte(state, 0x42, reg42);
+
+ return 0;
+}
+
+static int tda10086_set_fec(struct tda10086_state *state,
+ struct dvb_frontend_parameters *fe_params)
+{
+ u8 fecval;
+
+ dprintk ("%s %i\n", __FUNCTION__, fe_params->u.qpsk.fec_inner);
+
+ switch(fe_params->u.qpsk.fec_inner) {
+ case FEC_1_2:
+ fecval = 0x00;
+ break;
+ case FEC_2_3:
+ fecval = 0x01;
+ break;
+ case FEC_3_4:
+ fecval = 0x02;
+ break;
+ case FEC_4_5:
+ fecval = 0x03;
+ break;
+ case FEC_5_6:
+ fecval = 0x04;
+ break;
+ case FEC_6_7:
+ fecval = 0x05;
+ break;
+ case FEC_7_8:
+ fecval = 0x06;
+ break;
+ case FEC_8_9:
+ fecval = 0x07;
+ break;
+ case FEC_AUTO:
+ fecval = 0x08;
+ break;
+ default:
+ return -1;
+ }
+ tda10086_write_byte(state, 0x0d, fecval);
+
+ return 0;
+}
+
+static int tda10086_set_frontend(struct dvb_frontend* fe,
+ struct dvb_frontend_parameters *fe_params)
+{
+ struct tda10086_state *state = fe->demodulator_priv;
+ int ret;
+ u32 freq = 0;
+ int freqoff;
+
+ dprintk ("%s\n", __FUNCTION__);
+
+ // set params
+ if (fe->ops.tuner_ops.set_params) {
+ fe->ops.tuner_ops.set_params(fe, fe_params);
+ if (fe->ops.i2c_gate_ctrl)
+ fe->ops.i2c_gate_ctrl(fe, 0);
+
+ if (fe->ops.tuner_ops.get_frequency)
+ fe->ops.tuner_ops.get_frequency(fe, &freq);
+ if (fe->ops.i2c_gate_ctrl)
+ fe->ops.i2c_gate_ctrl(fe, 0);
+ }
+
+ // calcluate the frequency offset (in *Hz* not kHz)
+ freqoff = fe_params->frequency - freq;
+ freqoff = ((1<<16) * freqoff) / (SACLK/1000);
+ tda10086_write_byte(state, 0x3d, 0x80 | ((freqoff >> 8) & 0x7f));
+ tda10086_write_byte(state, 0x3e, freqoff);
+
+ if ((ret = tda10086_set_inversion(state, fe_params)) < 0)
+ return ret;
+ if ((ret = tda10086_set_symbol_rate(state, fe_params)) < 0)
+ return ret;
+ if ((ret = tda10086_set_fec(state, fe_params)) < 0)
+ return ret;
+
+ // soft reset + disable TS output until lock
+ tda10086_write_mask(state, 0x10, 0x40, 0x40);
+ tda10086_write_mask(state, 0x00, 0x01, 0x00);
+
+ state->symbol_rate = fe_params->u.qpsk.symbol_rate;
+ state->frequency = fe_params->frequency;
+ return 0;
+}
+
+static int tda10086_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *fe_params)
+{
+ struct tda10086_state* state = fe->demodulator_priv;
+ u8 val;
+ int tmp;
+ u64 tmp64;
+
+ dprintk ("%s\n", __FUNCTION__);
+
+ // calculate the updated frequency (note: we convert from Hz->kHz)
+ tmp64 = tda10086_read_byte(state, 0x52);
+ tmp64 |= (tda10086_read_byte(state, 0x51) << 8);
+ if (tmp64 & 0x8000)
+ tmp64 |= 0xffffffffffff0000ULL;
+ tmp64 = (tmp64 * (SACLK/1000ULL));
+ do_div(tmp64, (1ULL<<15) * (1ULL<<1));
+ fe_params->frequency = (int) state->frequency + (int) tmp64;
+
+ // the inversion
+ val = tda10086_read_byte(state, 0x0c);
+ if (val & 0x80) {
+ switch(val & 0x40) {
+ case 0x00:
+ fe_params->inversion = INVERSION_OFF;
+ if (state->config->invert)
+ fe_params->inversion = INVERSION_ON;
+ break;
+ default:
+ fe_params->inversion = INVERSION_ON;
+ if (state->config->invert)
+ fe_params->inversion = INVERSION_OFF;
+ break;
+ }
+ } else {
+ tda10086_read_byte(state, 0x0f);
+ switch(val & 0x02) {
+ case 0x00:
+ fe_params->inversion = INVERSION_OFF;
+ if (state->config->invert)
+ fe_params->inversion = INVERSION_ON;
+ break;
+ default:
+ fe_params->inversion = INVERSION_ON;
+ if (state->config->invert)
+ fe_params->inversion = INVERSION_OFF;
+ break;
+ }
+ }
+
+ // calculate the updated symbol rate
+ tmp = tda10086_read_byte(state, 0x1d);
+ if (tmp & 0x80)
+ tmp |= 0xffffff00;
+ tmp = (tmp * 480 * (1<<1)) / 128;
+ tmp = ((state->symbol_rate/1000) * tmp) / (1000000/1000);
+ fe_params->u.qpsk.symbol_rate = state->symbol_rate + tmp;
+
+ // the FEC
+ val = (tda10086_read_byte(state, 0x0d) & 0x70) >> 4;
+ switch(val) {
+ case 0x00:
+ fe_params->u.qpsk.fec_inner = FEC_1_2;
+ break;
+ case 0x01:
+ fe_params->u.qpsk.fec_inner = FEC_2_3;
+ break;
+ case 0x02:
+ fe_params->u.qpsk.fec_inner = FEC_3_4;
+ break;
+ case 0x03:
+ fe_params->u.qpsk.fec_inner = FEC_4_5;
+ break;
+ case 0x04:
+ fe_params->u.qpsk.fec_inner = FEC_5_6;
+ break;
+ case 0x05:
+ fe_params->u.qpsk.fec_inner = FEC_6_7;
+ break;
+ case 0x06:
+ fe_params->u.qpsk.fec_inner = FEC_7_8;
+ break;
+ case 0x07:
+ fe_params->u.qpsk.fec_inner = FEC_8_9;
+ break;
+ }
+
+ return 0;
+}
+
+static int tda10086_read_status(struct dvb_frontend* fe, fe_status_t *fe_status)
+{
+ struct tda10086_state* state = fe->demodulator_priv;
+ u8 val;
+
+ dprintk ("%s\n", __FUNCTION__);
+
+ val = tda10086_read_byte(state, 0x0e);
+ *fe_status = 0;
+ if (val & 0x01)
+ *fe_status |= FE_HAS_SIGNAL;
+ if (val & 0x02)
+ *fe_status |= FE_HAS_CARRIER;
+ if (val & 0x04)
+ *fe_status |= FE_HAS_VITERBI;
+ if (val & 0x08)
+ *fe_status |= FE_HAS_SYNC;
+ if (val & 0x10)
+ *fe_status |= FE_HAS_LOCK;
+
+ return 0;
+}
+
+static int tda10086_read_signal_strength(struct dvb_frontend* fe, u16 * signal)
+{
+ struct tda10086_state* state = fe->demodulator_priv;
+ u8 _str;
+
+ dprintk ("%s\n", __FUNCTION__);
+
+ _str = tda10086_read_byte(state, 0x43);
+ *signal = (_str << 8) | _str;
+
+ return 0;
+}
+
+static int tda10086_read_snr(struct dvb_frontend* fe, u16 * snr)
+{
+ struct tda10086_state* state = fe->demodulator_priv;
+ u8 _snr;
+
+ dprintk ("%s\n", __FUNCTION__);
+
+ _snr = tda10086_read_byte(state, 0x1c);
+ *snr = (_snr << 8) | _snr;
+
+ return 0;
+}
+
+static int tda10086_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
+{
+ struct tda10086_state* state = fe->demodulator_priv;
+
+ dprintk ("%s\n", __FUNCTION__);
+
+ // read it
+ *ucblocks = tda10086_read_byte(state, 0x18) & 0x7f;
+
+ // reset counter
+ tda10086_write_byte(state, 0x18, 0x00);
+ tda10086_write_byte(state, 0x18, 0x80);
+
+ return 0;
+}
+
+static int tda10086_read_ber(struct dvb_frontend* fe, u32* ber)
+{
+ struct tda10086_state* state = fe->demodulator_priv;
+
+ dprintk ("%s\n", __FUNCTION__);
+
+ // read it
+ *ber = 0;
+ *ber |= tda10086_read_byte(state, 0x15);
+ *ber |= tda10086_read_byte(state, 0x16) << 8;
+ *ber |= (tda10086_read_byte(state, 0x17) & 0xf) << 16;
+
+ return 0;
+}
+
+static int tda10086_sleep(struct dvb_frontend* fe)
+{
+ struct tda10086_state* state = fe->demodulator_priv;
+
+ dprintk ("%s\n", __FUNCTION__);
+
+ tda10086_write_mask(state, 0x00, 0x08, 0x08);
+
+ return 0;
+}
+
+static int tda10086_i2c_gate_ctrl(struct dvb_frontend* fe, int enable)
+{
+ struct tda10086_state* state = fe->demodulator_priv;
+
+ dprintk ("%s\n", __FUNCTION__);
+
+ if (enable) {
+ tda10086_write_mask(state, 0x00, 0x10, 0x10);
+ } else {
+ tda10086_write_mask(state, 0x00, 0x10, 0x00);
+ }
+
+ return 0;
+}
+
+static int tda10086_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* fesettings)
+{
+ if (fesettings->parameters.u.qpsk.symbol_rate > 20000000) {
+ fesettings->min_delay_ms = 50;
+ fesettings->step_size = 2000;
+ fesettings->max_drift = 8000;
+ } else if (fesettings->parameters.u.qpsk.symbol_rate > 12000000) {
+ fesettings->min_delay_ms = 100;
+ fesettings->step_size = 1500;
+ fesettings->max_drift = 9000;
+ } else if (fesettings->parameters.u.qpsk.symbol_rate > 8000000) {
+ fesettings->min_delay_ms = 100;
+ fesettings->step_size = 1000;
+ fesettings->max_drift = 8000;
+ } else if (fesettings->parameters.u.qpsk.symbol_rate > 4000000) {
+ fesettings->min_delay_ms = 100;
+ fesettings->step_size = 500;
+ fesettings->max_drift = 7000;
+ } else if (fesettings->parameters.u.qpsk.symbol_rate > 2000000) {
+ fesettings->min_delay_ms = 200;
+ fesettings->step_size = (fesettings->parameters.u.qpsk.symbol_rate / 8000);
+ fesettings->max_drift = 14 * fesettings->step_size;
+ } else {
+ fesettings->min_delay_ms = 200;
+ fesettings->step_size = (fesettings->parameters.u.qpsk.symbol_rate / 8000);
+ fesettings->max_drift = 18 * fesettings->step_size;
+ }
+
+ return 0;
+}
+
+static void tda10086_release(struct dvb_frontend* fe)
+{
+ struct tda10086_state *state = fe->demodulator_priv;
+ tda10086_sleep(fe);
+ kfree(state);
+}
+
+static struct dvb_frontend_ops tda10086_ops = {
+
+ .info = {
+ .name = "Philips TDA10086 DVB-S",
+ .type = FE_QPSK,
+ .frequency_min = 950000,
+ .frequency_max = 2150000,
+ .frequency_stepsize = 125, /* kHz for QPSK frontends */
+ .symbol_rate_min = 1000000,
+ .symbol_rate_max = 45000000,
+ .caps = FE_CAN_INVERSION_AUTO |
+ FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
+ FE_CAN_FEC_5_6 | FE_CAN_FEC_6_7 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
+ FE_CAN_QPSK
+ },
+
+ .release = tda10086_release,
+
+ .init = tda10086_init,
+ .sleep = tda10086_sleep,
+ .i2c_gate_ctrl = tda10086_i2c_gate_ctrl,
+
+ .set_frontend = tda10086_set_frontend,
+ .get_frontend = tda10086_get_frontend,
+ .get_tune_settings = tda10086_get_tune_settings,
+
+ .read_status = tda10086_read_status,
+ .read_ber = tda10086_read_ber,
+ .read_signal_strength = tda10086_read_signal_strength,
+ .read_snr = tda10086_read_snr,
+ .read_ucblocks = tda10086_read_ucblocks,
+
+ .diseqc_send_master_cmd = tda10086_send_master_cmd,
+ .diseqc_send_burst = tda10086_send_burst,
+ .set_tone = tda10086_set_tone,
+};
+
+struct dvb_frontend* tda10086_attach(const struct tda10086_config* config,
+ struct i2c_adapter* i2c)
+{
+ struct tda10086_state *state;
+
+ dprintk ("%s\n", __FUNCTION__);
+
+ /* allocate memory for the internal state */
+ state = kmalloc(sizeof(struct tda10086_state), GFP_KERNEL);
+ if (!state)
+ return NULL;
+
+ /* setup the state */
+ state->config = config;
+ state->i2c = i2c;
+
+ /* check if the demod is there */
+ if (tda10086_read_byte(state, 0x1e) != 0xe1) {
+ kfree(state);
+ return NULL;
+ }
+
+ /* create dvb_frontend */
+ memcpy(&state->frontend.ops, &tda10086_ops, sizeof(struct dvb_frontend_ops));
+ state->frontend.demodulator_priv = state;
+ return &state->frontend;
+}
+
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
+
+MODULE_DESCRIPTION("Philips TDA10086 DVB-S Demodulator");
+MODULE_AUTHOR("Andrew de Quincey");
+MODULE_LICENSE("GPL");
+
+EXPORT_SYMBOL(tda10086_attach);
diff --git a/drivers/media/dvb/frontends/tda10086.h b/drivers/media/dvb/frontends/tda10086.h
new file mode 100644
index 000000000000..e8061db11123
--- /dev/null
+++ b/drivers/media/dvb/frontends/tda10086.h
@@ -0,0 +1,41 @@
+ /*
+ Driver for Philips tda10086 DVBS Frontend
+
+ (c) 2006 Andrew de Quincey
+
+ 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ */
+
+#ifndef TDA10086_H
+#define TDA10086_H
+
+#include <linux/dvb/frontend.h>
+#include <linux/firmware.h>
+
+struct tda10086_config
+{
+ /* the demodulator's i2c address */
+ u8 demod_address;
+
+ /* does the "inversion" need inverted? */
+ u8 invert;
+};
+
+extern struct dvb_frontend* tda10086_attach(const struct tda10086_config* config,
+ struct i2c_adapter* i2c);
+
+#endif // TDA10086_H
diff --git a/drivers/media/dvb/frontends/tda8083.h b/drivers/media/dvb/frontends/tda8083.h
index e7a48f61ea2c..aae15bdce6eb 100644
--- a/drivers/media/dvb/frontends/tda8083.h
+++ b/drivers/media/dvb/frontends/tda8083.h
@@ -35,7 +35,16 @@ struct tda8083_config
u8 demod_address;
};
+#if defined(CONFIG_DVB_TDA8083) || defined(CONFIG_DVB_TDA8083_MODULE)
extern struct dvb_frontend* tda8083_attach(const struct tda8083_config* config,
struct i2c_adapter* i2c);
+#else
+static inline struct dvb_frontend* tda8083_attach(const struct tda8083_config* config,
+ struct i2c_adapter* i2c)
+{
+ printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__);
+ return NULL;
+}
+#endif // CONFIG_DVB_TDA8083
#endif // TDA8083_H
diff --git a/drivers/media/dvb/frontends/tda826x.c b/drivers/media/dvb/frontends/tda826x.c
new file mode 100644
index 000000000000..eeab26bd36ed
--- /dev/null
+++ b/drivers/media/dvb/frontends/tda826x.c
@@ -0,0 +1,173 @@
+ /*
+ Driver for Philips tda8262/tda8263 DVBS Silicon tuners
+
+ (c) 2006 Andrew de Quincey
+
+ 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ */
+
+#include <linux/module.h>
+#include <linux/dvb/frontend.h>
+#include <asm/types.h>
+
+#include "tda826x.h"
+
+static int debug = 0;
+#define dprintk(args...) \
+ do { \
+ if (debug) printk(KERN_DEBUG "tda826x: " args); \
+ } while (0)
+
+struct tda826x_priv {
+ /* i2c details */
+ int i2c_address;
+ struct i2c_adapter *i2c;
+ u8 has_loopthrough:1;
+ u32 frequency;
+};
+
+static int tda826x_release(struct dvb_frontend *fe)
+{
+ if (fe->tuner_priv)
+ kfree(fe->tuner_priv);
+ fe->tuner_priv = NULL;
+ return 0;
+}
+
+static int tda826x_sleep(struct dvb_frontend *fe)
+{
+ struct tda826x_priv *priv = fe->tuner_priv;
+ int ret;
+ u8 buf [] = { 0x00, 0x8d };
+ struct i2c_msg msg = { .addr = priv->i2c_address, .flags = 0, .buf = buf, .len = 2 };
+
+ dprintk("%s:\n", __FUNCTION__);
+
+ if (!priv->has_loopthrough)
+ buf[1] = 0xad;
+
+ if (fe->ops.i2c_gate_ctrl)
+ fe->ops.i2c_gate_ctrl(fe, 1);
+ if ((ret = i2c_transfer (priv->i2c, &msg, 1)) != 1) {
+ dprintk("%s: i2c error\n", __FUNCTION__);
+ }
+ if (fe->ops.i2c_gate_ctrl)
+ fe->ops.i2c_gate_ctrl(fe, 0);
+
+ return (ret == 1) ? 0 : ret;
+}
+
+static int tda826x_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *params)
+{
+ struct tda826x_priv *priv = fe->tuner_priv;
+ int ret;
+ u32 div;
+ u8 buf [11];
+ struct i2c_msg msg = { .addr = priv->i2c_address, .flags = 0, .buf = buf, .len = 11 };
+
+ dprintk("%s:\n", __FUNCTION__);
+
+ div = (params->frequency + (1000-1)) / 1000;
+
+ buf[0] = 0x00; // subaddress
+ buf[1] = 0x09; // powerdown RSSI + the magic value 1
+ if (!priv->has_loopthrough)
+ buf[1] |= 0x20; // power down loopthrough if not needed
+ buf[2] = (1<<5) | 0x0b; // 1Mhz + 0.45 VCO
+ buf[3] = div >> 7;
+ buf[4] = div << 1;
+ buf[5] = 0xff; // basedband filter to max
+ buf[6] = 0xfe; // gains at max + no RF attenuation
+ buf[7] = 0x83; // charge pumps at high, tests off
+ buf[8] = 0x80; // recommended value 4 for AMPVCO + disable ports.
+ buf[9] = 0x1a; // normal caltime + recommended values for SELTH + SELVTL
+ buf[10] = 0xd4; // recommended value 13 for BBIAS + unknown bit set on
+
+ if (fe->ops.i2c_gate_ctrl)
+ fe->ops.i2c_gate_ctrl(fe, 1);
+ if ((ret = i2c_transfer (priv->i2c, &msg, 1)) != 1) {
+ dprintk("%s: i2c error\n", __FUNCTION__);
+ }
+ if (fe->ops.i2c_gate_ctrl)
+ fe->ops.i2c_gate_ctrl(fe, 0);
+
+ priv->frequency = div * 1000;
+
+ return (ret == 1) ? 0 : ret;
+}
+
+static int tda826x_get_frequency(struct dvb_frontend *fe, u32 *frequency)
+{
+ struct tda826x_priv *priv = fe->tuner_priv;
+ *frequency = priv->frequency;
+ return 0;
+}
+
+static struct dvb_tuner_ops tda826x_tuner_ops = {
+ .info = {
+ .name = "Philips TDA826X",
+ .frequency_min = 950000,
+ .frequency_min = 2175000
+ },
+ .release = tda826x_release,
+ .sleep = tda826x_sleep,
+ .set_params = tda826x_set_params,
+ .get_frequency = tda826x_get_frequency,
+};
+
+struct dvb_frontend *tda826x_attach(struct dvb_frontend *fe, int addr, struct i2c_adapter *i2c, int has_loopthrough)
+{
+ struct tda826x_priv *priv = NULL;
+ u8 b1 [] = { 0, 0 };
+ struct i2c_msg msg = { .addr = addr, .flags = I2C_M_RD, .buf = b1, .len = 2 };
+ int ret;
+
+ dprintk("%s:\n", __FUNCTION__);
+
+ if (fe->ops.i2c_gate_ctrl)
+ fe->ops.i2c_gate_ctrl(fe, 1);
+ ret = i2c_transfer (i2c, &msg, 1);
+ if (fe->ops.i2c_gate_ctrl)
+ fe->ops.i2c_gate_ctrl(fe, 0);
+
+ if (ret != 1)
+ return NULL;
+ if (!(b1[1] & 0x80))
+ return NULL;
+
+ priv = kzalloc(sizeof(struct tda826x_priv), GFP_KERNEL);
+ if (priv == NULL)
+ return NULL;
+
+ priv->i2c_address = addr;
+ priv->i2c = i2c;
+ priv->has_loopthrough = has_loopthrough;
+
+ memcpy(&fe->ops.tuner_ops, &tda826x_tuner_ops, sizeof(struct dvb_tuner_ops));
+
+ fe->tuner_priv = priv;
+
+ return fe;
+}
+EXPORT_SYMBOL(tda826x_attach);
+
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
+
+MODULE_DESCRIPTION("DVB TDA826x driver");
+MODULE_AUTHOR("Andrew de Quincey");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/frontends/tda826x.h b/drivers/media/dvb/frontends/tda826x.h
new file mode 100644
index 000000000000..3307607632b0
--- /dev/null
+++ b/drivers/media/dvb/frontends/tda826x.h
@@ -0,0 +1,40 @@
+ /*
+ Driver for Philips tda8262/tda8263 DVBS Silicon tuners
+
+ (c) 2006 Andrew de Quincey
+
+ 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ */
+
+#ifndef __DVB_TDA826X_H__
+#define __DVB_TDA826X_H__
+
+#include <linux/i2c.h>
+#include "dvb_frontend.h"
+
+/**
+ * Attach a tda826x tuner to the supplied frontend structure.
+ *
+ * @param fe Frontend to attach to.
+ * @param addr i2c address of the tuner.
+ * @param i2c i2c adapter to use.
+ * @param has_loopthrough Set to 1 if the card has a loopthrough RF connector.
+ * @return FE pointer on success, NULL on failure.
+ */
+extern struct dvb_frontend *tda826x_attach(struct dvb_frontend *fe, int addr, struct i2c_adapter *i2c, int has_loopthrough);
+
+#endif
diff --git a/drivers/media/dvb/frontends/tua6100.c b/drivers/media/dvb/frontends/tua6100.c
new file mode 100644
index 000000000000..88554393a9bf
--- /dev/null
+++ b/drivers/media/dvb/frontends/tua6100.c
@@ -0,0 +1,205 @@
+/**
+ * Driver for Infineon tua6100 pll.
+ *
+ * (c) 2006 Andrew de Quincey
+ *
+ * Based on code found in budget-av.c, which has the following:
+ * Compiled from various sources by Michael Hunold <michael@mihu.de>
+ *
+ * CI interface support (c) 2004 Olivier Gournet <ogournet@anevia.com> &
+ * Andrew de Quincey <adq_dvb@lidskialf.net>
+ *
+ * Copyright (C) 2002 Ralph Metzler <rjkm@metzlerbros.de>
+ *
+ * Copyright (C) 1999-2002 Ralph Metzler
+ * & Marcus Metzler for convergence integrated media GmbH
+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/module.h>
+#include <linux/dvb/frontend.h>
+#include <asm/types.h>
+
+#include "tua6100.h"
+
+struct tua6100_priv {
+ /* i2c details */
+ int i2c_address;
+ struct i2c_adapter *i2c;
+ u32 frequency;
+};
+
+static int tua6100_release(struct dvb_frontend *fe)
+{
+ if (fe->tuner_priv)
+ kfree(fe->tuner_priv);
+ fe->tuner_priv = NULL;
+ return 0;
+}
+
+static int tua6100_sleep(struct dvb_frontend *fe)
+{
+ struct tua6100_priv *priv = fe->tuner_priv;
+ int ret;
+ u8 reg0[] = { 0x00, 0x00 };
+ struct i2c_msg msg = { .addr = priv->i2c_address, .flags = 0, .buf = reg0, .len = 2 };
+
+ if (fe->ops.i2c_gate_ctrl)
+ fe->ops.i2c_gate_ctrl(fe, 1);
+ if ((ret = i2c_transfer (priv->i2c, &msg, 1)) != 1) {
+ printk("%s: i2c error\n", __FUNCTION__);
+ }
+ if (fe->ops.i2c_gate_ctrl)
+ fe->ops.i2c_gate_ctrl(fe, 0);
+
+ return (ret == 1) ? 0 : ret;
+}
+
+static int tua6100_set_params(struct dvb_frontend *fe,
+ struct dvb_frontend_parameters *params)
+{
+ struct tua6100_priv *priv = fe->tuner_priv;
+ u32 div;
+ u32 prediv;
+ u8 reg0[] = { 0x00, 0x00 };
+ u8 reg1[] = { 0x01, 0x00, 0x00, 0x00 };
+ u8 reg2[] = { 0x02, 0x00, 0x00 };
+ struct i2c_msg msg0 = { .addr = priv->i2c_address, .flags = 0, .buf = reg0, .len = 2 };
+ struct i2c_msg msg1 = { .addr = priv->i2c_address, .flags = 0, .buf = reg1, .len = 4 };
+ struct i2c_msg msg2 = { .addr = priv->i2c_address, .flags = 0, .buf = reg2, .len = 3 };
+
+#define _R 4
+#define _P 32
+#define _ri 4000000
+
+ // setup register 0
+ if (params->frequency < 2000000) {
+ reg0[1] = 0x03;
+ } else {
+ reg0[1] = 0x07;
+ }
+
+ // setup register 1
+ if (params->frequency < 1630000) {
+ reg1[1] = 0x2c;
+ } else {
+ reg1[1] = 0x0c;
+ }
+ if (_P == 64)
+ reg1[1] |= 0x40;
+ if (params->frequency >= 1525000)
+ reg1[1] |= 0x80;
+
+ // register 2
+ reg2[1] = (_R >> 8) & 0x03;
+ reg2[2] = _R;
+ if (params->frequency < 1455000) {
+ reg2[1] |= 0x1c;
+ } else if (params->frequency < 1630000) {
+ reg2[1] |= 0x0c;
+ } else {
+ reg2[1] |= 0x1c;
+ }
+
+ // The N divisor ratio (note: params->frequency is in kHz, but we need it in Hz)
+ prediv = (params->frequency * _R) / (_ri / 1000);
+ div = prediv / _P;
+ reg1[1] |= (div >> 9) & 0x03;
+ reg1[2] = div >> 1;
+ reg1[3] = (div << 7);
+ priv->frequency = ((div * _P) * (_ri / 1000)) / _R;
+
+ // Finally, calculate and store the value for A
+ reg1[3] |= (prediv - (div*_P)) & 0x7f;
+
+#undef _R
+#undef _P
+#undef _ri
+
+ if (fe->ops.i2c_gate_ctrl)
+ fe->ops.i2c_gate_ctrl(fe, 1);
+ if (i2c_transfer(priv->i2c, &msg0, 1) != 1)
+ return -EIO;
+
+ if (fe->ops.i2c_gate_ctrl)
+ fe->ops.i2c_gate_ctrl(fe, 1);
+ if (i2c_transfer(priv->i2c, &msg2, 1) != 1)
+ return -EIO;
+
+ if (fe->ops.i2c_gate_ctrl)
+ fe->ops.i2c_gate_ctrl(fe, 1);
+ if (i2c_transfer(priv->i2c, &msg1, 1) != 1)
+ return -EIO;
+
+ if (fe->ops.i2c_gate_ctrl)
+ fe->ops.i2c_gate_ctrl(fe, 0);
+
+ return 0;
+}
+
+static int tua6100_get_frequency(struct dvb_frontend *fe, u32 *frequency)
+{
+ struct tua6100_priv *priv = fe->tuner_priv;
+ *frequency = priv->frequency;
+ return 0;
+}
+
+static struct dvb_tuner_ops tua6100_tuner_ops = {
+ .info = {
+ .name = "Infineon TUA6100",
+ .frequency_min = 950000,
+ .frequency_max = 2150000,
+ .frequency_step = 1000,
+ },
+ .release = tua6100_release,
+ .sleep = tua6100_sleep,
+ .set_params = tua6100_set_params,
+ .get_frequency = tua6100_get_frequency,
+};
+
+struct dvb_frontend *tua6100_attach(struct dvb_frontend *fe, int addr, struct i2c_adapter *i2c)
+{
+ struct tua6100_priv *priv = NULL;
+ u8 b1 [] = { 0x80 };
+ u8 b2 [] = { 0x00 };
+ struct i2c_msg msg [] = { { .addr = addr, .flags = 0, .buf = b1, .len = 1 },
+ { .addr = addr, .flags = I2C_M_RD, .buf = b2, .len = 1 } };
+ int ret;
+
+ if (fe->ops.i2c_gate_ctrl)
+ fe->ops.i2c_gate_ctrl(fe, 1);
+ ret = i2c_transfer (i2c, msg, 2);
+ if (fe->ops.i2c_gate_ctrl)
+ fe->ops.i2c_gate_ctrl(fe, 0);
+
+ if (ret != 2)
+ return NULL;
+
+ priv = kzalloc(sizeof(struct tua6100_priv), GFP_KERNEL);
+ if (priv == NULL)
+ return NULL;
+
+ priv->i2c_address = addr;
+ priv->i2c = i2c;
+
+ memcpy(&fe->ops.tuner_ops, &tua6100_tuner_ops, sizeof(struct dvb_tuner_ops));
+ fe->tuner_priv = priv;
+ return fe;
+}
+EXPORT_SYMBOL(tua6100_attach);
+
+MODULE_DESCRIPTION("DVB tua6100 driver");
+MODULE_AUTHOR("Andrew de Quincey");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/frontends/tua6100.h b/drivers/media/dvb/frontends/tua6100.h
new file mode 100644
index 000000000000..8f98033ffa7b
--- /dev/null
+++ b/drivers/media/dvb/frontends/tua6100.h
@@ -0,0 +1,47 @@
+/**
+ * Driver for Infineon tua6100 PLL.
+ *
+ * (c) 2006 Andrew de Quincey
+ *
+ * Based on code found in budget-av.c, which has the following:
+ * Compiled from various sources by Michael Hunold <michael@mihu.de>
+ *
+ * CI interface support (c) 2004 Olivier Gournet <ogournet@anevia.com> &
+ * Andrew de Quincey <adq_dvb@lidskialf.net>
+ *
+ * Copyright (C) 2002 Ralph Metzler <rjkm@metzlerbros.de>
+ *
+ * Copyright (C) 1999-2002 Ralph Metzler
+ * & Marcus Metzler for convergence integrated media GmbH
+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef __DVB_TUA6100_H__
+#define __DVB_TUA6100_H__
+
+#include <linux/i2c.h>
+#include "dvb_frontend.h"
+
+#if defined(CONFIG_DVB_TUA6100) || defined(CONFIG_DVB_TUA6100_MODULE)
+extern struct dvb_frontend *tua6100_attach(struct dvb_frontend *fe, int addr, struct i2c_adapter *i2c);
+#else
+static inline struct dvb_frontend* tua6100_attach(struct dvb_frontend *fe, int addr, struct i2c_adapter *i2c)
+{
+ printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__);
+ return NULL;
+}
+#endif // CONFIG_DVB_TUA6100
+
+#endif
diff --git a/drivers/media/dvb/frontends/ves1820.h b/drivers/media/dvb/frontends/ves1820.h
index 520f09522fbb..f0c9dded39d7 100644
--- a/drivers/media/dvb/frontends/ves1820.h
+++ b/drivers/media/dvb/frontends/ves1820.h
@@ -41,7 +41,16 @@ struct ves1820_config
u8 selagc:1;
};
+#if defined(CONFIG_DVB_VES1820) || defined(CONFIG_DVB_VES1820_MODULE)
extern struct dvb_frontend* ves1820_attach(const struct ves1820_config* config,
struct i2c_adapter* i2c, u8 pwm);
+#else
+static inline struct dvb_frontend* ves1820_attach(const struct ves1820_config* config,
+ struct i2c_adapter* i2c, u8 pwm)
+{
+ printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__);
+ return NULL;
+}
+#endif // CONFIG_DVB_VES1820
#endif // VES1820_H
diff --git a/drivers/media/dvb/frontends/ves1x93.h b/drivers/media/dvb/frontends/ves1x93.h
index ba88ae0855c9..395fed39b286 100644
--- a/drivers/media/dvb/frontends/ves1x93.h
+++ b/drivers/media/dvb/frontends/ves1x93.h
@@ -40,7 +40,16 @@ struct ves1x93_config
u8 invert_pwm:1;
};
+#if defined(CONFIG_DVB_VES1X93) || defined(CONFIG_DVB_VES1X93_MODULE)
extern struct dvb_frontend* ves1x93_attach(const struct ves1x93_config* config,
struct i2c_adapter* i2c);
+#else
+static inline struct dvb_frontend* ves1x93_attach(const struct ves1x93_config* config,
+ struct i2c_adapter* i2c)
+{
+ printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__);
+ return NULL;
+}
+#endif // CONFIG_DVB_VES1X93
#endif // VES1X93_H
diff --git a/drivers/media/dvb/frontends/zl10353.c b/drivers/media/dvb/frontends/zl10353.c
index 2b95e8b6cd39..0e9b59af271e 100644
--- a/drivers/media/dvb/frontends/zl10353.c
+++ b/drivers/media/dvb/frontends/zl10353.c
@@ -140,6 +140,8 @@ static int zl10353_set_parameters(struct dvb_frontend *fe,
zl10353_single_write(fe, 0x5E, 0x00);
zl10353_single_write(fe, 0x65, 0x5A);
zl10353_single_write(fe, 0x66, 0xE9);
+ zl10353_single_write(fe, 0x6C, 0xCD);
+ zl10353_single_write(fe, 0x6D, 0x7E);
zl10353_single_write(fe, 0x62, 0x0A);
// if there is no attached secondary tuner, we call set_params to program
@@ -168,6 +170,7 @@ static int zl10353_set_parameters(struct dvb_frontend *fe,
// even if there isn't a PLL attached to the secondary bus
zl10353_write(fe, pllbuf, sizeof(pllbuf));
+ zl10353_single_write(fe, 0x5F, 0x13);
zl10353_single_write(fe, 0x70, 0x01);
udelay(250);
zl10353_single_write(fe, 0xE4, 0x00);
@@ -243,9 +246,12 @@ static int zl10353_init(struct dvb_frontend *fe)
if (debug_regs)
zl10353_dump_regs(fe);
+ if (state->config.parallel_ts)
+ zl10353_reset_attach[2] &= ~0x20;
/* Do a "hard" reset if not already done */
- if (zl10353_read_register(state, 0x50) != 0x03) {
+ if (zl10353_read_register(state, 0x50) != zl10353_reset_attach[1] ||
+ zl10353_read_register(state, 0x51) != zl10353_reset_attach[2]) {
rc = zl10353_write(fe, zl10353_reset_attach,
sizeof(zl10353_reset_attach));
if (debug_regs)
@@ -258,7 +264,6 @@ static int zl10353_init(struct dvb_frontend *fe)
static void zl10353_release(struct dvb_frontend *fe)
{
struct zl10353_state *state = fe->demodulator_priv;
-
kfree(state);
}
@@ -314,6 +319,7 @@ static struct dvb_frontend_ops zl10353_ops = {
.init = zl10353_init,
.sleep = zl10353_sleep,
+ .write = zl10353_write,
.set_frontend = zl10353_set_parameters,
.get_tune_settings = zl10353_get_tune_settings,
@@ -330,4 +336,3 @@ MODULE_AUTHOR("Chris Pascoe");
MODULE_LICENSE("GPL");
EXPORT_SYMBOL(zl10353_attach);
-EXPORT_SYMBOL(zl10353_write);
diff --git a/drivers/media/dvb/frontends/zl10353.h b/drivers/media/dvb/frontends/zl10353.h
index 9770cb840cfc..79a947215c4d 100644
--- a/drivers/media/dvb/frontends/zl10353.h
+++ b/drivers/media/dvb/frontends/zl10353.h
@@ -31,11 +31,21 @@ struct zl10353_config
/* set if no pll is connected to the secondary i2c bus */
int no_tuner;
+
+ /* set if parallel ts output is required */
+ int parallel_ts;
};
+#if defined(CONFIG_DVB_ZL10353) || defined(CONFIG_DVB_ZL10353_MODULE)
extern struct dvb_frontend* zl10353_attach(const struct zl10353_config *config,
struct i2c_adapter *i2c);
-
-extern int zl10353_write(struct dvb_frontend *fe, u8 *ibuf, int ilen);
+#else
+static inline struct dvb_frontend* zl10353_attach(const struct zl10353_config *config,
+ struct i2c_adapter *i2c)
+{
+ printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__);
+ return NULL;
+}
+#endif // CONFIG_DVB_ZL10353
#endif /* ZL10353_H */
diff --git a/drivers/media/dvb/ttpci/Kconfig b/drivers/media/dvb/ttpci/Kconfig
index 5fb097595cfb..95531a624991 100644
--- a/drivers/media/dvb/ttpci/Kconfig
+++ b/drivers/media/dvb/ttpci/Kconfig
@@ -1,17 +1,17 @@
config DVB_AV7110
tristate "AV7110 cards"
depends on DVB_CORE && PCI && I2C && VIDEO_V4L1
- select FW_LOADER
+ select FW_LOADER if !DVB_AV7110_FIRMWARE
select VIDEO_SAA7146_VV
select DVB_PLL
- select DVB_VES1820
- select DVB_VES1X93
- select DVB_STV0299
- select DVB_TDA8083
- select DVB_SP8870
- select DVB_STV0297
- select DVB_L64781
- select DVB_LNBP21
+ select DVB_VES1820 if !DVB_FE_CUSTOMISE
+ select DVB_VES1X93 if !DVB_FE_CUSTOMISE
+ select DVB_STV0299 if !DVB_FE_CUSTOMISE
+ select DVB_TDA8083 if !DVB_FE_CUSTOMISE
+ select DVB_SP8870 if !DVB_FE_CUSTOMISE
+ select DVB_STV0297 if !DVB_FE_CUSTOMISE
+ select DVB_L64781 if !DVB_FE_CUSTOMISE
+ select DVB_LNBP21 if !DVB_FE_CUSTOMISE
help
Support for SAA7146 and AV7110 based DVB cards as produced
by Fujitsu-Siemens, Technotrend, Hauppauge and others.
@@ -63,14 +63,16 @@ config DVB_BUDGET
depends on DVB_CORE && PCI && I2C && VIDEO_V4L1
select VIDEO_SAA7146
select DVB_PLL
- select DVB_STV0299
- select DVB_VES1X93
- select DVB_VES1820
- select DVB_L64781
- select DVB_TDA8083
- select DVB_TDA10021
- select DVB_S5H1420
- select DVB_LNBP21
+ select DVB_STV0299 if !DVB_FE_CUSTOMISE
+ select DVB_VES1X93 if !DVB_FE_CUSTOMISE
+ select DVB_VES1820 if !DVB_FE_CUSTOMISE
+ select DVB_L64781 if !DVB_FE_CUSTOMISE
+ select DVB_TDA8083 if !DVB_FE_CUSTOMISE
+ select DVB_TDA10021 if !DVB_FE_CUSTOMISE
+ select DVB_S5H1420 if !DVB_FE_CUSTOMISE
+ select DVB_TDA10086 if !DVB_FE_CUSTOMISE
+ select DVB_TDA826X if !DVB_FE_CUSTOMISE
+ select DVB_LNBP21 if !DVB_FE_CUSTOMISE
help
Support for simple SAA7146 based DVB cards
(so called Budget- or Nova-PCI cards) without onboard
@@ -86,10 +88,10 @@ config DVB_BUDGET_CI
depends on DVB_CORE && PCI && I2C && VIDEO_V4L1
select VIDEO_SAA7146
select DVB_PLL
- select DVB_STV0297
- select DVB_STV0299
- select DVB_TDA1004X
- select DVB_LNBP21
+ select DVB_STV0297 if !DVB_FE_CUSTOMISE
+ select DVB_STV0299 if !DVB_FE_CUSTOMISE
+ select DVB_TDA1004X if !DVB_FE_CUSTOMISE
+ select DVB_LNBP21 if !DVB_FE_CUSTOMISE
help
Support for simple SAA7146 based DVB cards
(so called Budget- or Nova-PCI cards) without onboard
@@ -108,9 +110,10 @@ config DVB_BUDGET_AV
depends on DVB_CORE && PCI && I2C && VIDEO_V4L1
select VIDEO_SAA7146_VV
select DVB_PLL
- select DVB_STV0299
- select DVB_TDA1004X
- select DVB_TDA10021
+ select DVB_STV0299 if !DVB_FE_CUSTOMISE
+ select DVB_TDA1004X if !DVB_FE_CUSTOMISE
+ select DVB_TDA10021 if !DVB_FE_CUSTOMISE
+ select DVB_TUA6100 if !DVB_FE_CUSTOMISE
select FW_LOADER
help
Support for simple SAA7146 based DVB cards
@@ -127,9 +130,9 @@ config DVB_BUDGET_PATCH
depends on DVB_CORE && DVB_BUDGET && VIDEO_V4L1
select DVB_AV7110
select DVB_PLL
- select DVB_STV0299
- select DVB_VES1X93
- select DVB_TDA8083
+ select DVB_STV0299 if !DVB_FE_CUSTOMISE
+ select DVB_VES1X93 if !DVB_FE_CUSTOMISE
+ select DVB_TDA8083 if !DVB_FE_CUSTOMISE
help
Support for Budget Patch (full TS) modification on
SAA7146+AV7110 based cards (DVB-S cards). This
diff --git a/drivers/media/dvb/ttpci/av7110.c b/drivers/media/dvb/ttpci/av7110.c
index 4506165c5de2..bba23bcd1b11 100644
--- a/drivers/media/dvb/ttpci/av7110.c
+++ b/drivers/media/dvb/ttpci/av7110.c
@@ -1383,8 +1383,10 @@ static void dvb_unregister(struct av7110 *av7110)
dvb_dmxdev_release(&av7110->dmxdev);
dvb_dmx_release(&av7110->demux);
- if (av7110->fe != NULL)
+ if (av7110->fe != NULL) {
dvb_unregister_frontend(av7110->fe);
+ dvb_frontend_detach(av7110->fe);
+ }
dvb_unregister_device(av7110->osd_dev);
av7110_av_unregister(av7110);
av7110_ca_unregister(av7110);
@@ -1699,9 +1701,13 @@ static int alps_tdlb7_tuner_set_params(struct dvb_frontend* fe, struct dvb_front
static int alps_tdlb7_request_firmware(struct dvb_frontend* fe, const struct firmware **fw, char* name)
{
+#if defined(CONFIG_DVB_SP8870) || defined(CONFIG_DVB_SP8870_MODULE)
struct av7110* av7110 = (struct av7110*) fe->dvb->priv;
return request_firmware(fw, name, &av7110->dev->pci->dev);
+#else
+ return -EINVAL;
+#endif
}
static struct sp8870_config alps_tdlb7_config = {
@@ -2077,7 +2083,7 @@ static int frontend_init(struct av7110 *av7110)
if (av7110->dev->pci->subsystem_vendor == 0x110a) {
switch(av7110->dev->pci->subsystem_device) {
case 0x0000: // Fujitsu/Siemens DVB-Cable (ves1820/Philips CD1516(??))
- av7110->fe = ves1820_attach(&philips_cd1516_config,
+ av7110->fe = dvb_attach(ves1820_attach, &philips_cd1516_config,
&av7110->i2c_adap, read_pwm(av7110));
if (av7110->fe) {
av7110->fe->ops.tuner_ops.set_params = philips_cd1516_tuner_set_params;
@@ -2092,7 +2098,7 @@ static int frontend_init(struct av7110 *av7110)
case 0x1002: // Hauppauge/TT WinTV DVB-S rev1.3SE
// try the ALPS BSRV2 first of all
- av7110->fe = ves1x93_attach(&alps_bsrv2_config, &av7110->i2c_adap);
+ av7110->fe = dvb_attach(ves1x93_attach, &alps_bsrv2_config, &av7110->i2c_adap);
if (av7110->fe) {
av7110->fe->ops.tuner_ops.set_params = alps_bsrv2_tuner_set_params;
av7110->fe->ops.diseqc_send_master_cmd = av7110_diseqc_send_master_cmd;
@@ -2103,7 +2109,7 @@ static int frontend_init(struct av7110 *av7110)
}
// try the ALPS BSRU6 now
- av7110->fe = stv0299_attach(&alps_bsru6_config, &av7110->i2c_adap);
+ av7110->fe = dvb_attach(stv0299_attach, &alps_bsru6_config, &av7110->i2c_adap);
if (av7110->fe) {
av7110->fe->ops.tuner_ops.set_params = alps_bsru6_tuner_set_params;
av7110->fe->tuner_priv = &av7110->i2c_adap;
@@ -2116,7 +2122,7 @@ static int frontend_init(struct av7110 *av7110)
}
// Try the grundig 29504-451
- av7110->fe = tda8083_attach(&grundig_29504_451_config, &av7110->i2c_adap);
+ av7110->fe = dvb_attach(tda8083_attach, &grundig_29504_451_config, &av7110->i2c_adap);
if (av7110->fe) {
av7110->fe->ops.tuner_ops.set_params = grundig_29504_451_tuner_set_params;
av7110->fe->ops.diseqc_send_master_cmd = av7110_diseqc_send_master_cmd;
@@ -2130,7 +2136,7 @@ static int frontend_init(struct av7110 *av7110)
switch(av7110->dev->pci->subsystem_device) {
case 0x0000:
/* Siemens DVB-C (full-length card) VES1820/Philips CD1516 */
- av7110->fe = ves1820_attach(&philips_cd1516_config, &av7110->i2c_adap,
+ av7110->fe = dvb_attach(ves1820_attach, &philips_cd1516_config, &av7110->i2c_adap,
read_pwm(av7110));
if (av7110->fe) {
av7110->fe->ops.tuner_ops.set_params = philips_cd1516_tuner_set_params;
@@ -2138,7 +2144,7 @@ static int frontend_init(struct av7110 *av7110)
break;
case 0x0003:
/* Hauppauge DVB-C 2.1 VES1820/ALPS TDBE2 */
- av7110->fe = ves1820_attach(&alps_tdbe2_config, &av7110->i2c_adap,
+ av7110->fe = dvb_attach(ves1820_attach, &alps_tdbe2_config, &av7110->i2c_adap,
read_pwm(av7110));
if (av7110->fe) {
av7110->fe->ops.tuner_ops.set_params = alps_tdbe2_tuner_set_params;
@@ -2148,17 +2154,24 @@ static int frontend_init(struct av7110 *av7110)
break;
case 0x0001: // Hauppauge/TT Nexus-T premium rev1.X
-
- // ALPS TDLB7
- av7110->fe = sp8870_attach(&alps_tdlb7_config, &av7110->i2c_adap);
+ // try ALPS TDLB7 first, then Grundig 29504-401
+ av7110->fe = dvb_attach(sp8870_attach, &alps_tdlb7_config, &av7110->i2c_adap);
if (av7110->fe) {
av7110->fe->ops.tuner_ops.set_params = alps_tdlb7_tuner_set_params;
+ break;
}
+ /* fall-thru */
+
+ case 0x0008: // Hauppauge/TT DVB-T
+ // Grundig 29504-401
+ av7110->fe = dvb_attach(l64781_attach, &grundig_29504_401_config, &av7110->i2c_adap);
+ if (av7110->fe)
+ av7110->fe->ops.tuner_ops.set_params = grundig_29504_401_tuner_set_params;
break;
case 0x0002: // Hauppauge/TT DVB-C premium rev2.X
- av7110->fe = ves1820_attach(&alps_tdbe2_config, &av7110->i2c_adap, read_pwm(av7110));
+ av7110->fe = dvb_attach(ves1820_attach, &alps_tdbe2_config, &av7110->i2c_adap, read_pwm(av7110));
if (av7110->fe) {
av7110->fe->ops.tuner_ops.set_params = alps_tdbe2_tuner_set_params;
}
@@ -2166,7 +2179,7 @@ static int frontend_init(struct av7110 *av7110)
case 0x0004: // Galaxis DVB-S rev1.3
/* ALPS BSRV2 */
- av7110->fe = ves1x93_attach(&alps_bsrv2_config, &av7110->i2c_adap);
+ av7110->fe = dvb_attach(ves1x93_attach, &alps_bsrv2_config, &av7110->i2c_adap);
if (av7110->fe) {
av7110->fe->ops.tuner_ops.set_params = alps_bsrv2_tuner_set_params;
av7110->fe->ops.diseqc_send_master_cmd = av7110_diseqc_send_master_cmd;
@@ -2178,7 +2191,7 @@ static int frontend_init(struct av7110 *av7110)
case 0x0006: /* Fujitsu-Siemens DVB-S rev 1.6 */
/* Grundig 29504-451 */
- av7110->fe = tda8083_attach(&grundig_29504_451_config, &av7110->i2c_adap);
+ av7110->fe = dvb_attach(tda8083_attach, &grundig_29504_451_config, &av7110->i2c_adap);
if (av7110->fe) {
av7110->fe->ops.tuner_ops.set_params = grundig_29504_451_tuner_set_params;
av7110->fe->ops.diseqc_send_master_cmd = av7110_diseqc_send_master_cmd;
@@ -2188,17 +2201,9 @@ static int frontend_init(struct av7110 *av7110)
}
break;
- case 0x0008: // Hauppauge/TT DVB-T
-
- av7110->fe = l64781_attach(&grundig_29504_401_config, &av7110->i2c_adap);
- if (av7110->fe) {
- av7110->fe->ops.tuner_ops.set_params = grundig_29504_401_tuner_set_params;
- }
- break;
-
case 0x000A: // Hauppauge/TT Nexus-CA rev1.X
- av7110->fe = stv0297_attach(&nexusca_stv0297_config, &av7110->i2c_adap);
+ av7110->fe = dvb_attach(stv0297_attach, &nexusca_stv0297_config, &av7110->i2c_adap);
if (av7110->fe) {
av7110->fe->ops.tuner_ops.set_params = nexusca_stv0297_tuner_set_params;
@@ -2214,12 +2219,12 @@ static int frontend_init(struct av7110 *av7110)
case 0x000E: /* Hauppauge/TT Nexus-S rev 2.3 */
/* ALPS BSBE1 */
- av7110->fe = stv0299_attach(&alps_bsbe1_config, &av7110->i2c_adap);
+ av7110->fe = dvb_attach(stv0299_attach, &alps_bsbe1_config, &av7110->i2c_adap);
if (av7110->fe) {
av7110->fe->ops.tuner_ops.set_params = alps_bsbe1_tuner_set_params;
av7110->fe->tuner_priv = &av7110->i2c_adap;
- if (lnbp21_attach(av7110->fe, &av7110->i2c_adap, 0, 0)) {
+ if (dvb_attach(lnbp21_attach, av7110->fe, &av7110->i2c_adap, 0, 0) == NULL) {
printk("dvb-ttpci: LNBP21 not found!\n");
if (av7110->fe->ops.release)
av7110->fe->ops.release(av7110->fe);
@@ -2255,8 +2260,7 @@ static int frontend_init(struct av7110 *av7110)
ret = dvb_register_frontend(&av7110->dvb_adapter, av7110->fe);
if (ret < 0) {
printk("av7110: Frontend registration failed!\n");
- if (av7110->fe->ops.release)
- av7110->fe->ops.release(av7110->fe);
+ dvb_frontend_detach(av7110->fe);
av7110->fe = NULL;
}
}
@@ -2823,7 +2827,7 @@ MODULE_DEVICE_TABLE(pci, pci_tbl);
static struct saa7146_extension av7110_extension = {
- .name = "dvb\0",
+ .name = "dvb",
.flags = SAA7146_I2C_SHORT_DELAY,
.module = THIS_MODULE,
diff --git a/drivers/media/dvb/ttpci/av7110_av.c b/drivers/media/dvb/ttpci/av7110_av.c
index 0f3a044aeb17..8c577cf30fb3 100644
--- a/drivers/media/dvb/ttpci/av7110_av.c
+++ b/drivers/media/dvb/ttpci/av7110_av.c
@@ -33,7 +33,6 @@
#include <linux/string.h>
#include <linux/sched.h>
#include <linux/delay.h>
-#include <linux/byteorder/swabb.h>
#include <linux/smp_lock.h>
#include <linux/fs.h>
diff --git a/drivers/media/dvb/ttpci/av7110_ca.c b/drivers/media/dvb/ttpci/av7110_ca.c
index 6079e8865d5b..dd9aee314e0a 100644
--- a/drivers/media/dvb/ttpci/av7110_ca.c
+++ b/drivers/media/dvb/ttpci/av7110_ca.c
@@ -35,7 +35,6 @@
#include <linux/fs.h>
#include <linux/timer.h>
#include <linux/poll.h>
-#include <linux/byteorder/swabb.h>
#include <linux/smp_lock.h>
#include "av7110.h"
diff --git a/drivers/media/dvb/ttpci/av7110_hw.c b/drivers/media/dvb/ttpci/av7110_hw.c
index 75736f2fe838..37de2e88a273 100644
--- a/drivers/media/dvb/ttpci/av7110_hw.c
+++ b/drivers/media/dvb/ttpci/av7110_hw.c
@@ -34,7 +34,6 @@
#include <linux/string.h>
#include <linux/sched.h>
#include <linux/delay.h>
-#include <linux/byteorder/swabb.h>
#include <linux/smp_lock.h>
#include <linux/fs.h>
diff --git a/drivers/media/dvb/ttpci/av7110_v4l.c b/drivers/media/dvb/ttpci/av7110_v4l.c
index 6ffe53fdcf57..10cfe3131e72 100644
--- a/drivers/media/dvb/ttpci/av7110_v4l.c
+++ b/drivers/media/dvb/ttpci/av7110_v4l.c
@@ -32,7 +32,6 @@
#include <linux/fs.h>
#include <linux/timer.h>
#include <linux/poll.h>
-#include <linux/byteorder/swabb.h>
#include <linux/smp_lock.h>
#include "av7110.h"
@@ -922,7 +921,7 @@ static struct saa7146_ext_vv av7110_vv_data_st = {
static struct saa7146_ext_vv av7110_vv_data_c = {
.inputs = 1,
.audios = 1,
- .capabilities = V4L2_CAP_TUNER | V4L2_CAP_VBI_CAPTURE | V4L2_CAP_SLICED_VBI_OUTPUT,
+ .capabilities = V4L2_CAP_TUNER | V4L2_CAP_SLICED_VBI_OUTPUT,
.flags = SAA7146_USE_PORT_B_FOR_VBI,
.stds = &standard[0],
diff --git a/drivers/media/dvb/ttpci/budget-av.c b/drivers/media/dvb/ttpci/budget-av.c
index 2d21fec23b4d..2235ff8b8a1d 100644
--- a/drivers/media/dvb/ttpci/budget-av.c
+++ b/drivers/media/dvb/ttpci/budget-av.c
@@ -37,6 +37,7 @@
#include "stv0299.h"
#include "tda10021.h"
#include "tda1004x.h"
+#include "tua6100.h"
#include "dvb-pll.h"
#include <media/saa7146_vv.h>
#include <linux/module.h>
@@ -235,7 +236,7 @@ static int ciintf_slot_reset(struct dvb_ca_en50221 *ca, int slot)
/* set tda10021 back to original clock configuration on reset */
if (budget_av->tda10021_poclkp) {
- tda10021_write_byte(budget_av->budget.dvb_frontend, 0x12, 0xa0);
+ tda10021_writereg(budget_av->budget.dvb_frontend, 0x12, 0xa0);
budget_av->tda10021_ts_enabled = 0;
}
@@ -257,7 +258,7 @@ static int ciintf_slot_shutdown(struct dvb_ca_en50221 *ca, int slot)
/* set tda10021 back to original clock configuration when cam removed */
if (budget_av->tda10021_poclkp) {
- tda10021_write_byte(budget_av->budget.dvb_frontend, 0x12, 0xa0);
+ tda10021_writereg(budget_av->budget.dvb_frontend, 0x12, 0xa0);
budget_av->tda10021_ts_enabled = 0;
}
return 0;
@@ -277,7 +278,7 @@ static int ciintf_slot_ts_enable(struct dvb_ca_en50221 *ca, int slot)
/* tda10021 seems to need a different TS clock config when data is routed to the CAM */
if (budget_av->tda10021_poclkp) {
- tda10021_write_byte(budget_av->budget.dvb_frontend, 0x12, 0xa1);
+ tda10021_writereg(budget_av->budget.dvb_frontend, 0x12, 0xa1);
budget_av->tda10021_ts_enabled = 1;
}
@@ -548,144 +549,6 @@ static int philips_su1278_ty_ci_tuner_set_params(struct dvb_frontend *fe,
return 0;
}
-#define MIN2(a,b) ((a) < (b) ? (a) : (b))
-#define MIN3(a,b,c) MIN2(MIN2(a,b),c)
-
-static int philips_su1278sh2_tua6100_tuner_set_params(struct dvb_frontend *fe,
- struct dvb_frontend_parameters *params)
-{
- u8 reg0 [2] = { 0x00, 0x00 };
- u8 reg1 [4] = { 0x01, 0x00, 0x00, 0x00 };
- u8 reg2 [3] = { 0x02, 0x00, 0x00 };
- int _fband;
- int first_ZF;
- int R, A, N, P, M;
- struct i2c_msg msg = {.addr = 0x60,.flags = 0,.buf = NULL,.len = 0 };
- int freq = params->frequency;
- struct budget *budget = (struct budget *) fe->dvb->priv;
-
- first_ZF = (freq) / 1000;
-
- if (abs(MIN2(abs(first_ZF-1190),abs(first_ZF-1790))) <
- abs(MIN3(abs(first_ZF-1202),abs(first_ZF-1542),abs(first_ZF-1890))))
- _fband = 2;
- else
- _fband = 3;
-
- if (_fband == 2) {
- if (((first_ZF >= 950) && (first_ZF < 1350)) ||
- ((first_ZF >= 1430) && (first_ZF < 1950)))
- reg0[1] = 0x07;
- else if (((first_ZF >= 1350) && (first_ZF < 1430)) ||
- ((first_ZF >= 1950) && (first_ZF < 2150)))
- reg0[1] = 0x0B;
- }
-
- if(_fband == 3) {
- if (((first_ZF >= 950) && (first_ZF < 1350)) ||
- ((first_ZF >= 1455) && (first_ZF < 1950)))
- reg0[1] = 0x07;
- else if (((first_ZF >= 1350) && (first_ZF < 1420)) ||
- ((first_ZF >= 1950) && (first_ZF < 2150)))
- reg0[1] = 0x0B;
- else if ((first_ZF >= 1420) && (first_ZF < 1455))
- reg0[1] = 0x0F;
- }
-
- if (first_ZF > 1525)
- reg1[1] |= 0x80;
- else
- reg1[1] &= 0x7F;
-
- if (_fband == 2) {
- if (first_ZF > 1430) { /* 1430MHZ */
- reg1[1] &= 0xCF; /* N2 */
- reg2[1] &= 0xCF; /* R2 */
- reg2[1] |= 0x10;
- } else {
- reg1[1] &= 0xCF; /* N2 */
- reg1[1] |= 0x20;
- reg2[1] &= 0xCF; /* R2 */
- reg2[1] |= 0x10;
- }
- }
-
- if (_fband == 3) {
- if ((first_ZF >= 1455) &&
- (first_ZF < 1630)) {
- reg1[1] &= 0xCF; /* N2 */
- reg1[1] |= 0x20;
- reg2[1] &= 0xCF; /* R2 */
- } else {
- if (first_ZF < 1455) {
- reg1[1] &= 0xCF; /* N2 */
- reg1[1] |= 0x20;
- reg2[1] &= 0xCF; /* R2 */
- reg2[1] |= 0x10;
- } else {
- if (first_ZF >= 1630) {
- reg1[1] &= 0xCF; /* N2 */
- reg2[1] &= 0xCF; /* R2 */
- reg2[1] |= 0x10;
- }
- }
- }
- }
-
- /* set ports, enable P0 for symbol rates > 4Ms/s */
- if (params->u.qpsk.symbol_rate >= 4000000)
- reg1[1] |= 0x0c;
- else
- reg1[1] |= 0x04;
-
- reg2[1] |= 0x0c;
-
- R = 64;
- A = 64;
- P = 64; //32
-
- M = (freq * R) / 4; /* in Mhz */
- N = (M - A * 1000) / (P * 1000);
-
- reg1[1] |= (N >> 9) & 0x03;
- reg1[2] = (N >> 1) & 0xff;
- reg1[3] = (N << 7) & 0x80;
-
- reg2[1] |= (R >> 8) & 0x03;
- reg2[2] = R & 0xFF; /* R */
-
- reg1[3] |= A & 0x7f; /* A */
-
- if (P == 64)
- reg1[1] |= 0x40; /* Prescaler 64/65 */
-
- reg0[1] |= 0x03;
-
- /* already enabled - do not reenable i2c repeater or TX fails */
- if (fe->ops.i2c_gate_ctrl)
- fe->ops.i2c_gate_ctrl(fe, 1);
- msg.buf = reg0;
- msg.len = sizeof(reg0);
- if (i2c_transfer(&budget->i2c_adap, &msg, 1) != 1)
- return -EIO;
-
- if (fe->ops.i2c_gate_ctrl)
- fe->ops.i2c_gate_ctrl(fe, 1);
- msg.buf = reg1;
- msg.len = sizeof(reg1);
- if (i2c_transfer(&budget->i2c_adap, &msg, 1) != 1)
- return -EIO;
-
- if (fe->ops.i2c_gate_ctrl)
- fe->ops.i2c_gate_ctrl(fe, 1);
- msg.buf = reg2;
- msg.len = sizeof(reg2);
- if (i2c_transfer(&budget->i2c_adap, &msg, 1) != 1)
- return -EIO;
-
- return 0;
-}
-
static u8 typhoon_cinergy1200s_inittab[] = {
0x01, 0x15,
0x02, 0x30,
@@ -1068,9 +931,9 @@ static int tda10021_set_frontend(struct dvb_frontend *fe,
result = budget_av->tda10021_set_frontend(fe, p);
if (budget_av->tda10021_ts_enabled) {
- tda10021_write_byte(budget_av->budget.dvb_frontend, 0x12, 0xa1);
+ tda10021_writereg(budget_av->budget.dvb_frontend, 0x12, 0xa1);
} else {
- tda10021_write_byte(budget_av->budget.dvb_frontend, 0x12, 0xa0);
+ tda10021_writereg(budget_av->budget.dvb_frontend, 0x12, 0xa0);
}
return result;
@@ -1096,15 +959,16 @@ static void frontend_init(struct budget_av *budget_av)
switch (saa->pci->subsystem_device) {
case SUBID_DVBS_KNC1:
+ case SUBID_DVBS_KNC1_PLUS:
case SUBID_DVBS_EASYWATCH_1:
if (saa->pci->subsystem_vendor == 0x1894) {
- fe = stv0299_attach(&cinergy_1200s_1894_0010_config,
+ fe = dvb_attach(stv0299_attach, &cinergy_1200s_1894_0010_config,
&budget_av->budget.i2c_adap);
if (fe) {
- fe->ops.tuner_ops.set_params = philips_su1278sh2_tua6100_tuner_set_params;
+ dvb_attach(tua6100_attach, fe, 0x60, &budget_av->budget.i2c_adap);
}
} else {
- fe = stv0299_attach(&typhoon_config,
+ fe = dvb_attach(stv0299_attach, &typhoon_config,
&budget_av->budget.i2c_adap);
if (fe) {
fe->ops.tuner_ops.set_params = philips_su1278_ty_ci_tuner_set_params;
@@ -1116,16 +980,15 @@ static void frontend_init(struct budget_av *budget_av)
case SUBID_DVBS_TV_STAR_CI:
case SUBID_DVBS_CYNERGY1200N:
case SUBID_DVBS_EASYWATCH:
- fe = stv0299_attach(&philips_sd1878_config,
+ fe = dvb_attach(stv0299_attach, &philips_sd1878_config,
&budget_av->budget.i2c_adap);
if (fe) {
fe->ops.tuner_ops.set_params = philips_sd1878_tda8261_tuner_set_params;
}
break;
- case SUBID_DVBS_KNC1_PLUS:
case SUBID_DVBS_TYPHOON:
- fe = stv0299_attach(&typhoon_config,
+ fe = dvb_attach(stv0299_attach, &typhoon_config,
&budget_av->budget.i2c_adap);
if (fe) {
fe->ops.tuner_ops.set_params = philips_su1278_ty_ci_tuner_set_params;
@@ -1133,7 +996,7 @@ static void frontend_init(struct budget_av *budget_av)
break;
case SUBID_DVBS_CINERGY1200:
- fe = stv0299_attach(&cinergy_1200s_config,
+ fe = dvb_attach(stv0299_attach, &cinergy_1200s_config,
&budget_av->budget.i2c_adap);
if (fe) {
fe->ops.tuner_ops.set_params = philips_su1278_ty_ci_tuner_set_params;
@@ -1141,19 +1004,10 @@ static void frontend_init(struct budget_av *budget_av)
break;
case SUBID_DVBC_KNC1:
- budget_av->reinitialise_demod = 1;
- fe = tda10021_attach(&philips_cu1216_config,
- &budget_av->budget.i2c_adap,
- read_pwm(budget_av));
- if (fe) {
- fe->ops.tuner_ops.set_params = philips_cu1216_tuner_set_params;
- }
- break;
-
case SUBID_DVBC_KNC1_PLUS:
case SUBID_DVBC_CINERGY1200:
budget_av->reinitialise_demod = 1;
- fe = tda10021_attach(&philips_cu1216_config,
+ fe = dvb_attach(tda10021_attach, &philips_cu1216_config,
&budget_av->budget.i2c_adap,
read_pwm(budget_av));
if (fe) {
@@ -1168,7 +1022,7 @@ static void frontend_init(struct budget_av *budget_av)
case SUBID_DVBT_KNC1_PLUS:
case SUBID_DVBT_CINERGY1200:
budget_av->reinitialise_demod = 1;
- fe = tda10046_attach(&philips_tu1216_config,
+ fe = dvb_attach(tda10046_attach, &philips_tu1216_config,
&budget_av->budget.i2c_adap);
if (fe) {
fe->ops.tuner_ops.init = philips_tu1216_tuner_init;
@@ -1192,8 +1046,7 @@ static void frontend_init(struct budget_av *budget_av)
if (dvb_register_frontend(&budget_av->budget.dvb_adapter,
budget_av->budget.dvb_frontend)) {
printk(KERN_ERR "budget-av: Frontend registration failed!\n");
- if (budget_av->budget.dvb_frontend->ops.release)
- budget_av->budget.dvb_frontend->ops.release(budget_av->budget.dvb_frontend);
+ dvb_frontend_detach(budget_av->budget.dvb_frontend);
budget_av->budget.dvb_frontend = NULL;
}
}
@@ -1227,8 +1080,10 @@ static int budget_av_detach(struct saa7146_dev *dev)
if (budget_av->budget.ci_present)
ciintf_deinit(budget_av);
- if (budget_av->budget.dvb_frontend != NULL)
+ if (budget_av->budget.dvb_frontend != NULL) {
dvb_unregister_frontend(budget_av->budget.dvb_frontend);
+ dvb_frontend_detach(budget_av->budget.dvb_frontend);
+ }
err = ttpci_budget_deinit(&budget_av->budget);
kfree(budget_av);
@@ -1400,6 +1255,7 @@ static struct pci_device_id pci_tbl[] = {
MAKE_EXTENSION_PCI(knc1s, 0x1131, 0x0010),
MAKE_EXTENSION_PCI(knc1s, 0x1894, 0x0010),
MAKE_EXTENSION_PCI(knc1sp, 0x1131, 0x0011),
+ MAKE_EXTENSION_PCI(knc1sp, 0x1894, 0x0011),
MAKE_EXTENSION_PCI(kncxs, 0x1894, 0x0014),
MAKE_EXTENSION_PCI(kncxs, 0x1894, 0x0016),
MAKE_EXTENSION_PCI(satewpls, 0x1894, 0x001e),
diff --git a/drivers/media/dvb/ttpci/budget-ci.c b/drivers/media/dvb/ttpci/budget-ci.c
index ffbbb3e34be4..2a2e9b400613 100644
--- a/drivers/media/dvb/ttpci/budget-ci.c
+++ b/drivers/media/dvb/ttpci/budget-ci.c
@@ -749,17 +749,17 @@ static int philips_tdm1316l_tuner_set_params(struct dvb_frontend *fe, struct dvb
// setup PLL filter and TDA9889
switch (params->u.ofdm.bandwidth) {
case BANDWIDTH_6_MHZ:
- tda1004x_write_byte(fe, 0x0C, 0x14);
+ tda1004x_writereg(fe, 0x0C, 0x14);
filter = 0;
break;
case BANDWIDTH_7_MHZ:
- tda1004x_write_byte(fe, 0x0C, 0x80);
+ tda1004x_writereg(fe, 0x0C, 0x80);
filter = 0;
break;
case BANDWIDTH_8_MHZ:
- tda1004x_write_byte(fe, 0x0C, 0x14);
+ tda1004x_writereg(fe, 0x0C, 0x14);
filter = 1;
break;
@@ -988,7 +988,7 @@ static void frontend_init(struct budget_ci *budget_ci)
switch (budget_ci->budget.dev->pci->subsystem_device) {
case 0x100c: // Hauppauge/TT Nova-CI budget (stv0299/ALPS BSRU6(tsa5059))
budget_ci->budget.dvb_frontend =
- stv0299_attach(&alps_bsru6_config, &budget_ci->budget.i2c_adap);
+ dvb_attach(stv0299_attach, &alps_bsru6_config, &budget_ci->budget.i2c_adap);
if (budget_ci->budget.dvb_frontend) {
budget_ci->budget.dvb_frontend->ops.tuner_ops.set_params = alps_bsru6_tuner_set_params;
budget_ci->budget.dvb_frontend->tuner_priv = &budget_ci->budget.i2c_adap;
@@ -998,7 +998,7 @@ static void frontend_init(struct budget_ci *budget_ci)
case 0x100f: // Hauppauge/TT Nova-CI budget (stv0299b/Philips su1278(tsa5059))
budget_ci->budget.dvb_frontend =
- stv0299_attach(&philips_su1278_tt_config, &budget_ci->budget.i2c_adap);
+ dvb_attach(stv0299_attach, &philips_su1278_tt_config, &budget_ci->budget.i2c_adap);
if (budget_ci->budget.dvb_frontend) {
budget_ci->budget.dvb_frontend->ops.tuner_ops.set_params = philips_su1278_tt_tuner_set_params;
break;
@@ -1008,7 +1008,7 @@ static void frontend_init(struct budget_ci *budget_ci)
case 0x1010: // TT DVB-C CI budget (stv0297/Philips tdm1316l(tda6651tt))
budget_ci->tuner_pll_address = 0x61;
budget_ci->budget.dvb_frontend =
- stv0297_attach(&dvbc_philips_tdm1316l_config, &budget_ci->budget.i2c_adap);
+ dvb_attach(stv0297_attach, &dvbc_philips_tdm1316l_config, &budget_ci->budget.i2c_adap);
if (budget_ci->budget.dvb_frontend) {
budget_ci->budget.dvb_frontend->ops.tuner_ops.set_params = dvbc_philips_tdm1316l_tuner_set_params;
break;
@@ -1018,7 +1018,7 @@ static void frontend_init(struct budget_ci *budget_ci)
case 0x1011: // Hauppauge/TT Nova-T budget (tda10045/Philips tdm1316l(tda6651tt) + TDA9889)
budget_ci->tuner_pll_address = 0x63;
budget_ci->budget.dvb_frontend =
- tda10045_attach(&philips_tdm1316l_config, &budget_ci->budget.i2c_adap);
+ dvb_attach(tda10045_attach, &philips_tdm1316l_config, &budget_ci->budget.i2c_adap);
if (budget_ci->budget.dvb_frontend) {
budget_ci->budget.dvb_frontend->ops.tuner_ops.init = philips_tdm1316l_tuner_init;
budget_ci->budget.dvb_frontend->ops.tuner_ops.set_params = philips_tdm1316l_tuner_set_params;
@@ -1029,7 +1029,7 @@ static void frontend_init(struct budget_ci *budget_ci)
case 0x1012: // TT DVB-T CI budget (tda10046/Philips tdm1316l(tda6651tt))
budget_ci->tuner_pll_address = 0x60;
budget_ci->budget.dvb_frontend =
- tda10046_attach(&philips_tdm1316l_config, &budget_ci->budget.i2c_adap);
+ dvb_attach(tda10046_attach, &philips_tdm1316l_config, &budget_ci->budget.i2c_adap);
if (budget_ci->budget.dvb_frontend) {
budget_ci->budget.dvb_frontend->ops.tuner_ops.init = philips_tdm1316l_tuner_init;
budget_ci->budget.dvb_frontend->ops.tuner_ops.set_params = philips_tdm1316l_tuner_set_params;
@@ -1038,16 +1038,15 @@ static void frontend_init(struct budget_ci *budget_ci)
break;
case 0x1017: // TT S-1500 PCI
- budget_ci->budget.dvb_frontend = stv0299_attach(&alps_bsbe1_config, &budget_ci->budget.i2c_adap);
+ budget_ci->budget.dvb_frontend = dvb_attach(stv0299_attach, &alps_bsbe1_config, &budget_ci->budget.i2c_adap);
if (budget_ci->budget.dvb_frontend) {
budget_ci->budget.dvb_frontend->ops.tuner_ops.set_params = alps_bsbe1_tuner_set_params;
budget_ci->budget.dvb_frontend->tuner_priv = &budget_ci->budget.i2c_adap;
budget_ci->budget.dvb_frontend->ops.dishnetwork_send_legacy_command = NULL;
- if (lnbp21_attach(budget_ci->budget.dvb_frontend, &budget_ci->budget.i2c_adap, LNBP21_LLC, 0)) {
+ if (dvb_attach(lnbp21_attach, budget_ci->budget.dvb_frontend, &budget_ci->budget.i2c_adap, LNBP21_LLC, 0) == NULL) {
printk("%s: No LNBP21 found!\n", __FUNCTION__);
- if (budget_ci->budget.dvb_frontend->ops.release)
- budget_ci->budget.dvb_frontend->ops.release(budget_ci->budget.dvb_frontend);
+ dvb_frontend_detach(budget_ci->budget.dvb_frontend);
budget_ci->budget.dvb_frontend = NULL;
}
}
@@ -1065,8 +1064,7 @@ static void frontend_init(struct budget_ci *budget_ci)
if (dvb_register_frontend
(&budget_ci->budget.dvb_adapter, budget_ci->budget.dvb_frontend)) {
printk("budget-ci: Frontend registration failed!\n");
- if (budget_ci->budget.dvb_frontend->ops.release)
- budget_ci->budget.dvb_frontend->ops.release(budget_ci->budget.dvb_frontend);
+ dvb_frontend_detach(budget_ci->budget.dvb_frontend);
budget_ci->budget.dvb_frontend = NULL;
}
}
@@ -1114,8 +1112,10 @@ static int budget_ci_detach(struct saa7146_dev *dev)
if (budget_ci->budget.ci_present)
ciintf_deinit(budget_ci);
- if (budget_ci->budget.dvb_frontend)
+ if (budget_ci->budget.dvb_frontend) {
dvb_unregister_frontend(budget_ci->budget.dvb_frontend);
+ dvb_frontend_detach(budget_ci->budget.dvb_frontend);
+ }
err = ttpci_budget_deinit(&budget_ci->budget);
tasklet_kill(&budget_ci->msp430_irq_tasklet);
@@ -1153,7 +1153,7 @@ static struct pci_device_id pci_tbl[] = {
MODULE_DEVICE_TABLE(pci, pci_tbl);
static struct saa7146_extension budget_extension = {
- .name = "budget_ci dvb\0",
+ .name = "budget_ci dvb",
.flags = SAA7146_I2C_SHORT_DELAY,
.module = THIS_MODULE,
diff --git a/drivers/media/dvb/ttpci/budget-patch.c b/drivers/media/dvb/ttpci/budget-patch.c
index 57227441891e..fc1267b8c892 100644
--- a/drivers/media/dvb/ttpci/budget-patch.c
+++ b/drivers/media/dvb/ttpci/budget-patch.c
@@ -325,7 +325,7 @@ static void frontend_init(struct budget_patch* budget)
case 0x1013: // SATELCO Multimedia PCI
// try the ALPS BSRV2 first of all
- budget->dvb_frontend = ves1x93_attach(&alps_bsrv2_config, &budget->i2c_adap);
+ budget->dvb_frontend = dvb_attach(ves1x93_attach, &alps_bsrv2_config, &budget->i2c_adap);
if (budget->dvb_frontend) {
budget->dvb_frontend->ops.tuner_ops.set_params = alps_bsrv2_tuner_set_params;
budget->dvb_frontend->ops.diseqc_send_master_cmd = budget_patch_diseqc_send_master_cmd;
@@ -335,7 +335,7 @@ static void frontend_init(struct budget_patch* budget)
}
// try the ALPS BSRU6 now
- budget->dvb_frontend = stv0299_attach(&alps_bsru6_config, &budget->i2c_adap);
+ budget->dvb_frontend = dvb_attach(stv0299_attach, &alps_bsru6_config, &budget->i2c_adap);
if (budget->dvb_frontend) {
budget->dvb_frontend->ops.tuner_ops.set_params = alps_bsru6_tuner_set_params;
budget->dvb_frontend->tuner_priv = &budget->i2c_adap;
@@ -347,7 +347,7 @@ static void frontend_init(struct budget_patch* budget)
}
// Try the grundig 29504-451
- budget->dvb_frontend = tda8083_attach(&grundig_29504_451_config, &budget->i2c_adap);
+ budget->dvb_frontend = dvb_attach(tda8083_attach, &grundig_29504_451_config, &budget->i2c_adap);
if (budget->dvb_frontend) {
budget->dvb_frontend->ops.tuner_ops.set_params = grundig_29504_451_tuner_set_params;
budget->dvb_frontend->ops.diseqc_send_master_cmd = budget_diseqc_send_master_cmd;
@@ -367,8 +367,7 @@ static void frontend_init(struct budget_patch* budget)
} else {
if (dvb_register_frontend(&budget->dvb_adapter, budget->dvb_frontend)) {
printk("budget-av: Frontend registration failed!\n");
- if (budget->dvb_frontend->ops.release)
- budget->dvb_frontend->ops.release(budget->dvb_frontend);
+ dvb_frontend_detach(budget->dvb_frontend);
budget->dvb_frontend = NULL;
}
}
@@ -627,8 +626,10 @@ static int budget_patch_detach (struct saa7146_dev* dev)
struct budget_patch *budget = (struct budget_patch*) dev->ext_priv;
int err;
- if (budget->dvb_frontend) dvb_unregister_frontend(budget->dvb_frontend);
-
+ if (budget->dvb_frontend) {
+ dvb_unregister_frontend(budget->dvb_frontend);
+ dvb_frontend_detach(budget->dvb_frontend);
+ }
err = ttpci_budget_deinit (budget);
kfree (budget);
@@ -647,7 +648,7 @@ static void __exit budget_patch_exit(void)
}
static struct saa7146_extension budget_extension = {
- .name = "budget_patch dvb\0",
+ .name = "budget_patch dvb",
.flags = 0,
.module = THIS_MODULE,
diff --git a/drivers/media/dvb/ttpci/budget.c b/drivers/media/dvb/ttpci/budget.c
index 863dffb4ed8e..e58f0391e9d1 100644
--- a/drivers/media/dvb/ttpci/budget.c
+++ b/drivers/media/dvb/ttpci/budget.c
@@ -41,6 +41,8 @@
#include "l64781.h"
#include "tda8083.h"
#include "s5h1420.h"
+#include "tda10086.h"
+#include "tda826x.h"
#include "lnbp21.h"
#include "bsru6.h"
@@ -342,6 +344,11 @@ static struct s5h1420_config s5h1420_config = {
.invert = 1,
};
+static struct tda10086_config tda10086_config = {
+ .demod_address = 0x0e,
+ .invert = 0,
+};
+
static u8 read_pwm(struct budget* budget)
{
u8 b = 0xff;
@@ -361,7 +368,7 @@ static void frontend_init(struct budget *budget)
case 0x1003: // Hauppauge/TT Nova budget (stv0299/ALPS BSRU6(tsa5059) OR ves1893/ALPS BSRV2(sp5659))
case 0x1013:
// try the ALPS BSRV2 first of all
- budget->dvb_frontend = ves1x93_attach(&alps_bsrv2_config, &budget->i2c_adap);
+ budget->dvb_frontend = dvb_attach(ves1x93_attach, &alps_bsrv2_config, &budget->i2c_adap);
if (budget->dvb_frontend) {
budget->dvb_frontend->ops.tuner_ops.set_params = alps_bsrv2_tuner_set_params;
budget->dvb_frontend->ops.diseqc_send_master_cmd = budget_diseqc_send_master_cmd;
@@ -371,7 +378,7 @@ static void frontend_init(struct budget *budget)
}
// try the ALPS BSRU6 now
- budget->dvb_frontend = stv0299_attach(&alps_bsru6_config, &budget->i2c_adap);
+ budget->dvb_frontend = dvb_attach(stv0299_attach, &alps_bsru6_config, &budget->i2c_adap);
if (budget->dvb_frontend) {
budget->dvb_frontend->ops.tuner_ops.set_params = alps_bsru6_tuner_set_params;
budget->dvb_frontend->tuner_priv = &budget->i2c_adap;
@@ -381,7 +388,7 @@ static void frontend_init(struct budget *budget)
case 0x1004: // Hauppauge/TT DVB-C budget (ves1820/ALPS TDBE2(sp5659))
- budget->dvb_frontend = ves1820_attach(&alps_tdbe2_config, &budget->i2c_adap, read_pwm(budget));
+ budget->dvb_frontend = dvb_attach(ves1820_attach, &alps_tdbe2_config, &budget->i2c_adap, read_pwm(budget));
if (budget->dvb_frontend) {
budget->dvb_frontend->ops.tuner_ops.set_params = alps_tdbe2_tuner_set_params;
break;
@@ -390,7 +397,7 @@ static void frontend_init(struct budget *budget)
case 0x1005: // Hauppauge/TT Nova-T budget (L64781/Grundig 29504-401(tsa5060))
- budget->dvb_frontend = l64781_attach(&grundig_29504_401_config, &budget->i2c_adap);
+ budget->dvb_frontend = dvb_attach(l64781_attach, &grundig_29504_401_config, &budget->i2c_adap);
if (budget->dvb_frontend) {
budget->dvb_frontend->ops.tuner_ops.set_params = grundig_29504_401_tuner_set_params;
break;
@@ -398,7 +405,7 @@ static void frontend_init(struct budget *budget)
break;
case 0x4f60: // Fujitsu Siemens Activy Budget-S PCI rev AL (stv0299/ALPS BSRU6(tsa5059))
- budget->dvb_frontend = stv0299_attach(&alps_bsru6_config, &budget->i2c_adap);
+ budget->dvb_frontend = dvb_attach(stv0299_attach, &alps_bsru6_config, &budget->i2c_adap);
if (budget->dvb_frontend) {
budget->dvb_frontend->ops.tuner_ops.set_params = alps_bsru6_tuner_set_params;
budget->dvb_frontend->tuner_priv = &budget->i2c_adap;
@@ -408,7 +415,7 @@ static void frontend_init(struct budget *budget)
break;
case 0x4f61: // Fujitsu Siemens Activy Budget-S PCI rev GR (tda8083/Grundig 29504-451(tsa5522))
- budget->dvb_frontend = tda8083_attach(&grundig_29504_451_config, &budget->i2c_adap);
+ budget->dvb_frontend = dvb_attach(tda8083_attach, &grundig_29504_451_config, &budget->i2c_adap);
if (budget->dvb_frontend) {
budget->dvb_frontend->ops.tuner_ops.set_params = grundig_29504_451_tuner_set_params;
budget->dvb_frontend->ops.set_voltage = siemens_budget_set_voltage;
@@ -417,10 +424,28 @@ static void frontend_init(struct budget *budget)
break;
case 0x1016: // Hauppauge/TT Nova-S SE (samsung s5h1420/????(tda8260))
- budget->dvb_frontend = s5h1420_attach(&s5h1420_config, &budget->i2c_adap);
+ budget->dvb_frontend = dvb_attach(s5h1420_attach, &s5h1420_config, &budget->i2c_adap);
if (budget->dvb_frontend) {
budget->dvb_frontend->ops.tuner_ops.set_params = s5h1420_tuner_set_params;
- if (lnbp21_attach(budget->dvb_frontend, &budget->i2c_adap, 0, 0)) {
+ if (dvb_attach(lnbp21_attach, budget->dvb_frontend, &budget->i2c_adap, 0, 0) == NULL) {
+ printk("%s: No LNBP21 found!\n", __FUNCTION__);
+ goto error_out;
+ }
+ break;
+ }
+
+ case 0x1018: // TT Budget-S-1401 (philips tda10086/philips tda8262)
+ // gpio2 is connected to CLB - reset it + leave it high
+ saa7146_setgpio(budget->dev, 2, SAA7146_GPIO_OUTLO);
+ msleep(1);
+ saa7146_setgpio(budget->dev, 2, SAA7146_GPIO_OUTHI);
+ msleep(1);
+
+ budget->dvb_frontend = dvb_attach(tda10086_attach, &tda10086_config, &budget->i2c_adap);
+ if (budget->dvb_frontend) {
+ if (dvb_attach(tda826x_attach, budget->dvb_frontend, 0x60, &budget->i2c_adap, 0) == NULL)
+ printk("%s: No tda826x found!\n", __FUNCTION__);
+ if (dvb_attach(lnbp21_attach, budget->dvb_frontend, &budget->i2c_adap, 0, 0) == NULL) {
printk("%s: No LNBP21 found!\n", __FUNCTION__);
goto error_out;
}
@@ -442,8 +467,7 @@ static void frontend_init(struct budget *budget)
error_out:
printk("budget: Frontend registration failed!\n");
- if (budget->dvb_frontend->ops.release)
- budget->dvb_frontend->ops.release(budget->dvb_frontend);
+ dvb_frontend_detach(budget->dvb_frontend);
budget->dvb_frontend = NULL;
return;
}
@@ -481,7 +505,10 @@ static int budget_detach (struct saa7146_dev* dev)
struct budget *budget = (struct budget*) dev->ext_priv;
int err;
- if (budget->dvb_frontend) dvb_unregister_frontend(budget->dvb_frontend);
+ if (budget->dvb_frontend) {
+ dvb_unregister_frontend(budget->dvb_frontend);
+ dvb_frontend_detach(budget->dvb_frontend);
+ }
err = ttpci_budget_deinit (budget);
@@ -497,6 +524,7 @@ MAKE_BUDGET_INFO(ttbs, "TT-Budget/WinTV-NOVA-S PCI", BUDGET_TT);
MAKE_BUDGET_INFO(ttbc, "TT-Budget/WinTV-NOVA-C PCI", BUDGET_TT);
MAKE_BUDGET_INFO(ttbt, "TT-Budget/WinTV-NOVA-T PCI", BUDGET_TT);
MAKE_BUDGET_INFO(satel, "SATELCO Multimedia PCI", BUDGET_TT_HW_DISEQC);
+MAKE_BUDGET_INFO(ttbs1401, "TT-Budget-S-1401 PCI", BUDGET_TT);
MAKE_BUDGET_INFO(fsacs0, "Fujitsu Siemens Activy Budget-S PCI (rev GR/grundig frontend)", BUDGET_FS_ACTIVY);
MAKE_BUDGET_INFO(fsacs1, "Fujitsu Siemens Activy Budget-S PCI (rev AL/alps frontend)", BUDGET_FS_ACTIVY);
@@ -506,6 +534,7 @@ static struct pci_device_id pci_tbl[] = {
MAKE_EXTENSION_PCI(ttbt, 0x13c2, 0x1005),
MAKE_EXTENSION_PCI(satel, 0x13c2, 0x1013),
MAKE_EXTENSION_PCI(ttbs, 0x13c2, 0x1016),
+ MAKE_EXTENSION_PCI(ttbs1401, 0x13c2, 0x1018),
MAKE_EXTENSION_PCI(fsacs1,0x1131, 0x4f60),
MAKE_EXTENSION_PCI(fsacs0,0x1131, 0x4f61),
{
@@ -516,7 +545,7 @@ static struct pci_device_id pci_tbl[] = {
MODULE_DEVICE_TABLE(pci, pci_tbl);
static struct saa7146_extension budget_extension = {
- .name = "budget dvb\0",
+ .name = "budget dvb",
.flags = SAA7146_I2C_SHORT_DELAY,
.module = THIS_MODULE,
diff --git a/drivers/media/dvb/ttusb-budget/Kconfig b/drivers/media/dvb/ttusb-budget/Kconfig
index 46a6a60d2ab9..e78ea9227b0e 100644
--- a/drivers/media/dvb/ttusb-budget/Kconfig
+++ b/drivers/media/dvb/ttusb-budget/Kconfig
@@ -2,13 +2,13 @@ config DVB_TTUSB_BUDGET
tristate "Technotrend/Hauppauge Nova-USB devices"
depends on DVB_CORE && USB && I2C
select DVB_PLL
- select DVB_CX22700
- select DVB_TDA1004X
- select DVB_VES1820
- select DVB_TDA8083
- select DVB_STV0299
- select DVB_STV0297
- select DVB_LNBP21
+ select DVB_CX22700 if !DVB_FE_CUSTOMISE
+ select DVB_TDA1004X if !DVB_FE_CUSTOMISE
+ select DVB_VES1820 if !DVB_FE_CUSTOMISE
+ select DVB_TDA8083 if !DVB_FE_CUSTOMISE
+ select DVB_STV0299 if !DVB_FE_CUSTOMISE
+ select DVB_STV0297 if !DVB_FE_CUSTOMISE
+ select DVB_LNBP21 if !DVB_FE_CUSTOMISE
help
Support for external USB adapters designed by Technotrend and
produced by Hauppauge, shipped under the brand name 'Nova-USB'.
diff --git a/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c b/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c
index 04cef3023457..234199875f53 100644
--- a/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c
+++ b/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c
@@ -1107,17 +1107,17 @@ static int philips_tdm1316l_tuner_set_params(struct dvb_frontend* fe, struct dvb
// setup PLL filter
switch (params->u.ofdm.bandwidth) {
case BANDWIDTH_6_MHZ:
- tda1004x_write_byte(fe, 0x0C, 0);
+ tda1004x_writereg(fe, 0x0C, 0);
filter = 0;
break;
case BANDWIDTH_7_MHZ:
- tda1004x_write_byte(fe, 0x0C, 0);
+ tda1004x_writereg(fe, 0x0C, 0);
filter = 0;
break;
case BANDWIDTH_8_MHZ:
- tda1004x_write_byte(fe, 0x0C, 0xFF);
+ tda1004x_writereg(fe, 0x0C, 0xFF);
filter = 1;
break;
@@ -1564,13 +1564,13 @@ static void frontend_init(struct ttusb* ttusb)
switch(le16_to_cpu(ttusb->dev->descriptor.idProduct)) {
case 0x1003: // Hauppauge/TT Nova-USB-S budget (stv0299/ALPS BSRU6|BSBE1(tsa5059))
// try the stv0299 based first
- ttusb->fe = stv0299_attach(&alps_stv0299_config, &ttusb->i2c_adap);
+ ttusb->fe = dvb_attach(stv0299_attach, &alps_stv0299_config, &ttusb->i2c_adap);
if (ttusb->fe != NULL) {
ttusb->fe->ops.tuner_ops.set_params = philips_tsa5059_tuner_set_params;
if(ttusb->revision == TTUSB_REV_2_2) { // ALPS BSBE1
alps_stv0299_config.inittab = alps_bsbe1_inittab;
- lnbp21_attach(ttusb->fe, &ttusb->i2c_adap, 0, 0);
+ dvb_attach(lnbp21_attach, ttusb->fe, &ttusb->i2c_adap, 0, 0);
} else { // ALPS BSRU6
ttusb->fe->ops.set_voltage = ttusb_set_voltage;
}
@@ -1578,7 +1578,7 @@ static void frontend_init(struct ttusb* ttusb)
}
// Grundig 29504-491
- ttusb->fe = tda8083_attach(&ttusb_novas_grundig_29504_491_config, &ttusb->i2c_adap);
+ ttusb->fe = dvb_attach(tda8083_attach, &ttusb_novas_grundig_29504_491_config, &ttusb->i2c_adap);
if (ttusb->fe != NULL) {
ttusb->fe->ops.tuner_ops.set_params = ttusb_novas_grundig_29504_491_tuner_set_params;
ttusb->fe->ops.set_voltage = ttusb_set_voltage;
@@ -1587,13 +1587,13 @@ static void frontend_init(struct ttusb* ttusb)
break;
case 0x1004: // Hauppauge/TT DVB-C budget (ves1820/ALPS TDBE2(sp5659))
- ttusb->fe = ves1820_attach(&alps_tdbe2_config, &ttusb->i2c_adap, read_pwm(ttusb));
+ ttusb->fe = dvb_attach(ves1820_attach, &alps_tdbe2_config, &ttusb->i2c_adap, read_pwm(ttusb));
if (ttusb->fe != NULL) {
ttusb->fe->ops.tuner_ops.set_params = alps_tdbe2_tuner_set_params;
break;
}
- ttusb->fe = stv0297_attach(&dvbc_philips_tdm1316l_config, &ttusb->i2c_adap);
+ ttusb->fe = dvb_attach(stv0297_attach, &dvbc_philips_tdm1316l_config, &ttusb->i2c_adap);
if (ttusb->fe != NULL) {
ttusb->fe->ops.tuner_ops.set_params = dvbc_philips_tdm1316l_tuner_set_params;
break;
@@ -1602,14 +1602,14 @@ static void frontend_init(struct ttusb* ttusb)
case 0x1005: // Hauppauge/TT Nova-USB-t budget (tda10046/Philips td1316(tda6651tt) OR cx22700/ALPS TDMB7(??))
// try the ALPS TDMB7 first
- ttusb->fe = cx22700_attach(&alps_tdmb7_config, &ttusb->i2c_adap);
+ ttusb->fe = dvb_attach(cx22700_attach, &alps_tdmb7_config, &ttusb->i2c_adap);
if (ttusb->fe != NULL) {
ttusb->fe->ops.tuner_ops.set_params = alps_tdmb7_tuner_set_params;
break;
}
// Philips td1316
- ttusb->fe = tda10046_attach(&philips_tdm1316l_config, &ttusb->i2c_adap);
+ ttusb->fe = dvb_attach(tda10046_attach, &philips_tdm1316l_config, &ttusb->i2c_adap);
if (ttusb->fe != NULL) {
ttusb->fe->ops.tuner_ops.init = philips_tdm1316l_tuner_init;
ttusb->fe->ops.tuner_ops.set_params = philips_tdm1316l_tuner_set_params;
@@ -1625,8 +1625,7 @@ static void frontend_init(struct ttusb* ttusb)
} else {
if (dvb_register_frontend(&ttusb->adapter, ttusb->fe)) {
printk("dvb-ttusb-budget: Frontend registration failed!\n");
- if (ttusb->fe->ops.release)
- ttusb->fe->ops.release(ttusb->fe);
+ dvb_frontend_detach(ttusb->fe);
ttusb->fe = NULL;
}
}
@@ -1763,7 +1762,10 @@ static void ttusb_disconnect(struct usb_interface *intf)
dvb_net_release(&ttusb->dvbnet);
dvb_dmxdev_release(&ttusb->dmxdev);
dvb_dmx_release(&ttusb->dvb_demux);
- if (ttusb->fe != NULL) dvb_unregister_frontend(ttusb->fe);
+ if (ttusb->fe != NULL) {
+ dvb_unregister_frontend(ttusb->fe);
+ dvb_frontend_detach(ttusb->fe);
+ }
i2c_del_adapter(&ttusb->i2c_adap);
dvb_unregister_adapter(&ttusb->adapter);
diff --git a/drivers/media/dvb/ttusb-dec/ttusb_dec.c b/drivers/media/dvb/ttusb-dec/ttusb_dec.c
index c9d663549dff..de077a757192 100644
--- a/drivers/media/dvb/ttusb-dec/ttusb_dec.c
+++ b/drivers/media/dvb/ttusb-dec/ttusb_dec.c
@@ -1512,7 +1512,11 @@ static void ttusb_dec_exit_dvb(struct ttusb_dec *dec)
dec->demux.dmx.remove_frontend(&dec->demux.dmx, &dec->frontend);
dvb_dmxdev_release(&dec->dmxdev);
dvb_dmx_release(&dec->demux);
- if (dec->fe) dvb_unregister_frontend(dec->fe);
+ if (dec->fe) {
+ dvb_unregister_frontend(dec->fe);
+ if (dec->fe->ops.release)
+ dec->fe->ops.release(dec->fe);
+ }
dvb_unregister_adapter(&dec->adapter);
}
diff --git a/drivers/media/radio/Kconfig b/drivers/media/radio/Kconfig
index 220076b1b956..7015517e2c1b 100644
--- a/drivers/media/radio/Kconfig
+++ b/drivers/media/radio/Kconfig
@@ -7,7 +7,7 @@ menu "Radio Adapters"
config RADIO_CADET
tristate "ADS Cadet AM/FM Tuner"
- depends on ISA && VIDEO_V4L1
+ depends on ISA && VIDEO_V4L2
---help---
Choose Y here if you have one of these AM/FM radio cards, and then
fill in the port address below.
@@ -25,7 +25,7 @@ config RADIO_CADET
config RADIO_RTRACK
tristate "AIMSlab RadioTrack (aka RadioReveal) support"
- depends on ISA && VIDEO_V4L1
+ depends on ISA && VIDEO_V4L2
---help---
Choose Y here if you have one of these FM radio cards, and then fill
in the port address below.
@@ -59,7 +59,7 @@ config RADIO_RTRACK_PORT
config RADIO_RTRACK2
tristate "AIMSlab RadioTrack II support"
- depends on ISA && VIDEO_V4L1
+ depends on ISA && VIDEO_V4L2
---help---
Choose Y here if you have this FM radio card, and then fill in the
port address below.
@@ -82,7 +82,7 @@ config RADIO_RTRACK2_PORT
config RADIO_AZTECH
tristate "Aztech/Packard Bell Radio"
- depends on ISA && VIDEO_V4L1
+ depends on ISA && VIDEO_V4L2
---help---
Choose Y here if you have one of these FM radio cards, and then fill
in the port address below.
@@ -106,7 +106,7 @@ config RADIO_AZTECH_PORT
config RADIO_GEMTEK
tristate "GemTek Radio Card support"
- depends on ISA && VIDEO_V4L1
+ depends on ISA && VIDEO_V4L2
---help---
Choose Y here if you have this FM radio card, and then fill in the
port address below.
@@ -131,7 +131,7 @@ config RADIO_GEMTEK_PORT
config RADIO_GEMTEK_PCI
tristate "GemTek PCI Radio Card support"
- depends on VIDEO_V4L1 && PCI
+ depends on VIDEO_V4L2 && PCI
---help---
Choose Y here if you have this PCI FM radio card.
@@ -145,7 +145,7 @@ config RADIO_GEMTEK_PCI
config RADIO_MAXIRADIO
tristate "Guillemot MAXI Radio FM 2000 radio"
- depends on VIDEO_V4L1 && PCI
+ depends on VIDEO_V4L2 && PCI
---help---
Choose Y here if you have this radio card. This card may also be
found as Gemtek PCI FM.
@@ -160,7 +160,7 @@ config RADIO_MAXIRADIO
config RADIO_MAESTRO
tristate "Maestro on board radio"
- depends on VIDEO_V4L1
+ depends on VIDEO_V4L2 && PCI
---help---
Say Y here to directly support the on-board radio tuner on the
Maestro 2 or 2E sound card.
@@ -208,7 +208,7 @@ config RADIO_MIROPCM20_RDS
config RADIO_SF16FMI
tristate "SF16FMI Radio"
- depends on ISA && VIDEO_V4L1
+ depends on ISA && VIDEO_V4L2
---help---
Choose Y here if you have one of these FM radio cards. If you
compile the driver into the kernel and your card is not PnP one, you
@@ -225,7 +225,7 @@ config RADIO_SF16FMI
config RADIO_SF16FMR2
tristate "SF16FMR2 Radio"
- depends on ISA && VIDEO_V4L1
+ depends on ISA && VIDEO_V4L2
---help---
Choose Y here if you have one of these FM radio cards.
@@ -239,7 +239,7 @@ config RADIO_SF16FMR2
config RADIO_TERRATEC
tristate "TerraTec ActiveRadio ISA Standalone"
- depends on ISA && VIDEO_V4L1
+ depends on ISA && VIDEO_V4L2
---help---
Choose Y here if you have this FM radio card, and then fill in the
port address below. (TODO)
@@ -268,7 +268,7 @@ config RADIO_TERRATEC_PORT
config RADIO_TRUST
tristate "Trust FM radio card"
- depends on ISA && VIDEO_V4L1
+ depends on ISA && VIDEO_V4L2
help
This is a driver for the Trust FM radio cards. Say Y if you have
such a card and want to use it under Linux.
@@ -286,7 +286,7 @@ config RADIO_TRUST_PORT
config RADIO_TYPHOON
tristate "Typhoon Radio (a.k.a. EcoRadio)"
- depends on ISA && VIDEO_V4L1
+ depends on ISA && VIDEO_V4L2
---help---
Choose Y here if you have one of these FM radio cards, and then fill
in the port address and the frequency used for muting below.
@@ -330,7 +330,7 @@ config RADIO_TYPHOON_MUTEFREQ
config RADIO_ZOLTRIX
tristate "Zoltrix Radio"
- depends on ISA && VIDEO_V4L1
+ depends on ISA && VIDEO_V4L2
---help---
Choose Y here if you have one of these FM radio cards, and then fill
in the port address below.
@@ -352,7 +352,7 @@ config RADIO_ZOLTRIX_PORT
config USB_DSBR
tristate "D-Link USB FM radio support (EXPERIMENTAL)"
- depends on USB && VIDEO_V4L1 && EXPERIMENTAL
+ depends on USB && VIDEO_V4L2 && EXPERIMENTAL
---help---
Say Y here if you want to connect this type of radio to your
computer's USB port. Note that the audio is not digital, and
diff --git a/drivers/media/radio/dsbr100.c b/drivers/media/radio/dsbr100.c
index f7e33f9ee8e9..db865a0667e5 100644
--- a/drivers/media/radio/dsbr100.c
+++ b/drivers/media/radio/dsbr100.c
@@ -33,8 +33,14 @@
History:
+ Version 0.41-ac1:
+ Alan Cox: Some cleanups and fixes
+
+ Version 0.41:
+ Converted to V4L2 API by Mauro Carvalho Chehab <mchehab@infradead.org>
+
Version 0.40:
- Markus: Updates for 2.6.x kernels, code layout changes, name sanitizing
+ Markus: Updates for 2.6.x kernels, code layout changes, name sanitizing
Version 0.30:
Markus: Updates for 2.5.x kernel and more ISO compliant source
@@ -65,13 +71,12 @@
*/
-
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/input.h>
-#include <linux/videodev.h>
+#include <linux/videodev2.h>
#include <media/v4l2-common.h>
#include <linux/usb.h>
#include <linux/smp_lock.h>
@@ -79,7 +84,22 @@
/*
* Version Information
*/
-#define DRIVER_VERSION "v0.40"
+#include <linux/version.h> /* for KERNEL_VERSION MACRO */
+
+#define DRIVER_VERSION "v0.41"
+#define RADIO_VERSION KERNEL_VERSION(0,4,1)
+
+static struct v4l2_queryctrl radio_qctrl[] = {
+ {
+ .id = V4L2_CID_AUDIO_MUTE,
+ .name = "Mute",
+ .minimum = 0,
+ .maximum = 1,
+ .default_value = 1,
+ .type = V4L2_CTRL_TYPE_BOOLEAN,
+ }
+};
+
#define DRIVER_AUTHOR "Markus Demleitner <msdemlei@tucana.harvard.edu>"
#define DRIVER_DESC "D-Link DSB-R100 USB FM radio driver"
@@ -111,7 +131,7 @@ static int radio_nr = -1;
module_param(radio_nr, int, 0);
/* Data for one (physical) device */
-typedef struct {
+struct dsbr100_device {
struct usb_device *usbdev;
struct video_device *videodev;
unsigned char transfer_buffer[TB_LEN];
@@ -119,7 +139,8 @@ typedef struct {
int stereo;
int users;
int removed;
-} dsbr100_device;
+ int muted;
+};
/* File system interface */
@@ -138,7 +159,6 @@ static struct video_device dsbr100_videodev_template=
.owner = THIS_MODULE,
.name = "D-Link DSB-R 100",
.type = VID_TYPE_TUNER,
- .hardware = VID_HARDWARE_AZTECH,
.fops = &usb_dsbr100_fops,
.release = video_device_release,
};
@@ -161,7 +181,7 @@ static struct usb_driver usb_dsbr100_driver = {
/* Low-level device interface begins here */
/* switch on radio */
-static int dsbr100_start(dsbr100_device *radio)
+static int dsbr100_start(struct dsbr100_device *radio)
{
if (usb_control_msg(radio->usbdev, usb_rcvctrlpipe(radio->usbdev, 0),
USB_REQ_GET_STATUS,
@@ -172,12 +192,13 @@ static int dsbr100_start(dsbr100_device *radio)
USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
0x01, 0x00, radio->transfer_buffer, 8, 300)<0)
return -1;
+ radio->muted=0;
return (radio->transfer_buffer)[0];
}
/* switch off radio */
-static int dsbr100_stop(dsbr100_device *radio)
+static int dsbr100_stop(struct dsbr100_device *radio)
{
if (usb_control_msg(radio->usbdev, usb_rcvctrlpipe(radio->usbdev, 0),
USB_REQ_GET_STATUS,
@@ -188,11 +209,12 @@ static int dsbr100_stop(dsbr100_device *radio)
USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
0x00, 0x00, radio->transfer_buffer, 8, 300)<0)
return -1;
+ radio->muted=1;
return (radio->transfer_buffer)[0];
}
/* set a frequency, freq is defined by v4l's TUNER_LOW, i.e. 1/16th kHz */
-static int dsbr100_setfreq(dsbr100_device *radio, int freq)
+static int dsbr100_setfreq(struct dsbr100_device *radio, int freq)
{
freq = (freq/16*80)/1000+856;
if (usb_control_msg(radio->usbdev, usb_rcvctrlpipe(radio->usbdev, 0),
@@ -217,7 +239,7 @@ static int dsbr100_setfreq(dsbr100_device *radio, int freq)
/* return the device status. This is, in effect, just whether it
sees a stereo signal or not. Pity. */
-static void dsbr100_getstat(dsbr100_device *radio)
+static void dsbr100_getstat(struct dsbr100_device *radio)
{
if (usb_control_msg(radio->usbdev, usb_rcvctrlpipe(radio->usbdev, 0),
USB_REQ_GET_STATUS,
@@ -236,9 +258,9 @@ usb if it is */
static int usb_dsbr100_probe(struct usb_interface *intf,
const struct usb_device_id *id)
{
- dsbr100_device *radio;
+ struct dsbr100_device *radio;
- if (!(radio = kmalloc(sizeof(dsbr100_device), GFP_KERNEL)))
+ if (!(radio = kmalloc(sizeof(struct dsbr100_device), GFP_KERNEL)))
return -ENOMEM;
if (!(radio->videodev = video_device_alloc())) {
kfree(radio);
@@ -271,7 +293,7 @@ code I'd expect I better did that, but if there's a memory
leak here it's tiny (~50 bytes per disconnect) */
static void usb_dsbr100_disconnect(struct usb_interface *intf)
{
- dsbr100_device *radio = usb_get_intfdata(intf);
+ struct dsbr100_device *radio = usb_get_intfdata(intf);
usb_set_intfdata (intf, NULL);
if (radio) {
@@ -291,89 +313,121 @@ static void usb_dsbr100_disconnect(struct usb_interface *intf)
static int usb_dsbr100_do_ioctl(struct inode *inode, struct file *file,
unsigned int cmd, void *arg)
{
- dsbr100_device *radio=video_get_drvdata(video_devdata(file));
+ struct dsbr100_device *radio=video_get_drvdata(video_devdata(file));
if (!radio)
return -EIO;
switch(cmd) {
- case VIDIOCGCAP: {
- struct video_capability *v = arg;
-
- memset(v, 0, sizeof(*v));
- v->type = VID_TYPE_TUNER;
- v->channels = 1;
- v->audios = 1;
- strcpy(v->name, "D-Link R-100 USB FM Radio");
+ case VIDIOC_QUERYCAP:
+ {
+ struct v4l2_capability *v = arg;
+ memset(v,0,sizeof(*v));
+ strlcpy(v->driver, "dsbr100", sizeof (v->driver));
+ strlcpy(v->card, "D-Link R-100 USB FM Radio", sizeof (v->card));
+ sprintf(v->bus_info,"ISA");
+ v->version = RADIO_VERSION;
+ v->capabilities = V4L2_CAP_TUNER;
+
return 0;
}
- case VIDIOCGTUNER: {
- struct video_tuner *v = arg;
+ case VIDIOC_G_TUNER:
+ {
+ struct v4l2_tuner *v = arg;
- dsbr100_getstat(radio);
- if(v->tuner) /* Only 1 tuner */
+ if (v->index > 0)
return -EINVAL;
+
+ dsbr100_getstat(radio);
+
+ memset(v,0,sizeof(*v));
+ strcpy(v->name, "FM");
+ v->type = V4L2_TUNER_RADIO;
+
v->rangelow = FREQ_MIN*FREQ_MUL;
v->rangehigh = FREQ_MAX*FREQ_MUL;
- v->flags = VIDEO_TUNER_LOW;
- v->mode = VIDEO_MODE_AUTO;
- v->signal = radio->stereo*0x7000;
- /* Don't know how to get signal strength */
- v->flags |= VIDEO_TUNER_STEREO_ON*radio->stereo;
- strcpy(v->name, "DSB R-100");
- return 0;
- }
- case VIDIOCSTUNER: {
- struct video_tuner *v = arg;
+ v->rxsubchans =V4L2_TUNER_SUB_MONO|V4L2_TUNER_SUB_STEREO;
+ v->capability=V4L2_TUNER_CAP_LOW;
+ if(radio->stereo)
+ v->audmode = V4L2_TUNER_MODE_STEREO;
+ else
+ v->audmode = V4L2_TUNER_MODE_MONO;
+ v->signal = 0xFFFF; /* We can't get the signal strength */
- if(v->tuner!=0)
- return -EINVAL;
- /* Only 1 tuner so no setting needed ! */
return 0;
}
- case VIDIOCGFREQ: {
- int *freq = arg;
+ case VIDIOC_S_TUNER:
+ {
+ struct v4l2_tuner *v = arg;
- if (radio->curfreq==-1)
+ if (v->index > 0)
return -EINVAL;
- *freq = radio->curfreq;
+
return 0;
}
- case VIDIOCSFREQ: {
- int *freq = arg;
+ case VIDIOC_S_FREQUENCY:
+ {
+ struct v4l2_frequency *f = arg;
- radio->curfreq = *freq;
+ radio->curfreq = f->frequency;
if (dsbr100_setfreq(radio, radio->curfreq)==-1)
warn("Set frequency failed");
return 0;
}
- case VIDIOCGAUDIO: {
- struct video_audio *v = arg;
-
- memset(v, 0, sizeof(*v));
- v->flags |= VIDEO_AUDIO_MUTABLE;
- v->mode = VIDEO_SOUND_STEREO;
- v->volume = 1;
- v->step = 1;
- strcpy(v->name, "Radio");
+ case VIDIOC_G_FREQUENCY:
+ {
+ struct v4l2_frequency *f = arg;
+
+ f->type = V4L2_TUNER_RADIO;
+ f->frequency = radio->curfreq;
+
return 0;
}
- case VIDIOCSAUDIO: {
- struct video_audio *v = arg;
-
- if (v->audio)
- return -EINVAL;
- if (v->flags&VIDEO_AUDIO_MUTE) {
- if (dsbr100_stop(radio)==-1)
- warn("Radio did not respond properly");
+ case VIDIOC_QUERYCTRL:
+ {
+ struct v4l2_queryctrl *qc = arg;
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) {
+ if (qc->id && qc->id == radio_qctrl[i].id) {
+ memcpy(qc, &(radio_qctrl[i]),
+ sizeof(*qc));
+ return 0;
+ }
}
- else
- if (dsbr100_start(radio)==-1)
- warn("Radio did not respond properly");
- return 0;
+ return -EINVAL;
+ }
+ case VIDIOC_G_CTRL:
+ {
+ struct v4l2_control *ctrl= arg;
+
+ switch (ctrl->id) {
+ case V4L2_CID_AUDIO_MUTE:
+ ctrl->value=radio->muted;
+ return 0;
+ }
+ return -EINVAL;
+ }
+ case VIDIOC_S_CTRL:
+ {
+ struct v4l2_control *ctrl= arg;
+
+ switch (ctrl->id) {
+ case V4L2_CID_AUDIO_MUTE:
+ if (ctrl->value) {
+ if (dsbr100_stop(radio)==-1)
+ warn("Radio did not respond properly");
+ } else {
+ if (dsbr100_start(radio)==-1)
+ warn("Radio did not respond properly");
+ }
+ return 0;
+ }
+ return -EINVAL;
}
default:
- return -ENOIOCTLCMD;
+ return v4l_compat_translate_ioctl(inode,file,cmd,arg,
+ usb_dsbr100_do_ioctl);
}
}
@@ -385,9 +439,11 @@ static int usb_dsbr100_ioctl(struct inode *inode, struct file *file,
static int usb_dsbr100_open(struct inode *inode, struct file *file)
{
- dsbr100_device *radio=video_get_drvdata(video_devdata(file));
+ struct dsbr100_device *radio=video_get_drvdata(video_devdata(file));
radio->users = 1;
+ radio->muted = 1;
+
if (dsbr100_start(radio)<0) {
warn("Radio did not start up properly");
radio->users = 0;
@@ -399,7 +455,7 @@ static int usb_dsbr100_open(struct inode *inode, struct file *file)
static int usb_dsbr100_close(struct inode *inode, struct file *file)
{
- dsbr100_device *radio=video_get_drvdata(video_devdata(file));
+ struct dsbr100_device *radio=video_get_drvdata(video_devdata(file));
if (!radio)
return -ENODEV;
diff --git a/drivers/media/radio/radio-aimslab.c b/drivers/media/radio/radio-aimslab.c
index df22a582e7a2..3368a89bfadb 100644
--- a/drivers/media/radio/radio-aimslab.c
+++ b/drivers/media/radio/radio-aimslab.c
@@ -1,5 +1,6 @@
/* radiotrack (radioreveal) driver for Linux radio support
* (c) 1997 M. Kirkwood
+ * Converted to V4L2 API by Mauro Carvalho Chehab <mchehab@infradead.org>
* Converted to new API by Alan Cox <Alan.Cox@linux.org>
* Various bugfixes and enhancements by Russell Kroll <rkroll@exploits.org>
*
@@ -33,11 +34,13 @@
#include <linux/delay.h> /* udelay */
#include <asm/io.h> /* outb, outb_p */
#include <asm/uaccess.h> /* copy to/from user */
-#include <linux/videodev.h> /* kernel radio structs */
+#include <linux/videodev2.h> /* kernel radio structs */
#include <media/v4l2-common.h>
-#include <linux/config.h> /* CONFIG_RADIO_RTRACK_PORT */
#include <asm/semaphore.h> /* Lock for the I/O */
+#include <linux/version.h> /* for KERNEL_VERSION MACRO */
+#define RADIO_VERSION KERNEL_VERSION(0,0,2)
+
#ifndef CONFIG_RADIO_RTRACK_PORT
#define CONFIG_RADIO_RTRACK_PORT -1
#endif
@@ -209,6 +212,25 @@ static int rt_getsigstr(struct rt_device *dev)
return 1; /* signal present */
}
+static struct v4l2_queryctrl radio_qctrl[] = {
+ {
+ .id = V4L2_CID_AUDIO_MUTE,
+ .name = "Mute",
+ .minimum = 0,
+ .maximum = 1,
+ .default_value = 1,
+ .type = V4L2_CTRL_TYPE_BOOLEAN,
+ },{
+ .id = V4L2_CID_AUDIO_VOLUME,
+ .name = "Volume",
+ .minimum = 0,
+ .maximum = 0xff,
+ .step = 1,
+ .default_value = 0xff,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ }
+};
+
static int rt_do_ioctl(struct inode *inode, struct file *file,
unsigned int cmd, void *arg)
{
@@ -217,73 +239,114 @@ static int rt_do_ioctl(struct inode *inode, struct file *file,
switch(cmd)
{
- case VIDIOCGCAP:
+ case VIDIOC_QUERYCAP:
{
- struct video_capability *v = arg;
+ struct v4l2_capability *v = arg;
memset(v,0,sizeof(*v));
- v->type=VID_TYPE_TUNER;
- v->channels=1;
- v->audios=1;
- strcpy(v->name, "RadioTrack");
+ strlcpy(v->driver, "radio-aimslab", sizeof (v->driver));
+ strlcpy(v->card, "RadioTrack", sizeof (v->card));
+ sprintf(v->bus_info,"ISA");
+ v->version = RADIO_VERSION;
+ v->capabilities = V4L2_CAP_TUNER;
+
return 0;
}
- case VIDIOCGTUNER:
+ case VIDIOC_G_TUNER:
{
- struct video_tuner *v = arg;
- if(v->tuner) /* Only 1 tuner */
+ struct v4l2_tuner *v = arg;
+
+ if (v->index > 0)
return -EINVAL;
+
+ memset(v,0,sizeof(*v));
+ strcpy(v->name, "FM");
+ v->type = V4L2_TUNER_RADIO;
+
v->rangelow=(87*16000);
v->rangehigh=(108*16000);
- v->flags=VIDEO_TUNER_LOW;
- v->mode=VIDEO_MODE_AUTO;
- strcpy(v->name, "FM");
+ v->rxsubchans =V4L2_TUNER_SUB_MONO;
+ v->capability=V4L2_TUNER_CAP_LOW;
+ v->audmode = V4L2_TUNER_MODE_MONO;
v->signal=0xFFFF*rt_getsigstr(rt);
+
return 0;
}
- case VIDIOCSTUNER:
+ case VIDIOC_S_TUNER:
{
- struct video_tuner *v = arg;
- if(v->tuner!=0)
+ struct v4l2_tuner *v = arg;
+
+ if (v->index > 0)
return -EINVAL;
- /* Only 1 tuner so no setting needed ! */
+
return 0;
}
- case VIDIOCGFREQ:
+ case VIDIOC_S_FREQUENCY:
{
- unsigned long *freq = arg;
- *freq = rt->curfreq;
+ struct v4l2_frequency *f = arg;
+
+ rt->curfreq = f->frequency;
+ rt_setfreq(rt, rt->curfreq);
return 0;
}
- case VIDIOCSFREQ:
+ case VIDIOC_G_FREQUENCY:
{
- unsigned long *freq = arg;
- rt->curfreq = *freq;
- rt_setfreq(rt, rt->curfreq);
+ struct v4l2_frequency *f = arg;
+
+ f->type = V4L2_TUNER_RADIO;
+ f->frequency = rt->curfreq;
+
return 0;
}
- case VIDIOCGAUDIO:
+ case VIDIOC_QUERYCTRL:
{
- struct video_audio *v = arg;
- memset(v,0, sizeof(*v));
- v->flags|=VIDEO_AUDIO_MUTABLE|VIDEO_AUDIO_VOLUME;
- v->volume=rt->curvol * 6554;
- v->step=6554;
- strcpy(v->name, "Radio");
- return 0;
+ struct v4l2_queryctrl *qc = arg;
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) {
+ if (qc->id && qc->id == radio_qctrl[i].id) {
+ memcpy(qc, &(radio_qctrl[i]),
+ sizeof(*qc));
+ return (0);
+ }
+ }
+ return -EINVAL;
}
- case VIDIOCSAUDIO:
+ case VIDIOC_G_CTRL:
{
- struct video_audio *v = arg;
- if(v->audio)
- return -EINVAL;
- if(v->flags&VIDEO_AUDIO_MUTE)
- rt_mute(rt);
- else
- rt_setvol(rt,v->volume/6554);
- return 0;
+ struct v4l2_control *ctrl= arg;
+
+ switch (ctrl->id) {
+ case V4L2_CID_AUDIO_MUTE:
+ ctrl->value=rt->muted;
+ return (0);
+ case V4L2_CID_AUDIO_VOLUME:
+ ctrl->value=rt->curvol * 6554;
+ return (0);
+ }
+ return -EINVAL;
}
+ case VIDIOC_S_CTRL:
+ {
+ struct v4l2_control *ctrl= arg;
+
+ switch (ctrl->id) {
+ case V4L2_CID_AUDIO_MUTE:
+ if (ctrl->value) {
+ rt_mute(rt);
+ } else {
+ rt_setvol(rt,rt->curvol);
+ }
+ return (0);
+ case V4L2_CID_AUDIO_VOLUME:
+ rt_setvol(rt,ctrl->value);
+ return (0);
+ }
+ return -EINVAL;
+ }
+
default:
- return -ENOIOCTLCMD;
+ return v4l_compat_translate_ioctl(inode,file,cmd,arg,
+ rt_do_ioctl);
}
}
@@ -309,7 +372,7 @@ static struct video_device rtrack_radio=
.owner = THIS_MODULE,
.name = "RadioTrack radio",
.type = VID_TYPE_TUNER,
- .hardware = VID_HARDWARE_RTRACK,
+ .hardware = 0,
.fops = &rtrack_fops,
};
diff --git a/drivers/media/radio/radio-aztech.c b/drivers/media/radio/radio-aztech.c
index 95e6322133ee..3ba5fa8cf7e6 100644
--- a/drivers/media/radio/radio-aztech.c
+++ b/drivers/media/radio/radio-aztech.c
@@ -1,5 +1,6 @@
/* radio-aztech.c - Aztech radio card driver for Linux 2.2
*
+ * Converted to V4L2 API by Mauro Carvalho Chehab <mchehab@infradead.org>
* Adapted to support the Video for Linux API by
* Russell Kroll <rkroll@exploits.org>. Based on original tuner code by:
*
@@ -30,9 +31,30 @@
#include <linux/delay.h> /* udelay */
#include <asm/io.h> /* outb, outb_p */
#include <asm/uaccess.h> /* copy to/from user */
-#include <linux/videodev.h> /* kernel radio structs */
+#include <linux/videodev2.h> /* kernel radio structs */
#include <media/v4l2-common.h>
-#include <linux/config.h> /* CONFIG_RADIO_AZTECH_PORT */
+
+#include <linux/version.h> /* for KERNEL_VERSION MACRO */
+#define RADIO_VERSION KERNEL_VERSION(0,0,2)
+
+static struct v4l2_queryctrl radio_qctrl[] = {
+ {
+ .id = V4L2_CID_AUDIO_MUTE,
+ .name = "Mute",
+ .minimum = 0,
+ .maximum = 1,
+ .default_value = 1,
+ .type = V4L2_CTRL_TYPE_BOOLEAN,
+ },{
+ .id = V4L2_CID_AUDIO_VOLUME,
+ .name = "Volume",
+ .minimum = 0,
+ .maximum = 0xff,
+ .step = 1,
+ .default_value = 0xff,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ }
+};
/* acceptable ports: 0x350 (JP3 shorted), 0x358 (JP3 open) */
@@ -166,81 +188,121 @@ static int az_do_ioctl(struct inode *inode, struct file *file,
switch(cmd)
{
- case VIDIOCGCAP:
+ case VIDIOC_QUERYCAP:
{
- struct video_capability *v = arg;
+ struct v4l2_capability *v = arg;
memset(v,0,sizeof(*v));
- v->type=VID_TYPE_TUNER;
- v->channels=1;
- v->audios=1;
- strcpy(v->name, "Aztech Radio");
+ strlcpy(v->driver, "radio-aztech", sizeof (v->driver));
+ strlcpy(v->card, "Aztech Radio", sizeof (v->card));
+ sprintf(v->bus_info,"ISA");
+ v->version = RADIO_VERSION;
+ v->capabilities = V4L2_CAP_TUNER;
+
return 0;
}
- case VIDIOCGTUNER:
+ case VIDIOC_G_TUNER:
{
- struct video_tuner *v = arg;
- if(v->tuner) /* Only 1 tuner */
+ struct v4l2_tuner *v = arg;
+
+ if (v->index > 0)
return -EINVAL;
+
+ memset(v,0,sizeof(*v));
+ strcpy(v->name, "FM");
+ v->type = V4L2_TUNER_RADIO;
+
v->rangelow=(87*16000);
v->rangehigh=(108*16000);
- v->flags=VIDEO_TUNER_LOW;
- v->mode=VIDEO_MODE_AUTO;
- v->signal=0xFFFF*az_getsigstr(az);
+ v->rxsubchans =V4L2_TUNER_SUB_MONO|V4L2_TUNER_SUB_STEREO;
+ v->capability=V4L2_TUNER_CAP_LOW;
if(az_getstereo(az))
- v->flags|=VIDEO_TUNER_STEREO_ON;
- strcpy(v->name, "FM");
+ v->audmode = V4L2_TUNER_MODE_STEREO;
+ else
+ v->audmode = V4L2_TUNER_MODE_MONO;
+ v->signal=0xFFFF*az_getsigstr(az);
+
return 0;
}
- case VIDIOCSTUNER:
+ case VIDIOC_S_TUNER:
{
- struct video_tuner *v = arg;
- if(v->tuner!=0)
+ struct v4l2_tuner *v = arg;
+
+ if (v->index > 0)
return -EINVAL;
+
return 0;
}
- case VIDIOCGFREQ:
+ case VIDIOC_S_FREQUENCY:
{
- unsigned long *freq = arg;
- *freq = az->curfreq;
+ struct v4l2_frequency *f = arg;
+
+ az->curfreq = f->frequency;
+ az_setfreq(az, az->curfreq);
return 0;
}
- case VIDIOCSFREQ:
+ case VIDIOC_G_FREQUENCY:
{
- unsigned long *freq = arg;
- az->curfreq = *freq;
- az_setfreq(az, az->curfreq);
+ struct v4l2_frequency *f = arg;
+
+ f->type = V4L2_TUNER_RADIO;
+ f->frequency = az->curfreq;
+
return 0;
}
- case VIDIOCGAUDIO:
+
+ case VIDIOC_QUERYCTRL:
{
- struct video_audio *v = arg;
- memset(v,0, sizeof(*v));
- v->flags|=VIDEO_AUDIO_MUTABLE|VIDEO_AUDIO_VOLUME;
- if(az->stereo)
- v->mode=VIDEO_SOUND_STEREO;
- else
- v->mode=VIDEO_SOUND_MONO;
- v->volume=az->curvol;
- v->step=16384;
- strcpy(v->name, "Radio");
- return 0;
+ struct v4l2_queryctrl *qc = arg;
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) {
+ if (qc->id && qc->id == radio_qctrl[i].id) {
+ memcpy(qc, &(radio_qctrl[i]),
+ sizeof(*qc));
+ return (0);
+ }
+ }
+ return -EINVAL;
}
- case VIDIOCSAUDIO:
+ case VIDIOC_G_CTRL:
{
- struct video_audio *v = arg;
- if(v->audio)
- return -EINVAL;
- az->curvol=v->volume;
-
- az->stereo=(v->mode&VIDEO_SOUND_STEREO)?1:0;
- if(v->flags&VIDEO_AUDIO_MUTE)
- az_setvol(az,0);
- else
- az_setvol(az,az->curvol);
- return 0;
+ struct v4l2_control *ctrl= arg;
+
+ switch (ctrl->id) {
+ case V4L2_CID_AUDIO_MUTE:
+ if (az->curvol==0)
+ ctrl->value=1;
+ else
+ ctrl->value=0;
+ return (0);
+ case V4L2_CID_AUDIO_VOLUME:
+ ctrl->value=az->curvol * 6554;
+ return (0);
+ }
+ return -EINVAL;
+ }
+ case VIDIOC_S_CTRL:
+ {
+ struct v4l2_control *ctrl= arg;
+
+ switch (ctrl->id) {
+ case V4L2_CID_AUDIO_MUTE:
+ if (ctrl->value) {
+ az_setvol(az,0);
+ } else {
+ az_setvol(az,az->curvol);
+ }
+ return (0);
+ case V4L2_CID_AUDIO_VOLUME:
+ az_setvol(az,ctrl->value);
+ return (0);
+ }
+ return -EINVAL;
}
+
default:
- return -ENOIOCTLCMD;
+ return v4l_compat_translate_ioctl(inode,file,cmd,arg,
+ az_do_ioctl);
}
}
@@ -266,7 +328,7 @@ static struct video_device aztech_radio=
.owner = THIS_MODULE,
.name = "Aztech radio",
.type = VID_TYPE_TUNER,
- .hardware = VID_HARDWARE_AZTECH,
+ .hardware = 0,
.fops = &aztech_fops,
};
diff --git a/drivers/media/radio/radio-cadet.c b/drivers/media/radio/radio-cadet.c
index 8641aec7baf8..69d4b7919c5a 100644
--- a/drivers/media/radio/radio-cadet.c
+++ b/drivers/media/radio/radio-cadet.c
@@ -25,20 +25,28 @@
*
* 2003-01-31 Alan Cox <alan@redhat.com>
* Cleaned up locking, delay code, general odds and ends
+ *
+ * 2006-07-30 Hans J. Koch <koch@hjk-az.de>
+ * Changed API to V4L2
*/
+#include <linux/version.h>
#include <linux/module.h> /* Modules */
#include <linux/init.h> /* Initdata */
#include <linux/ioport.h> /* request_region */
#include <linux/delay.h> /* udelay */
#include <asm/io.h> /* outb, outb_p */
#include <asm/uaccess.h> /* copy to/from user */
-#include <linux/videodev.h> /* kernel radio structs */
+#include <linux/videodev2.h> /* V4L2 API defs */
#include <media/v4l2-common.h>
#include <linux/param.h>
#include <linux/pnp.h>
#define RDS_BUFFER 256
+#define RDS_RX_FLAG 1
+#define MBS_RX_FLAG 2
+
+#define CADET_VERSION KERNEL_VERSION(0,3,3)
static int io=-1; /* default to isapnp activation */
static int radio_nr = -1;
@@ -61,44 +69,24 @@ static int cadet_probe(void);
*/
static __u16 sigtable[2][4]={{5,10,30,150},{28,40,63,1000}};
-static int cadet_getrds(void)
-{
- int rdsstat=0;
-
- spin_lock(&cadet_io_lock);
- outb(3,io); /* Select Decoder Control/Status */
- outb(inb(io+1)&0x7f,io+1); /* Reset RDS detection */
- spin_unlock(&cadet_io_lock);
-
- msleep(100);
-
- spin_lock(&cadet_io_lock);
- outb(3,io); /* Select Decoder Control/Status */
- if((inb(io+1)&0x80)!=0) {
- rdsstat|=VIDEO_TUNER_RDS_ON;
- }
- if((inb(io+1)&0x10)!=0) {
- rdsstat|=VIDEO_TUNER_MBS_ON;
- }
- spin_unlock(&cadet_io_lock);
- return rdsstat;
-}
-static int cadet_getstereo(void)
+static int
+cadet_getstereo(void)
{
- int ret = 0;
+ int ret = V4L2_TUNER_SUB_MONO;
if(curtuner != 0) /* Only FM has stereo capability! */
- return 0;
+ return V4L2_TUNER_SUB_MONO;
spin_lock(&cadet_io_lock);
outb(7,io); /* Select tuner control */
if( (inb(io+1) & 0x40) == 0)
- ret = 1;
+ ret = V4L2_TUNER_SUB_STEREO;
spin_unlock(&cadet_io_lock);
return ret;
}
-static unsigned cadet_gettune(void)
+static unsigned
+cadet_gettune(void)
{
int curvol,i;
unsigned fifo=0;
@@ -135,7 +123,8 @@ static unsigned cadet_gettune(void)
return fifo;
}
-static unsigned cadet_getfreq(void)
+static unsigned
+cadet_getfreq(void)
{
int i;
unsigned freq=0,test,fifo=0;
@@ -167,7 +156,8 @@ static unsigned cadet_getfreq(void)
return freq;
}
-static void cadet_settune(unsigned fifo)
+static void
+cadet_settune(unsigned fifo)
{
int i;
unsigned test;
@@ -195,7 +185,8 @@ static void cadet_settune(unsigned fifo)
spin_unlock(&cadet_io_lock);
}
-static void cadet_setfreq(unsigned freq)
+static void
+cadet_setfreq(unsigned freq)
{
unsigned fifo;
int i,j,test;
@@ -255,7 +246,8 @@ static void cadet_setfreq(unsigned freq)
}
-static int cadet_getvol(void)
+static int
+cadet_getvol(void)
{
int ret = 0;
@@ -270,7 +262,8 @@ static int cadet_getvol(void)
}
-static void cadet_setvol(int vol)
+static void
+cadet_setvol(int vol)
{
spin_lock(&cadet_io_lock);
outb(7,io); /* Select tuner control */
@@ -281,7 +274,8 @@ static void cadet_setvol(int vol)
spin_unlock(&cadet_io_lock);
}
-static void cadet_handler(unsigned long data)
+static void
+cadet_handler(unsigned long data)
{
/*
* Service the RDS fifo
@@ -322,8 +316,8 @@ static void cadet_handler(unsigned long data)
-static ssize_t cadet_read(struct file *file, char __user *data,
- size_t count, loff_t *ppos)
+static ssize_t
+cadet_read(struct file *file, char __user *data, size_t count, loff_t *ppos)
{
int i=0;
unsigned char readbuf[RDS_BUFFER];
@@ -359,128 +353,156 @@ static int cadet_do_ioctl(struct inode *inode, struct file *file,
{
switch(cmd)
{
- case VIDIOCGCAP:
+ case VIDIOC_QUERYCAP:
{
- struct video_capability *v = arg;
- memset(v,0,sizeof(*v));
- v->type=VID_TYPE_TUNER;
- v->channels=2;
- v->audios=1;
- strcpy(v->name, "ADS Cadet");
+ struct v4l2_capability *cap = arg;
+ memset(cap,0,sizeof(*cap));
+ cap->capabilities =
+ V4L2_CAP_TUNER |
+ V4L2_CAP_READWRITE;
+ cap->version = CADET_VERSION;
+ strcpy(cap->driver, "ADS Cadet");
+ strcpy(cap->card, "ADS Cadet");
return 0;
}
- case VIDIOCGTUNER:
+ case VIDIOC_G_TUNER:
{
- struct video_tuner *v = arg;
- if((v->tuner<0)||(v->tuner>1)) {
- return -EINVAL;
- }
- switch(v->tuner) {
- case 0:
- strcpy(v->name,"FM");
- v->rangelow=1400; /* 87.5 MHz */
- v->rangehigh=1728; /* 108.0 MHz */
- v->flags=0;
- v->mode=0;
- v->mode|=VIDEO_MODE_AUTO;
- v->signal=sigstrength;
- if(cadet_getstereo()==1) {
- v->flags|=VIDEO_TUNER_STEREO_ON;
- }
- v->flags|=cadet_getrds();
- break;
- case 1:
- strcpy(v->name,"AM");
- v->rangelow=8320; /* 520 kHz */
- v->rangehigh=26400; /* 1650 kHz */
- v->flags=0;
- v->flags|=VIDEO_TUNER_LOW;
- v->mode=0;
- v->mode|=VIDEO_MODE_AUTO;
- v->signal=sigstrength;
- break;
+ struct v4l2_tuner *t = arg;
+ memset(t,0,sizeof(*t));
+ t->type = V4L2_TUNER_RADIO;
+ switch (t->index)
+ {
+ case 0: strcpy(t->name, "FM");
+ t->capability = V4L2_TUNER_CAP_STEREO;
+ t->rangelow = 1400; /* 87.5 MHz */
+ t->rangehigh = 1728; /* 108.0 MHz */
+ t->rxsubchans=cadet_getstereo();
+ switch (t->rxsubchans){
+ case V4L2_TUNER_SUB_MONO:
+ t->audmode = V4L2_TUNER_MODE_MONO;
+ break;
+ case V4L2_TUNER_SUB_STEREO:
+ t->audmode = V4L2_TUNER_MODE_STEREO;
+ break;
+ default: ;
+ }
+ break;
+ case 1: strcpy(t->name, "AM");
+ t->capability = V4L2_TUNER_CAP_LOW;
+ t->rangelow = 8320; /* 520 kHz */
+ t->rangehigh = 26400; /* 1650 kHz */
+ t->rxsubchans = V4L2_TUNER_SUB_MONO;
+ t->audmode = V4L2_TUNER_MODE_MONO;
+ break;
+ default:
+ return -EINVAL;
}
+
+ t->signal = sigstrength; /* We might need to modify scaling of this */
return 0;
}
- case VIDIOCSTUNER:
+ case VIDIOC_S_TUNER:
{
- struct video_tuner *v = arg;
- if((v->tuner<0)||(v->tuner>1)) {
+ struct v4l2_tuner *t = arg;
+ if((t->index != 0)&&(t->index != 1))
return -EINVAL;
- }
- curtuner=v->tuner;
+
+ curtuner = t->index;
return 0;
}
- case VIDIOCGFREQ:
+ case VIDIOC_G_FREQUENCY:
{
- unsigned long *freq = arg;
- *freq = cadet_getfreq();
+ struct v4l2_frequency *f = arg;
+ memset(f,0,sizeof(*f));
+ f->tuner = curtuner;
+ f->type = V4L2_TUNER_RADIO;
+ f->frequency = cadet_getfreq();
return 0;
}
- case VIDIOCSFREQ:
+ case VIDIOC_S_FREQUENCY:
{
- unsigned long *freq = arg;
- if((curtuner==0)&&((*freq<1400)||(*freq>1728))) {
+ struct v4l2_frequency *f = arg;
+ if (f->type != V4L2_TUNER_RADIO){
+ return -EINVAL;
+ }
+ if((curtuner==0)&&((f->frequency<1400)||(f->frequency>1728))) {
return -EINVAL;
}
- if((curtuner==1)&&((*freq<8320)||(*freq>26400))) {
+ if((curtuner==1)&&((f->frequency<8320)||(f->frequency>26400))) {
return -EINVAL;
}
- cadet_setfreq(*freq);
+ cadet_setfreq(f->frequency);
return 0;
}
- case VIDIOCGAUDIO:
+ case VIDIOC_G_CTRL:
{
- struct video_audio *v = arg;
- memset(v,0, sizeof(*v));
- v->flags=VIDEO_AUDIO_MUTABLE|VIDEO_AUDIO_VOLUME;
- if(cadet_getstereo()==0) {
- v->mode=VIDEO_SOUND_MONO;
- } else {
- v->mode=VIDEO_SOUND_STEREO;
+ struct v4l2_control *c = arg;
+ switch (c->id){
+ case V4L2_CID_AUDIO_MUTE: /* TODO: Handle this correctly */
+ c->value = (cadet_getvol() == 0);
+ break;
+ case V4L2_CID_AUDIO_VOLUME:
+ c->value = cadet_getvol();
+ break;
+ default:
+ return -EINVAL;
}
- v->volume=cadet_getvol();
- v->step=0xffff;
- strcpy(v->name, "Radio");
return 0;
}
- case VIDIOCSAUDIO:
+ case VIDIOC_S_CTRL:
{
- struct video_audio *v = arg;
- if(v->audio)
- return -EINVAL;
- cadet_setvol(v->volume);
- if(v->flags&VIDEO_AUDIO_MUTE)
- cadet_setvol(0);
- else
- cadet_setvol(0xffff);
+ struct v4l2_control *c = arg;
+ switch (c->id){
+ case V4L2_CID_AUDIO_MUTE: /* TODO: Handle this correctly */
+ if (c->value) cadet_setvol(0);
+ else cadet_setvol(0xffff);
+ break;
+ case V4L2_CID_AUDIO_VOLUME:
+ cadet_setvol(c->value);
+ break;
+ default:
+ return -EINVAL;
+ }
return 0;
}
+
default:
return -ENOIOCTLCMD;
}
}
-static int cadet_ioctl(struct inode *inode, struct file *file,
+static int
+cadet_ioctl(struct inode *inode, struct file *file,
unsigned int cmd, unsigned long arg)
{
return video_usercopy(inode, file, cmd, arg, cadet_do_ioctl);
}
-static int cadet_open(struct inode *inode, struct file *file)
+static int
+cadet_open(struct inode *inode, struct file *file)
{
- if(users)
- return -EBUSY;
users++;
- init_waitqueue_head(&read_queue);
+ if (1 == users) init_waitqueue_head(&read_queue);
return 0;
}
-static int cadet_release(struct inode *inode, struct file *file)
+static int
+cadet_release(struct inode *inode, struct file *file)
{
- del_timer_sync(&readtimer);
- rdsstat=0;
users--;
+ if (0 == users){
+ del_timer_sync(&readtimer);
+ rdsstat=0;
+ }
+ return 0;
+}
+
+static unsigned int
+cadet_poll(struct file *file, struct poll_table_struct *wait)
+{
+ poll_wait(file,&read_queue,wait);
+ if(rdsin != rdsout)
+ return POLLIN | POLLRDNORM;
return 0;
}
@@ -491,6 +513,7 @@ static struct file_operations cadet_fops = {
.release = cadet_release,
.read = cadet_read,
.ioctl = cadet_ioctl,
+ .poll = cadet_poll,
.compat_ioctl = v4l_compat_ioctl32,
.llseek = no_llseek,
};
@@ -500,7 +523,6 @@ static struct video_device cadet_radio=
.owner = THIS_MODULE,
.name = "Cadet radio",
.type = VID_TYPE_TUNER,
- .hardware = VID_HARDWARE_CADET,
.fops = &cadet_fops,
};
diff --git a/drivers/media/radio/radio-gemtek-pci.c b/drivers/media/radio/radio-gemtek-pci.c
index 4c82956390c1..cfab57d6bc4a 100644
--- a/drivers/media/radio/radio-gemtek-pci.c
+++ b/drivers/media/radio/radio-gemtek-pci.c
@@ -34,6 +34,8 @@
*
* TODO: multiple device support and portability were not tested
*
+ * Converted to V4L2 API by Mauro Carvalho Chehab <mchehab@infradead.org>
+ *
***************************************************************************
*/
@@ -42,10 +44,32 @@
#include <linux/module.h>
#include <linux/init.h>
#include <linux/pci.h>
-#include <linux/videodev.h>
+#include <linux/videodev2.h>
#include <media/v4l2-common.h>
#include <linux/errno.h>
+#include <linux/version.h> /* for KERNEL_VERSION MACRO */
+#define RADIO_VERSION KERNEL_VERSION(0,0,2)
+
+static struct v4l2_queryctrl radio_qctrl[] = {
+ {
+ .id = V4L2_CID_AUDIO_MUTE,
+ .name = "Mute",
+ .minimum = 0,
+ .maximum = 1,
+ .default_value = 1,
+ .type = V4L2_CTRL_TYPE_BOOLEAN,
+ },{
+ .id = V4L2_CID_AUDIO_VOLUME,
+ .name = "Volume",
+ .minimum = 0,
+ .maximum = 65535,
+ .step = 65535,
+ .default_value = 0xff,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ }
+};
+
#include <asm/io.h>
#include <asm/uaccess.h>
@@ -183,91 +207,117 @@ static int gemtek_pci_do_ioctl(struct inode *inode, struct file *file,
struct gemtek_pci_card *card = dev->priv;
switch ( cmd ) {
- case VIDIOCGCAP:
+ case VIDIOC_QUERYCAP:
{
- struct video_capability *c = arg;
+ struct v4l2_capability *v = arg;
+ memset(v,0,sizeof(*v));
+ strlcpy(v->driver, "radio-gemtek-pci", sizeof (v->driver));
+ strlcpy(v->card, "GemTek PCI Radio", sizeof (v->card));
+ sprintf(v->bus_info,"ISA");
+ v->version = RADIO_VERSION;
+ v->capabilities = V4L2_CAP_TUNER;
- memset(c,0,sizeof(*c));
- c->type = VID_TYPE_TUNER;
- c->channels = 1;
- c->audios = 1;
- strcpy( c->name, "Gemtek PCI Radio" );
return 0;
}
-
- case VIDIOCGTUNER:
+ case VIDIOC_G_TUNER:
{
- struct video_tuner *t = arg;
+ struct v4l2_tuner *v = arg;
- if ( t->tuner )
+ if (v->index > 0)
return -EINVAL;
- t->rangelow = GEMTEK_PCI_RANGE_LOW;
- t->rangehigh = GEMTEK_PCI_RANGE_HIGH;
- t->flags = VIDEO_TUNER_LOW;
- t->mode = VIDEO_MODE_AUTO;
- t->signal = 0xFFFF * gemtek_pci_getsignal( card );
- strcpy( t->name, "FM" );
+ memset(v,0,sizeof(*v));
+ strcpy(v->name, "FM");
+ v->type = V4L2_TUNER_RADIO;
+
+ v->rangelow = GEMTEK_PCI_RANGE_LOW;
+ v->rangehigh = GEMTEK_PCI_RANGE_HIGH;
+ v->rxsubchans =V4L2_TUNER_SUB_MONO;
+ v->capability=V4L2_TUNER_CAP_LOW;
+ v->audmode = V4L2_TUNER_MODE_MONO;
+ v->signal=0xFFFF*gemtek_pci_getsignal( card );
+
return 0;
}
-
- case VIDIOCSTUNER:
+ case VIDIOC_S_TUNER:
{
- struct video_tuner *t = arg;
- if ( t->tuner )
+ struct v4l2_tuner *v = arg;
+
+ if (v->index > 0)
return -EINVAL;
- return 0;
- }
- case VIDIOCGFREQ:
- {
- unsigned long *freq = arg;
- *freq = card->current_frequency;
return 0;
}
- case VIDIOCSFREQ:
+ case VIDIOC_S_FREQUENCY:
{
- unsigned long *freq = arg;
+ struct v4l2_frequency *f = arg;
- if ( (*freq < GEMTEK_PCI_RANGE_LOW) ||
- (*freq > GEMTEK_PCI_RANGE_HIGH) )
+ if ( (f->frequency < GEMTEK_PCI_RANGE_LOW) ||
+ (f->frequency > GEMTEK_PCI_RANGE_HIGH) )
return -EINVAL;
- gemtek_pci_setfrequency( card, *freq );
- card->current_frequency = *freq;
- card->mute = FALSE;
+ gemtek_pci_setfrequency( card, f->frequency );
+ card->current_frequency = f->frequency;
+ card->mute = FALSE;
return 0;
}
-
- case VIDIOCGAUDIO:
+ case VIDIOC_QUERYCTRL:
{
- struct video_audio *a = arg;
-
- memset( a, 0, sizeof( *a ) );
- a->flags |= VIDEO_AUDIO_MUTABLE;
- a->volume = 1;
- a->step = 65535;
- strcpy( a->name, "Radio" );
- return 0;
+ struct v4l2_queryctrl *qc = arg;
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) {
+ if (qc->id && qc->id == radio_qctrl[i].id) {
+ memcpy(qc, &(radio_qctrl[i]),
+ sizeof(*qc));
+ return (0);
+ }
+ }
+ return -EINVAL;
}
-
- case VIDIOCSAUDIO:
+ case VIDIOC_G_CTRL:
{
- struct video_audio *a = arg;
-
- if ( a->audio )
- return -EINVAL;
-
- if ( a->flags & VIDEO_AUDIO_MUTE )
- gemtek_pci_mute( card );
- else
- gemtek_pci_unmute( card );
- return 0;
+ struct v4l2_control *ctrl= arg;
+
+ switch (ctrl->id) {
+ case V4L2_CID_AUDIO_MUTE:
+ ctrl->value=card->mute;
+ return (0);
+ case V4L2_CID_AUDIO_VOLUME:
+ if (card->mute)
+ ctrl->value=0;
+ else
+ ctrl->value=65535;
+ return (0);
+ }
+ return -EINVAL;
+ }
+ case VIDIOC_S_CTRL:
+ {
+ struct v4l2_control *ctrl= arg;
+
+ switch (ctrl->id) {
+ case V4L2_CID_AUDIO_MUTE:
+ if (ctrl->value) {
+ gemtek_pci_mute(card);
+ } else {
+ gemtek_pci_unmute(card);
+ }
+ return (0);
+ case V4L2_CID_AUDIO_VOLUME:
+ if (ctrl->value) {
+ gemtek_pci_unmute(card);
+ } else {
+ gemtek_pci_mute(card);
+ }
+ return (0);
+ }
+ return -EINVAL;
}
-
default:
- return -ENOIOCTLCMD;
+ return v4l_compat_translate_ioctl(inode,file,cmd,arg,
+ gemtek_pci_do_ioctl);
}
}
@@ -309,7 +359,7 @@ static struct video_device vdev_template = {
.owner = THIS_MODULE,
.name = "Gemtek PCI Radio",
.type = VID_TYPE_TUNER,
- .hardware = VID_HARDWARE_GEMTEK,
+ .hardware = 0,
.fops = &gemtek_pci_fops,
};
diff --git a/drivers/media/radio/radio-gemtek.c b/drivers/media/radio/radio-gemtek.c
index 162f37d8bf96..730fe16126cb 100644
--- a/drivers/media/radio/radio-gemtek.c
+++ b/drivers/media/radio/radio-gemtek.c
@@ -13,6 +13,7 @@
*
* TODO: Allow for more than one of these foolish entities :-)
*
+ * Converted to V4L2 API by Mauro Carvalho Chehab <mchehab@infradead.org>
*/
#include <linux/module.h> /* Modules */
@@ -21,11 +22,32 @@
#include <linux/delay.h> /* udelay */
#include <asm/io.h> /* outb, outb_p */
#include <asm/uaccess.h> /* copy to/from user */
-#include <linux/videodev.h> /* kernel radio structs */
+#include <linux/videodev2.h> /* kernel radio structs */
#include <media/v4l2-common.h>
-#include <linux/config.h> /* CONFIG_RADIO_GEMTEK_PORT */
#include <linux/spinlock.h>
+#include <linux/version.h> /* for KERNEL_VERSION MACRO */
+#define RADIO_VERSION KERNEL_VERSION(0,0,2)
+
+static struct v4l2_queryctrl radio_qctrl[] = {
+ {
+ .id = V4L2_CID_AUDIO_MUTE,
+ .name = "Mute",
+ .minimum = 0,
+ .maximum = 1,
+ .default_value = 1,
+ .type = V4L2_CTRL_TYPE_BOOLEAN,
+ },{
+ .id = V4L2_CID_AUDIO_VOLUME,
+ .name = "Volume",
+ .minimum = 0,
+ .maximum = 65535,
+ .step = 65535,
+ .default_value = 0xff,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ }
+};
+
#ifndef CONFIG_RADIO_GEMTEK_PORT
#define CONFIG_RADIO_GEMTEK_PORT -1
#endif
@@ -147,77 +169,122 @@ static int gemtek_do_ioctl(struct inode *inode, struct file *file,
switch(cmd)
{
- case VIDIOCGCAP:
+ case VIDIOC_QUERYCAP:
{
- struct video_capability *v = arg;
+ struct v4l2_capability *v = arg;
memset(v,0,sizeof(*v));
- v->type=VID_TYPE_TUNER;
- v->channels=1;
- v->audios=1;
- strcpy(v->name, "GemTek");
+ strlcpy(v->driver, "radio-gemtek", sizeof (v->driver));
+ strlcpy(v->card, "GemTek", sizeof (v->card));
+ sprintf(v->bus_info,"ISA");
+ v->version = RADIO_VERSION;
+ v->capabilities = V4L2_CAP_TUNER;
+
return 0;
}
- case VIDIOCGTUNER:
+ case VIDIOC_G_TUNER:
{
- struct video_tuner *v = arg;
- if(v->tuner) /* Only 1 tuner */
+ struct v4l2_tuner *v = arg;
+
+ if (v->index > 0)
return -EINVAL;
- v->rangelow=87*16000;
- v->rangehigh=108*16000;
- v->flags=VIDEO_TUNER_LOW;
- v->mode=VIDEO_MODE_AUTO;
- v->signal=0xFFFF*gemtek_getsigstr(rt);
+
+ memset(v,0,sizeof(*v));
strcpy(v->name, "FM");
+ v->type = V4L2_TUNER_RADIO;
+
+ v->rangelow=(87*16000);
+ v->rangehigh=(108*16000);
+ v->rxsubchans =V4L2_TUNER_SUB_MONO;
+ v->capability=V4L2_TUNER_CAP_LOW;
+ v->audmode = V4L2_TUNER_MODE_MONO;
+ v->signal=0xFFFF*gemtek_getsigstr(rt);
+
return 0;
}
- case VIDIOCSTUNER:
+ case VIDIOC_S_TUNER:
{
- struct video_tuner *v = arg;
- if(v->tuner!=0)
+ struct v4l2_tuner *v = arg;
+
+ if (v->index > 0)
return -EINVAL;
- /* Only 1 tuner so no setting needed ! */
- return 0;
- }
- case VIDIOCGFREQ:
- {
- unsigned long *freq = arg;
- *freq = rt->curfreq;
+
return 0;
}
- case VIDIOCSFREQ:
+ case VIDIOC_S_FREQUENCY:
{
- unsigned long *freq = arg;
- rt->curfreq = *freq;
+ struct v4l2_frequency *f = arg;
+
+ rt->curfreq = f->frequency;
/* needs to be called twice in order for getsigstr to work */
gemtek_setfreq(rt, rt->curfreq);
gemtek_setfreq(rt, rt->curfreq);
return 0;
}
- case VIDIOCGAUDIO:
- {
- struct video_audio *v = arg;
- memset(v,0, sizeof(*v));
- v->flags|=VIDEO_AUDIO_MUTABLE;
- v->volume=1;
- v->step=65535;
- strcpy(v->name, "Radio");
- return 0;
- }
- case VIDIOCSAUDIO:
+ case VIDIOC_G_FREQUENCY:
{
- struct video_audio *v = arg;
- if(v->audio)
- return -EINVAL;
+ struct v4l2_frequency *f = arg;
- if(v->flags&VIDEO_AUDIO_MUTE)
- gemtek_mute(rt);
- else
- gemtek_unmute(rt);
+ f->type = V4L2_TUNER_RADIO;
+ f->frequency = rt->curfreq;
return 0;
}
+ case VIDIOC_QUERYCTRL:
+ {
+ struct v4l2_queryctrl *qc = arg;
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) {
+ if (qc->id && qc->id == radio_qctrl[i].id) {
+ memcpy(qc, &(radio_qctrl[i]),
+ sizeof(*qc));
+ return (0);
+ }
+ }
+ return -EINVAL;
+ }
+ case VIDIOC_G_CTRL:
+ {
+ struct v4l2_control *ctrl= arg;
+
+ switch (ctrl->id) {
+ case V4L2_CID_AUDIO_MUTE:
+ ctrl->value=rt->muted;
+ return (0);
+ case V4L2_CID_AUDIO_VOLUME:
+ if (rt->muted)
+ ctrl->value=0;
+ else
+ ctrl->value=65535;
+ return (0);
+ }
+ return -EINVAL;
+ }
+ case VIDIOC_S_CTRL:
+ {
+ struct v4l2_control *ctrl= arg;
+
+ switch (ctrl->id) {
+ case V4L2_CID_AUDIO_MUTE:
+ if (ctrl->value) {
+ gemtek_mute(rt);
+ } else {
+ gemtek_unmute(rt);
+ }
+ return (0);
+ case V4L2_CID_AUDIO_VOLUME:
+ if (ctrl->value) {
+ gemtek_unmute(rt);
+ } else {
+ gemtek_mute(rt);
+ }
+ return (0);
+ }
+ return -EINVAL;
+ }
default:
- return -ENOIOCTLCMD;
+ return v4l_compat_translate_ioctl(inode,file,cmd,arg,
+ gemtek_do_ioctl);
}
}
@@ -243,7 +310,7 @@ static struct video_device gemtek_radio=
.owner = THIS_MODULE,
.name = "GemTek radio",
.type = VID_TYPE_TUNER,
- .hardware = VID_HARDWARE_GEMTEK,
+ .hardware = 0,
.fops = &gemtek_fops,
};
diff --git a/drivers/media/radio/radio-maestro.c b/drivers/media/radio/radio-maestro.c
index fcfa6c9fe225..e8ce5f75cf12 100644
--- a/drivers/media/radio/radio-maestro.c
+++ b/drivers/media/radio/radio-maestro.c
@@ -14,6 +14,8 @@
* version 0.04
* + code improvements
* + VIDEO_TUNER_LOW is permanent
+ *
+ * Converted to V4L2 API by Mauro Carvalho Chehab <mchehab@infradead.org>
*/
#include <linux/module.h>
@@ -25,10 +27,23 @@
#include <asm/uaccess.h>
#include <linux/mutex.h>
#include <linux/pci.h>
-#include <linux/videodev.h>
+#include <linux/videodev2.h>
#include <media/v4l2-common.h>
-#define DRIVER_VERSION "0.05"
+#include <linux/version.h> /* for KERNEL_VERSION MACRO */
+#define RADIO_VERSION KERNEL_VERSION(0,0,6)
+#define DRIVER_VERSION "0.06"
+
+static struct v4l2_queryctrl radio_qctrl[] = {
+ {
+ .id = V4L2_CID_AUDIO_MUTE,
+ .name = "Mute",
+ .minimum = 0,
+ .maximum = 1,
+ .default_value = 1,
+ .type = V4L2_CTRL_TYPE_BOOLEAN,
+ }
+};
#define GPIO_DATA 0x60 /* port offset from ESS_IO_BASE */
@@ -96,7 +111,7 @@ static struct file_operations maestro_fops = {
static struct video_device maestro_radio = {
.name = "Maestro radio",
.type = VID_TYPE_TUNER,
- .hardware = VID_HARDWARE_SF16MI,
+ .hardware = 0,
.fops = &maestro_fops,
};
@@ -130,7 +145,7 @@ static u32 radio_bits_get(struct radio_device *dev)
rdata = inw(io);
if(!l)
dev->stereo = rdata & STR_MOST ?
- 0 : VIDEO_TUNER_STEREO_ON;
+ 0 : 1;
else
if(rdata & STR_DATA)
data++;
@@ -183,72 +198,120 @@ static inline int radio_function(struct inode *inode, struct file *file,
struct radio_device *card = video_get_drvdata(dev);
switch (cmd) {
- case VIDIOCGCAP: {
- struct video_capability *v = arg;
- memset(v, 0, sizeof(*v));
- strcpy(v->name, "Maestro radio");
- v->type = VID_TYPE_TUNER;
- v->channels = v->audios = 1;
- return 0;
- } case VIDIOCGTUNER: {
- struct video_tuner *v = arg;
- if (v->tuner)
- return -EINVAL;
- (void)radio_bits_get(card);
- v->flags = VIDEO_TUNER_LOW | card->stereo;
- v->signal = card->tuned;
- strcpy(v->name, "FM");
- v->rangelow = FREQ_LO;
- v->rangehigh = FREQ_HI;
- v->mode = VIDEO_MODE_AUTO;
- return 0;
- } case VIDIOCSTUNER: {
- struct video_tuner *v = arg;
- if (v->tuner != 0)
- return -EINVAL;
- return 0;
- } case VIDIOCGFREQ: {
- unsigned long *freq = arg;
- *freq = BITS2FREQ(radio_bits_get(card));
- return 0;
- } case VIDIOCSFREQ: {
- unsigned long *freq = arg;
- if (*freq < FREQ_LO || *freq > FREQ_HI)
+ case VIDIOC_QUERYCAP:
+ {
+ struct v4l2_capability *v = arg;
+ memset(v,0,sizeof(*v));
+ strlcpy(v->driver, "radio-maestro", sizeof (v->driver));
+ strlcpy(v->card, "Maestro Radio", sizeof (v->card));
+ sprintf(v->bus_info,"PCI");
+ v->version = RADIO_VERSION;
+ v->capabilities = V4L2_CAP_TUNER;
+
+ return 0;
+ }
+ case VIDIOC_G_TUNER:
+ {
+ struct v4l2_tuner *v = arg;
+
+ if (v->index > 0)
+ return -EINVAL;
+
+ (void)radio_bits_get(card);
+
+ memset(v,0,sizeof(*v));
+ strcpy(v->name, "FM");
+ v->type = V4L2_TUNER_RADIO;
+
+ v->rangelow = FREQ_LO;
+ v->rangehigh = FREQ_HI;
+ v->rxsubchans =V4L2_TUNER_SUB_MONO|V4L2_TUNER_SUB_STEREO;
+ v->capability=V4L2_TUNER_CAP_LOW;
+ if(card->stereo)
+ v->audmode = V4L2_TUNER_MODE_STEREO;
+ else
+ v->audmode = V4L2_TUNER_MODE_MONO;
+ v->signal=card->tuned;
+
+ return 0;
+ }
+ case VIDIOC_S_TUNER:
+ {
+ struct v4l2_tuner *v = arg;
+
+ if (v->index > 0)
+ return -EINVAL;
+
+ return 0;
+ }
+ case VIDIOC_S_FREQUENCY:
+ {
+ struct v4l2_frequency *f = arg;
+
+ if (f->frequency < FREQ_LO || f->frequency > FREQ_HI)
+ return -EINVAL;
+ radio_bits_set(card, FREQ2BITS(f->frequency));
+
+ return 0;
+ }
+ case VIDIOC_G_FREQUENCY:
+ {
+ struct v4l2_frequency *f = arg;
+
+ f->type = V4L2_TUNER_RADIO;
+ f->frequency = BITS2FREQ(radio_bits_get(card));
+
+ return 0;
+ }
+ case VIDIOC_QUERYCTRL:
+ {
+ struct v4l2_queryctrl *qc = arg;
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) {
+ if (qc->id && qc->id == radio_qctrl[i].id) {
+ memcpy(qc, &(radio_qctrl[i]),
+ sizeof(*qc));
+ return (0);
+ }
+ }
return -EINVAL;
- radio_bits_set(card, FREQ2BITS(*freq));
- return 0;
- } case VIDIOCGAUDIO: {
- struct video_audio *v = arg;
- memset(v, 0, sizeof(*v));
- strcpy(v->name, "Radio");
- v->flags = VIDEO_AUDIO_MUTABLE | card->muted;
- v->mode = VIDEO_SOUND_STEREO;
- return 0;
- } case VIDIOCSAUDIO: {
- struct video_audio *v = arg;
- if (v->audio)
+ }
+ case VIDIOC_G_CTRL:
+ {
+ struct v4l2_control *ctrl= arg;
+
+ switch (ctrl->id) {
+ case V4L2_CID_AUDIO_MUTE:
+ ctrl->value=card->muted;
+ return (0);
+ }
return -EINVAL;
+ }
+ case VIDIOC_S_CTRL:
{
- register u16 io = card->io;
- register u16 omask = inw(io + IO_MASK);
- outw(~STR_WREN, io + IO_MASK);
- outw((card->muted = v->flags & VIDEO_AUDIO_MUTE) ?
- STR_WREN : 0, io);
- udelay(4);
- outw(omask, io + IO_MASK);
- msleep(125);
- return 0;
+ struct v4l2_control *ctrl= arg;
+
+ switch (ctrl->id) {
+ case V4L2_CID_AUDIO_MUTE:
+ {
+ register u16 io = card->io;
+ register u16 omask = inw(io + IO_MASK);
+ outw(~STR_WREN, io + IO_MASK);
+ outw((card->muted = ctrl->value ) ?
+ STR_WREN : 0, io);
+ udelay(4);
+ outw(omask, io + IO_MASK);
+ msleep(125);
+
+ return (0);
+ }
+ }
+ return -EINVAL;
}
- } case VIDIOCGUNIT: {
- struct video_unit *v = arg;
- v->video = VIDEO_NO_UNIT;
- v->vbi = VIDEO_NO_UNIT;
- v->radio = dev->minor;
- v->audio = 0;
- v->teletext = VIDEO_NO_UNIT;
- return 0;
- } default:
- return -ENOIOCTLCMD;
+ default:
+ return v4l_compat_translate_ioctl(inode,file,cmd,arg,
+ radio_function);
}
}
@@ -275,7 +338,7 @@ static u16 __devinit radio_power_on(struct radio_device *dev)
omask = inw(io + IO_MASK);
odir = (inw(io + IO_DIR) & ~STR_DATA) | (STR_CLK | STR_WREN);
outw(odir & ~STR_WREN, io + IO_DIR);
- dev->muted = inw(io) & STR_WREN ? 0 : VIDEO_AUDIO_MUTE;
+ dev->muted = inw(io) & STR_WREN ? 0 : 1;
outw(odir, io + IO_DIR);
outw(~(STR_WREN | STR_CLK), io + IO_MASK);
outw(dev->muted ? 0 : STR_WREN, io);
diff --git a/drivers/media/radio/radio-maxiradio.c b/drivers/media/radio/radio-maxiradio.c
index f93d7afe7304..c2eeae7a10d0 100644
--- a/drivers/media/radio/radio-maxiradio.c
+++ b/drivers/media/radio/radio-maxiradio.c
@@ -20,13 +20,14 @@
* 0.75b
* - better pci interface thanks to Francois Romieu <romieu@cogenit.fr>
*
- * 0.75
+ * 0.75 Sun Feb 4 22:51:27 EET 2001
* - tiding up
* - removed support for multiple devices as it didn't work anyway
*
* BUGS:
* - card unmutes if you change frequency
*
+ * Converted to V4L2 API by Mauro Carvalho Chehab <mchehab@infradead.org>
*/
@@ -40,11 +41,24 @@
#include <linux/mutex.h>
#include <linux/pci.h>
-#include <linux/videodev.h>
+#include <linux/videodev2.h>
#include <media/v4l2-common.h>
-/* version 0.75 Sun Feb 4 22:51:27 EET 2001 */
-#define DRIVER_VERSION "0.75"
+#define DRIVER_VERSION "0.76"
+
+#include <linux/version.h> /* for KERNEL_VERSION MACRO */
+#define RADIO_VERSION KERNEL_VERSION(0,7,6)
+
+static struct v4l2_queryctrl radio_qctrl[] = {
+ {
+ .id = V4L2_CID_AUDIO_MUTE,
+ .name = "Mute",
+ .minimum = 0,
+ .maximum = 1,
+ .default_value = 1,
+ .type = V4L2_CTRL_TYPE_BOOLEAN,
+ }
+};
#ifndef PCI_VENDOR_ID_GUILLEMOT
#define PCI_VENDOR_ID_GUILLEMOT 0x5046
@@ -90,7 +104,6 @@ static struct video_device maxiradio_radio =
.owner = THIS_MODULE,
.name = "Maxi Radio FM2000 radio",
.type = VID_TYPE_TUNER,
- .hardware = VID_HARDWARE_SF16MI,
.fops = &maxiradio_fops,
};
@@ -176,89 +189,116 @@ static inline int radio_function(struct inode *inode, struct file *file,
struct radio_device *card=dev->priv;
switch(cmd) {
- case VIDIOCGCAP: {
- struct video_capability *v = arg;
-
+ case VIDIOC_QUERYCAP:
+ {
+ struct v4l2_capability *v = arg;
memset(v,0,sizeof(*v));
- strcpy(v->name, "Maxi Radio FM2000 radio");
- v->type=VID_TYPE_TUNER;
- v->channels=v->audios=1;
+ strlcpy(v->driver, "radio-maxiradio", sizeof (v->driver));
+ strlcpy(v->card, "Maxi Radio FM2000 radio", sizeof (v->card));
+ sprintf(v->bus_info,"ISA");
+ v->version = RADIO_VERSION;
+ v->capabilities = V4L2_CAP_TUNER;
+
return 0;
}
- case VIDIOCGTUNER: {
- struct video_tuner *v = arg;
+ case VIDIOC_G_TUNER:
+ {
+ struct v4l2_tuner *v = arg;
- if(v->tuner)
+ if (v->index > 0)
return -EINVAL;
- card->stereo = 0xffff * get_stereo(card->io);
- card->tuned = 0xffff * get_tune(card->io);
-
- v->flags = VIDEO_TUNER_LOW | card->stereo;
- v->signal = card->tuned;
-
+ memset(v,0,sizeof(*v));
strcpy(v->name, "FM");
-
- v->rangelow = FREQ_LO;
- v->rangehigh = FREQ_HI;
- v->mode = VIDEO_MODE_AUTO;
+ v->type = V4L2_TUNER_RADIO;
+
+ v->rangelow=FREQ_LO;
+ v->rangehigh=FREQ_HI;
+ v->rxsubchans =V4L2_TUNER_SUB_MONO|V4L2_TUNER_SUB_STEREO;
+ v->capability=V4L2_TUNER_CAP_LOW;
+ if(get_stereo(card->io))
+ v->audmode = V4L2_TUNER_MODE_STEREO;
+ else
+ v->audmode = V4L2_TUNER_MODE_MONO;
+ v->signal=0xffff*get_tune(card->io);
return 0;
}
- case VIDIOCSTUNER: {
- struct video_tuner *v = arg;
- if(v->tuner!=0)
+ case VIDIOC_S_TUNER:
+ {
+ struct v4l2_tuner *v = arg;
+
+ if (v->index > 0)
return -EINVAL;
- return 0;
- }
- case VIDIOCGFREQ: {
- unsigned long *freq = arg;
- *freq = card->freq;
return 0;
}
- case VIDIOCSFREQ: {
- unsigned long *freq = arg;
+ case VIDIOC_S_FREQUENCY:
+ {
+ struct v4l2_frequency *f = arg;
- if (*freq < FREQ_LO || *freq > FREQ_HI)
+ if (f->frequency < FREQ_LO || f->frequency > FREQ_HI)
return -EINVAL;
- card->freq = *freq;
+
+ card->freq = f->frequency;
set_freq(card->io, FREQ2BITS(card->freq));
msleep(125);
return 0;
}
- case VIDIOCGAUDIO: {
- struct video_audio *v = arg;
- memset(v,0,sizeof(*v));
- strcpy(v->name, "Radio");
- v->flags=VIDEO_AUDIO_MUTABLE | card->muted;
- v->mode=VIDEO_SOUND_STEREO;
- return 0;
- }
+ case VIDIOC_G_FREQUENCY:
+ {
+ struct v4l2_frequency *f = arg;
- case VIDIOCSAUDIO: {
- struct video_audio *v = arg;
+ f->type = V4L2_TUNER_RADIO;
+ f->frequency = card->freq;
- if(v->audio)
- return -EINVAL;
- card->muted = v->flags & VIDEO_AUDIO_MUTE;
- if(card->muted)
- turn_power(card->io, 0);
- else
- set_freq(card->io, FREQ2BITS(card->freq));
return 0;
}
- case VIDIOCGUNIT: {
- struct video_unit *v = arg;
-
- v->video=VIDEO_NO_UNIT;
- v->vbi=VIDEO_NO_UNIT;
- v->radio=dev->minor;
- v->audio=0;
- v->teletext=VIDEO_NO_UNIT;
- return 0;
+ case VIDIOC_QUERYCTRL:
+ {
+ struct v4l2_queryctrl *qc = arg;
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) {
+ if (qc->id && qc->id == radio_qctrl[i].id) {
+ memcpy(qc, &(radio_qctrl[i]),
+ sizeof(*qc));
+ return (0);
+ }
+ }
+ return -EINVAL;
+ }
+ case VIDIOC_G_CTRL:
+ {
+ struct v4l2_control *ctrl= arg;
+
+ switch (ctrl->id) {
+ case V4L2_CID_AUDIO_MUTE:
+ ctrl->value=card->muted;
+ return (0);
+ }
+ return -EINVAL;
}
- default: return -ENOIOCTLCMD;
+ case VIDIOC_S_CTRL:
+ {
+ struct v4l2_control *ctrl= arg;
+
+ switch (ctrl->id) {
+ case V4L2_CID_AUDIO_MUTE:
+ card->muted = ctrl->value;
+ if(card->muted)
+ turn_power(card->io, 0);
+ else
+ set_freq(card->io, FREQ2BITS(card->freq));
+ return 0;
+ }
+ return -EINVAL;
+ }
+
+ default:
+ return v4l_compat_translate_ioctl(inode,file,cmd,arg,
+ radio_function);
+
}
}
diff --git a/drivers/media/radio/radio-rtrack2.c b/drivers/media/radio/radio-rtrack2.c
index 5b68ac4c7322..b9e98483e58d 100644
--- a/drivers/media/radio/radio-rtrack2.c
+++ b/drivers/media/radio/radio-rtrack2.c
@@ -6,6 +6,7 @@
*
* TODO: Allow for more than one of these foolish entities :-)
*
+ * Converted to V4L2 API by Mauro Carvalho Chehab <mchehab@infradead.org>
*/
#include <linux/module.h> /* Modules */
@@ -14,11 +15,32 @@
#include <linux/delay.h> /* udelay */
#include <asm/io.h> /* outb, outb_p */
#include <asm/uaccess.h> /* copy to/from user */
-#include <linux/videodev.h> /* kernel radio structs */
+#include <linux/videodev2.h> /* kernel radio structs */
#include <media/v4l2-common.h>
-#include <linux/config.h> /* CONFIG_RADIO_RTRACK2_PORT */
#include <linux/spinlock.h>
+#include <linux/version.h> /* for KERNEL_VERSION MACRO */
+#define RADIO_VERSION KERNEL_VERSION(0,0,2)
+
+static struct v4l2_queryctrl radio_qctrl[] = {
+ {
+ .id = V4L2_CID_AUDIO_MUTE,
+ .name = "Mute",
+ .minimum = 0,
+ .maximum = 1,
+ .default_value = 1,
+ .type = V4L2_CTRL_TYPE_BOOLEAN,
+ },{
+ .id = V4L2_CID_AUDIO_VOLUME,
+ .name = "Volume",
+ .minimum = 0,
+ .maximum = 65535,
+ .step = 65535,
+ .default_value = 0xff,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ }
+};
+
#ifndef CONFIG_RADIO_RTRACK2_PORT
#define CONFIG_RADIO_RTRACK2_PORT -1
#endif
@@ -115,75 +137,120 @@ static int rt_do_ioctl(struct inode *inode, struct file *file,
switch(cmd)
{
- case VIDIOCGCAP:
+ case VIDIOC_QUERYCAP:
{
- struct video_capability *v = arg;
+ struct v4l2_capability *v = arg;
memset(v,0,sizeof(*v));
- v->type=VID_TYPE_TUNER;
- v->channels=1;
- v->audios=1;
- strcpy(v->name, "RadioTrack II");
+ strlcpy(v->driver, "radio-rtrack2", sizeof (v->driver));
+ strlcpy(v->card, "RadioTrack II", sizeof (v->card));
+ sprintf(v->bus_info,"ISA");
+ v->version = RADIO_VERSION;
+ v->capabilities = V4L2_CAP_TUNER;
+
return 0;
}
- case VIDIOCGTUNER:
+ case VIDIOC_G_TUNER:
{
- struct video_tuner *v = arg;
- if(v->tuner) /* Only 1 tuner */
+ struct v4l2_tuner *v = arg;
+
+ if (v->index > 0)
return -EINVAL;
- v->rangelow=88*16000;
- v->rangehigh=108*16000;
- v->flags=VIDEO_TUNER_LOW;
- v->mode=VIDEO_MODE_AUTO;
- v->signal=0xFFFF*rt_getsigstr(rt);
+
+ memset(v,0,sizeof(*v));
strcpy(v->name, "FM");
+ v->type = V4L2_TUNER_RADIO;
+
+ v->rangelow=(88*16000);
+ v->rangehigh=(108*16000);
+ v->rxsubchans =V4L2_TUNER_SUB_MONO;
+ v->capability=V4L2_TUNER_CAP_LOW;
+ v->audmode = V4L2_TUNER_MODE_MONO;
+ v->signal=0xFFFF*rt_getsigstr(rt);
+
return 0;
}
- case VIDIOCSTUNER:
+ case VIDIOC_S_TUNER:
{
- struct video_tuner *v = arg;
- if(v->tuner!=0)
+ struct v4l2_tuner *v = arg;
+
+ if (v->index > 0)
return -EINVAL;
- /* Only 1 tuner so no setting needed ! */
+
return 0;
}
- case VIDIOCGFREQ:
+ case VIDIOC_S_FREQUENCY:
{
- unsigned long *freq = arg;
- *freq = rt->curfreq;
+ struct v4l2_frequency *f = arg;
+
+ rt->curfreq = f->frequency;
+ rt_setfreq(rt, rt->curfreq);
return 0;
}
- case VIDIOCSFREQ:
+ case VIDIOC_G_FREQUENCY:
{
- unsigned long *freq = arg;
- rt->curfreq = *freq;
- rt_setfreq(rt, rt->curfreq);
+ struct v4l2_frequency *f = arg;
+
+ f->type = V4L2_TUNER_RADIO;
+ f->frequency = rt->curfreq;
+
return 0;
}
- case VIDIOCGAUDIO:
+ case VIDIOC_QUERYCTRL:
{
- struct video_audio *v = arg;
- memset(v,0, sizeof(*v));
- v->flags|=VIDEO_AUDIO_MUTABLE;
- v->volume=1;
- v->step=65535;
- strcpy(v->name, "Radio");
- return 0;
+ struct v4l2_queryctrl *qc = arg;
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) {
+ if (qc->id && qc->id == radio_qctrl[i].id) {
+ memcpy(qc, &(radio_qctrl[i]),
+ sizeof(*qc));
+ return (0);
+ }
+ }
+ return -EINVAL;
}
- case VIDIOCSAUDIO:
+ case VIDIOC_G_CTRL:
{
- struct video_audio *v = arg;
- if(v->audio)
- return -EINVAL;
-
- if(v->flags&VIDEO_AUDIO_MUTE)
- rt_mute(rt);
- else
- rt_unmute(rt);
-
- return 0;
+ struct v4l2_control *ctrl= arg;
+
+ switch (ctrl->id) {
+ case V4L2_CID_AUDIO_MUTE:
+ ctrl->value=rt->muted;
+ return (0);
+ case V4L2_CID_AUDIO_VOLUME:
+ if (rt->muted)
+ ctrl->value=0;
+ else
+ ctrl->value=65535;
+ return (0);
+ }
+ return -EINVAL;
+ }
+ case VIDIOC_S_CTRL:
+ {
+ struct v4l2_control *ctrl= arg;
+
+ switch (ctrl->id) {
+ case V4L2_CID_AUDIO_MUTE:
+ if (ctrl->value) {
+ rt_mute(rt);
+ } else {
+ rt_unmute(rt);
+ }
+ return (0);
+ case V4L2_CID_AUDIO_VOLUME:
+ if (ctrl->value) {
+ rt_unmute(rt);
+ } else {
+ rt_mute(rt);
+ }
+ return (0);
+ }
+ return -EINVAL;
}
default:
- return -ENOIOCTLCMD;
+ return v4l_compat_translate_ioctl(inode,file,cmd,arg,
+ rt_do_ioctl);
}
}
@@ -209,7 +276,7 @@ static struct video_device rtrack2_radio=
.owner = THIS_MODULE,
.name = "RadioTrack II radio",
.type = VID_TYPE_TUNER,
- .hardware = VID_HARDWARE_RTRACK2,
+ .hardware = 0,
.fops = &rtrack2_fops,
};
diff --git a/drivers/media/radio/radio-sf16fmi.c b/drivers/media/radio/radio-sf16fmi.c
index efee6e339d15..ecc854b4ba38 100644
--- a/drivers/media/radio/radio-sf16fmi.c
+++ b/drivers/media/radio/radio-sf16fmi.c
@@ -13,20 +13,35 @@
* No volume control - only mute/unmute - you have to use line volume
* control on SB-part of SF16FMI
*
+ * Converted to V4L2 API by Mauro Carvalho Chehab <mchehab@infradead.org>
*/
+#include <linux/version.h>
#include <linux/kernel.h> /* __setup */
#include <linux/module.h> /* Modules */
#include <linux/init.h> /* Initdata */
#include <linux/ioport.h> /* request_region */
#include <linux/delay.h> /* udelay */
-#include <linux/videodev.h> /* kernel radio structs */
+#include <linux/videodev2.h> /* kernel radio structs */
#include <media/v4l2-common.h>
#include <linux/isapnp.h>
#include <asm/io.h> /* outb, outb_p */
#include <asm/uaccess.h> /* copy to/from user */
#include <linux/mutex.h>
+#define RADIO_VERSION KERNEL_VERSION(0,0,2)
+
+static struct v4l2_queryctrl radio_qctrl[] = {
+ {
+ .id = V4L2_CID_AUDIO_MUTE,
+ .name = "Mute",
+ .minimum = 0,
+ .maximum = 1,
+ .default_value = 1,
+ .type = V4L2_CTRL_TYPE_BOOLEAN,
+ }
+};
+
struct fmi_device
{
int port;
@@ -123,93 +138,122 @@ static int fmi_do_ioctl(struct inode *inode, struct file *file,
switch(cmd)
{
- case VIDIOCGCAP:
+ case VIDIOC_QUERYCAP:
{
- struct video_capability *v = arg;
+ struct v4l2_capability *v = arg;
memset(v,0,sizeof(*v));
- strcpy(v->name, "SF16-FMx radio");
- v->type=VID_TYPE_TUNER;
- v->channels=1;
- v->audios=1;
+ strlcpy(v->driver, "radio-sf16fmi", sizeof (v->driver));
+ strlcpy(v->card, "SF16-FMx radio", sizeof (v->card));
+ sprintf(v->bus_info,"ISA");
+ v->version = RADIO_VERSION;
+ v->capabilities = V4L2_CAP_TUNER;
+
return 0;
}
- case VIDIOCGTUNER:
+ case VIDIOC_G_TUNER:
{
- struct video_tuner *v = arg;
+ struct v4l2_tuner *v = arg;
int mult;
- if(v->tuner) /* Only 1 tuner */
+ if (v->index > 0)
return -EINVAL;
+
+ memset(v,0,sizeof(*v));
strcpy(v->name, "FM");
- mult = (fmi->flags & VIDEO_TUNER_LOW) ? 1 : 1000;
+ v->type = V4L2_TUNER_RADIO;
+
+ mult = (fmi->flags & V4L2_TUNER_CAP_LOW) ? 1 : 1000;
v->rangelow = RSF16_MINFREQ/mult;
v->rangehigh = RSF16_MAXFREQ/mult;
- v->flags=fmi->flags;
- v->mode=VIDEO_MODE_AUTO;
+ v->rxsubchans =V4L2_TUNER_SUB_MONO | V4L2_TUNER_MODE_STEREO;
+ v->capability=fmi->flags&V4L2_TUNER_CAP_LOW;
+ v->audmode = V4L2_TUNER_MODE_STEREO;
v->signal = fmi_getsigstr(fmi);
+
return 0;
}
- case VIDIOCSTUNER:
+ case VIDIOC_S_TUNER:
{
- struct video_tuner *v = arg;
- if(v->tuner!=0)
+ struct v4l2_tuner *v = arg;
+
+ if (v->index > 0)
return -EINVAL;
- fmi->flags = v->flags & VIDEO_TUNER_LOW;
- /* Only 1 tuner so no setting needed ! */
- return 0;
- }
- case VIDIOCGFREQ:
- {
- unsigned long *freq = arg;
- *freq = fmi->curfreq;
- if (!(fmi->flags & VIDEO_TUNER_LOW))
- *freq /= 1000;
+
return 0;
}
- case VIDIOCSFREQ:
+ case VIDIOC_S_FREQUENCY:
{
- unsigned long *freq = arg;
- if (!(fmi->flags & VIDEO_TUNER_LOW))
- *freq *= 1000;
- if (*freq < RSF16_MINFREQ || *freq > RSF16_MAXFREQ )
+ struct v4l2_frequency *f = arg;
+
+ if (!(fmi->flags & V4L2_TUNER_CAP_LOW))
+ f->frequency *= 1000;
+ if (f->frequency < RSF16_MINFREQ ||
+ f->frequency > RSF16_MAXFREQ )
return -EINVAL;
/*rounding in steps of 800 to match th freq
that will be used */
- fmi->curfreq = (*freq/800)*800;
+ fmi->curfreq = (f->frequency/800)*800;
fmi_setfreq(fmi);
+
return 0;
}
- case VIDIOCGAUDIO:
+ case VIDIOC_G_FREQUENCY:
{
- struct video_audio *v = arg;
- memset(v,0,sizeof(*v));
- v->flags=( (!fmi->curvol)*VIDEO_AUDIO_MUTE | VIDEO_AUDIO_MUTABLE);
- strcpy(v->name, "Radio");
- v->mode=VIDEO_SOUND_STEREO;
+ struct v4l2_frequency *f = arg;
+
+ f->type = V4L2_TUNER_RADIO;
+ f->frequency = fmi->curfreq;
+ if (!(fmi->flags & V4L2_TUNER_CAP_LOW))
+ f->frequency /= 1000;
+
return 0;
}
- case VIDIOCSAUDIO:
+ case VIDIOC_QUERYCTRL:
{
- struct video_audio *v = arg;
- if(v->audio)
- return -EINVAL;
- fmi->curvol= v->flags&VIDEO_AUDIO_MUTE ? 0 : 1;
- fmi->curvol ?
- fmi_unmute(fmi->port) : fmi_mute(fmi->port);
- return 0;
+ struct v4l2_queryctrl *qc = arg;
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) {
+ if (qc->id && qc->id == radio_qctrl[i].id) {
+ memcpy(qc, &(radio_qctrl[i]),
+ sizeof(*qc));
+ return (0);
+ }
+ }
+ return -EINVAL;
}
- case VIDIOCGUNIT:
+ case VIDIOC_G_CTRL:
{
- struct video_unit *v = arg;
- v->video=VIDEO_NO_UNIT;
- v->vbi=VIDEO_NO_UNIT;
- v->radio=dev->minor;
- v->audio=0; /* How do we find out this??? */
- v->teletext=VIDEO_NO_UNIT;
- return 0;
+ struct v4l2_control *ctrl= arg;
+
+ switch (ctrl->id) {
+ case V4L2_CID_AUDIO_MUTE:
+ ctrl->value=fmi->curvol;
+ return (0);
+ }
+ return -EINVAL;
+ }
+ case VIDIOC_S_CTRL:
+ {
+ struct v4l2_control *ctrl= arg;
+
+ switch (ctrl->id) {
+ case V4L2_CID_AUDIO_MUTE:
+ {
+ if (ctrl->value)
+ fmi_mute(fmi->port);
+ else
+ fmi_unmute(fmi->port);
+
+ fmi->curvol=ctrl->value;
+ return (0);
+ }
+ }
+ return -EINVAL;
}
default:
- return -ENOIOCTLCMD;
+ return v4l_compat_translate_ioctl(inode,file,cmd,arg,
+ fmi_do_ioctl);
}
}
@@ -235,7 +279,7 @@ static struct video_device fmi_radio=
.owner = THIS_MODULE,
.name = "SF16FMx radio",
.type = VID_TYPE_TUNER,
- .hardware = VID_HARDWARE_SF16MI,
+ .hardware = 0,
.fops = &fmi_fops,
};
@@ -294,7 +338,7 @@ static int __init fmi_init(void)
fmi_unit.port = io;
fmi_unit.curvol = 0;
fmi_unit.curfreq = 0;
- fmi_unit.flags = VIDEO_TUNER_LOW;
+ fmi_unit.flags = V4L2_TUNER_CAP_LOW;
fmi_radio.priv = &fmi_unit;
mutex_init(&lock);
diff --git a/drivers/media/radio/radio-sf16fmr2.c b/drivers/media/radio/radio-sf16fmr2.c
index 3483b2c7bc9d..4444dce864a9 100644
--- a/drivers/media/radio/radio-sf16fmr2.c
+++ b/drivers/media/radio/radio-sf16fmr2.c
@@ -10,6 +10,8 @@
* For read stereo/mono you must wait 0.1 sec after set frequency and
* card unmuted so I set frequency on unmute
* Signal handling seem to work only on autoscanning (not implemented)
+ *
+ * Converted to V4L2 API by Mauro Carvalho Chehab <mchehab@infradead.org>
*/
#include <linux/module.h> /* Modules */
@@ -18,12 +20,34 @@
#include <linux/delay.h> /* udelay */
#include <asm/io.h> /* outb, outb_p */
#include <asm/uaccess.h> /* copy to/from user */
-#include <linux/videodev.h> /* kernel radio structs */
+#include <linux/videodev2.h> /* kernel radio structs */
#include <media/v4l2-common.h>
#include <linux/mutex.h>
static struct mutex lock;
+#include <linux/version.h> /* for KERNEL_VERSION MACRO */
+#define RADIO_VERSION KERNEL_VERSION(0,0,2)
+
+static struct v4l2_queryctrl radio_qctrl[] = {
+ {
+ .id = V4L2_CID_AUDIO_MUTE,
+ .name = "Mute",
+ .minimum = 0,
+ .maximum = 1,
+ .default_value = 1,
+ .type = V4L2_CTRL_TYPE_BOOLEAN,
+ },{
+ .id = V4L2_CID_AUDIO_VOLUME,
+ .name = "Volume",
+ .minimum = 0,
+ .maximum = 65535,
+ .step = 1<<12,
+ .default_value = 0xff,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ }
+};
+
#undef DEBUG
//#define DEBUG 1
@@ -214,63 +238,65 @@ static int fmr2_do_ioctl(struct inode *inode, struct file *file,
switch(cmd)
{
- case VIDIOCGCAP:
+ case VIDIOC_QUERYCAP:
{
- struct video_capability *v = arg;
+ struct v4l2_capability *v = arg;
memset(v,0,sizeof(*v));
- strcpy(v->name, "SF16-FMR2 radio");
- v->type=VID_TYPE_TUNER;
- v->channels=1;
- v->audios=1;
+ strlcpy(v->driver, "radio-sf16fmr2", sizeof (v->driver));
+ strlcpy(v->card, "SF16-FMR2 radio", sizeof (v->card));
+ sprintf(v->bus_info,"ISA");
+ v->version = RADIO_VERSION;
+ v->capabilities = V4L2_CAP_TUNER;
+
return 0;
}
- case VIDIOCGTUNER:
+ case VIDIOC_G_TUNER:
{
- struct video_tuner *v = arg;
+ struct v4l2_tuner *v = arg;
int mult;
- if(v->tuner) /* Only 1 tuner */
+ if (v->index > 0)
return -EINVAL;
+
+ memset(v,0,sizeof(*v));
strcpy(v->name, "FM");
- mult = (fmr2->flags & VIDEO_TUNER_LOW) ? 1 : 1000;
+ v->type = V4L2_TUNER_RADIO;
+
+ mult = (fmr2->flags & V4L2_TUNER_CAP_LOW) ? 1 : 1000;
v->rangelow = RSF16_MINFREQ/mult;
v->rangehigh = RSF16_MAXFREQ/mult;
- v->flags = fmr2->flags | VIDEO_AUDIO_MUTABLE;
- if (fmr2->mute)
- v->flags |= VIDEO_AUDIO_MUTE;
- v->mode=VIDEO_MODE_AUTO;
+ v->rxsubchans =V4L2_TUNER_SUB_MONO | V4L2_TUNER_MODE_STEREO;
+ v->capability=fmr2->flags&V4L2_TUNER_CAP_LOW;
+
+ v->audmode = fmr2->stereo ? V4L2_TUNER_MODE_STEREO:
+ V4L2_TUNER_MODE_MONO;
mutex_lock(&lock);
v->signal = fmr2_getsigstr(fmr2);
mutex_unlock(&lock);
+
return 0;
}
- case VIDIOCSTUNER:
+ case VIDIOC_S_TUNER:
{
- struct video_tuner *v = arg;
- if (v->tuner!=0)
+ struct v4l2_tuner *v = arg;
+
+ if (v->index > 0)
return -EINVAL;
- fmr2->flags = v->flags & VIDEO_TUNER_LOW;
- return 0;
- }
- case VIDIOCGFREQ:
- {
- unsigned long *freq = arg;
- *freq = fmr2->curfreq;
- if (!(fmr2->flags & VIDEO_TUNER_LOW))
- *freq /= 1000;
+
return 0;
}
- case VIDIOCSFREQ:
+ case VIDIOC_S_FREQUENCY:
{
- unsigned long *freq = arg;
- if (!(fmr2->flags & VIDEO_TUNER_LOW))
- *freq *= 1000;
- if ( *freq < RSF16_MINFREQ || *freq > RSF16_MAXFREQ )
+ struct v4l2_frequency *f = arg;
+
+ if (!(fmr2->flags & V4L2_TUNER_CAP_LOW))
+ f->frequency *= 1000;
+ if (f->frequency < RSF16_MINFREQ ||
+ f->frequency > RSF16_MAXFREQ )
return -EINVAL;
- /* rounding in steps of 200 to match th freq
- * that will be used
- */
- fmr2->curfreq = (*freq/200)*200;
+ /*rounding in steps of 200 to match th freq
+ that will be used */
+ fmr2->curfreq = (f->frequency/200)*200;
/* set card freq (if not muted) */
if (fmr2->curvol && !fmr2->mute)
@@ -279,40 +305,81 @@ static int fmr2_do_ioctl(struct inode *inode, struct file *file,
fmr2_setfreq(fmr2);
mutex_unlock(&lock);
}
+
return 0;
}
- case VIDIOCGAUDIO:
+ case VIDIOC_G_FREQUENCY:
{
- struct video_audio *v = arg;
- memset(v,0,sizeof(*v));
- /* !!! do not return VIDEO_AUDIO_MUTE */
- v->flags = VIDEO_AUDIO_MUTABLE;
- strcpy(v->name, "Radio");
- /* get current stereo mode */
- v->mode = fmr2->stereo ? VIDEO_SOUND_STEREO: VIDEO_SOUND_MONO;
- /* volume supported ? */
- if (fmr2->card_type == 11)
- {
- v->flags |= VIDEO_AUDIO_VOLUME;
- v->step = 1 << 12;
- v->volume = fmr2->curvol;
- }
- debug_print((KERN_DEBUG "Get flags %d vol %d\n", v->flags, v->volume));
+ struct v4l2_frequency *f = arg;
+
+ f->type = V4L2_TUNER_RADIO;
+ f->frequency = fmr2->curfreq;
+ if (!(fmr2->flags & V4L2_TUNER_CAP_LOW))
+ f->frequency /= 1000;
+
return 0;
}
- case VIDIOCSAUDIO:
+ case VIDIOC_QUERYCTRL:
{
- struct video_audio *v = arg;
- if(v->audio)
- return -EINVAL;
- debug_print((KERN_DEBUG "Set flags %d vol %d\n", v->flags, v->volume));
- /* set volume */
- if (v->flags & VIDEO_AUDIO_VOLUME)
- fmr2->curvol = v->volume; /* !!! set with precision */
- if (fmr2->card_type != 11) fmr2->curvol = 65535;
- fmr2->mute = 0;
- if (v->flags & VIDEO_AUDIO_MUTE)
- fmr2->mute = 1;
+ struct v4l2_queryctrl *qc = arg;
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) {
+ if ((fmr2->card_type != 11)
+ && V4L2_CID_AUDIO_VOLUME)
+ radio_qctrl[i].step=65535;
+ if (qc->id && qc->id == radio_qctrl[i].id) {
+ memcpy(qc, &(radio_qctrl[i]),
+ sizeof(*qc));
+ return (0);
+ }
+ }
+ return -EINVAL;
+ }
+ case VIDIOC_G_CTRL:
+ {
+ struct v4l2_control *ctrl= arg;
+
+ switch (ctrl->id) {
+ case V4L2_CID_AUDIO_MUTE:
+ ctrl->value=fmr2->mute;
+ return (0);
+ case V4L2_CID_AUDIO_VOLUME:
+ ctrl->value=fmr2->curvol;
+ return (0);
+ }
+ return -EINVAL;
+ }
+ case VIDIOC_S_CTRL:
+ {
+ struct v4l2_control *ctrl= arg;
+
+ switch (ctrl->id) {
+ case V4L2_CID_AUDIO_MUTE:
+ fmr2->mute=ctrl->value;
+ if (fmr2->card_type != 11) {
+ if (!fmr2->mute) {
+ fmr2->curvol = 65535;
+ } else {
+ fmr2->curvol = 0;
+ }
+ }
+ break;
+ case V4L2_CID_AUDIO_VOLUME:
+ fmr2->curvol = ctrl->value;
+ if (fmr2->card_type != 11) {
+ if (fmr2->curvol) {
+ fmr2->curvol = 65535;
+ fmr2->mute = 0;
+ } else {
+ fmr2->curvol = 0;
+ fmr2->mute = 1;
+ }
+ }
+ break;
+ default:
+ return -EINVAL;
+ }
#ifdef DEBUG
if (fmr2->curvol && !fmr2->mute)
printk(KERN_DEBUG "unmute\n");
@@ -320,27 +387,18 @@ static int fmr2_do_ioctl(struct inode *inode, struct file *file,
printk(KERN_DEBUG "mute\n");
#endif
mutex_lock(&lock);
- if (fmr2->curvol && !fmr2->mute)
- {
+ if (fmr2->curvol && !fmr2->mute) {
fmr2_setvolume(fmr2);
fmr2_setfreq(fmr2);
- }
- else fmr2_mute(fmr2->port);
+ } else
+ fmr2_mute(fmr2->port);
mutex_unlock(&lock);
- return 0;
- }
- case VIDIOCGUNIT:
- {
- struct video_unit *v = arg;
- v->video=VIDEO_NO_UNIT;
- v->vbi=VIDEO_NO_UNIT;
- v->radio=dev->minor;
- v->audio=0; /* How do we find out this??? */
- v->teletext=VIDEO_NO_UNIT;
- return 0;
+ return (0);
}
default:
- return -ENOIOCTLCMD;
+ return v4l_compat_translate_ioctl(inode,file,cmd,arg,
+ fmr2_do_ioctl);
+
}
}
@@ -366,7 +424,7 @@ static struct video_device fmr2_radio=
.owner = THIS_MODULE,
.name = "SF16FMR2 radio",
. type = VID_TYPE_TUNER,
- .hardware = VID_HARDWARE_SF16FMR2,
+ .hardware = 0,
.fops = &fmr2_fops,
};
@@ -377,7 +435,7 @@ static int __init fmr2_init(void)
fmr2_unit.mute = 0;
fmr2_unit.curfreq = 0;
fmr2_unit.stereo = 1;
- fmr2_unit.flags = VIDEO_TUNER_LOW;
+ fmr2_unit.flags = V4L2_TUNER_CAP_LOW;
fmr2_unit.card_type = 0;
fmr2_radio.priv = &fmr2_unit;
@@ -396,7 +454,6 @@ static int __init fmr2_init(void)
}
printk(KERN_INFO "SF16FMR2 radio card driver at 0x%x.\n", io);
- debug_print((KERN_DEBUG "Mute %d Low %d\n",VIDEO_AUDIO_MUTE,VIDEO_TUNER_LOW));
/* mute card - prevents noisy bootups */
mutex_lock(&lock);
fmr2_mute(io);
diff --git a/drivers/media/radio/radio-terratec.c b/drivers/media/radio/radio-terratec.c
index dfba4ae596cd..f539491a0d76 100644
--- a/drivers/media/radio/radio-terratec.c
+++ b/drivers/media/radio/radio-terratec.c
@@ -21,6 +21,7 @@
* If you can help me out with that, please contact me!!
*
*
+ * Converted to V4L2 API by Mauro Carvalho Chehab <mchehab@infradead.org>
*/
#include <linux/module.h> /* Modules */
@@ -29,11 +30,32 @@
#include <linux/delay.h> /* udelay */
#include <asm/io.h> /* outb, outb_p */
#include <asm/uaccess.h> /* copy to/from user */
-#include <linux/videodev.h> /* kernel radio structs */
+#include <linux/videodev2.h> /* kernel radio structs */
#include <media/v4l2-common.h>
-#include <linux/config.h> /* CONFIG_RADIO_TERRATEC_PORT */
#include <linux/spinlock.h>
+#include <linux/version.h> /* for KERNEL_VERSION MACRO */
+#define RADIO_VERSION KERNEL_VERSION(0,0,2)
+
+static struct v4l2_queryctrl radio_qctrl[] = {
+ {
+ .id = V4L2_CID_AUDIO_MUTE,
+ .name = "Mute",
+ .minimum = 0,
+ .maximum = 1,
+ .default_value = 1,
+ .type = V4L2_CTRL_TYPE_BOOLEAN,
+ },{
+ .id = V4L2_CID_AUDIO_VOLUME,
+ .name = "Volume",
+ .minimum = 0,
+ .maximum = 0xff,
+ .step = 1,
+ .default_value = 0xff,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ }
+};
+
#ifndef CONFIG_RADIO_TERRATEC_PORT
#define CONFIG_RADIO_TERRATEC_PORT 0x590
#endif
@@ -194,73 +216,117 @@ static int tt_do_ioctl(struct inode *inode, struct file *file,
switch(cmd)
{
- case VIDIOCGCAP:
+ case VIDIOC_QUERYCAP:
{
- struct video_capability *v = arg;
+ struct v4l2_capability *v = arg;
memset(v,0,sizeof(*v));
- v->type=VID_TYPE_TUNER;
- v->channels=1;
- v->audios=1;
- strcpy(v->name, "ActiveRadio");
+ strlcpy(v->driver, "radio-terratec", sizeof (v->driver));
+ strlcpy(v->card, "ActiveRadio", sizeof (v->card));
+ sprintf(v->bus_info,"ISA");
+ v->version = RADIO_VERSION;
+ v->capabilities = V4L2_CAP_TUNER;
+
return 0;
}
- case VIDIOCGTUNER:
+ case VIDIOC_G_TUNER:
{
- struct video_tuner *v = arg;
- if(v->tuner) /* Only 1 tuner */
+ struct v4l2_tuner *v = arg;
+
+ if (v->index > 0)
return -EINVAL;
+
+ memset(v,0,sizeof(*v));
+ strcpy(v->name, "FM");
+ v->type = V4L2_TUNER_RADIO;
+
v->rangelow=(87*16000);
v->rangehigh=(108*16000);
- v->flags=VIDEO_TUNER_LOW;
- v->mode=VIDEO_MODE_AUTO;
- strcpy(v->name, "FM");
+ v->rxsubchans =V4L2_TUNER_SUB_MONO;
+ v->capability=V4L2_TUNER_CAP_LOW;
+ v->audmode = V4L2_TUNER_MODE_MONO;
v->signal=0xFFFF*tt_getsigstr(tt);
+
return 0;
}
- case VIDIOCSTUNER:
+ case VIDIOC_S_TUNER:
{
- struct video_tuner *v = arg;
- if(v->tuner!=0)
+ struct v4l2_tuner *v = arg;
+
+ if (v->index > 0)
return -EINVAL;
- /* Only 1 tuner so no setting needed ! */
+
return 0;
}
- case VIDIOCGFREQ:
+ case VIDIOC_S_FREQUENCY:
{
- unsigned long *freq = arg;
- *freq = tt->curfreq;
+ struct v4l2_frequency *f = arg;
+
+ tt->curfreq = f->frequency;
+ tt_setfreq(tt, tt->curfreq);
return 0;
}
- case VIDIOCSFREQ:
+ case VIDIOC_G_FREQUENCY:
{
- unsigned long *freq = arg;
- tt->curfreq = *freq;
- tt_setfreq(tt, tt->curfreq);
+ struct v4l2_frequency *f = arg;
+
+ f->type = V4L2_TUNER_RADIO;
+ f->frequency = tt->curfreq;
+
return 0;
}
- case VIDIOCGAUDIO:
+ case VIDIOC_QUERYCTRL:
{
- struct video_audio *v = arg;
- memset(v,0, sizeof(*v));
- v->flags|=VIDEO_AUDIO_MUTABLE|VIDEO_AUDIO_VOLUME;
- v->volume=tt->curvol * 6554;
- v->step=6554;
- strcpy(v->name, "Radio");
- return 0;
+ struct v4l2_queryctrl *qc = arg;
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) {
+ if (qc->id && qc->id == radio_qctrl[i].id) {
+ memcpy(qc, &(radio_qctrl[i]),
+ sizeof(*qc));
+ return (0);
+ }
+ }
+ return -EINVAL;
}
- case VIDIOCSAUDIO:
+ case VIDIOC_G_CTRL:
{
- struct video_audio *v = arg;
- if(v->audio)
- return -EINVAL;
- if(v->flags&VIDEO_AUDIO_MUTE)
- tt_mute(tt);
- else
- tt_setvol(tt,v->volume/6554);
- return 0;
+ struct v4l2_control *ctrl= arg;
+
+ switch (ctrl->id) {
+ case V4L2_CID_AUDIO_MUTE:
+ if (tt->muted)
+ ctrl->value=1;
+ else
+ ctrl->value=0;
+ return (0);
+ case V4L2_CID_AUDIO_VOLUME:
+ ctrl->value=tt->curvol * 6554;
+ return (0);
+ }
+ return -EINVAL;
}
+ case VIDIOC_S_CTRL:
+ {
+ struct v4l2_control *ctrl= arg;
+
+ switch (ctrl->id) {
+ case V4L2_CID_AUDIO_MUTE:
+ if (ctrl->value) {
+ tt_mute(tt);
+ } else {
+ tt_setvol(tt,tt->curvol);
+ }
+ return (0);
+ case V4L2_CID_AUDIO_VOLUME:
+ tt_setvol(tt,ctrl->value);
+ return (0);
+ }
+ return -EINVAL;
+ }
+
default:
- return -ENOIOCTLCMD;
+ return v4l_compat_translate_ioctl(inode,file,cmd,arg,
+ tt_do_ioctl);
}
}
@@ -286,7 +352,7 @@ static struct video_device terratec_radio=
.owner = THIS_MODULE,
.name = "TerraTec ActiveRadio",
.type = VID_TYPE_TUNER,
- .hardware = VID_HARDWARE_TERRATEC,
+ .hardware = 0,
.fops = &terratec_fops,
};
diff --git a/drivers/media/radio/radio-trust.c b/drivers/media/radio/radio-trust.c
index 8da4badc22b4..bb03ad5a2033 100644
--- a/drivers/media/radio/radio-trust.c
+++ b/drivers/media/radio/radio-trust.c
@@ -12,7 +12,7 @@
* Scott McGrath (smcgrath@twilight.vtc.vsc.edu)
* William McGrath (wmcgrath@twilight.vtc.vsc.edu)
*
- * The basis for this code may be found at http://bigbang.vtc.vsc.edu/fmradio/
+ * Converted to V4L2 API by Mauro Carvalho Chehab <mchehab@infradead.org>
*/
#include <stdarg.h>
@@ -21,9 +21,46 @@
#include <linux/ioport.h>
#include <asm/io.h>
#include <asm/uaccess.h>
-#include <linux/videodev.h>
+#include <linux/videodev2.h>
#include <media/v4l2-common.h>
-#include <linux/config.h> /* CONFIG_RADIO_TRUST_PORT */
+
+#include <linux/version.h> /* for KERNEL_VERSION MACRO */
+#define RADIO_VERSION KERNEL_VERSION(0,0,2)
+
+static struct v4l2_queryctrl radio_qctrl[] = {
+ {
+ .id = V4L2_CID_AUDIO_MUTE,
+ .name = "Mute",
+ .minimum = 0,
+ .maximum = 1,
+ .default_value = 1,
+ .type = V4L2_CTRL_TYPE_BOOLEAN,
+ },{
+ .id = V4L2_CID_AUDIO_VOLUME,
+ .name = "Volume",
+ .minimum = 0,
+ .maximum = 65535,
+ .step = 2048,
+ .default_value = 65535,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ },{
+ .id = V4L2_CID_AUDIO_BASS,
+ .name = "Bass",
+ .minimum = 0,
+ .maximum = 65535,
+ .step = 4370,
+ .default_value = 32768,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ },{
+ .id = V4L2_CID_AUDIO_TREBLE,
+ .name = "Treble",
+ .minimum = 0,
+ .maximum = 65535,
+ .step = 4370,
+ .default_value = 32768,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ },
+};
/* acceptable ports: 0x350 (JP3 shorted), 0x358 (JP3 open) */
@@ -160,88 +197,125 @@ static int tr_do_ioctl(struct inode *inode, struct file *file,
{
switch(cmd)
{
- case VIDIOCGCAP:
+ case VIDIOC_QUERYCAP:
{
- struct video_capability *v = arg;
-
+ struct v4l2_capability *v = arg;
memset(v,0,sizeof(*v));
- v->type=VID_TYPE_TUNER;
- v->channels=1;
- v->audios=1;
- strcpy(v->name, "Trust FM Radio");
+ strlcpy(v->driver, "radio-trust", sizeof (v->driver));
+ strlcpy(v->card, "Trust FM Radio", sizeof (v->card));
+ sprintf(v->bus_info,"ISA");
+ v->version = RADIO_VERSION;
+ v->capabilities = V4L2_CAP_TUNER;
return 0;
}
- case VIDIOCGTUNER:
+ case VIDIOC_G_TUNER:
{
- struct video_tuner *v = arg;
+ struct v4l2_tuner *v = arg;
- if(v->tuner) /* Only 1 tuner */
+ if (v->index > 0)
return -EINVAL;
- v->rangelow = 87500 * 16;
- v->rangehigh = 108000 * 16;
- v->flags = VIDEO_TUNER_LOW;
- v->mode = VIDEO_MODE_AUTO;
+ memset(v,0,sizeof(*v));
+ strcpy(v->name, "FM");
+ v->type = V4L2_TUNER_RADIO;
- v->signal = tr_getsigstr();
+ v->rangelow=(87.5*16000);
+ v->rangehigh=(108*16000);
+ v->rxsubchans =V4L2_TUNER_SUB_MONO|V4L2_TUNER_SUB_STEREO;
+ v->capability=V4L2_TUNER_CAP_LOW;
if(tr_getstereo())
- v->flags |= VIDEO_TUNER_STEREO_ON;
-
- strcpy(v->name, "FM");
+ v->audmode = V4L2_TUNER_MODE_STEREO;
+ else
+ v->audmode = V4L2_TUNER_MODE_MONO;
+ v->signal=tr_getsigstr();
return 0;
}
- case VIDIOCSTUNER:
+ case VIDIOC_S_TUNER:
{
- struct video_tuner *v = arg;
- if(v->tuner != 0)
+ struct v4l2_tuner *v = arg;
+
+ if (v->index > 0)
return -EINVAL;
+
return 0;
}
- case VIDIOCGFREQ:
+ case VIDIOC_S_FREQUENCY:
{
- unsigned long *freq = arg;
- *freq = curfreq;
+ struct v4l2_frequency *f = arg;
+
+ curfreq = f->frequency;
+ tr_setfreq(curfreq);
return 0;
}
- case VIDIOCSFREQ:
+ case VIDIOC_G_FREQUENCY:
{
- unsigned long *freq = arg;
- tr_setfreq(*freq);
+ struct v4l2_frequency *f = arg;
+
+ f->type = V4L2_TUNER_RADIO;
+ f->frequency = curfreq;
+
return 0;
}
- case VIDIOCGAUDIO:
+ case VIDIOC_QUERYCTRL:
{
- struct video_audio *v = arg;
-
- memset(v,0, sizeof(*v));
- v->flags = VIDEO_AUDIO_MUTABLE | VIDEO_AUDIO_VOLUME |
- VIDEO_AUDIO_BASS | VIDEO_AUDIO_TREBLE;
- v->mode = curstereo? VIDEO_SOUND_STEREO : VIDEO_SOUND_MONO;
- v->volume = curvol * 2048;
- v->step = 2048;
- v->bass = curbass * 4370;
- v->treble = curtreble * 4370;
-
- strcpy(v->name, "Trust FM Radio");
- return 0;
+ struct v4l2_queryctrl *qc = arg;
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) {
+ if (qc->id && qc->id == radio_qctrl[i].id) {
+ memcpy(qc, &(radio_qctrl[i]),
+ sizeof(*qc));
+ return (0);
+ }
+ }
+ return -EINVAL;
}
- case VIDIOCSAUDIO:
+ case VIDIOC_G_CTRL:
{
- struct video_audio *v = arg;
-
- if(v->audio)
- return -EINVAL;
- tr_setvol(v->volume);
- tr_setbass(v->bass);
- tr_settreble(v->treble);
- tr_setstereo(v->mode & VIDEO_SOUND_STEREO);
- tr_setmute(v->flags & VIDEO_AUDIO_MUTE);
- return 0;
+ struct v4l2_control *ctrl= arg;
+
+ switch (ctrl->id) {
+ case V4L2_CID_AUDIO_MUTE:
+ ctrl->value=curmute;
+ return (0);
+ case V4L2_CID_AUDIO_VOLUME:
+ ctrl->value= curvol * 2048;
+ return (0);
+ case V4L2_CID_AUDIO_BASS:
+ ctrl->value= curbass * 4370;
+ return (0);
+ case V4L2_CID_AUDIO_TREBLE:
+ ctrl->value= curtreble * 4370;
+ return (0);
+ }
+ return -EINVAL;
}
+ case VIDIOC_S_CTRL:
+ {
+ struct v4l2_control *ctrl= arg;
+
+ switch (ctrl->id) {
+ case V4L2_CID_AUDIO_MUTE:
+ tr_setmute(ctrl->value);
+ return 0;
+ case V4L2_CID_AUDIO_VOLUME:
+ tr_setvol(ctrl->value);
+ return 0;
+ case V4L2_CID_AUDIO_BASS:
+ tr_setbass(ctrl->value);
+ return 0;
+ case V4L2_CID_AUDIO_TREBLE:
+ tr_settreble(ctrl->value);
+ return (0);
+ }
+ return -EINVAL;
+ }
+
default:
- return -ENOIOCTLCMD;
+ return v4l_compat_translate_ioctl(inode,file,cmd,arg,
+ tr_do_ioctl);
}
}
@@ -265,7 +339,7 @@ static struct video_device trust_radio=
.owner = THIS_MODULE,
.name = "Trust FM Radio",
.type = VID_TYPE_TUNER,
- .hardware = VID_HARDWARE_TRUST,
+ .hardware = 0,
.fops = &trust_fops,
};
diff --git a/drivers/media/radio/radio-typhoon.c b/drivers/media/radio/radio-typhoon.c
index edd012288669..4a72b4d4e62a 100644
--- a/drivers/media/radio/radio-typhoon.c
+++ b/drivers/media/radio/radio-typhoon.c
@@ -27,6 +27,8 @@
* value where I do expect just noise and turn the speaker volume down.
* The frequency change is necessary since the card never seems to be
* completely silent.
+ *
+ * Converted to V4L2 API by Mauro Carvalho Chehab <mchehab@infradead.org>
*/
#include <linux/module.h> /* Modules */
@@ -35,11 +37,32 @@
#include <linux/proc_fs.h> /* radio card status report */
#include <asm/io.h> /* outb, outb_p */
#include <asm/uaccess.h> /* copy to/from user */
-#include <linux/videodev.h> /* kernel radio structs */
+#include <linux/videodev2.h> /* kernel radio structs */
#include <media/v4l2-common.h>
-#include <linux/config.h> /* CONFIG_RADIO_TYPHOON_* */
-#define BANNER "Typhoon Radio Card driver v0.1\n"
+#include <linux/version.h> /* for KERNEL_VERSION MACRO */
+#define RADIO_VERSION KERNEL_VERSION(0,1,1)
+#define BANNER "Typhoon Radio Card driver v0.1.1\n"
+
+static struct v4l2_queryctrl radio_qctrl[] = {
+ {
+ .id = V4L2_CID_AUDIO_MUTE,
+ .name = "Mute",
+ .minimum = 0,
+ .maximum = 1,
+ .default_value = 1,
+ .type = V4L2_CTRL_TYPE_BOOLEAN,
+ },{
+ .id = V4L2_CID_AUDIO_VOLUME,
+ .name = "Volume",
+ .minimum = 0,
+ .maximum = 65535,
+ .step = 1<<14,
+ .default_value = 0xff,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ }
+};
+
#ifndef CONFIG_RADIO_TYPHOON_PORT
#define CONFIG_RADIO_TYPHOON_PORT -1
@@ -171,76 +194,114 @@ static int typhoon_do_ioctl(struct inode *inode, struct file *file,
struct typhoon_device *typhoon = dev->priv;
switch (cmd) {
- case VIDIOCGCAP:
+ case VIDIOC_QUERYCAP:
{
- struct video_capability *v = arg;
+ struct v4l2_capability *v = arg;
memset(v,0,sizeof(*v));
- v->type = VID_TYPE_TUNER;
- v->channels = 1;
- v->audios = 1;
- strcpy(v->name, "Typhoon Radio");
+ strlcpy(v->driver, "radio-typhoon", sizeof (v->driver));
+ strlcpy(v->card, "Typhoon Radio", sizeof (v->card));
+ sprintf(v->bus_info,"ISA");
+ v->version = RADIO_VERSION;
+ v->capabilities = V4L2_CAP_TUNER;
+
return 0;
}
- case VIDIOCGTUNER:
+ case VIDIOC_G_TUNER:
{
- struct video_tuner *v = arg;
- if (v->tuner) /* Only 1 tuner */
+ struct v4l2_tuner *v = arg;
+
+ if (v->index > 0)
return -EINVAL;
- v->rangelow = 875 * 1600;
- v->rangehigh = 1080 * 1600;
- v->flags = VIDEO_TUNER_LOW;
- v->mode = VIDEO_MODE_AUTO;
- v->signal = 0xFFFF; /* We can't get the signal strength */
+
+ memset(v,0,sizeof(*v));
strcpy(v->name, "FM");
+ v->type = V4L2_TUNER_RADIO;
+
+ v->rangelow=(87.5*16000);
+ v->rangehigh=(108*16000);
+ v->rxsubchans =V4L2_TUNER_SUB_MONO;
+ v->capability=V4L2_TUNER_CAP_LOW;
+ v->audmode = V4L2_TUNER_MODE_MONO;
+ v->signal = 0xFFFF; /* We can't get the signal strength */
+
return 0;
}
- case VIDIOCSTUNER:
+ case VIDIOC_S_TUNER:
{
- struct video_tuner *v = arg;
- if (v->tuner != 0)
+ struct v4l2_tuner *v = arg;
+
+ if (v->index > 0)
return -EINVAL;
- /* Only 1 tuner so no setting needed ! */
+
return 0;
}
- case VIDIOCGFREQ:
- {
- unsigned long *freq = arg;
- *freq = typhoon->curfreq;
- return 0;
- }
- case VIDIOCSFREQ:
- {
- unsigned long *freq = arg;
- typhoon->curfreq = *freq;
- typhoon_setfreq(typhoon, typhoon->curfreq);
- return 0;
- }
- case VIDIOCGAUDIO:
+ case VIDIOC_S_FREQUENCY:
{
- struct video_audio *v = arg;
- memset(v, 0, sizeof(*v));
- v->flags |= VIDEO_AUDIO_MUTABLE | VIDEO_AUDIO_VOLUME;
- v->mode |= VIDEO_SOUND_MONO;
- v->volume = typhoon->curvol;
- v->step = 1 << 14;
- strcpy(v->name, "Typhoon Radio");
+ struct v4l2_frequency *f = arg;
+
+ typhoon->curfreq = f->frequency;
+ typhoon_setfreq(typhoon, typhoon->curfreq);
return 0;
}
- case VIDIOCSAUDIO:
+ case VIDIOC_G_FREQUENCY:
{
- struct video_audio *v = arg;
- if (v->audio)
- return -EINVAL;
- if (v->flags & VIDEO_AUDIO_MUTE)
- typhoon_mute(typhoon);
- else
- typhoon_unmute(typhoon);
- if (v->flags & VIDEO_AUDIO_VOLUME)
- typhoon_setvol(typhoon, v->volume);
+ struct v4l2_frequency *f = arg;
+
+ f->type = V4L2_TUNER_RADIO;
+ f->frequency = typhoon->curfreq;
+
return 0;
}
- default:
- return -ENOIOCTLCMD;
+ case VIDIOC_QUERYCTRL:
+ {
+ struct v4l2_queryctrl *qc = arg;
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) {
+ if (qc->id && qc->id == radio_qctrl[i].id) {
+ memcpy(qc, &(radio_qctrl[i]),
+ sizeof(*qc));
+ return (0);
+ }
+ }
+ return -EINVAL;
+ }
+ case VIDIOC_G_CTRL:
+ {
+ struct v4l2_control *ctrl= arg;
+
+ switch (ctrl->id) {
+ case V4L2_CID_AUDIO_MUTE:
+ ctrl->value=typhoon->muted;
+ return (0);
+ case V4L2_CID_AUDIO_VOLUME:
+ ctrl->value=typhoon->curvol;
+ return (0);
+ }
+ return -EINVAL;
+ }
+ case VIDIOC_S_CTRL:
+ {
+ struct v4l2_control *ctrl= arg;
+
+ switch (ctrl->id) {
+ case V4L2_CID_AUDIO_MUTE:
+ if (ctrl->value) {
+ typhoon_mute(typhoon);
+ } else {
+ typhoon_unmute(typhoon);
+ }
+ return (0);
+ case V4L2_CID_AUDIO_VOLUME:
+ typhoon_setvol(typhoon, ctrl->value);
+ return (0);
+ }
+ return -EINVAL;
+ }
+
+ default:
+ return v4l_compat_translate_ioctl(inode,file,cmd,arg,
+ typhoon_do_ioctl);
}
}
@@ -271,7 +332,7 @@ static struct video_device typhoon_radio =
.owner = THIS_MODULE,
.name = "Typhoon Radio",
.type = VID_TYPE_TUNER,
- .hardware = VID_HARDWARE_TYPHOON,
+ .hardware = 0,
.fops = &typhoon_fops,
};
diff --git a/drivers/media/radio/radio-zoltrix.c b/drivers/media/radio/radio-zoltrix.c
index 59b86a6b4b0e..671fe1b1e5bc 100644
--- a/drivers/media/radio/radio-zoltrix.c
+++ b/drivers/media/radio/radio-zoltrix.c
@@ -24,6 +24,9 @@
* - Added unmute function
* - Reworked ioctl functions
* 2002-07-15 - Fix Stereo typo
+ *
+ * 2006-07-24 - Converted to V4L2 API
+ * by Mauro Carvalho Chehab <mchehab@infradead.org>
*/
#include <linux/module.h> /* Modules */
@@ -32,9 +35,30 @@
#include <linux/delay.h> /* udelay, msleep */
#include <asm/io.h> /* outb, outb_p */
#include <asm/uaccess.h> /* copy to/from user */
-#include <linux/videodev.h> /* kernel radio structs */
+#include <linux/videodev2.h> /* kernel radio structs */
#include <media/v4l2-common.h>
-#include <linux/config.h> /* CONFIG_RADIO_ZOLTRIX_PORT */
+
+#include <linux/version.h> /* for KERNEL_VERSION MACRO */
+#define RADIO_VERSION KERNEL_VERSION(0,0,2)
+
+static struct v4l2_queryctrl radio_qctrl[] = {
+ {
+ .id = V4L2_CID_AUDIO_MUTE,
+ .name = "Mute",
+ .minimum = 0,
+ .maximum = 1,
+ .default_value = 1,
+ .type = V4L2_CTRL_TYPE_BOOLEAN,
+ },{
+ .id = V4L2_CID_AUDIO_VOLUME,
+ .name = "Volume",
+ .minimum = 0,
+ .maximum = 65535,
+ .step = 4096,
+ .default_value = 0xff,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ }
+};
#ifndef CONFIG_RADIO_ZOLTRIX_PORT
#define CONFIG_RADIO_ZOLTRIX_PORT -1
@@ -213,78 +237,116 @@ static int zol_do_ioctl(struct inode *inode, struct file *file,
struct zol_device *zol = dev->priv;
switch (cmd) {
- case VIDIOCGCAP:
+ case VIDIOC_QUERYCAP:
{
- struct video_capability *v = arg;
-
+ struct v4l2_capability *v = arg;
memset(v,0,sizeof(*v));
- v->type = VID_TYPE_TUNER;
- v->channels = 1 + zol->stereo;
- v->audios = 1;
- strcpy(v->name, "Zoltrix Radio");
+ strlcpy(v->driver, "radio-zoltrix", sizeof (v->driver));
+ strlcpy(v->card, "Zoltrix Radio", sizeof (v->card));
+ sprintf(v->bus_info,"ISA");
+ v->version = RADIO_VERSION;
+ v->capabilities = V4L2_CAP_TUNER;
+
return 0;
}
- case VIDIOCGTUNER:
+ case VIDIOC_G_TUNER:
{
- struct video_tuner *v = arg;
- if (v->tuner)
+ struct v4l2_tuner *v = arg;
+
+ if (v->index > 0)
return -EINVAL;
+
+ memset(v,0,sizeof(*v));
strcpy(v->name, "FM");
- v->rangelow = (int) (88.0 * 16000);
- v->rangehigh = (int) (108.0 * 16000);
- v->flags = zol_is_stereo(zol)
- ? VIDEO_TUNER_STEREO_ON : 0;
- v->flags |= VIDEO_TUNER_LOW;
- v->mode = VIDEO_MODE_AUTO;
- v->signal = 0xFFFF * zol_getsigstr(zol);
+ v->type = V4L2_TUNER_RADIO;
+
+ v->rangelow=(88*16000);
+ v->rangehigh=(108*16000);
+ v->rxsubchans =V4L2_TUNER_SUB_MONO|V4L2_TUNER_SUB_STEREO;
+ v->capability=V4L2_TUNER_CAP_LOW;
+ if(zol_is_stereo(zol))
+ v->audmode = V4L2_TUNER_MODE_STEREO;
+ else
+ v->audmode = V4L2_TUNER_MODE_MONO;
+ v->signal=0xFFFF*zol_getsigstr(zol);
+
return 0;
}
- case VIDIOCSTUNER:
+ case VIDIOC_S_TUNER:
{
- struct video_tuner *v = arg;
- if (v->tuner != 0)
+ struct v4l2_tuner *v = arg;
+
+ if (v->index > 0)
return -EINVAL;
- /* Only 1 tuner so no setting needed ! */
+
return 0;
}
- case VIDIOCGFREQ:
- {
- unsigned long *freq = arg;
- *freq = zol->curfreq;
- return 0;
- }
- case VIDIOCSFREQ:
- {
- unsigned long *freq = arg;
- zol->curfreq = *freq;
- zol_setfreq(zol, zol->curfreq);
- return 0;
- }
- case VIDIOCGAUDIO:
+ case VIDIOC_S_FREQUENCY:
{
- struct video_audio *v = arg;
- memset(v, 0, sizeof(*v));
- v->flags |= VIDEO_AUDIO_MUTABLE | VIDEO_AUDIO_VOLUME;
- v->mode |= zol_is_stereo(zol)
- ? VIDEO_SOUND_STEREO : VIDEO_SOUND_MONO;
- v->volume = zol->curvol * 4096;
- v->step = 4096;
- strcpy(v->name, "Zoltrix Radio");
+ struct v4l2_frequency *f = arg;
+
+ zol->curfreq = f->frequency;
+ zol_setfreq(zol, zol->curfreq);
return 0;
}
- case VIDIOCSAUDIO:
+ case VIDIOC_G_FREQUENCY:
{
- struct video_audio *v = arg;
- if (v->audio)
- return -EINVAL;
+ struct v4l2_frequency *f = arg;
- if (v->flags & VIDEO_AUDIO_MUTE)
- zol_mute(zol);
- else {
- zol_unmute(zol);
- zol_setvol(zol, v->volume / 4096);
- }
+ f->type = V4L2_TUNER_RADIO;
+ f->frequency = zol->curfreq;
+ return 0;
+ }
+ case VIDIOC_QUERYCTRL:
+ {
+ struct v4l2_queryctrl *qc = arg;
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) {
+ if (qc->id && qc->id == radio_qctrl[i].id) {
+ memcpy(qc, &(radio_qctrl[i]),
+ sizeof(*qc));
+ return (0);
+ }
+ }
+ return -EINVAL;
+ }
+ case VIDIOC_G_CTRL:
+ {
+ struct v4l2_control *ctrl= arg;
+
+ switch (ctrl->id) {
+ case V4L2_CID_AUDIO_MUTE:
+ ctrl->value=zol->muted;
+ return (0);
+ case V4L2_CID_AUDIO_VOLUME:
+ ctrl->value=zol->curvol * 4096;
+ return (0);
+ }
+ return -EINVAL;
+ }
+ case VIDIOC_S_CTRL:
+ {
+ struct v4l2_control *ctrl= arg;
+
+ switch (ctrl->id) {
+ case V4L2_CID_AUDIO_MUTE:
+ if (ctrl->value) {
+ zol_mute(zol);
+ } else {
+ zol_unmute(zol);
+ zol_setvol(zol,zol->curvol);
+ }
+ return (0);
+ case V4L2_CID_AUDIO_VOLUME:
+ zol_setvol(zol,ctrl->value/4096);
+ return (0);
+ }
+ zol->stereo = 1;
+ zol_setfreq(zol, zol->curfreq);
+#if 0
+/* FIXME: Implement stereo/mono switch on V4L2 */
if (v->mode & VIDEO_SOUND_STEREO) {
zol->stereo = 1;
zol_setfreq(zol, zol->curfreq);
@@ -293,10 +355,13 @@ static int zol_do_ioctl(struct inode *inode, struct file *file,
zol->stereo = 0;
zol_setfreq(zol, zol->curfreq);
}
- return 0;
+#endif
+ return -EINVAL;
}
- default:
- return -ENOIOCTLCMD;
+
+ default:
+ return v4l_compat_translate_ioctl(inode,file,cmd,arg,
+ zol_do_ioctl);
}
}
@@ -323,7 +388,7 @@ static struct video_device zoltrix_radio =
.owner = THIS_MODULE,
.name = "Zoltrix Radio Plus",
.type = VID_TYPE_TUNER,
- .hardware = VID_HARDWARE_ZOLTRIX,
+ .hardware = 0,
.fops = &zoltrix_fops,
};
diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig
index 94d078b77bab..d1183c939221 100644
--- a/drivers/media/video/Kconfig
+++ b/drivers/media/video/Kconfig
@@ -16,6 +16,320 @@ config VIDEO_ADV_DEBUG
V4L devices.
In doubt, say N.
+config VIDEO_HELPER_CHIPS_AUTO
+ bool "Autoselect pertinent encoders/decoders and other helper chips"
+ default y
+ ---help---
+ Most video cards may require additional modules to encode or
+ decode audio/video standards. This option will autoselect
+ all pertinent modules to each selected video module.
+
+ Unselect this only if you know exaclty what you are doing, since
+ it may break support on some boards.
+
+ In doubt, say Y.
+
+#
+# Encoder / Decoder module configuration
+#
+
+menu "Encoders/decoders and other helper chips"
+ depends on VIDEO_DEV && !VIDEO_HELPER_CHIPS_AUTO
+
+comment "Audio Decoders"
+
+config VIDEO_TVAUDIO
+ tristate "Simple audio decoder chips"
+ depends on VIDEO_V4L1 && I2C
+ ---help---
+ Support for several audio decoder chips found on some bt8xx boards:
+ Philips: tda9840, tda9873h, tda9874h/a, tda9850, tda985x, tea6300,
+ tea6320, tea6420, tda8425, ta8874z.
+ Microchip: pic16c54 based design on ProVideo PV951 board.
+
+ To compile this driver as a module, choose M here: the
+ module will be called tvaudio.
+
+config VIDEO_TDA7432
+ tristate "Philips TDA7432 audio processor chip"
+ depends on VIDEO_V4L1 && I2C
+ ---help---
+ Support for tda7432 audio decoder chip found on some bt8xx boards.
+
+ To compile this driver as a module, choose M here: the
+ module will be called tda7432.
+
+config VIDEO_TDA9840
+ tristate "Philips TDA9840 audio processor chip"
+ depends on VIDEO_DEV && I2C
+ ---help---
+ Support for tda9840 audio decoder chip found on some Zoran boards.
+
+ To compile this driver as a module, choose M here: the
+ module will be called tda9840.
+
+config VIDEO_TDA9875
+ tristate "Philips TDA9875 audio processor chip"
+ depends on VIDEO_V4L1 && I2C
+ ---help---
+ Support for tda9875 audio decoder chip found on some bt8xx boards.
+
+ To compile this driver as a module, choose M here: the
+ module will be called tda9875.
+
+config VIDEO_TEA6415C
+ tristate "Philips TEA6415C audio processor chip"
+ depends on VIDEO_DEV && I2C
+ ---help---
+ Support for tea6415c audio decoder chip found on some bt8xx boards.
+
+ To compile this driver as a module, choose M here: the
+ module will be called tea6415c.
+
+config VIDEO_TEA6420
+ tristate "Philips TEA6420 audio processor chip"
+ depends on VIDEO_DEV && I2C
+ ---help---
+ Support for tea6420 audio decoder chip found on some bt8xx boards.
+
+ To compile this driver as a module, choose M here: the
+ module will be called tea6420.
+
+config VIDEO_MSP3400
+ tristate "Micronas MSP34xx audio decoders"
+ depends on VIDEO_V4L2 && I2C
+ ---help---
+ Support for the Micronas MSP34xx series of audio decoders.
+
+ To compile this driver as a module, choose M here: the
+ module will be called msp3400.
+
+config VIDEO_CS53L32A
+ tristate "Cirrus Logic CS53L32A audio ADC"
+ depends on VIDEO_V4L2 && I2C && EXPERIMENTAL
+ ---help---
+ Support for the Cirrus Logic CS53L32A low voltage
+ stereo A/D converter.
+
+ To compile this driver as a module, choose M here: the
+ module will be called cs53l32a.
+
+config VIDEO_TLV320AIC23B
+ tristate "Texas Instruments TLV320AIC23B audio codec"
+ depends on VIDEO_V4L2 && I2C && EXPERIMENTAL
+ ---help---
+ Support for the Texas Instruments TLV320AIC23B audio codec.
+
+ To compile this driver as a module, choose M here: the
+ module will be called tlv320aic23b.
+
+config VIDEO_WM8775
+ tristate "Wolfson Microelectronics WM8775 audio ADC with input mixer"
+ depends on VIDEO_V4L2 && I2C && EXPERIMENTAL
+ ---help---
+ Support for the Wolfson Microelectronics WM8775 high
+ performance stereo A/D Converter with a 4 channel input mixer.
+
+ To compile this driver as a module, choose M here: the
+ module will be called wm8775.
+
+config VIDEO_WM8739
+ tristate "Wolfson Microelectronics WM8739 stereo audio ADC"
+ depends on VIDEO_V4L2 && I2C && EXPERIMENTAL
+ ---help---
+ Support for the Wolfson Microelectronics WM8739
+ stereo A/D Converter.
+
+ To compile this driver as a module, choose M here: the
+ module will be called wm8739.
+
+comment "MPEG video encoders"
+
+config VIDEO_CX2341X
+ tristate "Conexant CX2341x MPEG encoders"
+ depends on VIDEO_V4L2 && EXPERIMENTAL
+ ---help---
+ Support for the Conexant CX23416 MPEG encoders
+ and CX23415 MPEG encoder/decoders.
+
+ This module currently supports the encoding functions only.
+
+ To compile this driver as a module, choose M here: the
+ module will be called cx2341x.
+
+source "drivers/media/video/cx25840/Kconfig"
+
+comment "Video encoders"
+
+config VIDEO_SAA7127
+ tristate "Philips SAA7127/9 digital video encoders"
+ depends on VIDEO_V4L2 && I2C && EXPERIMENTAL
+ ---help---
+ Support for the Philips SAA7127/9 digital video encoders.
+
+ To compile this driver as a module, choose M here: the
+ module will be called saa7127.
+
+config VIDEO_SAA7185
+ tristate "Philips SAA7185 video encoder"
+ depends on VIDEO_V4L1 && I2C
+ ---help---
+ Support for the Philips SAA7185 video encoder.
+
+ To compile this driver as a module, choose M here: the
+ module will be called saa7185.
+
+config VIDEO_ADV7170
+ tristate "Analog Devices ADV7170 video encoder driver"
+ depends on VIDEO_V4L1 && I2C
+ ---help---
+ Support for the Analog Devices ADV7170 video encoder driver
+
+ To compile this driver as a module, choose M here: the
+ module will be called adv7170.
+
+config VIDEO_ADV7175
+ tristate "Analog Devices ADV7175 video encoder driver"
+ depends on VIDEO_V4L1 && I2C
+ ---help---
+ Support for the Analog Devices ADV7175 video encoder driver
+
+ To compile this driver as a module, choose M here: the
+ module will be called adv7175.
+
+comment "Video decoders"
+
+config VIDEO_BT819
+ tristate "BT819A VideoStream Decoder"
+ depends on VIDEO_V4L1 && I2C
+ ---help---
+ Support for BT819A video decoder.
+
+ To compile this driver as a module, choose M here: the
+ module will be called bt819.
+
+config VIDEO_BT856
+ tristate "BT856 VideoStream Decoder"
+ depends on VIDEO_V4L1 && I2C
+ ---help---
+ Support for BT856 video decoder.
+
+ To compile this driver as a module, choose M here: the
+ module will be called bt856.
+
+config VIDEO_BT866
+ tristate "BT866 VideoStream Decoder"
+ depends on VIDEO_V4L1 && I2C
+ ---help---
+ Support for BT866 video decoder.
+
+ To compile this driver as a module, choose M here: the
+ module will be called bt866.
+
+config VIDEO_KS0127
+ tristate "KS0127 video decoder"
+ depends on VIDEO_V4L1 && I2C
+ ---help---
+ Support for KS0127 video decoder.
+
+ This chip is used on AverMedia AVS6EYES Zoran-based MJPEG
+ cards.
+
+ To compile this driver as a module, choose M here: the
+ module will be called ks0127.
+
+config VIDEO_SAA7110
+ tristate "Philips SAA7110 video decoder"
+ depends on VIDEO_V4L1
+ ---help---
+ Support for the Philips SAA7110 video decoders.
+
+ To compile this driver as a module, choose M here: the
+ module will be called saa7110.
+
+config VIDEO_SAA7111
+ tristate "Philips SAA7111 video decoder"
+ depends on VIDEO_V4L1 && I2C
+ ---help---
+ Support for the Philips SAA711 video decoder.
+
+ To compile this driver as a module, choose M here: the
+ module will be called saa7111.
+
+config VIDEO_SAA7114
+ tristate "Philips SAA7114 video decoder"
+ depends on VIDEO_V4L1 && I2C
+ ---help---
+ Support for the Philips SAA7114 video decoder. This driver
+ is used only on Zoran driver and should be moved soon to
+ SAA711x module.
+
+ To compile this driver as a module, choose M here: the
+ module will be called saa7114.
+
+config VIDEO_SAA711X
+ tristate "Philips SAA7113/4/5 video decoders"
+ depends on VIDEO_V4L2 && I2C && EXPERIMENTAL
+ ---help---
+ Support for the Philips SAA7113/4/5 video decoders.
+
+ To compile this driver as a module, choose M here: the
+ module will be called saa7115.
+
+config VIDEO_SAA7191
+ tristate "Philips SAA7191 video decoder"
+ depends on VIDEO_V4L1 && I2C
+ ---help---
+ Support for the Philips SAA7191 video decoder.
+
+ To compile this driver as a module, choose M here: the
+ module will be called saa7191.
+
+config VIDEO_TVP5150
+ tristate "Texas Instruments TVP5150 video decoder"
+ depends on VIDEO_V4L2 && I2C
+ ---help---
+ Support for the Texas Instruments TVP5150 video decoder.
+
+ To compile this driver as a module, choose M here: the
+ module will be called tvp5150.
+
+config VIDEO_VPX3220
+ tristate "vpx3220a, vpx3216b & vpx3214c video decoder driver"
+ depends on VIDEO_V4L1 && I2C
+ ---help---
+ Support for VPX322x video decoders.
+
+ To compile this driver as a module, choose M here: the
+ module will be called vpx3220.
+
+comment "Video improvement chips"
+
+config VIDEO_UPD64031A
+ tristate "NEC Electronics uPD64031A Ghost Reduction"
+ depends on VIDEO_V4L2 && I2C && EXPERIMENTAL
+ ---help---
+ Support for the NEC Electronics uPD64031A Ghost Reduction
+ video chip. It is most often found in NTSC TV cards made for
+ Japan and is used to reduce the 'ghosting' effect that can
+ be present in analog TV broadcasts.
+
+ To compile this driver as a module, choose M here: the
+ module will be called upd64031a.
+
+config VIDEO_UPD64083
+ tristate "NEC Electronics uPD64083 3-Dimensional Y/C separation"
+ depends on VIDEO_V4L2 && I2C && EXPERIMENTAL
+ ---help---
+ Support for the NEC Electronics uPD64083 3-Dimensional Y/C
+ separation video chip. It is used to improve the quality of
+ the colors of a composite signal.
+
+ To compile this driver as a module, choose M here: the
+ module will be called upd64083.
+
+endmenu # encoder / decoder chips
+
config VIDEO_VIVI
tristate "Virtual Video Driver"
depends on VIDEO_V4L2 && !SPARC32 && !SPARC64
@@ -135,7 +449,7 @@ source "drivers/media/video/cpia2/Kconfig"
config VIDEO_SAA5246A
tristate "SAA5246A, SAA5281 Teletext processor"
- depends on I2C && VIDEO_V4L1
+ depends on I2C && VIDEO_V4L2
help
Support for I2C bus based teletext using the SAA5246A or SAA5281
chip. Useful only if you live in Europe.
@@ -145,7 +459,7 @@ config VIDEO_SAA5246A
config VIDEO_SAA5249
tristate "SAA5249 Teletext processor"
- depends on VIDEO_DEV && I2C && VIDEO_V4L1
+ depends on VIDEO_DEV && I2C && VIDEO_V4L2
help
Support for I2C bus based teletext using the SAA5249 chip. At the
moment this is only useful on some European WinTV cards.
@@ -162,8 +476,9 @@ config TUNER_3036
config VIDEO_VINO
tristate "SGI Vino Video For Linux (EXPERIMENTAL)"
- depends on I2C && SGI_IP22 && EXPERIMENTAL && VIDEO_V4L1
+ depends on I2C && SGI_IP22 && EXPERIMENTAL && VIDEO_V4L2
select I2C_ALGO_SGI
+ select VIDEO_SAA7191 if VIDEO_HELPER_CHIPS_AUTO
help
Say Y here to build in support for the Vino video input system found
on SGI Indy machines.
@@ -176,6 +491,9 @@ config VIDEO_STRADIS
driver for PCI. There is a product page at
<http://www.stradis.com/>.
+config VIDEO_ZORAN_ZR36060
+ tristate
+
config VIDEO_ZORAN
tristate "Zoran ZR36057/36067 Video For Linux"
depends on PCI && I2C_ALGOBIT && VIDEO_V4L1 && !PPC64
@@ -192,12 +510,18 @@ config VIDEO_ZORAN
config VIDEO_ZORAN_BUZ
tristate "Iomega Buz support"
depends on VIDEO_ZORAN
+ select VIDEO_SAA7111 if VIDEO_HELPER_CHIPS_AUTO
+ select VIDEO_SAA7185 if VIDEO_HELPER_CHIPS_AUTO
+ select VIDEO_ZORAN_ZR36060
help
Support for the Iomega Buz MJPEG capture/playback card.
config VIDEO_ZORAN_DC10
tristate "Pinnacle/Miro DC10(+) support"
depends on VIDEO_ZORAN
+ select VIDEO_SAA7110
+ select VIDEO_ADV7175 if VIDEO_HELPER_CHIPS_AUTO
+ select VIDEO_ZORAN_ZR36060
help
Support for the Pinnacle/Miro DC10(+) MJPEG capture/playback
card.
@@ -205,6 +529,8 @@ config VIDEO_ZORAN_DC10
config VIDEO_ZORAN_DC30
tristate "Pinnacle/Miro DC30(+) support"
depends on VIDEO_ZORAN
+ select VIDEO_ADV7175 if VIDEO_HELPER_CHIPS_AUTO
+ select VIDEO_VPX3220 if VIDEO_HELPER_CHIPS_AUTO
help
Support for the Pinnacle/Miro DC30(+) MJPEG capture/playback
card. This also supports really old DC10 cards based on the
@@ -213,6 +539,9 @@ config VIDEO_ZORAN_DC30
config VIDEO_ZORAN_LML33
tristate "Linux Media Labs LML33 support"
depends on VIDEO_ZORAN
+ select VIDEO_BT819 if VIDEO_HELPER_CHIPS_AUTO
+ select VIDEO_BT856 if VIDEO_HELPER_CHIPS_AUTO
+ select VIDEO_ZORAN_ZR36060
help
Support for the Linux Media Labs LML33 MJPEG capture/playback
card.
@@ -220,6 +549,9 @@ config VIDEO_ZORAN_LML33
config VIDEO_ZORAN_LML33R10
tristate "Linux Media Labs LML33R10 support"
depends on VIDEO_ZORAN
+ select VIDEO_SAA7114 if VIDEO_HELPER_CHIPS_AUTO
+ select VIDEO_ADV7170 if VIDEO_HELPER_CHIPS_AUTO
+ select VIDEO_ZORAN_ZR36060
help
support for the Linux Media Labs LML33R10 MJPEG capture/playback
card.
@@ -227,6 +559,9 @@ config VIDEO_ZORAN_LML33R10
config VIDEO_ZORAN_AVS6EYES
tristate "AverMedia 6 Eyes support (EXPERIMENTAL)"
depends on VIDEO_ZORAN && EXPERIMENTAL && VIDEO_V4L1
+ select VIDEO_BT856 if VIDEO_HELPER_CHIPS_AUTO
+ select VIDEO_KS0127 if VIDEO_HELPER_CHIPS_AUTO
+ select VIDEO_ZORAN_ZR36060
help
Support for the AverMedia 6 Eyes video surveillance card.
@@ -263,6 +598,10 @@ config VIDEO_MXB
depends on PCI && VIDEO_V4L1 && I2C
select VIDEO_SAA7146_VV
select VIDEO_TUNER
+ select VIDEO_SAA7111 if VIDEO_HELPER_CHIPS_AUTO
+ select VIDEO_TDA9840 if VIDEO_HELPER_CHIPS_AUTO
+ select VIDEO_TEA6415C if VIDEO_HELPER_CHIPS_AUTO
+ select VIDEO_TEA6420 if VIDEO_HELPER_CHIPS_AUTO
---help---
This is a video4linux driver for the 'Multimedia eXtension Board'
TV card by Siemens-Nixdorf.
@@ -274,7 +613,7 @@ config VIDEO_DPC
tristate "Philips-Semiconductors 'dpc7146 demonstration board'"
depends on PCI && VIDEO_V4L1 && I2C
select VIDEO_SAA7146_VV
- select VIDEO_V4L2
+ select VIDEO_SAA7111 if VIDEO_HELPER_CHIPS_AUTO
---help---
This is a video4linux driver for the 'dpc7146 demonstration
board' by Philips-Semiconductors. It's the reference design
@@ -287,9 +626,8 @@ config VIDEO_DPC
config VIDEO_HEXIUM_ORION
tristate "Hexium HV-PCI6 and Orion frame grabber"
- depends on PCI && VIDEO_V4L1 && I2C
+ depends on PCI && VIDEO_V4L2 && I2C
select VIDEO_SAA7146_VV
- select VIDEO_V4L2
---help---
This is a video4linux driver for the Hexium HV-PCI6 and
Orion frame grabber cards by Hexium.
@@ -299,9 +637,8 @@ config VIDEO_HEXIUM_ORION
config VIDEO_HEXIUM_GEMINI
tristate "Hexium Gemini frame grabber"
- depends on PCI && VIDEO_V4L1 && I2C
+ depends on PCI && VIDEO_V4L2 && I2C
select VIDEO_SAA7146_VV
- select VIDEO_V4L2
---help---
This is a video4linux driver for the Hexium Gemini frame
grabber card by Hexium. Please note that the Gemini Dual
@@ -320,123 +657,16 @@ config VIDEO_M32R_AR
camera module.
config VIDEO_M32R_AR_M64278
- tristate "Use Colour AR module M64278(VGA)"
- depends on VIDEO_M32R_AR && PLAT_M32700UT
- ---help---
- Say Y here to use the Renesas M64278E-800 camera module,
- which supports VGA(640x480 pixcels) size of images.
-
-#
-# Encoder / Decoder module configuration
-#
-
-menu "Encoders and Decoders"
- depends on VIDEO_DEV
-
-config VIDEO_MSP3400
- tristate "Micronas MSP34xx audio decoders"
- depends on VIDEO_DEV && I2C
- ---help---
- Support for the Micronas MSP34xx series of audio decoders.
-
- To compile this driver as a module, choose M here: the
- module will be called msp3400.
-
-config VIDEO_CS53L32A
- tristate "Cirrus Logic CS53L32A audio ADC"
- depends on VIDEO_DEV && I2C && EXPERIMENTAL
- ---help---
- Support for the Cirrus Logic CS53L32A low voltage
- stereo A/D converter.
-
- To compile this driver as a module, choose M here: the
- module will be called cs53l32a.
-
-config VIDEO_TLV320AIC23B
- tristate "Texas Instruments TLV320AIC23B audio codec"
- depends on VIDEO_DEV && I2C && EXPERIMENTAL
+ tristate "AR device with color module M64278(VGA)"
+ depends on PLAT_M32700UT
+ select VIDEO_M32R_AR
---help---
- Support for the Texas Instruments TLV320AIC23B audio codec.
-
- To compile this driver as a module, choose M here: the
- module will be called tlv320aic23b.
-
-config VIDEO_WM8775
- tristate "Wolfson Microelectronics WM8775 audio ADC with input mixer"
- depends on VIDEO_DEV && I2C && EXPERIMENTAL
- ---help---
- Support for the Wolfson Microelectronics WM8775 high
- performance stereo A/D Converter with a 4 channel input mixer.
+ This is a video4linux driver for the Renesas AR (Artificial
+ Retina) with M64278E-800 camera module.
+ This module supports VGA(640x480 pixels) resolutions.
To compile this driver as a module, choose M here: the
- module will be called wm8775.
-
-config VIDEO_WM8739
- tristate "Wolfson Microelectronics WM8739 stereo audio ADC"
- depends on VIDEO_DEV && I2C && EXPERIMENTAL
- ---help---
- Support for the Wolfson Microelectronics WM8739
- stereo A/D Converter.
-
- To compile this driver as a module, choose M here: the
- module will be called wm8739.
-
-config VIDEO_CX2341X
- tristate "Conexant CX2341x MPEG encoders"
- depends on VIDEO_V4L2 && EXPERIMENTAL
- ---help---
- Support for the Conexant CX23416 MPEG encoders
- and CX23415 MPEG encoder/decoders.
-
- This module currently supports the encoding functions only.
-
- To compile this driver as a module, choose M here: the
- module will be called cx2341x.
-
-source "drivers/media/video/cx25840/Kconfig"
-
-config VIDEO_SAA711X
- tristate "Philips SAA7113/4/5 video decoders"
- depends on VIDEO_DEV && I2C && EXPERIMENTAL
- ---help---
- Support for the Philips SAA7113/4/5 video decoders.
-
- To compile this driver as a module, choose M here: the
- module will be called saa7115.
-
-config VIDEO_SAA7127
- tristate "Philips SAA7127/9 digital video encoders"
- depends on VIDEO_V4L2 && I2C && EXPERIMENTAL
- ---help---
- Support for the Philips SAA7127/9 digital video encoders.
-
- To compile this driver as a module, choose M here: the
- module will be called saa7127.
-
-config VIDEO_UPD64031A
- tristate "NEC Electronics uPD64031A Ghost Reduction"
- depends on VIDEO_V4L2 && I2C && EXPERIMENTAL
- ---help---
- Support for the NEC Electronics uPD64031A Ghost Reduction
- video chip. It is most often found in NTSC TV cards made for
- Japan and is used to reduce the 'ghosting' effect that can
- be present in analog TV broadcasts.
-
- To compile this driver as a module, choose M here: the
- module will be called upd64031a.
-
-config VIDEO_UPD64083
- tristate "NEC Electronics uPD64083 3-Dimensional Y/C separation"
- depends on VIDEO_V4L2 && I2C && EXPERIMENTAL
- ---help---
- Support for the NEC Electronics uPD64083 3-Dimensional Y/C
- separation video chip. It is used to improve the quality of
- the colors of a composite signal.
-
- To compile this driver as a module, choose M here: the
- module will be called upd64083.
-
-endmenu # encoder / decoder chips
+ module will be called arv.
#
# USB Multimedia device configuration
@@ -445,8 +675,6 @@ endmenu # encoder / decoder chips
menu "V4L USB devices"
depends on USB && VIDEO_DEV
-source "drivers/media/video/pvrusb2/Kconfig"
-
source "drivers/media/video/em28xx/Kconfig"
source "drivers/media/video/usbvideo/Kconfig"
diff --git a/drivers/media/video/Makefile b/drivers/media/video/Makefile
index e82e511f2a72..af57abce8a6e 100644
--- a/drivers/media/video/Makefile
+++ b/drivers/media/video/Makefile
@@ -17,7 +17,10 @@ ifeq ($(CONFIG_VIDEO_V4L1_COMPAT),y)
endif
obj-$(CONFIG_VIDEO_BT848) += bt8xx/
-obj-$(CONFIG_VIDEO_BT848) += tvaudio.o tda7432.o tda9875.o ir-kbd-i2c.o
+obj-$(CONFIG_VIDEO_BT848) += ir-kbd-i2c.o
+obj-$(CONFIG_VIDEO_TVAUDIO) += tvaudio.o
+obj-$(CONFIG_VIDEO_TDA7432) += tda7432.o
+obj-$(CONFIG_VIDEO_TDA9875) += tda9875.o
obj-$(CONFIG_SOUND_TVMIXER) += tvmixer.o
obj-$(CONFIG_VIDEO_ZR36120) += zoran.o
@@ -27,17 +30,32 @@ obj-$(CONFIG_VIDEO_SAA5249) += saa5249.o
obj-$(CONFIG_VIDEO_CQCAM) += c-qcam.o
obj-$(CONFIG_VIDEO_BWQCAM) += bw-qcam.o
obj-$(CONFIG_VIDEO_W9966) += w9966.o
-obj-$(CONFIG_VIDEO_ZORAN_BUZ) += saa7111.o saa7185.o zr36060.o
-obj-$(CONFIG_VIDEO_ZORAN_DC10) += saa7110.o adv7175.o zr36060.o
-obj-$(CONFIG_VIDEO_ZORAN_DC30) += adv7175.o vpx3220.o zr36050.o \
- zr36016.o
-obj-$(CONFIG_VIDEO_ZORAN_LML33) += bt819.o bt856.o zr36060.o
-obj-$(CONFIG_VIDEO_ZORAN_LML33R10) += saa7114.o adv7170.o zr36060.o
-obj-$(CONFIG_VIDEO_ZORAN_AVS6EYES) += bt866.o ks0127.o zr36060.o
+
+obj-$(CONFIG_VIDEO_TDA9840) += tda9840.o
+obj-$(CONFIG_VIDEO_TEA6415C) += tea6415c.o
+obj-$(CONFIG_VIDEO_TEA6420) += tea6420.o
+obj-$(CONFIG_VIDEO_SAA7110) += saa7110.o
+obj-$(CONFIG_VIDEO_SAA7111) += saa7111.o
+obj-$(CONFIG_VIDEO_SAA7114) += saa7114.o
+obj-$(CONFIG_VIDEO_SAA711X) += saa7115.o
+obj-$(CONFIG_VIDEO_SAA7127) += saa7127.o
+obj-$(CONFIG_VIDEO_SAA7185) += saa7185.o
+obj-$(CONFIG_VIDEO_SAA7191) += saa7191.o
+obj-$(CONFIG_VIDEO_ADV7170) += adv7170.o
+obj-$(CONFIG_VIDEO_ADV7175) += adv7175.o
+obj-$(CONFIG_VIDEO_VPX3220) += vpx3220.o
+obj-$(CONFIG_VIDEO_BT819) += bt819.o
+obj-$(CONFIG_VIDEO_BT856) += bt856.o
+obj-$(CONFIG_VIDEO_BT866) += bt866.o
+obj-$(CONFIG_VIDEO_KS0127) += ks0127.o
+
obj-$(CONFIG_VIDEO_ZORAN) += zr36067.o videocodec.o
+obj-$(CONFIG_VIDEO_ZORAN_DC30) += zr36050.o zr36016.o
+obj-$(CONFIG_VIDEO_ZORAN_ZR36060) += zr36060.o
+
obj-$(CONFIG_VIDEO_PMS) += pms.o
obj-$(CONFIG_VIDEO_PLANB) += planb.o
-obj-$(CONFIG_VIDEO_VINO) += vino.o saa7191.o indycam.o
+obj-$(CONFIG_VIDEO_VINO) += vino.o indycam.o
obj-$(CONFIG_VIDEO_STRADIS) += stradis.o
obj-$(CONFIG_VIDEO_CPIA) += cpia.o
obj-$(CONFIG_VIDEO_CPIA_PP) += cpia_pp.o
@@ -46,7 +64,7 @@ obj-$(CONFIG_VIDEO_MEYE) += meye.o
obj-$(CONFIG_VIDEO_SAA7134) += ir-kbd-i2c.o saa7134/
obj-$(CONFIG_VIDEO_CX88) += cx88/
obj-$(CONFIG_VIDEO_EM28XX) += em28xx/
-obj-$(CONFIG_VIDEO_EM28XX) += tvp5150.o
+obj-$(CONFIG_VIDEO_TVP5150) += tvp5150.o
obj-$(CONFIG_VIDEO_PVRUSB2) += pvrusb2/
obj-$(CONFIG_VIDEO_MSP3400) += msp3400.o
obj-$(CONFIG_VIDEO_CS53L32A) += cs53l32a.o
@@ -55,10 +73,10 @@ obj-$(CONFIG_VIDEO_WM8775) += wm8775.o
obj-$(CONFIG_VIDEO_WM8739) += wm8739.o
obj-$(CONFIG_VIDEO_OVCAMCHIP) += ovcamchip/
obj-$(CONFIG_VIDEO_CPIA2) += cpia2/
-obj-$(CONFIG_VIDEO_MXB) += saa7111.o tda9840.o tea6415c.o tea6420.o mxb.o
+obj-$(CONFIG_VIDEO_MXB) += mxb.o
obj-$(CONFIG_VIDEO_HEXIUM_ORION) += hexium_orion.o
obj-$(CONFIG_VIDEO_HEXIUM_GEMINI) += hexium_gemini.o
-obj-$(CONFIG_VIDEO_DPC) += saa7111.o dpc7146.o
+obj-$(CONFIG_VIDEO_DPC) += dpc7146.o
obj-$(CONFIG_TUNER_3036) += tuner-3036.o
obj-$(CONFIG_VIDEO_TUNER) += tuner.o
@@ -70,8 +88,6 @@ obj-$(CONFIG_VIDEO_TVEEPROM) += tveeprom.o
obj-$(CONFIG_VIDEO_M32R_AR_M64278) += arv.o
obj-$(CONFIG_VIDEO_CX25840) += cx25840/
-obj-$(CONFIG_VIDEO_SAA711X) += saa7115.o
-obj-$(CONFIG_VIDEO_SAA7127) += saa7127.o
obj-$(CONFIG_VIDEO_UPD64031A) += upd64031a.o
obj-$(CONFIG_VIDEO_UPD64083) += upd64083.o
obj-$(CONFIG_VIDEO_CX2341X) += cx2341x.o
@@ -96,4 +112,3 @@ obj-$(CONFIG_VIDEO_VIVI) += vivi.o
EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core
extra-cflags-$(CONFIG_VIDEO_V4L1_COMPAT) += -DCONFIG_VIDEO_V4L1_COMPAT
-
diff --git a/drivers/media/video/bt866.c b/drivers/media/video/bt866.c
index 05e42bbcfc3d..772fd52d551a 100644
--- a/drivers/media/video/bt866.c
+++ b/drivers/media/video/bt866.c
@@ -65,7 +65,7 @@ MODULE_LICENSE("GPL");
struct bt866 {
struct i2c_client *i2c;
int addr;
- unsigned char reg[128];
+ unsigned char reg[256];
int norm;
int enable;
diff --git a/drivers/media/video/bt8xx/Kconfig b/drivers/media/video/bt8xx/Kconfig
index cdcf55650714..58eae887a629 100644
--- a/drivers/media/video/bt8xx/Kconfig
+++ b/drivers/media/video/bt8xx/Kconfig
@@ -8,7 +8,10 @@ config VIDEO_BT848
select VIDEO_IR
select VIDEO_TUNER
select VIDEO_TVEEPROM
- select VIDEO_MSP3400
+ select VIDEO_MSP3400 if VIDEO_HELPER_CHIPS_AUTO
+ select VIDEO_TVAUDIO if VIDEO_HELPER_CHIPS_AUTO
+ select VIDEO_TDA7432 if VIDEO_HELPER_CHIPS_AUTO
+ select VIDEO_TDA9875 if VIDEO_HELPER_CHIPS_AUTO
---help---
Support for BT848 based frame grabber/overlay boards. This includes
the Miro, Hauppauge and STB boards. Please read the material in
diff --git a/drivers/media/video/bt8xx/bttv-cards.c b/drivers/media/video/bt8xx/bttv-cards.c
index de14818d5cc4..d23a42b1504f 100644
--- a/drivers/media/video/bt8xx/bttv-cards.c
+++ b/drivers/media/video/bt8xx/bttv-cards.c
@@ -4991,7 +4991,7 @@ void __devinit bttv_check_chipset(void)
int pcipci_fail = 0;
struct pci_dev *dev = NULL;
- if (pci_pci_problems & PCIPCI_FAIL)
+ if (pci_pci_problems & (PCIPCI_FAIL|PCIAGP_FAIL)) /* should check if target is AGP */
pcipci_fail = 1;
if (pci_pci_problems & (PCIPCI_TRITON|PCIPCI_NATOMA|PCIPCI_VIAETBF))
triton1 = 1;
diff --git a/drivers/media/video/bt8xx/bttv-driver.c b/drivers/media/video/bt8xx/bttv-driver.c
index 20dff7c316eb..50dde82844ec 100644
--- a/drivers/media/video/bt8xx/bttv-driver.c
+++ b/drivers/media/video/bt8xx/bttv-driver.c
@@ -2431,6 +2431,14 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file,
fbuf->bytesperline = btv->fbuf.fmt.bytesperline;
if (fh->ovfmt)
fbuf->depth = fh->ovfmt->depth;
+ else {
+ if (fbuf->width)
+ fbuf->depth = ((fbuf->bytesperline<<3)
+ + (fbuf->width-1) )
+ /fbuf->width;
+ else
+ fbuf->depth = 0;
+ }
return 0;
}
case VIDIOCSFBUF:
@@ -4186,6 +4194,7 @@ static void __devexit bttv_remove(struct pci_dev *pci_dev)
return;
}
+#ifdef CONFIG_PM
static int bttv_suspend(struct pci_dev *pci_dev, pm_message_t state)
{
struct bttv *btv = pci_get_drvdata(pci_dev);
@@ -4266,6 +4275,7 @@ static int bttv_resume(struct pci_dev *pci_dev)
spin_unlock_irqrestore(&btv->s_lock,flags);
return 0;
}
+#endif
static struct pci_device_id bttv_pci_tbl[] = {
{PCI_VENDOR_ID_BROOKTREE, PCI_DEVICE_ID_BT848,
@@ -4286,8 +4296,10 @@ static struct pci_driver bttv_pci_driver = {
.id_table = bttv_pci_tbl,
.probe = bttv_probe,
.remove = __devexit_p(bttv_remove),
+#ifdef CONFIG_PM
.suspend = bttv_suspend,
.resume = bttv_resume,
+#endif
};
static int bttv_init_module(void)
diff --git a/drivers/media/video/bt8xx/bttv-i2c.c b/drivers/media/video/bt8xx/bttv-i2c.c
index 0dfbcc85ebb9..70de6c96e201 100644
--- a/drivers/media/video/bt8xx/bttv-i2c.c
+++ b/drivers/media/video/bt8xx/bttv-i2c.c
@@ -8,6 +8,9 @@
& Marcus Metzler (mocm@thp.uni-koeln.de)
(c) 1999-2003 Gerd Knorr <kraxel@bytesex.org>
+ (c) 2005 Mauro Carvalho Chehab <mchehab@infradead.org>
+ - Multituner support and i2c address binding
+
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
@@ -45,10 +48,18 @@ static int i2c_debug;
static int i2c_hw;
static int i2c_scan;
module_param(i2c_debug, int, 0644);
+MODULE_PARM_DESC(i2c_hw,"configure i2c debug level");
module_param(i2c_hw, int, 0444);
+MODULE_PARM_DESC(i2c_hw,"force use of hardware i2c support, "
+ "instead of software bitbang");
module_param(i2c_scan, int, 0444);
MODULE_PARM_DESC(i2c_scan,"scan i2c bus at insmod time");
+static unsigned int i2c_udelay = 5;
+module_param(i2c_udelay, int, 0444);
+MODULE_PARM_DESC(i2c_udelay,"soft i2c delay at insmod time, in usecs "
+ "(should be 5 or higher). Lower value means higher bus speed.");
+
/* ----------------------------------------------------------------------- */
/* I2C functions - bitbanging adapter (software i2c) */
@@ -425,6 +436,11 @@ int __devinit init_bttv_i2c(struct bttv *btv)
sizeof(bttv_i2c_adap_hw_template));
} else {
/* bt848 */
+ /* Prevents usage of invalid delay values */
+ if (i2c_udelay<5)
+ i2c_udelay=5;
+ bttv_i2c_algo_bit_template.udelay=i2c_udelay;
+
memcpy(&btv->c.i2c_adap, &bttv_i2c_adap_sw_template,
sizeof(bttv_i2c_adap_sw_template));
memcpy(&btv->i2c_algo, &bttv_i2c_algo_bit_template,
diff --git a/drivers/media/video/compat_ioctl32.c b/drivers/media/video/compat_ioctl32.c
index b69ee1194815..d82a488f12a6 100644
--- a/drivers/media/video/compat_ioctl32.c
+++ b/drivers/media/video/compat_ioctl32.c
@@ -58,6 +58,7 @@ static int put_video_tuner32(struct video_tuner *kp, struct video_tuner32 __user
return 0;
}
+
struct video_buffer32 {
compat_caddr_t base;
compat_int_t height, width, depth, bytesperline;
@@ -618,6 +619,7 @@ static int do_video_ioctl(struct file *file, unsigned int cmd, unsigned long arg
struct video_buffer vb;
struct video_window vw;
struct video_code vc;
+ struct video_audio va;
#endif
struct v4l2_format v2f;
struct v4l2_buffer v2b;
@@ -635,31 +637,31 @@ static int do_video_ioctl(struct file *file, unsigned int cmd, unsigned long arg
/* First, convert the command. */
switch(cmd) {
#ifdef CONFIG_VIDEO_V4L1_COMPAT
- case VIDIOCGTUNER32: cmd = VIDIOCGTUNER; break;
- case VIDIOCSTUNER32: cmd = VIDIOCSTUNER; break;
- case VIDIOCGWIN32: cmd = VIDIOCGWIN; break;
- case VIDIOCGFBUF32: cmd = VIDIOCGFBUF; break;
- case VIDIOCSFBUF32: cmd = VIDIOCSFBUF; break;
- case VIDIOCGFREQ32: cmd = VIDIOCGFREQ; break;
- case VIDIOCSFREQ32: cmd = VIDIOCSFREQ; break;
- case VIDIOCSMICROCODE32: cmd = VIDIOCSMICROCODE; break;
+ case VIDIOCGTUNER32: realcmd = cmd = VIDIOCGTUNER; break;
+ case VIDIOCSTUNER32: realcmd = cmd = VIDIOCSTUNER; break;
+ case VIDIOCGWIN32: realcmd = cmd = VIDIOCGWIN; break;
+ case VIDIOCGFBUF32: realcmd = cmd = VIDIOCGFBUF; break;
+ case VIDIOCSFBUF32: realcmd = cmd = VIDIOCSFBUF; break;
+ case VIDIOCGFREQ32: realcmd = cmd = VIDIOCGFREQ; break;
+ case VIDIOCSFREQ32: realcmd = cmd = VIDIOCSFREQ; break;
+ case VIDIOCSMICROCODE32: realcmd = cmd = VIDIOCSMICROCODE; break;
#endif
- case VIDIOC_G_FMT32: cmd = VIDIOC_G_FMT; break;
- case VIDIOC_S_FMT32: cmd = VIDIOC_S_FMT; break;
- case VIDIOC_QUERYBUF32: cmd = VIDIOC_QUERYBUF; break;
- case VIDIOC_QBUF32: cmd = VIDIOC_QBUF; break;
- case VIDIOC_DQBUF32: cmd = VIDIOC_DQBUF; break;
- case VIDIOC_STREAMON32: cmd = VIDIOC_STREAMON; break;
- case VIDIOC_STREAMOFF32: cmd = VIDIOC_STREAMOFF; break;
- case VIDIOC_G_FBUF32: cmd = VIDIOC_G_FBUF; break;
- case VIDIOC_S_FBUF32: cmd = VIDIOC_S_FBUF; break;
- case VIDIOC_OVERLAY32: cmd = VIDIOC_OVERLAY; break;
+ case VIDIOC_G_FMT32: realcmd = cmd = VIDIOC_G_FMT; break;
+ case VIDIOC_S_FMT32: realcmd = cmd = VIDIOC_S_FMT; break;
+ case VIDIOC_QUERYBUF32: realcmd = cmd = VIDIOC_QUERYBUF; break;
+ case VIDIOC_QBUF32: realcmd = cmd = VIDIOC_QBUF; break;
+ case VIDIOC_DQBUF32: realcmd = cmd = VIDIOC_DQBUF; break;
+ case VIDIOC_STREAMON32: realcmd = cmd = VIDIOC_STREAMON; break;
+ case VIDIOC_STREAMOFF32: realcmd = cmd = VIDIOC_STREAMOFF; break;
+ case VIDIOC_G_FBUF32: realcmd = cmd = VIDIOC_G_FBUF; break;
+ case VIDIOC_S_FBUF32: realcmd = cmd = VIDIOC_S_FBUF; break;
+ case VIDIOC_OVERLAY32: realcmd = cmd = VIDIOC_OVERLAY; break;
case VIDIOC_ENUMSTD32: realcmd = VIDIOC_ENUMSTD; break;
case VIDIOC_ENUMINPUT32: realcmd = VIDIOC_ENUMINPUT; break;
- case VIDIOC_S_CTRL32: cmd = VIDIOC_S_CTRL; break;
- case VIDIOC_G_INPUT32: cmd = VIDIOC_G_INPUT; break;
- case VIDIOC_S_INPUT32: cmd = VIDIOC_S_INPUT; break;
- case VIDIOC_TRY_FMT32: cmd = VIDIOC_TRY_FMT; break;
+ case VIDIOC_S_CTRL32: realcmd = cmd = VIDIOC_S_CTRL; break;
+ case VIDIOC_G_INPUT32: realcmd = cmd = VIDIOC_G_INPUT; break;
+ case VIDIOC_S_INPUT32: realcmd = cmd = VIDIOC_S_INPUT; break;
+ case VIDIOC_TRY_FMT32: realcmd = cmd = VIDIOC_TRY_FMT; break;
};
switch(cmd) {
@@ -676,6 +678,7 @@ static int do_video_ioctl(struct file *file, unsigned int cmd, unsigned long arg
compatible_arg = 0;
break;
+
case VIDIOCSFREQ:
#endif
case VIDIOC_S_INPUT:
@@ -683,7 +686,7 @@ static int do_video_ioctl(struct file *file, unsigned int cmd, unsigned long arg
case VIDIOC_STREAMON:
case VIDIOC_STREAMOFF:
err = get_user(karg.vx, (u32 __user *)up);
- compatible_arg = 0;
+ compatible_arg = 1;
break;
case VIDIOC_S_FBUF:
@@ -739,6 +742,7 @@ static int do_video_ioctl(struct file *file, unsigned int cmd, unsigned long arg
case VIDIOC_G_FBUF:
case VIDIOC_G_INPUT:
compatible_arg = 0;
+ break;
#ifdef CONFIG_VIDEO_V4L1_COMPAT
case VIDIOCSMICROCODE:
err = microcode32(&karg.vc, up);
@@ -755,7 +759,7 @@ static int do_video_ioctl(struct file *file, unsigned int cmd, unsigned long arg
mm_segment_t old_fs = get_fs();
set_fs(KERNEL_DS);
- err = native_ioctl(file, realcmd, (unsigned long)&karg);
+ err = native_ioctl(file, realcmd, (unsigned long) &karg);
set_fs(old_fs);
}
if(err == 0) {
@@ -772,6 +776,7 @@ static int do_video_ioctl(struct file *file, unsigned int cmd, unsigned long arg
case VIDIOCGFBUF:
err = put_video_buffer32(&karg.vb, up);
break;
+
#endif
case VIDIOC_G_FBUF:
err = put_v4l2_framebuffer32(&karg.v2fb, up);
@@ -841,10 +846,14 @@ long v4l_compat_ioctl32(struct file *file, unsigned int cmd, unsigned long arg)
case VIDIOCSFBUF32:
case VIDIOCGFREQ32:
case VIDIOCSFREQ32:
+ case VIDIOCGAUDIO:
+ case VIDIOCSAUDIO:
#endif
case VIDIOC_QUERYCAP:
case VIDIOC_ENUM_FMT:
case VIDIOC_G_FMT32:
+ case VIDIOC_CROPCAP:
+ case VIDIOC_S_CROP:
case VIDIOC_S_FMT32:
case VIDIOC_REQBUFS:
case VIDIOC_QUERYBUF32:
@@ -882,8 +891,6 @@ long v4l_compat_ioctl32(struct file *file, unsigned int cmd, unsigned long arg)
case VIDIOCSPICT:
case VIDIOCCAPTURE:
case VIDIOCKEY:
- case VIDIOCGAUDIO:
- case VIDIOCSAUDIO:
case VIDIOCSYNC:
case VIDIOCMCAPTURE:
case VIDIOCGMBUF:
diff --git a/drivers/media/video/cpia2/cpia2.h b/drivers/media/video/cpia2/cpia2.h
index c5ecb2be5f93..8d2dfc128821 100644
--- a/drivers/media/video/cpia2/cpia2.h
+++ b/drivers/media/video/cpia2/cpia2.h
@@ -50,10 +50,6 @@
/***
* Image defines
***/
-#ifndef true
-#define true 1
-#define false 0
-#endif
/* Misc constants */
#define ALLOW_CORRUPT 0 /* Causes collater to discard checksum */
diff --git a/drivers/media/video/cx2341x.c b/drivers/media/video/cx2341x.c
index 65f00fc08fa9..657e0b969145 100644
--- a/drivers/media/video/cx2341x.c
+++ b/drivers/media/video/cx2341x.c
@@ -691,7 +691,7 @@ void cx2341x_fill_defaults(struct cx2341x_mpeg_params *p)
.video_luma_spatial_filter_type = V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_1D_HOR,
.video_chroma_spatial_filter_type = V4L2_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE_1D_HOR,
.video_temporal_filter_mode = V4L2_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE_MANUAL,
- .video_temporal_filter = 0,
+ .video_temporal_filter = 8,
.video_median_filter_type = V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_OFF,
.video_luma_median_filter_top = 255,
.video_luma_median_filter_bottom = 0,
@@ -731,6 +731,7 @@ int cx2341x_update(void *priv, cx2341x_mbox_func func,
};
int err = 0;
+ u16 temporal = new->video_temporal_filter;
cx2341x_api(priv, func, CX2341X_ENC_SET_OUTPUT_PORT, 2, new->port, 0);
@@ -741,6 +742,7 @@ int cx2341x_update(void *priv, cx2341x_mbox_func func,
if (old == NULL || old->width != new->width || old->height != new->height ||
old->video_encoding != new->video_encoding) {
+ int is_scaling;
u16 w = new->width;
u16 h = new->height;
@@ -750,6 +752,20 @@ int cx2341x_update(void *priv, cx2341x_mbox_func func,
}
err = cx2341x_api(priv, func, CX2341X_ENC_SET_FRAME_SIZE, 2, h, w);
if (err) return err;
+
+ /* Adjust temporal filter if necessary. The problem with the temporal
+ filter is that it works well with full resolution capturing, but
+ not when the capture window is scaled (the filter introduces
+ a ghosting effect). So if the capture window changed, and there is
+ no updated filter value, then the filter is set depending on whether
+ the new window is full resolution or not.
+
+ For full resolution a setting of 8 really improves the video
+ quality, especially if the original video quality is suboptimal. */
+ is_scaling = new->width != 720 || new->height != (new->is_50hz ? 576 : 480);
+ if (old && old->video_temporal_filter == temporal) {
+ temporal = is_scaling ? 0 : 8;
+ }
}
if (old == NULL || old->stream_type != new->stream_type) {
@@ -815,9 +831,9 @@ int cx2341x_update(void *priv, cx2341x_mbox_func func,
}
if (old == NULL ||
old->video_spatial_filter != new->video_spatial_filter ||
- old->video_temporal_filter != new->video_temporal_filter) {
+ old->video_temporal_filter != temporal) {
err = cx2341x_api(priv, func, CX2341X_ENC_SET_DNR_FILTER_PROPS, 2,
- new->video_spatial_filter, new->video_temporal_filter);
+ new->video_spatial_filter, temporal);
if (err) return err;
}
if (old == NULL || old->video_temporal_decimation != new->video_temporal_decimation) {
@@ -855,6 +871,9 @@ void cx2341x_log_status(struct cx2341x_mpeg_params *p, const char *prefix)
printk(KERN_INFO "%s: Stream: %s\n",
prefix,
cx2341x_menu_item(p, V4L2_CID_MPEG_STREAM_TYPE));
+ printk(KERN_INFO "%s: VBI Format: %s\n",
+ prefix,
+ cx2341x_menu_item(p, V4L2_CID_MPEG_STREAM_VBI_FMT));
/* Video */
printk(KERN_INFO "%s: Video: %dx%d, %d fps\n",
diff --git a/drivers/media/video/cx25840/Kconfig b/drivers/media/video/cx25840/Kconfig
index 854264e42ec0..7cf29a03ed63 100644
--- a/drivers/media/video/cx25840/Kconfig
+++ b/drivers/media/video/cx25840/Kconfig
@@ -1,6 +1,6 @@
config VIDEO_CX25840
tristate "Conexant CX2584x audio/video decoders"
- depends on VIDEO_DEV && I2C && EXPERIMENTAL
+ depends on VIDEO_V4L2 && I2C && EXPERIMENTAL
select FW_LOADER
---help---
Support for the Conexant CX2584x audio/video decoders.
diff --git a/drivers/media/video/cx25840/cx25840-vbi.c b/drivers/media/video/cx25840/cx25840-vbi.c
index 6cc8bf215e85..48014a254e15 100644
--- a/drivers/media/video/cx25840/cx25840-vbi.c
+++ b/drivers/media/video/cx25840/cx25840-vbi.c
@@ -111,6 +111,10 @@ void cx25840_vbi_setup(struct i2c_client *client)
uv_lpf=0;
comb=0;
sc=0x0a425f;
+ } else if (std == V4L2_STD_PAL_Nc) {
+ uv_lpf=1;
+ comb=0x20;
+ sc=556453;
} else {
uv_lpf=1;
comb=0x20;
diff --git a/drivers/media/video/cx88/Kconfig b/drivers/media/video/cx88/Kconfig
index 7a94e6a11927..51d68f32aa06 100644
--- a/drivers/media/video/cx88/Kconfig
+++ b/drivers/media/video/cx88/Kconfig
@@ -1,7 +1,3 @@
-config VIDEO_CX88_VP3054
- tristate
- depends on VIDEO_CX88_DVB && DVB_MT352
-
config VIDEO_CX88
tristate "Conexant 2388x (bt878 successor) support"
depends on VIDEO_DEV && PCI && I2C
@@ -52,6 +48,14 @@ config VIDEO_CX88_DVB
depends on VIDEO_CX88 && DVB_CORE
select VIDEO_BUF_DVB
select DVB_PLL
+ select DVB_MT352 if !DVB_FE_CUSTOMISE
+ select DVB_ZL10353 if !DVB_FE_CUSTOMISE
+ select DVB_OR51132 if !DVB_FE_CUSTOMISE
+ select DVB_CX22702 if !DVB_FE_CUSTOMISE
+ select DVB_LGDT330X if !DVB_FE_CUSTOMISE
+ select DVB_NXT200X if !DVB_FE_CUSTOMISE
+ select DVB_CX24123 if !DVB_FE_CUSTOMISE
+ select DVB_ISL6421 if !DVB_FE_CUSTOMISE
---help---
This adds support for DVB/ATSC cards based on the
Conexant 2388x chip.
@@ -59,101 +63,12 @@ config VIDEO_CX88_DVB
To compile this driver as a module, choose M here: the
module will be called cx88-dvb.
- You must also select one or more DVB/ATSC demodulators.
- If you are unsure which you need, choose all of them.
-
-config VIDEO_CX88_DVB_ALL_FRONTENDS
- bool "Build all supported frontends for cx2388x based TV cards"
- default y
- depends on VIDEO_CX88_DVB
- select DVB_MT352
- select VIDEO_CX88_VP3054
- select DVB_ZL10353
- select DVB_OR51132
- select DVB_CX22702
- select DVB_LGDT330X
- select DVB_NXT200X
- select DVB_CX24123
- select DVB_ISL6421
- ---help---
- This builds cx88-dvb with all currently supported frontend
- demodulators. If you wish to tweak your configuration, and
- only include support for the hardware that you need, choose N here.
-
- If you are unsure, choose Y.
-
-config VIDEO_CX88_DVB_MT352
- bool "Zarlink MT352 DVB-T Support"
- default y
- depends on VIDEO_CX88_DVB && !VIDEO_CX88_DVB_ALL_FRONTENDS
- select DVB_MT352
- ---help---
- This adds DVB-T support for cards based on the
- Connexant 2388x chip and the MT352 demodulator.
-
-config VIDEO_CX88_DVB_VP3054
- bool "VP-3054 Secondary I2C Bus Support"
- default y
- depends on VIDEO_CX88_DVB_MT352
- select VIDEO_CX88_VP3054
+config VIDEO_CX88_VP3054
+ tristate "VP-3054 Secondary I2C Bus Support"
+ default m
+ depends on VIDEO_CX88_DVB && DVB_MT352
---help---
This adds DVB-T support for cards based on the
Connexant 2388x chip and the MT352 demodulator,
which also require support for the VP-3054
Secondary I2C bus, such at DNTV Live! DVB-T Pro.
-
-config VIDEO_CX88_DVB_ZL10353
- bool "Zarlink ZL10353 DVB-T Support"
- default y
- depends on VIDEO_CX88_DVB && !VIDEO_CX88_DVB_ALL_FRONTENDS
- select DVB_ZL10353
- ---help---
- This adds DVB-T support for cards based on the
- Connexant 2388x chip and the ZL10353 demodulator,
- successor to the Zarlink MT352.
-
-config VIDEO_CX88_DVB_OR51132
- bool "OR51132 ATSC Support"
- default y
- depends on VIDEO_CX88_DVB && !VIDEO_CX88_DVB_ALL_FRONTENDS
- select DVB_OR51132
- ---help---
- This adds ATSC 8VSB and QAM64/256 support for cards based on the
- Connexant 2388x chip and the OR51132 demodulator.
-
-config VIDEO_CX88_DVB_CX22702
- bool "Conexant CX22702 DVB-T Support"
- default y
- depends on VIDEO_CX88_DVB && !VIDEO_CX88_DVB_ALL_FRONTENDS
- select DVB_CX22702
- ---help---
- This adds DVB-T support for cards based on the
- Connexant 2388x chip and the CX22702 demodulator.
-
-config VIDEO_CX88_DVB_LGDT330X
- bool "LG Electronics DT3302/DT3303 ATSC Support"
- default y
- depends on VIDEO_CX88_DVB && !VIDEO_CX88_DVB_ALL_FRONTENDS
- select DVB_LGDT330X
- ---help---
- This adds ATSC 8VSB and QAM64/256 support for cards based on the
- Connexant 2388x chip and the LGDT3302/LGDT3303 demodulator.
-
-config VIDEO_CX88_DVB_NXT200X
- bool "NXT2002/NXT2004 ATSC Support"
- default y
- depends on VIDEO_CX88_DVB && !VIDEO_CX88_DVB_ALL_FRONTENDS
- select DVB_NXT200X
- ---help---
- This adds ATSC 8VSB and QAM64/256 support for cards based on the
- Connexant 2388x chip and the NXT2002/NXT2004 demodulator.
-
-config VIDEO_CX88_DVB_CX24123
- bool "Conexant CX24123 DVB-S Support"
- default y
- depends on VIDEO_CX88_DVB && !VIDEO_CX88_DVB_ALL_FRONTENDS
- select DVB_CX24123
- select DVB_ISL6421
- ---help---
- This adds DVB-S support for cards based on the
- Connexant 2388x chip and the CX24123 demodulator.
diff --git a/drivers/media/video/cx88/Makefile b/drivers/media/video/cx88/Makefile
index 352b919f30c4..639c3b659d0e 100644
--- a/drivers/media/video/cx88/Makefile
+++ b/drivers/media/video/cx88/Makefile
@@ -14,13 +14,6 @@ EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core
EXTRA_CFLAGS += -Idrivers/media/dvb/frontends
extra-cflags-$(CONFIG_VIDEO_BUF_DVB) += -DHAVE_VIDEO_BUF_DVB=1
-extra-cflags-$(CONFIG_DVB_CX22702) += -DHAVE_CX22702=1
-extra-cflags-$(CONFIG_DVB_OR51132) += -DHAVE_OR51132=1
-extra-cflags-$(CONFIG_DVB_LGDT330X) += -DHAVE_LGDT330X=1
-extra-cflags-$(CONFIG_DVB_MT352) += -DHAVE_MT352=1
-extra-cflags-$(CONFIG_DVB_ZL10353) += -DHAVE_ZL10353=1
-extra-cflags-$(CONFIG_DVB_NXT200X) += -DHAVE_NXT200X=1
-extra-cflags-$(CONFIG_DVB_CX24123) += -DHAVE_CX24123=1
extra-cflags-$(CONFIG_VIDEO_CX88_VP3054)+= -DHAVE_VP3054_I2C=1
EXTRA_CFLAGS += $(extra-cflags-y) $(extra-cflags-m)
diff --git a/drivers/media/video/cx88/cx88-blackbird.c b/drivers/media/video/cx88/cx88-blackbird.c
index b60177f173c3..a7921f9d45d8 100644
--- a/drivers/media/video/cx88/cx88-blackbird.c
+++ b/drivers/media/video/cx88/cx88-blackbird.c
@@ -1160,8 +1160,10 @@ static struct pci_driver blackbird_pci_driver = {
.id_table = cx8802_pci_tbl,
.probe = blackbird_probe,
.remove = __devexit_p(blackbird_remove),
+#ifdef CONFIG_PM
.suspend = cx8802_suspend_common,
.resume = cx8802_resume_common,
+#endif
};
static int blackbird_init(void)
diff --git a/drivers/media/video/cx88/cx88-cards.c b/drivers/media/video/cx88/cx88-cards.c
index 14bd4863d157..6214eb823b29 100644
--- a/drivers/media/video/cx88/cx88-cards.c
+++ b/drivers/media/video/cx88/cx88-cards.c
@@ -1041,11 +1041,11 @@ struct cx88_board cx88_boards[] = {
.input = {{
.type = CX88_VMUX_COMPOSITE1,
.vmux = 1,
- .gpio0 = 0x000027df,
+ .gpio0 = 0x000067df,
},{
.type = CX88_VMUX_SVIDEO,
.vmux = 2,
- .gpio0 = 0x000027df,
+ .gpio0 = 0x000067df,
}},
.dvb = 1,
},
@@ -1209,6 +1209,100 @@ struct cx88_board cx88_boards[] = {
}},
.dvb = 1,
},
+ [CX88_BOARD_HAUPPAUGE_HVR3000] = {
+ /* FIXME: Add dvb & radio support */
+ .name = "Hauppauge WinTV-HVR3000 TriMode Analog/DVB-S/DVB-T",
+ .tuner_type = TUNER_PHILIPS_FMD1216ME_MK3,
+ .radio_type = UNSET,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ .tda9887_conf = TDA9887_PRESENT,
+ .input = {{
+ .type = CX88_VMUX_TELEVISION,
+ .vmux = 0,
+ .gpio0 = 0x84bf,
+ },{
+ .type = CX88_VMUX_COMPOSITE1,
+ .vmux = 1,
+ .gpio0 = 0x84bf,
+ },{
+ .type = CX88_VMUX_SVIDEO,
+ .vmux = 2,
+ .gpio0 = 0x84bf,
+ }},
+ },
+ [CX88_BOARD_NORWOOD_MICRO] = {
+ .name = "Norwood Micro TV Tuner",
+ .tuner_type = TUNER_TNF_5335MF,
+ .radio_type = UNSET,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ .input = {{
+ .type = CX88_VMUX_TELEVISION,
+ .vmux = 0,
+ .gpio0 = 0x0709,
+ },{
+ .type = CX88_VMUX_COMPOSITE1,
+ .vmux = 1,
+ .gpio0 = 0x070b,
+ },{
+ .type = CX88_VMUX_SVIDEO,
+ .vmux = 2,
+ .gpio0 = 0x070b,
+ }},
+ },
+ [CX88_BOARD_TE_DTV_250_OEM_SWANN] = {
+ .name = "Shenzhen Tungsten Ages Tech TE-DTV-250 / Swann OEM",
+ .tuner_type = TUNER_LG_PAL_NEW_TAPC,
+ .radio_type = UNSET,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ .input = {{
+ .type = CX88_VMUX_TELEVISION,
+ .vmux = 0,
+ .gpio0 = 0x003fffff,
+ .gpio1 = 0x00e00000,
+ .gpio2 = 0x003fffff,
+ .gpio3 = 0x02000000,
+ },{
+ .type = CX88_VMUX_COMPOSITE1,
+ .vmux = 1,
+ .gpio0 = 0x003fffff,
+ .gpio1 = 0x00e00000,
+ .gpio2 = 0x003fffff,
+ .gpio3 = 0x02000000,
+ },{
+ .type = CX88_VMUX_SVIDEO,
+ .vmux = 2,
+ .gpio0 = 0x003fffff,
+ .gpio1 = 0x00e00000,
+ .gpio2 = 0x003fffff,
+ .gpio3 = 0x02000000,
+ }},
+ },
+ [CX88_BOARD_HAUPPAUGE_HVR1300] = {
+ .name = "Hauppauge WinTV-HVR1300 DVB-T/Hybrid MPEG Encoder",
+ .tuner_type = TUNER_PHILIPS_FMD1216ME_MK3,
+ .radio_type = UNSET,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ .tda9887_conf = TDA9887_PRESENT,
+ .input = {{
+ .type = CX88_VMUX_TELEVISION,
+ .vmux = 0,
+ .gpio0 = 0xe780,
+ },{
+ .type = CX88_VMUX_COMPOSITE1,
+ .vmux = 1,
+ .gpio0 = 0xe780,
+ },{
+ .type = CX88_VMUX_SVIDEO,
+ .vmux = 2,
+ .gpio0 = 0xe780,
+ }},
+ /* fixme: Add radio support */
+ .dvb = 1,
+ },
};
const unsigned int cx88_bcount = ARRAY_SIZE(cx88_boards);
@@ -1254,7 +1348,7 @@ struct cx88_subid cx88_subids[] = {
.card = CX88_BOARD_LEADTEK_PVR2000,
},{
.subvendor = 0x107d,
- .subdevice = 0x663C,
+ .subdevice = 0x663c,
.card = CX88_BOARD_LEADTEK_PVR2000,
},{
.subvendor = 0x1461,
@@ -1458,6 +1552,35 @@ struct cx88_subid cx88_subids[] = {
.subvendor = 0x14f1,
.subdevice = 0x0084,
.card = CX88_BOARD_GENIATECH_DVBS,
+ },{
+ .subvendor = 0x0070,
+ .subdevice = 0x1404,
+ .card = CX88_BOARD_HAUPPAUGE_HVR3000,
+ },{
+ .subvendor = 0x1461,
+ .subdevice = 0xc111, /* AverMedia M150-D */
+ /* This board is known to work with the ASUS PVR416 config */
+ .card = CX88_BOARD_ASUS_PVR_416,
+ },{
+ .subvendor = 0xc180,
+ .subdevice = 0xc980,
+ .card = CX88_BOARD_TE_DTV_250_OEM_SWANN,
+ },{
+ .subvendor = 0x0070,
+ .subdevice = 0x9600,
+ .card = CX88_BOARD_HAUPPAUGE_HVR1300,
+ },{
+ .subvendor = 0x0070,
+ .subdevice = 0x9601,
+ .card = CX88_BOARD_HAUPPAUGE_HVR1300,
+ },{
+ .subvendor = 0x0070,
+ .subdevice = 0x9602,
+ .card = CX88_BOARD_HAUPPAUGE_HVR1300,
+ },{
+ .subvendor = 0x107d,
+ .subdevice = 0x6632,
+ .card = CX88_BOARD_LEADTEK_PVR2000,
},
};
const unsigned int cx88_idcount = ARRAY_SIZE(cx88_subids);
@@ -1501,6 +1624,7 @@ static void hauppauge_eeprom(struct cx88_core *core, u8 *eeprom_data)
/* Make sure we support the board model */
switch (tv.model)
{
+ case 14569: /* WinTV-HVR3000 (OEM, no IR, no back panel video) */
case 28552: /* WinTV-PVR 'Roslyn' (No IR) */
case 34519: /* WinTV-PCI-FM */
case 90002: /* Nova-T-PCI (9002) */
@@ -1512,6 +1636,11 @@ static void hauppauge_eeprom(struct cx88_core *core, u8 *eeprom_data)
case 92000: /* Nova-SE2 (OEM, No Video or IR) */
case 94009: /* WinTV-HVR1100 (Video and IR Retail) */
case 94501: /* WinTV-HVR1100 (Video and IR OEM) */
+ case 96009: /* WinTV-HVR1300 (PAL Video, MPEG Video and IR RX) */
+ case 96019: /* WinTV-HVR1300 (PAL Video, MPEG Video and IR RX/TX) */
+ case 96559: /* WinTV-HVR1300 (PAL Video, MPEG Video no IR) */
+ case 96569: /* WinTV-HVR1300 () */
+ case 96659: /* WinTV-HVR1300 () */
case 98559: /* WinTV-HVR1100LP (Video no IR, Retail - Low Profile) */
/* known */
break;
@@ -1638,6 +1767,22 @@ void cx88_card_list(struct cx88_core *core, struct pci_dev *pci)
core->name, i, cx88_boards[i].name);
}
+void cx88_card_setup_pre_i2c(struct cx88_core *core)
+{
+ switch (core->board) {
+ case CX88_BOARD_HAUPPAUGE_HVR1300:
+ /* Bring the 702 demod up before i2c scanning/attach or devices are hidden */
+ /* We leave here with the 702 on the bus */
+ cx_write(MO_GP0_IO, 0x0000e780);
+ udelay(1000);
+ cx_clear(MO_GP0_IO, 0x00000080);
+ udelay(50);
+ cx_set(MO_GP0_IO, 0x00000080); /* 702 out of reset */
+ udelay(1000);
+ break;
+ }
+}
+
void cx88_card_setup(struct cx88_core *core)
{
static u8 eeprom[256];
@@ -1666,6 +1811,8 @@ void cx88_card_setup(struct cx88_core *core)
case CX88_BOARD_HAUPPAUGE_DVB_T1:
case CX88_BOARD_HAUPPAUGE_HVR1100:
case CX88_BOARD_HAUPPAUGE_HVR1100LP:
+ case CX88_BOARD_HAUPPAUGE_HVR3000:
+ case CX88_BOARD_HAUPPAUGE_HVR1300:
if (0 == core->i2c_rc)
hauppauge_eeprom(core,eeprom);
break;
@@ -1673,9 +1820,15 @@ void cx88_card_setup(struct cx88_core *core)
cx_write(MO_GP0_IO, 0x000007f8);
cx_write(MO_GP1_IO, 0x00000001);
break;
+ case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL:
+ /* GPIO0:6 is hooked to FX2 reset pin */
+ cx_set(MO_GP0_IO, 0x00004040);
+ cx_clear(MO_GP0_IO, 0x00000040);
+ msleep(1000);
+ cx_set(MO_GP0_IO, 0x00004040);
+ /* FALLTHROUGH */
case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T1:
case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PLUS:
- case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL:
case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_HYBRID:
/* GPIO0:0 is hooked to mt352 reset pin */
cx_set(MO_GP0_IO, 0x00000101);
diff --git a/drivers/media/video/cx88/cx88-core.c b/drivers/media/video/cx88/cx88-core.c
index 973d3f39b2d5..f379ede3049a 100644
--- a/drivers/media/video/cx88/cx88-core.c
+++ b/drivers/media/video/cx88/cx88-core.c
@@ -105,7 +105,7 @@ static u32* cx88_risc_field(u32 *rp, struct scatterlist *sglist,
*(rp++)=cpu_to_le32(sg_dma_address(sg)+offset);
offset+=bpl;
} else {
- /* scanline needs to be splitted */
+ /* scanline needs to be split */
todo = bpl;
*(rp++)=cpu_to_le32(RISC_WRITE|RISC_SOL|
(sg_dma_len(sg)-offset));
@@ -792,6 +792,11 @@ int cx88_start_audio_dma(struct cx88_core *core)
{
/* constant 128 made buzz in analog Nicam-stereo for bigger fifo_size */
int bpl = cx88_sram_channels[SRAM_CH25].fifo_size/4;
+
+ /* If downstream RISC is enabled, bail out; ALSA is managing DMA */
+ if (cx_read(MO_AUD_DMACNTRL) & 0x10)
+ return 0;
+
/* setup fifo + format */
cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH25], bpl, 0);
cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH26], bpl, 0);
@@ -801,11 +806,16 @@ int cx88_start_audio_dma(struct cx88_core *core)
/* start dma */
cx_write(MO_AUD_DMACNTRL, 0x0003); /* Up and Down fifo enable */
+
return 0;
}
int cx88_stop_audio_dma(struct cx88_core *core)
{
+ /* If downstream RISC is enabled, bail out; ALSA is managing DMA */
+ if (cx_read(MO_AUD_DMACNTRL) & 0x10)
+ return 0;
+
/* stop dma */
cx_write(MO_AUD_DMACNTRL, 0x0000);
@@ -1123,6 +1133,7 @@ struct cx88_core* cx88_core_get(struct pci_dev *pci)
/* init hardware */
cx88_reset(core);
+ cx88_card_setup_pre_i2c(core);
cx88_i2c_init(core,pci);
cx88_call_i2c_clients (core, TUNER_SET_STANDBY, NULL);
cx88_card_setup(core);
diff --git a/drivers/media/video/cx88/cx88-dvb.c b/drivers/media/video/cx88/cx88-dvb.c
index afde3789d702..c87041dee21e 100644
--- a/drivers/media/video/cx88/cx88-dvb.c
+++ b/drivers/media/video/cx88/cx88-dvb.c
@@ -33,32 +33,18 @@
#include "dvb-pll.h"
#include <media/v4l2-common.h>
-#ifdef HAVE_MT352
-# include "mt352.h"
-# include "mt352_priv.h"
-# ifdef HAVE_VP3054_I2C
-# include "cx88-vp3054-i2c.h"
-# endif
-#endif
-#ifdef HAVE_ZL10353
-# include "zl10353.h"
-#endif
-#ifdef HAVE_CX22702
-# include "cx22702.h"
-#endif
-#ifdef HAVE_OR51132
-# include "or51132.h"
-#endif
-#ifdef HAVE_LGDT330X
-# include "lgdt330x.h"
-# include "lg_h06xf.h"
-#endif
-#ifdef HAVE_NXT200X
-# include "nxt200x.h"
-#endif
-#ifdef HAVE_CX24123
-# include "cx24123.h"
+#include "mt352.h"
+#include "mt352_priv.h"
+#ifdef HAVE_VP3054_I2C
+# include "cx88-vp3054-i2c.h"
#endif
+#include "zl10353.h"
+#include "cx22702.h"
+#include "or51132.h"
+#include "lgdt330x.h"
+#include "lg_h06xf.h"
+#include "nxt200x.h"
+#include "cx24123.h"
#include "isl6421.h"
MODULE_DESCRIPTION("driver for cx2388x based DVB cards");
@@ -114,8 +100,6 @@ static struct videobuf_queue_ops dvb_qops = {
};
/* ------------------------------------------------------------------ */
-
-#ifdef HAVE_MT352
static int dvico_fusionhdtv_demod_init(struct dvb_frontend* fe)
{
static u8 clock_config [] = { CLOCK_CTL, 0x38, 0x39 };
@@ -181,7 +165,7 @@ static int dntv_live_dvbt_demod_init(struct dvb_frontend* fe)
}
static struct mt352_config dvico_fusionhdtv = {
- .demod_address = 0x0F,
+ .demod_address = 0x0f,
.demod_init = dvico_fusionhdtv_demod_init,
};
@@ -191,7 +175,7 @@ static struct mt352_config dntv_live_dvbt_config = {
};
static struct mt352_config dvico_fusionhdtv_dual = {
- .demod_address = 0x0F,
+ .demod_address = 0x0f,
.demod_init = dvico_dual_demod_init,
};
@@ -266,8 +250,8 @@ static int dntv_live_dvbt_pro_tuner_set_params(struct dvb_frontend* fe,
if ((err = i2c_transfer(&dev->core->i2c_adap, &msg, 1)) != 1) {
printk(KERN_WARNING "cx88-dvb: %s error "
- "(addr %02x <- %02x, err = %i)\n",
- __FUNCTION__, dev->core->pll_addr, buf[0], err);
+ "(addr %02x <- %02x, err = %i)\n",
+ __FUNCTION__, dev->core->pll_addr, buf[0], err);
if (err < 0)
return err;
else
@@ -283,9 +267,7 @@ static struct mt352_config dntv_live_dvbt_pro_config = {
.demod_init = dntv_live_dvbt_pro_demod_init,
};
#endif
-#endif
-#ifdef HAVE_ZL10353
static int dvico_hybrid_tuner_set_params(struct dvb_frontend *fe,
struct dvb_frontend_parameters *params)
{
@@ -304,8 +286,8 @@ static int dvico_hybrid_tuner_set_params(struct dvb_frontend *fe,
fe->ops.i2c_gate_ctrl(fe, 1);
if ((err = i2c_transfer(&dev->core->i2c_adap, &msg, 1)) != 1) {
printk(KERN_WARNING "cx88-dvb: %s error "
- "(addr %02x <- %02x, err = %i)\n",
- __FUNCTION__, pllbuf[0], pllbuf[1], err);
+ "(addr %02x <- %02x, err = %i)\n",
+ __FUNCTION__, pllbuf[0], pllbuf[1], err);
if (err < 0)
return err;
else
@@ -316,16 +298,14 @@ static int dvico_hybrid_tuner_set_params(struct dvb_frontend *fe,
}
static struct zl10353_config dvico_fusionhdtv_hybrid = {
- .demod_address = 0x0F,
+ .demod_address = 0x0f,
.no_tuner = 1,
};
static struct zl10353_config dvico_fusionhdtv_plus_v1_1 = {
- .demod_address = 0x0F,
+ .demod_address = 0x0f,
};
-#endif
-#ifdef HAVE_CX22702
static struct cx22702_config connexant_refboard_config = {
.demod_address = 0x43,
.output_mode = CX22702_SERIAL_OUTPUT,
@@ -339,9 +319,11 @@ static struct cx22702_config hauppauge_hvr1100_config = {
.demod_address = 0x63,
.output_mode = CX22702_SERIAL_OUTPUT,
};
-#endif
+static struct cx22702_config hauppauge_hvr1300_config = {
+ .demod_address = 0x63,
+ .output_mode = CX22702_SERIAL_OUTPUT,
+};
-#ifdef HAVE_OR51132
static int or51132_set_ts_param(struct dvb_frontend* fe,
int is_punctured)
{
@@ -351,12 +333,10 @@ static int or51132_set_ts_param(struct dvb_frontend* fe,
}
static struct or51132_config pchdtv_hd3000 = {
- .demod_address = 0x15,
- .set_ts_params = or51132_set_ts_param,
+ .demod_address = 0x15,
+ .set_ts_params = or51132_set_ts_param,
};
-#endif
-#ifdef HAVE_LGDT330X
static int lgdt3302_tuner_set_params(struct dvb_frontend* fe,
struct dvb_frontend_parameters* params)
{
@@ -373,14 +353,14 @@ static int lgdt3302_tuner_set_params(struct dvb_frontend* fe,
dvb_pll_configure(core->pll_desc, buf, params->frequency, 0);
dprintk(1, "%s: tuner at 0x%02x bytes: 0x%02x 0x%02x 0x%02x 0x%02x\n",
- __FUNCTION__, msg.addr, buf[0],buf[1],buf[2],buf[3]);
+ __FUNCTION__, msg.addr, buf[0],buf[1],buf[2],buf[3]);
if (fe->ops.i2c_gate_ctrl)
fe->ops.i2c_gate_ctrl(fe, 1);
if ((err = i2c_transfer(&core->i2c_adap, &msg, 1)) != 1) {
printk(KERN_WARNING "cx88-dvb: %s error "
- "(addr %02x <- %02x, err = %i)\n",
- __FUNCTION__, buf[0], buf[1], err);
+ "(addr %02x <- %02x, err = %i)\n",
+ __FUNCTION__, buf[0], buf[1], err);
if (err < 0)
return err;
else
@@ -425,28 +405,26 @@ static int lgdt330x_set_ts_param(struct dvb_frontend* fe, int is_punctured)
}
static struct lgdt330x_config fusionhdtv_3_gold = {
- .demod_address = 0x0e,
- .demod_chip = LGDT3302,
- .serial_mpeg = 0x04, /* TPSERIAL for 3302 in TOP_CONTROL */
- .set_ts_params = lgdt330x_set_ts_param,
+ .demod_address = 0x0e,
+ .demod_chip = LGDT3302,
+ .serial_mpeg = 0x04, /* TPSERIAL for 3302 in TOP_CONTROL */
+ .set_ts_params = lgdt330x_set_ts_param,
};
static struct lgdt330x_config fusionhdtv_5_gold = {
- .demod_address = 0x0e,
- .demod_chip = LGDT3303,
- .serial_mpeg = 0x40, /* TPSERIAL for 3303 in TOP_CONTROL */
- .set_ts_params = lgdt330x_set_ts_param,
+ .demod_address = 0x0e,
+ .demod_chip = LGDT3303,
+ .serial_mpeg = 0x40, /* TPSERIAL for 3303 in TOP_CONTROL */
+ .set_ts_params = lgdt330x_set_ts_param,
};
static struct lgdt330x_config pchdtv_hd5500 = {
- .demod_address = 0x59,
- .demod_chip = LGDT3303,
- .serial_mpeg = 0x40, /* TPSERIAL for 3303 in TOP_CONTROL */
- .set_ts_params = lgdt330x_set_ts_param,
+ .demod_address = 0x59,
+ .demod_chip = LGDT3303,
+ .serial_mpeg = 0x40, /* TPSERIAL for 3303 in TOP_CONTROL */
+ .set_ts_params = lgdt330x_set_ts_param,
};
-#endif
-#ifdef HAVE_NXT200X
static int nxt200x_set_ts_param(struct dvb_frontend* fe,
int is_punctured)
{
@@ -465,28 +443,27 @@ static int nxt200x_set_pll_input(u8* buf, int input)
}
static struct nxt200x_config ati_hdtvwonder = {
- .demod_address = 0x0a,
- .set_pll_input = nxt200x_set_pll_input,
- .set_ts_params = nxt200x_set_ts_param,
+ .demod_address = 0x0a,
+ .set_pll_input = nxt200x_set_pll_input,
+ .set_ts_params = nxt200x_set_ts_param,
};
-#endif
-#ifdef HAVE_CX24123
static int cx24123_set_ts_param(struct dvb_frontend* fe,
int is_punctured)
{
struct cx8802_dev *dev= fe->dvb->priv;
- dev->ts_gen_cntrl = 0x2;
+ dev->ts_gen_cntrl = 0x02;
return 0;
}
-static int kworld_dvbs_100_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage)
+static int kworld_dvbs_100_set_voltage(struct dvb_frontend* fe,
+ fe_sec_voltage_t voltage)
{
struct cx8802_dev *dev= fe->dvb->priv;
struct cx88_core *core = dev->core;
if (voltage == SEC_VOLTAGE_OFF) {
- cx_write(MO_GP0_IO, 0x000006fB);
+ cx_write(MO_GP0_IO, 0x000006fb);
} else {
cx_write(MO_GP0_IO, 0x000006f9);
}
@@ -496,7 +473,8 @@ static int kworld_dvbs_100_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t
return 0;
}
-static int geniatech_dvbs_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage)
+static int geniatech_dvbs_set_voltage(struct dvb_frontend *fe,
+ fe_sec_voltage_t voltage)
{
struct cx8802_dev *dev= fe->dvb->priv;
struct cx88_core *core = dev->core;
@@ -512,20 +490,20 @@ static int geniatech_dvbs_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t
}
static struct cx24123_config geniatech_dvbs_config = {
- .demod_address = 0x55,
- .set_ts_params = cx24123_set_ts_param,
+ .demod_address = 0x55,
+ .set_ts_params = cx24123_set_ts_param,
};
static struct cx24123_config hauppauge_novas_config = {
- .demod_address = 0x55,
- .set_ts_params = cx24123_set_ts_param,
+ .demod_address = 0x55,
+ .set_ts_params = cx24123_set_ts_param,
};
static struct cx24123_config kworld_dvbs_100_config = {
- .demod_address = 0x15,
- .set_ts_params = cx24123_set_ts_param,
+ .demod_address = 0x15,
+ .set_ts_params = cx24123_set_ts_param,
+ .lnb_polarity = 1,
};
-#endif
static int dvb_register(struct cx8802_dev *dev)
{
@@ -535,114 +513,114 @@ static int dvb_register(struct cx8802_dev *dev)
/* init frontend */
switch (dev->core->board) {
-#ifdef HAVE_CX22702
case CX88_BOARD_HAUPPAUGE_DVB_T1:
- dev->dvb.frontend = cx22702_attach(&hauppauge_novat_config,
- &dev->core->i2c_adap);
+ dev->dvb.frontend = dvb_attach(cx22702_attach,
+ &hauppauge_novat_config,
+ &dev->core->i2c_adap);
if (dev->dvb.frontend != NULL) {
- dvb_pll_attach(dev->dvb.frontend, 0x61,
- &dev->core->i2c_adap,
- &dvb_pll_thomson_dtt759x);
+ dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61,
+ &dev->core->i2c_adap,
+ &dvb_pll_thomson_dtt759x);
}
break;
case CX88_BOARD_TERRATEC_CINERGY_1400_DVB_T1:
case CX88_BOARD_CONEXANT_DVB_T1:
case CX88_BOARD_KWORLD_DVB_T_CX22702:
case CX88_BOARD_WINFAST_DTV1000:
- dev->dvb.frontend = cx22702_attach(&connexant_refboard_config,
- &dev->core->i2c_adap);
+ dev->dvb.frontend = dvb_attach(cx22702_attach,
+ &connexant_refboard_config,
+ &dev->core->i2c_adap);
if (dev->dvb.frontend != NULL) {
- dvb_pll_attach(dev->dvb.frontend, 0x60,
- &dev->core->i2c_adap,
- &dvb_pll_thomson_dtt7579);
+ dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x60,
+ &dev->core->i2c_adap,
+ &dvb_pll_thomson_dtt7579);
}
break;
case CX88_BOARD_WINFAST_DTV2000H:
case CX88_BOARD_HAUPPAUGE_HVR1100:
case CX88_BOARD_HAUPPAUGE_HVR1100LP:
- dev->dvb.frontend = cx22702_attach(&hauppauge_hvr1100_config,
- &dev->core->i2c_adap);
+ dev->dvb.frontend = dvb_attach(cx22702_attach,
+ &hauppauge_hvr1100_config,
+ &dev->core->i2c_adap);
if (dev->dvb.frontend != NULL) {
- dvb_pll_attach(dev->dvb.frontend, 0x61,
- &dev->core->i2c_adap,
- &dvb_pll_fmd1216me);
+ dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61,
+ &dev->core->i2c_adap,
+ &dvb_pll_fmd1216me);
+ }
+ break;
+ case CX88_BOARD_HAUPPAUGE_HVR1300:
+ dev->dvb.frontend = dvb_attach(cx22702_attach,
+ &hauppauge_hvr1300_config,
+ &dev->core->i2c_adap);
+ if (dev->dvb.frontend != NULL) {
+ dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61,
+ &dev->core->i2c_adap,
+ &dvb_pll_fmd1216me);
}
break;
-#endif
-#if defined(HAVE_MT352) || defined(HAVE_ZL10353)
case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PLUS:
-#ifdef HAVE_MT352
- dev->dvb.frontend = mt352_attach(&dvico_fusionhdtv,
- &dev->core->i2c_adap);
+ dev->dvb.frontend = dvb_attach(mt352_attach,
+ &dvico_fusionhdtv,
+ &dev->core->i2c_adap);
if (dev->dvb.frontend != NULL) {
- dvb_pll_attach(dev->dvb.frontend, 0x60,
- &dev->core->i2c_adap,
- &dvb_pll_thomson_dtt7579);
+ dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x60,
+ NULL, &dvb_pll_thomson_dtt7579);
break;
}
-#endif
-#ifdef HAVE_ZL10353
/* ZL10353 replaces MT352 on later cards */
- dev->dvb.frontend = zl10353_attach(&dvico_fusionhdtv_plus_v1_1,
- &dev->core->i2c_adap);
+ dev->dvb.frontend = dvb_attach(zl10353_attach,
+ &dvico_fusionhdtv_plus_v1_1,
+ &dev->core->i2c_adap);
if (dev->dvb.frontend != NULL) {
- dvb_pll_attach(dev->dvb.frontend, 0x60,
- &dev->core->i2c_adap,
- &dvb_pll_thomson_dtt7579);
+ dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x60,
+ NULL, &dvb_pll_thomson_dtt7579);
}
-#endif
break;
case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL:
-#ifdef HAVE_MT352
/* The tin box says DEE1601, but it seems to be DTT7579
* compatible, with a slightly different MT352 AGC gain. */
- dev->dvb.frontend = mt352_attach(&dvico_fusionhdtv_dual,
- &dev->core->i2c_adap);
+ dev->dvb.frontend = dvb_attach(mt352_attach,
+ &dvico_fusionhdtv_dual,
+ &dev->core->i2c_adap);
if (dev->dvb.frontend != NULL) {
- dvb_pll_attach(dev->dvb.frontend, 0x61,
- &dev->core->i2c_adap,
- &dvb_pll_thomson_dtt7579);
+ dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61,
+ NULL, &dvb_pll_thomson_dtt7579);
break;
}
-#endif
-#ifdef HAVE_ZL10353
/* ZL10353 replaces MT352 on later cards */
- dev->dvb.frontend = zl10353_attach(&dvico_fusionhdtv_plus_v1_1,
- &dev->core->i2c_adap);
+ dev->dvb.frontend = dvb_attach(zl10353_attach,
+ &dvico_fusionhdtv_plus_v1_1,
+ &dev->core->i2c_adap);
if (dev->dvb.frontend != NULL) {
- dvb_pll_attach(dev->dvb.frontend, 0x61,
- &dev->core->i2c_adap,
- &dvb_pll_thomson_dtt7579);
+ dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61,
+ NULL, &dvb_pll_thomson_dtt7579);
}
-#endif
break;
-#endif /* HAVE_MT352 || HAVE_ZL10353 */
-#ifdef HAVE_MT352
case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T1:
- dev->dvb.frontend = mt352_attach(&dvico_fusionhdtv,
- &dev->core->i2c_adap);
+ dev->dvb.frontend = dvb_attach(mt352_attach,
+ &dvico_fusionhdtv,
+ &dev->core->i2c_adap);
if (dev->dvb.frontend != NULL) {
- dvb_pll_attach(dev->dvb.frontend, 0x61,
- &dev->core->i2c_adap,
- &dvb_pll_lg_z201);
+ dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61,
+ NULL, &dvb_pll_lg_z201);
}
break;
case CX88_BOARD_KWORLD_DVB_T:
case CX88_BOARD_DNTV_LIVE_DVB_T:
case CX88_BOARD_ADSTECH_DVB_T_PCI:
- dev->dvb.frontend = mt352_attach(&dntv_live_dvbt_config,
- &dev->core->i2c_adap);
+ dev->dvb.frontend = dvb_attach(mt352_attach,
+ &dntv_live_dvbt_config,
+ &dev->core->i2c_adap);
if (dev->dvb.frontend != NULL) {
- dvb_pll_attach(dev->dvb.frontend, 0x61,
- &dev->core->i2c_adap,
- &dvb_pll_unknown_1);
+ dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61,
+ NULL, &dvb_pll_unknown_1);
}
break;
case CX88_BOARD_DNTV_LIVE_DVB_T_PRO:
#ifdef HAVE_VP3054_I2C
dev->core->pll_addr = 0x61;
dev->core->pll_desc = &dvb_pll_fmd1216me;
- dev->dvb.frontend = mt352_attach(&dntv_live_dvbt_pro_config,
+ dev->dvb.frontend = dvb_attach(mt352_attach, &dntv_live_dvbt_pro_config,
&((struct vp3054_i2c_state *)dev->card_priv)->adap);
if (dev->dvb.frontend != NULL) {
dev->dvb.frontend->ops.tuner_ops.set_params = dntv_live_dvbt_pro_tuner_set_params;
@@ -651,30 +629,26 @@ static int dvb_register(struct cx8802_dev *dev)
printk("%s: built without vp3054 support\n", dev->core->name);
#endif
break;
-#endif
-#ifdef HAVE_ZL10353
case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_HYBRID:
dev->core->pll_addr = 0x61;
dev->core->pll_desc = &dvb_pll_thomson_fe6600;
- dev->dvb.frontend = zl10353_attach(&dvico_fusionhdtv_hybrid,
- &dev->core->i2c_adap);
+ dev->dvb.frontend = dvb_attach(zl10353_attach,
+ &dvico_fusionhdtv_hybrid,
+ &dev->core->i2c_adap);
if (dev->dvb.frontend != NULL) {
dev->dvb.frontend->ops.tuner_ops.set_params = dvico_hybrid_tuner_set_params;
}
break;
-#endif
-#ifdef HAVE_OR51132
case CX88_BOARD_PCHDTV_HD3000:
- dev->dvb.frontend = or51132_attach(&pchdtv_hd3000,
- &dev->core->i2c_adap);
+ dev->dvb.frontend = dvb_attach(or51132_attach,
+ &pchdtv_hd3000,
+ &dev->core->i2c_adap);
if (dev->dvb.frontend != NULL) {
- dvb_pll_attach(dev->dvb.frontend, 0x61,
- &dev->core->i2c_adap,
- &dvb_pll_thomson_dtt761x);
+ dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61,
+ &dev->core->i2c_adap,
+ &dvb_pll_thomson_dtt761x);
}
break;
-#endif
-#ifdef HAVE_LGDT330X
case CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_Q:
dev->ts_gen_cntrl = 0x08;
{
@@ -690,8 +664,9 @@ static int dvb_register(struct cx8802_dev *dev)
fusionhdtv_3_gold.pll_rf_set = lgdt330x_pll_rf_set;
dev->core->pll_addr = 0x61;
dev->core->pll_desc = &dvb_pll_microtune_4042;
- dev->dvb.frontend = lgdt330x_attach(&fusionhdtv_3_gold,
- &dev->core->i2c_adap);
+ dev->dvb.frontend = dvb_attach(lgdt330x_attach,
+ &fusionhdtv_3_gold,
+ &dev->core->i2c_adap);
if (dev->dvb.frontend != NULL) {
dev->dvb.frontend->ops.tuner_ops.set_params = lgdt3302_tuner_set_params;
}
@@ -709,8 +684,9 @@ static int dvb_register(struct cx8802_dev *dev)
mdelay(200);
dev->core->pll_addr = 0x61;
dev->core->pll_desc = &dvb_pll_thomson_dtt761x;
- dev->dvb.frontend = lgdt330x_attach(&fusionhdtv_3_gold,
- &dev->core->i2c_adap);
+ dev->dvb.frontend = dvb_attach(lgdt330x_attach,
+ &fusionhdtv_3_gold,
+ &dev->core->i2c_adap);
if (dev->dvb.frontend != NULL) {
dev->dvb.frontend->ops.tuner_ops.set_params = lgdt3302_tuner_set_params;
}
@@ -726,8 +702,9 @@ static int dvb_register(struct cx8802_dev *dev)
mdelay(100);
cx_set(MO_GP0_IO, 1);
mdelay(200);
- dev->dvb.frontend = lgdt330x_attach(&fusionhdtv_5_gold,
- &dev->core->i2c_adap);
+ dev->dvb.frontend = dvb_attach(lgdt330x_attach,
+ &fusionhdtv_5_gold,
+ &dev->core->i2c_adap);
if (dev->dvb.frontend != NULL) {
dev->dvb.frontend->ops.tuner_ops.set_params = lgdt3303_tuner_set_params;
}
@@ -743,52 +720,51 @@ static int dvb_register(struct cx8802_dev *dev)
mdelay(100);
cx_set(MO_GP0_IO, 1);
mdelay(200);
- dev->dvb.frontend = lgdt330x_attach(&pchdtv_hd5500,
- &dev->core->i2c_adap);
+ dev->dvb.frontend = dvb_attach(lgdt330x_attach,
+ &pchdtv_hd5500,
+ &dev->core->i2c_adap);
if (dev->dvb.frontend != NULL) {
dev->dvb.frontend->ops.tuner_ops.set_params = lgdt3303_tuner_set_params;
}
}
break;
-#endif
-#ifdef HAVE_NXT200X
case CX88_BOARD_ATI_HDTVWONDER:
- dev->dvb.frontend = nxt200x_attach(&ati_hdtvwonder,
- &dev->core->i2c_adap);
+ dev->dvb.frontend = dvb_attach(nxt200x_attach,
+ &ati_hdtvwonder,
+ &dev->core->i2c_adap);
if (dev->dvb.frontend != NULL) {
- dvb_pll_attach(dev->dvb.frontend, 0x61,
- &dev->core->i2c_adap,
- &dvb_pll_tuv1236d);
+ dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61,
+ NULL, &dvb_pll_tuv1236d);
}
break;
-#endif
-#ifdef HAVE_CX24123
case CX88_BOARD_HAUPPAUGE_NOVASPLUS_S1:
case CX88_BOARD_HAUPPAUGE_NOVASE2_S1:
- dev->dvb.frontend = cx24123_attach(&hauppauge_novas_config,
- &dev->core->i2c_adap);
+ dev->dvb.frontend = dvb_attach(cx24123_attach,
+ &hauppauge_novas_config,
+ &dev->core->i2c_adap);
if (dev->dvb.frontend) {
- isl6421_attach(dev->dvb.frontend, &dev->core->i2c_adap,
- 0x08, 0x00, 0x00);
+ dvb_attach(isl6421_attach, dev->dvb.frontend,
+ &dev->core->i2c_adap, 0x08, 0x00, 0x00);
}
break;
case CX88_BOARD_KWORLD_DVBS_100:
- dev->dvb.frontend = cx24123_attach(&kworld_dvbs_100_config,
- &dev->core->i2c_adap);
+ dev->dvb.frontend = dvb_attach(cx24123_attach,
+ &kworld_dvbs_100_config,
+ &dev->core->i2c_adap);
if (dev->dvb.frontend) {
dev->core->prev_set_voltage = dev->dvb.frontend->ops.set_voltage;
dev->dvb.frontend->ops.set_voltage = kworld_dvbs_100_set_voltage;
}
break;
case CX88_BOARD_GENIATECH_DVBS:
- dev->dvb.frontend = cx24123_attach(&geniatech_dvbs_config,
- &dev->core->i2c_adap);
+ dev->dvb.frontend = dvb_attach(cx24123_attach,
+ &geniatech_dvbs_config,
+ &dev->core->i2c_adap);
if (dev->dvb.frontend) {
dev->core->prev_set_voltage = dev->dvb.frontend->ops.set_voltage;
dev->dvb.frontend->ops.set_voltage = geniatech_dvbs_set_voltage;
}
break;
-#endif
default:
printk("%s: The frontend of your DVB/ATSC card isn't supported yet\n",
dev->core->name);
@@ -908,8 +884,10 @@ static struct pci_driver dvb_pci_driver = {
.id_table = cx8802_pci_tbl,
.probe = dvb_probe,
.remove = __devexit_p(dvb_remove),
+#ifdef CONFIG_PM
.suspend = cx8802_suspend_common,
.resume = cx8802_resume_common,
+#endif
};
static int dvb_init(void)
diff --git a/drivers/media/video/cx88/cx88-i2c.c b/drivers/media/video/cx88/cx88-i2c.c
index 7bea34714861..27b5dbb2ca1a 100644
--- a/drivers/media/video/cx88/cx88-i2c.c
+++ b/drivers/media/video/cx88/cx88-i2c.c
@@ -7,6 +7,9 @@
(c) 2002 Yurij Sysoev <yurij@naturesoft.net>
(c) 1999-2003 Gerd Knorr <kraxel@bytesex.org>
+ (c) 2005 Mauro Carvalho Chehab <mchehab@infradead.org>
+ - Multituner support and i2c address binding
+
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
@@ -40,6 +43,11 @@ static unsigned int i2c_scan = 0;
module_param(i2c_scan, int, 0444);
MODULE_PARM_DESC(i2c_scan,"scan i2c bus at insmod time");
+static unsigned int i2c_udelay = 5;
+module_param(i2c_udelay, int, 0644);
+MODULE_PARM_DESC(i2c_udelay,"i2c delay at insmod time, in usecs "
+ "(should be 5 or higher). Lower value means higher bus speed.");
+
#define dprintk(level,fmt, arg...) if (i2c_debug >= level) \
printk(KERN_DEBUG "%s: " fmt, core->name , ## arg)
@@ -198,6 +206,11 @@ static void do_i2c_scan(char *name, struct i2c_client *c)
/* init + register i2c algo-bit adapter */
int cx88_i2c_init(struct cx88_core *core, struct pci_dev *pci)
{
+ /* Prevents usage of invalid delay values */
+ if (i2c_udelay<5)
+ i2c_udelay=5;
+ cx8800_i2c_algo_template.udelay=i2c_udelay;
+
memcpy(&core->i2c_adap, &cx8800_i2c_adap_template,
sizeof(core->i2c_adap));
memcpy(&core->i2c_algo, &cx8800_i2c_algo_template,
diff --git a/drivers/media/video/cx88/cx88-input.c b/drivers/media/video/cx88/cx88-input.c
index c25564648993..83ebf7a3c054 100644
--- a/drivers/media/video/cx88/cx88-input.c
+++ b/drivers/media/video/cx88/cx88-input.c
@@ -107,7 +107,15 @@ static void cx88_ir_handle_key(struct cx88_IR *ir)
(gpio & ir->mask_keydown) ? " down" : "",
(gpio & ir->mask_keyup) ? " up" : "");
- if (ir->mask_keydown) {
+ if (ir->core->board == CX88_BOARD_NORWOOD_MICRO) {
+ u32 gpio_key = cx_read(MO_GP0_IO);
+
+ data = (data << 4) | ((gpio_key & 0xf0) >> 4);
+
+ ir_input_keydown(ir->input, &ir->ir, data, data);
+ ir_input_nokey(ir->input, &ir->ir);
+
+ } else if (ir->mask_keydown) {
/* bit set on keydown */
if (gpio & ir->mask_keydown) {
ir_input_keydown(ir->input, &ir->ir, data, data);
@@ -187,6 +195,7 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci)
case CX88_BOARD_HAUPPAUGE_NOVASE2_S1:
case CX88_BOARD_HAUPPAUGE_NOVASPLUS_S1:
case CX88_BOARD_HAUPPAUGE_HVR1100:
+ case CX88_BOARD_HAUPPAUGE_HVR1300:
ir_codes = ir_codes_hauppauge_new;
ir_type = IR_TYPE_RC5;
ir->sampling = 1;
@@ -248,6 +257,13 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci)
ir_type = IR_TYPE_PD;
ir->sampling = 0xff00; /* address */
break;
+ case CX88_BOARD_NORWOOD_MICRO:
+ ir_codes = ir_codes_norwood;
+ ir->gpio_addr = MO_GP1_IO;
+ ir->mask_keycode = 0x0e;
+ ir->mask_keyup = 0x80;
+ ir->polling = 50; /* ms */
+ break;
case CX88_BOARD_NPGTECH_REALTV_TOP10FM:
ir_codes = ir_codes_npgtech;
ir->gpio_addr = MO_GP0_IO;
@@ -402,6 +418,7 @@ void cx88_ir_irq(struct cx88_core *core)
case CX88_BOARD_HAUPPAUGE_NOVASE2_S1:
case CX88_BOARD_HAUPPAUGE_NOVASPLUS_S1:
case CX88_BOARD_HAUPPAUGE_HVR1100:
+ case CX88_BOARD_HAUPPAUGE_HVR1300:
ircode = ir_decode_biphase(ir->samples, ir->scount, 5, 7);
ir_dprintk("biphase decoded: %x\n", ircode);
if ((ircode & 0xfffff000) != 0x3000)
diff --git a/drivers/media/video/cx88/cx88-tvaudio.c b/drivers/media/video/cx88/cx88-tvaudio.c
index 5785c3481579..741e7c5e69ec 100644
--- a/drivers/media/video/cx88/cx88-tvaudio.c
+++ b/drivers/media/video/cx88/cx88-tvaudio.c
@@ -52,7 +52,6 @@
#include <linux/init.h>
#include <linux/smp_lock.h>
#include <linux/delay.h>
-#include <linux/config.h>
#include <linux/kthread.h>
#include "cx88.h"
@@ -138,14 +137,10 @@ static void set_audio_finish(struct cx88_core *core, u32 ctl)
{
u32 volume;
-#ifndef CONFIG_VIDEO_CX88_ALSA
/* restart dma; This avoids buzz in NICAM and is good in others */
cx88_stop_audio_dma(core);
-#endif
cx_write(AUD_RATE_THRES_DMD, 0x000000C0);
-#ifndef CONFIG_VIDEO_CX88_ALSA
cx88_start_audio_dma(core);
-#endif
if (cx88_boards[core->board].blackbird) {
/* sets sound input from external adc */
diff --git a/drivers/media/video/cx88/cx88-video.c b/drivers/media/video/cx88/cx88-video.c
index 94c92bacc342..fbc79e9842aa 100644
--- a/drivers/media/video/cx88/cx88-video.c
+++ b/drivers/media/video/cx88/cx88-video.c
@@ -497,6 +497,7 @@ static int start_video_dma(struct cx8800_dev *dev,
return 0;
}
+#ifdef CONFIG_PM
static int stop_video_dma(struct cx8800_dev *dev)
{
struct cx88_core *core = dev->core;
@@ -512,6 +513,7 @@ static int stop_video_dma(struct cx8800_dev *dev)
cx_clear(MO_VID_INTMSK, 0x0f0011);
return 0;
}
+#endif
static int restart_video_queue(struct cx8800_dev *dev,
struct cx88_dmaqueue *q)
@@ -2017,6 +2019,7 @@ static void __devexit cx8800_finidev(struct pci_dev *pci_dev)
kfree(dev);
}
+#ifdef CONFIG_PM
static int cx8800_suspend(struct pci_dev *pci_dev, pm_message_t state)
{
struct cx8800_dev *dev = pci_get_drvdata(pci_dev);
@@ -2092,6 +2095,7 @@ static int cx8800_resume(struct pci_dev *pci_dev)
return 0;
}
+#endif
/* ----------------------------------------------------------- */
@@ -2112,9 +2116,10 @@ static struct pci_driver cx8800_pci_driver = {
.id_table = cx8800_pci_tbl,
.probe = cx8800_initdev,
.remove = __devexit_p(cx8800_finidev),
-
+#ifdef CONFIG_PM
.suspend = cx8800_suspend,
.resume = cx8800_resume,
+#endif
};
static int cx8800_init(void)
diff --git a/drivers/media/video/cx88/cx88.h b/drivers/media/video/cx88/cx88.h
index e7810955dd4f..89f12e273b7f 100644
--- a/drivers/media/video/cx88/cx88.h
+++ b/drivers/media/video/cx88/cx88.h
@@ -197,6 +197,10 @@ extern struct sram_channel cx88_sram_channels[];
#define CX88_BOARD_NPGTECH_REALTV_TOP10FM 50
#define CX88_BOARD_WINFAST_DTV2000H 51
#define CX88_BOARD_GENIATECH_DVBS 52
+#define CX88_BOARD_HAUPPAUGE_HVR3000 53
+#define CX88_BOARD_NORWOOD_MICRO 54
+#define CX88_BOARD_TE_DTV_250_OEM_SWANN 55
+#define CX88_BOARD_HAUPPAUGE_HVR1300 56
enum cx88_itype {
CX88_VMUX_COMPOSITE1 = 1,
@@ -545,6 +549,7 @@ extern const unsigned int cx88_idcount;
extern void cx88_card_list(struct cx88_core *core, struct pci_dev *pci);
extern void cx88_card_setup(struct cx88_core *core);
+extern void cx88_card_setup_pre_i2c(struct cx88_core *core);
/* ----------------------------------------------------------- */
/* cx88-tvaudio.c */
diff --git a/drivers/media/video/em28xx/Kconfig b/drivers/media/video/em28xx/Kconfig
index dfb15bfb83dc..9285a58e47aa 100644
--- a/drivers/media/video/em28xx/Kconfig
+++ b/drivers/media/video/em28xx/Kconfig
@@ -5,7 +5,8 @@ config VIDEO_EM28XX
select VIDEO_TUNER
select VIDEO_TVEEPROM
select VIDEO_IR
- select VIDEO_SAA711X
+ select VIDEO_SAA711X if VIDEO_HELPER_CHIPS_AUTO
+ select VIDEO_TVP5150 if VIDEO_HELPER_CHIPS_AUTO
---help---
This is a video4linux driver for Empia 28xx based TV cards.
diff --git a/drivers/media/video/em28xx/em28xx-video.c b/drivers/media/video/em28xx/em28xx-video.c
index 2a461dde480c..20df657b70c8 100644
--- a/drivers/media/video/em28xx/em28xx-video.c
+++ b/drivers/media/video/em28xx/em28xx-video.c
@@ -174,7 +174,7 @@ static void em28xx_config_i2c(struct em28xx *dev)
route.input = INPUT(dev->ctl_input)->vmux;
route.output = 0;
- em28xx_i2c_call_clients(dev, VIDIOC_INT_RESET, NULL);
+ em28xx_i2c_call_clients(dev, VIDIOC_INT_RESET, 0);
em28xx_i2c_call_clients(dev, VIDIOC_INT_S_VIDEO_ROUTING, &route);
em28xx_i2c_call_clients(dev, VIDIOC_STREAMON, NULL);
diff --git a/drivers/media/video/ks0127.c b/drivers/media/video/ks0127.c
index 3bf7ac4f5288..c1a377f797d9 100644
--- a/drivers/media/video/ks0127.c
+++ b/drivers/media/video/ks0127.c
@@ -832,8 +832,7 @@ static int ks0127_detach(struct i2c_client *client)
static int __devinit ks0127_init_module(void)
{
init_reg_defaults();
- i2c_add_driver(&i2c_driver_ks0127);
- return 0;
+ return i2c_add_driver(&i2c_driver_ks0127);
}
static void __devexit ks0127_cleanup_module(void)
diff --git a/drivers/media/video/pvrusb2/Kconfig b/drivers/media/video/pvrusb2/Kconfig
index 7e727fe14b32..a52171ef6134 100644
--- a/drivers/media/video/pvrusb2/Kconfig
+++ b/drivers/media/video/pvrusb2/Kconfig
@@ -5,8 +5,6 @@ config VIDEO_PVRUSB2
select VIDEO_TUNER
select VIDEO_TVEEPROM
select VIDEO_CX2341X
- select VIDEO_SAA711X
- select VIDEO_MSP3400
---help---
This is a video4linux driver for Conexant 23416 based
usb2 personal video recorder devices.
@@ -14,6 +12,20 @@ config VIDEO_PVRUSB2
To compile this driver as a module, choose M here: the
module will be called pvrusb2
+config VIDEO_PVRUSB2_29XXX
+ bool "Hauppauge WinTV-PVR USB2 support for 29xxx model series"
+ depends on VIDEO_PVRUSB2 && EXPERIMENTAL
+ select VIDEO_SAA711X
+ select VIDEO_MSP3400
+ ---help---
+ This option enables support for WinTV-PVR USB2 devices whose
+ model number is of the form "29xxx" (leading prefix of "29"
+ followed by 3 digits).
+ To see if you may need this option, examine the white
+ sticker on the underside of your device.
+
+ If you are in doubt, say Y.
+
config VIDEO_PVRUSB2_24XXX
bool "Hauppauge WinTV-PVR USB2 support for 24xxx model series"
depends on VIDEO_PVRUSB2 && EXPERIMENTAL
@@ -60,3 +72,5 @@ config VIDEO_PVRUSB2_DEBUGIFC
You do not need to select this option unless you plan
on debugging the driver or performing a manual firmware
extraction.
+
+ If you are in doubt, say N.
diff --git a/drivers/media/video/pvrusb2/Makefile b/drivers/media/video/pvrusb2/Makefile
index 02e414210dac..69b3e43cd0eb 100644
--- a/drivers/media/video/pvrusb2/Makefile
+++ b/drivers/media/video/pvrusb2/Makefile
@@ -1,10 +1,6 @@
obj-pvrusb2-sysfs-$(CONFIG_VIDEO_PVRUSB2_SYSFS) := pvrusb2-sysfs.o
obj-pvrusb2-debugifc-$(CONFIG_VIDEO_PVRUSB2_DEBUGIFC) := pvrusb2-debugifc.o
-obj-pvrusb2-24xxx-$(CONFIG_VIDEO_PVRUSB2_24XXX) := \
- pvrusb2-cx2584x-v4l.o \
- pvrusb2-wm8775.o
-
pvrusb2-objs := pvrusb2-i2c-core.o pvrusb2-i2c-cmd-v4l2.o \
pvrusb2-audio.o pvrusb2-i2c-chips-v4l2.o \
pvrusb2-encoder.o pvrusb2-video-v4l.o \
@@ -12,7 +8,7 @@ pvrusb2-objs := pvrusb2-i2c-core.o pvrusb2-i2c-cmd-v4l2.o \
pvrusb2-main.o pvrusb2-hdw.o pvrusb2-v4l2.o \
pvrusb2-ctrl.o pvrusb2-std.o \
pvrusb2-context.o pvrusb2-io.o pvrusb2-ioread.o \
- $(obj-pvrusb2-24xxx-y) \
+ pvrusb2-cx2584x-v4l.o pvrusb2-wm8775.o \
$(obj-pvrusb2-sysfs-y) $(obj-pvrusb2-debugifc-y)
obj-$(CONFIG_VIDEO_PVRUSB2) += pvrusb2.o
diff --git a/drivers/media/video/pvrusb2/pvrusb2-ctrl.c b/drivers/media/video/pvrusb2/pvrusb2-ctrl.c
index fb6198f1df98..c77de859cc8e 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-ctrl.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-ctrl.c
@@ -43,12 +43,17 @@ int pvr2_ctrl_set_mask_value(struct pvr2_ctrl *cptr,int mask,int val)
if (cptr->info->type == pvr2_ctl_bitmask) {
mask &= cptr->info->def.type_bitmask.valid_bits;
} else if (cptr->info->type == pvr2_ctl_int) {
- if (val < cptr->info->def.type_int.min_value) {
- break;
+ int lim;
+ lim = cptr->info->def.type_int.min_value;
+ if (cptr->info->get_min_value) {
+ cptr->info->get_min_value(cptr,&lim);
}
- if (val > cptr->info->def.type_int.max_value) {
- break;
+ if (val < lim) break;
+ lim = cptr->info->def.type_int.max_value;
+ if (cptr->info->get_max_value) {
+ cptr->info->get_max_value(cptr,&lim);
}
+ if (val > lim) break;
} else if (cptr->info->type == pvr2_ctl_enum) {
if (val >= cptr->info->def.type_enum.count) {
break;
@@ -91,7 +96,9 @@ int pvr2_ctrl_get_max(struct pvr2_ctrl *cptr)
int ret = 0;
if (!cptr) return 0;
LOCK_TAKE(cptr->hdw->big_lock); do {
- if (cptr->info->type == pvr2_ctl_int) {
+ if (cptr->info->get_max_value) {
+ cptr->info->get_max_value(cptr,&ret);
+ } else if (cptr->info->type == pvr2_ctl_int) {
ret = cptr->info->def.type_int.max_value;
}
} while(0); LOCK_GIVE(cptr->hdw->big_lock);
@@ -105,7 +112,9 @@ int pvr2_ctrl_get_min(struct pvr2_ctrl *cptr)
int ret = 0;
if (!cptr) return 0;
LOCK_TAKE(cptr->hdw->big_lock); do {
- if (cptr->info->type == pvr2_ctl_int) {
+ if (cptr->info->get_min_value) {
+ cptr->info->get_min_value(cptr,&ret);
+ } else if (cptr->info->type == pvr2_ctl_int) {
ret = cptr->info->def.type_int.min_value;
}
} while(0); LOCK_GIVE(cptr->hdw->big_lock);
diff --git a/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.c b/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.c
index c80c26be6e4d..df8feac16aee 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.c
@@ -221,7 +221,7 @@ static unsigned int decoder_describe(struct pvr2_v4l_cx2584x *ctxt,
static void decoder_reset(struct pvr2_v4l_cx2584x *ctxt)
{
int ret;
- ret = pvr2_i2c_client_cmd(ctxt->client,VIDIOC_INT_RESET,NULL);
+ ret = pvr2_i2c_client_cmd(ctxt->client,VIDIOC_INT_RESET,0);
pvr2_trace(PVR2_TRACE_CHIPS,"i2c cx25840 decoder_reset (ret=%d)",ret);
}
diff --git a/drivers/media/video/pvrusb2/pvrusb2-encoder.c b/drivers/media/video/pvrusb2/pvrusb2-encoder.c
index 18a7073501c6..c94f97b79392 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-encoder.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-encoder.c
@@ -317,7 +317,7 @@ int pvr2_encoder_configure(struct pvr2_hdw *hdw)
if (ret) {
pvr2_trace(PVR2_TRACE_ERROR_LEGS,
- "Failed to configure cx32416");
+ "Failed to configure cx23416");
return ret;
}
@@ -337,7 +337,7 @@ int pvr2_encoder_configure(struct pvr2_hdw *hdw)
if (ret) {
pvr2_trace(PVR2_TRACE_ERROR_LEGS,
- "Failed to initialize cx32416 video input");
+ "Failed to initialize cx23416 video input");
return ret;
}
diff --git a/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h b/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h
index 0d6dc33ca320..34b08fbcc6ea 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h
+++ b/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h
@@ -33,7 +33,6 @@
*/
-#include <linux/config.h>
#include <linux/videodev2.h>
#include <linux/i2c.h>
#include <linux/mutex.h>
@@ -41,32 +40,6 @@
#include "pvrusb2-io.h"
#include <media/cx2341x.h>
-/* Legal values for the SRATE state variable */
-#define PVR2_CVAL_SRATE_48 0
-#define PVR2_CVAL_SRATE_44_1 1
-
-/* Legal values for the AUDIOBITRATE state variable */
-#define PVR2_CVAL_AUDIOBITRATE_384 0
-#define PVR2_CVAL_AUDIOBITRATE_320 1
-#define PVR2_CVAL_AUDIOBITRATE_256 2
-#define PVR2_CVAL_AUDIOBITRATE_224 3
-#define PVR2_CVAL_AUDIOBITRATE_192 4
-#define PVR2_CVAL_AUDIOBITRATE_160 5
-#define PVR2_CVAL_AUDIOBITRATE_128 6
-#define PVR2_CVAL_AUDIOBITRATE_112 7
-#define PVR2_CVAL_AUDIOBITRATE_96 8
-#define PVR2_CVAL_AUDIOBITRATE_80 9
-#define PVR2_CVAL_AUDIOBITRATE_64 10
-#define PVR2_CVAL_AUDIOBITRATE_56 11
-#define PVR2_CVAL_AUDIOBITRATE_48 12
-#define PVR2_CVAL_AUDIOBITRATE_32 13
-#define PVR2_CVAL_AUDIOBITRATE_VBR 14
-
-/* Legal values for the AUDIOEMPHASIS state variable */
-#define PVR2_CVAL_AUDIOEMPHASIS_NONE 0
-#define PVR2_CVAL_AUDIOEMPHASIS_50_15 1
-#define PVR2_CVAL_AUDIOEMPHASIS_CCITT 2
-
/* Legal values for PVR2_CID_HSM */
#define PVR2_CVAL_HSM_FAIL 0
#define PVR2_CVAL_HSM_FULL 1
@@ -107,6 +80,8 @@ struct pvr2_ctl_info {
/* Control's implementation */
pvr2_ctlf_get_value get_value; /* Get its value */
+ pvr2_ctlf_get_value get_min_value; /* Get minimum allowed value */
+ pvr2_ctlf_get_value get_max_value; /* Get maximum allowed value */
pvr2_ctlf_set_value set_value; /* Set its value */
pvr2_ctlf_val_to_sym val_to_sym; /* Custom convert value->symbol */
pvr2_ctlf_sym_to_val sym_to_val; /* Custom convert symbol->value */
@@ -193,9 +168,7 @@ struct pvr2_decoder_ctrl {
/* Known major hardware variants, keyed from device ID */
#define PVR2_HDW_TYPE_29XXX 0
-#ifdef CONFIG_VIDEO_PVRUSB2_24XXX
#define PVR2_HDW_TYPE_24XXX 1
-#endif
typedef int (*pvr2_i2c_func)(struct pvr2_hdw *,u8,u8 *,u16,u8 *, u16);
#define PVR2_I2C_FUNC_CNT 128
diff --git a/drivers/media/video/pvrusb2/pvrusb2-hdw.c b/drivers/media/video/pvrusb2/pvrusb2-hdw.c
index be1e5cc78081..88604365777c 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-hdw.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-hdw.c
@@ -38,9 +38,7 @@
struct usb_device_id pvr2_device_table[] = {
[PVR2_HDW_TYPE_29XXX] = { USB_DEVICE(0x2040, 0x2900) },
-#ifdef CONFIG_VIDEO_PVRUSB2_24XXX
[PVR2_HDW_TYPE_24XXX] = { USB_DEVICE(0x2040, 0x2400) },
-#endif
{ }
};
@@ -48,9 +46,7 @@ MODULE_DEVICE_TABLE(usb, pvr2_device_table);
static const char *pvr2_device_names[] = {
[PVR2_HDW_TYPE_29XXX] = "WinTV PVR USB2 Model Category 29xxxx",
-#ifdef CONFIG_VIDEO_PVRUSB2_24XXX
[PVR2_HDW_TYPE_24XXX] = "WinTV PVR USB2 Model Category 24xxxx",
-#endif
};
struct pvr2_string_table {
@@ -58,14 +54,12 @@ struct pvr2_string_table {
unsigned int cnt;
};
-#ifdef CONFIG_VIDEO_PVRUSB2_24XXX
// Names of other client modules to request for 24xxx model hardware
static const char *pvr2_client_24xxx[] = {
"cx25840",
"tuner",
"wm8775",
};
-#endif
// Names of other client modules to request for 29xxx model hardware
static const char *pvr2_client_29xxx[] = {
@@ -79,12 +73,10 @@ static struct pvr2_string_table pvr2_client_lists[] = {
pvr2_client_29xxx,
sizeof(pvr2_client_29xxx)/sizeof(pvr2_client_29xxx[0]),
},
-#ifdef CONFIG_VIDEO_PVRUSB2_24XXX
[PVR2_HDW_TYPE_24XXX] = {
pvr2_client_24xxx,
sizeof(pvr2_client_24xxx)/sizeof(pvr2_client_24xxx[0]),
},
-#endif
};
static struct pvr2_hdw *unit_pointers[PVR_NUM] = {[ 0 ... PVR_NUM-1 ] = NULL};
@@ -221,14 +213,15 @@ static const struct pvr2_mpeg_ids mpeg_ids[] = {
};
#define MPEGDEF_COUNT (sizeof(mpeg_ids)/sizeof(mpeg_ids[0]))
+
static const char *control_values_srate[] = {
- [PVR2_CVAL_SRATE_48] = "48KHz",
- [PVR2_CVAL_SRATE_44_1] = "44.1KHz",
+ [V4L2_MPEG_AUDIO_SAMPLING_FREQ_44100] = "44.1 kHz",
+ [V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000] = "48 kHz",
+ [V4L2_MPEG_AUDIO_SAMPLING_FREQ_32000] = "32 kHz",
};
-
static const char *control_values_input[] = {
[PVR2_CVAL_INPUT_TV] = "television", /*xawtv needs this name*/
[PVR2_CVAL_INPUT_RADIO] = "radio",
@@ -362,6 +355,50 @@ static int ctrl_freq_set(struct pvr2_ctrl *cptr,int m,int v)
return 0;
}
+static int ctrl_hres_max_get(struct pvr2_ctrl *cptr,int *vp)
+{
+ /* If we're dealing with a 24xxx device, force the horizontal
+ maximum to be 720 no matter what, since we can't get the device
+ to work properly with any other value. Otherwise just return
+ the normal value. */
+ *vp = cptr->info->def.type_int.max_value;
+ if (cptr->hdw->hdw_type == PVR2_HDW_TYPE_24XXX) *vp = 720;
+ return 0;
+}
+
+static int ctrl_hres_min_get(struct pvr2_ctrl *cptr,int *vp)
+{
+ /* If we're dealing with a 24xxx device, force the horizontal
+ minimum to be 720 no matter what, since we can't get the device
+ to work properly with any other value. Otherwise just return
+ the normal value. */
+ *vp = cptr->info->def.type_int.min_value;
+ if (cptr->hdw->hdw_type == PVR2_HDW_TYPE_24XXX) *vp = 720;
+ return 0;
+}
+
+static int ctrl_vres_max_get(struct pvr2_ctrl *cptr,int *vp)
+{
+ /* Actual maximum depends on the video standard in effect. */
+ if (cptr->hdw->std_mask_cur & V4L2_STD_525_60) {
+ *vp = 480;
+ } else {
+ *vp = 576;
+ }
+ return 0;
+}
+
+static int ctrl_vres_min_get(struct pvr2_ctrl *cptr,int *vp)
+{
+ /* Actual minimum depends on device type. */
+ if (cptr->hdw->hdw_type == PVR2_HDW_TYPE_24XXX) {
+ *vp = 75;
+ } else {
+ *vp = 17;
+ }
+ return 0;
+}
+
static int ctrl_cx2341x_is_dirty(struct pvr2_ctrl *cptr)
{
return cptr->hdw->enc_stale != 0;
@@ -719,19 +756,27 @@ static const struct pvr2_ctl_info control_defs[] = {
.internal_id = PVR2_CID_HRES,
.default_value = 720,
DEFREF(res_hor),
- DEFINT(320,720),
+ DEFINT(19,720),
+ /* Hook in check for clamp on horizontal resolution in
+ order to avoid unsolved problem involving cx25840. */
+ .get_max_value = ctrl_hres_max_get,
+ .get_min_value = ctrl_hres_min_get,
},{
.desc = "Vertical capture resolution",
.name = "resolution_ver",
.internal_id = PVR2_CID_VRES,
.default_value = 480,
DEFREF(res_ver),
- DEFINT(200,625),
+ DEFINT(17,576),
+ /* Hook in check for video standard and adjust maximum
+ depending on the standard. */
+ .get_max_value = ctrl_vres_max_get,
+ .get_min_value = ctrl_vres_min_get,
},{
.v4l_id = V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ,
- .desc = "Sample rate",
+ .default_value = V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000,
+ .desc = "Audio Sampling Frequency",
.name = "srate",
- .default_value = PVR2_CVAL_SRATE_48,
DEFREF(srate),
DEFENUM(control_values_srate),
},{
@@ -935,22 +980,18 @@ static int pvr2_upload_firmware1(struct pvr2_hdw *hdw)
static const char *fw_files_29xxx[] = {
"v4l-pvrusb2-29xxx-01.fw",
};
-#ifdef CONFIG_VIDEO_PVRUSB2_24XXX
static const char *fw_files_24xxx[] = {
"v4l-pvrusb2-24xxx-01.fw",
};
-#endif
static const struct pvr2_string_table fw_file_defs[] = {
[PVR2_HDW_TYPE_29XXX] = {
fw_files_29xxx,
sizeof(fw_files_29xxx)/sizeof(fw_files_29xxx[0]),
},
-#ifdef CONFIG_VIDEO_PVRUSB2_24XXX
[PVR2_HDW_TYPE_24XXX] = {
fw_files_24xxx,
sizeof(fw_files_24xxx)/sizeof(fw_files_24xxx[0]),
},
-#endif
};
hdw->fw1_state = FW1_STATE_FAILED; // default result
@@ -2237,11 +2278,14 @@ static int pvr2_hdw_commit_ctl_internal(struct pvr2_hdw *hdw)
}
if (hdw->std_dirty ||
+ hdw->enc_stale ||
+ hdw->srate_dirty ||
+ hdw->res_ver_dirty ||
+ hdw->res_hor_dirty ||
0) {
/* If any of this changes, then the encoder needs to be
reconfigured, and we need to reset the stream. */
stale_subsys_mask |= (1<<PVR2_SUBSYS_B_ENC_CFG);
- stale_subsys_mask |= hdw->subsys_stream_mask;
}
if (hdw->srate_dirty) {
diff --git a/drivers/media/video/pvrusb2/pvrusb2-i2c-chips-v4l2.c b/drivers/media/video/pvrusb2/pvrusb2-i2c-chips-v4l2.c
index fbe6039aeb6a..ed3e8105292a 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-i2c-chips-v4l2.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-i2c-chips-v4l2.c
@@ -26,10 +26,8 @@
#include "pvrusb2-audio.h"
#include "pvrusb2-tuner.h"
#include "pvrusb2-video-v4l.h"
-#ifdef CONFIG_VIDEO_PVRUSB2_24XXX
#include "pvrusb2-cx2584x-v4l.h"
#include "pvrusb2-wm8775.h"
-#endif
#define trace_i2c(...) pvr2_trace(PVR2_TRACE_I2C,__VA_ARGS__)
@@ -71,7 +69,6 @@ void pvr2_i2c_probe(struct pvr2_hdw *hdw,struct pvr2_i2c_client *cp)
return;
}
}
-#ifdef CONFIG_VIDEO_PVRUSB2_24XXX
if (id == I2C_DRIVERID_CX25840) {
if (pvr2_i2c_cx2584x_v4l_setup(hdw,cp)) {
return;
@@ -82,7 +79,6 @@ void pvr2_i2c_probe(struct pvr2_hdw *hdw,struct pvr2_i2c_client *cp)
return;
}
}
-#endif
if (id == I2C_DRIVERID_SAA711X) {
if (pvr2_i2c_decoder_v4l_setup(hdw,cp)) {
return;
diff --git a/drivers/media/video/pvrusb2/pvrusb2-i2c-cmd-v4l2.c b/drivers/media/video/pvrusb2/pvrusb2-i2c-cmd-v4l2.c
index 8a9933dec912..05ea17afe903 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-i2c-cmd-v4l2.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-i2c-cmd-v4l2.c
@@ -31,7 +31,7 @@ static void set_standard(struct pvr2_hdw *hdw)
v4l2_std_id vs;
vs = hdw->std_mask_cur;
pvr2_trace(PVR2_TRACE_CHIPS,
- "i2c v4l2 set_standard(0x%llx)",(__u64)vs);
+ "i2c v4l2 set_standard(0x%llx)",(long long unsigned)vs);
pvr2_i2c_core_cmd(hdw,VIDIOC_S_STD,&vs);
}
diff --git a/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c b/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c
index 7fca47982277..3b9012f8e380 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c
@@ -185,8 +185,6 @@ static int pvr2_i2c_basic_op(struct pvr2_hdw *hdw,
}
}
-#ifdef CONFIG_VIDEO_PVRUSB2_24XXX
-
/* This is a special entry point that is entered if an I2C operation is
attempted to a wm8775 chip on model 24xxx hardware. Autodetect of this
part doesn't work, but we know it is really there. So let's look for
@@ -289,8 +287,6 @@ static int i2c_hack_cx25840(struct pvr2_hdw *hdw,
return -EIO;
}
-#endif /* CONFIG_VIDEO_PVRUSB2_24XXX */
-
/* This is a very, very limited I2C adapter implementation. We can only
support what we actually know will work on the device... */
static int pvr2_i2c_xfer(struct i2c_adapter *i2c_adap,
@@ -897,14 +893,12 @@ void pvr2_i2c_core_init(struct pvr2_hdw *hdw)
hdw->i2c_func[idx] = pvr2_i2c_basic_op;
}
-#ifdef CONFIG_VIDEO_PVRUSB2_24XXX
// If however we're dealing with new hardware, insert some hacks in
// the I2C transfer stack to let things work better.
if (hdw->hdw_type == PVR2_HDW_TYPE_24XXX) {
hdw->i2c_func[0x1b] = i2c_hack_wm8775;
hdw->i2c_func[0x44] = i2c_hack_cx25840;
}
-#endif
// Configure the adapter and set up everything else related to it.
memcpy(&hdw->i2c_adap,&pvr2_i2c_adap_template,sizeof(hdw->i2c_adap));
diff --git a/drivers/media/video/pvrusb2/pvrusb2-main.c b/drivers/media/video/pvrusb2/pvrusb2-main.c
index 8f1a5afdd34e..e976c484c058 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-main.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-main.c
@@ -20,7 +20,6 @@
*
*/
-#include <linux/config.h>
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/slab.h>
diff --git a/drivers/media/video/pvrusb2/pvrusb2-sysfs.c b/drivers/media/video/pvrusb2/pvrusb2-sysfs.c
index d1dda5caf406..c294f46db9b9 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-sysfs.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-sysfs.c
@@ -19,7 +19,6 @@
*
*/
-#include <linux/config.h>
#include <linux/string.h>
#include <linux/slab.h>
#include <asm/semaphore.h>
@@ -40,8 +39,6 @@ struct pvr2_sysfs {
#endif /* CONFIG_VIDEO_PVRUSB2_DEBUGIFC */
struct pvr2_sysfs_ctl_item *item_first;
struct pvr2_sysfs_ctl_item *item_last;
- struct sysfs_ops kops;
- struct kobj_type ktype;
struct class_device_attribute attr_v4l_minor_number;
struct class_device_attribute attr_unit_number;
int v4l_minor_number_created_ok;
diff --git a/drivers/media/video/pvrusb2/pvrusb2-v4l2.c b/drivers/media/video/pvrusb2/pvrusb2-v4l2.c
index 0caf70b8c0de..3608c2f81df9 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-v4l2.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-v4l2.c
@@ -459,18 +459,26 @@ static int pvr2_v4l2_do_ioctl(struct inode *inode, struct file *file,
ret = 0;
switch(vf->type) {
case V4L2_BUF_TYPE_VIDEO_CAPTURE: {
+ int lmin,lmax;
+ struct pvr2_ctrl *hcp,*vcp;
int h = vf->fmt.pix.height;
int w = vf->fmt.pix.width;
-
- if (h < 200) {
- h = 200;
- } else if (h > 625) {
- h = 625;
+ hcp = pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_HRES);
+ vcp = pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_VRES);
+
+ lmin = pvr2_ctrl_get_min(hcp);
+ lmax = pvr2_ctrl_get_max(hcp);
+ if (w < lmin) {
+ w = lmin;
+ } else if (w > lmax) {
+ w = lmax;
}
- if (w < 320) {
- w = 320;
- } else if (w > 720) {
- w = 720;
+ lmin = pvr2_ctrl_get_min(vcp);
+ lmax = pvr2_ctrl_get_max(vcp);
+ if (h < lmin) {
+ h = lmin;
+ } else if (h > lmax) {
+ h = lmax;
}
memcpy(vf, &pvr_format[PVR_FORMAT_PIX],
@@ -479,14 +487,8 @@ static int pvr2_v4l2_do_ioctl(struct inode *inode, struct file *file,
vf->fmt.pix.height = h;
if (cmd == VIDIOC_S_FMT) {
- pvr2_ctrl_set_value(
- pvr2_hdw_get_ctrl_by_id(hdw,
- PVR2_CID_HRES),
- vf->fmt.pix.width);
- pvr2_ctrl_set_value(
- pvr2_hdw_get_ctrl_by_id(hdw,
- PVR2_CID_VRES),
- vf->fmt.pix.height);
+ pvr2_ctrl_set_value(hcp,vf->fmt.pix.width);
+ pvr2_ctrl_set_value(vcp,vf->fmt.pix.height);
}
} break;
case V4L2_BUF_TYPE_VBI_CAPTURE:
diff --git a/drivers/media/video/saa5246a.c b/drivers/media/video/saa5246a.c
index 59a187272c83..77bb940a1a4f 100644
--- a/drivers/media/video/saa5246a.c
+++ b/drivers/media/video/saa5246a.c
@@ -830,7 +830,6 @@ static struct video_device saa_template =
.owner = THIS_MODULE,
.name = IF_NAME,
.type = VID_TYPE_TELETEXT,
- .hardware = VID_HARDWARE_SAA5249,
.fops = &saa_fops,
.release = video_device_release,
.minor = -1,
diff --git a/drivers/media/video/saa5249.c b/drivers/media/video/saa5249.c
index 19a8d65699f8..bb3fb4387f65 100644
--- a/drivers/media/video/saa5249.c
+++ b/drivers/media/video/saa5249.c
@@ -713,7 +713,6 @@ static struct video_device saa_template =
.owner = THIS_MODULE,
.name = IF_NAME,
.type = VID_TYPE_TELETEXT, /*| VID_TYPE_TUNER ?? */
- .hardware = VID_HARDWARE_SAA5249,
.fops = &saa_fops,
};
diff --git a/drivers/media/video/saa7115.c b/drivers/media/video/saa7115.c
index b59c11717273..974179d4d389 100644
--- a/drivers/media/video/saa7115.c
+++ b/drivers/media/video/saa7115.c
@@ -1,4 +1,6 @@
-/* saa7115 - Philips SAA7113/SAA7114/SAA7115 video decoder driver
+/* saa711x - Philips SAA711x video decoder driver
+ * This driver can work with saa7111, saa7111a, saa7113, saa7114,
+ * saa7115 and saa7118.
*
* Based on saa7114 driver by Maxim Yevtyushkin, which is based on
* the saa7111 driver by Dave Perks.
@@ -16,7 +18,9 @@
* (2/17/2003)
*
* VBI support (2004) and cleanups (2005) by Hans Verkuil <hverkuil@xs4all.nl>
- * SAA7113 support by Mauro Carvalho Chehab <mchehab@infradead.org>
+ *
+ * Copyright (c) 2005-2006 Mauro Carvalho Chehab <mchehab@infradead.org>
+ * SAA7111, SAA7113 and SAA7118 support
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -33,6 +37,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
+#include "saa711x_regs.h"
#include <linux/kernel.h>
#include <linux/module.h>
@@ -43,7 +48,9 @@
#include <media/saa7115.h>
#include <asm/div64.h>
-MODULE_DESCRIPTION("Philips SAA7113/SAA7114/SAA7115 video decoder driver");
+#define VRES_60HZ (480+16)
+
+MODULE_DESCRIPTION("Philips SAA7111/SAA7113/SAA7114/SAA7115/SAA7118 video decoder driver");
MODULE_AUTHOR( "Maxim Yevtyushkin, Kevin Thayer, Chris Kennedy, "
"Hans Verkuil, Mauro Carvalho Chehab");
MODULE_LICENSE("GPL");
@@ -54,14 +61,14 @@ module_param(debug, bool, 0644);
MODULE_PARM_DESC(debug, "Debug level (0-1)");
static unsigned short normal_i2c[] = {
- 0x4a >> 1, 0x48 >> 1, /* SAA7113 */
- 0x42 >> 1, 0x40 >> 1, /* SAA7114 and SAA7115 */
+ 0x4a >> 1, 0x48 >> 1, /* SAA7111, SAA7111A and SAA7113 */
+ 0x42 >> 1, 0x40 >> 1, /* SAA7114, SAA7115 and SAA7118 */
I2C_CLIENT_END };
I2C_CLIENT_INSMOD;
-struct saa7115_state {
+struct saa711x_state {
v4l2_std_id std;
int input;
int enable;
@@ -70,6 +77,8 @@ struct saa7115_state {
int contrast;
int hue;
int sat;
+ int width;
+ int height;
enum v4l2_chip_ident ident;
u32 audclk_freq;
u32 crystal_freq;
@@ -80,420 +89,508 @@ struct saa7115_state {
/* ----------------------------------------------------------------------- */
-static inline int saa7115_write(struct i2c_client *client, u8 reg, u8 value)
+static inline int saa711x_write(struct i2c_client *client, u8 reg, u8 value)
{
return i2c_smbus_write_byte_data(client, reg, value);
}
-static int saa7115_writeregs(struct i2c_client *client, const unsigned char *regs)
+/* Sanity routine to check if a register is present */
+static int saa711x_has_reg(const int id, const u8 reg)
{
+ if (id == V4L2_IDENT_SAA7111)
+ return reg < 0x20 && reg != 0x01 && reg != 0x0f &&
+ (reg < 0x13 || reg > 0x19) && reg != 0x1d && reg != 0x1e;
+
+ /* common for saa7113/4/5/8 */
+ if (unlikely((reg >= 0x3b && reg <= 0x3f) || reg == 0x5c || reg == 0x5f ||
+ reg == 0xa3 || reg == 0xa7 || reg == 0xab || reg == 0xaf || (reg >= 0xb5 && reg <= 0xb7) ||
+ reg == 0xd3 || reg == 0xd7 || reg == 0xdb || reg == 0xdf || (reg >= 0xe5 && reg <= 0xe7) ||
+ reg == 0x82 || (reg >= 0x89 && reg <= 0x8e)))
+ return 0;
+
+ switch (id) {
+ case V4L2_IDENT_SAA7113:
+ return reg != 0x14 && (reg < 0x18 || reg > 0x1e) && (reg < 0x20 || reg > 0x3f) &&
+ reg != 0x5d && reg < 0x63;
+ case V4L2_IDENT_SAA7114:
+ return (reg < 0x1a || reg > 0x1e) && (reg < 0x20 || reg > 0x2f) &&
+ (reg < 0x63 || reg > 0x7f) && reg != 0x33 && reg != 0x37 &&
+ reg != 0x81 && reg < 0xf0;
+ case V4L2_IDENT_SAA7115:
+ return (reg < 0x20 || reg > 0x2f) && reg != 0x65 && (reg < 0xfc || reg > 0xfe);
+ case V4L2_IDENT_SAA7118:
+ return (reg < 0x1a || reg > 0x1d) && (reg < 0x20 || reg > 0x22) &&
+ (reg < 0x26 || reg > 0x28) && reg != 0x33 && reg != 0x37 &&
+ (reg < 0x63 || reg > 0x7f) && reg != 0x81 && reg < 0xf0;
+ }
+ return 1;
+}
+
+static int saa711x_writeregs(struct i2c_client *client, const unsigned char *regs)
+{
+ struct saa711x_state *state = i2c_get_clientdata(client);
unsigned char reg, data;
while (*regs != 0x00) {
reg = *(regs++);
data = *(regs++);
- if (saa7115_write(client, reg, data) < 0)
- return -1;
+
+ /* According with datasheets, reserved regs should be
+ filled with 0 - seems better not to touch on they */
+ if (saa711x_has_reg(state->ident,reg)) {
+ if (saa711x_write(client, reg, data) < 0)
+ return -1;
+ } else {
+ v4l_dbg(1, debug, client, "tried to access reserved reg 0x%02x\n", reg);
+ }
}
return 0;
}
-static inline int saa7115_read(struct i2c_client *client, u8 reg)
+static inline int saa711x_read(struct i2c_client *client, u8 reg)
{
return i2c_smbus_read_byte_data(client, reg);
}
/* ----------------------------------------------------------------------- */
+/* SAA7111 initialization table */
+static const unsigned char saa7111_init[] = {
+ R_01_INC_DELAY, 0x00, /* reserved */
+
+ /*front end */
+ R_02_INPUT_CNTL_1, 0xd0, /* FUSE=3, GUDL=2, MODE=0 */
+ R_03_INPUT_CNTL_2, 0x23, /* HLNRS=0, VBSL=1, WPOFF=0, HOLDG=0,
+ * GAFIX=0, GAI1=256, GAI2=256 */
+ R_04_INPUT_CNTL_3, 0x00, /* GAI1=256 */
+ R_05_INPUT_CNTL_4, 0x00, /* GAI2=256 */
+
+ /* decoder */
+ R_06_H_SYNC_START, 0xf3, /* HSB at 13(50Hz) / 17(60Hz)
+ * pixels after end of last line */
+ R_07_H_SYNC_STOP, 0xe8, /* HSS seems to be needed to
+ * work with NTSC, too */
+ R_08_SYNC_CNTL, 0xc8, /* AUFD=1, FSEL=1, EXFIL=0,
+ * VTRC=1, HPLL=0, VNOI=0 */
+ R_09_LUMA_CNTL, 0x01, /* BYPS=0, PREF=0, BPSS=0,
+ * VBLB=0, UPTCV=0, APER=1 */
+ R_0A_LUMA_BRIGHT_CNTL, 0x80,
+ R_0B_LUMA_CONTRAST_CNTL, 0x47, /* 0b - CONT=1.109 */
+ R_0C_CHROMA_SAT_CNTL, 0x40,
+ R_0D_CHROMA_HUE_CNTL, 0x00,
+ R_0E_CHROMA_CNTL_1, 0x01, /* 0e - CDTO=0, CSTD=0, DCCF=0,
+ * FCTC=0, CHBW=1 */
+ R_0F_CHROMA_GAIN_CNTL, 0x00, /* reserved */
+ R_10_CHROMA_CNTL_2, 0x48, /* 10 - OFTS=1, HDEL=0, VRLN=1, YDEL=0 */
+ R_11_MODE_DELAY_CNTL, 0x1c, /* 11 - GPSW=0, CM99=0, FECO=0, COMPO=1,
+ * OEYC=1, OEHV=1, VIPB=0, COLO=0 */
+ R_12_RT_SIGNAL_CNTL, 0x00, /* 12 - output control 2 */
+ R_13_RT_X_PORT_OUT_CNTL, 0x00, /* 13 - output control 3 */
+ R_14_ANAL_ADC_COMPAT_CNTL, 0x00,
+ R_15_VGATE_START_FID_CHG, 0x00,
+ R_16_VGATE_STOP, 0x00,
+ R_17_MISC_VGATE_CONF_AND_MSB, 0x00,
+
+ 0x00, 0x00
+};
+
+/* SAA7113 init codes */
+static const unsigned char saa7113_init[] = {
+ R_01_INC_DELAY, 0x08,
+ R_02_INPUT_CNTL_1, 0xc2,
+ R_03_INPUT_CNTL_2, 0x30,
+ R_04_INPUT_CNTL_3, 0x00,
+ R_05_INPUT_CNTL_4, 0x00,
+ R_06_H_SYNC_START, 0x89,
+ R_07_H_SYNC_STOP, 0x0d,
+ R_08_SYNC_CNTL, 0x88,
+ R_09_LUMA_CNTL, 0x01,
+ R_0A_LUMA_BRIGHT_CNTL, 0x80,
+ R_0B_LUMA_CONTRAST_CNTL, 0x47,
+ R_0C_CHROMA_SAT_CNTL, 0x40,
+ R_0D_CHROMA_HUE_CNTL, 0x00,
+ R_0E_CHROMA_CNTL_1, 0x01,
+ R_0F_CHROMA_GAIN_CNTL, 0x2a,
+ R_10_CHROMA_CNTL_2, 0x08,
+ R_11_MODE_DELAY_CNTL, 0x0c,
+ R_12_RT_SIGNAL_CNTL, 0x07,
+ R_13_RT_X_PORT_OUT_CNTL, 0x00,
+ R_14_ANAL_ADC_COMPAT_CNTL, 0x00,
+ R_15_VGATE_START_FID_CHG, 0x00,
+ R_16_VGATE_STOP, 0x00,
+ R_17_MISC_VGATE_CONF_AND_MSB, 0x00,
+
+ 0x00, 0x00
+};
+
/* If a value differs from the Hauppauge driver values, then the comment starts with
'was 0xXX' to denote the Hauppauge value. Otherwise the value is identical to what the
Hauppauge driver sets. */
+/* SAA7114 and SAA7115 initialization table */
static const unsigned char saa7115_init_auto_input[] = {
/* Front-End Part */
- 0x01, 0x48, /* white peak control disabled */
- 0x03, 0x20, /* was 0x30. 0x20: long vertical blanking */
- 0x04, 0x90, /* analog gain set to 0 */
- 0x05, 0x90, /* analog gain set to 0 */
+ R_01_INC_DELAY, 0x48, /* white peak control disabled */
+ R_03_INPUT_CNTL_2, 0x20, /* was 0x30. 0x20: long vertical blanking */
+ R_04_INPUT_CNTL_3, 0x90, /* analog gain set to 0 */
+ R_05_INPUT_CNTL_4, 0x90, /* analog gain set to 0 */
/* Decoder Part */
- 0x06, 0xeb, /* horiz sync begin = -21 */
- 0x07, 0xe0, /* horiz sync stop = -17 */
- 0x0a, 0x80, /* was 0x88. decoder brightness, 0x80 is itu standard */
- 0x0b, 0x44, /* was 0x48. decoder contrast, 0x44 is itu standard */
- 0x0c, 0x40, /* was 0x47. decoder saturation, 0x40 is itu standard */
- 0x0d, 0x00, /* chrominance hue control */
- 0x0f, 0x00, /* chrominance gain control: use automicatic mode */
- 0x10, 0x06, /* chrominance/luminance control: active adaptive combfilter */
- 0x11, 0x00, /* delay control */
- 0x12, 0x9d, /* RTS0 output control: VGATE */
- 0x13, 0x80, /* X-port output control: ITU656 standard mode, RTCO output enable RTCE */
- 0x14, 0x00, /* analog/ADC/auto compatibility control */
- 0x18, 0x40, /* raw data gain 0x00 = nominal */
- 0x19, 0x80, /* raw data offset 0x80 = 0 LSB */
- 0x1a, 0x77, /* color killer level control 0x77 = recommended */
- 0x1b, 0x42, /* misc chroma control 0x42 = recommended */
- 0x1c, 0xa9, /* combfilter control 0xA9 = recommended */
- 0x1d, 0x01, /* combfilter control 0x01 = recommended */
+ R_06_H_SYNC_START, 0xeb, /* horiz sync begin = -21 */
+ R_07_H_SYNC_STOP, 0xe0, /* horiz sync stop = -17 */
+ R_09_LUMA_CNTL, 0x53, /* 0x53, was 0x56 for 60hz. luminance control */
+ R_0A_LUMA_BRIGHT_CNTL, 0x80, /* was 0x88. decoder brightness, 0x80 is itu standard */
+ R_0B_LUMA_CONTRAST_CNTL, 0x44, /* was 0x48. decoder contrast, 0x44 is itu standard */
+ R_0C_CHROMA_SAT_CNTL, 0x40, /* was 0x47. decoder saturation, 0x40 is itu standard */
+ R_0D_CHROMA_HUE_CNTL, 0x00,
+ R_0F_CHROMA_GAIN_CNTL, 0x00, /* use automatic gain */
+ R_10_CHROMA_CNTL_2, 0x06, /* chroma: active adaptive combfilter */
+ R_11_MODE_DELAY_CNTL, 0x00,
+ R_12_RT_SIGNAL_CNTL, 0x9d, /* RTS0 output control: VGATE */
+ R_13_RT_X_PORT_OUT_CNTL, 0x80, /* ITU656 standard mode, RTCO output enable RTCE */
+ R_14_ANAL_ADC_COMPAT_CNTL, 0x00,
+ R_18_RAW_DATA_GAIN_CNTL, 0x40, /* gain 0x00 = nominal */
+ R_19_RAW_DATA_OFF_CNTL, 0x80,
+ R_1A_COLOR_KILL_LVL_CNTL, 0x77, /* recommended value */
+ R_1B_MISC_TVVCRDET, 0x42, /* recommended value */
+ R_1C_ENHAN_COMB_CTRL1, 0xa9, /* recommended value */
+ R_1D_ENHAN_COMB_CTRL2, 0x01, /* recommended value */
+
+
+ R_80_GLOBAL_CNTL_1, 0x0, /* No tasks enabled at init */
/* Power Device Control */
- 0x88, 0xd0, /* reset device */
- 0x88, 0xf0, /* set device programmed, all in operational mode */
+ R_88_POWER_SAVE_ADC_PORT_CNTL, 0xd0, /* reset device */
+ R_88_POWER_SAVE_ADC_PORT_CNTL, 0xf0, /* set device programmed, all in operational mode */
0x00, 0x00
};
+/* Used to reset saa7113, saa7114 and saa7115 */
static const unsigned char saa7115_cfg_reset_scaler[] = {
- 0x87, 0x00, /* disable I-port output */
- 0x88, 0xd0, /* reset scaler */
- 0x88, 0xf0, /* activate scaler */
- 0x87, 0x01, /* enable I-port output */
+ R_87_I_PORT_I_O_ENA_OUT_CLK_AND_GATED, 0x00, /* disable I-port output */
+ R_88_POWER_SAVE_ADC_PORT_CNTL, 0xd0, /* reset scaler */
+ R_88_POWER_SAVE_ADC_PORT_CNTL, 0xf0, /* activate scaler */
+ R_87_I_PORT_I_O_ENA_OUT_CLK_AND_GATED, 0x01, /* enable I-port output */
0x00, 0x00
};
/* ============== SAA7715 VIDEO templates ============= */
-static const unsigned char saa7115_cfg_60hz_fullres_x[] = {
- 0xcc, 0xd0, /* hsize low (output), hor. output window size = 0x2d0 = 720 */
- 0xcd, 0x02, /* hsize hi (output) */
+static const unsigned char saa7115_cfg_60hz_video[] = {
+ R_80_GLOBAL_CNTL_1, 0x00, /* reset tasks */
+ R_88_POWER_SAVE_ADC_PORT_CNTL, 0xd0, /* reset scaler */
- /* Why not in 60hz-Land, too? */
- 0xd0, 0x01, /* downscale = 1 */
- 0xd8, 0x00, /* hor lum scaling 0x0400 = 1 */
- 0xd9, 0x04,
- 0xdc, 0x00, /* hor chrom scaling 0x0200. must be hor lum scaling / 2 */
- 0xdd, 0x02, /* H-scaling incr chroma */
+ R_15_VGATE_START_FID_CHG, 0x03,
+ R_16_VGATE_STOP, 0x11,
+ R_17_MISC_VGATE_CONF_AND_MSB, 0x9c,
- 0x00, 0x00
-};
-static const unsigned char saa7115_cfg_60hz_fullres_y[] = {
- 0xce, 0xf8, /* vsize low (output), ver. output window size = 248 (but 60hz is 240?) */
- 0xcf, 0x00, /* vsize hi (output) */
+ R_08_SYNC_CNTL, 0x68, /* 0xBO: auto detection, 0x68 = NTSC */
+ R_0E_CHROMA_CNTL_1, 0x07, /* video autodetection is on */
- /* Why not in 60hz-Land, too? */
- 0xd5, 0x40, /* Lum contrast, nominal value = 0x40 */
- 0xd6, 0x40, /* Chroma satur. nominal value = 0x80 */
+ R_5A_V_OFF_FOR_SLICER, 0x06, /* standard 60hz value for ITU656 line counting */
- 0xe0, 0x00, /* V-scaling incr luma low */
- 0xe1, 0x04, /* " hi */
- 0xe2, 0x00, /* V-scaling incr chroma low */
- 0xe3, 0x04, /* " hi */
+ /* Task A */
+ R_90_A_TASK_HANDLING_CNTL, 0x80,
+ R_91_A_X_PORT_FORMATS_AND_CONF, 0x48,
+ R_92_A_X_PORT_INPUT_REFERENCE_SIGNAL, 0x40,
+ R_93_A_I_PORT_OUTPUT_FORMATS_AND_CONF, 0x84,
- 0x00, 0x00
-};
+ /* hoffset low (input), 0x0002 is minimum */
+ R_94_A_HORIZ_INPUT_WINDOW_START, 0x01,
+ R_95_A_HORIZ_INPUT_WINDOW_START_MSB, 0x00,
-static const unsigned char saa7115_cfg_60hz_video[] = {
- 0x80, 0x00, /* reset tasks */
- 0x88, 0xd0, /* reset scaler */
+ /* hsize low (input), 0x02d0 = 720 */
+ R_96_A_HORIZ_INPUT_WINDOW_LENGTH, 0xd0,
+ R_97_A_HORIZ_INPUT_WINDOW_LENGTH_MSB, 0x02,
- 0x15, 0x03, /* VGATE pulse start */
- 0x16, 0x11, /* VGATE pulse stop */
- 0x17, 0x9c, /* VGATE MSB and other values */
+ R_98_A_VERT_INPUT_WINDOW_START, 0x05,
+ R_99_A_VERT_INPUT_WINDOW_START_MSB, 0x00,
- 0x08, 0x68, /* 0xBO: auto detection, 0x68 = NTSC */
- 0x0e, 0x07, /* lots of different stuff... video autodetection is on */
+ R_9A_A_VERT_INPUT_WINDOW_LENGTH, 0x0c,
+ R_9B_A_VERT_INPUT_WINDOW_LENGTH_MSB, 0x00,
- 0x5a, 0x06, /* Vertical offset, standard 60hz value for ITU656 line counting */
+ R_9C_A_HORIZ_OUTPUT_WINDOW_LENGTH, 0xa0,
+ R_9D_A_HORIZ_OUTPUT_WINDOW_LENGTH_MSB, 0x05,
- /* Task A */
- 0x90, 0x80, /* Task Handling Control */
- 0x91, 0x48, /* X-port formats/config */
- 0x92, 0x40, /* Input Ref. signal Def. */
- 0x93, 0x84, /* I-port config */
- 0x94, 0x01, /* hoffset low (input), 0x0002 is minimum */
- 0x95, 0x00, /* hoffset hi (input) */
- 0x96, 0xd0, /* hsize low (input), 0x02d0 = 720 */
- 0x97, 0x02, /* hsize hi (input) */
- 0x98, 0x05, /* voffset low (input) */
- 0x99, 0x00, /* voffset hi (input) */
- 0x9a, 0x0c, /* vsize low (input), 0x0c = 12 */
- 0x9b, 0x00, /* vsize hi (input) */
- 0x9c, 0xa0, /* hsize low (output), 0x05a0 = 1440 */
- 0x9d, 0x05, /* hsize hi (output) */
- 0x9e, 0x0c, /* vsize low (output), 0x0c = 12 */
- 0x9f, 0x00, /* vsize hi (output) */
+ R_9E_A_VERT_OUTPUT_WINDOW_LENGTH, 0x0c,
+ R_9F_A_VERT_OUTPUT_WINDOW_LENGTH_MSB, 0x00,
/* Task B */
- 0xc0, 0x00, /* Task Handling Control */
- 0xc1, 0x08, /* X-port formats/config */
- 0xc2, 0x00, /* Input Ref. signal Def. */
- 0xc3, 0x80, /* I-port config */
- 0xc4, 0x02, /* hoffset low (input), 0x0002 is minimum */
- 0xc5, 0x00, /* hoffset hi (input) */
- 0xc6, 0xd0, /* hsize low (input), 0x02d0 = 720 */
- 0xc7, 0x02, /* hsize hi (input) */
- 0xc8, 0x12, /* voffset low (input), 0x12 = 18 */
- 0xc9, 0x00, /* voffset hi (input) */
- 0xca, 0xf8, /* vsize low (input), 0xf8 = 248 */
- 0xcb, 0x00, /* vsize hi (input) */
- 0xcc, 0xd0, /* hsize low (output), 0x02d0 = 720 */
- 0xcd, 0x02, /* hsize hi (output) */
-
- 0xf0, 0xad, /* Set PLL Register. 60hz 525 lines per frame, 27 MHz */
- 0xf1, 0x05, /* low bit with 0xF0 */
- 0xf5, 0xad, /* Set pulse generator register */
- 0xf6, 0x01,
-
- 0x87, 0x00, /* Disable I-port output */
- 0x88, 0xd0, /* reset scaler */
- 0x80, 0x20, /* Activate only task "B", continuous mode (was 0xA0) */
- 0x88, 0xf0, /* activate scaler */
- 0x87, 0x01, /* Enable I-port output */
- 0x00, 0x00
-};
+ R_C0_B_TASK_HANDLING_CNTL, 0x00,
+ R_C1_B_X_PORT_FORMATS_AND_CONF, 0x08,
+ R_C2_B_INPUT_REFERENCE_SIGNAL_DEFINITION, 0x00,
+ R_C3_B_I_PORT_FORMATS_AND_CONF, 0x80,
-static const unsigned char saa7115_cfg_50hz_fullres_x[] = {
- 0xcc, 0xd0, /* hsize low (output), 720 same as 60hz */
- 0xcd, 0x02, /* hsize hi (output) */
+ /* 0x0002 is minimum */
+ R_C4_B_HORIZ_INPUT_WINDOW_START, 0x02,
+ R_C5_B_HORIZ_INPUT_WINDOW_START_MSB, 0x00,
- 0xd0, 0x01, /* down scale = 1 */
- 0xd8, 0x00, /* hor lum scaling 0x0400 = 1 */
- 0xd9, 0x04,
- 0xdc, 0x00, /* hor chrom scaling 0x0200. must be hor lum scaling / 2 */
- 0xdd, 0x02, /* H-scaling incr chroma */
+ /* 0x02d0 = 720 */
+ R_C6_B_HORIZ_INPUT_WINDOW_LENGTH, 0xd0,
+ R_C7_B_HORIZ_INPUT_WINDOW_LENGTH_MSB, 0x02,
- 0x00, 0x00
-};
-static const unsigned char saa7115_cfg_50hz_fullres_y[] = {
- 0xce, 0x20, /* vsize low (output), 0x0120 = 288 */
- 0xcf, 0x01, /* vsize hi (output) */
+ /* vwindow start 0x12 = 18 */
+ R_C8_B_VERT_INPUT_WINDOW_START, 0x12,
+ R_C9_B_VERT_INPUT_WINDOW_START_MSB, 0x00,
+
+ /* vwindow length 0xf8 = 248 */
+ R_CA_B_VERT_INPUT_WINDOW_LENGTH, VRES_60HZ>>1,
+ R_CB_B_VERT_INPUT_WINDOW_LENGTH_MSB, VRES_60HZ>>9,
- 0xd5, 0x40, /* Lum contrast, nominal value = 0x40 */
- 0xd6, 0x40, /* Chroma satur. nominal value = 0x80 */
+ /* hwindow 0x02d0 = 720 */
+ R_CC_B_HORIZ_OUTPUT_WINDOW_LENGTH, 0xd0,
+ R_CD_B_HORIZ_OUTPUT_WINDOW_LENGTH_MSB, 0x02,
- 0xe0, 0x00, /* V-scaling incr luma low */
- 0xe1, 0x04, /* " hi */
- 0xe2, 0x00, /* V-scaling incr chroma low */
- 0xe3, 0x04, /* " hi */
+ R_F0_LFCO_PER_LINE, 0xad, /* Set PLL Register. 60hz 525 lines per frame, 27 MHz */
+ R_F1_P_I_PARAM_SELECT, 0x05, /* low bit with 0xF0 */
+ R_F5_PULSGEN_LINE_LENGTH, 0xad,
+ R_F6_PULSE_A_POS_LSB_AND_PULSEGEN_CONFIG, 0x01,
0x00, 0x00
};
static const unsigned char saa7115_cfg_50hz_video[] = {
- 0x80, 0x00, /* reset tasks */
- 0x88, 0xd0, /* reset scaler */
+ R_80_GLOBAL_CNTL_1, 0x00,
+ R_88_POWER_SAVE_ADC_PORT_CNTL, 0xd0, /* reset scaler */
- 0x15, 0x37, /* VGATE start */
- 0x16, 0x16, /* VGATE stop */
- 0x17, 0x99, /* VGATE MSB and other values */
+ R_15_VGATE_START_FID_CHG, 0x37, /* VGATE start */
+ R_16_VGATE_STOP, 0x16,
+ R_17_MISC_VGATE_CONF_AND_MSB, 0x99,
- 0x08, 0x28, /* 0x28 = PAL */
- 0x0e, 0x07, /* chrominance control 1 */
+ R_08_SYNC_CNTL, 0x28, /* 0x28 = PAL */
+ R_0E_CHROMA_CNTL_1, 0x07,
- 0x5a, 0x03, /* Vertical offset, standard 50hz value */
+ R_5A_V_OFF_FOR_SLICER, 0x03, /* standard 50hz value */
/* Task A */
- 0x90, 0x81, /* Task Handling Control */
- 0x91, 0x48, /* X-port formats/config */
- 0x92, 0x40, /* Input Ref. signal Def. */
- 0x93, 0x84, /* I-port config */
+ R_90_A_TASK_HANDLING_CNTL, 0x81,
+ R_91_A_X_PORT_FORMATS_AND_CONF, 0x48,
+ R_92_A_X_PORT_INPUT_REFERENCE_SIGNAL, 0x40,
+ R_93_A_I_PORT_OUTPUT_FORMATS_AND_CONF, 0x84,
+
/* This is weird: the datasheet says that you should use 2 as the minimum value, */
/* but Hauppauge uses 0, and changing that to 2 causes indeed problems (for 50hz) */
- 0x94, 0x00, /* hoffset low (input), 0x0002 is minimum */
- 0x95, 0x00, /* hoffset hi (input) */
- 0x96, 0xd0, /* hsize low (input), 0x02d0 = 720 */
- 0x97, 0x02, /* hsize hi (input) */
- 0x98, 0x03, /* voffset low (input) */
- 0x99, 0x00, /* voffset hi (input) */
- 0x9a, 0x12, /* vsize low (input), 0x12 = 18 */
- 0x9b, 0x00, /* vsize hi (input) */
- 0x9c, 0xa0, /* hsize low (output), 0x05a0 = 1440 */
- 0x9d, 0x05, /* hsize hi (output) */
- 0x9e, 0x12, /* vsize low (output), 0x12 = 18 */
- 0x9f, 0x00, /* vsize hi (output) */
+ /* hoffset low (input), 0x0002 is minimum */
+ R_94_A_HORIZ_INPUT_WINDOW_START, 0x00,
+ R_95_A_HORIZ_INPUT_WINDOW_START_MSB, 0x00,
+
+ /* hsize low (input), 0x02d0 = 720 */
+ R_96_A_HORIZ_INPUT_WINDOW_LENGTH, 0xd0,
+ R_97_A_HORIZ_INPUT_WINDOW_LENGTH_MSB, 0x02,
+
+ R_98_A_VERT_INPUT_WINDOW_START, 0x03,
+ R_99_A_VERT_INPUT_WINDOW_START_MSB, 0x00,
+
+ /* vsize 0x12 = 18 */
+ R_9A_A_VERT_INPUT_WINDOW_LENGTH, 0x12,
+ R_9B_A_VERT_INPUT_WINDOW_LENGTH_MSB, 0x00,
+
+ /* hsize 0x05a0 = 1440 */
+ R_9C_A_HORIZ_OUTPUT_WINDOW_LENGTH, 0xa0,
+ R_9D_A_HORIZ_OUTPUT_WINDOW_LENGTH_MSB, 0x05, /* hsize hi (output) */
+ R_9E_A_VERT_OUTPUT_WINDOW_LENGTH, 0x12, /* vsize low (output), 0x12 = 18 */
+ R_9F_A_VERT_OUTPUT_WINDOW_LENGTH_MSB, 0x00, /* vsize hi (output) */
/* Task B */
- 0xc0, 0x00, /* Task Handling Control */
- 0xc1, 0x08, /* X-port formats/config */
- 0xc2, 0x00, /* Input Ref. signal Def. */
- 0xc3, 0x80, /* I-port config */
- 0xc4, 0x00, /* hoffset low (input), 0x0002 is minimum. See comment at 0x94 above. */
- 0xc5, 0x00, /* hoffset hi (input) */
- 0xc6, 0xd0, /* hsize low (input), 0x02d0 = 720 */
- 0xc7, 0x02, /* hsize hi (input) */
- 0xc8, 0x16, /* voffset low (input), 0x16 = 22 */
- 0xc9, 0x00, /* voffset hi (input) */
- 0xca, 0x20, /* vsize low (input), 0x0120 = 288 */
- 0xcb, 0x01, /* vsize hi (input) */
- 0xcc, 0xd0, /* hsize low (output), 0x02d0 = 720 */
- 0xcd, 0x02, /* hsize hi (output) */
- 0xce, 0x20, /* vsize low (output), 0x0120 = 288 */
- 0xcf, 0x01, /* vsize hi (output) */
-
- 0xf0, 0xb0, /* Set PLL Register. 50hz 625 lines per frame, 27 MHz */
- 0xf1, 0x05, /* low bit with 0xF0, (was 0x05) */
- 0xf5, 0xb0, /* Set pulse generator register */
- 0xf6, 0x01,
-
- 0x87, 0x00, /* Disable I-port output */
- 0x88, 0xd0, /* reset scaler (was 0xD0) */
- 0x80, 0x20, /* Activate only task "B" */
- 0x88, 0xf0, /* activate scaler */
- 0x87, 0x01, /* Enable I-port output */
+ R_C0_B_TASK_HANDLING_CNTL, 0x00,
+ R_C1_B_X_PORT_FORMATS_AND_CONF, 0x08,
+ R_C2_B_INPUT_REFERENCE_SIGNAL_DEFINITION, 0x00,
+ R_C3_B_I_PORT_FORMATS_AND_CONF, 0x80,
+
+ /* This is weird: the datasheet says that you should use 2 as the minimum value, */
+ /* but Hauppauge uses 0, and changing that to 2 causes indeed problems (for 50hz) */
+ /* hoffset low (input), 0x0002 is minimum. See comment above. */
+ R_C4_B_HORIZ_INPUT_WINDOW_START, 0x00,
+ R_C5_B_HORIZ_INPUT_WINDOW_START_MSB, 0x00,
+
+ /* hsize 0x02d0 = 720 */
+ R_C6_B_HORIZ_INPUT_WINDOW_LENGTH, 0xd0,
+ R_C7_B_HORIZ_INPUT_WINDOW_LENGTH_MSB, 0x02,
+
+ /* voffset 0x16 = 22 */
+ R_C8_B_VERT_INPUT_WINDOW_START, 0x16,
+ R_C9_B_VERT_INPUT_WINDOW_START_MSB, 0x00,
+
+ /* vsize 0x0120 = 288 */
+ R_CA_B_VERT_INPUT_WINDOW_LENGTH, 0x20,
+ R_CB_B_VERT_INPUT_WINDOW_LENGTH_MSB, 0x01,
+
+ /* hsize 0x02d0 = 720 */
+ R_CC_B_HORIZ_OUTPUT_WINDOW_LENGTH, 0xd0,
+ R_CD_B_HORIZ_OUTPUT_WINDOW_LENGTH_MSB, 0x02,
+
+ R_F0_LFCO_PER_LINE, 0xb0, /* Set PLL Register. 50hz 625 lines per frame, 27 MHz */
+ R_F1_P_I_PARAM_SELECT, 0x05, /* low bit with 0xF0, (was 0x05) */
+ R_F5_PULSGEN_LINE_LENGTH, 0xb0,
+ R_F6_PULSE_A_POS_LSB_AND_PULSEGEN_CONFIG, 0x01,
+
0x00, 0x00
};
/* ============== SAA7715 VIDEO templates (end) ======= */
static const unsigned char saa7115_cfg_vbi_on[] = {
- 0x80, 0x00, /* reset tasks */
- 0x88, 0xd0, /* reset scaler */
- 0x80, 0x30, /* Activate both tasks */
- 0x88, 0xf0, /* activate scaler */
- 0x87, 0x01, /* Enable I-port output */
+ R_80_GLOBAL_CNTL_1, 0x00, /* reset tasks */
+ R_88_POWER_SAVE_ADC_PORT_CNTL, 0xd0, /* reset scaler */
+ R_80_GLOBAL_CNTL_1, 0x30, /* Activate both tasks */
+ R_88_POWER_SAVE_ADC_PORT_CNTL, 0xf0, /* activate scaler */
+ R_87_I_PORT_I_O_ENA_OUT_CLK_AND_GATED, 0x01, /* Enable I-port output */
+
0x00, 0x00
};
static const unsigned char saa7115_cfg_vbi_off[] = {
- 0x80, 0x00, /* reset tasks */
- 0x88, 0xd0, /* reset scaler */
- 0x80, 0x20, /* Activate only task "B" */
- 0x88, 0xf0, /* activate scaler */
- 0x87, 0x01, /* Enable I-port output */
- 0x00, 0x00
-};
+ R_80_GLOBAL_CNTL_1, 0x00, /* reset tasks */
+ R_88_POWER_SAVE_ADC_PORT_CNTL, 0xd0, /* reset scaler */
+ R_80_GLOBAL_CNTL_1, 0x20, /* Activate only task "B" */
+ R_88_POWER_SAVE_ADC_PORT_CNTL, 0xf0, /* activate scaler */
+ R_87_I_PORT_I_O_ENA_OUT_CLK_AND_GATED, 0x01, /* Enable I-port output */
-static const unsigned char saa7113_init_auto_input[] = {
- 0x01, 0x08, /* PH7113_INCREMENT_DELAY - (1) (1) (1) (1) IDEL3 IDEL2 IDELL1 IDEL0 */
- 0x02, 0xc2, /* PH7113_ANALOG_INPUT_CONTR_1 - FUSE1 FUSE0 GUDL1 GUDL0 MODE3 MODE2 MODE1 MODE0 */
- 0x03, 0x30, /* PH7113_ANALOG_INPUT_CONTR_2 - (1) HLNRS VBSL WPOFF HOLDG GAFIX GAI28 GAI18 */
- 0x04, 0x00, /* PH7113_ANALOG_INPUT_CONTR_3 - GAI17 GAI16 GAI15 GAI14 GAI13 GAI12 GAI11 GAI10 */
- 0x05, 0x00, /* PH7113_ANALOG_INPUT_CONTR_4 - GAI27 GAI26 GAI25 GAI24 GAI23 GAI22 GAI21 GAI20 */
- 0x06, 0x89, /* PH7113_HORIZONTAL_SYNC_START - HSB7 HSB6 HSB5 HSB4 HSB3 HSB2 HSB1 HSB0 */
- 0x07, 0x0d, /* PH7113_HORIZONTAL_SYNC_STOP - HSS7 HSS6 HSS5 HSS4 HSS3 HSS2 HSS1 HSS0 */
- 0x08, 0x88, /* PH7113_SYNC_CONTROL - AUFD FSEL FOET HTC1 HTC0 HPLL VNOI1 VNOI0 */
- 0x09, 0x01, /* PH7113_LUMINANCE_CONTROL - BYPS PREF BPSS1 BPSS0 VBLB UPTCV APER1 APER0 */
- 0x0a, 0x80, /* PH7113_LUMINANCE_BRIGHTNESS - BRIG7 BRIG6 BRIG5 BRIG4 BRIG3 BRIG2 BRIG1 BRIG0 */
- 0x0b, 0x47, /* PH7113_LUMINANCE_CONTRAST - CONT7 CONT6 CONT5 CONT4 CONT3 CONT2 CONT1 CONT0 */
- 0x0c, 0x40, /* PH7113_CHROMA_SATURATION - SATN7 SATN6 SATN5 SATN4 SATN3 SATN2 SATN1 SATN0 */
- 0x0d, 0x00, /* PH7113_CHROMA_HUE_CONTROL - HUEC7 HUEC6 HUEC5 HUEC4 HUEC3 HUEC2 HUEC1 HUEC0 */
- 0x0e, 0x01, /* PH7113_CHROMA_CONTROL - CDTO CSTD2 CSTD1 CSTD0 DCCF FCTC CHBW1 CHBW0 */
- 0x0f, 0x2a, /* PH7113_CHROMA_GAIN_CONTROL - ACGC CGAIN6 CGAIN5 CGAIN4 CGAIN3 CGAIN2 CGAIN1 CGAIN0 */
- 0x10, 0x08, /* PH7113_FORMAT_DELAY_CONTROL - OFTS1 OFTS0 HDEL1 HDEL0 VRLN YDEL2 YDEL1 YDEL0 */
- 0x11, 0x0c, /* PH7113_OUTPUT_CONTROL_1 - GPSW1 CM99 GPSW0 HLSEL OEYC OERT VIPB COLO */
- 0x12, 0x07, /* PH7113_OUTPUT_CONTROL_2 - RTSE13 RTSE12 RTSE11 RTSE10 RTSE03 RTSE02 RTSE01 RTSE00 */
- 0x13, 0x00, /* PH7113_OUTPUT_CONTROL_3 - ADLSB (1) (1) OLDSB FIDP (1) AOSL1 AOSL0 */
- 0x14, 0x00, /* RESERVED 14 - (1) (1) (1) (1) (1) (1) (1) (1) */
- 0x15, 0x00, /* PH7113_V_GATE1_START - VSTA7 VSTA6 VSTA5 VSTA4 VSTA3 VSTA2 VSTA1 VSTA0 */
- 0x16, 0x00, /* PH7113_V_GATE1_STOP - VSTO7 VSTO6 VSTO5 VSTO4 VSTO3 VSTO2 VSTO1 VSTO0 */
- 0x17, 0x00, /* PH7113_V_GATE1_MSB - (1) (1) (1) (1) (1) (1) VSTO8 VSTA8 */
0x00, 0x00
};
+
static const unsigned char saa7115_init_misc[] = {
- 0x81, 0x01, /* reg 0x15,0x16 define blanking window */
- 0x82, 0x00,
- 0x83, 0x01, /* I port settings */
- 0x84, 0x20,
- 0x85, 0x21,
- 0x86, 0xc5,
- 0x87, 0x01,
+ R_81_V_SYNC_FLD_ID_SRC_SEL_AND_RETIMED_V_F, 0x01,
+ R_83_X_PORT_I_O_ENA_AND_OUT_CLK, 0x01,
+ R_84_I_PORT_SIGNAL_DEF, 0x20,
+ R_85_I_PORT_SIGNAL_POLAR, 0x21,
+ R_86_I_PORT_FIFO_FLAG_CNTL_AND_ARBIT, 0xc5,
+ R_87_I_PORT_I_O_ENA_OUT_CLK_AND_GATED, 0x01,
/* Task A */
- 0xa0, 0x01, /* down scale = 1 */
- 0xa1, 0x00, /* prescale accumulation length = 1 */
- 0xa2, 0x00, /* dc gain and fir prefilter control */
- 0xa4, 0x80, /* Lum Brightness, nominal value = 0x80 */
- 0xa5, 0x40, /* Lum contrast, nominal value = 0x40 */
- 0xa6, 0x40, /* Chroma satur. nominal value = 0x80 */
- 0xa8, 0x00, /* hor lum scaling 0x0200 = 2 zoom */
- 0xa9, 0x02, /* note: 2 x zoom ensures that VBI lines have same length as video lines. */
- 0xaa, 0x00, /* H-phase offset Luma = 0 */
- 0xac, 0x00, /* hor chrom scaling 0x0200. must be hor lum scaling / 2 */
- 0xad, 0x01, /* H-scaling incr chroma */
- 0xae, 0x00, /* H-phase offset chroma. must be offset luma / 2 */
-
- 0xb0, 0x00, /* V-scaling incr luma low */
- 0xb1, 0x04, /* " hi */
- 0xb2, 0x00, /* V-scaling incr chroma low */
- 0xb3, 0x04, /* " hi */
- 0xb4, 0x01, /* V-scaling mode control */
- 0xb8, 0x00, /* V-phase offset chroma 00 */
- 0xb9, 0x00, /* V-phase offset chroma 01 */
- 0xba, 0x00, /* V-phase offset chroma 10 */
- 0xbb, 0x00, /* V-phase offset chroma 11 */
- 0xbc, 0x00, /* V-phase offset luma 00 */
- 0xbd, 0x00, /* V-phase offset luma 01 */
- 0xbe, 0x00, /* V-phase offset luma 10 */
- 0xbf, 0x00, /* V-phase offset luma 11 */
+ R_A0_A_HORIZ_PRESCALING, 0x01,
+ R_A1_A_ACCUMULATION_LENGTH, 0x00,
+ R_A2_A_PRESCALER_DC_GAIN_AND_FIR_PREFILTER, 0x00,
+
+ /* Configure controls at nominal value*/
+ R_A4_A_LUMA_BRIGHTNESS_CNTL, 0x80,
+ R_A5_A_LUMA_CONTRAST_CNTL, 0x40,
+ R_A6_A_CHROMA_SATURATION_CNTL, 0x40,
+
+ /* note: 2 x zoom ensures that VBI lines have same length as video lines. */
+ R_A8_A_HORIZ_LUMA_SCALING_INC, 0x00,
+ R_A9_A_HORIZ_LUMA_SCALING_INC_MSB, 0x02,
+
+ R_AA_A_HORIZ_LUMA_PHASE_OFF, 0x00,
+
+ /* must be horiz lum scaling / 2 */
+ R_AC_A_HORIZ_CHROMA_SCALING_INC, 0x00,
+ R_AD_A_HORIZ_CHROMA_SCALING_INC_MSB, 0x01,
+
+ /* must be offset luma / 2 */
+ R_AE_A_HORIZ_CHROMA_PHASE_OFF, 0x00,
+
+ R_B0_A_VERT_LUMA_SCALING_INC, 0x00,
+ R_B1_A_VERT_LUMA_SCALING_INC_MSB, 0x04,
+
+ R_B2_A_VERT_CHROMA_SCALING_INC, 0x00,
+ R_B3_A_VERT_CHROMA_SCALING_INC_MSB, 0x04,
+
+ R_B4_A_VERT_SCALING_MODE_CNTL, 0x01,
+
+ R_B8_A_VERT_CHROMA_PHASE_OFF_00, 0x00,
+ R_B9_A_VERT_CHROMA_PHASE_OFF_01, 0x00,
+ R_BA_A_VERT_CHROMA_PHASE_OFF_10, 0x00,
+ R_BB_A_VERT_CHROMA_PHASE_OFF_11, 0x00,
+
+ R_BC_A_VERT_LUMA_PHASE_OFF_00, 0x00,
+ R_BD_A_VERT_LUMA_PHASE_OFF_01, 0x00,
+ R_BE_A_VERT_LUMA_PHASE_OFF_10, 0x00,
+ R_BF_A_VERT_LUMA_PHASE_OFF_11, 0x00,
/* Task B */
- 0xd0, 0x01, /* down scale = 1 */
- 0xd1, 0x00, /* prescale accumulation length = 1 */
- 0xd2, 0x00, /* dc gain and fir prefilter control */
- 0xd4, 0x80, /* Lum Brightness, nominal value = 0x80 */
- 0xd5, 0x40, /* Lum contrast, nominal value = 0x40 */
- 0xd6, 0x40, /* Chroma satur. nominal value = 0x80 */
- 0xd8, 0x00, /* hor lum scaling 0x0400 = 1 */
- 0xd9, 0x04,
- 0xda, 0x00, /* H-phase offset Luma = 0 */
- 0xdc, 0x00, /* hor chrom scaling 0x0200. must be hor lum scaling / 2 */
- 0xdd, 0x02, /* H-scaling incr chroma */
- 0xde, 0x00, /* H-phase offset chroma. must be offset luma / 2 */
-
- 0xe0, 0x00, /* V-scaling incr luma low */
- 0xe1, 0x04, /* " hi */
- 0xe2, 0x00, /* V-scaling incr chroma low */
- 0xe3, 0x04, /* " hi */
- 0xe4, 0x01, /* V-scaling mode control */
- 0xe8, 0x00, /* V-phase offset chroma 00 */
- 0xe9, 0x00, /* V-phase offset chroma 01 */
- 0xea, 0x00, /* V-phase offset chroma 10 */
- 0xeb, 0x00, /* V-phase offset chroma 11 */
- 0xec, 0x00, /* V-phase offset luma 00 */
- 0xed, 0x00, /* V-phase offset luma 01 */
- 0xee, 0x00, /* V-phase offset luma 10 */
- 0xef, 0x00, /* V-phase offset luma 11 */
-
- 0xf2, 0x50, /* crystal clock = 24.576 MHz, target = 27MHz */
- 0xf3, 0x46,
- 0xf4, 0x00,
- 0xf7, 0x4b, /* not the recommended settings! */
- 0xf8, 0x00,
- 0xf9, 0x4b,
- 0xfa, 0x00,
- 0xfb, 0x4b,
- 0xff, 0x88, /* PLL2 lock detection settings: 71 lines 50% phase error */
+ R_D0_B_HORIZ_PRESCALING, 0x01,
+ R_D1_B_ACCUMULATION_LENGTH, 0x00,
+ R_D2_B_PRESCALER_DC_GAIN_AND_FIR_PREFILTER, 0x00,
+
+ /* Configure controls at nominal value*/
+ R_D4_B_LUMA_BRIGHTNESS_CNTL, 0x80,
+ R_D5_B_LUMA_CONTRAST_CNTL, 0x40,
+ R_D6_B_CHROMA_SATURATION_CNTL, 0x40,
+
+ /* hor lum scaling 0x0400 = 1 */
+ R_D8_B_HORIZ_LUMA_SCALING_INC, 0x00,
+ R_D9_B_HORIZ_LUMA_SCALING_INC_MSB, 0x04,
+
+ R_DA_B_HORIZ_LUMA_PHASE_OFF, 0x00,
+
+ /* must be hor lum scaling / 2 */
+ R_DC_B_HORIZ_CHROMA_SCALING, 0x00,
+ R_DD_B_HORIZ_CHROMA_SCALING_MSB, 0x02,
+
+ /* must be offset luma / 2 */
+ R_DE_B_HORIZ_PHASE_OFFSET_CRHOMA, 0x00,
+
+ R_E0_B_VERT_LUMA_SCALING_INC, 0x00,
+ R_E1_B_VERT_LUMA_SCALING_INC_MSB, 0x04,
+
+ R_E2_B_VERT_CHROMA_SCALING_INC, 0x00,
+ R_E3_B_VERT_CHROMA_SCALING_INC_MSB, 0x04,
+
+ R_E4_B_VERT_SCALING_MODE_CNTL, 0x01,
+
+ R_E8_B_VERT_CHROMA_PHASE_OFF_00, 0x00,
+ R_E9_B_VERT_CHROMA_PHASE_OFF_01, 0x00,
+ R_EA_B_VERT_CHROMA_PHASE_OFF_10, 0x00,
+ R_EB_B_VERT_CHROMA_PHASE_OFF_11, 0x00,
+
+ R_EC_B_VERT_LUMA_PHASE_OFF_00, 0x00,
+ R_ED_B_VERT_LUMA_PHASE_OFF_01, 0x00,
+ R_EE_B_VERT_LUMA_PHASE_OFF_10, 0x00,
+ R_EF_B_VERT_LUMA_PHASE_OFF_11, 0x00,
+
+ R_F2_NOMINAL_PLL2_DTO, 0x50, /* crystal clock = 24.576 MHz, target = 27MHz */
+ R_F3_PLL_INCREMENT, 0x46,
+ R_F4_PLL2_STATUS, 0x00,
+ R_F7_PULSE_A_POS_MSB, 0x4b, /* not the recommended settings! */
+ R_F8_PULSE_B_POS, 0x00,
+ R_F9_PULSE_B_POS_MSB, 0x4b,
+ R_FA_PULSE_C_POS, 0x00,
+ R_FB_PULSE_C_POS_MSB, 0x4b,
+
+ /* PLL2 lock detection settings: 71 lines 50% phase error */
+ R_FF_S_PLL_MAX_PHASE_ERR_THRESH_NUM_LINES, 0x88,
/* Turn off VBI */
- 0x40, 0x20, /* No framing code errors allowed. */
- 0x41, 0xff,
- 0x42, 0xff,
- 0x43, 0xff,
- 0x44, 0xff,
- 0x45, 0xff,
- 0x46, 0xff,
- 0x47, 0xff,
- 0x48, 0xff,
- 0x49, 0xff,
- 0x4a, 0xff,
- 0x4b, 0xff,
- 0x4c, 0xff,
- 0x4d, 0xff,
- 0x4e, 0xff,
- 0x4f, 0xff,
- 0x50, 0xff,
- 0x51, 0xff,
- 0x52, 0xff,
- 0x53, 0xff,
- 0x54, 0xff,
- 0x55, 0xff,
- 0x56, 0xff,
- 0x57, 0xff,
- 0x58, 0x40,
- 0x59, 0x47,
- 0x5b, 0x83,
- 0x5d, 0xbd,
- 0x5e, 0x35,
-
- 0x02, 0x84, /* input tuner -> input 4, amplifier active */
- 0x09, 0x53, /* 0x53, was 0x56 for 60hz. luminance control */
-
- 0x80, 0x20, /* enable task B */
- 0x88, 0xd0,
- 0x88, 0xf0,
+ R_40_SLICER_CNTL_1, 0x20, /* No framing code errors allowed. */
+ R_41_LCR_BASE, 0xff,
+ R_41_LCR_BASE+1, 0xff,
+ R_41_LCR_BASE+2, 0xff,
+ R_41_LCR_BASE+3, 0xff,
+ R_41_LCR_BASE+4, 0xff,
+ R_41_LCR_BASE+5, 0xff,
+ R_41_LCR_BASE+6, 0xff,
+ R_41_LCR_BASE+7, 0xff,
+ R_41_LCR_BASE+8, 0xff,
+ R_41_LCR_BASE+9, 0xff,
+ R_41_LCR_BASE+10, 0xff,
+ R_41_LCR_BASE+11, 0xff,
+ R_41_LCR_BASE+12, 0xff,
+ R_41_LCR_BASE+13, 0xff,
+ R_41_LCR_BASE+14, 0xff,
+ R_41_LCR_BASE+15, 0xff,
+ R_41_LCR_BASE+16, 0xff,
+ R_41_LCR_BASE+17, 0xff,
+ R_41_LCR_BASE+18, 0xff,
+ R_41_LCR_BASE+19, 0xff,
+ R_41_LCR_BASE+20, 0xff,
+ R_41_LCR_BASE+21, 0xff,
+ R_41_LCR_BASE+22, 0xff,
+ R_58_PROGRAM_FRAMING_CODE, 0x40,
+ R_59_H_OFF_FOR_SLICER, 0x47,
+ R_5B_FLD_OFF_AND_MSB_FOR_H_AND_V_OFF, 0x83,
+ R_5D_DID, 0xbd,
+ R_5E_SDID, 0x35,
+
+ R_02_INPUT_CNTL_1, 0x84, /* input tuner -> input 4, amplifier active */
+
+ R_80_GLOBAL_CNTL_1, 0x20, /* enable task B */
+ R_88_POWER_SAVE_ADC_PORT_CNTL, 0xd0,
+ R_88_POWER_SAVE_ADC_PORT_CNTL, 0xf0,
0x00, 0x00
};
-static int saa7115_odd_parity(u8 c)
+static int saa711x_odd_parity(u8 c)
{
c ^= (c >> 4);
c ^= (c >> 2);
@@ -502,7 +599,7 @@ static int saa7115_odd_parity(u8 c)
return c & 1;
}
-static int saa7115_decode_vps(u8 * dst, u8 * p)
+static int saa711x_decode_vps(u8 * dst, u8 * p)
{
static const u8 biphase_tbl[] = {
0xf0, 0x78, 0x70, 0xf0, 0xb4, 0x3c, 0x34, 0xb4,
@@ -549,7 +646,7 @@ static int saa7115_decode_vps(u8 * dst, u8 * p)
return err & 0xf0;
}
-static int saa7115_decode_wss(u8 * p)
+static int saa711x_decode_wss(u8 * p)
{
static const int wss_bits[8] = {
0, 0, 0, 1, 0, 1, 1, 1
@@ -576,26 +673,25 @@ static int saa7115_decode_wss(u8 * p)
return wss;
}
-
-static int saa7115_set_audio_clock_freq(struct i2c_client *client, u32 freq)
+static int saa711x_set_audio_clock_freq(struct i2c_client *client, u32 freq)
{
- struct saa7115_state *state = i2c_get_clientdata(client);
+ struct saa711x_state *state = i2c_get_clientdata(client);
u32 acpf;
u32 acni;
u32 hz;
u64 f;
u8 acc = 0; /* reg 0x3a, audio clock control */
+ /* Checks for chips that don't have audio clock (saa7111, saa7113) */
+ if (!saa711x_has_reg(state->ident,R_30_AUD_MAST_CLK_CYCLES_PER_FIELD))
+ return 0;
+
v4l_dbg(1, debug, client, "set audio clock freq: %d\n", freq);
/* sanity check */
if (freq < 32000 || freq > 48000)
return -EINVAL;
- /* The saa7113 has no audio clock */
- if (state->ident == V4L2_IDENT_SAA7113)
- return 0;
-
/* hz is the refresh rate times 100 */
hz = (state->std & V4L2_STD_525_60) ? 5994 : 5000;
/* acpf = (256 * freq) / field_frequency == (256 * 100 * freq) / hz */
@@ -617,22 +713,26 @@ static int saa7115_set_audio_clock_freq(struct i2c_client *client, u32 freq)
if (state->apll)
acc |= 0x08;
- saa7115_write(client, 0x38, 0x03);
- saa7115_write(client, 0x39, 0x10);
- saa7115_write(client, 0x3a, acc);
- saa7115_write(client, 0x30, acpf & 0xff);
- saa7115_write(client, 0x31, (acpf >> 8) & 0xff);
- saa7115_write(client, 0x32, (acpf >> 16) & 0x03);
- saa7115_write(client, 0x34, acni & 0xff);
- saa7115_write(client, 0x35, (acni >> 8) & 0xff);
- saa7115_write(client, 0x36, (acni >> 16) & 0x3f);
+ saa711x_write(client, R_38_CLK_RATIO_AMXCLK_TO_ASCLK, 0x03);
+ saa711x_write(client, R_39_CLK_RATIO_ASCLK_TO_ALRCLK, 0x10);
+ saa711x_write(client, R_3A_AUD_CLK_GEN_BASIC_SETUP, acc);
+
+ saa711x_write(client, R_30_AUD_MAST_CLK_CYCLES_PER_FIELD, acpf & 0xff);
+ saa711x_write(client, R_30_AUD_MAST_CLK_CYCLES_PER_FIELD+1,
+ (acpf >> 8) & 0xff);
+ saa711x_write(client, R_30_AUD_MAST_CLK_CYCLES_PER_FIELD+2,
+ (acpf >> 16) & 0x03);
+
+ saa711x_write(client, R_34_AUD_MAST_CLK_NOMINAL_INC, acni & 0xff);
+ saa711x_write(client, R_34_AUD_MAST_CLK_NOMINAL_INC+1, (acni >> 8) & 0xff);
+ saa711x_write(client, R_34_AUD_MAST_CLK_NOMINAL_INC+2, (acni >> 16) & 0x3f);
state->audclk_freq = freq;
return 0;
}
-static int saa7115_set_v4lctrl(struct i2c_client *client, struct v4l2_control *ctrl)
+static int saa711x_set_v4lctrl(struct i2c_client *client, struct v4l2_control *ctrl)
{
- struct saa7115_state *state = i2c_get_clientdata(client);
+ struct saa711x_state *state = i2c_get_clientdata(client);
switch (ctrl->id) {
case V4L2_CID_BRIGHTNESS:
@@ -642,7 +742,7 @@ static int saa7115_set_v4lctrl(struct i2c_client *client, struct v4l2_control *c
}
state->bright = ctrl->value;
- saa7115_write(client, 0x0a, state->bright);
+ saa711x_write(client, R_0A_LUMA_BRIGHT_CNTL, state->bright);
break;
case V4L2_CID_CONTRAST:
@@ -652,7 +752,7 @@ static int saa7115_set_v4lctrl(struct i2c_client *client, struct v4l2_control *c
}
state->contrast = ctrl->value;
- saa7115_write(client, 0x0b, state->contrast);
+ saa711x_write(client, R_0B_LUMA_CONTRAST_CNTL, state->contrast);
break;
case V4L2_CID_SATURATION:
@@ -662,7 +762,7 @@ static int saa7115_set_v4lctrl(struct i2c_client *client, struct v4l2_control *c
}
state->sat = ctrl->value;
- saa7115_write(client, 0x0c, state->sat);
+ saa711x_write(client, R_0C_CHROMA_SAT_CNTL, state->sat);
break;
case V4L2_CID_HUE:
@@ -672,7 +772,7 @@ static int saa7115_set_v4lctrl(struct i2c_client *client, struct v4l2_control *c
}
state->hue = ctrl->value;
- saa7115_write(client, 0x0d, state->hue);
+ saa711x_write(client, R_0D_CHROMA_HUE_CNTL, state->hue);
break;
default:
@@ -682,9 +782,9 @@ static int saa7115_set_v4lctrl(struct i2c_client *client, struct v4l2_control *c
return 0;
}
-static int saa7115_get_v4lctrl(struct i2c_client *client, struct v4l2_control *ctrl)
+static int saa711x_get_v4lctrl(struct i2c_client *client, struct v4l2_control *ctrl)
{
- struct saa7115_state *state = i2c_get_clientdata(client);
+ struct saa711x_state *state = i2c_get_clientdata(client);
switch (ctrl->id) {
case V4L2_CID_BRIGHTNESS:
@@ -706,10 +806,115 @@ static int saa7115_get_v4lctrl(struct i2c_client *client, struct v4l2_control *c
return 0;
}
-static void saa7115_set_v4lstd(struct i2c_client *client, v4l2_std_id std)
+static int saa711x_set_size(struct i2c_client *client, int width, int height)
+{
+ struct saa711x_state *state = i2c_get_clientdata(client);
+ int HPSC, HFSC;
+ int VSCY;
+ int res;
+ int is_50hz = state->std & V4L2_STD_625_50;
+ int Vsrc = is_50hz ? 576 : 480;
+
+ v4l_dbg(1, debug, client, "decoder set size to %ix%i\n",width,height);
+
+ /* FIXME need better bounds checking here */
+ if ((width < 1) || (width > 1440))
+ return -EINVAL;
+ if ((height < 1) || (height > Vsrc))
+ return -EINVAL;
+
+ if (!saa711x_has_reg(state->ident,R_D0_B_HORIZ_PRESCALING)) {
+ /* Decoder only supports 720 columns and 480 or 576 lines */
+ if (width != 720)
+ return -EINVAL;
+ if (height != Vsrc)
+ return -EINVAL;
+ }
+
+ state->width = width;
+ state->height = height;
+
+ if (!saa711x_has_reg(state->ident, R_CC_B_HORIZ_OUTPUT_WINDOW_LENGTH))
+ return 0;
+
+ /* probably have a valid size, let's set it */
+ /* Set output width/height */
+ /* width */
+
+ saa711x_write(client, R_CC_B_HORIZ_OUTPUT_WINDOW_LENGTH,
+ (u8) (width & 0xff));
+ saa711x_write(client, R_CD_B_HORIZ_OUTPUT_WINDOW_LENGTH_MSB,
+ (u8) ((width >> 8) & 0xff));
+
+ /* Vertical Scaling uses height/2 */
+ res=height/2;
+
+ /* On 60Hz, it is using a higher Vertical Output Size */
+ if (!is_50hz)
+ res+=(VRES_60HZ-480)>>1;
+
+ /* height */
+ saa711x_write(client, R_CE_B_VERT_OUTPUT_WINDOW_LENGTH,
+ (u8) (res & 0xff));
+ saa711x_write(client, R_CF_B_VERT_OUTPUT_WINDOW_LENGTH_MSB,
+ (u8) ((res >> 8) & 0xff));
+
+ /* Scaling settings */
+ /* Hprescaler is floor(inres/outres) */
+ HPSC = (int)(720 / width);
+ /* 0 is not allowed (div. by zero) */
+ HPSC = HPSC ? HPSC : 1;
+ HFSC = (int)((1024 * 720) / (HPSC * width));
+ /* FIXME hardcodes to "Task B"
+ * write H prescaler integer */
+ saa711x_write(client, R_D0_B_HORIZ_PRESCALING,
+ (u8) (HPSC & 0x3f));
+
+ v4l_dbg(1, debug, client, "Hpsc: 0x%05x, Hfsc: 0x%05x\n", HPSC, HFSC);
+ /* write H fine-scaling (luminance) */
+ saa711x_write(client, R_D8_B_HORIZ_LUMA_SCALING_INC,
+ (u8) (HFSC & 0xff));
+ saa711x_write(client, R_D9_B_HORIZ_LUMA_SCALING_INC_MSB,
+ (u8) ((HFSC >> 8) & 0xff));
+ /* write H fine-scaling (chrominance)
+ * must be lum/2, so i'll just bitshift :) */
+ saa711x_write(client, R_DC_B_HORIZ_CHROMA_SCALING,
+ (u8) ((HFSC >> 1) & 0xff));
+ saa711x_write(client, R_DD_B_HORIZ_CHROMA_SCALING_MSB,
+ (u8) ((HFSC >> 9) & 0xff));
+
+ VSCY = (int)((1024 * Vsrc) / height);
+ v4l_dbg(1, debug, client, "Vsrc: %d, Vscy: 0x%05x\n", Vsrc, VSCY);
+
+ /* Correct Contrast and Luminance */
+ saa711x_write(client, R_D5_B_LUMA_CONTRAST_CNTL,
+ (u8) (64 * 1024 / VSCY));
+ saa711x_write(client, R_D6_B_CHROMA_SATURATION_CNTL,
+ (u8) (64 * 1024 / VSCY));
+
+ /* write V fine-scaling (luminance) */
+ saa711x_write(client, R_E0_B_VERT_LUMA_SCALING_INC,
+ (u8) (VSCY & 0xff));
+ saa711x_write(client, R_E1_B_VERT_LUMA_SCALING_INC_MSB,
+ (u8) ((VSCY >> 8) & 0xff));
+ /* write V fine-scaling (chrominance) */
+ saa711x_write(client, R_E2_B_VERT_CHROMA_SCALING_INC,
+ (u8) (VSCY & 0xff));
+ saa711x_write(client, R_E3_B_VERT_CHROMA_SCALING_INC_MSB,
+ (u8) ((VSCY >> 8) & 0xff));
+
+ saa711x_writeregs(client, saa7115_cfg_reset_scaler);
+
+ /* Activates task "B" */
+ saa711x_write(client, R_80_GLOBAL_CNTL_1,
+ saa711x_read(client,R_80_GLOBAL_CNTL_1)|0x20);
+
+ return 0;
+}
+
+static void saa711x_set_v4lstd(struct i2c_client *client, v4l2_std_id std)
{
- struct saa7115_state *state = i2c_get_clientdata(client);
- int taskb = saa7115_read(client, 0x80) & 0x10;
+ struct saa711x_state *state = i2c_get_clientdata(client);
/* Prevent unnecessary standard changes. During a standard
change the I-Port is temporarily disabled. Any devices
@@ -721,17 +926,21 @@ static void saa7115_set_v4lstd(struct i2c_client *client, v4l2_std_id std)
if (std == state->std)
return;
+ state->std = std;
+
// This works for NTSC-M, SECAM-L and the 50Hz PAL variants.
if (std & V4L2_STD_525_60) {
v4l_dbg(1, debug, client, "decoder set standard 60 Hz\n");
- saa7115_writeregs(client, saa7115_cfg_60hz_video);
+ saa711x_writeregs(client, saa7115_cfg_60hz_video);
+ saa711x_set_size(client,720,480);
} else {
v4l_dbg(1, debug, client, "decoder set standard 50 Hz\n");
- saa7115_writeregs(client, saa7115_cfg_50hz_video);
+ saa711x_writeregs(client, saa7115_cfg_50hz_video);
+ saa711x_set_size(client,720,576);
}
/* Register 0E - Bits D6-D4 on NO-AUTO mode
- (SAA7113 doesn't have auto mode)
+ (SAA7111 and SAA7113 doesn't have auto mode)
50 Hz / 625 lines 60 Hz / 525 lines
000 PAL BGDHI (4.43Mhz) NTSC M (3.58MHz)
001 NTSC 4.43 (50 Hz) PAL 4.43 (60 Hz)
@@ -739,8 +948,9 @@ static void saa7115_set_v4lstd(struct i2c_client *client, v4l2_std_id std)
011 NTSC N (3.58MHz) PAL M (3.58MHz)
100 reserved NTSC-Japan (3.58MHz)
*/
- if (state->ident == V4L2_IDENT_SAA7113) {
- u8 reg = saa7115_read(client, 0x0e) & 0x8f;
+ if (state->ident == V4L2_IDENT_SAA7111 ||
+ state->ident == V4L2_IDENT_SAA7113) {
+ u8 reg = saa711x_read(client, R_0E_CHROMA_CNTL_1) & 0x8f;
if (std == V4L2_STD_PAL_M) {
reg |= 0x30;
@@ -751,31 +961,30 @@ static void saa7115_set_v4lstd(struct i2c_client *client, v4l2_std_id std)
} else if (std == V4L2_STD_NTSC_M_JP) {
reg |= 0x40;
}
- saa7115_write(client, 0x0e, reg);
- }
-
+ saa711x_write(client, R_0E_CHROMA_CNTL_1, reg);
+ } else {
+ /* restart task B if needed */
+ int taskb = saa711x_read(client, R_80_GLOBAL_CNTL_1) & 0x10;
- state->std = std;
+ if (taskb && state->ident == V4L2_IDENT_SAA7114) {
+ saa711x_writeregs(client, saa7115_cfg_vbi_on);
+ }
- /* restart task B if needed */
- if (taskb && state->ident != V4L2_IDENT_SAA7115) {
- saa7115_writeregs(client, saa7115_cfg_vbi_on);
+ /* switch audio mode too! */
+ saa711x_set_audio_clock_freq(client, state->audclk_freq);
}
-
- /* switch audio mode too! */
- saa7115_set_audio_clock_freq(client, state->audclk_freq);
}
-static v4l2_std_id saa7115_get_v4lstd(struct i2c_client *client)
+static v4l2_std_id saa711x_get_v4lstd(struct i2c_client *client)
{
- struct saa7115_state *state = i2c_get_clientdata(client);
+ struct saa711x_state *state = i2c_get_clientdata(client);
return state->std;
}
-static void saa7115_log_status(struct i2c_client *client)
+static void saa711x_log_status(struct i2c_client *client)
{
- struct saa7115_state *state = i2c_get_clientdata(client);
+ struct saa711x_state *state = i2c_get_clientdata(client);
int reg1e, reg1f;
int signalOk;
int vcr;
@@ -783,7 +992,7 @@ static void saa7115_log_status(struct i2c_client *client)
v4l_info(client, "Audio frequency: %d Hz\n", state->audclk_freq);
if (state->ident != V4L2_IDENT_SAA7115) {
/* status for the saa7114 */
- reg1f = saa7115_read(client, 0x1f);
+ reg1f = saa711x_read(client, R_1F_STATUS_BYTE_2_VD_DEC);
signalOk = (reg1f & 0xc1) == 0x81;
v4l_info(client, "Video signal: %s\n", signalOk ? "ok" : "bad");
v4l_info(client, "Frequency: %s\n", (reg1f & 0x20) ? "60 Hz" : "50 Hz");
@@ -791,8 +1000,8 @@ static void saa7115_log_status(struct i2c_client *client)
}
/* status for the saa7115 */
- reg1e = saa7115_read(client, 0x1e);
- reg1f = saa7115_read(client, 0x1f);
+ reg1e = saa711x_read(client, R_1E_STATUS_BYTE_1_VD_DEC);
+ reg1f = saa711x_read(client, R_1F_STATUS_BYTE_2_VD_DEC);
signalOk = (reg1f & 0xc1) == 0x81 && (reg1e & 0xc0) == 0x80;
vcr = !(reg1f & 0x10);
@@ -819,19 +1028,27 @@ static void saa7115_log_status(struct i2c_client *client)
v4l_info(client, "Detected format: BW/No color\n");
break;
}
+ v4l_info(client, "Width, Height: %d, %d\n", state->width, state->height);
}
/* setup the sliced VBI lcr registers according to the sliced VBI format */
-static void saa7115_set_lcr(struct i2c_client *client, struct v4l2_sliced_vbi_format *fmt)
+static void saa711x_set_lcr(struct i2c_client *client, struct v4l2_sliced_vbi_format *fmt)
{
- struct saa7115_state *state = i2c_get_clientdata(client);
+ struct saa711x_state *state = i2c_get_clientdata(client);
int is_50hz = (state->std & V4L2_STD_625_50);
u8 lcr[24];
int i, x;
- /* saa7113/7114 doesn't yet support VBI */
+#if 1
+ /* saa7113/7114/7118 VBI support are experimental */
+ if (!saa711x_has_reg(state->ident,R_41_LCR_BASE))
+ return;
+
+#else
+ /* SAA7113 and SAA7118 also should support VBI - Need testing */
if (state->ident != V4L2_IDENT_SAA7115)
return;
+#endif
for (i = 0; i <= 23; i++)
lcr[i] = 0xff;
@@ -888,14 +1105,16 @@ static void saa7115_set_lcr(struct i2c_client *client, struct v4l2_sliced_vbi_fo
/* write the lcr registers */
for (i = 2; i <= 23; i++) {
- saa7115_write(client, i - 2 + 0x41, lcr[i]);
+ saa711x_write(client, i - 2 + R_41_LCR_BASE, lcr[i]);
}
/* enable/disable raw VBI capturing */
- saa7115_writeregs(client, fmt->service_set == 0 ? saa7115_cfg_vbi_on : saa7115_cfg_vbi_off);
+ saa711x_writeregs(client, fmt->service_set == 0 ?
+ saa7115_cfg_vbi_on :
+ saa7115_cfg_vbi_off);
}
-static int saa7115_get_v4lfmt(struct i2c_client *client, struct v4l2_format *fmt)
+static int saa711x_get_v4lfmt(struct i2c_client *client, struct v4l2_format *fmt)
{
static u16 lcr2vbi[] = {
0, V4L2_SLICED_TELETEXT_B, 0, /* 1 */
@@ -911,10 +1130,10 @@ static int saa7115_get_v4lfmt(struct i2c_client *client, struct v4l2_format *fmt
return -EINVAL;
memset(sliced, 0, sizeof(*sliced));
/* done if using raw VBI */
- if (saa7115_read(client, 0x80) & 0x10)
+ if (saa711x_read(client, R_80_GLOBAL_CNTL_1) & 0x10)
return 0;
for (i = 2; i <= 23; i++) {
- u8 v = saa7115_read(client, i - 2 + 0x41);
+ u8 v = saa711x_read(client, i - 2 + R_41_LCR_BASE);
sliced->service_lines[0][i] = lcr2vbi[v >> 4];
sliced->service_lines[1][i] = lcr2vbi[v & 0xf];
@@ -924,114 +1143,31 @@ static int saa7115_get_v4lfmt(struct i2c_client *client, struct v4l2_format *fmt
return 0;
}
-static int saa7115_set_v4lfmt(struct i2c_client *client, struct v4l2_format *fmt)
+static int saa711x_set_v4lfmt(struct i2c_client *client, struct v4l2_format *fmt)
{
- struct saa7115_state *state = i2c_get_clientdata(client);
- struct v4l2_pix_format *pix;
- int HPSC, HFSC;
- int VSCY, Vsrc;
- int is_50hz = state->std & V4L2_STD_625_50;
-
if (fmt->type == V4L2_BUF_TYPE_SLICED_VBI_CAPTURE) {
- saa7115_set_lcr(client, &fmt->fmt.sliced);
+ saa711x_set_lcr(client, &fmt->fmt.sliced);
return 0;
}
if (fmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
return -EINVAL;
- pix = &(fmt->fmt.pix);
-
- v4l_dbg(1, debug, client, "decoder set size\n");
-
- /* FIXME need better bounds checking here */
- if ((pix->width < 1) || (pix->width > 1440))
- return -EINVAL;
- if ((pix->height < 1) || (pix->height > 960))
- return -EINVAL;
-
- /* probably have a valid size, let's set it */
- /* Set output width/height */
- /* width */
- saa7115_write(client, 0xcc, (u8) (pix->width & 0xff));
- saa7115_write(client, 0xcd, (u8) ((pix->width >> 8) & 0xff));
- /* height */
- saa7115_write(client, 0xce, (u8) (pix->height & 0xff));
- saa7115_write(client, 0xcf, (u8) ((pix->height >> 8) & 0xff));
-
- /* Scaling settings */
- /* Hprescaler is floor(inres/outres) */
- /* FIXME hardcoding input res */
- if (pix->width != 720) {
- HPSC = (int)(720 / pix->width);
- /* 0 is not allowed (div. by zero) */
- HPSC = HPSC ? HPSC : 1;
- HFSC = (int)((1024 * 720) / (HPSC * pix->width));
-
- v4l_dbg(1, debug, client, "Hpsc: 0x%05x, Hfsc: 0x%05x\n", HPSC, HFSC);
- /* FIXME hardcodes to "Task B"
- * write H prescaler integer */
- saa7115_write(client, 0xd0, (u8) (HPSC & 0x3f));
-
- /* write H fine-scaling (luminance) */
- saa7115_write(client, 0xd8, (u8) (HFSC & 0xff));
- saa7115_write(client, 0xd9, (u8) ((HFSC >> 8) & 0xff));
- /* write H fine-scaling (chrominance)
- * must be lum/2, so i'll just bitshift :) */
- saa7115_write(client, 0xDC, (u8) ((HFSC >> 1) & 0xff));
- saa7115_write(client, 0xDD, (u8) ((HFSC >> 9) & 0xff));
- } else {
- if (is_50hz) {
- v4l_dbg(1, debug, client, "Setting full 50hz width\n");
- saa7115_writeregs(client, saa7115_cfg_50hz_fullres_x);
- } else {
- v4l_dbg(1, debug, client, "Setting full 60hz width\n");
- saa7115_writeregs(client, saa7115_cfg_60hz_fullres_x);
- }
- }
-
- Vsrc = is_50hz ? 576 : 480;
-
- if (pix->height != Vsrc) {
- VSCY = (int)((1024 * Vsrc) / pix->height);
- v4l_dbg(1, debug, client, "Vsrc: %d, Vscy: 0x%05x\n", Vsrc, VSCY);
-
- /* Correct Contrast and Luminance */
- saa7115_write(client, 0xd5, (u8) (64 * 1024 / VSCY));
- saa7115_write(client, 0xd6, (u8) (64 * 1024 / VSCY));
-
- /* write V fine-scaling (luminance) */
- saa7115_write(client, 0xe0, (u8) (VSCY & 0xff));
- saa7115_write(client, 0xe1, (u8) ((VSCY >> 8) & 0xff));
- /* write V fine-scaling (chrominance) */
- saa7115_write(client, 0xe2, (u8) (VSCY & 0xff));
- saa7115_write(client, 0xe3, (u8) ((VSCY >> 8) & 0xff));
- } else {
- if (is_50hz) {
- v4l_dbg(1, debug, client, "Setting full 50Hz height\n");
- saa7115_writeregs(client, saa7115_cfg_50hz_fullres_y);
- } else {
- v4l_dbg(1, debug, client, "Setting full 60hz height\n");
- saa7115_writeregs(client, saa7115_cfg_60hz_fullres_y);
- }
- }
-
- saa7115_writeregs(client, saa7115_cfg_reset_scaler);
- return 0;
+ return saa711x_set_size(client,fmt->fmt.pix.width,fmt->fmt.pix.height);
}
/* Decode the sliced VBI data stream as created by the saa7115.
The format is described in the saa7115 datasheet in Tables 25 and 26
and in Figure 33.
The current implementation uses SAV/EAV codes and not the ancillary data
- headers. The vbi->p pointer points to the SDID byte right after the SAV
+ headers. The vbi->p pointer points to the R_5E_SDID byte right after the SAV
code. */
-static void saa7115_decode_vbi_line(struct i2c_client *client,
+static void saa711x_decode_vbi_line(struct i2c_client *client,
struct v4l2_decode_vbi_line *vbi)
{
static const char vbi_no_data_pattern[] = {
0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0
};
- struct saa7115_state *state = i2c_get_clientdata(client);
+ struct saa711x_state *state = i2c_get_clientdata(client);
u8 *p = vbi->p;
u32 wss;
int id1, id2; /* the ID1 and ID2 bytes from the internal header */
@@ -1066,12 +1202,12 @@ static void saa7115_decode_vbi_line(struct i2c_client *client,
vbi->type = V4L2_SLICED_TELETEXT_B;
break;
case 4:
- if (!saa7115_odd_parity(p[0]) || !saa7115_odd_parity(p[1]))
+ if (!saa711x_odd_parity(p[0]) || !saa711x_odd_parity(p[1]))
return;
vbi->type = V4L2_SLICED_CAPTION_525;
break;
case 5:
- wss = saa7115_decode_wss(p);
+ wss = saa711x_decode_wss(p);
if (wss == -1)
return;
p[0] = wss & 0xff;
@@ -1079,7 +1215,7 @@ static void saa7115_decode_vbi_line(struct i2c_client *client,
vbi->type = V4L2_SLICED_WSS_625;
break;
case 7:
- if (saa7115_decode_vps(p, p) != 0)
+ if (saa711x_decode_vps(p, p) != 0)
return;
vbi->type = V4L2_SLICED_VPS;
break;
@@ -1090,21 +1226,21 @@ static void saa7115_decode_vbi_line(struct i2c_client *client,
/* ============ SAA7115 AUDIO settings (end) ============= */
-static int saa7115_command(struct i2c_client *client, unsigned int cmd, void *arg)
+static int saa711x_command(struct i2c_client *client, unsigned int cmd, void *arg)
{
- struct saa7115_state *state = i2c_get_clientdata(client);
+ struct saa711x_state *state = i2c_get_clientdata(client);
int *iarg = arg;
/* ioctls to allow direct access to the saa7115 registers for testing */
switch (cmd) {
case VIDIOC_S_FMT:
- return saa7115_set_v4lfmt(client, (struct v4l2_format *)arg);
+ return saa711x_set_v4lfmt(client, (struct v4l2_format *)arg);
case VIDIOC_G_FMT:
- return saa7115_get_v4lfmt(client, (struct v4l2_format *)arg);
+ return saa711x_get_v4lfmt(client, (struct v4l2_format *)arg);
case VIDIOC_INT_AUDIO_CLOCK_FREQ:
- return saa7115_set_audio_clock_freq(client, *(u32 *)arg);
+ return saa711x_set_audio_clock_freq(client, *(u32 *)arg);
case VIDIOC_G_TUNER:
{
@@ -1113,7 +1249,7 @@ static int saa7115_command(struct i2c_client *client, unsigned int cmd, void *ar
if (state->radio)
break;
- status = saa7115_read(client, 0x1f);
+ status = saa711x_read(client, R_1F_STATUS_BYTE_2_VD_DEC);
v4l_dbg(1, debug, client, "status: 0x%02x\n", status);
vt->signal = ((status & (1 << 6)) == 0) ? 0xffff : 0x0;
@@ -1121,14 +1257,14 @@ static int saa7115_command(struct i2c_client *client, unsigned int cmd, void *ar
}
case VIDIOC_LOG_STATUS:
- saa7115_log_status(client);
+ saa711x_log_status(client);
break;
case VIDIOC_G_CTRL:
- return saa7115_get_v4lctrl(client, (struct v4l2_control *)arg);
+ return saa711x_get_v4lctrl(client, (struct v4l2_control *)arg);
case VIDIOC_S_CTRL:
- return saa7115_set_v4lctrl(client, (struct v4l2_control *)arg);
+ return saa711x_set_v4lctrl(client, (struct v4l2_control *)arg);
case VIDIOC_QUERYCTRL:
{
@@ -1146,12 +1282,12 @@ static int saa7115_command(struct i2c_client *client, unsigned int cmd, void *ar
}
case VIDIOC_G_STD:
- *(v4l2_std_id *)arg = saa7115_get_v4lstd(client);
+ *(v4l2_std_id *)arg = saa711x_get_v4lstd(client);
break;
case VIDIOC_S_STD:
state->radio = 0;
- saa7115_set_v4lstd(client, *(v4l2_std_id *)arg);
+ saa711x_set_v4lstd(client, *(v4l2_std_id *)arg);
break;
case AUDC_SET_RADIO:
@@ -1187,13 +1323,13 @@ static int saa7115_command(struct i2c_client *client, unsigned int cmd, void *ar
state->input = route->input;
/* select mode */
- saa7115_write(client, 0x02,
- (saa7115_read(client, 0x02) & 0xf0) |
+ saa711x_write(client, R_02_INPUT_CNTL_1,
+ (saa711x_read(client, R_02_INPUT_CNTL_1) & 0xf0) |
state->input);
/* bypass chrominance trap for S-Video modes */
- saa7115_write(client, 0x09,
- (saa7115_read(client, 0x09) & 0x7f) |
+ saa711x_write(client, R_09_LUMA_CNTL,
+ (saa711x_read(client, R_09_LUMA_CNTL) & 0x7f) |
(state->input >= SAA7115_SVIDEO0 ? 0x80 : 0x0));
break;
}
@@ -1205,7 +1341,9 @@ static int saa7115_command(struct i2c_client *client, unsigned int cmd, void *ar
if (state->enable != (cmd == VIDIOC_STREAMON)) {
state->enable = (cmd == VIDIOC_STREAMON);
- saa7115_write(client, 0x87, state->enable);
+ saa711x_write(client,
+ R_87_I_PORT_I_O_ENA_OUT_CLK_AND_GATED,
+ state->enable);
}
break;
@@ -1220,17 +1358,17 @@ static int saa7115_command(struct i2c_client *client, unsigned int cmd, void *ar
state->cgcdiv = (freq->flags & SAA7115_FREQ_FL_CGCDIV) ? 3 : 4;
state->ucgc = (freq->flags & SAA7115_FREQ_FL_UCGC) ? 1 : 0;
state->apll = (freq->flags & SAA7115_FREQ_FL_APLL) ? 1 : 0;
- saa7115_set_audio_clock_freq(client, state->audclk_freq);
+ saa711x_set_audio_clock_freq(client, state->audclk_freq);
break;
}
case VIDIOC_INT_DECODE_VBI_LINE:
- saa7115_decode_vbi_line(client, arg);
+ saa711x_decode_vbi_line(client, arg);
break;
case VIDIOC_INT_RESET:
v4l_dbg(1, debug, client, "decoder RESET\n");
- saa7115_writeregs(client, saa7115_cfg_reset_scaler);
+ saa711x_writeregs(client, saa7115_cfg_reset_scaler);
break;
case VIDIOC_INT_G_VBI_DATA:
@@ -1239,25 +1377,25 @@ static int saa7115_command(struct i2c_client *client, unsigned int cmd, void *ar
switch (data->id) {
case V4L2_SLICED_WSS_625:
- if (saa7115_read(client, 0x6b) & 0xc0)
+ if (saa711x_read(client, 0x6b) & 0xc0)
return -EIO;
- data->data[0] = saa7115_read(client, 0x6c);
- data->data[1] = saa7115_read(client, 0x6d);
+ data->data[0] = saa711x_read(client, 0x6c);
+ data->data[1] = saa711x_read(client, 0x6d);
return 0;
case V4L2_SLICED_CAPTION_525:
if (data->field == 0) {
/* CC */
- if (saa7115_read(client, 0x66) & 0xc0)
+ if (saa711x_read(client, 0x66) & 0xc0)
return -EIO;
- data->data[0] = saa7115_read(client, 0x67);
- data->data[1] = saa7115_read(client, 0x68);
+ data->data[0] = saa711x_read(client, 0x67);
+ data->data[1] = saa711x_read(client, 0x68);
return 0;
}
/* XDS */
- if (saa7115_read(client, 0x66) & 0x30)
+ if (saa711x_read(client, 0x66) & 0x30)
return -EIO;
- data->data[0] = saa7115_read(client, 0x69);
- data->data[1] = saa7115_read(client, 0x6a);
+ data->data[0] = saa711x_read(client, 0x69);
+ data->data[1] = saa711x_read(client, 0x6a);
return 0;
default:
return -EINVAL;
@@ -1272,7 +1410,7 @@ static int saa7115_command(struct i2c_client *client, unsigned int cmd, void *ar
if (reg->i2c_id != I2C_DRIVERID_SAA711X)
return -EINVAL;
- reg->val = saa7115_read(client, reg->reg & 0xff);
+ reg->val = saa711x_read(client, reg->reg & 0xff);
break;
}
@@ -1284,7 +1422,7 @@ static int saa7115_command(struct i2c_client *client, unsigned int cmd, void *ar
return -EINVAL;
if (!capable(CAP_SYS_ADMIN))
return -EPERM;
- saa7115_write(client, reg->reg & 0xff, reg->val & 0xff);
+ saa711x_write(client, reg->reg & 0xff, reg->val & 0xff);
break;
}
#endif
@@ -1302,12 +1440,14 @@ static int saa7115_command(struct i2c_client *client, unsigned int cmd, void *ar
/* ----------------------------------------------------------------------- */
-static struct i2c_driver i2c_driver_saa7115;
+static struct i2c_driver i2c_driver_saa711x;
-static int saa7115_attach(struct i2c_adapter *adapter, int address, int kind)
+static int saa711x_attach(struct i2c_adapter *adapter, int address, int kind)
{
struct i2c_client *client;
- struct saa7115_state *state;
+ struct saa711x_state *state;
+ int i;
+ char name[17];
u8 chip_id;
/* Check if the adapter supports the needed features */
@@ -1319,28 +1459,31 @@ static int saa7115_attach(struct i2c_adapter *adapter, int address, int kind)
return -ENOMEM;
client->addr = address;
client->adapter = adapter;
- client->driver = &i2c_driver_saa7115;
+ client->driver = &i2c_driver_saa711x;
snprintf(client->name, sizeof(client->name) - 1, "saa7115");
v4l_dbg(1, debug, client, "detecting saa7115 client on address 0x%x\n", address << 1);
- saa7115_write(client, 0, 5);
- chip_id = saa7115_read(client, 0) & 0x0f;
- if (chip_id < 3 && chip_id > 5) {
- v4l_dbg(1, debug, client, "saa7115 not found\n");
- kfree(client);
- return 0;
+ for (i=0;i<0x0f;i++) {
+ saa711x_write(client, 0, i);
+ name[i] = (saa711x_read(client, 0) &0x0f) +'0';
+ if (name[i]>'9')
+ name[i]+='a'-'9'-1;
}
+ name[i]='\0';
+
+ saa711x_write(client, 0, 5);
+ chip_id = saa711x_read(client, 0) & 0x0f;
+
snprintf(client->name, sizeof(client->name) - 1, "saa711%d",chip_id);
- v4l_info(client, "saa711%d found @ 0x%x (%s)\n", chip_id, address << 1, adapter->name);
+ v4l_info(client, "saa711%d found (%s) @ 0x%x (%s)\n", chip_id, name, address << 1, adapter->name);
- state = kzalloc(sizeof(struct saa7115_state), GFP_KERNEL);
+ state = kzalloc(sizeof(struct saa711x_state), GFP_KERNEL);
i2c_set_clientdata(client, state);
if (state == NULL) {
kfree(client);
return -ENOMEM;
}
- state->std = V4L2_STD_NTSC;
state->input = -1;
state->enable = 1;
state->radio = 0;
@@ -1349,15 +1492,25 @@ static int saa7115_attach(struct i2c_adapter *adapter, int address, int kind)
state->hue = 0;
state->sat = 64;
switch (chip_id) {
+ case 1:
+ state->ident = V4L2_IDENT_SAA7111;
+ break;
case 3:
state->ident = V4L2_IDENT_SAA7113;
break;
case 4:
state->ident = V4L2_IDENT_SAA7114;
break;
- default:
+ case 5:
state->ident = V4L2_IDENT_SAA7115;
break;
+ case 8:
+ state->ident = V4L2_IDENT_SAA7118;
+ break;
+ default:
+ state->ident = V4L2_IDENT_SAA7111;
+ v4l_info(client, "WARNING: Chip is not known - Falling back to saa7111\n");
+
}
state->audclk_freq = 48000;
@@ -1365,38 +1518,39 @@ static int saa7115_attach(struct i2c_adapter *adapter, int address, int kind)
v4l_dbg(1, debug, client, "writing init values\n");
/* init to 60hz/48khz */
- if (state->ident == V4L2_IDENT_SAA7113) {
- state->crystal_freq = SAA7115_FREQ_24_576_MHZ;
- saa7115_writeregs(client, saa7113_init_auto_input);
- } else {
+ state->crystal_freq = SAA7115_FREQ_24_576_MHZ;
+ switch (state->ident) {
+ case V4L2_IDENT_SAA7111:
+ saa711x_writeregs(client, saa7111_init);
+ break;
+ case V4L2_IDENT_SAA7113:
+ saa711x_writeregs(client, saa7113_init);
+ break;
+ default:
state->crystal_freq = SAA7115_FREQ_32_11_MHZ;
- saa7115_writeregs(client, saa7115_init_auto_input);
+ saa711x_writeregs(client, saa7115_init_auto_input);
}
- saa7115_writeregs(client, saa7115_init_misc);
- saa7115_writeregs(client, saa7115_cfg_60hz_fullres_x);
- saa7115_writeregs(client, saa7115_cfg_60hz_fullres_y);
- saa7115_writeregs(client, saa7115_cfg_60hz_video);
- saa7115_set_audio_clock_freq(client, state->audclk_freq);
- saa7115_writeregs(client, saa7115_cfg_reset_scaler);
+ saa711x_writeregs(client, saa7115_init_misc);
+ saa711x_set_v4lstd(client, V4L2_STD_NTSC);
i2c_attach_client(client);
v4l_dbg(1, debug, client, "status: (1E) 0x%02x, (1F) 0x%02x\n",
- saa7115_read(client, 0x1e), saa7115_read(client, 0x1f));
+ saa711x_read(client, R_1E_STATUS_BYTE_1_VD_DEC), saa711x_read(client, R_1F_STATUS_BYTE_2_VD_DEC));
return 0;
}
-static int saa7115_probe(struct i2c_adapter *adapter)
+static int saa711x_probe(struct i2c_adapter *adapter)
{
if (adapter->class & I2C_CLASS_TV_ANALOG)
- return i2c_probe(adapter, &addr_data, &saa7115_attach);
+ return i2c_probe(adapter, &addr_data, &saa711x_attach);
return 0;
}
-static int saa7115_detach(struct i2c_client *client)
+static int saa711x_detach(struct i2c_client *client)
{
- struct saa7115_state *state = i2c_get_clientdata(client);
+ struct saa711x_state *state = i2c_get_clientdata(client);
int err;
err = i2c_detach_client(client);
@@ -1412,26 +1566,26 @@ static int saa7115_detach(struct i2c_client *client)
/* ----------------------------------------------------------------------- */
/* i2c implementation */
-static struct i2c_driver i2c_driver_saa7115 = {
+static struct i2c_driver i2c_driver_saa711x = {
.driver = {
.name = "saa7115",
},
.id = I2C_DRIVERID_SAA711X,
- .attach_adapter = saa7115_probe,
- .detach_client = saa7115_detach,
- .command = saa7115_command,
+ .attach_adapter = saa711x_probe,
+ .detach_client = saa711x_detach,
+ .command = saa711x_command,
};
-static int __init saa7115_init_module(void)
+static int __init saa711x_init_module(void)
{
- return i2c_add_driver(&i2c_driver_saa7115);
+ return i2c_add_driver(&i2c_driver_saa711x);
}
-static void __exit saa7115_cleanup_module(void)
+static void __exit saa711x_cleanup_module(void)
{
- i2c_del_driver(&i2c_driver_saa7115);
+ i2c_del_driver(&i2c_driver_saa711x);
}
-module_init(saa7115_init_module);
-module_exit(saa7115_cleanup_module);
+module_init(saa711x_init_module);
+module_exit(saa711x_cleanup_module);
diff --git a/drivers/media/video/saa711x_regs.h b/drivers/media/video/saa711x_regs.h
new file mode 100644
index 000000000000..4e5f2eb0a2c1
--- /dev/null
+++ b/drivers/media/video/saa711x_regs.h
@@ -0,0 +1,549 @@
+/* saa711x - Philips SAA711x video decoder register specifications
+ *
+ * Copyright (c) 2006 Mauro Carvalho Chehab <mchehab@infradead.org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#define R_00_CHIP_VERSION 0x00
+/* Video Decoder */
+ /* Video Decoder - Frontend part */
+#define R_01_INC_DELAY 0x01
+#define R_02_INPUT_CNTL_1 0x02
+#define R_03_INPUT_CNTL_2 0x03
+#define R_04_INPUT_CNTL_3 0x04
+#define R_05_INPUT_CNTL_4 0x05
+ /* Video Decoder - Decoder part */
+#define R_06_H_SYNC_START 0x06
+#define R_07_H_SYNC_STOP 0x07
+#define R_08_SYNC_CNTL 0x08
+#define R_09_LUMA_CNTL 0x09
+#define R_0A_LUMA_BRIGHT_CNTL 0x0a
+#define R_0B_LUMA_CONTRAST_CNTL 0x0b
+#define R_0C_CHROMA_SAT_CNTL 0x0c
+#define R_0D_CHROMA_HUE_CNTL 0x0d
+#define R_0E_CHROMA_CNTL_1 0x0e
+#define R_0F_CHROMA_GAIN_CNTL 0x0f
+#define R_10_CHROMA_CNTL_2 0x10
+#define R_11_MODE_DELAY_CNTL 0x11
+#define R_12_RT_SIGNAL_CNTL 0x12
+#define R_13_RT_X_PORT_OUT_CNTL 0x13
+#define R_14_ANAL_ADC_COMPAT_CNTL 0x14
+#define R_15_VGATE_START_FID_CHG 0x15
+#define R_16_VGATE_STOP 0x16
+#define R_17_MISC_VGATE_CONF_AND_MSB 0x17
+#define R_18_RAW_DATA_GAIN_CNTL 0x18
+#define R_19_RAW_DATA_OFF_CNTL 0x19
+#define R_1A_COLOR_KILL_LVL_CNTL 0x1a
+#define R_1B_MISC_TVVCRDET 0x1b
+#define R_1C_ENHAN_COMB_CTRL1 0x1c
+#define R_1D_ENHAN_COMB_CTRL2 0x1d
+#define R_1E_STATUS_BYTE_1_VD_DEC 0x1e
+#define R_1F_STATUS_BYTE_2_VD_DEC 0x1f
+
+/* Component processing and interrupt masking part */
+#define R_23_INPUT_CNTL_5 0x23
+#define R_24_INPUT_CNTL_6 0x24
+#define R_25_INPUT_CNTL_7 0x25
+#define R_29_COMP_DELAY 0x29
+#define R_2A_COMP_BRIGHT_CNTL 0x2a
+#define R_2B_COMP_CONTRAST_CNTL 0x2b
+#define R_2C_COMP_SAT_CNTL 0x2c
+#define R_2D_INTERRUPT_MASK_1 0x2d
+#define R_2E_INTERRUPT_MASK_2 0x2e
+#define R_2F_INTERRUPT_MASK_3 0x2f
+
+/* Audio clock generator part */
+#define R_30_AUD_MAST_CLK_CYCLES_PER_FIELD 0x30
+#define R_34_AUD_MAST_CLK_NOMINAL_INC 0x34
+#define R_38_CLK_RATIO_AMXCLK_TO_ASCLK 0x38
+#define R_39_CLK_RATIO_ASCLK_TO_ALRCLK 0x39
+#define R_3A_AUD_CLK_GEN_BASIC_SETUP 0x3a
+
+/* General purpose VBI data slicer part */
+#define R_40_SLICER_CNTL_1 0x40
+#define R_41_LCR_BASE 0x41
+#define R_58_PROGRAM_FRAMING_CODE 0x58
+#define R_59_H_OFF_FOR_SLICER 0x59
+#define R_5A_V_OFF_FOR_SLICER 0x5a
+#define R_5B_FLD_OFF_AND_MSB_FOR_H_AND_V_OFF 0x5b
+#define R_5D_DID 0x5d
+#define R_5E_SDID 0x5e
+#define R_60_SLICER_STATUS_BYTE_0 0x60
+#define R_61_SLICER_STATUS_BYTE_1 0x61
+#define R_62_SLICER_STATUS_BYTE_2 0x62
+
+/* X port, I port and the scaler part */
+ /* Task independent global settings */
+#define R_80_GLOBAL_CNTL_1 0x80
+#define R_81_V_SYNC_FLD_ID_SRC_SEL_AND_RETIMED_V_F 0x81
+#define R_83_X_PORT_I_O_ENA_AND_OUT_CLK 0x83
+#define R_84_I_PORT_SIGNAL_DEF 0x84
+#define R_85_I_PORT_SIGNAL_POLAR 0x85
+#define R_86_I_PORT_FIFO_FLAG_CNTL_AND_ARBIT 0x86
+#define R_87_I_PORT_I_O_ENA_OUT_CLK_AND_GATED 0x87
+#define R_88_POWER_SAVE_ADC_PORT_CNTL 0x88
+#define R_8F_STATUS_INFO_SCALER 0x8f
+ /* Task A definition */
+ /* Basic settings and acquisition window definition */
+#define R_90_A_TASK_HANDLING_CNTL 0x90
+#define R_91_A_X_PORT_FORMATS_AND_CONF 0x91
+#define R_92_A_X_PORT_INPUT_REFERENCE_SIGNAL 0x92
+#define R_93_A_I_PORT_OUTPUT_FORMATS_AND_CONF 0x93
+#define R_94_A_HORIZ_INPUT_WINDOW_START 0x94
+#define R_95_A_HORIZ_INPUT_WINDOW_START_MSB 0x95
+#define R_96_A_HORIZ_INPUT_WINDOW_LENGTH 0x96
+#define R_97_A_HORIZ_INPUT_WINDOW_LENGTH_MSB 0x97
+#define R_98_A_VERT_INPUT_WINDOW_START 0x98
+#define R_99_A_VERT_INPUT_WINDOW_START_MSB 0x99
+#define R_9A_A_VERT_INPUT_WINDOW_LENGTH 0x9a
+#define R_9B_A_VERT_INPUT_WINDOW_LENGTH_MSB 0x9b
+#define R_9C_A_HORIZ_OUTPUT_WINDOW_LENGTH 0x9c
+#define R_9D_A_HORIZ_OUTPUT_WINDOW_LENGTH_MSB 0x9d
+#define R_9E_A_VERT_OUTPUT_WINDOW_LENGTH 0x9e
+#define R_9F_A_VERT_OUTPUT_WINDOW_LENGTH_MSB 0x9f
+ /* FIR filtering and prescaling */
+#define R_A0_A_HORIZ_PRESCALING 0xa0
+#define R_A1_A_ACCUMULATION_LENGTH 0xa1
+#define R_A2_A_PRESCALER_DC_GAIN_AND_FIR_PREFILTER 0xa2
+#define R_A4_A_LUMA_BRIGHTNESS_CNTL 0xa4
+#define R_A5_A_LUMA_CONTRAST_CNTL 0xa5
+#define R_A6_A_CHROMA_SATURATION_CNTL 0xa6
+ /* Horizontal phase scaling */
+#define R_A8_A_HORIZ_LUMA_SCALING_INC 0xa8
+#define R_A9_A_HORIZ_LUMA_SCALING_INC_MSB 0xa9
+#define R_AA_A_HORIZ_LUMA_PHASE_OFF 0xaa
+#define R_AC_A_HORIZ_CHROMA_SCALING_INC 0xac
+#define R_AD_A_HORIZ_CHROMA_SCALING_INC_MSB 0xad
+#define R_AE_A_HORIZ_CHROMA_PHASE_OFF 0xae
+#define R_AF_A_HORIZ_CHROMA_PHASE_OFF_MSB 0xaf
+ /* Vertical scaling */
+#define R_B0_A_VERT_LUMA_SCALING_INC 0xb0
+#define R_B1_A_VERT_LUMA_SCALING_INC_MSB 0xb1
+#define R_B2_A_VERT_CHROMA_SCALING_INC 0xb2
+#define R_B3_A_VERT_CHROMA_SCALING_INC_MSB 0xb3
+#define R_B4_A_VERT_SCALING_MODE_CNTL 0xb4
+#define R_B8_A_VERT_CHROMA_PHASE_OFF_00 0xb8
+#define R_B9_A_VERT_CHROMA_PHASE_OFF_01 0xb9
+#define R_BA_A_VERT_CHROMA_PHASE_OFF_10 0xba
+#define R_BB_A_VERT_CHROMA_PHASE_OFF_11 0xbb
+#define R_BC_A_VERT_LUMA_PHASE_OFF_00 0xbc
+#define R_BD_A_VERT_LUMA_PHASE_OFF_01 0xbd
+#define R_BE_A_VERT_LUMA_PHASE_OFF_10 0xbe
+#define R_BF_A_VERT_LUMA_PHASE_OFF_11 0xbf
+ /* Task B definition */
+ /* Basic settings and acquisition window definition */
+#define R_C0_B_TASK_HANDLING_CNTL 0xc0
+#define R_C1_B_X_PORT_FORMATS_AND_CONF 0xc1
+#define R_C2_B_INPUT_REFERENCE_SIGNAL_DEFINITION 0xc2
+#define R_C3_B_I_PORT_FORMATS_AND_CONF 0xc3
+#define R_C4_B_HORIZ_INPUT_WINDOW_START 0xc4
+#define R_C5_B_HORIZ_INPUT_WINDOW_START_MSB 0xc5
+#define R_C6_B_HORIZ_INPUT_WINDOW_LENGTH 0xc6
+#define R_C7_B_HORIZ_INPUT_WINDOW_LENGTH_MSB 0xc7
+#define R_C8_B_VERT_INPUT_WINDOW_START 0xc8
+#define R_C9_B_VERT_INPUT_WINDOW_START_MSB 0xc9
+#define R_CA_B_VERT_INPUT_WINDOW_LENGTH 0xca
+#define R_CB_B_VERT_INPUT_WINDOW_LENGTH_MSB 0xcb
+#define R_CC_B_HORIZ_OUTPUT_WINDOW_LENGTH 0xcc
+#define R_CD_B_HORIZ_OUTPUT_WINDOW_LENGTH_MSB 0xcd
+#define R_CE_B_VERT_OUTPUT_WINDOW_LENGTH 0xce
+#define R_CF_B_VERT_OUTPUT_WINDOW_LENGTH_MSB 0xcf
+ /* FIR filtering and prescaling */
+#define R_D0_B_HORIZ_PRESCALING 0xd0
+#define R_D1_B_ACCUMULATION_LENGTH 0xd1
+#define R_D2_B_PRESCALER_DC_GAIN_AND_FIR_PREFILTER 0xd2
+#define R_D4_B_LUMA_BRIGHTNESS_CNTL 0xd4
+#define R_D5_B_LUMA_CONTRAST_CNTL 0xd5
+#define R_D6_B_CHROMA_SATURATION_CNTL 0xd6
+ /* Horizontal phase scaling */
+#define R_D8_B_HORIZ_LUMA_SCALING_INC 0xd8
+#define R_D9_B_HORIZ_LUMA_SCALING_INC_MSB 0xd9
+#define R_DA_B_HORIZ_LUMA_PHASE_OFF 0xda
+#define R_DC_B_HORIZ_CHROMA_SCALING 0xdc
+#define R_DD_B_HORIZ_CHROMA_SCALING_MSB 0xdd
+#define R_DE_B_HORIZ_PHASE_OFFSET_CRHOMA 0xde
+ /* Vertical scaling */
+#define R_E0_B_VERT_LUMA_SCALING_INC 0xe0
+#define R_E1_B_VERT_LUMA_SCALING_INC_MSB 0xe1
+#define R_E2_B_VERT_CHROMA_SCALING_INC 0xe2
+#define R_E3_B_VERT_CHROMA_SCALING_INC_MSB 0xe3
+#define R_E4_B_VERT_SCALING_MODE_CNTL 0xe4
+#define R_E8_B_VERT_CHROMA_PHASE_OFF_00 0xe8
+#define R_E9_B_VERT_CHROMA_PHASE_OFF_01 0xe9
+#define R_EA_B_VERT_CHROMA_PHASE_OFF_10 0xea
+#define R_EB_B_VERT_CHROMA_PHASE_OFF_11 0xeb
+#define R_EC_B_VERT_LUMA_PHASE_OFF_00 0xec
+#define R_ED_B_VERT_LUMA_PHASE_OFF_01 0xed
+#define R_EE_B_VERT_LUMA_PHASE_OFF_10 0xee
+#define R_EF_B_VERT_LUMA_PHASE_OFF_11 0xef
+
+/* second PLL (PLL2) and Pulsegenerator Programming */
+#define R_F0_LFCO_PER_LINE 0xf0
+#define R_F1_P_I_PARAM_SELECT 0xf1
+#define R_F2_NOMINAL_PLL2_DTO 0xf2
+#define R_F3_PLL_INCREMENT 0xf3
+#define R_F4_PLL2_STATUS 0xf4
+#define R_F5_PULSGEN_LINE_LENGTH 0xf5
+#define R_F6_PULSE_A_POS_LSB_AND_PULSEGEN_CONFIG 0xf6
+#define R_F7_PULSE_A_POS_MSB 0xf7
+#define R_F8_PULSE_B_POS 0xf8
+#define R_F9_PULSE_B_POS_MSB 0xf9
+#define R_FA_PULSE_C_POS 0xfa
+#define R_FB_PULSE_C_POS_MSB 0xfb
+#define R_FF_S_PLL_MAX_PHASE_ERR_THRESH_NUM_LINES 0xff
+
+#if 0
+/* Those structs will be used in the future for debug purposes */
+struct saa711x_reg_descr {
+ u8 reg;
+ int count;
+ char *name;
+};
+
+struct saa711x_reg_descr saa711x_regs[] = {
+ /* REG COUNT NAME */
+ {R_00_CHIP_VERSION,1,
+ "Chip version"},
+
+ /* Video Decoder: R_01_INC_DELAY to R_1F_STATUS_BYTE_2_VD_DEC */
+
+ /* Video Decoder - Frontend part: R_01_INC_DELAY to R_05_INPUT_CNTL_4 */
+ {R_01_INC_DELAY,1,
+ "Increment delay"},
+ {R_02_INPUT_CNTL_1,1,
+ "Analog input control 1"},
+ {R_03_INPUT_CNTL_2,1,
+ "Analog input control 2"},
+ {R_04_INPUT_CNTL_3,1,
+ "Analog input control 3"},
+ {R_05_INPUT_CNTL_4,1,
+ "Analog input control 4"},
+
+ /* Video Decoder - Decoder part: R_06_H_SYNC_START to R_1F_STATUS_BYTE_2_VD_DEC */
+ {R_06_H_SYNC_START,1,
+ "Horizontal sync start"},
+ {R_07_H_SYNC_STOP,1,
+ "Horizontal sync stop"},
+ {R_08_SYNC_CNTL,1,
+ "Sync control"},
+ {R_09_LUMA_CNTL,1,
+ "Luminance control"},
+ {R_0A_LUMA_BRIGHT_CNTL,1,
+ "Luminance brightness control"},
+ {R_0B_LUMA_CONTRAST_CNTL,1,
+ "Luminance contrast control"},
+ {R_0C_CHROMA_SAT_CNTL,1,
+ "Chrominance saturation control"},
+ {R_0D_CHROMA_HUE_CNTL,1,
+ "Chrominance hue control"},
+ {R_0E_CHROMA_CNTL_1,1,
+ "Chrominance control 1"},
+ {R_0F_CHROMA_GAIN_CNTL,1,
+ "Chrominance gain control"},
+ {R_10_CHROMA_CNTL_2,1,
+ "Chrominance control 2"},
+ {R_11_MODE_DELAY_CNTL,1,
+ "Mode/delay control"},
+ {R_12_RT_SIGNAL_CNTL,1,
+ "RT signal control"},
+ {R_13_RT_X_PORT_OUT_CNTL,1,
+ "RT/X port output control"},
+ {R_14_ANAL_ADC_COMPAT_CNTL,1,
+ "Analog/ADC/compatibility control"},
+ {R_15_VGATE_START_FID_CHG, 1,
+ "VGATE start FID change"},
+ {R_16_VGATE_STOP,1,
+ "VGATE stop"},
+ {R_17_MISC_VGATE_CONF_AND_MSB, 1,
+ "Miscellaneous VGATE configuration and MSBs"},
+ {R_18_RAW_DATA_GAIN_CNTL,1,
+ "Raw data gain control",},
+ {R_19_RAW_DATA_OFF_CNTL,1,
+ "Raw data offset control",},
+ {R_1A_COLOR_KILL_LVL_CNTL,1,
+ "Color Killer Level Control"},
+ { R_1B_MISC_TVVCRDET, 1,
+ "MISC /TVVCRDET"},
+ { R_1C_ENHAN_COMB_CTRL1, 1,
+ "Enhanced comb ctrl1"},
+ { R_1D_ENHAN_COMB_CTRL2, 1,
+ "Enhanced comb ctrl1"},
+ {R_1E_STATUS_BYTE_1_VD_DEC,1,
+ "Status byte 1 video decoder"},
+ {R_1F_STATUS_BYTE_2_VD_DEC,1,
+ "Status byte 2 video decoder"},
+
+ /* Component processing and interrupt masking part: 0x20h to R_2F_INTERRUPT_MASK_3 */
+ /* 0x20 to 0x22 - Reserved */
+ {R_23_INPUT_CNTL_5,1,
+ "Analog input control 5"},
+ {R_24_INPUT_CNTL_6,1,
+ "Analog input control 6"},
+ {R_25_INPUT_CNTL_7,1,
+ "Analog input control 7"},
+ /* 0x26 to 0x28 - Reserved */
+ {R_29_COMP_DELAY,1,
+ "Component delay"},
+ {R_2A_COMP_BRIGHT_CNTL,1,
+ "Component brightness control"},
+ {R_2B_COMP_CONTRAST_CNTL,1,
+ "Component contrast control"},
+ {R_2C_COMP_SAT_CNTL,1,
+ "Component saturation control"},
+ {R_2D_INTERRUPT_MASK_1,1,
+ "Interrupt mask 1"},
+ {R_2E_INTERRUPT_MASK_2,1,
+ "Interrupt mask 2"},
+ {R_2F_INTERRUPT_MASK_3,1,
+ "Interrupt mask 3"},
+
+ /* Audio clock generator part: R_30_AUD_MAST_CLK_CYCLES_PER_FIELD to 0x3f */
+ {R_30_AUD_MAST_CLK_CYCLES_PER_FIELD,3,
+ "Audio master clock cycles per field"},
+ /* 0x33 - Reserved */
+ {R_34_AUD_MAST_CLK_NOMINAL_INC,3,
+ "Audio master clock nominal increment"},
+ /* 0x37 - Reserved */
+ {R_38_CLK_RATIO_AMXCLK_TO_ASCLK,1,
+ "Clock ratio AMXCLK to ASCLK"},
+ {R_39_CLK_RATIO_ASCLK_TO_ALRCLK,1,
+ "Clock ratio ASCLK to ALRCLK"},
+ {R_3A_AUD_CLK_GEN_BASIC_SETUP,1,
+ "Audio clock generator basic setup"},
+ /* 0x3b-0x3f - Reserved */
+
+ /* General purpose VBI data slicer part: R_40_SLICER_CNTL_1 to 0x7f */
+ {R_40_SLICER_CNTL_1,1,
+ "Slicer control 1"},
+ {R_41_LCR,23,
+ "R_41_LCR"},
+ {R_58_PROGRAM_FRAMING_CODE,1,
+ "Programmable framing code"},
+ {R_59_H_OFF_FOR_SLICER,1,
+ "Horizontal offset for slicer"},
+ {R_5A_V_OFF_FOR_SLICER,1,
+ "Vertical offset for slicer"},
+ {R_5B_FLD_OFF_AND_MSB_FOR_H_AND_V_OFF,1,
+ "Field offset and MSBs for horizontal and vertical offset"},
+ {R_5D_DID,1,
+ "Header and data identification (R_5D_DID)"},
+ {R_5E_SDID,1,
+ "Sliced data identification (R_5E_SDID) code"},
+ {R_60_SLICER_STATUS_BYTE_0,1,
+ "Slicer status byte 0"},
+ {R_61_SLICER_STATUS_BYTE_1,1,
+ "Slicer status byte 1"},
+ {R_62_SLICER_STATUS_BYTE_2,1,
+ "Slicer status byte 2"},
+ /* 0x63-0x7f - Reserved */
+
+ /* X port, I port and the scaler part: R_80_GLOBAL_CNTL_1 to R_EF_B_VERT_LUMA_PHASE_OFF_11 */
+ /* Task independent global settings: R_80_GLOBAL_CNTL_1 to R_8F_STATUS_INFO_SCALER */
+ {R_80_GLOBAL_CNTL_1,1,
+ "Global control 1"},
+ {R_81_V_SYNC_FLD_ID_SRC_SEL_AND_RETIMED_V_F,1,
+ "Vertical sync and Field ID source selection, retimed V and F signals"},
+ /* 0x82 - Reserved */
+ {R_83_X_PORT_I_O_ENA_AND_OUT_CLK,1,
+ "X port I/O enable and output clock"},
+ {R_84_I_PORT_SIGNAL_DEF,1,
+ "I port signal definitions"},
+ {R_85_I_PORT_SIGNAL_POLAR,1,
+ "I port signal polarities"},
+ {R_86_I_PORT_FIFO_FLAG_CNTL_AND_ARBIT,1,
+ "I port FIFO flag control and arbitration"},
+ {R_87_I_PORT_I_O_ENA_OUT_CLK_AND_GATED, 1,
+ "I port I/O enable output clock and gated"},
+ {R_88_POWER_SAVE_ADC_PORT_CNTL,1,
+ "Power save/ADC port control"},
+ /* 089-0x8e - Reserved */
+ {R_8F_STATUS_INFO_SCALER,1,
+ "Status information scaler part"},
+
+ /* Task A definition: R_90_A_TASK_HANDLING_CNTL to R_BF_A_VERT_LUMA_PHASE_OFF_11 */
+ /* Task A: Basic settings and acquisition window definition */
+ {R_90_A_TASK_HANDLING_CNTL,1,
+ "Task A: Task handling control"},
+ {R_91_A_X_PORT_FORMATS_AND_CONF,1,
+ "Task A: X port formats and configuration"},
+ {R_92_A_X_PORT_INPUT_REFERENCE_SIGNAL,1,
+ "Task A: X port input reference signal definition"},
+ {R_93_A_I_PORT_OUTPUT_FORMATS_AND_CONF,1,
+ "Task A: I port output formats and configuration"},
+ {R_94_A_HORIZ_INPUT_WINDOW_START,2,
+ "Task A: Horizontal input window start"},
+ {R_96_A_HORIZ_INPUT_WINDOW_LENGTH,2,
+ "Task A: Horizontal input window length"},
+ {R_98_A_VERT_INPUT_WINDOW_START,2,
+ "Task A: Vertical input window start"},
+ {R_9A_A_VERT_INPUT_WINDOW_LENGTH,2,
+ "Task A: Vertical input window length"},
+ {R_9C_A_HORIZ_OUTPUT_WINDOW_LENGTH,2,
+ "Task A: Horizontal output window length"},
+ {R_9E_A_VERT_OUTPUT_WINDOW_LENGTH,2,
+ "Task A: Vertical output window length"},
+
+ /* Task A: FIR filtering and prescaling */
+ {R_A0_A_HORIZ_PRESCALING,1,
+ "Task A: Horizontal prescaling"},
+ {R_A1_A_ACCUMULATION_LENGTH,1,
+ "Task A: Accumulation length"},
+ {R_A2_A_PRESCALER_DC_GAIN_AND_FIR_PREFILTER,1,
+ "Task A: Prescaler DC gain and FIR prefilter"},
+ /* 0xa3 - Reserved */
+ {R_A4_A_LUMA_BRIGHTNESS_CNTL,1,
+ "Task A: Luminance brightness control"},
+ {R_A5_A_LUMA_CONTRAST_CNTL,1,
+ "Task A: Luminance contrast control"},
+ {R_A6_A_CHROMA_SATURATION_CNTL,1,
+ "Task A: Chrominance saturation control"},
+ /* 0xa7 - Reserved */
+
+ /* Task A: Horizontal phase scaling */
+ {R_A8_A_HORIZ_LUMA_SCALING_INC,2,
+ "Task A: Horizontal luminance scaling increment"},
+ {R_AA_A_HORIZ_LUMA_PHASE_OFF,1,
+ "Task A: Horizontal luminance phase offset"},
+ /* 0xab - Reserved */
+ {R_AC_A_HORIZ_CHROMA_SCALING_INC,2,
+ "Task A: Horizontal chrominance scaling increment"},
+ {R_AE_A_HORIZ_CHROMA_PHASE_OFF,1,
+ "Task A: Horizontal chrominance phase offset"},
+ /* 0xaf - Reserved */
+
+ /* Task A: Vertical scaling */
+ {R_B0_A_VERT_LUMA_SCALING_INC,2,
+ "Task A: Vertical luminance scaling increment"},
+ {R_B2_A_VERT_CHROMA_SCALING_INC,2,
+ "Task A: Vertical chrominance scaling increment"},
+ {R_B4_A_VERT_SCALING_MODE_CNTL,1,
+ "Task A: Vertical scaling mode control"},
+ /* 0xb5-0xb7 - Reserved */
+ {R_B8_A_VERT_CHROMA_PHASE_OFF_00,1,
+ "Task A: Vertical chrominance phase offset '00'"},
+ {R_B9_A_VERT_CHROMA_PHASE_OFF_01,1,
+ "Task A: Vertical chrominance phase offset '01'"},
+ {R_BA_A_VERT_CHROMA_PHASE_OFF_10,1,
+ "Task A: Vertical chrominance phase offset '10'"},
+ {R_BB_A_VERT_CHROMA_PHASE_OFF_11,1,
+ "Task A: Vertical chrominance phase offset '11'"},
+ {R_BC_A_VERT_LUMA_PHASE_OFF_00,1,
+ "Task A: Vertical luminance phase offset '00'"},
+ {R_BD_A_VERT_LUMA_PHASE_OFF_01,1,
+ "Task A: Vertical luminance phase offset '01'"},
+ {R_BE_A_VERT_LUMA_PHASE_OFF_10,1,
+ "Task A: Vertical luminance phase offset '10'"},
+ {R_BF_A_VERT_LUMA_PHASE_OFF_11,1,
+ "Task A: Vertical luminance phase offset '11'"},
+
+ /* Task B definition: R_C0_B_TASK_HANDLING_CNTL to R_EF_B_VERT_LUMA_PHASE_OFF_11 */
+ /* Task B: Basic settings and acquisition window definition */
+ {R_C0_B_TASK_HANDLING_CNTL,1,
+ "Task B: Task handling control"},
+ {R_C1_B_X_PORT_FORMATS_AND_CONF,1,
+ "Task B: X port formats and configuration"},
+ {R_C2_B_INPUT_REFERENCE_SIGNAL_DEFINITION,1,
+ "Task B: Input reference signal definition"},
+ {R_C3_B_I_PORT_FORMATS_AND_CONF,1,
+ "Task B: I port formats and configuration"},
+ {R_C4_B_HORIZ_INPUT_WINDOW_START,2,
+ "Task B: Horizontal input window start"},
+ {R_C6_B_HORIZ_INPUT_WINDOW_LENGTH,2,
+ "Task B: Horizontal input window length"},
+ {R_C8_B_VERT_INPUT_WINDOW_START,2,
+ "Task B: Vertical input window start"},
+ {R_CA_B_VERT_INPUT_WINDOW_LENGTH,2,
+ "Task B: Vertical input window length"},
+ {R_CC_B_HORIZ_OUTPUT_WINDOW_LENGTH,2,
+ "Task B: Horizontal output window length"},
+ {R_CE_B_VERT_OUTPUT_WINDOW_LENGTH,2,
+ "Task B: Vertical output window length"},
+
+ /* Task B: FIR filtering and prescaling */
+ {R_D0_B_HORIZ_PRESCALING,1,
+ "Task B: Horizontal prescaling"},
+ {R_D1_B_ACCUMULATION_LENGTH,1,
+ "Task B: Accumulation length"},
+ {R_D2_B_PRESCALER_DC_GAIN_AND_FIR_PREFILTER,1,
+ "Task B: Prescaler DC gain and FIR prefilter"},
+ /* 0xd3 - Reserved */
+ {R_D4_B_LUMA_BRIGHTNESS_CNTL,1,
+ "Task B: Luminance brightness control"},
+ {R_D5_B_LUMA_CONTRAST_CNTL,1,
+ "Task B: Luminance contrast control"},
+ {R_D6_B_CHROMA_SATURATION_CNTL,1,
+ "Task B: Chrominance saturation control"},
+ /* 0xd7 - Reserved */
+
+ /* Task B: Horizontal phase scaling */
+ {R_D8_B_HORIZ_LUMA_SCALING_INC,2,
+ "Task B: Horizontal luminance scaling increment"},
+ {R_DA_B_HORIZ_LUMA_PHASE_OFF,1,
+ "Task B: Horizontal luminance phase offset"},
+ /* 0xdb - Reserved */
+ {R_DC_B_HORIZ_CHROMA_SCALING,2,
+ "Task B: Horizontal chrominance scaling"},
+ {R_DE_B_HORIZ_PHASE_OFFSET_CRHOMA,1,
+ "Task B: Horizontal Phase Offset Chroma"},
+ /* 0xdf - Reserved */
+
+ /* Task B: Vertical scaling */
+ {R_E0_B_VERT_LUMA_SCALING_INC,2,
+ "Task B: Vertical luminance scaling increment"},
+ {R_E2_B_VERT_CHROMA_SCALING_INC,2,
+ "Task B: Vertical chrominance scaling increment"},
+ {R_E4_B_VERT_SCALING_MODE_CNTL,1,
+ "Task B: Vertical scaling mode control"},
+ /* 0xe5-0xe7 - Reserved */
+ {R_E8_B_VERT_CHROMA_PHASE_OFF_00,1,
+ "Task B: Vertical chrominance phase offset '00'"},
+ {R_E9_B_VERT_CHROMA_PHASE_OFF_01,1,
+ "Task B: Vertical chrominance phase offset '01'"},
+ {R_EA_B_VERT_CHROMA_PHASE_OFF_10,1,
+ "Task B: Vertical chrominance phase offset '10'"},
+ {R_EB_B_VERT_CHROMA_PHASE_OFF_11,1,
+ "Task B: Vertical chrominance phase offset '11'"},
+ {R_EC_B_VERT_LUMA_PHASE_OFF_00,1,
+ "Task B: Vertical luminance phase offset '00'"},
+ {R_ED_B_VERT_LUMA_PHASE_OFF_01,1,
+ "Task B: Vertical luminance phase offset '01'"},
+ {R_EE_B_VERT_LUMA_PHASE_OFF_10,1,
+ "Task B: Vertical luminance phase offset '10'"},
+ {R_EF_B_VERT_LUMA_PHASE_OFF_11,1,
+ "Task B: Vertical luminance phase offset '11'"},
+
+ /* second PLL (PLL2) and Pulsegenerator Programming */
+ { R_F0_LFCO_PER_LINE, 1,
+ "LFCO's per line"},
+ { R_F1_P_I_PARAM_SELECT,1,
+ "P-/I- Param. Select., PLL Mode, PLL H-Src., LFCO's per line"},
+ { R_F2_NOMINAL_PLL2_DTO,1,
+ "Nominal PLL2 DTO"},
+ {R_F3_PLL_INCREMENT,1,
+ "PLL2 Increment"},
+ {R_F4_PLL2_STATUS,1,
+ "PLL2 Status"},
+ {R_F5_PULSGEN_LINE_LENGTH,1,
+ "Pulsgen. line length"},
+ {R_F6_PULSE_A_POS_LSB_AND_PULSEGEN_CONFIG,1,
+ "Pulse A Position, Pulsgen Resync., Pulsgen. H-Src., Pulsgen. line length"},
+ {R_F7_PULSE_A_POS_MSB,1,
+ "Pulse A Position"},
+ {R_F8_PULSE_B_POS,2,
+ "Pulse B Position"},
+ {R_FA_PULSE_C_POS,2,
+ "Pulse C Position"},
+ /* 0xfc to 0xfe - Reserved */
+ {R_FF_S_PLL_MAX_PHASE_ERR_THRESH_NUM_LINES,1,
+ "S_PLL max. phase, error threshold, PLL2 no. of lines, threshold"},
+};
+#endif
diff --git a/drivers/media/video/saa7134/Kconfig b/drivers/media/video/saa7134/Kconfig
index f5543166d193..59da79ce2efd 100644
--- a/drivers/media/video/saa7134/Kconfig
+++ b/drivers/media/video/saa7134/Kconfig
@@ -41,53 +41,15 @@ config VIDEO_SAA7134_DVB
select VIDEO_BUF_DVB
select FW_LOADER
select DVB_PLL
+ select DVB_MT352 if !DVB_FE_CUSTOMISE
+ select DVB_TDA1004X if !DVB_FE_CUSTOMISE
+ select DVB_NXT200X if !DVB_FE_CUSTOMISE
+ select DVB_TDA10086 if !DVB_FE_CUSTOMISE
+ select DVB_TDA826X if !DVB_FE_CUSTOMISE
+ select DVB_ISL6421 if !DVB_FE_CUSTOMISE
---help---
This adds support for DVB cards based on the
Philips saa7134 chip.
To compile this driver as a module, choose M here: the
module will be called saa7134-dvb.
-
- You must also select one or more DVB demodulators.
- If you are unsure which you need, choose all of them.
-
-config VIDEO_SAA7134_DVB_ALL_FRONTENDS
- bool "Build all supported frontends for saa7134 based TV cards"
- default y
- depends on VIDEO_SAA7134_DVB
- select DVB_MT352
- select DVB_TDA1004X
- select DVB_NXT200X
- ---help---
- This builds saa7134-dvb with all currently supported frontend
- demodulators. If you wish to tweak your configuration, and
- only include support for the hardware that you need, choose N here.
-
- If you are unsure, choose Y.
-
-config VIDEO_SAA7134_DVB_MT352
- bool "Zarlink MT352 DVB-T Support"
- default y
- depends on VIDEO_SAA7134_DVB && !VIDEO_SAA7134_DVB_ALL_FRONTENDS
- select DVB_MT352
- ---help---
- This adds DVB-T support for cards based on the
- Philips saa7134 chip and the MT352 demodulator.
-
-config VIDEO_SAA7134_DVB_TDA1004X
- bool "Phillips TDA10045H/TDA10046H DVB-T Support"
- default y
- depends on VIDEO_SAA7134_DVB && !VIDEO_SAA7134_DVB_ALL_FRONTENDS
- select DVB_TDA1004X
- ---help---
- This adds DVB-T support for cards based on the
- Philips saa7134 chip and the TDA10045H/TDA10046H demodulator.
-
-config VIDEO_SAA7134_DVB_NXT200X
- bool "NXT2002/NXT2004 ATSC Support"
- default y
- depends on VIDEO_SAA7134_DVB && !VIDEO_SAA7134_DVB_ALL_FRONTENDS
- select DVB_NXT200X
- ---help---
- This adds ATSC 8VSB and QAM64/256 support for cards based on the
- Philips saa7134 chip and the NXT2002/NXT2004 demodulator.
diff --git a/drivers/media/video/saa7134/Makefile b/drivers/media/video/saa7134/Makefile
index be7b9ee697d6..89a1565b4256 100644
--- a/drivers/media/video/saa7134/Makefile
+++ b/drivers/media/video/saa7134/Makefile
@@ -16,8 +16,5 @@ EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core
EXTRA_CFLAGS += -Idrivers/media/dvb/frontends
extra-cflags-$(CONFIG_VIDEO_BUF_DVB) += -DHAVE_VIDEO_BUF_DVB=1
-extra-cflags-$(CONFIG_DVB_MT352) += -DHAVE_MT352=1
-extra-cflags-$(CONFIG_DVB_TDA1004X) += -DHAVE_TDA1004X=1
-extra-cflags-$(CONFIG_DVB_NXT200X) += -DHAVE_NXT200X=1
EXTRA_CFLAGS += $(extra-cflags-y) $(extra-cflags-m)
diff --git a/drivers/media/video/saa7134/saa7134-alsa.c b/drivers/media/video/saa7134/saa7134-alsa.c
index d73cff1970ae..a39e0136ce3b 100644
--- a/drivers/media/video/saa7134/saa7134-alsa.c
+++ b/drivers/media/video/saa7134/saa7134-alsa.c
@@ -590,6 +590,11 @@ static int snd_card_saa7134_hw_free(struct snd_pcm_substream * substream)
static int snd_card_saa7134_capture_close(struct snd_pcm_substream * substream)
{
+ snd_card_saa7134_t *saa7134 = snd_pcm_substream_chip(substream);
+ struct saa7134_dev *dev = saa7134->dev;
+
+ dev->ctl_mute = 1;
+ saa7134_tvaudio_setmute(dev);
return 0;
}
@@ -631,6 +636,9 @@ static int snd_card_saa7134_capture_open(struct snd_pcm_substream * substream)
runtime->private_free = snd_card_saa7134_runtime_free;
runtime->hw = snd_card_saa7134_capture;
+ dev->ctl_mute = 0;
+ saa7134_tvaudio_setmute(dev);
+
if ((err = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS)) < 0)
return err;
diff --git a/drivers/media/video/saa7134/saa7134-cards.c b/drivers/media/video/saa7134/saa7134-cards.c
index 927413aded10..aa1db509f3d4 100644
--- a/drivers/media/video/saa7134/saa7134-cards.c
+++ b/drivers/media/video/saa7134/saa7134-cards.c
@@ -1911,7 +1911,7 @@ struct saa7134_board saa7134_boards[] = {
},
},
[SAA7134_BOARD_FLYDVBT_DUO_CARDBUS] = {
- .name = "LifeView/Typhoon FlyDVB-T Duo Cardbus",
+ .name = "LifeView/Typhoon/Genius FlyDVB-T Duo Cardbus",
.audio_clock = 0x00200000,
.tuner_type = TUNER_PHILIPS_TDA8290,
.radio_type = UNSET,
@@ -2891,6 +2891,80 @@ struct saa7134_board saa7134_boards[] = {
.gpio = 0x8000,
},
},
+ [SAA7134_BOARD_MEDION_MD8800_QUADRO] = {
+ .name = "Medion Md8800 Quadro",
+ .audio_clock = 0x00187de7,
+ .tuner_type = TUNER_PHILIPS_TDA8290,
+ .radio_type = UNSET,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ .mpeg = SAA7134_MPEG_DVB,
+ .inputs = {{
+ .name = name_tv,
+ .vmux = 1,
+ .amux = TV,
+ .tv = 1,
+ },{
+ .name = name_comp1,
+ .vmux = 0,
+ .amux = LINE2,
+ },{
+ .name = name_svideo,
+ .vmux = 8,
+ .amux = LINE2,
+ }},
+ },
+ [SAA7134_BOARD_FLYDVBS_LR300] = {
+ /* LifeView FlyDVB-s */
+ /* Igor M. Liplianin <liplianin@tut.by> */
+ .name = "LifeView FlyDVB-S /Acorp TV134DS",
+ .audio_clock = 0x00200000,
+ .tuner_type = TUNER_ABSENT,
+ .radio_type = UNSET,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ .mpeg = SAA7134_MPEG_DVB,
+ .inputs = {{
+ .name = name_comp1, /* Composite input */
+ .vmux = 3,
+ .amux = LINE1,
+ },{
+ .name = name_svideo, /* S-Video signal on S-Video input */
+ .vmux = 8,
+ .amux = LINE1,
+ }},
+ },
+ [SAA7134_BOARD_PROTEUS_2309] = {
+ .name = "Proteus Pro 2309",
+ .audio_clock = 0x00187de7,
+ .tuner_type = TUNER_PHILIPS_FM1216ME_MK3,
+ .radio_type = UNSET,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ .tda9887_conf = TDA9887_PRESENT,
+ .inputs = {{
+ .name = name_tv,
+ .vmux = 1,
+ .amux = LINE2,
+ .tv = 1,
+ },{
+ .name = name_comp1,
+ .vmux = 0,
+ .amux = LINE2,
+ },{
+ .name = name_comp2,
+ .vmux = 3,
+ .amux = LINE2,
+ },{
+ .name = name_svideo,
+ .vmux = 8,
+ .amux = LINE2,
+ }},
+ .mute = {
+ .name = name_mute,
+ .amux = LINE1,
+ },
+ },
};
const unsigned int saa7134_bcount = ARRAY_SIZE(saa7134_boards);
@@ -3375,7 +3449,7 @@ struct pci_device_id saa7134_pci_tbl[] = {
.driver_data = SAA7134_BOARD_FLYDVB_TRIO,
},{
.vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7134, /* SAA 7131E */
+ .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
.subvendor = 0x1461,
.subdevice = 0x2c05,
.driver_data = SAA7134_BOARD_AVERMEDIA_777,
@@ -3422,6 +3496,18 @@ struct pci_device_id saa7134_pci_tbl[] = {
.subdevice = 0x0005,
.driver_data = SAA7134_BOARD_MD7134_BRIDGE_2,
},{
+ .vendor = PCI_VENDOR_ID_PHILIPS,
+ .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
+ .subvendor = 0x5168,
+ .subdevice = 0x0300,
+ .driver_data = SAA7134_BOARD_FLYDVBS_LR300,
+ },{
+ .vendor = PCI_VENDOR_ID_PHILIPS,
+ .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
+ .subvendor = 0x4e42,
+ .subdevice = 0x0300,/* LR300 */
+ .driver_data = SAA7134_BOARD_FLYDVBS_LR300,
+ },{
.vendor = PCI_VENDOR_ID_PHILIPS,
.device = PCI_DEVICE_ID_PHILIPS_SAA7134,
.subvendor = 0x1489,
@@ -3446,6 +3532,36 @@ struct pci_device_id saa7134_pci_tbl[] = {
.subdevice = 0x3502, /* whats the difference to 0x3306 ?*/
.driver_data = SAA7134_BOARD_FLYDVBT_HYBRID_CARDBUS,
},{
+ .vendor = PCI_VENDOR_ID_PHILIPS,
+ .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
+ .subvendor = 0x16be,
+ .subdevice = 0x0007,
+ .driver_data = SAA7134_BOARD_MEDION_MD8800_QUADRO,
+ },{
+ .vendor = PCI_VENDOR_ID_PHILIPS,
+ .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
+ .subvendor = 0x16be,
+ .subdevice = 0x0008,
+ .driver_data = SAA7134_BOARD_MEDION_MD8800_QUADRO,
+ },{
+ .vendor = PCI_VENDOR_ID_PHILIPS,
+ .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
+ .subvendor = 0x1461,
+ .subdevice = 0x2c05,
+ .driver_data = SAA7134_BOARD_AVERMEDIA_777,
+ },{
+ .vendor = PCI_VENDOR_ID_PHILIPS,
+ .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
+ .subvendor = 0x1489,
+ .subdevice = 0x0502, /* Cardbus version */
+ .driver_data = SAA7134_BOARD_FLYDVBT_DUO_CARDBUS,
+ },{
+ .vendor = PCI_VENDOR_ID_PHILIPS,
+ .device = PCI_DEVICE_ID_PHILIPS_SAA7130,
+ .subvendor = 0x0919, /* Philips Proteus PRO 2309 */
+ .subdevice = 0x2003,
+ .driver_data = SAA7134_BOARD_PROTEUS_2309,
+ },{
/* --- boards without eeprom + subsystem ID --- */
.vendor = PCI_VENDOR_ID_PHILIPS,
.device = PCI_DEVICE_ID_PHILIPS_SAA7134,
@@ -3548,6 +3664,12 @@ int saa7134_board_init1(struct saa7134_dev *dev)
case SAA7134_BOARD_SEDNA_PC_TV_CARDBUS:
case SAA7134_BOARD_FLYDVBT_LR301:
case SAA7134_BOARD_FLYDVBTDUO:
+ case SAA7134_BOARD_PROTEUS_2309:
+ dev->has_remote = SAA7134_REMOTE_GPIO;
+ break;
+ case SAA7134_BOARD_FLYDVBS_LR300:
+ saa_writeb(SAA7134_GPIO_GPMODE3, 0x80);
+ saa_writeb(SAA7134_GPIO_GPSTATUS2, 0x40);
dev->has_remote = SAA7134_REMOTE_GPIO;
break;
case SAA7134_BOARD_MD5044:
@@ -3732,6 +3854,7 @@ int saa7134_board_init2(struct saa7134_dev *dev)
case SAA7134_BOARD_PHILIPS_TIGER:
case SAA7134_BOARD_TEVION_DVBT_220RF:
case SAA7134_BOARD_ASUSTeK_P7131_DUAL:
+ case SAA7134_BOARD_MEDION_MD8800_QUADRO:
/* this is a hybrid board, initialize to analog mode
* and configure firmware eeprom address
*/
diff --git a/drivers/media/video/saa7134/saa7134-core.c b/drivers/media/video/saa7134/saa7134-core.c
index be3a81fc90a2..09aa62f61af7 100644
--- a/drivers/media/video/saa7134/saa7134-core.c
+++ b/drivers/media/video/saa7134/saa7134-core.c
@@ -843,7 +843,7 @@ static int __devinit saa7134_initdev(struct pci_dev *pci_dev,
latency = 0x0A;
}
#endif
- if (pci_pci_problems & PCIPCI_FAIL) {
+ if (pci_pci_problems & (PCIPCI_FAIL|PCIAGP_FAIL)) {
printk(KERN_INFO "%s: quirk: this driver and your "
"chipset may not work together"
" in overlay mode.\n",dev->name);
diff --git a/drivers/media/video/saa7134/saa7134-dvb.c b/drivers/media/video/saa7134/saa7134-dvb.c
index 279828b8f299..b6881541e704 100644
--- a/drivers/media/video/saa7134/saa7134-dvb.c
+++ b/drivers/media/video/saa7134/saa7134-dvb.c
@@ -34,17 +34,14 @@
#include <media/v4l2-common.h>
#include "dvb-pll.h"
-#ifdef HAVE_MT352
-# include "mt352.h"
-# include "mt352_priv.h" /* FIXME */
-#endif
-#ifdef HAVE_TDA1004X
-# include "tda1004x.h"
-#endif
-#ifdef HAVE_NXT200X
-# include "nxt200x.h"
-#endif
-
+#include "mt352.h"
+#include "mt352_priv.h" /* FIXME */
+#include "tda1004x.h"
+#include "nxt200x.h"
+
+#include "tda10086.h"
+#include "tda826x.h"
+#include "isl6421.h"
MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]");
MODULE_LICENSE("GPL");
@@ -54,8 +51,6 @@ module_param(antenna_pwr, int, 0444);
MODULE_PARM_DESC(antenna_pwr,"enable antenna power (Pinnacle 300i)");
/* ------------------------------------------------------------------ */
-
-#ifdef HAVE_MT352
static int pinnacle_antenna_pwr(struct saa7134_dev *dev, int on)
{
u32 ok;
@@ -185,12 +180,8 @@ static struct mt352_config avermedia_777 = {
.demod_address = 0xf,
.demod_init = mt352_aver777_init,
};
-#endif
/* ------------------------------------------------------------------ */
-
-#ifdef HAVE_TDA1004X
-
static int philips_tda6651_pll_set(u8 addr, struct dvb_frontend *fe, struct dvb_frontend_parameters *params)
{
struct saa7134_dev *dev = fe->dvb->priv;
@@ -969,11 +960,58 @@ static struct tda1004x_config tevion_dvbt220rf_config = {
.request_firmware = NULL,
};
-#endif
+/* ------------------------------------------------------------------ */
+
+static int md8800_dvbt_analog_mode(struct dvb_frontend *fe)
+{
+ struct saa7134_dev *dev = fe->dvb->priv;
+ static u8 data[] = { 0x3c, 0x33, 0x68};
+ struct i2c_msg msg = {.addr=0x08, .flags=0, .buf=data, .len = sizeof(data)};
+
+ i2c_transfer(&dev->i2c_adap, &msg, 1);
+ philips_tda827xa_tuner_sleep( 0x61, fe);
+ return 0;
+}
+
+static int md8800_dvbt_pll_set(struct dvb_frontend *fe, struct dvb_frontend_parameters *params)
+{
+ int ret;
+ struct saa7134_dev *dev = fe->dvb->priv;
+ static u8 tda8290_close[] = { 0x21, 0xc0};
+ static u8 tda8290_open[] = { 0x21, 0x80};
+ struct i2c_msg tda8290_msg = {.addr = 0x4b,.flags = 0, .len = 2};
+ /* close tda8290 i2c bridge */
+ tda8290_msg.buf = tda8290_close;
+ ret = i2c_transfer(&dev->i2c_adap, &tda8290_msg, 1);
+ if (ret != 1)
+ return -EIO;
+ msleep(20);
+ ret = philips_tda827xa_pll_set(0x60, fe, params);
+ if (ret != 0)
+ return ret;
+ /* open tda8290 i2c bridge */
+ tda8290_msg.buf = tda8290_open;
+ i2c_transfer(&dev->i2c_adap, &tda8290_msg, 1);
+ return ret;
+}
+
+static struct tda1004x_config md8800_dvbt_config = {
+ .demod_address = 0x08,
+ .invert = 1,
+ .invert_oclk = 0,
+ .xtal_freq = TDA10046_XTAL_16M,
+ .agc_config = TDA10046_AGC_TDA827X,
+ .if_freq = TDA10046_FREQ_045,
+ .request_firmware = NULL,
+};
+
+static struct tda10086_config flydvbs = {
+ .demod_address = 0x0e,
+ .invert = 0,
+};
/* ------------------------------------------------------------------ */
-#ifdef HAVE_NXT200X
static struct nxt200x_config avertvhda180 = {
.demod_address = 0x0a,
};
@@ -991,7 +1029,6 @@ static struct nxt200x_config kworldatsc110 = {
.demod_address = 0x0a,
.set_pll_input = nxt200x_set_pll_input,
};
-#endif
/* ------------------------------------------------------------------ */
@@ -1009,29 +1046,26 @@ static int dvb_init(struct saa7134_dev *dev)
dev);
switch (dev->board) {
-#ifdef HAVE_MT352
case SAA7134_BOARD_PINNACLE_300I_DVBT_PAL:
printk("%s: pinnacle 300i dvb setup\n",dev->name);
- dev->dvb.frontend = mt352_attach(&pinnacle_300i,
- &dev->i2c_adap);
+ dev->dvb.frontend = dvb_attach(mt352_attach, &pinnacle_300i,
+ &dev->i2c_adap);
if (dev->dvb.frontend) {
dev->dvb.frontend->ops.tuner_ops.set_params = mt352_pinnacle_tuner_set_params;
}
break;
-
case SAA7134_BOARD_AVERMEDIA_777:
printk("%s: avertv 777 dvb setup\n",dev->name);
- dev->dvb.frontend = mt352_attach(&avermedia_777,
- &dev->i2c_adap);
+ dev->dvb.frontend = dvb_attach(mt352_attach, &avermedia_777,
+ &dev->i2c_adap);
if (dev->dvb.frontend) {
dev->dvb.frontend->ops.tuner_ops.calc_regs = mt352_aver777_tuner_calc_regs;
}
break;
-#endif
-#ifdef HAVE_TDA1004X
case SAA7134_BOARD_MD7134:
- dev->dvb.frontend = tda10046_attach(&medion_cardbus,
- &dev->i2c_adap);
+ dev->dvb.frontend = dvb_attach(tda10046_attach,
+ &medion_cardbus,
+ &dev->i2c_adap);
if (dev->dvb.frontend) {
dev->dvb.frontend->ops.tuner_ops.init = philips_fmd1216_tuner_init;
dev->dvb.frontend->ops.tuner_ops.sleep = philips_fmd1216_tuner_sleep;
@@ -1039,16 +1073,18 @@ static int dvb_init(struct saa7134_dev *dev)
}
break;
case SAA7134_BOARD_PHILIPS_TOUGH:
- dev->dvb.frontend = tda10046_attach(&philips_tu1216_60_config,
- &dev->i2c_adap);
+ dev->dvb.frontend = dvb_attach(tda10046_attach,
+ &philips_tu1216_60_config,
+ &dev->i2c_adap);
if (dev->dvb.frontend) {
dev->dvb.frontend->ops.tuner_ops.init = philips_tu1216_tuner_60_init;
dev->dvb.frontend->ops.tuner_ops.set_params = philips_tu1216_tuner_60_set_params;
}
break;
case SAA7134_BOARD_FLYDVBTDUO:
- dev->dvb.frontend = tda10046_attach(&tda827x_lifeview_config,
- &dev->i2c_adap);
+ dev->dvb.frontend = dvb_attach(tda10046_attach,
+ &tda827x_lifeview_config,
+ &dev->i2c_adap);
if (dev->dvb.frontend) {
dev->dvb.frontend->ops.tuner_ops.init = philips_tda827x_tuner_init;
dev->dvb.frontend->ops.tuner_ops.sleep = philips_tda827x_tuner_sleep;
@@ -1056,8 +1092,9 @@ static int dvb_init(struct saa7134_dev *dev)
}
break;
case SAA7134_BOARD_FLYDVBT_DUO_CARDBUS:
- dev->dvb.frontend = tda10046_attach(&tda827x_lifeview_config,
- &dev->i2c_adap);
+ dev->dvb.frontend = dvb_attach(tda10046_attach,
+ &tda827x_lifeview_config,
+ &dev->i2c_adap);
if (dev->dvb.frontend) {
dev->dvb.frontend->ops.tuner_ops.init = philips_tda827x_tuner_init;
dev->dvb.frontend->ops.tuner_ops.sleep = philips_tda827x_tuner_sleep;
@@ -1065,8 +1102,9 @@ static int dvb_init(struct saa7134_dev *dev)
}
break;
case SAA7134_BOARD_PHILIPS_EUROPA:
- dev->dvb.frontend = tda10046_attach(&philips_europa_config,
- &dev->i2c_adap);
+ dev->dvb.frontend = dvb_attach(tda10046_attach,
+ &philips_europa_config,
+ &dev->i2c_adap);
if (dev->dvb.frontend) {
dev->original_demod_sleep = dev->dvb.frontend->ops.sleep;
dev->dvb.frontend->ops.sleep = philips_europa_demod_sleep;
@@ -1076,8 +1114,9 @@ static int dvb_init(struct saa7134_dev *dev)
}
break;
case SAA7134_BOARD_VIDEOMATE_DVBT_300:
- dev->dvb.frontend = tda10046_attach(&philips_europa_config,
- &dev->i2c_adap);
+ dev->dvb.frontend = dvb_attach(tda10046_attach,
+ &philips_europa_config,
+ &dev->i2c_adap);
if (dev->dvb.frontend) {
dev->dvb.frontend->ops.tuner_ops.init = philips_europa_tuner_init;
dev->dvb.frontend->ops.tuner_ops.sleep = philips_europa_tuner_sleep;
@@ -1085,16 +1124,18 @@ static int dvb_init(struct saa7134_dev *dev)
}
break;
case SAA7134_BOARD_VIDEOMATE_DVBT_200:
- dev->dvb.frontend = tda10046_attach(&philips_tu1216_61_config,
- &dev->i2c_adap);
+ dev->dvb.frontend = dvb_attach(tda10046_attach,
+ &philips_tu1216_61_config,
+ &dev->i2c_adap);
if (dev->dvb.frontend) {
dev->dvb.frontend->ops.tuner_ops.init = philips_tu1216_tuner_61_init;
dev->dvb.frontend->ops.tuner_ops.set_params = philips_tu1216_tuner_61_set_params;
}
break;
case SAA7134_BOARD_PHILIPS_TIGER:
- dev->dvb.frontend = tda10046_attach(&philips_tiger_config,
- &dev->i2c_adap);
+ dev->dvb.frontend = dvb_attach(tda10046_attach,
+ &philips_tiger_config,
+ &dev->i2c_adap);
if (dev->dvb.frontend) {
dev->dvb.frontend->ops.tuner_ops.init = philips_tiger_tuner_init;
dev->dvb.frontend->ops.tuner_ops.sleep = philips_tiger_tuner_sleep;
@@ -1102,8 +1143,9 @@ static int dvb_init(struct saa7134_dev *dev)
}
break;
case SAA7134_BOARD_ASUSTeK_P7131_DUAL:
- dev->dvb.frontend = tda10046_attach(&philips_tiger_config,
- &dev->i2c_adap);
+ dev->dvb.frontend = dvb_attach(tda10046_attach,
+ &philips_tiger_config,
+ &dev->i2c_adap);
if (dev->dvb.frontend) {
dev->dvb.frontend->ops.tuner_ops.init = philips_tiger_tuner_init;
dev->dvb.frontend->ops.tuner_ops.sleep = philips_tiger_tuner_sleep;
@@ -1111,8 +1153,9 @@ static int dvb_init(struct saa7134_dev *dev)
}
break;
case SAA7134_BOARD_FLYDVBT_LR301:
- dev->dvb.frontend = tda10046_attach(&tda827x_lifeview_config,
- &dev->i2c_adap);
+ dev->dvb.frontend = dvb_attach(tda10046_attach,
+ &tda827x_lifeview_config,
+ &dev->i2c_adap);
if (dev->dvb.frontend) {
dev->dvb.frontend->ops.tuner_ops.init = philips_tda827x_tuner_init;
dev->dvb.frontend->ops.tuner_ops.sleep = philips_tda827x_tuner_sleep;
@@ -1120,16 +1163,18 @@ static int dvb_init(struct saa7134_dev *dev)
}
break;
case SAA7134_BOARD_FLYDVB_TRIO:
- dev->dvb.frontend = tda10046_attach(&lifeview_trio_config,
- &dev->i2c_adap);
+ dev->dvb.frontend = dvb_attach(tda10046_attach,
+ &lifeview_trio_config,
+ &dev->i2c_adap);
if (dev->dvb.frontend) {
dev->dvb.frontend->ops.tuner_ops.sleep = lifeview_trio_tuner_sleep;
dev->dvb.frontend->ops.tuner_ops.set_params = lifeview_trio_tuner_set_params;
}
break;
case SAA7134_BOARD_ADS_DUO_CARDBUS_PTV331:
- dev->dvb.frontend = tda10046_attach(&ads_tech_duo_config,
- &dev->i2c_adap);
+ dev->dvb.frontend = dvb_attach(tda10046_attach,
+ &ads_tech_duo_config,
+ &dev->i2c_adap);
if (dev->dvb.frontend) {
dev->dvb.frontend->ops.tuner_ops.init = ads_duo_tuner_init;
dev->dvb.frontend->ops.tuner_ops.sleep = ads_duo_tuner_sleep;
@@ -1137,37 +1182,63 @@ static int dvb_init(struct saa7134_dev *dev)
}
break;
case SAA7134_BOARD_TEVION_DVBT_220RF:
- dev->dvb.frontend = tda10046_attach(&tevion_dvbt220rf_config,
- &dev->i2c_adap);
+ dev->dvb.frontend = dvb_attach(tda10046_attach,
+ &tevion_dvbt220rf_config,
+ &dev->i2c_adap);
if (dev->dvb.frontend) {
dev->dvb.frontend->ops.tuner_ops.sleep = tevion_dvb220rf_tuner_sleep;
dev->dvb.frontend->ops.tuner_ops.set_params = tevion_dvb220rf_tuner_set_params;
}
break;
case SAA7134_BOARD_FLYDVBT_HYBRID_CARDBUS:
- dev->dvb.frontend = tda10046_attach(&ads_tech_duo_config,
- &dev->i2c_adap);
+ dev->dvb.frontend = dvb_attach(tda10046_attach,
+ &ads_tech_duo_config,
+ &dev->i2c_adap);
if (dev->dvb.frontend) {
dev->dvb.frontend->ops.tuner_ops.init = ads_duo_tuner_init;
dev->dvb.frontend->ops.tuner_ops.sleep = ads_duo_tuner_sleep;
dev->dvb.frontend->ops.tuner_ops.set_params = ads_duo_tuner_set_params;
}
break;
-#endif
-#ifdef HAVE_NXT200X
+ case SAA7134_BOARD_MEDION_MD8800_QUADRO:
+ dev->dvb.frontend = tda10046_attach(&md8800_dvbt_config,
+ &dev->i2c_adap);
+ if (dev->dvb.frontend) {
+ dev->dvb.frontend->ops.tuner_ops.init = philips_tiger_tuner_init;
+ dev->dvb.frontend->ops.tuner_ops.sleep = md8800_dvbt_analog_mode;
+ dev->dvb.frontend->ops.tuner_ops.set_params = md8800_dvbt_pll_set;
+ }
+ break;
case SAA7134_BOARD_AVERMEDIA_AVERTVHD_A180:
- dev->dvb.frontend = nxt200x_attach(&avertvhda180, &dev->i2c_adap);
+ dev->dvb.frontend = dvb_attach(nxt200x_attach, &avertvhda180,
+ &dev->i2c_adap);
if (dev->dvb.frontend) {
- dvb_pll_attach(dev->dvb.frontend, 0x61, &dev->i2c_adap, &dvb_pll_tdhu2);
+ dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61,
+ NULL, &dvb_pll_tdhu2);
}
break;
case SAA7134_BOARD_KWORLD_ATSC110:
- dev->dvb.frontend = nxt200x_attach(&kworldatsc110, &dev->i2c_adap);
+ dev->dvb.frontend = dvb_attach(nxt200x_attach, &kworldatsc110,
+ &dev->i2c_adap);
+ if (dev->dvb.frontend) {
+ dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61,
+ NULL, &dvb_pll_tuv1236d);
+ }
+ break;
+ case SAA7134_BOARD_FLYDVBS_LR300:
+ dev->dvb.frontend = dvb_attach(tda10086_attach, &flydvbs,
+ &dev->i2c_adap);
if (dev->dvb.frontend) {
- dvb_pll_attach(dev->dvb.frontend, 0x61, &dev->i2c_adap, &dvb_pll_tuv1236d);
+ if (dvb_attach(tda826x_attach, dev->dvb.frontend, 0x60,
+ &dev->i2c_adap, 0) == NULL) {
+ printk("%s: No tda826x found!\n", __FUNCTION__);
+ }
+ if (dvb_attach(isl6421_attach, dev->dvb.frontend,
+ &dev->i2c_adap, 0x08, 0, 0) == NULL) {
+ printk("%s: No ISL6421 found!\n", __FUNCTION__);
+ }
}
break;
-#endif
default:
printk("%s: Huh? unknown DVB card?\n",dev->name);
break;
diff --git a/drivers/media/video/saa7134/saa7134-input.c b/drivers/media/video/saa7134/saa7134-input.c
index 7c595492c56b..f7ea857d5d73 100644
--- a/drivers/media/video/saa7134/saa7134-input.c
+++ b/drivers/media/video/saa7134/saa7134-input.c
@@ -228,6 +228,12 @@ int saa7134_input_init1(struct saa7134_dev *dev)
mask_keyup = 0x400000;
polling = 50; // ms
break;
+ case SAA7134_BOARD_PROTEUS_2309:
+ ir_codes = ir_codes_proteus_2309;
+ mask_keycode = 0x00007F;
+ mask_keyup = 0x000080;
+ polling = 50; // ms
+ break;
case SAA7134_BOARD_VIDEOMATE_DVBT_300:
case SAA7134_BOARD_VIDEOMATE_DVBT_200:
ir_codes = ir_codes_videomate_tv_pvr;
diff --git a/drivers/media/video/saa7134/saa7134-tvaudio.c b/drivers/media/video/saa7134/saa7134-tvaudio.c
index 0db53d192b2a..d31220d20495 100644
--- a/drivers/media/video/saa7134/saa7134-tvaudio.c
+++ b/drivers/media/video/saa7134/saa7134-tvaudio.c
@@ -1046,6 +1046,7 @@ int saa7134_tvaudio_do_scan(struct saa7134_dev *dev)
}
EXPORT_SYMBOL(saa_dsp_writel);
+EXPORT_SYMBOL(saa7134_tvaudio_setmute);
/* ----------------------------------------------------------- */
/*
diff --git a/drivers/media/video/saa7134/saa7134.h b/drivers/media/video/saa7134/saa7134.h
index c04ce6152fd5..7db7b9705953 100644
--- a/drivers/media/video/saa7134/saa7134.h
+++ b/drivers/media/video/saa7134/saa7134.h
@@ -223,6 +223,9 @@ struct saa7134_format {
#define SAA7134_BOARD_MD7134_BRIDGE_2 93
#define SAA7134_BOARD_FLYDVBT_HYBRID_CARDBUS 94
#define SAA7134_BOARD_FLYVIDEO3000_NTSC 95
+#define SAA7134_BOARD_MEDION_MD8800_QUADRO 96
+#define SAA7134_BOARD_FLYDVBS_LR300 97
+#define SAA7134_BOARD_PROTEUS_2309 98
#define SAA7134_MAXBOARDS 8
#define SAA7134_INPUT_MAX 8
diff --git a/drivers/media/video/tda9887.c b/drivers/media/video/tda9887.c
index 8dab481d384a..87ffb0e84a7a 100644
--- a/drivers/media/video/tda9887.c
+++ b/drivers/media/video/tda9887.c
@@ -480,6 +480,8 @@ static int tda9887_set_config(struct tuner *t, char *buf)
}
if ((t->tda9887_config & TDA9887_INTERCARRIER_NTSC) && (t->std & V4L2_STD_NTSC))
buf[1] &= ~cQSS;
+ if (t->tda9887_config & TDA9887_GATING_18)
+ buf[3] &= ~cGating_36;
return 0;
}
diff --git a/drivers/media/video/tuner-simple.c b/drivers/media/video/tuner-simple.c
index abe37cf632c6..63db4e97ae6c 100644
--- a/drivers/media/video/tuner-simple.c
+++ b/drivers/media/video/tuner-simple.c
@@ -10,7 +10,7 @@
#include <media/v4l2-common.h>
static int offset = 0;
-module_param(offset, int, 0666);
+module_param(offset, int, 0664);
MODULE_PARM_DESC(offset,"Allows to specify an offset for tuner");
/* ---------------------------------------------------------------------- */
@@ -331,6 +331,8 @@ static void default_set_tv_freq(struct i2c_client *c, unsigned int freq)
else if (params->default_top_high)
config |= TDA9887_TOP(params->default_top_high);
}
+ if (params->default_pll_gating_18)
+ config |= TDA9887_GATING_18;
i2c_clients_command(c->adapter, TDA9887_SET_CONFIG, &config);
}
tuner_dbg("tv 0x%02x 0x%02x 0x%02x 0x%02x\n",
@@ -439,8 +441,6 @@ static void default_set_radio_freq(struct i2c_client *c, unsigned int freq)
buffer[3] = 0xa4;
break;
}
- buffer[0] = (div>>8) & 0x7f;
- buffer[1] = div & 0xff;
if (params->cb_first_if_lower_freq && div < t->last_div) {
buffer[0] = buffer[2];
buffer[1] = buffer[3];
diff --git a/drivers/media/video/tuner-types.c b/drivers/media/video/tuner-types.c
index 8b542599ed47..8fff642fad56 100644
--- a/drivers/media/video/tuner-types.c
+++ b/drivers/media/video/tuner-types.c
@@ -650,6 +650,7 @@ static struct tuner_params tuner_microtune_4049_fm5_params[] = {
.count = ARRAY_SIZE(tuner_temic_4009f_5_pal_ranges),
.has_tda9887 = 1,
.port1_invert_for_secam_lc = 1,
+ .default_pll_gating_18 = 1,
},
};
diff --git a/drivers/media/video/tvaudio.c b/drivers/media/video/tvaudio.c
index 936e3f746fba..fcaef4bf8289 100644
--- a/drivers/media/video/tvaudio.c
+++ b/drivers/media/video/tvaudio.c
@@ -28,6 +28,7 @@
#include <linux/i2c-algo-bit.h>
#include <linux/init.h>
#include <linux/smp_lock.h>
+#include <linux/kthread.h>
#include <media/tvaudio.h>
#include <media/v4l2-common.h>
@@ -124,11 +125,8 @@ struct CHIPSTATE {
int input;
/* thread */
- pid_t tpid;
- struct completion texit;
- wait_queue_head_t wq;
+ struct task_struct *thread;
struct timer_list wt;
- int done;
int watch_stereo;
int audmode;
};
@@ -264,28 +262,23 @@ static int chip_cmd(struct CHIPSTATE *chip, char *name, audiocmd *cmd)
static void chip_thread_wake(unsigned long data)
{
struct CHIPSTATE *chip = (struct CHIPSTATE*)data;
- wake_up_interruptible(&chip->wq);
+ wake_up_process(chip->thread);
}
static int chip_thread(void *data)
{
- DECLARE_WAITQUEUE(wait, current);
struct CHIPSTATE *chip = data;
struct CHIPDESC *desc = chiplist + chip->type;
- daemonize("%s", chip->c.name);
- allow_signal(SIGTERM);
v4l_dbg(1, debug, &chip->c, "%s: thread started\n", chip->c.name);
for (;;) {
- add_wait_queue(&chip->wq, &wait);
- if (!chip->done) {
- set_current_state(TASK_INTERRUPTIBLE);
+ set_current_state(TASK_INTERRUPTIBLE);
+ if (!kthread_should_stop())
schedule();
- }
- remove_wait_queue(&chip->wq, &wait);
+ set_current_state(TASK_RUNNING);
try_to_freeze();
- if (chip->done || signal_pending(current))
+ if (kthread_should_stop())
break;
v4l_dbg(1, debug, &chip->c, "%s: thread wakeup\n", chip->c.name);
@@ -301,7 +294,6 @@ static int chip_thread(void *data)
}
v4l_dbg(1, debug, &chip->c, "%s: thread exiting\n", chip->c.name);
- complete_and_exit(&chip->texit, 0);
return 0;
}
@@ -1536,19 +1528,18 @@ static int chip_attach(struct i2c_adapter *adap, int addr, int kind)
chip_write(chip,desc->treblereg,desc->treblefunc(chip->treble));
}
- chip->tpid = -1;
+ chip->thread = NULL;
if (desc->checkmode) {
/* start async thread */
init_timer(&chip->wt);
chip->wt.function = chip_thread_wake;
chip->wt.data = (unsigned long)chip;
- init_waitqueue_head(&chip->wq);
- init_completion(&chip->texit);
- chip->tpid = kernel_thread(chip_thread,(void *)chip,0);
- if (chip->tpid < 0)
- v4l_warn(&chip->c, "%s: kernel_thread() failed\n",
+ chip->thread = kthread_run(chip_thread, chip, chip->c.name);
+ if (IS_ERR(chip->thread)) {
+ v4l_warn(&chip->c, "%s: failed to create kthread\n",
chip->c.name);
- wake_up_interruptible(&chip->wq);
+ chip->thread = NULL;
+ }
}
return 0;
}
@@ -1569,11 +1560,10 @@ static int chip_detach(struct i2c_client *client)
struct CHIPSTATE *chip = i2c_get_clientdata(client);
del_timer_sync(&chip->wt);
- if (chip->tpid >= 0) {
+ if (chip->thread) {
/* shutdown async thread */
- chip->done = 1;
- wake_up_interruptible(&chip->wq);
- wait_for_completion(&chip->texit);
+ kthread_stop(chip->thread);
+ chip->thread = NULL;
}
i2c_detach_client(&chip->c);
diff --git a/drivers/media/video/tveeprom.c b/drivers/media/video/tveeprom.c
index d95529e8e513..cd1502ac9560 100644
--- a/drivers/media/video/tveeprom.c
+++ b/drivers/media/video/tveeprom.c
@@ -605,6 +605,8 @@ void tveeprom_hauppauge_analog(struct i2c_client *c, struct tveeprom *tvee,
tvee->tuner_formats |= hauppauge_tuner_fmt[i].id;
t_fmt_name1[j++] = hauppauge_tuner_fmt[i].name;
}
+ }
+ for (i = j = 0; i < 8; i++) {
if (t_format2 & (1 << i)) {
tvee->tuner2_formats |= hauppauge_tuner_fmt[i].id;
t_fmt_name2[j++] = hauppauge_tuner_fmt[i].name;
diff --git a/drivers/media/video/tvp5150.c b/drivers/media/video/tvp5150.c
index b167ffab2520..bc0a4fc27b24 100644
--- a/drivers/media/video/tvp5150.c
+++ b/drivers/media/video/tvp5150.c
@@ -294,7 +294,7 @@ static inline void tvp5150_selmux(struct i2c_client *c)
if ((decoder->route.output & TVP5150_BLACK_SCREEN) || !decoder->enable)
input = 8;
- switch (input) {
+ switch (decoder->route.input) {
case TVP5150_COMPOSITE1:
input |= 2;
/* fall through */
@@ -308,6 +308,11 @@ static inline void tvp5150_selmux(struct i2c_client *c)
break;
}
+ tvp5150_dbg( 1, "Selecting video route: route input=%i, output=%i "
+ "=> tvp5150 input=%i, opmode=%i\n",
+ decoder->route.input,decoder->route.output,
+ input, opmode );
+
tvp5150_write(c, TVP5150_OP_MODE_CTL, opmode);
tvp5150_write(c, TVP5150_VD_IN_SRC_SEL_1, input);
};
diff --git a/drivers/media/video/usbvideo/konicawc.c b/drivers/media/video/usbvideo/konicawc.c
index 6f31ecc88843..4eee8be88314 100644
--- a/drivers/media/video/usbvideo/konicawc.c
+++ b/drivers/media/video/usbvideo/konicawc.c
@@ -222,6 +222,7 @@ static void konicawc_adjust_picture(struct uvd *uvd)
static void konicawc_register_input(struct konicawc *cam, struct usb_device *dev)
{
struct input_dev *input_dev;
+ int error;
usb_make_path(dev, cam->input_physname, sizeof(cam->input_physname));
strncat(cam->input_physname, "/input0", sizeof(cam->input_physname));
@@ -242,7 +243,13 @@ static void konicawc_register_input(struct konicawc *cam, struct usb_device *dev
input_dev->private = cam;
- input_register_device(cam->input);
+ error = input_register_device(cam->input);
+ if (error) {
+ warn("Failed to register camera's input device, err: %d\n",
+ error);
+ input_free_device(cam->input);
+ cam->input = NULL;
+ }
}
static void konicawc_unregister_input(struct konicawc *cam)
diff --git a/drivers/media/video/usbvideo/vicam.c b/drivers/media/video/usbvideo/vicam.c
index 90d48e8510ba..08f9559a6bfa 100644
--- a/drivers/media/video/usbvideo/vicam.c
+++ b/drivers/media/video/usbvideo/vicam.c
@@ -7,6 +7,7 @@
* Monroe Williams (monroe@pobox.com)
*
* Supports 3COM HomeConnect PC Digital WebCam
+ * Supports Compro PS39U WebCam
*
* 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
@@ -60,6 +61,8 @@
/* Define these values to match your device */
#define USB_VICAM_VENDOR_ID 0x04c1
#define USB_VICAM_PRODUCT_ID 0x009d
+#define USB_COMPRO_VENDOR_ID 0x0602
+#define USB_COMPRO_PRODUCT_ID 0x1001
#define VICAM_BYTES_PER_PIXEL 3
#define VICAM_MAX_READ_SIZE (512*242+128)
@@ -1254,6 +1257,7 @@ static struct video_device vicam_template = {
/* table of devices that work with this driver */
static struct usb_device_id vicam_table[] = {
{USB_DEVICE(USB_VICAM_VENDOR_ID, USB_VICAM_PRODUCT_ID)},
+ {USB_DEVICE(USB_COMPRO_VENDOR_ID, USB_COMPRO_PRODUCT_ID)},
{} /* Terminating entry */
};
diff --git a/drivers/media/video/v4l1-compat.c b/drivers/media/video/v4l1-compat.c
index d7c3fcbc80f7..1d899e2db394 100644
--- a/drivers/media/video/v4l1-compat.c
+++ b/drivers/media/video/v4l1-compat.c
@@ -349,6 +349,8 @@ v4l_compat_translate_ioctl(struct inode *inode,
{
struct video_buffer *buffer = arg;
+ memset(buffer, 0, sizeof(*buffer));
+
err = drv(inode, file, VIDIOC_G_FBUF, &fbuf2);
if (err < 0) {
dprintk("VIDIOCGFBUF / VIDIOC_G_FBUF: %d\n",err);
@@ -361,7 +363,7 @@ v4l_compat_translate_ioctl(struct inode *inode,
switch (fbuf2.fmt.pixelformat) {
case V4L2_PIX_FMT_RGB332:
buffer->depth = 8;
- break;
+ break;
case V4L2_PIX_FMT_RGB555:
buffer->depth = 15;
break;
@@ -377,9 +379,13 @@ v4l_compat_translate_ioctl(struct inode *inode,
default:
buffer->depth = 0;
}
- if (0 != fbuf2.fmt.bytesperline)
+ if (fbuf2.fmt.bytesperline) {
buffer->bytesperline = fbuf2.fmt.bytesperline;
- else {
+ if (!buffer->depth && buffer->width)
+ buffer->depth = ((fbuf2.fmt.bytesperline<<3)
+ + (buffer->width-1) )
+ /buffer->width;
+ } else {
buffer->bytesperline =
(buffer->width * buffer->depth + 7) & 7;
buffer->bytesperline >>= 3;
diff --git a/drivers/media/video/v4l2-common.c b/drivers/media/video/v4l2-common.c
index 8d972ffdaf98..78d28b03ec93 100644
--- a/drivers/media/video/v4l2-common.c
+++ b/drivers/media/video/v4l2-common.c
@@ -938,6 +938,7 @@ void v4l_printk_ioctl_arg(char *s,unsigned int cmd, void *arg)
case VIDIOC_INT_AUDIO_CLOCK_FREQ:
case VIDIOC_INT_I2S_CLOCK_FREQ:
case VIDIOC_INT_S_STANDBY:
+ case VIDIOC_INT_RESET:
{
u32 *p=arg;
diff --git a/drivers/media/video/video-buf-dvb.c b/drivers/media/video/video-buf-dvb.c
index 7ee8a53cd336..f53edf1923b7 100644
--- a/drivers/media/video/video-buf-dvb.c
+++ b/drivers/media/video/video-buf-dvb.c
@@ -223,6 +223,7 @@ fail_dmxdev:
fail_dmx:
dvb_unregister_frontend(dvb->frontend);
fail_frontend:
+ dvb_frontend_detach(dvb->frontend);
dvb_unregister_adapter(&dvb->adapter);
fail_adapter:
return result;
@@ -236,6 +237,7 @@ void videobuf_dvb_unregister(struct videobuf_dvb *dvb)
dvb_dmxdev_release(&dvb->dmxdev);
dvb_dmx_release(&dvb->demux);
dvb_unregister_frontend(dvb->frontend);
+ dvb_frontend_detach(dvb->frontend);
dvb_unregister_adapter(&dvb->adapter);
}
diff --git a/drivers/media/video/videodev.c b/drivers/media/video/videodev.c
index edd7b83c3464..479a0675cf60 100644
--- a/drivers/media/video/videodev.c
+++ b/drivers/media/video/videodev.c
@@ -739,13 +739,13 @@ static int __video_do_ioctl(struct inode *inode, struct file *file,
case VIDIOC_DQBUF:
{
struct v4l2_buffer *p=arg;
- if (!vfd->vidioc_qbuf)
+ if (!vfd->vidioc_dqbuf)
break;
ret = check_fmt (vfd, p->type);
if (ret)
break;
- ret=vfd->vidioc_qbuf(file, fh, p);
+ ret=vfd->vidioc_dqbuf(file, fh, p);
if (!ret)
dbgbuf(cmd,vfd,p);
break;
@@ -836,7 +836,7 @@ static int __video_do_ioctl(struct inode *inode, struct file *file,
break;
}
- if (index < 0 || index >= vfd->tvnormsize) {
+ if (index<0 || index >= vfd->tvnormsize) {
ret=-EINVAL;
break;
}
@@ -1283,9 +1283,29 @@ static int __video_do_ioctl(struct inode *inode, struct file *file,
case VIDIOC_G_PARM:
{
struct v4l2_streamparm *p=arg;
- if (!vfd->vidioc_g_parm)
- break;
- ret=vfd->vidioc_g_parm(file, fh, p);
+ if (vfd->vidioc_g_parm) {
+ ret=vfd->vidioc_g_parm(file, fh, p);
+ } else {
+ struct v4l2_standard s;
+
+ if (!vfd->tvnormsize) {
+ printk (KERN_WARNING "%s: no TV norms defined!\n",
+ vfd->name);
+ break;
+ }
+
+ if (p->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+ return -EINVAL;
+
+ v4l2_video_std_construct(&s, vfd->tvnorms[vfd->current_norm].id,
+ vfd->tvnorms[vfd->current_norm].name);
+
+ memset(p,0,sizeof(*p));
+
+ p->parm.capture.timeperframe = s.frameperiod;
+ ret=0;
+ }
+
dbgarg (cmd, "type=%d\n", p->type);
break;
}
diff --git a/drivers/media/video/vino.c b/drivers/media/video/vino.c
index 268e69fdefc6..d1e04f7c530b 100644
--- a/drivers/media/video/vino.c
+++ b/drivers/media/video/vino.c
@@ -4404,7 +4404,6 @@ static struct video_device v4l_device_template = {
.name = "NOT SET",
//.type = VID_TYPE_CAPTURE | VID_TYPE_SUBCAPTURE |
// VID_TYPE_CLIPPING | VID_TYPE_SCALES, VID_TYPE_OVERLAY
- .hardware = VID_HARDWARE_VINO,
.fops = &vino_fops,
.minor = -1,
};
diff --git a/drivers/media/video/vivi.c b/drivers/media/video/vivi.c
index 841884af0cc0..e7c01d560b64 100644
--- a/drivers/media/video/vivi.c
+++ b/drivers/media/video/vivi.c
@@ -992,7 +992,8 @@ static int vidiocgmbuf (struct file *file, void *priv, struct video_mbuf *mbuf)
struct vivi_fh *fh=priv;
struct videobuf_queue *q=&fh->vb_vidq;
struct v4l2_requestbuffers req;
- unsigned int i, ret;
+ unsigned int i;
+ int ret;
req.type = q->type;
req.count = 8;
@@ -1359,6 +1360,8 @@ static int __init vivi_init(void)
dev->vidq.timeout.data = (unsigned long)dev;
init_timer(&dev->vidq.timeout);
+ vivi.current_norm = tvnorms[0].id;
+
ret = video_register_device(&vivi, VFL_TYPE_GRABBER, video_nr);
printk(KERN_INFO "Video Technology Magazine Virtual Video Capture Board (Load status: %d)\n", ret);
return ret;
diff --git a/drivers/media/video/vpx3220.c b/drivers/media/video/vpx3220.c
index 1eca7e65d235..8ef31ed7d3f1 100644
--- a/drivers/media/video/vpx3220.c
+++ b/drivers/media/video/vpx3220.c
@@ -744,6 +744,6 @@ vpx3220_cleanup (void)
module_init(vpx3220_init);
module_exit(vpx3220_cleanup);
-MODULE_DESCRIPTION("vpx3220a/vpx3216b/vpx3214c video encoder driver");
+MODULE_DESCRIPTION("vpx3220a/vpx3216b/vpx3214c video decoder driver");
MODULE_AUTHOR("Laurent Pinchart");
MODULE_LICENSE("GPL");
diff --git a/drivers/media/video/zoran_card.c b/drivers/media/video/zoran_card.c
index 29f59c36f001..9f21d0ba0f0f 100644
--- a/drivers/media/video/zoran_card.c
+++ b/drivers/media/video/zoran_card.c
@@ -1620,10 +1620,10 @@ init_dc10_cards (void)
dprintk(5, KERN_DEBUG "Jotti is een held!\n");
/* some mainboards might not do PCI-PCI data transfer well */
- if (pci_pci_problems & PCIPCI_FAIL) {
+ if (pci_pci_problems & (PCIPCI_FAIL|PCIAGP_FAIL|PCIPCI_ALIMAGIK)) {
dprintk(1,
KERN_WARNING
- "%s: chipset may not support reliable PCI-PCI DMA\n",
+ "%s: chipset does not support reliable PCI-PCI DMA\n",
ZORAN_NAME);
}
@@ -1631,7 +1631,7 @@ init_dc10_cards (void)
for (i = 0; i < zoran_num; i++) {
struct zoran *zr = &zoran[i];
- if (pci_pci_problems & PCIPCI_NATOMA && zr->revision <= 1) {
+ if ((pci_pci_problems & PCIPCI_NATOMA) && zr->revision <= 1) {
zr->jpg_buffers.need_contiguous = 1;
dprintk(1,
KERN_INFO
diff --git a/drivers/media/video/zoran_driver.c b/drivers/media/video/zoran_driver.c
index 5f90db27892b..862a984c2155 100644
--- a/drivers/media/video/zoran_driver.c
+++ b/drivers/media/video/zoran_driver.c
@@ -1512,6 +1512,13 @@ setup_fbuffer (struct file *file,
if (!capable(CAP_SYS_ADMIN) && !capable(CAP_SYS_RAWIO))
return -EPERM;
+ /* Don't allow frame buffer overlay if PCI or AGP is buggy, or on
+ ALi Magik (that needs very low latency while the card needs a
+ higher value always) */
+
+ if (pci_pci_problems & (PCIPCI_FAIL | PCIAGP_FAIL | PCIPCI_ALIMAGIK))
+ return -ENXIO;
+
/* we need a bytesperline value, even if not given */
if (!bytesperline)
bytesperline = width * ((fmt->depth + 7) & ~7) / 8;
diff --git a/drivers/media/video/zr36120.c b/drivers/media/video/zr36120.c
index 50437383ed62..9240638a0134 100644
--- a/drivers/media/video/zr36120.c
+++ b/drivers/media/video/zr36120.c
@@ -987,6 +987,8 @@ int zoran_ioctl(struct video_device* dev, unsigned int cmd, void *arg)
VID_TYPE_SCALES;
if (ztv->have_tuner)
c.type |= VID_TYPE_TUNER;
+ if (pci_problems & (PCIPCI_FAIL|PCIAGP_FAIL))
+ c.type &= ~VID_TYPE_OVERLAY;
if (ztv->have_decoder) {
c.channels = ztv->card->video_inputs;
c.audios = ztv->card->audio_inputs;
@@ -1284,6 +1286,8 @@ int zoran_ioctl(struct video_device* dev, unsigned int cmd, void *arg)
struct video_buffer v;
if(!capable(CAP_SYS_ADMIN))
return -EPERM;
+ if (pcipci_problems & (PCIPCI_FAIL|PCIAGP_FAIL))
+ return -ENXIO;
if (copy_from_user(&v, arg,sizeof(v)))
return -EFAULT;
DEBUG(printk(CARD_DEBUG "VIDIOCSFBUF(%p,%d,%d,%d,%d)\n",CARD,v.base, v.width,v.height,v.depth,v.bytesperline));
@@ -2030,7 +2034,7 @@ void release_zoran(int max)
/* free it */
free_irq(ztv->dev->irq,ztv);
- /* unregister i2c_bus */
+ /* unregister i2c_bus */
i2c_unregister_bus((&ztv->i2c));
/* unmap and free memory */
diff --git a/drivers/message/i2o/Kconfig b/drivers/message/i2o/Kconfig
index fef677103880..6443392bffff 100644
--- a/drivers/message/i2o/Kconfig
+++ b/drivers/message/i2o/Kconfig
@@ -88,7 +88,7 @@ config I2O_BUS
config I2O_BLOCK
tristate "I2O Block OSM"
- depends on I2O
+ depends on I2O && BLOCK
---help---
Include support for the I2O Block OSM. The Block OSM presents disk
and other structured block devices to the operating system. If you
diff --git a/drivers/message/i2o/i2o_block.c b/drivers/message/i2o/i2o_block.c
index 1ddc2fb429d5..eaba81bf2eca 100644
--- a/drivers/message/i2o/i2o_block.c
+++ b/drivers/message/i2o/i2o_block.c
@@ -390,9 +390,9 @@ static int i2o_block_prep_req_fn(struct request_queue *q, struct request *req)
}
/* request is already processed by us, so return */
- if (req->flags & REQ_SPECIAL) {
+ if (blk_special_request(req)) {
osm_debug("REQ_SPECIAL already set!\n");
- req->flags |= REQ_DONTPREP;
+ req->cmd_flags |= REQ_DONTPREP;
return BLKPREP_OK;
}
@@ -411,7 +411,8 @@ static int i2o_block_prep_req_fn(struct request_queue *q, struct request *req)
ireq = req->special;
/* do not come back here */
- req->flags |= REQ_DONTPREP | REQ_SPECIAL;
+ req->cmd_type = REQ_TYPE_SPECIAL;
+ req->cmd_flags |= REQ_DONTPREP;
return BLKPREP_OK;
};
diff --git a/drivers/message/i2o/pci.c b/drivers/message/i2o/pci.c
index 1b58444d5aaf..dec41cc89937 100644
--- a/drivers/message/i2o/pci.c
+++ b/drivers/message/i2o/pci.c
@@ -372,12 +372,13 @@ static int __devinit i2o_pci_probe(struct pci_dev *pdev,
* Expose the ship behind i960 for initialization, or it will
* failed
*/
- i960 =
- pci_find_slot(c->pdev->bus->number,
+ i960 = pci_get_slot(c->pdev->bus,
PCI_DEVFN(PCI_SLOT(c->pdev->devfn), 0));
- if (i960)
+ if (i960) {
pci_write_config_word(i960, 0x42, 0);
+ pci_dev_put(i960);
+ }
c->promise = 1;
c->limit_sectors = 1;
diff --git a/drivers/mfd/ucb1x00-ts.c b/drivers/mfd/ucb1x00-ts.c
index 02776814443e..82938ad6ddbd 100644
--- a/drivers/mfd/ucb1x00-ts.c
+++ b/drivers/mfd/ucb1x00-ts.c
@@ -58,6 +58,7 @@ static int adcsync;
static inline void ucb1x00_ts_evt_add(struct ucb1x00_ts *ts, u16 pressure, u16 x, u16 y)
{
struct input_dev *idev = ts->idev;
+
input_report_abs(idev, ABS_X, x);
input_report_abs(idev, ABS_Y, y);
input_report_abs(idev, ABS_PRESSURE, pressure);
@@ -67,6 +68,7 @@ static inline void ucb1x00_ts_evt_add(struct ucb1x00_ts *ts, u16 pressure, u16 x
static inline void ucb1x00_ts_event_release(struct ucb1x00_ts *ts)
{
struct input_dev *idev = ts->idev;
+
input_report_abs(idev, ABS_PRESSURE, 0);
input_sync(idev);
}
@@ -189,6 +191,7 @@ static inline unsigned int ucb1x00_ts_read_yres(struct ucb1x00_ts *ts)
static inline int ucb1x00_ts_pen_down(struct ucb1x00_ts *ts)
{
unsigned int val = ucb1x00_reg_read(ts->ucb, UCB_TS_CR);
+
if (machine_is_collie())
return (!(val & (UCB_TS_CR_TSPX_LOW)));
else
@@ -291,6 +294,7 @@ static int ucb1x00_thread(void *_ts)
static void ucb1x00_ts_irq(int idx, void *id)
{
struct ucb1x00_ts *ts = id;
+
ucb1x00_disable_irq(ts->ucb, UCB_IRQ_TSPX, UCB_FALLING);
wake_up(&ts->irq_wait);
}
@@ -372,36 +376,43 @@ static int ucb1x00_ts_resume(struct ucb1x00_dev *dev)
static int ucb1x00_ts_add(struct ucb1x00_dev *dev)
{
struct ucb1x00_ts *ts;
+ struct input_dev *idev;
+ int err;
ts = kzalloc(sizeof(struct ucb1x00_ts), GFP_KERNEL);
- if (!ts)
- return -ENOMEM;
-
- ts->idev = input_allocate_device();
- if (!ts->idev) {
- kfree(ts);
- return -ENOMEM;
+ idev = input_allocate_device();
+ if (!ts || !idev) {
+ err = -ENOMEM;
+ goto fail;
}
ts->ucb = dev->ucb;
+ ts->idev = idev;
ts->adcsync = adcsync ? UCB_SYNC : UCB_NOSYNC;
- ts->idev->private = ts;
- ts->idev->name = "Touchscreen panel";
- ts->idev->id.product = ts->ucb->id;
- ts->idev->open = ucb1x00_ts_open;
- ts->idev->close = ucb1x00_ts_close;
+ idev->private = ts;
+ idev->name = "Touchscreen panel";
+ idev->id.product = ts->ucb->id;
+ idev->open = ucb1x00_ts_open;
+ idev->close = ucb1x00_ts_close;
- __set_bit(EV_ABS, ts->idev->evbit);
- __set_bit(ABS_X, ts->idev->absbit);
- __set_bit(ABS_Y, ts->idev->absbit);
- __set_bit(ABS_PRESSURE, ts->idev->absbit);
+ __set_bit(EV_ABS, idev->evbit);
+ __set_bit(ABS_X, idev->absbit);
+ __set_bit(ABS_Y, idev->absbit);
+ __set_bit(ABS_PRESSURE, idev->absbit);
- input_register_device(ts->idev);
+ err = input_register_device(idev);
+ if (err)
+ goto fail;
dev->priv = ts;
return 0;
+
+ fail:
+ input_free_device(idev);
+ kfree(ts);
+ return err;
}
static void ucb1x00_ts_remove(struct ucb1x00_dev *dev)
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
index 19c2b85249c3..c1bf1fb04c5c 100644
--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
@@ -3,5 +3,6 @@
#
obj- := misc.o # Dummy rule to force built-in.o to be made
-obj-$(CONFIG_IBM_ASM) += ibmasm/
+obj-$(CONFIG_IBM_ASM) += ibmasm/
obj-$(CONFIG_HDPU_FEATURES) += hdpuftrs/
+obj-$(CONFIG_LKDTM) += lkdtm.o
diff --git a/drivers/misc/lkdtm.c b/drivers/misc/lkdtm.c
new file mode 100644
index 000000000000..e689ee94ac3d
--- /dev/null
+++ b/drivers/misc/lkdtm.c
@@ -0,0 +1,342 @@
+/*
+ * Kprobe module for testing crash dumps
+ *
+ * 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.
+ *
+ * Copyright (C) IBM Corporation, 2006
+ *
+ * Author: Ankita Garg <ankita@in.ibm.com>
+ *
+ * This module induces system failures at predefined crashpoints to
+ * evaluate the reliability of crash dumps obtained using different dumping
+ * solutions.
+ *
+ * It is adapted from the Linux Kernel Dump Test Tool by
+ * Fernando Luis Vazquez Cao <http://lkdtt.sourceforge.net>
+ *
+ * Usage : insmod lkdtm.ko [recur_count={>0}] cpoint_name=<> cpoint_type=<>
+ * [cpoint_count={>0}]
+ *
+ * recur_count : Recursion level for the stack overflow test. Default is 10.
+ *
+ * cpoint_name : Crash point where the kernel is to be crashed. It can be
+ * one of INT_HARDWARE_ENTRY, INT_HW_IRQ_EN, INT_TASKLET_ENTRY,
+ * FS_DEVRW, MEM_SWAPOUT, TIMERADD, SCSI_DISPATCH_CMD,
+ * IDE_CORE_CP
+ *
+ * cpoint_type : Indicates the action to be taken on hitting the crash point.
+ * It can be one of PANIC, BUG, EXCEPTION, LOOP, OVERFLOW
+ *
+ * cpoint_count : Indicates the number of times the crash point is to be hit
+ * to trigger an action. The default is 10.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/kprobes.h>
+#include <linux/kallsyms.h>
+#include <linux/init.h>
+#include <linux/irq.h>
+#include <linux/interrupt.h>
+#include <scsi/scsi_cmnd.h>
+
+#ifdef CONFIG_IDE
+#include <linux/ide.h>
+#endif
+
+#define NUM_CPOINTS 8
+#define NUM_CPOINT_TYPES 5
+#define DEFAULT_COUNT 10
+#define REC_NUM_DEFAULT 10
+
+enum cname {
+ INVALID,
+ INT_HARDWARE_ENTRY,
+ INT_HW_IRQ_EN,
+ INT_TASKLET_ENTRY,
+ FS_DEVRW,
+ MEM_SWAPOUT,
+ TIMERADD,
+ SCSI_DISPATCH_CMD,
+ IDE_CORE_CP
+};
+
+enum ctype {
+ NONE,
+ PANIC,
+ BUG,
+ EXCEPTION,
+ LOOP,
+ OVERFLOW
+};
+
+static char* cp_name[] = {
+ "INT_HARDWARE_ENTRY",
+ "INT_HW_IRQ_EN",
+ "INT_TASKLET_ENTRY",
+ "FS_DEVRW",
+ "MEM_SWAPOUT",
+ "TIMERADD",
+ "SCSI_DISPATCH_CMD",
+ "IDE_CORE_CP"
+};
+
+static char* cp_type[] = {
+ "PANIC",
+ "BUG",
+ "EXCEPTION",
+ "LOOP",
+ "OVERFLOW"
+};
+
+static struct jprobe lkdtm;
+
+static int lkdtm_parse_commandline(void);
+static void lkdtm_handler(void);
+
+static char* cpoint_name = INVALID;
+static char* cpoint_type = NONE;
+static int cpoint_count = DEFAULT_COUNT;
+static int recur_count = REC_NUM_DEFAULT;
+
+static enum cname cpoint = INVALID;
+static enum ctype cptype = NONE;
+static int count = DEFAULT_COUNT;
+
+module_param(recur_count, int, 0644);
+MODULE_PARM_DESC(recur_count, "Recurcion level for the stack overflow test,\
+ default is 10");
+module_param(cpoint_name, charp, 0644);
+MODULE_PARM_DESC(cpoint_name, "Crash Point, where kernel is to be crashed");
+module_param(cpoint_type, charp, 06444);
+MODULE_PARM_DESC(cpoint_type, "Crash Point Type, action to be taken on\
+ hitting the crash point");
+module_param(cpoint_count, int, 06444);
+MODULE_PARM_DESC(cpoint_count, "Crash Point Count, number of times the \
+ crash point is to be hit to trigger action");
+
+unsigned int jp_do_irq(unsigned int irq, struct pt_regs *regs)
+{
+ lkdtm_handler();
+ jprobe_return();
+ return 0;
+}
+
+irqreturn_t jp_handle_irq_event(unsigned int irq, struct pt_regs *regs,
+ struct irqaction *action)
+{
+ lkdtm_handler();
+ jprobe_return();
+ return 0;
+}
+
+void jp_tasklet_action(struct softirq_action *a)
+{
+ lkdtm_handler();
+ jprobe_return();
+}
+
+void jp_ll_rw_block(int rw, int nr, struct buffer_head *bhs[])
+{
+ lkdtm_handler();
+ jprobe_return();
+}
+
+struct scan_control;
+
+unsigned long jp_shrink_page_list(struct list_head *page_list,
+ struct scan_control *sc)
+{
+ lkdtm_handler();
+ jprobe_return();
+ return 0;
+}
+
+int jp_hrtimer_start(struct hrtimer *timer, ktime_t tim,
+ const enum hrtimer_mode mode)
+{
+ lkdtm_handler();
+ jprobe_return();
+ return 0;
+}
+
+int jp_scsi_dispatch_cmd(struct scsi_cmnd *cmd)
+{
+ lkdtm_handler();
+ jprobe_return();
+ return 0;
+}
+
+#ifdef CONFIG_IDE
+int jp_generic_ide_ioctl(ide_drive_t *drive, struct file *file,
+ struct block_device *bdev, unsigned int cmd,
+ unsigned long arg)
+{
+ lkdtm_handler();
+ jprobe_return();
+ return 0;
+}
+#endif
+
+static int lkdtm_parse_commandline(void)
+{
+ int i;
+
+ if (cpoint_name == INVALID || cpoint_type == NONE ||
+ cpoint_count < 1 || recur_count < 1)
+ return -EINVAL;
+
+ for (i = 0; i < NUM_CPOINTS; ++i) {
+ if (!strcmp(cpoint_name, cp_name[i])) {
+ cpoint = i + 1;
+ break;
+ }
+ }
+
+ for (i = 0; i < NUM_CPOINT_TYPES; ++i) {
+ if (!strcmp(cpoint_type, cp_type[i])) {
+ cptype = i + 1;
+ break;
+ }
+ }
+
+ if (cpoint == INVALID || cptype == NONE)
+ return -EINVAL;
+
+ count = cpoint_count;
+
+ return 0;
+}
+
+static int recursive_loop(int a)
+{
+ char buf[1024];
+
+ memset(buf,0xFF,1024);
+ recur_count--;
+ if (!recur_count)
+ return 0;
+ else
+ return recursive_loop(a);
+}
+
+void lkdtm_handler(void)
+{
+ printk(KERN_INFO "lkdtm : Crash point %s of type %s hit\n",
+ cpoint_name, cpoint_type);
+ --count;
+
+ if (count == 0) {
+ switch (cptype) {
+ case NONE:
+ break;
+ case PANIC:
+ printk(KERN_INFO "lkdtm : PANIC\n");
+ panic("dumptest");
+ break;
+ case BUG:
+ printk(KERN_INFO "lkdtm : BUG\n");
+ BUG();
+ break;
+ case EXCEPTION:
+ printk(KERN_INFO "lkdtm : EXCEPTION\n");
+ *((int *) 0) = 0;
+ break;
+ case LOOP:
+ printk(KERN_INFO "lkdtm : LOOP\n");
+ for (;;);
+ break;
+ case OVERFLOW:
+ printk(KERN_INFO "lkdtm : OVERFLOW\n");
+ (void) recursive_loop(0);
+ break;
+ default:
+ break;
+ }
+ count = cpoint_count;
+ }
+}
+
+int lkdtm_module_init(void)
+{
+ int ret;
+
+ if (lkdtm_parse_commandline() == -EINVAL) {
+ printk(KERN_INFO "lkdtm : Invalid command\n");
+ return -EINVAL;
+ }
+
+ switch (cpoint) {
+ case INT_HARDWARE_ENTRY:
+ lkdtm.kp.symbol_name = "__do_IRQ";
+ lkdtm.entry = (kprobe_opcode_t*) jp_do_irq;
+ break;
+ case INT_HW_IRQ_EN:
+ lkdtm.kp.symbol_name = "handle_IRQ_event";
+ lkdtm.entry = (kprobe_opcode_t*) jp_handle_irq_event;
+ break;
+ case INT_TASKLET_ENTRY:
+ lkdtm.kp.symbol_name = "tasklet_action";
+ lkdtm.entry = (kprobe_opcode_t*) jp_tasklet_action;
+ break;
+ case FS_DEVRW:
+ lkdtm.kp.symbol_name = "ll_rw_block";
+ lkdtm.entry = (kprobe_opcode_t*) jp_ll_rw_block;
+ break;
+ case MEM_SWAPOUT:
+ lkdtm.kp.symbol_name = "shrink_page_list";
+ lkdtm.entry = (kprobe_opcode_t*) jp_shrink_page_list;
+ break;
+ case TIMERADD:
+ lkdtm.kp.symbol_name = "hrtimer_start";
+ lkdtm.entry = (kprobe_opcode_t*) jp_hrtimer_start;
+ break;
+ case SCSI_DISPATCH_CMD:
+ lkdtm.kp.symbol_name = "scsi_dispatch_cmd";
+ lkdtm.entry = (kprobe_opcode_t*) jp_scsi_dispatch_cmd;
+ break;
+ case IDE_CORE_CP:
+#ifdef CONFIG_IDE
+ lkdtm.kp.symbol_name = "generic_ide_ioctl";
+ lkdtm.entry = (kprobe_opcode_t*) jp_generic_ide_ioctl;
+#else
+ printk(KERN_INFO "lkdtm : Crash point not available\n");
+#endif
+ break;
+ default:
+ printk(KERN_INFO "lkdtm : Invalid Crash Point\n");
+ break;
+ }
+
+ if ((ret = register_jprobe(&lkdtm)) < 0) {
+ printk(KERN_INFO "lkdtm : Couldn't register jprobe\n");
+ return ret;
+ }
+
+ printk(KERN_INFO "lkdtm : Crash point %s of type %s registered\n",
+ cpoint_name, cpoint_type);
+ return 0;
+}
+
+void lkdtm_module_exit(void)
+{
+ unregister_jprobe(&lkdtm);
+ printk(KERN_INFO "lkdtm : Crash point unregistered\n");
+}
+
+module_init(lkdtm_module_init);
+module_exit(lkdtm_module_exit);
+
+MODULE_LICENSE("GPL");
diff --git a/drivers/mmc/Kconfig b/drivers/mmc/Kconfig
index 45bcf098e762..f540bd88dc5a 100644
--- a/drivers/mmc/Kconfig
+++ b/drivers/mmc/Kconfig
@@ -21,7 +21,7 @@ config MMC_DEBUG
config MMC_BLOCK
tristate "MMC block device driver"
- depends on MMC
+ depends on MMC && BLOCK
default y
help
Say Y here to enable the MMC block device driver support.
diff --git a/drivers/mmc/Makefile b/drivers/mmc/Makefile
index d2957e35cc6f..b1f6e03e7aa9 100644
--- a/drivers/mmc/Makefile
+++ b/drivers/mmc/Makefile
@@ -24,7 +24,8 @@ obj-$(CONFIG_MMC_AU1X) += au1xmmc.o
obj-$(CONFIG_MMC_OMAP) += omap.o
obj-$(CONFIG_MMC_AT91RM9200) += at91_mci.o
-mmc_core-y := mmc.o mmc_queue.o mmc_sysfs.o
+mmc_core-y := mmc.o mmc_sysfs.o
+mmc_core-$(CONFIG_BLOCK) += mmc_queue.o
ifeq ($(CONFIG_MMC_DEBUG),y)
EXTRA_CFLAGS += -DDEBUG
diff --git a/drivers/mmc/mmc_queue.c b/drivers/mmc/mmc_queue.c
index 74f8cdeeff0f..4ccdd82b680f 100644
--- a/drivers/mmc/mmc_queue.c
+++ b/drivers/mmc/mmc_queue.c
@@ -28,7 +28,7 @@ static int mmc_prep_request(struct request_queue *q, struct request *req)
struct mmc_queue *mq = q->queuedata;
int ret = BLKPREP_KILL;
- if (req->flags & REQ_SPECIAL) {
+ if (blk_special_request(req)) {
/*
* Special commands already have the command
* blocks already setup in req->special.
@@ -36,7 +36,7 @@ static int mmc_prep_request(struct request_queue *q, struct request *req)
BUG_ON(!req->special);
ret = BLKPREP_OK;
- } else if (req->flags & (REQ_CMD | REQ_BLOCK_PC)) {
+ } else if (blk_fs_request(req) || blk_pc_request(req)) {
/*
* Block I/O requests need translating according
* to the protocol.
@@ -50,7 +50,7 @@ static int mmc_prep_request(struct request_queue *q, struct request *req)
}
if (ret == BLKPREP_OK)
- req->flags |= REQ_DONTPREP;
+ req->cmd_flags |= REQ_DONTPREP;
return ret;
}
diff --git a/drivers/mmc/sdhci.c b/drivers/mmc/sdhci.c
index fdfc3838dd79..4dab5ec392ea 100644
--- a/drivers/mmc/sdhci.c
+++ b/drivers/mmc/sdhci.c
@@ -4,8 +4,9 @@
* Copyright (C) 2005-2006 Pierre Ossman, All Rights Reserved.
*
* This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
+ * 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 <linux/delay.h>
diff --git a/drivers/mmc/sdhci.h b/drivers/mmc/sdhci.h
index f2453343f783..72a67937afe0 100644
--- a/drivers/mmc/sdhci.h
+++ b/drivers/mmc/sdhci.h
@@ -4,8 +4,9 @@
* Copyright (C) 2005 Pierre Ossman, All Rights Reserved.
*
* This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
+ * 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.
*/
/*
diff --git a/drivers/mmc/wbsd.c b/drivers/mmc/wbsd.c
index 6435a6822ad3..88c6f0b129f5 100644
--- a/drivers/mmc/wbsd.c
+++ b/drivers/mmc/wbsd.c
@@ -4,8 +4,9 @@
* Copyright (C) 2004-2005 Pierre Ossman, All Rights Reserved.
*
* This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
+ * 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.
*
*
* Warning!
diff --git a/drivers/mmc/wbsd.h b/drivers/mmc/wbsd.h
index 249baa701cb0..6072993f01e3 100644
--- a/drivers/mmc/wbsd.h
+++ b/drivers/mmc/wbsd.h
@@ -4,8 +4,9 @@
* Copyright (C) 2004-2005 Pierre Ossman, All Rights Reserved.
*
* This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
+ * 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.
*/
#define LOCK_CODE 0xAA
diff --git a/drivers/mtd/Kconfig b/drivers/mtd/Kconfig
index a03e862851db..a304b34c2632 100644
--- a/drivers/mtd/Kconfig
+++ b/drivers/mtd/Kconfig
@@ -166,7 +166,7 @@ config MTD_CHAR
config MTD_BLOCK
tristate "Caching block device access to MTD devices"
- depends on MTD
+ depends on MTD && BLOCK
---help---
Although most flash chips have an erase size too large to be useful
as block devices, it is possible to use MTD devices which are based
@@ -188,7 +188,7 @@ config MTD_BLOCK
config MTD_BLOCK_RO
tristate "Readonly block device access to MTD devices"
- depends on MTD_BLOCK!=y && MTD
+ depends on MTD_BLOCK!=y && MTD && BLOCK
help
This allows you to mount read-only file systems (such as cramfs)
from an MTD device, without the overhead (and danger) of the caching
@@ -199,7 +199,7 @@ config MTD_BLOCK_RO
config FTL
tristate "FTL (Flash Translation Layer) support"
- depends on MTD
+ depends on MTD && BLOCK
---help---
This provides support for the original Flash Translation Layer which
is part of the PCMCIA specification. It uses a kind of pseudo-
@@ -215,7 +215,7 @@ config FTL
config NFTL
tristate "NFTL (NAND Flash Translation Layer) support"
- depends on MTD
+ depends on MTD && BLOCK
---help---
This provides support for the NAND Flash Translation Layer which is
used on M-Systems' DiskOnChip devices. It uses a kind of pseudo-
@@ -238,7 +238,7 @@ config NFTL_RW
config INFTL
tristate "INFTL (Inverse NAND Flash Translation Layer) support"
- depends on MTD
+ depends on MTD && BLOCK
---help---
This provides support for the Inverse NAND Flash Translation
Layer which is used on M-Systems' newer DiskOnChip devices. It
@@ -255,7 +255,7 @@ config INFTL
config RFD_FTL
tristate "Resident Flash Disk (Flash Translation Layer) support"
- depends on MTD
+ depends on MTD && BLOCK
---help---
This provides support for the flash translation layer known
as the Resident Flash Disk (RFD), as used by the Embedded BIOS
diff --git a/drivers/mtd/devices/Kconfig b/drivers/mtd/devices/Kconfig
index 16c02b5ccf7e..440f6851da69 100644
--- a/drivers/mtd/devices/Kconfig
+++ b/drivers/mtd/devices/Kconfig
@@ -136,7 +136,7 @@ config MTDRAM_ABS_POS
config MTD_BLOCK2MTD
tristate "MTD using block device"
- depends on MTD
+ depends on MTD && BLOCK
help
This driver allows a block device to appear as an MTD. It would
generally be used in the following cases:
diff --git a/drivers/mtd/maps/arctic-mtd.c b/drivers/mtd/maps/arctic-mtd.c
index 642d96bc8919..2cc902436275 100644
--- a/drivers/mtd/maps/arctic-mtd.c
+++ b/drivers/mtd/maps/arctic-mtd.c
@@ -96,7 +96,7 @@ static struct mtd_partition arctic_partitions[PARTITIONS] = {
static int __init
init_arctic_mtd(void)
{
- int err = 0;
+ int err;
printk("%s: 0x%08x at 0x%08x\n", NAME, SIZE, PADDR);
@@ -112,7 +112,7 @@ init_arctic_mtd(void)
arctic_mtd = do_map_probe("cfi_probe", &arctic_mtd_map);
if (!arctic_mtd) {
- iounmap((void *) arctic_mtd_map.virt);
+ iounmap(arctic_mtd_map.virt);
return -ENXIO;
}
@@ -121,7 +121,7 @@ init_arctic_mtd(void)
err = add_mtd_partitions(arctic_mtd, arctic_partitions, PARTITIONS);
if (err) {
printk("%s: add_mtd_partitions failed\n", NAME);
- iounmap((void *) arctic_mtd_map.virt);
+ iounmap(arctic_mtd_map.virt);
}
return err;
diff --git a/drivers/mtd/maps/beech-mtd.c b/drivers/mtd/maps/beech-mtd.c
index a64b1a5ab316..d76d5981b863 100644
--- a/drivers/mtd/maps/beech-mtd.c
+++ b/drivers/mtd/maps/beech-mtd.c
@@ -72,7 +72,7 @@ static struct mtd_partition beech_partitions[2] = {
static int __init
init_beech_mtd(void)
{
- int err = 0;
+ int err;
printk("%s: 0x%08x at 0x%08x\n", NAME, SIZE, PADDR);
@@ -89,7 +89,7 @@ init_beech_mtd(void)
beech_mtd = do_map_probe("cfi_probe", &beech_mtd_map);
if (!beech_mtd) {
- iounmap((void *) beech_mtd_map.virt);
+ iounmap(beech_mtd_map.virt);
return -ENXIO;
}
@@ -98,7 +98,7 @@ init_beech_mtd(void)
err = add_mtd_partitions(beech_mtd, beech_partitions, 2);
if (err) {
printk("%s: add_mtd_partitions failed\n", NAME);
- iounmap((void *) beech_mtd_map.virt);
+ iounmap(beech_mtd_map.virt);
}
return err;
diff --git a/drivers/mtd/maps/cstm_mips_ixx.c b/drivers/mtd/maps/cstm_mips_ixx.c
index d6bef100d69a..df2c38ef105a 100644
--- a/drivers/mtd/maps/cstm_mips_ixx.c
+++ b/drivers/mtd/maps/cstm_mips_ixx.c
@@ -175,8 +175,8 @@ int __init init_cstm_mips_ixx(void)
printk(KERN_WARNING "Failed to ioremap\n");
for (j = 0; j < i; j++) {
if (cstm_mips_ixx_map[j].virt) {
- iounmap((void *)cstm_mips_ixx_map[j].virt);
- cstm_mips_ixx_map[j].virt = 0;
+ iounmap(cstm_mips_ixx_map[j].virt);
+ cstm_mips_ixx_map[j].virt = NULL;
}
}
return -EIO;
@@ -214,8 +214,8 @@ int __init init_cstm_mips_ixx(void)
else {
for (i = 0; i < PHYSMAP_NUMBER; i++) {
if (cstm_mips_ixx_map[i].virt) {
- iounmap((void *)cstm_mips_ixx_map[i].virt);
- cstm_mips_ixx_map[i].virt = 0;
+ iounmap(cstm_mips_ixx_map[i].virt);
+ cstm_mips_ixx_map[i].virt = NULL;
}
}
return -ENXIO;
diff --git a/drivers/mtd/maps/nettel.c b/drivers/mtd/maps/nettel.c
index 198e840ff6db..f9e8e5bcbc33 100644
--- a/drivers/mtd/maps/nettel.c
+++ b/drivers/mtd/maps/nettel.c
@@ -463,7 +463,7 @@ int __init nettel_init(void)
#ifdef CONFIG_MTD_CFI_INTELEXT
out_unmap1:
- iounmap((void *) nettel_intel_map.virt);
+ iounmap(nettel_intel_map.virt);
#endif
out_unmap2:
diff --git a/drivers/mtd/maps/redwood.c b/drivers/mtd/maps/redwood.c
index 2257d2b500c0..4d858b3d5f82 100644
--- a/drivers/mtd/maps/redwood.c
+++ b/drivers/mtd/maps/redwood.c
@@ -126,7 +126,7 @@ static struct mtd_info *redwood_mtd;
int __init init_redwood_flash(void)
{
- int err = 0;
+ int err;
printk(KERN_NOTICE "redwood: flash mapping: %x at %x\n",
WINDOW_SIZE, WINDOW_ADDR);
diff --git a/drivers/mtd/mtd_blkdevs.c b/drivers/mtd/mtd_blkdevs.c
index 458d3c8ae1ee..178b53b56be9 100644
--- a/drivers/mtd/mtd_blkdevs.c
+++ b/drivers/mtd/mtd_blkdevs.c
@@ -46,7 +46,7 @@ static int do_blktrans_request(struct mtd_blktrans_ops *tr,
nsect = req->current_nr_sectors;
buf = req->buffer;
- if (!(req->flags & REQ_CMD))
+ if (!blk_fs_request(req))
return 0;
if (block + nsect > get_capacity(req->rq_disk))
@@ -69,7 +69,7 @@ static int do_blktrans_request(struct mtd_blktrans_ops *tr,
return 1;
default:
- printk(KERN_NOTICE "Unknown request %ld\n", rq_data_dir(req));
+ printk(KERN_NOTICE "Unknown request %u\n", rq_data_dir(req));
return 0;
}
}
diff --git a/drivers/mtd/nand/edb7312.c b/drivers/mtd/nand/edb7312.c
index 12017f3c6bd6..1daf8231aaef 100644
--- a/drivers/mtd/nand/edb7312.c
+++ b/drivers/mtd/nand/edb7312.c
@@ -199,7 +199,7 @@ static void __exit ep7312_cleanup(void)
nand_release(ap7312_mtd);
/* Release io resource */
- iounmap((void *)this->IO_ADDR_R);
+ iounmap(this->IO_ADDR_R);
/* Free the MTD device structure */
kfree(ep7312_mtd);
diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
index 975b2ef61121..baece61169f4 100644
--- a/drivers/mtd/nand/nand_base.c
+++ b/drivers/mtd/nand/nand_base.c
@@ -415,7 +415,7 @@ static int nand_block_checkbad(struct mtd_info *mtd, loff_t ofs, int getchip,
* Wait for the ready pin, after a command
* The timeout is catched later.
*/
-static void nand_wait_ready(struct mtd_info *mtd)
+void nand_wait_ready(struct mtd_info *mtd)
{
struct nand_chip *chip = mtd->priv;
unsigned long timeo = jiffies + 2;
@@ -429,6 +429,7 @@ static void nand_wait_ready(struct mtd_info *mtd)
} while (time_before(jiffies, timeo));
led_trigger_event(nand_led_trigger, LED_OFF);
}
+EXPORT_SYMBOL_GPL(nand_wait_ready);
/**
* nand_command - [DEFAULT] Send command to NAND device
@@ -766,8 +767,8 @@ static int nand_read_page_swecc(struct mtd_info *mtd, struct nand_chip *chip,
int eccbytes = chip->ecc.bytes;
int eccsteps = chip->ecc.steps;
uint8_t *p = buf;
- uint8_t *ecc_calc = chip->buffers.ecccalc;
- uint8_t *ecc_code = chip->buffers.ecccode;
+ uint8_t *ecc_calc = chip->buffers->ecccalc;
+ uint8_t *ecc_code = chip->buffers->ecccode;
int *eccpos = chip->ecc.layout->eccpos;
nand_read_page_raw(mtd, chip, buf);
@@ -808,8 +809,8 @@ static int nand_read_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip,
int eccbytes = chip->ecc.bytes;
int eccsteps = chip->ecc.steps;
uint8_t *p = buf;
- uint8_t *ecc_calc = chip->buffers.ecccalc;
- uint8_t *ecc_code = chip->buffers.ecccode;
+ uint8_t *ecc_calc = chip->buffers->ecccalc;
+ uint8_t *ecc_code = chip->buffers->ecccode;
int *eccpos = chip->ecc.layout->eccpos;
for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize) {
@@ -970,7 +971,7 @@ static int nand_do_read_ops(struct mtd_info *mtd, loff_t from,
page = realpage & chip->pagemask;
col = (int)(from & (mtd->writesize - 1));
- chip->oob_poi = chip->buffers.oobrbuf;
+ chip->oob_poi = chip->buffers->oobrbuf;
buf = ops->datbuf;
oob = ops->oobbuf;
@@ -981,7 +982,7 @@ static int nand_do_read_ops(struct mtd_info *mtd, loff_t from,
/* Is the current page in the buffer ? */
if (realpage != chip->pagebuf || oob) {
- bufpoi = aligned ? buf : chip->buffers.databuf;
+ bufpoi = aligned ? buf : chip->buffers->databuf;
if (likely(sndcmd)) {
chip->cmdfunc(mtd, NAND_CMD_READ0, 0x00, page);
@@ -989,14 +990,17 @@ static int nand_do_read_ops(struct mtd_info *mtd, loff_t from,
}
/* Now read the page into the buffer */
- ret = chip->ecc.read_page(mtd, chip, bufpoi);
+ if (unlikely(ops->mode == MTD_OOB_RAW))
+ ret = chip->ecc.read_page_raw(mtd, chip, bufpoi);
+ else
+ ret = chip->ecc.read_page(mtd, chip, bufpoi);
if (ret < 0)
break;
/* Transfer not aligned data */
if (!aligned) {
chip->pagebuf = realpage;
- memcpy(buf, chip->buffers.databuf + col, bytes);
+ memcpy(buf, chip->buffers->databuf + col, bytes);
}
buf += bytes;
@@ -1023,7 +1027,7 @@ static int nand_do_read_ops(struct mtd_info *mtd, loff_t from,
nand_wait_ready(mtd);
}
} else {
- memcpy(buf, chip->buffers.databuf + col, bytes);
+ memcpy(buf, chip->buffers->databuf + col, bytes);
buf += bytes;
}
@@ -1266,7 +1270,7 @@ static int nand_do_read_oob(struct mtd_info *mtd, loff_t from,
realpage = (int)(from >> chip->page_shift);
page = realpage & chip->pagemask;
- chip->oob_poi = chip->buffers.oobrbuf;
+ chip->oob_poi = chip->buffers->oobrbuf;
while(1) {
sndcmd = chip->ecc.read_oob(mtd, chip, page, sndcmd);
@@ -1322,8 +1326,6 @@ static int nand_do_read_oob(struct mtd_info *mtd, loff_t from,
static int nand_read_oob(struct mtd_info *mtd, loff_t from,
struct mtd_oob_ops *ops)
{
- int (*read_page)(struct mtd_info *mtd, struct nand_chip *chip,
- uint8_t *buf) = NULL;
struct nand_chip *chip = mtd->priv;
int ret = -ENOTSUPP;
@@ -1341,12 +1343,7 @@ static int nand_read_oob(struct mtd_info *mtd, loff_t from,
switch(ops->mode) {
case MTD_OOB_PLACE:
case MTD_OOB_AUTO:
- break;
-
case MTD_OOB_RAW:
- /* Replace the read_page algorithm temporary */
- read_page = chip->ecc.read_page;
- chip->ecc.read_page = nand_read_page_raw;
break;
default:
@@ -1358,8 +1355,6 @@ static int nand_read_oob(struct mtd_info *mtd, loff_t from,
else
ret = nand_do_read_ops(mtd, from, ops);
- if (unlikely(ops->mode == MTD_OOB_RAW))
- chip->ecc.read_page = read_page;
out:
nand_release_device(mtd);
return ret;
@@ -1391,7 +1386,7 @@ static void nand_write_page_swecc(struct mtd_info *mtd, struct nand_chip *chip,
int i, eccsize = chip->ecc.size;
int eccbytes = chip->ecc.bytes;
int eccsteps = chip->ecc.steps;
- uint8_t *ecc_calc = chip->buffers.ecccalc;
+ uint8_t *ecc_calc = chip->buffers->ecccalc;
const uint8_t *p = buf;
int *eccpos = chip->ecc.layout->eccpos;
@@ -1417,7 +1412,7 @@ static void nand_write_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip,
int i, eccsize = chip->ecc.size;
int eccbytes = chip->ecc.bytes;
int eccsteps = chip->ecc.steps;
- uint8_t *ecc_calc = chip->buffers.ecccalc;
+ uint8_t *ecc_calc = chip->buffers->ecccalc;
const uint8_t *p = buf;
int *eccpos = chip->ecc.layout->eccpos;
@@ -1478,7 +1473,7 @@ static void nand_write_page_syndrome(struct mtd_info *mtd,
}
/**
- * nand_write_page - [INTERNAL] write one page
+ * nand_write_page - [REPLACEABLE] write one page
* @mtd: MTD device structure
* @chip: NAND chip descriptor
* @buf: the data to write
@@ -1486,13 +1481,16 @@ static void nand_write_page_syndrome(struct mtd_info *mtd,
* @cached: cached programming
*/
static int nand_write_page(struct mtd_info *mtd, struct nand_chip *chip,
- const uint8_t *buf, int page, int cached)
+ const uint8_t *buf, int page, int cached, int raw)
{
int status;
chip->cmdfunc(mtd, NAND_CMD_SEQIN, 0x00, page);
- chip->ecc.write_page(mtd, chip, buf);
+ if (unlikely(raw))
+ chip->ecc.write_page_raw(mtd, chip, buf);
+ else
+ chip->ecc.write_page(mtd, chip, buf);
/*
* Cached progamming disabled for now, Not sure if its worth the
@@ -1627,7 +1625,7 @@ static int nand_do_write_ops(struct mtd_info *mtd, loff_t to,
(chip->pagebuf << chip->page_shift) < (to + ops->len))
chip->pagebuf = -1;
- chip->oob_poi = chip->buffers.oobwbuf;
+ chip->oob_poi = chip->buffers->oobwbuf;
while(1) {
int cached = writelen > bytes && page != blockmask;
@@ -1635,7 +1633,8 @@ static int nand_do_write_ops(struct mtd_info *mtd, loff_t to,
if (unlikely(oob))
oob = nand_fill_oob(chip, oob, ops);
- ret = nand_write_page(mtd, chip, buf, page, cached);
+ ret = chip->write_page(mtd, chip, buf, page, cached,
+ (ops->mode == MTD_OOB_RAW));
if (ret)
break;
@@ -1745,7 +1744,7 @@ static int nand_do_write_oob(struct mtd_info *mtd, loff_t to,
if (page == chip->pagebuf)
chip->pagebuf = -1;
- chip->oob_poi = chip->buffers.oobwbuf;
+ chip->oob_poi = chip->buffers->oobwbuf;
memset(chip->oob_poi, 0xff, mtd->oobsize);
nand_fill_oob(chip, ops->oobbuf, ops);
status = chip->ecc.write_oob(mtd, chip, page & chip->pagemask);
@@ -1768,8 +1767,6 @@ static int nand_do_write_oob(struct mtd_info *mtd, loff_t to,
static int nand_write_oob(struct mtd_info *mtd, loff_t to,
struct mtd_oob_ops *ops)
{
- void (*write_page)(struct mtd_info *mtd, struct nand_chip *chip,
- const uint8_t *buf) = NULL;
struct nand_chip *chip = mtd->priv;
int ret = -ENOTSUPP;
@@ -1787,12 +1784,7 @@ static int nand_write_oob(struct mtd_info *mtd, loff_t to,
switch(ops->mode) {
case MTD_OOB_PLACE:
case MTD_OOB_AUTO:
- break;
-
case MTD_OOB_RAW:
- /* Replace the write_page algorithm temporary */
- write_page = chip->ecc.write_page;
- chip->ecc.write_page = nand_write_page_raw;
break;
default:
@@ -1804,8 +1796,6 @@ static int nand_write_oob(struct mtd_info *mtd, loff_t to,
else
ret = nand_do_write_ops(mtd, to, ops);
- if (unlikely(ops->mode == MTD_OOB_RAW))
- chip->ecc.write_page = write_page;
out:
nand_release_device(mtd);
return ret;
@@ -2288,40 +2278,22 @@ static struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd,
return type;
}
-/* module_text_address() isn't exported, and it's mostly a pointless
- test if this is a module _anyway_ -- they'd have to try _really_ hard
- to call us from in-kernel code if the core NAND support is modular. */
-#ifdef MODULE
-#define caller_is_module() (1)
-#else
-#define caller_is_module() \
- module_text_address((unsigned long)__builtin_return_address(0))
-#endif
-
/**
- * nand_scan - [NAND Interface] Scan for the NAND device
- * @mtd: MTD device structure
- * @maxchips: Number of chips to scan for
+ * nand_scan_ident - [NAND Interface] Scan for the NAND device
+ * @mtd: MTD device structure
+ * @maxchips: Number of chips to scan for
*
- * This fills out all the uninitialized function pointers
- * with the defaults.
- * The flash ID is read and the mtd/chip structures are
- * filled with the appropriate values.
- * The mtd->owner field must be set to the module of the caller
+ * This is the first phase of the normal nand_scan() function. It
+ * reads the flash ID and sets up MTD fields accordingly.
*
+ * The mtd->owner field must be set to the module of the caller.
*/
-int nand_scan(struct mtd_info *mtd, int maxchips)
+int nand_scan_ident(struct mtd_info *mtd, int maxchips)
{
int i, busw, nand_maf_id;
struct nand_chip *chip = mtd->priv;
struct nand_flash_dev *type;
- /* Many callers got this wrong, so check for it for a while... */
- if (!mtd->owner && caller_is_module()) {
- printk(KERN_CRIT "nand_scan() called with NULL mtd->owner!\n");
- BUG();
- }
-
/* Get buswidth to select the correct functions */
busw = chip->options & NAND_BUSWIDTH_16;
/* Set the default functions */
@@ -2353,8 +2325,31 @@ int nand_scan(struct mtd_info *mtd, int maxchips)
chip->numchips = i;
mtd->size = i * chip->chipsize;
+ return 0;
+}
+
+
+/**
+ * nand_scan_tail - [NAND Interface] Scan for the NAND device
+ * @mtd: MTD device structure
+ * @maxchips: Number of chips to scan for
+ *
+ * This is the second phase of the normal nand_scan() function. It
+ * fills out all the uninitialized function pointers with the defaults
+ * and scans for a bad block table if appropriate.
+ */
+int nand_scan_tail(struct mtd_info *mtd)
+{
+ int i;
+ struct nand_chip *chip = mtd->priv;
+
+ if (!(chip->options & NAND_OWN_BUFFERS))
+ chip->buffers = kmalloc(sizeof(*chip->buffers), GFP_KERNEL);
+ if (!chip->buffers)
+ return -ENOMEM;
+
/* Preset the internal oob write buffer */
- memset(chip->buffers.oobwbuf, 0xff, mtd->oobsize);
+ memset(chip->buffers->oobwbuf, 0xff, mtd->oobsize);
/*
* If no default placement scheme is given, select an appropriate one
@@ -2377,10 +2372,18 @@ int nand_scan(struct mtd_info *mtd, int maxchips)
}
}
+ if (!chip->write_page)
+ chip->write_page = nand_write_page;
+
/*
* check ECC mode, default to software if 3byte/512byte hardware ECC is
* selected and we have 256 byte pagesize fallback to software ECC
*/
+ if (!chip->ecc.read_page_raw)
+ chip->ecc.read_page_raw = nand_read_page_raw;
+ if (!chip->ecc.write_page_raw)
+ chip->ecc.write_page_raw = nand_write_page_raw;
+
switch (chip->ecc.mode) {
case NAND_ECC_HW:
/* Use standard hwecc read page function ? */
@@ -2438,6 +2441,7 @@ int nand_scan(struct mtd_info *mtd, int maxchips)
chip->ecc.size = mtd->writesize;
chip->ecc.bytes = 0;
break;
+
default:
printk(KERN_WARNING "Invalid NAND_ECC_MODE %d\n",
chip->ecc.mode);
@@ -2503,6 +2507,44 @@ int nand_scan(struct mtd_info *mtd, int maxchips)
return chip->scan_bbt(mtd);
}
+/* module_text_address() isn't exported, and it's mostly a pointless
+ test if this is a module _anyway_ -- they'd have to try _really_ hard
+ to call us from in-kernel code if the core NAND support is modular. */
+#ifdef MODULE
+#define caller_is_module() (1)
+#else
+#define caller_is_module() \
+ module_text_address((unsigned long)__builtin_return_address(0))
+#endif
+
+/**
+ * nand_scan - [NAND Interface] Scan for the NAND device
+ * @mtd: MTD device structure
+ * @maxchips: Number of chips to scan for
+ *
+ * This fills out all the uninitialized function pointers
+ * with the defaults.
+ * The flash ID is read and the mtd/chip structures are
+ * filled with the appropriate values.
+ * The mtd->owner field must be set to the module of the caller
+ *
+ */
+int nand_scan(struct mtd_info *mtd, int maxchips)
+{
+ int ret;
+
+ /* Many callers got this wrong, so check for it for a while... */
+ if (!mtd->owner && caller_is_module()) {
+ printk(KERN_CRIT "nand_scan() called with NULL mtd->owner!\n");
+ BUG();
+ }
+
+ ret = nand_scan_ident(mtd, maxchips);
+ if (!ret)
+ ret = nand_scan_tail(mtd);
+ return ret;
+}
+
/**
* nand_release - [NAND Interface] Free resources held by the NAND device
* @mtd: MTD device structure
@@ -2520,9 +2562,13 @@ void nand_release(struct mtd_info *mtd)
/* Free bad block table memory */
kfree(chip->bbt);
+ if (!(chip->options & NAND_OWN_BUFFERS))
+ kfree(chip->buffers);
}
EXPORT_SYMBOL_GPL(nand_scan);
+EXPORT_SYMBOL_GPL(nand_scan_ident);
+EXPORT_SYMBOL_GPL(nand_scan_tail);
EXPORT_SYMBOL_GPL(nand_release);
static int __init nand_base_init(void)
diff --git a/drivers/mtd/nand/nand_bbt.c b/drivers/mtd/nand/nand_bbt.c
index a612c4ea8194..9402653eb09b 100644
--- a/drivers/mtd/nand/nand_bbt.c
+++ b/drivers/mtd/nand/nand_bbt.c
@@ -759,7 +759,7 @@ static inline int nand_memory_bbt(struct mtd_info *mtd, struct nand_bbt_descr *b
struct nand_chip *this = mtd->priv;
bd->options &= ~NAND_BBT_SCANEMPTY;
- return create_bbt(mtd, this->buffers.databuf, bd, -1);
+ return create_bbt(mtd, this->buffers->databuf, bd, -1);
}
/**
diff --git a/drivers/mtd/nftlcore.c b/drivers/mtd/nftlcore.c
index dd5cea8b4a7a..b5a5f8da4722 100644
--- a/drivers/mtd/nftlcore.c
+++ b/drivers/mtd/nftlcore.c
@@ -175,6 +175,8 @@ int nftl_write_oob(struct mtd_info *mtd, loff_t offs, size_t len,
return res;
}
+#ifdef CONFIG_NFTL_RW
+
/*
* Write data and oob to flash
*/
@@ -196,8 +198,6 @@ static int nftl_write(struct mtd_info *mtd, loff_t offs, size_t len,
return res;
}
-#ifdef CONFIG_NFTL_RW
-
/* Actual NFTL access routines */
/* NFTL_findfreeblock: Find a free Erase Unit on the NFTL partition. This function is used
* when the give Virtual Unit Chain
diff --git a/drivers/mtd/onenand/Kconfig b/drivers/mtd/onenand/Kconfig
index 5930a03736d7..465961b8bcd1 100644
--- a/drivers/mtd/onenand/Kconfig
+++ b/drivers/mtd/onenand/Kconfig
@@ -43,10 +43,4 @@ config MTD_ONENAND_OTP
OTP block is fully-guaranteed to be a valid block.
-config MTD_ONENAND_SYNC_READ
- bool "OneNAND Sync. Burst Read Support"
- depends on ARCH_OMAP
- help
- This enables support for Sync. Burst Read.
-
endmenu
diff --git a/drivers/mtd/onenand/onenand_base.c b/drivers/mtd/onenand/onenand_base.c
index 84ec40d25438..8ed68b28afe3 100644
--- a/drivers/mtd/onenand/onenand_base.c
+++ b/drivers/mtd/onenand/onenand_base.c
@@ -1,7 +1,7 @@
/*
* linux/drivers/mtd/onenand/onenand_base.c
*
- * Copyright (C) 2005 Samsung Electronics
+ * Copyright (C) 2005-2006 Samsung Electronics
* Kyungmin Park <kyungmin.park@samsung.com>
*
* This program is free software; you can redistribute it and/or modify
@@ -199,6 +199,7 @@ static int onenand_command(struct mtd_info *mtd, int cmd, loff_t addr, size_t le
case ONENAND_CMD_UNLOCK:
case ONENAND_CMD_LOCK:
case ONENAND_CMD_LOCK_TIGHT:
+ case ONENAND_CMD_UNLOCK_ALL:
block = -1;
page = -1;
break;
@@ -1211,11 +1212,11 @@ static int onenand_unlock(struct mtd_info *mtd, loff_t ofs, size_t len)
end = len >> this->erase_shift;
/* Continuous lock scheme */
- if (this->options & ONENAND_CONT_LOCK) {
+ if (this->options & ONENAND_HAS_CONT_LOCK) {
/* Set start block address */
this->write_word(start, this->base + ONENAND_REG_START_BLOCK_ADDRESS);
/* Set end block address */
- this->write_word(end - 1, this->base + ONENAND_REG_END_BLOCK_ADDRESS);
+ this->write_word(start + end - 1, this->base + ONENAND_REG_END_BLOCK_ADDRESS);
/* Write unlock command */
this->command(mtd, ONENAND_CMD_UNLOCK, 0, 0);
@@ -1236,7 +1237,7 @@ static int onenand_unlock(struct mtd_info *mtd, loff_t ofs, size_t len)
}
/* Block lock scheme */
- for (block = start; block < end; block++) {
+ for (block = start; block < start + end; block++) {
/* Set block address */
value = onenand_block_address(this, block);
this->write_word(value, this->base + ONENAND_REG_START_ADDRESS1);
@@ -1265,6 +1266,79 @@ static int onenand_unlock(struct mtd_info *mtd, loff_t ofs, size_t len)
return 0;
}
+/**
+ * onenand_check_lock_status - [OneNAND Interface] Check lock status
+ * @param this onenand chip data structure
+ *
+ * Check lock status
+ */
+static void onenand_check_lock_status(struct onenand_chip *this)
+{
+ unsigned int value, block, status;
+ unsigned int end;
+
+ end = this->chipsize >> this->erase_shift;
+ for (block = 0; block < end; block++) {
+ /* Set block address */
+ value = onenand_block_address(this, block);
+ this->write_word(value, this->base + ONENAND_REG_START_ADDRESS1);
+ /* Select DataRAM for DDP */
+ value = onenand_bufferram_address(this, block);
+ this->write_word(value, this->base + ONENAND_REG_START_ADDRESS2);
+ /* Set start block address */
+ this->write_word(block, this->base + ONENAND_REG_START_BLOCK_ADDRESS);
+
+ /* Check lock status */
+ status = this->read_word(this->base + ONENAND_REG_WP_STATUS);
+ if (!(status & ONENAND_WP_US))
+ printk(KERN_ERR "block = %d, wp status = 0x%x\n", block, status);
+ }
+}
+
+/**
+ * onenand_unlock_all - [OneNAND Interface] unlock all blocks
+ * @param mtd MTD device structure
+ *
+ * Unlock all blocks
+ */
+static int onenand_unlock_all(struct mtd_info *mtd)
+{
+ struct onenand_chip *this = mtd->priv;
+
+ if (this->options & ONENAND_HAS_UNLOCK_ALL) {
+ /* Write unlock command */
+ this->command(mtd, ONENAND_CMD_UNLOCK_ALL, 0, 0);
+
+ /* There's no return value */
+ this->wait(mtd, FL_UNLOCKING);
+
+ /* Sanity check */
+ while (this->read_word(this->base + ONENAND_REG_CTRL_STATUS)
+ & ONENAND_CTRL_ONGO)
+ continue;
+
+ /* Workaround for all block unlock in DDP */
+ if (this->device_id & ONENAND_DEVICE_IS_DDP) {
+ loff_t ofs;
+ size_t len;
+
+ /* 1st block on another chip */
+ ofs = this->chipsize >> 1;
+ len = 1 << this->erase_shift;
+
+ onenand_unlock(mtd, ofs, len);
+ }
+
+ onenand_check_lock_status(this);
+
+ return 0;
+ }
+
+ mtd->unlock(mtd, 0x0, this->chipsize);
+
+ return 0;
+}
+
#ifdef CONFIG_MTD_ONENAND_OTP
/* Interal OTP operation */
@@ -1564,12 +1638,43 @@ static int onenand_lock_user_prot_reg(struct mtd_info *mtd, loff_t from,
#endif /* CONFIG_MTD_ONENAND_OTP */
/**
+ * onenand_lock_scheme - Check and set OneNAND lock scheme
+ * @param mtd MTD data structure
+ *
+ * Check and set OneNAND lock scheme
+ */
+static void onenand_lock_scheme(struct mtd_info *mtd)
+{
+ struct onenand_chip *this = mtd->priv;
+ unsigned int density, process;
+
+ /* Lock scheme depends on density and process */
+ density = this->device_id >> ONENAND_DEVICE_DENSITY_SHIFT;
+ process = this->version_id >> ONENAND_VERSION_PROCESS_SHIFT;
+
+ /* Lock scheme */
+ if (density >= ONENAND_DEVICE_DENSITY_1Gb) {
+ /* A-Die has all block unlock */
+ if (process) {
+ printk(KERN_DEBUG "Chip support all block unlock\n");
+ this->options |= ONENAND_HAS_UNLOCK_ALL;
+ }
+ } else {
+ /* Some OneNAND has continues lock scheme */
+ if (!process) {
+ printk(KERN_DEBUG "Lock scheme is Continues Lock\n");
+ this->options |= ONENAND_HAS_CONT_LOCK;
+ }
+ }
+}
+
+/**
* onenand_print_device_info - Print device ID
* @param device device ID
*
* Print device ID
*/
-static void onenand_print_device_info(int device)
+static void onenand_print_device_info(int device, int version)
{
int vcc, demuxed, ddp, density;
@@ -1583,6 +1688,7 @@ static void onenand_print_device_info(int device)
(16 << density),
vcc ? "2.65/3.3" : "1.8",
device);
+ printk(KERN_DEBUG "OneNAND version = 0x%04x\n", version);
}
static const struct onenand_manufacturers onenand_manuf_ids[] = {
@@ -1625,9 +1731,14 @@ static int onenand_check_maf(int manuf)
static int onenand_probe(struct mtd_info *mtd)
{
struct onenand_chip *this = mtd->priv;
- int bram_maf_id, bram_dev_id, maf_id, dev_id;
- int version_id;
+ int bram_maf_id, bram_dev_id, maf_id, dev_id, ver_id;
int density;
+ int syscfg;
+
+ /* Save system configuration 1 */
+ syscfg = this->read_word(this->base + ONENAND_REG_SYS_CFG1);
+ /* Clear Sync. Burst Read mode to read BootRAM */
+ this->write_word((syscfg & ~ONENAND_SYS_CFG1_SYNC_READ), this->base + ONENAND_REG_SYS_CFG1);
/* Send the command for reading device ID from BootRAM */
this->write_word(ONENAND_CMD_READID, this->base + ONENAND_BOOTRAM);
@@ -1636,24 +1747,31 @@ static int onenand_probe(struct mtd_info *mtd)
bram_maf_id = this->read_word(this->base + ONENAND_BOOTRAM + 0x0);
bram_dev_id = this->read_word(this->base + ONENAND_BOOTRAM + 0x2);
+ /* Reset OneNAND to read default register values */
+ this->write_word(ONENAND_CMD_RESET, this->base + ONENAND_BOOTRAM);
+ /* Wait reset */
+ this->wait(mtd, FL_RESETING);
+
+ /* Restore system configuration 1 */
+ this->write_word(syscfg, this->base + ONENAND_REG_SYS_CFG1);
+
/* Check manufacturer ID */
if (onenand_check_maf(bram_maf_id))
return -ENXIO;
- /* Reset OneNAND to read default register values */
- this->write_word(ONENAND_CMD_RESET, this->base + ONENAND_BOOTRAM);
-
/* Read manufacturer and device IDs from Register */
maf_id = this->read_word(this->base + ONENAND_REG_MANUFACTURER_ID);
dev_id = this->read_word(this->base + ONENAND_REG_DEVICE_ID);
+ ver_id= this->read_word(this->base + ONENAND_REG_VERSION_ID);
/* Check OneNAND device */
if (maf_id != bram_maf_id || dev_id != bram_dev_id)
return -ENXIO;
/* Flash device information */
- onenand_print_device_info(dev_id);
+ onenand_print_device_info(dev_id, ver_id);
this->device_id = dev_id;
+ this->version_id = ver_id;
density = dev_id >> ONENAND_DEVICE_DENSITY_SHIFT;
this->chipsize = (16 << density) << 20;
@@ -1676,16 +1794,8 @@ static int onenand_probe(struct mtd_info *mtd)
mtd->size = this->chipsize;
- /* Version ID */
- version_id = this->read_word(this->base + ONENAND_REG_VERSION_ID);
- printk(KERN_DEBUG "OneNAND version = 0x%04x\n", version_id);
-
- /* Lock scheme */
- if (density <= ONENAND_DEVICE_DENSITY_512Mb &&
- !(version_id >> ONENAND_VERSION_PROCESS_SHIFT)) {
- printk(KERN_INFO "Lock scheme is Continues Lock\n");
- this->options |= ONENAND_CONT_LOCK;
- }
+ /* Check OneNAND lock scheme */
+ onenand_lock_scheme(mtd);
return 0;
}
@@ -1821,7 +1931,7 @@ int onenand_scan(struct mtd_info *mtd, int maxchips)
mtd->owner = THIS_MODULE;
/* Unlock whole block */
- mtd->unlock(mtd, 0x0, this->chipsize);
+ onenand_unlock_all(mtd);
return this->scan_bbt(mtd);
}
diff --git a/drivers/net/8390.c b/drivers/net/8390.c
index 5b6b05ed8f3c..9d34056147ad 100644
--- a/drivers/net/8390.c
+++ b/drivers/net/8390.c
@@ -299,7 +299,7 @@ static int ei_start_xmit(struct sk_buff *skb, struct net_device *dev)
* Slow phase with lock held.
*/
- disable_irq_nosync_lockdep(dev->irq);
+ disable_irq_nosync_lockdep_irqsave(dev->irq, &flags);
spin_lock(&ei_local->page_lock);
@@ -338,7 +338,7 @@ static int ei_start_xmit(struct sk_buff *skb, struct net_device *dev)
netif_stop_queue(dev);
outb_p(ENISR_ALL, e8390_base + EN0_IMR);
spin_unlock(&ei_local->page_lock);
- enable_irq_lockdep(dev->irq);
+ enable_irq_lockdep_irqrestore(dev->irq, &flags);
ei_local->stat.tx_errors++;
return 1;
}
@@ -379,7 +379,7 @@ static int ei_start_xmit(struct sk_buff *skb, struct net_device *dev)
outb_p(ENISR_ALL, e8390_base + EN0_IMR);
spin_unlock(&ei_local->page_lock);
- enable_irq_lockdep(dev->irq);
+ enable_irq_lockdep_irqrestore(dev->irq, &flags);
dev_kfree_skb (skb);
ei_local->stat.tx_bytes += send_length;
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index 63154774c257..ff8a8c0a26d5 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -24,6 +24,9 @@ config NETDEVICES
If unsure, say Y.
+# All the following symbols are dependent on NETDEVICES - do not repeat
+# that for each of the symbols.
+if NETDEVICES
config IFB
tristate "Intermediate Functional Block support"
@@ -2852,6 +2855,8 @@ config NETCONSOLE
If you want to log kernel messages over the network, enable this.
See <file:Documentation/networking/netconsole.txt> for details.
+endif #NETDEVICES
+
config NETPOLL
def_bool NETCONSOLE
diff --git a/drivers/net/Space.c b/drivers/net/Space.c
index 9953201c670d..a67f5efc983f 100644
--- a/drivers/net/Space.c
+++ b/drivers/net/Space.c
@@ -165,7 +165,7 @@ static struct devprobe2 mca_probes[] __initdata = {
* look for EISA/PCI/MCA cards in addition to ISA cards).
*/
static struct devprobe2 isa_probes[] __initdata = {
-#ifdef CONFIG_HP100 /* ISA, EISA & PCI */
+#if defined(CONFIG_HP100) && defined(CONFIG_ISA) /* ISA, EISA */
{hp100_probe, 0},
#endif
#ifdef CONFIG_3C515
diff --git a/drivers/net/appletalk/ipddp.c b/drivers/net/appletalk/ipddp.c
index 7f7dd450226a..b98592a8bac8 100644
--- a/drivers/net/appletalk/ipddp.c
+++ b/drivers/net/appletalk/ipddp.c
@@ -145,9 +145,7 @@ static int ipddp_xmit(struct sk_buff *skb, struct net_device *dev)
/* Create the Extended DDP header */
ddp = (struct ddpehdr *)skb->data;
- ddp->deh_len = skb->len;
- ddp->deh_hops = 1;
- ddp->deh_pad = 0;
+ ddp->deh_len_hops = htons(skb->len + (1<<10));
ddp->deh_sum = 0;
/*
@@ -170,7 +168,6 @@ static int ipddp_xmit(struct sk_buff *skb, struct net_device *dev)
ddp->deh_sport = 72;
*((__u8 *)(ddp+1)) = 22; /* ddp type = IP */
- *((__u16 *)ddp)=ntohs(*((__u16 *)ddp)); /* fix up length field */
skb->protocol = htons(ETH_P_ATALK); /* Protocol has changed */
diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c
index 7fcf015021ec..6b4edb63c4c4 100644
--- a/drivers/net/bnx2.c
+++ b/drivers/net/bnx2.c
@@ -56,8 +56,8 @@
#define DRV_MODULE_NAME "bnx2"
#define PFX DRV_MODULE_NAME ": "
-#define DRV_MODULE_VERSION "1.4.44"
-#define DRV_MODULE_RELDATE "August 10, 2006"
+#define DRV_MODULE_VERSION "1.4.45"
+#define DRV_MODULE_RELDATE "September 29, 2006"
#define RUN_AT(x) (jiffies + (x))
@@ -5805,6 +5805,34 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev)
bp->cmd_ticks_int = bp->cmd_ticks;
}
+ /* Disable MSI on 5706 if AMD 8132 bridge is found.
+ *
+ * MSI is defined to be 32-bit write. The 5706 does 64-bit MSI writes
+ * with byte enables disabled on the unused 32-bit word. This is legal
+ * but causes problems on the AMD 8132 which will eventually stop
+ * responding after a while.
+ *
+ * AMD believes this incompatibility is unique to the 5706, and
+ * prefers to locally disable MSI rather than globally disabling it
+ * using pci_msi_quirk.
+ */
+ if (CHIP_NUM(bp) == CHIP_NUM_5706 && disable_msi == 0) {
+ struct pci_dev *amd_8132 = NULL;
+
+ while ((amd_8132 = pci_get_device(PCI_VENDOR_ID_AMD,
+ PCI_DEVICE_ID_AMD_8132_BRIDGE,
+ amd_8132))) {
+ u8 rev;
+
+ pci_read_config_byte(amd_8132, PCI_REVISION_ID, &rev);
+ if (rev >= 0x10 && rev <= 0x13) {
+ disable_msi = 1;
+ pci_dev_put(amd_8132);
+ break;
+ }
+ }
+ }
+
bp->autoneg = AUTONEG_SPEED | AUTONEG_FLOW_CTRL;
bp->req_line_speed = 0;
if (bp->phy_flags & PHY_SERDES_FLAG) {
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index 0fb5f653d3ce..c0bbddae4ec4 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -2252,7 +2252,7 @@ static u32 bond_glean_dev_ip(struct net_device *dev)
{
struct in_device *idev;
struct in_ifaddr *ifa;
- u32 addr = 0;
+ __be32 addr = 0;
if (!dev)
return 0;
diff --git a/drivers/net/dgrs.c b/drivers/net/dgrs.c
index e9361cb5f4cd..d0842527b369 100644
--- a/drivers/net/dgrs.c
+++ b/drivers/net/dgrs.c
@@ -110,7 +110,6 @@ static char version[] __initdata =
* DGRS include files
*/
typedef unsigned char uchar;
-typedef unsigned int bool;
#define vol volatile
#include "dgrs.h"
diff --git a/drivers/net/e100.c b/drivers/net/e100.c
index dc5e38aefca6..26073c345213 100644
--- a/drivers/net/e100.c
+++ b/drivers/net/e100.c
@@ -1,27 +1,27 @@
/*******************************************************************************
-
- Copyright(c) 1999 - 2006 Intel Corporation. All rights reserved.
+ Intel PRO/100 Linux driver
+ Copyright(c) 1999 - 2006 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; either version 2 of the License, or (at your option)
- any later version.
+ under the terms and conditions 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
+ This program is distributed in the hope 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 program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- The full GNU General Public License is included in this distribution in the
- file called LICENSE.
+ The full GNU General Public License is included in this distribution in
+ the file called "COPYING".
Contact Information:
Linux NICS <linux.nics@intel.com>
+ e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
*******************************************************************************/
@@ -159,7 +159,7 @@
#define DRV_NAME "e100"
#define DRV_EXT "-NAPI"
-#define DRV_VERSION "3.5.16-k2"DRV_EXT
+#define DRV_VERSION "3.5.17-k2"DRV_EXT
#define DRV_DESCRIPTION "Intel(R) PRO/100 Network Driver"
#define DRV_COPYRIGHT "Copyright(c) 1999-2006 Intel Corporation"
#define PFX DRV_NAME ": "
@@ -1657,13 +1657,14 @@ static int e100_tx_clean(struct nic *nic)
spin_lock(&nic->cb_lock);
- DPRINTK(TX_DONE, DEBUG, "cb->status = 0x%04X\n",
- nic->cb_to_clean->status);
-
/* Clean CBs marked complete */
for(cb = nic->cb_to_clean;
cb->status & cpu_to_le16(cb_complete);
cb = nic->cb_to_clean = cb->next) {
+ DPRINTK(TX_DONE, DEBUG, "cb[%d]->status = 0x%04X\n",
+ (int)(((void*)cb - (void*)nic->cbs)/sizeof(struct cb)),
+ cb->status);
+
if(likely(cb->skb != NULL)) {
nic->net_stats.tx_packets++;
nic->net_stats.tx_bytes += cb->skb->len;
@@ -2572,7 +2573,7 @@ static int __devinit e100_probe(struct pci_dev *pdev,
#ifdef CONFIG_NET_POLL_CONTROLLER
netdev->poll_controller = e100_netpoll;
#endif
- strcpy(netdev->name, pci_name(pdev));
+ strncpy(netdev->name, pci_name(pdev), sizeof(netdev->name) - 1);
nic = netdev_priv(netdev);
nic->netdev = netdev;
@@ -2714,68 +2715,56 @@ static void __devexit e100_remove(struct pci_dev *pdev)
}
}
-#ifdef CONFIG_PM
static int e100_suspend(struct pci_dev *pdev, pm_message_t state)
{
struct net_device *netdev = pci_get_drvdata(pdev);
struct nic *nic = netdev_priv(netdev);
- int retval;
- if(netif_running(netdev))
+ if (netif_running(netdev))
e100_down(nic);
e100_hw_reset(nic);
netif_device_detach(netdev);
+#ifdef CONFIG_PM
pci_save_state(pdev);
- retval = pci_enable_wake(pdev, pci_choose_state(pdev, state),
- nic->flags & (wol_magic | e100_asf(nic)));
- if (retval)
- DPRINTK(PROBE,ERR, "Error enabling wake\n");
+ if (nic->flags & (wol_magic | e100_asf(nic)))
+#else
+ if (nic->flags & (wol_magic))
+#endif
+ pci_enable_wake(pdev, pci_choose_state(pdev, state), 1);
+ else
+ /* disable PME */
+ pci_enable_wake(pdev, 0, 0);
+
pci_disable_device(pdev);
- retval = pci_set_power_state(pdev, pci_choose_state(pdev, state));
- if (retval)
- DPRINTK(PROBE,ERR, "Error %d setting power state\n", retval);
+ pci_set_power_state(pdev, pci_choose_state(pdev, state));
return 0;
}
+#ifdef CONFIG_PM
static int e100_resume(struct pci_dev *pdev)
{
struct net_device *netdev = pci_get_drvdata(pdev);
struct nic *nic = netdev_priv(netdev);
- int retval;
- retval = pci_set_power_state(pdev, PCI_D0);
- if (retval)
- DPRINTK(PROBE,ERR, "Error waking adapter\n");
+ pci_set_power_state(pdev, PCI_D0);
pci_restore_state(pdev);
/* ack any pending wake events, disable PME */
- retval = pci_enable_wake(pdev, 0, 0);
- if (retval)
- DPRINTK(PROBE,ERR, "Error clearing wake events\n");
+ pci_enable_wake(pdev, 0, 0);
netif_device_attach(netdev);
- if(netif_running(netdev))
+ if (netif_running(netdev))
e100_up(nic);
return 0;
}
-#endif
+#endif /* CONFIG_PM */
static void e100_shutdown(struct pci_dev *pdev)
{
- struct net_device *netdev = pci_get_drvdata(pdev);
- struct nic *nic = netdev_priv(netdev);
- int retval;
-
-#ifdef CONFIG_PM
- retval = pci_enable_wake(pdev, 0, nic->flags & (wol_magic | e100_asf(nic)));
-#else
- retval = pci_enable_wake(pdev, 0, nic->flags & (wol_magic));
-#endif
- if (retval)
- DPRINTK(PROBE,ERR, "Error enabling wake\n");
+ e100_suspend(pdev, PMSG_SUSPEND);
}
/* ------------------ PCI Error Recovery infrastructure -------------- */
@@ -2859,8 +2848,9 @@ static struct pci_driver e100_driver = {
.id_table = e100_id_table,
.probe = e100_probe,
.remove = __devexit_p(e100_remove),
-#ifdef CONFIG_PM
+ /* Power Management hooks */
.suspend = e100_suspend,
+#ifdef CONFIG_PM
.resume = e100_resume,
#endif
.shutdown = e100_shutdown,
diff --git a/drivers/net/e1000/LICENSE b/drivers/net/e1000/LICENSE
deleted file mode 100644
index 5f297e5bb465..000000000000
--- a/drivers/net/e1000/LICENSE
+++ /dev/null
@@ -1,339 +0,0 @@
-
-"This software program is licensed subject to the GNU General Public License
-(GPL). Version 2, June 1991, available at
-<http://www.fsf.org/copyleft/gpl.html>"
-
-GNU General Public License
-
-Version 2, June 1991
-
-Copyright (C) 1989, 1991 Free Software Foundation, Inc.
-59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
-
-Everyone is permitted to copy and distribute verbatim copies of this license
-document, but changing it is not allowed.
-
-Preamble
-
-The licenses for most software are designed to take away your freedom to
-share and change it. By contrast, the GNU General Public License is intended
-to guarantee your freedom to share and change free software--to make sure
-the software is free for all its users. This General Public License applies
-to most of the Free Software Foundation's software and to any other program
-whose authors commit to using it. (Some other Free Software Foundation
-software is covered by the GNU Library General Public License instead.) You
-can apply it to your programs, too.
-
-When we speak of free software, we are referring to freedom, not price. Our
-General Public Licenses are designed to make sure that you have the freedom
-to distribute copies of free software (and charge for this service if you
-wish), that you receive source code or can get it if you want it, that you
-can change the software or use pieces of it in new free programs; and that
-you know you can do these things.
-
-To protect your rights, we need to make restrictions that forbid anyone to
-deny you these rights or to ask you to surrender the rights. These
-restrictions translate to certain responsibilities for you if you distribute
-copies of the software, or if you modify it.
-
-For example, if you distribute copies of such a program, whether gratis or
-for a fee, you must give the recipients all the rights that you have. You
-must make sure that they, too, receive or can get the source code. And you
-must show them these terms so they know their rights.
-
-We protect your rights with two steps: (1) copyright the software, and (2)
-offer you this license which gives you legal permission to copy, distribute
-and/or modify the software.
-
-Also, for each author's protection and ours, we want to make certain that
-everyone understands that there is no warranty for this free software. If
-the software is modified by someone else and passed on, we want its
-recipients to know that what they have is not the original, so that any
-problems introduced by others will not reflect on the original authors'
-reputations.
-
-Finally, any free program is threatened constantly by software patents. We
-wish to avoid the danger that redistributors of a free program will
-individually obtain patent licenses, in effect making the program
-proprietary. To prevent this, we have made it clear that any patent must be
-licensed for everyone's free use or not licensed at all.
-
-The precise terms and conditions for copying, distribution and modification
-follow.
-
-TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
-
-0. This License applies to any program or other work which contains a notice
- placed by the copyright holder saying it may be distributed under the
- terms of this General Public License. The "Program", below, refers to any
- such program or work, and a "work based on the Program" means either the
- Program or any derivative work under copyright law: that is to say, a
- work containing the Program or a portion of it, either verbatim or with
- modifications and/or translated into another language. (Hereinafter,
- translation is included without limitation in the term "modification".)
- Each licensee is addressed as "you".
-
- Activities other than copying, distribution and modification are not
- covered by this License; they are outside its scope. The act of running
- the Program is not restricted, and the output from the Program is covered
- only if its contents constitute a work based on the Program (independent
- of having been made by running the Program). Whether that is true depends
- on what the Program does.
-
-1. You may copy and distribute verbatim copies of the Program's source code
- as you receive it, in any medium, provided that you conspicuously and
- appropriately publish on each copy an appropriate copyright notice and
- disclaimer of warranty; keep intact all the notices that refer to this
- License and to the absence of any warranty; and give any other recipients
- of the Program a copy of this License along with the Program.
-
- You may charge a fee for the physical act of transferring a copy, and you
- may at your option offer warranty protection in exchange for a fee.
-
-2. You may modify your copy or copies of the Program or any portion of it,
- thus forming a work based on the Program, and copy and distribute such
- modifications or work under the terms of Section 1 above, provided that
- you also meet all of these conditions:
-
- * a) You must cause the modified files to carry prominent notices stating
- that you changed the files and the date of any change.
-
- * b) You must cause any work that you distribute or publish, that in
- whole or in part contains or is derived from the Program or any part
- thereof, to be licensed as a whole at no charge to all third parties
- under the terms of this License.
-
- * c) If the modified program normally reads commands interactively when
- run, you must cause it, when started running for such interactive
- use in the most ordinary way, to print or display an announcement
- including an appropriate copyright notice and a notice that there is
- no warranty (or else, saying that you provide a warranty) and that
- users may redistribute the program under these conditions, and
- telling the user how to view a copy of this License. (Exception: if
- the Program itself is interactive but does not normally print such
- an announcement, your work based on the Program is not required to
- print an announcement.)
-
- These requirements apply to the modified work as a whole. If identifiable
- sections of that work are not derived from the Program, and can be
- reasonably considered independent and separate works in themselves, then
- this License, and its terms, do not apply to those sections when you
- distribute them as separate works. But when you distribute the same
- sections as part of a whole which is a work based on the Program, the
- distribution of the whole must be on the terms of this License, whose
- permissions for other licensees extend to the entire whole, and thus to
- each and every part regardless of who wrote it.
-
- Thus, it is not the intent of this section to claim rights or contest
- your rights to work written entirely by you; rather, the intent is to
- exercise the right to control the distribution of derivative or
- collective works based on the Program.
-
- In addition, mere aggregation of another work not based on the Program
- with the Program (or with a work based on the Program) on a volume of a
- storage or distribution medium does not bring the other work under the
- scope of this License.
-
-3. You may copy and distribute the Program (or a work based on it, under
- Section 2) in object code or executable form under the terms of Sections
- 1 and 2 above provided that you also do one of the following:
-
- * a) Accompany it with the complete corresponding machine-readable source
- code, which must be distributed under the terms of Sections 1 and 2
- above on a medium customarily used for software interchange; or,
-
- * b) Accompany it with a written offer, valid for at least three years,
- to give any third party, for a charge no more than your cost of
- physically performing source distribution, a complete machine-
- readable copy of the corresponding source code, to be distributed
- under the terms of Sections 1 and 2 above on a medium customarily
- used for software interchange; or,
-
- * c) Accompany it with the information you received as to the offer to
- distribute corresponding source code. (This alternative is allowed
- only for noncommercial distribution and only if you received the
- program in object code or executable form with such an offer, in
- accord with Subsection b above.)
-
- The source code for a work means the preferred form of the work for
- making modifications to it. For an executable work, complete source code
- means all the source code for all modules it contains, plus any
- associated interface definition files, plus the scripts used to control
- compilation and installation of the executable. However, as a special
- exception, the source code distributed need not include anything that is
- normally distributed (in either source or binary form) with the major
- components (compiler, kernel, and so on) of the operating system on which
- the executable runs, unless that component itself accompanies the
- executable.
-
- If distribution of executable or object code is made by offering access
- to copy from a designated place, then offering equivalent access to copy
- the source code from the same place counts as distribution of the source
- code, even though third parties are not compelled to copy the source
- along with the object code.
-
-4. You may not copy, modify, sublicense, or distribute the Program except as
- expressly provided under this License. Any attempt otherwise to copy,
- modify, sublicense or distribute the Program is void, and will
- automatically terminate your rights under this License. However, parties
- who have received copies, or rights, from you under this License will not
- have their licenses terminated so long as such parties remain in full
- compliance.
-
-5. You are not required to accept this License, since you have not signed
- it. However, nothing else grants you permission to modify or distribute
- the Program or its derivative works. These actions are prohibited by law
- if you do not accept this License. Therefore, by modifying or
- distributing the Program (or any work based on the Program), you
- indicate your acceptance of this License to do so, and all its terms and
- conditions for copying, distributing or modifying the Program or works
- based on it.
-
-6. Each time you redistribute the Program (or any work based on the
- Program), the recipient automatically receives a license from the
- original licensor to copy, distribute or modify the Program subject to
- these terms and conditions. You may not impose any further restrictions
- on the recipients' exercise of the rights granted herein. You are not
- responsible for enforcing compliance by third parties to this License.
-
-7. If, as a consequence of a court judgment or allegation of patent
- infringement or for any other reason (not limited to patent issues),
- conditions are imposed on you (whether by court order, agreement or
- otherwise) that contradict the conditions of this License, they do not
- excuse you from the conditions of this License. If you cannot distribute
- so as to satisfy simultaneously your obligations under this License and
- any other pertinent obligations, then as a consequence you may not
- distribute the Program at all. For example, if a patent license would
- not permit royalty-free redistribution of the Program by all those who
- receive copies directly or indirectly through you, then the only way you
- could satisfy both it and this License would be to refrain entirely from
- distribution of the Program.
-
- If any portion of this section is held invalid or unenforceable under any
- particular circumstance, the balance of the section is intended to apply
- and the section as a whole is intended to apply in other circumstances.
-
- It is not the purpose of this section to induce you to infringe any
- patents or other property right claims or to contest validity of any
- such claims; this section has the sole purpose of protecting the
- integrity of the free software distribution system, which is implemented
- by public license practices. Many people have made generous contributions
- to the wide range of software distributed through that system in
- reliance on consistent application of that system; it is up to the
- author/donor to decide if he or she is willing to distribute software
- through any other system and a licensee cannot impose that choice.
-
- This section is intended to make thoroughly clear what is believed to be
- a consequence of the rest of this License.
-
-8. If the distribution and/or use of the Program is restricted in certain
- countries either by patents or by copyrighted interfaces, the original
- copyright holder who places the Program under this License may add an
- explicit geographical distribution limitation excluding those countries,
- so that distribution is permitted only in or among countries not thus
- excluded. In such case, this License incorporates the limitation as if
- written in the body of this License.
-
-9. The Free Software Foundation may publish revised and/or new versions of
- the General Public License from time to time. Such new versions will be
- similar in spirit to the present version, but may differ in detail to
- address new problems or concerns.
-
- Each version is given a distinguishing version number. If the Program
- specifies a version number of this License which applies to it and "any
- later version", you have the option of following the terms and
- conditions either of that version or of any later version published by
- the Free Software Foundation. If the Program does not specify a version
- number of this License, you may choose any version ever published by the
- Free Software Foundation.
-
-10. If you wish to incorporate parts of the Program into other free programs
- whose distribution conditions are different, write to the author to ask
- for permission. For software which is copyrighted by the Free Software
- Foundation, write to the Free Software Foundation; we sometimes make
- exceptions for this. Our decision will be guided by the two goals of
- preserving the free status of all derivatives of our free software and
- of promoting the sharing and reuse of software generally.
-
- NO WARRANTY
-
-11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
- FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
- OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
- PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER
- EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE
- ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH
- YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL
- NECESSARY SERVICING, REPAIR OR CORRECTION.
-
-12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
- WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
- REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR
- DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL
- DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM
- (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED
- INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF
- THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR
- OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
-
-END OF TERMS AND CONDITIONS
-
-How to Apply These Terms to Your New Programs
-
-If you develop a new program, and you want it to be of the greatest
-possible use to the public, the best way to achieve this is to make it free
-software which everyone can redistribute and change under these terms.
-
-To do so, attach the following notices to the program. It is safest to
-attach them to the start of each source file to most effectively convey the
-exclusion of warranty; and each file should have at least the "copyright"
-line and a pointer to where the full notice is found.
-
-one line to give the program's name and an idea of what it does.
-Copyright (C) yyyy name of author
-
-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.
-
-Also add information on how to contact you by electronic and paper mail.
-
-If the program is interactive, make it output a short notice like this when
-it starts in an interactive mode:
-
-Gnomovision version 69, Copyright (C) year name of author Gnomovision comes
-with ABSOLUTELY NO WARRANTY; for details type 'show w'. This is free
-software, and you are welcome to redistribute it under certain conditions;
-type 'show c' for details.
-
-The hypothetical commands 'show w' and 'show c' should show the appropriate
-parts of the General Public License. Of course, the commands you use may be
-called something other than 'show w' and 'show c'; they could even be
-mouse-clicks or menu items--whatever suits your program.
-
-You should also get your employer (if you work as a programmer) or your
-school, if any, to sign a "copyright disclaimer" for the program, if
-necessary. Here is a sample; alter the names:
-
-Yoyodyne, Inc., hereby disclaims all copyright interest in the program
-'Gnomovision' (which makes passes at compilers) written by James Hacker.
-
-signature of Ty Coon, 1 April 1989
-Ty Coon, President of Vice
-
-This General Public License does not permit incorporating your program into
-proprietary programs. If your program is a subroutine library, you may
-consider it more useful to permit linking proprietary applications with the
-library. If this is what you want to do, use the GNU Library General Public
-License instead of this License.
diff --git a/drivers/net/e1000/Makefile b/drivers/net/e1000/Makefile
index 5dea2b7dea4d..4a6ab1522451 100644
--- a/drivers/net/e1000/Makefile
+++ b/drivers/net/e1000/Makefile
@@ -1,25 +1,24 @@
################################################################################
#
-#
-# Copyright(c) 1999 - 2006 Intel Corporation. All rights reserved.
-#
-# This program is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License as published by the Free
-# Software Foundation; 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
+# Intel PRO/1000 Linux driver
+# Copyright(c) 1999 - 2006 Intel Corporation.
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms and conditions of the GNU General Public License,
+# version 2, as published by the Free Software Foundation.
+#
+# This program is distributed in the hope 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.
-#
-# The full GNU General Public License is included in this distribution in the
-# file called LICENSE.
-#
+# this program; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# The full GNU General Public License is included in this distribution in
+# the file called "COPYING".
+#
# Contact Information:
# Linux NICS <linux.nics@intel.com>
# e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
diff --git a/drivers/net/e1000/e1000.h b/drivers/net/e1000/e1000.h
index 98afa9c2057e..7ecce438d258 100644
--- a/drivers/net/e1000/e1000.h
+++ b/drivers/net/e1000/e1000.h
@@ -1,25 +1,24 @@
/*******************************************************************************
-
- Copyright(c) 1999 - 2006 Intel Corporation. All rights reserved.
-
- This program is free software; you can redistribute it and/or modify it
- under the terms of the GNU General Public License as published by the Free
- Software Foundation; 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
+ Intel PRO/1000 Linux driver
+ Copyright(c) 1999 - 2006 Intel Corporation.
+
+ This program is free software; you can redistribute it and/or modify it
+ under the terms and conditions of the GNU General Public License,
+ version 2, as published by the Free Software Foundation.
+
+ This program is distributed in the hope 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.
-
- The full GNU General Public License is included in this distribution in the
- file called LICENSE.
-
+ this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+
+ The full GNU General Public License is included in this distribution in
+ the file called "COPYING".
+
Contact Information:
Linux NICS <linux.nics@intel.com>
e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
@@ -346,29 +345,9 @@ struct e1000_adapter {
};
enum e1000_state_t {
- __E1000_DRIVER_TESTING,
+ __E1000_TESTING,
__E1000_RESETTING,
+ __E1000_DOWN
};
-/* e1000_main.c */
-extern char e1000_driver_name[];
-extern char e1000_driver_version[];
-int e1000_up(struct e1000_adapter *adapter);
-void e1000_down(struct e1000_adapter *adapter);
-void e1000_reset(struct e1000_adapter *adapter);
-void e1000_reinit_locked(struct e1000_adapter *adapter);
-int e1000_setup_all_tx_resources(struct e1000_adapter *adapter);
-void e1000_free_all_tx_resources(struct e1000_adapter *adapter);
-int e1000_setup_all_rx_resources(struct e1000_adapter *adapter);
-void e1000_free_all_rx_resources(struct e1000_adapter *adapter);
-void e1000_update_stats(struct e1000_adapter *adapter);
-int e1000_set_spd_dplx(struct e1000_adapter *adapter, uint16_t spddplx);
-
-/* e1000_ethtool.c */
-void e1000_set_ethtool_ops(struct net_device *netdev);
-
-/* e1000_param.c */
-void e1000_check_options(struct e1000_adapter *adapter);
-
-
#endif /* _E1000_H_ */
diff --git a/drivers/net/e1000/e1000_ethtool.c b/drivers/net/e1000/e1000_ethtool.c
index e39aa1fc4d1e..778ede3c0216 100644
--- a/drivers/net/e1000/e1000_ethtool.c
+++ b/drivers/net/e1000/e1000_ethtool.c
@@ -1,25 +1,24 @@
/*******************************************************************************
-
- Copyright(c) 1999 - 2006 Intel Corporation. All rights reserved.
-
- This program is free software; you can redistribute it and/or modify it
- under the terms of the GNU General Public License as published by the Free
- Software Foundation; 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
+ Intel PRO/1000 Linux driver
+ Copyright(c) 1999 - 2006 Intel Corporation.
+
+ This program is free software; you can redistribute it and/or modify it
+ under the terms and conditions of the GNU General Public License,
+ version 2, as published by the Free Software Foundation.
+
+ This program is distributed in the hope 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.
-
- The full GNU General Public License is included in this distribution in the
- file called LICENSE.
-
+ this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+
+ The full GNU General Public License is included in this distribution in
+ the file called "COPYING".
+
Contact Information:
Linux NICS <linux.nics@intel.com>
e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
@@ -33,6 +32,21 @@
#include <asm/uaccess.h>
+extern char e1000_driver_name[];
+extern char e1000_driver_version[];
+
+extern int e1000_up(struct e1000_adapter *adapter);
+extern void e1000_down(struct e1000_adapter *adapter);
+extern void e1000_reinit_locked(struct e1000_adapter *adapter);
+extern void e1000_reset(struct e1000_adapter *adapter);
+extern int e1000_set_spd_dplx(struct e1000_adapter *adapter, uint16_t spddplx);
+extern int e1000_setup_all_rx_resources(struct e1000_adapter *adapter);
+extern int e1000_setup_all_tx_resources(struct e1000_adapter *adapter);
+extern void e1000_free_all_rx_resources(struct e1000_adapter *adapter);
+extern void e1000_free_all_tx_resources(struct e1000_adapter *adapter);
+extern void e1000_update_stats(struct e1000_adapter *adapter);
+
+
struct e1000_stats {
char stat_string[ETH_GSTRING_LEN];
int sizeof_stat;
@@ -42,26 +56,30 @@ struct e1000_stats {
#define E1000_STAT(m) sizeof(((struct e1000_adapter *)0)->m), \
offsetof(struct e1000_adapter, m)
static const struct e1000_stats e1000_gstrings_stats[] = {
- { "rx_packets", E1000_STAT(net_stats.rx_packets) },
- { "tx_packets", E1000_STAT(net_stats.tx_packets) },
- { "rx_bytes", E1000_STAT(net_stats.rx_bytes) },
- { "tx_bytes", E1000_STAT(net_stats.tx_bytes) },
- { "rx_errors", E1000_STAT(net_stats.rx_errors) },
- { "tx_errors", E1000_STAT(net_stats.tx_errors) },
+ { "rx_packets", E1000_STAT(stats.gprc) },
+ { "tx_packets", E1000_STAT(stats.gptc) },
+ { "rx_bytes", E1000_STAT(stats.gorcl) },
+ { "tx_bytes", E1000_STAT(stats.gotcl) },
+ { "rx_broadcast", E1000_STAT(stats.bprc) },
+ { "tx_broadcast", E1000_STAT(stats.bptc) },
+ { "rx_multicast", E1000_STAT(stats.mprc) },
+ { "tx_multicast", E1000_STAT(stats.mptc) },
+ { "rx_errors", E1000_STAT(stats.rxerrc) },
+ { "tx_errors", E1000_STAT(stats.txerrc) },
{ "tx_dropped", E1000_STAT(net_stats.tx_dropped) },
- { "multicast", E1000_STAT(net_stats.multicast) },
- { "collisions", E1000_STAT(net_stats.collisions) },
- { "rx_length_errors", E1000_STAT(net_stats.rx_length_errors) },
+ { "multicast", E1000_STAT(stats.mprc) },
+ { "collisions", E1000_STAT(stats.colc) },
+ { "rx_length_errors", E1000_STAT(stats.rlerrc) },
{ "rx_over_errors", E1000_STAT(net_stats.rx_over_errors) },
- { "rx_crc_errors", E1000_STAT(net_stats.rx_crc_errors) },
+ { "rx_crc_errors", E1000_STAT(stats.crcerrs) },
{ "rx_frame_errors", E1000_STAT(net_stats.rx_frame_errors) },
{ "rx_no_buffer_count", E1000_STAT(stats.rnbc) },
- { "rx_missed_errors", E1000_STAT(net_stats.rx_missed_errors) },
- { "tx_aborted_errors", E1000_STAT(net_stats.tx_aborted_errors) },
- { "tx_carrier_errors", E1000_STAT(net_stats.tx_carrier_errors) },
+ { "rx_missed_errors", E1000_STAT(stats.mpc) },
+ { "tx_aborted_errors", E1000_STAT(stats.ecol) },
+ { "tx_carrier_errors", E1000_STAT(stats.tncrs) },
{ "tx_fifo_errors", E1000_STAT(net_stats.tx_fifo_errors) },
{ "tx_heartbeat_errors", E1000_STAT(net_stats.tx_heartbeat_errors) },
- { "tx_window_errors", E1000_STAT(net_stats.tx_window_errors) },
+ { "tx_window_errors", E1000_STAT(stats.latecol) },
{ "tx_abort_late_coll", E1000_STAT(stats.latecol) },
{ "tx_deferred_ok", E1000_STAT(stats.dc) },
{ "tx_single_coll_ok", E1000_STAT(stats.scc) },
@@ -193,13 +211,9 @@ e1000_set_settings(struct net_device *netdev, struct ethtool_cmd *ecmd)
ADVERTISED_FIBRE |
ADVERTISED_Autoneg;
else
- hw->autoneg_advertised = ADVERTISED_10baseT_Half |
- ADVERTISED_10baseT_Full |
- ADVERTISED_100baseT_Half |
- ADVERTISED_100baseT_Full |
- ADVERTISED_1000baseT_Full|
- ADVERTISED_Autoneg |
- ADVERTISED_TP;
+ hw->autoneg_advertised = ecmd->advertising |
+ ADVERTISED_TP |
+ ADVERTISED_Autoneg;
ecmd->advertising = hw->autoneg_advertised;
} else
if (e1000_set_spd_dplx(adapter, ecmd->speed + ecmd->duplex)) {
@@ -229,11 +243,11 @@ e1000_get_pauseparam(struct net_device *netdev,
pause->autoneg =
(adapter->fc_autoneg ? AUTONEG_ENABLE : AUTONEG_DISABLE);
- if (hw->fc == e1000_fc_rx_pause)
+ if (hw->fc == E1000_FC_RX_PAUSE)
pause->rx_pause = 1;
- else if (hw->fc == e1000_fc_tx_pause)
+ else if (hw->fc == E1000_FC_TX_PAUSE)
pause->tx_pause = 1;
- else if (hw->fc == e1000_fc_full) {
+ else if (hw->fc == E1000_FC_FULL) {
pause->rx_pause = 1;
pause->tx_pause = 1;
}
@@ -253,13 +267,13 @@ e1000_set_pauseparam(struct net_device *netdev,
msleep(1);
if (pause->rx_pause && pause->tx_pause)
- hw->fc = e1000_fc_full;
+ hw->fc = E1000_FC_FULL;
else if (pause->rx_pause && !pause->tx_pause)
- hw->fc = e1000_fc_rx_pause;
+ hw->fc = E1000_FC_RX_PAUSE;
else if (!pause->rx_pause && pause->tx_pause)
- hw->fc = e1000_fc_tx_pause;
+ hw->fc = E1000_FC_TX_PAUSE;
else if (!pause->rx_pause && !pause->tx_pause)
- hw->fc = e1000_fc_none;
+ hw->fc = E1000_FC_NONE;
hw->original_fc = hw->fc;
@@ -632,8 +646,8 @@ e1000_set_ringparam(struct net_device *netdev,
{
struct e1000_adapter *adapter = netdev_priv(netdev);
e1000_mac_type mac_type = adapter->hw.mac_type;
- struct e1000_tx_ring *txdr, *tx_old, *tx_new;
- struct e1000_rx_ring *rxdr, *rx_old, *rx_new;
+ struct e1000_tx_ring *txdr, *tx_old;
+ struct e1000_rx_ring *rxdr, *rx_old;
int i, err, tx_ring_size, rx_ring_size;
if ((ring->rx_mini_pending) || (ring->rx_jumbo_pending))
@@ -651,23 +665,17 @@ e1000_set_ringparam(struct net_device *netdev,
tx_old = adapter->tx_ring;
rx_old = adapter->rx_ring;
- adapter->tx_ring = kmalloc(tx_ring_size, GFP_KERNEL);
- if (!adapter->tx_ring) {
- err = -ENOMEM;
- goto err_setup_rx;
- }
- memset(adapter->tx_ring, 0, tx_ring_size);
+ err = -ENOMEM;
+ txdr = kzalloc(tx_ring_size, GFP_KERNEL);
+ if (!txdr)
+ goto err_alloc_tx;
- adapter->rx_ring = kmalloc(rx_ring_size, GFP_KERNEL);
- if (!adapter->rx_ring) {
- kfree(adapter->tx_ring);
- err = -ENOMEM;
- goto err_setup_rx;
- }
- memset(adapter->rx_ring, 0, rx_ring_size);
+ rxdr = kzalloc(rx_ring_size, GFP_KERNEL);
+ if (!rxdr)
+ goto err_alloc_rx;
- txdr = adapter->tx_ring;
- rxdr = adapter->rx_ring;
+ adapter->tx_ring = txdr;
+ adapter->rx_ring = rxdr;
rxdr->count = max(ring->rx_pending,(uint32_t)E1000_MIN_RXD);
rxdr->count = min(rxdr->count,(uint32_t)(mac_type < e1000_82544 ?
@@ -694,16 +702,14 @@ e1000_set_ringparam(struct net_device *netdev,
/* save the new, restore the old in order to free it,
* then restore the new back again */
- rx_new = adapter->rx_ring;
- tx_new = adapter->tx_ring;
adapter->rx_ring = rx_old;
adapter->tx_ring = tx_old;
e1000_free_all_rx_resources(adapter);
e1000_free_all_tx_resources(adapter);
kfree(tx_old);
kfree(rx_old);
- adapter->rx_ring = rx_new;
- adapter->tx_ring = tx_new;
+ adapter->rx_ring = rxdr;
+ adapter->tx_ring = txdr;
if ((err = e1000_up(adapter)))
goto err_setup;
}
@@ -715,6 +721,10 @@ err_setup_tx:
err_setup_rx:
adapter->rx_ring = rx_old;
adapter->tx_ring = tx_old;
+ kfree(rxdr);
+err_alloc_rx:
+ kfree(txdr);
+err_alloc_tx:
e1000_up(adapter);
err_setup:
clear_bit(__E1000_RESETTING, &adapter->flags);
@@ -1610,7 +1620,7 @@ e1000_diag_test(struct net_device *netdev,
struct e1000_adapter *adapter = netdev_priv(netdev);
boolean_t if_running = netif_running(netdev);
- set_bit(__E1000_DRIVER_TESTING, &adapter->flags);
+ set_bit(__E1000_TESTING, &adapter->flags);
if (eth_test->flags == ETH_TEST_FL_OFFLINE) {
/* Offline tests */
@@ -1655,7 +1665,7 @@ e1000_diag_test(struct net_device *netdev,
adapter->hw.autoneg = autoneg;
e1000_reset(adapter);
- clear_bit(__E1000_DRIVER_TESTING, &adapter->flags);
+ clear_bit(__E1000_TESTING, &adapter->flags);
if (if_running)
dev_open(netdev);
} else {
@@ -1670,7 +1680,7 @@ e1000_diag_test(struct net_device *netdev,
data[2] = 0;
data[3] = 0;
- clear_bit(__E1000_DRIVER_TESTING, &adapter->flags);
+ clear_bit(__E1000_TESTING, &adapter->flags);
}
msleep_interruptible(4 * 1000);
}
diff --git a/drivers/net/e1000/e1000_hw.c b/drivers/net/e1000/e1000_hw.c
index 10b8c8c25325..65077f39da69 100644
--- a/drivers/net/e1000/e1000_hw.c
+++ b/drivers/net/e1000/e1000_hw.c
@@ -1,25 +1,24 @@
/*******************************************************************************
-
- Copyright(c) 1999 - 2006 Intel Corporation. All rights reserved.
-
- This program is free software; you can redistribute it and/or modify it
- under the terms of the GNU General Public License as published by the Free
- Software Foundation; 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
+ Intel PRO/1000 Linux driver
+ Copyright(c) 1999 - 2006 Intel Corporation.
+
+ This program is free software; you can redistribute it and/or modify it
+ under the terms and conditions of the GNU General Public License,
+ version 2, as published by the Free Software Foundation.
+
+ This program is distributed in the hope 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.
-
- The full GNU General Public License is included in this distribution in the
- file called LICENSE.
-
+ this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+
+ The full GNU General Public License is included in this distribution in
+ the file called "COPYING".
+
Contact Information:
Linux NICS <linux.nics@intel.com>
e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
@@ -34,6 +33,63 @@
#include "e1000_hw.h"
+static int32_t e1000_swfw_sync_acquire(struct e1000_hw *hw, uint16_t mask);
+static void e1000_swfw_sync_release(struct e1000_hw *hw, uint16_t mask);
+static int32_t e1000_read_kmrn_reg(struct e1000_hw *hw, uint32_t reg_addr, uint16_t *data);
+static int32_t e1000_write_kmrn_reg(struct e1000_hw *hw, uint32_t reg_addr, uint16_t data);
+static int32_t e1000_get_software_semaphore(struct e1000_hw *hw);
+static void e1000_release_software_semaphore(struct e1000_hw *hw);
+
+static uint8_t e1000_arc_subsystem_valid(struct e1000_hw *hw);
+static int32_t e1000_check_downshift(struct e1000_hw *hw);
+static int32_t e1000_check_polarity(struct e1000_hw *hw, e1000_rev_polarity *polarity);
+static void e1000_clear_hw_cntrs(struct e1000_hw *hw);
+static void e1000_clear_vfta(struct e1000_hw *hw);
+static int32_t e1000_commit_shadow_ram(struct e1000_hw *hw);
+static int32_t e1000_config_dsp_after_link_change(struct e1000_hw *hw, boolean_t link_up);
+static int32_t e1000_config_fc_after_link_up(struct e1000_hw *hw);
+static int32_t e1000_detect_gig_phy(struct e1000_hw *hw);
+static int32_t e1000_erase_ich8_4k_segment(struct e1000_hw *hw, uint32_t bank);
+static int32_t e1000_get_auto_rd_done(struct e1000_hw *hw);
+static int32_t e1000_get_cable_length(struct e1000_hw *hw, uint16_t *min_length, uint16_t *max_length);
+static int32_t e1000_get_hw_eeprom_semaphore(struct e1000_hw *hw);
+static int32_t e1000_get_phy_cfg_done(struct e1000_hw *hw);
+static int32_t e1000_get_software_flag(struct e1000_hw *hw);
+static int32_t e1000_ich8_cycle_init(struct e1000_hw *hw);
+static int32_t e1000_ich8_flash_cycle(struct e1000_hw *hw, uint32_t timeout);
+static int32_t e1000_id_led_init(struct e1000_hw *hw);
+static int32_t e1000_init_lcd_from_nvm_config_region(struct e1000_hw *hw, uint32_t cnf_base_addr, uint32_t cnf_size);
+static int32_t e1000_init_lcd_from_nvm(struct e1000_hw *hw);
+static void e1000_init_rx_addrs(struct e1000_hw *hw);
+static void e1000_initialize_hardware_bits(struct e1000_hw *hw);
+static boolean_t e1000_is_onboard_nvm_eeprom(struct e1000_hw *hw);
+static int32_t e1000_kumeran_lock_loss_workaround(struct e1000_hw *hw);
+static int32_t e1000_mng_enable_host_if(struct e1000_hw *hw);
+static int32_t e1000_mng_host_if_write(struct e1000_hw *hw, uint8_t *buffer, uint16_t length, uint16_t offset, uint8_t *sum);
+static int32_t e1000_mng_write_cmd_header(struct e1000_hw* hw, struct e1000_host_mng_command_header* hdr);
+static int32_t e1000_mng_write_commit(struct e1000_hw *hw);
+static int32_t e1000_phy_ife_get_info(struct e1000_hw *hw, struct e1000_phy_info *phy_info);
+static int32_t e1000_phy_igp_get_info(struct e1000_hw *hw, struct e1000_phy_info *phy_info);
+static int32_t e1000_read_eeprom_eerd(struct e1000_hw *hw, uint16_t offset, uint16_t words, uint16_t *data);
+static int32_t e1000_write_eeprom_eewr(struct e1000_hw *hw, uint16_t offset, uint16_t words, uint16_t *data);
+static int32_t e1000_poll_eerd_eewr_done(struct e1000_hw *hw, int eerd);
+static int32_t e1000_phy_m88_get_info(struct e1000_hw *hw, struct e1000_phy_info *phy_info);
+static void e1000_put_hw_eeprom_semaphore(struct e1000_hw *hw);
+static int32_t e1000_read_ich8_byte(struct e1000_hw *hw, uint32_t index, uint8_t *data);
+static int32_t e1000_verify_write_ich8_byte(struct e1000_hw *hw, uint32_t index, uint8_t byte);
+static int32_t e1000_write_ich8_byte(struct e1000_hw *hw, uint32_t index, uint8_t byte);
+static int32_t e1000_read_ich8_word(struct e1000_hw *hw, uint32_t index, uint16_t *data);
+static int32_t e1000_read_ich8_data(struct e1000_hw *hw, uint32_t index, uint32_t size, uint16_t *data);
+static int32_t e1000_write_ich8_data(struct e1000_hw *hw, uint32_t index, uint32_t size, uint16_t data);
+static int32_t e1000_read_eeprom_ich8(struct e1000_hw *hw, uint16_t offset, uint16_t words, uint16_t *data);
+static int32_t e1000_write_eeprom_ich8(struct e1000_hw *hw, uint16_t offset, uint16_t words, uint16_t *data);
+static void e1000_release_software_flag(struct e1000_hw *hw);
+static int32_t e1000_set_d3_lplu_state(struct e1000_hw *hw, boolean_t active);
+static int32_t e1000_set_d0_lplu_state(struct e1000_hw *hw, boolean_t active);
+static int32_t e1000_set_pci_ex_no_snoop(struct e1000_hw *hw, uint32_t no_snoop);
+static void e1000_set_pci_express_master_disable(struct e1000_hw *hw);
+static int32_t e1000_wait_autoneg(struct e1000_hw *hw);
+static void e1000_write_reg_io(struct e1000_hw *hw, uint32_t offset, uint32_t value);
static int32_t e1000_set_phy_type(struct e1000_hw *hw);
static void e1000_phy_init_script(struct e1000_hw *hw);
static int32_t e1000_setup_copper_link(struct e1000_hw *hw);
@@ -70,69 +126,10 @@ static int32_t e1000_polarity_reversal_workaround(struct e1000_hw *hw);
static int32_t e1000_set_phy_mode(struct e1000_hw *hw);
static int32_t e1000_host_if_read_cookie(struct e1000_hw *hw, uint8_t *buffer);
static uint8_t e1000_calculate_mng_checksum(char *buffer, uint32_t length);
-static uint8_t e1000_arc_subsystem_valid(struct e1000_hw *hw);
-static int32_t e1000_check_downshift(struct e1000_hw *hw);
-static int32_t e1000_check_polarity(struct e1000_hw *hw, uint16_t *polarity);
-static void e1000_clear_hw_cntrs(struct e1000_hw *hw);
-static void e1000_clear_vfta(struct e1000_hw *hw);
-static int32_t e1000_commit_shadow_ram(struct e1000_hw *hw);
-static int32_t e1000_config_dsp_after_link_change(struct e1000_hw *hw,
- boolean_t link_up);
-static int32_t e1000_config_fc_after_link_up(struct e1000_hw *hw);
-static int32_t e1000_detect_gig_phy(struct e1000_hw *hw);
-static int32_t e1000_get_auto_rd_done(struct e1000_hw *hw);
-static int32_t e1000_get_cable_length(struct e1000_hw *hw,
- uint16_t *min_length,
- uint16_t *max_length);
-static int32_t e1000_get_hw_eeprom_semaphore(struct e1000_hw *hw);
-static int32_t e1000_get_phy_cfg_done(struct e1000_hw *hw);
-static int32_t e1000_id_led_init(struct e1000_hw * hw);
-static void e1000_init_rx_addrs(struct e1000_hw *hw);
-static boolean_t e1000_is_onboard_nvm_eeprom(struct e1000_hw *hw);
-static int32_t e1000_poll_eerd_eewr_done(struct e1000_hw *hw, int eerd);
-static void e1000_put_hw_eeprom_semaphore(struct e1000_hw *hw);
-static int32_t e1000_read_eeprom_eerd(struct e1000_hw *hw, uint16_t offset,
- uint16_t words, uint16_t *data);
-static int32_t e1000_set_d0_lplu_state(struct e1000_hw *hw, boolean_t active);
-static int32_t e1000_set_d3_lplu_state(struct e1000_hw *hw, boolean_t active);
-static int32_t e1000_wait_autoneg(struct e1000_hw *hw);
-
-static void e1000_write_reg_io(struct e1000_hw *hw, uint32_t offset,
- uint32_t value);
-
-#define E1000_WRITE_REG_IO(a, reg, val) \
- e1000_write_reg_io((a), E1000_##reg, val)
static int32_t e1000_configure_kmrn_for_10_100(struct e1000_hw *hw,
uint16_t duplex);
static int32_t e1000_configure_kmrn_for_1000(struct e1000_hw *hw);
-static int32_t e1000_erase_ich8_4k_segment(struct e1000_hw *hw,
- uint32_t segment);
-static int32_t e1000_get_software_flag(struct e1000_hw *hw);
-static int32_t e1000_get_software_semaphore(struct e1000_hw *hw);
-static int32_t e1000_init_lcd_from_nvm(struct e1000_hw *hw);
-static int32_t e1000_kumeran_lock_loss_workaround(struct e1000_hw *hw);
-static int32_t e1000_read_eeprom_ich8(struct e1000_hw *hw, uint16_t offset,
- uint16_t words, uint16_t *data);
-static int32_t e1000_read_ich8_byte(struct e1000_hw *hw, uint32_t index,
- uint8_t* data);
-static int32_t e1000_read_ich8_word(struct e1000_hw *hw, uint32_t index,
- uint16_t *data);
-static int32_t e1000_read_kmrn_reg(struct e1000_hw *hw, uint32_t reg_addr,
- uint16_t *data);
-static void e1000_release_software_flag(struct e1000_hw *hw);
-static void e1000_release_software_semaphore(struct e1000_hw *hw);
-static int32_t e1000_set_pci_ex_no_snoop(struct e1000_hw *hw,
- uint32_t no_snoop);
-static int32_t e1000_verify_write_ich8_byte(struct e1000_hw *hw,
- uint32_t index, uint8_t byte);
-static int32_t e1000_write_eeprom_ich8(struct e1000_hw *hw, uint16_t offset,
- uint16_t words, uint16_t *data);
-static int32_t e1000_write_ich8_byte(struct e1000_hw *hw, uint32_t index,
- uint8_t data);
-static int32_t e1000_write_kmrn_reg(struct e1000_hw *hw, uint32_t reg_addr,
- uint16_t data);
-
/* IGP cable length table */
static const
uint16_t e1000_igp_cable_length_table[IGP01E1000_AGC_LENGTH_TABLE_SIZE] =
@@ -156,13 +153,12 @@ uint16_t e1000_igp_2_cable_length_table[IGP02E1000_AGC_LENGTH_TABLE_SIZE] =
83, 89, 95, 100, 105, 109, 113, 116, 119, 122, 124,
104, 109, 114, 118, 121, 124};
-
/******************************************************************************
* Set the phy type member in the hw struct.
*
* hw - Struct containing variables accessed by shared code
*****************************************************************************/
-int32_t
+static int32_t
e1000_set_phy_type(struct e1000_hw *hw)
{
DEBUGFUNC("e1000_set_phy_type");
@@ -208,7 +204,6 @@ e1000_set_phy_type(struct e1000_hw *hw)
return E1000_SUCCESS;
}
-
/******************************************************************************
* IGP phy init script - initializes the GbE PHY
*
@@ -667,19 +662,12 @@ e1000_reset_hw(struct e1000_hw *hw)
E1000_WRITE_FLUSH(hw);
}
/* fall through */
- case e1000_82571:
- case e1000_82572:
- case e1000_ich8lan:
- case e1000_80003es2lan:
+ default:
+ /* Auto read done will delay 5ms or poll based on mac type */
ret_val = e1000_get_auto_rd_done(hw);
if (ret_val)
- /* We don't want to continue accessing MAC registers. */
return ret_val;
break;
- default:
- /* Wait for EEPROM reload (it happens automatically) */
- msleep(5);
- break;
}
/* Disable HW ARPs on ASF enabled adapters */
@@ -722,6 +710,123 @@ e1000_reset_hw(struct e1000_hw *hw)
}
/******************************************************************************
+ *
+ * Initialize a number of hardware-dependent bits
+ *
+ * hw: Struct containing variables accessed by shared code
+ *
+ * This function contains hardware limitation workarounds for PCI-E adapters
+ *
+ *****************************************************************************/
+static void
+e1000_initialize_hardware_bits(struct e1000_hw *hw)
+{
+ if ((hw->mac_type >= e1000_82571) && (!hw->initialize_hw_bits_disable)) {
+ /* Settings common to all PCI-express silicon */
+ uint32_t reg_ctrl, reg_ctrl_ext;
+ uint32_t reg_tarc0, reg_tarc1;
+ uint32_t reg_tctl;
+ uint32_t reg_txdctl, reg_txdctl1;
+
+ /* link autonegotiation/sync workarounds */
+ reg_tarc0 = E1000_READ_REG(hw, TARC0);
+ reg_tarc0 &= ~((1 << 30)|(1 << 29)|(1 << 28)|(1 << 27));
+
+ /* Enable not-done TX descriptor counting */
+ reg_txdctl = E1000_READ_REG(hw, TXDCTL);
+ reg_txdctl |= E1000_TXDCTL_COUNT_DESC;
+ E1000_WRITE_REG(hw, TXDCTL, reg_txdctl);
+ reg_txdctl1 = E1000_READ_REG(hw, TXDCTL1);
+ reg_txdctl1 |= E1000_TXDCTL_COUNT_DESC;
+ E1000_WRITE_REG(hw, TXDCTL1, reg_txdctl1);
+
+ switch (hw->mac_type) {
+ case e1000_82571:
+ case e1000_82572:
+ /* Clear PHY TX compatible mode bits */
+ reg_tarc1 = E1000_READ_REG(hw, TARC1);
+ reg_tarc1 &= ~((1 << 30)|(1 << 29));
+
+ /* link autonegotiation/sync workarounds */
+ reg_tarc0 |= ((1 << 26)|(1 << 25)|(1 << 24)|(1 << 23));
+
+ /* TX ring control fixes */
+ reg_tarc1 |= ((1 << 26)|(1 << 25)|(1 << 24));
+
+ /* Multiple read bit is reversed polarity */
+ reg_tctl = E1000_READ_REG(hw, TCTL);
+ if (reg_tctl & E1000_TCTL_MULR)
+ reg_tarc1 &= ~(1 << 28);
+ else
+ reg_tarc1 |= (1 << 28);
+
+ E1000_WRITE_REG(hw, TARC1, reg_tarc1);
+ break;
+ case e1000_82573:
+ reg_ctrl_ext = E1000_READ_REG(hw, CTRL_EXT);
+ reg_ctrl_ext &= ~(1 << 23);
+ reg_ctrl_ext |= (1 << 22);
+
+ /* TX byte count fix */
+ reg_ctrl = E1000_READ_REG(hw, CTRL);
+ reg_ctrl &= ~(1 << 29);
+
+ E1000_WRITE_REG(hw, CTRL_EXT, reg_ctrl_ext);
+ E1000_WRITE_REG(hw, CTRL, reg_ctrl);
+ break;
+ case e1000_80003es2lan:
+ /* improve small packet performace for fiber/serdes */
+ if ((hw->media_type == e1000_media_type_fiber) ||
+ (hw->media_type == e1000_media_type_internal_serdes)) {
+ reg_tarc0 &= ~(1 << 20);
+ }
+
+ /* Multiple read bit is reversed polarity */
+ reg_tctl = E1000_READ_REG(hw, TCTL);
+ reg_tarc1 = E1000_READ_REG(hw, TARC1);
+ if (reg_tctl & E1000_TCTL_MULR)
+ reg_tarc1 &= ~(1 << 28);
+ else
+ reg_tarc1 |= (1 << 28);
+
+ E1000_WRITE_REG(hw, TARC1, reg_tarc1);
+ break;
+ case e1000_ich8lan:
+ /* Reduce concurrent DMA requests to 3 from 4 */
+ if ((hw->revision_id < 3) ||
+ ((hw->device_id != E1000_DEV_ID_ICH8_IGP_M_AMT) &&
+ (hw->device_id != E1000_DEV_ID_ICH8_IGP_M)))
+ reg_tarc0 |= ((1 << 29)|(1 << 28));
+
+ reg_ctrl_ext = E1000_READ_REG(hw, CTRL_EXT);
+ reg_ctrl_ext |= (1 << 22);
+ E1000_WRITE_REG(hw, CTRL_EXT, reg_ctrl_ext);
+
+ /* workaround TX hang with TSO=on */
+ reg_tarc0 |= ((1 << 27)|(1 << 26)|(1 << 24)|(1 << 23));
+
+ /* Multiple read bit is reversed polarity */
+ reg_tctl = E1000_READ_REG(hw, TCTL);
+ reg_tarc1 = E1000_READ_REG(hw, TARC1);
+ if (reg_tctl & E1000_TCTL_MULR)
+ reg_tarc1 &= ~(1 << 28);
+ else
+ reg_tarc1 |= (1 << 28);
+
+ /* workaround TX hang with TSO=on */
+ reg_tarc1 |= ((1 << 30)|(1 << 26)|(1 << 24));
+
+ E1000_WRITE_REG(hw, TARC1, reg_tarc1);
+ break;
+ default:
+ break;
+ }
+
+ E1000_WRITE_REG(hw, TARC0, reg_tarc0);
+ }
+}
+
+/******************************************************************************
* Performs basic configuration of the adapter.
*
* hw - Struct containing variables accessed by shared code
@@ -749,14 +854,13 @@ e1000_init_hw(struct e1000_hw *hw)
DEBUGFUNC("e1000_init_hw");
/* force full DMA clock frequency for 10/100 on ICH8 A0-B0 */
- if (hw->mac_type == e1000_ich8lan) {
- reg_data = E1000_READ_REG(hw, TARC0);
- reg_data |= 0x30000000;
- E1000_WRITE_REG(hw, TARC0, reg_data);
-
- reg_data = E1000_READ_REG(hw, STATUS);
- reg_data &= ~0x80000000;
- E1000_WRITE_REG(hw, STATUS, reg_data);
+ if ((hw->mac_type == e1000_ich8lan) &&
+ ((hw->revision_id < 3) ||
+ ((hw->device_id != E1000_DEV_ID_ICH8_IGP_M_AMT) &&
+ (hw->device_id != E1000_DEV_ID_ICH8_IGP_M)))) {
+ reg_data = E1000_READ_REG(hw, STATUS);
+ reg_data &= ~0x80000000;
+ E1000_WRITE_REG(hw, STATUS, reg_data);
}
/* Initialize Identification LED */
@@ -769,6 +873,9 @@ e1000_init_hw(struct e1000_hw *hw)
/* Set the media type and TBI compatibility */
e1000_set_media_type(hw);
+ /* Must be called after e1000_set_media_type because media_type is used */
+ e1000_initialize_hardware_bits(hw);
+
/* Disabling VLAN filtering. */
DEBUGOUT("Initializing the IEEE VLAN\n");
/* VET hardcoded to standard value and VFTA removed in ICH8 LAN */
@@ -860,17 +967,6 @@ e1000_init_hw(struct e1000_hw *hw)
if (hw->mac_type > e1000_82544) {
ctrl = E1000_READ_REG(hw, TXDCTL);
ctrl = (ctrl & ~E1000_TXDCTL_WTHRESH) | E1000_TXDCTL_FULL_TX_DESC_WB;
- switch (hw->mac_type) {
- default:
- break;
- case e1000_82571:
- case e1000_82572:
- case e1000_82573:
- case e1000_ich8lan:
- case e1000_80003es2lan:
- ctrl |= E1000_TXDCTL_COUNT_DESC;
- break;
- }
E1000_WRITE_REG(hw, TXDCTL, ctrl);
}
@@ -908,8 +1004,6 @@ e1000_init_hw(struct e1000_hw *hw)
case e1000_ich8lan:
ctrl = E1000_READ_REG(hw, TXDCTL1);
ctrl = (ctrl & ~E1000_TXDCTL_WTHRESH) | E1000_TXDCTL_FULL_TX_DESC_WB;
- if (hw->mac_type >= e1000_82571)
- ctrl |= E1000_TXDCTL_COUNT_DESC;
E1000_WRITE_REG(hw, TXDCTL1, ctrl);
break;
}
@@ -1018,11 +1112,11 @@ e1000_setup_link(struct e1000_hw *hw)
* control setting, then the variable hw->fc will
* be initialized based on a value in the EEPROM.
*/
- if (hw->fc == e1000_fc_default) {
+ if (hw->fc == E1000_FC_DEFAULT) {
switch (hw->mac_type) {
case e1000_ich8lan:
case e1000_82573:
- hw->fc = e1000_fc_full;
+ hw->fc = E1000_FC_FULL;
break;
default:
ret_val = e1000_read_eeprom(hw, EEPROM_INIT_CONTROL2_REG,
@@ -1032,12 +1126,12 @@ e1000_setup_link(struct e1000_hw *hw)
return -E1000_ERR_EEPROM;
}
if ((eeprom_data & EEPROM_WORD0F_PAUSE_MASK) == 0)
- hw->fc = e1000_fc_none;
+ hw->fc = E1000_FC_NONE;
else if ((eeprom_data & EEPROM_WORD0F_PAUSE_MASK) ==
EEPROM_WORD0F_ASM_DIR)
- hw->fc = e1000_fc_tx_pause;
+ hw->fc = E1000_FC_TX_PAUSE;
else
- hw->fc = e1000_fc_full;
+ hw->fc = E1000_FC_FULL;
break;
}
}
@@ -1047,10 +1141,10 @@ e1000_setup_link(struct e1000_hw *hw)
* hub or switch with different Flow Control capabilities.
*/
if (hw->mac_type == e1000_82542_rev2_0)
- hw->fc &= (~e1000_fc_tx_pause);
+ hw->fc &= (~E1000_FC_TX_PAUSE);
if ((hw->mac_type < e1000_82543) && (hw->report_tx_early == 1))
- hw->fc &= (~e1000_fc_rx_pause);
+ hw->fc &= (~E1000_FC_RX_PAUSE);
hw->original_fc = hw->fc;
@@ -1102,7 +1196,7 @@ e1000_setup_link(struct e1000_hw *hw)
* ability to transmit pause frames in not enabled, then these
* registers will be set to 0.
*/
- if (!(hw->fc & e1000_fc_tx_pause)) {
+ if (!(hw->fc & E1000_FC_TX_PAUSE)) {
E1000_WRITE_REG(hw, FCRTL, 0);
E1000_WRITE_REG(hw, FCRTH, 0);
} else {
@@ -1149,11 +1243,11 @@ e1000_setup_fiber_serdes_link(struct e1000_hw *hw)
if (hw->mac_type == e1000_82571 || hw->mac_type == e1000_82572)
E1000_WRITE_REG(hw, SCTL, E1000_DISABLE_SERDES_LOOPBACK);
- /* On adapters with a MAC newer than 82544, SW Defineable pin 1 will be
+ /* On adapters with a MAC newer than 82544, SWDP 1 will be
* set when the optics detect a signal. On older adapters, it will be
* cleared when there is a signal. This applies to fiber media only.
- * If we're on serdes media, adjust the output amplitude to value set in
- * the EEPROM.
+ * If we're on serdes media, adjust the output amplitude to value
+ * set in the EEPROM.
*/
ctrl = E1000_READ_REG(hw, CTRL);
if (hw->media_type == e1000_media_type_fiber)
@@ -1189,11 +1283,11 @@ e1000_setup_fiber_serdes_link(struct e1000_hw *hw)
* 3: Both Rx and TX flow control (symmetric) are enabled.
*/
switch (hw->fc) {
- case e1000_fc_none:
+ case E1000_FC_NONE:
/* Flow control is completely disabled by a software over-ride. */
txcw = (E1000_TXCW_ANE | E1000_TXCW_FD);
break;
- case e1000_fc_rx_pause:
+ case E1000_FC_RX_PAUSE:
/* RX Flow control is enabled and TX Flow control is disabled by a
* software over-ride. Since there really isn't a way to advertise
* that we are capable of RX Pause ONLY, we will advertise that we
@@ -1202,13 +1296,13 @@ e1000_setup_fiber_serdes_link(struct e1000_hw *hw)
*/
txcw = (E1000_TXCW_ANE | E1000_TXCW_FD | E1000_TXCW_PAUSE_MASK);
break;
- case e1000_fc_tx_pause:
+ case E1000_FC_TX_PAUSE:
/* TX Flow control is enabled, and RX Flow control is disabled, by a
* software over-ride.
*/
txcw = (E1000_TXCW_ANE | E1000_TXCW_FD | E1000_TXCW_ASM_DIR);
break;
- case e1000_fc_full:
+ case E1000_FC_FULL:
/* Flow control (both RX and TX) is enabled by a software over-ride. */
txcw = (E1000_TXCW_ANE | E1000_TXCW_FD | E1000_TXCW_PAUSE_MASK);
break;
@@ -2124,13 +2218,13 @@ e1000_phy_setup_autoneg(struct e1000_hw *hw)
* in the EEPROM is used.
*/
switch (hw->fc) {
- case e1000_fc_none: /* 0 */
+ case E1000_FC_NONE: /* 0 */
/* Flow control (RX & TX) is completely disabled by a
* software over-ride.
*/
mii_autoneg_adv_reg &= ~(NWAY_AR_ASM_DIR | NWAY_AR_PAUSE);
break;
- case e1000_fc_rx_pause: /* 1 */
+ case E1000_FC_RX_PAUSE: /* 1 */
/* RX Flow control is enabled, and TX Flow control is
* disabled, by a software over-ride.
*/
@@ -2142,14 +2236,14 @@ e1000_phy_setup_autoneg(struct e1000_hw *hw)
*/
mii_autoneg_adv_reg |= (NWAY_AR_ASM_DIR | NWAY_AR_PAUSE);
break;
- case e1000_fc_tx_pause: /* 2 */
+ case E1000_FC_TX_PAUSE: /* 2 */
/* TX Flow control is enabled, and RX Flow control is
* disabled, by a software over-ride.
*/
mii_autoneg_adv_reg |= NWAY_AR_ASM_DIR;
mii_autoneg_adv_reg &= ~NWAY_AR_PAUSE;
break;
- case e1000_fc_full: /* 3 */
+ case E1000_FC_FULL: /* 3 */
/* Flow control (both RX and TX) is enabled by a software
* over-ride.
*/
@@ -2193,7 +2287,7 @@ e1000_phy_force_speed_duplex(struct e1000_hw *hw)
DEBUGFUNC("e1000_phy_force_speed_duplex");
/* Turn off Flow control if we are forcing speed and duplex. */
- hw->fc = e1000_fc_none;
+ hw->fc = E1000_FC_NONE;
DEBUGOUT1("hw->fc = %d\n", hw->fc);
@@ -2547,18 +2641,18 @@ e1000_force_mac_fc(struct e1000_hw *hw)
*/
switch (hw->fc) {
- case e1000_fc_none:
+ case E1000_FC_NONE:
ctrl &= (~(E1000_CTRL_TFCE | E1000_CTRL_RFCE));
break;
- case e1000_fc_rx_pause:
+ case E1000_FC_RX_PAUSE:
ctrl &= (~E1000_CTRL_TFCE);
ctrl |= E1000_CTRL_RFCE;
break;
- case e1000_fc_tx_pause:
+ case E1000_FC_TX_PAUSE:
ctrl &= (~E1000_CTRL_RFCE);
ctrl |= E1000_CTRL_TFCE;
break;
- case e1000_fc_full:
+ case E1000_FC_FULL:
ctrl |= (E1000_CTRL_TFCE | E1000_CTRL_RFCE);
break;
default:
@@ -2657,14 +2751,14 @@ e1000_config_fc_after_link_up(struct e1000_hw *hw)
* LOCAL DEVICE | LINK PARTNER
* PAUSE | ASM_DIR | PAUSE | ASM_DIR | NIC Resolution
*-------|---------|-------|---------|--------------------
- * 0 | 0 | DC | DC | e1000_fc_none
- * 0 | 1 | 0 | DC | e1000_fc_none
- * 0 | 1 | 1 | 0 | e1000_fc_none
- * 0 | 1 | 1 | 1 | e1000_fc_tx_pause
- * 1 | 0 | 0 | DC | e1000_fc_none
- * 1 | DC | 1 | DC | e1000_fc_full
- * 1 | 1 | 0 | 0 | e1000_fc_none
- * 1 | 1 | 0 | 1 | e1000_fc_rx_pause
+ * 0 | 0 | DC | DC | E1000_FC_NONE
+ * 0 | 1 | 0 | DC | E1000_FC_NONE
+ * 0 | 1 | 1 | 0 | E1000_FC_NONE
+ * 0 | 1 | 1 | 1 | E1000_FC_TX_PAUSE
+ * 1 | 0 | 0 | DC | E1000_FC_NONE
+ * 1 | DC | 1 | DC | E1000_FC_FULL
+ * 1 | 1 | 0 | 0 | E1000_FC_NONE
+ * 1 | 1 | 0 | 1 | E1000_FC_RX_PAUSE
*
*/
/* Are both PAUSE bits set to 1? If so, this implies
@@ -2676,7 +2770,7 @@ e1000_config_fc_after_link_up(struct e1000_hw *hw)
* LOCAL DEVICE | LINK PARTNER
* PAUSE | ASM_DIR | PAUSE | ASM_DIR | Result
*-------|---------|-------|---------|--------------------
- * 1 | DC | 1 | DC | e1000_fc_full
+ * 1 | DC | 1 | DC | E1000_FC_FULL
*
*/
if ((mii_nway_adv_reg & NWAY_AR_PAUSE) &&
@@ -2687,11 +2781,11 @@ e1000_config_fc_after_link_up(struct e1000_hw *hw)
* ONLY. Hence, we must now check to see if we need to
* turn OFF the TRANSMISSION of PAUSE frames.
*/
- if (hw->original_fc == e1000_fc_full) {
- hw->fc = e1000_fc_full;
+ if (hw->original_fc == E1000_FC_FULL) {
+ hw->fc = E1000_FC_FULL;
DEBUGOUT("Flow Control = FULL.\n");
} else {
- hw->fc = e1000_fc_rx_pause;
+ hw->fc = E1000_FC_RX_PAUSE;
DEBUGOUT("Flow Control = RX PAUSE frames only.\n");
}
}
@@ -2700,14 +2794,14 @@ e1000_config_fc_after_link_up(struct e1000_hw *hw)
* LOCAL DEVICE | LINK PARTNER
* PAUSE | ASM_DIR | PAUSE | ASM_DIR | Result
*-------|---------|-------|---------|--------------------
- * 0 | 1 | 1 | 1 | e1000_fc_tx_pause
+ * 0 | 1 | 1 | 1 | E1000_FC_TX_PAUSE
*
*/
else if (!(mii_nway_adv_reg & NWAY_AR_PAUSE) &&
(mii_nway_adv_reg & NWAY_AR_ASM_DIR) &&
(mii_nway_lp_ability_reg & NWAY_LPAR_PAUSE) &&
(mii_nway_lp_ability_reg & NWAY_LPAR_ASM_DIR)) {
- hw->fc = e1000_fc_tx_pause;
+ hw->fc = E1000_FC_TX_PAUSE;
DEBUGOUT("Flow Control = TX PAUSE frames only.\n");
}
/* For transmitting PAUSE frames ONLY.
@@ -2715,14 +2809,14 @@ e1000_config_fc_after_link_up(struct e1000_hw *hw)
* LOCAL DEVICE | LINK PARTNER
* PAUSE | ASM_DIR | PAUSE | ASM_DIR | Result
*-------|---------|-------|---------|--------------------
- * 1 | 1 | 0 | 1 | e1000_fc_rx_pause
+ * 1 | 1 | 0 | 1 | E1000_FC_RX_PAUSE
*
*/
else if ((mii_nway_adv_reg & NWAY_AR_PAUSE) &&
(mii_nway_adv_reg & NWAY_AR_ASM_DIR) &&
!(mii_nway_lp_ability_reg & NWAY_LPAR_PAUSE) &&
(mii_nway_lp_ability_reg & NWAY_LPAR_ASM_DIR)) {
- hw->fc = e1000_fc_rx_pause;
+ hw->fc = E1000_FC_RX_PAUSE;
DEBUGOUT("Flow Control = RX PAUSE frames only.\n");
}
/* Per the IEEE spec, at this point flow control should be
@@ -2745,13 +2839,13 @@ e1000_config_fc_after_link_up(struct e1000_hw *hw)
* be asked to delay transmission of packets than asking
* our link partner to pause transmission of frames.
*/
- else if ((hw->original_fc == e1000_fc_none ||
- hw->original_fc == e1000_fc_tx_pause) ||
+ else if ((hw->original_fc == E1000_FC_NONE ||
+ hw->original_fc == E1000_FC_TX_PAUSE) ||
hw->fc_strict_ieee) {
- hw->fc = e1000_fc_none;
+ hw->fc = E1000_FC_NONE;
DEBUGOUT("Flow Control = NONE.\n");
} else {
- hw->fc = e1000_fc_rx_pause;
+ hw->fc = E1000_FC_RX_PAUSE;
DEBUGOUT("Flow Control = RX PAUSE frames only.\n");
}
@@ -2766,7 +2860,7 @@ e1000_config_fc_after_link_up(struct e1000_hw *hw)
}
if (duplex == HALF_DUPLEX)
- hw->fc = e1000_fc_none;
+ hw->fc = E1000_FC_NONE;
/* Now we call a subroutine to actually force the MAC
* controller to use the correct flow control settings.
@@ -3417,9 +3511,8 @@ e1000_read_phy_reg(struct e1000_hw *hw,
return ret_val;
}
-int32_t
-e1000_read_phy_reg_ex(struct e1000_hw *hw,
- uint32_t reg_addr,
+static int32_t
+e1000_read_phy_reg_ex(struct e1000_hw *hw, uint32_t reg_addr,
uint16_t *phy_data)
{
uint32_t i;
@@ -3499,8 +3592,7 @@ e1000_read_phy_reg_ex(struct e1000_hw *hw,
* data - data to write to the PHY
******************************************************************************/
int32_t
-e1000_write_phy_reg(struct e1000_hw *hw,
- uint32_t reg_addr,
+e1000_write_phy_reg(struct e1000_hw *hw, uint32_t reg_addr,
uint16_t phy_data)
{
uint32_t ret_val;
@@ -3557,10 +3649,9 @@ e1000_write_phy_reg(struct e1000_hw *hw,
return ret_val;
}
-int32_t
-e1000_write_phy_reg_ex(struct e1000_hw *hw,
- uint32_t reg_addr,
- uint16_t phy_data)
+static int32_t
+e1000_write_phy_reg_ex(struct e1000_hw *hw, uint32_t reg_addr,
+ uint16_t phy_data)
{
uint32_t i;
uint32_t mdic = 0;
@@ -3711,7 +3802,7 @@ e1000_phy_hw_reset(struct e1000_hw *hw)
swfw = E1000_SWFW_PHY0_SM;
}
if (e1000_swfw_sync_acquire(hw, swfw)) {
- e1000_release_software_semaphore(hw);
+ DEBUGOUT("Unable to acquire swfw sync\n");
return -E1000_ERR_SWFW_SYNC;
}
/* Read the device control register and assert the E1000_CTRL_PHY_RST
@@ -3734,6 +3825,7 @@ e1000_phy_hw_reset(struct e1000_hw *hw)
if (hw->mac_type >= e1000_82571)
mdelay(10);
+
e1000_swfw_sync_release(hw, swfw);
} else {
/* Read the Extended Device Control Register, assert the PHY_RESET_DIR
@@ -3792,15 +3884,14 @@ e1000_phy_reset(struct e1000_hw *hw)
if (ret_val)
return E1000_SUCCESS;
- switch (hw->mac_type) {
- case e1000_82541_rev_2:
- case e1000_82571:
- case e1000_82572:
- case e1000_ich8lan:
+ switch (hw->phy_type) {
+ case e1000_phy_igp:
+ case e1000_phy_igp_2:
+ case e1000_phy_igp_3:
+ case e1000_phy_ife:
ret_val = e1000_phy_hw_reset(hw);
if (ret_val)
return ret_val;
-
break;
default:
ret_val = e1000_read_phy_reg(hw, PHY_CTRL, &phy_data);
@@ -3936,7 +4027,7 @@ e1000_kumeran_lock_loss_workaround(struct e1000_hw *hw)
*
* hw - Struct containing variables accessed by shared code
******************************************************************************/
-int32_t
+static int32_t
e1000_detect_gig_phy(struct e1000_hw *hw)
{
int32_t phy_init_status, ret_val;
@@ -3945,6 +4036,9 @@ e1000_detect_gig_phy(struct e1000_hw *hw)
DEBUGFUNC("e1000_detect_gig_phy");
+ if (hw->phy_id != 0)
+ return E1000_SUCCESS;
+
/* The 82571 firmware may still be configuring the PHY. In this
* case, we cannot access the PHY until the configuration is done. So
* we explicitly set the PHY values. */
@@ -4061,7 +4155,8 @@ e1000_phy_igp_get_info(struct e1000_hw *hw,
struct e1000_phy_info *phy_info)
{
int32_t ret_val;
- uint16_t phy_data, polarity, min_length, max_length, average;
+ uint16_t phy_data, min_length, max_length, average;
+ e1000_rev_polarity polarity;
DEBUGFUNC("e1000_phy_igp_get_info");
@@ -4086,8 +4181,8 @@ e1000_phy_igp_get_info(struct e1000_hw *hw,
if (ret_val)
return ret_val;
- phy_info->mdix_mode = (phy_data & IGP01E1000_PSSR_MDIX) >>
- IGP01E1000_PSSR_MDIX_SHIFT;
+ phy_info->mdix_mode = (e1000_auto_x_mode)((phy_data & IGP01E1000_PSSR_MDIX) >>
+ IGP01E1000_PSSR_MDIX_SHIFT);
if ((phy_data & IGP01E1000_PSSR_SPEED_MASK) ==
IGP01E1000_PSSR_SPEED_1000MBPS) {
@@ -4096,10 +4191,12 @@ e1000_phy_igp_get_info(struct e1000_hw *hw,
if (ret_val)
return ret_val;
- phy_info->local_rx = (phy_data & SR_1000T_LOCAL_RX_STATUS) >>
- SR_1000T_LOCAL_RX_STATUS_SHIFT;
- phy_info->remote_rx = (phy_data & SR_1000T_REMOTE_RX_STATUS) >>
- SR_1000T_REMOTE_RX_STATUS_SHIFT;
+ phy_info->local_rx = ((phy_data & SR_1000T_LOCAL_RX_STATUS) >>
+ SR_1000T_LOCAL_RX_STATUS_SHIFT) ?
+ e1000_1000t_rx_status_ok : e1000_1000t_rx_status_not_ok;
+ phy_info->remote_rx = ((phy_data & SR_1000T_REMOTE_RX_STATUS) >>
+ SR_1000T_REMOTE_RX_STATUS_SHIFT) ?
+ e1000_1000t_rx_status_ok : e1000_1000t_rx_status_not_ok;
/* Get cable length */
ret_val = e1000_get_cable_length(hw, &min_length, &max_length);
@@ -4135,7 +4232,8 @@ e1000_phy_ife_get_info(struct e1000_hw *hw,
struct e1000_phy_info *phy_info)
{
int32_t ret_val;
- uint16_t phy_data, polarity;
+ uint16_t phy_data;
+ e1000_rev_polarity polarity;
DEBUGFUNC("e1000_phy_ife_get_info");
@@ -4146,8 +4244,9 @@ e1000_phy_ife_get_info(struct e1000_hw *hw,
if (ret_val)
return ret_val;
phy_info->polarity_correction =
- (phy_data & IFE_PSC_AUTO_POLARITY_DISABLE) >>
- IFE_PSC_AUTO_POLARITY_DISABLE_SHIFT;
+ ((phy_data & IFE_PSC_AUTO_POLARITY_DISABLE) >>
+ IFE_PSC_AUTO_POLARITY_DISABLE_SHIFT) ?
+ e1000_polarity_reversal_disabled : e1000_polarity_reversal_enabled;
if (phy_info->polarity_correction == e1000_polarity_reversal_enabled) {
ret_val = e1000_check_polarity(hw, &polarity);
@@ -4155,8 +4254,9 @@ e1000_phy_ife_get_info(struct e1000_hw *hw,
return ret_val;
} else {
/* Polarity is forced. */
- polarity = (phy_data & IFE_PSC_FORCE_POLARITY) >>
- IFE_PSC_FORCE_POLARITY_SHIFT;
+ polarity = ((phy_data & IFE_PSC_FORCE_POLARITY) >>
+ IFE_PSC_FORCE_POLARITY_SHIFT) ?
+ e1000_rev_polarity_reversed : e1000_rev_polarity_normal;
}
phy_info->cable_polarity = polarity;
@@ -4164,9 +4264,9 @@ e1000_phy_ife_get_info(struct e1000_hw *hw,
if (ret_val)
return ret_val;
- phy_info->mdix_mode =
- (phy_data & (IFE_PMC_AUTO_MDIX | IFE_PMC_FORCE_MDIX)) >>
- IFE_PMC_MDIX_MODE_SHIFT;
+ phy_info->mdix_mode = (e1000_auto_x_mode)
+ ((phy_data & (IFE_PMC_AUTO_MDIX | IFE_PMC_FORCE_MDIX)) >>
+ IFE_PMC_MDIX_MODE_SHIFT);
return E1000_SUCCESS;
}
@@ -4182,7 +4282,8 @@ e1000_phy_m88_get_info(struct e1000_hw *hw,
struct e1000_phy_info *phy_info)
{
int32_t ret_val;
- uint16_t phy_data, polarity;
+ uint16_t phy_data;
+ e1000_rev_polarity polarity;
DEBUGFUNC("e1000_phy_m88_get_info");
@@ -4195,11 +4296,14 @@ e1000_phy_m88_get_info(struct e1000_hw *hw,
return ret_val;
phy_info->extended_10bt_distance =
- (phy_data & M88E1000_PSCR_10BT_EXT_DIST_ENABLE) >>
- M88E1000_PSCR_10BT_EXT_DIST_ENABLE_SHIFT;
+ ((phy_data & M88E1000_PSCR_10BT_EXT_DIST_ENABLE) >>
+ M88E1000_PSCR_10BT_EXT_DIST_ENABLE_SHIFT) ?
+ e1000_10bt_ext_dist_enable_lower : e1000_10bt_ext_dist_enable_normal;
+
phy_info->polarity_correction =
- (phy_data & M88E1000_PSCR_POLARITY_REVERSAL) >>
- M88E1000_PSCR_POLARITY_REVERSAL_SHIFT;
+ ((phy_data & M88E1000_PSCR_POLARITY_REVERSAL) >>
+ M88E1000_PSCR_POLARITY_REVERSAL_SHIFT) ?
+ e1000_polarity_reversal_disabled : e1000_polarity_reversal_enabled;
/* Check polarity status */
ret_val = e1000_check_polarity(hw, &polarity);
@@ -4211,15 +4315,15 @@ e1000_phy_m88_get_info(struct e1000_hw *hw,
if (ret_val)
return ret_val;
- phy_info->mdix_mode = (phy_data & M88E1000_PSSR_MDIX) >>
- M88E1000_PSSR_MDIX_SHIFT;
+ phy_info->mdix_mode = (e1000_auto_x_mode)((phy_data & M88E1000_PSSR_MDIX) >>
+ M88E1000_PSSR_MDIX_SHIFT);
if ((phy_data & M88E1000_PSSR_SPEED) == M88E1000_PSSR_1000MBS) {
/* Cable Length Estimation and Local/Remote Receiver Information
* are only valid at 1000 Mbps.
*/
if (hw->phy_type != e1000_phy_gg82563) {
- phy_info->cable_length = ((phy_data & M88E1000_PSSR_CABLE_LENGTH) >>
+ phy_info->cable_length = (e1000_cable_length)((phy_data & M88E1000_PSSR_CABLE_LENGTH) >>
M88E1000_PSSR_CABLE_LENGTH_SHIFT);
} else {
ret_val = e1000_read_phy_reg(hw, GG82563_PHY_DSP_DISTANCE,
@@ -4227,18 +4331,20 @@ e1000_phy_m88_get_info(struct e1000_hw *hw,
if (ret_val)
return ret_val;
- phy_info->cable_length = phy_data & GG82563_DSPD_CABLE_LENGTH;
+ phy_info->cable_length = (e1000_cable_length)(phy_data & GG82563_DSPD_CABLE_LENGTH);
}
ret_val = e1000_read_phy_reg(hw, PHY_1000T_STATUS, &phy_data);
if (ret_val)
return ret_val;
- phy_info->local_rx = (phy_data & SR_1000T_LOCAL_RX_STATUS) >>
- SR_1000T_LOCAL_RX_STATUS_SHIFT;
+ phy_info->local_rx = ((phy_data & SR_1000T_LOCAL_RX_STATUS) >>
+ SR_1000T_LOCAL_RX_STATUS_SHIFT) ?
+ e1000_1000t_rx_status_ok : e1000_1000t_rx_status_not_ok;
+ phy_info->remote_rx = ((phy_data & SR_1000T_REMOTE_RX_STATUS) >>
+ SR_1000T_REMOTE_RX_STATUS_SHIFT) ?
+ e1000_1000t_rx_status_ok : e1000_1000t_rx_status_not_ok;
- phy_info->remote_rx = (phy_data & SR_1000T_REMOTE_RX_STATUS) >>
- SR_1000T_REMOTE_RX_STATUS_SHIFT;
}
return E1000_SUCCESS;
@@ -4441,7 +4547,7 @@ e1000_init_eeprom_params(struct e1000_hw *hw)
eeprom->use_eewr = FALSE;
break;
case e1000_ich8lan:
- {
+ {
int32_t i = 0;
uint32_t flash_size = E1000_READ_ICH8_REG(hw, ICH8_FLASH_GFPREG);
@@ -4468,7 +4574,7 @@ e1000_init_eeprom_params(struct e1000_hw *hw)
hw->flash_bank_size /= 2 * sizeof(uint16_t);
break;
- }
+ }
default:
break;
}
@@ -4800,7 +4906,7 @@ e1000_release_eeprom(struct e1000_hw *hw)
*
* hw - Struct containing variables accessed by shared code
*****************************************************************************/
-int32_t
+static int32_t
e1000_spi_eeprom_ready(struct e1000_hw *hw)
{
uint16_t retry_count = 0;
@@ -4854,44 +4960,43 @@ e1000_read_eeprom(struct e1000_hw *hw,
{
struct e1000_eeprom_info *eeprom = &hw->eeprom;
uint32_t i = 0;
- int32_t ret_val;
DEBUGFUNC("e1000_read_eeprom");
+ /* If eeprom is not yet detected, do so now */
+ if (eeprom->word_size == 0)
+ e1000_init_eeprom_params(hw);
+
/* A check for invalid values: offset too large, too many words, and not
* enough words.
*/
if ((offset >= eeprom->word_size) || (words > eeprom->word_size - offset) ||
(words == 0)) {
- DEBUGOUT("\"words\" parameter out of bounds\n");
+ DEBUGOUT2("\"words\" parameter out of bounds. Words = %d, size = %d\n", offset, eeprom->word_size);
return -E1000_ERR_EEPROM;
}
- /* FLASH reads without acquiring the semaphore are safe */
+ /* EEPROM's that don't use EERD to read require us to bit-bang the SPI
+ * directly. In this case, we need to acquire the EEPROM so that
+ * FW or other port software does not interrupt.
+ */
if (e1000_is_onboard_nvm_eeprom(hw) == TRUE &&
hw->eeprom.use_eerd == FALSE) {
- switch (hw->mac_type) {
- case e1000_80003es2lan:
- break;
- default:
- /* Prepare the EEPROM for reading */
- if (e1000_acquire_eeprom(hw) != E1000_SUCCESS)
- return -E1000_ERR_EEPROM;
- break;
- }
+ /* Prepare the EEPROM for bit-bang reading */
+ if (e1000_acquire_eeprom(hw) != E1000_SUCCESS)
+ return -E1000_ERR_EEPROM;
}
- if (eeprom->use_eerd == TRUE) {
- ret_val = e1000_read_eeprom_eerd(hw, offset, words, data);
- if ((e1000_is_onboard_nvm_eeprom(hw) == TRUE) ||
- (hw->mac_type != e1000_82573))
- e1000_release_eeprom(hw);
- return ret_val;
- }
+ /* Eerd register EEPROM access requires no eeprom aquire/release */
+ if (eeprom->use_eerd == TRUE)
+ return e1000_read_eeprom_eerd(hw, offset, words, data);
+ /* ICH EEPROM access is done via the ICH flash controller */
if (eeprom->type == e1000_eeprom_ich8)
return e1000_read_eeprom_ich8(hw, offset, words, data);
+ /* Set up the SPI or Microwire EEPROM for bit-bang reading. We have
+ * acquired the EEPROM at this point, so any returns should relase it */
if (eeprom->type == e1000_eeprom_spi) {
uint16_t word_in;
uint8_t read_opcode = EEPROM_READ_OPCODE_SPI;
@@ -5206,6 +5311,10 @@ e1000_write_eeprom(struct e1000_hw *hw,
DEBUGFUNC("e1000_write_eeprom");
+ /* If eeprom is not yet detected, do so now */
+ if (eeprom->word_size == 0)
+ e1000_init_eeprom_params(hw);
+
/* A check for invalid values: offset too large, too many words, and not
* enough words.
*/
@@ -5248,7 +5357,7 @@ e1000_write_eeprom(struct e1000_hw *hw,
* data - pointer to array of 8 bit words to be written to the EEPROM
*
*****************************************************************************/
-int32_t
+static int32_t
e1000_write_eeprom_spi(struct e1000_hw *hw,
uint16_t offset,
uint16_t words,
@@ -5314,7 +5423,7 @@ e1000_write_eeprom_spi(struct e1000_hw *hw,
* data - pointer to array of 16 bit words to be written to the EEPROM
*
*****************************************************************************/
-int32_t
+static int32_t
e1000_write_eeprom_microwire(struct e1000_hw *hw,
uint16_t offset,
uint16_t words,
@@ -5411,10 +5520,8 @@ e1000_commit_shadow_ram(struct e1000_hw *hw)
int32_t error = E1000_SUCCESS;
uint32_t old_bank_offset = 0;
uint32_t new_bank_offset = 0;
- uint32_t sector_retries = 0;
uint8_t low_byte = 0;
uint8_t high_byte = 0;
- uint8_t temp_byte = 0;
boolean_t sector_write_failed = FALSE;
if (hw->mac_type == e1000_82573) {
@@ -5467,41 +5574,46 @@ e1000_commit_shadow_ram(struct e1000_hw *hw)
e1000_erase_ich8_4k_segment(hw, 0);
}
- do {
- sector_write_failed = FALSE;
- /* Loop for every byte in the shadow RAM,
- * which is in units of words. */
- for (i = 0; i < E1000_SHADOW_RAM_WORDS; i++) {
- /* Determine whether to write the value stored
- * in the other NVM bank or a modified value stored
- * in the shadow RAM */
- if (hw->eeprom_shadow_ram[i].modified == TRUE) {
- low_byte = (uint8_t)hw->eeprom_shadow_ram[i].eeprom_word;
- e1000_read_ich8_byte(hw, (i << 1) + old_bank_offset,
- &temp_byte);
- udelay(100);
- error = e1000_verify_write_ich8_byte(hw,
- (i << 1) + new_bank_offset,
- low_byte);
- if (error != E1000_SUCCESS)
- sector_write_failed = TRUE;
+ sector_write_failed = FALSE;
+ /* Loop for every byte in the shadow RAM,
+ * which is in units of words. */
+ for (i = 0; i < E1000_SHADOW_RAM_WORDS; i++) {
+ /* Determine whether to write the value stored
+ * in the other NVM bank or a modified value stored
+ * in the shadow RAM */
+ if (hw->eeprom_shadow_ram[i].modified == TRUE) {
+ low_byte = (uint8_t)hw->eeprom_shadow_ram[i].eeprom_word;
+ udelay(100);
+ error = e1000_verify_write_ich8_byte(hw,
+ (i << 1) + new_bank_offset, low_byte);
+
+ if (error != E1000_SUCCESS)
+ sector_write_failed = TRUE;
+ else {
high_byte =
(uint8_t)(hw->eeprom_shadow_ram[i].eeprom_word >> 8);
- e1000_read_ich8_byte(hw, (i << 1) + old_bank_offset + 1,
- &temp_byte);
- udelay(100);
- } else {
- e1000_read_ich8_byte(hw, (i << 1) + old_bank_offset,
- &low_byte);
udelay(100);
- error = e1000_verify_write_ich8_byte(hw,
- (i << 1) + new_bank_offset, low_byte);
- if (error != E1000_SUCCESS)
- sector_write_failed = TRUE;
+ }
+ } else {
+ e1000_read_ich8_byte(hw, (i << 1) + old_bank_offset,
+ &low_byte);
+ udelay(100);
+ error = e1000_verify_write_ich8_byte(hw,
+ (i << 1) + new_bank_offset, low_byte);
+
+ if (error != E1000_SUCCESS)
+ sector_write_failed = TRUE;
+ else {
e1000_read_ich8_byte(hw, (i << 1) + old_bank_offset + 1,
&high_byte);
+ udelay(100);
}
+ }
+ /* If the write of the low byte was successful, go ahread and
+ * write the high byte while checking to make sure that if it
+ * is the signature byte, then it is handled properly */
+ if (sector_write_failed == FALSE) {
/* If the word is 0x13, then make sure the signature bits
* (15:14) are 11b until the commit has completed.
* This will allow us to write 10b which indicates the
@@ -5512,45 +5624,45 @@ e1000_commit_shadow_ram(struct e1000_hw *hw)
high_byte = E1000_ICH8_NVM_SIG_MASK | high_byte;
error = e1000_verify_write_ich8_byte(hw,
- (i << 1) + new_bank_offset + 1, high_byte);
+ (i << 1) + new_bank_offset + 1, high_byte);
if (error != E1000_SUCCESS)
sector_write_failed = TRUE;
- if (sector_write_failed == FALSE) {
- /* Clear the now not used entry in the cache */
- hw->eeprom_shadow_ram[i].modified = FALSE;
- hw->eeprom_shadow_ram[i].eeprom_word = 0xFFFF;
- }
+ } else {
+ /* If the write failed then break from the loop and
+ * return an error */
+ break;
}
+ }
- /* Don't bother writing the segment valid bits if sector
- * programming failed. */
- if (sector_write_failed == FALSE) {
- /* Finally validate the new segment by setting bit 15:14
- * to 10b in word 0x13 , this can be done without an
- * erase as well since these bits are 11 to start with
- * and we need to change bit 14 to 0b */
- e1000_read_ich8_byte(hw,
- E1000_ICH8_NVM_SIG_WORD * 2 + 1 + new_bank_offset,
- &high_byte);
- high_byte &= 0xBF;
+ /* Don't bother writing the segment valid bits if sector
+ * programming failed. */
+ if (sector_write_failed == FALSE) {
+ /* Finally validate the new segment by setting bit 15:14
+ * to 10b in word 0x13 , this can be done without an
+ * erase as well since these bits are 11 to start with
+ * and we need to change bit 14 to 0b */
+ e1000_read_ich8_byte(hw,
+ E1000_ICH8_NVM_SIG_WORD * 2 + 1 + new_bank_offset,
+ &high_byte);
+ high_byte &= 0xBF;
+ error = e1000_verify_write_ich8_byte(hw,
+ E1000_ICH8_NVM_SIG_WORD * 2 + 1 + new_bank_offset, high_byte);
+ /* And invalidate the previously valid segment by setting
+ * its signature word (0x13) high_byte to 0b. This can be
+ * done without an erase because flash erase sets all bits
+ * to 1's. We can write 1's to 0's without an erase */
+ if (error == E1000_SUCCESS) {
error = e1000_verify_write_ich8_byte(hw,
- E1000_ICH8_NVM_SIG_WORD * 2 + 1 + new_bank_offset,
- high_byte);
- if (error != E1000_SUCCESS)
- sector_write_failed = TRUE;
+ E1000_ICH8_NVM_SIG_WORD * 2 + 1 + old_bank_offset, 0);
+ }
- /* And invalidate the previously valid segment by setting
- * its signature word (0x13) high_byte to 0b. This can be
- * done without an erase because flash erase sets all bits
- * to 1's. We can write 1's to 0's without an erase */
- error = e1000_verify_write_ich8_byte(hw,
- E1000_ICH8_NVM_SIG_WORD * 2 + 1 + old_bank_offset,
- 0);
- if (error != E1000_SUCCESS)
- sector_write_failed = TRUE;
+ /* Clear the now not used entry in the cache */
+ for (i = 0; i < E1000_SHADOW_RAM_WORDS; i++) {
+ hw->eeprom_shadow_ram[i].modified = FALSE;
+ hw->eeprom_shadow_ram[i].eeprom_word = 0xFFFF;
}
- } while (++sector_retries < 10 && sector_write_failed == TRUE);
+ }
}
return error;
@@ -5640,99 +5752,6 @@ e1000_init_rx_addrs(struct e1000_hw *hw)
}
/******************************************************************************
- * Updates the MAC's list of multicast addresses.
- *
- * hw - Struct containing variables accessed by shared code
- * mc_addr_list - the list of new multicast addresses
- * mc_addr_count - number of addresses
- * pad - number of bytes between addresses in the list
- * rar_used_count - offset where to start adding mc addresses into the RAR's
- *
- * The given list replaces any existing list. Clears the last 15 receive
- * address registers and the multicast table. Uses receive address registers
- * for the first 15 multicast addresses, and hashes the rest into the
- * multicast table.
- *****************************************************************************/
-#if 0
-void
-e1000_mc_addr_list_update(struct e1000_hw *hw,
- uint8_t *mc_addr_list,
- uint32_t mc_addr_count,
- uint32_t pad,
- uint32_t rar_used_count)
-{
- uint32_t hash_value;
- uint32_t i;
- uint32_t num_rar_entry;
- uint32_t num_mta_entry;
-
- DEBUGFUNC("e1000_mc_addr_list_update");
-
- /* Set the new number of MC addresses that we are being requested to use. */
- hw->num_mc_addrs = mc_addr_count;
-
- /* Clear RAR[1-15] */
- DEBUGOUT(" Clearing RAR[1-15]\n");
- num_rar_entry = E1000_RAR_ENTRIES;
- if (hw->mac_type == e1000_ich8lan)
- num_rar_entry = E1000_RAR_ENTRIES_ICH8LAN;
- /* Reserve a spot for the Locally Administered Address to work around
- * an 82571 issue in which a reset on one port will reload the MAC on
- * the other port. */
- if ((hw->mac_type == e1000_82571) && (hw->laa_is_present == TRUE))
- num_rar_entry -= 1;
-
- for (i = rar_used_count; i < num_rar_entry; i++) {
- E1000_WRITE_REG_ARRAY(hw, RA, (i << 1), 0);
- E1000_WRITE_FLUSH(hw);
- E1000_WRITE_REG_ARRAY(hw, RA, ((i << 1) + 1), 0);
- E1000_WRITE_FLUSH(hw);
- }
-
- /* Clear the MTA */
- DEBUGOUT(" Clearing MTA\n");
- num_mta_entry = E1000_NUM_MTA_REGISTERS;
- if (hw->mac_type == e1000_ich8lan)
- num_mta_entry = E1000_NUM_MTA_REGISTERS_ICH8LAN;
- for (i = 0; i < num_mta_entry; i++) {
- E1000_WRITE_REG_ARRAY(hw, MTA, i, 0);
- E1000_WRITE_FLUSH(hw);
- }
-
- /* Add the new addresses */
- for (i = 0; i < mc_addr_count; i++) {
- DEBUGOUT(" Adding the multicast addresses:\n");
- DEBUGOUT7(" MC Addr #%d =%.2X %.2X %.2X %.2X %.2X %.2X\n", i,
- mc_addr_list[i * (ETH_LENGTH_OF_ADDRESS + pad)],
- mc_addr_list[i * (ETH_LENGTH_OF_ADDRESS + pad) + 1],
- mc_addr_list[i * (ETH_LENGTH_OF_ADDRESS + pad) + 2],
- mc_addr_list[i * (ETH_LENGTH_OF_ADDRESS + pad) + 3],
- mc_addr_list[i * (ETH_LENGTH_OF_ADDRESS + pad) + 4],
- mc_addr_list[i * (ETH_LENGTH_OF_ADDRESS + pad) + 5]);
-
- hash_value = e1000_hash_mc_addr(hw,
- mc_addr_list +
- (i * (ETH_LENGTH_OF_ADDRESS + pad)));
-
- DEBUGOUT1(" Hash value = 0x%03X\n", hash_value);
-
- /* Place this multicast address in the RAR if there is room, *
- * else put it in the MTA
- */
- if (rar_used_count < num_rar_entry) {
- e1000_rar_set(hw,
- mc_addr_list + (i * (ETH_LENGTH_OF_ADDRESS + pad)),
- rar_used_count);
- rar_used_count++;
- } else {
- e1000_mta_set(hw, hash_value);
- }
- }
- DEBUGOUT("MC Update Complete\n");
-}
-#endif /* 0 */
-
-/******************************************************************************
* Hashes an address to determine its location in the multicast table
*
* hw - Struct containing variables accessed by shared code
@@ -6290,7 +6309,7 @@ e1000_led_off(struct e1000_hw *hw)
*
* hw - Struct containing variables accessed by shared code
*****************************************************************************/
-void
+static void
e1000_clear_hw_cntrs(struct e1000_hw *hw)
{
volatile uint32_t temp;
@@ -6539,6 +6558,8 @@ e1000_tbi_adjust_stats(struct e1000_hw *hw,
void
e1000_get_bus_info(struct e1000_hw *hw)
{
+ int32_t ret_val;
+ uint16_t pci_ex_link_status;
uint32_t status;
switch (hw->mac_type) {
@@ -6548,18 +6569,25 @@ e1000_get_bus_info(struct e1000_hw *hw)
hw->bus_speed = e1000_bus_speed_unknown;
hw->bus_width = e1000_bus_width_unknown;
break;
+ case e1000_82571:
case e1000_82572:
case e1000_82573:
+ case e1000_80003es2lan:
hw->bus_type = e1000_bus_type_pci_express;
hw->bus_speed = e1000_bus_speed_2500;
- hw->bus_width = e1000_bus_width_pciex_1;
+ ret_val = e1000_read_pcie_cap_reg(hw,
+ PCI_EX_LINK_STATUS,
+ &pci_ex_link_status);
+ if (ret_val)
+ hw->bus_width = e1000_bus_width_unknown;
+ else
+ hw->bus_width = (pci_ex_link_status & PCI_EX_LINK_WIDTH_MASK) >>
+ PCI_EX_LINK_WIDTH_SHIFT;
break;
- case e1000_82571:
case e1000_ich8lan:
- case e1000_80003es2lan:
hw->bus_type = e1000_bus_type_pci_express;
hw->bus_speed = e1000_bus_speed_2500;
- hw->bus_width = e1000_bus_width_pciex_4;
+ hw->bus_width = e1000_bus_width_pciex_1;
break;
default:
status = E1000_READ_REG(hw, STATUS);
@@ -6593,25 +6621,6 @@ e1000_get_bus_info(struct e1000_hw *hw)
break;
}
}
-/******************************************************************************
- * Reads a value from one of the devices registers using port I/O (as opposed
- * memory mapped I/O). Only 82544 and newer devices support port I/O.
- *
- * hw - Struct containing variables accessed by shared code
- * offset - offset to read from
- *****************************************************************************/
-#if 0
-uint32_t
-e1000_read_reg_io(struct e1000_hw *hw,
- uint32_t offset)
-{
- unsigned long io_addr = hw->io_base;
- unsigned long io_data = hw->io_base + 4;
-
- e1000_io_write(hw, io_addr, offset);
- return e1000_io_read(hw, io_data);
-}
-#endif /* 0 */
/******************************************************************************
* Writes a value to one of the devices registers using port I/O (as opposed to
@@ -6633,7 +6642,6 @@ e1000_write_reg_io(struct e1000_hw *hw,
e1000_io_write(hw, io_data, value);
}
-
/******************************************************************************
* Estimates the cable length.
*
@@ -6842,7 +6850,7 @@ e1000_get_cable_length(struct e1000_hw *hw,
*****************************************************************************/
static int32_t
e1000_check_polarity(struct e1000_hw *hw,
- uint16_t *polarity)
+ e1000_rev_polarity *polarity)
{
int32_t ret_val;
uint16_t phy_data;
@@ -6856,8 +6864,10 @@ e1000_check_polarity(struct e1000_hw *hw,
&phy_data);
if (ret_val)
return ret_val;
- *polarity = (phy_data & M88E1000_PSSR_REV_POLARITY) >>
- M88E1000_PSSR_REV_POLARITY_SHIFT;
+ *polarity = ((phy_data & M88E1000_PSSR_REV_POLARITY) >>
+ M88E1000_PSSR_REV_POLARITY_SHIFT) ?
+ e1000_rev_polarity_reversed : e1000_rev_polarity_normal;
+
} else if (hw->phy_type == e1000_phy_igp ||
hw->phy_type == e1000_phy_igp_3 ||
hw->phy_type == e1000_phy_igp_2) {
@@ -6879,19 +6889,22 @@ e1000_check_polarity(struct e1000_hw *hw,
return ret_val;
/* Check the polarity bits */
- *polarity = (phy_data & IGP01E1000_PHY_POLARITY_MASK) ? 1 : 0;
+ *polarity = (phy_data & IGP01E1000_PHY_POLARITY_MASK) ?
+ e1000_rev_polarity_reversed : e1000_rev_polarity_normal;
} else {
/* For 10 Mbps, read the polarity bit in the status register. (for
* 100 Mbps this bit is always 0) */
- *polarity = phy_data & IGP01E1000_PSSR_POLARITY_REVERSED;
+ *polarity = (phy_data & IGP01E1000_PSSR_POLARITY_REVERSED) ?
+ e1000_rev_polarity_reversed : e1000_rev_polarity_normal;
}
} else if (hw->phy_type == e1000_phy_ife) {
ret_val = e1000_read_phy_reg(hw, IFE_PHY_EXTENDED_STATUS_CONTROL,
&phy_data);
if (ret_val)
return ret_val;
- *polarity = (phy_data & IFE_PESC_POLARITY_REVERSED) >>
- IFE_PESC_POLARITY_REVERSED_SHIFT;
+ *polarity = ((phy_data & IFE_PESC_POLARITY_REVERSED) >>
+ IFE_PESC_POLARITY_REVERSED_SHIFT) ?
+ e1000_rev_polarity_reversed : e1000_rev_polarity_normal;
}
return E1000_SUCCESS;
}
@@ -7259,7 +7272,7 @@ e1000_set_d3_lplu_state(struct e1000_hw *hw,
} else if (hw->smart_speed == e1000_smart_speed_off) {
ret_val = e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG,
&phy_data);
- if (ret_val)
+ if (ret_val)
return ret_val;
phy_data &= ~IGP01E1000_PSCFR_SMART_SPEED;
@@ -7369,7 +7382,7 @@ e1000_set_d0_lplu_state(struct e1000_hw *hw,
} else if (hw->smart_speed == e1000_smart_speed_off) {
ret_val = e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG,
&phy_data);
- if (ret_val)
+ if (ret_val)
return ret_val;
phy_data &= ~IGP01E1000_PSCFR_SMART_SPEED;
@@ -7475,7 +7488,7 @@ e1000_set_vco_speed(struct e1000_hw *hw)
*
* returns: - E1000_SUCCESS .
****************************************************************************/
-int32_t
+static int32_t
e1000_host_if_read_cookie(struct e1000_hw * hw, uint8_t *buffer)
{
uint8_t i;
@@ -7686,7 +7699,7 @@ e1000_check_mng_mode(struct e1000_hw *hw)
****************************************************************************/
int32_t
e1000_mng_write_dhcp_info(struct e1000_hw * hw, uint8_t *buffer,
- uint16_t length)
+ uint16_t length)
{
int32_t ret_val;
struct e1000_host_mng_command_header hdr;
@@ -7716,7 +7729,7 @@ e1000_mng_write_dhcp_info(struct e1000_hw * hw, uint8_t *buffer,
*
* returns - checksum of buffer contents.
****************************************************************************/
-uint8_t
+static uint8_t
e1000_calculate_mng_checksum(char *buffer, uint32_t length)
{
uint8_t sum = 0;
@@ -7914,32 +7927,6 @@ e1000_set_pci_express_master_disable(struct e1000_hw *hw)
E1000_WRITE_REG(hw, CTRL, ctrl);
}
-/***************************************************************************
- *
- * Enables PCI-Express master access.
- *
- * hw: Struct containing variables accessed by shared code
- *
- * returns: - none.
- *
- ***************************************************************************/
-#if 0
-void
-e1000_enable_pciex_master(struct e1000_hw *hw)
-{
- uint32_t ctrl;
-
- DEBUGFUNC("e1000_enable_pciex_master");
-
- if (hw->bus_type != e1000_bus_type_pci_express)
- return;
-
- ctrl = E1000_READ_REG(hw, CTRL);
- ctrl &= ~E1000_CTRL_GIO_MASTER_DISABLE;
- E1000_WRITE_REG(hw, CTRL, ctrl);
-}
-#endif /* 0 */
-
/*******************************************************************************
*
* Disables PCI-Express master access and verifies there are no pending requests
@@ -8063,7 +8050,6 @@ e1000_get_phy_cfg_done(struct e1000_hw *hw)
msleep(1);
timeout--;
}
-
if (!timeout) {
DEBUGOUT("MNG configuration cycle has not completed.\n");
return -E1000_ERR_RESET;
@@ -8172,8 +8158,9 @@ e1000_get_software_semaphore(struct e1000_hw *hw)
DEBUGFUNC("e1000_get_software_semaphore");
- if (hw->mac_type != e1000_80003es2lan)
+ if (hw->mac_type != e1000_80003es2lan) {
return E1000_SUCCESS;
+ }
while (timeout) {
swsm = E1000_READ_REG(hw, SWSM);
@@ -8206,8 +8193,9 @@ e1000_release_software_semaphore(struct e1000_hw *hw)
DEBUGFUNC("e1000_release_software_semaphore");
- if (hw->mac_type != e1000_80003es2lan)
+ if (hw->mac_type != e1000_80003es2lan) {
return;
+ }
swsm = E1000_READ_REG(hw, SWSM);
/* Release the SW semaphores.*/
@@ -8241,7 +8229,7 @@ e1000_check_phy_reset_block(struct e1000_hw *hw)
if (hw->mac_type > e1000_82547_rev_2)
manc = E1000_READ_REG(hw, MANC);
return (manc & E1000_MANC_BLK_PHY_RST_ON_IDE) ?
- E1000_BLK_PHY_RESET : E1000_SUCCESS;
+ E1000_BLK_PHY_RESET : E1000_SUCCESS;
}
static uint8_t
@@ -8377,66 +8365,6 @@ e1000_release_software_flag(struct e1000_hw *hw)
return;
}
-/***************************************************************************
- *
- * Disable dynamic power down mode in ife PHY.
- * It can be used to workaround band-gap problem.
- *
- * hw: Struct containing variables accessed by shared code
- *
- ***************************************************************************/
-#if 0
-int32_t
-e1000_ife_disable_dynamic_power_down(struct e1000_hw *hw)
-{
- uint16_t phy_data;
- int32_t ret_val = E1000_SUCCESS;
-
- DEBUGFUNC("e1000_ife_disable_dynamic_power_down");
-
- if (hw->phy_type == e1000_phy_ife) {
- ret_val = e1000_read_phy_reg(hw, IFE_PHY_SPECIAL_CONTROL, &phy_data);
- if (ret_val)
- return ret_val;
-
- phy_data |= IFE_PSC_DISABLE_DYNAMIC_POWER_DOWN;
- ret_val = e1000_write_phy_reg(hw, IFE_PHY_SPECIAL_CONTROL, phy_data);
- }
-
- return ret_val;
-}
-#endif /* 0 */
-
-/***************************************************************************
- *
- * Enable dynamic power down mode in ife PHY.
- * It can be used to workaround band-gap problem.
- *
- * hw: Struct containing variables accessed by shared code
- *
- ***************************************************************************/
-#if 0
-int32_t
-e1000_ife_enable_dynamic_power_down(struct e1000_hw *hw)
-{
- uint16_t phy_data;
- int32_t ret_val = E1000_SUCCESS;
-
- DEBUGFUNC("e1000_ife_enable_dynamic_power_down");
-
- if (hw->phy_type == e1000_phy_ife) {
- ret_val = e1000_read_phy_reg(hw, IFE_PHY_SPECIAL_CONTROL, &phy_data);
- if (ret_val)
- return ret_val;
-
- phy_data &= ~IFE_PSC_DISABLE_DYNAMIC_POWER_DOWN;
- ret_val = e1000_write_phy_reg(hw, IFE_PHY_SPECIAL_CONTROL, phy_data);
- }
-
- return ret_val;
-}
-#endif /* 0 */
-
/******************************************************************************
* Reads a 16 bit word or words from the EEPROM using the ICH8's flash access
* register.
@@ -8832,20 +8760,22 @@ static int32_t
e1000_verify_write_ich8_byte(struct e1000_hw *hw, uint32_t index, uint8_t byte)
{
int32_t error = E1000_SUCCESS;
- int32_t program_retries;
- uint8_t temp_byte;
+ int32_t program_retries = 0;
- e1000_write_ich8_byte(hw, index, byte);
- udelay(100);
+ DEBUGOUT2("Byte := %2.2X Offset := %d\n", byte, index);
- for (program_retries = 0; program_retries < 100; program_retries++) {
- e1000_read_ich8_byte(hw, index, &temp_byte);
- if (temp_byte == byte)
- break;
- udelay(10);
- e1000_write_ich8_byte(hw, index, byte);
- udelay(100);
+ error = e1000_write_ich8_byte(hw, index, byte);
+
+ if (error != E1000_SUCCESS) {
+ for (program_retries = 0; program_retries < 100; program_retries++) {
+ DEBUGOUT2("Retrying \t Byte := %2.2X Offset := %d\n", byte, index);
+ error = e1000_write_ich8_byte(hw, index, byte);
+ udelay(100);
+ if (error == E1000_SUCCESS)
+ break;
+ }
}
+
if (program_retries == 100)
error = E1000_ERR_EEPROM;
@@ -8886,39 +8816,27 @@ e1000_read_ich8_word(struct e1000_hw *hw, uint32_t index, uint16_t *data)
}
/******************************************************************************
- * Writes a word to the NVM using the ICH8 flash access registers.
+ * Erases the bank specified. Each bank may be a 4, 8 or 64k block. Banks are 0
+ * based.
*
* hw - pointer to e1000_hw structure
- * index - The starting byte index of the word to read.
- * data - The word to write to the NVM.
- *****************************************************************************/
-#if 0
-int32_t
-e1000_write_ich8_word(struct e1000_hw *hw, uint32_t index, uint16_t data)
-{
- int32_t status = E1000_SUCCESS;
- status = e1000_write_ich8_data(hw, index, 2, data);
- return status;
-}
-#endif /* 0 */
-
-/******************************************************************************
- * Erases the bank specified. Each bank is a 4k block. Segments are 0 based.
- * segment N is 4096 * N + flash_reg_addr.
+ * bank - 0 for first bank, 1 for second bank
*
- * hw - pointer to e1000_hw structure
- * segment - 0 for first segment, 1 for second segment, etc.
+ * Note that this function may actually erase as much as 8 or 64 KBytes. The
+ * amount of NVM used in each bank is a *minimum* of 4 KBytes, but in fact the
+ * bank size may be 4, 8 or 64 KBytes
*****************************************************************************/
-static int32_t
-e1000_erase_ich8_4k_segment(struct e1000_hw *hw, uint32_t segment)
+int32_t
+e1000_erase_ich8_4k_segment(struct e1000_hw *hw, uint32_t bank)
{
union ich8_hws_flash_status hsfsts;
union ich8_hws_flash_ctrl hsflctl;
uint32_t flash_linear_address;
int32_t count = 0;
int32_t error = E1000_ERR_EEPROM;
- int32_t iteration, seg_size;
- int32_t sector_size;
+ int32_t iteration;
+ int32_t sub_sector_size = 0;
+ int32_t bank_size;
int32_t j = 0;
int32_t error_flag = 0;
@@ -8927,22 +8845,27 @@ e1000_erase_ich8_4k_segment(struct e1000_hw *hw, uint32_t segment)
/* Determine HW Sector size: Read BERASE bits of Hw flash Status register */
/* 00: The Hw sector is 256 bytes, hence we need to erase 16
* consecutive sectors. The start index for the nth Hw sector can be
- * calculated as = segment * 4096 + n * 256
+ * calculated as bank * 4096 + n * 256
* 01: The Hw sector is 4K bytes, hence we need to erase 1 sector.
* The start index for the nth Hw sector can be calculated
- * as = segment * 4096
- * 10: Error condition
- * 11: The Hw sector size is much bigger than the size asked to
- * erase...error condition */
+ * as bank * 4096
+ * 10: The HW sector is 8K bytes
+ * 11: The Hw sector size is 64K bytes */
if (hsfsts.hsf_status.berasesz == 0x0) {
/* Hw sector size 256 */
- sector_size = seg_size = ICH8_FLASH_SEG_SIZE_256;
+ sub_sector_size = ICH8_FLASH_SEG_SIZE_256;
+ bank_size = ICH8_FLASH_SECTOR_SIZE;
iteration = ICH8_FLASH_SECTOR_SIZE / ICH8_FLASH_SEG_SIZE_256;
} else if (hsfsts.hsf_status.berasesz == 0x1) {
- sector_size = seg_size = ICH8_FLASH_SEG_SIZE_4K;
+ bank_size = ICH8_FLASH_SEG_SIZE_4K;
+ iteration = 1;
+ } else if (hw->mac_type != e1000_ich8lan &&
+ hsfsts.hsf_status.berasesz == 0x2) {
+ /* 8K erase size invalid for ICH8 - added in for ICH9 */
+ bank_size = ICH9_FLASH_SEG_SIZE_8K;
iteration = 1;
} else if (hsfsts.hsf_status.berasesz == 0x3) {
- sector_size = seg_size = ICH8_FLASH_SEG_SIZE_64K;
+ bank_size = ICH8_FLASH_SEG_SIZE_64K;
iteration = 1;
} else {
return error;
@@ -8966,16 +8889,15 @@ e1000_erase_ich8_4k_segment(struct e1000_hw *hw, uint32_t segment)
/* Write the last 24 bits of an index within the block into Flash
* Linear address field in Flash Address. This probably needs to
- * be calculated here based off the on-chip segment size and the
- * software segment size assumed (4K) */
- /* TBD */
- flash_linear_address = segment * sector_size + j * seg_size;
- flash_linear_address &= ICH8_FLASH_LINEAR_ADDR_MASK;
+ * be calculated here based off the on-chip erase sector size and
+ * the software bank size (4, 8 or 64 KBytes) */
+ flash_linear_address = bank * bank_size + j * sub_sector_size;
flash_linear_address += hw->flash_base_addr;
+ flash_linear_address &= ICH8_FLASH_LINEAR_ADDR_MASK;
E1000_WRITE_ICH8_REG(hw, ICH8_FLASH_FADDR, flash_linear_address);
- error = e1000_ich8_flash_cycle(hw, 1000000);
+ error = e1000_ich8_flash_cycle(hw, ICH8_FLASH_ERASE_TIMEOUT);
/* Check if FCERR is set to 1. If 1, clear it and try the whole
* sequence a few more times else Done */
if (error == E1000_SUCCESS) {
@@ -8999,44 +8921,6 @@ e1000_erase_ich8_4k_segment(struct e1000_hw *hw, uint32_t segment)
return error;
}
-/******************************************************************************
- *
- * Reverse duplex setting without breaking the link.
- *
- * hw: Struct containing variables accessed by shared code
- *
- *****************************************************************************/
-#if 0
-int32_t
-e1000_duplex_reversal(struct e1000_hw *hw)
-{
- int32_t ret_val;
- uint16_t phy_data;
-
- if (hw->phy_type != e1000_phy_igp_3)
- return E1000_SUCCESS;
-
- ret_val = e1000_read_phy_reg(hw, PHY_CTRL, &phy_data);
- if (ret_val)
- return ret_val;
-
- phy_data ^= MII_CR_FULL_DUPLEX;
-
- ret_val = e1000_write_phy_reg(hw, PHY_CTRL, phy_data);
- if (ret_val)
- return ret_val;
-
- ret_val = e1000_read_phy_reg(hw, IGP3E1000_PHY_MISC_CTRL, &phy_data);
- if (ret_val)
- return ret_val;
-
- phy_data |= IGP3_PHY_MISC_DUPLEX_MANUAL_SET;
- ret_val = e1000_write_phy_reg(hw, IGP3E1000_PHY_MISC_CTRL, phy_data);
-
- return ret_val;
-}
-#endif /* 0 */
-
static int32_t
e1000_init_lcd_from_nvm_config_region(struct e1000_hw *hw,
uint32_t cnf_base_addr, uint32_t cnf_size)
@@ -9071,6 +8955,14 @@ e1000_init_lcd_from_nvm_config_region(struct e1000_hw *hw,
}
+/******************************************************************************
+ * This function initializes the PHY from the NVM on ICH8 platforms. This
+ * is needed due to an issue where the NVM configuration is not properly
+ * autoloaded after power transitions. Therefore, after each PHY reset, we
+ * will load the configuration data out of the NVM manually.
+ *
+ * hw: Struct containing variables accessed by shared code
+ *****************************************************************************/
static int32_t
e1000_init_lcd_from_nvm(struct e1000_hw *hw)
{
diff --git a/drivers/net/e1000/e1000_hw.h b/drivers/net/e1000/e1000_hw.h
index 4020acb55005..112447fd8bf2 100644
--- a/drivers/net/e1000/e1000_hw.h
+++ b/drivers/net/e1000/e1000_hw.h
@@ -1,25 +1,24 @@
/*******************************************************************************
-
- Copyright(c) 1999 - 2006 Intel Corporation. All rights reserved.
-
- This program is free software; you can redistribute it and/or modify it
- under the terms of the GNU General Public License as published by the Free
- Software Foundation; 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
+ Intel PRO/1000 Linux driver
+ Copyright(c) 1999 - 2006 Intel Corporation.
+
+ This program is free software; you can redistribute it and/or modify it
+ under the terms and conditions of the GNU General Public License,
+ version 2, as published by the Free Software Foundation.
+
+ This program is distributed in the hope 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.
-
- The full GNU General Public License is included in this distribution in the
- file called LICENSE.
-
+ this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+
+ The full GNU General Public License is included in this distribution in
+ the file called "COPYING".
+
Contact Information:
Linux NICS <linux.nics@intel.com>
e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
@@ -93,11 +92,11 @@ typedef enum {
/* Flow Control Settings */
typedef enum {
- e1000_fc_none = 0,
- e1000_fc_rx_pause = 1,
- e1000_fc_tx_pause = 2,
- e1000_fc_full = 3,
- e1000_fc_default = 0xFF
+ E1000_FC_NONE = 0,
+ E1000_FC_RX_PAUSE = 1,
+ E1000_FC_TX_PAUSE = 2,
+ E1000_FC_FULL = 3,
+ E1000_FC_DEFAULT = 0xFF
} e1000_fc_type;
struct e1000_shadow_ram {
@@ -302,6 +301,9 @@ typedef enum {
#define E1000_BLK_PHY_RESET 12
#define E1000_ERR_SWFW_SYNC 13
+#define E1000_BYTE_SWAP_WORD(_value) ((((_value) & 0x00ff) << 8) | \
+ (((_value) & 0xff00) >> 8))
+
/* Function prototypes */
/* Initialization */
int32_t e1000_reset_hw(struct e1000_hw *hw);
@@ -314,7 +316,7 @@ int32_t e1000_setup_link(struct e1000_hw *hw);
int32_t e1000_phy_setup_autoneg(struct e1000_hw *hw);
void e1000_config_collision_dist(struct e1000_hw *hw);
int32_t e1000_check_for_link(struct e1000_hw *hw);
-int32_t e1000_get_speed_and_duplex(struct e1000_hw *hw, uint16_t * speed, uint16_t * duplex);
+int32_t e1000_get_speed_and_duplex(struct e1000_hw *hw, uint16_t *speed, uint16_t *duplex);
int32_t e1000_force_mac_fc(struct e1000_hw *hw);
/* PHY */
@@ -322,9 +324,9 @@ int32_t e1000_read_phy_reg(struct e1000_hw *hw, uint32_t reg_addr, uint16_t *phy
int32_t e1000_write_phy_reg(struct e1000_hw *hw, uint32_t reg_addr, uint16_t data);
int32_t e1000_phy_hw_reset(struct e1000_hw *hw);
int32_t e1000_phy_reset(struct e1000_hw *hw);
-void e1000_phy_powerdown_workaround(struct e1000_hw *hw);
int32_t e1000_phy_get_info(struct e1000_hw *hw, struct e1000_phy_info *phy_info);
int32_t e1000_validate_mdi_setting(struct e1000_hw *hw);
+void e1000_phy_powerdown_workaround(struct e1000_hw *hw);
/* EEPROM Functions */
int32_t e1000_init_eeprom_params(struct e1000_hw *hw);
@@ -393,7 +395,6 @@ int32_t e1000_read_eeprom(struct e1000_hw *hw, uint16_t reg, uint16_t words, uin
int32_t e1000_validate_eeprom_checksum(struct e1000_hw *hw);
int32_t e1000_update_eeprom_checksum(struct e1000_hw *hw);
int32_t e1000_write_eeprom(struct e1000_hw *hw, uint16_t reg, uint16_t words, uint16_t *data);
-int32_t e1000_read_part_num(struct e1000_hw *hw, uint32_t * part_num);
int32_t e1000_read_mac_addr(struct e1000_hw * hw);
/* Filters (multicast, vlan, receive) */
@@ -420,6 +421,7 @@ void e1000_pci_set_mwi(struct e1000_hw *hw);
void e1000_pci_clear_mwi(struct e1000_hw *hw);
void e1000_read_pci_cfg(struct e1000_hw *hw, uint32_t reg, uint16_t * value);
void e1000_write_pci_cfg(struct e1000_hw *hw, uint32_t reg, uint16_t * value);
+int32_t e1000_read_pcie_cap_reg(struct e1000_hw *hw, uint32_t reg, uint16_t *value);
/* Port I/O is only supported on 82544 and newer */
void e1000_io_write(struct e1000_hw *hw, unsigned long port, uint32_t value);
int32_t e1000_disable_pciex_master(struct e1000_hw *hw);
@@ -574,10 +576,10 @@ int32_t e1000_check_phy_reset_block(struct e1000_hw *hw);
* E1000_RAR_ENTRIES - 1 multicast addresses.
*/
#define E1000_RAR_ENTRIES 15
-#define E1000_RAR_ENTRIES_ICH8LAN 7
+#define E1000_RAR_ENTRIES_ICH8LAN 6
-#define MIN_NUMBER_OF_DESCRIPTORS 8
-#define MAX_NUMBER_OF_DESCRIPTORS 0xFFF8
+#define MIN_NUMBER_OF_DESCRIPTORS 8
+#define MAX_NUMBER_OF_DESCRIPTORS 0xFFF8
/* Receive Descriptor */
struct e1000_rx_desc {
@@ -1300,6 +1302,7 @@ struct e1000_hw_stats {
uint64_t algnerrc;
uint64_t symerrs;
uint64_t rxerrc;
+ uint64_t txerrc;
uint64_t mpc;
uint64_t scc;
uint64_t ecol;
@@ -1332,8 +1335,9 @@ struct e1000_hw_stats {
uint64_t gotch;
uint64_t rnbc;
uint64_t ruc;
- uint64_t rfc;
uint64_t roc;
+ uint64_t rlerrc;
+ uint64_t rfc;
uint64_t rjc;
uint64_t mgprc;
uint64_t mgpdc;
@@ -1440,6 +1444,7 @@ struct e1000_hw {
boolean_t tbi_compatibility_on;
boolean_t laa_is_present;
boolean_t phy_reset_disable;
+ boolean_t initialize_hw_bits_disable;
boolean_t fc_send_xon;
boolean_t fc_strict_ieee;
boolean_t report_tx_early;
@@ -1613,16 +1618,17 @@ struct e1000_hw {
#define E1000_CTRL_EXT_LINK_MODE_MASK 0x00C00000
#define E1000_CTRL_EXT_LINK_MODE_GMII 0x00000000
#define E1000_CTRL_EXT_LINK_MODE_TBI 0x00C00000
-#define E1000_CTRL_EXT_LINK_MODE_KMRN 0x00000000
+#define E1000_CTRL_EXT_LINK_MODE_KMRN 0x00000000
#define E1000_CTRL_EXT_LINK_MODE_SERDES 0x00C00000
+#define E1000_CTRL_EXT_LINK_MODE_SGMII 0x00800000
#define E1000_CTRL_EXT_WR_WMARK_MASK 0x03000000
#define E1000_CTRL_EXT_WR_WMARK_256 0x00000000
#define E1000_CTRL_EXT_WR_WMARK_320 0x01000000
#define E1000_CTRL_EXT_WR_WMARK_384 0x02000000
#define E1000_CTRL_EXT_WR_WMARK_448 0x03000000
-#define E1000_CTRL_EXT_DRV_LOAD 0x10000000 /* Driver loaded bit for FW */
-#define E1000_CTRL_EXT_IAME 0x08000000 /* Interrupt acknowledge Auto-mask */
-#define E1000_CTRL_EXT_INT_TIMER_CLR 0x20000000 /* Clear Interrupt timers after IMS clear */
+#define E1000_CTRL_EXT_DRV_LOAD 0x10000000 /* Driver loaded bit for FW */
+#define E1000_CTRL_EXT_IAME 0x08000000 /* Interrupt acknowledge Auto-mask */
+#define E1000_CTRL_EXT_INT_TIMER_CLR 0x20000000 /* Clear Interrupt timers after IMS clear */
#define E1000_CRTL_EXT_PB_PAREN 0x01000000 /* packet buffer parity error detection enabled */
#define E1000_CTRL_EXT_DF_PAREN 0x02000000 /* descriptor FIFO parity error detection enable */
#define E1000_CTRL_EXT_GHOST_PAREN 0x40000000
@@ -2218,6 +2224,11 @@ struct e1000_host_command_info {
#define E1000_FACTPS_LAN_FUNC_SEL 0x40000000
#define E1000_FACTPS_PM_STATE_CHANGED 0x80000000
+/* PCI-Ex Config Space */
+#define PCI_EX_LINK_STATUS 0x12
+#define PCI_EX_LINK_WIDTH_MASK 0x3F0
+#define PCI_EX_LINK_WIDTH_SHIFT 4
+
/* EEPROM Commands - Microwire */
#define EEPROM_READ_OPCODE_MICROWIRE 0x6 /* EEPROM read opcode */
#define EEPROM_WRITE_OPCODE_MICROWIRE 0x5 /* EEPROM write opcode */
@@ -3120,6 +3131,7 @@ struct e1000_host_command_info {
/* I = Integrated
* E = External
*/
+#define M88_VENDOR 0x0141
#define M88E1000_E_PHY_ID 0x01410C50
#define M88E1000_I_PHY_ID 0x01410C30
#define M88E1011_I_PHY_ID 0x01410C20
@@ -3244,10 +3256,12 @@ struct e1000_host_command_info {
#define IFE_PSCL_PROBE_LEDS_OFF 0x0006 /* Force LEDs 0 and 2 off */
#define IFE_PSCL_PROBE_LEDS_ON 0x0007 /* Force LEDs 0 and 2 on */
-#define ICH8_FLASH_COMMAND_TIMEOUT 500 /* 500 ms , should be adjusted */
-#define ICH8_FLASH_CYCLE_REPEAT_COUNT 10 /* 10 cycles , should be adjusted */
+#define ICH8_FLASH_COMMAND_TIMEOUT 5000 /* 5000 uSecs - adjusted */
+#define ICH8_FLASH_ERASE_TIMEOUT 3000000 /* Up to 3 seconds - worst case */
+#define ICH8_FLASH_CYCLE_REPEAT_COUNT 10 /* 10 cycles */
#define ICH8_FLASH_SEG_SIZE_256 256
#define ICH8_FLASH_SEG_SIZE_4K 4096
+#define ICH9_FLASH_SEG_SIZE_8K 8192
#define ICH8_FLASH_SEG_SIZE_64K 65536
#define ICH8_CYCLE_READ 0x0
diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c
index 3f6a752700a1..7dca38fba6a1 100644
--- a/drivers/net/e1000/e1000_main.c
+++ b/drivers/net/e1000/e1000_main.c
@@ -1,25 +1,24 @@
/*******************************************************************************
-
- Copyright(c) 1999 - 2006 Intel Corporation. All rights reserved.
-
- This program is free software; you can redistribute it and/or modify it
- under the terms of the GNU General Public License as published by the Free
- Software Foundation; 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
+ Intel PRO/1000 Linux driver
+ Copyright(c) 1999 - 2006 Intel Corporation.
+
+ This program is free software; you can redistribute it and/or modify it
+ under the terms and conditions of the GNU General Public License,
+ version 2, as published by the Free Software Foundation.
+
+ This program is distributed in the hope 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.
-
- The full GNU General Public License is included in this distribution in the
- file called LICENSE.
-
+ this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+
+ The full GNU General Public License is included in this distribution in
+ the file called "COPYING".
+
Contact Information:
Linux NICS <linux.nics@intel.com>
e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
@@ -36,7 +35,7 @@ static char e1000_driver_string[] = "Intel(R) PRO/1000 Network Driver";
#else
#define DRIVERNAPI "-NAPI"
#endif
-#define DRV_VERSION "7.2.7-k2"DRIVERNAPI
+#define DRV_VERSION "7.2.9-k2"DRIVERNAPI
char e1000_driver_version[] = DRV_VERSION;
static char e1000_copyright[] = "Copyright (c) 1999-2006 Intel Corporation.";
@@ -110,16 +109,24 @@ static struct pci_device_id e1000_pci_tbl[] = {
MODULE_DEVICE_TABLE(pci, e1000_pci_tbl);
+int e1000_up(struct e1000_adapter *adapter);
+void e1000_down(struct e1000_adapter *adapter);
+void e1000_reinit_locked(struct e1000_adapter *adapter);
+void e1000_reset(struct e1000_adapter *adapter);
+int e1000_set_spd_dplx(struct e1000_adapter *adapter, uint16_t spddplx);
+int e1000_setup_all_tx_resources(struct e1000_adapter *adapter);
+int e1000_setup_all_rx_resources(struct e1000_adapter *adapter);
+void e1000_free_all_tx_resources(struct e1000_adapter *adapter);
+void e1000_free_all_rx_resources(struct e1000_adapter *adapter);
static int e1000_setup_tx_resources(struct e1000_adapter *adapter,
- struct e1000_tx_ring *txdr);
+ struct e1000_tx_ring *txdr);
static int e1000_setup_rx_resources(struct e1000_adapter *adapter,
- struct e1000_rx_ring *rxdr);
+ struct e1000_rx_ring *rxdr);
static void e1000_free_tx_resources(struct e1000_adapter *adapter,
- struct e1000_tx_ring *tx_ring);
+ struct e1000_tx_ring *tx_ring);
static void e1000_free_rx_resources(struct e1000_adapter *adapter,
- struct e1000_rx_ring *rx_ring);
-
-/* Local Function Prototypes */
+ struct e1000_rx_ring *rx_ring);
+void e1000_update_stats(struct e1000_adapter *adapter);
static int e1000_init_module(void);
static void e1000_exit_module(void);
@@ -172,6 +179,7 @@ static void e1000_alloc_rx_buffers_ps(struct e1000_adapter *adapter,
static int e1000_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd);
static int e1000_mii_ioctl(struct net_device *netdev, struct ifreq *ifr,
int cmd);
+void e1000_set_ethtool_ops(struct net_device *netdev);
static void e1000_enter_82542_rst(struct e1000_adapter *adapter);
static void e1000_leave_82542_rst(struct e1000_adapter *adapter);
static void e1000_tx_timeout(struct net_device *dev);
@@ -196,6 +204,8 @@ static void e1000_shutdown(struct pci_dev *pdev);
static void e1000_netpoll (struct net_device *netdev);
#endif
+extern void e1000_check_options(struct e1000_adapter *adapter);
+
static pci_ers_result_t e1000_io_error_detected(struct pci_dev *pdev,
pci_channel_state_t state);
static pci_ers_result_t e1000_io_slot_reset(struct pci_dev *pdev);
@@ -212,9 +222,9 @@ static struct pci_driver e1000_driver = {
.id_table = e1000_pci_tbl,
.probe = e1000_probe,
.remove = __devexit_p(e1000_remove),
+#ifdef CONFIG_PM
/* Power Managment Hooks */
.suspend = e1000_suspend,
-#ifdef CONFIG_PM
.resume = e1000_resume,
#endif
.shutdown = e1000_shutdown,
@@ -466,13 +476,14 @@ e1000_up(struct e1000_adapter *adapter)
adapter->tx_queue_len = netdev->tx_queue_len;
- mod_timer(&adapter->watchdog_timer, jiffies);
-
#ifdef CONFIG_E1000_NAPI
netif_poll_enable(netdev);
#endif
e1000_irq_enable(adapter);
+ clear_bit(__E1000_DOWN, &adapter->flags);
+
+ mod_timer(&adapter->watchdog_timer, jiffies + 2 * HZ);
return 0;
}
@@ -502,25 +513,48 @@ void e1000_power_up_phy(struct e1000_adapter *adapter)
static void e1000_power_down_phy(struct e1000_adapter *adapter)
{
- boolean_t mng_mode_enabled = (adapter->hw.mac_type >= e1000_82571) &&
- e1000_check_mng_mode(&adapter->hw);
- /* Power down the PHY so no link is implied when interface is down
- * The PHY cannot be powered down if any of the following is TRUE
+ /* Power down the PHY so no link is implied when interface is down *
+ * The PHY cannot be powered down if any of the following is TRUE *
* (a) WoL is enabled
* (b) AMT is active
* (c) SoL/IDER session is active */
if (!adapter->wol && adapter->hw.mac_type >= e1000_82540 &&
- adapter->hw.mac_type != e1000_ich8lan &&
- adapter->hw.media_type == e1000_media_type_copper &&
- !(E1000_READ_REG(&adapter->hw, MANC) & E1000_MANC_SMBUS_EN) &&
- !mng_mode_enabled &&
- !e1000_check_phy_reset_block(&adapter->hw)) {
+ adapter->hw.media_type == e1000_media_type_copper) {
uint16_t mii_reg = 0;
+
+ switch (adapter->hw.mac_type) {
+ case e1000_82540:
+ case e1000_82545:
+ case e1000_82545_rev_3:
+ case e1000_82546:
+ case e1000_82546_rev_3:
+ case e1000_82541:
+ case e1000_82541_rev_2:
+ case e1000_82547:
+ case e1000_82547_rev_2:
+ if (E1000_READ_REG(&adapter->hw, MANC) &
+ E1000_MANC_SMBUS_EN)
+ goto out;
+ break;
+ case e1000_82571:
+ case e1000_82572:
+ case e1000_82573:
+ case e1000_80003es2lan:
+ case e1000_ich8lan:
+ if (e1000_check_mng_mode(&adapter->hw) ||
+ e1000_check_phy_reset_block(&adapter->hw))
+ goto out;
+ break;
+ default:
+ goto out;
+ }
e1000_read_phy_reg(&adapter->hw, PHY_CTRL, &mii_reg);
mii_reg |= MII_CR_POWER_DOWN;
e1000_write_phy_reg(&adapter->hw, PHY_CTRL, mii_reg);
mdelay(1);
}
+out:
+ return;
}
void
@@ -528,6 +562,10 @@ e1000_down(struct e1000_adapter *adapter)
{
struct net_device *netdev = adapter->netdev;
+ /* signal that we're down so the interrupt handler does not
+ * reschedule our watchdog timer */
+ set_bit(__E1000_DOWN, &adapter->flags);
+
e1000_irq_disable(adapter);
del_timer_sync(&adapter->tx_fifo_stall_timer);
@@ -563,6 +601,9 @@ void
e1000_reset(struct e1000_adapter *adapter)
{
uint32_t pba, manc;
+#ifdef DISABLE_MULR
+ uint32_t tctl;
+#endif
uint16_t fc_high_water_mark = E1000_FC_HIGH_DIFF;
/* Repartition Pba for greater than 9k mtu
@@ -629,6 +670,12 @@ e1000_reset(struct e1000_adapter *adapter)
e1000_reset_hw(&adapter->hw);
if (adapter->hw.mac_type >= e1000_82544)
E1000_WRITE_REG(&adapter->hw, WUC, 0);
+#ifdef DISABLE_MULR
+ /* disable Multiple Reads in Transmit Control Register for debugging */
+ tctl = E1000_READ_REG(hw, TCTL);
+ E1000_WRITE_REG(hw, TCTL, tctl & ~E1000_TCTL_MULR);
+
+#endif
if (e1000_init_hw(&adapter->hw))
DPRINTK(PROBE, ERR, "Hardware Error\n");
e1000_update_mng_vlan(adapter);
@@ -652,9 +699,7 @@ e1000_reset(struct e1000_adapter *adapter)
phy_data);
}
- if (adapter->hw.mac_type < e1000_ich8lan)
- /* FIXME: this code is duplicate and wrong for PCI Express */
- if (adapter->en_mng_pt) {
+ if ((adapter->en_mng_pt) && (adapter->hw.mac_type < e1000_82571)) {
manc = E1000_READ_REG(&adapter->hw, MANC);
manc |= (E1000_MANC_ARP_EN | E1000_MANC_EN_MNG2HOST);
E1000_WRITE_REG(&adapter->hw, MANC, manc);
@@ -760,7 +805,7 @@ e1000_probe(struct pci_dev *pdev,
#ifdef CONFIG_NET_POLL_CONTROLLER
netdev->poll_controller = e1000_netpoll;
#endif
- strcpy(netdev->name, pci_name(pdev));
+ strncpy(netdev->name, pci_name(pdev), sizeof(netdev->name) - 1);
netdev->mem_start = mmio_start;
netdev->mem_end = mmio_start + mmio_len;
@@ -863,11 +908,6 @@ e1000_probe(struct pci_dev *pdev,
INIT_WORK(&adapter->reset_task,
(void (*)(void *))e1000_reset_task, netdev);
- /* we're going to reset, so assume we have no link for now */
-
- netif_carrier_off(netdev);
- netif_stop_queue(netdev);
-
e1000_check_options(adapter);
/* Initial Wake on LAN setting
@@ -974,6 +1014,10 @@ e1000_probe(struct pci_dev *pdev,
if ((err = register_netdev(netdev)))
goto err_register;
+ /* tell the stack to leave us alone until e1000_open() is called */
+ netif_carrier_off(netdev);
+ netif_stop_queue(netdev);
+
DPRINTK(PROBE, INFO, "Intel(R) PRO/1000 Network Connection\n");
cards_found++;
@@ -1032,8 +1076,7 @@ e1000_remove(struct pci_dev *pdev)
flush_scheduled_work();
- if (adapter->hw.mac_type >= e1000_82540 &&
- adapter->hw.mac_type != e1000_ich8lan &&
+ if (adapter->hw.mac_type < e1000_82571 &&
adapter->hw.media_type == e1000_media_type_copper) {
manc = E1000_READ_REG(&adapter->hw, MANC);
if (manc & E1000_MANC_SMBUS_EN) {
@@ -1161,6 +1204,8 @@ e1000_sw_init(struct e1000_adapter *adapter)
atomic_set(&adapter->irq_sem, 1);
spin_lock_init(&adapter->stats_lock);
+ set_bit(__E1000_DOWN, &adapter->flags);
+
return 0;
}
@@ -1226,7 +1271,7 @@ e1000_open(struct net_device *netdev)
int err;
/* disallow open during test */
- if (test_bit(__E1000_DRIVER_TESTING, &adapter->flags))
+ if (test_bit(__E1000_TESTING, &adapter->flags))
return -EBUSY;
/* allocate transmit descriptors */
@@ -1299,8 +1344,12 @@ e1000_close(struct net_device *netdev)
e1000_free_all_tx_resources(adapter);
e1000_free_all_rx_resources(adapter);
+ /* kill manageability vlan ID if supported, but not if a vlan with
+ * the same ID is registered on the host OS (let 8021q kill it) */
if ((adapter->hw.mng_cookie.status &
- E1000_MNG_DHCP_COOKIE_STATUS_VLAN_SUPPORT)) {
+ E1000_MNG_DHCP_COOKIE_STATUS_VLAN_SUPPORT) &&
+ !(adapter->vlgrp &&
+ adapter->vlgrp->vlan_devices[adapter->mng_vlan_id])) {
e1000_vlan_rx_kill_vid(netdev, adapter->mng_vlan_id);
}
@@ -1510,27 +1559,14 @@ e1000_configure_tx(struct e1000_adapter *adapter)
/* Program the Transmit Control Register */
tctl = E1000_READ_REG(hw, TCTL);
-
tctl &= ~E1000_TCTL_CT;
tctl |= E1000_TCTL_PSP | E1000_TCTL_RTLC |
(E1000_COLLISION_THRESHOLD << E1000_CT_SHIFT);
-#ifdef DISABLE_MULR
- /* disable Multiple Reads for debugging */
- tctl &= ~E1000_TCTL_MULR;
-#endif
-
if (hw->mac_type == e1000_82571 || hw->mac_type == e1000_82572) {
tarc = E1000_READ_REG(hw, TARC0);
- tarc |= ((1 << 25) | (1 << 21));
+ tarc |= (1 << 21);
E1000_WRITE_REG(hw, TARC0, tarc);
- tarc = E1000_READ_REG(hw, TARC1);
- tarc |= (1 << 25);
- if (tctl & E1000_TCTL_MULR)
- tarc &= ~(1 << 28);
- else
- tarc |= (1 << 28);
- E1000_WRITE_REG(hw, TARC1, tarc);
} else if (hw->mac_type == e1000_80003es2lan) {
tarc = E1000_READ_REG(hw, TARC0);
tarc |= 1;
@@ -2892,6 +2928,35 @@ e1000_transfer_dhcp_info(struct e1000_adapter *adapter, struct sk_buff *skb)
return 0;
}
+static int __e1000_maybe_stop_tx(struct net_device *netdev, int size)
+{
+ struct e1000_adapter *adapter = netdev_priv(netdev);
+ struct e1000_tx_ring *tx_ring = adapter->tx_ring;
+
+ netif_stop_queue(netdev);
+ /* Herbert's original patch had:
+ * smp_mb__after_netif_stop_queue();
+ * but since that doesn't exist yet, just open code it. */
+ smp_mb();
+
+ /* We need to check again in a case another CPU has just
+ * made room available. */
+ if (likely(E1000_DESC_UNUSED(tx_ring) < size))
+ return -EBUSY;
+
+ /* A reprieve! */
+ netif_start_queue(netdev);
+ return 0;
+}
+
+static int e1000_maybe_stop_tx(struct net_device *netdev,
+ struct e1000_tx_ring *tx_ring, int size)
+{
+ if (likely(E1000_DESC_UNUSED(tx_ring) >= size))
+ return 0;
+ return __e1000_maybe_stop_tx(netdev, size);
+}
+
#define TXD_USE_COUNT(S, X) (((S) >> (X)) + 1 )
static int
e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
@@ -2910,6 +2975,10 @@ e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
unsigned int f;
len -= skb->data_len;
+ /* This goes back to the question of how to logically map a tx queue
+ * to a flow. Right now, performance is impacted slightly negatively
+ * if using multiple tx queues. If the stack breaks away from a
+ * single qdisc implementation, we can look at this again. */
tx_ring = adapter->tx_ring;
if (unlikely(skb->len <= 0)) {
@@ -3005,8 +3074,7 @@ e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
/* need: count + 2 desc gap to keep tail from touching
* head, otherwise try next time */
- if (unlikely(E1000_DESC_UNUSED(tx_ring) < count + 2)) {
- netif_stop_queue(netdev);
+ if (unlikely(e1000_maybe_stop_tx(netdev, tx_ring, count + 2))) {
spin_unlock_irqrestore(&tx_ring->tx_lock, flags);
return NETDEV_TX_BUSY;
}
@@ -3014,7 +3082,7 @@ e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
if (unlikely(adapter->hw.mac_type == e1000_82547)) {
if (unlikely(e1000_82547_fifo_workaround(adapter, skb))) {
netif_stop_queue(netdev);
- mod_timer(&adapter->tx_fifo_stall_timer, jiffies);
+ mod_timer(&adapter->tx_fifo_stall_timer, jiffies + 1);
spin_unlock_irqrestore(&tx_ring->tx_lock, flags);
return NETDEV_TX_BUSY;
}
@@ -3053,8 +3121,7 @@ e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
netdev->trans_start = jiffies;
/* Make sure there is space in the ring for the next send. */
- if (unlikely(E1000_DESC_UNUSED(tx_ring) < MAX_SKB_FRAGS + 2))
- netif_stop_queue(netdev);
+ e1000_maybe_stop_tx(netdev, tx_ring, MAX_SKB_FRAGS + 2);
spin_unlock_irqrestore(&tx_ring->tx_lock, flags);
return NETDEV_TX_OK;
@@ -3131,11 +3198,13 @@ e1000_change_mtu(struct net_device *netdev, int new_mtu)
}
break;
case e1000_82573:
- /* only enable jumbo frames if ASPM is disabled completely
- * this means both bits must be zero in 0x1A bits 3:2 */
+ /* Jumbo Frames not supported if:
+ * - this is not an 82573L device
+ * - ASPM is enabled in any way (0x1A bits 3:2) */
e1000_read_eeprom(&adapter->hw, EEPROM_INIT_3GIO_3, 1,
&eeprom_data);
- if (eeprom_data & EEPROM_WORD1A_ASPM_MASK) {
+ if ((adapter->hw.device_id != E1000_DEV_ID_82573L) ||
+ (eeprom_data & EEPROM_WORD1A_ASPM_MASK)) {
if (max_frame > MAXIMUM_ETHERNET_FRAME_SIZE) {
DPRINTK(PROBE, ERR,
"Jumbo Frames not supported.\n");
@@ -3143,6 +3212,8 @@ e1000_change_mtu(struct net_device *netdev, int new_mtu)
}
break;
}
+ /* ERT will be enabled later to enable wire speed receives */
+
/* fall through to get support */
case e1000_82571:
case e1000_82572:
@@ -3328,16 +3399,15 @@ e1000_update_stats(struct e1000_adapter *adapter)
adapter->stats.crcerrs + adapter->stats.algnerrc +
adapter->stats.ruc + adapter->stats.roc +
adapter->stats.cexterr;
- adapter->net_stats.rx_length_errors = adapter->stats.ruc +
- adapter->stats.roc;
+ adapter->stats.rlerrc = adapter->stats.ruc + adapter->stats.roc;
+ adapter->net_stats.rx_length_errors = adapter->stats.rlerrc;
adapter->net_stats.rx_crc_errors = adapter->stats.crcerrs;
adapter->net_stats.rx_frame_errors = adapter->stats.algnerrc;
adapter->net_stats.rx_missed_errors = adapter->stats.mpc;
/* Tx Errors */
-
- adapter->net_stats.tx_errors = adapter->stats.ecol +
- adapter->stats.latecol;
+ adapter->stats.txerrc = adapter->stats.ecol + adapter->stats.latecol;
+ adapter->net_stats.tx_errors = adapter->stats.txerrc;
adapter->net_stats.tx_aborted_errors = adapter->stats.ecol;
adapter->net_stats.tx_window_errors = adapter->stats.latecol;
adapter->net_stats.tx_carrier_errors = adapter->stats.tncrs;
@@ -3408,7 +3478,9 @@ e1000_intr(int irq, void *data, struct pt_regs *regs)
rctl = E1000_READ_REG(hw, RCTL);
E1000_WRITE_REG(hw, RCTL, rctl & ~E1000_RCTL_EN);
}
- mod_timer(&adapter->watchdog_timer, jiffies);
+ /* guard against interrupt when we're going down */
+ if (!test_bit(__E1000_DOWN, &adapter->flags))
+ mod_timer(&adapter->watchdog_timer, jiffies + 1);
}
#ifdef CONFIG_E1000_NAPI
@@ -3546,13 +3618,14 @@ e1000_clean_tx_irq(struct e1000_adapter *adapter,
tx_ring->next_to_clean = i;
#define TX_WAKE_THRESHOLD 32
- if (unlikely(cleaned && netif_queue_stopped(netdev) &&
- netif_carrier_ok(netdev))) {
- spin_lock(&tx_ring->tx_lock);
- if (netif_queue_stopped(netdev) &&
- (E1000_DESC_UNUSED(tx_ring) >= TX_WAKE_THRESHOLD))
+ if (unlikely(cleaned && netif_carrier_ok(netdev) &&
+ E1000_DESC_UNUSED(tx_ring) >= TX_WAKE_THRESHOLD)) {
+ /* Make sure that anybody stopping the queue after this
+ * sees the new next_to_clean.
+ */
+ smp_mb();
+ if (netif_queue_stopped(netdev))
netif_wake_queue(netdev);
- spin_unlock(&tx_ring->tx_lock);
}
if (adapter->detect_tx_hung) {
@@ -4412,13 +4485,21 @@ e1000_write_pci_cfg(struct e1000_hw *hw, uint32_t reg, uint16_t *value)
pci_write_config_word(adapter->pdev, reg, *value);
}
-#if 0
-uint32_t
-e1000_io_read(struct e1000_hw *hw, unsigned long port)
+int32_t
+e1000_read_pcie_cap_reg(struct e1000_hw *hw, uint32_t reg, uint16_t *value)
{
- return inl(port);
+ struct e1000_adapter *adapter = hw->back;
+ uint16_t cap_offset;
+
+ cap_offset = pci_find_capability(adapter->pdev, PCI_CAP_ID_EXP);
+ if (!cap_offset)
+ return -E1000_ERR_CONFIG;
+
+ pci_read_config_word(adapter->pdev, cap_offset + reg, value);
+
+ return E1000_SUCCESS;
}
-#endif /* 0 */
+
void
e1000_io_write(struct e1000_hw *hw, unsigned long port, uint32_t value)
@@ -4693,9 +4774,7 @@ e1000_suspend(struct pci_dev *pdev, pm_message_t state)
pci_enable_wake(pdev, PCI_D3cold, 0);
}
- /* FIXME: this code is incorrect for PCI Express */
- if (adapter->hw.mac_type >= e1000_82540 &&
- adapter->hw.mac_type != e1000_ich8lan &&
+ if (adapter->hw.mac_type < e1000_82571 &&
adapter->hw.media_type == e1000_media_type_copper) {
manc = E1000_READ_REG(&adapter->hw, MANC);
if (manc & E1000_MANC_SMBUS_EN) {
@@ -4747,9 +4826,7 @@ e1000_resume(struct pci_dev *pdev)
netif_device_attach(netdev);
- /* FIXME: this code is incorrect for PCI Express */
- if (adapter->hw.mac_type >= e1000_82540 &&
- adapter->hw.mac_type != e1000_ich8lan &&
+ if (adapter->hw.mac_type < e1000_82571 &&
adapter->hw.media_type == e1000_media_type_copper) {
manc = E1000_READ_REG(&adapter->hw, MANC);
manc &= ~(E1000_MANC_ARP_EN);
@@ -4835,8 +4912,8 @@ static pci_ers_result_t e1000_io_slot_reset(struct pci_dev *pdev)
}
pci_set_master(pdev);
- pci_enable_wake(pdev, 3, 0);
- pci_enable_wake(pdev, 4, 0); /* 4 == D3 cold */
+ pci_enable_wake(pdev, PCI_D3hot, 0);
+ pci_enable_wake(pdev, PCI_D3cold, 0);
/* Perform card reset only on one instance of the card */
if (PCI_FUNC (pdev->devfn) != 0)
diff --git a/drivers/net/e1000/e1000_osdep.h b/drivers/net/e1000/e1000_osdep.h
index 46bc49df15e7..a464cb290621 100644
--- a/drivers/net/e1000/e1000_osdep.h
+++ b/drivers/net/e1000/e1000_osdep.h
@@ -1,25 +1,24 @@
/*******************************************************************************
-
- Copyright(c) 1999 - 2006 Intel Corporation. All rights reserved.
-
- This program is free software; you can redistribute it and/or modify it
- under the terms of the GNU General Public License as published by the Free
- Software Foundation; 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
+ Intel PRO/1000 Linux driver
+ Copyright(c) 1999 - 2006 Intel Corporation.
+
+ This program is free software; you can redistribute it and/or modify it
+ under the terms and conditions of the GNU General Public License,
+ version 2, as published by the Free Software Foundation.
+
+ This program is distributed in the hope 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.
-
- The full GNU General Public License is included in this distribution in the
- file called LICENSE.
-
+ this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+
+ The full GNU General Public License is included in this distribution in
+ the file called "COPYING".
+
Contact Information:
Linux NICS <linux.nics@intel.com>
e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
diff --git a/drivers/net/e1000/e1000_param.c b/drivers/net/e1000/e1000_param.c
index 212842738972..9c3c1acefccc 100644
--- a/drivers/net/e1000/e1000_param.c
+++ b/drivers/net/e1000/e1000_param.c
@@ -1,25 +1,24 @@
/*******************************************************************************
-
- Copyright(c) 1999 - 2006 Intel Corporation. All rights reserved.
-
- This program is free software; you can redistribute it and/or modify it
- under the terms of the GNU General Public License as published by the Free
- Software Foundation; 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
+ Intel PRO/1000 Linux driver
+ Copyright(c) 1999 - 2006 Intel Corporation.
+
+ This program is free software; you can redistribute it and/or modify it
+ under the terms and conditions of the GNU General Public License,
+ version 2, as published by the Free Software Foundation.
+
+ This program is distributed in the hope 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.
-
- The full GNU General Public License is included in this distribution in the
- file called LICENSE.
-
+ this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+
+ The full GNU General Public License is included in this distribution in
+ the file called "COPYING".
+
Contact Information:
Linux NICS <linux.nics@intel.com>
e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
@@ -397,17 +396,17 @@ e1000_check_options(struct e1000_adapter *adapter)
{ /* Flow Control */
struct e1000_opt_list fc_list[] =
- {{ e1000_fc_none, "Flow Control Disabled" },
- { e1000_fc_rx_pause,"Flow Control Receive Only" },
- { e1000_fc_tx_pause,"Flow Control Transmit Only" },
- { e1000_fc_full, "Flow Control Enabled" },
- { e1000_fc_default, "Flow Control Hardware Default" }};
+ {{ E1000_FC_NONE, "Flow Control Disabled" },
+ { E1000_FC_RX_PAUSE,"Flow Control Receive Only" },
+ { E1000_FC_TX_PAUSE,"Flow Control Transmit Only" },
+ { E1000_FC_FULL, "Flow Control Enabled" },
+ { E1000_FC_DEFAULT, "Flow Control Hardware Default" }};
struct e1000_option opt = {
.type = list_option,
.name = "Flow Control",
.err = "reading default settings from EEPROM",
- .def = e1000_fc_default,
+ .def = E1000_FC_DEFAULT,
.arg = { .l = { .nr = ARRAY_SIZE(fc_list),
.p = fc_list }}
};
diff --git a/drivers/net/fec_8xx/fec_main.c b/drivers/net/fec_8xx/fec_main.c
index 22ac2df1aeb0..e17a1449ee10 100644
--- a/drivers/net/fec_8xx/fec_main.c
+++ b/drivers/net/fec_8xx/fec_main.c
@@ -30,6 +30,7 @@
#include <linux/mii.h>
#include <linux/ethtool.h>
#include <linux/bitops.h>
+#include <linux/dma-mapping.h>
#include <asm/8xx_immap.h>
#include <asm/pgtable.h>
@@ -37,7 +38,6 @@
#include <asm/irq.h>
#include <asm/uaccess.h>
#include <asm/commproc.h>
-#include <asm/dma-mapping.h>
#include "fec_8xx.h"
diff --git a/drivers/net/fs_enet/fs_enet-main.c b/drivers/net/fs_enet/fs_enet-main.c
index 34412bc7c4b6..d01870619a4a 100644
--- a/drivers/net/fs_enet/fs_enet-main.c
+++ b/drivers/net/fs_enet/fs_enet-main.c
@@ -944,12 +944,13 @@ extern int fs_mii_connect(struct net_device *dev);
extern void fs_mii_disconnect(struct net_device *dev);
static struct net_device *fs_init_instance(struct device *dev,
- const struct fs_platform_info *fpi)
+ struct fs_platform_info *fpi)
{
struct net_device *ndev = NULL;
struct fs_enet_private *fep = NULL;
int privsize, i, r, err = 0, registered = 0;
+ fpi->fs_no = fs_get_id(fpi);
/* guard */
if ((unsigned int)fpi->fs_no >= FS_MAX_INDEX)
return ERR_PTR(-EINVAL);
@@ -971,7 +972,7 @@ static struct net_device *fs_init_instance(struct device *dev,
dev_set_drvdata(dev, ndev);
fep->fpi = fpi;
if (fpi->init_ioports)
- fpi->init_ioports();
+ fpi->init_ioports((struct fs_platform_info *)fpi);
#ifdef CONFIG_FS_ENET_HAS_FEC
if (fs_get_fec_index(fpi->fs_no) >= 0)
diff --git a/drivers/net/fs_enet/fs_enet.h b/drivers/net/fs_enet/fs_enet.h
index 95022c005f75..92590d8fc24b 100644
--- a/drivers/net/fs_enet/fs_enet.h
+++ b/drivers/net/fs_enet/fs_enet.h
@@ -6,11 +6,10 @@
#include <linux/types.h>
#include <linux/list.h>
#include <linux/phy.h>
+#include <linux/dma-mapping.h>
#include <linux/fs_enet_pd.h>
-#include <asm/dma-mapping.h>
-
#ifdef CONFIG_CPM1
#include <asm/commproc.h>
diff --git a/drivers/net/hp100.c b/drivers/net/hp100.c
index 03b3df33d81b..ae8ad4f763bf 100644
--- a/drivers/net/hp100.c
+++ b/drivers/net/hp100.c
@@ -188,10 +188,12 @@ struct hp100_private {
/*
* variables
*/
+#ifdef CONFIG_ISA
static const char *hp100_isa_tbl[] = {
"HWPF150", /* HP J2573 rev A */
"HWP1950", /* HP J2573 */
};
+#endif
#ifdef CONFIG_EISA
static struct eisa_device_id hp100_eisa_tbl[] = {
@@ -333,6 +335,7 @@ static __devinit const char *hp100_read_id(int ioaddr)
return str;
}
+#ifdef CONFIG_ISA
static __init int hp100_isa_probe1(struct net_device *dev, int ioaddr)
{
const char *sig;
@@ -390,9 +393,9 @@ static int __init hp100_isa_probe(struct net_device *dev, int addr)
}
return err;
}
+#endif /* CONFIG_ISA */
-
-#ifndef MODULE
+#if !defined(MODULE) && defined(CONFIG_ISA)
struct net_device * __init hp100_probe(int unit)
{
struct net_device *dev = alloc_etherdev(sizeof(struct hp100_private));
@@ -422,7 +425,7 @@ struct net_device * __init hp100_probe(int unit)
free_netdev(dev);
return ERR_PTR(err);
}
-#endif
+#endif /* !MODULE && CONFIG_ISA */
static int __devinit hp100_probe1(struct net_device *dev, int ioaddr,
u_char bus, struct pci_dev *pci_dev)
diff --git a/drivers/net/ifb.c b/drivers/net/ifb.c
index 6469130c1413..c26a4b8e552a 100644
--- a/drivers/net/ifb.c
+++ b/drivers/net/ifb.c
@@ -200,8 +200,8 @@ static struct net_device_stats *ifb_get_stats(struct net_device *dev)
pr_debug("tasklets stats %ld:%ld:%ld:%ld:%ld:%ld:%ld:%ld:%ld \n",
dp->st_task_enter, dp->st_txq_refl_try, dp->st_rxq_enter,
- dp->st_rx2tx_tran dp->st_rxq_notenter, dp->st_rx_frm_egr,
- dp->st_rx_frm_ing, dp->st_rxq_check, dp->st_rxq_rsch );
+ dp->st_rx2tx_tran, dp->st_rxq_notenter, dp->st_rx_frm_egr,
+ dp->st_rx_frm_ing, dp->st_rxq_check, dp->st_rxq_rsch);
return stats;
}
diff --git a/drivers/net/irda/Kconfig b/drivers/net/irda/Kconfig
index e9e6d99a9add..7c8ccc09b601 100644
--- a/drivers/net/irda/Kconfig
+++ b/drivers/net/irda/Kconfig
@@ -287,6 +287,7 @@ comment "FIR device drivers"
config USB_IRDA
tristate "IrDA USB dongles"
depends on IRDA && USB
+ select FW_LOADER
---help---
Say Y here if you want to build support for the USB IrDA FIR Dongle
device driver. To compile it as a module, choose M here: the module
diff --git a/drivers/net/irda/nsc-ircc.c b/drivers/net/irda/nsc-ircc.c
index cb62f2a9676a..7185a4ee3c1e 100644
--- a/drivers/net/irda/nsc-ircc.c
+++ b/drivers/net/irda/nsc-ircc.c
@@ -110,7 +110,7 @@ static nsc_chip_t chips[] = {
{ "PC87338", { 0x398, 0x15c, 0x2e }, 0x08, 0xb0, 0xf8,
nsc_ircc_probe_338, nsc_ircc_init_338 },
/* Contributed by Steffen Pingel - IBM X40 */
- { "PC8738x", { 0x164e, 0x4e, 0x0 }, 0x20, 0xf4, 0xff,
+ { "PC8738x", { 0x164e, 0x4e, 0x2e }, 0x20, 0xf4, 0xff,
nsc_ircc_probe_39x, nsc_ircc_init_39x },
/* Contributed by Jan Frey - IBM A30/A31 */
{ "PC8739x", { 0x2e, 0x4e, 0x0 }, 0x20, 0xea, 0xff,
diff --git a/drivers/net/irda/smsc-ircc2.c b/drivers/net/irda/smsc-ircc2.c
index 2eff45bedc7c..22358ff68c4c 100644
--- a/drivers/net/irda/smsc-ircc2.c
+++ b/drivers/net/irda/smsc-ircc2.c
@@ -2354,6 +2354,26 @@ static int __init smsc_superio_lpc(unsigned short cfg_base)
#define PCIID_VENDOR_INTEL 0x8086
#define PCIID_VENDOR_ALI 0x10b9
static struct smsc_ircc_subsystem_configuration subsystem_configurations[] __initdata = {
+ /*
+ * Subsystems needing entries:
+ * 0x10b9:0x1533 0x103c:0x0850 HP nx9010 family
+ * 0x10b9:0x1533 0x0e11:0x005a Compaq nc4000 family
+ * 0x8086:0x24cc 0x0e11:0x002a HP nx9000 family
+ */
+ {
+ /* Guessed entry */
+ .vendor = PCIID_VENDOR_INTEL, /* Intel 82801DBM LPC bridge */
+ .device = 0x24cc,
+ .subvendor = 0x103c,
+ .subdevice = 0x08bc,
+ .sir_io = 0x02f8,
+ .fir_io = 0x0130,
+ .fir_irq = 0x05,
+ .fir_dma = 0x03,
+ .cfg_base = 0x004e,
+ .preconfigure = preconfigure_through_82801,
+ .name = "HP nx5000 family",
+ },
{
.vendor = PCIID_VENDOR_INTEL, /* Intel 82801DBM LPC bridge */
.device = 0x24cc,
@@ -2366,7 +2386,7 @@ static struct smsc_ircc_subsystem_configuration subsystem_configurations[] __ini
.fir_dma = 0x03,
.cfg_base = 0x004e,
.preconfigure = preconfigure_through_82801,
- .name = "HP nc8000",
+ .name = "HP nc8000 family",
},
{
.vendor = PCIID_VENDOR_INTEL, /* Intel 82801DBM LPC bridge */
@@ -2379,7 +2399,21 @@ static struct smsc_ircc_subsystem_configuration subsystem_configurations[] __ini
.fir_dma = 0x03,
.cfg_base = 0x004e,
.preconfigure = preconfigure_through_82801,
- .name = "HP nc6000",
+ .name = "HP nc6000 family",
+ },
+ {
+ .vendor = PCIID_VENDOR_INTEL, /* Intel 82801DBM LPC bridge */
+ .device = 0x24cc,
+ .subvendor = 0x0e11,
+ .subdevice = 0x0860,
+ /* I assume these are the same for x1000 as for the others */
+ .sir_io = 0x02e8,
+ .fir_io = 0x02f8,
+ .fir_irq = 0x07,
+ .fir_dma = 0x03,
+ .cfg_base = 0x002e,
+ .preconfigure = preconfigure_through_82801,
+ .name = "Compaq x1000 family",
},
{
/* Intel 82801DB/DBL (ICH4/ICH4-L) LPC Interface Bridge */
diff --git a/drivers/net/irda/stir4200.c b/drivers/net/irda/stir4200.c
index d61b208b52a2..12103c93f7ef 100644
--- a/drivers/net/irda/stir4200.c
+++ b/drivers/net/irda/stir4200.c
@@ -149,8 +149,6 @@ enum StirFifoCtlMask {
FIFOCTL_DIR = 0x10,
FIFOCTL_CLR = 0x08,
FIFOCTL_EMPTY = 0x04,
- FIFOCTL_RXERR = 0x02,
- FIFOCTL_TXERR = 0x01,
};
enum StirDiagMask {
@@ -615,19 +613,6 @@ static int fifo_txwait(struct stir_cb *stir, int space)
pr_debug("fifo status 0x%lx count %lu\n", status, count);
- /* error when receive/transmit fifo gets confused */
- if (status & FIFOCTL_RXERR) {
- stir->stats.rx_fifo_errors++;
- stir->stats.rx_errors++;
- break;
- }
-
- if (status & FIFOCTL_TXERR) {
- stir->stats.tx_fifo_errors++;
- stir->stats.tx_errors++;
- break;
- }
-
/* is fifo receiving already, or empty */
if (!(status & FIFOCTL_DIR)
|| (status & FIFOCTL_EMPTY))
diff --git a/drivers/net/irda/via-ircc.c b/drivers/net/irda/via-ircc.c
index 79b85f327500..d916e1257c47 100644
--- a/drivers/net/irda/via-ircc.c
+++ b/drivers/net/irda/via-ircc.c
@@ -1223,8 +1223,13 @@ static int upload_rxdata(struct via_ircc_cb *self, int iobase)
IRDA_DEBUG(2, "%s(): len=%x\n", __FUNCTION__, len);
+ if ((len - 4) < 2) {
+ self->stats.rx_dropped++;
+ return FALSE;
+ }
+
skb = dev_alloc_skb(len + 1);
- if ((skb == NULL) || ((len - 4) < 2)) {
+ if (skb == NULL) {
self->stats.rx_dropped++;
return FALSE;
}
diff --git a/drivers/net/ixgb/Makefile b/drivers/net/ixgb/Makefile
index a8a2d3d03567..838a5084fa00 100644
--- a/drivers/net/ixgb/Makefile
+++ b/drivers/net/ixgb/Makefile
@@ -1,33 +1,33 @@
################################################################################
#
-#
-# Copyright(c) 1999 - 2006 Intel Corporation. All rights reserved.
-#
-# This program is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License as published by the Free
-# Software Foundation; 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
+# Intel PRO/10GbE Linux driver
+# Copyright(c) 1999 - 2006 Intel Corporation.
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms and conditions of the GNU General Public License,
+# version 2, as published by the Free Software Foundation.
+#
+# This program is distributed in the hope 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.
-#
-# The full GNU General Public License is included in this distribution in the
-# file called LICENSE.
-#
+# this program; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# The full GNU General Public License is included in this distribution in
+# the file called "COPYING".
+#
# Contact Information:
# Linux NICS <linux.nics@intel.com>
+# e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
# Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
#
################################################################################
#
-# Makefile for the Intel(R) PRO/10GbE driver
+# Makefile for the Intel(R) PRO/10GbE ethernet driver
#
obj-$(CONFIG_IXGB) += ixgb.o
diff --git a/drivers/net/ixgb/ixgb.h b/drivers/net/ixgb/ixgb.h
index a51604b3651f..50ffe90488ff 100644
--- a/drivers/net/ixgb/ixgb.h
+++ b/drivers/net/ixgb/ixgb.h
@@ -1,27 +1,27 @@
/*******************************************************************************
-
- Copyright(c) 1999 - 2006 Intel Corporation. All rights reserved.
-
- This program is free software; you can redistribute it and/or modify it
- under the terms of the GNU General Public License as published by the Free
- Software Foundation; 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
+ Intel PRO/10GbE Linux driver
+ Copyright(c) 1999 - 2006 Intel Corporation.
+
+ This program is free software; you can redistribute it and/or modify it
+ under the terms and conditions of the GNU General Public License,
+ version 2, as published by the Free Software Foundation.
+
+ This program is distributed in the hope 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.
-
- The full GNU General Public License is included in this distribution in the
- file called LICENSE.
-
+ this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+
+ The full GNU General Public License is included in this distribution in
+ the file called "COPYING".
+
Contact Information:
Linux NICS <linux.nics@intel.com>
+ e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
*******************************************************************************/
@@ -111,7 +111,7 @@ struct ixgb_adapter;
#define IXGB_RXBUFFER_16384 16384
/* How many Rx Buffers do we bundle into one write to the hardware ? */
-#define IXGB_RX_BUFFER_WRITE 4 /* Must be power of 2 */
+#define IXGB_RX_BUFFER_WRITE 8 /* Must be power of 2 */
/* only works for sizes that are powers of 2 */
#define IXGB_ROUNDUP(i, size) ((i) = (((i) + (size) - 1) & ~((size) - 1)))
diff --git a/drivers/net/ixgb/ixgb_ee.c b/drivers/net/ixgb/ixgb_ee.c
index 8357c5590bfb..f15aebde7b90 100644
--- a/drivers/net/ixgb/ixgb_ee.c
+++ b/drivers/net/ixgb/ixgb_ee.c
@@ -1,27 +1,27 @@
/*******************************************************************************
-
- Copyright(c) 1999 - 2006 Intel Corporation. All rights reserved.
-
- This program is free software; you can redistribute it and/or modify it
- under the terms of the GNU General Public License as published by the Free
- Software Foundation; 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
+ Intel PRO/10GbE Linux driver
+ Copyright(c) 1999 - 2006 Intel Corporation.
+
+ This program is free software; you can redistribute it and/or modify it
+ under the terms and conditions of the GNU General Public License,
+ version 2, as published by the Free Software Foundation.
+
+ This program is distributed in the hope 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.
-
- The full GNU General Public License is included in this distribution in the
- file called LICENSE.
-
+ this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+
+ The full GNU General Public License is included in this distribution in
+ the file called "COPYING".
+
Contact Information:
Linux NICS <linux.nics@intel.com>
+ e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
*******************************************************************************/
diff --git a/drivers/net/ixgb/ixgb_ee.h b/drivers/net/ixgb/ixgb_ee.h
index bf6fa220f38e..ef236b935c15 100644
--- a/drivers/net/ixgb/ixgb_ee.h
+++ b/drivers/net/ixgb/ixgb_ee.h
@@ -1,27 +1,27 @@
/*******************************************************************************
-
- Copyright(c) 1999 - 2006 Intel Corporation. All rights reserved.
-
- This program is free software; you can redistribute it and/or modify it
- under the terms of the GNU General Public License as published by the Free
- Software Foundation; 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
+ Intel PRO/10GbE Linux driver
+ Copyright(c) 1999 - 2006 Intel Corporation.
+
+ This program is free software; you can redistribute it and/or modify it
+ under the terms and conditions of the GNU General Public License,
+ version 2, as published by the Free Software Foundation.
+
+ This program is distributed in the hope 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.
-
- The full GNU General Public License is included in this distribution in the
- file called LICENSE.
-
+ this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+
+ The full GNU General Public License is included in this distribution in
+ the file called "COPYING".
+
Contact Information:
Linux NICS <linux.nics@intel.com>
+ e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
*******************************************************************************/
diff --git a/drivers/net/ixgb/ixgb_ethtool.c b/drivers/net/ixgb/ixgb_ethtool.c
index 64a383e4e892..cd22523fb035 100644
--- a/drivers/net/ixgb/ixgb_ethtool.c
+++ b/drivers/net/ixgb/ixgb_ethtool.c
@@ -1,27 +1,27 @@
/*******************************************************************************
-
- Copyright(c) 1999 - 2006 Intel Corporation. All rights reserved.
-
- This program is free software; you can redistribute it and/or modify it
- under the terms of the GNU General Public License as published by the Free
- Software Foundation; 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
+ Intel PRO/10GbE Linux driver
+ Copyright(c) 1999 - 2006 Intel Corporation.
+
+ This program is free software; you can redistribute it and/or modify it
+ under the terms and conditions of the GNU General Public License,
+ version 2, as published by the Free Software Foundation.
+
+ This program is distributed in the hope 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.
-
- The full GNU General Public License is included in this distribution in the
- file called LICENSE.
-
+ this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+
+ The full GNU General Public License is included in this distribution in
+ the file called "COPYING".
+
Contact Information:
Linux NICS <linux.nics@intel.com>
+ e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
*******************************************************************************/
diff --git a/drivers/net/ixgb/ixgb_hw.c b/drivers/net/ixgb/ixgb_hw.c
index acc6df7a6b38..02089b64e42c 100644
--- a/drivers/net/ixgb/ixgb_hw.c
+++ b/drivers/net/ixgb/ixgb_hw.c
@@ -1,27 +1,27 @@
/*******************************************************************************
-
- Copyright(c) 1999 - 2006 Intel Corporation. All rights reserved.
-
- This program is free software; you can redistribute it and/or modify it
- under the terms of the GNU General Public License as published by the Free
- Software Foundation; 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
+ Intel PRO/10GbE Linux driver
+ Copyright(c) 1999 - 2006 Intel Corporation.
+
+ This program is free software; you can redistribute it and/or modify it
+ under the terms and conditions of the GNU General Public License,
+ version 2, as published by the Free Software Foundation.
+
+ This program is distributed in the hope 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.
-
- The full GNU General Public License is included in this distribution in the
- file called LICENSE.
-
+ this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+
+ The full GNU General Public License is included in this distribution in
+ the file called "COPYING".
+
Contact Information:
Linux NICS <linux.nics@intel.com>
+ e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
*******************************************************************************/
diff --git a/drivers/net/ixgb/ixgb_hw.h b/drivers/net/ixgb/ixgb_hw.h
index cb4568915ada..40ef5ca88717 100644
--- a/drivers/net/ixgb/ixgb_hw.h
+++ b/drivers/net/ixgb/ixgb_hw.h
@@ -1,27 +1,27 @@
/*******************************************************************************
-
- Copyright(c) 1999 - 2006 Intel Corporation. All rights reserved.
-
- This program is free software; you can redistribute it and/or modify it
- under the terms of the GNU General Public License as published by the Free
- Software Foundation; 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
+ Intel PRO/10GbE Linux driver
+ Copyright(c) 1999 - 2006 Intel Corporation.
+
+ This program is free software; you can redistribute it and/or modify it
+ under the terms and conditions of the GNU General Public License,
+ version 2, as published by the Free Software Foundation.
+
+ This program is distributed in the hope 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.
-
- The full GNU General Public License is included in this distribution in the
- file called LICENSE.
-
+ this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+
+ The full GNU General Public License is included in this distribution in
+ the file called "COPYING".
+
Contact Information:
Linux NICS <linux.nics@intel.com>
+ e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
*******************************************************************************/
diff --git a/drivers/net/ixgb/ixgb_ids.h b/drivers/net/ixgb/ixgb_ids.h
index 9fd61189b4b2..4376e7e8fbef 100644
--- a/drivers/net/ixgb/ixgb_ids.h
+++ b/drivers/net/ixgb/ixgb_ids.h
@@ -1,27 +1,27 @@
/*******************************************************************************
-
- Copyright(c) 1999 - 2006 Intel Corporation. All rights reserved.
-
- This program is free software; you can redistribute it and/or modify it
- under the terms of the GNU General Public License as published by the Free
- Software Foundation; 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
+ Intel PRO/10GbE Linux driver
+ Copyright(c) 1999 - 2006 Intel Corporation.
+
+ This program is free software; you can redistribute it and/or modify it
+ under the terms and conditions of the GNU General Public License,
+ version 2, as published by the Free Software Foundation.
+
+ This program is distributed in the hope 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.
-
- The full GNU General Public License is included in this distribution in the
- file called LICENSE.
-
+ this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+
+ The full GNU General Public License is included in this distribution in
+ the file called "COPYING".
+
Contact Information:
Linux NICS <linux.nics@intel.com>
+ e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
*******************************************************************************/
diff --git a/drivers/net/ixgb/ixgb_main.c b/drivers/net/ixgb/ixgb_main.c
index 2e0f4b950a90..cfde7c2569bb 100644
--- a/drivers/net/ixgb/ixgb_main.c
+++ b/drivers/net/ixgb/ixgb_main.c
@@ -1,27 +1,27 @@
/*******************************************************************************
-
- Copyright(c) 1999 - 2006 Intel Corporation. All rights reserved.
-
- This program is free software; you can redistribute it and/or modify it
- under the terms of the GNU General Public License as published by the Free
- Software Foundation; 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
+ Intel PRO/10GbE Linux driver
+ Copyright(c) 1999 - 2006 Intel Corporation.
+
+ This program is free software; you can redistribute it and/or modify it
+ under the terms and conditions of the GNU General Public License,
+ version 2, as published by the Free Software Foundation.
+
+ This program is distributed in the hope 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.
-
- The full GNU General Public License is included in this distribution in the
- file called LICENSE.
-
+ this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+
+ The full GNU General Public License is included in this distribution in
+ the file called "COPYING".
+
Contact Information:
Linux NICS <linux.nics@intel.com>
+ e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
*******************************************************************************/
@@ -36,7 +36,7 @@ static char ixgb_driver_string[] = "Intel(R) PRO/10GbE Network Driver";
#else
#define DRIVERNAPI "-NAPI"
#endif
-#define DRV_VERSION "1.0.112-k2"DRIVERNAPI
+#define DRV_VERSION "1.0.117-k2"DRIVERNAPI
char ixgb_driver_version[] = DRV_VERSION;
static char ixgb_copyright[] = "Copyright (c) 1999-2006 Intel Corporation.";
@@ -437,7 +437,7 @@ ixgb_probe(struct pci_dev *pdev,
netdev->poll_controller = ixgb_netpoll;
#endif
- strcpy(netdev->name, pci_name(pdev));
+ strncpy(netdev->name, pci_name(pdev), sizeof(netdev->name) - 1);
netdev->mem_start = mmio_start;
netdev->mem_end = mmio_start + mmio_len;
netdev->base_addr = adapter->hw.io_base;
@@ -2230,7 +2230,7 @@ static pci_ers_result_t ixgb_io_error_detected (struct pci_dev *pdev,
enum pci_channel_state state)
{
struct net_device *netdev = pci_get_drvdata(pdev);
- struct ixgb_adapter *adapter = netdev->priv;
+ struct ixgb_adapter *adapter = netdev_priv(netdev);
if(netif_running(netdev))
ixgb_down(adapter, TRUE);
@@ -2253,7 +2253,7 @@ static pci_ers_result_t ixgb_io_error_detected (struct pci_dev *pdev,
static pci_ers_result_t ixgb_io_slot_reset (struct pci_dev *pdev)
{
struct net_device *netdev = pci_get_drvdata(pdev);
- struct ixgb_adapter *adapter = netdev->priv;
+ struct ixgb_adapter *adapter = netdev_priv(netdev);
if(pci_enable_device(pdev)) {
DPRINTK(PROBE, ERR, "Cannot re-enable PCI device after reset.\n");
@@ -2297,7 +2297,7 @@ static pci_ers_result_t ixgb_io_slot_reset (struct pci_dev *pdev)
static void ixgb_io_resume (struct pci_dev *pdev)
{
struct net_device *netdev = pci_get_drvdata(pdev);
- struct ixgb_adapter *adapter = netdev->priv;
+ struct ixgb_adapter *adapter = netdev_priv(netdev);
pci_set_master(pdev);
diff --git a/drivers/net/ixgb/ixgb_osdep.h b/drivers/net/ixgb/ixgb_osdep.h
index 19cb1d586dec..8434d752fd81 100644
--- a/drivers/net/ixgb/ixgb_osdep.h
+++ b/drivers/net/ixgb/ixgb_osdep.h
@@ -1,27 +1,27 @@
/*******************************************************************************
-
- Copyright(c) 1999 - 2006 Intel Corporation. All rights reserved.
-
- This program is free software; you can redistribute it and/or modify it
- under the terms of the GNU General Public License as published by the Free
- Software Foundation; 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
+ Intel PRO/10GbE Linux driver
+ Copyright(c) 1999 - 2006 Intel Corporation.
+
+ This program is free software; you can redistribute it and/or modify it
+ under the terms and conditions of the GNU General Public License,
+ version 2, as published by the Free Software Foundation.
+
+ This program is distributed in the hope 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.
-
- The full GNU General Public License is included in this distribution in the
- file called LICENSE.
-
+ this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+
+ The full GNU General Public License is included in this distribution in
+ the file called "COPYING".
+
Contact Information:
Linux NICS <linux.nics@intel.com>
+ e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
*******************************************************************************/
diff --git a/drivers/net/ixgb/ixgb_param.c b/drivers/net/ixgb/ixgb_param.c
index 39fbed29a3df..b27442a121f2 100644
--- a/drivers/net/ixgb/ixgb_param.c
+++ b/drivers/net/ixgb/ixgb_param.c
@@ -1,27 +1,27 @@
/*******************************************************************************
-
- Copyright(c) 1999 - 2006 Intel Corporation. All rights reserved.
-
- This program is free software; you can redistribute it and/or modify it
- under the terms of the GNU General Public License as published by the Free
- Software Foundation; 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
+ Intel PRO/10GbE Linux driver
+ Copyright(c) 1999 - 2006 Intel Corporation.
+
+ This program is free software; you can redistribute it and/or modify it
+ under the terms and conditions of the GNU General Public License,
+ version 2, as published by the Free Software Foundation.
+
+ This program is distributed in the hope 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.
-
- The full GNU General Public License is included in this distribution in the
- file called LICENSE.
-
+ this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+
+ The full GNU General Public License is included in this distribution in
+ the file called "COPYING".
+
Contact Information:
Linux NICS <linux.nics@intel.com>
+ e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
*******************************************************************************/
diff --git a/drivers/net/loopback.c b/drivers/net/loopback.c
index f429b19bf620..4178b4b1d2df 100644
--- a/drivers/net/loopback.c
+++ b/drivers/net/loopback.c
@@ -161,15 +161,13 @@ static int loopback_xmit(struct sk_buff *skb, struct net_device *dev)
return(0);
}
+static struct net_device_stats loopback_stats;
+
static struct net_device_stats *get_stats(struct net_device *dev)
{
- struct net_device_stats *stats = dev->priv;
+ struct net_device_stats *stats = &loopback_stats;
int i;
- if (!stats) {
- return NULL;
- }
-
memset(stats, 0, sizeof(struct net_device_stats));
for_each_possible_cpu(i) {
@@ -185,19 +183,28 @@ static struct net_device_stats *get_stats(struct net_device *dev)
return stats;
}
-static u32 loopback_get_link(struct net_device *dev)
+static u32 always_on(struct net_device *dev)
{
return 1;
}
static const struct ethtool_ops loopback_ethtool_ops = {
- .get_link = loopback_get_link,
+ .get_link = always_on,
.get_tso = ethtool_op_get_tso,
.set_tso = ethtool_op_set_tso,
+ .get_tx_csum = always_on,
+ .get_sg = always_on,
+ .get_rx_csum = always_on,
};
+/*
+ * The loopback device is special. There is only one instance and
+ * it is statically allocated. Don't do this for other devices.
+ */
struct net_device loopback_dev = {
.name = "lo",
+ .get_stats = &get_stats,
+ .priv = &loopback_stats,
.mtu = (16 * 1024) + 20 + 20 + 12,
.hard_start_xmit = loopback_xmit,
.hard_header = eth_header,
@@ -221,16 +228,6 @@ struct net_device loopback_dev = {
/* Setup and register the loopback device. */
int __init loopback_init(void)
{
- struct net_device_stats *stats;
-
- /* Can survive without statistics */
- stats = kmalloc(sizeof(struct net_device_stats), GFP_KERNEL);
- if (stats) {
- memset(stats, 0, sizeof(struct net_device_stats));
- loopback_dev.priv = stats;
- loopback_dev.get_stats = &get_stats;
- }
-
return register_netdev(&loopback_dev);
};
diff --git a/drivers/net/phy/fixed.c b/drivers/net/phy/fixed.c
index 19f7ee63276f..94b47c8d0ab4 100644
--- a/drivers/net/phy/fixed.c
+++ b/drivers/net/phy/fixed.c
@@ -289,9 +289,13 @@ static int fixed_mdio_register_device(int number, int speed, int duplex)
goto probe_fail;
}
- device_bind_driver(&phydev->dev);
+ err = device_bind_driver(&phydev->dev);
+
up_write(&phydev->dev.bus->subsys.rwsem);
+ if (err)
+ goto probe_fail;
+
return 0;
probe_fail:
diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c
index ecd3da151e2d..3bbd5e70c209 100644
--- a/drivers/net/phy/phy_device.c
+++ b/drivers/net/phy/phy_device.c
@@ -212,11 +212,13 @@ struct phy_device *phy_attach(struct net_device *dev,
err = d->driver->probe(d);
- if (err < 0)
- return ERR_PTR(err);
+ if (err >= 0)
+ err = device_bind_driver(d);
- device_bind_driver(d);
up_write(&d->bus->subsys.rwsem);
+
+ if (err)
+ return ERR_PTR(err);
}
if (phydev->attached_dev) {
diff --git a/drivers/net/pppoe.c b/drivers/net/pppoe.c
index 5666ed998142..0adee733b761 100644
--- a/drivers/net/pppoe.c
+++ b/drivers/net/pppoe.c
@@ -600,6 +600,7 @@ static int pppoe_connect(struct socket *sock, struct sockaddr *uservaddr,
po->chan.hdrlen = (sizeof(struct pppoe_hdr) +
dev->hard_header_len);
+ po->chan.mtu = dev->mtu - sizeof(struct pppoe_hdr);
po->chan.private = sk;
po->chan.ops = &pppoe_chan_ops;
diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c
index 7eeefa2d6c89..396e7df3c61b 100644
--- a/drivers/net/sky2.c
+++ b/drivers/net/sky2.c
@@ -50,19 +50,18 @@
#include "sky2.h"
#define DRV_NAME "sky2"
-#define DRV_VERSION "1.7"
+#define DRV_VERSION "1.9"
#define PFX DRV_NAME " "
/*
* The Yukon II chipset takes 64 bit command blocks (called list elements)
* that are organized into three (receive, transmit, status) different rings
- * similar to Tigon3. A transmit can require several elements;
- * a receive requires one (or two if using 64 bit dma).
+ * similar to Tigon3.
*/
-#define RX_LE_SIZE 512
+#define RX_LE_SIZE 1024
#define RX_LE_BYTES (RX_LE_SIZE*sizeof(struct sky2_rx_le))
-#define RX_MAX_PENDING (RX_LE_SIZE/2 - 2)
+#define RX_MAX_PENDING (RX_LE_SIZE/6 - 2)
#define RX_DEF_PENDING RX_MAX_PENDING
#define RX_SKB_ALIGN 8
#define RX_BUF_WRITE 16
@@ -74,7 +73,6 @@
#define STATUS_RING_SIZE 2048 /* 2 ports * (TX + 2*RX) */
#define STATUS_LE_BYTES (STATUS_RING_SIZE*sizeof(struct sky2_status_le))
-#define ETH_JUMBO_MTU 9000
#define TX_WATCHDOG (5 * HZ)
#define NAPI_WEIGHT 64
#define PHY_RETRIES 1000
@@ -90,7 +88,7 @@ static int debug = -1; /* defaults above */
module_param(debug, int, 0);
MODULE_PARM_DESC(debug, "Debug level (0=none,...,16=all)");
-static int copybreak __read_mostly = 256;
+static int copybreak __read_mostly = 128;
module_param(copybreak, int, 0);
MODULE_PARM_DESC(copybreak, "Receive copy threshold");
@@ -769,9 +767,16 @@ static inline struct sky2_tx_le *get_tx_le(struct sky2_port *sky2)
struct sky2_tx_le *le = sky2->tx_le + sky2->tx_prod;
sky2->tx_prod = RING_NEXT(sky2->tx_prod, TX_RING_SIZE);
+ le->ctrl = 0;
return le;
}
+static inline struct tx_ring_info *tx_le_re(struct sky2_port *sky2,
+ struct sky2_tx_le *le)
+{
+ return sky2->tx_ring + (le - sky2->tx_le);
+}
+
/* Update chip's next pointer */
static inline void sky2_put_idx(struct sky2_hw *hw, unsigned q, u16 idx)
{
@@ -786,6 +791,7 @@ static inline struct sky2_rx_le *sky2_next_rx(struct sky2_port *sky2)
{
struct sky2_rx_le *le = sky2->rx_le + sky2->rx_put;
sky2->rx_put = RING_NEXT(sky2->rx_put, RX_LE_SIZE);
+ le->ctrl = 0;
return le;
}
@@ -795,17 +801,16 @@ static inline u32 high32(dma_addr_t a)
return sizeof(a) > sizeof(u32) ? (a >> 16) >> 16 : 0;
}
-/* Build description to hardware about buffer */
-static void sky2_rx_add(struct sky2_port *sky2, dma_addr_t map)
+/* Build description to hardware for one receive segment */
+static void sky2_rx_add(struct sky2_port *sky2, u8 op,
+ dma_addr_t map, unsigned len)
{
struct sky2_rx_le *le;
u32 hi = high32(map);
- u16 len = sky2->rx_bufsize;
if (sky2->rx_addr64 != hi) {
le = sky2_next_rx(sky2);
le->addr = cpu_to_le32(hi);
- le->ctrl = 0;
le->opcode = OP_ADDR64 | HW_OWNER;
sky2->rx_addr64 = high32(map + len);
}
@@ -813,11 +818,53 @@ static void sky2_rx_add(struct sky2_port *sky2, dma_addr_t map)
le = sky2_next_rx(sky2);
le->addr = cpu_to_le32((u32) map);
le->length = cpu_to_le16(len);
- le->ctrl = 0;
- le->opcode = OP_PACKET | HW_OWNER;
+ le->opcode = op | HW_OWNER;
+}
+
+/* Build description to hardware for one possibly fragmented skb */
+static void sky2_rx_submit(struct sky2_port *sky2,
+ const struct rx_ring_info *re)
+{
+ int i;
+
+ sky2_rx_add(sky2, OP_PACKET, re->data_addr, sky2->rx_data_size);
+
+ for (i = 0; i < skb_shinfo(re->skb)->nr_frags; i++)
+ sky2_rx_add(sky2, OP_BUFFER, re->frag_addr[i], PAGE_SIZE);
}
+static void sky2_rx_map_skb(struct pci_dev *pdev, struct rx_ring_info *re,
+ unsigned size)
+{
+ struct sk_buff *skb = re->skb;
+ int i;
+
+ re->data_addr = pci_map_single(pdev, skb->data, size, PCI_DMA_FROMDEVICE);
+ pci_unmap_len_set(re, data_size, size);
+
+ for (i = 0; i < skb_shinfo(skb)->nr_frags; i++)
+ re->frag_addr[i] = pci_map_page(pdev,
+ skb_shinfo(skb)->frags[i].page,
+ skb_shinfo(skb)->frags[i].page_offset,
+ skb_shinfo(skb)->frags[i].size,
+ PCI_DMA_FROMDEVICE);
+}
+
+static void sky2_rx_unmap_skb(struct pci_dev *pdev, struct rx_ring_info *re)
+{
+ struct sk_buff *skb = re->skb;
+ int i;
+
+ pci_unmap_single(pdev, re->data_addr, pci_unmap_len(re, data_size),
+ PCI_DMA_FROMDEVICE);
+
+ for (i = 0; i < skb_shinfo(skb)->nr_frags; i++)
+ pci_unmap_page(pdev, re->frag_addr[i],
+ skb_shinfo(skb)->frags[i].size,
+ PCI_DMA_FROMDEVICE);
+}
+
/* Tell chip where to start receive checksum.
* Actually has two checksums, but set both same to avoid possible byte
* order problems.
@@ -877,12 +924,10 @@ static void sky2_rx_clean(struct sky2_port *sky2)
memset(sky2->rx_le, 0, RX_LE_BYTES);
for (i = 0; i < sky2->rx_pending; i++) {
- struct ring_info *re = sky2->rx_ring + i;
+ struct rx_ring_info *re = sky2->rx_ring + i;
if (re->skb) {
- pci_unmap_single(sky2->hw->pdev,
- re->mapaddr, sky2->rx_bufsize,
- PCI_DMA_FROMDEVICE);
+ sky2_rx_unmap_skb(sky2->hw->pdev, re);
kfree_skb(re->skb);
re->skb = NULL;
}
@@ -936,13 +981,13 @@ static void sky2_vlan_rx_register(struct net_device *dev, struct vlan_group *grp
struct sky2_hw *hw = sky2->hw;
u16 port = sky2->port;
- spin_lock_bh(&sky2->tx_lock);
+ netif_tx_lock_bh(dev);
sky2_write32(hw, SK_REG(port, RX_GMF_CTRL_T), RX_VLAN_STRIP_ON);
sky2_write32(hw, SK_REG(port, TX_GMF_CTRL_T), TX_VLAN_TAG_ON);
sky2->vlgrp = grp;
- spin_unlock_bh(&sky2->tx_lock);
+ netif_tx_unlock_bh(dev);
}
static void sky2_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid)
@@ -951,50 +996,69 @@ static void sky2_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid)
struct sky2_hw *hw = sky2->hw;
u16 port = sky2->port;
- spin_lock_bh(&sky2->tx_lock);
+ netif_tx_lock_bh(dev);
sky2_write32(hw, SK_REG(port, RX_GMF_CTRL_T), RX_VLAN_STRIP_OFF);
sky2_write32(hw, SK_REG(port, TX_GMF_CTRL_T), TX_VLAN_TAG_OFF);
if (sky2->vlgrp)
sky2->vlgrp->vlan_devices[vid] = NULL;
- spin_unlock_bh(&sky2->tx_lock);
+ netif_tx_unlock_bh(dev);
}
#endif
/*
+ * Allocate an skb for receiving. If the MTU is large enough
+ * make the skb non-linear with a fragment list of pages.
+ *
* It appears the hardware has a bug in the FIFO logic that
* cause it to hang if the FIFO gets overrun and the receive buffer
* is not 64 byte aligned. The buffer returned from netdev_alloc_skb is
* aligned except if slab debugging is enabled.
*/
-static inline struct sk_buff *sky2_alloc_skb(struct net_device *dev,
- unsigned int length,
- gfp_t gfp_mask)
+static struct sk_buff *sky2_rx_alloc(struct sky2_port *sky2)
{
struct sk_buff *skb;
+ unsigned long p;
+ int i;
- skb = __netdev_alloc_skb(dev, length + RX_SKB_ALIGN, gfp_mask);
- if (likely(skb)) {
- unsigned long p = (unsigned long) skb->data;
- skb_reserve(skb, ALIGN(p, RX_SKB_ALIGN) - p);
+ skb = netdev_alloc_skb(sky2->netdev, sky2->rx_data_size + RX_SKB_ALIGN);
+ if (!skb)
+ goto nomem;
+
+ p = (unsigned long) skb->data;
+ skb_reserve(skb, ALIGN(p, RX_SKB_ALIGN) - p);
+
+ for (i = 0; i < sky2->rx_nfrags; i++) {
+ struct page *page = alloc_page(GFP_ATOMIC);
+
+ if (!page)
+ goto free_partial;
+ skb_fill_page_desc(skb, i, page, 0, PAGE_SIZE);
}
return skb;
+free_partial:
+ kfree_skb(skb);
+nomem:
+ return NULL;
}
/*
* Allocate and setup receiver buffer pool.
- * In case of 64 bit dma, there are 2X as many list elements
- * available as ring entries
- * and need to reserve one list element so we don't wrap around.
+ * Normal case this ends up creating one list element for skb
+ * in the receive ring. Worst case if using large MTU and each
+ * allocation falls on a different 64 bit region, that results
+ * in 6 list elements per ring entry.
+ * One element is used for checksum enable/disable, and one
+ * extra to avoid wrap.
*/
static int sky2_rx_start(struct sky2_port *sky2)
{
struct sky2_hw *hw = sky2->hw;
+ struct rx_ring_info *re;
unsigned rxq = rxqaddr[sky2->port];
- int i;
- unsigned thresh;
+ unsigned i, size, space, thresh;
sky2->rx_put = sky2->rx_next = 0;
sky2_qset(hw, rxq);
@@ -1007,27 +1071,56 @@ static int sky2_rx_start(struct sky2_port *sky2)
sky2_prefetch_init(hw, rxq, sky2->rx_le_map, RX_LE_SIZE - 1);
rx_set_checksum(sky2);
+
+ /* Space needed for frame data + headers rounded up */
+ size = ALIGN(sky2->netdev->mtu + ETH_HLEN + VLAN_HLEN, 8)
+ + 8;
+
+ /* Stopping point for hardware truncation */
+ thresh = (size - 8) / sizeof(u32);
+
+ /* Account for overhead of skb - to avoid order > 0 allocation */
+ space = SKB_DATA_ALIGN(size) + NET_SKB_PAD
+ + sizeof(struct skb_shared_info);
+
+ sky2->rx_nfrags = space >> PAGE_SHIFT;
+ BUG_ON(sky2->rx_nfrags > ARRAY_SIZE(re->frag_addr));
+
+ if (sky2->rx_nfrags != 0) {
+ /* Compute residue after pages */
+ space = sky2->rx_nfrags << PAGE_SHIFT;
+
+ if (space < size)
+ size -= space;
+ else
+ size = 0;
+
+ /* Optimize to handle small packets and headers */
+ if (size < copybreak)
+ size = copybreak;
+ if (size < ETH_HLEN)
+ size = ETH_HLEN;
+ }
+ sky2->rx_data_size = size;
+
+ /* Fill Rx ring */
for (i = 0; i < sky2->rx_pending; i++) {
- struct ring_info *re = sky2->rx_ring + i;
+ re = sky2->rx_ring + i;
- re->skb = sky2_alloc_skb(sky2->netdev, sky2->rx_bufsize,
- GFP_KERNEL);
+ re->skb = sky2_rx_alloc(sky2);
if (!re->skb)
goto nomem;
- re->mapaddr = pci_map_single(hw->pdev, re->skb->data,
- sky2->rx_bufsize, PCI_DMA_FROMDEVICE);
- sky2_rx_add(sky2, re->mapaddr);
+ sky2_rx_map_skb(hw->pdev, re, sky2->rx_data_size);
+ sky2_rx_submit(sky2, re);
}
-
/*
* The receiver hangs if it receives frames larger than the
* packet buffer. As a workaround, truncate oversize frames, but
* the register is limited to 9 bits, so if you do frames > 2052
* you better get the MTU right!
*/
- thresh = (sky2->rx_bufsize - 8) / sizeof(u32);
if (thresh > 0x1ff)
sky2_write32(hw, SK_REG(sky2->port, RX_GMF_CTRL_T), RX_TRUNC_OFF);
else {
@@ -1035,7 +1128,6 @@ static int sky2_rx_start(struct sky2_port *sky2)
sky2_write32(hw, SK_REG(sky2->port, RX_GMF_CTRL_T), RX_TRUNC_ON);
}
-
/* Tell chip about available buffers */
sky2_write16(hw, Y2_QADDR(rxq, PREF_UNIT_PUT_IDX), sky2->rx_put);
return 0;
@@ -1094,7 +1186,7 @@ static int sky2_up(struct net_device *dev)
goto err_out;
memset(sky2->rx_le, 0, RX_LE_BYTES);
- sky2->rx_ring = kcalloc(sky2->rx_pending, sizeof(struct ring_info),
+ sky2->rx_ring = kcalloc(sky2->rx_pending, sizeof(struct rx_ring_info),
GFP_KERNEL);
if (!sky2->rx_ring)
goto err_out;
@@ -1124,7 +1216,8 @@ static int sky2_up(struct net_device *dev)
sky2_qset(hw, txqaddr[port]);
/* Set almost empty threshold */
- if (hw->chip_id == CHIP_ID_YUKON_EC_U && hw->chip_rev == 1)
+ if (hw->chip_id == CHIP_ID_YUKON_EC_U
+ && hw->chip_rev == CHIP_REV_YU_EC_U_A0)
sky2_write16(hw, Q_ADDR(txqaddr[port], Q_AL), 0x1a0);
sky2_prefetch_init(hw, txqaddr[port], sky2->tx_le_map,
@@ -1195,8 +1288,6 @@ static unsigned tx_le_req(const struct sk_buff *skb)
* A single packet can generate multiple list elements, and
* the number of ring elements will probably be less than the number
* of list elements used.
- *
- * No BH disabling for tx_lock here (like tg3)
*/
static int sky2_xmit_frame(struct sk_buff *skb, struct net_device *dev)
{
@@ -1210,27 +1301,8 @@ static int sky2_xmit_frame(struct sk_buff *skb, struct net_device *dev)
u16 mss;
u8 ctrl;
- /* No BH disabling for tx_lock here. We are running in BH disabled
- * context and TX reclaim runs via poll inside of a software
- * interrupt, and no related locks in IRQ processing.
- */
- if (!spin_trylock(&sky2->tx_lock))
- return NETDEV_TX_LOCKED;
-
- if (unlikely(tx_avail(sky2) < tx_le_req(skb))) {
- /* There is a known but harmless race with lockless tx
- * and netif_stop_queue.
- */
- if (!netif_queue_stopped(dev)) {
- netif_stop_queue(dev);
- if (net_ratelimit())
- printk(KERN_WARNING PFX "%s: ring full when queue awake!\n",
- dev->name);
- }
- spin_unlock(&sky2->tx_lock);
-
- return NETDEV_TX_BUSY;
- }
+ if (unlikely(tx_avail(sky2) < tx_le_req(skb)))
+ return NETDEV_TX_BUSY;
if (unlikely(netif_msg_tx_queued(sky2)))
printk(KERN_DEBUG "%s: tx queued, slot %u, len %d\n",
@@ -1240,13 +1312,10 @@ static int sky2_xmit_frame(struct sk_buff *skb, struct net_device *dev)
mapping = pci_map_single(hw->pdev, skb->data, len, PCI_DMA_TODEVICE);
addr64 = high32(mapping);
- re = sky2->tx_ring + sky2->tx_prod;
-
/* Send high bits if changed or crosses boundary */
if (addr64 != sky2->tx_addr64 || high32(mapping + len) != sky2->tx_addr64) {
le = get_tx_le(sky2);
le->addr = cpu_to_le32(addr64);
- le->ctrl = 0;
le->opcode = OP_ADDR64 | HW_OWNER;
sky2->tx_addr64 = high32(mapping + len);
}
@@ -1262,7 +1331,6 @@ static int sky2_xmit_frame(struct sk_buff *skb, struct net_device *dev)
le = get_tx_le(sky2);
le->addr = cpu_to_le32(mss);
le->opcode = OP_LRGLEN | HW_OWNER;
- le->ctrl = 0;
sky2->tx_last_mss = mss;
}
}
@@ -1275,7 +1343,6 @@ static int sky2_xmit_frame(struct sk_buff *skb, struct net_device *dev)
le = get_tx_le(sky2);
le->addr = 0;
le->opcode = OP_VLAN|HW_OWNER;
- le->ctrl = 0;
} else
le->opcode |= OP_VLAN;
le->length = cpu_to_be16(vlan_tx_tag_get(skb));
@@ -1312,13 +1379,13 @@ static int sky2_xmit_frame(struct sk_buff *skb, struct net_device *dev)
le->ctrl = ctrl;
le->opcode = mss ? (OP_LARGESEND | HW_OWNER) : (OP_PACKET | HW_OWNER);
- /* Record the transmit mapping info */
+ re = tx_le_re(sky2, le);
re->skb = skb;
pci_unmap_addr_set(re, mapaddr, mapping);
+ pci_unmap_len_set(re, maplen, len);
for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
- skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
- struct tx_ring_info *fre;
+ const skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
mapping = pci_map_page(hw->pdev, frag->page, frag->page_offset,
frag->size, PCI_DMA_TODEVICE);
@@ -1337,12 +1404,12 @@ static int sky2_xmit_frame(struct sk_buff *skb, struct net_device *dev)
le->ctrl = ctrl;
le->opcode = OP_BUFFER | HW_OWNER;
- fre = sky2->tx_ring
- + RING_NEXT((re - sky2->tx_ring) + i, TX_RING_SIZE);
- pci_unmap_addr_set(fre, mapaddr, mapping);
+ re = tx_le_re(sky2, le);
+ re->skb = skb;
+ pci_unmap_addr_set(re, mapaddr, mapping);
+ pci_unmap_len_set(re, maplen, frag->size);
}
- re->idx = sky2->tx_prod;
le->ctrl |= EOP;
if (tx_avail(sky2) <= MAX_SKB_TX_LE)
@@ -1350,8 +1417,6 @@ static int sky2_xmit_frame(struct sk_buff *skb, struct net_device *dev)
sky2_put_idx(hw, txqaddr[sky2->port], sky2->tx_prod);
- spin_unlock(&sky2->tx_lock);
-
dev->trans_start = jiffies;
return NETDEV_TX_OK;
}
@@ -1360,59 +1425,59 @@ static int sky2_xmit_frame(struct sk_buff *skb, struct net_device *dev)
* Free ring elements from starting at tx_cons until "done"
*
* NB: the hardware will tell us about partial completion of multi-part
- * buffers; these are deferred until completion.
+ * buffers so make sure not to free skb to early.
*/
static void sky2_tx_complete(struct sky2_port *sky2, u16 done)
{
struct net_device *dev = sky2->netdev;
struct pci_dev *pdev = sky2->hw->pdev;
- u16 nxt, put;
- unsigned i;
+ unsigned idx;
BUG_ON(done >= TX_RING_SIZE);
- if (unlikely(netif_msg_tx_done(sky2)))
- printk(KERN_DEBUG "%s: tx done, up to %u\n",
- dev->name, done);
-
- for (put = sky2->tx_cons; put != done; put = nxt) {
- struct tx_ring_info *re = sky2->tx_ring + put;
- struct sk_buff *skb = re->skb;
-
- nxt = re->idx;
- BUG_ON(nxt >= TX_RING_SIZE);
- prefetch(sky2->tx_ring + nxt);
-
- /* Check for partial status */
- if (tx_dist(put, done) < tx_dist(put, nxt))
+ for (idx = sky2->tx_cons; idx != done;
+ idx = RING_NEXT(idx, TX_RING_SIZE)) {
+ struct sky2_tx_le *le = sky2->tx_le + idx;
+ struct tx_ring_info *re = sky2->tx_ring + idx;
+
+ switch(le->opcode & ~HW_OWNER) {
+ case OP_LARGESEND:
+ case OP_PACKET:
+ pci_unmap_single(pdev,
+ pci_unmap_addr(re, mapaddr),
+ pci_unmap_len(re, maplen),
+ PCI_DMA_TODEVICE);
break;
-
- skb = re->skb;
- pci_unmap_single(pdev, pci_unmap_addr(re, mapaddr),
- skb_headlen(skb), PCI_DMA_TODEVICE);
-
- for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
- struct tx_ring_info *fre;
- fre = sky2->tx_ring + RING_NEXT(put + i, TX_RING_SIZE);
- pci_unmap_page(pdev, pci_unmap_addr(fre, mapaddr),
- skb_shinfo(skb)->frags[i].size,
+ case OP_BUFFER:
+ pci_unmap_page(pdev, pci_unmap_addr(re, mapaddr),
+ pci_unmap_len(re, maplen),
PCI_DMA_TODEVICE);
+ break;
}
- dev_kfree_skb(skb);
+ if (le->ctrl & EOP) {
+ if (unlikely(netif_msg_tx_done(sky2)))
+ printk(KERN_DEBUG "%s: tx done %u\n",
+ dev->name, idx);
+ dev_kfree_skb(re->skb);
+ }
+
+ le->opcode = 0; /* paranoia */
}
- sky2->tx_cons = put;
+ sky2->tx_cons = idx;
if (tx_avail(sky2) > MAX_SKB_TX_LE + 4)
netif_wake_queue(dev);
}
/* Cleanup all untransmitted buffers, assume transmitter not running */
-static void sky2_tx_clean(struct sky2_port *sky2)
+static void sky2_tx_clean(struct net_device *dev)
{
- spin_lock_bh(&sky2->tx_lock);
+ struct sky2_port *sky2 = netdev_priv(dev);
+
+ netif_tx_lock_bh(dev);
sky2_tx_complete(sky2, sky2->tx_prod);
- spin_unlock_bh(&sky2->tx_lock);
+ netif_tx_unlock_bh(dev);
}
/* Network shutdown */
@@ -1443,6 +1508,13 @@ static int sky2_down(struct net_device *dev)
sky2_write32(hw, RB_ADDR(txqaddr[port], RB_CTRL),
RB_RST_SET | RB_DIS_OP_MD);
+ /* WA for dev. #4.209 */
+ if (hw->chip_id == CHIP_ID_YUKON_EC_U
+ && hw->chip_rev == CHIP_REV_YU_EC_U_A1)
+ sky2_write32(hw, SK_REG(port, TX_GMF_CTRL_T),
+ sky2->speed != SPEED_1000 ?
+ TX_STFW_ENA : TX_STFW_DIS);
+
ctrl = gma_read16(hw, port, GM_GP_CTRL);
ctrl &= ~(GM_GPCR_TX_ENA | GM_GPCR_RX_ENA);
gma_write16(hw, port, GM_GP_CTRL, ctrl);
@@ -1489,7 +1561,7 @@ static int sky2_down(struct net_device *dev)
synchronize_irq(hw->pdev->irq);
- sky2_tx_clean(sky2);
+ sky2_tx_clean(dev);
sky2_rx_clean(sky2);
pci_free_consistent(hw->pdev, RX_LE_BYTES,
@@ -1624,22 +1696,33 @@ static int sky2_autoneg_done(struct sky2_port *sky2, u16 aux)
return -1;
}
- if (hw->chip_id != CHIP_ID_YUKON_FE &&
- gm_phy_read(hw, port, PHY_MARV_1000T_STAT) & PHY_B_1000S_MSF) {
- printk(KERN_ERR PFX "%s: master/slave fault",
- sky2->netdev->name);
- return -1;
- }
-
if (!(aux & PHY_M_PS_SPDUP_RES)) {
printk(KERN_ERR PFX "%s: speed/duplex mismatch",
sky2->netdev->name);
return -1;
}
- sky2->duplex = (aux & PHY_M_PS_FULL_DUP) ? DUPLEX_FULL : DUPLEX_HALF;
-
sky2->speed = sky2_phy_speed(hw, aux);
+ if (sky2->speed == SPEED_1000) {
+ u16 ctl2 = gm_phy_read(hw, port, PHY_MARV_1000T_CTRL);
+ u16 lpa2 = gm_phy_read(hw, port, PHY_MARV_1000T_STAT);
+ if (lpa2 & PHY_B_1000S_MSF) {
+ printk(KERN_ERR PFX "%s: master/slave fault",
+ sky2->netdev->name);
+ return -1;
+ }
+
+ if ((ctl2 & PHY_M_1000C_AFD) && (lpa2 & PHY_B_1000S_LP_FD))
+ sky2->duplex = DUPLEX_FULL;
+ else
+ sky2->duplex = DUPLEX_HALF;
+ } else {
+ u16 adv = gm_phy_read(hw, port, PHY_MARV_AUNE_ADV);
+ if ((aux & adv) & PHY_AN_FULL)
+ sky2->duplex = DUPLEX_FULL;
+ else
+ sky2->duplex = DUPLEX_HALF;
+ }
/* Pause bits are offset (9..8) */
if (hw->chip_id == CHIP_ID_YUKON_XL || hw->chip_id == CHIP_ID_YUKON_EC_U)
@@ -1730,31 +1813,22 @@ static void sky2_tx_timeout(struct net_device *dev)
} else if (report != sky2->tx_cons) {
printk(KERN_INFO PFX "status report lost?\n");
- spin_lock_bh(&sky2->tx_lock);
+ netif_tx_lock_bh(dev);
sky2_tx_complete(sky2, report);
- spin_unlock_bh(&sky2->tx_lock);
+ netif_tx_unlock_bh(dev);
} else {
printk(KERN_INFO PFX "hardware hung? flushing\n");
sky2_write32(hw, Q_ADDR(txq, Q_CSR), BMU_STOP);
sky2_write32(hw, Y2_QADDR(txq, PREF_UNIT_CTRL), PREF_UNIT_RST_SET);
- sky2_tx_clean(sky2);
+ sky2_tx_clean(dev);
sky2_qset(hw, txq);
sky2_prefetch_init(hw, txq, sky2->tx_le_map, TX_RING_SIZE - 1);
}
}
-
-/* Want receive buffer size to be multiple of 64 bits
- * and incl room for vlan and truncation
- */
-static inline unsigned sky2_buf_size(int mtu)
-{
- return ALIGN(mtu + ETH_HLEN + VLAN_HLEN, 8) + 8;
-}
-
static int sky2_change_mtu(struct net_device *dev, int new_mtu)
{
struct sky2_port *sky2 = netdev_priv(dev);
@@ -1789,7 +1863,7 @@ static int sky2_change_mtu(struct net_device *dev, int new_mtu)
sky2_rx_clean(sky2);
dev->mtu = new_mtu;
- sky2->rx_bufsize = sky2_buf_size(new_mtu);
+
mode = DATA_BLIND_VAL(DATA_BLIND_DEF) |
GM_SMOD_VLAN_ENA | IPG_DATA_VAL(IPG_DATA_DEF);
@@ -1815,16 +1889,100 @@ static int sky2_change_mtu(struct net_device *dev, int new_mtu)
return err;
}
+/* For small just reuse existing skb for next receive */
+static struct sk_buff *receive_copy(struct sky2_port *sky2,
+ const struct rx_ring_info *re,
+ unsigned length)
+{
+ struct sk_buff *skb;
+
+ skb = netdev_alloc_skb(sky2->netdev, length + 2);
+ if (likely(skb)) {
+ skb_reserve(skb, 2);
+ pci_dma_sync_single_for_cpu(sky2->hw->pdev, re->data_addr,
+ length, PCI_DMA_FROMDEVICE);
+ memcpy(skb->data, re->skb->data, length);
+ skb->ip_summed = re->skb->ip_summed;
+ skb->csum = re->skb->csum;
+ pci_dma_sync_single_for_device(sky2->hw->pdev, re->data_addr,
+ length, PCI_DMA_FROMDEVICE);
+ re->skb->ip_summed = CHECKSUM_NONE;
+ __skb_put(skb, length);
+ }
+ return skb;
+}
+
+/* Adjust length of skb with fragments to match received data */
+static void skb_put_frags(struct sk_buff *skb, unsigned int hdr_space,
+ unsigned int length)
+{
+ int i, num_frags;
+ unsigned int size;
+
+ /* put header into skb */
+ size = min(length, hdr_space);
+ skb->tail += size;
+ skb->len += size;
+ length -= size;
+
+ num_frags = skb_shinfo(skb)->nr_frags;
+ for (i = 0; i < num_frags; i++) {
+ skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
+
+ if (length == 0) {
+ /* don't need this page */
+ __free_page(frag->page);
+ --skb_shinfo(skb)->nr_frags;
+ } else {
+ size = min(length, (unsigned) PAGE_SIZE);
+
+ frag->size = size;
+ skb->data_len += size;
+ skb->truesize += size;
+ skb->len += size;
+ length -= size;
+ }
+ }
+}
+
+/* Normal packet - take skb from ring element and put in a new one */
+static struct sk_buff *receive_new(struct sky2_port *sky2,
+ struct rx_ring_info *re,
+ unsigned int length)
+{
+ struct sk_buff *skb, *nskb;
+ unsigned hdr_space = sky2->rx_data_size;
+
+ pr_debug(PFX "receive new length=%d\n", length);
+
+ /* Don't be tricky about reusing pages (yet) */
+ nskb = sky2_rx_alloc(sky2);
+ if (unlikely(!nskb))
+ return NULL;
+
+ skb = re->skb;
+ sky2_rx_unmap_skb(sky2->hw->pdev, re);
+
+ prefetch(skb->data);
+ re->skb = nskb;
+ sky2_rx_map_skb(sky2->hw->pdev, re, hdr_space);
+
+ if (skb_shinfo(skb)->nr_frags)
+ skb_put_frags(skb, hdr_space, length);
+ else
+ skb_put(skb, hdr_space);
+ return skb;
+}
+
/*
* Receive one packet.
- * For small packets or errors, just reuse existing skb.
* For larger packets, get new buffer.
*/
static struct sk_buff *sky2_receive(struct net_device *dev,
u16 length, u32 status)
{
struct sky2_port *sky2 = netdev_priv(dev);
- struct ring_info *re = sky2->rx_ring + sky2->rx_next;
+ struct rx_ring_info *re = sky2->rx_ring + sky2->rx_next;
struct sk_buff *skb = NULL;
if (unlikely(netif_msg_rx_status(sky2)))
@@ -1843,40 +2001,12 @@ static struct sk_buff *sky2_receive(struct net_device *dev,
if (length > dev->mtu + ETH_HLEN)
goto oversize;
- if (length < copybreak) {
- skb = netdev_alloc_skb(dev, length + 2);
- if (!skb)
- goto resubmit;
-
- skb_reserve(skb, 2);
- pci_dma_sync_single_for_cpu(sky2->hw->pdev, re->mapaddr,
- length, PCI_DMA_FROMDEVICE);
- memcpy(skb->data, re->skb->data, length);
- skb->ip_summed = re->skb->ip_summed;
- skb->csum = re->skb->csum;
- pci_dma_sync_single_for_device(sky2->hw->pdev, re->mapaddr,
- length, PCI_DMA_FROMDEVICE);
- } else {
- struct sk_buff *nskb;
-
- nskb = sky2_alloc_skb(dev, sky2->rx_bufsize, GFP_ATOMIC);
- if (!nskb)
- goto resubmit;
-
- skb = re->skb;
- re->skb = nskb;
- pci_unmap_single(sky2->hw->pdev, re->mapaddr,
- sky2->rx_bufsize, PCI_DMA_FROMDEVICE);
- prefetch(skb->data);
-
- re->mapaddr = pci_map_single(sky2->hw->pdev, nskb->data,
- sky2->rx_bufsize, PCI_DMA_FROMDEVICE);
- }
-
- skb_put(skb, length);
+ if (length < copybreak)
+ skb = receive_copy(sky2, re, length);
+ else
+ skb = receive_new(sky2, re, length);
resubmit:
- re->skb->ip_summed = CHECKSUM_NONE;
- sky2_rx_add(sky2, re->mapaddr);
+ sky2_rx_submit(sky2, re);
return skb;
@@ -1909,9 +2039,9 @@ static inline void sky2_tx_done(struct net_device *dev, u16 last)
struct sky2_port *sky2 = netdev_priv(dev);
if (netif_running(dev)) {
- spin_lock(&sky2->tx_lock);
+ netif_tx_lock(dev);
sky2_tx_complete(sky2, last);
- spin_unlock(&sky2->tx_lock);
+ netif_tx_unlock(dev);
}
}
@@ -2082,7 +2212,7 @@ static void sky2_hw_intr(struct sky2_hw *hw)
sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_ON);
sky2_pci_write16(hw, PCI_STATUS,
- pci_err | PCI_STATUS_ERROR_BITS);
+ pci_err | PCI_STATUS_ERROR_BITS);
sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_OFF);
}
@@ -2090,7 +2220,8 @@ static void sky2_hw_intr(struct sky2_hw *hw)
/* PCI-Express uncorrectable Error occurred */
u32 pex_err;
- pex_err = sky2_pci_read32(hw, PEX_UNC_ERR_STAT);
+ pex_err = sky2_pci_read32(hw,
+ hw->err_cap + PCI_ERR_UNCOR_STATUS);
if (net_ratelimit())
printk(KERN_ERR PFX "%s: pci express error (0x%x)\n",
@@ -2098,15 +2229,20 @@ static void sky2_hw_intr(struct sky2_hw *hw)
/* clear the interrupt */
sky2_write32(hw, B2_TST_CTRL1, TST_CFG_WRITE_ON);
- sky2_pci_write32(hw, PEX_UNC_ERR_STAT,
- 0xffffffffUL);
+ sky2_pci_write32(hw,
+ hw->err_cap + PCI_ERR_UNCOR_STATUS,
+ 0xffffffffUL);
sky2_write32(hw, B2_TST_CTRL1, TST_CFG_WRITE_OFF);
- if (pex_err & PEX_FATAL_ERRORS) {
+
+ /* In case of fatal error mask off to keep from getting stuck */
+ if (pex_err & (PCI_ERR_UNC_POISON_TLP | PCI_ERR_UNC_FCP
+ | PCI_ERR_UNC_DLP)) {
u32 hwmsk = sky2_read32(hw, B0_HWE_IMSK);
hwmsk &= ~Y2_IS_PCI_EXP;
sky2_write32(hw, B0_HWE_IMSK, hwmsk);
}
+
}
if (status & Y2_HWE_L1_MASK)
@@ -2287,6 +2423,7 @@ static int sky2_reset(struct sky2_hw *hw)
u16 status;
u8 t8;
int i;
+ u32 msk;
sky2_write8(hw, B0_CTST, CS_RST_CLR);
@@ -2327,9 +2464,13 @@ static int sky2_reset(struct sky2_hw *hw)
sky2_write8(hw, B0_CTST, CS_MRST_CLR);
/* clear any PEX errors */
- if (pci_find_capability(hw->pdev, PCI_CAP_ID_EXP))
- sky2_pci_write32(hw, PEX_UNC_ERR_STAT, 0xffffffffUL);
-
+ if (pci_find_capability(hw->pdev, PCI_CAP_ID_EXP)) {
+ hw->err_cap = pci_find_ext_capability(hw->pdev, PCI_EXT_CAP_ID_ERR);
+ if (hw->err_cap)
+ sky2_pci_write32(hw,
+ hw->err_cap + PCI_ERR_UNCOR_STATUS,
+ 0xffffffffUL);
+ }
hw->pmd_type = sky2_read8(hw, B2_PMD_TYP);
hw->ports = 1;
@@ -2386,7 +2527,10 @@ static int sky2_reset(struct sky2_hw *hw)
sky2_write8(hw, RAM_BUFFER(i, B3_RI_RTO_XS2), SK_RI_TO_53);
}
- sky2_write32(hw, B0_HWE_IMSK, Y2_HWE_ALL_MASK);
+ msk = Y2_HWE_ALL_MASK;
+ if (!hw->err_cap)
+ msk &= ~Y2_IS_PCI_EXP;
+ sky2_write32(hw, B0_HWE_IMSK, msk);
for (i = 0; i < hw->ports; i++)
sky2_gmac_reset(hw, i);
@@ -3102,7 +3246,6 @@ static __devinit struct net_device *sky2_init_netdev(struct sky2_hw *hw,
sky2->hw = hw;
sky2->msg_enable = netif_msg_init(debug, default_msg);
- spin_lock_init(&sky2->tx_lock);
/* Auto speed and flow control */
sky2->autoneg = AUTONEG_ENABLE;
sky2->tx_pause = 1;
@@ -3115,13 +3258,11 @@ static __devinit struct net_device *sky2_init_netdev(struct sky2_hw *hw,
spin_lock_init(&sky2->phy_lock);
sky2->tx_pending = TX_DEF_PENDING;
sky2->rx_pending = RX_DEF_PENDING;
- sky2->rx_bufsize = sky2_buf_size(ETH_DATA_LEN);
hw->dev[port] = dev;
sky2->port = port;
- dev->features |= NETIF_F_LLTX;
if (hw->chip_id != CHIP_ID_YUKON_EC_U)
dev->features |= NETIF_F_TSO;
if (highmem)
@@ -3316,6 +3457,14 @@ static int __devinit sky2_probe(struct pci_dev *pdev,
if (!dev)
goto err_out_free_pci;
+ if (!disable_msi && pci_enable_msi(pdev) == 0) {
+ err = sky2_test_msi(hw);
+ if (err == -EOPNOTSUPP)
+ pci_disable_msi(pdev);
+ else if (err)
+ goto err_out_free_netdev;
+ }
+
err = register_netdev(dev);
if (err) {
printk(KERN_ERR PFX "%s: cannot register net device\n",
@@ -3323,6 +3472,14 @@ static int __devinit sky2_probe(struct pci_dev *pdev,
goto err_out_free_netdev;
}
+ err = request_irq(pdev->irq, sky2_intr, IRQF_SHARED, dev->name, hw);
+ if (err) {
+ printk(KERN_ERR PFX "%s: cannot assign irq %d\n",
+ pci_name(pdev), pdev->irq);
+ goto err_out_unregister;
+ }
+ sky2_write32(hw, B0_IMSK, Y2_IS_BASE);
+
sky2_show_addr(dev);
if (hw->ports > 1 && (dev1 = sky2_init_netdev(hw, 1, using_dac))) {
@@ -3337,23 +3494,6 @@ static int __devinit sky2_probe(struct pci_dev *pdev,
}
}
- if (!disable_msi && pci_enable_msi(pdev) == 0) {
- err = sky2_test_msi(hw);
- if (err == -EOPNOTSUPP)
- pci_disable_msi(pdev);
- else if (err)
- goto err_out_unregister;
- }
-
- err = request_irq(pdev->irq, sky2_intr, IRQF_SHARED, DRV_NAME, hw);
- if (err) {
- printk(KERN_ERR PFX "%s: cannot assign irq %d\n",
- pci_name(pdev), pdev->irq);
- goto err_out_unregister;
- }
-
- sky2_write32(hw, B0_IMSK, Y2_IS_BASE);
-
setup_timer(&hw->idle_timer, sky2_idle, (unsigned long) hw);
sky2_idle_start(hw);
@@ -3363,10 +3503,6 @@ static int __devinit sky2_probe(struct pci_dev *pdev,
err_out_unregister:
pci_disable_msi(pdev);
- if (dev1) {
- unregister_netdev(dev1);
- free_netdev(dev1);
- }
unregister_netdev(dev);
err_out_free_netdev:
free_netdev(dev);
diff --git a/drivers/net/sky2.h b/drivers/net/sky2.h
index 4c13c371bc21..f66109a96d95 100644
--- a/drivers/net/sky2.h
+++ b/drivers/net/sky2.h
@@ -4,24 +4,17 @@
#ifndef _SKY2_H
#define _SKY2_H
-/* PCI config registers */
+#define ETH_JUMBO_MTU 9000 /* Maximum MTU supported */
+
+/* PCI device specific config registers */
enum {
PCI_DEV_REG1 = 0x40,
PCI_DEV_REG2 = 0x44,
- PCI_DEV_STATUS = 0x7c,
PCI_DEV_REG3 = 0x80,
PCI_DEV_REG4 = 0x84,
PCI_DEV_REG5 = 0x88,
};
-enum {
- PEX_DEV_CAP = 0xe4,
- PEX_DEV_CTRL = 0xe8,
- PEX_DEV_STA = 0xea,
- PEX_LNK_STAT = 0xf2,
- PEX_UNC_ERR_STAT= 0x104,
-};
-
/* Yukon-2 */
enum pci_dev_reg_1 {
PCI_Y2_PIG_ENA = 1<<31, /* Enable Plug-in-Go (YUKON-2) */
@@ -70,39 +63,6 @@ enum pci_dev_reg_4 {
PCI_STATUS_REC_MASTER_ABORT | \
PCI_STATUS_REC_TARGET_ABORT | \
PCI_STATUS_PARITY)
-
-enum pex_dev_ctrl {
- PEX_DC_MAX_RRS_MSK = 7<<12, /* Bit 14..12: Max. Read Request Size */
- PEX_DC_EN_NO_SNOOP = 1<<11,/* Enable No Snoop */
- PEX_DC_EN_AUX_POW = 1<<10,/* Enable AUX Power */
- PEX_DC_EN_PHANTOM = 1<<9, /* Enable Phantom Functions */
- PEX_DC_EN_EXT_TAG = 1<<8, /* Enable Extended Tag Field */
- PEX_DC_MAX_PLS_MSK = 7<<5, /* Bit 7.. 5: Max. Payload Size Mask */
- PEX_DC_EN_REL_ORD = 1<<4, /* Enable Relaxed Ordering */
- PEX_DC_EN_UNS_RQ_RP = 1<<3, /* Enable Unsupported Request Reporting */
- PEX_DC_EN_FAT_ER_RP = 1<<2, /* Enable Fatal Error Reporting */
- PEX_DC_EN_NFA_ER_RP = 1<<1, /* Enable Non-Fatal Error Reporting */
- PEX_DC_EN_COR_ER_RP = 1<<0, /* Enable Correctable Error Reporting */
-};
-#define PEX_DC_MAX_RD_RQ_SIZE(x) (((x)<<12) & PEX_DC_MAX_RRS_MSK)
-
-/* PEX_UNC_ERR_STAT PEX Uncorrectable Errors Status Register (Yukon-2) */
-enum pex_err {
- PEX_UNSUP_REQ = 1<<20, /* Unsupported Request Error */
-
- PEX_MALFOR_TLP = 1<<18, /* Malformed TLP */
-
- PEX_UNEXP_COMP = 1<<16, /* Unexpected Completion */
-
- PEX_COMP_TO = 1<<14, /* Completion Timeout */
- PEX_FLOW_CTRL_P = 1<<13, /* Flow Control Protocol Error */
- PEX_POIS_TLP = 1<<12, /* Poisoned TLP */
-
- PEX_DATA_LINK_P = 1<<4, /* Data Link Protocol Error */
- PEX_FATAL_ERRORS= (PEX_MALFOR_TLP | PEX_FLOW_CTRL_P | PEX_DATA_LINK_P),
-};
-
-
enum csr_regs {
B0_RAP = 0x0000,
B0_CTST = 0x0004,
@@ -1816,12 +1776,14 @@ struct sky2_status_le {
struct tx_ring_info {
struct sk_buff *skb;
DECLARE_PCI_UNMAP_ADDR(mapaddr);
- u16 idx;
+ DECLARE_PCI_UNMAP_ADDR(maplen);
};
-struct ring_info {
+struct rx_ring_info {
struct sk_buff *skb;
- dma_addr_t mapaddr;
+ dma_addr_t data_addr;
+ DECLARE_PCI_UNMAP_ADDR(data_size);
+ dma_addr_t frag_addr[ETH_JUMBO_MTU >> PAGE_SHIFT];
};
struct sky2_port {
@@ -1831,7 +1793,6 @@ struct sky2_port {
u32 msg_enable;
spinlock_t phy_lock;
- spinlock_t tx_lock ____cacheline_aligned_in_smp;
struct tx_ring_info *tx_ring;
struct sky2_tx_le *tx_le;
u16 tx_cons; /* next le to check */
@@ -1841,13 +1802,15 @@ struct sky2_port {
u16 tx_last_mss;
u32 tx_tcpsum;
- struct ring_info *rx_ring ____cacheline_aligned_in_smp;
+ struct rx_ring_info *rx_ring ____cacheline_aligned_in_smp;
struct sky2_rx_le *rx_le;
u32 rx_addr64;
u16 rx_next; /* next re to check */
u16 rx_put; /* next le index to use */
u16 rx_pending;
- u16 rx_bufsize;
+ u16 rx_data_size;
+ u16 rx_nfrags;
+
#ifdef SKY2_VLAN_TAG_USED
u16 rx_tag;
struct vlan_group *vlgrp;
@@ -1873,6 +1836,7 @@ struct sky2_hw {
struct net_device *dev[2];
int pm_cap;
+ int err_cap;
u8 chip_id;
u8 chip_rev;
u8 pmd_type;
diff --git a/drivers/net/smc91x.h b/drivers/net/smc91x.h
index c660e33f43a2..fedd1a37bc3e 100644
--- a/drivers/net/smc91x.h
+++ b/drivers/net/smc91x.h
@@ -195,6 +195,7 @@ SMC_outw(u16 val, void __iomem *ioaddr, int reg)
#define SMC_IRQ_FLAGS (( \
machine_is_omap_h2() \
|| machine_is_omap_h3() \
+ || machine_is_omap_h4() \
|| (machine_is_omap_innovator() && !cpu_is_omap1510()) \
) ? IRQF_TRIGGER_FALLING : IRQF_TRIGGER_RISING)
diff --git a/drivers/net/spider_net.c b/drivers/net/spider_net.c
index cc240adb7269..1397fc55cf68 100644
--- a/drivers/net/spider_net.c
+++ b/drivers/net/spider_net.c
@@ -317,7 +317,7 @@ spider_net_init_chain(struct spider_net_card *card,
SPIDER_NET_DESCR_SIZE,
direction);
- if (buf == DMA_ERROR_CODE)
+ if (pci_dma_mapping_error(buf))
goto iommu_error;
descr->bus_addr = buf;
@@ -420,7 +420,7 @@ spider_net_prepare_rx_descr(struct spider_net_card *card,
buf = pci_map_single(card->pdev, descr->skb->data,
SPIDER_NET_MAX_FRAME, PCI_DMA_FROMDEVICE);
descr->buf_addr = buf;
- if (buf == DMA_ERROR_CODE) {
+ if (pci_dma_mapping_error(buf)) {
dev_kfree_skb_any(descr->skb);
if (netif_msg_rx_err(card) && net_ratelimit())
pr_err("Could not iommu-map rx buffer\n");
@@ -649,7 +649,7 @@ spider_net_prepare_tx_descr(struct spider_net_card *card,
dma_addr_t buf;
buf = pci_map_single(card->pdev, skb->data, skb->len, PCI_DMA_TODEVICE);
- if (buf == DMA_ERROR_CODE) {
+ if (pci_dma_mapping_error(buf)) {
if (netif_msg_tx_err(card) && net_ratelimit())
pr_err("could not iommu-map packet (%p, %i). "
"Dropping packet\n", skb->data, skb->len);
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c
index aaf45b907a78..c25ba273b745 100644
--- a/drivers/net/tg3.c
+++ b/drivers/net/tg3.c
@@ -68,8 +68,8 @@
#define DRV_MODULE_NAME "tg3"
#define PFX DRV_MODULE_NAME ": "
-#define DRV_MODULE_VERSION "3.65"
-#define DRV_MODULE_RELDATE "August 07, 2006"
+#define DRV_MODULE_VERSION "3.66"
+#define DRV_MODULE_RELDATE "September 23, 2006"
#define TG3_DEF_MAC_MODE 0
#define TG3_DEF_RX_MODE 0
@@ -173,6 +173,7 @@ static struct pci_device_id tg3_pci_tbl[] = {
{PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5705F)},
{PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5720)},
{PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5721)},
+ {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5722)},
{PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5750)},
{PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5751)},
{PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5750M)},
@@ -187,6 +188,7 @@ static struct pci_device_id tg3_pci_tbl[] = {
{PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5754M)},
{PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5755)},
{PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5755M)},
+ {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5756)},
{PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5786)},
{PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5787)},
{PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5787M)},
@@ -197,6 +199,8 @@ static struct pci_device_id tg3_pci_tbl[] = {
{PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5780)},
{PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5780S)},
{PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5781)},
+ {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5906)},
+ {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5906M)},
{PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, PCI_DEVICE_ID_SYSKONNECT_9DXX)},
{PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, PCI_DEVICE_ID_SYSKONNECT_9MXX)},
{PCI_DEVICE(PCI_VENDOR_ID_ALTIMA, PCI_DEVICE_ID_ALTIMA_AC1000)},
@@ -424,6 +428,16 @@ static void tg3_write32_tx_mbox(struct tg3 *tp, u32 off, u32 val)
readl(mbox);
}
+static u32 tg3_read32_mbox_5906(struct tg3 *tp, u32 off)
+{
+ return (readl(tp->regs + off + GRCMBOX_BASE));
+}
+
+static void tg3_write32_mbox_5906(struct tg3 *tp, u32 off, u32 val)
+{
+ writel(val, tp->regs + off + GRCMBOX_BASE);
+}
+
#define tw32_mailbox(reg, val) tp->write32_mbox(tp, reg, val)
#define tw32_mailbox_f(reg, val) tw32_mailbox_flush(tp, (reg), (val))
#define tw32_rx_mbox(reg, val) tp->write32_rx_mbox(tp, reg, val)
@@ -439,6 +453,10 @@ static void tg3_write_mem(struct tg3 *tp, u32 off, u32 val)
{
unsigned long flags;
+ if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) &&
+ (off >= NIC_SRAM_STATS_BLK) && (off < NIC_SRAM_TX_BUFFER_DESC))
+ return;
+
spin_lock_irqsave(&tp->indirect_lock, flags);
if (tp->tg3_flags & TG3_FLAG_SRAM_USE_CONFIG) {
pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_BASE_ADDR, off);
@@ -460,6 +478,12 @@ static void tg3_read_mem(struct tg3 *tp, u32 off, u32 *val)
{
unsigned long flags;
+ if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) &&
+ (off >= NIC_SRAM_STATS_BLK) && (off < NIC_SRAM_TX_BUFFER_DESC)) {
+ *val = 0;
+ return;
+ }
+
spin_lock_irqsave(&tp->indirect_lock, flags);
if (tp->tg3_flags & TG3_FLAG_SRAM_USE_CONFIG) {
pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_BASE_ADDR, off);
@@ -489,6 +513,9 @@ static inline void tg3_cond_int(struct tg3 *tp)
if (!(tp->tg3_flags & TG3_FLAG_TAGGED_STATUS) &&
(tp->hw_status->status & SD_STATUS_UPDATED))
tw32(GRC_LOCAL_CTRL, tp->grc_local_ctrl | GRC_LCLCTRL_SETINT);
+ else
+ tw32(HOSTCC_MODE, tp->coalesce_mode |
+ (HOSTCC_MODE_ENABLE | HOSTCC_MODE_NOW));
}
static void tg3_enable_ints(struct tg3 *tp)
@@ -654,6 +681,10 @@ static int tg3_writephy(struct tg3 *tp, int reg, u32 val)
unsigned int loops;
int ret;
+ if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906 &&
+ (reg == MII_TG3_CTRL || reg == MII_TG3_AUX_CTRL))
+ return 0;
+
if ((tp->mi_mode & MAC_MI_MODE_AUTO_POLL) != 0) {
tw32_f(MAC_MI_MODE,
(tp->mi_mode & ~MAC_MI_MODE_AUTO_POLL));
@@ -1004,6 +1035,24 @@ out:
phy_reg | MII_TG3_EXT_CTRL_FIFO_ELASTIC);
}
+ if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) {
+ u32 phy_reg;
+
+ /* adjust output voltage */
+ tg3_writephy(tp, MII_TG3_EPHY_PTEST, 0x12);
+
+ if (!tg3_readphy(tp, MII_TG3_EPHY_TEST, &phy_reg)) {
+ u32 phy_reg2;
+
+ tg3_writephy(tp, MII_TG3_EPHY_TEST,
+ phy_reg | MII_TG3_EPHY_SHADOW_EN);
+ /* Enable auto-MDIX */
+ if (!tg3_readphy(tp, 0x10, &phy_reg2))
+ tg3_writephy(tp, 0x10, phy_reg2 | 0x4000);
+ tg3_writephy(tp, MII_TG3_EPHY_TEST, phy_reg);
+ }
+ }
+
tg3_phy_set_wirespeed(tp);
return 0;
}
@@ -1117,6 +1166,15 @@ static void tg3_nvram_unlock(struct tg3 *);
static void tg3_power_down_phy(struct tg3 *tp)
{
+ if (tp->tg3_flags2 & TG3_FLG2_PHY_SERDES)
+ return;
+
+ if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5906) {
+ tg3_writephy(tp, MII_TG3_EXT_CTRL,
+ MII_TG3_EXT_CTRL_FORCE_LED_OFF);
+ tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x01b2);
+ }
+
/* The PHY should not be powered down on some chips because
* of bugs.
*/
@@ -1199,7 +1257,12 @@ static int tg3_set_power_state(struct tg3 *tp, pci_power_t state)
tg3_setup_phy(tp, 0);
}
- if (!(tp->tg3_flags & TG3_FLAG_ENABLE_ASF)) {
+ if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) {
+ u32 val;
+
+ val = tr32(GRC_VCPU_EXT_CTRL);
+ tw32(GRC_VCPU_EXT_CTRL, val | GRC_VCPU_EXT_CTRL_DISABLE_WOL);
+ } else if (!(tp->tg3_flags & TG3_FLAG_ENABLE_ASF)) {
int i;
u32 val;
@@ -1223,7 +1286,10 @@ static int tg3_set_power_state(struct tg3 *tp, pci_power_t state)
tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x5a);
udelay(40);
- mac_mode = MAC_MODE_PORT_MODE_MII;
+ if (tp->tg3_flags2 & TG3_FLG2_MII_SERDES)
+ mac_mode = MAC_MODE_PORT_MODE_GMII;
+ else
+ mac_mode = MAC_MODE_PORT_MODE_MII;
if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5700 ||
!(tp->tg3_flags & TG3_FLAG_WOL_SPEED_100MB))
@@ -1301,15 +1367,8 @@ static int tg3_set_power_state(struct tg3 *tp, pci_power_t state)
}
if (!(tp->tg3_flags & TG3_FLAG_WOL_ENABLE) &&
- !(tp->tg3_flags & TG3_FLAG_ENABLE_ASF)) {
- /* Turn off the PHY */
- if (!(tp->tg3_flags2 & TG3_FLG2_PHY_SERDES)) {
- tg3_writephy(tp, MII_TG3_EXT_CTRL,
- MII_TG3_EXT_CTRL_FORCE_LED_OFF);
- tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x01b2);
- tg3_power_down_phy(tp);
- }
- }
+ !(tp->tg3_flags & TG3_FLAG_ENABLE_ASF))
+ tg3_power_down_phy(tp);
tg3_frob_aux_power(tp);
@@ -1467,6 +1526,13 @@ static void tg3_aux_stat_to_speed_duplex(struct tg3 *tp, u32 val, u16 *speed, u8
break;
default:
+ if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) {
+ *speed = (val & MII_TG3_AUX_STAT_100) ? SPEED_100 :
+ SPEED_10;
+ *duplex = (val & MII_TG3_AUX_STAT_FULL) ? DUPLEX_FULL :
+ DUPLEX_HALF;
+ break;
+ }
*speed = SPEED_INVALID;
*duplex = DUPLEX_INVALID;
break;
@@ -1749,7 +1815,7 @@ static int tg3_setup_copper_phy(struct tg3 *tp, int force_reset)
if (tp->tg3_flags & TG3_FLAG_USE_MI_INTERRUPT)
tg3_writephy(tp, MII_TG3_IMASK, ~MII_TG3_INT_LINKCHG);
- else
+ else if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5906)
tg3_writephy(tp, MII_TG3_IMASK, ~0);
if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5700 ||
@@ -2406,24 +2472,27 @@ static int tg3_setup_fiber_hw_autoneg(struct tg3 *tp, u32 mac_status)
expected_sg_dig_ctrl |= (1 << 12);
if (sg_dig_ctrl != expected_sg_dig_ctrl) {
+ if ((tp->tg3_flags2 & TG3_FLG2_PARALLEL_DETECT) &&
+ tp->serdes_counter &&
+ ((mac_status & (MAC_STATUS_PCS_SYNCED |
+ MAC_STATUS_RCVD_CFG)) ==
+ MAC_STATUS_PCS_SYNCED)) {
+ tp->serdes_counter--;
+ current_link_up = 1;
+ goto out;
+ }
+restart_autoneg:
if (workaround)
tw32_f(MAC_SERDES_CFG, serdes_cfg | 0xc011000);
tw32_f(SG_DIG_CTRL, expected_sg_dig_ctrl | (1 << 30));
udelay(5);
tw32_f(SG_DIG_CTRL, expected_sg_dig_ctrl);
- tp->tg3_flags2 |= TG3_FLG2_PHY_JUST_INITTED;
+ tp->serdes_counter = SERDES_AN_TIMEOUT_5704S;
+ tp->tg3_flags2 &= ~TG3_FLG2_PARALLEL_DETECT;
} else if (mac_status & (MAC_STATUS_PCS_SYNCED |
MAC_STATUS_SIGNAL_DET)) {
- int i;
-
- /* Giver time to negotiate (~200ms) */
- for (i = 0; i < 40000; i++) {
- sg_dig_status = tr32(SG_DIG_STATUS);
- if (sg_dig_status & (0x3))
- break;
- udelay(5);
- }
+ sg_dig_status = tr32(SG_DIG_STATUS);
mac_status = tr32(MAC_STATUS);
if ((sg_dig_status & (1 << 1)) &&
@@ -2439,10 +2508,11 @@ static int tg3_setup_fiber_hw_autoneg(struct tg3 *tp, u32 mac_status)
tg3_setup_flow_control(tp, local_adv, remote_adv);
current_link_up = 1;
- tp->tg3_flags2 &= ~TG3_FLG2_PHY_JUST_INITTED;
+ tp->serdes_counter = 0;
+ tp->tg3_flags2 &= ~TG3_FLG2_PARALLEL_DETECT;
} else if (!(sg_dig_status & (1 << 1))) {
- if (tp->tg3_flags2 & TG3_FLG2_PHY_JUST_INITTED)
- tp->tg3_flags2 &= ~TG3_FLG2_PHY_JUST_INITTED;
+ if (tp->serdes_counter)
+ tp->serdes_counter--;
else {
if (workaround) {
u32 val = serdes_cfg;
@@ -2466,9 +2536,17 @@ static int tg3_setup_fiber_hw_autoneg(struct tg3 *tp, u32 mac_status)
!(mac_status & MAC_STATUS_RCVD_CFG)) {
tg3_setup_flow_control(tp, 0, 0);
current_link_up = 1;
- }
+ tp->tg3_flags2 |=
+ TG3_FLG2_PARALLEL_DETECT;
+ tp->serdes_counter =
+ SERDES_PARALLEL_DET_TIMEOUT;
+ } else
+ goto restart_autoneg;
}
}
+ } else {
+ tp->serdes_counter = SERDES_AN_TIMEOUT_5704S;
+ tp->tg3_flags2 &= ~TG3_FLG2_PARALLEL_DETECT;
}
out:
@@ -2599,14 +2677,16 @@ static int tg3_setup_fiber_phy(struct tg3 *tp, int force_reset)
MAC_STATUS_CFG_CHANGED));
udelay(5);
if ((tr32(MAC_STATUS) & (MAC_STATUS_SYNC_CHANGED |
- MAC_STATUS_CFG_CHANGED)) == 0)
+ MAC_STATUS_CFG_CHANGED |
+ MAC_STATUS_LNKSTATE_CHANGED)) == 0)
break;
}
mac_status = tr32(MAC_STATUS);
if ((mac_status & MAC_STATUS_PCS_SYNCED) == 0) {
current_link_up = 0;
- if (tp->link_config.autoneg == AUTONEG_ENABLE) {
+ if (tp->link_config.autoneg == AUTONEG_ENABLE &&
+ tp->serdes_counter == 0) {
tw32_f(MAC_MODE, (tp->mac_mode |
MAC_MODE_SEND_CONFIGS));
udelay(1);
@@ -2711,7 +2791,7 @@ static int tg3_setup_fiber_mii_phy(struct tg3 *tp, int force_reset)
tg3_writephy(tp, MII_BMCR, bmcr);
tw32_f(MAC_EVENT, MAC_EVENT_LNKSTATE_CHANGED);
- tp->tg3_flags2 |= TG3_FLG2_PHY_JUST_INITTED;
+ tp->serdes_counter = SERDES_AN_TIMEOUT_5714S;
tp->tg3_flags2 &= ~TG3_FLG2_PARALLEL_DETECT;
return err;
@@ -2816,9 +2896,9 @@ static int tg3_setup_fiber_mii_phy(struct tg3 *tp, int force_reset)
static void tg3_serdes_parallel_detect(struct tg3 *tp)
{
- if (tp->tg3_flags2 & TG3_FLG2_PHY_JUST_INITTED) {
+ if (tp->serdes_counter) {
/* Give autoneg time to complete. */
- tp->tg3_flags2 &= ~TG3_FLG2_PHY_JUST_INITTED;
+ tp->serdes_counter--;
return;
}
if (!netif_carrier_ok(tp->dev) &&
@@ -3535,8 +3615,7 @@ static irqreturn_t tg3_test_isr(int irq, void *dev_id,
if ((sblk->status & SD_STATUS_UPDATED) ||
!(tr32(TG3PCI_PCISTATE) & PCISTATE_INT_NOT_ACTIVE)) {
- tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW,
- 0x00000001);
+ tg3_disable_ints(tp);
return IRQ_RETVAL(1);
}
return IRQ_RETVAL(0);
@@ -4644,6 +4723,44 @@ static void tg3_write_sig_legacy(struct tg3 *tp, int kind)
}
}
+static int tg3_poll_fw(struct tg3 *tp)
+{
+ int i;
+ u32 val;
+
+ if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) {
+ for (i = 0; i < 400; i++) {
+ if (tr32(VCPU_STATUS) & VCPU_STATUS_INIT_DONE)
+ return 0;
+ udelay(10);
+ }
+ return -ENODEV;
+ }
+
+ /* Wait for firmware initialization to complete. */
+ for (i = 0; i < 100000; i++) {
+ tg3_read_mem(tp, NIC_SRAM_FIRMWARE_MBOX, &val);
+ if (val == ~NIC_SRAM_FIRMWARE_MBOX_MAGIC1)
+ break;
+ udelay(10);
+ }
+
+ /* Chip might not be fitted with firmware. Some Sun onboard
+ * parts are configured like that. So don't signal the timeout
+ * of the above loop as an error, but do report the lack of
+ * running firmware once.
+ */
+ if (i >= 100000 &&
+ !(tp->tg3_flags2 & TG3_FLG2_NO_FWARE_REPORTED)) {
+ tp->tg3_flags2 |= TG3_FLG2_NO_FWARE_REPORTED;
+
+ printk(KERN_INFO PFX "%s: No firmware running.\n",
+ tp->dev->name);
+ }
+
+ return 0;
+}
+
static void tg3_stop_fw(struct tg3 *);
/* tp->lock is held. */
@@ -4651,7 +4768,7 @@ static int tg3_chip_reset(struct tg3 *tp)
{
u32 val;
void (*write_op)(struct tg3 *, u32, u32);
- int i;
+ int err;
tg3_nvram_lock(tp);
@@ -4688,6 +4805,12 @@ static int tg3_chip_reset(struct tg3 *tp)
}
}
+ if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) {
+ tw32(VCPU_STATUS, tr32(VCPU_STATUS) | VCPU_STATUS_DRV_RESET);
+ tw32(GRC_VCPU_EXT_CTRL,
+ tr32(GRC_VCPU_EXT_CTRL) & ~GRC_VCPU_EXT_CTRL_HALT_CPU);
+ }
+
if (tp->tg3_flags2 & TG3_FLG2_5705_PLUS)
val |= GRC_MISC_CFG_KEEP_GPHY_POWER;
tw32(GRC_MISC_CFG, val);
@@ -4811,26 +4934,9 @@ static int tg3_chip_reset(struct tg3 *tp)
tw32_f(MAC_MODE, 0);
udelay(40);
- /* Wait for firmware initialization to complete. */
- for (i = 0; i < 100000; i++) {
- tg3_read_mem(tp, NIC_SRAM_FIRMWARE_MBOX, &val);
- if (val == ~NIC_SRAM_FIRMWARE_MBOX_MAGIC1)
- break;
- udelay(10);
- }
-
- /* Chip might not be fitted with firmare. Some Sun onboard
- * parts are configured like that. So don't signal the timeout
- * of the above loop as an error, but do report the lack of
- * running firmware once.
- */
- if (i >= 100000 &&
- !(tp->tg3_flags2 & TG3_FLG2_NO_FWARE_REPORTED)) {
- tp->tg3_flags2 |= TG3_FLG2_NO_FWARE_REPORTED;
-
- printk(KERN_INFO PFX "%s: No firmware running.\n",
- tp->dev->name);
- }
+ err = tg3_poll_fw(tp);
+ if (err)
+ return err;
if ((tp->tg3_flags2 & TG3_FLG2_PCI_EXPRESS) &&
tp->pci_chip_rev_id != CHIPREV_ID_5750_A0) {
@@ -5036,6 +5142,12 @@ static int tg3_halt_cpu(struct tg3 *tp, u32 offset)
BUG_ON(offset == TX_CPU_BASE &&
(tp->tg3_flags2 & TG3_FLG2_5705_PLUS));
+ if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) {
+ u32 val = tr32(GRC_VCPU_EXT_CTRL);
+
+ tw32(GRC_VCPU_EXT_CTRL, val | GRC_VCPU_EXT_CTRL_HALT_CPU);
+ return 0;
+ }
if (offset == RX_CPU_BASE) {
for (i = 0; i < 10000; i++) {
tw32(offset + CPU_STATE, 0xffffffff);
@@ -6040,6 +6152,13 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
val = 1;
else if (val > tp->rx_std_max_post)
val = tp->rx_std_max_post;
+ else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) {
+ if (tp->pci_chip_rev_id == CHIPREV_ID_5906_A1)
+ tw32(ISO_PKT_TX, (tr32(ISO_PKT_TX) & ~0x3) | 0x2);
+
+ if (val > (TG3_RX_INTERNAL_RING_SZ_5906 / 2))
+ val = TG3_RX_INTERNAL_RING_SZ_5906 / 2;
+ }
tw32(RCVBDI_STD_THRESH, val);
@@ -6460,7 +6579,8 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
if (err)
return err;
- if (!(tp->tg3_flags2 & TG3_FLG2_PHY_SERDES)) {
+ if (!(tp->tg3_flags2 & TG3_FLG2_PHY_SERDES) &&
+ GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5906) {
u32 tmp;
/* Clear CRC stats. */
@@ -6660,12 +6780,14 @@ static void tg3_timer(unsigned long __opaque)
need_setup = 1;
}
if (need_setup) {
- tw32_f(MAC_MODE,
- (tp->mac_mode &
- ~MAC_MODE_PORT_MODE_MASK));
- udelay(40);
- tw32_f(MAC_MODE, tp->mac_mode);
- udelay(40);
+ if (!tp->serdes_counter) {
+ tw32_f(MAC_MODE,
+ (tp->mac_mode &
+ ~MAC_MODE_PORT_MODE_MASK));
+ udelay(40);
+ tw32_f(MAC_MODE, tp->mac_mode);
+ udelay(40);
+ }
tg3_setup_phy(tp, 0);
}
} else if (tp->tg3_flags2 & TG3_FLG2_MII_SERDES)
@@ -6674,13 +6796,29 @@ static void tg3_timer(unsigned long __opaque)
tp->timer_counter = tp->timer_multiplier;
}
- /* Heartbeat is only sent once every 2 seconds. */
+ /* Heartbeat is only sent once every 2 seconds.
+ *
+ * The heartbeat is to tell the ASF firmware that the host
+ * driver is still alive. In the event that the OS crashes,
+ * ASF needs to reset the hardware to free up the FIFO space
+ * that may be filled with rx packets destined for the host.
+ * If the FIFO is full, ASF will no longer function properly.
+ *
+ * Unintended resets have been reported on real time kernels
+ * where the timer doesn't run on time. Netpoll will also have
+ * same problem.
+ *
+ * The new FWCMD_NICDRV_ALIVE3 command tells the ASF firmware
+ * to check the ring condition when the heartbeat is expiring
+ * before doing the reset. This will prevent most unintended
+ * resets.
+ */
if (!--tp->asf_counter) {
if (tp->tg3_flags & TG3_FLAG_ENABLE_ASF) {
u32 val;
tg3_write_mem(tp, NIC_SRAM_FW_CMD_MBOX,
- FWCMD_NICDRV_ALIVE2);
+ FWCMD_NICDRV_ALIVE3);
tg3_write_mem(tp, NIC_SRAM_FW_CMD_LEN_MBOX, 4);
/* 5 seconds timeout */
tg3_write_mem(tp, NIC_SRAM_FW_CMD_DATA_MBOX, 5);
@@ -6721,8 +6859,7 @@ static int tg3_request_irq(struct tg3 *tp)
static int tg3_test_interrupt(struct tg3 *tp)
{
struct net_device *dev = tp->dev;
- int err, i;
- u32 int_mbox = 0;
+ int err, i, intr_ok = 0;
if (!netif_running(dev))
return -ENODEV;
@@ -6743,10 +6880,18 @@ static int tg3_test_interrupt(struct tg3 *tp)
HOSTCC_MODE_NOW);
for (i = 0; i < 5; i++) {
+ u32 int_mbox, misc_host_ctrl;
+
int_mbox = tr32_mailbox(MAILBOX_INTERRUPT_0 +
TG3_64BIT_REG_LOW);
- if (int_mbox != 0)
+ misc_host_ctrl = tr32(TG3PCI_MISC_HOST_CTRL);
+
+ if ((int_mbox != 0) ||
+ (misc_host_ctrl & MISC_HOST_CTRL_MASK_PCI_INT)) {
+ intr_ok = 1;
break;
+ }
+
msleep(10);
}
@@ -6759,7 +6904,7 @@ static int tg3_test_interrupt(struct tg3 *tp)
if (err)
return err;
- if (int_mbox != 0)
+ if (intr_ok)
return 0;
return -EIO;
@@ -6936,9 +7081,10 @@ static int tg3_open(struct net_device *dev)
if (tp->tg3_flags2 & TG3_FLG2_USING_MSI) {
if (tp->tg3_flags2 & TG3_FLG2_1SHOT_MSI) {
- u32 val = tr32(0x7c04);
+ u32 val = tr32(PCIE_TRANSACTION_CFG);
- tw32(0x7c04, val | (1 << 29));
+ tw32(PCIE_TRANSACTION_CFG,
+ val | PCIE_TRANS_CFG_1SHOT_MSI);
}
}
}
@@ -7857,7 +8003,7 @@ static int tg3_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
if (wol->wolopts & ~WAKE_MAGIC)
return -EINVAL;
if ((wol->wolopts & WAKE_MAGIC) &&
- tp->tg3_flags2 & TG3_FLG2_PHY_SERDES &&
+ tp->tg3_flags2 & TG3_FLG2_ANY_SERDES &&
!(tp->tg3_flags & TG3_FLAG_SERDES_WOL_CAP))
return -EINVAL;
@@ -7893,7 +8039,8 @@ static int tg3_set_tso(struct net_device *dev, u32 value)
return -EINVAL;
return 0;
}
- if (tp->tg3_flags2 & TG3_FLG2_HW_TSO_2) {
+ if ((tp->tg3_flags2 & TG3_FLG2_HW_TSO_2) &&
+ (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5906)) {
if (value)
dev->features |= NETIF_F_TSO6;
else
@@ -8147,6 +8294,8 @@ static void tg3_get_ethtool_stats (struct net_device *dev,
#define NVRAM_TEST_SIZE 0x100
#define NVRAM_SELFBOOT_FORMAT1_SIZE 0x14
+#define NVRAM_SELFBOOT_HW_SIZE 0x20
+#define NVRAM_SELFBOOT_DATA_SIZE 0x1c
static int tg3_test_nvram(struct tg3 *tp)
{
@@ -8158,12 +8307,14 @@ static int tg3_test_nvram(struct tg3 *tp)
if (magic == TG3_EEPROM_MAGIC)
size = NVRAM_TEST_SIZE;
- else if ((magic & 0xff000000) == 0xa5000000) {
+ else if ((magic & TG3_EEPROM_MAGIC_FW_MSK) == TG3_EEPROM_MAGIC_FW) {
if ((magic & 0xe00000) == 0x200000)
size = NVRAM_SELFBOOT_FORMAT1_SIZE;
else
return 0;
- } else
+ } else if ((magic & TG3_EEPROM_MAGIC_HW_MSK) == TG3_EEPROM_MAGIC_HW)
+ size = NVRAM_SELFBOOT_HW_SIZE;
+ else
return -EIO;
buf = kmalloc(size, GFP_KERNEL);
@@ -8182,7 +8333,8 @@ static int tg3_test_nvram(struct tg3 *tp)
goto out;
/* Selfboot format */
- if (cpu_to_be32(buf[0]) != TG3_EEPROM_MAGIC) {
+ if ((cpu_to_be32(buf[0]) & TG3_EEPROM_MAGIC_FW_MSK) ==
+ TG3_EEPROM_MAGIC_FW) {
u8 *buf8 = (u8 *) buf, csum8 = 0;
for (i = 0; i < size; i++)
@@ -8197,6 +8349,51 @@ static int tg3_test_nvram(struct tg3 *tp)
goto out;
}
+ if ((cpu_to_be32(buf[0]) & TG3_EEPROM_MAGIC_HW_MSK) ==
+ TG3_EEPROM_MAGIC_HW) {
+ u8 data[NVRAM_SELFBOOT_DATA_SIZE];
+ u8 parity[NVRAM_SELFBOOT_DATA_SIZE];
+ u8 *buf8 = (u8 *) buf;
+ int j, k;
+
+ /* Separate the parity bits and the data bytes. */
+ for (i = 0, j = 0, k = 0; i < NVRAM_SELFBOOT_HW_SIZE; i++) {
+ if ((i == 0) || (i == 8)) {
+ int l;
+ u8 msk;
+
+ for (l = 0, msk = 0x80; l < 7; l++, msk >>= 1)
+ parity[k++] = buf8[i] & msk;
+ i++;
+ }
+ else if (i == 16) {
+ int l;
+ u8 msk;
+
+ for (l = 0, msk = 0x20; l < 6; l++, msk >>= 1)
+ parity[k++] = buf8[i] & msk;
+ i++;
+
+ for (l = 0, msk = 0x80; l < 8; l++, msk >>= 1)
+ parity[k++] = buf8[i] & msk;
+ i++;
+ }
+ data[j++] = buf8[i];
+ }
+
+ err = -EIO;
+ for (i = 0; i < NVRAM_SELFBOOT_DATA_SIZE; i++) {
+ u8 hw8 = hweight8(data[i]);
+
+ if ((hw8 & 0x1) && parity[i])
+ goto out;
+ else if (!(hw8 & 0x1) && !parity[i])
+ goto out;
+ }
+ err = 0;
+ goto out;
+ }
+
/* Bootstrap checksum at offset 0x10 */
csum = calc_crc((unsigned char *) buf, 0x10);
if(csum != cpu_to_le32(buf[0x10/4]))
@@ -8243,7 +8440,7 @@ static int tg3_test_link(struct tg3 *tp)
/* Only test the commonly used registers */
static int tg3_test_registers(struct tg3 *tp)
{
- int i, is_5705;
+ int i, is_5705, is_5750;
u32 offset, read_mask, write_mask, val, save_val, read_val;
static struct {
u16 offset;
@@ -8251,6 +8448,7 @@ static int tg3_test_registers(struct tg3 *tp)
#define TG3_FL_5705 0x1
#define TG3_FL_NOT_5705 0x2
#define TG3_FL_NOT_5788 0x4
+#define TG3_FL_NOT_5750 0x8
u32 read_mask;
u32 write_mask;
} reg_tbl[] = {
@@ -8361,9 +8559,9 @@ static int tg3_test_registers(struct tg3 *tp)
0xffffffff, 0x00000000 },
/* Buffer Manager Control Registers. */
- { BUFMGR_MB_POOL_ADDR, 0x0000,
+ { BUFMGR_MB_POOL_ADDR, TG3_FL_NOT_5750,
0x00000000, 0x007fff80 },
- { BUFMGR_MB_POOL_SIZE, 0x0000,
+ { BUFMGR_MB_POOL_SIZE, TG3_FL_NOT_5750,
0x00000000, 0x007fffff },
{ BUFMGR_MB_RDMA_LOW_WATER, 0x0000,
0x00000000, 0x0000003f },
@@ -8389,10 +8587,12 @@ static int tg3_test_registers(struct tg3 *tp)
{ 0xffff, 0x0000, 0x00000000, 0x00000000 },
};
- if (tp->tg3_flags2 & TG3_FLG2_5705_PLUS)
+ is_5705 = is_5750 = 0;
+ if (tp->tg3_flags2 & TG3_FLG2_5705_PLUS) {
is_5705 = 1;
- else
- is_5705 = 0;
+ if (tp->tg3_flags2 & TG3_FLG2_5750_PLUS)
+ is_5750 = 1;
+ }
for (i = 0; reg_tbl[i].offset != 0xffff; i++) {
if (is_5705 && (reg_tbl[i].flags & TG3_FL_NOT_5705))
@@ -8405,6 +8605,9 @@ static int tg3_test_registers(struct tg3 *tp)
(reg_tbl[i].flags & TG3_FL_NOT_5788))
continue;
+ if (is_5750 && (reg_tbl[i].flags & TG3_FL_NOT_5750))
+ continue;
+
offset = (u32) reg_tbl[i].offset;
read_mask = reg_tbl[i].read_mask;
write_mask = reg_tbl[i].write_mask;
@@ -8496,6 +8699,13 @@ static int tg3_test_memory(struct tg3 *tp)
{ 0x00008000, 0x02000},
{ 0x00010000, 0x0c000},
{ 0xffffffff, 0x00000}
+ }, mem_tbl_5906[] = {
+ { 0x00000200, 0x00008},
+ { 0x00004000, 0x00400},
+ { 0x00006000, 0x00400},
+ { 0x00008000, 0x01000},
+ { 0x00010000, 0x01000},
+ { 0xffffffff, 0x00000}
};
struct mem_entry *mem_tbl;
int err = 0;
@@ -8505,6 +8715,8 @@ static int tg3_test_memory(struct tg3 *tp)
if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5755 ||
GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5787)
mem_tbl = mem_tbl_5755;
+ else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906)
+ mem_tbl = mem_tbl_5906;
else
mem_tbl = mem_tbl_5705;
} else
@@ -8541,13 +8753,41 @@ static int tg3_run_loopback(struct tg3 *tp, int loopback_mode)
return 0;
mac_mode = (tp->mac_mode & ~MAC_MODE_PORT_MODE_MASK) |
- MAC_MODE_PORT_INT_LPBACK | MAC_MODE_LINK_POLARITY |
- MAC_MODE_PORT_MODE_GMII;
+ MAC_MODE_PORT_INT_LPBACK | MAC_MODE_LINK_POLARITY;
+ if (tp->tg3_flags & TG3_FLAG_10_100_ONLY)
+ mac_mode |= MAC_MODE_PORT_MODE_MII;
+ else
+ mac_mode |= MAC_MODE_PORT_MODE_GMII;
tw32(MAC_MODE, mac_mode);
} else if (loopback_mode == TG3_PHY_LOOPBACK) {
- tg3_writephy(tp, MII_BMCR, BMCR_LOOPBACK | BMCR_FULLDPLX |
- BMCR_SPEED1000);
+ u32 val;
+
+ if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) {
+ u32 phytest;
+
+ if (!tg3_readphy(tp, MII_TG3_EPHY_TEST, &phytest)) {
+ u32 phy;
+
+ tg3_writephy(tp, MII_TG3_EPHY_TEST,
+ phytest | MII_TG3_EPHY_SHADOW_EN);
+ if (!tg3_readphy(tp, 0x1b, &phy))
+ tg3_writephy(tp, 0x1b, phy & ~0x20);
+ if (!tg3_readphy(tp, 0x10, &phy))
+ tg3_writephy(tp, 0x10, phy & ~0x4000);
+ tg3_writephy(tp, MII_TG3_EPHY_TEST, phytest);
+ }
+ }
+ val = BMCR_LOOPBACK | BMCR_FULLDPLX;
+ if (tp->tg3_flags & TG3_FLAG_10_100_ONLY)
+ val |= BMCR_SPEED100;
+ else
+ val |= BMCR_SPEED1000;
+
+ tg3_writephy(tp, MII_BMCR, val);
udelay(40);
+ if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906)
+ tg3_writephy(tp, MII_TG3_EPHY_PTEST, 0x1800);
+
/* reset to prevent losing 1st rx packet intermittently */
if (tp->tg3_flags2 & TG3_FLG2_MII_SERDES) {
tw32_f(MAC_RX_MODE, RX_MODE_RESET);
@@ -8555,7 +8795,11 @@ static int tg3_run_loopback(struct tg3 *tp, int loopback_mode)
tw32_f(MAC_RX_MODE, tp->rx_mode);
}
mac_mode = (tp->mac_mode & ~MAC_MODE_PORT_MODE_MASK) |
- MAC_MODE_LINK_POLARITY | MAC_MODE_PORT_MODE_GMII;
+ MAC_MODE_LINK_POLARITY;
+ if (tp->tg3_flags & TG3_FLAG_10_100_ONLY)
+ mac_mode |= MAC_MODE_PORT_MODE_MII;
+ else
+ mac_mode |= MAC_MODE_PORT_MODE_GMII;
if ((tp->phy_id & PHY_ID_MASK) == PHY_ID_BCM5401) {
mac_mode &= ~MAC_MODE_LINK_POLARITY;
tg3_writephy(tp, MII_TG3_EXT_CTRL,
@@ -8604,7 +8848,8 @@ static int tg3_run_loopback(struct tg3 *tp, int loopback_mode)
udelay(10);
- for (i = 0; i < 10; i++) {
+ /* 250 usec to allow enough time on some 10/100 Mbps devices. */
+ for (i = 0; i < 25; i++) {
tw32_f(HOSTCC_MODE, tp->coalesce_mode | HOSTCC_MODE_ENABLE |
HOSTCC_MODE_NOW);
@@ -8956,7 +9201,9 @@ static void __devinit tg3_get_eeprom_size(struct tg3 *tp)
if (tg3_nvram_read_swab(tp, 0, &magic) != 0)
return;
- if ((magic != TG3_EEPROM_MAGIC) && ((magic & 0xff000000) != 0xa5000000))
+ if ((magic != TG3_EEPROM_MAGIC) &&
+ ((magic & TG3_EEPROM_MAGIC_FW_MSK) != TG3_EEPROM_MAGIC_FW) &&
+ ((magic & TG3_EEPROM_MAGIC_HW_MSK) != TG3_EEPROM_MAGIC_HW))
return;
/*
@@ -9194,6 +9441,13 @@ static void __devinit tg3_get_5787_nvram_info(struct tg3 *tp)
}
}
+static void __devinit tg3_get_5906_nvram_info(struct tg3 *tp)
+{
+ tp->nvram_jedecnum = JEDEC_ATMEL;
+ tp->tg3_flags |= TG3_FLAG_NVRAM_BUFFERED;
+ tp->nvram_pagesize = ATMEL_AT24C512_CHIP_SIZE;
+}
+
/* Chips other than 5700/5701 use the NVRAM for fetching info. */
static void __devinit tg3_nvram_init(struct tg3 *tp)
{
@@ -9230,6 +9484,8 @@ static void __devinit tg3_nvram_init(struct tg3 *tp)
tg3_get_5755_nvram_info(tp);
else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5787)
tg3_get_5787_nvram_info(tp);
+ else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906)
+ tg3_get_5906_nvram_info(tp);
else
tg3_get_nvram_info(tp);
@@ -9703,6 +9959,12 @@ static void __devinit tg3_get_eeprom_hw_cfg(struct tg3 *tp)
/* Assume an onboard device by default. */
tp->tg3_flags |= TG3_FLAG_EEPROM_WRITE_PROT;
+ if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) {
+ if (!(tr32(PCIE_TRANSACTION_CFG) & PCIE_TRANS_CFG_LOM))
+ tp->tg3_flags &= ~TG3_FLAG_EEPROM_WRITE_PROT;
+ return;
+ }
+
tg3_read_mem(tp, NIC_SRAM_DATA_SIG, &val);
if (val == NIC_SRAM_DATA_SIG_MAGIC) {
u32 nic_cfg, led_cfg;
@@ -10034,7 +10296,10 @@ static void __devinit tg3_read_partno(struct tg3 *tp)
}
out_not_found:
- strcpy(tp->board_part_number, "none");
+ if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906)
+ strcpy(tp->board_part_number, "BCM95906");
+ else
+ strcpy(tp->board_part_number, "none");
}
static void __devinit tg3_read_fw_ver(struct tg3 *tp)
@@ -10236,6 +10501,7 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5752 ||
GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5755 ||
GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5787 ||
+ GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906 ||
(tp->tg3_flags2 & TG3_FLG2_5780_CLASS))
tp->tg3_flags2 |= TG3_FLG2_5750_PLUS;
@@ -10245,7 +10511,8 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
if (tp->tg3_flags2 & TG3_FLG2_5750_PLUS) {
if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5755 ||
- GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5787) {
+ GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5787 ||
+ GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) {
tp->tg3_flags2 |= TG3_FLG2_HW_TSO_2;
tp->tg3_flags2 |= TG3_FLG2_1SHOT_MSI;
} else {
@@ -10262,7 +10529,8 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5750 &&
GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5752 &&
GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5755 &&
- GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5787)
+ GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5787 &&
+ GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5906)
tp->tg3_flags2 |= TG3_FLG2_JUMBO_CAPABLE;
if (pci_find_capability(tp->pdev, PCI_CAP_ID_EXP) != 0)
@@ -10392,6 +10660,12 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
pci_cmd &= ~PCI_COMMAND_MEMORY;
pci_write_config_word(tp->pdev, PCI_COMMAND, pci_cmd);
}
+ if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) {
+ tp->read32_mbox = tg3_read32_mbox_5906;
+ tp->write32_mbox = tg3_write32_mbox_5906;
+ tp->write32_tx_mbox = tg3_write32_mbox_5906;
+ tp->write32_rx_mbox = tg3_write32_mbox_5906;
+ }
if (tp->write32 == tg3_write_indirect_reg32 ||
((tp->tg3_flags & TG3_FLAG_PCIX_MODE) &&
@@ -10463,6 +10737,7 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705) &&
(tp->pci_chip_rev_id != CHIPREV_ID_5705_A0) &&
(tp->pci_chip_rev_id != CHIPREV_ID_5705_A1)) ||
+ (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) ||
(tp->tg3_flags2 & TG3_FLG2_ANY_SERDES))
tp->tg3_flags2 |= TG3_FLG2_NO_ETH_WIRE_SPEED;
@@ -10476,7 +10751,7 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5755 ||
GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5787)
tp->tg3_flags2 |= TG3_FLG2_PHY_JITTER_BUG;
- else
+ else if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5906)
tp->tg3_flags2 |= TG3_FLG2_PHY_BER_BUG;
}
@@ -10566,7 +10841,8 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
tp->pdev->device == PCI_DEVICE_ID_TIGON3_5705F)) ||
(tp->pdev->vendor == PCI_VENDOR_ID_BROADCOM &&
(tp->pdev->device == PCI_DEVICE_ID_TIGON3_5751F ||
- tp->pdev->device == PCI_DEVICE_ID_TIGON3_5753F)))
+ tp->pdev->device == PCI_DEVICE_ID_TIGON3_5753F)) ||
+ GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906)
tp->tg3_flags |= TG3_FLAG_10_100_ONLY;
err = tg3_phy_probe(tp);
@@ -10617,7 +10893,8 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
* straddle the 4GB address boundary in some cases.
*/
if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5755 ||
- GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5787)
+ GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5787 ||
+ GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906)
tp->dev->hard_start_xmit = tg3_start_xmit;
else
tp->dev->hard_start_xmit = tg3_start_xmit_dma_bug;
@@ -10698,6 +10975,8 @@ static int __devinit tg3_get_device_address(struct tg3 *tp)
else
tg3_nvram_unlock(tp);
}
+ if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906)
+ mac_offset = 0x10;
/* First try to get it from MAC address mailbox. */
tg3_read_mem(tp, NIC_SRAM_MAC_ADDR_HIGH_MBOX, &hi);
@@ -11181,6 +11460,12 @@ static void __devinit tg3_init_bufmgr_config(struct tg3 *tp)
DEFAULT_MB_MACRX_LOW_WATER_5705;
tp->bufmgr_config.mbuf_high_water =
DEFAULT_MB_HIGH_WATER_5705;
+ if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) {
+ tp->bufmgr_config.mbuf_mac_rx_low_water =
+ DEFAULT_MB_MACRX_LOW_WATER_5906;
+ tp->bufmgr_config.mbuf_high_water =
+ DEFAULT_MB_HIGH_WATER_5906;
+ }
tp->bufmgr_config.mbuf_read_dma_low_water_jumbo =
DEFAULT_MB_RDMA_LOW_WATER_JUMBO_5780;
@@ -11224,6 +11509,8 @@ static char * __devinit tg3_phy_string(struct tg3 *tp)
case PHY_ID_BCM5780: return "5780";
case PHY_ID_BCM5755: return "5755";
case PHY_ID_BCM5787: return "5787";
+ case PHY_ID_BCM5756: return "5722/5756";
+ case PHY_ID_BCM5906: return "5906";
case PHY_ID_BCM8002: return "8002/serdes";
case 0: return "serdes";
default: return "unknown";
@@ -11526,7 +11813,8 @@ static int __devinit tg3_init_one(struct pci_dev *pdev,
*/
if (tp->tg3_flags2 & TG3_FLG2_HW_TSO) {
dev->features |= NETIF_F_TSO;
- if (tp->tg3_flags2 & TG3_FLG2_HW_TSO_2)
+ if ((tp->tg3_flags2 & TG3_FLG2_HW_TSO_2) &&
+ (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5906))
dev->features |= NETIF_F_TSO6;
}
diff --git a/drivers/net/tg3.h b/drivers/net/tg3.h
index 3ecf356cfb08..92f53000bce6 100644
--- a/drivers/net/tg3.h
+++ b/drivers/net/tg3.h
@@ -24,6 +24,8 @@
#define RX_COPY_THRESHOLD 256
+#define TG3_RX_INTERNAL_RING_SZ_5906 32
+
#define RX_STD_MAX_SIZE 1536
#define RX_STD_MAX_SIZE_5705 512
#define RX_JUMBO_MAX_SIZE 0xdeadbeef /* XXX */
@@ -129,6 +131,7 @@
#define CHIPREV_ID_5752_A0_HW 0x5000
#define CHIPREV_ID_5752_A0 0x6000
#define CHIPREV_ID_5752_A1 0x6001
+#define CHIPREV_ID_5906_A1 0xc001
#define GET_ASIC_REV(CHIP_REV_ID) ((CHIP_REV_ID) >> 12)
#define ASIC_REV_5700 0x07
#define ASIC_REV_5701 0x00
@@ -141,6 +144,7 @@
#define ASIC_REV_5714 0x09
#define ASIC_REV_5755 0x0a
#define ASIC_REV_5787 0x0b
+#define ASIC_REV_5906 0x0c
#define GET_CHIP_REV(CHIP_REV_ID) ((CHIP_REV_ID) >> 8)
#define CHIPREV_5700_AX 0x70
#define CHIPREV_5700_BX 0x71
@@ -646,7 +650,8 @@
#define SNDDATAI_SCTRL_FORCE_ZERO 0x00000010
#define SNDDATAI_STATSENAB 0x00000c0c
#define SNDDATAI_STATSINCMASK 0x00000c10
-/* 0xc14 --> 0xc80 unused */
+#define ISO_PKT_TX 0x00000c20
+/* 0xc24 --> 0xc80 unused */
#define SNDDATAI_COS_CNT_0 0x00000c80
#define SNDDATAI_COS_CNT_1 0x00000c84
#define SNDDATAI_COS_CNT_2 0x00000c88
@@ -997,11 +1002,13 @@
#define BUFMGR_MB_MACRX_LOW_WATER 0x00004414
#define DEFAULT_MB_MACRX_LOW_WATER 0x00000020
#define DEFAULT_MB_MACRX_LOW_WATER_5705 0x00000010
+#define DEFAULT_MB_MACRX_LOW_WATER_5906 0x00000004
#define DEFAULT_MB_MACRX_LOW_WATER_JUMBO 0x00000098
#define DEFAULT_MB_MACRX_LOW_WATER_JUMBO_5780 0x0000004b
#define BUFMGR_MB_HIGH_WATER 0x00004418
#define DEFAULT_MB_HIGH_WATER 0x00000060
#define DEFAULT_MB_HIGH_WATER_5705 0x00000060
+#define DEFAULT_MB_HIGH_WATER_5906 0x00000010
#define DEFAULT_MB_HIGH_WATER_JUMBO 0x0000017c
#define DEFAULT_MB_HIGH_WATER_JUMBO_5780 0x00000096
#define BUFMGR_RX_MB_ALLOC_REQ 0x0000441c
@@ -1138,7 +1145,12 @@
#define TX_CPU_STATE 0x00005404
#define TX_CPU_PGMCTR 0x0000541c
+#define VCPU_STATUS 0x00005100
+#define VCPU_STATUS_INIT_DONE 0x04000000
+#define VCPU_STATUS_DRV_RESET 0x08000000
+
/* Mailboxes */
+#define GRCMBOX_BASE 0x00005600
#define GRCMBOX_INTERRUPT_0 0x00005800 /* 64-bit */
#define GRCMBOX_INTERRUPT_1 0x00005808 /* 64-bit */
#define GRCMBOX_INTERRUPT_2 0x00005810 /* 64-bit */
@@ -1398,7 +1410,10 @@
#define GRC_EEPROM_CTRL 0x00006840
#define GRC_MDI_CTRL 0x00006844
#define GRC_SEEPROM_DELAY 0x00006848
-/* 0x684c --> 0x6c00 unused */
+/* 0x684c --> 0x6890 unused */
+#define GRC_VCPU_EXT_CTRL 0x00006890
+#define GRC_VCPU_EXT_CTRL_HALT_CPU 0x00400000
+#define GRC_VCPU_EXT_CTRL_DISABLE_WOL 0x20000000
#define GRC_FASTBOOT_PC 0x00006894 /* 5752, 5755, 5787 */
/* 0x6c00 --> 0x7000 unused */
@@ -1485,9 +1500,17 @@
#define NVRAM_WRITE1 0x00007028
/* 0x702c --> 0x7400 unused */
-/* 0x7400 --> 0x8000 unused */
+/* 0x7400 --> 0x7c00 unused */
+#define PCIE_TRANSACTION_CFG 0x00007c04
+#define PCIE_TRANS_CFG_1SHOT_MSI 0x20000000
+#define PCIE_TRANS_CFG_LOM 0x00000020
+
#define TG3_EEPROM_MAGIC 0x669955aa
+#define TG3_EEPROM_MAGIC_FW 0xa5000000
+#define TG3_EEPROM_MAGIC_FW_MSK 0xff000000
+#define TG3_EEPROM_MAGIC_HW 0xabcd
+#define TG3_EEPROM_MAGIC_HW_MSK 0xffff
/* 32K Window into NIC internal memory */
#define NIC_SRAM_WIN_BASE 0x00008000
@@ -1537,6 +1560,7 @@
#define FWCMD_NICDRV_FIX_DMAR 0x00000005
#define FWCMD_NICDRV_FIX_DMAW 0x00000006
#define FWCMD_NICDRV_ALIVE2 0x0000000d
+#define FWCMD_NICDRV_ALIVE3 0x0000000e
#define NIC_SRAM_FW_CMD_LEN_MBOX 0x00000b7c
#define NIC_SRAM_FW_CMD_DATA_MBOX 0x00000b80
#define NIC_SRAM_FW_ASF_STATUS_MBOX 0x00000c00
@@ -1604,6 +1628,7 @@
#define MII_TG3_DSP_RW_PORT 0x15 /* DSP coefficient read/write port */
#define MII_TG3_DSP_ADDRESS 0x17 /* DSP address register */
+#define MII_TG3_EPHY_PTEST 0x17 /* 5906 PHY register */
#define MII_TG3_AUX_CTRL 0x18 /* auxilliary control register */
@@ -1617,6 +1642,8 @@
#define MII_TG3_AUX_STAT_100FULL 0x0500
#define MII_TG3_AUX_STAT_1000HALF 0x0600
#define MII_TG3_AUX_STAT_1000FULL 0x0700
+#define MII_TG3_AUX_STAT_100 0x0008
+#define MII_TG3_AUX_STAT_FULL 0x0001
#define MII_TG3_ISTAT 0x1a /* IRQ status register */
#define MII_TG3_IMASK 0x1b /* IRQ mask register */
@@ -1627,6 +1654,9 @@
#define MII_TG3_INT_DUPLEXCHG 0x0008
#define MII_TG3_INT_ANEG_PAGE_RX 0x0400
+#define MII_TG3_EPHY_TEST 0x1f /* 5906 PHY register */
+#define MII_TG3_EPHY_SHADOW_EN 0x80
+
/* There are two ways to manage the TX descriptors on the tigon3.
* Either the descriptors are in host DMA'able memory, or they
* exist only in the cards on-chip SRAM. All 16 send bds are under
@@ -2203,7 +2233,6 @@ struct tg3 {
#define TG3_FLG2_PCI_EXPRESS 0x00000200
#define TG3_FLG2_ASF_NEW_HANDSHAKE 0x00000400
#define TG3_FLG2_HW_AUTONEG 0x00000800
-#define TG3_FLG2_PHY_JUST_INITTED 0x00001000
#define TG3_FLG2_PHY_SERDES 0x00002000
#define TG3_FLG2_CAPACITIVE_COUPLING 0x00004000
#define TG3_FLG2_FLASH 0x00008000
@@ -2236,6 +2265,12 @@ struct tg3 {
u16 asf_counter;
u16 asf_multiplier;
+ /* 1 second counter for transient serdes link events */
+ u32 serdes_counter;
+#define SERDES_AN_TIMEOUT_5704S 2
+#define SERDES_PARALLEL_DET_TIMEOUT 1
+#define SERDES_AN_TIMEOUT_5714S 1
+
struct tg3_link_config link_config;
struct tg3_bufmgr_config bufmgr_config;
@@ -2276,6 +2311,8 @@ struct tg3 {
#define PHY_ID_BCM5780 0x60008350
#define PHY_ID_BCM5755 0xbc050cc0
#define PHY_ID_BCM5787 0xbc050ce0
+#define PHY_ID_BCM5756 0xbc050ed0
+#define PHY_ID_BCM5906 0xdc00ac40
#define PHY_ID_BCM8002 0x60010140
#define PHY_ID_INVALID 0xffffffff
#define PHY_ID_REV_MASK 0x0000000f
@@ -2302,7 +2339,8 @@ struct tg3 {
(X) == PHY_ID_BCM5705 || (X) == PHY_ID_BCM5750 || \
(X) == PHY_ID_BCM5752 || (X) == PHY_ID_BCM5714 || \
(X) == PHY_ID_BCM5780 || (X) == PHY_ID_BCM5787 || \
- (X) == PHY_ID_BCM5755 || (X) == PHY_ID_BCM8002)
+ (X) == PHY_ID_BCM5755 || (X) == PHY_ID_BCM5756 || \
+ (X) == PHY_ID_BCM5906 || (X) == PHY_ID_BCM8002)
struct tg3_hw_stats *hw_stats;
dma_addr_t stats_mapping;
diff --git a/drivers/net/tun.c b/drivers/net/tun.c
index de8da6dee1b0..151a2e10e4f3 100644
--- a/drivers/net/tun.c
+++ b/drivers/net/tun.c
@@ -288,11 +288,10 @@ static inline size_t iov_total(const struct iovec *iv, unsigned long count)
return len;
}
-/* Writev */
-static ssize_t tun_chr_writev(struct file * file, const struct iovec *iv,
- unsigned long count, loff_t *pos)
+static ssize_t tun_chr_aio_write(struct kiocb *iocb, const struct iovec *iv,
+ unsigned long count, loff_t pos)
{
- struct tun_struct *tun = file->private_data;
+ struct tun_struct *tun = iocb->ki_filp->private_data;
if (!tun)
return -EBADFD;
@@ -302,14 +301,6 @@ static ssize_t tun_chr_writev(struct file * file, const struct iovec *iv,
return tun_get_user(tun, (struct iovec *) iv, iov_total(iv, count));
}
-/* Write */
-static ssize_t tun_chr_write(struct file * file, const char __user * buf,
- size_t count, loff_t *pos)
-{
- struct iovec iv = { (void __user *) buf, count };
- return tun_chr_writev(file, &iv, 1, pos);
-}
-
/* Put packet to the user space buffer */
static __inline__ ssize_t tun_put_user(struct tun_struct *tun,
struct sk_buff *skb,
@@ -343,10 +334,10 @@ static __inline__ ssize_t tun_put_user(struct tun_struct *tun,
return total;
}
-/* Readv */
-static ssize_t tun_chr_readv(struct file *file, const struct iovec *iv,
- unsigned long count, loff_t *pos)
+static ssize_t tun_chr_aio_read(struct kiocb *iocb, const struct iovec *iv,
+ unsigned long count, loff_t pos)
{
+ struct file *file = iocb->ki_filp;
struct tun_struct *tun = file->private_data;
DECLARE_WAITQUEUE(wait, current);
struct sk_buff *skb;
@@ -426,14 +417,6 @@ static ssize_t tun_chr_readv(struct file *file, const struct iovec *iv,
return ret;
}
-/* Read */
-static ssize_t tun_chr_read(struct file * file, char __user * buf,
- size_t count, loff_t *pos)
-{
- struct iovec iv = { buf, count };
- return tun_chr_readv(file, &iv, 1, pos);
-}
-
static void tun_setup(struct net_device *dev)
{
struct tun_struct *tun = netdev_priv(dev);
@@ -714,7 +697,7 @@ static int tun_chr_fasync(int fd, struct file *file, int on)
return ret;
if (on) {
- ret = f_setown(file, current->pid, 0);
+ ret = __f_setown(file, task_pid(current), PIDTYPE_PID, 0);
if (ret)
return ret;
tun->flags |= TUN_FASYNC;
@@ -764,10 +747,10 @@ static int tun_chr_close(struct inode *inode, struct file *file)
static struct file_operations tun_fops = {
.owner = THIS_MODULE,
.llseek = no_llseek,
- .read = tun_chr_read,
- .readv = tun_chr_readv,
- .write = tun_chr_write,
- .writev = tun_chr_writev,
+ .read = do_sync_read,
+ .aio_read = tun_chr_aio_read,
+ .write = do_sync_write,
+ .aio_write = tun_chr_aio_write,
.poll = tun_chr_poll,
.ioctl = tun_chr_ioctl,
.open = tun_chr_open,
diff --git a/drivers/net/wan/hdlc_cisco.c b/drivers/net/wan/hdlc_cisco.c
index 7ec2b2f9b7ee..b0bc5ddcf1b1 100644
--- a/drivers/net/wan/hdlc_cisco.c
+++ b/drivers/net/wan/hdlc_cisco.c
@@ -161,7 +161,7 @@ static int cisco_rx(struct sk_buff *skb)
struct hdlc_header *data = (struct hdlc_header*)skb->data;
struct cisco_packet *cisco_data;
struct in_device *in_dev;
- u32 addr, mask;
+ __be32 addr, mask;
if (skb->len < sizeof(struct hdlc_header))
goto rx_error;
diff --git a/drivers/net/wan/syncppp.c b/drivers/net/wan/syncppp.c
index c13b459a0137..218f7b574ab3 100644
--- a/drivers/net/wan/syncppp.c
+++ b/drivers/net/wan/syncppp.c
@@ -469,7 +469,7 @@ static void sppp_lcp_input (struct sppp *sp, struct sk_buff *skb)
struct net_device *dev = sp->pp_if;
int len = skb->len;
u8 *p, opt[6];
- u32 rmagic;
+ u32 rmagic = 0;
if (!pskb_may_pull(skb, sizeof(struct lcp_header))) {
if (sp->pp_flags & PP_DEBUG)
@@ -763,7 +763,7 @@ static void sppp_cisco_input (struct sppp *sp, struct sk_buff *skb)
{
struct in_device *in_dev;
struct in_ifaddr *ifa;
- u32 addr = 0, mask = ~0; /* FIXME: is the mask correct? */
+ __be32 addr = 0, mask = ~0; /* FIXME: is the mask correct? */
#ifdef CONFIG_INET
rcu_read_lock();
if ((in_dev = __in_dev_get_rcu(dev)) != NULL)
diff --git a/drivers/net/wireless/airo.c b/drivers/net/wireless/airo.c
index ba737c6cebec..39d09345027c 100644
--- a/drivers/net/wireless/airo.c
+++ b/drivers/net/wireless/airo.c
@@ -5659,25 +5659,40 @@ static int airo_pci_resume(struct pci_dev *pdev)
static int __init airo_init_module( void )
{
- int i, have_isa_dev = 0;
+ int i;
+#if 0
+ int have_isa_dev = 0;
+#endif
airo_entry = create_proc_entry("aironet",
S_IFDIR | airo_perm,
proc_root_driver);
- airo_entry->uid = proc_uid;
- airo_entry->gid = proc_gid;
+
+ if (airo_entry) {
+ airo_entry->uid = proc_uid;
+ airo_entry->gid = proc_gid;
+ }
for( i = 0; i < 4 && io[i] && irq[i]; i++ ) {
airo_print_info("", "Trying to configure ISA adapter at irq=%d "
"io=0x%x", irq[i], io[i] );
if (init_airo_card( irq[i], io[i], 0, NULL ))
+#if 0
have_isa_dev = 1;
+#else
+ /* do nothing */ ;
+#endif
}
#ifdef CONFIG_PCI
airo_print_info("", "Probing for PCI adapters");
- pci_register_driver(&airo_driver);
+ i = pci_register_driver(&airo_driver);
airo_print_info("", "Finished probing for PCI adapters");
+
+ if (i) {
+ remove_proc_entry("aironet", proc_root_driver);
+ return i;
+ }
#endif
/* Always exit with success, as we are a library module
diff --git a/drivers/net/wireless/ipw2100.c b/drivers/net/wireless/ipw2100.c
index 6c5add701a6f..599e2fe76188 100644
--- a/drivers/net/wireless/ipw2100.c
+++ b/drivers/net/wireless/ipw2100.c
@@ -150,7 +150,6 @@ that only one external action is invoked at a time.
#include <linux/skbuff.h>
#include <asm/uaccess.h>
#include <asm/io.h>
-#define __KERNEL_SYSCALLS__
#include <linux/fs.h>
#include <linux/mm.h>
#include <linux/slab.h>
@@ -163,6 +162,7 @@ that only one external action is invoked at a time.
#include <linux/firmware.h>
#include <linux/acpi.h>
#include <linux/ctype.h>
+#include <linux/latency.h>
#include "ipw2100.h"
@@ -1697,6 +1697,11 @@ static int ipw2100_up(struct ipw2100_priv *priv, int deferred)
return 0;
}
+ /* the ipw2100 hardware really doesn't want power management delays
+ * longer than 175usec
+ */
+ modify_acceptable_latency("ipw2100", 175);
+
/* If the interrupt is enabled, turn it off... */
spin_lock_irqsave(&priv->low_lock, flags);
ipw2100_disable_interrupts(priv);
@@ -1849,6 +1854,8 @@ static void ipw2100_down(struct ipw2100_priv *priv)
ipw2100_disable_interrupts(priv);
spin_unlock_irqrestore(&priv->low_lock, flags);
+ modify_acceptable_latency("ipw2100", INFINITE_LATENCY);
+
#ifdef ACPI_CSTATE_LIMIT_DEFINED
if (priv->config & CFG_C3_DISABLED) {
IPW_DEBUG_INFO(": Resetting C3 transitions.\n");
@@ -6267,7 +6274,9 @@ static int ipw2100_pci_init_one(struct pci_dev *pci_dev,
IPW_DEBUG_INFO("%s: Bound to %s\n", dev->name, pci_name(pci_dev));
/* perform this after register_netdev so that dev->name is set */
- sysfs_create_group(&pci_dev->dev.kobj, &ipw2100_attribute_group);
+ err = sysfs_create_group(&pci_dev->dev.kobj, &ipw2100_attribute_group);
+ if (err)
+ goto fail_unlock;
/* If the RF Kill switch is disabled, go ahead and complete the
* startup sequence */
@@ -6533,13 +6542,17 @@ static int __init ipw2100_init(void)
printk(KERN_INFO DRV_NAME ": %s\n", DRV_COPYRIGHT);
ret = pci_register_driver(&ipw2100_pci_driver);
+ if (ret)
+ goto out;
+ set_acceptable_latency("ipw2100", INFINITE_LATENCY);
#ifdef CONFIG_IPW2100_DEBUG
ipw2100_debug_level = debug;
- driver_create_file(&ipw2100_pci_driver.driver,
- &driver_attr_debug_level);
+ ret = driver_create_file(&ipw2100_pci_driver.driver,
+ &driver_attr_debug_level);
#endif
+out:
return ret;
}
@@ -6554,6 +6567,7 @@ static void __exit ipw2100_exit(void)
&driver_attr_debug_level);
#endif
pci_unregister_driver(&ipw2100_pci_driver);
+ remove_acceptable_latency("ipw2100");
}
module_init(ipw2100_init);
diff --git a/drivers/net/wireless/strip.c b/drivers/net/wireless/strip.c
index ccaf28e8db0a..337c692f6fd6 100644
--- a/drivers/net/wireless/strip.c
+++ b/drivers/net/wireless/strip.c
@@ -1342,7 +1342,7 @@ static unsigned char *strip_make_packet(unsigned char *buffer,
* 'broadcast hub' radio (First byte of address being 0xFF means broadcast)
*/
if (haddr.c[0] == 0xFF) {
- u32 brd = 0;
+ __be32 brd = 0;
struct in_device *in_dev;
rcu_read_lock();
@@ -1406,7 +1406,7 @@ static void strip_send(struct strip *strip_info, struct sk_buff *skb)
int doreset = (long) jiffies - strip_info->watchdog_doreset >= 0;
int doprobe = (long) jiffies - strip_info->watchdog_doprobe >= 0
&& !doreset;
- u32 addr, brd;
+ __be32 addr, brd;
/*
* 1. If we have a packet, encapsulate it and put it in the buffer
diff --git a/drivers/parisc/led.c b/drivers/parisc/led.c
index bf00fa2537bb..8dac2ba82bb9 100644
--- a/drivers/parisc/led.c
+++ b/drivers/parisc/led.c
@@ -684,7 +684,7 @@ int __init led_init(void)
int ret;
snprintf(lcd_text_default, sizeof(lcd_text_default),
- "Linux %s", system_utsname.release);
+ "Linux %s", init_utsname()->release);
/* Work around the buggy PDC of KittyHawk-machines */
switch (CPU_HVERSION) {
diff --git a/drivers/parisc/power.c b/drivers/parisc/power.c
index fad5a33bf0fa..4a9f025a6b58 100644
--- a/drivers/parisc/power.c
+++ b/drivers/parisc/power.c
@@ -84,8 +84,7 @@
static void deferred_poweroff(void *dummy)
{
- extern int cad_pid; /* from kernel/sys.c */
- if (kill_proc(cad_pid, SIGINT, 1)) {
+ if (kill_cad_pid(SIGINT, 1)) {
/* just in case killing init process failed */
machine_power_off();
}
diff --git a/drivers/parport/parport_serial.c b/drivers/parport/parport_serial.c
index 98b83a85c60e..78c0a269a2ba 100644
--- a/drivers/parport/parport_serial.c
+++ b/drivers/parport/parport_serial.c
@@ -374,6 +374,7 @@ static void __devexit parport_serial_pci_remove (struct pci_dev *dev)
return;
}
+#ifdef CONFIG_PM
static int parport_serial_pci_suspend(struct pci_dev *dev, pm_message_t state)
{
struct parport_serial_private *priv = pci_get_drvdata(dev);
@@ -407,14 +408,17 @@ static int parport_serial_pci_resume(struct pci_dev *dev)
return 0;
}
+#endif
static struct pci_driver parport_serial_pci_driver = {
.name = "parport_serial",
.id_table = parport_serial_pci_tbl,
.probe = parport_serial_pci_probe,
.remove = __devexit_p(parport_serial_pci_remove),
+#ifdef CONFIG_PM
.suspend = parport_serial_pci_suspend,
.resume = parport_serial_pci_resume,
+#endif
};
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
index 08cd86a6dd66..23b599d6a9d5 100644
--- a/drivers/pci/quirks.c
+++ b/drivers/pci/quirks.c
@@ -93,8 +93,21 @@ static void __devinit quirk_nopcipci(struct pci_dev *dev)
pci_pci_problems |= PCIPCI_FAIL;
}
}
+
+static void __devinit quirk_nopciamd(struct pci_dev *dev)
+{
+ u8 rev;
+ pci_read_config_byte(dev, 0x08, &rev);
+ if (rev == 0x13) {
+ /* Erratum 24 */
+ printk(KERN_INFO "Chipset erratum: Disabling direct PCI/AGP transfers.\n");
+ pci_pci_problems |= PCIAGP_FAIL;
+ }
+}
+
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_5597, quirk_nopcipci );
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_496, quirk_nopcipci );
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8151_0, quirk_nopciamd );
/*
* Triton requires workarounds to be used by the drivers
@@ -555,7 +568,7 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8237, quirk_via_vt
* is currently marked NoFix
*
* We have multiple reports of hangs with this chipset that went away with
- * noapic specified. For the moment we assume its the errata. We may be wrong
+ * noapic specified. For the moment we assume it's the erratum. We may be wrong
* of course. However the advice is demonstrably good even if so..
*/
static void __devinit quirk_amd_ioapic(struct pci_dev *dev)
@@ -564,7 +577,7 @@ static void __devinit quirk_amd_ioapic(struct pci_dev *dev)
pci_read_config_byte(dev, PCI_REVISION_ID, &rev);
if (rev >= 0x02) {
- printk(KERN_WARNING "I/O APIC: AMD Errata #22 may be present. In the event of instability try\n");
+ printk(KERN_WARNING "I/O APIC: AMD Erratum #22 may be present. In the event of instability try\n");
printk(KERN_WARNING " : booting with the \"noapic\" option.\n");
}
}
diff --git a/drivers/pcmcia/cardbus.c b/drivers/pcmcia/cardbus.c
index 3f6d51d11374..2d7effe7990d 100644
--- a/drivers/pcmcia/cardbus.c
+++ b/drivers/pcmcia/cardbus.c
@@ -138,7 +138,7 @@ int read_cb_mem(struct pcmcia_socket * s, int space, u_int addr, u_int len, void
cs_dbg(s, 3, "read_cb_mem(%d, %#x, %u)\n", space, addr, len);
- dev = pci_find_slot(s->cb_dev->subordinate->number, 0);
+ dev = pci_get_slot(s->cb_dev->subordinate, 0);
if (!dev)
goto fail;
@@ -152,6 +152,9 @@ int read_cb_mem(struct pcmcia_socket * s, int space, u_int addr, u_int len, void
}
res = dev->resource + space - 1;
+
+ pci_dev_put(dev);
+
if (!res->flags)
goto fail;
diff --git a/drivers/pcmcia/omap_cf.c b/drivers/pcmcia/omap_cf.c
index 420e10aec0ae..01be47e72730 100644
--- a/drivers/pcmcia/omap_cf.c
+++ b/drivers/pcmcia/omap_cf.c
@@ -67,6 +67,7 @@ struct omap_cf_socket {
struct platform_device *pdev;
unsigned long phys_cf;
u_int irq;
+ struct resource iomem;
};
#define POLL_INTERVAL (2 * HZ)
@@ -112,16 +113,14 @@ static int omap_cf_get_status(struct pcmcia_socket *s, u_int *sp)
if (!sp)
return -EINVAL;
- /* FIXME power management should probably be board-specific:
- * - 3VCARD vs XVCARD (OSK only handles 3VCARD)
- * - POWERON (switched on/off by set_socket)
- */
+ /* NOTE CF is always 3VCARD */
if (omap_cf_present()) {
struct omap_cf_socket *cf;
*sp = SS_READY | SS_DETECT | SS_POWERON | SS_3VCARD;
cf = container_of(s, struct omap_cf_socket, socket);
- s->irq.AssignedIRQ = cf->irq;
+ s->irq.AssignedIRQ = 0;
+ s->pci_irq = cf->irq;
} else
*sp = 0;
return 0;
@@ -132,7 +131,7 @@ omap_cf_set_socket(struct pcmcia_socket *sock, struct socket_state_t *s)
{
u16 control;
- /* FIXME some non-OSK boards will support power switching */
+ /* REVISIT some non-OSK boards may support power switching */
switch (s->Vcc) {
case 0:
case 33:
@@ -204,7 +203,7 @@ static struct pccard_operations omap_cf_ops = {
* "what chipselect is used". Boards could want more.
*/
-static int __init omap_cf_probe(struct device *dev)
+static int __devinit omap_cf_probe(struct device *dev)
{
unsigned seg;
struct omap_cf_socket *cf;
@@ -253,6 +252,9 @@ static int __init omap_cf_probe(struct device *dev)
default:
goto fail1;
}
+ cf->iomem.start = cf->phys_cf;
+ cf->iomem.end = cf->iomem.end + SZ_8K - 1;
+ cf->iomem.flags = IORESOURCE_MEM;
/* pcmcia layer only remaps "real" memory */
cf->socket.io_offset = (unsigned long)
@@ -296,6 +298,7 @@ static int __init omap_cf_probe(struct device *dev)
cf->socket.features = SS_CAP_PCCARD | SS_CAP_STATIC_MAP
| SS_CAP_MEM_ALIGN;
cf->socket.map_size = SZ_2K;
+ cf->socket.io[0].res = &cf->iomem;
status = pcmcia_register_socket(&cf->socket);
if (status < 0)
@@ -334,15 +337,15 @@ static struct device_driver omap_cf_driver = {
.bus = &platform_bus_type,
.probe = omap_cf_probe,
.remove = __devexit_p(omap_cf_remove),
- .suspend = pcmcia_socket_dev_suspend,
- .resume = pcmcia_socket_dev_resume,
+ .suspend = pcmcia_socket_dev_suspend,
+ .resume = pcmcia_socket_dev_resume,
};
static int __init omap_cf_init(void)
{
if (cpu_is_omap16xx())
- driver_register(&omap_cf_driver);
- return 0;
+ return driver_register(&omap_cf_driver);
+ return -ENODEV;
}
static void __exit omap_cf_exit(void)
diff --git a/drivers/pcmcia/socket_sysfs.c b/drivers/pcmcia/socket_sysfs.c
index c5d7476da471..933cd864a5c9 100644
--- a/drivers/pcmcia/socket_sysfs.c
+++ b/drivers/pcmcia/socket_sysfs.c
@@ -298,7 +298,7 @@ static ssize_t pccard_store_cis(struct kobject *kobj, char *buf, loff_t off, siz
{
struct pcmcia_socket *s = to_socket(container_of(kobj, struct class_device, kobj));
cisdump_t *cis;
- ssize_t ret = count;
+ int error;
if (off)
return -EINVAL;
@@ -316,25 +316,22 @@ static ssize_t pccard_store_cis(struct kobject *kobj, char *buf, loff_t off, siz
cis->Length = count + 1;
memcpy(cis->Data, buf, count);
- if (pcmcia_replace_cis(s, cis))
- ret = -EIO;
-
+ error = pcmcia_replace_cis(s, cis);
kfree(cis);
+ if (error)
+ return -EIO;
- if (!ret) {
- mutex_lock(&s->skt_mutex);
- if ((s->callback) && (s->state & SOCKET_PRESENT) &&
- !(s->state & SOCKET_CARDBUS)) {
- if (try_module_get(s->callback->owner)) {
- s->callback->requery(s);
- module_put(s->callback->owner);
- }
+ mutex_lock(&s->skt_mutex);
+ if ((s->callback) && (s->state & SOCKET_PRESENT) &&
+ !(s->state & SOCKET_CARDBUS)) {
+ if (try_module_get(s->callback->owner)) {
+ s->callback->requery(s);
+ module_put(s->callback->owner);
}
- mutex_unlock(&s->skt_mutex);
}
+ mutex_unlock(&s->skt_mutex);
-
- return (ret);
+ return count;
}
diff --git a/drivers/pnp/isapnp/core.c b/drivers/pnp/isapnp/core.c
index f2e0179962e2..3ac5b123215a 100644
--- a/drivers/pnp/isapnp/core.c
+++ b/drivers/pnp/isapnp/core.c
@@ -1049,6 +1049,10 @@ static int __init isapnp_init(void)
printk(KERN_INFO "isapnp: ISA Plug & Play support disabled\n");
return 0;
}
+#ifdef CONFIG_PPC_MERGE
+ if (check_legacy_ioport(_PIDXR) || check_legacy_ioport(_PNPWRP))
+ return -EINVAL;
+#endif
#ifdef ISAPNP_REGION_OK
if (!request_region(_PIDXR, 1, "isapnp index")) {
printk(KERN_ERR "isapnp: Index Register 0x%x already used\n", _PIDXR);
diff --git a/drivers/pnp/pnpbios/core.c b/drivers/pnp/pnpbios/core.c
index 551f58e29810..81a6c83d89a6 100644
--- a/drivers/pnp/pnpbios/core.c
+++ b/drivers/pnp/pnpbios/core.c
@@ -526,6 +526,10 @@ static int __init pnpbios_init(void)
{
int ret;
+#if defined(CONFIG_PPC_MERGE)
+ if (check_legacy_ioport(PNPBIOS_BASE))
+ return -ENODEV;
+#endif
if (pnpbios_disabled || dmi_check_system(pnpbios_dmi_table)) {
printk(KERN_INFO "PnPBIOS: Disabled\n");
return -ENODEV;
@@ -575,6 +579,10 @@ subsys_initcall(pnpbios_init);
static int __init pnpbios_thread_init(void)
{
+#if defined(CONFIG_PPC_MERGE)
+ if (check_legacy_ioport(PNPBIOS_BASE))
+ return 0;
+#endif
if (pnpbios_disabled)
return 0;
#ifdef CONFIG_HOTPLUG
diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
index 33a7b720539b..fc766a7a611e 100644
--- a/drivers/rtc/Kconfig
+++ b/drivers/rtc/Kconfig
@@ -27,7 +27,7 @@ config RTC_HCTOSYS
help
If you say yes here, the system time will be set using
the value read from the specified RTC device. This is useful
- in order to avoid unnecessary fschk runs.
+ in order to avoid unnecessary fsck runs.
config RTC_HCTOSYS_DEVICE
string "The RTC to read the time from"
@@ -37,6 +37,13 @@ config RTC_HCTOSYS_DEVICE
The RTC device that will be used as the source for
the system time, usually rtc0.
+config RTC_DEBUG
+ bool "RTC debug support"
+ depends on RTC_CLASS = y
+ help
+ Say yes here to enable debugging support in the RTC framework
+ and individual RTC drivers.
+
comment "RTC interfaces"
depends on RTC_CLASS
@@ -45,8 +52,8 @@ config RTC_INTF_SYSFS
depends on RTC_CLASS && SYSFS
default RTC_CLASS
help
- Say yes here if you want to use your RTC using the sysfs
- interface, /sys/class/rtc/rtcX .
+ Say yes here if you want to use your RTCs using sysfs interfaces,
+ /sys/class/rtc/rtc0 through /sys/.../rtcN.
This driver can also be built as a module. If so, the module
will be called rtc-sysfs.
@@ -56,8 +63,9 @@ config RTC_INTF_PROC
depends on RTC_CLASS && PROC_FS
default RTC_CLASS
help
- Say yes here if you want to use your RTC using the proc
- interface, /proc/driver/rtc .
+ Say yes here if you want to use your first RTC through the proc
+ interface, /proc/driver/rtc. Other RTCs will not be available
+ through that API.
This driver can also be built as a module. If so, the module
will be called rtc-proc.
@@ -67,8 +75,11 @@ config RTC_INTF_DEV
depends on RTC_CLASS
default RTC_CLASS
help
- Say yes here if you want to use your RTC using the dev
- interface, /dev/rtc .
+ Say yes here if you want to use your RTCs using the /dev
+ interfaces, which "udev" sets up as /dev/rtc0 through
+ /dev/rtcN. You may want to set up a symbolic link so one
+ of these can be accessed as /dev/rtc, which is a name
+ expected by "hwclock" and some other programs.
This driver can also be built as a module. If so, the module
will be called rtc-dev.
@@ -78,7 +89,8 @@ config RTC_INTF_DEV_UIE_EMUL
depends on RTC_INTF_DEV
help
Provides an emulation for RTC_UIE if the underlaying rtc chip
- driver did not provide RTC_UIE ioctls.
+ driver does not expose RTC_UIE ioctls. Those requests generate
+ once-per-second update interrupts, used for synchronization.
comment "RTC drivers"
depends on RTC_CLASS
diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile
index e72d467ab214..3ba5ff6e6800 100644
--- a/drivers/rtc/Makefile
+++ b/drivers/rtc/Makefile
@@ -2,6 +2,10 @@
# Makefile for RTC class/drivers.
#
+ifeq ($(CONFIG_RTC_DEBUG),y)
+ EXTRA_CFLAGS += -DDEBUG
+endif
+
obj-$(CONFIG_RTC_LIB) += rtc-lib.o
obj-$(CONFIG_RTC_HCTOSYS) += hctosys.o
obj-$(CONFIG_RTC_CLASS) += rtc-core.o
diff --git a/drivers/rtc/class.c b/drivers/rtc/class.c
index 1cb61a761cb2..7a0d8ee2de9c 100644
--- a/drivers/rtc/class.c
+++ b/drivers/rtc/class.c
@@ -39,7 +39,7 @@ static void rtc_device_release(struct class_device *class_dev)
* Returns the pointer to the new struct class device.
*/
struct rtc_device *rtc_device_register(const char *name, struct device *dev,
- struct rtc_class_ops *ops,
+ const struct rtc_class_ops *ops,
struct module *owner)
{
struct rtc_device *rtc;
@@ -142,9 +142,9 @@ static void __exit rtc_exit(void)
class_destroy(rtc_class);
}
-module_init(rtc_init);
+subsys_initcall(rtc_init);
module_exit(rtc_exit);
-MODULE_AUTHOR("Alessandro Zummo <a.zummo@towerteh.it>");
+MODULE_AUTHOR("Alessandro Zummo <a.zummo@towertech.it>");
MODULE_DESCRIPTION("RTC class support");
MODULE_LICENSE("GPL");
diff --git a/drivers/rtc/rtc-at91.c b/drivers/rtc/rtc-at91.c
index dfd0ce86f6a0..c0714da44920 100644
--- a/drivers/rtc/rtc-at91.c
+++ b/drivers/rtc/rtc-at91.c
@@ -267,7 +267,7 @@ static irqreturn_t at91_rtc_interrupt(int irq, void *dev_id,
return IRQ_NONE; /* not handled */
}
-static struct rtc_class_ops at91_rtc_ops = {
+static const struct rtc_class_ops at91_rtc_ops = {
.ioctl = at91_rtc_ioctl,
.read_time = at91_rtc_readtime,
.set_time = at91_rtc_settime,
@@ -307,6 +307,7 @@ static int __init at91_rtc_probe(struct platform_device *pdev)
return PTR_ERR(rtc);
}
platform_set_drvdata(pdev, rtc);
+ device_init_wakeup(&pdev->dev, 1);
printk(KERN_INFO "AT91 Real Time Clock driver.\n");
return 0;
@@ -327,6 +328,7 @@ static int __devexit at91_rtc_remove(struct platform_device *pdev)
rtc_device_unregister(rtc);
platform_set_drvdata(pdev, NULL);
+ device_init_wakeup(&pdev->dev, 0);
return 0;
}
@@ -336,6 +338,7 @@ static int __devexit at91_rtc_remove(struct platform_device *pdev)
/* AT91RM9200 RTC Power management control */
static struct timespec at91_rtc_delta;
+static u32 at91_rtc_imr;
static int at91_rtc_suspend(struct platform_device *pdev, pm_message_t state)
{
@@ -349,6 +352,18 @@ static int at91_rtc_suspend(struct platform_device *pdev, pm_message_t state)
rtc_tm_to_time(&tm, &time.tv_sec);
save_time_delta(&at91_rtc_delta, &time);
+ /* this IRQ is shared with DBGU and other hardware which isn't
+ * necessarily doing PM like we are...
+ */
+ at91_rtc_imr = at91_sys_read(AT91_RTC_IMR)
+ & (AT91_RTC_ALARM|AT91_RTC_SECEV);
+ if (at91_rtc_imr) {
+ if (device_may_wakeup(&pdev->dev))
+ enable_irq_wake(AT91_ID_SYS);
+ else
+ at91_sys_write(AT91_RTC_IDR, at91_rtc_imr);
+ }
+
pr_debug("%s(): %4d-%02d-%02d %02d:%02d:%02d\n", __FUNCTION__,
1900 + tm.tm_year, tm.tm_mon, tm.tm_mday,
tm.tm_hour, tm.tm_min, tm.tm_sec);
@@ -367,6 +382,13 @@ static int at91_rtc_resume(struct platform_device *pdev)
rtc_tm_to_time(&tm, &time.tv_sec);
restore_time_delta(&at91_rtc_delta, &time);
+ if (at91_rtc_imr) {
+ if (device_may_wakeup(&pdev->dev))
+ disable_irq_wake(AT91_ID_SYS);
+ else
+ at91_sys_write(AT91_RTC_IER, at91_rtc_imr);
+ }
+
pr_debug("%s(): %4d-%02d-%02d %02d:%02d:%02d\n", __FUNCTION__,
1900 + tm.tm_year, tm.tm_mon, tm.tm_mday,
tm.tm_hour, tm.tm_min, tm.tm_sec);
diff --git a/drivers/rtc/rtc-dev.c b/drivers/rtc/rtc-dev.c
index 61a58259c93f..583789c66cdb 100644
--- a/drivers/rtc/rtc-dev.c
+++ b/drivers/rtc/rtc-dev.c
@@ -24,7 +24,7 @@ static int rtc_dev_open(struct inode *inode, struct file *file)
int err;
struct rtc_device *rtc = container_of(inode->i_cdev,
struct rtc_device, char_dev);
- struct rtc_class_ops *ops = rtc->ops;
+ const struct rtc_class_ops *ops = rtc->ops;
/* We keep the lock as long as the device is in use
* and return immediately if busy
@@ -209,7 +209,7 @@ static int rtc_dev_ioctl(struct inode *inode, struct file *file,
int err = 0;
struct class_device *class_dev = file->private_data;
struct rtc_device *rtc = to_rtc_device(class_dev);
- struct rtc_class_ops *ops = rtc->ops;
+ const struct rtc_class_ops *ops = rtc->ops;
struct rtc_time tm;
struct rtc_wkalrm alarm;
void __user *uarg = (void __user *) arg;
@@ -406,7 +406,6 @@ static int rtc_dev_add_device(struct class_device *class_dev,
rtc->char_dev.owner = rtc->owner;
if (cdev_add(&rtc->char_dev, MKDEV(MAJOR(rtc_devt), rtc->id), 1)) {
- cdev_del(&rtc->char_dev);
dev_err(class_dev->dev,
"failed to add char device %d:%d\n",
MAJOR(rtc_devt), rtc->id);
@@ -496,7 +495,7 @@ static void __exit rtc_dev_exit(void)
unregister_chrdev_region(rtc_devt, RTC_DEV_MAX);
}
-module_init(rtc_dev_init);
+subsys_initcall(rtc_dev_init);
module_exit(rtc_dev_exit);
MODULE_AUTHOR("Alessandro Zummo <a.zummo@towertech.it>");
diff --git a/drivers/rtc/rtc-ds1307.c b/drivers/rtc/rtc-ds1307.c
index e8afb9384786..cc5032b6f42a 100644
--- a/drivers/rtc/rtc-ds1307.c
+++ b/drivers/rtc/rtc-ds1307.c
@@ -178,7 +178,7 @@ static int ds1307_set_time(struct device *dev, struct rtc_time *t)
return 0;
}
-static struct rtc_class_ops ds13xx_rtc_ops = {
+static const struct rtc_class_ops ds13xx_rtc_ops = {
.read_time = ds1307_get_time,
.set_time = ds1307_set_time,
};
diff --git a/drivers/rtc/rtc-ds1553.c b/drivers/rtc/rtc-ds1553.c
index 209001495474..9647188fee2c 100644
--- a/drivers/rtc/rtc-ds1553.c
+++ b/drivers/rtc/rtc-ds1553.c
@@ -18,7 +18,7 @@
#include <linux/platform_device.h>
#include <linux/io.h>
-#define DRV_VERSION "0.1"
+#define DRV_VERSION "0.2"
#define RTC_REG_SIZE 0x2000
#define RTC_OFFSET 0x1ff0
@@ -250,7 +250,7 @@ static int ds1553_rtc_ioctl(struct device *dev, unsigned int cmd,
return 0;
}
-static struct rtc_class_ops ds1553_rtc_ops = {
+static const struct rtc_class_ops ds1553_rtc_ops = {
.read_time = ds1553_rtc_read_time,
.set_time = ds1553_rtc_set_time,
.read_alarm = ds1553_rtc_read_alarm,
@@ -357,9 +357,13 @@ static int __init ds1553_rtc_probe(struct platform_device *pdev)
pdata->rtc = rtc;
pdata->last_jiffies = jiffies;
platform_set_drvdata(pdev, pdata);
- sysfs_create_bin_file(&pdev->dev.kobj, &ds1553_nvram_attr);
+ ret = sysfs_create_bin_file(&pdev->dev.kobj, &ds1553_nvram_attr);
+ if (ret)
+ goto out;
return 0;
out:
+ if (pdata->rtc)
+ rtc_device_unregister(pdata->rtc);
if (pdata->irq >= 0)
free_irq(pdata->irq, pdev);
if (ioaddr)
diff --git a/drivers/rtc/rtc-ds1672.c b/drivers/rtc/rtc-ds1672.c
index 9be81fd4737c..9c68ec99afa5 100644
--- a/drivers/rtc/rtc-ds1672.c
+++ b/drivers/rtc/rtc-ds1672.c
@@ -156,7 +156,7 @@ static ssize_t show_control(struct device *dev, struct device_attribute *attr, c
}
static DEVICE_ATTR(control, S_IRUGO, show_control, NULL);
-static struct rtc_class_ops ds1672_rtc_ops = {
+static const struct rtc_class_ops ds1672_rtc_ops = {
.read_time = ds1672_rtc_read_time,
.set_time = ds1672_rtc_set_time,
.set_mmss = ds1672_rtc_set_mmss,
diff --git a/drivers/rtc/rtc-ds1742.c b/drivers/rtc/rtc-ds1742.c
index 8e47e5a06d2a..6273a3d240a2 100644
--- a/drivers/rtc/rtc-ds1742.c
+++ b/drivers/rtc/rtc-ds1742.c
@@ -17,7 +17,7 @@
#include <linux/platform_device.h>
#include <linux/io.h>
-#define DRV_VERSION "0.1"
+#define DRV_VERSION "0.2"
#define RTC_REG_SIZE 0x800
#define RTC_OFFSET 0x7f8
@@ -116,7 +116,7 @@ static int ds1742_rtc_read_time(struct device *dev, struct rtc_time *tm)
return 0;
}
-static struct rtc_class_ops ds1742_rtc_ops = {
+static const struct rtc_class_ops ds1742_rtc_ops = {
.read_time = ds1742_rtc_read_time,
.set_time = ds1742_rtc_set_time,
};
@@ -196,7 +196,7 @@ static int __init ds1742_rtc_probe(struct platform_device *pdev)
writeb(sec, ioaddr + RTC_SECONDS);
writeb(cen & RTC_CENTURY_MASK, ioaddr + RTC_CONTROL);
}
- if (readb(ioaddr + RTC_DAY) & RTC_BATT_FLAG)
+ if (!(readb(ioaddr + RTC_DAY) & RTC_BATT_FLAG))
dev_warn(&pdev->dev, "voltage-low detected.\n");
rtc = rtc_device_register(pdev->name, &pdev->dev,
@@ -208,9 +208,13 @@ static int __init ds1742_rtc_probe(struct platform_device *pdev)
pdata->rtc = rtc;
pdata->last_jiffies = jiffies;
platform_set_drvdata(pdev, pdata);
- sysfs_create_bin_file(&pdev->dev.kobj, &ds1742_nvram_attr);
+ ret = sysfs_create_bin_file(&pdev->dev.kobj, &ds1742_nvram_attr);
+ if (ret)
+ goto out;
return 0;
out:
+ if (pdata->rtc)
+ rtc_device_unregister(pdata->rtc);
if (ioaddr)
iounmap(ioaddr);
if (pdata->baseaddr)
diff --git a/drivers/rtc/rtc-ep93xx.c b/drivers/rtc/rtc-ep93xx.c
index e1a1169e4664..ef4f147f3c0c 100644
--- a/drivers/rtc/rtc-ep93xx.c
+++ b/drivers/rtc/rtc-ep93xx.c
@@ -73,7 +73,7 @@ static int ep93xx_rtc_proc(struct device *dev, struct seq_file *seq)
return 0;
}
-static struct rtc_class_ops ep93xx_rtc_ops = {
+static const struct rtc_class_ops ep93xx_rtc_ops = {
.read_time = ep93xx_rtc_read_time,
.set_time = ep93xx_rtc_set_time,
.set_mmss = ep93xx_rtc_set_mmss,
diff --git a/drivers/rtc/rtc-isl1208.c b/drivers/rtc/rtc-isl1208.c
index f324d0a635d4..1c743641b73b 100644
--- a/drivers/rtc/rtc-isl1208.c
+++ b/drivers/rtc/rtc-isl1208.c
@@ -390,7 +390,7 @@ static int isl1208_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alarm)
return isl1208_i2c_read_alarm(to_i2c_client(dev), alarm);
}
-static struct rtc_class_ops isl1208_rtc_ops = {
+static const struct rtc_class_ops isl1208_rtc_ops = {
.proc = isl1208_rtc_proc,
.read_time = isl1208_rtc_read_time,
.set_time = isl1208_rtc_set_time,
diff --git a/drivers/rtc/rtc-lib.c b/drivers/rtc/rtc-lib.c
index 9812120f3a7c..ba795a4db1e9 100644
--- a/drivers/rtc/rtc-lib.c
+++ b/drivers/rtc/rtc-lib.c
@@ -94,12 +94,12 @@ EXPORT_SYMBOL(rtc_time_to_tm);
int rtc_valid_tm(struct rtc_time *tm)
{
if (tm->tm_year < 70
- || tm->tm_mon >= 12
+ || ((unsigned)tm->tm_mon) >= 12
|| tm->tm_mday < 1
|| tm->tm_mday > rtc_month_days(tm->tm_mon, tm->tm_year + 1900)
- || tm->tm_hour >= 24
- || tm->tm_min >= 60
- || tm->tm_sec >= 60)
+ || ((unsigned)tm->tm_hour) >= 24
+ || ((unsigned)tm->tm_min) >= 60
+ || ((unsigned)tm->tm_sec) >= 60)
return -EINVAL;
return 0;
diff --git a/drivers/rtc/rtc-m48t86.c b/drivers/rtc/rtc-m48t86.c
index 8c0d1a6739ad..8ff4a1221f59 100644
--- a/drivers/rtc/rtc-m48t86.c
+++ b/drivers/rtc/rtc-m48t86.c
@@ -138,7 +138,7 @@ static int m48t86_rtc_proc(struct device *dev, struct seq_file *seq)
return 0;
}
-static struct rtc_class_ops m48t86_rtc_ops = {
+static const struct rtc_class_ops m48t86_rtc_ops = {
.read_time = m48t86_rtc_read_time,
.set_time = m48t86_rtc_set_time,
.proc = m48t86_rtc_proc,
diff --git a/drivers/rtc/rtc-max6902.c b/drivers/rtc/rtc-max6902.c
index 2c9739562b5c..9eeef964663a 100644
--- a/drivers/rtc/rtc-max6902.c
+++ b/drivers/rtc/rtc-max6902.c
@@ -207,7 +207,7 @@ static int max6902_set_time(struct device *dev, struct rtc_time *tm)
return max6902_set_datetime(dev, tm);
}
-static struct rtc_class_ops max6902_rtc_ops = {
+static const struct rtc_class_ops max6902_rtc_ops = {
.read_time = max6902_read_time,
.set_time = max6902_set_time,
};
diff --git a/drivers/rtc/rtc-pcf8563.c b/drivers/rtc/rtc-pcf8563.c
index ba9a583b7b68..a760cf69af90 100644
--- a/drivers/rtc/rtc-pcf8563.c
+++ b/drivers/rtc/rtc-pcf8563.c
@@ -95,7 +95,7 @@ static int pcf8563_get_datetime(struct i2c_client *client, struct rtc_time *tm)
tm->tm_wday = buf[PCF8563_REG_DW] & 0x07;
tm->tm_mon = BCD2BIN(buf[PCF8563_REG_MO] & 0x1F) - 1; /* rtc mn 1-12 */
tm->tm_year = BCD2BIN(buf[PCF8563_REG_YR])
- + (buf[PCF8563_REG_MO] & PCF8563_MO_C ? 100 : 0);
+ + (buf[PCF8563_REG_MO] & PCF8563_MO_C ? 0 : 100);
dev_dbg(&client->dev, "%s: tm is secs=%d, mins=%d, hours=%d, "
"mday=%d, mon=%d, year=%d, wday=%d\n",
@@ -135,7 +135,7 @@ static int pcf8563_set_datetime(struct i2c_client *client, struct rtc_time *tm)
/* year and century */
buf[PCF8563_REG_YR] = BIN2BCD(tm->tm_year % 100);
- if (tm->tm_year / 100)
+ if (tm->tm_year < 100)
buf[PCF8563_REG_MO] |= PCF8563_MO_C;
buf[PCF8563_REG_DW] = tm->tm_wday & 0x07;
@@ -227,7 +227,7 @@ static int pcf8563_rtc_set_time(struct device *dev, struct rtc_time *tm)
return pcf8563_set_datetime(to_i2c_client(dev), tm);
}
-static struct rtc_class_ops pcf8563_rtc_ops = {
+static const struct rtc_class_ops pcf8563_rtc_ops = {
.read_time = pcf8563_rtc_read_time,
.set_time = pcf8563_rtc_set_time,
};
diff --git a/drivers/rtc/rtc-pcf8583.c b/drivers/rtc/rtc-pcf8583.c
index b235a30cb661..5875ebb8c79d 100644
--- a/drivers/rtc/rtc-pcf8583.c
+++ b/drivers/rtc/rtc-pcf8583.c
@@ -273,7 +273,7 @@ static int pcf8583_rtc_set_time(struct device *dev, struct rtc_time *tm)
return ret;
}
-static struct rtc_class_ops pcf8583_rtc_ops = {
+static const struct rtc_class_ops pcf8583_rtc_ops = {
.read_time = pcf8583_rtc_read_time,
.set_time = pcf8583_rtc_set_time,
};
diff --git a/drivers/rtc/rtc-pl031.c b/drivers/rtc/rtc-pl031.c
index d6d1c5726b0e..739d1a6e14eb 100644
--- a/drivers/rtc/rtc-pl031.c
+++ b/drivers/rtc/rtc-pl031.c
@@ -128,7 +128,7 @@ static int pl031_set_alarm(struct device *dev, struct rtc_wkalrm *alarm)
return 0;
}
-static struct rtc_class_ops pl031_ops = {
+static const struct rtc_class_ops pl031_ops = {
.open = pl031_open,
.release = pl031_release,
.ioctl = pl031_ioctl,
diff --git a/drivers/rtc/rtc-proc.c b/drivers/rtc/rtc-proc.c
index cef5f5a3bbf9..d51d8f20e634 100644
--- a/drivers/rtc/rtc-proc.c
+++ b/drivers/rtc/rtc-proc.c
@@ -23,7 +23,7 @@ static int rtc_proc_show(struct seq_file *seq, void *offset)
{
int err;
struct class_device *class_dev = seq->private;
- struct rtc_class_ops *ops = to_rtc_device(class_dev)->ops;
+ const struct rtc_class_ops *ops = to_rtc_device(class_dev)->ops;
struct rtc_wkalrm alrm;
struct rtc_time tm;
@@ -61,7 +61,7 @@ static int rtc_proc_show(struct seq_file *seq, void *offset)
seq_printf(seq, "%02d-", alrm.time.tm_mon + 1);
else
seq_printf(seq, "**-");
- if ((unsigned int)alrm.time.tm_mday <= 31)
+ if (alrm.time.tm_mday && (unsigned int)alrm.time.tm_mday <= 31)
seq_printf(seq, "%02d\n", alrm.time.tm_mday);
else
seq_printf(seq, "**\n");
@@ -156,7 +156,7 @@ static void __exit rtc_proc_exit(void)
class_interface_unregister(&rtc_proc_interface);
}
-module_init(rtc_proc_init);
+subsys_initcall(rtc_proc_init);
module_exit(rtc_proc_exit);
MODULE_AUTHOR("Alessandro Zummo <a.zummo@towertech.it>");
diff --git a/drivers/rtc/rtc-rs5c348.c b/drivers/rtc/rtc-rs5c348.c
index 0964d1dba925..f50f3fc353cd 100644
--- a/drivers/rtc/rtc-rs5c348.c
+++ b/drivers/rtc/rtc-rs5c348.c
@@ -23,7 +23,7 @@
#include <linux/workqueue.h>
#include <linux/spi/spi.h>
-#define DRV_VERSION "0.1"
+#define DRV_VERSION "0.2"
#define RS5C348_REG_SECS 0
#define RS5C348_REG_MINS 1
@@ -140,7 +140,7 @@ rs5c348_rtc_read_time(struct device *dev, struct rtc_time *tm)
return 0;
}
-static struct rtc_class_ops rs5c348_rtc_ops = {
+static const struct rtc_class_ops rs5c348_rtc_ops = {
.read_time = rs5c348_rtc_read_time,
.set_time = rs5c348_rtc_set_time,
};
@@ -175,8 +175,15 @@ static int __devinit rs5c348_probe(struct spi_device *spi)
goto kfree_exit;
if (ret & (RS5C348_BIT_XSTP | RS5C348_BIT_VDET)) {
u8 buf[2];
+ struct rtc_time tm;
if (ret & RS5C348_BIT_VDET)
dev_warn(&spi->dev, "voltage-low detected.\n");
+ if (ret & RS5C348_BIT_XSTP)
+ dev_warn(&spi->dev, "oscillator-stop detected.\n");
+ rtc_time_to_tm(0, &tm); /* 1970/1/1 */
+ ret = rs5c348_rtc_set_time(&spi->dev, &tm);
+ if (ret < 0)
+ goto kfree_exit;
buf[0] = RS5C348_CMD_W(RS5C348_REG_CTL2);
buf[1] = 0;
ret = spi_write_then_read(spi, buf, sizeof(buf), NULL, 0);
diff --git a/drivers/rtc/rtc-rs5c372.c b/drivers/rtc/rtc-rs5c372.c
index 7553d797603f..bbdad099471d 100644
--- a/drivers/rtc/rtc-rs5c372.c
+++ b/drivers/rtc/rtc-rs5c372.c
@@ -160,7 +160,7 @@ static int rs5c372_rtc_proc(struct device *dev, struct seq_file *seq)
return 0;
}
-static struct rtc_class_ops rs5c372_rtc_ops = {
+static const struct rtc_class_ops rs5c372_rtc_ops = {
.proc = rs5c372_rtc_proc,
.read_time = rs5c372_rtc_read_time,
.set_time = rs5c372_rtc_set_time,
diff --git a/drivers/rtc/rtc-s3c.c b/drivers/rtc/rtc-s3c.c
index 2c7de79c83b9..625dad2eeb4f 100644
--- a/drivers/rtc/rtc-s3c.c
+++ b/drivers/rtc/rtc-s3c.c
@@ -386,7 +386,7 @@ static void s3c_rtc_release(struct device *dev)
free_irq(s3c_rtc_tickno, rtc_dev);
}
-static struct rtc_class_ops s3c_rtcops = {
+static const struct rtc_class_ops s3c_rtcops = {
.open = s3c_rtc_open,
.release = s3c_rtc_release,
.ioctl = s3c_rtc_ioctl,
diff --git a/drivers/rtc/rtc-sa1100.c b/drivers/rtc/rtc-sa1100.c
index ee4b61ee67b0..439c41aea31c 100644
--- a/drivers/rtc/rtc-sa1100.c
+++ b/drivers/rtc/rtc-sa1100.c
@@ -303,7 +303,7 @@ static int sa1100_rtc_proc(struct device *dev, struct seq_file *seq)
return 0;
}
-static struct rtc_class_ops sa1100_rtc_ops = {
+static const struct rtc_class_ops sa1100_rtc_ops = {
.open = sa1100_rtc_open,
.read_callback = sa1100_rtc_read_callback,
.release = sa1100_rtc_release,
diff --git a/drivers/rtc/rtc-sysfs.c b/drivers/rtc/rtc-sysfs.c
index 7c1f3d2e53c4..625637b84d33 100644
--- a/drivers/rtc/rtc-sysfs.c
+++ b/drivers/rtc/rtc-sysfs.c
@@ -116,7 +116,7 @@ static void __exit rtc_sysfs_exit(void)
class_interface_unregister(&rtc_sysfs_interface);
}
-module_init(rtc_sysfs_init);
+subsys_initcall(rtc_sysfs_init);
module_exit(rtc_sysfs_exit);
MODULE_AUTHOR("Alessandro Zummo <a.zummo@towertech.it>");
diff --git a/drivers/rtc/rtc-test.c b/drivers/rtc/rtc-test.c
index e1fa5fe7901f..bc4bd24508a2 100644
--- a/drivers/rtc/rtc-test.c
+++ b/drivers/rtc/rtc-test.c
@@ -75,7 +75,7 @@ static int test_rtc_ioctl(struct device *dev, unsigned int cmd,
}
}
-static struct rtc_class_ops test_rtc_ops = {
+static const struct rtc_class_ops test_rtc_ops = {
.proc = test_rtc_proc,
.read_time = test_rtc_read_time,
.set_time = test_rtc_set_time,
diff --git a/drivers/rtc/rtc-v3020.c b/drivers/rtc/rtc-v3020.c
index a40f400acff6..09b714f1cdc3 100644
--- a/drivers/rtc/rtc-v3020.c
+++ b/drivers/rtc/rtc-v3020.c
@@ -149,7 +149,7 @@ static int v3020_set_time(struct device *dev, struct rtc_time *dt)
return 0;
}
-static struct rtc_class_ops v3020_rtc_ops = {
+static const struct rtc_class_ops v3020_rtc_ops = {
.read_time = v3020_read_time,
.set_time = v3020_set_time,
};
@@ -169,9 +169,6 @@ static int rtc_probe(struct platform_device *pdev)
if (pdev->resource[0].flags != IORESOURCE_MEM)
return -EBUSY;
- if (pdev == NULL)
- return -EBUSY;
-
chip = kzalloc(sizeof *chip, GFP_KERNEL);
if (!chip)
return -ENOMEM;
diff --git a/drivers/rtc/rtc-vr41xx.c b/drivers/rtc/rtc-vr41xx.c
index 596764fd29f5..58e5ed0aa127 100644
--- a/drivers/rtc/rtc-vr41xx.c
+++ b/drivers/rtc/rtc-vr41xx.c
@@ -296,7 +296,7 @@ static irqreturn_t rtclong1_interrupt(int irq, void *dev_id, struct pt_regs *reg
return IRQ_HANDLED;
}
-static struct rtc_class_ops vr41xx_rtc_ops = {
+static const struct rtc_class_ops vr41xx_rtc_ops = {
.release = vr41xx_rtc_release,
.ioctl = vr41xx_rtc_ioctl,
.read_time = vr41xx_rtc_read_time,
diff --git a/drivers/rtc/rtc-x1205.c b/drivers/rtc/rtc-x1205.c
index 788b6d1f8f2f..522c69753bbf 100644
--- a/drivers/rtc/rtc-x1205.c
+++ b/drivers/rtc/rtc-x1205.c
@@ -460,7 +460,7 @@ static int x1205_rtc_proc(struct device *dev, struct seq_file *seq)
return 0;
}
-static struct rtc_class_ops x1205_rtc_ops = {
+static const struct rtc_class_ops x1205_rtc_ops = {
.proc = x1205_rtc_proc,
.read_time = x1205_rtc_read_time,
.set_time = x1205_rtc_set_time,
diff --git a/drivers/s390/block/Kconfig b/drivers/s390/block/Kconfig
index 929d6fff6152..b250c5354503 100644
--- a/drivers/s390/block/Kconfig
+++ b/drivers/s390/block/Kconfig
@@ -1,4 +1,4 @@
-if S390
+if S390 && BLOCK
comment "S/390 block device drivers"
depends on S390
diff --git a/drivers/s390/block/dasd_diag.c b/drivers/s390/block/dasd_diag.c
index 9d051e5687ea..222a8a71a5e8 100644
--- a/drivers/s390/block/dasd_diag.c
+++ b/drivers/s390/block/dasd_diag.c
@@ -529,7 +529,7 @@ dasd_diag_build_cp(struct dasd_device * device, struct request *req)
}
cqr->retries = DIAG_MAX_RETRIES;
cqr->buildclk = get_clock();
- if (req->flags & REQ_FAILFAST)
+ if (req->cmd_flags & REQ_FAILFAST)
set_bit(DASD_CQR_FLAGS_FAILFAST, &cqr->flags);
cqr->device = device;
cqr->expires = DIAG_TIMEOUT;
diff --git a/drivers/s390/block/dasd_eckd.c b/drivers/s390/block/dasd_eckd.c
index b7a7fac3f7c3..5ecea3e4fdef 100644
--- a/drivers/s390/block/dasd_eckd.c
+++ b/drivers/s390/block/dasd_eckd.c
@@ -1266,7 +1266,7 @@ dasd_eckd_build_cp(struct dasd_device * device, struct request *req)
recid++;
}
}
- if (req->flags & REQ_FAILFAST)
+ if (req->cmd_flags & REQ_FAILFAST)
set_bit(DASD_CQR_FLAGS_FAILFAST, &cqr->flags);
cqr->device = device;
cqr->expires = 5 * 60 * HZ; /* 5 minutes */
diff --git a/drivers/s390/block/dasd_fba.c b/drivers/s390/block/dasd_fba.c
index e85015be109b..80926c548228 100644
--- a/drivers/s390/block/dasd_fba.c
+++ b/drivers/s390/block/dasd_fba.c
@@ -344,7 +344,7 @@ dasd_fba_build_cp(struct dasd_device * device, struct request *req)
recid++;
}
}
- if (req->flags & REQ_FAILFAST)
+ if (req->cmd_flags & REQ_FAILFAST)
set_bit(DASD_CQR_FLAGS_FAILFAST, &cqr->flags);
cqr->device = device;
cqr->expires = 5 * 60 * HZ; /* 5 minutes */
diff --git a/drivers/s390/char/con3215.c b/drivers/s390/char/con3215.c
index 2fa566fa6da4..d7de175d53f0 100644
--- a/drivers/s390/char/con3215.c
+++ b/drivers/s390/char/con3215.c
@@ -1103,7 +1103,7 @@ tty3215_start(struct tty_struct *tty)
}
}
-static struct tty_operations tty3215_ops = {
+static const struct tty_operations tty3215_ops = {
.open = tty3215_open,
.close = tty3215_close,
.write = tty3215_write,
diff --git a/drivers/s390/char/fs3270.c b/drivers/s390/char/fs3270.c
index b4557fa30858..78f8bda81dae 100644
--- a/drivers/s390/char/fs3270.c
+++ b/drivers/s390/char/fs3270.c
@@ -27,7 +27,7 @@ struct raw3270_fn fs3270_fn;
struct fs3270 {
struct raw3270_view view;
- pid_t fs_pid; /* Pid of controlling program. */
+ struct pid *fs_pid; /* Pid of controlling program. */
int read_command; /* ccw command to use for reads. */
int write_command; /* ccw command to use for writes. */
int attention; /* Got attention. */
@@ -102,7 +102,7 @@ fs3270_restore_callback(struct raw3270_request *rq, void *data)
fp = (struct fs3270 *) rq->view;
if (rq->rc != 0 || rq->rescnt != 0) {
if (fp->fs_pid)
- kill_proc(fp->fs_pid, SIGHUP, 1);
+ kill_pid(fp->fs_pid, SIGHUP, 1);
}
fp->rdbuf_size = 0;
raw3270_request_reset(rq);
@@ -173,7 +173,7 @@ fs3270_save_callback(struct raw3270_request *rq, void *data)
*/
if (rq->rc != 0 || rq->rescnt == 0) {
if (fp->fs_pid)
- kill_proc(fp->fs_pid, SIGHUP, 1);
+ kill_pid(fp->fs_pid, SIGHUP, 1);
fp->rdbuf_size = 0;
} else
fp->rdbuf_size = fp->rdbuf->size - rq->rescnt;
@@ -442,7 +442,7 @@ fs3270_open(struct inode *inode, struct file *filp)
return PTR_ERR(fp);
init_waitqueue_head(&fp->wait);
- fp->fs_pid = current->pid;
+ fp->fs_pid = get_pid(task_pid(current));
rc = raw3270_add_view(&fp->view, &fs3270_fn, minor);
if (rc) {
fs3270_free_view(&fp->view);
@@ -480,7 +480,8 @@ fs3270_close(struct inode *inode, struct file *filp)
fp = filp->private_data;
filp->private_data = NULL;
if (fp) {
- fp->fs_pid = 0;
+ put_pid(fp->fs_pid);
+ fp->fs_pid = NULL;
raw3270_reset(&fp->view);
raw3270_put_view(&fp->view);
raw3270_del_view(&fp->view);
diff --git a/drivers/s390/char/sclp_tty.c b/drivers/s390/char/sclp_tty.c
index f6cf9023039e..6f43e04dbefd 100644
--- a/drivers/s390/char/sclp_tty.c
+++ b/drivers/s390/char/sclp_tty.c
@@ -711,7 +711,7 @@ static struct sclp_register sclp_input_event =
.receiver_fn = sclp_tty_receiver
};
-static struct tty_operations sclp_ops = {
+static const struct tty_operations sclp_ops = {
.open = sclp_tty_open,
.close = sclp_tty_close,
.write = sclp_tty_write,
diff --git a/drivers/s390/char/sclp_vt220.c b/drivers/s390/char/sclp_vt220.c
index 54fba6f17188..723bf4191bfe 100644
--- a/drivers/s390/char/sclp_vt220.c
+++ b/drivers/s390/char/sclp_vt220.c
@@ -655,7 +655,7 @@ __sclp_vt220_init(int early)
return 0;
}
-static struct tty_operations sclp_vt220_ops = {
+static const struct tty_operations sclp_vt220_ops = {
.open = sclp_vt220_open,
.close = sclp_vt220_close,
.write = sclp_vt220_write,
diff --git a/drivers/s390/char/tty3270.c b/drivers/s390/char/tty3270.c
index 06e2eeec8473..4717c3611601 100644
--- a/drivers/s390/char/tty3270.c
+++ b/drivers/s390/char/tty3270.c
@@ -1737,7 +1737,7 @@ tty3270_ioctl(struct tty_struct *tty, struct file *file,
return kbd_ioctl(tp->kbd, file, cmd, arg);
}
-static struct tty_operations tty3270_ops = {
+static const struct tty_operations tty3270_ops = {
.open = tty3270_open,
.close = tty3270_close,
.write = tty3270_write,
diff --git a/drivers/s390/net/qeth_main.c b/drivers/s390/net/qeth_main.c
index 5613b4564fa2..8364d5475ac7 100644
--- a/drivers/s390/net/qeth_main.c
+++ b/drivers/s390/net/qeth_main.c
@@ -8067,7 +8067,7 @@ qeth_arp_constructor(struct neighbour *neigh)
neigh->parms = neigh_parms_clone(parms);
rcu_read_unlock();
- neigh->type = inet_addr_type(*(u32 *) neigh->primary_key);
+ neigh->type = inet_addr_type(*(__be32 *) neigh->primary_key);
neigh->nud_state = NUD_NOARP;
neigh->ops = arp_direct_ops;
neigh->output = neigh->ops->queue_xmit;
diff --git a/drivers/s390/s390mach.c b/drivers/s390/s390mach.c
index 479364d0332a..e088b5e28711 100644
--- a/drivers/s390/s390mach.c
+++ b/drivers/s390/s390mach.c
@@ -208,7 +208,7 @@ s390_handle_mcck(void)
*/
__ctl_clear_bit(14, 24); /* Disable WARNING MCH */
if (xchg(&mchchk_wng_posted, 1) == 0)
- kill_proc(1, SIGPWR, 1);
+ kill_cad_pid(SIGPWR, 1);
}
#endif
diff --git a/drivers/s390/scsi/zfcp_scsi.c b/drivers/s390/scsi/zfcp_scsi.c
index 7cafa34e4c7f..4d2bc7981324 100644
--- a/drivers/s390/scsi/zfcp_scsi.c
+++ b/drivers/s390/scsi/zfcp_scsi.c
@@ -301,7 +301,7 @@ zfcp_scsi_command_sync(struct zfcp_unit *unit, struct scsi_cmnd *scpnt,
int use_timer)
{
int ret;
- DECLARE_COMPLETION(wait);
+ DECLARE_COMPLETION_ONSTACK(wait);
scpnt->SCp.ptr = (void *) &wait; /* silent re-use */
scpnt->scsi_done = zfcp_scsi_command_sync_handler;
diff --git a/drivers/sbus/char/aurora.c b/drivers/sbus/char/aurora.c
index 4fdb2c932210..a305d4091547 100644
--- a/drivers/sbus/char/aurora.c
+++ b/drivers/sbus/char/aurora.c
@@ -2187,7 +2187,7 @@ static void do_softint(void *private_)
#endif
}
-static struct tty_operations aurora_ops = {
+static const struct tty_operations aurora_ops = {
.open = aurora_open,
.close = aurora_close,
.write = aurora_write,
diff --git a/drivers/sbus/char/bbc_envctrl.c b/drivers/sbus/char/bbc_envctrl.c
index 1cc706e11119..d27e4f6d7045 100644
--- a/drivers/sbus/char/bbc_envctrl.c
+++ b/drivers/sbus/char/bbc_envctrl.c
@@ -4,9 +4,6 @@
* Copyright (C) 2001 David S. Miller (davem@redhat.com)
*/
-#define __KERNEL_SYSCALLS__
-static int errno;
-
#include <linux/kernel.h>
#include <linux/kthread.h>
#include <linux/sched.h>
@@ -200,7 +197,7 @@ static void do_envctrl_shutdown(struct bbc_cpu_temperature *tp)
printk(KERN_CRIT "kenvctrld: Shutting down the system now.\n");
shutting_down = 1;
- if (execve("/sbin/shutdown", argv, envp) < 0)
+ if (kernel_execve("/sbin/shutdown", argv, envp) < 0)
printk(KERN_CRIT "envctrl: shutdown execution failed\n");
}
diff --git a/drivers/sbus/char/envctrl.c b/drivers/sbus/char/envctrl.c
index 063e676a3ac0..728a133d0fc5 100644
--- a/drivers/sbus/char/envctrl.c
+++ b/drivers/sbus/char/envctrl.c
@@ -19,9 +19,6 @@
* Daniele Bellucci <bellucda@tiscali.it>
*/
-#define __KERNEL_SYSCALLS__
-static int errno;
-
#include <linux/module.h>
#include <linux/sched.h>
#include <linux/kthread.h>
@@ -976,13 +973,15 @@ static void envctrl_do_shutdown(void)
"HOME=/", "TERM=linux", "PATH=/sbin:/usr/sbin:/bin:/usr/bin", NULL };
char *argv[] = {
"/sbin/shutdown", "-h", "now", NULL };
+ int ret;
if (inprog != 0)
return;
inprog = 1;
printk(KERN_CRIT "kenvctrld: WARNING: Shutting down the system now.\n");
- if (0 > execve("/sbin/shutdown", argv, envp)) {
+ ret = kernel_execve("/sbin/shutdown", argv, envp);
+ if (ret < 0) {
printk(KERN_CRIT "kenvctrld: WARNING: system shutdown failed!\n");
inprog = 0; /* unlikely to succeed, but we could try again */
}
diff --git a/drivers/scsi/53c700.c b/drivers/scsi/53c700.c
index 657a3ab75399..15ce40a7053a 100644
--- a/drivers/scsi/53c700.c
+++ b/drivers/scsi/53c700.c
@@ -1939,7 +1939,7 @@ NCR_700_abort(struct scsi_cmnd * SCp)
STATIC int
NCR_700_bus_reset(struct scsi_cmnd * SCp)
{
- DECLARE_COMPLETION(complete);
+ DECLARE_COMPLETION_ONSTACK(complete);
struct NCR_700_Host_Parameters *hostdata =
(struct NCR_700_Host_Parameters *)SCp->device->host->hostdata[0];
diff --git a/drivers/scsi/BusLogic.h b/drivers/scsi/BusLogic.h
index 9792e5af5252..d6d1d5613c8a 100644
--- a/drivers/scsi/BusLogic.h
+++ b/drivers/scsi/BusLogic.h
@@ -237,10 +237,7 @@ enum BusLogic_BIOS_DiskGeometryTranslation {
Define a Boolean data type.
*/
-typedef enum {
- false,
- true
-} PACKED boolean;
+typedef bool boolean;
/*
Define a 10^18 Statistics Byte Counter data type.
diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig
index c4dfcc91ddda..dab082002e6f 100644
--- a/drivers/scsi/Kconfig
+++ b/drivers/scsi/Kconfig
@@ -3,11 +3,13 @@ menu "SCSI device support"
config RAID_ATTRS
tristate "RAID Transport Class"
default n
+ depends on BLOCK
---help---
Provides RAID
config SCSI
tristate "SCSI device support"
+ depends on BLOCK
---help---
If you want to use a SCSI hard disk, SCSI tape drive, SCSI CD-ROM or
any other SCSI device under Linux, say Y and make sure that you know
diff --git a/drivers/scsi/aic7xxx/aic79xx_osm.c b/drivers/scsi/aic7xxx/aic79xx_osm.c
index c7eeaced324a..1faa008b5b81 100644
--- a/drivers/scsi/aic7xxx/aic79xx_osm.c
+++ b/drivers/scsi/aic7xxx/aic79xx_osm.c
@@ -646,7 +646,7 @@ ahd_linux_dev_reset(struct scsi_cmnd *cmd)
struct ahd_initiator_tinfo *tinfo;
struct ahd_tmode_tstate *tstate;
unsigned long flags;
- DECLARE_COMPLETION(done);
+ DECLARE_COMPLETION_ONSTACK(done);
reset_scb = NULL;
paused = FALSE;
@@ -2251,7 +2251,7 @@ done:
if (paused)
ahd_unpause(ahd);
if (wait) {
- DECLARE_COMPLETION(done);
+ DECLARE_COMPLETION_ONSTACK(done);
ahd->platform_data->eh_done = &done;
ahd_unlock(ahd, &flags);
diff --git a/drivers/scsi/aic7xxx/aic7xxx_osm.c b/drivers/scsi/aic7xxx/aic7xxx_osm.c
index 64c8b88a429f..339b85cb61cd 100644
--- a/drivers/scsi/aic7xxx/aic7xxx_osm.c
+++ b/drivers/scsi/aic7xxx/aic7xxx_osm.c
@@ -2335,7 +2335,7 @@ done:
if (paused)
ahc_unpause(ahc);
if (wait) {
- DECLARE_COMPLETION(done);
+ DECLARE_COMPLETION_ONSTACK(done);
ahc->platform_data->eh_done = &done;
ahc_unlock(ahc, &flags);
diff --git a/drivers/scsi/aic7xxx_old.c b/drivers/scsi/aic7xxx_old.c
index 5dcef48d414f..10353379a074 100644
--- a/drivers/scsi/aic7xxx_old.c
+++ b/drivers/scsi/aic7xxx_old.c
@@ -2862,7 +2862,7 @@ aic7xxx_done(struct aic7xxx_host *p, struct aic7xxx_scb *scb)
aic_dev->r_total++;
ptr = aic_dev->r_bins;
}
- if(cmd->device->simple_tags && cmd->request->flags & REQ_HARDBARRIER)
+ if(cmd->device->simple_tags && cmd->request->cmd_flags & REQ_HARDBARRIER)
{
aic_dev->barrier_total++;
if(scb->tag_action == MSG_ORDERED_Q_TAG)
@@ -10158,7 +10158,7 @@ aic7xxx_buildscb(struct aic7xxx_host *p, Scsi_Cmnd *cmd,
/* We always force TEST_UNIT_READY to untagged */
if (cmd->cmnd[0] != TEST_UNIT_READY && sdptr->simple_tags)
{
- if (req->flags & REQ_HARDBARRIER)
+ if (req->cmd_flags & REQ_HARDBARRIER)
{
if(sdptr->ordered_tags)
{
diff --git a/drivers/scsi/gdth.c b/drivers/scsi/gdth.c
index 43afd476e606..0f3eb22b979a 100644
--- a/drivers/scsi/gdth.c
+++ b/drivers/scsi/gdth.c
@@ -724,7 +724,7 @@ int __gdth_execute(struct scsi_device *sdev, gdth_cmd_str *gdtcmd, char *cmnd,
int timeout, u32 *info)
{
Scsi_Cmnd *scp;
- DECLARE_COMPLETION(wait);
+ DECLARE_COMPLETION_ONSTACK(wait);
int rval;
scp = kmalloc(sizeof(*scp), GFP_KERNEL);
@@ -764,7 +764,7 @@ int __gdth_execute(struct scsi_device *sdev, gdth_cmd_str *gdtcmd, char *cmnd,
{
Scsi_Cmnd *scp = scsi_allocate_device(sdev, 1, FALSE);
unsigned bufflen = gdtcmd ? sizeof(gdth_cmd_str) : 0;
- DECLARE_COMPLETION(wait);
+ DECLARE_COMPLETION_ONSTACK(wait);
int rval;
if (!scp)
diff --git a/drivers/scsi/ide-scsi.c b/drivers/scsi/ide-scsi.c
index 94d1de55607f..1427a41e8441 100644
--- a/drivers/scsi/ide-scsi.c
+++ b/drivers/scsi/ide-scsi.c
@@ -344,7 +344,7 @@ static int idescsi_check_condition(ide_drive_t *drive, struct request *failed_co
pc->buffer = buf;
pc->c[0] = REQUEST_SENSE;
pc->c[4] = pc->request_transfer = pc->buffer_size = SCSI_SENSE_BUFFERSIZE;
- rq->flags = REQ_SENSE;
+ rq->cmd_type = REQ_TYPE_SENSE;
pc->timeout = jiffies + WAIT_READY;
/* NOTE! Save the failed packet command in "rq->buffer" */
rq->buffer = (void *) failed_command->special;
@@ -398,12 +398,12 @@ static int idescsi_end_request (ide_drive_t *drive, int uptodate, int nrsecs)
int errors = rq->errors;
unsigned long flags;
- if (!(rq->flags & (REQ_SPECIAL|REQ_SENSE))) {
+ if (!blk_special_request(rq) && !blk_sense_request(rq)) {
ide_end_request(drive, uptodate, nrsecs);
return 0;
}
ide_end_drive_cmd (drive, 0, 0);
- if (rq->flags & REQ_SENSE) {
+ if (blk_sense_request(rq)) {
idescsi_pc_t *opc = (idescsi_pc_t *) rq->buffer;
if (log) {
printk ("ide-scsi: %s: wrap up check %lu, rst = ", drive->name, opc->scsi_cmd->serial_number);
@@ -708,11 +708,11 @@ static ide_startstop_t idescsi_issue_pc (ide_drive_t *drive, idescsi_pc_t *pc)
static ide_startstop_t idescsi_do_request (ide_drive_t *drive, struct request *rq, sector_t block)
{
#if IDESCSI_DEBUG_LOG
- printk (KERN_INFO "rq_status: %d, dev: %s, cmd: %x, errors: %d\n",rq->rq_status, rq->rq_disk->disk_name,rq->cmd[0],rq->errors);
+ printk (KERN_INFO "dev: %s, cmd: %x, errors: %d\n", rq->rq_disk->disk_name,rq->cmd[0],rq->errors);
printk (KERN_INFO "sector: %ld, nr_sectors: %ld, current_nr_sectors: %d\n",rq->sector,rq->nr_sectors,rq->current_nr_sectors);
#endif /* IDESCSI_DEBUG_LOG */
- if (rq->flags & (REQ_SPECIAL|REQ_SENSE)) {
+ if (blk_sense_request(rq) || blk_special_request(rq)) {
return idescsi_issue_pc (drive, (idescsi_pc_t *) rq->special);
}
blk_dump_rq_flags(rq, "ide-scsi: unsup command");
@@ -938,7 +938,7 @@ static int idescsi_queue (struct scsi_cmnd *cmd,
ide_init_drive_cmd (rq);
rq->special = (char *) pc;
- rq->flags = REQ_SPECIAL;
+ rq->cmd_type = REQ_TYPE_SPECIAL;
spin_unlock_irq(host->host_lock);
rq->rq_disk = scsi->disk;
(void) ide_do_drive_cmd (drive, rq, ide_end);
@@ -992,7 +992,7 @@ static int idescsi_eh_abort (struct scsi_cmnd *cmd)
*/
printk (KERN_ERR "ide-scsi: cmd aborted!\n");
- if (scsi->pc->rq->flags & REQ_SENSE)
+ if (blk_sense_request(scsi->pc->rq))
kfree(scsi->pc->buffer);
kfree(scsi->pc->rq);
kfree(scsi->pc);
@@ -1042,7 +1042,7 @@ static int idescsi_eh_reset (struct scsi_cmnd *cmd)
/* kill current request */
blkdev_dequeue_request(req);
end_that_request_last(req, 0);
- if (req->flags & REQ_SENSE)
+ if (blk_sense_request(req))
kfree(scsi->pc->buffer);
kfree(scsi->pc);
scsi->pc = NULL;
diff --git a/drivers/scsi/libsas/sas_scsi_host.c b/drivers/scsi/libsas/sas_scsi_host.c
index 7f9e89bcac7e..e46e79355b77 100644
--- a/drivers/scsi/libsas/sas_scsi_host.c
+++ b/drivers/scsi/libsas/sas_scsi_host.c
@@ -126,7 +126,7 @@ static enum task_attribute sas_scsi_get_task_attr(struct scsi_cmnd *cmd)
enum task_attribute ta = TASK_ATTR_SIMPLE;
if (cmd->request && blk_rq_tagged(cmd->request)) {
if (cmd->device->ordered_tags &&
- (cmd->request->flags & REQ_HARDBARRIER))
+ (cmd->request->cmd_flags & REQ_HARDBARRIER))
ta = TASK_ATTR_HOQ;
}
return ta;
diff --git a/drivers/scsi/lpfc/lpfc_ct.c b/drivers/scsi/lpfc/lpfc_ct.c
index ae4106458991..1b53afb1cb57 100644
--- a/drivers/scsi/lpfc/lpfc_ct.c
+++ b/drivers/scsi/lpfc/lpfc_ct.c
@@ -933,8 +933,8 @@ lpfc_fdmi_cmd(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp, int cmdcode)
ae = (ATTRIBUTE_ENTRY *) ((uint8_t *) rh + size);
ae->ad.bits.AttrType = be16_to_cpu(OS_NAME_VERSION);
sprintf(ae->un.OsNameVersion, "%s %s %s",
- system_utsname.sysname, system_utsname.release,
- system_utsname.version);
+ init_utsname()->sysname, init_utsname()->release,
+ init_utsname()->version);
len = strlen(ae->un.OsNameVersion);
len += (len & 3) ? (4 - (len & 3)) : 4;
ae->ad.bits.AttrLen = be16_to_cpu(FOURBYTES + len);
@@ -1052,7 +1052,7 @@ lpfc_fdmi_cmd(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp, int cmdcode)
size);
ae->ad.bits.AttrType = be16_to_cpu(HOST_NAME);
sprintf(ae->un.HostName, "%s",
- system_utsname.nodename);
+ init_utsname()->nodename);
len = strlen(ae->un.HostName);
len += (len & 3) ? (4 - (len & 3)) : 4;
ae->ad.bits.AttrLen =
@@ -1140,7 +1140,7 @@ lpfc_fdmi_tmo_handler(struct lpfc_hba *phba)
ndlp = lpfc_findnode_did(phba, NLP_SEARCH_ALL, FDMI_DID);
if (ndlp) {
- if (system_utsname.nodename[0] != '\0') {
+ if (init_utsname()->nodename[0] != '\0') {
lpfc_fdmi_cmd(phba, ndlp, SLI_MGMT_DHBA);
} else {
mod_timer(&phba->fc_fdmitmo, jiffies + HZ * 60);
diff --git a/drivers/scsi/pluto.c b/drivers/scsi/pluto.c
index 0bd9c60e6455..aa60a5f1fbc3 100644
--- a/drivers/scsi/pluto.c
+++ b/drivers/scsi/pluto.c
@@ -67,7 +67,6 @@ static void __init pluto_detect_done(Scsi_Cmnd *SCpnt)
static void __init pluto_detect_scsi_done(Scsi_Cmnd *SCpnt)
{
- SCpnt->request->rq_status = RQ_SCSI_DONE;
PLND(("Detect done %08lx\n", (long)SCpnt))
if (atomic_dec_and_test (&fcss))
up(&fc_sem);
@@ -166,7 +165,7 @@ int __init pluto_detect(struct scsi_host_template *tpnt)
SCpnt->cmd_len = COMMAND_SIZE(INQUIRY);
- SCpnt->request->rq_status = RQ_SCSI_BUSY;
+ SCpnt->request->cmd_flags &= ~REQ_STARTED;
SCpnt->done = pluto_detect_done;
SCpnt->request_bufflen = 256;
@@ -178,7 +177,8 @@ int __init pluto_detect(struct scsi_host_template *tpnt)
for (retry = 0; retry < 5; retry++) {
for (i = 0; i < fcscount; i++) {
if (!fcs[i].fc) break;
- if (fcs[i].cmd.request->rq_status != RQ_SCSI_DONE) {
+ if (!(fcs[i].cmd.request->cmd_flags & REQ_STARTED)) {
+ fcs[i].cmd.request->cmd_flags |= REQ_STARTED;
disable_irq(fcs[i].fc->irq);
PLND(("queuecommand %d %d\n", retry, i))
fcp_scsi_queuecommand (&(fcs[i].cmd),
diff --git a/drivers/scsi/qla1280.c b/drivers/scsi/qla1280.c
index 8953991462d7..332151e2a018 100644
--- a/drivers/scsi/qla1280.c
+++ b/drivers/scsi/qla1280.c
@@ -813,7 +813,7 @@ qla1280_error_action(struct scsi_cmnd *cmd, enum action action)
uint16_t data;
unsigned char *handle;
int result, i;
- DECLARE_COMPLETION(wait);
+ DECLARE_COMPLETION_ONSTACK(wait);
struct timer_list timer;
ha = (struct scsi_qla_host *)(CMD_HOST(cmd)->hostdata);
@@ -2406,7 +2406,7 @@ qla1280_mailbox_command(struct scsi_qla_host *ha, uint8_t mr, uint16_t *mb)
uint16_t *optr, *iptr;
uint16_t __iomem *mptr;
uint16_t data;
- DECLARE_COMPLETION(wait);
+ DECLARE_COMPLETION_ONSTACK(wait);
struct timer_list timer;
ENTER("qla1280_mailbox_command");
diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c
index 7a054f9d1ee3..da95bce907dd 100644
--- a/drivers/scsi/scsi.c
+++ b/drivers/scsi/scsi.c
@@ -592,12 +592,6 @@ int scsi_dispatch_cmd(struct scsi_cmnd *cmd)
return rtn;
}
-
-/*
- * Per-CPU I/O completion queue.
- */
-static DEFINE_PER_CPU(struct list_head, scsi_done_q);
-
/**
* scsi_req_abort_cmd -- Request command recovery for the specified command
* cmd: pointer to the SCSI command of interest
@@ -1065,7 +1059,7 @@ int scsi_device_cancel(struct scsi_device *sdev, int recovery)
spin_lock_irqsave(&sdev->list_lock, flags);
list_for_each_entry(scmd, &sdev->cmd_list, list) {
- if (scmd->request && scmd->request->rq_status != RQ_INACTIVE) {
+ if (scmd->request) {
/*
* If we are unable to remove the timer, it means
* that the command has already timed out or
@@ -1102,7 +1096,7 @@ MODULE_PARM_DESC(scsi_logging_level, "a bit mask of logging levels");
static int __init init_scsi(void)
{
- int error, i;
+ int error;
error = scsi_init_queue();
if (error)
@@ -1123,9 +1117,6 @@ static int __init init_scsi(void)
if (error)
goto cleanup_sysctl;
- for_each_possible_cpu(i)
- INIT_LIST_HEAD(&per_cpu(scsi_done_q, i));
-
scsi_netlink_init();
printk(KERN_NOTICE "SCSI subsystem initialized\n");
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
index d6743b959a72..71084728eb42 100644
--- a/drivers/scsi/scsi_lib.c
+++ b/drivers/scsi/scsi_lib.c
@@ -82,7 +82,7 @@ static void scsi_unprep_request(struct request *req)
{
struct scsi_cmnd *cmd = req->special;
- req->flags &= ~REQ_DONTPREP;
+ req->cmd_flags &= ~REQ_DONTPREP;
req->special = NULL;
scsi_put_command(cmd);
@@ -196,7 +196,8 @@ int scsi_execute(struct scsi_device *sdev, const unsigned char *cmd,
req->sense_len = 0;
req->retries = retries;
req->timeout = timeout;
- req->flags |= flags | REQ_BLOCK_PC | REQ_SPECIAL | REQ_QUIET;
+ req->cmd_type = REQ_TYPE_BLOCK_PC;
+ req->cmd_flags |= flags | REQ_QUIET | REQ_PREEMPT;
/*
* head injection *required* here otherwise quiesce won't work
@@ -397,7 +398,8 @@ int scsi_execute_async(struct scsi_device *sdev, const unsigned char *cmd,
req = blk_get_request(sdev->request_queue, write, gfp);
if (!req)
goto free_sense;
- req->flags |= REQ_BLOCK_PC | REQ_QUIET;
+ req->cmd_type = REQ_TYPE_BLOCK_PC;
+ req->cmd_flags |= REQ_QUIET;
if (use_sg)
err = scsi_req_map_sg(req, buffer, use_sg, bufflen, gfp);
@@ -933,7 +935,7 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes)
break;
}
}
- if (!(req->flags & REQ_QUIET)) {
+ if (!(req->cmd_flags & REQ_QUIET)) {
scmd_printk(KERN_INFO, cmd,
"Device not ready: ");
scsi_print_sense_hdr("", &sshdr);
@@ -941,7 +943,7 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes)
scsi_end_request(cmd, 0, this_count, 1);
return;
case VOLUME_OVERFLOW:
- if (!(req->flags & REQ_QUIET)) {
+ if (!(req->cmd_flags & REQ_QUIET)) {
scmd_printk(KERN_INFO, cmd,
"Volume overflow, CDB: ");
__scsi_print_command(cmd->cmnd);
@@ -963,7 +965,7 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes)
return;
}
if (result) {
- if (!(req->flags & REQ_QUIET)) {
+ if (!(req->cmd_flags & REQ_QUIET)) {
scmd_printk(KERN_INFO, cmd,
"SCSI error: return code = 0x%08x\n",
result);
@@ -995,7 +997,7 @@ static int scsi_init_io(struct scsi_cmnd *cmd)
/*
* if this is a rq->data based REQ_BLOCK_PC, setup for a non-sg xfer
*/
- if ((req->flags & REQ_BLOCK_PC) && !req->bio) {
+ if (blk_pc_request(req) && !req->bio) {
cmd->request_bufflen = req->data_len;
cmd->request_buffer = req->data;
req->buffer = req->data;
@@ -1139,13 +1141,12 @@ static int scsi_prep_fn(struct request_queue *q, struct request *req)
* these two cases differently. We differentiate by looking
* at request->cmd, as this tells us the real story.
*/
- if (req->flags & REQ_SPECIAL && req->special) {
+ if (blk_special_request(req) && req->special)
cmd = req->special;
- } else if (req->flags & (REQ_CMD | REQ_BLOCK_PC)) {
-
- if(unlikely(specials_only) && !(req->flags & REQ_SPECIAL)) {
- if(specials_only == SDEV_QUIESCE ||
- specials_only == SDEV_BLOCK)
+ else if (blk_pc_request(req) || blk_fs_request(req)) {
+ if (unlikely(specials_only) && !(req->cmd_flags & REQ_PREEMPT)){
+ if (specials_only == SDEV_QUIESCE ||
+ specials_only == SDEV_BLOCK)
goto defer;
sdev_printk(KERN_ERR, sdev,
@@ -1153,7 +1154,6 @@ static int scsi_prep_fn(struct request_queue *q, struct request *req)
goto kill;
}
-
/*
* Now try and find a command block that we can use.
*/
@@ -1184,7 +1184,7 @@ static int scsi_prep_fn(struct request_queue *q, struct request *req)
* lock. We hope REQ_STARTED prevents anything untoward from
* happening now.
*/
- if (req->flags & (REQ_CMD | REQ_BLOCK_PC)) {
+ if (blk_fs_request(req) || blk_pc_request(req)) {
int ret;
/*
@@ -1216,7 +1216,7 @@ static int scsi_prep_fn(struct request_queue *q, struct request *req)
/*
* Initialize the actual SCSI command for this request.
*/
- if (req->flags & REQ_BLOCK_PC) {
+ if (blk_pc_request(req)) {
scsi_setup_blk_pc_cmnd(cmd);
} else if (req->rq_disk) {
struct scsi_driver *drv;
@@ -1233,7 +1233,7 @@ static int scsi_prep_fn(struct request_queue *q, struct request *req)
/*
* The request is now prepped, no need to come back here
*/
- req->flags |= REQ_DONTPREP;
+ req->cmd_flags |= REQ_DONTPREP;
return BLKPREP_OK;
defer:
@@ -1454,8 +1454,9 @@ static void scsi_request_fn(struct request_queue *q)
if (unlikely(cmd == NULL)) {
printk(KERN_CRIT "impossible request in %s.\n"
"please mail a stack trace to "
- "linux-scsi@vger.kernel.org",
+ "linux-scsi@vger.kernel.org\n",
__FUNCTION__);
+ blk_dump_rq_flags(req, "foo");
BUG();
}
spin_lock(shost->host_lock);
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
index 638cff41d436..10bc99c911fa 100644
--- a/drivers/scsi/sd.c
+++ b/drivers/scsi/sd.c
@@ -443,8 +443,7 @@ static int sd_init_command(struct scsi_cmnd * SCpnt)
SCpnt->cmnd[0] = READ_6;
SCpnt->sc_data_direction = DMA_FROM_DEVICE;
} else {
- printk(KERN_ERR "sd: Unknown command %lx\n", rq->flags);
-/* overkill panic("Unknown sd command %lx\n", rq->flags); */
+ printk(KERN_ERR "sd: Unknown command %x\n", rq->cmd_flags);
return 0;
}
@@ -840,7 +839,7 @@ static int sd_issue_flush(struct device *dev, sector_t *error_sector)
static void sd_prepare_flush(request_queue_t *q, struct request *rq)
{
memset(rq->cmd, 0, sizeof(rq->cmd));
- rq->flags |= REQ_BLOCK_PC;
+ rq->cmd_type = REQ_TYPE_BLOCK_PC;
rq->timeout = SD_TIMEOUT;
rq->cmd[0] = SYNCHRONIZE_CACHE;
rq->cmd_len = 10;
diff --git a/drivers/scsi/sun3_NCR5380.c b/drivers/scsi/sun3_NCR5380.c
index 2f8073b73bf3..7f9bcef6adfa 100644
--- a/drivers/scsi/sun3_NCR5380.c
+++ b/drivers/scsi/sun3_NCR5380.c
@@ -2017,7 +2017,7 @@ static void NCR5380_information_transfer (struct Scsi_Host *instance)
if((count > SUN3_DMA_MINSIZE) && (sun3_dma_setup_done
!= cmd))
{
- if(cmd->request->flags & REQ_CMD) {
+ if(blk_fs_request(cmd->request)) {
sun3scsi_dma_setup(d, count,
rq_data_dir(cmd->request));
sun3_dma_setup_done = cmd;
diff --git a/drivers/scsi/sun3_scsi.c b/drivers/scsi/sun3_scsi.c
index 837173415d4c..44a99aeb8180 100644
--- a/drivers/scsi/sun3_scsi.c
+++ b/drivers/scsi/sun3_scsi.c
@@ -524,7 +524,7 @@ static inline unsigned long sun3scsi_dma_residual(struct Scsi_Host *instance)
static inline unsigned long sun3scsi_dma_xfer_len(unsigned long wanted, Scsi_Cmnd *cmd,
int write_flag)
{
- if(cmd->request->flags & REQ_CMD)
+ if(blk_fs_request(cmd->request))
return wanted;
else
return 0;
diff --git a/drivers/scsi/sun3_scsi_vme.c b/drivers/scsi/sun3_scsi_vme.c
index 008a82ab8521..f5742b84b27a 100644
--- a/drivers/scsi/sun3_scsi_vme.c
+++ b/drivers/scsi/sun3_scsi_vme.c
@@ -458,7 +458,7 @@ static inline unsigned long sun3scsi_dma_residual(struct Scsi_Host *instance)
static inline unsigned long sun3scsi_dma_xfer_len(unsigned long wanted, Scsi_Cmnd *cmd,
int write_flag)
{
- if(cmd->request->flags & REQ_CMD)
+ if(blk_fs_request(cmd->request))
return wanted;
else
return 0;
diff --git a/drivers/serial/68328serial.c b/drivers/serial/68328serial.c
index 993a702422ec..bac853c5abb5 100644
--- a/drivers/serial/68328serial.c
+++ b/drivers/serial/68328serial.c
@@ -1378,7 +1378,7 @@ void startup_console(void)
#endif /* CONFIG_PM_LEGACY */
-static struct tty_operations rs_ops = {
+static const struct tty_operations rs_ops = {
.open = rs_open,
.close = rs_close,
.write = rs_write,
diff --git a/drivers/serial/68360serial.c b/drivers/serial/68360serial.c
index e80e70e9b126..1b299e8c57cd 100644
--- a/drivers/serial/68360serial.c
+++ b/drivers/serial/68360serial.c
@@ -2424,7 +2424,7 @@ long console_360_init(long kmem_start, long kmem_end)
*/
static int baud_idx;
-static struct tty_operations rs_360_ops = {
+static const struct tty_operations rs_360_ops = {
.owner = THIS_MODULE,
.open = rs_360_open,
.close = rs_360_close,
diff --git a/drivers/serial/8250.c b/drivers/serial/8250.c
index 0ae9ced00ed4..cc2a205d4230 100644
--- a/drivers/serial/8250.c
+++ b/drivers/serial/8250.c
@@ -320,8 +320,8 @@ static unsigned int serial_in(struct uart_8250_port *up, int offset)
case UPIO_TSI:
if (offset == UART_IIR) {
- tmp = readl((u32 *)(up->port.membase + UART_RX));
- return (cpu_to_le32(tmp) >> 8) & 0xff;
+ tmp = readl(up->port.membase + (UART_IIR & ~3));
+ return (tmp >> 16) & 0xff; /* UART_IIR % 4 == 2 */
} else
return readb(up->port.membase + offset);
@@ -1896,6 +1896,17 @@ serial8250_set_termios(struct uart_port *port, struct termios *termios,
serial_outp(up, UART_EFR, efr);
}
+#ifdef CONFIG_ARCH_OMAP15XX
+ /* Workaround to enable 115200 baud on OMAP1510 internal ports */
+ if (cpu_is_omap1510() && is_omap_port((unsigned int)up->port.membase)) {
+ if (baud == 115200) {
+ quot = 1;
+ serial_out(up, UART_OMAP_OSC_12M_SEL, 1);
+ } else
+ serial_out(up, UART_OMAP_OSC_12M_SEL, 0);
+ }
+#endif
+
if (up->capabilities & UART_NATSEMI) {
/* Switch to bank 2 not bank 1, to avoid resetting EXCR2 */
serial_outp(up, UART_LCR, 0xe0);
@@ -1949,6 +1960,8 @@ static int serial8250_request_std_resource(struct uart_8250_port *up)
case UPIO_AU:
size = 0x100000;
/* fall thru */
+ case UPIO_TSI:
+ case UPIO_MEM32:
case UPIO_MEM:
if (!up->port.mapbase)
break;
@@ -1984,6 +1997,8 @@ static void serial8250_release_std_resource(struct uart_8250_port *up)
case UPIO_AU:
size = 0x100000;
/* fall thru */
+ case UPIO_TSI:
+ case UPIO_MEM32:
case UPIO_MEM:
if (!up->port.mapbase)
break;
@@ -2007,17 +2022,15 @@ static int serial8250_request_rsa_resource(struct uart_8250_port *up)
{
unsigned long start = UART_RSA_BASE << up->port.regshift;
unsigned int size = 8 << up->port.regshift;
- int ret = 0;
+ int ret = -EINVAL;
switch (up->port.iotype) {
- case UPIO_MEM:
- ret = -EINVAL;
- break;
-
case UPIO_HUB6:
case UPIO_PORT:
start += up->port.iobase;
- if (!request_region(start, size, "serial-rsa"))
+ if (request_region(start, size, "serial-rsa"))
+ ret = 0;
+ else
ret = -EBUSY;
break;
}
@@ -2031,9 +2044,6 @@ static void serial8250_release_rsa_resource(struct uart_8250_port *up)
unsigned int size = 8 << up->port.regshift;
switch (up->port.iotype) {
- case UPIO_MEM:
- break;
-
case UPIO_HUB6:
case UPIO_PORT:
release_region(up->port.iobase + offset, size);
@@ -2222,9 +2232,10 @@ static inline void wait_for_xmitr(struct uart_8250_port *up, int bits)
/* Wait up to 1s for flow control if necessary */
if (up->port.flags & UPF_CONS_FLOW) {
tmout = 1000000;
- while (--tmout &&
- ((serial_in(up, UART_MSR) & UART_MSR_CTS) == 0))
+ while (!(serial_in(up, UART_MSR) & UART_MSR_CTS) && --tmout) {
udelay(1);
+ touch_nmi_watchdog();
+ }
}
}
@@ -2397,7 +2408,6 @@ int __init early_serial_setup(struct uart_port *port)
/**
* serial8250_suspend_port - suspend one serial port
* @line: serial line number
- * @level: the level of port suspension, as per uart_suspend_port
*
* Suspend one serial port.
*/
@@ -2409,7 +2419,6 @@ void serial8250_suspend_port(int line)
/**
* serial8250_resume_port - resume one serial port
* @line: serial line number
- * @level: the level of port resumption, as per uart_resume_port
*
* Resume one serial port.
*/
diff --git a/drivers/serial/8250_acorn.c b/drivers/serial/8250_acorn.c
index 32af3650e8b4..ef8cc8a70c60 100644
--- a/drivers/serial/8250_acorn.c
+++ b/drivers/serial/8250_acorn.c
@@ -35,6 +35,7 @@ struct serial_card_type {
struct serial_card_info {
unsigned int num_ports;
int ports[MAX_PORTS];
+ void __iomem *vaddr;
};
static int __devinit
@@ -44,7 +45,6 @@ serial_card_probe(struct expansion_card *ec, const struct ecard_id *id)
struct serial_card_type *type = id->data;
struct uart_port port;
unsigned long bus_addr;
- unsigned char __iomem *virt_addr;
unsigned int i;
info = kmalloc(sizeof(struct serial_card_info), GFP_KERNEL);
@@ -55,8 +55,8 @@ serial_card_probe(struct expansion_card *ec, const struct ecard_id *id)
info->num_ports = type->num_ports;
bus_addr = ecard_resource_start(ec, type->type);
- virt_addr = ioremap(bus_addr, ecard_resource_len(ec, type->type));
- if (!virt_addr) {
+ info->vaddr = ioremap(bus_addr, ecard_resource_len(ec, type->type));
+ if (!info->vaddr) {
kfree(info);
return -ENOMEM;
}
@@ -72,7 +72,7 @@ serial_card_probe(struct expansion_card *ec, const struct ecard_id *id)
port.dev = &ec->dev;
for (i = 0; i < info->num_ports; i ++) {
- port.membase = virt_addr + type->offset[i];
+ port.membase = info->vaddr + type->offset[i];
port.mapbase = bus_addr + type->offset[i];
info->ports[i] = serial8250_register_port(&port);
@@ -92,6 +92,7 @@ static void __devexit serial_card_remove(struct expansion_card *ec)
if (info->ports[i] > 0)
serial8250_unregister_port(info->ports[i]);
+ iounmap(info->vaddr);
kfree(info);
}
diff --git a/drivers/serial/8250_gsc.c b/drivers/serial/8250_gsc.c
index 913c71cc0569..1ebe6b585d2d 100644
--- a/drivers/serial/8250_gsc.c
+++ b/drivers/serial/8250_gsc.c
@@ -64,6 +64,7 @@ serial_init_chip(struct parisc_device *dev)
err = serial8250_register_port(&port);
if (err < 0) {
printk(KERN_WARNING "serial8250_register_port returned error %d\n", err);
+ iounmap(port.membase);
return err;
}
diff --git a/drivers/serial/8250_pci.c b/drivers/serial/8250_pci.c
index 851e4839d6d9..4d0ff8f4a01b 100644
--- a/drivers/serial/8250_pci.c
+++ b/drivers/serial/8250_pci.c
@@ -1789,6 +1789,7 @@ static void __devexit pciserial_remove_one(struct pci_dev *dev)
pci_disable_device(dev);
}
+#ifdef CONFIG_PM
static int pciserial_suspend_one(struct pci_dev *dev, pm_message_t state)
{
struct serial_private *priv = pci_get_drvdata(dev);
@@ -1818,6 +1819,7 @@ static int pciserial_resume_one(struct pci_dev *dev)
}
return 0;
}
+#endif
static struct pci_device_id serial_pci_tbl[] = {
{ PCI_VENDOR_ID_V3, PCI_DEVICE_ID_V3_V960,
@@ -2375,8 +2377,10 @@ static struct pci_driver serial_pci_driver = {
.name = "serial",
.probe = pciserial_init_one,
.remove = __devexit_p(pciserial_remove_one),
+#ifdef CONFIG_PM
.suspend = pciserial_suspend_one,
.resume = pciserial_resume_one,
+#endif
.id_table = serial_pci_tbl,
};
diff --git a/drivers/serial/8250_pnp.c b/drivers/serial/8250_pnp.c
index 632f62d6ec7e..71d907c8288b 100644
--- a/drivers/serial/8250_pnp.c
+++ b/drivers/serial/8250_pnp.c
@@ -327,6 +327,19 @@ static const struct pnp_device_id pnp_dev_table[] = {
{ "WACF004", 0 },
{ "WACF005", 0 },
{ "WACF006", 0 },
+ /* Compaq touchscreen */
+ { "FPI2002", 0 },
+ /* Fujitsu Stylistic touchscreens */
+ { "FUJ02B2", 0 },
+ { "FUJ02B3", 0 },
+ /* Fujitsu Stylistic LT touchscreens */
+ { "FUJ02B4", 0 },
+ /* Passive Fujitsu Stylistic touchscreens */
+ { "FUJ02B6", 0 },
+ { "FUJ02B7", 0 },
+ { "FUJ02B8", 0 },
+ { "FUJ02B9", 0 },
+ { "FUJ02BC", 0 },
/* Rockwell's (PORALiNK) 33600 INT PNP */
{ "WCI0003", 0 },
/* Unkown PnP modems */
diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig
index 261eaa442953..d926272a40db 100644
--- a/drivers/serial/Kconfig
+++ b/drivers/serial/Kconfig
@@ -295,7 +295,7 @@ config SERIAL_AMBA_PL011_CONSOLE
Even if you say Y here, the currently visible framebuffer console
(/dev/tty0) will still be used as the system console by default, but
you can alter that using a kernel command line option such as
- "console=ttyAM0". (Try "man bootparam" or see the documentation of
+ "console=ttyAMA0". (Try "man bootparam" or see the documentation of
your boot loader (lilo or loadlin) about how to pass options to the
kernel at boot time.)
diff --git a/drivers/serial/cpm_uart/cpm_uart_core.c b/drivers/serial/cpm_uart/cpm_uart_core.c
index 90ff96e3339b..a0d6136deb9b 100644
--- a/drivers/serial/cpm_uart/cpm_uart_core.c
+++ b/drivers/serial/cpm_uart/cpm_uart_core.c
@@ -46,6 +46,7 @@
#include <asm/io.h>
#include <asm/irq.h>
#include <asm/delay.h>
+#include <asm/fs_pd.h>
#if defined(CONFIG_SERIAL_CPM_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
#define SUPPORT_SYSRQ
@@ -1022,15 +1023,17 @@ int cpm_uart_drv_get_platform_data(struct platform_device *pdev, int is_con)
{
struct resource *r;
struct fs_uart_platform_info *pdata = pdev->dev.platform_data;
- int idx = pdata->fs_no; /* It is UART_SMCx or UART_SCCx index */
+ int idx; /* It is UART_SMCx or UART_SCCx index */
struct uart_cpm_port *pinfo;
int line;
u32 mem, pram;
+ idx = pdata->fs_no = fs_uart_get_id(pdata);
+
line = cpm_uart_id2nr(idx);
if(line < 0) {
printk(KERN_ERR"%s(): port %d is not registered", __FUNCTION__, idx);
- return -1;
+ return -EINVAL;
}
pinfo = (struct uart_cpm_port *) &cpm_uart_ports[idx];
@@ -1044,11 +1047,11 @@ int cpm_uart_drv_get_platform_data(struct platform_device *pdev, int is_con)
if (!(r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "regs")))
return -EINVAL;
- mem = r->start;
+ mem = (u32)ioremap(r->start, r->end - r->start + 1);
if (!(r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "pram")))
return -EINVAL;
- pram = r->start;
+ pram = (u32)ioremap(r->start, r->end - r->start + 1);
if(idx > fsid_smc2_uart) {
pinfo->sccp = (scc_t *)mem;
@@ -1179,7 +1182,7 @@ static int __init cpm_uart_console_setup(struct console *co, char *options)
pdata = pdev->dev.platform_data;
if (pdata)
if (pdata->init_ioports)
- pdata->init_ioports();
+ pdata->init_ioports(pdata);
cpm_uart_drv_get_platform_data(pdev, 1);
}
@@ -1189,11 +1192,7 @@ static int __init cpm_uart_console_setup(struct console *co, char *options)
if (options) {
uart_parse_options(options, &baud, &parity, &bits, &flow);
} else {
- bd_t *bd = (bd_t *) __res;
-
- if (bd->bi_baudrate)
- baud = bd->bi_baudrate;
- else
+ if ((baud = uart_baudrate()) == -1)
baud = 9600;
}
@@ -1266,13 +1265,14 @@ static int cpm_uart_drv_probe(struct device *dev)
}
pdata = pdev->dev.platform_data;
- pr_debug("cpm_uart_drv_probe: Adding CPM UART %d\n", cpm_uart_id2nr(pdata->fs_no));
if ((ret = cpm_uart_drv_get_platform_data(pdev, 0)))
return ret;
+ pr_debug("cpm_uart_drv_probe: Adding CPM UART %d\n", cpm_uart_id2nr(pdata->fs_no));
+
if (pdata->init_ioports)
- pdata->init_ioports();
+ pdata->init_ioports(pdata);
ret = uart_add_one_port(&cpm_reg, &cpm_uart_ports[pdata->fs_no].port);
diff --git a/drivers/serial/cpm_uart/cpm_uart_cpm2.c b/drivers/serial/cpm_uart/cpm_uart_cpm2.c
index ef3bb476c432..b691d3e14754 100644
--- a/drivers/serial/cpm_uart/cpm_uart_cpm2.c
+++ b/drivers/serial/cpm_uart/cpm_uart_cpm2.c
@@ -40,6 +40,7 @@
#include <asm/io.h>
#include <asm/irq.h>
+#include <asm/fs_pd.h>
#include <linux/serial_core.h>
#include <linux/kernel.h>
@@ -50,8 +51,9 @@
void cpm_line_cr_cmd(int line, int cmd)
{
- volatile cpm_cpm2_t *cp = cpmp;
ulong val;
+ volatile cpm_cpm2_t *cp = cpm2_map(im_cpm);
+
switch (line) {
case UART_SMC1:
@@ -84,11 +86,14 @@ void cpm_line_cr_cmd(int line, int cmd)
}
cp->cp_cpcr = val;
while (cp->cp_cpcr & CPM_CR_FLG) ;
+
+ cpm2_unmap(cp);
}
void smc1_lineif(struct uart_cpm_port *pinfo)
{
- volatile iop_cpm2_t *io = &cpm2_immr->im_ioport;
+ volatile iop_cpm2_t *io = cpm2_map(im_ioport);
+ volatile cpmux_t *cpmux = cpm2_map(im_cpmux);
/* SMC1 is only on port D */
io->iop_ppard |= 0x00c00000;
@@ -97,13 +102,17 @@ void smc1_lineif(struct uart_cpm_port *pinfo)
io->iop_psord &= ~0x00c00000;
/* Wire BRG1 to SMC1 */
- cpm2_immr->im_cpmux.cmx_smr &= 0x0f;
+ cpmux->cmx_smr &= 0x0f;
pinfo->brg = 1;
+
+ cpm2_unmap(cpmux);
+ cpm2_unmap(io);
}
void smc2_lineif(struct uart_cpm_port *pinfo)
{
- volatile iop_cpm2_t *io = &cpm2_immr->im_ioport;
+ volatile iop_cpm2_t *io = cpm2_map(im_ioport);
+ volatile cpmux_t *cpmux = cpm2_map(im_cpmux);
/* SMC2 is only on port A */
io->iop_ppara |= 0x00c00000;
@@ -112,13 +121,17 @@ void smc2_lineif(struct uart_cpm_port *pinfo)
io->iop_psora &= ~0x00c00000;
/* Wire BRG2 to SMC2 */
- cpm2_immr->im_cpmux.cmx_smr &= 0xf0;
+ cpmux->cmx_smr &= 0xf0;
pinfo->brg = 2;
+
+ cpm2_unmap(cpmux);
+ cpm2_unmap(io);
}
void scc1_lineif(struct uart_cpm_port *pinfo)
{
- volatile iop_cpm2_t *io = &cpm2_immr->im_ioport;
+ volatile iop_cpm2_t *io = cpm2_map(im_ioport);
+ volatile cpmux_t *cpmux = cpm2_map(im_cpmux);
/* Use Port D for SCC1 instead of other functions. */
io->iop_ppard |= 0x00000003;
@@ -128,9 +141,12 @@ void scc1_lineif(struct uart_cpm_port *pinfo)
io->iop_pdird |= 0x00000002; /* Tx */
/* Wire BRG1 to SCC1 */
- cpm2_immr->im_cpmux.cmx_scr &= 0x00ffffff;
- cpm2_immr->im_cpmux.cmx_scr |= 0x00000000;
+ cpmux->cmx_scr &= 0x00ffffff;
+ cpmux->cmx_scr |= 0x00000000;
pinfo->brg = 1;
+
+ cpm2_unmap(cpmux);
+ cpm2_unmap(io);
}
void scc2_lineif(struct uart_cpm_port *pinfo)
@@ -143,43 +159,57 @@ void scc2_lineif(struct uart_cpm_port *pinfo)
* be supported in a sane fashion.
*/
#ifndef CONFIG_STX_GP3
- volatile iop_cpm2_t *io = &cpm2_immr->im_ioport;
+ volatile iop_cpm2_t *io = cpm2_map(im_ioport);
+ volatile cpmux_t *cpmux = cpm2_map(im_cpmux);
+
io->iop_pparb |= 0x008b0000;
io->iop_pdirb |= 0x00880000;
io->iop_psorb |= 0x00880000;
io->iop_pdirb &= ~0x00030000;
io->iop_psorb &= ~0x00030000;
#endif
- cpm2_immr->im_cpmux.cmx_scr &= 0xff00ffff;
- cpm2_immr->im_cpmux.cmx_scr |= 0x00090000;
+ cpmux->cmx_scr &= 0xff00ffff;
+ cpmux->cmx_scr |= 0x00090000;
pinfo->brg = 2;
+
+ cpm2_unmap(cpmux);
+ cpm2_unmap(io);
}
void scc3_lineif(struct uart_cpm_port *pinfo)
{
- volatile iop_cpm2_t *io = &cpm2_immr->im_ioport;
+ volatile iop_cpm2_t *io = cpm2_map(im_ioport);
+ volatile cpmux_t *cpmux = cpm2_map(im_cpmux);
+
io->iop_pparb |= 0x008b0000;
io->iop_pdirb |= 0x00880000;
io->iop_psorb |= 0x00880000;
io->iop_pdirb &= ~0x00030000;
io->iop_psorb &= ~0x00030000;
- cpm2_immr->im_cpmux.cmx_scr &= 0xffff00ff;
- cpm2_immr->im_cpmux.cmx_scr |= 0x00001200;
+ cpmux->cmx_scr &= 0xffff00ff;
+ cpmux->cmx_scr |= 0x00001200;
pinfo->brg = 3;
+
+ cpm2_unmap(cpmux);
+ cpm2_unmap(io);
}
void scc4_lineif(struct uart_cpm_port *pinfo)
{
- volatile iop_cpm2_t *io = &cpm2_immr->im_ioport;
+ volatile iop_cpm2_t *io = cpm2_map(im_ioport);
+ volatile cpmux_t *cpmux = cpm2_map(im_cpmux);
io->iop_ppard |= 0x00000600;
io->iop_psord &= ~0x00000600; /* Tx/Rx */
io->iop_pdird &= ~0x00000200; /* Rx */
io->iop_pdird |= 0x00000400; /* Tx */
- cpm2_immr->im_cpmux.cmx_scr &= 0xffffff00;
- cpm2_immr->im_cpmux.cmx_scr |= 0x0000001b;
+ cpmux->cmx_scr &= 0xffffff00;
+ cpmux->cmx_scr |= 0x0000001b;
pinfo->brg = 4;
+
+ cpm2_unmap(cpmux);
+ cpm2_unmap(io);
}
/*
@@ -254,88 +284,103 @@ void cpm_uart_freebuf(struct uart_cpm_port *pinfo)
/* Setup any dynamic params in the uart desc */
int cpm_uart_init_portdesc(void)
{
+#if defined(CONFIG_SERIAL_CPM_SMC1) || defined(CONFIG_SERIAL_CPM_SMC2)
+ u32 addr;
+#endif
pr_debug("CPM uart[-]:init portdesc\n");
cpm_uart_nr = 0;
#ifdef CONFIG_SERIAL_CPM_SMC1
- cpm_uart_ports[UART_SMC1].smcp = (smc_t *) & cpm2_immr->im_smc[0];
- cpm_uart_ports[UART_SMC1].smcup =
- (smc_uart_t *) & cpm2_immr->im_dprambase[PROFF_SMC1];
- *(u16 *)(&cpm2_immr->im_dprambase[PROFF_SMC1_BASE]) = PROFF_SMC1;
+ cpm_uart_ports[UART_SMC1].smcp = (smc_t *) cpm2_map(im_smc[0]);
cpm_uart_ports[UART_SMC1].port.mapbase =
- (unsigned long)&cpm2_immr->im_smc[0];
+ (unsigned long)cpm_uart_ports[UART_SMC1].smcp;
+
+ cpm_uart_ports[UART_SMC1].smcup =
+ (smc_uart_t *) cpm2_map_size(im_dprambase[PROFF_SMC1], PROFF_SMC_SIZE);
+ addr = (u16 *)cpm2_map_size(im_dprambase[PROFF_SMC1_BASE], 2);
+ *addr = PROFF_SMC1;
+ cpm2_unmap(addr);
+
cpm_uart_ports[UART_SMC1].smcp->smc_smcm |= (SMCM_RX | SMCM_TX);
cpm_uart_ports[UART_SMC1].smcp->smc_smcmr &= ~(SMCMR_REN | SMCMR_TEN);
- cpm_uart_ports[UART_SMC1].port.uartclk = (((bd_t *) __res)->bi_intfreq);
+ cpm_uart_ports[UART_SMC1].port.uartclk = uart_clock();
cpm_uart_port_map[cpm_uart_nr++] = UART_SMC1;
#endif
#ifdef CONFIG_SERIAL_CPM_SMC2
- cpm_uart_ports[UART_SMC2].smcp = (smc_t *) & cpm2_immr->im_smc[1];
- cpm_uart_ports[UART_SMC2].smcup =
- (smc_uart_t *) & cpm2_immr->im_dprambase[PROFF_SMC2];
- *(u16 *)(&cpm2_immr->im_dprambase[PROFF_SMC2_BASE]) = PROFF_SMC2;
+ cpm_uart_ports[UART_SMC2].smcp = (smc_t *) cpm2_map(im_smc[1]);
cpm_uart_ports[UART_SMC2].port.mapbase =
- (unsigned long)&cpm2_immr->im_smc[1];
+ (unsigned long)cpm_uart_ports[UART_SMC2].smcp;
+
+ cpm_uart_ports[UART_SMC2].smcup =
+ (smc_uart_t *) cpm2_map_size(im_dprambase[PROFF_SMC2], PROFF_SMC_SIZE);
+ addr = (u16 *)cpm2_map_size(im_dprambase[PROFF_SMC2_BASE], 2);
+ *addr = PROFF_SMC2;
+ cpm2_unmap(addr);
+
cpm_uart_ports[UART_SMC2].smcp->smc_smcm |= (SMCM_RX | SMCM_TX);
cpm_uart_ports[UART_SMC2].smcp->smc_smcmr &= ~(SMCMR_REN | SMCMR_TEN);
- cpm_uart_ports[UART_SMC2].port.uartclk = (((bd_t *) __res)->bi_intfreq);
+ cpm_uart_ports[UART_SMC2].port.uartclk = uart_clock();
cpm_uart_port_map[cpm_uart_nr++] = UART_SMC2;
#endif
#ifdef CONFIG_SERIAL_CPM_SCC1
- cpm_uart_ports[UART_SCC1].sccp = (scc_t *) & cpm2_immr->im_scc[0];
- cpm_uart_ports[UART_SCC1].sccup =
- (scc_uart_t *) & cpm2_immr->im_dprambase[PROFF_SCC1];
+ cpm_uart_ports[UART_SCC1].sccp = (scc_t *) cpm2_map(im_scc[0]);
cpm_uart_ports[UART_SCC1].port.mapbase =
- (unsigned long)&cpm2_immr->im_scc[0];
+ (unsigned long)cpm_uart_ports[UART_SCC1].sccp;
+ cpm_uart_ports[UART_SCC1].sccup =
+ (scc_uart_t *) cpm2_map_size(im_dprambase[PROFF_SCC1], PROFF_SCC_SIZE);
+
cpm_uart_ports[UART_SCC1].sccp->scc_sccm &=
~(UART_SCCM_TX | UART_SCCM_RX);
cpm_uart_ports[UART_SCC1].sccp->scc_gsmrl &=
~(SCC_GSMRL_ENR | SCC_GSMRL_ENT);
- cpm_uart_ports[UART_SCC1].port.uartclk = (((bd_t *) __res)->bi_intfreq);
+ cpm_uart_ports[UART_SCC1].port.uartclk = uart_clock();
cpm_uart_port_map[cpm_uart_nr++] = UART_SCC1;
#endif
#ifdef CONFIG_SERIAL_CPM_SCC2
- cpm_uart_ports[UART_SCC2].sccp = (scc_t *) & cpm2_immr->im_scc[1];
- cpm_uart_ports[UART_SCC2].sccup =
- (scc_uart_t *) & cpm2_immr->im_dprambase[PROFF_SCC2];
+ cpm_uart_ports[UART_SCC2].sccp = (scc_t *) cpm2_map(im_scc[1]);
cpm_uart_ports[UART_SCC2].port.mapbase =
- (unsigned long)&cpm2_immr->im_scc[1];
+ (unsigned long)cpm_uart_ports[UART_SCC2].sccp;
+ cpm_uart_ports[UART_SCC2].sccup =
+ (scc_uart_t *) cpm2_map_size(im_dprambase[PROFF_SCC2], PROFF_SCC_SIZE);
+
cpm_uart_ports[UART_SCC2].sccp->scc_sccm &=
~(UART_SCCM_TX | UART_SCCM_RX);
cpm_uart_ports[UART_SCC2].sccp->scc_gsmrl &=
~(SCC_GSMRL_ENR | SCC_GSMRL_ENT);
- cpm_uart_ports[UART_SCC2].port.uartclk = (((bd_t *) __res)->bi_intfreq);
+ cpm_uart_ports[UART_SCC2].port.uartclk = uart_clock();
cpm_uart_port_map[cpm_uart_nr++] = UART_SCC2;
#endif
#ifdef CONFIG_SERIAL_CPM_SCC3
- cpm_uart_ports[UART_SCC3].sccp = (scc_t *) & cpm2_immr->im_scc[2];
- cpm_uart_ports[UART_SCC3].sccup =
- (scc_uart_t *) & cpm2_immr->im_dprambase[PROFF_SCC3];
+ cpm_uart_ports[UART_SCC3].sccp = (scc_t *) cpm2_map(im_scc[2]);
cpm_uart_ports[UART_SCC3].port.mapbase =
- (unsigned long)&cpm2_immr->im_scc[2];
+ (unsigned long)cpm_uart_ports[UART_SCC3].sccp;
+ cpm_uart_ports[UART_SCC3].sccup =
+ (scc_uart_t *) cpm2_map_size(im_dprambase[PROFF_SCC3], PROFF_SCC_SIZE);
+
cpm_uart_ports[UART_SCC3].sccp->scc_sccm &=
~(UART_SCCM_TX | UART_SCCM_RX);
cpm_uart_ports[UART_SCC3].sccp->scc_gsmrl &=
~(SCC_GSMRL_ENR | SCC_GSMRL_ENT);
- cpm_uart_ports[UART_SCC3].port.uartclk = (((bd_t *) __res)->bi_intfreq);
+ cpm_uart_ports[UART_SCC3].port.uartclk = uart_clock();
cpm_uart_port_map[cpm_uart_nr++] = UART_SCC3;
#endif
#ifdef CONFIG_SERIAL_CPM_SCC4
- cpm_uart_ports[UART_SCC4].sccp = (scc_t *) & cpm2_immr->im_scc[3];
- cpm_uart_ports[UART_SCC4].sccup =
- (scc_uart_t *) & cpm2_immr->im_dprambase[PROFF_SCC4];
+ cpm_uart_ports[UART_SCC4].sccp = (scc_t *) cpm2_map(im_scc[3]);
cpm_uart_ports[UART_SCC4].port.mapbase =
- (unsigned long)&cpm2_immr->im_scc[3];
+ (unsigned long)cpm_uart_ports[UART_SCC4].sccp;
+ cpm_uart_ports[UART_SCC4].sccup =
+ (scc_uart_t *) cpm2_map_size(im_dprambase[PROFF_SCC4], PROFF_SCC_SIZE);
+
cpm_uart_ports[UART_SCC4].sccp->scc_sccm &=
~(UART_SCCM_TX | UART_SCCM_RX);
cpm_uart_ports[UART_SCC4].sccp->scc_gsmrl &=
~(SCC_GSMRL_ENR | SCC_GSMRL_ENT);
- cpm_uart_ports[UART_SCC4].port.uartclk = (((bd_t *) __res)->bi_intfreq);
+ cpm_uart_ports[UART_SCC4].port.uartclk = uart_clock();
cpm_uart_port_map[cpm_uart_nr++] = UART_SCC4;
#endif
diff --git a/drivers/serial/cpm_uart/cpm_uart_cpm2.h b/drivers/serial/cpm_uart/cpm_uart_cpm2.h
index 4793fecf8ece..a663300d3476 100644
--- a/drivers/serial/cpm_uart/cpm_uart_cpm2.h
+++ b/drivers/serial/cpm_uart/cpm_uart_cpm2.h
@@ -40,6 +40,6 @@ static inline void cpm_set_smc_fcr(volatile smc_uart_t * up)
up->smc_tfcr = CPMFCR_GBL | CPMFCR_EB;
}
-#define DPRAM_BASE ((unsigned char *)&cpm2_immr->im_dprambase[0])
+#define DPRAM_BASE ((unsigned char *)cpm_dpram_addr(0))
#endif
diff --git a/drivers/serial/crisv10.c b/drivers/serial/crisv10.c
index cabd048c8636..9851d9eff022 100644
--- a/drivers/serial/crisv10.c
+++ b/drivers/serial/crisv10.c
@@ -4825,7 +4825,7 @@ show_serial_version(void)
/* rs_init inits the driver at boot (using the module_init chain) */
-static struct tty_operations rs_ops = {
+static const struct tty_operations rs_ops = {
.open = rs_open,
.close = rs_close,
.write = rs_write,
diff --git a/drivers/serial/ioc4_serial.c b/drivers/serial/ioc4_serial.c
index 576ca1eaa2b6..5ec4716c99bf 100644
--- a/drivers/serial/ioc4_serial.c
+++ b/drivers/serial/ioc4_serial.c
@@ -2685,6 +2685,7 @@ static int ioc4_serial_remove_one(struct ioc4_driver_data *idd)
if (soft) {
free_irq(control->ic_irq, soft);
if (soft->is_ioc4_serial_addr) {
+ iounmap(soft->is_ioc4_serial_addr);
release_region((unsigned long)
soft->is_ioc4_serial_addr,
sizeof(struct ioc4_serial));
@@ -2887,6 +2888,8 @@ out4:
out3:
kfree(control);
out2:
+ if (serial)
+ iounmap(serial);
release_region(tmp_addr1, sizeof(struct ioc4_serial));
out1:
diff --git a/drivers/serial/ip22zilog.c b/drivers/serial/ip22zilog.c
index 5ff269fb604c..dbf13c03a1bb 100644
--- a/drivers/serial/ip22zilog.c
+++ b/drivers/serial/ip22zilog.c
@@ -1229,13 +1229,27 @@ static int __init ip22zilog_init(void)
static void __exit ip22zilog_exit(void)
{
int i;
+ struct uart_ip22zilog_port *up;
for (i = 0; i < NUM_CHANNELS; i++) {
- struct uart_ip22zilog_port *up = &ip22zilog_port_table[i];
+ up = &ip22zilog_port_table[i];
uart_remove_one_port(&ip22zilog_reg, &up->port);
}
+ /* Free IO mem */
+ up = &ip22zilog_port_table[0];
+ for (i = 0; i < NUM_IP22ZILOG; i++) {
+ if (up[(i * 2) + 0].port.mapbase) {
+ iounmap((void*)up[(i * 2) + 0].port.mapbase);
+ up[(i * 2) + 0].port.mapbase = 0;
+ }
+ if (up[(i * 2) + 1].port.mapbase) {
+ iounmap((void*)up[(i * 2) + 1].port.mapbase);
+ up[(i * 2) + 1].port.mapbase = 0;
+ }
+ }
+
uart_unregister_driver(&ip22zilog_reg);
}
diff --git a/drivers/serial/m32r_sio.c b/drivers/serial/m32r_sio.c
index e7fe4bb46eca..28c9ce6f0bdc 100644
--- a/drivers/serial/m32r_sio.c
+++ b/drivers/serial/m32r_sio.c
@@ -76,7 +76,7 @@
*/
#define is_real_interrupt(irq) ((irq) != 0)
-#include <asm/serial.h>
+#define BASE_BAUD 115200
/* Standard COM flags */
#define STD_COM_FLAGS (UPF_BOOT_AUTOCONF | UPF_SKIP_TEST)
@@ -86,7 +86,6 @@
* standard enumeration mechanism. Platforms that can find all
* serial ports via mechanisms like ACPI or PCI need not supply it.
*/
-#undef SERIAL_PORT_DFNS
#if defined(CONFIG_PLAT_USRV)
#define SERIAL_PORT_DFNS \
@@ -109,7 +108,7 @@
#endif /* !CONFIG_PLAT_USRV */
static struct old_serial_port old_serial_port[] = {
- SERIAL_PORT_DFNS /* defined in asm/serial.h */
+ SERIAL_PORT_DFNS
};
#define UART_NR ARRAY_SIZE(old_serial_port)
diff --git a/drivers/serial/mcfserial.c b/drivers/serial/mcfserial.c
index 832abd3c4706..00d7859c167e 100644
--- a/drivers/serial/mcfserial.c
+++ b/drivers/serial/mcfserial.c
@@ -1666,7 +1666,7 @@ static void show_serial_version(void)
printk(mcfrs_drivername);
}
-static struct tty_operations mcfrs_ops = {
+static const struct tty_operations mcfrs_ops = {
.open = mcfrs_open,
.close = mcfrs_close,
.write = mcfrs_write,
diff --git a/drivers/serial/mpc52xx_uart.c b/drivers/serial/mpc52xx_uart.c
index 7708e5dd3656..dbad0e31e005 100644
--- a/drivers/serial/mpc52xx_uart.c
+++ b/drivers/serial/mpc52xx_uart.c
@@ -338,14 +338,23 @@ mpc52xx_uart_release_port(struct uart_port *port)
static int
mpc52xx_uart_request_port(struct uart_port *port)
{
+ int err;
+
if (port->flags & UPF_IOREMAP) /* Need to remap ? */
port->membase = ioremap(port->mapbase, MPC52xx_PSC_SIZE);
if (!port->membase)
return -EINVAL;
- return request_mem_region(port->mapbase, MPC52xx_PSC_SIZE,
+ err = request_mem_region(port->mapbase, MPC52xx_PSC_SIZE,
"mpc52xx_psc_uart") != NULL ? 0 : -EBUSY;
+
+ if (err && (port->flags & UPF_IOREMAP)) {
+ iounmap(port->membase);
+ port->membase = NULL;
+ }
+
+ return err;
}
static void
diff --git a/drivers/serial/mpsc.c b/drivers/serial/mpsc.c
index 63d2a66e563b..704243c9f78a 100644
--- a/drivers/serial/mpsc.c
+++ b/drivers/serial/mpsc.c
@@ -1893,6 +1893,10 @@ mpsc_drv_map_regs(struct mpsc_port_info *pi, struct platform_device *pd)
}
else {
mpsc_resource_err("SDMA base");
+ if (pi->mpsc_base) {
+ iounmap(pi->mpsc_base);
+ pi->mpsc_base = NULL;
+ }
return -ENOMEM;
}
@@ -1905,6 +1909,14 @@ mpsc_drv_map_regs(struct mpsc_port_info *pi, struct platform_device *pd)
}
else {
mpsc_resource_err("BRG base");
+ if (pi->mpsc_base) {
+ iounmap(pi->mpsc_base);
+ pi->mpsc_base = NULL;
+ }
+ if (pi->sdma_base) {
+ iounmap(pi->sdma_base);
+ pi->sdma_base = NULL;
+ }
return -ENOMEM;
}
diff --git a/drivers/serial/mux.c b/drivers/serial/mux.c
index 4a1c9983f38f..aa819d3f8ee5 100644
--- a/drivers/serial/mux.c
+++ b/drivers/serial/mux.c
@@ -521,6 +521,8 @@ static void __exit mux_exit(void)
for (i = 0; i < port_cnt; i++) {
uart_remove_one_port(&mux_driver, &mux_ports[i]);
+ if (mux_ports[i].membase)
+ iounmap(mux_ports[i].membase);
}
uart_unregister_driver(&mux_driver);
diff --git a/drivers/serial/serial_core.c b/drivers/serial/serial_core.c
index 5f7ba1adb309..c67b05e9a451 100644
--- a/drivers/serial/serial_core.c
+++ b/drivers/serial/serial_core.c
@@ -792,6 +792,7 @@ static int uart_set_info(struct uart_state *state,
* We failed anyway.
*/
retval = -EBUSY;
+ goto exit; // Added to return the correct error -Ram Gupta
}
}
@@ -1662,16 +1663,16 @@ static int uart_line_info(char *buf, struct uart_driver *drv, int i)
struct uart_port *port = state->port;
char stat_buf[32];
unsigned int status;
- int ret;
+ int mmio, ret;
if (!port)
return 0;
+ mmio = port->iotype >= UPIO_MEM;
ret = sprintf(buf, "%d: uart:%s %s%08lX irq:%d",
port->line, uart_type(port),
- port->iotype == UPIO_MEM ? "mmio:0x" : "port:",
- port->iotype == UPIO_MEM ? port->mapbase :
- (unsigned long) port->iobase,
+ mmio ? "mmio:0x" : "port:",
+ mmio ? port->mapbase : (unsigned long) port->iobase,
port->irq);
if (port->type == PORT_UNKNOWN) {
@@ -1939,6 +1940,9 @@ int uart_suspend_port(struct uart_driver *drv, struct uart_port *port)
if (state->info && state->info->flags & UIF_INITIALIZED) {
const struct uart_ops *ops = port->ops;
+ state->info->flags = (state->info->flags & ~UIF_INITIALIZED)
+ | UIF_SUSPENDED;
+
spin_lock_irq(&port->lock);
ops->stop_tx(port);
ops->set_mctrl(port, 0);
@@ -2005,7 +2009,7 @@ int uart_resume_port(struct uart_driver *drv, struct uart_port *port)
console_start(port->cons);
}
- if (state->info && state->info->flags & UIF_INITIALIZED) {
+ if (state->info && state->info->flags & UIF_SUSPENDED) {
const struct uart_ops *ops = port->ops;
int ret;
@@ -2017,15 +2021,17 @@ int uart_resume_port(struct uart_driver *drv, struct uart_port *port)
ops->set_mctrl(port, port->mctrl);
ops->start_tx(port);
spin_unlock_irq(&port->lock);
+ state->info->flags |= UIF_INITIALIZED;
} else {
/*
* Failed to resume - maybe hardware went away?
* Clear the "initialized" flag so we won't try
* to call the low level drivers shutdown method.
*/
- state->info->flags &= ~UIF_INITIALIZED;
uart_shutdown(state);
}
+
+ state->info->flags &= ~UIF_SUSPENDED;
}
mutex_unlock(&state->mutex);
@@ -2111,7 +2117,7 @@ uart_configure_port(struct uart_driver *drv, struct uart_state *state,
}
}
-static struct tty_operations uart_ops = {
+static const struct tty_operations uart_ops = {
.open = uart_open,
.close = uart_close,
.write = uart_write,
diff --git a/drivers/serial/serial_cs.c b/drivers/serial/serial_cs.c
index cbf260bc225d..00f9ffd69489 100644
--- a/drivers/serial/serial_cs.c
+++ b/drivers/serial/serial_cs.c
@@ -80,23 +80,16 @@ module_param(buggy_uart, int, 0444);
/* Table of multi-port card ID's */
-struct multi_id {
- u_short manfid;
- u_short prodid;
+struct serial_quirk {
+ unsigned int manfid;
+ unsigned int prodid;
int multi; /* 1 = multifunction, > 1 = # ports */
+ void (*config)(struct pcmcia_device *);
+ void (*setup)(struct pcmcia_device *, struct uart_port *);
+ void (*wakeup)(struct pcmcia_device *);
+ int (*post)(struct pcmcia_device *);
};
-static const struct multi_id multi_id[] = {
- { MANFID_OMEGA, PRODID_OMEGA_QSP_100, 4 },
- { MANFID_QUATECH, PRODID_QUATECH_DUAL_RS232, 2 },
- { MANFID_QUATECH, PRODID_QUATECH_DUAL_RS232_D1, 2 },
- { MANFID_QUATECH, PRODID_QUATECH_QUAD_RS232, 4 },
- { MANFID_SOCKET, PRODID_SOCKET_DUAL_RS232, 2 },
- { MANFID_INTEL, PRODID_INTEL_DUAL_RS232, 2 },
- { MANFID_NATINST, PRODID_NATINST_QUAD_RS232, 4 }
-};
-#define MULTI_COUNT (sizeof(multi_id)/sizeof(struct multi_id))
-
struct serial_info {
struct pcmcia_device *p_dev;
int ndev;
@@ -107,6 +100,7 @@ struct serial_info {
int c950ctrl;
dev_node_t node[4];
int line[4];
+ const struct serial_quirk *quirk;
};
struct serial_cfg_mem {
@@ -115,37 +109,165 @@ struct serial_cfg_mem {
u_char buf[256];
};
+/*
+ * vers_1 5.0, "Brain Boxes", "2-Port RS232 card", "r6"
+ * manfid 0x0160, 0x0104
+ * This card appears to have a 14.7456MHz clock.
+ */
+static void quirk_setup_brainboxes_0104(struct pcmcia_device *link, struct uart_port *port)
+{
+ port->uartclk = 14745600;
+}
-static int serial_config(struct pcmcia_device * link);
+static int quirk_post_ibm(struct pcmcia_device *link)
+{
+ conf_reg_t reg = { 0, CS_READ, 0x800, 0 };
+ int last_ret, last_fn;
+ last_ret = pcmcia_access_configuration_register(link, &reg);
+ if (last_ret) {
+ last_fn = AccessConfigurationRegister;
+ goto cs_failed;
+ }
+ reg.Action = CS_WRITE;
+ reg.Value = reg.Value | 1;
+ last_ret = pcmcia_access_configuration_register(link, &reg);
+ if (last_ret) {
+ last_fn = AccessConfigurationRegister;
+ goto cs_failed;
+ }
+ return 0;
-static void wakeup_card(struct serial_info *info)
+ cs_failed:
+ cs_error(link, last_fn, last_ret);
+ return -ENODEV;
+}
+
+/*
+ * Nokia cards are not really multiport cards. Shouldn't this
+ * be handled by setting the quirk entry .multi = 0 | 1 ?
+ */
+static void quirk_config_nokia(struct pcmcia_device *link)
{
- int ctrl = info->c950ctrl;
-
- if (info->manfid == MANFID_OXSEMI) {
- outb(12, ctrl + 1);
- } else if (info->manfid == MANFID_POSSIO && info->prodid == PRODID_POSSIO_GCC) {
- /* request_region? oxsemi branch does no request_region too... */
- /* This sequence is needed to properly initialize MC45 attached to OXCF950.
- * I tried decreasing these msleep()s, but it worked properly (survived
- * 1000 stop/start operations) with these timeouts (or bigger). */
- outb(0xA, ctrl + 1);
- msleep(100);
- outb(0xE, ctrl + 1);
- msleep(300);
- outb(0xC, ctrl + 1);
- msleep(100);
- outb(0xE, ctrl + 1);
- msleep(200);
- outb(0xF, ctrl + 1);
- msleep(100);
- outb(0xE, ctrl + 1);
- msleep(100);
- outb(0xC, ctrl + 1);
+ struct serial_info *info = link->priv;
+
+ if (info->multi > 1)
+ info->multi = 1;
+}
+
+static void quirk_wakeup_oxsemi(struct pcmcia_device *link)
+{
+ struct serial_info *info = link->priv;
+
+ outb(12, info->c950ctrl + 1);
+}
+
+/* request_region? oxsemi branch does no request_region too... */
+/*
+ * This sequence is needed to properly initialize MC45 attached to OXCF950.
+ * I tried decreasing these msleep()s, but it worked properly (survived
+ * 1000 stop/start operations) with these timeouts (or bigger).
+ */
+static void quirk_wakeup_possio_gcc(struct pcmcia_device *link)
+{
+ struct serial_info *info = link->priv;
+ unsigned int ctrl = info->c950ctrl;
+
+ outb(0xA, ctrl + 1);
+ msleep(100);
+ outb(0xE, ctrl + 1);
+ msleep(300);
+ outb(0xC, ctrl + 1);
+ msleep(100);
+ outb(0xE, ctrl + 1);
+ msleep(200);
+ outb(0xF, ctrl + 1);
+ msleep(100);
+ outb(0xE, ctrl + 1);
+ msleep(100);
+ outb(0xC, ctrl + 1);
+}
+
+/*
+ * Socket Dual IO: this enables irq's for second port
+ */
+static void quirk_config_socket(struct pcmcia_device *link)
+{
+ struct serial_info *info = link->priv;
+
+ if (info->multi) {
+ link->conf.Present |= PRESENT_EXT_STATUS;
+ link->conf.ExtStatus = ESR_REQ_ATTN_ENA;
}
}
+static const struct serial_quirk quirks[] = {
+ {
+ .manfid = 0x0160,
+ .prodid = 0x0104,
+ .multi = -1,
+ .setup = quirk_setup_brainboxes_0104,
+ }, {
+ .manfid = MANFID_IBM,
+ .prodid = ~0,
+ .multi = -1,
+ .post = quirk_post_ibm,
+ }, {
+ .manfid = MANFID_INTEL,
+ .prodid = PRODID_INTEL_DUAL_RS232,
+ .multi = 2,
+ }, {
+ .manfid = MANFID_NATINST,
+ .prodid = PRODID_NATINST_QUAD_RS232,
+ .multi = 4,
+ }, {
+ .manfid = MANFID_NOKIA,
+ .prodid = ~0,
+ .multi = -1,
+ .config = quirk_config_nokia,
+ }, {
+ .manfid = MANFID_OMEGA,
+ .prodid = PRODID_OMEGA_QSP_100,
+ .multi = 4,
+ }, {
+ .manfid = MANFID_OXSEMI,
+ .prodid = ~0,
+ .multi = -1,
+ .wakeup = quirk_wakeup_oxsemi,
+ }, {
+ .manfid = MANFID_POSSIO,
+ .prodid = PRODID_POSSIO_GCC,
+ .multi = -1,
+ .wakeup = quirk_wakeup_possio_gcc,
+ }, {
+ .manfid = MANFID_QUATECH,
+ .prodid = PRODID_QUATECH_DUAL_RS232,
+ .multi = 2,
+ }, {
+ .manfid = MANFID_QUATECH,
+ .prodid = PRODID_QUATECH_DUAL_RS232_D1,
+ .multi = 2,
+ }, {
+ .manfid = MANFID_QUATECH,
+ .prodid = PRODID_QUATECH_QUAD_RS232,
+ .multi = 4,
+ }, {
+ .manfid = MANFID_SOCKET,
+ .prodid = PRODID_SOCKET_DUAL_RS232,
+ .multi = 2,
+ .config = quirk_config_socket,
+ }, {
+ .manfid = MANFID_SOCKET,
+ .prodid = ~0,
+ .multi = -1,
+ .config = quirk_config_socket,
+ }
+};
+
+
+static int serial_config(struct pcmcia_device * link);
+
+
/*======================================================================
After a card is removed, serial_remove() will unregister
@@ -185,14 +307,14 @@ static int serial_suspend(struct pcmcia_device *link)
static int serial_resume(struct pcmcia_device *link)
{
- if (pcmcia_dev_present(link)) {
- struct serial_info *info = link->priv;
- int i;
+ struct serial_info *info = link->priv;
+ int i;
- for (i = 0; i < info->ndev; i++)
- serial8250_resume_port(info->line[i]);
- wakeup_card(info);
- }
+ for (i = 0; i < info->ndev; i++)
+ serial8250_resume_port(info->line[i]);
+
+ if (info->quirk && info->quirk->wakeup)
+ info->quirk->wakeup(link);
return 0;
}
@@ -278,6 +400,10 @@ static int setup_serial(struct pcmcia_device *handle, struct serial_info * info,
port.dev = &handle_to_dev(handle);
if (buggy_uart)
port.flags |= UPF_BUGGY_UART;
+
+ if (info->quirk && info->quirk->setup)
+ info->quirk->setup(handle, &port);
+
line = serial8250_register_port(&port);
if (line < 0) {
printk(KERN_NOTICE "serial_cs: serial8250_register_port() at "
@@ -433,6 +559,13 @@ next_entry:
}
if (info->multi && (info->manfid == MANFID_3COM))
link->conf.ConfigIndex &= ~(0x08);
+
+ /*
+ * Apply any configuration quirks.
+ */
+ if (info->quirk && info->quirk->config)
+ info->quirk->config(link);
+
i = pcmcia_request_configuration(link, &link->conf);
if (i != CS_SUCCESS) {
cs_error(link, RequestConfiguration, i);
@@ -521,11 +654,13 @@ static int multi_config(struct pcmcia_device * link)
cs_error(link, RequestIRQ, i);
link->irq.AssignedIRQ = 0;
}
- /* Socket Dual IO: this enables irq's for second port */
- if (info->multi && (info->manfid == MANFID_SOCKET)) {
- link->conf.Present |= PRESENT_EXT_STATUS;
- link->conf.ExtStatus = ESR_REQ_ATTN_ENA;
- }
+
+ /*
+ * Apply any configuration quirks.
+ */
+ if (info->quirk && info->quirk->config)
+ info->quirk->config(link);
+
i = pcmcia_request_configuration(link, &link->conf);
if (i != CS_SUCCESS) {
cs_error(link, RequestConfiguration, i);
@@ -550,17 +685,19 @@ static int multi_config(struct pcmcia_device * link)
link->irq.AssignedIRQ);
}
info->c950ctrl = base2;
- wakeup_card(info);
+
+ /*
+ * FIXME: We really should wake up the port prior to
+ * handing it over to the serial layer.
+ */
+ if (info->quirk && info->quirk->wakeup)
+ info->quirk->wakeup(link);
+
rc = 0;
goto free_cfg_mem;
}
setup_serial(link, info, link->io.BasePort1, link->irq.AssignedIRQ);
- /* The Nokia cards are not really multiport cards */
- if (info->manfid == MANFID_NOKIA) {
- rc = 0;
- goto free_cfg_mem;
- }
for (i = 0; i < info->multi - 1; i++)
setup_serial(link, info, base2 + (8 * i),
link->irq.AssignedIRQ);
@@ -622,13 +759,16 @@ static int serial_config(struct pcmcia_device * link)
tuple->DesiredTuple = CISTPL_MANFID;
if (first_tuple(link, tuple, parse) == CS_SUCCESS) {
info->manfid = parse->manfid.manf;
- info->prodid = le16_to_cpu(buf[1]);
- for (i = 0; i < MULTI_COUNT; i++)
- if ((info->manfid == multi_id[i].manfid) &&
- (parse->manfid.card == multi_id[i].prodid))
+ info->prodid = parse->manfid.card;
+
+ for (i = 0; i < ARRAY_SIZE(quirks); i++)
+ if ((quirks[i].manfid == ~0 ||
+ quirks[i].manfid == info->manfid) &&
+ (quirks[i].prodid == ~0 ||
+ quirks[i].prodid == info->prodid)) {
+ info->quirk = &quirks[i];
break;
- if (i < MULTI_COUNT)
- info->multi = multi_id[i].multi;
+ }
}
/* Another check for dual-serial cards: look for either serial or
@@ -648,6 +788,12 @@ static int serial_config(struct pcmcia_device * link)
}
}
+ /*
+ * Apply any multi-port quirk.
+ */
+ if (info->quirk && info->quirk->multi != -1)
+ info->multi = info->quirk->multi;
+
if (info->multi > 1)
multi_config(link);
else
@@ -656,21 +802,13 @@ static int serial_config(struct pcmcia_device * link)
if (info->ndev == 0)
goto failed;
- if (info->manfid == MANFID_IBM) {
- conf_reg_t reg = { 0, CS_READ, 0x800, 0 };
- last_ret = pcmcia_access_configuration_register(link, &reg);
- if (last_ret) {
- last_fn = AccessConfigurationRegister;
- goto cs_failed;
- }
- reg.Action = CS_WRITE;
- reg.Value = reg.Value | 1;
- last_ret = pcmcia_access_configuration_register(link, &reg);
- if (last_ret) {
- last_fn = AccessConfigurationRegister;
- goto cs_failed;
- }
- }
+ /*
+ * Apply any post-init quirk. FIXME: This should really happen
+ * before we register the port, since it might already be in use.
+ */
+ if (info->quirk && info->quirk->post)
+ if (info->quirk->post(link))
+ goto failed;
link->dev_node = &info->node[0];
kfree(cfg_mem);
diff --git a/drivers/serial/serial_txx9.c b/drivers/serial/serial_txx9.c
index b361669f85a1..ebd8d2bb17fd 100644
--- a/drivers/serial/serial_txx9.c
+++ b/drivers/serial/serial_txx9.c
@@ -990,7 +990,6 @@ int __init early_serial_txx9_setup(struct uart_port *port)
/**
* serial_txx9_suspend_port - suspend one serial port
* @line: serial line number
- * @level: the level of port suspension, as per uart_suspend_port
*
* Suspend one serial port.
*/
@@ -1002,7 +1001,6 @@ static void serial_txx9_suspend_port(int line)
/**
* serial_txx9_resume_port - resume one serial port
* @line: serial line number
- * @level: the level of port resumption, as per uart_resume_port
*
* Resume one serial port.
*/
diff --git a/drivers/serial/sunsu.c b/drivers/serial/sunsu.c
index d3a5aeee73a3..9b3b9aaa6b90 100644
--- a/drivers/serial/sunsu.c
+++ b/drivers/serial/sunsu.c
@@ -1499,6 +1499,9 @@ static int __devexit su_remove(struct of_device *dev)
uart_remove_one_port(&sunsu_reg, &up->port);
}
+ if (up->port.membase)
+ of_iounmap(up->port.membase, up->reg_size);
+
dev_set_drvdata(&dev->dev, NULL);
return 0;
diff --git a/drivers/serial/sunzilog.c b/drivers/serial/sunzilog.c
index d34f336d53d8..0da3ebfff82d 100644
--- a/drivers/serial/sunzilog.c
+++ b/drivers/serial/sunzilog.c
@@ -1270,7 +1270,7 @@ static void __init sunzilog_register_serio(struct uart_sunzilog_port *up)
}
#endif
-static void __init sunzilog_init_hw(struct uart_sunzilog_port *up)
+static void __devinit sunzilog_init_hw(struct uart_sunzilog_port *up)
{
struct zilog_channel __iomem *channel;
unsigned long flags;
diff --git a/drivers/tc/zs.c b/drivers/tc/zs.c
index 5e8a27620f6f..622881f26761 100644
--- a/drivers/tc/zs.c
+++ b/drivers/tc/zs.c
@@ -1701,7 +1701,7 @@ static void __init probe_sccs(void)
spin_unlock_irqrestore(&zs_lock, flags);
}
-static struct tty_operations serial_ops = {
+static const struct tty_operations serial_ops = {
.open = rs_open,
.close = rs_close,
.write = rs_write,
diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c
index ca90326f2f5c..71288295df2f 100644
--- a/drivers/usb/class/cdc-acm.c
+++ b/drivers/usb/class/cdc-acm.c
@@ -1120,7 +1120,7 @@ static struct usb_driver acm_driver = {
* TTY driver structures.
*/
-static struct tty_operations acm_ops = {
+static const struct tty_operations acm_ops = {
.open = acm_tty_open,
.close = acm_tty_close,
.write = acm_tty_write,
diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c
index a94c63bef632..3f509beb88e4 100644
--- a/drivers/usb/core/devio.c
+++ b/drivers/usb/core/devio.c
@@ -65,7 +65,7 @@ DEFINE_MUTEX(usbfs_mutex);
struct async {
struct list_head asynclist;
struct dev_state *ps;
- pid_t pid;
+ struct pid *pid;
uid_t uid, euid;
unsigned int signr;
unsigned int ifnum;
@@ -225,6 +225,7 @@ static struct async *alloc_async(unsigned int numisoframes)
static void free_async(struct async *as)
{
+ put_pid(as->pid);
kfree(as->urb->transfer_buffer);
kfree(as->urb->setup_packet);
usb_free_urb(as->urb);
@@ -317,7 +318,7 @@ static void async_completed(struct urb *urb, struct pt_regs *regs)
sinfo.si_errno = as->urb->status;
sinfo.si_code = SI_ASYNCIO;
sinfo.si_addr = as->userurb;
- kill_proc_info_as_uid(as->signr, &sinfo, as->pid, as->uid,
+ kill_pid_info_as_uid(as->signr, &sinfo, as->pid, as->uid,
as->euid, as->secid);
}
snoop(&urb->dev->dev, "urb complete\n");
@@ -573,7 +574,7 @@ static int usbdev_open(struct inode *inode, struct file *file)
INIT_LIST_HEAD(&ps->async_completed);
init_waitqueue_head(&ps->wait);
ps->discsignr = 0;
- ps->disc_pid = current->pid;
+ ps->disc_pid = get_pid(task_pid(current));
ps->disc_uid = current->uid;
ps->disc_euid = current->euid;
ps->disccontext = NULL;
@@ -611,6 +612,7 @@ static int usbdev_release(struct inode *inode, struct file *file)
usb_autosuspend_device(dev, 1);
usb_unlock_device(dev);
usb_put_dev(dev);
+ put_pid(ps->disc_pid);
kfree(ps);
return 0;
}
@@ -1063,7 +1065,7 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb,
as->userbuffer = NULL;
as->signr = uurb->signr;
as->ifnum = ifnum;
- as->pid = current->pid;
+ as->pid = get_pid(task_pid(current));
as->uid = current->uid;
as->euid = current->euid;
security_task_getsecid(current, &as->secid);
diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c
index 37f9f5e7425d..e658089f7b50 100644
--- a/drivers/usb/core/hcd.c
+++ b/drivers/usb/core/hcd.c
@@ -318,8 +318,8 @@ static int rh_string (
// id 3 == vendor description
} else if (id == 3) {
- snprintf (buf, sizeof buf, "%s %s %s", system_utsname.sysname,
- system_utsname.release, hcd->driver->description);
+ snprintf (buf, sizeof buf, "%s %s %s", init_utsname()->sysname,
+ init_utsname()->release, hcd->driver->description);
// unsupported IDs --> "protocol stall"
} else
diff --git a/drivers/usb/core/inode.c b/drivers/usb/core/inode.c
index df3d152f0493..b5d6a79af0be 100644
--- a/drivers/usb/core/inode.c
+++ b/drivers/usb/core/inode.c
@@ -263,7 +263,7 @@ static struct inode *usbfs_get_inode (struct super_block *sb, int mode, dev_t de
inode->i_fop = &simple_dir_operations;
/* directory inodes start off with i_nlink == 2 (for "." entry) */
- inode->i_nlink++;
+ inc_nlink(inode);
break;
}
}
@@ -295,7 +295,7 @@ static int usbfs_mkdir (struct inode *dir, struct dentry *dentry, int mode)
mode = (mode & (S_IRWXUGO | S_ISVTX)) | S_IFDIR;
res = usbfs_mknod (dir, dentry, mode, 0);
if (!res)
- dir->i_nlink++;
+ inc_nlink(dir);
return res;
}
@@ -332,7 +332,7 @@ static int usbfs_unlink (struct inode *dir, struct dentry *dentry)
{
struct inode *inode = dentry->d_inode;
mutex_lock(&inode->i_mutex);
- dentry->d_inode->i_nlink--;
+ drop_nlink(dentry->d_inode);
dput(dentry);
mutex_unlock(&inode->i_mutex);
d_delete(dentry);
@@ -347,10 +347,11 @@ static int usbfs_rmdir(struct inode *dir, struct dentry *dentry)
mutex_lock(&inode->i_mutex);
dentry_unhash(dentry);
if (usbfs_empty(dentry)) {
- dentry->d_inode->i_nlink -= 2;
+ drop_nlink(dentry->d_inode);
+ drop_nlink(dentry->d_inode);
dput(dentry);
inode->i_flags |= S_DEAD;
- dir->i_nlink--;
+ drop_nlink(dir);
error = 0;
}
mutex_unlock(&inode->i_mutex);
@@ -698,7 +699,7 @@ static void usbfs_remove_device(struct usb_device *dev)
sinfo.si_errno = EPIPE;
sinfo.si_code = SI_ASYNCIO;
sinfo.si_addr = ds->disccontext;
- kill_proc_info_as_uid(ds->discsignr, &sinfo, ds->disc_pid, ds->disc_uid, ds->disc_euid, ds->secid);
+ kill_pid_info_as_uid(ds->discsignr, &sinfo, ds->disc_pid, ds->disc_uid, ds->disc_euid, ds->secid);
}
}
}
diff --git a/drivers/usb/core/usb.h b/drivers/usb/core/usb.h
index f69df137ec0e..13322e33f912 100644
--- a/drivers/usb/core/usb.h
+++ b/drivers/usb/core/usb.h
@@ -139,7 +139,7 @@ struct dev_state {
struct list_head async_completed;
wait_queue_head_t wait; /* wake up if a request completed */
unsigned int discsignr;
- pid_t disc_pid;
+ struct pid *disc_pid;
uid_t disc_uid, disc_euid;
void __user *disccontext;
unsigned long ifclaimed;
diff --git a/drivers/usb/gadget/ether.c b/drivers/usb/gadget/ether.c
index 366dc0a9e52c..1c17d26d03b8 100644
--- a/drivers/usb/gadget/ether.c
+++ b/drivers/usb/gadget/ether.c
@@ -2260,7 +2260,7 @@ eth_bind (struct usb_gadget *gadget)
return -ENODEV;
}
snprintf (manufacturer, sizeof manufacturer, "%s %s/%s",
- system_utsname.sysname, system_utsname.release,
+ init_utsname()->sysname, init_utsname()->release,
gadget->name);
/* If there's an RNDIS configuration, that's what Windows wants to
diff --git a/drivers/usb/gadget/file_storage.c b/drivers/usb/gadget/file_storage.c
index c83d3b6c68f2..8b975d15538d 100644
--- a/drivers/usb/gadget/file_storage.c
+++ b/drivers/usb/gadget/file_storage.c
@@ -4001,7 +4001,7 @@ static int __init fsg_bind(struct usb_gadget *gadget)
usb_gadget_set_selfpowered(gadget);
snprintf(manufacturer, sizeof manufacturer, "%s %s with %s",
- system_utsname.sysname, system_utsname.release,
+ init_utsname()->sysname, init_utsname()->release,
gadget->name);
/* On a real device, serial[] would be loaded from permanent
diff --git a/drivers/usb/gadget/gmidi.c b/drivers/usb/gadget/gmidi.c
index b68cecd57411..83601d4009e3 100644
--- a/drivers/usb/gadget/gmidi.c
+++ b/drivers/usb/gadget/gmidi.c
@@ -1189,7 +1189,7 @@ static int __devinit gmidi_bind(struct usb_gadget *gadget)
strlcpy(manufacturer, iManufacturer, sizeof(manufacturer));
} else {
snprintf(manufacturer, sizeof(manufacturer), "%s %s with %s",
- system_utsname.sysname, system_utsname.release,
+ init_utsname()->sysname, init_utsname()->release,
gadget->name);
}
if (iProduct) {
diff --git a/drivers/usb/gadget/inode.c b/drivers/usb/gadget/inode.c
index 4655522a08d9..86924f9cdd7e 100644
--- a/drivers/usb/gadget/inode.c
+++ b/drivers/usb/gadget/inode.c
@@ -342,7 +342,7 @@ fail:
static ssize_t
ep_io (struct ep_data *epdata, void *buf, unsigned len)
{
- DECLARE_COMPLETION (done);
+ DECLARE_COMPLETION_ONSTACK (done);
int value;
spin_lock_irq (&epdata->dev->lock);
@@ -533,7 +533,8 @@ struct kiocb_priv {
struct usb_request *req;
struct ep_data *epdata;
void *buf;
- char __user *ubuf; /* NULL for writes */
+ const struct iovec *iv;
+ unsigned long nr_segs;
unsigned actual;
};
@@ -561,17 +562,32 @@ static int ep_aio_cancel(struct kiocb *iocb, struct io_event *e)
static ssize_t ep_aio_read_retry(struct kiocb *iocb)
{
struct kiocb_priv *priv = iocb->private;
- ssize_t status = priv->actual;
-
- /* we "retry" to get the right mm context for this: */
- status = copy_to_user(priv->ubuf, priv->buf, priv->actual);
- if (unlikely(0 != status))
- status = -EFAULT;
- else
- status = priv->actual;
- kfree(priv->buf);
- kfree(priv);
- return status;
+ ssize_t len, total;
+ int i;
+
+ /* we "retry" to get the right mm context for this: */
+
+ /* copy stuff into user buffers */
+ total = priv->actual;
+ len = 0;
+ for (i=0; i < priv->nr_segs; i++) {
+ ssize_t this = min((ssize_t)(priv->iv[i].iov_len), total);
+
+ if (copy_to_user(priv->iv[i].iov_base, priv->buf, this)) {
+ if (len == 0)
+ len = -EFAULT;
+ break;
+ }
+
+ total -= this;
+ len += this;
+ if (total == 0)
+ break;
+ }
+ kfree(priv->buf);
+ kfree(priv);
+ aio_put_req(iocb);
+ return len;
}
static void ep_aio_complete(struct usb_ep *ep, struct usb_request *req)
@@ -584,7 +600,7 @@ static void ep_aio_complete(struct usb_ep *ep, struct usb_request *req)
spin_lock(&epdata->dev->lock);
priv->req = NULL;
priv->epdata = NULL;
- if (priv->ubuf == NULL
+ if (priv->iv == NULL
|| unlikely(req->actual == 0)
|| unlikely(kiocbIsCancelled(iocb))) {
kfree(req->buf);
@@ -619,7 +635,8 @@ ep_aio_rwtail(
char *buf,
size_t len,
struct ep_data *epdata,
- char __user *ubuf
+ const struct iovec *iv,
+ unsigned long nr_segs
)
{
struct kiocb_priv *priv;
@@ -634,7 +651,8 @@ fail:
return value;
}
iocb->private = priv;
- priv->ubuf = ubuf;
+ priv->iv = iv;
+ priv->nr_segs = nr_segs;
value = get_ready_ep(iocb->ki_filp->f_flags, epdata);
if (unlikely(value < 0)) {
@@ -674,41 +692,53 @@ fail:
kfree(priv);
put_ep(epdata);
} else
- value = (ubuf ? -EIOCBRETRY : -EIOCBQUEUED);
+ value = (iv ? -EIOCBRETRY : -EIOCBQUEUED);
return value;
}
static ssize_t
-ep_aio_read(struct kiocb *iocb, char __user *ubuf, size_t len, loff_t o)
+ep_aio_read(struct kiocb *iocb, const struct iovec *iov,
+ unsigned long nr_segs, loff_t o)
{
struct ep_data *epdata = iocb->ki_filp->private_data;
char *buf;
if (unlikely(epdata->desc.bEndpointAddress & USB_DIR_IN))
return -EINVAL;
- buf = kmalloc(len, GFP_KERNEL);
+
+ buf = kmalloc(iocb->ki_left, GFP_KERNEL);
if (unlikely(!buf))
return -ENOMEM;
+
iocb->ki_retry = ep_aio_read_retry;
- return ep_aio_rwtail(iocb, buf, len, epdata, ubuf);
+ return ep_aio_rwtail(iocb, buf, iocb->ki_left, epdata, iov, nr_segs);
}
static ssize_t
-ep_aio_write(struct kiocb *iocb, const char __user *ubuf, size_t len, loff_t o)
+ep_aio_write(struct kiocb *iocb, const struct iovec *iov,
+ unsigned long nr_segs, loff_t o)
{
struct ep_data *epdata = iocb->ki_filp->private_data;
char *buf;
+ size_t len = 0;
+ int i = 0;
if (unlikely(!(epdata->desc.bEndpointAddress & USB_DIR_IN)))
return -EINVAL;
- buf = kmalloc(len, GFP_KERNEL);
+
+ buf = kmalloc(iocb->ki_left, GFP_KERNEL);
if (unlikely(!buf))
return -ENOMEM;
- if (unlikely(copy_from_user(buf, ubuf, len) != 0)) {
- kfree(buf);
- return -EFAULT;
+
+ for (i=0; i < nr_segs; i++) {
+ if (unlikely(copy_from_user(&buf[len], iov[i].iov_base,
+ iov[i].iov_len) != 0)) {
+ kfree(buf);
+ return -EFAULT;
+ }
+ len += iov[i].iov_len;
}
- return ep_aio_rwtail(iocb, buf, len, epdata, NULL);
+ return ep_aio_rwtail(iocb, buf, len, epdata, NULL, 0);
}
/*----------------------------------------------------------------------*/
diff --git a/drivers/usb/gadget/omap_udc.c b/drivers/usb/gadget/omap_udc.c
index 0a64504c2545..8c18df869833 100644
--- a/drivers/usb/gadget/omap_udc.c
+++ b/drivers/usb/gadget/omap_udc.c
@@ -2869,7 +2869,7 @@ cleanup0:
static int __exit omap_udc_remove(struct platform_device *pdev)
{
- DECLARE_COMPLETION(done);
+ DECLARE_COMPLETION_ONSTACK(done);
if (!udc)
return -ENODEV;
diff --git a/drivers/usb/gadget/serial.c b/drivers/usb/gadget/serial.c
index b893e3118e1b..208e55a667ac 100644
--- a/drivers/usb/gadget/serial.c
+++ b/drivers/usb/gadget/serial.c
@@ -271,7 +271,7 @@ static unsigned int use_acm = GS_DEFAULT_USE_ACM;
/* tty driver struct */
-static struct tty_operations gs_tty_ops = {
+static const struct tty_operations gs_tty_ops = {
.open = gs_open,
.close = gs_close,
.write = gs_write,
@@ -1434,7 +1434,7 @@ static int __init gs_bind(struct usb_gadget *gadget)
return -ENOMEM;
snprintf(manufacturer, sizeof(manufacturer), "%s %s with %s",
- system_utsname.sysname, system_utsname.release,
+ init_utsname()->sysname, init_utsname()->release,
gadget->name);
memset(dev, 0, sizeof(struct gs_dev));
diff --git a/drivers/usb/gadget/zero.c b/drivers/usb/gadget/zero.c
index b7018ee487ea..0f809dd68492 100644
--- a/drivers/usb/gadget/zero.c
+++ b/drivers/usb/gadget/zero.c
@@ -1242,7 +1242,7 @@ autoconf_fail:
EP_OUT_NAME, EP_IN_NAME);
snprintf (manufacturer, sizeof manufacturer, "%s %s with %s",
- system_utsname.sysname, system_utsname.release,
+ init_utsname()->sysname, init_utsname()->release,
gadget->name);
return 0;
diff --git a/drivers/usb/host/ohci-hub.c b/drivers/usb/host/ohci-hub.c
index f36cbd02736d..ec75774abeac 100644
--- a/drivers/usb/host/ohci-hub.c
+++ b/drivers/usb/host/ohci-hub.c
@@ -132,6 +132,8 @@ static inline struct ed *find_head (struct ed *ed)
return ed;
}
+static int ohci_restart (struct ohci_hcd *ohci);
+
/* caller has locked the root hub */
static int ohci_rh_resume (struct ohci_hcd *ohci)
__releases(ohci->lock)
@@ -181,8 +183,6 @@ __acquires(ohci->lock)
#ifdef CONFIG_PM
if (status == -EBUSY) {
if (!autostopped) {
- static int ohci_restart (struct ohci_hcd *ohci);
-
spin_unlock_irq (&ohci->lock);
(void) ohci_init (ohci);
status = ohci_restart (ohci);
diff --git a/drivers/usb/input/Kconfig b/drivers/usb/input/Kconfig
index a102a58fe361..21cd22640080 100644
--- a/drivers/usb/input/Kconfig
+++ b/drivers/usb/input/Kconfig
@@ -60,16 +60,17 @@ config HID_FF
If unsure, say N.
config HID_PID
- bool "PID Devices (Microsoft Sidewinder Force Feedback 2)"
+ bool "PID device support"
depends on HID_FF
help
- Say Y here if you have a PID-compliant joystick and wish to enable force
- feedback for it. The Microsoft Sidewinder Force Feedback 2 is one such
- device.
+ Say Y here if you have a PID-compliant device and wish to enable force
+ feedback for it. Microsoft Sidewinder Force Feedback 2 is one of such
+ devices.
config LOGITECH_FF
bool "Logitech WingMan *3D support"
depends on HID_FF
+ select INPUT_FF_MEMLESS if USB_HID
help
Say Y here if you have one of these devices:
- Logitech WingMan Cordless RumblePad
@@ -81,12 +82,21 @@ config LOGITECH_FF
config THRUSTMASTER_FF
bool "ThrustMaster FireStorm Dual Power 2 support (EXPERIMENTAL)"
depends on HID_FF && EXPERIMENTAL
+ select INPUT_FF_MEMLESS if USB_HID
help
Say Y here if you have a THRUSTMASTER FireStore Dual Power 2,
and want to enable force feedback support for it.
Note: if you say N here, this device will still be supported, but without
force feedback.
+config ZEROPLUS_FF
+ bool "Zeroplus based game controller support"
+ depends on HID_FF
+ select INPUT_FF_MEMLESS if USB_HID
+ help
+ Say Y here if you have a Zeroplus based game controller and want to
+ enable force feedback for it.
+
config USB_HIDDEV
bool "/dev/hiddev raw HID device support"
depends on USB_HID
diff --git a/drivers/usb/input/Makefile b/drivers/usb/input/Makefile
index 48551be324ac..295f459d1079 100644
--- a/drivers/usb/input/Makefile
+++ b/drivers/usb/input/Makefile
@@ -15,7 +15,7 @@ ifeq ($(CONFIG_USB_HIDINPUT),y)
usbhid-objs += hid-input.o
endif
ifeq ($(CONFIG_HID_PID),y)
- usbhid-objs += pid.o
+ usbhid-objs += hid-pidff.o
endif
ifeq ($(CONFIG_LOGITECH_FF),y)
usbhid-objs += hid-lgff.o
@@ -23,6 +23,9 @@ endif
ifeq ($(CONFIG_THRUSTMASTER_FF),y)
usbhid-objs += hid-tmff.o
endif
+ifeq ($(CONFIG_ZEROPLUS_FF),y)
+ usbhid-objs += hid-zpff.o
+endif
ifeq ($(CONFIG_HID_FF),y)
usbhid-objs += hid-ff.o
endif
diff --git a/drivers/usb/input/hid-core.c b/drivers/usb/input/hid-core.c
index 81b1ea01a172..e0fd11605b43 100644
--- a/drivers/usb/input/hid-core.c
+++ b/drivers/usb/input/hid-core.c
@@ -543,8 +543,6 @@ static void hid_free_device(struct hid_device *device)
{
unsigned i,j;
- hid_ff_exit(device);
-
for (i = 0; i < HID_REPORT_TYPES; i++) {
struct hid_report_enum *report_enum = device->report_enum + i;
@@ -1109,7 +1107,7 @@ int hid_set_field(struct hid_field *field, unsigned offset, __s32 value)
/*
* Find a report field with a specified HID usage.
*/
-
+#if 0
struct hid_field *hid_find_field_by_usage(struct hid_device *hid, __u32 wanted_usage, int type)
{
struct hid_report *report;
@@ -1121,6 +1119,7 @@ struct hid_field *hid_find_field_by_usage(struct hid_device *hid, __u32 wanted_u
return report->field[i];
return NULL;
}
+#endif /* 0 */
static int hid_submit_out(struct hid_device *hid)
{
diff --git a/drivers/usb/input/hid-ff.c b/drivers/usb/input/hid-ff.c
index d5c91ee67991..a8fc46c721c5 100644
--- a/drivers/usb/input/hid-ff.c
+++ b/drivers/usb/input/hid-ff.c
@@ -44,45 +44,38 @@ struct hid_ff_initializer {
int (*init)(struct hid_device*);
};
+/*
+ * We try pidff when no other driver is found because PID is the
+ * standards compliant way of implementing force feedback in HID.
+ * pidff_init() will quickly abort if the device doesn't appear to
+ * be a PID device
+ */
static struct hid_ff_initializer inits[] = {
#ifdef CONFIG_LOGITECH_FF
- {0x46d, 0xc211, hid_lgff_init}, // Logitech Cordless rumble pad
- {0x46d, 0xc283, hid_lgff_init}, // Logitech Wingman Force 3d
- {0x46d, 0xc295, hid_lgff_init}, // Logitech MOMO force wheel
- {0x46d, 0xc219, hid_lgff_init}, // Logitech Cordless rumble pad 2
-#endif
-#ifdef CONFIG_HID_PID
- {0x45e, 0x001b, hid_pid_init},
+ { 0x46d, 0xc211, hid_lgff_init }, /* Logitech Cordless rumble pad */
+ { 0x46d, 0xc283, hid_lgff_init }, /* Logitech Wingman Force 3d */
+ { 0x46d, 0xc295, hid_lgff_init }, /* Logitech MOMO force wheel */
+ { 0x46d, 0xc219, hid_lgff_init }, /* Logitech Cordless rumble pad 2 */
#endif
#ifdef CONFIG_THRUSTMASTER_FF
- {0x44f, 0xb304, hid_tmff_init},
+ { 0x44f, 0xb304, hid_tmff_init },
#endif
- {0, 0, NULL} /* Terminating entry */
+#ifdef CONFIG_ZEROPLUS_FF
+ { 0xc12, 0x0005, hid_zpff_init },
+ { 0xc12, 0x0030, hid_zpff_init },
+#endif
+ { 0, 0, hid_pidff_init} /* Matches anything */
};
-static struct hid_ff_initializer *hid_get_ff_init(__u16 idVendor,
- __u16 idProduct)
-{
- struct hid_ff_initializer *init;
- for (init = inits;
- init->idVendor
- && !(init->idVendor == idVendor
- && init->idProduct == idProduct);
- init++);
-
- return init->idVendor? init : NULL;
-}
-
int hid_ff_init(struct hid_device* hid)
{
struct hid_ff_initializer *init;
+ int vendor = le16_to_cpu(hid->dev->descriptor.idVendor);
+ int product = le16_to_cpu(hid->dev->descriptor.idProduct);
- init = hid_get_ff_init(le16_to_cpu(hid->dev->descriptor.idVendor),
- le16_to_cpu(hid->dev->descriptor.idProduct));
+ for (init = inits; init->idVendor; init++)
+ if (init->idVendor == vendor && init->idProduct == product)
+ break;
- if (!init) {
- dbg("hid_ff_init could not find initializer");
- return -ENOSYS;
- }
return init->init(hid);
}
diff --git a/drivers/usb/input/hid-input.c b/drivers/usb/input/hid-input.c
index 7208839f2dbf..4c62afbeb430 100644
--- a/drivers/usb/input/hid-input.c
+++ b/drivers/usb/input/hid-input.c
@@ -65,11 +65,9 @@ static const struct {
#define map_rel(c) do { usage->code = c; usage->type = EV_REL; bit = input->relbit; max = REL_MAX; } while (0)
#define map_key(c) do { usage->code = c; usage->type = EV_KEY; bit = input->keybit; max = KEY_MAX; } while (0)
#define map_led(c) do { usage->code = c; usage->type = EV_LED; bit = input->ledbit; max = LED_MAX; } while (0)
-#define map_ff(c) do { usage->code = c; usage->type = EV_FF; bit = input->ffbit; max = FF_MAX; } while (0)
#define map_abs_clear(c) do { map_abs(c); clear_bit(c, bit); } while (0)
#define map_key_clear(c) do { map_key(c); clear_bit(c, bit); } while (0)
-#define map_ff_effect(c) do { set_bit(c, input->ffbit); } while (0)
#ifdef CONFIG_USB_HIDINPUT_POWERBOOK
@@ -525,23 +523,7 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel
case HID_UP_PID:
- set_bit(EV_FF, input->evbit);
switch(usage->hid & HID_USAGE) {
- case 0x26: map_ff_effect(FF_CONSTANT); goto ignore;
- case 0x27: map_ff_effect(FF_RAMP); goto ignore;
- case 0x28: map_ff_effect(FF_CUSTOM); goto ignore;
- case 0x30: map_ff_effect(FF_SQUARE); map_ff_effect(FF_PERIODIC); goto ignore;
- case 0x31: map_ff_effect(FF_SINE); map_ff_effect(FF_PERIODIC); goto ignore;
- case 0x32: map_ff_effect(FF_TRIANGLE); map_ff_effect(FF_PERIODIC); goto ignore;
- case 0x33: map_ff_effect(FF_SAW_UP); map_ff_effect(FF_PERIODIC); goto ignore;
- case 0x34: map_ff_effect(FF_SAW_DOWN); map_ff_effect(FF_PERIODIC); goto ignore;
- case 0x40: map_ff_effect(FF_SPRING); goto ignore;
- case 0x41: map_ff_effect(FF_DAMPER); goto ignore;
- case 0x42: map_ff_effect(FF_INERTIA); goto ignore;
- case 0x43: map_ff_effect(FF_FRICTION); goto ignore;
- case 0x7e: map_ff(FF_GAIN); break;
- case 0x83: input->ff_effects_max = field->value[0]; goto ignore;
- case 0x98: map_ff(FF_AUTOCENTER); break;
case 0xa4: map_key_clear(BTN_DEAD); break;
default: goto ignore;
}
@@ -698,8 +680,7 @@ void hidinput_hid_event(struct hid_device *hid, struct hid_field *field, struct
}
if (usage->hid == (HID_UP_PID | 0x83UL)) { /* Simultaneous Effects Max */
- input->ff_effects_max = value;
- dbg("Maximum Effects - %d",input->ff_effects_max);
+ dbg("Maximum Effects - %d",value);
return;
}
@@ -748,7 +729,7 @@ static int hidinput_input_event(struct input_dev *dev, unsigned int type, unsign
int offset;
if (type == EV_FF)
- return hid_ff_event(hid, dev, type, code, value);
+ return input_ff_event(dev, type, code, value);
if (type != EV_LED)
return -1;
diff --git a/drivers/usb/input/hid-lgff.c b/drivers/usb/input/hid-lgff.c
index f07d44357ff1..93da222b6da8 100644
--- a/drivers/usb/input/hid-lgff.c
+++ b/drivers/usb/input/hid-lgff.c
@@ -1,12 +1,11 @@
/*
- * $$
- *
* Force feedback support for hid-compliant for some of the devices from
* Logitech, namely:
* - WingMan Cordless RumblePad
* - WingMan Force 3D
*
* Copyright (c) 2002-2004 Johann Deneux
+ * Copyright (c) 2006 Anssi Hannula <anssi.hannula@gmail.com>
*/
/*
@@ -29,495 +28,117 @@
*/
#include <linux/input.h>
-#include <linux/sched.h>
-
-//#define DEBUG
#include <linux/usb.h>
-
-#include <linux/circ_buf.h>
-
#include "hid.h"
-#include "fixp-arith.h"
-
-
-/* Periodicity of the update */
-#define PERIOD (HZ/10)
-
-#define RUN_AT(t) (jiffies + (t))
-
-/* Effect status */
-#define EFFECT_STARTED 0 /* Effect is going to play after some time
- (ff_replay.delay) */
-#define EFFECT_PLAYING 1 /* Effect is being played */
-#define EFFECT_USED 2
-
-// For lgff_device::flags
-#define DEVICE_CLOSING 0 /* The driver is being unitialised */
-
-/* Check that the current process can access an effect */
-#define CHECK_OWNERSHIP(effect) (current->pid == 0 \
- || effect.owner == current->pid)
-
-#define LGFF_CHECK_OWNERSHIP(i, l) \
- (i>=0 && i<LGFF_EFFECTS \
- && test_bit(EFFECT_USED, l->effects[i].flags) \
- && CHECK_OWNERSHIP(l->effects[i]))
-
-#define LGFF_EFFECTS 8
struct device_type {
u16 idVendor;
u16 idProduct;
- signed short *ff;
-};
-
-struct lgff_effect {
- pid_t owner;
-
- struct ff_effect effect;
-
- unsigned long flags[1];
- unsigned int count; /* Number of times left to play */
- unsigned long started_at; /* When the effect started to play */
-};
-
-struct lgff_device {
- struct hid_device* hid;
-
- struct hid_report* constant;
- struct hid_report* rumble;
- struct hid_report* condition;
-
- struct lgff_effect effects[LGFF_EFFECTS];
- spinlock_t lock; /* device-level lock. Having locks on
- a per-effect basis could be nice, but
- isn't really necessary */
-
- unsigned long flags[1]; /* Contains various information about the
- state of the driver for this device */
-
- struct timer_list timer;
+ const signed short *ff;
};
-/* Callbacks */
-static void hid_lgff_exit(struct hid_device* hid);
-static int hid_lgff_event(struct hid_device *hid, struct input_dev *input,
- unsigned int type, unsigned int code, int value);
-static int hid_lgff_flush(struct input_dev *input, struct file *file);
-static int hid_lgff_upload_effect(struct input_dev *input,
- struct ff_effect *effect);
-static int hid_lgff_erase(struct input_dev *input, int id);
-
-/* Local functions */
-static void hid_lgff_input_init(struct hid_device* hid);
-static void hid_lgff_timer(unsigned long timer_data);
-static struct hid_report* hid_lgff_duplicate_report(struct hid_report*);
-static void hid_lgff_delete_report(struct hid_report*);
-
-static signed short ff_rumble[] = {
+static const signed short ff_rumble[] = {
FF_RUMBLE,
-1
};
-static signed short ff_joystick[] = {
+static const signed short ff_joystick[] = {
FF_CONSTANT,
-1
};
-static struct device_type devices[] = {
- {0x046d, 0xc211, ff_rumble},
- {0x046d, 0xc219, ff_rumble},
- {0x046d, 0xc283, ff_joystick},
- {0x0000, 0x0000, ff_joystick}
+static const struct device_type devices[] = {
+ { 0x046d, 0xc211, ff_rumble },
+ { 0x046d, 0xc219, ff_rumble },
+ { 0x046d, 0xc283, ff_joystick },
+ { 0x0000, 0x0000, ff_joystick }
};
+static int hid_lgff_play(struct input_dev *dev, void *data, struct ff_effect *effect)
+{
+ struct hid_device *hid = dev->private;
+ struct list_head *report_list = &hid->report_enum[HID_OUTPUT_REPORT].report_list;
+ struct hid_report *report = list_entry(report_list->next, struct hid_report, list);
+ int x, y;
+ unsigned int left, right;
+
+#define CLAMP(x) if (x < 0) x = 0; if (x > 0xff) x = 0xff
+
+ switch (effect->type) {
+ case FF_CONSTANT:
+ x = effect->u.ramp.start_level + 0x7f; /* 0x7f is center */
+ y = effect->u.ramp.end_level + 0x7f;
+ CLAMP(x);
+ CLAMP(y);
+ report->field[0]->value[0] = 0x51;
+ report->field[0]->value[1] = 0x08;
+ report->field[0]->value[2] = x;
+ report->field[0]->value[3] = y;
+ dbg("(x, y)=(%04x, %04x)", x, y);
+ hid_submit_report(hid, report, USB_DIR_OUT);
+ break;
+
+ case FF_RUMBLE:
+ right = effect->u.rumble.strong_magnitude;
+ left = effect->u.rumble.weak_magnitude;
+ right = right * 0xff / 0xffff;
+ left = left * 0xff / 0xffff;
+ CLAMP(left);
+ CLAMP(right);
+ report->field[0]->value[0] = 0x42;
+ report->field[0]->value[1] = 0x00;
+ report->field[0]->value[2] = left;
+ report->field[0]->value[3] = right;
+ dbg("(left, right)=(%04x, %04x)", left, right);
+ hid_submit_report(hid, report, USB_DIR_OUT);
+ break;
+ }
+ return 0;
+}
+
int hid_lgff_init(struct hid_device* hid)
{
- struct lgff_device *private;
- struct hid_report* report;
- struct hid_field* field;
+ struct hid_input *hidinput = list_entry(hid->inputs.next, struct hid_input, list);
+ struct list_head *report_list = &hid->report_enum[HID_OUTPUT_REPORT].report_list;
+ struct input_dev *dev = hidinput->input;
+ struct hid_report *report;
+ struct hid_field *field;
+ int error;
+ int i, j;
/* Find the report to use */
- if (list_empty(&hid->report_enum[HID_OUTPUT_REPORT].report_list)) {
+ if (list_empty(report_list)) {
err("No output report found");
return -1;
}
+
/* Check that the report looks ok */
- report = (struct hid_report*)hid->report_enum[HID_OUTPUT_REPORT].report_list.next;
+ report = list_entry(report_list->next, struct hid_report, list);
if (!report) {
err("NULL output report");
return -1;
}
+
field = report->field[0];
if (!field) {
err("NULL field");
return -1;
}
- private = kzalloc(sizeof(struct lgff_device), GFP_KERNEL);
- if (!private)
- return -1;
- hid->ff_private = private;
-
- /* Input init */
- hid_lgff_input_init(hid);
-
-
- private->constant = hid_lgff_duplicate_report(report);
- if (!private->constant) {
- kfree(private);
- return -1;
- }
- private->constant->field[0]->value[0] = 0x51;
- private->constant->field[0]->value[1] = 0x08;
- private->constant->field[0]->value[2] = 0x7f;
- private->constant->field[0]->value[3] = 0x7f;
-
- private->rumble = hid_lgff_duplicate_report(report);
- if (!private->rumble) {
- hid_lgff_delete_report(private->constant);
- kfree(private);
- return -1;
- }
- private->rumble->field[0]->value[0] = 0x42;
-
-
- private->condition = hid_lgff_duplicate_report(report);
- if (!private->condition) {
- hid_lgff_delete_report(private->rumble);
- hid_lgff_delete_report(private->constant);
- kfree(private);
- return -1;
- }
-
- private->hid = hid;
-
- spin_lock_init(&private->lock);
- init_timer(&private->timer);
- private->timer.data = (unsigned long)private;
- private->timer.function = hid_lgff_timer;
-
- /* Event and exit callbacks */
- hid->ff_exit = hid_lgff_exit;
- hid->ff_event = hid_lgff_event;
-
- /* Start the update task */
- private->timer.expires = RUN_AT(PERIOD);
- add_timer(&private->timer); /*TODO: only run the timer when at least
- one effect is playing */
-
- printk(KERN_INFO "Force feedback for Logitech force feedback devices by Johann Deneux <johann.deneux@it.uu.se>\n");
-
- return 0;
-}
-
-static struct hid_report* hid_lgff_duplicate_report(struct hid_report* report)
-{
- struct hid_report* ret;
-
- ret = kmalloc(sizeof(struct lgff_device), GFP_KERNEL);
- if (!ret)
- return NULL;
- *ret = *report;
-
- ret->field[0] = kmalloc(sizeof(struct hid_field), GFP_KERNEL);
- if (!ret->field[0]) {
- kfree(ret);
- return NULL;
- }
- *ret->field[0] = *report->field[0];
-
- ret->field[0]->value = kzalloc(sizeof(s32[8]), GFP_KERNEL);
- if (!ret->field[0]->value) {
- kfree(ret->field[0]);
- kfree(ret);
- return NULL;
- }
-
- return ret;
-}
-
-static void hid_lgff_delete_report(struct hid_report* report)
-{
- if (report) {
- kfree(report->field[0]->value);
- kfree(report->field[0]);
- kfree(report);
- }
-}
-
-static void hid_lgff_input_init(struct hid_device* hid)
-{
- struct device_type* dev = devices;
- signed short* ff;
- u16 idVendor = le16_to_cpu(hid->dev->descriptor.idVendor);
- u16 idProduct = le16_to_cpu(hid->dev->descriptor.idProduct);
- struct hid_input *hidinput = list_entry(hid->inputs.next, struct hid_input, list);
- struct input_dev *input_dev = hidinput->input;
-
- while (dev->idVendor && (idVendor != dev->idVendor || idProduct != dev->idProduct))
- dev++;
-
- for (ff = dev->ff; *ff >= 0; ff++)
- set_bit(*ff, input_dev->ffbit);
-
- input_dev->upload_effect = hid_lgff_upload_effect;
- input_dev->flush = hid_lgff_flush;
-
- set_bit(EV_FF, input_dev->evbit);
- input_dev->ff_effects_max = LGFF_EFFECTS;
-}
-
-static void hid_lgff_exit(struct hid_device* hid)
-{
- struct lgff_device *lgff = hid->ff_private;
-
- set_bit(DEVICE_CLOSING, lgff->flags);
- del_timer_sync(&lgff->timer);
-
- hid_lgff_delete_report(lgff->condition);
- hid_lgff_delete_report(lgff->rumble);
- hid_lgff_delete_report(lgff->constant);
-
- kfree(lgff);
-}
-
-static int hid_lgff_event(struct hid_device *hid, struct input_dev* input,
- unsigned int type, unsigned int code, int value)
-{
- struct lgff_device *lgff = hid->ff_private;
- struct lgff_effect *effect = lgff->effects + code;
- unsigned long flags;
-
- if (type != EV_FF) return -EINVAL;
- if (!LGFF_CHECK_OWNERSHIP(code, lgff)) return -EACCES;
- if (value < 0) return -EINVAL;
-
- spin_lock_irqsave(&lgff->lock, flags);
-
- if (value > 0) {
- if (test_bit(EFFECT_STARTED, effect->flags)) {
- spin_unlock_irqrestore(&lgff->lock, flags);
- return -EBUSY;
- }
- if (test_bit(EFFECT_PLAYING, effect->flags)) {
- spin_unlock_irqrestore(&lgff->lock, flags);
- return -EBUSY;
- }
-
- effect->count = value;
-
- if (effect->effect.replay.delay) {
- set_bit(EFFECT_STARTED, effect->flags);
- } else {
- set_bit(EFFECT_PLAYING, effect->flags);
- }
- effect->started_at = jiffies;
- }
- else { /* value == 0 */
- clear_bit(EFFECT_STARTED, effect->flags);
- clear_bit(EFFECT_PLAYING, effect->flags);
- }
-
- spin_unlock_irqrestore(&lgff->lock, flags);
-
- return 0;
-
-}
-
-/* Erase all effects this process owns */
-static int hid_lgff_flush(struct input_dev *dev, struct file *file)
-{
- struct hid_device *hid = dev->private;
- struct lgff_device *lgff = hid->ff_private;
- int i;
-
- for (i=0; i<dev->ff_effects_max; ++i) {
-
- /*NOTE: no need to lock here. The only times EFFECT_USED is
- modified is when effects are uploaded or when an effect is
- erased. But a process cannot close its dev/input/eventX fd
- and perform ioctls on the same fd all at the same time */
- if ( current->pid == lgff->effects[i].owner
- && test_bit(EFFECT_USED, lgff->effects[i].flags)) {
-
- if (hid_lgff_erase(dev, i))
- warn("erase effect %d failed", i);
- }
-
- }
-
- return 0;
-}
-
-static int hid_lgff_erase(struct input_dev *dev, int id)
-{
- struct hid_device *hid = dev->private;
- struct lgff_device *lgff = hid->ff_private;
- unsigned long flags;
-
- if (!LGFF_CHECK_OWNERSHIP(id, lgff)) return -EACCES;
-
- spin_lock_irqsave(&lgff->lock, flags);
- lgff->effects[id].flags[0] = 0;
- spin_unlock_irqrestore(&lgff->lock, flags);
-
- return 0;
-}
-
-static int hid_lgff_upload_effect(struct input_dev* input,
- struct ff_effect* effect)
-{
- struct hid_device *hid = input->private;
- struct lgff_device *lgff = hid->ff_private;
- struct lgff_effect new;
- int id;
- unsigned long flags;
-
- dbg("ioctl rumble");
-
- if (!test_bit(effect->type, input->ffbit)) return -EINVAL;
-
- spin_lock_irqsave(&lgff->lock, flags);
-
- if (effect->id == -1) {
- int i;
-
- for (i=0; i<LGFF_EFFECTS && test_bit(EFFECT_USED, lgff->effects[i].flags); ++i);
- if (i >= LGFF_EFFECTS) {
- spin_unlock_irqrestore(&lgff->lock, flags);
- return -ENOSPC;
+ for (i = 0; i < ARRAY_SIZE(devices); i++) {
+ if (dev->id.vendor == devices[i].idVendor &&
+ dev->id.product == devices[i].idProduct) {
+ for (j = 0; devices[i].ff[j] >= 0; j++)
+ set_bit(devices[i].ff[j], dev->ffbit);
+ break;
}
-
- effect->id = i;
- lgff->effects[i].owner = current->pid;
- lgff->effects[i].flags[0] = 0;
- set_bit(EFFECT_USED, lgff->effects[i].flags);
}
- else if (!LGFF_CHECK_OWNERSHIP(effect->id, lgff)) {
- spin_unlock_irqrestore(&lgff->lock, flags);
- return -EACCES;
- }
-
- id = effect->id;
- new = lgff->effects[id];
-
- new.effect = *effect;
-
- if (test_bit(EFFECT_STARTED, lgff->effects[id].flags)
- || test_bit(EFFECT_STARTED, lgff->effects[id].flags)) {
-
- /* Changing replay parameters is not allowed (for the time
- being) */
- if (new.effect.replay.delay != lgff->effects[id].effect.replay.delay
- || new.effect.replay.length != lgff->effects[id].effect.replay.length) {
- spin_unlock_irqrestore(&lgff->lock, flags);
- return -ENOSYS;
- }
- lgff->effects[id] = new;
+ error = input_ff_create_memless(dev, NULL, hid_lgff_play);
+ if (error)
+ return error;
- } else {
- lgff->effects[id] = new;
- }
+ printk(KERN_INFO "Force feedback for Logitech force feedback devices by Johann Deneux <johann.deneux@it.uu.se>\n");
- spin_unlock_irqrestore(&lgff->lock, flags);
return 0;
}
-
-static void hid_lgff_timer(unsigned long timer_data)
-{
- struct lgff_device *lgff = (struct lgff_device*)timer_data;
- struct hid_device *hid = lgff->hid;
- unsigned long flags;
- int x = 0x7f, y = 0x7f; // Coordinates of constant effects
- unsigned int left = 0, right = 0; // Rumbling
- int i;
-
- spin_lock_irqsave(&lgff->lock, flags);
-
- for (i=0; i<LGFF_EFFECTS; ++i) {
- struct lgff_effect* effect = lgff->effects +i;
-
- if (test_bit(EFFECT_PLAYING, effect->flags)) {
-
- switch (effect->effect.type) {
- case FF_CONSTANT: {
- //TODO: handle envelopes
- int degrees = effect->effect.direction * 360 >> 16;
- x += fixp_mult(fixp_sin(degrees),
- fixp_new16(effect->effect.u.constant.level));
- y += fixp_mult(-fixp_cos(degrees),
- fixp_new16(effect->effect.u.constant.level));
- } break;
- case FF_RUMBLE:
- right += effect->effect.u.rumble.strong_magnitude;
- left += effect->effect.u.rumble.weak_magnitude;
- break;
- };
-
- /* One run of the effect is finished playing */
- if (time_after(jiffies,
- effect->started_at
- + effect->effect.replay.delay*HZ/1000
- + effect->effect.replay.length*HZ/1000)) {
- dbg("Finished playing once %d", i);
- if (--effect->count <= 0) {
- dbg("Stopped %d", i);
- clear_bit(EFFECT_PLAYING, effect->flags);
- }
- else {
- dbg("Start again %d", i);
- if (effect->effect.replay.length != 0) {
- clear_bit(EFFECT_PLAYING, effect->flags);
- set_bit(EFFECT_STARTED, effect->flags);
- }
- effect->started_at = jiffies;
- }
- }
-
- } else if (test_bit(EFFECT_STARTED, lgff->effects[i].flags)) {
- /* Check if we should start playing the effect */
- if (time_after(jiffies,
- lgff->effects[i].started_at
- + lgff->effects[i].effect.replay.delay*HZ/1000)) {
- dbg("Now playing %d", i);
- clear_bit(EFFECT_STARTED, lgff->effects[i].flags);
- set_bit(EFFECT_PLAYING, lgff->effects[i].flags);
- }
- }
- }
-
-#define CLAMP(x) if (x < 0) x = 0; if (x > 0xff) x = 0xff
-
- // Clamp values
- CLAMP(x);
- CLAMP(y);
- CLAMP(left);
- CLAMP(right);
-
-#undef CLAMP
-
- if (x != lgff->constant->field[0]->value[2]
- || y != lgff->constant->field[0]->value[3]) {
- lgff->constant->field[0]->value[2] = x;
- lgff->constant->field[0]->value[3] = y;
- dbg("(x,y)=(%04x, %04x)", x, y);
- hid_submit_report(hid, lgff->constant, USB_DIR_OUT);
- }
-
- if (left != lgff->rumble->field[0]->value[2]
- || right != lgff->rumble->field[0]->value[3]) {
- lgff->rumble->field[0]->value[2] = left;
- lgff->rumble->field[0]->value[3] = right;
- dbg("(left,right)=(%04x, %04x)", left, right);
- hid_submit_report(hid, lgff->rumble, USB_DIR_OUT);
- }
-
- if (!test_bit(DEVICE_CLOSING, lgff->flags)) {
- lgff->timer.expires = RUN_AT(PERIOD);
- add_timer(&lgff->timer);
- }
-
- spin_unlock_irqrestore(&lgff->lock, flags);
-}
diff --git a/drivers/usb/input/hid-pidff.c b/drivers/usb/input/hid-pidff.c
new file mode 100644
index 000000000000..5420c13eb8eb
--- /dev/null
+++ b/drivers/usb/input/hid-pidff.c
@@ -0,0 +1,1330 @@
+/*
+ * Force feedback driver for USB HID PID compliant devices
+ *
+ * Copyright (c) 2005, 2006 Anssi Hannula <anssi.hannula@gmail.com>
+ */
+
+/*
+ * 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 DEBUG */
+
+#define debug(format, arg...) pr_debug("hid-pidff: " format "\n" , ## arg)
+
+#include <linux/sched.h>
+#include <linux/input.h>
+#include <linux/usb.h>
+
+#include "hid.h"
+
+#define PID_EFFECTS_MAX 64
+
+/* Report usage table used to put reports into an array */
+
+#define PID_SET_EFFECT 0
+#define PID_EFFECT_OPERATION 1
+#define PID_DEVICE_GAIN 2
+#define PID_POOL 3
+#define PID_BLOCK_LOAD 4
+#define PID_BLOCK_FREE 5
+#define PID_DEVICE_CONTROL 6
+#define PID_CREATE_NEW_EFFECT 7
+
+#define PID_REQUIRED_REPORTS 7
+
+#define PID_SET_ENVELOPE 8
+#define PID_SET_CONDITION 9
+#define PID_SET_PERIODIC 10
+#define PID_SET_CONSTANT 11
+#define PID_SET_RAMP 12
+static const u8 pidff_reports[] = {
+ 0x21, 0x77, 0x7d, 0x7f, 0x89, 0x90, 0x96, 0xab,
+ 0x5a, 0x5f, 0x6e, 0x73, 0x74
+};
+
+/* device_control is really 0x95, but 0x96 specified as it is the usage of
+the only field in that report */
+
+/* Value usage tables used to put fields and values into arrays */
+
+#define PID_EFFECT_BLOCK_INDEX 0
+
+#define PID_DURATION 1
+#define PID_GAIN 2
+#define PID_TRIGGER_BUTTON 3
+#define PID_TRIGGER_REPEAT_INT 4
+#define PID_DIRECTION_ENABLE 5
+#define PID_START_DELAY 6
+static const u8 pidff_set_effect[] = {
+ 0x22, 0x50, 0x52, 0x53, 0x54, 0x56, 0xa7
+};
+
+#define PID_ATTACK_LEVEL 1
+#define PID_ATTACK_TIME 2
+#define PID_FADE_LEVEL 3
+#define PID_FADE_TIME 4
+static const u8 pidff_set_envelope[] = { 0x22, 0x5b, 0x5c, 0x5d, 0x5e };
+
+#define PID_PARAM_BLOCK_OFFSET 1
+#define PID_CP_OFFSET 2
+#define PID_POS_COEFFICIENT 3
+#define PID_NEG_COEFFICIENT 4
+#define PID_POS_SATURATION 5
+#define PID_NEG_SATURATION 6
+#define PID_DEAD_BAND 7
+static const u8 pidff_set_condition[] = {
+ 0x22, 0x23, 0x60, 0x61, 0x62, 0x63, 0x64, 0x65
+};
+
+#define PID_MAGNITUDE 1
+#define PID_OFFSET 2
+#define PID_PHASE 3
+#define PID_PERIOD 4
+static const u8 pidff_set_periodic[] = { 0x22, 0x70, 0x6f, 0x71, 0x72 };
+static const u8 pidff_set_constant[] = { 0x22, 0x70 };
+
+#define PID_RAMP_START 1
+#define PID_RAMP_END 2
+static const u8 pidff_set_ramp[] = { 0x22, 0x75, 0x76 };
+
+#define PID_RAM_POOL_AVAILABLE 1
+static const u8 pidff_block_load[] = { 0x22, 0xac };
+
+#define PID_LOOP_COUNT 1
+static const u8 pidff_effect_operation[] = { 0x22, 0x7c };
+
+static const u8 pidff_block_free[] = { 0x22 };
+
+#define PID_DEVICE_GAIN_FIELD 0
+static const u8 pidff_device_gain[] = { 0x7e };
+
+#define PID_RAM_POOL_SIZE 0
+#define PID_SIMULTANEOUS_MAX 1
+#define PID_DEVICE_MANAGED_POOL 2
+static const u8 pidff_pool[] = { 0x80, 0x83, 0xa9 };
+
+/* Special field key tables used to put special field keys into arrays */
+
+#define PID_ENABLE_ACTUATORS 0
+#define PID_RESET 1
+static const u8 pidff_device_control[] = { 0x97, 0x9a };
+
+#define PID_CONSTANT 0
+#define PID_RAMP 1
+#define PID_SQUARE 2
+#define PID_SINE 3
+#define PID_TRIANGLE 4
+#define PID_SAW_UP 5
+#define PID_SAW_DOWN 6
+#define PID_SPRING 7
+#define PID_DAMPER 8
+#define PID_INERTIA 9
+#define PID_FRICTION 10
+static const u8 pidff_effect_types[] = {
+ 0x26, 0x27, 0x30, 0x31, 0x32, 0x33, 0x34,
+ 0x40, 0x41, 0x42, 0x43
+};
+
+#define PID_BLOCK_LOAD_SUCCESS 0
+#define PID_BLOCK_LOAD_FULL 1
+static const u8 pidff_block_load_status[] = { 0x8c, 0x8d };
+
+#define PID_EFFECT_START 0
+#define PID_EFFECT_STOP 1
+static const u8 pidff_effect_operation_status[] = { 0x79, 0x7b };
+
+struct pidff_usage {
+ struct hid_field *field;
+ s32 *value;
+};
+
+struct pidff_device {
+ struct hid_device *hid;
+
+ struct hid_report *reports[sizeof(pidff_reports)];
+
+ struct pidff_usage set_effect[sizeof(pidff_set_effect)];
+ struct pidff_usage set_envelope[sizeof(pidff_set_envelope)];
+ struct pidff_usage set_condition[sizeof(pidff_set_condition)];
+ struct pidff_usage set_periodic[sizeof(pidff_set_periodic)];
+ struct pidff_usage set_constant[sizeof(pidff_set_constant)];
+ struct pidff_usage set_ramp[sizeof(pidff_set_ramp)];
+
+ struct pidff_usage device_gain[sizeof(pidff_device_gain)];
+ struct pidff_usage block_load[sizeof(pidff_block_load)];
+ struct pidff_usage pool[sizeof(pidff_pool)];
+ struct pidff_usage effect_operation[sizeof(pidff_effect_operation)];
+ struct pidff_usage block_free[sizeof(pidff_block_free)];
+
+ /* Special field is a field that is not composed of
+ usage<->value pairs that pidff_usage values are */
+
+ /* Special field in create_new_effect */
+ struct hid_field *create_new_effect_type;
+
+ /* Special fields in set_effect */
+ struct hid_field *set_effect_type;
+ struct hid_field *effect_direction;
+
+ /* Special field in device_control */
+ struct hid_field *device_control;
+
+ /* Special field in block_load */
+ struct hid_field *block_load_status;
+
+ /* Special field in effect_operation */
+ struct hid_field *effect_operation_status;
+
+ int control_id[sizeof(pidff_device_control)];
+ int type_id[sizeof(pidff_effect_types)];
+ int status_id[sizeof(pidff_block_load_status)];
+ int operation_id[sizeof(pidff_effect_operation_status)];
+
+ int pid_id[PID_EFFECTS_MAX];
+};
+
+/*
+ * Scale an unsigned value with range 0..max for the given field
+ */
+static int pidff_rescale(int i, int max, struct hid_field *field)
+{
+ return i * (field->logical_maximum - field->logical_minimum) / max +
+ field->logical_minimum;
+}
+
+/*
+ * Scale a signed value in range -0x8000..0x7fff for the given field
+ */
+static int pidff_rescale_signed(int i, struct hid_field *field)
+{
+ return i == 0 ? 0 : i >
+ 0 ? i * field->logical_maximum / 0x7fff : i *
+ field->logical_minimum / -0x8000;
+}
+
+static void pidff_set(struct pidff_usage *usage, u16 value)
+{
+ usage->value[0] = pidff_rescale(value, 0xffff, usage->field);
+ debug("calculated from %d to %d", value, usage->value[0]);
+}
+
+static void pidff_set_signed(struct pidff_usage *usage, s16 value)
+{
+ if (usage->field->logical_minimum < 0)
+ usage->value[0] = pidff_rescale_signed(value, usage->field);
+ else {
+ if (value < 0)
+ usage->value[0] =
+ pidff_rescale(-value, 0x8000, usage->field);
+ else
+ usage->value[0] =
+ pidff_rescale(value, 0x7fff, usage->field);
+ }
+ debug("calculated from %d to %d", value, usage->value[0]);
+}
+
+/*
+ * Send envelope report to the device
+ */
+static void pidff_set_envelope_report(struct pidff_device *pidff,
+ struct ff_envelope *envelope)
+{
+ pidff->set_envelope[PID_EFFECT_BLOCK_INDEX].value[0] =
+ pidff->block_load[PID_EFFECT_BLOCK_INDEX].value[0];
+
+ pidff->set_envelope[PID_ATTACK_LEVEL].value[0] =
+ pidff_rescale(envelope->attack_level >
+ 0x7fff ? 0x7fff : envelope->attack_level, 0x7fff,
+ pidff->set_envelope[PID_ATTACK_LEVEL].field);
+ pidff->set_envelope[PID_FADE_LEVEL].value[0] =
+ pidff_rescale(envelope->fade_level >
+ 0x7fff ? 0x7fff : envelope->fade_level, 0x7fff,
+ pidff->set_envelope[PID_FADE_LEVEL].field);
+
+ pidff->set_envelope[PID_ATTACK_TIME].value[0] = envelope->attack_length;
+ pidff->set_envelope[PID_FADE_TIME].value[0] = envelope->fade_length;
+
+ debug("attack %u => %d", envelope->attack_level,
+ pidff->set_envelope[PID_ATTACK_LEVEL].value[0]);
+
+ hid_submit_report(pidff->hid, pidff->reports[PID_SET_ENVELOPE],
+ USB_DIR_OUT);
+}
+
+/*
+ * Test if the new envelope differs from old one
+ */
+static int pidff_needs_set_envelope(struct ff_envelope *envelope,
+ struct ff_envelope *old)
+{
+ return envelope->attack_level != old->attack_level ||
+ envelope->fade_level != old->fade_level ||
+ envelope->attack_length != old->attack_length ||
+ envelope->fade_length != old->fade_length;
+}
+
+/*
+ * Send constant force report to the device
+ */
+static void pidff_set_constant_force_report(struct pidff_device *pidff,
+ struct ff_effect *effect)
+{
+ pidff->set_constant[PID_EFFECT_BLOCK_INDEX].value[0] =
+ pidff->block_load[PID_EFFECT_BLOCK_INDEX].value[0];
+ pidff_set_signed(&pidff->set_constant[PID_MAGNITUDE],
+ effect->u.constant.level);
+
+ hid_submit_report(pidff->hid, pidff->reports[PID_SET_CONSTANT],
+ USB_DIR_OUT);
+}
+
+/*
+ * Test if the constant parameters have changed between effects
+ */
+static int pidff_needs_set_constant(struct ff_effect *effect,
+ struct ff_effect *old)
+{
+ return effect->u.constant.level != old->u.constant.level;
+}
+
+/*
+ * Send set effect report to the device
+ */
+static void pidff_set_effect_report(struct pidff_device *pidff,
+ struct ff_effect *effect)
+{
+ pidff->set_effect[PID_EFFECT_BLOCK_INDEX].value[0] =
+ pidff->block_load[PID_EFFECT_BLOCK_INDEX].value[0];
+ pidff->set_effect_type->value[0] =
+ pidff->create_new_effect_type->value[0];
+ pidff->set_effect[PID_DURATION].value[0] = effect->replay.length;
+ pidff->set_effect[PID_TRIGGER_BUTTON].value[0] = effect->trigger.button;
+ pidff->set_effect[PID_TRIGGER_REPEAT_INT].value[0] =
+ effect->trigger.interval;
+ pidff->set_effect[PID_GAIN].value[0] =
+ pidff->set_effect[PID_GAIN].field->logical_maximum;
+ pidff->set_effect[PID_DIRECTION_ENABLE].value[0] = 1;
+ pidff->effect_direction->value[0] =
+ pidff_rescale(effect->direction, 0xffff,
+ pidff->effect_direction);
+ pidff->set_effect[PID_START_DELAY].value[0] = effect->replay.delay;
+
+ hid_submit_report(pidff->hid, pidff->reports[PID_SET_EFFECT],
+ USB_DIR_OUT);
+}
+
+/*
+ * Test if the values used in set_effect have changed
+ */
+static int pidff_needs_set_effect(struct ff_effect *effect,
+ struct ff_effect *old)
+{
+ return effect->replay.length != old->replay.length ||
+ effect->trigger.interval != old->trigger.interval ||
+ effect->trigger.button != old->trigger.button ||
+ effect->direction != old->direction ||
+ effect->replay.delay != old->replay.delay;
+}
+
+/*
+ * Send periodic effect report to the device
+ */
+static void pidff_set_periodic_report(struct pidff_device *pidff,
+ struct ff_effect *effect)
+{
+ pidff->set_periodic[PID_EFFECT_BLOCK_INDEX].value[0] =
+ pidff->block_load[PID_EFFECT_BLOCK_INDEX].value[0];
+ pidff_set_signed(&pidff->set_periodic[PID_MAGNITUDE],
+ effect->u.periodic.magnitude);
+ pidff_set_signed(&pidff->set_periodic[PID_OFFSET],
+ effect->u.periodic.offset);
+ pidff_set(&pidff->set_periodic[PID_PHASE], effect->u.periodic.phase);
+ pidff->set_periodic[PID_PERIOD].value[0] = effect->u.periodic.period;
+
+ hid_submit_report(pidff->hid, pidff->reports[PID_SET_PERIODIC],
+ USB_DIR_OUT);
+
+}
+
+/*
+ * Test if periodic effect parameters have changed
+ */
+static int pidff_needs_set_periodic(struct ff_effect *effect,
+ struct ff_effect *old)
+{
+ return effect->u.periodic.magnitude != old->u.periodic.magnitude ||
+ effect->u.periodic.offset != old->u.periodic.offset ||
+ effect->u.periodic.phase != old->u.periodic.phase ||
+ effect->u.periodic.period != old->u.periodic.period;
+}
+
+/*
+ * Send condition effect reports to the device
+ */
+static void pidff_set_condition_report(struct pidff_device *pidff,
+ struct ff_effect *effect)
+{
+ int i;
+
+ pidff->set_condition[PID_EFFECT_BLOCK_INDEX].value[0] =
+ pidff->block_load[PID_EFFECT_BLOCK_INDEX].value[0];
+
+ for (i = 0; i < 2; i++) {
+ pidff->set_condition[PID_PARAM_BLOCK_OFFSET].value[0] = i;
+ pidff_set_signed(&pidff->set_condition[PID_CP_OFFSET],
+ effect->u.condition[i].center);
+ pidff_set_signed(&pidff->set_condition[PID_POS_COEFFICIENT],
+ effect->u.condition[i].right_coeff);
+ pidff_set_signed(&pidff->set_condition[PID_NEG_COEFFICIENT],
+ effect->u.condition[i].left_coeff);
+ pidff_set(&pidff->set_condition[PID_POS_SATURATION],
+ effect->u.condition[i].right_saturation);
+ pidff_set(&pidff->set_condition[PID_NEG_SATURATION],
+ effect->u.condition[i].left_saturation);
+ pidff_set(&pidff->set_condition[PID_DEAD_BAND],
+ effect->u.condition[i].deadband);
+ hid_wait_io(pidff->hid);
+ hid_submit_report(pidff->hid, pidff->reports[PID_SET_CONDITION],
+ USB_DIR_OUT);
+ }
+}
+
+/*
+ * Test if condition effect parameters have changed
+ */
+static int pidff_needs_set_condition(struct ff_effect *effect,
+ struct ff_effect *old)
+{
+ int i;
+ int ret = 0;
+
+ for (i = 0; i < 2; i++) {
+ struct ff_condition_effect *cond = &effect->u.condition[i];
+ struct ff_condition_effect *old_cond = &old->u.condition[i];
+
+ ret |= cond->center != old_cond->center ||
+ cond->right_coeff != old_cond->right_coeff ||
+ cond->left_coeff != old_cond->left_coeff ||
+ cond->right_saturation != old_cond->right_saturation ||
+ cond->left_saturation != old_cond->left_saturation ||
+ cond->deadband != old_cond->deadband;
+ }
+
+ return ret;
+}
+
+/*
+ * Send ramp force report to the device
+ */
+static void pidff_set_ramp_force_report(struct pidff_device *pidff,
+ struct ff_effect *effect)
+{
+ pidff->set_ramp[PID_EFFECT_BLOCK_INDEX].value[0] =
+ pidff->block_load[PID_EFFECT_BLOCK_INDEX].value[0];
+ pidff_set_signed(&pidff->set_ramp[PID_RAMP_START],
+ effect->u.ramp.start_level);
+ pidff_set_signed(&pidff->set_ramp[PID_RAMP_END],
+ effect->u.ramp.end_level);
+ hid_submit_report(pidff->hid, pidff->reports[PID_SET_RAMP],
+ USB_DIR_OUT);
+}
+
+/*
+ * Test if ramp force parameters have changed
+ */
+static int pidff_needs_set_ramp(struct ff_effect *effect, struct ff_effect *old)
+{
+ return effect->u.ramp.start_level != old->u.ramp.start_level ||
+ effect->u.ramp.end_level != old->u.ramp.end_level;
+}
+
+/*
+ * Send a request for effect upload to the device
+ *
+ * Returns 0 if device reported success, -ENOSPC if the device reported memory
+ * is full. Upon unknown response the function will retry for 60 times, if
+ * still unsuccessful -EIO is returned.
+ */
+static int pidff_request_effect_upload(struct pidff_device *pidff, int efnum)
+{
+ int j;
+
+ pidff->create_new_effect_type->value[0] = efnum;
+ hid_submit_report(pidff->hid, pidff->reports[PID_CREATE_NEW_EFFECT],
+ USB_DIR_OUT);
+ debug("create_new_effect sent, type: %d", efnum);
+
+ pidff->block_load[PID_EFFECT_BLOCK_INDEX].value[0] = 0;
+ pidff->block_load_status->value[0] = 0;
+ hid_wait_io(pidff->hid);
+
+ for (j = 0; j < 60; j++) {
+ debug("pid_block_load requested");
+ hid_submit_report(pidff->hid, pidff->reports[PID_BLOCK_LOAD],
+ USB_DIR_IN);
+ hid_wait_io(pidff->hid);
+ if (pidff->block_load_status->value[0] ==
+ pidff->status_id[PID_BLOCK_LOAD_SUCCESS]) {
+ debug("device reported free memory: %d bytes",
+ pidff->block_load[PID_RAM_POOL_AVAILABLE].value ?
+ pidff->block_load[PID_RAM_POOL_AVAILABLE].value[0] : -1);
+ return 0;
+ }
+ if (pidff->block_load_status->value[0] ==
+ pidff->status_id[PID_BLOCK_LOAD_FULL]) {
+ debug("not enough memory free: %d bytes",
+ pidff->block_load[PID_RAM_POOL_AVAILABLE].value ?
+ pidff->block_load[PID_RAM_POOL_AVAILABLE].value[0] : -1);
+ return -ENOSPC;
+ }
+ }
+ printk(KERN_ERR "hid-pidff: pid_block_load failed 60 times\n");
+ return -EIO;
+}
+
+/*
+ * Play the effect with PID id n times
+ */
+static void pidff_playback_pid(struct pidff_device *pidff, int pid_id, int n)
+{
+ pidff->effect_operation[PID_EFFECT_BLOCK_INDEX].value[0] = pid_id;
+
+ if (n == 0) {
+ pidff->effect_operation_status->value[0] =
+ pidff->operation_id[PID_EFFECT_STOP];
+ } else {
+ pidff->effect_operation_status->value[0] =
+ pidff->operation_id[PID_EFFECT_START];
+ pidff->effect_operation[PID_LOOP_COUNT].value[0] = n;
+ }
+
+ hid_wait_io(pidff->hid);
+ hid_submit_report(pidff->hid, pidff->reports[PID_EFFECT_OPERATION],
+ USB_DIR_OUT);
+}
+
+/**
+ * Play the effect with effect id @effect_id for @value times
+ */
+static int pidff_playback(struct input_dev *dev, int effect_id, int value)
+{
+ struct pidff_device *pidff = dev->ff->private;
+
+ pidff_playback_pid(pidff, pidff->pid_id[effect_id], value);
+
+ return 0;
+}
+
+/*
+ * Erase effect with PID id
+ */
+static void pidff_erase_pid(struct pidff_device *pidff, int pid_id)
+{
+ pidff->block_free[PID_EFFECT_BLOCK_INDEX].value[0] = pid_id;
+ hid_submit_report(pidff->hid, pidff->reports[PID_BLOCK_FREE],
+ USB_DIR_OUT);
+}
+
+/*
+ * Stop and erase effect with effect_id
+ */
+static int pidff_erase_effect(struct input_dev *dev, int effect_id)
+{
+ struct pidff_device *pidff = dev->ff->private;
+ int pid_id = pidff->pid_id[effect_id];
+
+ debug("starting to erase %d/%d", effect_id, pidff->pid_id[effect_id]);
+ pidff_playback_pid(pidff, pid_id, 0);
+ pidff_erase_pid(pidff, pid_id);
+
+ return 0;
+}
+
+/*
+ * Effect upload handler
+ */
+static int pidff_upload_effect(struct input_dev *dev, struct ff_effect *effect,
+ struct ff_effect *old)
+{
+ struct pidff_device *pidff = dev->ff->private;
+ int type_id;
+ int error;
+
+ switch (effect->type) {
+ case FF_CONSTANT:
+ if (!old) {
+ error = pidff_request_effect_upload(pidff,
+ pidff->type_id[PID_CONSTANT]);
+ if (error)
+ return error;
+ }
+ if (!old || pidff_needs_set_effect(effect, old))
+ pidff_set_effect_report(pidff, effect);
+ if (!old || pidff_needs_set_constant(effect, old))
+ pidff_set_constant_force_report(pidff, effect);
+ if (!old ||
+ pidff_needs_set_envelope(&effect->u.constant.envelope,
+ &old->u.constant.envelope))
+ pidff_set_envelope_report(pidff,
+ &effect->u.constant.envelope);
+ break;
+
+ case FF_PERIODIC:
+ if (!old) {
+ switch (effect->u.periodic.waveform) {
+ case FF_SQUARE:
+ type_id = PID_SQUARE;
+ break;
+ case FF_TRIANGLE:
+ type_id = PID_TRIANGLE;
+ break;
+ case FF_SINE:
+ type_id = PID_SINE;
+ break;
+ case FF_SAW_UP:
+ type_id = PID_SAW_UP;
+ break;
+ case FF_SAW_DOWN:
+ type_id = PID_SAW_DOWN;
+ break;
+ default:
+ printk(KERN_ERR
+ "hid-pidff: invalid waveform\n");
+ return -EINVAL;
+ }
+
+ error = pidff_request_effect_upload(pidff,
+ pidff->type_id[type_id]);
+ if (error)
+ return error;
+ }
+ if (!old || pidff_needs_set_effect(effect, old))
+ pidff_set_effect_report(pidff, effect);
+ if (!old || pidff_needs_set_periodic(effect, old))
+ pidff_set_periodic_report(pidff, effect);
+ if (!old ||
+ pidff_needs_set_envelope(&effect->u.periodic.envelope,
+ &old->u.periodic.envelope))
+ pidff_set_envelope_report(pidff,
+ &effect->u.periodic.envelope);
+ break;
+
+ case FF_RAMP:
+ if (!old) {
+ error = pidff_request_effect_upload(pidff,
+ pidff->type_id[PID_RAMP]);
+ if (error)
+ return error;
+ }
+ if (!old || pidff_needs_set_effect(effect, old))
+ pidff_set_effect_report(pidff, effect);
+ if (!old || pidff_needs_set_ramp(effect, old))
+ pidff_set_ramp_force_report(pidff, effect);
+ if (!old ||
+ pidff_needs_set_envelope(&effect->u.ramp.envelope,
+ &old->u.ramp.envelope))
+ pidff_set_envelope_report(pidff,
+ &effect->u.ramp.envelope);
+ break;
+
+ case FF_SPRING:
+ if (!old) {
+ error = pidff_request_effect_upload(pidff,
+ pidff->type_id[PID_SPRING]);
+ if (error)
+ return error;
+ }
+ if (!old || pidff_needs_set_effect(effect, old))
+ pidff_set_effect_report(pidff, effect);
+ if (!old || pidff_needs_set_condition(effect, old))
+ pidff_set_condition_report(pidff, effect);
+ break;
+
+ case FF_FRICTION:
+ if (!old) {
+ error = pidff_request_effect_upload(pidff,
+ pidff->type_id[PID_FRICTION]);
+ if (error)
+ return error;
+ }
+ if (!old || pidff_needs_set_effect(effect, old))
+ pidff_set_effect_report(pidff, effect);
+ if (!old || pidff_needs_set_condition(effect, old))
+ pidff_set_condition_report(pidff, effect);
+ break;
+
+ case FF_DAMPER:
+ if (!old) {
+ error = pidff_request_effect_upload(pidff,
+ pidff->type_id[PID_DAMPER]);
+ if (error)
+ return error;
+ }
+ if (!old || pidff_needs_set_effect(effect, old))
+ pidff_set_effect_report(pidff, effect);
+ if (!old || pidff_needs_set_condition(effect, old))
+ pidff_set_condition_report(pidff, effect);
+ break;
+
+ case FF_INERTIA:
+ if (!old) {
+ error = pidff_request_effect_upload(pidff,
+ pidff->type_id[PID_INERTIA]);
+ if (error)
+ return error;
+ }
+ if (!old || pidff_needs_set_effect(effect, old))
+ pidff_set_effect_report(pidff, effect);
+ if (!old || pidff_needs_set_condition(effect, old))
+ pidff_set_condition_report(pidff, effect);
+ break;
+
+ default:
+ printk(KERN_ERR "hid-pidff: invalid type\n");
+ return -EINVAL;
+ }
+
+ if (!old)
+ pidff->pid_id[effect->id] =
+ pidff->block_load[PID_EFFECT_BLOCK_INDEX].value[0];
+
+ debug("uploaded");
+
+ return 0;
+}
+
+/*
+ * set_gain() handler
+ */
+static void pidff_set_gain(struct input_dev *dev, u16 gain)
+{
+ struct pidff_device *pidff = dev->ff->private;
+
+ pidff_set(&pidff->device_gain[PID_DEVICE_GAIN_FIELD], gain);
+ hid_submit_report(pidff->hid, pidff->reports[PID_DEVICE_GAIN],
+ USB_DIR_OUT);
+}
+
+static void pidff_autocenter(struct pidff_device *pidff, u16 magnitude)
+{
+ struct hid_field *field =
+ pidff->block_load[PID_EFFECT_BLOCK_INDEX].field;
+
+ if (!magnitude) {
+ pidff_playback_pid(pidff, field->logical_minimum, 0);
+ return;
+ }
+
+ pidff_playback_pid(pidff, field->logical_minimum, 1);
+
+ pidff->set_effect[PID_EFFECT_BLOCK_INDEX].value[0] =
+ pidff->block_load[PID_EFFECT_BLOCK_INDEX].field->logical_minimum;
+ pidff->set_effect_type->value[0] = pidff->type_id[PID_SPRING];
+ pidff->set_effect[PID_DURATION].value[0] = 0;
+ pidff->set_effect[PID_TRIGGER_BUTTON].value[0] = 0;
+ pidff->set_effect[PID_TRIGGER_REPEAT_INT].value[0] = 0;
+ pidff_set(&pidff->set_effect[PID_GAIN], magnitude);
+ pidff->set_effect[PID_START_DELAY].value[0] = 0;
+
+ hid_submit_report(pidff->hid, pidff->reports[PID_SET_EFFECT],
+ USB_DIR_OUT);
+}
+
+/*
+ * pidff_set_autocenter() handler
+ */
+static void pidff_set_autocenter(struct input_dev *dev, u16 magnitude)
+{
+ struct pidff_device *pidff = dev->ff->private;
+
+ pidff_autocenter(pidff, magnitude);
+}
+
+/*
+ * Find fields from a report and fill a pidff_usage
+ */
+static int pidff_find_fields(struct pidff_usage *usage, const u8 *table,
+ struct hid_report *report, int count, int strict)
+{
+ int i, j, k, found;
+
+ for (k = 0; k < count; k++) {
+ found = 0;
+ for (i = 0; i < report->maxfield; i++) {
+ if (report->field[i]->maxusage !=
+ report->field[i]->report_count) {
+ debug("maxusage and report_count do not match, "
+ "skipping");
+ continue;
+ }
+ for (j = 0; j < report->field[i]->maxusage; j++) {
+ if (report->field[i]->usage[j].hid ==
+ (HID_UP_PID | table[k])) {
+ debug("found %d at %d->%d", k, i, j);
+ usage[k].field = report->field[i];
+ usage[k].value =
+ &report->field[i]->value[j];
+ found = 1;
+ break;
+ }
+ }
+ if (found)
+ break;
+ }
+ if (!found && strict) {
+ debug("failed to locate %d", k);
+ return -1;
+ }
+ }
+ return 0;
+}
+
+/*
+ * Return index into pidff_reports for the given usage
+ */
+static int pidff_check_usage(int usage)
+{
+ int i;
+
+ for (i = 0; i < sizeof(pidff_reports); i++)
+ if (usage == (HID_UP_PID | pidff_reports[i]))
+ return i;
+
+ return -1;
+}
+
+/*
+ * Find the reports and fill pidff->reports[]
+ * report_type specifies either OUTPUT or FEATURE reports
+ */
+static void pidff_find_reports(struct hid_device *hid, int report_type,
+ struct pidff_device *pidff)
+{
+ struct hid_report *report;
+ int i, ret;
+
+ list_for_each_entry(report,
+ &hid->report_enum[report_type].report_list, list) {
+ if (report->maxfield < 1)
+ continue;
+ ret = pidff_check_usage(report->field[0]->logical);
+ if (ret != -1) {
+ debug("found usage 0x%02x from field->logical",
+ pidff_reports[ret]);
+ pidff->reports[ret] = report;
+ continue;
+ }
+
+ /*
+ * Sometimes logical collections are stacked to indicate
+ * different usages for the report and the field, in which
+ * case we want the usage of the parent. However, Linux HID
+ * implementation hides this fact, so we have to dig it up
+ * ourselves
+ */
+ i = report->field[0]->usage[0].collection_index;
+ if (i <= 0 ||
+ hid->collection[i - 1].type != HID_COLLECTION_LOGICAL)
+ continue;
+ ret = pidff_check_usage(hid->collection[i - 1].usage);
+ if (ret != -1 && !pidff->reports[ret]) {
+ debug("found usage 0x%02x from collection array",
+ pidff_reports[ret]);
+ pidff->reports[ret] = report;
+ }
+ }
+}
+
+/*
+ * Test if the required reports have been found
+ */
+static int pidff_reports_ok(struct pidff_device *pidff)
+{
+ int i;
+
+ for (i = 0; i <= PID_REQUIRED_REPORTS; i++) {
+ if (!pidff->reports[i]) {
+ debug("%d missing", i);
+ return 0;
+ }
+ }
+
+ return 1;
+}
+
+/*
+ * Find a field with a specific usage within a report
+ */
+static struct hid_field *pidff_find_special_field(struct hid_report *report,
+ int usage, int enforce_min)
+{
+ int i;
+
+ for (i = 0; i < report->maxfield; i++) {
+ if (report->field[i]->logical == (HID_UP_PID | usage) &&
+ report->field[i]->report_count > 0) {
+ if (!enforce_min ||
+ report->field[i]->logical_minimum == 1)
+ return report->field[i];
+ else {
+ printk(KERN_ERR "hid-pidff: logical_minimum "
+ "is not 1 as it should be\n");
+ return NULL;
+ }
+ }
+ }
+ return NULL;
+}
+
+/*
+ * Fill a pidff->*_id struct table
+ */
+static int pidff_find_special_keys(int *keys, struct hid_field *fld,
+ const u8 *usagetable, int count)
+{
+
+ int i, j;
+ int found = 0;
+
+ for (i = 0; i < count; i++) {
+ for (j = 0; j < fld->maxusage; j++) {
+ if (fld->usage[j].hid == (HID_UP_PID | usagetable[i])) {
+ keys[i] = j + 1;
+ found++;
+ break;
+ }
+ }
+ }
+ return found;
+}
+
+#define PIDFF_FIND_SPECIAL_KEYS(keys, field, name) \
+ pidff_find_special_keys(pidff->keys, pidff->field, pidff_ ## name, \
+ sizeof(pidff_ ## name))
+
+/*
+ * Find and check the special fields
+ */
+static int pidff_find_special_fields(struct pidff_device *pidff)
+{
+ debug("finding special fields");
+
+ pidff->create_new_effect_type =
+ pidff_find_special_field(pidff->reports[PID_CREATE_NEW_EFFECT],
+ 0x25, 1);
+ pidff->set_effect_type =
+ pidff_find_special_field(pidff->reports[PID_SET_EFFECT],
+ 0x25, 1);
+ pidff->effect_direction =
+ pidff_find_special_field(pidff->reports[PID_SET_EFFECT],
+ 0x57, 0);
+ pidff->device_control =
+ pidff_find_special_field(pidff->reports[PID_DEVICE_CONTROL],
+ 0x96, 1);
+ pidff->block_load_status =
+ pidff_find_special_field(pidff->reports[PID_BLOCK_LOAD],
+ 0x8b, 1);
+ pidff->effect_operation_status =
+ pidff_find_special_field(pidff->reports[PID_EFFECT_OPERATION],
+ 0x78, 1);
+
+ debug("search done");
+
+ if (!pidff->create_new_effect_type || !pidff->set_effect_type) {
+ printk(KERN_ERR "hid-pidff: effect lists not found\n");
+ return -1;
+ }
+
+ if (!pidff->effect_direction) {
+ printk(KERN_ERR "hid-pidff: direction field not found\n");
+ return -1;
+ }
+
+ if (!pidff->device_control) {
+ printk(KERN_ERR "hid-pidff: device control field not found\n");
+ return -1;
+ }
+
+ if (!pidff->block_load_status) {
+ printk(KERN_ERR
+ "hid-pidff: block load status field not found\n");
+ return -1;
+ }
+
+ if (!pidff->effect_operation_status) {
+ printk(KERN_ERR
+ "hid-pidff: effect operation field not found\n");
+ return -1;
+ }
+
+ pidff_find_special_keys(pidff->control_id, pidff->device_control,
+ pidff_device_control,
+ sizeof(pidff_device_control));
+
+ PIDFF_FIND_SPECIAL_KEYS(control_id, device_control, device_control);
+
+ if (!PIDFF_FIND_SPECIAL_KEYS(type_id, create_new_effect_type,
+ effect_types)) {
+ printk(KERN_ERR "hid-pidff: no effect types found\n");
+ return -1;
+ }
+
+ if (PIDFF_FIND_SPECIAL_KEYS(status_id, block_load_status,
+ block_load_status) !=
+ sizeof(pidff_block_load_status)) {
+ printk(KERN_ERR
+ "hidpidff: block load status identifiers not found\n");
+ return -1;
+ }
+
+ if (PIDFF_FIND_SPECIAL_KEYS(operation_id, effect_operation_status,
+ effect_operation_status) !=
+ sizeof(pidff_effect_operation_status)) {
+ printk(KERN_ERR
+ "hidpidff: effect operation identifiers not found\n");
+ return -1;
+ }
+
+ return 0;
+}
+
+/**
+ * Find the implemented effect types
+ */
+static int pidff_find_effects(struct pidff_device *pidff,
+ struct input_dev *dev)
+{
+ int i;
+
+ for (i = 0; i < sizeof(pidff_effect_types); i++) {
+ int pidff_type = pidff->type_id[i];
+ if (pidff->set_effect_type->usage[pidff_type].hid !=
+ pidff->create_new_effect_type->usage[pidff_type].hid) {
+ printk(KERN_ERR "hid-pidff: "
+ "effect type number %d is invalid\n", i);
+ return -1;
+ }
+ }
+
+ if (pidff->type_id[PID_CONSTANT])
+ set_bit(FF_CONSTANT, dev->ffbit);
+ if (pidff->type_id[PID_RAMP])
+ set_bit(FF_RAMP, dev->ffbit);
+ if (pidff->type_id[PID_SQUARE]) {
+ set_bit(FF_SQUARE, dev->ffbit);
+ set_bit(FF_PERIODIC, dev->ffbit);
+ }
+ if (pidff->type_id[PID_SINE]) {
+ set_bit(FF_SINE, dev->ffbit);
+ set_bit(FF_PERIODIC, dev->ffbit);
+ }
+ if (pidff->type_id[PID_TRIANGLE]) {
+ set_bit(FF_TRIANGLE, dev->ffbit);
+ set_bit(FF_PERIODIC, dev->ffbit);
+ }
+ if (pidff->type_id[PID_SAW_UP]) {
+ set_bit(FF_SAW_UP, dev->ffbit);
+ set_bit(FF_PERIODIC, dev->ffbit);
+ }
+ if (pidff->type_id[PID_SAW_DOWN]) {
+ set_bit(FF_SAW_DOWN, dev->ffbit);
+ set_bit(FF_PERIODIC, dev->ffbit);
+ }
+ if (pidff->type_id[PID_SPRING])
+ set_bit(FF_SPRING, dev->ffbit);
+ if (pidff->type_id[PID_DAMPER])
+ set_bit(FF_DAMPER, dev->ffbit);
+ if (pidff->type_id[PID_INERTIA])
+ set_bit(FF_INERTIA, dev->ffbit);
+ if (pidff->type_id[PID_FRICTION])
+ set_bit(FF_FRICTION, dev->ffbit);
+
+ return 0;
+
+}
+
+#define PIDFF_FIND_FIELDS(name, report, strict) \
+ pidff_find_fields(pidff->name, pidff_ ## name, \
+ pidff->reports[report], \
+ sizeof(pidff_ ## name), strict)
+
+/*
+ * Fill and check the pidff_usages
+ */
+static int pidff_init_fields(struct pidff_device *pidff, struct input_dev *dev)
+{
+ int envelope_ok = 0;
+
+ if (PIDFF_FIND_FIELDS(set_effect, PID_SET_EFFECT, 1)) {
+ printk(KERN_ERR
+ "hid-pidff: unknown set_effect report layout\n");
+ return -ENODEV;
+ }
+
+ PIDFF_FIND_FIELDS(block_load, PID_BLOCK_LOAD, 0);
+ if (!pidff->block_load[PID_EFFECT_BLOCK_INDEX].value) {
+ printk(KERN_ERR
+ "hid-pidff: unknown pid_block_load report layout\n");
+ return -ENODEV;
+ }
+
+ if (PIDFF_FIND_FIELDS(effect_operation, PID_EFFECT_OPERATION, 1)) {
+ printk(KERN_ERR
+ "hid-pidff: unknown effect_operation report layout\n");
+ return -ENODEV;
+ }
+
+ if (PIDFF_FIND_FIELDS(block_free, PID_BLOCK_FREE, 1)) {
+ printk(KERN_ERR
+ "hid-pidff: unknown pid_block_free report layout\n");
+ return -ENODEV;
+ }
+
+ if (!PIDFF_FIND_FIELDS(set_envelope, PID_SET_ENVELOPE, 1))
+ envelope_ok = 1;
+
+ if (pidff_find_special_fields(pidff) || pidff_find_effects(pidff, dev))
+ return -ENODEV;
+
+ if (!envelope_ok) {
+ if (test_and_clear_bit(FF_CONSTANT, dev->ffbit))
+ printk(KERN_WARNING "hid-pidff: "
+ "has constant effect but no envelope\n");
+ if (test_and_clear_bit(FF_RAMP, dev->ffbit))
+ printk(KERN_WARNING "hid-pidff: "
+ "has ramp effect but no envelope\n");
+
+ if (test_and_clear_bit(FF_PERIODIC, dev->ffbit))
+ printk(KERN_WARNING "hid-pidff: "
+ "has periodic effect but no envelope\n");
+ }
+
+ if (test_bit(FF_CONSTANT, dev->ffbit) &&
+ PIDFF_FIND_FIELDS(set_constant, PID_SET_CONSTANT, 1)) {
+ printk(KERN_WARNING
+ "hid-pidff: unknown constant effect layout\n");
+ clear_bit(FF_CONSTANT, dev->ffbit);
+ }
+
+ if (test_bit(FF_RAMP, dev->ffbit) &&
+ PIDFF_FIND_FIELDS(set_ramp, PID_SET_RAMP, 1)) {
+ printk(KERN_WARNING "hid-pidff: unknown ramp effect layout\n");
+ clear_bit(FF_RAMP, dev->ffbit);
+ }
+
+ if ((test_bit(FF_SPRING, dev->ffbit) ||
+ test_bit(FF_DAMPER, dev->ffbit) ||
+ test_bit(FF_FRICTION, dev->ffbit) ||
+ test_bit(FF_INERTIA, dev->ffbit)) &&
+ PIDFF_FIND_FIELDS(set_condition, PID_SET_CONDITION, 1)) {
+ printk(KERN_WARNING
+ "hid-pidff: unknown condition effect layout\n");
+ clear_bit(FF_SPRING, dev->ffbit);
+ clear_bit(FF_DAMPER, dev->ffbit);
+ clear_bit(FF_FRICTION, dev->ffbit);
+ clear_bit(FF_INERTIA, dev->ffbit);
+ }
+
+ if (test_bit(FF_PERIODIC, dev->ffbit) &&
+ PIDFF_FIND_FIELDS(set_periodic, PID_SET_PERIODIC, 1)) {
+ printk(KERN_WARNING
+ "hid-pidff: unknown periodic effect layout\n");
+ clear_bit(FF_PERIODIC, dev->ffbit);
+ }
+
+ PIDFF_FIND_FIELDS(pool, PID_POOL, 0);
+
+ if (!PIDFF_FIND_FIELDS(device_gain, PID_DEVICE_GAIN, 1))
+ set_bit(FF_GAIN, dev->ffbit);
+
+ return 0;
+}
+
+/*
+ * Reset the device
+ */
+static void pidff_reset(struct pidff_device *pidff)
+{
+ struct hid_device *hid = pidff->hid;
+ int i = 0;
+
+ pidff->device_control->value[0] = pidff->control_id[PID_RESET];
+ /* We reset twice as sometimes hid_wait_io isn't waiting long enough */
+ hid_submit_report(hid, pidff->reports[PID_DEVICE_CONTROL], USB_DIR_OUT);
+ hid_wait_io(hid);
+ hid_submit_report(hid, pidff->reports[PID_DEVICE_CONTROL], USB_DIR_OUT);
+ hid_wait_io(hid);
+
+ pidff->device_control->value[0] =
+ pidff->control_id[PID_ENABLE_ACTUATORS];
+ hid_submit_report(hid, pidff->reports[PID_DEVICE_CONTROL], USB_DIR_OUT);
+ hid_wait_io(hid);
+
+ /* pool report is sometimes messed up, refetch it */
+ hid_submit_report(hid, pidff->reports[PID_POOL], USB_DIR_IN);
+ hid_wait_io(hid);
+
+ if (pidff->pool[PID_SIMULTANEOUS_MAX].value) {
+ int sim_effects = pidff->pool[PID_SIMULTANEOUS_MAX].value[0];
+ while (sim_effects < 2) {
+ if (i++ > 20) {
+ printk(KERN_WARNING "hid-pidff: device reports "
+ "%d simultaneous effects\n",
+ sim_effects);
+ break;
+ }
+ debug("pid_pool requested again");
+ hid_submit_report(hid, pidff->reports[PID_POOL],
+ USB_DIR_IN);
+ hid_wait_io(hid);
+ }
+ }
+}
+
+/*
+ * Test if autocenter modification is using the supported method
+ */
+static int pidff_check_autocenter(struct pidff_device *pidff,
+ struct input_dev *dev)
+{
+ int error;
+
+ /*
+ * Let's find out if autocenter modification is supported
+ * Specification doesn't specify anything, so we request an
+ * effect upload and cancel it immediately. If the approved
+ * effect id was one above the minimum, then we assume the first
+ * effect id is a built-in spring type effect used for autocenter
+ */
+
+ error = pidff_request_effect_upload(pidff, 1);
+ if (error) {
+ printk(KERN_ERR "hid-pidff: upload request failed\n");
+ return error;
+ }
+
+ if (pidff->block_load[PID_EFFECT_BLOCK_INDEX].value[0] ==
+ pidff->block_load[PID_EFFECT_BLOCK_INDEX].field->logical_minimum + 1) {
+ pidff_autocenter(pidff, 0xffff);
+ set_bit(FF_AUTOCENTER, dev->ffbit);
+ } else {
+ printk(KERN_NOTICE "hid-pidff: "
+ "device has unknown autocenter control method\n");
+ }
+
+ pidff_erase_pid(pidff,
+ pidff->block_load[PID_EFFECT_BLOCK_INDEX].value[0]);
+
+ return 0;
+
+}
+
+/*
+ * Check if the device is PID and initialize it
+ */
+int hid_pidff_init(struct hid_device *hid)
+{
+ struct pidff_device *pidff;
+ struct hid_input *hidinput = list_entry(hid->inputs.next,
+ struct hid_input, list);
+ struct input_dev *dev = hidinput->input;
+ struct ff_device *ff;
+ int max_effects;
+ int error;
+
+ debug("starting pid init");
+
+ if (list_empty(&hid->report_enum[HID_OUTPUT_REPORT].report_list)) {
+ debug("not a PID device, no output report");
+ return -ENODEV;
+ }
+
+ pidff = kzalloc(sizeof(*pidff), GFP_KERNEL);
+ if (!pidff)
+ return -ENOMEM;
+
+ pidff->hid = hid;
+
+ pidff_find_reports(hid, HID_OUTPUT_REPORT, pidff);
+ pidff_find_reports(hid, HID_FEATURE_REPORT, pidff);
+
+ if (!pidff_reports_ok(pidff)) {
+ debug("reports not ok, aborting");
+ error = -ENODEV;
+ goto fail;
+ }
+
+ error = pidff_init_fields(pidff, dev);
+ if (error)
+ goto fail;
+
+ pidff_reset(pidff);
+
+ if (test_bit(FF_GAIN, dev->ffbit)) {
+ pidff_set(&pidff->device_gain[PID_DEVICE_GAIN_FIELD], 0xffff);
+ hid_submit_report(pidff->hid, pidff->reports[PID_DEVICE_GAIN],
+ USB_DIR_OUT);
+ }
+
+ error = pidff_check_autocenter(pidff, dev);
+ if (error)
+ goto fail;
+
+ max_effects =
+ pidff->block_load[PID_EFFECT_BLOCK_INDEX].field->logical_maximum -
+ pidff->block_load[PID_EFFECT_BLOCK_INDEX].field->logical_minimum +
+ 1;
+ debug("max effects is %d", max_effects);
+
+ if (max_effects > PID_EFFECTS_MAX)
+ max_effects = PID_EFFECTS_MAX;
+
+ if (pidff->pool[PID_SIMULTANEOUS_MAX].value)
+ debug("max simultaneous effects is %d",
+ pidff->pool[PID_SIMULTANEOUS_MAX].value[0]);
+
+ if (pidff->pool[PID_RAM_POOL_SIZE].value)
+ debug("device memory size is %d bytes",
+ pidff->pool[PID_RAM_POOL_SIZE].value[0]);
+
+ if (pidff->pool[PID_DEVICE_MANAGED_POOL].value &&
+ pidff->pool[PID_DEVICE_MANAGED_POOL].value[0] == 0) {
+ printk(KERN_NOTICE "hid-pidff: "
+ "device does not support device managed pool\n");
+ goto fail;
+ }
+
+ error = input_ff_create(dev, max_effects);
+ if (error)
+ goto fail;
+
+ ff = dev->ff;
+ ff->private = pidff;
+ ff->upload = pidff_upload_effect;
+ ff->erase = pidff_erase_effect;
+ ff->set_gain = pidff_set_gain;
+ ff->set_autocenter = pidff_set_autocenter;
+ ff->playback = pidff_playback;
+
+ printk(KERN_INFO "Force feedback for USB HID PID devices by "
+ "Anssi Hannula <anssi.hannula@gmail.com>\n");
+
+ return 0;
+
+ fail:
+ kfree(pidff);
+ return error;
+}
diff --git a/drivers/usb/input/hid-tmff.c b/drivers/usb/input/hid-tmff.c
index 534425c69c0a..2d5be4c318ac 100644
--- a/drivers/usb/input/hid-tmff.c
+++ b/drivers/usb/input/hid-tmff.c
@@ -28,97 +28,65 @@
*/
#include <linux/input.h>
-#include <linux/sched.h>
#undef DEBUG
#include <linux/usb.h>
-#include <linux/circ_buf.h>
-
#include "hid.h"
-#include "fixp-arith.h"
/* Usages for thrustmaster devices I know about */
#define THRUSTMASTER_USAGE_RUMBLE_LR (HID_UP_GENDESK | 0xbb)
-#define DELAY_CALC(t,delay) ((t) + (delay)*HZ/1000)
-
-/* Effect status */
-#define EFFECT_STARTED 0 /* Effect is going to play after some time */
-#define EFFECT_PLAYING 1 /* Effect is playing */
-#define EFFECT_USED 2
-
-/* For tmff_device::flags */
-#define DEVICE_CLOSING 0 /* The driver is being unitialised */
-
-/* Check that the current process can access an effect */
-#define CHECK_OWNERSHIP(effect) (current->pid == 0 \
- || effect.owner == current->pid)
-
-#define TMFF_CHECK_ID(id) ((id) >= 0 && (id) < TMFF_EFFECTS)
-#define TMFF_CHECK_OWNERSHIP(i, l) \
- (test_bit(EFFECT_USED, l->effects[i].flags) \
- && CHECK_OWNERSHIP(l->effects[i]))
-
-#define TMFF_EFFECTS 8
-
-struct tmff_effect {
- pid_t owner;
-
- struct ff_effect effect;
-
- unsigned long flags[1];
- unsigned int count; /* Number of times left to play */
-
- unsigned long play_at; /* When the effect starts to play */
- unsigned long stop_at; /* When the effect ends */
-};
struct tmff_device {
- struct hid_device *hid;
-
struct hid_report *report;
-
struct hid_field *rumble;
+};
- unsigned int effects_playing;
- struct tmff_effect effects[TMFF_EFFECTS];
- spinlock_t lock; /* device-level lock. Having locks on
- a per-effect basis could be nice, but
- isn't really necessary */
+/* Changes values from 0 to 0xffff into values from minimum to maximum */
+static inline int hid_tmff_scale(unsigned int in, int minimum, int maximum)
+{
+ int ret;
- unsigned long flags[1]; /* Contains various information about the
- state of the driver for this device */
+ ret = (in * (maximum - minimum) / 0xffff) + minimum;
+ if (ret < minimum)
+ return minimum;
+ if (ret > maximum)
+ return maximum;
+ return ret;
+}
- struct timer_list timer;
-};
+static int hid_tmff_play(struct input_dev *dev, void *data, struct ff_effect *effect)
+{
+ struct hid_device *hid = dev->private;
+ struct tmff_device *tmff = data;
+ int left, right; /* Rumbling */
-/* Callbacks */
-static void hid_tmff_exit(struct hid_device *hid);
-static int hid_tmff_event(struct hid_device *hid, struct input_dev *input,
- unsigned int type, unsigned int code, int value);
-static int hid_tmff_flush(struct input_dev *input, struct file *file);
-static int hid_tmff_upload_effect(struct input_dev *input,
- struct ff_effect *effect);
-static int hid_tmff_erase(struct input_dev *input, int id);
+ left = hid_tmff_scale(effect->u.rumble.weak_magnitude,
+ tmff->rumble->logical_minimum, tmff->rumble->logical_maximum);
+ right = hid_tmff_scale(effect->u.rumble.strong_magnitude,
+ tmff->rumble->logical_minimum, tmff->rumble->logical_maximum);
-/* Local functions */
-static void hid_tmff_recalculate_timer(struct tmff_device *tmff);
-static void hid_tmff_timer(unsigned long timer_data);
+ tmff->rumble->value[0] = left;
+ tmff->rumble->value[1] = right;
+ dbg("(left,right)=(%08x, %08x)", left, right);
+ hid_submit_report(hid, tmff->report, USB_DIR_OUT);
+
+ return 0;
+}
int hid_tmff_init(struct hid_device *hid)
{
- struct tmff_device *private;
+ struct tmff_device *tmff;
struct list_head *pos;
struct hid_input *hidinput = list_entry(hid->inputs.next, struct hid_input, list);
struct input_dev *input_dev = hidinput->input;
+ int error;
- private = kzalloc(sizeof(struct tmff_device), GFP_KERNEL);
- if (!private)
+ tmff = kzalloc(sizeof(struct tmff_device), GFP_KERNEL);
+ if (!tmff)
return -ENOMEM;
- hid->ff_private = private;
-
/* Find the report to use */
__list_for_each(pos, &hid->report_enum[HID_OUTPUT_REPORT].report_list) {
struct hid_report *report = (struct hid_report *)pos;
@@ -142,18 +110,18 @@ int hid_tmff_init(struct hid_device *hid)
continue;
}
- if (private->report && private->report != report) {
+ if (tmff->report && tmff->report != report) {
warn("ignoring THRUSTMASTER_USAGE_RUMBLE_LR in other report");
continue;
}
- if (private->rumble && private->rumble != field) {
+ if (tmff->rumble && tmff->rumble != field) {
warn("ignoring duplicate THRUSTMASTER_USAGE_RUMBLE_LR");
continue;
}
- private->report = report;
- private->rumble = field;
+ tmff->report = report;
+ tmff->rumble = field;
set_bit(FF_RUMBLE, input_dev->ffbit);
break;
@@ -162,302 +130,17 @@ int hid_tmff_init(struct hid_device *hid)
warn("ignoring unknown output usage %08x", field->usage[0].hid);
continue;
}
-
- /* Fallthrough to here only when a valid usage is found */
- input_dev->upload_effect = hid_tmff_upload_effect;
- input_dev->flush = hid_tmff_flush;
-
- set_bit(EV_FF, input_dev->evbit);
- input_dev->ff_effects_max = TMFF_EFFECTS;
}
}
- private->hid = hid;
-
- spin_lock_init(&private->lock);
- init_timer(&private->timer);
- private->timer.data = (unsigned long)private;
- private->timer.function = hid_tmff_timer;
-
- /* Event and exit callbacks */
- hid->ff_exit = hid_tmff_exit;
- hid->ff_event = hid_tmff_event;
-
- info("Force feedback for ThrustMaster rumble pad devices by Zinx Verituse <zinx@epicsol.org>");
-
- return 0;
-}
-
-static void hid_tmff_exit(struct hid_device *hid)
-{
- struct tmff_device *tmff = hid->ff_private;
- unsigned long flags;
-
- spin_lock_irqsave(&tmff->lock, flags);
-
- set_bit(DEVICE_CLOSING, tmff->flags);
- del_timer_sync(&tmff->timer);
-
- spin_unlock_irqrestore(&tmff->lock, flags);
-
- kfree(tmff);
-}
-
-static int hid_tmff_event(struct hid_device *hid, struct input_dev *input,
- unsigned int type, unsigned int code, int value)
-{
- struct tmff_device *tmff = hid->ff_private;
- struct tmff_effect *effect = &tmff->effects[code];
- unsigned long flags;
-
- if (type != EV_FF)
- return -EINVAL;
- if (!TMFF_CHECK_ID(code))
- return -EINVAL;
- if (!TMFF_CHECK_OWNERSHIP(code, tmff))
- return -EACCES;
- if (value < 0)
- return -EINVAL;
-
- spin_lock_irqsave(&tmff->lock, flags);
-
- if (value > 0) {
- set_bit(EFFECT_STARTED, effect->flags);
- clear_bit(EFFECT_PLAYING, effect->flags);
- effect->count = value;
- effect->play_at = DELAY_CALC(jiffies, effect->effect.replay.delay);
- } else {
- clear_bit(EFFECT_STARTED, effect->flags);
- clear_bit(EFFECT_PLAYING, effect->flags);
- }
-
- hid_tmff_recalculate_timer(tmff);
-
- spin_unlock_irqrestore(&tmff->lock, flags);
-
- return 0;
-
-}
-
-/* Erase all effects this process owns */
-
-static int hid_tmff_flush(struct input_dev *dev, struct file *file)
-{
- struct hid_device *hid = dev->private;
- struct tmff_device *tmff = hid->ff_private;
- int i;
-
- for (i=0; i<dev->ff_effects_max; ++i)
-
- /* NOTE: no need to lock here. The only times EFFECT_USED is
- modified is when effects are uploaded or when an effect is
- erased. But a process cannot close its dev/input/eventX fd
- and perform ioctls on the same fd all at the same time */
-
- if (current->pid == tmff->effects[i].owner
- && test_bit(EFFECT_USED, tmff->effects[i].flags))
- if (hid_tmff_erase(dev, i))
- warn("erase effect %d failed", i);
-
-
- return 0;
-}
-
-static int hid_tmff_erase(struct input_dev *dev, int id)
-{
- struct hid_device *hid = dev->private;
- struct tmff_device *tmff = hid->ff_private;
- unsigned long flags;
-
- if (!TMFF_CHECK_ID(id))
- return -EINVAL;
- if (!TMFF_CHECK_OWNERSHIP(id, tmff))
- return -EACCES;
-
- spin_lock_irqsave(&tmff->lock, flags);
-
- tmff->effects[id].flags[0] = 0;
- hid_tmff_recalculate_timer(tmff);
-
- spin_unlock_irqrestore(&tmff->lock, flags);
-
- return 0;
-}
-
-static int hid_tmff_upload_effect(struct input_dev *input,
- struct ff_effect *effect)
-{
- struct hid_device *hid = input->private;
- struct tmff_device *tmff = hid->ff_private;
- int id;
- unsigned long flags;
-
- if (!test_bit(effect->type, input->ffbit))
- return -EINVAL;
- if (effect->id != -1 && !TMFF_CHECK_ID(effect->id))
- return -EINVAL;
-
- spin_lock_irqsave(&tmff->lock, flags);
-
- if (effect->id == -1) {
- /* Find a free effect */
- for (id = 0; id < TMFF_EFFECTS && test_bit(EFFECT_USED, tmff->effects[id].flags); ++id);
-
- if (id >= TMFF_EFFECTS) {
- spin_unlock_irqrestore(&tmff->lock, flags);
- return -ENOSPC;
- }
-
- effect->id = id;
- tmff->effects[id].owner = current->pid;
- tmff->effects[id].flags[0] = 0;
- set_bit(EFFECT_USED, tmff->effects[id].flags);
-
- } else {
- /* Re-uploading an owned effect, to change parameters */
- id = effect->id;
- clear_bit(EFFECT_PLAYING, tmff->effects[id].flags);
+ error = input_ff_create_memless(input_dev, tmff, hid_tmff_play);
+ if (error) {
+ kfree(tmff);
+ return error;
}
- tmff->effects[id].effect = *effect;
-
- hid_tmff_recalculate_timer(tmff);
+ info("Force feedback for ThrustMaster rumble pad devices by Zinx Verituse <zinx@epicsol.org>");
- spin_unlock_irqrestore(&tmff->lock, flags);
return 0;
}
-/* Start the timer for the next start/stop/delay */
-/* Always call this while tmff->lock is locked */
-
-static void hid_tmff_recalculate_timer(struct tmff_device *tmff)
-{
- int i;
- int events = 0;
- unsigned long next_time;
-
- next_time = 0; /* Shut up compiler's incorrect warning */
-
- /* Find the next change in an effect's status */
- for (i = 0; i < TMFF_EFFECTS; ++i) {
- struct tmff_effect *effect = &tmff->effects[i];
- unsigned long play_time;
-
- if (!test_bit(EFFECT_STARTED, effect->flags))
- continue;
-
- effect->stop_at = DELAY_CALC(effect->play_at, effect->effect.replay.length);
-
- if (!test_bit(EFFECT_PLAYING, effect->flags))
- play_time = effect->play_at;
- else
- play_time = effect->stop_at;
-
- events++;
-
- if (time_after(jiffies, play_time))
- play_time = jiffies;
-
- if (events == 1)
- next_time = play_time;
- else {
- if (time_after(next_time, play_time))
- next_time = play_time;
- }
- }
-
- if (!events && tmff->effects_playing) {
- /* Treat all effects turning off as an event */
- events = 1;
- next_time = jiffies;
- }
-
- if (!events) {
- /* No events, no time, no need for a timer. */
- del_timer_sync(&tmff->timer);
- return;
- }
-
- mod_timer(&tmff->timer, next_time);
-}
-
-/* Changes values from 0 to 0xffff into values from minimum to maximum */
-static inline int hid_tmff_scale(unsigned int in, int minimum, int maximum)
-{
- int ret;
-
- ret = (in * (maximum - minimum) / 0xffff) + minimum;
- if (ret < minimum)
- return minimum;
- if (ret > maximum)
- return maximum;
- return ret;
-}
-
-static void hid_tmff_timer(unsigned long timer_data)
-{
- struct tmff_device *tmff = (struct tmff_device *) timer_data;
- struct hid_device *hid = tmff->hid;
- unsigned long flags;
- int left = 0, right = 0; /* Rumbling */
- int i;
-
- spin_lock_irqsave(&tmff->lock, flags);
-
- tmff->effects_playing = 0;
-
- for (i = 0; i < TMFF_EFFECTS; ++i) {
- struct tmff_effect *effect = &tmff->effects[i];
-
- if (!test_bit(EFFECT_STARTED, effect->flags))
- continue;
-
- if (!time_after(jiffies, effect->play_at))
- continue;
-
- if (time_after(jiffies, effect->stop_at)) {
-
- dbg("Finished playing once %d", i);
- clear_bit(EFFECT_PLAYING, effect->flags);
-
- if (--effect->count <= 0) {
- dbg("Stopped %d", i);
- clear_bit(EFFECT_STARTED, effect->flags);
- continue;
- } else {
- dbg("Start again %d", i);
- effect->play_at = DELAY_CALC(jiffies, effect->effect.replay.delay);
- continue;
- }
- }
-
- ++tmff->effects_playing;
-
- set_bit(EFFECT_PLAYING, effect->flags);
-
- switch (effect->effect.type) {
- case FF_RUMBLE:
- right += effect->effect.u.rumble.strong_magnitude;
- left += effect->effect.u.rumble.weak_magnitude;
- break;
- default:
- BUG();
- break;
- }
- }
-
- left = hid_tmff_scale(left, tmff->rumble->logical_minimum, tmff->rumble->logical_maximum);
- right = hid_tmff_scale(right, tmff->rumble->logical_minimum, tmff->rumble->logical_maximum);
-
- if (left != tmff->rumble->value[0] || right != tmff->rumble->value[1]) {
- tmff->rumble->value[0] = left;
- tmff->rumble->value[1] = right;
- dbg("(left,right)=(%08x, %08x)", left, right);
- hid_submit_report(hid, tmff->report, USB_DIR_OUT);
- }
-
- if (!test_bit(DEVICE_CLOSING, tmff->flags))
- hid_tmff_recalculate_timer(tmff);
-
- spin_unlock_irqrestore(&tmff->lock, flags);
-}
diff --git a/drivers/usb/input/hid-zpff.c b/drivers/usb/input/hid-zpff.c
new file mode 100644
index 000000000000..d2ce3214572c
--- /dev/null
+++ b/drivers/usb/input/hid-zpff.c
@@ -0,0 +1,110 @@
+/*
+ * Force feedback support for Zeroplus based devices
+ *
+ * Copyright (c) 2005, 2006 Anssi Hannula <anssi.hannula@gmail.com>
+ */
+
+/*
+ * 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 DEBUG */
+
+#define debug(format, arg...) pr_debug("hid-zpff: " format "\n" , ## arg)
+
+#include <linux/input.h>
+#include <linux/usb.h>
+#include "hid.h"
+
+struct zpff_device {
+ struct hid_report *report;
+};
+
+static int hid_zpff_play(struct input_dev *dev, void *data,
+ struct ff_effect *effect)
+{
+ struct hid_device *hid = dev->private;
+ struct zpff_device *zpff = data;
+ int left, right;
+
+ /*
+ * The following is specified the other way around in the Zeroplus
+ * datasheet but the order below is correct for the XFX Executioner;
+ * however it is possible that the XFX Executioner is an exception
+ */
+
+ left = effect->u.rumble.strong_magnitude;
+ right = effect->u.rumble.weak_magnitude;
+ debug("called with 0x%04x 0x%04x", left, right);
+
+ left = left * 0x7f / 0xffff;
+ right = right * 0x7f / 0xffff;
+
+ zpff->report->field[2]->value[0] = left;
+ zpff->report->field[3]->value[0] = right;
+ debug("running with 0x%02x 0x%02x", left, right);
+ hid_submit_report(hid, zpff->report, USB_DIR_OUT);
+
+ return 0;
+}
+
+int hid_zpff_init(struct hid_device *hid)
+{
+ struct zpff_device *zpff;
+ struct hid_report *report;
+ struct hid_input *hidinput = list_entry(hid->inputs.next,
+ struct hid_input, list);
+ struct list_head *report_list =
+ &hid->report_enum[HID_OUTPUT_REPORT].report_list;
+ struct input_dev *dev = hidinput->input;
+ int error;
+
+ if (list_empty(report_list)) {
+ printk(KERN_ERR "hid-zpff: no output report found\n");
+ return -ENODEV;
+ }
+
+ report = list_entry(report_list->next, struct hid_report, list);
+
+ if (report->maxfield < 4) {
+ printk(KERN_ERR "hid-zpff: not enough fields in report\n");
+ return -ENODEV;
+ }
+
+ zpff = kzalloc(sizeof(struct zpff_device), GFP_KERNEL);
+ if (!zpff)
+ return -ENOMEM;
+
+ set_bit(FF_RUMBLE, dev->ffbit);
+
+ error = input_ff_create_memless(dev, zpff, hid_zpff_play);
+ if (error) {
+ kfree(zpff);
+ return error;
+ }
+
+ zpff->report = report;
+ zpff->report->field[0]->value[0] = 0x00;
+ zpff->report->field[1]->value[0] = 0x02;
+ zpff->report->field[2]->value[0] = 0x00;
+ zpff->report->field[3]->value[0] = 0x00;
+ hid_submit_report(hid, zpff->report, USB_DIR_OUT);
+
+ printk(KERN_INFO "Force feedback for Zeroplus based devices by "
+ "Anssi Hannula <anssi.hannula@gmail.com>\n");
+
+ return 0;
+}
diff --git a/drivers/usb/input/hid.h b/drivers/usb/input/hid.h
index 778e575de352..b03fd9b075df 100644
--- a/drivers/usb/input/hid.h
+++ b/drivers/usb/input/hid.h
@@ -449,11 +449,6 @@ struct hid_device { /* device report descriptor */
char phys[64]; /* Device physical location */
char uniq[64]; /* Device unique identifier (serial #) */
- void *ff_private; /* Private data for the force-feedback driver */
- void (*ff_exit)(struct hid_device*); /* Called by hid_exit_ff(hid) */
- int (*ff_event)(struct hid_device *hid, struct input_dev *input,
- unsigned int type, unsigned int code, int value);
-
#ifdef CONFIG_USB_HIDINPUT_POWERBOOK
unsigned long pb_pressed_fn[NBITS(KEY_MAX)];
unsigned long pb_pressed_numlock[NBITS(KEY_MAX)];
@@ -521,29 +516,22 @@ void hid_close(struct hid_device *);
int hid_set_field(struct hid_field *, unsigned, __s32);
void hid_submit_report(struct hid_device *, struct hid_report *, unsigned char dir);
void hid_init_reports(struct hid_device *hid);
-struct hid_field *hid_find_field_by_usage(struct hid_device *hid, __u32 wanted_usage, int type);
int hid_wait_io(struct hid_device* hid);
#ifdef CONFIG_HID_FF
int hid_ff_init(struct hid_device *hid);
+
+int hid_lgff_init(struct hid_device *hid);
+int hid_tmff_init(struct hid_device *hid);
+int hid_zpff_init(struct hid_device *hid);
+#ifdef CONFIG_HID_PID
+int hid_pidff_init(struct hid_device *hid);
+#else
+static inline int hid_pidff_init(struct hid_device *hid) { return -ENODEV; }
+#endif
+
#else
static inline int hid_ff_init(struct hid_device *hid) { return -1; }
#endif
-static inline void hid_ff_exit(struct hid_device *hid)
-{
- if (hid->ff_exit)
- hid->ff_exit(hid);
-}
-static inline int hid_ff_event(struct hid_device *hid, struct input_dev *input,
- unsigned int type, unsigned int code, int value)
-{
- if (hid->ff_event)
- return hid->ff_event(hid, input, type, code, value);
- return -ENOSYS;
-}
-
-int hid_lgff_init(struct hid_device* hid);
-int hid_tmff_init(struct hid_device* hid);
-int hid_pid_init(struct hid_device* hid);
diff --git a/drivers/usb/input/pid.c b/drivers/usb/input/pid.c
deleted file mode 100644
index d9d9f656b8c9..000000000000
--- a/drivers/usb/input/pid.c
+++ /dev/null
@@ -1,295 +0,0 @@
-/*
- * PID Force feedback support for hid devices.
- *
- * Copyright (c) 2002 Rodrigo Damazio.
- * Portions by Johann Deneux and Bjorn Augustson
- */
-
-/*
- * 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
- *
- * Should you need to contact me, the author, you can do so by
- * e-mail - mail your message to <rdamazio@lsi.usp.br>
- */
-
-#include <linux/config.h>
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/mm.h>
-#include <linux/smp_lock.h>
-#include <linux/spinlock.h>
-#include <linux/input.h>
-#include <linux/usb.h>
-#include "hid.h"
-#include "pid.h"
-
-#define CHECK_OWNERSHIP(i, hid_pid) \
- ((i) < FF_EFFECTS_MAX && i >= 0 && \
- test_bit(FF_PID_FLAGS_USED, &hid_pid->effects[(i)].flags) && \
- (current->pid == 0 || \
- (hid_pid)->effects[(i)].owner == current->pid))
-
-/* Called when a transfer is completed */
-static void hid_pid_ctrl_out(struct urb *u, struct pt_regs *regs)
-{
- dev_dbg(&u->dev->dev, "hid_pid_ctrl_out - Transfer Completed\n");
-}
-
-static void hid_pid_exit(struct hid_device *hid)
-{
- struct hid_ff_pid *private = hid->ff_private;
-
- if (private->urbffout) {
- usb_kill_urb(private->urbffout);
- usb_free_urb(private->urbffout);
- }
-}
-
-static int pid_upload_periodic(struct hid_ff_pid *pid, struct ff_effect *effect, int is_update)
-{
- dev_info(&pid->hid->dev->dev, "requested periodic force upload\n");
- return 0;
-}
-
-static int pid_upload_constant(struct hid_ff_pid *pid, struct ff_effect *effect, int is_update)
-{
- dev_info(&pid->hid->dev->dev, "requested constant force upload\n");
- return 0;
-}
-
-static int pid_upload_condition(struct hid_ff_pid *pid, struct ff_effect *effect, int is_update)
-{
- dev_info(&pid->hid->dev->dev, "requested Condition force upload\n");
- return 0;
-}
-
-static int pid_upload_ramp(struct hid_ff_pid *pid, struct ff_effect *effect, int is_update)
-{
- dev_info(&pid->hid->dev->dev, "request ramp force upload\n");
- return 0;
-}
-
-static int hid_pid_event(struct hid_device *hid, struct input_dev *input,
- unsigned int type, unsigned int code, int value)
-{
- dev_dbg(&hid->dev->dev, "PID event received: type=%d,code=%d,value=%d.\n", type, code, value);
-
- if (type != EV_FF)
- return -1;
-
- return 0;
-}
-
-/* Lock must be held by caller */
-static void hid_pid_ctrl_playback(struct hid_device *hid, struct hid_pid_effect *effect, int play)
-{
- if (play)
- set_bit(FF_PID_FLAGS_PLAYING, &effect->flags);
- else
- clear_bit(FF_PID_FLAGS_PLAYING, &effect->flags);
-}
-
-static int hid_pid_erase(struct input_dev *dev, int id)
-{
- struct hid_device *hid = dev->private;
- struct hid_ff_pid *pid = hid->ff_private;
- struct hid_field *field;
- unsigned long flags;
- int ret;
-
- if (!CHECK_OWNERSHIP(id, pid))
- return -EACCES;
-
- /* Find report */
- field = hid_find_field_by_usage(hid, HID_UP_PID | FF_PID_USAGE_BLOCK_FREE,
- HID_OUTPUT_REPORT);
- if (!field) {
- dev_err(&hid->dev->dev, "couldn't find report\n");
- return -EIO;
- }
-
- ret = hid_set_field(field, 0, pid->effects[id].device_id);
- if (ret) {
- dev_err(&hid->dev->dev, "couldn't set field\n");
- return ret;
- }
-
- hid_submit_report(hid, field->report, USB_DIR_OUT);
-
- spin_lock_irqsave(&pid->lock, flags);
- hid_pid_ctrl_playback(hid, pid->effects + id, 0);
- pid->effects[id].flags = 0;
- spin_unlock_irqrestore(&pid->lock, flags);
-
- return 0;
-}
-
-/* Erase all effects this process owns */
-static int hid_pid_flush(struct input_dev *dev, struct file *file)
-{
- struct hid_device *hid = dev->private;
- struct hid_ff_pid *pid = hid->ff_private;
- int i;
-
- /*NOTE: no need to lock here. The only times EFFECT_USED is
- modified is when effects are uploaded or when an effect is
- erased. But a process cannot close its dev/input/eventX fd
- and perform ioctls on the same fd all at the same time */
- /*FIXME: multiple threads, anyone? */
- for (i = 0; i < dev->ff_effects_max; ++i)
- if (current->pid == pid->effects[i].owner
- && test_bit(FF_PID_FLAGS_USED, &pid->effects[i].flags))
- if (hid_pid_erase(dev, i))
- dev_warn(&hid->dev->dev, "erase effect %d failed", i);
-
- return 0;
-}
-
-static int hid_pid_upload_effect(struct input_dev *dev,
- struct ff_effect *effect)
-{
- struct hid_ff_pid *pid_private = (struct hid_ff_pid *)(dev->private);
- int ret;
- int is_update;
- unsigned long flags;
-
- dev_dbg(&pid_private->hid->dev->dev, "upload effect called: effect_type=%x\n", effect->type);
- /* Check this effect type is supported by this device */
- if (!test_bit(effect->type, dev->ffbit)) {
- dev_dbg(&pid_private->hid->dev->dev,
- "invalid kind of effect requested.\n");
- return -EINVAL;
- }
-
- /*
- * If we want to create a new effect, get a free id
- */
- if (effect->id == -1) {
- int id = 0;
-
- // Spinlock so we don`t get a race condition when choosing IDs
- spin_lock_irqsave(&pid_private->lock, flags);
-
- while (id < FF_EFFECTS_MAX)
- if (!test_and_set_bit(FF_PID_FLAGS_USED, &pid_private->effects[id++].flags))
- break;
-
- if (id == FF_EFFECTS_MAX) {
- spin_unlock_irqrestore(&pid_private->lock, flags);
-// TEMP - We need to get ff_effects_max correctly first: || id >= dev->ff_effects_max) {
- dev_dbg(&pid_private->hid->dev->dev, "Not enough device memory\n");
- return -ENOMEM;
- }
-
- effect->id = id;
- dev_dbg(&pid_private->hid->dev->dev, "effect ID is %d.\n", id);
- pid_private->effects[id].owner = current->pid;
- pid_private->effects[id].flags = (1 << FF_PID_FLAGS_USED);
- spin_unlock_irqrestore(&pid_private->lock, flags);
-
- is_update = FF_PID_FALSE;
- } else {
- /* We want to update an effect */
- if (!CHECK_OWNERSHIP(effect->id, pid_private))
- return -EACCES;
-
- /* Parameter type cannot be updated */
- if (effect->type != pid_private->effects[effect->id].effect.type)
- return -EINVAL;
-
- /* Check the effect is not already being updated */
- if (test_bit(FF_PID_FLAGS_UPDATING, &pid_private->effects[effect->id].flags))
- return -EAGAIN;
-
- is_update = FF_PID_TRUE;
- }
-
- /*
- * Upload the effect
- */
- switch (effect->type) {
- case FF_PERIODIC:
- ret = pid_upload_periodic(pid_private, effect, is_update);
- break;
-
- case FF_CONSTANT:
- ret = pid_upload_constant(pid_private, effect, is_update);
- break;
-
- case FF_SPRING:
- case FF_FRICTION:
- case FF_DAMPER:
- case FF_INERTIA:
- ret = pid_upload_condition(pid_private, effect, is_update);
- break;
-
- case FF_RAMP:
- ret = pid_upload_ramp(pid_private, effect, is_update);
- break;
-
- default:
- dev_dbg(&pid_private->hid->dev->dev,
- "invalid type of effect requested - %x.\n",
- effect->type);
- return -EINVAL;
- }
- /* If a packet was sent, forbid new updates until we are notified
- * that the packet was updated
- */
- if (ret == 0)
- set_bit(FF_PID_FLAGS_UPDATING, &pid_private->effects[effect->id].flags);
- pid_private->effects[effect->id].effect = *effect;
- return ret;
-}
-
-int hid_pid_init(struct hid_device *hid)
-{
- struct hid_ff_pid *private;
- struct hid_input *hidinput = list_entry(hid->inputs.next, struct hid_input, list);
- struct input_dev *input_dev = hidinput->input;
-
- private = hid->ff_private = kzalloc(sizeof(struct hid_ff_pid), GFP_KERNEL);
- if (!private)
- return -ENOMEM;
-
- private->hid = hid;
-
- hid->ff_exit = hid_pid_exit;
- hid->ff_event = hid_pid_event;
-
- /* Open output URB */
- if (!(private->urbffout = usb_alloc_urb(0, GFP_KERNEL))) {
- kfree(private);
- return -1;
- }
-
- usb_fill_control_urb(private->urbffout, hid->dev, 0,
- (void *)&private->ffcr, private->ctrl_buffer, 8,
- hid_pid_ctrl_out, hid);
-
- input_dev->upload_effect = hid_pid_upload_effect;
- input_dev->flush = hid_pid_flush;
- input_dev->ff_effects_max = 8; // A random default
- set_bit(EV_FF, input_dev->evbit);
- set_bit(EV_FF_STATUS, input_dev->evbit);
-
- spin_lock_init(&private->lock);
-
- printk(KERN_INFO "Force feedback driver for PID devices by Rodrigo Damazio <rdamazio@lsi.usp.br>.\n");
-
- return 0;
-}
diff --git a/drivers/usb/input/pid.h b/drivers/usb/input/pid.h
deleted file mode 100644
index a2cb9627ed0e..000000000000
--- a/drivers/usb/input/pid.h
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * PID Force feedback support for hid devices.
- *
- * Copyright (c) 2002 Rodrigo Damazio.
- */
-
-/*
- * 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
- *
- * Should you need to contact me, the author, you can do so by
- * e-mail - mail your message to <rdamazio@lsi.usp.br>
- */
-
-#define FF_EFFECTS_MAX 64
-
-#define FF_PID_FLAGS_USED 1 /* If the effect exists */
-#define FF_PID_FLAGS_UPDATING 2 /* If the effect is being updated */
-#define FF_PID_FLAGS_PLAYING 3 /* If the effect is currently being played */
-
-#define FF_PID_FALSE 0
-#define FF_PID_TRUE 1
-
-struct hid_pid_effect {
- unsigned long flags;
- pid_t owner;
- unsigned int device_id; /* The device-assigned ID */
- struct ff_effect effect;
-};
-
-struct hid_ff_pid {
- struct hid_device *hid;
- unsigned long gain;
-
- struct urb *urbffout;
- struct usb_ctrlrequest ffcr;
- spinlock_t lock;
-
- unsigned char ctrl_buffer[8];
-
- struct hid_pid_effect effects[FF_EFFECTS_MAX];
-};
-
-/*
- * Constants from the PID usage table (still far from complete)
- */
-
-#define FF_PID_USAGE_BLOCK_LOAD 0x89UL
-#define FF_PID_USAGE_BLOCK_FREE 0x90UL
-#define FF_PID_USAGE_NEW_EFFECT 0xABUL
-#define FF_PID_USAGE_POOL_REPORT 0x7FUL
diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c
index 0222d92842b8..8006e51c34bb 100644
--- a/drivers/usb/serial/usb-serial.c
+++ b/drivers/usb/serial/usb-serial.c
@@ -1015,7 +1015,7 @@ void usb_serial_disconnect(struct usb_interface *interface)
dev_info(dev, "device disconnected\n");
}
-static struct tty_operations serial_ops = {
+static const struct tty_operations serial_ops = {
.open = serial_open,
.close = serial_close,
.write = serial_write,
diff --git a/drivers/usb/storage/Kconfig b/drivers/usb/storage/Kconfig
index 86e48c42d6af..422a4b288e34 100644
--- a/drivers/usb/storage/Kconfig
+++ b/drivers/usb/storage/Kconfig
@@ -8,8 +8,7 @@ comment "may also be needed; see USB_STORAGE Help for more information"
config USB_STORAGE
tristate "USB Mass Storage support"
- depends on USB
- select SCSI
+ depends on USB && SCSI
---help---
Say Y here if you want to connect USB mass storage devices to your
computer's USB port. This is the driver you need for USB
@@ -18,7 +17,7 @@ config USB_STORAGE
similar devices. This driver may also be used for some cameras
and card readers.
- This option 'selects' (turns on, enables) 'SCSI', but you
+ This option depends on 'SCSI' support being enabled, but you
probably also need 'SCSI device support: SCSI disk support'
(BLK_DEV_SD) for most USB storage devices.
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index 702eb933cf88..a1c8923b0bf5 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -53,6 +53,11 @@ config FB
(e.g. an accelerated X server) and that are not frame buffer
device-aware may cause unexpected results. If unsure, say N.
+config FB_DDC
+ tristate
+ depends on FB && I2C && I2C_ALGOBIT
+ default n
+
config FB_CFB_FILLRECT
tristate
depends on FB
@@ -696,6 +701,7 @@ config FB_NVIDIA
depends on FB && PCI
select I2C_ALGOBIT if FB_NVIDIA_I2C
select I2C if FB_NVIDIA_I2C
+ select FB_DDC if FB_NVIDIA_I2C
select FB_MODE_HELPERS
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
@@ -734,6 +740,7 @@ config FB_RIVA
depends on FB && PCI
select I2C_ALGOBIT if FB_RIVA_I2C
select I2C if FB_RIVA_I2C
+ select FB_DDC if FB_RIVA_I2C
select FB_MODE_HELPERS
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
@@ -822,33 +829,52 @@ config FB_I810_I2C
depends on FB_I810 && FB_I810_GTF
select I2C
select I2C_ALGOBIT
+ select FB_DDC
help
config FB_INTEL
- tristate "Intel 830M/845G/852GM/855GM/865G support (EXPERIMENTAL)"
+ tristate "Intel 830M/845G/852GM/855GM/865G/915G/945G support (EXPERIMENTAL)"
depends on FB && EXPERIMENTAL && PCI && X86
select AGP
select AGP_INTEL
+ select I2C_ALGOBIT if FB_INTEL_I2C
+ select I2C if FB_INTEL_I2C
select FB_MODE_HELPERS
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
help
This driver supports the on-board graphics built in to the Intel
- 830M/845G/852GM/855GM/865G chipsets.
+ 830M/845G/852GM/855GM/865G/915G/915GM/945G/945GM chipsets.
Say Y if you have and plan to use such a board.
- To compile this driver as a module, choose M here: the
+ If you say Y here and want DDC/I2C support you must first say Y to
+ "I2C support" and "I2C bit-banging support" in the character devices
+ section.
+
+ If you say M here then "I2C support" and "I2C bit-banging support"
+ can be build either as modules or built-in.
+
+ To compile this driver as a module, choose M here: the
module will be called intelfb.
+ For more information, please read <file:Documentation/fb/intelfb.txt>
+
config FB_INTEL_DEBUG
- bool "Intel driver Debug Messages"
+ bool "Intel driver Debug Messages"
depends on FB_INTEL
---help---
Say Y here if you want the Intel driver to output all sorts
of debugging informations to provide to the maintainer when
something goes wrong.
+config FB_INTEL_I2C
+ bool "DDC/I2C for Intel framebuffer support"
+ depends on FB_INTEL
+ default y
+ help
+ Say Y here if you want DDC/I2C support for your on-board Intel graphics.
+
config FB_MATROX
tristate "Matrox acceleration"
depends on FB && PCI
@@ -994,6 +1020,7 @@ config FB_RADEON
depends on FB && PCI
select I2C_ALGOBIT if FB_RADEON_I2C
select I2C if FB_RADEON_I2C
+ select FB_DDC if FB_RADEON_I2C
select FB_MODE_HELPERS
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
@@ -1122,6 +1149,7 @@ config FB_SAVAGE
depends on FB && PCI && EXPERIMENTAL
select I2C_ALGOBIT if FB_SAVAGE_I2C
select I2C if FB_SAVAGE_I2C
+ select FB_DDC if FB_SAVAGE_I2C
select FB_MODE_HELPERS
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
@@ -1601,7 +1629,8 @@ config FB_VIRTUAL
kernel option `video=vfb:'.
To compile this driver as a module, choose M here: the
- module will be called vfb.
+ module will be called vfb. In order to load it, you must use
+ the vfb_enable=1 option.
If unsure, say N.
if VT
diff --git a/drivers/video/Makefile b/drivers/video/Makefile
index 481c6c9695f8..a6980e9a2481 100644
--- a/drivers/video/Makefile
+++ b/drivers/video/Makefile
@@ -18,6 +18,7 @@ obj-$(CONFIG_FB_CFB_FILLRECT) += cfbfillrect.o
obj-$(CONFIG_FB_CFB_COPYAREA) += cfbcopyarea.o
obj-$(CONFIG_FB_CFB_IMAGEBLIT) += cfbimgblt.o
obj-$(CONFIG_FB_MACMODES) += macmodes.o
+obj-$(CONFIG_FB_DDC) += fb_ddc.o
# Hardware specific drivers go first
obj-$(CONFIG_FB_RETINAZ3) += retz3fb.o
diff --git a/drivers/video/aty/atyfb.h b/drivers/video/aty/atyfb.h
index 55fb8b04489b..b04f49fb976a 100644
--- a/drivers/video/aty/atyfb.h
+++ b/drivers/video/aty/atyfb.h
@@ -355,5 +355,9 @@ static inline void wait_for_idle(struct atyfb_par *par)
extern void aty_reset_engine(const struct atyfb_par *par);
extern void aty_init_engine(struct atyfb_par *par, struct fb_info *info);
-extern void aty_st_pll_ct(int offset, u8 val, const struct atyfb_par *par);
extern u8 aty_ld_pll_ct(int offset, const struct atyfb_par *par);
+
+void atyfb_copyarea(struct fb_info *info, const struct fb_copyarea *area);
+void atyfb_fillrect(struct fb_info *info, const struct fb_fillrect *rect);
+void atyfb_imageblit(struct fb_info *info, const struct fb_image *image);
+
diff --git a/drivers/video/aty/atyfb_base.c b/drivers/video/aty/atyfb_base.c
index 19a71f045784..b45c9fd1b330 100644
--- a/drivers/video/aty/atyfb_base.c
+++ b/drivers/video/aty/atyfb_base.c
@@ -240,9 +240,6 @@ static int atyfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
static int atyfb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info);
static int atyfb_blank(int blank, struct fb_info *info);
static int atyfb_ioctl(struct fb_info *info, u_int cmd, u_long arg);
-extern void atyfb_fillrect(struct fb_info *info, const struct fb_fillrect *rect);
-extern void atyfb_copyarea(struct fb_info *info, const struct fb_copyarea *area);
-extern void atyfb_imageblit(struct fb_info *info, const struct fb_image *image);
#ifdef __sparc__
static int atyfb_mmap(struct fb_info *info, struct vm_area_struct *vma);
#endif
@@ -3863,6 +3860,7 @@ static int __devinit atyfb_setup(char *options)
static int __devinit atyfb_init(void)
{
+ int err1 = 1, err2 = 1;
#ifndef MODULE
char *option = NULL;
@@ -3872,12 +3870,13 @@ static int __devinit atyfb_init(void)
#endif
#ifdef CONFIG_PCI
- pci_register_driver(&atyfb_driver);
+ err1 = pci_register_driver(&atyfb_driver);
#endif
#ifdef CONFIG_ATARI
- atyfb_atari_probe();
+ err2 = atyfb_atari_probe();
#endif
- return 0;
+
+ return (err1 && err2) ? -ENODEV : 0;
}
static void __exit atyfb_exit(void)
diff --git a/drivers/video/aty/mach64_ct.c b/drivers/video/aty/mach64_ct.c
index e7056934c6a8..5080816be653 100644
--- a/drivers/video/aty/mach64_ct.c
+++ b/drivers/video/aty/mach64_ct.c
@@ -27,7 +27,7 @@ u8 aty_ld_pll_ct(int offset, const struct atyfb_par *par)
return res;
}
-void aty_st_pll_ct(int offset, u8 val, const struct atyfb_par *par)
+static void aty_st_pll_ct(int offset, u8 val, const struct atyfb_par *par)
{
/* write addr byte */
aty_st_8(CLOCK_CNTL_ADDR, ((offset << 2) & PLL_ADDR) | PLL_WR_EN, par);
diff --git a/drivers/video/aty/radeon_i2c.c b/drivers/video/aty/radeon_i2c.c
index 9aaca58c074a..676754520099 100644
--- a/drivers/video/aty/radeon_i2c.c
+++ b/drivers/video/aty/radeon_i2c.c
@@ -16,8 +16,6 @@
#include "radeonfb.h"
#include "../edid.h"
-#define RADEON_DDC 0x50
-
static void radeon_gpio_setscl(void* data, int state)
{
struct radeon_i2c_chan *chan = data;
@@ -138,108 +136,10 @@ void radeon_delete_i2c_busses(struct radeonfb_info *rinfo)
rinfo->i2c[3].rinfo = NULL;
}
-
-static u8 *radeon_do_probe_i2c_edid(struct radeon_i2c_chan *chan)
-{
- u8 start = 0x0;
- struct i2c_msg msgs[] = {
- {
- .addr = RADEON_DDC,
- .len = 1,
- .buf = &start,
- }, {
- .addr = RADEON_DDC,
- .flags = I2C_M_RD,
- .len = EDID_LENGTH,
- },
- };
- u8 *buf;
-
- buf = kmalloc(EDID_LENGTH, GFP_KERNEL);
- if (!buf) {
- dev_warn(&chan->rinfo->pdev->dev, "Out of memory!\n");
- return NULL;
- }
- msgs[1].buf = buf;
-
- if (i2c_transfer(&chan->adapter, msgs, 2) == 2)
- return buf;
- dev_dbg(&chan->rinfo->pdev->dev, "Unable to read EDID block.\n");
- kfree(buf);
- return NULL;
-}
-
-
-int radeon_probe_i2c_connector(struct radeonfb_info *rinfo, int conn, u8 **out_edid)
+int radeon_probe_i2c_connector(struct radeonfb_info *rinfo, int conn,
+ u8 **out_edid)
{
- u32 reg = rinfo->i2c[conn-1].ddc_reg;
- u8 *edid = NULL;
- int i, j;
-
- OUTREG(reg, INREG(reg) &
- ~(VGA_DDC_DATA_OUTPUT | VGA_DDC_CLK_OUTPUT));
-
- OUTREG(reg, INREG(reg) & ~(VGA_DDC_CLK_OUT_EN));
- (void)INREG(reg);
-
- for (i = 0; i < 3; i++) {
- /* For some old monitors we need the
- * following process to initialize/stop DDC
- */
- OUTREG(reg, INREG(reg) & ~(VGA_DDC_DATA_OUT_EN));
- (void)INREG(reg);
- msleep(13);
-
- OUTREG(reg, INREG(reg) & ~(VGA_DDC_CLK_OUT_EN));
- (void)INREG(reg);
- for (j = 0; j < 5; j++) {
- msleep(10);
- if (INREG(reg) & VGA_DDC_CLK_INPUT)
- break;
- }
- if (j == 5)
- continue;
-
- OUTREG(reg, INREG(reg) | VGA_DDC_DATA_OUT_EN);
- (void)INREG(reg);
- msleep(15);
- OUTREG(reg, INREG(reg) | VGA_DDC_CLK_OUT_EN);
- (void)INREG(reg);
- msleep(15);
- OUTREG(reg, INREG(reg) & ~(VGA_DDC_DATA_OUT_EN));
- (void)INREG(reg);
- msleep(15);
-
- /* Do the real work */
- edid = radeon_do_probe_i2c_edid(&rinfo->i2c[conn-1]);
-
- OUTREG(reg, INREG(reg) |
- (VGA_DDC_DATA_OUT_EN | VGA_DDC_CLK_OUT_EN));
- (void)INREG(reg);
- msleep(15);
-
- OUTREG(reg, INREG(reg) & ~(VGA_DDC_CLK_OUT_EN));
- (void)INREG(reg);
- for (j = 0; j < 10; j++) {
- msleep(10);
- if (INREG(reg) & VGA_DDC_CLK_INPUT)
- break;
- }
-
- OUTREG(reg, INREG(reg) & ~(VGA_DDC_DATA_OUT_EN));
- (void)INREG(reg);
- msleep(15);
- OUTREG(reg, INREG(reg) |
- (VGA_DDC_DATA_OUT_EN | VGA_DDC_CLK_OUT_EN));
- (void)INREG(reg);
- if (edid)
- break;
- }
- /* Release the DDC lines when done or the Apple Cinema HD display
- * will switch off
- */
- OUTREG(reg, INREG(reg) & ~(VGA_DDC_CLK_OUT_EN | VGA_DDC_DATA_OUT_EN));
- (void)INREG(reg);
+ u8 *edid = fb_ddc_read(&rinfo->i2c[conn-1].adapter);
if (out_edid)
*out_edid = edid;
diff --git a/drivers/video/aty/radeon_pm.c b/drivers/video/aty/radeon_pm.c
index 365de5dcc888..9a2b0d69b0ae 100644
--- a/drivers/video/aty/radeon_pm.c
+++ b/drivers/video/aty/radeon_pm.c
@@ -86,6 +86,9 @@ static struct radeon_device_id radeon_workaround_list[] = {
BUGFIX("Samsung P35",
PCI_VENDOR_ID_SAMSUNG, 0xc00c,
radeon_pm_off, radeon_reinitialize_M10),
+ BUGFIX("Acer Aspire 2010",
+ PCI_VENDOR_ID_AI, 0x0061,
+ radeon_pm_off, radeon_reinitialize_M10),
{ .ident = NULL }
};
diff --git a/drivers/video/au1100fb.c b/drivers/video/au1100fb.c
index f25d5d648333..ef5c16f7f5a6 100644
--- a/drivers/video/au1100fb.c
+++ b/drivers/video/au1100fb.c
@@ -8,6 +8,7 @@
* <c.pellegrin@exadron.com>
*
* PM support added by Rodolfo Giometti <giometti@linux.it>
+ * Cursor enable/disable by Rodolfo Giometti <giometti@linux.it>
*
* Copyright 2002 MontaVista Software
* Author: MontaVista Software, Inc.
@@ -110,6 +111,10 @@ static struct fb_var_screeninfo au1100fb_var __initdata = {
static struct au1100fb_drv_info drv_info;
+static int nocursor = 0;
+module_param(nocursor, int, 0644);
+MODULE_PARM_DESC(nocursor, "cursor enable/disable");
+
/*
* Set hardware with var settings. This will enable the controller with a specific
* mode, normally validated with the fb_check_var method
@@ -422,6 +427,17 @@ int au1100fb_fb_mmap(struct fb_info *fbi, struct vm_area_struct *vma)
return 0;
}
+/* fb_cursor
+ * Used to disable cursor drawing...
+ */
+int au1100fb_fb_cursor(struct fb_info *info, struct fb_cursor *cursor)
+{
+ if (nocursor)
+ return 0;
+ else
+ return -EINVAL; /* just to force soft_cursor() call */
+}
+
static struct fb_ops au1100fb_ops =
{
.owner = THIS_MODULE,
@@ -433,6 +449,7 @@ static struct fb_ops au1100fb_ops =
.fb_imageblit = cfb_imageblit,
.fb_rotate = au1100fb_fb_rotate,
.fb_mmap = au1100fb_fb_mmap,
+ .fb_cursor = au1100fb_fb_cursor,
};
@@ -677,7 +694,7 @@ int au1100fb_setup(char *options)
if (options) {
while ((this_opt = strsep(&options,",")) != NULL) {
/* Panel option */
- if (!strncmp(this_opt, "panel:", 6)) {
+ if (!strncmp(this_opt, "panel:", 6)) {
int i;
this_opt += 6;
for (i = 0; i < num_panels; i++) {
@@ -685,13 +702,18 @@ int au1100fb_setup(char *options)
known_lcd_panels[i].name,
strlen(this_opt))) {
panel_idx = i;
- break;
+ break;
+ }
}
- }
if (i >= num_panels) {
print_warn("Panel %s not supported!", this_opt);
}
}
+ if (!strncmp(this_opt, "nocursor", 8)) {
+ this_opt += 8;
+ nocursor = 1;
+ print_info("Cursor disabled");
+ }
/* Mode option (only option that start with digit) */
else if (isdigit(this_opt[0])) {
mode = kmalloc(strlen(this_opt) + 1, GFP_KERNEL);
@@ -700,7 +722,7 @@ int au1100fb_setup(char *options)
/* Unsupported option */
else {
print_warn("Unsupported option \"%s\"", this_opt);
- }
+ }
}
}
diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c
index 1b4f75d1f8a9..8c041daa3a15 100644
--- a/drivers/video/console/fbcon.c
+++ b/drivers/video/console/fbcon.c
@@ -133,6 +133,7 @@ static int info_idx = -1;
/* console rotation */
static int rotate;
+static int fbcon_has_sysfs;
static const struct consw fb_con;
@@ -396,9 +397,8 @@ static void fb_flashcursor(void *private)
vc = vc_cons[ops->currcon].d;
if (!vc || !CON_IS_VISIBLE(vc) ||
- fbcon_is_inactive(vc, info) ||
registered_fb[con2fb_map[vc->vc_num]] != info ||
- vc_cons[ops->currcon].d->vc_deccm != 1) {
+ vc->vc_deccm != 1) {
release_console_sem();
return;
}
@@ -2166,7 +2166,12 @@ static int fbcon_switch(struct vc_data *vc)
fbcon_del_cursor_timer(old_info);
}
- fbcon_add_cursor_timer(info);
+ if (fbcon_is_inactive(vc, info) ||
+ ops->blank_state != FB_BLANK_UNBLANK)
+ fbcon_del_cursor_timer(info);
+ else
+ fbcon_add_cursor_timer(info);
+
set_blitting_type(vc, info);
ops->cursor_reset = 1;
@@ -2276,10 +2281,11 @@ static int fbcon_blank(struct vc_data *vc, int blank, int mode_switch)
update_screen(vc);
}
- if (!blank)
- fbcon_add_cursor_timer(info);
- else
+ if (fbcon_is_inactive(vc, info) ||
+ ops->blank_state != FB_BLANK_UNBLANK)
fbcon_del_cursor_timer(info);
+ else
+ fbcon_add_cursor_timer(info);
return 0;
}
@@ -3161,11 +3167,26 @@ static struct class_device_attribute class_device_attrs[] = {
static int fbcon_init_class_device(void)
{
- int i;
+ int i, error = 0;
+
+ fbcon_has_sysfs = 1;
+
+ for (i = 0; i < ARRAY_SIZE(class_device_attrs); i++) {
+ error = class_device_create_file(fbcon_class_device,
+ &class_device_attrs[i]);
+
+ if (error)
+ break;
+ }
+
+ if (error) {
+ while (--i >= 0)
+ class_device_remove_file(fbcon_class_device,
+ &class_device_attrs[i]);
+
+ fbcon_has_sysfs = 0;
+ }
- for (i = 0; i < ARRAY_SIZE(class_device_attrs); i++)
- class_device_create_file(fbcon_class_device,
- &class_device_attrs[i]);
return 0;
}
@@ -3225,7 +3246,10 @@ static void fbcon_exit(void)
module_put(info->fbops->owner);
if (info->fbcon_par) {
+ struct fbcon_ops *ops = info->fbcon_par;
+
fbcon_del_cursor_timer(info);
+ kfree(ops->cursor_src);
kfree(info->fbcon_par);
info->fbcon_par = NULL;
}
@@ -3271,9 +3295,13 @@ static void __exit fbcon_deinit_class_device(void)
{
int i;
- for (i = 0; i < ARRAY_SIZE(class_device_attrs); i++)
- class_device_remove_file(fbcon_class_device,
- &class_device_attrs[i]);
+ if (fbcon_has_sysfs) {
+ for (i = 0; i < ARRAY_SIZE(class_device_attrs); i++)
+ class_device_remove_file(fbcon_class_device,
+ &class_device_attrs[i]);
+
+ fbcon_has_sysfs = 0;
+ }
}
static void __exit fb_console_exit(void)
diff --git a/drivers/video/console/fbcon.h b/drivers/video/console/fbcon.h
index f244ad066d68..b9386d168c04 100644
--- a/drivers/video/console/fbcon.h
+++ b/drivers/video/console/fbcon.h
@@ -80,6 +80,8 @@ struct fbcon_ops {
char *cursor_data;
u8 *fontbuffer;
u8 *fontdata;
+ u8 *cursor_src;
+ u32 cursor_size;
u32 fd_size;
};
/*
diff --git a/drivers/video/console/fbcon_ccw.c b/drivers/video/console/fbcon_ccw.c
index 4481c80b8b2a..825e6d6972a7 100644
--- a/drivers/video/console/fbcon_ccw.c
+++ b/drivers/video/console/fbcon_ccw.c
@@ -391,7 +391,7 @@ static void ccw_cursor(struct vc_data *vc, struct fb_info *info, int mode,
ops->cursor_reset = 0;
}
-int ccw_update_start(struct fb_info *info)
+static int ccw_update_start(struct fb_info *info)
{
struct fbcon_ops *ops = info->fbcon_par;
u32 yoffset;
diff --git a/drivers/video/console/fbcon_cw.c b/drivers/video/console/fbcon_cw.c
index 7f92c06afea7..c637e6318803 100644
--- a/drivers/video/console/fbcon_cw.c
+++ b/drivers/video/console/fbcon_cw.c
@@ -375,7 +375,7 @@ static void cw_cursor(struct vc_data *vc, struct fb_info *info, int mode,
ops->cursor_reset = 0;
}
-int cw_update_start(struct fb_info *info)
+static int cw_update_start(struct fb_info *info)
{
struct fbcon_ops *ops = info->fbcon_par;
u32 vxres = GETVXRES(ops->p->scrollmode, info);
diff --git a/drivers/video/console/fbcon_ud.c b/drivers/video/console/fbcon_ud.c
index ab91005e64dc..1473506df5d0 100644
--- a/drivers/video/console/fbcon_ud.c
+++ b/drivers/video/console/fbcon_ud.c
@@ -415,7 +415,7 @@ static void ud_cursor(struct vc_data *vc, struct fb_info *info, int mode,
ops->cursor_reset = 0;
}
-int ud_update_start(struct fb_info *info)
+static int ud_update_start(struct fb_info *info)
{
struct fbcon_ops *ops = info->fbcon_par;
int xoffset, yoffset;
diff --git a/drivers/video/console/softcursor.c b/drivers/video/console/softcursor.c
index 557c563e4aed..7d07d8383569 100644
--- a/drivers/video/console/softcursor.c
+++ b/drivers/video/console/softcursor.c
@@ -20,11 +20,12 @@
int soft_cursor(struct fb_info *info, struct fb_cursor *cursor)
{
+ struct fbcon_ops *ops = info->fbcon_par;
unsigned int scan_align = info->pixmap.scan_align - 1;
unsigned int buf_align = info->pixmap.buf_align - 1;
unsigned int i, size, dsize, s_pitch, d_pitch;
struct fb_image *image;
- u8 *dst, *src;
+ u8 *dst;
if (info->state != FBINFO_STATE_RUNNING)
return 0;
@@ -32,11 +33,19 @@ int soft_cursor(struct fb_info *info, struct fb_cursor *cursor)
s_pitch = (cursor->image.width + 7) >> 3;
dsize = s_pitch * cursor->image.height;
- src = kmalloc(dsize + sizeof(struct fb_image), GFP_ATOMIC);
- if (!src)
- return -ENOMEM;
+ if (dsize + sizeof(struct fb_image) != ops->cursor_size) {
+ if (ops->cursor_src != NULL)
+ kfree(ops->cursor_src);
+ ops->cursor_size = dsize + sizeof(struct fb_image);
- image = (struct fb_image *) (src + dsize);
+ ops->cursor_src = kmalloc(ops->cursor_size, GFP_ATOMIC);
+ if (!ops->cursor_src) {
+ ops->cursor_size = 0;
+ return -ENOMEM;
+ }
+ }
+
+ image = (struct fb_image *) (ops->cursor_src + dsize);
*image = cursor->image;
d_pitch = (s_pitch + scan_align) & ~scan_align;
@@ -48,21 +57,23 @@ int soft_cursor(struct fb_info *info, struct fb_cursor *cursor)
switch (cursor->rop) {
case ROP_XOR:
for (i = 0; i < dsize; i++)
- src[i] = image->data[i] ^ cursor->mask[i];
+ ops->cursor_src[i] = image->data[i] ^
+ cursor->mask[i];
break;
case ROP_COPY:
default:
for (i = 0; i < dsize; i++)
- src[i] = image->data[i] & cursor->mask[i];
+ ops->cursor_src[i] = image->data[i] &
+ cursor->mask[i];
break;
}
} else
- memcpy(src, image->data, dsize);
+ memcpy(ops->cursor_src, image->data, dsize);
- fb_pad_aligned_buffer(dst, d_pitch, src, s_pitch, image->height);
+ fb_pad_aligned_buffer(dst, d_pitch, ops->cursor_src, s_pitch,
+ image->height);
image->data = dst;
info->fbops->fb_imageblit(info, image);
- kfree(src);
return 0;
}
diff --git a/drivers/video/fb_ddc.c b/drivers/video/fb_ddc.c
new file mode 100644
index 000000000000..3aa6ebf68f17
--- /dev/null
+++ b/drivers/video/fb_ddc.c
@@ -0,0 +1,116 @@
+/*
+ * driver/vide/fb_ddc.c - DDC/EDID read support.
+ *
+ * Copyright (C) 2006 Dennis Munsie <dmunsie@cecropia.com>
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file COPYING in the main directory of this archive
+ * for more details.
+ */
+
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/fb.h>
+#include <linux/i2c-algo-bit.h>
+
+#include "edid.h"
+
+#define DDC_ADDR 0x50
+
+static unsigned char *fb_do_probe_ddc_edid(struct i2c_adapter *adapter)
+{
+ unsigned char start = 0x0;
+ struct i2c_msg msgs[] = {
+ {
+ .addr = DDC_ADDR,
+ .len = 1,
+ .buf = &start,
+ }, {
+ .addr = DDC_ADDR,
+ .flags = I2C_M_RD,
+ .len = EDID_LENGTH,
+ }
+ };
+ unsigned char *buf;
+
+ buf = kmalloc(EDID_LENGTH, GFP_KERNEL);
+ if (!buf) {
+ dev_warn(&adapter->dev, "unable to allocate memory for EDID "
+ "block.\n");
+ return NULL;
+ }
+ msgs[1].buf = buf;
+
+ if (i2c_transfer(adapter, msgs, 2) == 2)
+ return buf;
+
+ dev_warn(&adapter->dev, "unable to read EDID block.\n");
+ kfree(buf);
+ return NULL;
+}
+
+unsigned char *fb_ddc_read(struct i2c_adapter *adapter)
+{
+ struct i2c_algo_bit_data *algo_data = adapter->algo_data;
+ unsigned char *edid = NULL;
+ int i, j;
+
+ algo_data->setscl(algo_data->data, 1);
+ algo_data->setscl(algo_data->data, 0);
+
+ for (i = 0; i < 3; i++) {
+ /* For some old monitors we need the
+ * following process to initialize/stop DDC
+ */
+ algo_data->setsda(algo_data->data, 0);
+ msleep(13);
+
+ algo_data->setscl(algo_data->data, 1);
+ for (j = 0; j < 5; j++) {
+ msleep(10);
+ if (algo_data->getscl(algo_data->data))
+ break;
+ }
+ if (j == 5)
+ continue;
+
+ algo_data->setsda(algo_data->data, 0);
+ msleep(15);
+ algo_data->setscl(algo_data->data, 0);
+ msleep(15);
+ algo_data->setsda(algo_data->data, 1);
+ msleep(15);
+
+ /* Do the real work */
+ edid = fb_do_probe_ddc_edid(adapter);
+ algo_data->setsda(algo_data->data, 0);
+ algo_data->setscl(algo_data->data, 0);
+ msleep(15);
+
+ algo_data->setscl(algo_data->data, 1);
+ for (j = 0; j < 10; j++) {
+ msleep(10);
+ if (algo_data->getscl(algo_data->data))
+ break;
+ }
+
+ algo_data->setsda(algo_data->data, 1);
+ msleep(15);
+ algo_data->setscl(algo_data->data, 0);
+ if (edid)
+ break;
+ }
+ /* Release the DDC lines when done or the Apple Cinema HD display
+ * will switch off
+ */
+ algo_data->setsda(algo_data->data, 0);
+ algo_data->setscl(algo_data->data, 0);
+
+ return edid;
+}
+
+EXPORT_SYMBOL_GPL(fb_ddc_read);
+
+MODULE_AUTHOR("Dennis Munsie <dmunsie@cecropia.com>");
+MODULE_DESCRIPTION("DDC/EDID reading support");
+MODULE_LICENSE("GPL");
diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c
index 17961e3ecaa0..93ffcdd95f50 100644
--- a/drivers/video/fbmem.c
+++ b/drivers/video/fbmem.c
@@ -554,7 +554,8 @@ static int fbmem_read_proc(char *buf, char **start, off_t offset,
int clen;
clen = 0;
- for (fi = registered_fb; fi < &registered_fb[FB_MAX] && len < 4000; fi++)
+ for (fi = registered_fb; fi < &registered_fb[FB_MAX] && clen < 4000;
+ fi++)
if (*fi)
clen += sprintf(buf + clen, "%d %s\n",
(*fi)->node,
diff --git a/drivers/video/fbsysfs.c b/drivers/video/fbsysfs.c
index c151dcf68786..d3a50417ed9a 100644
--- a/drivers/video/fbsysfs.c
+++ b/drivers/video/fbsysfs.c
@@ -20,6 +20,8 @@
#include <linux/console.h>
#include <linux/module.h>
+#define FB_SYSFS_FLAG_ATTR 1
+
/**
* framebuffer_alloc - creates a new frame buffer info structure
*
@@ -483,12 +485,27 @@ static struct class_device_attribute class_device_attrs[] = {
int fb_init_class_device(struct fb_info *fb_info)
{
- unsigned int i;
+ int i, error = 0;
+
class_set_devdata(fb_info->class_device, fb_info);
- for (i = 0; i < ARRAY_SIZE(class_device_attrs); i++)
- class_device_create_file(fb_info->class_device,
- &class_device_attrs[i]);
+ fb_info->class_flag |= FB_SYSFS_FLAG_ATTR;
+
+ for (i = 0; i < ARRAY_SIZE(class_device_attrs); i++) {
+ error = class_device_create_file(fb_info->class_device,
+ &class_device_attrs[i]);
+
+ if (error)
+ break;
+ }
+
+ if (error) {
+ while (--i >= 0)
+ class_device_remove_file(fb_info->class_device,
+ &class_device_attrs[i]);
+ fb_info->class_flag &= ~FB_SYSFS_FLAG_ATTR;
+ }
+
return 0;
}
@@ -496,9 +513,13 @@ void fb_cleanup_class_device(struct fb_info *fb_info)
{
unsigned int i;
- for (i = 0; i < ARRAY_SIZE(class_device_attrs); i++)
- class_device_remove_file(fb_info->class_device,
- &class_device_attrs[i]);
+ if (fb_info->class_flag & FB_SYSFS_FLAG_ATTR) {
+ for (i = 0; i < ARRAY_SIZE(class_device_attrs); i++)
+ class_device_remove_file(fb_info->class_device,
+ &class_device_attrs[i]);
+
+ fb_info->class_flag &= ~FB_SYSFS_FLAG_ATTR;
+ }
}
#ifdef CONFIG_FB_BACKLIGHT
diff --git a/drivers/video/i810/i810-i2c.c b/drivers/video/i810/i810-i2c.c
index 7d06b38e80a0..b38d805db313 100644
--- a/drivers/video/i810/i810-i2c.c
+++ b/drivers/video/i810/i810-i2c.c
@@ -19,7 +19,6 @@
#include "i810_main.h"
#include "../edid.h"
-#define I810_DDC 0x50
/* bit locations in the registers */
#define SCL_DIR_MASK 0x0001
#define SCL_DIR 0x0002
@@ -150,53 +149,14 @@ void i810_delete_i2c_busses(struct i810fb_par *par)
par->chan[2].par = NULL;
}
-static u8 *i810_do_probe_i2c_edid(struct i810fb_i2c_chan *chan)
-{
- u8 start = 0x0;
- struct i2c_msg msgs[] = {
- {
- .addr = I810_DDC,
- .len = 1,
- .buf = &start,
- }, {
- .addr = I810_DDC,
- .flags = I2C_M_RD,
- .len = EDID_LENGTH,
- },
- };
- u8 *buf;
-
- buf = kmalloc(EDID_LENGTH, GFP_KERNEL);
- if (!buf) {
- DPRINTK("i810-i2c: Failed to allocate memory\n");
- return NULL;
- }
- msgs[1].buf = buf;
-
- if (i2c_transfer(&chan->adapter, msgs, 2) == 2) {
- DPRINTK("i810-i2c: I2C Transfer successful\n");
- return buf;
- }
-
- DPRINTK("i810-i2c: Unable to read EDID block.\n");
- kfree(buf);
- return NULL;
-}
-
int i810_probe_i2c_connector(struct fb_info *info, u8 **out_edid, int conn)
{
struct i810fb_par *par = info->par;
u8 *edid = NULL;
- int i;
DPRINTK("i810-i2c: Probe DDC%i Bus\n", conn+1);
if (conn < par->ddc_num) {
- for (i = 0; i < 3; i++) {
- /* Do the real work */
- edid = i810_do_probe_i2c_edid(&par->chan[conn]);
- if (edid)
- break;
- }
+ edid = fb_ddc_read(&par->chan[conn].adapter);
} else {
const u8 *e = fb_firmware_edid(info->device);
diff --git a/drivers/video/i810/i810_main.c b/drivers/video/i810/i810_main.c
index d42edaccb84c..b55a12d95eb2 100644
--- a/drivers/video/i810/i810_main.c
+++ b/drivers/video/i810/i810_main.c
@@ -1602,7 +1602,10 @@ static int i810fb_resume(struct pci_dev *dev)
acquire_console_sem();
pci_set_power_state(dev, PCI_D0);
pci_restore_state(dev);
- pci_enable_device(dev);
+
+ if (pci_enable_device(dev))
+ goto fail;
+
pci_set_master(dev);
agp_bind_memory(par->i810_gtt.i810_fb_memory,
par->fb.offset);
@@ -1611,6 +1614,7 @@ static int i810fb_resume(struct pci_dev *dev)
i810fb_set_par(info);
fb_set_suspend (info, 0);
info->fbops->fb_blank(VESA_NO_BLANKING, info);
+fail:
release_console_sem();
return 0;
}
diff --git a/drivers/video/intelfb/Makefile b/drivers/video/intelfb/Makefile
index 722d21d6e5cd..6c782d3ae1be 100644
--- a/drivers/video/intelfb/Makefile
+++ b/drivers/video/intelfb/Makefile
@@ -1,6 +1,8 @@
obj-$(CONFIG_FB_INTEL) += intelfb.o
-intelfb-objs := intelfbdrv.o intelfbhw.o
+intelfb-y := intelfbdrv.o intelfbhw.o
+intelfb-$(CONFIG_FB_INTEL_I2C) += intelfb_i2c.o
+intelfb-objs := $(intelfb-y)
ifdef CONFIG_FB_INTEL_DEBUG
#EXTRA_CFLAGS += -DDEBUG -DVERBOSE -DREGDUMP
diff --git a/drivers/video/intelfb/intelfb.h b/drivers/video/intelfb/intelfb.h
index e290d7460e1b..80b94c19a9fa 100644
--- a/drivers/video/intelfb/intelfb.h
+++ b/drivers/video/intelfb/intelfb.h
@@ -6,6 +6,10 @@
#include <linux/agp_backend.h>
#include <linux/fb.h>
+#ifdef CONFIG_FB_INTEL_I2C
+#include <linux/i2c.h>
+#include <linux/i2c-algo-bit.h>
+#endif
/*** Version/name ***/
#define INTELFB_VERSION "0.9.4"
@@ -115,6 +119,29 @@
/* Intel agpgart driver */
#define AGP_PHYSICAL_MEMORY 2
+/* store information about an Ixxx DVO */
+/* The i830->i865 use multiple DVOs with multiple i2cs */
+/* the i915, i945 have a single sDVO i2c bus - which is different */
+#define MAX_OUTPUTS 6
+
+/* these are outputs from the chip - integrated only
+ external chips are via DVO or SDVO output */
+#define INTELFB_OUTPUT_UNUSED 0
+#define INTELFB_OUTPUT_ANALOG 1
+#define INTELFB_OUTPUT_DVO 2
+#define INTELFB_OUTPUT_SDVO 3
+#define INTELFB_OUTPUT_LVDS 4
+#define INTELFB_OUTPUT_TVOUT 5
+
+#define INTELFB_DVO_CHIP_NONE 0
+#define INTELFB_DVO_CHIP_LVDS 1
+#define INTELFB_DVO_CHIP_TMDS 2
+#define INTELFB_DVO_CHIP_TVOUT 4
+
+#define INTELFB_OUTPUT_PIPE_NC 0
+#define INTELFB_OUTPUT_PIPE_A 1
+#define INTELFB_OUTPUT_PIPE_B 2
+
/*** Data Types ***/
/* supported chipsets */
@@ -195,6 +222,10 @@ struct intelfb_hwstate {
u32 mem_mode;
u32 fw_blc_0;
u32 fw_blc_1;
+ u16 hwstam;
+ u16 ier;
+ u16 iir;
+ u16 imr;
};
struct intelfb_heap_data {
@@ -204,6 +235,33 @@ struct intelfb_heap_data {
u32 size; // in bytes
};
+#ifdef CONFIG_FB_INTEL_I2C
+struct intelfb_i2c_chan {
+ struct intelfb_info *dinfo;
+ u32 reg;
+ struct i2c_adapter adapter;
+ struct i2c_algo_bit_data algo;
+};
+#endif
+
+struct intelfb_output_rec {
+ int type;
+ int pipe;
+ int flags;
+
+#ifdef CONFIG_FB_INTEL_I2C
+ struct intelfb_i2c_chan i2c_bus;
+ struct intelfb_i2c_chan ddc_bus;
+#endif
+};
+
+struct intelfb_vsync {
+ wait_queue_head_t wait;
+ unsigned int count;
+ int pan_display;
+ u32 pan_offset;
+};
+
struct intelfb_info {
struct fb_info *info;
struct fb_ops *fbops;
@@ -220,7 +278,7 @@ struct intelfb_info {
u8 fbmem_gart;
/* mtrr support */
- u32 mtrr_reg;
+ int mtrr_reg;
u32 has_mtrr;
/* heap data */
@@ -267,6 +325,12 @@ struct intelfb_info {
int fixed_mode;
int ring_active;
int flag;
+ unsigned long irq_flags;
+ int open;
+
+ /* vsync */
+ struct intelfb_vsync vsync;
+ spinlock_t int_lock;
/* hw cursor */
int cursor_on;
@@ -285,12 +349,25 @@ struct intelfb_info {
/* index into plls */
int pll_index;
+
+ /* outputs */
+ int num_outputs;
+ struct intelfb_output_rec output[MAX_OUTPUTS];
};
#define IS_I9XX(dinfo) (((dinfo)->chipset == INTEL_915G)||(dinfo->chipset == INTEL_915GM)||((dinfo)->chipset == INTEL_945G)||(dinfo->chipset==INTEL_945GM))
+#ifndef FBIO_WAITFORVSYNC
+#define FBIO_WAITFORVSYNC _IOW('F', 0x20, __u32)
+#endif
+
/*** function prototypes ***/
extern int intelfb_var_to_depth(const struct fb_var_screeninfo *var);
+#ifdef CONFIG_FB_INTEL_I2C
+extern void intelfb_create_i2c_busses(struct intelfb_info *dinfo);
+extern void intelfb_delete_i2c_busses(struct intelfb_info *dinfo);
+#endif
+
#endif /* _INTELFB_H */
diff --git a/drivers/video/intelfb/intelfb_i2c.c b/drivers/video/intelfb/intelfb_i2c.c
new file mode 100644
index 000000000000..c1113d6e941d
--- /dev/null
+++ b/drivers/video/intelfb/intelfb_i2c.c
@@ -0,0 +1,200 @@
+/**************************************************************************
+
+ Copyright 2006 Dave Airlie <airlied@linux.ie>
+
+All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+on the rights to use, copy, modify, merge, publish, distribute, sub
+license, and/or sell copies of the Software, and to permit persons to whom
+the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice (including the next
+paragraph) shall be included in all copies or substantial portions of the
+Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+THE COPYRIGHT HOLDERS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
+DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/delay.h>
+#include <linux/pci.h>
+#include <linux/fb.h>
+
+#include <linux/i2c.h>
+#include <linux/i2c-id.h>
+#include <linux/i2c-algo-bit.h>
+
+#include <asm/io.h>
+
+#include "intelfb.h"
+#include "intelfbhw.h"
+
+/* bit locations in the registers */
+#define SCL_DIR_MASK 0x0001
+#define SCL_DIR 0x0002
+#define SCL_VAL_MASK 0x0004
+#define SCL_VAL_OUT 0x0008
+#define SCL_VAL_IN 0x0010
+#define SDA_DIR_MASK 0x0100
+#define SDA_DIR 0x0200
+#define SDA_VAL_MASK 0x0400
+#define SDA_VAL_OUT 0x0800
+#define SDA_VAL_IN 0x1000
+
+static void intelfb_gpio_setscl(void *data, int state)
+{
+ struct intelfb_i2c_chan *chan = data;
+ struct intelfb_info *dinfo = chan->dinfo;
+ u32 val;
+
+ OUTREG(chan->reg, (state ? SCL_VAL_OUT : 0) | SCL_DIR | SCL_DIR_MASK | SCL_VAL_MASK);
+ val = INREG(chan->reg);
+}
+
+static void intelfb_gpio_setsda(void *data, int state)
+{
+ struct intelfb_i2c_chan *chan = data;
+ struct intelfb_info *dinfo = chan->dinfo;
+ u32 val;
+
+ OUTREG(chan->reg, (state ? SDA_VAL_OUT : 0) | SDA_DIR | SDA_DIR_MASK | SDA_VAL_MASK);
+ val = INREG(chan->reg);
+}
+
+static int intelfb_gpio_getscl(void *data)
+{
+ struct intelfb_i2c_chan *chan = data;
+ struct intelfb_info *dinfo = chan->dinfo;
+ u32 val;
+
+ OUTREG(chan->reg, SCL_DIR_MASK);
+ OUTREG(chan->reg, 0);
+ val = INREG(chan->reg);
+ return ((val & SCL_VAL_IN) != 0);
+}
+
+static int intelfb_gpio_getsda(void *data)
+{
+ struct intelfb_i2c_chan *chan = data;
+ struct intelfb_info *dinfo = chan->dinfo;
+ u32 val;
+
+ OUTREG(chan->reg, SDA_DIR_MASK);
+ OUTREG(chan->reg, 0);
+ val = INREG(chan->reg);
+ return ((val & SDA_VAL_IN) != 0);
+}
+
+static int intelfb_setup_i2c_bus(struct intelfb_info *dinfo,
+ struct intelfb_i2c_chan *chan,
+ const u32 reg, const char *name)
+{
+ int rc;
+
+ chan->dinfo = dinfo;
+ chan->reg = reg;
+ snprintf(chan->adapter.name, I2C_NAME_SIZE, "intelfb %s", name);
+ chan->adapter.owner = THIS_MODULE;
+ chan->adapter.id = I2C_HW_B_INTELFB;
+ chan->adapter.algo_data = &chan->algo;
+ chan->adapter.dev.parent = &chan->dinfo->pdev->dev;
+ chan->algo.setsda = intelfb_gpio_setsda;
+ chan->algo.setscl = intelfb_gpio_setscl;
+ chan->algo.getsda = intelfb_gpio_getsda;
+ chan->algo.getscl = intelfb_gpio_getscl;
+ chan->algo.udelay = 40;
+ chan->algo.timeout = 20;
+ chan->algo.data = chan;
+
+ i2c_set_adapdata(&chan->adapter, chan);
+
+ /* Raise SCL and SDA */
+ intelfb_gpio_setsda(chan, 1);
+ intelfb_gpio_setscl(chan, 1);
+ udelay(20);
+
+ rc = i2c_bit_add_bus(&chan->adapter);
+ if (rc == 0)
+ DBG_MSG("I2C bus %s registered.\n", name);
+ else
+ WRN_MSG("Failed to register I2C bus %s.\n", name);
+ return rc;
+}
+
+void intelfb_create_i2c_busses(struct intelfb_info *dinfo)
+{
+ int i = 0;
+
+ /* everyone has at least a single analog output */
+ dinfo->num_outputs = 1;
+ dinfo->output[i].type = INTELFB_OUTPUT_ANALOG;
+
+ /* setup the DDC bus for analog output */
+ intelfb_setup_i2c_bus(dinfo, &dinfo->output[i].ddc_bus, GPIOA, "CRTDDC_A");
+ i++;
+
+ /* need to add the output busses for each device
+ - this function is very incomplete
+ - i915GM has LVDS and TVOUT for example
+ */
+ switch(dinfo->chipset) {
+ case INTEL_830M:
+ case INTEL_845G:
+ case INTEL_855GM:
+ case INTEL_865G:
+ dinfo->output[i].type = INTELFB_OUTPUT_DVO;
+ intelfb_setup_i2c_bus(dinfo, &dinfo->output[i].ddc_bus, GPIOD, "DVODDC_D");
+ intelfb_setup_i2c_bus(dinfo, &dinfo->output[i].i2c_bus, GPIOE, "DVOI2C_E");
+ i++;
+ break;
+ case INTEL_915G:
+ case INTEL_915GM:
+ /* has some LVDS + tv-out */
+ case INTEL_945G:
+ case INTEL_945GM:
+ /* SDVO ports have a single control bus - 2 devices */
+ dinfo->output[i].type = INTELFB_OUTPUT_SDVO;
+ intelfb_setup_i2c_bus(dinfo, &dinfo->output[i].i2c_bus, GPIOE, "SDVOCTRL_E");
+ /* TODO: initialize the SDVO */
+// I830SDVOInit(pScrn, i, DVOB);
+ i++;
+
+ /* set up SDVOC */
+ dinfo->output[i].type = INTELFB_OUTPUT_SDVO;
+ dinfo->output[i].i2c_bus = dinfo->output[i - 1].i2c_bus;
+ /* TODO: initialize the SDVO */
+// I830SDVOInit(pScrn, i, DVOC);
+ i++;
+ break;
+ }
+ dinfo->num_outputs = i;
+}
+
+void intelfb_delete_i2c_busses(struct intelfb_info *dinfo)
+{
+ int i;
+
+ for (i = 0; i < MAX_OUTPUTS; i++) {
+ if (dinfo->output[i].i2c_bus.dinfo) {
+ i2c_bit_del_bus(&dinfo->output[i].i2c_bus.adapter);
+ dinfo->output[i].i2c_bus.dinfo = NULL;
+ }
+ if (dinfo->output[i].ddc_bus.dinfo) {
+ i2c_bit_del_bus(&dinfo->output[i].ddc_bus.adapter);
+ dinfo->output[i].ddc_bus.dinfo = NULL;
+ }
+ }
+}
diff --git a/drivers/video/intelfb/intelfbdrv.c b/drivers/video/intelfb/intelfbdrv.c
index 06af89d44a0d..6f9de04193d2 100644
--- a/drivers/video/intelfb/intelfbdrv.c
+++ b/drivers/video/intelfb/intelfbdrv.c
@@ -136,6 +136,8 @@
static void __devinit get_initial_mode(struct intelfb_info *dinfo);
static void update_dinfo(struct intelfb_info *dinfo,
struct fb_var_screeninfo *var);
+static int intelfb_open(struct fb_info *info, int user);
+static int intelfb_release(struct fb_info *info, int user);
static int intelfb_check_var(struct fb_var_screeninfo *var,
struct fb_info *info);
static int intelfb_set_par(struct fb_info *info);
@@ -194,6 +196,8 @@ static int num_registered = 0;
/* fb ops */
static struct fb_ops intel_fb_ops = {
.owner = THIS_MODULE,
+ .fb_open = intelfb_open,
+ .fb_release = intelfb_release,
.fb_check_var = intelfb_check_var,
.fb_set_par = intelfb_set_par,
.fb_setcolreg = intelfb_setcolreg,
@@ -446,6 +450,8 @@ cleanup(struct intelfb_info *dinfo)
if (!dinfo)
return;
+ intelfbhw_disable_irq(dinfo);
+
fb_dealloc_cmap(&dinfo->info->cmap);
kfree(dinfo->info->pixmap.addr);
@@ -467,6 +473,11 @@ cleanup(struct intelfb_info *dinfo)
agp_free_memory(dinfo->gtt_ring_mem);
}
+#ifdef CONFIG_FB_INTEL_I2C
+ /* un-register I2C bus */
+ intelfb_delete_i2c_busses(dinfo);
+#endif
+
if (dinfo->mmio_base)
iounmap((void __iomem *)dinfo->mmio_base);
if (dinfo->aperture.virtual)
@@ -844,6 +855,11 @@ intelfb_pci_register(struct pci_dev *pdev, const struct pci_device_id *ent)
if (bailearly == 5)
bailout(dinfo);
+#ifdef CONFIG_FB_INTEL_I2C
+ /* register I2C bus */
+ intelfb_create_i2c_busses(dinfo);
+#endif
+
if (bailearly == 6)
bailout(dinfo);
@@ -888,6 +904,13 @@ intelfb_pci_register(struct pci_dev *pdev, const struct pci_device_id *ent)
}
dinfo->registered = 1;
+ dinfo->open = 0;
+
+ init_waitqueue_head(&dinfo->vsync.wait);
+ spin_lock_init(&dinfo->int_lock);
+ dinfo->irq_flags = 0;
+ dinfo->vsync.pan_display = 0;
+ dinfo->vsync.pan_offset = 0;
return 0;
@@ -1188,6 +1211,34 @@ update_dinfo(struct intelfb_info *dinfo, struct fb_var_screeninfo *var)
***************************************************************/
static int
+intelfb_open(struct fb_info *info, int user)
+{
+ struct intelfb_info *dinfo = GET_DINFO(info);
+
+ if (user) {
+ dinfo->open++;
+ }
+
+ return 0;
+}
+
+static int
+intelfb_release(struct fb_info *info, int user)
+{
+ struct intelfb_info *dinfo = GET_DINFO(info);
+
+ if (user) {
+ dinfo->open--;
+ msleep(1);
+ if (!dinfo->open) {
+ intelfbhw_disable_irq(dinfo);
+ }
+ }
+
+ return 0;
+}
+
+static int
intelfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
{
int change_var = 0;
@@ -1433,6 +1484,19 @@ static int
intelfb_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg)
{
int retval = 0;
+ struct intelfb_info *dinfo = GET_DINFO(info);
+ u32 pipe = 0;
+
+ switch (cmd) {
+ case FBIO_WAITFORVSYNC:
+ if (get_user(pipe, (__u32 __user *)arg))
+ return -EFAULT;
+
+ retval = intelfbhw_wait_for_vsync(dinfo, pipe);
+ break;
+ default:
+ break;
+ }
return retval;
}
diff --git a/drivers/video/intelfb/intelfbhw.c b/drivers/video/intelfb/intelfbhw.c
index 2a9322f9cfdc..f887f1efd3fe 100644
--- a/drivers/video/intelfb/intelfbhw.c
+++ b/drivers/video/intelfb/intelfbhw.c
@@ -32,6 +32,7 @@
#include <linux/pci.h>
#include <linux/vmalloc.h>
#include <linux/pagemap.h>
+#include <linux/interrupt.h>
#include <asm/io.h>
@@ -368,7 +369,13 @@ intelfbhw_pan_display(struct fb_var_screeninfo *var, struct fb_info *info)
offset += dinfo->fb.offset << 12;
- OUTREG(DSPABASE, offset);
+ dinfo->vsync.pan_offset = offset;
+ if ((var->activate & FB_ACTIVATE_VBL) && !intelfbhw_enable_irq(dinfo, 0)) {
+ dinfo->vsync.pan_display = 1;
+ } else {
+ dinfo->vsync.pan_display = 0;
+ OUTREG(DSPABASE, offset);
+ }
return 0;
}
@@ -585,6 +592,11 @@ intelfbhw_read_hw_state(struct intelfb_info *dinfo, struct intelfb_hwstate *hw,
hw->fw_blc_0 = INREG(FW_BLC_0);
hw->fw_blc_1 = INREG(FW_BLC_1);
+ hw->hwstam = INREG16(HWSTAM);
+ hw->ier = INREG16(IER);
+ hw->iir = INREG16(IIR);
+ hw->imr = INREG16(IMR);
+
return 0;
}
@@ -613,6 +625,7 @@ static int calc_vclock(int index, int m1, int m2, int n, int p1, int p2, int lvd
return vco / p;
}
+#if REGDUMP
static void
intelfbhw_get_p1p2(struct intelfb_info *dinfo, int dpll, int *o_p1, int *o_p2)
{
@@ -638,6 +651,7 @@ intelfbhw_get_p1p2(struct intelfb_info *dinfo, int dpll, int *o_p1, int *o_p2)
*o_p1 = p1;
*o_p2 = p2;
}
+#endif
void
@@ -794,6 +808,10 @@ intelfbhw_print_hw_state(struct intelfb_info *dinfo, struct intelfb_hwstate *hw)
printk(" FW_BLC_0 0x%08x\n", hw->fw_blc_0);
printk(" FW_BLC_1 0x%08x\n", hw->fw_blc_1);
+ printk(" HWSTAM 0x%04x\n", hw->hwstam);
+ printk(" IER 0x%04x\n", hw->ier);
+ printk(" IIR 0x%04x\n", hw->iir);
+ printk(" IMR 0x%04x\n", hw->imr);
printk("hw state dump end\n");
#endif
}
@@ -1932,3 +1950,119 @@ intelfbhw_cursor_reset(struct intelfb_info *dinfo) {
addr += 16;
}
}
+
+static irqreturn_t
+intelfbhw_irq(int irq, void *dev_id, struct pt_regs *fp) {
+ int handled = 0;
+ u16 tmp;
+ struct intelfb_info *dinfo = (struct intelfb_info *)dev_id;
+
+ spin_lock(&dinfo->int_lock);
+
+ tmp = INREG16(IIR);
+ tmp &= VSYNC_PIPE_A_INTERRUPT;
+
+ if (tmp == 0) {
+ spin_unlock(&dinfo->int_lock);
+ return IRQ_RETVAL(handled);
+ }
+
+ OUTREG16(IIR, tmp);
+
+ if (tmp & VSYNC_PIPE_A_INTERRUPT) {
+ dinfo->vsync.count++;
+ if (dinfo->vsync.pan_display) {
+ dinfo->vsync.pan_display = 0;
+ OUTREG(DSPABASE, dinfo->vsync.pan_offset);
+ }
+ wake_up_interruptible(&dinfo->vsync.wait);
+ handled = 1;
+ }
+
+ spin_unlock(&dinfo->int_lock);
+
+ return IRQ_RETVAL(handled);
+}
+
+int
+intelfbhw_enable_irq(struct intelfb_info *dinfo, int reenable) {
+
+ if (!test_and_set_bit(0, &dinfo->irq_flags)) {
+ if (request_irq(dinfo->pdev->irq, intelfbhw_irq, SA_SHIRQ, "intelfb", dinfo)) {
+ clear_bit(0, &dinfo->irq_flags);
+ return -EINVAL;
+ }
+
+ spin_lock_irq(&dinfo->int_lock);
+ OUTREG16(HWSTAM, 0xfffe);
+ OUTREG16(IMR, 0x0);
+ OUTREG16(IER, VSYNC_PIPE_A_INTERRUPT);
+ spin_unlock_irq(&dinfo->int_lock);
+ } else if (reenable) {
+ u16 ier;
+
+ spin_lock_irq(&dinfo->int_lock);
+ ier = INREG16(IER);
+ if ((ier & VSYNC_PIPE_A_INTERRUPT)) {
+ DBG_MSG("someone disabled the IRQ [%08X]\n", ier);
+ OUTREG(IER, VSYNC_PIPE_A_INTERRUPT);
+ }
+ spin_unlock_irq(&dinfo->int_lock);
+ }
+ return 0;
+}
+
+void
+intelfbhw_disable_irq(struct intelfb_info *dinfo) {
+ u16 tmp;
+
+ if (test_and_clear_bit(0, &dinfo->irq_flags)) {
+ if (dinfo->vsync.pan_display) {
+ dinfo->vsync.pan_display = 0;
+ OUTREG(DSPABASE, dinfo->vsync.pan_offset);
+ }
+ spin_lock_irq(&dinfo->int_lock);
+ OUTREG16(HWSTAM, 0xffff);
+ OUTREG16(IMR, 0xffff);
+ OUTREG16(IER, 0x0);
+
+ tmp = INREG16(IIR);
+ OUTREG16(IIR, tmp);
+ spin_unlock_irq(&dinfo->int_lock);
+
+ free_irq(dinfo->pdev->irq, dinfo);
+ }
+}
+
+int
+intelfbhw_wait_for_vsync(struct intelfb_info *dinfo, u32 pipe) {
+ struct intelfb_vsync *vsync;
+ unsigned int count;
+ int ret;
+
+ switch (pipe) {
+ case 0:
+ vsync = &dinfo->vsync;
+ break;
+ default:
+ return -ENODEV;
+ }
+
+ ret = intelfbhw_enable_irq(dinfo, 0);
+ if (ret) {
+ return ret;
+ }
+
+ count = vsync->count;
+ ret = wait_event_interruptible_timeout(vsync->wait, count != vsync->count, HZ/10);
+ if (ret < 0) {
+ return ret;
+ }
+ if (ret == 0) {
+ intelfbhw_enable_irq(dinfo, 1);
+ DBG_MSG("wait_for_vsync timed out!\n");
+ return -ETIMEDOUT;
+ }
+
+ return 0;
+}
diff --git a/drivers/video/intelfb/intelfbhw.h b/drivers/video/intelfb/intelfbhw.h
index 10acda098b71..8c54ba8fbdda 100644
--- a/drivers/video/intelfb/intelfbhw.h
+++ b/drivers/video/intelfb/intelfbhw.h
@@ -88,6 +88,19 @@
#define INSTDONE 0x2090
#define PRI_RING_EMPTY 1
+#define HWSTAM 0x2098
+#define IER 0x20A0
+#define IIR 0x20A4
+#define IMR 0x20A8
+#define VSYNC_PIPE_A_INTERRUPT (1 << 7)
+#define PIPE_A_EVENT_INTERRUPT (1 << 4)
+#define VSYNC_PIPE_B_INTERRUPT (1 << 5)
+#define PIPE_B_EVENT_INTERRUPT (1 << 4)
+#define HOST_PORT_EVENT_INTERRUPT (1 << 3)
+#define CAPTURE_EVENT_INTERRUPT (1 << 2)
+#define USER_DEFINED_INTERRUPT (1 << 1)
+#define BREAKPOINT_INTERRUPT 1
+
#define INSTPM 0x20c0
#define SYNC_FLUSH_ENABLE (1 << 5)
@@ -113,6 +126,12 @@
#define FW_DISPC_BL_SHIFT 8
#define FW_DISPC_BL_MASK 0x7
+#define GPIOA 0x5010
+#define GPIOB 0x5014
+#define GPIOC 0x5018 // this may be external DDC on i830
+#define GPIOD 0x501C // this is DVO DDC
+#define GPIOE 0x5020 // this is DVO i2C
+#define GPIOF 0x5024
/* PLL registers */
#define VGA0_DIVISOR 0x06000
@@ -468,9 +487,12 @@
/* I/O macros */
#define INREG8(addr) readb((u8 __iomem *)(dinfo->mmio_base + (addr)))
+#define INREG16(addr) readw((u16 __iomem *)(dinfo->mmio_base + (addr)))
#define INREG(addr) readl((u32 __iomem *)(dinfo->mmio_base + (addr)))
#define OUTREG8(addr, val) writeb((val),(u8 __iomem *)(dinfo->mmio_base + \
(addr)))
+#define OUTREG16(addr, val) writew((val),(u16 __iomem *)(dinfo->mmio_base + \
+ (addr)))
#define OUTREG(addr, val) writel((val),(u32 __iomem *)(dinfo->mmio_base + \
(addr)))
@@ -545,5 +567,8 @@ extern void intelfbhw_cursor_setcolor(struct intelfb_info *dinfo, u32 bg,
extern void intelfbhw_cursor_load(struct intelfb_info *dinfo, int width,
int height, u8 *data);
extern void intelfbhw_cursor_reset(struct intelfb_info *dinfo);
+extern int intelfbhw_enable_irq(struct intelfb_info *dinfo, int reenable);
+extern void intelfbhw_disable_irq(struct intelfb_info *dinfo);
+extern int intelfbhw_wait_for_vsync(struct intelfb_info *dinfo, u32 pipe);
#endif /* _INTELFBHW_H */
diff --git a/drivers/video/matrox/matroxfb_base.c b/drivers/video/matrox/matroxfb_base.c
index 4a57dabb77d4..7acf01c181ee 100644
--- a/drivers/video/matrox/matroxfb_base.c
+++ b/drivers/video/matrox/matroxfb_base.c
@@ -2277,10 +2277,13 @@ static void __init matroxfb_init_params(void) {
}
}
-static void __init matrox_init(void) {
+static int __init matrox_init(void) {
+ int err;
+
matroxfb_init_params();
- pci_register_driver(&matroxfb_driver);
+ err = pci_register_driver(&matroxfb_driver);
dev = -1; /* accept all new devices... */
+ return err;
}
/* **************************** exit-time only **************************** */
@@ -2437,6 +2440,7 @@ static int __initdata initialized = 0;
static int __init matroxfb_init(void)
{
char *option = NULL;
+ int err = 0;
DBG(__FUNCTION__)
@@ -2448,11 +2452,11 @@ static int __init matroxfb_init(void)
return -ENXIO;
if (!initialized) {
initialized = 1;
- matrox_init();
+ err = matrox_init();
}
hotplug = 1;
/* never return failure, user can hotplug matrox later... */
- return 0;
+ return err;
}
module_init(matroxfb_init);
diff --git a/drivers/video/mbx/mbxfb.c b/drivers/video/mbx/mbxfb.c
index 6849ab75d403..a32d1af79e07 100644
--- a/drivers/video/mbx/mbxfb.c
+++ b/drivers/video/mbx/mbxfb.c
@@ -118,8 +118,19 @@ static unsigned int mbxfb_get_pixclock(unsigned int pixclock_ps,
/* convert pixclock to KHz */
pixclock = PICOS2KHZ(pixclock_ps);
+ /* PLL output freq = (ref_clk * M) / (N * 2^P)
+ *
+ * M: 1 to 63
+ * N: 1 to 7
+ * P: 0 to 7
+ */
+
+ /* RAPH: When N==1, the resulting pixel clock appears to
+ * get divided by 2. Preventing N=1 by starting the following
+ * loop at 2 prevents this. Is this a bug with my chip
+ * revision or something I dont understand? */
for (m = 1; m < 64; m++) {
- for (n = 1; n < 8; n++) {
+ for (n = 2; n < 8; n++) {
for (p = 0; p < 8; p++) {
clk = (ref_clk * m) / (n * (1 << p));
err = (clk > pixclock) ? (clk - pixclock) :
@@ -244,8 +255,8 @@ static int mbxfb_set_par(struct fb_info *info)
/* setup resolution */
gsctrl &= ~(FMsk(GSCTRL_GSWIDTH) | FMsk(GSCTRL_GSHEIGHT));
- gsctrl |= Gsctrl_Width(info->var.xres - 1) |
- Gsctrl_Height(info->var.yres - 1);
+ gsctrl |= Gsctrl_Width(info->var.xres) |
+ Gsctrl_Height(info->var.yres);
writel(gsctrl, GSCTRL);
udelay(1000);
@@ -402,8 +413,8 @@ static void __devinit setup_graphics(struct fb_info *fbi)
{
unsigned long gsctrl;
- gsctrl = GSCTRL_GAMMA_EN | Gsctrl_Width(fbi->var.xres - 1) |
- Gsctrl_Height(fbi->var.yres - 1);
+ gsctrl = GSCTRL_GAMMA_EN | Gsctrl_Width(fbi->var.xres) |
+ Gsctrl_Height(fbi->var.yres);
switch (fbi->var.bits_per_pixel) {
case 16:
if (fbi->var.green.length == 5)
diff --git a/drivers/video/nvidia/nv_i2c.c b/drivers/video/nvidia/nv_i2c.c
index 19eef3a09023..e48de3c9fd13 100644
--- a/drivers/video/nvidia/nv_i2c.c
+++ b/drivers/video/nvidia/nv_i2c.c
@@ -160,51 +160,12 @@ void nvidia_delete_i2c_busses(struct nvidia_par *par)
}
-static u8 *nvidia_do_probe_i2c_edid(struct nvidia_i2c_chan *chan)
-{
- u8 start = 0x0;
- struct i2c_msg msgs[] = {
- {
- .addr = 0x50,
- .len = 1,
- .buf = &start,
- }, {
- .addr = 0x50,
- .flags = I2C_M_RD,
- .len = EDID_LENGTH,
- },
- };
- u8 *buf;
-
- if (!chan->par)
- return NULL;
-
- buf = kmalloc(EDID_LENGTH, GFP_KERNEL);
- if (!buf) {
- dev_warn(&chan->par->pci_dev->dev, "Out of memory!\n");
- return NULL;
- }
- msgs[1].buf = buf;
-
- if (i2c_transfer(&chan->adapter, msgs, 2) == 2)
- return buf;
- dev_dbg(&chan->par->pci_dev->dev, "Unable to read EDID block.\n");
- kfree(buf);
- return NULL;
-}
-
int nvidia_probe_i2c_connector(struct fb_info *info, int conn, u8 **out_edid)
{
struct nvidia_par *par = info->par;
- u8 *edid = NULL;
- int i;
-
- for (i = 0; i < 3; i++) {
- /* Do the real work */
- edid = nvidia_do_probe_i2c_edid(&par->chan[conn - 1]);
- if (edid)
- break;
- }
+ u8 *edid;
+
+ edid = fb_ddc_read(&par->chan[conn - 1].adapter);
if (!edid && conn == 1) {
/* try to get from firmware */
diff --git a/drivers/video/nvidia/nvidia.c b/drivers/video/nvidia/nvidia.c
index f8cd4c519aeb..eb24107bcc81 100644
--- a/drivers/video/nvidia/nvidia.c
+++ b/drivers/video/nvidia/nvidia.c
@@ -28,6 +28,9 @@
#include <asm/prom.h>
#include <asm/pci-bridge.h>
#endif
+#ifdef CONFIG_BOOTX_TEXT
+#include <asm/btext.h>
+#endif
#include "nv_local.h"
#include "nv_type.h"
@@ -681,6 +684,13 @@ static int nvidiafb_set_par(struct fb_info *info)
nvidia_vga_protect(par, 0);
+#ifdef CONFIG_BOOTX_TEXT
+ /* Update debug text engine */
+ btext_update_display(info->fix.smem_start,
+ info->var.xres, info->var.yres,
+ info->var.bits_per_pixel, info->fix.line_length);
+#endif
+
NVTRACE_LEAVE();
return 0;
}
@@ -984,7 +994,10 @@ static int nvidiafb_resume(struct pci_dev *dev)
if (par->pm_state != PM_EVENT_FREEZE) {
pci_restore_state(dev);
- pci_enable_device(dev);
+
+ if (pci_enable_device(dev))
+ goto fail;
+
pci_set_master(dev);
}
@@ -993,6 +1006,7 @@ static int nvidiafb_resume(struct pci_dev *dev)
fb_set_suspend (info, 0);
nvidiafb_blank(FB_BLANK_UNBLANK, info);
+fail:
release_console_sem();
return 0;
}
diff --git a/drivers/video/riva/fbdev.c b/drivers/video/riva/fbdev.c
index 4acde4f7dbf8..b120896c8ab4 100644
--- a/drivers/video/riva/fbdev.c
+++ b/drivers/video/riva/fbdev.c
@@ -393,8 +393,8 @@ static void riva_bl_init(struct riva_par *par)
mutex_lock(&info->bl_mutex);
info->bl_dev = bd;
fb_bl_default_curve(info, 0,
- 0x158 * FB_BACKLIGHT_MAX / MAX_LEVEL,
- 0x534 * FB_BACKLIGHT_MAX / MAX_LEVEL);
+ MIN_LEVEL * FB_BACKLIGHT_MAX / MAX_LEVEL,
+ FB_BACKLIGHT_MAX);
mutex_unlock(&info->bl_mutex);
down(&bd->sem);
@@ -784,7 +784,7 @@ static void riva_load_video_mode(struct fb_info *info)
NVTRACE_ENTER();
/* time to calculate */
- rivafb_blank(1, info);
+ rivafb_blank(FB_BLANK_NORMAL, info);
bpp = info->var.bits_per_pixel;
if (bpp == 16 && info->var.green.length == 5)
@@ -917,7 +917,7 @@ static void riva_load_video_mode(struct fb_info *info)
par->current_state = newmode;
riva_load_state(par, &par->current_state);
par->riva.LockUnlock(&par->riva, 0); /* important for HW cursor */
- rivafb_blank(0, info);
+ rivafb_blank(FB_BLANK_UNBLANK, info);
NVTRACE_LEAVE();
}
diff --git a/drivers/video/riva/rivafb-i2c.c b/drivers/video/riva/rivafb-i2c.c
index 9751c37c0bfd..c15b259af644 100644
--- a/drivers/video/riva/rivafb-i2c.c
+++ b/drivers/video/riva/rivafb-i2c.c
@@ -25,8 +25,6 @@
#include "rivafb.h"
#include "../edid.h"
-#define RIVA_DDC 0x50
-
static void riva_gpio_setscl(void* data, int state)
{
struct riva_i2c_chan *chan = data;
@@ -158,50 +156,12 @@ void riva_delete_i2c_busses(struct riva_par *par)
par->chan[2].par = NULL;
}
-static u8 *riva_do_probe_i2c_edid(struct riva_i2c_chan *chan)
-{
- u8 start = 0x0;
- struct i2c_msg msgs[] = {
- {
- .addr = RIVA_DDC,
- .len = 1,
- .buf = &start,
- }, {
- .addr = RIVA_DDC,
- .flags = I2C_M_RD,
- .len = EDID_LENGTH,
- },
- };
- u8 *buf;
-
- if (!chan->par)
- return NULL;
-
- buf = kmalloc(EDID_LENGTH, GFP_KERNEL);
- if (!buf) {
- dev_warn(&chan->par->pdev->dev, "Out of memory!\n");
- return NULL;
- }
- msgs[1].buf = buf;
-
- if (i2c_transfer(&chan->adapter, msgs, 2) == 2)
- return buf;
- dev_dbg(&chan->par->pdev->dev, "Unable to read EDID block.\n");
- kfree(buf);
- return NULL;
-}
-
int riva_probe_i2c_connector(struct riva_par *par, int conn, u8 **out_edid)
{
u8 *edid = NULL;
- int i;
- for (i = 0; i < 3; i++) {
- /* Do the real work */
- edid = riva_do_probe_i2c_edid(&par->chan[conn-1]);
- if (edid)
- break;
- }
+ edid = fb_ddc_read(&par->chan[conn-1].adapter);
+
if (out_edid)
*out_edid = edid;
if (!edid)
diff --git a/drivers/video/savage/savagefb-i2c.c b/drivers/video/savage/savagefb-i2c.c
index d7d810dbf0bd..3f94223b7f0c 100644
--- a/drivers/video/savage/savagefb-i2c.c
+++ b/drivers/video/savage/savagefb-i2c.c
@@ -213,52 +213,15 @@ void savagefb_delete_i2c_busses(struct fb_info *info)
par->chan.par = NULL;
}
-static u8 *savage_do_probe_i2c_edid(struct savagefb_i2c_chan *chan)
-{
- u8 start = 0x0;
- struct i2c_msg msgs[] = {
- {
- .addr = SAVAGE_DDC,
- .len = 1,
- .buf = &start,
- }, {
- .addr = SAVAGE_DDC,
- .flags = I2C_M_RD,
- .len = EDID_LENGTH,
- },
- };
- u8 *buf = NULL;
-
- if (chan->par) {
- buf = kmalloc(EDID_LENGTH, GFP_KERNEL);
-
- if (buf) {
- msgs[1].buf = buf;
-
- if (i2c_transfer(&chan->adapter, msgs, 2) != 2) {
- dev_dbg(&chan->par->pcidev->dev,
- "Unable to read EDID block.\n");
- kfree(buf);
- buf = NULL;
- }
- }
- }
-
- return buf;
-}
-
int savagefb_probe_i2c_connector(struct fb_info *info, u8 **out_edid)
{
struct savagefb_par *par = info->par;
- u8 *edid = NULL;
- int i;
-
- for (i = 0; i < 3; i++) {
- /* Do the real work */
- edid = savage_do_probe_i2c_edid(&par->chan);
- if (edid)
- break;
- }
+ u8 *edid;
+
+ if (par->chan.par)
+ edid = fb_ddc_read(&par->chan.adapter);
+ else
+ edid = NULL;
if (!edid) {
/* try to get from firmware */
diff --git a/drivers/video/sis/init.h b/drivers/video/sis/init.h
index 7ecab87cef02..59d12844b4dd 100644
--- a/drivers/video/sis/init.h
+++ b/drivers/video/sis/init.h
@@ -77,16 +77,9 @@
#include <linux/types.h>
#include <asm/io.h>
#include <linux/fb.h>
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-#include <video/fbcon.h>
-#endif
#include "sis.h"
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-#include <linux/sisfb.h>
-#else
#include <video/sisfb.h>
#endif
-#endif
/* Mode numbers */
static const unsigned short ModeIndex_320x200[] = {0x59, 0x41, 0x00, 0x4f};
diff --git a/drivers/video/sis/init301.h b/drivers/video/sis/init301.h
index bc321dc57e92..4f3a28699d37 100644
--- a/drivers/video/sis/init301.h
+++ b/drivers/video/sis/init301.h
@@ -71,16 +71,9 @@
#include <linux/types.h>
#include <asm/io.h>
#include <linux/fb.h>
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-#include <video/fbcon.h>
-#endif
#include "sis.h"
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-#include <linux/sisfb.h>
-#else
#include <video/sisfb.h>
#endif
-#endif
static const unsigned char SiS_YPbPrTable[3][64] = {
{
diff --git a/drivers/video/sis/initextlfb.c b/drivers/video/sis/initextlfb.c
index 09f5d758b6c0..c3884a29f4c5 100644
--- a/drivers/video/sis/initextlfb.c
+++ b/drivers/video/sis/initextlfb.c
@@ -34,12 +34,10 @@
#include <linux/types.h>
#include <linux/fb.h>
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
int sisfb_mode_rate_to_dclock(struct SiS_Private *SiS_Pr,
unsigned char modeno, unsigned char rateindex);
int sisfb_mode_rate_to_ddata(struct SiS_Private *SiS_Pr, unsigned char modeno,
unsigned char rateindex, struct fb_var_screeninfo *var);
-#endif
BOOLEAN sisfb_gettotalfrommode(struct SiS_Private *SiS_Pr, unsigned char modeno,
int *htotal, int *vtotal, unsigned char rateindex);
@@ -49,7 +47,6 @@ extern BOOLEAN SiS_SearchModeID(struct SiS_Private *SiS_Pr, unsigned short *Mode
extern void SiS_Generic_ConvertCRData(struct SiS_Private *SiS_Pr, unsigned char *crdata,
int xres, int yres, struct fb_var_screeninfo *var, BOOLEAN writeres);
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
int
sisfb_mode_rate_to_dclock(struct SiS_Private *SiS_Pr, unsigned char modeno,
unsigned char rateindex)
@@ -177,7 +174,6 @@ sisfb_mode_rate_to_ddata(struct SiS_Private *SiS_Pr, unsigned char modeno,
return 1;
}
-#endif /* Linux >= 2.5 */
BOOLEAN
sisfb_gettotalfrommode(struct SiS_Private *SiS_Pr, unsigned char modeno, int *htotal,
diff --git a/drivers/video/sis/osdef.h b/drivers/video/sis/osdef.h
index f59568020eb2..d048bd39961b 100644
--- a/drivers/video/sis/osdef.h
+++ b/drivers/video/sis/osdef.h
@@ -100,11 +100,7 @@
#define SIS315H
#endif
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
#define SIS_LINUX_KERNEL_26
-#else
-#define SIS_LINUX_KERNEL_24
-#endif
#if !defined(SIS300) && !defined(SIS315H)
#warning Neither CONFIG_FB_SIS_300 nor CONFIG_FB_SIS_315 is set
diff --git a/drivers/video/sis/sis_accel.c b/drivers/video/sis/sis_accel.c
index 3b7ce032e2ed..7addf91d2fea 100644
--- a/drivers/video/sis/sis_accel.c
+++ b/drivers/video/sis/sis_accel.c
@@ -32,22 +32,10 @@
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fb.h>
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-#include <linux/console.h>
-#endif
#include <linux/ioport.h>
#include <linux/types.h>
-
#include <asm/io.h>
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-#include <video/fbcon.h>
-#include <video/fbcon-cfb8.h>
-#include <video/fbcon-cfb16.h>
-#include <video/fbcon-cfb24.h>
-#include <video/fbcon-cfb32.h>
-#endif
-
#include "sis.h"
#include "sis_accel.h"
@@ -91,11 +79,9 @@ static const u8 sisPatALUConv[] =
0xFF, /* dest = 0xFF; 1, GXset, 0xF */
};
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,34)
static const int myrops[] = {
3, 10, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3
};
-#endif
/* 300 series ----------------------------------------------------- */
#ifdef CONFIG_FB_SIS_300
@@ -315,8 +301,6 @@ void sisfb_syncaccel(struct sis_video_info *ivideo)
}
}
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) /* --------------- 2.5 --------------- */
-
int fbcon_sis_sync(struct fb_info *info)
{
struct sis_video_info *ivideo = (struct sis_video_info *)info->par;
@@ -438,13 +422,3 @@ void fbcon_sis_copyarea(struct fb_info *info, const struct fb_copyarea *area)
sisfb_syncaccel(ivideo);
}
-
-#endif
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) /* -------------- 2.4 --------------- */
-
-#include "sisfb_accel_2_4.h"
-
-#endif /* KERNEL VERSION */
-
-
diff --git a/drivers/video/sis/sis_accel.h b/drivers/video/sis/sis_accel.h
index 046e2c4a8e09..30e03cdf6b85 100644
--- a/drivers/video/sis/sis_accel.h
+++ b/drivers/video/sis/sis_accel.h
@@ -390,25 +390,11 @@
MMIO_OUT32(ivideo->mmio_vbase, FIRE_TRIGGER, 0); \
CmdQueLen -= 2;
-
int sisfb_initaccel(struct sis_video_info *ivideo);
void sisfb_syncaccel(struct sis_video_info *ivideo);
-#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,5,33)
-void fbcon_sis_bmove(struct display *p, int srcy, int srcx, int dsty,
- int dstx, int height, int width);
-void fbcon_sis_revc(struct display *p, int srcy, int srcx);
-void fbcon_sis_clear8(struct vc_data *conp, struct display *p, int srcy,
- int srcx, int height, int width);
-void fbcon_sis_clear16(struct vc_data *conp, struct display *p, int srcy,
- int srcx, int height, int width);
-void fbcon_sis_clear32(struct vc_data *conp, struct display *p, int srcy,
- int srcx, int height, int width);
-#endif
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,34)
int fbcon_sis_sync(struct fb_info *info);
void fbcon_sis_fillrect(struct fb_info *info, const struct fb_fillrect *rect);
void fbcon_sis_copyarea(struct fb_info *info, const struct fb_copyarea *area);
-#endif
#endif
diff --git a/drivers/video/sis/sis_main.c b/drivers/video/sis/sis_main.c
index 895ebda7d9e3..baaf495a0a6d 100644
--- a/drivers/video/sis/sis_main.c
+++ b/drivers/video/sis/sis_main.c
@@ -35,9 +35,7 @@
#include <linux/version.h>
#include <linux/module.h>
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
#include <linux/moduleparam.h>
-#endif
#include <linux/kernel.h>
#include <linux/smp_lock.h>
#include <linux/spinlock.h>
@@ -58,9 +56,6 @@
#include <linux/init.h>
#include <linux/pci.h>
#include <linux/vmalloc.h>
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-#include <linux/vt_kern.h>
-#endif
#include <linux/capability.h>
#include <linux/fs.h>
#include <linux/types.h>
@@ -70,35 +65,9 @@
#include <asm/mtrr.h>
#endif
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-#include <video/fbcon.h>
-#include <video/fbcon-cfb8.h>
-#include <video/fbcon-cfb16.h>
-#include <video/fbcon-cfb24.h>
-#include <video/fbcon-cfb32.h>
-#endif
-
#include "sis.h"
#include "sis_main.h"
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,3)
-#error "This version of sisfb requires at least 2.6.3"
-#endif
-#endif
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-#ifdef FBCON_HAS_CFB8
-extern struct display_switch fbcon_sis8;
-#endif
-#ifdef FBCON_HAS_CFB16
-extern struct display_switch fbcon_sis16;
-#endif
-#ifdef FBCON_HAS_CFB32
-extern struct display_switch fbcon_sis32;
-#endif
-#endif
-
static void sisfb_handle_command(struct sis_video_info *ivideo,
struct sisfb_cmd *sisfb_command);
@@ -114,17 +83,7 @@ sisfb_setdefaultparms(void)
sisfb_max = -1;
sisfb_userom = -1;
sisfb_useoem = -1;
-#ifdef MODULE
- /* Module: "None" for 2.4, default mode for 2.5+ */
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
- sisfb_mode_idx = -1;
-#else
- sisfb_mode_idx = MODE_INDEX_NONE;
-#endif
-#else
- /* Static: Default mode */
sisfb_mode_idx = -1;
-#endif
sisfb_parm_rate = -1;
sisfb_crt1off = 0;
sisfb_forcecrt1 = -1;
@@ -142,10 +101,6 @@ sisfb_setdefaultparms(void)
sisfb_tvxposoffset = 0;
sisfb_tvyposoffset = 0;
sisfb_nocrt2rate = 0;
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
- sisfb_inverse = 0;
- sisfb_fontname[0] = 0;
-#endif
#if !defined(__i386__) && !defined(__x86_64__)
sisfb_resetcard = 0;
sisfb_videoram = 0;
@@ -162,14 +117,11 @@ sisfb_search_vesamode(unsigned int vesamode, BOOLEAN quiet)
/* We don't know the hardware specs yet and there is no ivideo */
if(vesamode == 0) {
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
- sisfb_mode_idx = MODE_INDEX_NONE;
-#else
if(!quiet)
printk(KERN_ERR "sisfb: Invalid mode. Using default.\n");
sisfb_mode_idx = DEFAULT_MODE;
-#endif
+
return;
}
@@ -215,7 +167,6 @@ sisfb_search_mode(char *name, BOOLEAN quiet)
return;
}
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
if(!strnicmp(name, sisbios_mode[MODE_INDEX_NONE].name, strlen(name))) {
if(!quiet)
printk(KERN_ERR "sisfb: Mode 'none' not supported anymore. Using default.\n");
@@ -223,7 +174,7 @@ sisfb_search_mode(char *name, BOOLEAN quiet)
sisfb_mode_idx = DEFAULT_MODE;
return;
}
-#endif
+
if(strlen(name) <= 19) {
strcpy(strbuf1, name);
for(i = 0; i < strlen(strbuf1); i++) {
@@ -1315,20 +1266,7 @@ sisfb_do_set_var(struct fb_var_screeninfo *var, int isactive, struct fb_info *in
ivideo->refresh_rate = 60;
}
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
- if(ivideo->sisfb_thismonitor.datavalid) {
- if(!sisfb_verify_rate(ivideo, &ivideo->sisfb_thismonitor, ivideo->sisfb_mode_idx,
- ivideo->rate_idx, ivideo->refresh_rate)) {
- printk(KERN_INFO "sisfb: WARNING: Refresh rate exceeds monitor specs!\n");
- }
- }
-#endif
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
- if(((var->activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW) && isactive) {
-#else
if(isactive) {
-#endif
/* If acceleration to be used? Need to know
* before pre/post_set_mode()
*/
@@ -1367,9 +1305,7 @@ sisfb_do_set_var(struct fb_var_screeninfo *var, int isactive, struct fb_info *in
ivideo->current_linelength = ivideo->video_linelength;
ivideo->current_pixclock = var->pixclock;
ivideo->current_refresh_rate = ivideo->refresh_rate;
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
ivideo->sisfb_lastrates[ivideo->mode_no] = ivideo->refresh_rate;
-#endif
}
return 0;
@@ -1435,18 +1371,6 @@ sisfb_pan_var(struct sis_video_info *ivideo, struct fb_var_screeninfo *var)
return 0;
}
-/* ------------ FBDev related routines for 2.4 series ----------- */
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-
-#include "sisfb_fbdev_2_4.h"
-
-#endif
-
-/* ------------ FBDev related routines for 2.6 series ----------- */
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
-
static int
sisfb_open(struct fb_info *info, int user)
{
@@ -1744,8 +1668,6 @@ sisfb_blank(int blank, struct fb_info *info)
return sisfb_myblank(ivideo, blank);
}
-#endif
-
/* ----------- FBDev related routines for all series ---------- */
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,15)
@@ -1969,20 +1891,6 @@ sisfb_get_fix(struct fb_fix_screeninfo *fix, int con, struct fb_info *info)
/* ---------------- fb_ops structures ----------------- */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-static struct fb_ops sisfb_ops = {
- .owner = THIS_MODULE,
- .fb_get_fix = sisfb_get_fix,
- .fb_get_var = sisfb_get_var,
- .fb_set_var = sisfb_set_var,
- .fb_get_cmap = sisfb_get_cmap,
- .fb_set_cmap = sisfb_set_cmap,
- .fb_pan_display = sisfb_pan_display,
- .fb_ioctl = sisfb_ioctl
-};
-#endif
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
static struct fb_ops sisfb_ops = {
.owner = THIS_MODULE,
.fb_open = sisfb_open,
@@ -2004,7 +1912,6 @@ static struct fb_ops sisfb_ops = {
#endif
.fb_ioctl = sisfb_ioctl
};
-#endif
/* ---------------- Chip generation dependent routines ---------------- */
@@ -4100,16 +4007,6 @@ sisfb_setup(char *options)
sisfb_search_mode(this_opt + 5, FALSE);
} else if(!strnicmp(this_opt, "vesa:", 5)) {
sisfb_search_vesamode(simple_strtoul(this_opt + 5, NULL, 0), FALSE);
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
- } else if(!strnicmp(this_opt, "inverse", 7)) {
- sisfb_inverse = 1;
- /* fb_invert_cmaps(); */
- } else if(!strnicmp(this_opt, "font:", 5)) {
- if(strlen(this_opt + 5) < 40) {
- strncpy(sisfb_fontname, this_opt + 5, sizeof(sisfb_fontname) - 1);
- sisfb_fontname[sizeof(sisfb_fontname) - 1] = '\0';
- }
-#endif
} else if(!strnicmp(this_opt, "rate:", 5)) {
sisfb_parm_rate = simple_strtoul(this_opt + 5, NULL, 0);
} else if(!strnicmp(this_opt, "forcecrt1:", 10)) {
@@ -5870,17 +5767,9 @@ sisfb_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
if(sisfb_off)
return -ENXIO;
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,3))
sis_fb_info = framebuffer_alloc(sizeof(*ivideo), &pdev->dev);
if(!sis_fb_info)
return -ENOMEM;
-#else
- sis_fb_info = kmalloc(sizeof(*sis_fb_info) + sizeof(*ivideo), GFP_KERNEL);
- if(!sis_fb_info)
- return -ENOMEM;
- memset(sis_fb_info, 0, sizeof(*sis_fb_info) + sizeof(*ivideo));
- sis_fb_info->par = ((char *)sis_fb_info + sizeof(*sis_fb_info));
-#endif
ivideo = (struct sis_video_info *)sis_fb_info->par;
ivideo->memyselfandi = sis_fb_info;
@@ -5970,10 +5859,6 @@ sisfb_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
ivideo->tvxpos = sisfb_tvxposoffset;
ivideo->tvypos = sisfb_tvyposoffset;
ivideo->sisfb_nocrt2rate = sisfb_nocrt2rate;
-#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,5,0)
- ivideo->sisfb_inverse = sisfb_inverse;
-#endif
-
ivideo->refresh_rate = 0;
if(ivideo->sisfb_parm_rate != -1) {
ivideo->refresh_rate = ivideo->sisfb_parm_rate;
@@ -6049,10 +5934,6 @@ sisfb_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
}
}
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
- strcpy(sis_fb_info->modename, ivideo->myid);
-#endif
-
ivideo->SiS_Pr.ChipType = ivideo->chip;
ivideo->SiS_Pr.ivideo = (void *)ivideo;
@@ -6134,20 +6015,6 @@ sisfb_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
#endif
}
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-#ifdef MODULE
- if((reg & 0x80) && (reg != 0xff)) {
- if((sisbios_mode[ivideo->sisfb_mode_idx].mode_no[ivideo->mni])
- != 0xFF) {
- printk(KERN_INFO "sisfb: Cannot initialize display mode, "
- "X server is active\n");
- ret = -EBUSY;
- goto error_4;
- }
- }
-#endif
-#endif
-
/* Search and copy ROM image */
ivideo->bios_abase = NULL;
ivideo->SiS_Pr.VirtualRomBase = NULL;
@@ -6281,9 +6148,6 @@ error_0: iounmap(ivideo->video_vbase);
error_1: release_mem_region(ivideo->video_base, ivideo->video_size);
error_2: release_mem_region(ivideo->mmio_base, ivideo->mmio_size);
error_3: vfree(ivideo->bios_abase);
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-error_4:
-#endif
if(ivideo->lpcdev)
SIS_PCI_PUT_DEVICE(ivideo->lpcdev);
if(ivideo->nbridge)
@@ -6586,7 +6450,6 @@ error_4:
sis_fb_info->fix = ivideo->sisfb_fix;
sis_fb_info->screen_base = ivideo->video_vbase + ivideo->video_offset;
sis_fb_info->fbops = &sisfb_ops;
-
sisfb_get_fix(&sis_fb_info->fix, -1, sis_fb_info);
sis_fb_info->pseudo_palette = ivideo->pseudo_palette;
@@ -6603,10 +6466,6 @@ error_4:
}
#endif
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
- vc_resize_con(1, 1, 0);
-#endif
-
if(register_framebuffer(sis_fb_info) < 0) {
printk(KERN_ERR "sisfb: Fatal error: Failed to register framebuffer\n");
ret = -EINVAL;
@@ -6653,12 +6512,7 @@ error_4:
printk(KERN_INFO "fb%d: %s frame buffer device version %d.%d.%d\n",
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
- GET_FB_IDX(sis_fb_info->node),
-#else
- sis_fb_info->node,
-#endif
- ivideo->myid, VER_MAJOR, VER_MINOR, VER_LEVEL);
+ sis_fb_info->node, ivideo->myid, VER_MAJOR, VER_MINOR, VER_LEVEL);
printk(KERN_INFO "sisfb: Copyright (C) 2001-2005 Thomas Winischhofer\n");
@@ -6732,11 +6586,7 @@ static void __devexit sisfb_remove(struct pci_dev *pdev)
/* Unregister the framebuffer */
if(ivideo->registered) {
unregister_framebuffer(sis_fb_info);
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,3))
framebuffer_release(sis_fb_info);
-#else
- kfree(sis_fb_info);
-#endif
}
/* OK, our ivideo is gone for good from here. */
@@ -6762,7 +6612,6 @@ static struct pci_driver sisfb_driver = {
SISINITSTATIC int __init sisfb_init(void)
{
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,8)
#ifndef MODULE
char *options = NULL;
@@ -6771,15 +6620,12 @@ SISINITSTATIC int __init sisfb_init(void)
sisfb_setup(options);
#endif
-#endif
return pci_register_driver(&sisfb_driver);
}
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,8)
#ifndef MODULE
module_init(sisfb_init);
#endif
-#endif
/*****************************************************/
/* MODULE */
@@ -6799,9 +6645,6 @@ static int pdc1 = -1;
static int noaccel = -1;
static int noypan = -1;
static int nomax = -1;
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-static int inverse = 0;
-#endif
static int userom = -1;
static int useoem = -1;
static char *tvstandard = NULL;
@@ -6861,10 +6704,6 @@ static int __init sisfb_init_module(void)
else if(nomax == 0)
sisfb_max = 1;
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
- if(inverse) sisfb_inverse = 1;
-#endif
-
if(mem)
sisfb_parm_mem = mem;
@@ -6913,35 +6752,6 @@ MODULE_DESCRIPTION("SiS 300/540/630/730/315/55x/65x/661/74x/330/76x/34x, XGI V3X
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Thomas Winischhofer <thomas@winischhofer.net>, Others");
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-MODULE_PARM(mem, "i");
-MODULE_PARM(noaccel, "i");
-MODULE_PARM(noypan, "i");
-MODULE_PARM(nomax, "i");
-MODULE_PARM(userom, "i");
-MODULE_PARM(useoem, "i");
-MODULE_PARM(mode, "s");
-MODULE_PARM(vesa, "i");
-MODULE_PARM(rate, "i");
-MODULE_PARM(forcecrt1, "i");
-MODULE_PARM(forcecrt2type, "s");
-MODULE_PARM(scalelcd, "i");
-MODULE_PARM(pdc, "i");
-MODULE_PARM(pdc1, "i");
-MODULE_PARM(specialtiming, "s");
-MODULE_PARM(lvdshl, "i");
-MODULE_PARM(tvstandard, "s");
-MODULE_PARM(tvxposoffset, "i");
-MODULE_PARM(tvyposoffset, "i");
-MODULE_PARM(nocrt2rate, "i");
-MODULE_PARM(inverse, "i");
-#if !defined(__i386__) && !defined(__x86_64__)
-MODULE_PARM(resetcard, "i");
-MODULE_PARM(videoram, "i");
-#endif
-#endif
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
module_param(mem, int, 0);
module_param(noaccel, int, 0);
module_param(noypan, int, 0);
@@ -6966,18 +6776,7 @@ module_param(nocrt2rate, int, 0);
module_param(resetcard, int, 0);
module_param(videoram, int, 0);
#endif
-#endif
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-MODULE_PARM_DESC(mem,
- "\nDetermines the beginning of the video memory heap in KB. This heap is used\n"
- "for video RAM management for eg. DRM/DRI. On 300 series, the default depends\n"
- "on the amount of video RAM available. If 8MB of video RAM or less is available,\n"
- "the heap starts at 4096KB, if between 8 and 16MB are available at 8192KB,\n"
- "otherwise at 12288KB. On 315/330/340 series, the heap size is 32KB by default.\n"
- "The value is to be specified without 'KB' and must match the MaxXFBMem setting\n"
- "for XFree86 4.x/X.org 6.7 and later.\n");
-#else
MODULE_PARM_DESC(mem,
"\nDetermines the beginning of the video memory heap in KB. This heap is used\n"
"for video RAM management for eg. DRM/DRI. On 300 series, the default depends\n"
@@ -6985,7 +6784,6 @@ MODULE_PARM_DESC(mem,
"the heap starts at 4096KB, if between 8 and 16MB are available at 8192KB,\n"
"otherwise at 12288KB. On 315/330/340 series, the heap size is 32KB by default.\n"
"The value is to be specified without 'KB'.\n");
-#endif
MODULE_PARM_DESC(noaccel,
"\nIf set to anything other than 0, 2D acceleration will be disabled.\n"
@@ -7002,23 +6800,6 @@ MODULE_PARM_DESC(nomax,
"enable the user to positively specify a virtual Y size of the screen using\n"
"fbset. (default: 0)\n");
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-MODULE_PARM_DESC(mode,
- "\nSelects the desired display mode in the format [X]x[Y]x[Depth], eg.\n"
- "1024x768x16. Other formats supported include XxY-Depth and\n"
- "XxY-Depth@Rate. If the parameter is only one (decimal or hexadecimal)\n"
- "number, it will be interpreted as a VESA mode number. (default: none if\n"
- "sisfb is a module; this leaves the console untouched and the driver will\n"
- "only do the video memory management for eg. DRM/DRI; 800x600x8 if sisfb\n"
- "is in the kernel)\n");
-MODULE_PARM_DESC(vesa,
- "\nSelects the desired display mode by VESA defined mode number, eg. 0x117\n"
- "(default: 0x0000 if sisfb is a module; this leaves the console untouched\n"
- "and the driver will only do the video memory management for eg. DRM/DRI;\n"
- "0x0103 if sisfb is in the kernel)\n");
-#endif
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
MODULE_PARM_DESC(mode,
"\nSelects the desired default display mode in the format XxYxDepth,\n"
"eg. 1024x768x16. Other formats supported include XxY-Depth and\n"
@@ -7028,7 +6809,6 @@ MODULE_PARM_DESC(mode,
MODULE_PARM_DESC(vesa,
"\nSelects the desired default display mode by VESA defined mode number, eg.\n"
"0x117 (default: 0x0103)\n");
-#endif
MODULE_PARM_DESC(rate,
"\nSelects the desired vertical refresh rate for CRT1 (external VGA) in Hz.\n"
@@ -7094,12 +6874,6 @@ MODULE_PARM_DESC(nocrt2rate,
"\nSetting this to 1 will force the driver to use the default refresh rate for\n"
"CRT2 if CRT2 type is VGA. (default: 0, use same rate as CRT1)\n");
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-MODULE_PARM_DESC(inverse,
- "\nSetting this to anything but 0 should invert the display colors, but this\n"
- "does not seem to work. (default: 0)\n");
-#endif
-
#if !defined(__i386__) && !defined(__x86_64__)
#ifdef CONFIG_FB_SIS_300
MODULE_PARM_DESC(resetcard,
diff --git a/drivers/video/sis/sis_main.h b/drivers/video/sis/sis_main.h
index 70b6df371b8e..88e4f1e41470 100644
--- a/drivers/video/sis/sis_main.h
+++ b/drivers/video/sis/sis_main.h
@@ -67,15 +67,7 @@ static int sisfb_ypan = -1;
static int sisfb_max = -1;
static int sisfb_userom = 1;
static int sisfb_useoem = -1;
-#ifdef MODULE
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
-static int sisfb_mode_idx = -1;
-#else
-static int sisfb_mode_idx = MODE_INDEX_NONE; /* Don't use a mode by default if we are a module */
-#endif
-#else
static int sisfb_mode_idx = -1; /* Use a default mode if we are inside the kernel */
-#endif
static int sisfb_parm_rate = -1;
static int sisfb_crt1off = 0;
static int sisfb_forcecrt1 = -1;
@@ -93,10 +85,6 @@ static int sisfb_tvstd = -1;
static int sisfb_tvxposoffset = 0;
static int sisfb_tvyposoffset = 0;
static int sisfb_nocrt2rate = 0;
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-static int sisfb_inverse = 0;
-static char sisfb_fontname[40];
-#endif
#if !defined(__i386__) && !defined(__x86_64__)
static int sisfb_resetcard = 0;
static int sisfb_videoram = 0;
@@ -687,54 +675,8 @@ SISINITSTATIC int sisfb_init(void);
static int sisfb_get_fix(struct fb_fix_screeninfo *fix, int con,
struct fb_info *info);
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-static int sisfb_get_fix(struct fb_fix_screeninfo *fix,
- int con,
- struct fb_info *info);
-static int sisfb_get_var(struct fb_var_screeninfo *var,
- int con,
- struct fb_info *info);
-static int sisfb_set_var(struct fb_var_screeninfo *var,
- int con,
- struct fb_info *info);
-static void sisfb_crtc_to_var(struct sis_video_info *ivideo,
- struct fb_var_screeninfo *var);
-static int sisfb_get_cmap(struct fb_cmap *cmap,
- int kspc,
- int con,
- struct fb_info *info);
-static int sisfb_set_cmap(struct fb_cmap *cmap,
- int kspc,
- int con,
- struct fb_info *info);
-static int sisfb_update_var(int con,
- struct fb_info *info);
-static int sisfb_switch(int con,
- struct fb_info *info);
-static void sisfb_blank(int blank,
- struct fb_info *info);
-static void sisfb_set_disp(int con,
- struct fb_var_screeninfo *var,
- struct fb_info *info);
-static int sis_getcolreg(unsigned regno, unsigned *red, unsigned *green,
- unsigned *blue, unsigned *transp,
- struct fb_info *fb_info);
-static void sisfb_do_install_cmap(int con,
- struct fb_info *info);
-static int sisfb_ioctl(struct inode *inode, struct file *file,
- unsigned int cmd, unsigned long arg, int con,
- struct fb_info *info);
-#endif
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,15)
static int sisfb_ioctl(struct fb_info *info, unsigned int cmd,
unsigned long arg);
-#else
-static int sisfb_ioctl(struct inode *inode, struct file *file,
- unsigned int cmd, unsigned long arg,
- struct fb_info *info);
-#endif
static int sisfb_set_par(struct fb_info *info);
static int sisfb_blank(int blank,
struct fb_info *info);
@@ -743,7 +685,6 @@ extern void fbcon_sis_fillrect(struct fb_info *info,
extern void fbcon_sis_copyarea(struct fb_info *info,
const struct fb_copyarea *area);
extern int fbcon_sis_sync(struct fb_info *info);
-#endif
/* Internal 2D accelerator functions */
extern int sisfb_initaccel(struct sis_video_info *ivideo);
@@ -811,16 +752,10 @@ extern BOOLEAN SiSDetermineROMLayout661(struct SiS_Private *SiS_Pr);
extern BOOLEAN sisfb_gettotalfrommode(struct SiS_Private *SiS_Pr, unsigned char modeno,
int *htotal, int *vtotal, unsigned char rateindex);
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
extern int sisfb_mode_rate_to_dclock(struct SiS_Private *SiS_Pr,
unsigned char modeno, unsigned char rateindex);
extern int sisfb_mode_rate_to_ddata(struct SiS_Private *SiS_Pr, unsigned char modeno,
unsigned char rateindex, struct fb_var_screeninfo *var);
-#endif
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-extern void SiS_Generic_ConvertCRData(struct SiS_Private *SiS_Pr, unsigned char *crdata, int xres,
- int yres, struct fb_var_screeninfo *var, BOOLEAN writeres);
-#endif
/* Chrontel TV, DDC and DPMS functions */
extern unsigned short SiS_GetCH700x(struct SiS_Private *SiS_Pr, unsigned short reg);
diff --git a/drivers/video/sis/vgatypes.h b/drivers/video/sis/vgatypes.h
index 831b9f42264b..05d08b7889a1 100644
--- a/drivers/video/sis/vgatypes.h
+++ b/drivers/video/sis/vgatypes.h
@@ -73,12 +73,10 @@ typedef unsigned int BOOLEAN;
#ifdef SIS_LINUX_KERNEL
typedef unsigned long SISIOADDRESS;
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,8)
#include <linux/types.h> /* Need __iomem */
#undef SISIOMEMTYPE
#define SISIOMEMTYPE __iomem
#endif
-#endif
#ifdef SIS_XORG_XF86
#if XF86_VERSION_CURRENT < XF86_VERSION_NUMERIC(4,2,0,0,0)
diff --git a/drivers/video/sstfb.c b/drivers/video/sstfb.c
index dad54e73147b..711cb11d6eb3 100644
--- a/drivers/video/sstfb.c
+++ b/drivers/video/sstfb.c
@@ -17,7 +17,10 @@
* (port driver to new frambuffer infrastructure)
* 01/2003 Helge Deller <deller@gmx.de>
* (initial work on fb hardware acceleration for voodoo2)
- *
+ * 08/2006 Alan Cox <alan@redhat.com>
+ * Remove never finished and bogus 24/32bit support
+ * Clean up macro abuse
+ * Minor tidying for format.
*/
/*
@@ -40,6 +43,7 @@
through the fifo. warning: issuing a nop command seems to need pci_fifo
-FIXME: in case of failure in the init sequence, be sure we return to a safe
state.
+- FIXME: Use accelerator for 2D scroll
-FIXME: 4MB boards have banked memory (FbiInit2 bits 1 & 20)
*/
@@ -67,9 +71,6 @@
#undef SST_DEBUG
-/* enable 24/32 bpp functions ? (completely untested!) */
-#undef EN_24_32_BPP
-
/*
Default video mode .
0 800x600@60 took from glide
@@ -377,7 +378,11 @@ static void sstfb_clear_screen(struct fb_info *info)
* sstfb_check_var - Optional function. Validates a var passed in.
* @var: frame buffer variable screen structure
* @info: frame buffer structure that represents a single frame buffer
+ *
+ * Limit to the abilities of a single chip as SLI is not supported
+ * by this driver.
*/
+
static int sstfb_check_var(struct fb_var_screeninfo *var,
struct fb_info *info)
{
@@ -390,7 +395,7 @@ static int sstfb_check_var(struct fb_var_screeninfo *var,
unsigned int freq;
if (sst_calc_pll(PICOS2KHZ(var->pixclock), &freq, &par->pll)) {
- eprintk("Pixclock at %ld KHZ out of range\n",
+ printk(KERN_ERR "sstfb: Pixclock at %ld KHZ out of range\n",
PICOS2KHZ(var->pixclock));
return -EINVAL;
}
@@ -409,27 +414,15 @@ static int sstfb_check_var(struct fb_var_screeninfo *var,
case 0 ... 16 :
var->bits_per_pixel = 16;
break;
-#ifdef EN_24_32_BPP
- case 17 ... 24 :
- var->bits_per_pixel = 24;
- break;
- case 25 ... 32 :
- var->bits_per_pixel = 32;
- break;
-#endif
default :
- eprintk("Unsupported bpp %d\n", var->bits_per_pixel);
+ printk(KERN_ERR "sstfb: Unsupported bpp %d\n", var->bits_per_pixel);
return -EINVAL;
}
/* validity tests */
- if ((var->xres <= 1) || (yDim <= 0 )
- || (var->hsync_len <= 1)
- || (hSyncOff <= 1)
- || (var->left_margin <= 2)
- || (vSyncOn <= 0)
- || (vSyncOff <= 0)
- || (vBackPorch <= 0)) {
+ if (var->xres <= 1 || yDim <= 0 || var->hsync_len <= 1 ||
+ hSyncOff <= 1 || var->left_margin <= 2 || vSyncOn <= 0 ||
+ vSyncOff <= 0 || vBackPorch <= 0) {
return -EINVAL;
}
@@ -437,21 +430,17 @@ static int sstfb_check_var(struct fb_var_screeninfo *var,
/* Voodoo 2 limits */
tiles_in_X = (var->xres + 63 ) / 64 * 2;
- if (((var->xres - 1) >= POW2(11)) || (yDim >= POW2(11))) {
- eprintk("Unsupported resolution %dx%d\n",
+ if (var->xres > POW2(11) || yDim >= POW2(11)) {
+ printk(KERN_ERR "sstfb: Unsupported resolution %dx%d\n",
var->xres, var->yres);
return -EINVAL;
}
- if (((var->hsync_len-1) >= POW2(9))
- || ((hSyncOff-1) >= POW2(11))
- || ((var->left_margin - 2) >= POW2(9))
- || (vSyncOn >= POW2(13))
- || (vSyncOff >= POW2(13))
- || (vBackPorch >= POW2(9))
- || (tiles_in_X >= POW2(6))
- || (tiles_in_X <= 0)) {
- eprintk("Unsupported Timings\n");
+ if (var->hsync_len > POW2(9) || hSyncOff > POW2(11) ||
+ var->left_margin - 2 >= POW2(9) || vSyncOn >= POW2(13) ||
+ vSyncOff >= POW2(13) || vBackPorch >= POW2(9) ||
+ tiles_in_X >= POW2(6) || tiles_in_X <= 0) {
+ printk(KERN_ERR "sstfb: Unsupported timings\n");
return -EINVAL;
}
} else {
@@ -459,24 +448,20 @@ static int sstfb_check_var(struct fb_var_screeninfo *var,
tiles_in_X = (var->xres + 63 ) / 64;
if (var->vmode) {
- eprintk("Interlace/Doublescan not supported %#x\n",
+ printk(KERN_ERR "sstfb: Interlace/doublescan not supported %#x\n",
var->vmode);
return -EINVAL;
}
- if (((var->xres - 1) >= POW2(10)) || (var->yres >= POW2(10))) {
- eprintk("Unsupported resolution %dx%d\n",
+ if (var->xres > POW2(10) || var->yres >= POW2(10)) {
+ printk(KERN_ERR "sstfb: Unsupported resolution %dx%d\n",
var->xres, var->yres);
return -EINVAL;
}
- if (((var->hsync_len - 1) >= POW2(8))
- || ((hSyncOff-1) >= POW2(10))
- || ((var->left_margin - 2) >= POW2(8))
- || (vSyncOn >= POW2(12))
- || (vSyncOff >= POW2(12))
- || (vBackPorch >= POW2(8))
- || (tiles_in_X >= POW2(4))
- || (tiles_in_X <= 0)) {
- eprintk("Unsupported Timings\n");
+ if (var->hsync_len > POW2(8) || hSyncOff - 1 > POW2(10) ||
+ var->left_margin - 2 >= POW2(8) || vSyncOn >= POW2(12) ||
+ vSyncOff >= POW2(12) || vBackPorch >= POW2(8) ||
+ tiles_in_X >= POW2(4) || tiles_in_X <= 0) {
+ printk(KERN_ERR "sstfb: Unsupported timings\n");
return -EINVAL;
}
}
@@ -486,8 +471,8 @@ static int sstfb_check_var(struct fb_var_screeninfo *var,
real_length = tiles_in_X * (IS_VOODOO2(par) ? 32 : 64 )
* ((var->bits_per_pixel == 16) ? 2 : 4);
- if ((real_length * yDim) > info->fix.smem_len) {
- eprintk("Not enough video memory\n");
+ if (real_length * yDim > info->fix.smem_len) {
+ printk(KERN_ERR "sstfb: Not enough video memory\n");
return -ENOMEM;
}
@@ -515,20 +500,6 @@ static int sstfb_check_var(struct fb_var_screeninfo *var,
var->blue.offset = 0;
var->transp.offset = 0;
break;
-#ifdef EN_24_32_BPP
- case 24: /* RGB 888 LfbMode 4 */
- case 32: /* ARGB 8888 LfbMode 5 */
- var->red.length = 8;
- var->green.length = 8;
- var->blue.length = 8;
- var->transp.length = 0;
-
- var->red.offset = 16;
- var->green.offset = 8;
- var->blue.offset = 0;
- var->transp.offset = 0; /* in 24bpp we fake a 32 bpp mode */
- break;
-#endif
default:
return -EINVAL;
}
@@ -653,13 +624,6 @@ static int sstfb_set_par(struct fb_info *info)
case 16:
fbiinit1 |= SEL_SOURCE_VCLK_2X_SEL;
break;
-#ifdef EN_24_32_BPP
- case 24:
- case 32:
- /* sst_set_bits(FBIINIT1, SEL_SOURCE_VCLK_2X_DIV2 | EN_24BPP);*/
- fbiinit1 |= SEL_SOURCE_VCLK_2X_SEL | EN_24BPP;
- break;
-#endif
default:
return -EINVAL;
}
@@ -690,14 +654,6 @@ static int sstfb_set_par(struct fb_info *info)
case 16:
lfbmode = LFB_565;
break;
-#ifdef EN_24_32_BPP
- case 24:
- lfbmode = LFB_888;
- break;
- case 32:
- lfbmode = LFB_8888;
- break;
-#endif
default:
return -EINVAL;
}
@@ -789,8 +745,7 @@ static int sstfb_ioctl(struct fb_info *info, u_int cmd, u_long arg)
return -EFAULT;
if (val > info->fix.smem_len)
val = info->fix.smem_len;
- printk("filling %#x \n", val);
- for (p=0 ; p<val; p+=2)
+ for (p = 0 ; p < val; p += 2)
writew(p >> 6, info->screen_base + p);
return 0;
@@ -802,13 +757,10 @@ static int sstfb_ioctl(struct fb_info *info, u_int cmd, u_long arg)
pci_write_config_dword(sst_dev, PCI_INIT_ENABLE,
tmp | PCI_EN_INIT_WR );
fbiinit0 = sst_read (FBIINIT0);
- if (val) {
+ if (val)
sst_write(FBIINIT0, fbiinit0 & ~EN_VGA_PASSTHROUGH);
- iprintk("Disabling VGA pass-through\n");
- } else {
+ else
sst_write(FBIINIT0, fbiinit0 | EN_VGA_PASSTHROUGH);
- iprintk("Enabling VGA pass-through\n");
- }
pci_write_config_dword(sst_dev, PCI_INIT_ENABLE, tmp);
return 0;
@@ -884,9 +836,9 @@ static int __devinit sst_get_memsize(struct fb_info *info, __u32 *memsize)
u8 __iomem *fbbase_virt = info->screen_base;
/* force memsize */
- if ((mem >= 1 ) && (mem <= 4)) {
+ if (mem >= 1 && mem <= 4) {
*memsize = (mem * 0x100000);
- iprintk("supplied memsize: %#x\n", *memsize);
+ printk(KERN_INFO "supplied memsize: %#x\n", *memsize);
return 1;
}
@@ -927,7 +879,7 @@ static int __devinit sst_detect_att(struct fb_info *info)
struct sstfb_par *par = info->par;
int i, mir, dir;
- for (i=0; i<3; i++) {
+ for (i = 0; i < 3; i++) {
sst_dac_write(DACREG_WMA, 0); /* backdoor */
sst_dac_read(DACREG_RMR); /* read 4 times RMR */
sst_dac_read(DACREG_RMR);
@@ -940,7 +892,7 @@ static int __devinit sst_detect_att(struct fb_info *info)
/*the 7th, device ID register */
dir = sst_dac_read(DACREG_RMR);
f_ddprintk("mir: %#x, dir: %#x\n", mir, dir);
- if ((mir == DACREG_MIR_ATT ) && (dir == DACREG_DIR_ATT)) {
+ if (mir == DACREG_MIR_ATT && dir == DACREG_DIR_ATT) {
return 1;
}
}
@@ -1134,12 +1086,6 @@ static void sst_set_vidmod_att_ti(struct fb_info *info, const int bpp)
case 16:
sst_dac_write(DACREG_RMR, (cr0 & 0x0f) | DACREG_CR0_16BPP);
break;
-#ifdef EN_24_32_BPP
- case 24:
- case 32:
- sst_dac_write(DACREG_RMR, (cr0 & 0x0f) | DACREG_CR0_24BPP);
- break;
-#endif
default:
dprintk("%s: bad depth '%u'\n", __FUNCTION__, bpp);
break;
@@ -1154,12 +1100,6 @@ static void sst_set_vidmod_ics(struct fb_info *info, const int bpp)
case 16:
sst_dac_write(DACREG_ICS_CMD, DACREG_ICS_CMD_16BPP);
break;
-#ifdef EN_24_32_BPP
- case 24:
- case 32:
- sst_dac_write(DACREG_ICS_CMD, DACREG_ICS_CMD_24BPP);
- break;
-#endif
default:
dprintk("%s: bad depth '%u'\n", __FUNCTION__, bpp);
break;
@@ -1250,7 +1190,7 @@ static int __devinit sst_init(struct fb_info *info, struct sstfb_par *par)
PCI_EN_INIT_WR | PCI_REMAP_DAC );
/* detect dac type */
if (!sst_detect_dactype(info, par)) {
- eprintk("Unknown dac type\n");
+ printk(KERN_ERR "sstfb: unknown dac type.\n");
//FIXME watch it: we are not in a safe state, bad bad bad.
return 0;
}
@@ -1258,10 +1198,10 @@ static int __devinit sst_init(struct fb_info *info, struct sstfb_par *par)
/* set graphic clock */
par->gfx_clock = spec->default_gfx_clock;
if ((gfxclk >10 ) && (gfxclk < spec->max_gfxclk)) {
- iprintk("Using supplied graphic freq : %dMHz\n", gfxclk);
+ printk(KERN_INFO "sstfb: Using supplied graphic freq : %dMHz\n", gfxclk);
par->gfx_clock = gfxclk *1000;
} else if (gfxclk) {
- wprintk ("%dMhz is way out of spec! Using default\n", gfxclk);
+ printk(KERN_WARNING "sstfb: %dMhz is way out of spec! Using default\n", gfxclk);
}
sst_calc_pll(par->gfx_clock, &Fout, &gfx_timings);
@@ -1396,7 +1336,7 @@ static int __devinit sstfb_probe(struct pci_dev *pdev,
/* Enable device in PCI config. */
if ((err=pci_enable_device(pdev))) {
- eprintk("cannot enable device\n");
+ printk(KERN_ERR "cannot enable device\n");
return err;
}
@@ -1422,39 +1362,39 @@ static int __devinit sstfb_probe(struct pci_dev *pdev,
fix->smem_start = fix->mmio_start + 0x400000;
if (!request_mem_region(fix->mmio_start, fix->mmio_len, "sstfb MMIO")) {
- eprintk("cannot reserve mmio memory\n");
+ printk(KERN_ERR "sstfb: cannot reserve mmio memory\n");
goto fail_mmio_mem;
}
if (!request_mem_region(fix->smem_start, 0x400000,"sstfb FB")) {
- eprintk("cannot reserve fb memory\n");
+ printk(KERN_ERR "sstfb: cannot reserve fb memory\n");
goto fail_fb_mem;
}
par->mmio_vbase = ioremap_nocache(fix->mmio_start,
fix->mmio_len);
if (!par->mmio_vbase) {
- eprintk("cannot remap register area %#lx\n",
+ printk(KERN_ERR "sstfb: cannot remap register area %#lx\n",
fix->mmio_start);
goto fail_mmio_remap;
}
info->screen_base = ioremap_nocache(fix->smem_start, 0x400000);
if (!info->screen_base) {
- eprintk("cannot remap framebuffer %#lx\n",
+ printk(KERN_ERR "sstfb: cannot remap framebuffer %#lx\n",
fix->smem_start);
goto fail_fb_remap;
}
if (!sst_init(info, par)) {
- eprintk("Init failed\n");
+ printk(KERN_ERR "sstfb: Init failed\n");
goto fail;
}
sst_get_memsize(info, &fix->smem_len);
strlcpy(fix->id, spec->name, sizeof(fix->id));
- iprintk("%s (revision %d) with %s dac\n",
+ printk(KERN_INFO "%s (revision %d) with %s dac\n",
fix->id, par->revision, par->dac_sw.name);
- iprintk("framebuffer at %#lx, mapped to 0x%p, size %dMB\n",
+ printk(KERN_INFO "framebuffer at %#lx, mapped to 0x%p, size %dMB\n",
fix->smem_start, info->screen_base,
fix->smem_len >> 20);
@@ -1471,24 +1411,25 @@ static int __devinit sstfb_probe(struct pci_dev *pdev,
fix->accel = FB_ACCEL_NONE; /* FIXME */
/*
* According to the specs, the linelength must be of 1024 *pixels*
- * and the 24bpp mode is in fact a 32 bpp mode.
+ * and the 24bpp mode is in fact a 32 bpp mode (and both are in
+ * fact dithered to 16bit).
*/
fix->line_length = 2048; /* default value, for 24 or 32bit: 4096 */
if ( mode_option &&
fb_find_mode(&info->var, info, mode_option, NULL, 0, NULL, 16)) {
- eprintk("can't set supplied video mode. Using default\n");
+ printk(KERN_ERR "sstfb: can't set supplied video mode. Using default\n");
info->var = sstfb_default;
} else
info->var = sstfb_default;
if (sstfb_check_var(&info->var, info)) {
- eprintk("invalid default video mode.\n");
+ printk(KERN_ERR "sstfb: invalid default video mode.\n");
goto fail;
}
if (sstfb_set_par(info)) {
- eprintk("can't set default video mode.\n");
+ printk(KERN_ERR "sstfb: can't set default video mode.\n");
goto fail;
}
@@ -1497,7 +1438,7 @@ static int __devinit sstfb_probe(struct pci_dev *pdev,
/* register fb */
info->device = &pdev->dev;
if (register_framebuffer(info) < 0) {
- eprintk("can't register framebuffer.\n");
+ printk(KERN_ERR "sstfb: can't register framebuffer.\n");
goto fail;
}
@@ -1711,4 +1652,3 @@ module_param(gfxclk, int, 0);
MODULE_PARM_DESC(gfxclk, "Force graphic chip frequency in MHz. DANGEROUS. (default=auto)");
module_param(slowpci, bool, 0);
MODULE_PARM_DESC(slowpci, "Uses slow PCI settings (0 or 1) (default=0)");
-
diff --git a/fs/9p/v9fs.c b/fs/9p/v9fs.c
index 22f7ccd58d38..0f628041e3f7 100644
--- a/fs/9p/v9fs.c
+++ b/fs/9p/v9fs.c
@@ -460,8 +460,10 @@ static int __init init_v9fs(void)
ret = v9fs_mux_global_init();
if (!ret)
- ret = register_filesystem(&v9fs_fs_type);
-
+ return ret;
+ ret = register_filesystem(&v9fs_fs_type);
+ if (!ret)
+ v9fs_mux_global_exit();
return ret;
}
diff --git a/fs/9p/vfs_inode.c b/fs/9p/vfs_inode.c
index 7a7ec2d1d2f4..5241c600ce28 100644
--- a/fs/9p/vfs_inode.c
+++ b/fs/9p/vfs_inode.c
@@ -233,7 +233,7 @@ struct inode *v9fs_get_inode(struct super_block *sb, int mode)
inode->i_op = &v9fs_symlink_inode_operations;
break;
case S_IFDIR:
- inode->i_nlink++;
+ inc_nlink(inode);
if(v9ses->extended)
inode->i_op = &v9fs_dir_inode_operations_ext;
else
diff --git a/fs/Kconfig b/fs/Kconfig
index d311198bba43..1453d2d164f7 100644
--- a/fs/Kconfig
+++ b/fs/Kconfig
@@ -4,6 +4,8 @@
menu "File systems"
+if BLOCK
+
config EXT2_FS
tristate "Second extended fs support"
help
@@ -399,6 +401,8 @@ config ROMFS_FS
If you don't know whether you need it, then you don't need it:
answer N.
+endif
+
config INOTIFY
bool "Inotify file change notification support"
default y
@@ -530,6 +534,7 @@ config FUSE_FS
If you want to develop a userspace FS, or if you want to use
a filesystem based on FUSE, answer Y or M.
+if BLOCK
menu "CD-ROM/DVD Filesystems"
config ISO9660_FS
@@ -597,7 +602,9 @@ config UDF_NLS
depends on (UDF_FS=m && NLS) || (UDF_FS=y && NLS=y)
endmenu
+endif
+if BLOCK
menu "DOS/FAT/NT Filesystems"
config FAT_FS
@@ -782,6 +789,7 @@ config NTFS_RW
It is perfectly safe to say N here.
endmenu
+endif
menu "Pseudo filesystems"
@@ -881,6 +889,19 @@ config TMPFS
See <file:Documentation/filesystems/tmpfs.txt> for details.
+config TMPFS_POSIX_ACL
+ bool "Tmpfs POSIX Access Control Lists"
+ depends on TMPFS
+ select GENERIC_ACL
+ help
+ POSIX Access Control Lists (ACLs) support permissions for users and
+ groups beyond the owner/group/world scheme.
+
+ To learn more about Access Control Lists, visit the POSIX ACLs for
+ Linux website <http://acl.bestbits.at/>.
+
+ If you don't know what Access Control Lists are, say N.
+
config HUGETLBFS
bool "HugeTLB file system support"
depends X86 || IA64 || PPC64 || SPARC64 || SUPERH || BROKEN
@@ -926,7 +947,7 @@ menu "Miscellaneous filesystems"
config ADFS_FS
tristate "ADFS file system support (EXPERIMENTAL)"
- depends on EXPERIMENTAL
+ depends on BLOCK && EXPERIMENTAL
help
The Acorn Disc Filing System is the standard file system of the
RiscOS operating system which runs on Acorn's ARM-based Risc PC
@@ -954,7 +975,7 @@ config ADFS_FS_RW
config AFFS_FS
tristate "Amiga FFS file system support (EXPERIMENTAL)"
- depends on EXPERIMENTAL
+ depends on BLOCK && EXPERIMENTAL
help
The Fast File System (FFS) is the common file system used on hard
disks by Amiga(tm) systems since AmigaOS Version 1.3 (34.20). Say Y
@@ -976,7 +997,7 @@ config AFFS_FS
config HFS_FS
tristate "Apple Macintosh file system support (EXPERIMENTAL)"
- depends on EXPERIMENTAL
+ depends on BLOCK && EXPERIMENTAL
select NLS
help
If you say Y here, you will be able to mount Macintosh-formatted
@@ -989,6 +1010,7 @@ config HFS_FS
config HFSPLUS_FS
tristate "Apple Extended HFS file system support"
+ depends on BLOCK
select NLS
select NLS_UTF8
help
@@ -1002,7 +1024,7 @@ config HFSPLUS_FS
config BEFS_FS
tristate "BeOS file system (BeFS) support (read only) (EXPERIMENTAL)"
- depends on EXPERIMENTAL
+ depends on BLOCK && EXPERIMENTAL
select NLS
help
The BeOS File System (BeFS) is the native file system of Be, Inc's
@@ -1029,7 +1051,7 @@ config BEFS_DEBUG
config BFS_FS
tristate "BFS file system support (EXPERIMENTAL)"
- depends on EXPERIMENTAL
+ depends on BLOCK && EXPERIMENTAL
help
Boot File System (BFS) is a file system used under SCO UnixWare to
allow the bootloader access to the kernel image and other important
@@ -1051,7 +1073,7 @@ config BFS_FS
config EFS_FS
tristate "EFS file system support (read only) (EXPERIMENTAL)"
- depends on EXPERIMENTAL
+ depends on BLOCK && EXPERIMENTAL
help
EFS is an older file system used for non-ISO9660 CD-ROMs and hard
disk partitions by SGI's IRIX operating system (IRIX 6.0 and newer
@@ -1066,7 +1088,7 @@ config EFS_FS
config JFFS_FS
tristate "Journalling Flash File System (JFFS) support"
- depends on MTD
+ depends on MTD && BLOCK
help
JFFS is the Journaling Flash File System developed by Axis
Communications in Sweden, aimed at providing a crash/powerdown-safe
@@ -1251,6 +1273,7 @@ endchoice
config CRAMFS
tristate "Compressed ROM file system support (cramfs)"
+ depends on BLOCK
select ZLIB_INFLATE
help
Saying Y here includes support for CramFs (Compressed ROM File
@@ -1270,6 +1293,7 @@ config CRAMFS
config VXFS_FS
tristate "FreeVxFS file system support (VERITAS VxFS(TM) compatible)"
+ depends on BLOCK
help
FreeVxFS is a file system driver that support the VERITAS VxFS(TM)
file system format. VERITAS VxFS(TM) is the standard file system
@@ -1287,6 +1311,7 @@ config VXFS_FS
config HPFS_FS
tristate "OS/2 HPFS file system support"
+ depends on BLOCK
help
OS/2 is IBM's operating system for PC's, the same as Warp, and HPFS
is the file system used for organizing files on OS/2 hard disk
@@ -1303,6 +1328,7 @@ config HPFS_FS
config QNX4FS_FS
tristate "QNX4 file system support (read only)"
+ depends on BLOCK
help
This is the file system used by the real-time operating systems
QNX 4 and QNX 6 (the latter is also called QNX RTP).
@@ -1330,6 +1356,7 @@ config QNX4FS_RW
config SYSV_FS
tristate "System V/Xenix/V7/Coherent file system support"
+ depends on BLOCK
help
SCO, Xenix and Coherent are commercial Unix systems for Intel
machines, and Version 7 was used on the DEC PDP-11. Saying Y
@@ -1368,6 +1395,7 @@ config SYSV_FS
config UFS_FS
tristate "UFS file system support (read only)"
+ depends on BLOCK
help
BSD and derivate versions of Unix (such as SunOS, FreeBSD, NetBSD,
OpenBSD and NeXTstep) use a file system called UFS. Some System V
@@ -1940,13 +1968,19 @@ config 9P_FS
If unsure, say N.
+config GENERIC_ACL
+ bool
+ select FS_POSIX_ACL
+
endmenu
+if BLOCK
menu "Partition Types"
source "fs/partitions/Kconfig"
endmenu
+endif
source "fs/nls/Kconfig"
diff --git a/fs/Makefile b/fs/Makefile
index 89135428a539..819b2a93bebe 100644
--- a/fs/Makefile
+++ b/fs/Makefile
@@ -5,12 +5,18 @@
# Rewritten to use lists instead of if-statements.
#
-obj-y := open.o read_write.o file_table.o buffer.o bio.o super.o \
- block_dev.o char_dev.o stat.o exec.o pipe.o namei.o fcntl.o \
+obj-y := open.o read_write.o file_table.o super.o \
+ char_dev.o stat.o exec.o pipe.o namei.o fcntl.o \
ioctl.o readdir.o select.o fifo.o locks.o dcache.o inode.o \
attr.o bad_inode.o file.o filesystems.o namespace.o aio.o \
- seq_file.o xattr.o libfs.o fs-writeback.o mpage.o direct-io.o \
- ioprio.o pnode.o drop_caches.o splice.o sync.o
+ seq_file.o xattr.o libfs.o fs-writeback.o \
+ pnode.o drop_caches.o splice.o sync.o utimes.o
+
+ifeq ($(CONFIG_BLOCK),y)
+obj-y += buffer.o bio.o block_dev.o direct-io.o mpage.o ioprio.o
+else
+obj-y += no-block.o
+endif
obj-$(CONFIG_INOTIFY) += inotify.o
obj-$(CONFIG_INOTIFY_USER) += inotify_user.o
@@ -35,6 +41,7 @@ obj-$(CONFIG_BINFMT_FLAT) += binfmt_flat.o
obj-$(CONFIG_FS_MBCACHE) += mbcache.o
obj-$(CONFIG_FS_POSIX_ACL) += posix_acl.o xattr_acl.o
obj-$(CONFIG_NFS_COMMON) += nfs_common/
+obj-$(CONFIG_GENERIC_ACL) += generic_acl.o
obj-$(CONFIG_QUOTA) += dquot.o
obj-$(CONFIG_QFMT_V1) += quota_v1.o
diff --git a/fs/adfs/file.c b/fs/adfs/file.c
index 1014b9f2117b..6101ea679cb1 100644
--- a/fs/adfs/file.c
+++ b/fs/adfs/file.c
@@ -27,10 +27,12 @@
const struct file_operations adfs_file_operations = {
.llseek = generic_file_llseek,
- .read = generic_file_read,
+ .read = do_sync_read,
+ .aio_read = generic_file_aio_read,
.mmap = generic_file_mmap,
.fsync = file_fsync,
- .write = generic_file_write,
+ .write = do_sync_write,
+ .aio_write = generic_file_aio_write,
.sendfile = generic_file_sendfile,
};
diff --git a/fs/affs/file.c b/fs/affs/file.c
index 3de8590e4f6a..05b5e22de759 100644
--- a/fs/affs/file.c
+++ b/fs/affs/file.c
@@ -27,8 +27,10 @@ static int affs_file_release(struct inode *inode, struct file *filp);
const struct file_operations affs_file_operations = {
.llseek = generic_file_llseek,
- .read = generic_file_read,
- .write = generic_file_write,
+ .read = do_sync_read,
+ .aio_read = generic_file_aio_read,
+ .write = do_sync_write,
+ .aio_write = generic_file_aio_write,
.mmap = generic_file_mmap,
.open = affs_file_open,
.release = affs_file_release,
diff --git a/fs/afs/dir.c b/fs/afs/dir.c
index 2fc99877cb0d..cf8a2cb28505 100644
--- a/fs/afs/dir.c
+++ b/fs/afs/dir.c
@@ -30,7 +30,7 @@ static int afs_dir_readdir(struct file *file, void *dirent, filldir_t filldir);
static int afs_d_revalidate(struct dentry *dentry, struct nameidata *nd);
static int afs_d_delete(struct dentry *dentry);
static int afs_dir_lookup_filldir(void *_cookie, const char *name, int nlen,
- loff_t fpos, ino_t ino, unsigned dtype);
+ loff_t fpos, u64 ino, unsigned dtype);
const struct file_operations afs_dir_file_operations = {
.open = afs_dir_open,
@@ -409,7 +409,7 @@ static int afs_dir_readdir(struct file *file, void *cookie, filldir_t filldir)
* uniquifier through dtype
*/
static int afs_dir_lookup_filldir(void *_cookie, const char *name, int nlen,
- loff_t fpos, ino_t ino, unsigned dtype)
+ loff_t fpos, u64 ino, unsigned dtype)
{
struct afs_dir_lookup_cookie *cookie = _cookie;
diff --git a/fs/afs/file.c b/fs/afs/file.c
index 67d6634101fd..2e8c42639eaa 100644
--- a/fs/afs/file.c
+++ b/fs/afs/file.c
@@ -16,7 +16,6 @@
#include <linux/slab.h>
#include <linux/fs.h>
#include <linux/pagemap.h>
-#include <linux/buffer_head.h>
#include "volume.h"
#include "vnode.h"
#include <rxrpc/call.h>
@@ -37,7 +36,6 @@ struct inode_operations afs_file_inode_operations = {
const struct address_space_operations afs_fs_aops = {
.readpage = afs_file_readpage,
- .sync_page = block_sync_page,
.set_page_dirty = __set_page_dirty_nobuffers,
.releasepage = afs_file_releasepage,
.invalidatepage = afs_file_invalidatepage,
diff --git a/fs/afs/proc.c b/fs/afs/proc.c
index 101d21b6c037..86463ec9ccb4 100644
--- a/fs/afs/proc.c
+++ b/fs/afs/proc.c
@@ -775,6 +775,7 @@ static int afs_proc_cell_servers_release(struct inode *inode,
* first item
*/
static void *afs_proc_cell_servers_start(struct seq_file *m, loff_t *_pos)
+ __acquires(m->private->sv_lock)
{
struct list_head *_p;
struct afs_cell *cell = m->private;
@@ -823,6 +824,7 @@ static void *afs_proc_cell_servers_next(struct seq_file *p, void *v,
* clean up after reading from the cells list
*/
static void afs_proc_cell_servers_stop(struct seq_file *p, void *v)
+ __releases(p->private->sv_lock)
{
struct afs_cell *cell = p->private;
diff --git a/fs/aio.c b/fs/aio.c
index 950630187acc..94766599db00 100644
--- a/fs/aio.c
+++ b/fs/aio.c
@@ -15,6 +15,7 @@
#include <linux/aio_abi.h>
#include <linux/module.h>
#include <linux/syscalls.h>
+#include <linux/uio.h>
#define DEBUG 0
@@ -414,6 +415,7 @@ static struct kiocb fastcall *__aio_get_req(struct kioctx *ctx)
req->ki_retry = NULL;
req->ki_dtor = NULL;
req->private = NULL;
+ req->ki_iovec = NULL;
INIT_LIST_HEAD(&req->ki_run_list);
/* Check if the completion queue has enough free space to
@@ -459,6 +461,8 @@ static inline void really_put_req(struct kioctx *ctx, struct kiocb *req)
if (req->ki_dtor)
req->ki_dtor(req);
+ if (req->ki_iovec != &req->ki_inline_vec)
+ kfree(req->ki_iovec);
kmem_cache_free(kiocb_cachep, req);
ctx->reqs_active--;
@@ -671,7 +675,7 @@ static ssize_t aio_run_iocb(struct kiocb *iocb)
}
if (!(iocb->ki_retried & 0xff)) {
- pr_debug("%ld retry: %d of %d\n", iocb->ki_retried,
+ pr_debug("%ld retry: %zd of %zd\n", iocb->ki_retried,
iocb->ki_nbytes - iocb->ki_left, iocb->ki_nbytes);
}
@@ -1004,7 +1008,7 @@ int fastcall aio_complete(struct kiocb *iocb, long res, long res2)
pr_debug("added to ring %p at [%lu]\n", iocb, tail);
- pr_debug("%ld retries: %d of %d\n", iocb->ki_retried,
+ pr_debug("%ld retries: %zd of %zd\n", iocb->ki_retried,
iocb->ki_nbytes - iocb->ki_left, iocb->ki_nbytes);
put_rq:
/* everything turned out well, dispose of the aiocb. */
@@ -1300,63 +1304,63 @@ asmlinkage long sys_io_destroy(aio_context_t ctx)
return -EINVAL;
}
-/*
- * aio_p{read,write} are the default ki_retry methods for
- * IO_CMD_P{READ,WRITE}. They maintains kiocb retry state around potentially
- * multiple calls to f_op->aio_read(). They loop around partial progress
- * instead of returning -EIOCBRETRY because they don't have the means to call
- * kick_iocb().
- */
-static ssize_t aio_pread(struct kiocb *iocb)
+static void aio_advance_iovec(struct kiocb *iocb, ssize_t ret)
{
- struct file *file = iocb->ki_filp;
- struct address_space *mapping = file->f_mapping;
- struct inode *inode = mapping->host;
- ssize_t ret = 0;
-
- do {
- ret = file->f_op->aio_read(iocb, iocb->ki_buf,
- iocb->ki_left, iocb->ki_pos);
- /*
- * Can't just depend on iocb->ki_left to determine
- * whether we are done. This may have been a short read.
- */
- if (ret > 0) {
- iocb->ki_buf += ret;
- iocb->ki_left -= ret;
+ struct iovec *iov = &iocb->ki_iovec[iocb->ki_cur_seg];
+
+ BUG_ON(ret <= 0);
+
+ while (iocb->ki_cur_seg < iocb->ki_nr_segs && ret > 0) {
+ ssize_t this = min((ssize_t)iov->iov_len, ret);
+ iov->iov_base += this;
+ iov->iov_len -= this;
+ iocb->ki_left -= this;
+ ret -= this;
+ if (iov->iov_len == 0) {
+ iocb->ki_cur_seg++;
+ iov++;
}
+ }
- /*
- * For pipes and sockets we return once we have some data; for
- * regular files we retry till we complete the entire read or
- * find that we can't read any more data (e.g short reads).
- */
- } while (ret > 0 && iocb->ki_left > 0 &&
- !S_ISFIFO(inode->i_mode) && !S_ISSOCK(inode->i_mode));
-
- /* This means we must have transferred all that we could */
- /* No need to retry anymore */
- if ((ret == 0) || (iocb->ki_left == 0))
- ret = iocb->ki_nbytes - iocb->ki_left;
-
- return ret;
+ /* the caller should not have done more io than what fit in
+ * the remaining iovecs */
+ BUG_ON(ret > 0 && iocb->ki_left == 0);
}
-/* see aio_pread() */
-static ssize_t aio_pwrite(struct kiocb *iocb)
+static ssize_t aio_rw_vect_retry(struct kiocb *iocb)
{
struct file *file = iocb->ki_filp;
+ struct address_space *mapping = file->f_mapping;
+ struct inode *inode = mapping->host;
+ ssize_t (*rw_op)(struct kiocb *, const struct iovec *,
+ unsigned long, loff_t);
ssize_t ret = 0;
+ unsigned short opcode;
+
+ if ((iocb->ki_opcode == IOCB_CMD_PREADV) ||
+ (iocb->ki_opcode == IOCB_CMD_PREAD)) {
+ rw_op = file->f_op->aio_read;
+ opcode = IOCB_CMD_PREADV;
+ } else {
+ rw_op = file->f_op->aio_write;
+ opcode = IOCB_CMD_PWRITEV;
+ }
do {
- ret = file->f_op->aio_write(iocb, iocb->ki_buf,
- iocb->ki_left, iocb->ki_pos);
- if (ret > 0) {
- iocb->ki_buf += ret;
- iocb->ki_left -= ret;
- }
- } while (ret > 0 && iocb->ki_left > 0);
+ ret = rw_op(iocb, &iocb->ki_iovec[iocb->ki_cur_seg],
+ iocb->ki_nr_segs - iocb->ki_cur_seg,
+ iocb->ki_pos);
+ if (ret > 0)
+ aio_advance_iovec(iocb, ret);
+
+ /* retry all partial writes. retry partial reads as long as its a
+ * regular file. */
+ } while (ret > 0 && iocb->ki_left > 0 &&
+ (opcode == IOCB_CMD_PWRITEV ||
+ (!S_ISFIFO(inode->i_mode) && !S_ISSOCK(inode->i_mode))));
+ /* This means we must have transferred all that we could */
+ /* No need to retry anymore */
if ((ret == 0) || (iocb->ki_left == 0))
ret = iocb->ki_nbytes - iocb->ki_left;
@@ -1383,6 +1387,38 @@ static ssize_t aio_fsync(struct kiocb *iocb)
return ret;
}
+static ssize_t aio_setup_vectored_rw(int type, struct kiocb *kiocb)
+{
+ ssize_t ret;
+
+ ret = rw_copy_check_uvector(type, (struct iovec __user *)kiocb->ki_buf,
+ kiocb->ki_nbytes, 1,
+ &kiocb->ki_inline_vec, &kiocb->ki_iovec);
+ if (ret < 0)
+ goto out;
+
+ kiocb->ki_nr_segs = kiocb->ki_nbytes;
+ kiocb->ki_cur_seg = 0;
+ /* ki_nbytes/left now reflect bytes instead of segs */
+ kiocb->ki_nbytes = ret;
+ kiocb->ki_left = ret;
+
+ ret = 0;
+out:
+ return ret;
+}
+
+static ssize_t aio_setup_single_vector(struct kiocb *kiocb)
+{
+ kiocb->ki_iovec = &kiocb->ki_inline_vec;
+ kiocb->ki_iovec->iov_base = kiocb->ki_buf;
+ kiocb->ki_iovec->iov_len = kiocb->ki_left;
+ kiocb->ki_nr_segs = 1;
+ kiocb->ki_cur_seg = 0;
+ kiocb->ki_nbytes = kiocb->ki_left;
+ return 0;
+}
+
/*
* aio_setup_iocb:
* Performs the initial checks and aio retry method
@@ -1405,9 +1441,12 @@ static ssize_t aio_setup_iocb(struct kiocb *kiocb)
ret = security_file_permission(file, MAY_READ);
if (unlikely(ret))
break;
+ ret = aio_setup_single_vector(kiocb);
+ if (ret)
+ break;
ret = -EINVAL;
if (file->f_op->aio_read)
- kiocb->ki_retry = aio_pread;
+ kiocb->ki_retry = aio_rw_vect_retry;
break;
case IOCB_CMD_PWRITE:
ret = -EBADF;
@@ -1420,9 +1459,40 @@ static ssize_t aio_setup_iocb(struct kiocb *kiocb)
ret = security_file_permission(file, MAY_WRITE);
if (unlikely(ret))
break;
+ ret = aio_setup_single_vector(kiocb);
+ if (ret)
+ break;
+ ret = -EINVAL;
+ if (file->f_op->aio_write)
+ kiocb->ki_retry = aio_rw_vect_retry;
+ break;
+ case IOCB_CMD_PREADV:
+ ret = -EBADF;
+ if (unlikely(!(file->f_mode & FMODE_READ)))
+ break;
+ ret = security_file_permission(file, MAY_READ);
+ if (unlikely(ret))
+ break;
+ ret = aio_setup_vectored_rw(READ, kiocb);
+ if (ret)
+ break;
+ ret = -EINVAL;
+ if (file->f_op->aio_read)
+ kiocb->ki_retry = aio_rw_vect_retry;
+ break;
+ case IOCB_CMD_PWRITEV:
+ ret = -EBADF;
+ if (unlikely(!(file->f_mode & FMODE_WRITE)))
+ break;
+ ret = security_file_permission(file, MAY_WRITE);
+ if (unlikely(ret))
+ break;
+ ret = aio_setup_vectored_rw(WRITE, kiocb);
+ if (ret)
+ break;
ret = -EINVAL;
if (file->f_op->aio_write)
- kiocb->ki_retry = aio_pwrite;
+ kiocb->ki_retry = aio_rw_vect_retry;
break;
case IOCB_CMD_FDSYNC:
ret = -EINVAL;
diff --git a/fs/autofs/root.c b/fs/autofs/root.c
index 9cac08d6a873..368a1c33a3c8 100644
--- a/fs/autofs/root.c
+++ b/fs/autofs/root.c
@@ -414,7 +414,7 @@ static int autofs_root_rmdir(struct inode *dir, struct dentry *dentry)
dentry->d_time = (unsigned long)(struct autofs_dir_ent *)NULL;
autofs_hash_delete(ent);
- dir->i_nlink--;
+ drop_nlink(dir);
d_drop(dentry);
unlock_kernel();
@@ -466,7 +466,7 @@ static int autofs_root_mkdir(struct inode *dir, struct dentry *dentry, int mode)
ent->dentry = dentry;
autofs_hash_insert(dh,ent);
- dir->i_nlink++;
+ inc_nlink(dir);
d_instantiate(dentry, iget(dir->i_sb,ino));
unlock_kernel();
diff --git a/fs/autofs4/root.c b/fs/autofs4/root.c
index 27e17f96cada..c1493524da4d 100644
--- a/fs/autofs4/root.c
+++ b/fs/autofs4/root.c
@@ -281,9 +281,6 @@ static int try_to_fill_dentry(struct dentry *dentry, int flags)
DPRINTK("mount done status=%d", status);
- if (status && dentry->d_inode)
- return status; /* Try to get the kernel to invalidate this dentry */
-
/* Turn this into a real negative dentry? */
if (status == -ENOENT) {
spin_lock(&dentry->d_lock);
@@ -359,7 +356,7 @@ static void *autofs4_follow_link(struct dentry *dentry, struct nameidata *nd)
* don't try to mount it again.
*/
spin_lock(&dcache_lock);
- if (!d_mountpoint(dentry) && list_empty(&dentry->d_subdirs)) {
+ if (!d_mountpoint(dentry) && __simple_empty(dentry)) {
spin_unlock(&dcache_lock);
status = try_to_fill_dentry(dentry, 0);
@@ -540,6 +537,9 @@ static struct dentry *autofs4_lookup(struct inode *dir, struct dentry *dentry, s
return ERR_PTR(-ERESTARTNOINTR);
}
}
+ spin_lock(&dentry->d_lock);
+ dentry->d_flags &= ~DCACHE_AUTOFS_PENDING;
+ spin_unlock(&dentry->d_lock);
}
/*
@@ -638,7 +638,7 @@ static int autofs4_dir_unlink(struct inode *dir, struct dentry *dentry)
dput(ino->dentry);
dentry->d_inode->i_size = 0;
- dentry->d_inode->i_nlink = 0;
+ clear_nlink(dentry->d_inode);
dir->i_mtime = CURRENT_TIME;
@@ -673,10 +673,10 @@ static int autofs4_dir_rmdir(struct inode *dir, struct dentry *dentry)
}
dput(ino->dentry);
dentry->d_inode->i_size = 0;
- dentry->d_inode->i_nlink = 0;
+ clear_nlink(dentry->d_inode);
if (dir->i_nlink)
- dir->i_nlink--;
+ drop_nlink(dir);
return 0;
}
@@ -713,7 +713,7 @@ static int autofs4_dir_mkdir(struct inode *dir, struct dentry *dentry, int mode)
if (p_ino && dentry->d_parent != dentry)
atomic_inc(&p_ino->count);
ino->inode = inode;
- dir->i_nlink++;
+ inc_nlink(dir);
dir->i_mtime = CURRENT_TIME;
return 0;
diff --git a/fs/bad_inode.c b/fs/bad_inode.c
index 80599ae33966..34e6d7b220c3 100644
--- a/fs/bad_inode.c
+++ b/fs/bad_inode.c
@@ -40,8 +40,6 @@ static const struct file_operations bad_file_ops =
.aio_fsync = EIO_ERROR,
.fasync = EIO_ERROR,
.lock = EIO_ERROR,
- .readv = EIO_ERROR,
- .writev = EIO_ERROR,
.sendfile = EIO_ERROR,
.sendpage = EIO_ERROR,
.get_unmapped_area = EIO_ERROR,
diff --git a/fs/bfs/dir.c b/fs/bfs/dir.c
index dcf04cb13283..a650f1d0b85e 100644
--- a/fs/bfs/dir.c
+++ b/fs/bfs/dir.c
@@ -117,8 +117,7 @@ static int bfs_create(struct inode * dir, struct dentry * dentry, int mode,
err = bfs_add_entry(dir, dentry->d_name.name, dentry->d_name.len, inode->i_ino);
if (err) {
- inode->i_nlink--;
- mark_inode_dirty(inode);
+ inode_dec_link_count(inode);
iput(inode);
unlock_kernel();
return err;
@@ -164,7 +163,7 @@ static int bfs_link(struct dentry * old, struct inode * dir, struct dentry * new
unlock_kernel();
return err;
}
- inode->i_nlink++;
+ inc_nlink(inode);
inode->i_ctime = CURRENT_TIME_SEC;
mark_inode_dirty(inode);
atomic_inc(&inode->i_count);
@@ -196,9 +195,8 @@ static int bfs_unlink(struct inode * dir, struct dentry * dentry)
mark_buffer_dirty(bh);
dir->i_ctime = dir->i_mtime = CURRENT_TIME_SEC;
mark_inode_dirty(dir);
- inode->i_nlink--;
inode->i_ctime = dir->i_ctime;
- mark_inode_dirty(inode);
+ inode_dec_link_count(inode);
error = 0;
out_brelse:
@@ -249,9 +247,8 @@ static int bfs_rename(struct inode * old_dir, struct dentry * old_dentry,
old_dir->i_ctime = old_dir->i_mtime = CURRENT_TIME_SEC;
mark_inode_dirty(old_dir);
if (new_inode) {
- new_inode->i_nlink--;
new_inode->i_ctime = CURRENT_TIME_SEC;
- mark_inode_dirty(new_inode);
+ inode_dec_link_count(new_inode);
}
mark_buffer_dirty(old_bh);
error = 0;
diff --git a/fs/bfs/file.c b/fs/bfs/file.c
index 3d5aca28a0a0..a9164a87f8de 100644
--- a/fs/bfs/file.c
+++ b/fs/bfs/file.c
@@ -19,8 +19,10 @@
const struct file_operations bfs_file_operations = {
.llseek = generic_file_llseek,
- .read = generic_file_read,
- .write = generic_file_write,
+ .read = do_sync_read,
+ .aio_read = generic_file_aio_read,
+ .write = do_sync_write,
+ .aio_write = generic_file_aio_write,
.mmap = generic_file_mmap,
.sendfile = generic_file_sendfile,
};
diff --git a/fs/binfmt_aout.c b/fs/binfmt_aout.c
index f312103434d4..517e111bb7ef 100644
--- a/fs/binfmt_aout.c
+++ b/fs/binfmt_aout.c
@@ -278,6 +278,13 @@ static int load_aout_binary(struct linux_binprm * bprm, struct pt_regs * regs)
return -ENOEXEC;
}
+ /*
+ * Requires a mmap handler. This prevents people from using a.out
+ * as part of an exploit attack against /proc-related vulnerabilities.
+ */
+ if (!bprm->file->f_op || !bprm->file->f_op->mmap)
+ return -ENOEXEC;
+
fd_offset = N_TXTOFF(ex);
/* Check initial limits. This avoids letting people circumvent
@@ -476,6 +483,13 @@ static int load_aout_library(struct file *file)
goto out;
}
+ /*
+ * Requires a mmap handler. This prevents people from using a.out
+ * as part of an exploit attack against /proc-related vulnerabilities.
+ */
+ if (!file->f_op || !file->f_op->mmap)
+ goto out;
+
if (N_FLAGS(ex))
goto out;
diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c
index dfd8cfb7fb5d..06435f3665f4 100644
--- a/fs/binfmt_elf.c
+++ b/fs/binfmt_elf.c
@@ -46,7 +46,6 @@
static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs);
static int load_elf_library(struct file *);
static unsigned long elf_map (struct file *, unsigned long, struct elf_phdr *, int, int);
-extern int dump_fpu (struct pt_regs *, elf_fpregset_t *);
#ifndef elf_addr_t
#define elf_addr_t unsigned long
@@ -1038,10 +1037,8 @@ out_free_interp:
out_free_file:
sys_close(elf_exec_fileno);
out_free_fh:
- if (files) {
- put_files_struct(current->files);
- current->files = files;
- }
+ if (files)
+ reset_files_struct(current, files);
out_free_ph:
kfree(elf_phdata);
goto out;
@@ -1154,11 +1151,23 @@ static int dump_write(struct file *file, const void *addr, int nr)
static int dump_seek(struct file *file, loff_t off)
{
- if (file->f_op->llseek) {
- if (file->f_op->llseek(file, off, 0) != off)
+ if (file->f_op->llseek && file->f_op->llseek != no_llseek) {
+ if (file->f_op->llseek(file, off, 1) != off)
return 0;
- } else
- file->f_pos = off;
+ } else {
+ char *buf = (char *)get_zeroed_page(GFP_KERNEL);
+ if (!buf)
+ return 0;
+ while (off > 0) {
+ unsigned long n = off;
+ if (n > PAGE_SIZE)
+ n = PAGE_SIZE;
+ if (!dump_write(file, buf, n))
+ return 0;
+ off -= n;
+ }
+ free_page((unsigned long)buf);
+ }
return 1;
}
@@ -1206,30 +1215,35 @@ static int notesize(struct memelfnote *en)
return sz;
}
-#define DUMP_WRITE(addr, nr) \
- do { if (!dump_write(file, (addr), (nr))) return 0; } while(0)
-#define DUMP_SEEK(off) \
- do { if (!dump_seek(file, (off))) return 0; } while(0)
+#define DUMP_WRITE(addr, nr, foffset) \
+ do { if (!dump_write(file, (addr), (nr))) return 0; *foffset += (nr); } while(0)
-static int writenote(struct memelfnote *men, struct file *file)
+static int alignfile(struct file *file, loff_t *foffset)
{
- struct elf_note en;
+ char buf[4] = { 0, };
+ DUMP_WRITE(buf, roundup(*foffset, 4) - *foffset, foffset);
+ return 1;
+}
+static int writenote(struct memelfnote *men, struct file *file,
+ loff_t *foffset)
+{
+ struct elf_note en;
en.n_namesz = strlen(men->name) + 1;
en.n_descsz = men->datasz;
en.n_type = men->type;
- DUMP_WRITE(&en, sizeof(en));
- DUMP_WRITE(men->name, en.n_namesz);
- /* XXX - cast from long long to long to avoid need for libgcc.a */
- DUMP_SEEK(roundup((unsigned long)file->f_pos, 4)); /* XXX */
- DUMP_WRITE(men->data, men->datasz);
- DUMP_SEEK(roundup((unsigned long)file->f_pos, 4)); /* XXX */
+ DUMP_WRITE(&en, sizeof(en), foffset);
+ DUMP_WRITE(men->name, en.n_namesz, foffset);
+ if (!alignfile(file, foffset))
+ return 0;
+ DUMP_WRITE(men->data, men->datasz, foffset);
+ if (!alignfile(file, foffset))
+ return 0;
return 1;
}
#undef DUMP_WRITE
-#undef DUMP_SEEK
#define DUMP_WRITE(addr, nr) \
if ((size += (nr)) > limit || !dump_write(file, (addr), (nr))) \
@@ -1429,7 +1443,7 @@ static int elf_core_dump(long signr, struct pt_regs *regs, struct file *file)
int i;
struct vm_area_struct *vma;
struct elfhdr *elf = NULL;
- loff_t offset = 0, dataoff;
+ loff_t offset = 0, dataoff, foffset;
unsigned long limit = current->signal->rlim[RLIMIT_CORE].rlim_cur;
int numnote;
struct memelfnote *notes = NULL;
@@ -1481,20 +1495,19 @@ static int elf_core_dump(long signr, struct pt_regs *regs, struct file *file)
if (signr) {
struct elf_thread_status *tmp;
- read_lock(&tasklist_lock);
+ rcu_read_lock();
do_each_thread(g,p)
if (current->mm == p->mm && current != p) {
tmp = kzalloc(sizeof(*tmp), GFP_ATOMIC);
if (!tmp) {
- read_unlock(&tasklist_lock);
+ rcu_read_unlock();
goto cleanup;
}
- INIT_LIST_HEAD(&tmp->list);
tmp->thread = p;
list_add(&tmp->list, &thread_list);
}
while_each_thread(g,p);
- read_unlock(&tasklist_lock);
+ rcu_read_unlock();
list_for_each(t, &thread_list) {
struct elf_thread_status *tmp;
int sz;
@@ -1573,7 +1586,8 @@ static int elf_core_dump(long signr, struct pt_regs *regs, struct file *file)
DUMP_WRITE(&phdr, sizeof(phdr));
}
- /* Page-align dumped data */
+ foffset = offset;
+
dataoff = offset = roundup(offset, ELF_EXEC_PAGESIZE);
/* Write program headers for segments dump */
@@ -1598,6 +1612,7 @@ static int elf_core_dump(long signr, struct pt_regs *regs, struct file *file)
phdr.p_align = ELF_EXEC_PAGESIZE;
DUMP_WRITE(&phdr, sizeof(phdr));
+ foffset += sizeof(phdr);
}
#ifdef ELF_CORE_WRITE_EXTRA_PHDRS
@@ -1606,7 +1621,7 @@ static int elf_core_dump(long signr, struct pt_regs *regs, struct file *file)
/* write out the notes section */
for (i = 0; i < numnote; i++)
- if (!writenote(notes + i, file))
+ if (!writenote(notes + i, file, &foffset))
goto end_coredump;
/* write out the thread status notes section */
@@ -1615,11 +1630,12 @@ static int elf_core_dump(long signr, struct pt_regs *regs, struct file *file)
list_entry(t, struct elf_thread_status, list);
for (i = 0; i < tmp->num_notes; i++)
- if (!writenote(&tmp->notes[i], file))
+ if (!writenote(&tmp->notes[i], file, &foffset))
goto end_coredump;
}
-
- DUMP_SEEK(dataoff);
+
+ /* Align to page */
+ DUMP_SEEK(dataoff - foffset);
for (vma = current->mm->mmap; vma != NULL; vma = vma->vm_next) {
unsigned long addr;
@@ -1635,10 +1651,10 @@ static int elf_core_dump(long signr, struct pt_regs *regs, struct file *file)
if (get_user_pages(current, current->mm, addr, 1, 0, 1,
&page, &vma) <= 0) {
- DUMP_SEEK(file->f_pos + PAGE_SIZE);
+ DUMP_SEEK(PAGE_SIZE);
} else {
if (page == ZERO_PAGE(addr)) {
- DUMP_SEEK(file->f_pos + PAGE_SIZE);
+ DUMP_SEEK(PAGE_SIZE);
} else {
void *kaddr;
flush_cache_page(vma, addr,
@@ -1662,13 +1678,6 @@ static int elf_core_dump(long signr, struct pt_regs *regs, struct file *file)
ELF_CORE_WRITE_EXTRA_DATA;
#endif
- if (file->f_pos != offset) {
- /* Sanity check */
- printk(KERN_WARNING
- "elf_core_dump: file->f_pos (%Ld) != offset (%Ld)\n",
- file->f_pos, offset);
- }
-
end_coredump:
set_fs(fs);
diff --git a/fs/binfmt_elf_fdpic.c b/fs/binfmt_elf_fdpic.c
index 2f3365829229..f86d5c9ce5eb 100644
--- a/fs/binfmt_elf_fdpic.c
+++ b/fs/binfmt_elf_fdpic.c
@@ -1597,20 +1597,19 @@ static int elf_fdpic_core_dump(long signr, struct pt_regs *regs,
if (signr) {
struct elf_thread_status *tmp;
- read_lock(&tasklist_lock);
+ rcu_read_lock();
do_each_thread(g,p)
if (current->mm == p->mm && current != p) {
tmp = kzalloc(sizeof(*tmp), GFP_ATOMIC);
if (!tmp) {
- read_unlock(&tasklist_lock);
+ rcu_read_unlock();
goto cleanup;
}
- INIT_LIST_HEAD(&tmp->list);
tmp->thread = p;
list_add(&tmp->list, &thread_list);
}
while_each_thread(g,p);
- read_unlock(&tasklist_lock);
+ rcu_read_unlock();
list_for_each(t, &thread_list) {
struct elf_thread_status *tmp;
int sz;
diff --git a/fs/binfmt_misc.c b/fs/binfmt_misc.c
index 66ba137f8661..1713c48fef54 100644
--- a/fs/binfmt_misc.c
+++ b/fs/binfmt_misc.c
@@ -215,10 +215,8 @@ _error:
bprm->interp_flags = 0;
bprm->interp_data = 0;
_unshare:
- if (files) {
- put_files_struct(current->files);
- current->files = files;
- }
+ if (files)
+ reset_files_struct(current, files);
goto _ret;
}
diff --git a/fs/bio.c b/fs/bio.c
index 6a0b9ad8f8c9..8f93e939f213 100644
--- a/fs/bio.c
+++ b/fs/bio.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2001 Jens Axboe <axboe@suse.de>
+ * Copyright (C) 2001 Jens Axboe <axboe@kernel.dk>
*
* 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
@@ -1142,7 +1142,7 @@ static int biovec_create_pools(struct bio_set *bs, int pool_entries, int scale)
struct biovec_slab *bp = bvec_slabs + i;
mempool_t **bvp = bs->bvec_pools + i;
- if (i >= scale)
+ if (pool_entries > 1 && i >= scale)
pool_entries >>= 1;
*bvp = mempool_create_slab_pool(pool_entries, bp->slab);
diff --git a/fs/block_dev.c b/fs/block_dev.c
index 045f98854f14..bc8f27cc4483 100644
--- a/fs/block_dev.c
+++ b/fs/block_dev.c
@@ -17,11 +17,13 @@
#include <linux/module.h>
#include <linux/blkpg.h>
#include <linux/buffer_head.h>
+#include <linux/writeback.h>
#include <linux/mpage.h>
#include <linux/mount.h>
#include <linux/uio.h>
#include <linux/namei.h>
#include <asm/uaccess.h>
+#include "internal.h"
struct bdev_inode {
struct block_device bdev;
@@ -543,11 +545,11 @@ static struct kobject *bdev_get_holder(struct block_device *bdev)
return kobject_get(bdev->bd_disk->holder_dir);
}
-static void add_symlink(struct kobject *from, struct kobject *to)
+static int add_symlink(struct kobject *from, struct kobject *to)
{
if (!from || !to)
- return;
- sysfs_create_link(from, to, kobject_name(to));
+ return 0;
+ return sysfs_create_link(from, to, kobject_name(to));
}
static void del_symlink(struct kobject *from, struct kobject *to)
@@ -648,30 +650,38 @@ static void free_bd_holder(struct bd_holder *bo)
* If there is no matching entry with @bo in @bdev->bd_holder_list,
* add @bo to the list, create symlinks.
*
- * Returns 1 if @bo was added to the list.
- * Returns 0 if @bo wasn't used by any reason and should be freed.
+ * Returns 0 if symlinks are created or already there.
+ * Returns -ve if something fails and @bo can be freed.
*/
static int add_bd_holder(struct block_device *bdev, struct bd_holder *bo)
{
struct bd_holder *tmp;
+ int ret;
if (!bo)
- return 0;
+ return -EINVAL;
list_for_each_entry(tmp, &bdev->bd_holder_list, list) {
if (tmp->sdir == bo->sdir) {
tmp->count++;
+ /* We've already done what we need to do here. */
+ free_bd_holder(bo);
return 0;
}
}
if (!bd_holder_grab_dirs(bdev, bo))
- return 0;
+ return -EBUSY;
- add_symlink(bo->sdir, bo->sdev);
- add_symlink(bo->hdir, bo->hdev);
- list_add_tail(&bo->list, &bdev->bd_holder_list);
- return 1;
+ ret = add_symlink(bo->sdir, bo->sdev);
+ if (ret == 0) {
+ ret = add_symlink(bo->hdir, bo->hdev);
+ if (ret)
+ del_symlink(bo->sdir, bo->sdev);
+ }
+ if (ret == 0)
+ list_add_tail(&bo->list, &bdev->bd_holder_list);
+ return ret;
}
/**
@@ -741,7 +751,9 @@ static int bd_claim_by_kobject(struct block_device *bdev, void *holder,
mutex_lock_nested(&bdev->bd_mutex, BD_MUTEX_PARTITION);
res = bd_claim(bdev, holder);
- if (res || !add_bd_holder(bdev, bo))
+ if (res == 0)
+ res = add_bd_holder(bdev, bo);
+ if (res)
free_bd_holder(bo);
mutex_unlock(&bdev->bd_mutex);
@@ -1021,7 +1033,7 @@ do_open(struct block_device *bdev, struct file *file, unsigned int subclass)
rescan_partitions(bdev->bd_disk, bdev);
} else {
mutex_lock_nested(&bdev->bd_contains->bd_mutex,
- BD_MUTEX_PARTITION);
+ BD_MUTEX_WHOLE);
bdev->bd_contains->bd_part_count++;
mutex_unlock(&bdev->bd_contains->bd_mutex);
}
@@ -1142,22 +1154,6 @@ static int blkdev_close(struct inode * inode, struct file * filp)
return blkdev_put(bdev);
}
-static ssize_t blkdev_file_write(struct file *file, const char __user *buf,
- size_t count, loff_t *ppos)
-{
- struct iovec local_iov = { .iov_base = (void __user *)buf, .iov_len = count };
-
- return generic_file_write_nolock(file, &local_iov, 1, ppos);
-}
-
-static ssize_t blkdev_file_aio_write(struct kiocb *iocb, const char __user *buf,
- size_t count, loff_t pos)
-{
- struct iovec local_iov = { .iov_base = (void __user *)buf, .iov_len = count };
-
- return generic_file_aio_write_nolock(iocb, &local_iov, 1, &iocb->ki_pos);
-}
-
static long block_ioctl(struct file *file, unsigned cmd, unsigned long arg)
{
return blkdev_ioctl(file->f_mapping->host, file, cmd, arg);
@@ -1177,18 +1173,16 @@ const struct file_operations def_blk_fops = {
.open = blkdev_open,
.release = blkdev_close,
.llseek = block_llseek,
- .read = generic_file_read,
- .write = blkdev_file_write,
+ .read = do_sync_read,
+ .write = do_sync_write,
.aio_read = generic_file_aio_read,
- .aio_write = blkdev_file_aio_write,
+ .aio_write = generic_file_aio_write_nolock,
.mmap = generic_file_mmap,
.fsync = block_fsync,
.unlocked_ioctl = block_ioctl,
#ifdef CONFIG_COMPAT
.compat_ioctl = compat_blkdev_ioctl,
#endif
- .readv = generic_file_readv,
- .writev = generic_file_write_nolock,
.sendfile = generic_file_sendfile,
.splice_read = generic_file_splice_read,
.splice_write = generic_file_splice_write,
@@ -1303,3 +1297,24 @@ void close_bdev_excl(struct block_device *bdev)
}
EXPORT_SYMBOL(close_bdev_excl);
+
+int __invalidate_device(struct block_device *bdev)
+{
+ struct super_block *sb = get_super(bdev);
+ int res = 0;
+
+ if (sb) {
+ /*
+ * no need to lock the super, get_super holds the
+ * read mutex so the filesystem cannot go away
+ * under us (->put_super runs with the write lock
+ * hold).
+ */
+ shrink_dcache_sb(sb);
+ res = invalidate_inodes(sb);
+ drop_super(sb);
+ }
+ invalidate_bdev(bdev, 0);
+ return res;
+}
+EXPORT_SYMBOL(__invalidate_device);
diff --git a/fs/buffer.c b/fs/buffer.c
index 3b6d701073e7..16cfbcd254f1 100644
--- a/fs/buffer.c
+++ b/fs/buffer.c
@@ -159,31 +159,6 @@ int sync_blockdev(struct block_device *bdev)
}
EXPORT_SYMBOL(sync_blockdev);
-static void __fsync_super(struct super_block *sb)
-{
- sync_inodes_sb(sb, 0);
- DQUOT_SYNC(sb);
- lock_super(sb);
- if (sb->s_dirt && sb->s_op->write_super)
- sb->s_op->write_super(sb);
- unlock_super(sb);
- if (sb->s_op->sync_fs)
- sb->s_op->sync_fs(sb, 1);
- sync_blockdev(sb->s_bdev);
- sync_inodes_sb(sb, 1);
-}
-
-/*
- * Write out and wait upon all dirty data associated with this
- * superblock. Filesystem data as well as the underlying block
- * device. Takes the superblock lock.
- */
-int fsync_super(struct super_block *sb)
-{
- __fsync_super(sb);
- return sync_blockdev(sb->s_bdev);
-}
-
/*
* Write out and wait upon all dirty data associated with this
* device. Filesystem data as well as the underlying block
@@ -260,118 +235,6 @@ void thaw_bdev(struct block_device *bdev, struct super_block *sb)
EXPORT_SYMBOL(thaw_bdev);
/*
- * sync everything. Start out by waking pdflush, because that writes back
- * all queues in parallel.
- */
-static void do_sync(unsigned long wait)
-{
- wakeup_pdflush(0);
- sync_inodes(0); /* All mappings, inodes and their blockdevs */
- DQUOT_SYNC(NULL);
- sync_supers(); /* Write the superblocks */
- sync_filesystems(0); /* Start syncing the filesystems */
- sync_filesystems(wait); /* Waitingly sync the filesystems */
- sync_inodes(wait); /* Mappings, inodes and blockdevs, again. */
- if (!wait)
- printk("Emergency Sync complete\n");
- if (unlikely(laptop_mode))
- laptop_sync_completion();
-}
-
-asmlinkage long sys_sync(void)
-{
- do_sync(1);
- return 0;
-}
-
-void emergency_sync(void)
-{
- pdflush_operation(do_sync, 0);
-}
-
-/*
- * Generic function to fsync a file.
- *
- * filp may be NULL if called via the msync of a vma.
- */
-
-int file_fsync(struct file *filp, struct dentry *dentry, int datasync)
-{
- struct inode * inode = dentry->d_inode;
- struct super_block * sb;
- int ret, err;
-
- /* sync the inode to buffers */
- ret = write_inode_now(inode, 0);
-
- /* sync the superblock to buffers */
- sb = inode->i_sb;
- lock_super(sb);
- if (sb->s_op->write_super)
- sb->s_op->write_super(sb);
- unlock_super(sb);
-
- /* .. finally sync the buffers to disk */
- err = sync_blockdev(sb->s_bdev);
- if (!ret)
- ret = err;
- return ret;
-}
-
-long do_fsync(struct file *file, int datasync)
-{
- int ret;
- int err;
- struct address_space *mapping = file->f_mapping;
-
- if (!file->f_op || !file->f_op->fsync) {
- /* Why? We can still call filemap_fdatawrite */
- ret = -EINVAL;
- goto out;
- }
-
- ret = filemap_fdatawrite(mapping);
-
- /*
- * We need to protect against concurrent writers, which could cause
- * livelocks in fsync_buffers_list().
- */
- mutex_lock(&mapping->host->i_mutex);
- err = file->f_op->fsync(file, file->f_dentry, datasync);
- if (!ret)
- ret = err;
- mutex_unlock(&mapping->host->i_mutex);
- err = filemap_fdatawait(mapping);
- if (!ret)
- ret = err;
-out:
- return ret;
-}
-
-static long __do_fsync(unsigned int fd, int datasync)
-{
- struct file *file;
- int ret = -EBADF;
-
- file = fget(fd);
- if (file) {
- ret = do_fsync(file, datasync);
- fput(file);
- }
- return ret;
-}
-
-asmlinkage long sys_fsync(unsigned int fd)
-{
- return __do_fsync(fd, 0);
-}
-
-asmlinkage long sys_fdatasync(unsigned int fd)
-{
- return __do_fsync(fd, 1);
-}
-
-/*
* Various filesystems appear to want __find_get_block to be non-blocking.
* But it's the page lock which protects the buffers. To get around this,
* we get exclusion from try_to_free_buffers with the blockdev mapping's
@@ -1551,35 +1414,6 @@ static void discard_buffer(struct buffer_head * bh)
}
/**
- * try_to_release_page() - release old fs-specific metadata on a page
- *
- * @page: the page which the kernel is trying to free
- * @gfp_mask: memory allocation flags (and I/O mode)
- *
- * The address_space is to try to release any data against the page
- * (presumably at page->private). If the release was successful, return `1'.
- * Otherwise return zero.
- *
- * The @gfp_mask argument specifies whether I/O may be performed to release
- * this page (__GFP_IO), and whether the call may block (__GFP_WAIT).
- *
- * NOTE: @gfp_mask may go away, and this function may become non-blocking.
- */
-int try_to_release_page(struct page *page, gfp_t gfp_mask)
-{
- struct address_space * const mapping = page->mapping;
-
- BUG_ON(!PageLocked(page));
- if (PageWriteback(page))
- return 0;
-
- if (mapping && mapping->a_ops->releasepage)
- return mapping->a_ops->releasepage(page, gfp_mask);
- return try_to_free_buffers(page);
-}
-EXPORT_SYMBOL(try_to_release_page);
-
-/**
* block_invalidatepage - invalidate part of all of a buffer-backed page
*
* @page: the page which is affected
@@ -1630,14 +1464,6 @@ out:
}
EXPORT_SYMBOL(block_invalidatepage);
-void do_invalidatepage(struct page *page, unsigned long offset)
-{
- void (*invalidatepage)(struct page *, unsigned long);
- invalidatepage = page->mapping->a_ops->invalidatepage ? :
- block_invalidatepage;
- (*invalidatepage)(page, offset);
-}
-
/*
* We attach and possibly dirty the buffers atomically wrt
* __set_page_dirty_buffers() via private_lock. try_to_free_buffers
diff --git a/fs/char_dev.c b/fs/char_dev.c
index 0009346d827f..a885f46ca001 100644
--- a/fs/char_dev.c
+++ b/fs/char_dev.c
@@ -24,6 +24,7 @@
#ifdef CONFIG_KMOD
#include <linux/kmod.h>
#endif
+#include "internal.h"
/*
* capabilities for /dev/mem, /dev/kmem and similar directly mappable character
@@ -128,13 +129,31 @@ __register_chrdev_region(unsigned int major, unsigned int baseminor,
for (cp = &chrdevs[i]; *cp; cp = &(*cp)->next)
if ((*cp)->major > major ||
- ((*cp)->major == major && (*cp)->baseminor >= baseminor))
+ ((*cp)->major == major &&
+ (((*cp)->baseminor >= baseminor) ||
+ ((*cp)->baseminor + (*cp)->minorct > baseminor))))
break;
- if (*cp && (*cp)->major == major &&
- (*cp)->baseminor < baseminor + minorct) {
- ret = -EBUSY;
- goto out;
+
+ /* Check for overlapping minor ranges. */
+ if (*cp && (*cp)->major == major) {
+ int old_min = (*cp)->baseminor;
+ int old_max = (*cp)->baseminor + (*cp)->minorct - 1;
+ int new_min = baseminor;
+ int new_max = baseminor + minorct - 1;
+
+ /* New driver overlaps from the left. */
+ if (new_max >= old_min && new_max <= old_max) {
+ ret = -EBUSY;
+ goto out;
+ }
+
+ /* New driver overlaps from the right. */
+ if (new_min <= old_max && new_min >= old_min) {
+ ret = -EBUSY;
+ goto out;
+ }
}
+
cd->next = *cp;
*cp = cd;
mutex_unlock(&chrdevs_lock);
@@ -165,6 +184,15 @@ __unregister_chrdev_region(unsigned major, unsigned baseminor, int minorct)
return cd;
}
+/**
+ * register_chrdev_region() - register a range of device numbers
+ * @from: the first in the desired range of device numbers; must include
+ * the major number.
+ * @count: the number of consecutive device numbers required
+ * @name: the name of the device or driver.
+ *
+ * Return value is zero on success, a negative error code on failure.
+ */
int register_chrdev_region(dev_t from, unsigned count, const char *name)
{
struct char_device_struct *cd;
@@ -190,6 +218,17 @@ fail:
return PTR_ERR(cd);
}
+/**
+ * alloc_chrdev_region() - register a range of char device numbers
+ * @dev: output parameter for first assigned number
+ * @baseminor: first of the requested range of minor numbers
+ * @count: the number of minor numbers required
+ * @name: the name of the associated device or driver
+ *
+ * Allocates a range of char device numbers. The major number will be
+ * chosen dynamically, and returned (along with the first minor number)
+ * in @dev. Returns zero or a negative error code.
+ */
int alloc_chrdev_region(dev_t *dev, unsigned baseminor, unsigned count,
const char *name)
{
@@ -259,6 +298,15 @@ out2:
return err;
}
+/**
+ * unregister_chrdev_region() - return a range of device numbers
+ * @from: the first in the range of numbers to unregister
+ * @count: the number of device numbers to unregister
+ *
+ * This function will unregister a range of @count device numbers,
+ * starting with @from. The caller should normally be the one who
+ * allocated those numbers in the first place...
+ */
void unregister_chrdev_region(dev_t from, unsigned count)
{
dev_t to = from + count;
@@ -396,6 +444,16 @@ static int exact_lock(dev_t dev, void *data)
return cdev_get(p) ? 0 : -1;
}
+/**
+ * cdev_add() - add a char device to the system
+ * @p: the cdev structure for the device
+ * @dev: the first device number for which this device is responsible
+ * @count: the number of consecutive minor numbers corresponding to this
+ * device
+ *
+ * cdev_add() adds the device represented by @p to the system, making it
+ * live immediately. A negative error code is returned on failure.
+ */
int cdev_add(struct cdev *p, dev_t dev, unsigned count)
{
p->dev = dev;
@@ -408,6 +466,13 @@ static void cdev_unmap(dev_t dev, unsigned count)
kobj_unmap(cdev_map, dev, count);
}
+/**
+ * cdev_del() - remove a cdev from the system
+ * @p: the cdev structure to be removed
+ *
+ * cdev_del() removes @p from the system, possibly freeing the structure
+ * itself.
+ */
void cdev_del(struct cdev *p)
{
cdev_unmap(p->dev, p->count);
@@ -436,6 +501,11 @@ static struct kobj_type ktype_cdev_dynamic = {
.release = cdev_dynamic_release,
};
+/**
+ * cdev_alloc() - allocate a cdev structure
+ *
+ * Allocates and returns a cdev structure, or NULL on failure.
+ */
struct cdev *cdev_alloc(void)
{
struct cdev *p = kzalloc(sizeof(struct cdev), GFP_KERNEL);
@@ -447,6 +517,14 @@ struct cdev *cdev_alloc(void)
return p;
}
+/**
+ * cdev_init() - initialize a cdev structure
+ * @cdev: the structure to initialize
+ * @fops: the file_operations for this device
+ *
+ * Initializes @cdev, remembering @fops, making it ready to add to the
+ * system with cdev_add().
+ */
void cdev_init(struct cdev *cdev, const struct file_operations *fops)
{
memset(cdev, 0, sizeof *cdev);
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c
index 22bcf4d7e7ae..c00c654f2e11 100644
--- a/fs/cifs/cifsfs.c
+++ b/fs/cifs/cifsfs.c
@@ -480,25 +480,13 @@ cifs_get_sb(struct file_system_type *fs_type,
return simple_set_mnt(mnt, sb);
}
-static ssize_t cifs_file_writev(struct file *file, const struct iovec *iov,
- unsigned long nr_segs, loff_t *ppos)
-{
- struct inode *inode = file->f_dentry->d_inode;
- ssize_t written;
-
- written = generic_file_writev(file, iov, nr_segs, ppos);
- if (!CIFS_I(inode)->clientCanCacheAll)
- filemap_fdatawrite(inode->i_mapping);
- return written;
-}
-
-static ssize_t cifs_file_aio_write(struct kiocb *iocb, const char __user *buf,
- size_t count, loff_t pos)
+static ssize_t cifs_file_aio_write(struct kiocb *iocb, const struct iovec *iov,
+ unsigned long nr_segs, loff_t pos)
{
struct inode *inode = iocb->ki_filp->f_dentry->d_inode;
ssize_t written;
- written = generic_file_aio_write(iocb, buf, count, pos);
+ written = generic_file_aio_write(iocb, iov, nr_segs, pos);
if (!CIFS_I(inode)->clientCanCacheAll)
filemap_fdatawrite(inode->i_mapping);
return written;
@@ -577,8 +565,6 @@ struct inode_operations cifs_symlink_inode_ops = {
const struct file_operations cifs_file_ops = {
.read = do_sync_read,
.write = do_sync_write,
- .readv = generic_file_readv,
- .writev = cifs_file_writev,
.aio_read = generic_file_aio_read,
.aio_write = cifs_file_aio_write,
.open = cifs_open,
@@ -620,8 +606,6 @@ const struct file_operations cifs_file_direct_ops = {
const struct file_operations cifs_file_nobrl_ops = {
.read = do_sync_read,
.write = do_sync_write,
- .readv = generic_file_readv,
- .writev = cifs_file_writev,
.aio_read = generic_file_aio_read,
.aio_write = cifs_file_aio_write,
.open = cifs_open,
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index 0e9ba0b9d71e..c78762051da4 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -772,12 +772,12 @@ cifs_parse_mount_options(char *options, const char *devname,struct smb_vol *vol)
separator[1] = 0;
memset(vol->source_rfc1001_name,0x20,15);
- for(i=0;i < strnlen(system_utsname.nodename,15);i++) {
+ for(i=0;i < strnlen(utsname()->nodename,15);i++) {
/* does not have to be a perfect mapping since the field is
informational, only used for servers that do not support
port 445 and it can be overridden at mount time */
vol->source_rfc1001_name[i] =
- toupper(system_utsname.nodename[i]);
+ toupper(utsname()->nodename[i]);
}
vol->source_rfc1001_name[15] = 0;
/* null target name indicates to use *SMBSERVR default called name
@@ -2153,7 +2153,7 @@ CIFSSessSetup(unsigned int xid, struct cifsSesInfo *ses,
32, nls_codepage);
bcc_ptr += 2 * bytes_returned;
bytes_returned =
- cifs_strtoUCS((__le16 *) bcc_ptr, system_utsname.release,
+ cifs_strtoUCS((__le16 *) bcc_ptr, utsname()->release,
32, nls_codepage);
bcc_ptr += 2 * bytes_returned;
bcc_ptr += 2;
@@ -2180,8 +2180,8 @@ CIFSSessSetup(unsigned int xid, struct cifsSesInfo *ses,
}
strcpy(bcc_ptr, "Linux version ");
bcc_ptr += strlen("Linux version ");
- strcpy(bcc_ptr, system_utsname.release);
- bcc_ptr += strlen(system_utsname.release) + 1;
+ strcpy(bcc_ptr, utsname()->release);
+ bcc_ptr += strlen(utsname()->release) + 1;
strcpy(bcc_ptr, CIFS_NETWORK_OPSYS);
bcc_ptr += strlen(CIFS_NETWORK_OPSYS) + 1;
}
@@ -2445,7 +2445,7 @@ CIFSNTLMSSPNegotiateSessSetup(unsigned int xid,
32, nls_codepage);
bcc_ptr += 2 * bytes_returned;
bytes_returned =
- cifs_strtoUCS((__le16 *) bcc_ptr, system_utsname.release, 32,
+ cifs_strtoUCS((__le16 *) bcc_ptr, utsname()->release, 32,
nls_codepage);
bcc_ptr += 2 * bytes_returned;
bcc_ptr += 2; /* null terminate Linux version */
@@ -2462,8 +2462,8 @@ CIFSNTLMSSPNegotiateSessSetup(unsigned int xid,
} else { /* ASCII */
strcpy(bcc_ptr, "Linux version ");
bcc_ptr += strlen("Linux version ");
- strcpy(bcc_ptr, system_utsname.release);
- bcc_ptr += strlen(system_utsname.release) + 1;
+ strcpy(bcc_ptr, utsname()->release);
+ bcc_ptr += strlen(utsname()->release) + 1;
strcpy(bcc_ptr, CIFS_NETWORK_OPSYS);
bcc_ptr += strlen(CIFS_NETWORK_OPSYS) + 1;
bcc_ptr++; /* empty domain field */
@@ -2836,7 +2836,7 @@ CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses,
32, nls_codepage);
bcc_ptr += 2 * bytes_returned;
bytes_returned =
- cifs_strtoUCS((__le16 *) bcc_ptr, system_utsname.release, 32,
+ cifs_strtoUCS((__le16 *) bcc_ptr, utsname()->release, 32,
nls_codepage);
bcc_ptr += 2 * bytes_returned;
bcc_ptr += 2; /* null term version string */
@@ -2888,8 +2888,8 @@ CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses,
strcpy(bcc_ptr, "Linux version ");
bcc_ptr += strlen("Linux version ");
- strcpy(bcc_ptr, system_utsname.release);
- bcc_ptr += strlen(system_utsname.release) + 1;
+ strcpy(bcc_ptr, utsname()->release);
+ bcc_ptr += strlen(utsname()->release) + 1;
strcpy(bcc_ptr, CIFS_NETWORK_OPSYS);
bcc_ptr += strlen(CIFS_NETWORK_OPSYS) + 1;
bcc_ptr++; /* null domain */
diff --git a/fs/cifs/file.c b/fs/cifs/file.c
index ddb012a68023..976a691c5a68 100644
--- a/fs/cifs/file.c
+++ b/fs/cifs/file.c
@@ -25,7 +25,6 @@
#include <linux/backing-dev.h>
#include <linux/stat.h>
#include <linux/fcntl.h>
-#include <linux/mpage.h>
#include <linux/pagemap.h>
#include <linux/pagevec.h>
#include <linux/smp_lock.h>
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c
index b88147c1dc27..6b90ef98e4cf 100644
--- a/fs/cifs/inode.c
+++ b/fs/cifs/inode.c
@@ -19,7 +19,6 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <linux/fs.h>
-#include <linux/buffer_head.h>
#include <linux/stat.h>
#include <linux/pagemap.h>
#include <asm/div64.h>
@@ -591,7 +590,7 @@ int cifs_unlink(struct inode *inode, struct dentry *direntry)
if (!rc) {
if (direntry->d_inode)
- direntry->d_inode->i_nlink--;
+ drop_nlink(direntry->d_inode);
} else if (rc == -ENOENT) {
d_drop(direntry);
} else if (rc == -ETXTBSY) {
@@ -610,7 +609,7 @@ int cifs_unlink(struct inode *inode, struct dentry *direntry)
CIFS_MOUNT_MAP_SPECIAL_CHR);
CIFSSMBClose(xid, pTcon, netfid);
if (direntry->d_inode)
- direntry->d_inode->i_nlink--;
+ drop_nlink(direntry->d_inode);
}
} else if (rc == -EACCES) {
/* try only if r/o attribute set in local lookup data? */
@@ -664,7 +663,7 @@ int cifs_unlink(struct inode *inode, struct dentry *direntry)
CIFS_MOUNT_MAP_SPECIAL_CHR);
if (!rc) {
if (direntry->d_inode)
- direntry->d_inode->i_nlink--;
+ drop_nlink(direntry->d_inode);
} else if (rc == -ETXTBSY) {
int oplock = FALSE;
__u16 netfid;
@@ -685,7 +684,7 @@ int cifs_unlink(struct inode *inode, struct dentry *direntry)
CIFS_MOUNT_MAP_SPECIAL_CHR);
CIFSSMBClose(xid, pTcon, netfid);
if (direntry->d_inode)
- direntry->d_inode->i_nlink--;
+ drop_nlink(direntry->d_inode);
}
/* BB if rc = -ETXTBUSY goto the rename logic BB */
}
@@ -736,7 +735,7 @@ int cifs_mkdir(struct inode *inode, struct dentry *direntry, int mode)
cFYI(1, ("cifs_mkdir returned 0x%x", rc));
d_drop(direntry);
} else {
- inode->i_nlink++;
+ inc_nlink(inode);
if (pTcon->ses->capabilities & CAP_UNIX)
rc = cifs_get_inode_info_unix(&newinode, full_path,
inode->i_sb,xid);
@@ -817,9 +816,9 @@ int cifs_rmdir(struct inode *inode, struct dentry *direntry)
cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
if (!rc) {
- inode->i_nlink--;
+ drop_nlink(inode);
i_size_write(direntry->d_inode,0);
- direntry->d_inode->i_nlink = 0;
+ clear_nlink(direntry->d_inode);
}
cifsInode = CIFS_I(direntry->d_inode);
diff --git a/fs/cifs/ioctl.c b/fs/cifs/ioctl.c
index b0ea6687ab55..e34c7db00f6f 100644
--- a/fs/cifs/ioctl.c
+++ b/fs/cifs/ioctl.c
@@ -22,7 +22,6 @@
*/
#include <linux/fs.h>
-#include <linux/ext2_fs.h>
#include "cifspdu.h"
#include "cifsglob.h"
#include "cifsproto.h"
@@ -74,7 +73,7 @@ int cifs_ioctl (struct inode * inode, struct file * filep,
}
break;
#ifdef CONFIG_CIFS_POSIX
- case EXT2_IOC_GETFLAGS:
+ case FS_IOC_GETFLAGS:
if(CIFS_UNIX_EXTATTR_CAP & caps) {
if (pSMBFile == NULL)
break;
@@ -82,12 +81,12 @@ int cifs_ioctl (struct inode * inode, struct file * filep,
&ExtAttrBits, &ExtAttrMask);
if(rc == 0)
rc = put_user(ExtAttrBits &
- EXT2_FL_USER_VISIBLE,
+ FS_FL_USER_VISIBLE,
(int __user *)arg);
}
break;
- case EXT2_IOC_SETFLAGS:
+ case FS_IOC_SETFLAGS:
if(CIFS_UNIX_EXTATTR_CAP & caps) {
if(get_user(ExtAttrBits,(int __user *)arg)) {
rc = -EFAULT;
diff --git a/fs/cifs/sess.c b/fs/cifs/sess.c
index d1705ab8136e..22b4c35dcfe3 100644
--- a/fs/cifs/sess.c
+++ b/fs/cifs/sess.c
@@ -111,7 +111,7 @@ static void unicode_ssetup_strings(char ** pbcc_area, struct cifsSesInfo *ses,
bytes_ret = cifs_strtoUCS((__le16 *)bcc_ptr, "Linux version ", 32,
nls_cp);
bcc_ptr += 2 * bytes_ret;
- bytes_ret = cifs_strtoUCS((__le16 *) bcc_ptr, system_utsname.release,
+ bytes_ret = cifs_strtoUCS((__le16 *) bcc_ptr, init_utsname()->release,
32, nls_cp);
bcc_ptr += 2 * bytes_ret;
bcc_ptr += 2; /* trailing null */
@@ -158,8 +158,8 @@ static void ascii_ssetup_strings(char ** pbcc_area, struct cifsSesInfo *ses,
strcpy(bcc_ptr, "Linux version ");
bcc_ptr += strlen("Linux version ");
- strcpy(bcc_ptr, system_utsname.release);
- bcc_ptr += strlen(system_utsname.release) + 1;
+ strcpy(bcc_ptr, init_utsname()->release);
+ bcc_ptr += strlen(init_utsname()->release) + 1;
strcpy(bcc_ptr, CIFS_NETWORK_OPSYS);
bcc_ptr += strlen(CIFS_NETWORK_OPSYS) + 1;
diff --git a/fs/coda/dir.c b/fs/coda/dir.c
index 8651ea6a23b7..0102b28a15fb 100644
--- a/fs/coda/dir.c
+++ b/fs/coda/dir.c
@@ -304,7 +304,7 @@ static int coda_link(struct dentry *source_de, struct inode *dir_inode,
coda_dir_changed(dir_inode, 0);
atomic_inc(&inode->i_count);
d_instantiate(de, inode);
- inode->i_nlink++;
+ inc_nlink(inode);
out:
unlock_kernel();
@@ -367,7 +367,7 @@ int coda_unlink(struct inode *dir, struct dentry *de)
}
coda_dir_changed(dir, 0);
- de->d_inode->i_nlink--;
+ drop_nlink(de->d_inode);
unlock_kernel();
return 0;
@@ -394,7 +394,7 @@ int coda_rmdir(struct inode *dir, struct dentry *de)
}
coda_dir_changed(dir, -1);
- de->d_inode->i_nlink--;
+ drop_nlink(de->d_inode);
d_delete(de);
unlock_kernel();
diff --git a/fs/compat.c b/fs/compat.c
index ce982f6e8c80..4d3fbcb2ddb1 100644
--- a/fs/compat.c
+++ b/fs/compat.c
@@ -44,7 +44,7 @@
#include <linux/nfsd/syscall.h>
#include <linux/personality.h>
#include <linux/rwsem.h>
-#include <linux/acct.h>
+#include <linux/tsacct_kern.h>
#include <linux/mm.h>
#include <net/sock.h> /* siocdevprivate_ioctl */
@@ -52,8 +52,7 @@
#include <asm/uaccess.h>
#include <asm/mmu_context.h>
#include <asm/ioctls.h>
-
-extern void sigset_from_compat(sigset_t *set, compat_sigset_t *compat);
+#include "internal.h"
int compat_log = 1;
@@ -69,6 +68,8 @@ int compat_printk(const char *fmt, ...)
return ret;
}
+#include "read_write.h"
+
/*
* Not all architectures have sys_utime, so implement this in terms
* of sys_utimes.
@@ -313,9 +314,6 @@ out:
#define IOCTL_HASHSIZE 256
static struct ioctl_trans *ioctl32_hash_table[IOCTL_HASHSIZE];
-extern struct ioctl_trans ioctl_start[];
-extern int ioctl_table_size;
-
static inline unsigned long ioctl32_hash(unsigned long cmd)
{
return (((cmd >> 6) ^ (cmd >> 4) ^ cmd)) % IOCTL_HASHSIZE;
@@ -838,8 +836,6 @@ static int do_nfs4_super_data_conv(void *raw_data)
return 0;
}
-extern int copy_mount_options (const void __user *, unsigned long *);
-
#define SMBFS_NAME "smbfs"
#define NCPFS_NAME "ncpfs"
#define NFS4_NAME "nfs4"
@@ -918,20 +914,24 @@ struct compat_readdir_callback {
};
static int compat_fillonedir(void *__buf, const char *name, int namlen,
- loff_t offset, ino_t ino, unsigned int d_type)
+ loff_t offset, u64 ino, unsigned int d_type)
{
struct compat_readdir_callback *buf = __buf;
struct compat_old_linux_dirent __user *dirent;
+ compat_ulong_t d_ino;
if (buf->result)
return -EINVAL;
+ d_ino = ino;
+ if (sizeof(d_ino) < sizeof(ino) && d_ino != ino)
+ return -EOVERFLOW;
buf->result++;
dirent = buf->dirent;
if (!access_ok(VERIFY_WRITE, dirent,
(unsigned long)(dirent->d_name + namlen + 1) -
(unsigned long)dirent))
goto efault;
- if ( __put_user(ino, &dirent->d_ino) ||
+ if ( __put_user(d_ino, &dirent->d_ino) ||
__put_user(offset, &dirent->d_offset) ||
__put_user(namlen, &dirent->d_namlen) ||
__copy_to_user(dirent->d_name, name, namlen) ||
@@ -982,22 +982,26 @@ struct compat_getdents_callback {
};
static int compat_filldir(void *__buf, const char *name, int namlen,
- loff_t offset, ino_t ino, unsigned int d_type)
+ loff_t offset, u64 ino, unsigned int d_type)
{
struct compat_linux_dirent __user * dirent;
struct compat_getdents_callback *buf = __buf;
+ compat_ulong_t d_ino;
int reclen = COMPAT_ROUND_UP(NAME_OFFSET(dirent) + namlen + 2);
buf->error = -EINVAL; /* only used if we fail.. */
if (reclen > buf->count)
return -EINVAL;
+ d_ino = ino;
+ if (sizeof(d_ino) < sizeof(ino) && d_ino != ino)
+ return -EOVERFLOW;
dirent = buf->previous;
if (dirent) {
if (__put_user(offset, &dirent->d_off))
goto efault;
}
dirent = buf->current_dir;
- if (__put_user(ino, &dirent->d_ino))
+ if (__put_user(d_ino, &dirent->d_ino))
goto efault;
if (__put_user(reclen, &dirent->d_reclen))
goto efault;
@@ -1068,7 +1072,7 @@ struct compat_getdents_callback64 {
};
static int compat_filldir64(void * __buf, const char * name, int namlen, loff_t offset,
- ino_t ino, unsigned int d_type)
+ u64 ino, unsigned int d_type)
{
struct linux_dirent64 __user *dirent;
struct compat_getdents_callback64 *buf = __buf;
@@ -1153,9 +1157,6 @@ static ssize_t compat_do_readv_writev(int type, struct file *file,
const struct compat_iovec __user *uvector,
unsigned long nr_segs, loff_t *pos)
{
- typedef ssize_t (*io_fn_t)(struct file *, char __user *, size_t, loff_t *);
- typedef ssize_t (*iov_fn_t)(struct file *, const struct iovec *, unsigned long, loff_t *);
-
compat_ssize_t tot_len;
struct iovec iovstack[UIO_FASTIOV];
struct iovec *iov=iovstack, *vector;
@@ -1238,39 +1239,18 @@ static ssize_t compat_do_readv_writev(int type, struct file *file,
fnv = NULL;
if (type == READ) {
fn = file->f_op->read;
- fnv = file->f_op->readv;
+ fnv = file->f_op->aio_read;
} else {
fn = (io_fn_t)file->f_op->write;
- fnv = file->f_op->writev;
- }
- if (fnv) {
- ret = fnv(file, iov, nr_segs, pos);
- goto out;
+ fnv = file->f_op->aio_write;
}
- /* Do it by hand, with file-ops */
- ret = 0;
- vector = iov;
- while (nr_segs > 0) {
- void __user * base;
- size_t len;
- ssize_t nr;
-
- base = vector->iov_base;
- len = vector->iov_len;
- vector++;
- nr_segs--;
-
- nr = fn(file, base, len, pos);
+ if (fnv)
+ ret = do_sync_readv_writev(file, iov, nr_segs, tot_len,
+ pos, fnv);
+ else
+ ret = do_loop_readv_writev(file, iov, nr_segs, pos, fn);
- if (nr < 0) {
- if (!ret) ret = nr;
- break;
- }
- ret += nr;
- if (nr != len)
- break;
- }
out:
if (iov != iovstack)
kfree(iov);
@@ -1298,7 +1278,7 @@ compat_sys_readv(unsigned long fd, const struct compat_iovec __user *vec, unsign
goto out;
ret = -EINVAL;
- if (!file->f_op || (!file->f_op->readv && !file->f_op->read))
+ if (!file->f_op || (!file->f_op->aio_read && !file->f_op->read))
goto out;
ret = compat_do_readv_writev(READ, file, vec, vlen, &file->f_pos);
@@ -1321,7 +1301,7 @@ compat_sys_writev(unsigned long fd, const struct compat_iovec __user *vec, unsig
goto out;
ret = -EINVAL;
- if (!file->f_op || (!file->f_op->writev && !file->f_op->write))
+ if (!file->f_op || (!file->f_op->aio_write && !file->f_op->write))
goto out;
ret = compat_do_readv_writev(WRITE, file, vec, vlen, &file->f_pos);
diff --git a/fs/compat_ioctl.c b/fs/compat_ioctl.c
index 4063a9396977..27ca1aa30562 100644
--- a/fs/compat_ioctl.c
+++ b/fs/compat_ioctl.c
@@ -40,15 +40,11 @@
#include <linux/if_pppox.h>
#include <linux/mtio.h>
#include <linux/cdrom.h>
-#include <linux/loop.h>
#include <linux/auto_fs.h>
#include <linux/auto_fs4.h>
#include <linux/tty.h>
#include <linux/vt_kern.h>
#include <linux/fb.h>
-#include <linux/ext2_fs.h>
-#include <linux/ext3_jbd.h>
-#include <linux/ext3_fs.h>
#include <linux/videodev.h>
#include <linux/netdevice.h>
#include <linux/raw.h>
@@ -60,12 +56,10 @@
#include <linux/pci.h>
#include <linux/module.h>
#include <linux/serial.h>
-#include <linux/reiserfs_fs.h>
#include <linux/if_tun.h>
#include <linux/ctype.h>
#include <linux/ioctl32.h>
#include <linux/syscalls.h>
-#include <linux/ncp_fs.h>
#include <linux/i2c.h>
#include <linux/i2c-dev.h>
#include <linux/wireless.h>
@@ -113,7 +107,6 @@
#include <linux/nbd.h>
#include <linux/random.h>
#include <linux/filter.h>
-#include <linux/msdos_fs.h>
#include <linux/pktcdvd.h>
#include <linux/hiddev.h>
@@ -124,21 +117,6 @@
#include <linux/dvb/video.h>
#include <linux/lp.h>
-/* Aiee. Someone does not find a difference between int and long */
-#define EXT2_IOC32_GETFLAGS _IOR('f', 1, int)
-#define EXT2_IOC32_SETFLAGS _IOW('f', 2, int)
-#define EXT3_IOC32_GETVERSION _IOR('f', 3, int)
-#define EXT3_IOC32_SETVERSION _IOW('f', 4, int)
-#define EXT3_IOC32_GETRSVSZ _IOR('f', 5, int)
-#define EXT3_IOC32_SETRSVSZ _IOW('f', 6, int)
-#define EXT3_IOC32_GROUP_EXTEND _IOW('f', 7, unsigned int)
-#ifdef CONFIG_JBD_DEBUG
-#define EXT3_IOC32_WAIT_FOR_READONLY _IOR('f', 99, int)
-#endif
-
-#define EXT2_IOC32_GETVERSION _IOR('v', 1, int)
-#define EXT2_IOC32_SETVERSION _IOW('v', 2, int)
-
static int do_ioctl32_pointer(unsigned int fd, unsigned int cmd,
unsigned long arg, struct file *f)
{
@@ -176,34 +154,6 @@ static int rw_long(unsigned int fd, unsigned int cmd, unsigned long arg)
return err;
}
-static int do_ext2_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
-{
- /* These are just misnamed, they actually get/put from/to user an int */
- switch (cmd) {
- case EXT2_IOC32_GETFLAGS: cmd = EXT2_IOC_GETFLAGS; break;
- case EXT2_IOC32_SETFLAGS: cmd = EXT2_IOC_SETFLAGS; break;
- case EXT2_IOC32_GETVERSION: cmd = EXT2_IOC_GETVERSION; break;
- case EXT2_IOC32_SETVERSION: cmd = EXT2_IOC_SETVERSION; break;
- }
- return sys_ioctl(fd, cmd, (unsigned long)compat_ptr(arg));
-}
-
-static int do_ext3_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
-{
- /* These are just misnamed, they actually get/put from/to user an int */
- switch (cmd) {
- case EXT3_IOC32_GETVERSION: cmd = EXT3_IOC_GETVERSION; break;
- case EXT3_IOC32_SETVERSION: cmd = EXT3_IOC_SETVERSION; break;
- case EXT3_IOC32_GETRSVSZ: cmd = EXT3_IOC_GETRSVSZ; break;
- case EXT3_IOC32_SETRSVSZ: cmd = EXT3_IOC_SETRSVSZ; break;
- case EXT3_IOC32_GROUP_EXTEND: cmd = EXT3_IOC_GROUP_EXTEND; break;
-#ifdef CONFIG_JBD_DEBUG
- case EXT3_IOC32_WAIT_FOR_READONLY: cmd = EXT3_IOC_WAIT_FOR_READONLY; break;
-#endif
- }
- return sys_ioctl(fd, cmd, (unsigned long)compat_ptr(arg));
-}
-
struct compat_video_event {
int32_t type;
compat_time_t timestamp;
@@ -694,6 +644,7 @@ out:
}
#endif
+#ifdef CONFIG_BLOCK
struct hd_geometry32 {
unsigned char heads;
unsigned char sectors;
@@ -918,6 +869,7 @@ static int sg_grt_trans(unsigned int fd, unsigned int cmd, unsigned long arg)
}
return err;
}
+#endif /* CONFIG_BLOCK */
struct sock_fprog32 {
unsigned short len;
@@ -1041,6 +993,7 @@ static int ppp_ioctl_trans(unsigned int fd, unsigned int cmd, unsigned long arg)
}
+#ifdef CONFIG_BLOCK
struct mtget32 {
compat_long_t mt_type;
compat_long_t mt_resid;
@@ -1213,73 +1166,7 @@ static int cdrom_ioctl_trans(unsigned int fd, unsigned int cmd, unsigned long ar
return err;
}
-
-struct loop_info32 {
- compat_int_t lo_number; /* ioctl r/o */
- compat_dev_t lo_device; /* ioctl r/o */
- compat_ulong_t lo_inode; /* ioctl r/o */
- compat_dev_t lo_rdevice; /* ioctl r/o */
- compat_int_t lo_offset;
- compat_int_t lo_encrypt_type;
- compat_int_t lo_encrypt_key_size; /* ioctl w/o */
- compat_int_t lo_flags; /* ioctl r/o */
- char lo_name[LO_NAME_SIZE];
- unsigned char lo_encrypt_key[LO_KEY_SIZE]; /* ioctl w/o */
- compat_ulong_t lo_init[2];
- char reserved[4];
-};
-
-static int loop_status(unsigned int fd, unsigned int cmd, unsigned long arg)
-{
- mm_segment_t old_fs = get_fs();
- struct loop_info l;
- struct loop_info32 __user *ul;
- int err = -EINVAL;
-
- ul = compat_ptr(arg);
- switch(cmd) {
- case LOOP_SET_STATUS:
- err = get_user(l.lo_number, &ul->lo_number);
- err |= __get_user(l.lo_device, &ul->lo_device);
- err |= __get_user(l.lo_inode, &ul->lo_inode);
- err |= __get_user(l.lo_rdevice, &ul->lo_rdevice);
- err |= __copy_from_user(&l.lo_offset, &ul->lo_offset,
- 8 + (unsigned long)l.lo_init - (unsigned long)&l.lo_offset);
- if (err) {
- err = -EFAULT;
- } else {
- set_fs (KERNEL_DS);
- err = sys_ioctl (fd, cmd, (unsigned long)&l);
- set_fs (old_fs);
- }
- break;
- case LOOP_GET_STATUS:
- set_fs (KERNEL_DS);
- err = sys_ioctl (fd, cmd, (unsigned long)&l);
- set_fs (old_fs);
- if (!err) {
- err = put_user(l.lo_number, &ul->lo_number);
- err |= __put_user(l.lo_device, &ul->lo_device);
- err |= __put_user(l.lo_inode, &ul->lo_inode);
- err |= __put_user(l.lo_rdevice, &ul->lo_rdevice);
- err |= __copy_to_user(&ul->lo_offset, &l.lo_offset,
- (unsigned long)l.lo_init - (unsigned long)&l.lo_offset);
- if (err)
- err = -EFAULT;
- }
- break;
- default: {
- static int count;
- if (++count <= 20)
- printk("%s: Unknown loop ioctl cmd, fd(%d) "
- "cmd(%08x) arg(%08lx)\n",
- __FUNCTION__, fd, cmd, arg);
- }
- }
- return err;
-}
-
-extern int tty_ioctl(struct inode * inode, struct file * file, unsigned int cmd, unsigned long arg);
+#endif /* CONFIG_BLOCK */
#ifdef CONFIG_VT
@@ -1607,6 +1494,7 @@ ret_einval(unsigned int fd, unsigned int cmd, unsigned long arg)
return -EINVAL;
}
+#ifdef CONFIG_BLOCK
static int broken_blkgetsize(unsigned int fd, unsigned int cmd, unsigned long arg)
{
/* The mkswap binary hard codes it to Intel value :-((( */
@@ -1641,12 +1529,14 @@ static int blkpg_ioctl_trans(unsigned int fd, unsigned int cmd, unsigned long ar
return sys_ioctl(fd, cmd, (unsigned long)a);
}
+#endif
static int ioc_settimeout(unsigned int fd, unsigned int cmd, unsigned long arg)
{
return rw_long(fd, AUTOFS_IOC_SETTIMEOUT, arg);
}
+#ifdef CONFIG_BLOCK
/* Fix sizeof(sizeof()) breakage */
#define BLKBSZGET_32 _IOR(0x12,112,int)
#define BLKBSZSET_32 _IOW(0x12,113,int)
@@ -1667,6 +1557,7 @@ static int do_blkgetsize64(unsigned int fd, unsigned int cmd,
{
return sys_ioctl(fd, BLKGETSIZE64, (unsigned long)compat_ptr(arg));
}
+#endif
/* Bluetooth ioctls */
#define HCIUARTSETPROTO _IOW('U', 200, int)
@@ -1687,6 +1578,7 @@ static int do_blkgetsize64(unsigned int fd, unsigned int cmd,
#define HIDPGETCONNLIST _IOR('H', 210, int)
#define HIDPGETCONNINFO _IOR('H', 211, int)
+#ifdef CONFIG_BLOCK
struct floppy_struct32 {
compat_uint_t size;
compat_uint_t sect;
@@ -2011,6 +1903,7 @@ out:
kfree(karg);
return err;
}
+#endif
struct mtd_oob_buf32 {
u_int32_t start;
@@ -2052,61 +1945,7 @@ static int mtd_rw_oob(unsigned int fd, unsigned int cmd, unsigned long arg)
return err;
}
-#define VFAT_IOCTL_READDIR_BOTH32 _IOR('r', 1, struct compat_dirent[2])
-#define VFAT_IOCTL_READDIR_SHORT32 _IOR('r', 2, struct compat_dirent[2])
-
-static long
-put_dirent32 (struct dirent *d, struct compat_dirent __user *d32)
-{
- if (!access_ok(VERIFY_WRITE, d32, sizeof(struct compat_dirent)))
- return -EFAULT;
-
- __put_user(d->d_ino, &d32->d_ino);
- __put_user(d->d_off, &d32->d_off);
- __put_user(d->d_reclen, &d32->d_reclen);
- if (__copy_to_user(d32->d_name, d->d_name, d->d_reclen))
- return -EFAULT;
-
- return 0;
-}
-
-static int vfat_ioctl32(unsigned fd, unsigned cmd, unsigned long arg)
-{
- struct compat_dirent __user *p = compat_ptr(arg);
- int ret;
- mm_segment_t oldfs = get_fs();
- struct dirent d[2];
-
- switch(cmd)
- {
- case VFAT_IOCTL_READDIR_BOTH32:
- cmd = VFAT_IOCTL_READDIR_BOTH;
- break;
- case VFAT_IOCTL_READDIR_SHORT32:
- cmd = VFAT_IOCTL_READDIR_SHORT;
- break;
- }
-
- set_fs(KERNEL_DS);
- ret = sys_ioctl(fd,cmd,(unsigned long)&d);
- set_fs(oldfs);
- if (ret >= 0) {
- ret |= put_dirent32(&d[0], p);
- ret |= put_dirent32(&d[1], p + 1);
- }
- return ret;
-}
-
-#define REISERFS_IOC_UNPACK32 _IOW(0xCD,1,int)
-
-static int reiserfs_ioctl32(unsigned fd, unsigned cmd, unsigned long ptr)
-{
- if (cmd == REISERFS_IOC_UNPACK32)
- cmd = REISERFS_IOC_UNPACK;
-
- return sys_ioctl(fd,cmd,ptr);
-}
-
+#ifdef CONFIG_BLOCK
struct raw32_config_request
{
compat_int_t raw_minor;
@@ -2171,6 +2010,7 @@ static int raw_ioctl(unsigned fd, unsigned cmd, unsigned long arg)
}
return ret;
}
+#endif /* CONFIG_BLOCK */
struct serial_struct32 {
compat_int_t type;
@@ -2507,193 +2347,6 @@ static int rtc_ioctl(unsigned fd, unsigned cmd, unsigned long arg)
}
}
-#if defined(CONFIG_NCP_FS) || defined(CONFIG_NCP_FS_MODULE)
-struct ncp_ioctl_request_32 {
- u32 function;
- u32 size;
- compat_caddr_t data;
-};
-
-struct ncp_fs_info_v2_32 {
- s32 version;
- u32 mounted_uid;
- u32 connection;
- u32 buffer_size;
-
- u32 volume_number;
- u32 directory_id;
-
- u32 dummy1;
- u32 dummy2;
- u32 dummy3;
-};
-
-struct ncp_objectname_ioctl_32
-{
- s32 auth_type;
- u32 object_name_len;
- compat_caddr_t object_name; /* an userspace data, in most cases user name */
-};
-
-struct ncp_privatedata_ioctl_32
-{
- u32 len;
- compat_caddr_t data; /* ~1000 for NDS */
-};
-
-#define NCP_IOC_NCPREQUEST_32 _IOR('n', 1, struct ncp_ioctl_request_32)
-#define NCP_IOC_GETMOUNTUID2_32 _IOW('n', 2, u32)
-#define NCP_IOC_GET_FS_INFO_V2_32 _IOWR('n', 4, struct ncp_fs_info_v2_32)
-#define NCP_IOC_GETOBJECTNAME_32 _IOWR('n', 9, struct ncp_objectname_ioctl_32)
-#define NCP_IOC_SETOBJECTNAME_32 _IOR('n', 9, struct ncp_objectname_ioctl_32)
-#define NCP_IOC_GETPRIVATEDATA_32 _IOWR('n', 10, struct ncp_privatedata_ioctl_32)
-#define NCP_IOC_SETPRIVATEDATA_32 _IOR('n', 10, struct ncp_privatedata_ioctl_32)
-
-static int do_ncp_ncprequest(unsigned int fd, unsigned int cmd, unsigned long arg)
-{
- struct ncp_ioctl_request_32 n32;
- struct ncp_ioctl_request __user *p = compat_alloc_user_space(sizeof(*p));
-
- if (copy_from_user(&n32, compat_ptr(arg), sizeof(n32)) ||
- put_user(n32.function, &p->function) ||
- put_user(n32.size, &p->size) ||
- put_user(compat_ptr(n32.data), &p->data))
- return -EFAULT;
-
- return sys_ioctl(fd, NCP_IOC_NCPREQUEST, (unsigned long)p);
-}
-
-static int do_ncp_getmountuid2(unsigned int fd, unsigned int cmd, unsigned long arg)
-{
- mm_segment_t old_fs = get_fs();
- __kernel_uid_t kuid;
- int err;
-
- cmd = NCP_IOC_GETMOUNTUID2;
-
- set_fs(KERNEL_DS);
- err = sys_ioctl(fd, cmd, (unsigned long)&kuid);
- set_fs(old_fs);
-
- if (!err)
- err = put_user(kuid,
- (unsigned int __user *) compat_ptr(arg));
-
- return err;
-}
-
-static int do_ncp_getfsinfo2(unsigned int fd, unsigned int cmd, unsigned long arg)
-{
- mm_segment_t old_fs = get_fs();
- struct ncp_fs_info_v2_32 n32;
- struct ncp_fs_info_v2 n;
- int err;
-
- if (copy_from_user(&n32, compat_ptr(arg), sizeof(n32)))
- return -EFAULT;
- if (n32.version != NCP_GET_FS_INFO_VERSION_V2)
- return -EINVAL;
- n.version = NCP_GET_FS_INFO_VERSION_V2;
-
- set_fs(KERNEL_DS);
- err = sys_ioctl(fd, NCP_IOC_GET_FS_INFO_V2, (unsigned long)&n);
- set_fs(old_fs);
-
- if (!err) {
- n32.version = n.version;
- n32.mounted_uid = n.mounted_uid;
- n32.connection = n.connection;
- n32.buffer_size = n.buffer_size;
- n32.volume_number = n.volume_number;
- n32.directory_id = n.directory_id;
- n32.dummy1 = n.dummy1;
- n32.dummy2 = n.dummy2;
- n32.dummy3 = n.dummy3;
- err = copy_to_user(compat_ptr(arg), &n32, sizeof(n32)) ? -EFAULT : 0;
- }
- return err;
-}
-
-static int do_ncp_getobjectname(unsigned int fd, unsigned int cmd, unsigned long arg)
-{
- struct ncp_objectname_ioctl_32 n32, __user *p32 = compat_ptr(arg);
- struct ncp_objectname_ioctl __user *p = compat_alloc_user_space(sizeof(*p));
- s32 auth_type;
- u32 name_len;
- int err;
-
- if (copy_from_user(&n32, p32, sizeof(n32)) ||
- put_user(n32.object_name_len, &p->object_name_len) ||
- put_user(compat_ptr(n32.object_name), &p->object_name))
- return -EFAULT;
-
- err = sys_ioctl(fd, NCP_IOC_GETOBJECTNAME, (unsigned long)p);
- if (err)
- return err;
-
- if (get_user(auth_type, &p->auth_type) ||
- put_user(auth_type, &p32->auth_type) ||
- get_user(name_len, &p->object_name_len) ||
- put_user(name_len, &p32->object_name_len))
- return -EFAULT;
-
- return 0;
-}
-
-static int do_ncp_setobjectname(unsigned int fd, unsigned int cmd, unsigned long arg)
-{
- struct ncp_objectname_ioctl_32 n32, __user *p32 = compat_ptr(arg);
- struct ncp_objectname_ioctl __user *p = compat_alloc_user_space(sizeof(*p));
-
- if (copy_from_user(&n32, p32, sizeof(n32)) ||
- put_user(n32.auth_type, &p->auth_type) ||
- put_user(n32.object_name_len, &p->object_name_len) ||
- put_user(compat_ptr(n32.object_name), &p->object_name))
- return -EFAULT;
-
- return sys_ioctl(fd, NCP_IOC_SETOBJECTNAME, (unsigned long)p);
-}
-
-static int do_ncp_getprivatedata(unsigned int fd, unsigned int cmd, unsigned long arg)
-{
- struct ncp_privatedata_ioctl_32 n32, __user *p32 = compat_ptr(arg);
- struct ncp_privatedata_ioctl __user *p =
- compat_alloc_user_space(sizeof(*p));
- u32 len;
- int err;
-
- if (copy_from_user(&n32, p32, sizeof(n32)) ||
- put_user(n32.len, &p->len) ||
- put_user(compat_ptr(n32.data), &p->data))
- return -EFAULT;
-
- err = sys_ioctl(fd, NCP_IOC_GETPRIVATEDATA, (unsigned long)p);
- if (err)
- return err;
-
- if (get_user(len, &p->len) ||
- put_user(len, &p32->len))
- return -EFAULT;
-
- return 0;
-}
-
-static int do_ncp_setprivatedata(unsigned int fd, unsigned int cmd, unsigned long arg)
-{
- struct ncp_privatedata_ioctl_32 n32;
- struct ncp_privatedata_ioctl_32 __user *p32 = compat_ptr(arg);
- struct ncp_privatedata_ioctl __user *p =
- compat_alloc_user_space(sizeof(*p));
-
- if (copy_from_user(&n32, p32, sizeof(n32)) ||
- put_user(n32.len, &p->len) ||
- put_user(compat_ptr(n32.data), &p->data))
- return -EFAULT;
-
- return sys_ioctl(fd, NCP_IOC_SETPRIVATEDATA, (unsigned long)p);
-}
-#endif
-
static int
lp_timeout_trans(unsigned int fd, unsigned int cmd, unsigned long arg)
{
@@ -2777,6 +2430,7 @@ HANDLE_IOCTL(SIOCBRDELIF, dev_ifsioc)
HANDLE_IOCTL(SIOCRTMSG, ret_einval)
HANDLE_IOCTL(SIOCGSTAMP, do_siocgstamp)
#endif
+#ifdef CONFIG_BLOCK
HANDLE_IOCTL(HDIO_GETGEO, hdio_getgeo)
HANDLE_IOCTL(BLKRAGET, w_long)
HANDLE_IOCTL(BLKGETSIZE, w_long)
@@ -2802,16 +2456,17 @@ HANDLE_IOCTL(FDGETFDCSTAT32, fd_ioctl_trans)
HANDLE_IOCTL(FDWERRORGET32, fd_ioctl_trans)
HANDLE_IOCTL(SG_IO,sg_ioctl_trans)
HANDLE_IOCTL(SG_GET_REQUEST_TABLE, sg_grt_trans)
+#endif
HANDLE_IOCTL(PPPIOCGIDLE32, ppp_ioctl_trans)
HANDLE_IOCTL(PPPIOCSCOMPRESS32, ppp_ioctl_trans)
HANDLE_IOCTL(PPPIOCSPASS32, ppp_sock_fprog_ioctl_trans)
HANDLE_IOCTL(PPPIOCSACTIVE32, ppp_sock_fprog_ioctl_trans)
+#ifdef CONFIG_BLOCK
HANDLE_IOCTL(MTIOCGET32, mt_ioctl_trans)
HANDLE_IOCTL(MTIOCPOS32, mt_ioctl_trans)
HANDLE_IOCTL(CDROMREADAUDIO, cdrom_ioctl_trans)
HANDLE_IOCTL(CDROM_SEND_PACKET, cdrom_ioctl_trans)
-HANDLE_IOCTL(LOOP_SET_STATUS, loop_status)
-HANDLE_IOCTL(LOOP_GET_STATUS, loop_status)
+#endif
#define AUTOFS_IOC_SETTIMEOUT32 _IOWR(0x93,0x64,unsigned int)
HANDLE_IOCTL(AUTOFS_IOC_SETTIMEOUT32, ioc_settimeout)
#ifdef CONFIG_VT
@@ -2821,19 +2476,6 @@ HANDLE_IOCTL(PIO_UNIMAP, do_unimap_ioctl)
HANDLE_IOCTL(GIO_UNIMAP, do_unimap_ioctl)
HANDLE_IOCTL(KDFONTOP, do_kdfontop_ioctl)
#endif
-HANDLE_IOCTL(EXT2_IOC32_GETFLAGS, do_ext2_ioctl)
-HANDLE_IOCTL(EXT2_IOC32_SETFLAGS, do_ext2_ioctl)
-HANDLE_IOCTL(EXT2_IOC32_GETVERSION, do_ext2_ioctl)
-HANDLE_IOCTL(EXT2_IOC32_SETVERSION, do_ext2_ioctl)
-HANDLE_IOCTL(EXT3_IOC32_GETVERSION, do_ext3_ioctl)
-HANDLE_IOCTL(EXT3_IOC32_SETVERSION, do_ext3_ioctl)
-HANDLE_IOCTL(EXT3_IOC32_GETRSVSZ, do_ext3_ioctl)
-HANDLE_IOCTL(EXT3_IOC32_SETRSVSZ, do_ext3_ioctl)
-HANDLE_IOCTL(EXT3_IOC32_GROUP_EXTEND, do_ext3_ioctl)
-COMPATIBLE_IOCTL(EXT3_IOC_GROUP_ADD)
-#ifdef CONFIG_JBD_DEBUG
-HANDLE_IOCTL(EXT3_IOC32_WAIT_FOR_READONLY, do_ext3_ioctl)
-#endif
/* One SMB ioctl needs translations. */
#define SMB_IOC_GETMOUNTUID_32 _IOR('u', 1, compat_uid_t)
HANDLE_IOCTL(SMB_IOC_GETMOUNTUID_32, do_smb_getmountuid)
@@ -2863,16 +2505,14 @@ HANDLE_IOCTL(SONET_SETFRAMING, do_atm_ioctl)
HANDLE_IOCTL(SONET_GETFRAMING, do_atm_ioctl)
HANDLE_IOCTL(SONET_GETFRSENSE, do_atm_ioctl)
/* block stuff */
+#ifdef CONFIG_BLOCK
HANDLE_IOCTL(BLKBSZGET_32, do_blkbszget)
HANDLE_IOCTL(BLKBSZSET_32, do_blkbszset)
HANDLE_IOCTL(BLKGETSIZE64_32, do_blkgetsize64)
-/* vfat */
-HANDLE_IOCTL(VFAT_IOCTL_READDIR_BOTH32, vfat_ioctl32)
-HANDLE_IOCTL(VFAT_IOCTL_READDIR_SHORT32, vfat_ioctl32)
-HANDLE_IOCTL(REISERFS_IOC_UNPACK32, reiserfs_ioctl32)
/* Raw devices */
HANDLE_IOCTL(RAW_SETBIND, raw_ioctl)
HANDLE_IOCTL(RAW_GETBIND, raw_ioctl)
+#endif
/* Serial */
HANDLE_IOCTL(TIOCGSERIAL, serial_struct_ioctl)
HANDLE_IOCTL(TIOCSSERIAL, serial_struct_ioctl)
@@ -2920,16 +2560,6 @@ HANDLE_IOCTL(RTC_IRQP_SET32, rtc_ioctl)
HANDLE_IOCTL(RTC_EPOCH_READ32, rtc_ioctl)
HANDLE_IOCTL(RTC_EPOCH_SET32, rtc_ioctl)
-#if defined(CONFIG_NCP_FS) || defined(CONFIG_NCP_FS_MODULE)
-HANDLE_IOCTL(NCP_IOC_NCPREQUEST_32, do_ncp_ncprequest)
-HANDLE_IOCTL(NCP_IOC_GETMOUNTUID2_32, do_ncp_getmountuid2)
-HANDLE_IOCTL(NCP_IOC_GET_FS_INFO_V2_32, do_ncp_getfsinfo2)
-HANDLE_IOCTL(NCP_IOC_GETOBJECTNAME_32, do_ncp_getobjectname)
-HANDLE_IOCTL(NCP_IOC_SETOBJECTNAME_32, do_ncp_setobjectname)
-HANDLE_IOCTL(NCP_IOC_GETPRIVATEDATA_32, do_ncp_getprivatedata)
-HANDLE_IOCTL(NCP_IOC_SETPRIVATEDATA_32, do_ncp_setprivatedata)
-#endif
-
/* dvb */
HANDLE_IOCTL(VIDEO_GET_EVENT, do_video_get_event)
HANDLE_IOCTL(VIDEO_STILLPICTURE, do_video_stillpicture)
diff --git a/fs/configfs/dir.c b/fs/configfs/dir.c
index 816e8ef64560..8a3b6a1a6ad1 100644
--- a/fs/configfs/dir.c
+++ b/fs/configfs/dir.c
@@ -139,7 +139,7 @@ static int init_dir(struct inode * inode)
inode->i_fop = &configfs_dir_operations;
/* directory inodes start off with i_nlink == 2 (for "." entry) */
- inode->i_nlink++;
+ inc_nlink(inode);
return 0;
}
@@ -169,7 +169,7 @@ static int create_dir(struct config_item * k, struct dentry * p,
if (!error) {
error = configfs_create(d, mode, init_dir);
if (!error) {
- p->d_inode->i_nlink++;
+ inc_nlink(p->d_inode);
(d)->d_op = &configfs_dentry_ops;
} else {
struct configfs_dirent *sd = d->d_fsdata;
diff --git a/fs/configfs/file.c b/fs/configfs/file.c
index 85105e50f7db..e6d5754a715e 100644
--- a/fs/configfs/file.c
+++ b/fs/configfs/file.c
@@ -137,8 +137,8 @@ configfs_read_file(struct file *file, char __user *buf, size_t count, loff_t *pp
if ((retval = fill_read_buffer(file->f_dentry,buffer)))
goto out;
}
- pr_debug("%s: count = %d, ppos = %lld, buf = %s\n",
- __FUNCTION__,count,*ppos,buffer->page);
+ pr_debug("%s: count = %zd, ppos = %lld, buf = %s\n",
+ __FUNCTION__, count, *ppos, buffer->page);
retval = flush_read_buffer(buffer,buf,count,ppos);
out:
up(&buffer->sem);
diff --git a/fs/configfs/mount.c b/fs/configfs/mount.c
index 3e5fe843e1df..68bd5c93ca52 100644
--- a/fs/configfs/mount.c
+++ b/fs/configfs/mount.c
@@ -84,7 +84,7 @@ static int configfs_fill_super(struct super_block *sb, void *data, int silent)
inode->i_op = &configfs_dir_inode_operations;
inode->i_fop = &configfs_dir_operations;
/* directory inodes start off with i_nlink == 2 (for "." entry) */
- inode->i_nlink++;
+ inc_nlink(inode);
} else {
pr_debug("configfs: could not get root inode\n");
return -ENOMEM;
diff --git a/fs/cramfs/inode.c b/fs/cramfs/inode.c
index ad96b6990715..a624c3ec8189 100644
--- a/fs/cramfs/inode.c
+++ b/fs/cramfs/inode.c
@@ -543,8 +543,15 @@ static struct file_system_type cramfs_fs_type = {
static int __init init_cramfs_fs(void)
{
- cramfs_uncompress_init();
- return register_filesystem(&cramfs_fs_type);
+ int rv;
+
+ rv = cramfs_uncompress_init();
+ if (rv < 0)
+ return rv;
+ rv = register_filesystem(&cramfs_fs_type);
+ if (rv < 0)
+ cramfs_uncompress_exit();
+ return rv;
}
static void __exit exit_cramfs_fs(void)
diff --git a/fs/cramfs/uncompress.c b/fs/cramfs/uncompress.c
index 8def89f2c438..fc3ccb74626f 100644
--- a/fs/cramfs/uncompress.c
+++ b/fs/cramfs/uncompress.c
@@ -68,11 +68,10 @@ int cramfs_uncompress_init(void)
return 0;
}
-int cramfs_uncompress_exit(void)
+void cramfs_uncompress_exit(void)
{
if (!--initialized) {
zlib_inflateEnd(&stream);
vfree(stream.workspace);
}
- return 0;
}
diff --git a/fs/dcache.c b/fs/dcache.c
index 17b392a2049e..fc2faa44f8d1 100644
--- a/fs/dcache.c
+++ b/fs/dcache.c
@@ -32,6 +32,7 @@
#include <linux/seqlock.h>
#include <linux/swap.h>
#include <linux/bootmem.h>
+#include "internal.h"
int sysctl_vfs_cache_pressure __read_mostly = 100;
@@ -1877,9 +1878,6 @@ kmem_cache_t *filp_cachep __read_mostly;
EXPORT_SYMBOL(d_genocide);
-extern void bdev_cache_init(void);
-extern void chrdev_init(void);
-
void __init vfs_caches_init_early(void)
{
dcache_init_early();
diff --git a/fs/debugfs/inode.c b/fs/debugfs/inode.c
index 269e649e6dc6..ecf3da9edf21 100644
--- a/fs/debugfs/inode.c
+++ b/fs/debugfs/inode.c
@@ -54,7 +54,7 @@ static struct inode *debugfs_get_inode(struct super_block *sb, int mode, dev_t d
inode->i_fop = &simple_dir_operations;
/* directory inodes start off with i_nlink == 2 (for "." entry) */
- inode->i_nlink++;
+ inc_nlink(inode);
break;
}
}
@@ -87,7 +87,7 @@ static int debugfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
mode = (mode & (S_IRWXUGO | S_ISVTX)) | S_IFDIR;
res = debugfs_mknod(dir, dentry, mode, 0);
if (!res)
- dir->i_nlink++;
+ inc_nlink(dir);
return res;
}
diff --git a/fs/dnotify.c b/fs/dnotify.c
index f932591df5a4..2b0442db67e0 100644
--- a/fs/dnotify.c
+++ b/fs/dnotify.c
@@ -92,7 +92,7 @@ int fcntl_dirnotify(int fd, struct file *filp, unsigned long arg)
prev = &odn->dn_next;
}
- error = f_setown(filp, current->pid, 0);
+ error = __f_setown(filp, task_pid(current), PIDTYPE_PID, 0);
if (error)
goto out_free;
diff --git a/fs/dquot.c b/fs/dquot.c
index 0122a279106a..9af789567e51 100644
--- a/fs/dquot.c
+++ b/fs/dquot.c
@@ -834,6 +834,9 @@ static void print_warning(struct dquot *dquot, const char warntype)
if (!need_print_warning(dquot) || (flag && test_and_set_bit(flag, &dquot->dq_flags)))
return;
+ mutex_lock(&tty_mutex);
+ if (!current->signal->tty)
+ goto out_lock;
tty_write_message(current->signal->tty, dquot->dq_sb->s_id);
if (warntype == ISOFTWARN || warntype == BSOFTWARN)
tty_write_message(current->signal->tty, ": warning, ");
@@ -861,6 +864,8 @@ static void print_warning(struct dquot *dquot, const char warntype)
break;
}
tty_write_message(current->signal->tty, msg);
+out_lock:
+ mutex_unlock(&tty_mutex);
}
static inline void flush_warnings(struct dquot **dquots, char *warntype)
diff --git a/fs/eventpoll.c b/fs/eventpoll.c
index 8d544334bcd2..557d5b614fae 100644
--- a/fs/eventpoll.c
+++ b/fs/eventpoll.c
@@ -720,9 +720,10 @@ static int ep_getfd(int *efd, struct inode **einode, struct file **efile,
/* Allocates an inode from the eventpoll file system */
inode = ep_eventpoll_inode();
- error = PTR_ERR(inode);
- if (IS_ERR(inode))
+ if (IS_ERR(inode)) {
+ error = PTR_ERR(inode);
goto eexit_2;
+ }
/* Allocates a free descriptor to plug the file onto */
error = get_unused_fd();
diff --git a/fs/exec.c b/fs/exec.c
index 97df6e0aeaee..d993ea1a81ae 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -46,7 +46,7 @@
#include <linux/security.h>
#include <linux/syscalls.h>
#include <linux/rmap.h>
-#include <linux/acct.h>
+#include <linux/tsacct_kern.h>
#include <linux/cn_proc.h>
#include <linux/audit.h>
@@ -58,7 +58,7 @@
#endif
int core_uses_pid;
-char core_pattern[65] = "core";
+char core_pattern[128] = "core";
int suid_dumpable = 0;
EXPORT_SYMBOL(suid_dumpable);
@@ -898,8 +898,7 @@ int flush_old_exec(struct linux_binprm * bprm)
return 0;
mmap_failed:
- put_files_struct(current->files);
- current->files = files;
+ reset_files_struct(current, files);
out:
return retval;
}
@@ -1319,7 +1318,7 @@ static void format_corename(char *corename, const char *pattern, long signr)
case 'h':
down_read(&uts_sem);
rc = snprintf(out_ptr, out_end - out_ptr,
- "%s", system_utsname.nodename);
+ "%s", utsname()->nodename);
up_read(&uts_sem);
if (rc > out_end - out_ptr)
goto out;
@@ -1464,6 +1463,7 @@ int do_coredump(long signr, int exit_code, struct pt_regs * regs)
int retval = 0;
int fsuid = current->fsuid;
int flag = 0;
+ int ispipe = 0;
binfmt = current->binfmt;
if (!binfmt || !binfmt->core_dump)
@@ -1505,22 +1505,34 @@ int do_coredump(long signr, int exit_code, struct pt_regs * regs)
lock_kernel();
format_corename(corename, core_pattern, signr);
unlock_kernel();
- file = filp_open(corename, O_CREAT | 2 | O_NOFOLLOW | O_LARGEFILE | flag, 0600);
+ if (corename[0] == '|') {
+ /* SIGPIPE can happen, but it's just never processed */
+ if(call_usermodehelper_pipe(corename+1, NULL, NULL, &file)) {
+ printk(KERN_INFO "Core dump to %s pipe failed\n",
+ corename);
+ goto fail_unlock;
+ }
+ ispipe = 1;
+ } else
+ file = filp_open(corename,
+ O_CREAT | 2 | O_NOFOLLOW | O_LARGEFILE, 0600);
if (IS_ERR(file))
goto fail_unlock;
inode = file->f_dentry->d_inode;
if (inode->i_nlink > 1)
goto close_fail; /* multiple links - don't dump */
- if (d_unhashed(file->f_dentry))
+ if (!ispipe && d_unhashed(file->f_dentry))
goto close_fail;
- if (!S_ISREG(inode->i_mode))
+ /* AK: actually i see no reason to not allow this for named pipes etc.,
+ but keep the previous behaviour for now. */
+ if (!ispipe && !S_ISREG(inode->i_mode))
goto close_fail;
if (!file->f_op)
goto close_fail;
if (!file->f_op->write)
goto close_fail;
- if (do_truncate(file->f_dentry, 0, 0, file) != 0)
+ if (!ispipe && do_truncate(file->f_dentry, 0, 0, file) != 0)
goto close_fail;
retval = binfmt->core_dump(signr, regs, file);
diff --git a/fs/exportfs/expfs.c b/fs/exportfs/expfs.c
index 4c39009350f3..93e77c3d2490 100644
--- a/fs/exportfs/expfs.c
+++ b/fs/exportfs/expfs.c
@@ -315,7 +315,7 @@ struct getdents_callback {
* the name matching the specified inode number.
*/
static int filldir_one(void * __buf, const char * name, int len,
- loff_t pos, ino_t ino, unsigned int d_type)
+ loff_t pos, u64 ino, unsigned int d_type)
{
struct getdents_callback *buf = __buf;
int result = 0;
diff --git a/fs/ext2/dir.c b/fs/ext2/dir.c
index 92ea8265d7d5..3e7a84a1e509 100644
--- a/fs/ext2/dir.c
+++ b/fs/ext2/dir.c
@@ -661,5 +661,8 @@ const struct file_operations ext2_dir_operations = {
.read = generic_read_dir,
.readdir = ext2_readdir,
.ioctl = ext2_ioctl,
+#ifdef CONFIG_COMPAT
+ .compat_ioctl = ext2_compat_ioctl,
+#endif
.fsync = ext2_sync_file,
};
diff --git a/fs/ext2/ext2.h b/fs/ext2/ext2.h
index e65a019fc7a5..c19ac153f56b 100644
--- a/fs/ext2/ext2.h
+++ b/fs/ext2/ext2.h
@@ -137,6 +137,7 @@ extern void ext2_set_inode_flags(struct inode *inode);
/* ioctl.c */
extern int ext2_ioctl (struct inode *, struct file *, unsigned int,
unsigned long);
+extern long ext2_compat_ioctl(struct file *, unsigned int, unsigned long);
/* namei.c */
struct dentry *ext2_get_parent(struct dentry *child);
diff --git a/fs/ext2/file.c b/fs/ext2/file.c
index 23e2c7ccec1d..2dba473c524a 100644
--- a/fs/ext2/file.c
+++ b/fs/ext2/file.c
@@ -41,17 +41,18 @@ static int ext2_release_file (struct inode * inode, struct file * filp)
*/
const struct file_operations ext2_file_operations = {
.llseek = generic_file_llseek,
- .read = generic_file_read,
- .write = generic_file_write,
+ .read = do_sync_read,
+ .write = do_sync_write,
.aio_read = generic_file_aio_read,
.aio_write = generic_file_aio_write,
.ioctl = ext2_ioctl,
+#ifdef CONFIG_COMPAT
+ .compat_ioctl = ext2_compat_ioctl,
+#endif
.mmap = generic_file_mmap,
.open = generic_file_open,
.release = ext2_release_file,
.fsync = ext2_sync_file,
- .readv = generic_file_readv,
- .writev = generic_file_writev,
.sendfile = generic_file_sendfile,
.splice_read = generic_file_splice_read,
.splice_write = generic_file_splice_write,
@@ -63,6 +64,9 @@ const struct file_operations ext2_xip_file_operations = {
.read = xip_file_read,
.write = xip_file_write,
.ioctl = ext2_ioctl,
+#ifdef CONFIG_COMPAT
+ .compat_ioctl = ext2_compat_ioctl,
+#endif
.mmap = xip_file_mmap,
.open = generic_file_open,
.release = ext2_release_file,
diff --git a/fs/ext2/ioctl.c b/fs/ext2/ioctl.c
index 3ca9afdf713d..1dfba77eab10 100644
--- a/fs/ext2/ioctl.c
+++ b/fs/ext2/ioctl.c
@@ -11,6 +11,8 @@
#include <linux/capability.h>
#include <linux/time.h>
#include <linux/sched.h>
+#include <linux/compat.h>
+#include <linux/smp_lock.h>
#include <asm/current.h>
#include <asm/uaccess.h>
@@ -80,3 +82,33 @@ int ext2_ioctl (struct inode * inode, struct file * filp, unsigned int cmd,
return -ENOTTY;
}
}
+
+#ifdef CONFIG_COMPAT
+long ext2_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+{
+ struct inode *inode = file->f_dentry->d_inode;
+ int ret;
+
+ /* These are just misnamed, they actually get/put from/to user an int */
+ switch (cmd) {
+ case EXT2_IOC32_GETFLAGS:
+ cmd = EXT2_IOC_GETFLAGS;
+ break;
+ case EXT2_IOC32_SETFLAGS:
+ cmd = EXT2_IOC_SETFLAGS;
+ break;
+ case EXT2_IOC32_GETVERSION:
+ cmd = EXT2_IOC_GETVERSION;
+ break;
+ case EXT2_IOC32_SETVERSION:
+ cmd = EXT2_IOC_SETVERSION;
+ break;
+ default:
+ return -ENOIOCTLCMD;
+ }
+ lock_kernel();
+ ret = ext2_ioctl(inode, file, cmd, (unsigned long) compat_ptr(arg));
+ unlock_kernel();
+ return ret;
+}
+#endif
diff --git a/fs/ext2/namei.c b/fs/ext2/namei.c
index 4ca824985321..e1af5b4cf80c 100644
--- a/fs/ext2/namei.c
+++ b/fs/ext2/namei.c
@@ -326,7 +326,7 @@ static int ext2_rename (struct inode * old_dir, struct dentry * old_dentry,
ext2_set_link(new_dir, new_de, new_page, old_inode);
new_inode->i_ctime = CURRENT_TIME_SEC;
if (dir_de)
- new_inode->i_nlink--;
+ drop_nlink(new_inode);
inode_dec_link_count(new_inode);
} else {
if (dir_de) {
diff --git a/fs/ext3/dir.c b/fs/ext3/dir.c
index 429acbb4e064..d0b54f30b914 100644
--- a/fs/ext3/dir.c
+++ b/fs/ext3/dir.c
@@ -44,6 +44,9 @@ const struct file_operations ext3_dir_operations = {
.read = generic_read_dir,
.readdir = ext3_readdir, /* we take BKL. needed?*/
.ioctl = ext3_ioctl, /* BKL held */
+#ifdef CONFIG_COMPAT
+ .compat_ioctl = ext3_compat_ioctl,
+#endif
.fsync = ext3_sync_file, /* BKL held */
#ifdef CONFIG_EXT3_INDEX
.release = ext3_release_dir,
diff --git a/fs/ext3/file.c b/fs/ext3/file.c
index 994efd189f4e..e96c388047e0 100644
--- a/fs/ext3/file.c
+++ b/fs/ext3/file.c
@@ -48,14 +48,15 @@ static int ext3_release_file (struct inode * inode, struct file * filp)
}
static ssize_t
-ext3_file_write(struct kiocb *iocb, const char __user *buf, size_t count, loff_t pos)
+ext3_file_write(struct kiocb *iocb, const struct iovec *iov,
+ unsigned long nr_segs, loff_t pos)
{
struct file *file = iocb->ki_filp;
struct inode *inode = file->f_dentry->d_inode;
ssize_t ret;
int err;
- ret = generic_file_aio_write(iocb, buf, count, pos);
+ ret = generic_file_aio_write(iocb, iov, nr_segs, pos);
/*
* Skip flushing if there was an error, or if nothing was written.
@@ -111,9 +112,10 @@ const struct file_operations ext3_file_operations = {
.write = do_sync_write,
.aio_read = generic_file_aio_read,
.aio_write = ext3_file_write,
- .readv = generic_file_readv,
- .writev = generic_file_writev,
.ioctl = ext3_ioctl,
+#ifdef CONFIG_COMPAT
+ .compat_ioctl = ext3_compat_ioctl,
+#endif
.mmap = generic_file_mmap,
.open = generic_file_open,
.release = ext3_release_file,
diff --git a/fs/ext3/inode.c b/fs/ext3/inode.c
index dcf4f1dd108b..03ba5bcab186 100644
--- a/fs/ext3/inode.c
+++ b/fs/ext3/inode.c
@@ -36,6 +36,7 @@
#include <linux/writeback.h>
#include <linux/mpage.h>
#include <linux/uio.h>
+#include <linux/bio.h>
#include "xattr.h"
#include "acl.h"
@@ -1073,7 +1074,7 @@ struct buffer_head *ext3_bread(handle_t *handle, struct inode *inode,
return bh;
if (buffer_uptodate(bh))
return bh;
- ll_rw_block(READ, 1, &bh);
+ ll_rw_block(READ_META, 1, &bh);
wait_on_buffer(bh);
if (buffer_uptodate(bh))
return bh;
@@ -2540,7 +2541,7 @@ make_io:
*/
get_bh(bh);
bh->b_end_io = end_buffer_read_sync;
- submit_bh(READ, bh);
+ submit_bh(READ_META, bh);
wait_on_buffer(bh);
if (!buffer_uptodate(bh)) {
ext3_error(inode->i_sb, "ext3_get_inode_loc",
diff --git a/fs/ext3/ioctl.c b/fs/ext3/ioctl.c
index 3a6b012d120c..12daa6869572 100644
--- a/fs/ext3/ioctl.c
+++ b/fs/ext3/ioctl.c
@@ -13,9 +13,10 @@
#include <linux/ext3_fs.h>
#include <linux/ext3_jbd.h>
#include <linux/time.h>
+#include <linux/compat.h>
+#include <linux/smp_lock.h>
#include <asm/uaccess.h>
-
int ext3_ioctl (struct inode * inode, struct file * filp, unsigned int cmd,
unsigned long arg)
{
@@ -252,3 +253,55 @@ flags_err:
return -ENOTTY;
}
}
+
+#ifdef CONFIG_COMPAT
+long ext3_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+{
+ struct inode *inode = file->f_dentry->d_inode;
+ int ret;
+
+ /* These are just misnamed, they actually get/put from/to user an int */
+ switch (cmd) {
+ case EXT3_IOC32_GETFLAGS:
+ cmd = EXT3_IOC_GETFLAGS;
+ break;
+ case EXT3_IOC32_SETFLAGS:
+ cmd = EXT3_IOC_SETFLAGS;
+ break;
+ case EXT3_IOC32_GETVERSION:
+ cmd = EXT3_IOC_GETVERSION;
+ break;
+ case EXT3_IOC32_SETVERSION:
+ cmd = EXT3_IOC_SETVERSION;
+ break;
+ case EXT3_IOC32_GROUP_EXTEND:
+ cmd = EXT3_IOC_GROUP_EXTEND;
+ break;
+ case EXT3_IOC32_GETVERSION_OLD:
+ cmd = EXT3_IOC_GETVERSION_OLD;
+ break;
+ case EXT3_IOC32_SETVERSION_OLD:
+ cmd = EXT3_IOC_SETVERSION_OLD;
+ break;
+#ifdef CONFIG_JBD_DEBUG
+ case EXT3_IOC32_WAIT_FOR_READONLY:
+ cmd = EXT3_IOC_WAIT_FOR_READONLY;
+ break;
+#endif
+ case EXT3_IOC32_GETRSVSZ:
+ cmd = EXT3_IOC_GETRSVSZ;
+ break;
+ case EXT3_IOC32_SETRSVSZ:
+ cmd = EXT3_IOC_SETRSVSZ;
+ break;
+ case EXT3_IOC_GROUP_ADD:
+ break;
+ default:
+ return -ENOIOCTLCMD;
+ }
+ lock_kernel();
+ ret = ext3_ioctl(inode, file, cmd, (unsigned long) compat_ptr(arg));
+ unlock_kernel();
+ return ret;
+}
+#endif
diff --git a/fs/ext3/namei.c b/fs/ext3/namei.c
index 85d132c37ee0..906731a20f1a 100644
--- a/fs/ext3/namei.c
+++ b/fs/ext3/namei.c
@@ -35,6 +35,7 @@
#include <linux/string.h>
#include <linux/quotaops.h>
#include <linux/buffer_head.h>
+#include <linux/bio.h>
#include <linux/smp_lock.h>
#include "namei.h"
@@ -870,7 +871,7 @@ restart:
bh = ext3_getblk(NULL, dir, b++, 0, &err);
bh_use[ra_max] = bh;
if (bh)
- ll_rw_block(READ, 1, &bh);
+ ll_rw_block(READ_META, 1, &bh);
}
}
if ((bh = bh_use[ra_ptr++]) == NULL)
@@ -1615,12 +1616,12 @@ static int ext3_delete_entry (handle_t *handle,
*/
static inline void ext3_inc_count(handle_t *handle, struct inode *inode)
{
- inode->i_nlink++;
+ inc_nlink(inode);
}
static inline void ext3_dec_count(handle_t *handle, struct inode *inode)
{
- inode->i_nlink--;
+ drop_nlink(inode);
}
static int ext3_add_nondir(handle_t *handle,
@@ -1742,7 +1743,7 @@ retry:
inode->i_size = EXT3_I(inode)->i_disksize = inode->i_sb->s_blocksize;
dir_block = ext3_bread (handle, inode, 0, 1, &err);
if (!dir_block) {
- inode->i_nlink--; /* is this nlink == 0? */
+ drop_nlink(inode); /* is this nlink == 0? */
ext3_mark_inode_dirty(handle, inode);
iput (inode);
goto out_stop;
@@ -1774,7 +1775,7 @@ retry:
iput (inode);
goto out_stop;
}
- dir->i_nlink++;
+ inc_nlink(dir);
ext3_update_dx_flag(dir);
ext3_mark_inode_dirty(handle, dir);
d_instantiate(dentry, inode);
@@ -2044,7 +2045,7 @@ static int ext3_rmdir (struct inode * dir, struct dentry *dentry)
"empty directory has nlink!=2 (%d)",
inode->i_nlink);
inode->i_version++;
- inode->i_nlink = 0;
+ clear_nlink(inode);
/* There's no need to set i_disksize: the fact that i_nlink is
* zero will ensure that the right thing happens during any
* recovery. */
@@ -2052,7 +2053,7 @@ static int ext3_rmdir (struct inode * dir, struct dentry *dentry)
ext3_orphan_add(handle, inode);
inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME_SEC;
ext3_mark_inode_dirty(handle, inode);
- dir->i_nlink--;
+ drop_nlink(dir);
ext3_update_dx_flag(dir);
ext3_mark_inode_dirty(handle, dir);
@@ -2103,7 +2104,7 @@ static int ext3_unlink(struct inode * dir, struct dentry *dentry)
dir->i_ctime = dir->i_mtime = CURRENT_TIME_SEC;
ext3_update_dx_flag(dir);
ext3_mark_inode_dirty(handle, dir);
- inode->i_nlink--;
+ drop_nlink(inode);
if (!inode->i_nlink)
ext3_orphan_add(handle, inode);
inode->i_ctime = dir->i_ctime;
@@ -2325,7 +2326,7 @@ static int ext3_rename (struct inode * old_dir, struct dentry *old_dentry,
}
if (new_inode) {
- new_inode->i_nlink--;
+ drop_nlink(new_inode);
new_inode->i_ctime = CURRENT_TIME_SEC;
}
old_dir->i_ctime = old_dir->i_mtime = CURRENT_TIME_SEC;
@@ -2336,11 +2337,11 @@ static int ext3_rename (struct inode * old_dir, struct dentry *old_dentry,
PARENT_INO(dir_bh->b_data) = cpu_to_le32(new_dir->i_ino);
BUFFER_TRACE(dir_bh, "call ext3_journal_dirty_metadata");
ext3_journal_dirty_metadata(handle, dir_bh);
- old_dir->i_nlink--;
+ drop_nlink(old_dir);
if (new_inode) {
- new_inode->i_nlink--;
+ drop_nlink(new_inode);
} else {
- new_dir->i_nlink++;
+ inc_nlink(new_dir);
ext3_update_dx_flag(new_dir);
ext3_mark_inode_dirty(handle, new_dir);
}
diff --git a/fs/fat/dir.c b/fs/fat/dir.c
index 698b85bb1dd4..69c439f44387 100644
--- a/fs/fat/dir.c
+++ b/fs/fat/dir.c
@@ -20,6 +20,7 @@
#include <linux/dirent.h>
#include <linux/smp_lock.h>
#include <linux/buffer_head.h>
+#include <linux/compat.h>
#include <asm/uaccess.h>
static inline loff_t fat_make_i_pos(struct super_block *sb,
@@ -647,7 +648,7 @@ static int fat_readdir(struct file *filp, void *dirent, filldir_t filldir)
}
static int fat_ioctl_filldir(void *__buf, const char *name, int name_len,
- loff_t offset, ino_t ino, unsigned int d_type)
+ loff_t offset, u64 ino, unsigned int d_type)
{
struct fat_ioctl_filldir_callback *buf = __buf;
struct dirent __user *d1 = buf->dirent;
@@ -741,10 +742,65 @@ static int fat_dir_ioctl(struct inode * inode, struct file * filp,
return ret;
}
+#ifdef CONFIG_COMPAT
+#define VFAT_IOCTL_READDIR_BOTH32 _IOR('r', 1, struct compat_dirent[2])
+#define VFAT_IOCTL_READDIR_SHORT32 _IOR('r', 2, struct compat_dirent[2])
+
+static long fat_compat_put_dirent32(struct dirent *d,
+ struct compat_dirent __user *d32)
+{
+ if (!access_ok(VERIFY_WRITE, d32, sizeof(struct compat_dirent)))
+ return -EFAULT;
+
+ __put_user(d->d_ino, &d32->d_ino);
+ __put_user(d->d_off, &d32->d_off);
+ __put_user(d->d_reclen, &d32->d_reclen);
+ if (__copy_to_user(d32->d_name, d->d_name, d->d_reclen))
+ return -EFAULT;
+
+ return 0;
+}
+
+static long fat_compat_dir_ioctl(struct file *file, unsigned cmd,
+ unsigned long arg)
+{
+ struct compat_dirent __user *p = compat_ptr(arg);
+ int ret;
+ mm_segment_t oldfs = get_fs();
+ struct dirent d[2];
+
+ switch (cmd) {
+ case VFAT_IOCTL_READDIR_BOTH32:
+ cmd = VFAT_IOCTL_READDIR_BOTH;
+ break;
+ case VFAT_IOCTL_READDIR_SHORT32:
+ cmd = VFAT_IOCTL_READDIR_SHORT;
+ break;
+ default:
+ return -ENOIOCTLCMD;
+ }
+
+ set_fs(KERNEL_DS);
+ lock_kernel();
+ ret = fat_dir_ioctl(file->f_dentry->d_inode, file,
+ cmd, (unsigned long) &d);
+ unlock_kernel();
+ set_fs(oldfs);
+ if (ret >= 0) {
+ ret |= fat_compat_put_dirent32(&d[0], p);
+ ret |= fat_compat_put_dirent32(&d[1], p + 1);
+ }
+ return ret;
+}
+#endif /* CONFIG_COMPAT */
+
const struct file_operations fat_dir_operations = {
.read = generic_read_dir,
.readdir = fat_readdir,
.ioctl = fat_dir_ioctl,
+#ifdef CONFIG_COMPAT
+ .compat_ioctl = fat_compat_dir_ioctl,
+#endif
.fsync = file_fsync,
};
diff --git a/fs/fat/file.c b/fs/fat/file.c
index 1ee25232e6af..f4b8f8b3fbdd 100644
--- a/fs/fat/file.c
+++ b/fs/fat/file.c
@@ -13,6 +13,7 @@
#include <linux/smp_lock.h>
#include <linux/buffer_head.h>
#include <linux/writeback.h>
+#include <linux/blkdev.h>
int fat_generic_ioctl(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg)
@@ -112,15 +113,24 @@ int fat_generic_ioctl(struct inode *inode, struct file *filp,
}
}
+static int fat_file_release(struct inode *inode, struct file *filp)
+{
+ if ((filp->f_mode & FMODE_WRITE) &&
+ MSDOS_SB(inode->i_sb)->options.flush) {
+ fat_flush_inodes(inode->i_sb, inode, NULL);
+ blk_congestion_wait(WRITE, HZ/10);
+ }
+ return 0;
+}
+
const struct file_operations fat_file_operations = {
.llseek = generic_file_llseek,
.read = do_sync_read,
.write = do_sync_write,
- .readv = generic_file_readv,
- .writev = generic_file_writev,
.aio_read = generic_file_aio_read,
.aio_write = generic_file_aio_write,
.mmap = generic_file_mmap,
+ .release = fat_file_release,
.ioctl = fat_generic_ioctl,
.fsync = file_fsync,
.sendfile = generic_file_sendfile,
@@ -289,6 +299,7 @@ void fat_truncate(struct inode *inode)
lock_kernel();
fat_free(inode, nr_clusters);
unlock_kernel();
+ fat_flush_inodes(inode->i_sb, inode, NULL);
}
struct inode_operations fat_file_inode_operations = {
diff --git a/fs/fat/inode.c b/fs/fat/inode.c
index ab96ae823753..045738032a83 100644
--- a/fs/fat/inode.c
+++ b/fs/fat/inode.c
@@ -24,6 +24,7 @@
#include <linux/vfs.h>
#include <linux/parser.h>
#include <linux/uio.h>
+#include <linux/writeback.h>
#include <asm/unaligned.h>
#ifndef CONFIG_FAT_DEFAULT_IOCHARSET
@@ -853,7 +854,7 @@ enum {
Opt_charset, Opt_shortname_lower, Opt_shortname_win95,
Opt_shortname_winnt, Opt_shortname_mixed, Opt_utf8_no, Opt_utf8_yes,
Opt_uni_xl_no, Opt_uni_xl_yes, Opt_nonumtail_no, Opt_nonumtail_yes,
- Opt_obsolate, Opt_err,
+ Opt_obsolate, Opt_flush, Opt_err,
};
static match_table_t fat_tokens = {
@@ -885,7 +886,8 @@ static match_table_t fat_tokens = {
{Opt_obsolate, "cvf_format=%20s"},
{Opt_obsolate, "cvf_options=%100s"},
{Opt_obsolate, "posix"},
- {Opt_err, NULL}
+ {Opt_flush, "flush"},
+ {Opt_err, NULL},
};
static match_table_t msdos_tokens = {
{Opt_nodots, "nodots"},
@@ -1026,6 +1028,9 @@ static int parse_options(char *options, int is_vfat, int silent, int *debug,
return 0;
opts->codepage = option;
break;
+ case Opt_flush:
+ opts->flush = 1;
+ break;
/* msdos specific */
case Opt_dots:
@@ -1425,6 +1430,56 @@ out_fail:
EXPORT_SYMBOL_GPL(fat_fill_super);
+/*
+ * helper function for fat_flush_inodes. This writes both the inode
+ * and the file data blocks, waiting for in flight data blocks before
+ * the start of the call. It does not wait for any io started
+ * during the call
+ */
+static int writeback_inode(struct inode *inode)
+{
+
+ int ret;
+ struct address_space *mapping = inode->i_mapping;
+ struct writeback_control wbc = {
+ .sync_mode = WB_SYNC_NONE,
+ .nr_to_write = 0,
+ };
+ /* if we used WB_SYNC_ALL, sync_inode waits for the io for the
+ * inode to finish. So WB_SYNC_NONE is sent down to sync_inode
+ * and filemap_fdatawrite is used for the data blocks
+ */
+ ret = sync_inode(inode, &wbc);
+ if (!ret)
+ ret = filemap_fdatawrite(mapping);
+ return ret;
+}
+
+/*
+ * write data and metadata corresponding to i1 and i2. The io is
+ * started but we do not wait for any of it to finish.
+ *
+ * filemap_flush is used for the block device, so if there is a dirty
+ * page for a block already in flight, we will not wait and start the
+ * io over again
+ */
+int fat_flush_inodes(struct super_block *sb, struct inode *i1, struct inode *i2)
+{
+ int ret = 0;
+ if (!MSDOS_SB(sb)->options.flush)
+ return 0;
+ if (i1)
+ ret = writeback_inode(i1);
+ if (!ret && i2)
+ ret = writeback_inode(i2);
+ if (!ret && sb) {
+ struct address_space *mapping = sb->s_bdev->bd_inode->i_mapping;
+ ret = filemap_flush(mapping);
+ }
+ return ret;
+}
+EXPORT_SYMBOL_GPL(fat_flush_inodes);
+
static int __init init_fat_fs(void)
{
int err;
diff --git a/fs/fcntl.c b/fs/fcntl.c
index d35cbc6bc112..e4f26165f12a 100644
--- a/fs/fcntl.c
+++ b/fs/fcntl.c
@@ -250,19 +250,22 @@ static int setfl(int fd, struct file * filp, unsigned long arg)
return error;
}
-static void f_modown(struct file *filp, unsigned long pid,
+static void f_modown(struct file *filp, struct pid *pid, enum pid_type type,
uid_t uid, uid_t euid, int force)
{
write_lock_irq(&filp->f_owner.lock);
if (force || !filp->f_owner.pid) {
- filp->f_owner.pid = pid;
+ put_pid(filp->f_owner.pid);
+ filp->f_owner.pid = get_pid(pid);
+ filp->f_owner.pid_type = type;
filp->f_owner.uid = uid;
filp->f_owner.euid = euid;
}
write_unlock_irq(&filp->f_owner.lock);
}
-int f_setown(struct file *filp, unsigned long arg, int force)
+int __f_setown(struct file *filp, struct pid *pid, enum pid_type type,
+ int force)
{
int err;
@@ -270,15 +273,44 @@ int f_setown(struct file *filp, unsigned long arg, int force)
if (err)
return err;
- f_modown(filp, arg, current->uid, current->euid, force);
+ f_modown(filp, pid, type, current->uid, current->euid, force);
return 0;
}
+EXPORT_SYMBOL(__f_setown);
+int f_setown(struct file *filp, unsigned long arg, int force)
+{
+ enum pid_type type;
+ struct pid *pid;
+ int who = arg;
+ int result;
+ type = PIDTYPE_PID;
+ if (who < 0) {
+ type = PIDTYPE_PGID;
+ who = -who;
+ }
+ rcu_read_lock();
+ pid = find_pid(who);
+ result = __f_setown(filp, pid, type, force);
+ rcu_read_unlock();
+ return result;
+}
EXPORT_SYMBOL(f_setown);
void f_delown(struct file *filp)
{
- f_modown(filp, 0, 0, 0, 1);
+ f_modown(filp, NULL, PIDTYPE_PID, 0, 0, 1);
+}
+
+pid_t f_getown(struct file *filp)
+{
+ pid_t pid;
+ read_lock(&filp->f_owner.lock);
+ pid = pid_nr(filp->f_owner.pid);
+ if (filp->f_owner.pid_type == PIDTYPE_PGID)
+ pid = -pid;
+ read_unlock(&filp->f_owner.lock);
+ return pid;
}
static long do_fcntl(int fd, unsigned int cmd, unsigned long arg,
@@ -319,7 +351,7 @@ static long do_fcntl(int fd, unsigned int cmd, unsigned long arg,
* current syscall conventions, the only way
* to fix this will be in libc.
*/
- err = filp->f_owner.pid;
+ err = f_getown(filp);
force_successful_syscall_return();
break;
case F_SETOWN:
@@ -470,24 +502,19 @@ static void send_sigio_to_task(struct task_struct *p,
void send_sigio(struct fown_struct *fown, int fd, int band)
{
struct task_struct *p;
- int pid;
+ enum pid_type type;
+ struct pid *pid;
read_lock(&fown->lock);
+ type = fown->pid_type;
pid = fown->pid;
if (!pid)
goto out_unlock_fown;
read_lock(&tasklist_lock);
- if (pid > 0) {
- p = find_task_by_pid(pid);
- if (p) {
- send_sigio_to_task(p, fown, fd, band);
- }
- } else {
- do_each_task_pid(-pid, PIDTYPE_PGID, p) {
- send_sigio_to_task(p, fown, fd, band);
- } while_each_task_pid(-pid, PIDTYPE_PGID, p);
- }
+ do_each_pid_task(pid, type, p) {
+ send_sigio_to_task(p, fown, fd, band);
+ } while_each_pid_task(pid, type, p);
read_unlock(&tasklist_lock);
out_unlock_fown:
read_unlock(&fown->lock);
@@ -503,9 +530,12 @@ static void send_sigurg_to_task(struct task_struct *p,
int send_sigurg(struct fown_struct *fown)
{
struct task_struct *p;
- int pid, ret = 0;
+ enum pid_type type;
+ struct pid *pid;
+ int ret = 0;
read_lock(&fown->lock);
+ type = fown->pid_type;
pid = fown->pid;
if (!pid)
goto out_unlock_fown;
@@ -513,16 +543,9 @@ int send_sigurg(struct fown_struct *fown)
ret = 1;
read_lock(&tasklist_lock);
- if (pid > 0) {
- p = find_task_by_pid(pid);
- if (p) {
- send_sigurg_to_task(p, fown);
- }
- } else {
- do_each_task_pid(-pid, PIDTYPE_PGID, p) {
- send_sigurg_to_task(p, fown);
- } while_each_task_pid(-pid, PIDTYPE_PGID, p);
- }
+ do_each_pid_task(pid, type, p) {
+ send_sigurg_to_task(p, fown);
+ } while_each_pid_task(pid, type, p);
read_unlock(&tasklist_lock);
out_unlock_fown:
read_unlock(&fown->lock);
diff --git a/fs/file.c b/fs/file.c
index 8d3bfca7714b..8e81775c5dc8 100644
--- a/fs/file.c
+++ b/fs/file.c
@@ -288,71 +288,63 @@ out:
}
/*
- * Expands the file descriptor table - it will allocate a new fdtable and
- * both fd array and fdset. It is expected to be called with the
- * files_lock held.
+ * Expand the file descriptor table.
+ * This function will allocate a new fdtable and both fd array and fdset, of
+ * the given size.
+ * Return <0 error code on error; 1 on successful completion.
+ * The files->file_lock should be held on entry, and will be held on exit.
*/
static int expand_fdtable(struct files_struct *files, int nr)
__releases(files->file_lock)
__acquires(files->file_lock)
{
- int error = 0;
- struct fdtable *fdt;
- struct fdtable *nfdt = NULL;
+ struct fdtable *new_fdt, *cur_fdt;
spin_unlock(&files->file_lock);
- nfdt = alloc_fdtable(nr);
- if (!nfdt) {
- error = -ENOMEM;
- spin_lock(&files->file_lock);
- goto out;
- }
-
+ new_fdt = alloc_fdtable(nr);
spin_lock(&files->file_lock);
- fdt = files_fdtable(files);
+ if (!new_fdt)
+ return -ENOMEM;
/*
- * Check again since another task may have expanded the
- * fd table while we dropped the lock
+ * Check again since another task may have expanded the fd table while
+ * we dropped the lock
*/
- if (nr >= fdt->max_fds || nr >= fdt->max_fdset) {
- copy_fdtable(nfdt, fdt);
+ cur_fdt = files_fdtable(files);
+ if (nr >= cur_fdt->max_fds || nr >= cur_fdt->max_fdset) {
+ /* Continue as planned */
+ copy_fdtable(new_fdt, cur_fdt);
+ rcu_assign_pointer(files->fdt, new_fdt);
+ free_fdtable(cur_fdt);
} else {
- /* Somebody expanded while we dropped file_lock */
- spin_unlock(&files->file_lock);
- __free_fdtable(nfdt);
- spin_lock(&files->file_lock);
- goto out;
+ /* Somebody else expanded, so undo our attempt */
+ __free_fdtable(new_fdt);
}
- rcu_assign_pointer(files->fdt, nfdt);
- free_fdtable(fdt);
-out:
- return error;
+ return 1;
}
/*
* Expand files.
- * Return <0 on error; 0 nothing done; 1 files expanded, we may have blocked.
- * Should be called with the files->file_lock spinlock held for write.
+ * This function will expand the file structures, if the requested size exceeds
+ * the current capacity and there is room for expansion.
+ * Return <0 error code on error; 0 when nothing done; 1 when files were
+ * expanded and execution may have blocked.
+ * The files->file_lock should be held on entry, and will be held on exit.
*/
int expand_files(struct files_struct *files, int nr)
{
- int err, expand = 0;
struct fdtable *fdt;
fdt = files_fdtable(files);
- if (nr >= fdt->max_fdset || nr >= fdt->max_fds) {
- if (fdt->max_fdset >= NR_OPEN ||
- fdt->max_fds >= NR_OPEN || nr >= NR_OPEN) {
- err = -EMFILE;
- goto out;
- }
- expand = 1;
- if ((err = expand_fdtable(files, nr)))
- goto out;
- }
- err = expand;
-out:
- return err;
+ /* Do we need to expand? */
+ if (nr < fdt->max_fdset && nr < fdt->max_fds)
+ return 0;
+ /* Can we expand? */
+ if (fdt->max_fdset >= NR_OPEN || fdt->max_fds >= NR_OPEN ||
+ nr >= NR_OPEN)
+ return -EMFILE;
+
+ /* All good, so we try */
+ return expand_fdtable(files, nr);
}
static void __devinit fdtable_defer_list_init(int cpu)
diff --git a/fs/file_table.c b/fs/file_table.c
index bc35a40417d7..24f25a057d9c 100644
--- a/fs/file_table.c
+++ b/fs/file_table.c
@@ -174,6 +174,7 @@ void fastcall __fput(struct file *file)
fops_put(file->f_op);
if (file->f_mode & FMODE_WRITE)
put_write_access(inode);
+ put_pid(file->f_owner.pid);
file_kill(file);
file->f_dentry = NULL;
file->f_vfsmnt = NULL;
diff --git a/fs/filesystems.c b/fs/filesystems.c
index 9f1072836c8e..e3fa77c6ed56 100644
--- a/fs/filesystems.c
+++ b/fs/filesystems.c
@@ -69,8 +69,6 @@ int register_filesystem(struct file_system_type * fs)
int res = 0;
struct file_system_type ** p;
- if (!fs)
- return -EINVAL;
if (fs->next)
return -EBUSY;
INIT_LIST_HEAD(&fs->fs_supers);
diff --git a/fs/freevxfs/vxfs_super.c b/fs/freevxfs/vxfs_super.c
index b74b791fc23b..ac28b0835ffc 100644
--- a/fs/freevxfs/vxfs_super.c
+++ b/fs/freevxfs/vxfs_super.c
@@ -260,12 +260,17 @@ static struct file_system_type vxfs_fs_type = {
static int __init
vxfs_init(void)
{
+ int rv;
+
vxfs_inode_cachep = kmem_cache_create("vxfs_inode",
sizeof(struct vxfs_inode_info), 0,
SLAB_RECLAIM_ACCOUNT|SLAB_MEM_SPREAD, NULL, NULL);
- if (vxfs_inode_cachep)
- return register_filesystem(&vxfs_fs_type);
- return -ENOMEM;
+ if (!vxfs_inode_cachep)
+ return -ENOMEM;
+ rv = register_filesystem(&vxfs_fs_type);
+ if (rv < 0)
+ kmem_cache_destroy(vxfs_inode_cachep);
+ return rv;
}
static void __exit
diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c
index 892643dc9af1..c403b66ec83c 100644
--- a/fs/fs-writeback.c
+++ b/fs/fs-writeback.c
@@ -22,8 +22,7 @@
#include <linux/blkdev.h>
#include <linux/backing-dev.h>
#include <linux/buffer_head.h>
-
-extern struct super_block *blockdev_superblock;
+#include "internal.h"
/**
* __mark_inode_dirty - internal function
@@ -320,7 +319,7 @@ sync_sb_inodes(struct super_block *sb, struct writeback_control *wbc)
if (!bdi_cap_writeback_dirty(bdi)) {
list_move(&inode->i_list, &sb->s_dirty);
- if (sb == blockdev_superblock) {
+ if (sb_is_blkdev_sb(sb)) {
/*
* Dirty memory-backed blockdev: the ramdisk
* driver does this. Skip just this inode
@@ -337,14 +336,14 @@ sync_sb_inodes(struct super_block *sb, struct writeback_control *wbc)
if (wbc->nonblocking && bdi_write_congested(bdi)) {
wbc->encountered_congestion = 1;
- if (sb != blockdev_superblock)
+ if (!sb_is_blkdev_sb(sb))
break; /* Skip a congested fs */
list_move(&inode->i_list, &sb->s_dirty);
continue; /* Skip a congested blockdev */
}
if (wbc->bdi && bdi != wbc->bdi) {
- if (sb != blockdev_superblock)
+ if (!sb_is_blkdev_sb(sb))
break; /* fs has the wrong queue */
list_move(&inode->i_list, &sb->s_dirty);
continue; /* blockdev has wrong queue */
diff --git a/fs/fuse/control.c b/fs/fuse/control.c
index 79ec1f23d4d2..16b39c053d47 100644
--- a/fs/fuse/control.c
+++ b/fs/fuse/control.c
@@ -116,7 +116,7 @@ int fuse_ctl_add_conn(struct fuse_conn *fc)
return 0;
parent = fuse_control_sb->s_root;
- parent->d_inode->i_nlink++;
+ inc_nlink(parent->d_inode);
sprintf(name, "%llu", (unsigned long long) fc->id);
parent = fuse_ctl_add_dentry(parent, fc, name, S_IFDIR | 0500, 2,
&simple_dir_inode_operations,
diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c
index 1e2006caf158..66571eafbb1e 100644
--- a/fs/fuse/dev.c
+++ b/fs/fuse/dev.c
@@ -212,6 +212,7 @@ void fuse_put_request(struct fuse_conn *fc, struct fuse_req *req)
* Called with fc->lock, unlocks it
*/
static void request_end(struct fuse_conn *fc, struct fuse_req *req)
+ __releases(fc->lock)
{
void (*end) (struct fuse_conn *, struct fuse_req *) = req->end;
req->end = NULL;
@@ -640,6 +641,7 @@ static void request_wait(struct fuse_conn *fc)
*/
static int fuse_read_interrupt(struct fuse_conn *fc, struct fuse_req *req,
const struct iovec *iov, unsigned long nr_segs)
+ __releases(fc->lock)
{
struct fuse_copy_state cs;
struct fuse_in_header ih;
@@ -678,14 +680,15 @@ static int fuse_read_interrupt(struct fuse_conn *fc, struct fuse_req *req,
* request_end(). Otherwise add it to the processing list, and set
* the 'sent' flag.
*/
-static ssize_t fuse_dev_readv(struct file *file, const struct iovec *iov,
- unsigned long nr_segs, loff_t *off)
+static ssize_t fuse_dev_read(struct kiocb *iocb, const struct iovec *iov,
+ unsigned long nr_segs, loff_t pos)
{
int err;
struct fuse_req *req;
struct fuse_in *in;
struct fuse_copy_state cs;
unsigned reqsize;
+ struct file *file = iocb->ki_filp;
struct fuse_conn *fc = fuse_get_conn(file);
if (!fc)
return -EPERM;
@@ -759,15 +762,6 @@ static ssize_t fuse_dev_readv(struct file *file, const struct iovec *iov,
return err;
}
-static ssize_t fuse_dev_read(struct file *file, char __user *buf,
- size_t nbytes, loff_t *off)
-{
- struct iovec iov;
- iov.iov_len = nbytes;
- iov.iov_base = buf;
- return fuse_dev_readv(file, &iov, 1, off);
-}
-
/* Look up request on processing list by unique ID */
static struct fuse_req *request_find(struct fuse_conn *fc, u64 unique)
{
@@ -812,15 +806,15 @@ static int copy_out_args(struct fuse_copy_state *cs, struct fuse_out *out,
* it from the list and copy the rest of the buffer to the request.
* The request is finished by calling request_end()
*/
-static ssize_t fuse_dev_writev(struct file *file, const struct iovec *iov,
- unsigned long nr_segs, loff_t *off)
+static ssize_t fuse_dev_write(struct kiocb *iocb, const struct iovec *iov,
+ unsigned long nr_segs, loff_t pos)
{
int err;
unsigned nbytes = iov_length(iov, nr_segs);
struct fuse_req *req;
struct fuse_out_header oh;
struct fuse_copy_state cs;
- struct fuse_conn *fc = fuse_get_conn(file);
+ struct fuse_conn *fc = fuse_get_conn(iocb->ki_filp);
if (!fc)
return -EPERM;
@@ -896,15 +890,6 @@ static ssize_t fuse_dev_writev(struct file *file, const struct iovec *iov,
return err;
}
-static ssize_t fuse_dev_write(struct file *file, const char __user *buf,
- size_t nbytes, loff_t *off)
-{
- struct iovec iov;
- iov.iov_len = nbytes;
- iov.iov_base = (char __user *) buf;
- return fuse_dev_writev(file, &iov, 1, off);
-}
-
static unsigned fuse_dev_poll(struct file *file, poll_table *wait)
{
unsigned mask = POLLOUT | POLLWRNORM;
@@ -1039,10 +1024,10 @@ static int fuse_dev_fasync(int fd, struct file *file, int on)
const struct file_operations fuse_dev_operations = {
.owner = THIS_MODULE,
.llseek = no_llseek,
- .read = fuse_dev_read,
- .readv = fuse_dev_readv,
- .write = fuse_dev_write,
- .writev = fuse_dev_writev,
+ .read = do_sync_read,
+ .aio_read = fuse_dev_read,
+ .write = do_sync_write,
+ .aio_write = fuse_dev_write,
.poll = fuse_dev_poll,
.release = fuse_dev_release,
.fasync = fuse_dev_fasync,
diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c
index 409ce6a7cca4..8605155db171 100644
--- a/fs/fuse/dir.c
+++ b/fs/fuse/dir.c
@@ -508,7 +508,7 @@ static int fuse_unlink(struct inode *dir, struct dentry *entry)
/* Set nlink to zero so the inode can be cleared, if
the inode does have more links this will be
discovered at the next lookup/getattr */
- inode->i_nlink = 0;
+ clear_nlink(inode);
fuse_invalidate_attr(inode);
fuse_invalidate_attr(dir);
fuse_invalidate_entry_cache(entry);
@@ -534,7 +534,7 @@ static int fuse_rmdir(struct inode *dir, struct dentry *entry)
err = req->out.h.error;
fuse_put_request(fc, req);
if (!err) {
- entry->d_inode->i_nlink = 0;
+ clear_nlink(entry->d_inode);
fuse_invalidate_attr(dir);
fuse_invalidate_entry_cache(entry);
} else if (err == -EINTR)
@@ -776,7 +776,7 @@ static int fuse_permission(struct inode *inode, int mask, struct nameidata *nd)
if ((mask & MAY_EXEC) && !S_ISDIR(mode) && !(mode & S_IXUGO))
return -EACCES;
- if (nd && (nd->flags & LOOKUP_ACCESS))
+ if (nd && (nd->flags & (LOOKUP_ACCESS | LOOKUP_CHDIR)))
return fuse_access(inode, mask);
return 0;
}
diff --git a/fs/fuse/file.c b/fs/fuse/file.c
index 5c4fcd1dbf59..183626868eea 100644
--- a/fs/fuse/file.c
+++ b/fs/fuse/file.c
@@ -753,8 +753,10 @@ static int fuse_file_lock(struct file *file, int cmd, struct file_lock *fl)
static const struct file_operations fuse_file_operations = {
.llseek = generic_file_llseek,
- .read = generic_file_read,
- .write = generic_file_write,
+ .read = do_sync_read,
+ .aio_read = generic_file_aio_read,
+ .write = do_sync_write,
+ .aio_write = generic_file_aio_write,
.mmap = fuse_file_mmap,
.open = fuse_open,
.flush = fuse_flush,
diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c
index cb7cadb0b790..7d0a9aee01f2 100644
--- a/fs/fuse/inode.c
+++ b/fs/fuse/inode.c
@@ -251,6 +251,7 @@ static int fuse_statfs(struct dentry *dentry, struct kstatfs *buf)
memset(&outarg, 0, sizeof(outarg));
req->in.numargs = 0;
req->in.h.opcode = FUSE_STATFS;
+ req->in.h.nodeid = get_node_id(dentry->d_inode);
req->out.numargs = 1;
req->out.args[0].size =
fc->minor < 4 ? FUSE_COMPAT_STATFS_SIZE : sizeof(outarg);
diff --git a/fs/generic_acl.c b/fs/generic_acl.c
new file mode 100644
index 000000000000..9ccb78947171
--- /dev/null
+++ b/fs/generic_acl.c
@@ -0,0 +1,197 @@
+/*
+ * fs/generic_acl.c
+ *
+ * (C) 2005 Andreas Gruenbacher <agruen@suse.de>
+ *
+ * This file is released under the GPL.
+ */
+
+#include <linux/sched.h>
+#include <linux/fs.h>
+#include <linux/generic_acl.h>
+
+/**
+ * generic_acl_list - Generic xattr_handler->list() operation
+ * @ops: Filesystem specific getacl and setacl callbacks
+ */
+size_t
+generic_acl_list(struct inode *inode, struct generic_acl_operations *ops,
+ int type, char *list, size_t list_size)
+{
+ struct posix_acl *acl;
+ const char *name;
+ size_t size;
+
+ acl = ops->getacl(inode, type);
+ if (!acl)
+ return 0;
+ posix_acl_release(acl);
+
+ switch(type) {
+ case ACL_TYPE_ACCESS:
+ name = POSIX_ACL_XATTR_ACCESS;
+ break;
+
+ case ACL_TYPE_DEFAULT:
+ name = POSIX_ACL_XATTR_DEFAULT;
+ break;
+
+ default:
+ return 0;
+ }
+ size = strlen(name) + 1;
+ if (list && size <= list_size)
+ memcpy(list, name, size);
+ return size;
+}
+
+/**
+ * generic_acl_get - Generic xattr_handler->get() operation
+ * @ops: Filesystem specific getacl and setacl callbacks
+ */
+int
+generic_acl_get(struct inode *inode, struct generic_acl_operations *ops,
+ int type, void *buffer, size_t size)
+{
+ struct posix_acl *acl;
+ int error;
+
+ acl = ops->getacl(inode, type);
+ if (!acl)
+ return -ENODATA;
+ error = posix_acl_to_xattr(acl, buffer, size);
+ posix_acl_release(acl);
+
+ return error;
+}
+
+/**
+ * generic_acl_set - Generic xattr_handler->set() operation
+ * @ops: Filesystem specific getacl and setacl callbacks
+ */
+int
+generic_acl_set(struct inode *inode, struct generic_acl_operations *ops,
+ int type, const void *value, size_t size)
+{
+ struct posix_acl *acl = NULL;
+ int error;
+
+ if (S_ISLNK(inode->i_mode))
+ return -EOPNOTSUPP;
+ if (current->fsuid != inode->i_uid && !capable(CAP_FOWNER))
+ return -EPERM;
+ if (value) {
+ acl = posix_acl_from_xattr(value, size);
+ if (IS_ERR(acl))
+ return PTR_ERR(acl);
+ }
+ if (acl) {
+ mode_t mode;
+
+ error = posix_acl_valid(acl);
+ if (error)
+ goto failed;
+ switch(type) {
+ case ACL_TYPE_ACCESS:
+ mode = inode->i_mode;
+ error = posix_acl_equiv_mode(acl, &mode);
+ if (error < 0)
+ goto failed;
+ inode->i_mode = mode;
+ if (error == 0) {
+ posix_acl_release(acl);
+ acl = NULL;
+ }
+ break;
+
+ case ACL_TYPE_DEFAULT:
+ if (!S_ISDIR(inode->i_mode)) {
+ error = -EINVAL;
+ goto failed;
+ }
+ break;
+ }
+ }
+ ops->setacl(inode, type, acl);
+ error = 0;
+failed:
+ posix_acl_release(acl);
+ return error;
+}
+
+/**
+ * generic_acl_init - Take care of acl inheritance at @inode create time
+ * @ops: Filesystem specific getacl and setacl callbacks
+ *
+ * Files created inside a directory with a default ACL inherit the
+ * directory's default ACL.
+ */
+int
+generic_acl_init(struct inode *inode, struct inode *dir,
+ struct generic_acl_operations *ops)
+{
+ struct posix_acl *acl = NULL;
+ mode_t mode = inode->i_mode;
+ int error;
+
+ inode->i_mode = mode & ~current->fs->umask;
+ if (!S_ISLNK(inode->i_mode))
+ acl = ops->getacl(dir, ACL_TYPE_DEFAULT);
+ if (acl) {
+ struct posix_acl *clone;
+
+ if (S_ISDIR(inode->i_mode)) {
+ clone = posix_acl_clone(acl, GFP_KERNEL);
+ error = -ENOMEM;
+ if (!clone)
+ goto cleanup;
+ ops->setacl(inode, ACL_TYPE_DEFAULT, clone);
+ posix_acl_release(clone);
+ }
+ clone = posix_acl_clone(acl, GFP_KERNEL);
+ error = -ENOMEM;
+ if (!clone)
+ goto cleanup;
+ error = posix_acl_create_masq(clone, &mode);
+ if (error >= 0) {
+ inode->i_mode = mode;
+ if (error > 0)
+ ops->setacl(inode, ACL_TYPE_ACCESS, clone);
+ }
+ posix_acl_release(clone);
+ }
+ error = 0;
+
+cleanup:
+ posix_acl_release(acl);
+ return error;
+}
+
+/**
+ * generic_acl_chmod - change the access acl of @inode upon chmod()
+ * @ops: FIlesystem specific getacl and setacl callbacks
+ *
+ * A chmod also changes the permissions of the owner, group/mask, and
+ * other ACL entries.
+ */
+int
+generic_acl_chmod(struct inode *inode, struct generic_acl_operations *ops)
+{
+ struct posix_acl *acl, *clone;
+ int error = 0;
+
+ if (S_ISLNK(inode->i_mode))
+ return -EOPNOTSUPP;
+ acl = ops->getacl(inode, ACL_TYPE_ACCESS);
+ if (acl) {
+ clone = posix_acl_clone(acl, GFP_KERNEL);
+ posix_acl_release(acl);
+ if (!clone)
+ return -ENOMEM;
+ error = posix_acl_chmod_masq(clone, inode->i_mode);
+ if (!error)
+ ops->setacl(inode, ACL_TYPE_ACCESS, clone);
+ posix_acl_release(clone);
+ }
+ return error;
+}
diff --git a/fs/hfs/dir.c b/fs/hfs/dir.c
index 7cd8cc03aea7..37d681b4f216 100644
--- a/fs/hfs/dir.c
+++ b/fs/hfs/dir.c
@@ -246,7 +246,7 @@ static int hfs_unlink(struct inode *dir, struct dentry *dentry)
if (res)
return res;
- inode->i_nlink--;
+ drop_nlink(inode);
hfs_delete_inode(inode);
inode->i_ctime = CURRENT_TIME_SEC;
mark_inode_dirty(inode);
@@ -273,7 +273,7 @@ static int hfs_rmdir(struct inode *dir, struct dentry *dentry)
res = hfs_cat_delete(inode->i_ino, dir, &dentry->d_name);
if (res)
return res;
- inode->i_nlink = 0;
+ clear_nlink(inode);
inode->i_ctime = CURRENT_TIME_SEC;
hfs_delete_inode(inode);
mark_inode_dirty(inode);
diff --git a/fs/hfs/inode.c b/fs/hfs/inode.c
index d05641c35fc9..02f5573e0349 100644
--- a/fs/hfs/inode.c
+++ b/fs/hfs/inode.c
@@ -601,8 +601,10 @@ int hfs_inode_setattr(struct dentry *dentry, struct iattr * attr)
static const struct file_operations hfs_file_operations = {
.llseek = generic_file_llseek,
- .read = generic_file_read,
- .write = generic_file_write,
+ .read = do_sync_read,
+ .aio_read = generic_file_aio_read,
+ .write = do_sync_write,
+ .aio_write = generic_file_aio_write,
.mmap = generic_file_mmap,
.sendfile = generic_file_sendfile,
.fsync = file_fsync,
diff --git a/fs/hfsplus/dir.c b/fs/hfsplus/dir.c
index 1f9ece0de326..7e309751645f 100644
--- a/fs/hfsplus/dir.c
+++ b/fs/hfsplus/dir.c
@@ -298,7 +298,7 @@ static int hfsplus_link(struct dentry *src_dentry, struct inode *dst_dir,
if (res)
return res;
- inode->i_nlink++;
+ inc_nlink(inode);
hfsplus_instantiate(dst_dentry, inode, cnid);
atomic_inc(&inode->i_count);
inode->i_ctime = CURRENT_TIME_SEC;
@@ -338,7 +338,7 @@ static int hfsplus_unlink(struct inode *dir, struct dentry *dentry)
return res;
if (inode->i_nlink > 0)
- inode->i_nlink--;
+ drop_nlink(inode);
hfsplus_delete_inode(inode);
if (inode->i_ino != cnid && !inode->i_nlink) {
if (!atomic_read(&HFSPLUS_I(inode).opencnt)) {
@@ -348,7 +348,7 @@ static int hfsplus_unlink(struct inode *dir, struct dentry *dentry)
} else
inode->i_flags |= S_DEAD;
} else
- inode->i_nlink = 0;
+ clear_nlink(inode);
inode->i_ctime = CURRENT_TIME_SEC;
mark_inode_dirty(inode);
@@ -387,7 +387,7 @@ static int hfsplus_rmdir(struct inode *dir, struct dentry *dentry)
res = hfsplus_delete_cat(inode->i_ino, dir, &dentry->d_name);
if (res)
return res;
- inode->i_nlink = 0;
+ clear_nlink(inode);
inode->i_ctime = CURRENT_TIME_SEC;
hfsplus_delete_inode(inode);
mark_inode_dirty(inode);
diff --git a/fs/hfsplus/hfsplus_fs.h b/fs/hfsplus/hfsplus_fs.h
index 8a1ca5ef7ada..3915635b4470 100644
--- a/fs/hfsplus/hfsplus_fs.h
+++ b/fs/hfsplus/hfsplus_fs.h
@@ -246,12 +246,8 @@ struct hfsplus_readdir_data {
/* ext2 ioctls (EXT2_IOC_GETFLAGS and EXT2_IOC_SETFLAGS) to support
* chattr/lsattr */
-#define HFSPLUS_IOC_EXT2_GETFLAGS _IOR('f', 1, long)
-#define HFSPLUS_IOC_EXT2_SETFLAGS _IOW('f', 2, long)
-
-#define EXT2_FLAG_IMMUTABLE 0x00000010 /* Immutable file */
-#define EXT2_FLAG_APPEND 0x00000020 /* writes to file may only append */
-#define EXT2_FLAG_NODUMP 0x00000040 /* do not dump file */
+#define HFSPLUS_IOC_EXT2_GETFLAGS FS_IOC_GETFLAGS
+#define HFSPLUS_IOC_EXT2_SETFLAGS FS_IOC_SETFLAGS
/*
diff --git a/fs/hfsplus/inode.c b/fs/hfsplus/inode.c
index 0eb1a6092668..9e3675249633 100644
--- a/fs/hfsplus/inode.c
+++ b/fs/hfsplus/inode.c
@@ -282,8 +282,10 @@ static struct inode_operations hfsplus_file_inode_operations = {
static const struct file_operations hfsplus_file_operations = {
.llseek = generic_file_llseek,
- .read = generic_file_read,
- .write = generic_file_write,
+ .read = do_sync_read,
+ .aio_read = generic_file_aio_read,
+ .write = do_sync_write,
+ .aio_write = generic_file_aio_write,
.mmap = generic_file_mmap,
.sendfile = generic_file_sendfile,
.fsync = file_fsync,
diff --git a/fs/hfsplus/ioctl.c b/fs/hfsplus/ioctl.c
index 13cf848ac833..79fd10402ea3 100644
--- a/fs/hfsplus/ioctl.c
+++ b/fs/hfsplus/ioctl.c
@@ -28,11 +28,11 @@ int hfsplus_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
case HFSPLUS_IOC_EXT2_GETFLAGS:
flags = 0;
if (HFSPLUS_I(inode).rootflags & HFSPLUS_FLG_IMMUTABLE)
- flags |= EXT2_FLAG_IMMUTABLE; /* EXT2_IMMUTABLE_FL */
+ flags |= FS_IMMUTABLE_FL; /* EXT2_IMMUTABLE_FL */
if (HFSPLUS_I(inode).rootflags & HFSPLUS_FLG_APPEND)
- flags |= EXT2_FLAG_APPEND; /* EXT2_APPEND_FL */
+ flags |= FS_APPEND_FL; /* EXT2_APPEND_FL */
if (HFSPLUS_I(inode).userflags & HFSPLUS_FLG_NODUMP)
- flags |= EXT2_FLAG_NODUMP; /* EXT2_NODUMP_FL */
+ flags |= FS_NODUMP_FL; /* EXT2_NODUMP_FL */
return put_user(flags, (int __user *)arg);
case HFSPLUS_IOC_EXT2_SETFLAGS: {
if (IS_RDONLY(inode))
@@ -44,32 +44,31 @@ int hfsplus_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
if (get_user(flags, (int __user *)arg))
return -EFAULT;
- if (flags & (EXT2_FLAG_IMMUTABLE|EXT2_FLAG_APPEND) ||
+ if (flags & (FS_IMMUTABLE_FL|FS_APPEND_FL) ||
HFSPLUS_I(inode).rootflags & (HFSPLUS_FLG_IMMUTABLE|HFSPLUS_FLG_APPEND)) {
if (!capable(CAP_LINUX_IMMUTABLE))
return -EPERM;
}
/* don't silently ignore unsupported ext2 flags */
- if (flags & ~(EXT2_FLAG_IMMUTABLE|EXT2_FLAG_APPEND|
- EXT2_FLAG_NODUMP))
+ if (flags & ~(FS_IMMUTABLE_FL|FS_APPEND_FL|FS_NODUMP_FL))
return -EOPNOTSUPP;
- if (flags & EXT2_FLAG_IMMUTABLE) { /* EXT2_IMMUTABLE_FL */
+ if (flags & FS_IMMUTABLE_FL) { /* EXT2_IMMUTABLE_FL */
inode->i_flags |= S_IMMUTABLE;
HFSPLUS_I(inode).rootflags |= HFSPLUS_FLG_IMMUTABLE;
} else {
inode->i_flags &= ~S_IMMUTABLE;
HFSPLUS_I(inode).rootflags &= ~HFSPLUS_FLG_IMMUTABLE;
}
- if (flags & EXT2_FLAG_APPEND) { /* EXT2_APPEND_FL */
+ if (flags & FS_APPEND_FL) { /* EXT2_APPEND_FL */
inode->i_flags |= S_APPEND;
HFSPLUS_I(inode).rootflags |= HFSPLUS_FLG_APPEND;
} else {
inode->i_flags &= ~S_APPEND;
HFSPLUS_I(inode).rootflags &= ~HFSPLUS_FLG_APPEND;
}
- if (flags & EXT2_FLAG_NODUMP) /* EXT2_NODUMP_FL */
+ if (flags & FS_NODUMP_FL) /* EXT2_NODUMP_FL */
HFSPLUS_I(inode).userflags |= HFSPLUS_FLG_NODUMP;
else
HFSPLUS_I(inode).userflags &= ~HFSPLUS_FLG_NODUMP;
diff --git a/fs/hostfs/hostfs_kern.c b/fs/hostfs/hostfs_kern.c
index 322e876c35ed..b6bd33ca3731 100644
--- a/fs/hostfs/hostfs_kern.c
+++ b/fs/hostfs/hostfs_kern.c
@@ -385,13 +385,11 @@ int hostfs_fsync(struct file *file, struct dentry *dentry, int datasync)
static const struct file_operations hostfs_file_fops = {
.llseek = generic_file_llseek,
- .read = generic_file_read,
+ .read = do_sync_read,
.sendfile = generic_file_sendfile,
.aio_read = generic_file_aio_read,
.aio_write = generic_file_aio_write,
- .readv = generic_file_readv,
- .writev = generic_file_writev,
- .write = generic_file_write,
+ .write = do_sync_write,
.mmap = generic_file_mmap,
.open = hostfs_file_open,
.release = NULL,
diff --git a/fs/hpfs/file.c b/fs/hpfs/file.c
index d9eb19b7b8ae..8b94d24855f0 100644
--- a/fs/hpfs/file.c
+++ b/fs/hpfs/file.c
@@ -113,7 +113,7 @@ static ssize_t hpfs_file_write(struct file *file, const char __user *buf,
{
ssize_t retval;
- retval = generic_file_write(file, buf, count, ppos);
+ retval = do_sync_write(file, buf, count, ppos);
if (retval > 0)
hpfs_i(file->f_dentry->d_inode)->i_dirty = 1;
return retval;
@@ -122,8 +122,10 @@ static ssize_t hpfs_file_write(struct file *file, const char __user *buf,
const struct file_operations hpfs_file_ops =
{
.llseek = generic_file_llseek,
- .read = generic_file_read,
+ .read = do_sync_read,
+ .aio_read = generic_file_aio_read,
.write = hpfs_file_write,
+ .aio_write = generic_file_aio_write,
.mmap = generic_file_mmap,
.release = hpfs_file_release,
.fsync = hpfs_file_fsync,
diff --git a/fs/hpfs/namei.c b/fs/hpfs/namei.c
index 59e7dc182a0c..2507e7393f3c 100644
--- a/fs/hpfs/namei.c
+++ b/fs/hpfs/namei.c
@@ -89,7 +89,7 @@ static int hpfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
brelse(bh);
hpfs_mark_4buffers_dirty(&qbh0);
hpfs_brelse4(&qbh0);
- dir->i_nlink++;
+ inc_nlink(dir);
insert_inode_hash(result);
if (result->i_uid != current->fsuid ||
@@ -434,7 +434,7 @@ again:
unlock_kernel();
return -ENOSPC;
default:
- inode->i_nlink--;
+ drop_nlink(inode);
err = 0;
}
goto out;
@@ -494,8 +494,8 @@ static int hpfs_rmdir(struct inode *dir, struct dentry *dentry)
err = -ENOSPC;
break;
default:
- dir->i_nlink--;
- inode->i_nlink = 0;
+ drop_nlink(dir);
+ clear_nlink(inode);
err = 0;
}
goto out;
@@ -590,7 +590,7 @@ static int hpfs_rename(struct inode *old_dir, struct dentry *old_dentry,
int r;
if ((r = hpfs_remove_dirent(old_dir, dno, dep, &qbh, 1)) != 2) {
if ((nde = map_dirent(new_dir, hpfs_i(new_dir)->i_dno, (char *)new_name, new_len, NULL, &qbh1))) {
- new_inode->i_nlink = 0;
+ clear_nlink(new_inode);
copy_de(nde, &de);
memcpy(nde->name, new_name, new_len);
hpfs_mark_4buffers_dirty(&qbh1);
@@ -635,8 +635,8 @@ static int hpfs_rename(struct inode *old_dir, struct dentry *old_dentry,
end:
hpfs_i(i)->i_parent_dir = new_dir->i_ino;
if (S_ISDIR(i->i_mode)) {
- new_dir->i_nlink++;
- old_dir->i_nlink--;
+ inc_nlink(new_dir);
+ drop_nlink(old_dir);
}
if ((fnode = hpfs_map_fnode(i->i_sb, i->i_ino, &bh))) {
fnode->up = new_dir->i_ino;
diff --git a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c
index e025a31b4c64..5e03b2f67b93 100644
--- a/fs/hugetlbfs/inode.c
+++ b/fs/hugetlbfs/inode.c
@@ -229,7 +229,7 @@ static void hugetlbfs_delete_inode(struct inode *inode)
clear_inode(inode);
}
-static void hugetlbfs_forget_inode(struct inode *inode)
+static void hugetlbfs_forget_inode(struct inode *inode) __releases(inode_lock)
{
struct super_block *sb = inode->i_sb;
@@ -377,7 +377,7 @@ static struct inode *hugetlbfs_get_inode(struct super_block *sb, uid_t uid,
inode->i_fop = &simple_dir_operations;
/* directory inodes start off with i_nlink == 2 (for "." entry) */
- inode->i_nlink++;
+ inc_nlink(inode);
break;
case S_IFLNK:
inode->i_op = &page_symlink_inode_operations;
@@ -418,7 +418,7 @@ static int hugetlbfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
{
int retval = hugetlbfs_mknod(dir, dentry, mode | S_IFDIR, 0);
if (!retval)
- dir->i_nlink++;
+ inc_nlink(dir);
return retval;
}
diff --git a/fs/inode.c b/fs/inode.c
index f5c04dd9ae8a..bf6bec4e54ff 100644
--- a/fs/inode.c
+++ b/fs/inode.c
@@ -133,7 +133,6 @@ static struct inode *alloc_inode(struct super_block *sb)
inode->i_bdev = NULL;
inode->i_cdev = NULL;
inode->i_rdev = 0;
- inode->i_security = NULL;
inode->dirtied_when = 0;
if (security_inode_alloc(inode)) {
if (inode->i_sb->s_op->destroy_inode)
@@ -363,27 +362,6 @@ int invalidate_inodes(struct super_block * sb)
}
EXPORT_SYMBOL(invalidate_inodes);
-
-int __invalidate_device(struct block_device *bdev)
-{
- struct super_block *sb = get_super(bdev);
- int res = 0;
-
- if (sb) {
- /*
- * no need to lock the super, get_super holds the
- * read mutex so the filesystem cannot go away
- * under us (->put_super runs with the write lock
- * hold).
- */
- shrink_dcache_sb(sb);
- res = invalidate_inodes(sb);
- drop_super(sb);
- }
- invalidate_bdev(bdev, 0);
- return res;
-}
-EXPORT_SYMBOL(__invalidate_device);
static int can_unuse(struct inode *inode)
{
@@ -679,7 +657,7 @@ static struct inode * get_new_inode_fast(struct super_block *sb, struct hlist_he
return inode;
}
-static inline unsigned long hash(struct super_block *sb, unsigned long hashval)
+static unsigned long hash(struct super_block *sb, unsigned long hashval)
{
unsigned long tmp;
@@ -1025,7 +1003,7 @@ void generic_delete_inode(struct inode *inode)
list_del_init(&inode->i_list);
list_del_init(&inode->i_sb_list);
- inode->i_state|=I_FREEING;
+ inode->i_state |= I_FREEING;
inodes_stat.nr_inodes--;
spin_unlock(&inode_lock);
@@ -1232,13 +1210,15 @@ void file_update_time(struct file *file)
return;
now = current_fs_time(inode->i_sb);
- if (!timespec_equal(&inode->i_mtime, &now))
+ if (!timespec_equal(&inode->i_mtime, &now)) {
+ inode->i_mtime = now;
sync_it = 1;
- inode->i_mtime = now;
+ }
- if (!timespec_equal(&inode->i_ctime, &now))
+ if (!timespec_equal(&inode->i_ctime, &now)) {
+ inode->i_ctime = now;
sync_it = 1;
- inode->i_ctime = now;
+ }
if (sync_it)
mark_inode_dirty_sync(inode);
diff --git a/fs/internal.h b/fs/internal.h
new file mode 100644
index 000000000000..ea00126c9a59
--- /dev/null
+++ b/fs/internal.h
@@ -0,0 +1,55 @@
+/* fs/ internal definitions
+ *
+ * Copyright (C) 2006 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * 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 <linux/ioctl32.h>
+
+struct super_block;
+
+/*
+ * block_dev.c
+ */
+#ifdef CONFIG_BLOCK
+extern struct super_block *blockdev_superblock;
+extern void __init bdev_cache_init(void);
+
+static inline int sb_is_blkdev_sb(struct super_block *sb)
+{
+ return sb == blockdev_superblock;
+}
+
+#else
+static inline void bdev_cache_init(void)
+{
+}
+
+static inline int sb_is_blkdev_sb(struct super_block *sb)
+{
+ return 0;
+}
+#endif
+
+/*
+ * char_dev.c
+ */
+extern void __init chrdev_init(void);
+
+/*
+ * compat_ioctl.c
+ */
+#ifdef CONFIG_COMPAT
+extern struct ioctl_trans ioctl_start[];
+extern int ioctl_table_size;
+#endif
+
+/*
+ * namespace.c
+ */
+extern int copy_mount_options(const void __user *, unsigned long *);
diff --git a/fs/ioprio.c b/fs/ioprio.c
index 78b1deae3fa2..6dc6721d9e82 100644
--- a/fs/ioprio.c
+++ b/fs/ioprio.c
@@ -1,7 +1,7 @@
/*
* fs/ioprio.c
*
- * Copyright (C) 2004 Jens Axboe <axboe@suse.de>
+ * Copyright (C) 2004 Jens Axboe <axboe@kernel.dk>
*
* Helper functions for setting/querying io priorities of processes. The
* system calls closely mimmick getpriority/setpriority, see the man page for
@@ -47,8 +47,8 @@ static int set_task_ioprio(struct task_struct *task, int ioprio)
/* see wmb() in current_io_context() */
smp_read_barrier_depends();
- if (ioc && ioc->set_ioprio)
- ioc->set_ioprio(ioc, ioprio);
+ if (ioc)
+ ioc->ioprio_changed = 1;
task_unlock(task);
return 0;
@@ -81,7 +81,12 @@ asmlinkage long sys_ioprio_set(int which, int who, int ioprio)
}
ret = -ESRCH;
- read_lock_irq(&tasklist_lock);
+ /*
+ * We want IOPRIO_WHO_PGRP/IOPRIO_WHO_USER to be "atomic",
+ * so we can't use rcu_read_lock(). See re-copy of ->ioprio
+ * in copy_process().
+ */
+ read_lock(&tasklist_lock);
switch (which) {
case IOPRIO_WHO_PROCESS:
if (!who)
@@ -124,7 +129,7 @@ free_uid:
ret = -EINVAL;
}
- read_unlock_irq(&tasklist_lock);
+ read_unlock(&tasklist_lock);
return ret;
}
@@ -170,7 +175,7 @@ asmlinkage long sys_ioprio_get(int which, int who)
int ret = -ESRCH;
int tmpio;
- read_lock_irq(&tasklist_lock);
+ read_lock(&tasklist_lock);
switch (which) {
case IOPRIO_WHO_PROCESS:
if (!who)
@@ -221,7 +226,7 @@ asmlinkage long sys_ioprio_get(int which, int who)
ret = -EINVAL;
}
- read_unlock_irq(&tasklist_lock);
+ read_unlock(&tasklist_lock);
return ret;
}
diff --git a/fs/isofs/inode.c b/fs/isofs/inode.c
index 4527692f432b..c34b862cdbf2 100644
--- a/fs/isofs/inode.c
+++ b/fs/isofs/inode.c
@@ -960,30 +960,30 @@ int isofs_get_blocks(struct inode *inode, sector_t iblock_s,
goto abort;
}
- if (nextblk) {
- while (b_off >= (offset + sect_size)) {
- struct inode *ninode;
-
- offset += sect_size;
- if (nextblk == 0)
- goto abort;
- ninode = isofs_iget(inode->i_sb, nextblk, nextoff);
- if (!ninode)
- goto abort;
- firstext = ISOFS_I(ninode)->i_first_extent;
- sect_size = ISOFS_I(ninode)->i_section_size >> ISOFS_BUFFER_BITS(ninode);
- nextblk = ISOFS_I(ninode)->i_next_section_block;
- nextoff = ISOFS_I(ninode)->i_next_section_offset;
- iput(ninode);
-
- if (++section > 100) {
- printk("isofs_get_blocks: More than 100 file sections ?!?, aborting...\n");
- printk("isofs_get_blocks: block=%ld firstext=%u sect_size=%u "
- "nextblk=%lu nextoff=%lu\n",
- iblock, firstext, (unsigned) sect_size,
- nextblk, nextoff);
- goto abort;
- }
+ /* On the last section, nextblk == 0, section size is likely to
+ * exceed sect_size by a partial block, and access beyond the
+ * end of the file will reach beyond the section size, too.
+ */
+ while (nextblk && (b_off >= (offset + sect_size))) {
+ struct inode *ninode;
+
+ offset += sect_size;
+ ninode = isofs_iget(inode->i_sb, nextblk, nextoff);
+ if (!ninode)
+ goto abort;
+ firstext = ISOFS_I(ninode)->i_first_extent;
+ sect_size = ISOFS_I(ninode)->i_section_size >> ISOFS_BUFFER_BITS(ninode);
+ nextblk = ISOFS_I(ninode)->i_next_section_block;
+ nextoff = ISOFS_I(ninode)->i_next_section_offset;
+ iput(ninode);
+
+ if (++section > 100) {
+ printk("isofs_get_blocks: More than 100 file sections ?!?, aborting...\n");
+ printk("isofs_get_blocks: block=%ld firstext=%u sect_size=%u "
+ "nextblk=%lu nextoff=%lu\n",
+ iblock, firstext, (unsigned) sect_size,
+ nextblk, nextoff);
+ goto abort;
}
}
diff --git a/fs/jbd/journal.c b/fs/jbd/journal.c
index 2fc66c3e6681..7af6099c911c 100644
--- a/fs/jbd/journal.c
+++ b/fs/jbd/journal.c
@@ -715,18 +715,8 @@ journal_t * journal_init_dev(struct block_device *bdev,
if (!journal)
return NULL;
- journal->j_dev = bdev;
- journal->j_fs_dev = fs_dev;
- journal->j_blk_offset = start;
- journal->j_maxlen = len;
- journal->j_blocksize = blocksize;
-
- bh = __getblk(journal->j_dev, start, journal->j_blocksize);
- J_ASSERT(bh != NULL);
- journal->j_sb_buffer = bh;
- journal->j_superblock = (journal_superblock_t *)bh->b_data;
-
/* journal descriptor can store up to n blocks -bzzz */
+ journal->j_blocksize = blocksize;
n = journal->j_blocksize / sizeof(journal_block_tag_t);
journal->j_wbufsize = n;
journal->j_wbuf = kmalloc(n * sizeof(struct buffer_head*), GFP_KERNEL);
@@ -736,6 +726,15 @@ journal_t * journal_init_dev(struct block_device *bdev,
kfree(journal);
journal = NULL;
}
+ journal->j_dev = bdev;
+ journal->j_fs_dev = fs_dev;
+ journal->j_blk_offset = start;
+ journal->j_maxlen = len;
+
+ bh = __getblk(journal->j_dev, start, journal->j_blocksize);
+ J_ASSERT(bh != NULL);
+ journal->j_sb_buffer = bh;
+ journal->j_superblock = (journal_superblock_t *)bh->b_data;
return journal;
}
diff --git a/fs/jbd/recovery.c b/fs/jbd/recovery.c
index 445eed6ce5dc..11563fe2a52b 100644
--- a/fs/jbd/recovery.c
+++ b/fs/jbd/recovery.c
@@ -46,7 +46,7 @@ static int scan_revoke_records(journal_t *, struct buffer_head *,
#ifdef __KERNEL__
/* Release readahead buffers after use */
-void journal_brelse_array(struct buffer_head *b[], int n)
+static void journal_brelse_array(struct buffer_head *b[], int n)
{
while (--n >= 0)
brelse (b[n]);
diff --git a/fs/jffs/inode-v23.c b/fs/jffs/inode-v23.c
index f5cf9c93e243..3f7899ea4cba 100644
--- a/fs/jffs/inode-v23.c
+++ b/fs/jffs/inode-v23.c
@@ -1052,9 +1052,8 @@ jffs_remove(struct inode *dir, struct dentry *dentry, int type)
dir->i_ctime = dir->i_mtime = CURRENT_TIME_SEC;
mark_inode_dirty(dir);
- inode->i_nlink--;
inode->i_ctime = dir->i_ctime;
- mark_inode_dirty(inode);
+ inode_dec_link_count(inode);
d_delete(dentry); /* This also frees the inode */
@@ -1632,8 +1631,10 @@ static const struct file_operations jffs_file_operations =
{
.open = generic_file_open,
.llseek = generic_file_llseek,
- .read = generic_file_read,
- .write = generic_file_write,
+ .read = do_sync_read,
+ .aio_read = generic_file_aio_read,
+ .write = do_sync_write,
+ .aio_write = generic_file_aio_write,
.ioctl = jffs_ioctl,
.mmap = generic_file_readonly_mmap,
.fsync = jffs_fsync,
diff --git a/fs/jffs2/dir.c b/fs/jffs2/dir.c
index edd8371fc6a5..9def6adf4a5d 100644
--- a/fs/jffs2/dir.c
+++ b/fs/jffs2/dir.c
@@ -588,7 +588,7 @@ static int jffs2_mkdir (struct inode *dir_i, struct dentry *dentry, int mode)
}
dir_i->i_mtime = dir_i->i_ctime = ITIME(je32_to_cpu(rd->mctime));
- dir_i->i_nlink++;
+ inc_nlink(dir_i);
jffs2_free_raw_dirent(rd);
@@ -615,7 +615,7 @@ static int jffs2_rmdir (struct inode *dir_i, struct dentry *dentry)
}
ret = jffs2_unlink(dir_i, dentry);
if (!ret)
- dir_i->i_nlink--;
+ drop_nlink(dir_i);
return ret;
}
@@ -823,7 +823,7 @@ static int jffs2_rename (struct inode *old_dir_i, struct dentry *old_dentry,
if (victim_f) {
/* There was a victim. Kill it off nicely */
- new_dentry->d_inode->i_nlink--;
+ drop_nlink(new_dentry->d_inode);
/* Don't oops if the victim was a dirent pointing to an
inode which didn't exist. */
if (victim_f->inocache) {
@@ -836,7 +836,7 @@ static int jffs2_rename (struct inode *old_dir_i, struct dentry *old_dentry,
/* If it was a directory we moved, and there was no victim,
increase i_nlink on its new parent */
if (S_ISDIR(old_dentry->d_inode->i_mode) && !victim_f)
- new_dir_i->i_nlink++;
+ inc_nlink(new_dir_i);
/* Unlink the original */
ret = jffs2_do_unlink(c, JFFS2_INODE_INFO(old_dir_i),
@@ -848,7 +848,7 @@ static int jffs2_rename (struct inode *old_dir_i, struct dentry *old_dentry,
/* Oh shit. We really ought to make a single node which can do both atomically */
struct jffs2_inode_info *f = JFFS2_INODE_INFO(old_dentry->d_inode);
down(&f->sem);
- old_dentry->d_inode->i_nlink++;
+ inc_nlink(old_dentry->d_inode);
if (f->inocache)
f->inocache->nlink++;
up(&f->sem);
@@ -862,7 +862,7 @@ static int jffs2_rename (struct inode *old_dir_i, struct dentry *old_dentry,
}
if (S_ISDIR(old_dentry->d_inode->i_mode))
- old_dir_i->i_nlink--;
+ drop_nlink(old_dir_i);
new_dir_i->i_mtime = new_dir_i->i_ctime = old_dir_i->i_mtime = old_dir_i->i_ctime = ITIME(now);
diff --git a/fs/jffs2/file.c b/fs/jffs2/file.c
index 3ed6e3e120b6..242875f77cb3 100644
--- a/fs/jffs2/file.c
+++ b/fs/jffs2/file.c
@@ -42,8 +42,10 @@ const struct file_operations jffs2_file_operations =
{
.llseek = generic_file_llseek,
.open = generic_file_open,
- .read = generic_file_read,
- .write = generic_file_write,
+ .read = do_sync_read,
+ .aio_read = generic_file_aio_read,
+ .write = do_sync_write,
+ .aio_write = generic_file_aio_write,
.ioctl = jffs2_ioctl,
.mmap = generic_file_readonly_mmap,
.fsync = jffs2_fsync,
diff --git a/fs/jffs2/fs.c b/fs/jffs2/fs.c
index 72d9909d95ff..7bc1a4201c0c 100644
--- a/fs/jffs2/fs.c
+++ b/fs/jffs2/fs.c
@@ -277,13 +277,13 @@ void jffs2_read_inode (struct inode *inode)
for (fd=f->dents; fd; fd = fd->next) {
if (fd->type == DT_DIR && fd->ino)
- inode->i_nlink++;
+ inc_nlink(inode);
}
/* and '..' */
- inode->i_nlink++;
+ inc_nlink(inode);
/* Root dir gets i_nlink 3 for some reason */
if (inode->i_ino == 1)
- inode->i_nlink++;
+ inc_nlink(inode);
inode->i_op = &jffs2_dir_inode_operations;
inode->i_fop = &jffs2_dir_operations;
diff --git a/fs/jfs/acl.c b/fs/jfs/acl.c
index e2281300979c..4d84bdc88299 100644
--- a/fs/jfs/acl.c
+++ b/fs/jfs/acl.c
@@ -5,16 +5,16 @@
*
* 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
+ * 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
+ * along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
@@ -183,7 +183,7 @@ cleanup:
posix_acl_release(acl);
} else
inode->i_mode &= ~current->fs->umask;
-
+
JFS_IP(inode)->mode2 = (JFS_IP(inode)->mode2 & 0xffff0000) |
inode->i_mode;
diff --git a/fs/jfs/endian24.h b/fs/jfs/endian24.h
index ab7cd0567c95..79494c4f2b10 100644
--- a/fs/jfs/endian24.h
+++ b/fs/jfs/endian24.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) International Business Machines Corp., 2001
+ * Copyright (C) International Business Machines Corp., 2001
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
diff --git a/fs/jfs/file.c b/fs/jfs/file.c
index 1c9745be5ada..34181b8f5a0a 100644
--- a/fs/jfs/file.c
+++ b/fs/jfs/file.c
@@ -4,16 +4,16 @@
*
* 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
+ * 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
+ * along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
@@ -103,14 +103,12 @@ struct inode_operations jfs_file_inode_operations = {
const struct file_operations jfs_file_operations = {
.open = jfs_open,
.llseek = generic_file_llseek,
- .write = generic_file_write,
- .read = generic_file_read,
+ .write = do_sync_write,
+ .read = do_sync_read,
.aio_read = generic_file_aio_read,
.aio_write = generic_file_aio_write,
.mmap = generic_file_mmap,
- .readv = generic_file_readv,
- .writev = generic_file_writev,
- .sendfile = generic_file_sendfile,
+ .sendfile = generic_file_sendfile,
.fsync = jfs_fsync,
.release = jfs_release,
.ioctl = jfs_ioctl,
diff --git a/fs/jfs/inode.c b/fs/jfs/inode.c
index a223cf4faa9b..f5719117edfe 100644
--- a/fs/jfs/inode.c
+++ b/fs/jfs/inode.c
@@ -4,16 +4,16 @@
*
* 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
+ * 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
+ * along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
@@ -33,7 +33,7 @@
void jfs_read_inode(struct inode *inode)
{
- if (diRead(inode)) {
+ if (diRead(inode)) {
make_bad_inode(inode);
return;
}
@@ -227,7 +227,7 @@ int jfs_get_block(struct inode *ip, sector_t lblock,
#ifdef _JFS_4K
if ((rc = extHint(ip, lblock64 << ip->i_sb->s_blocksize_bits, &xad)))
goto unlock;
- rc = extAlloc(ip, xlen, lblock64, &xad, FALSE);
+ rc = extAlloc(ip, xlen, lblock64, &xad, false);
if (rc)
goto unlock;
diff --git a/fs/jfs/ioctl.c b/fs/jfs/ioctl.c
index 67b3774820eb..37db52488262 100644
--- a/fs/jfs/ioctl.c
+++ b/fs/jfs/ioctl.c
@@ -6,7 +6,6 @@
*/
#include <linux/fs.h>
-#include <linux/ext2_fs.h>
#include <linux/ctype.h>
#include <linux/capability.h>
#include <linux/time.h>
@@ -22,13 +21,13 @@ static struct {
long jfs_flag;
long ext2_flag;
} jfs_map[] = {
- {JFS_NOATIME_FL, EXT2_NOATIME_FL},
- {JFS_DIRSYNC_FL, EXT2_DIRSYNC_FL},
- {JFS_SYNC_FL, EXT2_SYNC_FL},
- {JFS_SECRM_FL, EXT2_SECRM_FL},
- {JFS_UNRM_FL, EXT2_UNRM_FL},
- {JFS_APPEND_FL, EXT2_APPEND_FL},
- {JFS_IMMUTABLE_FL, EXT2_IMMUTABLE_FL},
+ {JFS_NOATIME_FL, FS_NOATIME_FL},
+ {JFS_DIRSYNC_FL, FS_DIRSYNC_FL},
+ {JFS_SYNC_FL, FS_SYNC_FL},
+ {JFS_SECRM_FL, FS_SECRM_FL},
+ {JFS_UNRM_FL, FS_UNRM_FL},
+ {JFS_APPEND_FL, FS_APPEND_FL},
+ {JFS_IMMUTABLE_FL, FS_IMMUTABLE_FL},
{0, 0},
};
diff --git a/fs/jfs/jfs_acl.h b/fs/jfs/jfs_acl.h
index a76293767c73..455fa4292045 100644
--- a/fs/jfs/jfs_acl.h
+++ b/fs/jfs/jfs_acl.h
@@ -1,18 +1,18 @@
/*
- * Copyright (c) International Business Machines Corp., 2002
+ * Copyright (C) International Business Machines Corp., 2002
*
* 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
+ * 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
+ * along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef _H_JFS_ACL
diff --git a/fs/jfs/jfs_btree.h b/fs/jfs/jfs_btree.h
index 7f3e9ac454ff..79c61805bd33 100644
--- a/fs/jfs/jfs_btree.h
+++ b/fs/jfs/jfs_btree.h
@@ -3,16 +3,16 @@
*
* 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
+ * 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
+ * along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef _H_JFS_BTREE
diff --git a/fs/jfs/jfs_debug.c b/fs/jfs/jfs_debug.c
index 81f0e514c490..9c5d59632aac 100644
--- a/fs/jfs/jfs_debug.c
+++ b/fs/jfs/jfs_debug.c
@@ -4,16 +4,16 @@
*
* 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
+ * 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
+ * along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
diff --git a/fs/jfs/jfs_dinode.h b/fs/jfs/jfs_dinode.h
index 9f2572aea561..40b20111383c 100644
--- a/fs/jfs/jfs_dinode.h
+++ b/fs/jfs/jfs_dinode.h
@@ -1,18 +1,18 @@
/*
- * Copyright (c) International Business Machines Corp., 2000-2001
+ * Copyright (C) International Business Machines Corp., 2000-2001
*
* 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
+ * 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
+ * along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef _H_JFS_DINODE
diff --git a/fs/jfs/jfs_dmap.c b/fs/jfs/jfs_dmap.c
index c161c98954e0..23546c8fd48b 100644
--- a/fs/jfs/jfs_dmap.c
+++ b/fs/jfs/jfs_dmap.c
@@ -3,16 +3,16 @@
*
* 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
+ * 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
+ * along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
@@ -30,28 +30,28 @@
*
* the working state of the block allocation map is accessed in
* two directions:
- *
+ *
* 1) allocation and free requests that start at the dmap
* level and move up through the dmap control pages (i.e.
* the vast majority of requests).
- *
- * 2) allocation requests that start at dmap control page
+ *
+ * 2) allocation requests that start at dmap control page
* level and work down towards the dmaps.
- *
- * the serialization scheme used here is as follows.
*
- * requests which start at the bottom are serialized against each
- * other through buffers and each requests holds onto its buffers
- * as it works it way up from a single dmap to the required level
+ * the serialization scheme used here is as follows.
+ *
+ * requests which start at the bottom are serialized against each
+ * other through buffers and each requests holds onto its buffers
+ * as it works it way up from a single dmap to the required level
* of dmap control page.
* requests that start at the top are serialized against each other
* and request that start from the bottom by the multiple read/single
* write inode lock of the bmap inode. requests starting at the top
* take this lock in write mode while request starting at the bottom
* take the lock in read mode. a single top-down request may proceed
- * exclusively while multiple bottoms-up requests may proceed
- * simultaneously (under the protection of busy buffers).
- *
+ * exclusively while multiple bottoms-up requests may proceed
+ * simultaneously (under the protection of busy buffers).
+ *
* in addition to information found in dmaps and dmap control pages,
* the working state of the block allocation map also includes read/
* write information maintained in the bmap descriptor (i.e. total
@@ -59,7 +59,7 @@
* a single exclusive lock (BMAP_LOCK) is used to guard this information
* in the face of multiple-bottoms up requests.
* (lock ordering: IREAD_LOCK, BMAP_LOCK);
- *
+ *
* accesses to the persistent state of the block allocation map (limited
* to the persistent bitmaps in dmaps) is guarded by (busy) buffers.
*/
@@ -120,7 +120,7 @@ static int dbGetL2AGSize(s64 nblocks);
/*
* buddy table
*
- * table used for determining buddy sizes within characters of
+ * table used for determining buddy sizes within characters of
* dmap bitmap words. the characters themselves serve as indexes
* into the table, with the table elements yielding the maximum
* binary buddy of free bits within the character.
@@ -146,7 +146,7 @@ static const s8 budtab[256] = {
/*
- * NAME: dbMount()
+ * NAME: dbMount()
*
* FUNCTION: initializate the block allocation map.
*
@@ -223,12 +223,12 @@ int dbMount(struct inode *ipbmap)
/*
- * NAME: dbUnmount()
+ * NAME: dbUnmount()
*
* FUNCTION: terminate the block allocation map in preparation for
* file system unmount.
*
- * the in-core bmap descriptor is written to disk and
+ * the in-core bmap descriptor is written to disk and
* the memory for this descriptor is freed.
*
* PARAMETERS:
@@ -311,7 +311,7 @@ int dbSync(struct inode *ipbmap)
/*
- * NAME: dbFree()
+ * NAME: dbFree()
*
* FUNCTION: free the specified block range from the working block
* allocation map.
@@ -397,14 +397,14 @@ int dbFree(struct inode *ip, s64 blkno, s64 nblocks)
*
* FUNCTION: update the allocation state (free or allocate) of the
* specified block range in the persistent block allocation map.
- *
+ *
* the blocks will be updated in the persistent map one
* dmap at a time.
*
* PARAMETERS:
* ipbmap - pointer to in-core inode for the block map.
- * free - TRUE if block range is to be freed from the persistent
- * map; FALSE if it is to be allocated.
+ * free - 'true' if block range is to be freed from the persistent
+ * map; 'false' if it is to be allocated.
* blkno - starting block number of the range.
* nblocks - number of contiguous blocks in the range.
* tblk - transaction block;
@@ -475,7 +475,7 @@ dbUpdatePMap(struct inode *ipbmap,
/* update the bits of the dmap words. the first and last
* words may only have a subset of their bits updated. if
* this is the case, we'll work against that word (i.e.
- * partial first and/or last) only in a single pass. a
+ * partial first and/or last) only in a single pass. a
* single pass will also be used to update all words that
* are to have all their bits updated.
*/
@@ -662,11 +662,11 @@ unlock:
* the block allocation policy uses hints and a multi-step
* approach.
*
- * for allocation requests smaller than the number of blocks
+ * for allocation requests smaller than the number of blocks
* per dmap, we first try to allocate the new blocks
* immediately following the hint. if these blocks are not
* available, we try to allocate blocks near the hint. if
- * no blocks near the hint are available, we next try to
+ * no blocks near the hint are available, we next try to
* allocate within the same dmap as contains the hint.
*
* if no blocks are available in the dmap or the allocation
@@ -713,7 +713,7 @@ int dbAlloc(struct inode *ip, s64 hint, s64 nblocks, s64 * results)
#endif /* _STILL_TO_PORT */
/* get the log2 number of blocks to be allocated.
- * if the number of blocks is not a log2 multiple,
+ * if the number of blocks is not a log2 multiple,
* it will be rounded up to the next log2 multiple.
*/
l2nb = BLKSTOL2(nblocks);
@@ -906,7 +906,7 @@ int dbAllocExact(struct inode *ip, s64 blkno, int nblocks)
* validate extent request:
*
* note: defragfs policy:
- * max 64 blocks will be moved.
+ * max 64 blocks will be moved.
* allocation request size must be satisfied from a single dmap.
*/
if (nblocks <= 0 || nblocks > BPERDMAP || blkno >= bmp->db_mapsize) {
@@ -1333,7 +1333,7 @@ dbAllocNear(struct bmap * bmp,
* or two sub-trees, depending on the allocation group size.
* we search the top nodes of these subtrees left to right for
* sufficient free space. if sufficient free space is found,
- * the subtree is searched to find the leftmost leaf that
+ * the subtree is searched to find the leftmost leaf that
* has free space. once we have made it to the leaf, we
* move the search to the next lower level dmap control page
* corresponding to this leaf. we continue down the dmap control
@@ -1398,7 +1398,7 @@ dbAllocAG(struct bmap * bmp, int agno, s64 nblocks, int l2nb, s64 * results)
* that fully describes the allocation group since the allocation
* group is already fully described by a dmap. in this case, we
* just call dbAllocCtl() to search the dmap tree and allocate the
- * required space if available.
+ * required space if available.
*
* if the allocation group is completely free, dbAllocCtl() is
* also called to allocate the required space. this is done for
@@ -1450,7 +1450,7 @@ dbAllocAG(struct bmap * bmp, int agno, s64 nblocks, int l2nb, s64 * results)
(1 << (L2LPERCTL - (bmp->db_agheigth << 1))) / bmp->db_agwidth;
ti = bmp->db_agstart + bmp->db_agwidth * (agno & (agperlev - 1));
- /* dmap control page trees fan-out by 4 and a single allocation
+ /* dmap control page trees fan-out by 4 and a single allocation
* group may be described by 1 or 2 subtrees within the ag level
* dmap control page, depending upon the ag size. examine the ag's
* subtrees for sufficient free space, starting with the leftmost
@@ -1633,7 +1633,7 @@ static int dbFindCtl(struct bmap * bmp, int l2nb, int level, s64 * blkno)
/* starting at the specified dmap control page level and block
* number, search down the dmap control levels for the starting
- * block number of a dmap page that contains or starts off
+ * block number of a dmap page that contains or starts off
* sufficient free blocks.
*/
for (lev = level, b = *blkno; lev >= 0; lev--) {
@@ -1677,7 +1677,7 @@ static int dbFindCtl(struct bmap * bmp, int l2nb, int level, s64 * blkno)
}
/* adjust the block number to reflect the location within
- * the dmap control page (i.e. the leaf) at which free
+ * the dmap control page (i.e. the leaf) at which free
* space was found.
*/
b += (((s64) leafidx) << budmin);
@@ -1700,12 +1700,12 @@ static int dbFindCtl(struct bmap * bmp, int l2nb, int level, s64 * blkno)
* NAME: dbAllocCtl()
*
* FUNCTION: attempt to allocate a specified number of contiguous
- * blocks starting within a specific dmap.
- *
+ * blocks starting within a specific dmap.
+ *
* this routine is called by higher level routines that search
* the dmap control pages above the actual dmaps for contiguous
* free space. the result of successful searches by these
- * routines are the starting block numbers within dmaps, with
+ * routines are the starting block numbers within dmaps, with
* the dmaps themselves containing the desired contiguous free
* space or starting a contiguous free space of desired size
* that is made up of the blocks of one or more dmaps. these
@@ -1872,14 +1872,14 @@ dbAllocCtl(struct bmap * bmp, s64 nblocks, int l2nb, s64 blkno, s64 * results)
*
* FUNCTION: attempt to allocate a specified number of contiguous blocks
* from a specified dmap.
- *
+ *
* this routine checks if the contiguous blocks are available.
* if so, nblocks of blocks are allocated; otherwise, ENOSPC is
* returned.
*
* PARAMETERS:
* mp - pointer to bmap descriptor
- * dp - pointer to dmap to attempt to allocate blocks from.
+ * dp - pointer to dmap to attempt to allocate blocks from.
* l2nb - log2 number of contiguous block desired.
* nblocks - actual number of contiguous block desired.
* results - on successful return, set to the starting block number
@@ -1890,7 +1890,7 @@ dbAllocCtl(struct bmap * bmp, s64 nblocks, int l2nb, s64 blkno, s64 * results)
* -ENOSPC - insufficient disk resources
* -EIO - i/o error
*
- * serialization: IREAD_LOCK(ipbmap), e.g., from dbAlloc(), or
+ * serialization: IREAD_LOCK(ipbmap), e.g., from dbAlloc(), or
* IWRITE_LOCK(ipbmap), e.g., dbAllocCtl(), held on entry/exit;
*/
static int
@@ -2032,7 +2032,7 @@ static int dbFreeDmap(struct bmap * bmp, struct dmap * dp, s64 blkno,
/* root changed. bubble the change up to the dmap control pages.
* if the adjustment of the upper level control pages fails,
- * backout the deallocation.
+ * backout the deallocation.
*/
if ((rc = dbAdjCtl(bmp, blkno, dp->tree.stree[ROOT], 0, 0))) {
word = (blkno & (BPERDMAP - 1)) >> L2DBWORD;
@@ -2245,7 +2245,7 @@ static int dbFreeBits(struct bmap * bmp, struct dmap * dp, s64 blkno,
* words (i.e. partial first and/or last) on an individual basis
* (a single pass), freeing the bits of interest by hand and updating
* the leaf corresponding to the dmap word. a single pass will be used
- * for all dmap words fully contained within the specified range.
+ * for all dmap words fully contained within the specified range.
* within this pass, the bits of all fully contained dmap words will
* be marked as free in a single shot and the leaves will be updated. a
* single leaf may describe the free space of multiple dmap words,
@@ -2267,7 +2267,7 @@ static int dbFreeBits(struct bmap * bmp, struct dmap * dp, s64 blkno,
*/
if (nb < DBWORD) {
/* free (zero) the appropriate bits within this
- * dmap word.
+ * dmap word.
*/
dp->wmap[word] &=
cpu_to_le32(~(ONES << (DBWORD - nb)
@@ -2327,7 +2327,7 @@ static int dbFreeBits(struct bmap * bmp, struct dmap * dp, s64 blkno,
BMAP_LOCK(bmp);
- /* update the free count for the allocation group and
+ /* update the free count for the allocation group and
* map.
*/
agno = blkno >> bmp->db_agl2size;
@@ -2378,7 +2378,7 @@ static int dbFreeBits(struct bmap * bmp, struct dmap * dp, s64 blkno,
* or deallocation resulted in the root change. this range
* is respresented by a single leaf of the current dmapctl
* and the leaf will be updated with this value, possibly
- * causing a binary buddy system within the leaves to be
+ * causing a binary buddy system within the leaves to be
* split or joined. the update may also cause the dmapctl's
* dmtree to be updated.
*
@@ -2394,7 +2394,7 @@ static int dbFreeBits(struct bmap * bmp, struct dmap * dp, s64 blkno,
* requires the dmap control page to be adjusted.
* newval - the new value of the lower level dmap or dmap control
* page root.
- * alloc - TRUE if adjustment is due to an allocation.
+ * alloc - 'true' if adjustment is due to an allocation.
* level - current level of dmap control page (i.e. L0, L1, L2) to
* be adjusted.
*
@@ -2590,7 +2590,7 @@ static void dbSplit(dmtree_t * tp, int leafno, int splitsz, int newval)
}
}
- /* adjust the dmap tree to reflect the specified leaf's new
+ /* adjust the dmap tree to reflect the specified leaf's new
* value.
*/
dbAdjTree(tp, leafno, newval);
@@ -2638,7 +2638,7 @@ static int dbBackSplit(dmtree_t * tp, int leafno)
/* the back split is accomplished by iteratively finding the leaf
* that starts the buddy system that contains the specified leaf and
* splitting that system in two. this iteration continues until
- * the specified leaf becomes the start of a buddy system.
+ * the specified leaf becomes the start of a buddy system.
*
* determine maximum possible l2 size for the specified leaf.
*/
@@ -2853,7 +2853,7 @@ static void dbAdjTree(dmtree_t * tp, int leafno, int newval)
* NAME: dbFindLeaf()
*
* FUNCTION: search a dmtree_t for sufficient free blocks, returning
- * the index of a leaf describing the free blocks if
+ * the index of a leaf describing the free blocks if
* sufficient free blocks are found.
*
* the search starts at the top of the dmtree_t tree and
@@ -2869,7 +2869,7 @@ static void dbAdjTree(dmtree_t * tp, int leafno, int newval)
*
* RETURN VALUES:
* 0 - success
- * -ENOSPC - insufficient free blocks.
+ * -ENOSPC - insufficient free blocks.
*/
static int dbFindLeaf(dmtree_t * tp, int l2nb, int *leafidx)
{
@@ -3090,7 +3090,7 @@ static int blkstol2(s64 nb)
/*
- * NAME: dbAllocBottomUp()
+ * NAME: dbAllocBottomUp()
*
* FUNCTION: alloc the specified block range from the working block
* allocation map.
@@ -3241,7 +3241,7 @@ static int dbAllocDmapBU(struct bmap * bmp, struct dmap * dp, s64 blkno,
BMAP_LOCK(bmp);
/* if this allocation group is completely free,
- * update the highest active allocation group number
+ * update the highest active allocation group number
* if this allocation group is the new max.
*/
agno = blkno >> bmp->db_agl2size;
@@ -3273,7 +3273,7 @@ static int dbAllocDmapBU(struct bmap * bmp, struct dmap * dp, s64 blkno,
* NAME: dbExtendFS()
*
* FUNCTION: extend bmap from blkno for nblocks;
- * dbExtendFS() updates bmap ready for dbAllocBottomUp();
+ * dbExtendFS() updates bmap ready for dbAllocBottomUp();
*
* L2
* |
@@ -3284,13 +3284,13 @@ static int dbAllocDmapBU(struct bmap * bmp, struct dmap * dp, s64 blkno,
* d0,...,dn d0,...,dn d0,...,dn d0,...,dn d0,...,dn d0,.,dm;
* L2L1L0d0,...,dnL0d0,...,dnL0d0,...,dnL1L0d0,...,dnL0d0,...,dnL0d0,..dm
*
- * <---old---><----------------------------extend----------------------->
+ * <---old---><----------------------------extend----------------------->
*/
int dbExtendFS(struct inode *ipbmap, s64 blkno, s64 nblocks)
{
struct jfs_sb_info *sbi = JFS_SBI(ipbmap->i_sb);
int nbperpage = sbi->nbperpage;
- int i, i0 = TRUE, j, j0 = TRUE, k, n;
+ int i, i0 = true, j, j0 = true, k, n;
s64 newsize;
s64 p;
struct metapage *mp, *l2mp, *l1mp = NULL, *l0mp = NULL;
@@ -3330,7 +3330,7 @@ int dbExtendFS(struct inode *ipbmap, s64 blkno, s64 nblocks)
bmp->db_numag += ((u32) newsize % (u32) bmp->db_agsize) ? 1 : 0;
/*
- * reconfigure db_agfree[]
+ * reconfigure db_agfree[]
* from old AG configuration to new AG configuration;
*
* coalesce contiguous k (newAGSize/oldAGSize) AGs;
@@ -3398,7 +3398,7 @@ int dbExtendFS(struct inode *ipbmap, s64 blkno, s64 nblocks)
j = (blkno & (MAXL1SIZE - 1)) >> L2MAXL0SIZE;
l1leaf = l1dcp->stree + CTLLEAFIND + j;
p = BLKTOL0(blkno, sbi->l2nbperpage);
- j0 = FALSE;
+ j0 = false;
} else {
/* assign/init L1 page */
l1mp = get_metapage(ipbmap, p, PSIZE, 0);
@@ -3432,7 +3432,7 @@ int dbExtendFS(struct inode *ipbmap, s64 blkno, s64 nblocks)
l0leaf = l0dcp->stree + CTLLEAFIND + i;
p = BLKTODMAP(blkno,
sbi->l2nbperpage);
- i0 = FALSE;
+ i0 = false;
} else {
/* assign/init L0 page */
l0mp = get_metapage(ipbmap, p, PSIZE, 0);
@@ -3491,7 +3491,7 @@ int dbExtendFS(struct inode *ipbmap, s64 blkno, s64 nblocks)
} /* for each dmap in a L0 */
/*
- * build current L0 page from its leaves, and
+ * build current L0 page from its leaves, and
* initialize corresponding parent L1 leaf
*/
*l1leaf = dbInitDmapCtl(l0dcp, 0, ++i);
@@ -3515,7 +3515,7 @@ int dbExtendFS(struct inode *ipbmap, s64 blkno, s64 nblocks)
} /* for each L0 in a L1 */
/*
- * build current L1 page from its leaves, and
+ * build current L1 page from its leaves, and
* initialize corresponding parent L2 leaf
*/
*l2leaf = dbInitDmapCtl(l1dcp, 1, ++j);
@@ -3570,7 +3570,7 @@ void dbFinalizeBmap(struct inode *ipbmap)
* finalize bmap control page
*/
//finalize:
- /*
+ /*
* compute db_agpref: preferred ag to allocate from
* (the leftmost ag with average free space in it);
*/
@@ -3614,9 +3614,9 @@ void dbFinalizeBmap(struct inode *ipbmap)
/*
* compute db_aglevel, db_agheigth, db_width, db_agstart:
- * an ag is covered in aglevel dmapctl summary tree,
- * at agheight level height (from leaf) with agwidth number of nodes
- * each, which starts at agstart index node of the smmary tree node
+ * an ag is covered in aglevel dmapctl summary tree,
+ * at agheight level height (from leaf) with agwidth number of nodes
+ * each, which starts at agstart index node of the smmary tree node
* array;
*/
bmp->db_aglevel = BMAPSZTOLEV(bmp->db_agsize);
@@ -3635,13 +3635,13 @@ void dbFinalizeBmap(struct inode *ipbmap)
/*
* NAME: dbInitDmap()/ujfs_idmap_page()
- *
+ *
* FUNCTION: initialize working/persistent bitmap of the dmap page
* for the specified number of blocks:
- *
+ *
* at entry, the bitmaps had been initialized as free (ZEROS);
- * The number of blocks will only account for the actually
- * existing blocks. Blocks which don't actually exist in
+ * The number of blocks will only account for the actually
+ * existing blocks. Blocks which don't actually exist in
* the aggregate will be marked as allocated (ONES);
*
* PARAMETERS:
@@ -3677,7 +3677,7 @@ static int dbInitDmap(struct dmap * dp, s64 Blkno, int nblocks)
/*
* free the bits corresponding to the block range (ZEROS):
- * note: not all bits of the first and last words may be contained
+ * note: not all bits of the first and last words may be contained
* within the block range.
*/
for (r = nblocks; r > 0; r -= nb, blkno += nb) {
@@ -3709,7 +3709,7 @@ static int dbInitDmap(struct dmap * dp, s64 Blkno, int nblocks)
}
/*
- * mark bits following the range to be freed (non-existing
+ * mark bits following the range to be freed (non-existing
* blocks) as allocated (ONES)
*/
@@ -3741,11 +3741,11 @@ static int dbInitDmap(struct dmap * dp, s64 Blkno, int nblocks)
/*
* NAME: dbInitDmapTree()/ujfs_complete_dmap()
- *
+ *
* FUNCTION: initialize summary tree of the specified dmap:
*
* at entry, bitmap of the dmap has been initialized;
- *
+ *
* PARAMETERS:
* dp - dmap to complete
* blkno - starting block number for this dmap
@@ -3769,7 +3769,7 @@ static int dbInitDmapTree(struct dmap * dp)
/* init each leaf from corresponding wmap word:
* note: leaf is set to NOFREE(-1) if all blocks of corresponding
- * bitmap word are allocated.
+ * bitmap word are allocated.
*/
cp = tp->stree + le32_to_cpu(tp->leafidx);
for (i = 0; i < LPERDMAP; i++)
@@ -3782,10 +3782,10 @@ static int dbInitDmapTree(struct dmap * dp)
/*
* NAME: dbInitTree()/ujfs_adjtree()
- *
+ *
* FUNCTION: initialize binary buddy summary tree of a dmap or dmapctl.
*
- * at entry, the leaves of the tree has been initialized
+ * at entry, the leaves of the tree has been initialized
* from corresponding bitmap word or root of summary tree
* of the child control page;
* configure binary buddy system at the leaf level, then
@@ -3813,15 +3813,15 @@ static int dbInitTree(struct dmaptree * dtp)
/*
* configure the leaf levevl into binary buddy system
*
- * Try to combine buddies starting with a buddy size of 1
- * (i.e. two leaves). At a buddy size of 1 two buddy leaves
- * can be combined if both buddies have a maximum free of l2min;
- * the combination will result in the left-most buddy leaf having
- * a maximum free of l2min+1.
- * After processing all buddies for a given size, process buddies
- * at the next higher buddy size (i.e. current size * 2) and
- * the next maximum free (current free + 1).
- * This continues until the maximum possible buddy combination
+ * Try to combine buddies starting with a buddy size of 1
+ * (i.e. two leaves). At a buddy size of 1 two buddy leaves
+ * can be combined if both buddies have a maximum free of l2min;
+ * the combination will result in the left-most buddy leaf having
+ * a maximum free of l2min+1.
+ * After processing all buddies for a given size, process buddies
+ * at the next higher buddy size (i.e. current size * 2) and
+ * the next maximum free (current free + 1).
+ * This continues until the maximum possible buddy combination
* yields maximum free.
*/
for (l2free = dtp->budmin, bsize = 1; l2free < l2max;
@@ -3845,10 +3845,10 @@ static int dbInitTree(struct dmaptree * dtp)
* bubble summary information of leaves up the tree.
*
* Starting at the leaf node level, the four nodes described by
- * the higher level parent node are compared for a maximum free and
- * this maximum becomes the value of the parent node.
- * when all lower level nodes are processed in this fashion then
- * move up to the next level (parent becomes a lower level node) and
+ * the higher level parent node are compared for a maximum free and
+ * this maximum becomes the value of the parent node.
+ * when all lower level nodes are processed in this fashion then
+ * move up to the next level (parent becomes a lower level node) and
* continue the process for that level.
*/
for (child = le32_to_cpu(dtp->leafidx),
@@ -3857,7 +3857,7 @@ static int dbInitTree(struct dmaptree * dtp)
/* get index of 1st node of parent level */
parent = (child - 1) >> 2;
- /* set the value of the parent node as the maximum
+ /* set the value of the parent node as the maximum
* of the four nodes of the current level.
*/
for (i = 0, cp = tp + child, cp1 = tp + parent;
@@ -3885,8 +3885,8 @@ static int dbInitDmapCtl(struct dmapctl * dcp, int level, int i)
dcp->budmin = L2BPERDMAP + L2LPERCTL * level;
/*
- * initialize the leaves of current level that were not covered
- * by the specified input block range (i.e. the leaves have no
+ * initialize the leaves of current level that were not covered
+ * by the specified input block range (i.e. the leaves have no
* low level dmapctl or dmap).
*/
cp = &dcp->stree[CTLLEAFIND + i];
@@ -3900,9 +3900,9 @@ static int dbInitDmapCtl(struct dmapctl * dcp, int level, int i)
/*
* NAME: dbGetL2AGSize()/ujfs_getagl2size()
- *
+ *
* FUNCTION: Determine log2(allocation group size) from aggregate size
- *
+ *
* PARAMETERS:
* nblocks - Number of blocks in aggregate
*
@@ -3935,8 +3935,8 @@ static int dbGetL2AGSize(s64 nblocks)
/*
* NAME: dbMapFileSizeToMapSize()
- *
- * FUNCTION: compute number of blocks the block allocation map file
+ *
+ * FUNCTION: compute number of blocks the block allocation map file
* can cover from the map file size;
*
* RETURNS: Number of blocks which can be covered by this block map file;
@@ -3968,7 +3968,7 @@ s64 dbMapFileSizeToMapSize(struct inode * ipbmap)
npages = nblocks >> JFS_SBI(sb)->l2nbperpage;
level = BMAPPGTOLEV(npages);
- /* At each level, accumulate the number of dmap pages covered by
+ /* At each level, accumulate the number of dmap pages covered by
* the number of full child levels below it;
* repeat for the last incomplete child level.
*/
@@ -3990,7 +3990,7 @@ s64 dbMapFileSizeToMapSize(struct inode * ipbmap)
npages--;
}
- /* convert the number of dmaps into the number of blocks
+ /* convert the number of dmaps into the number of blocks
* which can be covered by the dmaps;
*/
nblocks = ndmaps << L2BPERDMAP;
diff --git a/fs/jfs/jfs_dmap.h b/fs/jfs/jfs_dmap.h
index 8b14cc8e0228..45ea454c74bd 100644
--- a/fs/jfs/jfs_dmap.h
+++ b/fs/jfs/jfs_dmap.h
@@ -1,18 +1,18 @@
/*
- * Copyright (c) International Business Machines Corp., 2000-2002
+ * Copyright (C) International Business Machines Corp., 2000-2002
*
* 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
+ * 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
+ * along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef _H_JFS_DMAP
@@ -27,7 +27,7 @@
#define L2LPERDMAP 8 /* l2 number of leaves per dmap tree */
#define DBWORD 32 /* # of blks covered by a map word */
#define L2DBWORD 5 /* l2 # of blks covered by a mword */
-#define BUDMIN L2DBWORD /* max free string in a map word */
+#define BUDMIN L2DBWORD /* max free string in a map word */
#define BPERDMAP (LPERDMAP * DBWORD) /* num of blks per dmap */
#define L2BPERDMAP 13 /* l2 num of blks per dmap */
#define CTLTREESIZE (1024+256+64+16+4+1) /* size of a dmapctl tree */
@@ -57,7 +57,7 @@
#define MAXMAPSIZE MAXL2SIZE /* maximum aggregate map size */
-/*
+/*
* determine the maximum free string for four (lower level) nodes
* of the tree.
*/
@@ -122,7 +122,7 @@ static __inline signed char TREEMAX(signed char *cp)
#define BLKTOCTL(b,s,l) \
(((l) == 2) ? 1 : ((l) == 1) ? BLKTOL1((b),(s)) : BLKTOL0((b),(s)))
-/*
+/*
* convert aggregate map size to the zero origin dmapctl level of the
* top dmapctl.
*/
@@ -192,13 +192,13 @@ typedef union dmtree {
/* macros for accessing fields within dmtree */
#define dmt_nleafs t1.nleafs
-#define dmt_l2nleafs t1.l2nleafs
-#define dmt_leafidx t1.leafidx
-#define dmt_height t1.height
-#define dmt_budmin t1.budmin
-#define dmt_stree t1.stree
+#define dmt_l2nleafs t1.l2nleafs
+#define dmt_leafidx t1.leafidx
+#define dmt_height t1.height
+#define dmt_budmin t1.budmin
+#define dmt_stree t1.stree
-/*
+/*
* on-disk aggregate disk allocation map descriptor.
*/
struct dbmap_disk {
@@ -237,7 +237,7 @@ struct dbmap {
s64 dn_agsize; /* num of blks per alloc group */
signed char dn_maxfreebud; /* max free buddy system */
}; /* - 4096 - */
-/*
+/*
* in-memory aggregate disk allocation map descriptor.
*/
struct bmap {
diff --git a/fs/jfs/jfs_dtree.c b/fs/jfs/jfs_dtree.c
index 6c3f08319846..ecb2216d881c 100644
--- a/fs/jfs/jfs_dtree.c
+++ b/fs/jfs/jfs_dtree.c
@@ -3,16 +3,16 @@
*
* 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
+ * 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
+ * along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
@@ -78,7 +78,7 @@
*
* case-insensitive search:
*
- * fold search key;
+ * fold search key;
*
* case-insensitive search of B-tree:
* for internal entry, router key is already folded;
@@ -93,7 +93,7 @@
* else
* return no match;
*
- * serialization:
+ * serialization:
* target directory inode lock is being held on entry/exit
* of all main directory service routines.
*
@@ -925,7 +925,7 @@ int dtInsert(tid_t tid, struct inode *ip,
*
* return: 0 - success;
* errno - failure;
- * leaf page unpinned;
+ * leaf page unpinned;
*/
static int dtSplitUp(tid_t tid,
struct inode *ip, struct dtsplit * split, struct btstack * btstack)
@@ -3767,7 +3767,7 @@ static int ciCompare(struct component_name * key, /* search key */
* across page boundary
*
* return: non-zero on error
- *
+ *
*/
static int ciGetLeafPrefixKey(dtpage_t * lp, int li, dtpage_t * rp,
int ri, struct component_name * key, int flag)
@@ -3780,13 +3780,13 @@ static int ciGetLeafPrefixKey(dtpage_t * lp, int li, dtpage_t * rp,
lkey.name = (wchar_t *) kmalloc((JFS_NAME_MAX + 1) * sizeof(wchar_t),
GFP_KERNEL);
if (lkey.name == NULL)
- return -ENOSPC;
+ return -ENOMEM;
rkey.name = (wchar_t *) kmalloc((JFS_NAME_MAX + 1) * sizeof(wchar_t),
GFP_KERNEL);
if (rkey.name == NULL) {
kfree(lkey.name);
- return -ENOSPC;
+ return -ENOMEM;
}
/* get left and right key */
diff --git a/fs/jfs/jfs_dtree.h b/fs/jfs/jfs_dtree.h
index 13e4fdf07724..af8513f78648 100644
--- a/fs/jfs/jfs_dtree.h
+++ b/fs/jfs/jfs_dtree.h
@@ -1,18 +1,18 @@
/*
- * Copyright (c) International Business Machines Corp., 2000-2002
+ * Copyright (C) International Business Machines Corp., 2000-2002
*
* 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
+ * 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
+ * along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef _H_JFS_DTREE
@@ -80,7 +80,7 @@ struct idtentry {
/*
* leaf node entry head/only segment
*
- * For legacy filesystems, name contains 13 wchars -- no index field
+ * For legacy filesystems, name contains 13 wchars -- no index field
*/
struct ldtentry {
__le32 inumber; /* 4: 4-byte aligned */
diff --git a/fs/jfs/jfs_extent.c b/fs/jfs/jfs_extent.c
index 4c74f0944f7e..a35bdca6a805 100644
--- a/fs/jfs/jfs_extent.c
+++ b/fs/jfs/jfs_extent.c
@@ -3,16 +3,16 @@
*
* 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
+ * 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
+ * along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
@@ -74,7 +74,7 @@ static s64 extRoundDown(s64 nb);
* extent that is used as an allocation hint if the
* xaddr of the xad is non-zero. on successful exit,
* the xad describes the newly allocated extent.
- * abnr - boolean_t indicating whether the newly allocated extent
+ * abnr - bool indicating whether the newly allocated extent
* should be marked as allocated but not recorded.
*
* RETURN VALUES:
@@ -83,7 +83,7 @@ static s64 extRoundDown(s64 nb);
* -ENOSPC - insufficient disk resources.
*/
int
-extAlloc(struct inode *ip, s64 xlen, s64 pno, xad_t * xp, boolean_t abnr)
+extAlloc(struct inode *ip, s64 xlen, s64 pno, xad_t * xp, bool abnr)
{
struct jfs_sb_info *sbi = JFS_SBI(ip->i_sb);
s64 nxlen, nxaddr, xoff, hint, xaddr = 0;
@@ -117,7 +117,7 @@ extAlloc(struct inode *ip, s64 xlen, s64 pno, xad_t * xp, boolean_t abnr)
* following the hint extent.
*/
if (offsetXAD(xp) + nxlen == xoff &&
- abnr == ((xp->flag & XAD_NOTRECORDED) ? TRUE : FALSE))
+ abnr == ((xp->flag & XAD_NOTRECORDED) ? true : false))
xaddr = hint + nxlen;
/* adjust the hint to the last block of the extent */
@@ -125,7 +125,7 @@ extAlloc(struct inode *ip, s64 xlen, s64 pno, xad_t * xp, boolean_t abnr)
}
/* allocate the disk blocks for the extent. initially, extBalloc()
- * will try to allocate disk blocks for the requested size (xlen).
+ * will try to allocate disk blocks for the requested size (xlen).
* if this fails (xlen contiguous free blocks not avaliable), it'll
* try to allocate a smaller number of blocks (producing a smaller
* extent), with this smaller number of blocks consisting of the
@@ -148,9 +148,9 @@ extAlloc(struct inode *ip, s64 xlen, s64 pno, xad_t * xp, boolean_t abnr)
}
/* determine the value of the extent flag */
- xflag = (abnr == TRUE) ? XAD_NOTRECORDED : 0;
+ xflag = abnr ? XAD_NOTRECORDED : 0;
- /* if we can extend the hint extent to cover the current request,
+ /* if we can extend the hint extent to cover the current request,
* extend it. otherwise, insert a new extent to
* cover the current request.
*/
@@ -159,7 +159,7 @@ extAlloc(struct inode *ip, s64 xlen, s64 pno, xad_t * xp, boolean_t abnr)
else
rc = xtInsert(0, ip, xflag, xoff, (int) nxlen, &nxaddr, 0);
- /* if the extend or insert failed,
+ /* if the extend or insert failed,
* free the newly allocated blocks and return the error.
*/
if (rc) {
@@ -203,7 +203,7 @@ extAlloc(struct inode *ip, s64 xlen, s64 pno, xad_t * xp, boolean_t abnr)
* xlen - request size of the resulting extent.
* xp - pointer to an xad. on successful exit, the xad
* describes the newly allocated extent.
- * abnr - boolean_t indicating whether the newly allocated extent
+ * abnr - bool indicating whether the newly allocated extent
* should be marked as allocated but not recorded.
*
* RETURN VALUES:
@@ -211,7 +211,7 @@ extAlloc(struct inode *ip, s64 xlen, s64 pno, xad_t * xp, boolean_t abnr)
* -EIO - i/o error.
* -ENOSPC - insufficient disk resources.
*/
-int extRealloc(struct inode *ip, s64 nxlen, xad_t * xp, boolean_t abnr)
+int extRealloc(struct inode *ip, s64 nxlen, xad_t * xp, bool abnr)
{
struct super_block *sb = ip->i_sb;
s64 xaddr, xlen, nxaddr, delta, xoff;
@@ -235,7 +235,7 @@ int extRealloc(struct inode *ip, s64 nxlen, xad_t * xp, boolean_t abnr)
xoff = offsetXAD(xp);
/* if the extend page is abnr and if the request is for
- * the extent to be allocated and recorded,
+ * the extent to be allocated and recorded,
* make the page allocated and recorded.
*/
if ((xp->flag & XAD_NOTRECORDED) && !abnr) {
@@ -397,7 +397,7 @@ int extHint(struct inode *ip, s64 offset, xad_t * xp)
if ((rc = xtLookupList(ip, &lxdl, &xadl, 0)))
return (rc);
- /* check if not extent exists for the previous page.
+ /* check if not extent exists for the previous page.
* this is possible for sparse files.
*/
if (xadl.nxad == 0) {
@@ -410,7 +410,7 @@ int extHint(struct inode *ip, s64 offset, xad_t * xp)
*/
xp->flag &= XAD_NOTRECORDED;
- if(xadl.nxad != 1 || lengthXAD(xp) != nbperpage) {
+ if(xadl.nxad != 1 || lengthXAD(xp) != nbperpage) {
jfs_error(ip->i_sb, "extHint: corrupt xtree");
return -EIO;
}
@@ -476,7 +476,7 @@ int extFill(struct inode *ip, xad_t * xp)
XADaddress(xp, 0);
/* allocate an extent to fill the hole */
- if ((rc = extAlloc(ip, nbperpage, blkno, xp, FALSE)))
+ if ((rc = extAlloc(ip, nbperpage, blkno, xp, false)))
return (rc);
assert(lengthPXD(xp) == nbperpage);
@@ -492,7 +492,7 @@ int extFill(struct inode *ip, xad_t * xp)
* FUNCTION: allocate disk blocks to form an extent.
*
* initially, we will try to allocate disk blocks for the
- * requested size (nblocks). if this fails (nblocks
+ * requested size (nblocks). if this fails (nblocks
* contiguous free blocks not avaliable), we'll try to allocate
* a smaller number of blocks (producing a smaller extent), with
* this smaller number of blocks consisting of the requested
@@ -500,7 +500,7 @@ int extFill(struct inode *ip, xad_t * xp)
* number (i.e. 16 -> 8). we'll continue to round down and
* retry the allocation until the number of blocks to allocate
* is smaller than the number of blocks per page.
- *
+ *
* PARAMETERS:
* ip - the inode of the file.
* hint - disk block number to be used as an allocation hint.
@@ -509,7 +509,7 @@ int extFill(struct inode *ip, xad_t * xp)
* exit, this value is set to the number of blocks actually
* allocated.
* blkno - pointer to a block address that is filled in on successful
- * return with the starting block number of the newly
+ * return with the starting block number of the newly
* allocated block range.
*
* RETURN VALUES:
@@ -530,7 +530,7 @@ extBalloc(struct inode *ip, s64 hint, s64 * nblocks, s64 * blkno)
/* get the number of blocks to initially attempt to allocate.
* we'll first try the number of blocks requested unless this
* number is greater than the maximum number of contiguous free
- * blocks in the map. in that case, we'll start off with the
+ * blocks in the map. in that case, we'll start off with the
* maximum free.
*/
max = (s64) 1 << bmp->db_maxfreebud;
@@ -582,19 +582,19 @@ extBalloc(struct inode *ip, s64 hint, s64 * nblocks, s64 * blkno)
*
* FUNCTION: attempt to extend an extent's allocation.
*
- * initially, we will try to extend the extent's allocation
- * in place. if this fails, we'll try to move the extent
- * to a new set of blocks. if moving the extent, we initially
+ * Initially, we will try to extend the extent's allocation
+ * in place. If this fails, we'll try to move the extent
+ * to a new set of blocks. If moving the extent, we initially
* will try to allocate disk blocks for the requested size
- * (nnew). if this fails (new contiguous free blocks not
- * avaliable), we'll try to allocate a smaller number of
+ * (newnblks). if this fails (new contiguous free blocks not
+ * avaliable), we'll try to allocate a smaller number of
* blocks (producing a smaller extent), with this smaller
* number of blocks consisting of the requested number of
* blocks rounded down to the next smaller power of 2
- * number (i.e. 16 -> 8). we'll continue to round down and
+ * number (i.e. 16 -> 8). We'll continue to round down and
* retry the allocation until the number of blocks to allocate
* is smaller than the number of blocks per page.
- *
+ *
* PARAMETERS:
* ip - the inode of the file.
* blkno - starting block number of the extents current allocation.
@@ -625,7 +625,7 @@ extBrealloc(struct inode *ip,
return (rc);
}
- /* in place extension not possible.
+ /* in place extension not possible.
* try to move the extent to a new set of blocks.
*/
return (extBalloc(ip, blkno, newnblks, newblkno));
diff --git a/fs/jfs/jfs_extent.h b/fs/jfs/jfs_extent.h
index e80fc7ced87d..b567e12c52d3 100644
--- a/fs/jfs/jfs_extent.h
+++ b/fs/jfs/jfs_extent.h
@@ -1,18 +1,18 @@
/*
- * Copyright (c) International Business Machines Corp., 2000-2001
+ * Copyright (C) International Business Machines Corp., 2000-2001
*
* 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
+ * 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
+ * along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef _H_JFS_EXTENT
@@ -22,10 +22,10 @@
#define INOHINT(ip) \
(addressPXD(&(JFS_IP(ip)->ixpxd)) + lengthPXD(&(JFS_IP(ip)->ixpxd)) - 1)
-extern int extAlloc(struct inode *, s64, s64, xad_t *, boolean_t);
+extern int extAlloc(struct inode *, s64, s64, xad_t *, bool);
extern int extFill(struct inode *, xad_t *);
extern int extHint(struct inode *, s64, xad_t *);
-extern int extRealloc(struct inode *, s64, xad_t *, boolean_t);
+extern int extRealloc(struct inode *, s64, xad_t *, bool);
extern int extRecord(struct inode *, xad_t *);
#endif /* _H_JFS_EXTENT */
diff --git a/fs/jfs/jfs_filsys.h b/fs/jfs/jfs_filsys.h
index 72a5588faeca..9901928668cf 100644
--- a/fs/jfs/jfs_filsys.h
+++ b/fs/jfs/jfs_filsys.h
@@ -3,16 +3,16 @@
*
* 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
+ * 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
+ * along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef _H_JFS_FILSYS
@@ -21,9 +21,9 @@
/*
* jfs_filsys.h
*
- * file system (implementation-dependent) constants
+ * file system (implementation-dependent) constants
*
- * refer to <limits.h> for system wide implementation-dependent constants
+ * refer to <limits.h> for system wide implementation-dependent constants
*/
/*
@@ -49,7 +49,7 @@
#define JFS_DFS 0x20000000 /* DCE DFS LFS support */
-#define JFS_LINUX 0x10000000 /* Linux support */
+#define JFS_LINUX 0x10000000 /* Linux support */
/* case-sensitive name/directory support */
/* directory option */
@@ -59,7 +59,7 @@
#define JFS_COMMIT 0x00000f00 /* commit option mask */
#define JFS_GROUPCOMMIT 0x00000100 /* group (of 1) commit */
#define JFS_LAZYCOMMIT 0x00000200 /* lazy commit */
-#define JFS_TMPFS 0x00000400 /* temporary file system -
+#define JFS_TMPFS 0x00000400 /* temporary file system -
* do not log/commit:
*/
@@ -196,7 +196,7 @@
* followed by 1st extent of map
*/
#define AITBL_OFF (AIMAP_OFF + (SIZE_OF_MAP_PAGE << 1))
- /*
+ /*
* 1st extent of aggregate inode table
*/
#define SUPER2_OFF (AITBL_OFF + INODE_EXTENT_SIZE)
@@ -270,13 +270,13 @@
*/
#define FM_CLEAN 0x00000000 /* file system is unmounted and clean */
#define FM_MOUNT 0x00000001 /* file system is mounted cleanly */
-#define FM_DIRTY 0x00000002 /* file system was not unmounted and clean
- * when mounted or
+#define FM_DIRTY 0x00000002 /* file system was not unmounted and clean
+ * when mounted or
* commit failure occurred while being mounted:
- * fsck() must be run to repair
+ * fsck() must be run to repair
*/
#define FM_LOGREDO 0x00000004 /* log based recovery (logredo()) failed:
- * fsck() must be run to repair
+ * fsck() must be run to repair
*/
#define FM_EXTENDFS 0x00000008 /* file system extendfs() in progress */
diff --git a/fs/jfs/jfs_imap.c b/fs/jfs/jfs_imap.c
index 369d7f39c040..489a3d63002d 100644
--- a/fs/jfs/jfs_imap.c
+++ b/fs/jfs/jfs_imap.c
@@ -3,16 +3,16 @@
*
* 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
+ * 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
+ * along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
@@ -78,8 +78,8 @@ static HLIST_HEAD(aggregate_hash);
/*
* forward references
*/
-static int diAllocAG(struct inomap *, int, boolean_t, struct inode *);
-static int diAllocAny(struct inomap *, int, boolean_t, struct inode *);
+static int diAllocAG(struct inomap *, int, bool, struct inode *);
+static int diAllocAny(struct inomap *, int, bool, struct inode *);
static int diAllocBit(struct inomap *, struct iag *, int);
static int diAllocExt(struct inomap *, int, struct inode *);
static int diAllocIno(struct inomap *, int, struct inode *);
@@ -98,7 +98,7 @@ static void copy_to_dinode(struct dinode *, struct inode *);
* FUNCTION: initialize the incore inode map control structures for
* a fileset or aggregate init time.
*
- * the inode map's control structure (dinomap) is
+ * the inode map's control structure (dinomap) is
* brought in from disk and placed in virtual memory.
*
* PARAMETERS:
@@ -107,7 +107,7 @@ static void copy_to_dinode(struct dinode *, struct inode *);
* RETURN VALUES:
* 0 - success
* -ENOMEM - insufficient free virtual memory.
- * -EIO - i/o error.
+ * -EIO - i/o error.
*/
int diMount(struct inode *ipimap)
{
@@ -191,7 +191,7 @@ int diMount(struct inode *ipimap)
* RETURN VALUES:
* 0 - success
* -ENOMEM - insufficient free virtual memory.
- * -EIO - i/o error.
+ * -EIO - i/o error.
*/
int diUnmount(struct inode *ipimap, int mounterror)
{
@@ -281,7 +281,7 @@ int diSync(struct inode *ipimap)
* on entry, the specifed incore inode should itself
* specify the disk inode number corresponding to the
* incore inode (i.e. i_number should be initialized).
- *
+ *
* this routine handles incore inode initialization for
* both "special" and "regular" inodes. special inodes
* are those required early in the mount process and
@@ -289,7 +289,7 @@ int diSync(struct inode *ipimap)
* is not yet initialized. these "special" inodes are
* identified by a NULL inode map inode pointer and are
* actually initialized by a call to diReadSpecial().
- *
+ *
* for regular inodes, the iag describing the disk inode
* is read from disk to determine the inode extent address
* for the disk inode. with the inode extent address in
@@ -302,9 +302,9 @@ int diSync(struct inode *ipimap)
*
* RETURN VALUES:
* 0 - success
- * -EIO - i/o error.
+ * -EIO - i/o error.
* -ENOMEM - insufficient memory
- *
+ *
*/
int diRead(struct inode *ip)
{
@@ -586,14 +586,14 @@ void diFreeSpecial(struct inode *ip)
* page of the extent that contains the disk inode is
* read and the disk inode portion of the incore inode
* is copied to the disk inode.
- *
+ *
* PARAMETERS:
* tid - transacation id
* ip - pointer to incore inode to be written to the inode extent.
*
* RETURN VALUES:
* 0 - success
- * -EIO - i/o error.
+ * -EIO - i/o error.
*/
int diWrite(tid_t tid, struct inode *ip)
{
@@ -676,11 +676,11 @@ int diWrite(tid_t tid, struct inode *ip)
* copy btree root from in-memory inode to on-disk inode
*
* (tlock is taken from inline B+-tree root in in-memory
- * inode when the B+-tree root is updated, which is pointed
+ * inode when the B+-tree root is updated, which is pointed
* by jfs_ip->blid as well as being on tx tlock list)
*
- * further processing of btree root is based on the copy
- * in in-memory inode, where txLog() will log from, and,
+ * further processing of btree root is based on the copy
+ * in in-memory inode, where txLog() will log from, and,
* for xtree root, txUpdateMap() will update map and reset
* XAD_NEW bit;
*/
@@ -824,7 +824,7 @@ int diWrite(tid_t tid, struct inode *ip)
memcpy(&dp->di_DASD, &ip->i_DASD, sizeof(struct dasd));
#endif /* _JFS_FASTDASD */
- /* release the buffer holding the updated on-disk inode.
+ /* release the buffer holding the updated on-disk inode.
* the buffer will be later written by commit processing.
*/
write_metapage(mp);
@@ -842,7 +842,7 @@ int diWrite(tid_t tid, struct inode *ip)
* if the inode to be freed represents the first (only)
* free inode within the iag, the iag will be placed on
* the ag free inode list.
- *
+ *
* freeing the inode will cause the inode extent to be
* freed if the inode is the only allocated inode within
* the extent. in this case all the disk resource backing
@@ -865,11 +865,11 @@ int diWrite(tid_t tid, struct inode *ip)
* any updates and are held until all updates are complete.
*
* PARAMETERS:
- * ip - inode to be freed.
+ * ip - inode to be freed.
*
* RETURN VALUES:
* 0 - success
- * -EIO - i/o error.
+ * -EIO - i/o error.
*/
int diFree(struct inode *ip)
{
@@ -898,7 +898,7 @@ int diFree(struct inode *ip)
*/
iagno = INOTOIAG(inum);
- /* make sure that the iag is contained within
+ /* make sure that the iag is contained within
* the map.
*/
if (iagno >= imap->im_nextiag) {
@@ -1013,7 +1013,7 @@ int diFree(struct inode *ip)
/* update the free inode summary map for the extent if
* freeing the inode means the extent will now have free
- * inodes (i.e., the inode being freed is the first free
+ * inodes (i.e., the inode being freed is the first free
* inode of extent),
*/
if (iagp->wmap[extno] == cpu_to_le32(ONES)) {
@@ -1204,9 +1204,9 @@ int diFree(struct inode *ip)
iagp->inofreefwd = iagp->inofreeback = cpu_to_le32(-1);
}
- /* update the inode extent address and working map
+ /* update the inode extent address and working map
* to reflect the free extent.
- * the permanent map should have been updated already
+ * the permanent map should have been updated already
* for the inode being freed.
*/
if (iagp->pmap[extno] != 0) {
@@ -1218,7 +1218,7 @@ int diFree(struct inode *ip)
/* update the free extent and free inode summary maps
* to reflect the freed extent.
- * the inode summary map is marked to indicate no inodes
+ * the inode summary map is marked to indicate no inodes
* available for the freed extent.
*/
sword = extno >> L2EXTSPERSUM;
@@ -1255,17 +1255,17 @@ int diFree(struct inode *ip)
* start transaction to update block allocation map
* for the inode extent freed;
*
- * N.B. AG_LOCK is released and iag will be released below, and
+ * N.B. AG_LOCK is released and iag will be released below, and
* other thread may allocate inode from/reusing the ixad freed
- * BUT with new/different backing inode extent from the extent
- * to be freed by the transaction;
+ * BUT with new/different backing inode extent from the extent
+ * to be freed by the transaction;
*/
tid = txBegin(ipimap->i_sb, COMMIT_FORCE);
mutex_lock(&JFS_IP(ipimap)->commit_mutex);
- /* acquire tlock of the iag page of the freed ixad
+ /* acquire tlock of the iag page of the freed ixad
* to force the page NOHOMEOK (even though no data is
- * logged from the iag page) until NOREDOPAGE|FREEXTENT log
+ * logged from the iag page) until NOREDOPAGE|FREEXTENT log
* for the free of the extent is committed;
* write FREEXTENT|NOREDOPAGE log record
* N.B. linelock is overlaid as freed extent descriptor;
@@ -1284,8 +1284,8 @@ int diFree(struct inode *ip)
* logredo needs the IAG number and IAG extent index in order
* to ensure that the IMap is consistent. The least disruptive
* way to pass these values through to the transaction manager
- * is in the iplist array.
- *
+ * is in the iplist array.
+ *
* It's not pretty, but it works.
*/
iplist[1] = (struct inode *) (size_t)iagno;
@@ -1340,20 +1340,20 @@ diInitInode(struct inode *ip, int iagno, int ino, int extno, struct iag * iagp)
/*
* NAME: diAlloc(pip,dir,ip)
*
- * FUNCTION: allocate a disk inode from the inode working map
+ * FUNCTION: allocate a disk inode from the inode working map
* for a fileset or aggregate.
*
* PARAMETERS:
- * pip - pointer to incore inode for the parent inode.
- * dir - TRUE if the new disk inode is for a directory.
- * ip - pointer to a new inode
+ * pip - pointer to incore inode for the parent inode.
+ * dir - 'true' if the new disk inode is for a directory.
+ * ip - pointer to a new inode
*
* RETURN VALUES:
* 0 - success.
* -ENOSPC - insufficient disk resources.
- * -EIO - i/o error.
+ * -EIO - i/o error.
*/
-int diAlloc(struct inode *pip, boolean_t dir, struct inode *ip)
+int diAlloc(struct inode *pip, bool dir, struct inode *ip)
{
int rc, ino, iagno, addext, extno, bitno, sword;
int nwords, rem, i, agno;
@@ -1372,10 +1372,10 @@ int diAlloc(struct inode *pip, boolean_t dir, struct inode *ip)
JFS_IP(ip)->ipimap = ipimap;
JFS_IP(ip)->fileset = FILESYSTEM_I;
- /* for a directory, the allocation policy is to start
+ /* for a directory, the allocation policy is to start
* at the ag level using the preferred ag.
*/
- if (dir == TRUE) {
+ if (dir) {
agno = dbNextAG(JFS_SBI(pip->i_sb)->ipbmap);
AG_LOCK(imap, agno);
goto tryag;
@@ -1435,7 +1435,7 @@ int diAlloc(struct inode *pip, boolean_t dir, struct inode *ip)
/*
* try to allocate from the IAG
*/
- /* check if the inode may be allocated from the iag
+ /* check if the inode may be allocated from the iag
* (i.e. the inode has free inodes or new extent can be added).
*/
if (iagp->nfreeinos || addext) {
@@ -1490,7 +1490,7 @@ int diAlloc(struct inode *pip, boolean_t dir, struct inode *ip)
* hint or, if appropriate (i.e. addext is true), allocate
* an extent of free inodes at or following the extent
* containing the hint.
- *
+ *
* the free inode and free extent summary maps are used
* here, so determine the starting summary map position
* and the number of words we'll have to examine. again,
@@ -1641,7 +1641,7 @@ int diAlloc(struct inode *pip, boolean_t dir, struct inode *ip)
* inodes should be added for the allocation group, with
* the current request satisfied from this extent. if this
* is the case, an attempt will be made to do just that. if
- * this attempt fails or it has been determined that a new
+ * this attempt fails or it has been determined that a new
* extent should not be added, an attempt is made to satisfy
* the request by allocating an existing (backed) free inode
* from the allocation group.
@@ -1649,24 +1649,24 @@ int diAlloc(struct inode *pip, boolean_t dir, struct inode *ip)
* PRE CONDITION: Already have the AG lock for this AG.
*
* PARAMETERS:
- * imap - pointer to inode map control structure.
- * agno - allocation group to allocate from.
- * dir - TRUE if the new disk inode is for a directory.
- * ip - pointer to the new inode to be filled in on successful return
+ * imap - pointer to inode map control structure.
+ * agno - allocation group to allocate from.
+ * dir - 'true' if the new disk inode is for a directory.
+ * ip - pointer to the new inode to be filled in on successful return
* with the disk inode number allocated, its extent address
* and the start of the ag.
*
* RETURN VALUES:
* 0 - success.
* -ENOSPC - insufficient disk resources.
- * -EIO - i/o error.
+ * -EIO - i/o error.
*/
static int
-diAllocAG(struct inomap * imap, int agno, boolean_t dir, struct inode *ip)
+diAllocAG(struct inomap * imap, int agno, bool dir, struct inode *ip)
{
int rc, addext, numfree, numinos;
- /* get the number of free and the number of backed disk
+ /* get the number of free and the number of backed disk
* inodes currently within the ag.
*/
numfree = imap->im_agctl[agno].numfree;
@@ -1682,7 +1682,7 @@ diAllocAG(struct inomap * imap, int agno, boolean_t dir, struct inode *ip)
* if there are a small number of free inodes or number of free
* inodes is a small percentage of the number of backed inodes.
*/
- if (dir == TRUE)
+ if (dir)
addext = (numfree < 64 ||
(numfree < 256
&& ((numfree * 100) / numinos) <= 20));
@@ -1719,26 +1719,26 @@ diAllocAG(struct inomap * imap, int agno, boolean_t dir, struct inode *ip)
* specified primary group.
*
* PARAMETERS:
- * imap - pointer to inode map control structure.
- * agno - primary allocation group (to avoid).
- * dir - TRUE if the new disk inode is for a directory.
- * ip - pointer to a new inode to be filled in on successful return
+ * imap - pointer to inode map control structure.
+ * agno - primary allocation group (to avoid).
+ * dir - 'true' if the new disk inode is for a directory.
+ * ip - pointer to a new inode to be filled in on successful return
* with the disk inode number allocated, its extent address
* and the start of the ag.
*
* RETURN VALUES:
* 0 - success.
* -ENOSPC - insufficient disk resources.
- * -EIO - i/o error.
+ * -EIO - i/o error.
*/
static int
-diAllocAny(struct inomap * imap, int agno, boolean_t dir, struct inode *ip)
+diAllocAny(struct inomap * imap, int agno, bool dir, struct inode *ip)
{
int ag, rc;
int maxag = JFS_SBI(imap->im_ipimap->i_sb)->bmap->db_maxag;
- /* try to allocate from the ags following agno up to
+ /* try to allocate from the ags following agno up to
* the maximum ag number.
*/
for (ag = agno + 1; ag <= maxag; ag++) {
@@ -1780,21 +1780,21 @@ diAllocAny(struct inomap * imap, int agno, boolean_t dir, struct inode *ip)
*
* allocation occurs from the first iag on the list using
* the iag's free inode summary map to find the leftmost
- * free inode in the iag.
- *
+ * free inode in the iag.
+ *
* PRE CONDITION: Already have AG lock for this AG.
- *
+ *
* PARAMETERS:
- * imap - pointer to inode map control structure.
- * agno - allocation group.
- * ip - pointer to new inode to be filled in on successful return
+ * imap - pointer to inode map control structure.
+ * agno - allocation group.
+ * ip - pointer to new inode to be filled in on successful return
* with the disk inode number allocated, its extent address
* and the start of the ag.
*
* RETURN VALUES:
* 0 - success.
* -ENOSPC - insufficient disk resources.
- * -EIO - i/o error.
+ * -EIO - i/o error.
*/
static int diAllocIno(struct inomap * imap, int agno, struct inode *ip)
{
@@ -1867,7 +1867,7 @@ static int diAllocIno(struct inomap * imap, int agno, struct inode *ip)
return -EIO;
}
- /* compute the inode number within the iag.
+ /* compute the inode number within the iag.
*/
ino = (extno << L2INOSPEREXT) + rem;
@@ -1892,17 +1892,17 @@ static int diAllocIno(struct inomap * imap, int agno, struct inode *ip)
/*
* NAME: diAllocExt(imap,agno,ip)
*
- * FUNCTION: add a new extent of free inodes to an iag, allocating
- * an inode from this extent to satisfy the current allocation
- * request.
- *
+ * FUNCTION: add a new extent of free inodes to an iag, allocating
+ * an inode from this extent to satisfy the current allocation
+ * request.
+ *
* this routine first tries to find an existing iag with free
* extents through the ag free extent list. if list is not
* empty, the head of the list will be selected as the home
* of the new extent of free inodes. otherwise (the list is
* empty), a new iag will be allocated for the ag to contain
* the extent.
- *
+ *
* once an iag has been selected, the free extent summary map
* is used to locate a free extent within the iag and diNewExt()
* is called to initialize the extent, with initialization
@@ -1910,16 +1910,16 @@ static int diAllocIno(struct inomap * imap, int agno, struct inode *ip)
* for the purpose of satisfying this request.
*
* PARAMETERS:
- * imap - pointer to inode map control structure.
- * agno - allocation group number.
- * ip - pointer to new inode to be filled in on successful return
+ * imap - pointer to inode map control structure.
+ * agno - allocation group number.
+ * ip - pointer to new inode to be filled in on successful return
* with the disk inode number allocated, its extent address
* and the start of the ag.
*
* RETURN VALUES:
* 0 - success.
* -ENOSPC - insufficient disk resources.
- * -EIO - i/o error.
+ * -EIO - i/o error.
*/
static int diAllocExt(struct inomap * imap, int agno, struct inode *ip)
{
@@ -2012,7 +2012,7 @@ static int diAllocExt(struct inomap * imap, int agno, struct inode *ip)
/*
* NAME: diAllocBit(imap,iagp,ino)
*
- * FUNCTION: allocate a backed inode from an iag.
+ * FUNCTION: allocate a backed inode from an iag.
*
* this routine performs the mechanics of allocating a
* specified inode from a backed extent.
@@ -2025,19 +2025,19 @@ static int diAllocExt(struct inomap * imap, int agno, struct inode *ip)
* in the face of updates to multiple buffers. under this
* approach, all required buffers are obtained before making
* any updates and are held all are updates are complete.
- *
+ *
* PRE CONDITION: Already have buffer lock on iagp. Already have AG lock on
* this AG. Must have read lock on imap inode.
*
* PARAMETERS:
- * imap - pointer to inode map control structure.
- * iagp - pointer to iag.
- * ino - inode number to be allocated within the iag.
+ * imap - pointer to inode map control structure.
+ * iagp - pointer to iag.
+ * ino - inode number to be allocated within the iag.
*
* RETURN VALUES:
* 0 - success.
* -ENOSPC - insufficient disk resources.
- * -EIO - i/o error.
+ * -EIO - i/o error.
*/
static int diAllocBit(struct inomap * imap, struct iag * iagp, int ino)
{
@@ -2172,19 +2172,19 @@ static int diAllocBit(struct inomap * imap, struct iag * iagp, int ino)
* buffers. under this approach, all required buffers are
* obtained before making any updates and are held until all
* updates are complete.
- *
+ *
* PRE CONDITION: Already have buffer lock on iagp. Already have AG lock on
* this AG. Must have read lock on imap inode.
*
* PARAMETERS:
- * imap - pointer to inode map control structure.
- * iagp - pointer to iag.
- * extno - extent number.
+ * imap - pointer to inode map control structure.
+ * iagp - pointer to iag.
+ * extno - extent number.
*
* RETURN VALUES:
* 0 - success.
* -ENOSPC - insufficient disk resources.
- * -EIO - i/o error.
+ * -EIO - i/o error.
*/
static int diNewExt(struct inomap * imap, struct iag * iagp, int extno)
{
@@ -2432,34 +2432,34 @@ static int diNewExt(struct inomap * imap, struct iag * iagp, int extno)
/*
* NAME: diNewIAG(imap,iagnop,agno)
*
- * FUNCTION: allocate a new iag for an allocation group.
- *
- * first tries to allocate the iag from the inode map
- * iagfree list:
- * if the list has free iags, the head of the list is removed
+ * FUNCTION: allocate a new iag for an allocation group.
+ *
+ * first tries to allocate the iag from the inode map
+ * iagfree list:
+ * if the list has free iags, the head of the list is removed
* and returned to satisfy the request.
* if the inode map's iag free list is empty, the inode map
* is extended to hold a new iag. this new iag is initialized
* and returned to satisfy the request.
*
* PARAMETERS:
- * imap - pointer to inode map control structure.
- * iagnop - pointer to an iag number set with the number of the
+ * imap - pointer to inode map control structure.
+ * iagnop - pointer to an iag number set with the number of the
* newly allocated iag upon successful return.
- * agno - allocation group number.
+ * agno - allocation group number.
* bpp - Buffer pointer to be filled in with new IAG's buffer
*
* RETURN VALUES:
* 0 - success.
* -ENOSPC - insufficient disk resources.
- * -EIO - i/o error.
+ * -EIO - i/o error.
*
- * serialization:
+ * serialization:
* AG lock held on entry/exit;
* write lock on the map is held inside;
* read lock on the map is held on successful completion;
*
- * note: new iag transaction:
+ * note: new iag transaction:
* . synchronously write iag;
* . write log of xtree and inode of imap;
* . commit;
@@ -2494,7 +2494,7 @@ diNewIAG(struct inomap * imap, int *iagnop, int agno, struct metapage ** mpp)
/* acquire the free iag lock */
IAGFREE_LOCK(imap);
- /* if there are any iags on the inode map free iag list,
+ /* if there are any iags on the inode map free iag list,
* allocate the iag from the head of the list.
*/
if (imap->im_freeiag >= 0) {
@@ -2618,8 +2618,8 @@ diNewIAG(struct inomap * imap, int *iagnop, int agno, struct metapage ** mpp)
flush_metapage(mp);
/*
- * txCommit(COMMIT_FORCE) will synchronously write address
- * index pages and inode after commit in careful update order
+ * txCommit(COMMIT_FORCE) will synchronously write address
+ * index pages and inode after commit in careful update order
* of address index pages (right to left, bottom up);
*/
iplist[0] = ipimap;
@@ -2678,11 +2678,11 @@ diNewIAG(struct inomap * imap, int *iagnop, int agno, struct metapage ** mpp)
*
* FUNCTION: get the buffer for the specified iag within a fileset
* or aggregate inode map.
- *
+ *
* PARAMETERS:
- * imap - pointer to inode map control structure.
- * iagno - iag number.
- * bpp - point to buffer pointer to be filled in on successful
+ * imap - pointer to inode map control structure.
+ * iagno - iag number.
+ * bpp - point to buffer pointer to be filled in on successful
* exit.
*
* SERIALIZATION:
@@ -2692,7 +2692,7 @@ diNewIAG(struct inomap * imap, int *iagnop, int agno, struct metapage ** mpp)
*
* RETURN VALUES:
* 0 - success.
- * -EIO - i/o error.
+ * -EIO - i/o error.
*/
static int diIAGRead(struct inomap * imap, int iagno, struct metapage ** mpp)
{
@@ -2718,8 +2718,8 @@ static int diIAGRead(struct inomap * imap, int iagno, struct metapage ** mpp)
* the specified bit position.
*
* PARAMETERS:
- * word - word to be examined.
- * start - starting bit position.
+ * word - word to be examined.
+ * start - starting bit position.
*
* RETURN VALUES:
* bit position of first free bit in the word or 32 if
@@ -2740,24 +2740,24 @@ static int diFindFree(u32 word, int start)
/*
* NAME: diUpdatePMap()
- *
- * FUNCTION: Update the persistent map in an IAG for the allocation or
+ *
+ * FUNCTION: Update the persistent map in an IAG for the allocation or
* freeing of the specified inode.
- *
+ *
* PRE CONDITIONS: Working map has already been updated for allocate.
*
* PARAMETERS:
* ipimap - Incore inode map inode
* inum - Number of inode to mark in permanent map
- * is_free - If TRUE indicates inode should be marked freed, otherwise
+ * is_free - If 'true' indicates inode should be marked freed, otherwise
* indicates inode should be marked allocated.
*
- * RETURN VALUES:
+ * RETURN VALUES:
* 0 for success
*/
int
diUpdatePMap(struct inode *ipimap,
- unsigned long inum, boolean_t is_free, struct tblock * tblk)
+ unsigned long inum, bool is_free, struct tblock * tblk)
{
int rc;
struct iag *iagp;
@@ -2793,17 +2793,17 @@ diUpdatePMap(struct inode *ipimap,
extno = ino >> L2INOSPEREXT;
bitno = ino & (INOSPEREXT - 1);
mask = HIGHORDER >> bitno;
- /*
+ /*
* mark the inode free in persistent map:
*/
- if (is_free == TRUE) {
+ if (is_free) {
/* The inode should have been allocated both in working
* map and in persistent map;
* the inode will be freed from working map at the release
* of last reference release;
*/
if (!(le32_to_cpu(iagp->wmap[extno]) & mask)) {
- jfs_error(ipimap->i_sb,
+ jfs_error(ipimap->i_sb,
"diUpdatePMap: inode %ld not marked as "
"allocated in wmap!", inum);
}
@@ -2877,8 +2877,8 @@ diUpdatePMap(struct inode *ipimap,
* diExtendFS()
*
* function: update imap for extendfs();
- *
- * note: AG size has been increased s.t. each k old contiguous AGs are
+ *
+ * note: AG size has been increased s.t. each k old contiguous AGs are
* coalesced into a new AG;
*/
int diExtendFS(struct inode *ipimap, struct inode *ipbmap)
@@ -2897,7 +2897,7 @@ int diExtendFS(struct inode *ipimap, struct inode *ipbmap)
atomic_read(&imap->im_numfree));
/*
- * reconstruct imap
+ * reconstruct imap
*
* coalesce contiguous k (newAGSize/oldAGSize) AGs;
* i.e., (AGi, ..., AGj) where i = k*n and j = k*(n+1) - 1 to AGn;
@@ -2931,7 +2931,7 @@ int diExtendFS(struct inode *ipimap, struct inode *ipbmap)
}
/* leave free iag in the free iag list */
- if (iagp->nfreeexts == cpu_to_le32(EXTSPERIAG)) {
+ if (iagp->nfreeexts == cpu_to_le32(EXTSPERIAG)) {
release_metapage(bp);
continue;
}
diff --git a/fs/jfs/jfs_imap.h b/fs/jfs/jfs_imap.h
index 6e24465f0f98..4f9c346ed498 100644
--- a/fs/jfs/jfs_imap.h
+++ b/fs/jfs/jfs_imap.h
@@ -1,18 +1,18 @@
/*
- * Copyright (c) International Business Machines Corp., 2000-2002
+ * Copyright (C) International Business Machines Corp., 2000-2002
*
* 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
+ * 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
+ * along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef _H_JFS_IMAP
@@ -45,13 +45,13 @@
/* get the starting block number of the 4K page of an inode extent
* that contains ino.
*/
-#define INOPBLK(pxd,ino,l2nbperpg) (addressPXD((pxd)) + \
+#define INOPBLK(pxd,ino,l2nbperpg) (addressPXD((pxd)) + \
((((ino) & (INOSPEREXT-1)) >> L2INOSPERPAGE) << (l2nbperpg)))
/*
* inode allocation map:
- *
- * inode allocation map consists of
+ *
+ * inode allocation map consists of
* . the inode map control page and
* . inode allocation group pages (per 4096 inodes)
* which are addressed by standard JFS xtree.
@@ -159,11 +159,11 @@ struct inomap {
#define im_maxag im_imap.in_maxag
extern int diFree(struct inode *);
-extern int diAlloc(struct inode *, boolean_t, struct inode *);
+extern int diAlloc(struct inode *, bool, struct inode *);
extern int diSync(struct inode *);
/* external references */
extern int diUpdatePMap(struct inode *ipimap, unsigned long inum,
- boolean_t is_free, struct tblock * tblk);
+ bool is_free, struct tblock * tblk);
extern int diExtendFS(struct inode *ipimap, struct inode *ipbmap);
extern int diMount(struct inode *);
extern int diUnmount(struct inode *, int);
diff --git a/fs/jfs/jfs_incore.h b/fs/jfs/jfs_incore.h
index 54d73716ca8c..94005584445a 100644
--- a/fs/jfs/jfs_incore.h
+++ b/fs/jfs/jfs_incore.h
@@ -4,18 +4,18 @@
*
* 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
+ * 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
+ * along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
+ */
#ifndef _H_JFS_INCORE
#define _H_JFS_INCORE
diff --git a/fs/jfs/jfs_inode.c b/fs/jfs/jfs_inode.c
index bffaca9ae3a2..4c67ed97682b 100644
--- a/fs/jfs/jfs_inode.c
+++ b/fs/jfs/jfs_inode.c
@@ -3,16 +3,16 @@
*
* 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
+ * 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
+ * along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
@@ -61,7 +61,7 @@ struct inode *ialloc(struct inode *parent, umode_t mode)
inode = new_inode(sb);
if (!inode) {
jfs_warn("ialloc: new_inode returned NULL!");
- return inode;
+ return ERR_PTR(-ENOMEM);
}
jfs_inode = JFS_IP(inode);
@@ -69,9 +69,10 @@ struct inode *ialloc(struct inode *parent, umode_t mode)
rc = diAlloc(parent, S_ISDIR(mode), inode);
if (rc) {
jfs_warn("ialloc: diAlloc returned %d!", rc);
- make_bad_inode(inode);
+ if (rc == -EIO)
+ make_bad_inode(inode);
iput(inode);
- return NULL;
+ return ERR_PTR(rc);
}
inode->i_uid = current->fsuid;
@@ -97,7 +98,7 @@ struct inode *ialloc(struct inode *parent, umode_t mode)
inode->i_flags |= S_NOQUOTA;
inode->i_nlink = 0;
iput(inode);
- return NULL;
+ return ERR_PTR(-EDQUOT);
}
inode->i_mode = mode;
diff --git a/fs/jfs/jfs_inode.h b/fs/jfs/jfs_inode.h
index 1fc48df670c8..0d06ccfaff0e 100644
--- a/fs/jfs/jfs_inode.h
+++ b/fs/jfs/jfs_inode.h
@@ -3,16 +3,16 @@
*
* 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
+ * 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
+ * along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef _H_JFS_INODE
diff --git a/fs/jfs/jfs_lock.h b/fs/jfs/jfs_lock.h
index 70ac9f7d1e00..7d78e83d7c40 100644
--- a/fs/jfs/jfs_lock.h
+++ b/fs/jfs/jfs_lock.h
@@ -1,19 +1,19 @@
/*
- * Copyright (c) International Business Machines Corp., 2000-2001
- * Portions Copyright (c) Christoph Hellwig, 2001-2002
+ * Copyright (C) International Business Machines Corp., 2000-2001
+ * Portions Copyright (C) Christoph Hellwig, 2001-2002
*
* 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
+ * 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
+ * along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef _H_JFS_LOCK
diff --git a/fs/jfs/jfs_logmgr.c b/fs/jfs/jfs_logmgr.c
index 3315f0b1fbc0..b89c9aba0466 100644
--- a/fs/jfs/jfs_logmgr.c
+++ b/fs/jfs/jfs_logmgr.c
@@ -4,16 +4,16 @@
*
* 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
+ * 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
+ * along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
@@ -337,7 +337,7 @@ int lmLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd,
* PARAMETER: cd - commit descriptor
*
* RETURN: end-of-log address
- *
+ *
* serialization: LOG_LOCK() held on entry/exit
*/
static int
@@ -554,7 +554,7 @@ lmWriteRecord(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd,
* PARAMETER: log
*
* RETURN: 0
- *
+ *
* serialization: LOG_LOCK() held on entry/exit
*/
static int lmNextPage(struct jfs_log * log)
@@ -656,7 +656,7 @@ static int lmNextPage(struct jfs_log * log)
* page number - redrive pageout of the page at the head of
* pageout queue until full page has been written.
*
- * RETURN:
+ * RETURN:
*
* NOTE:
* LOGGC_LOCK serializes log group commit queue, and
@@ -920,10 +920,10 @@ static void lmPostGC(struct lbuf * bp)
* this code is called again.
*
* PARAMETERS: log - log structure
- * hard_sync - 1 to force all metadata to be written
+ * hard_sync - 1 to force all metadata to be written
*
* RETURN: 0
- *
+ *
* serialization: LOG_LOCK() held on entry/exit
*/
static int lmLogSync(struct jfs_log * log, int hard_sync)
@@ -1052,7 +1052,7 @@ static int lmLogSync(struct jfs_log * log, int hard_sync)
* FUNCTION: write log SYNCPT record for specified log
*
* PARAMETERS: log - log structure
- * hard_sync - set to 1 to force metadata to be written
+ * hard_sync - set to 1 to force metadata to be written
*/
void jfs_syncpt(struct jfs_log *log, int hard_sync)
{ LOG_LOCK(log);
@@ -1067,7 +1067,7 @@ void jfs_syncpt(struct jfs_log *log, int hard_sync)
* insert filesystem in the active list of the log.
*
* PARAMETER: ipmnt - file system mount inode
- * iplog - log inode (out)
+ * iplog - log inode (out)
*
* RETURN:
*
@@ -1082,7 +1082,7 @@ int lmLogOpen(struct super_block *sb)
if (sbi->flag & JFS_NOINTEGRITY)
return open_dummy_log(sb);
-
+
if (sbi->mntflag & JFS_INLINELOG)
return open_inline_log(sb);
@@ -1131,7 +1131,7 @@ int lmLogOpen(struct super_block *sb)
log->bdev = bdev;
memcpy(log->uuid, sbi->loguuid, sizeof(log->uuid));
-
+
/*
* initialize log:
*/
@@ -1253,13 +1253,13 @@ static int open_dummy_log(struct super_block *sb)
* initialize the log from log superblock.
* set the log state in the superblock to LOGMOUNT and
* write SYNCPT log record.
- *
+ *
* PARAMETER: log - log structure
*
* RETURN: 0 - if ok
* -EINVAL - bad log magic number or superblock dirty
* error returned from logwait()
- *
+ *
* serialization: single first open thread
*/
int lmLogInit(struct jfs_log * log)
@@ -1297,7 +1297,7 @@ int lmLogInit(struct jfs_log * log)
if (!test_bit(log_INLINELOG, &log->flag))
log->l2bsize = L2LOGPSIZE;
-
+
/* check for disabled journaling to disk */
if (log->no_integrity) {
/*
@@ -1651,7 +1651,7 @@ void jfs_flush_journal(struct jfs_log *log, int wait)
* PARAMETER: log - log inode
*
* RETURN: 0 - success
- *
+ *
* serialization: single last close thread
*/
int lmLogShutdown(struct jfs_log * log)
@@ -1677,7 +1677,7 @@ int lmLogShutdown(struct jfs_log * log)
lrd.type = cpu_to_le16(LOG_SYNCPT);
lrd.length = 0;
lrd.log.syncpt.sync = 0;
-
+
lsn = lmWriteRecord(log, NULL, &lrd, NULL);
bp = log->bp;
lp = (struct logpage *) bp->l_ldata;
@@ -1703,7 +1703,7 @@ int lmLogShutdown(struct jfs_log * log)
jfs_info("lmLogShutdown: lsn:0x%x page:%d eor:%d",
lsn, log->page, log->eor);
- out:
+ out:
/*
* shutdown per log i/o
*/
@@ -1769,7 +1769,7 @@ static int lmLogFileSystem(struct jfs_log * log, struct jfs_sb_info *sbi,
lbmFree(bpsuper);
return -EIO;
}
-
+
}
/*
diff --git a/fs/jfs/jfs_logmgr.h b/fs/jfs/jfs_logmgr.h
index 8c6909b80014..a53fb17ea219 100644
--- a/fs/jfs/jfs_logmgr.h
+++ b/fs/jfs/jfs_logmgr.h
@@ -4,16 +4,16 @@
*
* 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
+ * 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
+ * along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef _H_JFS_LOGMGR
@@ -35,19 +35,19 @@
/*
* log logical volume
*
- * a log is used to make the commit operation on journalled
+ * a log is used to make the commit operation on journalled
* files within the same logical volume group atomic.
* a log is implemented with a logical volume.
- * there is one log per logical volume group.
+ * there is one log per logical volume group.
*
* block 0 of the log logical volume is not used (ipl etc).
* block 1 contains a log "superblock" and is used by logFormat(),
- * lmLogInit(), lmLogShutdown(), and logRedo() to record status
- * of the log but is not otherwise used during normal processing.
+ * lmLogInit(), lmLogShutdown(), and logRedo() to record status
+ * of the log but is not otherwise used during normal processing.
* blocks 2 - (N-1) are used to contain log records.
*
- * when a volume group is varied-on-line, logRedo() must have
- * been executed before the file systems (logical volumes) in
+ * when a volume group is varied-on-line, logRedo() must have
+ * been executed before the file systems (logical volumes) in
* the volume group can be mounted.
*/
/*
@@ -97,26 +97,26 @@ struct logsuper {
* log logical page
*
* (this comment should be rewritten !)
- * the header and trailer structures (h,t) will normally have
+ * the header and trailer structures (h,t) will normally have
* the same page and eor value.
- * An exception to this occurs when a complete page write is not
+ * An exception to this occurs when a complete page write is not
* accomplished on a power failure. Since the hardware may "split write"
- * sectors in the page, any out of order sequence may occur during powerfail
+ * sectors in the page, any out of order sequence may occur during powerfail
* and needs to be recognized during log replay. The xor value is
* an "exclusive or" of all log words in the page up to eor. This
* 32 bit eor is stored with the top 16 bits in the header and the
* bottom 16 bits in the trailer. logredo can easily recognize pages
- * that were not completed by reconstructing this eor and checking
+ * that were not completed by reconstructing this eor and checking
* the log page.
*
- * Previous versions of the operating system did not allow split
- * writes and detected partially written records in logredo by
- * ordering the updates to the header, trailer, and the move of data
- * into the logdata area. The order: (1) data is moved (2) header
- * is updated (3) trailer is updated. In logredo, when the header
- * differed from the trailer, the header and trailer were reconciled
- * as follows: if h.page != t.page they were set to the smaller of
- * the two and h.eor and t.eor set to 8 (i.e. empty page). if (only)
+ * Previous versions of the operating system did not allow split
+ * writes and detected partially written records in logredo by
+ * ordering the updates to the header, trailer, and the move of data
+ * into the logdata area. The order: (1) data is moved (2) header
+ * is updated (3) trailer is updated. In logredo, when the header
+ * differed from the trailer, the header and trailer were reconciled
+ * as follows: if h.page != t.page they were set to the smaller of
+ * the two and h.eor and t.eor set to 8 (i.e. empty page). if (only)
* h.eor != t.eor they were set to the smaller of their two values.
*/
struct logpage {
@@ -147,20 +147,20 @@ struct logpage {
* in a page, pages are written to temporary paging space if
* if they must be written to disk before commit, and i/o is
* scheduled for modified pages to their home location after
- * the log records containing the after values and the commit
+ * the log records containing the after values and the commit
* record is written to the log on disk, undo discards the copy
* in main-memory.)
*
- * a log record consists of a data area of variable length followed by
+ * a log record consists of a data area of variable length followed by
* a descriptor of fixed size LOGRDSIZE bytes.
- * the data area is rounded up to an integral number of 4-bytes and
+ * the data area is rounded up to an integral number of 4-bytes and
* must be no longer than LOGPSIZE.
- * the descriptor is of size of multiple of 4-bytes and aligned on a
- * 4-byte boundary.
+ * the descriptor is of size of multiple of 4-bytes and aligned on a
+ * 4-byte boundary.
* records are packed one after the other in the data area of log pages.
- * (sometimes a DUMMY record is inserted so that at least one record ends
+ * (sometimes a DUMMY record is inserted so that at least one record ends
* on every page or the longest record is placed on at most two pages).
- * the field eor in page header/trailer points to the byte following
+ * the field eor in page header/trailer points to the byte following
* the last record on a page.
*/
@@ -270,11 +270,11 @@ struct lrd {
/*
* NOREDOINOEXT: the inode extent is freed
*
- * do not apply after-image records which precede this
- * record in the log with the any of the 4 page block
- * numbers in this inode extent.
- *
- * NOTE: The fileset and pxd fields MUST remain in
+ * do not apply after-image records which precede this
+ * record in the log with the any of the 4 page block
+ * numbers in this inode extent.
+ *
+ * NOTE: The fileset and pxd fields MUST remain in
* the same fields in the REDOPAGE record format.
*
*/
@@ -319,12 +319,10 @@ struct lrd {
* do not apply records which precede this record in the log
* with the same inode number.
*
- * NOREDILE must be the first to be written at commit
+ * NOREDOFILE must be the first to be written at commit
* (last to be read in logredo()) - it prevents
* replay of preceding updates of all preceding generations
- * of the inumber esp. the on-disk inode itself,
- * but does NOT prevent
- * replay of the
+ * of the inumber esp. the on-disk inode itself.
*/
struct {
__le32 fileset; /* 4: fileset number */
@@ -332,7 +330,7 @@ struct lrd {
} noredofile;
/*
- * ? NEWPAGE:
+ * ? NEWPAGE:
*
* metadata type dependent
*/
@@ -464,7 +462,7 @@ struct lbuf {
s64 l_blkno; /* 8: log page block number */
caddr_t l_ldata; /* 4: data page */
struct page *l_page; /* The page itself */
- uint l_offset; /* Offset of l_ldata within the page */
+ uint l_offset; /* Offset of l_ldata within the page */
wait_queue_head_t l_ioevent; /* 4: i/o done event */
};
diff --git a/fs/jfs/jfs_metapage.c b/fs/jfs/jfs_metapage.c
index f5afc129d6b1..0cccd1c39d75 100644
--- a/fs/jfs/jfs_metapage.c
+++ b/fs/jfs/jfs_metapage.c
@@ -4,16 +4,16 @@
*
* 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
+ * 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
+ * along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
@@ -461,7 +461,7 @@ static int metapage_writepage(struct page *page, struct writeback_control *wbc)
goto add_failed;
if (!bio->bi_size)
goto dump_bio;
-
+
submit_bio(WRITE, bio);
}
if (redirty)
@@ -648,7 +648,7 @@ struct metapage *__get_metapage(struct inode *inode, unsigned long lblock,
jfs_err("logical_size = %d, size = %d",
mp->logical_size, size);
dump_stack();
- goto unlock;
+ goto unlock;
}
mp->count++;
lock_metapage(mp);
@@ -658,7 +658,7 @@ struct metapage *__get_metapage(struct inode *inode, unsigned long lblock,
"__get_metapage: using a "
"discarded metapage");
discard_metapage(mp);
- goto unlock;
+ goto unlock;
}
clear_bit(META_discard, &mp->flag);
}
diff --git a/fs/jfs/jfs_metapage.h b/fs/jfs/jfs_metapage.h
index d17a3290f5aa..d94f8d9e87d7 100644
--- a/fs/jfs/jfs_metapage.h
+++ b/fs/jfs/jfs_metapage.h
@@ -4,16 +4,16 @@
*
* 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
+ * 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
+ * along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef _H_JFS_METAPAGE
@@ -33,7 +33,7 @@ struct metapage {
unsigned long flag; /* See Below */
unsigned long count; /* Reference count */
void *data; /* Data pointer */
- sector_t index; /* block address of page */
+ sector_t index; /* block address of page */
wait_queue_head_t wait;
/* implementation */
@@ -65,10 +65,10 @@ extern struct metapage *__get_metapage(struct inode *inode,
int absolute, unsigned long new);
#define read_metapage(inode, lblock, size, absolute)\
- __get_metapage(inode, lblock, size, absolute, FALSE)
+ __get_metapage(inode, lblock, size, absolute, false)
#define get_metapage(inode, lblock, size, absolute)\
- __get_metapage(inode, lblock, size, absolute, TRUE)
+ __get_metapage(inode, lblock, size, absolute, true)
extern void release_metapage(struct metapage *);
extern void grab_metapage(struct metapage *);
diff --git a/fs/jfs/jfs_mount.c b/fs/jfs/jfs_mount.c
index 032d111bc330..4dd479834897 100644
--- a/fs/jfs/jfs_mount.c
+++ b/fs/jfs/jfs_mount.c
@@ -3,16 +3,16 @@
*
* 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
+ * 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
+ * along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
@@ -21,18 +21,18 @@
*
* note: file system in transition to aggregate/fileset:
*
- * file system mount is interpreted as the mount of aggregate,
- * if not already mounted, and mount of the single/only fileset in
+ * file system mount is interpreted as the mount of aggregate,
+ * if not already mounted, and mount of the single/only fileset in
* the aggregate;
*
* a file system/aggregate is represented by an internal inode
* (aka mount inode) initialized with aggregate superblock;
- * each vfs represents a fileset, and points to its "fileset inode
+ * each vfs represents a fileset, and points to its "fileset inode
* allocation map inode" (aka fileset inode):
- * (an aggregate itself is structured recursively as a filset:
- * an internal vfs is constructed and points to its "fileset inode
- * allocation map inode" (aka aggregate inode) where each inode
- * represents a fileset inode) so that inode number is mapped to
+ * (an aggregate itself is structured recursively as a filset:
+ * an internal vfs is constructed and points to its "fileset inode
+ * allocation map inode" (aka aggregate inode) where each inode
+ * represents a fileset inode) so that inode number is mapped to
* on-disk inode in uniform way at both aggregate and fileset level;
*
* each vnode/inode of a fileset is linked to its vfs (to facilitate
@@ -41,7 +41,7 @@
* per aggregate information, e.g., block size, etc.) as well as
* its file set inode.
*
- * aggregate
+ * aggregate
* ipmnt
* mntvfs -> fileset ipimap+ -> aggregate ipbmap -> aggregate ipaimap;
* fileset vfs -> vp(1) <-> ... <-> vp(n) <->vproot;
@@ -88,7 +88,7 @@ int jfs_mount(struct super_block *sb)
struct inode *ipbmap = NULL;
/*
- * read/validate superblock
+ * read/validate superblock
* (initialize mount inode from the superblock)
*/
if ((rc = chkSuper(sb))) {
@@ -238,7 +238,7 @@ int jfs_mount(struct super_block *sb)
*/
int jfs_mount_rw(struct super_block *sb, int remount)
{
- struct jfs_sb_info *sbi = JFS_SBI(sb);
+ struct jfs_sb_info *sbi = JFS_SBI(sb);
int rc;
/*
@@ -291,7 +291,7 @@ int jfs_mount_rw(struct super_block *sb, int remount)
/*
* chkSuper()
*
- * validate the superblock of the file system to be mounted and
+ * validate the superblock of the file system to be mounted and
* get the file system parameters.
*
* returns
@@ -426,7 +426,7 @@ int updateSuper(struct super_block *sb, uint state)
jfs_err("updateSuper: bad state");
} else if (sbi->state == FM_DIRTY)
return 0;
-
+
if ((rc = readSuper(sb, &bh)))
return rc;
@@ -486,9 +486,9 @@ int readSuper(struct super_block *sb, struct buffer_head **bpp)
* for this file system past this point in log.
* it is harmless if mount fails.
*
- * note: MOUNT record is at aggregate level, not at fileset level,
+ * note: MOUNT record is at aggregate level, not at fileset level,
* since log records of previous mounts of a fileset
- * (e.g., AFTER record of extent allocation) have to be processed
+ * (e.g., AFTER record of extent allocation) have to be processed
* to update block allocation map at aggregate level.
*/
static int logMOUNT(struct super_block *sb)
diff --git a/fs/jfs/jfs_superblock.h b/fs/jfs/jfs_superblock.h
index 682cf1a68a18..884fc21ab8ee 100644
--- a/fs/jfs/jfs_superblock.h
+++ b/fs/jfs/jfs_superblock.h
@@ -3,16 +3,16 @@
*
* 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
+ * 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
+ * along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef _H_JFS_SUPERBLOCK
@@ -21,14 +21,14 @@
/*
* make the magic number something a human could read
*/
-#define JFS_MAGIC "JFS1" /* Magic word */
+#define JFS_MAGIC "JFS1" /* Magic word */
#define JFS_VERSION 2 /* Version number: Version 2 */
#define LV_NAME_SIZE 11 /* MUST BE 11 for OS/2 boot sector */
-/*
- * aggregate superblock
+/*
+ * aggregate superblock
*
* The name superblock is too close to super_block, so the name has been
* changed to jfs_superblock. The utilities are still using the old name.
@@ -40,7 +40,7 @@ struct jfs_superblock {
__le64 s_size; /* 8: aggregate size in hardware/LVM blocks;
* VFS: number of blocks
*/
- __le32 s_bsize; /* 4: aggregate block size in bytes;
+ __le32 s_bsize; /* 4: aggregate block size in bytes;
* VFS: fragment size
*/
__le16 s_l2bsize; /* 2: log2 of s_bsize */
@@ -54,7 +54,7 @@ struct jfs_superblock {
__le32 s_flag; /* 4: aggregate attributes:
* see jfs_filsys.h
*/
- __le32 s_state; /* 4: mount/unmount/recovery state:
+ __le32 s_state; /* 4: mount/unmount/recovery state:
* see jfs_filsys.h
*/
__le32 s_compress; /* 4: > 0 if data compression */
@@ -75,11 +75,11 @@ struct jfs_superblock {
struct timestruc_t s_time; /* 8: time last updated */
__le32 s_fsckloglen; /* 4: Number of filesystem blocks reserved for
- * the fsck service log.
+ * the fsck service log.
* N.B. These blocks are divided among the
* versions kept. This is not a per
* version size.
- * N.B. These blocks are included in the
+ * N.B. These blocks are included in the
* length field of s_fsckpxd.
*/
s8 s_fscklog; /* 1: which fsck service log is most recent
@@ -87,7 +87,7 @@ struct jfs_superblock {
* 1 => the first one
* 2 => the 2nd one
*/
- char s_fpack[11]; /* 11: file system volume name
+ char s_fpack[11]; /* 11: file system volume name
* N.B. This must be 11 bytes to
* conform with the OS/2 BootSector
* requirements
diff --git a/fs/jfs/jfs_txnmgr.c b/fs/jfs/jfs_txnmgr.c
index 3856efc399c1..81f6f04af192 100644
--- a/fs/jfs/jfs_txnmgr.c
+++ b/fs/jfs/jfs_txnmgr.c
@@ -4,16 +4,16 @@
*
* 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
+ * 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
+ * along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
@@ -2026,8 +2026,6 @@ static void xtLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd,
* truncate entry XAD[twm == next - 1]:
*/
if (twm == next - 1) {
- struct pxd_lock *pxdlock;
-
/* format a maplock for txUpdateMap() to update bmap
* to free truncated delta extent of the truncated
* entry XAD[next - 1];
@@ -2393,7 +2391,7 @@ static void txUpdateMap(struct tblock * tblk)
* unlock mapper/write lock
*/
if (tblk->xflag & COMMIT_CREATE) {
- diUpdatePMap(ipimap, tblk->ino, FALSE, tblk);
+ diUpdatePMap(ipimap, tblk->ino, false, tblk);
/* update persistent block allocation map
* for the allocation of inode extent;
*/
@@ -2403,7 +2401,7 @@ static void txUpdateMap(struct tblock * tblk)
txAllocPMap(ipimap, (struct maplock *) & pxdlock, tblk);
} else if (tblk->xflag & COMMIT_DELETE) {
ip = tblk->u.ip;
- diUpdatePMap(ipimap, ip->i_ino, TRUE, tblk);
+ diUpdatePMap(ipimap, ip->i_ino, true, tblk);
iput(ip);
}
}
@@ -2451,7 +2449,7 @@ static void txAllocPMap(struct inode *ip, struct maplock * maplock,
if (xad->flag & (XAD_NEW | XAD_EXTENDED)) {
xaddr = addressXAD(xad);
xlen = lengthXAD(xad);
- dbUpdatePMap(ipbmap, FALSE, xaddr,
+ dbUpdatePMap(ipbmap, false, xaddr,
(s64) xlen, tblk);
xad->flag &= ~(XAD_NEW | XAD_EXTENDED);
jfs_info("allocPMap: xaddr:0x%lx xlen:%d",
@@ -2462,7 +2460,7 @@ static void txAllocPMap(struct inode *ip, struct maplock * maplock,
pxdlock = (struct pxd_lock *) maplock;
xaddr = addressPXD(&pxdlock->pxd);
xlen = lengthPXD(&pxdlock->pxd);
- dbUpdatePMap(ipbmap, FALSE, xaddr, (s64) xlen, tblk);
+ dbUpdatePMap(ipbmap, false, xaddr, (s64) xlen, tblk);
jfs_info("allocPMap: xaddr:0x%lx xlen:%d", (ulong) xaddr, xlen);
} else { /* (maplock->flag & mlckALLOCPXDLIST) */
@@ -2471,7 +2469,7 @@ static void txAllocPMap(struct inode *ip, struct maplock * maplock,
for (n = 0; n < pxdlistlock->count; n++, pxd++) {
xaddr = addressPXD(pxd);
xlen = lengthPXD(pxd);
- dbUpdatePMap(ipbmap, FALSE, xaddr, (s64) xlen,
+ dbUpdatePMap(ipbmap, false, xaddr, (s64) xlen,
tblk);
jfs_info("allocPMap: xaddr:0x%lx xlen:%d",
(ulong) xaddr, xlen);
@@ -2513,7 +2511,7 @@ void txFreeMap(struct inode *ip,
if (!(xad->flag & XAD_NEW)) {
xaddr = addressXAD(xad);
xlen = lengthXAD(xad);
- dbUpdatePMap(ipbmap, TRUE, xaddr,
+ dbUpdatePMap(ipbmap, true, xaddr,
(s64) xlen, tblk);
jfs_info("freePMap: xaddr:0x%lx "
"xlen:%d",
@@ -2524,7 +2522,7 @@ void txFreeMap(struct inode *ip,
pxdlock = (struct pxd_lock *) maplock;
xaddr = addressPXD(&pxdlock->pxd);
xlen = lengthPXD(&pxdlock->pxd);
- dbUpdatePMap(ipbmap, TRUE, xaddr, (s64) xlen,
+ dbUpdatePMap(ipbmap, true, xaddr, (s64) xlen,
tblk);
jfs_info("freePMap: xaddr:0x%lx xlen:%d",
(ulong) xaddr, xlen);
@@ -2535,7 +2533,7 @@ void txFreeMap(struct inode *ip,
for (n = 0; n < pxdlistlock->count; n++, pxd++) {
xaddr = addressPXD(pxd);
xlen = lengthPXD(pxd);
- dbUpdatePMap(ipbmap, TRUE, xaddr,
+ dbUpdatePMap(ipbmap, true, xaddr,
(s64) xlen, tblk);
jfs_info("freePMap: xaddr:0x%lx xlen:%d",
(ulong) xaddr, xlen);
diff --git a/fs/jfs/jfs_txnmgr.h b/fs/jfs/jfs_txnmgr.h
index 0e4dc4514c47..7863cf21afca 100644
--- a/fs/jfs/jfs_txnmgr.h
+++ b/fs/jfs/jfs_txnmgr.h
@@ -3,16 +3,16 @@
*
* 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
+ * 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
+ * along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef _H_JFS_TXNMGR
@@ -179,7 +179,7 @@ struct linelock {
/* (8) */
struct lv lv[20]; /* 40: */
-}; /* (48) */
+}; /* (48) */
#define dt_lock linelock
@@ -211,8 +211,8 @@ struct xtlock {
* at tlock.lock/linelock: watch for alignment;
* N.B. next field may be set by linelock, and should not
* be modified by maplock;
- * N.B. index of the first pxdlock specifies index of next
- * free maplock (i.e., number of maplock) in the tlock;
+ * N.B. index of the first pxdlock specifies index of next
+ * free maplock (i.e., number of maplock) in the tlock;
*/
struct maplock {
lid_t next; /* 2: */
diff --git a/fs/jfs/jfs_types.h b/fs/jfs/jfs_types.h
index 5bfad39a2078..09b252958687 100644
--- a/fs/jfs/jfs_types.h
+++ b/fs/jfs/jfs_types.h
@@ -57,10 +57,6 @@ struct timestruc_t {
#define HIGHORDER 0x80000000u /* high order bit on */
#define ONES 0xffffffffu /* all bit on */
-typedef int boolean_t;
-#define TRUE 1
-#define FALSE 0
-
/*
* logical xd (lxd)
*/
diff --git a/fs/jfs/jfs_umount.c b/fs/jfs/jfs_umount.c
index 21eaf7ac0fcb..a386f48c73fc 100644
--- a/fs/jfs/jfs_umount.c
+++ b/fs/jfs/jfs_umount.c
@@ -3,16 +3,16 @@
*
* 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
+ * 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
+ * along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
@@ -22,8 +22,8 @@
* note: file system in transition to aggregate/fileset:
* (ref. jfs_mount.c)
*
- * file system unmount is interpreted as mount of the single/only
- * fileset in the aggregate and, if unmount of the last fileset,
+ * file system unmount is interpreted as mount of the single/only
+ * fileset in the aggregate and, if unmount of the last fileset,
* as unmount of the aggerate;
*/
@@ -60,13 +60,13 @@ int jfs_umount(struct super_block *sb)
jfs_info("UnMount JFS: sb:0x%p", sb);
/*
- * update superblock and close log
+ * update superblock and close log
*
* if mounted read-write and log based recovery was enabled
*/
if ((log = sbi->log))
/*
- * Wait for outstanding transactions to be written to log:
+ * Wait for outstanding transactions to be written to log:
*/
jfs_flush_journal(log, 2);
@@ -112,17 +112,17 @@ int jfs_umount(struct super_block *sb)
/*
* ensure all file system file pages are propagated to their
- * home blocks on disk (and their in-memory buffer pages are
+ * home blocks on disk (and their in-memory buffer pages are
* invalidated) BEFORE updating file system superblock state
- * (to signify file system is unmounted cleanly, and thus in
- * consistent state) and log superblock active file system
+ * (to signify file system is unmounted cleanly, and thus in
+ * consistent state) and log superblock active file system
* list (to signify skip logredo()).
*/
if (log) { /* log = NULL if read-only mount */
updateSuper(sb, FM_CLEAN);
/*
- * close log:
+ * close log:
*
* remove file system from log active file system list.
*/
@@ -142,7 +142,7 @@ int jfs_umount_rw(struct super_block *sb)
return 0;
/*
- * close log:
+ * close log:
*
* remove file system from log active file system list.
*/
diff --git a/fs/jfs/jfs_unicode.c b/fs/jfs/jfs_unicode.c
index f327decfb155..c7de6f5bbefc 100644
--- a/fs/jfs/jfs_unicode.c
+++ b/fs/jfs/jfs_unicode.c
@@ -3,16 +3,16 @@
*
* 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
+ * 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
+ * along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
@@ -57,8 +57,8 @@ int jfs_strfromUCS_le(char *to, const __le16 * from,
warn--;
warn_again--;
printk(KERN_ERR
- "non-latin1 character 0x%x found in JFS file name\n",
- le16_to_cpu(from[i]));
+ "non-latin1 character 0x%x found in JFS file name\n",
+ le16_to_cpu(from[i]));
printk(KERN_ERR
"mount with iocharset=utf8 to access\n");
}
@@ -124,7 +124,7 @@ int get_UCSname(struct component_name * uniName, struct dentry *dentry)
kmalloc((length + 1) * sizeof(wchar_t), GFP_NOFS);
if (uniName->name == NULL)
- return -ENOSPC;
+ return -ENOMEM;
uniName->namlen = jfs_strtoUCS(uniName->name, dentry->d_name.name,
length, nls_tab);
diff --git a/fs/jfs/jfs_unicode.h b/fs/jfs/jfs_unicode.h
index 69e25ebe87ac..3fbb3a225590 100644
--- a/fs/jfs/jfs_unicode.h
+++ b/fs/jfs/jfs_unicode.h
@@ -1,19 +1,19 @@
/*
- * Copyright (c) International Business Machines Corp., 2000-2002
- * Portions Copyright (c) Christoph Hellwig, 2001-2002
+ * Copyright (C) International Business Machines Corp., 2000-2002
+ * Portions Copyright (C) Christoph Hellwig, 2001-2002
*
* 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
+ * 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
+ * along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef _H_JFS_UNICODE
diff --git a/fs/jfs/jfs_uniupr.c b/fs/jfs/jfs_uniupr.c
index 4ab185d26308..cfe50666d312 100644
--- a/fs/jfs/jfs_uniupr.c
+++ b/fs/jfs/jfs_uniupr.c
@@ -1,18 +1,18 @@
/*
- * Copyright (c) International Business Machines Corp., 2000-2002
+ * Copyright (C) International Business Machines Corp., 2000-2002
*
* 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
+ * 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
+ * along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
diff --git a/fs/jfs/jfs_xattr.h b/fs/jfs/jfs_xattr.h
index 25e9990bccd1..88b6cc535bf2 100644
--- a/fs/jfs/jfs_xattr.h
+++ b/fs/jfs/jfs_xattr.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) International Business Machines Corp., 2000-2002
+ * Copyright (C) International Business Machines Corp., 2000-2002
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
diff --git a/fs/jfs/jfs_xtree.c b/fs/jfs/jfs_xtree.c
index e72f4ebb6e9c..e98eb03e5310 100644
--- a/fs/jfs/jfs_xtree.c
+++ b/fs/jfs/jfs_xtree.c
@@ -3,16 +3,16 @@
*
* 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
+ * 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
+ * along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/*
@@ -2428,7 +2428,7 @@ printf("xtUpdate.updateLeft.split p:0x%p\n", p);
* return:
*/
int xtAppend(tid_t tid, /* transaction id */
- struct inode *ip, int xflag, s64 xoff, s32 maxblocks,
+ struct inode *ip, int xflag, s64 xoff, s32 maxblocks,
s32 * xlenp, /* (in/out) */
s64 * xaddrp, /* (in/out) */
int flag)
@@ -2499,7 +2499,7 @@ int xtAppend(tid_t tid, /* transaction id */
pxdlist.maxnpxd = pxdlist.npxd = 0;
pxd = &pxdlist.pxd[0];
nblocks = JFS_SBI(ip->i_sb)->nbperpage;
- for (; nsplit > 0; nsplit--, pxd++, xaddr += nblocks, maxblocks -= nblocks) {
+ for (; nsplit > 0; nsplit--, pxd++, xaddr += nblocks, maxblocks -= nblocks) {
if ((rc = dbAllocBottomUp(ip, xaddr, (s64) nblocks)) == 0) {
PXDaddress(pxd, xaddr);
PXDlength(pxd, nblocks);
@@ -2514,7 +2514,7 @@ int xtAppend(tid_t tid, /* transaction id */
goto out;
}
- xlen = min(xlen, maxblocks);
+ xlen = min(xlen, maxblocks);
/*
* allocate data extent requested
@@ -2964,7 +2964,7 @@ xtRelocate(tid_t tid, struct inode * ip, xad_t * oxad, /* old XAD */
cmSetXD(ip, cp, pno, dxaddr, nblks);
/* release the cbuf, mark it as modified */
- cmPut(cp, TRUE);
+ cmPut(cp, true);
dxaddr += nblks;
sxaddr += nblks;
diff --git a/fs/jfs/jfs_xtree.h b/fs/jfs/jfs_xtree.h
index af668a80b40f..164f6f2b1019 100644
--- a/fs/jfs/jfs_xtree.h
+++ b/fs/jfs/jfs_xtree.h
@@ -1,18 +1,18 @@
/*
- * Copyright (c) International Business Machines Corp., 2000-2002
+ * Copyright (C) International Business Machines Corp., 2000-2002
*
* 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
+ * 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
+ * along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef _H_JFS_XTREE
diff --git a/fs/jfs/namei.c b/fs/jfs/namei.c
index 295268ad231b..a6a8c16c872c 100644
--- a/fs/jfs/namei.c
+++ b/fs/jfs/namei.c
@@ -4,16 +4,16 @@
*
* 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
+ * 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
+ * along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
@@ -41,7 +41,7 @@ static s64 commitZeroLink(tid_t, struct inode *);
/*
* NAME: free_ea_wmap(inode)
*
- * FUNCTION: free uncommitted extended attributes from working map
+ * FUNCTION: free uncommitted extended attributes from working map
*
*/
static inline void free_ea_wmap(struct inode *inode)
@@ -62,7 +62,7 @@ static inline void free_ea_wmap(struct inode *inode)
* FUNCTION: create a regular file in the parent directory <dip>
* with name = <from dentry> and mode = <mode>
*
- * PARAMETER: dip - parent directory vnode
+ * PARAMETER: dip - parent directory vnode
* dentry - dentry of new file
* mode - create mode (rwxrwxrwx).
* nd- nd struct
@@ -97,8 +97,8 @@ static int jfs_create(struct inode *dip, struct dentry *dentry, int mode,
* begin the transaction before we search the directory.
*/
ip = ialloc(dip, mode);
- if (ip == NULL) {
- rc = -ENOSPC;
+ if (IS_ERR(ip)) {
+ rc = PTR_ERR(ip);
goto out2;
}
@@ -190,7 +190,7 @@ static int jfs_create(struct inode *dip, struct dentry *dentry, int mode,
* FUNCTION: create a child directory in the parent directory <dip>
* with name = <from dentry> and mode = <mode>
*
- * PARAMETER: dip - parent directory vnode
+ * PARAMETER: dip - parent directory vnode
* dentry - dentry of child directory
* mode - create mode (rwxrwxrwx).
*
@@ -231,8 +231,8 @@ static int jfs_mkdir(struct inode *dip, struct dentry *dentry, int mode)
* begin the transaction before we search the directory.
*/
ip = ialloc(dip, S_IFDIR | mode);
- if (ip == NULL) {
- rc = -ENOSPC;
+ if (IS_ERR(ip)) {
+ rc = PTR_ERR(ip);
goto out2;
}
@@ -292,7 +292,7 @@ static int jfs_mkdir(struct inode *dip, struct dentry *dentry, int mode)
mark_inode_dirty(ip);
/* update parent directory inode */
- dip->i_nlink++; /* for '..' from child directory */
+ inc_nlink(dip); /* for '..' from child directory */
dip->i_ctime = dip->i_mtime = CURRENT_TIME;
mark_inode_dirty(dip);
@@ -324,7 +324,7 @@ static int jfs_mkdir(struct inode *dip, struct dentry *dentry, int mode)
*
* FUNCTION: remove a link to child directory
*
- * PARAMETER: dip - parent inode
+ * PARAMETER: dip - parent inode
* dentry - child directory dentry
*
* RETURN: -EINVAL - if name is . or ..
@@ -332,10 +332,10 @@ static int jfs_mkdir(struct inode *dip, struct dentry *dentry, int mode)
* errors from subroutines
*
* note:
- * if other threads have the directory open when the last link
- * is removed, the "." and ".." entries, if present, are removed before
- * rmdir() returns and no new entries may be created in the directory,
- * but the directory is not removed until the last reference to
+ * if other threads have the directory open when the last link
+ * is removed, the "." and ".." entries, if present, are removed before
+ * rmdir() returns and no new entries may be created in the directory,
+ * but the directory is not removed until the last reference to
* the directory is released (cf.unlink() of regular file).
*/
static int jfs_rmdir(struct inode *dip, struct dentry *dentry)
@@ -393,9 +393,8 @@ static int jfs_rmdir(struct inode *dip, struct dentry *dentry)
/* update parent directory's link count corresponding
* to ".." entry of the target directory deleted
*/
- dip->i_nlink--;
dip->i_ctime = dip->i_mtime = CURRENT_TIME;
- mark_inode_dirty(dip);
+ inode_dec_link_count(dip);
/*
* OS/2 could have created EA and/or ACL
@@ -415,7 +414,7 @@ static int jfs_rmdir(struct inode *dip, struct dentry *dentry)
JFS_IP(ip)->acl.flag = 0;
/* mark the target directory as deleted */
- ip->i_nlink = 0;
+ clear_nlink(ip);
mark_inode_dirty(ip);
rc = txCommit(tid, 2, &iplist[0], 0);
@@ -447,11 +446,11 @@ static int jfs_rmdir(struct inode *dip, struct dentry *dentry)
/*
* NAME: jfs_unlink(dip, dentry)
*
- * FUNCTION: remove a link to object <vp> named by <name>
+ * FUNCTION: remove a link to object <vp> named by <name>
* from parent directory <dvp>
*
- * PARAMETER: dip - inode of parent directory
- * dentry - dentry of object to be removed
+ * PARAMETER: dip - inode of parent directory
+ * dentry - dentry of object to be removed
*
* RETURN: errors from subroutines
*
@@ -515,8 +514,7 @@ static int jfs_unlink(struct inode *dip, struct dentry *dentry)
mark_inode_dirty(dip);
/* update target's inode */
- ip->i_nlink--;
- mark_inode_dirty(ip);
+ inode_dec_link_count(ip);
/*
* commit zero link count object
@@ -600,7 +598,7 @@ static int jfs_unlink(struct inode *dip, struct dentry *dentry)
*
* FUNCTION: for non-directory, called by jfs_remove(),
* truncate a regular file, directory or symbolic
- * link to zero length. return 0 if type is not
+ * link to zero length. return 0 if type is not
* one of these.
*
* if the file is currently associated with a VM segment
@@ -610,7 +608,7 @@ static int jfs_unlink(struct inode *dip, struct dentry *dentry)
* map by ctrunc1.
* if there is no VM segment on entry, the resources are
* freed in both work and permanent map.
- * (? for temporary file - memory object is cached even
+ * (? for temporary file - memory object is cached even
* after no reference:
* reference count > 0 - )
*
@@ -664,7 +662,7 @@ static s64 commitZeroLink(tid_t tid, struct inode *ip)
/*
* free xtree/data (truncate to zero length):
- * free xtree/data pages from cache if COMMIT_PWMAP,
+ * free xtree/data pages from cache if COMMIT_PWMAP,
* free xtree/data blocks from persistent block map, and
* free xtree/data blocks from working block map if COMMIT_PWMAP;
*/
@@ -679,7 +677,7 @@ static s64 commitZeroLink(tid_t tid, struct inode *ip)
* NAME: jfs_free_zero_link()
*
* FUNCTION: for non-directory, called by iClose(),
- * free resources of a file from cache and WORKING map
+ * free resources of a file from cache and WORKING map
* for a file previously committed with zero link count
* while associated with a pager object,
*
@@ -764,7 +762,7 @@ void jfs_free_zero_link(struct inode *ip)
* FUNCTION: create a link to <vp> by the name = <name>
* in the parent directory <dvp>
*
- * PARAMETER: vp - target object
+ * PARAMETER: vp - target object
* dvp - parent directory of new link
* name - name of new link to target object
* crp - credential
@@ -824,7 +822,7 @@ static int jfs_link(struct dentry *old_dentry,
goto free_dname;
/* update object inode */
- ip->i_nlink++; /* for new link */
+ inc_nlink(ip); /* for new link */
ip->i_ctime = CURRENT_TIME;
dir->i_ctime = dir->i_mtime = CURRENT_TIME;
mark_inode_dirty(dir);
@@ -835,7 +833,7 @@ static int jfs_link(struct dentry *old_dentry,
rc = txCommit(tid, 2, &iplist[0], 0);
if (rc) {
- ip->i_nlink--;
+ ip->i_nlink--; /* never instantiated */
iput(ip);
} else
d_instantiate(dentry, ip);
@@ -860,8 +858,8 @@ static int jfs_link(struct dentry *old_dentry,
* in directory <dip>
*
* PARAMETER: dip - parent directory vnode
- * dentry - dentry of symbolic link
- * name - the path name of the existing object
+ * dentry - dentry of symbolic link
+ * name - the path name of the existing object
* that will be the source of the link
*
* RETURN: errors from subroutines
@@ -908,8 +906,8 @@ static int jfs_symlink(struct inode *dip, struct dentry *dentry,
* (iAlloc() returns new, locked inode)
*/
ip = ialloc(dip, S_IFLNK | 0777);
- if (ip == NULL) {
- rc = -ENOSPC;
+ if (IS_ERR(ip)) {
+ rc = PTR_ERR(ip);
goto out2;
}
@@ -928,7 +926,7 @@ static int jfs_symlink(struct inode *dip, struct dentry *dentry,
tblk->u.ixpxd = JFS_IP(ip)->ixpxd;
/* fix symlink access permission
- * (dir_create() ANDs in the u.u_cmask,
+ * (dir_create() ANDs in the u.u_cmask,
* but symlinks really need to be 777 access)
*/
ip->i_mode |= 0777;
@@ -969,7 +967,7 @@ static int jfs_symlink(struct inode *dip, struct dentry *dentry,
ip->i_mapping->a_ops = &jfs_aops;
/*
- * even though the data of symlink object (source
+ * even though the data of symlink object (source
* path name) is treated as non-journaled user data,
* it is read/written thru buffer cache for performance.
*/
@@ -980,7 +978,6 @@ static int jfs_symlink(struct inode *dip, struct dentry *dentry,
xlen = xsize >> JFS_SBI(sb)->l2bsize;
if ((rc = xtInsert(tid, ip, 0, 0, xlen, &xaddr, 0))) {
txAbort(tid, 0);
- rc = -ENOSPC;
goto out3;
}
extent = xaddr;
@@ -1155,9 +1152,9 @@ static int jfs_rename(struct inode *old_dir, struct dentry *old_dentry,
old_ip->i_ino, JFS_RENAME);
if (rc)
goto out4;
- new_ip->i_nlink--;
+ drop_nlink(new_ip);
if (S_ISDIR(new_ip->i_mode)) {
- new_ip->i_nlink--;
+ drop_nlink(new_ip);
if (new_ip->i_nlink) {
mutex_unlock(&JFS_IP(new_ip)->commit_mutex);
if (old_dir != new_dir)
@@ -1178,7 +1175,7 @@ static int jfs_rename(struct inode *old_dir, struct dentry *old_dentry,
/* free block resources */
if ((new_size = commitZeroLink(tid, new_ip)) < 0) {
txAbort(tid, 1); /* Marks FS Dirty */
- rc = new_size;
+ rc = new_size;
goto out4;
}
tblk = tid_to_tblock(tid);
@@ -1208,7 +1205,7 @@ static int jfs_rename(struct inode *old_dir, struct dentry *old_dentry,
goto out4;
}
if (S_ISDIR(old_ip->i_mode))
- new_dir->i_nlink++;
+ inc_nlink(new_dir);
}
/*
* Remove old directory entry
@@ -1223,7 +1220,7 @@ static int jfs_rename(struct inode *old_dir, struct dentry *old_dentry,
goto out4;
}
if (S_ISDIR(old_ip->i_mode)) {
- old_dir->i_nlink--;
+ drop_nlink(old_dir);
if (old_dir != new_dir) {
/*
* Change inode number of parent for moved directory
@@ -1294,7 +1291,7 @@ static int jfs_rename(struct inode *old_dir, struct dentry *old_dentry,
new_size = xtTruncate_pmap(tid, new_ip, new_size);
if (new_size < 0) {
txAbort(tid, 1);
- rc = new_size;
+ rc = new_size;
} else
rc = txCommit(tid, 1, &new_ip, COMMIT_SYNC);
txEnd(tid);
@@ -1352,8 +1349,8 @@ static int jfs_mknod(struct inode *dir, struct dentry *dentry,
goto out;
ip = ialloc(dir, mode);
- if (ip == NULL) {
- rc = -ENOSPC;
+ if (IS_ERR(ip)) {
+ rc = PTR_ERR(ip);
goto out1;
}
jfs_ip = JFS_IP(ip);
diff --git a/fs/jfs/resize.c b/fs/jfs/resize.c
index 45180361871c..79d625f3f733 100644
--- a/fs/jfs/resize.c
+++ b/fs/jfs/resize.c
@@ -3,16 +3,16 @@
*
* 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
+ * 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
+ * along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
diff --git a/fs/jfs/super.c b/fs/jfs/super.c
index 143bcd1d5eaa..9c1c6e0e633d 100644
--- a/fs/jfs/super.c
+++ b/fs/jfs/super.c
@@ -4,16 +4,16 @@
*
* 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
+ * 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
+ * along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
@@ -82,7 +82,7 @@ static void jfs_handle_error(struct super_block *sb)
"as read-only\n",
sb->s_id);
sb->s_flags |= MS_RDONLY;
- }
+ }
/* nothing is done for continue beyond marking the superblock dirty */
}
@@ -422,7 +422,7 @@ static int jfs_fill_super(struct super_block *sb, void *data, int silent)
sbi = kzalloc(sizeof (struct jfs_sb_info), GFP_KERNEL);
if (!sbi)
- return -ENOSPC;
+ return -ENOMEM;
sb->s_fs_info = sbi;
sbi->sb = sb;
sbi->uid = sbi->gid = sbi->umask = -1;
@@ -775,7 +775,7 @@ static int __init init_jfs_fs(void)
int rc;
jfs_inode_cachep =
- kmem_cache_create("jfs_ip", sizeof(struct jfs_inode_info), 0,
+ kmem_cache_create("jfs_ip", sizeof(struct jfs_inode_info), 0,
SLAB_RECLAIM_ACCOUNT|SLAB_MEM_SPREAD,
init_once, NULL);
if (jfs_inode_cachep == NULL)
diff --git a/fs/jfs/symlink.c b/fs/jfs/symlink.c
index 16477b3835e1..cee43f36f51d 100644
--- a/fs/jfs/symlink.c
+++ b/fs/jfs/symlink.c
@@ -3,16 +3,16 @@
*
* 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
+ * 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
+ * along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
diff --git a/fs/jfs/xattr.c b/fs/jfs/xattr.c
index 9bc5b7c055ce..4c7985ebca92 100644
--- a/fs/jfs/xattr.c
+++ b/fs/jfs/xattr.c
@@ -4,16 +4,16 @@
*
* 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
+ * 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
+ * along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
@@ -57,7 +57,7 @@
*
* 0 4 4 + EA_SIZE(ea1)
* +------------+-------------------+--------------------+-----
- * | Overall EA | First FEA Element | Second FEA Element | .....
+ * | Overall EA | First FEA Element | Second FEA Element | .....
* | List Size | | |
* +------------+-------------------+--------------------+-----
*
@@ -97,26 +97,26 @@ static inline int is_os2_xattr(struct jfs_ea *ea)
*/
if ((ea->namelen >= XATTR_SYSTEM_PREFIX_LEN) &&
!strncmp(ea->name, XATTR_SYSTEM_PREFIX, XATTR_SYSTEM_PREFIX_LEN))
- return FALSE;
+ return false;
/*
* Check for "user."
*/
if ((ea->namelen >= XATTR_USER_PREFIX_LEN) &&
!strncmp(ea->name, XATTR_USER_PREFIX, XATTR_USER_PREFIX_LEN))
- return FALSE;
+ return false;
/*
* Check for "security."
*/
if ((ea->namelen >= XATTR_SECURITY_PREFIX_LEN) &&
!strncmp(ea->name, XATTR_SECURITY_PREFIX,
XATTR_SECURITY_PREFIX_LEN))
- return FALSE;
+ return false;
/*
* Check for "trusted."
*/
if ((ea->namelen >= XATTR_TRUSTED_PREFIX_LEN) &&
!strncmp(ea->name, XATTR_TRUSTED_PREFIX, XATTR_TRUSTED_PREFIX_LEN))
- return FALSE;
+ return false;
/*
* Add any other valid namespace prefixes here
*/
@@ -124,7 +124,7 @@ static inline int is_os2_xattr(struct jfs_ea *ea)
/*
* We assume it's OS/2's flat namespace
*/
- return TRUE;
+ return true;
}
static inline int name_size(struct jfs_ea *ea)
@@ -155,9 +155,9 @@ static void ea_release(struct inode *inode, struct ea_buffer *ea_buf);
/*
* NAME: ea_write_inline
- *
+ *
* FUNCTION: Attempt to write an EA inline if area is available
- *
+ *
* PRE CONDITIONS:
* Already verified that the specified EA is small enough to fit inline
*
@@ -216,10 +216,10 @@ static int ea_write_inline(struct inode *ip, struct jfs_ea_list *ealist,
/*
* NAME: ea_write
- *
+ *
* FUNCTION: Write an EA for an inode
- *
- * PRE CONDITIONS: EA has been verified
+ *
+ * PRE CONDITIONS: EA has been verified
*
* PARAMETERS:
* ip - Inode pointer
@@ -340,9 +340,9 @@ static int ea_write(struct inode *ip, struct jfs_ea_list *ealist, int size,
/*
* NAME: ea_read_inline
- *
+ *
* FUNCTION: Read an inlined EA into user's buffer
- *
+ *
* PARAMETERS:
* ip - Inode pointer
* ealist - Pointer to buffer to fill in with EA
@@ -372,9 +372,9 @@ static int ea_read_inline(struct inode *ip, struct jfs_ea_list *ealist)
/*
* NAME: ea_read
- *
+ *
* FUNCTION: copy EA data into user's buffer
- *
+ *
* PARAMETERS:
* ip - Inode pointer
* ealist - Pointer to buffer to fill in with EA
@@ -406,7 +406,7 @@ static int ea_read(struct inode *ip, struct jfs_ea_list *ealist)
return -EIO;
}
- /*
+ /*
* Figure out how many blocks were allocated when this EA list was
* originally written to disk.
*/
@@ -443,14 +443,14 @@ static int ea_read(struct inode *ip, struct jfs_ea_list *ealist)
/*
* NAME: ea_get
- *
+ *
* FUNCTION: Returns buffer containing existing extended attributes.
* The size of the buffer will be the larger of the existing
* attributes size, or min_size.
*
* The buffer, which may be inlined in the inode or in the
- * page cache must be release by calling ea_release or ea_put
- *
+ * page cache must be release by calling ea_release or ea_put
+ *
* PARAMETERS:
* inode - Inode pointer
* ea_buf - Structure to be populated with ealist and its metadata
@@ -1054,7 +1054,7 @@ ssize_t jfs_listxattr(struct dentry * dentry, char *data, size_t buf_size)
/* compute required size of list */
for (ea = FIRST_EA(ealist); ea < END_EALIST(ealist); ea = NEXT_EA(ea)) {
- if (can_list(ea))
+ if (can_list(ea))
size += name_size(ea) + 1;
}
@@ -1069,7 +1069,7 @@ ssize_t jfs_listxattr(struct dentry * dentry, char *data, size_t buf_size)
/* Copy attribute names to buffer */
buffer = data;
for (ea = FIRST_EA(ealist); ea < END_EALIST(ealist); ea = NEXT_EA(ea)) {
- if (can_list(ea)) {
+ if (can_list(ea)) {
int namelen = copy_name(buffer, ea);
buffer += namelen + 1;
}
diff --git a/fs/libfs.c b/fs/libfs.c
index 8db5afb7b0a7..bd08e0e64a8c 100644
--- a/fs/libfs.c
+++ b/fs/libfs.c
@@ -243,7 +243,7 @@ int simple_link(struct dentry *old_dentry, struct inode *dir, struct dentry *den
struct inode *inode = old_dentry->d_inode;
inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME;
- inode->i_nlink++;
+ inc_nlink(inode);
atomic_inc(&inode->i_count);
dget(dentry);
d_instantiate(dentry, inode);
@@ -275,7 +275,7 @@ int simple_unlink(struct inode *dir, struct dentry *dentry)
struct inode *inode = dentry->d_inode;
inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME;
- inode->i_nlink--;
+ drop_nlink(inode);
dput(dentry);
return 0;
}
@@ -285,9 +285,9 @@ int simple_rmdir(struct inode *dir, struct dentry *dentry)
if (!simple_empty(dentry))
return -ENOTEMPTY;
- dentry->d_inode->i_nlink--;
+ drop_nlink(dentry->d_inode);
simple_unlink(dir, dentry);
- dir->i_nlink--;
+ drop_nlink(dir);
return 0;
}
@@ -303,10 +303,10 @@ int simple_rename(struct inode *old_dir, struct dentry *old_dentry,
if (new_dentry->d_inode) {
simple_unlink(new_dir, new_dentry);
if (they_are_dirs)
- old_dir->i_nlink--;
+ drop_nlink(old_dir);
} else if (they_are_dirs) {
- old_dir->i_nlink--;
- new_dir->i_nlink++;
+ drop_nlink(old_dir);
+ inc_nlink(new_dir);
}
old_dir->i_ctime = old_dir->i_mtime = new_dir->i_ctime =
@@ -317,17 +317,9 @@ int simple_rename(struct inode *old_dir, struct dentry *old_dentry,
int simple_readpage(struct file *file, struct page *page)
{
- void *kaddr;
-
- if (PageUptodate(page))
- goto out;
-
- kaddr = kmap_atomic(page, KM_USER0);
- memset(kaddr, 0, PAGE_CACHE_SIZE);
- kunmap_atomic(kaddr, KM_USER0);
+ clear_highpage(page);
flush_dcache_page(page);
SetPageUptodate(page);
-out:
unlock_page(page);
return 0;
}
diff --git a/fs/lockd/clntlock.c b/fs/lockd/clntlock.c
index f95cc3f3c42d..87e1d03e8267 100644
--- a/fs/lockd/clntlock.c
+++ b/fs/lockd/clntlock.c
@@ -202,7 +202,7 @@ reclaimer(void *ptr)
/* This one ensures that our parent doesn't terminate while the
* reclaim is in progress */
lock_kernel();
- lockd_up();
+ lockd_up(0); /* note: this cannot fail as lockd is already running */
nlmclnt_prepare_reclaim(host);
/* First, reclaim all locks that have been marked. */
diff --git a/fs/lockd/clntproc.c b/fs/lockd/clntproc.c
index 271e2165fff6..0116729cec5f 100644
--- a/fs/lockd/clntproc.c
+++ b/fs/lockd/clntproc.c
@@ -129,11 +129,11 @@ static void nlmclnt_setlockargs(struct nlm_rqst *req, struct file_lock *fl)
nlmclnt_next_cookie(&argp->cookie);
argp->state = nsm_local_state;
memcpy(&lock->fh, NFS_FH(fl->fl_file->f_dentry->d_inode), sizeof(struct nfs_fh));
- lock->caller = system_utsname.nodename;
+ lock->caller = utsname()->nodename;
lock->oh.data = req->a_owner;
lock->oh.len = snprintf(req->a_owner, sizeof(req->a_owner), "%u@%s",
(unsigned int)fl->fl_u.nfs_fl.owner->pid,
- system_utsname.nodename);
+ utsname()->nodename);
lock->svid = fl->fl_u.nfs_fl.owner->pid;
lock->fl.fl_start = fl->fl_start;
lock->fl.fl_end = fl->fl_end;
diff --git a/fs/lockd/mon.c b/fs/lockd/mon.c
index 5954dcb497e4..a816b920d431 100644
--- a/fs/lockd/mon.c
+++ b/fs/lockd/mon.c
@@ -145,7 +145,7 @@ xdr_encode_common(struct rpc_rqst *rqstp, u32 *p, struct nsm_args *argp)
*/
sprintf(buffer, "%u.%u.%u.%u", NIPQUAD(argp->addr));
if (!(p = xdr_encode_string(p, buffer))
- || !(p = xdr_encode_string(p, system_utsname.nodename)))
+ || !(p = xdr_encode_string(p, utsname()->nodename)))
return ERR_PTR(-EIO);
*p++ = htonl(argp->prog);
*p++ = htonl(argp->vers);
diff --git a/fs/lockd/svc.c b/fs/lockd/svc.c
index 9a991b52c647..3cc369e5693f 100644
--- a/fs/lockd/svc.c
+++ b/fs/lockd/svc.c
@@ -31,6 +31,7 @@
#include <linux/sunrpc/clnt.h>
#include <linux/sunrpc/svc.h>
#include <linux/sunrpc/svcsock.h>
+#include <net/ip.h>
#include <linux/lockd/lockd.h>
#include <linux/nfs.h>
@@ -46,6 +47,7 @@ EXPORT_SYMBOL(nlmsvc_ops);
static DEFINE_MUTEX(nlmsvc_mutex);
static unsigned int nlmsvc_users;
static pid_t nlmsvc_pid;
+static struct svc_serv *nlmsvc_serv;
int nlmsvc_grace_period;
unsigned long nlmsvc_timeout;
@@ -96,7 +98,6 @@ static inline void clear_grace_period(void)
static void
lockd(struct svc_rqst *rqstp)
{
- struct svc_serv *serv = rqstp->rq_server;
int err = 0;
unsigned long grace_period_expire;
@@ -112,6 +113,7 @@ lockd(struct svc_rqst *rqstp)
* Let our maker know we're running.
*/
nlmsvc_pid = current->pid;
+ nlmsvc_serv = rqstp->rq_server;
complete(&lockd_start_done);
daemonize("lockd");
@@ -161,7 +163,7 @@ lockd(struct svc_rqst *rqstp)
* Find a socket with data available and call its
* recvfrom routine.
*/
- err = svc_recv(serv, rqstp, timeout);
+ err = svc_recv(rqstp, timeout);
if (err == -EAGAIN || err == -EINTR)
continue;
if (err < 0) {
@@ -174,7 +176,7 @@ lockd(struct svc_rqst *rqstp)
dprintk("lockd: request from %08x\n",
(unsigned)ntohl(rqstp->rq_addr.sin_addr.s_addr));
- svc_process(serv, rqstp);
+ svc_process(rqstp);
}
@@ -189,6 +191,7 @@ lockd(struct svc_rqst *rqstp)
nlmsvc_invalidate_all();
nlm_shutdown_hosts();
nlmsvc_pid = 0;
+ nlmsvc_serv = NULL;
} else
printk(KERN_DEBUG
"lockd: new process, skipping host shutdown\n");
@@ -205,54 +208,77 @@ lockd(struct svc_rqst *rqstp)
module_put_and_exit(0);
}
+
+static int find_socket(struct svc_serv *serv, int proto)
+{
+ struct svc_sock *svsk;
+ int found = 0;
+ list_for_each_entry(svsk, &serv->sv_permsocks, sk_list)
+ if (svsk->sk_sk->sk_protocol == proto) {
+ found = 1;
+ break;
+ }
+ return found;
+}
+
+static int make_socks(struct svc_serv *serv, int proto)
+{
+ /* Make any sockets that are needed but not present.
+ * If nlm_udpport or nlm_tcpport were set as module
+ * options, make those sockets unconditionally
+ */
+ static int warned;
+ int err = 0;
+ if (proto == IPPROTO_UDP || nlm_udpport)
+ if (!find_socket(serv, IPPROTO_UDP))
+ err = svc_makesock(serv, IPPROTO_UDP, nlm_udpport);
+ if (err == 0 && (proto == IPPROTO_TCP || nlm_tcpport))
+ if (!find_socket(serv, IPPROTO_TCP))
+ err= svc_makesock(serv, IPPROTO_TCP, nlm_tcpport);
+ if (!err)
+ warned = 0;
+ else if (warned++ == 0)
+ printk(KERN_WARNING
+ "lockd_up: makesock failed, error=%d\n", err);
+ return err;
+}
+
/*
* Bring up the lockd process if it's not already up.
*/
int
-lockd_up(void)
+lockd_up(int proto) /* Maybe add a 'family' option when IPv6 is supported ?? */
{
- static int warned;
struct svc_serv * serv;
int error = 0;
mutex_lock(&nlmsvc_mutex);
/*
- * Unconditionally increment the user count ... this is
- * the number of clients who _want_ a lockd process.
- */
- nlmsvc_users++;
- /*
* Check whether we're already up and running.
*/
- if (nlmsvc_pid)
+ if (nlmsvc_pid) {
+ if (proto)
+ error = make_socks(nlmsvc_serv, proto);
goto out;
+ }
/*
* Sanity check: if there's no pid,
* we should be the first user ...
*/
- if (nlmsvc_users > 1)
+ if (nlmsvc_users)
printk(KERN_WARNING
"lockd_up: no pid, %d users??\n", nlmsvc_users);
error = -ENOMEM;
- serv = svc_create(&nlmsvc_program, LOCKD_BUFSIZE);
+ serv = svc_create(&nlmsvc_program, LOCKD_BUFSIZE, NULL);
if (!serv) {
printk(KERN_WARNING "lockd_up: create service failed\n");
goto out;
}
- if ((error = svc_makesock(serv, IPPROTO_UDP, nlm_udpport)) < 0
-#ifdef CONFIG_NFSD_TCP
- || (error = svc_makesock(serv, IPPROTO_TCP, nlm_tcpport)) < 0
-#endif
- ) {
- if (warned++ == 0)
- printk(KERN_WARNING
- "lockd_up: makesock failed, error=%d\n", error);
+ if ((error = make_socks(serv, proto)) < 0)
goto destroy_and_out;
- }
- warned = 0;
/*
* Create the kernel thread and wait for it to start.
@@ -272,6 +298,8 @@ lockd_up(void)
destroy_and_out:
svc_destroy(serv);
out:
+ if (!error)
+ nlmsvc_users++;
mutex_unlock(&nlmsvc_mutex);
return error;
}
diff --git a/fs/lockd/svclock.c b/fs/lockd/svclock.c
index c9d419703cf3..93c00ee7189d 100644
--- a/fs/lockd/svclock.c
+++ b/fs/lockd/svclock.c
@@ -325,7 +325,7 @@ static int nlmsvc_setgrantargs(struct nlm_rqst *call, struct nlm_lock *lock)
{
locks_copy_lock(&call->a_args.lock.fl, &lock->fl);
memcpy(&call->a_args.lock.fh, &lock->fh, sizeof(call->a_args.lock.fh));
- call->a_args.lock.caller = system_utsname.nodename;
+ call->a_args.lock.caller = utsname()->nodename;
call->a_args.lock.oh.len = lock->oh.len;
/* set default data area */
diff --git a/fs/lockd/xdr.c b/fs/lockd/xdr.c
index 033ea4ac2c30..61c46facf257 100644
--- a/fs/lockd/xdr.c
+++ b/fs/lockd/xdr.c
@@ -515,7 +515,7 @@ nlmclt_decode_res(struct rpc_rqst *req, u32 *p, struct nlm_res *resp)
*/
#define NLM_void_sz 0
#define NLM_cookie_sz 1+XDR_QUADLEN(NLM_MAXCOOKIELEN)
-#define NLM_caller_sz 1+XDR_QUADLEN(sizeof(system_utsname.nodename))
+#define NLM_caller_sz 1+XDR_QUADLEN(sizeof(utsname()->nodename))
#define NLM_netobj_sz 1+XDR_QUADLEN(XDR_MAX_NETOBJ)
/* #define NLM_owner_sz 1+XDR_QUADLEN(NLM_MAXOWNER) */
#define NLM_fhandle_sz 1+XDR_QUADLEN(NFS2_FHSIZE)
diff --git a/fs/locks.c b/fs/locks.c
index d7c53392cac1..e0b6a80649a0 100644
--- a/fs/locks.c
+++ b/fs/locks.c
@@ -314,13 +314,13 @@ static int flock_to_posix_lock(struct file *filp, struct file_lock *fl,
off_t start, end;
switch (l->l_whence) {
- case 0: /*SEEK_SET*/
+ case SEEK_SET:
start = 0;
break;
- case 1: /*SEEK_CUR*/
+ case SEEK_CUR:
start = filp->f_pos;
break;
- case 2: /*SEEK_END*/
+ case SEEK_END:
start = i_size_read(filp->f_dentry->d_inode);
break;
default:
@@ -364,13 +364,13 @@ static int flock64_to_posix_lock(struct file *filp, struct file_lock *fl,
loff_t start;
switch (l->l_whence) {
- case 0: /*SEEK_SET*/
+ case SEEK_SET:
start = 0;
break;
- case 1: /*SEEK_CUR*/
+ case SEEK_CUR:
start = filp->f_pos;
break;
- case 2: /*SEEK_END*/
+ case SEEK_END:
start = i_size_read(filp->f_dentry->d_inode);
break;
default:
@@ -1514,7 +1514,7 @@ int fcntl_setlease(unsigned int fd, struct file *filp, long arg)
goto out_unlock;
}
- error = f_setown(filp, current->pid, 0);
+ error = __f_setown(filp, task_pid(current), PIDTYPE_PID, 0);
out_unlock:
unlock_kernel();
return error;
diff --git a/fs/mbcache.c b/fs/mbcache.c
index e4fde1ab22cd..0ff71256e65b 100644
--- a/fs/mbcache.c
+++ b/fs/mbcache.c
@@ -160,6 +160,7 @@ __mb_cache_entry_forget(struct mb_cache_entry *ce, gfp_t gfp_mask)
static void
__mb_cache_entry_release_unlock(struct mb_cache_entry *ce)
+ __releases(mb_cache_spinlock)
{
/* Wake up all processes queuing for this cache entry. */
if (ce->e_queued)
diff --git a/fs/minix/file.c b/fs/minix/file.c
index 420b32882a10..40eac2e60d25 100644
--- a/fs/minix/file.c
+++ b/fs/minix/file.c
@@ -17,8 +17,10 @@ int minix_sync_file(struct file *, struct dentry *, int);
const struct file_operations minix_file_operations = {
.llseek = generic_file_llseek,
- .read = generic_file_read,
- .write = generic_file_write,
+ .read = do_sync_read,
+ .aio_read = generic_file_aio_read,
+ .write = do_sync_write,
+ .aio_write = generic_file_aio_write,
.mmap = generic_file_mmap,
.fsync = minix_sync_file,
.sendfile = generic_file_sendfile,
diff --git a/fs/minix/namei.c b/fs/minix/namei.c
index 5b6a4540a05b..299bb66e3bde 100644
--- a/fs/minix/namei.c
+++ b/fs/minix/namei.c
@@ -249,7 +249,7 @@ static int minix_rename(struct inode * old_dir, struct dentry *old_dentry,
minix_set_link(new_de, new_page, old_inode);
new_inode->i_ctime = CURRENT_TIME_SEC;
if (dir_de)
- new_inode->i_nlink--;
+ drop_nlink(new_inode);
inode_dec_link_count(new_inode);
} else {
if (dir_de) {
diff --git a/fs/mpage.c b/fs/mpage.c
index 1e4598247d0b..692a3e578fc8 100644
--- a/fs/mpage.c
+++ b/fs/mpage.c
@@ -693,6 +693,8 @@ out:
* the call was made get new I/O started against them. If wbc->sync_mode is
* WB_SYNC_ALL then we were called for data integrity and we must wait for
* existing IO to complete.
+ *
+ * If you fix this you should check generic_writepages() also!
*/
int
mpage_writepages(struct address_space *mapping,
diff --git a/fs/msdos/namei.c b/fs/msdos/namei.c
index 9e44158a7540..b0f01b3b0536 100644
--- a/fs/msdos/namei.c
+++ b/fs/msdos/namei.c
@@ -280,7 +280,7 @@ static int msdos_create(struct inode *dir, struct dentry *dentry, int mode,
struct nameidata *nd)
{
struct super_block *sb = dir->i_sb;
- struct inode *inode;
+ struct inode *inode = NULL;
struct fat_slot_info sinfo;
struct timespec ts;
unsigned char msdos_name[MSDOS_NAME];
@@ -316,6 +316,8 @@ static int msdos_create(struct inode *dir, struct dentry *dentry, int mode,
d_instantiate(dentry, inode);
out:
unlock_kernel();
+ if (!err)
+ err = fat_flush_inodes(sb, dir, inode);
return err;
}
@@ -341,13 +343,15 @@ static int msdos_rmdir(struct inode *dir, struct dentry *dentry)
err = fat_remove_entries(dir, &sinfo); /* and releases bh */
if (err)
goto out;
- dir->i_nlink--;
+ drop_nlink(dir);
- inode->i_nlink = 0;
+ clear_nlink(inode);
inode->i_ctime = CURRENT_TIME_SEC;
fat_detach(inode);
out:
unlock_kernel();
+ if (!err)
+ err = fat_flush_inodes(inode->i_sb, dir, inode);
return err;
}
@@ -385,7 +389,7 @@ static int msdos_mkdir(struct inode *dir, struct dentry *dentry, int mode)
err = msdos_add_entry(dir, msdos_name, 1, is_hid, cluster, &ts, &sinfo);
if (err)
goto out_free;
- dir->i_nlink++;
+ inc_nlink(dir);
inode = fat_build_inode(sb, sinfo.de, sinfo.i_pos);
brelse(sinfo.bh);
@@ -401,6 +405,7 @@ static int msdos_mkdir(struct inode *dir, struct dentry *dentry, int mode)
d_instantiate(dentry, inode);
unlock_kernel();
+ fat_flush_inodes(sb, dir, inode);
return 0;
out_free:
@@ -425,11 +430,13 @@ static int msdos_unlink(struct inode *dir, struct dentry *dentry)
err = fat_remove_entries(dir, &sinfo); /* and releases bh */
if (err)
goto out;
- inode->i_nlink = 0;
+ clear_nlink(inode);
inode->i_ctime = CURRENT_TIME_SEC;
fat_detach(inode);
out:
unlock_kernel();
+ if (!err)
+ err = fat_flush_inodes(inode->i_sb, dir, inode);
return err;
}
@@ -542,9 +549,9 @@ static int do_msdos_rename(struct inode *old_dir, unsigned char *old_name,
if (err)
goto error_dotdot;
}
- old_dir->i_nlink--;
+ drop_nlink(old_dir);
if (!new_inode)
- new_dir->i_nlink++;
+ inc_nlink(new_dir);
}
err = fat_remove_entries(old_dir, &old_sinfo); /* and releases bh */
@@ -559,10 +566,9 @@ static int do_msdos_rename(struct inode *old_dir, unsigned char *old_name,
mark_inode_dirty(old_dir);
if (new_inode) {
+ drop_nlink(new_inode);
if (is_dir)
- new_inode->i_nlink -= 2;
- else
- new_inode->i_nlink--;
+ drop_nlink(new_inode);
new_inode->i_ctime = ts;
}
out:
@@ -635,6 +641,8 @@ static int msdos_rename(struct inode *old_dir, struct dentry *old_dentry,
new_dir, new_msdos_name, new_dentry, is_hid);
out:
unlock_kernel();
+ if (!err)
+ err = fat_flush_inodes(old_dir->i_sb, old_dir, new_dir);
return err;
}
diff --git a/fs/namei.c b/fs/namei.c
index 808e4ea2bb94..28d49b301d55 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -518,18 +518,20 @@ static int __emul_lookup_dentry(const char *, struct nameidata *);
static __always_inline int
walk_init_root(const char *name, struct nameidata *nd)
{
- read_lock(&current->fs->lock);
- if (current->fs->altroot && !(nd->flags & LOOKUP_NOALT)) {
- nd->mnt = mntget(current->fs->altrootmnt);
- nd->dentry = dget(current->fs->altroot);
- read_unlock(&current->fs->lock);
+ struct fs_struct *fs = current->fs;
+
+ read_lock(&fs->lock);
+ if (fs->altroot && !(nd->flags & LOOKUP_NOALT)) {
+ nd->mnt = mntget(fs->altrootmnt);
+ nd->dentry = dget(fs->altroot);
+ read_unlock(&fs->lock);
if (__emul_lookup_dentry(name,nd))
return 0;
- read_lock(&current->fs->lock);
+ read_lock(&fs->lock);
}
- nd->mnt = mntget(current->fs->rootmnt);
- nd->dentry = dget(current->fs->root);
- read_unlock(&current->fs->lock);
+ nd->mnt = mntget(fs->rootmnt);
+ nd->dentry = dget(fs->root);
+ read_unlock(&fs->lock);
return 1;
}
@@ -724,17 +726,19 @@ int follow_down(struct vfsmount **mnt, struct dentry **dentry)
static __always_inline void follow_dotdot(struct nameidata *nd)
{
+ struct fs_struct *fs = current->fs;
+
while(1) {
struct vfsmount *parent;
struct dentry *old = nd->dentry;
- read_lock(&current->fs->lock);
- if (nd->dentry == current->fs->root &&
- nd->mnt == current->fs->rootmnt) {
- read_unlock(&current->fs->lock);
+ read_lock(&fs->lock);
+ if (nd->dentry == fs->root &&
+ nd->mnt == fs->rootmnt) {
+ read_unlock(&fs->lock);
break;
}
- read_unlock(&current->fs->lock);
+ read_unlock(&fs->lock);
spin_lock(&dcache_lock);
if (nd->dentry != nd->mnt->mnt_root) {
nd->dentry = dget(nd->dentry->d_parent);
@@ -1042,15 +1046,17 @@ static int __emul_lookup_dentry(const char *name, struct nameidata *nd)
struct vfsmount *old_mnt = nd->mnt;
struct qstr last = nd->last;
int last_type = nd->last_type;
+ struct fs_struct *fs = current->fs;
+
/*
- * NAME was not found in alternate root or it's a directory. Try to find
- * it in the normal root:
+ * NAME was not found in alternate root or it's a directory.
+ * Try to find it in the normal root:
*/
nd->last_type = LAST_ROOT;
- read_lock(&current->fs->lock);
- nd->mnt = mntget(current->fs->rootmnt);
- nd->dentry = dget(current->fs->root);
- read_unlock(&current->fs->lock);
+ read_lock(&fs->lock);
+ nd->mnt = mntget(fs->rootmnt);
+ nd->dentry = dget(fs->root);
+ read_unlock(&fs->lock);
if (path_walk(name, nd) == 0) {
if (nd->dentry->d_inode) {
dput(old_dentry);
@@ -1074,6 +1080,7 @@ void set_fs_altroot(void)
struct vfsmount *mnt = NULL, *oldmnt;
struct dentry *dentry = NULL, *olddentry;
int err;
+ struct fs_struct *fs = current->fs;
if (!emul)
goto set_it;
@@ -1083,12 +1090,12 @@ void set_fs_altroot(void)
dentry = nd.dentry;
}
set_it:
- write_lock(&current->fs->lock);
- oldmnt = current->fs->altrootmnt;
- olddentry = current->fs->altroot;
- current->fs->altrootmnt = mnt;
- current->fs->altroot = dentry;
- write_unlock(&current->fs->lock);
+ write_lock(&fs->lock);
+ oldmnt = fs->altrootmnt;
+ olddentry = fs->altroot;
+ fs->altrootmnt = mnt;
+ fs->altroot = dentry;
+ write_unlock(&fs->lock);
if (olddentry) {
dput(olddentry);
mntput(oldmnt);
@@ -1102,29 +1109,30 @@ static int fastcall do_path_lookup(int dfd, const char *name,
int retval = 0;
int fput_needed;
struct file *file;
+ struct fs_struct *fs = current->fs;
nd->last_type = LAST_ROOT; /* if there are only slashes... */
nd->flags = flags;
nd->depth = 0;
if (*name=='/') {
- read_lock(&current->fs->lock);
- if (current->fs->altroot && !(nd->flags & LOOKUP_NOALT)) {
- nd->mnt = mntget(current->fs->altrootmnt);
- nd->dentry = dget(current->fs->altroot);
- read_unlock(&current->fs->lock);
+ read_lock(&fs->lock);
+ if (fs->altroot && !(nd->flags & LOOKUP_NOALT)) {
+ nd->mnt = mntget(fs->altrootmnt);
+ nd->dentry = dget(fs->altroot);
+ read_unlock(&fs->lock);
if (__emul_lookup_dentry(name,nd))
goto out; /* found in altroot */
- read_lock(&current->fs->lock);
+ read_lock(&fs->lock);
}
- nd->mnt = mntget(current->fs->rootmnt);
- nd->dentry = dget(current->fs->root);
- read_unlock(&current->fs->lock);
+ nd->mnt = mntget(fs->rootmnt);
+ nd->dentry = dget(fs->root);
+ read_unlock(&fs->lock);
} else if (dfd == AT_FDCWD) {
- read_lock(&current->fs->lock);
- nd->mnt = mntget(current->fs->pwdmnt);
- nd->dentry = dget(current->fs->pwd);
- read_unlock(&current->fs->lock);
+ read_lock(&fs->lock);
+ nd->mnt = mntget(fs->pwdmnt);
+ nd->dentry = dget(fs->pwd);
+ read_unlock(&fs->lock);
} else {
struct dentry *dentry;
@@ -1587,6 +1595,24 @@ int may_open(struct nameidata *nd, int acc_mode, int flag)
return 0;
}
+static int open_namei_create(struct nameidata *nd, struct path *path,
+ int flag, int mode)
+{
+ int error;
+ struct dentry *dir = nd->dentry;
+
+ if (!IS_POSIXACL(dir->d_inode))
+ mode &= ~current->fs->umask;
+ error = vfs_create(dir->d_inode, path->dentry, mode, nd);
+ mutex_unlock(&dir->d_inode->i_mutex);
+ dput(nd->dentry);
+ nd->dentry = path->dentry;
+ if (error)
+ return error;
+ /* Don't check for write permission, don't truncate */
+ return may_open(nd, 0, flag & ~O_TRUNC);
+}
+
/*
* open_namei()
*
@@ -1668,18 +1694,10 @@ do_last:
/* Negative dentry, just create the file */
if (!path.dentry->d_inode) {
- if (!IS_POSIXACL(dir->d_inode))
- mode &= ~current->fs->umask;
- error = vfs_create(dir->d_inode, path.dentry, mode, nd);
- mutex_unlock(&dir->d_inode->i_mutex);
- dput(nd->dentry);
- nd->dentry = path.dentry;
+ error = open_namei_create(nd, &path, flag, mode);
if (error)
goto exit;
- /* Don't check for write permission, don't truncate */
- acc_mode = 0;
- flag &= ~O_TRUNC;
- goto ok;
+ return 0;
}
/*
@@ -1926,30 +1944,32 @@ asmlinkage long sys_mkdirat(int dfd, const char __user *pathname, int mode)
{
int error = 0;
char * tmp;
+ struct dentry *dentry;
+ struct nameidata nd;
tmp = getname(pathname);
error = PTR_ERR(tmp);
- if (!IS_ERR(tmp)) {
- struct dentry *dentry;
- struct nameidata nd;
+ if (IS_ERR(tmp))
+ goto out_err;
- error = do_path_lookup(dfd, tmp, LOOKUP_PARENT, &nd);
- if (error)
- goto out;
- dentry = lookup_create(&nd, 1);
- error = PTR_ERR(dentry);
- if (!IS_ERR(dentry)) {
- if (!IS_POSIXACL(nd.dentry->d_inode))
- mode &= ~current->fs->umask;
- error = vfs_mkdir(nd.dentry->d_inode, dentry, mode);
- dput(dentry);
- }
- mutex_unlock(&nd.dentry->d_inode->i_mutex);
- path_release(&nd);
-out:
- putname(tmp);
- }
+ error = do_path_lookup(dfd, tmp, LOOKUP_PARENT, &nd);
+ if (error)
+ goto out;
+ dentry = lookup_create(&nd, 1);
+ error = PTR_ERR(dentry);
+ if (IS_ERR(dentry))
+ goto out_unlock;
+ if (!IS_POSIXACL(nd.dentry->d_inode))
+ mode &= ~current->fs->umask;
+ error = vfs_mkdir(nd.dentry->d_inode, dentry, mode);
+ dput(dentry);
+out_unlock:
+ mutex_unlock(&nd.dentry->d_inode->i_mutex);
+ path_release(&nd);
+out:
+ putname(tmp);
+out_err:
return error;
}
@@ -2048,10 +2068,11 @@ static long do_rmdir(int dfd, const char __user *pathname)
mutex_lock_nested(&nd.dentry->d_inode->i_mutex, I_MUTEX_PARENT);
dentry = lookup_hash(&nd);
error = PTR_ERR(dentry);
- if (!IS_ERR(dentry)) {
- error = vfs_rmdir(nd.dentry->d_inode, dentry);
- dput(dentry);
- }
+ if (IS_ERR(dentry))
+ goto exit2;
+ error = vfs_rmdir(nd.dentry->d_inode, dentry);
+ dput(dentry);
+exit2:
mutex_unlock(&nd.dentry->d_inode->i_mutex);
exit1:
path_release(&nd);
@@ -2191,30 +2212,33 @@ asmlinkage long sys_symlinkat(const char __user *oldname,
int error = 0;
char * from;
char * to;
+ struct dentry *dentry;
+ struct nameidata nd;
from = getname(oldname);
if(IS_ERR(from))
return PTR_ERR(from);
to = getname(newname);
error = PTR_ERR(to);
- if (!IS_ERR(to)) {
- struct dentry *dentry;
- struct nameidata nd;
+ if (IS_ERR(to))
+ goto out_putname;
- error = do_path_lookup(newdfd, to, LOOKUP_PARENT, &nd);
- if (error)
- goto out;
- dentry = lookup_create(&nd, 0);
- error = PTR_ERR(dentry);
- if (!IS_ERR(dentry)) {
- error = vfs_symlink(nd.dentry->d_inode, dentry, from, S_IALLUGO);
- dput(dentry);
- }
- mutex_unlock(&nd.dentry->d_inode->i_mutex);
- path_release(&nd);
+ error = do_path_lookup(newdfd, to, LOOKUP_PARENT, &nd);
+ if (error)
+ goto out;
+ dentry = lookup_create(&nd, 0);
+ error = PTR_ERR(dentry);
+ if (IS_ERR(dentry))
+ goto out_unlock;
+
+ error = vfs_symlink(nd.dentry->d_inode, dentry, from, S_IALLUGO);
+ dput(dentry);
+out_unlock:
+ mutex_unlock(&nd.dentry->d_inode->i_mutex);
+ path_release(&nd);
out:
- putname(to);
- }
+ putname(to);
+out_putname:
putname(from);
return error;
}
@@ -2300,10 +2324,11 @@ asmlinkage long sys_linkat(int olddfd, const char __user *oldname,
goto out_release;
new_dentry = lookup_create(&nd, 0);
error = PTR_ERR(new_dentry);
- if (!IS_ERR(new_dentry)) {
- error = vfs_link(old_nd.dentry, nd.dentry->d_inode, new_dentry);
- dput(new_dentry);
- }
+ if (IS_ERR(new_dentry))
+ goto out_unlock;
+ error = vfs_link(old_nd.dentry, nd.dentry->d_inode, new_dentry);
+ dput(new_dentry);
+out_unlock:
mutex_unlock(&nd.dentry->d_inode->i_mutex);
out_release:
path_release(&nd);
diff --git a/fs/namespace.c b/fs/namespace.c
index 36d180858136..55442a6cf221 100644
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -13,6 +13,7 @@
#include <linux/sched.h>
#include <linux/smp_lock.h>
#include <linux/init.h>
+#include <linux/kernel.h>
#include <linux/quotaops.h>
#include <linux/acct.h>
#include <linux/capability.h>
@@ -23,12 +24,11 @@
#include <linux/namei.h>
#include <linux/security.h>
#include <linux/mount.h>
+#include <linux/ramfs.h>
#include <asm/uaccess.h>
#include <asm/unistd.h>
#include "pnode.h"
-extern int __init init_rootfs(void);
-
/* spinlock for vfsmount related operations, inplace of dcache_lock */
__cacheline_aligned_in_smp DEFINE_SPINLOCK(vfsmount_lock);
@@ -133,7 +133,7 @@ struct vfsmount *lookup_mnt(struct vfsmount *mnt, struct dentry *dentry)
static inline int check_mnt(struct vfsmount *mnt)
{
- return mnt->mnt_namespace == current->namespace;
+ return mnt->mnt_namespace == current->nsproxy->namespace;
}
static void touch_namespace(struct namespace *ns)
@@ -830,7 +830,7 @@ static int attach_recursive_mnt(struct vfsmount *source_mnt,
if (parent_nd) {
detach_mnt(source_mnt, parent_nd);
attach_mnt(source_mnt, nd);
- touch_namespace(current->namespace);
+ touch_namespace(current->nsproxy->namespace);
} else {
mnt_set_mountpoint(dest_mnt, dest_dentry, source_mnt);
commit_tree(source_mnt);
@@ -1441,7 +1441,7 @@ dput_out:
*/
struct namespace *dup_namespace(struct task_struct *tsk, struct fs_struct *fs)
{
- struct namespace *namespace = tsk->namespace;
+ struct namespace *namespace = tsk->nsproxy->namespace;
struct namespace *new_ns;
struct vfsmount *rootmnt = NULL, *pwdmnt = NULL, *altrootmnt = NULL;
struct vfsmount *p, *q;
@@ -1508,7 +1508,7 @@ struct namespace *dup_namespace(struct task_struct *tsk, struct fs_struct *fs)
int copy_namespace(int flags, struct task_struct *tsk)
{
- struct namespace *namespace = tsk->namespace;
+ struct namespace *namespace = tsk->nsproxy->namespace;
struct namespace *new_ns;
int err = 0;
@@ -1531,7 +1531,7 @@ int copy_namespace(int flags, struct task_struct *tsk)
goto out;
}
- tsk->namespace = new_ns;
+ tsk->nsproxy->namespace = new_ns;
out:
put_namespace(namespace);
@@ -1754,7 +1754,7 @@ asmlinkage long sys_pivot_root(const char __user * new_root,
detach_mnt(user_nd.mnt, &root_parent);
attach_mnt(user_nd.mnt, &old_nd); /* mount old root on put_old */
attach_mnt(new_nd.mnt, &root_parent); /* mount new_root on / */
- touch_namespace(current->namespace);
+ touch_namespace(current->nsproxy->namespace);
spin_unlock(&vfsmount_lock);
chroot_fs_refs(&user_nd, &new_nd);
security_sb_post_pivotroot(&user_nd, &new_nd);
@@ -1780,7 +1780,6 @@ static void __init init_mount_tree(void)
{
struct vfsmount *mnt;
struct namespace *namespace;
- struct task_struct *g, *p;
mnt = do_kern_mount("rootfs", 0, "rootfs", NULL);
if (IS_ERR(mnt))
@@ -1796,13 +1795,8 @@ static void __init init_mount_tree(void)
namespace->root = mnt;
mnt->mnt_namespace = namespace;
- init_task.namespace = namespace;
- read_lock(&tasklist_lock);
- do_each_thread(g, p) {
- get_namespace(namespace);
- p->namespace = namespace;
- } while_each_thread(g, p);
- read_unlock(&tasklist_lock);
+ init_task.nsproxy->namespace = namespace;
+ get_namespace(namespace);
set_fs_pwd(current->fs, namespace->root, namespace->root->mnt_root);
set_fs_root(current->fs, namespace->root, namespace->root->mnt_root);
@@ -1813,6 +1807,7 @@ void __init mnt_init(unsigned long mempages)
struct list_head *d;
unsigned int nr_hash;
int i;
+ int err;
init_rwsem(&namespace_sem);
@@ -1853,8 +1848,14 @@ void __init mnt_init(unsigned long mempages)
d++;
i--;
} while (i);
- sysfs_init();
- subsystem_register(&fs_subsys);
+ err = sysfs_init();
+ if (err)
+ printk(KERN_WARNING "%s: sysfs_init error: %d\n",
+ __FUNCTION__, err);
+ err = subsystem_register(&fs_subsys);
+ if (err)
+ printk(KERN_WARNING "%s: subsystem_register error: %d\n",
+ __FUNCTION__, err);
init_rootfs();
init_mount_tree();
}
diff --git a/fs/ncpfs/dir.c b/fs/ncpfs/dir.c
index b4ee89250e95..458b3b785194 100644
--- a/fs/ncpfs/dir.c
+++ b/fs/ncpfs/dir.c
@@ -53,6 +53,9 @@ const struct file_operations ncp_dir_operations =
.read = generic_read_dir,
.readdir = ncp_readdir,
.ioctl = ncp_ioctl,
+#ifdef CONFIG_COMPAT
+ .compat_ioctl = ncp_compat_ioctl,
+#endif
};
struct inode_operations ncp_dir_inode_operations =
diff --git a/fs/ncpfs/file.c b/fs/ncpfs/file.c
index e6b7c67cf057..df37524b85db 100644
--- a/fs/ncpfs/file.c
+++ b/fs/ncpfs/file.c
@@ -289,6 +289,9 @@ const struct file_operations ncp_file_operations =
.read = ncp_file_read,
.write = ncp_file_write,
.ioctl = ncp_ioctl,
+#ifdef CONFIG_COMPAT
+ .compat_ioctl = ncp_compat_ioctl,
+#endif
.mmap = ncp_mmap,
.release = ncp_release,
.fsync = ncp_fsync,
diff --git a/fs/ncpfs/ioctl.c b/fs/ncpfs/ioctl.c
index 42039fe0653c..a89ac84a8241 100644
--- a/fs/ncpfs/ioctl.c
+++ b/fs/ncpfs/ioctl.c
@@ -7,19 +7,21 @@
*
*/
-
-#include <asm/uaccess.h>
#include <linux/capability.h>
+#include <linux/compat.h>
#include <linux/errno.h>
#include <linux/fs.h>
#include <linux/ioctl.h>
#include <linux/time.h>
#include <linux/mm.h>
#include <linux/highuid.h>
+#include <linux/smp_lock.h>
#include <linux/vmalloc.h>
#include <linux/ncp_fs.h>
+#include <asm/uaccess.h>
+
#include "ncplib_kernel.h"
/* maximum limit for ncp_objectname_ioctl */
@@ -89,6 +91,82 @@ ncp_get_fs_info_v2(struct ncp_server * server, struct file *file,
return 0;
}
+#ifdef CONFIG_COMPAT
+struct compat_ncp_objectname_ioctl
+{
+ s32 auth_type;
+ u32 object_name_len;
+ compat_caddr_t object_name; /* an userspace data, in most cases user name */
+};
+
+struct compat_ncp_fs_info_v2 {
+ s32 version;
+ u32 mounted_uid;
+ u32 connection;
+ u32 buffer_size;
+
+ u32 volume_number;
+ u32 directory_id;
+
+ u32 dummy1;
+ u32 dummy2;
+ u32 dummy3;
+};
+
+struct compat_ncp_ioctl_request {
+ u32 function;
+ u32 size;
+ compat_caddr_t data;
+};
+
+struct compat_ncp_privatedata_ioctl
+{
+ u32 len;
+ compat_caddr_t data; /* ~1000 for NDS */
+};
+
+#define NCP_IOC_GET_FS_INFO_V2_32 _IOWR('n', 4, struct compat_ncp_fs_info_v2)
+#define NCP_IOC_NCPREQUEST_32 _IOR('n', 1, struct compat_ncp_ioctl_request)
+#define NCP_IOC_GETOBJECTNAME_32 _IOWR('n', 9, struct compat_ncp_objectname_ioctl)
+#define NCP_IOC_SETOBJECTNAME_32 _IOR('n', 9, struct compat_ncp_objectname_ioctl)
+#define NCP_IOC_GETPRIVATEDATA_32 _IOWR('n', 10, struct compat_ncp_privatedata_ioctl)
+#define NCP_IOC_SETPRIVATEDATA_32 _IOR('n', 10, struct compat_ncp_privatedata_ioctl)
+
+static int
+ncp_get_compat_fs_info_v2(struct ncp_server * server, struct file *file,
+ struct compat_ncp_fs_info_v2 __user * arg)
+{
+ struct inode *inode = file->f_dentry->d_inode;
+ struct compat_ncp_fs_info_v2 info2;
+
+ if ((file_permission(file, MAY_WRITE) != 0)
+ && (current->uid != server->m.mounted_uid)) {
+ return -EACCES;
+ }
+ if (copy_from_user(&info2, arg, sizeof(info2)))
+ return -EFAULT;
+
+ if (info2.version != NCP_GET_FS_INFO_VERSION_V2) {
+ DPRINTK("info.version invalid: %d\n", info2.version);
+ return -EINVAL;
+ }
+ info2.mounted_uid = server->m.mounted_uid;
+ info2.connection = server->connection;
+ info2.buffer_size = server->buffer_size;
+ info2.volume_number = NCP_FINFO(inode)->volNumber;
+ info2.directory_id = NCP_FINFO(inode)->DosDirNum;
+ info2.dummy1 = info2.dummy2 = info2.dummy3 = 0;
+
+ if (copy_to_user(arg, &info2, sizeof(info2)))
+ return -EFAULT;
+ return 0;
+}
+#endif
+
+#define NCP_IOC_GETMOUNTUID16 _IOW('n', 2, u16)
+#define NCP_IOC_GETMOUNTUID32 _IOW('n', 2, u32)
+#define NCP_IOC_GETMOUNTUID64 _IOW('n', 2, u64)
+
#ifdef CONFIG_NCPFS_NLS
/* Here we are select the iocharset and the codepage for NLS.
* Thanks Petr Vandrovec for idea and many hints.
@@ -192,12 +270,24 @@ int ncp_ioctl(struct inode *inode, struct file *filp,
void __user *argp = (void __user *)arg;
switch (cmd) {
+#ifdef CONFIG_COMPAT
+ case NCP_IOC_NCPREQUEST_32:
+#endif
case NCP_IOC_NCPREQUEST:
-
if ((file_permission(filp, MAY_WRITE) != 0)
&& (current->uid != server->m.mounted_uid)) {
return -EACCES;
}
+#ifdef CONFIG_COMPAT
+ if (cmd == NCP_IOC_NCPREQUEST_32) {
+ struct compat_ncp_ioctl_request request32;
+ if (copy_from_user(&request32, argp, sizeof(request32)))
+ return -EFAULT;
+ request.function = request32.function;
+ request.size = request32.size;
+ request.data = compat_ptr(request32.data);
+ } else
+#endif
if (copy_from_user(&request, argp, sizeof(request)))
return -EFAULT;
@@ -254,19 +344,35 @@ int ncp_ioctl(struct inode *inode, struct file *filp,
case NCP_IOC_GET_FS_INFO_V2:
return ncp_get_fs_info_v2(server, filp, argp);
- case NCP_IOC_GETMOUNTUID2:
- {
- unsigned long tmp = server->m.mounted_uid;
-
- if ((file_permission(filp, MAY_READ) != 0)
- && (current->uid != server->m.mounted_uid))
- {
- return -EACCES;
- }
- if (put_user(tmp, (unsigned long __user *)argp))
+#ifdef CONFIG_COMPAT
+ case NCP_IOC_GET_FS_INFO_V2_32:
+ return ncp_get_compat_fs_info_v2(server, filp, argp);
+#endif
+ /* we have too many combinations of CONFIG_COMPAT,
+ * CONFIG_64BIT and CONFIG_UID16, so just handle
+ * any of the possible ioctls */
+ case NCP_IOC_GETMOUNTUID16:
+ case NCP_IOC_GETMOUNTUID32:
+ case NCP_IOC_GETMOUNTUID64:
+ if ((file_permission(filp, MAY_READ) != 0)
+ && (current->uid != server->m.mounted_uid)) {
+ return -EACCES;
+ }
+ if (cmd == NCP_IOC_GETMOUNTUID16) {
+ u16 uid;
+ SET_UID(uid, server->m.mounted_uid);
+ if (put_user(uid, (u16 __user *)argp))
+ return -EFAULT;
+ } else if (cmd == NCP_IOC_GETMOUNTUID32) {
+ if (put_user(server->m.mounted_uid,
+ (u32 __user *)argp))
+ return -EFAULT;
+ } else {
+ if (put_user(server->m.mounted_uid,
+ (u64 __user *)argp))
return -EFAULT;
- return 0;
}
+ return 0;
case NCP_IOC_GETROOT:
{
@@ -476,6 +582,32 @@ outrel:
}
#endif /* CONFIG_NCPFS_IOCTL_LOCKING */
+#ifdef CONFIG_COMPAT
+ case NCP_IOC_GETOBJECTNAME_32:
+ if (current->uid != server->m.mounted_uid) {
+ return -EACCES;
+ }
+ {
+ struct compat_ncp_objectname_ioctl user;
+ size_t outl;
+
+ if (copy_from_user(&user, argp, sizeof(user)))
+ return -EFAULT;
+ user.auth_type = server->auth.auth_type;
+ outl = user.object_name_len;
+ user.object_name_len = server->auth.object_name_len;
+ if (outl > user.object_name_len)
+ outl = user.object_name_len;
+ if (outl) {
+ if (copy_to_user(compat_ptr(user.object_name),
+ server->auth.object_name,
+ outl)) return -EFAULT;
+ }
+ if (copy_to_user(argp, &user, sizeof(user)))
+ return -EFAULT;
+ return 0;
+ }
+#endif
case NCP_IOC_GETOBJECTNAME:
if (current->uid != server->m.mounted_uid) {
return -EACCES;
@@ -500,6 +632,9 @@ outrel:
return -EFAULT;
return 0;
}
+#ifdef CONFIG_COMPAT
+ case NCP_IOC_SETOBJECTNAME_32:
+#endif
case NCP_IOC_SETOBJECTNAME:
if (current->uid != server->m.mounted_uid) {
return -EACCES;
@@ -512,8 +647,19 @@ outrel:
void* oldprivate;
size_t oldprivatelen;
+#ifdef CONFIG_COMPAT
+ if (cmd == NCP_IOC_SETOBJECTNAME_32) {
+ struct compat_ncp_objectname_ioctl user32;
+ if (copy_from_user(&user32, argp, sizeof(user32)))
+ return -EFAULT;
+ user.auth_type = user32.auth_type;
+ user.object_name_len = user32.object_name_len;
+ user.object_name = compat_ptr(user32.object_name);
+ } else
+#endif
if (copy_from_user(&user, argp, sizeof(user)))
return -EFAULT;
+
if (user.object_name_len > NCP_OBJECT_NAME_MAX_LEN)
return -ENOMEM;
if (user.object_name_len) {
@@ -544,6 +690,9 @@ outrel:
kfree(oldname);
return 0;
}
+#ifdef CONFIG_COMPAT
+ case NCP_IOC_GETPRIVATEDATA_32:
+#endif
case NCP_IOC_GETPRIVATEDATA:
if (current->uid != server->m.mounted_uid) {
return -EACCES;
@@ -552,8 +701,18 @@ outrel:
struct ncp_privatedata_ioctl user;
size_t outl;
+#ifdef CONFIG_COMPAT
+ if (cmd == NCP_IOC_GETPRIVATEDATA_32) {
+ struct compat_ncp_privatedata_ioctl user32;
+ if (copy_from_user(&user32, argp, sizeof(user32)))
+ return -EFAULT;
+ user.len = user32.len;
+ user.data = compat_ptr(user32.data);
+ } else
+#endif
if (copy_from_user(&user, argp, sizeof(user)))
return -EFAULT;
+
outl = user.len;
user.len = server->priv.len;
if (outl > user.len) outl = user.len;
@@ -562,10 +721,23 @@ outrel:
server->priv.data,
outl)) return -EFAULT;
}
+#ifdef CONFIG_COMPAT
+ if (cmd == NCP_IOC_GETPRIVATEDATA_32) {
+ struct compat_ncp_privatedata_ioctl user32;
+ user32.len = user.len;
+ user32.data = (unsigned long) user.data;
+ if (copy_to_user(&user32, argp, sizeof(user32)))
+ return -EFAULT;
+ } else
+#endif
if (copy_to_user(argp, &user, sizeof(user)))
return -EFAULT;
+
return 0;
}
+#ifdef CONFIG_COMPAT
+ case NCP_IOC_SETPRIVATEDATA_32:
+#endif
case NCP_IOC_SETPRIVATEDATA:
if (current->uid != server->m.mounted_uid) {
return -EACCES;
@@ -576,8 +748,18 @@ outrel:
void* old;
size_t oldlen;
+#ifdef CONFIG_COMPAT
+ if (cmd == NCP_IOC_SETPRIVATEDATA_32) {
+ struct compat_ncp_privatedata_ioctl user32;
+ if (copy_from_user(&user32, argp, sizeof(user32)))
+ return -EFAULT;
+ user.len = user32.len;
+ user.data = compat_ptr(user32.data);
+ } else
+#endif
if (copy_from_user(&user, argp, sizeof(user)))
return -EFAULT;
+
if (user.len > NCP_PRIVATE_DATA_MAX_LEN)
return -ENOMEM;
if (user.len) {
@@ -636,20 +818,19 @@ outrel:
}
}
-/* #ifdef CONFIG_UID16 */
- /* NCP_IOC_GETMOUNTUID may be same as NCP_IOC_GETMOUNTUID2,
- so we have this out of switch */
- if (cmd == NCP_IOC_GETMOUNTUID) {
- __kernel_uid_t uid = 0;
- if ((file_permission(filp, MAY_READ) != 0)
- && (current->uid != server->m.mounted_uid)) {
- return -EACCES;
- }
- SET_UID(uid, server->m.mounted_uid);
- if (put_user(uid, (__kernel_uid_t __user *)argp))
- return -EFAULT;
- return 0;
- }
-/* #endif */
return -EINVAL;
}
+
+#ifdef CONFIG_COMPAT
+long ncp_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+{
+ struct inode *inode = file->f_dentry->d_inode;
+ int ret;
+
+ lock_kernel();
+ arg = (unsigned long) compat_ptr(arg);
+ ret = ncp_ioctl(inode, file, cmd, arg);
+ unlock_kernel();
+ return ret;
+}
+#endif
diff --git a/fs/nfs/callback.c b/fs/nfs/callback.c
index a3ee11364db0..7933e2e99dbc 100644
--- a/fs/nfs/callback.c
+++ b/fs/nfs/callback.c
@@ -58,7 +58,6 @@ module_param_call(callback_tcpport, param_set_port, param_get_int,
*/
static void nfs_callback_svc(struct svc_rqst *rqstp)
{
- struct svc_serv *serv = rqstp->rq_server;
int err;
__module_get(THIS_MODULE);
@@ -80,7 +79,7 @@ static void nfs_callback_svc(struct svc_rqst *rqstp)
/*
* Listen for a request on the socket
*/
- err = svc_recv(serv, rqstp, MAX_SCHEDULE_TIMEOUT);
+ err = svc_recv(rqstp, MAX_SCHEDULE_TIMEOUT);
if (err == -EAGAIN || err == -EINTR)
continue;
if (err < 0) {
@@ -91,7 +90,7 @@ static void nfs_callback_svc(struct svc_rqst *rqstp)
}
dprintk("%s: request from %u.%u.%u.%u\n", __FUNCTION__,
NIPQUAD(rqstp->rq_addr.sin_addr.s_addr));
- svc_process(serv, rqstp);
+ svc_process(rqstp);
}
svc_exit_thread(rqstp);
@@ -116,7 +115,7 @@ int nfs_callback_up(void)
goto out;
init_completion(&nfs_callback_info.started);
init_completion(&nfs_callback_info.stopped);
- serv = svc_create(&nfs4_callback_program, NFS4_CALLBACK_BUFSIZE);
+ serv = svc_create(&nfs4_callback_program, NFS4_CALLBACK_BUFSIZE, NULL);
ret = -ENOMEM;
if (!serv)
goto out_err;
diff --git a/fs/nfs/client.c b/fs/nfs/client.c
index ec1938d4b814..8106f3b29e4a 100644
--- a/fs/nfs/client.c
+++ b/fs/nfs/client.c
@@ -460,7 +460,8 @@ static int nfs_start_lockd(struct nfs_server *server)
goto out;
if (server->flags & NFS_MOUNT_NONLM)
goto out;
- error = lockd_up();
+ error = lockd_up((server->flags & NFS_MOUNT_TCP) ?
+ IPPROTO_TCP : IPPROTO_UDP);
if (error < 0)
server->flags |= NFS_MOUNT_NONLM;
else
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c
index 7432f1a43f3d..481f8892a919 100644
--- a/fs/nfs/dir.c
+++ b/fs/nfs/dir.c
@@ -843,7 +843,7 @@ static void nfs_dentry_iput(struct dentry *dentry, struct inode *inode)
nfs_inode_return_delegation(inode);
if (dentry->d_flags & DCACHE_NFSFS_RENAMED) {
lock_kernel();
- inode->i_nlink--;
+ drop_nlink(inode);
nfs_complete_unlink(dentry);
unlock_kernel();
}
@@ -1286,7 +1286,7 @@ static int nfs_rmdir(struct inode *dir, struct dentry *dentry)
error = NFS_PROTO(dir)->rmdir(dir, &dentry->d_name);
/* Ensure the VFS deletes this inode */
if (error == 0 && dentry->d_inode != NULL)
- dentry->d_inode->i_nlink = 0;
+ clear_nlink(dentry->d_inode);
nfs_end_data_update(dir);
unlock_kernel();
@@ -1401,7 +1401,7 @@ static int nfs_safe_remove(struct dentry *dentry)
error = NFS_PROTO(dir)->remove(dir, &dentry->d_name);
/* The VFS may want to delete this inode */
if (error == 0)
- inode->i_nlink--;
+ drop_nlink(inode);
nfs_mark_for_revalidate(inode);
nfs_end_data_update(inode);
} else
@@ -1639,7 +1639,7 @@ static int nfs_rename(struct inode *old_dir, struct dentry *old_dentry,
goto out;
}
} else
- new_inode->i_nlink--;
+ drop_nlink(new_inode);
go_ahead:
/*
diff --git a/fs/nfs/direct.c b/fs/nfs/direct.c
index 377839bed172..9f7f8b9ea1e2 100644
--- a/fs/nfs/direct.c
+++ b/fs/nfs/direct.c
@@ -707,8 +707,8 @@ static ssize_t nfs_direct_write(struct kiocb *iocb, unsigned long user_addr, siz
/**
* nfs_file_direct_read - file direct read operation for NFS files
* @iocb: target I/O control block
- * @buf: user's buffer into which to read data
- * @count: number of bytes to read
+ * @iov: vector of user buffers into which to read data
+ * @nr_segs: size of iov vector
* @pos: byte offset in file where reading starts
*
* We use this function for direct reads instead of calling
@@ -725,17 +725,24 @@ static ssize_t nfs_direct_write(struct kiocb *iocb, unsigned long user_addr, siz
* client must read the updated atime from the server back into its
* cache.
*/
-ssize_t nfs_file_direct_read(struct kiocb *iocb, char __user *buf, size_t count, loff_t pos)
+ssize_t nfs_file_direct_read(struct kiocb *iocb, const struct iovec *iov,
+ unsigned long nr_segs, loff_t pos)
{
ssize_t retval = -EINVAL;
struct file *file = iocb->ki_filp;
struct address_space *mapping = file->f_mapping;
+ /* XXX: temporary */
+ const char __user *buf = iov[0].iov_base;
+ size_t count = iov[0].iov_len;
dprintk("nfs: direct read(%s/%s, %lu@%Ld)\n",
file->f_dentry->d_parent->d_name.name,
file->f_dentry->d_name.name,
(unsigned long) count, (long long) pos);
+ if (nr_segs != 1)
+ return -EINVAL;
+
if (count < 0)
goto out;
retval = -EFAULT;
@@ -760,8 +767,8 @@ out:
/**
* nfs_file_direct_write - file direct write operation for NFS files
* @iocb: target I/O control block
- * @buf: user's buffer from which to write data
- * @count: number of bytes to write
+ * @iov: vector of user buffers from which to write data
+ * @nr_segs: size of iov vector
* @pos: byte offset in file where writing starts
*
* We use this function for direct writes instead of calling
@@ -782,17 +789,24 @@ out:
* Note that O_APPEND is not supported for NFS direct writes, as there
* is no atomic O_APPEND write facility in the NFS protocol.
*/
-ssize_t nfs_file_direct_write(struct kiocb *iocb, const char __user *buf, size_t count, loff_t pos)
+ssize_t nfs_file_direct_write(struct kiocb *iocb, const struct iovec *iov,
+ unsigned long nr_segs, loff_t pos)
{
ssize_t retval;
struct file *file = iocb->ki_filp;
struct address_space *mapping = file->f_mapping;
+ /* XXX: temporary */
+ const char __user *buf = iov[0].iov_base;
+ size_t count = iov[0].iov_len;
dfprintk(VFS, "nfs: direct write(%s/%s, %lu@%Ld)\n",
file->f_dentry->d_parent->d_name.name,
file->f_dentry->d_name.name,
(unsigned long) count, (long long) pos);
+ if (nr_segs != 1)
+ return -EINVAL;
+
retval = generic_write_checks(file, &pos, &count, 0);
if (retval)
goto out;
diff --git a/fs/nfs/file.c b/fs/nfs/file.c
index be997d649127..cc93865cea93 100644
--- a/fs/nfs/file.c
+++ b/fs/nfs/file.c
@@ -41,8 +41,10 @@ static int nfs_file_release(struct inode *, struct file *);
static loff_t nfs_file_llseek(struct file *file, loff_t offset, int origin);
static int nfs_file_mmap(struct file *, struct vm_area_struct *);
static ssize_t nfs_file_sendfile(struct file *, loff_t *, size_t, read_actor_t, void *);
-static ssize_t nfs_file_read(struct kiocb *, char __user *, size_t, loff_t);
-static ssize_t nfs_file_write(struct kiocb *, const char __user *, size_t, loff_t);
+static ssize_t nfs_file_read(struct kiocb *, const struct iovec *iov,
+ unsigned long nr_segs, loff_t pos);
+static ssize_t nfs_file_write(struct kiocb *, const struct iovec *iov,
+ unsigned long nr_segs, loff_t pos);
static int nfs_file_flush(struct file *, fl_owner_t id);
static int nfs_fsync(struct file *, struct dentry *dentry, int datasync);
static int nfs_check_flags(int flags);
@@ -53,8 +55,8 @@ const struct file_operations nfs_file_operations = {
.llseek = nfs_file_llseek,
.read = do_sync_read,
.write = do_sync_write,
- .aio_read = nfs_file_read,
- .aio_write = nfs_file_write,
+ .aio_read = nfs_file_read,
+ .aio_write = nfs_file_write,
.mmap = nfs_file_mmap,
.open = nfs_file_open,
.flush = nfs_file_flush,
@@ -196,15 +198,17 @@ nfs_file_flush(struct file *file, fl_owner_t id)
}
static ssize_t
-nfs_file_read(struct kiocb *iocb, char __user * buf, size_t count, loff_t pos)
+nfs_file_read(struct kiocb *iocb, const struct iovec *iov,
+ unsigned long nr_segs, loff_t pos)
{
struct dentry * dentry = iocb->ki_filp->f_dentry;
struct inode * inode = dentry->d_inode;
ssize_t result;
+ size_t count = iov_length(iov, nr_segs);
#ifdef CONFIG_NFS_DIRECTIO
if (iocb->ki_filp->f_flags & O_DIRECT)
- return nfs_file_direct_read(iocb, buf, count, pos);
+ return nfs_file_direct_read(iocb, iov, nr_segs, pos);
#endif
dfprintk(VFS, "nfs: read(%s/%s, %lu@%lu)\n",
@@ -214,7 +218,7 @@ nfs_file_read(struct kiocb *iocb, char __user * buf, size_t count, loff_t pos)
result = nfs_revalidate_mapping(inode, iocb->ki_filp->f_mapping);
nfs_add_stats(inode, NFSIOS_NORMALREADBYTES, count);
if (!result)
- result = generic_file_aio_read(iocb, buf, count, pos);
+ result = generic_file_aio_read(iocb, iov, nr_segs, pos);
return result;
}
@@ -336,24 +340,22 @@ const struct address_space_operations nfs_file_aops = {
#endif
};
-/*
- * Write to a file (through the page cache).
- */
-static ssize_t
-nfs_file_write(struct kiocb *iocb, const char __user *buf, size_t count, loff_t pos)
+static ssize_t nfs_file_write(struct kiocb *iocb, const struct iovec *iov,
+ unsigned long nr_segs, loff_t pos)
{
struct dentry * dentry = iocb->ki_filp->f_dentry;
struct inode * inode = dentry->d_inode;
ssize_t result;
+ size_t count = iov_length(iov, nr_segs);
#ifdef CONFIG_NFS_DIRECTIO
if (iocb->ki_filp->f_flags & O_DIRECT)
- return nfs_file_direct_write(iocb, buf, count, pos);
+ return nfs_file_direct_write(iocb, iov, nr_segs, pos);
#endif
- dfprintk(VFS, "nfs: write(%s/%s(%ld), %lu@%lu)\n",
+ dfprintk(VFS, "nfs: write(%s/%s(%ld), %lu@%Ld)\n",
dentry->d_parent->d_name.name, dentry->d_name.name,
- inode->i_ino, (unsigned long) count, (unsigned long) pos);
+ inode->i_ino, (unsigned long) count, (long long) pos);
result = -EBUSY;
if (IS_SWAPFILE(inode))
@@ -372,7 +374,7 @@ nfs_file_write(struct kiocb *iocb, const char __user *buf, size_t count, loff_t
goto out;
nfs_add_stats(inode, NFSIOS_NORMALWRITTENBYTES, count);
- result = generic_file_aio_write(iocb, buf, count, pos);
+ result = generic_file_aio_write(iocb, iov, nr_segs, pos);
out:
return result;
diff --git a/fs/nfs/nfsroot.c b/fs/nfs/nfsroot.c
index c0a754ecdee6..1d656a645199 100644
--- a/fs/nfs/nfsroot.c
+++ b/fs/nfs/nfsroot.c
@@ -312,7 +312,7 @@ static int __init root_nfs_name(char *name)
/* Override them by options set on kernel command-line */
root_nfs_parse(name, buf);
- cp = system_utsname.nodename;
+ cp = utsname()->nodename;
if (strlen(buf) + strlen(cp) > NFS_MAXPATHLEN) {
printk(KERN_ERR "Root-NFS: Pathname for remote directory too long.\n");
return -1;
diff --git a/fs/nfs/write.c b/fs/nfs/write.c
index b674462793d3..f6675d2c386c 100644
--- a/fs/nfs/write.c
+++ b/fs/nfs/write.c
@@ -51,7 +51,6 @@
#include <linux/mm.h>
#include <linux/pagemap.h>
#include <linux/file.h>
-#include <linux/mpage.h>
#include <linux/writeback.h>
#include <linux/sunrpc/clnt.h>
diff --git a/fs/nfsd/export.c b/fs/nfsd/export.c
index 01bc68c628ad..cfe141e5d759 100644
--- a/fs/nfsd/export.c
+++ b/fs/nfsd/export.c
@@ -370,7 +370,7 @@ static int check_export(struct inode *inode, int flags)
*/
if (!(inode->i_sb->s_type->fs_flags & FS_REQUIRES_DEV) &&
!(flags & NFSEXP_FSID)) {
- dprintk("exp_export: export of non-dev fs without fsid");
+ dprintk("exp_export: export of non-dev fs without fsid\n");
return -EINVAL;
}
if (!inode->i_sb->s_export_op) {
@@ -1078,6 +1078,7 @@ exp_pseudoroot(struct auth_domain *clp, struct svc_fh *fhp,
/* Iterator */
static void *e_start(struct seq_file *m, loff_t *pos)
+ __acquires(svc_export_cache.hash_lock)
{
loff_t n = *pos;
unsigned hash, export;
@@ -1086,7 +1087,7 @@ static void *e_start(struct seq_file *m, loff_t *pos)
exp_readlock();
read_lock(&svc_export_cache.hash_lock);
if (!n--)
- return (void *)1;
+ return SEQ_START_TOKEN;
hash = n >> 32;
export = n & ((1LL<<32) - 1);
@@ -1110,7 +1111,7 @@ static void *e_next(struct seq_file *m, void *p, loff_t *pos)
struct cache_head *ch = p;
int hash = (*pos >> 32);
- if (p == (void *)1)
+ if (p == SEQ_START_TOKEN)
hash = 0;
else if (ch->next == NULL) {
hash++;
@@ -1131,6 +1132,7 @@ static void *e_next(struct seq_file *m, void *p, loff_t *pos)
}
static void e_stop(struct seq_file *m, void *p)
+ __releases(svc_export_cache.hash_lock)
{
read_unlock(&svc_export_cache.hash_lock);
exp_readunlock();
@@ -1178,15 +1180,13 @@ static int e_show(struct seq_file *m, void *p)
{
struct cache_head *cp = p;
struct svc_export *exp = container_of(cp, struct svc_export, h);
- svc_client *clp;
- if (p == (void *)1) {
+ if (p == SEQ_START_TOKEN) {
seq_puts(m, "# Version 1.1\n");
seq_puts(m, "# Path Client(Flags) # IPs\n");
return 0;
}
- clp = exp->ex_client;
cache_get(&exp->h);
if (cache_check(&svc_export_cache, &exp->h, NULL))
return 0;
diff --git a/fs/nfsd/nfs4callback.c b/fs/nfsd/nfs4callback.c
index 8583d99ee740..f6ca9fb3fc63 100644
--- a/fs/nfsd/nfs4callback.c
+++ b/fs/nfsd/nfs4callback.c
@@ -131,7 +131,7 @@ xdr_error: \
#define READ_BUF(nbytes) do { \
p = xdr_inline_decode(xdr, nbytes); \
if (!p) { \
- dprintk("NFSD: %s: reply buffer overflowed in line %d.", \
+ dprintk("NFSD: %s: reply buffer overflowed in line %d.\n", \
__FUNCTION__, __LINE__); \
return -EIO; \
} \
diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c
index ee4eff27aedc..15ded7a30a72 100644
--- a/fs/nfsd/nfs4proc.c
+++ b/fs/nfsd/nfs4proc.c
@@ -600,7 +600,7 @@ nfsd4_setattr(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_se
&setattr->sa_stateid, CHECK_FH | WR_STATE, NULL);
nfs4_unlock_state();
if (status) {
- dprintk("NFSD: nfsd4_setattr: couldn't process stateid!");
+ dprintk("NFSD: nfsd4_setattr: couldn't process stateid!\n");
return status;
}
}
diff --git a/fs/nfsd/nfs4recover.c b/fs/nfsd/nfs4recover.c
index e35d7e52fdeb..1cbd2e4ee122 100644
--- a/fs/nfsd/nfs4recover.c
+++ b/fs/nfsd/nfs4recover.c
@@ -184,7 +184,7 @@ struct dentry_list_arg {
static int
nfsd4_build_dentrylist(void *arg, const char *name, int namlen,
- loff_t offset, ino_t ino, unsigned int d_type)
+ loff_t offset, u64 ino, unsigned int d_type)
{
struct dentry_list_arg *dla = arg;
struct list_head *dentries = &dla->dentries;
diff --git a/fs/nfsd/nfsctl.c b/fs/nfsd/nfsctl.c
index 7046ac9cf97f..5c6a477c20ec 100644
--- a/fs/nfsd/nfsctl.c
+++ b/fs/nfsd/nfsctl.c
@@ -23,10 +23,14 @@
#include <linux/pagemap.h>
#include <linux/init.h>
#include <linux/string.h>
+#include <linux/smp_lock.h>
+#include <linux/ctype.h>
#include <linux/nfs.h>
#include <linux/nfsd_idmap.h>
+#include <linux/lockd/bind.h>
#include <linux/sunrpc/svc.h>
+#include <linux/sunrpc/svcsock.h>
#include <linux/nfsd/nfsd.h>
#include <linux/nfsd/cache.h>
#include <linux/nfsd/xdr.h>
@@ -35,8 +39,6 @@
#include <asm/uaccess.h>
-unsigned int nfsd_versbits = ~0;
-
/*
* We have a single directory with 9 nodes in it.
*/
@@ -52,7 +54,9 @@ enum {
NFSD_List,
NFSD_Fh,
NFSD_Threads,
+ NFSD_Pool_Threads,
NFSD_Versions,
+ NFSD_Ports,
/*
* The below MUST come last. Otherwise we leave a hole in nfsd_files[]
* with !CONFIG_NFSD_V4 and simple_fill_super() goes oops
@@ -75,7 +79,9 @@ static ssize_t write_getfd(struct file *file, char *buf, size_t size);
static ssize_t write_getfs(struct file *file, char *buf, size_t size);
static ssize_t write_filehandle(struct file *file, char *buf, size_t size);
static ssize_t write_threads(struct file *file, char *buf, size_t size);
+static ssize_t write_pool_threads(struct file *file, char *buf, size_t size);
static ssize_t write_versions(struct file *file, char *buf, size_t size);
+static ssize_t write_ports(struct file *file, char *buf, size_t size);
#ifdef CONFIG_NFSD_V4
static ssize_t write_leasetime(struct file *file, char *buf, size_t size);
static ssize_t write_recoverydir(struct file *file, char *buf, size_t size);
@@ -91,7 +97,9 @@ static ssize_t (*write_op[])(struct file *, char *, size_t) = {
[NFSD_Getfs] = write_getfs,
[NFSD_Fh] = write_filehandle,
[NFSD_Threads] = write_threads,
+ [NFSD_Pool_Threads] = write_pool_threads,
[NFSD_Versions] = write_versions,
+ [NFSD_Ports] = write_ports,
#ifdef CONFIG_NFSD_V4
[NFSD_Leasetime] = write_leasetime,
[NFSD_RecoveryDir] = write_recoverydir,
@@ -358,6 +366,72 @@ static ssize_t write_threads(struct file *file, char *buf, size_t size)
return strlen(buf);
}
+extern int nfsd_nrpools(void);
+extern int nfsd_get_nrthreads(int n, int *);
+extern int nfsd_set_nrthreads(int n, int *);
+
+static ssize_t write_pool_threads(struct file *file, char *buf, size_t size)
+{
+ /* if size > 0, look for an array of number of threads per node
+ * and apply them then write out number of threads per node as reply
+ */
+ char *mesg = buf;
+ int i;
+ int rv;
+ int len;
+ int npools = nfsd_nrpools();
+ int *nthreads;
+
+ if (npools == 0) {
+ /*
+ * NFS is shut down. The admin can start it by
+ * writing to the threads file but NOT the pool_threads
+ * file, sorry. Report zero threads.
+ */
+ strcpy(buf, "0\n");
+ return strlen(buf);
+ }
+
+ nthreads = kcalloc(npools, sizeof(int), GFP_KERNEL);
+ if (nthreads == NULL)
+ return -ENOMEM;
+
+ if (size > 0) {
+ for (i = 0; i < npools; i++) {
+ rv = get_int(&mesg, &nthreads[i]);
+ if (rv == -ENOENT)
+ break; /* fewer numbers than pools */
+ if (rv)
+ goto out_free; /* syntax error */
+ rv = -EINVAL;
+ if (nthreads[i] < 0)
+ goto out_free;
+ }
+ rv = nfsd_set_nrthreads(i, nthreads);
+ if (rv)
+ goto out_free;
+ }
+
+ rv = nfsd_get_nrthreads(npools, nthreads);
+ if (rv)
+ goto out_free;
+
+ mesg = buf;
+ size = SIMPLE_TRANSACTION_LIMIT;
+ for (i = 0; i < npools && size > 0; i++) {
+ snprintf(mesg, size, "%d%c", nthreads[i], (i == npools-1 ? '\n' : ' '));
+ len = strlen(mesg);
+ size -= len;
+ mesg += len;
+ }
+
+ return (mesg-buf);
+
+out_free:
+ kfree(nthreads);
+ return rv;
+}
+
static ssize_t write_versions(struct file *file, char *buf, size_t size)
{
/*
@@ -372,6 +446,10 @@ static ssize_t write_versions(struct file *file, char *buf, size_t size)
if (size>0) {
if (nfsd_serv)
+ /* Cannot change versions without updating
+ * nfsd_serv->sv_xdrsize, and reallocing
+ * rq_argp and rq_resp
+ */
return -EBUSY;
if (buf[size-1] != '\n')
return -EINVAL;
@@ -390,10 +468,7 @@ static ssize_t write_versions(struct file *file, char *buf, size_t size)
case 2:
case 3:
case 4:
- if (sign != '-')
- NFSCTL_VERSET(nfsd_versbits, num);
- else
- NFSCTL_VERUNSET(nfsd_versbits, num);
+ nfsd_vers(num, sign == '-' ? NFSD_CLEAR : NFSD_SET);
break;
default:
return -EINVAL;
@@ -404,16 +479,15 @@ static ssize_t write_versions(struct file *file, char *buf, size_t size)
/* If all get turned off, turn them back on, as
* having no versions is BAD
*/
- if ((nfsd_versbits & NFSCTL_VERALL)==0)
- nfsd_versbits = NFSCTL_VERALL;
+ nfsd_reset_versions();
}
/* Now write current state into reply buffer */
len = 0;
sep = "";
for (num=2 ; num <= 4 ; num++)
- if (NFSCTL_VERISSET(NFSCTL_VERALL, num)) {
+ if (nfsd_vers(num, NFSD_AVAIL)) {
len += sprintf(buf+len, "%s%c%d", sep,
- NFSCTL_VERISSET(nfsd_versbits, num)?'+':'-',
+ nfsd_vers(num, NFSD_TEST)?'+':'-',
num);
sep = " ";
}
@@ -421,6 +495,62 @@ static ssize_t write_versions(struct file *file, char *buf, size_t size)
return len;
}
+static ssize_t write_ports(struct file *file, char *buf, size_t size)
+{
+ if (size == 0) {
+ int len = 0;
+ lock_kernel();
+ if (nfsd_serv)
+ len = svc_sock_names(buf, nfsd_serv, NULL);
+ unlock_kernel();
+ return len;
+ }
+ /* Either a single 'fd' number is written, in which
+ * case it must be for a socket of a supported family/protocol,
+ * and we use it as an nfsd socket, or
+ * A '-' followed by the 'name' of a socket in which case
+ * we close the socket.
+ */
+ if (isdigit(buf[0])) {
+ char *mesg = buf;
+ int fd;
+ int err;
+ err = get_int(&mesg, &fd);
+ if (err)
+ return -EINVAL;
+ if (fd < 0)
+ return -EINVAL;
+ err = nfsd_create_serv();
+ if (!err) {
+ int proto = 0;
+ err = lockd_up(proto);
+ if (!err) {
+ err = svc_addsock(nfsd_serv, fd, buf, &proto);
+ if (err)
+ lockd_down();
+ }
+ /* Decrease the count, but don't shutdown the
+ * the service
+ */
+ nfsd_serv->sv_nrthreads--;
+ }
+ return err;
+ }
+ if (buf[0] == '-') {
+ char *toclose = kstrdup(buf+1, GFP_KERNEL);
+ int len = 0;
+ if (!toclose)
+ return -ENOMEM;
+ lock_kernel();
+ if (nfsd_serv)
+ len = svc_sock_names(buf, nfsd_serv, toclose);
+ unlock_kernel();
+ kfree(toclose);
+ return len;
+ }
+ return -EINVAL;
+}
+
#ifdef CONFIG_NFSD_V4
extern time_t nfs4_leasetime(void);
@@ -483,7 +613,9 @@ static int nfsd_fill_super(struct super_block * sb, void * data, int silent)
[NFSD_List] = {"exports", &exports_operations, S_IRUGO},
[NFSD_Fh] = {"filehandle", &transaction_ops, S_IWUSR|S_IRUSR},
[NFSD_Threads] = {"threads", &transaction_ops, S_IWUSR|S_IRUSR},
+ [NFSD_Pool_Threads] = {"pool_threads", &transaction_ops, S_IWUSR|S_IRUSR},
[NFSD_Versions] = {"versions", &transaction_ops, S_IWUSR|S_IRUSR},
+ [NFSD_Ports] = {"portlist", &transaction_ops, S_IWUSR|S_IRUGO},
#ifdef CONFIG_NFSD_V4
[NFSD_Leasetime] = {"nfsv4leasetime", &transaction_ops, S_IWUSR|S_IRUSR},
[NFSD_RecoveryDir] = {"nfsv4recoverydir", &transaction_ops, S_IWUSR|S_IRUSR},
diff --git a/fs/nfsd/nfssvc.c b/fs/nfsd/nfssvc.c
index ec1decf29bab..19443056ec30 100644
--- a/fs/nfsd/nfssvc.c
+++ b/fs/nfsd/nfssvc.c
@@ -57,12 +57,6 @@ static atomic_t nfsd_busy;
static unsigned long nfsd_last_call;
static DEFINE_SPINLOCK(nfsd_call_lock);
-struct nfsd_list {
- struct list_head list;
- struct task_struct *task;
-};
-static struct list_head nfsd_list = LIST_HEAD_INIT(nfsd_list);
-
#if defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL)
static struct svc_stat nfsd_acl_svcstats;
static struct svc_version * nfsd_acl_version[] = {
@@ -117,6 +111,32 @@ struct svc_program nfsd_program = {
};
+int nfsd_vers(int vers, enum vers_op change)
+{
+ if (vers < NFSD_MINVERS || vers >= NFSD_NRVERS)
+ return -1;
+ switch(change) {
+ case NFSD_SET:
+ nfsd_versions[vers] = nfsd_version[vers];
+ break;
+#if defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL)
+ if (vers < NFSD_ACL_NRVERS)
+ nfsd_acl_version[vers] = nfsd_acl_version[vers];
+#endif
+ case NFSD_CLEAR:
+ nfsd_versions[vers] = NULL;
+#if defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL)
+ if (vers < NFSD_ACL_NRVERS)
+ nfsd_acl_version[vers] = NULL;
+#endif
+ break;
+ case NFSD_TEST:
+ return nfsd_versions[vers] != NULL;
+ case NFSD_AVAIL:
+ return nfsd_version[vers] != NULL;
+ }
+ return 0;
+}
/*
* Maximum number of nfsd processes
*/
@@ -130,16 +150,175 @@ int nfsd_nrthreads(void)
return nfsd_serv->sv_nrthreads;
}
+static int killsig; /* signal that was used to kill last nfsd */
+static void nfsd_last_thread(struct svc_serv *serv)
+{
+ /* When last nfsd thread exits we need to do some clean-up */
+ struct svc_sock *svsk;
+ list_for_each_entry(svsk, &serv->sv_permsocks, sk_list)
+ lockd_down();
+ nfsd_serv = NULL;
+ nfsd_racache_shutdown();
+ nfs4_state_shutdown();
+
+ printk(KERN_WARNING "nfsd: last server has exited\n");
+ if (killsig != SIG_NOCLEAN) {
+ printk(KERN_WARNING "nfsd: unexporting all filesystems\n");
+ nfsd_export_flush();
+ }
+}
+
+void nfsd_reset_versions(void)
+{
+ int found_one = 0;
+ int i;
+
+ for (i = NFSD_MINVERS; i < NFSD_NRVERS; i++) {
+ if (nfsd_program.pg_vers[i])
+ found_one = 1;
+ }
+
+ if (!found_one) {
+ for (i = NFSD_MINVERS; i < NFSD_NRVERS; i++)
+ nfsd_program.pg_vers[i] = nfsd_version[i];
+#if defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL)
+ for (i = NFSD_ACL_MINVERS; i < NFSD_ACL_NRVERS; i++)
+ nfsd_acl_program.pg_vers[i] =
+ nfsd_acl_version[i];
+#endif
+ }
+}
+
+int nfsd_create_serv(void)
+{
+ int err = 0;
+ lock_kernel();
+ if (nfsd_serv) {
+ svc_get(nfsd_serv);
+ unlock_kernel();
+ return 0;
+ }
+
+ atomic_set(&nfsd_busy, 0);
+ nfsd_serv = svc_create_pooled(&nfsd_program, NFSD_BUFSIZE,
+ nfsd_last_thread,
+ nfsd, SIG_NOCLEAN, THIS_MODULE);
+ if (nfsd_serv == NULL)
+ err = -ENOMEM;
+ unlock_kernel();
+ do_gettimeofday(&nfssvc_boot); /* record boot time */
+ return err;
+}
+
+static int nfsd_init_socks(int port)
+{
+ int error;
+ if (!list_empty(&nfsd_serv->sv_permsocks))
+ return 0;
+
+ error = lockd_up(IPPROTO_UDP);
+ if (error >= 0) {
+ error = svc_makesock(nfsd_serv, IPPROTO_UDP, port);
+ if (error < 0)
+ lockd_down();
+ }
+ if (error < 0)
+ return error;
+
+#ifdef CONFIG_NFSD_TCP
+ error = lockd_up(IPPROTO_TCP);
+ if (error >= 0) {
+ error = svc_makesock(nfsd_serv, IPPROTO_TCP, port);
+ if (error < 0)
+ lockd_down();
+ }
+ if (error < 0)
+ return error;
+#endif
+ return 0;
+}
+
+int nfsd_nrpools(void)
+{
+ if (nfsd_serv == NULL)
+ return 0;
+ else
+ return nfsd_serv->sv_nrpools;
+}
+
+int nfsd_get_nrthreads(int n, int *nthreads)
+{
+ int i = 0;
+
+ if (nfsd_serv != NULL) {
+ for (i = 0; i < nfsd_serv->sv_nrpools && i < n; i++)
+ nthreads[i] = nfsd_serv->sv_pools[i].sp_nrthreads;
+ }
+
+ return 0;
+}
+
+int nfsd_set_nrthreads(int n, int *nthreads)
+{
+ int i = 0;
+ int tot = 0;
+ int err = 0;
+
+ if (nfsd_serv == NULL || n <= 0)
+ return 0;
+
+ if (n > nfsd_serv->sv_nrpools)
+ n = nfsd_serv->sv_nrpools;
+
+ /* enforce a global maximum number of threads */
+ tot = 0;
+ for (i = 0; i < n; i++) {
+ if (nthreads[i] > NFSD_MAXSERVS)
+ nthreads[i] = NFSD_MAXSERVS;
+ tot += nthreads[i];
+ }
+ if (tot > NFSD_MAXSERVS) {
+ /* total too large: scale down requested numbers */
+ for (i = 0; i < n && tot > 0; i++) {
+ int new = nthreads[i] * NFSD_MAXSERVS / tot;
+ tot -= (nthreads[i] - new);
+ nthreads[i] = new;
+ }
+ for (i = 0; i < n && tot > 0; i++) {
+ nthreads[i]--;
+ tot--;
+ }
+ }
+
+ /*
+ * There must always be a thread in pool 0; the admin
+ * can't shut down NFS completely using pool_threads.
+ */
+ if (nthreads[0] == 0)
+ nthreads[0] = 1;
+
+ /* apply the new numbers */
+ lock_kernel();
+ svc_get(nfsd_serv);
+ for (i = 0; i < n; i++) {
+ err = svc_set_num_threads(nfsd_serv, &nfsd_serv->sv_pools[i],
+ nthreads[i]);
+ if (err)
+ break;
+ }
+ svc_destroy(nfsd_serv);
+ unlock_kernel();
+
+ return err;
+}
+
int
nfsd_svc(unsigned short port, int nrservs)
{
int error;
- int none_left, found_one, i;
- struct list_head *victim;
lock_kernel();
- dprintk("nfsd: creating service: vers 0x%x\n",
- nfsd_versbits);
+ dprintk("nfsd: creating service\n");
error = -EINVAL;
if (nrservs <= 0)
nrservs = 0;
@@ -153,91 +332,20 @@ nfsd_svc(unsigned short port, int nrservs)
error = nfs4_state_start();
if (error<0)
goto out;
- if (!nfsd_serv) {
- /*
- * Use the nfsd_ctlbits to define which
- * versions that will be advertised.
- * If nfsd_ctlbits doesn't list any version,
- * export them all.
- */
- found_one = 0;
-
- for (i = NFSD_MINVERS; i < NFSD_NRVERS; i++) {
- if (NFSCTL_VERISSET(nfsd_versbits, i)) {
- nfsd_program.pg_vers[i] = nfsd_version[i];
- found_one = 1;
- } else
- nfsd_program.pg_vers[i] = NULL;
- }
- if (!found_one) {
- for (i = NFSD_MINVERS; i < NFSD_NRVERS; i++)
- nfsd_program.pg_vers[i] = nfsd_version[i];
- }
+ nfsd_reset_versions();
+ error = nfsd_create_serv();
-#if defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL)
- found_one = 0;
-
- for (i = NFSD_ACL_MINVERS; i < NFSD_ACL_NRVERS; i++) {
- if (NFSCTL_VERISSET(nfsd_versbits, i)) {
- nfsd_acl_program.pg_vers[i] =
- nfsd_acl_version[i];
- found_one = 1;
- } else
- nfsd_acl_program.pg_vers[i] = NULL;
- }
-
- if (!found_one) {
- for (i = NFSD_ACL_MINVERS; i < NFSD_ACL_NRVERS; i++)
- nfsd_acl_program.pg_vers[i] =
- nfsd_acl_version[i];
- }
-#endif
-
- atomic_set(&nfsd_busy, 0);
- error = -ENOMEM;
- nfsd_serv = svc_create(&nfsd_program, NFSD_BUFSIZE);
- if (nfsd_serv == NULL)
- goto out;
- error = svc_makesock(nfsd_serv, IPPROTO_UDP, port);
- if (error < 0)
- goto failure;
+ if (error)
+ goto out;
+ error = nfsd_init_socks(port);
+ if (error)
+ goto failure;
-#ifdef CONFIG_NFSD_TCP
- error = svc_makesock(nfsd_serv, IPPROTO_TCP, port);
- if (error < 0)
- goto failure;
-#endif
- do_gettimeofday(&nfssvc_boot); /* record boot time */
- } else
- nfsd_serv->sv_nrthreads++;
- nrservs -= (nfsd_serv->sv_nrthreads-1);
- while (nrservs > 0) {
- nrservs--;
- __module_get(THIS_MODULE);
- error = svc_create_thread(nfsd, nfsd_serv);
- if (error < 0) {
- module_put(THIS_MODULE);
- break;
- }
- }
- victim = nfsd_list.next;
- while (nrservs < 0 && victim != &nfsd_list) {
- struct nfsd_list *nl =
- list_entry(victim,struct nfsd_list, list);
- victim = victim->next;
- send_sig(SIG_NOCLEAN, nl->task, 1);
- nrservs++;
- }
+ error = svc_set_num_threads(nfsd_serv, NULL, nrservs);
failure:
- none_left = (nfsd_serv->sv_nrthreads == 1);
svc_destroy(nfsd_serv); /* Release server */
- if (none_left) {
- nfsd_serv = NULL;
- nfsd_racache_shutdown();
- nfs4_state_shutdown();
- }
out:
unlock_kernel();
return error;
@@ -270,10 +378,8 @@ update_thread_usage(int busy_threads)
static void
nfsd(struct svc_rqst *rqstp)
{
- struct svc_serv *serv = rqstp->rq_server;
struct fs_struct *fsp;
int err;
- struct nfsd_list me;
sigset_t shutdown_mask, allowed_mask;
/* Lock module and set up kernel thread */
@@ -297,10 +403,7 @@ nfsd(struct svc_rqst *rqstp)
nfsdstats.th_cnt++;
- lockd_up(); /* start lockd */
-
- me.task = current;
- list_add(&me.list, &nfsd_list);
+ rqstp->rq_task = current;
unlock_kernel();
@@ -322,8 +425,7 @@ nfsd(struct svc_rqst *rqstp)
* Find a socket with data available and call its
* recvfrom routine.
*/
- while ((err = svc_recv(serv, rqstp,
- 60*60*HZ)) == -EAGAIN)
+ while ((err = svc_recv(rqstp, 60*60*HZ)) == -EAGAIN)
;
if (err < 0)
break;
@@ -336,7 +438,7 @@ nfsd(struct svc_rqst *rqstp)
/* Process request with signals blocked. */
sigprocmask(SIG_SETMASK, &allowed_mask, NULL);
- svc_process(serv, rqstp);
+ svc_process(rqstp);
/* Unlock export hash tables */
exp_readunlock();
@@ -353,29 +455,13 @@ nfsd(struct svc_rqst *rqstp)
if (sigismember(&current->pending.signal, signo) &&
!sigismember(&current->blocked, signo))
break;
- err = signo;
+ killsig = signo;
}
- /* Clear signals before calling lockd_down() and svc_exit_thread() */
+ /* Clear signals before calling svc_exit_thread() */
flush_signals(current);
lock_kernel();
- /* Release lockd */
- lockd_down();
-
- /* Check if this is last thread */
- if (serv->sv_nrthreads==1) {
-
- printk(KERN_WARNING "nfsd: last server has exited\n");
- if (err != SIG_NOCLEAN) {
- printk(KERN_WARNING "nfsd: unexporting all filesystems\n");
- nfsd_export_flush();
- }
- nfsd_serv = NULL;
- nfsd_racache_shutdown(); /* release read-ahead cache */
- nfs4_state_shutdown();
- }
- list_del(&me.list);
nfsdstats.th_cnt --;
out:
diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c
index c9e3b5a8fe07..443ebc52e382 100644
--- a/fs/nfsd/vfs.c
+++ b/fs/nfsd/vfs.c
@@ -1114,7 +1114,7 @@ nfsd_create(struct svc_rqst *rqstp, struct svc_fh *fhp,
*/
if (!resfhp->fh_dentry) {
/* called from nfsd_proc_mkdir, or possibly nfsd3_proc_create */
- fh_lock(fhp);
+ fh_lock_nested(fhp, I_MUTEX_PARENT);
dchild = lookup_one_len(fname, dentry, flen);
err = PTR_ERR(dchild);
if (IS_ERR(dchild))
@@ -1240,7 +1240,7 @@ nfsd_create_v3(struct svc_rqst *rqstp, struct svc_fh *fhp,
err = nfserr_notdir;
if(!dirp->i_op || !dirp->i_op->lookup)
goto out;
- fh_lock(fhp);
+ fh_lock_nested(fhp, I_MUTEX_PARENT);
/*
* Compose the response file handle.
@@ -1494,7 +1494,7 @@ nfsd_link(struct svc_rqst *rqstp, struct svc_fh *ffhp,
if (isdotent(name, len))
goto out;
- fh_lock(ffhp);
+ fh_lock_nested(ffhp, I_MUTEX_PARENT);
ddir = ffhp->fh_dentry;
dirp = ddir->d_inode;
@@ -1644,7 +1644,7 @@ nfsd_unlink(struct svc_rqst *rqstp, struct svc_fh *fhp, int type,
if (err)
goto out;
- fh_lock(fhp);
+ fh_lock_nested(fhp, I_MUTEX_PARENT);
dentry = fhp->fh_dentry;
dirp = dentry->d_inode;
diff --git a/fs/nls/nls_base.c b/fs/nls/nls_base.c
index 9de6b495f112..b1317ad5ca18 100644
--- a/fs/nls/nls_base.c
+++ b/fs/nls/nls_base.c
@@ -163,8 +163,6 @@ int register_nls(struct nls_table * nls)
{
struct nls_table ** tmp = &tables;
- if (!nls)
- return -EINVAL;
if (nls->next)
return -EBUSY;
diff --git a/fs/no-block.c b/fs/no-block.c
new file mode 100644
index 000000000000..d269a93d3467
--- /dev/null
+++ b/fs/no-block.c
@@ -0,0 +1,22 @@
+/* no-block.c: implementation of routines required for non-BLOCK configuration
+ *
+ * Copyright (C) 2006 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * 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 <linux/kernel.h>
+#include <linux/fs.h>
+
+static int no_blkdev_open(struct inode * inode, struct file * filp)
+{
+ return -ENODEV;
+}
+
+const struct file_operations def_blk_fops = {
+ .open = no_blkdev_open,
+};
diff --git a/fs/ntfs/aops.c b/fs/ntfs/aops.c
index bc579bfdfbd8..7b2c8f4f6a6f 100644
--- a/fs/ntfs/aops.c
+++ b/fs/ntfs/aops.c
@@ -254,7 +254,7 @@ static int ntfs_read_block(struct page *page)
bh->b_bdev = vol->sb->s_bdev;
/* Is the block within the allowed limits? */
if (iblock < lblock) {
- BOOL is_retry = FALSE;
+ bool is_retry = false;
/* Convert iblock into corresponding vcn and offset. */
vcn = (VCN)iblock << blocksize_bits >>
@@ -292,7 +292,7 @@ lock_retry_remap:
goto handle_hole;
/* If first try and runlist unmapped, map and retry. */
if (!is_retry && lcn == LCN_RL_NOT_MAPPED) {
- is_retry = TRUE;
+ is_retry = true;
/*
* Attempt to map runlist, dropping lock for
* the duration.
@@ -558,7 +558,7 @@ static int ntfs_write_block(struct page *page, struct writeback_control *wbc)
unsigned long flags;
unsigned int blocksize, vcn_ofs;
int err;
- BOOL need_end_writeback;
+ bool need_end_writeback;
unsigned char blocksize_bits;
vi = page->mapping->host;
@@ -626,7 +626,7 @@ static int ntfs_write_block(struct page *page, struct writeback_control *wbc)
rl = NULL;
err = 0;
do {
- BOOL is_retry = FALSE;
+ bool is_retry = false;
if (unlikely(block >= dblock)) {
/*
@@ -768,7 +768,7 @@ lock_retry_remap:
}
/* If first try and runlist unmapped, map and retry. */
if (!is_retry && lcn == LCN_RL_NOT_MAPPED) {
- is_retry = TRUE;
+ is_retry = true;
/*
* Attempt to map runlist, dropping lock for
* the duration.
@@ -874,12 +874,12 @@ lock_retry_remap:
set_page_writeback(page); /* Keeps try_to_free_buffers() away. */
/* Submit the prepared buffers for i/o. */
- need_end_writeback = TRUE;
+ need_end_writeback = true;
do {
struct buffer_head *next = bh->b_this_page;
if (buffer_async_write(bh)) {
submit_bh(WRITE, bh);
- need_end_writeback = FALSE;
+ need_end_writeback = false;
}
bh = next;
} while (bh != head);
@@ -932,7 +932,7 @@ static int ntfs_write_mst_block(struct page *page,
runlist_element *rl;
int i, nr_locked_nis, nr_recs, nr_bhs, max_bhs, bhs_per_rec, err, err2;
unsigned bh_size, rec_size_bits;
- BOOL sync, is_mft, page_is_dirty, rec_is_dirty;
+ bool sync, is_mft, page_is_dirty, rec_is_dirty;
unsigned char bh_size_bits;
ntfs_debug("Entering for inode 0x%lx, attribute type 0x%x, page index "
@@ -975,10 +975,10 @@ static int ntfs_write_mst_block(struct page *page,
rl = NULL;
err = err2 = nr_bhs = nr_recs = nr_locked_nis = 0;
- page_is_dirty = rec_is_dirty = FALSE;
+ page_is_dirty = rec_is_dirty = false;
rec_start_bh = NULL;
do {
- BOOL is_retry = FALSE;
+ bool is_retry = false;
if (likely(block < rec_block)) {
if (unlikely(block >= dblock)) {
@@ -1009,10 +1009,10 @@ static int ntfs_write_mst_block(struct page *page,
}
if (!buffer_dirty(bh)) {
/* Clean records are not written out. */
- rec_is_dirty = FALSE;
+ rec_is_dirty = false;
continue;
}
- rec_is_dirty = TRUE;
+ rec_is_dirty = true;
rec_start_bh = bh;
}
/* Need to map the buffer if it is not mapped already. */
@@ -1053,7 +1053,7 @@ lock_retry_remap:
*/
if (!is_mft && !is_retry &&
lcn == LCN_RL_NOT_MAPPED) {
- is_retry = TRUE;
+ is_retry = true;
/*
* Attempt to map runlist, dropping
* lock for the duration.
@@ -1063,7 +1063,7 @@ lock_retry_remap:
if (likely(!err2))
goto lock_retry_remap;
if (err2 == -ENOMEM)
- page_is_dirty = TRUE;
+ page_is_dirty = true;
lcn = err2;
} else {
err2 = -EIO;
@@ -1145,7 +1145,7 @@ lock_retry_remap:
* means we need to redirty the page before
* returning.
*/
- page_is_dirty = TRUE;
+ page_is_dirty = true;
/*
* Remove the buffers in this mft record from
* the list of buffers to write.
diff --git a/fs/ntfs/aops.h b/fs/ntfs/aops.h
index 325ce261a107..9393f4b1e298 100644
--- a/fs/ntfs/aops.h
+++ b/fs/ntfs/aops.h
@@ -80,7 +80,7 @@ static inline void ntfs_unmap_page(struct page *page)
*
* The unlocked and uptodate page is returned on success or an encoded error
* on failure. Caller has to test for error using the IS_ERR() macro on the
- * return value. If that evaluates to TRUE, the negative error code can be
+ * return value. If that evaluates to 'true', the negative error code can be
* obtained using PTR_ERR() on the return value of ntfs_map_page().
*/
static inline struct page *ntfs_map_page(struct address_space *mapping,
diff --git a/fs/ntfs/attrib.c b/fs/ntfs/attrib.c
index 6708e1d68a9e..9f08e851cfb6 100644
--- a/fs/ntfs/attrib.c
+++ b/fs/ntfs/attrib.c
@@ -67,7 +67,7 @@
* the attribute has zero allocated size, i.e. there simply is no runlist.
*
* WARNING: If @ctx is supplied, regardless of whether success or failure is
- * returned, you need to check IS_ERR(@ctx->mrec) and if TRUE the @ctx
+ * returned, you need to check IS_ERR(@ctx->mrec) and if 'true' the @ctx
* is no longer valid, i.e. you need to either call
* ntfs_attr_reinit_search_ctx() or ntfs_attr_put_search_ctx() on it.
* In that case PTR_ERR(@ctx->mrec) will give you the error code for
@@ -90,7 +90,7 @@ int ntfs_map_runlist_nolock(ntfs_inode *ni, VCN vcn, ntfs_attr_search_ctx *ctx)
runlist_element *rl;
struct page *put_this_page = NULL;
int err = 0;
- BOOL ctx_is_temporary, ctx_needs_reset;
+ bool ctx_is_temporary, ctx_needs_reset;
ntfs_attr_search_ctx old_ctx = { NULL, };
ntfs_debug("Mapping runlist part containing vcn 0x%llx.",
@@ -100,7 +100,7 @@ int ntfs_map_runlist_nolock(ntfs_inode *ni, VCN vcn, ntfs_attr_search_ctx *ctx)
else
base_ni = ni->ext.base_ntfs_ino;
if (!ctx) {
- ctx_is_temporary = ctx_needs_reset = TRUE;
+ ctx_is_temporary = ctx_needs_reset = true;
m = map_mft_record(base_ni);
if (IS_ERR(m))
return PTR_ERR(m);
@@ -115,7 +115,7 @@ int ntfs_map_runlist_nolock(ntfs_inode *ni, VCN vcn, ntfs_attr_search_ctx *ctx)
BUG_ON(IS_ERR(ctx->mrec));
a = ctx->attr;
BUG_ON(!a->non_resident);
- ctx_is_temporary = FALSE;
+ ctx_is_temporary = false;
end_vcn = sle64_to_cpu(a->data.non_resident.highest_vcn);
read_lock_irqsave(&ni->size_lock, flags);
allocated_size_vcn = ni->allocated_size >>
@@ -136,7 +136,7 @@ int ntfs_map_runlist_nolock(ntfs_inode *ni, VCN vcn, ntfs_attr_search_ctx *ctx)
ni->name, ni->name_len) &&
sle64_to_cpu(a->data.non_resident.lowest_vcn)
<= vcn && end_vcn >= vcn))
- ctx_needs_reset = FALSE;
+ ctx_needs_reset = false;
else {
/* Save the old search context. */
old_ctx = *ctx;
@@ -158,7 +158,7 @@ int ntfs_map_runlist_nolock(ntfs_inode *ni, VCN vcn, ntfs_attr_search_ctx *ctx)
* needed attribute extent.
*/
ntfs_attr_reinit_search_ctx(ctx);
- ctx_needs_reset = TRUE;
+ ctx_needs_reset = true;
}
}
if (ctx_needs_reset) {
@@ -336,16 +336,16 @@ int ntfs_map_runlist(ntfs_inode *ni, VCN vcn)
* LCN_EIO Critical error (runlist/file is corrupt, i/o error, etc).
*
* Locking: - The runlist must be locked on entry and is left locked on return.
- * - If @write_locked is FALSE, i.e. the runlist is locked for reading,
+ * - If @write_locked is 'false', i.e. the runlist is locked for reading,
* the lock may be dropped inside the function so you cannot rely on
* the runlist still being the same when this function returns.
*/
LCN ntfs_attr_vcn_to_lcn_nolock(ntfs_inode *ni, const VCN vcn,
- const BOOL write_locked)
+ const bool write_locked)
{
LCN lcn;
unsigned long flags;
- BOOL is_retry = FALSE;
+ bool is_retry = false;
ntfs_debug("Entering for i_ino 0x%lx, vcn 0x%llx, %s_locked.",
ni->mft_no, (unsigned long long)vcn,
@@ -390,7 +390,7 @@ retry_remap:
down_read(&ni->runlist.lock);
}
if (likely(!err)) {
- is_retry = TRUE;
+ is_retry = true;
goto retry_remap;
}
if (err == -ENOENT)
@@ -449,7 +449,7 @@ retry_remap:
* -EIO - Critical error (runlist/file is corrupt, i/o error, etc).
*
* WARNING: If @ctx is supplied, regardless of whether success or failure is
- * returned, you need to check IS_ERR(@ctx->mrec) and if TRUE the @ctx
+ * returned, you need to check IS_ERR(@ctx->mrec) and if 'true' the @ctx
* is no longer valid, i.e. you need to either call
* ntfs_attr_reinit_search_ctx() or ntfs_attr_put_search_ctx() on it.
* In that case PTR_ERR(@ctx->mrec) will give you the error code for
@@ -469,7 +469,7 @@ runlist_element *ntfs_attr_find_vcn_nolock(ntfs_inode *ni, const VCN vcn,
unsigned long flags;
runlist_element *rl;
int err = 0;
- BOOL is_retry = FALSE;
+ bool is_retry = false;
ntfs_debug("Entering for i_ino 0x%lx, vcn 0x%llx, with%s ctx.",
ni->mft_no, (unsigned long long)vcn, ctx ? "" : "out");
@@ -518,7 +518,7 @@ retry_remap:
*/
err = ntfs_map_runlist_nolock(ni, vcn, ctx);
if (likely(!err)) {
- is_retry = TRUE;
+ is_retry = true;
goto retry_remap;
}
}
@@ -558,8 +558,8 @@ retry_remap:
* On actual error, ntfs_attr_find() returns -EIO. In this case @ctx->attr is
* undefined and in particular do not rely on it not changing.
*
- * If @ctx->is_first is TRUE, the search begins with @ctx->attr itself. If it
- * is FALSE, the search begins after @ctx->attr.
+ * If @ctx->is_first is 'true', the search begins with @ctx->attr itself. If it
+ * is 'false', the search begins after @ctx->attr.
*
* If @ic is IGNORE_CASE, the @name comparisson is not case sensitive and
* @ctx->ntfs_ino must be set to the ntfs inode to which the mft record
@@ -599,11 +599,11 @@ static int ntfs_attr_find(const ATTR_TYPE type, const ntfschar *name,
/*
* Iterate over attributes in mft record starting at @ctx->attr, or the
- * attribute following that, if @ctx->is_first is TRUE.
+ * attribute following that, if @ctx->is_first is 'true'.
*/
if (ctx->is_first) {
a = ctx->attr;
- ctx->is_first = FALSE;
+ ctx->is_first = false;
} else
a = (ATTR_RECORD*)((u8*)ctx->attr +
le32_to_cpu(ctx->attr->length));
@@ -890,11 +890,11 @@ static int ntfs_external_attr_find(const ATTR_TYPE type,
ctx->al_entry = (ATTR_LIST_ENTRY*)al_start;
/*
* Iterate over entries in attribute list starting at @ctx->al_entry,
- * or the entry following that, if @ctx->is_first is TRUE.
+ * or the entry following that, if @ctx->is_first is 'true'.
*/
if (ctx->is_first) {
al_entry = ctx->al_entry;
- ctx->is_first = FALSE;
+ ctx->is_first = false;
} else
al_entry = (ATTR_LIST_ENTRY*)((u8*)ctx->al_entry +
le16_to_cpu(ctx->al_entry->length));
@@ -1127,7 +1127,7 @@ not_found:
ctx->mrec = ctx->base_mrec;
ctx->attr = (ATTR_RECORD*)((u8*)ctx->mrec +
le16_to_cpu(ctx->mrec->attrs_offset));
- ctx->is_first = TRUE;
+ ctx->is_first = true;
ctx->ntfs_ino = base_ni;
ctx->base_ntfs_ino = NULL;
ctx->base_mrec = NULL;
@@ -1224,7 +1224,7 @@ static inline void ntfs_attr_init_search_ctx(ntfs_attr_search_ctx *ctx,
/* Sanity checks are performed elsewhere. */
.attr = (ATTR_RECORD*)((u8*)mrec +
le16_to_cpu(mrec->attrs_offset)),
- .is_first = TRUE,
+ .is_first = true,
.ntfs_ino = ni,
};
}
@@ -1243,7 +1243,7 @@ void ntfs_attr_reinit_search_ctx(ntfs_attr_search_ctx *ctx)
{
if (likely(!ctx->base_ntfs_ino)) {
/* No attribute list. */
- ctx->is_first = TRUE;
+ ctx->is_first = true;
/* Sanity checks are performed elsewhere. */
ctx->attr = (ATTR_RECORD*)((u8*)ctx->mrec +
le16_to_cpu(ctx->mrec->attrs_offset));
@@ -1585,7 +1585,7 @@ int ntfs_attr_make_non_resident(ntfs_inode *ni, const u32 data_size)
return -ENOMEM;
/* Start by allocating clusters to hold the attribute value. */
rl = ntfs_cluster_alloc(vol, 0, new_size >>
- vol->cluster_size_bits, -1, DATA_ZONE, TRUE);
+ vol->cluster_size_bits, -1, DATA_ZONE, true);
if (IS_ERR(rl)) {
err = PTR_ERR(rl);
ntfs_debug("Failed to allocate cluster%s, error code "
@@ -1919,7 +1919,7 @@ s64 ntfs_attr_extend_allocation(ntfs_inode *ni, s64 new_alloc_size,
unsigned long flags;
int err, mp_size;
u32 attr_len = 0; /* Silence stupid gcc warning. */
- BOOL mp_rebuilt;
+ bool mp_rebuilt;
#ifdef NTFS_DEBUG
read_lock_irqsave(&ni->size_lock, flags);
@@ -2222,7 +2222,7 @@ first_alloc:
rl2 = ntfs_cluster_alloc(vol, allocated_size >> vol->cluster_size_bits,
(new_alloc_size - allocated_size) >>
vol->cluster_size_bits, (rl && (rl->lcn >= 0)) ?
- rl->lcn + rl->length : -1, DATA_ZONE, TRUE);
+ rl->lcn + rl->length : -1, DATA_ZONE, true);
if (IS_ERR(rl2)) {
err = PTR_ERR(rl2);
if (start < 0 || start >= allocated_size)
@@ -2265,7 +2265,7 @@ first_alloc:
BUG_ON(!rl2);
BUG_ON(!rl2->length);
BUG_ON(rl2->lcn < LCN_HOLE);
- mp_rebuilt = FALSE;
+ mp_rebuilt = false;
/* Get the size for the new mapping pairs array for this extent. */
mp_size = ntfs_get_size_for_mapping_pairs(vol, rl2, ll, -1);
if (unlikely(mp_size <= 0)) {
@@ -2300,7 +2300,7 @@ first_alloc:
err = -EOPNOTSUPP;
goto undo_alloc;
}
- mp_rebuilt = TRUE;
+ mp_rebuilt = true;
/* Generate the mapping pairs array directly into the attr record. */
err = ntfs_mapping_pairs_build(vol, (u8*)a +
le16_to_cpu(a->data.non_resident.mapping_pairs_offset),
diff --git a/fs/ntfs/attrib.h b/fs/ntfs/attrib.h
index 9074886b44ba..3c8b74c99b80 100644
--- a/fs/ntfs/attrib.h
+++ b/fs/ntfs/attrib.h
@@ -40,10 +40,10 @@
* Structure must be initialized to zero before the first call to one of the
* attribute search functions. Initialize @mrec to point to the mft record to
* search, and @attr to point to the first attribute within @mrec (not necessary
- * if calling the _first() functions), and set @is_first to TRUE (not necessary
+ * if calling the _first() functions), and set @is_first to 'true' (not necessary
* if calling the _first() functions).
*
- * If @is_first is TRUE, the search begins with @attr. If @is_first is FALSE,
+ * If @is_first is 'true', the search begins with @attr. If @is_first is 'false',
* the search begins after @attr. This is so that, after the first call to one
* of the search attribute functions, we can call the function again, without
* any modification of the search context, to automagically get the next
@@ -52,7 +52,7 @@
typedef struct {
MFT_RECORD *mrec;
ATTR_RECORD *attr;
- BOOL is_first;
+ bool is_first;
ntfs_inode *ntfs_ino;
ATTR_LIST_ENTRY *al_entry;
ntfs_inode *base_ntfs_ino;
@@ -65,7 +65,7 @@ extern int ntfs_map_runlist_nolock(ntfs_inode *ni, VCN vcn,
extern int ntfs_map_runlist(ntfs_inode *ni, VCN vcn);
extern LCN ntfs_attr_vcn_to_lcn_nolock(ntfs_inode *ni, const VCN vcn,
- const BOOL write_locked);
+ const bool write_locked);
extern runlist_element *ntfs_attr_find_vcn_nolock(ntfs_inode *ni,
const VCN vcn, ntfs_attr_search_ctx *ctx);
diff --git a/fs/ntfs/bitmap.c b/fs/ntfs/bitmap.c
index 7a190cdc60e2..0809cf876098 100644
--- a/fs/ntfs/bitmap.c
+++ b/fs/ntfs/bitmap.c
@@ -34,18 +34,18 @@
* @start_bit: first bit to set
* @count: number of bits to set
* @value: value to set the bits to (i.e. 0 or 1)
- * @is_rollback: if TRUE this is a rollback operation
+ * @is_rollback: if 'true' this is a rollback operation
*
* Set @count bits starting at bit @start_bit in the bitmap described by the
* vfs inode @vi to @value, where @value is either 0 or 1.
*
- * @is_rollback should always be FALSE, it is for internal use to rollback
+ * @is_rollback should always be 'false', it is for internal use to rollback
* errors. You probably want to use ntfs_bitmap_set_bits_in_run() instead.
*
* Return 0 on success and -errno on error.
*/
int __ntfs_bitmap_set_bits_in_run(struct inode *vi, const s64 start_bit,
- const s64 count, const u8 value, const BOOL is_rollback)
+ const s64 count, const u8 value, const bool is_rollback)
{
s64 cnt = count;
pgoff_t index, end_index;
@@ -172,7 +172,7 @@ rollback:
return PTR_ERR(page);
if (count != cnt)
pos = __ntfs_bitmap_set_bits_in_run(vi, start_bit, count - cnt,
- value ? 0 : 1, TRUE);
+ value ? 0 : 1, true);
else
pos = 0;
if (!pos) {
diff --git a/fs/ntfs/bitmap.h b/fs/ntfs/bitmap.h
index bb50d6bc9212..72c9ad8be70d 100644
--- a/fs/ntfs/bitmap.h
+++ b/fs/ntfs/bitmap.h
@@ -30,7 +30,7 @@
#include "types.h"
extern int __ntfs_bitmap_set_bits_in_run(struct inode *vi, const s64 start_bit,
- const s64 count, const u8 value, const BOOL is_rollback);
+ const s64 count, const u8 value, const bool is_rollback);
/**
* ntfs_bitmap_set_bits_in_run - set a run of bits in a bitmap to a value
@@ -48,7 +48,7 @@ static inline int ntfs_bitmap_set_bits_in_run(struct inode *vi,
const s64 start_bit, const s64 count, const u8 value)
{
return __ntfs_bitmap_set_bits_in_run(vi, start_bit, count, value,
- FALSE);
+ false);
}
/**
diff --git a/fs/ntfs/collate.h b/fs/ntfs/collate.h
index e027f36fcc2f..aba83347e5fe 100644
--- a/fs/ntfs/collate.h
+++ b/fs/ntfs/collate.h
@@ -26,7 +26,7 @@
#include "types.h"
#include "volume.h"
-static inline BOOL ntfs_is_collation_rule_supported(COLLATION_RULE cr) {
+static inline bool ntfs_is_collation_rule_supported(COLLATION_RULE cr) {
int i;
/*
@@ -35,12 +35,12 @@ static inline BOOL ntfs_is_collation_rule_supported(COLLATION_RULE cr) {
* now.
*/
if (unlikely(cr != COLLATION_BINARY && cr != COLLATION_NTOFS_ULONG))
- return FALSE;
+ return false;
i = le32_to_cpu(cr);
if (likely(((i >= 0) && (i <= 0x02)) ||
((i >= 0x10) && (i <= 0x13))))
- return TRUE;
- return FALSE;
+ return true;
+ return false;
}
extern int ntfs_collate(ntfs_volume *vol, COLLATION_RULE cr,
diff --git a/fs/ntfs/compress.c b/fs/ntfs/compress.c
index 68a607ff9fd3..d98daf59e0b6 100644
--- a/fs/ntfs/compress.c
+++ b/fs/ntfs/compress.c
@@ -600,7 +600,7 @@ do_next_cb:
rl = NULL;
for (vcn = start_vcn, start_vcn += cb_clusters; vcn < start_vcn;
vcn++) {
- BOOL is_retry = FALSE;
+ bool is_retry = false;
if (!rl) {
lock_retry_remap:
@@ -626,7 +626,7 @@ lock_retry_remap:
break;
if (is_retry || lcn != LCN_RL_NOT_MAPPED)
goto rl_err;
- is_retry = TRUE;
+ is_retry = true;
/*
* Attempt to map runlist, dropping lock for the
* duration.
diff --git a/fs/ntfs/file.c b/fs/ntfs/file.c
index 2e42c2dcae12..ae2fe0016d2c 100644
--- a/fs/ntfs/file.c
+++ b/fs/ntfs/file.c
@@ -509,7 +509,7 @@ static int ntfs_prepare_pages_for_non_resident_write(struct page **pages,
u32 attr_rec_len = 0;
unsigned blocksize, u;
int err, mp_size;
- BOOL rl_write_locked, was_hole, is_retry;
+ bool rl_write_locked, was_hole, is_retry;
unsigned char blocksize_bits;
struct {
u8 runlist_merged:1;
@@ -543,13 +543,13 @@ static int ntfs_prepare_pages_for_non_resident_write(struct page **pages,
return -ENOMEM;
}
} while (++u < nr_pages);
- rl_write_locked = FALSE;
+ rl_write_locked = false;
rl = NULL;
err = 0;
vcn = lcn = -1;
vcn_len = 0;
lcn_block = -1;
- was_hole = FALSE;
+ was_hole = false;
cpos = pos >> vol->cluster_size_bits;
end = pos + bytes;
cend = (end + vol->cluster_size - 1) >> vol->cluster_size_bits;
@@ -760,7 +760,7 @@ map_buffer_cached:
}
continue;
}
- is_retry = FALSE;
+ is_retry = false;
if (!rl) {
down_read(&ni->runlist.lock);
retry_remap:
@@ -776,7 +776,7 @@ retry_remap:
* Successful remap, setup the map cache and
* use that to deal with the buffer.
*/
- was_hole = FALSE;
+ was_hole = false;
vcn = bh_cpos;
vcn_len = rl[1].vcn - vcn;
lcn_block = lcn << (vol->cluster_size_bits -
@@ -792,7 +792,7 @@ retry_remap:
if (likely(vcn + vcn_len >= cend)) {
if (rl_write_locked) {
up_write(&ni->runlist.lock);
- rl_write_locked = FALSE;
+ rl_write_locked = false;
} else
up_read(&ni->runlist.lock);
rl = NULL;
@@ -818,13 +818,13 @@ retry_remap:
*/
up_read(&ni->runlist.lock);
down_write(&ni->runlist.lock);
- rl_write_locked = TRUE;
+ rl_write_locked = true;
goto retry_remap;
}
err = ntfs_map_runlist_nolock(ni, bh_cpos,
NULL);
if (likely(!err)) {
- is_retry = TRUE;
+ is_retry = true;
goto retry_remap;
}
/*
@@ -903,7 +903,7 @@ rl_not_mapped_enoent:
if (!rl_write_locked) {
up_read(&ni->runlist.lock);
down_write(&ni->runlist.lock);
- rl_write_locked = TRUE;
+ rl_write_locked = true;
goto retry_remap;
}
/* Find the previous last allocated cluster. */
@@ -917,7 +917,7 @@ rl_not_mapped_enoent:
}
}
rl2 = ntfs_cluster_alloc(vol, bh_cpos, 1, lcn, DATA_ZONE,
- FALSE);
+ false);
if (IS_ERR(rl2)) {
err = PTR_ERR(rl2);
ntfs_debug("Failed to allocate cluster, error code %i.",
@@ -1093,7 +1093,7 @@ rl_not_mapped_enoent:
status.mft_attr_mapped = 0;
status.mp_rebuilt = 0;
/* Setup the map cache and use that to deal with the buffer. */
- was_hole = TRUE;
+ was_hole = true;
vcn = bh_cpos;
vcn_len = 1;
lcn_block = lcn << (vol->cluster_size_bits - blocksize_bits);
@@ -1105,7 +1105,7 @@ rl_not_mapped_enoent:
*/
if (likely(vcn + vcn_len >= cend)) {
up_write(&ni->runlist.lock);
- rl_write_locked = FALSE;
+ rl_write_locked = false;
rl = NULL;
}
goto map_buffer_cached;
@@ -1117,7 +1117,7 @@ rl_not_mapped_enoent:
if (likely(!err)) {
if (unlikely(rl_write_locked)) {
up_write(&ni->runlist.lock);
- rl_write_locked = FALSE;
+ rl_write_locked = false;
} else if (unlikely(rl))
up_read(&ni->runlist.lock);
rl = NULL;
@@ -1528,19 +1528,19 @@ static inline int ntfs_commit_pages_after_non_resident_write(
do {
s64 bh_pos;
struct page *page;
- BOOL partial;
+ bool partial;
page = pages[u];
bh_pos = (s64)page->index << PAGE_CACHE_SHIFT;
bh = head = page_buffers(page);
- partial = FALSE;
+ partial = false;
do {
s64 bh_end;
bh_end = bh_pos + blocksize;
if (bh_end <= pos || bh_pos >= end) {
if (!buffer_uptodate(bh))
- partial = TRUE;
+ partial = true;
} else {
set_buffer_uptodate(bh);
mark_buffer_dirty(bh);
@@ -1997,7 +1997,7 @@ static ssize_t ntfs_file_buffered_write(struct kiocb *iocb,
*/
down_read(&ni->runlist.lock);
lcn = ntfs_attr_vcn_to_lcn_nolock(ni, pos >>
- vol->cluster_size_bits, FALSE);
+ vol->cluster_size_bits, false);
up_read(&ni->runlist.lock);
if (unlikely(lcn < LCN_HOLE)) {
status = -EIO;
@@ -2176,20 +2176,18 @@ out:
/**
* ntfs_file_aio_write -
*/
-static ssize_t ntfs_file_aio_write(struct kiocb *iocb, const char __user *buf,
- size_t count, loff_t pos)
+static ssize_t ntfs_file_aio_write(struct kiocb *iocb, const struct iovec *iov,
+ unsigned long nr_segs, loff_t pos)
{
struct file *file = iocb->ki_filp;
struct address_space *mapping = file->f_mapping;
struct inode *inode = mapping->host;
ssize_t ret;
- struct iovec local_iov = { .iov_base = (void __user *)buf,
- .iov_len = count };
BUG_ON(iocb->ki_pos != pos);
mutex_lock(&inode->i_mutex);
- ret = ntfs_file_aio_write_nolock(iocb, &local_iov, 1, &iocb->ki_pos);
+ ret = ntfs_file_aio_write_nolock(iocb, iov, nr_segs, &iocb->ki_pos);
mutex_unlock(&inode->i_mutex);
if (ret > 0 && ((file->f_flags & O_SYNC) || IS_SYNC(inode))) {
int err = sync_page_range(inode, mapping, pos, ret);
@@ -2298,13 +2296,11 @@ static int ntfs_file_fsync(struct file *filp, struct dentry *dentry,
const struct file_operations ntfs_file_ops = {
.llseek = generic_file_llseek, /* Seek inside file. */
- .read = generic_file_read, /* Read from file. */
+ .read = do_sync_read, /* Read from file. */
.aio_read = generic_file_aio_read, /* Async read from file. */
- .readv = generic_file_readv, /* Read from file. */
#ifdef NTFS_RW
.write = ntfs_file_write, /* Write to file. */
.aio_write = ntfs_file_aio_write, /* Async write to file. */
- .writev = ntfs_file_writev, /* Write to file. */
/*.release = ,*/ /* Last file is closed. See
fs/ext2/file.c::
ext2_release_file() for
diff --git a/fs/ntfs/index.c b/fs/ntfs/index.c
index 9f5427c2d105..e32cde486362 100644
--- a/fs/ntfs/index.c
+++ b/fs/ntfs/index.c
@@ -204,7 +204,7 @@ int ntfs_index_lookup(const void *key, const int key_len,
if ((key_len == le16_to_cpu(ie->key_length)) && !memcmp(key,
&ie->key, key_len)) {
ir_done:
- ictx->is_in_root = TRUE;
+ ictx->is_in_root = true;
ictx->ir = ir;
ictx->actx = actx;
ictx->base_ni = base_ni;
@@ -374,7 +374,7 @@ fast_descend_into_child_node:
if ((key_len == le16_to_cpu(ie->key_length)) && !memcmp(key,
&ie->key, key_len)) {
ia_done:
- ictx->is_in_root = FALSE;
+ ictx->is_in_root = false;
ictx->actx = NULL;
ictx->base_ni = NULL;
ictx->ia = ia;
diff --git a/fs/ntfs/index.h b/fs/ntfs/index.h
index 846a489e8692..8745469c3989 100644
--- a/fs/ntfs/index.h
+++ b/fs/ntfs/index.h
@@ -37,12 +37,12 @@
* @entry: index entry (points into @ir or @ia)
* @data: index entry data (points into @entry)
* @data_len: length in bytes of @data
- * @is_in_root: TRUE if @entry is in @ir and FALSE if it is in @ia
+ * @is_in_root: 'true' if @entry is in @ir and 'false' if it is in @ia
* @ir: index root if @is_in_root and NULL otherwise
* @actx: attribute search context if @is_in_root and NULL otherwise
* @base_ni: base inode if @is_in_root and NULL otherwise
- * @ia: index block if @is_in_root is FALSE and NULL otherwise
- * @page: page if @is_in_root is FALSE and NULL otherwise
+ * @ia: index block if @is_in_root is 'false' and NULL otherwise
+ * @page: page if @is_in_root is 'false' and NULL otherwise
*
* @idx_ni is the index inode this context belongs to.
*
@@ -50,11 +50,11 @@
* are the index entry data and its length in bytes, respectively. @data
* simply points into @entry. This is probably what the user is interested in.
*
- * If @is_in_root is TRUE, @entry is in the index root attribute @ir described
+ * If @is_in_root is 'true', @entry is in the index root attribute @ir described
* by the attribute search context @actx and the base inode @base_ni. @ia and
* @page are NULL in this case.
*
- * If @is_in_root is FALSE, @entry is in the index allocation attribute and @ia
+ * If @is_in_root is 'false', @entry is in the index allocation attribute and @ia
* and @page point to the index allocation block and the mapped, locked page it
* is in, respectively. @ir, @actx and @base_ni are NULL in this case.
*
@@ -77,7 +77,7 @@ typedef struct {
INDEX_ENTRY *entry;
void *data;
u16 data_len;
- BOOL is_in_root;
+ bool is_in_root;
INDEX_ROOT *ir;
ntfs_attr_search_ctx *actx;
ntfs_inode *base_ni;
diff --git a/fs/ntfs/inode.c b/fs/ntfs/inode.c
index 933dbd89c2a4..2d3de9c89818 100644
--- a/fs/ntfs/inode.c
+++ b/fs/ntfs/inode.c
@@ -2301,7 +2301,7 @@ void ntfs_clear_big_inode(struct inode *vi)
}
#ifdef NTFS_RW
if (NInoDirty(ni)) {
- BOOL was_bad = (is_bad_inode(vi));
+ bool was_bad = (is_bad_inode(vi));
/* Committing the inode also commits all extent inodes. */
ntfs_commit_inode(vi);
@@ -3015,7 +3015,7 @@ int ntfs_write_inode(struct inode *vi, int sync)
MFT_RECORD *m;
STANDARD_INFORMATION *si;
int err = 0;
- BOOL modified = FALSE;
+ bool modified = false;
ntfs_debug("Entering for %sinode 0x%lx.", NInoAttr(ni) ? "attr " : "",
vi->i_ino);
@@ -3057,7 +3057,7 @@ int ntfs_write_inode(struct inode *vi, int sync)
sle64_to_cpu(si->last_data_change_time),
(long long)sle64_to_cpu(nt));
si->last_data_change_time = nt;
- modified = TRUE;
+ modified = true;
}
nt = utc2ntfs(vi->i_ctime);
if (si->last_mft_change_time != nt) {
@@ -3066,7 +3066,7 @@ int ntfs_write_inode(struct inode *vi, int sync)
sle64_to_cpu(si->last_mft_change_time),
(long long)sle64_to_cpu(nt));
si->last_mft_change_time = nt;
- modified = TRUE;
+ modified = true;
}
nt = utc2ntfs(vi->i_atime);
if (si->last_access_time != nt) {
@@ -3075,7 +3075,7 @@ int ntfs_write_inode(struct inode *vi, int sync)
(long long)sle64_to_cpu(si->last_access_time),
(long long)sle64_to_cpu(nt));
si->last_access_time = nt;
- modified = TRUE;
+ modified = true;
}
/*
* If we just modified the standard information attribute we need to
diff --git a/fs/ntfs/layout.h b/fs/ntfs/layout.h
index d34b93cb8b48..1e383328eceb 100644
--- a/fs/ntfs/layout.h
+++ b/fs/ntfs/layout.h
@@ -142,13 +142,13 @@ typedef le32 NTFS_RECORD_TYPE;
* operator! (-8
*/
-static inline BOOL __ntfs_is_magic(le32 x, NTFS_RECORD_TYPE r)
+static inline bool __ntfs_is_magic(le32 x, NTFS_RECORD_TYPE r)
{
return (x == r);
}
#define ntfs_is_magic(x, m) __ntfs_is_magic(x, magic_##m)
-static inline BOOL __ntfs_is_magicp(le32 *p, NTFS_RECORD_TYPE r)
+static inline bool __ntfs_is_magicp(le32 *p, NTFS_RECORD_TYPE r)
{
return (*p == r);
}
@@ -323,7 +323,7 @@ typedef le64 leMFT_REF;
#define MREF_LE(x) ((unsigned long)(le64_to_cpu(x) & MFT_REF_MASK_CPU))
#define MSEQNO_LE(x) ((u16)((le64_to_cpu(x) >> 48) & 0xffff))
-#define IS_ERR_MREF(x) (((x) & 0x0000800000000000ULL) ? 1 : 0)
+#define IS_ERR_MREF(x) (((x) & 0x0000800000000000ULL) ? true : false)
#define ERR_MREF(x) ((u64)((s64)(x)))
#define MREF_ERR(x) ((int)((s64)(x)))
diff --git a/fs/ntfs/lcnalloc.c b/fs/ntfs/lcnalloc.c
index 29cabf93d2d2..1711b710b641 100644
--- a/fs/ntfs/lcnalloc.c
+++ b/fs/ntfs/lcnalloc.c
@@ -76,7 +76,7 @@ int ntfs_cluster_free_from_rl_nolock(ntfs_volume *vol,
* @count: number of clusters to allocate
* @start_lcn: starting lcn at which to allocate the clusters (or -1 if none)
* @zone: zone from which to allocate the clusters
- * @is_extension: if TRUE, this is an attribute extension
+ * @is_extension: if 'true', this is an attribute extension
*
* Allocate @count clusters preferably starting at cluster @start_lcn or at the
* current allocator position if @start_lcn is -1, on the mounted ntfs volume
@@ -87,11 +87,11 @@ int ntfs_cluster_free_from_rl_nolock(ntfs_volume *vol,
* @start_vcn specifies the vcn of the first allocated cluster. This makes
* merging the resulting runlist with the old runlist easier.
*
- * If @is_extension is TRUE, the caller is allocating clusters to extend an
- * attribute and if it is FALSE, the caller is allocating clusters to fill a
+ * If @is_extension is 'true', the caller is allocating clusters to extend an
+ * attribute and if it is 'false', the caller is allocating clusters to fill a
* hole in an attribute. Practically the difference is that if @is_extension
- * is TRUE the returned runlist will be terminated with LCN_ENOENT and if
- * @is_extension is FALSE the runlist will be terminated with
+ * is 'true' the returned runlist will be terminated with LCN_ENOENT and if
+ * @is_extension is 'false' the runlist will be terminated with
* LCN_RL_NOT_MAPPED.
*
* You need to check the return value with IS_ERR(). If this is false, the
@@ -146,7 +146,7 @@ int ntfs_cluster_free_from_rl_nolock(ntfs_volume *vol,
runlist_element *ntfs_cluster_alloc(ntfs_volume *vol, const VCN start_vcn,
const s64 count, const LCN start_lcn,
const NTFS_CLUSTER_ALLOCATION_ZONES zone,
- const BOOL is_extension)
+ const bool is_extension)
{
LCN zone_start, zone_end, bmp_pos, bmp_initial_pos, last_read_pos, lcn;
LCN prev_lcn = 0, prev_run_len = 0, mft_zone_size;
@@ -818,7 +818,7 @@ out:
* Assuming you cache ctx->attr in a variable @a of type ATTR_RECORD * and that
* you cache ctx->mrec in a variable @m of type MFT_RECORD *.
*
- * @is_rollback should always be FALSE, it is for internal use to rollback
+ * @is_rollback should always be 'false', it is for internal use to rollback
* errors. You probably want to use ntfs_cluster_free() instead.
*
* Note, __ntfs_cluster_free() does not modify the runlist, so you have to
@@ -828,7 +828,7 @@ out:
* success and -errno on error.
*
* WARNING: If @ctx is supplied, regardless of whether success or failure is
- * returned, you need to check IS_ERR(@ctx->mrec) and if TRUE the @ctx
+ * returned, you need to check IS_ERR(@ctx->mrec) and if 'true' the @ctx
* is no longer valid, i.e. you need to either call
* ntfs_attr_reinit_search_ctx() or ntfs_attr_put_search_ctx() on it.
* In that case PTR_ERR(@ctx->mrec) will give you the error code for
@@ -847,7 +847,7 @@ out:
* and it will be left mapped on return.
*/
s64 __ntfs_cluster_free(ntfs_inode *ni, const VCN start_vcn, s64 count,
- ntfs_attr_search_ctx *ctx, const BOOL is_rollback)
+ ntfs_attr_search_ctx *ctx, const bool is_rollback)
{
s64 delta, to_free, total_freed, real_freed;
ntfs_volume *vol;
@@ -999,7 +999,7 @@ err_out:
* If rollback fails, set the volume errors flag, emit an error
* message, and return the error code.
*/
- delta = __ntfs_cluster_free(ni, start_vcn, total_freed, ctx, TRUE);
+ delta = __ntfs_cluster_free(ni, start_vcn, total_freed, ctx, true);
if (delta < 0) {
ntfs_error(vol->sb, "Failed to rollback (error %i). Leaving "
"inconsistent metadata! Unmount and run "
diff --git a/fs/ntfs/lcnalloc.h b/fs/ntfs/lcnalloc.h
index 72cbca7003b2..2adb04316941 100644
--- a/fs/ntfs/lcnalloc.h
+++ b/fs/ntfs/lcnalloc.h
@@ -43,10 +43,10 @@ typedef enum {
extern runlist_element *ntfs_cluster_alloc(ntfs_volume *vol,
const VCN start_vcn, const s64 count, const LCN start_lcn,
const NTFS_CLUSTER_ALLOCATION_ZONES zone,
- const BOOL is_extension);
+ const bool is_extension);
extern s64 __ntfs_cluster_free(ntfs_inode *ni, const VCN start_vcn,
- s64 count, ntfs_attr_search_ctx *ctx, const BOOL is_rollback);
+ s64 count, ntfs_attr_search_ctx *ctx, const bool is_rollback);
/**
* ntfs_cluster_free - free clusters on an ntfs volume
@@ -86,7 +86,7 @@ extern s64 __ntfs_cluster_free(ntfs_inode *ni, const VCN start_vcn,
* success and -errno on error.
*
* WARNING: If @ctx is supplied, regardless of whether success or failure is
- * returned, you need to check IS_ERR(@ctx->mrec) and if TRUE the @ctx
+ * returned, you need to check IS_ERR(@ctx->mrec) and if 'true' the @ctx
* is no longer valid, i.e. you need to either call
* ntfs_attr_reinit_search_ctx() or ntfs_attr_put_search_ctx() on it.
* In that case PTR_ERR(@ctx->mrec) will give you the error code for
@@ -107,7 +107,7 @@ extern s64 __ntfs_cluster_free(ntfs_inode *ni, const VCN start_vcn,
static inline s64 ntfs_cluster_free(ntfs_inode *ni, const VCN start_vcn,
s64 count, ntfs_attr_search_ctx *ctx)
{
- return __ntfs_cluster_free(ni, start_vcn, count, ctx, FALSE);
+ return __ntfs_cluster_free(ni, start_vcn, count, ctx, false);
}
extern int ntfs_cluster_free_from_rl_nolock(ntfs_volume *vol,
diff --git a/fs/ntfs/logfile.c b/fs/ntfs/logfile.c
index 4af2ad1193ec..acfed325f4ec 100644
--- a/fs/ntfs/logfile.c
+++ b/fs/ntfs/logfile.c
@@ -41,18 +41,18 @@
* @rp: restart page header to check
* @pos: position in @vi at which the restart page header resides
*
- * Check the restart page header @rp for consistency and return TRUE if it is
- * consistent and FALSE otherwise.
+ * Check the restart page header @rp for consistency and return 'true' if it is
+ * consistent and 'false' otherwise.
*
* This function only needs NTFS_BLOCK_SIZE bytes in @rp, i.e. it does not
* require the full restart page.
*/
-static BOOL ntfs_check_restart_page_header(struct inode *vi,
+static bool ntfs_check_restart_page_header(struct inode *vi,
RESTART_PAGE_HEADER *rp, s64 pos)
{
u32 logfile_system_page_size, logfile_log_page_size;
u16 ra_ofs, usa_count, usa_ofs, usa_end = 0;
- BOOL have_usa = TRUE;
+ bool have_usa = true;
ntfs_debug("Entering.");
/*
@@ -67,7 +67,7 @@ static BOOL ntfs_check_restart_page_header(struct inode *vi,
(logfile_system_page_size - 1) ||
logfile_log_page_size & (logfile_log_page_size - 1)) {
ntfs_error(vi->i_sb, "$LogFile uses unsupported page size.");
- return FALSE;
+ return false;
}
/*
* We must be either at !pos (1st restart page) or at pos = system page
@@ -76,7 +76,7 @@ static BOOL ntfs_check_restart_page_header(struct inode *vi,
if (pos && pos != logfile_system_page_size) {
ntfs_error(vi->i_sb, "Found restart area in incorrect "
"position in $LogFile.");
- return FALSE;
+ return false;
}
/* We only know how to handle version 1.1. */
if (sle16_to_cpu(rp->major_ver) != 1 ||
@@ -85,14 +85,14 @@ static BOOL ntfs_check_restart_page_header(struct inode *vi,
"supported. (This driver supports version "
"1.1 only.)", (int)sle16_to_cpu(rp->major_ver),
(int)sle16_to_cpu(rp->minor_ver));
- return FALSE;
+ return false;
}
/*
* If chkdsk has been run the restart page may not be protected by an
* update sequence array.
*/
if (ntfs_is_chkd_record(rp->magic) && !le16_to_cpu(rp->usa_count)) {
- have_usa = FALSE;
+ have_usa = false;
goto skip_usa_checks;
}
/* Verify the size of the update sequence array. */
@@ -100,7 +100,7 @@ static BOOL ntfs_check_restart_page_header(struct inode *vi,
if (usa_count != le16_to_cpu(rp->usa_count)) {
ntfs_error(vi->i_sb, "$LogFile restart page specifies "
"inconsistent update sequence array count.");
- return FALSE;
+ return false;
}
/* Verify the position of the update sequence array. */
usa_ofs = le16_to_cpu(rp->usa_ofs);
@@ -109,7 +109,7 @@ static BOOL ntfs_check_restart_page_header(struct inode *vi,
usa_end > NTFS_BLOCK_SIZE - sizeof(u16)) {
ntfs_error(vi->i_sb, "$LogFile restart page specifies "
"inconsistent update sequence array offset.");
- return FALSE;
+ return false;
}
skip_usa_checks:
/*
@@ -124,7 +124,7 @@ skip_usa_checks:
ra_ofs > logfile_system_page_size) {
ntfs_error(vi->i_sb, "$LogFile restart page specifies "
"inconsistent restart area offset.");
- return FALSE;
+ return false;
}
/*
* Only restart pages modified by chkdsk are allowed to have chkdsk_lsn
@@ -133,10 +133,10 @@ skip_usa_checks:
if (!ntfs_is_chkd_record(rp->magic) && sle64_to_cpu(rp->chkdsk_lsn)) {
ntfs_error(vi->i_sb, "$LogFile restart page is not modified "
"by chkdsk but a chkdsk LSN is specified.");
- return FALSE;
+ return false;
}
ntfs_debug("Done.");
- return TRUE;
+ return true;
}
/**
@@ -145,7 +145,7 @@ skip_usa_checks:
* @rp: restart page whose restart area to check
*
* Check the restart area of the restart page @rp for consistency and return
- * TRUE if it is consistent and FALSE otherwise.
+ * 'true' if it is consistent and 'false' otherwise.
*
* This function assumes that the restart page header has already been
* consistency checked.
@@ -153,7 +153,7 @@ skip_usa_checks:
* This function only needs NTFS_BLOCK_SIZE bytes in @rp, i.e. it does not
* require the full restart page.
*/
-static BOOL ntfs_check_restart_area(struct inode *vi, RESTART_PAGE_HEADER *rp)
+static bool ntfs_check_restart_area(struct inode *vi, RESTART_PAGE_HEADER *rp)
{
u64 file_size;
RESTART_AREA *ra;
@@ -172,7 +172,7 @@ static BOOL ntfs_check_restart_area(struct inode *vi, RESTART_PAGE_HEADER *rp)
NTFS_BLOCK_SIZE - sizeof(u16)) {
ntfs_error(vi->i_sb, "$LogFile restart area specifies "
"inconsistent file offset.");
- return FALSE;
+ return false;
}
/*
* Now that we can access ra->client_array_offset, make sure everything
@@ -186,7 +186,7 @@ static BOOL ntfs_check_restart_area(struct inode *vi, RESTART_PAGE_HEADER *rp)
ra_ofs + ca_ofs > NTFS_BLOCK_SIZE - sizeof(u16)) {
ntfs_error(vi->i_sb, "$LogFile restart area specifies "
"inconsistent client array offset.");
- return FALSE;
+ return false;
}
/*
* The restart area must end within the system page size both when
@@ -203,7 +203,7 @@ static BOOL ntfs_check_restart_area(struct inode *vi, RESTART_PAGE_HEADER *rp)
"of the system page size specified by the "
"restart page header and/or the specified "
"restart area length is inconsistent.");
- return FALSE;
+ return false;
}
/*
* The ra->client_free_list and ra->client_in_use_list must be either
@@ -218,7 +218,7 @@ static BOOL ntfs_check_restart_area(struct inode *vi, RESTART_PAGE_HEADER *rp)
le16_to_cpu(ra->log_clients))) {
ntfs_error(vi->i_sb, "$LogFile restart area specifies "
"overflowing client free and/or in use lists.");
- return FALSE;
+ return false;
}
/*
* Check ra->seq_number_bits against ra->file_size for consistency.
@@ -233,24 +233,24 @@ static BOOL ntfs_check_restart_area(struct inode *vi, RESTART_PAGE_HEADER *rp)
if (le32_to_cpu(ra->seq_number_bits) != 67 - fs_bits) {
ntfs_error(vi->i_sb, "$LogFile restart area specifies "
"inconsistent sequence number bits.");
- return FALSE;
+ return false;
}
/* The log record header length must be a multiple of 8. */
if (((le16_to_cpu(ra->log_record_header_length) + 7) & ~7) !=
le16_to_cpu(ra->log_record_header_length)) {
ntfs_error(vi->i_sb, "$LogFile restart area specifies "
"inconsistent log record header length.");
- return FALSE;
+ return false;
}
/* Dito for the log page data offset. */
if (((le16_to_cpu(ra->log_page_data_offset) + 7) & ~7) !=
le16_to_cpu(ra->log_page_data_offset)) {
ntfs_error(vi->i_sb, "$LogFile restart area specifies "
"inconsistent log page data offset.");
- return FALSE;
+ return false;
}
ntfs_debug("Done.");
- return TRUE;
+ return true;
}
/**
@@ -259,7 +259,7 @@ static BOOL ntfs_check_restart_area(struct inode *vi, RESTART_PAGE_HEADER *rp)
* @rp: restart page whose log client array to check
*
* Check the log client array of the restart page @rp for consistency and
- * return TRUE if it is consistent and FALSE otherwise.
+ * return 'true' if it is consistent and 'false' otherwise.
*
* This function assumes that the restart page header and the restart area have
* already been consistency checked.
@@ -268,13 +268,13 @@ static BOOL ntfs_check_restart_area(struct inode *vi, RESTART_PAGE_HEADER *rp)
* function needs @rp->system_page_size bytes in @rp, i.e. it requires the full
* restart page and the page must be multi sector transfer deprotected.
*/
-static BOOL ntfs_check_log_client_array(struct inode *vi,
+static bool ntfs_check_log_client_array(struct inode *vi,
RESTART_PAGE_HEADER *rp)
{
RESTART_AREA *ra;
LOG_CLIENT_RECORD *ca, *cr;
u16 nr_clients, idx;
- BOOL in_free_list, idx_is_first;
+ bool in_free_list, idx_is_first;
ntfs_debug("Entering.");
ra = (RESTART_AREA*)((u8*)rp + le16_to_cpu(rp->restart_area_offset));
@@ -290,9 +290,9 @@ static BOOL ntfs_check_log_client_array(struct inode *vi,
*/
nr_clients = le16_to_cpu(ra->log_clients);
idx = le16_to_cpu(ra->client_free_list);
- in_free_list = TRUE;
+ in_free_list = true;
check_list:
- for (idx_is_first = TRUE; idx != LOGFILE_NO_CLIENT_CPU; nr_clients--,
+ for (idx_is_first = true; idx != LOGFILE_NO_CLIENT_CPU; nr_clients--,
idx = le16_to_cpu(cr->next_client)) {
if (!nr_clients || idx >= le16_to_cpu(ra->log_clients))
goto err_out;
@@ -302,20 +302,20 @@ check_list:
if (idx_is_first) {
if (cr->prev_client != LOGFILE_NO_CLIENT)
goto err_out;
- idx_is_first = FALSE;
+ idx_is_first = false;
}
}
/* Switch to and check the in use list if we just did the free list. */
if (in_free_list) {
- in_free_list = FALSE;
+ in_free_list = false;
idx = le16_to_cpu(ra->client_in_use_list);
goto check_list;
}
ntfs_debug("Done.");
- return TRUE;
+ return true;
err_out:
ntfs_error(vi->i_sb, "$LogFile log client array is corrupt.");
- return FALSE;
+ return false;
}
/**
@@ -468,8 +468,8 @@ err_out:
* @log_vi: struct inode of loaded journal $LogFile to check
* @rp: [OUT] on success this is a copy of the current restart page
*
- * Check the $LogFile journal for consistency and return TRUE if it is
- * consistent and FALSE if not. On success, the current restart page is
+ * Check the $LogFile journal for consistency and return 'true' if it is
+ * consistent and 'false' if not. On success, the current restart page is
* returned in *@rp. Caller must call ntfs_free(*@rp) when finished with it.
*
* At present we only check the two restart pages and ignore the log record
@@ -480,7 +480,7 @@ err_out:
* if the $LogFile was created on a system with a different page size to ours
* yet and mst deprotection would fail if our page size is smaller.
*/
-BOOL ntfs_check_logfile(struct inode *log_vi, RESTART_PAGE_HEADER **rp)
+bool ntfs_check_logfile(struct inode *log_vi, RESTART_PAGE_HEADER **rp)
{
s64 size, pos;
LSN rstr1_lsn, rstr2_lsn;
@@ -491,7 +491,7 @@ BOOL ntfs_check_logfile(struct inode *log_vi, RESTART_PAGE_HEADER **rp)
RESTART_PAGE_HEADER *rstr1_ph = NULL;
RESTART_PAGE_HEADER *rstr2_ph = NULL;
int log_page_size, log_page_mask, err;
- BOOL logfile_is_empty = TRUE;
+ bool logfile_is_empty = true;
u8 log_page_bits;
ntfs_debug("Entering.");
@@ -527,7 +527,7 @@ BOOL ntfs_check_logfile(struct inode *log_vi, RESTART_PAGE_HEADER **rp)
if (size < log_page_size * 2 || (size - log_page_size * 2) >>
log_page_bits < MinLogRecordPages) {
ntfs_error(vol->sb, "$LogFile is too small.");
- return FALSE;
+ return false;
}
/*
* Read through the file looking for a restart page. Since the restart
@@ -556,7 +556,7 @@ BOOL ntfs_check_logfile(struct inode *log_vi, RESTART_PAGE_HEADER **rp)
* means we are done.
*/
if (!ntfs_is_empty_recordp((le32*)kaddr))
- logfile_is_empty = FALSE;
+ logfile_is_empty = false;
else if (!logfile_is_empty)
break;
/*
@@ -615,13 +615,13 @@ BOOL ntfs_check_logfile(struct inode *log_vi, RESTART_PAGE_HEADER **rp)
NVolSetLogFileEmpty(vol);
is_empty:
ntfs_debug("Done. ($LogFile is empty.)");
- return TRUE;
+ return true;
}
if (!rstr1_ph) {
BUG_ON(rstr2_ph);
ntfs_error(vol->sb, "Did not find any restart pages in "
"$LogFile and it was not empty.");
- return FALSE;
+ return false;
}
/* If both restart pages were found, use the more recent one. */
if (rstr2_ph) {
@@ -648,11 +648,11 @@ is_empty:
else
ntfs_free(rstr1_ph);
ntfs_debug("Done.");
- return TRUE;
+ return true;
err_out:
if (rstr1_ph)
ntfs_free(rstr1_ph);
- return FALSE;
+ return false;
}
/**
@@ -660,8 +660,8 @@ err_out:
* @log_vi: struct inode of loaded journal $LogFile to check
* @rp: copy of the current restart page
*
- * Analyze the $LogFile journal and return TRUE if it indicates the volume was
- * shutdown cleanly and FALSE if not.
+ * Analyze the $LogFile journal and return 'true' if it indicates the volume was
+ * shutdown cleanly and 'false' if not.
*
* At present we only look at the two restart pages and ignore the log record
* pages. This is a little bit crude in that there will be a very small number
@@ -675,7 +675,7 @@ err_out:
* is empty this function requires that NVolLogFileEmpty() is true otherwise an
* empty volume will be reported as dirty.
*/
-BOOL ntfs_is_logfile_clean(struct inode *log_vi, const RESTART_PAGE_HEADER *rp)
+bool ntfs_is_logfile_clean(struct inode *log_vi, const RESTART_PAGE_HEADER *rp)
{
ntfs_volume *vol = NTFS_SB(log_vi->i_sb);
RESTART_AREA *ra;
@@ -684,7 +684,7 @@ BOOL ntfs_is_logfile_clean(struct inode *log_vi, const RESTART_PAGE_HEADER *rp)
/* An empty $LogFile must have been clean before it got emptied. */
if (NVolLogFileEmpty(vol)) {
ntfs_debug("Done. ($LogFile is empty.)");
- return TRUE;
+ return true;
}
BUG_ON(!rp);
if (!ntfs_is_rstr_record(rp->magic) &&
@@ -693,7 +693,7 @@ BOOL ntfs_is_logfile_clean(struct inode *log_vi, const RESTART_PAGE_HEADER *rp)
"probably a bug in that the $LogFile should "
"have been consistency checked before calling "
"this function.");
- return FALSE;
+ return false;
}
ra = (RESTART_AREA*)((u8*)rp + le16_to_cpu(rp->restart_area_offset));
/*
@@ -704,25 +704,25 @@ BOOL ntfs_is_logfile_clean(struct inode *log_vi, const RESTART_PAGE_HEADER *rp)
if (ra->client_in_use_list != LOGFILE_NO_CLIENT &&
!(ra->flags & RESTART_VOLUME_IS_CLEAN)) {
ntfs_debug("Done. $LogFile indicates a dirty shutdown.");
- return FALSE;
+ return false;
}
/* $LogFile indicates a clean shutdown. */
ntfs_debug("Done. $LogFile indicates a clean shutdown.");
- return TRUE;
+ return true;
}
/**
* ntfs_empty_logfile - empty the contents of the $LogFile journal
* @log_vi: struct inode of loaded journal $LogFile to empty
*
- * Empty the contents of the $LogFile journal @log_vi and return TRUE on
- * success and FALSE on error.
+ * Empty the contents of the $LogFile journal @log_vi and return 'true' on
+ * success and 'false' on error.
*
* This function assumes that the $LogFile journal has already been consistency
* checked by a call to ntfs_check_logfile() and that ntfs_is_logfile_clean()
* has been used to ensure that the $LogFile is clean.
*/
-BOOL ntfs_empty_logfile(struct inode *log_vi)
+bool ntfs_empty_logfile(struct inode *log_vi)
{
ntfs_volume *vol = NTFS_SB(log_vi->i_sb);
@@ -735,13 +735,13 @@ BOOL ntfs_empty_logfile(struct inode *log_vi)
if (unlikely(err)) {
ntfs_error(vol->sb, "Failed to fill $LogFile with "
"0xff bytes (error code %i).", err);
- return FALSE;
+ return false;
}
/* Set the flag so we do not have to do it again on remount. */
NVolSetLogFileEmpty(vol);
}
ntfs_debug("Done.");
- return TRUE;
+ return true;
}
#endif /* NTFS_RW */
diff --git a/fs/ntfs/logfile.h b/fs/ntfs/logfile.h
index a51f3dd0e9eb..9468e1c45ae3 100644
--- a/fs/ntfs/logfile.h
+++ b/fs/ntfs/logfile.h
@@ -296,13 +296,13 @@ typedef struct {
/* sizeof() = 160 (0xa0) bytes */
} __attribute__ ((__packed__)) LOG_CLIENT_RECORD;
-extern BOOL ntfs_check_logfile(struct inode *log_vi,
+extern bool ntfs_check_logfile(struct inode *log_vi,
RESTART_PAGE_HEADER **rp);
-extern BOOL ntfs_is_logfile_clean(struct inode *log_vi,
+extern bool ntfs_is_logfile_clean(struct inode *log_vi,
const RESTART_PAGE_HEADER *rp);
-extern BOOL ntfs_empty_logfile(struct inode *log_vi);
+extern bool ntfs_empty_logfile(struct inode *log_vi);
#endif /* NTFS_RW */
diff --git a/fs/ntfs/mft.c b/fs/ntfs/mft.c
index 584260fd6848..2ad5c8b104b9 100644
--- a/fs/ntfs/mft.c
+++ b/fs/ntfs/mft.c
@@ -251,7 +251,7 @@ MFT_RECORD *map_extent_mft_record(ntfs_inode *base_ni, MFT_REF mref,
int i;
unsigned long mft_no = MREF(mref);
u16 seq_no = MSEQNO(mref);
- BOOL destroy_ni = FALSE;
+ bool destroy_ni = false;
ntfs_debug("Mapping extent mft record 0x%lx (base mft record 0x%lx).",
mft_no, base_ni->mft_no);
@@ -322,7 +322,7 @@ map_err_out:
if (seq_no && (le16_to_cpu(m->sequence_number) != seq_no)) {
ntfs_error(base_ni->vol->sb, "Found stale extent mft "
"reference! Corrupt filesystem. Run chkdsk.");
- destroy_ni = TRUE;
+ destroy_ni = true;
m = ERR_PTR(-EIO);
goto unm_err_out;
}
@@ -335,7 +335,7 @@ map_err_out:
if (unlikely(!tmp)) {
ntfs_error(base_ni->vol->sb, "Failed to allocate "
"internal buffer.");
- destroy_ni = TRUE;
+ destroy_ni = true;
m = ERR_PTR(-ENOMEM);
goto unm_err_out;
}
@@ -857,7 +857,7 @@ err_out:
* caller is responsible for unlocking the ntfs inode and unpinning the base
* vfs inode.
*
- * Return TRUE if the mft record may be written out and FALSE if not.
+ * Return 'true' if the mft record may be written out and 'false' if not.
*
* The caller has locked the page and cleared the uptodate flag on it which
* means that we can safely write out any dirty mft records that do not have
@@ -868,7 +868,7 @@ err_out:
* Here is a description of the tests we perform:
*
* If the inode is found in icache we know the mft record must be a base mft
- * record. If it is dirty, we do not write it and return FALSE as the vfs
+ * record. If it is dirty, we do not write it and return 'false' as the vfs
* inode write paths will result in the access times being updated which would
* cause the base mft record to be redirtied and written out again. (We know
* the access time update will modify the base mft record because Windows
@@ -877,11 +877,11 @@ err_out:
*
* If the inode is in icache and not dirty, we attempt to lock the mft record
* and if we find the lock was already taken, it is not safe to write the mft
- * record and we return FALSE.
+ * record and we return 'false'.
*
* If we manage to obtain the lock we have exclusive access to the mft record,
* which also allows us safe writeout of the mft record. We then set
- * @locked_ni to the locked ntfs inode and return TRUE.
+ * @locked_ni to the locked ntfs inode and return 'true'.
*
* Note we cannot just lock the mft record and sleep while waiting for the lock
* because this would deadlock due to lock reversal (normally the mft record is
@@ -891,24 +891,24 @@ err_out:
* If the inode is not in icache we need to perform further checks.
*
* If the mft record is not a FILE record or it is a base mft record, we can
- * safely write it and return TRUE.
+ * safely write it and return 'true'.
*
* We now know the mft record is an extent mft record. We check if the inode
* corresponding to its base mft record is in icache and obtain a reference to
- * it if it is. If it is not, we can safely write it and return TRUE.
+ * it if it is. If it is not, we can safely write it and return 'true'.
*
* We now have the base inode for the extent mft record. We check if it has an
* ntfs inode for the extent mft record attached and if not it is safe to write
- * the extent mft record and we return TRUE.
+ * the extent mft record and we return 'true'.
*
* The ntfs inode for the extent mft record is attached to the base inode so we
* attempt to lock the extent mft record and if we find the lock was already
- * taken, it is not safe to write the extent mft record and we return FALSE.
+ * taken, it is not safe to write the extent mft record and we return 'false'.
*
* If we manage to obtain the lock we have exclusive access to the extent mft
* record, which also allows us safe writeout of the extent mft record. We
* set the ntfs inode of the extent mft record clean and then set @locked_ni to
- * the now locked ntfs inode and return TRUE.
+ * the now locked ntfs inode and return 'true'.
*
* Note, the reason for actually writing dirty mft records here and not just
* relying on the vfs inode dirty code paths is that we can have mft records
@@ -922,7 +922,7 @@ err_out:
* appear if the mft record is reused for a new inode before it got written
* out.
*/
-BOOL ntfs_may_write_mft_record(ntfs_volume *vol, const unsigned long mft_no,
+bool ntfs_may_write_mft_record(ntfs_volume *vol, const unsigned long mft_no,
const MFT_RECORD *m, ntfs_inode **locked_ni)
{
struct super_block *sb = vol->sb;
@@ -977,7 +977,7 @@ BOOL ntfs_may_write_mft_record(ntfs_volume *vol, const unsigned long mft_no,
mft_no);
atomic_dec(&ni->count);
iput(vi);
- return FALSE;
+ return false;
}
ntfs_debug("Inode 0x%lx is not dirty.", mft_no);
/* The inode is not dirty, try to take the mft record lock. */
@@ -986,7 +986,7 @@ BOOL ntfs_may_write_mft_record(ntfs_volume *vol, const unsigned long mft_no,
"not write it.", mft_no);
atomic_dec(&ni->count);
iput(vi);
- return FALSE;
+ return false;
}
ntfs_debug("Managed to lock mft record 0x%lx, write it.",
mft_no);
@@ -995,7 +995,7 @@ BOOL ntfs_may_write_mft_record(ntfs_volume *vol, const unsigned long mft_no,
* return the locked ntfs inode.
*/
*locked_ni = ni;
- return TRUE;
+ return true;
}
ntfs_debug("Inode 0x%lx is not in icache.", mft_no);
/* The inode is not in icache. */
@@ -1003,13 +1003,13 @@ BOOL ntfs_may_write_mft_record(ntfs_volume *vol, const unsigned long mft_no,
if (!ntfs_is_mft_record(m->magic)) {
ntfs_debug("Mft record 0x%lx is not a FILE record, write it.",
mft_no);
- return TRUE;
+ return true;
}
/* Write the mft record if it is a base inode. */
if (!m->base_mft_record) {
ntfs_debug("Mft record 0x%lx is a base record, write it.",
mft_no);
- return TRUE;
+ return true;
}
/*
* This is an extent mft record. Check if the inode corresponding to
@@ -1033,7 +1033,7 @@ BOOL ntfs_may_write_mft_record(ntfs_volume *vol, const unsigned long mft_no,
*/
ntfs_debug("Base inode 0x%lx is not in icache, write the "
"extent record.", na.mft_no);
- return TRUE;
+ return true;
}
ntfs_debug("Base inode 0x%lx is in icache.", na.mft_no);
/*
@@ -1051,7 +1051,7 @@ BOOL ntfs_may_write_mft_record(ntfs_volume *vol, const unsigned long mft_no,
iput(vi);
ntfs_debug("Base inode 0x%lx has no attached extent inodes, "
"write the extent record.", na.mft_no);
- return TRUE;
+ return true;
}
/* Iterate over the attached extent inodes. */
extent_nis = ni->ext.extent_ntfs_inos;
@@ -1075,7 +1075,7 @@ BOOL ntfs_may_write_mft_record(ntfs_volume *vol, const unsigned long mft_no,
ntfs_debug("Extent inode 0x%lx is not attached to its base "
"inode 0x%lx, write the extent record.",
mft_no, na.mft_no);
- return TRUE;
+ return true;
}
ntfs_debug("Extent inode 0x%lx is attached to its base inode 0x%lx.",
mft_no, na.mft_no);
@@ -1091,7 +1091,7 @@ BOOL ntfs_may_write_mft_record(ntfs_volume *vol, const unsigned long mft_no,
iput(vi);
ntfs_debug("Extent mft record 0x%lx is already locked, do "
"not write it.", mft_no);
- return FALSE;
+ return false;
}
ntfs_debug("Managed to lock extent mft record 0x%lx, write it.",
mft_no);
@@ -1103,7 +1103,7 @@ BOOL ntfs_may_write_mft_record(ntfs_volume *vol, const unsigned long mft_no,
* the locked extent ntfs inode.
*/
*locked_ni = eni;
- return TRUE;
+ return true;
}
static const char *es = " Leaving inconsistent metadata. Unmount and run "
@@ -1354,7 +1354,7 @@ static int ntfs_mft_bitmap_extend_allocation_nolock(ntfs_volume *vol)
ntfs_unmap_page(page);
/* Allocate a cluster from the DATA_ZONE. */
rl2 = ntfs_cluster_alloc(vol, rl[1].vcn, 1, lcn, DATA_ZONE,
- TRUE);
+ true);
if (IS_ERR(rl2)) {
up_write(&mftbmp_ni->runlist.lock);
ntfs_error(vol->sb, "Failed to allocate a cluster for "
@@ -1724,7 +1724,7 @@ static int ntfs_mft_data_extend_allocation_nolock(ntfs_volume *vol)
ATTR_RECORD *a = NULL;
int ret, mp_size;
u32 old_alen = 0;
- BOOL mp_rebuilt = FALSE;
+ bool mp_rebuilt = false;
ntfs_debug("Extending mft data allocation.");
mft_ni = NTFS_I(vol->mft_ino);
@@ -1780,7 +1780,7 @@ static int ntfs_mft_data_extend_allocation_nolock(ntfs_volume *vol)
old_last_vcn = rl[1].vcn;
do {
rl2 = ntfs_cluster_alloc(vol, old_last_vcn, nr, lcn, MFT_ZONE,
- TRUE);
+ true);
if (likely(!IS_ERR(rl2)))
break;
if (PTR_ERR(rl2) != -ENOSPC || nr == min_nr) {
@@ -1884,7 +1884,7 @@ static int ntfs_mft_data_extend_allocation_nolock(ntfs_volume *vol)
ret = -EOPNOTSUPP;
goto undo_alloc;
}
- mp_rebuilt = TRUE;
+ mp_rebuilt = true;
/* Generate the mapping pairs array directly into the attr record. */
ret = ntfs_mapping_pairs_build(vol, (u8*)a +
le16_to_cpu(a->data.non_resident.mapping_pairs_offset),
@@ -2255,7 +2255,7 @@ ntfs_inode *ntfs_mft_record_alloc(ntfs_volume *vol, const int mode,
unsigned int ofs;
int err;
le16 seq_no, usn;
- BOOL record_formatted = FALSE;
+ bool record_formatted = false;
if (base_ni) {
ntfs_debug("Entering (allocating an extent mft record for "
@@ -2454,7 +2454,7 @@ have_alloc_rec:
mft_ni->initialized_size = new_initialized_size;
}
write_unlock_irqrestore(&mft_ni->size_lock, flags);
- record_formatted = TRUE;
+ record_formatted = true;
/* Update the mft data attribute record to reflect the new sizes. */
m = map_mft_record(mft_ni);
if (IS_ERR(m)) {
diff --git a/fs/ntfs/mft.h b/fs/ntfs/mft.h
index 639cd1bab08b..b52bf87b99de 100644
--- a/fs/ntfs/mft.h
+++ b/fs/ntfs/mft.h
@@ -111,7 +111,7 @@ static inline int write_mft_record(ntfs_inode *ni, MFT_RECORD *m, int sync)
return err;
}
-extern BOOL ntfs_may_write_mft_record(ntfs_volume *vol,
+extern bool ntfs_may_write_mft_record(ntfs_volume *vol,
const unsigned long mft_no, const MFT_RECORD *m,
ntfs_inode **locked_ni);
diff --git a/fs/ntfs/ntfs.h b/fs/ntfs/ntfs.h
index ddd3d503097c..a12847ae467d 100644
--- a/fs/ntfs/ntfs.h
+++ b/fs/ntfs/ntfs.h
@@ -105,7 +105,7 @@ extern int pre_write_mst_fixup(NTFS_RECORD *b, const u32 size);
extern void post_write_mst_fixup(NTFS_RECORD *b);
/* From fs/ntfs/unistr.c */
-extern BOOL ntfs_are_names_equal(const ntfschar *s1, size_t s1_len,
+extern bool ntfs_are_names_equal(const ntfschar *s1, size_t s1_len,
const ntfschar *s2, size_t s2_len,
const IGNORE_CASE_BOOL ic,
const ntfschar *upcase, const u32 upcase_size);
diff --git a/fs/ntfs/quota.c b/fs/ntfs/quota.c
index d0ef4182147b..d80e3315cab0 100644
--- a/fs/ntfs/quota.c
+++ b/fs/ntfs/quota.c
@@ -31,10 +31,10 @@
* ntfs_mark_quotas_out_of_date - mark the quotas out of date on an ntfs volume
* @vol: ntfs volume on which to mark the quotas out of date
*
- * Mark the quotas out of date on the ntfs volume @vol and return TRUE on
- * success and FALSE on error.
+ * Mark the quotas out of date on the ntfs volume @vol and return 'true' on
+ * success and 'false' on error.
*/
-BOOL ntfs_mark_quotas_out_of_date(ntfs_volume *vol)
+bool ntfs_mark_quotas_out_of_date(ntfs_volume *vol)
{
ntfs_index_context *ictx;
QUOTA_CONTROL_ENTRY *qce;
@@ -46,7 +46,7 @@ BOOL ntfs_mark_quotas_out_of_date(ntfs_volume *vol)
goto done;
if (!vol->quota_ino || !vol->quota_q_ino) {
ntfs_error(vol->sb, "Quota inodes are not open.");
- return FALSE;
+ return false;
}
mutex_lock(&vol->quota_q_ino->i_mutex);
ictx = ntfs_index_ctx_get(NTFS_I(vol->quota_q_ino));
@@ -106,12 +106,12 @@ set_done:
NVolSetQuotaOutOfDate(vol);
done:
ntfs_debug("Done.");
- return TRUE;
+ return true;
err_out:
if (ictx)
ntfs_index_ctx_put(ictx);
mutex_unlock(&vol->quota_q_ino->i_mutex);
- return FALSE;
+ return false;
}
#endif /* NTFS_RW */
diff --git a/fs/ntfs/quota.h b/fs/ntfs/quota.h
index 40e4763aa222..4cbe5594c0b0 100644
--- a/fs/ntfs/quota.h
+++ b/fs/ntfs/quota.h
@@ -28,7 +28,7 @@
#include "types.h"
#include "volume.h"
-extern BOOL ntfs_mark_quotas_out_of_date(ntfs_volume *vol);
+extern bool ntfs_mark_quotas_out_of_date(ntfs_volume *vol);
#endif /* NTFS_RW */
diff --git a/fs/ntfs/runlist.c b/fs/ntfs/runlist.c
index eb52b801512b..9afd72c7ad0d 100644
--- a/fs/ntfs/runlist.c
+++ b/fs/ntfs/runlist.c
@@ -149,10 +149,10 @@ static inline runlist_element *ntfs_rl_realloc_nofail(runlist_element *rl,
*
* It is up to the caller to serialize access to the runlists @dst and @src.
*
- * Return: TRUE Success, the runlists can be merged.
- * FALSE Failure, the runlists cannot be merged.
+ * Return: true Success, the runlists can be merged.
+ * false Failure, the runlists cannot be merged.
*/
-static inline BOOL ntfs_are_rl_mergeable(runlist_element *dst,
+static inline bool ntfs_are_rl_mergeable(runlist_element *dst,
runlist_element *src)
{
BUG_ON(!dst);
@@ -160,19 +160,19 @@ static inline BOOL ntfs_are_rl_mergeable(runlist_element *dst,
/* We can merge unmapped regions even if they are misaligned. */
if ((dst->lcn == LCN_RL_NOT_MAPPED) && (src->lcn == LCN_RL_NOT_MAPPED))
- return TRUE;
+ return true;
/* If the runs are misaligned, we cannot merge them. */
if ((dst->vcn + dst->length) != src->vcn)
- return FALSE;
+ return false;
/* If both runs are non-sparse and contiguous, we can merge them. */
if ((dst->lcn >= 0) && (src->lcn >= 0) &&
((dst->lcn + dst->length) == src->lcn))
- return TRUE;
+ return true;
/* If we are merging two holes, we can merge them. */
if ((dst->lcn == LCN_HOLE) && (src->lcn == LCN_HOLE))
- return TRUE;
+ return true;
/* Cannot merge. */
- return FALSE;
+ return false;
}
/**
@@ -218,7 +218,7 @@ static inline void __ntfs_rl_merge(runlist_element *dst, runlist_element *src)
static inline runlist_element *ntfs_rl_append(runlist_element *dst,
int dsize, runlist_element *src, int ssize, int loc)
{
- BOOL right = FALSE; /* Right end of @src needs merging. */
+ bool right = false; /* Right end of @src needs merging. */
int marker; /* End of the inserted runs. */
BUG_ON(!dst);
@@ -285,8 +285,8 @@ static inline runlist_element *ntfs_rl_append(runlist_element *dst,
static inline runlist_element *ntfs_rl_insert(runlist_element *dst,
int dsize, runlist_element *src, int ssize, int loc)
{
- BOOL left = FALSE; /* Left end of @src needs merging. */
- BOOL disc = FALSE; /* Discontinuity between @dst and @src. */
+ bool left = false; /* Left end of @src needs merging. */
+ bool disc = false; /* Discontinuity between @dst and @src. */
int marker; /* End of the inserted runs. */
BUG_ON(!dst);
@@ -382,8 +382,8 @@ static inline runlist_element *ntfs_rl_replace(runlist_element *dst,
int dsize, runlist_element *src, int ssize, int loc)
{
signed delta;
- BOOL left = FALSE; /* Left end of @src needs merging. */
- BOOL right = FALSE; /* Right end of @src needs merging. */
+ bool left = false; /* Left end of @src needs merging. */
+ bool right = false; /* Right end of @src needs merging. */
int tail; /* Start of tail of @dst. */
int marker; /* End of the inserted runs. */
@@ -620,8 +620,8 @@ runlist_element *ntfs_runlists_merge(runlist_element *drl,
;
{
- BOOL start;
- BOOL finish;
+ bool start;
+ bool finish;
int ds = dend + 1; /* Number of elements in drl & srl */
int ss = sfinal - sstart + 1;
@@ -635,7 +635,7 @@ runlist_element *ntfs_runlists_merge(runlist_element *drl,
if (finish && !drl[dins].length)
ss++;
if (marker && (drl[dins].vcn + drl[dins].length > srl[send - 1].vcn))
- finish = FALSE;
+ finish = false;
#if 0
ntfs_debug("dfinal = %i, dend = %i", dfinal, dend);
ntfs_debug("sstart = %i, sfinal = %i, send = %i", sstart, sfinal, send);
@@ -1134,7 +1134,7 @@ int ntfs_get_size_for_mapping_pairs(const ntfs_volume *vol,
{
LCN prev_lcn;
int rls;
- BOOL the_end = FALSE;
+ bool the_end = false;
BUG_ON(first_vcn < 0);
BUG_ON(last_vcn < -1);
@@ -1168,7 +1168,7 @@ int ntfs_get_size_for_mapping_pairs(const ntfs_volume *vol,
s64 s1 = last_vcn + 1;
if (unlikely(rl[1].vcn > s1))
length = s1 - rl->vcn;
- the_end = TRUE;
+ the_end = true;
}
delta = first_vcn - rl->vcn;
/* Header byte + length. */
@@ -1204,7 +1204,7 @@ int ntfs_get_size_for_mapping_pairs(const ntfs_volume *vol,
s64 s1 = last_vcn + 1;
if (unlikely(rl[1].vcn > s1))
length = s1 - rl->vcn;
- the_end = TRUE;
+ the_end = true;
}
/* Header byte + length. */
rls += 1 + ntfs_get_nr_significant_bytes(length);
@@ -1327,7 +1327,7 @@ int ntfs_mapping_pairs_build(const ntfs_volume *vol, s8 *dst,
LCN prev_lcn;
s8 *dst_max, *dst_next;
int err = -ENOSPC;
- BOOL the_end = FALSE;
+ bool the_end = false;
s8 len_len, lcn_len;
BUG_ON(first_vcn < 0);
@@ -1370,7 +1370,7 @@ int ntfs_mapping_pairs_build(const ntfs_volume *vol, s8 *dst,
s64 s1 = last_vcn + 1;
if (unlikely(rl[1].vcn > s1))
length = s1 - rl->vcn;
- the_end = TRUE;
+ the_end = true;
}
delta = first_vcn - rl->vcn;
/* Write length. */
@@ -1422,7 +1422,7 @@ int ntfs_mapping_pairs_build(const ntfs_volume *vol, s8 *dst,
s64 s1 = last_vcn + 1;
if (unlikely(rl[1].vcn > s1))
length = s1 - rl->vcn;
- the_end = TRUE;
+ the_end = true;
}
/* Write length. */
len_len = ntfs_write_significant_bytes(dst + 1, dst_max,
@@ -1541,7 +1541,7 @@ int ntfs_rl_truncate_nolock(const ntfs_volume *vol, runlist *const runlist,
*/
if (rl->length) {
runlist_element *trl;
- BOOL is_end;
+ bool is_end;
ntfs_debug("Shrinking runlist.");
/* Determine the runlist size. */
@@ -1555,11 +1555,11 @@ int ntfs_rl_truncate_nolock(const ntfs_volume *vol, runlist *const runlist,
* If a run was partially truncated, make the following runlist
* element a terminator.
*/
- is_end = FALSE;
+ is_end = false;
if (rl->length) {
rl++;
if (!rl->length)
- is_end = TRUE;
+ is_end = true;
rl->vcn = new_length;
rl->length = 0;
}
@@ -1648,7 +1648,7 @@ int ntfs_rl_punch_nolock(const ntfs_volume *vol, runlist *const runlist,
s64 delta;
runlist_element *rl, *rl_end, *rl_real_end, *trl;
int old_size;
- BOOL lcn_fixup = FALSE;
+ bool lcn_fixup = false;
ntfs_debug("Entering for start 0x%llx, length 0x%llx.",
(long long)start, (long long)length);
@@ -1862,7 +1862,7 @@ split_end:
if (rl->lcn >= 0) {
rl->lcn -= delta;
/* Need this in case the lcn just became negative. */
- lcn_fixup = TRUE;
+ lcn_fixup = true;
}
rl->length += delta;
goto split_end;
diff --git a/fs/ntfs/super.c b/fs/ntfs/super.c
index 6b2712f10dd2..03a391ac7145 100644
--- a/fs/ntfs/super.c
+++ b/fs/ntfs/super.c
@@ -74,18 +74,18 @@ const option_t on_errors_arr[] = {
*
* Copied from old ntfs driver (which copied from vfat driver).
*/
-static int simple_getbool(char *s, BOOL *setval)
+static int simple_getbool(char *s, bool *setval)
{
if (s) {
if (!strcmp(s, "1") || !strcmp(s, "yes") || !strcmp(s, "true"))
- *setval = TRUE;
+ *setval = true;
else if (!strcmp(s, "0") || !strcmp(s, "no") ||
!strcmp(s, "false"))
- *setval = FALSE;
+ *setval = false;
else
return 0;
} else
- *setval = TRUE;
+ *setval = true;
return 1;
}
@@ -96,7 +96,7 @@ static int simple_getbool(char *s, BOOL *setval)
*
* Parse the recognized options in @opt for the ntfs volume described by @vol.
*/
-static BOOL parse_options(ntfs_volume *vol, char *opt)
+static bool parse_options(ntfs_volume *vol, char *opt)
{
char *p, *v, *ov;
static char *utf8 = "utf8";
@@ -137,7 +137,7 @@ static BOOL parse_options(ntfs_volume *vol, char *opt)
}
#define NTFS_GETOPT_BOOL(option, variable) \
if (!strcmp(p, option)) { \
- BOOL val; \
+ bool val; \
if (!simple_getbool(v, &val)) \
goto needs_bool; \
variable = val; \
@@ -170,7 +170,7 @@ static BOOL parse_options(ntfs_volume *vol, char *opt)
else NTFS_GETOPT_OCTAL("fmask", fmask)
else NTFS_GETOPT_OCTAL("dmask", dmask)
else NTFS_GETOPT("mft_zone_multiplier", mft_zone_multiplier)
- else NTFS_GETOPT_WITH_DEFAULT("sloppy", sloppy, TRUE)
+ else NTFS_GETOPT_WITH_DEFAULT("sloppy", sloppy, true)
else NTFS_GETOPT_BOOL("show_sys_files", show_sys_files)
else NTFS_GETOPT_BOOL("case_sensitive", case_sensitive)
else NTFS_GETOPT_BOOL("disable_sparse", disable_sparse)
@@ -194,7 +194,7 @@ use_utf8:
if (!old_nls) {
ntfs_error(vol->sb, "NLS character set "
"%s not found.", v);
- return FALSE;
+ return false;
}
ntfs_error(vol->sb, "NLS character set %s not "
"found. Using previous one %s.",
@@ -205,14 +205,14 @@ use_utf8:
unload_nls(old_nls);
}
} else if (!strcmp(p, "utf8")) {
- BOOL val = FALSE;
+ bool val = false;
ntfs_warning(vol->sb, "Option utf8 is no longer "
"supported, using option nls=utf8. Please "
"use option nls=utf8 in the future and "
"make sure utf8 is compiled either as a "
"module or into the kernel.");
if (!v || !*v)
- val = TRUE;
+ val = true;
else if (!simple_getbool(v, &val))
goto needs_bool;
if (val) {
@@ -231,7 +231,7 @@ use_utf8:
}
no_mount_options:
if (errors && !sloppy)
- return FALSE;
+ return false;
if (sloppy)
ntfs_warning(vol->sb, "Sloppy option given. Ignoring "
"unrecognized mount option(s) and continuing.");
@@ -240,14 +240,14 @@ no_mount_options:
if (!on_errors) {
ntfs_error(vol->sb, "Invalid errors option argument "
"or bug in options parser.");
- return FALSE;
+ return false;
}
}
if (nls_map) {
if (vol->nls_map && vol->nls_map != nls_map) {
ntfs_error(vol->sb, "Cannot change NLS character set "
"on remount.");
- return FALSE;
+ return false;
} /* else (!vol->nls_map) */
ntfs_debug("Using NLS character set %s.", nls_map->charset);
vol->nls_map = nls_map;
@@ -257,7 +257,7 @@ no_mount_options:
if (!vol->nls_map) {
ntfs_error(vol->sb, "Failed to load default "
"NLS character set.");
- return FALSE;
+ return false;
}
ntfs_debug("Using default NLS character set (%s).",
vol->nls_map->charset);
@@ -268,7 +268,7 @@ no_mount_options:
mft_zone_multiplier) {
ntfs_error(vol->sb, "Cannot change mft_zone_multiplier "
"on remount.");
- return FALSE;
+ return false;
}
if (mft_zone_multiplier < 1 || mft_zone_multiplier > 4) {
ntfs_error(vol->sb, "Invalid mft_zone_multiplier. "
@@ -318,16 +318,16 @@ no_mount_options:
NVolSetSparseEnabled(vol);
}
}
- return TRUE;
+ return true;
needs_arg:
ntfs_error(vol->sb, "The %s option requires an argument.", p);
- return FALSE;
+ return false;
needs_bool:
ntfs_error(vol->sb, "The %s option requires a boolean argument.", p);
- return FALSE;
+ return false;
needs_val:
ntfs_error(vol->sb, "Invalid %s option argument: %s", p, ov);
- return FALSE;
+ return false;
}
#ifdef NTFS_RW
@@ -543,16 +543,16 @@ static int ntfs_remount(struct super_block *sb, int *flags, char *opt)
* is_boot_sector_ntfs - check whether a boot sector is a valid NTFS boot sector
* @sb: Super block of the device to which @b belongs.
* @b: Boot sector of device @sb to check.
- * @silent: If TRUE, all output will be silenced.
+ * @silent: If 'true', all output will be silenced.
*
* is_boot_sector_ntfs() checks whether the boot sector @b is a valid NTFS boot
- * sector. Returns TRUE if it is valid and FALSE if not.
+ * sector. Returns 'true' if it is valid and 'false' if not.
*
* @sb is only needed for warning/error output, i.e. it can be NULL when silent
- * is TRUE.
+ * is 'true'.
*/
-static BOOL is_boot_sector_ntfs(const struct super_block *sb,
- const NTFS_BOOT_SECTOR *b, const BOOL silent)
+static bool is_boot_sector_ntfs(const struct super_block *sb,
+ const NTFS_BOOT_SECTOR *b, const bool silent)
{
/*
* Check that checksum == sum of u32 values from b to the checksum
@@ -620,9 +620,9 @@ static BOOL is_boot_sector_ntfs(const struct super_block *sb,
*/
if (!silent && b->end_of_sector_marker != const_cpu_to_le16(0xaa55))
ntfs_warning(sb, "Invalid end of sector marker.");
- return TRUE;
+ return true;
not_ntfs:
- return FALSE;
+ return false;
}
/**
@@ -732,9 +732,9 @@ hotfix_primary_boot_sector:
* @b: boot sector to parse
*
* Parse the ntfs boot sector @b and store all imporant information therein in
- * the ntfs super block @vol. Return TRUE on success and FALSE on error.
+ * the ntfs super block @vol. Return 'true' on success and 'false' on error.
*/
-static BOOL parse_ntfs_boot_sector(ntfs_volume *vol, const NTFS_BOOT_SECTOR *b)
+static bool parse_ntfs_boot_sector(ntfs_volume *vol, const NTFS_BOOT_SECTOR *b)
{
unsigned int sectors_per_cluster_bits, nr_hidden_sects;
int clusters_per_mft_record, clusters_per_index_record;
@@ -751,7 +751,7 @@ static BOOL parse_ntfs_boot_sector(ntfs_volume *vol, const NTFS_BOOT_SECTOR *b)
"device block size (%lu). This is not "
"supported. Sorry.", vol->sector_size,
vol->sb->s_blocksize);
- return FALSE;
+ return false;
}
ntfs_debug("sectors_per_cluster = 0x%x", b->bpb.sectors_per_cluster);
sectors_per_cluster_bits = ffs(b->bpb.sectors_per_cluster) - 1;
@@ -770,7 +770,7 @@ static BOOL parse_ntfs_boot_sector(ntfs_volume *vol, const NTFS_BOOT_SECTOR *b)
ntfs_error(vol->sb, "Cluster size (%i) is smaller than the "
"sector size (%i). This is not supported. "
"Sorry.", vol->cluster_size, vol->sector_size);
- return FALSE;
+ return false;
}
clusters_per_mft_record = b->clusters_per_mft_record;
ntfs_debug("clusters_per_mft_record = %i (0x%x)",
@@ -802,7 +802,7 @@ static BOOL parse_ntfs_boot_sector(ntfs_volume *vol, const NTFS_BOOT_SECTOR *b)
"PAGE_CACHE_SIZE on your system (%lu). "
"This is not supported. Sorry.",
vol->mft_record_size, PAGE_CACHE_SIZE);
- return FALSE;
+ return false;
}
/* We cannot support mft record sizes below the sector size. */
if (vol->mft_record_size < vol->sector_size) {
@@ -810,7 +810,7 @@ static BOOL parse_ntfs_boot_sector(ntfs_volume *vol, const NTFS_BOOT_SECTOR *b)
"sector size (%i). This is not supported. "
"Sorry.", vol->mft_record_size,
vol->sector_size);
- return FALSE;
+ return false;
}
clusters_per_index_record = b->clusters_per_index_record;
ntfs_debug("clusters_per_index_record = %i (0x%x)",
@@ -841,7 +841,7 @@ static BOOL parse_ntfs_boot_sector(ntfs_volume *vol, const NTFS_BOOT_SECTOR *b)
"the sector size (%i). This is not "
"supported. Sorry.", vol->index_record_size,
vol->sector_size);
- return FALSE;
+ return false;
}
/*
* Get the size of the volume in clusters and check for 64-bit-ness.
@@ -851,7 +851,7 @@ static BOOL parse_ntfs_boot_sector(ntfs_volume *vol, const NTFS_BOOT_SECTOR *b)
ll = sle64_to_cpu(b->number_of_sectors) >> sectors_per_cluster_bits;
if ((u64)ll >= 1ULL << 32) {
ntfs_error(vol->sb, "Cannot handle 64-bit clusters. Sorry.");
- return FALSE;
+ return false;
}
vol->nr_clusters = ll;
ntfs_debug("vol->nr_clusters = 0x%llx", (long long)vol->nr_clusters);
@@ -867,7 +867,7 @@ static BOOL parse_ntfs_boot_sector(ntfs_volume *vol, const NTFS_BOOT_SECTOR *b)
"Maximum supported is 2TiB. Sorry.",
(unsigned long long)ll >> (40 -
vol->cluster_size_bits));
- return FALSE;
+ return false;
}
}
ll = sle64_to_cpu(b->mft_lcn);
@@ -875,7 +875,7 @@ static BOOL parse_ntfs_boot_sector(ntfs_volume *vol, const NTFS_BOOT_SECTOR *b)
ntfs_error(vol->sb, "MFT LCN (%lli, 0x%llx) is beyond end of "
"volume. Weird.", (unsigned long long)ll,
(unsigned long long)ll);
- return FALSE;
+ return false;
}
vol->mft_lcn = ll;
ntfs_debug("vol->mft_lcn = 0x%llx", (long long)vol->mft_lcn);
@@ -884,7 +884,7 @@ static BOOL parse_ntfs_boot_sector(ntfs_volume *vol, const NTFS_BOOT_SECTOR *b)
ntfs_error(vol->sb, "MFTMirr LCN (%lli, 0x%llx) is beyond end "
"of volume. Weird.", (unsigned long long)ll,
(unsigned long long)ll);
- return FALSE;
+ return false;
}
vol->mftmirr_lcn = ll;
ntfs_debug("vol->mftmirr_lcn = 0x%llx", (long long)vol->mftmirr_lcn);
@@ -907,7 +907,7 @@ static BOOL parse_ntfs_boot_sector(ntfs_volume *vol, const NTFS_BOOT_SECTOR *b)
vol->serial_no = le64_to_cpu(b->volume_serial_number);
ntfs_debug("vol->serial_no = 0x%llx",
(unsigned long long)vol->serial_no);
- return TRUE;
+ return true;
}
/**
@@ -1000,9 +1000,9 @@ static void ntfs_setup_allocators(ntfs_volume *vol)
* load_and_init_mft_mirror - load and setup the mft mirror inode for a volume
* @vol: ntfs super block describing device whose mft mirror to load
*
- * Return TRUE on success or FALSE on error.
+ * Return 'true' on success or 'false' on error.
*/
-static BOOL load_and_init_mft_mirror(ntfs_volume *vol)
+static bool load_and_init_mft_mirror(ntfs_volume *vol)
{
struct inode *tmp_ino;
ntfs_inode *tmp_ni;
@@ -1014,7 +1014,7 @@ static BOOL load_and_init_mft_mirror(ntfs_volume *vol)
if (!IS_ERR(tmp_ino))
iput(tmp_ino);
/* Caller will display error message. */
- return FALSE;
+ return false;
}
/*
* Re-initialize some specifics about $MFTMirr's inode as
@@ -1041,20 +1041,20 @@ static BOOL load_and_init_mft_mirror(ntfs_volume *vol)
tmp_ni->itype.index.block_size_bits = vol->mft_record_size_bits;
vol->mftmirr_ino = tmp_ino;
ntfs_debug("Done.");
- return TRUE;
+ return true;
}
/**
* check_mft_mirror - compare contents of the mft mirror with the mft
* @vol: ntfs super block describing device whose mft mirror to check
*
- * Return TRUE on success or FALSE on error.
+ * Return 'true' on success or 'false' on error.
*
* Note, this function also results in the mft mirror runlist being completely
* mapped into memory. The mft mirror write code requires this and will BUG()
* should it find an unmapped runlist element.
*/
-static BOOL check_mft_mirror(ntfs_volume *vol)
+static bool check_mft_mirror(ntfs_volume *vol)
{
struct super_block *sb = vol->sb;
ntfs_inode *mirr_ni;
@@ -1086,7 +1086,7 @@ static BOOL check_mft_mirror(ntfs_volume *vol)
index);
if (IS_ERR(mft_page)) {
ntfs_error(sb, "Failed to read $MFT.");
- return FALSE;
+ return false;
}
kmft = page_address(mft_page);
/* Get the $MFTMirr page. */
@@ -1110,7 +1110,7 @@ mm_unmap_out:
ntfs_unmap_page(mirr_page);
mft_unmap_out:
ntfs_unmap_page(mft_page);
- return FALSE;
+ return false;
}
}
/* Do not check the mirror record if it is not in use. */
@@ -1169,21 +1169,21 @@ mft_unmap_out:
ntfs_error(sb, "$MFTMirr location mismatch. "
"Run chkdsk.");
up_read(&mirr_ni->runlist.lock);
- return FALSE;
+ return false;
}
} while (rl2[i++].length);
up_read(&mirr_ni->runlist.lock);
ntfs_debug("Done.");
- return TRUE;
+ return true;
}
/**
* load_and_check_logfile - load and check the logfile inode for a volume
* @vol: ntfs super block describing device whose logfile to load
*
- * Return TRUE on success or FALSE on error.
+ * Return 'true' on success or 'false' on error.
*/
-static BOOL load_and_check_logfile(ntfs_volume *vol,
+static bool load_and_check_logfile(ntfs_volume *vol,
RESTART_PAGE_HEADER **rp)
{
struct inode *tmp_ino;
@@ -1194,17 +1194,17 @@ static BOOL load_and_check_logfile(ntfs_volume *vol,
if (!IS_ERR(tmp_ino))
iput(tmp_ino);
/* Caller will display error message. */
- return FALSE;
+ return false;
}
if (!ntfs_check_logfile(tmp_ino, rp)) {
iput(tmp_ino);
/* ntfs_check_logfile() will have displayed error output. */
- return FALSE;
+ return false;
}
NInoSetSparseDisabled(NTFS_I(tmp_ino));
vol->logfile_ino = tmp_ino;
ntfs_debug("Done.");
- return TRUE;
+ return true;
}
#define NTFS_HIBERFIL_HEADER_SIZE 4096
@@ -1329,10 +1329,10 @@ iput_out:
* load_and_init_quota - load and setup the quota file for a volume if present
* @vol: ntfs super block describing device whose quota file to load
*
- * Return TRUE on success or FALSE on error. If $Quota is not present, we
+ * Return 'true' on success or 'false' on error. If $Quota is not present, we
* leave vol->quota_ino as NULL and return success.
*/
-static BOOL load_and_init_quota(ntfs_volume *vol)
+static bool load_and_init_quota(ntfs_volume *vol)
{
MFT_REF mref;
struct inode *tmp_ino;
@@ -1366,11 +1366,11 @@ static BOOL load_and_init_quota(ntfs_volume *vol)
* not enabled.
*/
NVolSetQuotaOutOfDate(vol);
- return TRUE;
+ return true;
}
/* A real error occured. */
ntfs_error(vol->sb, "Failed to find inode number for $Quota.");
- return FALSE;
+ return false;
}
/* We do not care for the type of match that was found. */
kfree(name);
@@ -1380,25 +1380,25 @@ static BOOL load_and_init_quota(ntfs_volume *vol)
if (!IS_ERR(tmp_ino))
iput(tmp_ino);
ntfs_error(vol->sb, "Failed to load $Quota.");
- return FALSE;
+ return false;
}
vol->quota_ino = tmp_ino;
/* Get the $Q index allocation attribute. */
tmp_ino = ntfs_index_iget(vol->quota_ino, Q, 2);
if (IS_ERR(tmp_ino)) {
ntfs_error(vol->sb, "Failed to load $Quota/$Q index.");
- return FALSE;
+ return false;
}
vol->quota_q_ino = tmp_ino;
ntfs_debug("Done.");
- return TRUE;
+ return true;
}
/**
* load_and_init_usnjrnl - load and setup the transaction log if present
* @vol: ntfs super block describing device whose usnjrnl file to load
*
- * Return TRUE on success or FALSE on error.
+ * Return 'true' on success or 'false' on error.
*
* If $UsnJrnl is not present or in the process of being disabled, we set
* NVolUsnJrnlStamped() and return success.
@@ -1408,7 +1408,7 @@ static BOOL load_and_init_quota(ntfs_volume *vol)
* stamped and nothing has been logged since, we also set NVolUsnJrnlStamped()
* and return success.
*/
-static BOOL load_and_init_usnjrnl(ntfs_volume *vol)
+static bool load_and_init_usnjrnl(ntfs_volume *vol)
{
MFT_REF mref;
struct inode *tmp_ino;
@@ -1450,12 +1450,12 @@ not_enabled:
* transaction logging is not enabled.
*/
NVolSetUsnJrnlStamped(vol);
- return TRUE;
+ return true;
}
/* A real error occured. */
ntfs_error(vol->sb, "Failed to find inode number for "
"$UsnJrnl.");
- return FALSE;
+ return false;
}
/* We do not care for the type of match that was found. */
kfree(name);
@@ -1465,7 +1465,7 @@ not_enabled:
if (!IS_ERR(tmp_ino))
iput(tmp_ino);
ntfs_error(vol->sb, "Failed to load $UsnJrnl.");
- return FALSE;
+ return false;
}
vol->usnjrnl_ino = tmp_ino;
/*
@@ -1483,7 +1483,7 @@ not_enabled:
if (IS_ERR(tmp_ino)) {
ntfs_error(vol->sb, "Failed to load $UsnJrnl/$DATA/$Max "
"attribute.");
- return FALSE;
+ return false;
}
vol->usnjrnl_max_ino = tmp_ino;
if (unlikely(i_size_read(tmp_ino) < sizeof(USN_HEADER))) {
@@ -1491,14 +1491,14 @@ not_enabled:
"attribute (size is 0x%llx but should be at "
"least 0x%zx bytes).", i_size_read(tmp_ino),
sizeof(USN_HEADER));
- return FALSE;
+ return false;
}
/* Get the $DATA/$J attribute. */
tmp_ino = ntfs_attr_iget(vol->usnjrnl_ino, AT_DATA, J, 2);
if (IS_ERR(tmp_ino)) {
ntfs_error(vol->sb, "Failed to load $UsnJrnl/$DATA/$J "
"attribute.");
- return FALSE;
+ return false;
}
vol->usnjrnl_j_ino = tmp_ino;
/* Verify $J is non-resident and sparse. */
@@ -1506,14 +1506,14 @@ not_enabled:
if (unlikely(!NInoNonResident(tmp_ni) || !NInoSparse(tmp_ni))) {
ntfs_error(vol->sb, "$UsnJrnl/$DATA/$J attribute is resident "
"and/or not sparse.");
- return FALSE;
+ return false;
}
/* Read the USN_HEADER from $DATA/$Max. */
page = ntfs_map_page(vol->usnjrnl_max_ino->i_mapping, 0);
if (IS_ERR(page)) {
ntfs_error(vol->sb, "Failed to read from $UsnJrnl/$DATA/$Max "
"attribute.");
- return FALSE;
+ return false;
}
uh = (USN_HEADER*)page_address(page);
/* Sanity check the $Max. */
@@ -1524,7 +1524,7 @@ not_enabled:
(long long)sle64_to_cpu(uh->allocation_delta),
(long long)sle64_to_cpu(uh->maximum_size));
ntfs_unmap_page(page);
- return FALSE;
+ return false;
}
/*
* If the transaction log has been stamped and nothing has been written
@@ -1548,20 +1548,20 @@ not_enabled:
(long long)sle64_to_cpu(uh->lowest_valid_usn),
i_size_read(vol->usnjrnl_j_ino));
ntfs_unmap_page(page);
- return FALSE;
+ return false;
}
ntfs_unmap_page(page);
ntfs_debug("Done.");
- return TRUE;
+ return true;
}
/**
* load_and_init_attrdef - load the attribute definitions table for a volume
* @vol: ntfs super block describing device whose attrdef to load
*
- * Return TRUE on success or FALSE on error.
+ * Return 'true' on success or 'false' on error.
*/
-static BOOL load_and_init_attrdef(ntfs_volume *vol)
+static bool load_and_init_attrdef(ntfs_volume *vol)
{
loff_t i_size;
struct super_block *sb = vol->sb;
@@ -1607,7 +1607,7 @@ read_partial_attrdef_page:
vol->attrdef_size = i_size;
ntfs_debug("Read %llu bytes from $AttrDef.", i_size);
iput(ino);
- return TRUE;
+ return true;
free_iput_failed:
ntfs_free(vol->attrdef);
vol->attrdef = NULL;
@@ -1615,7 +1615,7 @@ iput_failed:
iput(ino);
failed:
ntfs_error(sb, "Failed to initialize attribute definition table.");
- return FALSE;
+ return false;
}
#endif /* NTFS_RW */
@@ -1624,9 +1624,9 @@ failed:
* load_and_init_upcase - load the upcase table for an ntfs volume
* @vol: ntfs super block describing device whose upcase to load
*
- * Return TRUE on success or FALSE on error.
+ * Return 'true' on success or 'false' on error.
*/
-static BOOL load_and_init_upcase(ntfs_volume *vol)
+static bool load_and_init_upcase(ntfs_volume *vol)
{
loff_t i_size;
struct super_block *sb = vol->sb;
@@ -1682,7 +1682,7 @@ read_partial_upcase_page:
ntfs_debug("Using volume specified $UpCase since default is "
"not present.");
mutex_unlock(&ntfs_lock);
- return TRUE;
+ return true;
}
max = default_upcase_len;
if (max > vol->upcase_len)
@@ -1698,12 +1698,12 @@ read_partial_upcase_page:
mutex_unlock(&ntfs_lock);
ntfs_debug("Volume specified $UpCase matches default. Using "
"default.");
- return TRUE;
+ return true;
}
mutex_unlock(&ntfs_lock);
ntfs_debug("Using volume specified $UpCase since it does not match "
"the default.");
- return TRUE;
+ return true;
iput_upcase_failed:
iput(ino);
ntfs_free(vol->upcase);
@@ -1717,11 +1717,11 @@ upcase_failed:
mutex_unlock(&ntfs_lock);
ntfs_error(sb, "Failed to load $UpCase from the volume. Using "
"default.");
- return TRUE;
+ return true;
}
mutex_unlock(&ntfs_lock);
ntfs_error(sb, "Failed to initialize upcase table.");
- return FALSE;
+ return false;
}
/*
@@ -1739,9 +1739,9 @@ static struct lock_class_key
* Open the system files with normal access functions and complete setting up
* the ntfs super block @vol.
*
- * Return TRUE on success or FALSE on error.
+ * Return 'true' on success or 'false' on error.
*/
-static BOOL load_system_files(ntfs_volume *vol)
+static bool load_system_files(ntfs_volume *vol)
{
struct super_block *sb = vol->sb;
MFT_RECORD *m;
@@ -2067,7 +2067,7 @@ get_ctx_vol_failed:
#endif /* NTFS_RW */
/* If on NTFS versions before 3.0, we are done. */
if (unlikely(vol->major_ver < 3))
- return TRUE;
+ return true;
/* NTFS 3.0+ specific initialization. */
/* Get the security descriptors inode. */
vol->secure_ino = ntfs_iget(sb, FILE_Secure);
@@ -2173,7 +2173,7 @@ get_ctx_vol_failed:
NVolSetErrors(vol);
}
#endif /* NTFS_RW */
- return TRUE;
+ return true;
#ifdef NTFS_RW
iput_usnjrnl_err_out:
if (vol->usnjrnl_j_ino)
@@ -2229,7 +2229,7 @@ iput_mirr_err_out:
if (vol->mftmirr_ino)
iput(vol->mftmirr_ino);
#endif /* NTFS_RW */
- return FALSE;
+ return false;
}
/**
diff --git a/fs/ntfs/types.h b/fs/ntfs/types.h
index 6e4a7e3343f2..8c8053b66984 100644
--- a/fs/ntfs/types.h
+++ b/fs/ntfs/types.h
@@ -62,11 +62,6 @@ typedef s64 USN;
typedef sle64 leUSN;
typedef enum {
- FALSE = 0,
- TRUE = 1
-} BOOL;
-
-typedef enum {
CASE_SENSITIVE = 0,
IGNORE_CASE = 1,
} IGNORE_CASE_BOOL;
diff --git a/fs/ntfs/unistr.c b/fs/ntfs/unistr.c
index a1b572196fe4..6a495f7369f9 100644
--- a/fs/ntfs/unistr.c
+++ b/fs/ntfs/unistr.c
@@ -61,16 +61,16 @@ static const u8 legal_ansi_char_array[0x40] = {
* @upcase: upcase table (only if @ic == IGNORE_CASE)
* @upcase_size: length in Unicode characters of @upcase (if present)
*
- * Compare the names @s1 and @s2 and return TRUE (1) if the names are
- * identical, or FALSE (0) if they are not identical. If @ic is IGNORE_CASE,
+ * Compare the names @s1 and @s2 and return 'true' (1) if the names are
+ * identical, or 'false' (0) if they are not identical. If @ic is IGNORE_CASE,
* the @upcase table is used to performa a case insensitive comparison.
*/
-BOOL ntfs_are_names_equal(const ntfschar *s1, size_t s1_len,
+bool ntfs_are_names_equal(const ntfschar *s1, size_t s1_len,
const ntfschar *s2, size_t s2_len, const IGNORE_CASE_BOOL ic,
const ntfschar *upcase, const u32 upcase_size)
{
if (s1_len != s2_len)
- return FALSE;
+ return false;
if (ic == CASE_SENSITIVE)
return !ntfs_ucsncmp(s1, s2, s1_len);
return !ntfs_ucsncasecmp(s1, s2, s1_len, upcase, upcase_size);
diff --git a/fs/ntfs/usnjrnl.c b/fs/ntfs/usnjrnl.c
index 77773240d139..b2bc0d55b036 100644
--- a/fs/ntfs/usnjrnl.c
+++ b/fs/ntfs/usnjrnl.c
@@ -39,12 +39,12 @@
* @vol: ntfs volume on which to stamp the transaction log
*
* Stamp the transaction log ($UsnJrnl) on the ntfs volume @vol and return
- * TRUE on success and FALSE on error.
+ * 'true' on success and 'false' on error.
*
* This function assumes that the transaction log has already been loaded and
* consistency checked by a call to fs/ntfs/super.c::load_and_init_usnjrnl().
*/
-BOOL ntfs_stamp_usnjrnl(ntfs_volume *vol)
+bool ntfs_stamp_usnjrnl(ntfs_volume *vol)
{
ntfs_debug("Entering.");
if (likely(!NVolUsnJrnlStamped(vol))) {
@@ -56,7 +56,7 @@ BOOL ntfs_stamp_usnjrnl(ntfs_volume *vol)
if (IS_ERR(page)) {
ntfs_error(vol->sb, "Failed to read from "
"$UsnJrnl/$DATA/$Max attribute.");
- return FALSE;
+ return false;
}
uh = (USN_HEADER*)page_address(page);
stamp = get_current_ntfs_time();
@@ -78,7 +78,7 @@ BOOL ntfs_stamp_usnjrnl(ntfs_volume *vol)
NVolSetUsnJrnlStamped(vol);
}
ntfs_debug("Done.");
- return TRUE;
+ return true;
}
#endif /* NTFS_RW */
diff --git a/fs/ntfs/usnjrnl.h b/fs/ntfs/usnjrnl.h
index ff988b0deb45..3a8af75351e8 100644
--- a/fs/ntfs/usnjrnl.h
+++ b/fs/ntfs/usnjrnl.h
@@ -198,7 +198,7 @@ typedef struct {
/* sizeof() = 60 (0x3c) bytes */
} __attribute__ ((__packed__)) USN_RECORD;
-extern BOOL ntfs_stamp_usnjrnl(ntfs_volume *vol);
+extern bool ntfs_stamp_usnjrnl(ntfs_volume *vol);
#endif /* NTFS_RW */
diff --git a/fs/ocfs2/dlm/dlmfs.c b/fs/ocfs2/dlm/dlmfs.c
index 0368c6402182..16b8d1ba7066 100644
--- a/fs/ocfs2/dlm/dlmfs.c
+++ b/fs/ocfs2/dlm/dlmfs.c
@@ -338,7 +338,7 @@ static struct inode *dlmfs_get_root_inode(struct super_block *sb)
inode->i_blocks = 0;
inode->i_mapping->backing_dev_info = &dlmfs_backing_dev_info;
inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
- inode->i_nlink++;
+ inc_nlink(inode);
inode->i_fop = &simple_dir_operations;
inode->i_op = &dlmfs_root_inode_operations;
@@ -395,7 +395,7 @@ static struct inode *dlmfs_get_inode(struct inode *parent,
/* directory inodes start off with i_nlink ==
* 2 (for "." entry) */
- inode->i_nlink++;
+ inc_nlink(inode);
break;
}
@@ -449,7 +449,7 @@ static int dlmfs_mkdir(struct inode * dir,
}
ip->ip_dlm = dlm;
- dir->i_nlink++;
+ inc_nlink(dir);
d_instantiate(dentry, inode);
dget(dentry); /* Extra count - pin the dentry in core */
diff --git a/fs/ocfs2/file.c b/fs/ocfs2/file.c
index 2bbfa17090cf..d9ba0a931a03 100644
--- a/fs/ocfs2/file.c
+++ b/fs/ocfs2/file.c
@@ -961,25 +961,23 @@ static inline int ocfs2_write_should_remove_suid(struct inode *inode)
}
static ssize_t ocfs2_file_aio_write(struct kiocb *iocb,
- const char __user *buf,
- size_t count,
+ const struct iovec *iov,
+ unsigned long nr_segs,
loff_t pos)
{
- struct iovec local_iov = { .iov_base = (void __user *)buf,
- .iov_len = count };
int ret, rw_level = -1, meta_level = -1, have_alloc_sem = 0;
u32 clusters;
struct file *filp = iocb->ki_filp;
struct inode *inode = filp->f_dentry->d_inode;
loff_t newsize, saved_pos;
- mlog_entry("(0x%p, 0x%p, %u, '%.*s')\n", filp, buf,
- (unsigned int)count,
+ mlog_entry("(0x%p, %u, '%.*s')\n", filp,
+ (unsigned int)nr_segs,
filp->f_dentry->d_name.len,
filp->f_dentry->d_name.name);
/* happy write of zero bytes */
- if (count == 0)
+ if (iocb->ki_left == 0)
return 0;
if (!inode) {
@@ -1048,7 +1046,7 @@ static ssize_t ocfs2_file_aio_write(struct kiocb *iocb,
} else {
saved_pos = iocb->ki_pos;
}
- newsize = count + saved_pos;
+ newsize = iocb->ki_left + saved_pos;
mlog(0, "pos=%lld newsize=%lld cursize=%lld\n",
(long long) saved_pos, (long long) newsize,
@@ -1081,7 +1079,7 @@ static ssize_t ocfs2_file_aio_write(struct kiocb *iocb,
if (!clusters)
break;
- ret = ocfs2_extend_file(inode, NULL, newsize, count);
+ ret = ocfs2_extend_file(inode, NULL, newsize, iocb->ki_left);
if (ret < 0) {
if (ret != -ENOSPC)
mlog_errno(ret);
@@ -1098,7 +1096,7 @@ static ssize_t ocfs2_file_aio_write(struct kiocb *iocb,
/* communicate with ocfs2_dio_end_io */
ocfs2_iocb_set_rw_locked(iocb);
- ret = generic_file_aio_write_nolock(iocb, &local_iov, 1, &iocb->ki_pos);
+ ret = generic_file_aio_write_nolock(iocb, iov, nr_segs, iocb->ki_pos);
/* buffered aio wouldn't have proper lock coverage today */
BUG_ON(ret == -EIOCBQUEUED && !(filp->f_flags & O_DIRECT));
@@ -1132,16 +1130,16 @@ out:
}
static ssize_t ocfs2_file_aio_read(struct kiocb *iocb,
- char __user *buf,
- size_t count,
+ const struct iovec *iov,
+ unsigned long nr_segs,
loff_t pos)
{
int ret = 0, rw_level = -1, have_alloc_sem = 0;
struct file *filp = iocb->ki_filp;
struct inode *inode = filp->f_dentry->d_inode;
- mlog_entry("(0x%p, 0x%p, %u, '%.*s')\n", filp, buf,
- (unsigned int)count,
+ mlog_entry("(0x%p, %u, '%.*s')\n", filp,
+ (unsigned int)nr_segs,
filp->f_dentry->d_name.len,
filp->f_dentry->d_name.name);
@@ -1185,7 +1183,7 @@ static ssize_t ocfs2_file_aio_read(struct kiocb *iocb,
}
ocfs2_meta_unlock(inode, 0);
- ret = generic_file_aio_read(iocb, buf, count, iocb->ki_pos);
+ ret = generic_file_aio_read(iocb, iov, nr_segs, iocb->ki_pos);
if (ret == -EINVAL)
mlog(ML_ERROR, "generic_file_aio_read returned -EINVAL\n");
diff --git a/fs/ocfs2/namei.c b/fs/ocfs2/namei.c
index 849c3b4bb94a..259155f0eb2e 100644
--- a/fs/ocfs2/namei.c
+++ b/fs/ocfs2/namei.c
@@ -429,7 +429,7 @@ static int ocfs2_mknod(struct inode *dir,
mlog_errno(status);
goto leave;
}
- dir->i_nlink++;
+ inc_nlink(dir);
}
status = ocfs2_add_entry(handle, dentry, inode,
@@ -730,7 +730,7 @@ static int ocfs2_link(struct dentry *old_dentry,
goto bail;
}
- inode->i_nlink++;
+ inc_nlink(inode);
inode->i_ctime = CURRENT_TIME;
fe->i_links_count = cpu_to_le16(inode->i_nlink);
fe->i_ctime = cpu_to_le64(inode->i_ctime.tv_sec);
@@ -739,7 +739,7 @@ static int ocfs2_link(struct dentry *old_dentry,
err = ocfs2_journal_dirty(handle, fe_bh);
if (err < 0) {
le16_add_cpu(&fe->i_links_count, -1);
- inode->i_nlink--;
+ drop_nlink(inode);
mlog_errno(err);
goto bail;
}
@@ -749,7 +749,7 @@ static int ocfs2_link(struct dentry *old_dentry,
parent_fe_bh, de_bh);
if (err) {
le16_add_cpu(&fe->i_links_count, -1);
- inode->i_nlink--;
+ drop_nlink(inode);
mlog_errno(err);
goto bail;
}
@@ -795,11 +795,23 @@ static int ocfs2_remote_dentry_delete(struct dentry *dentry)
return ret;
}
+static inline int inode_is_unlinkable(struct inode *inode)
+{
+ if (S_ISDIR(inode->i_mode)) {
+ if (inode->i_nlink == 2)
+ return 1;
+ return 0;
+ }
+
+ if (inode->i_nlink == 1)
+ return 1;
+ return 0;
+}
+
static int ocfs2_unlink(struct inode *dir,
struct dentry *dentry)
{
int status;
- unsigned int saved_nlink = 0;
struct inode *inode = dentry->d_inode;
struct ocfs2_super *osb = OCFS2_SB(dir->i_sb);
u64 blkno;
@@ -874,16 +886,6 @@ static int ocfs2_unlink(struct inode *dir,
}
}
- /* There are still a few steps left until we can consider the
- * unlink to have succeeded. Save off nlink here before
- * modification so we can set it back in case we hit an issue
- * before commit. */
- saved_nlink = inode->i_nlink;
- if (S_ISDIR(inode->i_mode))
- inode->i_nlink = 0;
- else
- inode->i_nlink--;
-
status = ocfs2_remote_dentry_delete(dentry);
if (status < 0) {
/* This vote should succeed under all normal
@@ -892,7 +894,7 @@ static int ocfs2_unlink(struct inode *dir,
goto leave;
}
- if (!inode->i_nlink) {
+ if (inode_is_unlinkable(inode)) {
status = ocfs2_prepare_orphan_dir(osb, handle, inode,
orphan_name,
&orphan_entry_bh);
@@ -919,7 +921,7 @@ static int ocfs2_unlink(struct inode *dir,
fe = (struct ocfs2_dinode *) fe_bh->b_data;
- if (!inode->i_nlink) {
+ if (inode_is_unlinkable(inode)) {
status = ocfs2_orphan_add(osb, handle, inode, fe, orphan_name,
orphan_entry_bh);
if (status < 0) {
@@ -935,10 +937,10 @@ static int ocfs2_unlink(struct inode *dir,
goto leave;
}
- /* We can set nlink on the dinode now. clear the saved version
- * so that it doesn't get set later. */
+ if (S_ISDIR(inode->i_mode))
+ drop_nlink(inode);
+ drop_nlink(inode);
fe->i_links_count = cpu_to_le16(inode->i_nlink);
- saved_nlink = 0;
status = ocfs2_journal_dirty(handle, fe_bh);
if (status < 0) {
@@ -947,19 +949,16 @@ static int ocfs2_unlink(struct inode *dir,
}
if (S_ISDIR(inode->i_mode)) {
- dir->i_nlink--;
+ drop_nlink(dir);
status = ocfs2_mark_inode_dirty(handle, dir,
parent_node_bh);
if (status < 0) {
mlog_errno(status);
- dir->i_nlink++;
+ inc_nlink(dir);
}
}
leave:
- if (status < 0 && saved_nlink)
- inode->i_nlink = saved_nlink;
-
if (handle)
ocfs2_commit_trans(handle);
@@ -1382,7 +1381,7 @@ static int ocfs2_rename(struct inode *old_dir,
if (new_inode) {
new_inode->i_nlink--;
} else {
- new_dir->i_nlink++;
+ inc_nlink(new_dir);
mark_inode_dirty(new_dir);
}
}
diff --git a/fs/open.c b/fs/open.c
index 303f06d2a7b9..89e0c237a636 100644
--- a/fs/open.c
+++ b/fs/open.c
@@ -6,7 +6,6 @@
#include <linux/string.h>
#include <linux/mm.h>
-#include <linux/utime.h>
#include <linux/file.h>
#include <linux/smp_lock.h>
#include <linux/quotaops.h>
@@ -29,8 +28,6 @@
#include <linux/rcupdate.h>
#include <linux/audit.h>
-#include <asm/unistd.h>
-
int vfs_statfs(struct dentry *dentry, struct kstatfs *buf)
{
int retval = -ENODEV;
@@ -353,137 +350,6 @@ asmlinkage long sys_ftruncate64(unsigned int fd, loff_t length)
}
#endif
-#ifdef __ARCH_WANT_SYS_UTIME
-
-/*
- * sys_utime() can be implemented in user-level using sys_utimes().
- * Is this for backwards compatibility? If so, why not move it
- * into the appropriate arch directory (for those architectures that
- * need it).
- */
-
-/* If times==NULL, set access and modification to current time,
- * must be owner or have write permission.
- * Else, update from *times, must be owner or super user.
- */
-asmlinkage long sys_utime(char __user * filename, struct utimbuf __user * times)
-{
- int error;
- struct nameidata nd;
- struct inode * inode;
- struct iattr newattrs;
-
- error = user_path_walk(filename, &nd);
- if (error)
- goto out;
- inode = nd.dentry->d_inode;
-
- error = -EROFS;
- if (IS_RDONLY(inode))
- goto dput_and_out;
-
- /* Don't worry, the checks are done in inode_change_ok() */
- newattrs.ia_valid = ATTR_CTIME | ATTR_MTIME | ATTR_ATIME;
- if (times) {
- error = -EPERM;
- if (IS_APPEND(inode) || IS_IMMUTABLE(inode))
- goto dput_and_out;
-
- error = get_user(newattrs.ia_atime.tv_sec, &times->actime);
- newattrs.ia_atime.tv_nsec = 0;
- if (!error)
- error = get_user(newattrs.ia_mtime.tv_sec, &times->modtime);
- newattrs.ia_mtime.tv_nsec = 0;
- if (error)
- goto dput_and_out;
-
- newattrs.ia_valid |= ATTR_ATIME_SET | ATTR_MTIME_SET;
- } else {
- error = -EACCES;
- if (IS_IMMUTABLE(inode))
- goto dput_and_out;
-
- if (current->fsuid != inode->i_uid &&
- (error = vfs_permission(&nd, MAY_WRITE)) != 0)
- goto dput_and_out;
- }
- mutex_lock(&inode->i_mutex);
- error = notify_change(nd.dentry, &newattrs);
- mutex_unlock(&inode->i_mutex);
-dput_and_out:
- path_release(&nd);
-out:
- return error;
-}
-
-#endif
-
-/* If times==NULL, set access and modification to current time,
- * must be owner or have write permission.
- * Else, update from *times, must be owner or super user.
- */
-long do_utimes(int dfd, char __user *filename, struct timeval *times)
-{
- int error;
- struct nameidata nd;
- struct inode * inode;
- struct iattr newattrs;
-
- error = __user_walk_fd(dfd, filename, LOOKUP_FOLLOW, &nd);
-
- if (error)
- goto out;
- inode = nd.dentry->d_inode;
-
- error = -EROFS;
- if (IS_RDONLY(inode))
- goto dput_and_out;
-
- /* Don't worry, the checks are done in inode_change_ok() */
- newattrs.ia_valid = ATTR_CTIME | ATTR_MTIME | ATTR_ATIME;
- if (times) {
- error = -EPERM;
- if (IS_APPEND(inode) || IS_IMMUTABLE(inode))
- goto dput_and_out;
-
- newattrs.ia_atime.tv_sec = times[0].tv_sec;
- newattrs.ia_atime.tv_nsec = times[0].tv_usec * 1000;
- newattrs.ia_mtime.tv_sec = times[1].tv_sec;
- newattrs.ia_mtime.tv_nsec = times[1].tv_usec * 1000;
- newattrs.ia_valid |= ATTR_ATIME_SET | ATTR_MTIME_SET;
- } else {
- error = -EACCES;
- if (IS_IMMUTABLE(inode))
- goto dput_and_out;
-
- if (current->fsuid != inode->i_uid &&
- (error = vfs_permission(&nd, MAY_WRITE)) != 0)
- goto dput_and_out;
- }
- mutex_lock(&inode->i_mutex);
- error = notify_change(nd.dentry, &newattrs);
- mutex_unlock(&inode->i_mutex);
-dput_and_out:
- path_release(&nd);
-out:
- return error;
-}
-
-asmlinkage long sys_futimesat(int dfd, char __user *filename, struct timeval __user *utimes)
-{
- struct timeval times[2];
-
- if (utimes && copy_from_user(&times, utimes, sizeof(times)))
- return -EFAULT;
- return do_utimes(dfd, filename, utimes ? times : NULL);
-}
-
-asmlinkage long sys_utimes(char __user *filename, struct timeval __user *utimes)
-{
- return sys_futimesat(AT_FDCWD, filename, utimes);
-}
-
-
/*
* access() needs to use the real uid/gid, not the effective uid/gid.
* We do this by temporarily clearing all FS-related capabilities and
@@ -520,15 +386,21 @@ asmlinkage long sys_faccessat(int dfd, const char __user *filename, int mode)
current->cap_effective = current->cap_permitted;
res = __user_walk_fd(dfd, filename, LOOKUP_FOLLOW|LOOKUP_ACCESS, &nd);
- if (!res) {
- res = vfs_permission(&nd, mode);
- /* SuS v2 requires we report a read only fs too */
- if(!res && (mode & S_IWOTH) && IS_RDONLY(nd.dentry->d_inode)
- && !special_file(nd.dentry->d_inode->i_mode))
- res = -EROFS;
- path_release(&nd);
- }
+ if (res)
+ goto out;
+
+ res = vfs_permission(&nd, mode);
+ /* SuS v2 requires we report a read only fs too */
+ if(res || !(mode & S_IWOTH) ||
+ special_file(nd.dentry->d_inode->i_mode))
+ goto out_path_release;
+
+ if(IS_RDONLY(nd.dentry->d_inode))
+ res = -EROFS;
+out_path_release:
+ path_release(&nd);
+out:
current->fsuid = old_fsuid;
current->fsgid = old_fsgid;
current->cap_effective = old_cap;
@@ -546,7 +418,8 @@ asmlinkage long sys_chdir(const char __user * filename)
struct nameidata nd;
int error;
- error = __user_walk(filename, LOOKUP_FOLLOW|LOOKUP_DIRECTORY, &nd);
+ error = __user_walk(filename,
+ LOOKUP_FOLLOW|LOOKUP_DIRECTORY|LOOKUP_CHDIR, &nd);
if (error)
goto out;
@@ -736,10 +609,11 @@ asmlinkage long sys_chown(const char __user * filename, uid_t user, gid_t group)
int error;
error = user_path_walk(filename, &nd);
- if (!error) {
- error = chown_common(nd.dentry, user, group);
- path_release(&nd);
- }
+ if (error)
+ goto out;
+ error = chown_common(nd.dentry, user, group);
+ path_release(&nd);
+out:
return error;
}
@@ -755,10 +629,10 @@ asmlinkage long sys_fchownat(int dfd, const char __user *filename, uid_t user,
follow = (flag & AT_SYMLINK_NOFOLLOW) ? 0 : LOOKUP_FOLLOW;
error = __user_walk_fd(dfd, filename, follow, &nd);
- if (!error) {
- error = chown_common(nd.dentry, user, group);
- path_release(&nd);
- }
+ if (error)
+ goto out;
+ error = chown_common(nd.dentry, user, group);
+ path_release(&nd);
out:
return error;
}
@@ -769,10 +643,11 @@ asmlinkage long sys_lchown(const char __user * filename, uid_t user, gid_t group
int error;
error = user_path_walk_link(filename, &nd);
- if (!error) {
- error = chown_common(nd.dentry, user, group);
- path_release(&nd);
- }
+ if (error)
+ goto out;
+ error = chown_common(nd.dentry, user, group);
+ path_release(&nd);
+out:
return error;
}
@@ -781,15 +656,17 @@ asmlinkage long sys_fchown(unsigned int fd, uid_t user, gid_t group)
{
struct file * file;
int error = -EBADF;
+ struct dentry * dentry;
file = fget(fd);
- if (file) {
- struct dentry * dentry;
- dentry = file->f_dentry;
- audit_inode(NULL, dentry->d_inode);
- error = chown_common(dentry, user, group);
- fput(file);
- }
+ if (!file)
+ goto out;
+
+ dentry = file->f_dentry;
+ audit_inode(NULL, dentry->d_inode);
+ error = chown_common(dentry, user, group);
+ fput(file);
+out:
return error;
}
@@ -1172,6 +1049,7 @@ asmlinkage long sys_close(unsigned int fd)
struct file * filp;
struct files_struct *files = current->files;
struct fdtable *fdt;
+ int retval;
spin_lock(&files->file_lock);
fdt = files_fdtable(files);
@@ -1184,7 +1062,16 @@ asmlinkage long sys_close(unsigned int fd)
FD_CLR(fd, fdt->close_on_exec);
__put_unused_fd(files, fd);
spin_unlock(&files->file_lock);
- return filp_close(filp, files);
+ retval = filp_close(filp, files);
+
+ /* can't restart close syscall because file table entry was cleared */
+ if (unlikely(retval == -ERESTARTSYS ||
+ retval == -ERESTARTNOINTR ||
+ retval == -ERESTARTNOHAND ||
+ retval == -ERESTART_RESTARTBLOCK))
+ retval = -EINTR;
+
+ return retval;
out_unlock:
spin_unlock(&files->file_lock);
diff --git a/fs/partitions/Makefile b/fs/partitions/Makefile
index d713ce6b3e12..67e665fdb7fc 100644
--- a/fs/partitions/Makefile
+++ b/fs/partitions/Makefile
@@ -2,7 +2,7 @@
# Makefile for the linux kernel.
#
-obj-y := check.o
+obj-$(CONFIG_BLOCK) := check.o
obj-$(CONFIG_ACORN_PARTITION) += acorn.o
obj-$(CONFIG_AMIGA_PARTITION) += amiga.o
diff --git a/fs/partitions/ldm.c b/fs/partitions/ldm.c
index 7ab1c11dca4e..1a60926a4ccd 100644
--- a/fs/partitions/ldm.c
+++ b/fs/partitions/ldm.c
@@ -30,11 +30,6 @@
#include "check.h"
#include "msdos.h"
-typedef enum {
- FALSE = 0,
- TRUE = 1
-} BOOL;
-
/**
* ldm_debug/info/error/crit - Output an error message
* @f: A printf format string containing the message
@@ -103,24 +98,24 @@ static int ldm_parse_hexbyte (const u8 *src)
*
* N.B. The GUID need not be NULL terminated.
*
- * Return: TRUE @dest contains binary GUID
- * FALSE @dest contents are undefined
+ * Return: 'true' @dest contains binary GUID
+ * 'false' @dest contents are undefined
*/
-static BOOL ldm_parse_guid (const u8 *src, u8 *dest)
+static bool ldm_parse_guid (const u8 *src, u8 *dest)
{
static const int size[] = { 4, 2, 2, 2, 6 };
int i, j, v;
if (src[8] != '-' || src[13] != '-' ||
src[18] != '-' || src[23] != '-')
- return FALSE;
+ return false;
for (j = 0; j < 5; j++, src++)
for (i = 0; i < size[j]; i++, src+=2, *dest++ = v)
if ((v = ldm_parse_hexbyte (src)) < 0)
- return FALSE;
+ return false;
- return TRUE;
+ return true;
}
@@ -132,17 +127,17 @@ static BOOL ldm_parse_guid (const u8 *src, u8 *dest)
* This parses the LDM database PRIVHEAD structure supplied in @data and
* sets up the in-memory privhead structure @ph with the obtained information.
*
- * Return: TRUE @ph contains the PRIVHEAD data
- * FALSE @ph contents are undefined
+ * Return: 'true' @ph contains the PRIVHEAD data
+ * 'false' @ph contents are undefined
*/
-static BOOL ldm_parse_privhead (const u8 *data, struct privhead *ph)
+static bool ldm_parse_privhead (const u8 *data, struct privhead *ph)
{
BUG_ON (!data || !ph);
if (MAGIC_PRIVHEAD != BE64 (data)) {
ldm_error ("Cannot find PRIVHEAD structure. LDM database is"
" corrupt. Aborting.");
- return FALSE;
+ return false;
}
ph->ver_major = BE16 (data + 0x000C);
@@ -155,7 +150,7 @@ static BOOL ldm_parse_privhead (const u8 *data, struct privhead *ph)
if ((ph->ver_major != 2) || (ph->ver_minor != 11)) {
ldm_error ("Expected PRIVHEAD version %d.%d, got %d.%d."
" Aborting.", 2, 11, ph->ver_major, ph->ver_minor);
- return FALSE;
+ return false;
}
if (ph->config_size != LDM_DB_SIZE) { /* 1 MiB in sectors. */
/* Warn the user and continue, carefully */
@@ -166,16 +161,16 @@ static BOOL ldm_parse_privhead (const u8 *data, struct privhead *ph)
if ((ph->logical_disk_size == 0) ||
(ph->logical_disk_start + ph->logical_disk_size > ph->config_start)) {
ldm_error ("PRIVHEAD disk size doesn't match real disk size");
- return FALSE;
+ return false;
}
if (!ldm_parse_guid (data + 0x0030, ph->disk_id)) {
ldm_error ("PRIVHEAD contains an invalid GUID.");
- return FALSE;
+ return false;
}
ldm_debug ("Parsed PRIVHEAD successfully.");
- return TRUE;
+ return true;
}
/**
@@ -189,16 +184,16 @@ static BOOL ldm_parse_privhead (const u8 *data, struct privhead *ph)
*
* N.B. The *_start and *_size values returned in @toc are not range-checked.
*
- * Return: TRUE @toc contains the TOCBLOCK data
- * FALSE @toc contents are undefined
+ * Return: 'true' @toc contains the TOCBLOCK data
+ * 'false' @toc contents are undefined
*/
-static BOOL ldm_parse_tocblock (const u8 *data, struct tocblock *toc)
+static bool ldm_parse_tocblock (const u8 *data, struct tocblock *toc)
{
BUG_ON (!data || !toc);
if (MAGIC_TOCBLOCK != BE64 (data)) {
ldm_crit ("Cannot find TOCBLOCK, database may be corrupt.");
- return FALSE;
+ return false;
}
strncpy (toc->bitmap1_name, data + 0x24, sizeof (toc->bitmap1_name));
toc->bitmap1_name[sizeof (toc->bitmap1_name) - 1] = 0;
@@ -209,7 +204,7 @@ static BOOL ldm_parse_tocblock (const u8 *data, struct tocblock *toc)
sizeof (toc->bitmap1_name)) != 0) {
ldm_crit ("TOCBLOCK's first bitmap is '%s', should be '%s'.",
TOC_BITMAP1, toc->bitmap1_name);
- return FALSE;
+ return false;
}
strncpy (toc->bitmap2_name, data + 0x46, sizeof (toc->bitmap2_name));
toc->bitmap2_name[sizeof (toc->bitmap2_name) - 1] = 0;
@@ -219,10 +214,10 @@ static BOOL ldm_parse_tocblock (const u8 *data, struct tocblock *toc)
sizeof (toc->bitmap2_name)) != 0) {
ldm_crit ("TOCBLOCK's second bitmap is '%s', should be '%s'.",
TOC_BITMAP2, toc->bitmap2_name);
- return FALSE;
+ return false;
}
ldm_debug ("Parsed TOCBLOCK successfully.");
- return TRUE;
+ return true;
}
/**
@@ -235,16 +230,16 @@ static BOOL ldm_parse_tocblock (const u8 *data, struct tocblock *toc)
*
* N.B. The *_start, *_size and *_seq values will be range-checked later.
*
- * Return: TRUE @vm contains VMDB info
- * FALSE @vm contents are undefined
+ * Return: 'true' @vm contains VMDB info
+ * 'false' @vm contents are undefined
*/
-static BOOL ldm_parse_vmdb (const u8 *data, struct vmdb *vm)
+static bool ldm_parse_vmdb (const u8 *data, struct vmdb *vm)
{
BUG_ON (!data || !vm);
if (MAGIC_VMDB != BE32 (data)) {
ldm_crit ("Cannot find the VMDB, database may be corrupt.");
- return FALSE;
+ return false;
}
vm->ver_major = BE16 (data + 0x12);
@@ -252,7 +247,7 @@ static BOOL ldm_parse_vmdb (const u8 *data, struct vmdb *vm)
if ((vm->ver_major != 4) || (vm->ver_minor != 10)) {
ldm_error ("Expected VMDB version %d.%d, got %d.%d. "
"Aborting.", 4, 10, vm->ver_major, vm->ver_minor);
- return FALSE;
+ return false;
}
vm->vblk_size = BE32 (data + 0x08);
@@ -260,7 +255,7 @@ static BOOL ldm_parse_vmdb (const u8 *data, struct vmdb *vm)
vm->last_vblk_seq = BE32 (data + 0x04);
ldm_debug ("Parsed VMDB successfully.");
- return TRUE;
+ return true;
}
/**
@@ -270,10 +265,10 @@ static BOOL ldm_parse_vmdb (const u8 *data, struct vmdb *vm)
*
* This compares the two privhead structures @ph1 and @ph2.
*
- * Return: TRUE Identical
- * FALSE Different
+ * Return: 'true' Identical
+ * 'false' Different
*/
-static BOOL ldm_compare_privheads (const struct privhead *ph1,
+static bool ldm_compare_privheads (const struct privhead *ph1,
const struct privhead *ph2)
{
BUG_ON (!ph1 || !ph2);
@@ -294,10 +289,10 @@ static BOOL ldm_compare_privheads (const struct privhead *ph1,
*
* This compares the two tocblock structures @toc1 and @toc2.
*
- * Return: TRUE Identical
- * FALSE Different
+ * Return: 'true' Identical
+ * 'false' Different
*/
-static BOOL ldm_compare_tocblocks (const struct tocblock *toc1,
+static bool ldm_compare_tocblocks (const struct tocblock *toc1,
const struct tocblock *toc2)
{
BUG_ON (!toc1 || !toc2);
@@ -323,17 +318,17 @@ static BOOL ldm_compare_tocblocks (const struct tocblock *toc1,
* the configuration area (the database). The values are range-checked against
* @hd, which contains the real size of the disk.
*
- * Return: TRUE Success
- * FALSE Error
+ * Return: 'true' Success
+ * 'false' Error
*/
-static BOOL ldm_validate_privheads (struct block_device *bdev,
+static bool ldm_validate_privheads (struct block_device *bdev,
struct privhead *ph1)
{
static const int off[3] = { OFF_PRIV1, OFF_PRIV2, OFF_PRIV3 };
struct privhead *ph[3] = { ph1 };
Sector sect;
u8 *data;
- BOOL result = FALSE;
+ bool result = false;
long num_sects;
int i;
@@ -393,7 +388,7 @@ static BOOL ldm_validate_privheads (struct block_device *bdev,
goto out;
}*/
ldm_debug ("Validated PRIVHEADs successfully.");
- result = TRUE;
+ result = true;
out:
kfree (ph[1]);
kfree (ph[2]);
@@ -411,10 +406,10 @@ out:
*
* The offsets and sizes of the configs are range-checked against a privhead.
*
- * Return: TRUE @toc1 contains validated TOCBLOCK info
- * FALSE @toc1 contents are undefined
+ * Return: 'true' @toc1 contains validated TOCBLOCK info
+ * 'false' @toc1 contents are undefined
*/
-static BOOL ldm_validate_tocblocks (struct block_device *bdev,
+static bool ldm_validate_tocblocks (struct block_device *bdev,
unsigned long base, struct ldmdb *ldb)
{
static const int off[4] = { OFF_TOCB1, OFF_TOCB2, OFF_TOCB3, OFF_TOCB4};
@@ -422,7 +417,7 @@ static BOOL ldm_validate_tocblocks (struct block_device *bdev,
struct privhead *ph;
Sector sect;
u8 *data;
- BOOL result = FALSE;
+ bool result = false;
int i;
BUG_ON (!bdev || !ldb);
@@ -465,7 +460,7 @@ static BOOL ldm_validate_tocblocks (struct block_device *bdev,
}
ldm_debug ("Validated TOCBLOCKs successfully.");
- result = TRUE;
+ result = true;
out:
kfree (tb[1]);
kfree (tb[2]);
@@ -482,15 +477,15 @@ out:
* Find the vmdb of the LDM Database stored on @bdev and return the parsed
* information in @ldb.
*
- * Return: TRUE @ldb contains validated VBDB info
- * FALSE @ldb contents are undefined
+ * Return: 'true' @ldb contains validated VBDB info
+ * 'false' @ldb contents are undefined
*/
-static BOOL ldm_validate_vmdb (struct block_device *bdev, unsigned long base,
+static bool ldm_validate_vmdb (struct block_device *bdev, unsigned long base,
struct ldmdb *ldb)
{
Sector sect;
u8 *data;
- BOOL result = FALSE;
+ bool result = false;
struct vmdb *vm;
struct tocblock *toc;
@@ -502,7 +497,7 @@ static BOOL ldm_validate_vmdb (struct block_device *bdev, unsigned long base,
data = read_dev_sector (bdev, base + OFF_VMDB, &sect);
if (!data) {
ldm_crit ("Disk read failed.");
- return FALSE;
+ return false;
}
if (!ldm_parse_vmdb (data, vm))
@@ -527,7 +522,7 @@ static BOOL ldm_validate_vmdb (struct block_device *bdev, unsigned long base,
goto out;
}
- result = TRUE;
+ result = true;
out:
put_dev_sector (sect);
return result;
@@ -547,23 +542,23 @@ out:
* only likely to happen if the underlying device is strange. If that IS
* the case we should return zero to let someone else try.
*
- * Return: TRUE @bdev is a dynamic disk
- * FALSE @bdev is not a dynamic disk, or an error occurred
+ * Return: 'true' @bdev is a dynamic disk
+ * 'false' @bdev is not a dynamic disk, or an error occurred
*/
-static BOOL ldm_validate_partition_table (struct block_device *bdev)
+static bool ldm_validate_partition_table (struct block_device *bdev)
{
Sector sect;
u8 *data;
struct partition *p;
int i;
- BOOL result = FALSE;
+ bool result = false;
BUG_ON (!bdev);
data = read_dev_sector (bdev, 0, &sect);
if (!data) {
ldm_crit ("Disk read failed.");
- return FALSE;
+ return false;
}
if (*(__le16*) (data + 0x01FE) != cpu_to_le16 (MSDOS_LABEL_MAGIC))
@@ -572,7 +567,7 @@ static BOOL ldm_validate_partition_table (struct block_device *bdev)
p = (struct partition*)(data + 0x01BE);
for (i = 0; i < 4; i++, p++)
if (SYS_IND (p) == WIN2K_DYNAMIC_PARTITION) {
- result = TRUE;
+ result = true;
break;
}
@@ -625,10 +620,10 @@ static struct vblk * ldm_get_disk_objid (const struct ldmdb *ldb)
* N.B. This function creates the partitions in the order it finds partition
* objects in the linked list.
*
- * Return: TRUE Partition created
- * FALSE Error, probably a range checking problem
+ * Return: 'true' Partition created
+ * 'false' Error, probably a range checking problem
*/
-static BOOL ldm_create_data_partitions (struct parsed_partitions *pp,
+static bool ldm_create_data_partitions (struct parsed_partitions *pp,
const struct ldmdb *ldb)
{
struct list_head *item;
@@ -642,7 +637,7 @@ static BOOL ldm_create_data_partitions (struct parsed_partitions *pp,
disk = ldm_get_disk_objid (ldb);
if (!disk) {
ldm_crit ("Can't find the ID of this disk in the database.");
- return FALSE;
+ return false;
}
printk (" [LDM]");
@@ -661,7 +656,7 @@ static BOOL ldm_create_data_partitions (struct parsed_partitions *pp,
}
printk ("\n");
- return TRUE;
+ return true;
}
@@ -766,10 +761,10 @@ static int ldm_get_vstr (const u8 *block, u8 *buffer, int buflen)
*
* Read a raw VBLK Component object (version 3) into a vblk structure.
*
- * Return: TRUE @vb contains a Component VBLK
- * FALSE @vb contents are not defined
+ * Return: 'true' @vb contains a Component VBLK
+ * 'false' @vb contents are not defined
*/
-static BOOL ldm_parse_cmp3 (const u8 *buffer, int buflen, struct vblk *vb)
+static bool ldm_parse_cmp3 (const u8 *buffer, int buflen, struct vblk *vb)
{
int r_objid, r_name, r_vstate, r_child, r_parent, r_stripe, r_cols, len;
struct vblk_comp *comp;
@@ -792,11 +787,11 @@ static BOOL ldm_parse_cmp3 (const u8 *buffer, int buflen, struct vblk *vb)
len = r_parent;
}
if (len < 0)
- return FALSE;
+ return false;
len += VBLK_SIZE_CMP3;
if (len != BE32 (buffer + 0x14))
- return FALSE;
+ return false;
comp = &vb->vblk.comp;
ldm_get_vstr (buffer + 0x18 + r_name, comp->state,
@@ -806,7 +801,7 @@ static BOOL ldm_parse_cmp3 (const u8 *buffer, int buflen, struct vblk *vb)
comp->parent_id = ldm_get_vnum (buffer + 0x2D + r_child);
comp->chunksize = r_stripe ? ldm_get_vnum (buffer+r_parent+0x2E) : 0;
- return TRUE;
+ return true;
}
/**
@@ -817,8 +812,8 @@ static BOOL ldm_parse_cmp3 (const u8 *buffer, int buflen, struct vblk *vb)
*
* Read a raw VBLK Disk Group object (version 3) into a vblk structure.
*
- * Return: TRUE @vb contains a Disk Group VBLK
- * FALSE @vb contents are not defined
+ * Return: 'true' @vb contains a Disk Group VBLK
+ * 'false' @vb contents are not defined
*/
static int ldm_parse_dgr3 (const u8 *buffer, int buflen, struct vblk *vb)
{
@@ -841,16 +836,16 @@ static int ldm_parse_dgr3 (const u8 *buffer, int buflen, struct vblk *vb)
len = r_diskid;
}
if (len < 0)
- return FALSE;
+ return false;
len += VBLK_SIZE_DGR3;
if (len != BE32 (buffer + 0x14))
- return FALSE;
+ return false;
dgrp = &vb->vblk.dgrp;
ldm_get_vstr (buffer + 0x18 + r_name, dgrp->disk_id,
sizeof (dgrp->disk_id));
- return TRUE;
+ return true;
}
/**
@@ -861,10 +856,10 @@ static int ldm_parse_dgr3 (const u8 *buffer, int buflen, struct vblk *vb)
*
* Read a raw VBLK Disk Group object (version 4) into a vblk structure.
*
- * Return: TRUE @vb contains a Disk Group VBLK
- * FALSE @vb contents are not defined
+ * Return: 'true' @vb contains a Disk Group VBLK
+ * 'false' @vb contents are not defined
*/
-static BOOL ldm_parse_dgr4 (const u8 *buffer, int buflen, struct vblk *vb)
+static bool ldm_parse_dgr4 (const u8 *buffer, int buflen, struct vblk *vb)
{
char buf[64];
int r_objid, r_name, r_id1, r_id2, len;
@@ -885,16 +880,16 @@ static BOOL ldm_parse_dgr4 (const u8 *buffer, int buflen, struct vblk *vb)
len = r_name;
}
if (len < 0)
- return FALSE;
+ return false;
len += VBLK_SIZE_DGR4;
if (len != BE32 (buffer + 0x14))
- return FALSE;
+ return false;
dgrp = &vb->vblk.dgrp;
ldm_get_vstr (buffer + 0x18 + r_objid, buf, sizeof (buf));
- return TRUE;
+ return true;
}
/**
@@ -905,10 +900,10 @@ static BOOL ldm_parse_dgr4 (const u8 *buffer, int buflen, struct vblk *vb)
*
* Read a raw VBLK Disk object (version 3) into a vblk structure.
*
- * Return: TRUE @vb contains a Disk VBLK
- * FALSE @vb contents are not defined
+ * Return: 'true' @vb contains a Disk VBLK
+ * 'false' @vb contents are not defined
*/
-static BOOL ldm_parse_dsk3 (const u8 *buffer, int buflen, struct vblk *vb)
+static bool ldm_parse_dsk3 (const u8 *buffer, int buflen, struct vblk *vb)
{
int r_objid, r_name, r_diskid, r_altname, len;
struct vblk_disk *disk;
@@ -921,19 +916,19 @@ static BOOL ldm_parse_dsk3 (const u8 *buffer, int buflen, struct vblk *vb)
r_altname = ldm_relative (buffer, buflen, 0x18, r_diskid);
len = r_altname;
if (len < 0)
- return FALSE;
+ return false;
len += VBLK_SIZE_DSK3;
if (len != BE32 (buffer + 0x14))
- return FALSE;
+ return false;
disk = &vb->vblk.disk;
ldm_get_vstr (buffer + 0x18 + r_diskid, disk->alt_name,
sizeof (disk->alt_name));
if (!ldm_parse_guid (buffer + 0x19 + r_name, disk->disk_id))
- return FALSE;
+ return false;
- return TRUE;
+ return true;
}
/**
@@ -944,10 +939,10 @@ static BOOL ldm_parse_dsk3 (const u8 *buffer, int buflen, struct vblk *vb)
*
* Read a raw VBLK Disk object (version 4) into a vblk structure.
*
- * Return: TRUE @vb contains a Disk VBLK
- * FALSE @vb contents are not defined
+ * Return: 'true' @vb contains a Disk VBLK
+ * 'false' @vb contents are not defined
*/
-static BOOL ldm_parse_dsk4 (const u8 *buffer, int buflen, struct vblk *vb)
+static bool ldm_parse_dsk4 (const u8 *buffer, int buflen, struct vblk *vb)
{
int r_objid, r_name, len;
struct vblk_disk *disk;
@@ -958,15 +953,15 @@ static BOOL ldm_parse_dsk4 (const u8 *buffer, int buflen, struct vblk *vb)
r_name = ldm_relative (buffer, buflen, 0x18, r_objid);
len = r_name;
if (len < 0)
- return FALSE;
+ return false;
len += VBLK_SIZE_DSK4;
if (len != BE32 (buffer + 0x14))
- return FALSE;
+ return false;
disk = &vb->vblk.disk;
memcpy (disk->disk_id, buffer + 0x18 + r_name, GUID_SIZE);
- return TRUE;
+ return true;
}
/**
@@ -977,10 +972,10 @@ static BOOL ldm_parse_dsk4 (const u8 *buffer, int buflen, struct vblk *vb)
*
* Read a raw VBLK Partition object (version 3) into a vblk structure.
*
- * Return: TRUE @vb contains a Partition VBLK
- * FALSE @vb contents are not defined
+ * Return: 'true' @vb contains a Partition VBLK
+ * 'false' @vb contents are not defined
*/
-static BOOL ldm_parse_prt3 (const u8 *buffer, int buflen, struct vblk *vb)
+static bool ldm_parse_prt3 (const u8 *buffer, int buflen, struct vblk *vb)
{
int r_objid, r_name, r_size, r_parent, r_diskid, r_index, len;
struct vblk_part *part;
@@ -1001,11 +996,11 @@ static BOOL ldm_parse_prt3 (const u8 *buffer, int buflen, struct vblk *vb)
len = r_diskid;
}
if (len < 0)
- return FALSE;
+ return false;
len += VBLK_SIZE_PRT3;
if (len != BE32 (buffer + 0x14))
- return FALSE;
+ return false;
part = &vb->vblk.part;
part->start = BE64 (buffer + 0x24 + r_name);
@@ -1018,7 +1013,7 @@ static BOOL ldm_parse_prt3 (const u8 *buffer, int buflen, struct vblk *vb)
else
part->partnum = 0;
- return TRUE;
+ return true;
}
/**
@@ -1029,10 +1024,10 @@ static BOOL ldm_parse_prt3 (const u8 *buffer, int buflen, struct vblk *vb)
*
* Read a raw VBLK Volume object (version 5) into a vblk structure.
*
- * Return: TRUE @vb contains a Volume VBLK
- * FALSE @vb contents are not defined
+ * Return: 'true' @vb contains a Volume VBLK
+ * 'false' @vb contents are not defined
*/
-static BOOL ldm_parse_vol5 (const u8 *buffer, int buflen, struct vblk *vb)
+static bool ldm_parse_vol5 (const u8 *buffer, int buflen, struct vblk *vb)
{
int r_objid, r_name, r_vtype, r_child, r_size, r_id1, r_id2, r_size2;
int r_drive, len;
@@ -1068,11 +1063,11 @@ static BOOL ldm_parse_vol5 (const u8 *buffer, int buflen, struct vblk *vb)
len = r_drive;
if (len < 0)
- return FALSE;
+ return false;
len += VBLK_SIZE_VOL5;
if (len != BE32 (buffer + 0x14))
- return FALSE;
+ return false;
volu = &vb->vblk.volu;
@@ -1087,7 +1082,7 @@ static BOOL ldm_parse_vol5 (const u8 *buffer, int buflen, struct vblk *vb)
ldm_get_vstr (buffer + 0x53 + r_size, volu->drive_hint,
sizeof (volu->drive_hint));
}
- return TRUE;
+ return true;
}
/**
@@ -1100,12 +1095,12 @@ static BOOL ldm_parse_vol5 (const u8 *buffer, int buflen, struct vblk *vb)
* information common to all VBLK types, then delegates the rest of the work to
* helper functions: ldm_parse_*.
*
- * Return: TRUE @vb contains a VBLK
- * FALSE @vb contents are not defined
+ * Return: 'true' @vb contains a VBLK
+ * 'false' @vb contents are not defined
*/
-static BOOL ldm_parse_vblk (const u8 *buf, int len, struct vblk *vb)
+static bool ldm_parse_vblk (const u8 *buf, int len, struct vblk *vb)
{
- BOOL result = FALSE;
+ bool result = false;
int r_objid;
BUG_ON (!buf || !vb);
@@ -1113,7 +1108,7 @@ static BOOL ldm_parse_vblk (const u8 *buf, int len, struct vblk *vb)
r_objid = ldm_relative (buf, len, 0x18, 0);
if (r_objid < 0) {
ldm_error ("VBLK header is corrupt.");
- return FALSE;
+ return false;
}
vb->flags = buf[0x12];
@@ -1152,10 +1147,10 @@ static BOOL ldm_parse_vblk (const u8 *buf, int len, struct vblk *vb)
*
* N.B. This function does not check the validity of the VBLKs.
*
- * Return: TRUE The VBLK was added
- * FALSE An error occurred
+ * Return: 'true' The VBLK was added
+ * 'false' An error occurred
*/
-static BOOL ldm_ldmdb_add (u8 *data, int len, struct ldmdb *ldb)
+static bool ldm_ldmdb_add (u8 *data, int len, struct ldmdb *ldb)
{
struct vblk *vb;
struct list_head *item;
@@ -1165,12 +1160,12 @@ static BOOL ldm_ldmdb_add (u8 *data, int len, struct ldmdb *ldb)
vb = kmalloc (sizeof (*vb), GFP_KERNEL);
if (!vb) {
ldm_crit ("Out of memory.");
- return FALSE;
+ return false;
}
if (!ldm_parse_vblk (data, len, vb)) {
kfree(vb);
- return FALSE; /* Already logged */
+ return false; /* Already logged */
}
/* Put vblk into the correct list. */
@@ -1196,13 +1191,13 @@ static BOOL ldm_ldmdb_add (u8 *data, int len, struct ldmdb *ldb)
if ((v->vblk.part.disk_id == vb->vblk.part.disk_id) &&
(v->vblk.part.start > vb->vblk.part.start)) {
list_add_tail (&vb->list, &v->list);
- return TRUE;
+ return true;
}
}
list_add_tail (&vb->list, &ldb->v_part);
break;
}
- return TRUE;
+ return true;
}
/**
@@ -1214,10 +1209,10 @@ static BOOL ldm_ldmdb_add (u8 *data, int len, struct ldmdb *ldb)
* Fragmented VBLKs may not be consecutive in the database, so they are placed
* in a list so they can be pieced together later.
*
- * Return: TRUE Success, the VBLK was added to the list
- * FALSE Error, a problem occurred
+ * Return: 'true' Success, the VBLK was added to the list
+ * 'false' Error, a problem occurred
*/
-static BOOL ldm_frag_add (const u8 *data, int size, struct list_head *frags)
+static bool ldm_frag_add (const u8 *data, int size, struct list_head *frags)
{
struct frag *f;
struct list_head *item;
@@ -1230,7 +1225,7 @@ static BOOL ldm_frag_add (const u8 *data, int size, struct list_head *frags)
num = BE16 (data + 0x0E);
if ((num < 1) || (num > 4)) {
ldm_error ("A VBLK claims to have %d parts.", num);
- return FALSE;
+ return false;
}
list_for_each (item, frags) {
@@ -1242,7 +1237,7 @@ static BOOL ldm_frag_add (const u8 *data, int size, struct list_head *frags)
f = kmalloc (sizeof (*f) + size*num, GFP_KERNEL);
if (!f) {
ldm_crit ("Out of memory.");
- return FALSE;
+ return false;
}
f->group = group;
@@ -1255,7 +1250,7 @@ found:
if (f->map & (1 << rec)) {
ldm_error ("Duplicate VBLK, part %d.", rec);
f->map &= 0x7F; /* Mark the group as broken */
- return FALSE;
+ return false;
}
f->map |= (1 << rec);
@@ -1266,7 +1261,7 @@ found:
}
memcpy (f->data+rec*(size-VBLK_SIZE_HEAD)+VBLK_SIZE_HEAD, data, size);
- return TRUE;
+ return true;
}
/**
@@ -1295,10 +1290,10 @@ static void ldm_frag_free (struct list_head *list)
* Now that all the fragmented VBLKs have been collected, they must be added to
* the database for later use.
*
- * Return: TRUE All the fragments we added successfully
- * FALSE One or more of the fragments we invalid
+ * Return: 'true' All the fragments we added successfully
+ * 'false' One or more of the fragments we invalid
*/
-static BOOL ldm_frag_commit (struct list_head *frags, struct ldmdb *ldb)
+static bool ldm_frag_commit (struct list_head *frags, struct ldmdb *ldb)
{
struct frag *f;
struct list_head *item;
@@ -1311,13 +1306,13 @@ static BOOL ldm_frag_commit (struct list_head *frags, struct ldmdb *ldb)
if (f->map != 0xFF) {
ldm_error ("VBLK group %d is incomplete (0x%02x).",
f->group, f->map);
- return FALSE;
+ return false;
}
if (!ldm_ldmdb_add (f->data, f->num*ldb->vm.vblk_size, ldb))
- return FALSE; /* Already logged */
+ return false; /* Already logged */
}
- return TRUE;
+ return true;
}
/**
@@ -1329,16 +1324,16 @@ static BOOL ldm_frag_commit (struct list_head *frags, struct ldmdb *ldb)
* To use the information from the VBLKs, they need to be read from the disk,
* unpacked and validated. We cache them in @ldb according to their type.
*
- * Return: TRUE All the VBLKs were read successfully
- * FALSE An error occurred
+ * Return: 'true' All the VBLKs were read successfully
+ * 'false' An error occurred
*/
-static BOOL ldm_get_vblks (struct block_device *bdev, unsigned long base,
+static bool ldm_get_vblks (struct block_device *bdev, unsigned long base,
struct ldmdb *ldb)
{
int size, perbuf, skip, finish, s, v, recs;
u8 *data = NULL;
Sector sect;
- BOOL result = FALSE;
+ bool result = false;
LIST_HEAD (frags);
BUG_ON (!bdev || !ldb);
diff --git a/fs/partitions/msdos.c b/fs/partitions/msdos.c
index 8f12587c3129..4f8df71e49d3 100644
--- a/fs/partitions/msdos.c
+++ b/fs/partitions/msdos.c
@@ -58,6 +58,31 @@ msdos_magic_present(unsigned char *p)
return (p[0] == MSDOS_LABEL_MAGIC1 && p[1] == MSDOS_LABEL_MAGIC2);
}
+/* Value is EBCDIC 'IBMA' */
+#define AIX_LABEL_MAGIC1 0xC9
+#define AIX_LABEL_MAGIC2 0xC2
+#define AIX_LABEL_MAGIC3 0xD4
+#define AIX_LABEL_MAGIC4 0xC1
+static int aix_magic_present(unsigned char *p, struct block_device *bdev)
+{
+ Sector sect;
+ unsigned char *d;
+ int ret = 0;
+
+ if (p[0] != AIX_LABEL_MAGIC1 &&
+ p[1] != AIX_LABEL_MAGIC2 &&
+ p[2] != AIX_LABEL_MAGIC3 &&
+ p[3] != AIX_LABEL_MAGIC4)
+ return 0;
+ d = read_dev_sector(bdev, 7, &sect);
+ if (d) {
+ if (d[0] == '_' && d[1] == 'L' && d[2] == 'V' && d[3] == 'M')
+ ret = 1;
+ put_dev_sector(sect);
+ };
+ return ret;
+}
+
/*
* Create devices for each logical partition in an extended partition.
* The logical partitions form a linked list, with each entry being
@@ -393,6 +418,12 @@ int msdos_partition(struct parsed_partitions *state, struct block_device *bdev)
return 0;
}
+ if (aix_magic_present(data, bdev)) {
+ put_dev_sector(sect);
+ printk( " [AIX]");
+ return 0;
+ }
+
/*
* Now that the 55aa signature is present, this is probably
* either the boot sector of a FAT filesystem or a DOS-type
diff --git a/fs/pipe.c b/fs/pipe.c
index f3b6f71e9d0b..b1626f269a34 100644
--- a/fs/pipe.c
+++ b/fs/pipe.c
@@ -218,9 +218,10 @@ static struct pipe_buf_operations anon_pipe_buf_ops = {
};
static ssize_t
-pipe_readv(struct file *filp, const struct iovec *_iov,
- unsigned long nr_segs, loff_t *ppos)
+pipe_read(struct kiocb *iocb, const struct iovec *_iov,
+ unsigned long nr_segs, loff_t pos)
{
+ struct file *filp = iocb->ki_filp;
struct inode *inode = filp->f_dentry->d_inode;
struct pipe_inode_info *pipe;
int do_wakeup;
@@ -330,17 +331,10 @@ redo:
}
static ssize_t
-pipe_read(struct file *filp, char __user *buf, size_t count, loff_t *ppos)
-{
- struct iovec iov = { .iov_base = buf, .iov_len = count };
-
- return pipe_readv(filp, &iov, 1, ppos);
-}
-
-static ssize_t
-pipe_writev(struct file *filp, const struct iovec *_iov,
- unsigned long nr_segs, loff_t *ppos)
+pipe_write(struct kiocb *iocb, const struct iovec *_iov,
+ unsigned long nr_segs, loff_t ppos)
{
+ struct file *filp = iocb->ki_filp;
struct inode *inode = filp->f_dentry->d_inode;
struct pipe_inode_info *pipe;
ssize_t ret;
@@ -510,15 +504,6 @@ out:
}
static ssize_t
-pipe_write(struct file *filp, const char __user *buf,
- size_t count, loff_t *ppos)
-{
- struct iovec iov = { .iov_base = (void __user *)buf, .iov_len = count };
-
- return pipe_writev(filp, &iov, 1, ppos);
-}
-
-static ssize_t
bad_pipe_r(struct file *filp, char __user *buf, size_t count, loff_t *ppos)
{
return -EBADF;
@@ -736,8 +721,8 @@ pipe_rdwr_open(struct inode *inode, struct file *filp)
*/
const struct file_operations read_fifo_fops = {
.llseek = no_llseek,
- .read = pipe_read,
- .readv = pipe_readv,
+ .read = do_sync_read,
+ .aio_read = pipe_read,
.write = bad_pipe_w,
.poll = pipe_poll,
.ioctl = pipe_ioctl,
@@ -749,8 +734,8 @@ const struct file_operations read_fifo_fops = {
const struct file_operations write_fifo_fops = {
.llseek = no_llseek,
.read = bad_pipe_r,
- .write = pipe_write,
- .writev = pipe_writev,
+ .write = do_sync_write,
+ .aio_write = pipe_write,
.poll = pipe_poll,
.ioctl = pipe_ioctl,
.open = pipe_write_open,
@@ -760,10 +745,10 @@ const struct file_operations write_fifo_fops = {
const struct file_operations rdwr_fifo_fops = {
.llseek = no_llseek,
- .read = pipe_read,
- .readv = pipe_readv,
- .write = pipe_write,
- .writev = pipe_writev,
+ .read = do_sync_read,
+ .aio_read = pipe_read,
+ .write = do_sync_write,
+ .aio_write = pipe_write,
.poll = pipe_poll,
.ioctl = pipe_ioctl,
.open = pipe_rdwr_open,
@@ -773,8 +758,8 @@ const struct file_operations rdwr_fifo_fops = {
static struct file_operations read_pipe_fops = {
.llseek = no_llseek,
- .read = pipe_read,
- .readv = pipe_readv,
+ .read = do_sync_read,
+ .aio_read = pipe_read,
.write = bad_pipe_w,
.poll = pipe_poll,
.ioctl = pipe_ioctl,
@@ -786,8 +771,8 @@ static struct file_operations read_pipe_fops = {
static struct file_operations write_pipe_fops = {
.llseek = no_llseek,
.read = bad_pipe_r,
- .write = pipe_write,
- .writev = pipe_writev,
+ .write = do_sync_write,
+ .aio_write = pipe_write,
.poll = pipe_poll,
.ioctl = pipe_ioctl,
.open = pipe_write_open,
@@ -797,10 +782,10 @@ static struct file_operations write_pipe_fops = {
static struct file_operations rdwr_pipe_fops = {
.llseek = no_llseek,
- .read = pipe_read,
- .readv = pipe_readv,
- .write = pipe_write,
- .writev = pipe_writev,
+ .read = do_sync_read,
+ .aio_read = pipe_read,
+ .write = do_sync_write,
+ .aio_write = pipe_write,
.poll = pipe_poll,
.ioctl = pipe_ioctl,
.open = pipe_rdwr_open,
@@ -889,87 +874,118 @@ fail_inode:
return NULL;
}
-int do_pipe(int *fd)
+struct file *create_write_pipe(void)
{
- struct qstr this;
- char name[32];
+ int err;
+ struct inode *inode;
+ struct file *f;
struct dentry *dentry;
- struct inode * inode;
- struct file *f1, *f2;
- int error;
- int i, j;
-
- error = -ENFILE;
- f1 = get_empty_filp();
- if (!f1)
- goto no_files;
-
- f2 = get_empty_filp();
- if (!f2)
- goto close_f1;
+ char name[32];
+ struct qstr this;
+ f = get_empty_filp();
+ if (!f)
+ return ERR_PTR(-ENFILE);
+ err = -ENFILE;
inode = get_pipe_inode();
if (!inode)
- goto close_f12;
-
- error = get_unused_fd();
- if (error < 0)
- goto close_f12_inode;
- i = error;
-
- error = get_unused_fd();
- if (error < 0)
- goto close_f12_inode_i;
- j = error;
+ goto err_file;
- error = -ENOMEM;
sprintf(name, "[%lu]", inode->i_ino);
this.name = name;
this.len = strlen(name);
this.hash = inode->i_ino; /* will go */
+ err = -ENOMEM;
dentry = d_alloc(pipe_mnt->mnt_sb->s_root, &this);
if (!dentry)
- goto close_f12_inode_i_j;
+ goto err_inode;
dentry->d_op = &pipefs_dentry_operations;
d_add(dentry, inode);
- f1->f_vfsmnt = f2->f_vfsmnt = mntget(mntget(pipe_mnt));
- f1->f_dentry = f2->f_dentry = dget(dentry);
- f1->f_mapping = f2->f_mapping = inode->i_mapping;
-
- /* read file */
- f1->f_pos = f2->f_pos = 0;
- f1->f_flags = O_RDONLY;
- f1->f_op = &read_pipe_fops;
- f1->f_mode = FMODE_READ;
- f1->f_version = 0;
-
- /* write file */
- f2->f_flags = O_WRONLY;
- f2->f_op = &write_pipe_fops;
- f2->f_mode = FMODE_WRITE;
- f2->f_version = 0;
-
- fd_install(i, f1);
- fd_install(j, f2);
- fd[0] = i;
- fd[1] = j;
+ f->f_vfsmnt = mntget(pipe_mnt);
+ f->f_dentry = dentry;
+ f->f_mapping = inode->i_mapping;
- return 0;
+ f->f_flags = O_WRONLY;
+ f->f_op = &write_pipe_fops;
+ f->f_mode = FMODE_WRITE;
+ f->f_version = 0;
+
+ return f;
-close_f12_inode_i_j:
- put_unused_fd(j);
-close_f12_inode_i:
- put_unused_fd(i);
-close_f12_inode:
+ err_inode:
free_pipe_info(inode);
iput(inode);
-close_f12:
- put_filp(f2);
-close_f1:
- put_filp(f1);
-no_files:
- return error;
+ err_file:
+ put_filp(f);
+ return ERR_PTR(err);
+}
+
+void free_write_pipe(struct file *f)
+{
+ mntput(f->f_vfsmnt);
+ dput(f->f_dentry);
+ put_filp(f);
+}
+
+struct file *create_read_pipe(struct file *wrf)
+{
+ struct file *f = get_empty_filp();
+ if (!f)
+ return ERR_PTR(-ENFILE);
+
+ /* Grab pipe from the writer */
+ f->f_vfsmnt = mntget(wrf->f_vfsmnt);
+ f->f_dentry = dget(wrf->f_dentry);
+ f->f_mapping = wrf->f_dentry->d_inode->i_mapping;
+
+ f->f_pos = 0;
+ f->f_flags = O_RDONLY;
+ f->f_op = &read_pipe_fops;
+ f->f_mode = FMODE_READ;
+ f->f_version = 0;
+
+ return f;
+}
+
+int do_pipe(int *fd)
+{
+ struct file *fw, *fr;
+ int error;
+ int fdw, fdr;
+
+ fw = create_write_pipe();
+ if (IS_ERR(fw))
+ return PTR_ERR(fw);
+ fr = create_read_pipe(fw);
+ error = PTR_ERR(fr);
+ if (IS_ERR(fr))
+ goto err_write_pipe;
+
+ error = get_unused_fd();
+ if (error < 0)
+ goto err_read_pipe;
+ fdr = error;
+
+ error = get_unused_fd();
+ if (error < 0)
+ goto err_fdr;
+ fdw = error;
+
+ fd_install(fdr, fr);
+ fd_install(fdw, fw);
+ fd[0] = fdr;
+ fd[1] = fdw;
+
+ return 0;
+
+ err_fdr:
+ put_unused_fd(fdr);
+ err_read_pipe:
+ put_filp(fr);
+ err_write_pipe:
+ free_write_pipe(fw);
+ return error;
}
/*
diff --git a/fs/posix_acl.c b/fs/posix_acl.c
index 6c8dcf7613fd..aec931e09973 100644
--- a/fs/posix_acl.c
+++ b/fs/posix_acl.c
@@ -58,11 +58,9 @@ posix_acl_clone(const struct posix_acl *acl, gfp_t flags)
if (acl) {
int size = sizeof(struct posix_acl) + acl->a_count *
sizeof(struct posix_acl_entry);
- clone = kmalloc(size, flags);
- if (clone) {
- memcpy(clone, acl, size);
+ clone = kmemdup(acl, size, flags);
+ if (clone)
atomic_set(&clone->a_refcount, 1);
- }
}
return clone;
}
diff --git a/fs/proc/array.c b/fs/proc/array.c
index 0b615d62a159..25e917fb4739 100644
--- a/fs/proc/array.c
+++ b/fs/proc/array.c
@@ -162,7 +162,7 @@ static inline char * task_state(struct task_struct *p, char *buffer)
int g;
struct fdtable *fdt = NULL;
- read_lock(&tasklist_lock);
+ rcu_read_lock();
buffer += sprintf(buffer,
"State:\t%s\n"
"SleepAVG:\t%lu%%\n"
@@ -174,14 +174,13 @@ static inline char * task_state(struct task_struct *p, char *buffer)
"Gid:\t%d\t%d\t%d\t%d\n",
get_task_state(p),
(p->sleep_avg/1024)*100/(1020000000/1024),
- p->tgid,
- p->pid, pid_alive(p) ? p->group_leader->real_parent->tgid : 0,
- pid_alive(p) && p->ptrace ? p->parent->pid : 0,
+ p->tgid, p->pid,
+ pid_alive(p) ? rcu_dereference(p->real_parent)->tgid : 0,
+ pid_alive(p) && p->ptrace ? rcu_dereference(p->parent)->pid : 0,
p->uid, p->euid, p->suid, p->fsuid,
p->gid, p->egid, p->sgid, p->fsgid);
- read_unlock(&tasklist_lock);
+
task_lock(p);
- rcu_read_lock();
if (p->files)
fdt = files_fdtable(p->files);
buffer += sprintf(buffer,
@@ -244,6 +243,7 @@ static void collect_sigign_sigcatch(struct task_struct *p, sigset_t *ign,
static inline char * task_sig(struct task_struct *p, char *buffer)
{
+ unsigned long flags;
sigset_t pending, shpending, blocked, ignored, caught;
int num_threads = 0;
unsigned long qsize = 0;
@@ -255,10 +255,8 @@ static inline char * task_sig(struct task_struct *p, char *buffer)
sigemptyset(&ignored);
sigemptyset(&caught);
- /* Gather all the data with the appropriate locks held */
- read_lock(&tasklist_lock);
- if (p->sighand) {
- spin_lock_irq(&p->sighand->siglock);
+ rcu_read_lock();
+ if (lock_task_sighand(p, &flags)) {
pending = p->pending.signal;
shpending = p->signal->shared_pending.signal;
blocked = p->blocked;
@@ -266,9 +264,9 @@ static inline char * task_sig(struct task_struct *p, char *buffer)
num_threads = atomic_read(&p->signal->count);
qsize = atomic_read(&p->user->sigpending);
qlim = p->signal->rlim[RLIMIT_SIGPENDING].rlim_cur;
- spin_unlock_irq(&p->sighand->siglock);
+ unlock_task_sighand(p, &flags);
}
- read_unlock(&tasklist_lock);
+ rcu_read_unlock();
buffer += sprintf(buffer, "Threads:\t%d\n", num_threads);
buffer += sprintf(buffer, "SigQ:\t%lu/%lu\n", qsize, qlim);
@@ -322,7 +320,7 @@ static int do_task_stat(struct task_struct *task, char * buffer, int whole)
sigset_t sigign, sigcatch;
char state;
int res;
- pid_t ppid, pgid = -1, sid = -1;
+ pid_t ppid = 0, pgid = -1, sid = -1;
int num_threads = 0;
struct mm_struct *mm;
unsigned long long start_time;
@@ -330,8 +328,8 @@ static int do_task_stat(struct task_struct *task, char * buffer, int whole)
unsigned long min_flt = 0, maj_flt = 0;
cputime_t cutime, cstime, utime, stime;
unsigned long rsslim = 0;
- struct task_struct *t;
char tcomm[sizeof(task->comm)];
+ unsigned long flags;
state = *get_task_state(task);
vsize = eip = esp = 0;
@@ -347,15 +345,35 @@ static int do_task_stat(struct task_struct *task, char * buffer, int whole)
sigemptyset(&sigign);
sigemptyset(&sigcatch);
cutime = cstime = utime = stime = cputime_zero;
- read_lock(&tasklist_lock);
- if (task->sighand) {
- spin_lock_irq(&task->sighand->siglock);
- num_threads = atomic_read(&task->signal->count);
+
+ mutex_lock(&tty_mutex);
+ rcu_read_lock();
+ if (lock_task_sighand(task, &flags)) {
+ struct signal_struct *sig = task->signal;
+ struct tty_struct *tty = sig->tty;
+
+ if (tty) {
+ /*
+ * sig->tty is not stable, but tty_mutex
+ * protects us from release_dev(tty)
+ */
+ barrier();
+ tty_pgrp = tty->pgrp;
+ tty_nr = new_encode_dev(tty_devnum(tty));
+ }
+
+ num_threads = atomic_read(&sig->count);
collect_sigign_sigcatch(task, &sigign, &sigcatch);
+ cmin_flt = sig->cmin_flt;
+ cmaj_flt = sig->cmaj_flt;
+ cutime = sig->cutime;
+ cstime = sig->cstime;
+ rsslim = sig->rlim[RLIMIT_RSS].rlim_cur;
+
/* add up live thread stats at the group level */
if (whole) {
- t = task;
+ struct task_struct *t = task;
do {
min_flt += t->min_flt;
maj_flt += t->maj_flt;
@@ -363,31 +381,21 @@ static int do_task_stat(struct task_struct *task, char * buffer, int whole)
stime = cputime_add(stime, t->stime);
t = next_thread(t);
} while (t != task);
- }
- spin_unlock_irq(&task->sighand->siglock);
- }
- if (task->signal) {
- if (task->signal->tty) {
- tty_pgrp = task->signal->tty->pgrp;
- tty_nr = new_encode_dev(tty_devnum(task->signal->tty));
+ min_flt += sig->min_flt;
+ maj_flt += sig->maj_flt;
+ utime = cputime_add(utime, sig->utime);
+ stime = cputime_add(stime, sig->stime);
}
+
+ sid = sig->session;
pgid = process_group(task);
- sid = task->signal->session;
- cmin_flt = task->signal->cmin_flt;
- cmaj_flt = task->signal->cmaj_flt;
- cutime = task->signal->cutime;
- cstime = task->signal->cstime;
- rsslim = task->signal->rlim[RLIMIT_RSS].rlim_cur;
- if (whole) {
- min_flt += task->signal->min_flt;
- maj_flt += task->signal->maj_flt;
- utime = cputime_add(utime, task->signal->utime);
- stime = cputime_add(stime, task->signal->stime);
- }
+ ppid = rcu_dereference(task->real_parent)->tgid;
+
+ unlock_task_sighand(task, &flags);
}
- ppid = pid_alive(task) ? task->group_leader->real_parent->tgid : 0;
- read_unlock(&tasklist_lock);
+ rcu_read_unlock();
+ mutex_unlock(&tty_mutex);
if (!whole || num_threads<2)
wchan = get_wchan(task);
diff --git a/fs/proc/base.c b/fs/proc/base.c
index fe8d55fb17cc..82da55b5cffe 100644
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -71,6 +71,7 @@
#include <linux/cpuset.h>
#include <linux/audit.h>
#include <linux/poll.h>
+#include <linux/nsproxy.h>
#include "internal.h"
/* NOTE:
@@ -83,262 +84,44 @@
* in /proc for a task before it execs a suid executable.
*/
-/*
- * For hysterical raisins we keep the same inumbers as in the old procfs.
- * Feel free to change the macro below - just keep the range distinct from
- * inumbers of the rest of procfs (currently those are in 0x0000--0xffff).
- * As soon as we'll get a separate superblock we will be able to forget
- * about magical ranges too.
- */
-
-#define fake_ino(pid,ino) (((pid)<<16)|(ino))
-
-enum pid_directory_inos {
- PROC_TGID_INO = 2,
- PROC_TGID_TASK,
- PROC_TGID_STATUS,
- PROC_TGID_MEM,
-#ifdef CONFIG_SECCOMP
- PROC_TGID_SECCOMP,
-#endif
- PROC_TGID_CWD,
- PROC_TGID_ROOT,
- PROC_TGID_EXE,
- PROC_TGID_FD,
- PROC_TGID_ENVIRON,
- PROC_TGID_AUXV,
- PROC_TGID_CMDLINE,
- PROC_TGID_STAT,
- PROC_TGID_STATM,
- PROC_TGID_MAPS,
- PROC_TGID_NUMA_MAPS,
- PROC_TGID_MOUNTS,
- PROC_TGID_MOUNTSTATS,
- PROC_TGID_WCHAN,
-#ifdef CONFIG_MMU
- PROC_TGID_SMAPS,
-#endif
-#ifdef CONFIG_SCHEDSTATS
- PROC_TGID_SCHEDSTAT,
-#endif
-#ifdef CONFIG_CPUSETS
- PROC_TGID_CPUSET,
-#endif
-#ifdef CONFIG_SECURITY
- PROC_TGID_ATTR,
- PROC_TGID_ATTR_CURRENT,
- PROC_TGID_ATTR_PREV,
- PROC_TGID_ATTR_EXEC,
- PROC_TGID_ATTR_FSCREATE,
- PROC_TGID_ATTR_KEYCREATE,
- PROC_TGID_ATTR_SOCKCREATE,
-#endif
-#ifdef CONFIG_AUDITSYSCALL
- PROC_TGID_LOGINUID,
-#endif
- PROC_TGID_OOM_SCORE,
- PROC_TGID_OOM_ADJUST,
- PROC_TID_INO,
- PROC_TID_STATUS,
- PROC_TID_MEM,
-#ifdef CONFIG_SECCOMP
- PROC_TID_SECCOMP,
-#endif
- PROC_TID_CWD,
- PROC_TID_ROOT,
- PROC_TID_EXE,
- PROC_TID_FD,
- PROC_TID_ENVIRON,
- PROC_TID_AUXV,
- PROC_TID_CMDLINE,
- PROC_TID_STAT,
- PROC_TID_STATM,
- PROC_TID_MAPS,
- PROC_TID_NUMA_MAPS,
- PROC_TID_MOUNTS,
- PROC_TID_MOUNTSTATS,
- PROC_TID_WCHAN,
-#ifdef CONFIG_MMU
- PROC_TID_SMAPS,
-#endif
-#ifdef CONFIG_SCHEDSTATS
- PROC_TID_SCHEDSTAT,
-#endif
-#ifdef CONFIG_CPUSETS
- PROC_TID_CPUSET,
-#endif
-#ifdef CONFIG_SECURITY
- PROC_TID_ATTR,
- PROC_TID_ATTR_CURRENT,
- PROC_TID_ATTR_PREV,
- PROC_TID_ATTR_EXEC,
- PROC_TID_ATTR_FSCREATE,
- PROC_TID_ATTR_KEYCREATE,
- PROC_TID_ATTR_SOCKCREATE,
-#endif
-#ifdef CONFIG_AUDITSYSCALL
- PROC_TID_LOGINUID,
-#endif
- PROC_TID_OOM_SCORE,
- PROC_TID_OOM_ADJUST,
-
- /* Add new entries before this */
- PROC_TID_FD_DIR = 0x8000, /* 0x8000-0xffff */
-};
/* Worst case buffer size needed for holding an integer. */
#define PROC_NUMBUF 10
struct pid_entry {
- int type;
int len;
char *name;
mode_t mode;
+ struct inode_operations *iop;
+ struct file_operations *fop;
+ union proc_op op;
};
-#define E(type,name,mode) {(type),sizeof(name)-1,(name),(mode)}
-
-static struct pid_entry tgid_base_stuff[] = {
- E(PROC_TGID_TASK, "task", S_IFDIR|S_IRUGO|S_IXUGO),
- E(PROC_TGID_FD, "fd", S_IFDIR|S_IRUSR|S_IXUSR),
- E(PROC_TGID_ENVIRON, "environ", S_IFREG|S_IRUSR),
- E(PROC_TGID_AUXV, "auxv", S_IFREG|S_IRUSR),
- E(PROC_TGID_STATUS, "status", S_IFREG|S_IRUGO),
- E(PROC_TGID_CMDLINE, "cmdline", S_IFREG|S_IRUGO),
- E(PROC_TGID_STAT, "stat", S_IFREG|S_IRUGO),
- E(PROC_TGID_STATM, "statm", S_IFREG|S_IRUGO),
- E(PROC_TGID_MAPS, "maps", S_IFREG|S_IRUGO),
-#ifdef CONFIG_NUMA
- E(PROC_TGID_NUMA_MAPS, "numa_maps", S_IFREG|S_IRUGO),
-#endif
- E(PROC_TGID_MEM, "mem", S_IFREG|S_IRUSR|S_IWUSR),
-#ifdef CONFIG_SECCOMP
- E(PROC_TGID_SECCOMP, "seccomp", S_IFREG|S_IRUSR|S_IWUSR),
-#endif
- E(PROC_TGID_CWD, "cwd", S_IFLNK|S_IRWXUGO),
- E(PROC_TGID_ROOT, "root", S_IFLNK|S_IRWXUGO),
- E(PROC_TGID_EXE, "exe", S_IFLNK|S_IRWXUGO),
- E(PROC_TGID_MOUNTS, "mounts", S_IFREG|S_IRUGO),
- E(PROC_TGID_MOUNTSTATS, "mountstats", S_IFREG|S_IRUSR),
-#ifdef CONFIG_MMU
- E(PROC_TGID_SMAPS, "smaps", S_IFREG|S_IRUGO),
-#endif
-#ifdef CONFIG_SECURITY
- E(PROC_TGID_ATTR, "attr", S_IFDIR|S_IRUGO|S_IXUGO),
-#endif
-#ifdef CONFIG_KALLSYMS
- E(PROC_TGID_WCHAN, "wchan", S_IFREG|S_IRUGO),
-#endif
-#ifdef CONFIG_SCHEDSTATS
- E(PROC_TGID_SCHEDSTAT, "schedstat", S_IFREG|S_IRUGO),
-#endif
-#ifdef CONFIG_CPUSETS
- E(PROC_TGID_CPUSET, "cpuset", S_IFREG|S_IRUGO),
-#endif
- E(PROC_TGID_OOM_SCORE, "oom_score",S_IFREG|S_IRUGO),
- E(PROC_TGID_OOM_ADJUST,"oom_adj", S_IFREG|S_IRUGO|S_IWUSR),
-#ifdef CONFIG_AUDITSYSCALL
- E(PROC_TGID_LOGINUID, "loginuid", S_IFREG|S_IWUSR|S_IRUGO),
-#endif
- {0,0,NULL,0}
-};
-static struct pid_entry tid_base_stuff[] = {
- E(PROC_TID_FD, "fd", S_IFDIR|S_IRUSR|S_IXUSR),
- E(PROC_TID_ENVIRON, "environ", S_IFREG|S_IRUSR),
- E(PROC_TID_AUXV, "auxv", S_IFREG|S_IRUSR),
- E(PROC_TID_STATUS, "status", S_IFREG|S_IRUGO),
- E(PROC_TID_CMDLINE, "cmdline", S_IFREG|S_IRUGO),
- E(PROC_TID_STAT, "stat", S_IFREG|S_IRUGO),
- E(PROC_TID_STATM, "statm", S_IFREG|S_IRUGO),
- E(PROC_TID_MAPS, "maps", S_IFREG|S_IRUGO),
-#ifdef CONFIG_NUMA
- E(PROC_TID_NUMA_MAPS, "numa_maps", S_IFREG|S_IRUGO),
-#endif
- E(PROC_TID_MEM, "mem", S_IFREG|S_IRUSR|S_IWUSR),
-#ifdef CONFIG_SECCOMP
- E(PROC_TID_SECCOMP, "seccomp", S_IFREG|S_IRUSR|S_IWUSR),
-#endif
- E(PROC_TID_CWD, "cwd", S_IFLNK|S_IRWXUGO),
- E(PROC_TID_ROOT, "root", S_IFLNK|S_IRWXUGO),
- E(PROC_TID_EXE, "exe", S_IFLNK|S_IRWXUGO),
- E(PROC_TID_MOUNTS, "mounts", S_IFREG|S_IRUGO),
-#ifdef CONFIG_MMU
- E(PROC_TID_SMAPS, "smaps", S_IFREG|S_IRUGO),
-#endif
-#ifdef CONFIG_SECURITY
- E(PROC_TID_ATTR, "attr", S_IFDIR|S_IRUGO|S_IXUGO),
-#endif
-#ifdef CONFIG_KALLSYMS
- E(PROC_TID_WCHAN, "wchan", S_IFREG|S_IRUGO),
-#endif
-#ifdef CONFIG_SCHEDSTATS
- E(PROC_TID_SCHEDSTAT, "schedstat",S_IFREG|S_IRUGO),
-#endif
-#ifdef CONFIG_CPUSETS
- E(PROC_TID_CPUSET, "cpuset", S_IFREG|S_IRUGO),
-#endif
- E(PROC_TID_OOM_SCORE, "oom_score",S_IFREG|S_IRUGO),
- E(PROC_TID_OOM_ADJUST, "oom_adj", S_IFREG|S_IRUGO|S_IWUSR),
-#ifdef CONFIG_AUDITSYSCALL
- E(PROC_TID_LOGINUID, "loginuid", S_IFREG|S_IWUSR|S_IRUGO),
-#endif
- {0,0,NULL,0}
-};
-
-#ifdef CONFIG_SECURITY
-static struct pid_entry tgid_attr_stuff[] = {
- E(PROC_TGID_ATTR_CURRENT, "current", S_IFREG|S_IRUGO|S_IWUGO),
- E(PROC_TGID_ATTR_PREV, "prev", S_IFREG|S_IRUGO),
- E(PROC_TGID_ATTR_EXEC, "exec", S_IFREG|S_IRUGO|S_IWUGO),
- E(PROC_TGID_ATTR_FSCREATE, "fscreate", S_IFREG|S_IRUGO|S_IWUGO),
- E(PROC_TGID_ATTR_KEYCREATE, "keycreate", S_IFREG|S_IRUGO|S_IWUGO),
- E(PROC_TGID_ATTR_SOCKCREATE, "sockcreate", S_IFREG|S_IRUGO|S_IWUGO),
- {0,0,NULL,0}
-};
-static struct pid_entry tid_attr_stuff[] = {
- E(PROC_TID_ATTR_CURRENT, "current", S_IFREG|S_IRUGO|S_IWUGO),
- E(PROC_TID_ATTR_PREV, "prev", S_IFREG|S_IRUGO),
- E(PROC_TID_ATTR_EXEC, "exec", S_IFREG|S_IRUGO|S_IWUGO),
- E(PROC_TID_ATTR_FSCREATE, "fscreate", S_IFREG|S_IRUGO|S_IWUGO),
- E(PROC_TID_ATTR_KEYCREATE, "keycreate", S_IFREG|S_IRUGO|S_IWUGO),
- E(PROC_TID_ATTR_SOCKCREATE, "sockcreate", S_IFREG|S_IRUGO|S_IWUGO),
- {0,0,NULL,0}
-};
-#endif
-
-#undef E
-
-static int proc_fd_link(struct inode *inode, struct dentry **dentry, struct vfsmount **mnt)
-{
- struct task_struct *task = get_proc_task(inode);
- struct files_struct *files = NULL;
- struct file *file;
- int fd = proc_fd(inode);
-
- if (task) {
- files = get_files_struct(task);
- put_task_struct(task);
- }
- if (files) {
- /*
- * We are not taking a ref to the file structure, so we must
- * hold ->file_lock.
- */
- spin_lock(&files->file_lock);
- file = fcheck_files(files, fd);
- if (file) {
- *mnt = mntget(file->f_vfsmnt);
- *dentry = dget(file->f_dentry);
- spin_unlock(&files->file_lock);
- put_files_struct(files);
- return 0;
- }
- spin_unlock(&files->file_lock);
- put_files_struct(files);
- }
- return -ENOENT;
+#define NOD(NAME, MODE, IOP, FOP, OP) { \
+ .len = sizeof(NAME) - 1, \
+ .name = (NAME), \
+ .mode = MODE, \
+ .iop = IOP, \
+ .fop = FOP, \
+ .op = OP, \
}
+#define DIR(NAME, MODE, OTYPE) \
+ NOD(NAME, (S_IFDIR|(MODE)), \
+ &proc_##OTYPE##_inode_operations, &proc_##OTYPE##_operations, \
+ {} )
+#define LNK(NAME, OTYPE) \
+ NOD(NAME, (S_IFLNK|S_IRWXUGO), \
+ &proc_pid_link_inode_operations, NULL, \
+ { .proc_get_link = &proc_##OTYPE##_link } )
+#define REG(NAME, MODE, OTYPE) \
+ NOD(NAME, (S_IFREG|(MODE)), NULL, \
+ &proc_##OTYPE##_operations, {})
+#define INF(NAME, MODE, OTYPE) \
+ NOD(NAME, (S_IFREG|(MODE)), \
+ NULL, &proc_info_file_operations, \
+ { .proc_read = &proc_##OTYPE } )
+
static struct fs_struct *get_fs_struct(struct task_struct *task)
{
struct fs_struct *fs;
@@ -587,7 +370,7 @@ static int mounts_open(struct inode *inode, struct file *file)
if (task) {
task_lock(task);
- namespace = task->namespace;
+ namespace = task->nsproxy->namespace;
if (namespace)
get_namespace(namespace);
task_unlock(task);
@@ -658,7 +441,7 @@ static int mountstats_open(struct inode *inode, struct file *file)
if (task) {
task_lock(task);
- namespace = task->namespace;
+ namespace = task->nsproxy->namespace;
if (namespace)
get_namespace(namespace);
task_unlock(task);
@@ -797,7 +580,7 @@ out_no_task:
static ssize_t mem_write(struct file * file, const char * buf,
size_t count, loff_t *ppos)
{
- int copied = 0;
+ int copied;
char *page;
struct task_struct *task = get_proc_task(file->f_dentry->d_inode);
unsigned long dst = *ppos;
@@ -814,6 +597,7 @@ static ssize_t mem_write(struct file * file, const char * buf,
if (!page)
goto out;
+ copied = 0;
while (count > 0) {
int this_len, retval;
@@ -1136,143 +920,6 @@ static struct inode_operations proc_pid_link_inode_operations = {
.setattr = proc_setattr,
};
-static int proc_readfd(struct file * filp, void * dirent, filldir_t filldir)
-{
- struct dentry *dentry = filp->f_dentry;
- struct inode *inode = dentry->d_inode;
- struct task_struct *p = get_proc_task(inode);
- unsigned int fd, tid, ino;
- int retval;
- char buf[PROC_NUMBUF];
- struct files_struct * files;
- struct fdtable *fdt;
-
- retval = -ENOENT;
- if (!p)
- goto out_no_task;
- retval = 0;
- tid = p->pid;
-
- fd = filp->f_pos;
- switch (fd) {
- case 0:
- if (filldir(dirent, ".", 1, 0, inode->i_ino, DT_DIR) < 0)
- goto out;
- filp->f_pos++;
- case 1:
- ino = parent_ino(dentry);
- if (filldir(dirent, "..", 2, 1, ino, DT_DIR) < 0)
- goto out;
- filp->f_pos++;
- default:
- files = get_files_struct(p);
- if (!files)
- goto out;
- rcu_read_lock();
- fdt = files_fdtable(files);
- for (fd = filp->f_pos-2;
- fd < fdt->max_fds;
- fd++, filp->f_pos++) {
- unsigned int i,j;
-
- if (!fcheck_files(files, fd))
- continue;
- rcu_read_unlock();
-
- j = PROC_NUMBUF;
- i = fd;
- do {
- j--;
- buf[j] = '0' + (i % 10);
- i /= 10;
- } while (i);
-
- ino = fake_ino(tid, PROC_TID_FD_DIR + fd);
- if (filldir(dirent, buf+j, PROC_NUMBUF-j, fd+2, ino, DT_LNK) < 0) {
- rcu_read_lock();
- break;
- }
- rcu_read_lock();
- }
- rcu_read_unlock();
- put_files_struct(files);
- }
-out:
- put_task_struct(p);
-out_no_task:
- return retval;
-}
-
-static int proc_pident_readdir(struct file *filp,
- void *dirent, filldir_t filldir,
- struct pid_entry *ents, unsigned int nents)
-{
- int i;
- int pid;
- struct dentry *dentry = filp->f_dentry;
- struct inode *inode = dentry->d_inode;
- struct task_struct *task = get_proc_task(inode);
- struct pid_entry *p;
- ino_t ino;
- int ret;
-
- ret = -ENOENT;
- if (!task)
- goto out;
-
- ret = 0;
- pid = task->pid;
- put_task_struct(task);
- i = filp->f_pos;
- switch (i) {
- case 0:
- ino = inode->i_ino;
- if (filldir(dirent, ".", 1, i, ino, DT_DIR) < 0)
- goto out;
- i++;
- filp->f_pos++;
- /* fall through */
- case 1:
- ino = parent_ino(dentry);
- if (filldir(dirent, "..", 2, i, ino, DT_DIR) < 0)
- goto out;
- i++;
- filp->f_pos++;
- /* fall through */
- default:
- i -= 2;
- if (i >= nents) {
- ret = 1;
- goto out;
- }
- p = ents + i;
- while (p->name) {
- if (filldir(dirent, p->name, p->len, filp->f_pos,
- fake_ino(pid, p->type), p->mode >> 12) < 0)
- goto out;
- filp->f_pos++;
- p++;
- }
- }
-
- ret = 1;
-out:
- return ret;
-}
-
-static int proc_tgid_base_readdir(struct file * filp,
- void * dirent, filldir_t filldir)
-{
- return proc_pident_readdir(filp,dirent,filldir,
- tgid_base_stuff,ARRAY_SIZE(tgid_base_stuff));
-}
-
-static int proc_tid_base_readdir(struct file * filp,
- void * dirent, filldir_t filldir)
-{
- return proc_pident_readdir(filp,dirent,filldir,
- tid_base_stuff,ARRAY_SIZE(tid_base_stuff));
-}
/* building an inode */
@@ -1292,13 +939,13 @@ static int task_dumpable(struct task_struct *task)
}
-static struct inode *proc_pid_make_inode(struct super_block * sb, struct task_struct *task, int ino)
+static struct inode *proc_pid_make_inode(struct super_block * sb, struct task_struct *task)
{
struct inode * inode;
struct proc_inode *ei;
/* We need a new inode */
-
+
inode = new_inode(sb);
if (!inode)
goto out;
@@ -1306,13 +953,12 @@ static struct inode *proc_pid_make_inode(struct super_block * sb, struct task_st
/* Common stuff */
ei = PROC_I(inode);
inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
- inode->i_ino = fake_ino(task->pid, ino);
inode->i_op = &proc_def_inode_operations;
/*
* grab the reference to task.
*/
- ei->pid = get_pid(task->pids[PIDTYPE_PID].pid);
+ ei->pid = get_task_pid(task, PIDTYPE_PID);
if (!ei->pid)
goto out_unlock;
@@ -1332,6 +978,27 @@ out_unlock:
return NULL;
}
+static int pid_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat)
+{
+ struct inode *inode = dentry->d_inode;
+ struct task_struct *task;
+ generic_fillattr(inode, stat);
+
+ rcu_read_lock();
+ stat->uid = 0;
+ stat->gid = 0;
+ task = pid_task(proc_pid(inode), PIDTYPE_PID);
+ if (task) {
+ if ((inode->i_mode == (S_IFDIR|S_IRUGO|S_IXUGO)) ||
+ task_dumpable(task)) {
+ stat->uid = task->euid;
+ stat->gid = task->egid;
+ }
+ }
+ rcu_read_unlock();
+ return 0;
+}
+
/* dentry stuff */
/*
@@ -1371,25 +1038,130 @@ static int pid_revalidate(struct dentry *dentry, struct nameidata *nd)
return 0;
}
-static int pid_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat)
+static int pid_delete_dentry(struct dentry * dentry)
{
- struct inode *inode = dentry->d_inode;
- struct task_struct *task;
- generic_fillattr(inode, stat);
+ /* Is the task we represent dead?
+ * If so, then don't put the dentry on the lru list,
+ * kill it immediately.
+ */
+ return !proc_pid(dentry->d_inode)->tasks[PIDTYPE_PID].first;
+}
+
+static struct dentry_operations pid_dentry_operations =
+{
+ .d_revalidate = pid_revalidate,
+ .d_delete = pid_delete_dentry,
+};
+
+/* Lookups */
+
+typedef struct dentry *instantiate_t(struct inode *, struct dentry *, struct task_struct *, void *);
+
+/*
+ * Fill a directory entry.
+ *
+ * If possible create the dcache entry and derive our inode number and
+ * file type from dcache entry.
+ *
+ * Since all of the proc inode numbers are dynamically generated, the inode
+ * numbers do not exist until the inode is cache. This means creating the
+ * the dcache entry in readdir is necessary to keep the inode numbers
+ * reported by readdir in sync with the inode numbers reported
+ * by stat.
+ */
+static int proc_fill_cache(struct file *filp, void *dirent, filldir_t filldir,
+ char *name, int len,
+ instantiate_t instantiate, struct task_struct *task, void *ptr)
+{
+ struct dentry *child, *dir = filp->f_dentry;
+ struct inode *inode;
+ struct qstr qname;
+ ino_t ino = 0;
+ unsigned type = DT_UNKNOWN;
+
+ qname.name = name;
+ qname.len = len;
+ qname.hash = full_name_hash(name, len);
+
+ child = d_lookup(dir, &qname);
+ if (!child) {
+ struct dentry *new;
+ new = d_alloc(dir, &qname);
+ if (new) {
+ child = instantiate(dir->d_inode, new, task, ptr);
+ if (child)
+ dput(new);
+ else
+ child = new;
+ }
+ }
+ if (!child || IS_ERR(child) || !child->d_inode)
+ goto end_instantiate;
+ inode = child->d_inode;
+ if (inode) {
+ ino = inode->i_ino;
+ type = inode->i_mode >> 12;
+ }
+ dput(child);
+end_instantiate:
+ if (!ino)
+ ino = find_inode_number(dir, &qname);
+ if (!ino)
+ ino = 1;
+ return filldir(dirent, name, len, filp->f_pos, ino, type);
+}
+
+static unsigned name_to_int(struct dentry *dentry)
+{
+ const char *name = dentry->d_name.name;
+ int len = dentry->d_name.len;
+ unsigned n = 0;
+
+ if (len > 1 && *name == '0')
+ goto out;
+ while (len-- > 0) {
+ unsigned c = *name++ - '0';
+ if (c > 9)
+ goto out;
+ if (n >= (~0U-9)/10)
+ goto out;
+ n *= 10;
+ n += c;
+ }
+ return n;
+out:
+ return ~0U;
+}
+
+static int proc_fd_link(struct inode *inode, struct dentry **dentry, struct vfsmount **mnt)
+{
+ struct task_struct *task = get_proc_task(inode);
+ struct files_struct *files = NULL;
+ struct file *file;
+ int fd = proc_fd(inode);
- rcu_read_lock();
- stat->uid = 0;
- stat->gid = 0;
- task = pid_task(proc_pid(inode), PIDTYPE_PID);
if (task) {
- if ((inode->i_mode == (S_IFDIR|S_IRUGO|S_IXUGO)) ||
- task_dumpable(task)) {
- stat->uid = task->euid;
- stat->gid = task->egid;
+ files = get_files_struct(task);
+ put_task_struct(task);
+ }
+ if (files) {
+ /*
+ * We are not taking a ref to the file structure, so we must
+ * hold ->file_lock.
+ */
+ spin_lock(&files->file_lock);
+ file = fcheck_files(files, fd);
+ if (file) {
+ *mnt = mntget(file->f_vfsmnt);
+ *dentry = dget(file->f_dentry);
+ spin_unlock(&files->file_lock);
+ put_files_struct(files);
+ return 0;
}
+ spin_unlock(&files->file_lock);
+ put_files_struct(files);
}
- rcu_read_unlock();
- return 0;
+ return -ENOENT;
}
static int tid_fd_revalidate(struct dentry *dentry, struct nameidata *nd)
@@ -1427,75 +1199,30 @@ static int tid_fd_revalidate(struct dentry *dentry, struct nameidata *nd)
return 0;
}
-static int pid_delete_dentry(struct dentry * dentry)
-{
- /* Is the task we represent dead?
- * If so, then don't put the dentry on the lru list,
- * kill it immediately.
- */
- return !proc_pid(dentry->d_inode)->tasks[PIDTYPE_PID].first;
-}
-
static struct dentry_operations tid_fd_dentry_operations =
{
.d_revalidate = tid_fd_revalidate,
.d_delete = pid_delete_dentry,
};
-static struct dentry_operations pid_dentry_operations =
-{
- .d_revalidate = pid_revalidate,
- .d_delete = pid_delete_dentry,
-};
-
-/* Lookups */
-
-static unsigned name_to_int(struct dentry *dentry)
-{
- const char *name = dentry->d_name.name;
- int len = dentry->d_name.len;
- unsigned n = 0;
-
- if (len > 1 && *name == '0')
- goto out;
- while (len-- > 0) {
- unsigned c = *name++ - '0';
- if (c > 9)
- goto out;
- if (n >= (~0U-9)/10)
- goto out;
- n *= 10;
- n += c;
- }
- return n;
-out:
- return ~0U;
-}
-
-/* SMP-safe */
-static struct dentry *proc_lookupfd(struct inode * dir, struct dentry * dentry, struct nameidata *nd)
+static struct dentry *proc_fd_instantiate(struct inode *dir,
+ struct dentry *dentry, struct task_struct *task, void *ptr)
{
- struct task_struct *task = get_proc_task(dir);
- unsigned fd = name_to_int(dentry);
- struct dentry *result = ERR_PTR(-ENOENT);
- struct file * file;
- struct files_struct * files;
- struct inode *inode;
- struct proc_inode *ei;
-
- if (!task)
- goto out_no_task;
- if (fd == ~0U)
- goto out;
+ unsigned fd = *(unsigned *)ptr;
+ struct file *file;
+ struct files_struct *files;
+ struct inode *inode;
+ struct proc_inode *ei;
+ struct dentry *error = ERR_PTR(-ENOENT);
- inode = proc_pid_make_inode(dir->i_sb, task, PROC_TID_FD_DIR+fd);
+ inode = proc_pid_make_inode(dir->i_sb, task);
if (!inode)
goto out;
ei = PROC_I(inode);
ei->fd = fd;
files = get_files_struct(task);
if (!files)
- goto out_unlock;
+ goto out_iput;
inode->i_mode = S_IFLNK;
/*
@@ -1505,13 +1232,14 @@ static struct dentry *proc_lookupfd(struct inode * dir, struct dentry * dentry,
spin_lock(&files->file_lock);
file = fcheck_files(files, fd);
if (!file)
- goto out_unlock2;
+ goto out_unlock;
if (file->f_mode & 1)
inode->i_mode |= S_IRUSR | S_IXUSR;
if (file->f_mode & 2)
inode->i_mode |= S_IWUSR | S_IXUSR;
spin_unlock(&files->file_lock);
put_files_struct(files);
+
inode->i_op = &proc_pid_link_inode_operations;
inode->i_size = 64;
ei->op.proc_get_link = proc_fd_link;
@@ -1519,34 +1247,106 @@ static struct dentry *proc_lookupfd(struct inode * dir, struct dentry * dentry,
d_add(dentry, inode);
/* Close the race of the process dying before we return the dentry */
if (tid_fd_revalidate(dentry, NULL))
- result = NULL;
-out:
- put_task_struct(task);
-out_no_task:
- return result;
+ error = NULL;
-out_unlock2:
+ out:
+ return error;
+out_unlock:
spin_unlock(&files->file_lock);
put_files_struct(files);
-out_unlock:
+out_iput:
iput(inode);
goto out;
}
-static int proc_task_readdir(struct file * filp, void * dirent, filldir_t filldir);
-static struct dentry *proc_task_lookup(struct inode *dir, struct dentry * dentry, struct nameidata *nd);
-static int proc_task_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat);
+static struct dentry *proc_lookupfd(struct inode * dir, struct dentry * dentry, struct nameidata *nd)
+{
+ struct task_struct *task = get_proc_task(dir);
+ unsigned fd = name_to_int(dentry);
+ struct dentry *result = ERR_PTR(-ENOENT);
+
+ if (!task)
+ goto out_no_task;
+ if (fd == ~0U)
+ goto out;
+
+ result = proc_fd_instantiate(dir, dentry, task, &fd);
+out:
+ put_task_struct(task);
+out_no_task:
+ return result;
+}
+
+static int proc_fd_fill_cache(struct file *filp, void *dirent, filldir_t filldir,
+ struct task_struct *task, int fd)
+{
+ char name[PROC_NUMBUF];
+ int len = snprintf(name, sizeof(name), "%d", fd);
+ return proc_fill_cache(filp, dirent, filldir, name, len,
+ proc_fd_instantiate, task, &fd);
+}
+
+static int proc_readfd(struct file * filp, void * dirent, filldir_t filldir)
+{
+ struct dentry *dentry = filp->f_dentry;
+ struct inode *inode = dentry->d_inode;
+ struct task_struct *p = get_proc_task(inode);
+ unsigned int fd, tid, ino;
+ int retval;
+ struct files_struct * files;
+ struct fdtable *fdt;
+
+ retval = -ENOENT;
+ if (!p)
+ goto out_no_task;
+ retval = 0;
+ tid = p->pid;
+
+ fd = filp->f_pos;
+ switch (fd) {
+ case 0:
+ if (filldir(dirent, ".", 1, 0, inode->i_ino, DT_DIR) < 0)
+ goto out;
+ filp->f_pos++;
+ case 1:
+ ino = parent_ino(dentry);
+ if (filldir(dirent, "..", 2, 1, ino, DT_DIR) < 0)
+ goto out;
+ filp->f_pos++;
+ default:
+ files = get_files_struct(p);
+ if (!files)
+ goto out;
+ rcu_read_lock();
+ fdt = files_fdtable(files);
+ for (fd = filp->f_pos-2;
+ fd < fdt->max_fds;
+ fd++, filp->f_pos++) {
+
+ if (!fcheck_files(files, fd))
+ continue;
+ rcu_read_unlock();
+
+ if (proc_fd_fill_cache(filp, dirent, filldir, p, fd) < 0) {
+ rcu_read_lock();
+ break;
+ }
+ rcu_read_lock();
+ }
+ rcu_read_unlock();
+ put_files_struct(files);
+ }
+out:
+ put_task_struct(p);
+out_no_task:
+ return retval;
+}
static struct file_operations proc_fd_operations = {
.read = generic_read_dir,
.readdir = proc_readfd,
};
-static struct file_operations proc_task_operations = {
- .read = generic_read_dir,
- .readdir = proc_task_readdir,
-};
-
/*
* proc directories can do almost nothing..
*/
@@ -1555,11 +1355,137 @@ static struct inode_operations proc_fd_inode_operations = {
.setattr = proc_setattr,
};
-static struct inode_operations proc_task_inode_operations = {
- .lookup = proc_task_lookup,
- .getattr = proc_task_getattr,
- .setattr = proc_setattr,
-};
+static struct dentry *proc_pident_instantiate(struct inode *dir,
+ struct dentry *dentry, struct task_struct *task, void *ptr)
+{
+ struct pid_entry *p = ptr;
+ struct inode *inode;
+ struct proc_inode *ei;
+ struct dentry *error = ERR_PTR(-EINVAL);
+
+ inode = proc_pid_make_inode(dir->i_sb, task);
+ if (!inode)
+ goto out;
+
+ ei = PROC_I(inode);
+ inode->i_mode = p->mode;
+ if (S_ISDIR(inode->i_mode))
+ inode->i_nlink = 2; /* Use getattr to fix if necessary */
+ if (p->iop)
+ inode->i_op = p->iop;
+ if (p->fop)
+ inode->i_fop = p->fop;
+ ei->op = p->op;
+ dentry->d_op = &pid_dentry_operations;
+ d_add(dentry, inode);
+ /* Close the race of the process dying before we return the dentry */
+ if (pid_revalidate(dentry, NULL))
+ error = NULL;
+out:
+ return error;
+}
+
+static struct dentry *proc_pident_lookup(struct inode *dir,
+ struct dentry *dentry,
+ struct pid_entry *ents,
+ unsigned int nents)
+{
+ struct inode *inode;
+ struct dentry *error;
+ struct task_struct *task = get_proc_task(dir);
+ struct pid_entry *p, *last;
+
+ error = ERR_PTR(-ENOENT);
+ inode = NULL;
+
+ if (!task)
+ goto out_no_task;
+
+ /*
+ * Yes, it does not scale. And it should not. Don't add
+ * new entries into /proc/<tgid>/ without very good reasons.
+ */
+ last = &ents[nents - 1];
+ for (p = ents; p <= last; p++) {
+ if (p->len != dentry->d_name.len)
+ continue;
+ if (!memcmp(dentry->d_name.name, p->name, p->len))
+ break;
+ }
+ if (p > last)
+ goto out;
+
+ error = proc_pident_instantiate(dir, dentry, task, p);
+out:
+ put_task_struct(task);
+out_no_task:
+ return error;
+}
+
+static int proc_pident_fill_cache(struct file *filp, void *dirent, filldir_t filldir,
+ struct task_struct *task, struct pid_entry *p)
+{
+ return proc_fill_cache(filp, dirent, filldir, p->name, p->len,
+ proc_pident_instantiate, task, p);
+}
+
+static int proc_pident_readdir(struct file *filp,
+ void *dirent, filldir_t filldir,
+ struct pid_entry *ents, unsigned int nents)
+{
+ int i;
+ int pid;
+ struct dentry *dentry = filp->f_dentry;
+ struct inode *inode = dentry->d_inode;
+ struct task_struct *task = get_proc_task(inode);
+ struct pid_entry *p, *last;
+ ino_t ino;
+ int ret;
+
+ ret = -ENOENT;
+ if (!task)
+ goto out_no_task;
+
+ ret = 0;
+ pid = task->pid;
+ i = filp->f_pos;
+ switch (i) {
+ case 0:
+ ino = inode->i_ino;
+ if (filldir(dirent, ".", 1, i, ino, DT_DIR) < 0)
+ goto out;
+ i++;
+ filp->f_pos++;
+ /* fall through */
+ case 1:
+ ino = parent_ino(dentry);
+ if (filldir(dirent, "..", 2, i, ino, DT_DIR) < 0)
+ goto out;
+ i++;
+ filp->f_pos++;
+ /* fall through */
+ default:
+ i -= 2;
+ if (i >= nents) {
+ ret = 1;
+ goto out;
+ }
+ p = ents + i;
+ last = &ents[nents - 1];
+ while (p <= last) {
+ if (proc_pident_fill_cache(filp, dirent, filldir, task, p) < 0)
+ goto out;
+ filp->f_pos++;
+ p++;
+ }
+ }
+
+ ret = 1;
+out:
+ put_task_struct(task);
+out_no_task:
+ return ret;
+}
#ifdef CONFIG_SECURITY
static ssize_t proc_pid_attr_read(struct file * file, char __user * buf,
@@ -1580,8 +1506,8 @@ static ssize_t proc_pid_attr_read(struct file * file, char __user * buf,
if (!(page = __get_free_page(GFP_KERNEL)))
goto out;
- length = security_getprocattr(task,
- (char*)file->f_dentry->d_name.name,
+ length = security_getprocattr(task,
+ (char*)file->f_dentry->d_name.name,
(void*)page, count);
if (length >= 0)
length = simple_read_from_buffer(buf, count, ppos, (char *)page, length);
@@ -1594,17 +1520,17 @@ out_no_task:
static ssize_t proc_pid_attr_write(struct file * file, const char __user * buf,
size_t count, loff_t *ppos)
-{
+{
struct inode * inode = file->f_dentry->d_inode;
- char *page;
- ssize_t length;
+ char *page;
+ ssize_t length;
struct task_struct *task = get_proc_task(inode);
length = -ESRCH;
if (!task)
goto out_no_task;
- if (count > PAGE_SIZE)
- count = PAGE_SIZE;
+ if (count > PAGE_SIZE)
+ count = PAGE_SIZE;
/* No partial writes. */
length = -EINVAL;
@@ -1612,16 +1538,16 @@ static ssize_t proc_pid_attr_write(struct file * file, const char __user * buf,
goto out;
length = -ENOMEM;
- page = (char*)__get_free_page(GFP_USER);
- if (!page)
+ page = (char*)__get_free_page(GFP_USER);
+ if (!page)
goto out;
- length = -EFAULT;
- if (copy_from_user(page, buf, count))
+ length = -EFAULT;
+ if (copy_from_user(page, buf, count))
goto out_free;
- length = security_setprocattr(task,
- (char*)file->f_dentry->d_name.name,
+ length = security_setprocattr(task,
+ (char*)file->f_dentry->d_name.name,
(void*)page, count);
out_free:
free_page((unsigned long) page);
@@ -1629,330 +1555,263 @@ out:
put_task_struct(task);
out_no_task:
return length;
-}
+}
static struct file_operations proc_pid_attr_operations = {
.read = proc_pid_attr_read,
.write = proc_pid_attr_write,
};
-static struct file_operations proc_tid_attr_operations;
-static struct inode_operations proc_tid_attr_inode_operations;
-static struct file_operations proc_tgid_attr_operations;
-static struct inode_operations proc_tgid_attr_inode_operations;
+static struct pid_entry attr_dir_stuff[] = {
+ REG("current", S_IRUGO|S_IWUGO, pid_attr),
+ REG("prev", S_IRUGO, pid_attr),
+ REG("exec", S_IRUGO|S_IWUGO, pid_attr),
+ REG("fscreate", S_IRUGO|S_IWUGO, pid_attr),
+ REG("keycreate", S_IRUGO|S_IWUGO, pid_attr),
+ REG("sockcreate", S_IRUGO|S_IWUGO, pid_attr),
+};
+
+static int proc_attr_dir_readdir(struct file * filp,
+ void * dirent, filldir_t filldir)
+{
+ return proc_pident_readdir(filp,dirent,filldir,
+ attr_dir_stuff,ARRAY_SIZE(attr_dir_stuff));
+}
+
+static struct file_operations proc_attr_dir_operations = {
+ .read = generic_read_dir,
+ .readdir = proc_attr_dir_readdir,
+};
+
+static struct dentry *proc_attr_dir_lookup(struct inode *dir,
+ struct dentry *dentry, struct nameidata *nd)
+{
+ return proc_pident_lookup(dir, dentry,
+ attr_dir_stuff, ARRAY_SIZE(attr_dir_stuff));
+}
+
+static struct inode_operations proc_attr_dir_inode_operations = {
+ .lookup = proc_attr_dir_lookup,
+ .getattr = pid_getattr,
+ .setattr = proc_setattr,
+};
+
#endif
-/* SMP-safe */
-static struct dentry *proc_pident_lookup(struct inode *dir,
- struct dentry *dentry,
- struct pid_entry *ents)
+/*
+ * /proc/self:
+ */
+static int proc_self_readlink(struct dentry *dentry, char __user *buffer,
+ int buflen)
+{
+ char tmp[PROC_NUMBUF];
+ sprintf(tmp, "%d", current->tgid);
+ return vfs_readlink(dentry,buffer,buflen,tmp);
+}
+
+static void *proc_self_follow_link(struct dentry *dentry, struct nameidata *nd)
{
+ char tmp[PROC_NUMBUF];
+ sprintf(tmp, "%d", current->tgid);
+ return ERR_PTR(vfs_follow_link(nd,tmp));
+}
+
+static struct inode_operations proc_self_inode_operations = {
+ .readlink = proc_self_readlink,
+ .follow_link = proc_self_follow_link,
+};
+
+/*
+ * proc base
+ *
+ * These are the directory entries in the root directory of /proc
+ * that properly belong to the /proc filesystem, as they describe
+ * describe something that is process related.
+ */
+static struct pid_entry proc_base_stuff[] = {
+ NOD("self", S_IFLNK|S_IRWXUGO,
+ &proc_self_inode_operations, NULL, {}),
+};
+
+/*
+ * Exceptional case: normally we are not allowed to unhash a busy
+ * directory. In this case, however, we can do it - no aliasing problems
+ * due to the way we treat inodes.
+ */
+static int proc_base_revalidate(struct dentry *dentry, struct nameidata *nd)
+{
+ struct inode *inode = dentry->d_inode;
+ struct task_struct *task = get_proc_task(inode);
+ if (task) {
+ put_task_struct(task);
+ return 1;
+ }
+ d_drop(dentry);
+ return 0;
+}
+
+static struct dentry_operations proc_base_dentry_operations =
+{
+ .d_revalidate = proc_base_revalidate,
+ .d_delete = pid_delete_dentry,
+};
+
+static struct dentry *proc_base_instantiate(struct inode *dir,
+ struct dentry *dentry, struct task_struct *task, void *ptr)
+{
+ struct pid_entry *p = ptr;
struct inode *inode;
+ struct proc_inode *ei;
+ struct dentry *error = ERR_PTR(-EINVAL);
+
+ /* Allocate the inode */
+ error = ERR_PTR(-ENOMEM);
+ inode = new_inode(dir->i_sb);
+ if (!inode)
+ goto out;
+
+ /* Initialize the inode */
+ ei = PROC_I(inode);
+ inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
+
+ /*
+ * grab the reference to the task.
+ */
+ ei->pid = get_task_pid(task, PIDTYPE_PID);
+ if (!ei->pid)
+ goto out_iput;
+
+ inode->i_uid = 0;
+ inode->i_gid = 0;
+ inode->i_mode = p->mode;
+ if (S_ISDIR(inode->i_mode))
+ inode->i_nlink = 2;
+ if (S_ISLNK(inode->i_mode))
+ inode->i_size = 64;
+ if (p->iop)
+ inode->i_op = p->iop;
+ if (p->fop)
+ inode->i_fop = p->fop;
+ ei->op = p->op;
+ dentry->d_op = &proc_base_dentry_operations;
+ d_add(dentry, inode);
+ error = NULL;
+out:
+ return error;
+out_iput:
+ iput(inode);
+ goto out;
+}
+
+static struct dentry *proc_base_lookup(struct inode *dir, struct dentry *dentry)
+{
struct dentry *error;
struct task_struct *task = get_proc_task(dir);
- struct pid_entry *p;
- struct proc_inode *ei;
+ struct pid_entry *p, *last;
error = ERR_PTR(-ENOENT);
- inode = NULL;
if (!task)
goto out_no_task;
- for (p = ents; p->name; p++) {
+ /* Lookup the directory entry */
+ last = &proc_base_stuff[ARRAY_SIZE(proc_base_stuff) - 1];
+ for (p = proc_base_stuff; p <= last; p++) {
if (p->len != dentry->d_name.len)
continue;
if (!memcmp(dentry->d_name.name, p->name, p->len))
break;
}
- if (!p->name)
+ if (p > last)
goto out;
- error = ERR_PTR(-EINVAL);
- inode = proc_pid_make_inode(dir->i_sb, task, p->type);
- if (!inode)
- goto out;
+ error = proc_base_instantiate(dir, dentry, task, p);
- ei = PROC_I(inode);
- inode->i_mode = p->mode;
- /*
- * Yes, it does not scale. And it should not. Don't add
- * new entries into /proc/<tgid>/ without very good reasons.
- */
- switch(p->type) {
- case PROC_TGID_TASK:
- inode->i_nlink = 2;
- inode->i_op = &proc_task_inode_operations;
- inode->i_fop = &proc_task_operations;
- break;
- case PROC_TID_FD:
- case PROC_TGID_FD:
- inode->i_nlink = 2;
- inode->i_op = &proc_fd_inode_operations;
- inode->i_fop = &proc_fd_operations;
- break;
- case PROC_TID_EXE:
- case PROC_TGID_EXE:
- inode->i_op = &proc_pid_link_inode_operations;
- ei->op.proc_get_link = proc_exe_link;
- break;
- case PROC_TID_CWD:
- case PROC_TGID_CWD:
- inode->i_op = &proc_pid_link_inode_operations;
- ei->op.proc_get_link = proc_cwd_link;
- break;
- case PROC_TID_ROOT:
- case PROC_TGID_ROOT:
- inode->i_op = &proc_pid_link_inode_operations;
- ei->op.proc_get_link = proc_root_link;
- break;
- case PROC_TID_ENVIRON:
- case PROC_TGID_ENVIRON:
- inode->i_fop = &proc_info_file_operations;
- ei->op.proc_read = proc_pid_environ;
- break;
- case PROC_TID_AUXV:
- case PROC_TGID_AUXV:
- inode->i_fop = &proc_info_file_operations;
- ei->op.proc_read = proc_pid_auxv;
- break;
- case PROC_TID_STATUS:
- case PROC_TGID_STATUS:
- inode->i_fop = &proc_info_file_operations;
- ei->op.proc_read = proc_pid_status;
- break;
- case PROC_TID_STAT:
- inode->i_fop = &proc_info_file_operations;
- ei->op.proc_read = proc_tid_stat;
- break;
- case PROC_TGID_STAT:
- inode->i_fop = &proc_info_file_operations;
- ei->op.proc_read = proc_tgid_stat;
- break;
- case PROC_TID_CMDLINE:
- case PROC_TGID_CMDLINE:
- inode->i_fop = &proc_info_file_operations;
- ei->op.proc_read = proc_pid_cmdline;
- break;
- case PROC_TID_STATM:
- case PROC_TGID_STATM:
- inode->i_fop = &proc_info_file_operations;
- ei->op.proc_read = proc_pid_statm;
- break;
- case PROC_TID_MAPS:
- case PROC_TGID_MAPS:
- inode->i_fop = &proc_maps_operations;
- break;
+out:
+ put_task_struct(task);
+out_no_task:
+ return error;
+}
+
+static int proc_base_fill_cache(struct file *filp, void *dirent, filldir_t filldir,
+ struct task_struct *task, struct pid_entry *p)
+{
+ return proc_fill_cache(filp, dirent, filldir, p->name, p->len,
+ proc_base_instantiate, task, p);
+}
+
+/*
+ * Thread groups
+ */
+static struct file_operations proc_task_operations;
+static struct inode_operations proc_task_inode_operations;
+
+static struct pid_entry tgid_base_stuff[] = {
+ DIR("task", S_IRUGO|S_IXUGO, task),
+ DIR("fd", S_IRUSR|S_IXUSR, fd),
+ INF("environ", S_IRUSR, pid_environ),
+ INF("auxv", S_IRUSR, pid_auxv),
+ INF("status", S_IRUGO, pid_status),
+ INF("cmdline", S_IRUGO, pid_cmdline),
+ INF("stat", S_IRUGO, tgid_stat),
+ INF("statm", S_IRUGO, pid_statm),
+ REG("maps", S_IRUGO, maps),
#ifdef CONFIG_NUMA
- case PROC_TID_NUMA_MAPS:
- case PROC_TGID_NUMA_MAPS:
- inode->i_fop = &proc_numa_maps_operations;
- break;
+ REG("numa_maps", S_IRUGO, numa_maps),
#endif
- case PROC_TID_MEM:
- case PROC_TGID_MEM:
- inode->i_fop = &proc_mem_operations;
- break;
+ REG("mem", S_IRUSR|S_IWUSR, mem),
#ifdef CONFIG_SECCOMP
- case PROC_TID_SECCOMP:
- case PROC_TGID_SECCOMP:
- inode->i_fop = &proc_seccomp_operations;
- break;
-#endif /* CONFIG_SECCOMP */
- case PROC_TID_MOUNTS:
- case PROC_TGID_MOUNTS:
- inode->i_fop = &proc_mounts_operations;
- break;
+ REG("seccomp", S_IRUSR|S_IWUSR, seccomp),
+#endif
+ LNK("cwd", cwd),
+ LNK("root", root),
+ LNK("exe", exe),
+ REG("mounts", S_IRUGO, mounts),
+ REG("mountstats", S_IRUSR, mountstats),
#ifdef CONFIG_MMU
- case PROC_TID_SMAPS:
- case PROC_TGID_SMAPS:
- inode->i_fop = &proc_smaps_operations;
- break;
+ REG("smaps", S_IRUGO, smaps),
#endif
- case PROC_TID_MOUNTSTATS:
- case PROC_TGID_MOUNTSTATS:
- inode->i_fop = &proc_mountstats_operations;
- break;
#ifdef CONFIG_SECURITY
- case PROC_TID_ATTR:
- inode->i_nlink = 2;
- inode->i_op = &proc_tid_attr_inode_operations;
- inode->i_fop = &proc_tid_attr_operations;
- break;
- case PROC_TGID_ATTR:
- inode->i_nlink = 2;
- inode->i_op = &proc_tgid_attr_inode_operations;
- inode->i_fop = &proc_tgid_attr_operations;
- break;
- case PROC_TID_ATTR_CURRENT:
- case PROC_TGID_ATTR_CURRENT:
- case PROC_TID_ATTR_PREV:
- case PROC_TGID_ATTR_PREV:
- case PROC_TID_ATTR_EXEC:
- case PROC_TGID_ATTR_EXEC:
- case PROC_TID_ATTR_FSCREATE:
- case PROC_TGID_ATTR_FSCREATE:
- case PROC_TID_ATTR_KEYCREATE:
- case PROC_TGID_ATTR_KEYCREATE:
- case PROC_TID_ATTR_SOCKCREATE:
- case PROC_TGID_ATTR_SOCKCREATE:
- inode->i_fop = &proc_pid_attr_operations;
- break;
+ DIR("attr", S_IRUGO|S_IXUGO, attr_dir),
#endif
#ifdef CONFIG_KALLSYMS
- case PROC_TID_WCHAN:
- case PROC_TGID_WCHAN:
- inode->i_fop = &proc_info_file_operations;
- ei->op.proc_read = proc_pid_wchan;
- break;
+ INF("wchan", S_IRUGO, pid_wchan),
#endif
#ifdef CONFIG_SCHEDSTATS
- case PROC_TID_SCHEDSTAT:
- case PROC_TGID_SCHEDSTAT:
- inode->i_fop = &proc_info_file_operations;
- ei->op.proc_read = proc_pid_schedstat;
- break;
+ INF("schedstat", S_IRUGO, pid_schedstat),
#endif
#ifdef CONFIG_CPUSETS
- case PROC_TID_CPUSET:
- case PROC_TGID_CPUSET:
- inode->i_fop = &proc_cpuset_operations;
- break;
+ REG("cpuset", S_IRUGO, cpuset),
#endif
- case PROC_TID_OOM_SCORE:
- case PROC_TGID_OOM_SCORE:
- inode->i_fop = &proc_info_file_operations;
- ei->op.proc_read = proc_oom_score;
- break;
- case PROC_TID_OOM_ADJUST:
- case PROC_TGID_OOM_ADJUST:
- inode->i_fop = &proc_oom_adjust_operations;
- break;
+ INF("oom_score", S_IRUGO, oom_score),
+ REG("oom_adj", S_IRUGO|S_IWUSR, oom_adjust),
#ifdef CONFIG_AUDITSYSCALL
- case PROC_TID_LOGINUID:
- case PROC_TGID_LOGINUID:
- inode->i_fop = &proc_loginuid_operations;
- break;
+ REG("loginuid", S_IWUSR|S_IRUGO, loginuid),
#endif
- default:
- printk("procfs: impossible type (%d)",p->type);
- iput(inode);
- error = ERR_PTR(-EINVAL);
- goto out;
- }
- dentry->d_op = &pid_dentry_operations;
- d_add(dentry, inode);
- /* Close the race of the process dying before we return the dentry */
- if (pid_revalidate(dentry, NULL))
- error = NULL;
-out:
- put_task_struct(task);
-out_no_task:
- return error;
-}
-
-static struct dentry *proc_tgid_base_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd){
- return proc_pident_lookup(dir, dentry, tgid_base_stuff);
-}
-
-static struct dentry *proc_tid_base_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd){
- return proc_pident_lookup(dir, dentry, tid_base_stuff);
-}
-
-static struct file_operations proc_tgid_base_operations = {
- .read = generic_read_dir,
- .readdir = proc_tgid_base_readdir,
};
-static struct file_operations proc_tid_base_operations = {
- .read = generic_read_dir,
- .readdir = proc_tid_base_readdir,
-};
-
-static struct inode_operations proc_tgid_base_inode_operations = {
- .lookup = proc_tgid_base_lookup,
- .getattr = pid_getattr,
- .setattr = proc_setattr,
-};
-
-static struct inode_operations proc_tid_base_inode_operations = {
- .lookup = proc_tid_base_lookup,
- .getattr = pid_getattr,
- .setattr = proc_setattr,
-};
-
-#ifdef CONFIG_SECURITY
-static int proc_tgid_attr_readdir(struct file * filp,
- void * dirent, filldir_t filldir)
-{
- return proc_pident_readdir(filp,dirent,filldir,
- tgid_attr_stuff,ARRAY_SIZE(tgid_attr_stuff));
-}
-
-static int proc_tid_attr_readdir(struct file * filp,
+static int proc_tgid_base_readdir(struct file * filp,
void * dirent, filldir_t filldir)
{
return proc_pident_readdir(filp,dirent,filldir,
- tid_attr_stuff,ARRAY_SIZE(tid_attr_stuff));
+ tgid_base_stuff,ARRAY_SIZE(tgid_base_stuff));
}
-static struct file_operations proc_tgid_attr_operations = {
- .read = generic_read_dir,
- .readdir = proc_tgid_attr_readdir,
-};
-
-static struct file_operations proc_tid_attr_operations = {
+static struct file_operations proc_tgid_base_operations = {
.read = generic_read_dir,
- .readdir = proc_tid_attr_readdir,
+ .readdir = proc_tgid_base_readdir,
};
-static struct dentry *proc_tgid_attr_lookup(struct inode *dir,
- struct dentry *dentry, struct nameidata *nd)
-{
- return proc_pident_lookup(dir, dentry, tgid_attr_stuff);
-}
-
-static struct dentry *proc_tid_attr_lookup(struct inode *dir,
- struct dentry *dentry, struct nameidata *nd)
-{
- return proc_pident_lookup(dir, dentry, tid_attr_stuff);
+static struct dentry *proc_tgid_base_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd){
+ return proc_pident_lookup(dir, dentry,
+ tgid_base_stuff, ARRAY_SIZE(tgid_base_stuff));
}
-static struct inode_operations proc_tgid_attr_inode_operations = {
- .lookup = proc_tgid_attr_lookup,
- .getattr = pid_getattr,
- .setattr = proc_setattr,
-};
-
-static struct inode_operations proc_tid_attr_inode_operations = {
- .lookup = proc_tid_attr_lookup,
+static struct inode_operations proc_tgid_base_inode_operations = {
+ .lookup = proc_tgid_base_lookup,
.getattr = pid_getattr,
.setattr = proc_setattr,
};
-#endif
-
-/*
- * /proc/self:
- */
-static int proc_self_readlink(struct dentry *dentry, char __user *buffer,
- int buflen)
-{
- char tmp[PROC_NUMBUF];
- sprintf(tmp, "%d", current->tgid);
- return vfs_readlink(dentry,buffer,buflen,tmp);
-}
-
-static void *proc_self_follow_link(struct dentry *dentry, struct nameidata *nd)
-{
- char tmp[PROC_NUMBUF];
- sprintf(tmp, "%d", current->tgid);
- return ERR_PTR(vfs_follow_link(nd,tmp));
-}
-
-static struct inode_operations proc_self_inode_operations = {
- .readlink = proc_self_readlink,
- .follow_link = proc_self_follow_link,
-};
/**
* proc_flush_task - Remove dcache entries for @task from the /proc dcache.
@@ -2021,54 +1880,23 @@ out:
return;
}
-/* SMP-safe */
-struct dentry *proc_pid_lookup(struct inode *dir, struct dentry * dentry, struct nameidata *nd)
+struct dentry *proc_pid_instantiate(struct inode *dir,
+ struct dentry * dentry, struct task_struct *task, void *ptr)
{
- struct dentry *result = ERR_PTR(-ENOENT);
- struct task_struct *task;
+ struct dentry *error = ERR_PTR(-ENOENT);
struct inode *inode;
- struct proc_inode *ei;
- unsigned tgid;
-
- if (dentry->d_name.len == 4 && !memcmp(dentry->d_name.name,"self",4)) {
- inode = new_inode(dir->i_sb);
- if (!inode)
- return ERR_PTR(-ENOMEM);
- ei = PROC_I(inode);
- inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
- inode->i_ino = fake_ino(0, PROC_TGID_INO);
- ei->pde = NULL;
- inode->i_mode = S_IFLNK|S_IRWXUGO;
- inode->i_uid = inode->i_gid = 0;
- inode->i_size = 64;
- inode->i_op = &proc_self_inode_operations;
- d_add(dentry, inode);
- return NULL;
- }
- tgid = name_to_int(dentry);
- if (tgid == ~0U)
- goto out;
- rcu_read_lock();
- task = find_task_by_pid(tgid);
- if (task)
- get_task_struct(task);
- rcu_read_unlock();
- if (!task)
- goto out;
-
- inode = proc_pid_make_inode(dir->i_sb, task, PROC_TGID_INO);
+ inode = proc_pid_make_inode(dir->i_sb, task);
if (!inode)
- goto out_put_task;
+ goto out;
inode->i_mode = S_IFDIR|S_IRUGO|S_IXUGO;
inode->i_op = &proc_tgid_base_inode_operations;
inode->i_fop = &proc_tgid_base_operations;
inode->i_flags|=S_IMMUTABLE;
-#ifdef CONFIG_SECURITY
- inode->i_nlink = 5;
-#else
inode->i_nlink = 4;
+#ifdef CONFIG_SECURITY
+ inode->i_nlink += 1;
#endif
dentry->d_op = &pid_dentry_operations;
@@ -2076,179 +1904,251 @@ struct dentry *proc_pid_lookup(struct inode *dir, struct dentry * dentry, struct
d_add(dentry, inode);
/* Close the race of the process dying before we return the dentry */
if (pid_revalidate(dentry, NULL))
- result = NULL;
-
-out_put_task:
- put_task_struct(task);
+ error = NULL;
out:
- return result;
+ return error;
}
-/* SMP-safe */
-static struct dentry *proc_task_lookup(struct inode *dir, struct dentry * dentry, struct nameidata *nd)
+struct dentry *proc_pid_lookup(struct inode *dir, struct dentry * dentry, struct nameidata *nd)
{
struct dentry *result = ERR_PTR(-ENOENT);
struct task_struct *task;
- struct task_struct *leader = get_proc_task(dir);
- struct inode *inode;
- unsigned tid;
+ unsigned tgid;
- if (!leader)
- goto out_no_task;
+ result = proc_base_lookup(dir, dentry);
+ if (!IS_ERR(result) || PTR_ERR(result) != -ENOENT)
+ goto out;
- tid = name_to_int(dentry);
- if (tid == ~0U)
+ tgid = name_to_int(dentry);
+ if (tgid == ~0U)
goto out;
rcu_read_lock();
- task = find_task_by_pid(tid);
+ task = find_task_by_pid(tgid);
if (task)
get_task_struct(task);
rcu_read_unlock();
if (!task)
goto out;
- if (leader->tgid != task->tgid)
- goto out_drop_task;
-
- inode = proc_pid_make_inode(dir->i_sb, task, PROC_TID_INO);
-
-
- if (!inode)
- goto out_drop_task;
- inode->i_mode = S_IFDIR|S_IRUGO|S_IXUGO;
- inode->i_op = &proc_tid_base_inode_operations;
- inode->i_fop = &proc_tid_base_operations;
- inode->i_flags|=S_IMMUTABLE;
-#ifdef CONFIG_SECURITY
- inode->i_nlink = 4;
-#else
- inode->i_nlink = 3;
-#endif
-
- dentry->d_op = &pid_dentry_operations;
-
- d_add(dentry, inode);
- /* Close the race of the process dying before we return the dentry */
- if (pid_revalidate(dentry, NULL))
- result = NULL;
-out_drop_task:
+ result = proc_pid_instantiate(dir, dentry, task, NULL);
put_task_struct(task);
out:
- put_task_struct(leader);
-out_no_task:
return result;
}
/*
- * Find the first tgid to return to user space.
- *
- * Usually this is just whatever follows &init_task, but if the users
- * buffer was too small to hold the full list or there was a seek into
- * the middle of the directory we have more work to do.
- *
- * In the case of a short read we start with find_task_by_pid.
+ * Find the first task with tgid >= tgid
*
- * In the case of a seek we start with &init_task and walk nr
- * threads past it.
*/
-static struct task_struct *first_tgid(int tgid, unsigned int nr)
+static struct task_struct *next_tgid(unsigned int tgid)
{
- struct task_struct *pos;
- rcu_read_lock();
- if (tgid && nr) {
- pos = find_task_by_pid(tgid);
- if (pos && thread_group_leader(pos))
- goto found;
- }
- /* If nr exceeds the number of processes get out quickly */
- pos = NULL;
- if (nr && nr >= nr_processes())
- goto done;
+ struct task_struct *task;
+ struct pid *pid;
- /* If we haven't found our starting place yet start with
- * the init_task and walk nr tasks forward.
- */
- for (pos = next_task(&init_task); nr > 0; --nr) {
- pos = next_task(pos);
- if (pos == &init_task) {
- pos = NULL;
- goto done;
- }
+ rcu_read_lock();
+retry:
+ task = NULL;
+ pid = find_ge_pid(tgid);
+ if (pid) {
+ tgid = pid->nr + 1;
+ task = pid_task(pid, PIDTYPE_PID);
+ /* What we to know is if the pid we have find is the
+ * pid of a thread_group_leader. Testing for task
+ * being a thread_group_leader is the obvious thing
+ * todo but there is a window when it fails, due to
+ * the pid transfer logic in de_thread.
+ *
+ * So we perform the straight forward test of seeing
+ * if the pid we have found is the pid of a thread
+ * group leader, and don't worry if the task we have
+ * found doesn't happen to be a thread group leader.
+ * As we don't care in the case of readdir.
+ */
+ if (!task || !has_group_leader_pid(task))
+ goto retry;
+ get_task_struct(task);
}
-found:
- get_task_struct(pos);
-done:
rcu_read_unlock();
- return pos;
+ return task;
}
-/*
- * Find the next task in the task list.
- * Return NULL if we loop or there is any error.
- *
- * The reference to the input task_struct is released.
- */
-static struct task_struct *next_tgid(struct task_struct *start)
+#define TGID_OFFSET (FIRST_PROCESS_ENTRY + ARRAY_SIZE(proc_base_stuff))
+
+static int proc_pid_fill_cache(struct file *filp, void *dirent, filldir_t filldir,
+ struct task_struct *task, int tgid)
{
- struct task_struct *pos;
- rcu_read_lock();
- pos = start;
- if (pid_alive(start))
- pos = next_task(start);
- if (pid_alive(pos) && (pos != &init_task)) {
- get_task_struct(pos);
- goto done;
- }
- pos = NULL;
-done:
- rcu_read_unlock();
- put_task_struct(start);
- return pos;
+ char name[PROC_NUMBUF];
+ int len = snprintf(name, sizeof(name), "%d", tgid);
+ return proc_fill_cache(filp, dirent, filldir, name, len,
+ proc_pid_instantiate, task, NULL);
}
/* for the /proc/ directory itself, after non-process stuff has been done */
int proc_pid_readdir(struct file * filp, void * dirent, filldir_t filldir)
{
- char buf[PROC_NUMBUF];
unsigned int nr = filp->f_pos - FIRST_PROCESS_ENTRY;
+ struct task_struct *reaper = get_proc_task(filp->f_dentry->d_inode);
struct task_struct *task;
int tgid;
- if (!nr) {
- ino_t ino = fake_ino(0,PROC_TGID_INO);
- if (filldir(dirent, "self", 4, filp->f_pos, ino, DT_LNK) < 0)
- return 0;
- filp->f_pos++;
- nr++;
+ if (!reaper)
+ goto out_no_task;
+
+ for (; nr < ARRAY_SIZE(proc_base_stuff); filp->f_pos++, nr++) {
+ struct pid_entry *p = &proc_base_stuff[nr];
+ if (proc_base_fill_cache(filp, dirent, filldir, reaper, p) < 0)
+ goto out;
}
- nr -= 1;
- /* f_version caches the tgid value that the last readdir call couldn't
- * return. lseek aka telldir automagically resets f_version to 0.
- */
- tgid = filp->f_version;
- filp->f_version = 0;
- for (task = first_tgid(tgid, nr);
+ tgid = filp->f_pos - TGID_OFFSET;
+ for (task = next_tgid(tgid);
task;
- task = next_tgid(task), filp->f_pos++) {
- int len;
- ino_t ino;
+ put_task_struct(task), task = next_tgid(tgid + 1)) {
tgid = task->pid;
- len = snprintf(buf, sizeof(buf), "%d", tgid);
- ino = fake_ino(tgid, PROC_TGID_INO);
- if (filldir(dirent, buf, len, filp->f_pos, ino, DT_DIR) < 0) {
- /* returning this tgid failed, save it as the first
- * pid for the next readir call */
- filp->f_version = tgid;
+ filp->f_pos = tgid + TGID_OFFSET;
+ if (proc_pid_fill_cache(filp, dirent, filldir, task, tgid) < 0) {
put_task_struct(task);
- break;
+ goto out;
}
}
+ filp->f_pos = PID_MAX_LIMIT + TGID_OFFSET;
+out:
+ put_task_struct(reaper);
+out_no_task:
return 0;
}
/*
+ * Tasks
+ */
+static struct pid_entry tid_base_stuff[] = {
+ DIR("fd", S_IRUSR|S_IXUSR, fd),
+ INF("environ", S_IRUSR, pid_environ),
+ INF("auxv", S_IRUSR, pid_auxv),
+ INF("status", S_IRUGO, pid_status),
+ INF("cmdline", S_IRUGO, pid_cmdline),
+ INF("stat", S_IRUGO, tid_stat),
+ INF("statm", S_IRUGO, pid_statm),
+ REG("maps", S_IRUGO, maps),
+#ifdef CONFIG_NUMA
+ REG("numa_maps", S_IRUGO, numa_maps),
+#endif
+ REG("mem", S_IRUSR|S_IWUSR, mem),
+#ifdef CONFIG_SECCOMP
+ REG("seccomp", S_IRUSR|S_IWUSR, seccomp),
+#endif
+ LNK("cwd", cwd),
+ LNK("root", root),
+ LNK("exe", exe),
+ REG("mounts", S_IRUGO, mounts),
+#ifdef CONFIG_MMU
+ REG("smaps", S_IRUGO, smaps),
+#endif
+#ifdef CONFIG_SECURITY
+ DIR("attr", S_IRUGO|S_IXUGO, attr_dir),
+#endif
+#ifdef CONFIG_KALLSYMS
+ INF("wchan", S_IRUGO, pid_wchan),
+#endif
+#ifdef CONFIG_SCHEDSTATS
+ INF("schedstat", S_IRUGO, pid_schedstat),
+#endif
+#ifdef CONFIG_CPUSETS
+ REG("cpuset", S_IRUGO, cpuset),
+#endif
+ INF("oom_score", S_IRUGO, oom_score),
+ REG("oom_adj", S_IRUGO|S_IWUSR, oom_adjust),
+#ifdef CONFIG_AUDITSYSCALL
+ REG("loginuid", S_IWUSR|S_IRUGO, loginuid),
+#endif
+};
+
+static int proc_tid_base_readdir(struct file * filp,
+ void * dirent, filldir_t filldir)
+{
+ return proc_pident_readdir(filp,dirent,filldir,
+ tid_base_stuff,ARRAY_SIZE(tid_base_stuff));
+}
+
+static struct dentry *proc_tid_base_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd){
+ return proc_pident_lookup(dir, dentry,
+ tid_base_stuff, ARRAY_SIZE(tid_base_stuff));
+}
+
+static struct file_operations proc_tid_base_operations = {
+ .read = generic_read_dir,
+ .readdir = proc_tid_base_readdir,
+};
+
+static struct inode_operations proc_tid_base_inode_operations = {
+ .lookup = proc_tid_base_lookup,
+ .getattr = pid_getattr,
+ .setattr = proc_setattr,
+};
+
+static struct dentry *proc_task_instantiate(struct inode *dir,
+ struct dentry *dentry, struct task_struct *task, void *ptr)
+{
+ struct dentry *error = ERR_PTR(-ENOENT);
+ struct inode *inode;
+ inode = proc_pid_make_inode(dir->i_sb, task);
+
+ if (!inode)
+ goto out;
+ inode->i_mode = S_IFDIR|S_IRUGO|S_IXUGO;
+ inode->i_op = &proc_tid_base_inode_operations;
+ inode->i_fop = &proc_tid_base_operations;
+ inode->i_flags|=S_IMMUTABLE;
+ inode->i_nlink = 3;
+#ifdef CONFIG_SECURITY
+ inode->i_nlink += 1;
+#endif
+
+ dentry->d_op = &pid_dentry_operations;
+
+ d_add(dentry, inode);
+ /* Close the race of the process dying before we return the dentry */
+ if (pid_revalidate(dentry, NULL))
+ error = NULL;
+out:
+ return error;
+}
+
+static struct dentry *proc_task_lookup(struct inode *dir, struct dentry * dentry, struct nameidata *nd)
+{
+ struct dentry *result = ERR_PTR(-ENOENT);
+ struct task_struct *task;
+ struct task_struct *leader = get_proc_task(dir);
+ unsigned tid;
+
+ if (!leader)
+ goto out_no_task;
+
+ tid = name_to_int(dentry);
+ if (tid == ~0U)
+ goto out;
+
+ rcu_read_lock();
+ task = find_task_by_pid(tid);
+ if (task)
+ get_task_struct(task);
+ rcu_read_unlock();
+ if (!task)
+ goto out;
+ if (leader->tgid != task->tgid)
+ goto out_drop_task;
+
+ result = proc_task_instantiate(dir, dentry, task, NULL);
+out_drop_task:
+ put_task_struct(task);
+out:
+ put_task_struct(leader);
+out_no_task:
+ return result;
+}
+
+/*
* Find the first tid of a thread group to return to user space.
*
* Usually this is just the thread group leader, but if the users
@@ -2317,10 +2217,18 @@ static struct task_struct *next_tid(struct task_struct *start)
return pos;
}
+static int proc_task_fill_cache(struct file *filp, void *dirent, filldir_t filldir,
+ struct task_struct *task, int tid)
+{
+ char name[PROC_NUMBUF];
+ int len = snprintf(name, sizeof(name), "%d", tid);
+ return proc_fill_cache(filp, dirent, filldir, name, len,
+ proc_task_instantiate, task, NULL);
+}
+
/* for the /proc/TGID/task/ directories */
static int proc_task_readdir(struct file * filp, void * dirent, filldir_t filldir)
{
- char buf[PROC_NUMBUF];
struct dentry *dentry = filp->f_dentry;
struct inode *inode = dentry->d_inode;
struct task_struct *leader = get_proc_task(inode);
@@ -2357,11 +2265,8 @@ static int proc_task_readdir(struct file * filp, void * dirent, filldir_t filldi
for (task = first_tid(leader, tid, pos - 2);
task;
task = next_tid(task), pos++) {
- int len;
tid = task->pid;
- len = snprintf(buf, sizeof(buf), "%d", tid);
- ino = fake_ino(tid, PROC_TID_INO);
- if (filldir(dirent, buf, len, pos, ino, DT_DIR < 0)) {
+ if (proc_task_fill_cache(filp, dirent, filldir, task, tid) < 0) {
/* returning this tgid failed, save it as the first
* pid for the next readir call */
filp->f_version = tid;
@@ -2391,3 +2296,14 @@ static int proc_task_getattr(struct vfsmount *mnt, struct dentry *dentry, struct
return 0;
}
+
+static struct inode_operations proc_task_inode_operations = {
+ .lookup = proc_task_lookup,
+ .getattr = proc_task_getattr,
+ .setattr = proc_setattr,
+};
+
+static struct file_operations proc_task_operations = {
+ .read = generic_read_dir,
+ .readdir = proc_task_readdir,
+};
diff --git a/fs/proc/kcore.c b/fs/proc/kcore.c
index 3ceff3857272..1294eda4acae 100644
--- a/fs/proc/kcore.c
+++ b/fs/proc/kcore.c
@@ -100,7 +100,7 @@ static int notesize(struct memelfnote *en)
int sz;
sz = sizeof(struct elf_note);
- sz += roundup(strlen(en->name), 4);
+ sz += roundup((strlen(en->name) + 1), 4);
sz += roundup(en->datasz, 4);
return sz;
@@ -116,7 +116,7 @@ static char *storenote(struct memelfnote *men, char *bufp)
#define DUMP_WRITE(addr,nr) do { memcpy(bufp,addr,nr); bufp += nr; } while(0)
- en.n_namesz = strlen(men->name);
+ en.n_namesz = strlen(men->name) + 1;
en.n_descsz = men->datasz;
en.n_type = men->type;
diff --git a/fs/proc/proc_misc.c b/fs/proc/proc_misc.c
index 5bbd60896050..8d88e58ed5cc 100644
--- a/fs/proc/proc_misc.c
+++ b/fs/proc/proc_misc.c
@@ -45,6 +45,7 @@
#include <linux/sysrq.h>
#include <linux/vmalloc.h>
#include <linux/crash_dump.h>
+#include <linux/pspace.h>
#include <asm/uaccess.h>
#include <asm/pgtable.h>
#include <asm/io.h>
@@ -91,7 +92,7 @@ static int loadavg_read_proc(char *page, char **start, off_t off,
LOAD_INT(a), LOAD_FRAC(a),
LOAD_INT(b), LOAD_FRAC(b),
LOAD_INT(c), LOAD_FRAC(c),
- nr_running(), nr_threads, last_pid);
+ nr_running(), nr_threads, init_pspace.last_pid);
return proc_calc_metrics(page, start, off, count, eof, len);
}
@@ -277,12 +278,15 @@ static int devinfo_show(struct seq_file *f, void *v)
if (i == 0)
seq_printf(f, "Character devices:\n");
chrdev_show(f, i);
- } else {
+ }
+#ifdef CONFIG_BLOCK
+ else {
i -= CHRDEV_MAJOR_HASH_SIZE;
if (i == 0)
seq_printf(f, "\nBlock devices:\n");
blkdev_show(f, i);
}
+#endif
return 0;
}
@@ -355,6 +359,7 @@ static int stram_read_proc(char *page, char **start, off_t off,
}
#endif
+#ifdef CONFIG_BLOCK
extern struct seq_operations partitions_op;
static int partitions_open(struct inode *inode, struct file *file)
{
@@ -378,6 +383,7 @@ static struct file_operations proc_diskstats_operations = {
.llseek = seq_lseek,
.release = seq_release,
};
+#endif
#ifdef CONFIG_MODULES
extern struct seq_operations modules_op;
@@ -695,7 +701,9 @@ void __init proc_misc_init(void)
entry->proc_fops = &proc_kmsg_operations;
create_seq_entry("devices", 0, &proc_devinfo_operations);
create_seq_entry("cpuinfo", 0, &proc_cpuinfo_operations);
+#ifdef CONFIG_BLOCK
create_seq_entry("partitions", 0, &proc_partitions_operations);
+#endif
create_seq_entry("stat", 0, &proc_stat_operations);
create_seq_entry("interrupts", 0, &proc_interrupts_operations);
#ifdef CONFIG_SLAB
@@ -707,7 +715,9 @@ void __init proc_misc_init(void)
create_seq_entry("buddyinfo",S_IRUGO, &fragmentation_file_operations);
create_seq_entry("vmstat",S_IRUGO, &proc_vmstat_file_operations);
create_seq_entry("zoneinfo",S_IRUGO, &proc_zoneinfo_file_operations);
+#ifdef CONFIG_BLOCK
create_seq_entry("diskstats", 0, &proc_diskstats_operations);
+#endif
#ifdef CONFIG_MODULES
create_seq_entry("modules", 0, &proc_modules_operations);
#endif
diff --git a/fs/proc/root.c b/fs/proc/root.c
index 8901c65caca8..ffe66c38488b 100644
--- a/fs/proc/root.c
+++ b/fs/proc/root.c
@@ -16,6 +16,7 @@
#include <linux/module.h>
#include <linux/bitops.h>
#include <linux/smp_lock.h>
+#include <linux/mount.h>
#include "internal.h"
@@ -28,6 +29,17 @@ struct proc_dir_entry *proc_sys_root;
static int proc_get_sb(struct file_system_type *fs_type,
int flags, const char *dev_name, void *data, struct vfsmount *mnt)
{
+ if (proc_mnt) {
+ /* Seed the root directory with a pid so it doesn't need
+ * to be special in base.c. I would do this earlier but
+ * the only task alive when /proc is mounted the first time
+ * is the init_task and it doesn't have any pids.
+ */
+ struct proc_inode *ei;
+ ei = PROC_I(proc_mnt->mnt_sb->s_root->d_inode);
+ if (!ei->pid)
+ ei->pid = find_get_pid(1);
+ }
return get_sb_single(fs_type, flags, data, proc_fill_super, mnt);
}
diff --git a/fs/qnx4/file.c b/fs/qnx4/file.c
index 62af4b1348bd..467e5ac7280e 100644
--- a/fs/qnx4/file.c
+++ b/fs/qnx4/file.c
@@ -22,11 +22,13 @@
const struct file_operations qnx4_file_operations =
{
.llseek = generic_file_llseek,
- .read = generic_file_read,
+ .read = do_sync_read,
+ .aio_read = generic_file_aio_read,
.mmap = generic_file_mmap,
.sendfile = generic_file_sendfile,
#ifdef CONFIG_QNX4FS_RW
- .write = generic_file_write,
+ .write = do_sync_write,
+ .aio_write = generic_file_aio_write,
.fsync = qnx4_sync_file,
#endif
};
diff --git a/fs/qnx4/namei.c b/fs/qnx4/namei.c
index c3d83f67154a..733cdf01d645 100644
--- a/fs/qnx4/namei.c
+++ b/fs/qnx4/namei.c
@@ -186,11 +186,10 @@ int qnx4_rmdir(struct inode *dir, struct dentry *dentry)
memset(de->di_fname, 0, sizeof de->di_fname);
de->di_mode = 0;
mark_buffer_dirty(bh);
- inode->i_nlink = 0;
+ clear_nlink(inode);
mark_inode_dirty(inode);
inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME_SEC;
- dir->i_nlink--;
- mark_inode_dirty(dir);
+ inode_dec_link_count(dir);
retval = 0;
end_rmdir:
@@ -234,9 +233,8 @@ int qnx4_unlink(struct inode *dir, struct dentry *dentry)
mark_buffer_dirty(bh);
dir->i_ctime = dir->i_mtime = CURRENT_TIME_SEC;
mark_inode_dirty(dir);
- inode->i_nlink--;
inode->i_ctime = dir->i_ctime;
- mark_inode_dirty(inode);
+ inode_dec_link_count(inode);
retval = 0;
end_unlink:
diff --git a/fs/quota.c b/fs/quota.c
index d6a2be826e29..b9dae76a0b6e 100644
--- a/fs/quota.c
+++ b/fs/quota.c
@@ -338,6 +338,34 @@ static int do_quotactl(struct super_block *sb, int type, int cmd, qid_t id, void
}
/*
+ * look up a superblock on which quota ops will be performed
+ * - use the name of a block device to find the superblock thereon
+ */
+static inline struct super_block *quotactl_block(const char __user *special)
+{
+#ifdef CONFIG_BLOCK
+ struct block_device *bdev;
+ struct super_block *sb;
+ char *tmp = getname(special);
+
+ if (IS_ERR(tmp))
+ return ERR_PTR(PTR_ERR(tmp));
+ bdev = lookup_bdev(tmp);
+ putname(tmp);
+ if (IS_ERR(bdev))
+ return ERR_PTR(PTR_ERR(bdev));
+ sb = get_super(bdev);
+ bdput(bdev);
+ if (!sb)
+ return ERR_PTR(-ENODEV);
+
+ return sb;
+#else
+ return ERR_PTR(-ENODEV);
+#endif
+}
+
+/*
* This is the system call interface. This communicates with
* the user-level programs. Currently this only supports diskquota
* calls. Maybe we need to add the process quotas etc. in the future,
@@ -347,25 +375,15 @@ asmlinkage long sys_quotactl(unsigned int cmd, const char __user *special, qid_t
{
uint cmds, type;
struct super_block *sb = NULL;
- struct block_device *bdev;
- char *tmp;
int ret;
cmds = cmd >> SUBCMDSHIFT;
type = cmd & SUBCMDMASK;
if (cmds != Q_SYNC || special) {
- tmp = getname(special);
- if (IS_ERR(tmp))
- return PTR_ERR(tmp);
- bdev = lookup_bdev(tmp);
- putname(tmp);
- if (IS_ERR(bdev))
- return PTR_ERR(bdev);
- sb = get_super(bdev);
- bdput(bdev);
- if (!sb)
- return -ENODEV;
+ sb = quotactl_block(special);
+ if (IS_ERR(sb))
+ return PTR_ERR(sb);
}
ret = check_quotactl_valid(sb, type, cmds, id);
diff --git a/fs/ramfs/file-mmu.c b/fs/ramfs/file-mmu.c
index 86f14cacf641..0947fb57dcf3 100644
--- a/fs/ramfs/file-mmu.c
+++ b/fs/ramfs/file-mmu.c
@@ -33,8 +33,10 @@ const struct address_space_operations ramfs_aops = {
};
const struct file_operations ramfs_file_operations = {
- .read = generic_file_read,
- .write = generic_file_write,
+ .read = do_sync_read,
+ .aio_read = generic_file_aio_read,
+ .write = do_sync_write,
+ .aio_write = generic_file_aio_write,
.mmap = generic_file_mmap,
.fsync = simple_sync_file,
.sendfile = generic_file_sendfile,
diff --git a/fs/ramfs/file-nommu.c b/fs/ramfs/file-nommu.c
index 677139b48e00..bfe5dbf1002e 100644
--- a/fs/ramfs/file-nommu.c
+++ b/fs/ramfs/file-nommu.c
@@ -36,8 +36,10 @@ const struct address_space_operations ramfs_aops = {
const struct file_operations ramfs_file_operations = {
.mmap = ramfs_nommu_mmap,
.get_unmapped_area = ramfs_nommu_get_unmapped_area,
- .read = generic_file_read,
- .write = generic_file_write,
+ .read = do_sync_read,
+ .aio_read = generic_file_aio_read,
+ .write = do_sync_write,
+ .aio_write = generic_file_aio_write,
.fsync = simple_sync_file,
.sendfile = generic_file_sendfile,
.llseek = generic_file_llseek,
diff --git a/fs/ramfs/inode.c b/fs/ramfs/inode.c
index bc0e51662424..2faf4cdf61b0 100644
--- a/fs/ramfs/inode.c
+++ b/fs/ramfs/inode.c
@@ -75,7 +75,7 @@ struct inode *ramfs_get_inode(struct super_block *sb, int mode, dev_t dev)
inode->i_fop = &simple_dir_operations;
/* directory inodes start off with i_nlink == 2 (for "." entry) */
- inode->i_nlink++;
+ inc_nlink(inode);
break;
case S_IFLNK:
inode->i_op = &page_symlink_inode_operations;
@@ -113,7 +113,7 @@ static int ramfs_mkdir(struct inode * dir, struct dentry * dentry, int mode)
{
int retval = ramfs_mknod(dir, dentry, mode | S_IFDIR, 0);
if (!retval)
- dir->i_nlink++;
+ inc_nlink(dir);
return retval;
}
diff --git a/fs/read_write.c b/fs/read_write.c
index d4cb3183c99c..f792000a28e6 100644
--- a/fs/read_write.c
+++ b/fs/read_write.c
@@ -15,13 +15,15 @@
#include <linux/module.h>
#include <linux/syscalls.h>
#include <linux/pagemap.h>
+#include "read_write.h"
#include <asm/uaccess.h>
#include <asm/unistd.h>
const struct file_operations generic_ro_fops = {
.llseek = generic_file_llseek,
- .read = generic_file_read,
+ .read = do_sync_read,
+ .aio_read = generic_file_aio_read,
.mmap = generic_file_readonly_mmap,
.sendfile = generic_file_sendfile,
};
@@ -227,14 +229,20 @@ static void wait_on_retry_sync_kiocb(struct kiocb *iocb)
ssize_t do_sync_read(struct file *filp, char __user *buf, size_t len, loff_t *ppos)
{
+ struct iovec iov = { .iov_base = buf, .iov_len = len };
struct kiocb kiocb;
ssize_t ret;
init_sync_kiocb(&kiocb, filp);
kiocb.ki_pos = *ppos;
- while (-EIOCBRETRY ==
- (ret = filp->f_op->aio_read(&kiocb, buf, len, kiocb.ki_pos)))
+ kiocb.ki_left = len;
+
+ for (;;) {
+ ret = filp->f_op->aio_read(&kiocb, &iov, 1, kiocb.ki_pos);
+ if (ret != -EIOCBRETRY)
+ break;
wait_on_retry_sync_kiocb(&kiocb);
+ }
if (-EIOCBQUEUED == ret)
ret = wait_on_sync_kiocb(&kiocb);
@@ -279,14 +287,20 @@ EXPORT_SYMBOL(vfs_read);
ssize_t do_sync_write(struct file *filp, const char __user *buf, size_t len, loff_t *ppos)
{
+ struct iovec iov = { .iov_base = (void __user *)buf, .iov_len = len };
struct kiocb kiocb;
ssize_t ret;
init_sync_kiocb(&kiocb, filp);
kiocb.ki_pos = *ppos;
- while (-EIOCBRETRY ==
- (ret = filp->f_op->aio_write(&kiocb, buf, len, kiocb.ki_pos)))
+ kiocb.ki_left = len;
+
+ for (;;) {
+ ret = filp->f_op->aio_write(&kiocb, &iov, 1, kiocb.ki_pos);
+ if (ret != -EIOCBRETRY)
+ break;
wait_on_retry_sync_kiocb(&kiocb);
+ }
if (-EIOCBQUEUED == ret)
ret = wait_on_sync_kiocb(&kiocb);
@@ -438,78 +452,155 @@ unsigned long iov_shorten(struct iovec *iov, unsigned long nr_segs, size_t to)
EXPORT_UNUSED_SYMBOL(iov_shorten); /* June 2006 */
+ssize_t do_sync_readv_writev(struct file *filp, const struct iovec *iov,
+ unsigned long nr_segs, size_t len, loff_t *ppos, iov_fn_t fn)
+{
+ struct kiocb kiocb;
+ ssize_t ret;
+
+ init_sync_kiocb(&kiocb, filp);
+ kiocb.ki_pos = *ppos;
+ kiocb.ki_left = len;
+ kiocb.ki_nbytes = len;
+
+ for (;;) {
+ ret = fn(&kiocb, iov, nr_segs, kiocb.ki_pos);
+ if (ret != -EIOCBRETRY)
+ break;
+ wait_on_retry_sync_kiocb(&kiocb);
+ }
+
+ if (ret == -EIOCBQUEUED)
+ ret = wait_on_sync_kiocb(&kiocb);
+ *ppos = kiocb.ki_pos;
+ return ret;
+}
+
+/* Do it by hand, with file-ops */
+ssize_t do_loop_readv_writev(struct file *filp, struct iovec *iov,
+ unsigned long nr_segs, loff_t *ppos, io_fn_t fn)
+{
+ struct iovec *vector = iov;
+ ssize_t ret = 0;
+
+ while (nr_segs > 0) {
+ void __user *base;
+ size_t len;
+ ssize_t nr;
+
+ base = vector->iov_base;
+ len = vector->iov_len;
+ vector++;
+ nr_segs--;
+
+ nr = fn(filp, base, len, ppos);
+
+ if (nr < 0) {
+ if (!ret)
+ ret = nr;
+ break;
+ }
+ ret += nr;
+ if (nr != len)
+ break;
+ }
+
+ return ret;
+}
+
/* A write operation does a read from user space and vice versa */
#define vrfy_dir(type) ((type) == READ ? VERIFY_WRITE : VERIFY_READ)
+ssize_t rw_copy_check_uvector(int type, const struct iovec __user * uvector,
+ unsigned long nr_segs, unsigned long fast_segs,
+ struct iovec *fast_pointer,
+ struct iovec **ret_pointer)
+ {
+ unsigned long seg;
+ ssize_t ret;
+ struct iovec *iov = fast_pointer;
+
+ /*
+ * SuS says "The readv() function *may* fail if the iovcnt argument
+ * was less than or equal to 0, or greater than {IOV_MAX}. Linux has
+ * traditionally returned zero for zero segments, so...
+ */
+ if (nr_segs == 0) {
+ ret = 0;
+ goto out;
+ }
+
+ /*
+ * First get the "struct iovec" from user memory and
+ * verify all the pointers
+ */
+ if (nr_segs > UIO_MAXIOV) {
+ ret = -EINVAL;
+ goto out;
+ }
+ if (nr_segs > fast_segs) {
+ iov = kmalloc(nr_segs*sizeof(struct iovec), GFP_KERNEL);
+ if (iov == NULL) {
+ ret = -ENOMEM;
+ goto out;
+ }
+ }
+ if (copy_from_user(iov, uvector, nr_segs*sizeof(*uvector))) {
+ ret = -EFAULT;
+ goto out;
+ }
+
+ /*
+ * According to the Single Unix Specification we should return EINVAL
+ * if an element length is < 0 when cast to ssize_t or if the
+ * total length would overflow the ssize_t return value of the
+ * system call.
+ */
+ ret = 0;
+ for (seg = 0; seg < nr_segs; seg++) {
+ void __user *buf = iov[seg].iov_base;
+ ssize_t len = (ssize_t)iov[seg].iov_len;
+
+ /* see if we we're about to use an invalid len or if
+ * it's about to overflow ssize_t */
+ if (len < 0 || (ret + len < ret)) {
+ ret = -EINVAL;
+ goto out;
+ }
+ if (unlikely(!access_ok(vrfy_dir(type), buf, len))) {
+ ret = -EFAULT;
+ goto out;
+ }
+
+ ret += len;
+ }
+out:
+ *ret_pointer = iov;
+ return ret;
+}
+
static ssize_t do_readv_writev(int type, struct file *file,
const struct iovec __user * uvector,
unsigned long nr_segs, loff_t *pos)
{
- typedef ssize_t (*io_fn_t)(struct file *, char __user *, size_t, loff_t *);
- typedef ssize_t (*iov_fn_t)(struct file *, const struct iovec *, unsigned long, loff_t *);
-
size_t tot_len;
struct iovec iovstack[UIO_FASTIOV];
- struct iovec *iov=iovstack, *vector;
+ struct iovec *iov = iovstack;
ssize_t ret;
- int seg;
io_fn_t fn;
iov_fn_t fnv;
- /*
- * SuS says "The readv() function *may* fail if the iovcnt argument
- * was less than or equal to 0, or greater than {IOV_MAX}. Linux has
- * traditionally returned zero for zero segments, so...
- */
- ret = 0;
- if (nr_segs == 0)
+ if (!file->f_op) {
+ ret = -EINVAL;
goto out;
+ }
- /*
- * First get the "struct iovec" from user memory and
- * verify all the pointers
- */
- ret = -EINVAL;
- if (nr_segs > UIO_MAXIOV)
- goto out;
- if (!file->f_op)
- goto out;
- if (nr_segs > UIO_FASTIOV) {
- ret = -ENOMEM;
- iov = kmalloc(nr_segs*sizeof(struct iovec), GFP_KERNEL);
- if (!iov)
- goto out;
- }
- ret = -EFAULT;
- if (copy_from_user(iov, uvector, nr_segs*sizeof(*uvector)))
+ ret = rw_copy_check_uvector(type, uvector, nr_segs,
+ ARRAY_SIZE(iovstack), iovstack, &iov);
+ if (ret <= 0)
goto out;
- /*
- * Single unix specification:
- * We should -EINVAL if an element length is not >= 0 and fitting an
- * ssize_t. The total length is fitting an ssize_t
- *
- * Be careful here because iov_len is a size_t not an ssize_t
- */
- tot_len = 0;
- ret = -EINVAL;
- for (seg = 0; seg < nr_segs; seg++) {
- void __user *buf = iov[seg].iov_base;
- ssize_t len = (ssize_t)iov[seg].iov_len;
-
- if (len < 0) /* size_t not fitting an ssize_t .. */
- goto out;
- if (unlikely(!access_ok(vrfy_dir(type), buf, len)))
- goto Efault;
- tot_len += len;
- if ((ssize_t)tot_len < 0) /* maths overflow on the ssize_t */
- goto out;
- }
- if (tot_len == 0) {
- ret = 0;
- goto out;
- }
-
+ tot_len = ret;
ret = rw_verify_area(type, file, pos, tot_len);
if (ret < 0)
goto out;
@@ -520,39 +611,18 @@ static ssize_t do_readv_writev(int type, struct file *file,
fnv = NULL;
if (type == READ) {
fn = file->f_op->read;
- fnv = file->f_op->readv;
+ fnv = file->f_op->aio_read;
} else {
fn = (io_fn_t)file->f_op->write;
- fnv = file->f_op->writev;
+ fnv = file->f_op->aio_write;
}
- if (fnv) {
- ret = fnv(file, iov, nr_segs, pos);
- goto out;
- }
-
- /* Do it by hand, with file-ops */
- ret = 0;
- vector = iov;
- while (nr_segs > 0) {
- void __user * base;
- size_t len;
- ssize_t nr;
- base = vector->iov_base;
- len = vector->iov_len;
- vector++;
- nr_segs--;
-
- nr = fn(file, base, len, pos);
+ if (fnv)
+ ret = do_sync_readv_writev(file, iov, nr_segs, tot_len,
+ pos, fnv);
+ else
+ ret = do_loop_readv_writev(file, iov, nr_segs, pos, fn);
- if (nr < 0) {
- if (!ret) ret = nr;
- break;
- }
- ret += nr;
- if (nr != len)
- break;
- }
out:
if (iov != iovstack)
kfree(iov);
@@ -563,9 +633,6 @@ out:
fsnotify_modify(file->f_dentry);
}
return ret;
-Efault:
- ret = -EFAULT;
- goto out;
}
ssize_t vfs_readv(struct file *file, const struct iovec __user *vec,
@@ -573,7 +640,7 @@ ssize_t vfs_readv(struct file *file, const struct iovec __user *vec,
{
if (!(file->f_mode & FMODE_READ))
return -EBADF;
- if (!file->f_op || (!file->f_op->readv && !file->f_op->read))
+ if (!file->f_op || (!file->f_op->aio_read && !file->f_op->read))
return -EINVAL;
return do_readv_writev(READ, file, vec, vlen, pos);
@@ -586,7 +653,7 @@ ssize_t vfs_writev(struct file *file, const struct iovec __user *vec,
{
if (!(file->f_mode & FMODE_WRITE))
return -EBADF;
- if (!file->f_op || (!file->f_op->writev && !file->f_op->write))
+ if (!file->f_op || (!file->f_op->aio_write && !file->f_op->write))
return -EINVAL;
return do_readv_writev(WRITE, file, vec, vlen, pos);
diff --git a/fs/read_write.h b/fs/read_write.h
new file mode 100644
index 000000000000..d07b954c6e0c
--- /dev/null
+++ b/fs/read_write.h
@@ -0,0 +1,14 @@
+/*
+ * This file is only for sharing some helpers from read_write.c with compat.c.
+ * Don't use anywhere else.
+ */
+
+
+typedef ssize_t (*io_fn_t)(struct file *, char __user *, size_t, loff_t *);
+typedef ssize_t (*iov_fn_t)(struct kiocb *, const struct iovec *,
+ unsigned long, loff_t);
+
+ssize_t do_sync_readv_writev(struct file *filp, const struct iovec *iov,
+ unsigned long nr_segs, size_t len, loff_t *ppos, iov_fn_t fn);
+ssize_t do_loop_readv_writev(struct file *filp, struct iovec *iov,
+ unsigned long nr_segs, loff_t *ppos, io_fn_t fn);
diff --git a/fs/readdir.c b/fs/readdir.c
index b6109329b607..bff3ee58e2f8 100644
--- a/fs/readdir.c
+++ b/fs/readdir.c
@@ -69,20 +69,24 @@ struct readdir_callback {
};
static int fillonedir(void * __buf, const char * name, int namlen, loff_t offset,
- ino_t ino, unsigned int d_type)
+ u64 ino, unsigned int d_type)
{
struct readdir_callback * buf = (struct readdir_callback *) __buf;
struct old_linux_dirent __user * dirent;
+ unsigned long d_ino;
if (buf->result)
return -EINVAL;
+ d_ino = ino;
+ if (sizeof(d_ino) < sizeof(ino) && d_ino != ino)
+ return -EOVERFLOW;
buf->result++;
dirent = buf->dirent;
if (!access_ok(VERIFY_WRITE, dirent,
(unsigned long)(dirent->d_name + namlen + 1) -
(unsigned long)dirent))
goto efault;
- if ( __put_user(ino, &dirent->d_ino) ||
+ if ( __put_user(d_ino, &dirent->d_ino) ||
__put_user(offset, &dirent->d_offset) ||
__put_user(namlen, &dirent->d_namlen) ||
__copy_to_user(dirent->d_name, name, namlen) ||
@@ -138,22 +142,26 @@ struct getdents_callback {
};
static int filldir(void * __buf, const char * name, int namlen, loff_t offset,
- ino_t ino, unsigned int d_type)
+ u64 ino, unsigned int d_type)
{
struct linux_dirent __user * dirent;
struct getdents_callback * buf = (struct getdents_callback *) __buf;
+ unsigned long d_ino;
int reclen = ROUND_UP(NAME_OFFSET(dirent) + namlen + 2);
buf->error = -EINVAL; /* only used if we fail.. */
if (reclen > buf->count)
return -EINVAL;
+ d_ino = ino;
+ if (sizeof(d_ino) < sizeof(ino) && d_ino != ino)
+ return -EOVERFLOW;
dirent = buf->previous;
if (dirent) {
if (__put_user(offset, &dirent->d_off))
goto efault;
}
dirent = buf->current_dir;
- if (__put_user(ino, &dirent->d_ino))
+ if (__put_user(d_ino, &dirent->d_ino))
goto efault;
if (__put_user(reclen, &dirent->d_reclen))
goto efault;
@@ -222,7 +230,7 @@ struct getdents_callback64 {
};
static int filldir64(void * __buf, const char * name, int namlen, loff_t offset,
- ino_t ino, unsigned int d_type)
+ u64 ino, unsigned int d_type)
{
struct linux_dirent64 __user *dirent;
struct getdents_callback64 * buf = (struct getdents_callback64 *) __buf;
diff --git a/fs/reiserfs/Makefile b/fs/reiserfs/Makefile
index 3a59309f3ca9..0eb7ac080484 100644
--- a/fs/reiserfs/Makefile
+++ b/fs/reiserfs/Makefile
@@ -28,7 +28,7 @@ endif
# will work around it. If any other architecture displays this behavior,
# add it here.
ifeq ($(CONFIG_PPC32),y)
-EXTRA_CFLAGS := -O1
+EXTRA_CFLAGS := $(call cc-ifversion, -lt, 0400, -O1)
endif
TAGS:
diff --git a/fs/reiserfs/bitmap.c b/fs/reiserfs/bitmap.c
index 4a7dbdee1b6d..1bfae42117ca 100644
--- a/fs/reiserfs/bitmap.c
+++ b/fs/reiserfs/bitmap.c
@@ -9,6 +9,7 @@
#include <linux/buffer_head.h>
#include <linux/kernel.h>
#include <linux/pagemap.h>
+#include <linux/vmalloc.h>
#include <linux/reiserfs_fs_sb.h>
#include <linux/reiserfs_fs_i.h>
#include <linux/quotaops.h>
@@ -50,16 +51,15 @@ static inline void get_bit_address(struct super_block *s,
{
/* It is in the bitmap block number equal to the block
* number divided by the number of bits in a block. */
- *bmap_nr = block / (s->s_blocksize << 3);
+ *bmap_nr = block >> (s->s_blocksize_bits + 3);
/* Within that bitmap block it is located at bit offset *offset. */
*offset = block & ((s->s_blocksize << 3) - 1);
- return;
}
#ifdef CONFIG_REISERFS_CHECK
int is_reusable(struct super_block *s, b_blocknr_t block, int bit_value)
{
- int i, j;
+ int bmap, offset;
if (block == 0 || block >= SB_BLOCK_COUNT(s)) {
reiserfs_warning(s,
@@ -68,36 +68,32 @@ int is_reusable(struct super_block *s, b_blocknr_t block, int bit_value)
return 0;
}
- /* it can't be one of the bitmap blocks */
- for (i = 0; i < SB_BMAP_NR(s); i++)
- if (block == SB_AP_BITMAP(s)[i].bh->b_blocknr) {
+ get_bit_address(s, block, &bmap, &offset);
+
+ /* Old format filesystem? Unlikely, but the bitmaps are all up front so
+ * we need to account for it. */
+ if (unlikely(test_bit(REISERFS_OLD_FORMAT,
+ &(REISERFS_SB(s)->s_properties)))) {
+ b_blocknr_t bmap1 = REISERFS_SB(s)->s_sbh->b_blocknr + 1;
+ if (block >= bmap1 && block <= bmap1 + SB_BMAP_NR(s)) {
+ reiserfs_warning(s, "vs: 4019: is_reusable: "
+ "bitmap block %lu(%u) can't be freed or reused",
+ block, SB_BMAP_NR(s));
+ return 0;
+ }
+ } else {
+ if (offset == 0) {
reiserfs_warning(s, "vs: 4020: is_reusable: "
"bitmap block %lu(%u) can't be freed or reused",
block, SB_BMAP_NR(s));
return 0;
}
-
- get_bit_address(s, block, &i, &j);
-
- if (i >= SB_BMAP_NR(s)) {
- reiserfs_warning(s,
- "vs-4030: is_reusable: there is no so many bitmap blocks: "
- "block=%lu, bitmap_nr=%d", block, i);
- return 0;
}
- if ((bit_value == 0 &&
- reiserfs_test_le_bit(j, SB_AP_BITMAP(s)[i].bh->b_data)) ||
- (bit_value == 1 &&
- reiserfs_test_le_bit(j, SB_AP_BITMAP(s)[i].bh->b_data) == 0)) {
+ if (bmap >= SB_BMAP_NR(s)) {
reiserfs_warning(s,
- "vs-4040: is_reusable: corresponding bit of block %lu does not "
- "match required value (i==%d, j==%d) test_bit==%d",
- block, i, j, reiserfs_test_le_bit(j,
- SB_AP_BITMAP
- (s)[i].bh->
- b_data));
-
+ "vs-4030: is_reusable: there is no so many bitmap blocks: "
+ "block=%lu, bitmap_nr=%d", block, bmap);
return 0;
}
@@ -141,6 +137,7 @@ static int scan_bitmap_block(struct reiserfs_transaction_handle *th,
{
struct super_block *s = th->t_super;
struct reiserfs_bitmap_info *bi = &SB_AP_BITMAP(s)[bmap_n];
+ struct buffer_head *bh;
int end, next;
int org = *beg;
@@ -159,22 +156,25 @@ static int scan_bitmap_block(struct reiserfs_transaction_handle *th,
bmap_n);
return 0;
}
- if (buffer_locked(bi->bh)) {
- PROC_INFO_INC(s, scan_bitmap.wait);
- __wait_on_buffer(bi->bh);
- }
+
+ bh = reiserfs_read_bitmap_block(s, bmap_n);
+ if (bh == NULL)
+ return 0;
while (1) {
cont:
- if (bi->free_count < min)
+ if (bi->free_count < min) {
+ brelse(bh);
return 0; // No free blocks in this bitmap
+ }
/* search for a first zero bit -- beggining of a window */
*beg = reiserfs_find_next_zero_le_bit
- ((unsigned long *)(bi->bh->b_data), boundary, *beg);
+ ((unsigned long *)(bh->b_data), boundary, *beg);
if (*beg + min > boundary) { /* search for a zero bit fails or the rest of bitmap block
* cannot contain a zero window of minimum size */
+ brelse(bh);
return 0;
}
@@ -183,7 +183,7 @@ static int scan_bitmap_block(struct reiserfs_transaction_handle *th,
/* first zero bit found; we check next bits */
for (end = *beg + 1;; end++) {
if (end >= *beg + max || end >= boundary
- || reiserfs_test_le_bit(end, bi->bh->b_data)) {
+ || reiserfs_test_le_bit(end, bh->b_data)) {
next = end;
break;
}
@@ -197,12 +197,12 @@ static int scan_bitmap_block(struct reiserfs_transaction_handle *th,
* (end) points to one bit after the window end */
if (end - *beg >= min) { /* it seems we have found window of proper size */
int i;
- reiserfs_prepare_for_journal(s, bi->bh, 1);
+ reiserfs_prepare_for_journal(s, bh, 1);
/* try to set all blocks used checking are they still free */
for (i = *beg; i < end; i++) {
/* It seems that we should not check in journal again. */
if (reiserfs_test_and_set_le_bit
- (i, bi->bh->b_data)) {
+ (i, bh->b_data)) {
/* bit was set by another process
* while we slept in prepare_for_journal() */
PROC_INFO_INC(s, scan_bitmap.stolen);
@@ -214,17 +214,16 @@ static int scan_bitmap_block(struct reiserfs_transaction_handle *th,
/* otherwise we clear all bit were set ... */
while (--i >= *beg)
reiserfs_test_and_clear_le_bit
- (i, bi->bh->b_data);
- reiserfs_restore_prepared_buffer(s,
- bi->
- bh);
+ (i, bh->b_data);
+ reiserfs_restore_prepared_buffer(s, bh);
*beg = org;
/* ... and search again in current block from beginning */
goto cont;
}
}
bi->free_count -= (end - *beg);
- journal_mark_dirty(th, s, bi->bh);
+ journal_mark_dirty(th, s, bh);
+ brelse(bh);
/* free block count calculation */
reiserfs_prepare_for_journal(s, SB_BUFFER_WITH_SB(s),
@@ -266,9 +265,20 @@ static int bmap_hash_id(struct super_block *s, u32 id)
*/
static inline int block_group_used(struct super_block *s, u32 id)
{
- int bm;
- bm = bmap_hash_id(s, id);
- if (SB_AP_BITMAP(s)[bm].free_count > ((s->s_blocksize << 3) * 60 / 100)) {
+ int bm = bmap_hash_id(s, id);
+ struct reiserfs_bitmap_info *info = &SB_AP_BITMAP(s)[bm];
+
+ /* If we don't have cached information on this bitmap block, we're
+ * going to have to load it later anyway. Loading it here allows us
+ * to make a better decision. This favors long-term performace gain
+ * with a better on-disk layout vs. a short term gain of skipping the
+ * read and potentially having a bad placement. */
+ if (info->first_zero_hint == 0) {
+ struct buffer_head *bh = reiserfs_read_bitmap_block(s, bm);
+ brelse(bh);
+ }
+
+ if (info->free_count > ((s->s_blocksize << 3) * 60 / 100)) {
return 0;
}
return 1;
@@ -373,7 +383,7 @@ static void _reiserfs_free_block(struct reiserfs_transaction_handle *th,
{
struct super_block *s = th->t_super;
struct reiserfs_super_block *rs;
- struct buffer_head *sbh;
+ struct buffer_head *sbh, *bmbh;
struct reiserfs_bitmap_info *apbi;
int nr, offset;
@@ -394,16 +404,21 @@ static void _reiserfs_free_block(struct reiserfs_transaction_handle *th,
return;
}
- reiserfs_prepare_for_journal(s, apbi[nr].bh, 1);
+ bmbh = reiserfs_read_bitmap_block(s, nr);
+ if (!bmbh)
+ return;
+
+ reiserfs_prepare_for_journal(s, bmbh, 1);
/* clear bit for the given block in bit map */
- if (!reiserfs_test_and_clear_le_bit(offset, apbi[nr].bh->b_data)) {
+ if (!reiserfs_test_and_clear_le_bit(offset, bmbh->b_data)) {
reiserfs_warning(s, "vs-4080: reiserfs_free_block: "
"free_block (%s:%lu)[dev:blocknr]: bit already cleared",
reiserfs_bdevname(s), block);
}
apbi[nr].free_count++;
- journal_mark_dirty(th, s, apbi[nr].bh);
+ journal_mark_dirty(th, s, bmbh);
+ brelse(bmbh);
reiserfs_prepare_for_journal(s, sbh, 1);
/* update super block */
@@ -1019,7 +1034,6 @@ static inline int blocknrs_and_prealloc_arrays_from_search_start
b_blocknr_t finish = SB_BLOCK_COUNT(s) - 1;
int passno = 0;
int nr_allocated = 0;
- int bigalloc = 0;
determine_prealloc_size(hint);
if (!hint->formatted_node) {
@@ -1046,28 +1060,9 @@ static inline int blocknrs_and_prealloc_arrays_from_search_start
hint->preallocate = hint->prealloc_size = 0;
}
/* for unformatted nodes, force large allocations */
- bigalloc = amount_needed;
}
do {
- /* in bigalloc mode, nr_allocated should stay zero until
- * the entire allocation is filled
- */
- if (unlikely(bigalloc && nr_allocated)) {
- reiserfs_warning(s, "bigalloc is %d, nr_allocated %d\n",
- bigalloc, nr_allocated);
- /* reset things to a sane value */
- bigalloc = amount_needed - nr_allocated;
- }
- /*
- * try pass 0 and pass 1 looking for a nice big
- * contiguous allocation. Then reset and look
- * for anything you can find.
- */
- if (passno == 2 && bigalloc) {
- passno = 0;
- bigalloc = 0;
- }
switch (passno++) {
case 0: /* Search from hint->search_start to end of disk */
start = hint->search_start;
@@ -1105,8 +1100,7 @@ static inline int blocknrs_and_prealloc_arrays_from_search_start
new_blocknrs +
nr_allocated,
start, finish,
- bigalloc ?
- bigalloc : 1,
+ 1,
amount_needed -
nr_allocated,
hint->
@@ -1263,3 +1257,89 @@ int reiserfs_can_fit_pages(struct super_block *sb /* superblock of filesystem
return space > 0 ? space : 0;
}
+
+void reiserfs_cache_bitmap_metadata(struct super_block *sb,
+ struct buffer_head *bh,
+ struct reiserfs_bitmap_info *info)
+{
+ unsigned long *cur = (unsigned long *)(bh->b_data + bh->b_size);
+
+ info->first_zero_hint = 1 << (sb->s_blocksize_bits + 3);
+
+ while (--cur >= (unsigned long *)bh->b_data) {
+ int base = ((char *)cur - bh->b_data) << 3;
+
+ /* 0 and ~0 are special, we can optimize for them */
+ if (*cur == 0) {
+ info->first_zero_hint = base;
+ info->free_count += BITS_PER_LONG;
+ } else if (*cur != ~0L) { /* A mix, investigate */
+ int b;
+ for (b = BITS_PER_LONG - 1; b >= 0; b--) {
+ if (!reiserfs_test_le_bit(b, cur)) {
+ info->first_zero_hint = base + b;
+ info->free_count++;
+ }
+ }
+ }
+ }
+ /* The first bit must ALWAYS be 1 */
+ BUG_ON(info->first_zero_hint == 0);
+}
+
+struct buffer_head *reiserfs_read_bitmap_block(struct super_block *sb,
+ unsigned int bitmap)
+{
+ b_blocknr_t block = (sb->s_blocksize << 3) * bitmap;
+ struct reiserfs_bitmap_info *info = SB_AP_BITMAP(sb) + bitmap;
+ struct buffer_head *bh;
+
+ /* Way old format filesystems had the bitmaps packed up front.
+ * I doubt there are any of these left, but just in case... */
+ if (unlikely(test_bit(REISERFS_OLD_FORMAT,
+ &(REISERFS_SB(sb)->s_properties))))
+ block = REISERFS_SB(sb)->s_sbh->b_blocknr + 1 + bitmap;
+ else if (bitmap == 0)
+ block = (REISERFS_DISK_OFFSET_IN_BYTES >> sb->s_blocksize_bits) + 1;
+
+ bh = sb_bread(sb, block);
+ if (bh == NULL)
+ reiserfs_warning(sb, "sh-2029: %s: bitmap block (#%lu) "
+ "reading failed", __FUNCTION__, bh->b_blocknr);
+ else {
+ if (buffer_locked(bh)) {
+ PROC_INFO_INC(sb, scan_bitmap.wait);
+ __wait_on_buffer(bh);
+ }
+ BUG_ON(!buffer_uptodate(bh));
+ BUG_ON(atomic_read(&bh->b_count) == 0);
+
+ if (info->first_zero_hint == 0)
+ reiserfs_cache_bitmap_metadata(sb, bh, info);
+ }
+
+ return bh;
+}
+
+int reiserfs_init_bitmap_cache(struct super_block *sb)
+{
+ struct reiserfs_bitmap_info *bitmap;
+
+ bitmap = vmalloc(sizeof (*bitmap) * SB_BMAP_NR(sb));
+ if (bitmap == NULL)
+ return -ENOMEM;
+
+ memset(bitmap, 0, sizeof (*bitmap) * SB_BMAP_NR(sb));
+
+ SB_AP_BITMAP(sb) = bitmap;
+
+ return 0;
+}
+
+void reiserfs_free_bitmap_cache(struct super_block *sb)
+{
+ if (SB_AP_BITMAP(sb)) {
+ vfree(SB_AP_BITMAP(sb));
+ SB_AP_BITMAP(sb) = NULL;
+ }
+}
diff --git a/fs/reiserfs/dir.c b/fs/reiserfs/dir.c
index 9aabcc0ccd2d..657050ad7430 100644
--- a/fs/reiserfs/dir.c
+++ b/fs/reiserfs/dir.c
@@ -22,6 +22,9 @@ const struct file_operations reiserfs_dir_operations = {
.readdir = reiserfs_readdir,
.fsync = reiserfs_dir_fsync,
.ioctl = reiserfs_ioctl,
+#ifdef CONFIG_COMPAT
+ .compat_ioctl = reiserfs_compat_ioctl,
+#endif
};
static int reiserfs_dir_fsync(struct file *filp, struct dentry *dentry,
diff --git a/fs/reiserfs/file.c b/fs/reiserfs/file.c
index 1627edd50810..41f24369e47a 100644
--- a/fs/reiserfs/file.c
+++ b/fs/reiserfs/file.c
@@ -2,6 +2,7 @@
* Copyright 2000 by Hans Reiser, licensing governed by reiserfs/README
*/
+#include <linux/config.h>
#include <linux/time.h>
#include <linux/reiserfs_fs.h>
#include <linux/reiserfs_acl.h>
@@ -130,7 +131,7 @@ static int reiserfs_sync_file(struct file *p_s_filp,
reiserfs_write_lock(p_s_inode->i_sb);
barrier_done = reiserfs_commit_for_inode(p_s_inode);
reiserfs_write_unlock(p_s_inode->i_sb);
- if (barrier_done != 1)
+ if (barrier_done != 1 && reiserfs_barrier_flush(p_s_inode->i_sb))
blkdev_issue_flush(p_s_inode->i_sb->s_bdev, NULL);
if (barrier_done < 0)
return barrier_done;
@@ -1333,7 +1334,7 @@ static ssize_t reiserfs_file_write(struct file *file, /* the file we are going t
if (err)
return err;
}
- result = generic_file_write(file, buf, count, ppos);
+ result = do_sync_write(file, buf, count, ppos);
if (after_file_end) { /* Now update i_size and remove the savelink */
struct reiserfs_transaction_handle th;
@@ -1565,10 +1566,14 @@ static ssize_t reiserfs_file_write(struct file *file, /* the file we are going t
}
const struct file_operations reiserfs_file_operations = {
- .read = generic_file_read,
+ .read = do_sync_read,
.write = reiserfs_file_write,
.ioctl = reiserfs_ioctl,
+#ifdef CONFIG_COMPAT
+ .compat_ioctl = reiserfs_compat_ioctl,
+#endif
.mmap = generic_file_mmap,
+ .open = generic_file_open,
.release = reiserfs_file_release,
.fsync = reiserfs_sync_file,
.sendfile = generic_file_sendfile,
diff --git a/fs/reiserfs/inode.c b/fs/reiserfs/inode.c
index 8810fda0da46..7e5a2f5ebeb0 100644
--- a/fs/reiserfs/inode.c
+++ b/fs/reiserfs/inode.c
@@ -1127,9 +1127,9 @@ static void init_inode(struct inode *inode, struct path *path)
REISERFS_I(inode)->i_prealloc_count = 0;
REISERFS_I(inode)->i_trans_id = 0;
REISERFS_I(inode)->i_jl = NULL;
- REISERFS_I(inode)->i_acl_access = NULL;
- REISERFS_I(inode)->i_acl_default = NULL;
- init_rwsem(&REISERFS_I(inode)->xattr_sem);
+ reiserfs_init_acl_access(inode);
+ reiserfs_init_acl_default(inode);
+ reiserfs_init_xattr_rwsem(inode);
if (stat_data_v1(ih)) {
struct stat_data_v1 *sd =
@@ -1834,9 +1834,9 @@ int reiserfs_new_inode(struct reiserfs_transaction_handle *th,
REISERFS_I(inode)->i_attrs =
REISERFS_I(dir)->i_attrs & REISERFS_INHERIT_MASK;
sd_attrs_to_i_attrs(REISERFS_I(inode)->i_attrs, inode);
- REISERFS_I(inode)->i_acl_access = NULL;
- REISERFS_I(inode)->i_acl_default = NULL;
- init_rwsem(&REISERFS_I(inode)->xattr_sem);
+ reiserfs_init_acl_access(inode);
+ reiserfs_init_acl_default(inode);
+ reiserfs_init_xattr_rwsem(inode);
if (old_format_only(sb))
make_le_item_head(&ih, NULL, KEY_FORMAT_3_5, SD_OFFSET,
@@ -1974,11 +1974,13 @@ int reiserfs_new_inode(struct reiserfs_transaction_handle *th,
* iput doesn't deadlock in reiserfs_delete_xattrs. The locking
* code really needs to be reworked, but this will take care of it
* for now. -jeffm */
+#ifdef CONFIG_REISERFS_FS_POSIX_ACL
if (REISERFS_I(dir)->i_acl_default && !IS_ERR(REISERFS_I(dir)->i_acl_default)) {
reiserfs_write_unlock_xattrs(dir->i_sb);
iput(inode);
reiserfs_write_lock_xattrs(dir->i_sb);
} else
+#endif
iput(inode);
return err;
}
diff --git a/fs/reiserfs/ioctl.c b/fs/reiserfs/ioctl.c
index a986b5e1e288..9c57578cb831 100644
--- a/fs/reiserfs/ioctl.c
+++ b/fs/reiserfs/ioctl.c
@@ -9,6 +9,7 @@
#include <asm/uaccess.h>
#include <linux/pagemap.h>
#include <linux/smp_lock.h>
+#include <linux/compat.h>
static int reiserfs_unpack(struct inode *inode, struct file *filp);
@@ -94,6 +95,40 @@ int reiserfs_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
}
}
+#ifdef CONFIG_COMPAT
+long reiserfs_compat_ioctl(struct file *file, unsigned int cmd,
+ unsigned long arg)
+{
+ struct inode *inode = file->f_dentry->d_inode;
+ int ret;
+
+ /* These are just misnamed, they actually get/put from/to user an int */
+ switch (cmd) {
+ case REISERFS_IOC32_UNPACK:
+ cmd = REISERFS_IOC_UNPACK;
+ break;
+ case REISERFS_IOC32_GETFLAGS:
+ cmd = REISERFS_IOC_GETFLAGS;
+ break;
+ case REISERFS_IOC32_SETFLAGS:
+ cmd = REISERFS_IOC_SETFLAGS;
+ break;
+ case REISERFS_IOC32_GETVERSION:
+ cmd = REISERFS_IOC_GETVERSION;
+ break;
+ case REISERFS_IOC32_SETVERSION:
+ cmd = REISERFS_IOC_SETVERSION;
+ break;
+ default:
+ return -ENOIOCTLCMD;
+ }
+ lock_kernel();
+ ret = reiserfs_ioctl(inode, file, cmd, (unsigned long) compat_ptr(arg));
+ unlock_kernel();
+ return ret;
+}
+#endif
+
/*
** reiserfs_unpack
** Function try to convert tail from direct item into indirect.
diff --git a/fs/reiserfs/journal.c b/fs/reiserfs/journal.c
index 9b3672d69367..e6b5ccf23f15 100644
--- a/fs/reiserfs/journal.c
+++ b/fs/reiserfs/journal.c
@@ -1186,6 +1186,21 @@ static struct reiserfs_journal_list *find_newer_jl_for_cn(struct
return NULL;
}
+static int newer_jl_done(struct reiserfs_journal_cnode *cn)
+{
+ struct super_block *sb = cn->sb;
+ b_blocknr_t blocknr = cn->blocknr;
+
+ cn = cn->hprev;
+ while (cn) {
+ if (cn->sb == sb && cn->blocknr == blocknr && cn->jlist &&
+ atomic_read(&cn->jlist->j_commit_left) != 0)
+ return 0;
+ cn = cn->hprev;
+ }
+ return 1;
+}
+
static void remove_journal_hash(struct super_block *,
struct reiserfs_journal_cnode **,
struct reiserfs_journal_list *, unsigned long,
@@ -1604,6 +1619,31 @@ static int flush_journal_list(struct super_block *s,
return err;
}
+static int test_transaction(struct super_block *s,
+ struct reiserfs_journal_list *jl)
+{
+ struct reiserfs_journal_cnode *cn;
+
+ if (jl->j_len == 0 || atomic_read(&jl->j_nonzerolen) == 0)
+ return 1;
+
+ cn = jl->j_realblock;
+ while (cn) {
+ /* if the blocknr == 0, this has been cleared from the hash,
+ ** skip it
+ */
+ if (cn->blocknr == 0) {
+ goto next;
+ }
+ if (cn->bh && !newer_jl_done(cn))
+ return 0;
+ next:
+ cn = cn->next;
+ cond_resched();
+ }
+ return 0;
+}
+
static int write_one_transaction(struct super_block *s,
struct reiserfs_journal_list *jl,
struct buffer_chunk *chunk)
@@ -3433,16 +3473,6 @@ static void flush_async_commits(void *p)
flush_commit_list(p_s_sb, jl, 1);
}
unlock_kernel();
- /*
- * this is a little racey, but there's no harm in missing
- * the filemap_fdata_write
- */
- if (!atomic_read(&journal->j_async_throttle)
- && !reiserfs_is_journal_aborted(journal)) {
- atomic_inc(&journal->j_async_throttle);
- filemap_fdatawrite(p_s_sb->s_bdev->bd_inode->i_mapping);
- atomic_dec(&journal->j_async_throttle);
- }
}
/*
@@ -3844,7 +3874,9 @@ static void flush_old_journal_lists(struct super_block *s)
entry = journal->j_journal_list.next;
jl = JOURNAL_LIST_ENTRY(entry);
/* this check should always be run, to send old lists to disk */
- if (jl->j_timestamp < (now - (JOURNAL_MAX_TRANS_AGE * 4))) {
+ if (jl->j_timestamp < (now - (JOURNAL_MAX_TRANS_AGE * 4)) &&
+ atomic_read(&jl->j_commit_left) == 0 &&
+ test_transaction(s, jl)) {
flush_used_journal_lists(s, jl);
} else {
break;
diff --git a/fs/reiserfs/namei.c b/fs/reiserfs/namei.c
index c61710e49c62..16e9cff8f15d 100644
--- a/fs/reiserfs/namei.c
+++ b/fs/reiserfs/namei.c
@@ -19,8 +19,8 @@
#include <linux/smp_lock.h>
#include <linux/quotaops.h>
-#define INC_DIR_INODE_NLINK(i) if (i->i_nlink != 1) { i->i_nlink++; if (i->i_nlink >= REISERFS_LINK_MAX) i->i_nlink=1; }
-#define DEC_DIR_INODE_NLINK(i) if (i->i_nlink != 1) i->i_nlink--;
+#define INC_DIR_INODE_NLINK(i) if (i->i_nlink != 1) { inc_nlink(i); if (i->i_nlink >= REISERFS_LINK_MAX) i->i_nlink=1; }
+#define DEC_DIR_INODE_NLINK(i) if (i->i_nlink != 1) drop_nlink(i);
// directory item contains array of entry headers. This performs
// binary search through that array
@@ -913,7 +913,7 @@ static int reiserfs_rmdir(struct inode *dir, struct dentry *dentry)
reiserfs_warning(inode->i_sb, "%s: empty directory has nlink "
"!= 2 (%d)", __FUNCTION__, inode->i_nlink);
- inode->i_nlink = 0;
+ clear_nlink(inode);
inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME_SEC;
reiserfs_update_sd(&th, inode);
@@ -994,7 +994,7 @@ static int reiserfs_unlink(struct inode *dir, struct dentry *dentry)
inode->i_nlink = 1;
}
- inode->i_nlink--;
+ drop_nlink(inode);
/*
* we schedule before doing the add_save_link call, save the link
@@ -1006,7 +1006,7 @@ static int reiserfs_unlink(struct inode *dir, struct dentry *dentry)
reiserfs_cut_from_item(&th, &path, &(de.de_entry_key), dir, NULL,
0);
if (retval < 0) {
- inode->i_nlink++;
+ inc_nlink(inode);
goto end_unlink;
}
inode->i_ctime = CURRENT_TIME_SEC;
@@ -1143,7 +1143,7 @@ static int reiserfs_link(struct dentry *old_dentry, struct inode *dir,
}
/* inc before scheduling so reiserfs_unlink knows we are here */
- inode->i_nlink++;
+ inc_nlink(inode);
retval = journal_begin(&th, dir->i_sb, jbegin_count);
if (retval) {
@@ -1473,9 +1473,9 @@ static int reiserfs_rename(struct inode *old_dir, struct dentry *old_dentry,
if (new_dentry_inode) {
// adjust link number of the victim
if (S_ISDIR(new_dentry_inode->i_mode)) {
- new_dentry_inode->i_nlink = 0;
+ clear_nlink(new_dentry_inode);
} else {
- new_dentry_inode->i_nlink--;
+ drop_nlink(new_dentry_inode);
}
new_dentry_inode->i_ctime = ctime;
savelink = new_dentry_inode->i_nlink;
diff --git a/fs/reiserfs/resize.c b/fs/reiserfs/resize.c
index 39cc7f47f5dc..315684793d1d 100644
--- a/fs/reiserfs/resize.c
+++ b/fs/reiserfs/resize.c
@@ -22,6 +22,7 @@ int reiserfs_resize(struct super_block *s, unsigned long block_count_new)
int err = 0;
struct reiserfs_super_block *sb;
struct reiserfs_bitmap_info *bitmap;
+ struct reiserfs_bitmap_info *info;
struct reiserfs_bitmap_info *old_bitmap = SB_AP_BITMAP(s);
struct buffer_head *bh;
struct reiserfs_transaction_handle th;
@@ -127,16 +128,20 @@ int reiserfs_resize(struct super_block *s, unsigned long block_count_new)
* transaction begins, and the new bitmaps don't matter if the
* transaction fails. */
for (i = bmap_nr; i < bmap_nr_new; i++) {
- bitmap[i].bh = sb_getblk(s, i * s->s_blocksize * 8);
- memset(bitmap[i].bh->b_data, 0, sb_blocksize(sb));
- reiserfs_test_and_set_le_bit(0, bitmap[i].bh->b_data);
-
- set_buffer_uptodate(bitmap[i].bh);
- mark_buffer_dirty(bitmap[i].bh);
- sync_dirty_buffer(bitmap[i].bh);
+ /* don't use read_bitmap_block since it will cache
+ * the uninitialized bitmap */
+ bh = sb_bread(s, i * s->s_blocksize * 8);
+ memset(bh->b_data, 0, sb_blocksize(sb));
+ reiserfs_test_and_set_le_bit(0, bh->b_data);
+ reiserfs_cache_bitmap_metadata(s, bh, bitmap + i);
+
+ set_buffer_uptodate(bh);
+ mark_buffer_dirty(bh);
+ sync_dirty_buffer(bh);
// update bitmap_info stuff
bitmap[i].first_zero_hint = 1;
bitmap[i].free_count = sb_blocksize(sb) * 8 - 1;
+ brelse(bh);
}
/* free old bitmap blocks array */
SB_AP_BITMAP(s) = bitmap;
@@ -150,30 +155,46 @@ int reiserfs_resize(struct super_block *s, unsigned long block_count_new)
if (err)
return err;
- /* correct last bitmap blocks in old and new disk layout */
- reiserfs_prepare_for_journal(s, SB_AP_BITMAP(s)[bmap_nr - 1].bh, 1);
+ /* Extend old last bitmap block - new blocks have been made available */
+ info = SB_AP_BITMAP(s) + bmap_nr - 1;
+ bh = reiserfs_read_bitmap_block(s, bmap_nr - 1);
+ if (!bh) {
+ int jerr = journal_end(&th, s, 10);
+ if (jerr)
+ return jerr;
+ return -EIO;
+ }
+
+ reiserfs_prepare_for_journal(s, bh, 1);
for (i = block_r; i < s->s_blocksize * 8; i++)
- reiserfs_test_and_clear_le_bit(i,
- SB_AP_BITMAP(s)[bmap_nr -
- 1].bh->b_data);
- SB_AP_BITMAP(s)[bmap_nr - 1].free_count += s->s_blocksize * 8 - block_r;
- if (!SB_AP_BITMAP(s)[bmap_nr - 1].first_zero_hint)
- SB_AP_BITMAP(s)[bmap_nr - 1].first_zero_hint = block_r;
+ reiserfs_test_and_clear_le_bit(i, bh->b_data);
+ info->free_count += s->s_blocksize * 8 - block_r;
+ if (!info->first_zero_hint)
+ info->first_zero_hint = block_r;
- journal_mark_dirty(&th, s, SB_AP_BITMAP(s)[bmap_nr - 1].bh);
+ journal_mark_dirty(&th, s, bh);
+ brelse(bh);
+
+ /* Correct new last bitmap block - It may not be full */
+ info = SB_AP_BITMAP(s) + bmap_nr_new - 1;
+ bh = reiserfs_read_bitmap_block(s, bmap_nr_new - 1);
+ if (!bh) {
+ int jerr = journal_end(&th, s, 10);
+ if (jerr)
+ return jerr;
+ return -EIO;
+ }
- reiserfs_prepare_for_journal(s, SB_AP_BITMAP(s)[bmap_nr_new - 1].bh, 1);
+ reiserfs_prepare_for_journal(s, bh, 1);
for (i = block_r_new; i < s->s_blocksize * 8; i++)
- reiserfs_test_and_set_le_bit(i,
- SB_AP_BITMAP(s)[bmap_nr_new -
- 1].bh->b_data);
- journal_mark_dirty(&th, s, SB_AP_BITMAP(s)[bmap_nr_new - 1].bh);
+ reiserfs_test_and_set_le_bit(i, bh->b_data);
+ journal_mark_dirty(&th, s, bh);
+ brelse(bh);
- SB_AP_BITMAP(s)[bmap_nr_new - 1].free_count -=
- s->s_blocksize * 8 - block_r_new;
+ info->free_count -= s->s_blocksize * 8 - block_r_new;
/* Extreme case where last bitmap is the only valid block in itself. */
- if (!SB_AP_BITMAP(s)[bmap_nr_new - 1].free_count)
- SB_AP_BITMAP(s)[bmap_nr_new - 1].first_zero_hint = 0;
+ if (!info->free_count)
+ info->first_zero_hint = 0;
/* update super */
reiserfs_prepare_for_journal(s, SB_BUFFER_WITH_SB(s), 1);
free_blocks = SB_FREE_BLOCKS(s);
diff --git a/fs/reiserfs/super.c b/fs/reiserfs/super.c
index b40d4d64d598..c89aa2338191 100644
--- a/fs/reiserfs/super.c
+++ b/fs/reiserfs/super.c
@@ -432,7 +432,6 @@ int remove_save_link(struct inode *inode, int truncate)
static void reiserfs_put_super(struct super_block *s)
{
- int i;
struct reiserfs_transaction_handle th;
th.t_trans_id = 0;
@@ -462,10 +461,7 @@ static void reiserfs_put_super(struct super_block *s)
*/
journal_release(&th, s);
- for (i = 0; i < SB_BMAP_NR(s); i++)
- brelse(SB_AP_BITMAP(s)[i].bh);
-
- vfree(SB_AP_BITMAP(s));
+ reiserfs_free_bitmap_cache(s);
brelse(SB_BUFFER_WITH_SB(s));
@@ -510,8 +506,10 @@ static void init_once(void *foo, kmem_cache_t * cachep, unsigned long flags)
SLAB_CTOR_CONSTRUCTOR) {
INIT_LIST_HEAD(&ei->i_prealloc_list);
inode_init_once(&ei->vfs_inode);
+#ifdef CONFIG_REISERFS_FS_POSIX_ACL
ei->i_acl_access = NULL;
ei->i_acl_default = NULL;
+#endif
}
}
@@ -560,6 +558,7 @@ static void reiserfs_dirty_inode(struct inode *inode)
reiserfs_write_unlock(inode->i_sb);
}
+#ifdef CONFIG_REISERFS_FS_POSIX_ACL
static void reiserfs_clear_inode(struct inode *inode)
{
struct posix_acl *acl;
@@ -574,6 +573,9 @@ static void reiserfs_clear_inode(struct inode *inode)
posix_acl_release(acl);
REISERFS_I(inode)->i_acl_default = NULL;
}
+#else
+#define reiserfs_clear_inode NULL
+#endif
#ifdef CONFIG_QUOTA
static ssize_t reiserfs_quota_write(struct super_block *, int, const char *,
@@ -1237,118 +1239,6 @@ static int reiserfs_remount(struct super_block *s, int *mount_flags, char *arg)
return 0;
}
-/* load_bitmap_info_data - Sets up the reiserfs_bitmap_info structure from disk.
- * @sb - superblock for this filesystem
- * @bi - the bitmap info to be loaded. Requires that bi->bh is valid.
- *
- * This routine counts how many free bits there are, finding the first zero
- * as a side effect. Could also be implemented as a loop of test_bit() calls, or
- * a loop of find_first_zero_bit() calls. This implementation is similar to
- * find_first_zero_bit(), but doesn't return after it finds the first bit.
- * Should only be called on fs mount, but should be fairly efficient anyways.
- *
- * bi->first_zero_hint is considered unset if it == 0, since the bitmap itself
- * will * invariably occupt block 0 represented in the bitmap. The only
- * exception to this is when free_count also == 0, since there will be no
- * free blocks at all.
- */
-
-static void load_bitmap_info_data(struct super_block *sb,
- struct reiserfs_bitmap_info *bi)
-{
- unsigned long *cur = (unsigned long *)bi->bh->b_data;
-
- while ((char *)cur < (bi->bh->b_data + sb->s_blocksize)) {
-
- /* No need to scan if all 0's or all 1's.
- * Since we're only counting 0's, we can simply ignore all 1's */
- if (*cur == 0) {
- if (bi->first_zero_hint == 0) {
- bi->first_zero_hint =
- ((char *)cur - bi->bh->b_data) << 3;
- }
- bi->free_count += sizeof(unsigned long) * 8;
- } else if (*cur != ~0L) {
- int b;
- for (b = 0; b < sizeof(unsigned long) * 8; b++) {
- if (!reiserfs_test_le_bit(b, cur)) {
- bi->free_count++;
- if (bi->first_zero_hint == 0)
- bi->first_zero_hint =
- (((char *)cur -
- bi->bh->b_data) << 3) + b;
- }
- }
- }
- cur++;
- }
-
-#ifdef CONFIG_REISERFS_CHECK
-// This outputs a lot of unneded info on big FSes
-// reiserfs_warning ("bitmap loaded from block %d: %d free blocks",
-// bi->bh->b_blocknr, bi->free_count);
-#endif
-}
-
-static int read_bitmaps(struct super_block *s)
-{
- int i, bmap_nr;
-
- SB_AP_BITMAP(s) =
- vmalloc(sizeof(struct reiserfs_bitmap_info) * SB_BMAP_NR(s));
- if (SB_AP_BITMAP(s) == 0)
- return 1;
- memset(SB_AP_BITMAP(s), 0,
- sizeof(struct reiserfs_bitmap_info) * SB_BMAP_NR(s));
- for (i = 0, bmap_nr =
- REISERFS_DISK_OFFSET_IN_BYTES / s->s_blocksize + 1;
- i < SB_BMAP_NR(s); i++, bmap_nr = s->s_blocksize * 8 * i) {
- SB_AP_BITMAP(s)[i].bh = sb_getblk(s, bmap_nr);
- if (!buffer_uptodate(SB_AP_BITMAP(s)[i].bh))
- ll_rw_block(READ, 1, &SB_AP_BITMAP(s)[i].bh);
- }
- for (i = 0; i < SB_BMAP_NR(s); i++) {
- wait_on_buffer(SB_AP_BITMAP(s)[i].bh);
- if (!buffer_uptodate(SB_AP_BITMAP(s)[i].bh)) {
- reiserfs_warning(s, "sh-2029: reiserfs read_bitmaps: "
- "bitmap block (#%lu) reading failed",
- SB_AP_BITMAP(s)[i].bh->b_blocknr);
- for (i = 0; i < SB_BMAP_NR(s); i++)
- brelse(SB_AP_BITMAP(s)[i].bh);
- vfree(SB_AP_BITMAP(s));
- SB_AP_BITMAP(s) = NULL;
- return 1;
- }
- load_bitmap_info_data(s, SB_AP_BITMAP(s) + i);
- }
- return 0;
-}
-
-static int read_old_bitmaps(struct super_block *s)
-{
- int i;
- struct reiserfs_super_block *rs = SB_DISK_SUPER_BLOCK(s);
- int bmp1 = (REISERFS_OLD_DISK_OFFSET_IN_BYTES / s->s_blocksize) + 1; /* first of bitmap blocks */
-
- /* read true bitmap */
- SB_AP_BITMAP(s) =
- vmalloc(sizeof(struct reiserfs_buffer_info *) * sb_bmap_nr(rs));
- if (SB_AP_BITMAP(s) == 0)
- return 1;
-
- memset(SB_AP_BITMAP(s), 0,
- sizeof(struct reiserfs_buffer_info *) * sb_bmap_nr(rs));
-
- for (i = 0; i < sb_bmap_nr(rs); i++) {
- SB_AP_BITMAP(s)[i].bh = sb_bread(s, bmp1 + i);
- if (!SB_AP_BITMAP(s)[i].bh)
- return 1;
- load_bitmap_info_data(s, SB_AP_BITMAP(s) + i);
- }
-
- return 0;
-}
-
static int read_super_block(struct super_block *s, int offset)
{
struct buffer_head *bh;
@@ -1450,7 +1340,6 @@ static int read_super_block(struct super_block *s, int offset)
/* after journal replay, reread all bitmap and super blocks */
static int reread_meta_blocks(struct super_block *s)
{
- int i;
ll_rw_block(READ, 1, &(SB_BUFFER_WITH_SB(s)));
wait_on_buffer(SB_BUFFER_WITH_SB(s));
if (!buffer_uptodate(SB_BUFFER_WITH_SB(s))) {
@@ -1459,20 +1348,7 @@ static int reread_meta_blocks(struct super_block *s)
return 1;
}
- for (i = 0; i < SB_BMAP_NR(s); i++) {
- ll_rw_block(READ, 1, &(SB_AP_BITMAP(s)[i].bh));
- wait_on_buffer(SB_AP_BITMAP(s)[i].bh);
- if (!buffer_uptodate(SB_AP_BITMAP(s)[i].bh)) {
- reiserfs_warning(s,
- "reread_meta_blocks, error reading bitmap block number %d at %llu",
- i,
- (unsigned long long)SB_AP_BITMAP(s)[i].
- bh->b_blocknr);
- return 1;
- }
- }
return 0;
-
}
/////////////////////////////////////////////////////
@@ -1653,7 +1529,6 @@ static int function2code(hashf_t func)
static int reiserfs_fill_super(struct super_block *s, void *data, int silent)
{
struct inode *root_inode;
- int j;
struct reiserfs_transaction_handle th;
int old_format = 0;
unsigned long blocks;
@@ -1730,7 +1605,7 @@ static int reiserfs_fill_super(struct super_block *s, void *data, int silent)
sbi->s_mount_state = SB_REISERFS_STATE(s);
sbi->s_mount_state = REISERFS_VALID_FS;
- if (old_format ? read_old_bitmaps(s) : read_bitmaps(s)) {
+ if ((errval = reiserfs_init_bitmap_cache(s))) {
SWARN(silent, s,
"jmacd-8: reiserfs_fill_super: unable to read bitmap");
goto error;
@@ -1812,6 +1687,8 @@ static int reiserfs_fill_super(struct super_block *s, void *data, int silent)
if (is_reiserfs_3_5(rs)
|| (is_reiserfs_jr(rs) && SB_VERSION(s) == REISERFS_VERSION_1))
set_bit(REISERFS_3_5, &(sbi->s_properties));
+ else if (old_format)
+ set_bit(REISERFS_OLD_FORMAT, &(sbi->s_properties));
else
set_bit(REISERFS_3_6, &(sbi->s_properties));
@@ -1897,19 +1774,17 @@ static int reiserfs_fill_super(struct super_block *s, void *data, int silent)
if (jinit_done) { /* kill the commit thread, free journal ram */
journal_release_error(NULL, s);
}
- if (SB_DISK_SUPER_BLOCK(s)) {
- for (j = 0; j < SB_BMAP_NR(s); j++) {
- if (SB_AP_BITMAP(s))
- brelse(SB_AP_BITMAP(s)[j].bh);
- }
- vfree(SB_AP_BITMAP(s));
- }
+
+ reiserfs_free_bitmap_cache(s);
if (SB_BUFFER_WITH_SB(s))
brelse(SB_BUFFER_WITH_SB(s));
#ifdef CONFIG_QUOTA
- for (j = 0; j < MAXQUOTAS; j++) {
- kfree(sbi->s_qf_names[j]);
- sbi->s_qf_names[j] = NULL;
+ {
+ int j;
+ for (j = 0; j < MAXQUOTAS; j++) {
+ kfree(sbi->s_qf_names[j]);
+ sbi->s_qf_names[j] = NULL;
+ }
}
#endif
kfree(sbi);
diff --git a/fs/reiserfs/xattr.c b/fs/reiserfs/xattr.c
index d935fb9394e3..7bdb0ed443e1 100644
--- a/fs/reiserfs/xattr.c
+++ b/fs/reiserfs/xattr.c
@@ -773,7 +773,7 @@ int reiserfs_xattr_del(struct inode *inode, const char *name)
static int
reiserfs_delete_xattrs_filler(void *buf, const char *name, int namelen,
- loff_t offset, ino_t ino, unsigned int d_type)
+ loff_t offset, u64 ino, unsigned int d_type)
{
struct dentry *xadir = (struct dentry *)buf;
@@ -851,7 +851,7 @@ struct reiserfs_chown_buf {
/* XXX: If there is a better way to do this, I'd love to hear about it */
static int
reiserfs_chown_xattrs_filler(void *buf, const char *name, int namelen,
- loff_t offset, ino_t ino, unsigned int d_type)
+ loff_t offset, u64 ino, unsigned int d_type)
{
struct reiserfs_chown_buf *chown_buf = (struct reiserfs_chown_buf *)buf;
struct dentry *xafile, *xadir = chown_buf->xadir;
@@ -1036,7 +1036,7 @@ struct reiserfs_listxattr_buf {
static int
reiserfs_listxattr_filler(void *buf, const char *name, int namelen,
- loff_t offset, ino_t ino, unsigned int d_type)
+ loff_t offset, u64 ino, unsigned int d_type)
{
struct reiserfs_listxattr_buf *b = (struct reiserfs_listxattr_buf *)buf;
int len = 0;
diff --git a/fs/select.c b/fs/select.c
index 33b72ba0f86f..dcbc1112b7ec 100644
--- a/fs/select.c
+++ b/fs/select.c
@@ -658,8 +658,6 @@ int do_sys_poll(struct pollfd __user *ufds, unsigned int nfds, s64 *timeout)
unsigned int i;
struct poll_list *head;
struct poll_list *walk;
- struct fdtable *fdt;
- int max_fdset;
/* Allocate small arguments on the stack to save memory and be
faster - use long to make sure the buffer is aligned properly
on 64 bit archs to avoid unaligned access */
@@ -667,11 +665,7 @@ int do_sys_poll(struct pollfd __user *ufds, unsigned int nfds, s64 *timeout)
struct poll_list *stack_pp = NULL;
/* Do a sanity check on nfds ... */
- rcu_read_lock();
- fdt = files_fdtable(current->files);
- max_fdset = fdt->max_fdset;
- rcu_read_unlock();
- if (nfds > max_fdset && nfds > OPEN_MAX)
+ if (nfds > current->signal->rlim[RLIMIT_NOFILE].rlim_cur)
return -EINVAL;
poll_initwait(&table);
diff --git a/fs/smbfs/file.c b/fs/smbfs/file.c
index dae67048baba..50784d13c87b 100644
--- a/fs/smbfs/file.c
+++ b/fs/smbfs/file.c
@@ -214,13 +214,15 @@ smb_updatepage(struct file *file, struct page *page, unsigned long offset,
}
static ssize_t
-smb_file_read(struct file * file, char __user * buf, size_t count, loff_t *ppos)
+smb_file_aio_read(struct kiocb *iocb, const struct iovec *iov,
+ unsigned long nr_segs, loff_t pos)
{
+ struct file * file = iocb->ki_filp;
struct dentry * dentry = file->f_dentry;
ssize_t status;
VERBOSE("file %s/%s, count=%lu@%lu\n", DENTRY_PATH(dentry),
- (unsigned long) count, (unsigned long) *ppos);
+ (unsigned long) iocb->ki_left, (unsigned long) pos);
status = smb_revalidate_inode(dentry);
if (status) {
@@ -233,7 +235,7 @@ smb_file_read(struct file * file, char __user * buf, size_t count, loff_t *ppos)
(long)dentry->d_inode->i_size,
dentry->d_inode->i_flags, dentry->d_inode->i_atime);
- status = generic_file_read(file, buf, count, ppos);
+ status = generic_file_aio_read(iocb, iov, nr_segs, pos);
out:
return status;
}
@@ -317,14 +319,16 @@ const struct address_space_operations smb_file_aops = {
* Write to a file (through the page cache).
*/
static ssize_t
-smb_file_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos)
+smb_file_aio_write(struct kiocb *iocb, const struct iovec *iov,
+ unsigned long nr_segs, loff_t pos)
{
+ struct file * file = iocb->ki_filp;
struct dentry * dentry = file->f_dentry;
ssize_t result;
VERBOSE("file %s/%s, count=%lu@%lu\n",
DENTRY_PATH(dentry),
- (unsigned long) count, (unsigned long) *ppos);
+ (unsigned long) iocb->ki_left, (unsigned long) pos);
result = smb_revalidate_inode(dentry);
if (result) {
@@ -337,8 +341,8 @@ smb_file_write(struct file *file, const char __user *buf, size_t count, loff_t *
if (result)
goto out;
- if (count > 0) {
- result = generic_file_write(file, buf, count, ppos);
+ if (iocb->ki_left > 0) {
+ result = generic_file_aio_write(iocb, iov, nr_segs, pos);
VERBOSE("pos=%ld, size=%ld, mtime=%ld, atime=%ld\n",
(long) file->f_pos, (long) dentry->d_inode->i_size,
dentry->d_inode->i_mtime, dentry->d_inode->i_atime);
@@ -402,8 +406,10 @@ smb_file_permission(struct inode *inode, int mask, struct nameidata *nd)
const struct file_operations smb_file_operations =
{
.llseek = remote_llseek,
- .read = smb_file_read,
- .write = smb_file_write,
+ .read = do_sync_read,
+ .aio_read = smb_file_aio_read,
+ .write = do_sync_write,
+ .aio_write = smb_file_aio_write,
.ioctl = smb_ioctl,
.mmap = smb_file_mmap,
.open = smb_file_open,
diff --git a/fs/splice.c b/fs/splice.c
index 684bca3d3a10..13e92dd19fbb 100644
--- a/fs/splice.c
+++ b/fs/splice.c
@@ -12,7 +12,7 @@
* Jens to support splicing to files, network, direct splicing, etc and
* fixing lots of bugs.
*
- * Copyright (C) 2005-2006 Jens Axboe <axboe@suse.de>
+ * Copyright (C) 2005-2006 Jens Axboe <axboe@kernel.dk>
* Copyright (C) 2005-2006 Linus Torvalds <torvalds@osdl.org>
* Copyright (C) 2006 Ingo Molnar <mingo@elte.hu>
*
diff --git a/fs/stat.c b/fs/stat.c
index 60a31d5e5966..bca07eb2003c 100644
--- a/fs/stat.c
+++ b/fs/stat.c
@@ -140,6 +140,8 @@ static int cp_old_stat(struct kstat *stat, struct __old_kernel_stat __user * sta
memset(&tmp, 0, sizeof(struct __old_kernel_stat));
tmp.st_dev = old_encode_dev(stat->dev);
tmp.st_ino = stat->ino;
+ if (sizeof(tmp.st_ino) < sizeof(stat->ino) && tmp.st_ino != stat->ino)
+ return -EOVERFLOW;
tmp.st_mode = stat->mode;
tmp.st_nlink = stat->nlink;
if (tmp.st_nlink != stat->nlink)
@@ -210,6 +212,8 @@ static int cp_new_stat(struct kstat *stat, struct stat __user *statbuf)
tmp.st_dev = new_encode_dev(stat->dev);
#endif
tmp.st_ino = stat->ino;
+ if (sizeof(tmp.st_ino) < sizeof(stat->ino) && tmp.st_ino != stat->ino)
+ return -EOVERFLOW;
tmp.st_mode = stat->mode;
tmp.st_nlink = stat->nlink;
if (tmp.st_nlink != stat->nlink)
@@ -347,6 +351,8 @@ static long cp_new_stat64(struct kstat *stat, struct stat64 __user *statbuf)
tmp.st_rdev = huge_encode_dev(stat->rdev);
#endif
tmp.st_ino = stat->ino;
+ if (sizeof(tmp.st_ino) < sizeof(stat->ino) && tmp.st_ino != stat->ino)
+ return -EOVERFLOW;
#ifdef STAT64_HAS_BROKEN_ST_INO
tmp.__st_ino = stat->ino;
#endif
diff --git a/fs/super.c b/fs/super.c
index 5c4c94d5495e..aec99ddbe53f 100644
--- a/fs/super.c
+++ b/fs/super.c
@@ -199,7 +199,7 @@ EXPORT_SYMBOL(deactivate_super);
* success, 0 if we had failed (superblock contents was already dead or
* dying when grab_super() had been called).
*/
-static int grab_super(struct super_block *s)
+static int grab_super(struct super_block *s) __releases(sb_lock)
{
s->s_count++;
spin_unlock(&sb_lock);
@@ -220,6 +220,37 @@ static int grab_super(struct super_block *s)
return 0;
}
+/*
+ * Write out and wait upon all dirty data associated with this
+ * superblock. Filesystem data as well as the underlying block
+ * device. Takes the superblock lock. Requires a second blkdev
+ * flush by the caller to complete the operation.
+ */
+void __fsync_super(struct super_block *sb)
+{
+ sync_inodes_sb(sb, 0);
+ DQUOT_SYNC(sb);
+ lock_super(sb);
+ if (sb->s_dirt && sb->s_op->write_super)
+ sb->s_op->write_super(sb);
+ unlock_super(sb);
+ if (sb->s_op->sync_fs)
+ sb->s_op->sync_fs(sb, 1);
+ sync_blockdev(sb->s_bdev);
+ sync_inodes_sb(sb, 1);
+}
+
+/*
+ * Write out and wait upon all dirty data associated with this
+ * superblock. Filesystem data as well as the underlying block
+ * device. Takes the superblock lock.
+ */
+int fsync_super(struct super_block *sb)
+{
+ __fsync_super(sb);
+ return sync_blockdev(sb->s_bdev);
+}
+
/**
* generic_shutdown_super - common helper for ->kill_sb()
* @sb: superblock to kill
@@ -540,8 +571,10 @@ int do_remount_sb(struct super_block *sb, int flags, void *data, int force)
{
int retval;
+#ifdef CONFIG_BLOCK
if (!(flags & MS_RDONLY) && bdev_read_only(sb->s_bdev))
return -EACCES;
+#endif
if (flags & MS_RDONLY)
acct_auto_close(sb);
shrink_dcache_sb(sb);
@@ -661,6 +694,7 @@ void kill_litter_super(struct super_block *sb)
EXPORT_SYMBOL(kill_litter_super);
+#ifdef CONFIG_BLOCK
static int set_bdev_super(struct super_block *s, void *data)
{
s->s_bdev = data;
@@ -756,6 +790,7 @@ void kill_block_super(struct super_block *sb)
}
EXPORT_SYMBOL(kill_block_super);
+#endif
int get_sb_nodev(struct file_system_type *fs_type,
int flags, void *data,
diff --git a/fs/sync.c b/fs/sync.c
index 955aef04da28..1de747b5ddb9 100644
--- a/fs/sync.c
+++ b/fs/sync.c
@@ -10,11 +10,124 @@
#include <linux/syscalls.h>
#include <linux/linkage.h>
#include <linux/pagemap.h>
+#include <linux/quotaops.h>
+#include <linux/buffer_head.h>
#define VALID_FLAGS (SYNC_FILE_RANGE_WAIT_BEFORE|SYNC_FILE_RANGE_WRITE| \
SYNC_FILE_RANGE_WAIT_AFTER)
/*
+ * sync everything. Start out by waking pdflush, because that writes back
+ * all queues in parallel.
+ */
+static void do_sync(unsigned long wait)
+{
+ wakeup_pdflush(0);
+ sync_inodes(0); /* All mappings, inodes and their blockdevs */
+ DQUOT_SYNC(NULL);
+ sync_supers(); /* Write the superblocks */
+ sync_filesystems(0); /* Start syncing the filesystems */
+ sync_filesystems(wait); /* Waitingly sync the filesystems */
+ sync_inodes(wait); /* Mappings, inodes and blockdevs, again. */
+ if (!wait)
+ printk("Emergency Sync complete\n");
+ if (unlikely(laptop_mode))
+ laptop_sync_completion();
+}
+
+asmlinkage long sys_sync(void)
+{
+ do_sync(1);
+ return 0;
+}
+
+void emergency_sync(void)
+{
+ pdflush_operation(do_sync, 0);
+}
+
+/*
+ * Generic function to fsync a file.
+ *
+ * filp may be NULL if called via the msync of a vma.
+ */
+int file_fsync(struct file *filp, struct dentry *dentry, int datasync)
+{
+ struct inode * inode = dentry->d_inode;
+ struct super_block * sb;
+ int ret, err;
+
+ /* sync the inode to buffers */
+ ret = write_inode_now(inode, 0);
+
+ /* sync the superblock to buffers */
+ sb = inode->i_sb;
+ lock_super(sb);
+ if (sb->s_op->write_super)
+ sb->s_op->write_super(sb);
+ unlock_super(sb);
+
+ /* .. finally sync the buffers to disk */
+ err = sync_blockdev(sb->s_bdev);
+ if (!ret)
+ ret = err;
+ return ret;
+}
+
+long do_fsync(struct file *file, int datasync)
+{
+ int ret;
+ int err;
+ struct address_space *mapping = file->f_mapping;
+
+ if (!file->f_op || !file->f_op->fsync) {
+ /* Why? We can still call filemap_fdatawrite */
+ ret = -EINVAL;
+ goto out;
+ }
+
+ ret = filemap_fdatawrite(mapping);
+
+ /*
+ * We need to protect against concurrent writers, which could cause
+ * livelocks in fsync_buffers_list().
+ */
+ mutex_lock(&mapping->host->i_mutex);
+ err = file->f_op->fsync(file, file->f_dentry, datasync);
+ if (!ret)
+ ret = err;
+ mutex_unlock(&mapping->host->i_mutex);
+ err = filemap_fdatawait(mapping);
+ if (!ret)
+ ret = err;
+out:
+ return ret;
+}
+
+static long __do_fsync(unsigned int fd, int datasync)
+{
+ struct file *file;
+ int ret = -EBADF;
+
+ file = fget(fd);
+ if (file) {
+ ret = do_fsync(file, datasync);
+ fput(file);
+ }
+ return ret;
+}
+
+asmlinkage long sys_fsync(unsigned int fd)
+{
+ return __do_fsync(fd, 0);
+}
+
+asmlinkage long sys_fdatasync(unsigned int fd)
+{
+ return __do_fsync(fd, 1);
+}
+
+/*
* sys_sync_file_range() permits finely controlled syncing over a segment of
* a file in the range offset .. (offset+nbytes-1) inclusive. If nbytes is
* zero then sys_sync_file_range() will operate from offset out to EOF.
diff --git a/fs/sysfs/dir.c b/fs/sysfs/dir.c
index 5f3d725d1125..3aa3434621ca 100644
--- a/fs/sysfs/dir.c
+++ b/fs/sysfs/dir.c
@@ -103,7 +103,7 @@ static int init_dir(struct inode * inode)
inode->i_fop = &sysfs_dir_operations;
/* directory inodes start off with i_nlink == 2 (for "." entry) */
- inode->i_nlink++;
+ inc_nlink(inode);
return 0;
}
@@ -137,7 +137,7 @@ static int create_dir(struct kobject * k, struct dentry * p,
if (!error) {
error = sysfs_create(*d, mode, init_dir);
if (!error) {
- p->d_inode->i_nlink++;
+ inc_nlink(p->d_inode);
(*d)->d_op = &sysfs_dentry_ops;
d_rehash(*d);
}
diff --git a/fs/sysfs/file.c b/fs/sysfs/file.c
index cf3786625bfa..146f1dedec84 100644
--- a/fs/sysfs/file.c
+++ b/fs/sysfs/file.c
@@ -157,8 +157,8 @@ sysfs_read_file(struct file *file, char __user *buf, size_t count, loff_t *ppos)
if ((retval = fill_read_buffer(file->f_dentry,buffer)))
goto out;
}
- pr_debug("%s: count = %d, ppos = %lld, buf = %s\n",
- __FUNCTION__,count,*ppos,buffer->page);
+ pr_debug("%s: count = %zd, ppos = %lld, buf = %s\n",
+ __FUNCTION__, count, *ppos, buffer->page);
retval = flush_read_buffer(buffer,buf,count,ppos);
out:
up(&buffer->sem);
diff --git a/fs/sysfs/mount.c b/fs/sysfs/mount.c
index 40190c489271..20551a1b8a56 100644
--- a/fs/sysfs/mount.c
+++ b/fs/sysfs/mount.c
@@ -49,7 +49,7 @@ static int sysfs_fill_super(struct super_block *sb, void *data, int silent)
inode->i_op = &sysfs_dir_inode_operations;
inode->i_fop = &sysfs_dir_operations;
/* directory inodes start off with i_nlink == 2 (for "." entry) */
- inode->i_nlink++;
+ inc_nlink(inode);
} else {
pr_debug("sysfs: could not get root inode\n");
return -ENOMEM;
diff --git a/fs/sysv/file.c b/fs/sysv/file.c
index a59e303135fa..47a4b728f15b 100644
--- a/fs/sysv/file.c
+++ b/fs/sysv/file.c
@@ -21,8 +21,10 @@
*/
const struct file_operations sysv_file_operations = {
.llseek = generic_file_llseek,
- .read = generic_file_read,
- .write = generic_file_write,
+ .read = do_sync_read,
+ .aio_read = generic_file_aio_read,
+ .write = do_sync_write,
+ .aio_write = generic_file_aio_write,
.mmap = generic_file_mmap,
.fsync = sysv_sync_file,
.sendfile = generic_file_sendfile,
diff --git a/fs/sysv/namei.c b/fs/sysv/namei.c
index b8a73f716fbe..f7c08db8e34c 100644
--- a/fs/sysv/namei.c
+++ b/fs/sysv/namei.c
@@ -250,7 +250,7 @@ static int sysv_rename(struct inode * old_dir, struct dentry * old_dentry,
sysv_set_link(new_de, new_page, old_inode);
new_inode->i_ctime = CURRENT_TIME_SEC;
if (dir_de)
- new_inode->i_nlink--;
+ drop_nlink(new_inode);
inode_dec_link_count(new_inode);
} else {
if (dir_de) {
diff --git a/fs/udf/file.c b/fs/udf/file.c
index a59e5f33daf6..7aedd552cba1 100644
--- a/fs/udf/file.c
+++ b/fs/udf/file.c
@@ -103,19 +103,21 @@ const struct address_space_operations udf_adinicb_aops = {
.commit_write = udf_adinicb_commit_write,
};
-static ssize_t udf_file_write(struct file * file, const char __user * buf,
- size_t count, loff_t *ppos)
+static ssize_t udf_file_aio_write(struct kiocb *iocb, const struct iovec *iov,
+ unsigned long nr_segs, loff_t ppos)
{
ssize_t retval;
+ struct file *file = iocb->ki_filp;
struct inode *inode = file->f_dentry->d_inode;
int err, pos;
+ size_t count = iocb->ki_left;
if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_IN_ICB)
{
if (file->f_flags & O_APPEND)
pos = inode->i_size;
else
- pos = *ppos;
+ pos = ppos;
if (inode->i_sb->s_blocksize < (udf_file_entry_alloc_offset(inode) +
pos + count))
@@ -136,7 +138,7 @@ static ssize_t udf_file_write(struct file * file, const char __user * buf,
}
}
- retval = generic_file_write(file, buf, count, ppos);
+ retval = generic_file_aio_write(iocb, iov, nr_segs, ppos);
if (retval > 0)
mark_inode_dirty(inode);
@@ -249,11 +251,13 @@ static int udf_release_file(struct inode * inode, struct file * filp)
}
const struct file_operations udf_file_operations = {
- .read = generic_file_read,
+ .read = do_sync_read,
+ .aio_read = generic_file_aio_read,
.ioctl = udf_ioctl,
.open = generic_file_open,
.mmap = generic_file_mmap,
- .write = udf_file_write,
+ .write = do_sync_write,
+ .aio_write = udf_file_aio_write,
.release = udf_release_file,
.fsync = udf_fsync_file,
.sendfile = generic_file_sendfile,
diff --git a/fs/udf/inode.c b/fs/udf/inode.c
index b223b32db991..ae21a0e59e95 100644
--- a/fs/udf/inode.c
+++ b/fs/udf/inode.c
@@ -1165,7 +1165,7 @@ static void udf_fill_inode(struct inode *inode, struct buffer_head *bh)
inode->i_op = &udf_dir_inode_operations;
inode->i_fop = &udf_dir_operations;
inode->i_mode |= S_IFDIR;
- inode->i_nlink ++;
+ inc_nlink(inode);
break;
}
case ICBTAG_FILE_TYPE_REALTIME:
diff --git a/fs/udf/namei.c b/fs/udf/namei.c
index ab9a7629d23e..73163325e5ec 100644
--- a/fs/udf/namei.c
+++ b/fs/udf/namei.c
@@ -762,7 +762,7 @@ static int udf_mkdir(struct inode * dir, struct dentry * dentry, int mode)
cpu_to_le32(UDF_I_UNIQUE(inode) & 0x00000000FFFFFFFFUL);
cfi.fileCharacteristics |= FID_FILE_CHAR_DIRECTORY;
udf_write_fi(dir, &cfi, fi, &fibh, NULL, NULL);
- dir->i_nlink++;
+ inc_nlink(dir);
mark_inode_dirty(dir);
d_instantiate(dentry, inode);
if (fibh.sbh != fibh.ebh)
@@ -876,10 +876,9 @@ static int udf_rmdir(struct inode * dir, struct dentry * dentry)
udf_warning(inode->i_sb, "udf_rmdir",
"empty directory has nlink != 2 (%d)",
inode->i_nlink);
- inode->i_nlink = 0;
+ clear_nlink(inode);
inode->i_size = 0;
- mark_inode_dirty(inode);
- dir->i_nlink --;
+ inode_dec_link_count(inode);
inode->i_ctime = dir->i_ctime = dir->i_mtime = current_fs_time(dir->i_sb);
mark_inode_dirty(dir);
@@ -923,8 +922,7 @@ static int udf_unlink(struct inode * dir, struct dentry * dentry)
goto end_unlink;
dir->i_ctime = dir->i_mtime = current_fs_time(dir->i_sb);
mark_inode_dirty(dir);
- inode->i_nlink--;
- mark_inode_dirty(inode);
+ inode_dec_link_count(inode);
inode->i_ctime = dir->i_ctime;
retval = 0;
@@ -1101,8 +1099,7 @@ out:
return err;
out_no_entry:
- inode->i_nlink--;
- mark_inode_dirty(inode);
+ inode_dec_link_count(inode);
iput(inode);
goto out;
}
@@ -1150,7 +1147,7 @@ static int udf_link(struct dentry * old_dentry, struct inode * dir,
if (fibh.sbh != fibh.ebh)
udf_release_data(fibh.ebh);
udf_release_data(fibh.sbh);
- inode->i_nlink ++;
+ inc_nlink(inode);
inode->i_ctime = current_fs_time(inode->i_sb);
mark_inode_dirty(inode);
atomic_inc(&inode->i_count);
@@ -1261,9 +1258,8 @@ static int udf_rename (struct inode * old_dir, struct dentry * old_dentry,
if (new_inode)
{
- new_inode->i_nlink--;
new_inode->i_ctime = current_fs_time(new_inode->i_sb);
- mark_inode_dirty(new_inode);
+ inode_dec_link_count(new_inode);
}
old_dir->i_ctime = old_dir->i_mtime = current_fs_time(old_dir->i_sb);
mark_inode_dirty(old_dir);
@@ -1279,16 +1275,14 @@ static int udf_rename (struct inode * old_dir, struct dentry * old_dentry,
}
else
mark_buffer_dirty_inode(dir_bh, old_inode);
- old_dir->i_nlink --;
- mark_inode_dirty(old_dir);
+ inode_dec_link_count(old_dir);
if (new_inode)
{
- new_inode->i_nlink --;
- mark_inode_dirty(new_inode);
+ inode_dec_link_count(new_inode);
}
else
{
- new_dir->i_nlink ++;
+ inc_nlink(new_dir);
mark_inode_dirty(new_dir);
}
}
diff --git a/fs/udf/super.c b/fs/udf/super.c
index 5dd356cbbda6..1d3b5d2070e5 100644
--- a/fs/udf/super.c
+++ b/fs/udf/super.c
@@ -1621,6 +1621,10 @@ static int udf_fill_super(struct super_block *sb, void *options, int silent)
goto error_out;
}
+ if (UDF_SB_PARTFLAGS(sb, UDF_SB_PARTITION(sb)) & UDF_PART_FLAG_READ_ONLY)
+ printk("UDF-fs: Partition marked readonly; forcing readonly mount\n");
+ sb->s_flags |= MS_RDONLY;
+
if ( udf_find_fileset(sb, &fileset, &rootdir) )
{
printk("UDF-fs: No fileset found\n");
diff --git a/fs/ufs/file.c b/fs/ufs/file.c
index a9c6e5f04fae..1e096323bad4 100644
--- a/fs/ufs/file.c
+++ b/fs/ufs/file.c
@@ -53,8 +53,10 @@ static int ufs_sync_file(struct file *file, struct dentry *dentry, int datasync)
const struct file_operations ufs_file_operations = {
.llseek = generic_file_llseek,
- .read = generic_file_read,
- .write = generic_file_write,
+ .read = do_sync_read,
+ .aio_read = generic_file_aio_read,
+ .write = do_sync_write,
+ .aio_write = generic_file_aio_write,
.mmap = generic_file_mmap,
.open = generic_file_open,
.fsync = ufs_sync_file,
diff --git a/fs/ufs/namei.c b/fs/ufs/namei.c
index d344b411e261..e84c0ecf0730 100644
--- a/fs/ufs/namei.c
+++ b/fs/ufs/namei.c
@@ -308,7 +308,7 @@ static int ufs_rename(struct inode *old_dir, struct dentry *old_dentry,
ufs_set_link(new_dir, new_de, new_page, old_inode);
new_inode->i_ctime = CURRENT_TIME_SEC;
if (dir_de)
- new_inode->i_nlink--;
+ drop_nlink(new_inode);
inode_dec_link_count(new_inode);
} else {
if (dir_de) {
diff --git a/fs/utimes.c b/fs/utimes.c
new file mode 100644
index 000000000000..1bcd852fc4a9
--- /dev/null
+++ b/fs/utimes.c
@@ -0,0 +1,137 @@
+#include <linux/compiler.h>
+#include <linux/fs.h>
+#include <linux/linkage.h>
+#include <linux/namei.h>
+#include <linux/utime.h>
+#include <asm/uaccess.h>
+#include <asm/unistd.h>
+
+#ifdef __ARCH_WANT_SYS_UTIME
+
+/*
+ * sys_utime() can be implemented in user-level using sys_utimes().
+ * Is this for backwards compatibility? If so, why not move it
+ * into the appropriate arch directory (for those architectures that
+ * need it).
+ */
+
+/* If times==NULL, set access and modification to current time,
+ * must be owner or have write permission.
+ * Else, update from *times, must be owner or super user.
+ */
+asmlinkage long sys_utime(char __user * filename, struct utimbuf __user * times)
+{
+ int error;
+ struct nameidata nd;
+ struct inode * inode;
+ struct iattr newattrs;
+
+ error = user_path_walk(filename, &nd);
+ if (error)
+ goto out;
+ inode = nd.dentry->d_inode;
+
+ error = -EROFS;
+ if (IS_RDONLY(inode))
+ goto dput_and_out;
+
+ /* Don't worry, the checks are done in inode_change_ok() */
+ newattrs.ia_valid = ATTR_CTIME | ATTR_MTIME | ATTR_ATIME;
+ if (times) {
+ error = -EPERM;
+ if (IS_APPEND(inode) || IS_IMMUTABLE(inode))
+ goto dput_and_out;
+
+ error = get_user(newattrs.ia_atime.tv_sec, &times->actime);
+ newattrs.ia_atime.tv_nsec = 0;
+ if (!error)
+ error = get_user(newattrs.ia_mtime.tv_sec, &times->modtime);
+ newattrs.ia_mtime.tv_nsec = 0;
+ if (error)
+ goto dput_and_out;
+
+ newattrs.ia_valid |= ATTR_ATIME_SET | ATTR_MTIME_SET;
+ } else {
+ error = -EACCES;
+ if (IS_IMMUTABLE(inode))
+ goto dput_and_out;
+
+ if (current->fsuid != inode->i_uid &&
+ (error = vfs_permission(&nd, MAY_WRITE)) != 0)
+ goto dput_and_out;
+ }
+ mutex_lock(&inode->i_mutex);
+ error = notify_change(nd.dentry, &newattrs);
+ mutex_unlock(&inode->i_mutex);
+dput_and_out:
+ path_release(&nd);
+out:
+ return error;
+}
+
+#endif
+
+/* If times==NULL, set access and modification to current time,
+ * must be owner or have write permission.
+ * Else, update from *times, must be owner or super user.
+ */
+long do_utimes(int dfd, char __user *filename, struct timeval *times)
+{
+ int error;
+ struct nameidata nd;
+ struct inode * inode;
+ struct iattr newattrs;
+
+ error = __user_walk_fd(dfd, filename, LOOKUP_FOLLOW, &nd);
+
+ if (error)
+ goto out;
+ inode = nd.dentry->d_inode;
+
+ error = -EROFS;
+ if (IS_RDONLY(inode))
+ goto dput_and_out;
+
+ /* Don't worry, the checks are done in inode_change_ok() */
+ newattrs.ia_valid = ATTR_CTIME | ATTR_MTIME | ATTR_ATIME;
+ if (times) {
+ error = -EPERM;
+ if (IS_APPEND(inode) || IS_IMMUTABLE(inode))
+ goto dput_and_out;
+
+ newattrs.ia_atime.tv_sec = times[0].tv_sec;
+ newattrs.ia_atime.tv_nsec = times[0].tv_usec * 1000;
+ newattrs.ia_mtime.tv_sec = times[1].tv_sec;
+ newattrs.ia_mtime.tv_nsec = times[1].tv_usec * 1000;
+ newattrs.ia_valid |= ATTR_ATIME_SET | ATTR_MTIME_SET;
+ } else {
+ error = -EACCES;
+ if (IS_IMMUTABLE(inode))
+ goto dput_and_out;
+
+ if (current->fsuid != inode->i_uid &&
+ (error = vfs_permission(&nd, MAY_WRITE)) != 0)
+ goto dput_and_out;
+ }
+ mutex_lock(&inode->i_mutex);
+ error = notify_change(nd.dentry, &newattrs);
+ mutex_unlock(&inode->i_mutex);
+dput_and_out:
+ path_release(&nd);
+out:
+ return error;
+}
+
+asmlinkage long sys_futimesat(int dfd, char __user *filename, struct timeval __user *utimes)
+{
+ struct timeval times[2];
+
+ if (utimes && copy_from_user(&times, utimes, sizeof(times)))
+ return -EFAULT;
+ return do_utimes(dfd, filename, utimes ? times : NULL);
+}
+
+asmlinkage long sys_utimes(char __user *filename, struct timeval __user *utimes)
+{
+ return sys_futimesat(AT_FDCWD, filename, utimes);
+}
diff --git a/fs/vfat/namei.c b/fs/vfat/namei.c
index 9a8f48bae956..edb711ff7b05 100644
--- a/fs/vfat/namei.c
+++ b/fs/vfat/namei.c
@@ -782,9 +782,9 @@ static int vfat_rmdir(struct inode *dir, struct dentry *dentry)
err = fat_remove_entries(dir, &sinfo); /* and releases bh */
if (err)
goto out;
- dir->i_nlink--;
+ drop_nlink(dir);
- inode->i_nlink = 0;
+ clear_nlink(inode);
inode->i_mtime = inode->i_atime = CURRENT_TIME_SEC;
fat_detach(inode);
out:
@@ -808,7 +808,7 @@ static int vfat_unlink(struct inode *dir, struct dentry *dentry)
err = fat_remove_entries(dir, &sinfo); /* and releases bh */
if (err)
goto out;
- inode->i_nlink = 0;
+ clear_nlink(inode);
inode->i_mtime = inode->i_atime = CURRENT_TIME_SEC;
fat_detach(inode);
out:
@@ -837,7 +837,7 @@ static int vfat_mkdir(struct inode *dir, struct dentry *dentry, int mode)
if (err)
goto out_free;
dir->i_version++;
- dir->i_nlink++;
+ inc_nlink(dir);
inode = fat_build_inode(sb, sinfo.de, sinfo.i_pos);
brelse(sinfo.bh);
@@ -930,9 +930,9 @@ static int vfat_rename(struct inode *old_dir, struct dentry *old_dentry,
if (err)
goto error_dotdot;
}
- old_dir->i_nlink--;
+ drop_nlink(old_dir);
if (!new_inode)
- new_dir->i_nlink++;
+ inc_nlink(new_dir);
}
err = fat_remove_entries(old_dir, &old_sinfo); /* and releases bh */
@@ -947,10 +947,9 @@ static int vfat_rename(struct inode *old_dir, struct dentry *old_dentry,
mark_inode_dirty(old_dir);
if (new_inode) {
+ drop_nlink(new_inode);
if (is_dir)
- new_inode->i_nlink -= 2;
- else
- new_inode->i_nlink--;
+ drop_nlink(new_inode);
new_inode->i_ctime = ts;
}
out:
diff --git a/fs/xfs/Kconfig b/fs/xfs/Kconfig
index 26b364c9d62c..35115bca036e 100644
--- a/fs/xfs/Kconfig
+++ b/fs/xfs/Kconfig
@@ -1,5 +1,6 @@
config XFS_FS
tristate "XFS filesystem support"
+ depends on BLOCK
help
XFS is a high performance journaling filesystem which originated
on the SGI IRIX platform. It is completely multi-threaded, can
diff --git a/fs/xfs/Makefile-linux-2.6 b/fs/xfs/Makefile-linux-2.6
index 9e7f85986d0d..291948d5085a 100644
--- a/fs/xfs/Makefile-linux-2.6
+++ b/fs/xfs/Makefile-linux-2.6
@@ -30,7 +30,6 @@ ifeq ($(CONFIG_XFS_TRACE),y)
EXTRA_CFLAGS += -DXFS_BLI_TRACE
EXTRA_CFLAGS += -DXFS_BMAP_TRACE
EXTRA_CFLAGS += -DXFS_BMBT_TRACE
- EXTRA_CFLAGS += -DXFS_DIR_TRACE
EXTRA_CFLAGS += -DXFS_DIR2_TRACE
EXTRA_CFLAGS += -DXFS_DQUOT_TRACE
EXTRA_CFLAGS += -DXFS_ILOCK_TRACE
diff --git a/fs/xfs/linux-2.6/kmem.c b/fs/xfs/linux-2.6/kmem.c
index aba7fcf881a2..d59737589815 100644
--- a/fs/xfs/linux-2.6/kmem.c
+++ b/fs/xfs/linux-2.6/kmem.c
@@ -34,6 +34,14 @@ kmem_alloc(size_t size, unsigned int __nocast flags)
gfp_t lflags = kmem_flags_convert(flags);
void *ptr;
+#ifdef DEBUG
+ if (unlikely(!(flags & KM_LARGE) && (size > PAGE_SIZE))) {
+ printk(KERN_WARNING "Large %s attempt, size=%ld\n",
+ __FUNCTION__, (long)size);
+ dump_stack();
+ }
+#endif
+
do {
if (size < MAX_SLAB_SIZE || retries > MAX_VMALLOCS)
ptr = kmalloc(size, lflags);
@@ -60,6 +68,27 @@ kmem_zalloc(size_t size, unsigned int __nocast flags)
return ptr;
}
+void *
+kmem_zalloc_greedy(size_t *size, size_t minsize, size_t maxsize,
+ unsigned int __nocast flags)
+{
+ void *ptr;
+ size_t kmsize = maxsize;
+ unsigned int kmflags = (flags & ~KM_SLEEP) | KM_NOSLEEP;
+
+ while (!(ptr = kmem_zalloc(kmsize, kmflags))) {
+ if ((kmsize <= minsize) && (flags & KM_NOSLEEP))
+ break;
+ if ((kmsize >>= 1) <= minsize) {
+ kmsize = minsize;
+ kmflags = flags;
+ }
+ }
+ if (ptr)
+ *size = kmsize;
+ return ptr;
+}
+
void
kmem_free(void *ptr, size_t size)
{
diff --git a/fs/xfs/linux-2.6/kmem.h b/fs/xfs/linux-2.6/kmem.h
index 0e8293c5a32f..9ebabdf7829c 100644
--- a/fs/xfs/linux-2.6/kmem.h
+++ b/fs/xfs/linux-2.6/kmem.h
@@ -30,6 +30,7 @@
#define KM_NOSLEEP 0x0002u
#define KM_NOFS 0x0004u
#define KM_MAYFAIL 0x0008u
+#define KM_LARGE 0x0010u
/*
* We use a special process flag to avoid recursive callbacks into
@@ -41,7 +42,7 @@ kmem_flags_convert(unsigned int __nocast flags)
{
gfp_t lflags;
- BUG_ON(flags & ~(KM_SLEEP|KM_NOSLEEP|KM_NOFS|KM_MAYFAIL));
+ BUG_ON(flags & ~(KM_SLEEP|KM_NOSLEEP|KM_NOFS|KM_MAYFAIL|KM_LARGE));
if (flags & KM_NOSLEEP) {
lflags = GFP_ATOMIC | __GFP_NOWARN;
@@ -54,8 +55,9 @@ kmem_flags_convert(unsigned int __nocast flags)
}
extern void *kmem_alloc(size_t, unsigned int __nocast);
-extern void *kmem_realloc(void *, size_t, size_t, unsigned int __nocast);
extern void *kmem_zalloc(size_t, unsigned int __nocast);
+extern void *kmem_zalloc_greedy(size_t *, size_t, size_t, unsigned int __nocast);
+extern void *kmem_realloc(void *, size_t, size_t, unsigned int __nocast);
extern void kmem_free(void *, size_t);
/*
diff --git a/fs/xfs/linux-2.6/sema.h b/fs/xfs/linux-2.6/sema.h
index b25090094cca..2009e6d922ce 100644
--- a/fs/xfs/linux-2.6/sema.h
+++ b/fs/xfs/linux-2.6/sema.h
@@ -29,8 +29,6 @@
typedef struct semaphore sema_t;
-#define init_sema(sp, val, c, d) sema_init(sp, val)
-#define initsema(sp, val) sema_init(sp, val)
#define initnsema(sp, val, name) sema_init(sp, val)
#define psema(sp, b) down(sp)
#define vsema(sp) up(sp)
diff --git a/fs/xfs/linux-2.6/sv.h b/fs/xfs/linux-2.6/sv.h
index 9a8ad481b008..351a8f454bd1 100644
--- a/fs/xfs/linux-2.6/sv.h
+++ b/fs/xfs/linux-2.6/sv.h
@@ -53,8 +53,6 @@ static inline void _sv_wait(sv_t *sv, spinlock_t *lock, int state,
remove_wait_queue(&sv->waiters, &wait);
}
-#define init_sv(sv,type,name,flag) \
- init_waitqueue_head(&(sv)->waiters)
#define sv_init(sv,flag,name) \
init_waitqueue_head(&(sv)->waiters)
#define sv_destroy(sv) \
diff --git a/fs/xfs/linux-2.6/xfs_aops.c b/fs/xfs/linux-2.6/xfs_aops.c
index 34dcb43a7837..09360cf1e1f2 100644
--- a/fs/xfs/linux-2.6/xfs_aops.c
+++ b/fs/xfs/linux-2.6/xfs_aops.c
@@ -71,7 +71,7 @@ xfs_page_trace(
int tag,
struct inode *inode,
struct page *page,
- int mask)
+ unsigned long pgoff)
{
xfs_inode_t *ip;
bhv_vnode_t *vp = vn_from_inode(inode);
@@ -91,7 +91,7 @@ xfs_page_trace(
(void *)ip,
(void *)inode,
(void *)page,
- (void *)((unsigned long)mask),
+ (void *)pgoff,
(void *)((unsigned long)((ip->i_d.di_size >> 32) & 0xffffffff)),
(void *)((unsigned long)(ip->i_d.di_size & 0xffffffff)),
(void *)((unsigned long)((isize >> 32) & 0xffffffff)),
@@ -105,7 +105,7 @@ xfs_page_trace(
(void *)NULL);
}
#else
-#define xfs_page_trace(tag, inode, page, mask)
+#define xfs_page_trace(tag, inode, page, pgoff)
#endif
/*
@@ -1197,7 +1197,7 @@ xfs_vm_releasepage(
.nr_to_write = 1,
};
- xfs_page_trace(XFS_RELEASEPAGE_ENTER, inode, page, gfp_mask);
+ xfs_page_trace(XFS_RELEASEPAGE_ENTER, inode, page, 0);
if (!page_has_buffers(page))
return 0;
@@ -1356,7 +1356,6 @@ xfs_end_io_direct(
ioend->io_size = size;
xfs_finish_ioend(ioend);
} else {
- ASSERT(size >= 0);
xfs_destroy_ioend(ioend);
}
diff --git a/fs/xfs/linux-2.6/xfs_buf.c b/fs/xfs/linux-2.6/xfs_buf.c
index 2af528dcfb04..9bbadafdcb00 100644
--- a/fs/xfs/linux-2.6/xfs_buf.c
+++ b/fs/xfs/linux-2.6/xfs_buf.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000-2005 Silicon Graphics, Inc.
+ * Copyright (c) 2000-2006 Silicon Graphics, Inc.
* All Rights Reserved.
*
* This program is free software; you can redistribute it and/or
@@ -318,8 +318,12 @@ xfs_buf_free(
if ((bp->b_flags & XBF_MAPPED) && (bp->b_page_count > 1))
free_address(bp->b_addr - bp->b_offset);
- for (i = 0; i < bp->b_page_count; i++)
- page_cache_release(bp->b_pages[i]);
+ for (i = 0; i < bp->b_page_count; i++) {
+ struct page *page = bp->b_pages[i];
+
+ ASSERT(!PagePrivate(page));
+ page_cache_release(page);
+ }
_xfs_buf_free_pages(bp);
} else if (bp->b_flags & _XBF_KMEM_ALLOC) {
/*
@@ -400,6 +404,7 @@ _xfs_buf_lookup_pages(
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) {
@@ -768,7 +773,7 @@ xfs_buf_get_noaddr(
_xfs_buf_initialize(bp, target, 0, len, 0);
try_again:
- data = kmem_alloc(malloc_len, KM_SLEEP | KM_MAYFAIL);
+ data = kmem_alloc(malloc_len, KM_SLEEP | KM_MAYFAIL | KM_LARGE);
if (unlikely(data == NULL))
goto fail_free_buf;
@@ -1117,10 +1122,10 @@ xfs_buf_bio_end_io(
do {
struct page *page = bvec->bv_page;
+ ASSERT(!PagePrivate(page));
if (unlikely(bp->b_error)) {
if (bp->b_flags & XBF_READ)
ClearPageUptodate(page);
- SetPageError(page);
} else if (blocksize >= PAGE_CACHE_SIZE) {
SetPageUptodate(page);
} else if (!PagePrivate(page) &&
@@ -1156,16 +1161,16 @@ _xfs_buf_ioapply(
total_nr_pages = bp->b_page_count;
map_i = 0;
- if (bp->b_flags & _XBF_RUN_QUEUES) {
- bp->b_flags &= ~_XBF_RUN_QUEUES;
- rw = (bp->b_flags & XBF_READ) ? READ_SYNC : WRITE_SYNC;
- } else {
- rw = (bp->b_flags & XBF_READ) ? READ : WRITE;
- }
-
if (bp->b_flags & XBF_ORDERED) {
ASSERT(!(bp->b_flags & XBF_READ));
rw = WRITE_BARRIER;
+ } else if (bp->b_flags & _XBF_RUN_QUEUES) {
+ ASSERT(!(bp->b_flags & XBF_READ_AHEAD));
+ bp->b_flags &= ~_XBF_RUN_QUEUES;
+ rw = (bp->b_flags & XBF_WRITE) ? WRITE_SYNC : READ_SYNC;
+ } else {
+ rw = (bp->b_flags & XBF_WRITE) ? WRITE :
+ (bp->b_flags & XBF_READ_AHEAD) ? READA : READ;
}
/* Special code path for reading a sub page size buffer in --
@@ -1681,6 +1686,7 @@ xfsbufd(
xfs_buf_t *bp, *n;
struct list_head *dwq = &target->bt_delwrite_queue;
spinlock_t *dwlk = &target->bt_delwrite_lock;
+ int count;
current->flags |= PF_MEMALLOC;
@@ -1696,6 +1702,7 @@ xfsbufd(
schedule_timeout_interruptible(
xfs_buf_timer_centisecs * msecs_to_jiffies(10));
+ count = 0;
age = xfs_buf_age_centisecs * msecs_to_jiffies(10);
spin_lock(dwlk);
list_for_each_entry_safe(bp, n, dwq, b_list) {
@@ -1711,9 +1718,11 @@ xfsbufd(
break;
}
- bp->b_flags &= ~(XBF_DELWRI|_XBF_DELWRI_Q);
+ bp->b_flags &= ~(XBF_DELWRI|_XBF_DELWRI_Q|
+ _XBF_RUN_QUEUES);
bp->b_flags |= XBF_WRITE;
- list_move(&bp->b_list, &tmp);
+ list_move_tail(&bp->b_list, &tmp);
+ count++;
}
}
spin_unlock(dwlk);
@@ -1724,12 +1733,12 @@ xfsbufd(
list_del_init(&bp->b_list);
xfs_buf_iostrategy(bp);
-
- blk_run_address_space(target->bt_mapping);
}
if (as_list_len > 0)
purge_addresses();
+ if (count)
+ blk_run_address_space(target->bt_mapping);
clear_bit(XBT_FORCE_FLUSH, &target->bt_flags);
} while (!kthread_should_stop());
@@ -1767,7 +1776,7 @@ xfs_flush_buftarg(
continue;
}
- list_move(&bp->b_list, &tmp);
+ list_move_tail(&bp->b_list, &tmp);
}
spin_unlock(dwlk);
@@ -1776,7 +1785,7 @@ xfs_flush_buftarg(
*/
list_for_each_entry_safe(bp, n, &tmp, b_list) {
xfs_buf_lock(bp);
- bp->b_flags &= ~(XBF_DELWRI|_XBF_DELWRI_Q);
+ bp->b_flags &= ~(XBF_DELWRI|_XBF_DELWRI_Q|_XBF_RUN_QUEUES);
bp->b_flags |= XBF_WRITE;
if (wait)
bp->b_flags &= ~XBF_ASYNC;
@@ -1786,6 +1795,9 @@ xfs_flush_buftarg(
xfs_buf_iostrategy(bp);
}
+ if (wait)
+ blk_run_address_space(target->bt_mapping);
+
/*
* Remaining list items must be flushed before returning
*/
@@ -1797,9 +1809,6 @@ xfs_flush_buftarg(
xfs_buf_relse(bp);
}
- if (wait)
- blk_run_address_space(target->bt_mapping);
-
return pincount;
}
diff --git a/fs/xfs/linux-2.6/xfs_buf.h b/fs/xfs/linux-2.6/xfs_buf.h
index 7858703ed84c..9dd235cb0107 100644
--- a/fs/xfs/linux-2.6/xfs_buf.h
+++ b/fs/xfs/linux-2.6/xfs_buf.h
@@ -298,11 +298,6 @@ extern void xfs_buf_trace(xfs_buf_t *, char *, void *, void *);
#define XFS_BUF_UNWRITE(bp) ((bp)->b_flags &= ~XBF_WRITE)
#define XFS_BUF_ISWRITE(bp) ((bp)->b_flags & XBF_WRITE)
-#define XFS_BUF_ISUNINITIAL(bp) (0)
-#define XFS_BUF_UNUNINITIAL(bp) (0)
-
-#define XFS_BUF_BP_ISMAPPED(bp) (1)
-
#define XFS_BUF_IODONE_FUNC(bp) ((bp)->b_iodone)
#define XFS_BUF_SET_IODONE_FUNC(bp, func) ((bp)->b_iodone = (func))
#define XFS_BUF_CLR_IODONE_FUNC(bp) ((bp)->b_iodone = NULL)
@@ -393,8 +388,6 @@ static inline int XFS_bwrite(xfs_buf_t *bp)
return error;
}
-#define XFS_bdwrite(bp) xfs_buf_iostart(bp, XBF_DELWRI | XBF_ASYNC)
-
static inline int xfs_bdwrite(void *mp, xfs_buf_t *bp)
{
bp->b_strat = xfs_bdstrat_cb;
diff --git a/fs/xfs/linux-2.6/xfs_file.c b/fs/xfs/linux-2.6/xfs_file.c
index 41cfcba7ce49..d93d8dd1958d 100644
--- a/fs/xfs/linux-2.6/xfs_file.c
+++ b/fs/xfs/linux-2.6/xfs_file.c
@@ -49,50 +49,49 @@ static struct vm_operations_struct xfs_dmapi_file_vm_ops;
STATIC inline ssize_t
__xfs_file_read(
struct kiocb *iocb,
- char __user *buf,
+ const struct iovec *iov,
+ unsigned long nr_segs,
int ioflags,
- size_t count,
loff_t pos)
{
- struct iovec iov = {buf, count};
struct file *file = iocb->ki_filp;
bhv_vnode_t *vp = vn_from_inode(file->f_dentry->d_inode);
BUG_ON(iocb->ki_pos != pos);
if (unlikely(file->f_flags & O_DIRECT))
ioflags |= IO_ISDIRECT;
- return bhv_vop_read(vp, iocb, &iov, 1, &iocb->ki_pos, ioflags, NULL);
+ return bhv_vop_read(vp, iocb, iov, nr_segs, &iocb->ki_pos,
+ ioflags, NULL);
}
STATIC ssize_t
xfs_file_aio_read(
struct kiocb *iocb,
- char __user *buf,
- size_t count,
+ const struct iovec *iov,
+ unsigned long nr_segs,
loff_t pos)
{
- return __xfs_file_read(iocb, buf, IO_ISAIO, count, pos);
+ return __xfs_file_read(iocb, iov, nr_segs, IO_ISAIO, pos);
}
STATIC ssize_t
xfs_file_aio_read_invis(
struct kiocb *iocb,
- char __user *buf,
- size_t count,
+ const struct iovec *iov,
+ unsigned long nr_segs,
loff_t pos)
{
- return __xfs_file_read(iocb, buf, IO_ISAIO|IO_INVIS, count, pos);
+ return __xfs_file_read(iocb, iov, nr_segs, IO_ISAIO|IO_INVIS, pos);
}
STATIC inline ssize_t
__xfs_file_write(
- struct kiocb *iocb,
- const char __user *buf,
- int ioflags,
- size_t count,
- loff_t pos)
+ struct kiocb *iocb,
+ const struct iovec *iov,
+ unsigned long nr_segs,
+ int ioflags,
+ loff_t pos)
{
- struct iovec iov = {(void __user *)buf, count};
struct file *file = iocb->ki_filp;
struct inode *inode = file->f_mapping->host;
bhv_vnode_t *vp = vn_from_inode(inode);
@@ -100,117 +99,28 @@ __xfs_file_write(
BUG_ON(iocb->ki_pos != pos);
if (unlikely(file->f_flags & O_DIRECT))
ioflags |= IO_ISDIRECT;
- return bhv_vop_write(vp, iocb, &iov, 1, &iocb->ki_pos, ioflags, NULL);
+ return bhv_vop_write(vp, iocb, iov, nr_segs, &iocb->ki_pos,
+ ioflags, NULL);
}
STATIC ssize_t
xfs_file_aio_write(
struct kiocb *iocb,
- const char __user *buf,
- size_t count,
+ const struct iovec *iov,
+ unsigned long nr_segs,
loff_t pos)
{
- return __xfs_file_write(iocb, buf, IO_ISAIO, count, pos);
+ return __xfs_file_write(iocb, iov, nr_segs, IO_ISAIO, pos);
}
STATIC ssize_t
xfs_file_aio_write_invis(
struct kiocb *iocb,
- const char __user *buf,
- size_t count,
- loff_t pos)
-{
- return __xfs_file_write(iocb, buf, IO_ISAIO|IO_INVIS, count, pos);
-}
-
-STATIC inline ssize_t
-__xfs_file_readv(
- struct file *file,
- const struct iovec *iov,
- int ioflags,
- unsigned long nr_segs,
- loff_t *ppos)
-{
- struct inode *inode = file->f_mapping->host;
- bhv_vnode_t *vp = vn_from_inode(inode);
- struct kiocb kiocb;
- ssize_t rval;
-
- init_sync_kiocb(&kiocb, file);
- kiocb.ki_pos = *ppos;
-
- if (unlikely(file->f_flags & O_DIRECT))
- ioflags |= IO_ISDIRECT;
- rval = bhv_vop_read(vp, &kiocb, iov, nr_segs,
- &kiocb.ki_pos, ioflags, NULL);
-
- *ppos = kiocb.ki_pos;
- return rval;
-}
-
-STATIC ssize_t
-xfs_file_readv(
- struct file *file,
- const struct iovec *iov,
- unsigned long nr_segs,
- loff_t *ppos)
-{
- return __xfs_file_readv(file, iov, 0, nr_segs, ppos);
-}
-
-STATIC ssize_t
-xfs_file_readv_invis(
- struct file *file,
- const struct iovec *iov,
- unsigned long nr_segs,
- loff_t *ppos)
-{
- return __xfs_file_readv(file, iov, IO_INVIS, nr_segs, ppos);
-}
-
-STATIC inline ssize_t
-__xfs_file_writev(
- struct file *file,
- const struct iovec *iov,
- int ioflags,
- unsigned long nr_segs,
- loff_t *ppos)
-{
- struct inode *inode = file->f_mapping->host;
- bhv_vnode_t *vp = vn_from_inode(inode);
- struct kiocb kiocb;
- ssize_t rval;
-
- init_sync_kiocb(&kiocb, file);
- kiocb.ki_pos = *ppos;
- if (unlikely(file->f_flags & O_DIRECT))
- ioflags |= IO_ISDIRECT;
-
- rval = bhv_vop_write(vp, &kiocb, iov, nr_segs,
- &kiocb.ki_pos, ioflags, NULL);
-
- *ppos = kiocb.ki_pos;
- return rval;
-}
-
-STATIC ssize_t
-xfs_file_writev(
- struct file *file,
- const struct iovec *iov,
+ const struct iovec *iov,
unsigned long nr_segs,
- loff_t *ppos)
-{
- return __xfs_file_writev(file, iov, 0, nr_segs, ppos);
-}
-
-STATIC ssize_t
-xfs_file_writev_invis(
- struct file *file,
- const struct iovec *iov,
- unsigned long nr_segs,
- loff_t *ppos)
+ loff_t pos)
{
- return __xfs_file_writev(file, iov, IO_INVIS, nr_segs, ppos);
+ return __xfs_file_write(iocb, iov, nr_segs, IO_ISAIO|IO_INVIS, pos);
}
STATIC ssize_t
@@ -540,8 +450,6 @@ const struct file_operations xfs_file_operations = {
.llseek = generic_file_llseek,
.read = do_sync_read,
.write = do_sync_write,
- .readv = xfs_file_readv,
- .writev = xfs_file_writev,
.aio_read = xfs_file_aio_read,
.aio_write = xfs_file_aio_write,
.sendfile = xfs_file_sendfile,
@@ -565,8 +473,6 @@ const struct file_operations xfs_invis_file_operations = {
.llseek = generic_file_llseek,
.read = do_sync_read,
.write = do_sync_write,
- .readv = xfs_file_readv_invis,
- .writev = xfs_file_writev_invis,
.aio_read = xfs_file_aio_read_invis,
.aio_write = xfs_file_aio_write_invis,
.sendfile = xfs_file_sendfile_invis,
diff --git a/fs/xfs/linux-2.6/xfs_globals.c b/fs/xfs/linux-2.6/xfs_globals.c
index 6c162c3dde7e..ed3a5e1b4b67 100644
--- a/fs/xfs/linux-2.6/xfs_globals.c
+++ b/fs/xfs/linux-2.6/xfs_globals.c
@@ -34,7 +34,7 @@ xfs_param_t xfs_params = {
.restrict_chown = { 0, 1, 1 },
.sgid_inherit = { 0, 0, 1 },
.symlink_mode = { 0, 0, 1 },
- .panic_mask = { 0, 0, 127 },
+ .panic_mask = { 0, 0, 255 },
.error_level = { 0, 3, 11 },
.syncd_timer = { 1*100, 30*100, 7200*100},
.stats_clear = { 0, 0, 1 },
diff --git a/fs/xfs/linux-2.6/xfs_ioctl.c b/fs/xfs/linux-2.6/xfs_ioctl.c
index 6e52a5dd38d8..a74f854d91e6 100644
--- a/fs/xfs/linux-2.6/xfs_ioctl.c
+++ b/fs/xfs/linux-2.6/xfs_ioctl.c
@@ -653,7 +653,7 @@ xfs_attrmulti_by_handle(
STATIC int
xfs_ioc_space(
bhv_desc_t *bdp,
- bhv_vnode_t *vp,
+ struct inode *inode,
struct file *filp,
int flags,
unsigned int cmd,
@@ -735,7 +735,7 @@ xfs_ioctl(
!capable(CAP_SYS_ADMIN))
return -EPERM;
- return xfs_ioc_space(bdp, vp, filp, ioflags, cmd, arg);
+ return xfs_ioc_space(bdp, inode, filp, ioflags, cmd, arg);
case XFS_IOC_DIOINFO: {
struct dioattr da;
@@ -763,6 +763,8 @@ xfs_ioctl(
return xfs_ioc_fsgeometry(mp, arg);
case XFS_IOC_GETVERSION:
+ return put_user(inode->i_generation, (int __user *)arg);
+
case XFS_IOC_GETXFLAGS:
case XFS_IOC_SETXFLAGS:
case XFS_IOC_FSGETXATTR:
@@ -957,7 +959,7 @@ xfs_ioctl(
STATIC int
xfs_ioc_space(
bhv_desc_t *bdp,
- bhv_vnode_t *vp,
+ struct inode *inode,
struct file *filp,
int ioflags,
unsigned int cmd,
@@ -967,13 +969,13 @@ xfs_ioc_space(
int attr_flags = 0;
int error;
- if (vp->v_inode.i_flags & (S_IMMUTABLE|S_APPEND))
+ if (inode->i_flags & (S_IMMUTABLE|S_APPEND))
return -XFS_ERROR(EPERM);
if (!(filp->f_mode & FMODE_WRITE))
return -XFS_ERROR(EBADF);
- if (!VN_ISREG(vp))
+ if (!S_ISREG(inode->i_mode))
return -XFS_ERROR(EINVAL);
if (copy_from_user(&bf, arg, sizeof(bf)))
@@ -1264,13 +1266,6 @@ xfs_ioc_xattr(
break;
}
- case XFS_IOC_GETVERSION: {
- flags = vn_to_inode(vp)->i_generation;
- if (copy_to_user(arg, &flags, sizeof(flags)))
- error = -EFAULT;
- break;
- }
-
default:
error = -ENOTTY;
break;
diff --git a/fs/xfs/linux-2.6/xfs_iops.c b/fs/xfs/linux-2.6/xfs_iops.c
index 22e3b714f629..3ba814ae3bba 100644
--- a/fs/xfs/linux-2.6/xfs_iops.c
+++ b/fs/xfs/linux-2.6/xfs_iops.c
@@ -623,12 +623,27 @@ xfs_vn_getattr(
{
struct inode *inode = dentry->d_inode;
bhv_vnode_t *vp = vn_from_inode(inode);
- int error = 0;
+ bhv_vattr_t vattr = { .va_mask = XFS_AT_STAT };
+ int error;
- if (unlikely(vp->v_flag & VMODIFIED))
- error = vn_revalidate(vp);
- if (!error)
- generic_fillattr(inode, stat);
+ error = bhv_vop_getattr(vp, &vattr, ATTR_LAZY, NULL);
+ if (likely(!error)) {
+ stat->size = i_size_read(inode);
+ stat->dev = inode->i_sb->s_dev;
+ stat->rdev = (vattr.va_rdev == 0) ? 0 :
+ MKDEV(sysv_major(vattr.va_rdev) & 0x1ff,
+ sysv_minor(vattr.va_rdev));
+ stat->mode = vattr.va_mode;
+ stat->nlink = vattr.va_nlink;
+ stat->uid = vattr.va_uid;
+ stat->gid = vattr.va_gid;
+ stat->ino = vattr.va_nodeid;
+ stat->atime = vattr.va_atime;
+ stat->mtime = vattr.va_mtime;
+ stat->ctime = vattr.va_ctime;
+ stat->blocks = vattr.va_nblocks;
+ stat->blksize = vattr.va_blocksize;
+ }
return -error;
}
diff --git a/fs/xfs/linux-2.6/xfs_linux.h b/fs/xfs/linux-2.6/xfs_linux.h
index a13f75c1a936..2b0e0018738a 100644
--- a/fs/xfs/linux-2.6/xfs_linux.h
+++ b/fs/xfs/linux-2.6/xfs_linux.h
@@ -148,11 +148,7 @@ BUFFER_FNS(PrivateStart, unwritten);
(current->flags = ((current->flags & ~(f)) | (*(sp) & (f))))
#define NBPP PAGE_SIZE
-#define DPPSHFT (PAGE_SHIFT - 9)
#define NDPP (1 << (PAGE_SHIFT - 9))
-#define dtop(DD) (((DD) + NDPP - 1) >> DPPSHFT)
-#define dtopt(DD) ((DD) >> DPPSHFT)
-#define dpoff(DD) ((DD) & (NDPP-1))
#define NBBY 8 /* number of bits per byte */
#define NBPC PAGE_SIZE /* Number of bytes per click */
@@ -172,8 +168,6 @@ BUFFER_FNS(PrivateStart, unwritten);
#define btoct(x) ((__psunsigned_t)(x)>>BPCSHIFT)
#define btoc64(x) (((__uint64_t)(x)+(NBPC-1))>>BPCSHIFT)
#define btoct64(x) ((__uint64_t)(x)>>BPCSHIFT)
-#define io_btoc(x) (((__psunsigned_t)(x)+(IO_NBPC-1))>>IO_BPCSHIFT)
-#define io_btoct(x) ((__psunsigned_t)(x)>>IO_BPCSHIFT)
/* off_t bytes to clicks */
#define offtoc(x) (((__uint64_t)(x)+(NBPC-1))>>BPCSHIFT)
@@ -186,7 +180,6 @@ BUFFER_FNS(PrivateStart, unwritten);
#define ctob(x) ((__psunsigned_t)(x)<<BPCSHIFT)
#define btoct(x) ((__psunsigned_t)(x)>>BPCSHIFT)
#define ctob64(x) ((__uint64_t)(x)<<BPCSHIFT)
-#define io_ctob(x) ((__psunsigned_t)(x)<<IO_BPCSHIFT)
/* bytes to clicks */
#define btoc(x) (((__psunsigned_t)(x)+(NBPC-1))>>BPCSHIFT)
@@ -339,4 +332,11 @@ static inline __uint64_t roundup_64(__uint64_t x, __uint32_t y)
return(x * y);
}
+static inline __uint64_t howmany_64(__uint64_t x, __uint32_t y)
+{
+ x += y - 1;
+ do_div(x, y);
+ return x;
+}
+
#endif /* __XFS_LINUX__ */
diff --git a/fs/xfs/linux-2.6/xfs_lrw.c b/fs/xfs/linux-2.6/xfs_lrw.c
index ee788b1cb364..fa842f1c9fa2 100644
--- a/fs/xfs/linux-2.6/xfs_lrw.c
+++ b/fs/xfs/linux-2.6/xfs_lrw.c
@@ -270,16 +270,18 @@ xfs_read(
}
}
- if (unlikely((ioflags & IO_ISDIRECT) && VN_CACHED(vp)))
- bhv_vop_flushinval_pages(vp, ctooff(offtoct(*offset)),
- -1, FI_REMAPF_LOCKED);
-
- if (unlikely(ioflags & IO_ISDIRECT))
+ if (unlikely(ioflags & IO_ISDIRECT)) {
+ if (VN_CACHED(vp))
+ bhv_vop_flushinval_pages(vp, ctooff(offtoct(*offset)),
+ -1, FI_REMAPF_LOCKED);
mutex_unlock(&inode->i_mutex);
+ }
xfs_rw_enter_trace(XFS_READ_ENTER, &ip->i_iocore,
(void *)iovp, segs, *offset, ioflags);
- ret = __generic_file_aio_read(iocb, iovp, segs, offset);
+
+ iocb->ki_pos = *offset;
+ ret = generic_file_aio_read(iocb, iovp, segs, *offset);
if (ret == -EIOCBQUEUED && !(ioflags & IO_ISAIO))
ret = wait_on_sync_kiocb(iocb);
if (ret > 0)
diff --git a/fs/xfs/linux-2.6/xfs_super.c b/fs/xfs/linux-2.6/xfs_super.c
index 9df9ed37d219..38c4d128a8c0 100644
--- a/fs/xfs/linux-2.6/xfs_super.c
+++ b/fs/xfs/linux-2.6/xfs_super.c
@@ -227,7 +227,9 @@ xfs_initialize_vnode(
xfs_revalidate_inode(XFS_BHVTOM(bdp), vp, ip);
xfs_set_inodeops(inode);
+ spin_lock(&ip->i_flags_lock);
ip->i_flags &= ~XFS_INEW;
+ spin_unlock(&ip->i_flags_lock);
barrier();
unlock_new_inode(inode);
diff --git a/fs/xfs/linux-2.6/xfs_vfs.h b/fs/xfs/linux-2.6/xfs_vfs.h
index 91fc2c4b3353..da255bdf5260 100644
--- a/fs/xfs/linux-2.6/xfs_vfs.h
+++ b/fs/xfs/linux-2.6/xfs_vfs.h
@@ -79,7 +79,7 @@ typedef enum {
#define VFS_RDONLY 0x0001 /* read-only vfs */
#define VFS_GRPID 0x0002 /* group-ID assigned from directory */
#define VFS_DMI 0x0004 /* filesystem has the DMI enabled */
-#define VFS_UMOUNT 0x0008 /* unmount in progress */
+/* ---- VFS_UMOUNT ---- 0x0008 -- unneeded, fixed via kthread APIs */
#define VFS_32BITINODES 0x0010 /* do not use inums above 32 bits */
#define VFS_END 0x0010 /* max flag */
diff --git a/fs/xfs/linux-2.6/xfs_vnode.h b/fs/xfs/linux-2.6/xfs_vnode.h
index c42b3221b20c..515f5fdea57a 100644
--- a/fs/xfs/linux-2.6/xfs_vnode.h
+++ b/fs/xfs/linux-2.6/xfs_vnode.h
@@ -85,8 +85,6 @@ typedef enum {
#define VN_BHV_HEAD(vp) ((bhv_head_t *)(&((vp)->v_bh)))
#define vn_bhv_head_init(bhp,name) bhv_head_init(bhp,name)
#define vn_bhv_remove(bhp,bdp) bhv_remove(bhp,bdp)
-#define vn_bhv_lookup(bhp,ops) bhv_lookup(bhp,ops)
-#define vn_bhv_lookup_unlocked(bhp,ops) bhv_lookup_unlocked(bhp,ops)
/*
* Vnode to Linux inode mapping.
diff --git a/fs/xfs/quota/xfs_dquot_item.c b/fs/xfs/quota/xfs_dquot_item.c
index 5b2dcc58b244..33ad5af386e0 100644
--- a/fs/xfs/quota/xfs_dquot_item.c
+++ b/fs/xfs/quota/xfs_dquot_item.c
@@ -382,18 +382,6 @@ xfs_qm_dquot_logitem_unlock(
/*
- * The transaction with the dquot locked has aborted. The dquot
- * must not be dirty within the transaction. We simply unlock just
- * as if the transaction had been cancelled.
- */
-STATIC void
-xfs_qm_dquot_logitem_abort(
- xfs_dq_logitem_t *ql)
-{
- xfs_qm_dquot_logitem_unlock(ql);
-}
-
-/*
* this needs to stamp an lsn into the dquot, I think.
* rpc's that look at user dquot's would then have to
* push on the dependency recorded in the dquot
@@ -426,7 +414,6 @@ STATIC struct xfs_item_ops xfs_dquot_item_ops = {
.iop_committed = (xfs_lsn_t(*)(xfs_log_item_t*, xfs_lsn_t))
xfs_qm_dquot_logitem_committed,
.iop_push = (void(*)(xfs_log_item_t*))xfs_qm_dquot_logitem_push,
- .iop_abort = (void(*)(xfs_log_item_t*))xfs_qm_dquot_logitem_abort,
.iop_pushbuf = (void(*)(xfs_log_item_t*))
xfs_qm_dquot_logitem_pushbuf,
.iop_committing = (void(*)(xfs_log_item_t*, xfs_lsn_t))
@@ -559,17 +546,6 @@ xfs_qm_qoff_logitem_committed(xfs_qoff_logitem_t *qf, xfs_lsn_t lsn)
}
/*
- * The transaction of which this QUOTAOFF is a part has been aborted.
- * Just clean up after ourselves.
- * Shouldn't this never happen in the case of qoffend logitems? XXX
- */
-STATIC void
-xfs_qm_qoff_logitem_abort(xfs_qoff_logitem_t *qf)
-{
- kmem_free(qf, sizeof(xfs_qoff_logitem_t));
-}
-
-/*
* There isn't much you can do to push on an quotaoff item. It is simply
* stuck waiting for the log to be flushed to disk.
*/
@@ -644,7 +620,6 @@ STATIC struct xfs_item_ops xfs_qm_qoffend_logitem_ops = {
.iop_committed = (xfs_lsn_t(*)(xfs_log_item_t*, xfs_lsn_t))
xfs_qm_qoffend_logitem_committed,
.iop_push = (void(*)(xfs_log_item_t*))xfs_qm_qoff_logitem_push,
- .iop_abort = (void(*)(xfs_log_item_t*))xfs_qm_qoff_logitem_abort,
.iop_pushbuf = NULL,
.iop_committing = (void(*)(xfs_log_item_t*, xfs_lsn_t))
xfs_qm_qoffend_logitem_committing
@@ -667,7 +642,6 @@ STATIC struct xfs_item_ops xfs_qm_qoff_logitem_ops = {
.iop_committed = (xfs_lsn_t(*)(xfs_log_item_t*, xfs_lsn_t))
xfs_qm_qoff_logitem_committed,
.iop_push = (void(*)(xfs_log_item_t*))xfs_qm_qoff_logitem_push,
- .iop_abort = (void(*)(xfs_log_item_t*))xfs_qm_qoff_logitem_abort,
.iop_pushbuf = NULL,
.iop_committing = (void(*)(xfs_log_item_t*, xfs_lsn_t))
xfs_qm_qoff_logitem_committing
diff --git a/fs/xfs/quota/xfs_qm.c b/fs/xfs/quota/xfs_qm.c
index e23e45535c48..7c6a3a50379e 100644
--- a/fs/xfs/quota/xfs_qm.c
+++ b/fs/xfs/quota/xfs_qm.c
@@ -112,17 +112,17 @@ xfs_Gqm_init(void)
{
xfs_dqhash_t *udqhash, *gdqhash;
xfs_qm_t *xqm;
- uint i, hsize, flags = KM_SLEEP | KM_MAYFAIL;
+ size_t hsize;
+ uint i;
/*
* Initialize the dquot hash tables.
*/
- hsize = XFS_QM_HASHSIZE_HIGH;
- while (!(udqhash = kmem_zalloc(hsize * sizeof(xfs_dqhash_t), flags))) {
- if ((hsize >>= 1) <= XFS_QM_HASHSIZE_LOW)
- flags = KM_SLEEP;
- }
- gdqhash = kmem_zalloc(hsize * sizeof(xfs_dqhash_t), KM_SLEEP);
+ udqhash = kmem_zalloc_greedy(&hsize,
+ XFS_QM_HASHSIZE_LOW, XFS_QM_HASHSIZE_HIGH,
+ KM_SLEEP | KM_MAYFAIL | KM_LARGE);
+ gdqhash = kmem_zalloc(hsize, KM_SLEEP | KM_LARGE);
+ hsize /= sizeof(xfs_dqhash_t);
ndquot = hsize << 8;
xqm = kmem_zalloc(sizeof(xfs_qm_t), KM_SLEEP);
diff --git a/fs/xfs/quota/xfs_qm.h b/fs/xfs/quota/xfs_qm.h
index 4568deb6da86..689407de0a20 100644
--- a/fs/xfs/quota/xfs_qm.h
+++ b/fs/xfs/quota/xfs_qm.h
@@ -56,12 +56,6 @@ extern kmem_zone_t *qm_dqtrxzone;
#define XFS_QM_HASHSIZE_HIGH ((NBPP * 4) / sizeof(xfs_dqhash_t))
/*
- * We output a cmn_err when quotachecking a quota file with more than
- * this many fsbs.
- */
-#define XFS_QM_BIG_QCHECK_NBLKS 500
-
-/*
* This defines the unit of allocation of dquots.
* Currently, it is just one file system block, and a 4K blk contains 30
* (136 * 30 = 4080) dquots. It's probably not worth trying to make
diff --git a/fs/xfs/quota/xfs_quota_priv.h b/fs/xfs/quota/xfs_quota_priv.h
index b7ddd04aae32..a8b85e2be9d5 100644
--- a/fs/xfs/quota/xfs_quota_priv.h
+++ b/fs/xfs/quota/xfs_quota_priv.h
@@ -75,7 +75,6 @@ static inline int XQMISLCKD(struct xfs_dqhash *h)
#define xfs_qm_freelist_lock(qm) XQMLCK(&((qm)->qm_dqfreelist))
#define xfs_qm_freelist_unlock(qm) XQMUNLCK(&((qm)->qm_dqfreelist))
-#define XFS_QM_IS_FREELIST_LOCKED(qm) XQMISLCKD(&((qm)->qm_dqfreelist))
/*
* Hash into a bucket in the dquot hash table, based on <mp, id>.
@@ -170,6 +169,5 @@ for ((dqp) = (qlist)->qh_next; (dqp) != (xfs_dquot_t *)(qlist); \
#define DQFLAGTO_TYPESTR(d) (((d)->dq_flags & XFS_DQ_USER) ? "USR" : \
(((d)->dq_flags & XFS_DQ_GROUP) ? "GRP" : \
(((d)->dq_flags & XFS_DQ_PROJ) ? "PRJ":"???")))
-#define DQFLAGTO_DIRTYSTR(d) (XFS_DQ_IS_DIRTY(d) ? "DIRTY" : "NOTDIRTY")
#endif /* __XFS_QUOTA_PRIV_H__ */
diff --git a/fs/xfs/support/ktrace.c b/fs/xfs/support/ktrace.c
index addf5a7ea06c..5cf2e86caa71 100644
--- a/fs/xfs/support/ktrace.c
+++ b/fs/xfs/support/ktrace.c
@@ -75,7 +75,7 @@ ktrace_alloc(int nentries, unsigned int __nocast sleep)
sleep);
} else {
ktep = (ktrace_entry_t*)kmem_zalloc((nentries * sizeof(*ktep)),
- sleep);
+ sleep | KM_LARGE);
}
if (ktep == NULL) {
diff --git a/fs/xfs/xfs_ag.h b/fs/xfs/xfs_ag.h
index dc2361dd740a..9ece7f87ec5b 100644
--- a/fs/xfs/xfs_ag.h
+++ b/fs/xfs/xfs_ag.h
@@ -150,7 +150,7 @@ typedef struct xfs_agi {
#define XFS_BUF_TO_AGFL(bp) ((xfs_agfl_t *)XFS_BUF_PTR(bp))
typedef struct xfs_agfl {
- xfs_agblock_t agfl_bno[1]; /* actually XFS_AGFL_SIZE(mp) */
+ __be32 agfl_bno[1]; /* actually XFS_AGFL_SIZE(mp) */
} xfs_agfl_t;
/*
diff --git a/fs/xfs/xfs_alloc.c b/fs/xfs/xfs_alloc.c
index d2bbcd882a69..e80dda3437d1 100644
--- a/fs/xfs/xfs_alloc.c
+++ b/fs/xfs/xfs_alloc.c
@@ -1477,8 +1477,10 @@ xfs_alloc_ag_vextent_small(
/*
* Can't allocate from the freelist for some reason.
*/
- else
+ else {
+ fbno = NULLAGBLOCK;
flen = 0;
+ }
/*
* Can't do the allocation, give up.
*/
@@ -2021,7 +2023,7 @@ xfs_alloc_get_freelist(
/*
* Get the block number and update the data structures.
*/
- bno = INT_GET(agfl->agfl_bno[be32_to_cpu(agf->agf_flfirst)], ARCH_CONVERT);
+ bno = be32_to_cpu(agfl->agfl_bno[be32_to_cpu(agf->agf_flfirst)]);
be32_add(&agf->agf_flfirst, 1);
xfs_trans_brelse(tp, agflbp);
if (be32_to_cpu(agf->agf_flfirst) == XFS_AGFL_SIZE(mp))
@@ -2108,7 +2110,7 @@ xfs_alloc_put_freelist(
{
xfs_agf_t *agf; /* a.g. freespace structure */
xfs_agfl_t *agfl; /* a.g. free block array */
- xfs_agblock_t *blockp;/* pointer to array entry */
+ __be32 *blockp;/* pointer to array entry */
int error;
#ifdef XFS_ALLOC_TRACE
static char fname[] = "xfs_alloc_put_freelist";
@@ -2132,7 +2134,7 @@ xfs_alloc_put_freelist(
pag->pagf_flcount++;
ASSERT(be32_to_cpu(agf->agf_flcount) <= XFS_AGFL_SIZE(mp));
blockp = &agfl->agfl_bno[be32_to_cpu(agf->agf_fllast)];
- INT_SET(*blockp, ARCH_CONVERT, bno);
+ *blockp = cpu_to_be32(bno);
TRACE_MODAGF(NULL, agf, XFS_AGF_FLLAST | XFS_AGF_FLCOUNT);
xfs_alloc_log_agf(tp, agbp, XFS_AGF_FLLAST | XFS_AGF_FLCOUNT);
xfs_trans_log_buf(tp, agflbp,
diff --git a/fs/xfs/xfs_alloc_btree.c b/fs/xfs/xfs_alloc_btree.c
index 7446556e8021..74cadf95d4e8 100644
--- a/fs/xfs/xfs_alloc_btree.c
+++ b/fs/xfs/xfs_alloc_btree.c
@@ -92,6 +92,7 @@ xfs_alloc_delrec(
xfs_alloc_key_t *rkp; /* right block key pointer */
xfs_alloc_ptr_t *rpp; /* right block address pointer */
int rrecs=0; /* number of records in right block */
+ int numrecs;
xfs_alloc_rec_t *rrp; /* right block record pointer */
xfs_btree_cur_t *tcur; /* temporary btree cursor */
@@ -115,7 +116,8 @@ xfs_alloc_delrec(
/*
* Fail if we're off the end of the block.
*/
- if (ptr > be16_to_cpu(block->bb_numrecs)) {
+ numrecs = be16_to_cpu(block->bb_numrecs);
+ if (ptr > numrecs) {
*stat = 0;
return 0;
}
@@ -129,18 +131,18 @@ xfs_alloc_delrec(
lkp = XFS_ALLOC_KEY_ADDR(block, 1, cur);
lpp = XFS_ALLOC_PTR_ADDR(block, 1, cur);
#ifdef DEBUG
- for (i = ptr; i < be16_to_cpu(block->bb_numrecs); i++) {
+ for (i = ptr; i < numrecs; i++) {
if ((error = xfs_btree_check_sptr(cur, be32_to_cpu(lpp[i]), level)))
return error;
}
#endif
- if (ptr < be16_to_cpu(block->bb_numrecs)) {
+ if (ptr < numrecs) {
memmove(&lkp[ptr - 1], &lkp[ptr],
- (be16_to_cpu(block->bb_numrecs) - ptr) * sizeof(*lkp));
+ (numrecs - ptr) * sizeof(*lkp));
memmove(&lpp[ptr - 1], &lpp[ptr],
- (be16_to_cpu(block->bb_numrecs) - ptr) * sizeof(*lpp));
- xfs_alloc_log_ptrs(cur, bp, ptr, be16_to_cpu(block->bb_numrecs) - 1);
- xfs_alloc_log_keys(cur, bp, ptr, be16_to_cpu(block->bb_numrecs) - 1);
+ (numrecs - ptr) * sizeof(*lpp));
+ xfs_alloc_log_ptrs(cur, bp, ptr, numrecs - 1);
+ xfs_alloc_log_keys(cur, bp, ptr, numrecs - 1);
}
}
/*
@@ -149,10 +151,10 @@ xfs_alloc_delrec(
*/
else {
lrp = XFS_ALLOC_REC_ADDR(block, 1, cur);
- if (ptr < be16_to_cpu(block->bb_numrecs)) {
+ if (ptr < numrecs) {
memmove(&lrp[ptr - 1], &lrp[ptr],
- (be16_to_cpu(block->bb_numrecs) - ptr) * sizeof(*lrp));
- xfs_alloc_log_recs(cur, bp, ptr, be16_to_cpu(block->bb_numrecs) - 1);
+ (numrecs - ptr) * sizeof(*lrp));
+ xfs_alloc_log_recs(cur, bp, ptr, numrecs - 1);
}
/*
* If it's the first record in the block, we'll need a key
@@ -167,7 +169,8 @@ xfs_alloc_delrec(
/*
* Decrement and log the number of entries in the block.
*/
- be16_add(&block->bb_numrecs, -1);
+ numrecs--;
+ block->bb_numrecs = cpu_to_be16(numrecs);
xfs_alloc_log_block(cur->bc_tp, bp, XFS_BB_NUMRECS);
/*
* See if the longest free extent in the allocation group was
@@ -181,14 +184,14 @@ xfs_alloc_delrec(
if (level == 0 &&
cur->bc_btnum == XFS_BTNUM_CNT &&
be32_to_cpu(block->bb_rightsib) == NULLAGBLOCK &&
- ptr > be16_to_cpu(block->bb_numrecs)) {
- ASSERT(ptr == be16_to_cpu(block->bb_numrecs) + 1);
+ ptr > numrecs) {
+ ASSERT(ptr == numrecs + 1);
/*
* There are still records in the block. Grab the size
* from the last one.
*/
- if (be16_to_cpu(block->bb_numrecs)) {
- rrp = XFS_ALLOC_REC_ADDR(block, be16_to_cpu(block->bb_numrecs), cur);
+ if (numrecs) {
+ rrp = XFS_ALLOC_REC_ADDR(block, numrecs, cur);
agf->agf_longest = rrp->ar_blockcount;
}
/*
@@ -211,7 +214,7 @@ xfs_alloc_delrec(
* and it's NOT the leaf level,
* then we can get rid of this level.
*/
- if (be16_to_cpu(block->bb_numrecs) == 1 && level > 0) {
+ if (numrecs == 1 && level > 0) {
/*
* lpp is still set to the first pointer in the block.
* Make it the new root of the btree.
@@ -267,7 +270,7 @@ xfs_alloc_delrec(
* If the number of records remaining in the block is at least
* the minimum, we're done.
*/
- if (be16_to_cpu(block->bb_numrecs) >= XFS_ALLOC_BLOCK_MINRECS(level, cur)) {
+ if (numrecs >= XFS_ALLOC_BLOCK_MINRECS(level, cur)) {
if (level > 0 && (error = xfs_alloc_decrement(cur, level, &i)))
return error;
*stat = 1;
@@ -419,19 +422,21 @@ xfs_alloc_delrec(
* See if we can join with the left neighbor block.
*/
if (lbno != NULLAGBLOCK &&
- lrecs + be16_to_cpu(block->bb_numrecs) <= XFS_ALLOC_BLOCK_MAXRECS(level, cur)) {
+ lrecs + numrecs <= XFS_ALLOC_BLOCK_MAXRECS(level, cur)) {
/*
* Set "right" to be the starting block,
* "left" to be the left neighbor.
*/
rbno = bno;
right = block;
+ rrecs = be16_to_cpu(right->bb_numrecs);
rbp = bp;
if ((error = xfs_btree_read_bufs(mp, cur->bc_tp,
cur->bc_private.a.agno, lbno, 0, &lbp,
XFS_ALLOC_BTREE_REF)))
return error;
left = XFS_BUF_TO_ALLOC_BLOCK(lbp);
+ lrecs = be16_to_cpu(left->bb_numrecs);
if ((error = xfs_btree_check_sblock(cur, left, level, lbp)))
return error;
}
@@ -439,20 +444,21 @@ xfs_alloc_delrec(
* If that won't work, see if we can join with the right neighbor block.
*/
else if (rbno != NULLAGBLOCK &&
- rrecs + be16_to_cpu(block->bb_numrecs) <=
- XFS_ALLOC_BLOCK_MAXRECS(level, cur)) {
+ rrecs + numrecs <= XFS_ALLOC_BLOCK_MAXRECS(level, cur)) {
/*
* Set "left" to be the starting block,
* "right" to be the right neighbor.
*/
lbno = bno;
left = block;
+ lrecs = be16_to_cpu(left->bb_numrecs);
lbp = bp;
if ((error = xfs_btree_read_bufs(mp, cur->bc_tp,
cur->bc_private.a.agno, rbno, 0, &rbp,
XFS_ALLOC_BTREE_REF)))
return error;
right = XFS_BUF_TO_ALLOC_BLOCK(rbp);
+ rrecs = be16_to_cpu(right->bb_numrecs);
if ((error = xfs_btree_check_sblock(cur, right, level, rbp)))
return error;
}
@@ -474,34 +480,28 @@ xfs_alloc_delrec(
/*
* It's a non-leaf. Move keys and pointers.
*/
- lkp = XFS_ALLOC_KEY_ADDR(left, be16_to_cpu(left->bb_numrecs) + 1, cur);
- lpp = XFS_ALLOC_PTR_ADDR(left, be16_to_cpu(left->bb_numrecs) + 1, cur);
+ lkp = XFS_ALLOC_KEY_ADDR(left, lrecs + 1, cur);
+ lpp = XFS_ALLOC_PTR_ADDR(left, lrecs + 1, cur);
rkp = XFS_ALLOC_KEY_ADDR(right, 1, cur);
rpp = XFS_ALLOC_PTR_ADDR(right, 1, cur);
#ifdef DEBUG
- for (i = 0; i < be16_to_cpu(right->bb_numrecs); i++) {
+ for (i = 0; i < rrecs; i++) {
if ((error = xfs_btree_check_sptr(cur, be32_to_cpu(rpp[i]), level)))
return error;
}
#endif
- memcpy(lkp, rkp, be16_to_cpu(right->bb_numrecs) * sizeof(*lkp));
- memcpy(lpp, rpp, be16_to_cpu(right->bb_numrecs) * sizeof(*lpp));
- xfs_alloc_log_keys(cur, lbp, be16_to_cpu(left->bb_numrecs) + 1,
- be16_to_cpu(left->bb_numrecs) +
- be16_to_cpu(right->bb_numrecs));
- xfs_alloc_log_ptrs(cur, lbp, be16_to_cpu(left->bb_numrecs) + 1,
- be16_to_cpu(left->bb_numrecs) +
- be16_to_cpu(right->bb_numrecs));
+ memcpy(lkp, rkp, rrecs * sizeof(*lkp));
+ memcpy(lpp, rpp, rrecs * sizeof(*lpp));
+ xfs_alloc_log_keys(cur, lbp, lrecs + 1, lrecs + rrecs);
+ xfs_alloc_log_ptrs(cur, lbp, lrecs + 1, lrecs + rrecs);
} else {
/*
* It's a leaf. Move records.
*/
- lrp = XFS_ALLOC_REC_ADDR(left, be16_to_cpu(left->bb_numrecs) + 1, cur);
+ lrp = XFS_ALLOC_REC_ADDR(left, lrecs + 1, cur);
rrp = XFS_ALLOC_REC_ADDR(right, 1, cur);
- memcpy(lrp, rrp, be16_to_cpu(right->bb_numrecs) * sizeof(*lrp));
- xfs_alloc_log_recs(cur, lbp, be16_to_cpu(left->bb_numrecs) + 1,
- be16_to_cpu(left->bb_numrecs) +
- be16_to_cpu(right->bb_numrecs));
+ memcpy(lrp, rrp, rrecs * sizeof(*lrp));
+ xfs_alloc_log_recs(cur, lbp, lrecs + 1, lrecs + rrecs);
}
/*
* If we joined with the left neighbor, set the buffer in the
@@ -509,7 +509,7 @@ xfs_alloc_delrec(
*/
if (bp != lbp) {
xfs_btree_setbuf(cur, level, lbp);
- cur->bc_ptrs[level] += be16_to_cpu(left->bb_numrecs);
+ cur->bc_ptrs[level] += lrecs;
}
/*
* If we joined with the right neighbor and there's a level above
@@ -521,7 +521,8 @@ xfs_alloc_delrec(
/*
* Fix up the number of records in the surviving block.
*/
- be16_add(&left->bb_numrecs, be16_to_cpu(right->bb_numrecs));
+ lrecs += rrecs;
+ left->bb_numrecs = cpu_to_be16(lrecs);
/*
* Fix up the right block pointer in the surviving block, and log it.
*/
@@ -608,6 +609,7 @@ xfs_alloc_insrec(
xfs_btree_cur_t *ncur; /* new cursor to be used at next lvl */
xfs_alloc_key_t nkey; /* new key value, from split */
xfs_alloc_rec_t nrec; /* new record value, for caller */
+ int numrecs;
int optr; /* old ptr value */
xfs_alloc_ptr_t *pp; /* pointer to btree addresses */
int ptr; /* index in btree block for this rec */
@@ -653,13 +655,14 @@ xfs_alloc_insrec(
*/
bp = cur->bc_bufs[level];
block = XFS_BUF_TO_ALLOC_BLOCK(bp);
+ numrecs = be16_to_cpu(block->bb_numrecs);
#ifdef DEBUG
if ((error = xfs_btree_check_sblock(cur, block, level, bp)))
return error;
/*
* Check that the new entry is being inserted in the right place.
*/
- if (ptr <= be16_to_cpu(block->bb_numrecs)) {
+ if (ptr <= numrecs) {
if (level == 0) {
rp = XFS_ALLOC_REC_ADDR(block, ptr, cur);
xfs_btree_check_rec(cur->bc_btnum, recp, rp);
@@ -670,12 +673,12 @@ xfs_alloc_insrec(
}
#endif
nbno = NULLAGBLOCK;
- ncur = (xfs_btree_cur_t *)0;
+ ncur = NULL;
/*
* If the block is full, we can't insert the new entry until we
* make the block un-full.
*/
- if (be16_to_cpu(block->bb_numrecs) == XFS_ALLOC_BLOCK_MAXRECS(level, cur)) {
+ if (numrecs == XFS_ALLOC_BLOCK_MAXRECS(level, cur)) {
/*
* First, try shifting an entry to the right neighbor.
*/
@@ -729,6 +732,7 @@ xfs_alloc_insrec(
* At this point we know there's room for our new entry in the block
* we're pointing at.
*/
+ numrecs = be16_to_cpu(block->bb_numrecs);
if (level > 0) {
/*
* It's a non-leaf entry. Make a hole for the new data
@@ -737,15 +741,15 @@ xfs_alloc_insrec(
kp = XFS_ALLOC_KEY_ADDR(block, 1, cur);
pp = XFS_ALLOC_PTR_ADDR(block, 1, cur);
#ifdef DEBUG
- for (i = be16_to_cpu(block->bb_numrecs); i >= ptr; i--) {
+ for (i = numrecs; i >= ptr; i--) {
if ((error = xfs_btree_check_sptr(cur, be32_to_cpu(pp[i - 1]), level)))
return error;
}
#endif
memmove(&kp[ptr], &kp[ptr - 1],
- (be16_to_cpu(block->bb_numrecs) - ptr + 1) * sizeof(*kp));
+ (numrecs - ptr + 1) * sizeof(*kp));
memmove(&pp[ptr], &pp[ptr - 1],
- (be16_to_cpu(block->bb_numrecs) - ptr + 1) * sizeof(*pp));
+ (numrecs - ptr + 1) * sizeof(*pp));
#ifdef DEBUG
if ((error = xfs_btree_check_sptr(cur, *bnop, level)))
return error;
@@ -755,11 +759,12 @@ xfs_alloc_insrec(
*/
kp[ptr - 1] = key;
pp[ptr - 1] = cpu_to_be32(*bnop);
- be16_add(&block->bb_numrecs, 1);
- xfs_alloc_log_keys(cur, bp, ptr, be16_to_cpu(block->bb_numrecs));
- xfs_alloc_log_ptrs(cur, bp, ptr, be16_to_cpu(block->bb_numrecs));
+ numrecs++;
+ block->bb_numrecs = cpu_to_be16(numrecs);
+ xfs_alloc_log_keys(cur, bp, ptr, numrecs);
+ xfs_alloc_log_ptrs(cur, bp, ptr, numrecs);
#ifdef DEBUG
- if (ptr < be16_to_cpu(block->bb_numrecs))
+ if (ptr < numrecs)
xfs_btree_check_key(cur->bc_btnum, kp + ptr - 1,
kp + ptr);
#endif
@@ -769,16 +774,17 @@ xfs_alloc_insrec(
*/
rp = XFS_ALLOC_REC_ADDR(block, 1, cur);
memmove(&rp[ptr], &rp[ptr - 1],
- (be16_to_cpu(block->bb_numrecs) - ptr + 1) * sizeof(*rp));
+ (numrecs - ptr + 1) * sizeof(*rp));
/*
* Now stuff the new record in, bump numrecs
* and log the new data.
*/
- rp[ptr - 1] = *recp; /* INT_: struct copy */
- be16_add(&block->bb_numrecs, 1);
- xfs_alloc_log_recs(cur, bp, ptr, be16_to_cpu(block->bb_numrecs));
+ rp[ptr - 1] = *recp;
+ numrecs++;
+ block->bb_numrecs = cpu_to_be16(numrecs);
+ xfs_alloc_log_recs(cur, bp, ptr, numrecs);
#ifdef DEBUG
- if (ptr < be16_to_cpu(block->bb_numrecs))
+ if (ptr < numrecs)
xfs_btree_check_rec(cur->bc_btnum, rp + ptr - 1,
rp + ptr);
#endif
@@ -819,8 +825,8 @@ xfs_alloc_insrec(
*/
*bnop = nbno;
if (nbno != NULLAGBLOCK) {
- *recp = nrec; /* INT_: struct copy */
- *curp = ncur; /* INT_: struct copy */
+ *recp = nrec;
+ *curp = ncur;
}
*stat = 1;
return 0;
@@ -981,7 +987,7 @@ xfs_alloc_lookup(
*/
bp = cur->bc_bufs[level];
if (bp && XFS_BUF_ADDR(bp) != d)
- bp = (xfs_buf_t *)0;
+ bp = NULL;
if (!bp) {
/*
* Need to get a new buffer. Read it, then
@@ -1229,7 +1235,7 @@ xfs_alloc_lshift(
if ((error = xfs_btree_check_sptr(cur, be32_to_cpu(*rpp), level)))
return error;
#endif
- *lpp = *rpp; /* INT_: copy */
+ *lpp = *rpp;
xfs_alloc_log_ptrs(cur, lbp, nrec, nrec);
xfs_btree_check_key(cur->bc_btnum, lkp - 1, lkp);
}
@@ -1406,8 +1412,8 @@ xfs_alloc_newroot(
kp = XFS_ALLOC_KEY_ADDR(new, 1, cur);
if (be16_to_cpu(left->bb_level) > 0) {
- kp[0] = *XFS_ALLOC_KEY_ADDR(left, 1, cur); /* INT_: structure copy */
- kp[1] = *XFS_ALLOC_KEY_ADDR(right, 1, cur);/* INT_: structure copy */
+ kp[0] = *XFS_ALLOC_KEY_ADDR(left, 1, cur);
+ kp[1] = *XFS_ALLOC_KEY_ADDR(right, 1, cur);
} else {
xfs_alloc_rec_t *rp; /* btree record pointer */
@@ -1527,8 +1533,8 @@ xfs_alloc_rshift(
if ((error = xfs_btree_check_sptr(cur, be32_to_cpu(*lpp), level)))
return error;
#endif
- *rkp = *lkp; /* INT_: copy */
- *rpp = *lpp; /* INT_: copy */
+ *rkp = *lkp;
+ *rpp = *lpp;
xfs_alloc_log_keys(cur, rbp, 1, be16_to_cpu(right->bb_numrecs) + 1);
xfs_alloc_log_ptrs(cur, rbp, 1, be16_to_cpu(right->bb_numrecs) + 1);
xfs_btree_check_key(cur->bc_btnum, rkp, rkp + 1);
@@ -2044,7 +2050,7 @@ xfs_alloc_insert(
nbno = NULLAGBLOCK;
nrec.ar_startblock = cpu_to_be32(cur->bc_rec.a.ar_startblock);
nrec.ar_blockcount = cpu_to_be32(cur->bc_rec.a.ar_blockcount);
- ncur = (xfs_btree_cur_t *)0;
+ ncur = NULL;
pcur = cur;
/*
* Loop going up the tree, starting at the leaf level.
@@ -2076,7 +2082,7 @@ xfs_alloc_insert(
*/
if (ncur) {
pcur = ncur;
- ncur = (xfs_btree_cur_t *)0;
+ ncur = NULL;
}
} while (nbno != NULLAGBLOCK);
*stat = i;
diff --git a/fs/xfs/xfs_attr.c b/fs/xfs/xfs_attr.c
index 1a2101043275..9ada7bdbae52 100644
--- a/fs/xfs/xfs_attr.c
+++ b/fs/xfs/xfs_attr.c
@@ -91,7 +91,6 @@ STATIC int xfs_attr_refillstate(xfs_da_state_t *state);
/*
* Routines to manipulate out-of-line attribute values.
*/
-STATIC int xfs_attr_rmtval_get(xfs_da_args_t *args);
STATIC int xfs_attr_rmtval_set(xfs_da_args_t *args);
STATIC int xfs_attr_rmtval_remove(xfs_da_args_t *args);
@@ -180,7 +179,7 @@ xfs_attr_get(bhv_desc_t *bdp, const char *name, char *value, int *valuelenp,
return(error);
}
-STATIC int
+int
xfs_attr_set_int(xfs_inode_t *dp, const char *name, int namelen,
char *value, int valuelen, int flags)
{
@@ -440,7 +439,7 @@ xfs_attr_set(bhv_desc_t *bdp, const char *name, char *value, int valuelen, int f
* Generic handler routine to remove a name from an attribute list.
* Transitions attribute list from Btree to shortform as necessary.
*/
-STATIC int
+int
xfs_attr_remove_int(xfs_inode_t *dp, const char *name, int namelen, int flags)
{
xfs_da_args_t args;
@@ -591,6 +590,110 @@ xfs_attr_remove(bhv_desc_t *bdp, const char *name, int flags, struct cred *cred)
return xfs_attr_remove_int(dp, name, namelen, flags);
}
+int /* error */
+xfs_attr_list_int(xfs_attr_list_context_t *context)
+{
+ int error;
+ xfs_inode_t *dp = context->dp;
+
+ /*
+ * Decide on what work routines to call based on the inode size.
+ */
+ if (XFS_IFORK_Q(dp) == 0 ||
+ (dp->i_d.di_aformat == XFS_DINODE_FMT_EXTENTS &&
+ dp->i_d.di_anextents == 0)) {
+ error = 0;
+ } else if (dp->i_d.di_aformat == XFS_DINODE_FMT_LOCAL) {
+ error = xfs_attr_shortform_list(context);
+ } else if (xfs_bmap_one_block(dp, XFS_ATTR_FORK)) {
+ error = xfs_attr_leaf_list(context);
+ } else {
+ error = xfs_attr_node_list(context);
+ }
+ return error;
+}
+
+#define ATTR_ENTBASESIZE /* minimum bytes used by an attr */ \
+ (((struct attrlist_ent *) 0)->a_name - (char *) 0)
+#define ATTR_ENTSIZE(namelen) /* actual bytes used by an attr */ \
+ ((ATTR_ENTBASESIZE + (namelen) + 1 + sizeof(u_int32_t)-1) \
+ & ~(sizeof(u_int32_t)-1))
+
+/*
+ * Format an attribute and copy it out to the user's buffer.
+ * Take care to check values and protect against them changing later,
+ * we may be reading them directly out of a user buffer.
+ */
+/*ARGSUSED*/
+STATIC int
+xfs_attr_put_listent(xfs_attr_list_context_t *context, attrnames_t *namesp,
+ char *name, int namelen,
+ int valuelen, char *value)
+{
+ attrlist_ent_t *aep;
+ int arraytop;
+
+ ASSERT(!(context->flags & ATTR_KERNOVAL));
+ ASSERT(context->count >= 0);
+ ASSERT(context->count < (ATTR_MAX_VALUELEN/8));
+ ASSERT(context->firstu >= sizeof(*context->alist));
+ ASSERT(context->firstu <= context->bufsize);
+
+ arraytop = sizeof(*context->alist) +
+ context->count * sizeof(context->alist->al_offset[0]);
+ context->firstu -= ATTR_ENTSIZE(namelen);
+ if (context->firstu < arraytop) {
+ xfs_attr_trace_l_c("buffer full", context);
+ context->alist->al_more = 1;
+ context->seen_enough = 1;
+ return 1;
+ }
+
+ aep = (attrlist_ent_t *)&(((char *)context->alist)[ context->firstu ]);
+ aep->a_valuelen = valuelen;
+ memcpy(aep->a_name, name, namelen);
+ aep->a_name[ namelen ] = 0;
+ context->alist->al_offset[ context->count++ ] = context->firstu;
+ context->alist->al_count = context->count;
+ xfs_attr_trace_l_c("add", context);
+ return 0;
+}
+
+STATIC int
+xfs_attr_kern_list(xfs_attr_list_context_t *context, attrnames_t *namesp,
+ char *name, int namelen,
+ int valuelen, char *value)
+{
+ char *offset;
+ int arraytop;
+
+ ASSERT(context->count >= 0);
+
+ arraytop = context->count + namesp->attr_namelen + namelen + 1;
+ if (arraytop > context->firstu) {
+ context->count = -1; /* insufficient space */
+ return 1;
+ }
+ offset = (char *)context->alist + context->count;
+ strncpy(offset, namesp->attr_name, namesp->attr_namelen);
+ offset += namesp->attr_namelen;
+ strncpy(offset, name, namelen); /* real name */
+ offset += namelen;
+ *offset = '\0';
+ context->count += namesp->attr_namelen + namelen + 1;
+ return 0;
+}
+
+/*ARGSUSED*/
+STATIC int
+xfs_attr_kern_list_sizes(xfs_attr_list_context_t *context, attrnames_t *namesp,
+ char *name, int namelen,
+ int valuelen, char *value)
+{
+ context->count += namesp->attr_namelen + namelen + 1;
+ return 0;
+}
+
/*
* Generate a list of extended attribute names and optionally
* also value lengths. Positive return value follows the XFS
@@ -615,13 +718,13 @@ xfs_attr_list(bhv_desc_t *bdp, char *buffer, int bufsize, int flags,
return(XFS_ERROR(EINVAL));
if ((cursor->initted == 0) &&
(cursor->hashval || cursor->blkno || cursor->offset))
- return(XFS_ERROR(EINVAL));
+ return XFS_ERROR(EINVAL);
/*
* Check for a properly aligned buffer.
*/
if (((long)buffer) & (sizeof(int)-1))
- return(XFS_ERROR(EFAULT));
+ return XFS_ERROR(EFAULT);
if (flags & ATTR_KERNOVAL)
bufsize = 0;
@@ -634,53 +737,47 @@ xfs_attr_list(bhv_desc_t *bdp, char *buffer, int bufsize, int flags,
context.dupcnt = 0;
context.resynch = 1;
context.flags = flags;
- if (!(flags & ATTR_KERNAMELS)) {
+ context.seen_enough = 0;
+ context.alist = (attrlist_t *)buffer;
+ context.put_value = 0;
+
+ if (flags & ATTR_KERNAMELS) {
+ context.bufsize = bufsize;
+ context.firstu = context.bufsize;
+ if (flags & ATTR_KERNOVAL)
+ context.put_listent = xfs_attr_kern_list_sizes;
+ else
+ context.put_listent = xfs_attr_kern_list;
+ } else {
context.bufsize = (bufsize & ~(sizeof(int)-1)); /* align */
context.firstu = context.bufsize;
- context.alist = (attrlist_t *)buffer;
context.alist->al_count = 0;
context.alist->al_more = 0;
context.alist->al_offset[0] = context.bufsize;
- }
- else {
- context.bufsize = bufsize;
- context.firstu = context.bufsize;
- context.alist = (attrlist_t *)buffer;
+ context.put_listent = xfs_attr_put_listent;
}
if (XFS_FORCED_SHUTDOWN(dp->i_mount))
- return (EIO);
+ return EIO;
xfs_ilock(dp, XFS_ILOCK_SHARED);
- /*
- * Decide on what work routines to call based on the inode size.
- */
xfs_attr_trace_l_c("syscall start", &context);
- if (XFS_IFORK_Q(dp) == 0 ||
- (dp->i_d.di_aformat == XFS_DINODE_FMT_EXTENTS &&
- dp->i_d.di_anextents == 0)) {
- error = 0;
- } else if (dp->i_d.di_aformat == XFS_DINODE_FMT_LOCAL) {
- error = xfs_attr_shortform_list(&context);
- } else if (xfs_bmap_one_block(dp, XFS_ATTR_FORK)) {
- error = xfs_attr_leaf_list(&context);
- } else {
- error = xfs_attr_node_list(&context);
- }
+
+ error = xfs_attr_list_int(&context);
+
xfs_iunlock(dp, XFS_ILOCK_SHARED);
xfs_attr_trace_l_c("syscall end", &context);
- if (!(context.flags & (ATTR_KERNOVAL|ATTR_KERNAMELS))) {
- ASSERT(error >= 0);
- }
- else { /* must return negated buffer size or the error */
+ if (context.flags & (ATTR_KERNOVAL|ATTR_KERNAMELS)) {
+ /* must return negated buffer size or the error */
if (context.count < 0)
error = XFS_ERROR(ERANGE);
else
error = -context.count;
- }
+ } else
+ ASSERT(error >= 0);
- return(error);
+ return error;
}
int /* error */
@@ -1122,19 +1219,19 @@ xfs_attr_leaf_list(xfs_attr_list_context_t *context)
context->cursor->blkno = 0;
error = xfs_da_read_buf(NULL, context->dp, 0, -1, &bp, XFS_ATTR_FORK);
if (error)
- return(error);
+ return XFS_ERROR(error);
ASSERT(bp != NULL);
leaf = bp->data;
if (unlikely(be16_to_cpu(leaf->hdr.info.magic) != XFS_ATTR_LEAF_MAGIC)) {
XFS_CORRUPTION_ERROR("xfs_attr_leaf_list", XFS_ERRLEVEL_LOW,
context->dp->i_mount, leaf);
xfs_da_brelse(NULL, bp);
- return(XFS_ERROR(EFSCORRUPTED));
+ return XFS_ERROR(EFSCORRUPTED);
}
- (void)xfs_attr_leaf_list_int(bp, context);
+ error = xfs_attr_leaf_list_int(bp, context);
xfs_da_brelse(NULL, bp);
- return(0);
+ return XFS_ERROR(error);
}
@@ -1858,8 +1955,12 @@ xfs_attr_node_list(xfs_attr_list_context_t *context)
return(XFS_ERROR(EFSCORRUPTED));
}
error = xfs_attr_leaf_list_int(bp, context);
- if (error || !leaf->hdr.info.forw)
- break; /* not really an error, buffer full or EOF */
+ if (error) {
+ xfs_da_brelse(NULL, bp);
+ return error;
+ }
+ if (context->seen_enough || leaf->hdr.info.forw == 0)
+ break;
cursor->blkno = be32_to_cpu(leaf->hdr.info.forw);
xfs_da_brelse(NULL, bp);
error = xfs_da_read_buf(NULL, context->dp, cursor->blkno, -1,
@@ -1886,7 +1987,7 @@ xfs_attr_node_list(xfs_attr_list_context_t *context)
* Read the value associated with an attribute from the out-of-line buffer
* that we stored it in.
*/
-STATIC int
+int
xfs_attr_rmtval_get(xfs_da_args_t *args)
{
xfs_bmbt_irec_t map[ATTR_RMTVALUE_MAPSIZE];
diff --git a/fs/xfs/xfs_attr.h b/fs/xfs/xfs_attr.h
index 981633f6c077..783977d3ea71 100644
--- a/fs/xfs/xfs_attr.h
+++ b/fs/xfs/xfs_attr.h
@@ -37,6 +37,7 @@
struct cred;
struct bhv_vnode;
+struct xfs_attr_list_context;
typedef int (*attrset_t)(struct bhv_vnode *, char *, void *, size_t, int);
typedef int (*attrget_t)(struct bhv_vnode *, char *, void *, size_t, int);
@@ -160,13 +161,16 @@ struct xfs_da_args;
*/
int xfs_attr_get(bhv_desc_t *, const char *, char *, int *, int, struct cred *);
int xfs_attr_set(bhv_desc_t *, const char *, char *, int, int, struct cred *);
+int xfs_attr_set_int(struct xfs_inode *, const char *, int, char *, int, int);
int xfs_attr_remove(bhv_desc_t *, const char *, int, struct cred *);
-int xfs_attr_list(bhv_desc_t *, char *, int, int,
- struct attrlist_cursor_kern *, struct cred *);
+int xfs_attr_remove_int(struct xfs_inode *, const char *, int, int);
+int xfs_attr_list(bhv_desc_t *, char *, int, int, struct attrlist_cursor_kern *, struct cred *);
+int xfs_attr_list_int(struct xfs_attr_list_context *);
int xfs_attr_inactive(struct xfs_inode *dp);
int xfs_attr_shortform_getvalue(struct xfs_da_args *);
int xfs_attr_fetch(struct xfs_inode *, const char *, int,
char *, int *, int, struct cred *);
+int xfs_attr_rmtval_get(struct xfs_da_args *args);
#endif /* __XFS_ATTR_H__ */
diff --git a/fs/xfs/xfs_attr_leaf.c b/fs/xfs/xfs_attr_leaf.c
index 9455051f0120..9719bbef122c 100644
--- a/fs/xfs/xfs_attr_leaf.c
+++ b/fs/xfs/xfs_attr_leaf.c
@@ -89,9 +89,46 @@ STATIC void xfs_attr_leaf_moveents(xfs_attr_leafblock_t *src_leaf,
int dst_start, int move_count,
xfs_mount_t *mp);
STATIC int xfs_attr_leaf_entsize(xfs_attr_leafblock_t *leaf, int index);
-STATIC int xfs_attr_put_listent(xfs_attr_list_context_t *context,
- attrnames_t *, char *name, int namelen,
- int valuelen);
+
+/*========================================================================
+ * Namespace helper routines
+ *========================================================================*/
+
+STATIC inline attrnames_t *
+xfs_attr_flags_namesp(int flags)
+{
+ return ((flags & XFS_ATTR_SECURE) ? &attr_secure:
+ ((flags & XFS_ATTR_ROOT) ? &attr_trusted : &attr_user));
+}
+
+/*
+ * If namespace bits don't match return 0.
+ * If all match then return 1.
+ */
+STATIC inline int
+xfs_attr_namesp_match(int arg_flags, int ondisk_flags)
+{
+ return XFS_ATTR_NSP_ONDISK(ondisk_flags) == XFS_ATTR_NSP_ARGS_TO_ONDISK(arg_flags);
+}
+
+/*
+ * If namespace bits don't match and we don't have an override for it
+ * then return 0.
+ * If all match or are overridable then return 1.
+ */
+STATIC inline int
+xfs_attr_namesp_match_overrides(int arg_flags, int ondisk_flags)
+{
+ if (((arg_flags & ATTR_SECURE) == 0) !=
+ ((ondisk_flags & XFS_ATTR_SECURE) == 0) &&
+ !(arg_flags & ATTR_KERNORMALS))
+ return 0;
+ if (((arg_flags & ATTR_ROOT) == 0) !=
+ ((ondisk_flags & XFS_ATTR_ROOT) == 0) &&
+ !(arg_flags & ATTR_KERNROOTLS))
+ return 0;
+ return 1;
+}
/*========================================================================
@@ -228,11 +265,7 @@ xfs_attr_shortform_add(xfs_da_args_t *args, int forkoff)
continue;
if (memcmp(args->name, sfe->nameval, args->namelen) != 0)
continue;
- if (((args->flags & ATTR_SECURE) != 0) !=
- ((sfe->flags & XFS_ATTR_SECURE) != 0))
- continue;
- if (((args->flags & ATTR_ROOT) != 0) !=
- ((sfe->flags & XFS_ATTR_ROOT) != 0))
+ if (!xfs_attr_namesp_match(args->flags, sfe->flags))
continue;
ASSERT(0);
#endif
@@ -246,8 +279,7 @@ xfs_attr_shortform_add(xfs_da_args_t *args, int forkoff)
sfe->namelen = args->namelen;
sfe->valuelen = args->valuelen;
- sfe->flags = (args->flags & ATTR_SECURE) ? XFS_ATTR_SECURE :
- ((args->flags & ATTR_ROOT) ? XFS_ATTR_ROOT : 0);
+ sfe->flags = XFS_ATTR_NSP_ARGS_TO_ONDISK(args->flags);
memcpy(sfe->nameval, args->name, args->namelen);
memcpy(&sfe->nameval[args->namelen], args->value, args->valuelen);
sf->hdr.count++;
@@ -282,11 +314,7 @@ xfs_attr_shortform_remove(xfs_da_args_t *args)
continue;
if (memcmp(sfe->nameval, args->name, args->namelen) != 0)
continue;
- if (((args->flags & ATTR_SECURE) != 0) !=
- ((sfe->flags & XFS_ATTR_SECURE) != 0))
- continue;
- if (((args->flags & ATTR_ROOT) != 0) !=
- ((sfe->flags & XFS_ATTR_ROOT) != 0))
+ if (!xfs_attr_namesp_match(args->flags, sfe->flags))
continue;
break;
}
@@ -363,11 +391,7 @@ xfs_attr_shortform_lookup(xfs_da_args_t *args)
continue;
if (memcmp(args->name, sfe->nameval, args->namelen) != 0)
continue;
- if (((args->flags & ATTR_SECURE) != 0) !=
- ((sfe->flags & XFS_ATTR_SECURE) != 0))
- continue;
- if (((args->flags & ATTR_ROOT) != 0) !=
- ((sfe->flags & XFS_ATTR_ROOT) != 0))
+ if (!xfs_attr_namesp_match(args->flags, sfe->flags))
continue;
return(XFS_ERROR(EEXIST));
}
@@ -394,11 +418,7 @@ xfs_attr_shortform_getvalue(xfs_da_args_t *args)
continue;
if (memcmp(args->name, sfe->nameval, args->namelen) != 0)
continue;
- if (((args->flags & ATTR_SECURE) != 0) !=
- ((sfe->flags & XFS_ATTR_SECURE) != 0))
- continue;
- if (((args->flags & ATTR_ROOT) != 0) !=
- ((sfe->flags & XFS_ATTR_ROOT) != 0))
+ if (!xfs_attr_namesp_match(args->flags, sfe->flags))
continue;
if (args->flags & ATTR_KERNOVAL) {
args->valuelen = sfe->valuelen;
@@ -485,8 +505,7 @@ xfs_attr_shortform_to_leaf(xfs_da_args_t *args)
nargs.valuelen = sfe->valuelen;
nargs.hashval = xfs_da_hashname((char *)sfe->nameval,
sfe->namelen);
- nargs.flags = (sfe->flags & XFS_ATTR_SECURE) ? ATTR_SECURE :
- ((sfe->flags & XFS_ATTR_ROOT) ? ATTR_ROOT : 0);
+ nargs.flags = XFS_ATTR_NSP_ONDISK_TO_ARGS(sfe->flags);
error = xfs_attr_leaf_lookup_int(bp, &nargs); /* set a->index */
ASSERT(error == ENOATTR);
error = xfs_attr_leaf_add(bp, &nargs);
@@ -520,6 +539,10 @@ xfs_attr_shortform_compare(const void *a, const void *b)
}
}
+
+#define XFS_ISRESET_CURSOR(cursor) \
+ (!((cursor)->initted) && !((cursor)->hashval) && \
+ !((cursor)->blkno) && !((cursor)->offset))
/*
* Copy out entries of shortform attribute lists for attr_list().
* Shortform attribute lists are not stored in hashval sorted order.
@@ -537,6 +560,7 @@ xfs_attr_shortform_list(xfs_attr_list_context_t *context)
xfs_attr_sf_entry_t *sfe;
xfs_inode_t *dp;
int sbsize, nsbuf, count, i;
+ int error;
ASSERT(context != NULL);
dp = context->dp;
@@ -552,46 +576,51 @@ xfs_attr_shortform_list(xfs_attr_list_context_t *context)
xfs_attr_trace_l_c("sf start", context);
/*
- * If the buffer is large enough, do not bother with sorting.
+ * If the buffer is large enough and the cursor is at the start,
+ * do not bother with sorting since we will return everything in
+ * one buffer and another call using the cursor won't need to be
+ * made.
* Note the generous fudge factor of 16 overhead bytes per entry.
+ * If bufsize is zero then put_listent must be a search function
+ * and can just scan through what we have.
*/
- if ((dp->i_afp->if_bytes + sf->hdr.count * 16) < context->bufsize) {
+ if (context->bufsize == 0 ||
+ (XFS_ISRESET_CURSOR(cursor) &&
+ (dp->i_afp->if_bytes + sf->hdr.count * 16) < context->bufsize)) {
for (i = 0, sfe = &sf->list[0]; i < sf->hdr.count; i++) {
attrnames_t *namesp;
- if (((context->flags & ATTR_SECURE) != 0) !=
- ((sfe->flags & XFS_ATTR_SECURE) != 0) &&
- !(context->flags & ATTR_KERNORMALS)) {
- sfe = XFS_ATTR_SF_NEXTENTRY(sfe);
- continue;
- }
- if (((context->flags & ATTR_ROOT) != 0) !=
- ((sfe->flags & XFS_ATTR_ROOT) != 0) &&
- !(context->flags & ATTR_KERNROOTLS)) {
+ if (!xfs_attr_namesp_match_overrides(context->flags, sfe->flags)) {
sfe = XFS_ATTR_SF_NEXTENTRY(sfe);
continue;
}
- namesp = (sfe->flags & XFS_ATTR_SECURE) ? &attr_secure:
- ((sfe->flags & XFS_ATTR_ROOT) ? &attr_trusted :
- &attr_user);
- if (context->flags & ATTR_KERNOVAL) {
- ASSERT(context->flags & ATTR_KERNAMELS);
- context->count += namesp->attr_namelen +
- sfe->namelen + 1;
- }
- else {
- if (xfs_attr_put_listent(context, namesp,
- (char *)sfe->nameval,
- (int)sfe->namelen,
- (int)sfe->valuelen))
- break;
- }
+ namesp = xfs_attr_flags_namesp(sfe->flags);
+ error = context->put_listent(context,
+ namesp,
+ (char *)sfe->nameval,
+ (int)sfe->namelen,
+ (int)sfe->valuelen,
+ (char*)&sfe->nameval[sfe->namelen]);
+
+ /*
+ * Either search callback finished early or
+ * didn't fit it all in the buffer after all.
+ */
+ if (context->seen_enough)
+ break;
+
+ if (error)
+ return error;
sfe = XFS_ATTR_SF_NEXTENTRY(sfe);
}
xfs_attr_trace_l_c("sf big-gulp", context);
return(0);
}
+ /* do no more for a search callback */
+ if (context->bufsize == 0)
+ return 0;
+
/*
* It didn't all fit, so we have to sort everything on hashval.
*/
@@ -614,15 +643,7 @@ xfs_attr_shortform_list(xfs_attr_list_context_t *context)
kmem_free(sbuf, sbsize);
return XFS_ERROR(EFSCORRUPTED);
}
- if (((context->flags & ATTR_SECURE) != 0) !=
- ((sfe->flags & XFS_ATTR_SECURE) != 0) &&
- !(context->flags & ATTR_KERNORMALS)) {
- sfe = XFS_ATTR_SF_NEXTENTRY(sfe);
- continue;
- }
- if (((context->flags & ATTR_ROOT) != 0) !=
- ((sfe->flags & XFS_ATTR_ROOT) != 0) &&
- !(context->flags & ATTR_KERNROOTLS)) {
+ if (!xfs_attr_namesp_match_overrides(context->flags, sfe->flags)) {
sfe = XFS_ATTR_SF_NEXTENTRY(sfe);
continue;
}
@@ -671,24 +692,22 @@ xfs_attr_shortform_list(xfs_attr_list_context_t *context)
for ( ; i < nsbuf; i++, sbp++) {
attrnames_t *namesp;
- namesp = (sbp->flags & XFS_ATTR_SECURE) ? &attr_secure :
- ((sbp->flags & XFS_ATTR_ROOT) ? &attr_trusted :
- &attr_user);
+ namesp = xfs_attr_flags_namesp(sbp->flags);
if (cursor->hashval != sbp->hash) {
cursor->hashval = sbp->hash;
cursor->offset = 0;
}
- if (context->flags & ATTR_KERNOVAL) {
- ASSERT(context->flags & ATTR_KERNAMELS);
- context->count += namesp->attr_namelen +
- sbp->namelen + 1;
- } else {
- if (xfs_attr_put_listent(context, namesp,
- sbp->name, sbp->namelen,
- sbp->valuelen))
- break;
- }
+ error = context->put_listent(context,
+ namesp,
+ sbp->name,
+ sbp->namelen,
+ sbp->valuelen,
+ &sbp->name[sbp->namelen]);
+ if (error)
+ return error;
+ if (context->seen_enough)
+ break;
cursor->offset++;
}
@@ -810,8 +829,7 @@ xfs_attr_leaf_to_shortform(xfs_dabuf_t *bp, xfs_da_args_t *args, int forkoff)
nargs.value = (char *)&name_loc->nameval[nargs.namelen];
nargs.valuelen = be16_to_cpu(name_loc->valuelen);
nargs.hashval = be32_to_cpu(entry->hashval);
- nargs.flags = (entry->flags & XFS_ATTR_SECURE) ? ATTR_SECURE :
- ((entry->flags & XFS_ATTR_ROOT) ? ATTR_ROOT : 0);
+ nargs.flags = XFS_ATTR_NSP_ONDISK_TO_ARGS(entry->flags);
xfs_attr_shortform_add(&nargs, forkoff);
}
error = 0;
@@ -1098,8 +1116,7 @@ xfs_attr_leaf_add_work(xfs_dabuf_t *bp, xfs_da_args_t *args, int mapindex)
be16_to_cpu(map->size));
entry->hashval = cpu_to_be32(args->hashval);
entry->flags = tmp ? XFS_ATTR_LOCAL : 0;
- entry->flags |= (args->flags & ATTR_SECURE) ? XFS_ATTR_SECURE :
- ((args->flags & ATTR_ROOT) ? XFS_ATTR_ROOT : 0);
+ entry->flags |= XFS_ATTR_NSP_ARGS_TO_ONDISK(args->flags);
if (args->rename) {
entry->flags |= XFS_ATTR_INCOMPLETE;
if ((args->blkno2 == args->blkno) &&
@@ -1926,7 +1943,7 @@ xfs_attr_leaf_lookup_int(xfs_dabuf_t *bp, xfs_da_args_t *args)
else
break;
}
- ASSERT((probe >= 0) &&
+ ASSERT((probe >= 0) &&
(!leaf->hdr.count
|| (probe < be16_to_cpu(leaf->hdr.count))));
ASSERT((span <= 4) || (be32_to_cpu(entry->hashval) == hashval));
@@ -1971,14 +1988,9 @@ xfs_attr_leaf_lookup_int(xfs_dabuf_t *bp, xfs_da_args_t *args)
name_loc = XFS_ATTR_LEAF_NAME_LOCAL(leaf, probe);
if (name_loc->namelen != args->namelen)
continue;
- if (memcmp(args->name, (char *)name_loc->nameval,
- args->namelen) != 0)
+ if (memcmp(args->name, (char *)name_loc->nameval, args->namelen) != 0)
continue;
- if (((args->flags & ATTR_SECURE) != 0) !=
- ((entry->flags & XFS_ATTR_SECURE) != 0))
- continue;
- if (((args->flags & ATTR_ROOT) != 0) !=
- ((entry->flags & XFS_ATTR_ROOT) != 0))
+ if (!xfs_attr_namesp_match(args->flags, entry->flags))
continue;
args->index = probe;
return(XFS_ERROR(EEXIST));
@@ -1989,11 +2001,7 @@ xfs_attr_leaf_lookup_int(xfs_dabuf_t *bp, xfs_da_args_t *args)
if (memcmp(args->name, (char *)name_rmt->name,
args->namelen) != 0)
continue;
- if (((args->flags & ATTR_SECURE) != 0) !=
- ((entry->flags & XFS_ATTR_SECURE) != 0))
- continue;
- if (((args->flags & ATTR_ROOT) != 0) !=
- ((entry->flags & XFS_ATTR_ROOT) != 0))
+ if (!xfs_attr_namesp_match(args->flags, entry->flags))
continue;
args->index = probe;
args->rmtblkno = be32_to_cpu(name_rmt->valueblk);
@@ -2312,8 +2320,6 @@ xfs_attr_leaf_list_int(xfs_dabuf_t *bp, xfs_attr_list_context_t *context)
attrlist_cursor_kern_t *cursor;
xfs_attr_leafblock_t *leaf;
xfs_attr_leaf_entry_t *entry;
- xfs_attr_leaf_name_local_t *name_loc;
- xfs_attr_leaf_name_remote_t *name_rmt;
int retval, i;
ASSERT(bp != NULL);
@@ -2355,9 +2361,8 @@ xfs_attr_leaf_list_int(xfs_dabuf_t *bp, xfs_attr_list_context_t *context)
* We have found our place, start copying out the new attributes.
*/
retval = 0;
- for ( ; (i < be16_to_cpu(leaf->hdr.count))
- && (retval == 0); entry++, i++) {
- attrnames_t *namesp;
+ for ( ; (i < be16_to_cpu(leaf->hdr.count)); entry++, i++) {
+ attrnames_t *namesp;
if (be32_to_cpu(entry->hashval) != cursor->hashval) {
cursor->hashval = be32_to_cpu(entry->hashval);
@@ -2366,115 +2371,69 @@ xfs_attr_leaf_list_int(xfs_dabuf_t *bp, xfs_attr_list_context_t *context)
if (entry->flags & XFS_ATTR_INCOMPLETE)
continue; /* skip incomplete entries */
- if (((context->flags & ATTR_SECURE) != 0) !=
- ((entry->flags & XFS_ATTR_SECURE) != 0) &&
- !(context->flags & ATTR_KERNORMALS))
- continue; /* skip non-matching entries */
- if (((context->flags & ATTR_ROOT) != 0) !=
- ((entry->flags & XFS_ATTR_ROOT) != 0) &&
- !(context->flags & ATTR_KERNROOTLS))
- continue; /* skip non-matching entries */
-
- namesp = (entry->flags & XFS_ATTR_SECURE) ? &attr_secure :
- ((entry->flags & XFS_ATTR_ROOT) ? &attr_trusted :
- &attr_user);
+ if (!xfs_attr_namesp_match_overrides(context->flags, entry->flags))
+ continue;
+
+ namesp = xfs_attr_flags_namesp(entry->flags);
if (entry->flags & XFS_ATTR_LOCAL) {
- name_loc = XFS_ATTR_LEAF_NAME_LOCAL(leaf, i);
- if (context->flags & ATTR_KERNOVAL) {
- ASSERT(context->flags & ATTR_KERNAMELS);
- context->count += namesp->attr_namelen +
- (int)name_loc->namelen + 1;
- } else {
- retval = xfs_attr_put_listent(context, namesp,
- (char *)name_loc->nameval,
- (int)name_loc->namelen,
- be16_to_cpu(name_loc->valuelen));
- }
+ xfs_attr_leaf_name_local_t *name_loc =
+ XFS_ATTR_LEAF_NAME_LOCAL(leaf, i);
+
+ retval = context->put_listent(context,
+ namesp,
+ (char *)name_loc->nameval,
+ (int)name_loc->namelen,
+ be16_to_cpu(name_loc->valuelen),
+ (char *)&name_loc->nameval[name_loc->namelen]);
+ if (retval)
+ return retval;
} else {
- name_rmt = XFS_ATTR_LEAF_NAME_REMOTE(leaf, i);
- if (context->flags & ATTR_KERNOVAL) {
- ASSERT(context->flags & ATTR_KERNAMELS);
- context->count += namesp->attr_namelen +
- (int)name_rmt->namelen + 1;
- } else {
- retval = xfs_attr_put_listent(context, namesp,
- (char *)name_rmt->name,
- (int)name_rmt->namelen,
- be32_to_cpu(name_rmt->valuelen));
+ xfs_attr_leaf_name_remote_t *name_rmt =
+ XFS_ATTR_LEAF_NAME_REMOTE(leaf, i);
+
+ int valuelen = be32_to_cpu(name_rmt->valuelen);
+
+ if (context->put_value) {
+ xfs_da_args_t args;
+
+ memset((char *)&args, 0, sizeof(args));
+ args.dp = context->dp;
+ args.whichfork = XFS_ATTR_FORK;
+ args.valuelen = valuelen;
+ args.value = kmem_alloc(valuelen, KM_SLEEP);
+ args.rmtblkno = be32_to_cpu(name_rmt->valueblk);
+ args.rmtblkcnt = XFS_B_TO_FSB(args.dp->i_mount, valuelen);
+ retval = xfs_attr_rmtval_get(&args);
+ if (retval)
+ return retval;
+ retval = context->put_listent(context,
+ namesp,
+ (char *)name_rmt->name,
+ (int)name_rmt->namelen,
+ valuelen,
+ (char*)args.value);
+ kmem_free(args.value, valuelen);
}
+ else {
+ retval = context->put_listent(context,
+ namesp,
+ (char *)name_rmt->name,
+ (int)name_rmt->namelen,
+ valuelen,
+ NULL);
+ }
+ if (retval)
+ return retval;
}
- if (retval == 0) {
- cursor->offset++;
- }
+ if (context->seen_enough)
+ break;
+ cursor->offset++;
}
xfs_attr_trace_l_cl("blk end", context, leaf);
return(retval);
}
-#define ATTR_ENTBASESIZE /* minimum bytes used by an attr */ \
- (((struct attrlist_ent *) 0)->a_name - (char *) 0)
-#define ATTR_ENTSIZE(namelen) /* actual bytes used by an attr */ \
- ((ATTR_ENTBASESIZE + (namelen) + 1 + sizeof(u_int32_t)-1) \
- & ~(sizeof(u_int32_t)-1))
-
-/*
- * Format an attribute and copy it out to the user's buffer.
- * Take care to check values and protect against them changing later,
- * we may be reading them directly out of a user buffer.
- */
-/*ARGSUSED*/
-STATIC int
-xfs_attr_put_listent(xfs_attr_list_context_t *context,
- attrnames_t *namesp, char *name, int namelen, int valuelen)
-{
- attrlist_ent_t *aep;
- int arraytop;
-
- ASSERT(!(context->flags & ATTR_KERNOVAL));
- if (context->flags & ATTR_KERNAMELS) {
- char *offset;
-
- ASSERT(context->count >= 0);
-
- arraytop = context->count + namesp->attr_namelen + namelen + 1;
- if (arraytop > context->firstu) {
- context->count = -1; /* insufficient space */
- return(1);
- }
- offset = (char *)context->alist + context->count;
- strncpy(offset, namesp->attr_name, namesp->attr_namelen);
- offset += namesp->attr_namelen;
- strncpy(offset, name, namelen); /* real name */
- offset += namelen;
- *offset = '\0';
- context->count += namesp->attr_namelen + namelen + 1;
- return(0);
- }
-
- ASSERT(context->count >= 0);
- ASSERT(context->count < (ATTR_MAX_VALUELEN/8));
- ASSERT(context->firstu >= sizeof(*context->alist));
- ASSERT(context->firstu <= context->bufsize);
-
- arraytop = sizeof(*context->alist) +
- context->count * sizeof(context->alist->al_offset[0]);
- context->firstu -= ATTR_ENTSIZE(namelen);
- if (context->firstu < arraytop) {
- xfs_attr_trace_l_c("buffer full", context);
- context->alist->al_more = 1;
- return(1);
- }
-
- aep = (attrlist_ent_t *)&(((char *)context->alist)[ context->firstu ]);
- aep->a_valuelen = valuelen;
- memcpy(aep->a_name, name, namelen);
- aep->a_name[ namelen ] = 0;
- context->alist->al_offset[ context->count++ ] = context->firstu;
- context->alist->al_count = context->count;
- xfs_attr_trace_l_c("add", context);
- return(0);
-}
/*========================================================================
* Manage the INCOMPLETE flag in a leaf entry
diff --git a/fs/xfs/xfs_attr_leaf.h b/fs/xfs/xfs_attr_leaf.h
index 51c3ee156b2f..040f732ce1e2 100644
--- a/fs/xfs/xfs_attr_leaf.h
+++ b/fs/xfs/xfs_attr_leaf.h
@@ -130,6 +130,19 @@ typedef struct xfs_attr_leafblock {
#define XFS_ATTR_INCOMPLETE (1 << XFS_ATTR_INCOMPLETE_BIT)
/*
+ * Conversion macros for converting namespace bits from argument flags
+ * to ondisk flags.
+ */
+#define XFS_ATTR_NSP_ARGS_MASK (ATTR_ROOT | ATTR_SECURE)
+#define XFS_ATTR_NSP_ONDISK_MASK (XFS_ATTR_ROOT | XFS_ATTR_SECURE)
+#define XFS_ATTR_NSP_ONDISK(flags) ((flags) & XFS_ATTR_NSP_ONDISK_MASK)
+#define XFS_ATTR_NSP_ARGS(flags) ((flags) & XFS_ATTR_NSP_ARGS_MASK)
+#define XFS_ATTR_NSP_ARGS_TO_ONDISK(x) (((x) & ATTR_ROOT ? XFS_ATTR_ROOT : 0) |\
+ ((x) & ATTR_SECURE ? XFS_ATTR_SECURE : 0))
+#define XFS_ATTR_NSP_ONDISK_TO_ARGS(x) (((x) & XFS_ATTR_ROOT ? ATTR_ROOT : 0) |\
+ ((x) & XFS_ATTR_SECURE ? ATTR_SECURE : 0))
+
+/*
* Alignment for namelist and valuelist entries (since they are mixed
* there can be only one alignment value)
*/
@@ -196,16 +209,26 @@ static inline int xfs_attr_leaf_entsize_local_max(int bsize)
* Structure used to pass context around among the routines.
*========================================================================*/
+
+struct xfs_attr_list_context;
+
+typedef int (*put_listent_func_t)(struct xfs_attr_list_context *, struct attrnames *,
+ char *, int, int, char *);
+
typedef struct xfs_attr_list_context {
- struct xfs_inode *dp; /* inode */
- struct attrlist_cursor_kern *cursor;/* position in list */
- struct attrlist *alist; /* output buffer */
- int count; /* num used entries */
- int dupcnt; /* count dup hashvals seen */
- int bufsize;/* total buffer size */
- int firstu; /* first used byte in buffer */
- int flags; /* from VOP call */
- int resynch;/* T/F: resynch with cursor */
+ struct xfs_inode *dp; /* inode */
+ struct attrlist_cursor_kern *cursor; /* position in list */
+ struct attrlist *alist; /* output buffer */
+ int seen_enough; /* T/F: seen enough of list? */
+ int count; /* num used entries */
+ int dupcnt; /* count dup hashvals seen */
+ int bufsize; /* total buffer size */
+ int firstu; /* first used byte in buffer */
+ int flags; /* from VOP call */
+ int resynch; /* T/F: resynch with cursor */
+ int put_value; /* T/F: need value for listent */
+ put_listent_func_t put_listent; /* list output fmt function */
+ int index; /* index into output buffer */
} xfs_attr_list_context_t;
/*
diff --git a/fs/xfs/xfs_behavior.c b/fs/xfs/xfs_behavior.c
index f4fe3715a803..0dc17219d412 100644
--- a/fs/xfs/xfs_behavior.c
+++ b/fs/xfs/xfs_behavior.c
@@ -110,26 +110,6 @@ bhv_remove_not_first(bhv_head_t *bhp, bhv_desc_t *bdp)
}
/*
- * Look for a specific ops vector on the specified behavior chain.
- * Return the associated behavior descriptor. Or NULL, if not found.
- */
-bhv_desc_t *
-bhv_lookup(bhv_head_t *bhp, void *ops)
-{
- bhv_desc_t *curdesc;
-
- for (curdesc = bhp->bh_first;
- curdesc != NULL;
- curdesc = curdesc->bd_next) {
-
- if (curdesc->bd_ops == ops)
- return curdesc;
- }
-
- return NULL;
-}
-
-/*
* Looks for the first behavior within a specified range of positions.
* Return the associated behavior descriptor. Or NULL, if none found.
*/
diff --git a/fs/xfs/xfs_behavior.h b/fs/xfs/xfs_behavior.h
index 6e6e56fb352d..e7ca1fed955a 100644
--- a/fs/xfs/xfs_behavior.h
+++ b/fs/xfs/xfs_behavior.h
@@ -176,12 +176,10 @@ extern void bhv_insert_initial(bhv_head_t *, bhv_desc_t *);
* Behavior module prototypes.
*/
extern void bhv_remove_not_first(bhv_head_t *bhp, bhv_desc_t *bdp);
-extern bhv_desc_t * bhv_lookup(bhv_head_t *bhp, void *ops);
extern bhv_desc_t * bhv_lookup_range(bhv_head_t *bhp, int low, int high);
extern bhv_desc_t * bhv_base(bhv_head_t *bhp);
/* No bhv locking on Linux */
-#define bhv_lookup_unlocked bhv_lookup
#define bhv_base_unlocked bhv_base
#endif /* __XFS_BEHAVIOR_H__ */
diff --git a/fs/xfs/xfs_bmap.c b/fs/xfs/xfs_bmap.c
index bf46fae303af..5b050c06795f 100644
--- a/fs/xfs/xfs_bmap.c
+++ b/fs/xfs/xfs_bmap.c
@@ -2999,7 +2999,7 @@ xfs_bmap_btree_to_extents(
int error; /* error return value */
xfs_ifork_t *ifp; /* inode fork data */
xfs_mount_t *mp; /* mount point structure */
- xfs_bmbt_ptr_t *pp; /* ptr to block address */
+ __be64 *pp; /* ptr to block address */
xfs_bmbt_block_t *rblock;/* root btree block */
ifp = XFS_IFORK_PTR(ip, whichfork);
@@ -3011,12 +3011,12 @@ xfs_bmap_btree_to_extents(
ASSERT(XFS_BMAP_BROOT_MAXRECS(ifp->if_broot_bytes) == 1);
mp = ip->i_mount;
pp = XFS_BMAP_BROOT_PTR_ADDR(rblock, 1, ifp->if_broot_bytes);
+ cbno = be64_to_cpu(*pp);
*logflagsp = 0;
#ifdef DEBUG
- if ((error = xfs_btree_check_lptr(cur, INT_GET(*pp, ARCH_CONVERT), 1)))
+ if ((error = xfs_btree_check_lptr(cur, cbno, 1)))
return error;
#endif
- cbno = INT_GET(*pp, ARCH_CONVERT);
if ((error = xfs_btree_read_bufl(mp, tp, cbno, 0, &cbp,
XFS_BMAP_BTREE_REF)))
return error;
@@ -3512,9 +3512,9 @@ xfs_bmap_extents_to_btree(
*/
kp = XFS_BMAP_KEY_IADDR(block, 1, cur);
arp = XFS_BMAP_REC_IADDR(ablock, 1, cur);
- INT_SET(kp->br_startoff, ARCH_CONVERT, xfs_bmbt_disk_get_startoff(arp));
+ kp->br_startoff = cpu_to_be64(xfs_bmbt_disk_get_startoff(arp));
pp = XFS_BMAP_PTR_IADDR(block, 1, cur);
- INT_SET(*pp, ARCH_CONVERT, args.fsbno);
+ *pp = cpu_to_be64(args.fsbno);
/*
* Do all this logging at the end so that
* the root is at the right level.
@@ -3705,7 +3705,7 @@ STATIC xfs_bmbt_rec_t * /* pointer to found extent entry */
xfs_bmap_search_extents(
xfs_inode_t *ip, /* incore inode pointer */
xfs_fileoff_t bno, /* block number searched for */
- int whichfork, /* data or attr fork */
+ int fork, /* data or attr fork */
int *eofp, /* out: end of file found */
xfs_extnum_t *lastxp, /* out: last extent index */
xfs_bmbt_irec_t *gotp, /* out: extent entry found */
@@ -3713,25 +3713,28 @@ xfs_bmap_search_extents(
{
xfs_ifork_t *ifp; /* inode fork pointer */
xfs_bmbt_rec_t *ep; /* extent record pointer */
- int rt; /* realtime flag */
XFS_STATS_INC(xs_look_exlist);
- ifp = XFS_IFORK_PTR(ip, whichfork);
+ ifp = XFS_IFORK_PTR(ip, fork);
ep = xfs_bmap_search_multi_extents(ifp, bno, eofp, lastxp, gotp, prevp);
- rt = (whichfork == XFS_DATA_FORK) && XFS_IS_REALTIME_INODE(ip);
- if (unlikely(!rt && !gotp->br_startblock && (*lastxp != NULLEXTNUM))) {
- cmn_err(CE_PANIC,"Access to block zero: fs: <%s> inode: %lld "
- "start_block : %llx start_off : %llx blkcnt : %llx "
- "extent-state : %x \n",
- (ip->i_mount)->m_fsname, (long long)ip->i_ino,
+ if (unlikely(!(gotp->br_startblock) && (*lastxp != NULLEXTNUM) &&
+ !(XFS_IS_REALTIME_INODE(ip) && fork == XFS_DATA_FORK))) {
+ xfs_cmn_err(XFS_PTAG_FSBLOCK_ZERO, CE_ALERT, ip->i_mount,
+ "Access to block zero in inode %llu "
+ "start_block: %llx start_off: %llx "
+ "blkcnt: %llx extent-state: %x lastx: %x\n",
+ (unsigned long long)ip->i_ino,
(unsigned long long)gotp->br_startblock,
(unsigned long long)gotp->br_startoff,
(unsigned long long)gotp->br_blockcount,
- gotp->br_state);
- }
- return ep;
+ gotp->br_state, *lastxp);
+ *lastxp = NULLEXTNUM;
+ *eofp = 1;
+ return NULL;
+ }
+ return ep;
}
@@ -4494,7 +4497,7 @@ xfs_bmap_read_extents(
xfs_ifork_t *ifp; /* fork structure */
int level; /* btree level, for checking */
xfs_mount_t *mp; /* file system mount structure */
- xfs_bmbt_ptr_t *pp; /* pointer to block address */
+ __be64 *pp; /* pointer to block address */
/* REFERENCED */
xfs_extnum_t room; /* number of entries there's room for */
@@ -4510,10 +4513,10 @@ xfs_bmap_read_extents(
level = be16_to_cpu(block->bb_level);
ASSERT(level > 0);
pp = XFS_BMAP_BROOT_PTR_ADDR(block, 1, ifp->if_broot_bytes);
- ASSERT(INT_GET(*pp, ARCH_CONVERT) != NULLDFSBNO);
- ASSERT(XFS_FSB_TO_AGNO(mp, INT_GET(*pp, ARCH_CONVERT)) < mp->m_sb.sb_agcount);
- ASSERT(XFS_FSB_TO_AGBNO(mp, INT_GET(*pp, ARCH_CONVERT)) < mp->m_sb.sb_agblocks);
- bno = INT_GET(*pp, ARCH_CONVERT);
+ bno = be64_to_cpu(*pp);
+ ASSERT(bno != NULLDFSBNO);
+ ASSERT(XFS_FSB_TO_AGNO(mp, bno) < mp->m_sb.sb_agcount);
+ ASSERT(XFS_FSB_TO_AGBNO(mp, bno) < mp->m_sb.sb_agblocks);
/*
* Go down the tree until leaf level is reached, following the first
* pointer (leftmost) at each level.
@@ -4530,10 +4533,8 @@ xfs_bmap_read_extents(
break;
pp = XFS_BTREE_PTR_ADDR(mp->m_sb.sb_blocksize, xfs_bmbt, block,
1, mp->m_bmap_dmxr[1]);
- XFS_WANT_CORRUPTED_GOTO(
- XFS_FSB_SANITY_CHECK(mp, INT_GET(*pp, ARCH_CONVERT)),
- error0);
- bno = INT_GET(*pp, ARCH_CONVERT);
+ bno = be64_to_cpu(*pp);
+ XFS_WANT_CORRUPTED_GOTO(XFS_FSB_SANITY_CHECK(mp, bno), error0);
xfs_trans_brelse(tp, bp);
}
/*
@@ -6141,7 +6142,7 @@ xfs_check_block(
short sz)
{
int i, j, dmxr;
- xfs_bmbt_ptr_t *pp, *thispa; /* pointer to block address */
+ __be64 *pp, *thispa; /* pointer to block address */
xfs_bmbt_key_t *prevp, *keyp;
ASSERT(be16_to_cpu(block->bb_level) > 0);
@@ -6179,11 +6180,10 @@ xfs_check_block(
thispa = XFS_BTREE_PTR_ADDR(mp->m_sb.sb_blocksize,
xfs_bmbt, block, j, dmxr);
}
- if (INT_GET(*thispa, ARCH_CONVERT) ==
- INT_GET(*pp, ARCH_CONVERT)) {
+ if (*thispa == *pp) {
cmn_err(CE_WARN, "%s: thispa(%d) == pp(%d) %Ld",
__FUNCTION__, j, i,
- INT_GET(*thispa, ARCH_CONVERT));
+ (unsigned long long)be64_to_cpu(*thispa));
panic("%s: ptrs are equal in node\n",
__FUNCTION__);
}
@@ -6210,7 +6210,7 @@ xfs_bmap_check_leaf_extents(
xfs_ifork_t *ifp; /* fork structure */
int level; /* btree level, for checking */
xfs_mount_t *mp; /* file system mount structure */
- xfs_bmbt_ptr_t *pp; /* pointer to block address */
+ __be64 *pp; /* pointer to block address */
xfs_bmbt_rec_t *ep; /* pointer to current extent */
xfs_bmbt_rec_t *lastp; /* pointer to previous extent */
xfs_bmbt_rec_t *nextp; /* pointer to next extent */
@@ -6231,10 +6231,12 @@ xfs_bmap_check_leaf_extents(
ASSERT(level > 0);
xfs_check_block(block, mp, 1, ifp->if_broot_bytes);
pp = XFS_BMAP_BROOT_PTR_ADDR(block, 1, ifp->if_broot_bytes);
- ASSERT(INT_GET(*pp, ARCH_CONVERT) != NULLDFSBNO);
- ASSERT(XFS_FSB_TO_AGNO(mp, INT_GET(*pp, ARCH_CONVERT)) < mp->m_sb.sb_agcount);
- ASSERT(XFS_FSB_TO_AGBNO(mp, INT_GET(*pp, ARCH_CONVERT)) < mp->m_sb.sb_agblocks);
- bno = INT_GET(*pp, ARCH_CONVERT);
+ bno = be64_to_cpu(*pp);
+
+ ASSERT(bno != NULLDFSBNO);
+ ASSERT(XFS_FSB_TO_AGNO(mp, bno) < mp->m_sb.sb_agcount);
+ ASSERT(XFS_FSB_TO_AGBNO(mp, bno) < mp->m_sb.sb_agblocks);
+
/*
* Go down the tree until leaf level is reached, following the first
* pointer (leftmost) at each level.
@@ -6265,8 +6267,8 @@ xfs_bmap_check_leaf_extents(
xfs_check_block(block, mp, 0, 0);
pp = XFS_BTREE_PTR_ADDR(mp->m_sb.sb_blocksize, xfs_bmbt, block,
1, mp->m_bmap_dmxr[1]);
- XFS_WANT_CORRUPTED_GOTO(XFS_FSB_SANITY_CHECK(mp, INT_GET(*pp, ARCH_CONVERT)), error0);
- bno = INT_GET(*pp, ARCH_CONVERT);
+ bno = be64_to_cpu(*pp);
+ XFS_WANT_CORRUPTED_GOTO(XFS_FSB_SANITY_CHECK(mp, bno), error0);
if (bp_release) {
bp_release = 0;
xfs_trans_brelse(NULL, bp);
@@ -6372,7 +6374,7 @@ xfs_bmap_count_blocks(
xfs_ifork_t *ifp; /* fork structure */
int level; /* btree level, for checking */
xfs_mount_t *mp; /* file system mount structure */
- xfs_bmbt_ptr_t *pp; /* pointer to block address */
+ __be64 *pp; /* pointer to block address */
bno = NULLFSBLOCK;
mp = ip->i_mount;
@@ -6395,10 +6397,10 @@ xfs_bmap_count_blocks(
level = be16_to_cpu(block->bb_level);
ASSERT(level > 0);
pp = XFS_BMAP_BROOT_PTR_ADDR(block, 1, ifp->if_broot_bytes);
- ASSERT(INT_GET(*pp, ARCH_CONVERT) != NULLDFSBNO);
- ASSERT(XFS_FSB_TO_AGNO(mp, INT_GET(*pp, ARCH_CONVERT)) < mp->m_sb.sb_agcount);
- ASSERT(XFS_FSB_TO_AGBNO(mp, INT_GET(*pp, ARCH_CONVERT)) < mp->m_sb.sb_agblocks);
- bno = INT_GET(*pp, ARCH_CONVERT);
+ bno = be64_to_cpu(*pp);
+ ASSERT(bno != NULLDFSBNO);
+ ASSERT(XFS_FSB_TO_AGNO(mp, bno) < mp->m_sb.sb_agcount);
+ ASSERT(XFS_FSB_TO_AGBNO(mp, bno) < mp->m_sb.sb_agblocks);
if (unlikely(xfs_bmap_count_tree(mp, tp, ifp, bno, level, count) < 0)) {
XFS_ERROR_REPORT("xfs_bmap_count_blocks(2)", XFS_ERRLEVEL_LOW,
@@ -6425,7 +6427,7 @@ xfs_bmap_count_tree(
int error;
xfs_buf_t *bp, *nbp;
int level = levelin;
- xfs_bmbt_ptr_t *pp;
+ __be64 *pp;
xfs_fsblock_t bno = blockno;
xfs_fsblock_t nextbno;
xfs_bmbt_block_t *block, *nextblock;
@@ -6452,7 +6454,7 @@ xfs_bmap_count_tree(
/* Dive to the next level */
pp = XFS_BTREE_PTR_ADDR(mp->m_sb.sb_blocksize,
xfs_bmbt, block, 1, mp->m_bmap_dmxr[1]);
- bno = INT_GET(*pp, ARCH_CONVERT);
+ bno = be64_to_cpu(*pp);
if (unlikely((error =
xfs_bmap_count_tree(mp, tp, ifp, bno, level, count)) < 0)) {
xfs_trans_brelse(tp, bp);
diff --git a/fs/xfs/xfs_bmap_btree.c b/fs/xfs/xfs_bmap_btree.c
index 18fb7385d719..a7b835bf870a 100644
--- a/fs/xfs/xfs_bmap_btree.c
+++ b/fs/xfs/xfs_bmap_btree.c
@@ -58,7 +58,7 @@ STATIC void xfs_bmbt_log_ptrs(xfs_btree_cur_t *, xfs_buf_t *, int, int);
STATIC int xfs_bmbt_lshift(xfs_btree_cur_t *, int, int *);
STATIC int xfs_bmbt_rshift(xfs_btree_cur_t *, int, int *);
STATIC int xfs_bmbt_split(xfs_btree_cur_t *, int, xfs_fsblock_t *,
- xfs_bmbt_key_t *, xfs_btree_cur_t **, int *);
+ __uint64_t *, xfs_btree_cur_t **, int *);
STATIC int xfs_bmbt_updkey(xfs_btree_cur_t *, xfs_bmbt_key_t *, int);
@@ -192,16 +192,11 @@ xfs_bmbt_trace_argifk(
xfs_btree_cur_t *cur,
int i,
xfs_fsblock_t f,
- xfs_bmbt_key_t *k,
+ xfs_dfiloff_t o,
int line)
{
- xfs_dfsbno_t d;
- xfs_dfiloff_t o;
-
- d = (xfs_dfsbno_t)f;
- o = INT_GET(k->br_startoff, ARCH_CONVERT);
xfs_bmbt_trace_enter(func, cur, ARGS, XFS_BMBT_KTRACE_ARGIFK, line,
- i, d >> 32, (int)d, o >> 32,
+ i, (xfs_dfsbno_t)f >> 32, (int)f, o >> 32,
(int)o, 0, 0, 0,
0, 0, 0);
}
@@ -248,7 +243,7 @@ xfs_bmbt_trace_argik(
{
xfs_dfiloff_t o;
- o = INT_GET(k->br_startoff, ARCH_CONVERT);
+ o = be64_to_cpu(k->br_startoff);
xfs_bmbt_trace_enter(func, cur, ARGS, XFS_BMBT_KTRACE_ARGIFK, line,
i, o >> 32, (int)o, 0,
0, 0, 0, 0,
@@ -286,8 +281,8 @@ xfs_bmbt_trace_cursor(
xfs_bmbt_trace_argfffi(fname, c, o, b, i, j, __LINE__)
#define XFS_BMBT_TRACE_ARGI(c,i) \
xfs_bmbt_trace_argi(fname, c, i, __LINE__)
-#define XFS_BMBT_TRACE_ARGIFK(c,i,f,k) \
- xfs_bmbt_trace_argifk(fname, c, i, f, k, __LINE__)
+#define XFS_BMBT_TRACE_ARGIFK(c,i,f,s) \
+ xfs_bmbt_trace_argifk(fname, c, i, f, s, __LINE__)
#define XFS_BMBT_TRACE_ARGIFR(c,i,f,r) \
xfs_bmbt_trace_argifr(fname, c, i, f, r, __LINE__)
#define XFS_BMBT_TRACE_ARGIK(c,i,k) \
@@ -299,7 +294,7 @@ xfs_bmbt_trace_cursor(
#define XFS_BMBT_TRACE_ARGBII(c,b,i,j)
#define XFS_BMBT_TRACE_ARGFFFI(c,o,b,i,j)
#define XFS_BMBT_TRACE_ARGI(c,i)
-#define XFS_BMBT_TRACE_ARGIFK(c,i,f,k)
+#define XFS_BMBT_TRACE_ARGIFK(c,i,f,s)
#define XFS_BMBT_TRACE_ARGIFR(c,i,f,r)
#define XFS_BMBT_TRACE_ARGIK(c,i,k)
#define XFS_BMBT_TRACE_CURSOR(c,s)
@@ -357,7 +352,7 @@ xfs_bmbt_delrec(
XFS_BMBT_TRACE_CURSOR(cur, ENTRY);
XFS_BMBT_TRACE_ARGI(cur, level);
ptr = cur->bc_ptrs[level];
- tcur = (xfs_btree_cur_t *)0;
+ tcur = NULL;
if (ptr == 0) {
XFS_BMBT_TRACE_CURSOR(cur, EXIT);
*stat = 0;
@@ -382,7 +377,7 @@ xfs_bmbt_delrec(
pp = XFS_BMAP_PTR_IADDR(block, 1, cur);
#ifdef DEBUG
for (i = ptr; i < numrecs; i++) {
- if ((error = xfs_btree_check_lptr(cur, INT_GET(pp[i], ARCH_CONVERT), level))) {
+ if ((error = xfs_btree_check_lptr_disk(cur, pp[i], level))) {
XFS_BMBT_TRACE_CURSOR(cur, ERROR);
goto error0;
}
@@ -404,7 +399,8 @@ xfs_bmbt_delrec(
xfs_bmbt_log_recs(cur, bp, ptr, numrecs - 1);
}
if (ptr == 1) {
- INT_SET(key.br_startoff, ARCH_CONVERT, xfs_bmbt_disk_get_startoff(rp));
+ key.br_startoff =
+ cpu_to_be64(xfs_bmbt_disk_get_startoff(rp));
kp = &key;
}
}
@@ -621,7 +617,7 @@ xfs_bmbt_delrec(
rpp = XFS_BMAP_PTR_IADDR(right, 1, cur);
#ifdef DEBUG
for (i = 0; i < numrrecs; i++) {
- if ((error = xfs_btree_check_lptr(cur, INT_GET(rpp[i], ARCH_CONVERT), level))) {
+ if ((error = xfs_btree_check_lptr_disk(cur, rpp[i], level))) {
XFS_BMBT_TRACE_CURSOR(cur, ERROR);
goto error0;
}
@@ -748,7 +744,7 @@ xfs_bmbt_insrec(
int logflags; /* inode logging flags */
xfs_fsblock_t nbno; /* new block number */
struct xfs_btree_cur *ncur; /* new btree cursor */
- xfs_bmbt_key_t nkey; /* new btree key value */
+ __uint64_t startoff; /* new btree key value */
xfs_bmbt_rec_t nrec; /* new record count */
int optr; /* old key/record index */
xfs_bmbt_ptr_t *pp; /* pointer to bmap block addr */
@@ -759,9 +755,8 @@ xfs_bmbt_insrec(
ASSERT(level < cur->bc_nlevels);
XFS_BMBT_TRACE_CURSOR(cur, ENTRY);
XFS_BMBT_TRACE_ARGIFR(cur, level, *bnop, recp);
- ncur = (xfs_btree_cur_t *)0;
- INT_SET(key.br_startoff, ARCH_CONVERT,
- xfs_bmbt_disk_get_startoff(recp));
+ ncur = NULL;
+ key.br_startoff = cpu_to_be64(xfs_bmbt_disk_get_startoff(recp));
optr = ptr = cur->bc_ptrs[level];
if (ptr == 0) {
XFS_BMBT_TRACE_CURSOR(cur, EXIT);
@@ -820,7 +815,7 @@ xfs_bmbt_insrec(
optr = ptr = cur->bc_ptrs[level];
} else {
if ((error = xfs_bmbt_split(cur, level,
- &nbno, &nkey, &ncur,
+ &nbno, &startoff, &ncur,
&i))) {
XFS_BMBT_TRACE_CURSOR(cur,
ERROR);
@@ -840,7 +835,7 @@ xfs_bmbt_insrec(
#endif
ptr = cur->bc_ptrs[level];
xfs_bmbt_disk_set_allf(&nrec,
- nkey.br_startoff, 0, 0,
+ startoff, 0, 0,
XFS_EXT_NORM);
} else {
XFS_BMBT_TRACE_CURSOR(cur,
@@ -858,7 +853,7 @@ xfs_bmbt_insrec(
pp = XFS_BMAP_PTR_IADDR(block, 1, cur);
#ifdef DEBUG
for (i = numrecs; i >= ptr; i--) {
- if ((error = xfs_btree_check_lptr(cur, INT_GET(pp[i - 1], ARCH_CONVERT),
+ if ((error = xfs_btree_check_lptr_disk(cur, pp[i - 1],
level))) {
XFS_BMBT_TRACE_CURSOR(cur, ERROR);
return error;
@@ -870,14 +865,13 @@ xfs_bmbt_insrec(
memmove(&pp[ptr], &pp[ptr - 1], /* INT_: direct copy */
(numrecs - ptr + 1) * sizeof(*pp));
#ifdef DEBUG
- if ((error = xfs_btree_check_lptr(cur, (xfs_bmbt_ptr_t)*bnop,
- level))) {
+ if ((error = xfs_btree_check_lptr(cur, *bnop, level))) {
XFS_BMBT_TRACE_CURSOR(cur, ERROR);
return error;
}
#endif
kp[ptr - 1] = key;
- INT_SET(pp[ptr - 1], ARCH_CONVERT, *bnop);
+ pp[ptr - 1] = cpu_to_be64(*bnop);
numrecs++;
block->bb_numrecs = cpu_to_be16(numrecs);
xfs_bmbt_log_keys(cur, bp, ptr, numrecs);
@@ -988,7 +982,7 @@ xfs_bmbt_killroot(
cpp = XFS_BMAP_PTR_IADDR(cblock, 1, cur);
#ifdef DEBUG
for (i = 0; i < be16_to_cpu(cblock->bb_numrecs); i++) {
- if ((error = xfs_btree_check_lptr(cur, INT_GET(cpp[i], ARCH_CONVERT), level - 1))) {
+ if ((error = xfs_btree_check_lptr_disk(cur, cpp[i], level - 1))) {
XFS_BMBT_TRACE_CURSOR(cur, ERROR);
return error;
}
@@ -1132,7 +1126,7 @@ xfs_bmbt_lookup(
d = XFS_FSB_TO_DADDR(mp, fsbno);
bp = cur->bc_bufs[level];
if (bp && XFS_BUF_ADDR(bp) != d)
- bp = (xfs_buf_t *)0;
+ bp = NULL;
if (!bp) {
if ((error = xfs_btree_read_bufl(mp, tp, fsbno,
0, &bp, XFS_BMAP_BTREE_REF))) {
@@ -1170,7 +1164,7 @@ xfs_bmbt_lookup(
keyno = (low + high) >> 1;
if (level > 0) {
kkp = kkbase + keyno - 1;
- startoff = INT_GET(kkp->br_startoff, ARCH_CONVERT);
+ startoff = be64_to_cpu(kkp->br_startoff);
} else {
krp = krbase + keyno - 1;
startoff = xfs_bmbt_disk_get_startoff(krp);
@@ -1189,13 +1183,13 @@ xfs_bmbt_lookup(
if (diff > 0 && --keyno < 1)
keyno = 1;
pp = XFS_BMAP_PTR_IADDR(block, keyno, cur);
+ fsbno = be64_to_cpu(*pp);
#ifdef DEBUG
- if ((error = xfs_btree_check_lptr(cur, INT_GET(*pp, ARCH_CONVERT), level))) {
+ if ((error = xfs_btree_check_lptr(cur, fsbno, level))) {
XFS_BMBT_TRACE_CURSOR(cur, ERROR);
return error;
}
#endif
- fsbno = INT_GET(*pp, ARCH_CONVERT);
cur->bc_ptrs[level] = keyno;
}
}
@@ -1313,7 +1307,7 @@ xfs_bmbt_lshift(
lpp = XFS_BMAP_PTR_IADDR(left, lrecs, cur);
rpp = XFS_BMAP_PTR_IADDR(right, 1, cur);
#ifdef DEBUG
- if ((error = xfs_btree_check_lptr(cur, INT_GET(*rpp, ARCH_CONVERT), level))) {
+ if ((error = xfs_btree_check_lptr_disk(cur, *rpp, level))) {
XFS_BMBT_TRACE_CURSOR(cur, ERROR);
return error;
}
@@ -1340,7 +1334,7 @@ xfs_bmbt_lshift(
if (level > 0) {
#ifdef DEBUG
for (i = 0; i < rrecs; i++) {
- if ((error = xfs_btree_check_lptr(cur, INT_GET(rpp[i + 1], ARCH_CONVERT),
+ if ((error = xfs_btree_check_lptr_disk(cur, rpp[i + 1],
level))) {
XFS_BMBT_TRACE_CURSOR(cur, ERROR);
return error;
@@ -1354,8 +1348,7 @@ xfs_bmbt_lshift(
} else {
memmove(rrp, rrp + 1, rrecs * sizeof(*rrp));
xfs_bmbt_log_recs(cur, rbp, 1, rrecs);
- INT_SET(key.br_startoff, ARCH_CONVERT,
- xfs_bmbt_disk_get_startoff(rrp));
+ key.br_startoff = cpu_to_be64(xfs_bmbt_disk_get_startoff(rrp));
rkp = &key;
}
if ((error = xfs_bmbt_updkey(cur, rkp, level + 1))) {
@@ -1445,7 +1438,7 @@ xfs_bmbt_rshift(
rpp = XFS_BMAP_PTR_IADDR(right, 1, cur);
#ifdef DEBUG
for (i = be16_to_cpu(right->bb_numrecs) - 1; i >= 0; i--) {
- if ((error = xfs_btree_check_lptr(cur, INT_GET(rpp[i], ARCH_CONVERT), level))) {
+ if ((error = xfs_btree_check_lptr_disk(cur, rpp[i], level))) {
XFS_BMBT_TRACE_CURSOR(cur, ERROR);
return error;
}
@@ -1454,7 +1447,7 @@ xfs_bmbt_rshift(
memmove(rkp + 1, rkp, be16_to_cpu(right->bb_numrecs) * sizeof(*rkp));
memmove(rpp + 1, rpp, be16_to_cpu(right->bb_numrecs) * sizeof(*rpp));
#ifdef DEBUG
- if ((error = xfs_btree_check_lptr(cur, INT_GET(*lpp, ARCH_CONVERT), level))) {
+ if ((error = xfs_btree_check_lptr_disk(cur, *lpp, level))) {
XFS_BMBT_TRACE_CURSOR(cur, ERROR);
return error;
}
@@ -1469,8 +1462,7 @@ xfs_bmbt_rshift(
memmove(rrp + 1, rrp, be16_to_cpu(right->bb_numrecs) * sizeof(*rrp));
*rrp = *lrp;
xfs_bmbt_log_recs(cur, rbp, 1, be16_to_cpu(right->bb_numrecs) + 1);
- INT_SET(key.br_startoff, ARCH_CONVERT,
- xfs_bmbt_disk_get_startoff(rrp));
+ key.br_startoff = cpu_to_be64(xfs_bmbt_disk_get_startoff(rrp));
rkp = &key;
}
be16_add(&left->bb_numrecs, -1);
@@ -1535,7 +1527,7 @@ xfs_bmbt_split(
xfs_btree_cur_t *cur,
int level,
xfs_fsblock_t *bnop,
- xfs_bmbt_key_t *keyp,
+ __uint64_t *startoff,
xfs_btree_cur_t **curp,
int *stat) /* success/failure */
{
@@ -1560,7 +1552,7 @@ xfs_bmbt_split(
xfs_bmbt_rec_t *rrp; /* right record pointer */
XFS_BMBT_TRACE_CURSOR(cur, ENTRY);
- XFS_BMBT_TRACE_ARGIFK(cur, level, *bnop, keyp);
+ XFS_BMBT_TRACE_ARGIFK(cur, level, *bnop, *startoff);
args.tp = cur->bc_tp;
args.mp = cur->bc_mp;
lbp = cur->bc_bufs[level];
@@ -1619,7 +1611,7 @@ xfs_bmbt_split(
rpp = XFS_BMAP_PTR_IADDR(right, 1, cur);
#ifdef DEBUG
for (i = 0; i < be16_to_cpu(right->bb_numrecs); i++) {
- if ((error = xfs_btree_check_lptr(cur, INT_GET(lpp[i], ARCH_CONVERT), level))) {
+ if ((error = xfs_btree_check_lptr_disk(cur, lpp[i], level))) {
XFS_BMBT_TRACE_CURSOR(cur, ERROR);
return error;
}
@@ -1629,13 +1621,13 @@ xfs_bmbt_split(
memcpy(rpp, lpp, be16_to_cpu(right->bb_numrecs) * sizeof(*rpp));
xfs_bmbt_log_keys(cur, rbp, 1, be16_to_cpu(right->bb_numrecs));
xfs_bmbt_log_ptrs(cur, rbp, 1, be16_to_cpu(right->bb_numrecs));
- keyp->br_startoff = INT_GET(rkp->br_startoff, ARCH_CONVERT);
+ *startoff = be64_to_cpu(rkp->br_startoff);
} else {
lrp = XFS_BMAP_REC_IADDR(left, i, cur);
rrp = XFS_BMAP_REC_IADDR(right, 1, cur);
memcpy(rrp, lrp, be16_to_cpu(right->bb_numrecs) * sizeof(*rrp));
xfs_bmbt_log_recs(cur, rbp, 1, be16_to_cpu(right->bb_numrecs));
- keyp->br_startoff = xfs_bmbt_disk_get_startoff(rrp);
+ *startoff = xfs_bmbt_disk_get_startoff(rrp);
}
be16_add(&left->bb_numrecs, -(be16_to_cpu(right->bb_numrecs)));
right->bb_rightsib = left->bb_rightsib;
@@ -1728,9 +1720,9 @@ xfs_bmdr_to_bmbt(
{
int dmxr;
xfs_bmbt_key_t *fkp;
- xfs_bmbt_ptr_t *fpp;
+ __be64 *fpp;
xfs_bmbt_key_t *tkp;
- xfs_bmbt_ptr_t *tpp;
+ __be64 *tpp;
rblock->bb_magic = cpu_to_be32(XFS_BMAP_MAGIC);
rblock->bb_level = dblock->bb_level;
@@ -1745,7 +1737,7 @@ xfs_bmdr_to_bmbt(
tpp = XFS_BMAP_BROOT_PTR_ADDR(rblock, 1, rblocklen);
dmxr = be16_to_cpu(dblock->bb_numrecs);
memcpy(tkp, fkp, sizeof(*fkp) * dmxr);
- memcpy(tpp, fpp, sizeof(*fpp) * dmxr); /* INT_: direct copy */
+ memcpy(tpp, fpp, sizeof(*fpp) * dmxr);
}
/*
@@ -1805,7 +1797,7 @@ xfs_bmbt_decrement(
tp = cur->bc_tp;
mp = cur->bc_mp;
for (block = xfs_bmbt_get_block(cur, lev, &bp); lev > level; ) {
- fsbno = INT_GET(*XFS_BMAP_PTR_IADDR(block, cur->bc_ptrs[lev], cur), ARCH_CONVERT);
+ fsbno = be64_to_cpu(*XFS_BMAP_PTR_IADDR(block, cur->bc_ptrs[lev], cur));
if ((error = xfs_btree_read_bufl(mp, tp, fsbno, 0, &bp,
XFS_BMAP_BTREE_REF))) {
XFS_BMBT_TRACE_CURSOR(cur, ERROR);
@@ -2135,7 +2127,7 @@ xfs_bmbt_increment(
tp = cur->bc_tp;
mp = cur->bc_mp;
for (block = xfs_bmbt_get_block(cur, lev, &bp); lev > level; ) {
- fsbno = INT_GET(*XFS_BMAP_PTR_IADDR(block, cur->bc_ptrs[lev], cur), ARCH_CONVERT);
+ fsbno = be64_to_cpu(*XFS_BMAP_PTR_IADDR(block, cur->bc_ptrs[lev], cur));
if ((error = xfs_btree_read_bufl(mp, tp, fsbno, 0, &bp,
XFS_BMAP_BTREE_REF))) {
XFS_BMBT_TRACE_CURSOR(cur, ERROR);
@@ -2178,7 +2170,7 @@ xfs_bmbt_insert(
level = 0;
nbno = NULLFSBLOCK;
xfs_bmbt_disk_set_all(&nrec, &cur->bc_rec.b);
- ncur = (xfs_btree_cur_t *)0;
+ ncur = NULL;
pcur = cur;
do {
if ((error = xfs_bmbt_insrec(pcur, level++, &nbno, &nrec, &ncur,
@@ -2205,7 +2197,7 @@ xfs_bmbt_insert(
}
if (ncur) {
pcur = ncur;
- ncur = (xfs_btree_cur_t *)0;
+ ncur = NULL;
}
} while (nbno != NULLFSBLOCK);
XFS_BMBT_TRACE_CURSOR(cur, EXIT);
@@ -2356,12 +2348,12 @@ xfs_bmbt_newroot(
args.firstblock = args.fsbno;
if (args.fsbno == NULLFSBLOCK) {
#ifdef DEBUG
- if ((error = xfs_btree_check_lptr(cur, INT_GET(*pp, ARCH_CONVERT), level))) {
+ if ((error = xfs_btree_check_lptr_disk(cur, *pp, level))) {
XFS_BMBT_TRACE_CURSOR(cur, ERROR);
return error;
}
#endif
- args.fsbno = INT_GET(*pp, ARCH_CONVERT);
+ args.fsbno = be64_to_cpu(*pp);
args.type = XFS_ALLOCTYPE_START_BNO;
} else
args.type = XFS_ALLOCTYPE_NEAR_BNO;
@@ -2393,7 +2385,7 @@ xfs_bmbt_newroot(
cpp = XFS_BMAP_PTR_IADDR(cblock, 1, cur);
#ifdef DEBUG
for (i = 0; i < be16_to_cpu(cblock->bb_numrecs); i++) {
- if ((error = xfs_btree_check_lptr(cur, INT_GET(pp[i], ARCH_CONVERT), level))) {
+ if ((error = xfs_btree_check_lptr_disk(cur, pp[i], level))) {
XFS_BMBT_TRACE_CURSOR(cur, ERROR);
return error;
}
@@ -2401,13 +2393,12 @@ xfs_bmbt_newroot(
#endif
memcpy(cpp, pp, be16_to_cpu(cblock->bb_numrecs) * sizeof(*pp));
#ifdef DEBUG
- if ((error = xfs_btree_check_lptr(cur, (xfs_bmbt_ptr_t)args.fsbno,
- level))) {
+ if ((error = xfs_btree_check_lptr(cur, args.fsbno, level))) {
XFS_BMBT_TRACE_CURSOR(cur, ERROR);
return error;
}
#endif
- INT_SET(*pp, ARCH_CONVERT, args.fsbno);
+ *pp = cpu_to_be64(args.fsbno);
xfs_iroot_realloc(cur->bc_private.b.ip, 1 - be16_to_cpu(cblock->bb_numrecs),
cur->bc_private.b.whichfork);
xfs_btree_setbuf(cur, level, bp);
@@ -2681,9 +2672,9 @@ xfs_bmbt_to_bmdr(
{
int dmxr;
xfs_bmbt_key_t *fkp;
- xfs_bmbt_ptr_t *fpp;
+ __be64 *fpp;
xfs_bmbt_key_t *tkp;
- xfs_bmbt_ptr_t *tpp;
+ __be64 *tpp;
ASSERT(be32_to_cpu(rblock->bb_magic) == XFS_BMAP_MAGIC);
ASSERT(be64_to_cpu(rblock->bb_leftsib) == NULLDFSBNO);
@@ -2698,7 +2689,7 @@ xfs_bmbt_to_bmdr(
tpp = XFS_BTREE_PTR_ADDR(dblocklen, xfs_bmdr, dblock, 1, dmxr);
dmxr = be16_to_cpu(dblock->bb_numrecs);
memcpy(tkp, fkp, sizeof(*fkp) * dmxr);
- memcpy(tpp, fpp, sizeof(*fpp) * dmxr); /* INT_: direct copy */
+ memcpy(tpp, fpp, sizeof(*fpp) * dmxr);
}
/*
@@ -2740,7 +2731,7 @@ xfs_bmbt_update(
XFS_BMBT_TRACE_CURSOR(cur, EXIT);
return 0;
}
- INT_SET(key.br_startoff, ARCH_CONVERT, off);
+ key.br_startoff = cpu_to_be64(off);
if ((error = xfs_bmbt_updkey(cur, &key, 1))) {
XFS_BMBT_TRACE_CURSOR(cur, ERROR);
return error;
diff --git a/fs/xfs/xfs_bmap_btree.h b/fs/xfs/xfs_bmap_btree.h
index 6478cfa0e539..49539de9525b 100644
--- a/fs/xfs/xfs_bmap_btree.h
+++ b/fs/xfs/xfs_bmap_btree.h
@@ -163,13 +163,14 @@ typedef struct xfs_bmbt_irec
/*
* Key structure for non-leaf levels of the tree.
*/
-typedef struct xfs_bmbt_key
-{
- xfs_dfiloff_t br_startoff; /* starting file offset */
+typedef struct xfs_bmbt_key {
+ __be64 br_startoff; /* starting file offset */
} xfs_bmbt_key_t, xfs_bmdr_key_t;
-typedef xfs_dfsbno_t xfs_bmbt_ptr_t, xfs_bmdr_ptr_t; /* btree pointer type */
- /* btree block header type */
+/* btree pointer type */
+typedef __be64 xfs_bmbt_ptr_t, xfs_bmdr_ptr_t;
+
+/* btree block header type */
typedef struct xfs_btree_lblock xfs_bmbt_block_t;
#define XFS_BUF_TO_BMBT_BLOCK(bp) ((xfs_bmbt_block_t *)XFS_BUF_PTR(bp))
diff --git a/fs/xfs/xfs_btree.c b/fs/xfs/xfs_btree.c
index ee2255bd6562..aeb87ca69fcc 100644
--- a/fs/xfs/xfs_btree.c
+++ b/fs/xfs/xfs_btree.c
@@ -161,7 +161,7 @@ xfs_btree_check_key(
k1 = ak1;
k2 = ak2;
- ASSERT(INT_GET(k1->br_startoff, ARCH_CONVERT) < INT_GET(k2->br_startoff, ARCH_CONVERT));
+ ASSERT(be64_to_cpu(k1->br_startoff) < be64_to_cpu(k2->br_startoff));
break;
}
case XFS_BTNUM_INO: {
@@ -170,7 +170,7 @@ xfs_btree_check_key(
k1 = ak1;
k2 = ak2;
- ASSERT(INT_GET(k1->ir_startino, ARCH_CONVERT) < INT_GET(k2->ir_startino, ARCH_CONVERT));
+ ASSERT(be32_to_cpu(k1->ir_startino) < be32_to_cpu(k2->ir_startino));
break;
}
default:
@@ -285,8 +285,8 @@ xfs_btree_check_rec(
r1 = ar1;
r2 = ar2;
- ASSERT(INT_GET(r1->ir_startino, ARCH_CONVERT) + XFS_INODES_PER_CHUNK <=
- INT_GET(r2->ir_startino, ARCH_CONVERT));
+ ASSERT(be32_to_cpu(r1->ir_startino) + XFS_INODES_PER_CHUNK <=
+ be32_to_cpu(r2->ir_startino));
break;
}
default:
diff --git a/fs/xfs/xfs_btree.h b/fs/xfs/xfs_btree.h
index 44f1bd98064a..892b06c54263 100644
--- a/fs/xfs/xfs_btree.h
+++ b/fs/xfs/xfs_btree.h
@@ -145,7 +145,7 @@ typedef struct xfs_btree_cur
union {
xfs_alloc_rec_incore_t a;
xfs_bmbt_irec_t b;
- xfs_inobt_rec_t i;
+ xfs_inobt_rec_incore_t i;
} bc_rec; /* current insert/search record value */
struct xfs_buf *bc_bufs[XFS_BTREE_MAXLEVELS]; /* buf ptr per level */
int bc_ptrs[XFS_BTREE_MAXLEVELS]; /* key/record # */
@@ -243,6 +243,9 @@ xfs_btree_check_lptr(
xfs_dfsbno_t ptr, /* btree block disk address */
int level); /* btree block level */
+#define xfs_btree_check_lptr_disk(cur, ptr, level) \
+ xfs_btree_check_lptr(cur, be64_to_cpu(ptr), level)
+
/*
* Checking routine: check that short form block header is ok.
*/
diff --git a/fs/xfs/xfs_buf_item.c b/fs/xfs/xfs_buf_item.c
index a4aa53974f76..7a55c248ea70 100644
--- a/fs/xfs/xfs_buf_item.c
+++ b/fs/xfs/xfs_buf_item.c
@@ -234,7 +234,6 @@ xfs_buf_item_format(
ASSERT((bip->bli_flags & XFS_BLI_LOGGED) ||
(bip->bli_flags & XFS_BLI_STALE));
bp = bip->bli_buf;
- ASSERT(XFS_BUF_BP_ISMAPPED(bp));
vecp = log_vector;
/*
@@ -628,25 +627,6 @@ xfs_buf_item_committed(
}
/*
- * This is called when the transaction holding the buffer is aborted.
- * Just behave as if the transaction had been cancelled. If we're shutting down
- * and have aborted this transaction, we'll trap this buffer when it tries to
- * get written out.
- */
-STATIC void
-xfs_buf_item_abort(
- xfs_buf_log_item_t *bip)
-{
- xfs_buf_t *bp;
-
- bp = bip->bli_buf;
- xfs_buftrace("XFS_ABORT", bp);
- XFS_BUF_SUPER_STALE(bp);
- xfs_buf_item_unlock(bip);
- return;
-}
-
-/*
* This is called to asynchronously write the buffer associated with this
* buf log item out to disk. The buffer will already have been locked by
* a successful call to xfs_buf_item_trylock(). If the buffer still has
@@ -693,7 +673,6 @@ STATIC struct xfs_item_ops xfs_buf_item_ops = {
.iop_committed = (xfs_lsn_t(*)(xfs_log_item_t*, xfs_lsn_t))
xfs_buf_item_committed,
.iop_push = (void(*)(xfs_log_item_t*))xfs_buf_item_push,
- .iop_abort = (void(*)(xfs_log_item_t*))xfs_buf_item_abort,
.iop_pushbuf = NULL,
.iop_committing = (void(*)(xfs_log_item_t*, xfs_lsn_t))
xfs_buf_item_committing
@@ -901,7 +880,6 @@ xfs_buf_item_relse(
XFS_BUF_SET_FSPRIVATE(bp, bip->bli_item.li_bio_list);
if ((XFS_BUF_FSPRIVATE(bp, void *) == NULL) &&
(XFS_BUF_IODONE_FUNC(bp) != NULL)) {
- ASSERT((XFS_BUF_ISUNINITIAL(bp)) == 0);
XFS_BUF_CLR_IODONE_FUNC(bp);
}
diff --git a/fs/xfs/xfs_da_btree.c b/fs/xfs/xfs_da_btree.c
index 32ab61d17ace..a68bc1f1a313 100644
--- a/fs/xfs/xfs_da_btree.c
+++ b/fs/xfs/xfs_da_btree.c
@@ -1054,7 +1054,7 @@ xfs_da_node_lookup_int(xfs_da_state_t *state, int *result)
xfs_da_node_entry_t *btree;
xfs_dablk_t blkno;
int probe, span, max, error, retval;
- xfs_dahash_t hashval;
+ xfs_dahash_t hashval, btreehashval;
xfs_da_args_t *args;
args = state->args;
@@ -1079,30 +1079,32 @@ xfs_da_node_lookup_int(xfs_da_state_t *state, int *result)
return(error);
}
curr = blk->bp->data;
- ASSERT(be16_to_cpu(curr->magic) == XFS_DA_NODE_MAGIC ||
- be16_to_cpu(curr->magic) == XFS_DIR2_LEAFN_MAGIC ||
- be16_to_cpu(curr->magic) == XFS_ATTR_LEAF_MAGIC);
+ blk->magic = be16_to_cpu(curr->magic);
+ ASSERT(blk->magic == XFS_DA_NODE_MAGIC ||
+ blk->magic == XFS_DIR2_LEAFN_MAGIC ||
+ blk->magic == XFS_ATTR_LEAF_MAGIC);
/*
* Search an intermediate node for a match.
*/
- blk->magic = be16_to_cpu(curr->magic);
if (blk->magic == XFS_DA_NODE_MAGIC) {
node = blk->bp->data;
- blk->hashval = be32_to_cpu(node->btree[be16_to_cpu(node->hdr.count)-1].hashval);
+ max = be16_to_cpu(node->hdr.count);
+ btreehashval = node->btree[max-1].hashval;
+ blk->hashval = be32_to_cpu(btreehashval);
/*
* Binary search. (note: small blocks will skip loop)
*/
- max = be16_to_cpu(node->hdr.count);
probe = span = max / 2;
hashval = args->hashval;
for (btree = &node->btree[probe]; span > 4;
btree = &node->btree[probe]) {
span /= 2;
- if (be32_to_cpu(btree->hashval) < hashval)
+ btreehashval = be32_to_cpu(btree->hashval);
+ if (btreehashval < hashval)
probe += span;
- else if (be32_to_cpu(btree->hashval) > hashval)
+ else if (btreehashval > hashval)
probe -= span;
else
break;
@@ -1133,10 +1135,10 @@ xfs_da_node_lookup_int(xfs_da_state_t *state, int *result)
blk->index = probe;
blkno = be32_to_cpu(btree->before);
}
- } else if (be16_to_cpu(curr->magic) == XFS_ATTR_LEAF_MAGIC) {
+ } else if (blk->magic == XFS_ATTR_LEAF_MAGIC) {
blk->hashval = xfs_attr_leaf_lasthash(blk->bp, NULL);
break;
- } else if (be16_to_cpu(curr->magic) == XFS_DIR2_LEAFN_MAGIC) {
+ } else if (blk->magic == XFS_DIR2_LEAFN_MAGIC) {
blk->hashval = xfs_dir2_leafn_lasthash(blk->bp, NULL);
break;
}
@@ -1152,11 +1154,13 @@ xfs_da_node_lookup_int(xfs_da_state_t *state, int *result)
if (blk->magic == XFS_DIR2_LEAFN_MAGIC) {
retval = xfs_dir2_leafn_lookup_int(blk->bp, args,
&blk->index, state);
- }
- else if (blk->magic == XFS_ATTR_LEAF_MAGIC) {
+ } else if (blk->magic == XFS_ATTR_LEAF_MAGIC) {
retval = xfs_attr_leaf_lookup_int(blk->bp, args);
blk->index = args->index;
args->blkno = blk->blkno;
+ } else {
+ ASSERT(0);
+ return XFS_ERROR(EFSCORRUPTED);
}
if (((retval == ENOENT) || (retval == ENOATTR)) &&
(blk->hashval == args->hashval)) {
@@ -1166,8 +1170,7 @@ xfs_da_node_lookup_int(xfs_da_state_t *state, int *result)
return(error);
if (retval == 0) {
continue;
- }
- else if (blk->magic == XFS_ATTR_LEAF_MAGIC) {
+ } else if (blk->magic == XFS_ATTR_LEAF_MAGIC) {
/* path_shift() gives ENOENT */
retval = XFS_ERROR(ENOATTR);
}
diff --git a/fs/xfs/xfs_error.h b/fs/xfs/xfs_error.h
index bc43163456ef..0893e16b7d83 100644
--- a/fs/xfs/xfs_error.h
+++ b/fs/xfs/xfs_error.h
@@ -18,14 +18,6 @@
#ifndef __XFS_ERROR_H__
#define __XFS_ERROR_H__
-#define XFS_ERECOVER 1 /* Failure to recover log */
-#define XFS_ELOGSTAT 2 /* Failure to stat log in user space */
-#define XFS_ENOLOGSPACE 3 /* Reservation too large */
-#define XFS_ENOTSUP 4 /* Operation not supported */
-#define XFS_ENOLSN 5 /* Can't find the lsn you asked for */
-#define XFS_ENOTFOUND 6
-#define XFS_ENOTXFS 7 /* Not XFS filesystem */
-
#ifdef DEBUG
#define XFS_ERROR_NTRAP 10
extern int xfs_etrap[XFS_ERROR_NTRAP];
@@ -175,6 +167,7 @@ extern int xfs_errortag_clearall_umount(int64_t fsid, char *fsname, int loud);
#define XFS_PTAG_SHUTDOWN_CORRUPT 0x00000010
#define XFS_PTAG_SHUTDOWN_IOERROR 0x00000020
#define XFS_PTAG_SHUTDOWN_LOGERROR 0x00000040
+#define XFS_PTAG_FSBLOCK_ZERO 0x00000080
struct xfs_mount;
/* PRINTFLIKE4 */
diff --git a/fs/xfs/xfs_extfree_item.c b/fs/xfs/xfs_extfree_item.c
index 6cf6d8769b97..6dba78199faf 100644
--- a/fs/xfs/xfs_extfree_item.c
+++ b/fs/xfs/xfs_extfree_item.c
@@ -33,9 +33,6 @@ kmem_zone_t *xfs_efi_zone;
kmem_zone_t *xfs_efd_zone;
STATIC void xfs_efi_item_unlock(xfs_efi_log_item_t *);
-STATIC void xfs_efi_item_abort(xfs_efi_log_item_t *);
-STATIC void xfs_efd_item_abort(xfs_efd_log_item_t *);
-
void
xfs_efi_item_free(xfs_efi_log_item_t *efip)
@@ -184,7 +181,7 @@ STATIC void
xfs_efi_item_unlock(xfs_efi_log_item_t *efip)
{
if (efip->efi_item.li_flags & XFS_LI_ABORTED)
- xfs_efi_item_abort(efip);
+ xfs_efi_item_free(efip);
return;
}
@@ -202,18 +199,6 @@ xfs_efi_item_committed(xfs_efi_log_item_t *efip, xfs_lsn_t lsn)
}
/*
- * This is called when the transaction logging the EFI is aborted.
- * Free up the EFI and return. No need to clean up the slot for
- * the item in the transaction. That was done by the unpin code
- * which is called prior to this routine in the abort/fs-shutdown path.
- */
-STATIC void
-xfs_efi_item_abort(xfs_efi_log_item_t *efip)
-{
- xfs_efi_item_free(efip);
-}
-
-/*
* There isn't much you can do to push on an efi item. It is simply
* stuck waiting for all of its corresponding efd items to be
* committed to disk.
@@ -255,7 +240,6 @@ STATIC struct xfs_item_ops xfs_efi_item_ops = {
.iop_committed = (xfs_lsn_t(*)(xfs_log_item_t*, xfs_lsn_t))
xfs_efi_item_committed,
.iop_push = (void(*)(xfs_log_item_t*))xfs_efi_item_push,
- .iop_abort = (void(*)(xfs_log_item_t*))xfs_efi_item_abort,
.iop_pushbuf = NULL,
.iop_committing = (void(*)(xfs_log_item_t*, xfs_lsn_t))
xfs_efi_item_committing
@@ -386,33 +370,6 @@ xfs_efi_release(xfs_efi_log_item_t *efip,
}
}
-/*
- * This is called when the transaction that should be committing the
- * EFD corresponding to the given EFI is aborted. The committed and
- * canceled flags are used to coordinate the freeing of the EFI and
- * the references by the transaction that committed it.
- */
-STATIC void
-xfs_efi_cancel(
- xfs_efi_log_item_t *efip)
-{
- xfs_mount_t *mp;
- SPLDECL(s);
-
- mp = efip->efi_item.li_mountp;
- AIL_LOCK(mp, s);
- if (efip->efi_flags & XFS_EFI_COMMITTED) {
- /*
- * xfs_trans_delete_ail() drops the AIL lock.
- */
- xfs_trans_delete_ail(mp, (xfs_log_item_t *)efip, s);
- xfs_efi_item_free(efip);
- } else {
- efip->efi_flags |= XFS_EFI_CANCELED;
- AIL_UNLOCK(mp, s);
- }
-}
-
STATIC void
xfs_efd_item_free(xfs_efd_log_item_t *efdp)
{
@@ -514,7 +471,7 @@ STATIC void
xfs_efd_item_unlock(xfs_efd_log_item_t *efdp)
{
if (efdp->efd_item.li_flags & XFS_LI_ABORTED)
- xfs_efd_item_abort(efdp);
+ xfs_efd_item_free(efdp);
return;
}
@@ -541,27 +498,6 @@ xfs_efd_item_committed(xfs_efd_log_item_t *efdp, xfs_lsn_t lsn)
}
/*
- * The transaction of which this EFD is a part has been aborted.
- * Inform its companion EFI of this fact and then clean up after
- * ourselves. No need to clean up the slot for the item in the
- * transaction. That was done by the unpin code which is called
- * prior to this routine in the abort/fs-shutdown path.
- */
-STATIC void
-xfs_efd_item_abort(xfs_efd_log_item_t *efdp)
-{
- /*
- * If we got a log I/O error, it's always the case that the LR with the
- * EFI got unpinned and freed before the EFD got aborted. So don't
- * reference the EFI at all in that case.
- */
- if ((efdp->efd_item.li_flags & XFS_LI_ABORTED) == 0)
- xfs_efi_cancel(efdp->efd_efip);
-
- xfs_efd_item_free(efdp);
-}
-
-/*
* There isn't much you can do to push on an efd item. It is simply
* stuck waiting for the log to be flushed to disk.
*/
@@ -602,7 +538,6 @@ STATIC struct xfs_item_ops xfs_efd_item_ops = {
.iop_committed = (xfs_lsn_t(*)(xfs_log_item_t*, xfs_lsn_t))
xfs_efd_item_committed,
.iop_push = (void(*)(xfs_log_item_t*))xfs_efd_item_push,
- .iop_abort = (void(*)(xfs_log_item_t*))xfs_efd_item_abort,
.iop_pushbuf = NULL,
.iop_committing = (void(*)(xfs_log_item_t*, xfs_lsn_t))
xfs_efd_item_committing
diff --git a/fs/xfs/xfs_extfree_item.h b/fs/xfs/xfs_extfree_item.h
index 0ea45edaab03..2f049f63e85f 100644
--- a/fs/xfs/xfs_extfree_item.h
+++ b/fs/xfs/xfs_extfree_item.h
@@ -33,14 +33,16 @@ typedef struct xfs_extent {
* conversion routine.
*/
+#ifndef HAVE_FORMAT32
typedef struct xfs_extent_32 {
- xfs_dfsbno_t ext_start;
- xfs_extlen_t ext_len;
+ __uint64_t ext_start;
+ __uint32_t ext_len;
} __attribute__((packed)) xfs_extent_32_t;
+#endif
typedef struct xfs_extent_64 {
- xfs_dfsbno_t ext_start;
- xfs_extlen_t ext_len;
+ __uint64_t ext_start;
+ __uint32_t ext_len;
__uint32_t ext_pad;
} xfs_extent_64_t;
@@ -50,25 +52,27 @@ typedef struct xfs_extent_64 {
* size is given by efi_nextents.
*/
typedef struct xfs_efi_log_format {
- unsigned short efi_type; /* efi log item type */
- unsigned short efi_size; /* size of this item */
- uint efi_nextents; /* # extents to free */
+ __uint16_t efi_type; /* efi log item type */
+ __uint16_t efi_size; /* size of this item */
+ __uint32_t efi_nextents; /* # extents to free */
__uint64_t efi_id; /* efi identifier */
xfs_extent_t efi_extents[1]; /* array of extents to free */
} xfs_efi_log_format_t;
+#ifndef HAVE_FORMAT32
typedef struct xfs_efi_log_format_32 {
- unsigned short efi_type; /* efi log item type */
- unsigned short efi_size; /* size of this item */
- uint efi_nextents; /* # extents to free */
+ __uint16_t efi_type; /* efi log item type */
+ __uint16_t efi_size; /* size of this item */
+ __uint32_t efi_nextents; /* # extents to free */
__uint64_t efi_id; /* efi identifier */
xfs_extent_32_t efi_extents[1]; /* array of extents to free */
} __attribute__((packed)) xfs_efi_log_format_32_t;
+#endif
typedef struct xfs_efi_log_format_64 {
- unsigned short efi_type; /* efi log item type */
- unsigned short efi_size; /* size of this item */
- uint efi_nextents; /* # extents to free */
+ __uint16_t efi_type; /* efi log item type */
+ __uint16_t efi_size; /* size of this item */
+ __uint32_t efi_nextents; /* # extents to free */
__uint64_t efi_id; /* efi identifier */
xfs_extent_64_t efi_extents[1]; /* array of extents to free */
} xfs_efi_log_format_64_t;
@@ -79,25 +83,27 @@ typedef struct xfs_efi_log_format_64 {
* size is given by efd_nextents;
*/
typedef struct xfs_efd_log_format {
- unsigned short efd_type; /* efd log item type */
- unsigned short efd_size; /* size of this item */
- uint efd_nextents; /* # of extents freed */
+ __uint16_t efd_type; /* efd log item type */
+ __uint16_t efd_size; /* size of this item */
+ __uint32_t efd_nextents; /* # of extents freed */
__uint64_t efd_efi_id; /* id of corresponding efi */
xfs_extent_t efd_extents[1]; /* array of extents freed */
} xfs_efd_log_format_t;
+#ifndef HAVE_FORMAT32
typedef struct xfs_efd_log_format_32 {
- unsigned short efd_type; /* efd log item type */
- unsigned short efd_size; /* size of this item */
- uint efd_nextents; /* # of extents freed */
+ __uint16_t efd_type; /* efd log item type */
+ __uint16_t efd_size; /* size of this item */
+ __uint32_t efd_nextents; /* # of extents freed */
__uint64_t efd_efi_id; /* id of corresponding efi */
xfs_extent_32_t efd_extents[1]; /* array of extents freed */
} __attribute__((packed)) xfs_efd_log_format_32_t;
+#endif
typedef struct xfs_efd_log_format_64 {
- unsigned short efd_type; /* efd log item type */
- unsigned short efd_size; /* size of this item */
- uint efd_nextents; /* # of extents freed */
+ __uint16_t efd_type; /* efd log item type */
+ __uint16_t efd_size; /* size of this item */
+ __uint32_t efd_nextents; /* # of extents freed */
__uint64_t efd_efi_id; /* id of corresponding efi */
xfs_extent_64_t efd_extents[1]; /* array of extents freed */
} xfs_efd_log_format_64_t;
diff --git a/fs/xfs/xfs_fs.h b/fs/xfs/xfs_fs.h
index 0f0ad1535951..1335449841cd 100644
--- a/fs/xfs/xfs_fs.h
+++ b/fs/xfs/xfs_fs.h
@@ -22,8 +22,6 @@
* SGI's XFS filesystem's major stuff (constants, structures)
*/
-#define XFS_NAME "xfs"
-
/*
* Direct I/O attribute record used with XFS_IOC_DIOINFO
* d_miniosz is the min xfer size, xfer size multiple and file seek offset
@@ -426,11 +424,7 @@ typedef struct xfs_handle {
- (char *) &(handle)) \
+ (handle).ha_fid.xfs_fid_len)
-#define XFS_HANDLE_CMP(h1, h2) memcmp(h1, h2, sizeof(xfs_handle_t))
-
-#define FSHSIZE sizeof(fsid_t)
-
-/*
+/*
* Flags for going down operation
*/
#define XFS_FSOP_GOING_FLAGS_DEFAULT 0x0 /* going down */
diff --git a/fs/xfs/xfs_ialloc.c b/fs/xfs/xfs_ialloc.c
index 33164a85aa9d..a446e5a115c6 100644
--- a/fs/xfs/xfs_ialloc.c
+++ b/fs/xfs/xfs_ialloc.c
@@ -458,7 +458,7 @@ nextag:
*/
if (XFS_FORCED_SHUTDOWN(mp)) {
up_read(&mp->m_peraglock);
- return (xfs_buf_t *)0;
+ return NULL;
}
agno++;
if (agno >= agcount)
@@ -466,7 +466,7 @@ nextag:
if (agno == pagno) {
if (flags == 0) {
up_read(&mp->m_peraglock);
- return (xfs_buf_t *)0;
+ return NULL;
}
flags = 0;
}
@@ -529,10 +529,10 @@ xfs_dialloc(
int offset; /* index of inode in chunk */
xfs_agino_t pagino; /* parent's a.g. relative inode # */
xfs_agnumber_t pagno; /* parent's allocation group number */
- xfs_inobt_rec_t rec; /* inode allocation record */
+ xfs_inobt_rec_incore_t rec; /* inode allocation record */
xfs_agnumber_t tagno; /* testing allocation group number */
xfs_btree_cur_t *tcur; /* temp cursor */
- xfs_inobt_rec_t trec; /* temp inode allocation record */
+ xfs_inobt_rec_incore_t trec; /* temp inode allocation record */
if (*IO_agbp == NULL) {
@@ -945,7 +945,7 @@ xfs_difree(
int ilen; /* inodes in an inode cluster */
xfs_mount_t *mp; /* mount structure for filesystem */
int off; /* offset of inode in inode chunk */
- xfs_inobt_rec_t rec; /* btree record */
+ xfs_inobt_rec_incore_t rec; /* btree record */
mp = tp->t_mountp;
@@ -1195,6 +1195,7 @@ xfs_dilocate(
"(0x%llx)",
ino, XFS_AGINO_TO_INO(mp, agno, agino));
}
+ xfs_stack_trace();
#endif /* DEBUG */
return XFS_ERROR(EINVAL);
}
diff --git a/fs/xfs/xfs_ialloc_btree.c b/fs/xfs/xfs_ialloc_btree.c
index 616eeeb6953e..8cdeeaf8632b 100644
--- a/fs/xfs/xfs_ialloc_btree.c
+++ b/fs/xfs/xfs_ialloc_btree.c
@@ -568,7 +568,7 @@ xfs_inobt_insrec(
/*
* Make a key out of the record data to be inserted, and save it.
*/
- key.ir_startino = recp->ir_startino; /* INT_: direct copy */
+ key.ir_startino = recp->ir_startino;
optr = ptr = cur->bc_ptrs[level];
/*
* If we're off the left edge, return failure.
@@ -600,7 +600,7 @@ xfs_inobt_insrec(
}
#endif
nbno = NULLAGBLOCK;
- ncur = (xfs_btree_cur_t *)0;
+ ncur = NULL;
/*
* If the block is full, we can't insert the new entry until we
* make the block un-full.
@@ -641,7 +641,7 @@ xfs_inobt_insrec(
return error;
#endif
ptr = cur->bc_ptrs[level];
- nrec.ir_startino = nkey.ir_startino; /* INT_: direct copy */
+ nrec.ir_startino = nkey.ir_startino;
} else {
/*
* Otherwise the insert fails.
@@ -681,7 +681,7 @@ xfs_inobt_insrec(
if ((error = xfs_btree_check_sptr(cur, *bnop, level)))
return error;
#endif
- kp[ptr - 1] = key; /* INT_: struct copy */
+ kp[ptr - 1] = key;
pp[ptr - 1] = cpu_to_be32(*bnop);
numrecs++;
block->bb_numrecs = cpu_to_be16(numrecs);
@@ -698,7 +698,7 @@ xfs_inobt_insrec(
* Now stuff the new record in, bump numrecs
* and log the new data.
*/
- rp[ptr - 1] = *recp; /* INT_: struct copy */
+ rp[ptr - 1] = *recp;
numrecs++;
block->bb_numrecs = cpu_to_be16(numrecs);
xfs_inobt_log_recs(cur, bp, ptr, numrecs);
@@ -731,7 +731,7 @@ xfs_inobt_insrec(
*/
*bnop = nbno;
if (nbno != NULLAGBLOCK) {
- *recp = nrec; /* INT_: struct copy */
+ *recp = nrec;
*curp = ncur;
}
*stat = 1;
@@ -878,7 +878,7 @@ xfs_inobt_lookup(
*/
bp = cur->bc_bufs[level];
if (bp && XFS_BUF_ADDR(bp) != d)
- bp = (xfs_buf_t *)0;
+ bp = NULL;
if (!bp) {
/*
* Need to get a new buffer. Read it, then
@@ -950,12 +950,12 @@ xfs_inobt_lookup(
xfs_inobt_key_t *kkp;
kkp = kkbase + keyno - 1;
- startino = INT_GET(kkp->ir_startino, ARCH_CONVERT);
+ startino = be32_to_cpu(kkp->ir_startino);
} else {
xfs_inobt_rec_t *krp;
krp = krbase + keyno - 1;
- startino = INT_GET(krp->ir_startino, ARCH_CONVERT);
+ startino = be32_to_cpu(krp->ir_startino);
}
/*
* Compute difference to get next direction.
@@ -1117,7 +1117,7 @@ xfs_inobt_lshift(
if ((error = xfs_btree_check_sptr(cur, be32_to_cpu(*rpp), level)))
return error;
#endif
- *lpp = *rpp; /* INT_: no-change copy */
+ *lpp = *rpp;
xfs_inobt_log_ptrs(cur, lbp, nrec, nrec);
}
/*
@@ -1160,7 +1160,7 @@ xfs_inobt_lshift(
} else {
memmove(rrp, rrp + 1, be16_to_cpu(right->bb_numrecs) * sizeof(*rrp));
xfs_inobt_log_recs(cur, rbp, 1, be16_to_cpu(right->bb_numrecs));
- key.ir_startino = rrp->ir_startino; /* INT_: direct copy */
+ key.ir_startino = rrp->ir_startino;
rkp = &key;
}
/*
@@ -1297,13 +1297,13 @@ xfs_inobt_newroot(
*/
kp = XFS_INOBT_KEY_ADDR(new, 1, cur);
if (be16_to_cpu(left->bb_level) > 0) {
- kp[0] = *XFS_INOBT_KEY_ADDR(left, 1, cur); /* INT_: struct copy */
- kp[1] = *XFS_INOBT_KEY_ADDR(right, 1, cur); /* INT_: struct copy */
+ kp[0] = *XFS_INOBT_KEY_ADDR(left, 1, cur);
+ kp[1] = *XFS_INOBT_KEY_ADDR(right, 1, cur);
} else {
rp = XFS_INOBT_REC_ADDR(left, 1, cur);
- INT_COPY(kp[0].ir_startino, rp->ir_startino, ARCH_CONVERT);
+ kp[0].ir_startino = rp->ir_startino;
rp = XFS_INOBT_REC_ADDR(right, 1, cur);
- INT_COPY(kp[1].ir_startino, rp->ir_startino, ARCH_CONVERT);
+ kp[1].ir_startino = rp->ir_startino;
}
xfs_inobt_log_keys(cur, nbp, 1, 2);
/*
@@ -1410,8 +1410,8 @@ xfs_inobt_rshift(
if ((error = xfs_btree_check_sptr(cur, be32_to_cpu(*lpp), level)))
return error;
#endif
- *rkp = *lkp; /* INT_: no change copy */
- *rpp = *lpp; /* INT_: no change copy */
+ *rkp = *lkp;
+ *rpp = *lpp;
xfs_inobt_log_keys(cur, rbp, 1, be16_to_cpu(right->bb_numrecs) + 1);
xfs_inobt_log_ptrs(cur, rbp, 1, be16_to_cpu(right->bb_numrecs) + 1);
} else {
@@ -1420,7 +1420,7 @@ xfs_inobt_rshift(
memmove(rrp + 1, rrp, be16_to_cpu(right->bb_numrecs) * sizeof(*rrp));
*rrp = *lrp;
xfs_inobt_log_recs(cur, rbp, 1, be16_to_cpu(right->bb_numrecs) + 1);
- key.ir_startino = rrp->ir_startino; /* INT_: direct copy */
+ key.ir_startino = rrp->ir_startino;
rkp = &key;
}
/*
@@ -1559,7 +1559,7 @@ xfs_inobt_split(
rrp = XFS_INOBT_REC_ADDR(right, 1, cur);
memcpy(rrp, lrp, be16_to_cpu(right->bb_numrecs) * sizeof(*rrp));
xfs_inobt_log_recs(cur, rbp, 1, be16_to_cpu(right->bb_numrecs));
- keyp->ir_startino = rrp->ir_startino; /* INT_: direct copy */
+ keyp->ir_startino = rrp->ir_startino;
}
/*
* Find the left block number by looking in the buffer.
@@ -1813,9 +1813,9 @@ xfs_inobt_get_rec(
* Point to the record and extract its data.
*/
rec = XFS_INOBT_REC_ADDR(block, ptr, cur);
- *ino = INT_GET(rec->ir_startino, ARCH_CONVERT);
- *fcnt = INT_GET(rec->ir_freecount, ARCH_CONVERT);
- *free = INT_GET(rec->ir_free, ARCH_CONVERT);
+ *ino = be32_to_cpu(rec->ir_startino);
+ *fcnt = be32_to_cpu(rec->ir_freecount);
+ *free = be64_to_cpu(rec->ir_free);
*stat = 1;
return 0;
}
@@ -1930,10 +1930,10 @@ xfs_inobt_insert(
level = 0;
nbno = NULLAGBLOCK;
- INT_SET(nrec.ir_startino, ARCH_CONVERT, cur->bc_rec.i.ir_startino);
- INT_SET(nrec.ir_freecount, ARCH_CONVERT, cur->bc_rec.i.ir_freecount);
- INT_SET(nrec.ir_free, ARCH_CONVERT, cur->bc_rec.i.ir_free);
- ncur = (xfs_btree_cur_t *)0;
+ nrec.ir_startino = cpu_to_be32(cur->bc_rec.i.ir_startino);
+ nrec.ir_freecount = cpu_to_be32(cur->bc_rec.i.ir_freecount);
+ nrec.ir_free = cpu_to_be64(cur->bc_rec.i.ir_free);
+ ncur = NULL;
pcur = cur;
/*
* Loop going up the tree, starting at the leaf level.
@@ -1965,7 +1965,7 @@ xfs_inobt_insert(
*/
if (ncur) {
pcur = ncur;
- ncur = (xfs_btree_cur_t *)0;
+ ncur = NULL;
}
} while (nbno != NULLAGBLOCK);
*stat = i;
@@ -2060,9 +2060,9 @@ xfs_inobt_update(
/*
* Fill in the new contents and log them.
*/
- INT_SET(rp->ir_startino, ARCH_CONVERT, ino);
- INT_SET(rp->ir_freecount, ARCH_CONVERT, fcnt);
- INT_SET(rp->ir_free, ARCH_CONVERT, free);
+ rp->ir_startino = cpu_to_be32(ino);
+ rp->ir_freecount = cpu_to_be32(fcnt);
+ rp->ir_free = cpu_to_be64(free);
xfs_inobt_log_recs(cur, bp, ptr, ptr);
/*
* Updating first record in leaf. Pass new key value up to our parent.
@@ -2070,7 +2070,7 @@ xfs_inobt_update(
if (ptr == 1) {
xfs_inobt_key_t key; /* key containing [ino] */
- INT_SET(key.ir_startino, ARCH_CONVERT, ino);
+ key.ir_startino = cpu_to_be32(ino);
if ((error = xfs_inobt_updkey(cur, &key, 1)))
return error;
}
diff --git a/fs/xfs/xfs_ialloc_btree.h b/fs/xfs/xfs_ialloc_btree.h
index ae3904cb1ee8..2c0e49893ff7 100644
--- a/fs/xfs/xfs_ialloc_btree.h
+++ b/fs/xfs/xfs_ialloc_btree.h
@@ -47,19 +47,24 @@ static inline xfs_inofree_t xfs_inobt_maskn(int i, int n)
/*
* Data record structure
*/
-typedef struct xfs_inobt_rec
-{
+typedef struct xfs_inobt_rec {
+ __be32 ir_startino; /* starting inode number */
+ __be32 ir_freecount; /* count of free inodes (set bits) */
+ __be64 ir_free; /* free inode mask */
+} xfs_inobt_rec_t;
+
+typedef struct xfs_inobt_rec_incore {
xfs_agino_t ir_startino; /* starting inode number */
__int32_t ir_freecount; /* count of free inodes (set bits) */
xfs_inofree_t ir_free; /* free inode mask */
-} xfs_inobt_rec_t;
+} xfs_inobt_rec_incore_t;
+
/*
* Key structure
*/
-typedef struct xfs_inobt_key
-{
- xfs_agino_t ir_startino; /* starting inode number */
+typedef struct xfs_inobt_key {
+ __be32 ir_startino; /* starting inode number */
} xfs_inobt_key_t;
/* btree pointer type */
@@ -77,7 +82,7 @@ typedef struct xfs_btree_sblock xfs_inobt_block_t;
#define XFS_INOBT_IS_FREE(rp,i) \
(((rp)->ir_free & XFS_INOBT_MASK(i)) != 0)
#define XFS_INOBT_IS_FREE_DISK(rp,i) \
- ((INT_GET((rp)->ir_free,ARCH_CONVERT) & XFS_INOBT_MASK(i)) != 0)
+ ((be64_to_cpu((rp)->ir_free) & XFS_INOBT_MASK(i)) != 0)
#define XFS_INOBT_SET_FREE(rp,i) ((rp)->ir_free |= XFS_INOBT_MASK(i))
#define XFS_INOBT_CLR_FREE(rp,i) ((rp)->ir_free &= ~XFS_INOBT_MASK(i))
diff --git a/fs/xfs/xfs_iget.c b/fs/xfs/xfs_iget.c
index 0724df7fabb7..b73d216ecaf9 100644
--- a/fs/xfs/xfs_iget.c
+++ b/fs/xfs/xfs_iget.c
@@ -50,7 +50,7 @@ void
xfs_ihash_init(xfs_mount_t *mp)
{
__uint64_t icount;
- uint i, flags = KM_SLEEP | KM_MAYFAIL;
+ uint i;
if (!mp->m_ihsize) {
icount = mp->m_maxicount ? mp->m_maxicount :
@@ -61,14 +61,13 @@ xfs_ihash_init(xfs_mount_t *mp)
(64 * NBPP) / sizeof(xfs_ihash_t));
}
- while (!(mp->m_ihash = (xfs_ihash_t *)kmem_zalloc(mp->m_ihsize *
- sizeof(xfs_ihash_t), flags))) {
- if ((mp->m_ihsize >>= 1) <= NBPP)
- flags = KM_SLEEP;
- }
- for (i = 0; i < mp->m_ihsize; i++) {
+ mp->m_ihash = kmem_zalloc_greedy(&mp->m_ihsize,
+ NBPC * sizeof(xfs_ihash_t),
+ mp->m_ihsize * sizeof(xfs_ihash_t),
+ KM_SLEEP | KM_MAYFAIL | KM_LARGE);
+ mp->m_ihsize /= sizeof(xfs_ihash_t);
+ for (i = 0; i < mp->m_ihsize; i++)
rwlock_init(&(mp->m_ihash[i].ih_lock));
- }
}
/*
@@ -77,7 +76,7 @@ xfs_ihash_init(xfs_mount_t *mp)
void
xfs_ihash_free(xfs_mount_t *mp)
{
- kmem_free(mp->m_ihash, mp->m_ihsize*sizeof(xfs_ihash_t));
+ kmem_free(mp->m_ihash, mp->m_ihsize * sizeof(xfs_ihash_t));
mp->m_ihash = NULL;
}
@@ -95,7 +94,7 @@ xfs_chash_init(xfs_mount_t *mp)
mp->m_chsize = min_t(uint, mp->m_chsize, mp->m_ihsize);
mp->m_chash = (xfs_chash_t *)kmem_zalloc(mp->m_chsize
* sizeof(xfs_chash_t),
- KM_SLEEP);
+ KM_SLEEP | KM_LARGE);
for (i = 0; i < mp->m_chsize; i++) {
spinlock_init(&mp->m_chash[i].ch_lock,"xfshash");
}
@@ -244,7 +243,9 @@ again:
XFS_STATS_INC(xs_ig_found);
+ spin_lock(&ip->i_flags_lock);
ip->i_flags &= ~XFS_IRECLAIMABLE;
+ spin_unlock(&ip->i_flags_lock);
version = ih->ih_version;
read_unlock(&ih->ih_lock);
xfs_ihash_promote(ih, ip, version);
@@ -290,15 +291,17 @@ again:
finish_inode:
if (ip->i_d.di_mode == 0) {
- if (!(flags & IGET_CREATE))
+ if (!(flags & XFS_IGET_CREATE))
return ENOENT;
xfs_iocore_inode_reinit(ip);
}
-
+
if (lock_flags != 0)
xfs_ilock(ip, lock_flags);
+ spin_lock(&ip->i_flags_lock);
ip->i_flags &= ~XFS_ISTALE;
+ spin_unlock(&ip->i_flags_lock);
vn_trace_exit(vp, "xfs_iget.found",
(inst_t *)__return_address);
@@ -320,21 +323,20 @@ finish_inode:
* Read the disk inode attributes into a new inode structure and get
* a new vnode for it. This should also initialize i_ino and i_mount.
*/
- error = xfs_iread(mp, tp, ino, &ip, bno);
- if (error) {
+ error = xfs_iread(mp, tp, ino, &ip, bno,
+ (flags & XFS_IGET_BULKSTAT) ? XFS_IMAP_BULKSTAT : 0);
+ if (error)
return error;
- }
vn_trace_exit(vp, "xfs_iget.alloc", (inst_t *)__return_address);
xfs_inode_lock_init(ip, vp);
xfs_iocore_inode_init(ip);
- if (lock_flags != 0) {
+ if (lock_flags)
xfs_ilock(ip, lock_flags);
- }
-
- if ((ip->i_d.di_mode == 0) && !(flags & IGET_CREATE)) {
+
+ if ((ip->i_d.di_mode == 0) && !(flags & XFS_IGET_CREATE)) {
xfs_idestroy(ip);
return ENOENT;
}
@@ -369,7 +371,9 @@ finish_inode:
ih->ih_next = ip;
ip->i_udquot = ip->i_gdquot = NULL;
ih->ih_version++;
+ spin_lock(&ip->i_flags_lock);
ip->i_flags |= XFS_INEW;
+ spin_unlock(&ip->i_flags_lock);
write_unlock(&ih->ih_lock);
@@ -548,7 +552,7 @@ xfs_inode_lock_init(
mrlock_init(&ip->i_iolock, MRLOCK_BARRIER, "xfsio", vp->v_number);
init_waitqueue_head(&ip->i_ipin_wait);
atomic_set(&ip->i_pincount, 0);
- init_sema(&ip->i_flock, 1, "xfsfino", vp->v_number);
+ initnsema(&ip->i_flock, 1, "xfsfino");
}
/*
diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c
index 1f8ecff8553a..c27d7d495aa0 100644
--- a/fs/xfs/xfs_inode.c
+++ b/fs/xfs/xfs_inode.c
@@ -854,7 +854,8 @@ xfs_iread(
xfs_trans_t *tp,
xfs_ino_t ino,
xfs_inode_t **ipp,
- xfs_daddr_t bno)
+ xfs_daddr_t bno,
+ uint imap_flags)
{
xfs_buf_t *bp;
xfs_dinode_t *dip;
@@ -866,6 +867,7 @@ xfs_iread(
ip = kmem_zone_zalloc(xfs_inode_zone, KM_SLEEP);
ip->i_ino = ino;
ip->i_mount = mp;
+ spin_lock_init(&ip->i_flags_lock);
/*
* Get pointer's to the on-disk inode and the buffer containing it.
@@ -874,7 +876,7 @@ xfs_iread(
* return NULL as well. Set i_blkno to 0 so that xfs_itobp() will
* know that this is a new incore inode.
*/
- error = xfs_itobp(mp, tp, ip, &dip, &bp, bno, 0);
+ error = xfs_itobp(mp, tp, ip, &dip, &bp, bno, imap_flags);
if (error) {
kmem_zone_free(xfs_inode_zone, ip);
return error;
@@ -1113,7 +1115,7 @@ xfs_ialloc(
* to prevent others from looking at until we're done.
*/
error = xfs_trans_iget(tp->t_mountp, tp, ino,
- IGET_CREATE, XFS_ILOCK_EXCL, &ip);
+ XFS_IGET_CREATE, XFS_ILOCK_EXCL, &ip);
if (error != 0) {
return error;
}
@@ -2213,7 +2215,9 @@ xfs_ifree_cluster(
if (ip == free_ip) {
if (xfs_iflock_nowait(ip)) {
+ spin_lock(&ip->i_flags_lock);
ip->i_flags |= XFS_ISTALE;
+ spin_unlock(&ip->i_flags_lock);
if (xfs_inode_clean(ip)) {
xfs_ifunlock(ip);
@@ -2227,7 +2231,9 @@ xfs_ifree_cluster(
if (xfs_ilock_nowait(ip, XFS_ILOCK_EXCL)) {
if (xfs_iflock_nowait(ip)) {
+ spin_lock(&ip->i_flags_lock);
ip->i_flags |= XFS_ISTALE;
+ spin_unlock(&ip->i_flags_lock);
if (xfs_inode_clean(ip)) {
xfs_ifunlock(ip);
@@ -2257,7 +2263,9 @@ xfs_ifree_cluster(
AIL_LOCK(mp,s);
iip->ili_flush_lsn = iip->ili_item.li_lsn;
AIL_UNLOCK(mp, s);
+ spin_lock(&iip->ili_inode->i_flags_lock);
iip->ili_inode->i_flags |= XFS_ISTALE;
+ spin_unlock(&iip->ili_inode->i_flags_lock);
pre_flushed++;
}
lip = lip->li_bio_list;
@@ -2753,19 +2761,29 @@ xfs_iunpin(
* call as the inode reclaim may be blocked waiting for
* the inode to become unpinned.
*/
+ struct inode *inode = NULL;
+
+ spin_lock(&ip->i_flags_lock);
if (!(ip->i_flags & (XFS_IRECLAIM|XFS_IRECLAIMABLE))) {
bhv_vnode_t *vp = XFS_ITOV_NULL(ip);
/* make sync come back and flush this inode */
if (vp) {
- struct inode *inode = vn_to_inode(vp);
+ inode = vn_to_inode(vp);
if (!(inode->i_state &
- (I_NEW|I_FREEING|I_CLEAR)))
- mark_inode_dirty_sync(inode);
+ (I_NEW|I_FREEING|I_CLEAR))) {
+ inode = igrab(inode);
+ if (inode)
+ mark_inode_dirty_sync(inode);
+ } else
+ inode = NULL;
}
}
+ spin_unlock(&ip->i_flags_lock);
wake_up(&ip->i_ipin_wait);
+ if (inode)
+ iput(inode);
}
}
diff --git a/fs/xfs/xfs_inode.h b/fs/xfs/xfs_inode.h
index d10b76ed1e5b..e96eb0835fe6 100644
--- a/fs/xfs/xfs_inode.h
+++ b/fs/xfs/xfs_inode.h
@@ -267,6 +267,7 @@ typedef struct xfs_inode {
sema_t i_flock; /* inode flush lock */
atomic_t i_pincount; /* inode pin count */
wait_queue_head_t i_ipin_wait; /* inode pinning wait queue */
+ spinlock_t i_flags_lock; /* inode i_flags lock */
#ifdef HAVE_REFCACHE
struct xfs_inode **i_refcache; /* ptr to entry in ref cache */
struct xfs_inode *i_release; /* inode to unref */
@@ -389,11 +390,14 @@ typedef struct xfs_inode {
(((vfsp)->vfs_flag & VFS_GRPID) || ((pip)->i_d.di_mode & S_ISGID))
/*
- * xfs_iget.c prototypes.
+ * Flags for xfs_iget()
*/
+#define XFS_IGET_CREATE 0x1
+#define XFS_IGET_BULKSTAT 0x2
-#define IGET_CREATE 1
-
+/*
+ * xfs_iget.c prototypes.
+ */
void xfs_ihash_init(struct xfs_mount *);
void xfs_ihash_free(struct xfs_mount *);
void xfs_chash_init(struct xfs_mount *);
@@ -425,7 +429,7 @@ int xfs_itobp(struct xfs_mount *, struct xfs_trans *,
xfs_inode_t *, xfs_dinode_t **, struct xfs_buf **,
xfs_daddr_t, uint);
int xfs_iread(struct xfs_mount *, struct xfs_trans *, xfs_ino_t,
- xfs_inode_t **, xfs_daddr_t);
+ xfs_inode_t **, xfs_daddr_t, uint);
int xfs_iread_extents(struct xfs_trans *, xfs_inode_t *, int);
int xfs_ialloc(struct xfs_trans *, xfs_inode_t *, mode_t,
xfs_nlink_t, xfs_dev_t, struct cred *, xfs_prid_t,
diff --git a/fs/xfs/xfs_inode_item.c b/fs/xfs/xfs_inode_item.c
index f8e80d8e7237..a7a92251eb56 100644
--- a/fs/xfs/xfs_inode_item.c
+++ b/fs/xfs/xfs_inode_item.c
@@ -743,21 +743,6 @@ xfs_inode_item_committed(
}
/*
- * The transaction with the inode locked has aborted. The inode
- * must not be dirty within the transaction (unless we're forcibly
- * shutting down). We simply unlock just as if the transaction
- * had been cancelled.
- */
-STATIC void
-xfs_inode_item_abort(
- xfs_inode_log_item_t *iip)
-{
- xfs_inode_item_unlock(iip);
- return;
-}
-
-
-/*
* This gets called by xfs_trans_push_ail(), when IOP_TRYLOCK
* failed to get the inode flush lock but did get the inode locked SHARED.
* Here we're trying to see if the inode buffer is incore, and if so whether it's
@@ -915,7 +900,6 @@ STATIC struct xfs_item_ops xfs_inode_item_ops = {
.iop_committed = (xfs_lsn_t(*)(xfs_log_item_t*, xfs_lsn_t))
xfs_inode_item_committed,
.iop_push = (void(*)(xfs_log_item_t*))xfs_inode_item_push,
- .iop_abort = (void(*)(xfs_log_item_t*))xfs_inode_item_abort,
.iop_pushbuf = (void(*)(xfs_log_item_t*))xfs_inode_item_pushbuf,
.iop_committing = (void(*)(xfs_log_item_t*, xfs_lsn_t))
xfs_inode_item_committing
diff --git a/fs/xfs/xfs_inode_item.h b/fs/xfs/xfs_inode_item.h
index 5db6cd1b4cf3..bfe92ea17952 100644
--- a/fs/xfs/xfs_inode_item.h
+++ b/fs/xfs/xfs_inode_item.h
@@ -25,52 +25,54 @@
* must be added on to the end.
*/
typedef struct xfs_inode_log_format {
- unsigned short ilf_type; /* inode log item type */
- unsigned short ilf_size; /* size of this item */
- uint ilf_fields; /* flags for fields logged */
- ushort ilf_asize; /* size of attr d/ext/root */
- ushort ilf_dsize; /* size of data/ext/root */
- xfs_ino_t ilf_ino; /* inode number */
+ __uint16_t ilf_type; /* inode log item type */
+ __uint16_t ilf_size; /* size of this item */
+ __uint32_t ilf_fields; /* flags for fields logged */
+ __uint16_t ilf_asize; /* size of attr d/ext/root */
+ __uint16_t ilf_dsize; /* size of data/ext/root */
+ __uint64_t ilf_ino; /* inode number */
union {
- xfs_dev_t ilfu_rdev; /* rdev value for dev inode*/
+ __uint32_t ilfu_rdev; /* rdev value for dev inode*/
uuid_t ilfu_uuid; /* mount point value */
} ilf_u;
__int64_t ilf_blkno; /* blkno of inode buffer */
- int ilf_len; /* len of inode buffer */
- int ilf_boffset; /* off of inode in buffer */
+ __int32_t ilf_len; /* len of inode buffer */
+ __int32_t ilf_boffset; /* off of inode in buffer */
} xfs_inode_log_format_t;
+#ifndef HAVE_FORMAT32
typedef struct xfs_inode_log_format_32 {
- unsigned short ilf_type; /* 16: inode log item type */
- unsigned short ilf_size; /* 16: size of this item */
- uint ilf_fields; /* 32: flags for fields logged */
- ushort ilf_asize; /* 32: size of attr d/ext/root */
- ushort ilf_dsize; /* 32: size of data/ext/root */
- xfs_ino_t ilf_ino; /* 64: inode number */
+ __uint16_t ilf_type; /* inode log item type */
+ __uint16_t ilf_size; /* size of this item */
+ __uint32_t ilf_fields; /* flags for fields logged */
+ __uint16_t ilf_asize; /* size of attr d/ext/root */
+ __uint16_t ilf_dsize; /* size of data/ext/root */
+ __uint64_t ilf_ino; /* inode number */
union {
- xfs_dev_t ilfu_rdev; /* 32: rdev value for dev inode*/
- uuid_t ilfu_uuid; /* 128: mount point value */
+ __uint32_t ilfu_rdev; /* rdev value for dev inode*/
+ uuid_t ilfu_uuid; /* mount point value */
} ilf_u;
- __int64_t ilf_blkno; /* 64: blkno of inode buffer */
- int ilf_len; /* 32: len of inode buffer */
- int ilf_boffset; /* 32: off of inode in buffer */
+ __int64_t ilf_blkno; /* blkno of inode buffer */
+ __int32_t ilf_len; /* len of inode buffer */
+ __int32_t ilf_boffset; /* off of inode in buffer */
} __attribute__((packed)) xfs_inode_log_format_32_t;
+#endif
typedef struct xfs_inode_log_format_64 {
- unsigned short ilf_type; /* 16: inode log item type */
- unsigned short ilf_size; /* 16: size of this item */
- uint ilf_fields; /* 32: flags for fields logged */
- ushort ilf_asize; /* 32: size of attr d/ext/root */
- ushort ilf_dsize; /* 32: size of data/ext/root */
- __uint32_t ilf_pad; /* 32: pad for 64 bit boundary */
- xfs_ino_t ilf_ino; /* 64: inode number */
+ __uint16_t ilf_type; /* inode log item type */
+ __uint16_t ilf_size; /* size of this item */
+ __uint32_t ilf_fields; /* flags for fields logged */
+ __uint16_t ilf_asize; /* size of attr d/ext/root */
+ __uint16_t ilf_dsize; /* size of data/ext/root */
+ __uint32_t ilf_pad; /* pad for 64 bit boundary */
+ __uint64_t ilf_ino; /* inode number */
union {
- xfs_dev_t ilfu_rdev; /* 32: rdev value for dev inode*/
- uuid_t ilfu_uuid; /* 128: mount point value */
+ __uint32_t ilfu_rdev; /* rdev value for dev inode*/
+ uuid_t ilfu_uuid; /* mount point value */
} ilf_u;
- __int64_t ilf_blkno; /* 64: blkno of inode buffer */
- int ilf_len; /* 32: len of inode buffer */
- int ilf_boffset; /* 32: off of inode in buffer */
+ __int64_t ilf_blkno; /* blkno of inode buffer */
+ __int32_t ilf_len; /* len of inode buffer */
+ __int32_t ilf_boffset; /* off of inode in buffer */
} xfs_inode_log_format_64_t;
/*
diff --git a/fs/xfs/xfs_iomap.c b/fs/xfs/xfs_iomap.c
index f1949c16df15..19655124da78 100644
--- a/fs/xfs/xfs_iomap.c
+++ b/fs/xfs/xfs_iomap.c
@@ -398,6 +398,23 @@ xfs_flush_space(
return 1;
}
+STATIC int
+xfs_cmn_err_fsblock_zero(
+ xfs_inode_t *ip,
+ xfs_bmbt_irec_t *imap)
+{
+ xfs_cmn_err(XFS_PTAG_FSBLOCK_ZERO, CE_ALERT, ip->i_mount,
+ "Access to block zero in inode %llu "
+ "start_block: %llx start_off: %llx "
+ "blkcnt: %llx extent-state: %x\n",
+ (unsigned long long)ip->i_ino,
+ (unsigned long long)imap->br_startblock,
+ (unsigned long long)imap->br_startoff,
+ (unsigned long long)imap->br_blockcount,
+ imap->br_state);
+ return EFSCORRUPTED;
+}
+
int
xfs_iomap_write_direct(
xfs_inode_t *ip,
@@ -536,23 +553,17 @@ xfs_iomap_write_direct(
* Copy any maps to caller's array and return any error.
*/
if (nimaps == 0) {
- error = (ENOSPC);
+ error = ENOSPC;
+ goto error_out;
+ }
+
+ if (unlikely(!imap.br_startblock && !(io->io_flags & XFS_IOCORE_RT))) {
+ error = xfs_cmn_err_fsblock_zero(ip, &imap);
goto error_out;
}
*ret_imap = imap;
*nmaps = 1;
- if ( !(io->io_flags & XFS_IOCORE_RT) && !ret_imap->br_startblock) {
- cmn_err(CE_PANIC,"Access to block zero: fs <%s> inode: %lld "
- "start_block : %llx start_off : %llx blkcnt : %llx "
- "extent-state : %x \n",
- (ip->i_mount)->m_fsname,
- (long long)ip->i_ino,
- (unsigned long long)ret_imap->br_startblock,
- (unsigned long long)ret_imap->br_startoff,
- (unsigned long long)ret_imap->br_blockcount,
- ret_imap->br_state);
- }
return 0;
error0: /* Cancel bmap, unlock inode, unreserve quota blocks, cancel trans */
@@ -715,17 +726,8 @@ retry:
goto retry;
}
- if (!(io->io_flags & XFS_IOCORE_RT) && !ret_imap->br_startblock) {
- cmn_err(CE_PANIC,"Access to block zero: fs <%s> inode: %lld "
- "start_block : %llx start_off : %llx blkcnt : %llx "
- "extent-state : %x \n",
- (ip->i_mount)->m_fsname,
- (long long)ip->i_ino,
- (unsigned long long)ret_imap->br_startblock,
- (unsigned long long)ret_imap->br_startoff,
- (unsigned long long)ret_imap->br_blockcount,
- ret_imap->br_state);
- }
+ if (unlikely(!imap[0].br_startblock && !(io->io_flags & XFS_IOCORE_RT)))
+ return xfs_cmn_err_fsblock_zero(ip, &imap[0]);
*ret_imap = imap[0];
*nmaps = 1;
@@ -853,24 +855,10 @@ xfs_iomap_write_allocate(
* See if we were able to allocate an extent that
* covers at least part of the callers request
*/
-
for (i = 0; i < nimaps; i++) {
- if (!(io->io_flags & XFS_IOCORE_RT) &&
- !imap[i].br_startblock) {
- cmn_err(CE_PANIC,"Access to block zero: "
- "fs <%s> inode: %lld "
- "start_block : %llx start_off : %llx "
- "blkcnt : %llx extent-state : %x \n",
- (ip->i_mount)->m_fsname,
- (long long)ip->i_ino,
- (unsigned long long)
- imap[i].br_startblock,
- (unsigned long long)
- imap[i].br_startoff,
- (unsigned long long)
- imap[i].br_blockcount,
- imap[i].br_state);
- }
+ if (unlikely(!imap[i].br_startblock &&
+ !(io->io_flags & XFS_IOCORE_RT)))
+ return xfs_cmn_err_fsblock_zero(ip, &imap[i]);
if ((offset_fsb >= imap[i].br_startoff) &&
(offset_fsb < (imap[i].br_startoff +
imap[i].br_blockcount))) {
@@ -941,7 +929,7 @@ xfs_iomap_write_unwritten(
XFS_WRITE_LOG_COUNT);
if (error) {
xfs_trans_cancel(tp, 0);
- goto error0;
+ return XFS_ERROR(error);
}
xfs_ilock(ip, XFS_ILOCK_EXCL);
@@ -967,19 +955,11 @@ xfs_iomap_write_unwritten(
error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES, NULL);
xfs_iunlock(ip, XFS_ILOCK_EXCL);
if (error)
- goto error0;
-
- if ( !(io->io_flags & XFS_IOCORE_RT) && !imap.br_startblock) {
- cmn_err(CE_PANIC,"Access to block zero: fs <%s> "
- "inode: %lld start_block : %llx start_off : "
- "%llx blkcnt : %llx extent-state : %x \n",
- (ip->i_mount)->m_fsname,
- (long long)ip->i_ino,
- (unsigned long long)imap.br_startblock,
- (unsigned long long)imap.br_startoff,
- (unsigned long long)imap.br_blockcount,
- imap.br_state);
- }
+ return XFS_ERROR(error);
+
+ if (unlikely(!imap.br_startblock &&
+ !(io->io_flags & XFS_IOCORE_RT)))
+ return xfs_cmn_err_fsblock_zero(ip, &imap);
if ((numblks_fsb = imap.br_blockcount) == 0) {
/*
@@ -999,6 +979,5 @@ error_on_bmapi_transaction:
xfs_bmap_cancel(&free_list);
xfs_trans_cancel(tp, (XFS_TRANS_RELEASE_LOG_RES | XFS_TRANS_ABORT));
xfs_iunlock(ip, XFS_ILOCK_EXCL);
-error0:
return XFS_ERROR(error);
}
diff --git a/fs/xfs/xfs_itable.c b/fs/xfs/xfs_itable.c
index 46249e4d1fea..7775ddc0b3c6 100644
--- a/fs/xfs/xfs_itable.c
+++ b/fs/xfs/xfs_itable.c
@@ -39,6 +39,16 @@
#include "xfs_error.h"
#include "xfs_btree.h"
+int
+xfs_internal_inum(
+ xfs_mount_t *mp,
+ xfs_ino_t ino)
+{
+ return (ino == mp->m_sb.sb_rbmino || ino == mp->m_sb.sb_rsumino ||
+ (XFS_SB_VERSION_HASQUOTA(&mp->m_sb) &&
+ (ino == mp->m_sb.sb_uquotino || ino == mp->m_sb.sb_gquotino)));
+}
+
STATIC int
xfs_bulkstat_one_iget(
xfs_mount_t *mp, /* mount point for filesystem */
@@ -52,7 +62,8 @@ xfs_bulkstat_one_iget(
bhv_vnode_t *vp;
int error;
- error = xfs_iget(mp, NULL, ino, 0, XFS_ILOCK_SHARED, &ip, bno);
+ error = xfs_iget(mp, NULL, ino,
+ XFS_IGET_BULKSTAT, XFS_ILOCK_SHARED, &ip, bno);
if (error) {
*stat = BULKSTAT_RV_NOTHING;
return error;
@@ -212,17 +223,12 @@ xfs_bulkstat_one(
xfs_dinode_t *dip; /* dinode inode pointer */
dip = (xfs_dinode_t *)dibuff;
+ *stat = BULKSTAT_RV_NOTHING;
- if (!buffer || ino == mp->m_sb.sb_rbmino || ino == mp->m_sb.sb_rsumino ||
- (XFS_SB_VERSION_HASQUOTA(&mp->m_sb) &&
- (ino == mp->m_sb.sb_uquotino || ino == mp->m_sb.sb_gquotino))) {
- *stat = BULKSTAT_RV_NOTHING;
+ if (!buffer || xfs_internal_inum(mp, ino))
return XFS_ERROR(EINVAL);
- }
- if (ubsize < sizeof(*buf)) {
- *stat = BULKSTAT_RV_NOTHING;
+ if (ubsize < sizeof(*buf))
return XFS_ERROR(ENOMEM);
- }
buf = kmem_alloc(sizeof(*buf), KM_SLEEP);
@@ -238,8 +244,7 @@ xfs_bulkstat_one(
}
if (copy_to_user(buffer, buf, sizeof(*buf))) {
- *stat = BULKSTAT_RV_NOTHING;
- error = EFAULT;
+ error = EFAULT;
goto out_free;
}
@@ -253,6 +258,46 @@ xfs_bulkstat_one(
}
/*
+ * Test to see whether we can use the ondisk inode directly, based
+ * on the given bulkstat flags, filling in dipp accordingly.
+ * Returns zero if the inode is dodgey.
+ */
+STATIC int
+xfs_bulkstat_use_dinode(
+ xfs_mount_t *mp,
+ int flags,
+ xfs_buf_t *bp,
+ int clustidx,
+ xfs_dinode_t **dipp)
+{
+ xfs_dinode_t *dip;
+ unsigned int aformat;
+
+ *dipp = NULL;
+ if (!bp || (flags & BULKSTAT_FG_IGET))
+ return 1;
+ dip = (xfs_dinode_t *)
+ xfs_buf_offset(bp, clustidx << mp->m_sb.sb_inodelog);
+ if (INT_GET(dip->di_core.di_magic, ARCH_CONVERT) != XFS_DINODE_MAGIC ||
+ !XFS_DINODE_GOOD_VERSION(
+ INT_GET(dip->di_core.di_version, ARCH_CONVERT)))
+ return 0;
+ if (flags & BULKSTAT_FG_QUICK) {
+ *dipp = dip;
+ return 1;
+ }
+ /* BULKSTAT_FG_INLINE: if attr fork is local, or not there, use it */
+ aformat = INT_GET(dip->di_core.di_aformat, ARCH_CONVERT);
+ if ((XFS_CFORK_Q(&dip->di_core) == 0) ||
+ (aformat == XFS_DINODE_FMT_LOCAL) ||
+ (aformat == XFS_DINODE_FMT_EXTENTS && !dip->di_core.di_anextents)) {
+ *dipp = dip;
+ return 1;
+ }
+ return 1;
+}
+
+/*
* Return stat information in bulk (by-inode) for the filesystem.
*/
int /* error status */
@@ -284,10 +329,11 @@ xfs_bulkstat(
xfs_agino_t gino; /* current btree rec's start inode */
int i; /* loop index */
int icount; /* count of inodes good in irbuf */
+ size_t irbsize; /* size of irec buffer in bytes */
xfs_ino_t ino; /* inode number (filesystem) */
- xfs_inobt_rec_t *irbp; /* current irec buffer pointer */
- xfs_inobt_rec_t *irbuf; /* start of irec buffer */
- xfs_inobt_rec_t *irbufend; /* end of good irec buffer entries */
+ xfs_inobt_rec_incore_t *irbp; /* current irec buffer pointer */
+ xfs_inobt_rec_incore_t *irbuf; /* start of irec buffer */
+ xfs_inobt_rec_incore_t *irbufend; /* end of good irec buffer entries */
xfs_ino_t lastino=0; /* last inode number returned */
int nbcluster; /* # of blocks in a cluster */
int nicluster; /* # of inodes in a cluster */
@@ -328,13 +374,10 @@ xfs_bulkstat(
(XFS_INODE_CLUSTER_SIZE(mp) >> mp->m_sb.sb_inodelog);
nimask = ~(nicluster - 1);
nbcluster = nicluster >> mp->m_sb.sb_inopblog;
- /*
- * Allocate a page-sized buffer for inode btree records.
- * We could try allocating something smaller, but for normal
- * calls we'll always (potentially) need the whole page.
- */
- irbuf = kmem_alloc(NBPC, KM_SLEEP);
- nirbuf = NBPC / sizeof(*irbuf);
+ irbuf = kmem_zalloc_greedy(&irbsize, NBPC, NBPC * 4,
+ KM_SLEEP | KM_MAYFAIL | KM_LARGE);
+ nirbuf = irbsize / sizeof(*irbuf);
+
/*
* Loop over the allocation groups, starting from the last
* inode returned; 0 means start of the allocation group.
@@ -358,7 +401,7 @@ xfs_bulkstat(
* Allocate and initialize a btree cursor for ialloc btree.
*/
cur = xfs_btree_init_cursor(mp, NULL, agbp, agno, XFS_BTNUM_INO,
- (xfs_inode_t *)0, 0);
+ (xfs_inode_t *)0, 0);
irbp = irbuf;
irbufend = irbuf + nirbuf;
end_of_ag = 0;
@@ -395,9 +438,9 @@ xfs_bulkstat(
gcnt++;
}
gfree |= XFS_INOBT_MASKN(0, chunkidx);
- INT_SET(irbp->ir_startino, ARCH_CONVERT, gino);
- INT_SET(irbp->ir_freecount, ARCH_CONVERT, gcnt);
- INT_SET(irbp->ir_free, ARCH_CONVERT, gfree);
+ irbp->ir_startino = gino;
+ irbp->ir_freecount = gcnt;
+ irbp->ir_free = gfree;
irbp++;
agino = gino + XFS_INODES_PER_CHUNK;
icount = XFS_INODES_PER_CHUNK - gcnt;
@@ -451,11 +494,27 @@ xfs_bulkstat(
}
/*
* If this chunk has any allocated inodes, save it.
+ * Also start read-ahead now for this chunk.
*/
if (gcnt < XFS_INODES_PER_CHUNK) {
- INT_SET(irbp->ir_startino, ARCH_CONVERT, gino);
- INT_SET(irbp->ir_freecount, ARCH_CONVERT, gcnt);
- INT_SET(irbp->ir_free, ARCH_CONVERT, gfree);
+ /*
+ * Loop over all clusters in the next chunk.
+ * Do a readahead if there are any allocated
+ * inodes in that cluster.
+ */
+ for (agbno = XFS_AGINO_TO_AGBNO(mp, gino),
+ chunkidx = 0;
+ chunkidx < XFS_INODES_PER_CHUNK;
+ chunkidx += nicluster,
+ agbno += nbcluster) {
+ if (XFS_INOBT_MASKN(chunkidx,
+ nicluster) & ~gfree)
+ xfs_btree_reada_bufs(mp, agno,
+ agbno, nbcluster);
+ }
+ irbp->ir_startino = gino;
+ irbp->ir_freecount = gcnt;
+ irbp->ir_free = gfree;
irbp++;
icount += XFS_INODES_PER_CHUNK - gcnt;
}
@@ -479,33 +538,11 @@ xfs_bulkstat(
for (irbp = irbuf;
irbp < irbufend && ubleft >= statstruct_size; irbp++) {
/*
- * Read-ahead the next chunk's worth of inodes.
- */
- if (&irbp[1] < irbufend) {
- /*
- * Loop over all clusters in the next chunk.
- * Do a readahead if there are any allocated
- * inodes in that cluster.
- */
- for (agbno = XFS_AGINO_TO_AGBNO(mp,
- INT_GET(irbp[1].ir_startino, ARCH_CONVERT)),
- chunkidx = 0;
- chunkidx < XFS_INODES_PER_CHUNK;
- chunkidx += nicluster,
- agbno += nbcluster) {
- if (XFS_INOBT_MASKN(chunkidx,
- nicluster) &
- ~(INT_GET(irbp[1].ir_free, ARCH_CONVERT)))
- xfs_btree_reada_bufs(mp, agno,
- agbno, nbcluster);
- }
- }
- /*
* Now process this chunk of inodes.
*/
- for (agino = INT_GET(irbp->ir_startino, ARCH_CONVERT), chunkidx = 0, clustidx = 0;
+ for (agino = irbp->ir_startino, chunkidx = clustidx = 0;
ubleft > 0 &&
- INT_GET(irbp->ir_freecount, ARCH_CONVERT) < XFS_INODES_PER_CHUNK;
+ irbp->ir_freecount < XFS_INODES_PER_CHUNK;
chunkidx++, clustidx++, agino++) {
ASSERT(chunkidx < XFS_INODES_PER_CHUNK);
/*
@@ -525,11 +562,12 @@ xfs_bulkstat(
*/
if ((chunkidx & (nicluster - 1)) == 0) {
agbno = XFS_AGINO_TO_AGBNO(mp,
- INT_GET(irbp->ir_startino, ARCH_CONVERT)) +
+ irbp->ir_startino) +
((chunkidx & nimask) >>
mp->m_sb.sb_inopblog);
- if (flags & BULKSTAT_FG_QUICK) {
+ if (flags & (BULKSTAT_FG_QUICK |
+ BULKSTAT_FG_INLINE)) {
ino = XFS_AGINO_TO_INO(mp, agno,
agino);
bno = XFS_AGB_TO_DADDR(mp, agno,
@@ -543,6 +581,7 @@ xfs_bulkstat(
KM_SLEEP);
ip->i_ino = ino;
ip->i_mount = mp;
+ spin_lock_init(&ip->i_flags_lock);
if (bp)
xfs_buf_relse(bp);
error = xfs_itobp(mp, NULL, ip,
@@ -564,30 +603,34 @@ xfs_bulkstat(
/*
* Skip if this inode is free.
*/
- if (XFS_INOBT_MASK(chunkidx) & INT_GET(irbp->ir_free, ARCH_CONVERT))
+ if (XFS_INOBT_MASK(chunkidx) & irbp->ir_free)
continue;
/*
* Count used inodes as free so we can tell
* when the chunk is used up.
*/
- INT_MOD(irbp->ir_freecount, ARCH_CONVERT, +1);
+ irbp->ir_freecount++;
ino = XFS_AGINO_TO_INO(mp, agno, agino);
bno = XFS_AGB_TO_DADDR(mp, agno, agbno);
- if (flags & BULKSTAT_FG_QUICK) {
- dip = (xfs_dinode_t *)xfs_buf_offset(bp,
- (clustidx << mp->m_sb.sb_inodelog));
-
- if (INT_GET(dip->di_core.di_magic, ARCH_CONVERT)
- != XFS_DINODE_MAGIC
- || !XFS_DINODE_GOOD_VERSION(
- INT_GET(dip->di_core.di_version, ARCH_CONVERT)))
- continue;
+ if (!xfs_bulkstat_use_dinode(mp, flags, bp,
+ clustidx, &dip))
+ continue;
+ /*
+ * If we need to do an iget, cannot hold bp.
+ * Drop it, until starting the next cluster.
+ */
+ if ((flags & BULKSTAT_FG_INLINE) && !dip) {
+ if (bp)
+ xfs_buf_relse(bp);
+ bp = NULL;
}
/*
* Get the inode and fill in a single buffer.
* BULKSTAT_FG_QUICK uses dip to fill it in.
* BULKSTAT_FG_IGET uses igets.
+ * BULKSTAT_FG_INLINE uses dip if we have an
+ * inline attr fork, else igets.
* See: xfs_bulkstat_one & xfs_dm_bulkstat_one.
* This is also used to count inodes/blks, etc
* in xfs_qm_quotacheck.
@@ -597,8 +640,15 @@ xfs_bulkstat(
ubleft, private_data,
bno, &ubused, dip, &fmterror);
if (fmterror == BULKSTAT_RV_NOTHING) {
- if (error == ENOMEM)
+ if (error == EFAULT) {
+ ubleft = 0;
+ rval = error;
+ break;
+ }
+ else if (error == ENOMEM)
ubleft = 0;
+ else
+ lastino = ino;
continue;
}
if (fmterror == BULKSTAT_RV_GIVEUP) {
@@ -633,7 +683,7 @@ xfs_bulkstat(
/*
* Done, we're either out of filesystem or space to put the data.
*/
- kmem_free(irbuf, NBPC);
+ kmem_free(irbuf, irbsize);
*ubcountp = ubelem;
if (agno >= mp->m_sb.sb_agcount) {
/*
diff --git a/fs/xfs/xfs_itable.h b/fs/xfs/xfs_itable.h
index be5f12e07d22..f25a28862a17 100644
--- a/fs/xfs/xfs_itable.h
+++ b/fs/xfs/xfs_itable.h
@@ -36,15 +36,16 @@ typedef int (*bulkstat_one_pf)(struct xfs_mount *mp,
/*
* Values for stat return value.
*/
-#define BULKSTAT_RV_NOTHING 0
-#define BULKSTAT_RV_DIDONE 1
-#define BULKSTAT_RV_GIVEUP 2
+#define BULKSTAT_RV_NOTHING 0
+#define BULKSTAT_RV_DIDONE 1
+#define BULKSTAT_RV_GIVEUP 2
/*
* Values for bulkstat flag argument.
*/
-#define BULKSTAT_FG_IGET 0x1 /* Go through the buffer cache */
-#define BULKSTAT_FG_QUICK 0x2 /* No iget, walk the dinode cluster */
+#define BULKSTAT_FG_IGET 0x1 /* Go through the buffer cache */
+#define BULKSTAT_FG_QUICK 0x2 /* No iget, walk the dinode cluster */
+#define BULKSTAT_FG_INLINE 0x4 /* No iget if inline attrs */
/*
* Return stat information in bulk (by-inode) for the filesystem.
@@ -80,6 +81,11 @@ xfs_bulkstat_one(
void *dibuff,
int *stat);
+int
+xfs_internal_inum(
+ xfs_mount_t *mp,
+ xfs_ino_t ino);
+
int /* error status */
xfs_inumbers(
xfs_mount_t *mp, /* mount point for filesystem */
diff --git a/fs/xfs/xfs_log.c b/fs/xfs/xfs_log.c
index 21ac1a67e3e0..c48bf61f17bd 100644
--- a/fs/xfs/xfs_log.c
+++ b/fs/xfs/xfs_log.c
@@ -617,7 +617,8 @@ xfs_log_unmount_write(xfs_mount_t *mp)
reg[0].i_len = sizeof(magic);
XLOG_VEC_SET_TYPE(&reg[0], XLOG_REG_TYPE_UNMOUNT);
- error = xfs_log_reserve(mp, 600, 1, &tic, XFS_LOG, 0, 0);
+ error = xfs_log_reserve(mp, 600, 1, &tic,
+ XFS_LOG, 0, XLOG_UNMOUNT_REC_TYPE);
if (!error) {
/* remove inited flag */
((xlog_ticket_t *)tic)->t_flags = 0;
@@ -655,8 +656,11 @@ xfs_log_unmount_write(xfs_mount_t *mp)
} else {
LOG_UNLOCK(log, s);
}
- if (tic)
+ if (tic) {
+ xlog_trace_loggrant(log, tic, "unmount rec");
+ xlog_ungrant_log_space(log, tic);
xlog_state_put_ticket(log, tic);
+ }
} else {
/*
* We're already in forced_shutdown mode, couldn't
@@ -1196,7 +1200,7 @@ xlog_alloc_log(xfs_mount_t *mp,
kmem_zalloc(sizeof(xlog_in_core_t), KM_SLEEP);
iclog = *iclogp;
iclog->hic_data = (xlog_in_core_2_t *)
- kmem_zalloc(iclogsize, KM_SLEEP);
+ kmem_zalloc(iclogsize, KM_SLEEP | KM_LARGE);
iclog->ic_prev = prev_iclog;
prev_iclog = iclog;
@@ -2212,9 +2216,13 @@ xlog_state_do_callback(
iclog = iclog->ic_next;
} while (first_iclog != iclog);
- if (repeats && (repeats % 10) == 0) {
+
+ if (repeats > 5000) {
+ flushcnt += repeats;
+ repeats = 0;
xfs_fs_cmn_err(CE_WARN, log->l_mp,
- "xlog_state_do_callback: looping %d", repeats);
+ "%s: possible infinite loop (%d iterations)",
+ __FUNCTION__, flushcnt);
}
} while (!ioerrors && loopdidcallbacks);
@@ -2246,6 +2254,7 @@ xlog_state_do_callback(
}
#endif
+ flushcnt = 0;
if (log->l_iclog->ic_state & (XLOG_STATE_ACTIVE|XLOG_STATE_IOERROR)) {
flushcnt = log->l_flushcnt;
log->l_flushcnt = 0;
diff --git a/fs/xfs/xfs_log.h b/fs/xfs/xfs_log.h
index eacb3d4987f2..ebbe93f4f97b 100644
--- a/fs/xfs/xfs_log.h
+++ b/fs/xfs/xfs_log.h
@@ -48,16 +48,10 @@ static inline xfs_lsn_t _lsn_cmp(xfs_lsn_t lsn1, xfs_lsn_t lsn2)
*/
/*
- * Flags to xfs_log_mount
- */
-#define XFS_LOG_RECOVER 0x1
-
-/*
* Flags to xfs_log_done()
*/
#define XFS_LOG_REL_PERM_RESERV 0x1
-
/*
* Flags to xfs_log_reserve()
*
@@ -70,8 +64,6 @@ static inline xfs_lsn_t _lsn_cmp(xfs_lsn_t lsn1, xfs_lsn_t lsn2)
#define XFS_LOG_SLEEP 0x0
#define XFS_LOG_NOSLEEP 0x1
#define XFS_LOG_PERM_RESERV 0x2
-#define XFS_LOG_RESV_ALL (XFS_LOG_NOSLEEP|XFS_LOG_PERM_RESERV)
-
/*
* Flags to xfs_log_force()
diff --git a/fs/xfs/xfs_log_priv.h b/fs/xfs/xfs_log_priv.h
index 34bcbf50789c..9bd3cdf11a87 100644
--- a/fs/xfs/xfs_log_priv.h
+++ b/fs/xfs/xfs_log_priv.h
@@ -32,7 +32,6 @@ struct xfs_mount;
#define XLOG_MIN_ICLOGS 2
#define XLOG_MED_ICLOGS 4
#define XLOG_MAX_ICLOGS 8
-#define XLOG_CALLBACK_SIZE 10
#define XLOG_HEADER_MAGIC_NUM 0xFEEDbabe /* Invalid cycle number */
#define XLOG_VERSION_1 1
#define XLOG_VERSION_2 2 /* Large IClogs, Log sunit */
@@ -149,9 +148,6 @@ struct xfs_mount;
#define XLOG_WAS_CONT_TRANS 0x08 /* Cont this trans into new region */
#define XLOG_END_TRANS 0x10 /* End a continued transaction */
#define XLOG_UNMOUNT_TRANS 0x20 /* Unmount a filesystem transaction */
-#define XLOG_SKIP_TRANS (XLOG_COMMIT_TRANS | XLOG_CONTINUE_TRANS | \
- XLOG_WAS_CONT_TRANS | XLOG_END_TRANS | \
- XLOG_UNMOUNT_TRANS)
#ifdef __KERNEL__
/*
@@ -506,6 +502,12 @@ extern int xlog_bread(xlog_t *, xfs_daddr_t, int, struct xfs_buf *);
#define XLOG_TRACE_SLEEP_FLUSH 3
#define XLOG_TRACE_WAKE_FLUSH 4
+/*
+ * Unmount record type is used as a pseudo transaction type for the ticket.
+ * It's value must be outside the range of XFS_TRANS_* values.
+ */
+#define XLOG_UNMOUNT_REC_TYPE (-1U)
+
#endif /* __KERNEL__ */
#endif /* __XFS_LOG_PRIV_H__ */
diff --git a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h
index b2bd4be4200a..e5f396ff9a3d 100644
--- a/fs/xfs/xfs_mount.h
+++ b/fs/xfs/xfs_mount.h
@@ -331,7 +331,7 @@ typedef struct xfs_mount {
xfs_agnumber_t m_agirotor; /* last ag dir inode alloced */
lock_t m_agirotor_lock;/* .. and lock protecting it */
xfs_agnumber_t m_maxagi; /* highest inode alloc group */
- uint m_ihsize; /* size of next field */
+ size_t m_ihsize; /* size of next field */
struct xfs_ihash *m_ihash; /* fs private inode hash table*/
struct xfs_inode *m_inodes; /* active inode list */
struct list_head m_del_inodes; /* inodes to reclaim */
@@ -541,7 +541,8 @@ static inline xfs_mount_t *xfs_bhvtom(bhv_desc_t *bdp)
#define XFS_VFSTOM(vfs) xfs_vfstom(vfs)
static inline xfs_mount_t *xfs_vfstom(bhv_vfs_t *vfs)
{
- return XFS_BHVTOM(bhv_lookup(VFS_BHVHEAD(vfs), &xfs_vfsops));
+ return XFS_BHVTOM(bhv_lookup_range(VFS_BHVHEAD(vfs),
+ VFS_POSITION_XFS, VFS_POSITION_XFS));
}
#define XFS_DADDR_TO_AGNO(mp,d) xfs_daddr_to_agno(mp,d)
diff --git a/fs/xfs/xfs_quota.h b/fs/xfs/xfs_quota.h
index acb853b33ebb..9dcb32aa4e2e 100644
--- a/fs/xfs/xfs_quota.h
+++ b/fs/xfs/xfs_quota.h
@@ -281,8 +281,6 @@ typedef struct xfs_qoff_logformat {
XFS_UQUOTA_CHKD|XFS_PQUOTA_ACCT|\
XFS_OQUOTA_ENFD|XFS_OQUOTA_CHKD|\
XFS_GQUOTA_ACCT)
-#define XFS_MOUNT_QUOTA_MASK (XFS_MOUNT_QUOTA_ALL | XFS_UQUOTA_ACTIVE | \
- XFS_GQUOTA_ACTIVE | XFS_PQUOTA_ACTIVE)
/*
diff --git a/fs/xfs/xfs_rtalloc.c b/fs/xfs/xfs_rtalloc.c
index 5a0b678956e0..880c73271c05 100644
--- a/fs/xfs/xfs_rtalloc.c
+++ b/fs/xfs/xfs_rtalloc.c
@@ -1948,7 +1948,7 @@ xfs_growfs_rt(
*/
nrextents = nrblocks;
do_div(nrextents, in->extsize);
- nrbmblocks = roundup_64(nrextents, NBBY * sbp->sb_blocksize);
+ nrbmblocks = howmany_64(nrextents, NBBY * sbp->sb_blocksize);
nrextslog = xfs_highbit32(nrextents);
nrsumlevels = nrextslog + 1;
nrsumsize = (uint)sizeof(xfs_suminfo_t) * nrsumlevels * nrbmblocks;
@@ -1976,7 +1976,10 @@ xfs_growfs_rt(
if ((error = xfs_growfs_rt_alloc(mp, rsumblocks, nrsumblocks,
mp->m_sb.sb_rsumino)))
return error;
- nmp = NULL;
+ /*
+ * Allocate a new (fake) mount/sb.
+ */
+ nmp = kmem_alloc(sizeof(*nmp), KM_SLEEP);
/*
* Loop over the bitmap blocks.
* We will do everything one bitmap block at a time.
@@ -1987,10 +1990,6 @@ xfs_growfs_rt(
((sbp->sb_rextents & ((1 << mp->m_blkbit_log) - 1)) != 0);
bmbno < nrbmblocks;
bmbno++) {
- /*
- * Allocate a new (fake) mount/sb.
- */
- nmp = kmem_alloc(sizeof(*nmp), KM_SLEEP);
*nmp = *mp;
nsbp = &nmp->m_sb;
/*
@@ -2018,13 +2017,13 @@ xfs_growfs_rt(
cancelflags = 0;
if ((error = xfs_trans_reserve(tp, 0,
XFS_GROWRTFREE_LOG_RES(nmp), 0, 0, 0)))
- goto error_exit;
+ break;
/*
* Lock out other callers by grabbing the bitmap inode lock.
*/
if ((error = xfs_trans_iget(mp, tp, mp->m_sb.sb_rbmino, 0,
XFS_ILOCK_EXCL, &ip)))
- goto error_exit;
+ break;
ASSERT(ip == mp->m_rbmip);
/*
* Update the bitmap inode's size.
@@ -2038,7 +2037,7 @@ xfs_growfs_rt(
*/
if ((error = xfs_trans_iget(mp, tp, mp->m_sb.sb_rsumino, 0,
XFS_ILOCK_EXCL, &ip)))
- goto error_exit;
+ break;
ASSERT(ip == mp->m_rsumip);
/*
* Update the summary inode's size.
@@ -2053,7 +2052,7 @@ xfs_growfs_rt(
mp->m_rsumlevels != nmp->m_rsumlevels) {
error = xfs_rtcopy_summary(mp, nmp, tp);
if (error)
- goto error_exit;
+ break;
}
/*
* Update superblock fields.
@@ -2080,18 +2079,13 @@ xfs_growfs_rt(
error = xfs_rtfree_range(nmp, tp, sbp->sb_rextents,
nsbp->sb_rextents - sbp->sb_rextents, &bp, &sumbno);
if (error)
- goto error_exit;
+ break;
/*
* Mark more blocks free in the superblock.
*/
xfs_trans_mod_sb(tp, XFS_TRANS_SB_FREXTENTS,
nsbp->sb_rextents - sbp->sb_rextents);
/*
- * Free the fake mp structure.
- */
- kmem_free(nmp, sizeof(*nmp));
- nmp = NULL;
- /*
* Update mp values into the real mp structure.
*/
mp->m_rsumlevels = nrsumlevels;
@@ -2101,15 +2095,15 @@ xfs_growfs_rt(
*/
xfs_trans_commit(tp, 0, NULL);
}
- return 0;
+
+ if (error)
+ xfs_trans_cancel(tp, cancelflags);
/*
- * Error paths come here.
+ * Free the fake mp structure.
*/
-error_exit:
- if (nmp)
- kmem_free(nmp, sizeof(*nmp));
- xfs_trans_cancel(tp, cancelflags);
+ kmem_free(nmp, sizeof(*nmp));
+
return error;
}
diff --git a/fs/xfs/xfs_sb.h b/fs/xfs/xfs_sb.h
index bf168a91ddb8..467854b45c8f 100644
--- a/fs/xfs/xfs_sb.h
+++ b/fs/xfs/xfs_sb.h
@@ -60,10 +60,6 @@ struct xfs_mount;
XFS_SB_VERSION_LOGV2BIT | \
XFS_SB_VERSION_SECTORBIT | \
XFS_SB_VERSION_MOREBITSBIT)
-#define XFS_SB_VERSION_OKSASHBITS \
- (XFS_SB_VERSION_NUMBITS | \
- XFS_SB_VERSION_REALFBITS | \
- XFS_SB_VERSION_OKSASHFBITS)
#define XFS_SB_VERSION_OKREALBITS \
(XFS_SB_VERSION_NUMBITS | \
XFS_SB_VERSION_OKREALFBITS | \
@@ -81,9 +77,6 @@ struct xfs_mount;
#define XFS_SB_VERSION2_RESERVED2BIT 0x00000002
#define XFS_SB_VERSION2_RESERVED4BIT 0x00000004
#define XFS_SB_VERSION2_ATTR2BIT 0x00000008 /* Inline attr rework */
-#define XFS_SB_VERSION2_SASHFBITS 0xff000000 /* Mask: features that
- require changing
- PROM and SASH */
#define XFS_SB_VERSION2_OKREALFBITS \
(XFS_SB_VERSION2_ATTR2BIT)
@@ -238,12 +231,6 @@ static inline int xfs_sb_good_version(xfs_sb_t *sbp)
}
#endif /* __KERNEL__ */
-#define XFS_SB_GOOD_SASH_VERSION(sbp) \
- ((((sbp)->sb_versionnum >= XFS_SB_VERSION_1) && \
- ((sbp)->sb_versionnum <= XFS_SB_VERSION_3)) || \
- ((XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_4) && \
- !((sbp)->sb_versionnum & ~XFS_SB_VERSION_OKSASHBITS)))
-
#define XFS_SB_VERSION_TONEW(v) xfs_sb_version_tonew(v)
static inline unsigned xfs_sb_version_tonew(unsigned v)
{
@@ -461,15 +448,6 @@ static inline void xfs_sb_version_addattr2(xfs_sb_t *sbp)
* File system sector to basic block conversions.
*/
#define XFS_FSS_TO_BB(mp,sec) ((sec) << (mp)->m_sectbb_log)
-#define XFS_BB_TO_FSS(mp,bb) \
- (((bb) + (XFS_FSS_TO_BB(mp,1) - 1)) >> (mp)->m_sectbb_log)
-#define XFS_BB_TO_FSST(mp,bb) ((bb) >> (mp)->m_sectbb_log)
-
-/*
- * File system sector to byte conversions.
- */
-#define XFS_FSS_TO_B(mp,sectno) ((xfs_fsize_t)(sectno) << (mp)->m_sb.sb_sectlog)
-#define XFS_B_TO_FSST(mp,b) (((__uint64_t)(b)) >> (mp)->m_sb.sb_sectlog)
/*
* File system block to basic block conversions.
diff --git a/fs/xfs/xfs_trans.h b/fs/xfs/xfs_trans.h
index 9dc88b380608..c68e00105d23 100644
--- a/fs/xfs/xfs_trans.h
+++ b/fs/xfs/xfs_trans.h
@@ -149,7 +149,6 @@ typedef struct xfs_item_ops {
void (*iop_unlock)(xfs_log_item_t *);
xfs_lsn_t (*iop_committed)(xfs_log_item_t *, xfs_lsn_t);
void (*iop_push)(xfs_log_item_t *);
- void (*iop_abort)(xfs_log_item_t *);
void (*iop_pushbuf)(xfs_log_item_t *);
void (*iop_committing)(xfs_log_item_t *, xfs_lsn_t);
} xfs_item_ops_t;
@@ -163,7 +162,6 @@ typedef struct xfs_item_ops {
#define IOP_UNLOCK(ip) (*(ip)->li_ops->iop_unlock)(ip)
#define IOP_COMMITTED(ip, lsn) (*(ip)->li_ops->iop_committed)(ip, lsn)
#define IOP_PUSH(ip) (*(ip)->li_ops->iop_push)(ip)
-#define IOP_ABORT(ip) (*(ip)->li_ops->iop_abort)(ip)
#define IOP_PUSHBUF(ip) (*(ip)->li_ops->iop_pushbuf)(ip)
#define IOP_COMMITTING(ip, lsn) (*(ip)->li_ops->iop_committing)(ip, lsn)
diff --git a/fs/xfs/xfs_trans_ail.c b/fs/xfs/xfs_trans_ail.c
index 558c87ff0c41..fc39b166d403 100644
--- a/fs/xfs/xfs_trans_ail.c
+++ b/fs/xfs/xfs_trans_ail.c
@@ -276,7 +276,7 @@ xfs_trans_update_ail(
xfs_mount_t *mp,
xfs_log_item_t *lip,
xfs_lsn_t lsn,
- unsigned long s)
+ unsigned long s) __releases(mp->m_ail_lock)
{
xfs_ail_entry_t *ailp;
xfs_log_item_t *dlip=NULL;
@@ -328,7 +328,7 @@ void
xfs_trans_delete_ail(
xfs_mount_t *mp,
xfs_log_item_t *lip,
- unsigned long s)
+ unsigned long s) __releases(mp->m_ail_lock)
{
xfs_ail_entry_t *ailp;
xfs_log_item_t *dlip;
diff --git a/fs/xfs/xfs_trans_priv.h b/fs/xfs/xfs_trans_priv.h
index 13edab8a9e94..447ac4308c91 100644
--- a/fs/xfs/xfs_trans_priv.h
+++ b/fs/xfs/xfs_trans_priv.h
@@ -46,11 +46,13 @@ xfs_log_busy_slot_t *xfs_trans_add_busy(xfs_trans_t *tp,
/*
* From xfs_trans_ail.c
*/
-void xfs_trans_update_ail(struct xfs_mount *,
- struct xfs_log_item *, xfs_lsn_t,
- unsigned long);
-void xfs_trans_delete_ail(struct xfs_mount *,
- struct xfs_log_item *, unsigned long);
+void xfs_trans_update_ail(struct xfs_mount *mp,
+ struct xfs_log_item *lip, xfs_lsn_t lsn,
+ unsigned long s)
+ __releases(mp->m_ail_lock);
+void xfs_trans_delete_ail(struct xfs_mount *mp,
+ struct xfs_log_item *lip, unsigned long s)
+ __releases(mp->m_ail_lock);
struct xfs_log_item *xfs_trans_first_ail(struct xfs_mount *, int *);
struct xfs_log_item *xfs_trans_next_ail(struct xfs_mount *,
struct xfs_log_item *, int *, int *);
diff --git a/fs/xfs/xfs_vfsops.c b/fs/xfs/xfs_vfsops.c
index a34796e57afb..62336a4cc5a4 100644
--- a/fs/xfs/xfs_vfsops.c
+++ b/fs/xfs/xfs_vfsops.c
@@ -1922,7 +1922,7 @@ xfs_showargs(
}
if (mp->m_flags & XFS_MOUNT_IHASHSIZE)
- seq_printf(m, "," MNTOPT_IHASHSIZE "=%d", mp->m_ihsize);
+ seq_printf(m, "," MNTOPT_IHASHSIZE "=%d", (int)mp->m_ihsize);
if (mp->m_flags & XFS_MOUNT_DFLT_IOSIZE)
seq_printf(m, "," MNTOPT_ALLOCSIZE "=%dk",
diff --git a/fs/xfs/xfs_vnodeops.c b/fs/xfs/xfs_vnodeops.c
index 23cfa5837728..061e2ffdd1de 100644
--- a/fs/xfs/xfs_vnodeops.c
+++ b/fs/xfs/xfs_vnodeops.c
@@ -2366,10 +2366,15 @@ xfs_remove(
namelen = VNAMELEN(dentry);
+ if (!xfs_get_dir_entry(dentry, &ip)) {
+ dm_di_mode = ip->i_d.di_mode;
+ IRELE(ip);
+ }
+
if (DM_EVENT_ENABLED(dir_vp->v_vfsp, dp, DM_EVENT_REMOVE)) {
error = XFS_SEND_NAMESP(mp, DM_EVENT_REMOVE, dir_vp,
DM_RIGHT_NULL, NULL, DM_RIGHT_NULL,
- name, NULL, 0, 0, 0);
+ name, NULL, dm_di_mode, 0, 0);
if (error)
return error;
}
@@ -2995,7 +3000,7 @@ xfs_rmdir(
int cancel_flags;
int committed;
bhv_vnode_t *dir_vp;
- int dm_di_mode = 0;
+ int dm_di_mode = S_IFDIR;
int last_cdp_link;
int namelen;
uint resblks;
@@ -3010,11 +3015,16 @@ xfs_rmdir(
return XFS_ERROR(EIO);
namelen = VNAMELEN(dentry);
+ if (!xfs_get_dir_entry(dentry, &cdp)) {
+ dm_di_mode = cdp->i_d.di_mode;
+ IRELE(cdp);
+ }
+
if (DM_EVENT_ENABLED(dir_vp->v_vfsp, dp, DM_EVENT_REMOVE)) {
error = XFS_SEND_NAMESP(mp, DM_EVENT_REMOVE,
dir_vp, DM_RIGHT_NULL,
NULL, DM_RIGHT_NULL,
- name, NULL, 0, 0, 0);
+ name, NULL, dm_di_mode, 0, 0);
if (error)
return XFS_ERROR(error);
}
@@ -3834,7 +3844,9 @@ xfs_reclaim(
XFS_MOUNT_ILOCK(mp);
vn_bhv_remove(VN_BHV_HEAD(vp), XFS_ITOBHV(ip));
list_add_tail(&ip->i_reclaim, &mp->m_del_inodes);
+ spin_lock(&ip->i_flags_lock);
ip->i_flags |= XFS_IRECLAIMABLE;
+ spin_unlock(&ip->i_flags_lock);
XFS_MOUNT_IUNLOCK(mp);
}
return 0;
@@ -3859,8 +3871,10 @@ xfs_finish_reclaim(
* us.
*/
write_lock(&ih->ih_lock);
+ spin_lock(&ip->i_flags_lock);
if ((ip->i_flags & XFS_IRECLAIM) ||
(!(ip->i_flags & XFS_IRECLAIMABLE) && vp == NULL)) {
+ spin_unlock(&ip->i_flags_lock);
write_unlock(&ih->ih_lock);
if (locked) {
xfs_ifunlock(ip);
@@ -3869,6 +3883,7 @@ xfs_finish_reclaim(
return 1;
}
ip->i_flags |= XFS_IRECLAIM;
+ spin_unlock(&ip->i_flags_lock);
write_unlock(&ih->ih_lock);
/*
@@ -4272,7 +4287,7 @@ xfs_free_file_space(
xfs_mount_t *mp;
int nimap;
uint resblks;
- int rounding;
+ uint rounding;
int rt;
xfs_fileoff_t startoffset_fsb;
xfs_trans_t *tp;
@@ -4313,8 +4328,7 @@ xfs_free_file_space(
vn_iowait(vp); /* wait for the completion of any pending DIOs */
}
- rounding = MAX((__uint8_t)(1 << mp->m_sb.sb_blocklog),
- (__uint8_t)NBPP);
+ rounding = max_t(uint, 1 << mp->m_sb.sb_blocklog, NBPP);
ilen = len + (offset & (rounding - 1));
ioffset = offset & ~(rounding - 1);
if (ilen & (rounding - 1))
diff --git a/include/asm-alpha/spinlock.h b/include/asm-alpha/spinlock.h
index 0c294c9b0c55..aeeb125f6851 100644
--- a/include/asm-alpha/spinlock.h
+++ b/include/asm-alpha/spinlock.h
@@ -166,4 +166,8 @@ static inline void __raw_write_unlock(raw_rwlock_t * lock)
lock->lock = 0;
}
+#define _raw_spin_relax(lock) cpu_relax()
+#define _raw_read_relax(lock) cpu_relax()
+#define _raw_write_relax(lock) cpu_relax()
+
#endif /* _ALPHA_SPINLOCK_H */
diff --git a/include/asm-alpha/unistd.h b/include/asm-alpha/unistd.h
index bc6e6a9259dc..2cabbd465c0c 100644
--- a/include/asm-alpha/unistd.h
+++ b/include/asm-alpha/unistd.h
@@ -580,75 +580,6 @@ type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5, type6 arg6)\
#define __ARCH_WANT_SYS_OLDUMOUNT
#define __ARCH_WANT_SYS_SIGPENDING
-#ifdef __KERNEL_SYSCALLS__
-
-#include <linux/compiler.h>
-#include <linux/types.h>
-#include <linux/string.h>
-#include <linux/signal.h>
-#include <linux/syscalls.h>
-#include <asm/ptrace.h>
-
-static inline long open(const char * name, int mode, int flags)
-{
- return sys_open(name, mode, flags);
-}
-
-static inline long dup(int fd)
-{
- return sys_dup(fd);
-}
-
-static inline long close(int fd)
-{
- return sys_close(fd);
-}
-
-static inline off_t lseek(int fd, off_t off, int whence)
-{
- return sys_lseek(fd, off, whence);
-}
-
-static inline void _exit(int value)
-{
- sys_exit(value);
-}
-
-#define exit(x) _exit(x)
-
-static inline long write(int fd, const char * buf, size_t nr)
-{
- return sys_write(fd, buf, nr);
-}
-
-static inline long read(int fd, char * buf, size_t nr)
-{
- return sys_read(fd, buf, nr);
-}
-
-extern int execve(char *, char **, char **);
-
-static inline long setsid(void)
-{
- return sys_setsid();
-}
-
-static inline pid_t waitpid(int pid, int * wait_stat, int flags)
-{
- return sys_wait4(pid, wait_stat, flags, NULL);
-}
-
-asmlinkage int sys_execve(char *ufilename, char **argv, char **envp,
- unsigned long a3, unsigned long a4, unsigned long a5,
- struct pt_regs regs);
-asmlinkage long sys_rt_sigaction(int sig,
- const struct sigaction __user *act,
- struct sigaction __user *oact,
- size_t sigsetsize,
- void *restorer);
-
-#endif /* __KERNEL_SYSCALLS__ */
-
/* "Conditional" syscalls. What we want is
__attribute__((weak,alias("sys_ni_syscall")))
diff --git a/include/asm-arm/arch-clps711x/time.h b/include/asm-arm/arch-clps711x/time.h
index 9cb27cd4e6ae..0e4a3901d3b3 100644
--- a/include/asm-arm/arch-clps711x/time.h
+++ b/include/asm-arm/arch-clps711x/time.h
@@ -29,7 +29,7 @@ static irqreturn_t
p720t_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
do_leds();
- do_timer(regs);
+ do_timer(1);
#ifndef CONFIG_SMP
update_process_times(user_mode(regs));
#endif
diff --git a/include/asm-arm/arch-l7200/time.h b/include/asm-arm/arch-l7200/time.h
index 7b98b533e63a..c69cb508735f 100644
--- a/include/asm-arm/arch-l7200/time.h
+++ b/include/asm-arm/arch-l7200/time.h
@@ -45,7 +45,7 @@
static irqreturn_t
timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
- do_timer(regs);
+ do_timer(1);
#ifndef CONFIG_SMP
update_process_times(user_mode(regs));
#endif
diff --git a/include/asm-arm/arch-omap/keypad.h b/include/asm-arm/arch-omap/keypad.h
index 8a023a984acb..b7f83075436e 100644
--- a/include/asm-arm/arch-omap/keypad.h
+++ b/include/asm-arm/arch-omap/keypad.h
@@ -14,7 +14,10 @@ struct omap_kp_platform_data {
int rows;
int cols;
int *keymap;
+ unsigned int keymapsize;
unsigned int rep:1;
+ unsigned long delay;
+ unsigned int dbounce:1;
/* specific to OMAP242x*/
unsigned int *row_gpios;
unsigned int *col_gpios;
diff --git a/include/asm-arm/arch-pnx4008/clock.h b/include/asm-arm/arch-pnx4008/clock.h
index 91ae0030fdf2..ce155e161269 100644
--- a/include/asm-arm/arch-pnx4008/clock.h
+++ b/include/asm-arm/arch-pnx4008/clock.h
@@ -32,6 +32,7 @@ struct clk;
#define KEYCLKCTRL_REG (PWRMAN_VA_BASE + 0xb0)
#define TSCLKCTRL_REG (PWRMAN_VA_BASE + 0xb4)
#define PWMCLKCTRL_REG (PWRMAN_VA_BASE + 0xb8)
+#define TIMCLKCTRL_REG (PWRMAN_VA_BASE + 0xbc)
#define SPICTRL_REG (PWRMAN_VA_BASE + 0xc4)
#define FLASHCLKCTRL_REG (PWRMAN_VA_BASE + 0xc8)
#define UART3CLK_REG (PWRMAN_VA_BASE + 0xd0)
diff --git a/include/asm-arm/spinlock.h b/include/asm-arm/spinlock.h
index 01b7c26a3038..861092fbaa53 100644
--- a/include/asm-arm/spinlock.h
+++ b/include/asm-arm/spinlock.h
@@ -218,4 +218,8 @@ static inline int __raw_read_trylock(raw_rwlock_t *rw)
/* read_can_lock - would read_trylock() succeed? */
#define __raw_read_can_lock(x) ((x)->lock < 0x80000000)
+#define _raw_spin_relax(lock) cpu_relax()
+#define _raw_read_relax(lock) cpu_relax()
+#define _raw_write_relax(lock) cpu_relax()
+
#endif /* __ASM_SPINLOCK_H */
diff --git a/include/asm-arm/unistd.h b/include/asm-arm/unistd.h
index 2ab4078334bf..14a87eec5a2d 100644
--- a/include/asm-arm/unistd.h
+++ b/include/asm-arm/unistd.h
@@ -549,30 +549,6 @@ type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5, type6 arg6
#define __ARCH_WANT_SYS_SOCKETCALL
#endif
-#ifdef __KERNEL_SYSCALLS__
-
-#include <linux/compiler.h>
-#include <linux/types.h>
-#include <linux/syscalls.h>
-
-extern long execve(const char *file, char **argv, char **envp);
-
-struct pt_regs;
-asmlinkage int sys_execve(char *filenamei, char **argv, char **envp,
- struct pt_regs *regs);
-asmlinkage int sys_clone(unsigned long clone_flags, unsigned long newsp,
- struct pt_regs *regs);
-asmlinkage int sys_fork(struct pt_regs *regs);
-asmlinkage int sys_vfork(struct pt_regs *regs);
-asmlinkage int sys_pipe(unsigned long *fildes);
-struct sigaction;
-asmlinkage long sys_rt_sigaction(int sig,
- const struct sigaction __user *act,
- struct sigaction __user *oact,
- size_t sigsetsize);
-
-#endif /* __KERNEL_SYSCALLS__ */
-
/*
* "Conditional" syscalls
*
diff --git a/include/asm-arm26/unistd.h b/include/asm-arm26/unistd.h
index c6d2436c9d34..25a5eead85be 100644
--- a/include/asm-arm26/unistd.h
+++ b/include/asm-arm26/unistd.h
@@ -464,30 +464,6 @@ type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5, type6 arg6
#define __ARCH_WANT_SYS_SIGPROCMASK
#define __ARCH_WANT_SYS_RT_SIGACTION
-#ifdef __KERNEL_SYSCALLS__
-
-#include <linux/compiler.h>
-#include <linux/types.h>
-#include <linux/syscalls.h>
-
-extern long execve(const char *file, char **argv, char **envp);
-
-struct pt_regs;
-asmlinkage int sys_execve(char *filenamei, char **argv, char **envp,
- struct pt_regs *regs);
-asmlinkage int sys_clone(unsigned long clone_flags, unsigned long newsp,
- struct pt_regs *regs);
-asmlinkage int sys_fork(struct pt_regs *regs);
-asmlinkage int sys_vfork(struct pt_regs *regs);
-asmlinkage int sys_pipe(unsigned long *fildes);
-struct sigaction;
-asmlinkage long sys_rt_sigaction(int sig,
- const struct sigaction __user *act,
- struct sigaction __user *oact,
- size_t sigsetsize);
-
-#endif /* __KERNEL_SYSCALLS__ */
-
/*
* "Conditional" syscalls
*
diff --git a/include/asm-avr32/unistd.h b/include/asm-avr32/unistd.h
index 1f528f92690d..a50e5004550c 100644
--- a/include/asm-avr32/unistd.h
+++ b/include/asm-avr32/unistd.h
@@ -281,30 +281,10 @@
#define __NR_tee 263
#define __NR_vmsplice 264
+#ifdef __KERNEL__
#define NR_syscalls 265
-/*
- * AVR32 calling convention for system calls:
- * - System call number in r8
- * - Parameters in r12 and downwards to r9 as well as r6 and r5.
- * - Return value in r12
- */
-
-/*
- * user-visible error numbers are in the range -1 - -124: see
- * <asm-generic/errno.h>
- */
-
-#define __syscall_return(type, res) do { \
- if ((unsigned long)(res) >= (unsigned long)(-125)) { \
- errno = -(res); \
- res = -1; \
- } \
- return (type) (res); \
- } while (0)
-
-#ifdef __KERNEL__
#define __ARCH_WANT_IPC_PARSE_VERSION
#define __ARCH_WANT_STAT64
#define __ARCH_WANT_SYS_ALARM
@@ -319,62 +299,6 @@
#define __ARCH_WANT_SYS_GETPGRP
#define __ARCH_WANT_SYS_RT_SIGACTION
#define __ARCH_WANT_SYS_RT_SIGSUSPEND
-#endif
-
-#if defined(__KERNEL_SYSCALLS__) || defined(__CHECKER__)
-
-#include <linux/types.h>
-#include <linux/linkage.h>
-#include <asm/signal.h>
-
-struct pt_regs;
-
-/*
- * we need this inline - forking from kernel space will result
- * in NO COPY ON WRITE (!!!), until an execve is executed. This
- * is no problem, but for the stack. This is handled by not letting
- * main() use the stack at all after fork(). Thus, no function
- * calls - which means inline code for fork too, as otherwise we
- * would use the stack upon exit from 'fork()'.
- *
- * Actually only pause and fork are needed inline, so that there
- * won't be any messing with the stack from main(), but we define
- * some others too.
- */
-static inline int execve(const char *file, char **argv, char **envp)
-{
- register long scno asm("r8") = __NR_execve;
- register long sc1 asm("r12") = (long)file;
- register long sc2 asm("r11") = (long)argv;
- register long sc3 asm("r10") = (long)envp;
- int res;
-
- asm volatile("scall"
- : "=r"(sc1)
- : "r"(scno), "0"(sc1), "r"(sc2), "r"(sc3)
- : "lr", "memory");
- res = sc1;
- __syscall_return(int, res);
-}
-
-asmlinkage long sys_rt_sigsuspend(sigset_t __user *unewset, size_t sigsetsize);
-asmlinkage int sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss,
- struct pt_regs *regs);
-asmlinkage int sys_rt_sigreturn(struct pt_regs *regs);
-asmlinkage int sys_pipe(unsigned long __user *filedes);
-asmlinkage long sys_mmap2(unsigned long addr, unsigned long len,
- unsigned long prot, unsigned long flags,
- unsigned long fd, off_t offset);
-asmlinkage int sys_cacheflush(int operation, void __user *addr, size_t len);
-asmlinkage int sys_fork(struct pt_regs *regs);
-asmlinkage int sys_clone(unsigned long clone_flags, unsigned long newsp,
- unsigned long parent_tidptr,
- unsigned long child_tidptr, struct pt_regs *regs);
-asmlinkage int sys_vfork(struct pt_regs *regs);
-asmlinkage int sys_execve(char __user *ufilename, char __user *__user *uargv,
- char __user *__user *uenvp, struct pt_regs *regs);
-
-#endif
/*
* "Conditional" syscalls
@@ -384,4 +308,6 @@ asmlinkage int sys_execve(char __user *ufilename, char __user *__user *uargv,
*/
#define cond_syscall(x) asm(".weak\t" #x "\n\t.set\t" #x ",sys_ni_syscall");
+#endif /* __KERNEL__ */
+
#endif /* __ASM_AVR32_UNISTD_H */
diff --git a/include/asm-cris/arch-v32/spinlock.h b/include/asm-cris/arch-v32/spinlock.h
index 52df72a62232..5f43df0a5fb4 100644
--- a/include/asm-cris/arch-v32/spinlock.h
+++ b/include/asm-cris/arch-v32/spinlock.h
@@ -160,4 +160,8 @@ static __inline__ int is_write_locked(rwlock_t *rw)
return rw->counter < 0;
}
+#define _raw_spin_relax(lock) cpu_relax()
+#define _raw_read_relax(lock) cpu_relax()
+#define _raw_write_relax(lock) cpu_relax()
+
#endif /* __ASM_ARCH_SPINLOCK_H */
diff --git a/include/asm-cris/unistd.h b/include/asm-cris/unistd.h
index 7372efae0516..7c90fa970c38 100644
--- a/include/asm-cris/unistd.h
+++ b/include/asm-cris/unistd.h
@@ -322,67 +322,6 @@
#define __ARCH_WANT_SYS_SIGPROCMASK
#define __ARCH_WANT_SYS_RT_SIGACTION
-#ifdef __KERNEL_SYSCALLS__
-
-#include <linux/compiler.h>
-#include <linux/types.h>
-#include <linux/linkage.h>
-
-/*
- * we need this inline - forking from kernel space will result
- * in NO COPY ON WRITE (!!!), until an execve is executed. This
- * is no problem, but for the stack. This is handled by not letting
- * main() use the stack at all after fork(). Thus, no function
- * calls - which means inline code for fork too, as otherwise we
- * would use the stack upon exit from 'fork()'.
- *
- * Actually only pause and fork are needed inline, so that there
- * won't be any messing with the stack from main(), but we define
- * some others too.
- */
-#define __NR__exit __NR_exit
-static inline _syscall0(pid_t,setsid)
-static inline _syscall3(int,write,int,fd,const char *,buf,off_t,count)
-static inline _syscall3(int,read,int,fd,char *,buf,off_t,count)
-static inline _syscall3(off_t,lseek,int,fd,off_t,offset,int,count)
-static inline _syscall1(int,dup,int,fd)
-static inline _syscall3(int,execve,const char *,file,char **,argv,char **,envp)
-static inline _syscall3(int,open,const char *,file,int,flag,int,mode)
-static inline _syscall1(int,close,int,fd)
-
-struct pt_regs;
-asmlinkage long sys_mmap2(
- unsigned long addr, unsigned long len,
- unsigned long prot, unsigned long flags,
- unsigned long fd, unsigned long pgoff);
-asmlinkage int sys_execve(const char *fname, char **argv, char **envp,
- long r13, long mof, long srp, struct pt_regs *regs);
-asmlinkage int sys_clone(unsigned long newusp, unsigned long flags,
- int* parent_tid, int* child_tid, long mof, long srp,
- struct pt_regs *regs);
-asmlinkage int sys_fork(long r10, long r11, long r12, long r13,
- long mof, long srp, struct pt_regs *regs);
-asmlinkage int sys_vfork(long r10, long r11, long r12, long r13,
- long mof, long srp, struct pt_regs *regs);
-asmlinkage int sys_pipe(unsigned long __user *fildes);
-struct sigaction;
-asmlinkage long sys_rt_sigaction(int sig,
- const struct sigaction __user *act,
- struct sigaction __user *oact,
- size_t sigsetsize);
-
-/*
- * Since we define it "external", it collides with the built-in
- * definition, which has the "noreturn" attribute and will cause
- * complaints. We don't want to use -fno-builtin, so just use a
- * different name when in the kernel.
- */
-#define _exit kernel_syscall_exit
-static inline _syscall1(int,_exit,int,exitcode)
-static inline _syscall3(pid_t,waitpid,pid_t,pid,int *,wait_stat,int,options)
-#endif /* __KERNEL_SYSCALLS__ */
-
-
/*
* "Conditional" syscalls
*
diff --git a/include/asm-frv/pgtable.h b/include/asm-frv/pgtable.h
index 2fb3c6f05e03..ba1b37df69d5 100644
--- a/include/asm-frv/pgtable.h
+++ b/include/asm-frv/pgtable.h
@@ -176,8 +176,6 @@ do { \
} while(0)
#define set_pte_at(mm,addr,ptep,pteval) set_pte(ptep,pteval)
-#define set_pte_atomic(pteptr, pteval) set_pte((pteptr), (pteval))
-
/*
* pgd_offset() returns a (pgd_t *)
* pgd_index() is used get the offset into the pgd page's array of pgd_t's;
diff --git a/include/asm-frv/timex.h b/include/asm-frv/timex.h
index 2aa562fa067b..a89bddefdacf 100644
--- a/include/asm-frv/timex.h
+++ b/include/asm-frv/timex.h
@@ -6,11 +6,6 @@
#define CLOCK_TICK_RATE 1193180 /* Underlying HZ */
#define CLOCK_TICK_FACTOR 20 /* Factor of both 1000000 and CLOCK_TICK_RATE */
-#define FINETUNE \
-((((((long)LATCH * HZ - CLOCK_TICK_RATE) << SHIFT_HZ) * \
- (1000000/CLOCK_TICK_FACTOR) / (CLOCK_TICK_RATE/CLOCK_TICK_FACTOR)) \
- << (SHIFT_SCALE-SHIFT_HZ)) / HZ)
-
typedef unsigned long cycles_t;
static inline cycles_t get_cycles(void)
diff --git a/include/asm-frv/unistd.h b/include/asm-frv/unistd.h
index d104d1b91d39..725e854928cf 100644
--- a/include/asm-frv/unistd.h
+++ b/include/asm-frv/unistd.h
@@ -440,31 +440,6 @@ type name (type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5, type6 arg
__syscall_return(type, __sc0); \
}
-
-#ifdef __KERNEL_SYSCALLS__
-
-#include <linux/compiler.h>
-#include <linux/types.h>
-#include <linux/linkage.h>
-#include <asm/ptrace.h>
-
-/*
- * we need this inline - forking from kernel space will result
- * in NO COPY ON WRITE (!!!), until an execve is executed. This
- * is no problem, but for the stack. This is handled by not letting
- * main() use the stack at all after fork(). Thus, no function
- * calls - which means inline code for fork too, as otherwise we
- * would use the stack upon exit from 'fork()'.
- *
- * Actually only pause and fork are needed inline, so that there
- * won't be any messing with the stack from main(), but we define
- * some others too.
- */
-#define __NR__exit __NR_exit
-static inline _syscall3(int,execve,const char *,file,char **,argv,char **,envp)
-
-#endif /* __KERNEL_SYSCALLS__ */
-
#define __ARCH_WANT_IPC_PARSE_VERSION
/* #define __ARCH_WANT_OLD_READDIR */
#define __ARCH_WANT_OLD_STAT
diff --git a/include/asm-generic/bug.h b/include/asm-generic/bug.h
index 8ceab7bcd8b4..a5250895155e 100644
--- a/include/asm-generic/bug.h
+++ b/include/asm-generic/bug.h
@@ -16,12 +16,15 @@
#endif
#ifndef HAVE_ARCH_WARN_ON
-#define WARN_ON(condition) do { \
- if (unlikely((condition)!=0)) { \
- printk("BUG: warning at %s:%d/%s()\n", __FILE__, __LINE__, __FUNCTION__); \
- dump_stack(); \
- } \
-} while (0)
+#define WARN_ON(condition) ({ \
+ typeof(condition) __ret_warn_on = (condition); \
+ if (unlikely(__ret_warn_on)) { \
+ printk("BUG: warning at %s:%d/%s()\n", __FILE__, \
+ __LINE__, __FUNCTION__); \
+ dump_stack(); \
+ } \
+ unlikely(__ret_warn_on); \
+})
#endif
#else /* !CONFIG_BUG */
@@ -34,21 +37,18 @@
#endif
#ifndef HAVE_ARCH_WARN_ON
-#define WARN_ON(condition) do { if (condition) ; } while(0)
+#define WARN_ON(condition) unlikely((condition))
#endif
#endif
-#define WARN_ON_ONCE(condition) \
-({ \
+#define WARN_ON_ONCE(condition) ({ \
static int __warn_once = 1; \
- int __ret = 0; \
+ typeof(condition) __ret_warn_once = (condition);\
\
- if (unlikely((condition) && __warn_once)) { \
- __warn_once = 0; \
- WARN_ON(1); \
- __ret = 1; \
- } \
- __ret; \
+ if (likely(__warn_once)) \
+ if (WARN_ON(__ret_warn_once)) \
+ __warn_once = 0; \
+ unlikely(__ret_warn_once); \
})
#ifdef CONFIG_SMP
diff --git a/include/asm-generic/pgtable.h b/include/asm-generic/pgtable.h
index 349260cd86ed..9d774d07d95b 100644
--- a/include/asm-generic/pgtable.h
+++ b/include/asm-generic/pgtable.h
@@ -15,19 +15,11 @@
* Note: the old pte is known to not be writable, so we don't need to
* worry about dirty bits etc getting lost.
*/
-#ifndef __HAVE_ARCH_SET_PTE_ATOMIC
#define ptep_establish(__vma, __address, __ptep, __entry) \
do { \
set_pte_at((__vma)->vm_mm, (__address), __ptep, __entry); \
flush_tlb_page(__vma, __address); \
} while (0)
-#else /* __HAVE_ARCH_SET_PTE_ATOMIC */
-#define ptep_establish(__vma, __address, __ptep, __entry) \
-do { \
- set_pte_atomic(__ptep, __entry); \
- flush_tlb_page(__vma, __address); \
-} while (0)
-#endif /* __HAVE_ARCH_SET_PTE_ATOMIC */
#endif
#ifndef __HAVE_ARCH_PTEP_SET_ACCESS_FLAGS
@@ -112,8 +104,13 @@ do { \
})
#endif
-#ifndef __HAVE_ARCH_PTE_CLEAR_FULL
-#define pte_clear_full(__mm, __address, __ptep, __full) \
+/*
+ * Some architectures may be able to avoid expensive synchronization
+ * primitives when modifications are made to PTE's which are already
+ * not present, or in the process of an address space destruction.
+ */
+#ifndef __HAVE_ARCH_PTE_CLEAR_NOT_PRESENT_FULL
+#define pte_clear_not_present_full(__mm, __address, __ptep, __full) \
do { \
pte_clear((__mm), (__address), (__ptep)); \
} while (0)
@@ -166,6 +163,26 @@ static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long addres
#endif
/*
+ * A facility to provide lazy MMU batching. This allows PTE updates and
+ * page invalidations to be delayed until a call to leave lazy MMU mode
+ * is issued. Some architectures may benefit from doing this, and it is
+ * beneficial for both shadow and direct mode hypervisors, which may batch
+ * the PTE updates which happen during this window. Note that using this
+ * interface requires that read hazards be removed from the code. A read
+ * hazard could result in the direct mode hypervisor case, since the actual
+ * write to the page tables may not yet have taken place, so reads though
+ * a raw PTE pointer after it has been modified are not guaranteed to be
+ * up to date. This mode can only be entered and left under the protection of
+ * the page table locks for all page tables which may be modified. In the UP
+ * case, this is required so that preemption is disabled, and in the SMP case,
+ * it must synchronize the delayed page table writes properly on other CPUs.
+ */
+#ifndef __HAVE_ARCH_ENTER_LAZY_MMU_MODE
+#define arch_enter_lazy_mmu_mode() do {} while (0)
+#define arch_leave_lazy_mmu_mode() do {} while (0)
+#endif
+
+/*
* When walking page tables, get the address of the next boundary,
* or the end address of the range if that comes earlier. Although no
* vma end wraps to 0, rounded up __boundary may wrap to 0 throughout.
diff --git a/include/asm-h8300/keyboard.h b/include/asm-h8300/keyboard.h
index fbad65e8a5c0..90efbd655390 100644
--- a/include/asm-h8300/keyboard.h
+++ b/include/asm-h8300/keyboard.h
@@ -18,14 +18,6 @@
#define kbd_enable_irq(x...) do {;} while (0)
#define kbd_disable_irq(x...) do {;} while (0)
-
-/* needed if MAGIC_SYSRQ is enabled for serial console */
-#ifndef SYSRQ_KEY
-#define SYSRQ_KEY ((unsigned char)(-1))
-#define kbd_sysrq_xlate ((unsigned char *)NULL)
-#endif
-
-
#endif /* _H8300_KEYBOARD_H */
diff --git a/include/asm-h8300/unistd.h b/include/asm-h8300/unistd.h
index a2dd90462d80..747788d629ae 100644
--- a/include/asm-h8300/unistd.h
+++ b/include/asm-h8300/unistd.h
@@ -485,57 +485,6 @@ type name(atype a, btype b, ctype c, dtype d, etype e, ftype f) \
#define __ARCH_WANT_SYS_SIGPROCMASK
#define __ARCH_WANT_SYS_RT_SIGACTION
-#ifdef __KERNEL_SYSCALLS__
-
-#include <linux/compiler.h>
-#include <linux/types.h>
-
-/*
- * we need this inline - forking from kernel space will result
- * in NO COPY ON WRITE (!!!), until an execve is executed. This
- * is no problem, but for the stack. This is handled by not letting
- * main() use the stack at all after fork(). Thus, no function
- * calls - which means inline code for fork too, as otherwise we
- * would use the stack upon exit from 'fork()'.
- *
- * Actually only pause and fork are needed inline, so that there
- * won't be any messing with the stack from main(), but we define
- * some others too.
- */
-#define __NR__exit __NR_exit
-static inline _syscall0(int,pause)
-static inline _syscall0(int,sync)
-static inline _syscall0(pid_t,setsid)
-static inline _syscall3(int,write,int,fd,const char *,buf,off_t,count)
-static inline _syscall3(int,read,int,fd,char *,buf,off_t,count)
-static inline _syscall3(off_t,lseek,int,fd,off_t,offset,int,count)
-static inline _syscall1(int,dup,int,fd)
-static inline _syscall3(int,execve,const char *,file,char **,argv,char **,envp)
-static inline _syscall3(int,open,const char *,file,int,flag,int,mode)
-static inline _syscall1(int,close,int,fd)
-static inline _syscall1(int,_exit,int,exitcode)
-static inline _syscall3(pid_t,waitpid,pid_t,pid,int *,wait_stat,int,options)
-static inline _syscall1(int,delete_module,const char *,name)
-
-static inline pid_t wait(int * wait_stat)
-{
- return waitpid(-1,wait_stat,0);
-}
-
-asmlinkage long sys_mmap2(unsigned long addr, unsigned long len,
- unsigned long prot, unsigned long flags,
- unsigned long fd, unsigned long pgoff);
-asmlinkage int sys_execve(char *name, char **argv, char **envp,
- int dummy, ...);
-asmlinkage int sys_pipe(unsigned long *fildes);
-struct sigaction;
-asmlinkage long sys_rt_sigaction(int sig,
- const struct sigaction __user *act,
- struct sigaction __user *oact,
- size_t sigsetsize);
-
-#endif /* __KERNEL_SYSCALLS__ */
-
/*
* "Conditional" syscalls
*/
diff --git a/include/asm-i386/bugs.h b/include/asm-i386/bugs.h
index 2a9e4ee5904d..592ffeeda45e 100644
--- a/include/asm-i386/bugs.h
+++ b/include/asm-i386/bugs.h
@@ -189,6 +189,6 @@ static void __init check_bugs(void)
check_fpu();
check_hlt();
check_popad();
- system_utsname.machine[1] = '0' + (boot_cpu_data.x86 > 6 ? 6 : boot_cpu_data.x86);
+ init_utsname()->machine[1] = '0' + (boot_cpu_data.x86 > 6 ? 6 : boot_cpu_data.x86);
alternative_instructions();
}
diff --git a/include/asm-i386/dma-mapping.h b/include/asm-i386/dma-mapping.h
index 576ae01d71c8..81999a3ebe7c 100644
--- a/include/asm-i386/dma-mapping.h
+++ b/include/asm-i386/dma-mapping.h
@@ -21,7 +21,7 @@ static inline dma_addr_t
dma_map_single(struct device *dev, void *ptr, size_t size,
enum dma_data_direction direction)
{
- BUG_ON(direction == DMA_NONE);
+ BUG_ON(!valid_dma_direction(direction));
WARN_ON(size == 0);
flush_write_buffers();
return virt_to_phys(ptr);
@@ -31,7 +31,7 @@ static inline void
dma_unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size,
enum dma_data_direction direction)
{
- BUG_ON(direction == DMA_NONE);
+ BUG_ON(!valid_dma_direction(direction));
}
static inline int
@@ -40,7 +40,7 @@ dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
{
int i;
- BUG_ON(direction == DMA_NONE);
+ BUG_ON(!valid_dma_direction(direction));
WARN_ON(nents == 0 || sg[0].length == 0);
for (i = 0; i < nents; i++ ) {
@@ -57,7 +57,7 @@ static inline dma_addr_t
dma_map_page(struct device *dev, struct page *page, unsigned long offset,
size_t size, enum dma_data_direction direction)
{
- BUG_ON(direction == DMA_NONE);
+ BUG_ON(!valid_dma_direction(direction));
return page_to_phys(page) + offset;
}
@@ -65,7 +65,7 @@ static inline void
dma_unmap_page(struct device *dev, dma_addr_t dma_address, size_t size,
enum dma_data_direction direction)
{
- BUG_ON(direction == DMA_NONE);
+ BUG_ON(!valid_dma_direction(direction));
}
@@ -73,7 +73,7 @@ static inline void
dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nhwentries,
enum dma_data_direction direction)
{
- BUG_ON(direction == DMA_NONE);
+ BUG_ON(!valid_dma_direction(direction));
}
static inline void
diff --git a/include/asm-i386/elf.h b/include/asm-i386/elf.h
index db4344d9f73f..3a05436f31c0 100644
--- a/include/asm-i386/elf.h
+++ b/include/asm-i386/elf.h
@@ -112,7 +112,7 @@ typedef struct user_fxsr_struct elf_fpxregset_t;
For the moment, we have only optimizations for the Intel generations,
but that could change... */
-#define ELF_PLATFORM (system_utsname.machine)
+#define ELF_PLATFORM (utsname()->machine)
#define SET_PERSONALITY(ex, ibcs2) do { } while (0)
diff --git a/include/asm-i386/mach-default/do_timer.h b/include/asm-i386/mach-default/do_timer.h
index 6312c3e79814..4182c347ef85 100644
--- a/include/asm-i386/mach-default/do_timer.h
+++ b/include/asm-i386/mach-default/do_timer.h
@@ -16,7 +16,7 @@
static inline void do_timer_interrupt_hook(struct pt_regs *regs)
{
- do_timer(regs);
+ do_timer(1);
#ifndef CONFIG_SMP
update_process_times(user_mode_vm(regs));
#endif
diff --git a/include/asm-i386/mach-summit/mach_apic.h b/include/asm-i386/mach-summit/mach_apic.h
index a81b05961595..254a0fe01c6a 100644
--- a/include/asm-i386/mach-summit/mach_apic.h
+++ b/include/asm-i386/mach-summit/mach_apic.h
@@ -88,7 +88,7 @@ static inline void clustered_apic_check(void)
static inline int apicid_to_node(int logical_apicid)
{
- return logical_apicid >> 5; /* 2 clusterids per CEC */
+ return apicid_2_node[logical_apicid];
}
/* Mapping from cpu number to logical apicid */
diff --git a/include/asm-i386/mach-visws/do_timer.h b/include/asm-i386/mach-visws/do_timer.h
index 95568e6ca91c..8db618c5a72b 100644
--- a/include/asm-i386/mach-visws/do_timer.h
+++ b/include/asm-i386/mach-visws/do_timer.h
@@ -9,7 +9,7 @@ static inline void do_timer_interrupt_hook(struct pt_regs *regs)
/* Clear the interrupt */
co_cpu_write(CO_CPU_STAT,co_cpu_read(CO_CPU_STAT) & ~CO_STAT_TIMEINTR);
- do_timer(regs);
+ do_timer(1);
#ifndef CONFIG_SMP
update_process_times(user_mode_vm(regs));
#endif
diff --git a/include/asm-i386/mach-voyager/do_timer.h b/include/asm-i386/mach-voyager/do_timer.h
index eaf518098981..099fe9f5c1b2 100644
--- a/include/asm-i386/mach-voyager/do_timer.h
+++ b/include/asm-i386/mach-voyager/do_timer.h
@@ -3,7 +3,7 @@
static inline void do_timer_interrupt_hook(struct pt_regs *regs)
{
- do_timer(regs);
+ do_timer(1);
#ifndef CONFIG_SMP
update_process_times(user_mode_vm(regs));
#endif
diff --git a/include/asm-i386/mca_dma.h b/include/asm-i386/mca_dma.h
index 4b3b526c5a3f..fbb1f3b71279 100644
--- a/include/asm-i386/mca_dma.h
+++ b/include/asm-i386/mca_dma.h
@@ -181,7 +181,7 @@ static __inline__ void mca_set_dma_io(unsigned int dmanr, unsigned int io_addr)
* @mode: mode to set
*
* The DMA controller supports several modes. The mode values you can
- * set are :
+ * set are-
*
* %MCA_DMA_MODE_READ when reading from the DMA device.
*
@@ -190,7 +190,6 @@ static __inline__ void mca_set_dma_io(unsigned int dmanr, unsigned int io_addr)
* %MCA_DMA_MODE_IO to do DMA to or from an I/O port.
*
* %MCA_DMA_MODE_16 to do 16bit transfers.
- *
*/
static __inline__ void mca_set_dma_mode(unsigned int dmanr, unsigned int mode)
diff --git a/include/asm-i386/nmi.h b/include/asm-i386/nmi.h
index 303bcd4592bb..269d315719ca 100644
--- a/include/asm-i386/nmi.h
+++ b/include/asm-i386/nmi.h
@@ -36,4 +36,10 @@ extern unsigned int nmi_watchdog;
#define NMI_LOCAL_APIC 2
#define NMI_INVALID 3
+struct ctl_table;
+struct file;
+extern int proc_nmi_enabled(struct ctl_table *, int , struct file *,
+ void __user *, size_t *, loff_t *);
+extern int unknown_nmi_panic;
+
#endif /* ASM_NMI_H */
diff --git a/include/asm-i386/pgtable-2level.h b/include/asm-i386/pgtable-2level.h
index 201c86a6711e..8d8d3b9ecdb0 100644
--- a/include/asm-i386/pgtable-2level.h
+++ b/include/asm-i386/pgtable-2level.h
@@ -16,6 +16,7 @@
#define set_pte(pteptr, pteval) (*(pteptr) = pteval)
#define set_pte_at(mm,addr,ptep,pteval) set_pte(ptep,pteval)
#define set_pte_atomic(pteptr, pteval) set_pte(pteptr,pteval)
+#define set_pte_present(mm,addr,ptep,pteval) set_pte_at(mm,addr,ptep,pteval)
#define set_pmd(pmdptr, pmdval) (*(pmdptr) = (pmdval))
#define pte_clear(mm,addr,xp) do { set_pte_at(mm, addr, xp, __pte(0)); } while (0)
diff --git a/include/asm-i386/pgtable-3level.h b/include/asm-i386/pgtable-3level.h
index 0d899173232e..c2d701ea35be 100644
--- a/include/asm-i386/pgtable-3level.h
+++ b/include/asm-i386/pgtable-3level.h
@@ -58,7 +58,21 @@ static inline void set_pte(pte_t *ptep, pte_t pte)
}
#define set_pte_at(mm,addr,ptep,pteval) set_pte(ptep,pteval)
-#define __HAVE_ARCH_SET_PTE_ATOMIC
+/*
+ * Since this is only called on user PTEs, and the page fault handler
+ * must handle the already racy situation of simultaneous page faults,
+ * we are justified in merely clearing the PTE present bit, followed
+ * by a set. The ordering here is important.
+ */
+static inline void set_pte_present(struct mm_struct *mm, unsigned long addr, pte_t *ptep, pte_t pte)
+{
+ ptep->pte_low = 0;
+ smp_wmb();
+ ptep->pte_high = pte.pte_high;
+ smp_wmb();
+ ptep->pte_low = pte.pte_low;
+}
+
#define set_pte_atomic(pteptr,pteval) \
set_64bit((unsigned long long *)(pteptr),pte_val(pteval))
#define set_pmd(pmdptr,pmdval) \
diff --git a/include/asm-i386/pgtable.h b/include/asm-i386/pgtable.h
index 541b3e234335..7d398f493dde 100644
--- a/include/asm-i386/pgtable.h
+++ b/include/asm-i386/pgtable.h
@@ -247,6 +247,23 @@ static inline pte_t pte_mkhuge(pte_t pte) { (pte).pte_low |= _PAGE_PSE; return p
#endif
/*
+ * Rules for using pte_update - it must be called after any PTE update which
+ * has not been done using the set_pte / clear_pte interfaces. It is used by
+ * shadow mode hypervisors to resynchronize the shadow page tables. Kernel PTE
+ * updates should either be sets, clears, or set_pte_atomic for P->P
+ * transitions, which means this hook should only be called for user PTEs.
+ * This hook implies a P->P protection or access change has taken place, which
+ * requires a subsequent TLB flush. The notification can optionally be delayed
+ * until the TLB flush event by using the pte_update_defer form of the
+ * interface, but care must be taken to assure that the flush happens while
+ * still holding the same page table lock so that the shadow and primary pages
+ * do not become out of sync on SMP.
+ */
+#define pte_update(mm, addr, ptep) do { } while (0)
+#define pte_update_defer(mm, addr, ptep) do { } while (0)
+
+
+/*
* We only update the dirty/accessed state if we set
* the dirty bit by hand in the kernel, since the hardware
* will do the accessed bit for us, and we don't want to
@@ -258,25 +275,54 @@ static inline pte_t pte_mkhuge(pte_t pte) { (pte).pte_low |= _PAGE_PSE; return p
do { \
if (dirty) { \
(ptep)->pte_low = (entry).pte_low; \
+ pte_update_defer((vma)->vm_mm, (addr), (ptep)); \
flush_tlb_page(vma, address); \
} \
} while (0)
+/*
+ * We don't actually have these, but we want to advertise them so that
+ * we can encompass the flush here.
+ */
#define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_DIRTY
-static inline int ptep_test_and_clear_dirty(struct vm_area_struct *vma, unsigned long addr, pte_t *ptep)
-{
- if (!pte_dirty(*ptep))
- return 0;
- return test_and_clear_bit(_PAGE_BIT_DIRTY, &ptep->pte_low);
-}
-
#define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_YOUNG
-static inline int ptep_test_and_clear_young(struct vm_area_struct *vma, unsigned long addr, pte_t *ptep)
-{
- if (!pte_young(*ptep))
- return 0;
- return test_and_clear_bit(_PAGE_BIT_ACCESSED, &ptep->pte_low);
-}
+
+/*
+ * Rules for using ptep_establish: the pte MUST be a user pte, and
+ * must be a present->present transition.
+ */
+#define __HAVE_ARCH_PTEP_ESTABLISH
+#define ptep_establish(vma, address, ptep, pteval) \
+do { \
+ set_pte_present((vma)->vm_mm, address, ptep, pteval); \
+ flush_tlb_page(vma, address); \
+} while (0)
+
+#define __HAVE_ARCH_PTEP_CLEAR_DIRTY_FLUSH
+#define ptep_clear_flush_dirty(vma, address, ptep) \
+({ \
+ int __dirty; \
+ __dirty = pte_dirty(*(ptep)); \
+ if (__dirty) { \
+ clear_bit(_PAGE_BIT_DIRTY, &(ptep)->pte_low); \
+ pte_update_defer((vma)->vm_mm, (addr), (ptep)); \
+ flush_tlb_page(vma, address); \
+ } \
+ __dirty; \
+})
+
+#define __HAVE_ARCH_PTEP_CLEAR_YOUNG_FLUSH
+#define ptep_clear_flush_young(vma, address, ptep) \
+({ \
+ int __young; \
+ __young = pte_young(*(ptep)); \
+ if (__young) { \
+ clear_bit(_PAGE_BIT_ACCESSED, &(ptep)->pte_low); \
+ pte_update_defer((vma)->vm_mm, (addr), (ptep)); \
+ flush_tlb_page(vma, address); \
+ } \
+ __young; \
+})
#define __HAVE_ARCH_PTEP_GET_AND_CLEAR_FULL
static inline pte_t ptep_get_and_clear_full(struct mm_struct *mm, unsigned long addr, pte_t *ptep, int full)
@@ -295,6 +341,7 @@ static inline pte_t ptep_get_and_clear_full(struct mm_struct *mm, unsigned long
static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long addr, pte_t *ptep)
{
clear_bit(_PAGE_BIT_RW, &ptep->pte_low);
+ pte_update(mm, addr, ptep);
}
/*
@@ -426,6 +473,13 @@ extern pte_t *lookup_address(unsigned long address);
#define pte_unmap_nested(pte) do { } while (0)
#endif
+/* Clear a kernel PTE and flush it from the TLB */
+#define kpte_clear_flush(ptep, vaddr) \
+do { \
+ pte_clear(&init_mm, vaddr, ptep); \
+ __flush_tlb_one(vaddr); \
+} while (0)
+
/*
* The i386 doesn't have any external MMU info: the kernel page
* tables contain all the necessary information.
diff --git a/include/asm-i386/ptrace.h b/include/asm-i386/ptrace.h
index a4a0e5207db5..d505f501077a 100644
--- a/include/asm-i386/ptrace.h
+++ b/include/asm-i386/ptrace.h
@@ -47,7 +47,10 @@ static inline int user_mode_vm(struct pt_regs *regs)
{
return ((regs->xcs & SEGMENT_RPL_MASK) | (regs->eflags & VM_MASK)) >= USER_RPL;
}
+
#define instruction_pointer(regs) ((regs)->eip)
+#define regs_return_value(regs) ((regs)->eax)
+
extern unsigned long profile_pc(struct pt_regs *regs);
#endif /* __KERNEL__ */
diff --git a/include/asm-i386/smp.h b/include/asm-i386/smp.h
index 32ac8c91d5c5..6aa1206f6e2a 100644
--- a/include/asm-i386/smp.h
+++ b/include/asm-i386/smp.h
@@ -46,6 +46,8 @@ extern u8 x86_cpu_to_apicid[];
#define cpu_physical_id(cpu) x86_cpu_to_apicid[cpu]
+extern u8 apicid_2_node[];
+
#ifdef CONFIG_HOTPLUG_CPU
extern void cpu_exit_clear(void);
extern void cpu_uninit(void);
@@ -82,6 +84,7 @@ static inline int hard_smp_processor_id(void)
#endif
#endif
+extern int safe_smp_processor_id(void);
extern int __cpu_disable(void);
extern void __cpu_die(unsigned int cpu);
extern unsigned int num_processors;
@@ -90,6 +93,7 @@ extern unsigned int num_processors;
#else /* CONFIG_SMP */
+#define safe_smp_processor_id() 0
#define cpu_physical_id(cpu) boot_cpu_physical_apicid
#define NO_PROC_ID 0xFF /* No processor magic marker */
diff --git a/include/asm-i386/spinlock.h b/include/asm-i386/spinlock.h
index b0b3043f05e1..c18b71fae6b3 100644
--- a/include/asm-i386/spinlock.h
+++ b/include/asm-i386/spinlock.h
@@ -205,4 +205,8 @@ static inline void __raw_write_unlock(raw_rwlock_t *rw)
: "+m" (rw->lock) : : "memory");
}
+#define _raw_spin_relax(lock) cpu_relax()
+#define _raw_read_relax(lock) cpu_relax()
+#define _raw_write_relax(lock) cpu_relax()
+
#endif /* __ASM_SPINLOCK_H */
diff --git a/include/asm-i386/topology.h b/include/asm-i386/topology.h
index 6adbd9b1ae88..978d09596130 100644
--- a/include/asm-i386/topology.h
+++ b/include/asm-i386/topology.h
@@ -74,6 +74,7 @@ static inline int node_to_first_cpu(int node)
#define SD_NODE_INIT (struct sched_domain) { \
.span = CPU_MASK_NONE, \
.parent = NULL, \
+ .child = NULL, \
.groups = NULL, \
.min_interval = 8, \
.max_interval = 32, \
diff --git a/include/asm-i386/unistd.h b/include/asm-i386/unistd.h
index bd9987087adc..3ca7ab963d7d 100644
--- a/include/asm-i386/unistd.h
+++ b/include/asm-i386/unistd.h
@@ -451,45 +451,6 @@ __syscall_return(type,__res); \
#define __ARCH_WANT_SYS_RT_SIGACTION
#define __ARCH_WANT_SYS_RT_SIGSUSPEND
-#ifdef __KERNEL_SYSCALLS__
-
-#include <linux/compiler.h>
-#include <linux/types.h>
-#include <linux/linkage.h>
-#include <asm/ptrace.h>
-
-/*
- * we need this inline - forking from kernel space will result
- * in NO COPY ON WRITE (!!!), until an execve is executed. This
- * is no problem, but for the stack. This is handled by not letting
- * main() use the stack at all after fork(). Thus, no function
- * calls - which means inline code for fork too, as otherwise we
- * would use the stack upon exit from 'fork()'.
- *
- * Actually only pause and fork are needed inline, so that there
- * won't be any messing with the stack from main(), but we define
- * some others too.
- */
-static inline _syscall3(int,execve,const char *,file,char **,argv,char **,envp)
-
-asmlinkage int sys_modify_ldt(int func, void __user *ptr, unsigned long bytecount);
-asmlinkage long sys_mmap2(unsigned long addr, unsigned long len,
- unsigned long prot, unsigned long flags,
- unsigned long fd, unsigned long pgoff);
-asmlinkage int sys_execve(struct pt_regs regs);
-asmlinkage int sys_clone(struct pt_regs regs);
-asmlinkage int sys_fork(struct pt_regs regs);
-asmlinkage int sys_vfork(struct pt_regs regs);
-asmlinkage int sys_pipe(unsigned long __user *fildes);
-asmlinkage long sys_iopl(unsigned long unused);
-struct sigaction;
-asmlinkage long sys_rt_sigaction(int sig,
- const struct sigaction __user *act,
- struct sigaction __user *oact,
- size_t sigsetsize);
-
-#endif /* __KERNEL_SYSCALLS__ */
-
/*
* "Conditional" syscalls
*
diff --git a/include/asm-ia64/ptrace.h b/include/asm-ia64/ptrace.h
index 1414316efd40..f4ef87a36236 100644
--- a/include/asm-ia64/ptrace.h
+++ b/include/asm-ia64/ptrace.h
@@ -241,6 +241,9 @@ struct switch_stack {
* the canonical representation by adding to instruction pointer.
*/
# define instruction_pointer(regs) ((regs)->cr_iip + ia64_psr(regs)->ri)
+
+#define regs_return_value(regs) ((regs)->r8)
+
/* Conserve space in histogram by encoding slot bits in address
* bits 2 and 3 rather than bits 0 and 1.
*/
diff --git a/include/asm-ia64/spinlock.h b/include/asm-ia64/spinlock.h
index 9e83210dc312..ff857e31738a 100644
--- a/include/asm-ia64/spinlock.h
+++ b/include/asm-ia64/spinlock.h
@@ -213,4 +213,8 @@ static inline int __raw_read_trylock(raw_rwlock_t *x)
return (u32)ia64_cmpxchg4_acq((__u32 *)(x), new.word, old.word) == old.word;
}
+#define _raw_spin_relax(lock) cpu_relax()
+#define _raw_read_relax(lock) cpu_relax()
+#define _raw_write_relax(lock) cpu_relax()
+
#endif /* _ASM_IA64_SPINLOCK_H */
diff --git a/include/asm-ia64/topology.h b/include/asm-ia64/topology.h
index 937c21257523..a6e38565ab4c 100644
--- a/include/asm-ia64/topology.h
+++ b/include/asm-ia64/topology.h
@@ -59,6 +59,7 @@ void build_cpu_to_node_map(void);
#define SD_CPU_INIT (struct sched_domain) { \
.span = CPU_MASK_NONE, \
.parent = NULL, \
+ .child = NULL, \
.groups = NULL, \
.min_interval = 1, \
.max_interval = 4, \
@@ -84,6 +85,7 @@ void build_cpu_to_node_map(void);
#define SD_NODE_INIT (struct sched_domain) { \
.span = CPU_MASK_NONE, \
.parent = NULL, \
+ .child = NULL, \
.groups = NULL, \
.min_interval = 8, \
.max_interval = 8*(min(num_online_cpus(), 32)), \
diff --git a/include/asm-ia64/unistd.h b/include/asm-ia64/unistd.h
index bb0eb727dcd0..53c5c0ee122c 100644
--- a/include/asm-ia64/unistd.h
+++ b/include/asm-ia64/unistd.h
@@ -319,78 +319,6 @@
extern long __ia64_syscall (long a0, long a1, long a2, long a3, long a4, long nr);
-#ifdef __KERNEL_SYSCALLS__
-
-#include <linux/compiler.h>
-#include <linux/string.h>
-#include <linux/signal.h>
-#include <asm/ptrace.h>
-#include <linux/stringify.h>
-#include <linux/syscalls.h>
-
-static inline long
-open (const char * name, int mode, int flags)
-{
- return sys_open(name, mode, flags);
-}
-
-static inline long
-dup (int fd)
-{
- return sys_dup(fd);
-}
-
-static inline long
-close (int fd)
-{
- return sys_close(fd);
-}
-
-static inline off_t
-lseek (int fd, off_t off, int whence)
-{
- return sys_lseek(fd, off, whence);
-}
-
-static inline void
-_exit (int value)
-{
- sys_exit(value);
-}
-
-#define exit(x) _exit(x)
-
-static inline long
-write (int fd, const char * buf, size_t nr)
-{
- return sys_write(fd, buf, nr);
-}
-
-static inline long
-read (int fd, char * buf, size_t nr)
-{
- return sys_read(fd, buf, nr);
-}
-
-
-static inline long
-setsid (void)
-{
- return sys_setsid();
-}
-
-static inline pid_t
-waitpid (int pid, int * wait_stat, int flags)
-{
- return sys_wait4(pid, wait_stat, flags, NULL);
-}
-
-
-extern int execve (const char *filename, char *const av[], char *const ep[]);
-extern pid_t clone (unsigned long flags, void *sp);
-
-#endif /* __KERNEL_SYSCALLS__ */
-
asmlinkage unsigned long sys_mmap(
unsigned long addr, unsigned long len,
int prot, int flags,
diff --git a/include/asm-m32r/pgtable-2level.h b/include/asm-m32r/pgtable-2level.h
index 6a674e3d37a2..84152760e0b5 100644
--- a/include/asm-m32r/pgtable-2level.h
+++ b/include/asm-m32r/pgtable-2level.h
@@ -44,7 +44,7 @@ static inline int pgd_present(pgd_t pgd) { return 1; }
*/
#define set_pte(pteptr, pteval) (*(pteptr) = pteval)
#define set_pte_at(mm,addr,ptep,pteval) set_pte(ptep,pteval)
-#define set_pte_atomic(pteptr, pteval) set_pte(pteptr, pteval)
+
/*
* (pmds are folded into pgds so this doesnt get actually called,
* but the define is needed for a generic inline function.)
diff --git a/include/asm-m32r/spinlock.h b/include/asm-m32r/spinlock.h
index f9f90727a4a1..f5cfba81ee10 100644
--- a/include/asm-m32r/spinlock.h
+++ b/include/asm-m32r/spinlock.h
@@ -316,4 +316,8 @@ static inline int __raw_write_trylock(raw_rwlock_t *lock)
return 0;
}
+#define _raw_spin_relax(lock) cpu_relax()
+#define _raw_read_relax(lock) cpu_relax()
+#define _raw_write_relax(lock) cpu_relax()
+
#endif /* _ASM_M32R_SPINLOCK_H */
diff --git a/include/asm-m32r/timex.h b/include/asm-m32r/timex.h
index e89bfd17db51..019441c1d7a0 100644
--- a/include/asm-m32r/timex.h
+++ b/include/asm-m32r/timex.h
@@ -12,9 +12,6 @@
#define CLOCK_TICK_RATE (CONFIG_BUS_CLOCK / CONFIG_TIMER_DIVIDE)
#define CLOCK_TICK_FACTOR 20 /* Factor of both 1000000 and CLOCK_TICK_RATE */
-#define FINETUNE ((((((long)LATCH * HZ - CLOCK_TICK_RATE) << SHIFT_HZ) * \
- (1000000/CLOCK_TICK_FACTOR) / (CLOCK_TICK_RATE/CLOCK_TICK_FACTOR)) \
- << (SHIFT_SCALE-SHIFT_HZ)) / HZ)
#ifdef __KERNEL__
/*
diff --git a/include/asm-m32r/unistd.h b/include/asm-m32r/unistd.h
index 5c6a9ac6cf1a..95aa34298d82 100644
--- a/include/asm-m32r/unistd.h
+++ b/include/asm-m32r/unistd.h
@@ -424,43 +424,6 @@ __syscall_return(type,__res); \
#define __ARCH_WANT_SYS_OLDUMOUNT
#define __ARCH_WANT_SYS_RT_SIGACTION
-#ifdef __KERNEL_SYSCALLS__
-
-#include <linux/compiler.h>
-#include <linux/types.h>
-#include <linux/linkage.h>
-#include <asm/ptrace.h>
-
-/*
- * we need this inline - forking from kernel space will result
- * in NO COPY ON WRITE (!!!), until an execve is executed. This
- * is no problem, but for the stack. This is handled by not letting
- * main() use the stack at all after fork(). Thus, no function
- * calls - which means inline code for fork too, as otherwise we
- * would use the stack upon exit from 'fork()'.
- *
- * Actually only pause and fork are needed inline, so that there
- * won't be any messing with the stack from main(), but we define
- * some others too.
- */
-static __inline__ _syscall3(int,execve,const char *,file,char **,argv,char **,envp)
-
-asmlinkage long sys_mmap2(unsigned long addr, unsigned long len,
- unsigned long prot, unsigned long flags,
- unsigned long fd, unsigned long pgoff);
-asmlinkage int sys_execve(struct pt_regs regs);
-asmlinkage int sys_clone(struct pt_regs regs);
-asmlinkage int sys_fork(struct pt_regs regs);
-asmlinkage int sys_vfork(struct pt_regs regs);
-asmlinkage int sys_pipe(unsigned long __user *fildes);
-struct sigaction;
-asmlinkage long sys_rt_sigaction(int sig,
- const struct sigaction __user *act,
- struct sigaction __user *oact,
- size_t sigsetsize);
-
-#endif /* __KERNEL_SYSCALLS__ */
-
/*
* "Conditional" syscalls
*
diff --git a/include/asm-m68k/unistd.h b/include/asm-m68k/unistd.h
index 751632b904db..3ab716f0fc18 100644
--- a/include/asm-m68k/unistd.h
+++ b/include/asm-m68k/unistd.h
@@ -409,12 +409,6 @@ __syscall_return(type,__res); \
#define __ARCH_WANT_SYS_SIGPROCMASK
#define __ARCH_WANT_SYS_RT_SIGACTION
-#ifdef __KERNEL_SYSCALLS__
-
-static inline _syscall3(int,execve,const char *,file,char **,argv,char **,envp)
-
-#endif /* __KERNEL_SYSCALLS__ */
-
/*
* "Conditional" syscalls
*
diff --git a/include/asm-m68knommu/unistd.h b/include/asm-m68knommu/unistd.h
index 21fdc37c5c2c..daafb5d43ef1 100644
--- a/include/asm-m68knommu/unistd.h
+++ b/include/asm-m68knommu/unistd.h
@@ -463,61 +463,6 @@ type name(atype a, btype b, ctype c, dtype d, etype e) \
#define __ARCH_WANT_SYS_SIGPROCMASK
#define __ARCH_WANT_SYS_RT_SIGACTION
-#ifdef __KERNEL_SYSCALLS__
-
-#include <linux/compiler.h>
-#include <linux/interrupt.h>
-#include <linux/types.h>
-
-/*
- * we need this inline - forking from kernel space will result
- * in NO COPY ON WRITE (!!!), until an execve is executed. This
- * is no problem, but for the stack. This is handled by not letting
- * main() use the stack at all after fork(). Thus, no function
- * calls - which means inline code for fork too, as otherwise we
- * would use the stack upon exit from 'fork()'.
- *
- * Actually only pause and fork are needed inline, so that there
- * won't be any messing with the stack from main(), but we define
- * some others too.
- */
-#define __NR__exit __NR_exit
-static inline _syscall0(int,pause)
-static inline _syscall0(int,sync)
-static inline _syscall0(pid_t,setsid)
-static inline _syscall3(int,write,int,fd,const char *,buf,off_t,count)
-static inline _syscall3(int,read,int,fd,char *,buf,off_t,count)
-static inline _syscall3(off_t,lseek,int,fd,off_t,offset,int,count)
-static inline _syscall1(int,dup,int,fd)
-static inline _syscall3(int,execve,const char *,file,char **,argv,char **,envp)
-static inline _syscall3(int,open,const char *,file,int,flag,int,mode)
-static inline _syscall1(int,close,int,fd)
-static inline _syscall1(int,_exit,int,exitcode)
-static inline _syscall3(pid_t,waitpid,pid_t,pid,int *,wait_stat,int,options)
-static inline _syscall1(int,delete_module,const char *,name)
-
-static inline pid_t wait(int * wait_stat)
-{
- return waitpid(-1,wait_stat,0);
-}
-asmlinkage long sys_mmap2(unsigned long addr, unsigned long len,
- unsigned long prot, unsigned long flags,
- unsigned long fd, unsigned long pgoff);
-asmlinkage int sys_execve(char *name, char **argv, char **envp);
-asmlinkage int sys_pipe(unsigned long *fildes);
-struct pt_regs;
-int sys_request_irq(unsigned int,
- irqreturn_t (*)(int, void *, struct pt_regs *),
- unsigned long, const char *, void *);
-void sys_free_irq(unsigned int, void *);
-struct sigaction;
-asmlinkage long sys_rt_sigaction(int sig,
- const struct sigaction __user *act,
- struct sigaction __user *oact,
- size_t sigsetsize);
-
-#endif /* __KERNEL_SYSCALLS__ */
-
/*
* "Conditional" syscalls
*
diff --git a/include/asm-mips/cacheflush.h b/include/asm-mips/cacheflush.h
index 36416fdfcf68..9ab59e2bb233 100644
--- a/include/asm-mips/cacheflush.h
+++ b/include/asm-mips/cacheflush.h
@@ -46,8 +46,6 @@ static inline void flush_dcache_page(struct page *page)
#define flush_dcache_mmap_lock(mapping) do { } while (0)
#define flush_dcache_mmap_unlock(mapping) do { } while (0)
-extern void (*__flush_icache_page)(struct vm_area_struct *vma,
- struct page *page);
static inline void flush_icache_page(struct vm_area_struct *vma,
struct page *page)
{
diff --git a/include/asm-mips/galileo-boards/ev96100.h b/include/asm-mips/galileo-boards/ev96100.h
deleted file mode 100644
index 070dfd84a8e8..000000000000
--- a/include/asm-mips/galileo-boards/ev96100.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- *
- */
-#ifndef _MIPS_EV96100_H
-#define _MIPS_EV96100_H
-
-#include <asm/addrspace.h>
-
-/*
- * GT64120 config space base address
- */
-#define GT64120_BASE (KSEG1ADDR(0x14000000))
-#define MIPS_GT_BASE GT64120_BASE
-
-/*
- * PCI Bus allocation
- */
-#define GT_PCI_MEM_BASE 0x12000000UL
-#define GT_PCI_MEM_SIZE 0x02000000UL
-#define GT_PCI_IO_BASE 0x10000000UL
-#define GT_PCI_IO_SIZE 0x02000000UL
-#define GT_ISA_IO_BASE PCI_IO_BASE
-
-/*
- * Duart I/O ports.
- */
-#define EV96100_COM1_BASE_ADDR (0xBD000000 + 0x20)
-#define EV96100_COM2_BASE_ADDR (0xBD000000 + 0x00)
-
-
-/*
- * EV96100 interrupt controller register base.
- */
-#define EV96100_ICTRL_REGS_BASE (KSEG1ADDR(0x1f000000))
-
-/*
- * EV96100 UART register base.
- */
-#define EV96100_UART0_REGS_BASE EV96100_COM1_BASE_ADDR
-#define EV96100_UART1_REGS_BASE EV96100_COM2_BASE_ADDR
-#define EV96100_BASE_BAUD ( 3686400 / 16 )
-
-
-/*
- * Because of an error/peculiarity in the Galileo chip, we need to swap the
- * bytes when running bigendian.
- */
-#define __GT_READ(ofs) \
- (*(volatile u32 *)(GT64120_BASE+(ofs)))
-#define __GT_WRITE(ofs, data) \
- do { *(volatile u32 *)(GT64120_BASE+(ofs)) = (data); } while (0)
-#define GT_READ(ofs) le32_to_cpu(__GT_READ(ofs))
-#define GT_WRITE(ofs, data) __GT_WRITE(ofs, cpu_to_le32(data))
-
-#endif /* !(_MIPS_EV96100_H) */
diff --git a/include/asm-mips/galileo-boards/ev96100int.h b/include/asm-mips/galileo-boards/ev96100int.h
deleted file mode 100644
index c58b16d06d6e..000000000000
--- a/include/asm-mips/galileo-boards/ev96100int.h
+++ /dev/null
@@ -1,12 +0,0 @@
-/*
- *
- */
-#ifndef _MIPS_EV96100INT_H
-#define _MIPS_EV96100INT_H
-
-#define EV96100INT_UART_0 6 /* IP 6 */
-#define EV96100INT_TIMER 7 /* IP 7 */
-
-extern void ev96100int_init(void);
-
-#endif /* !(_MIPS_EV96100_H) */
diff --git a/include/asm-mips/irqflags.h b/include/asm-mips/irqflags.h
index 43ca09a3a3d0..46bf5de5ac72 100644
--- a/include/asm-mips/irqflags.h
+++ b/include/asm-mips/irqflags.h
@@ -213,12 +213,37 @@ static inline int raw_irqs_disabled_flags(unsigned long flags)
* Do the CPU's IRQ-state tracing from assembly code.
*/
#ifdef CONFIG_TRACE_IRQFLAGS
+/* Reload some registers clobbered by trace_hardirqs_on */
+#ifdef CONFIG_64BIT
+# define TRACE_IRQS_RELOAD_REGS \
+ LONG_L $11, PT_R11(sp); \
+ LONG_L $10, PT_R10(sp); \
+ LONG_L $9, PT_R9(sp); \
+ LONG_L $8, PT_R8(sp); \
+ LONG_L $7, PT_R7(sp); \
+ LONG_L $6, PT_R6(sp); \
+ LONG_L $5, PT_R5(sp); \
+ LONG_L $4, PT_R4(sp); \
+ LONG_L $2, PT_R2(sp)
+#else
+# define TRACE_IRQS_RELOAD_REGS \
+ LONG_L $7, PT_R7(sp); \
+ LONG_L $6, PT_R6(sp); \
+ LONG_L $5, PT_R5(sp); \
+ LONG_L $4, PT_R4(sp); \
+ LONG_L $2, PT_R2(sp)
+#endif
# define TRACE_IRQS_ON \
+ CLI; /* make sure trace_hardirqs_on() is called in kernel level */ \
jal trace_hardirqs_on
+# define TRACE_IRQS_ON_RELOAD \
+ TRACE_IRQS_ON; \
+ TRACE_IRQS_RELOAD_REGS
# define TRACE_IRQS_OFF \
jal trace_hardirqs_off
#else
# define TRACE_IRQS_ON
+# define TRACE_IRQS_ON_RELOAD
# define TRACE_IRQS_OFF
#endif
diff --git a/include/asm-mips/mach-ev64120/mach-gt64120.h b/include/asm-mips/mach-ev64120/mach-gt64120.h
index 13b1443a7a65..7e272ce57ea3 100644
--- a/include/asm-mips/mach-ev64120/mach-gt64120.h
+++ b/include/asm-mips/mach-ev64120/mach-gt64120.h
@@ -42,6 +42,7 @@ extern unsigned long gt64120_base;
#define EV64120_UART0_REGS_BASE (KSEG1ADDR(EV64120_COM1_BASE_ADDR))
#define EV64120_UART1_REGS_BASE (KSEG1ADDR(EV64120_COM2_BASE_ADDR))
#define EV64120_BASE_BAUD ( 3686400 / 16 )
+#define EV64120_UART_IRQ 6
/*
* PCI interrupts will come in on either the INTA or INTD interrups lines,
diff --git a/include/asm-mips/mach-ip27/topology.h b/include/asm-mips/mach-ip27/topology.h
index 59d26b52ba32..a13b715fd9ca 100644
--- a/include/asm-mips/mach-ip27/topology.h
+++ b/include/asm-mips/mach-ip27/topology.h
@@ -22,6 +22,7 @@ extern unsigned char __node_distances[MAX_COMPACT_NODES][MAX_COMPACT_NODES];
#define SD_NODE_INIT (struct sched_domain) { \
.span = CPU_MASK_NONE, \
.parent = NULL, \
+ .child = NULL, \
.groups = NULL, \
.min_interval = 8, \
.max_interval = 32, \
diff --git a/include/asm-mips/serial.h b/include/asm-mips/serial.h
index 035637c67e7c..c882e04e1497 100644
--- a/include/asm-mips/serial.h
+++ b/include/asm-mips/serial.h
@@ -55,19 +55,18 @@
* Galileo EV64120 evaluation board
*/
#ifdef CONFIG_MIPS_EV64120
-#include <asm/galileo-boards/ev96100.h>
-#include <asm/galileo-boards/ev96100int.h>
-#define EV96100_SERIAL_PORT_DEFNS \
- { .baud_base = EV96100_BASE_BAUD, .irq = EV96100INT_UART_0, \
+#include <mach-gt64120.h>
+#define EV64120_SERIAL_PORT_DEFNS \
+ { .baud_base = EV64120_BASE_BAUD, .irq = EV64120_UART_IRQ, \
.flags = STD_COM_FLAGS, \
- .iomem_base = EV96100_UART0_REGS_BASE, .iomem_reg_shift = 2, \
+ .iomem_base = EV64120_UART0_REGS_BASE, .iomem_reg_shift = 2, \
.io_type = SERIAL_IO_MEM }, \
- { .baud_base = EV96100_BASE_BAUD, .irq = EV96100INT_UART_0, \
+ { .baud_base = EV64120_BASE_BAUD, .irq = EV64120_UART_IRQ, \
.flags = STD_COM_FLAGS, \
- .iomem_base = EV96100_UART1_REGS_BASE, .iomem_reg_shift = 2, \
+ .iomem_base = EV64120_UART1_REGS_BASE, .iomem_reg_shift = 2, \
.io_type = SERIAL_IO_MEM },
#else
-#define EV96100_SERIAL_PORT_DEFNS
+#define EV64120_SERIAL_PORT_DEFNS
#endif
#ifdef CONFIG_MIPS_ITE8172
@@ -239,7 +238,7 @@
#define SERIAL_PORT_DFNS \
DDB5477_SERIAL_PORT_DEFNS \
- EV96100_SERIAL_PORT_DEFNS \
+ EV64120_SERIAL_PORT_DEFNS \
IP32_SERIAL_PORT_DEFNS \
ITE_SERIAL_PORT_DEFNS \
IVR_SERIAL_PORT_DEFNS \
diff --git a/include/asm-mips/spinlock.h b/include/asm-mips/spinlock.h
index 4c1a1b53aeaf..c8d5587467bb 100644
--- a/include/asm-mips/spinlock.h
+++ b/include/asm-mips/spinlock.h
@@ -328,4 +328,8 @@ static inline int __raw_write_trylock(raw_rwlock_t *rw)
}
+#define _raw_spin_relax(lock) cpu_relax()
+#define _raw_read_relax(lock) cpu_relax()
+#define _raw_write_relax(lock) cpu_relax()
+
#endif /* _ASM_SPINLOCK_H */
diff --git a/include/asm-mips/stacktrace.h b/include/asm-mips/stacktrace.h
new file mode 100644
index 000000000000..07f873351a86
--- /dev/null
+++ b/include/asm-mips/stacktrace.h
@@ -0,0 +1,44 @@
+#ifndef _ASM_STACKTRACE_H
+#define _ASM_STACKTRACE_H
+
+#include <asm/ptrace.h>
+
+#ifdef CONFIG_KALLSYMS
+extern int raw_show_trace;
+extern unsigned long unwind_stack(struct task_struct *task, unsigned long *sp,
+ unsigned long pc, unsigned long *ra);
+#else
+#define raw_show_trace 1
+#define unwind_stack(task, sp, pc, ra) 0
+#endif
+
+static __always_inline void prepare_frametrace(struct pt_regs *regs)
+{
+#ifndef CONFIG_KALLSYMS
+ /*
+ * Remove any garbage that may be in regs (specially func
+ * addresses) to avoid show_raw_backtrace() to report them
+ */
+ memset(regs, 0, sizeof(*regs));
+#endif
+ __asm__ __volatile__(
+ ".set push\n\t"
+ ".set noat\n\t"
+#ifdef CONFIG_64BIT
+ "1: dla $1, 1b\n\t"
+ "sd $1, %0\n\t"
+ "sd $29, %1\n\t"
+ "sd $31, %2\n\t"
+#else
+ "1: la $1, 1b\n\t"
+ "sw $1, %0\n\t"
+ "sw $29, %1\n\t"
+ "sw $31, %2\n\t"
+#endif
+ ".set pop\n\t"
+ : "=m" (regs->cp0_epc),
+ "=m" (regs->regs[29]), "=m" (regs->regs[31])
+ : : "memory");
+}
+
+#endif /* _ASM_STACKTRACE_H */
diff --git a/include/asm-mips/unistd.h b/include/asm-mips/unistd.h
index c39142920fe6..685c91467e63 100644
--- a/include/asm-mips/unistd.h
+++ b/include/asm-mips/unistd.h
@@ -1212,45 +1212,6 @@ type name (atype a,btype b,ctype c,dtype d,etype e,ftype f) \
# define __ARCH_WANT_COMPAT_SYS_TIME
# endif
-#ifdef __KERNEL_SYSCALLS__
-
-#include <linux/compiler.h>
-#include <linux/types.h>
-#include <linux/linkage.h>
-#include <asm/ptrace.h>
-#include <asm/sim.h>
-
-/*
- * we need this inline - forking from kernel space will result
- * in NO COPY ON WRITE (!!!), until an execve is executed. This
- * is no problem, but for the stack. This is handled by not letting
- * main() use the stack at all after fork(). Thus, no function
- * calls - which means inline code for fork too, as otherwise we
- * would use the stack upon exit from 'fork()'.
- *
- * Actually only pause and fork are needed inline, so that there
- * won't be any messing with the stack from main(), but we define
- * some others too.
- */
-static inline _syscall3(int,execve,const char *,file,char **,argv,char **,envp)
-
-asmlinkage unsigned long sys_mmap(
- unsigned long addr, size_t len,
- int prot, int flags,
- int fd, off_t offset);
-asmlinkage long sys_mmap2(
- unsigned long addr, unsigned long len,
- unsigned long prot, unsigned long flags,
- unsigned long fd, unsigned long pgoff);
-asmlinkage int sys_execve(nabi_no_regargs struct pt_regs regs);
-asmlinkage int sys_pipe(nabi_no_regargs struct pt_regs regs);
-struct sigaction;
-asmlinkage long sys_rt_sigaction(int sig,
- const struct sigaction __user *act,
- struct sigaction __user *oact,
- size_t sigsetsize);
-
-#endif /* __KERNEL_SYSCALLS__ */
#endif /* !__ASSEMBLY__ */
/*
diff --git a/include/asm-parisc/spinlock.h b/include/asm-parisc/spinlock.h
index a93960e232cf..e1825530365d 100644
--- a/include/asm-parisc/spinlock.h
+++ b/include/asm-parisc/spinlock.h
@@ -152,4 +152,8 @@ static __inline__ int __raw_write_can_lock(raw_rwlock_t *rw)
return !rw->counter;
}
+#define _raw_spin_relax(lock) cpu_relax()
+#define _raw_read_relax(lock) cpu_relax()
+#define _raw_write_relax(lock) cpu_relax()
+
#endif /* __ASM_SPINLOCK_H */
diff --git a/include/asm-parisc/unistd.h b/include/asm-parisc/unistd.h
index 27bcfad1c3e3..53b0f5d290e4 100644
--- a/include/asm-parisc/unistd.h
+++ b/include/asm-parisc/unistd.h
@@ -952,92 +952,6 @@ type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5) \
#define __ARCH_WANT_SYS_SIGPROCMASK
#define __ARCH_WANT_SYS_RT_SIGACTION
-/* mmap & mmap2 take 6 arguments */
-#define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4,type5,arg5,type6,arg6) \
-type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5, type6 arg6) \
-{ \
- return K_INLINE_SYSCALL(name, 6, arg1, arg2, arg3, arg4, arg5, arg6); \
-}
-
-#ifdef __KERNEL_SYSCALLS__
-
-#include <asm/current.h>
-#include <linux/compiler.h>
-#include <linux/types.h>
-#include <linux/syscalls.h>
-
-static inline pid_t setsid(void)
-{
- return sys_setsid();
-}
-
-static inline int write(int fd, const char *buf, off_t count)
-{
- return sys_write(fd, buf, count);
-}
-
-static inline int read(int fd, char *buf, off_t count)
-{
- return sys_read(fd, buf, count);
-}
-
-static inline off_t lseek(int fd, off_t offset, int count)
-{
- return sys_lseek(fd, offset, count);
-}
-
-static inline int dup(int fd)
-{
- return sys_dup(fd);
-}
-
-static inline int execve(char *filename, char * argv [],
- char * envp[])
-{
- extern int __execve(char *, char **, char **, struct task_struct *);
- return __execve(filename, argv, envp, current);
-}
-
-static inline int open(const char *file, int flag, int mode)
-{
- return sys_open(file, flag, mode);
-}
-
-static inline int close(int fd)
-{
- return sys_close(fd);
-}
-
-static inline void _exit(int exitcode)
-{
- sys_exit(exitcode);
-}
-
-static inline pid_t waitpid(pid_t pid, int *wait_stat, int options)
-{
- return sys_wait4(pid, wait_stat, options, NULL);
-}
-
-asmlinkage unsigned long sys_mmap(unsigned long addr, unsigned long len,
- unsigned long prot, unsigned long flags,
- unsigned long fd, unsigned long offset);
-asmlinkage unsigned long sys_mmap2(unsigned long addr, unsigned long len,
- unsigned long prot, unsigned long flags,
- unsigned long fd, unsigned long pgoff);
-struct pt_regs;
-asmlinkage int sys_execve(struct pt_regs *regs);
-int sys_clone(unsigned long clone_flags, unsigned long usp,
- struct pt_regs *regs);
-int sys_vfork(struct pt_regs *regs);
-int sys_pipe(int *fildes);
-struct sigaction;
-asmlinkage long sys_rt_sigaction(int sig,
- const struct sigaction __user *act,
- struct sigaction __user *oact,
- size_t sigsetsize);
-
-#endif /* __KERNEL_SYSCALLS__ */
-
#endif /* __ASSEMBLY__ */
#undef STR
diff --git a/include/asm-powerpc/bug.h b/include/asm-powerpc/bug.h
index f44b529e3298..978b2c7e84ea 100644
--- a/include/asm-powerpc/bug.h
+++ b/include/asm-powerpc/bug.h
@@ -70,9 +70,10 @@ struct bug_entry *find_bug(unsigned long bugaddr);
"i" (__FILE__), "i" (__FUNCTION__)); \
} while (0)
-#define WARN_ON(x) do { \
- if (__builtin_constant_p(x)) { \
- if (x) \
+#define WARN_ON(x) ({ \
+ typeof(x) __ret_warn_on = (x); \
+ if (__builtin_constant_p(__ret_warn_on)) { \
+ if (__ret_warn_on) \
__WARN(); \
} else { \
__asm__ __volatile__( \
@@ -80,11 +81,12 @@ struct bug_entry *find_bug(unsigned long bugaddr);
".section __bug_table,\"a\"\n" \
"\t"PPC_LONG" 1b,%1,%2,%3\n" \
".previous" \
- : : "r" ((long)(x)), \
+ : : "r" (__ret_warn_on), \
"i" (__LINE__ + BUG_WARNING_TRAP), \
"i" (__FILE__), "i" (__FUNCTION__)); \
} \
-} while (0)
+ unlikely(__ret_warn_on); \
+})
#define HAVE_ARCH_BUG
#define HAVE_ARCH_BUG_ON
diff --git a/include/asm-powerpc/fs_pd.h b/include/asm-powerpc/fs_pd.h
new file mode 100644
index 000000000000..3d0e819d37f1
--- /dev/null
+++ b/include/asm-powerpc/fs_pd.h
@@ -0,0 +1,45 @@
+/*
+ * Platform information definitions.
+ *
+ * 2006 (c) MontaVista Software, Inc.
+ * Vitaly Bordug <vbordug@ru.mvista.com>
+ *
+ * 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 FS_PD_H
+#define FS_PD_H
+#include <asm/cpm2.h>
+#include <sysdev/fsl_soc.h>
+#include <asm/time.h>
+
+static inline int uart_baudrate(void)
+{
+ return get_baudrate();
+}
+
+static inline int uart_clock(void)
+{
+ return ppc_proc_freq;
+}
+
+#define cpm2_map(member) \
+({ \
+ u32 offset = offsetof(cpm2_map_t, member); \
+ void *addr = ioremap (CPM_MAP_ADDR + offset, \
+ sizeof( ((cpm2_map_t*)0)->member)); \
+ addr; \
+})
+
+#define cpm2_map_size(member, size) \
+({ \
+ u32 offset = offsetof(cpm2_map_t, member); \
+ void *addr = ioremap (CPM_MAP_ADDR + offset, size); \
+ addr; \
+})
+
+#define cpm2_unmap(addr) iounmap(addr)
+
+#endif
diff --git a/include/asm-powerpc/io.h b/include/asm-powerpc/io.h
index 46bae1cf385b..cbbd8c648df1 100644
--- a/include/asm-powerpc/io.h
+++ b/include/asm-powerpc/io.h
@@ -11,6 +11,7 @@
/* Check of existence of legacy devices */
extern int check_legacy_ioport(unsigned long base_port);
+#define PNPBIOS_BASE 0xf000 /* only relevant for PReP */
#ifndef CONFIG_PPC64
#include <asm-ppc/io.h>
diff --git a/include/asm-powerpc/kprobes.h b/include/asm-powerpc/kprobes.h
index 34e1f89a5fa0..2dafa376a63f 100644
--- a/include/asm-powerpc/kprobes.h
+++ b/include/asm-powerpc/kprobes.h
@@ -44,6 +44,28 @@ typedef unsigned int kprobe_opcode_t;
#define IS_TDI(instr) (((instr) & 0xfc000000) == 0x08000000)
#define IS_TWI(instr) (((instr) & 0xfc000000) == 0x0c000000)
+/*
+ * 64bit powerpc uses function descriptors.
+ * Handle cases where:
+ * - User passes a <.symbol> or <module:.symbol>
+ * - User passes a <symbol> or <module:symbol>
+ * - User passes a non-existant symbol, kallsyms_lookup_name
+ * returns 0. Don't deref the NULL pointer in that case
+ */
+#define kprobe_lookup_name(name, addr) \
+{ \
+ addr = (kprobe_opcode_t *)kallsyms_lookup_name(name); \
+ if (addr) { \
+ char *colon; \
+ if ((colon = strchr(name, ':')) != NULL) { \
+ colon++; \
+ if (*colon != '\0' && *colon != '.') \
+ addr = *(kprobe_opcode_t **)addr; \
+ } else if (name[0] != '.') \
+ addr = *(kprobe_opcode_t **)addr; \
+ } \
+}
+
#define JPROBE_ENTRY(pentry) (kprobe_opcode_t *)((func_descr_t *)pentry)
#define is_trap(instr) (IS_TW(instr) || IS_TD(instr) || \
diff --git a/include/asm-powerpc/mpc85xx.h b/include/asm-powerpc/mpc85xx.h
new file mode 100644
index 000000000000..ccdb8a21138f
--- /dev/null
+++ b/include/asm-powerpc/mpc85xx.h
@@ -0,0 +1,53 @@
+/*
+ * include/asm-powerpc/mpc85xx.h
+ *
+ * MPC85xx definitions
+ *
+ * Maintainer: Kumar Gala <galak@kernel.crashing.org>
+ *
+ * Copyright 2004 Freescale Semiconductor, Inc
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+#ifdef __KERNEL__
+#ifndef __ASM_MPC85xx_H__
+#define __ASM_MPC85xx_H__
+
+#include <asm/mmu.h>
+
+#ifdef CONFIG_85xx
+
+#if defined(CONFIG_MPC8540_ADS) || defined(CONFIG_MPC8560_ADS)
+#include <platforms/85xx/mpc85xx_ads.h>
+#endif
+#if defined(CONFIG_MPC8555_CDS) || defined(CONFIG_MPC8548_CDS)
+#include <platforms/85xx/mpc8555_cds.h>
+#endif
+#ifdef CONFIG_MPC85xx_CDS
+#include <platforms/85xx/mpc85xx_cds.h>
+#endif
+
+#define _IO_BASE isa_io_base
+#define _ISA_MEM_BASE isa_mem_base
+#ifdef CONFIG_PCI
+#define PCI_DRAM_OFFSET pci_dram_offset
+#else
+#define PCI_DRAM_OFFSET 0
+#endif
+
+/* Let modules/drivers get at CCSRBAR */
+extern phys_addr_t get_ccsrbar(void);
+
+#ifdef MODULE
+#define CCSRBAR get_ccsrbar()
+#else
+#define CCSRBAR BOARD_CCSRBAR
+#endif
+
+#endif /* CONFIG_85xx */
+#endif /* __ASM_MPC85xx_H__ */
+#endif /* __KERNEL__ */
diff --git a/include/asm-powerpc/ptrace.h b/include/asm-powerpc/ptrace.h
index 4435efe85d0e..4ad77a13f865 100644
--- a/include/asm-powerpc/ptrace.h
+++ b/include/asm-powerpc/ptrace.h
@@ -73,6 +73,8 @@ struct pt_regs {
#ifndef __ASSEMBLY__
#define instruction_pointer(regs) ((regs)->nip)
+#define regs_return_value(regs) ((regs)->gpr[3])
+
#ifdef CONFIG_SMP
extern unsigned long profile_pc(struct pt_regs *regs);
#else
diff --git a/include/asm-powerpc/spinlock.h b/include/asm-powerpc/spinlock.h
index c31e4382a775..cc4cfceac67c 100644
--- a/include/asm-powerpc/spinlock.h
+++ b/include/asm-powerpc/spinlock.h
@@ -285,5 +285,9 @@ static __inline__ void __raw_write_unlock(raw_rwlock_t *rw)
rw->lock = 0;
}
+#define _raw_spin_relax(lock) __spin_yield(lock)
+#define _raw_read_relax(lock) __rw_yield(lock)
+#define _raw_write_relax(lock) __rw_yield(lock)
+
#endif /* __KERNEL__ */
#endif /* __ASM_SPINLOCK_H */
diff --git a/include/asm-powerpc/time.h b/include/asm-powerpc/time.h
index 5785ac4737b5..b051d4c88c3b 100644
--- a/include/asm-powerpc/time.h
+++ b/include/asm-powerpc/time.h
@@ -39,6 +39,10 @@ extern void generic_calibrate_decr(void);
extern void wakeup_decrementer(void);
extern void snapshot_timebase(void);
+#ifdef CONFIG_RTC_CLASS
+extern int __init rtc_class_hookup(void);
+#endif
+
/* Some sane defaults: 125 MHz timebase, 1GHz processor */
extern unsigned long ppc_proc_freq;
#define DEFAULT_PROC_FREQ (DEFAULT_TB_FREQ * 8)
@@ -234,4 +238,4 @@ extern void snapshot_timebases(void);
#endif
#endif /* __KERNEL__ */
-#endif /* __PPC64_TIME_H */
+#endif /* __POWERPC_TIME_H */
diff --git a/include/asm-powerpc/topology.h b/include/asm-powerpc/topology.h
index bbc3844b086f..8f7ee16781a4 100644
--- a/include/asm-powerpc/topology.h
+++ b/include/asm-powerpc/topology.h
@@ -43,6 +43,7 @@ extern int pcibus_to_node(struct pci_bus *bus);
#define SD_NODE_INIT (struct sched_domain) { \
.span = CPU_MASK_NONE, \
.parent = NULL, \
+ .child = NULL, \
.groups = NULL, \
.min_interval = 8, \
.max_interval = 32, \
diff --git a/include/asm-powerpc/unistd.h b/include/asm-powerpc/unistd.h
index eb66eae6616f..464a48cce7f5 100644
--- a/include/asm-powerpc/unistd.h
+++ b/include/asm-powerpc/unistd.h
@@ -479,13 +479,6 @@ type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5, type6 arg6
#endif
/*
- * System call prototypes.
- */
-#ifdef __KERNEL_SYSCALLS__
-extern int execve(const char *file, char **argv, char **envp);
-#endif /* __KERNEL_SYSCALLS__ */
-
-/*
* "Conditional" syscalls
*
* What we want is __attribute__((weak,alias("sys_ni_syscall"))),
diff --git a/include/asm-ppc/cpm2.h b/include/asm-ppc/cpm2.h
index f6a7ff04ffe5..220cc2debe08 100644
--- a/include/asm-ppc/cpm2.h
+++ b/include/asm-ppc/cpm2.h
@@ -42,6 +42,8 @@
#define CPM_CR_IDMA4_SBLOCK (0x17)
#define CPM_CR_MCC1_SBLOCK (0x1c)
+#define CPM_CR_FCC_SBLOCK(x) (x + 0x10)
+
#define CPM_CR_SCC1_PAGE (0x00)
#define CPM_CR_SCC2_PAGE (0x01)
#define CPM_CR_SCC3_PAGE (0x02)
@@ -62,6 +64,8 @@
#define CPM_CR_MCC1_PAGE (0x07)
#define CPM_CR_MCC2_PAGE (0x08)
+#define CPM_CR_FCC_PAGE(x) (x + 0x04)
+
/* Some opcodes (there are more...later)
*/
#define CPM_CR_INIT_TRX ((ushort)0x0000)
@@ -173,6 +177,10 @@ typedef struct cpm_buf_desc {
#define PROFF_I2C_BASE ((uint)0x8afc)
#define PROFF_IDMA4_BASE ((uint)0x8afe)
+#define PROFF_SCC_SIZE ((uint)0x100)
+#define PROFF_FCC_SIZE ((uint)0x100)
+#define PROFF_SMC_SIZE ((uint)64)
+
/* The SMCs are relocated to any of the first eight DPRAM pages.
* We will fix these at the first locations of DPRAM, until we
* get some microcode patches :-).
@@ -1186,7 +1194,60 @@ typedef struct im_idma {
#define FCC_MEM_OFFSET(x) (CPM_FCC_SPECIAL_BASE + (x*128))
#define FCC1_MEM_OFFSET FCC_MEM_OFFSET(0)
#define FCC2_MEM_OFFSET FCC_MEM_OFFSET(1)
-#define FCC2_MEM_OFFSET FCC_MEM_OFFSET(2)
+#define FCC3_MEM_OFFSET FCC_MEM_OFFSET(2)
+
+/* Clocks and GRG's */
+
+enum cpm_clk_dir {
+ CPM_CLK_RX,
+ CPM_CLK_TX,
+ CPM_CLK_RTX
+};
+
+enum cpm_clk_target {
+ CPM_CLK_SCC1,
+ CPM_CLK_SCC2,
+ CPM_CLK_SCC3,
+ CPM_CLK_SCC4,
+ CPM_CLK_FCC1,
+ CPM_CLK_FCC2,
+ CPM_CLK_FCC3
+};
+
+enum cpm_clk {
+ CPM_CLK_NONE = 0,
+ CPM_BRG1, /* Baud Rate Generator 1 */
+ CPM_BRG2, /* Baud Rate Generator 2 */
+ CPM_BRG3, /* Baud Rate Generator 3 */
+ CPM_BRG4, /* Baud Rate Generator 4 */
+ CPM_BRG5, /* Baud Rate Generator 5 */
+ CPM_BRG6, /* Baud Rate Generator 6 */
+ CPM_BRG7, /* Baud Rate Generator 7 */
+ CPM_BRG8, /* Baud Rate Generator 8 */
+ CPM_CLK1, /* Clock 1 */
+ CPM_CLK2, /* Clock 2 */
+ CPM_CLK3, /* Clock 3 */
+ CPM_CLK4, /* Clock 4 */
+ CPM_CLK5, /* Clock 5 */
+ CPM_CLK6, /* Clock 6 */
+ CPM_CLK7, /* Clock 7 */
+ CPM_CLK8, /* Clock 8 */
+ CPM_CLK9, /* Clock 9 */
+ CPM_CLK10, /* Clock 10 */
+ CPM_CLK11, /* Clock 11 */
+ CPM_CLK12, /* Clock 12 */
+ CPM_CLK13, /* Clock 13 */
+ CPM_CLK14, /* Clock 14 */
+ CPM_CLK15, /* Clock 15 */
+ CPM_CLK16, /* Clock 16 */
+ CPM_CLK17, /* Clock 17 */
+ CPM_CLK18, /* Clock 18 */
+ CPM_CLK19, /* Clock 19 */
+ CPM_CLK20, /* Clock 20 */
+ CPM_CLK_DUMMY
+};
+
+extern int cpm2_clk_setup(enum cpm_clk_target target, int clock, int mode);
#endif /* __CPM2__ */
#endif /* __KERNEL__ */
diff --git a/include/asm-ppc/fs_pd.h b/include/asm-ppc/fs_pd.h
new file mode 100644
index 000000000000..8691327653af
--- /dev/null
+++ b/include/asm-ppc/fs_pd.h
@@ -0,0 +1,36 @@
+/*
+ * Platform information definitions.
+ *
+ * 2006 (c) MontaVista Software, Inc.
+ * Vitaly Bordug <vbordug@ru.mvista.com>
+ *
+ * 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 FS_PD_H
+#define FS_PD_H
+
+static inline int uart_baudrate(void)
+{
+ int baud;
+ bd_t *bd = (bd_t *) __res;
+
+ if (bd->bi_baudrate)
+ baud = bd->bi_baudrate;
+ else
+ baud = -1;
+ return baud;
+}
+
+static inline int uart_clock(void)
+{
+ return (((bd_t *) __res)->bi_intfreq);
+}
+
+#define cpm2_map(member) (&cpm2_immr->member)
+#define cpm2_map_size(member, size) (&cpm2_immr->member)
+#define cpm2_unmap(addr) do {} while(0)
+
+#endif
diff --git a/include/asm-ppc/rheap.h b/include/asm-ppc/rheap.h
index e6ca1f67cedc..65b93225a778 100644
--- a/include/asm-ppc/rheap.h
+++ b/include/asm-ppc/rheap.h
@@ -62,6 +62,10 @@ extern int rh_attach_region(rh_info_t * info, void *start, int size);
/* Detach a free region */
extern void *rh_detach_region(rh_info_t * info, void *start, int size);
+/* Allocate the given size from the remote heap (with alignment) */
+extern void *rh_alloc_align(rh_info_t * info, int size, int alignment,
+ const char *owner);
+
/* Allocate the given size from the remote heap */
extern void *rh_alloc(rh_info_t * info, int size, const char *owner);
diff --git a/include/asm-ppc/spinlock.h b/include/asm-ppc/spinlock.h
index 5c64b75f0295..fccaf5531e57 100644
--- a/include/asm-ppc/spinlock.h
+++ b/include/asm-ppc/spinlock.h
@@ -161,4 +161,8 @@ static __inline__ void __raw_write_unlock(raw_rwlock_t *rw)
rw->lock = 0;
}
+#define _raw_spin_relax(lock) cpu_relax()
+#define _raw_read_relax(lock) cpu_relax()
+#define _raw_write_relax(lock) cpu_relax()
+
#endif /* __ASM_SPINLOCK_H */
diff --git a/include/asm-s390/irq.h b/include/asm-s390/irq.h
index bd1a721f7aa2..7da991a858f8 100644
--- a/include/asm-s390/irq.h
+++ b/include/asm-s390/irq.h
@@ -19,8 +19,5 @@ enum interruption_class {
NR_IRQS,
};
-#define touch_nmi_watchdog() do { } while(0)
-
#endif /* __KERNEL__ */
#endif
-
diff --git a/include/asm-s390/pgtable.h b/include/asm-s390/pgtable.h
index 83425cdefc91..ecdff13b2505 100644
--- a/include/asm-s390/pgtable.h
+++ b/include/asm-s390/pgtable.h
@@ -31,9 +31,9 @@
* the S390 page table tree.
*/
#ifndef __ASSEMBLY__
+#include <linux/mm_types.h>
#include <asm/bug.h>
#include <asm/processor.h>
-#include <linux/threads.h>
struct vm_area_struct; /* forward declaration (include/linux/mm.h) */
struct mm_struct;
@@ -597,31 +597,31 @@ ptep_establish(struct vm_area_struct *vma,
* should therefore only be called if it is not mapped in any
* address space.
*/
-#define page_test_and_clear_dirty(_page) \
-({ \
- struct page *__page = (_page); \
- unsigned long __physpage = __pa((__page-mem_map) << PAGE_SHIFT); \
- int __skey = page_get_storage_key(__physpage); \
- if (__skey & _PAGE_CHANGED) \
- page_set_storage_key(__physpage, __skey & ~_PAGE_CHANGED);\
- (__skey & _PAGE_CHANGED); \
-})
+static inline int page_test_and_clear_dirty(struct page *page)
+{
+ unsigned long physpage = __pa((page - mem_map) << PAGE_SHIFT);
+ int skey = page_get_storage_key(physpage);
+
+ if (skey & _PAGE_CHANGED)
+ page_set_storage_key(physpage, skey & ~_PAGE_CHANGED);
+ return skey & _PAGE_CHANGED;
+}
/*
* Test and clear referenced bit in storage key.
*/
-#define page_test_and_clear_young(page) \
-({ \
- struct page *__page = (page); \
- unsigned long __physpage = __pa((__page-mem_map) << PAGE_SHIFT);\
- int __ccode; \
- asm volatile( \
- " rrbe 0,%1\n" \
- " ipm %0\n" \
- " srl %0,28\n" \
- : "=d" (__ccode) : "a" (__physpage) : "cc"); \
- (__ccode & 2); \
-})
+static inline int page_test_and_clear_young(struct page *page)
+{
+ unsigned long physpage = __pa((page - mem_map) << PAGE_SHIFT);
+ int ccode;
+
+ asm volatile (
+ "rrbe 0,%1\n"
+ "ipm %0\n"
+ "srl %0,28\n"
+ : "=d" (ccode) : "a" (physpage) : "cc" );
+ return ccode & 2;
+}
/*
* Conversion functions: convert a page and protection to a page entry,
@@ -634,32 +634,28 @@ static inline pte_t mk_pte_phys(unsigned long physpage, pgprot_t pgprot)
return __pte;
}
-#define mk_pte(pg, pgprot) \
-({ \
- struct page *__page = (pg); \
- pgprot_t __pgprot = (pgprot); \
- unsigned long __physpage = __pa((__page-mem_map) << PAGE_SHIFT); \
- pte_t __pte = mk_pte_phys(__physpage, __pgprot); \
- __pte; \
-})
+static inline pte_t mk_pte(struct page *page, pgprot_t pgprot)
+{
+ unsigned long physpage = __pa((page - mem_map) << PAGE_SHIFT);
-#define pfn_pte(pfn, pgprot) \
-({ \
- pgprot_t __pgprot = (pgprot); \
- unsigned long __physpage = __pa((pfn) << PAGE_SHIFT); \
- pte_t __pte = mk_pte_phys(__physpage, __pgprot); \
- __pte; \
-})
+ return mk_pte_phys(physpage, pgprot);
+}
+
+static inline pte_t pfn_pte(unsigned long pfn, pgprot_t pgprot)
+{
+ unsigned long physpage = __pa((pfn) << PAGE_SHIFT);
+
+ return mk_pte_phys(physpage, pgprot);
+}
#ifdef __s390x__
-#define pfn_pmd(pfn, pgprot) \
-({ \
- pgprot_t __pgprot = (pgprot); \
- unsigned long __physpage = __pa((pfn) << PAGE_SHIFT); \
- pmd_t __pmd = __pmd(__physpage + pgprot_val(__pgprot)); \
- __pmd; \
-})
+static inline pmd_t pfn_pmd(unsigned long pfn, pgprot_t pgprot)
+{
+ unsigned long physpage = __pa((pfn) << PAGE_SHIFT);
+
+ return __pmd(physpage + pgprot_val(pgprot));
+}
#endif /* __s390x__ */
diff --git a/include/asm-s390/ptrace.h b/include/asm-s390/ptrace.h
index 8d2bf65b0b64..7b768c5c68a8 100644
--- a/include/asm-s390/ptrace.h
+++ b/include/asm-s390/ptrace.h
@@ -472,6 +472,7 @@ struct user_regs_struct
#define user_mode(regs) (((regs)->psw.mask & PSW_MASK_PSTATE) != 0)
#define instruction_pointer(regs) ((regs)->psw.addr & PSW_ADDR_INSN)
+#define regs_return_value(regs)((regs)->gprs[2])
#define profile_pc(regs) instruction_pointer(regs)
extern void show_regs(struct pt_regs * regs);
#endif
diff --git a/include/asm-s390/setup.h b/include/asm-s390/setup.h
index f1959732b6fd..5d72eda8a11b 100644
--- a/include/asm-s390/setup.h
+++ b/include/asm-s390/setup.h
@@ -39,6 +39,7 @@ extern unsigned long machine_flags;
#define MACHINE_IS_P390 (machine_flags & 4)
#define MACHINE_HAS_MVPG (machine_flags & 16)
#define MACHINE_HAS_IDTE (machine_flags & 128)
+#define MACHINE_HAS_DIAG9C (machine_flags & 256)
#ifndef __s390x__
#define MACHINE_HAS_IEEE (machine_flags & 2)
diff --git a/include/asm-s390/spinlock.h b/include/asm-s390/spinlock.h
index ce3edf6d63b3..6b78af16999b 100644
--- a/include/asm-s390/spinlock.h
+++ b/include/asm-s390/spinlock.h
@@ -13,6 +13,8 @@
#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ > 2)
+#include <linux/smp.h>
+
static inline int
_raw_compare_and_swap(volatile unsigned int *lock,
unsigned int old, unsigned int new)
@@ -50,34 +52,46 @@ _raw_compare_and_swap(volatile unsigned int *lock,
* (the type definitions are in asm/spinlock_types.h)
*/
-#define __raw_spin_is_locked(x) ((x)->lock != 0)
+#define __raw_spin_is_locked(x) ((x)->owner_cpu != 0)
#define __raw_spin_lock_flags(lock, flags) __raw_spin_lock(lock)
#define __raw_spin_unlock_wait(lock) \
- do { while (__raw_spin_is_locked(lock)) cpu_relax(); } while (0)
+ do { while (__raw_spin_is_locked(lock)) \
+ _raw_spin_relax(lock); } while (0)
-extern void _raw_spin_lock_wait(raw_spinlock_t *lp, unsigned int pc);
-extern int _raw_spin_trylock_retry(raw_spinlock_t *lp, unsigned int pc);
+extern void _raw_spin_lock_wait(raw_spinlock_t *, unsigned int pc);
+extern int _raw_spin_trylock_retry(raw_spinlock_t *, unsigned int pc);
+extern void _raw_spin_relax(raw_spinlock_t *lock);
static inline void __raw_spin_lock(raw_spinlock_t *lp)
{
unsigned long pc = 1 | (unsigned long) __builtin_return_address(0);
-
- if (unlikely(_raw_compare_and_swap(&lp->lock, 0, pc) != 0))
- _raw_spin_lock_wait(lp, pc);
+ int old;
+
+ old = _raw_compare_and_swap(&lp->owner_cpu, 0, ~smp_processor_id());
+ if (likely(old == 0)) {
+ lp->owner_pc = pc;
+ return;
+ }
+ _raw_spin_lock_wait(lp, pc);
}
static inline int __raw_spin_trylock(raw_spinlock_t *lp)
{
unsigned long pc = 1 | (unsigned long) __builtin_return_address(0);
+ int old;
- if (likely(_raw_compare_and_swap(&lp->lock, 0, pc) == 0))
+ old = _raw_compare_and_swap(&lp->owner_cpu, 0, ~smp_processor_id());
+ if (likely(old == 0)) {
+ lp->owner_pc = pc;
return 1;
+ }
return _raw_spin_trylock_retry(lp, pc);
}
static inline void __raw_spin_unlock(raw_spinlock_t *lp)
{
- _raw_compare_and_swap(&lp->lock, lp->lock, 0);
+ lp->owner_pc = 0;
+ _raw_compare_and_swap(&lp->owner_cpu, lp->owner_cpu, 0);
}
/*
@@ -154,4 +168,7 @@ static inline int __raw_write_trylock(raw_rwlock_t *rw)
return _raw_write_trylock_retry(rw);
}
+#define _raw_read_relax(lock) cpu_relax()
+#define _raw_write_relax(lock) cpu_relax()
+
#endif /* __ASM_SPINLOCK_H */
diff --git a/include/asm-s390/spinlock_types.h b/include/asm-s390/spinlock_types.h
index f79a2216204f..b7ac13f7aa37 100644
--- a/include/asm-s390/spinlock_types.h
+++ b/include/asm-s390/spinlock_types.h
@@ -6,16 +6,16 @@
#endif
typedef struct {
- volatile unsigned int lock;
+ volatile unsigned int owner_cpu;
+ volatile unsigned int owner_pc;
} __attribute__ ((aligned (4))) raw_spinlock_t;
#define __RAW_SPIN_LOCK_UNLOCKED { 0 }
typedef struct {
volatile unsigned int lock;
- volatile unsigned int owner_pc;
} raw_rwlock_t;
-#define __RAW_RW_LOCK_UNLOCKED { 0, 0 }
+#define __RAW_RW_LOCK_UNLOCKED { 0 }
#endif
diff --git a/include/asm-s390/unistd.h b/include/asm-s390/unistd.h
index 0361ac5dcde3..0cccfd83c457 100644
--- a/include/asm-s390/unistd.h
+++ b/include/asm-s390/unistd.h
@@ -523,57 +523,6 @@ type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
# define __ARCH_WANT_COMPAT_SYS_RT_SIGSUSPEND
# endif
-#ifdef __KERNEL_SYSCALLS__
-
-#include <linux/compiler.h>
-#include <linux/types.h>
-#include <asm/ptrace.h>
-#include <asm/stat.h>
-#include <linux/syscalls.h>
-
-/*
- * we need this inline - forking from kernel space will result
- * in NO COPY ON WRITE (!!!), until an execve is executed. This
- * is no problem, but for the stack. This is handled by not letting
- * main() use the stack at all after fork(). Thus, no function
- * calls - which means inline code for fork too, as otherwise we
- * would use the stack upon exit from 'fork()'.
- *
- * Actually only pause and fork are needed inline, so that there
- * won't be any messing with the stack from main(), but we define
- * some others too.
- */
-#define __NR__exit __NR_exit
-static inline _syscall0(pid_t,setsid)
-static inline _syscall3(int,write,int,fd,const char *,buf,off_t,count)
-static inline _syscall3(int,read,int,fd,char *,buf,off_t,count)
-static inline _syscall3(off_t,lseek,int,fd,off_t,offset,int,count)
-static inline _syscall1(int,dup,int,fd)
-static inline _syscall3(int,execve,const char *,file,char **,argv,char **,envp)
-static inline _syscall3(int,open,const char *,file,int,flag,int,mode)
-static inline _syscall1(int,close,int,fd)
-static inline _syscall2(long,stat,char *,filename,struct stat *,statbuf)
-
-static inline pid_t waitpid(int pid, int *wait_stat, int flags)
-{
- return sys_wait4(pid, wait_stat, flags, NULL);
-}
-struct mmap_arg_struct;
-asmlinkage long sys_mmap2(struct mmap_arg_struct __user *arg);
-
-asmlinkage long sys_execve(struct pt_regs regs);
-asmlinkage long sys_clone(struct pt_regs regs);
-asmlinkage long sys_fork(struct pt_regs regs);
-asmlinkage long sys_vfork(struct pt_regs regs);
-asmlinkage long sys_pipe(unsigned long __user *fildes);
-struct sigaction;
-asmlinkage long sys_rt_sigaction(int sig,
- const struct sigaction __user *act,
- struct sigaction __user *oact,
- size_t sigsetsize);
-
-#endif /* __KERNEL_SYSCALLS__ */
-
/*
* "Conditional" syscalls
*
diff --git a/include/asm-sh/.gitignore b/include/asm-sh/.gitignore
new file mode 100644
index 000000000000..9218ef82b698
--- /dev/null
+++ b/include/asm-sh/.gitignore
@@ -0,0 +1,3 @@
+cpu
+mach
+machtypes.h
diff --git a/include/asm-sh/bugs.h b/include/asm-sh/bugs.h
index b4000c8bf31b..beeea40f549e 100644
--- a/include/asm-sh/bugs.h
+++ b/include/asm-sh/bugs.h
@@ -18,7 +18,7 @@ static void __init check_bugs(void)
{
extern char *get_cpu_subtype(void);
extern unsigned long loops_per_jiffy;
- char *p= &system_utsname.machine[2]; /* "sh" */
+ char *p= &init_utsname()->machine[2]; /* "sh" */
cpu_data->loops_per_jiffy = loops_per_jiffy;
diff --git a/include/asm-sh/cpu-sh3/rtc.h b/include/asm-sh/cpu-sh3/rtc.h
deleted file mode 100644
index 2d926671115a..000000000000
--- a/include/asm-sh/cpu-sh3/rtc.h
+++ /dev/null
@@ -1,25 +0,0 @@
-#ifndef __ASM_CPU_SH3_RTC_H
-#define __ASM_CPU_SH3_RTC_H
-
-/* SH-3 RTC */
-#define R64CNT 0xfffffec0
-#define RSECCNT 0xfffffec2
-#define RMINCNT 0xfffffec4
-#define RHRCNT 0xfffffec6
-#define RWKCNT 0xfffffec8
-#define RDAYCNT 0xfffffeca
-#define RMONCNT 0xfffffecc
-#define RYRCNT 0xfffffece
-#define RSECAR 0xfffffed0
-#define RMINAR 0xfffffed2
-#define RHRAR 0xfffffed4
-#define RWKAR 0xfffffed6
-#define RDAYAR 0xfffffed8
-#define RMONAR 0xfffffeda
-#define RCR1 0xfffffedc
-#define RCR2 0xfffffede
-
-#define RTC_BIT_INVERTED 0 /* No bug on SH7708, SH7709A */
-
-#endif /* __ASM_CPU_SH3_RTC_H */
-
diff --git a/include/asm-sh/cpu-sh4/rtc.h b/include/asm-sh/cpu-sh4/rtc.h
deleted file mode 100644
index e091e32a67b7..000000000000
--- a/include/asm-sh/cpu-sh4/rtc.h
+++ /dev/null
@@ -1,25 +0,0 @@
-#ifndef __ASM_CPU_SH4_RTC_H
-#define __ASM_CPU_SH4_RTC_H
-
-/* SH-4 RTC */
-#define R64CNT 0xffc80000
-#define RSECCNT 0xffc80004
-#define RMINCNT 0xffc80008
-#define RHRCNT 0xffc8000c
-#define RWKCNT 0xffc80010
-#define RDAYCNT 0xffc80014
-#define RMONCNT 0xffc80018
-#define RYRCNT 0xffc8001c /* 16bit */
-#define RSECAR 0xffc80020
-#define RMINAR 0xffc80024
-#define RHRAR 0xffc80028
-#define RWKAR 0xffc8002c
-#define RDAYAR 0xffc80030
-#define RMONAR 0xffc80034
-#define RCR1 0xffc80038
-#define RCR2 0xffc8003c
-
-#define RTC_BIT_INVERTED 0x40 /* bug on SH7750, SH7750S */
-
-#endif /* __ASM_CPU_SH4_RTC_H */
-
diff --git a/include/asm-sh/ec3104/keyboard.h b/include/asm-sh/ec3104/keyboard.h
index 0dee7b05b49d..c1253a683197 100644
--- a/include/asm-sh/ec3104/keyboard.h
+++ b/include/asm-sh/ec3104/keyboard.h
@@ -6,8 +6,6 @@ extern char ec3104_kbd_unexpected_up(unsigned char);
extern void ec3104_kbd_leds(unsigned char);
extern void ec3104_kbd_init_hw(void);
-#define SYSRQ_KEY 0x54
-
#define kbd_sysrq_xlate ec3104_kbd_sysrq_xlate
#define kbd_setkeycode ec3104_kbd_setkeycode
#define kbd_getkeycode ec3104_kbd_getkeycode
diff --git a/include/asm-sh/elf.h b/include/asm-sh/elf.h
index 3a07ab40ac4d..fc050fd7645e 100644
--- a/include/asm-sh/elf.h
+++ b/include/asm-sh/elf.h
@@ -1,7 +1,6 @@
#ifndef __ASM_SH_ELF_H
#define __ASM_SH_ELF_H
-#include <asm/processor.h>
#include <asm/auxvec.h>
#include <asm/ptrace.h>
#include <asm/user.h>
diff --git a/include/asm-sh/hs7751rvoip/io.h b/include/asm-sh/hs7751rvoip/io.h
deleted file mode 100644
index 513c8514001b..000000000000
--- a/include/asm-sh/hs7751rvoip/io.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * include/asm-sh/hs7751rvoip/hs7751rvoip.h
- *
- * Modified version of io_se.h for the hs7751rvoip-specific functions.
- *
- * May be copied or modified under the terms of the GNU General Public
- * License. See linux/COPYING for more information.
- *
- * IO functions for an Renesas Technology sales HS7751RVOIP
- */
-
-#ifndef _ASM_SH_IO_HS7751RVOIP_H
-#define _ASM_SH_IO_HS7751RVOIP_H
-
-#include <asm/io_generic.h>
-
-extern unsigned char hs7751rvoip_inb(unsigned long port);
-extern unsigned short hs7751rvoip_inw(unsigned long port);
-extern unsigned int hs7751rvoip_inl(unsigned long port);
-
-extern void hs7751rvoip_outb(unsigned char value, unsigned long port);
-extern void hs7751rvoip_outw(unsigned short value, unsigned long port);
-extern void hs7751rvoip_outl(unsigned int value, unsigned long port);
-
-extern unsigned char hs7751rvoip_inb_p(unsigned long port);
-extern void hs7751rvoip_outb_p(unsigned char value, unsigned long port);
-
-extern void hs7751rvoip_insb(unsigned long port, void *addr, unsigned long count);
-extern void hs7751rvoip_insw(unsigned long port, void *addr, unsigned long count);
-extern void hs7751rvoip_insl(unsigned long port, void *addr, unsigned long count);
-extern void hs7751rvoip_outsb(unsigned long port, const void *addr, unsigned long count);
-extern void hs7751rvoip_outsw(unsigned long port, const void *addr, unsigned long count);
-extern void hs7751rvoip_outsl(unsigned long port, const void *addr, unsigned long count);
-
-extern void *hs7751rvoip_ioremap(unsigned long offset, unsigned long size);
-
-extern unsigned long hs7751rvoip_isa_port2addr(unsigned long offset);
-
-#endif /* _ASM_SH_IO_HS7751RVOIP_H */
diff --git a/include/asm-sh/mpc1211/keyboard.h b/include/asm-sh/mpc1211/keyboard.h
index 71ef4cf4242d..9020feee7b4c 100644
--- a/include/asm-sh/mpc1211/keyboard.h
+++ b/include/asm-sh/mpc1211/keyboard.h
@@ -24,7 +24,6 @@ extern void pckbd_leds(unsigned char leds);
extern void pckbd_init_hw(void);
extern int pckbd_pm_resume(struct pm_dev *, pm_request_t, void *);
extern pm_callback pm_kbd_request_override;
-extern unsigned char pckbd_sysrq_xlate[128];
#define kbd_setkeycode pckbd_setkeycode
#define kbd_getkeycode pckbd_getkeycode
@@ -32,9 +31,6 @@ extern unsigned char pckbd_sysrq_xlate[128];
#define kbd_unexpected_up pckbd_unexpected_up
#define kbd_leds pckbd_leds
#define kbd_init_hw pckbd_init_hw
-#define kbd_sysrq_xlate pckbd_sysrq_xlate
-
-#define SYSRQ_KEY 0x54
/* resource allocation */
#define kbd_request_region()
diff --git a/include/asm-sh/rts7751r2d/io.h b/include/asm-sh/rts7751r2d/io.h
deleted file mode 100644
index 241094020567..000000000000
--- a/include/asm-sh/rts7751r2d/io.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * include/asm-sh/io_rts7751r2d.h
- *
- * Modified version of io_se.h for the rts7751r2d-specific functions.
- *
- * May be copied or modified under the terms of the GNU General Public
- * License. See linux/COPYING for more information.
- *
- * IO functions for an Renesas Technology sales RTS7751R2D
- */
-
-#ifndef _ASM_SH_IO_RTS7751R2D_H
-#define _ASM_SH_IO_RTS7751R2D_H
-
-extern unsigned char rts7751r2d_inb(unsigned long port);
-extern unsigned short rts7751r2d_inw(unsigned long port);
-extern unsigned int rts7751r2d_inl(unsigned long port);
-
-extern void rts7751r2d_outb(unsigned char value, unsigned long port);
-extern void rts7751r2d_outw(unsigned short value, unsigned long port);
-extern void rts7751r2d_outl(unsigned int value, unsigned long port);
-
-extern unsigned char rts7751r2d_inb_p(unsigned long port);
-extern void rts7751r2d_outb_p(unsigned char value, unsigned long port);
-
-extern void rts7751r2d_insb(unsigned long port, void *addr, unsigned long count);
-extern void rts7751r2d_insw(unsigned long port, void *addr, unsigned long count);
-extern void rts7751r2d_insl(unsigned long port, void *addr, unsigned long count);
-extern void rts7751r2d_outsb(unsigned long port, const void *addr, unsigned long count);
-extern void rts7751r2d_outsw(unsigned long port, const void *addr, unsigned long count);
-extern void rts7751r2d_outsl(unsigned long port, const void *addr, unsigned long count);
-
-extern void *rts7751r2d_ioremap(unsigned long offset, unsigned long size);
-
-extern unsigned long rts7751r2d_isa_port2addr(unsigned long offset);
-
-#endif /* _ASM_SH_IO_RTS7751R2D_H */
diff --git a/include/asm-sh/rts7751r2d/rts7751r2d.h b/include/asm-sh/rts7751r2d/rts7751r2d.h
index b112ae221fd1..796b8fcb81a8 100644
--- a/include/asm-sh/rts7751r2d/rts7751r2d.h
+++ b/include/asm-sh/rts7751r2d/rts7751r2d.h
@@ -68,4 +68,7 @@
#define IRQ_PCISLOT2 10 /* PCI Slot #2 IRQ */
#define IRQ_EXTENTION 11 /* EXTn IRQ */
+#define __IO_PREFIX rts7751r2d
+#include <asm/io_generic.h>
+
#endif /* __ASM_SH_RENESAS_RTS7751R2D */
diff --git a/include/asm-sh/sfp-machine.h b/include/asm-sh/sfp-machine.h
index 8a6399a8cfe0..d3c548443f2a 100644
--- a/include/asm-sh/sfp-machine.h
+++ b/include/asm-sh/sfp-machine.h
@@ -25,8 +25,6 @@
#ifndef _SFP_MACHINE_H
#define _SFP_MACHINE_H
-#include <linux/config.h>
-
#define _FP_W_TYPE_SIZE 32
#define _FP_W_TYPE unsigned long
#define _FP_WS_TYPE signed long
diff --git a/include/asm-sh/spinlock.h b/include/asm-sh/spinlock.h
index 846322d4c35d..2586eef07d57 100644
--- a/include/asm-sh/spinlock.h
+++ b/include/asm-sh/spinlock.h
@@ -88,7 +88,14 @@ static inline void __raw_write_unlock(raw_rwlock_t *rw)
__raw_spin_unlock(&rw->lock);
}
-#define __raw_read_trylock(lock) generic__raw_read_trylock(lock)
+static inline int __raw_read_trylock(raw_rwlock_t *lock)
+{
+ atomic_t *count = (atomic_t*)lock;
+ if (atomic_dec_return(count) >= 0)
+ return 1;
+ atomic_inc(count);
+ return 0;
+}
static inline int __raw_write_trylock(raw_rwlock_t *rw)
{
@@ -100,4 +107,8 @@ static inline int __raw_write_trylock(raw_rwlock_t *rw)
return 0;
}
+#define _raw_spin_relax(lock) cpu_relax()
+#define _raw_read_relax(lock) cpu_relax()
+#define _raw_write_relax(lock) cpu_relax()
+
#endif /* __ASM_SH_SPINLOCK_H */
diff --git a/include/asm-sh/string.h b/include/asm-sh/string.h
index 3e0cff04caec..95bc7db006b0 100644
--- a/include/asm-sh/string.h
+++ b/include/asm-sh/string.h
@@ -1,13 +1,15 @@
#ifndef __ASM_SH_STRING_H
#define __ASM_SH_STRING_H
+#ifdef __KERNEL__
+
/*
* Copyright (C) 1999 Niibe Yutaka
* But consider these trivial functions to be public domain.
*/
#define __HAVE_ARCH_STRCPY
-static __inline__ char *strcpy(char *__dest, const char *__src)
+static inline char *strcpy(char *__dest, const char *__src)
{
register char *__xdest = __dest;
unsigned long __dummy;
@@ -26,7 +28,7 @@ static __inline__ char *strcpy(char *__dest, const char *__src)
}
#define __HAVE_ARCH_STRNCPY
-static __inline__ char *strncpy(char *__dest, const char *__src, size_t __n)
+static inline char *strncpy(char *__dest, const char *__src, size_t __n)
{
register char *__xdest = __dest;
unsigned long __dummy;
@@ -52,7 +54,7 @@ static __inline__ char *strncpy(char *__dest, const char *__src, size_t __n)
}
#define __HAVE_ARCH_STRCMP
-static __inline__ int strcmp(const char *__cs, const char *__ct)
+static inline int strcmp(const char *__cs, const char *__ct)
{
register int __res;
unsigned long __dummy;
@@ -78,7 +80,7 @@ static __inline__ int strcmp(const char *__cs, const char *__ct)
}
#define __HAVE_ARCH_STRNCMP
-static __inline__ int strncmp(const char *__cs, const char *__ct, size_t __n)
+static inline int strncmp(const char *__cs, const char *__ct, size_t __n)
{
register int __res;
unsigned long __dummy;
@@ -124,4 +126,9 @@ extern void *memchr(const void *__s, int __c, size_t __n);
#define __HAVE_ARCH_STRLEN
extern size_t strlen(const char *);
+/* arch/sh/lib/strcasecmp.c */
+extern int strcasecmp(const char *, const char *);
+
+#endif /* __KERNEL__ */
+
#endif /* __ASM_SH_STRING_H */
diff --git a/include/asm-sh/unistd.h b/include/asm-sh/unistd.h
index 5d5e9f94def5..f1a0cbc966be 100644
--- a/include/asm-sh/unistd.h
+++ b/include/asm-sh/unistd.h
@@ -472,76 +472,6 @@ __syscall_return(type,__sc0); \
#define __ARCH_WANT_SYS_RT_SIGACTION
#define __ARCH_WANT_SYS_RT_SIGSUSPEND
-#ifdef __KERNEL_SYSCALLS__
-
-#include <linux/compiler.h>
-#include <linux/types.h>
-#include <linux/linkage.h>
-#include <asm/ptrace.h>
-
-/*
- * we need this inline - forking from kernel space will result
- * in NO COPY ON WRITE (!!!), until an execve is executed. This
- * is no problem, but for the stack. This is handled by not letting
- * main() use the stack at all after fork(). Thus, no function
- * calls - which means inline code for fork too, as otherwise we
- * would use the stack upon exit from 'fork()'.
- *
- * Actually only pause and fork are needed inline, so that there
- * won't be any messing with the stack from main(), but we define
- * some others too.
- */
-#define __NR__exit __NR_exit
-static __inline__ _syscall0(int,pause)
-static __inline__ _syscall0(int,sync)
-static __inline__ _syscall0(pid_t,setsid)
-static __inline__ _syscall3(int,write,int,fd,const char *,buf,off_t,count)
-static __inline__ _syscall3(int,read,int,fd,char *,buf,off_t,count)
-static __inline__ _syscall3(off_t,lseek,int,fd,off_t,offset,int,count)
-static __inline__ _syscall1(int,dup,int,fd)
-static __inline__ _syscall3(int,execve,const char *,file,char **,argv,char **,envp)
-static __inline__ _syscall3(int,open,const char *,file,int,flag,int,mode)
-static __inline__ _syscall1(int,close,int,fd)
-static __inline__ _syscall3(pid_t,waitpid,pid_t,pid,int *,wait_stat,int,options)
-static __inline__ _syscall1(int,delete_module,const char *,name)
-
-static __inline__ pid_t wait(int * wait_stat)
-{
- return waitpid(-1,wait_stat,0);
-}
-
-asmlinkage long sys_mmap2(
- unsigned long addr, unsigned long len,
- unsigned long prot, unsigned long flags,
- unsigned long fd, unsigned long pgoff);
-asmlinkage int sys_execve(char *ufilename, char **uargv,
- char **uenvp, unsigned long r7,
- struct pt_regs regs);
-asmlinkage int sys_clone(unsigned long clone_flags, unsigned long newsp,
- unsigned long parent_tidptr,
- unsigned long child_tidptr,
- struct pt_regs regs);
-asmlinkage int sys_fork(unsigned long r4, unsigned long r5,
- unsigned long r6, unsigned long r7,
- struct pt_regs regs);
-asmlinkage int sys_vfork(unsigned long r4, unsigned long r5,
- unsigned long r6, unsigned long r7,
- struct pt_regs regs);
-asmlinkage int sys_pipe(unsigned long r4, unsigned long r5,
- unsigned long r6, unsigned long r7,
- struct pt_regs regs);
-asmlinkage ssize_t sys_pread_wrapper(unsigned int fd, char *buf,
- size_t count, long dummy, loff_t pos);
-asmlinkage ssize_t sys_pwrite_wrapper(unsigned int fd, const char *buf,
- size_t count, long dummy, loff_t pos);
-struct sigaction;
-asmlinkage long sys_rt_sigaction(int sig,
- const struct sigaction __user *act,
- struct sigaction __user *oact,
- size_t sigsetsize);
-
-#endif /* __KERNEL_SYSCALLS__ */
-
/*
* "Conditional" syscalls
*
diff --git a/include/asm-sh64/keyboard.h b/include/asm-sh64/keyboard.h
index 1fab96d792bf..0b01c3beb2f8 100644
--- a/include/asm-sh64/keyboard.h
+++ b/include/asm-sh64/keyboard.h
@@ -30,7 +30,6 @@ extern int pckbd_translate(unsigned char scancode, unsigned char *keycode,
extern char pckbd_unexpected_up(unsigned char keycode);
extern void pckbd_leds(unsigned char leds);
extern void pckbd_init_hw(void);
-extern unsigned char pckbd_sysrq_xlate[128];
#define kbd_setkeycode pckbd_setkeycode
#define kbd_getkeycode pckbd_getkeycode
@@ -38,9 +37,6 @@ extern unsigned char pckbd_sysrq_xlate[128];
#define kbd_unexpected_up pckbd_unexpected_up
#define kbd_leds pckbd_leds
#define kbd_init_hw pckbd_init_hw
-#define kbd_sysrq_xlate pckbd_sysrq_xlate
-
-#define SYSRQ_KEY 0x54
/* resource allocation */
#define kbd_request_region()
diff --git a/include/asm-sh64/timex.h b/include/asm-sh64/timex.h
index af0b79269661..163e2b62fe27 100644
--- a/include/asm-sh64/timex.h
+++ b/include/asm-sh64/timex.h
@@ -17,9 +17,6 @@
#define CLOCK_TICK_RATE 1193180 /* Underlying HZ */
#define CLOCK_TICK_FACTOR 20 /* Factor of both 1000000 and CLOCK_TICK_RATE */
-#define FINETUNE ((((((long)LATCH * HZ - CLOCK_TICK_RATE) << SHIFT_HZ) * \
- (1000000/CLOCK_TICK_FACTOR) / (CLOCK_TICK_RATE/CLOCK_TICK_FACTOR)) \
- << (SHIFT_SCALE-SHIFT_HZ)) / HZ)
typedef unsigned long cycles_t;
diff --git a/include/asm-sh64/unistd.h b/include/asm-sh64/unistd.h
index c113566bef33..ee7828b27ad1 100644
--- a/include/asm-sh64/unistd.h
+++ b/include/asm-sh64/unistd.h
@@ -513,47 +513,6 @@ __syscall_return(type,__sc0); \
#define __ARCH_WANT_SYS_SIGPROCMASK
#define __ARCH_WANT_SYS_RT_SIGACTION
-#ifdef __KERNEL_SYSCALLS__
-
-/* Copy from sh */
-#include <linux/compiler.h>
-#include <linux/types.h>
-#include <asm/ptrace.h>
-
-/*
- * we need this inline - forking from kernel space will result
- * in NO COPY ON WRITE (!!!), until an execve is executed. This
- * is no problem, but for the stack. This is handled by not letting
- * main() use the stack at all after fork(). Thus, no function
- * calls - which means inline code for fork too, as otherwise we
- * would use the stack upon exit from 'fork()'.
- *
- * Actually only pause and fork are needed inline, so that there
- * won't be any messing with the stack from main(), but we define
- * some others too.
- */
-#define __NR__exit __NR_exit
-static inline _syscall0(int,pause)
-static inline _syscall1(int,setup,int,magic)
-static inline _syscall0(int,sync)
-static inline _syscall0(pid_t,setsid)
-static inline _syscall3(int,write,int,fd,const char *,buf,off_t,count)
-static inline _syscall3(int,read,int,fd,char *,buf,off_t,count)
-static inline _syscall3(off_t,lseek,int,fd,off_t,offset,int,count)
-static inline _syscall1(int,dup,int,fd)
-static inline _syscall3(int,execve,const char *,file,char **,argv,char **,envp)
-static inline _syscall3(int,open,const char *,file,int,flag,int,mode)
-static inline _syscall1(int,close,int,fd)
-static inline _syscall1(int,_exit,int,exitcode)
-static inline _syscall3(pid_t,waitpid,pid_t,pid,int *,wait_stat,int,options)
-static inline _syscall1(int,delete_module,const char *,name)
-
-static inline pid_t wait(int * wait_stat)
-{
- return waitpid(-1,wait_stat,0);
-}
-#endif /* __KERNEL_SYSCALLS__ */
-
/*
* "Conditional" syscalls
*
diff --git a/include/asm-sparc/spinlock.h b/include/asm-sparc/spinlock.h
index 1c75474ba1df..557d08959d2f 100644
--- a/include/asm-sparc/spinlock.h
+++ b/include/asm-sparc/spinlock.h
@@ -154,6 +154,10 @@ static inline int __raw_write_trylock(raw_rwlock_t *rw)
#define __raw_spin_lock_flags(lock, flags) __raw_spin_lock(lock)
#define __raw_read_trylock(lock) generic__raw_read_trylock(lock)
+#define _raw_spin_relax(lock) cpu_relax()
+#define _raw_read_relax(lock) cpu_relax()
+#define _raw_write_relax(lock) cpu_relax()
+
#define __raw_read_can_lock(rw) (!((rw)->lock & 0xff))
#define __raw_write_can_lock(rw) (!(rw)->lock)
diff --git a/include/asm-sparc/unistd.h b/include/asm-sparc/unistd.h
index 2553762465ca..c7a495afc82e 100644
--- a/include/asm-sparc/unistd.h
+++ b/include/asm-sparc/unistd.h
@@ -478,53 +478,6 @@ return -1; \
#define __ARCH_WANT_SYS_SIGPROCMASK
#define __ARCH_WANT_SYS_RT_SIGSUSPEND
-#ifdef __KERNEL_SYSCALLS__
-
-#include <linux/compiler.h>
-#include <linux/types.h>
-
-/*
- * we need this inline - forking from kernel space will result
- * in NO COPY ON WRITE (!!!), until an execve is executed. This
- * is no problem, but for the stack. This is handled by not letting
- * main() use the stack at all after fork(). Thus, no function
- * calls - which means inline code for fork too, as otherwise we
- * would use the stack upon exit from 'fork()'.
- *
- * Actually only pause and fork are needed inline, so that there
- * won't be any messing with the stack from main(), but we define
- * some others too.
- */
-#define __NR__exit __NR_exit
-static __inline__ _syscall0(pid_t,setsid)
-static __inline__ _syscall3(int,write,int,fd,__const__ char *,buf,off_t,count)
-static __inline__ _syscall3(int,read,int,fd,char *,buf,off_t,count)
-static __inline__ _syscall3(off_t,lseek,int,fd,off_t,offset,int,count)
-static __inline__ _syscall1(int,dup,int,fd)
-static __inline__ _syscall3(int,execve,__const__ char *,file,char **,argv,char **,envp)
-static __inline__ _syscall3(int,open,__const__ char *,file,int,flag,int,mode)
-static __inline__ _syscall1(int,close,int,fd)
-static __inline__ _syscall3(pid_t,waitpid,pid_t,pid,int *,wait_stat,int,options)
-
-#include <linux/linkage.h>
-
-asmlinkage unsigned long sys_mmap(
- unsigned long addr, unsigned long len,
- unsigned long prot, unsigned long flags,
- unsigned long fd, unsigned long off);
-asmlinkage unsigned long sys_mmap2(
- unsigned long addr, unsigned long len,
- unsigned long prot, unsigned long flags,
- unsigned long fd, unsigned long pgoff);
-struct sigaction;
-asmlinkage long sys_rt_sigaction(int sig,
- const struct sigaction __user *act,
- struct sigaction __user *oact,
- void __user *restorer,
- size_t sigsetsize);
-
-#endif /* __KERNEL_SYSCALLS__ */
-
/*
* "Conditional" syscalls
*
diff --git a/include/asm-sparc64/compat_signal.h b/include/asm-sparc64/compat_signal.h
new file mode 100644
index 000000000000..7aefa301321e
--- /dev/null
+++ b/include/asm-sparc64/compat_signal.h
@@ -0,0 +1,30 @@
+#ifndef _COMPAT_SIGNAL_H
+#define _COMPAT_SIGNAL_H
+
+#include <linux/config.h>
+#include <linux/compat.h>
+#include <asm/signal.h>
+
+#ifdef CONFIG_COMPAT
+struct __new_sigaction32 {
+ unsigned sa_handler;
+ unsigned int sa_flags;
+ unsigned sa_restorer; /* not used by Linux/SPARC yet */
+ compat_sigset_t sa_mask;
+};
+
+struct __old_sigaction32 {
+ unsigned sa_handler;
+ compat_old_sigset_t sa_mask;
+ unsigned int sa_flags;
+ unsigned sa_restorer; /* not used by Linux/SPARC yet */
+};
+
+typedef struct sigaltstack32 {
+ u32 ss_sp;
+ int ss_flags;
+ compat_size_t ss_size;
+} stack_t32;
+#endif
+
+#endif /* !(_COMPAT_SIGNAL_H) */
diff --git a/include/asm-sparc64/signal.h b/include/asm-sparc64/signal.h
index 9968871103bc..fa6f467389db 100644
--- a/include/asm-sparc64/signal.h
+++ b/include/asm-sparc64/signal.h
@@ -8,7 +8,6 @@
#ifndef __ASSEMBLY__
#include <linux/personality.h>
#include <linux/types.h>
-#include <linux/compat.h>
#endif
#endif
@@ -167,23 +166,6 @@ struct __new_sigaction {
__new_sigset_t sa_mask;
};
-#ifdef __KERNEL__
-
-#ifdef CONFIG_COMPAT
-struct __new_sigaction32 {
- unsigned sa_handler;
- unsigned int sa_flags;
- unsigned sa_restorer; /* not used by Linux/SPARC yet */
- compat_sigset_t sa_mask;
-};
-#endif
-
-struct k_sigaction {
- struct __new_sigaction sa;
- void __user *ka_restorer;
-};
-#endif
-
struct __old_sigaction {
__sighandler_t sa_handler;
__old_sigset_t sa_mask;
@@ -191,19 +173,6 @@ struct __old_sigaction {
void (*sa_restorer)(void); /* not used by Linux/SPARC yet */
};
-#ifdef __KERNEL__
-
-#ifdef CONFIG_COMPAT
-struct __old_sigaction32 {
- unsigned sa_handler;
- compat_old_sigset_t sa_mask;
- unsigned int sa_flags;
- unsigned sa_restorer; /* not used by Linux/SPARC yet */
-};
-#endif
-
-#endif
-
typedef struct sigaltstack {
void __user *ss_sp;
int ss_flags;
@@ -212,13 +181,10 @@ typedef struct sigaltstack {
#ifdef __KERNEL__
-#ifdef CONFIG_COMPAT
-typedef struct sigaltstack32 {
- u32 ss_sp;
- int ss_flags;
- compat_size_t ss_size;
-} stack_t32;
-#endif
+struct k_sigaction {
+ struct __new_sigaction sa;
+ void __user *ka_restorer;
+};
struct signal_deliver_cookie {
int restart_syscall;
diff --git a/include/asm-sparc64/spinlock.h b/include/asm-sparc64/spinlock.h
index bd5ffc76bc7e..0006fe9f8c7a 100644
--- a/include/asm-sparc64/spinlock.h
+++ b/include/asm-sparc64/spinlock.h
@@ -241,6 +241,10 @@ static int inline __write_trylock(raw_rwlock_t *lock)
#define __raw_read_can_lock(rw) (!((rw)->lock & 0x80000000UL))
#define __raw_write_can_lock(rw) (!(rw)->lock)
+#define _raw_spin_relax(lock) cpu_relax()
+#define _raw_read_relax(lock) cpu_relax()
+#define _raw_write_relax(lock) cpu_relax()
+
#endif /* !(__ASSEMBLY__) */
#endif /* !(__SPARC64_SPINLOCK_H) */
diff --git a/include/asm-sparc64/unistd.h b/include/asm-sparc64/unistd.h
index badc73fdcb97..124cf076717f 100644
--- a/include/asm-sparc64/unistd.h
+++ b/include/asm-sparc64/unistd.h
@@ -445,48 +445,6 @@ if (__res>=0) \
errno = -__res; \
return -1; \
}
-#ifdef __KERNEL_SYSCALLS__
-
-#include <linux/compiler.h>
-#include <linux/types.h>
-
-/*
- * we need this inline - forking from kernel space will result
- * in NO COPY ON WRITE (!!!), until an execve is executed. This
- * is no problem, but for the stack. This is handled by not letting
- * main() use the stack at all after fork(). Thus, no function
- * calls - which means inline code for fork too, as otherwise we
- * would use the stack upon exit from 'fork()'.
- *
- * Actually only pause and fork are needed inline, so that there
- * won't be any messing with the stack from main(), but we define
- * some others too.
- */
-#define __NR__exit __NR_exit
-static __inline__ _syscall0(pid_t,setsid)
-static __inline__ _syscall3(int,write,int,fd,__const__ char *,buf,off_t,count)
-static __inline__ _syscall3(int,read,int,fd,char *,buf,off_t,count)
-static __inline__ _syscall3(off_t,lseek,int,fd,off_t,offset,int,count)
-static __inline__ _syscall1(int,dup,int,fd)
-static __inline__ _syscall3(int,execve,__const__ char *,file,char **,argv,char **,envp)
-static __inline__ _syscall3(int,open,__const__ char *,file,int,flag,int,mode)
-static __inline__ _syscall1(int,close,int,fd)
-static __inline__ _syscall3(pid_t,waitpid,pid_t,pid,int *,wait_stat,int,options)
-
-#include <linux/linkage.h>
-
-asmlinkage unsigned long sys_mmap(
- unsigned long addr, unsigned long len,
- unsigned long prot, unsigned long flags,
- unsigned long fd, unsigned long off);
-struct sigaction;
-asmlinkage long sys_rt_sigaction(int sig,
- const struct sigaction __user *act,
- struct sigaction __user *oact,
- void __user *restorer,
- size_t sigsetsize);
-
-#endif /* __KERNEL_SYSCALLS__ */
/* sysconf options, for SunOS compatibility */
#define _SC_ARG_MAX 1
diff --git a/include/asm-um/pgtable.h b/include/asm-um/pgtable.h
index 4862daf8b906..188f72621776 100644
--- a/include/asm-um/pgtable.h
+++ b/include/asm-um/pgtable.h
@@ -274,12 +274,6 @@ static inline pte_t pte_mkread(pte_t pte)
return(pte_mknewprot(pte));
}
-static inline pte_t pte_mkexec(pte_t pte)
-{
- pte_set_bits(pte, _PAGE_USER);
- return(pte_mknewprot(pte));
-}
-
static inline pte_t pte_mkdirty(pte_t pte)
{
pte_set_bits(pte, _PAGE_DIRTY);
diff --git a/include/asm-um/unistd.h b/include/asm-um/unistd.h
index afccfcaa9ea9..732c83f04c3d 100644
--- a/include/asm-um/unistd.h
+++ b/include/asm-um/unistd.h
@@ -37,34 +37,6 @@ extern int um_execve(const char *file, char *const argv[], char *const env[]);
#define __ARCH_WANT_SYS_RT_SIGSUSPEND
#endif
-#ifdef __KERNEL_SYSCALLS__
-
-#include <linux/compiler.h>
-#include <linux/types.h>
-
-static inline int execve(const char *filename, char *const argv[],
- char *const envp[])
-{
- mm_segment_t fs;
- int ret;
-
- fs = get_fs();
- set_fs(KERNEL_DS);
- ret = um_execve(filename, argv, envp);
- set_fs(fs);
-
- if (ret >= 0)
- return ret;
-
- errno = -(long)ret;
- return -1;
-}
-
-int sys_execve(char *file, char **argv, char **env);
-
-#endif /* __KERNEL_SYSCALLS__ */
-
-#undef __KERNEL_SYSCALLS__
#include "asm/arch/unistd.h"
#endif /* _UM_UNISTD_H_*/
diff --git a/include/asm-v850/unistd.h b/include/asm-v850/unistd.h
index 552b7c873a57..737401e7d3ad 100644
--- a/include/asm-v850/unistd.h
+++ b/include/asm-v850/unistd.h
@@ -387,57 +387,6 @@ type name (atype a, btype b, ctype c, dtype d, etype e, ftype f) \
#define __ARCH_WANT_SYS_SIGPROCMASK
#define __ARCH_WANT_SYS_RT_SIGACTION
-#ifdef __KERNEL_SYSCALLS__
-
-#include <linux/compiler.h>
-#include <linux/types.h>
-
-/*
- * we need this inline - forking from kernel space will result
- * in NO COPY ON WRITE (!!!), until an execve is executed. This
- * is no problem, but for the stack. This is handled by not letting
- * main() use the stack at all after fork(). Thus, no function
- * calls - which means inline code for fork too, as otherwise we
- * would use the stack upon exit from 'fork()'.
- *
- * Actually only pause and fork are needed inline, so that there
- * won't be any messing with the stack from main(), but we define
- * some others too.
- */
-#define __NR__exit __NR_exit
-extern inline _syscall0(pid_t,setsid)
-extern inline _syscall3(int,write,int,fd,const char *,buf,off_t,count)
-extern inline _syscall3(int,read,int,fd,char *,buf,off_t,count)
-extern inline _syscall3(off_t,lseek,int,fd,off_t,offset,int,count)
-extern inline _syscall1(int,dup,int,fd)
-extern inline _syscall3(int,execve,const char *,file,char **,argv,char **,envp)
-extern inline _syscall3(int,open,const char *,file,int,flag,int,mode)
-extern inline _syscall1(int,close,int,fd)
-extern inline _syscall1(int,_exit,int,exitcode)
-extern inline _syscall3(pid_t,waitpid,pid_t,pid,int *,wait_stat,int,options)
-
-extern inline pid_t wait(int * wait_stat)
-{
- return waitpid (-1, wait_stat, 0);
-}
-
-unsigned long sys_mmap(unsigned long addr, size_t len,
- unsigned long prot, unsigned long flags,
- unsigned long fd, off_t offset);
-unsigned long sys_mmap2(unsigned long addr, size_t len,
- unsigned long prot, unsigned long flags,
- unsigned long fd, unsigned long pgoff);
-struct pt_regs;
-int sys_execve (char *name, char **argv, char **envp, struct pt_regs *regs);
-int sys_pipe (int *fildes);
-struct sigaction;
-asmlinkage long sys_rt_sigaction(int sig,
- const struct sigaction __user *act,
- struct sigaction __user *oact,
- size_t sigsetsize);
-
-#endif /* __KERNEL_SYSCALLS__ */
-
/*
* "Conditional" syscalls
*/
diff --git a/include/asm-x86_64/dma-mapping.h b/include/asm-x86_64/dma-mapping.h
index b6da83dcc7a6..10174b110a5c 100644
--- a/include/asm-x86_64/dma-mapping.h
+++ b/include/asm-x86_64/dma-mapping.h
@@ -55,13 +55,6 @@ extern dma_addr_t bad_dma_address;
extern struct dma_mapping_ops* dma_ops;
extern int iommu_merge;
-static inline int valid_dma_direction(int dma_direction)
-{
- return ((dma_direction == DMA_BIDIRECTIONAL) ||
- (dma_direction == DMA_TO_DEVICE) ||
- (dma_direction == DMA_FROM_DEVICE));
-}
-
static inline int dma_mapping_error(dma_addr_t dma_addr)
{
if (dma_ops->mapping_error)
diff --git a/include/asm-x86_64/nmi.h b/include/asm-x86_64/nmi.h
index cbf2669bca71..f367d4014b42 100644
--- a/include/asm-x86_64/nmi.h
+++ b/include/asm-x86_64/nmi.h
@@ -70,4 +70,11 @@ extern unsigned int nmi_watchdog;
#define NMI_LOCAL_APIC 2
#define NMI_INVALID 3
+struct ctl_table;
+struct file;
+extern int proc_nmi_enabled(struct ctl_table *, int , struct file *,
+ void __user *, size_t *, loff_t *);
+
+extern int unknown_nmi_panic;
+
#endif /* ASM_NMI_H */
diff --git a/include/asm-x86_64/ptrace.h b/include/asm-x86_64/ptrace.h
index ab827dc381d7..5ea84dbb1e9c 100644
--- a/include/asm-x86_64/ptrace.h
+++ b/include/asm-x86_64/ptrace.h
@@ -39,6 +39,8 @@ struct pt_regs {
#define user_mode(regs) (!!((regs)->cs & 3))
#define user_mode_vm(regs) user_mode(regs)
#define instruction_pointer(regs) ((regs)->rip)
+#define regs_return_value(regs) ((regs)->rax)
+
extern unsigned long profile_pc(struct pt_regs *regs);
void signal_fault(struct pt_regs *regs, void __user *frame, char *where);
diff --git a/include/asm-x86_64/semaphore.h b/include/asm-x86_64/semaphore.h
index 107bd90429e8..1194888536b9 100644
--- a/include/asm-x86_64/semaphore.h
+++ b/include/asm-x86_64/semaphore.h
@@ -132,7 +132,7 @@ static inline int down_interruptible(struct semaphore * sem)
"jns 2f\n\t"
"call __down_failed_interruptible\n"
"2:\n"
- :"=a" (result), "=m" (sem->count)
+ :"=&a" (result), "=m" (sem->count)
:"D" (sem)
:"memory");
return result;
@@ -153,7 +153,7 @@ static inline int down_trylock(struct semaphore * sem)
"jns 2f\n\t"
"call __down_failed_trylock\n\t"
"2:\n"
- :"=a" (result), "=m" (sem->count)
+ :"=&a" (result), "=m" (sem->count)
:"D" (sem)
:"memory","cc");
return result;
diff --git a/include/asm-x86_64/spinlock.h b/include/asm-x86_64/spinlock.h
index 3daf5b005905..05ef097ba55b 100644
--- a/include/asm-x86_64/spinlock.h
+++ b/include/asm-x86_64/spinlock.h
@@ -133,4 +133,8 @@ static inline void __raw_write_unlock(raw_rwlock_t *rw)
: "=m" (rw->lock) : : "memory");
}
+#define _raw_spin_relax(lock) cpu_relax()
+#define _raw_read_relax(lock) cpu_relax()
+#define _raw_write_relax(lock) cpu_relax()
+
#endif /* __ASM_SPINLOCK_H */
diff --git a/include/asm-x86_64/topology.h b/include/asm-x86_64/topology.h
index 6e7a2e976b04..5c8f49280dbc 100644
--- a/include/asm-x86_64/topology.h
+++ b/include/asm-x86_64/topology.h
@@ -31,6 +31,7 @@ extern int __node_distance(int, int);
#define SD_NODE_INIT (struct sched_domain) { \
.span = CPU_MASK_NONE, \
.parent = NULL, \
+ .child = NULL, \
.groups = NULL, \
.min_interval = 8, \
.max_interval = 32, \
diff --git a/include/asm-x86_64/uaccess.h b/include/asm-x86_64/uaccess.h
index e856570c0689..19f99178fe83 100644
--- a/include/asm-x86_64/uaccess.h
+++ b/include/asm-x86_64/uaccess.h
@@ -361,6 +361,11 @@ __must_check unsigned long clear_user(void __user *mem, unsigned long len);
__must_check unsigned long __clear_user(void __user *mem, unsigned long len);
__must_check long __copy_from_user_inatomic(void *dst, const void __user *src, unsigned size);
-#define __copy_to_user_inatomic copy_user_generic
+
+static __must_check __always_inline int
+__copy_to_user_inatomic(void __user *dst, const void *src, unsigned size)
+{
+ return copy_user_generic((__force void *)dst, src, size);
+}
#endif /* __X86_64_UACCESS_H */
diff --git a/include/asm-x86_64/unistd.h b/include/asm-x86_64/unistd.h
index 6137146516d3..777288eb7e75 100644
--- a/include/asm-x86_64/unistd.h
+++ b/include/asm-x86_64/unistd.h
@@ -620,10 +620,11 @@ __SYSCALL(__NR_vmsplice, sys_vmsplice)
#define __NR_move_pages 279
__SYSCALL(__NR_move_pages, sys_move_pages)
-#ifdef __KERNEL__
-
#define __NR_syscall_max __NR_move_pages
+
+#ifdef __KERNEL__
#include <linux/err.h>
+#endif
#ifndef __NO_STUBS
@@ -663,8 +664,6 @@ do { \
#define __ARCH_WANT_SYS_TIME
#define __ARCH_WANT_COMPAT_SYS_TIME
-#ifndef __KERNEL_SYSCALLS__
-
#define __syscall "syscall"
#define _syscall0(type,name) \
@@ -746,83 +745,7 @@ __asm__ volatile ("movq %5,%%r10 ; movq %6,%%r8 ; movq %7,%%r9 ; " __syscall \
__syscall_return(type,__res); \
}
-#else /* __KERNEL_SYSCALLS__ */
-
-#include <linux/syscalls.h>
-#include <asm/ptrace.h>
-
-/*
- * we need this inline - forking from kernel space will result
- * in NO COPY ON WRITE (!!!), until an execve is executed. This
- * is no problem, but for the stack. This is handled by not letting
- * main() use the stack at all after fork(). Thus, no function
- * calls - which means inline code for fork too, as otherwise we
- * would use the stack upon exit from 'fork()'.
- *
- * Actually only pause and fork are needed inline, so that there
- * won't be any messing with the stack from main(), but we define
- * some others too.
- */
-#define __NR__exit __NR_exit
-
-static inline pid_t setsid(void)
-{
- return sys_setsid();
-}
-
-static inline ssize_t write(unsigned int fd, char * buf, size_t count)
-{
- return sys_write(fd, buf, count);
-}
-
-static inline ssize_t read(unsigned int fd, char * buf, size_t count)
-{
- return sys_read(fd, buf, count);
-}
-
-static inline off_t lseek(unsigned int fd, off_t offset, unsigned int origin)
-{
- return sys_lseek(fd, offset, origin);
-}
-
-static inline long dup(unsigned int fd)
-{
- return sys_dup(fd);
-}
-
-/* implemented in asm in arch/x86_64/kernel/entry.S */
-extern int execve(const char *, char * const *, char * const *);
-
-static inline long open(const char * filename, int flags, int mode)
-{
- return sys_open(filename, flags, mode);
-}
-
-static inline long close(unsigned int fd)
-{
- return sys_close(fd);
-}
-
-static inline pid_t waitpid(int pid, int * wait_stat, int flags)
-{
- return sys_wait4(pid, wait_stat, flags, NULL);
-}
-
-extern long sys_mmap(unsigned long addr, unsigned long len,
- unsigned long prot, unsigned long flags,
- unsigned long fd, unsigned long off);
-
-extern int sys_modify_ldt(int func, void *ptr, unsigned long bytecount);
-
-asmlinkage long sys_execve(char *name, char **argv, char **envp,
- struct pt_regs regs);
-asmlinkage long sys_clone(unsigned long clone_flags, unsigned long newsp,
- void *parent_tid, void *child_tid,
- struct pt_regs regs);
-asmlinkage long sys_fork(struct pt_regs regs);
-asmlinkage long sys_vfork(struct pt_regs regs);
-asmlinkage long sys_pipe(int *fildes);
-
+#ifdef __KERNEL__
#ifndef __ASSEMBLY__
#include <linux/linkage.h>
@@ -839,8 +762,8 @@ asmlinkage long sys_rt_sigaction(int sig,
size_t sigsetsize);
#endif /* __ASSEMBLY__ */
-
-#endif /* __KERNEL_SYSCALLS__ */
+#endif /* __KERNEL__ */
+#endif /* __NO_STUBS */
/*
* "Conditional" syscalls
@@ -850,8 +773,4 @@ asmlinkage long sys_rt_sigaction(int sig,
*/
#define cond_syscall(x) asm(".weak\t" #x "\n\t.set\t" #x ",sys_ni_syscall")
-#endif /* __NO_STUBS */
-
-#endif /* __KERNEL__ */
-
#endif /* _ASM_X86_64_UNISTD_H_ */
diff --git a/include/asm-x86_64/vsyscall.h b/include/asm-x86_64/vsyscall.h
index 2281e9399b96..fd452fc2c037 100644
--- a/include/asm-x86_64/vsyscall.h
+++ b/include/asm-x86_64/vsyscall.h
@@ -17,7 +17,6 @@ enum vsyscall_num {
#define __section_vxtime __attribute__ ((unused, __section__ (".vxtime"), aligned(16)))
#define __section_vgetcpu_mode __attribute__ ((unused, __section__ (".vgetcpu_mode"), aligned(16)))
-#define __section_wall_jiffies __attribute__ ((unused, __section__ (".wall_jiffies"), aligned(16)))
#define __section_jiffies __attribute__ ((unused, __section__ (".jiffies"), aligned(16)))
#define __section_sys_tz __attribute__ ((unused, __section__ (".sys_tz"), aligned(16)))
#define __section_sysctl_vsyscall __attribute__ ((unused, __section__ (".sysctl_vsyscall"), aligned(16)))
@@ -48,14 +47,12 @@ extern struct vxtime_data __vxtime;
extern int __vgetcpu_mode;
extern struct timespec __xtime;
extern volatile unsigned long __jiffies;
-extern unsigned long __wall_jiffies;
extern struct timezone __sys_tz;
extern seqlock_t __xtime_lock;
/* kernel space (writeable) */
extern struct vxtime_data vxtime;
extern int vgetcpu_mode;
-extern unsigned long wall_jiffies;
extern struct timezone sys_tz;
extern int sysctl_vsyscall;
extern seqlock_t xtime_lock;
diff --git a/include/asm-xtensa/timex.h b/include/asm-xtensa/timex.h
index d14a3755a12b..c7b705e66655 100644
--- a/include/asm-xtensa/timex.h
+++ b/include/asm-xtensa/timex.h
@@ -31,9 +31,6 @@
#define CLOCK_TICK_RATE 1193180 /* (everyone is using this value) */
#define CLOCK_TICK_FACTOR 20 /* Factor of both 10^6 and CLOCK_TICK_RATE */
-#define FINETUNE ((((((long)LATCH * HZ - CLOCK_TICK_RATE) << SHIFT_HZ) * \
- (1000000/CLOCK_TICK_FACTOR) / (CLOCK_TICK_RATE/CLOCK_TICK_FACTOR)) \
- << (SHIFT_SCALE-SHIFT_HZ)) / HZ)
#ifdef CONFIG_XTENSA_CALIBRATE_CCOUNT
extern unsigned long ccount_per_jiffy;
diff --git a/include/asm-xtensa/unistd.h b/include/asm-xtensa/unistd.h
index 5e1b99dc4ab3..411f810a55c6 100644
--- a/include/asm-xtensa/unistd.h
+++ b/include/asm-xtensa/unistd.h
@@ -402,11 +402,6 @@ __asm__ __volatile__ ( \
__syscall_return(type,__res); \
}
-
-#ifdef __KERNEL_SYSCALLS__
-static __inline__ _syscall3(int,execve,const char*,file,char**,argv,char**,envp)
-#endif
-
/*
* "Conditional" syscalls
*
diff --git a/include/linux/Kbuild b/include/linux/Kbuild
index 1df2ac30a4d2..f7a52e19b4be 100644
--- a/include/linux/Kbuild
+++ b/include/linux/Kbuild
@@ -58,6 +58,7 @@ header-y += elf-em.h
header-y += fadvise.h
header-y += fd.h
header-y += fdreg.h
+header-y += fib_rules.h
header-y += ftape-header-segment.h
header-y += ftape-vendors.h
header-y += fuse.h
@@ -70,6 +71,7 @@ header-y += hysdn_if.h
header-y += i2c-dev.h
header-y += i8k.h
header-y += icmp.h
+header-y += if_addr.h
header-y += if_arcnet.h
header-y += if_arp.h
header-y += if_bonding.h
@@ -79,6 +81,7 @@ header-y += if_fddi.h
header-y += if.h
header-y += if_hippi.h
header-y += if_infiniband.h
+header-y += if_link.h
header-y += if_packet.h
header-y += if_plip.h
header-y += if_ppp.h
@@ -110,6 +113,7 @@ header-y += mmtimer.h
header-y += mqueue.h
header-y += mtio.h
header-y += ncp_no.h
+header-y += neighbour.h
header-y += netfilter_arp.h
header-y += netrom.h
header-y += nfs2.h
diff --git a/include/linux/acct.h b/include/linux/acct.h
index e86bae7324d2..0496d1f09952 100644
--- a/include/linux/acct.h
+++ b/include/linux/acct.h
@@ -124,16 +124,12 @@ extern void acct_auto_close(struct super_block *sb);
extern void acct_init_pacct(struct pacct_struct *pacct);
extern void acct_collect(long exitcode, int group_dead);
extern void acct_process(void);
-extern void acct_update_integrals(struct task_struct *tsk);
-extern void acct_clear_integrals(struct task_struct *tsk);
#else
#define acct_auto_close_mnt(x) do { } while (0)
#define acct_auto_close(x) do { } while (0)
#define acct_init_pacct(x) do { } while (0)
#define acct_collect(x,y) do { } while (0)
#define acct_process() do { } while (0)
-#define acct_update_integrals(x) do { } while (0)
-#define acct_clear_integrals(task) do { } while (0)
#endif
/*
diff --git a/include/linux/aio.h b/include/linux/aio.h
index 00c8efa95cc3..0d71c0041f13 100644
--- a/include/linux/aio.h
+++ b/include/linux/aio.h
@@ -4,8 +4,10 @@
#include <linux/list.h>
#include <linux/workqueue.h>
#include <linux/aio_abi.h>
+#include <linux/uio.h>
#include <asm/atomic.h>
+#include <linux/uio.h>
#define AIO_MAXSEGS 4
#define AIO_KIOGRP_NR_ATOMIC 8
@@ -110,8 +112,10 @@ struct kiocb {
char __user *ki_buf; /* remaining iocb->aio_buf */
size_t ki_left; /* remaining bytes */
long ki_retried; /* just for testing */
- long ki_kicked; /* just for testing */
- long ki_queued; /* just for testing */
+ struct iovec ki_inline_vec; /* inline vector */
+ struct iovec *ki_iovec;
+ unsigned long ki_nr_segs;
+ unsigned long ki_cur_seg;
struct list_head ki_list; /* the aio core uses this
* for cancellation */
@@ -213,11 +217,11 @@ int FASTCALL(io_submit_one(struct kioctx *ctx, struct iocb __user *user_iocb,
struct iocb *iocb));
#define get_ioctx(kioctx) do { \
- BUG_ON(unlikely(atomic_read(&(kioctx)->users) <= 0)); \
+ BUG_ON(atomic_read(&(kioctx)->users) <= 0); \
atomic_inc(&(kioctx)->users); \
} while (0)
#define put_ioctx(kioctx) do { \
- BUG_ON(unlikely(atomic_read(&(kioctx)->users) <= 0)); \
+ BUG_ON(atomic_read(&(kioctx)->users) <= 0); \
if (unlikely(atomic_dec_and_test(&(kioctx)->users))) \
__put_ioctx(kioctx); \
} while (0)
diff --git a/include/linux/aio_abi.h b/include/linux/aio_abi.h
index 30fdcc89d142..3466b1d0ffd2 100644
--- a/include/linux/aio_abi.h
+++ b/include/linux/aio_abi.h
@@ -41,6 +41,8 @@ enum {
* IOCB_CMD_POLL = 5,
*/
IOCB_CMD_NOOP = 6,
+ IOCB_CMD_PREADV = 7,
+ IOCB_CMD_PWRITEV = 8,
};
/* read() from /dev/aio returns these structures. */
diff --git a/include/linux/atalk.h b/include/linux/atalk.h
index 6ba3aa8a81f4..75b8baca08f3 100644
--- a/include/linux/atalk.h
+++ b/include/linux/atalk.h
@@ -88,15 +88,7 @@ static inline struct atalk_sock *at_sk(struct sock *sk)
#include <asm/byteorder.h>
struct ddpehdr {
-#ifdef __LITTLE_ENDIAN_BITFIELD
- __u16 deh_len:10,
- deh_hops:4,
- deh_pad:2;
-#else
- __u16 deh_pad:2,
- deh_hops:4,
- deh_len:10;
-#endif
+ __be16 deh_len_hops; /* lower 10 bits are length, next 4 - hops */
__be16 deh_sum;
__be16 deh_dnet;
__be16 deh_snet;
@@ -112,36 +104,6 @@ static __inline__ struct ddpehdr *ddp_hdr(struct sk_buff *skb)
return (struct ddpehdr *)skb->h.raw;
}
-/*
- * Don't drop the struct into the struct above. You'll get some
- * surprise padding.
- */
-struct ddpebits {
-#ifdef __LITTLE_ENDIAN_BITFIELD
- __u16 deh_len:10,
- deh_hops:4,
- deh_pad:2;
-#else
- __u16 deh_pad:2,
- deh_hops:4,
- deh_len:10;
-#endif
-};
-
-/* Short form header */
-struct ddpshdr {
-#ifdef __LITTLE_ENDIAN_BITFIELD
- __u16 dsh_len:10,
- dsh_pad:6;
-#else
- __u16 dsh_pad:6,
- dsh_len:10;
-#endif
- __u8 dsh_dport;
- __u8 dsh_sport;
- /* And netatalk apps expect to stick the type in themselves */
-};
-
/* AppleTalk AARP headers */
struct elapaarp {
__be16 hw_type;
diff --git a/include/linux/atmlec.h b/include/linux/atmlec.h
index f267f2442766..6f5a1bab8f50 100644
--- a/include/linux/atmlec.h
+++ b/include/linux/atmlec.h
@@ -1,9 +1,7 @@
/*
- *
- * ATM Lan Emulation Daemon vs. driver interface
- *
- * mkiiskila@yahoo.com
+ * ATM Lan Emulation Daemon driver interface
*
+ * Marko Kiiskila <mkiiskila@yahoo.com>
*/
#ifndef _ATMLEC_H_
@@ -13,76 +11,87 @@
#include <linux/atmioc.h>
#include <linux/atm.h>
#include <linux/if_ether.h>
+
/* ATM lec daemon control socket */
-#define ATMLEC_CTRL _IO('a',ATMIOC_LANE)
-#define ATMLEC_DATA _IO('a',ATMIOC_LANE+1)
-#define ATMLEC_MCAST _IO('a',ATMIOC_LANE+2)
+#define ATMLEC_CTRL _IO('a', ATMIOC_LANE)
+#define ATMLEC_DATA _IO('a', ATMIOC_LANE+1)
+#define ATMLEC_MCAST _IO('a', ATMIOC_LANE+2)
/* Maximum number of LEC interfaces (tweakable) */
#define MAX_LEC_ITF 48
-/* From the total of MAX_LEC_ITF, last NUM_TR_DEVS are reserved for Token Ring.
+/*
+ * From the total of MAX_LEC_ITF, last NUM_TR_DEVS are reserved for Token Ring.
* E.g. if MAX_LEC_ITF = 48 and NUM_TR_DEVS = 8, then lec0-lec39 are for
* Ethernet ELANs and lec40-lec47 are for Token Ring ELANS.
*/
#define NUM_TR_DEVS 8
-typedef enum {
- l_set_mac_addr, l_del_mac_addr,
- l_svc_setup,
- l_addr_delete, l_topology_change,
- l_flush_complete, l_arp_update,
- l_narp_req, /* LANE2 mandates the use of this */
- l_config, l_flush_tran_id,
- l_set_lecid, l_arp_xmt,
- l_rdesc_arp_xmt,
- l_associate_req,
- l_should_bridge /* should we bridge this MAC? */
+typedef enum {
+ l_set_mac_addr,
+ l_del_mac_addr,
+ l_svc_setup,
+ l_addr_delete,
+ l_topology_change,
+ l_flush_complete,
+ l_arp_update,
+ l_narp_req, /* LANE2 mandates the use of this */
+ l_config,
+ l_flush_tran_id,
+ l_set_lecid,
+ l_arp_xmt,
+ l_rdesc_arp_xmt,
+ l_associate_req,
+ l_should_bridge /* should we bridge this MAC? */
} atmlec_msg_type;
#define ATMLEC_MSG_TYPE_MAX l_should_bridge
struct atmlec_config_msg {
- unsigned int maximum_unknown_frame_count;
- unsigned int max_unknown_frame_time;
- unsigned short max_retry_count;
- unsigned int aging_time;
- unsigned int forward_delay_time;
- unsigned int arp_response_time;
- unsigned int flush_timeout;
- unsigned int path_switching_delay;
- unsigned int lane_version; /* LANE2: 1 for LANEv1, 2 for LANEv2 */
- int mtu;
- int is_proxy;
+ unsigned int maximum_unknown_frame_count;
+ unsigned int max_unknown_frame_time;
+ unsigned short max_retry_count;
+ unsigned int aging_time;
+ unsigned int forward_delay_time;
+ unsigned int arp_response_time;
+ unsigned int flush_timeout;
+ unsigned int path_switching_delay;
+ unsigned int lane_version; /* LANE2: 1 for LANEv1, 2 for LANEv2 */
+ int mtu;
+ int is_proxy;
};
-
+
struct atmlec_msg {
- atmlec_msg_type type;
- int sizeoftlvs; /* LANE2: if != 0, tlvs follow */
- union {
- struct {
- unsigned char mac_addr[ETH_ALEN];
- unsigned char atm_addr[ATM_ESA_LEN];
- unsigned int flag;/* Topology_change flag,
- remoteflag, permanent flag,
- lecid, transaction id */
- unsigned int targetless_le_arp; /* LANE2 */
- unsigned int no_source_le_narp; /* LANE2 */
- } normal;
- struct atmlec_config_msg config;
- struct {
- uint16_t lec_id; /* requestor lec_id */
- uint32_t tran_id; /* transaction id */
- unsigned char mac_addr[ETH_ALEN]; /* dst mac addr */
- unsigned char atm_addr[ATM_ESA_LEN]; /* reqestor ATM addr */
- } proxy;
- /* For mapping LE_ARP requests to responses. Filled by */
- } content; /* zeppelin, returned by kernel. Used only when proxying */
+ atmlec_msg_type type;
+ int sizeoftlvs; /* LANE2: if != 0, tlvs follow */
+ union {
+ struct {
+ unsigned char mac_addr[ETH_ALEN];
+ unsigned char atm_addr[ATM_ESA_LEN];
+ unsigned int flag; /*
+ * Topology_change flag,
+ * remoteflag, permanent flag,
+ * lecid, transaction id
+ */
+ unsigned int targetless_le_arp; /* LANE2 */
+ unsigned int no_source_le_narp; /* LANE2 */
+ } normal;
+ struct atmlec_config_msg config;
+ struct {
+ uint16_t lec_id; /* requestor lec_id */
+ uint32_t tran_id; /* transaction id */
+ unsigned char mac_addr[ETH_ALEN]; /* dst mac addr */
+ unsigned char atm_addr[ATM_ESA_LEN]; /* reqestor ATM addr */
+ } proxy; /*
+ * For mapping LE_ARP requests to responses. Filled by
+ * zeppelin, returned by kernel. Used only when proxying
+ */
+ } content;
} __ATM_API_ALIGN;
struct atmlec_ioc {
- int dev_num;
- unsigned char atm_addr[ATM_ESA_LEN];
- unsigned char receive; /* 1= receive vcc, 0 = send vcc */
+ int dev_num;
+ unsigned char atm_addr[ATM_ESA_LEN];
+ unsigned char receive; /* 1= receive vcc, 0 = send vcc */
};
#endif /* _ATMLEC_H_ */
diff --git a/include/linux/audit.h b/include/linux/audit.h
index 40a6c26294ae..c3aa09751814 100644
--- a/include/linux/audit.h
+++ b/include/linux/audit.h
@@ -95,6 +95,11 @@
#define AUDIT_MAC_POLICY_LOAD 1403 /* Policy file load */
#define AUDIT_MAC_STATUS 1404 /* Changed enforcing,permissive,off */
#define AUDIT_MAC_CONFIG_CHANGE 1405 /* Changes to booleans */
+#define AUDIT_MAC_UNLBL_ALLOW 1406 /* NetLabel: allow unlabeled traffic */
+#define AUDIT_MAC_CIPSOV4_ADD 1407 /* NetLabel: add CIPSOv4 DOI entry */
+#define AUDIT_MAC_CIPSOV4_DEL 1408 /* NetLabel: del CIPSOv4 DOI entry */
+#define AUDIT_MAC_MAP_ADD 1409 /* NetLabel: add LSM domain mapping */
+#define AUDIT_MAC_MAP_DEL 1410 /* NetLabel: del LSM domain mapping */
#define AUDIT_FIRST_KERN_ANOM_MSG 1700
#define AUDIT_LAST_KERN_ANOM_MSG 1799
diff --git a/include/linux/bio.h b/include/linux/bio.h
index 76bdaeab6f62..711c321a7011 100644
--- a/include/linux/bio.h
+++ b/include/linux/bio.h
@@ -148,6 +148,7 @@ struct bio {
#define BIO_RW_BARRIER 2
#define BIO_RW_FAILFAST 3
#define BIO_RW_SYNC 4
+#define BIO_RW_META 5
/*
* upper 16 bits of bi_rw define the io priority of this bio
@@ -178,6 +179,7 @@ struct bio {
#define bio_sync(bio) ((bio)->bi_rw & (1 << BIO_RW_SYNC))
#define bio_failfast(bio) ((bio)->bi_rw & (1 << BIO_RW_FAILFAST))
#define bio_rw_ahead(bio) ((bio)->bi_rw & (1 << BIO_RW_AHEAD))
+#define bio_rw_meta(bio) ((bio)->bi_rw & (1 << BIO_RW_META))
/*
* will die
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
index c773ee545ebd..1d79b8d4ca6d 100644
--- a/include/linux/blkdev.h
+++ b/include/linux/blkdev.h
@@ -1,6 +1,7 @@
#ifndef _LINUX_BLKDEV_H
#define _LINUX_BLKDEV_H
+#include <linux/sched.h>
#include <linux/major.h>
#include <linux/genhd.h>
#include <linux/list.h>
@@ -16,6 +17,22 @@
#include <asm/scatterlist.h>
+#ifdef CONFIG_LBD
+# include <asm/div64.h>
+# define sector_div(a, b) do_div(a, b)
+#else
+# define sector_div(n, b)( \
+{ \
+ int _res; \
+ _res = (n) % (b); \
+ (n) /= (b); \
+ _res; \
+} \
+)
+#endif
+
+#ifdef CONFIG_BLOCK
+
struct scsi_ioctl_command;
struct request_queue;
@@ -90,7 +107,7 @@ struct io_context {
atomic_t refcount;
struct task_struct *task;
- int (*set_ioprio)(struct io_context *, unsigned int);
+ unsigned int ioprio_changed;
/*
* For request batching
@@ -104,8 +121,7 @@ struct io_context {
void put_io_context(struct io_context *ioc);
void exit_io_context(void);
-struct io_context *current_io_context(gfp_t gfp_flags);
-struct io_context *get_io_context(gfp_t gfp_flags);
+struct io_context *get_io_context(gfp_t gfp_flags, int node);
void copy_io_context(struct io_context **pdst, struct io_context **psrc);
void swap_io_context(struct io_context **ioc1, struct io_context **ioc2);
@@ -120,6 +136,90 @@ struct request_list {
wait_queue_head_t wait[2];
};
+/*
+ * request command types
+ */
+enum rq_cmd_type_bits {
+ REQ_TYPE_FS = 1, /* fs request */
+ REQ_TYPE_BLOCK_PC, /* scsi command */
+ REQ_TYPE_SENSE, /* sense request */
+ REQ_TYPE_PM_SUSPEND, /* suspend request */
+ REQ_TYPE_PM_RESUME, /* resume request */
+ REQ_TYPE_PM_SHUTDOWN, /* shutdown request */
+ REQ_TYPE_FLUSH, /* flush request */
+ REQ_TYPE_SPECIAL, /* driver defined type */
+ REQ_TYPE_LINUX_BLOCK, /* generic block layer message */
+ /*
+ * for ATA/ATAPI devices. this really doesn't belong here, ide should
+ * use REQ_TYPE_SPECIAL and use rq->cmd[0] with the range of driver
+ * private REQ_LB opcodes to differentiate what type of request this is
+ */
+ REQ_TYPE_ATA_CMD,
+ REQ_TYPE_ATA_TASK,
+ REQ_TYPE_ATA_TASKFILE,
+};
+
+/*
+ * For request of type REQ_TYPE_LINUX_BLOCK, rq->cmd[0] is the opcode being
+ * sent down (similar to how REQ_TYPE_BLOCK_PC means that ->cmd[] holds a
+ * SCSI cdb.
+ *
+ * 0x00 -> 0x3f are driver private, to be used for whatever purpose they need,
+ * typically to differentiate REQ_TYPE_SPECIAL requests.
+ *
+ */
+enum {
+ /*
+ * just examples for now
+ */
+ REQ_LB_OP_EJECT = 0x40, /* eject request */
+ REQ_LB_OP_FLUSH = 0x41, /* flush device */
+};
+
+/*
+ * request type modified bits. first three bits match BIO_RW* bits, important
+ */
+enum rq_flag_bits {
+ __REQ_RW, /* not set, read. set, write */
+ __REQ_FAILFAST, /* no low level driver retries */
+ __REQ_SORTED, /* elevator knows about this request */
+ __REQ_SOFTBARRIER, /* may not be passed by ioscheduler */
+ __REQ_HARDBARRIER, /* may not be passed by drive either */
+ __REQ_FUA, /* forced unit access */
+ __REQ_NOMERGE, /* don't touch this for merging */
+ __REQ_STARTED, /* drive already may have started this one */
+ __REQ_DONTPREP, /* don't call prep for this one */
+ __REQ_QUEUED, /* uses queueing */
+ __REQ_ELVPRIV, /* elevator private data attached */
+ __REQ_FAILED, /* set if the request failed */
+ __REQ_QUIET, /* don't worry about errors */
+ __REQ_PREEMPT, /* set for "ide_preempt" requests */
+ __REQ_ORDERED_COLOR, /* is before or after barrier */
+ __REQ_RW_SYNC, /* request is sync (O_DIRECT) */
+ __REQ_ALLOCED, /* request came from our alloc pool */
+ __REQ_RW_META, /* metadata io request */
+ __REQ_NR_BITS, /* stops here */
+};
+
+#define REQ_RW (1 << __REQ_RW)
+#define REQ_FAILFAST (1 << __REQ_FAILFAST)
+#define REQ_SORTED (1 << __REQ_SORTED)
+#define REQ_SOFTBARRIER (1 << __REQ_SOFTBARRIER)
+#define REQ_HARDBARRIER (1 << __REQ_HARDBARRIER)
+#define REQ_FUA (1 << __REQ_FUA)
+#define REQ_NOMERGE (1 << __REQ_NOMERGE)
+#define REQ_STARTED (1 << __REQ_STARTED)
+#define REQ_DONTPREP (1 << __REQ_DONTPREP)
+#define REQ_QUEUED (1 << __REQ_QUEUED)
+#define REQ_ELVPRIV (1 << __REQ_ELVPRIV)
+#define REQ_FAILED (1 << __REQ_FAILED)
+#define REQ_QUIET (1 << __REQ_QUIET)
+#define REQ_PREEMPT (1 << __REQ_PREEMPT)
+#define REQ_ORDERED_COLOR (1 << __REQ_ORDERED_COLOR)
+#define REQ_RW_SYNC (1 << __REQ_RW_SYNC)
+#define REQ_ALLOCED (1 << __REQ_ALLOCED)
+#define REQ_RW_META (1 << __REQ_RW_META)
+
#define BLK_MAX_CDB 16
/*
@@ -129,30 +229,46 @@ struct request {
struct list_head queuelist;
struct list_head donelist;
- unsigned long flags; /* see REQ_ bits below */
+ request_queue_t *q;
+
+ unsigned int cmd_flags;
+ enum rq_cmd_type_bits cmd_type;
/* Maintain bio traversal state for part by part I/O submission.
* hard_* are block layer internals, no driver should touch them!
*/
sector_t sector; /* next sector to submit */
+ sector_t hard_sector; /* next sector to complete */
unsigned long nr_sectors; /* no. of sectors left to submit */
+ unsigned long hard_nr_sectors; /* no. of sectors left to complete */
/* no. of sectors left to submit in the current segment */
unsigned int current_nr_sectors;
- sector_t hard_sector; /* next sector to complete */
- unsigned long hard_nr_sectors; /* no. of sectors left to complete */
/* no. of sectors left to complete in the current segment */
unsigned int hard_cur_sectors;
struct bio *bio;
struct bio *biotail;
+ struct hlist_node hash; /* merge hash */
+ /*
+ * The rb_node is only used inside the io scheduler, requests
+ * are pruned when moved to the dispatch queue. So let the
+ * completion_data share space with the rb_node.
+ */
+ union {
+ struct rb_node rb_node; /* sort/lookup */
+ void *completion_data;
+ };
+
+ /*
+ * two pointers are available for the IO schedulers, if they need
+ * more they have to dynamically allocate it.
+ */
void *elevator_private;
- void *completion_data;
+ void *elevator_private2;
- int rq_status; /* should split this into a few status bits */
- int errors;
struct gendisk *rq_disk;
unsigned long start_time;
@@ -170,15 +286,13 @@ struct request {
unsigned short ioprio;
+ void *special;
+ char *buffer;
+
int tag;
+ int errors;
int ref_count;
- request_queue_t *q;
- struct request_list *rl;
-
- struct completion *waiting;
- void *special;
- char *buffer;
/*
* when request is used as a packet command carrier
@@ -195,80 +309,14 @@ struct request {
int retries;
/*
- * completion callback. end_io_data should be folded in with waiting
+ * completion callback.
*/
rq_end_io_fn *end_io;
void *end_io_data;
};
/*
- * first three bits match BIO_RW* bits, important
- */
-enum rq_flag_bits {
- __REQ_RW, /* not set, read. set, write */
- __REQ_FAILFAST, /* no low level driver retries */
- __REQ_SORTED, /* elevator knows about this request */
- __REQ_SOFTBARRIER, /* may not be passed by ioscheduler */
- __REQ_HARDBARRIER, /* may not be passed by drive either */
- __REQ_FUA, /* forced unit access */
- __REQ_CMD, /* is a regular fs rw request */
- __REQ_NOMERGE, /* don't touch this for merging */
- __REQ_STARTED, /* drive already may have started this one */
- __REQ_DONTPREP, /* don't call prep for this one */
- __REQ_QUEUED, /* uses queueing */
- __REQ_ELVPRIV, /* elevator private data attached */
- /*
- * for ATA/ATAPI devices
- */
- __REQ_PC, /* packet command (special) */
- __REQ_BLOCK_PC, /* queued down pc from block layer */
- __REQ_SENSE, /* sense retrival */
-
- __REQ_FAILED, /* set if the request failed */
- __REQ_QUIET, /* don't worry about errors */
- __REQ_SPECIAL, /* driver suplied command */
- __REQ_DRIVE_CMD,
- __REQ_DRIVE_TASK,
- __REQ_DRIVE_TASKFILE,
- __REQ_PREEMPT, /* set for "ide_preempt" requests */
- __REQ_PM_SUSPEND, /* suspend request */
- __REQ_PM_RESUME, /* resume request */
- __REQ_PM_SHUTDOWN, /* shutdown request */
- __REQ_ORDERED_COLOR, /* is before or after barrier */
- __REQ_RW_SYNC, /* request is sync (O_DIRECT) */
- __REQ_NR_BITS, /* stops here */
-};
-
-#define REQ_RW (1 << __REQ_RW)
-#define REQ_FAILFAST (1 << __REQ_FAILFAST)
-#define REQ_SORTED (1 << __REQ_SORTED)
-#define REQ_SOFTBARRIER (1 << __REQ_SOFTBARRIER)
-#define REQ_HARDBARRIER (1 << __REQ_HARDBARRIER)
-#define REQ_FUA (1 << __REQ_FUA)
-#define REQ_CMD (1 << __REQ_CMD)
-#define REQ_NOMERGE (1 << __REQ_NOMERGE)
-#define REQ_STARTED (1 << __REQ_STARTED)
-#define REQ_DONTPREP (1 << __REQ_DONTPREP)
-#define REQ_QUEUED (1 << __REQ_QUEUED)
-#define REQ_ELVPRIV (1 << __REQ_ELVPRIV)
-#define REQ_PC (1 << __REQ_PC)
-#define REQ_BLOCK_PC (1 << __REQ_BLOCK_PC)
-#define REQ_SENSE (1 << __REQ_SENSE)
-#define REQ_FAILED (1 << __REQ_FAILED)
-#define REQ_QUIET (1 << __REQ_QUIET)
-#define REQ_SPECIAL (1 << __REQ_SPECIAL)
-#define REQ_DRIVE_CMD (1 << __REQ_DRIVE_CMD)
-#define REQ_DRIVE_TASK (1 << __REQ_DRIVE_TASK)
-#define REQ_DRIVE_TASKFILE (1 << __REQ_DRIVE_TASKFILE)
-#define REQ_PREEMPT (1 << __REQ_PREEMPT)
-#define REQ_PM_SUSPEND (1 << __REQ_PM_SUSPEND)
-#define REQ_PM_RESUME (1 << __REQ_PM_RESUME)
-#define REQ_PM_SHUTDOWN (1 << __REQ_PM_SHUTDOWN)
-#define REQ_ORDERED_COLOR (1 << __REQ_ORDERED_COLOR)
-#define REQ_RW_SYNC (1 << __REQ_RW_SYNC)
-
-/*
- * State information carried for REQ_PM_SUSPEND and REQ_PM_RESUME
+ * State information carried for REQ_TYPE_PM_SUSPEND and REQ_TYPE_PM_RESUME
* requests. Some step values could eventually be made generic.
*/
struct request_pm_state
@@ -417,9 +465,9 @@ struct request_queue
unsigned int sg_timeout;
unsigned int sg_reserved_size;
int node;
-
+#ifdef CONFIG_BLK_DEV_IO_TRACE
struct blk_trace *blk_trace;
-
+#endif
/*
* reserved for flush operations
*/
@@ -432,9 +480,6 @@ struct request_queue
struct mutex sysfs_lock;
};
-#define RQ_INACTIVE (-1)
-#define RQ_ACTIVE 1
-
#define QUEUE_FLAG_CLUSTER 0 /* cluster several segments into 1 */
#define QUEUE_FLAG_QUEUED 1 /* uses generic tag queueing */
#define QUEUE_FLAG_STOPPED 2 /* queue is stopped */
@@ -490,25 +535,34 @@ enum {
#define blk_queue_stopped(q) test_bit(QUEUE_FLAG_STOPPED, &(q)->queue_flags)
#define blk_queue_flushing(q) ((q)->ordseq)
-#define blk_fs_request(rq) ((rq)->flags & REQ_CMD)
-#define blk_pc_request(rq) ((rq)->flags & REQ_BLOCK_PC)
-#define blk_noretry_request(rq) ((rq)->flags & REQ_FAILFAST)
-#define blk_rq_started(rq) ((rq)->flags & REQ_STARTED)
+#define blk_fs_request(rq) ((rq)->cmd_type == REQ_TYPE_FS)
+#define blk_pc_request(rq) ((rq)->cmd_type == REQ_TYPE_BLOCK_PC)
+#define blk_special_request(rq) ((rq)->cmd_type == REQ_TYPE_SPECIAL)
+#define blk_sense_request(rq) ((rq)->cmd_type == REQ_TYPE_SENSE)
+
+#define blk_noretry_request(rq) ((rq)->cmd_flags & REQ_FAILFAST)
+#define blk_rq_started(rq) ((rq)->cmd_flags & REQ_STARTED)
#define blk_account_rq(rq) (blk_rq_started(rq) && blk_fs_request(rq))
-#define blk_pm_suspend_request(rq) ((rq)->flags & REQ_PM_SUSPEND)
-#define blk_pm_resume_request(rq) ((rq)->flags & REQ_PM_RESUME)
+#define blk_pm_suspend_request(rq) ((rq)->cmd_type == REQ_TYPE_PM_SUSPEND)
+#define blk_pm_resume_request(rq) ((rq)->cmd_type == REQ_TYPE_PM_RESUME)
#define blk_pm_request(rq) \
- ((rq)->flags & (REQ_PM_SUSPEND | REQ_PM_RESUME))
+ (blk_pm_suspend_request(rq) || blk_pm_resume_request(rq))
-#define blk_sorted_rq(rq) ((rq)->flags & REQ_SORTED)
-#define blk_barrier_rq(rq) ((rq)->flags & REQ_HARDBARRIER)
-#define blk_fua_rq(rq) ((rq)->flags & REQ_FUA)
+#define blk_sorted_rq(rq) ((rq)->cmd_flags & REQ_SORTED)
+#define blk_barrier_rq(rq) ((rq)->cmd_flags & REQ_HARDBARRIER)
+#define blk_fua_rq(rq) ((rq)->cmd_flags & REQ_FUA)
#define list_entry_rq(ptr) list_entry((ptr), struct request, queuelist)
-#define rq_data_dir(rq) ((rq)->flags & 1)
+#define rq_data_dir(rq) ((rq)->cmd_flags & 1)
+
+/*
+ * We regard a request as sync, if it's a READ or a SYNC write.
+ */
+#define rq_is_sync(rq) (rq_data_dir((rq)) == READ || (rq)->cmd_flags & REQ_RW_SYNC)
+#define rq_is_meta(rq) ((rq)->cmd_flags & REQ_RW_META)
static inline int blk_queue_full(struct request_queue *q, int rw)
{
@@ -541,13 +595,7 @@ static inline void blk_clear_queue_full(struct request_queue *q, int rw)
#define RQ_NOMERGE_FLAGS \
(REQ_NOMERGE | REQ_STARTED | REQ_HARDBARRIER | REQ_SOFTBARRIER)
#define rq_mergeable(rq) \
- (!((rq)->flags & RQ_NOMERGE_FLAGS) && blk_fs_request((rq)))
-
-/*
- * noop, requests are automagically marked as active/inactive by I/O
- * scheduler -- see elv_next_request
- */
-#define blk_queue_headactive(q, head_active)
+ (!((rq)->cmd_flags & RQ_NOMERGE_FLAGS) && blk_fs_request((rq)))
/*
* q->prep_rq_fn return values
@@ -586,11 +634,6 @@ static inline void blk_queue_bounce(request_queue_t *q, struct bio **bio)
if ((rq->bio)) \
for (_bio = (rq)->bio; _bio; _bio = _bio->bi_next)
-struct sec_size {
- unsigned block_size;
- unsigned block_size_bits;
-};
-
extern int blk_register_queue(struct gendisk *disk);
extern void blk_unregister_queue(struct gendisk *disk);
extern void register_disk(struct gendisk *dev);
@@ -612,6 +655,7 @@ extern void blk_stop_queue(request_queue_t *q);
extern void blk_sync_queue(struct request_queue *q);
extern void __blk_stop_queue(request_queue_t *q);
extern void blk_run_queue(request_queue_t *);
+extern void blk_start_queueing(request_queue_t *);
extern void blk_queue_activity_fn(request_queue_t *, activity_fn *, void *);
extern int blk_rq_map_user(request_queue_t *, struct request *, void __user *, unsigned int);
extern int blk_rq_unmap_user(struct bio *, unsigned int);
@@ -655,16 +699,6 @@ extern void end_that_request_last(struct request *, int);
extern void end_request(struct request *req, int uptodate);
extern void blk_complete_request(struct request *);
-static inline int rq_all_done(struct request *rq, unsigned int nr_bytes)
-{
- if (blk_fs_request(rq))
- return (nr_bytes >= (rq->hard_nr_sectors << 9));
- else if (blk_pc_request(rq))
- return nr_bytes >= rq->data_len;
-
- return 0;
-}
-
/*
* end_that_request_first/chunk() takes an uptodate argument. we account
* any value <= as an io error. 0 means -EIO for compatability reasons,
@@ -679,21 +713,6 @@ static inline void blkdev_dequeue_request(struct request *req)
}
/*
- * This should be in elevator.h, but that requires pulling in rq and q
- */
-static inline void elv_dispatch_add_tail(struct request_queue *q,
- struct request *rq)
-{
- if (q->last_merge == rq)
- q->last_merge = NULL;
- q->nr_sorted--;
-
- q->end_sector = rq_end_sector(rq);
- q->boundary_rq = rq;
- list_add_tail(&rq->queuelist, &q->queue_head);
-}
-
-/*
* Access functions for manipulating queue properties
*/
extern request_queue_t *blk_init_queue_node(request_fn_proc *rfn,
@@ -737,7 +756,7 @@ extern void blk_put_queue(request_queue_t *);
*/
#define blk_queue_tag_depth(q) ((q)->queue_tags->busy)
#define blk_queue_tag_queue(q) ((q)->queue_tags->busy < (q)->queue_tags->max_depth)
-#define blk_rq_tagged(rq) ((rq)->flags & REQ_QUEUED)
+#define blk_rq_tagged(rq) ((rq)->cmd_flags & REQ_QUEUED)
extern int blk_queue_start_tag(request_queue_t *, struct request *);
extern struct request *blk_queue_find_tag(request_queue_t *, int);
extern void blk_queue_end_tag(request_queue_t *, struct request *);
@@ -787,14 +806,6 @@ static inline int queue_dma_alignment(request_queue_t *q)
return retval;
}
-static inline int bdev_dma_aligment(struct block_device *bdev)
-{
- return queue_dma_alignment(bdev_get_queue(bdev));
-}
-
-#define blk_finished_io(nsects) do { } while (0)
-#define blk_started_io(nsects) do { } while (0)
-
/* assumes size > 256 */
static inline unsigned int blksize_bits(unsigned int size)
{
@@ -824,24 +835,32 @@ struct work_struct;
int kblockd_schedule_work(struct work_struct *work);
void kblockd_flush(void);
-#ifdef CONFIG_LBD
-# include <asm/div64.h>
-# define sector_div(a, b) do_div(a, b)
-#else
-# define sector_div(n, b)( \
-{ \
- int _res; \
- _res = (n) % (b); \
- (n) /= (b); \
- _res; \
-} \
-)
-#endif
-
#define MODULE_ALIAS_BLOCKDEV(major,minor) \
MODULE_ALIAS("block-major-" __stringify(major) "-" __stringify(minor))
#define MODULE_ALIAS_BLOCKDEV_MAJOR(major) \
MODULE_ALIAS("block-major-" __stringify(major) "-*")
+#else /* CONFIG_BLOCK */
+/*
+ * stubs for when the block layer is configured out
+ */
+#define buffer_heads_over_limit 0
+
+static inline long blk_congestion_wait(int rw, long timeout)
+{
+ return io_schedule_timeout(timeout);
+}
+
+static inline long nr_blockdev_pages(void)
+{
+ return 0;
+}
+
+static inline void exit_io_context(void)
+{
+}
+
+#endif /* CONFIG_BLOCK */
+
#endif
diff --git a/include/linux/blktrace_api.h b/include/linux/blktrace_api.h
index 7520cc1ff9e2..b99a714fcac6 100644
--- a/include/linux/blktrace_api.h
+++ b/include/linux/blktrace_api.h
@@ -20,6 +20,7 @@ enum blktrace_cat {
BLK_TC_PC = 1 << 9, /* pc requests */
BLK_TC_NOTIFY = 1 << 10, /* special message */
BLK_TC_AHEAD = 1 << 11, /* readahead */
+ BLK_TC_META = 1 << 12, /* metadata */
BLK_TC_END = 1 << 15, /* only 16-bits, reminder */
};
@@ -148,7 +149,7 @@ static inline void blk_add_trace_rq(struct request_queue *q, struct request *rq,
u32 what)
{
struct blk_trace *bt = q->blk_trace;
- int rw = rq->flags & 0x03;
+ int rw = rq->cmd_flags & 0x03;
if (likely(!bt))
return;
diff --git a/include/linux/buffer_head.h b/include/linux/buffer_head.h
index 737e407d0cd1..131ffd37e716 100644
--- a/include/linux/buffer_head.h
+++ b/include/linux/buffer_head.h
@@ -14,6 +14,8 @@
#include <linux/wait.h>
#include <asm/atomic.h>
+#ifdef CONFIG_BLOCK
+
enum bh_state_bits {
BH_Uptodate, /* Contains valid data */
BH_Dirty, /* Is dirty */
@@ -190,9 +192,7 @@ extern int buffer_heads_over_limit;
* Generic address_space_operations implementations for buffer_head-backed
* address_spaces.
*/
-int try_to_release_page(struct page * page, gfp_t gfp_mask);
void block_invalidatepage(struct page *page, unsigned long offset);
-void do_invalidatepage(struct page *page, unsigned long offset);
int block_write_full_page(struct page *page, get_block_t *get_block,
struct writeback_control *wbc);
int block_read_full_page(struct page*, get_block_t*);
@@ -302,4 +302,19 @@ static inline void lock_buffer(struct buffer_head *bh)
__lock_buffer(bh);
}
+extern int __set_page_dirty_buffers(struct page *page);
+
+#else /* CONFIG_BLOCK */
+
+static inline void buffer_init(void) {}
+static inline int try_to_free_buffers(struct page *page) { return 1; }
+static inline int sync_blockdev(struct block_device *bdev) { return 0; }
+static inline int inode_has_buffers(struct inode *inode) { return 0; }
+static inline void invalidate_inode_buffers(struct inode *inode) {}
+static inline int remove_inode_buffers(struct inode *inode) { return 1; }
+static inline int sync_mapping_buffers(struct address_space *mapping) { return 0; }
+static inline void invalidate_bdev(struct block_device *bdev, int destroy_dirty_buffers) {}
+
+
+#endif /* CONFIG_BLOCK */
#endif /* _LINUX_BUFFER_HEAD_H */
diff --git a/include/linux/compat.h b/include/linux/compat.h
index 9760753e662b..ef5cd192784c 100644
--- a/include/linux/compat.h
+++ b/include/linux/compat.h
@@ -13,6 +13,7 @@
#include <asm/compat.h>
#include <asm/siginfo.h>
+#include <asm/signal.h>
#define compat_jiffies_to_clock_t(x) \
(((unsigned long)(x) * COMPAT_USER_HZ) / HZ)
@@ -227,6 +228,7 @@ static inline int compat_timespec_compare(struct compat_timespec *lhs,
asmlinkage long compat_sys_adjtimex(struct compat_timex __user *utp);
extern int compat_printk(const char *fmt, ...);
+extern void sigset_from_compat(sigset_t *set, compat_sigset_t *compat);
#endif /* CONFIG_COMPAT */
#endif /* _LINUX_COMPAT_H */
diff --git a/include/linux/compat_ioctl.h b/include/linux/compat_ioctl.h
index bea0255196c4..4e1663d7691e 100644
--- a/include/linux/compat_ioctl.h
+++ b/include/linux/compat_ioctl.h
@@ -90,6 +90,7 @@ COMPATIBLE_IOCTL(FDTWADDLE)
COMPATIBLE_IOCTL(FDFMTTRK)
COMPATIBLE_IOCTL(FDRAWCMD)
/* 0x12 */
+#ifdef CONFIG_BLOCK
COMPATIBLE_IOCTL(BLKRASET)
COMPATIBLE_IOCTL(BLKROSET)
COMPATIBLE_IOCTL(BLKROGET)
@@ -103,6 +104,7 @@ COMPATIBLE_IOCTL(BLKTRACESETUP)
COMPATIBLE_IOCTL(BLKTRACETEARDOWN)
ULONG_IOCTL(BLKRASET)
ULONG_IOCTL(BLKFRASET)
+#endif
/* RAID */
COMPATIBLE_IOCTL(RAID_VERSION)
COMPATIBLE_IOCTL(GET_ARRAY_INFO)
@@ -120,10 +122,10 @@ COMPATIBLE_IOCTL(PROTECT_ARRAY)
ULONG_IOCTL(HOT_ADD_DISK)
ULONG_IOCTL(SET_DISK_FAULTY)
COMPATIBLE_IOCTL(RUN_ARRAY)
-ULONG_IOCTL(START_ARRAY)
COMPATIBLE_IOCTL(STOP_ARRAY)
COMPATIBLE_IOCTL(STOP_ARRAY_RO)
COMPATIBLE_IOCTL(RESTART_ARRAY_RW)
+ULONG_IOCTL(SET_BITMAP_FILE)
/* DM */
COMPATIBLE_IOCTL(DM_VERSION_32)
COMPATIBLE_IOCTL(DM_REMOVE_ALL_32)
@@ -395,12 +397,6 @@ COMPATIBLE_IOCTL(DVD_WRITE_STRUCT)
COMPATIBLE_IOCTL(DVD_AUTH)
/* pktcdvd */
COMPATIBLE_IOCTL(PACKET_CTRL_CMD)
-/* Big L */
-ULONG_IOCTL(LOOP_SET_FD)
-ULONG_IOCTL(LOOP_CHANGE_FD)
-COMPATIBLE_IOCTL(LOOP_CLR_FD)
-COMPATIBLE_IOCTL(LOOP_GET_STATUS64)
-COMPATIBLE_IOCTL(LOOP_SET_STATUS64)
/* Big A */
/* sparc only */
/* Big Q for sound/OSS */
@@ -573,18 +569,6 @@ COMPATIBLE_IOCTL(RAW_SETBIND)
COMPATIBLE_IOCTL(RAW_GETBIND)
/* SMB ioctls which do not need any translations */
COMPATIBLE_IOCTL(SMB_IOC_NEWCONN)
-/* NCP ioctls which do not need any translations */
-COMPATIBLE_IOCTL(NCP_IOC_CONN_LOGGED_IN)
-COMPATIBLE_IOCTL(NCP_IOC_SIGN_INIT)
-COMPATIBLE_IOCTL(NCP_IOC_SIGN_WANTED)
-COMPATIBLE_IOCTL(NCP_IOC_SET_SIGN_WANTED)
-COMPATIBLE_IOCTL(NCP_IOC_LOCKUNLOCK)
-COMPATIBLE_IOCTL(NCP_IOC_GETROOT)
-COMPATIBLE_IOCTL(NCP_IOC_SETROOT)
-COMPATIBLE_IOCTL(NCP_IOC_GETCHARSETS)
-COMPATIBLE_IOCTL(NCP_IOC_SETCHARSETS)
-COMPATIBLE_IOCTL(NCP_IOC_GETDENTRYTTL)
-COMPATIBLE_IOCTL(NCP_IOC_SETDENTRYTTL)
/* Little a */
COMPATIBLE_IOCTL(ATMSIGD_CTRL)
COMPATIBLE_IOCTL(ATMARPD_CTRL)
diff --git a/include/linux/compiler.h b/include/linux/compiler.h
index 060b96112ec6..538423d4a865 100644
--- a/include/linux/compiler.h
+++ b/include/linux/compiler.h
@@ -10,11 +10,11 @@
# define __force __attribute__((force))
# define __nocast __attribute__((nocast))
# define __iomem __attribute__((noderef, address_space(2)))
-# define __acquires(x) __attribute__((context(0,1)))
-# define __releases(x) __attribute__((context(1,0)))
-# define __acquire(x) __context__(1)
-# define __release(x) __context__(-1)
-# define __cond_lock(x) ((x) ? ({ __context__(1); 1; }) : 0)
+# define __acquires(x) __attribute__((context(x,0,1)))
+# define __releases(x) __attribute__((context(x,1,0)))
+# define __acquire(x) __context__(x,1)
+# define __release(x) __context__(x,-1)
+# define __cond_lock(x,c) ((c) ? ({ __acquire(x); 1; }) : 0)
extern void __chk_user_ptr(void __user *);
extern void __chk_io_ptr(void __iomem *);
#else
@@ -31,7 +31,7 @@ extern void __chk_io_ptr(void __iomem *);
# define __releases(x)
# define __acquire(x) (void)0
# define __release(x) (void)0
-# define __cond_lock(x) (x)
+# define __cond_lock(x,c) (c)
#endif
#ifdef __KERNEL__
diff --git a/include/linux/console.h b/include/linux/console.h
index 76a1807726eb..7d0420274de0 100644
--- a/include/linux/console.h
+++ b/include/linux/console.h
@@ -129,6 +129,9 @@ static inline void suspend_console(void) {}
static inline void resume_console(void) {}
#endif /* CONFIG_DISABLE_CONSOLE_SUSPEND */
+int mda_console_init(void);
+void prom_con_init(void);
+
/* Some debug stub to catch some of the obvious races in the VT code */
#if 1
#define WARN_CONSOLE_UNLOCKED() WARN_ON(!is_console_locked() && !oops_in_progress)
diff --git a/include/linux/console_struct.h b/include/linux/console_struct.h
index 25423f79bf9f..ed6c0fee1ac7 100644
--- a/include/linux/console_struct.h
+++ b/include/linux/console_struct.h
@@ -54,7 +54,7 @@ struct vc_data {
struct tty_struct *vc_tty; /* TTY we are attached to */
/* data for manual vt switching */
struct vt_mode vt_mode;
- int vt_pid;
+ struct pid *vt_pid;
int vt_newvt;
wait_queue_head_t paste_wait;
/* mode flags */
diff --git a/include/linux/consolemap.h b/include/linux/consolemap.h
index 65842efc1b70..82c9a1f11020 100644
--- a/include/linux/consolemap.h
+++ b/include/linux/consolemap.h
@@ -13,3 +13,4 @@ struct vc_data;
extern unsigned char inverse_translate(struct vc_data *conp, int glyph);
extern unsigned short *set_translate(int m, struct vc_data *vc);
extern int conv_uni_to_pc(struct vc_data *conp, long ucs);
+void console_map_init(void);
diff --git a/include/linux/cpuset.h b/include/linux/cpuset.h
index 9354722a9217..4d8adf663681 100644
--- a/include/linux/cpuset.h
+++ b/include/linux/cpuset.h
@@ -63,6 +63,8 @@ static inline int cpuset_do_slab_mem_spread(void)
return current->flags & PF_SPREAD_SLAB;
}
+extern void cpuset_track_online_nodes(void);
+
#else /* !CONFIG_CPUSETS */
static inline int cpuset_init_early(void) { return 0; }
@@ -126,6 +128,8 @@ static inline int cpuset_do_slab_mem_spread(void)
return 0;
}
+static inline void cpuset_track_online_nodes(void) {}
+
#endif /* !CONFIG_CPUSETS */
#endif /* _LINUX_CPUSET_H */
diff --git a/include/linux/cramfs_fs.h b/include/linux/cramfs_fs.h
index a41f38428c37..1dba681e428d 100644
--- a/include/linux/cramfs_fs.h
+++ b/include/linux/cramfs_fs.h
@@ -87,6 +87,6 @@ struct cramfs_super {
/* Uncompression interfaces to the underlying zlib */
int cramfs_uncompress_block(void *dst, int dstlen, void *src, int srclen);
int cramfs_uncompress_init(void);
-int cramfs_uncompress_exit(void);
+void cramfs_uncompress_exit(void);
#endif
diff --git a/include/linux/device-mapper.h b/include/linux/device-mapper.h
index e3d1c33d1558..03ef41c1eaac 100644
--- a/include/linux/device-mapper.h
+++ b/include/linux/device-mapper.h
@@ -55,8 +55,10 @@ typedef int (*dm_endio_fn) (struct dm_target *ti,
struct bio *bio, int error,
union map_info *map_context);
+typedef void (*dm_flush_fn) (struct dm_target *ti);
typedef void (*dm_presuspend_fn) (struct dm_target *ti);
typedef void (*dm_postsuspend_fn) (struct dm_target *ti);
+typedef int (*dm_preresume_fn) (struct dm_target *ti);
typedef void (*dm_resume_fn) (struct dm_target *ti);
typedef int (*dm_status_fn) (struct dm_target *ti, status_type_t status_type,
@@ -64,9 +66,18 @@ typedef int (*dm_status_fn) (struct dm_target *ti, status_type_t status_type,
typedef int (*dm_message_fn) (struct dm_target *ti, unsigned argc, char **argv);
+typedef int (*dm_ioctl_fn) (struct dm_target *ti, struct inode *inode,
+ struct file *filp, unsigned int cmd,
+ unsigned long arg);
+
void dm_error(const char *message);
/*
+ * Combine device limits.
+ */
+void dm_set_device_limits(struct dm_target *ti, struct block_device *bdev);
+
+/*
* Constructors should call these functions to ensure destination devices
* are opened/closed correctly.
* FIXME: too many arguments.
@@ -86,11 +97,14 @@ struct target_type {
dm_dtr_fn dtr;
dm_map_fn map;
dm_endio_fn end_io;
+ dm_flush_fn flush;
dm_presuspend_fn presuspend;
dm_postsuspend_fn postsuspend;
+ dm_preresume_fn preresume;
dm_resume_fn resume;
dm_status_fn status;
dm_message_fn message;
+ dm_ioctl_fn ioctl;
};
struct io_restrictions {
diff --git a/include/linux/dm-ioctl.h b/include/linux/dm-ioctl.h
index 9623bb625090..8853fc4d1c5e 100644
--- a/include/linux/dm-ioctl.h
+++ b/include/linux/dm-ioctl.h
@@ -285,9 +285,9 @@ typedef char ioctl_struct[308];
#define DM_DEV_SET_GEOMETRY _IOWR(DM_IOCTL, DM_DEV_SET_GEOMETRY_CMD, struct dm_ioctl)
#define DM_VERSION_MAJOR 4
-#define DM_VERSION_MINOR 7
+#define DM_VERSION_MINOR 10
#define DM_VERSION_PATCHLEVEL 0
-#define DM_VERSION_EXTRA "-ioctl (2006-06-24)"
+#define DM_VERSION_EXTRA "-ioctl (2006-09-14)"
/* Status bits */
#define DM_READONLY_FLAG (1 << 0) /* In/Out */
diff --git a/include/linux/dma-mapping.h b/include/linux/dma-mapping.h
index 635690cf3e3d..ff203c465fed 100644
--- a/include/linux/dma-mapping.h
+++ b/include/linux/dma-mapping.h
@@ -24,6 +24,13 @@ enum dma_data_direction {
#define DMA_28BIT_MASK 0x000000000fffffffULL
#define DMA_24BIT_MASK 0x0000000000ffffffULL
+static inline int valid_dma_direction(int dma_direction)
+{
+ return ((dma_direction == DMA_BIDIRECTIONAL) ||
+ (dma_direction == DMA_TO_DEVICE) ||
+ (dma_direction == DMA_FROM_DEVICE));
+}
+
#include <asm/dma-mapping.h>
/* Backwards compat, remove in 2.7.x */
diff --git a/include/linux/dmi.h b/include/linux/dmi.h
index b2cd2071d432..38dc403be70b 100644
--- a/include/linux/dmi.h
+++ b/include/linux/dmi.h
@@ -27,7 +27,8 @@ enum dmi_device_type {
DMI_DEV_TYPE_ETHERNET,
DMI_DEV_TYPE_TOKENRING,
DMI_DEV_TYPE_SOUND,
- DMI_DEV_TYPE_IPMI = -1
+ DMI_DEV_TYPE_IPMI = -1,
+ DMI_DEV_TYPE_OEM_STRING = -2
};
struct dmi_header {
diff --git a/include/linux/elevator.h b/include/linux/elevator.h
index 1713ace808bf..b3370ef5164d 100644
--- a/include/linux/elevator.h
+++ b/include/linux/elevator.h
@@ -1,12 +1,16 @@
#ifndef _LINUX_ELEVATOR_H
#define _LINUX_ELEVATOR_H
+#include <linux/percpu.h>
+
+#ifdef CONFIG_BLOCK
+
typedef int (elevator_merge_fn) (request_queue_t *, struct request **,
struct bio *);
typedef void (elevator_merge_req_fn) (request_queue_t *, struct request *, struct request *);
-typedef void (elevator_merged_fn) (request_queue_t *, struct request *);
+typedef void (elevator_merged_fn) (request_queue_t *, struct request *, int);
typedef int (elevator_dispatch_fn) (request_queue_t *, int);
@@ -14,9 +18,9 @@ typedef void (elevator_add_req_fn) (request_queue_t *, struct request *);
typedef int (elevator_queue_empty_fn) (request_queue_t *);
typedef struct request *(elevator_request_list_fn) (request_queue_t *, struct request *);
typedef void (elevator_completed_req_fn) (request_queue_t *, struct request *);
-typedef int (elevator_may_queue_fn) (request_queue_t *, int, struct bio *);
+typedef int (elevator_may_queue_fn) (request_queue_t *, int);
-typedef int (elevator_set_req_fn) (request_queue_t *, struct request *, struct bio *, gfp_t);
+typedef int (elevator_set_req_fn) (request_queue_t *, struct request *, gfp_t);
typedef void (elevator_put_req_fn) (request_queue_t *, struct request *);
typedef void (elevator_activate_req_fn) (request_queue_t *, struct request *);
typedef void (elevator_deactivate_req_fn) (request_queue_t *, struct request *);
@@ -82,19 +86,21 @@ struct elevator_queue
struct kobject kobj;
struct elevator_type *elevator_type;
struct mutex sysfs_lock;
+ struct hlist_head *hash;
};
/*
* block elevator interface
*/
extern void elv_dispatch_sort(request_queue_t *, struct request *);
+extern void elv_dispatch_add_tail(request_queue_t *, struct request *);
extern void elv_add_request(request_queue_t *, struct request *, int, int);
extern void __elv_add_request(request_queue_t *, struct request *, int, int);
extern void elv_insert(request_queue_t *, struct request *, int);
extern int elv_merge(request_queue_t *, struct request **, struct bio *);
extern void elv_merge_requests(request_queue_t *, struct request *,
struct request *);
-extern void elv_merged_request(request_queue_t *, struct request *);
+extern void elv_merged_request(request_queue_t *, struct request *, int);
extern void elv_dequeue_request(request_queue_t *, struct request *);
extern void elv_requeue_request(request_queue_t *, struct request *);
extern int elv_queue_empty(request_queue_t *);
@@ -103,9 +109,9 @@ extern struct request *elv_former_request(request_queue_t *, struct request *);
extern struct request *elv_latter_request(request_queue_t *, struct request *);
extern int elv_register_queue(request_queue_t *q);
extern void elv_unregister_queue(request_queue_t *q);
-extern int elv_may_queue(request_queue_t *, int, struct bio *);
+extern int elv_may_queue(request_queue_t *, int);
extern void elv_completed_request(request_queue_t *, struct request *);
-extern int elv_set_request(request_queue_t *, struct request *, struct bio *, gfp_t);
+extern int elv_set_request(request_queue_t *, struct request *, gfp_t);
extern void elv_put_request(request_queue_t *, struct request *);
/*
@@ -125,6 +131,19 @@ extern void elevator_exit(elevator_t *);
extern int elv_rq_merge_ok(struct request *, struct bio *);
/*
+ * Helper functions.
+ */
+extern struct request *elv_rb_former_request(request_queue_t *, struct request *);
+extern struct request *elv_rb_latter_request(request_queue_t *, struct request *);
+
+/*
+ * rb support functions.
+ */
+extern struct request *elv_rb_add(struct rb_root *, struct request *);
+extern void elv_rb_del(struct rb_root *, struct request *);
+extern struct request *elv_rb_find(struct rb_root *, sector_t);
+
+/*
* Return values from elevator merger
*/
#define ELEVATOR_NO_MERGE 0
@@ -149,5 +168,42 @@ enum {
};
#define rq_end_sector(rq) ((rq)->sector + (rq)->nr_sectors)
+#define rb_entry_rq(node) rb_entry((node), struct request, rb_node)
+
+/*
+ * Hack to reuse the donelist list_head as the fifo time holder while
+ * the request is in the io scheduler. Saves an unsigned long in rq.
+ */
+#define rq_fifo_time(rq) ((unsigned long) (rq)->donelist.next)
+#define rq_set_fifo_time(rq,exp) ((rq)->donelist.next = (void *) (exp))
+#define rq_entry_fifo(ptr) list_entry((ptr), struct request, queuelist)
+#define rq_fifo_clear(rq) do { \
+ list_del_init(&(rq)->queuelist); \
+ INIT_LIST_HEAD(&(rq)->donelist); \
+ } while (0)
+/*
+ * io context count accounting
+ */
+#define elv_ioc_count_mod(name, __val) \
+ do { \
+ preempt_disable(); \
+ __get_cpu_var(name) += (__val); \
+ preempt_enable(); \
+ } while (0)
+
+#define elv_ioc_count_inc(name) elv_ioc_count_mod(name, 1)
+#define elv_ioc_count_dec(name) elv_ioc_count_mod(name, -1)
+
+#define elv_ioc_count_read(name) \
+({ \
+ unsigned long __val = 0; \
+ int __cpu; \
+ smp_wmb(); \
+ for_each_possible_cpu(__cpu) \
+ __val += per_cpu(name, __cpu); \
+ __val; \
+})
+
+#endif /* CONFIG_BLOCK */
#endif
diff --git a/include/linux/errqueue.h b/include/linux/errqueue.h
index 408118a07763..92f8d4fab32b 100644
--- a/include/linux/errqueue.h
+++ b/include/linux/errqueue.h
@@ -38,7 +38,7 @@ struct sock_exterr_skb
} header;
struct sock_extended_err ee;
u16 addr_offset;
- u16 port;
+ __be16 port;
};
#endif
diff --git a/include/linux/ext2_fs.h b/include/linux/ext2_fs.h
index 33a1aa107329..153d755376a4 100644
--- a/include/linux/ext2_fs.h
+++ b/include/linux/ext2_fs.h
@@ -165,41 +165,49 @@ struct ext2_group_desc
#define EXT2_N_BLOCKS (EXT2_TIND_BLOCK + 1)
/*
- * Inode flags
+ * Inode flags (GETFLAGS/SETFLAGS)
*/
-#define EXT2_SECRM_FL 0x00000001 /* Secure deletion */
-#define EXT2_UNRM_FL 0x00000002 /* Undelete */
-#define EXT2_COMPR_FL 0x00000004 /* Compress file */
-#define EXT2_SYNC_FL 0x00000008 /* Synchronous updates */
-#define EXT2_IMMUTABLE_FL 0x00000010 /* Immutable file */
-#define EXT2_APPEND_FL 0x00000020 /* writes to file may only append */
-#define EXT2_NODUMP_FL 0x00000040 /* do not dump file */
-#define EXT2_NOATIME_FL 0x00000080 /* do not update atime */
+#define EXT2_SECRM_FL FS_SECRM_FL /* Secure deletion */
+#define EXT2_UNRM_FL FS_UNRM_FL /* Undelete */
+#define EXT2_COMPR_FL FS_COMPR_FL /* Compress file */
+#define EXT2_SYNC_FL FS_SYNC_FL /* Synchronous updates */
+#define EXT2_IMMUTABLE_FL FS_IMMUTABLE_FL /* Immutable file */
+#define EXT2_APPEND_FL FS_APPEND_FL /* writes to file may only append */
+#define EXT2_NODUMP_FL FS_NODUMP_FL /* do not dump file */
+#define EXT2_NOATIME_FL FS_NOATIME_FL /* do not update atime */
/* Reserved for compression usage... */
-#define EXT2_DIRTY_FL 0x00000100
-#define EXT2_COMPRBLK_FL 0x00000200 /* One or more compressed clusters */
-#define EXT2_NOCOMP_FL 0x00000400 /* Don't compress */
-#define EXT2_ECOMPR_FL 0x00000800 /* Compression error */
+#define EXT2_DIRTY_FL FS_DIRTY_FL
+#define EXT2_COMPRBLK_FL FS_COMPRBLK_FL /* One or more compressed clusters */
+#define EXT2_NOCOMP_FL FS_NOCOMP_FL /* Don't compress */
+#define EXT2_ECOMPR_FL FS_ECOMPR_FL /* Compression error */
/* End compression flags --- maybe not all used */
-#define EXT2_BTREE_FL 0x00001000 /* btree format dir */
-#define EXT2_INDEX_FL 0x00001000 /* hash-indexed directory */
-#define EXT2_IMAGIC_FL 0x00002000 /* AFS directory */
-#define EXT2_JOURNAL_DATA_FL 0x00004000 /* Reserved for ext3 */
-#define EXT2_NOTAIL_FL 0x00008000 /* file tail should not be merged */
-#define EXT2_DIRSYNC_FL 0x00010000 /* dirsync behaviour (directories only) */
-#define EXT2_TOPDIR_FL 0x00020000 /* Top of directory hierarchies*/
-#define EXT2_RESERVED_FL 0x80000000 /* reserved for ext2 lib */
-
-#define EXT2_FL_USER_VISIBLE 0x0003DFFF /* User visible flags */
-#define EXT2_FL_USER_MODIFIABLE 0x000380FF /* User modifiable flags */
+#define EXT2_BTREE_FL FS_BTREE_FL /* btree format dir */
+#define EXT2_INDEX_FL FS_INDEX_FL /* hash-indexed directory */
+#define EXT2_IMAGIC_FL FS_IMAGIC_FL /* AFS directory */
+#define EXT2_JOURNAL_DATA_FL FS_JOURNAL_DATA_FL /* Reserved for ext3 */
+#define EXT2_NOTAIL_FL FS_NOTAIL_FL /* file tail should not be merged */
+#define EXT2_DIRSYNC_FL FS_DIRSYNC_FL /* dirsync behaviour (directories only) */
+#define EXT2_TOPDIR_FL FS_TOPDIR_FL /* Top of directory hierarchies*/
+#define EXT2_RESERVED_FL FS_RESERVED_FL /* reserved for ext2 lib */
+
+#define EXT2_FL_USER_VISIBLE FS_FL_USER_VISIBLE /* User visible flags */
+#define EXT2_FL_USER_MODIFIABLE FS_FL_USER_MODIFIABLE /* User modifiable flags */
/*
* ioctl commands
*/
-#define EXT2_IOC_GETFLAGS _IOR('f', 1, long)
-#define EXT2_IOC_SETFLAGS _IOW('f', 2, long)
-#define EXT2_IOC_GETVERSION _IOR('v', 1, long)
-#define EXT2_IOC_SETVERSION _IOW('v', 2, long)
+#define EXT2_IOC_GETFLAGS FS_IOC_GETFLAGS
+#define EXT2_IOC_SETFLAGS FS_IOC_SETFLAGS
+#define EXT2_IOC_GETVERSION FS_IOC_GETVERSION
+#define EXT2_IOC_SETVERSION FS_IOC_SETVERSION
+
+/*
+ * ioctl commands in 32 bit emulation
+ */
+#define EXT2_IOC32_GETFLAGS FS_IOC32_GETFLAGS
+#define EXT2_IOC32_SETFLAGS FS_IOC32_SETFLAGS
+#define EXT2_IOC32_GETVERSION FS_IOC32_GETVERSION
+#define EXT2_IOC32_SETVERSION FS_IOC32_SETVERSION
/*
* Structure of an inode on the disk
diff --git a/include/linux/ext3_fs.h b/include/linux/ext3_fs.h
index cc08f56750da..11cca1bdc0c7 100644
--- a/include/linux/ext3_fs.h
+++ b/include/linux/ext3_fs.h
@@ -216,14 +216,14 @@ struct ext3_new_group_data {
/*
* ioctl commands
*/
-#define EXT3_IOC_GETFLAGS _IOR('f', 1, long)
-#define EXT3_IOC_SETFLAGS _IOW('f', 2, long)
+#define EXT3_IOC_GETFLAGS FS_IOC_GETFLAGS
+#define EXT3_IOC_SETFLAGS FS_IOC_SETFLAGS
#define EXT3_IOC_GETVERSION _IOR('f', 3, long)
#define EXT3_IOC_SETVERSION _IOW('f', 4, long)
#define EXT3_IOC_GROUP_EXTEND _IOW('f', 7, unsigned long)
#define EXT3_IOC_GROUP_ADD _IOW('f', 8,struct ext3_new_group_input)
-#define EXT3_IOC_GETVERSION_OLD _IOR('v', 1, long)
-#define EXT3_IOC_SETVERSION_OLD _IOW('v', 2, long)
+#define EXT3_IOC_GETVERSION_OLD FS_IOC_GETVERSION
+#define EXT3_IOC_SETVERSION_OLD FS_IOC_SETVERSION
#ifdef CONFIG_JBD_DEBUG
#define EXT3_IOC_WAIT_FOR_READONLY _IOR('f', 99, long)
#endif
@@ -231,6 +231,23 @@ struct ext3_new_group_data {
#define EXT3_IOC_SETRSVSZ _IOW('f', 6, long)
/*
+ * ioctl commands in 32 bit emulation
+ */
+#define EXT3_IOC32_GETFLAGS FS_IOC32_GETFLAGS
+#define EXT3_IOC32_SETFLAGS FS_IOC32_SETFLAGS
+#define EXT3_IOC32_GETVERSION _IOR('f', 3, int)
+#define EXT3_IOC32_SETVERSION _IOW('f', 4, int)
+#define EXT3_IOC32_GETRSVSZ _IOR('f', 5, int)
+#define EXT3_IOC32_SETRSVSZ _IOW('f', 6, int)
+#define EXT3_IOC32_GROUP_EXTEND _IOW('f', 7, unsigned int)
+#ifdef CONFIG_JBD_DEBUG
+#define EXT3_IOC32_WAIT_FOR_READONLY _IOR('f', 99, int)
+#endif
+#define EXT3_IOC32_GETVERSION_OLD FS_IOC32_GETVERSION
+#define EXT3_IOC32_SETVERSION_OLD FS_IOC32_SETVERSION
+
+
+/*
* Mount options
*/
struct ext3_mount_options {
@@ -812,6 +829,7 @@ extern void ext3_set_aops(struct inode *inode);
/* ioctl.c */
extern int ext3_ioctl (struct inode *, struct file *, unsigned int,
unsigned long);
+extern long ext3_compat_ioctl (struct file *, unsigned int, unsigned long);
/* namei.c */
extern int ext3_orphan_add(handle_t *, struct inode *);
diff --git a/include/linux/fb.h b/include/linux/fb.h
index 2f335e966011..3e69241e6a81 100644
--- a/include/linux/fb.h
+++ b/include/linux/fb.h
@@ -2,6 +2,7 @@
#define _LINUX_FB_H
#include <asm/types.h>
+#include <linux/i2c.h>
/* Definitions of frame buffers */
@@ -775,6 +776,7 @@ struct fb_info {
struct fb_ops *fbops;
struct device *device;
struct class_device *class_device; /* sysfs per device attrs */
+ int class_flag; /* private sysfs flags */
#ifdef CONFIG_FB_TILEBLITTING
struct fb_tile_ops *tileops; /* Tile Blitting */
#endif
@@ -940,6 +942,7 @@ extern void fb_edid_to_monspecs(unsigned char *edid,
struct fb_monspecs *specs);
extern void fb_destroy_modedb(struct fb_videomode *modedb);
extern int fb_find_mode_cvt(struct fb_videomode *mode, int margins, int rb);
+extern unsigned char *fb_ddc_read(struct i2c_adapter *adapter);
/* drivers/video/modedb.c */
#define VESA_MODEDB_SIZE 34
diff --git a/include/linux/file.h b/include/linux/file.h
index 9f7c2513866f..74183e6f7f45 100644
--- a/include/linux/file.h
+++ b/include/linux/file.h
@@ -112,5 +112,6 @@ struct task_struct;
struct files_struct *get_files_struct(struct task_struct *);
void FASTCALL(put_files_struct(struct files_struct *fs));
+void reset_files_struct(struct task_struct *, struct files_struct *);
#endif /* __LINUX_FILE_H */
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 8f74dfbb2edd..f53bf4ff1955 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -79,8 +79,8 @@ extern int dir_notify_enable;
#define WRITE 1
#define READA 2 /* read-ahead - don't block if no resources */
#define SWRITE 3 /* for ll_rw_block() - wait for buffer lock */
-#define SPECIAL 4 /* For non-blockdevice requests in request queue */
#define READ_SYNC (READ | (1 << BIO_RW_SYNC))
+#define READ_META (READ | (1 << BIO_RW_META))
#define WRITE_SYNC (WRITE | (1 << BIO_RW_SYNC))
#define WRITE_BARRIER ((1 << BIO_RW) | (1 << BIO_RW_BARRIER))
@@ -217,6 +217,45 @@ extern int dir_notify_enable;
#define FIBMAP _IO(0x00,1) /* bmap access */
#define FIGETBSZ _IO(0x00,2) /* get the block size used for bmap */
+#define FS_IOC_GETFLAGS _IOR('f', 1, long)
+#define FS_IOC_SETFLAGS _IOW('f', 2, long)
+#define FS_IOC_GETVERSION _IOR('v', 1, long)
+#define FS_IOC_SETVERSION _IOW('v', 2, long)
+#define FS_IOC32_GETFLAGS _IOR('f', 1, int)
+#define FS_IOC32_SETFLAGS _IOW('f', 2, int)
+#define FS_IOC32_GETVERSION _IOR('v', 1, int)
+#define FS_IOC32_SETVERSION _IOW('v', 2, int)
+
+/*
+ * Inode flags (FS_IOC_GETFLAGS / FS_IOC_SETFLAGS)
+ */
+#define FS_SECRM_FL 0x00000001 /* Secure deletion */
+#define FS_UNRM_FL 0x00000002 /* Undelete */
+#define FS_COMPR_FL 0x00000004 /* Compress file */
+#define FS_SYNC_FL 0x00000008 /* Synchronous updates */
+#define FS_IMMUTABLE_FL 0x00000010 /* Immutable file */
+#define FS_APPEND_FL 0x00000020 /* writes to file may only append */
+#define FS_NODUMP_FL 0x00000040 /* do not dump file */
+#define FS_NOATIME_FL 0x00000080 /* do not update atime */
+/* Reserved for compression usage... */
+#define FS_DIRTY_FL 0x00000100
+#define FS_COMPRBLK_FL 0x00000200 /* One or more compressed clusters */
+#define FS_NOCOMP_FL 0x00000400 /* Don't compress */
+#define FS_ECOMPR_FL 0x00000800 /* Compression error */
+/* End compression flags --- maybe not all used */
+#define FS_BTREE_FL 0x00001000 /* btree format dir */
+#define FS_INDEX_FL 0x00001000 /* hash-indexed directory */
+#define FS_IMAGIC_FL 0x00002000 /* AFS directory */
+#define FS_JOURNAL_DATA_FL 0x00004000 /* Reserved for ext3 */
+#define FS_NOTAIL_FL 0x00008000 /* file tail should not be merged */
+#define FS_DIRSYNC_FL 0x00010000 /* dirsync behaviour (directories only) */
+#define FS_TOPDIR_FL 0x00020000 /* Top of directory hierarchies*/
+#define FS_RESERVED_FL 0x80000000 /* reserved for ext2 lib */
+
+#define FS_FL_USER_VISIBLE 0x0003DFFF /* User visible flags */
+#define FS_FL_USER_MODIFIABLE 0x000380FF /* User modifiable flags */
+
+
#define SYNC_FILE_RANGE_WAIT_BEFORE 1
#define SYNC_FILE_RANGE_WRITE 2
#define SYNC_FILE_RANGE_WAIT_AFTER 4
@@ -553,7 +592,9 @@ struct inode {
unsigned int i_flags;
atomic_t i_writecount;
+#ifdef CONFIG_SECURITY
void *i_security;
+#endif
void *i_private; /* fs or device private pointer */
#ifdef __NEED_I_SIZE_ORDERED
seqcount_t i_size_seqcount;
@@ -643,9 +684,9 @@ extern struct block_device *I_BDEV(struct inode *inode);
struct fown_struct {
rwlock_t lock; /* protects pid, uid, euid fields */
- int pid; /* pid or -pgrp where SIGIO should be sent */
+ struct pid *pid; /* pid or -pgrp where SIGIO should be sent */
+ enum pid_type pid_type; /* Kind of process group SIGIO should be sent to */
uid_t uid, euid; /* uid/euid of process setting the owner */
- void *security;
int signum; /* posix.1b rt signal to be delivered on IO */
};
@@ -688,8 +729,9 @@ struct file {
struct file_ra_state f_ra;
unsigned long f_version;
+#ifdef CONFIG_SECURITY
void *f_security;
-
+#endif
/* needed for tty driver, and maybe others */
void *private_data;
@@ -839,8 +881,10 @@ extern void kill_fasync(struct fasync_struct **, int, int);
/* only for net: no internal synchronization */
extern void __kill_fasync(struct fasync_struct *, int, int);
+extern int __f_setown(struct file *filp, struct pid *, enum pid_type, int force);
extern int f_setown(struct file *filp, unsigned long arg, int force);
extern void f_delown(struct file *filp);
+extern pid_t f_getown(struct file *filp);
extern int send_sigurg(struct fown_struct *fown);
/*
@@ -877,7 +921,9 @@ struct super_block {
int s_syncing;
int s_need_sync_fs;
atomic_t s_active;
+#ifdef CONFIG_SECURITY
void *s_security;
+#endif
struct xattr_handler **s_xattr;
struct list_head s_inodes; /* all inodes */
@@ -1003,7 +1049,7 @@ int generic_osync_inode(struct inode *, struct address_space *, int);
* This allows the kernel to read directories into kernel space or
* to have different dirent layouts depending on the binary type.
*/
-typedef int (*filldir_t)(void *, const char *, int, loff_t, ino_t, unsigned);
+typedef int (*filldir_t)(void *, const char *, int, loff_t, u64, unsigned);
struct block_device_operations {
int (*open) (struct inode *, struct file *);
@@ -1054,9 +1100,9 @@ struct file_operations {
struct module *owner;
loff_t (*llseek) (struct file *, loff_t, int);
ssize_t (*read) (struct file *, char __user *, size_t, loff_t *);
- ssize_t (*aio_read) (struct kiocb *, char __user *, size_t, loff_t);
ssize_t (*write) (struct file *, const char __user *, size_t, loff_t *);
- ssize_t (*aio_write) (struct kiocb *, const char __user *, size_t, loff_t);
+ ssize_t (*aio_read) (struct kiocb *, const struct iovec *, unsigned long, loff_t);
+ ssize_t (*aio_write) (struct kiocb *, const struct iovec *, unsigned long, loff_t);
int (*readdir) (struct file *, void *, filldir_t);
unsigned int (*poll) (struct file *, struct poll_table_struct *);
int (*ioctl) (struct inode *, struct file *, unsigned int, unsigned long);
@@ -1070,8 +1116,6 @@ struct file_operations {
int (*aio_fsync) (struct kiocb *, int datasync);
int (*fasync) (int, struct file *, int);
int (*lock) (struct file *, int, struct file_lock *);
- ssize_t (*readv) (struct file *, const struct iovec *, unsigned long, loff_t *);
- ssize_t (*writev) (struct file *, const struct iovec *, unsigned long, loff_t *);
ssize_t (*sendfile) (struct file *, loff_t *, size_t, read_actor_t, void *);
ssize_t (*sendpage) (struct file *, struct page *, int, size_t, loff_t *, int);
unsigned long (*get_unmapped_area)(struct file *, unsigned long, unsigned long, unsigned long, unsigned long);
@@ -1109,6 +1153,11 @@ struct inode_operations {
struct seq_file;
+ssize_t rw_copy_check_uvector(int type, const struct iovec __user * uvector,
+ unsigned long nr_segs, unsigned long fast_segs,
+ struct iovec *fast_pointer,
+ struct iovec **ret_pointer);
+
extern ssize_t vfs_read(struct file *, char __user *, size_t, loff_t *);
extern ssize_t vfs_write(struct file *, const char __user *, size_t, loff_t *);
extern ssize_t vfs_readv(struct file *, const struct iovec __user *,
@@ -1143,9 +1192,10 @@ struct super_operations {
int (*show_options)(struct seq_file *, struct vfsmount *);
int (*show_stats)(struct seq_file *, struct vfsmount *);
-
+#ifdef CONFIG_QUOTA
ssize_t (*quota_read)(struct super_block *, int, char *, size_t, loff_t);
ssize_t (*quota_write)(struct super_block *, int, const char *, size_t, loff_t);
+#endif
};
/* Inode state bits. Protected by inode_lock. */
@@ -1172,15 +1222,30 @@ static inline void mark_inode_dirty_sync(struct inode *inode)
__mark_inode_dirty(inode, I_DIRTY_SYNC);
}
-static inline void inode_inc_link_count(struct inode *inode)
+static inline void inc_nlink(struct inode *inode)
{
inode->i_nlink++;
+}
+
+static inline void inode_inc_link_count(struct inode *inode)
+{
+ inc_nlink(inode);
mark_inode_dirty(inode);
}
-static inline void inode_dec_link_count(struct inode *inode)
+static inline void drop_nlink(struct inode *inode)
{
inode->i_nlink--;
+}
+
+static inline void clear_nlink(struct inode *inode)
+{
+ inode->i_nlink = 0;
+}
+
+static inline void inode_dec_link_count(struct inode *inode)
+{
+ drop_nlink(inode);
mark_inode_dirty(inode);
}
@@ -1438,6 +1503,7 @@ extern void __init vfs_caches_init(unsigned long);
extern void putname(const char *name);
#endif
+#ifdef CONFIG_BLOCK
extern int register_blkdev(unsigned int, const char *);
extern int unregister_blkdev(unsigned int, const char *);
extern struct block_device *bdget(dev_t);
@@ -1446,13 +1512,20 @@ extern void bd_forget(struct inode *inode);
extern void bdput(struct block_device *);
extern struct block_device *open_by_devnum(dev_t, unsigned);
extern struct block_device *open_partition_by_devnum(dev_t, unsigned);
-extern const struct file_operations def_blk_fops;
extern const struct address_space_operations def_blk_aops;
+#else
+static inline void bd_forget(struct inode *inode) {}
+#endif
+extern const struct file_operations def_blk_fops;
extern const struct file_operations def_chr_fops;
extern const struct file_operations bad_sock_fops;
extern const struct file_operations def_fifo_fops;
+#ifdef CONFIG_BLOCK
extern int ioctl_by_bdev(struct block_device *, unsigned, unsigned long);
extern int blkdev_ioctl(struct inode *, struct file *, unsigned, unsigned long);
+extern int blkdev_driver_ioctl(struct inode *inode, struct file *file,
+ struct gendisk *disk, unsigned cmd,
+ unsigned long arg);
extern long compat_blkdev_ioctl(struct file *, unsigned, unsigned long);
extern int blkdev_get(struct block_device *, mode_t, unsigned);
extern int blkdev_put(struct block_device *);
@@ -1466,6 +1539,7 @@ extern void bd_release_from_disk(struct block_device *, struct gendisk *);
#define bd_claim_by_disk(bdev, holder, disk) bd_claim(bdev, holder)
#define bd_release_from_disk(bdev, disk) bd_release(bdev)
#endif
+#endif
/* fs/char_dev.c */
#define CHRDEV_MAJOR_HASH_SIZE 255
@@ -1479,14 +1553,19 @@ extern int chrdev_open(struct inode *, struct file *);
extern void chrdev_show(struct seq_file *,off_t);
/* fs/block_dev.c */
-#define BLKDEV_MAJOR_HASH_SIZE 255
#define BDEVNAME_SIZE 32 /* Largest string for a blockdev identifier */
+
+#ifdef CONFIG_BLOCK
+#define BLKDEV_MAJOR_HASH_SIZE 255
extern const char *__bdevname(dev_t, char *buffer);
extern const char *bdevname(struct block_device *bdev, char *buffer);
extern struct block_device *lookup_bdev(const char *);
extern struct block_device *open_bdev_excl(const char *, int, void *);
extern void close_bdev_excl(struct block_device *);
extern void blkdev_show(struct seq_file *,off_t);
+#else
+#define BLKDEV_MAJOR_HASH_SIZE 0
+#endif
extern void init_special_inode(struct inode *, umode_t, dev_t);
@@ -1500,6 +1579,7 @@ extern const struct file_operations rdwr_fifo_fops;
extern int fs_may_remount_ro(struct super_block *);
+#ifdef CONFIG_BLOCK
/*
* return READ, READA, or WRITE
*/
@@ -1511,9 +1591,10 @@ extern int fs_may_remount_ro(struct super_block *);
#define bio_data_dir(bio) ((bio)->bi_rw & 1)
extern int check_disk_change(struct block_device *);
-extern int invalidate_inodes(struct super_block *);
extern int __invalidate_device(struct block_device *);
extern int invalidate_partition(struct gendisk *, int);
+#endif
+extern int invalidate_inodes(struct super_block *);
unsigned long invalidate_mapping_pages(struct address_space *mapping,
pgoff_t start, pgoff_t end);
unsigned long invalidate_inode_pages(struct address_space *mapping);
@@ -1541,11 +1622,14 @@ extern int __filemap_fdatawrite_range(struct address_space *mapping,
extern long do_fsync(struct file *file, int datasync);
extern void sync_supers(void);
extern void sync_filesystems(int wait);
+extern void __fsync_super(struct super_block *sb);
extern void emergency_sync(void);
extern void emergency_remount(void);
extern int do_remount_sb(struct super_block *sb, int flags,
void *data, int force);
+#ifdef CONFIG_BLOCK
extern sector_t bmap(struct inode *, sector_t);
+#endif
extern int notify_change(struct dentry *, struct iattr *);
extern int permission(struct inode *, int, struct nameidata *);
extern int generic_permission(struct inode *, int,
@@ -1563,6 +1647,9 @@ static inline void allow_write_access(struct file *file)
atomic_inc(&file->f_dentry->d_inode->i_writecount);
}
extern int do_pipe(int *);
+extern struct file *create_read_pipe(struct file *f);
+extern struct file *create_write_pipe(void);
+extern void free_write_pipe(struct file *);
extern int open_namei(int dfd, const char *, int, int, struct nameidata *);
extern int may_open(struct nameidata *, int, int);
@@ -1628,9 +1715,11 @@ static inline void insert_inode_hash(struct inode *inode) {
extern struct file * get_empty_filp(void);
extern void file_move(struct file *f, struct list_head *list);
extern void file_kill(struct file *f);
+#ifdef CONFIG_BLOCK
struct bio;
extern void submit_bio(int, struct bio *);
extern int bdev_read_only(struct block_device *);
+#endif
extern int set_blocksize(struct block_device *, int);
extern int sb_set_blocksize(struct super_block *, int);
extern int sb_min_blocksize(struct super_block *, int);
@@ -1639,22 +1728,17 @@ extern int generic_file_mmap(struct file *, struct vm_area_struct *);
extern int generic_file_readonly_mmap(struct file *, struct vm_area_struct *);
extern int file_read_actor(read_descriptor_t * desc, struct page *page, unsigned long offset, unsigned long size);
extern int file_send_actor(read_descriptor_t * desc, struct page *page, unsigned long offset, unsigned long size);
-extern ssize_t generic_file_read(struct file *, char __user *, size_t, loff_t *);
int generic_write_checks(struct file *file, loff_t *pos, size_t *count, int isblk);
-extern ssize_t generic_file_write(struct file *, const char __user *, size_t, loff_t *);
-extern ssize_t generic_file_aio_read(struct kiocb *, char __user *, size_t, loff_t);
-extern ssize_t __generic_file_aio_read(struct kiocb *, const struct iovec *, unsigned long, loff_t *);
-extern ssize_t generic_file_aio_write(struct kiocb *, const char __user *, size_t, loff_t);
+extern ssize_t generic_file_aio_read(struct kiocb *, const struct iovec *, unsigned long, loff_t);
+extern ssize_t generic_file_aio_write(struct kiocb *, const struct iovec *, unsigned long, loff_t);
extern ssize_t generic_file_aio_write_nolock(struct kiocb *, const struct iovec *,
- unsigned long, loff_t *);
+ unsigned long, loff_t);
extern ssize_t generic_file_direct_write(struct kiocb *, const struct iovec *,
unsigned long *, loff_t, loff_t *, size_t, size_t);
extern ssize_t generic_file_buffered_write(struct kiocb *, const struct iovec *,
unsigned long, loff_t, loff_t *, size_t, ssize_t);
extern ssize_t do_sync_read(struct file *filp, char __user *buf, size_t len, loff_t *ppos);
extern ssize_t do_sync_write(struct file *filp, const char __user *buf, size_t len, loff_t *ppos);
-ssize_t generic_file_write_nolock(struct file *file, const struct iovec *iov,
- unsigned long nr_segs, loff_t *ppos);
extern ssize_t generic_file_sendfile(struct file *, loff_t *, size_t, read_actor_t, void *);
extern void do_generic_mapping_read(struct address_space *mapping,
struct file_ra_state *, struct file *,
@@ -1672,10 +1756,6 @@ extern long do_splice_direct(struct file *in, loff_t *ppos, struct file *out,
extern void
file_ra_state_init(struct file_ra_state *ra, struct address_space *mapping);
-extern ssize_t generic_file_readv(struct file *filp, const struct iovec *iov,
- unsigned long nr_segs, loff_t *ppos);
-ssize_t generic_file_writev(struct file *filp, const struct iovec *iov,
- unsigned long nr_segs, loff_t *ppos);
extern loff_t no_llseek(struct file *file, loff_t offset, int origin);
extern loff_t generic_file_llseek(struct file *file, loff_t offset, int origin);
extern loff_t remote_llseek(struct file *file, loff_t offset, int origin);
@@ -1711,6 +1791,7 @@ static inline void do_generic_file_read(struct file * filp, loff_t *ppos,
actor);
}
+#ifdef CONFIG_BLOCK
ssize_t __blockdev_direct_IO(int rw, struct kiocb *iocb, struct inode *inode,
struct block_device *bdev, const struct iovec *iov, loff_t offset,
unsigned long nr_segs, get_block_t get_block, dio_iodone_t end_io,
@@ -1748,6 +1829,7 @@ static inline ssize_t blockdev_direct_IO_own_locking(int rw, struct kiocb *iocb,
return __blockdev_direct_IO(rw, iocb, inode, bdev, iov, offset,
nr_segs, get_block, end_io, DIO_OWN_LOCKING);
}
+#endif
extern const struct file_operations generic_ro_fops;
diff --git a/include/linux/fs_enet_pd.h b/include/linux/fs_enet_pd.h
index 74ed35a00a94..543cd3cd9e77 100644
--- a/include/linux/fs_enet_pd.h
+++ b/include/linux/fs_enet_pd.h
@@ -55,6 +55,30 @@ static inline int fs_get_scc_index(enum fs_id id)
return -1;
}
+static inline int fs_fec_index2id(int index)
+{
+ int id = fsid_fec1 + index - 1;
+ if (id >= fsid_fec1 && id <= fsid_fec2)
+ return id;
+ return FS_MAX_INDEX;
+ }
+
+static inline int fs_fcc_index2id(int index)
+{
+ int id = fsid_fcc1 + index - 1;
+ if (id >= fsid_fcc1 && id <= fsid_fcc3)
+ return id;
+ return FS_MAX_INDEX;
+}
+
+static inline int fs_scc_index2id(int index)
+{
+ int id = fsid_scc1 + index - 1;
+ if (id >= fsid_scc1 && id <= fsid_scc4)
+ return id;
+ return FS_MAX_INDEX;
+}
+
enum fs_mii_method {
fsmii_fixed,
fsmii_fec,
@@ -87,18 +111,21 @@ struct fs_mii_bb_platform_info {
};
struct fs_platform_info {
-
- void(*init_ioports)(void);
+
+ void(*init_ioports)(struct fs_platform_info *);
/* device specific information */
int fs_no; /* controller index */
+ char fs_type[4]; /* controller type */
u32 cp_page; /* CPM page */
u32 cp_block; /* CPM sblock */
-
+
u32 clk_trx; /* some stuff for pins & mux configuration*/
+ u32 clk_rx;
+ u32 clk_tx;
u32 clk_route;
u32 clk_mask;
-
+
u32 mem_offset;
u32 dpram_offset;
u32 fcc_regs_c;
@@ -124,4 +151,16 @@ struct fs_mii_fec_platform_info {
u32 irq[32];
u32 mii_speed;
};
+
+static inline int fs_get_id(struct fs_platform_info *fpi)
+{
+ if(strstr(fpi->fs_type, "SCC"))
+ return fs_scc_index2id(fpi->fs_no);
+ if(strstr(fpi->fs_type, "FCC"))
+ return fs_fcc_index2id(fpi->fs_no);
+ if(strstr(fpi->fs_type, "FEC"))
+ return fs_fec_index2id(fpi->fs_no);
+ return fpi->fs_no;
+}
+
#endif
diff --git a/include/linux/fs_uart_pd.h b/include/linux/fs_uart_pd.h
index f5975126b712..809bb9ffc788 100644
--- a/include/linux/fs_uart_pd.h
+++ b/include/linux/fs_uart_pd.h
@@ -46,15 +46,27 @@ static inline int fs_uart_id_fsid2smc(int id)
}
struct fs_uart_platform_info {
- void(*init_ioports)(void);
+ void(*init_ioports)(struct fs_uart_platform_info *);
/* device specific information */
int fs_no; /* controller index */
+ char fs_type[4]; /* controller type */
u32 uart_clk;
u8 tx_num_fifo;
u8 tx_buf_size;
u8 rx_num_fifo;
u8 rx_buf_size;
u8 brg;
+ u8 clk_rx;
+ u8 clk_tx;
};
+static inline int fs_uart_get_id(struct fs_uart_platform_info *fpi)
+{
+ if(strstr(fpi->fs_type, "SMC"))
+ return fs_uart_id_smc2fsid(fpi->fs_no);
+ if(strstr(fpi->fs_type, "SCC"))
+ return fs_uart_id_scc2fsid(fpi->fs_no);
+ return fpi->fs_no;
+}
+
#endif
diff --git a/include/linux/genalloc.h b/include/linux/genalloc.h
index 690c42803d2e..9869ef3674ac 100644
--- a/include/linux/genalloc.h
+++ b/include/linux/genalloc.h
@@ -31,5 +31,6 @@ struct gen_pool_chunk {
extern struct gen_pool *gen_pool_create(int, int);
extern int gen_pool_add(struct gen_pool *, unsigned long, size_t, int);
+extern void gen_pool_destroy(struct gen_pool *);
extern unsigned long gen_pool_alloc(struct gen_pool *, size_t);
extern void gen_pool_free(struct gen_pool *, unsigned long, size_t);
diff --git a/include/linux/generic_acl.h b/include/linux/generic_acl.h
new file mode 100644
index 000000000000..80764f40be75
--- /dev/null
+++ b/include/linux/generic_acl.h
@@ -0,0 +1,36 @@
+/*
+ * fs/generic_acl.c
+ *
+ * (C) 2005 Andreas Gruenbacher <agruen@suse.de>
+ *
+ * This file is released under the GPL.
+ */
+
+#ifndef GENERIC_ACL_H
+#define GENERIC_ACL_H
+
+#include <linux/posix_acl.h>
+#include <linux/posix_acl_xattr.h>
+
+/**
+ * struct generic_acl_operations - filesystem operations
+ *
+ * Filesystems must make these operations available to the generic
+ * operations.
+ */
+struct generic_acl_operations {
+ struct posix_acl *(*getacl)(struct inode *, int);
+ void (*setacl)(struct inode *, int, struct posix_acl *);
+};
+
+size_t generic_acl_list(struct inode *, struct generic_acl_operations *, int,
+ char *, size_t);
+int generic_acl_get(struct inode *, struct generic_acl_operations *, int,
+ void *, size_t);
+int generic_acl_set(struct inode *, struct generic_acl_operations *, int,
+ const void *, size_t);
+int generic_acl_init(struct inode *, struct inode *,
+ struct generic_acl_operations *);
+int generic_acl_chmod(struct inode *, struct generic_acl_operations *);
+
+#endif
diff --git a/include/linux/genhd.h b/include/linux/genhd.h
index e4af57e87c17..41f276fdd185 100644
--- a/include/linux/genhd.h
+++ b/include/linux/genhd.h
@@ -11,6 +11,8 @@
#include <linux/types.h>
+#ifdef CONFIG_BLOCK
+
enum {
/* These three have identical behaviour; use the second one if DOS FDISK gets
confused about extended/logical partitions starting past cylinder 1023. */
@@ -420,3 +422,5 @@ static inline struct block_device *bdget_disk(struct gendisk *disk, int index)
#endif
#endif
+
+#endif
diff --git a/include/linux/getcpu.h b/include/linux/getcpu.h
index 031ed3780e45..c7372d7a97be 100644
--- a/include/linux/getcpu.h
+++ b/include/linux/getcpu.h
@@ -1,16 +1,18 @@
#ifndef _LINUX_GETCPU_H
#define _LINUX_GETCPU_H 1
-/* Cache for getcpu() to speed it up. Results might be upto a jiffie
+/* Cache for getcpu() to speed it up. Results might be a short time
out of date, but will be faster.
+
User programs should not refer to the contents of this structure.
- It is only a cache for vgetcpu(). It might change in future kernels.
+ I repeat they should not refer to it. If they do they will break
+ in future kernels.
+
+ It is only a private cache for vgetcpu(). It will change in future kernels.
The user program must store this information per thread (__thread)
If you want 100% accurate information pass NULL instead. */
struct getcpu_cache {
- unsigned long t0;
- unsigned long t1;
- unsigned long res[4];
+ unsigned long blob[128 / sizeof(long)];
};
#endif
diff --git a/include/linux/hrtimer.h b/include/linux/hrtimer.h
index 4fc379de6c2f..fca93025ab51 100644
--- a/include/linux/hrtimer.h
+++ b/include/linux/hrtimer.h
@@ -138,6 +138,7 @@ extern long hrtimer_nanosleep(struct timespec *rqtp,
struct timespec __user *rmtp,
const enum hrtimer_mode mode,
const clockid_t clockid);
+extern long hrtimer_nanosleep_restart(struct restart_block *restart_block);
extern void hrtimer_init_sleeper(struct hrtimer_sleeper *sl,
struct task_struct *tsk);
diff --git a/include/linux/i2c-id.h b/include/linux/i2c-id.h
index 9418519a55d1..0a8f750cbede 100644
--- a/include/linux/i2c-id.h
+++ b/include/linux/i2c-id.h
@@ -193,6 +193,7 @@
#define I2C_HW_B_RADEON 0x01001e /* radeon framebuffer driver */
#define I2C_HW_B_EM28XX 0x01001f /* em28xx video capture cards */
#define I2C_HW_B_CX2341X 0x010020 /* Conexant CX2341X MPEG encoder cards */
+#define I2C_HW_B_INTELFB 0x010021 /* intel framebuffer driver */
/* --- PCF 8584 based algorithms */
#define I2C_HW_P_LP 0x020000 /* Parallel port interface */
diff --git a/include/linux/icmp.h b/include/linux/icmp.h
index f0b571f1060b..878cfe4e587f 100644
--- a/include/linux/icmp.h
+++ b/include/linux/icmp.h
@@ -68,16 +68,16 @@
struct icmphdr {
__u8 type;
__u8 code;
- __u16 checksum;
+ __be16 checksum;
union {
struct {
- __u16 id;
- __u16 sequence;
+ __be16 id;
+ __be16 sequence;
} echo;
- __u32 gateway;
+ __be32 gateway;
struct {
- __u16 __unused;
- __u16 mtu;
+ __be16 __unused;
+ __be16 mtu;
} frag;
} un;
};
diff --git a/include/linux/ide.h b/include/linux/ide.h
index 99620451d958..07d8d725541f 100644
--- a/include/linux/ide.h
+++ b/include/linux/ide.h
@@ -251,7 +251,8 @@ static inline void ide_std_init_ports(hw_regs_t *hw,
#include <asm/ide.h>
-#ifndef MAX_HWIFS
+#if !defined(MAX_HWIFS) || defined(CONFIG_EMBEDDED)
+#undef MAX_HWIFS
#define MAX_HWIFS CONFIG_IDE_MAX_HWIFS
#endif
@@ -773,12 +774,13 @@ typedef struct hwif_s {
unsigned long dma_status; /* dma status register */
unsigned long dma_vendor3; /* dma vendor 3 register */
unsigned long dma_prdtable; /* actual prd table address */
- unsigned long dma_base2; /* extended base addr for dma ports */
- unsigned dma_extra; /* extra addr for dma ports */
unsigned long config_data; /* for use by chipset-specific code */
unsigned long select_data; /* for use by chipset-specific code */
+ unsigned long extra_base; /* extra addr for dma ports */
+ unsigned extra_ports; /* number of extra dma ports */
+
unsigned noprobe : 1; /* don't probe for this interface */
unsigned present : 1; /* this interface exists */
unsigned hold : 1; /* this interface is always present */
@@ -823,6 +825,9 @@ typedef struct hwgroup_s {
unsigned int sleeping : 1;
/* BOOL: polling active & poll_timeout field valid */
unsigned int polling : 1;
+ /* BOOL: in a polling reset situation. Must not trigger another reset yet */
+ unsigned int resetting : 1;
+
/* current drive */
ide_drive_t *drive;
/* ptr to current hwif in linked-list */
@@ -1190,7 +1195,6 @@ extern int ideprobe_init(void);
extern void ide_scan_pcibus(int scan_direction) __init;
extern int __ide_pci_register_driver(struct pci_driver *driver, struct module *owner);
#define ide_pci_register_driver(d) __ide_pci_register_driver(d, THIS_MODULE)
-extern void ide_pci_unregister_driver(struct pci_driver *driver);
void ide_pci_setup_ports(struct pci_dev *, struct ide_pci_device_s *, int, ata_index_t *);
extern void ide_setup_pci_noise (struct pci_dev *dev, struct ide_pci_device_s *d);
diff --git a/include/linux/if.h b/include/linux/if.h
index 8018c2e22c0c..32bf419351f1 100644
--- a/include/linux/if.h
+++ b/include/linux/if.h
@@ -214,134 +214,4 @@ struct ifconf
#define ifc_buf ifc_ifcu.ifcu_buf /* buffer address */
#define ifc_req ifc_ifcu.ifcu_req /* array of structures */
-/* The struct should be in sync with struct net_device_stats */
-struct rtnl_link_stats
-{
- __u32 rx_packets; /* total packets received */
- __u32 tx_packets; /* total packets transmitted */
- __u32 rx_bytes; /* total bytes received */
- __u32 tx_bytes; /* total bytes transmitted */
- __u32 rx_errors; /* bad packets received */
- __u32 tx_errors; /* packet transmit problems */
- __u32 rx_dropped; /* no space in linux buffers */
- __u32 tx_dropped; /* no space available in linux */
- __u32 multicast; /* multicast packets received */
- __u32 collisions;
-
- /* detailed rx_errors: */
- __u32 rx_length_errors;
- __u32 rx_over_errors; /* receiver ring buff overflow */
- __u32 rx_crc_errors; /* recved pkt with crc error */
- __u32 rx_frame_errors; /* recv'd frame alignment error */
- __u32 rx_fifo_errors; /* recv'r fifo overrun */
- __u32 rx_missed_errors; /* receiver missed packet */
-
- /* detailed tx_errors */
- __u32 tx_aborted_errors;
- __u32 tx_carrier_errors;
- __u32 tx_fifo_errors;
- __u32 tx_heartbeat_errors;
- __u32 tx_window_errors;
-
- /* for cslip etc */
- __u32 rx_compressed;
- __u32 tx_compressed;
-};
-
-/* The struct should be in sync with struct ifmap */
-struct rtnl_link_ifmap
-{
- __u64 mem_start;
- __u64 mem_end;
- __u64 base_addr;
- __u16 irq;
- __u8 dma;
- __u8 port;
-};
-
-enum
-{
- IFLA_UNSPEC,
- IFLA_ADDRESS,
- IFLA_BROADCAST,
- IFLA_IFNAME,
- IFLA_MTU,
- IFLA_LINK,
- IFLA_QDISC,
- IFLA_STATS,
- IFLA_COST,
-#define IFLA_COST IFLA_COST
- IFLA_PRIORITY,
-#define IFLA_PRIORITY IFLA_PRIORITY
- IFLA_MASTER,
-#define IFLA_MASTER IFLA_MASTER
- IFLA_WIRELESS, /* Wireless Extension event - see wireless.h */
-#define IFLA_WIRELESS IFLA_WIRELESS
- IFLA_PROTINFO, /* Protocol specific information for a link */
-#define IFLA_PROTINFO IFLA_PROTINFO
- IFLA_TXQLEN,
-#define IFLA_TXQLEN IFLA_TXQLEN
- IFLA_MAP,
-#define IFLA_MAP IFLA_MAP
- IFLA_WEIGHT,
-#define IFLA_WEIGHT IFLA_WEIGHT
- IFLA_OPERSTATE,
- IFLA_LINKMODE,
- __IFLA_MAX
-};
-
-
-#define IFLA_MAX (__IFLA_MAX - 1)
-
-/* ifi_flags.
-
- IFF_* flags.
-
- The only change is:
- IFF_LOOPBACK, IFF_BROADCAST and IFF_POINTOPOINT are
- more not changeable by user. They describe link media
- characteristics and set by device driver.
-
- Comments:
- - Combination IFF_BROADCAST|IFF_POINTOPOINT is invalid
- - If neither of these three flags are set;
- the interface is NBMA.
-
- - IFF_MULTICAST does not mean anything special:
- multicasts can be used on all not-NBMA links.
- IFF_MULTICAST means that this media uses special encapsulation
- for multicast frames. Apparently, all IFF_POINTOPOINT and
- IFF_BROADCAST devices are able to use multicasts too.
- */
-
-/* IFLA_LINK.
- For usual devices it is equal ifi_index.
- If it is a "virtual interface" (f.e. tunnel), ifi_link
- can point to real physical interface (f.e. for bandwidth calculations),
- or maybe 0, what means, that real media is unknown (usual
- for IPIP tunnels, when route to endpoint is allowed to change)
- */
-
-/* Subtype attributes for IFLA_PROTINFO */
-enum
-{
- IFLA_INET6_UNSPEC,
- IFLA_INET6_FLAGS, /* link flags */
- IFLA_INET6_CONF, /* sysctl parameters */
- IFLA_INET6_STATS, /* statistics */
- IFLA_INET6_MCAST, /* MC things. What of them? */
- IFLA_INET6_CACHEINFO, /* time values and max reasm size */
- __IFLA_INET6_MAX
-};
-
-#define IFLA_INET6_MAX (__IFLA_INET6_MAX - 1)
-
-struct ifla_cacheinfo
-{
- __u32 max_reasm_len;
- __u32 tstamp; /* ipv6InterfaceTable updated timestamp */
- __u32 reachable_time;
- __u32 retrans_time;
-};
-
#endif /* _LINUX_IF_H */
diff --git a/include/linux/if_arp.h b/include/linux/if_arp.h
index a8b1a2071838..7f5714214ee3 100644
--- a/include/linux/if_arp.h
+++ b/include/linux/if_arp.h
@@ -130,11 +130,11 @@ struct arpreq_old {
struct arphdr
{
- unsigned short ar_hrd; /* format of hardware address */
- unsigned short ar_pro; /* format of protocol address */
+ __be16 ar_hrd; /* format of hardware address */
+ __be16 ar_pro; /* format of protocol address */
unsigned char ar_hln; /* length of hardware address */
unsigned char ar_pln; /* length of protocol address */
- unsigned short ar_op; /* ARP opcode (command) */
+ __be16 ar_op; /* ARP opcode (command) */
#if 0
/*
diff --git a/include/linux/if_link.h b/include/linux/if_link.h
new file mode 100644
index 000000000000..e963a077e6f5
--- /dev/null
+++ b/include/linux/if_link.h
@@ -0,0 +1,136 @@
+#ifndef _LINUX_IF_LINK_H
+#define _LINUX_IF_LINK_H
+
+#include <linux/netlink.h>
+
+/* The struct should be in sync with struct net_device_stats */
+struct rtnl_link_stats
+{
+ __u32 rx_packets; /* total packets received */
+ __u32 tx_packets; /* total packets transmitted */
+ __u32 rx_bytes; /* total bytes received */
+ __u32 tx_bytes; /* total bytes transmitted */
+ __u32 rx_errors; /* bad packets received */
+ __u32 tx_errors; /* packet transmit problems */
+ __u32 rx_dropped; /* no space in linux buffers */
+ __u32 tx_dropped; /* no space available in linux */
+ __u32 multicast; /* multicast packets received */
+ __u32 collisions;
+
+ /* detailed rx_errors: */
+ __u32 rx_length_errors;
+ __u32 rx_over_errors; /* receiver ring buff overflow */
+ __u32 rx_crc_errors; /* recved pkt with crc error */
+ __u32 rx_frame_errors; /* recv'd frame alignment error */
+ __u32 rx_fifo_errors; /* recv'r fifo overrun */
+ __u32 rx_missed_errors; /* receiver missed packet */
+
+ /* detailed tx_errors */
+ __u32 tx_aborted_errors;
+ __u32 tx_carrier_errors;
+ __u32 tx_fifo_errors;
+ __u32 tx_heartbeat_errors;
+ __u32 tx_window_errors;
+
+ /* for cslip etc */
+ __u32 rx_compressed;
+ __u32 tx_compressed;
+};
+
+/* The struct should be in sync with struct ifmap */
+struct rtnl_link_ifmap
+{
+ __u64 mem_start;
+ __u64 mem_end;
+ __u64 base_addr;
+ __u16 irq;
+ __u8 dma;
+ __u8 port;
+};
+
+enum
+{
+ IFLA_UNSPEC,
+ IFLA_ADDRESS,
+ IFLA_BROADCAST,
+ IFLA_IFNAME,
+ IFLA_MTU,
+ IFLA_LINK,
+ IFLA_QDISC,
+ IFLA_STATS,
+ IFLA_COST,
+#define IFLA_COST IFLA_COST
+ IFLA_PRIORITY,
+#define IFLA_PRIORITY IFLA_PRIORITY
+ IFLA_MASTER,
+#define IFLA_MASTER IFLA_MASTER
+ IFLA_WIRELESS, /* Wireless Extension event - see wireless.h */
+#define IFLA_WIRELESS IFLA_WIRELESS
+ IFLA_PROTINFO, /* Protocol specific information for a link */
+#define IFLA_PROTINFO IFLA_PROTINFO
+ IFLA_TXQLEN,
+#define IFLA_TXQLEN IFLA_TXQLEN
+ IFLA_MAP,
+#define IFLA_MAP IFLA_MAP
+ IFLA_WEIGHT,
+#define IFLA_WEIGHT IFLA_WEIGHT
+ IFLA_OPERSTATE,
+ IFLA_LINKMODE,
+ __IFLA_MAX
+};
+
+
+#define IFLA_MAX (__IFLA_MAX - 1)
+
+/* ifi_flags.
+
+ IFF_* flags.
+
+ The only change is:
+ IFF_LOOPBACK, IFF_BROADCAST and IFF_POINTOPOINT are
+ more not changeable by user. They describe link media
+ characteristics and set by device driver.
+
+ Comments:
+ - Combination IFF_BROADCAST|IFF_POINTOPOINT is invalid
+ - If neither of these three flags are set;
+ the interface is NBMA.
+
+ - IFF_MULTICAST does not mean anything special:
+ multicasts can be used on all not-NBMA links.
+ IFF_MULTICAST means that this media uses special encapsulation
+ for multicast frames. Apparently, all IFF_POINTOPOINT and
+ IFF_BROADCAST devices are able to use multicasts too.
+ */
+
+/* IFLA_LINK.
+ For usual devices it is equal ifi_index.
+ If it is a "virtual interface" (f.e. tunnel), ifi_link
+ can point to real physical interface (f.e. for bandwidth calculations),
+ or maybe 0, what means, that real media is unknown (usual
+ for IPIP tunnels, when route to endpoint is allowed to change)
+ */
+
+/* Subtype attributes for IFLA_PROTINFO */
+enum
+{
+ IFLA_INET6_UNSPEC,
+ IFLA_INET6_FLAGS, /* link flags */
+ IFLA_INET6_CONF, /* sysctl parameters */
+ IFLA_INET6_STATS, /* statistics */
+ IFLA_INET6_MCAST, /* MC things. What of them? */
+ IFLA_INET6_CACHEINFO, /* time values and max reasm size */
+ __IFLA_INET6_MAX
+};
+
+#define IFLA_INET6_MAX (__IFLA_INET6_MAX - 1)
+
+struct ifla_cacheinfo
+{
+ __u32 max_reasm_len;
+ __u32 tstamp; /* ipv6InterfaceTable updated timestamp */
+ __u32 reachable_time;
+ __u32 retrans_time;
+};
+
+#endif /* _LINUX_IF_LINK_H */
diff --git a/include/linux/igmp.h b/include/linux/igmp.h
index 899c3d4776f3..03f43e2893a4 100644
--- a/include/linux/igmp.h
+++ b/include/linux/igmp.h
@@ -30,8 +30,8 @@ struct igmphdr
{
__u8 type;
__u8 code; /* For newer IGMP */
- __u16 csum;
- __u32 group;
+ __be16 csum;
+ __be32 group;
};
/* V3 group record types [grec_type] */
@@ -45,25 +45,25 @@ struct igmphdr
struct igmpv3_grec {
__u8 grec_type;
__u8 grec_auxwords;
- __u16 grec_nsrcs;
- __u32 grec_mca;
- __u32 grec_src[0];
+ __be16 grec_nsrcs;
+ __be32 grec_mca;
+ __be32 grec_src[0];
};
struct igmpv3_report {
__u8 type;
__u8 resv1;
- __u16 csum;
- __u16 resv2;
- __u16 ngrec;
+ __be16 csum;
+ __be16 resv2;
+ __be16 ngrec;
struct igmpv3_grec grec[0];
};
struct igmpv3_query {
__u8 type;
__u8 code;
- __u16 csum;
- __u32 group;
+ __be16 csum;
+ __be32 group;
#if defined(__LITTLE_ENDIAN_BITFIELD)
__u8 qrv:3,
suppress:1,
@@ -76,8 +76,8 @@ struct igmpv3_query {
#error "Please fix <asm/byteorder.h>"
#endif
__u8 qqic;
- __u16 nsrcs;
- __u32 srcs[0];
+ __be16 nsrcs;
+ __be32 srcs[0];
};
#define IGMP_HOST_MEMBERSHIP_QUERY 0x11 /* From RFC1112 */
@@ -136,11 +136,11 @@ struct ip_sf_socklist
{
unsigned int sl_max;
unsigned int sl_count;
- __u32 sl_addr[0];
+ __be32 sl_addr[0];
};
#define IP_SFLSIZE(count) (sizeof(struct ip_sf_socklist) + \
- (count) * sizeof(__u32))
+ (count) * sizeof(__be32))
#define IP_SFBLOCK 10 /* allocate this many at once */
@@ -159,7 +159,7 @@ struct ip_mc_socklist
struct ip_sf_list
{
struct ip_sf_list *sf_next;
- __u32 sf_inaddr;
+ __be32 sf_inaddr;
unsigned long sf_count[2]; /* include/exclude counts */
unsigned char sf_gsresp; /* include in g & s response? */
unsigned char sf_oldin; /* change state */
@@ -197,7 +197,7 @@ struct ip_mc_list
#define IGMPV3_QQIC(value) IGMPV3_EXP(0x80, 4, 3, value)
#define IGMPV3_MRC(value) IGMPV3_EXP(0x80, 4, 3, value)
-extern int ip_check_mc(struct in_device *dev, u32 mc_addr, u32 src_addr, u16 proto);
+extern int ip_check_mc(struct in_device *dev, __be32 mc_addr, __be32 src_addr, u16 proto);
extern int igmp_rcv(struct sk_buff *);
extern int ip_mc_join_group(struct sock *sk, struct ip_mreqn *imr);
extern int ip_mc_leave_group(struct sock *sk, struct ip_mreqn *imr);
@@ -209,13 +209,13 @@ extern int ip_mc_msfget(struct sock *sk, struct ip_msfilter *msf,
struct ip_msfilter __user *optval, int __user *optlen);
extern int ip_mc_gsfget(struct sock *sk, struct group_filter *gsf,
struct group_filter __user *optval, int __user *optlen);
-extern int ip_mc_sf_allow(struct sock *sk, u32 local, u32 rmt, int dif);
+extern int ip_mc_sf_allow(struct sock *sk, __be32 local, __be32 rmt, int dif);
extern void ip_mr_init(void);
extern void ip_mc_init_dev(struct in_device *);
extern void ip_mc_destroy_dev(struct in_device *);
extern void ip_mc_up(struct in_device *);
extern void ip_mc_down(struct in_device *);
-extern void ip_mc_dec_group(struct in_device *in_dev, u32 addr);
-extern void ip_mc_inc_group(struct in_device *in_dev, u32 addr);
+extern void ip_mc_dec_group(struct in_device *in_dev, __be32 addr);
+extern void ip_mc_inc_group(struct in_device *in_dev, __be32 addr);
#endif
#endif
diff --git a/include/linux/in.h b/include/linux/in.h
index bcaca8399aed..d79fc75fa7c2 100644
--- a/include/linux/in.h
+++ b/include/linux/in.h
@@ -123,17 +123,17 @@ struct ip_mreqn
};
struct ip_mreq_source {
- __u32 imr_multiaddr;
- __u32 imr_interface;
- __u32 imr_sourceaddr;
+ __be32 imr_multiaddr;
+ __be32 imr_interface;
+ __be32 imr_sourceaddr;
};
struct ip_msfilter {
- __u32 imsf_multiaddr;
- __u32 imsf_interface;
+ __be32 imsf_multiaddr;
+ __be32 imsf_interface;
__u32 imsf_fmode;
__u32 imsf_numsrc;
- __u32 imsf_slist[1];
+ __be32 imsf_slist[1];
};
#define IP_MSFILTER_SIZE(numsrc) \
diff --git a/include/linux/in6.h b/include/linux/in6.h
index d776829b443f..9be6a4756f0b 100644
--- a/include/linux/in6.h
+++ b/include/linux/in6.h
@@ -32,8 +32,8 @@ struct in6_addr
union
{
__u8 u6_addr8[16];
- __u16 u6_addr16[8];
- __u32 u6_addr32[4];
+ __be16 u6_addr16[8];
+ __be32 u6_addr32[4];
} in6_u;
#define s6_addr in6_u.u6_addr8
#define s6_addr16 in6_u.u6_addr16
@@ -53,7 +53,7 @@ extern const struct in6_addr in6addr_loopback;
struct sockaddr_in6 {
unsigned short int sin6_family; /* AF_INET6 */
- __u16 sin6_port; /* Transport layer port # */
+ __be16 sin6_port; /* Transport layer port # */
__u32 sin6_flowinfo; /* IPv6 flow information */
struct in6_addr sin6_addr; /* IPv6 address */
__u32 sin6_scope_id; /* scope id (new in RFC2553) */
diff --git a/include/linux/inet_diag.h b/include/linux/inet_diag.h
index a4606e5810e5..6e8bc548635a 100644
--- a/include/linux/inet_diag.h
+++ b/include/linux/inet_diag.h
@@ -9,10 +9,10 @@
/* Socket identity */
struct inet_diag_sockid {
- __u16 idiag_sport;
- __u16 idiag_dport;
- __u32 idiag_src[4];
- __u32 idiag_dst[4];
+ __be16 idiag_sport;
+ __be16 idiag_dport;
+ __be32 idiag_src[4];
+ __be32 idiag_dst[4];
__u32 idiag_if;
__u32 idiag_cookie[2];
#define INET_DIAG_NOCOOKIE (~0U)
@@ -67,7 +67,7 @@ struct inet_diag_hostcond {
__u8 family;
__u8 prefix_len;
int port;
- __u32 addr[0];
+ __be32 addr[0];
};
/* Base info structure. It contains socket identity (addrs/ports/cookie)
diff --git a/include/linux/inetdevice.h b/include/linux/inetdevice.h
index 92297ff24e85..5a0ab04627bc 100644
--- a/include/linux/inetdevice.h
+++ b/include/linux/inetdevice.h
@@ -90,11 +90,11 @@ struct in_ifaddr
struct in_ifaddr *ifa_next;
struct in_device *ifa_dev;
struct rcu_head rcu_head;
- u32 ifa_local;
- u32 ifa_address;
- u32 ifa_mask;
- u32 ifa_broadcast;
- u32 ifa_anycast;
+ __be32 ifa_local;
+ __be32 ifa_address;
+ __be32 ifa_mask;
+ __be32 ifa_broadcast;
+ __be32 ifa_anycast;
unsigned char ifa_scope;
unsigned char ifa_flags;
unsigned char ifa_prefixlen;
@@ -104,18 +104,18 @@ struct in_ifaddr
extern int register_inetaddr_notifier(struct notifier_block *nb);
extern int unregister_inetaddr_notifier(struct notifier_block *nb);
-extern struct net_device *ip_dev_find(u32 addr);
-extern int inet_addr_onlink(struct in_device *in_dev, u32 a, u32 b);
+extern struct net_device *ip_dev_find(__be32 addr);
+extern int inet_addr_onlink(struct in_device *in_dev, __be32 a, __be32 b);
extern int devinet_ioctl(unsigned int cmd, void __user *);
extern void devinet_init(void);
extern struct in_device *inetdev_init(struct net_device *dev);
extern struct in_device *inetdev_by_index(int);
-extern u32 inet_select_addr(const struct net_device *dev, u32 dst, int scope);
-extern u32 inet_confirm_addr(const struct net_device *dev, u32 dst, u32 local, int scope);
-extern struct in_ifaddr *inet_ifa_byprefix(struct in_device *in_dev, u32 prefix, u32 mask);
+extern __be32 inet_select_addr(const struct net_device *dev, __be32 dst, int scope);
+extern __be32 inet_confirm_addr(const struct net_device *dev, __be32 dst, __be32 local, int scope);
+extern struct in_ifaddr *inet_ifa_byprefix(struct in_device *in_dev, __be32 prefix, __be32 mask);
extern void inet_forward_change(void);
-static __inline__ int inet_ifa_match(u32 addr, struct in_ifaddr *ifa)
+static __inline__ int inet_ifa_match(__be32 addr, struct in_ifaddr *ifa)
{
return !((addr^ifa->ifa_address)&ifa->ifa_mask);
}
@@ -183,7 +183,7 @@ static inline void in_dev_put(struct in_device *idev)
#endif /* __KERNEL__ */
-static __inline__ __u32 inet_make_mask(int logmask)
+static __inline__ __be32 inet_make_mask(int logmask)
{
if (logmask)
return htonl(~((1<<(32-logmask))-1));
diff --git a/include/linux/init_task.h b/include/linux/init_task.h
index 60aac2cea0cf..33c5daacc743 100644
--- a/include/linux/init_task.h
+++ b/include/linux/init_task.h
@@ -4,7 +4,9 @@
#include <linux/file.h>
#include <linux/rcupdate.h>
#include <linux/irqflags.h>
+#include <linux/utsname.h>
#include <linux/lockdep.h>
+#include <linux/ipc.h>
#define INIT_FDTABLE \
{ \
@@ -68,6 +70,15 @@
.session = 1, \
}
+extern struct nsproxy init_nsproxy;
+#define INIT_NSPROXY(nsproxy) { \
+ .count = ATOMIC_INIT(1), \
+ .nslock = SPIN_LOCK_UNLOCKED, \
+ .uts_ns = &init_uts_ns, \
+ .namespace = NULL, \
+ INIT_IPC_NS(ipc_ns) \
+}
+
#define INIT_SIGHAND(sighand) { \
.count = ATOMIC_INIT(1), \
.action = { { { .sa_handler = NULL, } }, }, \
@@ -117,6 +128,7 @@ extern struct group_info init_groups;
.files = &init_files, \
.signal = &init_signals, \
.sighand = &init_sighand, \
+ .nsproxy = &init_nsproxy, \
.pending = { \
.list = LIST_HEAD_INIT(tsk.pending.list), \
.signal = {{0}}}, \
diff --git a/include/linux/input.h b/include/linux/input.h
index b3253ab72ff7..5770105471dd 100644
--- a/include/linux/input.h
+++ b/include/linux/input.h
@@ -349,6 +349,9 @@ struct input_absinfo {
#define KEY_BATTERY 236
+#define KEY_BLUETOOTH 237
+#define KEY_WLAN 238
+
#define KEY_UNKNOWN 240
#define BTN_MISC 0x100
@@ -645,6 +648,7 @@ struct input_absinfo {
#define BUS_USB 0x03
#define BUS_HIL 0x04
#define BUS_BLUETOOTH 0x05
+#define BUS_VIRTUAL 0x06
#define BUS_ISA 0x10
#define BUS_I8042 0x11
@@ -667,98 +671,167 @@ struct input_absinfo {
/*
* Structures used in ioctls to upload effects to a device
- * The first structures are not passed directly by using ioctls.
- * They are sub-structures of the actually sent structure (called ff_effect)
+ * They are pieces of a bigger structure (called ff_effect)
+ */
+
+/*
+ * All duration values are expressed in ms. Values above 32767 ms (0x7fff)
+ * should not be used and have unspecified results.
*/
+/**
+ * struct ff_replay - defines scheduling of the effect
+ * @length: duration of the effect
+ * @delay: delay before effect should start playing
+ */
struct ff_replay {
- __u16 length; /* Duration of an effect in ms. All other times are also expressed in ms */
- __u16 delay; /* Time to wait before to start playing an effect */
+ __u16 length;
+ __u16 delay;
};
+/**
+ * struct ff_trigger - defines what triggers the effect
+ * @button: number of the button triggering the effect
+ * @interval: controls how soon the effect can be re-triggered
+ */
struct ff_trigger {
- __u16 button; /* Number of button triggering an effect */
- __u16 interval; /* Time to wait before an effect can be re-triggered (ms) */
+ __u16 button;
+ __u16 interval;
};
+/**
+ * struct ff_envelope - generic effect envelope
+ * @attack_length: duration of the attack (ms)
+ * @attack_level: level at the beginning of the attack
+ * @fade_length: duration of fade (ms)
+ * @fade_level: level at the end of fade
+ *
+ * The @attack_level and @fade_level are absolute values; when applying
+ * envelope force-feedback core will convert to positive/negative
+ * value based on polarity of the default level of the effect.
+ * Valid range for the attack and fade levels is 0x0000 - 0x7fff
+ */
struct ff_envelope {
- __u16 attack_length; /* Duration of attack (ms) */
- __u16 attack_level; /* Level at beginning of attack */
- __u16 fade_length; /* Duration of fade (ms) */
- __u16 fade_level; /* Level at end of fade */
+ __u16 attack_length;
+ __u16 attack_level;
+ __u16 fade_length;
+ __u16 fade_level;
};
-/* FF_CONSTANT */
+/**
+ * struct ff_constant_effect - defines parameters of a constant effect
+ * @level: strength of the effect; may be negative
+ * @envelope: envelope data
+ */
struct ff_constant_effect {
- __s16 level; /* Strength of effect. Negative values are OK */
+ __s16 level;
struct ff_envelope envelope;
};
-/* FF_RAMP */
+/**
+ * struct ff_ramp_effect - defines parameters of a ramp effect
+ * @start_level: beginning strength of the effect; may be negative
+ * @end_level: final strength of the effect; may be negative
+ * @envelope: envelope data
+ */
struct ff_ramp_effect {
__s16 start_level;
__s16 end_level;
struct ff_envelope envelope;
};
-/* FF_SPRING of FF_FRICTION */
+/**
+ * struct ff_condition_effect - defines a spring or friction effect
+ * @right_saturation: maximum level when joystick moved all way to the right
+ * @left_saturation: same for the left side
+ * @right_coeff: controls how fast the force grows when the joystick moves
+ * to the right
+ * @left_coeff: same for the left side
+ * @deadband: size of the dead zone, where no force is produced
+ * @center: position of the dead zone
+ */
struct ff_condition_effect {
- __u16 right_saturation; /* Max level when joystick is on the right */
- __u16 left_saturation; /* Max level when joystick in on the left */
-
- __s16 right_coeff; /* Indicates how fast the force grows when the
- joystick moves to the right */
- __s16 left_coeff; /* Same for left side */
+ __u16 right_saturation;
+ __u16 left_saturation;
- __u16 deadband; /* Size of area where no force is produced */
- __s16 center; /* Position of dead zone */
+ __s16 right_coeff;
+ __s16 left_coeff;
+ __u16 deadband;
+ __s16 center;
};
-/* FF_PERIODIC */
+/**
+ * struct ff_periodic_effect - defines parameters of a periodic effect
+ * @waveform: kind of the effect (wave)
+ * @period: period of the wave (ms)
+ * @magnitude: peak value
+ * @offset: mean value of the wave (roughly)
+ * @phase: 'horizontal' shift
+ * @envelope: envelope data
+ * @custom_len: number of samples (FF_CUSTOM only)
+ * @custom_data: buffer of samples (FF_CUSTOM only)
+ *
+ * Known waveforms - FF_SQUARE, FF_TRIANGLE, FF_SINE, FF_SAW_UP,
+ * FF_SAW_DOWN, FF_CUSTOM. The exact syntax FF_CUSTOM is undefined
+ * for the time being as no driver supports it yet.
+ *
+ * Note: the data pointed by custom_data is copied by the driver.
+ * You can therefore dispose of the memory after the upload/update.
+ */
struct ff_periodic_effect {
- __u16 waveform; /* Kind of wave (sine, square...) */
- __u16 period; /* in ms */
- __s16 magnitude; /* Peak value */
- __s16 offset; /* Mean value of wave (roughly) */
- __u16 phase; /* 'Horizontal' shift */
+ __u16 waveform;
+ __u16 period;
+ __s16 magnitude;
+ __s16 offset;
+ __u16 phase;
struct ff_envelope envelope;
-/* Only used if waveform == FF_CUSTOM */
- __u32 custom_len; /* Number of samples */
- __s16 *custom_data; /* Buffer of samples */
-/* Note: the data pointed by custom_data is copied by the driver. You can
- * therefore dispose of the memory after the upload/update */
+ __u32 custom_len;
+ __s16 *custom_data;
};
-/* FF_RUMBLE */
-/* Some rumble pads have two motors of different weight.
- strong_magnitude represents the magnitude of the vibration generated
- by the heavy motor.
-*/
+/**
+ * struct ff_rumble_effect - defines parameters of a periodic effect
+ * @strong_magnitude: magnitude of the heavy motor
+ * @weak_magnitude: magnitude of the light one
+ *
+ * Some rumble pads have two motors of different weight. Strong_magnitude
+ * represents the magnitude of the vibration generated by the heavy one.
+ */
struct ff_rumble_effect {
- __u16 strong_magnitude; /* Magnitude of the heavy motor */
- __u16 weak_magnitude; /* Magnitude of the light one */
+ __u16 strong_magnitude;
+ __u16 weak_magnitude;
};
-/*
- * Structure sent through ioctl from the application to the driver
+/**
+ * struct ff_effect - defines force feedback effect
+ * @type: type of the effect (FF_CONSTANT, FF_PERIODIC, FF_RAMP, FF_SPRING,
+ * FF_FRICTION, FF_DAMPER, FF_RUMBLE, FF_INERTIA, or FF_CUSTOM)
+ * @id: an unique id assigned to an effect
+ * @direction: direction of the effect
+ * @trigger: trigger conditions (struct ff_trigger)
+ * @replay: scheduling of the effect (struct ff_replay)
+ * @u: effect-specific structure (one of ff_constant_effect, ff_ramp_effect,
+ * ff_periodic_effect, ff_condition_effect, ff_rumble_effect) further
+ * defining effect parameters
+ *
+ * This structure is sent through ioctl from the application to the driver.
+ * To create a new effect aplication should set its @id to -1; the kernel
+ * will return assigned @id which can later be used to update or delete
+ * this effect.
+ *
+ * Direction of the effect is encoded as follows:
+ * 0 deg -> 0x0000 (down)
+ * 90 deg -> 0x4000 (left)
+ * 180 deg -> 0x8000 (up)
+ * 270 deg -> 0xC000 (right)
*/
struct ff_effect {
__u16 type;
-/* Following field denotes the unique id assigned to an effect.
- * If user sets if to -1, a new effect is created, and its id is returned in the same field
- * Else, the user sets it to the effect id it wants to update.
- */
__s16 id;
-
- __u16 direction; /* Direction. 0 deg -> 0x0000 (down)
- 90 deg -> 0x4000 (left)
- 180 deg -> 0x8000 (up)
- 270 deg -> 0xC000 (right)
- */
-
+ __u16 direction;
struct ff_trigger trigger;
struct ff_replay replay;
@@ -784,6 +857,9 @@ struct ff_effect {
#define FF_INERTIA 0x56
#define FF_RAMP 0x57
+#define FF_EFFECT_MIN FF_RUMBLE
+#define FF_EFFECT_MAX FF_RAMP
+
/*
* Force feedback periodic effect types
*/
@@ -795,6 +871,9 @@ struct ff_effect {
#define FF_SAW_DOWN 0x5c
#define FF_CUSTOM 0x5d
+#define FF_WAVEFORM_MIN FF_SQUARE
+#define FF_WAVEFORM_MAX FF_CUSTOM
+
/*
* Set ff device properties
*/
@@ -864,12 +943,13 @@ struct input_dev {
unsigned long sndbit[NBITS(SND_MAX)];
unsigned long ffbit[NBITS(FF_MAX)];
unsigned long swbit[NBITS(SW_MAX)];
- int ff_effects_max;
unsigned int keycodemax;
unsigned int keycodesize;
void *keycode;
+ struct ff_device *ff;
+
unsigned int repeat_key;
struct timer_list timer;
@@ -895,8 +975,6 @@ struct input_dev {
void (*close)(struct input_dev *dev);
int (*flush)(struct input_dev *dev, struct file *file);
int (*event)(struct input_dev *dev, unsigned int type, unsigned int code, int value);
- int (*upload_effect)(struct input_dev *dev, struct ff_effect *effect);
- int (*erase_effect)(struct input_dev *dev, int effect_id);
struct input_handle *grab;
@@ -904,9 +982,6 @@ struct input_dev {
unsigned int users;
struct class_device cdev;
- struct device *dev; /* will be removed soon */
-
- int dynalloc; /* temporarily */
struct list_head h_list;
struct list_head node;
@@ -985,16 +1060,16 @@ struct input_handler {
void *private;
void (*event)(struct input_handle *handle, unsigned int type, unsigned int code, int value);
- struct input_handle* (*connect)(struct input_handler *handler, struct input_dev *dev, struct input_device_id *id);
+ struct input_handle* (*connect)(struct input_handler *handler, struct input_dev *dev, const struct input_device_id *id);
void (*disconnect)(struct input_handle *handle);
void (*start)(struct input_handle *handle);
const struct file_operations *fops;
int minor;
- char *name;
+ const char *name;
- struct input_device_id *id_table;
- struct input_device_id *blacklist;
+ const struct input_device_id *id_table;
+ const struct input_device_id *blacklist;
struct list_head h_list;
struct list_head node;
@@ -1005,7 +1080,7 @@ struct input_handle {
void *private;
int open;
- char *name;
+ const char *name;
struct input_dev *dev;
struct input_handler *handler;
@@ -1019,12 +1094,6 @@ struct input_handle {
#define to_handle(n) container_of(n,struct input_handle,d_node)
#define to_handle_h(n) container_of(n,struct input_handle,h_node)
-static inline void init_input_dev(struct input_dev *dev)
-{
- INIT_LIST_HEAD(&dev->h_list);
- INIT_LIST_HEAD(&dev->node);
-}
-
struct input_dev *input_allocate_device(void);
void input_free_device(struct input_dev *dev);
@@ -1041,7 +1110,7 @@ static inline void input_put_device(struct input_dev *dev)
int input_register_device(struct input_dev *);
void input_unregister_device(struct input_dev *);
-void input_register_handler(struct input_handler *);
+int input_register_handler(struct input_handler *);
void input_unregister_handler(struct input_handler *);
int input_grab_device(struct input_handle *);
@@ -1070,11 +1139,6 @@ static inline void input_report_abs(struct input_dev *dev, unsigned int code, in
input_event(dev, EV_ABS, code, value);
}
-static inline void input_report_ff(struct input_dev *dev, unsigned int code, int value)
-{
- input_event(dev, EV_FF, code, value);
-}
-
static inline void input_report_ff_status(struct input_dev *dev, unsigned int code, int value)
{
input_event(dev, EV_FF_STATUS, code, value);
@@ -1108,5 +1172,61 @@ static inline void input_set_abs_params(struct input_dev *dev, int axis, int min
extern struct class input_class;
+/**
+ * struct ff_device - force-feedback part of an input device
+ * @upload: Called to upload an new effect into device
+ * @erase: Called to erase an effect from device
+ * @playback: Called to request device to start playing specified effect
+ * @set_gain: Called to set specified gain
+ * @set_autocenter: Called to auto-center device
+ * @destroy: called by input core when parent input device is being
+ * destroyed
+ * @private: driver-specific data, will be freed automatically
+ * @ffbit: bitmap of force feedback capabilities truly supported by
+ * device (not emulated like ones in input_dev->ffbit)
+ * @mutex: mutex for serializing access to the device
+ * @max_effects: maximum number of effects supported by device
+ * @effects: pointer to an array of effects currently loaded into device
+ * @effect_owners: array of effect owners; when file handle owning
+ * an effect gets closed the effcet is automatically erased
+ *
+ * Every force-feedback device must implement upload() and playback()
+ * methods; erase() is optional. set_gain() and set_autocenter() need
+ * only be implemented if driver sets up FF_GAIN and FF_AUTOCENTER
+ * bits.
+ */
+struct ff_device {
+ int (*upload)(struct input_dev *dev, struct ff_effect *effect,
+ struct ff_effect *old);
+ int (*erase)(struct input_dev *dev, int effect_id);
+
+ int (*playback)(struct input_dev *dev, int effect_id, int value);
+ void (*set_gain)(struct input_dev *dev, u16 gain);
+ void (*set_autocenter)(struct input_dev *dev, u16 magnitude);
+
+ void (*destroy)(struct ff_device *);
+
+ void *private;
+
+ unsigned long ffbit[NBITS(FF_MAX)];
+
+ struct mutex mutex;
+
+ int max_effects;
+ struct ff_effect *effects;
+ struct file *effect_owners[];
+};
+
+int input_ff_create(struct input_dev *dev, int max_effects);
+void input_ff_destroy(struct input_dev *dev);
+
+int input_ff_event(struct input_dev *dev, unsigned int type, unsigned int code, int value);
+
+int input_ff_upload(struct input_dev *dev, struct ff_effect *effect, struct file *file);
+int input_ff_erase(struct input_dev *dev, int effect_id, struct file *file);
+
+int input_ff_create_memless(struct input_dev *dev, void *data,
+ int (*play_effect)(struct input_dev *, void *, struct ff_effect *));
+
#endif
#endif
diff --git a/include/linux/interrupt.h b/include/linux/interrupt.h
index d5afee95fd43..1f97e3d92639 100644
--- a/include/linux/interrupt.h
+++ b/include/linux/interrupt.h
@@ -123,6 +123,14 @@ static inline void disable_irq_nosync_lockdep(unsigned int irq)
#endif
}
+static inline void disable_irq_nosync_lockdep_irqsave(unsigned int irq, unsigned long *flags)
+{
+ disable_irq_nosync(irq);
+#ifdef CONFIG_LOCKDEP
+ local_irq_save(*flags);
+#endif
+}
+
static inline void disable_irq_lockdep(unsigned int irq)
{
disable_irq(irq);
@@ -139,6 +147,14 @@ static inline void enable_irq_lockdep(unsigned int irq)
enable_irq(irq);
}
+static inline void enable_irq_lockdep_irqrestore(unsigned int irq, unsigned long *flags)
+{
+#ifdef CONFIG_LOCKDEP
+ local_irq_restore(*flags);
+#endif
+ enable_irq(irq);
+}
+
/* IRQ wakeup (PM) control: */
extern int set_irq_wake(unsigned int irq, unsigned int on);
diff --git a/include/linux/io.h b/include/linux/io.h
index 420e2fdf26f6..aa3f5af670b5 100644
--- a/include/linux/io.h
+++ b/include/linux/io.h
@@ -19,8 +19,12 @@
#define _LINUX_IO_H
#include <asm/io.h>
+#include <asm/page.h>
void __iowrite32_copy(void __iomem *to, const void *from, size_t count);
void __iowrite64_copy(void __iomem *to, const void *from, size_t count);
+int ioremap_page_range(unsigned long addr, unsigned long end,
+ unsigned long phys_addr, pgprot_t prot);
+
#endif /* _LINUX_IO_H */
diff --git a/include/linux/ip.h b/include/linux/ip.h
index 2f4600146f83..6b25d36fc54c 100644
--- a/include/linux/ip.h
+++ b/include/linux/ip.h
@@ -96,7 +96,7 @@ struct iphdr {
__be16 frag_off;
__u8 ttl;
__u8 protocol;
- __u16 check;
+ __be16 check;
__be32 saddr;
__be32 daddr;
/*The options start here. */
@@ -105,22 +105,22 @@ struct iphdr {
struct ip_auth_hdr {
__u8 nexthdr;
__u8 hdrlen; /* This one is measured in 32 bit units! */
- __u16 reserved;
- __u32 spi;
- __u32 seq_no; /* Sequence number */
+ __be16 reserved;
+ __be32 spi;
+ __be32 seq_no; /* Sequence number */
__u8 auth_data[0]; /* Variable len but >=4. Mind the 64 bit alignment! */
};
struct ip_esp_hdr {
- __u32 spi;
- __u32 seq_no; /* Sequence number */
+ __be32 spi;
+ __be32 seq_no; /* Sequence number */
__u8 enc_data[0]; /* Variable len but >=8. Mind the 64 bit alignment! */
};
struct ip_comp_hdr {
__u8 nexthdr;
__u8 flags;
- __u16 cpi;
+ __be16 cpi;
};
#endif /* _LINUX_IP_H */
diff --git a/include/linux/ipc.h b/include/linux/ipc.h
index b291189737e7..d9e2b3f36c35 100644
--- a/include/linux/ipc.h
+++ b/include/linux/ipc.h
@@ -2,6 +2,7 @@
#define _LINUX_IPC_H
#include <linux/types.h>
+#include <linux/kref.h>
#define IPC_PRIVATE ((__kernel_key_t) 0)
@@ -68,6 +69,59 @@ struct kern_ipc_perm
void *security;
};
+struct ipc_ids;
+struct ipc_namespace {
+ struct kref kref;
+ struct ipc_ids *ids[3];
+
+ int sem_ctls[4];
+ int used_sems;
+
+ int msg_ctlmax;
+ int msg_ctlmnb;
+ int msg_ctlmni;
+
+ size_t shm_ctlmax;
+ size_t shm_ctlall;
+ int shm_ctlmni;
+ int shm_tot;
+};
+
+extern struct ipc_namespace init_ipc_ns;
+
+#ifdef CONFIG_SYSVIPC
+#define INIT_IPC_NS(ns) .ns = &init_ipc_ns,
+#else
+#define INIT_IPC_NS(ns)
+#endif
+
+#ifdef CONFIG_IPC_NS
+extern void free_ipc_ns(struct kref *kref);
+extern int copy_ipcs(unsigned long flags, struct task_struct *tsk);
+extern int unshare_ipcs(unsigned long flags, struct ipc_namespace **ns);
+#else
+static inline int copy_ipcs(unsigned long flags, struct task_struct *tsk)
+{
+ return 0;
+}
+#endif
+
+static inline struct ipc_namespace *get_ipc_ns(struct ipc_namespace *ns)
+{
+#ifdef CONFIG_IPC_NS
+ if (ns)
+ kref_get(&ns->kref);
+#endif
+ return ns;
+}
+
+static inline void put_ipc_ns(struct ipc_namespace *ns)
+{
+#ifdef CONFIG_IPC_NS
+ kref_put(&ns->kref, free_ipc_ns);
+#endif
+}
+
#endif /* __KERNEL__ */
#endif /* _LINUX_IPC_H */
diff --git a/include/linux/ipmi.h b/include/linux/ipmi.h
index d09fbeabf1dc..796ca009fd46 100644
--- a/include/linux/ipmi.h
+++ b/include/linux/ipmi.h
@@ -148,6 +148,13 @@ struct ipmi_lan_addr
#define IPMI_BMC_CHANNEL 0xf
#define IPMI_NUM_CHANNELS 0x10
+/*
+ * Used to signify an "all channel" bitmask. This is more than the
+ * actual number of channels because this is used in userland and
+ * will cover us if the number of channels is extended.
+ */
+#define IPMI_CHAN_ALL (~0)
+
/*
* A raw IPMI message without any addressing. This covers both
@@ -350,18 +357,21 @@ int ipmi_request_supply_msgs(ipmi_user_t user,
/*
* When commands come in to the SMS, the user can register to receive
- * them. Only one user can be listening on a specific netfn/cmd pair
+ * them. Only one user can be listening on a specific netfn/cmd/chan tuple
* at a time, you will get an EBUSY error if the command is already
* registered. If a command is received that does not have a user
* registered, the driver will automatically return the proper
- * error.
+ * error. Channels are specified as a bitfield, use IPMI_CHAN_ALL to
+ * mean all channels.
*/
int ipmi_register_for_cmd(ipmi_user_t user,
unsigned char netfn,
- unsigned char cmd);
+ unsigned char cmd,
+ unsigned int chans);
int ipmi_unregister_for_cmd(ipmi_user_t user,
unsigned char netfn,
- unsigned char cmd);
+ unsigned char cmd,
+ unsigned int chans);
/*
* Allow run-to-completion mode to be set for the interface of
@@ -571,6 +581,36 @@ struct ipmi_cmdspec
#define IPMICTL_UNREGISTER_FOR_CMD _IOR(IPMI_IOC_MAGIC, 15, \
struct ipmi_cmdspec)
+/*
+ * Register to get commands from other entities on specific channels.
+ * This way, you can only listen on specific channels, or have messages
+ * from some channels go to one place and other channels to someplace
+ * else. The chans field is a bitmask, (1 << channel) for each channel.
+ * It may be IPMI_CHAN_ALL for all channels.
+ */
+struct ipmi_cmdspec_chans
+{
+ unsigned int netfn;
+ unsigned int cmd;
+ unsigned int chans;
+};
+
+/*
+ * Register to receive a specific command on specific channels. error values:
+ * - EFAULT - an address supplied was invalid.
+ * - EBUSY - One of the netfn/cmd/chans supplied was already in use.
+ * - ENOMEM - could not allocate memory for the entry.
+ */
+#define IPMICTL_REGISTER_FOR_CMD_CHANS _IOR(IPMI_IOC_MAGIC, 28, \
+ struct ipmi_cmdspec_chans)
+/*
+ * Unregister some netfn/cmd/chans. error values:
+ * - EFAULT - an address supplied was invalid.
+ * - ENOENT - None of the netfn/cmd/chans were found registered for this user.
+ */
+#define IPMICTL_UNREGISTER_FOR_CMD_CHANS _IOR(IPMI_IOC_MAGIC, 29, \
+ struct ipmi_cmdspec_chans)
+
/*
* Set whether this interface receives events. Note that the first
* user registered for events will get all pending events for the
diff --git a/include/linux/ipv6.h b/include/linux/ipv6.h
index caca57df0d7d..4f435c59de06 100644
--- a/include/linux/ipv6.h
+++ b/include/linux/ipv6.h
@@ -99,22 +99,22 @@ struct ipv6_destopt_hao {
struct ipv6_auth_hdr {
__u8 nexthdr;
__u8 hdrlen; /* This one is measured in 32 bit units! */
- __u16 reserved;
- __u32 spi;
- __u32 seq_no; /* Sequence number */
+ __be16 reserved;
+ __be32 spi;
+ __be32 seq_no; /* Sequence number */
__u8 auth_data[0]; /* Length variable but >=4. Mind the 64 bit alignment! */
};
struct ipv6_esp_hdr {
- __u32 spi;
- __u32 seq_no; /* Sequence number */
+ __be32 spi;
+ __be32 seq_no; /* Sequence number */
__u8 enc_data[0]; /* Length variable but >=8. Mind the 64 bit alignment! */
};
struct ipv6_comp_hdr {
__u8 nexthdr;
__u8 flags;
- __u16 cpi;
+ __be16 cpi;
};
/*
@@ -136,7 +136,7 @@ struct ipv6hdr {
#endif
__u8 flow_lbl[3];
- __u16 payload_len;
+ __be16 payload_len;
__u8 nexthdr;
__u8 hop_limit;
@@ -461,7 +461,7 @@ static inline struct raw6_sock *raw6_sk(const struct sock *sk)
#define INET6_MATCH(__sk, __hash, __saddr, __daddr, __ports, __dif)\
(((__sk)->sk_hash == (__hash)) && \
- ((*((__u32 *)&(inet_sk(__sk)->dport))) == (__ports)) && \
+ ((*((__portpair *)&(inet_sk(__sk)->dport))) == (__ports)) && \
((__sk)->sk_family == AF_INET6) && \
ipv6_addr_equal(&inet6_sk(__sk)->daddr, (__saddr)) && \
ipv6_addr_equal(&inet6_sk(__sk)->rcv_saddr, (__daddr)) && \
diff --git a/include/linux/jbd.h b/include/linux/jbd.h
index a6d9daa38c6d..fe89444b1c6f 100644
--- a/include/linux/jbd.h
+++ b/include/linux/jbd.h
@@ -977,7 +977,6 @@ extern void journal_write_revoke_records(journal_t *, transaction_t *);
extern int journal_set_revoke(journal_t *, unsigned long, tid_t);
extern int journal_test_revoke(journal_t *, unsigned long, tid_t);
extern void journal_clear_revoke(journal_t *);
-extern void journal_brelse_array(struct buffer_head *b[], int n);
extern void journal_switch_revoke_table(journal_t *journal);
/*
diff --git a/include/linux/kallsyms.h b/include/linux/kallsyms.h
index 849043ce4ed6..1cebcbc28b47 100644
--- a/include/linux/kallsyms.h
+++ b/include/linux/kallsyms.h
@@ -12,6 +12,10 @@
/* Lookup the address for a symbol. Returns 0 if not found. */
unsigned long kallsyms_lookup_name(const char *name);
+extern int kallsyms_lookup_size_offset(unsigned long addr,
+ unsigned long *symbolsize,
+ unsigned long *offset);
+
/* Lookup an address. modname is set to NULL if it's in the kernel. */
const char *kallsyms_lookup(unsigned long addr,
unsigned long *symbolsize,
@@ -28,6 +32,13 @@ static inline unsigned long kallsyms_lookup_name(const char *name)
return 0;
}
+static inline int kallsyms_lookup_size_offset(unsigned long addr,
+ unsigned long *symbolsize,
+ unsigned long *offset)
+{
+ return 0;
+}
+
static inline const char *kallsyms_lookup(unsigned long addr,
unsigned long *symbolsize,
unsigned long *offset,
diff --git a/include/linux/kernel.h b/include/linux/kernel.h
index 4d00988dad03..80f39cab470a 100644
--- a/include/linux/kernel.h
+++ b/include/linux/kernel.h
@@ -216,8 +216,10 @@ extern void dump_stack(void);
#define pr_debug(fmt,arg...) \
printk(KERN_DEBUG fmt,##arg)
#else
-#define pr_debug(fmt,arg...) \
- do { } while (0)
+static inline int __attribute__ ((format (printf, 1, 2))) pr_debug(const char * fmt, ...)
+{
+ return 0;
+}
#endif
#define pr_info(fmt,arg...) \
diff --git a/include/linux/kmod.h b/include/linux/kmod.h
index 0db22a1ab474..10f505c8431d 100644
--- a/include/linux/kmod.h
+++ b/include/linux/kmod.h
@@ -47,4 +47,8 @@ call_usermodehelper(char *path, char **argv, char **envp, int wait)
extern void usermodehelper_init(void);
+struct file;
+extern int call_usermodehelper_pipe(char *path, char *argv[], char *envp[],
+ struct file **filp);
+
#endif /* __LINUX_KMOD_H__ */
diff --git a/include/linux/kprobes.h b/include/linux/kprobes.h
index 8bf6702da2a0..ac4c0559f751 100644
--- a/include/linux/kprobes.h
+++ b/include/linux/kprobes.h
@@ -77,6 +77,12 @@ struct kprobe {
/* location of the probe point */
kprobe_opcode_t *addr;
+ /* Allow user to indicate symbol name of the probe point */
+ char *symbol_name;
+
+ /* Offset into the symbol */
+ unsigned int offset;
+
/* Called before addr is executed. */
kprobe_pre_handler_t pre_handler;
@@ -196,7 +202,7 @@ void unregister_kretprobe(struct kretprobe *rp);
struct kretprobe_instance *get_free_rp_inst(struct kretprobe *rp);
void add_rp_inst(struct kretprobe_instance *ri);
void kprobe_flush_task(struct task_struct *tk);
-void recycle_rp_inst(struct kretprobe_instance *ri);
+void recycle_rp_inst(struct kretprobe_instance *ri, struct hlist_head *head);
#else /* CONFIG_KPROBES */
#define __kprobes /**/
diff --git a/include/linux/latency.h b/include/linux/latency.h
new file mode 100644
index 000000000000..c08b52bb55b0
--- /dev/null
+++ b/include/linux/latency.h
@@ -0,0 +1,25 @@
+/*
+ * latency.h: Explicit system-wide latency-expectation infrastructure
+ *
+ * (C) Copyright 2006 Intel Corporation
+ * Author: Arjan van de Ven <arjan@linux.intel.com>
+ *
+ */
+
+#ifndef _INCLUDE_GUARD_LATENCY_H_
+#define _INCLUDE_GUARD_LATENCY_H_
+
+#include <linux/notifier.h>
+
+void set_acceptable_latency(char *identifier, int usecs);
+void modify_acceptable_latency(char *identifier, int usecs);
+void remove_acceptable_latency(char *identifier);
+void synchronize_acceptable_latency(void);
+int system_latency_constraint(void);
+
+int register_latency_notifier(struct notifier_block * nb);
+int unregister_latency_notifier(struct notifier_block * nb);
+
+#define INFINITE_LATENCY 1000000
+
+#endif
diff --git a/include/linux/leds.h b/include/linux/leds.h
index dc23c7c639f3..88afceffb7cb 100644
--- a/include/linux/leds.h
+++ b/include/linux/leds.h
@@ -12,6 +12,9 @@
#ifndef __LINUX_LEDS_H_INCLUDED
#define __LINUX_LEDS_H_INCLUDED
+#include <linux/list.h>
+#include <linux/spinlock.h>
+
struct device;
struct class_device;
/*
diff --git a/include/linux/libps2.h b/include/linux/libps2.h
index 08a450a9dbf7..f6f301e2b0f5 100644
--- a/include/linux/libps2.h
+++ b/include/linux/libps2.h
@@ -47,5 +47,6 @@ int ps2_schedule_command(struct ps2dev *ps2dev, unsigned char *param, int comman
int ps2_handle_ack(struct ps2dev *ps2dev, unsigned char data);
int ps2_handle_response(struct ps2dev *ps2dev, unsigned char data);
void ps2_cmd_aborted(struct ps2dev *ps2dev);
+int ps2_is_keyboard_id(char id);
#endif /* _LIBPS2_H */
diff --git a/include/linux/list.h b/include/linux/list.h
index 65a5b5ceda49..a9c90287c0ff 100644
--- a/include/linux/list.h
+++ b/include/linux/list.h
@@ -39,6 +39,7 @@ static inline void INIT_LIST_HEAD(struct list_head *list)
* This is only for internal list manipulation where we know
* the prev/next entries already!
*/
+#ifndef CONFIG_DEBUG_LIST
static inline void __list_add(struct list_head *new,
struct list_head *prev,
struct list_head *next)
@@ -48,6 +49,11 @@ static inline void __list_add(struct list_head *new,
new->prev = prev;
prev->next = new;
}
+#else
+extern void __list_add(struct list_head *new,
+ struct list_head *prev,
+ struct list_head *next);
+#endif
/**
* list_add - add a new entry
@@ -57,10 +63,15 @@ static inline void __list_add(struct list_head *new,
* Insert a new entry after the specified head.
* This is good for implementing stacks.
*/
+#ifndef CONFIG_DEBUG_LIST
static inline void list_add(struct list_head *new, struct list_head *head)
{
__list_add(new, head, head->next);
}
+#else
+extern void list_add(struct list_head *new, struct list_head *head);
+#endif
+
/**
* list_add_tail - add a new entry
@@ -153,12 +164,16 @@ static inline void __list_del(struct list_head * prev, struct list_head * next)
* Note: list_empty on entry does not return true after this, the entry is
* in an undefined state.
*/
+#ifndef CONFIG_DEBUG_LIST
static inline void list_del(struct list_head *entry)
{
__list_del(entry->prev, entry->next);
entry->next = LIST_POISON1;
entry->prev = LIST_POISON2;
}
+#else
+extern void list_del(struct list_head *entry);
+#endif
/**
* list_del_rcu - deletes entry from list without re-initialization
diff --git a/include/linux/lockd/bind.h b/include/linux/lockd/bind.h
index b054debef2e0..81e3a185f951 100644
--- a/include/linux/lockd/bind.h
+++ b/include/linux/lockd/bind.h
@@ -30,7 +30,7 @@ extern struct nlmsvc_binding * nlmsvc_ops;
* Functions exported by the lockd module
*/
extern int nlmclnt_proc(struct inode *, int, struct file_lock *);
-extern int lockd_up(void);
+extern int lockd_up(int proto);
extern void lockd_down(void);
#endif /* LINUX_LOCKD_BIND_H */
diff --git a/include/linux/lockd/lockd.h b/include/linux/lockd/lockd.h
index 0d92c468d55a..47b7dbd647a6 100644
--- a/include/linux/lockd/lockd.h
+++ b/include/linux/lockd/lockd.h
@@ -80,7 +80,7 @@ struct nlm_wait;
/*
* Memory chunk for NLM client RPC request.
*/
-#define NLMCLNT_OHSIZE (sizeof(system_utsname.nodename)+10)
+#define NLMCLNT_OHSIZE (sizeof(utsname()->nodename)+10)
struct nlm_rqst {
unsigned int a_flags; /* initial RPC task flags */
struct nlm_host * a_host; /* host handle */
diff --git a/include/linux/lockdep.h b/include/linux/lockdep.h
index c040a8c969aa..1314ca0f29be 100644
--- a/include/linux/lockdep.h
+++ b/include/linux/lockdep.h
@@ -8,13 +8,13 @@
#ifndef __LINUX_LOCKDEP_H
#define __LINUX_LOCKDEP_H
+#ifdef CONFIG_LOCKDEP
+
#include <linux/linkage.h>
#include <linux/list.h>
#include <linux/debug_locks.h>
#include <linux/stacktrace.h>
-#ifdef CONFIG_LOCKDEP
-
/*
* Lock-class usage-state bits:
*/
diff --git a/include/linux/loop.h b/include/linux/loop.h
index e76c7611d6cc..191a595055f0 100644
--- a/include/linux/loop.h
+++ b/include/linux/loop.h
@@ -59,10 +59,9 @@ struct loop_device {
struct bio *lo_bio;
struct bio *lo_biotail;
int lo_state;
- struct completion lo_done;
- struct completion lo_bh_done;
struct mutex lo_ctl_mutex;
- int lo_pending;
+ struct task_struct *lo_thread;
+ wait_queue_head_t lo_event;
request_queue_t *lo_queue;
};
diff --git a/include/linux/memory.h b/include/linux/memory.h
index 8f04143ca363..654ef5544878 100644
--- a/include/linux/memory.h
+++ b/include/linux/memory.h
@@ -57,7 +57,7 @@ struct memory_block {
struct notifier_block;
struct mem_section;
-#ifndef CONFIG_MEMORY_HOTPLUG
+#ifndef CONFIG_MEMORY_HOTPLUG_SPARSE
static inline int memory_dev_init(void)
{
return 0;
@@ -78,7 +78,7 @@ extern int remove_memory_block(unsigned long, struct mem_section *, int);
#define CONFIG_MEM_BLOCK_SIZE (PAGES_PER_SECTION<<PAGE_SHIFT)
-#endif /* CONFIG_MEMORY_HOTPLUG */
+#endif /* CONFIG_MEMORY_HOTPLUG_SPARSE */
#define hotplug_memory_notifier(fn, pri) { \
static struct notifier_block fn##_mem_nb = \
diff --git a/include/linux/memory_hotplug.h b/include/linux/memory_hotplug.h
index 218501cfaeb9..7b54666cea8e 100644
--- a/include/linux/memory_hotplug.h
+++ b/include/linux/memory_hotplug.h
@@ -172,5 +172,7 @@ static inline int __remove_pages(struct zone *zone, unsigned long start_pfn,
extern int add_memory(int nid, u64 start, u64 size);
extern int arch_add_memory(int nid, u64 start, u64 size);
extern int remove_memory(u64 start, u64 size);
+extern int sparse_add_one_section(struct zone *zone, unsigned long start_pfn,
+ int nr_pages);
#endif /* __LINUX_MEMORY_HOTPLUG_H */
diff --git a/include/linux/mm.h b/include/linux/mm.h
index 7b703b6d4358..b7966ab8cb6a 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -743,7 +743,9 @@ int get_user_pages(struct task_struct *tsk, struct mm_struct *mm, unsigned long
int len, int write, int force, struct page **pages, struct vm_area_struct **vmas);
void print_bad_pte(struct vm_area_struct *, pte_t, unsigned long);
-int __set_page_dirty_buffers(struct page *page);
+extern int try_to_release_page(struct page * page, gfp_t gfp_mask);
+extern void do_invalidatepage(struct page *page, unsigned long offset);
+
int __set_page_dirty_nobuffers(struct page *page);
int redirty_page_for_writepage(struct writeback_control *wbc,
struct page *page);
@@ -944,6 +946,8 @@ extern void mem_init(void);
extern void show_mem(void);
extern void si_meminfo(struct sysinfo * val);
extern void si_meminfo_node(struct sysinfo *val, int nid);
+extern void zonetable_add(struct zone *zone, int nid, enum zone_type zid,
+ unsigned long pfn, unsigned long size);
#ifdef CONFIG_NUMA
extern void setup_per_cpu_pageset(void);
diff --git a/include/linux/module.h b/include/linux/module.h
index d4486cc2e7fe..4b2d8091a410 100644
--- a/include/linux/module.h
+++ b/include/linux/module.h
@@ -232,17 +232,17 @@ enum module_state
};
/* Similar stuff for section attributes. */
-#define MODULE_SECT_NAME_LEN 32
struct module_sect_attr
{
struct module_attribute mattr;
- char name[MODULE_SECT_NAME_LEN];
+ char *name;
unsigned long address;
};
struct module_sect_attrs
{
struct attribute_group grp;
+ int nsections;
struct module_sect_attr attrs[0];
};
@@ -320,6 +320,8 @@ struct module
/* Am I GPL-compatible */
int license_gplok;
+ unsigned int taints; /* same bits as kernel:tainted */
+
#ifdef CONFIG_MODULE_UNLOAD
/* Reference counts */
struct module_ref ref[NR_CPUS];
diff --git a/include/linux/mpage.h b/include/linux/mpage.h
index 3ca880463c47..cc5fb75af78a 100644
--- a/include/linux/mpage.h
+++ b/include/linux/mpage.h
@@ -9,6 +9,7 @@
* (And no, it doesn't do the #ifdef __MPAGE_H thing, and it doesn't do
* nested includes. Get it right in the .c file).
*/
+#ifdef CONFIG_BLOCK
struct writeback_control;
typedef int (writepage_t)(struct page *page, struct writeback_control *wbc);
@@ -21,8 +22,4 @@ int mpage_writepages(struct address_space *mapping,
int mpage_writepage(struct page *page, get_block_t *get_block,
struct writeback_control *wbc);
-static inline int
-generic_writepages(struct address_space *mapping, struct writeback_control *wbc)
-{
- return mpage_writepages(mapping, wbc, NULL);
-}
+#endif
diff --git a/include/linux/mroute.h b/include/linux/mroute.h
index e05d54a90743..7da2cee8e132 100644
--- a/include/linux/mroute.h
+++ b/include/linux/mroute.h
@@ -142,7 +142,7 @@ struct vif_device
unsigned long rate_limit; /* Traffic shaping (NI) */
unsigned char threshold; /* TTL threshold */
unsigned short flags; /* Control flags */
- __u32 local,remote; /* Addresses(remote for tunnels)*/
+ __be32 local,remote; /* Addresses(remote for tunnels)*/
int link; /* Physical interface index */
};
@@ -151,8 +151,8 @@ struct vif_device
struct mfc_cache
{
struct mfc_cache *next; /* Next entry on cache line */
- __u32 mfc_mcastgrp; /* Group the entry belongs to */
- __u32 mfc_origin; /* Source of packet */
+ __be32 mfc_mcastgrp; /* Group the entry belongs to */
+ __be32 mfc_origin; /* Source of packet */
vifi_t mfc_parent; /* Source interface */
int mfc_flags; /* Flags on line */
@@ -179,9 +179,9 @@ struct mfc_cache
#define MFC_LINES 64
#ifdef __BIG_ENDIAN
-#define MFC_HASH(a,b) ((((a)>>24)^((b)>>26))&(MFC_LINES-1))
+#define MFC_HASH(a,b) (((((__force u32)(__be32)a)>>24)^(((__force u32)(__be32)b)>>26))&(MFC_LINES-1))
#else
-#define MFC_HASH(a,b) (((a)^((b)>>2))&(MFC_LINES-1))
+#define MFC_HASH(a,b) ((((__force u32)(__be32)a)^(((__force u32)(__be32)b)>>2))&(MFC_LINES-1))
#endif
#endif
@@ -213,8 +213,8 @@ struct pimreghdr
{
__u8 type;
__u8 reserved;
- __u16 csum;
- __u32 flags;
+ __be16 csum;
+ __be32 flags;
};
extern int pim_rcv_v1(struct sk_buff *);
diff --git a/include/linux/msdos_fs.h b/include/linux/msdos_fs.h
index bae62d62dc3e..ce6c85815cbd 100644
--- a/include/linux/msdos_fs.h
+++ b/include/linux/msdos_fs.h
@@ -204,6 +204,7 @@ struct fat_mount_options {
unicode_xlate:1, /* create escape sequences for unhandled Unicode */
numtail:1, /* Does first alias have a numeric '~1' type tail? */
atari:1, /* Use Atari GEMDOS variation of MS-DOS fs */
+ flush:1, /* write things quickly */
nocase:1; /* Does this need case conversion? 0=need case conversion*/
};
@@ -412,6 +413,8 @@ extern int fat_sync_inode(struct inode *inode);
extern int fat_fill_super(struct super_block *sb, void *data, int silent,
struct inode_operations *fs_dir_inode_ops, int isvfat);
+extern int fat_flush_inodes(struct super_block *sb, struct inode *i1,
+ struct inode *i2);
/* fat/misc.c */
extern void fat_fs_panic(struct super_block *s, const char *fmt, ...);
extern void fat_clusters_flush(struct super_block *sb);
diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h
index 0b4cd2fa64aa..70420bbae82b 100644
--- a/include/linux/mtd/nand.h
+++ b/include/linux/mtd/nand.h
@@ -27,9 +27,17 @@
struct mtd_info;
/* Scan and identify a NAND device */
extern int nand_scan (struct mtd_info *mtd, int max_chips);
+/* Separate phases of nand_scan(), allowing board driver to intervene
+ * and override command or ECC setup according to flash type */
+extern int nand_scan_ident(struct mtd_info *mtd, int max_chips);
+extern int nand_scan_tail(struct mtd_info *mtd);
+
/* Free resources held by the NAND device */
extern void nand_release (struct mtd_info *mtd);
+/* Internal helper for board drivers which need to override command function */
+extern void nand_wait_ready(struct mtd_info *mtd);
+
/* The maximum number of NAND chips in an array */
#define NAND_MAX_CHIPS 8
@@ -178,7 +186,9 @@ typedef enum {
#define NAND_USE_FLASH_BBT 0x00010000
/* This option skips the bbt scan during initialization. */
#define NAND_SKIP_BBTSCAN 0x00020000
-
+/* This option is defined if the board driver allocates its own buffers
+ (e.g. because it needs them DMA-coherent */
+#define NAND_OWN_BUFFERS 0x00040000
/* Options set by nand scan */
/* Nand scan has allocated controller struct */
#define NAND_CONTROLLER_ALLOC 0x80000000
@@ -228,6 +238,8 @@ struct nand_hw_control {
* be provided if an hardware ECC is available
* @calculate: function for ecc calculation or readback from ecc hardware
* @correct: function for ecc correction, matching to ecc generator (sw/hw)
+ * @read_page_raw: function to read a raw page without ECC
+ * @write_page_raw: function to write a raw page without ECC
* @read_page: function to read a page according to the ecc generator requirements
* @write_page: function to write a page according to the ecc generator requirements
* @read_oob: function to read chip OOB data
@@ -249,6 +261,12 @@ struct nand_ecc_ctrl {
int (*correct)(struct mtd_info *mtd, uint8_t *dat,
uint8_t *read_ecc,
uint8_t *calc_ecc);
+ int (*read_page_raw)(struct mtd_info *mtd,
+ struct nand_chip *chip,
+ uint8_t *buf);
+ void (*write_page_raw)(struct mtd_info *mtd,
+ struct nand_chip *chip,
+ const uint8_t *buf);
int (*read_page)(struct mtd_info *mtd,
struct nand_chip *chip,
uint8_t *buf);
@@ -337,6 +355,7 @@ struct nand_buffers {
* @priv: [OPTIONAL] pointer to private chip date
* @errstat: [OPTIONAL] hardware specific function to perform additional error status checks
* (determine if errors are correctable)
+ * @write_page [REPLACEABLE] High-level page write function
*/
struct nand_chip {
@@ -359,6 +378,8 @@ struct nand_chip {
void (*erase_cmd)(struct mtd_info *mtd, int page);
int (*scan_bbt)(struct mtd_info *mtd);
int (*errstat)(struct mtd_info *mtd, struct nand_chip *this, int state, int status, int page);
+ int (*write_page)(struct mtd_info *mtd, struct nand_chip *chip,
+ const uint8_t *buf, int page, int cached, int raw);
int chip_delay;
unsigned int options;
@@ -380,7 +401,7 @@ struct nand_chip {
struct nand_ecclayout *ecclayout;
struct nand_ecc_ctrl ecc;
- struct nand_buffers buffers;
+ struct nand_buffers *buffers;
struct nand_hw_control hwcontrol;
struct mtd_oob_ops ops;
diff --git a/include/linux/mtd/onenand.h b/include/linux/mtd/onenand.h
index 1f4972155249..6f045b586e76 100644
--- a/include/linux/mtd/onenand.h
+++ b/include/linux/mtd/onenand.h
@@ -1,7 +1,7 @@
/*
* linux/include/linux/mtd/onenand.h
*
- * Copyright (C) 2005 Samsung Electronics
+ * Copyright (C) 2005-2006 Samsung Electronics
* Kyungmin Park <kyungmin.park@samsung.com>
*
* This program is free software; you can redistribute it and/or modify
@@ -96,6 +96,7 @@ struct onenand_chip {
void __iomem *base;
unsigned int chipsize;
unsigned int device_id;
+ unsigned int version_id;
unsigned int density_mask;
unsigned int options;
@@ -149,7 +150,8 @@ struct onenand_chip {
/*
* Options bits
*/
-#define ONENAND_CONT_LOCK (0x0001)
+#define ONENAND_HAS_CONT_LOCK (0x0001)
+#define ONENAND_HAS_UNLOCK_ALL (0x0002)
#define ONENAND_PAGEBUF_ALLOC (0x1000)
/*
diff --git a/include/linux/mtd/onenand_regs.h b/include/linux/mtd/onenand_regs.h
index 4a72818d2545..9e409fe6ded6 100644
--- a/include/linux/mtd/onenand_regs.h
+++ b/include/linux/mtd/onenand_regs.h
@@ -3,7 +3,7 @@
*
* OneNAND Register header file
*
- * Copyright (C) 2005 Samsung Electronics
+ * Copyright (C) 2005-2006 Samsung Electronics
*
* 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
@@ -72,6 +72,7 @@
#define ONENAND_DEVICE_VCC_MASK (0x3)
#define ONENAND_DEVICE_DENSITY_512Mb (0x002)
+#define ONENAND_DEVICE_DENSITY_1Gb (0x003)
/*
* Version ID Register F002h (R)
@@ -110,6 +111,7 @@
#define ONENAND_CMD_UNLOCK (0x23)
#define ONENAND_CMD_LOCK (0x2A)
#define ONENAND_CMD_LOCK_TIGHT (0x2C)
+#define ONENAND_CMD_UNLOCK_ALL (0x27)
#define ONENAND_CMD_ERASE (0x94)
#define ONENAND_CMD_RESET (0xF0)
#define ONENAND_CMD_OTP_ACCESS (0x65)
diff --git a/include/linux/namei.h b/include/linux/namei.h
index 45511a5918d3..f5f19606effb 100644
--- a/include/linux/namei.h
+++ b/include/linux/namei.h
@@ -1,6 +1,7 @@
#ifndef _LINUX_NAMEI_H
#define _LINUX_NAMEI_H
+#include <linux/dcache.h>
#include <linux/linkage.h>
struct vfsmount;
@@ -54,6 +55,7 @@ enum {LAST_NORM, LAST_ROOT, LAST_DOT, LAST_DOTDOT, LAST_BIND};
#define LOOKUP_OPEN (0x0100)
#define LOOKUP_CREATE (0x0200)
#define LOOKUP_ACCESS (0x0400)
+#define LOOKUP_CHDIR (0x0800)
extern int FASTCALL(__user_walk(const char __user *, unsigned, struct nameidata *));
extern int FASTCALL(__user_walk_fd(int dfd, const char __user *, unsigned, struct nameidata *));
diff --git a/include/linux/namespace.h b/include/linux/namespace.h
index 3abc8e3b4879..d137009f0b2b 100644
--- a/include/linux/namespace.h
+++ b/include/linux/namespace.h
@@ -4,6 +4,7 @@
#include <linux/mount.h>
#include <linux/sched.h>
+#include <linux/nsproxy.h>
struct namespace {
atomic_t count;
@@ -26,11 +27,8 @@ static inline void put_namespace(struct namespace *namespace)
static inline void exit_namespace(struct task_struct *p)
{
- struct namespace *namespace = p->namespace;
+ struct namespace *namespace = p->nsproxy->namespace;
if (namespace) {
- task_lock(p);
- p->namespace = NULL;
- task_unlock(p);
put_namespace(namespace);
}
}
diff --git a/include/linux/ncp_fs.h b/include/linux/ncp_fs.h
index 02e352be717e..0ea7f89e613c 100644
--- a/include/linux/ncp_fs.h
+++ b/include/linux/ncp_fs.h
@@ -212,6 +212,7 @@ void ncp_date_unix2dos(int unix_date, __le16 * time, __le16 * date);
/* linux/fs/ncpfs/ioctl.c */
int ncp_ioctl(struct inode *, struct file *, unsigned int, unsigned long);
+long ncp_compat_ioctl(struct file *, unsigned int, unsigned long);
/* linux/fs/ncpfs/sock.c */
int ncp_request2(struct ncp_server *server, int function,
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index 13d6d4eb8b3a..9264139bd8df 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -187,7 +187,7 @@ struct hh_cache
{
struct hh_cache *hh_next; /* Next entry */
atomic_t hh_refcnt; /* number of users */
- unsigned short hh_type; /* protocol identifier, f.e ETH_P_IP
+ __be16 hh_type; /* protocol identifier, f.e ETH_P_IP
* NOTE: For VLANs, this will be the
* encapuslated type. --BLG
*/
diff --git a/include/linux/netfilter_arp/arp_tables.h b/include/linux/netfilter_arp/arp_tables.h
index 149e87c9ab13..44e39b61d9e7 100644
--- a/include/linux/netfilter_arp/arp_tables.h
+++ b/include/linux/netfilter_arp/arp_tables.h
@@ -46,11 +46,11 @@ struct arpt_arp {
struct arpt_devaddr_info tgt_devaddr;
/* ARP operation code. */
- u_int16_t arpop, arpop_mask;
+ __be16 arpop, arpop_mask;
/* ARP hardware address and protocol address format. */
- u_int16_t arhrd, arhrd_mask;
- u_int16_t arpro, arpro_mask;
+ __be16 arhrd, arhrd_mask;
+ __be16 arpro, arpro_mask;
/* The protocol address length is only accepted if it is 4
* so there is no use in offering a way to do filtering on it.
diff --git a/include/linux/netfilter_ipv4/ip_conntrack.h b/include/linux/netfilter_ipv4/ip_conntrack.h
index 51dbec1892c8..64e868034c4a 100644
--- a/include/linux/netfilter_ipv4/ip_conntrack.h
+++ b/include/linux/netfilter_ipv4/ip_conntrack.h
@@ -157,7 +157,7 @@ struct ip_conntrack_expect
unsigned int flags;
#ifdef CONFIG_IP_NF_NAT_NEEDED
- u_int32_t saved_ip;
+ __be32 saved_ip;
/* This is the original per-proto part, used to map the
* expected connection the way the recipient expects. */
union ip_conntrack_manip_proto saved_proto;
diff --git a/include/linux/netfilter_ipv4/ip_conntrack_h323.h b/include/linux/netfilter_ipv4/ip_conntrack_h323.h
index 3cbff7379002..943cc6a4871d 100644
--- a/include/linux/netfilter_ipv4/ip_conntrack_h323.h
+++ b/include/linux/netfilter_ipv4/ip_conntrack_h323.h
@@ -30,7 +30,7 @@ struct ip_ct_h323_master {
struct ip_conntrack_expect;
extern int get_h225_addr(unsigned char *data, TransportAddress * addr,
- u_int32_t * ip, u_int16_t * port);
+ __be32 * ip, u_int16_t * port);
extern void ip_conntrack_h245_expect(struct ip_conntrack *new,
struct ip_conntrack_expect *this);
extern void ip_conntrack_q931_expect(struct ip_conntrack *new,
@@ -38,11 +38,11 @@ extern void ip_conntrack_q931_expect(struct ip_conntrack *new,
extern int (*set_h245_addr_hook) (struct sk_buff ** pskb,
unsigned char **data, int dataoff,
H245_TransportAddress * addr,
- u_int32_t ip, u_int16_t port);
+ __be32 ip, u_int16_t port);
extern int (*set_h225_addr_hook) (struct sk_buff ** pskb,
unsigned char **data, int dataoff,
TransportAddress * addr,
- u_int32_t ip, u_int16_t port);
+ __be32 ip, u_int16_t port);
extern int (*set_sig_addr_hook) (struct sk_buff ** pskb,
struct ip_conntrack * ct,
enum ip_conntrack_info ctinfo,
diff --git a/include/linux/netfilter_ipv4/ip_conntrack_tuple.h b/include/linux/netfilter_ipv4/ip_conntrack_tuple.h
index 2fdabdb4c0ef..c228bde74c33 100644
--- a/include/linux/netfilter_ipv4/ip_conntrack_tuple.h
+++ b/include/linux/netfilter_ipv4/ip_conntrack_tuple.h
@@ -23,13 +23,13 @@ union ip_conntrack_manip_proto
__be16 port;
} tcp;
struct {
- u_int16_t port;
+ __be16 port;
} udp;
struct {
- u_int16_t id;
+ __be16 id;
} icmp;
struct {
- u_int16_t port;
+ __be16 port;
} sctp;
struct {
__be16 key; /* key is 32bit, pptp only uses 16 */
@@ -39,7 +39,7 @@ union ip_conntrack_manip_proto
/* The manipulable part of the tuple. */
struct ip_conntrack_manip
{
- u_int32_t ip;
+ __be32 ip;
union ip_conntrack_manip_proto u;
};
@@ -50,22 +50,22 @@ struct ip_conntrack_tuple
/* These are the parts of the tuple which are fixed. */
struct {
- u_int32_t ip;
+ __be32 ip;
union {
/* Add other protocols here. */
u_int16_t all;
struct {
- u_int16_t port;
+ __be16 port;
} tcp;
struct {
- u_int16_t port;
+ __be16 port;
} udp;
struct {
u_int8_t type, code;
} icmp;
struct {
- u_int16_t port;
+ __be16 port;
} sctp;
struct {
__be16 key; /* key is 32bit,
diff --git a/include/linux/netfilter_ipv4/ip_nat.h b/include/linux/netfilter_ipv4/ip_nat.h
index 98f8407e4cb5..bdf553620ca1 100644
--- a/include/linux/netfilter_ipv4/ip_nat.h
+++ b/include/linux/netfilter_ipv4/ip_nat.h
@@ -33,7 +33,7 @@ struct ip_nat_range
unsigned int flags;
/* Inclusive: network order. */
- u_int32_t min_ip, max_ip;
+ __be32 min_ip, max_ip;
/* Inclusive: network order */
union ip_conntrack_manip_proto min, max;
diff --git a/include/linux/netfilter_ipv4/ip_queue.h b/include/linux/netfilter_ipv4/ip_queue.h
index aa08d68c4841..a03507f465f8 100644
--- a/include/linux/netfilter_ipv4/ip_queue.h
+++ b/include/linux/netfilter_ipv4/ip_queue.h
@@ -26,7 +26,7 @@ typedef struct ipq_packet_msg {
unsigned int hook; /* Netfilter hook we rode in on */
char indev_name[IFNAMSIZ]; /* Name of incoming interface */
char outdev_name[IFNAMSIZ]; /* Name of outgoing interface */
- unsigned short hw_protocol; /* Hardware protocol (network order) */
+ __be16 hw_protocol; /* Hardware protocol (network order) */
unsigned short hw_type; /* Hardware type */
unsigned char hw_addrlen; /* Hardware address length */
unsigned char hw_addr[8]; /* Hardware address */
diff --git a/include/linux/netfilter_ipv4/ipt_iprange.h b/include/linux/netfilter_ipv4/ipt_iprange.h
index 3ecb3bd63676..34ab0fb736e2 100644
--- a/include/linux/netfilter_ipv4/ipt_iprange.h
+++ b/include/linux/netfilter_ipv4/ipt_iprange.h
@@ -8,7 +8,7 @@
struct ipt_iprange {
/* Inclusive: network order. */
- u_int32_t min_ip, max_ip;
+ __be32 min_ip, max_ip;
};
struct ipt_iprange_info
diff --git a/include/linux/nfs_fs.h b/include/linux/nfs_fs.h
index 98c9b9f667a5..76ff54846ada 100644
--- a/include/linux/nfs_fs.h
+++ b/include/linux/nfs_fs.h
@@ -367,10 +367,12 @@ extern int nfs3_removexattr (struct dentry *, const char *name);
*/
extern ssize_t nfs_direct_IO(int, struct kiocb *, const struct iovec *, loff_t,
unsigned long);
-extern ssize_t nfs_file_direct_read(struct kiocb *iocb, char __user *buf,
- size_t count, loff_t pos);
-extern ssize_t nfs_file_direct_write(struct kiocb *iocb, const char __user *buf,
- size_t count, loff_t pos);
+extern ssize_t nfs_file_direct_read(struct kiocb *iocb,
+ const struct iovec *iov, unsigned long nr_segs,
+ loff_t pos);
+extern ssize_t nfs_file_direct_write(struct kiocb *iocb,
+ const struct iovec *iov, unsigned long nr_segs,
+ loff_t pos);
/*
* linux/fs/nfs/dir.c
diff --git a/include/linux/nfsd/nfsd.h b/include/linux/nfsd/nfsd.h
index 2dcad295fece..e1dbc86c270b 100644
--- a/include/linux/nfsd/nfsd.h
+++ b/include/linux/nfsd/nfsd.h
@@ -140,6 +140,11 @@ struct posix_acl *nfsd_get_posix_acl(struct svc_fh *, int);
int nfsd_set_posix_acl(struct svc_fh *, int, struct posix_acl *);
#endif
+enum vers_op {NFSD_SET, NFSD_CLEAR, NFSD_TEST, NFSD_AVAIL };
+int nfsd_vers(int vers, enum vers_op change);
+void nfsd_reset_versions(void);
+int nfsd_create_serv(void);
+
/*
* NFSv4 State
diff --git a/include/linux/nfsd/nfsfh.h b/include/linux/nfsd/nfsfh.h
index 31a3cb617ce0..069257ea99a0 100644
--- a/include/linux/nfsd/nfsfh.h
+++ b/include/linux/nfsd/nfsfh.h
@@ -290,8 +290,9 @@ fill_post_wcc(struct svc_fh *fhp)
* vfs.c:nfsd_rename as it needs to grab 2 i_mutex's at once
* so, any changes here should be reflected there.
*/
+
static inline void
-fh_lock(struct svc_fh *fhp)
+fh_lock_nested(struct svc_fh *fhp, unsigned int subclass)
{
struct dentry *dentry = fhp->fh_dentry;
struct inode *inode;
@@ -310,11 +311,17 @@ fh_lock(struct svc_fh *fhp)
}
inode = dentry->d_inode;
- mutex_lock(&inode->i_mutex);
+ mutex_lock_nested(&inode->i_mutex, subclass);
fill_pre_wcc(fhp);
fhp->fh_locked = 1;
}
+static inline void
+fh_lock(struct svc_fh *fhp)
+{
+ fh_lock_nested(fhp, I_MUTEX_NORMAL);
+}
+
/*
* Unlock a file handle/inode
*/
diff --git a/include/linux/nfsd/syscall.h b/include/linux/nfsd/syscall.h
index dae0faea2807..8bcddccb6c42 100644
--- a/include/linux/nfsd/syscall.h
+++ b/include/linux/nfsd/syscall.h
@@ -38,21 +38,6 @@
#define NFSCTL_GETFD 7 /* get an fh by path (used by mountd) */
#define NFSCTL_GETFS 8 /* get an fh by path with max FH len */
-/*
- * Macros used to set version
- */
-#define NFSCTL_VERSET(_cltbits, _v) ((_cltbits) |= (1 << (_v)))
-#define NFSCTL_VERUNSET(_cltbits, _v) ((_cltbits) &= ~(1 << (_v)))
-#define NFSCTL_VERISSET(_cltbits, _v) ((_cltbits) & (1 << (_v)))
-
-#if defined(CONFIG_NFSD_V4)
-#define NFSCTL_VERALL (0x1c /* 0b011100 */)
-#elif defined(CONFIG_NFSD_V3)
-#define NFSCTL_VERALL (0x0c /* 0b001100 */)
-#else
-#define NFSCTL_VERALL (0x04 /* 0b000100 */)
-#endif
-
/* SVC */
struct nfsctl_svc {
unsigned short svc_port;
@@ -134,8 +119,6 @@ extern int exp_delclient(struct nfsctl_client *ncp);
extern int exp_export(struct nfsctl_export *nxp);
extern int exp_unexport(struct nfsctl_export *nxp);
-extern unsigned int nfsd_versbits;
-
#endif /* __KERNEL__ */
#endif /* NFSD_SYSCALL_H */
diff --git a/include/linux/nmi.h b/include/linux/nmi.h
index c8f4d2f627d7..e16904e28c3a 100644
--- a/include/linux/nmi.h
+++ b/include/linux/nmi.h
@@ -4,6 +4,7 @@
#ifndef LINUX_NMI_H
#define LINUX_NMI_H
+#include <linux/sched.h>
#include <asm/irq.h>
/**
@@ -16,7 +17,7 @@
#ifdef ARCH_HAS_NMI_WATCHDOG
extern void touch_nmi_watchdog(void);
#else
-# define touch_nmi_watchdog() do { } while(0)
+# define touch_nmi_watchdog() touch_softlockup_watchdog()
#endif
#endif
diff --git a/include/linux/nodemask.h b/include/linux/nodemask.h
index 1a9ef3e627d1..5dce5c21822c 100644
--- a/include/linux/nodemask.h
+++ b/include/linux/nodemask.h
@@ -352,6 +352,7 @@ extern nodemask_t node_possible_map;
#define node_possible(node) node_isset((node), node_possible_map)
#define first_online_node first_node(node_online_map)
#define next_online_node(nid) next_node((nid), node_online_map)
+int highest_possible_node_id(void);
#else
#define num_online_nodes() 1
#define num_possible_nodes() 1
@@ -359,6 +360,7 @@ extern nodemask_t node_possible_map;
#define node_possible(node) ((node) == 0)
#define first_online_node 0
#define next_online_node(nid) (MAX_NUMNODES)
+#define highest_possible_node_id() 0
#endif
#define any_online_node(mask) \
diff --git a/include/linux/nsproxy.h b/include/linux/nsproxy.h
new file mode 100644
index 000000000000..f6baecdeecd6
--- /dev/null
+++ b/include/linux/nsproxy.h
@@ -0,0 +1,52 @@
+#ifndef _LINUX_NSPROXY_H
+#define _LINUX_NSPROXY_H
+
+#include <linux/spinlock.h>
+#include <linux/sched.h>
+
+struct namespace;
+struct uts_namespace;
+struct ipc_namespace;
+
+/*
+ * A structure to contain pointers to all per-process
+ * namespaces - fs (mount), uts, network, sysvipc, etc.
+ *
+ * 'count' is the number of tasks holding a reference.
+ * The count for each namespace, then, will be the number
+ * of nsproxies pointing to it, not the number of tasks.
+ *
+ * The nsproxy is shared by tasks which share all namespaces.
+ * As soon as a single namespace is cloned or unshared, the
+ * nsproxy is copied.
+ */
+struct nsproxy {
+ atomic_t count;
+ spinlock_t nslock;
+ struct uts_namespace *uts_ns;
+ struct ipc_namespace *ipc_ns;
+ struct namespace *namespace;
+};
+extern struct nsproxy init_nsproxy;
+
+struct nsproxy *dup_namespaces(struct nsproxy *orig);
+int copy_namespaces(int flags, struct task_struct *tsk);
+void get_task_namespaces(struct task_struct *tsk);
+void free_nsproxy(struct nsproxy *ns);
+
+static inline void put_nsproxy(struct nsproxy *ns)
+{
+ if (atomic_dec_and_test(&ns->count)) {
+ free_nsproxy(ns);
+ }
+}
+
+static inline void exit_task_namespaces(struct task_struct *p)
+{
+ struct nsproxy *ns = p->nsproxy;
+ if (ns) {
+ put_nsproxy(ns);
+ p->nsproxy = NULL;
+ }
+}
+#endif
diff --git a/include/linux/page-flags.h b/include/linux/page-flags.h
index 9d7921dd50f0..4830a3bedfb2 100644
--- a/include/linux/page-flags.h
+++ b/include/linux/page-flags.h
@@ -128,12 +128,11 @@
#define PageUptodate(page) test_bit(PG_uptodate, &(page)->flags)
#ifdef CONFIG_S390
-#define SetPageUptodate(_page) \
- do { \
- struct page *__page = (_page); \
- if (!test_and_set_bit(PG_uptodate, &__page->flags)) \
- page_test_and_clear_dirty(_page); \
- } while (0)
+static inline void SetPageUptodate(struct page *page)
+{
+ if (!test_and_set_bit(PG_uptodate, &page->flags))
+ page_test_and_clear_dirty(page);
+}
#else
#define SetPageUptodate(page) set_bit(PG_uptodate, &(page)->flags)
#endif
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 5c3a4176eb64..4431ce4e1e6f 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -787,12 +787,13 @@ enum pci_fixup_pass {
void pci_fixup_device(enum pci_fixup_pass pass, struct pci_dev *dev);
extern int pci_pci_problems;
-#define PCIPCI_FAIL 1
+#define PCIPCI_FAIL 1 /* No PCI PCI DMA */
#define PCIPCI_TRITON 2
#define PCIPCI_NATOMA 4
#define PCIPCI_VIAETBF 8
#define PCIPCI_VSFX 16
-#define PCIPCI_ALIMAGIK 32
+#define PCIPCI_ALIMAGIK 32 /* Need low latency setting */
+#define PCIAGP_FAIL 64 /* No PCI to AGP DMA */
#endif /* __KERNEL__ */
#endif /* LINUX_PCI_H */
diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h
index 61db1907f06f..c9ffbc3843d5 100644
--- a/include/linux/pci_ids.h
+++ b/include/linux/pci_ids.h
@@ -507,6 +507,7 @@
#define PCI_DEVICE_ID_AMD_8151_0 0x7454
#define PCI_DEVICE_ID_AMD_8131_BRIDGE 0x7450
#define PCI_DEVICE_ID_AMD_8131_APIC 0x7451
+#define PCI_DEVICE_ID_AMD_8132_BRIDGE 0x7458
#define PCI_DEVICE_ID_AMD_CS5536_ISA 0x2090
#define PCI_DEVICE_ID_AMD_CS5536_FLASH 0x2091
#define PCI_DEVICE_ID_AMD_CS5536_AUDIO 0x2093
@@ -1904,6 +1905,7 @@
#define PCI_DEVICE_ID_TIGON3_5705_2 0x1654
#define PCI_DEVICE_ID_TIGON3_5720 0x1658
#define PCI_DEVICE_ID_TIGON3_5721 0x1659
+#define PCI_DEVICE_ID_TIGON3_5722 0x165a
#define PCI_DEVICE_ID_TIGON3_5705M 0x165d
#define PCI_DEVICE_ID_TIGON3_5705M_2 0x165e
#define PCI_DEVICE_ID_TIGON3_5714 0x1668
@@ -1913,6 +1915,7 @@
#define PCI_DEVICE_ID_TIGON3_5705F 0x166e
#define PCI_DEVICE_ID_TIGON3_5754M 0x1672
#define PCI_DEVICE_ID_TIGON3_5755M 0x1673
+#define PCI_DEVICE_ID_TIGON3_5756 0x1674
#define PCI_DEVICE_ID_TIGON3_5750 0x1676
#define PCI_DEVICE_ID_TIGON3_5751 0x1677
#define PCI_DEVICE_ID_TIGON3_5715 0x1678
@@ -1942,6 +1945,8 @@
#define PCI_DEVICE_ID_TIGON3_5901 0x170d
#define PCI_DEVICE_ID_BCM4401B1 0x170c
#define PCI_DEVICE_ID_TIGON3_5901_2 0x170e
+#define PCI_DEVICE_ID_TIGON3_5906 0x1712
+#define PCI_DEVICE_ID_TIGON3_5906M 0x1713
#define PCI_DEVICE_ID_BCM4401 0x4401
#define PCI_DEVICE_ID_BCM4401B0 0x4402
diff --git a/include/linux/percpu.h b/include/linux/percpu.h
index 3835a9642f13..46ec72fa2c84 100644
--- a/include/linux/percpu.h
+++ b/include/linux/percpu.h
@@ -74,7 +74,7 @@ static inline int __percpu_populate_mask(void *__pdata, size_t size, gfp_t gfp,
return 0;
}
-static inline void *__percpu_alloc_mask(size_t size, gfp_t gfp, cpumask_t *mask)
+static __always_inline void *__percpu_alloc_mask(size_t size, gfp_t gfp, cpumask_t *mask)
{
return kzalloc(size, gfp);
}
diff --git a/include/linux/pid.h b/include/linux/pid.h
index 93da7e2d9f30..2c0007d17218 100644
--- a/include/linux/pid.h
+++ b/include/linux/pid.h
@@ -68,6 +68,8 @@ extern struct task_struct *FASTCALL(pid_task(struct pid *pid, enum pid_type));
extern struct task_struct *FASTCALL(get_pid_task(struct pid *pid,
enum pid_type));
+extern struct pid *get_task_pid(struct task_struct *task, enum pid_type type);
+
/*
* attach_pid() and detach_pid() must be called with the tasklist_lock
* write-held.
@@ -89,33 +91,42 @@ extern struct pid *FASTCALL(find_pid(int nr));
* Lookup a PID in the hash table, and return with it's count elevated.
*/
extern struct pid *find_get_pid(int nr);
+extern struct pid *find_ge_pid(int nr);
extern struct pid *alloc_pid(void);
extern void FASTCALL(free_pid(struct pid *pid));
-#define pid_next(task, type) \
- ((task)->pids[(type)].node.next)
-
-#define pid_next_task(task, type) \
- hlist_entry(pid_next(task, type), struct task_struct, \
- pids[(type)].node)
+static inline pid_t pid_nr(struct pid *pid)
+{
+ pid_t nr = 0;
+ if (pid)
+ nr = pid->nr;
+ return nr;
+}
-/* We could use hlist_for_each_entry_rcu here but it takes more arguments
- * than the do_each_task_pid/while_each_task_pid. So we roll our own
- * to preserve the existing interface.
- */
#define do_each_task_pid(who, type, task) \
- if ((task = find_task_by_pid_type(type, who))) { \
- prefetch(pid_next(task, type)); \
- do {
+ do { \
+ struct hlist_node *pos___; \
+ struct pid *pid___ = find_pid(who); \
+ if (pid___ != NULL) \
+ hlist_for_each_entry_rcu((task), pos___, \
+ &pid___->tasks[type], pids[type].node) {
#define while_each_task_pid(who, type, task) \
- } while (pid_next(task, type) && ({ \
- task = pid_next_task(task, type); \
- rcu_dereference(task); \
- prefetch(pid_next(task, type)); \
- 1; }) ); \
- }
+ } \
+ } while (0)
+
+
+#define do_each_pid_task(pid, type, task) \
+ do { \
+ struct hlist_node *pos___; \
+ if (pid != NULL) \
+ hlist_for_each_entry_rcu((task), pos___, \
+ &pid->tasks[type], pids[type].node) {
+
+#define while_each_pid_task(pid, type, task) \
+ } \
+ } while (0)
#endif /* _LINUX_PID_H */
diff --git a/include/linux/posix-timers.h b/include/linux/posix-timers.h
index 95572c434bc9..a7dd38f30ade 100644
--- a/include/linux/posix-timers.h
+++ b/include/linux/posix-timers.h
@@ -72,6 +72,7 @@ struct k_clock {
int (*timer_create) (struct k_itimer *timer);
int (*nsleep) (const clockid_t which_clock, int flags,
struct timespec *, struct timespec __user *);
+ long (*nsleep_restart) (struct restart_block *restart_block);
int (*timer_set) (struct k_itimer * timr, int flags,
struct itimerspec * new_setting,
struct itimerspec * old_setting);
@@ -97,6 +98,7 @@ int posix_cpu_clock_set(const clockid_t which_clock, const struct timespec *ts);
int posix_cpu_timer_create(struct k_itimer *timer);
int posix_cpu_nsleep(const clockid_t which_clock, int flags,
struct timespec *rqtp, struct timespec __user *rmtp);
+long posix_cpu_nsleep_restart(struct restart_block *restart_block);
int posix_cpu_timer_set(struct k_itimer *timer, int flags,
struct itimerspec *new, struct itimerspec *old);
int posix_cpu_timer_del(struct k_itimer *timer);
@@ -111,4 +113,6 @@ void posix_cpu_timers_exit_group(struct task_struct *task);
void set_process_cpu_timer(struct task_struct *task, unsigned int clock_idx,
cputime_t *newval, cputime_t *oldval);
+long clock_nanosleep_restart(struct restart_block *restart_block);
+
#endif
diff --git a/include/linux/proc_fs.h b/include/linux/proc_fs.h
index 57f70bc8b24b..87dec8fe6de9 100644
--- a/include/linux/proc_fs.h
+++ b/include/linux/proc_fs.h
@@ -244,13 +244,15 @@ static inline void kclist_add(struct kcore_list *new, void *addr, size_t size)
extern void kclist_add(struct kcore_list *, void *, size_t);
#endif
+union proc_op {
+ int (*proc_get_link)(struct inode *, struct dentry **, struct vfsmount **);
+ int (*proc_read)(struct task_struct *task, char *page);
+};
+
struct proc_inode {
struct pid *pid;
int fd;
- union {
- int (*proc_get_link)(struct inode *, struct dentry **, struct vfsmount **);
- int (*proc_read)(struct task_struct *task, char *page);
- } op;
+ union proc_op op;
struct proc_dir_entry *pde;
struct inode vfs_inode;
};
diff --git a/include/linux/pspace.h b/include/linux/pspace.h
new file mode 100644
index 000000000000..91d48b8b2d99
--- /dev/null
+++ b/include/linux/pspace.h
@@ -0,0 +1,23 @@
+#ifndef _LINUX_PSPACE_H
+#define _LINUX_PSPACE_H
+
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/threads.h>
+#include <linux/pid.h>
+
+struct pidmap {
+ atomic_t nr_free;
+ void *page;
+};
+
+#define PIDMAP_ENTRIES ((PID_MAX_LIMIT + 8*PAGE_SIZE - 1)/PAGE_SIZE/8)
+
+struct pspace {
+ struct pidmap pidmap[PIDMAP_ENTRIES];
+ int last_pid;
+};
+
+extern struct pspace init_pspace;
+
+#endif /* _LINUX_PSPACE_H */
diff --git a/include/linux/ptrace.h b/include/linux/ptrace.h
index 8b2749a259dc..eeb1976ef7bf 100644
--- a/include/linux/ptrace.h
+++ b/include/linux/ptrace.h
@@ -16,8 +16,8 @@
#define PTRACE_KILL 8
#define PTRACE_SINGLESTEP 9
-#define PTRACE_ATTACH 0x10
-#define PTRACE_DETACH 0x11
+#define PTRACE_ATTACH 16
+#define PTRACE_DETACH 17
#define PTRACE_SYSCALL 24
diff --git a/include/linux/raid/bitmap.h b/include/linux/raid/bitmap.h
index 63df898fe2e9..84d887751855 100644
--- a/include/linux/raid/bitmap.h
+++ b/include/linux/raid/bitmap.h
@@ -265,6 +265,8 @@ int bitmap_update_sb(struct bitmap *bitmap);
int bitmap_setallbits(struct bitmap *bitmap);
void bitmap_write_all(struct bitmap *bitmap);
+void bitmap_dirty_bits(struct bitmap *bitmap, unsigned long s, unsigned long e);
+
/* these are exported */
int bitmap_startwrite(struct bitmap *bitmap, sector_t offset,
unsigned long sectors, int behind);
diff --git a/include/linux/raid/md.h b/include/linux/raid/md.h
index eb3e547c8fee..866a1e2b0ce0 100644
--- a/include/linux/raid/md.h
+++ b/include/linux/raid/md.h
@@ -53,6 +53,8 @@
#include <linux/raid/md_u.h>
#include <linux/raid/md_k.h>
+#ifdef CONFIG_MD
+
/*
* Different major versions are not compatible.
* Different minor versions are only downward compatible.
@@ -93,7 +95,7 @@ extern int sync_page_io(struct block_device *bdev, sector_t sector, int size,
extern void md_do_sync(mddev_t *mddev);
extern void md_new_event(mddev_t *mddev);
-extern void md_update_sb(mddev_t * mddev);
+#endif /* CONFIG_MD */
#endif
diff --git a/include/linux/raid/md_k.h b/include/linux/raid/md_k.h
index d28890295852..8245c282168b 100644
--- a/include/linux/raid/md_k.h
+++ b/include/linux/raid/md_k.h
@@ -18,6 +18,8 @@
/* and dm-bio-list.h is not under include/linux because.... ??? */
#include "../../../drivers/md/dm-bio-list.h"
+#ifdef CONFIG_BLOCK
+
#define LEVEL_MULTIPATH (-4)
#define LEVEL_LINEAR (-1)
#define LEVEL_FAULTY (-5)
@@ -29,18 +31,15 @@
#define LEVEL_NONE (-1000000)
#define MaxSector (~(sector_t)0)
-#define MD_THREAD_NAME_MAX 14
typedef struct mddev_s mddev_t;
typedef struct mdk_rdev_s mdk_rdev_t;
-#define MAX_MD_DEVS 256 /* Max number of md dev */
-
/*
* options passed in raidrun:
*/
-/* Currently this must fix in an 'int' */
+/* Currently this must fit in an 'int' */
#define MAX_CHUNK_SIZE (1<<30)
/*
@@ -114,7 +113,11 @@ struct mddev_s
dev_t unit;
int md_minor;
struct list_head disks;
- int sb_dirty;
+ unsigned long flags;
+#define MD_CHANGE_DEVS 0 /* Some device status has changed */
+#define MD_CHANGE_CLEAN 1 /* transition to or from 'clean' */
+#define MD_CHANGE_PENDING 2 /* superblock update in progress */
+
int ro;
struct gendisk *gendisk;
@@ -362,5 +365,6 @@ static inline void safe_put_page(struct page *p)
if (p) put_page(p);
}
+#endif /* CONFIG_BLOCK */
#endif
diff --git a/include/linux/raid/md_u.h b/include/linux/raid/md_u.h
index 81da20ccec4d..7192035fc4b0 100644
--- a/include/linux/raid/md_u.h
+++ b/include/linux/raid/md_u.h
@@ -41,7 +41,7 @@
/* usage */
#define RUN_ARRAY _IOW (MD_MAJOR, 0x30, mdu_param_t)
-#define START_ARRAY _IO (MD_MAJOR, 0x31)
+/* 0x31 was START_ARRAY */
#define STOP_ARRAY _IO (MD_MAJOR, 0x32)
#define STOP_ARRAY_RO _IO (MD_MAJOR, 0x33)
#define RESTART_ARRAY_RW _IO (MD_MAJOR, 0x34)
diff --git a/include/linux/raid/raid1.h b/include/linux/raid/raid1.h
index 3009c813d83d..0a9ba7c3302e 100644
--- a/include/linux/raid/raid1.h
+++ b/include/linux/raid/raid1.h
@@ -30,7 +30,6 @@ struct r1_private_data_s {
mddev_t *mddev;
mirror_info_t *mirrors;
int raid_disks;
- int working_disks;
int last_used;
sector_t next_seq_sect;
spinlock_t device_lock;
diff --git a/include/linux/raid/raid10.h b/include/linux/raid/raid10.h
index c41e56a7c090..e9091cfeb286 100644
--- a/include/linux/raid/raid10.h
+++ b/include/linux/raid/raid10.h
@@ -16,7 +16,6 @@ struct r10_private_data_s {
mddev_t *mddev;
mirror_info_t *mirrors;
int raid_disks;
- int working_disks;
spinlock_t device_lock;
/* geometry */
diff --git a/include/linux/raid/raid5.h b/include/linux/raid/raid5.h
index 20ed4c997636..f13299a15591 100644
--- a/include/linux/raid/raid5.h
+++ b/include/linux/raid/raid5.h
@@ -195,8 +195,9 @@ struct stripe_head {
* it to the count of prereading stripes.
* When write is initiated, or the stripe refcnt == 0 (just in case) we
* clear the PREREAD_ACTIVE flag and decrement the count
- * Whenever the delayed queue is empty and the device is not plugged, we
- * move any strips from delayed to handle and clear the DELAYED flag and set PREREAD_ACTIVE.
+ * Whenever the 'handle' queue is empty and the device is not plugged, we
+ * move any strips from delayed to handle and clear the DELAYED flag and set
+ * PREREAD_ACTIVE.
* In stripe_handle, if we find pre-reading is necessary, we do it if
* PREREAD_ACTIVE is set, else we set DELAYED which will send it to the delayed queue.
* HANDLE gets cleared if stripe_handle leave nothing locked.
@@ -213,7 +214,7 @@ struct raid5_private_data {
struct disk_info *spare;
int chunk_size, level, algorithm;
int max_degraded;
- int raid_disks, working_disks, failed_disks;
+ int raid_disks;
int max_nr_stripes;
/* used during an expand */
diff --git a/include/linux/ramfs.h b/include/linux/ramfs.h
index 00b340ba6612..b160fb18e8d6 100644
--- a/include/linux/ramfs.h
+++ b/include/linux/ramfs.h
@@ -17,5 +17,6 @@ extern int ramfs_nommu_mmap(struct file *file, struct vm_area_struct *vma);
extern const struct file_operations ramfs_file_operations;
extern struct vm_operations_struct generic_file_vm_ops;
+extern int __init init_rootfs(void);
#endif
diff --git a/include/linux/rbtree.h b/include/linux/rbtree.h
index 8d5382e62c08..344bc3495ddb 100644
--- a/include/linux/rbtree.h
+++ b/include/linux/rbtree.h
@@ -133,7 +133,7 @@ static inline void rb_set_color(struct rb_node *rb, int color)
#define rb_entry(ptr, type, member) container_of(ptr, type, member)
#define RB_EMPTY_ROOT(root) ((root)->rb_node == NULL)
-#define RB_EMPTY_NODE(node) (rb_parent(node) != node)
+#define RB_EMPTY_NODE(node) (rb_parent(node) == node)
#define RB_CLEAR_NODE(node) (rb_set_parent(node, node))
extern void rb_insert_color(struct rb_node *, struct rb_root *);
diff --git a/include/linux/reiserfs_acl.h b/include/linux/reiserfs_acl.h
index 806ec5b06707..fe00f781a622 100644
--- a/include/linux/reiserfs_acl.h
+++ b/include/linux/reiserfs_acl.h
@@ -56,6 +56,16 @@ extern int reiserfs_xattr_posix_acl_init(void) __init;
extern int reiserfs_xattr_posix_acl_exit(void);
extern struct reiserfs_xattr_handler posix_acl_default_handler;
extern struct reiserfs_xattr_handler posix_acl_access_handler;
+
+static inline void reiserfs_init_acl_access(struct inode *inode)
+{
+ REISERFS_I(inode)->i_acl_access = NULL;
+}
+
+static inline void reiserfs_init_acl_default(struct inode *inode)
+{
+ REISERFS_I(inode)->i_acl_default = NULL;
+}
#else
#define reiserfs_cache_default_acl(inode) 0
@@ -87,4 +97,11 @@ reiserfs_inherit_default_acl(const struct inode *dir, struct dentry *dentry,
return 0;
}
+static inline void reiserfs_init_acl_access(struct inode *inode)
+{
+}
+
+static inline void reiserfs_init_acl_default(struct inode *inode)
+{
+}
#endif
diff --git a/include/linux/reiserfs_fs.h b/include/linux/reiserfs_fs.h
index 28493ffaafe7..7bc6bfb86253 100644
--- a/include/linux/reiserfs_fs.h
+++ b/include/linux/reiserfs_fs.h
@@ -807,21 +807,19 @@ struct stat_data_v1 {
#define set_sd_v1_first_direct_byte(sdp,v) \
((sdp)->sd_first_direct_byte = cpu_to_le32(v))
-#include <linux/ext2_fs.h>
-
/* inode flags stored in sd_attrs (nee sd_reserved) */
/* we want common flags to have the same values as in ext2,
so chattr(1) will work without problems */
-#define REISERFS_IMMUTABLE_FL EXT2_IMMUTABLE_FL
-#define REISERFS_APPEND_FL EXT2_APPEND_FL
-#define REISERFS_SYNC_FL EXT2_SYNC_FL
-#define REISERFS_NOATIME_FL EXT2_NOATIME_FL
-#define REISERFS_NODUMP_FL EXT2_NODUMP_FL
-#define REISERFS_SECRM_FL EXT2_SECRM_FL
-#define REISERFS_UNRM_FL EXT2_UNRM_FL
-#define REISERFS_COMPR_FL EXT2_COMPR_FL
-#define REISERFS_NOTAIL_FL EXT2_NOTAIL_FL
+#define REISERFS_IMMUTABLE_FL FS_IMMUTABLE_FL
+#define REISERFS_APPEND_FL FS_APPEND_FL
+#define REISERFS_SYNC_FL FS_SYNC_FL
+#define REISERFS_NOATIME_FL FS_NOATIME_FL
+#define REISERFS_NODUMP_FL FS_NODUMP_FL
+#define REISERFS_SECRM_FL FS_SECRM_FL
+#define REISERFS_UNRM_FL FS_UNRM_FL
+#define REISERFS_COMPR_FL FS_COMPR_FL
+#define REISERFS_NOTAIL_FL FS_NOTAIL_FL
/* persistent flags that file inherits from the parent directory */
#define REISERFS_INHERIT_MASK ( REISERFS_IMMUTABLE_FL | \
@@ -2075,6 +2073,10 @@ void reiserfs_init_alloc_options(struct super_block *s);
*/
__le32 reiserfs_choose_packing(struct inode *dir);
+int reiserfs_init_bitmap_cache(struct super_block *sb);
+void reiserfs_free_bitmap_cache(struct super_block *sb);
+void reiserfs_cache_bitmap_metadata(struct super_block *sb, struct buffer_head *bh, struct reiserfs_bitmap_info *info);
+struct buffer_head *reiserfs_read_bitmap_block(struct super_block *sb, unsigned int bitmap);
int is_reusable(struct super_block *s, b_blocknr_t block, int bit_value);
void reiserfs_free_block(struct reiserfs_transaction_handle *th, struct inode *,
b_blocknr_t, int for_unformatted);
@@ -2163,15 +2165,24 @@ __u32 r5_hash(const signed char *msg, int len);
/* prototypes from ioctl.c */
int reiserfs_ioctl(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg);
+long reiserfs_compat_ioctl(struct file *filp,
+ unsigned int cmd, unsigned long arg);
/* ioctl's command */
#define REISERFS_IOC_UNPACK _IOW(0xCD,1,long)
/* define following flags to be the same as in ext2, so that chattr(1),
lsattr(1) will work with us. */
-#define REISERFS_IOC_GETFLAGS EXT2_IOC_GETFLAGS
-#define REISERFS_IOC_SETFLAGS EXT2_IOC_SETFLAGS
-#define REISERFS_IOC_GETVERSION EXT2_IOC_GETVERSION
-#define REISERFS_IOC_SETVERSION EXT2_IOC_SETVERSION
+#define REISERFS_IOC_GETFLAGS FS_IOC_GETFLAGS
+#define REISERFS_IOC_SETFLAGS FS_IOC_SETFLAGS
+#define REISERFS_IOC_GETVERSION FS_IOC_GETVERSION
+#define REISERFS_IOC_SETVERSION FS_IOC_SETVERSION
+
+/* the 32 bit compat definitions with int argument */
+#define REISERFS_IOC32_UNPACK _IOW(0xCD, 1, int)
+#define REISERFS_IOC32_GETFLAGS FS_IOC32_GETFLAGS
+#define REISERFS_IOC32_SETFLAGS FS_IOC32_SETFLAGS
+#define REISERFS_IOC32_GETVERSION FS_IOC32_GETVERSION
+#define REISERFS_IOC32_SETVERSION FS_IOC32_SETVERSION
/* Locking primitives */
/* Right now we are still falling back to (un)lock_kernel, but eventually that
diff --git a/include/linux/reiserfs_fs_i.h b/include/linux/reiserfs_fs_i.h
index 149be8d9a0c9..5b3b297aa2c5 100644
--- a/include/linux/reiserfs_fs_i.h
+++ b/include/linux/reiserfs_fs_i.h
@@ -52,10 +52,13 @@ struct reiserfs_inode_info {
** flushed */
unsigned long i_trans_id;
struct reiserfs_journal_list *i_jl;
-
+#ifdef CONFIG_REISERFS_FS_POSIX_ACL
struct posix_acl *i_acl_access;
struct posix_acl *i_acl_default;
+#endif
+#ifdef CONFIG_REISERFS_FS_XATTR
struct rw_semaphore xattr_sem;
+#endif
struct inode vfs_inode;
};
diff --git a/include/linux/reiserfs_fs_sb.h b/include/linux/reiserfs_fs_sb.h
index 31b4c0bd4fa0..73e0becec086 100644
--- a/include/linux/reiserfs_fs_sb.h
+++ b/include/linux/reiserfs_fs_sb.h
@@ -267,7 +267,6 @@ struct reiserfs_bitmap_info {
// FIXME: Won't work with block sizes > 8K
__u16 first_zero_hint;
__u16 free_count;
- struct buffer_head *bh; /* the actual bitmap */
};
struct proc_dir_entry;
@@ -414,6 +413,7 @@ struct reiserfs_sb_info {
/* Definitions of reiserfs on-disk properties: */
#define REISERFS_3_5 0
#define REISERFS_3_6 1
+#define REISERFS_OLD_FORMAT 2
enum reiserfs_mount_options {
/* Mount options */
diff --git a/include/linux/reiserfs_xattr.h b/include/linux/reiserfs_xattr.h
index 5e961035c725..966c35851b2e 100644
--- a/include/linux/reiserfs_xattr.h
+++ b/include/linux/reiserfs_xattr.h
@@ -97,6 +97,11 @@ static inline void reiserfs_mark_inode_private(struct inode *inode)
inode->i_flags |= S_PRIVATE;
}
+static inline void reiserfs_init_xattr_rwsem(struct inode *inode)
+{
+ init_rwsem(&REISERFS_I(inode)->xattr_sem);
+}
+
#else
#define is_reiserfs_priv_object(inode) 0
@@ -129,6 +134,9 @@ static inline int reiserfs_xattr_init(struct super_block *sb, int mount_flags)
sb->s_flags = (sb->s_flags & ~MS_POSIXACL); /* to be sure */
return 0;
};
+static inline void reiserfs_init_xattr_rwsem(struct inode *inode)
+{
+}
#endif
#endif /* __KERNEL__ */
diff --git a/include/linux/rtc.h b/include/linux/rtc.h
index 5371e4e74595..b89f09357054 100644
--- a/include/linux/rtc.h
+++ b/include/linux/rtc.h
@@ -141,7 +141,7 @@ struct rtc_device
int id;
char name[RTC_DEVICE_NAME_SIZE];
- struct rtc_class_ops *ops;
+ const struct rtc_class_ops *ops;
struct mutex ops_lock;
struct class_device *rtc_dev;
@@ -172,7 +172,7 @@ struct rtc_device
extern struct rtc_device *rtc_device_register(const char *name,
struct device *dev,
- struct rtc_class_ops *ops,
+ const struct rtc_class_ops *ops,
struct module *owner);
extern void rtc_device_unregister(struct rtc_device *rdev);
extern int rtc_interface_register(struct class_interface *intf);
diff --git a/include/linux/rtnetlink.h b/include/linux/rtnetlink.h
index 9c92dc8b9a08..3a18addaed4c 100644
--- a/include/linux/rtnetlink.h
+++ b/include/linux/rtnetlink.h
@@ -2,7 +2,7 @@
#define __LINUX_RTNETLINK_H
#include <linux/netlink.h>
-#include <linux/if.h>
+#include <linux/if_link.h>
/****
* Routing/neighbour discovery messages.
diff --git a/include/linux/sched.h b/include/linux/sched.h
index 9d4aa7f95bc8..331f4502e92b 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -24,6 +24,8 @@
#define CLONE_UNTRACED 0x00800000 /* set if the tracing process can't force CLONE_PTRACE on this clone */
#define CLONE_CHILD_SETTID 0x01000000 /* set the TID in the child */
#define CLONE_STOPPED 0x02000000 /* Start in stopped state */
+#define CLONE_NEWUTS 0x04000000 /* New utsname group? */
+#define CLONE_NEWIPC 0x08000000 /* New ipcs */
/*
* Scheduling policies
@@ -118,7 +120,6 @@ extern unsigned long avenrun[]; /* Load averages */
extern unsigned long total_forks;
extern int nr_threads;
-extern int last_pid;
DECLARE_PER_CPU(unsigned long, process_counts);
extern int nr_processes(void);
extern unsigned long nr_running(void);
@@ -148,6 +149,7 @@ extern unsigned long weighted_cpuload(const int cpu);
#define EXIT_DEAD 32
/* in tsk->state again */
#define TASK_NONINTERACTIVE 64
+#define TASK_DEAD 128
#define __set_task_state(tsk, state_value) \
do { (tsk)->state = (state_value); } while (0)
@@ -238,7 +240,7 @@ extern signed long schedule_timeout_interruptible(signed long timeout);
extern signed long schedule_timeout_uninterruptible(signed long timeout);
asmlinkage void schedule(void);
-struct namespace;
+struct nsproxy;
/* Maximum number of active map areas.. This is a random (large) number */
#define DEFAULT_MAX_MAP_COUNT 65536
@@ -504,8 +506,8 @@ struct signal_struct {
#define rt_prio(prio) unlikely((prio) < MAX_RT_PRIO)
#define rt_task(p) rt_prio((p)->prio)
#define batch_task(p) (unlikely((p)->policy == SCHED_BATCH))
-#define has_rt_policy(p) \
- unlikely((p)->policy != SCHED_NORMAL && (p)->policy != SCHED_BATCH)
+#define is_rt_policy(p) ((p) != SCHED_NORMAL && (p) != SCHED_BATCH)
+#define has_rt_policy(p) unlikely(is_rt_policy((p)->policy))
/*
* Some day this will be a full-fledged user tracking system..
@@ -623,9 +625,17 @@ enum idle_type
#define SD_WAKE_BALANCE 64 /* Perform balancing at task wakeup */
#define SD_SHARE_CPUPOWER 128 /* Domain members share cpu power */
#define SD_POWERSAVINGS_BALANCE 256 /* Balance for power savings */
+#define SD_SHARE_PKG_RESOURCES 512 /* Domain members share cpu pkg resources */
-#define BALANCE_FOR_POWER ((sched_mc_power_savings || sched_smt_power_savings) \
- ? SD_POWERSAVINGS_BALANCE : 0)
+#define BALANCE_FOR_MC_POWER \
+ (sched_smt_power_savings ? SD_POWERSAVINGS_BALANCE : 0)
+
+#define BALANCE_FOR_PKG_POWER \
+ ((sched_mc_power_savings || sched_smt_power_savings) ? \
+ SD_POWERSAVINGS_BALANCE : 0)
+
+#define test_sd_parent(sd, flag) ((sd->parent && \
+ (sd->parent->flags & flag)) ? 1 : 0)
struct sched_group {
@@ -642,6 +652,7 @@ struct sched_group {
struct sched_domain {
/* These fields must be setup */
struct sched_domain *parent; /* top domain must be null terminated */
+ struct sched_domain *child; /* bottom domain must be null terminated */
struct sched_group *groups; /* the balancing groups of the domain */
cpumask_t span; /* span of all CPUs in this domain */
unsigned long min_interval; /* Minimum balance interval ms */
@@ -709,7 +720,6 @@ extern unsigned int max_cache_size;
struct io_context; /* See blkdev.h */
-void exit_io_context(void);
struct cpuset;
#define NGROUPS_SMALL 32
@@ -754,6 +764,7 @@ static inline void prefetch_stack(struct task_struct *t) { }
struct audit_context; /* See audit.c */
struct mempolicy;
struct pipe_inode_info;
+struct uts_namespace;
enum sleep_type {
SLEEP_NORMAL,
@@ -784,8 +795,9 @@ struct task_struct {
struct prio_array *array;
unsigned short ioprio;
+#ifdef CONFIG_BLK_DEV_IO_TRACE
unsigned int btrace_seq;
-
+#endif
unsigned long sleep_avg;
unsigned long long timestamp, last_ran;
unsigned long long sched_time; /* sched_clock time spent running */
@@ -886,16 +898,18 @@ struct task_struct {
- initialized normally by flush_old_exec */
/* file system info */
int link_count, total_link_count;
+#ifdef CONFIG_SYSVIPC
/* ipc stuff */
struct sysv_sem sysvsem;
+#endif
/* CPU-specific state of this task */
struct thread_struct thread;
/* filesystem information */
struct fs_struct *fs;
/* open file information */
struct files_struct *files;
-/* namespace */
- struct namespace *namespace;
+/* namespaces */
+ struct nsproxy *nsproxy;
/* signal handlers */
struct signal_struct *signal;
struct sighand_struct *sighand;
@@ -978,10 +992,10 @@ struct task_struct {
wait_queue_t *io_wait;
/* i/o counters(bytes read/written, #syscalls */
u64 rchar, wchar, syscr, syscw;
-#if defined(CONFIG_BSD_PROCESS_ACCT)
+#if defined(CONFIG_TASK_XACCT)
u64 acct_rss_mem1; /* accumulated rss usage */
u64 acct_vm_mem1; /* accumulated virtual memory usage */
- clock_t acct_stimexpd; /* clock_t-converted stime since last update */
+ cputime_t acct_stimexpd;/* stime since last update */
#endif
#ifdef CONFIG_NUMA
struct mempolicy *mempolicy;
@@ -1017,6 +1031,26 @@ static inline pid_t process_group(struct task_struct *tsk)
return tsk->signal->pgrp;
}
+static inline struct pid *task_pid(struct task_struct *task)
+{
+ return task->pids[PIDTYPE_PID].pid;
+}
+
+static inline struct pid *task_tgid(struct task_struct *task)
+{
+ return task->group_leader->pids[PIDTYPE_PID].pid;
+}
+
+static inline struct pid *task_pgrp(struct task_struct *task)
+{
+ return task->group_leader->pids[PIDTYPE_PGID].pid;
+}
+
+static inline struct pid *task_session(struct task_struct *task)
+{
+ return task->group_leader->pids[PIDTYPE_SID].pid;
+}
+
/**
* pid_alive - check that a task structure is not stale
* @p: Task structure to be checked.
@@ -1030,6 +1064,18 @@ static inline int pid_alive(struct task_struct *p)
return p->pids[PIDTYPE_PID].pid != NULL;
}
+/**
+ * is_init - check if a task structure is the first user space
+ * task the kernel created.
+ * @p: Task structure to be checked.
+ */
+static inline int is_init(struct task_struct *tsk)
+{
+ return tsk->pid == 1;
+}
+
+extern struct pid *cad_pid;
+
extern void free_task(struct task_struct *tsk);
#define get_task_struct(tsk) do { atomic_inc(&(tsk)->usage); } while(0)
@@ -1048,7 +1094,6 @@ static inline void put_task_struct(struct task_struct *t)
/* Not implemented yet, only for 486*/
#define PF_STARTING 0x00000002 /* being created */
#define PF_EXITING 0x00000004 /* getting shut down */
-#define PF_DEAD 0x00000008 /* Dead */
#define PF_FORKNOEXEC 0x00000040 /* forked but didn't exec */
#define PF_SUPERPRIV 0x00000100 /* used super-user privileges */
#define PF_DUMPCORE 0x00000200 /* dumped core */
@@ -1193,7 +1238,7 @@ extern void switch_uid(struct user_struct *);
#include <asm/current.h>
-extern void do_timer(struct pt_regs *);
+extern void do_timer(unsigned long ticks);
extern int FASTCALL(wake_up_state(struct task_struct * tsk, unsigned int state));
extern int FASTCALL(wake_up_process(struct task_struct * tsk));
@@ -1235,10 +1280,15 @@ extern int send_sig_info(int, struct siginfo *, struct task_struct *);
extern int send_group_sig_info(int, struct siginfo *, struct task_struct *);
extern int force_sigsegv(int, struct task_struct *);
extern int force_sig_info(int, struct siginfo *, struct task_struct *);
+extern int __kill_pgrp_info(int sig, struct siginfo *info, struct pid *pgrp);
+extern int kill_pgrp_info(int sig, struct siginfo *info, struct pid *pgrp);
+extern int kill_pid_info(int sig, struct siginfo *info, struct pid *pid);
+extern int kill_pid_info_as_uid(int, struct siginfo *, struct pid *, uid_t, uid_t, u32);
+extern int kill_pgrp(struct pid *pid, int sig, int priv);
+extern int kill_pid(struct pid *pid, int sig, int priv);
extern int __kill_pg_info(int sig, struct siginfo *info, pid_t pgrp);
extern int kill_pg_info(int, struct siginfo *, pid_t);
extern int kill_proc_info(int, struct siginfo *, pid_t);
-extern int kill_proc_info_as_uid(int, struct siginfo *, pid_t, uid_t, uid_t, u32);
extern void do_notify_parent(struct task_struct *, int);
extern void force_sig(int, struct task_struct *);
extern void force_sig_specific(int, struct task_struct *);
@@ -1253,6 +1303,11 @@ extern int send_group_sigqueue(int, struct sigqueue *, struct task_struct *);
extern int do_sigaction(int, struct k_sigaction *, struct k_sigaction *);
extern int do_sigaltstack(const stack_t __user *, stack_t __user *, unsigned long);
+static inline int kill_cad_pid(int sig, int priv)
+{
+ return kill_pid(cad_pid, sig, priv);
+}
+
/* These can be the second arg to send_sig_info/send_group_sig_info. */
#define SEND_SIG_NOINFO ((struct siginfo *) 0)
#define SEND_SIG_PRIV ((struct siginfo *) 1)
@@ -1346,6 +1401,17 @@ extern void wait_task_inactive(struct task_struct * p);
/* de_thread depends on thread_group_leader not being a pid based check */
#define thread_group_leader(p) (p == p->group_leader)
+/* Do to the insanities of de_thread it is possible for a process
+ * to have the pid of the thread group leader without actually being
+ * the thread group leader. For iteration through the pids in proc
+ * all we care about is that we have a task with the appropriate
+ * pid, we don't actually care if we have the right task.
+ */
+static inline int has_group_leader_pid(struct task_struct *p)
+{
+ return p->pid == p->tgid;
+}
+
static inline struct task_struct *next_thread(const struct task_struct *p)
{
return list_entry(rcu_dereference(p->thread_group.next),
diff --git a/include/linux/scx200_gpio.h b/include/linux/scx200_gpio.h
index 90dd069cc145..1a82d30c4b17 100644
--- a/include/linux/scx200_gpio.h
+++ b/include/linux/scx200_gpio.h
@@ -4,6 +4,7 @@ u32 scx200_gpio_configure(unsigned index, u32 set, u32 clear);
extern unsigned scx200_gpio_base;
extern long scx200_gpio_shadow[2];
+extern struct nsc_gpio_ops scx200_gpio_ops;
#define scx200_gpio_present() (scx200_gpio_base!=0)
diff --git a/include/linux/security.h b/include/linux/security.h
index 9f56fb8a4a6c..9b5fea81f55e 100644
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -1595,6 +1595,7 @@ static inline void security_sb_post_pivotroot (struct nameidata *old_nd,
static inline int security_inode_alloc (struct inode *inode)
{
+ inode->i_security = NULL;
return security_ops->inode_alloc_security (inode);
}
diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h
index 86501a3de2ac..de2e68159d96 100644
--- a/include/linux/serial_core.h
+++ b/include/linux/serial_core.h
@@ -319,6 +319,7 @@ struct uart_info {
#define UIF_CTS_FLOW ((__force uif_t) (1 << 26))
#define UIF_NORMAL_ACTIVE ((__force uif_t) (1 << 29))
#define UIF_INITIALIZED ((__force uif_t) (1 << 31))
+#define UIF_SUSPENDED ((__force uif_t) (1 << 30))
int blocked_open;
@@ -414,7 +415,7 @@ uart_handle_sysrq_char(struct uart_port *port, unsigned int ch,
#ifdef SUPPORT_SYSRQ
if (port->sysrq) {
if (ch && time_before(jiffies, port->sysrq)) {
- handle_sysrq(ch, regs, NULL);
+ handle_sysrq(ch, regs, port->info->tty);
port->sysrq = 0;
return 1;
}
diff --git a/include/linux/serio.h b/include/linux/serio.h
index 6348e8330897..c9069310b6ac 100644
--- a/include/linux/serio.h
+++ b/include/linux/serio.h
@@ -217,5 +217,8 @@ static inline void serio_unpin_driver(struct serio *serio)
#define SERIO_LKKBD 0x28
#define SERIO_ELO 0x29
#define SERIO_MICROTOUCH 0x30
+#define SERIO_PENMOUNT 0x31
+#define SERIO_TOUCHRIGHT 0x32
+#define SERIO_TOUCHWIN 0x33
#endif
diff --git a/include/linux/shmem_fs.h b/include/linux/shmem_fs.h
index c057f0b32318..f3c51899117f 100644
--- a/include/linux/shmem_fs.h
+++ b/include/linux/shmem_fs.h
@@ -19,6 +19,10 @@ struct shmem_inode_info {
swp_entry_t i_direct[SHMEM_NR_DIRECT]; /* first blocks */
struct list_head swaplist; /* chain of maybes on swap */
struct inode vfs_inode;
+#ifdef CONFIG_TMPFS_POSIX_ACL
+ struct posix_acl *i_acl;
+ struct posix_acl *i_default_acl;
+#endif
};
struct shmem_sb_info {
@@ -36,4 +40,24 @@ static inline struct shmem_inode_info *SHMEM_I(struct inode *inode)
return container_of(inode, struct shmem_inode_info, vfs_inode);
}
+#ifdef CONFIG_TMPFS_POSIX_ACL
+int shmem_permission(struct inode *, int, struct nameidata *);
+int shmem_acl_init(struct inode *, struct inode *);
+void shmem_acl_destroy_inode(struct inode *);
+
+extern struct xattr_handler shmem_xattr_acl_access_handler;
+extern struct xattr_handler shmem_xattr_acl_default_handler;
+
+extern struct generic_acl_operations shmem_acl_ops;
+
+#else
+static inline int shmem_acl_init(struct inode *inode, struct inode *dir)
+{
+ return 0;
+}
+static inline void shmem_acl_destroy_inode(struct inode *inode)
+{
+}
+#endif /* CONFIG_TMPFS_POSIX_ACL */
+
#endif
diff --git a/include/linux/spinlock.h b/include/linux/spinlock.h
index 31473db92d3b..b800d2d68b32 100644
--- a/include/linux/spinlock.h
+++ b/include/linux/spinlock.h
@@ -167,9 +167,9 @@ do { \
* regardless of whether CONFIG_SMP or CONFIG_PREEMPT are set. The various
* methods are defined as nops in the case they are not required.
*/
-#define spin_trylock(lock) __cond_lock(_spin_trylock(lock))
-#define read_trylock(lock) __cond_lock(_read_trylock(lock))
-#define write_trylock(lock) __cond_lock(_write_trylock(lock))
+#define spin_trylock(lock) __cond_lock(lock, _spin_trylock(lock))
+#define read_trylock(lock) __cond_lock(lock, _read_trylock(lock))
+#define write_trylock(lock) __cond_lock(lock, _write_trylock(lock))
#define spin_lock(lock) _spin_lock(lock)
@@ -236,19 +236,19 @@ do { \
_write_unlock_irqrestore(lock, flags)
#define write_unlock_bh(lock) _write_unlock_bh(lock)
-#define spin_trylock_bh(lock) __cond_lock(_spin_trylock_bh(lock))
+#define spin_trylock_bh(lock) __cond_lock(lock, _spin_trylock_bh(lock))
#define spin_trylock_irq(lock) \
({ \
local_irq_disable(); \
- _spin_trylock(lock) ? \
+ spin_trylock(lock) ? \
1 : ({ local_irq_enable(); 0; }); \
})
#define spin_trylock_irqsave(lock, flags) \
({ \
local_irq_save(flags); \
- _spin_trylock(lock) ? \
+ spin_trylock(lock) ? \
1 : ({ local_irq_restore(flags); 0; }); \
})
@@ -264,7 +264,7 @@ do { \
*/
extern int _atomic_dec_and_lock(atomic_t *atomic, spinlock_t *lock);
#define atomic_dec_and_lock(atomic, lock) \
- __cond_lock(_atomic_dec_and_lock(atomic, lock))
+ __cond_lock(lock, _atomic_dec_and_lock(atomic, lock))
/**
* spin_can_lock - would spin_trylock() succeed?
diff --git a/include/linux/spinlock_api_smp.h b/include/linux/spinlock_api_smp.h
index b2c4f8299464..8828b8155e9c 100644
--- a/include/linux/spinlock_api_smp.h
+++ b/include/linux/spinlock_api_smp.h
@@ -19,41 +19,41 @@ int in_lock_functions(unsigned long addr);
#define assert_spin_locked(x) BUG_ON(!spin_is_locked(x))
-void __lockfunc _spin_lock(spinlock_t *lock) __acquires(spinlock_t);
+void __lockfunc _spin_lock(spinlock_t *lock) __acquires(lock);
void __lockfunc _spin_lock_nested(spinlock_t *lock, int subclass)
- __acquires(spinlock_t);
-void __lockfunc _read_lock(rwlock_t *lock) __acquires(rwlock_t);
-void __lockfunc _write_lock(rwlock_t *lock) __acquires(rwlock_t);
-void __lockfunc _spin_lock_bh(spinlock_t *lock) __acquires(spinlock_t);
-void __lockfunc _read_lock_bh(rwlock_t *lock) __acquires(rwlock_t);
-void __lockfunc _write_lock_bh(rwlock_t *lock) __acquires(rwlock_t);
-void __lockfunc _spin_lock_irq(spinlock_t *lock) __acquires(spinlock_t);
-void __lockfunc _read_lock_irq(rwlock_t *lock) __acquires(rwlock_t);
-void __lockfunc _write_lock_irq(rwlock_t *lock) __acquires(rwlock_t);
+ __acquires(lock);
+void __lockfunc _read_lock(rwlock_t *lock) __acquires(lock);
+void __lockfunc _write_lock(rwlock_t *lock) __acquires(lock);
+void __lockfunc _spin_lock_bh(spinlock_t *lock) __acquires(lock);
+void __lockfunc _read_lock_bh(rwlock_t *lock) __acquires(lock);
+void __lockfunc _write_lock_bh(rwlock_t *lock) __acquires(lock);
+void __lockfunc _spin_lock_irq(spinlock_t *lock) __acquires(lock);
+void __lockfunc _read_lock_irq(rwlock_t *lock) __acquires(lock);
+void __lockfunc _write_lock_irq(rwlock_t *lock) __acquires(lock);
unsigned long __lockfunc _spin_lock_irqsave(spinlock_t *lock)
- __acquires(spinlock_t);
+ __acquires(lock);
unsigned long __lockfunc _read_lock_irqsave(rwlock_t *lock)
- __acquires(rwlock_t);
+ __acquires(lock);
unsigned long __lockfunc _write_lock_irqsave(rwlock_t *lock)
- __acquires(rwlock_t);
+ __acquires(lock);
int __lockfunc _spin_trylock(spinlock_t *lock);
int __lockfunc _read_trylock(rwlock_t *lock);
int __lockfunc _write_trylock(rwlock_t *lock);
int __lockfunc _spin_trylock_bh(spinlock_t *lock);
-void __lockfunc _spin_unlock(spinlock_t *lock) __releases(spinlock_t);
-void __lockfunc _read_unlock(rwlock_t *lock) __releases(rwlock_t);
-void __lockfunc _write_unlock(rwlock_t *lock) __releases(rwlock_t);
-void __lockfunc _spin_unlock_bh(spinlock_t *lock) __releases(spinlock_t);
-void __lockfunc _read_unlock_bh(rwlock_t *lock) __releases(rwlock_t);
-void __lockfunc _write_unlock_bh(rwlock_t *lock) __releases(rwlock_t);
-void __lockfunc _spin_unlock_irq(spinlock_t *lock) __releases(spinlock_t);
-void __lockfunc _read_unlock_irq(rwlock_t *lock) __releases(rwlock_t);
-void __lockfunc _write_unlock_irq(rwlock_t *lock) __releases(rwlock_t);
+void __lockfunc _spin_unlock(spinlock_t *lock) __releases(lock);
+void __lockfunc _read_unlock(rwlock_t *lock) __releases(lock);
+void __lockfunc _write_unlock(rwlock_t *lock) __releases(lock);
+void __lockfunc _spin_unlock_bh(spinlock_t *lock) __releases(lock);
+void __lockfunc _read_unlock_bh(rwlock_t *lock) __releases(lock);
+void __lockfunc _write_unlock_bh(rwlock_t *lock) __releases(lock);
+void __lockfunc _spin_unlock_irq(spinlock_t *lock) __releases(lock);
+void __lockfunc _read_unlock_irq(rwlock_t *lock) __releases(lock);
+void __lockfunc _write_unlock_irq(rwlock_t *lock) __releases(lock);
void __lockfunc _spin_unlock_irqrestore(spinlock_t *lock, unsigned long flags)
- __releases(spinlock_t);
+ __releases(lock);
void __lockfunc _read_unlock_irqrestore(rwlock_t *lock, unsigned long flags)
- __releases(rwlock_t);
+ __releases(lock);
void __lockfunc _write_unlock_irqrestore(rwlock_t *lock, unsigned long flags)
- __releases(rwlock_t);
+ __releases(lock);
#endif /* __LINUX_SPINLOCK_API_SMP_H */
diff --git a/include/linux/stat.h b/include/linux/stat.h
index 8669291352db..679ef0d70b6b 100644
--- a/include/linux/stat.h
+++ b/include/linux/stat.h
@@ -57,7 +57,7 @@
#include <linux/time.h>
struct kstat {
- unsigned long ino;
+ u64 ino;
dev_t dev;
umode_t mode;
unsigned int nlink;
diff --git a/include/linux/stddef.h b/include/linux/stddef.h
index ea65dfb60cd8..6a40c76bdcf1 100644
--- a/include/linux/stddef.h
+++ b/include/linux/stddef.h
@@ -11,6 +11,12 @@
#endif
#ifdef __KERNEL__
+
+enum {
+ false = 0,
+ true = 1
+};
+
#undef offsetof
#ifdef __compiler_offsetof
#define offsetof(TYPE,MEMBER) __compiler_offsetof(TYPE,MEMBER)
diff --git a/include/linux/string.h b/include/linux/string.h
index e4c755860316..4f69ef9e6eb5 100644
--- a/include/linux/string.h
+++ b/include/linux/string.h
@@ -99,6 +99,7 @@ extern void * memchr(const void *,int,__kernel_size_t);
#endif
extern char *kstrdup(const char *s, gfp_t gfp);
+extern void *kmemdup(const void *src, size_t len, gfp_t gfp);
#ifdef __cplusplus
}
diff --git a/include/linux/sunrpc/auth.h b/include/linux/sunrpc/auth.h
index a6de332e57d4..862c0d8c8381 100644
--- a/include/linux/sunrpc/auth.h
+++ b/include/linux/sunrpc/auth.h
@@ -109,13 +109,13 @@ struct rpc_credops {
void (*crdestroy)(struct rpc_cred *);
int (*crmatch)(struct auth_cred *, struct rpc_cred *, int);
- u32 * (*crmarshal)(struct rpc_task *, u32 *);
+ __be32 * (*crmarshal)(struct rpc_task *, __be32 *);
int (*crrefresh)(struct rpc_task *);
- u32 * (*crvalidate)(struct rpc_task *, u32 *);
+ __be32 * (*crvalidate)(struct rpc_task *, __be32 *);
int (*crwrap_req)(struct rpc_task *, kxdrproc_t,
- void *, u32 *, void *);
+ void *, __be32 *, void *);
int (*crunwrap_resp)(struct rpc_task *, kxdrproc_t,
- void *, u32 *, void *);
+ void *, __be32 *, void *);
};
extern struct rpc_authops authunix_ops;
@@ -134,10 +134,10 @@ struct rpc_cred * rpcauth_bindcred(struct rpc_task *);
void rpcauth_holdcred(struct rpc_task *);
void put_rpccred(struct rpc_cred *);
void rpcauth_unbindcred(struct rpc_task *);
-u32 * rpcauth_marshcred(struct rpc_task *, u32 *);
-u32 * rpcauth_checkverf(struct rpc_task *, u32 *);
-int rpcauth_wrap_req(struct rpc_task *task, kxdrproc_t encode, void *rqstp, u32 *data, void *obj);
-int rpcauth_unwrap_resp(struct rpc_task *task, kxdrproc_t decode, void *rqstp, u32 *data, void *obj);
+__be32 * rpcauth_marshcred(struct rpc_task *, __be32 *);
+__be32 * rpcauth_checkverf(struct rpc_task *, __be32 *);
+int rpcauth_wrap_req(struct rpc_task *task, kxdrproc_t encode, void *rqstp, __be32 *data, void *obj);
+int rpcauth_unwrap_resp(struct rpc_task *task, kxdrproc_t decode, void *rqstp, __be32 *data, void *obj);
int rpcauth_refreshcred(struct rpc_task *);
void rpcauth_invalcred(struct rpc_task *);
int rpcauth_uptodatecred(struct rpc_task *);
diff --git a/include/linux/sunrpc/msg_prot.h b/include/linux/sunrpc/msg_prot.h
index f43f237360ae..d9f5934ac9fe 100644
--- a/include/linux/sunrpc/msg_prot.h
+++ b/include/linux/sunrpc/msg_prot.h
@@ -95,7 +95,7 @@ enum rpc_auth_stat {
* 2GB.
*/
-typedef u32 rpc_fraghdr;
+typedef __be32 rpc_fraghdr;
#define RPC_LAST_STREAM_FRAGMENT (1U << 31)
#define RPC_FRAGMENT_SIZE_MASK (~RPC_LAST_STREAM_FRAGMENT)
diff --git a/include/linux/sunrpc/svc.h b/include/linux/sunrpc/svc.h
index 7b27c09b5604..4ebcdf91f3b3 100644
--- a/include/linux/sunrpc/svc.h
+++ b/include/linux/sunrpc/svc.h
@@ -18,6 +18,30 @@
#include <linux/mm.h>
/*
+ * This is the RPC server thread function prototype
+ */
+typedef void (*svc_thread_fn)(struct svc_rqst *);
+
+/*
+ *
+ * RPC service thread pool.
+ *
+ * Pool of threads and temporary sockets. Generally there is only
+ * a single one of these per RPC service, but on NUMA machines those
+ * services that can benefit from it (i.e. nfs but not lockd) will
+ * have one pool per NUMA node. This optimisation reduces cross-
+ * node traffic on multi-node NUMA NFS servers.
+ */
+struct svc_pool {
+ unsigned int sp_id; /* pool id; also node id on NUMA */
+ spinlock_t sp_lock; /* protects all fields */
+ struct list_head sp_threads; /* idle server threads */
+ struct list_head sp_sockets; /* pending sockets */
+ unsigned int sp_nrthreads; /* # of threads in pool */
+ struct list_head sp_all_threads; /* all server threads */
+} ____cacheline_aligned_in_smp;
+
+/*
* RPC service.
*
* An RPC service is a ``daemon,'' possibly multithreaded, which
@@ -28,8 +52,6 @@
* We currently do not support more than one RPC program per daemon.
*/
struct svc_serv {
- struct list_head sv_threads; /* idle server threads */
- struct list_head sv_sockets; /* pending sockets */
struct svc_program * sv_program; /* RPC program */
struct svc_stat * sv_stats; /* RPC statistics */
spinlock_t sv_lock;
@@ -40,11 +62,36 @@ struct svc_serv {
struct list_head sv_permsocks; /* all permanent sockets */
struct list_head sv_tempsocks; /* all temporary sockets */
int sv_tmpcnt; /* count of temporary sockets */
+ struct timer_list sv_temptimer; /* timer for aging temporary sockets */
char * sv_name; /* service name */
+
+ unsigned int sv_nrpools; /* number of thread pools */
+ struct svc_pool * sv_pools; /* array of thread pools */
+
+ void (*sv_shutdown)(struct svc_serv *serv);
+ /* Callback to use when last thread
+ * exits.
+ */
+
+ struct module * sv_module; /* optional module to count when
+ * adding threads */
+ svc_thread_fn sv_function; /* main function for threads */
+ int sv_kill_signal; /* signal to kill threads */
};
/*
+ * We use sv_nrthreads as a reference count. svc_destroy() drops
+ * this refcount, so we need to bump it up around operations that
+ * change the number of threads. Horrible, but there it is.
+ * Should be called with the BKL held.
+ */
+static inline void svc_get(struct svc_serv *serv)
+{
+ serv->sv_nrthreads++;
+}
+
+/*
* Maximum payload size supported by a kernel RPC server.
* This is use to determine the max number of pages nfsd is
* willing to return in a single READ operation.
@@ -78,28 +125,45 @@ struct svc_serv {
*/
#define RPCSVC_MAXPAGES ((RPCSVC_MAXPAYLOAD+PAGE_SIZE-1)/PAGE_SIZE + 2)
-static inline u32 svc_getu32(struct kvec *iov)
+static inline u32 svc_getnl(struct kvec *iov)
+{
+ __be32 val, *vp;
+ vp = iov->iov_base;
+ val = *vp++;
+ iov->iov_base = (void*)vp;
+ iov->iov_len -= sizeof(__be32);
+ return ntohl(val);
+}
+
+static inline void svc_putnl(struct kvec *iov, u32 val)
{
- u32 val, *vp;
+ __be32 *vp = iov->iov_base + iov->iov_len;
+ *vp = htonl(val);
+ iov->iov_len += sizeof(__be32);
+}
+
+static inline __be32 svc_getu32(struct kvec *iov)
+{
+ __be32 val, *vp;
vp = iov->iov_base;
val = *vp++;
iov->iov_base = (void*)vp;
- iov->iov_len -= sizeof(u32);
+ iov->iov_len -= sizeof(__be32);
return val;
}
static inline void svc_ungetu32(struct kvec *iov)
{
- u32 *vp = (u32 *)iov->iov_base;
+ __be32 *vp = (__be32 *)iov->iov_base;
iov->iov_base = (void *)(vp - 1);
iov->iov_len += sizeof(*vp);
}
-static inline void svc_putu32(struct kvec *iov, u32 val)
+static inline void svc_putu32(struct kvec *iov, __be32 val)
{
- u32 *vp = iov->iov_base + iov->iov_len;
+ __be32 *vp = iov->iov_base + iov->iov_len;
*vp = val;
- iov->iov_len += sizeof(u32);
+ iov->iov_len += sizeof(__be32);
}
@@ -110,11 +174,13 @@ static inline void svc_putu32(struct kvec *iov, u32 val)
*/
struct svc_rqst {
struct list_head rq_list; /* idle list */
+ struct list_head rq_all; /* all threads list */
struct svc_sock * rq_sock; /* socket */
struct sockaddr_in rq_addr; /* peer address */
int rq_addrlen;
struct svc_serv * rq_server; /* RPC service definition */
+ struct svc_pool * rq_pool; /* thread pool */
struct svc_procedure * rq_procinfo; /* procedure info */
struct auth_ops * rq_authop; /* authentication flavour */
struct svc_cred rq_cred; /* auth info */
@@ -130,7 +196,7 @@ struct svc_rqst {
short rq_arghi; /* pages available in argument page list */
short rq_resused; /* pages used for result */
- u32 rq_xid; /* transmission id */
+ __be32 rq_xid; /* transmission id */
u32 rq_prog; /* program number */
u32 rq_vers; /* program version */
u32 rq_proc; /* procedure number */
@@ -139,7 +205,7 @@ struct svc_rqst {
rq_secure : 1; /* secure port */
- __u32 rq_daddr; /* dest addr of request - reply from here */
+ __be32 rq_daddr; /* dest addr of request - reply from here */
void * rq_argp; /* decoded arguments */
void * rq_resp; /* xdr'd results */
@@ -163,13 +229,14 @@ struct svc_rqst {
* to prevent encrypting page
* cache pages */
wait_queue_head_t rq_wait; /* synchronization */
+ struct task_struct *rq_task; /* service thread */
};
/*
* Check buffer bounds after decoding arguments
*/
static inline int
-xdr_argsize_check(struct svc_rqst *rqstp, u32 *p)
+xdr_argsize_check(struct svc_rqst *rqstp, __be32 *p)
{
char *cp = (char *)p;
struct kvec *vec = &rqstp->rq_arg.head[0];
@@ -178,7 +245,7 @@ xdr_argsize_check(struct svc_rqst *rqstp, u32 *p)
}
static inline int
-xdr_ressize_check(struct svc_rqst *rqstp, u32 *p)
+xdr_ressize_check(struct svc_rqst *rqstp, __be32 *p)
{
struct kvec *vec = &rqstp->rq_res.head[0];
char *cp = (char*)p;
@@ -249,10 +316,10 @@ struct svc_deferred_req {
u32 prot; /* protocol (UDP or TCP) */
struct sockaddr_in addr;
struct svc_sock *svsk; /* where reply must go */
- u32 daddr; /* where reply must come from */
+ __be32 daddr; /* where reply must come from */
struct cache_deferred_req handle;
int argslen;
- u32 args[0];
+ __be32 args[0];
};
/*
@@ -284,7 +351,7 @@ struct svc_version {
* A return value of 0 means drop the request.
* vs_dispatch == NULL means use default dispatcher.
*/
- int (*vs_dispatch)(struct svc_rqst *, u32 *);
+ int (*vs_dispatch)(struct svc_rqst *, __be32 *);
};
/*
@@ -304,20 +371,21 @@ struct svc_procedure {
};
/*
- * This is the RPC server thread function prototype
- */
-typedef void (*svc_thread_fn)(struct svc_rqst *);
-
-/*
* Function prototypes.
*/
-struct svc_serv * svc_create(struct svc_program *, unsigned int);
+struct svc_serv * svc_create(struct svc_program *, unsigned int,
+ void (*shutdown)(struct svc_serv*));
int svc_create_thread(svc_thread_fn, struct svc_serv *);
void svc_exit_thread(struct svc_rqst *);
+struct svc_serv * svc_create_pooled(struct svc_program *, unsigned int,
+ void (*shutdown)(struct svc_serv*),
+ svc_thread_fn, int sig, struct module *);
+int svc_set_num_threads(struct svc_serv *, struct svc_pool *, int);
void svc_destroy(struct svc_serv *);
-int svc_process(struct svc_serv *, struct svc_rqst *);
+int svc_process(struct svc_rqst *);
int svc_register(struct svc_serv *, int, unsigned short);
void svc_wake_up(struct svc_serv *);
void svc_reserve(struct svc_rqst *rqstp, int space);
+struct svc_pool * svc_pool_for_cpu(struct svc_serv *serv, int cpu);
#endif /* SUNRPC_SVC_H */
diff --git a/include/linux/sunrpc/svcauth.h b/include/linux/sunrpc/svcauth.h
index 2fe2087edd66..a6601650deeb 100644
--- a/include/linux/sunrpc/svcauth.h
+++ b/include/linux/sunrpc/svcauth.h
@@ -95,7 +95,7 @@ struct auth_ops {
char * name;
struct module *owner;
int flavour;
- int (*accept)(struct svc_rqst *rq, u32 *authp);
+ int (*accept)(struct svc_rqst *rq, __be32 *authp);
int (*release)(struct svc_rqst *rq);
void (*domain_release)(struct auth_domain *);
int (*set_client)(struct svc_rqst *rq);
@@ -112,7 +112,7 @@ struct auth_ops {
#define SVC_COMPLETE 9
-extern int svc_authenticate(struct svc_rqst *rqstp, u32 *authp);
+extern int svc_authenticate(struct svc_rqst *rqstp, __be32 *authp);
extern int svc_authorise(struct svc_rqst *rqstp);
extern int svc_set_client(struct svc_rqst *rqstp);
extern int svc_auth_register(rpc_authflavor_t flavor, struct auth_ops *aops);
diff --git a/include/linux/sunrpc/svcsock.h b/include/linux/sunrpc/svcsock.h
index b4acb3d37c3f..4c296152cbfa 100644
--- a/include/linux/sunrpc/svcsock.h
+++ b/include/linux/sunrpc/svcsock.h
@@ -20,8 +20,9 @@ struct svc_sock {
struct socket * sk_sock; /* berkeley socket layer */
struct sock * sk_sk; /* INET layer */
+ struct svc_pool * sk_pool; /* current pool iff queued */
struct svc_serv * sk_server; /* service for this socket */
- unsigned int sk_inuse; /* use count */
+ atomic_t sk_inuse; /* use count */
unsigned long sk_flags;
#define SK_BUSY 0 /* enqueued/receiving */
#define SK_CONN 1 /* conn pending */
@@ -31,9 +32,12 @@ struct svc_sock {
#define SK_DEAD 6 /* socket closed */
#define SK_CHNGBUF 7 /* need to change snd/rcv buffer sizes */
#define SK_DEFERRED 8 /* request on sk_deferred */
+#define SK_OLD 9 /* used for temp socket aging mark+sweep */
+#define SK_DETACHED 10 /* detached from tempsocks list */
- int sk_reserved; /* space on outq that is reserved */
+ atomic_t sk_reserved; /* space on outq that is reserved */
+ spinlock_t sk_defer_lock; /* protects sk_deferred */
struct list_head sk_deferred; /* deferred requests that need to
* be revisted */
struct mutex sk_mutex; /* to serialize sending data */
@@ -57,9 +61,14 @@ struct svc_sock {
*/
int svc_makesock(struct svc_serv *, int, unsigned short);
void svc_delete_socket(struct svc_sock *);
-int svc_recv(struct svc_serv *, struct svc_rqst *, long);
+int svc_recv(struct svc_rqst *, long);
int svc_send(struct svc_rqst *);
void svc_drop(struct svc_rqst *);
void svc_sock_update_bufs(struct svc_serv *serv);
+int svc_sock_names(char *buf, struct svc_serv *serv, char *toclose);
+int svc_addsock(struct svc_serv *serv,
+ int fd,
+ char *name_return,
+ int *proto);
#endif /* SUNRPC_SVCSOCK_H */
diff --git a/include/linux/sunrpc/xdr.h b/include/linux/sunrpc/xdr.h
index e6d3d349506c..953723b09bc6 100644
--- a/include/linux/sunrpc/xdr.h
+++ b/include/linux/sunrpc/xdr.h
@@ -32,7 +32,7 @@ struct xdr_netobj {
* side) or svc_rqst pointer (server side).
* Encode functions always assume there's enough room in the buffer.
*/
-typedef int (*kxdrproc_t)(void *rqstp, u32 *data, void *obj);
+typedef int (*kxdrproc_t)(void *rqstp, __be32 *data, void *obj);
/*
* Basic structure for transmission/reception of a client XDR message.
@@ -88,19 +88,19 @@ struct xdr_buf {
/*
* Miscellaneous XDR helper functions
*/
-u32 * xdr_encode_opaque_fixed(u32 *p, const void *ptr, unsigned int len);
-u32 * xdr_encode_opaque(u32 *p, const void *ptr, unsigned int len);
-u32 * xdr_encode_string(u32 *p, const char *s);
-u32 * xdr_decode_string_inplace(u32 *p, char **sp, int *lenp, int maxlen);
-u32 * xdr_encode_netobj(u32 *p, const struct xdr_netobj *);
-u32 * xdr_decode_netobj(u32 *p, struct xdr_netobj *);
+__be32 *xdr_encode_opaque_fixed(__be32 *p, const void *ptr, unsigned int len);
+__be32 *xdr_encode_opaque(__be32 *p, const void *ptr, unsigned int len);
+__be32 *xdr_encode_string(__be32 *p, const char *s);
+__be32 *xdr_decode_string_inplace(__be32 *p, char **sp, int *lenp, int maxlen);
+__be32 *xdr_encode_netobj(__be32 *p, const struct xdr_netobj *);
+__be32 *xdr_decode_netobj(__be32 *p, struct xdr_netobj *);
void xdr_encode_pages(struct xdr_buf *, struct page **, unsigned int,
unsigned int);
void xdr_inline_pages(struct xdr_buf *, unsigned int,
struct page **, unsigned int, unsigned int);
-static inline u32 *xdr_encode_array(u32 *p, const void *s, unsigned int len)
+static inline __be32 *xdr_encode_array(__be32 *p, const void *s, unsigned int len)
{
return xdr_encode_opaque(p, s, len);
}
@@ -108,16 +108,16 @@ static inline u32 *xdr_encode_array(u32 *p, const void *s, unsigned int len)
/*
* Decode 64bit quantities (NFSv3 support)
*/
-static inline u32 *
-xdr_encode_hyper(u32 *p, __u64 val)
+static inline __be32 *
+xdr_encode_hyper(__be32 *p, __u64 val)
{
*p++ = htonl(val >> 32);
*p++ = htonl(val & 0xFFFFFFFF);
return p;
}
-static inline u32 *
-xdr_decode_hyper(u32 *p, __u64 *valp)
+static inline __be32 *
+xdr_decode_hyper(__be32 *p, __u64 *valp)
{
*valp = ((__u64) ntohl(*p++)) << 32;
*valp |= ntohl(*p++);
@@ -128,7 +128,7 @@ xdr_decode_hyper(u32 *p, __u64 *valp)
* Adjust kvec to reflect end of xdr'ed data (RPC client XDR)
*/
static inline int
-xdr_adjust_iovec(struct kvec *iov, u32 *p)
+xdr_adjust_iovec(struct kvec *iov, __be32 *p)
{
return iov->iov_len = ((u8 *) p - (u8 *) iov->iov_base);
}
@@ -180,19 +180,19 @@ extern int xdr_encode_array2(struct xdr_buf *buf, unsigned int base,
* Provide some simple tools for XDR buffer overflow-checking etc.
*/
struct xdr_stream {
- uint32_t *p; /* start of available buffer */
+ __be32 *p; /* start of available buffer */
struct xdr_buf *buf; /* XDR buffer to read/write */
- uint32_t *end; /* end of available buffer space */
+ __be32 *end; /* end of available buffer space */
struct kvec *iov; /* pointer to the current kvec */
};
-extern void xdr_init_encode(struct xdr_stream *xdr, struct xdr_buf *buf, uint32_t *p);
-extern uint32_t *xdr_reserve_space(struct xdr_stream *xdr, size_t nbytes);
+extern void xdr_init_encode(struct xdr_stream *xdr, struct xdr_buf *buf, __be32 *p);
+extern __be32 *xdr_reserve_space(struct xdr_stream *xdr, size_t nbytes);
extern void xdr_write_pages(struct xdr_stream *xdr, struct page **pages,
unsigned int base, unsigned int len);
-extern void xdr_init_decode(struct xdr_stream *xdr, struct xdr_buf *buf, uint32_t *p);
-extern uint32_t *xdr_inline_decode(struct xdr_stream *xdr, size_t nbytes);
+extern void xdr_init_decode(struct xdr_stream *xdr, struct xdr_buf *buf, __be32 *p);
+extern __be32 *xdr_inline_decode(struct xdr_stream *xdr, size_t nbytes);
extern void xdr_read_pages(struct xdr_stream *xdr, unsigned int len);
extern void xdr_enter_page(struct xdr_stream *xdr, unsigned int len);
diff --git a/include/linux/sunrpc/xprt.h b/include/linux/sunrpc/xprt.h
index bdeba8538c71..6cf626580752 100644
--- a/include/linux/sunrpc/xprt.h
+++ b/include/linux/sunrpc/xprt.h
@@ -79,7 +79,7 @@ struct rpc_rqst {
* This is the private part
*/
struct rpc_task * rq_task; /* RPC task data */
- __u32 rq_xid; /* request XID */
+ __be32 rq_xid; /* request XID */
int rq_cong; /* has incremented xprt->cong */
int rq_received; /* receive completed */
u32 rq_seqno; /* gss seq no. used on req. */
@@ -171,9 +171,9 @@ struct rpc_xprt {
/*
* State of TCP reply receive stuff
*/
- u32 tcp_recm, /* Fragment header */
- tcp_xid, /* Current XID */
- tcp_reclen, /* fragment length */
+ __be32 tcp_recm, /* Fragment header */
+ tcp_xid; /* Current XID */
+ u32 tcp_reclen, /* fragment length */
tcp_offset; /* fragment offset */
unsigned long tcp_copied, /* copied to request */
tcp_flags;
@@ -253,7 +253,7 @@ void xprt_release(struct rpc_task *task);
struct rpc_xprt * xprt_get(struct rpc_xprt *xprt);
void xprt_put(struct rpc_xprt *xprt);
-static inline u32 *xprt_skip_transport_header(struct rpc_xprt *xprt, u32 *p)
+static inline __be32 *xprt_skip_transport_header(struct rpc_xprt *xprt, __be32 *p)
{
return p + xprt->tsh_size;
}
@@ -268,7 +268,7 @@ void xprt_wait_for_buffer_space(struct rpc_task *task);
void xprt_write_space(struct rpc_xprt *xprt);
void xprt_update_rtt(struct rpc_task *task);
void xprt_adjust_cwnd(struct rpc_task *task, int result);
-struct rpc_rqst * xprt_lookup_rqst(struct rpc_xprt *xprt, u32 xid);
+struct rpc_rqst * xprt_lookup_rqst(struct rpc_xprt *xprt, __be32 xid);
void xprt_complete_rqst(struct rpc_task *task, int copied);
void xprt_release_rqst_cong(struct rpc_task *task);
void xprt_disconnect(struct rpc_xprt *xprt);
diff --git a/include/linux/synclink.h b/include/linux/synclink.h
index 0577f5284cbc..c8b042667af1 100644
--- a/include/linux/synclink.h
+++ b/include/linux/synclink.h
@@ -1,7 +1,7 @@
/*
* SyncLink Multiprotocol Serial Adapter Driver
*
- * $Id: synclink.h,v 3.13 2006/05/23 18:25:06 paulkf Exp $
+ * $Id: synclink.h,v 3.14 2006/07/17 20:15:43 paulkf Exp $
*
* Copyright (C) 1998-2000 by Microgate Corporation
*
@@ -124,6 +124,8 @@
#define MGSL_MODE_ASYNC 1
#define MGSL_MODE_HDLC 2
+#define MGSL_MODE_MONOSYNC 3
+#define MGSL_MODE_BISYNC 4
#define MGSL_MODE_RAW 6
#define MGSL_BUS_TYPE_ISA 1
diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h
index 3f0f716225ec..3efcfc7e9c6c 100644
--- a/include/linux/syscalls.h
+++ b/include/linux/syscalls.h
@@ -597,6 +597,8 @@ asmlinkage long sys_get_robust_list(int pid,
size_t __user *len_ptr);
asmlinkage long sys_set_robust_list(struct robust_list_head __user *head,
size_t len);
-asmlinkage long sys_getcpu(unsigned *cpu, unsigned *node, struct getcpu_cache *cache);
+asmlinkage long sys_getcpu(unsigned __user *cpu, unsigned __user *node, struct getcpu_cache __user *cache);
+
+int kernel_execve(const char *filename, char *const argv[], char *const envp[]);
#endif
diff --git a/include/linux/sysrq.h b/include/linux/sysrq.h
index 4812ff60561c..e657e523b9bf 100644
--- a/include/linux/sysrq.h
+++ b/include/linux/sysrq.h
@@ -11,6 +11,8 @@
* based upon discusions in irc://irc.openprojects.net/#kernelnewbies
*/
+#ifndef _LINUX_SYSRQ_H
+#define _LINUX_SYSRQ_H
struct pt_regs;
struct tty_struct;
@@ -57,3 +59,5 @@ static inline int __reterr(void)
#define unregister_sysrq_key(ig,nore) __reterr()
#endif
+
+#endif /* _LINUX_SYSRQ_H */
diff --git a/include/linux/taskstats.h b/include/linux/taskstats.h
index f1cb6cddd19d..45248806ae9c 100644
--- a/include/linux/taskstats.h
+++ b/include/linux/taskstats.h
@@ -2,6 +2,7 @@
*
* Copyright (C) Shailabh Nagar, IBM Corp. 2006
* (C) Balbir Singh, IBM Corp. 2006
+ * (C) Jay Lan, SGI, 2006
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2.1 of the GNU Lesser General Public License
@@ -29,16 +30,25 @@
* c) add new fields after version comment; maintain 64-bit alignment
*/
-#define TASKSTATS_VERSION 1
+
+#define TASKSTATS_VERSION 2
+#define TS_COMM_LEN 32 /* should be >= TASK_COMM_LEN
+ * in linux/sched.h */
struct taskstats {
- /* Version 1 */
+ /* The version number of this struct. This field is always set to
+ * TAKSTATS_VERSION, which is defined in <linux/taskstats.h>.
+ * Each time the struct is changed, the value should be incremented.
+ */
__u16 version;
- __u16 padding[3]; /* Userspace should not interpret the padding
- * field which can be replaced by useful
- * fields if struct taskstats is extended.
- */
+ __u32 ac_exitcode; /* Exit status */
+
+ /* The accounting flags of a task as defined in <linux/acct.h>
+ * Defined values are AFORK, ASU, ACOMPAT, ACORE, and AXSIG.
+ */
+ __u8 ac_flag; /* Record flags */
+ __u8 ac_nice; /* task_nice */
/* Delay accounting fields start
*
@@ -88,6 +98,48 @@ struct taskstats {
__u64 cpu_run_virtual_total;
/* Delay accounting fields end */
/* version 1 ends here */
+
+ /* Basic Accounting Fields start */
+ char ac_comm[TS_COMM_LEN]; /* Command name */
+ __u8 ac_sched; /* Scheduling discipline */
+ __u8 ac_pad[3];
+ __u32 ac_uid; /* User ID */
+ __u32 ac_gid; /* Group ID */
+ __u32 ac_pid; /* Process ID */
+ __u32 ac_ppid; /* Parent process ID */
+ __u32 ac_btime; /* Begin time [sec since 1970] */
+ __u64 ac_etime; /* Elapsed time [usec] */
+ __u64 ac_utime; /* User CPU time [usec] */
+ __u64 ac_stime; /* SYstem CPU time [usec] */
+ __u64 ac_minflt; /* Minor Page Fault Count */
+ __u64 ac_majflt; /* Major Page Fault Count */
+ /* Basic Accounting Fields end */
+
+ /* Extended accounting fields start */
+ /* Accumulated RSS usage in duration of a task, in MBytes-usecs.
+ * The current rss usage is added to this counter every time
+ * a tick is charged to a task's system time. So, at the end we
+ * will have memory usage multiplied by system time. Thus an
+ * average usage per system time unit can be calculated.
+ */
+ __u64 coremem; /* accumulated RSS usage in MB-usec */
+ /* Accumulated virtual memory usage in duration of a task.
+ * Same as acct_rss_mem1 above except that we keep track of VM usage.
+ */
+ __u64 virtmem; /* accumulated VM usage in MB-usec */
+
+ /* High watermark of RSS and virtual memory usage in duration of
+ * a task, in KBytes.
+ */
+ __u64 hiwater_rss; /* High-watermark of RSS usage, in KB */
+ __u64 hiwater_vm; /* High-water VM usage, in KB */
+
+ /* The following four fields are I/O statistics of a task. */
+ __u64 read_char; /* bytes read */
+ __u64 write_char; /* bytes written */
+ __u64 read_syscalls; /* read syscalls */
+ __u64 write_syscalls; /* write syscalls */
+ /* Extended accounting fields end */
};
diff --git a/include/linux/tcp.h b/include/linux/tcp.h
index 8ebf497907f8..0e058a2d1c6d 100644
--- a/include/linux/tcp.h
+++ b/include/linux/tcp.h
@@ -21,10 +21,10 @@
#include <asm/byteorder.h>
struct tcphdr {
- __u16 source;
- __u16 dest;
- __u32 seq;
- __u32 ack_seq;
+ __be16 source;
+ __be16 dest;
+ __be32 seq;
+ __be32 ack_seq;
#if defined(__LITTLE_ENDIAN_BITFIELD)
__u16 res1:4,
doff:4,
@@ -50,9 +50,9 @@ struct tcphdr {
#else
#error "Adjust your <asm/byteorder.h> defines"
#endif
- __u16 window;
- __u16 check;
- __u16 urg_ptr;
+ __be16 window;
+ __be16 check;
+ __be16 urg_ptr;
};
/*
@@ -62,7 +62,7 @@ struct tcphdr {
*/
union tcp_word_hdr {
struct tcphdr hdr;
- __u32 words[5];
+ __be32 words[5];
};
#define tcp_flag_word(tp) ( ((union tcp_word_hdr *)(tp))->words [3])
@@ -166,6 +166,11 @@ struct tcp_info
#include <net/inet_timewait_sock.h>
/* This defines a selective acknowledgement block. */
+struct tcp_sack_block_wire {
+ __be32 start_seq;
+ __be32 end_seq;
+};
+
struct tcp_sack_block {
__u32 start_seq;
__u32 end_seq;
@@ -211,7 +216,7 @@ struct tcp_sock {
* Header prediction flags
* 0x5?10 << 16 + snd_wnd in net byte order
*/
- __u32 pred_flags;
+ __be32 pred_flags;
/*
* RFC793 variables by their proper names. This means you can
diff --git a/include/linux/timex.h b/include/linux/timex.h
index d543d3871e38..049dfe4a11f2 100644
--- a/include/linux/timex.h
+++ b/include/linux/timex.h
@@ -69,34 +69,28 @@
* zero to MAXTC, the PLL will converge in 15 minutes to 16 hours,
* respectively.
*/
-#define SHIFT_KG 6 /* phase factor (shift) */
-#define SHIFT_KF 16 /* PLL frequency factor (shift) */
-#define SHIFT_KH 2 /* FLL frequency factor (shift) */
-#define MAXTC 6 /* maximum time constant (shift) */
+#define SHIFT_PLL 4 /* PLL frequency factor (shift) */
+#define SHIFT_FLL 2 /* FLL frequency factor (shift) */
+#define MAXTC 10 /* maximum time constant (shift) */
/*
- * The SHIFT_SCALE define establishes the decimal point of the time_phase
- * variable which serves as an extension to the low-order bits of the
- * system clock variable. The SHIFT_UPDATE define establishes the decimal
- * point of the time_offset variable which represents the current offset
- * with respect to standard time. The FINENSEC define represents 1 nsec in
- * scaled units.
+ * The SHIFT_UPDATE define establishes the decimal point of the
+ * time_offset variable which represents the current offset with
+ * respect to standard time.
*
* SHIFT_USEC defines the scaling (shift) of the time_freq and
* time_tolerance variables, which represent the current frequency
* offset and maximum frequency tolerance.
- *
- * FINENSEC is 1 ns in SHIFT_UPDATE units of the time_phase variable.
*/
-#define SHIFT_SCALE 22 /* phase scale (shift) */
-#define SHIFT_UPDATE (SHIFT_KG + MAXTC) /* time offset scale (shift) */
+#define SHIFT_UPDATE (SHIFT_HZ + 1) /* time offset scale (shift) */
#define SHIFT_USEC 16 /* frequency offset scale (shift) */
-#define FINENSEC (1L << (SHIFT_SCALE - 10)) /* ~1 ns in phase units */
+#define SHIFT_NSEC 12 /* kernel frequency offset scale */
#define MAXPHASE 512000L /* max phase error (us) */
#define MAXFREQ (512L << SHIFT_USEC) /* max frequency error (ppm) */
-#define MINSEC 16L /* min interval between updates (s) */
-#define MAXSEC 1200L /* max interval between updates (s) */
+#define MAXFREQ_NSEC (512000L << SHIFT_NSEC) /* max frequency error (ppb) */
+#define MINSEC 256 /* min interval between updates (s) */
+#define MAXSEC 2048 /* max interval between updates (s) */
#define NTP_PHASE_LIMIT (MAXPHASE << 5) /* beyond max. dispersion */
/*
@@ -204,33 +198,15 @@ extern int tickadj; /* amount of adjustment per tick */
/*
* phase-lock loop variables
*/
-extern int time_state; /* clock status */
extern int time_status; /* clock synchronization status bits */
-extern long time_offset; /* time adjustment (us) */
-extern long time_constant; /* pll time constant */
-extern long time_tolerance; /* frequency tolerance (ppm) */
-extern long time_precision; /* clock precision (us) */
extern long time_maxerror; /* maximum error */
extern long time_esterror; /* estimated error */
extern long time_freq; /* frequency offset (scaled ppm) */
-extern long time_reftime; /* time at last adjustment (s) */
extern long time_adjust; /* The amount of adjtime left */
-extern long time_next_adjust; /* Value for time_adjust at next tick */
-/**
- * ntp_clear - Clears the NTP state variables
- *
- * Must be called while holding a write on the xtime_lock
- */
-static inline void ntp_clear(void)
-{
- time_adjust = 0; /* stop active adjtime() */
- time_status |= STA_UNSYNC;
- time_maxerror = NTP_PHASE_LIMIT;
- time_esterror = NTP_PHASE_LIMIT;
-}
+extern void ntp_clear(void);
/**
* ntp_synced - Returns 1 if the NTP status is not UNSYNC
@@ -294,11 +270,15 @@ extern void register_time_interpolator(struct time_interpolator *);
extern void unregister_time_interpolator(struct time_interpolator *);
extern void time_interpolator_reset(void);
extern unsigned long time_interpolator_get_offset(void);
+extern void time_interpolator_update(long delta_nsec);
#else /* !CONFIG_TIME_INTERPOLATION */
-static inline void
-time_interpolator_reset(void)
+static inline void time_interpolator_reset(void)
+{
+}
+
+static inline void time_interpolator_update(long delta_nsec)
{
}
@@ -309,6 +289,8 @@ time_interpolator_reset(void)
/* Returns how long ticks are at present, in ns / 2^(SHIFT_SCALE-10). */
extern u64 current_tick_length(void);
+extern void second_overflow(void);
+extern void update_ntp_one_tick(void);
extern int do_adjtimex(struct timex *);
#endif /* KERNEL */
diff --git a/include/linux/topology.h b/include/linux/topology.h
index ec1eca85290a..da508d1998e4 100644
--- a/include/linux/topology.h
+++ b/include/linux/topology.h
@@ -89,6 +89,7 @@
#define SD_SIBLING_INIT (struct sched_domain) { \
.span = CPU_MASK_NONE, \
.parent = NULL, \
+ .child = NULL, \
.groups = NULL, \
.min_interval = 1, \
.max_interval = 2, \
@@ -114,11 +115,44 @@
#endif
#endif /* CONFIG_SCHED_SMT */
+#ifdef CONFIG_SCHED_MC
+/* Common values for MC siblings. for now mostly derived from SD_CPU_INIT */
+#ifndef SD_MC_INIT
+#define SD_MC_INIT (struct sched_domain) { \
+ .span = CPU_MASK_NONE, \
+ .parent = NULL, \
+ .child = NULL, \
+ .groups = NULL, \
+ .min_interval = 1, \
+ .max_interval = 4, \
+ .busy_factor = 64, \
+ .imbalance_pct = 125, \
+ .cache_nice_tries = 1, \
+ .per_cpu_gain = 100, \
+ .busy_idx = 2, \
+ .idle_idx = 1, \
+ .newidle_idx = 2, \
+ .wake_idx = 1, \
+ .forkexec_idx = 1, \
+ .flags = SD_LOAD_BALANCE \
+ | SD_BALANCE_NEWIDLE \
+ | SD_BALANCE_EXEC \
+ | SD_WAKE_AFFINE \
+ | SD_SHARE_PKG_RESOURCES\
+ | BALANCE_FOR_MC_POWER, \
+ .last_balance = jiffies, \
+ .balance_interval = 1, \
+ .nr_balance_failed = 0, \
+}
+#endif
+#endif /* CONFIG_SCHED_MC */
+
/* Common values for CPUs */
#ifndef SD_CPU_INIT
#define SD_CPU_INIT (struct sched_domain) { \
.span = CPU_MASK_NONE, \
.parent = NULL, \
+ .child = NULL, \
.groups = NULL, \
.min_interval = 1, \
.max_interval = 4, \
@@ -135,7 +169,7 @@
| SD_BALANCE_NEWIDLE \
| SD_BALANCE_EXEC \
| SD_WAKE_AFFINE \
- | BALANCE_FOR_POWER, \
+ | BALANCE_FOR_PKG_POWER,\
.last_balance = jiffies, \
.balance_interval = 1, \
.nr_balance_failed = 0, \
@@ -146,6 +180,7 @@
#define SD_ALLNODES_INIT (struct sched_domain) { \
.span = CPU_MASK_NONE, \
.parent = NULL, \
+ .child = NULL, \
.groups = NULL, \
.min_interval = 64, \
.max_interval = 64*num_online_cpus(), \
@@ -165,15 +200,6 @@
.nr_balance_failed = 0, \
}
-#ifdef CONFIG_SCHED_MC
-#ifndef SD_MC_INIT
-/* for now its same as SD_CPU_INIT.
- * TBD: Tune Domain parameters!
- */
-#define SD_MC_INIT SD_CPU_INIT
-#endif
-#endif
-
#ifdef CONFIG_NUMA
#ifndef SD_NODE_INIT
#error Please define an appropriate SD_NODE_INIT in include/asm/topology.h!!!
diff --git a/include/linux/trdevice.h b/include/linux/trdevice.h
index 99e02ef54c47..bfc84a7aecc5 100644
--- a/include/linux/trdevice.h
+++ b/include/linux/trdevice.h
@@ -28,7 +28,7 @@
#include <linux/if_tr.h>
#ifdef __KERNEL__
-extern unsigned short tr_type_trans(struct sk_buff *skb, struct net_device *dev);
+extern __be16 tr_type_trans(struct sk_buff *skb, struct net_device *dev);
extern void tr_source_route(struct sk_buff *skb, struct trh_hdr *trh, struct net_device *dev);
extern struct net_device *alloc_trdev(int sizeof_priv);
diff --git a/include/linux/tsacct_kern.h b/include/linux/tsacct_kern.h
new file mode 100644
index 000000000000..7e50ac795b0b
--- /dev/null
+++ b/include/linux/tsacct_kern.h
@@ -0,0 +1,34 @@
+/*
+ * tsacct_kern.h - kernel header for system accounting over taskstats interface
+ *
+ * Copyright (C) Jay Lan SGI
+ */
+
+#ifndef _LINUX_TSACCT_KERN_H
+#define _LINUX_TSACCT_KERN_H
+
+#include <linux/taskstats.h>
+
+#ifdef CONFIG_TASKSTATS
+extern void bacct_add_tsk(struct taskstats *stats, struct task_struct *tsk);
+#else
+static inline void bacct_add_tsk(struct taskstats *stats, struct task_struct *tsk)
+{}
+#endif /* CONFIG_TASKSTATS */
+
+#ifdef CONFIG_TASK_XACCT
+extern void xacct_add_tsk(struct taskstats *stats, struct task_struct *p);
+extern void acct_update_integrals(struct task_struct *tsk);
+extern void acct_clear_integrals(struct task_struct *tsk);
+#else
+static inline void xacct_add_tsk(struct taskstats *stats, struct task_struct *p)
+{}
+static inline void acct_update_integrals(struct task_struct *tsk)
+{}
+static inline void acct_clear_integrals(struct task_struct *tsk)
+{}
+#endif /* CONFIG_TASK_XACCT */
+
+#endif
+
+
diff --git a/include/linux/tty.h b/include/linux/tty.h
index 04827ca65781..44091c0db0b4 100644
--- a/include/linux/tty.h
+++ b/include/linux/tty.h
@@ -174,7 +174,7 @@ struct tty_struct {
struct tty_driver *driver;
int index;
struct tty_ldisc ldisc;
- struct semaphore termios_sem;
+ struct mutex termios_mutex;
struct termios *termios, *termios_locked;
char name[64];
int pgrp;
@@ -190,7 +190,6 @@ struct tty_struct {
struct tty_struct *link;
struct fasync_struct *fasync;
struct tty_bufhead buf;
- int max_flip_cnt;
int alt_speed; /* For magic substitution of 38400 bps */
wait_queue_head_t write_wait;
wait_queue_head_t read_wait;
@@ -308,6 +307,9 @@ extern void tty_ldisc_put(int);
extern void tty_wakeup(struct tty_struct *tty);
extern void tty_ldisc_flush(struct tty_struct *tty);
+extern int tty_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
+ unsigned long arg);
+
extern struct mutex tty_mutex;
/* n_tty.c */
diff --git a/include/linux/tty_driver.h b/include/linux/tty_driver.h
index 58c961c9e170..5c8473bb6882 100644
--- a/include/linux/tty_driver.h
+++ b/include/linux/tty_driver.h
@@ -219,7 +219,8 @@ extern struct list_head tty_drivers;
struct tty_driver *alloc_tty_driver(int lines);
void put_tty_driver(struct tty_driver *driver);
-void tty_set_operations(struct tty_driver *driver, struct tty_operations *op);
+void tty_set_operations(struct tty_driver *driver,
+ const struct tty_operations *op);
/* tty driver magic number */
#define TTY_DRIVER_MAGIC 0x5402
diff --git a/include/linux/types.h b/include/linux/types.h
index 3f235660a3cd..406d4ae57631 100644
--- a/include/linux/types.h
+++ b/include/linux/types.h
@@ -33,6 +33,8 @@ typedef __kernel_clockid_t clockid_t;
typedef __kernel_mqd_t mqd_t;
#ifdef __KERNEL__
+typedef _Bool bool;
+
typedef __kernel_uid32_t uid_t;
typedef __kernel_gid32_t gid_t;
typedef __kernel_uid16_t uid16_t;
diff --git a/include/linux/udp.h b/include/linux/udp.h
index 90223f057d50..014b41d1e308 100644
--- a/include/linux/udp.h
+++ b/include/linux/udp.h
@@ -20,10 +20,10 @@
#include <linux/types.h>
struct udphdr {
- __u16 source;
- __u16 dest;
- __u16 len;
- __u16 check;
+ __be16 source;
+ __be16 dest;
+ __be16 len;
+ __be16 check;
};
/* UDP socket options */
diff --git a/include/linux/uinput.h b/include/linux/uinput.h
index 7168302f9844..1fd61eeed664 100644
--- a/include/linux/uinput.h
+++ b/include/linux/uinput.h
@@ -22,12 +22,18 @@
* Author: Aristeu Sergio Rozanski Filho <aris@cathedrallabs.org>
*
* Changes/Revisions:
+ * 0.3 24/05/2006 (Anssi Hannula <anssi.hannulagmail.com>)
+ * - update ff support for the changes in kernel interface
+ * - add UINPUT_VERSION
* 0.2 16/10/2004 (Micah Dowty <micah@navi.cx>)
* - added force feedback support
* - added UI_SET_PHYS
* 0.1 20/06/2002
* - first public version
*/
+
+#define UINPUT_VERSION 3
+
#ifdef __KERNEL__
#define UINPUT_MINOR 223
#define UINPUT_NAME "uinput"
@@ -45,7 +51,10 @@ struct uinput_request {
union {
int effect_id;
- struct ff_effect* effect;
+ struct {
+ struct ff_effect *effect;
+ struct ff_effect *old;
+ } upload;
} u;
};
@@ -58,6 +67,7 @@ struct uinput_device {
unsigned char head;
unsigned char tail;
struct input_event buff[UINPUT_BUFFER_SIZE];
+ int ff_effects_max;
struct uinput_request *requests[UINPUT_NUM_REQUESTS];
wait_queue_head_t requests_waitq;
@@ -69,6 +79,7 @@ struct uinput_ff_upload {
int request_id;
int retval;
struct ff_effect effect;
+ struct ff_effect old;
};
struct uinput_ff_erase {
@@ -98,33 +109,33 @@ struct uinput_ff_erase {
#define UI_BEGIN_FF_ERASE _IOWR(UINPUT_IOCTL_BASE, 202, struct uinput_ff_erase)
#define UI_END_FF_ERASE _IOW(UINPUT_IOCTL_BASE, 203, struct uinput_ff_erase)
-/* To write a force-feedback-capable driver, the upload_effect
+/*
+ * To write a force-feedback-capable driver, the upload_effect
* and erase_effect callbacks in input_dev must be implemented.
* The uinput driver will generate a fake input event when one of
* these callbacks are invoked. The userspace code then uses
* ioctls to retrieve additional parameters and send the return code.
* The callback blocks until this return code is sent.
*
- * The described callback mechanism is only used if EV_FF is set.
- * Otherwise, default implementations of upload_effect and erase_effect
- * are used.
+ * The described callback mechanism is only used if ff_effects_max
+ * is set.
*
* To implement upload_effect():
- * 1. Wait for an event with type==EV_UINPUT and code==UI_FF_UPLOAD.
+ * 1. Wait for an event with type == EV_UINPUT and code == UI_FF_UPLOAD.
* A request ID will be given in 'value'.
* 2. Allocate a uinput_ff_upload struct, fill in request_id with
* the 'value' from the EV_UINPUT event.
* 3. Issue a UI_BEGIN_FF_UPLOAD ioctl, giving it the
* uinput_ff_upload struct. It will be filled in with the
- * ff_effect passed to upload_effect().
- * 4. Perform the effect upload, and place the modified ff_effect
- * and a return code back into the uinput_ff_upload struct.
+ * ff_effects passed to upload_effect().
+ * 4. Perform the effect upload, and place a return code back into
+ the uinput_ff_upload struct.
* 5. Issue a UI_END_FF_UPLOAD ioctl, also giving it the
* uinput_ff_upload_effect struct. This will complete execution
* of our upload_effect() handler.
*
* To implement erase_effect():
- * 1. Wait for an event with type==EV_UINPUT and code==UI_FF_ERASE.
+ * 1. Wait for an event with type == EV_UINPUT and code == UI_FF_ERASE.
* A request ID will be given in 'value'.
* 2. Allocate a uinput_ff_erase struct, fill in request_id with
* the 'value' from the EV_UINPUT event.
@@ -133,13 +144,13 @@ struct uinput_ff_erase {
* effect ID passed to erase_effect().
* 4. Perform the effect erasure, and place a return code back
* into the uinput_ff_erase struct.
- * and a return code back into the uinput_ff_erase struct.
* 5. Issue a UI_END_FF_ERASE ioctl, also giving it the
* uinput_ff_erase_effect struct. This will complete execution
* of our erase_effect() handler.
*/
-/* This is the new event type, used only by uinput.
+/*
+ * This is the new event type, used only by uinput.
* 'code' is UI_FF_UPLOAD or UI_FF_ERASE, and 'value'
* is the unique request ID. This number was picked
* arbitrarily, above EV_MAX (since the input system
diff --git a/include/linux/unistd.h b/include/linux/unistd.h
index c18c60f3254e..aa8d5b5e2e3e 100644
--- a/include/linux/unistd.h
+++ b/include/linux/unistd.h
@@ -1,12 +1,8 @@
#ifndef _LINUX_UNISTD_H_
#define _LINUX_UNISTD_H_
-#ifdef __KERNEL__
-extern int errno;
-#endif
-
/*
- * Include machine specific syscallX macros
+ * Include machine specific syscall numbers
*/
#include <asm/unistd.h>
diff --git a/include/linux/unwind.h b/include/linux/unwind.h
index ce48e2cd37a2..73e1751d03dd 100644
--- a/include/linux/unwind.h
+++ b/include/linux/unwind.h
@@ -12,8 +12,6 @@
* is not much point in implementing the full Dwarf2 unwind API.
*/
-#include <linux/config.h>
-
struct module;
#ifdef CONFIG_STACK_UNWIND
diff --git a/include/linux/utime.h b/include/linux/utime.h
index c6bf27b7897e..640be6a1959e 100644
--- a/include/linux/utime.h
+++ b/include/linux/utime.h
@@ -1,6 +1,8 @@
#ifndef _LINUX_UTIME_H
#define _LINUX_UTIME_H
+#include <linux/types.h>
+
struct utimbuf {
time_t actime;
time_t modtime;
diff --git a/include/linux/utsname.h b/include/linux/utsname.h
index 13e1da0c538d..02e4b6972064 100644
--- a/include/linux/utsname.h
+++ b/include/linux/utsname.h
@@ -1,6 +1,11 @@
#ifndef _LINUX_UTSNAME_H
#define _LINUX_UTSNAME_H
+#include <linux/sched.h>
+#include <linux/kref.h>
+#include <linux/nsproxy.h>
+#include <asm/atomic.h>
+
#define __OLD_UTS_LEN 8
struct oldold_utsname {
@@ -30,7 +35,55 @@ struct new_utsname {
char domainname[65];
};
-extern struct new_utsname system_utsname;
+struct uts_namespace {
+ struct kref kref;
+ struct new_utsname name;
+};
+extern struct uts_namespace init_uts_ns;
+
+static inline void get_uts_ns(struct uts_namespace *ns)
+{
+ kref_get(&ns->kref);
+}
+
+#ifdef CONFIG_UTS_NS
+extern int unshare_utsname(unsigned long unshare_flags,
+ struct uts_namespace **new_uts);
+extern int copy_utsname(int flags, struct task_struct *tsk);
+extern void free_uts_ns(struct kref *kref);
+
+static inline void put_uts_ns(struct uts_namespace *ns)
+{
+ kref_put(&ns->kref, free_uts_ns);
+}
+#else
+static inline int unshare_utsname(unsigned long unshare_flags,
+ struct uts_namespace **new_uts)
+{
+ if (unshare_flags & CLONE_NEWUTS)
+ return -EINVAL;
+
+ return 0;
+}
+
+static inline int copy_utsname(int flags, struct task_struct *tsk)
+{
+ return 0;
+}
+static inline void put_uts_ns(struct uts_namespace *ns)
+{
+}
+#endif
+
+static inline struct new_utsname *utsname(void)
+{
+ return &current->nsproxy->uts_ns->name;
+}
+
+static inline struct new_utsname *init_utsname(void)
+{
+ return &init_uts_ns.name;
+}
extern struct rw_semaphore uts_sem;
#endif
diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h
index e3715d774197..44c59da26ed2 100644
--- a/include/linux/videodev2.h
+++ b/include/linux/videodev2.h
@@ -1135,7 +1135,8 @@ struct v4l2_sliced_vbi_cap
(equals frame lines 313-336 for 625 line video
standards, 263-286 for 525 line standards) */
__u16 service_lines[2][24];
- __u32 reserved[4]; /* must be 0 */
+ enum v4l2_buf_type type;
+ __u32 reserved[3]; /* must be 0 */
};
struct v4l2_sliced_vbi_data
@@ -1242,7 +1243,7 @@ struct v4l2_streamparm
#define VIDIOC_G_PRIORITY _IOR ('V', 67, enum v4l2_priority)
#define VIDIOC_S_PRIORITY _IOW ('V', 68, enum v4l2_priority)
#if 1
-#define VIDIOC_G_SLICED_VBI_CAP _IOR ('V', 69, struct v4l2_sliced_vbi_cap)
+#define VIDIOC_G_SLICED_VBI_CAP _IOWR ('V', 69, struct v4l2_sliced_vbi_cap)
#endif
#define VIDIOC_LOG_STATUS _IO ('V', 70)
#define VIDIOC_G_EXT_CTRLS _IOWR ('V', 71, struct v4l2_ext_controls)
diff --git a/include/linux/vmstat.h b/include/linux/vmstat.h
index 176c7f797339..c89df55f6e03 100644
--- a/include/linux/vmstat.h
+++ b/include/linux/vmstat.h
@@ -3,7 +3,6 @@
#include <linux/types.h>
#include <linux/percpu.h>
-#include <linux/config.h>
#include <linux/mmzone.h>
#include <asm/atomic.h>
diff --git a/include/linux/vt_kern.h b/include/linux/vt_kern.h
index 918a29763aea..37a1a41f5b65 100644
--- a/include/linux/vt_kern.h
+++ b/include/linux/vt_kern.h
@@ -33,7 +33,8 @@ extern int fg_console, last_console, want_console;
int vc_allocate(unsigned int console);
int vc_cons_allocated(unsigned int console);
int vc_resize(struct vc_data *vc, unsigned int cols, unsigned int lines);
-void vc_disallocate(unsigned int console);
+int vc_lock_resize(struct vc_data *vc, unsigned int cols, unsigned int lines);
+void vc_deallocate(unsigned int console);
void reset_palette(struct vc_data *vc);
void do_blank_screen(int entering_gfx);
void do_unblank_screen(int leaving_gfx);
@@ -83,4 +84,11 @@ void reset_vc(struct vc_data *vc);
extern char con_buf[CON_BUF_SIZE];
extern struct semaphore con_buf_sem;
+struct vt_spawn_console {
+ spinlock_t lock;
+ struct pid *pid;
+ int sig;
+};
+extern struct vt_spawn_console vt_spawn_con;
+
#endif /* _VT_KERN_H */
diff --git a/include/linux/writeback.h b/include/linux/writeback.h
index 56a23a0e7f2e..4f4d98addb44 100644
--- a/include/linux/writeback.h
+++ b/include/linux/writeback.h
@@ -111,12 +111,15 @@ balance_dirty_pages_ratelimited(struct address_space *mapping)
}
int pdflush_operation(void (*fn)(unsigned long), unsigned long arg0);
+extern int generic_writepages(struct address_space *mapping,
+ struct writeback_control *wbc);
int do_writepages(struct address_space *mapping, struct writeback_control *wbc);
int sync_page_range(struct inode *inode, struct address_space *mapping,
loff_t pos, loff_t count);
int sync_page_range_nolock(struct inode *inode, struct address_space *mapping,
loff_t pos, loff_t count);
void set_page_dirty_balance(struct page *page);
+void writeback_set_ratelimit(void);
/* pdflush.c */
extern int nr_pdflush_threads; /* Global so it can be exported to sysctl
diff --git a/include/linux/xfrm.h b/include/linux/xfrm.h
index 14ecd19f4cdc..430afd058269 100644
--- a/include/linux/xfrm.h
+++ b/include/linux/xfrm.h
@@ -12,8 +12,8 @@
*/
typedef union
{
- __u32 a4;
- __u32 a6[4];
+ __be32 a4;
+ __be32 a6[4];
} xfrm_address_t;
/* Ident of a specific xfrm_state. It is used on input to lookup
@@ -23,7 +23,7 @@ typedef union
struct xfrm_id
{
xfrm_address_t daddr;
- __u32 spi;
+ __be32 spi;
__u8 proto;
};
@@ -49,10 +49,10 @@ struct xfrm_selector
{
xfrm_address_t daddr;
xfrm_address_t saddr;
- __u16 dport;
- __u16 dport_mask;
- __u16 sport;
- __u16 sport_mask;
+ __be16 dport;
+ __be16 dport_mask;
+ __be16 sport;
+ __be16 sport_mask;
__u16 family;
__u8 prefixlen_d;
__u8 prefixlen_s;
@@ -281,7 +281,7 @@ struct xfrm_usersa_info {
struct xfrm_usersa_id {
xfrm_address_t daddr;
- __u32 spi;
+ __be32 spi;
__u16 family;
__u8 proto;
};
diff --git a/include/media/ir-common.h b/include/media/ir-common.h
index 7bab09b0ed45..8f58406533c6 100644
--- a/include/media/ir-common.h
+++ b/include/media/ir-common.h
@@ -90,6 +90,8 @@ extern IR_KEYTAB_TYPE ir_codes_winfast[IR_KEYTAB_SIZE];
extern IR_KEYTAB_TYPE ir_codes_pinnacle_color[IR_KEYTAB_SIZE];
extern IR_KEYTAB_TYPE ir_codes_hauppauge_new[IR_KEYTAB_SIZE];
extern IR_KEYTAB_TYPE ir_codes_npgtech[IR_KEYTAB_SIZE];
+extern IR_KEYTAB_TYPE ir_codes_norwood[IR_KEYTAB_SIZE];
+extern IR_KEYTAB_TYPE ir_codes_proteus_2309[IR_KEYTAB_SIZE];
#endif
diff --git a/include/media/tuner-types.h b/include/media/tuner-types.h
index 3c43b95f4c0d..37dad07a8439 100644
--- a/include/media/tuner-types.h
+++ b/include/media/tuner-types.h
@@ -72,6 +72,9 @@ struct tuner_params {
unsigned int port2_invert_for_secam_lc:1;
/* Some cards require PORT1 to be 1 for mono Radio FM and 0 for stereo. */
unsigned int port1_set_for_fm_mono:1;
+ /* Select 18% (or according to datasheet 0%) L standard PLL gating,
+ vs the driver default of 36%. */
+ unsigned int default_pll_gating_18:1;
/* Default tda9887 TOP value in dB for the low band. Default is 0.
Range: -16:+15 */
signed int default_top_low:5;
diff --git a/include/media/tuner.h b/include/media/tuner.h
index 2f7b00b08e88..3116e750132f 100644
--- a/include/media/tuner.h
+++ b/include/media/tuner.h
@@ -144,6 +144,7 @@ extern int tuner_debug;
#define TDA9887_DEEMPHASIS_50 (2<<16)
#define TDA9887_DEEMPHASIS_75 (3<<16)
#define TDA9887_AUTOMUTE (1<<18)
+#define TDA9887_GATING_18 (1<<19)
#ifdef __KERNEL__
diff --git a/include/media/v4l2-common.h b/include/media/v4l2-common.h
index 5564db13c0d5..aecc946980a3 100644
--- a/include/media/v4l2-common.h
+++ b/include/media/v4l2-common.h
@@ -121,10 +121,17 @@ enum v4l2_chip_ident {
/* general idents: reserved range 0-49 */
V4L2_IDENT_UNKNOWN = 0,
- /* module saa7115: reserved range 100-149 */
+ /* module saa7110: just ident= 100 */
+ V4L2_IDENT_SAA7110 = 100,
+
+ /* module saa7111: just ident= 101 */
+ V4L2_IDENT_SAA7111 = 101,
+
+ /* module saa7115: reserved range 102-149 */
V4L2_IDENT_SAA7113 = 103,
V4L2_IDENT_SAA7114 = 104,
V4L2_IDENT_SAA7115 = 105,
+ V4L2_IDENT_SAA7118 = 108,
/* module saa7127: reserved range 150-199 */
V4L2_IDENT_SAA7127 = 157,
@@ -166,11 +173,12 @@ enum v4l2_chip_ident {
#define VIDIOC_INT_S_STANDBY _IOW('d', 94, u32)
/* only implemented if CONFIG_VIDEO_ADV_DEBUG is defined */
-#define VIDIOC_INT_S_REGISTER _IOR ('d', 100, struct v4l2_register)
+#define VIDIOC_INT_S_REGISTER _IOW ('d', 100, struct v4l2_register)
#define VIDIOC_INT_G_REGISTER _IOWR('d', 101, struct v4l2_register)
-/* Reset the I2C chip */
-#define VIDIOC_INT_RESET _IO ('d', 102)
+/* Generic reset command. The argument selects which subsystems to reset.
+ Passing 0 will always reset the whole chip. */
+#define VIDIOC_INT_RESET _IOW ('d', 102, u32)
/* Set the frequency (in Hz) of the audio clock output.
Used to slave an audio processor to the video decoder, ensuring that audio
diff --git a/include/media/v4l2-dev.h b/include/media/v4l2-dev.h
index bb495b7f4680..6a11d772700f 100644
--- a/include/media/v4l2-dev.h
+++ b/include/media/v4l2-dev.h
@@ -9,7 +9,8 @@
#ifndef _V4L2_DEV_H
#define _V4L2_DEV_H
-#define OBSOLETE_OWNER 1 /* to be removed soon */
+#define OBSOLETE_OWNER 1 /* to be removed soon */
+#define OBSOLETE_DEVDATA 1 /* to be removed soon */
#include <linux/poll.h>
#include <linux/fs.h>
@@ -338,8 +339,6 @@ extern int video_usercopy(struct inode *inode, struct file *file,
#ifdef CONFIG_VIDEO_V4L1_COMPAT
#include <linux/mm.h>
-extern struct video_device* video_devdata(struct file*);
-
#define to_video_device(cd) container_of(cd, struct video_device, class_dev)
static inline int __must_check
video_device_create_file(struct video_device *vfd,
@@ -370,9 +369,14 @@ static inline void video_set_drvdata(struct video_device *dev, void *data)
{
dev->priv = data;
}
+
#endif
+#ifdef OBSOLETE_DEVDATA /* to be removed soon */
+/* Obsolete stuff - Still needed for radio devices and obsolete drivers */
+extern struct video_device* video_devdata(struct file*);
extern int video_exclusive_open(struct inode *inode, struct file *file);
extern int video_exclusive_release(struct inode *inode, struct file *file);
+#endif
#endif /* _V4L2_DEV_H */
diff --git a/include/mtd/Kbuild b/include/mtd/Kbuild
index 13e7a3c6d794..e0fe92b03a4e 100644
--- a/include/mtd/Kbuild
+++ b/include/mtd/Kbuild
@@ -1,6 +1,5 @@
header-y += inftl-user.h
header-y += jffs2-user.h
+header-y += mtd-abi.h
header-y += mtd-user.h
header-y += nftl-user.h
-
-unifdef-y += mtd-abi.h
diff --git a/include/mtd/mtd-abi.h b/include/mtd/mtd-abi.h
index b0a67b7ffdcd..f913c30d7b89 100644
--- a/include/mtd/mtd-abi.h
+++ b/include/mtd/mtd-abi.h
@@ -7,12 +7,6 @@
#ifndef __MTD_ABI_H__
#define __MTD_ABI_H__
-#ifndef __KERNEL__
-/* Urgh. The whole point of splitting this out into
- separate files was to avoid #ifdef __KERNEL__ */
-#define __user
-#endif
-
struct erase_info_user {
uint32_t start;
uint32_t length;
diff --git a/include/net/arp.h b/include/net/arp.h
index 643bded9f557..6a3d9a7d302b 100644
--- a/include/net/arp.h
+++ b/include/net/arp.h
@@ -12,15 +12,15 @@ extern struct neigh_table arp_tbl;
extern void arp_init(void);
extern int arp_find(unsigned char *haddr, struct sk_buff *skb);
extern int arp_ioctl(unsigned int cmd, void __user *arg);
-extern void arp_send(int type, int ptype, u32 dest_ip,
- struct net_device *dev, u32 src_ip,
+extern void arp_send(int type, int ptype, __be32 dest_ip,
+ struct net_device *dev, __be32 src_ip,
unsigned char *dest_hw, unsigned char *src_hw, unsigned char *th);
extern int arp_bind_neighbour(struct dst_entry *dst);
extern int arp_mc_map(u32 addr, u8 *haddr, struct net_device *dev, int dir);
extern void arp_ifdown(struct net_device *dev);
-extern struct sk_buff *arp_create(int type, int ptype, u32 dest_ip,
- struct net_device *dev, u32 src_ip,
+extern struct sk_buff *arp_create(int type, int ptype, __be32 dest_ip,
+ struct net_device *dev, __be32 src_ip,
unsigned char *dest_hw, unsigned char *src_hw,
unsigned char *target_hw);
extern void arp_xmit(struct sk_buff *skb);
diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h
index b2bdb1aa0429..10a3eec191fd 100644
--- a/include/net/bluetooth/hci.h
+++ b/include/net/bluetooth/hci.h
@@ -44,12 +44,13 @@
#define HCI_NOTIFY_VOICE_SETTING 3
/* HCI device types */
-#define HCI_VHCI 0
+#define HCI_VIRTUAL 0
#define HCI_USB 1
#define HCI_PCCARD 2
#define HCI_UART 3
#define HCI_RS232 4
#define HCI_PCI 5
+#define HCI_SDIO 6
/* HCI device quirks */
enum {
@@ -296,6 +297,7 @@ struct hci_cp_host_buffer_size {
/* Link Control */
#define OGF_LINK_CTL 0x01
+
#define OCF_CREATE_CONN 0x0005
struct hci_cp_create_conn {
bdaddr_t bdaddr;
@@ -306,6 +308,11 @@ struct hci_cp_create_conn {
__u8 role_switch;
} __attribute__ ((packed));
+#define OCF_CREATE_CONN_CANCEL 0x0008
+struct hci_cp_create_conn_cancel {
+ bdaddr_t bdaddr;
+} __attribute__ ((packed));
+
#define OCF_ACCEPT_CONN_REQ 0x0009
struct hci_cp_accept_conn_req {
bdaddr_t bdaddr;
@@ -339,6 +346,8 @@ struct hci_cp_inquiry {
#define OCF_INQUIRY_CANCEL 0x0002
+#define OCF_EXIT_PERIODIC_INQ 0x0004
+
#define OCF_LINK_KEY_REPLY 0x000B
struct hci_cp_link_key_reply {
bdaddr_t bdaddr;
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index d84855fe7336..df22efcfcc0b 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -72,6 +72,9 @@ struct hci_dev {
__u8 type;
bdaddr_t bdaddr;
__u8 features[8];
+ __u8 hci_ver;
+ __u16 hci_rev;
+ __u16 manufacturer;
__u16 voice_setting;
__u16 pkt_type;
@@ -165,6 +168,10 @@ struct hci_conn {
struct timer_list disc_timer;
struct timer_list idle_timer;
+ struct work_struct work;
+
+ struct device dev;
+
struct hci_dev *hdev;
void *l2cap_data;
void *sco_data;
@@ -309,10 +316,13 @@ static inline void hci_conn_put(struct hci_conn *conn)
if (atomic_dec_and_test(&conn->refcnt)) {
unsigned long timeo;
if (conn->type == ACL_LINK) {
- timeo = msecs_to_jiffies(HCI_DISCONN_TIMEOUT);
- if (!conn->out)
- timeo *= 2;
del_timer(&conn->idle_timer);
+ if (conn->state == BT_CONNECTED) {
+ timeo = msecs_to_jiffies(HCI_DISCONN_TIMEOUT);
+ if (!conn->out)
+ timeo *= 2;
+ } else
+ timeo = msecs_to_jiffies(10);
} else
timeo = msecs_to_jiffies(10);
mod_timer(&conn->disc_timer, jiffies + timeo);
@@ -412,6 +422,8 @@ static inline int hci_recv_frame(struct sk_buff *skb)
int hci_register_sysfs(struct hci_dev *hdev);
void hci_unregister_sysfs(struct hci_dev *hdev);
+void hci_conn_add_sysfs(struct hci_conn *conn);
+void hci_conn_del_sysfs(struct hci_conn *conn);
#define SET_HCIDEV_DEV(hdev, pdev) ((hdev)->parent = (pdev))
diff --git a/include/net/cipso_ipv4.h b/include/net/cipso_ipv4.h
index 2d72496c2029..718b4d9c891f 100644
--- a/include/net/cipso_ipv4.h
+++ b/include/net/cipso_ipv4.h
@@ -128,7 +128,9 @@ extern int cipso_v4_rbm_strictvalid;
#ifdef CONFIG_NETLABEL
int cipso_v4_doi_add(struct cipso_v4_doi *doi_def);
-int cipso_v4_doi_remove(u32 doi, void (*callback) (struct rcu_head * head));
+int cipso_v4_doi_remove(u32 doi,
+ struct netlbl_audit *audit_info,
+ void (*callback) (struct rcu_head * head));
struct cipso_v4_doi *cipso_v4_doi_getdef(u32 doi);
int cipso_v4_doi_walk(u32 *skip_cnt,
int (*callback) (struct cipso_v4_doi *doi_def, void *arg),
@@ -143,6 +145,7 @@ static inline int cipso_v4_doi_add(struct cipso_v4_doi *doi_def)
}
static inline int cipso_v4_doi_remove(u32 doi,
+ struct netlbl_audit *audit_info,
void (*callback) (struct rcu_head * head))
{
return 0;
diff --git a/include/net/dst.h b/include/net/dst.h
index a8d825f90305..e156e38e4ac3 100644
--- a/include/net/dst.h
+++ b/include/net/dst.h
@@ -84,7 +84,7 @@ struct dst_entry
struct dst_ops
{
unsigned short family;
- unsigned short protocol;
+ __be16 protocol;
unsigned gc_thresh;
int (*gc)(void);
diff --git a/include/net/flow.h b/include/net/flow.h
index 3ca210ec1379..ddf5f3ca1720 100644
--- a/include/net/flow.h
+++ b/include/net/flow.h
@@ -16,8 +16,8 @@ struct flowi {
union {
struct {
- __u32 daddr;
- __u32 saddr;
+ __be32 daddr;
+ __be32 saddr;
__u32 fwmark;
__u8 tos;
__u8 scope;
@@ -56,8 +56,8 @@ struct flowi {
#define FLOWI_FLAG_MULTIPATHOLDROUTE 0x01
union {
struct {
- __u16 sport;
- __u16 dport;
+ __be16 sport;
+ __be16 dport;
} ports;
struct {
@@ -73,7 +73,7 @@ struct flowi {
__u8 objname[16]; /* Not zero terminated */
} dnports;
- __u32 spi;
+ __be32 spi;
#ifdef CONFIG_IPV6_MIP6
struct {
diff --git a/include/net/genetlink.h b/include/net/genetlink.h
index 4a38d85e4e25..b619314218a6 100644
--- a/include/net/genetlink.h
+++ b/include/net/genetlink.h
@@ -169,4 +169,22 @@ static inline int genlmsg_len(const struct genlmsghdr *gnlh)
return (nlh->nlmsg_len - GENL_HDRLEN - NLMSG_HDRLEN);
}
+/**
+ * genlmsg_msg_size - length of genetlink message not including padding
+ * @payload: length of message payload
+ */
+static inline int genlmsg_msg_size(int payload)
+{
+ return GENL_HDRLEN + payload;
+}
+
+/**
+ * genlmsg_total_size - length of genetlink message including padding
+ * @payload: length of message payload
+ */
+static inline int genlmsg_total_size(int payload)
+{
+ return NLMSG_ALIGN(genlmsg_msg_size(payload));
+}
+
#endif /* __NET_GENERIC_NETLINK_H */
diff --git a/include/net/icmp.h b/include/net/icmp.h
index 05f8ff7d9316..dc09474efcf3 100644
--- a/include/net/icmp.h
+++ b/include/net/icmp.h
@@ -38,7 +38,7 @@ struct dst_entry;
struct net_proto_family;
struct sk_buff;
-extern void icmp_send(struct sk_buff *skb_in, int type, int code, u32 info);
+extern void icmp_send(struct sk_buff *skb_in, int type, int code, __be32 info);
extern int icmp_rcv(struct sk_buff *skb);
extern int icmp_ioctl(struct sock *sk, int cmd, unsigned long arg);
extern void icmp_init(struct net_proto_family *ops);
diff --git a/include/net/inet_connection_sock.h b/include/net/inet_connection_sock.h
index de4e83b6da4b..0bcf9f237e1f 100644
--- a/include/net/inet_connection_sock.h
+++ b/include/net/inet_connection_sock.h
@@ -238,9 +238,9 @@ extern struct sock *inet_csk_accept(struct sock *sk, int flags, int *err);
extern struct request_sock *inet_csk_search_req(const struct sock *sk,
struct request_sock ***prevp,
- const __u16 rport,
- const __u32 raddr,
- const __u32 laddr);
+ const __be16 rport,
+ const __be32 raddr,
+ const __be32 laddr);
extern int inet_csk_bind_conflict(const struct sock *sk,
const struct inet_bind_bucket *tb);
extern int inet_csk_get_port(struct inet_hashinfo *hashinfo,
diff --git a/include/net/inet_hashtables.h b/include/net/inet_hashtables.h
index b4491c9e2a5a..a9eb2eaf094e 100644
--- a/include/net/inet_hashtables.h
+++ b/include/net/inet_hashtables.h
@@ -272,42 +272,56 @@ static inline int inet_iif(const struct sk_buff *skb)
}
extern struct sock *__inet_lookup_listener(struct inet_hashinfo *hashinfo,
- const u32 daddr,
+ const __be32 daddr,
const unsigned short hnum,
const int dif);
static inline struct sock *inet_lookup_listener(struct inet_hashinfo *hashinfo,
- u32 daddr, u16 dport, int dif)
+ __be32 daddr, __be16 dport, int dif)
{
return __inet_lookup_listener(hashinfo, daddr, ntohs(dport), dif);
}
/* Socket demux engine toys. */
+/* What happens here is ugly; there's a pair of adjacent fields in
+ struct inet_sock; __be16 dport followed by __u16 num. We want to
+ search by pair, so we combine the keys into a single 32bit value
+ and compare with 32bit value read from &...->dport. Let's at least
+ make sure that it's not mixed with anything else...
+ On 64bit targets we combine comparisons with pair of adjacent __be32
+ fields in the same way.
+*/
+typedef __u32 __bitwise __portpair;
#ifdef __BIG_ENDIAN
#define INET_COMBINED_PORTS(__sport, __dport) \
- (((__u32)(__sport) << 16) | (__u32)(__dport))
+ ((__force __portpair)(((__force __u32)(__be16)(__sport) << 16) | (__u32)(__dport)))
#else /* __LITTLE_ENDIAN */
#define INET_COMBINED_PORTS(__sport, __dport) \
- (((__u32)(__dport) << 16) | (__u32)(__sport))
+ ((__force __portpair)(((__u32)(__dport) << 16) | (__force __u32)(__be16)(__sport)))
#endif
#if (BITS_PER_LONG == 64)
+typedef __u64 __bitwise __addrpair;
#ifdef __BIG_ENDIAN
#define INET_ADDR_COOKIE(__name, __saddr, __daddr) \
- const __u64 __name = (((__u64)(__saddr)) << 32) | ((__u64)(__daddr));
+ const __addrpair __name = (__force __addrpair) ( \
+ (((__force __u64)(__be32)(__saddr)) << 32) | \
+ ((__force __u64)(__be32)(__daddr)));
#else /* __LITTLE_ENDIAN */
#define INET_ADDR_COOKIE(__name, __saddr, __daddr) \
- const __u64 __name = (((__u64)(__daddr)) << 32) | ((__u64)(__saddr));
+ const __addrpair __name = (__force __addrpair) ( \
+ (((__force __u64)(__be32)(__daddr)) << 32) | \
+ ((__force __u64)(__be32)(__saddr)));
#endif /* __BIG_ENDIAN */
#define INET_MATCH(__sk, __hash, __cookie, __saddr, __daddr, __ports, __dif)\
(((__sk)->sk_hash == (__hash)) && \
- ((*((__u64 *)&(inet_sk(__sk)->daddr))) == (__cookie)) && \
- ((*((__u32 *)&(inet_sk(__sk)->dport))) == (__ports)) && \
+ ((*((__addrpair *)&(inet_sk(__sk)->daddr))) == (__cookie)) && \
+ ((*((__portpair *)&(inet_sk(__sk)->dport))) == (__ports)) && \
(!((__sk)->sk_bound_dev_if) || ((__sk)->sk_bound_dev_if == (__dif))))
#define INET_TW_MATCH(__sk, __hash, __cookie, __saddr, __daddr, __ports, __dif)\
(((__sk)->sk_hash == (__hash)) && \
- ((*((__u64 *)&(inet_twsk(__sk)->tw_daddr))) == (__cookie)) && \
- ((*((__u32 *)&(inet_twsk(__sk)->tw_dport))) == (__ports)) && \
+ ((*((__addrpair *)&(inet_twsk(__sk)->tw_daddr))) == (__cookie)) && \
+ ((*((__portpair *)&(inet_twsk(__sk)->tw_dport))) == (__ports)) && \
(!((__sk)->sk_bound_dev_if) || ((__sk)->sk_bound_dev_if == (__dif))))
#else /* 32-bit arch */
#define INET_ADDR_COOKIE(__name, __saddr, __daddr)
@@ -315,13 +329,13 @@ static inline struct sock *inet_lookup_listener(struct inet_hashinfo *hashinfo,
(((__sk)->sk_hash == (__hash)) && \
(inet_sk(__sk)->daddr == (__saddr)) && \
(inet_sk(__sk)->rcv_saddr == (__daddr)) && \
- ((*((__u32 *)&(inet_sk(__sk)->dport))) == (__ports)) && \
+ ((*((__portpair *)&(inet_sk(__sk)->dport))) == (__ports)) && \
(!((__sk)->sk_bound_dev_if) || ((__sk)->sk_bound_dev_if == (__dif))))
#define INET_TW_MATCH(__sk, __hash,__cookie, __saddr, __daddr, __ports, __dif) \
(((__sk)->sk_hash == (__hash)) && \
(inet_twsk(__sk)->tw_daddr == (__saddr)) && \
(inet_twsk(__sk)->tw_rcv_saddr == (__daddr)) && \
- ((*((__u32 *)&(inet_twsk(__sk)->tw_dport))) == (__ports)) && \
+ ((*((__portpair *)&(inet_twsk(__sk)->tw_dport))) == (__ports)) && \
(!((__sk)->sk_bound_dev_if) || ((__sk)->sk_bound_dev_if == (__dif))))
#endif /* 64-bit arch */
@@ -333,12 +347,12 @@ static inline struct sock *inet_lookup_listener(struct inet_hashinfo *hashinfo,
*/
static inline struct sock *
__inet_lookup_established(struct inet_hashinfo *hashinfo,
- const u32 saddr, const u16 sport,
- const u32 daddr, const u16 hnum,
+ const __be32 saddr, const __be16 sport,
+ const __be32 daddr, const u16 hnum,
const int dif)
{
INET_ADDR_COOKIE(acookie, saddr, daddr)
- const __u32 ports = INET_COMBINED_PORTS(sport, hnum);
+ const __portpair ports = INET_COMBINED_PORTS(sport, hnum);
struct sock *sk;
const struct hlist_node *node;
/* Optimize here for direct hit, only listening connections can
@@ -370,8 +384,8 @@ hit:
static inline struct sock *
inet_lookup_established(struct inet_hashinfo *hashinfo,
- const u32 saddr, const u16 sport,
- const u32 daddr, const u16 dport,
+ const __be32 saddr, const __be16 sport,
+ const __be32 daddr, const __be16 dport,
const int dif)
{
return __inet_lookup_established(hashinfo, saddr, sport, daddr,
@@ -379,8 +393,8 @@ static inline struct sock *
}
static inline struct sock *__inet_lookup(struct inet_hashinfo *hashinfo,
- const u32 saddr, const u16 sport,
- const u32 daddr, const u16 dport,
+ const __be32 saddr, const __be16 sport,
+ const __be32 daddr, const __be16 dport,
const int dif)
{
u16 hnum = ntohs(dport);
@@ -390,8 +404,8 @@ static inline struct sock *__inet_lookup(struct inet_hashinfo *hashinfo,
}
static inline struct sock *inet_lookup(struct inet_hashinfo *hashinfo,
- const u32 saddr, const u16 sport,
- const u32 daddr, const u16 dport,
+ const __be32 saddr, const __be16 sport,
+ const __be32 daddr, const __be16 dport,
const int dif)
{
struct sock *sk;
diff --git a/include/net/inet_sock.h b/include/net/inet_sock.h
index f6242710f2ff..ce6da97bc848 100644
--- a/include/net/inet_sock.h
+++ b/include/net/inet_sock.h
@@ -36,7 +36,7 @@
* @ts_needaddr - Need to record addr of outgoing dev
*/
struct ip_options {
- __u32 faddr;
+ __be32 faddr;
unsigned char optlen;
unsigned char srr;
unsigned char rr;
@@ -62,9 +62,9 @@ struct inet_request_sock {
u16 inet6_rsk_offset;
/* 2 bytes hole, try to pack */
#endif
- u32 loc_addr;
- u32 rmt_addr;
- u16 rmt_port;
+ __be32 loc_addr;
+ __be32 rmt_addr;
+ __be16 rmt_port;
u16 snd_wscale : 4,
rcv_wscale : 4,
tstamp_ok : 1,
@@ -110,15 +110,15 @@ struct inet_sock {
struct ipv6_pinfo *pinet6;
#endif
/* Socket demultiplex comparisons on incoming packets. */
- __u32 daddr;
- __u32 rcv_saddr;
- __u16 dport;
+ __be32 daddr;
+ __be32 rcv_saddr;
+ __be16 dport;
__u16 num;
- __u32 saddr;
+ __be32 saddr;
__s16 uc_ttl;
__u16 cmsg_flags;
struct ip_options *opt;
- __u16 sport;
+ __be16 sport;
__u16 id;
__u8 tos;
__u8 mc_ttl;
@@ -129,7 +129,7 @@ struct inet_sock {
hdrincl:1,
mc_loop:1;
int mc_index;
- __u32 mc_addr;
+ __be32 mc_addr;
struct ip_mc_socklist *mc_list;
struct {
unsigned int flags;
@@ -137,7 +137,7 @@ struct inet_sock {
struct ip_options *opt;
struct rtable *rt;
int length; /* Total length of all frames */
- u32 addr;
+ __be32 addr;
struct flowi fl;
} cork;
};
@@ -167,10 +167,10 @@ static inline void inet_sk_copy_descendant(struct sock *sk_to,
extern int inet_sk_rebuild_header(struct sock *sk);
-static inline unsigned int inet_ehashfn(const __u32 laddr, const __u16 lport,
- const __u32 faddr, const __u16 fport)
+static inline unsigned int inet_ehashfn(const __be32 laddr, const __u16 lport,
+ const __be32 faddr, const __be16 fport)
{
- unsigned int h = (laddr ^ lport) ^ (faddr ^ fport);
+ unsigned int h = ((__force __u32)laddr ^ lport) ^ ((__force __u32)faddr ^ (__force __u32)fport);
h ^= h >> 16;
h ^= h >> 8;
return h;
@@ -179,10 +179,10 @@ static inline unsigned int inet_ehashfn(const __u32 laddr, const __u16 lport,
static inline int inet_sk_ehashfn(const struct sock *sk)
{
const struct inet_sock *inet = inet_sk(sk);
- const __u32 laddr = inet->rcv_saddr;
+ const __be32 laddr = inet->rcv_saddr;
const __u16 lport = inet->num;
- const __u32 faddr = inet->daddr;
- const __u16 fport = inet->dport;
+ const __be32 faddr = inet->daddr;
+ const __be16 fport = inet->dport;
return inet_ehashfn(laddr, lport, faddr, fport);
}
diff --git a/include/net/inet_timewait_sock.h b/include/net/inet_timewait_sock.h
index 600cb543550d..6d14c22a00c5 100644
--- a/include/net/inet_timewait_sock.h
+++ b/include/net/inet_timewait_sock.h
@@ -120,10 +120,10 @@ struct inet_timewait_sock {
unsigned char tw_rcv_wscale;
/* Socket demultiplex comparisons on incoming packets. */
/* these five are in inet_sock */
- __u16 tw_sport;
- __u32 tw_daddr __attribute__((aligned(INET_TIMEWAIT_ADDRCMP_ALIGN_BYTES)));
- __u32 tw_rcv_saddr;
- __u16 tw_dport;
+ __be16 tw_sport;
+ __be32 tw_daddr __attribute__((aligned(INET_TIMEWAIT_ADDRCMP_ALIGN_BYTES)));
+ __be32 tw_rcv_saddr;
+ __be16 tw_dport;
__u16 tw_num;
/* And these are ours. */
__u8 tw_ipv6only:1;
@@ -186,7 +186,7 @@ static inline struct inet_timewait_sock *inet_twsk(const struct sock *sk)
return (struct inet_timewait_sock *)sk;
}
-static inline u32 inet_rcv_saddr(const struct sock *sk)
+static inline __be32 inet_rcv_saddr(const struct sock *sk)
{
return likely(sk->sk_state != TCP_TIME_WAIT) ?
inet_sk(sk)->rcv_saddr : inet_twsk(sk)->tw_rcv_saddr;
diff --git a/include/net/inetpeer.h b/include/net/inetpeer.h
index 0965515f40cf..925573fd2aed 100644
--- a/include/net/inetpeer.h
+++ b/include/net/inetpeer.h
@@ -22,7 +22,7 @@ struct inet_peer
unsigned long dtime; /* the time of last use of not
* referenced entries */
atomic_t refcnt;
- __u32 v4daddr; /* peer's address */
+ __be32 v4daddr; /* peer's address */
__u16 avl_height;
__u16 ip_id_count; /* IP ID for the next packet */
atomic_t rid; /* Frag reception counter */
@@ -33,7 +33,7 @@ struct inet_peer
void inet_initpeers(void) __init;
/* can be called with or without local BH being disabled */
-struct inet_peer *inet_getpeer(__u32 daddr, int create);
+struct inet_peer *inet_getpeer(__be32 daddr, int create);
extern spinlock_t inet_peer_unused_lock;
extern struct inet_peer **inet_peer_unused_tailp;
diff --git a/include/net/ip.h b/include/net/ip.h
index 98f908400771..b6d95e553401 100644
--- a/include/net/ip.h
+++ b/include/net/ip.h
@@ -45,7 +45,7 @@ struct inet_skb_parm
struct ipcm_cookie
{
- u32 addr;
+ __be32 addr;
int oif;
struct ip_options *opt;
};
@@ -86,7 +86,7 @@ extern int igmp_mc_proc_init(void);
*/
extern int ip_build_and_send_pkt(struct sk_buff *skb, struct sock *sk,
- u32 saddr, u32 daddr,
+ __be32 saddr, __be32 daddr,
struct ip_options *opt);
extern int ip_rcv(struct sk_buff *skb, struct net_device *dev,
struct packet_type *pt, struct net_device *orig_dev);
@@ -335,7 +335,7 @@ extern int ip_net_unreachable(struct sk_buff *skb);
* Functions provided by ip_options.c
*/
-extern void ip_options_build(struct sk_buff *skb, struct ip_options *opt, u32 daddr, struct rtable *rt, int is_frag);
+extern void ip_options_build(struct sk_buff *skb, struct ip_options *opt, __be32 daddr, struct rtable *rt, int is_frag);
extern int ip_options_echo(struct ip_options *dopt, struct sk_buff *skb);
extern void ip_options_fragment(struct sk_buff *skb);
extern int ip_options_compile(struct ip_options *opt, struct sk_buff *skb);
@@ -363,8 +363,8 @@ extern int ip_ra_control(struct sock *sk, unsigned char on, void (*destructor)(s
extern int ip_recv_error(struct sock *sk, struct msghdr *msg, int len);
extern void ip_icmp_error(struct sock *sk, struct sk_buff *skb, int err,
- u16 port, u32 info, u8 *payload);
-extern void ip_local_error(struct sock *sk, int err, u32 daddr, u16 dport,
+ __be16 port, u32 info, u8 *payload);
+extern void ip_local_error(struct sock *sk, int err, __be32 daddr, __be16 dport,
u32 info);
/* sysctl helpers - any sysctl which holds a value that ends up being
diff --git a/include/net/ip_fib.h b/include/net/ip_fib.h
index fcc159a4ac17..82229146bac7 100644
--- a/include/net/ip_fib.h
+++ b/include/net/ip_fib.h
@@ -30,13 +30,13 @@ struct fib_config {
u8 fc_type;
/* 1 byte unused */
u32 fc_table;
- u32 fc_dst;
- u32 fc_src;
- u32 fc_gw;
+ __be32 fc_dst;
+ __be32 fc_src;
+ __be32 fc_gw;
int fc_oif;
u32 fc_flags;
u32 fc_priority;
- u32 fc_prefsrc;
+ __be32 fc_prefsrc;
struct nlattr *fc_mx;
struct rtnexthop *fc_mp;
int fc_mx_len;
@@ -63,7 +63,7 @@ struct fib_nh {
__u32 nh_tclassid;
#endif
int nh_oif;
- u32 nh_gw;
+ __be32 nh_gw;
};
/*
@@ -78,7 +78,7 @@ struct fib_info {
int fib_dead;
unsigned fib_flags;
int fib_protocol;
- u32 fib_prefsrc;
+ __be32 fib_prefsrc;
u32 fib_priority;
u32 fib_metrics[RTAX_MAX];
#define fib_mtu fib_metrics[RTAX_MTU-1]
@@ -107,8 +107,8 @@ struct fib_result {
unsigned char type;
unsigned char scope;
#ifdef CONFIG_IP_ROUTE_MULTIPATH_CACHED
- __u32 network;
- __u32 netmask;
+ __be32 network;
+ __be32 netmask;
#endif
struct fib_info *fi;
#ifdef CONFIG_IP_MULTIPLE_TABLES
@@ -117,7 +117,7 @@ struct fib_result {
};
struct fib_result_nl {
- u32 fl_addr; /* To be looked up*/
+ __be32 fl_addr; /* To be looked up*/
u32 fl_fwmark;
unsigned char fl_tos;
unsigned char fl_scope;
@@ -222,17 +222,17 @@ extern int inet_rtm_delroute(struct sk_buff *skb, struct nlmsghdr* nlh, void *ar
extern int inet_rtm_newroute(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg);
extern int inet_rtm_getroute(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg);
extern int inet_dump_fib(struct sk_buff *skb, struct netlink_callback *cb);
-extern int fib_validate_source(u32 src, u32 dst, u8 tos, int oif,
- struct net_device *dev, u32 *spec_dst, u32 *itag);
+extern int fib_validate_source(__be32 src, __be32 dst, u8 tos, int oif,
+ struct net_device *dev, __be32 *spec_dst, u32 *itag);
extern void fib_select_multipath(const struct flowi *flp, struct fib_result *res);
struct rtentry;
/* Exported by fib_semantics.c */
-extern int ip_fib_check_default(u32 gw, struct net_device *dev);
-extern int fib_sync_down(u32 local, struct net_device *dev, int force);
+extern int ip_fib_check_default(__be32 gw, struct net_device *dev);
+extern int fib_sync_down(__be32 local, struct net_device *dev, int force);
extern int fib_sync_up(struct net_device *dev);
-extern u32 __fib_res_prefsrc(struct fib_result *res);
+extern __be32 __fib_res_prefsrc(struct fib_result *res);
/* Exported by fib_hash.c */
extern struct fib_table *fib_hash_init(u32 id);
diff --git a/include/net/ip_mp_alg.h b/include/net/ip_mp_alg.h
index ac747b64734c..beffdd66ad74 100644
--- a/include/net/ip_mp_alg.h
+++ b/include/net/ip_mp_alg.h
@@ -17,7 +17,7 @@ struct ip_mp_alg_ops {
void (*mp_alg_select_route)(const struct flowi *flp,
struct rtable *rth, struct rtable **rp);
void (*mp_alg_flush)(void);
- void (*mp_alg_set_nhinfo)(__u32 network, __u32 netmask,
+ void (*mp_alg_set_nhinfo)(__be32 network, __be32 netmask,
unsigned char prefixlen,
const struct fib_nh *nh);
void (*mp_alg_remove)(struct rtable *rth);
@@ -59,7 +59,7 @@ static inline void multipath_flush(void)
}
static inline void multipath_set_nhinfo(struct rtable *rth,
- __u32 network, __u32 netmask,
+ __be32 network, __be32 netmask,
unsigned char prefixlen,
const struct fib_nh *nh)
{
diff --git a/include/net/ip_vs.h b/include/net/ip_vs.h
index 3b57b159b653..49c717e3b040 100644
--- a/include/net/ip_vs.h
+++ b/include/net/ip_vs.h
@@ -100,22 +100,22 @@
struct ip_vs_service_user {
/* virtual service addresses */
u_int16_t protocol;
- u_int32_t addr; /* virtual ip address */
- u_int16_t port;
+ __be32 addr; /* virtual ip address */
+ __be16 port;
u_int32_t fwmark; /* firwall mark of service */
/* virtual service options */
char sched_name[IP_VS_SCHEDNAME_MAXLEN];
unsigned flags; /* virtual service flags */
unsigned timeout; /* persistent timeout in sec */
- u_int32_t netmask; /* persistent netmask */
+ __be32 netmask; /* persistent netmask */
};
struct ip_vs_dest_user {
/* destination server address */
- u_int32_t addr;
- u_int16_t port;
+ __be32 addr;
+ __be16 port;
/* real server options */
unsigned conn_flags; /* connection flags */
@@ -163,15 +163,15 @@ struct ip_vs_getinfo {
struct ip_vs_service_entry {
/* which service: user fills in these */
u_int16_t protocol;
- u_int32_t addr; /* virtual address */
- u_int16_t port;
+ __be32 addr; /* virtual address */
+ __be16 port;
u_int32_t fwmark; /* firwall mark of service */
/* service options */
char sched_name[IP_VS_SCHEDNAME_MAXLEN];
unsigned flags; /* virtual service flags */
unsigned timeout; /* persistent timeout */
- u_int32_t netmask; /* persistent netmask */
+ __be32 netmask; /* persistent netmask */
/* number of real servers */
unsigned int num_dests;
@@ -182,8 +182,8 @@ struct ip_vs_service_entry {
struct ip_vs_dest_entry {
- u_int32_t addr; /* destination address */
- u_int16_t port;
+ __be32 addr; /* destination address */
+ __be16 port;
unsigned conn_flags; /* connection flags */
int weight; /* destination weight */
@@ -203,8 +203,8 @@ struct ip_vs_dest_entry {
struct ip_vs_get_dests {
/* which service: user fills in these */
u_int16_t protocol;
- u_int32_t addr; /* virtual address */
- u_int16_t port;
+ __be32 addr; /* virtual address */
+ __be16 port;
u_int32_t fwmark; /* firwall mark of service */
/* number of real servers */
@@ -502,12 +502,12 @@ struct ip_vs_conn {
struct list_head c_list; /* hashed list heads */
/* Protocol, addresses and port numbers */
- __u32 caddr; /* client address */
- __u32 vaddr; /* virtual address */
- __u32 daddr; /* destination address */
- __u16 cport;
- __u16 vport;
- __u16 dport;
+ __be32 caddr; /* client address */
+ __be32 vaddr; /* virtual address */
+ __be32 daddr; /* destination address */
+ __be16 cport;
+ __be16 vport;
+ __be16 dport;
__u16 protocol; /* Which protocol (TCP/UDP) */
/* counter and timer */
@@ -554,12 +554,12 @@ struct ip_vs_service {
atomic_t usecnt; /* use counter */
__u16 protocol; /* which protocol (TCP/UDP) */
- __u32 addr; /* IP address for virtual service */
- __u16 port; /* port number for the service */
+ __be32 addr; /* IP address for virtual service */
+ __be16 port; /* port number for the service */
__u32 fwmark; /* firewall mark of the service */
unsigned flags; /* service status flags */
unsigned timeout; /* persistent timeout in ticks */
- __u32 netmask; /* grouping granularity */
+ __be32 netmask; /* grouping granularity */
struct list_head destinations; /* real server d-linked list */
__u32 num_dests; /* number of servers */
@@ -581,8 +581,8 @@ struct ip_vs_dest {
struct list_head n_list; /* for the dests in the service */
struct list_head d_list; /* for table with all the dests */
- __u32 addr; /* IP address of the server */
- __u16 port; /* port number of the server */
+ __be32 addr; /* IP address of the server */
+ __be16 port; /* port number of the server */
volatile unsigned flags; /* dest status flags */
atomic_t conn_flags; /* flags to copy to conn */
atomic_t weight; /* server weight */
@@ -605,8 +605,8 @@ struct ip_vs_dest {
/* for virtual service */
struct ip_vs_service *svc; /* service it belongs to */
__u16 protocol; /* which protocol (TCP/UDP) */
- __u32 vaddr; /* virtual IP address */
- __u16 vport; /* virtual port number */
+ __be32 vaddr; /* virtual IP address */
+ __be16 vport; /* virtual port number */
__u32 vfwmark; /* firewall mark of service */
};
@@ -648,7 +648,7 @@ struct ip_vs_app
/* members for application incarnations */
struct list_head p_list; /* member in proto app list */
struct ip_vs_app *app; /* its real application */
- __u16 port; /* port number in net order */
+ __be16 port; /* port number in net order */
atomic_t usecnt; /* usage counter */
/* output hook: return false if can't linearize. diff set for TCP. */
@@ -740,11 +740,11 @@ enum {
};
extern struct ip_vs_conn *ip_vs_conn_in_get
-(int protocol, __u32 s_addr, __u16 s_port, __u32 d_addr, __u16 d_port);
+(int protocol, __be32 s_addr, __be16 s_port, __be32 d_addr, __be16 d_port);
extern struct ip_vs_conn *ip_vs_ct_in_get
-(int protocol, __u32 s_addr, __u16 s_port, __u32 d_addr, __u16 d_port);
+(int protocol, __be32 s_addr, __be16 s_port, __be32 d_addr, __be16 d_port);
extern struct ip_vs_conn *ip_vs_conn_out_get
-(int protocol, __u32 s_addr, __u16 s_port, __u32 d_addr, __u16 d_port);
+(int protocol, __be32 s_addr, __be16 s_port, __be32 d_addr, __be16 d_port);
/* put back the conn without restarting its timer */
static inline void __ip_vs_conn_put(struct ip_vs_conn *cp)
@@ -752,11 +752,11 @@ static inline void __ip_vs_conn_put(struct ip_vs_conn *cp)
atomic_dec(&cp->refcnt);
}
extern void ip_vs_conn_put(struct ip_vs_conn *cp);
-extern void ip_vs_conn_fill_cport(struct ip_vs_conn *cp, __u16 cport);
+extern void ip_vs_conn_fill_cport(struct ip_vs_conn *cp, __be16 cport);
extern struct ip_vs_conn *
-ip_vs_conn_new(int proto, __u32 caddr, __u16 cport, __u32 vaddr, __u16 vport,
- __u32 daddr, __u16 dport, unsigned flags,
+ip_vs_conn_new(int proto, __be32 caddr, __be16 cport, __be32 vaddr, __be16 vport,
+ __be32 daddr, __be16 dport, unsigned flags,
struct ip_vs_dest *dest);
extern void ip_vs_conn_expire_now(struct ip_vs_conn *cp);
@@ -887,7 +887,7 @@ extern int sysctl_ip_vs_nat_icmp_send;
extern struct ip_vs_stats ip_vs_stats;
extern struct ip_vs_service *
-ip_vs_service_get(__u32 fwmark, __u16 protocol, __u32 vaddr, __u16 vport);
+ip_vs_service_get(__u32 fwmark, __u16 protocol, __be32 vaddr, __be16 vport);
static inline void ip_vs_service_put(struct ip_vs_service *svc)
{
@@ -895,7 +895,7 @@ static inline void ip_vs_service_put(struct ip_vs_service *svc)
}
extern struct ip_vs_dest *
-ip_vs_lookup_real_service(__u16 protocol, __u32 daddr, __u16 dport);
+ip_vs_lookup_real_service(__u16 protocol, __be32 daddr, __be16 dport);
extern int ip_vs_use_count_inc(void);
extern void ip_vs_use_count_dec(void);
extern int ip_vs_control_init(void);
diff --git a/include/net/ipv6.h b/include/net/ipv6.h
index 72bf47b2a4e0..8223c4410b4b 100644
--- a/include/net/ipv6.h
+++ b/include/net/ipv6.h
@@ -318,8 +318,8 @@ static inline void ipv6_addr_prefix(struct in6_addr *pfx,
#ifndef __HAVE_ARCH_ADDR_SET
static inline void ipv6_addr_set(struct in6_addr *addr,
- __u32 w1, __u32 w2,
- __u32 w3, __u32 w4)
+ __be32 w1, __be32 w2,
+ __be32 w3, __be32 w4)
{
addr->s6_addr32[0] = w1;
addr->s6_addr32[1] = w2;
@@ -337,7 +337,7 @@ static inline int ipv6_addr_equal(const struct in6_addr *a1,
a1->s6_addr32[3] == a2->s6_addr32[3]);
}
-static inline int __ipv6_prefix_equal(const u32 *a1, const u32 *a2,
+static inline int __ipv6_prefix_equal(const __be32 *a1, const __be32 *a2,
unsigned int prefixlen)
{
unsigned pdw, pbi;
diff --git a/include/net/irda/irlan_common.h b/include/net/irda/irlan_common.h
index 1c73bdbc3eb3..9592c374b41d 100644
--- a/include/net/irda/irlan_common.h
+++ b/include/net/irda/irlan_common.h
@@ -98,7 +98,15 @@
#define IRLAN_SHORT 1
#define IRLAN_ARRAY 2
-#define IRLAN_MAX_HEADER (TTP_HEADER+LMP_HEADER+LAP_MAX_HEADER)
+/* IrLAN sits on top if IrTTP */
+#define IRLAN_MAX_HEADER (TTP_HEADER+LMP_HEADER)
+/* 1 byte for the command code and 1 byte for the parameter count */
+#define IRLAN_CMD_HEADER 2
+
+#define IRLAN_STRING_PARAMETER_LEN(name, value) (1 + strlen((name)) + 2 \
+ + strlen ((value)))
+#define IRLAN_BYTE_PARAMETER_LEN(name) (1 + strlen((name)) + 2 + 1)
+#define IRLAN_SHORT_PARAMETER_LEN(name) (1 + strlen((name)) + 2 + 2)
/*
* IrLAN client
diff --git a/include/net/irda/irlap_frame.h b/include/net/irda/irlap_frame.h
index 3452ae257c84..9dd54a5002b2 100644
--- a/include/net/irda/irlap_frame.h
+++ b/include/net/irda/irlap_frame.h
@@ -74,6 +74,19 @@ struct discovery_t;
#define PF_BIT 0x10 /* Poll/final bit */
+/* Some IrLAP field lengths */
+/*
+ * Only baud rate triplet is 4 bytes (PV can be 2 bytes).
+ * All others params (7) are 3 bytes, so that's 7*3 + 1*4 bytes.
+ */
+#define IRLAP_NEGOCIATION_PARAMS_LEN 25
+#define IRLAP_DISCOVERY_INFO_LEN 32
+
+struct disc_frame {
+ __u8 caddr; /* Connection address */
+ __u8 control;
+} IRDA_PACK;
+
struct xid_frame {
__u8 caddr; /* Connection address */
__u8 control;
@@ -95,11 +108,25 @@ struct test_frame {
struct ua_frame {
__u8 caddr;
__u8 control;
-
__u32 saddr; /* Source device address */
__u32 daddr; /* Dest device address */
} IRDA_PACK;
-
+
+struct dm_frame {
+ __u8 caddr; /* Connection address */
+ __u8 control;
+} IRDA_PACK;
+
+struct rd_frame {
+ __u8 caddr; /* Connection address */
+ __u8 control;
+} IRDA_PACK;
+
+struct rr_frame {
+ __u8 caddr; /* Connection address */
+ __u8 control;
+} IRDA_PACK;
+
struct i_frame {
__u8 caddr;
__u8 control;
diff --git a/include/net/irda/irlmp.h b/include/net/irda/irlmp.h
index 11ecfa58a648..e212b9bc2503 100644
--- a/include/net/irda/irlmp.h
+++ b/include/net/irda/irlmp.h
@@ -48,7 +48,7 @@
#define DEV_ADDR_ANY 0xffffffff
#define LMP_HEADER 2 /* Dest LSAP + Source LSAP */
-#define LMP_CONTROL_HEADER 4
+#define LMP_CONTROL_HEADER 4 /* LMP_HEADER + opcode + parameter */
#define LMP_PID_HEADER 1 /* Used by Ultra */
#define LMP_MAX_HEADER (LMP_CONTROL_HEADER+LAP_MAX_HEADER)
diff --git a/include/net/netlabel.h b/include/net/netlabel.h
index 6692430063fd..c63a58058e21 100644
--- a/include/net/netlabel.h
+++ b/include/net/netlabel.h
@@ -92,11 +92,17 @@
*
*/
+/* NetLabel audit information */
+struct netlbl_audit {
+ u32 secid;
+ uid_t loginuid;
+};
+
/* Domain mapping definition struct */
struct netlbl_dom_map;
/* Domain mapping operations */
-int netlbl_domhsh_remove(const char *domain);
+int netlbl_domhsh_remove(const char *domain, struct netlbl_audit *audit_info);
/* LSM security attributes */
struct netlbl_lsm_cache {
diff --git a/include/net/netlink.h b/include/net/netlink.h
index 4ab68a7a636a..ce5cba19c393 100644
--- a/include/net/netlink.h
+++ b/include/net/netlink.h
@@ -831,6 +831,9 @@ static inline int nla_put_msecs(struct sk_buff *skb, int attrtype,
#define NLA_PUT_U32(skb, attrtype, value) \
NLA_PUT_TYPE(skb, u32, attrtype, value)
+#define NLA_PUT_BE32(skb, attrtype, value) \
+ NLA_PUT_TYPE(skb, __be32, attrtype, value)
+
#define NLA_PUT_U64(skb, attrtype, value) \
NLA_PUT_TYPE(skb, u64, attrtype, value)
@@ -853,6 +856,15 @@ static inline u32 nla_get_u32(struct nlattr *nla)
}
/**
+ * nla_get_be32 - return payload of __be32 attribute
+ * @nla: __be32 netlink attribute
+ */
+static inline __be32 nla_get_be32(struct nlattr *nla)
+{
+ return *(__be32 *) nla_data(nla);
+}
+
+/**
* nla_get_u16 - return payload of u16 attribute
* @nla: u16 netlink attribute
*/
diff --git a/include/net/route.h b/include/net/route.h
index 7f93ac0e0899..486e37aff06c 100644
--- a/include/net/route.h
+++ b/include/net/route.h
@@ -62,18 +62,18 @@ struct rtable
__u16 rt_type;
__u16 rt_multipath_alg;
- __u32 rt_dst; /* Path destination */
- __u32 rt_src; /* Path source */
+ __be32 rt_dst; /* Path destination */
+ __be32 rt_src; /* Path source */
int rt_iif;
/* Info on neighbour */
- __u32 rt_gateway;
+ __be32 rt_gateway;
/* Cache lookup keys */
struct flowi fl;
/* Miscellaneous cached information */
- __u32 rt_spec_dst; /* RFC1122 specific destination */
+ __be32 rt_spec_dst; /* RFC1122 specific destination */
struct inet_peer *peer; /* long-living peer info */
};
@@ -109,18 +109,18 @@ extern struct ip_rt_acct *ip_rt_acct;
struct in_device;
extern int ip_rt_init(void);
-extern void ip_rt_redirect(u32 old_gw, u32 dst, u32 new_gw,
- u32 src, struct net_device *dev);
+extern void ip_rt_redirect(__be32 old_gw, __be32 dst, __be32 new_gw,
+ __be32 src, struct net_device *dev);
extern void ip_rt_advice(struct rtable **rp, int advice);
extern void rt_cache_flush(int how);
extern int __ip_route_output_key(struct rtable **, const struct flowi *flp);
extern int ip_route_output_key(struct rtable **, struct flowi *flp);
extern int ip_route_output_flow(struct rtable **rp, struct flowi *flp, struct sock *sk, int flags);
-extern int ip_route_input(struct sk_buff*, u32 dst, u32 src, u8 tos, struct net_device *devin);
+extern int ip_route_input(struct sk_buff*, __be32 dst, __be32 src, u8 tos, struct net_device *devin);
extern unsigned short ip_rt_frag_needed(struct iphdr *iph, unsigned short new_mtu);
extern void ip_rt_send_redirect(struct sk_buff *skb);
-extern unsigned inet_addr_type(u32 addr);
+extern unsigned inet_addr_type(__be32 addr);
extern void ip_rt_multicast_event(struct in_device *);
extern int ip_rt_ioctl(unsigned int cmd, void __user *arg);
extern void ip_rt_get_source(u8 *src, struct rtable *rt);
@@ -144,9 +144,9 @@ static inline char rt_tos2priority(u8 tos)
return ip_tos2prio[IPTOS_TOS(tos)>>1];
}
-static inline int ip_route_connect(struct rtable **rp, u32 dst,
- u32 src, u32 tos, int oif, u8 protocol,
- u16 sport, u16 dport, struct sock *sk)
+static inline int ip_route_connect(struct rtable **rp, __be32 dst,
+ __be32 src, u32 tos, int oif, u8 protocol,
+ __be16 sport, __be16 dport, struct sock *sk)
{
struct flowi fl = { .oif = oif,
.nl_u = { .ip4_u = { .daddr = dst,
@@ -172,7 +172,7 @@ static inline int ip_route_connect(struct rtable **rp, u32 dst,
}
static inline int ip_route_newports(struct rtable **rp, u8 protocol,
- u16 sport, u16 dport, struct sock *sk)
+ __be16 sport, __be16 dport, struct sock *sk)
{
if (sport != (*rp)->fl.fl_ip_sport ||
dport != (*rp)->fl.fl_ip_dport) {
diff --git a/include/net/sock.h b/include/net/sock.h
index edd4d73ce7f5..40bb90ebb2d1 100644
--- a/include/net/sock.h
+++ b/include/net/sock.h
@@ -665,7 +665,6 @@ struct sock_iocb {
struct sock *sk;
struct scm_cookie *scm;
struct msghdr *msg, async_msg;
- struct iovec async_iov;
struct kiocb *kiocb;
};
diff --git a/include/net/xfrm.h b/include/net/xfrm.h
index 11e0b1d6bd47..1e2a4ddec96e 100644
--- a/include/net/xfrm.h
+++ b/include/net/xfrm.h
@@ -437,8 +437,8 @@ static inline void xfrm_state_hold(struct xfrm_state *x)
static __inline__ int addr_match(void *token1, void *token2, int prefixlen)
{
- __u32 *a1 = token1;
- __u32 *a2 = token2;
+ __be32 *a1 = token1;
+ __be32 *a2 = token2;
int pdw;
int pbi;
@@ -450,7 +450,7 @@ static __inline__ int addr_match(void *token1, void *token2, int prefixlen)
return 0;
if (pbi) {
- __u32 mask;
+ __be32 mask;
mask = htonl((0xffffffff) << (32 - pbi));
@@ -462,9 +462,9 @@ static __inline__ int addr_match(void *token1, void *token2, int prefixlen)
}
static __inline__
-u16 xfrm_flowi_sport(struct flowi *fl)
+__be16 xfrm_flowi_sport(struct flowi *fl)
{
- u16 port;
+ __be16 port;
switch(fl->proto) {
case IPPROTO_TCP:
case IPPROTO_UDP:
@@ -487,9 +487,9 @@ u16 xfrm_flowi_sport(struct flowi *fl)
}
static __inline__
-u16 xfrm_flowi_dport(struct flowi *fl)
+__be16 xfrm_flowi_dport(struct flowi *fl)
{
- u16 port;
+ __be16 port;
switch(fl->proto) {
case IPPROTO_TCP:
case IPPROTO_UDP:
@@ -912,7 +912,7 @@ extern int xfrm_state_check_expire(struct xfrm_state *x);
extern void xfrm_state_insert(struct xfrm_state *x);
extern int xfrm_state_add(struct xfrm_state *x);
extern int xfrm_state_update(struct xfrm_state *x);
-extern struct xfrm_state *xfrm_state_lookup(xfrm_address_t *daddr, u32 spi, u8 proto, unsigned short family);
+extern struct xfrm_state *xfrm_state_lookup(xfrm_address_t *daddr, __be32 spi, u8 proto, unsigned short family);
extern struct xfrm_state *xfrm_state_lookup_byaddr(xfrm_address_t *daddr, xfrm_address_t *saddr, u8 proto, unsigned short family);
#ifdef CONFIG_XFRM_SUB_POLICY
extern int xfrm_tmpl_sort(struct xfrm_tmpl **dst, struct xfrm_tmpl **src,
@@ -935,8 +935,8 @@ static inline int xfrm_state_sort(struct xfrm_state **dst, struct xfrm_state **s
extern struct xfrm_state *xfrm_find_acq_byseq(u32 seq);
extern int xfrm_state_delete(struct xfrm_state *x);
extern void xfrm_state_flush(u8 proto);
-extern int xfrm_replay_check(struct xfrm_state *x, u32 seq);
-extern void xfrm_replay_advance(struct xfrm_state *x, u32 seq);
+extern int xfrm_replay_check(struct xfrm_state *x, __be32 seq);
+extern void xfrm_replay_advance(struct xfrm_state *x, __be32 seq);
extern void xfrm_replay_notify(struct xfrm_state *x, int event);
extern int xfrm_state_check(struct xfrm_state *x, struct sk_buff *skb);
extern int xfrm_state_mtu(struct xfrm_state *x, int mtu);
@@ -945,7 +945,7 @@ extern int xfrm4_rcv(struct sk_buff *skb);
extern int xfrm4_output(struct sk_buff *skb);
extern int xfrm4_tunnel_register(struct xfrm_tunnel *handler);
extern int xfrm4_tunnel_deregister(struct xfrm_tunnel *handler);
-extern int xfrm6_rcv_spi(struct sk_buff *skb, u32 spi);
+extern int xfrm6_rcv_spi(struct sk_buff *skb, __be32 spi);
extern int xfrm6_rcv(struct sk_buff **pskb);
extern int xfrm6_input_addr(struct sk_buff *skb, xfrm_address_t *daddr,
xfrm_address_t *saddr, u8 proto);
@@ -989,7 +989,7 @@ struct xfrm_policy *xfrm_policy_bysel_ctx(u8 type, int dir,
struct xfrm_policy *xfrm_policy_byid(u8, int dir, u32 id, int delete);
void xfrm_policy_flush(u8 type);
u32 xfrm_get_acqseq(void);
-void xfrm_alloc_spi(struct xfrm_state *x, u32 minspi, u32 maxspi);
+void xfrm_alloc_spi(struct xfrm_state *x, __be32 minspi, __be32 maxspi);
struct xfrm_state * xfrm_find_acq(u8 mode, u32 reqid, u8 proto,
xfrm_address_t *daddr, xfrm_address_t *saddr,
int create, unsigned short family);
@@ -1004,7 +1004,7 @@ extern void km_policy_expired(struct xfrm_policy *pol, int dir, int hard, u32 pi
extern int km_report(u8 proto, struct xfrm_selector *sel, xfrm_address_t *addr);
extern void xfrm_input_init(void);
-extern int xfrm_parse_spi(struct sk_buff *skb, u8 nexthdr, u32 *spi, u32 *seq);
+extern int xfrm_parse_spi(struct sk_buff *skb, u8 nexthdr, __be32 *spi, __be32 *seq);
extern void xfrm_probe_algs(void);
extern int xfrm_count_auth_supported(void);
diff --git a/include/scsi/scsi_device.h b/include/scsi/scsi_device.h
index 895d212864cd..b401c82036be 100644
--- a/include/scsi/scsi_device.h
+++ b/include/scsi/scsi_device.h
@@ -298,9 +298,9 @@ extern int scsi_execute_async(struct scsi_device *sdev,
void (*done)(void *, char *, int, int),
gfp_t gfp);
-static inline void scsi_device_reprobe(struct scsi_device *sdev)
+static inline int __must_check scsi_device_reprobe(struct scsi_device *sdev)
{
- device_reprobe(&sdev->sdev_gendev);
+ return device_reprobe(&sdev->sdev_gendev);
}
static inline unsigned int sdev_channel(struct scsi_device *sdev)
diff --git a/include/scsi/scsi_tcq.h b/include/scsi/scsi_tcq.h
index d04d05adfa9b..c247a28259bc 100644
--- a/include/scsi/scsi_tcq.h
+++ b/include/scsi/scsi_tcq.h
@@ -6,7 +6,6 @@
#include <scsi/scsi_device.h>
#include <scsi/scsi_host.h>
-
#define MSG_SIMPLE_TAG 0x20
#define MSG_HEAD_TAG 0x21
#define MSG_ORDERED_TAG 0x22
@@ -14,6 +13,7 @@
#define SCSI_NO_TAG (-1) /* identify no tag in use */
+#ifdef CONFIG_BLOCK
/**
* scsi_get_tag_type - get the type of tag the device supports
@@ -100,7 +100,7 @@ static inline int scsi_populate_tag_msg(struct scsi_cmnd *cmd, char *msg)
struct scsi_device *sdev = cmd->device;
if (blk_rq_tagged(req)) {
- if (sdev->ordered_tags && req->flags & REQ_HARDBARRIER)
+ if (sdev->ordered_tags && req->cmd_flags & REQ_HARDBARRIER)
*msg++ = MSG_ORDERED_TAG;
else
*msg++ = MSG_SIMPLE_TAG;
@@ -144,4 +144,5 @@ static inline int scsi_init_shared_tag_map(struct Scsi_Host *shost, int depth)
return shost->bqt ? 0 : -ENOMEM;
}
+#endif /* CONFIG_BLOCK */
#endif /* _SCSI_SCSI_TCQ_H */
diff --git a/include/sound/pcm.h b/include/sound/pcm.h
index 60d40b34efc0..afaf3e88e086 100644
--- a/include/sound/pcm.h
+++ b/include/sound/pcm.h
@@ -347,6 +347,7 @@ struct snd_pcm_substream {
int number;
char name[32]; /* substream name */
int stream; /* stream (direction) */
+ char latency_id[20]; /* latency identifier */
size_t buffer_bytes_max; /* limit ring buffer size */
struct snd_dma_buffer dma_buffer;
unsigned int dma_buf_id;
diff --git a/include/video/sstfb.h b/include/video/sstfb.h
index 3570f9c9b111..5dbf5e7e50a8 100644
--- a/include/video/sstfb.h
+++ b/include/video/sstfb.h
@@ -68,10 +68,6 @@
# define print_var(X,Y...)
#endif
-#define eprintk(X...) printk(KERN_ERR "sstfb: " X)
-#define iprintk(X...) printk(KERN_INFO "sstfb: " X)
-#define wprintk(X...) printk(KERN_WARNING "sstfb: " X)
-
#define BIT(x) (1ul<<(x))
#define POW2(x) (1ul<<(x))
diff --git a/init/Kconfig b/init/Kconfig
index 4381006dd666..10382931eead 100644
--- a/init/Kconfig
+++ b/init/Kconfig
@@ -92,7 +92,7 @@ config LOCALVERSION_AUTO
config SWAP
bool "Support for paging of anonymous memory (swap)"
- depends on MMU
+ depends on MMU && BLOCK
default y
help
This option allows you to choose whether you want to have support
@@ -115,6 +115,15 @@ config SYSVIPC
section 6.4 of the Linux Programmer's Guide, available from
<http://www.tldp.org/guides.html>.
+config IPC_NS
+ bool "IPC Namespaces"
+ depends on SYSVIPC
+ default n
+ help
+ Support ipc namespaces. This allows containers, i.e. virtual
+ environments, to use ipc namespaces to provide different ipc
+ objects for different servers. If unsure, say N.
+
config POSIX_MQUEUE
bool "POSIX Message Queues"
depends on NET && EXPERIMENTAL
@@ -182,6 +191,14 @@ config TASK_DELAY_ACCT
Say N if unsure.
+config UTS_NS
+ bool "UTS Namespaces"
+ default n
+ help
+ Support uts namespaces. This allows containers, i.e.
+ vservers, to use uts namespaces to provide different
+ uts info for different servers. If unsure, say N.
+
config AUDIT
bool "Auditing support"
depends on NET
@@ -202,7 +219,7 @@ config AUDITSYSCALL
ensure that INOTIFY is configured.
config IKCONFIG
- bool "Kernel .config support"
+ tristate "Kernel .config support"
---help---
This option enables the complete Linux kernel ".config" file
contents to be saved in the kernel. It provides documentation
@@ -257,6 +274,18 @@ config CC_OPTIMIZE_FOR_SIZE
If unsure, say N.
+config TASK_XACCT
+ bool "Enable extended accounting over taskstats (EXPERIMENTAL)"
+ depends on TASKSTATS
+ help
+ Collect extended task accounting data and send the data
+ to userland for processing over the taskstats interface.
+
+ Say N if unsure.
+
+config SYSCTL
+ bool
+
menuconfig EMBEDDED
bool "Configure standard kernel features (for small systems)"
help
@@ -272,11 +301,8 @@ config UID16
help
This enables the legacy 16-bit UID syscall wrappers.
-config SYSCTL
- bool
-
config SYSCTL_SYSCALL
- bool "Sysctl syscall support"
+ bool "Sysctl syscall support" if EMBEDDED
default n
select SYSCTL
---help---
@@ -285,11 +311,11 @@ config SYSCTL_SYSCALL
and use. The interface in /proc/sys is now the primary and what
everyone uses.
- Nothing has been using the binary sysctl interface for some time
+ Nothing has been using the binary sysctl interface for some
time now so nothing should break if you disable sysctl syscall
- support, and you kernel will get marginally smaller.
+ support, and your kernel will get marginally smaller.
- Unless you have an application that uses the sys_syscall interface
+ Unless you have an application that uses the sys_sysctl interface
you should probably say N here.
config KALLSYMS
diff --git a/init/do_mounts.c b/init/do_mounts.c
index b290aadb1d3f..dc1ec0803ef9 100644
--- a/init/do_mounts.c
+++ b/init/do_mounts.c
@@ -285,7 +285,11 @@ void __init mount_block_root(char *name, int flags)
{
char *fs_names = __getname();
char *p;
+#ifdef CONFIG_BLOCK
char b[BDEVNAME_SIZE];
+#else
+ const char *b = name;
+#endif
get_fs_names(fs_names);
retry:
@@ -304,7 +308,9 @@ retry:
* Allow the user to distinguish between failed sys_open
* and bad superblock on root device.
*/
+#ifdef CONFIG_BLOCK
__bdevname(ROOT_DEV, b);
+#endif
printk("VFS: Cannot open root device \"%s\" or %s\n",
root_device_name, b);
printk("Please append a correct \"root=\" boot option\n");
@@ -316,7 +322,10 @@ retry:
for (p = fs_names; *p; p += strlen(p)+1)
printk(" %s", p);
printk("\n");
- panic("VFS: Unable to mount root fs on %s", __bdevname(ROOT_DEV, b));
+#ifdef CONFIG_BLOCK
+ __bdevname(ROOT_DEV, b);
+#endif
+ panic("VFS: Unable to mount root fs on %s", b);
out:
putname(fs_names);
}
@@ -387,8 +396,10 @@ void __init mount_root(void)
change_floppy("root floppy");
}
#endif
+#ifdef CONFIG_BLOCK
create_dev("/dev/root", ROOT_DEV);
mount_block_root("/dev/root", root_mountflags);
+#endif
}
/*
diff --git a/init/do_mounts_initrd.c b/init/do_mounts_initrd.c
index a06f037fa000..919a80cb322e 100644
--- a/init/do_mounts_initrd.c
+++ b/init/do_mounts_initrd.c
@@ -1,4 +1,3 @@
-#define __KERNEL_SYSCALLS__
#include <linux/unistd.h>
#include <linux/kernel.h>
#include <linux/fs.h>
@@ -35,7 +34,7 @@ static int __init do_linuxrc(void * shell)
(void) sys_open("/dev/console",O_RDWR,0);
(void) sys_dup(0);
(void) sys_dup(0);
- return execve(shell, argv, envp_init);
+ return kernel_execve(shell, argv, envp_init);
}
static void __init handle_initrd(void)
diff --git a/init/do_mounts_md.c b/init/do_mounts_md.c
index 2429e1bf8c60..753dc54a6649 100644
--- a/init/do_mounts_md.c
+++ b/init/do_mounts_md.c
@@ -20,7 +20,7 @@ static struct {
int level;
int chunk;
char *device_names;
-} md_setup_args[MAX_MD_DEVS] __initdata;
+} md_setup_args[256] __initdata;
static int md_setup_ents __initdata;
@@ -61,10 +61,6 @@ static int __init md_setup(char *str)
return 0;
}
str1 = str;
- if (minor >= MAX_MD_DEVS) {
- printk(KERN_WARNING "md: md=%d, Minor device number too high.\n", minor);
- return 0;
- }
for (ent=0 ; ent< md_setup_ents ; ent++)
if (md_setup_args[ent].minor == minor &&
md_setup_args[ent].partitioned == partitioned) {
@@ -72,7 +68,7 @@ static int __init md_setup(char *str)
"Replacing previous definition.\n", partitioned?"d":"", minor);
break;
}
- if (ent >= MAX_MD_DEVS) {
+ if (ent >= ARRAY_SIZE(md_setup_args)) {
printk(KERN_WARNING "md: md=%s%d - too many md initialisations\n", partitioned?"d":"", minor);
return 0;
}
diff --git a/init/main.c b/init/main.c
index 0766e69712b2..ee123243fb53 100644
--- a/init/main.c
+++ b/init/main.c
@@ -9,8 +9,6 @@
* Simplified starting of init: Michael A. Griffith <grif@acm.org>
*/
-#define __KERNEL_SYSCALLS__
-
#include <linux/types.h>
#include <linux/module.h>
#include <linux/proc_fs.h>
@@ -703,7 +701,7 @@ static void do_pre_smp_initcalls(void)
static void run_init_process(char *init_filename)
{
argv_init[0] = init_filename;
- execve(init_filename, argv_init, envp_init);
+ kernel_execve(init_filename, argv_init, envp_init);
}
static int init(void * unused)
@@ -723,6 +721,8 @@ static int init(void * unused)
*/
child_reaper = current;
+ cad_pid = task_pid(current);
+
smp_prepare_cpus(max_cpus);
do_pre_smp_initcalls();
diff --git a/init/version.c b/init/version.c
index e290802c6bd2..8f28344d9c70 100644
--- a/init/version.c
+++ b/init/version.c
@@ -12,22 +12,27 @@
#include <linux/utsname.h>
#include <linux/utsrelease.h>
#include <linux/version.h>
+#include <linux/sched.h>
#define version(a) Version_ ## a
#define version_string(a) version(a)
int version_string(LINUX_VERSION_CODE);
-struct new_utsname system_utsname = {
- .sysname = UTS_SYSNAME,
- .nodename = UTS_NODENAME,
- .release = UTS_RELEASE,
- .version = UTS_VERSION,
- .machine = UTS_MACHINE,
- .domainname = UTS_DOMAINNAME,
+struct uts_namespace init_uts_ns = {
+ .kref = {
+ .refcount = ATOMIC_INIT(2),
+ },
+ .name = {
+ .sysname = UTS_SYSNAME,
+ .nodename = UTS_NODENAME,
+ .release = UTS_RELEASE,
+ .version = UTS_VERSION,
+ .machine = UTS_MACHINE,
+ .domainname = UTS_DOMAINNAME,
+ },
};
-
-EXPORT_SYMBOL(system_utsname);
+EXPORT_SYMBOL_GPL(init_uts_ns);
const char linux_banner[] =
"Linux version " UTS_RELEASE " (" LINUX_COMPILE_BY "@"
diff --git a/ipc/mqueue.c b/ipc/mqueue.c
index 840f8a6fb85f..c45ae86cec31 100644
--- a/ipc/mqueue.c
+++ b/ipc/mqueue.c
@@ -73,7 +73,7 @@ struct mqueue_inode_info {
struct mq_attr attr;
struct sigevent notify;
- pid_t notify_owner;
+ struct pid* notify_owner;
struct user_struct *user; /* user who created, for accounting */
struct sock *notify_sock;
struct sk_buff *notify_cookie;
@@ -134,7 +134,7 @@ static struct inode *mqueue_get_inode(struct super_block *sb, int mode,
INIT_LIST_HEAD(&info->e_wait_q[0].list);
INIT_LIST_HEAD(&info->e_wait_q[1].list);
info->messages = NULL;
- info->notify_owner = 0;
+ info->notify_owner = NULL;
info->qsize = 0;
info->user = NULL; /* set when all is ok */
memset(&info->attr, 0, sizeof(info->attr));
@@ -168,7 +168,7 @@ static struct inode *mqueue_get_inode(struct super_block *sb, int mode,
/* all is ok */
info->user = get_uid(u);
} else if (S_ISDIR(mode)) {
- inode->i_nlink++;
+ inc_nlink(inode);
/* Some things misbehave if size == 0 on a directory */
inode->i_size = 2 * DIRENT_SIZE;
inode->i_op = &mqueue_dir_inode_operations;
@@ -307,7 +307,7 @@ static int mqueue_unlink(struct inode *dir, struct dentry *dentry)
dir->i_ctime = dir->i_mtime = dir->i_atime = CURRENT_TIME;
dir->i_size -= DIRENT_SIZE;
- inode->i_nlink--;
+ drop_nlink(inode);
dput(dentry);
return 0;
}
@@ -338,7 +338,7 @@ static ssize_t mqueue_read_file(struct file *filp, char __user *u_data,
(info->notify_owner &&
info->notify.sigev_notify == SIGEV_SIGNAL) ?
info->notify.sigev_signo : 0,
- info->notify_owner);
+ pid_nr(info->notify_owner));
spin_unlock(&info->lock);
buffer[sizeof(buffer)-1] = '\0';
slen = strlen(buffer)+1;
@@ -363,7 +363,7 @@ static int mqueue_flush_file(struct file *filp, fl_owner_t id)
struct mqueue_inode_info *info = MQUEUE_I(filp->f_dentry->d_inode);
spin_lock(&info->lock);
- if (current->tgid == info->notify_owner)
+ if (task_tgid(current) == info->notify_owner)
remove_notification(info);
spin_unlock(&info->lock);
@@ -518,8 +518,8 @@ static void __do_notify(struct mqueue_inode_info *info)
sig_i.si_pid = current->tgid;
sig_i.si_uid = current->uid;
- kill_proc_info(info->notify.sigev_signo,
- &sig_i, info->notify_owner);
+ kill_pid_info(info->notify.sigev_signo,
+ &sig_i, info->notify_owner);
break;
case SIGEV_THREAD:
set_cookie(info->notify_cookie, NOTIFY_WOKENUP);
@@ -528,7 +528,8 @@ static void __do_notify(struct mqueue_inode_info *info)
break;
}
/* after notification unregisters process */
- info->notify_owner = 0;
+ put_pid(info->notify_owner);
+ info->notify_owner = NULL;
}
wake_up(&info->wait_q);
}
@@ -566,12 +567,13 @@ static long prepare_timeout(const struct timespec __user *u_arg)
static void remove_notification(struct mqueue_inode_info *info)
{
- if (info->notify_owner != 0 &&
+ if (info->notify_owner != NULL &&
info->notify.sigev_notify == SIGEV_THREAD) {
set_cookie(info->notify_cookie, NOTIFY_REMOVED);
netlink_sendskb(info->notify_sock, info->notify_cookie, 0);
}
- info->notify_owner = 0;
+ put_pid(info->notify_owner);
+ info->notify_owner = NULL;
}
static int mq_attr_ok(struct mq_attr *attr)
@@ -1062,11 +1064,11 @@ retry:
ret = 0;
spin_lock(&info->lock);
if (u_notification == NULL) {
- if (info->notify_owner == current->tgid) {
+ if (info->notify_owner == task_tgid(current)) {
remove_notification(info);
inode->i_atime = inode->i_ctime = CURRENT_TIME;
}
- } else if (info->notify_owner != 0) {
+ } else if (info->notify_owner != NULL) {
ret = -EBUSY;
} else {
switch (notification.sigev_notify) {
@@ -1086,7 +1088,8 @@ retry:
info->notify.sigev_notify = SIGEV_SIGNAL;
break;
}
- info->notify_owner = current->tgid;
+
+ info->notify_owner = get_pid(task_tgid(current));
inode->i_atime = inode->i_ctime = CURRENT_TIME;
}
spin_unlock(&info->lock);
diff --git a/ipc/msg.c b/ipc/msg.c
index 2b4fccf8ea55..5b213d952545 100644
--- a/ipc/msg.c
+++ b/ipc/msg.c
@@ -16,6 +16,10 @@
*
* support for audit of ipc object properties and permission changes
* Dustin Kirkland <dustin.kirkland@us.ibm.com>
+ *
+ * namespaces support
+ * OpenVZ, SWsoft Inc.
+ * Pavel Emelianov <xemul@openvz.org>
*/
#include <linux/capability.h>
@@ -31,16 +35,12 @@
#include <linux/audit.h>
#include <linux/seq_file.h>
#include <linux/mutex.h>
+#include <linux/nsproxy.h>
#include <asm/current.h>
#include <asm/uaccess.h>
#include "util.h"
-/* sysctl: */
-int msg_ctlmax = MSGMAX;
-int msg_ctlmnb = MSGMNB;
-int msg_ctlmni = MSGMNI;
-
/*
* one msg_receiver structure for each sleeping receiver:
*/
@@ -69,30 +69,75 @@ struct msg_sender {
static atomic_t msg_bytes = ATOMIC_INIT(0);
static atomic_t msg_hdrs = ATOMIC_INIT(0);
-static struct ipc_ids msg_ids;
+static struct ipc_ids init_msg_ids;
-#define msg_lock(id) ((struct msg_queue *)ipc_lock(&msg_ids, id))
-#define msg_unlock(msq) ipc_unlock(&(msq)->q_perm)
-#define msg_rmid(id) ((struct msg_queue *)ipc_rmid(&msg_ids, id))
-#define msg_checkid(msq, msgid) ipc_checkid(&msg_ids, &msq->q_perm, msgid)
-#define msg_buildid(id, seq) ipc_buildid(&msg_ids, id, seq)
+#define msg_ids(ns) (*((ns)->ids[IPC_MSG_IDS]))
-static void freeque(struct msg_queue *msq, int id);
-static int newque(key_t key, int msgflg);
+#define msg_lock(ns, id) ((struct msg_queue*)ipc_lock(&msg_ids(ns), id))
+#define msg_unlock(msq) ipc_unlock(&(msq)->q_perm)
+#define msg_rmid(ns, id) ((struct msg_queue*)ipc_rmid(&msg_ids(ns), id))
+#define msg_checkid(ns, msq, msgid) \
+ ipc_checkid(&msg_ids(ns), &msq->q_perm, msgid)
+#define msg_buildid(ns, id, seq) \
+ ipc_buildid(&msg_ids(ns), id, seq)
+
+static void freeque (struct ipc_namespace *ns, struct msg_queue *msq, int id);
+static int newque (struct ipc_namespace *ns, key_t key, int msgflg);
#ifdef CONFIG_PROC_FS
static int sysvipc_msg_proc_show(struct seq_file *s, void *it);
#endif
+static void __ipc_init __msg_init_ns(struct ipc_namespace *ns, struct ipc_ids *ids)
+{
+ ns->ids[IPC_MSG_IDS] = ids;
+ ns->msg_ctlmax = MSGMAX;
+ ns->msg_ctlmnb = MSGMNB;
+ ns->msg_ctlmni = MSGMNI;
+ ipc_init_ids(ids, ns->msg_ctlmni);
+}
+
+#ifdef CONFIG_IPC_NS
+int msg_init_ns(struct ipc_namespace *ns)
+{
+ struct ipc_ids *ids;
+
+ ids = kmalloc(sizeof(struct ipc_ids), GFP_KERNEL);
+ if (ids == NULL)
+ return -ENOMEM;
+
+ __msg_init_ns(ns, ids);
+ return 0;
+}
+
+void msg_exit_ns(struct ipc_namespace *ns)
+{
+ int i;
+ struct msg_queue *msq;
+
+ mutex_lock(&msg_ids(ns).mutex);
+ for (i = 0; i <= msg_ids(ns).max_id; i++) {
+ msq = msg_lock(ns, i);
+ if (msq == NULL)
+ continue;
+
+ freeque(ns, msq, i);
+ }
+ mutex_unlock(&msg_ids(ns).mutex);
+
+ kfree(ns->ids[IPC_MSG_IDS]);
+ ns->ids[IPC_MSG_IDS] = NULL;
+}
+#endif
+
void __init msg_init(void)
{
- ipc_init_ids(&msg_ids, msg_ctlmni);
+ __msg_init_ns(&init_ipc_ns, &init_msg_ids);
ipc_init_proc_interface("sysvipc/msg",
" key msqid perms cbytes qnum lspid lrpid uid gid cuid cgid stime rtime ctime\n",
- &msg_ids,
- sysvipc_msg_proc_show);
+ IPC_MSG_IDS, sysvipc_msg_proc_show);
}
-static int newque(key_t key, int msgflg)
+static int newque (struct ipc_namespace *ns, key_t key, int msgflg)
{
struct msg_queue *msq;
int id, retval;
@@ -111,18 +156,18 @@ static int newque(key_t key, int msgflg)
return retval;
}
- id = ipc_addid(&msg_ids, &msq->q_perm, msg_ctlmni);
+ id = ipc_addid(&msg_ids(ns), &msq->q_perm, ns->msg_ctlmni);
if (id == -1) {
security_msg_queue_free(msq);
ipc_rcu_putref(msq);
return -ENOSPC;
}
- msq->q_id = msg_buildid(id, msq->q_perm.seq);
+ msq->q_id = msg_buildid(ns, id, msq->q_perm.seq);
msq->q_stime = msq->q_rtime = 0;
msq->q_ctime = get_seconds();
msq->q_cbytes = msq->q_qnum = 0;
- msq->q_qbytes = msg_ctlmnb;
+ msq->q_qbytes = ns->msg_ctlmnb;
msq->q_lspid = msq->q_lrpid = 0;
INIT_LIST_HEAD(&msq->q_messages);
INIT_LIST_HEAD(&msq->q_receivers);
@@ -186,13 +231,13 @@ static void expunge_all(struct msg_queue *msq, int res)
* msg_ids.mutex and the spinlock for this message queue is hold
* before freeque() is called. msg_ids.mutex remains locked on exit.
*/
-static void freeque(struct msg_queue *msq, int id)
+static void freeque(struct ipc_namespace *ns, struct msg_queue *msq, int id)
{
struct list_head *tmp;
expunge_all(msq, -EIDRM);
ss_wakeup(&msq->q_senders, 1);
- msq = msg_rmid(id);
+ msq = msg_rmid(ns, id);
msg_unlock(msq);
tmp = msq->q_messages.next;
@@ -212,24 +257,27 @@ asmlinkage long sys_msgget(key_t key, int msgflg)
{
struct msg_queue *msq;
int id, ret = -EPERM;
+ struct ipc_namespace *ns;
+
+ ns = current->nsproxy->ipc_ns;
- mutex_lock(&msg_ids.mutex);
+ mutex_lock(&msg_ids(ns).mutex);
if (key == IPC_PRIVATE)
- ret = newque(key, msgflg);
- else if ((id = ipc_findkey(&msg_ids, key)) == -1) { /* key not used */
+ ret = newque(ns, key, msgflg);
+ else if ((id = ipc_findkey(&msg_ids(ns), key)) == -1) { /* key not used */
if (!(msgflg & IPC_CREAT))
ret = -ENOENT;
else
- ret = newque(key, msgflg);
+ ret = newque(ns, key, msgflg);
} else if (msgflg & IPC_CREAT && msgflg & IPC_EXCL) {
ret = -EEXIST;
} else {
- msq = msg_lock(id);
+ msq = msg_lock(ns, id);
BUG_ON(msq == NULL);
if (ipcperms(&msq->q_perm, msgflg))
ret = -EACCES;
else {
- int qid = msg_buildid(id, msq->q_perm.seq);
+ int qid = msg_buildid(ns, id, msq->q_perm.seq);
ret = security_msg_queue_associate(msq, msgflg);
if (!ret)
@@ -237,7 +285,7 @@ asmlinkage long sys_msgget(key_t key, int msgflg)
}
msg_unlock(msq);
}
- mutex_unlock(&msg_ids.mutex);
+ mutex_unlock(&msg_ids(ns).mutex);
return ret;
}
@@ -341,11 +389,13 @@ asmlinkage long sys_msgctl(int msqid, int cmd, struct msqid_ds __user *buf)
struct msq_setbuf setbuf;
struct msg_queue *msq;
int err, version;
+ struct ipc_namespace *ns;
if (msqid < 0 || cmd < 0)
return -EINVAL;
version = ipc_parse_version(&cmd);
+ ns = current->nsproxy->ipc_ns;
switch (cmd) {
case IPC_INFO:
@@ -366,14 +416,14 @@ asmlinkage long sys_msgctl(int msqid, int cmd, struct msqid_ds __user *buf)
return err;
memset(&msginfo, 0, sizeof(msginfo));
- msginfo.msgmni = msg_ctlmni;
- msginfo.msgmax = msg_ctlmax;
- msginfo.msgmnb = msg_ctlmnb;
+ msginfo.msgmni = ns->msg_ctlmni;
+ msginfo.msgmax = ns->msg_ctlmax;
+ msginfo.msgmnb = ns->msg_ctlmnb;
msginfo.msgssz = MSGSSZ;
msginfo.msgseg = MSGSEG;
- mutex_lock(&msg_ids.mutex);
+ mutex_lock(&msg_ids(ns).mutex);
if (cmd == MSG_INFO) {
- msginfo.msgpool = msg_ids.in_use;
+ msginfo.msgpool = msg_ids(ns).in_use;
msginfo.msgmap = atomic_read(&msg_hdrs);
msginfo.msgtql = atomic_read(&msg_bytes);
} else {
@@ -381,8 +431,8 @@ asmlinkage long sys_msgctl(int msqid, int cmd, struct msqid_ds __user *buf)
msginfo.msgpool = MSGPOOL;
msginfo.msgtql = MSGTQL;
}
- max_id = msg_ids.max_id;
- mutex_unlock(&msg_ids.mutex);
+ max_id = msg_ids(ns).max_id;
+ mutex_unlock(&msg_ids(ns).mutex);
if (copy_to_user(buf, &msginfo, sizeof(struct msginfo)))
return -EFAULT;
return (max_id < 0) ? 0 : max_id;
@@ -395,20 +445,20 @@ asmlinkage long sys_msgctl(int msqid, int cmd, struct msqid_ds __user *buf)
if (!buf)
return -EFAULT;
- if (cmd == MSG_STAT && msqid >= msg_ids.entries->size)
+ if (cmd == MSG_STAT && msqid >= msg_ids(ns).entries->size)
return -EINVAL;
memset(&tbuf, 0, sizeof(tbuf));
- msq = msg_lock(msqid);
+ msq = msg_lock(ns, msqid);
if (msq == NULL)
return -EINVAL;
if (cmd == MSG_STAT) {
- success_return = msg_buildid(msqid, msq->q_perm.seq);
+ success_return = msg_buildid(ns, msqid, msq->q_perm.seq);
} else {
err = -EIDRM;
- if (msg_checkid(msq, msqid))
+ if (msg_checkid(ns, msq, msqid))
goto out_unlock;
success_return = 0;
}
@@ -446,14 +496,14 @@ asmlinkage long sys_msgctl(int msqid, int cmd, struct msqid_ds __user *buf)
return -EINVAL;
}
- mutex_lock(&msg_ids.mutex);
- msq = msg_lock(msqid);
+ mutex_lock(&msg_ids(ns).mutex);
+ msq = msg_lock(ns, msqid);
err = -EINVAL;
if (msq == NULL)
goto out_up;
err = -EIDRM;
- if (msg_checkid(msq, msqid))
+ if (msg_checkid(ns, msq, msqid))
goto out_unlock_up;
ipcp = &msq->q_perm;
@@ -481,7 +531,7 @@ asmlinkage long sys_msgctl(int msqid, int cmd, struct msqid_ds __user *buf)
case IPC_SET:
{
err = -EPERM;
- if (setbuf.qbytes > msg_ctlmnb && !capable(CAP_SYS_RESOURCE))
+ if (setbuf.qbytes > ns->msg_ctlmnb && !capable(CAP_SYS_RESOURCE))
goto out_unlock_up;
msq->q_qbytes = setbuf.qbytes;
@@ -503,12 +553,12 @@ asmlinkage long sys_msgctl(int msqid, int cmd, struct msqid_ds __user *buf)
break;
}
case IPC_RMID:
- freeque(msq, msqid);
+ freeque(ns, msq, msqid);
break;
}
err = 0;
out_up:
- mutex_unlock(&msg_ids.mutex);
+ mutex_unlock(&msg_ids(ns).mutex);
return err;
out_unlock_up:
msg_unlock(msq);
@@ -582,8 +632,11 @@ sys_msgsnd(int msqid, struct msgbuf __user *msgp, size_t msgsz, int msgflg)
struct msg_msg *msg;
long mtype;
int err;
+ struct ipc_namespace *ns;
+
+ ns = current->nsproxy->ipc_ns;
- if (msgsz > msg_ctlmax || (long) msgsz < 0 || msqid < 0)
+ if (msgsz > ns->msg_ctlmax || (long) msgsz < 0 || msqid < 0)
return -EINVAL;
if (get_user(mtype, &msgp->mtype))
return -EFAULT;
@@ -597,13 +650,13 @@ sys_msgsnd(int msqid, struct msgbuf __user *msgp, size_t msgsz, int msgflg)
msg->m_type = mtype;
msg->m_ts = msgsz;
- msq = msg_lock(msqid);
+ msq = msg_lock(ns, msqid);
err = -EINVAL;
if (msq == NULL)
goto out_free;
err= -EIDRM;
- if (msg_checkid(msq, msqid))
+ if (msg_checkid(ns, msq, msqid))
goto out_unlock_free;
for (;;) {
@@ -694,17 +747,19 @@ asmlinkage long sys_msgrcv(int msqid, struct msgbuf __user *msgp, size_t msgsz,
struct msg_queue *msq;
struct msg_msg *msg;
int mode;
+ struct ipc_namespace *ns;
if (msqid < 0 || (long) msgsz < 0)
return -EINVAL;
mode = convert_mode(&msgtyp, msgflg);
+ ns = current->nsproxy->ipc_ns;
- msq = msg_lock(msqid);
+ msq = msg_lock(ns, msqid);
if (msq == NULL)
return -EINVAL;
msg = ERR_PTR(-EIDRM);
- if (msg_checkid(msq, msqid))
+ if (msg_checkid(ns, msq, msqid))
goto out_unlock;
for (;;) {
diff --git a/ipc/sem.c b/ipc/sem.c
index 6013c751156f..0dafcc455f92 100644
--- a/ipc/sem.c
+++ b/ipc/sem.c
@@ -64,6 +64,10 @@
*
* support for audit of ipc object properties and permission changes
* Dustin Kirkland <dustin.kirkland@us.ibm.com>
+ *
+ * namespaces support
+ * OpenVZ, SWsoft Inc.
+ * Pavel Emelianov <xemul@openvz.org>
*/
#include <linux/slab.h>
@@ -78,22 +82,25 @@
#include <linux/capability.h>
#include <linux/seq_file.h>
#include <linux/mutex.h>
+#include <linux/nsproxy.h>
#include <asm/uaccess.h>
#include "util.h"
+#define sem_ids(ns) (*((ns)->ids[IPC_SEM_IDS]))
+
+#define sem_lock(ns, id) ((struct sem_array*)ipc_lock(&sem_ids(ns), id))
+#define sem_unlock(sma) ipc_unlock(&(sma)->sem_perm)
+#define sem_rmid(ns, id) ((struct sem_array*)ipc_rmid(&sem_ids(ns), id))
+#define sem_checkid(ns, sma, semid) \
+ ipc_checkid(&sem_ids(ns),&sma->sem_perm,semid)
+#define sem_buildid(ns, id, seq) \
+ ipc_buildid(&sem_ids(ns), id, seq)
-#define sem_lock(id) ((struct sem_array*)ipc_lock(&sem_ids,id))
-#define sem_unlock(sma) ipc_unlock(&(sma)->sem_perm)
-#define sem_rmid(id) ((struct sem_array*)ipc_rmid(&sem_ids,id))
-#define sem_checkid(sma, semid) \
- ipc_checkid(&sem_ids,&sma->sem_perm,semid)
-#define sem_buildid(id, seq) \
- ipc_buildid(&sem_ids, id, seq)
-static struct ipc_ids sem_ids;
+static struct ipc_ids init_sem_ids;
-static int newary (key_t, int, int);
-static void freeary (struct sem_array *sma, int id);
+static int newary(struct ipc_namespace *, key_t, int, int);
+static void freeary(struct ipc_namespace *ns, struct sem_array *sma, int id);
#ifdef CONFIG_PROC_FS
static int sysvipc_sem_proc_show(struct seq_file *s, void *it);
#endif
@@ -110,22 +117,61 @@ static int sysvipc_sem_proc_show(struct seq_file *s, void *it);
*
*/
-int sem_ctls[4] = {SEMMSL, SEMMNS, SEMOPM, SEMMNI};
-#define sc_semmsl (sem_ctls[0])
-#define sc_semmns (sem_ctls[1])
-#define sc_semopm (sem_ctls[2])
-#define sc_semmni (sem_ctls[3])
+#define sc_semmsl sem_ctls[0]
+#define sc_semmns sem_ctls[1]
+#define sc_semopm sem_ctls[2]
+#define sc_semmni sem_ctls[3]
-static int used_sems;
+static void __ipc_init __sem_init_ns(struct ipc_namespace *ns, struct ipc_ids *ids)
+{
+ ns->ids[IPC_SEM_IDS] = ids;
+ ns->sc_semmsl = SEMMSL;
+ ns->sc_semmns = SEMMNS;
+ ns->sc_semopm = SEMOPM;
+ ns->sc_semmni = SEMMNI;
+ ns->used_sems = 0;
+ ipc_init_ids(ids, ns->sc_semmni);
+}
+
+#ifdef CONFIG_IPC_NS
+int sem_init_ns(struct ipc_namespace *ns)
+{
+ struct ipc_ids *ids;
+
+ ids = kmalloc(sizeof(struct ipc_ids), GFP_KERNEL);
+ if (ids == NULL)
+ return -ENOMEM;
+
+ __sem_init_ns(ns, ids);
+ return 0;
+}
+
+void sem_exit_ns(struct ipc_namespace *ns)
+{
+ int i;
+ struct sem_array *sma;
+
+ mutex_lock(&sem_ids(ns).mutex);
+ for (i = 0; i <= sem_ids(ns).max_id; i++) {
+ sma = sem_lock(ns, i);
+ if (sma == NULL)
+ continue;
+
+ freeary(ns, sma, i);
+ }
+ mutex_unlock(&sem_ids(ns).mutex);
+
+ kfree(ns->ids[IPC_SEM_IDS]);
+ ns->ids[IPC_SEM_IDS] = NULL;
+}
+#endif
void __init sem_init (void)
{
- used_sems = 0;
- ipc_init_ids(&sem_ids,sc_semmni);
+ __sem_init_ns(&init_ipc_ns, &init_sem_ids);
ipc_init_proc_interface("sysvipc/sem",
" key semid perms nsems uid gid cuid cgid otime ctime\n",
- &sem_ids,
- sysvipc_sem_proc_show);
+ IPC_SEM_IDS, sysvipc_sem_proc_show);
}
/*
@@ -162,7 +208,7 @@ void __init sem_init (void)
*/
#define IN_WAKEUP 1
-static int newary (key_t key, int nsems, int semflg)
+static int newary (struct ipc_namespace *ns, key_t key, int nsems, int semflg)
{
int id;
int retval;
@@ -171,7 +217,7 @@ static int newary (key_t key, int nsems, int semflg)
if (!nsems)
return -EINVAL;
- if (used_sems + nsems > sc_semmns)
+ if (ns->used_sems + nsems > ns->sc_semmns)
return -ENOSPC;
size = sizeof (*sma) + nsems * sizeof (struct sem);
@@ -191,15 +237,15 @@ static int newary (key_t key, int nsems, int semflg)
return retval;
}
- id = ipc_addid(&sem_ids, &sma->sem_perm, sc_semmni);
+ id = ipc_addid(&sem_ids(ns), &sma->sem_perm, ns->sc_semmni);
if(id == -1) {
security_sem_free(sma);
ipc_rcu_putref(sma);
return -ENOSPC;
}
- used_sems += nsems;
+ ns->used_sems += nsems;
- sma->sem_id = sem_buildid(id, sma->sem_perm.seq);
+ sma->sem_id = sem_buildid(ns, id, sma->sem_perm.seq);
sma->sem_base = (struct sem *) &sma[1];
/* sma->sem_pending = NULL; */
sma->sem_pending_last = &sma->sem_pending;
@@ -215,29 +261,32 @@ asmlinkage long sys_semget (key_t key, int nsems, int semflg)
{
int id, err = -EINVAL;
struct sem_array *sma;
+ struct ipc_namespace *ns;
- if (nsems < 0 || nsems > sc_semmsl)
+ ns = current->nsproxy->ipc_ns;
+
+ if (nsems < 0 || nsems > ns->sc_semmsl)
return -EINVAL;
- mutex_lock(&sem_ids.mutex);
+ mutex_lock(&sem_ids(ns).mutex);
if (key == IPC_PRIVATE) {
- err = newary(key, nsems, semflg);
- } else if ((id = ipc_findkey(&sem_ids, key)) == -1) { /* key not used */
+ err = newary(ns, key, nsems, semflg);
+ } else if ((id = ipc_findkey(&sem_ids(ns), key)) == -1) { /* key not used */
if (!(semflg & IPC_CREAT))
err = -ENOENT;
else
- err = newary(key, nsems, semflg);
+ err = newary(ns, key, nsems, semflg);
} else if (semflg & IPC_CREAT && semflg & IPC_EXCL) {
err = -EEXIST;
} else {
- sma = sem_lock(id);
+ sma = sem_lock(ns, id);
BUG_ON(sma==NULL);
if (nsems > sma->sem_nsems)
err = -EINVAL;
else if (ipcperms(&sma->sem_perm, semflg))
err = -EACCES;
else {
- int semid = sem_buildid(id, sma->sem_perm.seq);
+ int semid = sem_buildid(ns, id, sma->sem_perm.seq);
err = security_sem_associate(sma, semflg);
if (!err)
err = semid;
@@ -245,7 +294,7 @@ asmlinkage long sys_semget (key_t key, int nsems, int semflg)
sem_unlock(sma);
}
- mutex_unlock(&sem_ids.mutex);
+ mutex_unlock(&sem_ids(ns).mutex);
return err;
}
@@ -444,7 +493,7 @@ static int count_semzcnt (struct sem_array * sma, ushort semnum)
* the spinlock for this semaphore set hold. sem_ids.mutex remains locked
* on exit.
*/
-static void freeary (struct sem_array *sma, int id)
+static void freeary (struct ipc_namespace *ns, struct sem_array *sma, int id)
{
struct sem_undo *un;
struct sem_queue *q;
@@ -472,10 +521,10 @@ static void freeary (struct sem_array *sma, int id)
}
/* Remove the semaphore set from the ID array*/
- sma = sem_rmid(id);
+ sma = sem_rmid(ns, id);
sem_unlock(sma);
- used_sems -= sma->sem_nsems;
+ ns->used_sems -= sma->sem_nsems;
size = sizeof (*sma) + sma->sem_nsems * sizeof (struct sem);
security_sem_free(sma);
ipc_rcu_putref(sma);
@@ -503,7 +552,8 @@ static unsigned long copy_semid_to_user(void __user *buf, struct semid64_ds *in,
}
}
-static int semctl_nolock(int semid, int semnum, int cmd, int version, union semun arg)
+static int semctl_nolock(struct ipc_namespace *ns, int semid, int semnum,
+ int cmd, int version, union semun arg)
{
int err = -EINVAL;
struct sem_array *sma;
@@ -520,24 +570,24 @@ static int semctl_nolock(int semid, int semnum, int cmd, int version, union semu
return err;
memset(&seminfo,0,sizeof(seminfo));
- seminfo.semmni = sc_semmni;
- seminfo.semmns = sc_semmns;
- seminfo.semmsl = sc_semmsl;
- seminfo.semopm = sc_semopm;
+ seminfo.semmni = ns->sc_semmni;
+ seminfo.semmns = ns->sc_semmns;
+ seminfo.semmsl = ns->sc_semmsl;
+ seminfo.semopm = ns->sc_semopm;
seminfo.semvmx = SEMVMX;
seminfo.semmnu = SEMMNU;
seminfo.semmap = SEMMAP;
seminfo.semume = SEMUME;
- mutex_lock(&sem_ids.mutex);
+ mutex_lock(&sem_ids(ns).mutex);
if (cmd == SEM_INFO) {
- seminfo.semusz = sem_ids.in_use;
- seminfo.semaem = used_sems;
+ seminfo.semusz = sem_ids(ns).in_use;
+ seminfo.semaem = ns->used_sems;
} else {
seminfo.semusz = SEMUSZ;
seminfo.semaem = SEMAEM;
}
- max_id = sem_ids.max_id;
- mutex_unlock(&sem_ids.mutex);
+ max_id = sem_ids(ns).max_id;
+ mutex_unlock(&sem_ids(ns).mutex);
if (copy_to_user (arg.__buf, &seminfo, sizeof(struct seminfo)))
return -EFAULT;
return (max_id < 0) ? 0: max_id;
@@ -547,12 +597,12 @@ static int semctl_nolock(int semid, int semnum, int cmd, int version, union semu
struct semid64_ds tbuf;
int id;
- if(semid >= sem_ids.entries->size)
+ if(semid >= sem_ids(ns).entries->size)
return -EINVAL;
memset(&tbuf,0,sizeof(tbuf));
- sma = sem_lock(semid);
+ sma = sem_lock(ns, semid);
if(sma == NULL)
return -EINVAL;
@@ -564,7 +614,7 @@ static int semctl_nolock(int semid, int semnum, int cmd, int version, union semu
if (err)
goto out_unlock;
- id = sem_buildid(semid, sma->sem_perm.seq);
+ id = sem_buildid(ns, semid, sma->sem_perm.seq);
kernel_to_ipc64_perm(&sma->sem_perm, &tbuf.sem_perm);
tbuf.sem_otime = sma->sem_otime;
@@ -584,7 +634,8 @@ out_unlock:
return err;
}
-static int semctl_main(int semid, int semnum, int cmd, int version, union semun arg)
+static int semctl_main(struct ipc_namespace *ns, int semid, int semnum,
+ int cmd, int version, union semun arg)
{
struct sem_array *sma;
struct sem* curr;
@@ -593,14 +644,14 @@ static int semctl_main(int semid, int semnum, int cmd, int version, union semun
ushort* sem_io = fast_sem_io;
int nsems;
- sma = sem_lock(semid);
+ sma = sem_lock(ns, semid);
if(sma==NULL)
return -EINVAL;
nsems = sma->sem_nsems;
err=-EIDRM;
- if (sem_checkid(sma,semid))
+ if (sem_checkid(ns,sma,semid))
goto out_unlock;
err = -EACCES;
@@ -802,7 +853,8 @@ static inline unsigned long copy_semid_from_user(struct sem_setbuf *out, void __
}
}
-static int semctl_down(int semid, int semnum, int cmd, int version, union semun arg)
+static int semctl_down(struct ipc_namespace *ns, int semid, int semnum,
+ int cmd, int version, union semun arg)
{
struct sem_array *sma;
int err;
@@ -813,11 +865,11 @@ static int semctl_down(int semid, int semnum, int cmd, int version, union semun
if(copy_semid_from_user (&setbuf, arg.buf, version))
return -EFAULT;
}
- sma = sem_lock(semid);
+ sma = sem_lock(ns, semid);
if(sma==NULL)
return -EINVAL;
- if (sem_checkid(sma,semid)) {
+ if (sem_checkid(ns,sma,semid)) {
err=-EIDRM;
goto out_unlock;
}
@@ -844,7 +896,7 @@ static int semctl_down(int semid, int semnum, int cmd, int version, union semun
switch(cmd){
case IPC_RMID:
- freeary(sma, semid);
+ freeary(ns, sma, semid);
err = 0;
break;
case IPC_SET:
@@ -872,17 +924,19 @@ asmlinkage long sys_semctl (int semid, int semnum, int cmd, union semun arg)
{
int err = -EINVAL;
int version;
+ struct ipc_namespace *ns;
if (semid < 0)
return -EINVAL;
version = ipc_parse_version(&cmd);
+ ns = current->nsproxy->ipc_ns;
switch(cmd) {
case IPC_INFO:
case SEM_INFO:
case SEM_STAT:
- err = semctl_nolock(semid,semnum,cmd,version,arg);
+ err = semctl_nolock(ns,semid,semnum,cmd,version,arg);
return err;
case GETALL:
case GETVAL:
@@ -892,13 +946,13 @@ asmlinkage long sys_semctl (int semid, int semnum, int cmd, union semun arg)
case IPC_STAT:
case SETVAL:
case SETALL:
- err = semctl_main(semid,semnum,cmd,version,arg);
+ err = semctl_main(ns,semid,semnum,cmd,version,arg);
return err;
case IPC_RMID:
case IPC_SET:
- mutex_lock(&sem_ids.mutex);
- err = semctl_down(semid,semnum,cmd,version,arg);
- mutex_unlock(&sem_ids.mutex);
+ mutex_lock(&sem_ids(ns).mutex);
+ err = semctl_down(ns,semid,semnum,cmd,version,arg);
+ mutex_unlock(&sem_ids(ns).mutex);
return err;
default:
return -EINVAL;
@@ -949,15 +1003,12 @@ static inline void unlock_semundo(void)
static inline int get_undo_list(struct sem_undo_list **undo_listp)
{
struct sem_undo_list *undo_list;
- int size;
undo_list = current->sysvsem.undo_list;
if (!undo_list) {
- size = sizeof(struct sem_undo_list);
- undo_list = (struct sem_undo_list *) kmalloc(size, GFP_KERNEL);
+ undo_list = kzalloc(sizeof(*undo_list), GFP_KERNEL);
if (undo_list == NULL)
return -ENOMEM;
- memset(undo_list, 0, size);
spin_lock_init(&undo_list->lock);
atomic_set(&undo_list->refcnt, 1);
current->sysvsem.undo_list = undo_list;
@@ -986,7 +1037,7 @@ static struct sem_undo *lookup_undo(struct sem_undo_list *ulp, int semid)
return un;
}
-static struct sem_undo *find_undo(int semid)
+static struct sem_undo *find_undo(struct ipc_namespace *ns, int semid)
{
struct sem_array *sma;
struct sem_undo_list *ulp;
@@ -1005,12 +1056,12 @@ static struct sem_undo *find_undo(int semid)
goto out;
/* no undo structure around - allocate one. */
- sma = sem_lock(semid);
+ sma = sem_lock(ns, semid);
un = ERR_PTR(-EINVAL);
if(sma==NULL)
goto out;
un = ERR_PTR(-EIDRM);
- if (sem_checkid(sma,semid)) {
+ if (sem_checkid(ns,sma,semid)) {
sem_unlock(sma);
goto out;
}
@@ -1070,10 +1121,13 @@ asmlinkage long sys_semtimedop(int semid, struct sembuf __user *tsops,
int undos = 0, alter = 0, max;
struct sem_queue queue;
unsigned long jiffies_left = 0;
+ struct ipc_namespace *ns;
+
+ ns = current->nsproxy->ipc_ns;
if (nsops < 1 || semid < 0)
return -EINVAL;
- if (nsops > sc_semopm)
+ if (nsops > ns->sc_semopm)
return -E2BIG;
if(nsops > SEMOPM_FAST) {
sops = kmalloc(sizeof(*sops)*nsops,GFP_KERNEL);
@@ -1109,7 +1163,7 @@ asmlinkage long sys_semtimedop(int semid, struct sembuf __user *tsops,
retry_undos:
if (undos) {
- un = find_undo(semid);
+ un = find_undo(ns, semid);
if (IS_ERR(un)) {
error = PTR_ERR(un);
goto out_free;
@@ -1117,12 +1171,12 @@ retry_undos:
} else
un = NULL;
- sma = sem_lock(semid);
+ sma = sem_lock(ns, semid);
error=-EINVAL;
if(sma==NULL)
goto out_free;
error = -EIDRM;
- if (sem_checkid(sma,semid))
+ if (sem_checkid(ns,sma,semid))
goto out_unlock_free;
/*
* semid identifies are not unique - find_undo may have
@@ -1190,7 +1244,7 @@ retry_undos:
goto out_free;
}
- sma = sem_lock(semid);
+ sma = sem_lock(ns, semid);
if(sma==NULL) {
BUG_ON(queue.prev != NULL);
error = -EIDRM;
@@ -1267,6 +1321,7 @@ void exit_sem(struct task_struct *tsk)
{
struct sem_undo_list *undo_list;
struct sem_undo *u, **up;
+ struct ipc_namespace *ns;
undo_list = tsk->sysvsem.undo_list;
if (!undo_list)
@@ -1275,6 +1330,7 @@ void exit_sem(struct task_struct *tsk)
if (!atomic_dec_and_test(&undo_list->refcnt))
return;
+ ns = tsk->nsproxy->ipc_ns;
/* There's no need to hold the semundo list lock, as current
* is the last task exiting for this undo list.
*/
@@ -1288,14 +1344,14 @@ void exit_sem(struct task_struct *tsk)
if(semid == -1)
continue;
- sma = sem_lock(semid);
+ sma = sem_lock(ns, semid);
if (sma == NULL)
continue;
if (u->semid == -1)
goto next_entry;
- BUG_ON(sem_checkid(sma,u->semid));
+ BUG_ON(sem_checkid(ns,sma,u->semid));
/* remove u from the sma->undo list */
for (unp = &sma->undo; (un = *unp); unp = &un->id_next) {
diff --git a/ipc/shm.c b/ipc/shm.c
index 940b0c9b13aa..bfbd317ec11c 100644
--- a/ipc/shm.c
+++ b/ipc/shm.c
@@ -15,6 +15,10 @@
*
* support for audit of ipc object properties and permission changes
* Dustin Kirkland <dustin.kirkland@us.ibm.com>
+ *
+ * namespaces support
+ * OpenVZ, SWsoft Inc.
+ * Pavel Emelianov <xemul@openvz.org>
*/
#include <linux/slab.h>
@@ -32,6 +36,7 @@
#include <linux/ptrace.h>
#include <linux/seq_file.h>
#include <linux/mutex.h>
+#include <linux/nsproxy.h>
#include <asm/uaccess.h>
@@ -40,59 +45,115 @@
static struct file_operations shm_file_operations;
static struct vm_operations_struct shm_vm_ops;
-static struct ipc_ids shm_ids;
+static struct ipc_ids init_shm_ids;
+
+#define shm_ids(ns) (*((ns)->ids[IPC_SHM_IDS]))
-#define shm_lock(id) ((struct shmid_kernel*)ipc_lock(&shm_ids,id))
-#define shm_unlock(shp) ipc_unlock(&(shp)->shm_perm)
-#define shm_get(id) ((struct shmid_kernel*)ipc_get(&shm_ids,id))
-#define shm_buildid(id, seq) \
- ipc_buildid(&shm_ids, id, seq)
+#define shm_lock(ns, id) \
+ ((struct shmid_kernel*)ipc_lock(&shm_ids(ns),id))
+#define shm_unlock(shp) \
+ ipc_unlock(&(shp)->shm_perm)
+#define shm_get(ns, id) \
+ ((struct shmid_kernel*)ipc_get(&shm_ids(ns),id))
+#define shm_buildid(ns, id, seq) \
+ ipc_buildid(&shm_ids(ns), id, seq)
-static int newseg (key_t key, int shmflg, size_t size);
+static int newseg (struct ipc_namespace *ns, key_t key,
+ int shmflg, size_t size);
static void shm_open (struct vm_area_struct *shmd);
static void shm_close (struct vm_area_struct *shmd);
+static void shm_destroy (struct ipc_namespace *ns, struct shmid_kernel *shp);
#ifdef CONFIG_PROC_FS
static int sysvipc_shm_proc_show(struct seq_file *s, void *it);
#endif
-size_t shm_ctlmax = SHMMAX;
-size_t shm_ctlall = SHMALL;
-int shm_ctlmni = SHMMNI;
+static void __ipc_init __shm_init_ns(struct ipc_namespace *ns, struct ipc_ids *ids)
+{
+ ns->ids[IPC_SHM_IDS] = ids;
+ ns->shm_ctlmax = SHMMAX;
+ ns->shm_ctlall = SHMALL;
+ ns->shm_ctlmni = SHMMNI;
+ ns->shm_tot = 0;
+ ipc_init_ids(ids, 1);
+}
+
+static void do_shm_rmid(struct ipc_namespace *ns, struct shmid_kernel *shp)
+{
+ if (shp->shm_nattch){
+ shp->shm_perm.mode |= SHM_DEST;
+ /* Do not find it any more */
+ shp->shm_perm.key = IPC_PRIVATE;
+ shm_unlock(shp);
+ } else
+ shm_destroy(ns, shp);
+}
+
+#ifdef CONFIG_IPC_NS
+int shm_init_ns(struct ipc_namespace *ns)
+{
+ struct ipc_ids *ids;
+
+ ids = kmalloc(sizeof(struct ipc_ids), GFP_KERNEL);
+ if (ids == NULL)
+ return -ENOMEM;
-static int shm_tot; /* total number of shared memory pages */
+ __shm_init_ns(ns, ids);
+ return 0;
+}
+
+void shm_exit_ns(struct ipc_namespace *ns)
+{
+ int i;
+ struct shmid_kernel *shp;
+
+ mutex_lock(&shm_ids(ns).mutex);
+ for (i = 0; i <= shm_ids(ns).max_id; i++) {
+ shp = shm_lock(ns, i);
+ if (shp == NULL)
+ continue;
+
+ do_shm_rmid(ns, shp);
+ }
+ mutex_unlock(&shm_ids(ns).mutex);
+
+ kfree(ns->ids[IPC_SHM_IDS]);
+ ns->ids[IPC_SHM_IDS] = NULL;
+}
+#endif
void __init shm_init (void)
{
- ipc_init_ids(&shm_ids, 1);
+ __shm_init_ns(&init_ipc_ns, &init_shm_ids);
ipc_init_proc_interface("sysvipc/shm",
" key shmid perms size cpid lpid nattch uid gid cuid cgid atime dtime ctime\n",
- &shm_ids,
- sysvipc_shm_proc_show);
+ IPC_SHM_IDS, sysvipc_shm_proc_show);
}
-static inline int shm_checkid(struct shmid_kernel *s, int id)
+static inline int shm_checkid(struct ipc_namespace *ns,
+ struct shmid_kernel *s, int id)
{
- if (ipc_checkid(&shm_ids,&s->shm_perm,id))
+ if (ipc_checkid(&shm_ids(ns), &s->shm_perm, id))
return -EIDRM;
return 0;
}
-static inline struct shmid_kernel *shm_rmid(int id)
+static inline struct shmid_kernel *shm_rmid(struct ipc_namespace *ns, int id)
{
- return (struct shmid_kernel *)ipc_rmid(&shm_ids,id);
+ return (struct shmid_kernel *)ipc_rmid(&shm_ids(ns), id);
}
-static inline int shm_addid(struct shmid_kernel *shp)
+static inline int shm_addid(struct ipc_namespace *ns, struct shmid_kernel *shp)
{
- return ipc_addid(&shm_ids, &shp->shm_perm, shm_ctlmni);
+ return ipc_addid(&shm_ids(ns), &shp->shm_perm, ns->shm_ctlmni);
}
-static inline void shm_inc (int id) {
+static inline void shm_inc(struct ipc_namespace *ns, int id)
+{
struct shmid_kernel *shp;
- shp = shm_lock(id);
+ shp = shm_lock(ns, id);
BUG_ON(!shp);
shp->shm_atim = get_seconds();
shp->shm_lprid = current->tgid;
@@ -100,10 +161,13 @@ static inline void shm_inc (int id) {
shm_unlock(shp);
}
+#define shm_file_ns(file) (*((struct ipc_namespace **)&(file)->private_data))
+
/* This is called by fork, once for every shm attach. */
-static void shm_open (struct vm_area_struct *shmd)
+static void shm_open(struct vm_area_struct *shmd)
{
- shm_inc (shmd->vm_file->f_dentry->d_inode->i_ino);
+ shm_inc(shm_file_ns(shmd->vm_file),
+ shmd->vm_file->f_dentry->d_inode->i_ino);
}
/*
@@ -114,10 +178,10 @@ static void shm_open (struct vm_area_struct *shmd)
* It has to be called with shp and shm_ids.mutex locked,
* but returns with shp unlocked and freed.
*/
-static void shm_destroy (struct shmid_kernel *shp)
+static void shm_destroy(struct ipc_namespace *ns, struct shmid_kernel *shp)
{
- shm_tot -= (shp->shm_segsz + PAGE_SIZE - 1) >> PAGE_SHIFT;
- shm_rmid (shp->id);
+ ns->shm_tot -= (shp->shm_segsz + PAGE_SIZE - 1) >> PAGE_SHIFT;
+ shm_rmid(ns, shp->id);
shm_unlock(shp);
if (!is_file_hugepages(shp->shm_file))
shmem_lock(shp->shm_file, 0, shp->mlock_user);
@@ -140,20 +204,23 @@ static void shm_close (struct vm_area_struct *shmd)
struct file * file = shmd->vm_file;
int id = file->f_dentry->d_inode->i_ino;
struct shmid_kernel *shp;
+ struct ipc_namespace *ns;
- mutex_lock(&shm_ids.mutex);
+ ns = shm_file_ns(file);
+
+ mutex_lock(&shm_ids(ns).mutex);
/* remove from the list of attaches of the shm segment */
- shp = shm_lock(id);
+ shp = shm_lock(ns, id);
BUG_ON(!shp);
shp->shm_lprid = current->tgid;
shp->shm_dtim = get_seconds();
shp->shm_nattch--;
if(shp->shm_nattch == 0 &&
shp->shm_perm.mode & SHM_DEST)
- shm_destroy (shp);
+ shm_destroy(ns, shp);
else
shm_unlock(shp);
- mutex_unlock(&shm_ids.mutex);
+ mutex_unlock(&shm_ids(ns).mutex);
}
static int shm_mmap(struct file * file, struct vm_area_struct * vma)
@@ -165,14 +232,25 @@ static int shm_mmap(struct file * file, struct vm_area_struct * vma)
vma->vm_ops = &shm_vm_ops;
if (!(vma->vm_flags & VM_WRITE))
vma->vm_flags &= ~VM_MAYWRITE;
- shm_inc(file->f_dentry->d_inode->i_ino);
+ shm_inc(shm_file_ns(file), file->f_dentry->d_inode->i_ino);
}
return ret;
}
+static int shm_release(struct inode *ino, struct file *file)
+{
+ struct ipc_namespace *ns;
+
+ ns = shm_file_ns(file);
+ put_ipc_ns(ns);
+ shm_file_ns(file) = NULL;
+ return 0;
+}
+
static struct file_operations shm_file_operations = {
- .mmap = shm_mmap,
+ .mmap = shm_mmap,
+ .release = shm_release,
#ifndef CONFIG_MMU
.get_unmapped_area = shmem_get_unmapped_area,
#endif
@@ -188,7 +266,7 @@ static struct vm_operations_struct shm_vm_ops = {
#endif
};
-static int newseg (key_t key, int shmflg, size_t size)
+static int newseg (struct ipc_namespace *ns, key_t key, int shmflg, size_t size)
{
int error;
struct shmid_kernel *shp;
@@ -197,10 +275,10 @@ static int newseg (key_t key, int shmflg, size_t size)
char name[13];
int id;
- if (size < SHMMIN || size > shm_ctlmax)
+ if (size < SHMMIN || size > ns->shm_ctlmax)
return -EINVAL;
- if (shm_tot + numpages >= shm_ctlall)
+ if (ns->shm_tot + numpages >= ns->shm_ctlall)
return -ENOSPC;
shp = ipc_rcu_alloc(sizeof(*shp));
@@ -239,7 +317,7 @@ static int newseg (key_t key, int shmflg, size_t size)
goto no_file;
error = -ENOSPC;
- id = shm_addid(shp);
+ id = shm_addid(ns, shp);
if(id == -1)
goto no_id;
@@ -249,15 +327,17 @@ static int newseg (key_t key, int shmflg, size_t size)
shp->shm_ctim = get_seconds();
shp->shm_segsz = size;
shp->shm_nattch = 0;
- shp->id = shm_buildid(id,shp->shm_perm.seq);
+ shp->id = shm_buildid(ns, id, shp->shm_perm.seq);
shp->shm_file = file;
file->f_dentry->d_inode->i_ino = shp->id;
+ shm_file_ns(file) = get_ipc_ns(ns);
+
/* Hugetlb ops would have already been assigned. */
if (!(shmflg & SHM_HUGETLB))
file->f_op = &shm_file_operations;
- shm_tot += numpages;
+ ns->shm_tot += numpages;
shm_unlock(shp);
return shp->id;
@@ -273,33 +353,36 @@ asmlinkage long sys_shmget (key_t key, size_t size, int shmflg)
{
struct shmid_kernel *shp;
int err, id = 0;
+ struct ipc_namespace *ns;
+
+ ns = current->nsproxy->ipc_ns;
- mutex_lock(&shm_ids.mutex);
+ mutex_lock(&shm_ids(ns).mutex);
if (key == IPC_PRIVATE) {
- err = newseg(key, shmflg, size);
- } else if ((id = ipc_findkey(&shm_ids, key)) == -1) {
+ err = newseg(ns, key, shmflg, size);
+ } else if ((id = ipc_findkey(&shm_ids(ns), key)) == -1) {
if (!(shmflg & IPC_CREAT))
err = -ENOENT;
else
- err = newseg(key, shmflg, size);
+ err = newseg(ns, key, shmflg, size);
} else if ((shmflg & IPC_CREAT) && (shmflg & IPC_EXCL)) {
err = -EEXIST;
} else {
- shp = shm_lock(id);
+ shp = shm_lock(ns, id);
BUG_ON(shp==NULL);
if (shp->shm_segsz < size)
err = -EINVAL;
else if (ipcperms(&shp->shm_perm, shmflg))
err = -EACCES;
else {
- int shmid = shm_buildid(id, shp->shm_perm.seq);
+ int shmid = shm_buildid(ns, id, shp->shm_perm.seq);
err = security_shm_associate(shp, shmflg);
if (!err)
err = shmid;
}
shm_unlock(shp);
}
- mutex_unlock(&shm_ids.mutex);
+ mutex_unlock(&shm_ids(ns).mutex);
return err;
}
@@ -395,18 +478,19 @@ static inline unsigned long copy_shminfo_to_user(void __user *buf, struct shminf
}
}
-static void shm_get_stat(unsigned long *rss, unsigned long *swp)
+static void shm_get_stat(struct ipc_namespace *ns, unsigned long *rss,
+ unsigned long *swp)
{
int i;
*rss = 0;
*swp = 0;
- for (i = 0; i <= shm_ids.max_id; i++) {
+ for (i = 0; i <= shm_ids(ns).max_id; i++) {
struct shmid_kernel *shp;
struct inode *inode;
- shp = shm_get(i);
+ shp = shm_get(ns, i);
if(!shp)
continue;
@@ -430,6 +514,7 @@ asmlinkage long sys_shmctl (int shmid, int cmd, struct shmid_ds __user *buf)
struct shm_setbuf setbuf;
struct shmid_kernel *shp;
int err, version;
+ struct ipc_namespace *ns;
if (cmd < 0 || shmid < 0) {
err = -EINVAL;
@@ -437,6 +522,7 @@ asmlinkage long sys_shmctl (int shmid, int cmd, struct shmid_ds __user *buf)
}
version = ipc_parse_version(&cmd);
+ ns = current->nsproxy->ipc_ns;
switch (cmd) { /* replace with proc interface ? */
case IPC_INFO:
@@ -448,15 +534,15 @@ asmlinkage long sys_shmctl (int shmid, int cmd, struct shmid_ds __user *buf)
return err;
memset(&shminfo,0,sizeof(shminfo));
- shminfo.shmmni = shminfo.shmseg = shm_ctlmni;
- shminfo.shmmax = shm_ctlmax;
- shminfo.shmall = shm_ctlall;
+ shminfo.shmmni = shminfo.shmseg = ns->shm_ctlmni;
+ shminfo.shmmax = ns->shm_ctlmax;
+ shminfo.shmall = ns->shm_ctlall;
shminfo.shmmin = SHMMIN;
if(copy_shminfo_to_user (buf, &shminfo, version))
return -EFAULT;
/* reading a integer is always atomic */
- err= shm_ids.max_id;
+ err= shm_ids(ns).max_id;
if(err<0)
err = 0;
goto out;
@@ -470,14 +556,14 @@ asmlinkage long sys_shmctl (int shmid, int cmd, struct shmid_ds __user *buf)
return err;
memset(&shm_info,0,sizeof(shm_info));
- mutex_lock(&shm_ids.mutex);
- shm_info.used_ids = shm_ids.in_use;
- shm_get_stat (&shm_info.shm_rss, &shm_info.shm_swp);
- shm_info.shm_tot = shm_tot;
+ mutex_lock(&shm_ids(ns).mutex);
+ shm_info.used_ids = shm_ids(ns).in_use;
+ shm_get_stat (ns, &shm_info.shm_rss, &shm_info.shm_swp);
+ shm_info.shm_tot = ns->shm_tot;
shm_info.swap_attempts = 0;
shm_info.swap_successes = 0;
- err = shm_ids.max_id;
- mutex_unlock(&shm_ids.mutex);
+ err = shm_ids(ns).max_id;
+ mutex_unlock(&shm_ids(ns).mutex);
if(copy_to_user (buf, &shm_info, sizeof(shm_info))) {
err = -EFAULT;
goto out;
@@ -492,17 +578,17 @@ asmlinkage long sys_shmctl (int shmid, int cmd, struct shmid_ds __user *buf)
struct shmid64_ds tbuf;
int result;
memset(&tbuf, 0, sizeof(tbuf));
- shp = shm_lock(shmid);
+ shp = shm_lock(ns, shmid);
if(shp==NULL) {
err = -EINVAL;
goto out;
} else if(cmd==SHM_STAT) {
err = -EINVAL;
- if (shmid > shm_ids.max_id)
+ if (shmid > shm_ids(ns).max_id)
goto out_unlock;
- result = shm_buildid(shmid, shp->shm_perm.seq);
+ result = shm_buildid(ns, shmid, shp->shm_perm.seq);
} else {
- err = shm_checkid(shp,shmid);
+ err = shm_checkid(ns, shp,shmid);
if(err)
goto out_unlock;
result = 0;
@@ -534,12 +620,12 @@ asmlinkage long sys_shmctl (int shmid, int cmd, struct shmid_ds __user *buf)
case SHM_LOCK:
case SHM_UNLOCK:
{
- shp = shm_lock(shmid);
+ shp = shm_lock(ns, shmid);
if(shp==NULL) {
err = -EINVAL;
goto out;
}
- err = shm_checkid(shp,shmid);
+ err = shm_checkid(ns, shp,shmid);
if(err)
goto out_unlock;
@@ -590,12 +676,12 @@ asmlinkage long sys_shmctl (int shmid, int cmd, struct shmid_ds __user *buf)
* Instead we set a destroyed flag, and then blow
* the name away when the usage hits zero.
*/
- mutex_lock(&shm_ids.mutex);
- shp = shm_lock(shmid);
+ mutex_lock(&shm_ids(ns).mutex);
+ shp = shm_lock(ns, shmid);
err = -EINVAL;
if (shp == NULL)
goto out_up;
- err = shm_checkid(shp, shmid);
+ err = shm_checkid(ns, shp, shmid);
if(err)
goto out_unlock_up;
@@ -614,14 +700,8 @@ asmlinkage long sys_shmctl (int shmid, int cmd, struct shmid_ds __user *buf)
if (err)
goto out_unlock_up;
- if (shp->shm_nattch){
- shp->shm_perm.mode |= SHM_DEST;
- /* Do not find it any more */
- shp->shm_perm.key = IPC_PRIVATE;
- shm_unlock(shp);
- } else
- shm_destroy (shp);
- mutex_unlock(&shm_ids.mutex);
+ do_shm_rmid(ns, shp);
+ mutex_unlock(&shm_ids(ns).mutex);
goto out;
}
@@ -631,12 +711,12 @@ asmlinkage long sys_shmctl (int shmid, int cmd, struct shmid_ds __user *buf)
err = -EFAULT;
goto out;
}
- mutex_lock(&shm_ids.mutex);
- shp = shm_lock(shmid);
+ mutex_lock(&shm_ids(ns).mutex);
+ shp = shm_lock(ns, shmid);
err=-EINVAL;
if(shp==NULL)
goto out_up;
- err = shm_checkid(shp,shmid);
+ err = shm_checkid(ns, shp,shmid);
if(err)
goto out_unlock_up;
err = audit_ipc_obj(&(shp->shm_perm));
@@ -673,7 +753,7 @@ asmlinkage long sys_shmctl (int shmid, int cmd, struct shmid_ds __user *buf)
out_unlock_up:
shm_unlock(shp);
out_up:
- mutex_unlock(&shm_ids.mutex);
+ mutex_unlock(&shm_ids(ns).mutex);
goto out;
out_unlock:
shm_unlock(shp);
@@ -699,6 +779,7 @@ long do_shmat(int shmid, char __user *shmaddr, int shmflg, ulong *raddr)
unsigned long prot;
int acc_mode;
void *user_addr;
+ struct ipc_namespace *ns;
if (shmid < 0) {
err = -EINVAL;
@@ -737,12 +818,13 @@ long do_shmat(int shmid, char __user *shmaddr, int shmflg, ulong *raddr)
* We cannot rely on the fs check since SYSV IPC does have an
* additional creator id...
*/
- shp = shm_lock(shmid);
+ ns = current->nsproxy->ipc_ns;
+ shp = shm_lock(ns, shmid);
if(shp == NULL) {
err = -EINVAL;
goto out;
}
- err = shm_checkid(shp,shmid);
+ err = shm_checkid(ns, shp,shmid);
if (err) {
shm_unlock(shp);
goto out;
@@ -783,16 +865,16 @@ long do_shmat(int shmid, char __user *shmaddr, int shmflg, ulong *raddr)
invalid:
up_write(&current->mm->mmap_sem);
- mutex_lock(&shm_ids.mutex);
- shp = shm_lock(shmid);
+ mutex_lock(&shm_ids(ns).mutex);
+ shp = shm_lock(ns, shmid);
BUG_ON(!shp);
shp->shm_nattch--;
if(shp->shm_nattch == 0 &&
shp->shm_perm.mode & SHM_DEST)
- shm_destroy (shp);
+ shm_destroy(ns, shp);
else
shm_unlock(shp);
- mutex_unlock(&shm_ids.mutex);
+ mutex_unlock(&shm_ids(ns).mutex);
*raddr = (unsigned long) user_addr;
err = 0;
diff --git a/ipc/util.c b/ipc/util.c
index 67b6d178db6e..42479e4eec59 100644
--- a/ipc/util.c
+++ b/ipc/util.c
@@ -12,6 +12,9 @@
* Mingming Cao <cmm@us.ibm.com>
* Mar 2006 - support for audit of ipc object properties
* Dustin Kirkland <dustin.kirkland@us.ibm.com>
+ * Jun 2006 - namespaces ssupport
+ * OpenVZ, SWsoft Inc.
+ * Pavel Emelianov <xemul@openvz.org>
*/
#include <linux/mm.h>
@@ -29,6 +32,7 @@
#include <linux/seq_file.h>
#include <linux/proc_fs.h>
#include <linux/audit.h>
+#include <linux/nsproxy.h>
#include <asm/unistd.h>
@@ -37,10 +41,111 @@
struct ipc_proc_iface {
const char *path;
const char *header;
- struct ipc_ids *ids;
+ int ids;
int (*show)(struct seq_file *, void *);
};
+struct ipc_namespace init_ipc_ns = {
+ .kref = {
+ .refcount = ATOMIC_INIT(2),
+ },
+};
+
+#ifdef CONFIG_IPC_NS
+static struct ipc_namespace *clone_ipc_ns(struct ipc_namespace *old_ns)
+{
+ int err;
+ struct ipc_namespace *ns;
+
+ err = -ENOMEM;
+ ns = kmalloc(sizeof(struct ipc_namespace), GFP_KERNEL);
+ if (ns == NULL)
+ goto err_mem;
+
+ err = sem_init_ns(ns);
+ if (err)
+ goto err_sem;
+ err = msg_init_ns(ns);
+ if (err)
+ goto err_msg;
+ err = shm_init_ns(ns);
+ if (err)
+ goto err_shm;
+
+ kref_init(&ns->kref);
+ return ns;
+
+err_shm:
+ msg_exit_ns(ns);
+err_msg:
+ sem_exit_ns(ns);
+err_sem:
+ kfree(ns);
+err_mem:
+ return ERR_PTR(err);
+}
+
+int unshare_ipcs(unsigned long unshare_flags, struct ipc_namespace **new_ipc)
+{
+ struct ipc_namespace *new;
+
+ if (unshare_flags & CLONE_NEWIPC) {
+ if (!capable(CAP_SYS_ADMIN))
+ return -EPERM;
+
+ new = clone_ipc_ns(current->nsproxy->ipc_ns);
+ if (IS_ERR(new))
+ return PTR_ERR(new);
+
+ *new_ipc = new;
+ }
+
+ return 0;
+}
+
+int copy_ipcs(unsigned long flags, struct task_struct *tsk)
+{
+ struct ipc_namespace *old_ns = tsk->nsproxy->ipc_ns;
+ struct ipc_namespace *new_ns;
+ int err = 0;
+
+ if (!old_ns)
+ return 0;
+
+ get_ipc_ns(old_ns);
+
+ if (!(flags & CLONE_NEWIPC))
+ return 0;
+
+ if (!capable(CAP_SYS_ADMIN)) {
+ err = -EPERM;
+ goto out;
+ }
+
+ new_ns = clone_ipc_ns(old_ns);
+ if (!new_ns) {
+ err = -ENOMEM;
+ goto out;
+ }
+
+ tsk->nsproxy->ipc_ns = new_ns;
+out:
+ put_ipc_ns(old_ns);
+ return err;
+}
+
+void free_ipc_ns(struct kref *kref)
+{
+ struct ipc_namespace *ns;
+
+ ns = container_of(kref, struct ipc_namespace, kref);
+ sem_exit_ns(ns);
+ msg_exit_ns(ns);
+ shm_exit_ns(ns);
+ kfree(ns);
+}
+#endif
+
/**
* ipc_init - initialise IPC subsystem
*
@@ -67,7 +172,7 @@ __initcall(ipc_init);
* array itself.
*/
-void __init ipc_init_ids(struct ipc_ids* ids, int size)
+void __ipc_init ipc_init_ids(struct ipc_ids* ids, int size)
{
int i;
@@ -110,8 +215,7 @@ static struct file_operations sysvipc_proc_fops;
* @show: show routine.
*/
void __init ipc_init_proc_interface(const char *path, const char *header,
- struct ipc_ids *ids,
- int (*show)(struct seq_file *, void *))
+ int ids, int (*show)(struct seq_file *, void *))
{
struct proc_dir_entry *pde;
struct ipc_proc_iface *iface;
@@ -635,6 +739,9 @@ static void *sysvipc_proc_next(struct seq_file *s, void *it, loff_t *pos)
struct ipc_proc_iface *iface = s->private;
struct kern_ipc_perm *ipc = it;
loff_t p;
+ struct ipc_ids *ids;
+
+ ids = current->nsproxy->ipc_ns->ids[iface->ids];
/* If we had an ipc id locked before, unlock it */
if (ipc && ipc != SEQ_START_TOKEN)
@@ -644,8 +751,8 @@ static void *sysvipc_proc_next(struct seq_file *s, void *it, loff_t *pos)
* p = *pos - 1 (because id 0 starts at position 1)
* + 1 (because we increment the position by one)
*/
- for (p = *pos; p <= iface->ids->max_id; p++) {
- if ((ipc = ipc_lock(iface->ids, p)) != NULL) {
+ for (p = *pos; p <= ids->max_id; p++) {
+ if ((ipc = ipc_lock(ids, p)) != NULL) {
*pos = p + 1;
return ipc;
}
@@ -664,12 +771,15 @@ static void *sysvipc_proc_start(struct seq_file *s, loff_t *pos)
struct ipc_proc_iface *iface = s->private;
struct kern_ipc_perm *ipc;
loff_t p;
+ struct ipc_ids *ids;
+
+ ids = current->nsproxy->ipc_ns->ids[iface->ids];
/*
* Take the lock - this will be released by the corresponding
* call to stop().
*/
- mutex_lock(&iface->ids->mutex);
+ mutex_lock(&ids->mutex);
/* pos < 0 is invalid */
if (*pos < 0)
@@ -680,8 +790,8 @@ static void *sysvipc_proc_start(struct seq_file *s, loff_t *pos)
return SEQ_START_TOKEN;
/* Find the (pos-1)th ipc */
- for (p = *pos - 1; p <= iface->ids->max_id; p++) {
- if ((ipc = ipc_lock(iface->ids, p)) != NULL) {
+ for (p = *pos - 1; p <= ids->max_id; p++) {
+ if ((ipc = ipc_lock(ids, p)) != NULL) {
*pos = p + 1;
return ipc;
}
@@ -693,13 +803,15 @@ static void sysvipc_proc_stop(struct seq_file *s, void *it)
{
struct kern_ipc_perm *ipc = it;
struct ipc_proc_iface *iface = s->private;
+ struct ipc_ids *ids;
/* If we had a locked segment, release it */
if (ipc && ipc != SEQ_START_TOKEN)
ipc_unlock(ipc);
+ ids = current->nsproxy->ipc_ns->ids[iface->ids];
/* Release the lock we took in start() */
- mutex_unlock(&iface->ids->mutex);
+ mutex_unlock(&ids->mutex);
}
static int sysvipc_proc_show(struct seq_file *s, void *it)
diff --git a/ipc/util.h b/ipc/util.h
index 0181553d31d8..c8fd6b9d77b5 100644
--- a/ipc/util.h
+++ b/ipc/util.h
@@ -3,6 +3,8 @@
* Copyright (C) 1999 Christoph Rohland
*
* ipc helper functions (c) 1999 Manfred Spraul <manfred@colorfullife.com>
+ * namespaces support. 2006 OpenVZ, SWsoft Inc.
+ * Pavel Emelianov <xemul@openvz.org>
*/
#ifndef _IPC_UTIL_H
@@ -15,6 +17,14 @@ void sem_init (void);
void msg_init (void);
void shm_init (void);
+int sem_init_ns(struct ipc_namespace *ns);
+int msg_init_ns(struct ipc_namespace *ns);
+int shm_init_ns(struct ipc_namespace *ns);
+
+void sem_exit_ns(struct ipc_namespace *ns);
+void msg_exit_ns(struct ipc_namespace *ns);
+void shm_exit_ns(struct ipc_namespace *ns);
+
struct ipc_id_ary {
int size;
struct kern_ipc_perm *p[0];
@@ -31,15 +41,23 @@ struct ipc_ids {
};
struct seq_file;
-void __init ipc_init_ids(struct ipc_ids* ids, int size);
+#ifdef CONFIG_IPC_NS
+#define __ipc_init
+#else
+#define __ipc_init __init
+#endif
+void __ipc_init ipc_init_ids(struct ipc_ids *ids, int size);
#ifdef CONFIG_PROC_FS
void __init ipc_init_proc_interface(const char *path, const char *header,
- struct ipc_ids *ids,
- int (*show)(struct seq_file *, void *));
+ int ids, int (*show)(struct seq_file *, void *));
#else
#define ipc_init_proc_interface(path, header, ids, show) do {} while (0)
#endif
+#define IPC_SEM_IDS 0
+#define IPC_MSG_IDS 1
+#define IPC_SHM_IDS 2
+
/* must be called with ids->mutex acquired.*/
int ipc_findkey(struct ipc_ids* ids, key_t key);
int ipc_addid(struct ipc_ids* ids, struct kern_ipc_perm* new, int size);
diff --git a/kernel/Makefile b/kernel/Makefile
index d62ec66c1af2..d948ca12acf0 100644
--- a/kernel/Makefile
+++ b/kernel/Makefile
@@ -8,7 +8,7 @@ obj-y = sched.o fork.o exec_domain.o panic.o printk.o profile.o \
signal.o sys.o kmod.o workqueue.o pid.o \
rcupdate.o extable.o params.o posix-timers.o \
kthread.o wait.o kfifo.o sys_ni.o posix-cpu-timers.o mutex.o \
- hrtimer.o rwsem.o
+ hrtimer.o rwsem.o latency.o nsproxy.o
obj-$(CONFIG_STACKTRACE) += stacktrace.o
obj-y += time/
@@ -48,8 +48,9 @@ obj-$(CONFIG_GENERIC_HARDIRQS) += irq/
obj-$(CONFIG_SECCOMP) += seccomp.o
obj-$(CONFIG_RCU_TORTURE_TEST) += rcutorture.o
obj-$(CONFIG_RELAY) += relay.o
+obj-$(CONFIG_UTS_NS) += utsname.o
obj-$(CONFIG_TASK_DELAY_ACCT) += delayacct.o
-obj-$(CONFIG_TASKSTATS) += taskstats.o
+obj-$(CONFIG_TASKSTATS) += taskstats.o tsacct.o
ifneq ($(CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER),y)
# According to Alan Modra <alan@linuxcare.com.au>, the -fno-omit-frame-pointer is
diff --git a/kernel/acct.c b/kernel/acct.c
index 2a7c933651c7..0aad5ca36a81 100644
--- a/kernel/acct.c
+++ b/kernel/acct.c
@@ -483,10 +483,14 @@ static void do_acct_process(struct file *file)
ac.ac_ppid = current->parent->tgid;
#endif
- read_lock(&tasklist_lock); /* pin current->signal */
+ mutex_lock(&tty_mutex);
+ /* FIXME: Whoever is responsible for current->signal locking needs
+ to use the same locking all over the kernel and document it */
+ read_lock(&tasklist_lock);
ac.ac_tty = current->signal->tty ?
old_encode_dev(tty_devnum(current->signal->tty)) : 0;
read_unlock(&tasklist_lock);
+ mutex_unlock(&tty_mutex);
spin_lock_irq(&current->sighand->siglock);
ac.ac_utime = encode_comp_t(jiffies_to_AHZ(cputime_to_jiffies(pacct->ac_utime)));
@@ -598,33 +602,3 @@ void acct_process(void)
do_acct_process(file);
fput(file);
}
-
-
-/**
- * acct_update_integrals - update mm integral fields in task_struct
- * @tsk: task_struct for accounting
- */
-void acct_update_integrals(struct task_struct *tsk)
-{
- if (likely(tsk->mm)) {
- long delta =
- cputime_to_jiffies(tsk->stime) - tsk->acct_stimexpd;
-
- if (delta == 0)
- return;
- tsk->acct_stimexpd = tsk->stime;
- tsk->acct_rss_mem1 += delta * get_mm_rss(tsk->mm);
- tsk->acct_vm_mem1 += delta * tsk->mm->total_vm;
- }
-}
-
-/**
- * acct_clear_integrals - clear the mm integral fields in task_struct
- * @tsk: task_struct whose accounting fields are cleared
- */
-void acct_clear_integrals(struct task_struct *tsk)
-{
- tsk->acct_stimexpd = 0;
- tsk->acct_rss_mem1 = 0;
- tsk->acct_vm_mem1 = 0;
-}
diff --git a/kernel/auditsc.c b/kernel/auditsc.c
index fb83c5cb8c32..105147631753 100644
--- a/kernel/auditsc.c
+++ b/kernel/auditsc.c
@@ -817,6 +817,8 @@ static void audit_log_exit(struct audit_context *context, struct task_struct *ts
audit_log_format(ab, " success=%s exit=%ld",
(context->return_valid==AUDITSC_SUCCESS)?"yes":"no",
context->return_code);
+
+ mutex_lock(&tty_mutex);
if (tsk->signal && tsk->signal->tty && tsk->signal->tty->name)
tty = tsk->signal->tty->name;
else
@@ -838,6 +840,9 @@ static void audit_log_exit(struct audit_context *context, struct task_struct *ts
context->gid,
context->euid, context->suid, context->fsuid,
context->egid, context->sgid, context->fsgid, tty);
+
+ mutex_unlock(&tty_mutex);
+
audit_log_task_info(ab, tsk);
if (context->filterkey) {
audit_log_format(ab, " key=");
diff --git a/kernel/capability.c b/kernel/capability.c
index c7685ad00a97..edb845a6e84a 100644
--- a/kernel/capability.c
+++ b/kernel/capability.c
@@ -133,7 +133,7 @@ static inline int cap_set_all(kernel_cap_t *effective,
int found = 0;
do_each_thread(g, target) {
- if (target == current || target->pid == 1)
+ if (target == current || is_init(target))
continue;
found = 1;
if (security_capset_check(target, effective, inheritable,
diff --git a/kernel/compat.c b/kernel/compat.c
index 126dee9530aa..75573e5d27b0 100644
--- a/kernel/compat.c
+++ b/kernel/compat.c
@@ -22,6 +22,7 @@
#include <linux/security.h>
#include <linux/timex.h>
#include <linux/migrate.h>
+#include <linux/posix-timers.h>
#include <asm/uaccess.h>
@@ -601,6 +602,30 @@ long compat_sys_clock_getres(clockid_t which_clock,
return err;
}
+static long compat_clock_nanosleep_restart(struct restart_block *restart)
+{
+ long err;
+ mm_segment_t oldfs;
+ struct timespec tu;
+ struct compat_timespec *rmtp = (struct compat_timespec *)(restart->arg1);
+
+ restart->arg1 = (unsigned long) &tu;
+ oldfs = get_fs();
+ set_fs(KERNEL_DS);
+ err = clock_nanosleep_restart(restart);
+ set_fs(oldfs);
+
+ if ((err == -ERESTART_RESTARTBLOCK) && rmtp &&
+ put_compat_timespec(&tu, rmtp))
+ return -EFAULT;
+
+ if (err == -ERESTART_RESTARTBLOCK) {
+ restart->fn = compat_clock_nanosleep_restart;
+ restart->arg1 = (unsigned long) rmtp;
+ }
+ return err;
+}
+
long compat_sys_clock_nanosleep(clockid_t which_clock, int flags,
struct compat_timespec __user *rqtp,
struct compat_timespec __user *rmtp)
@@ -608,6 +633,7 @@ long compat_sys_clock_nanosleep(clockid_t which_clock, int flags,
long err;
mm_segment_t oldfs;
struct timespec in, out;
+ struct restart_block *restart;
if (get_compat_timespec(&in, rqtp))
return -EFAULT;
@@ -618,9 +644,16 @@ long compat_sys_clock_nanosleep(clockid_t which_clock, int flags,
(struct timespec __user *) &in,
(struct timespec __user *) &out);
set_fs(oldfs);
+
if ((err == -ERESTART_RESTARTBLOCK) && rmtp &&
put_compat_timespec(&out, rmtp))
return -EFAULT;
+
+ if (err == -ERESTART_RESTARTBLOCK) {
+ restart = &current_thread_info()->restart_block;
+ restart->fn = compat_clock_nanosleep_restart;
+ restart->arg1 = (unsigned long) rmtp;
+ }
return err;
}
diff --git a/kernel/cpuset.c b/kernel/cpuset.c
index 1b32c2c04c15..9d850ae13b1b 100644
--- a/kernel/cpuset.c
+++ b/kernel/cpuset.c
@@ -240,7 +240,7 @@ static struct super_block *cpuset_sb;
* A cpuset can only be deleted if both its 'count' of using tasks
* is zero, and its list of 'children' cpusets is empty. Since all
* tasks in the system use _some_ cpuset, and since there is always at
- * least one task in the system (init, pid == 1), therefore, top_cpuset
+ * least one task in the system (init), therefore, top_cpuset
* always has either children cpusets and/or using tasks. So we don't
* need a special hack to ensure that top_cpuset cannot be deleted.
*
@@ -377,7 +377,7 @@ static int cpuset_fill_super(struct super_block *sb, void *unused_data,
inode->i_op = &simple_dir_inode_operations;
inode->i_fop = &simple_dir_operations;
/* directories start off with i_nlink == 2 (for "." entry) */
- inode->i_nlink++;
+ inc_nlink(inode);
} else {
return -ENOMEM;
}
@@ -912,6 +912,10 @@ static int update_nodemask(struct cpuset *cs, char *buf)
int fudge;
int retval;
+ /* top_cpuset.mems_allowed tracks node_online_map; it's read-only */
+ if (cs == &top_cpuset)
+ return -EACCES;
+
trialcs = *cs;
retval = nodelist_parse(buf, trialcs.mems_allowed);
if (retval < 0)
@@ -1221,7 +1225,12 @@ static int attach_task(struct cpuset *cs, char *pidbuf, char **ppathbuf)
task_lock(tsk);
oldcs = tsk->cpuset;
- if (!oldcs) {
+ /*
+ * After getting 'oldcs' cpuset ptr, be sure still not exiting.
+ * If 'oldcs' might be the top_cpuset due to the_top_cpuset_hack
+ * then fail this attach_task(), to avoid breaking top_cpuset.count.
+ */
+ if (tsk->flags & PF_EXITING) {
task_unlock(tsk);
mutex_unlock(&callback_mutex);
put_task_struct(tsk);
@@ -1556,7 +1565,7 @@ static int cpuset_create_file(struct dentry *dentry, int mode)
inode->i_fop = &simple_dir_operations;
/* start off with i_nlink == 2 (for "." entry) */
- inode->i_nlink++;
+ inc_nlink(inode);
} else if (S_ISREG(mode)) {
inode->i_size = 0;
inode->i_fop = &cpuset_file_operations;
@@ -1589,7 +1598,7 @@ static int cpuset_create_dir(struct cpuset *cs, const char *name, int mode)
error = cpuset_create_file(dentry, S_IFDIR | mode);
if (!error) {
dentry->d_fsdata = cs;
- parent->d_inode->i_nlink++;
+ inc_nlink(parent->d_inode);
cs->dentry = dentry;
}
dput(dentry);
@@ -2024,7 +2033,7 @@ int __init cpuset_init(void)
}
root = cpuset_mount->mnt_sb->s_root;
root->d_fsdata = &top_cpuset;
- root->d_inode->i_nlink++;
+ inc_nlink(root->d_inode);
top_cpuset.dentry = root;
root->d_inode->i_op = &cpuset_dir_inode_operations;
number_of_cpusets = 1;
@@ -2036,33 +2045,104 @@ out:
return err;
}
+#if defined(CONFIG_HOTPLUG_CPU) || defined(CONFIG_MEMORY_HOTPLUG)
/*
- * The top_cpuset tracks what CPUs and Memory Nodes are online,
- * period. This is necessary in order to make cpusets transparent
- * (of no affect) on systems that are actively using CPU hotplug
- * but making no active use of cpusets.
- *
- * This handles CPU hotplug (cpuhp) events. If someday Memory
- * Nodes can be hotplugged (dynamically changing node_online_map)
- * then we should handle that too, perhaps in a similar way.
+ * If common_cpu_mem_hotplug_unplug(), below, unplugs any CPUs
+ * or memory nodes, we need to walk over the cpuset hierarchy,
+ * removing that CPU or node from all cpusets. If this removes the
+ * last CPU or node from a cpuset, then the guarantee_online_cpus()
+ * or guarantee_online_mems() code will use that emptied cpusets
+ * parent online CPUs or nodes. Cpusets that were already empty of
+ * CPUs or nodes are left empty.
+ *
+ * This routine is intentionally inefficient in a couple of regards.
+ * It will check all cpusets in a subtree even if the top cpuset of
+ * the subtree has no offline CPUs or nodes. It checks both CPUs and
+ * nodes, even though the caller could have been coded to know that
+ * only one of CPUs or nodes needed to be checked on a given call.
+ * This was done to minimize text size rather than cpu cycles.
+ *
+ * Call with both manage_mutex and callback_mutex held.
+ *
+ * Recursive, on depth of cpuset subtree.
*/
-#ifdef CONFIG_HOTPLUG_CPU
-static int cpuset_handle_cpuhp(struct notifier_block *nb,
- unsigned long phase, void *cpu)
+static void guarantee_online_cpus_mems_in_subtree(const struct cpuset *cur)
+{
+ struct cpuset *c;
+
+ /* Each of our child cpusets mems must be online */
+ list_for_each_entry(c, &cur->children, sibling) {
+ guarantee_online_cpus_mems_in_subtree(c);
+ if (!cpus_empty(c->cpus_allowed))
+ guarantee_online_cpus(c, &c->cpus_allowed);
+ if (!nodes_empty(c->mems_allowed))
+ guarantee_online_mems(c, &c->mems_allowed);
+ }
+}
+
+/*
+ * The cpus_allowed and mems_allowed nodemasks in the top_cpuset track
+ * cpu_online_map and node_online_map. Force the top cpuset to track
+ * whats online after any CPU or memory node hotplug or unplug event.
+ *
+ * To ensure that we don't remove a CPU or node from the top cpuset
+ * that is currently in use by a child cpuset (which would violate
+ * the rule that cpusets must be subsets of their parent), we first
+ * call the recursive routine guarantee_online_cpus_mems_in_subtree().
+ *
+ * Since there are two callers of this routine, one for CPU hotplug
+ * events and one for memory node hotplug events, we could have coded
+ * two separate routines here. We code it as a single common routine
+ * in order to minimize text size.
+ */
+
+static void common_cpu_mem_hotplug_unplug(void)
{
mutex_lock(&manage_mutex);
mutex_lock(&callback_mutex);
+ guarantee_online_cpus_mems_in_subtree(&top_cpuset);
top_cpuset.cpus_allowed = cpu_online_map;
+ top_cpuset.mems_allowed = node_online_map;
mutex_unlock(&callback_mutex);
mutex_unlock(&manage_mutex);
+}
+#endif
+
+#ifdef CONFIG_HOTPLUG_CPU
+/*
+ * The top_cpuset tracks what CPUs and Memory Nodes are online,
+ * period. This is necessary in order to make cpusets transparent
+ * (of no affect) on systems that are actively using CPU hotplug
+ * but making no active use of cpusets.
+ *
+ * This routine ensures that top_cpuset.cpus_allowed tracks
+ * cpu_online_map on each CPU hotplug (cpuhp) event.
+ */
+static int cpuset_handle_cpuhp(struct notifier_block *nb,
+ unsigned long phase, void *cpu)
+{
+ common_cpu_mem_hotplug_unplug();
return 0;
}
#endif
+#ifdef CONFIG_MEMORY_HOTPLUG
+/*
+ * Keep top_cpuset.mems_allowed tracking node_online_map.
+ * Call this routine anytime after you change node_online_map.
+ * See also the previous routine cpuset_handle_cpuhp().
+ */
+
+void cpuset_track_online_nodes()
+{
+ common_cpu_mem_hotplug_unplug();
+}
+#endif
+
/**
* cpuset_init_smp - initialize cpus_allowed
*
diff --git a/kernel/dma.c b/kernel/dma.c
index aef0a45b7893..2020644c938a 100644
--- a/kernel/dma.c
+++ b/kernel/dma.c
@@ -62,6 +62,11 @@ static struct dma_chan dma_chan_busy[MAX_DMA_CHANNELS] = {
};
+/**
+ * request_dma - request and reserve a system DMA channel
+ * @dmanr: DMA channel number
+ * @device_id: reserving device ID string, used in /proc/dma
+ */
int request_dma(unsigned int dmanr, const char * device_id)
{
if (dmanr >= MAX_DMA_CHANNELS)
@@ -76,7 +81,10 @@ int request_dma(unsigned int dmanr, const char * device_id)
return 0;
} /* request_dma */
-
+/**
+ * free_dma - free a reserved system DMA channel
+ * @dmanr: DMA channel number
+ */
void free_dma(unsigned int dmanr)
{
if (dmanr >= MAX_DMA_CHANNELS) {
diff --git a/kernel/exit.c b/kernel/exit.c
index d891883420f7..f250a5e3e281 100644
--- a/kernel/exit.c
+++ b/kernel/exit.c
@@ -18,8 +18,10 @@
#include <linux/security.h>
#include <linux/cpu.h>
#include <linux/acct.h>
+#include <linux/tsacct_kern.h>
#include <linux/file.h>
#include <linux/binfmts.h>
+#include <linux/nsproxy.h>
#include <linux/ptrace.h>
#include <linux/profile.h>
#include <linux/mount.h>
@@ -38,6 +40,7 @@
#include <linux/pipe_fs_i.h>
#include <linux/audit.h> /* for audit_free() */
#include <linux/resource.h>
+#include <linux/blkdev.h>
#include <asm/uaccess.h>
#include <asm/unistd.h>
@@ -219,7 +222,7 @@ static int will_become_orphaned_pgrp(int pgrp, struct task_struct *ignored_task)
do_each_task_pid(pgrp, PIDTYPE_PGID, p) {
if (p == ignored_task
|| p->exit_state
- || p->real_parent->pid == 1)
+ || is_init(p->real_parent))
continue;
if (process_group(p->real_parent) != pgrp
&& p->real_parent->signal->session == p->signal->session) {
@@ -249,17 +252,6 @@ static int has_stopped_jobs(int pgrp)
do_each_task_pid(pgrp, PIDTYPE_PGID, p) {
if (p->state != TASK_STOPPED)
continue;
-
- /* If p is stopped by a debugger on a signal that won't
- stop it, then don't count p as stopped. This isn't
- perfect but it's a good approximation. */
- if (unlikely (p->ptrace)
- && p->exit_code != SIGSTOP
- && p->exit_code != SIGTSTP
- && p->exit_code != SIGTTOU
- && p->exit_code != SIGTTIN)
- continue;
-
retval = 1;
break;
} while_each_task_pid(pgrp, PIDTYPE_PGID, p);
@@ -292,9 +284,7 @@ static void reparent_to_init(void)
/* Set the exit signal to SIGCHLD so we signal init on exit */
current->exit_signal = SIGCHLD;
- if ((current->policy == SCHED_NORMAL ||
- current->policy == SCHED_BATCH)
- && (task_nice(current) < 0))
+ if (!has_rt_policy(current) && (task_nice(current) < 0))
set_user_nice(current, 0);
/* cpus_allowed? */
/* rt_priority? */
@@ -408,9 +398,11 @@ void daemonize(const char *name, ...)
fs = init_task.fs;
current->fs = fs;
atomic_inc(&fs->count);
- exit_namespace(current);
- current->namespace = init_task.namespace;
- get_namespace(current->namespace);
+
+ exit_task_namespaces(current);
+ current->nsproxy = init_task.nsproxy;
+ get_task_namespaces(current);
+
exit_files(current);
current->files = init_task.files;
atomic_inc(&current->files->count);
@@ -487,6 +479,18 @@ void fastcall put_files_struct(struct files_struct *files)
EXPORT_SYMBOL(put_files_struct);
+void reset_files_struct(struct task_struct *tsk, struct files_struct *files)
+{
+ struct files_struct *old;
+
+ old = tsk->files;
+ task_lock(tsk);
+ tsk->files = files;
+ task_unlock(tsk);
+ put_files_struct(old);
+}
+EXPORT_SYMBOL(reset_files_struct);
+
static inline void __exit_files(struct task_struct *tsk)
{
struct files_struct * files = tsk->files;
@@ -916,7 +920,6 @@ fastcall NORET_TYPE void do_exit(long code)
exit_sem(tsk);
__exit_files(tsk);
__exit_fs(tsk);
- exit_namespace(tsk);
exit_thread();
cpuset_exit(tsk);
exit_keys(tsk);
@@ -931,6 +934,7 @@ fastcall NORET_TYPE void do_exit(long code)
tsk->exit_code = code;
proc_exit_connector(tsk);
exit_notify(tsk);
+ exit_task_namespaces(tsk);
#ifdef CONFIG_NUMA
mpol_free(tsk->mempolicy);
tsk->mempolicy = NULL;
@@ -954,15 +958,15 @@ fastcall NORET_TYPE void do_exit(long code)
if (tsk->splice_pipe)
__free_pipe_info(tsk->splice_pipe);
- /* PF_DEAD causes final put_task_struct after we schedule. */
preempt_disable();
- BUG_ON(tsk->flags & PF_DEAD);
- tsk->flags |= PF_DEAD;
+ /* causes final put_task_struct in finish_task_switch(). */
+ tsk->state = TASK_DEAD;
schedule();
BUG();
/* Avoid "noreturn function does return". */
- for (;;) ;
+ for (;;)
+ cpu_relax(); /* For when BUG is null */
}
EXPORT_SYMBOL_GPL(do_exit);
@@ -971,7 +975,7 @@ NORET_TYPE void complete_and_exit(struct completion *comp, long code)
{
if (comp)
complete(comp);
-
+
do_exit(code);
}
diff --git a/kernel/fork.c b/kernel/fork.c
index 802b1cf0e63f..7dc6140baac6 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -27,6 +27,7 @@
#include <linux/binfmts.h>
#include <linux/mman.h>
#include <linux/fs.h>
+#include <linux/nsproxy.h>
#include <linux/capability.h>
#include <linux/cpu.h>
#include <linux/cpuset.h>
@@ -42,6 +43,7 @@
#include <linux/profile.h>
#include <linux/rmap.h>
#include <linux/acct.h>
+#include <linux/tsacct_kern.h>
#include <linux/cn_proc.h>
#include <linux/delayacct.h>
#include <linux/taskstats_kern.h>
@@ -183,7 +185,9 @@ static struct task_struct *dup_task_struct(struct task_struct *orig)
/* One for us, one for whoever does the "release_task()" (usually parent) */
atomic_set(&tsk->usage,2);
atomic_set(&tsk->fs_excl, 0);
+#ifdef CONFIG_BLK_DEV_IO_TRACE
tsk->btrace_seq = 0;
+#endif
tsk->splice_pipe = NULL;
return tsk;
}
@@ -1113,11 +1117,11 @@ static struct task_struct *copy_process(unsigned long clone_flags,
goto bad_fork_cleanup_signal;
if ((retval = copy_keys(clone_flags, p)))
goto bad_fork_cleanup_mm;
- if ((retval = copy_namespace(clone_flags, p)))
+ if ((retval = copy_namespaces(clone_flags, p)))
goto bad_fork_cleanup_keys;
retval = copy_thread(0, clone_flags, stack_start, stack_size, p, regs);
if (retval)
- goto bad_fork_cleanup_namespace;
+ goto bad_fork_cleanup_namespaces;
p->set_child_tid = (clone_flags & CLONE_CHILD_SETTID) ? child_tidptr : NULL;
/*
@@ -1148,7 +1152,6 @@ static struct task_struct *copy_process(unsigned long clone_flags,
/* Our parent execution domain becomes current domain
These must match for thread signalling to apply */
-
p->parent_exec_id = p->self_exec_id;
/* ok, now we should be set up.. */
@@ -1171,6 +1174,9 @@ static struct task_struct *copy_process(unsigned long clone_flags,
/* Need tasklist lock for parent etc handling! */
write_lock_irq(&tasklist_lock);
+ /* for sys_ioprio_set(IOPRIO_WHO_PGRP) */
+ p->ioprio = current->ioprio;
+
/*
* The task hasn't been attached yet, so its cpus_allowed mask will
* not be changed, nor will its assigned CPU.
@@ -1207,7 +1213,7 @@ static struct task_struct *copy_process(unsigned long clone_flags,
spin_unlock(&current->sighand->siglock);
write_unlock_irq(&tasklist_lock);
retval = -ERESTARTNOINTR;
- goto bad_fork_cleanup_namespace;
+ goto bad_fork_cleanup_namespaces;
}
if (clone_flags & CLONE_THREAD) {
@@ -1230,11 +1236,6 @@ static struct task_struct *copy_process(unsigned long clone_flags,
}
}
- /*
- * inherit ioprio
- */
- p->ioprio = current->ioprio;
-
if (likely(p->pid)) {
add_parent(p);
if (unlikely(p->ptrace & PT_PTRACED))
@@ -1260,8 +1261,8 @@ static struct task_struct *copy_process(unsigned long clone_flags,
proc_fork_connector(p);
return p;
-bad_fork_cleanup_namespace:
- exit_namespace(p);
+bad_fork_cleanup_namespaces:
+ exit_task_namespaces(p);
bad_fork_cleanup_keys:
exit_keys(p);
bad_fork_cleanup_mm:
@@ -1514,10 +1515,9 @@ static int unshare_fs(unsigned long unshare_flags, struct fs_struct **new_fsp)
*/
static int unshare_namespace(unsigned long unshare_flags, struct namespace **new_nsp, struct fs_struct *new_fs)
{
- struct namespace *ns = current->namespace;
+ struct namespace *ns = current->nsproxy->namespace;
- if ((unshare_flags & CLONE_NEWNS) &&
- (ns && atomic_read(&ns->count) > 1)) {
+ if ((unshare_flags & CLONE_NEWNS) && ns) {
if (!capable(CAP_SYS_ADMIN))
return -EPERM;
@@ -1589,6 +1589,16 @@ static int unshare_semundo(unsigned long unshare_flags, struct sem_undo_list **n
return 0;
}
+#ifndef CONFIG_IPC_NS
+static inline int unshare_ipcs(unsigned long flags, struct ipc_namespace **ns)
+{
+ if (flags & CLONE_NEWIPC)
+ return -EINVAL;
+
+ return 0;
+}
+#endif
+
/*
* unshare allows a process to 'unshare' part of the process
* context which was originally shared using clone. copy_*
@@ -1606,13 +1616,17 @@ asmlinkage long sys_unshare(unsigned long unshare_flags)
struct mm_struct *mm, *new_mm = NULL, *active_mm = NULL;
struct files_struct *fd, *new_fd = NULL;
struct sem_undo_list *new_ulist = NULL;
+ struct nsproxy *new_nsproxy = NULL, *old_nsproxy = NULL;
+ struct uts_namespace *uts, *new_uts = NULL;
+ struct ipc_namespace *ipc, *new_ipc = NULL;
check_unshare_flags(&unshare_flags);
/* Return -EINVAL for all unsupported flags */
err = -EINVAL;
if (unshare_flags & ~(CLONE_THREAD|CLONE_FS|CLONE_NEWNS|CLONE_SIGHAND|
- CLONE_VM|CLONE_FILES|CLONE_SYSVSEM))
+ CLONE_VM|CLONE_FILES|CLONE_SYSVSEM|
+ CLONE_NEWUTS|CLONE_NEWIPC))
goto bad_unshare_out;
if ((err = unshare_thread(unshare_flags)))
@@ -1629,11 +1643,30 @@ asmlinkage long sys_unshare(unsigned long unshare_flags)
goto bad_unshare_cleanup_vm;
if ((err = unshare_semundo(unshare_flags, &new_ulist)))
goto bad_unshare_cleanup_fd;
+ if ((err = unshare_utsname(unshare_flags, &new_uts)))
+ goto bad_unshare_cleanup_semundo;
+ if ((err = unshare_ipcs(unshare_flags, &new_ipc)))
+ goto bad_unshare_cleanup_uts;
+
+ if (new_ns || new_uts || new_ipc) {
+ old_nsproxy = current->nsproxy;
+ new_nsproxy = dup_namespaces(old_nsproxy);
+ if (!new_nsproxy) {
+ err = -ENOMEM;
+ goto bad_unshare_cleanup_ipc;
+ }
+ }
- if (new_fs || new_ns || new_sigh || new_mm || new_fd || new_ulist) {
+ if (new_fs || new_ns || new_sigh || new_mm || new_fd || new_ulist ||
+ new_uts || new_ipc) {
task_lock(current);
+ if (new_nsproxy) {
+ current->nsproxy = new_nsproxy;
+ new_nsproxy = old_nsproxy;
+ }
+
if (new_fs) {
fs = current->fs;
current->fs = new_fs;
@@ -1641,8 +1674,8 @@ asmlinkage long sys_unshare(unsigned long unshare_flags)
}
if (new_ns) {
- ns = current->namespace;
- current->namespace = new_ns;
+ ns = current->nsproxy->namespace;
+ current->nsproxy->namespace = new_ns;
new_ns = ns;
}
@@ -1667,9 +1700,33 @@ asmlinkage long sys_unshare(unsigned long unshare_flags)
new_fd = fd;
}
+ if (new_uts) {
+ uts = current->nsproxy->uts_ns;
+ current->nsproxy->uts_ns = new_uts;
+ new_uts = uts;
+ }
+
+ if (new_ipc) {
+ ipc = current->nsproxy->ipc_ns;
+ current->nsproxy->ipc_ns = new_ipc;
+ new_ipc = ipc;
+ }
+
task_unlock(current);
}
+ if (new_nsproxy)
+ put_nsproxy(new_nsproxy);
+
+bad_unshare_cleanup_ipc:
+ if (new_ipc)
+ put_ipc_ns(new_ipc);
+
+bad_unshare_cleanup_uts:
+ if (new_uts)
+ put_uts_ns(new_uts);
+
+bad_unshare_cleanup_semundo:
bad_unshare_cleanup_fd:
if (new_fd)
put_files_struct(new_fd);
diff --git a/kernel/futex.c b/kernel/futex.c
index 9d260e838cff..4aaf91951a43 100644
--- a/kernel/futex.c
+++ b/kernel/futex.c
@@ -389,7 +389,7 @@ static struct task_struct * futex_find_get_task(pid_t pid)
{
struct task_struct *p;
- read_lock(&tasklist_lock);
+ rcu_read_lock();
p = find_task_by_pid(pid);
if (!p)
goto out_unlock;
@@ -403,7 +403,7 @@ static struct task_struct * futex_find_get_task(pid_t pid)
}
get_task_struct(p);
out_unlock:
- read_unlock(&tasklist_lock);
+ rcu_read_unlock();
return p;
}
@@ -1527,7 +1527,7 @@ static int futex_fd(u32 __user *uaddr, int signal)
filp->f_mapping = filp->f_dentry->d_inode->i_mapping;
if (signal) {
- err = f_setown(filp, current->pid, 1);
+ err = __f_setown(filp, task_pid(current), PIDTYPE_PID, 1);
if (err < 0) {
goto error;
}
@@ -1624,7 +1624,7 @@ sys_get_robust_list(int pid, struct robust_list_head __user **head_ptr,
struct task_struct *p;
ret = -ESRCH;
- read_lock(&tasklist_lock);
+ rcu_read_lock();
p = find_task_by_pid(pid);
if (!p)
goto err_unlock;
@@ -1633,7 +1633,7 @@ sys_get_robust_list(int pid, struct robust_list_head __user **head_ptr,
!capable(CAP_SYS_PTRACE))
goto err_unlock;
head = p->robust_list;
- read_unlock(&tasklist_lock);
+ rcu_read_unlock();
}
if (put_user(sizeof(*head), len_ptr))
@@ -1641,7 +1641,7 @@ sys_get_robust_list(int pid, struct robust_list_head __user **head_ptr,
return put_user(head, head_ptr);
err_unlock:
- read_unlock(&tasklist_lock);
+ rcu_read_unlock();
return ret;
}
diff --git a/kernel/hrtimer.c b/kernel/hrtimer.c
index 21c38a7e666b..d0ba190dfeb6 100644
--- a/kernel/hrtimer.c
+++ b/kernel/hrtimer.c
@@ -693,7 +693,7 @@ static int __sched do_nanosleep(struct hrtimer_sleeper *t, enum hrtimer_mode mod
return t->task == NULL;
}
-static long __sched nanosleep_restart(struct restart_block *restart)
+long __sched hrtimer_nanosleep_restart(struct restart_block *restart)
{
struct hrtimer_sleeper t;
struct timespec __user *rmtp;
@@ -702,13 +702,13 @@ static long __sched nanosleep_restart(struct restart_block *restart)
restart->fn = do_no_restart_syscall;
- hrtimer_init(&t.timer, restart->arg3, HRTIMER_ABS);
- t.timer.expires.tv64 = ((u64)restart->arg1 << 32) | (u64) restart->arg0;
+ hrtimer_init(&t.timer, restart->arg0, HRTIMER_ABS);
+ t.timer.expires.tv64 = ((u64)restart->arg3 << 32) | (u64) restart->arg2;
if (do_nanosleep(&t, HRTIMER_ABS))
return 0;
- rmtp = (struct timespec __user *) restart->arg2;
+ rmtp = (struct timespec __user *) restart->arg1;
if (rmtp) {
time = ktime_sub(t.timer.expires, t.timer.base->get_time());
if (time.tv64 <= 0)
@@ -718,7 +718,7 @@ static long __sched nanosleep_restart(struct restart_block *restart)
return -EFAULT;
}
- restart->fn = nanosleep_restart;
+ restart->fn = hrtimer_nanosleep_restart;
/* The other values in restart are already filled in */
return -ERESTART_RESTARTBLOCK;
@@ -751,11 +751,11 @@ long hrtimer_nanosleep(struct timespec *rqtp, struct timespec __user *rmtp,
}
restart = &current_thread_info()->restart_block;
- restart->fn = nanosleep_restart;
- restart->arg0 = t.timer.expires.tv64 & 0xFFFFFFFF;
- restart->arg1 = t.timer.expires.tv64 >> 32;
- restart->arg2 = (unsigned long) rmtp;
- restart->arg3 = (unsigned long) t.timer.base->index;
+ restart->fn = hrtimer_nanosleep_restart;
+ restart->arg0 = (unsigned long) t.timer.base->index;
+ restart->arg1 = (unsigned long) rmtp;
+ restart->arg2 = t.timer.expires.tv64 & 0xFFFFFFFF;
+ restart->arg3 = t.timer.expires.tv64 >> 32;
return -ERESTART_RESTARTBLOCK;
}
diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c
index ac1f850d4937..736cb0bd498f 100644
--- a/kernel/irq/chip.c
+++ b/kernel/irq/chip.c
@@ -40,10 +40,6 @@ int set_irq_chip(unsigned int irq, struct irq_chip *chip)
spin_lock_irqsave(&desc->lock, flags);
irq_chip_set_defaults(chip);
desc->chip = chip;
- /*
- * For compatibility only:
- */
- desc->chip = chip;
spin_unlock_irqrestore(&desc->lock, flags);
return 0;
@@ -146,7 +142,7 @@ static void default_disable(unsigned int irq)
struct irq_desc *desc = irq_desc + irq;
if (!(desc->status & IRQ_DELAYED_DISABLE))
- irq_desc[irq].chip->mask(irq);
+ desc->chip->mask(irq);
}
/*
diff --git a/kernel/kallsyms.c b/kernel/kallsyms.c
index ab16a5a4cfe9..eeac3e313b2b 100644
--- a/kernel/kallsyms.c
+++ b/kernel/kallsyms.c
@@ -69,6 +69,15 @@ static inline int is_kernel(unsigned long addr)
return in_gate_area_no_task(addr);
}
+static int is_ksym_addr(unsigned long addr)
+{
+ if (all_var)
+ return is_kernel(addr);
+
+ return is_kernel_text(addr) || is_kernel_inittext(addr) ||
+ is_kernel_extratext(addr);
+}
+
/* expand a compressed symbol data into the resulting uncompressed string,
given the offset to where the symbol is in the compressed stream */
static unsigned int kallsyms_expand_symbol(unsigned int off, char *result)
@@ -154,7 +163,73 @@ unsigned long kallsyms_lookup_name(const char *name)
}
return module_kallsyms_lookup_name(name);
}
-EXPORT_SYMBOL_GPL(kallsyms_lookup_name);
+
+static unsigned long get_symbol_pos(unsigned long addr,
+ unsigned long *symbolsize,
+ unsigned long *offset)
+{
+ unsigned long symbol_start = 0, symbol_end = 0;
+ unsigned long i, low, high, mid;
+
+ /* This kernel should never had been booted. */
+ BUG_ON(!kallsyms_addresses);
+
+ /* do a binary search on the sorted kallsyms_addresses array */
+ low = 0;
+ high = kallsyms_num_syms;
+
+ while (high - low > 1) {
+ mid = (low + high) / 2;
+ if (kallsyms_addresses[mid] <= addr)
+ low = mid;
+ else
+ high = mid;
+ }
+
+ /*
+ * search for the first aliased symbol. Aliased
+ * symbols are symbols with the same address
+ */
+ while (low && kallsyms_addresses[low-1] == kallsyms_addresses[low])
+ --low;
+
+ symbol_start = kallsyms_addresses[low];
+
+ /* Search for next non-aliased symbol */
+ for (i = low + 1; i < kallsyms_num_syms; i++) {
+ if (kallsyms_addresses[i] > symbol_start) {
+ symbol_end = kallsyms_addresses[i];
+ break;
+ }
+ }
+
+ /* if we found no next symbol, we use the end of the section */
+ if (!symbol_end) {
+ if (is_kernel_inittext(addr))
+ symbol_end = (unsigned long)_einittext;
+ else if (all_var)
+ symbol_end = (unsigned long)_end;
+ else
+ symbol_end = (unsigned long)_etext;
+ }
+
+ *symbolsize = symbol_end - symbol_start;
+ *offset = addr - symbol_start;
+
+ return low;
+}
+
+/*
+ * Lookup an address but don't bother to find any names.
+ */
+int kallsyms_lookup_size_offset(unsigned long addr, unsigned long *symbolsize,
+ unsigned long *offset)
+{
+ if (is_ksym_addr(addr))
+ return !!get_symbol_pos(addr, symbolsize, offset);
+
+ return !!module_address_lookup(addr, symbolsize, offset, NULL);
+}
/*
* Lookup an address
@@ -168,57 +243,18 @@ const char *kallsyms_lookup(unsigned long addr,
unsigned long *offset,
char **modname, char *namebuf)
{
- unsigned long i, low, high, mid;
const char *msym;
- /* This kernel should never had been booted. */
- BUG_ON(!kallsyms_addresses);
-
namebuf[KSYM_NAME_LEN] = 0;
namebuf[0] = 0;
- if ((all_var && is_kernel(addr)) ||
- (!all_var && (is_kernel_text(addr) || is_kernel_inittext(addr) ||
- is_kernel_extratext(addr)))) {
- unsigned long symbol_end = 0;
-
- /* do a binary search on the sorted kallsyms_addresses array */
- low = 0;
- high = kallsyms_num_syms;
-
- while (high-low > 1) {
- mid = (low + high) / 2;
- if (kallsyms_addresses[mid] <= addr) low = mid;
- else high = mid;
- }
-
- /* search for the first aliased symbol. Aliased symbols are
- symbols with the same address */
- while (low && kallsyms_addresses[low - 1] == kallsyms_addresses[low])
- --low;
+ if (is_ksym_addr(addr)) {
+ unsigned long pos;
+ pos = get_symbol_pos(addr, symbolsize, offset);
/* Grab name */
- kallsyms_expand_symbol(get_symbol_offset(low), namebuf);
-
- /* Search for next non-aliased symbol */
- for (i = low + 1; i < kallsyms_num_syms; i++) {
- if (kallsyms_addresses[i] > kallsyms_addresses[low]) {
- symbol_end = kallsyms_addresses[i];
- break;
- }
- }
-
- /* if we found no next symbol, we use the end of the section */
- if (!symbol_end) {
- if (is_kernel_inittext(addr))
- symbol_end = (unsigned long)_einittext;
- else
- symbol_end = all_var ? (unsigned long)_end : (unsigned long)_etext;
- }
-
- *symbolsize = symbol_end - kallsyms_addresses[low];
+ kallsyms_expand_symbol(get_symbol_offset(pos), namebuf);
*modname = NULL;
- *offset = addr - kallsyms_addresses[low];
return namebuf;
}
diff --git a/kernel/kexec.c b/kernel/kexec.c
index 50087ecf337e..fcdd5d2bc3f4 100644
--- a/kernel/kexec.c
+++ b/kernel/kexec.c
@@ -40,7 +40,7 @@ struct resource crashk_res = {
int kexec_should_crash(struct task_struct *p)
{
- if (in_interrupt() || !p->pid || p->pid == 1 || panic_on_oops)
+ if (in_interrupt() || !p->pid || is_init(p) || panic_on_oops)
return 1;
return 0;
}
@@ -995,7 +995,8 @@ asmlinkage long sys_kexec_load(unsigned long entry, unsigned long nr_segments,
image = xchg(dest_image, image);
out:
- xchg(&kexec_lock, 0); /* Release the mutex */
+ locked = xchg(&kexec_lock, 0); /* Release the mutex */
+ BUG_ON(!locked);
kimage_free(image);
return result;
@@ -1061,7 +1062,8 @@ void crash_kexec(struct pt_regs *regs)
machine_crash_shutdown(&fixed_regs);
machine_kexec(kexec_crash_image);
}
- xchg(&kexec_lock, 0);
+ locked = xchg(&kexec_lock, 0);
+ BUG_ON(!locked);
}
}
diff --git a/kernel/kfifo.c b/kernel/kfifo.c
index 64ab045c3d9d..5d1d907378a2 100644
--- a/kernel/kfifo.c
+++ b/kernel/kfifo.c
@@ -122,6 +122,13 @@ unsigned int __kfifo_put(struct kfifo *fifo,
len = min(len, fifo->size - fifo->in + fifo->out);
+ /*
+ * Ensure that we sample the fifo->out index -before- we
+ * start putting bytes into the kfifo.
+ */
+
+ smp_mb();
+
/* first put the data starting from fifo->in to buffer end */
l = min(len, fifo->size - (fifo->in & (fifo->size - 1)));
memcpy(fifo->buffer + (fifo->in & (fifo->size - 1)), buffer, l);
@@ -129,6 +136,13 @@ unsigned int __kfifo_put(struct kfifo *fifo,
/* then put the rest (if any) at the beginning of the buffer */
memcpy(fifo->buffer, buffer + l, len - l);
+ /*
+ * Ensure that we add the bytes to the kfifo -before-
+ * we update the fifo->in index.
+ */
+
+ smp_wmb();
+
fifo->in += len;
return len;
@@ -154,6 +168,13 @@ unsigned int __kfifo_get(struct kfifo *fifo,
len = min(len, fifo->in - fifo->out);
+ /*
+ * Ensure that we sample the fifo->in index -before- we
+ * start removing bytes from the kfifo.
+ */
+
+ smp_rmb();
+
/* first get the data from fifo->out until the end of the buffer */
l = min(len, fifo->size - (fifo->out & (fifo->size - 1)));
memcpy(buffer, fifo->buffer + (fifo->out & (fifo->size - 1)), l);
@@ -161,6 +182,13 @@ unsigned int __kfifo_get(struct kfifo *fifo,
/* then get the rest (if any) from the beginning of the buffer */
memcpy(buffer + l, fifo->buffer, len - l);
+ /*
+ * Ensure that we remove the bytes from the kfifo -before-
+ * we update the fifo->out index.
+ */
+
+ smp_mb();
+
fifo->out += len;
return len;
diff --git a/kernel/kmod.c b/kernel/kmod.c
index 5c470c57fb57..bb4e29d924e4 100644
--- a/kernel/kmod.c
+++ b/kernel/kmod.c
@@ -18,8 +18,6 @@
call_usermodehelper wait flag, and remove exec_usermodehelper.
Rusty Russell <rusty@rustcorp.com.au> Jan 2003
*/
-#define __KERNEL_SYSCALLS__
-
#include <linux/module.h>
#include <linux/sched.h>
#include <linux/syscalls.h>
@@ -35,6 +33,7 @@
#include <linux/mount.h>
#include <linux/kernel.h>
#include <linux/init.h>
+#include <linux/resource.h>
#include <asm/uaccess.h>
extern int max_threads;
@@ -122,6 +121,7 @@ struct subprocess_info {
struct key *ring;
int wait;
int retval;
+ struct file *stdin;
};
/*
@@ -145,12 +145,30 @@ static int ____call_usermodehelper(void *data)
key_put(old_session);
+ /* Install input pipe when needed */
+ if (sub_info->stdin) {
+ struct files_struct *f = current->files;
+ struct fdtable *fdt;
+ /* no races because files should be private here */
+ sys_close(0);
+ fd_install(0, sub_info->stdin);
+ spin_lock(&f->file_lock);
+ fdt = files_fdtable(f);
+ FD_SET(0, fdt->open_fds);
+ FD_CLR(0, fdt->close_on_exec);
+ spin_unlock(&f->file_lock);
+
+ /* and disallow core files too */
+ current->signal->rlim[RLIMIT_CORE] = (struct rlimit){0, 0};
+ }
+
/* We can run anywhere, unlike our parent keventd(). */
set_cpus_allowed(current, CPU_MASK_ALL);
retval = -EPERM;
if (current->fs->root)
- retval = execve(sub_info->path, sub_info->argv,sub_info->envp);
+ retval = kernel_execve(sub_info->path,
+ sub_info->argv, sub_info->envp);
/* Exec failed? */
sub_info->retval = retval;
@@ -176,6 +194,8 @@ static int wait_for_helper(void *data)
if (pid < 0) {
sub_info->retval = pid;
} else {
+ int ret;
+
/*
* Normally it is bogus to call wait4() from in-kernel because
* wait4() wants to write the exit code to a userspace address.
@@ -185,7 +205,15 @@ static int wait_for_helper(void *data)
*
* Thus the __user pointer cast is valid here.
*/
- sys_wait4(pid, (int __user *) &sub_info->retval, 0, NULL);
+ sys_wait4(pid, (int __user *)&ret, 0, NULL);
+
+ /*
+ * If ret is 0, either ____call_usermodehelper failed and the
+ * real error code is already in sub_info->retval or
+ * sub_info->retval is 0 anyway, so don't mess with it then.
+ */
+ if (ret)
+ sub_info->retval = ret;
}
complete(sub_info->complete);
@@ -258,6 +286,44 @@ int call_usermodehelper_keys(char *path, char **argv, char **envp,
}
EXPORT_SYMBOL(call_usermodehelper_keys);
+int call_usermodehelper_pipe(char *path, char **argv, char **envp,
+ struct file **filp)
+{
+ DECLARE_COMPLETION(done);
+ struct subprocess_info sub_info = {
+ .complete = &done,
+ .path = path,
+ .argv = argv,
+ .envp = envp,
+ .retval = 0,
+ };
+ struct file *f;
+ DECLARE_WORK(work, __call_usermodehelper, &sub_info);
+
+ if (!khelper_wq)
+ return -EBUSY;
+
+ if (path[0] == '\0')
+ return 0;
+
+ f = create_write_pipe();
+ if (!f)
+ return -ENOMEM;
+ *filp = f;
+
+ f = create_read_pipe(f);
+ if (!f) {
+ free_write_pipe(*filp);
+ return -ENOMEM;
+ }
+ sub_info.stdin = f;
+
+ queue_work(khelper_wq, &work);
+ wait_for_completion(&done);
+ return sub_info.retval;
+}
+EXPORT_SYMBOL(call_usermodehelper_pipe);
+
void __init usermodehelper_init(void)
{
khelper_wq = create_singlethread_workqueue("khelper");
diff --git a/kernel/kprobes.c b/kernel/kprobes.c
index 3f57dfdc8f92..610c837ad9e0 100644
--- a/kernel/kprobes.c
+++ b/kernel/kprobes.c
@@ -37,6 +37,7 @@
#include <linux/slab.h>
#include <linux/module.h>
#include <linux/moduleloader.h>
+#include <linux/kallsyms.h>
#include <asm-generic/sections.h>
#include <asm/cacheflush.h>
#include <asm/errno.h>
@@ -45,6 +46,16 @@
#define KPROBE_HASH_BITS 6
#define KPROBE_TABLE_SIZE (1 << KPROBE_HASH_BITS)
+
+/*
+ * Some oddball architectures like 64bit powerpc have function descriptors
+ * so this must be overridable.
+ */
+#ifndef kprobe_lookup_name
+#define kprobe_lookup_name(name, addr) \
+ addr = ((kprobe_opcode_t *)(kallsyms_lookup_name(name)))
+#endif
+
static struct hlist_head kprobe_table[KPROBE_TABLE_SIZE];
static struct hlist_head kretprobe_inst_table[KPROBE_TABLE_SIZE];
static atomic_t kprobe_count;
@@ -308,7 +319,8 @@ void __kprobes add_rp_inst(struct kretprobe_instance *ri)
}
/* Called with kretprobe_lock held */
-void __kprobes recycle_rp_inst(struct kretprobe_instance *ri)
+void __kprobes recycle_rp_inst(struct kretprobe_instance *ri,
+ struct hlist_head *head)
{
/* remove rp inst off the rprobe_inst_table */
hlist_del(&ri->hlist);
@@ -320,7 +332,7 @@ void __kprobes recycle_rp_inst(struct kretprobe_instance *ri)
hlist_add_head(&ri->uflist, &ri->rp->free_instances);
} else
/* Unregistering */
- kfree(ri);
+ hlist_add_head(&ri->hlist, head);
}
struct hlist_head __kprobes *kretprobe_inst_table_head(struct task_struct *tsk)
@@ -336,18 +348,24 @@ struct hlist_head __kprobes *kretprobe_inst_table_head(struct task_struct *tsk)
*/
void __kprobes kprobe_flush_task(struct task_struct *tk)
{
- struct kretprobe_instance *ri;
- struct hlist_head *head;
+ struct kretprobe_instance *ri;
+ struct hlist_head *head, empty_rp;
struct hlist_node *node, *tmp;
unsigned long flags = 0;
+ INIT_HLIST_HEAD(&empty_rp);
spin_lock_irqsave(&kretprobe_lock, flags);
- head = kretprobe_inst_table_head(tk);
- hlist_for_each_entry_safe(ri, node, tmp, head, hlist) {
- if (ri->task == tk)
- recycle_rp_inst(ri);
- }
+ head = kretprobe_inst_table_head(tk);
+ hlist_for_each_entry_safe(ri, node, tmp, head, hlist) {
+ if (ri->task == tk)
+ recycle_rp_inst(ri, &empty_rp);
+ }
spin_unlock_irqrestore(&kretprobe_lock, flags);
+
+ hlist_for_each_entry_safe(ri, node, tmp, &empty_rp, hlist) {
+ hlist_del(&ri->hlist);
+ kfree(ri);
+ }
}
static inline void free_rp_inst(struct kretprobe *rp)
@@ -447,6 +465,21 @@ static int __kprobes __register_kprobe(struct kprobe *p,
struct kprobe *old_p;
struct module *probed_mod;
+ /*
+ * If we have a symbol_name argument look it up,
+ * and add it to the address. That way the addr
+ * field can either be global or relative to a symbol.
+ */
+ if (p->symbol_name) {
+ if (p->addr)
+ return -EINVAL;
+ kprobe_lookup_name(p->symbol_name, p->addr);
+ }
+
+ if (!p->addr)
+ return -EINVAL;
+ p->addr = (kprobe_opcode_t *)(((char *)p->addr)+ p->offset);
+
if ((!kernel_text_address((unsigned long) p->addr)) ||
in_kprobes_functions((unsigned long) p->addr))
return -EINVAL;
@@ -488,7 +521,7 @@ static int __kprobes __register_kprobe(struct kprobe *p,
(ARCH_INACTIVE_KPROBE_COUNT + 1))
register_page_fault_notifier(&kprobe_page_fault_nb);
- arch_arm_kprobe(p);
+ arch_arm_kprobe(p);
out:
mutex_unlock(&kprobe_mutex);
diff --git a/kernel/latency.c b/kernel/latency.c
new file mode 100644
index 000000000000..258f2555abbc
--- /dev/null
+++ b/kernel/latency.c
@@ -0,0 +1,279 @@
+/*
+ * latency.c: Explicit system-wide latency-expectation infrastructure
+ *
+ * The purpose of this infrastructure is to allow device drivers to set
+ * latency constraint they have and to collect and summarize these
+ * expectations globally. The cummulated result can then be used by
+ * power management and similar users to make decisions that have
+ * tradoffs with a latency component.
+ *
+ * An example user of this are the x86 C-states; each higher C state saves
+ * more power, but has a higher exit latency. For the idle loop power
+ * code to make a good decision which C-state to use, information about
+ * acceptable latencies is required.
+ *
+ * An example announcer of latency is an audio driver that knowns it
+ * will get an interrupt when the hardware has 200 usec of samples
+ * left in the DMA buffer; in that case the driver can set a latency
+ * constraint of, say, 150 usec.
+ *
+ * Multiple drivers can each announce their maximum accepted latency,
+ * to keep these appart, a string based identifier is used.
+ *
+ *
+ * (C) Copyright 2006 Intel Corporation
+ * Author: Arjan van de Ven <arjan@linux.intel.com>
+ *
+ * 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.
+ */
+
+#include <linux/latency.h>
+#include <linux/list.h>
+#include <linux/spinlock.h>
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <linux/notifier.h>
+#include <asm/atomic.h>
+
+struct latency_info {
+ struct list_head list;
+ int usecs;
+ char *identifier;
+};
+
+/*
+ * locking rule: all modifications to current_max_latency and
+ * latency_list need to be done while holding the latency_lock.
+ * latency_lock needs to be taken _irqsave.
+ */
+static atomic_t current_max_latency;
+static DEFINE_SPINLOCK(latency_lock);
+
+static LIST_HEAD(latency_list);
+static BLOCKING_NOTIFIER_HEAD(latency_notifier);
+
+/*
+ * This function returns the maximum latency allowed, which
+ * happens to be the minimum of all maximum latencies on the
+ * list.
+ */
+static int __find_max_latency(void)
+{
+ int min = INFINITE_LATENCY;
+ struct latency_info *info;
+
+ list_for_each_entry(info, &latency_list, list) {
+ if (info->usecs < min)
+ min = info->usecs;
+ }
+ return min;
+}
+
+/**
+ * set_acceptable_latency - sets the maximum latency acceptable
+ * @identifier: string that identifies this driver
+ * @usecs: maximum acceptable latency for this driver
+ *
+ * This function informs the kernel that this device(driver)
+ * can accept at most usecs latency. This setting is used for
+ * power management and similar tradeoffs.
+ *
+ * This function sleeps and can only be called from process
+ * context.
+ * Calling this function with an existing identifier is valid
+ * and will cause the existing latency setting to be changed.
+ */
+void set_acceptable_latency(char *identifier, int usecs)
+{
+ struct latency_info *info, *iter;
+ unsigned long flags;
+ int found_old = 0;
+
+ info = kzalloc(sizeof(struct latency_info), GFP_KERNEL);
+ if (!info)
+ return;
+ info->usecs = usecs;
+ info->identifier = kstrdup(identifier, GFP_KERNEL);
+ if (!info->identifier)
+ goto free_info;
+
+ spin_lock_irqsave(&latency_lock, flags);
+ list_for_each_entry(iter, &latency_list, list) {
+ if (strcmp(iter->identifier, identifier)==0) {
+ found_old = 1;
+ iter->usecs = usecs;
+ break;
+ }
+ }
+ if (!found_old)
+ list_add(&info->list, &latency_list);
+
+ if (usecs < atomic_read(&current_max_latency))
+ atomic_set(&current_max_latency, usecs);
+
+ spin_unlock_irqrestore(&latency_lock, flags);
+
+ blocking_notifier_call_chain(&latency_notifier,
+ atomic_read(&current_max_latency), NULL);
+
+ /*
+ * if we inserted the new one, we're done; otherwise there was
+ * an existing one so we need to free the redundant data
+ */
+ if (!found_old)
+ return;
+
+ kfree(info->identifier);
+free_info:
+ kfree(info);
+}
+EXPORT_SYMBOL_GPL(set_acceptable_latency);
+
+/**
+ * modify_acceptable_latency - changes the maximum latency acceptable
+ * @identifier: string that identifies this driver
+ * @usecs: maximum acceptable latency for this driver
+ *
+ * This function informs the kernel that this device(driver)
+ * can accept at most usecs latency. This setting is used for
+ * power management and similar tradeoffs.
+ *
+ * This function does not sleep and can be called in any context.
+ * Trying to use a non-existing identifier silently gets ignored.
+ *
+ * Due to the atomic nature of this function, the modified latency
+ * value will only be used for future decisions; past decisions
+ * can still lead to longer latencies in the near future.
+ */
+void modify_acceptable_latency(char *identifier, int usecs)
+{
+ struct latency_info *iter;
+ unsigned long flags;
+
+ spin_lock_irqsave(&latency_lock, flags);
+ list_for_each_entry(iter, &latency_list, list) {
+ if (strcmp(iter->identifier, identifier) == 0) {
+ iter->usecs = usecs;
+ break;
+ }
+ }
+ if (usecs < atomic_read(&current_max_latency))
+ atomic_set(&current_max_latency, usecs);
+ spin_unlock_irqrestore(&latency_lock, flags);
+}
+EXPORT_SYMBOL_GPL(modify_acceptable_latency);
+
+/**
+ * remove_acceptable_latency - removes the maximum latency acceptable
+ * @identifier: string that identifies this driver
+ *
+ * This function removes a previously set maximum latency setting
+ * for the driver and frees up any resources associated with the
+ * bookkeeping needed for this.
+ *
+ * This function does not sleep and can be called in any context.
+ * Trying to use a non-existing identifier silently gets ignored.
+ */
+void remove_acceptable_latency(char *identifier)
+{
+ unsigned long flags;
+ int newmax = 0;
+ struct latency_info *iter, *temp;
+
+ spin_lock_irqsave(&latency_lock, flags);
+
+ list_for_each_entry_safe(iter, temp, &latency_list, list) {
+ if (strcmp(iter->identifier, identifier) == 0) {
+ list_del(&iter->list);
+ newmax = iter->usecs;
+ kfree(iter->identifier);
+ kfree(iter);
+ break;
+ }
+ }
+
+ /* If we just deleted the system wide value, we need to
+ * recalculate with a full search
+ */
+ if (newmax == atomic_read(&current_max_latency)) {
+ newmax = __find_max_latency();
+ atomic_set(&current_max_latency, newmax);
+ }
+ spin_unlock_irqrestore(&latency_lock, flags);
+}
+EXPORT_SYMBOL_GPL(remove_acceptable_latency);
+
+/**
+ * system_latency_constraint - queries the system wide latency maximum
+ *
+ * This function returns the system wide maximum latency in
+ * microseconds.
+ *
+ * This function does not sleep and can be called in any context.
+ */
+int system_latency_constraint(void)
+{
+ return atomic_read(&current_max_latency);
+}
+EXPORT_SYMBOL_GPL(system_latency_constraint);
+
+/**
+ * synchronize_acceptable_latency - recalculates all latency decisions
+ *
+ * This function will cause a callback to various kernel pieces that
+ * will make those pieces rethink their latency decisions. This implies
+ * that if there are overlong latencies in hardware state already, those
+ * latencies get taken right now. When this call completes no overlong
+ * latency decisions should be active anymore.
+ *
+ * Typical usecase of this is after a modify_acceptable_latency() call,
+ * which in itself is non-blocking and non-synchronizing.
+ *
+ * This function blocks and should not be called with locks held.
+ */
+
+void synchronize_acceptable_latency(void)
+{
+ blocking_notifier_call_chain(&latency_notifier,
+ atomic_read(&current_max_latency), NULL);
+}
+EXPORT_SYMBOL_GPL(synchronize_acceptable_latency);
+
+/*
+ * Latency notifier: this notifier gets called when a non-atomic new
+ * latency value gets set. The expectation nof the caller of the
+ * non-atomic set is that when the call returns, future latencies
+ * are within bounds, so the functions on the notifier list are
+ * expected to take the overlong latencies immediately, inside the
+ * callback, and not make a overlong latency decision anymore.
+ *
+ * The callback gets called when the new latency value is made
+ * active so system_latency_constraint() returns the new latency.
+ */
+int register_latency_notifier(struct notifier_block * nb)
+{
+ return blocking_notifier_chain_register(&latency_notifier, nb);
+}
+EXPORT_SYMBOL_GPL(register_latency_notifier);
+
+int unregister_latency_notifier(struct notifier_block * nb)
+{
+ return blocking_notifier_chain_unregister(&latency_notifier, nb);
+}
+EXPORT_SYMBOL_GPL(unregister_latency_notifier);
+
+static __init int latency_init(void)
+{
+ atomic_set(&current_max_latency, INFINITE_LATENCY);
+ /*
+ * we don't want by default to have longer latencies than 2 ticks,
+ * since that would cause lost ticks
+ */
+ set_acceptable_latency("kernel", 2*1000000/HZ);
+ return 0;
+}
+
+module_init(latency_init);
diff --git a/kernel/lockdep.c b/kernel/lockdep.c
index c088e5542e84..4c0553461000 100644
--- a/kernel/lockdep.c
+++ b/kernel/lockdep.c
@@ -36,6 +36,7 @@
#include <linux/stacktrace.h>
#include <linux/debug_locks.h>
#include <linux/irqflags.h>
+#include <linux/utsname.h>
#include <asm/sections.h>
@@ -121,8 +122,8 @@ static struct list_head chainhash_table[CHAINHASH_SIZE];
* unique.
*/
#define iterate_chain_key(key1, key2) \
- (((key1) << MAX_LOCKDEP_KEYS_BITS/2) ^ \
- ((key1) >> (64-MAX_LOCKDEP_KEYS_BITS/2)) ^ \
+ (((key1) << MAX_LOCKDEP_KEYS_BITS) ^ \
+ ((key1) >> (64-MAX_LOCKDEP_KEYS_BITS)) ^ \
(key2))
void lockdep_off(void)
@@ -515,6 +516,13 @@ print_circular_bug_entry(struct lock_list *target, unsigned int depth)
return 0;
}
+static void print_kernel_version(void)
+{
+ printk("%s %.*s\n", init_utsname()->release,
+ (int)strcspn(init_utsname()->version, " "),
+ init_utsname()->version);
+}
+
/*
* When a circular dependency is detected, print the
* header first:
@@ -531,6 +539,7 @@ print_circular_bug_header(struct lock_list *entry, unsigned int depth)
printk("\n=======================================================\n");
printk( "[ INFO: possible circular locking dependency detected ]\n");
+ print_kernel_version();
printk( "-------------------------------------------------------\n");
printk("%s/%d is trying to acquire lock:\n",
curr->comm, curr->pid);
@@ -712,6 +721,7 @@ print_bad_irq_dependency(struct task_struct *curr,
printk("\n======================================================\n");
printk( "[ INFO: %s-safe -> %s-unsafe lock order detected ]\n",
irqclass, irqclass);
+ print_kernel_version();
printk( "------------------------------------------------------\n");
printk("%s/%d [HC%u[%lu]:SC%u[%lu]:HE%u:SE%u] is trying to acquire:\n",
curr->comm, curr->pid,
@@ -793,6 +803,7 @@ print_deadlock_bug(struct task_struct *curr, struct held_lock *prev,
printk("\n=============================================\n");
printk( "[ INFO: possible recursive locking detected ]\n");
+ print_kernel_version();
printk( "---------------------------------------------\n");
printk("%s/%d is trying to acquire lock:\n",
curr->comm, curr->pid);
@@ -1375,6 +1386,7 @@ print_irq_inversion_bug(struct task_struct *curr, struct lock_class *other,
printk("\n=========================================================\n");
printk( "[ INFO: possible irq lock inversion dependency detected ]\n");
+ print_kernel_version();
printk( "---------------------------------------------------------\n");
printk("%s/%d just changed the state of lock:\n",
curr->comm, curr->pid);
@@ -1469,6 +1481,7 @@ print_usage_bug(struct task_struct *curr, struct held_lock *this,
printk("\n=================================\n");
printk( "[ INFO: inconsistent lock state ]\n");
+ print_kernel_version();
printk( "---------------------------------\n");
printk("inconsistent {%s} -> {%s} usage.\n",
diff --git a/kernel/module.c b/kernel/module.c
index b7fe6e840963..7f60e782de1e 100644
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -851,6 +851,7 @@ static int check_version(Elf_Shdr *sechdrs,
printk("%s: no version for \"%s\" found: kernel tainted.\n",
mod->name, symname);
add_taint(TAINT_FORCED_MODULE);
+ mod->taints |= TAINT_FORCED_MODULE;
}
return 1;
}
@@ -933,6 +934,15 @@ static ssize_t module_sect_show(struct module_attribute *mattr,
return sprintf(buf, "0x%lx\n", sattr->address);
}
+static void free_sect_attrs(struct module_sect_attrs *sect_attrs)
+{
+ int section;
+
+ for (section = 0; section < sect_attrs->nsections; section++)
+ kfree(sect_attrs->attrs[section].name);
+ kfree(sect_attrs);
+}
+
static void add_sect_attrs(struct module *mod, unsigned int nsect,
char *secstrings, Elf_Shdr *sechdrs)
{
@@ -949,21 +959,26 @@ static void add_sect_attrs(struct module *mod, unsigned int nsect,
+ nloaded * sizeof(sect_attrs->attrs[0]),
sizeof(sect_attrs->grp.attrs[0]));
size[1] = (nloaded + 1) * sizeof(sect_attrs->grp.attrs[0]);
- if (! (sect_attrs = kmalloc(size[0] + size[1], GFP_KERNEL)))
+ sect_attrs = kzalloc(size[0] + size[1], GFP_KERNEL);
+ if (sect_attrs == NULL)
return;
/* Setup section attributes. */
sect_attrs->grp.name = "sections";
sect_attrs->grp.attrs = (void *)sect_attrs + size[0];
+ sect_attrs->nsections = 0;
sattr = &sect_attrs->attrs[0];
gattr = &sect_attrs->grp.attrs[0];
for (i = 0; i < nsect; i++) {
if (! (sechdrs[i].sh_flags & SHF_ALLOC))
continue;
sattr->address = sechdrs[i].sh_addr;
- strlcpy(sattr->name, secstrings + sechdrs[i].sh_name,
- MODULE_SECT_NAME_LEN);
+ sattr->name = kstrdup(secstrings + sechdrs[i].sh_name,
+ GFP_KERNEL);
+ if (sattr->name == NULL)
+ goto out;
+ sect_attrs->nsections++;
sattr->mattr.show = module_sect_show;
sattr->mattr.store = NULL;
sattr->mattr.attr.name = sattr->name;
@@ -979,7 +994,7 @@ static void add_sect_attrs(struct module *mod, unsigned int nsect,
mod->sect_attrs = sect_attrs;
return;
out:
- kfree(sect_attrs);
+ free_sect_attrs(sect_attrs);
}
static void remove_sect_attrs(struct module *mod)
@@ -989,13 +1004,13 @@ static void remove_sect_attrs(struct module *mod)
&mod->sect_attrs->grp);
/* We are positive that no one is using any sect attrs
* at this point. Deallocate immediately. */
- kfree(mod->sect_attrs);
+ free_sect_attrs(mod->sect_attrs);
mod->sect_attrs = NULL;
}
}
-
#else
+
static inline void add_sect_attrs(struct module *mod, unsigned int nsect,
char *sectstrings, Elf_Shdr *sechdrs)
{
@@ -1325,6 +1340,7 @@ static void set_license(struct module *mod, const char *license)
printk(KERN_WARNING "%s: module license '%s' taints kernel.\n",
mod->name, license);
add_taint(TAINT_PROPRIETARY_MODULE);
+ mod->taints |= TAINT_PROPRIETARY_MODULE;
}
}
@@ -1604,6 +1620,7 @@ static struct module *load_module(void __user *umod,
/* This is allowed: modprobe --force will invalidate it. */
if (!modmagic) {
add_taint(TAINT_FORCED_MODULE);
+ mod->taints |= TAINT_FORCED_MODULE;
printk(KERN_WARNING "%s: no version magic, tainting kernel.\n",
mod->name);
} else if (!same_magic(modmagic, vermagic)) {
@@ -1697,10 +1714,14 @@ static struct module *load_module(void __user *umod,
/* Set up license info based on the info section */
set_license(mod, get_modinfo(sechdrs, infoindex, "license"));
- if (strcmp(mod->name, "ndiswrapper") == 0)
+ if (strcmp(mod->name, "ndiswrapper") == 0) {
add_taint(TAINT_PROPRIETARY_MODULE);
- if (strcmp(mod->name, "driverloader") == 0)
+ mod->taints |= TAINT_PROPRIETARY_MODULE;
+ }
+ if (strcmp(mod->name, "driverloader") == 0) {
add_taint(TAINT_PROPRIETARY_MODULE);
+ mod->taints |= TAINT_PROPRIETARY_MODULE;
+ }
/* Set up MODINFO_ATTR fields */
setup_modinfo(mod, sechdrs, infoindex);
@@ -1746,6 +1767,7 @@ static struct module *load_module(void __user *umod,
printk(KERN_WARNING "%s: No versions for exported symbols."
" Tainting kernel.\n", mod->name);
add_taint(TAINT_FORCED_MODULE);
+ mod->taints |= TAINT_FORCED_MODULE;
}
#endif
@@ -2018,7 +2040,8 @@ const char *module_address_lookup(unsigned long addr,
list_for_each_entry(mod, &modules, list) {
if (within(addr, mod->module_init, mod->init_size)
|| within(addr, mod->module_core, mod->core_size)) {
- *modname = mod->name;
+ if (modname)
+ *modname = mod->name;
return get_ksymbol(mod, addr, size, offset);
}
}
@@ -2212,14 +2235,37 @@ struct module *module_text_address(unsigned long addr)
return mod;
}
+static char *taint_flags(unsigned int taints, char *buf)
+{
+ *buf = '\0';
+ if (taints) {
+ int bx;
+
+ buf[0] = '(';
+ bx = 1;
+ if (taints & TAINT_PROPRIETARY_MODULE)
+ buf[bx++] = 'P';
+ if (taints & TAINT_FORCED_MODULE)
+ buf[bx++] = 'F';
+ /*
+ * TAINT_FORCED_RMMOD: could be added.
+ * TAINT_UNSAFE_SMP, TAINT_MACHINE_CHECK, TAINT_BAD_PAGE don't
+ * apply to modules.
+ */
+ buf[bx] = ')';
+ }
+ return buf;
+}
+
/* Don't grab lock, we're oopsing. */
void print_modules(void)
{
struct module *mod;
+ char buf[8];
printk("Modules linked in:");
list_for_each_entry(mod, &modules, list)
- printk(" %s", mod->name);
+ printk(" %s%s", mod->name, taint_flags(mod->taints, buf));
printk("\n");
}
diff --git a/kernel/nsproxy.c b/kernel/nsproxy.c
new file mode 100644
index 000000000000..6ebdb82a0ce4
--- /dev/null
+++ b/kernel/nsproxy.c
@@ -0,0 +1,139 @@
+/*
+ * Copyright (C) 2006 IBM Corporation
+ *
+ * Author: Serge Hallyn <serue@us.ibm.com>
+ *
+ * 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.
+ *
+ * Jun 2006 - namespaces support
+ * OpenVZ, SWsoft Inc.
+ * Pavel Emelianov <xemul@openvz.org>
+ */
+
+#include <linux/module.h>
+#include <linux/version.h>
+#include <linux/nsproxy.h>
+#include <linux/init_task.h>
+#include <linux/namespace.h>
+#include <linux/utsname.h>
+
+struct nsproxy init_nsproxy = INIT_NSPROXY(init_nsproxy);
+
+static inline void get_nsproxy(struct nsproxy *ns)
+{
+ atomic_inc(&ns->count);
+}
+
+void get_task_namespaces(struct task_struct *tsk)
+{
+ struct nsproxy *ns = tsk->nsproxy;
+ if (ns) {
+ get_nsproxy(ns);
+ }
+}
+
+/*
+ * creates a copy of "orig" with refcount 1.
+ * This does not grab references to the contained namespaces,
+ * so that needs to be done by dup_namespaces.
+ */
+static inline struct nsproxy *clone_namespaces(struct nsproxy *orig)
+{
+ struct nsproxy *ns;
+
+ ns = kmalloc(sizeof(struct nsproxy), GFP_KERNEL);
+ if (ns) {
+ memcpy(ns, orig, sizeof(struct nsproxy));
+ atomic_set(&ns->count, 1);
+ }
+ return ns;
+}
+
+/*
+ * copies the nsproxy, setting refcount to 1, and grabbing a
+ * reference to all contained namespaces. Called from
+ * sys_unshare()
+ */
+struct nsproxy *dup_namespaces(struct nsproxy *orig)
+{
+ struct nsproxy *ns = clone_namespaces(orig);
+
+ if (ns) {
+ if (ns->namespace)
+ get_namespace(ns->namespace);
+ if (ns->uts_ns)
+ get_uts_ns(ns->uts_ns);
+ if (ns->ipc_ns)
+ get_ipc_ns(ns->ipc_ns);
+ }
+
+ return ns;
+}
+
+/*
+ * called from clone. This now handles copy for nsproxy and all
+ * namespaces therein.
+ */
+int copy_namespaces(int flags, struct task_struct *tsk)
+{
+ struct nsproxy *old_ns = tsk->nsproxy;
+ struct nsproxy *new_ns;
+ int err = 0;
+
+ if (!old_ns)
+ return 0;
+
+ get_nsproxy(old_ns);
+
+ if (!(flags & (CLONE_NEWNS | CLONE_NEWUTS | CLONE_NEWIPC)))
+ return 0;
+
+ new_ns = clone_namespaces(old_ns);
+ if (!new_ns) {
+ err = -ENOMEM;
+ goto out;
+ }
+
+ tsk->nsproxy = new_ns;
+
+ err = copy_namespace(flags, tsk);
+ if (err)
+ goto out_ns;
+
+ err = copy_utsname(flags, tsk);
+ if (err)
+ goto out_uts;
+
+ err = copy_ipcs(flags, tsk);
+ if (err)
+ goto out_ipc;
+
+out:
+ put_nsproxy(old_ns);
+ return err;
+
+out_ipc:
+ if (new_ns->uts_ns)
+ put_uts_ns(new_ns->uts_ns);
+out_uts:
+ if (new_ns->namespace)
+ put_namespace(new_ns->namespace);
+out_ns:
+ tsk->nsproxy = old_ns;
+ kfree(new_ns);
+ goto out;
+}
+
+void free_nsproxy(struct nsproxy *ns)
+{
+ if (ns->namespace)
+ put_namespace(ns->namespace);
+ if (ns->uts_ns)
+ put_uts_ns(ns->uts_ns);
+ if (ns->ipc_ns)
+ put_ipc_ns(ns->ipc_ns);
+ kfree(ns);
+}
diff --git a/kernel/panic.c b/kernel/panic.c
index 6ceb664fb52a..525e365f7239 100644
--- a/kernel/panic.c
+++ b/kernel/panic.c
@@ -21,7 +21,6 @@
#include <linux/debug_locks.h>
int panic_on_oops;
-int panic_on_unrecovered_nmi;
int tainted;
static int pause_on_oops;
static int pause_on_oops_flag;
diff --git a/kernel/params.c b/kernel/params.c
index 91aea7aa532e..f406655d6653 100644
--- a/kernel/params.c
+++ b/kernel/params.c
@@ -547,6 +547,7 @@ static void __init kernel_param_sysfs_setup(const char *name,
unsigned int name_skip)
{
struct module_kobject *mk;
+ int ret;
mk = kzalloc(sizeof(struct module_kobject), GFP_KERNEL);
BUG_ON(!mk);
@@ -554,7 +555,8 @@ static void __init kernel_param_sysfs_setup(const char *name,
mk->mod = THIS_MODULE;
kobj_set_kset_s(mk, module_subsys);
kobject_set_name(&mk->kobj, name);
- kobject_register(&mk->kobj);
+ ret = kobject_register(&mk->kobj);
+ BUG_ON(ret < 0);
/* no need to keep the kobject if no parameter is exported */
if (!param_sysfs_setup(mk, kparam, num_params, name_skip)) {
@@ -684,13 +686,20 @@ decl_subsys(module, &module_ktype, NULL);
*/
static int __init param_sysfs_init(void)
{
- subsystem_register(&module_subsys);
+ int ret;
+
+ ret = subsystem_register(&module_subsys);
+ if (ret < 0) {
+ printk(KERN_WARNING "%s (%d): subsystem_register error: %d\n",
+ __FILE__, __LINE__, ret);
+ return ret;
+ }
param_sysfs_builtin();
return 0;
}
-__initcall(param_sysfs_init);
+subsys_initcall(param_sysfs_init);
EXPORT_SYMBOL(param_set_byte);
EXPORT_SYMBOL(param_get_byte);
diff --git a/kernel/pid.c b/kernel/pid.c
index 8387e8c68193..b914392085f9 100644
--- a/kernel/pid.c
+++ b/kernel/pid.c
@@ -26,6 +26,7 @@
#include <linux/init.h>
#include <linux/bootmem.h>
#include <linux/hash.h>
+#include <linux/pspace.h>
#define pid_hashfn(nr) hash_long((unsigned long)nr, pidhash_shift)
static struct hlist_head *pid_hash;
@@ -33,17 +34,20 @@ static int pidhash_shift;
static kmem_cache_t *pid_cachep;
int pid_max = PID_MAX_DEFAULT;
-int last_pid;
#define RESERVED_PIDS 300
int pid_max_min = RESERVED_PIDS + 1;
int pid_max_max = PID_MAX_LIMIT;
-#define PIDMAP_ENTRIES ((PID_MAX_LIMIT + 8*PAGE_SIZE - 1)/PAGE_SIZE/8)
#define BITS_PER_PAGE (PAGE_SIZE*8)
#define BITS_PER_PAGE_MASK (BITS_PER_PAGE-1)
-#define mk_pid(map, off) (((map) - pidmap_array)*BITS_PER_PAGE + (off))
+
+static inline int mk_pid(struct pspace *pspace, struct pidmap *map, int off)
+{
+ return (map - pspace->pidmap)*BITS_PER_PAGE + off;
+}
+
#define find_next_offset(map, off) \
find_next_zero_bit((map)->page, BITS_PER_PAGE, off)
@@ -53,13 +57,12 @@ int pid_max_max = PID_MAX_LIMIT;
* value does not cause lots of bitmaps to be allocated, but
* the scheme scales to up to 4 million PIDs, runtime.
*/
-typedef struct pidmap {
- atomic_t nr_free;
- void *page;
-} pidmap_t;
-
-static pidmap_t pidmap_array[PIDMAP_ENTRIES] =
- { [ 0 ... PIDMAP_ENTRIES-1 ] = { ATOMIC_INIT(BITS_PER_PAGE), NULL } };
+struct pspace init_pspace = {
+ .pidmap = {
+ [ 0 ... PIDMAP_ENTRIES-1] = { ATOMIC_INIT(BITS_PER_PAGE), NULL }
+ },
+ .last_pid = 0
+};
/*
* Note: disable interrupts while the pidmap_lock is held as an
@@ -74,40 +77,41 @@ static pidmap_t pidmap_array[PIDMAP_ENTRIES] =
* irq handlers that take it we can leave the interrupts enabled.
* For now it is easier to be safe than to prove it can't happen.
*/
+
static __cacheline_aligned_in_smp DEFINE_SPINLOCK(pidmap_lock);
-static fastcall void free_pidmap(int pid)
+static fastcall void free_pidmap(struct pspace *pspace, int pid)
{
- pidmap_t *map = pidmap_array + pid / BITS_PER_PAGE;
+ struct pidmap *map = pspace->pidmap + pid / BITS_PER_PAGE;
int offset = pid & BITS_PER_PAGE_MASK;
clear_bit(offset, map->page);
atomic_inc(&map->nr_free);
}
-static int alloc_pidmap(void)
+static int alloc_pidmap(struct pspace *pspace)
{
- int i, offset, max_scan, pid, last = last_pid;
- pidmap_t *map;
+ int i, offset, max_scan, pid, last = pspace->last_pid;
+ struct pidmap *map;
pid = last + 1;
if (pid >= pid_max)
pid = RESERVED_PIDS;
offset = pid & BITS_PER_PAGE_MASK;
- map = &pidmap_array[pid/BITS_PER_PAGE];
+ map = &pspace->pidmap[pid/BITS_PER_PAGE];
max_scan = (pid_max + BITS_PER_PAGE - 1)/BITS_PER_PAGE - !offset;
for (i = 0; i <= max_scan; ++i) {
if (unlikely(!map->page)) {
- unsigned long page = get_zeroed_page(GFP_KERNEL);
+ void *page = kzalloc(PAGE_SIZE, GFP_KERNEL);
/*
* Free the page if someone raced with us
* installing it:
*/
spin_lock_irq(&pidmap_lock);
if (map->page)
- free_page(page);
+ kfree(page);
else
- map->page = (void *)page;
+ map->page = page;
spin_unlock_irq(&pidmap_lock);
if (unlikely(!map->page))
break;
@@ -116,11 +120,11 @@ static int alloc_pidmap(void)
do {
if (!test_and_set_bit(offset, map->page)) {
atomic_dec(&map->nr_free);
- last_pid = pid;
+ pspace->last_pid = pid;
return pid;
}
offset = find_next_offset(map, offset);
- pid = mk_pid(map, offset);
+ pid = mk_pid(pspace, map, offset);
/*
* find_next_offset() found a bit, the pid from it
* is in-bounds, and if we fell back to the last
@@ -131,16 +135,34 @@ static int alloc_pidmap(void)
(i != max_scan || pid < last ||
!((last+1) & BITS_PER_PAGE_MASK)));
}
- if (map < &pidmap_array[(pid_max-1)/BITS_PER_PAGE]) {
+ if (map < &pspace->pidmap[(pid_max-1)/BITS_PER_PAGE]) {
++map;
offset = 0;
} else {
- map = &pidmap_array[0];
+ map = &pspace->pidmap[0];
offset = RESERVED_PIDS;
if (unlikely(last == offset))
break;
}
- pid = mk_pid(map, offset);
+ pid = mk_pid(pspace, map, offset);
+ }
+ return -1;
+}
+
+static int next_pidmap(struct pspace *pspace, int last)
+{
+ int offset;
+ struct pidmap *map, *end;
+
+ offset = (last + 1) & BITS_PER_PAGE_MASK;
+ map = &pspace->pidmap[(last + 1)/BITS_PER_PAGE];
+ end = &pspace->pidmap[PIDMAP_ENTRIES];
+ for (; map < end; map++, offset = 0) {
+ if (unlikely(!map->page))
+ continue;
+ offset = find_next_bit((map)->page, BITS_PER_PAGE, offset);
+ if (offset < BITS_PER_PAGE)
+ return mk_pid(pspace, map, offset);
}
return -1;
}
@@ -153,6 +175,7 @@ fastcall void put_pid(struct pid *pid)
atomic_dec_and_test(&pid->count))
kmem_cache_free(pid_cachep, pid);
}
+EXPORT_SYMBOL_GPL(put_pid);
static void delayed_put_pid(struct rcu_head *rhp)
{
@@ -169,7 +192,7 @@ fastcall void free_pid(struct pid *pid)
hlist_del_rcu(&pid->pid_chain);
spin_unlock_irqrestore(&pidmap_lock, flags);
- free_pidmap(pid->nr);
+ free_pidmap(&init_pspace, pid->nr);
call_rcu(&pid->rcu, delayed_put_pid);
}
@@ -183,7 +206,7 @@ struct pid *alloc_pid(void)
if (!pid)
goto out;
- nr = alloc_pidmap();
+ nr = alloc_pidmap(&init_pspace);
if (nr < 0)
goto out_free;
@@ -217,6 +240,7 @@ struct pid * fastcall find_pid(int nr)
}
return NULL;
}
+EXPORT_SYMBOL_GPL(find_pid);
int fastcall attach_pid(struct task_struct *task, enum pid_type type, int nr)
{
@@ -280,6 +304,15 @@ struct task_struct *find_task_by_pid_type(int type, int nr)
EXPORT_SYMBOL(find_task_by_pid_type);
+struct pid *get_task_pid(struct task_struct *task, enum pid_type type)
+{
+ struct pid *pid;
+ rcu_read_lock();
+ pid = get_pid(task->pids[type].pid);
+ rcu_read_unlock();
+ return pid;
+}
+
struct task_struct *fastcall get_pid_task(struct pid *pid, enum pid_type type)
{
struct task_struct *result;
@@ -303,6 +336,26 @@ struct pid *find_get_pid(pid_t nr)
}
/*
+ * Used by proc to find the first pid that is greater then or equal to nr.
+ *
+ * If there is a pid at nr this function is exactly the same as find_pid.
+ */
+struct pid *find_ge_pid(int nr)
+{
+ struct pid *pid;
+
+ do {
+ pid = find_pid(nr);
+ if (pid)
+ break;
+ nr = next_pidmap(&init_pspace, nr);
+ } while (nr > 0);
+
+ return pid;
+}
+EXPORT_SYMBOL_GPL(find_get_pid);
+
+/*
* The pid hash table is scaled according to the amount of memory in the
* machine. From a minimum of 16 slots up to 4096 slots at one gigabyte or
* more.
@@ -329,10 +382,10 @@ void __init pidhash_init(void)
void __init pidmap_init(void)
{
- pidmap_array->page = (void *)get_zeroed_page(GFP_KERNEL);
+ init_pspace.pidmap[0].page = kzalloc(PAGE_SIZE, GFP_KERNEL);
/* Reserve PID 0. We never call free_pidmap(0) */
- set_bit(0, pidmap_array->page);
- atomic_dec(&pidmap_array->nr_free);
+ set_bit(0, init_pspace.pidmap[0].page);
+ atomic_dec(&init_pspace.pidmap[0].nr_free);
pid_cachep = kmem_cache_create("pid", sizeof(struct pid),
__alignof__(struct pid),
diff --git a/kernel/posix-cpu-timers.c b/kernel/posix-cpu-timers.c
index d38d9ec3276c..479b16b44f79 100644
--- a/kernel/posix-cpu-timers.c
+++ b/kernel/posix-cpu-timers.c
@@ -1393,25 +1393,13 @@ void set_process_cpu_timer(struct task_struct *tsk, unsigned int clock_idx,
}
}
-static long posix_cpu_clock_nanosleep_restart(struct restart_block *);
-
-int posix_cpu_nsleep(const clockid_t which_clock, int flags,
- struct timespec *rqtp, struct timespec __user *rmtp)
+static int do_cpu_nanosleep(const clockid_t which_clock, int flags,
+ struct timespec *rqtp, struct itimerspec *it)
{
- struct restart_block *restart_block =
- &current_thread_info()->restart_block;
struct k_itimer timer;
int error;
/*
- * Diagnose required errors first.
- */
- if (CPUCLOCK_PERTHREAD(which_clock) &&
- (CPUCLOCK_PID(which_clock) == 0 ||
- CPUCLOCK_PID(which_clock) == current->pid))
- return -EINVAL;
-
- /*
* Set up a temporary timer and then wait for it to go off.
*/
memset(&timer, 0, sizeof timer);
@@ -1422,11 +1410,12 @@ int posix_cpu_nsleep(const clockid_t which_clock, int flags,
timer.it_process = current;
if (!error) {
static struct itimerspec zero_it;
- struct itimerspec it = { .it_value = *rqtp,
- .it_interval = {} };
+
+ memset(it, 0, sizeof *it);
+ it->it_value = *rqtp;
spin_lock_irq(&timer.it_lock);
- error = posix_cpu_timer_set(&timer, flags, &it, NULL);
+ error = posix_cpu_timer_set(&timer, flags, it, NULL);
if (error) {
spin_unlock_irq(&timer.it_lock);
return error;
@@ -1454,49 +1443,89 @@ int posix_cpu_nsleep(const clockid_t which_clock, int flags,
* We were interrupted by a signal.
*/
sample_to_timespec(which_clock, timer.it.cpu.expires, rqtp);
- posix_cpu_timer_set(&timer, 0, &zero_it, &it);
+ posix_cpu_timer_set(&timer, 0, &zero_it, it);
spin_unlock_irq(&timer.it_lock);
- if ((it.it_value.tv_sec | it.it_value.tv_nsec) == 0) {
+ if ((it->it_value.tv_sec | it->it_value.tv_nsec) == 0) {
/*
* It actually did fire already.
*/
return 0;
}
+ error = -ERESTART_RESTARTBLOCK;
+ }
+
+ return error;
+}
+
+int posix_cpu_nsleep(const clockid_t which_clock, int flags,
+ struct timespec *rqtp, struct timespec __user *rmtp)
+{
+ struct restart_block *restart_block =
+ &current_thread_info()->restart_block;
+ struct itimerspec it;
+ int error;
+
+ /*
+ * Diagnose required errors first.
+ */
+ if (CPUCLOCK_PERTHREAD(which_clock) &&
+ (CPUCLOCK_PID(which_clock) == 0 ||
+ CPUCLOCK_PID(which_clock) == current->pid))
+ return -EINVAL;
+
+ error = do_cpu_nanosleep(which_clock, flags, rqtp, &it);
+
+ if (error == -ERESTART_RESTARTBLOCK) {
+
+ if (flags & TIMER_ABSTIME)
+ return -ERESTARTNOHAND;
/*
- * Report back to the user the time still remaining.
- */
- if (rmtp != NULL && !(flags & TIMER_ABSTIME) &&
- copy_to_user(rmtp, &it.it_value, sizeof *rmtp))
+ * Report back to the user the time still remaining.
+ */
+ if (rmtp != NULL && copy_to_user(rmtp, &it.it_value, sizeof *rmtp))
return -EFAULT;
- restart_block->fn = posix_cpu_clock_nanosleep_restart;
- /* Caller already set restart_block->arg1 */
+ restart_block->fn = posix_cpu_nsleep_restart;
restart_block->arg0 = which_clock;
restart_block->arg1 = (unsigned long) rmtp;
restart_block->arg2 = rqtp->tv_sec;
restart_block->arg3 = rqtp->tv_nsec;
-
- error = -ERESTART_RESTARTBLOCK;
}
-
return error;
}
-static long
-posix_cpu_clock_nanosleep_restart(struct restart_block *restart_block)
+long posix_cpu_nsleep_restart(struct restart_block *restart_block)
{
clockid_t which_clock = restart_block->arg0;
struct timespec __user *rmtp;
struct timespec t;
+ struct itimerspec it;
+ int error;
rmtp = (struct timespec __user *) restart_block->arg1;
t.tv_sec = restart_block->arg2;
t.tv_nsec = restart_block->arg3;
restart_block->fn = do_no_restart_syscall;
- return posix_cpu_nsleep(which_clock, TIMER_ABSTIME, &t, rmtp);
+ error = do_cpu_nanosleep(which_clock, TIMER_ABSTIME, &t, &it);
+
+ if (error == -ERESTART_RESTARTBLOCK) {
+ /*
+ * Report back to the user the time still remaining.
+ */
+ if (rmtp != NULL && copy_to_user(rmtp, &it.it_value, sizeof *rmtp))
+ return -EFAULT;
+
+ restart_block->fn = posix_cpu_nsleep_restart;
+ restart_block->arg0 = which_clock;
+ restart_block->arg1 = (unsigned long) rmtp;
+ restart_block->arg2 = t.tv_sec;
+ restart_block->arg3 = t.tv_nsec;
+ }
+ return error;
+
}
@@ -1524,6 +1553,10 @@ static int process_cpu_nsleep(const clockid_t which_clock, int flags,
{
return posix_cpu_nsleep(PROCESS_CLOCK, flags, rqtp, rmtp);
}
+static long process_cpu_nsleep_restart(struct restart_block *restart_block)
+{
+ return -EINVAL;
+}
static int thread_cpu_clock_getres(const clockid_t which_clock,
struct timespec *tp)
{
@@ -1544,6 +1577,10 @@ static int thread_cpu_nsleep(const clockid_t which_clock, int flags,
{
return -EINVAL;
}
+static long thread_cpu_nsleep_restart(struct restart_block *restart_block)
+{
+ return -EINVAL;
+}
static __init int init_posix_cpu_timers(void)
{
@@ -1553,6 +1590,7 @@ static __init int init_posix_cpu_timers(void)
.clock_set = do_posix_clock_nosettime,
.timer_create = process_cpu_timer_create,
.nsleep = process_cpu_nsleep,
+ .nsleep_restart = process_cpu_nsleep_restart,
};
struct k_clock thread = {
.clock_getres = thread_cpu_clock_getres,
@@ -1560,6 +1598,7 @@ static __init int init_posix_cpu_timers(void)
.clock_set = do_posix_clock_nosettime,
.timer_create = thread_cpu_timer_create,
.nsleep = thread_cpu_nsleep,
+ .nsleep_restart = thread_cpu_nsleep_restart,
};
register_posix_clock(CLOCK_PROCESS_CPUTIME_ID, &process);
diff --git a/kernel/posix-timers.c b/kernel/posix-timers.c
index ac6dc8744429..e5ebcc1ec3a0 100644
--- a/kernel/posix-timers.c
+++ b/kernel/posix-timers.c
@@ -973,3 +973,24 @@ sys_clock_nanosleep(const clockid_t which_clock, int flags,
return CLOCK_DISPATCH(which_clock, nsleep,
(which_clock, flags, &t, rmtp));
}
+
+/*
+ * nanosleep_restart for monotonic and realtime clocks
+ */
+static int common_nsleep_restart(struct restart_block *restart_block)
+{
+ return hrtimer_nanosleep_restart(restart_block);
+}
+
+/*
+ * This will restart clock_nanosleep. This is required only by
+ * compat_clock_nanosleep_restart for now.
+ */
+long
+clock_nanosleep_restart(struct restart_block *restart_block)
+{
+ clockid_t which_clock = restart_block->arg0;
+
+ return CLOCK_DISPATCH(which_clock, nsleep_restart,
+ (restart_block));
+}
diff --git a/kernel/power/snapshot.c b/kernel/power/snapshot.c
index 1b84313cbab5..99f9b7d177d6 100644
--- a/kernel/power/snapshot.c
+++ b/kernel/power/snapshot.c
@@ -906,7 +906,7 @@ static void init_header(struct swsusp_info *info)
memset(info, 0, sizeof(struct swsusp_info));
info->version_code = LINUX_VERSION_CODE;
info->num_physpages = num_physpages;
- memcpy(&info->uts, &system_utsname, sizeof(system_utsname));
+ memcpy(&info->uts, init_utsname(), sizeof(struct new_utsname));
info->cpus = num_online_cpus();
info->image_pages = nr_copy_pages;
info->pages = nr_copy_pages + nr_meta_pages + 1;
@@ -1050,13 +1050,13 @@ static inline int check_header(struct swsusp_info *info)
reason = "kernel version";
if (info->num_physpages != num_physpages)
reason = "memory size";
- if (strcmp(info->uts.sysname,system_utsname.sysname))
+ if (strcmp(info->uts.sysname,init_utsname()->sysname))
reason = "system type";
- if (strcmp(info->uts.release,system_utsname.release))
+ if (strcmp(info->uts.release,init_utsname()->release))
reason = "kernel release";
- if (strcmp(info->uts.version,system_utsname.version))
+ if (strcmp(info->uts.version,init_utsname()->version))
reason = "version";
- if (strcmp(info->uts.machine,system_utsname.machine))
+ if (strcmp(info->uts.machine,init_utsname()->machine))
reason = "machine";
if (reason) {
printk(KERN_ERR "swsusp: Resume mismatch: %s\n", reason);
diff --git a/kernel/ptrace.c b/kernel/ptrace.c
index 8aad0331d82e..4d50e06fd745 100644
--- a/kernel/ptrace.c
+++ b/kernel/ptrace.c
@@ -440,6 +440,7 @@ struct task_struct *ptrace_get_task_struct(pid_t pid)
child = find_task_by_pid(pid);
if (child)
get_task_struct(child);
+
read_unlock(&tasklist_lock);
if (!child)
return ERR_PTR(-ESRCH);
diff --git a/kernel/rcutorture.c b/kernel/rcutorture.c
index 4d1c3d247127..4f2c4272d59c 100644
--- a/kernel/rcutorture.c
+++ b/kernel/rcutorture.c
@@ -192,13 +192,13 @@ static struct rcu_torture_ops *cur_ops = NULL;
* Definitions for rcu torture testing.
*/
-static int rcu_torture_read_lock(void)
+static int rcu_torture_read_lock(void) __acquires(RCU)
{
rcu_read_lock();
return 0;
}
-static void rcu_torture_read_unlock(int idx)
+static void rcu_torture_read_unlock(int idx) __releases(RCU)
{
rcu_read_unlock();
}
@@ -250,13 +250,13 @@ static struct rcu_torture_ops rcu_ops = {
* Definitions for rcu_bh torture testing.
*/
-static int rcu_bh_torture_read_lock(void)
+static int rcu_bh_torture_read_lock(void) __acquires(RCU_BH)
{
rcu_read_lock_bh();
return 0;
}
-static void rcu_bh_torture_read_unlock(int idx)
+static void rcu_bh_torture_read_unlock(int idx) __releases(RCU_BH)
{
rcu_read_unlock_bh();
}
diff --git a/kernel/relay.c b/kernel/relay.c
index 85786ff2a4f9..1d63ecddfa70 100644
--- a/kernel/relay.c
+++ b/kernel/relay.c
@@ -95,7 +95,7 @@ int relay_mmap_buf(struct rchan_buf *buf, struct vm_area_struct *vma)
* @buf: the buffer struct
* @size: total size of the buffer
*
- * Returns a pointer to the resulting buffer, NULL if unsuccessful. The
+ * Returns a pointer to the resulting buffer, %NULL if unsuccessful. The
* passed in size will get page aligned, if it isn't already.
*/
static void *relay_alloc_buf(struct rchan_buf *buf, size_t *size)
@@ -132,10 +132,9 @@ depopulate:
/**
* relay_create_buf - allocate and initialize a channel buffer
- * @alloc_size: size of the buffer to allocate
- * @n_subbufs: number of sub-buffers in the channel
+ * @chan: the relay channel
*
- * Returns channel buffer if successful, NULL otherwise
+ * Returns channel buffer if successful, %NULL otherwise.
*/
struct rchan_buf *relay_create_buf(struct rchan *chan)
{
@@ -163,6 +162,7 @@ free_buf:
/**
* relay_destroy_channel - free the channel struct
+ * @kref: target kernel reference that contains the relay channel
*
* Should only be called from kref_put().
*/
@@ -194,6 +194,7 @@ void relay_destroy_buf(struct rchan_buf *buf)
/**
* relay_remove_buf - remove a channel buffer
+ * @kref: target kernel reference that contains the relay buffer
*
* Removes the file from the fileystem, which also frees the
* rchan_buf_struct and the channel buffer. Should only be called from
@@ -374,7 +375,7 @@ void relay_reset(struct rchan *chan)
}
EXPORT_SYMBOL_GPL(relay_reset);
-/**
+/*
* relay_open_buf - create a new relay channel buffer
*
* Internal - used by relay_open().
@@ -448,12 +449,12 @@ static inline void setup_callbacks(struct rchan *chan,
/**
* relay_open - create a new relay channel
* @base_filename: base name of files to create
- * @parent: dentry of parent directory, NULL for root directory
+ * @parent: dentry of parent directory, %NULL for root directory
* @subbuf_size: size of sub-buffers
* @n_subbufs: number of sub-buffers
* @cb: client callback functions
*
- * Returns channel pointer if successful, NULL otherwise.
+ * Returns channel pointer if successful, %NULL otherwise.
*
* Creates a channel buffer for each cpu using the sizes and
* attributes specified. The created channel buffer files
@@ -585,7 +586,7 @@ EXPORT_SYMBOL_GPL(relay_switch_subbuf);
* subbufs_consumed should be the number of sub-buffers newly consumed,
* not the total consumed.
*
- * NOTE: kernel clients don't need to call this function if the channel
+ * NOTE: Kernel clients don't need to call this function if the channel
* mode is 'overwrite'.
*/
void relay_subbufs_consumed(struct rchan *chan,
@@ -641,7 +642,7 @@ EXPORT_SYMBOL_GPL(relay_close);
* relay_flush - close the channel
* @chan: the channel
*
- * Flushes all channel buffers i.e. forces buffer switch.
+ * Flushes all channel buffers, i.e. forces buffer switch.
*/
void relay_flush(struct rchan *chan)
{
@@ -729,7 +730,7 @@ static int relay_file_release(struct inode *inode, struct file *filp)
return 0;
}
-/**
+/*
* relay_file_read_consume - update the consumed count for the buffer
*/
static void relay_file_read_consume(struct rchan_buf *buf,
@@ -756,7 +757,7 @@ static void relay_file_read_consume(struct rchan_buf *buf,
}
}
-/**
+/*
* relay_file_read_avail - boolean, are there unconsumed bytes available?
*/
static int relay_file_read_avail(struct rchan_buf *buf, size_t read_pos)
@@ -793,6 +794,8 @@ static int relay_file_read_avail(struct rchan_buf *buf, size_t read_pos)
/**
* relay_file_read_subbuf_avail - return bytes available in sub-buffer
+ * @read_pos: file read position
+ * @buf: relay channel buffer
*/
static size_t relay_file_read_subbuf_avail(size_t read_pos,
struct rchan_buf *buf)
@@ -818,6 +821,8 @@ static size_t relay_file_read_subbuf_avail(size_t read_pos,
/**
* relay_file_read_start_pos - find the first available byte to read
+ * @read_pos: file read position
+ * @buf: relay channel buffer
*
* If the read_pos is in the middle of padding, return the
* position of the first actually available byte, otherwise
@@ -844,6 +849,9 @@ static size_t relay_file_read_start_pos(size_t read_pos,
/**
* relay_file_read_end_pos - return the new read position
+ * @read_pos: file read position
+ * @buf: relay channel buffer
+ * @count: number of bytes to be read
*/
static size_t relay_file_read_end_pos(struct rchan_buf *buf,
size_t read_pos,
@@ -865,7 +873,7 @@ static size_t relay_file_read_end_pos(struct rchan_buf *buf,
return end_pos;
}
-/**
+/*
* subbuf_read_actor - read up to one subbuf's worth of data
*/
static int subbuf_read_actor(size_t read_start,
@@ -890,7 +898,7 @@ static int subbuf_read_actor(size_t read_start,
return ret;
}
-/**
+/*
* subbuf_send_actor - send up to one subbuf's worth of data
*/
static int subbuf_send_actor(size_t read_start,
@@ -933,7 +941,7 @@ typedef int (*subbuf_actor_t) (size_t read_start,
read_descriptor_t *desc,
read_actor_t actor);
-/**
+/*
* relay_file_read_subbufs - read count bytes, bridging subbuf boundaries
*/
static inline ssize_t relay_file_read_subbufs(struct file *filp,
diff --git a/kernel/resource.c b/kernel/resource.c
index 9db38a1a7520..6de60c12143e 100644
--- a/kernel/resource.c
+++ b/kernel/resource.c
@@ -193,6 +193,13 @@ static int __release_resource(struct resource *old)
return -EINVAL;
}
+/**
+ * request_resource - request and reserve an I/O or memory resource
+ * @root: root resource descriptor
+ * @new: resource descriptor desired by caller
+ *
+ * Returns 0 for success, negative error code on error.
+ */
int request_resource(struct resource *root, struct resource *new)
{
struct resource *conflict;
@@ -205,6 +212,15 @@ int request_resource(struct resource *root, struct resource *new)
EXPORT_SYMBOL(request_resource);
+/**
+ * ____request_resource - reserve a resource, with resource conflict returned
+ * @root: root resource descriptor
+ * @new: resource descriptor desired by caller
+ *
+ * Returns:
+ * On success, NULL is returned.
+ * On error, a pointer to the conflicting resource is returned.
+ */
struct resource *____request_resource(struct resource *root, struct resource *new)
{
struct resource *conflict;
@@ -217,6 +233,10 @@ struct resource *____request_resource(struct resource *root, struct resource *ne
EXPORT_SYMBOL(____request_resource);
+/**
+ * release_resource - release a previously reserved resource
+ * @old: resource pointer
+ */
int release_resource(struct resource *old)
{
int retval;
@@ -315,8 +335,16 @@ static int find_resource(struct resource *root, struct resource *new,
return -EBUSY;
}
-/*
- * Allocate empty slot in the resource tree given range and alignment.
+/**
+ * allocate_resource - allocate empty slot in the resource tree given range & alignment
+ * @root: root resource descriptor
+ * @new: resource descriptor desired by caller
+ * @size: requested resource region size
+ * @min: minimum size to allocate
+ * @max: maximum size to allocate
+ * @align: alignment requested, in bytes
+ * @alignf: alignment function, optional, called if not NULL
+ * @alignf_data: arbitrary data to pass to the @alignf function
*/
int allocate_resource(struct resource *root, struct resource *new,
resource_size_t size, resource_size_t min,
@@ -407,10 +435,15 @@ int insert_resource(struct resource *parent, struct resource *new)
return result;
}
-/*
+/**
+ * adjust_resource - modify a resource's start and size
+ * @res: resource to modify
+ * @start: new start value
+ * @size: new size
+ *
* Given an existing resource, change its start and size to match the
- * arguments. Returns -EBUSY if it can't fit. Existing children of
- * the resource are assumed to be immutable.
+ * arguments. Returns 0 on success, -EBUSY if it can't fit.
+ * Existing children of the resource are assumed to be immutable.
*/
int adjust_resource(struct resource *res, resource_size_t start, resource_size_t size)
{
@@ -456,11 +489,19 @@ EXPORT_SYMBOL(adjust_resource);
* Note how this, unlike the above, knows about
* the IO flag meanings (busy etc).
*
- * Request-region creates a new busy region.
+ * request_region creates a new busy region.
*
- * Check-region returns non-zero if the area is already busy
+ * check_region returns non-zero if the area is already busy.
*
- * Release-region releases a matching busy region.
+ * release_region releases a matching busy region.
+ */
+
+/**
+ * __request_region - create a new busy resource region
+ * @parent: parent resource descriptor
+ * @start: resource start address
+ * @n: resource region size
+ * @name: reserving caller's ID string
*/
struct resource * __request_region(struct resource *parent,
resource_size_t start, resource_size_t n,
@@ -497,9 +538,23 @@ struct resource * __request_region(struct resource *parent,
}
return res;
}
-
EXPORT_SYMBOL(__request_region);
+/**
+ * __check_region - check if a resource region is busy or free
+ * @parent: parent resource descriptor
+ * @start: resource start address
+ * @n: resource region size
+ *
+ * Returns 0 if the region is free at the moment it is checked,
+ * returns %-EBUSY if the region is busy.
+ *
+ * NOTE:
+ * This function is deprecated because its use is racy.
+ * Even if it returns 0, a subsequent call to request_region()
+ * may fail because another driver etc. just allocated the region.
+ * Do NOT use it. It will be removed from the kernel.
+ */
int __check_region(struct resource *parent, resource_size_t start,
resource_size_t n)
{
@@ -513,9 +568,16 @@ int __check_region(struct resource *parent, resource_size_t start,
kfree(res);
return 0;
}
-
EXPORT_SYMBOL(__check_region);
+/**
+ * __release_region - release a previously reserved resource region
+ * @parent: parent resource descriptor
+ * @start: resource start address
+ * @n: resource region size
+ *
+ * The described resource region must match a currently busy region.
+ */
void __release_region(struct resource *parent, resource_size_t start,
resource_size_t n)
{
@@ -553,7 +615,6 @@ void __release_region(struct resource *parent, resource_size_t start,
"<%016llx-%016llx>\n", (unsigned long long)start,
(unsigned long long)end);
}
-
EXPORT_SYMBOL(__release_region);
/*
diff --git a/kernel/rtmutex.c b/kernel/rtmutex.c
index 3e13a1e5856f..4ab17da46fd8 100644
--- a/kernel/rtmutex.c
+++ b/kernel/rtmutex.c
@@ -251,6 +251,7 @@ static int rt_mutex_adjust_prio_chain(struct task_struct *task,
/* Grab the next task */
task = rt_mutex_owner(lock);
+ get_task_struct(task);
spin_lock_irqsave(&task->pi_lock, flags);
if (waiter == rt_mutex_top_waiter(lock)) {
@@ -269,7 +270,6 @@ static int rt_mutex_adjust_prio_chain(struct task_struct *task,
__rt_mutex_adjust_prio(task);
}
- get_task_struct(task);
spin_unlock_irqrestore(&task->pi_lock, flags);
top_waiter = rt_mutex_top_waiter(lock);
@@ -409,7 +409,7 @@ static int task_blocks_on_rt_mutex(struct rt_mutex *lock,
struct task_struct *owner = rt_mutex_owner(lock);
struct rt_mutex_waiter *top_waiter = waiter;
unsigned long flags;
- int boost = 0, res;
+ int chain_walk = 0, res;
spin_lock_irqsave(&current->pi_lock, flags);
__rt_mutex_adjust_prio(current);
@@ -433,25 +433,23 @@ static int task_blocks_on_rt_mutex(struct rt_mutex *lock,
plist_add(&waiter->pi_list_entry, &owner->pi_waiters);
__rt_mutex_adjust_prio(owner);
- if (owner->pi_blocked_on) {
- boost = 1;
- /* gets dropped in rt_mutex_adjust_prio_chain()! */
- get_task_struct(owner);
- }
- spin_unlock_irqrestore(&owner->pi_lock, flags);
- }
- else if (debug_rt_mutex_detect_deadlock(waiter, detect_deadlock)) {
- spin_lock_irqsave(&owner->pi_lock, flags);
- if (owner->pi_blocked_on) {
- boost = 1;
- /* gets dropped in rt_mutex_adjust_prio_chain()! */
- get_task_struct(owner);
- }
+ if (owner->pi_blocked_on)
+ chain_walk = 1;
spin_unlock_irqrestore(&owner->pi_lock, flags);
}
- if (!boost)
+ else if (debug_rt_mutex_detect_deadlock(waiter, detect_deadlock))
+ chain_walk = 1;
+
+ if (!chain_walk)
return 0;
+ /*
+ * The owner can't disappear while holding a lock,
+ * so the owner struct is protected by wait_lock.
+ * Gets dropped in rt_mutex_adjust_prio_chain()!
+ */
+ get_task_struct(owner);
+
spin_unlock(&lock->wait_lock);
res = rt_mutex_adjust_prio_chain(owner, detect_deadlock, lock, waiter,
@@ -532,7 +530,7 @@ static void remove_waiter(struct rt_mutex *lock,
int first = (waiter == rt_mutex_top_waiter(lock));
struct task_struct *owner = rt_mutex_owner(lock);
unsigned long flags;
- int boost = 0;
+ int chain_walk = 0;
spin_lock_irqsave(&current->pi_lock, flags);
plist_del(&waiter->list_entry, &lock->wait_list);
@@ -554,19 +552,20 @@ static void remove_waiter(struct rt_mutex *lock,
}
__rt_mutex_adjust_prio(owner);
- if (owner->pi_blocked_on) {
- boost = 1;
- /* gets dropped in rt_mutex_adjust_prio_chain()! */
- get_task_struct(owner);
- }
+ if (owner->pi_blocked_on)
+ chain_walk = 1;
+
spin_unlock_irqrestore(&owner->pi_lock, flags);
}
WARN_ON(!plist_node_empty(&waiter->pi_list_entry));
- if (!boost)
+ if (!chain_walk)
return;
+ /* gets dropped in rt_mutex_adjust_prio_chain()! */
+ get_task_struct(owner);
+
spin_unlock(&lock->wait_lock);
rt_mutex_adjust_prio_chain(owner, 0, lock, NULL, current);
@@ -592,10 +591,10 @@ void rt_mutex_adjust_pi(struct task_struct *task)
return;
}
- /* gets dropped in rt_mutex_adjust_prio_chain()! */
- get_task_struct(task);
spin_unlock_irqrestore(&task->pi_lock, flags);
+ /* gets dropped in rt_mutex_adjust_prio_chain()! */
+ get_task_struct(task);
rt_mutex_adjust_prio_chain(task, 0, NULL, NULL, task);
}
diff --git a/kernel/sched.c b/kernel/sched.c
index 5c848fd4e461..53608a59d6e3 100644
--- a/kernel/sched.c
+++ b/kernel/sched.c
@@ -49,7 +49,7 @@
#include <linux/seq_file.h>
#include <linux/syscalls.h>
#include <linux/times.h>
-#include <linux/acct.h>
+#include <linux/tsacct_kern.h>
#include <linux/kprobes.h>
#include <linux/delayacct.h>
#include <asm/tlb.h>
@@ -1232,7 +1232,7 @@ nextgroup:
}
/*
- * find_idlest_queue - find the idlest runqueue among the cpus in group.
+ * find_idlest_cpu - find the idlest cpu among the cpus in group.
*/
static int
find_idlest_cpu(struct sched_group *group, struct task_struct *p, int this_cpu)
@@ -1286,21 +1286,29 @@ static int sched_balance_self(int cpu, int flag)
while (sd) {
cpumask_t span;
struct sched_group *group;
- int new_cpu;
- int weight;
+ int new_cpu, weight;
+
+ if (!(sd->flags & flag)) {
+ sd = sd->child;
+ continue;
+ }
span = sd->span;
group = find_idlest_group(sd, t, cpu);
- if (!group)
- goto nextlevel;
+ if (!group) {
+ sd = sd->child;
+ continue;
+ }
new_cpu = find_idlest_cpu(group, t, cpu);
- if (new_cpu == -1 || new_cpu == cpu)
- goto nextlevel;
+ if (new_cpu == -1 || new_cpu == cpu) {
+ /* Now try balancing at a lower domain level of cpu */
+ sd = sd->child;
+ continue;
+ }
- /* Now try balancing at a lower domain level */
+ /* Now try balancing at a lower domain level of new_cpu */
cpu = new_cpu;
-nextlevel:
sd = NULL;
weight = cpus_weight(span);
for_each_domain(cpu, tmp) {
@@ -1755,27 +1763,27 @@ static inline void finish_task_switch(struct rq *rq, struct task_struct *prev)
__releases(rq->lock)
{
struct mm_struct *mm = rq->prev_mm;
- unsigned long prev_task_flags;
+ long prev_state;
rq->prev_mm = NULL;
/*
* A task struct has one reference for the use as "current".
- * If a task dies, then it sets EXIT_ZOMBIE in tsk->exit_state and
- * calls schedule one last time. The schedule call will never return,
- * and the scheduled task must drop that reference.
- * The test for EXIT_ZOMBIE must occur while the runqueue locks are
+ * If a task dies, then it sets TASK_DEAD in tsk->state and calls
+ * schedule one last time. The schedule call will never return, and
+ * the scheduled task must drop that reference.
+ * The test for TASK_DEAD must occur while the runqueue locks are
* still held, otherwise prev could be scheduled on another cpu, die
* there before we look at prev->state, and then the reference would
* be dropped twice.
* Manfred Spraul <manfred@colorfullife.com>
*/
- prev_task_flags = prev->flags;
+ prev_state = prev->state;
finish_arch_switch(prev);
finish_lock_switch(rq, prev);
if (mm)
mmdrop(mm);
- if (unlikely(prev_task_flags & PF_DEAD)) {
+ if (unlikely(prev_state == TASK_DEAD)) {
/*
* Remove function-return probe instances associated with this
* task and put them back on the free list.
@@ -2533,8 +2541,14 @@ static int load_balance(int this_cpu, struct rq *this_rq,
struct rq *busiest;
cpumask_t cpus = CPU_MASK_ALL;
+ /*
+ * When power savings policy is enabled for the parent domain, idle
+ * sibling can pick up load irrespective of busy siblings. In this case,
+ * let the state of idle sibling percolate up as IDLE, instead of
+ * portraying it as NOT_IDLE.
+ */
if (idle != NOT_IDLE && sd->flags & SD_SHARE_CPUPOWER &&
- !sched_smt_power_savings)
+ !test_sd_parent(sd, SD_POWERSAVINGS_BALANCE))
sd_idle = 1;
schedstat_inc(sd, lb_cnt[idle]);
@@ -2630,7 +2644,7 @@ redo:
}
if (!nr_moved && !sd_idle && sd->flags & SD_SHARE_CPUPOWER &&
- !sched_smt_power_savings)
+ !test_sd_parent(sd, SD_POWERSAVINGS_BALANCE))
return -1;
return nr_moved;
@@ -2646,7 +2660,7 @@ out_one_pinned:
sd->balance_interval *= 2;
if (!sd_idle && sd->flags & SD_SHARE_CPUPOWER &&
- !sched_smt_power_savings)
+ !test_sd_parent(sd, SD_POWERSAVINGS_BALANCE))
return -1;
return 0;
}
@@ -2668,7 +2682,14 @@ load_balance_newidle(int this_cpu, struct rq *this_rq, struct sched_domain *sd)
int sd_idle = 0;
cpumask_t cpus = CPU_MASK_ALL;
- if (sd->flags & SD_SHARE_CPUPOWER && !sched_smt_power_savings)
+ /*
+ * When power savings policy is enabled for the parent domain, idle
+ * sibling can pick up load irrespective of busy siblings. In this case,
+ * let the state of idle sibling percolate up as IDLE, instead of
+ * portraying it as NOT_IDLE.
+ */
+ if (sd->flags & SD_SHARE_CPUPOWER &&
+ !test_sd_parent(sd, SD_POWERSAVINGS_BALANCE))
sd_idle = 1;
schedstat_inc(sd, lb_cnt[NEWLY_IDLE]);
@@ -2709,7 +2730,8 @@ redo:
if (!nr_moved) {
schedstat_inc(sd, lb_failed[NEWLY_IDLE]);
- if (!sd_idle && sd->flags & SD_SHARE_CPUPOWER)
+ if (!sd_idle && sd->flags & SD_SHARE_CPUPOWER &&
+ !test_sd_parent(sd, SD_POWERSAVINGS_BALANCE))
return -1;
} else
sd->nr_balance_failed = 0;
@@ -2719,7 +2741,7 @@ redo:
out_balanced:
schedstat_inc(sd, lb_balanced[NEWLY_IDLE]);
if (!sd_idle && sd->flags & SD_SHARE_CPUPOWER &&
- !sched_smt_power_savings)
+ !test_sd_parent(sd, SD_POWERSAVINGS_BALANCE))
return -1;
sd->nr_balance_failed = 0;
@@ -3348,9 +3370,6 @@ need_resched_nonpreemptible:
spin_lock_irq(&rq->lock);
- if (unlikely(prev->flags & PF_DEAD))
- prev->state = EXIT_DEAD;
-
switch_count = &prev->nivcsw;
if (prev->state && !(preempt_count() & PREEMPT_ACTIVE)) {
switch_count = &prev->nvcsw;
@@ -4080,6 +4099,8 @@ static void __setscheduler(struct task_struct *p, int policy, int prio)
* @p: the task in question.
* @policy: new policy.
* @param: structure containing the new RT priority.
+ *
+ * NOTE: the task may be already dead
*/
int sched_setscheduler(struct task_struct *p, int policy,
struct sched_param *param)
@@ -4107,28 +4128,32 @@ recheck:
(p->mm && param->sched_priority > MAX_USER_RT_PRIO-1) ||
(!p->mm && param->sched_priority > MAX_RT_PRIO-1))
return -EINVAL;
- if ((policy == SCHED_NORMAL || policy == SCHED_BATCH)
- != (param->sched_priority == 0))
+ if (is_rt_policy(policy) != (param->sched_priority != 0))
return -EINVAL;
/*
* Allow unprivileged RT tasks to decrease priority:
*/
if (!capable(CAP_SYS_NICE)) {
- /*
- * can't change policy, except between SCHED_NORMAL
- * and SCHED_BATCH:
- */
- if (((policy != SCHED_NORMAL && p->policy != SCHED_BATCH) &&
- (policy != SCHED_BATCH && p->policy != SCHED_NORMAL)) &&
- !p->signal->rlim[RLIMIT_RTPRIO].rlim_cur)
- return -EPERM;
- /* can't increase priority */
- if ((policy != SCHED_NORMAL && policy != SCHED_BATCH) &&
- param->sched_priority > p->rt_priority &&
- param->sched_priority >
- p->signal->rlim[RLIMIT_RTPRIO].rlim_cur)
- return -EPERM;
+ if (is_rt_policy(policy)) {
+ unsigned long rlim_rtprio;
+ unsigned long flags;
+
+ if (!lock_task_sighand(p, &flags))
+ return -ESRCH;
+ rlim_rtprio = p->signal->rlim[RLIMIT_RTPRIO].rlim_cur;
+ unlock_task_sighand(p, &flags);
+
+ /* can't set/change the rt policy */
+ if (policy != p->policy && !rlim_rtprio)
+ return -EPERM;
+
+ /* can't increase priority */
+ if (param->sched_priority > p->rt_priority &&
+ param->sched_priority > rlim_rtprio)
+ return -EPERM;
+ }
+
/* can't change other user's priorities */
if ((current->euid != p->euid) &&
(current->euid != p->uid))
@@ -4193,14 +4218,13 @@ do_sched_setscheduler(pid_t pid, int policy, struct sched_param __user *param)
return -EINVAL;
if (copy_from_user(&lparam, param, sizeof(struct sched_param)))
return -EFAULT;
- read_lock_irq(&tasklist_lock);
+
+ rcu_read_lock();
+ retval = -ESRCH;
p = find_process_by_pid(pid);
- if (!p) {
- read_unlock_irq(&tasklist_lock);
- return -ESRCH;
- }
- retval = sched_setscheduler(p, policy, &lparam);
- read_unlock_irq(&tasklist_lock);
+ if (p != NULL)
+ retval = sched_setscheduler(p, policy, &lparam);
+ rcu_read_unlock();
return retval;
}
@@ -4382,7 +4406,10 @@ EXPORT_SYMBOL(cpu_present_map);
#ifndef CONFIG_SMP
cpumask_t cpu_online_map __read_mostly = CPU_MASK_ALL;
+EXPORT_SYMBOL(cpu_online_map);
+
cpumask_t cpu_possible_map __read_mostly = CPU_MASK_ALL;
+EXPORT_SYMBOL(cpu_possible_map);
#endif
long sched_getaffinity(pid_t pid, cpumask_t *mask)
@@ -4812,7 +4839,7 @@ void show_state(void)
* NOTE: this function does not set the idle thread's NEED_RESCHED
* flag, to make booting more robust.
*/
-void __devinit init_idle(struct task_struct *idle, int cpu)
+void __cpuinit init_idle(struct task_struct *idle, int cpu)
{
struct rq *rq = cpu_rq(cpu);
unsigned long flags;
@@ -5151,7 +5178,7 @@ static void migrate_dead(unsigned int dead_cpu, struct task_struct *p)
BUG_ON(p->exit_state != EXIT_ZOMBIE && p->exit_state != EXIT_DEAD);
/* Cannot have done final schedule yet: would have vanished. */
- BUG_ON(p->flags & PF_DEAD);
+ BUG_ON(p->state == TASK_DEAD);
get_task_struct(p);
@@ -5272,9 +5299,11 @@ static struct notifier_block __cpuinitdata migration_notifier = {
int __init migration_init(void)
{
void *cpu = (void *)(long)smp_processor_id();
+ int err;
/* Start one for the boot CPU: */
- migration_call(&migration_notifier, CPU_UP_PREPARE, cpu);
+ err = migration_call(&migration_notifier, CPU_UP_PREPARE, cpu);
+ BUG_ON(err == NOTIFY_BAD);
migration_call(&migration_notifier, CPU_ONLINE, cpu);
register_cpu_notifier(&migration_notifier);
@@ -5385,7 +5414,9 @@ static int sd_degenerate(struct sched_domain *sd)
if (sd->flags & (SD_LOAD_BALANCE |
SD_BALANCE_NEWIDLE |
SD_BALANCE_FORK |
- SD_BALANCE_EXEC)) {
+ SD_BALANCE_EXEC |
+ SD_SHARE_CPUPOWER |
+ SD_SHARE_PKG_RESOURCES)) {
if (sd->groups != sd->groups->next)
return 0;
}
@@ -5419,7 +5450,9 @@ sd_parent_degenerate(struct sched_domain *sd, struct sched_domain *parent)
pflags &= ~(SD_LOAD_BALANCE |
SD_BALANCE_NEWIDLE |
SD_BALANCE_FORK |
- SD_BALANCE_EXEC);
+ SD_BALANCE_EXEC |
+ SD_SHARE_CPUPOWER |
+ SD_SHARE_PKG_RESOURCES);
}
if (~cflags & pflags)
return 0;
@@ -5441,12 +5474,18 @@ static void cpu_attach_domain(struct sched_domain *sd, int cpu)
struct sched_domain *parent = tmp->parent;
if (!parent)
break;
- if (sd_parent_degenerate(tmp, parent))
+ if (sd_parent_degenerate(tmp, parent)) {
tmp->parent = parent->parent;
+ if (parent->parent)
+ parent->parent->child = tmp;
+ }
}
- if (sd && sd_degenerate(sd))
+ if (sd && sd_degenerate(sd)) {
sd = sd->parent;
+ if (sd)
+ sd->child = NULL;
+ }
sched_domain_debug(sd, cpu);
@@ -5454,7 +5493,7 @@ static void cpu_attach_domain(struct sched_domain *sd, int cpu)
}
/* cpus with isolated domains */
-static cpumask_t __devinitdata cpu_isolated_map = CPU_MASK_NONE;
+static cpumask_t __cpuinitdata cpu_isolated_map = CPU_MASK_NONE;
/* Setup the mask of cpus configured for isolated domains */
static int __init isolated_cpu_setup(char *str)
@@ -5482,15 +5521,17 @@ __setup ("isolcpus=", isolated_cpu_setup);
* covered by the given span, and will set each group's ->cpumask correctly,
* and ->cpu_power to 0.
*/
-static void init_sched_build_groups(struct sched_group groups[], cpumask_t span,
- int (*group_fn)(int cpu))
+static void
+init_sched_build_groups(struct sched_group groups[], cpumask_t span,
+ const cpumask_t *cpu_map,
+ int (*group_fn)(int cpu, const cpumask_t *cpu_map))
{
struct sched_group *first = NULL, *last = NULL;
cpumask_t covered = CPU_MASK_NONE;
int i;
for_each_cpu_mask(i, span) {
- int group = group_fn(i);
+ int group = group_fn(i, cpu_map);
struct sched_group *sg = &groups[group];
int j;
@@ -5501,7 +5542,7 @@ static void init_sched_build_groups(struct sched_group groups[], cpumask_t span,
sg->cpu_power = 0;
for_each_cpu_mask(j, span) {
- if (group_fn(j) != group)
+ if (group_fn(j, cpu_map) != group)
continue;
cpu_set(j, covered);
@@ -5968,13 +6009,15 @@ static void calibrate_migration_costs(const cpumask_t *cpu_map)
#endif
);
if (system_state == SYSTEM_BOOTING) {
- printk("migration_cost=");
- for (distance = 0; distance <= max_distance; distance++) {
- if (distance)
- printk(",");
- printk("%ld", (long)migration_cost[distance] / 1000);
+ if (num_online_cpus() > 1) {
+ printk("migration_cost=");
+ for (distance = 0; distance <= max_distance; distance++) {
+ if (distance)
+ printk(",");
+ printk("%ld", (long)migration_cost[distance] / 1000);
+ }
+ printk("\n");
}
- printk("\n");
}
j1 = jiffies;
if (migration_debug)
@@ -6077,7 +6120,7 @@ int sched_smt_power_savings = 0, sched_mc_power_savings = 0;
static DEFINE_PER_CPU(struct sched_domain, cpu_domains);
static struct sched_group sched_group_cpus[NR_CPUS];
-static int cpu_to_cpu_group(int cpu)
+static int cpu_to_cpu_group(int cpu, const cpumask_t *cpu_map)
{
return cpu;
}
@@ -6088,31 +6131,36 @@ static int cpu_to_cpu_group(int cpu)
*/
#ifdef CONFIG_SCHED_MC
static DEFINE_PER_CPU(struct sched_domain, core_domains);
-static struct sched_group *sched_group_core_bycpu[NR_CPUS];
+static struct sched_group sched_group_core[NR_CPUS];
#endif
#if defined(CONFIG_SCHED_MC) && defined(CONFIG_SCHED_SMT)
-static int cpu_to_core_group(int cpu)
+static int cpu_to_core_group(int cpu, const cpumask_t *cpu_map)
{
- return first_cpu(cpu_sibling_map[cpu]);
+ cpumask_t mask = cpu_sibling_map[cpu];
+ cpus_and(mask, mask, *cpu_map);
+ return first_cpu(mask);
}
#elif defined(CONFIG_SCHED_MC)
-static int cpu_to_core_group(int cpu)
+static int cpu_to_core_group(int cpu, const cpumask_t *cpu_map)
{
return cpu;
}
#endif
static DEFINE_PER_CPU(struct sched_domain, phys_domains);
-static struct sched_group *sched_group_phys_bycpu[NR_CPUS];
+static struct sched_group sched_group_phys[NR_CPUS];
-static int cpu_to_phys_group(int cpu)
+static int cpu_to_phys_group(int cpu, const cpumask_t *cpu_map)
{
#ifdef CONFIG_SCHED_MC
cpumask_t mask = cpu_coregroup_map(cpu);
+ cpus_and(mask, mask, *cpu_map);
return first_cpu(mask);
#elif defined(CONFIG_SCHED_SMT)
- return first_cpu(cpu_sibling_map[cpu]);
+ cpumask_t mask = cpu_sibling_map[cpu];
+ cpus_and(mask, mask, *cpu_map);
+ return first_cpu(mask);
#else
return cpu;
#endif
@@ -6130,7 +6178,7 @@ static struct sched_group **sched_group_nodes_bycpu[NR_CPUS];
static DEFINE_PER_CPU(struct sched_domain, allnodes_domains);
static struct sched_group *sched_group_allnodes_bycpu[NR_CPUS];
-static int cpu_to_allnodes_group(int cpu)
+static int cpu_to_allnodes_group(int cpu, const cpumask_t *cpu_map)
{
return cpu_to_node(cpu);
}
@@ -6162,12 +6210,11 @@ next_sg:
}
#endif
+#ifdef CONFIG_NUMA
/* Free memory allocated for various sched_group structures */
static void free_sched_groups(const cpumask_t *cpu_map)
{
- int cpu;
-#ifdef CONFIG_NUMA
- int i;
+ int cpu, i;
for_each_cpu_mask(cpu, *cpu_map) {
struct sched_group *sched_group_allnodes
@@ -6204,19 +6251,63 @@ next_sg:
kfree(sched_group_nodes);
sched_group_nodes_bycpu[cpu] = NULL;
}
+}
+#else
+static void free_sched_groups(const cpumask_t *cpu_map)
+{
+}
#endif
- for_each_cpu_mask(cpu, *cpu_map) {
- if (sched_group_phys_bycpu[cpu]) {
- kfree(sched_group_phys_bycpu[cpu]);
- sched_group_phys_bycpu[cpu] = NULL;
- }
-#ifdef CONFIG_SCHED_MC
- if (sched_group_core_bycpu[cpu]) {
- kfree(sched_group_core_bycpu[cpu]);
- sched_group_core_bycpu[cpu] = NULL;
- }
-#endif
+
+/*
+ * Initialize sched groups cpu_power.
+ *
+ * cpu_power indicates the capacity of sched group, which is used while
+ * distributing the load between different sched groups in a sched domain.
+ * Typically cpu_power for all the groups in a sched domain will be same unless
+ * there are asymmetries in the topology. If there are asymmetries, group
+ * having more cpu_power will pickup more load compared to the group having
+ * less cpu_power.
+ *
+ * cpu_power will be a multiple of SCHED_LOAD_SCALE. This multiple represents
+ * the maximum number of tasks a group can handle in the presence of other idle
+ * or lightly loaded groups in the same sched domain.
+ */
+static void init_sched_groups_power(int cpu, struct sched_domain *sd)
+{
+ struct sched_domain *child;
+ struct sched_group *group;
+
+ WARN_ON(!sd || !sd->groups);
+
+ if (cpu != first_cpu(sd->groups->cpumask))
+ return;
+
+ child = sd->child;
+
+ /*
+ * For perf policy, if the groups in child domain share resources
+ * (for example cores sharing some portions of the cache hierarchy
+ * or SMT), then set this domain groups cpu_power such that each group
+ * can handle only one task, when there are other idle groups in the
+ * same sched domain.
+ */
+ if (!child || (!(sd->flags & SD_POWERSAVINGS_BALANCE) &&
+ (child->flags &
+ (SD_SHARE_CPUPOWER | SD_SHARE_PKG_RESOURCES)))) {
+ sd->groups->cpu_power = SCHED_LOAD_SCALE;
+ return;
}
+
+ sd->groups->cpu_power = 0;
+
+ /*
+ * add cpu_power of each child group to this groups cpu_power
+ */
+ group = child->groups;
+ do {
+ sd->groups->cpu_power += group->cpu_power;
+ group = group->next;
+ } while (group != child->groups);
}
/*
@@ -6226,10 +6317,7 @@ next_sg:
static int build_sched_domains(const cpumask_t *cpu_map)
{
int i;
- struct sched_group *sched_group_phys = NULL;
-#ifdef CONFIG_SCHED_MC
- struct sched_group *sched_group_core = NULL;
-#endif
+ struct sched_domain *sd;
#ifdef CONFIG_NUMA
struct sched_group **sched_group_nodes = NULL;
struct sched_group *sched_group_allnodes = NULL;
@@ -6261,9 +6349,10 @@ static int build_sched_domains(const cpumask_t *cpu_map)
> SD_NODES_PER_DOMAIN*cpus_weight(nodemask)) {
if (!sched_group_allnodes) {
sched_group_allnodes
- = kmalloc(sizeof(struct sched_group)
- * MAX_NUMNODES,
- GFP_KERNEL);
+ = kmalloc_node(sizeof(struct sched_group)
+ * MAX_NUMNODES,
+ GFP_KERNEL,
+ cpu_to_node(i));
if (!sched_group_allnodes) {
printk(KERN_WARNING
"Can not alloc allnodes sched group\n");
@@ -6275,7 +6364,7 @@ static int build_sched_domains(const cpumask_t *cpu_map)
sd = &per_cpu(allnodes_domains, i);
*sd = SD_ALLNODES_INIT;
sd->span = *cpu_map;
- group = cpu_to_allnodes_group(i);
+ group = cpu_to_allnodes_group(i, cpu_map);
sd->groups = &sched_group_allnodes[group];
p = sd;
} else
@@ -6285,60 +6374,42 @@ static int build_sched_domains(const cpumask_t *cpu_map)
*sd = SD_NODE_INIT;
sd->span = sched_domain_node_span(cpu_to_node(i));
sd->parent = p;
+ if (p)
+ p->child = sd;
cpus_and(sd->span, sd->span, *cpu_map);
#endif
- if (!sched_group_phys) {
- sched_group_phys
- = kmalloc(sizeof(struct sched_group) * NR_CPUS,
- GFP_KERNEL);
- if (!sched_group_phys) {
- printk (KERN_WARNING "Can not alloc phys sched"
- "group\n");
- goto error;
- }
- sched_group_phys_bycpu[i] = sched_group_phys;
- }
-
p = sd;
sd = &per_cpu(phys_domains, i);
- group = cpu_to_phys_group(i);
+ group = cpu_to_phys_group(i, cpu_map);
*sd = SD_CPU_INIT;
sd->span = nodemask;
sd->parent = p;
+ if (p)
+ p->child = sd;
sd->groups = &sched_group_phys[group];
#ifdef CONFIG_SCHED_MC
- if (!sched_group_core) {
- sched_group_core
- = kmalloc(sizeof(struct sched_group) * NR_CPUS,
- GFP_KERNEL);
- if (!sched_group_core) {
- printk (KERN_WARNING "Can not alloc core sched"
- "group\n");
- goto error;
- }
- sched_group_core_bycpu[i] = sched_group_core;
- }
-
p = sd;
sd = &per_cpu(core_domains, i);
- group = cpu_to_core_group(i);
+ group = cpu_to_core_group(i, cpu_map);
*sd = SD_MC_INIT;
sd->span = cpu_coregroup_map(i);
cpus_and(sd->span, sd->span, *cpu_map);
sd->parent = p;
+ p->child = sd;
sd->groups = &sched_group_core[group];
#endif
#ifdef CONFIG_SCHED_SMT
p = sd;
sd = &per_cpu(cpu_domains, i);
- group = cpu_to_cpu_group(i);
+ group = cpu_to_cpu_group(i, cpu_map);
*sd = SD_SIBLING_INIT;
sd->span = cpu_sibling_map[i];
cpus_and(sd->span, sd->span, *cpu_map);
sd->parent = p;
+ p->child = sd;
sd->groups = &sched_group_cpus[group];
#endif
}
@@ -6352,7 +6423,7 @@ static int build_sched_domains(const cpumask_t *cpu_map)
continue;
init_sched_build_groups(sched_group_cpus, this_sibling_map,
- &cpu_to_cpu_group);
+ cpu_map, &cpu_to_cpu_group);
}
#endif
@@ -6364,7 +6435,7 @@ static int build_sched_domains(const cpumask_t *cpu_map)
if (i != first_cpu(this_core_map))
continue;
init_sched_build_groups(sched_group_core, this_core_map,
- &cpu_to_core_group);
+ cpu_map, &cpu_to_core_group);
}
#endif
@@ -6378,14 +6449,14 @@ static int build_sched_domains(const cpumask_t *cpu_map)
continue;
init_sched_build_groups(sched_group_phys, nodemask,
- &cpu_to_phys_group);
+ cpu_map, &cpu_to_phys_group);
}
#ifdef CONFIG_NUMA
/* Set up node groups */
if (sched_group_allnodes)
init_sched_build_groups(sched_group_allnodes, *cpu_map,
- &cpu_to_allnodes_group);
+ cpu_map, &cpu_to_allnodes_group);
for (i = 0; i < MAX_NUMNODES; i++) {
/* Set up node groups */
@@ -6457,72 +6528,20 @@ static int build_sched_domains(const cpumask_t *cpu_map)
/* Calculate CPU power for physical packages and nodes */
#ifdef CONFIG_SCHED_SMT
for_each_cpu_mask(i, *cpu_map) {
- struct sched_domain *sd;
sd = &per_cpu(cpu_domains, i);
- sd->groups->cpu_power = SCHED_LOAD_SCALE;
+ init_sched_groups_power(i, sd);
}
#endif
#ifdef CONFIG_SCHED_MC
for_each_cpu_mask(i, *cpu_map) {
- int power;
- struct sched_domain *sd;
sd = &per_cpu(core_domains, i);
- if (sched_smt_power_savings)
- power = SCHED_LOAD_SCALE * cpus_weight(sd->groups->cpumask);
- else
- power = SCHED_LOAD_SCALE + (cpus_weight(sd->groups->cpumask)-1)
- * SCHED_LOAD_SCALE / 10;
- sd->groups->cpu_power = power;
+ init_sched_groups_power(i, sd);
}
#endif
for_each_cpu_mask(i, *cpu_map) {
- struct sched_domain *sd;
-#ifdef CONFIG_SCHED_MC
- sd = &per_cpu(phys_domains, i);
- if (i != first_cpu(sd->groups->cpumask))
- continue;
-
- sd->groups->cpu_power = 0;
- if (sched_mc_power_savings || sched_smt_power_savings) {
- int j;
-
- for_each_cpu_mask(j, sd->groups->cpumask) {
- struct sched_domain *sd1;
- sd1 = &per_cpu(core_domains, j);
- /*
- * for each core we will add once
- * to the group in physical domain
- */
- if (j != first_cpu(sd1->groups->cpumask))
- continue;
-
- if (sched_smt_power_savings)
- sd->groups->cpu_power += sd1->groups->cpu_power;
- else
- sd->groups->cpu_power += SCHED_LOAD_SCALE;
- }
- } else
- /*
- * This has to be < 2 * SCHED_LOAD_SCALE
- * Lets keep it SCHED_LOAD_SCALE, so that
- * while calculating NUMA group's cpu_power
- * we can simply do
- * numa_group->cpu_power += phys_group->cpu_power;
- *
- * See "only add power once for each physical pkg"
- * comment below
- */
- sd->groups->cpu_power = SCHED_LOAD_SCALE;
-#else
- int power;
sd = &per_cpu(phys_domains, i);
- if (sched_smt_power_savings)
- power = SCHED_LOAD_SCALE * cpus_weight(sd->groups->cpumask);
- else
- power = SCHED_LOAD_SCALE;
- sd->groups->cpu_power = power;
-#endif
+ init_sched_groups_power(i, sd);
}
#ifdef CONFIG_NUMA
@@ -6530,7 +6549,7 @@ static int build_sched_domains(const cpumask_t *cpu_map)
init_numa_sched_groups_power(sched_group_nodes[i]);
if (sched_group_allnodes) {
- int group = cpu_to_allnodes_group(first_cpu(*cpu_map));
+ int group = cpu_to_allnodes_group(first_cpu(*cpu_map), cpu_map);
struct sched_group *sg = &sched_group_allnodes[group];
init_numa_sched_groups_power(sg);
@@ -6556,9 +6575,11 @@ static int build_sched_domains(const cpumask_t *cpu_map)
return 0;
+#ifdef CONFIG_NUMA
error:
free_sched_groups(cpu_map);
return -ENOMEM;
+#endif
}
/*
* Set up scheduler domains and groups. Callers must hold the hotplug lock.
@@ -6740,11 +6761,20 @@ static int update_sched_domains(struct notifier_block *nfb,
void __init sched_init_smp(void)
{
+ cpumask_t non_isolated_cpus;
+
lock_cpu_hotplug();
arch_init_sched_domains(&cpu_online_map);
+ cpus_andnot(non_isolated_cpus, cpu_online_map, cpu_isolated_map);
+ if (cpus_empty(non_isolated_cpus))
+ cpu_set(smp_processor_id(), non_isolated_cpus);
unlock_cpu_hotplug();
/* XXX: Theoretical race here - CPU may be hotplugged now */
hotcpu_notifier(update_sched_domains, 0);
+
+ /* Move init over to a non-isolated CPU */
+ if (set_cpus_allowed(current, non_isolated_cpus) < 0)
+ BUG();
}
#else
void __init sched_init_smp(void)
diff --git a/kernel/signal.c b/kernel/signal.c
index 05853a7337e3..7ed8d5304bec 100644
--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -417,9 +417,8 @@ static int collect_signal(int sig, struct sigpending *list, siginfo_t *info)
static int __dequeue_signal(struct sigpending *pending, sigset_t *mask,
siginfo_t *info)
{
- int sig = 0;
+ int sig = next_signal(pending, mask);
- sig = next_signal(pending, mask);
if (sig) {
if (current->notifier) {
if (sigismember(current->notifier_mask, sig)) {
@@ -432,9 +431,7 @@ static int __dequeue_signal(struct sigpending *pending, sigset_t *mask,
if (!collect_signal(sig, pending, info))
sig = 0;
-
}
- recalc_sigpending();
return sig;
}
@@ -451,6 +448,7 @@ int dequeue_signal(struct task_struct *tsk, sigset_t *mask, siginfo_t *info)
if (!signr)
signr = __dequeue_signal(&tsk->signal->shared_pending,
mask, info);
+ recalc_sigpending_tsk(tsk);
if (signr && unlikely(sig_kernel_stop(signr))) {
/*
* Set a marker that we have dequeued a stop signal. Our
@@ -1057,28 +1055,44 @@ int group_send_sig_info(int sig, struct siginfo *info, struct task_struct *p)
}
/*
- * kill_pg_info() sends a signal to a process group: this is what the tty
+ * kill_pgrp_info() sends a signal to a process group: this is what the tty
* control characters do (^C, ^Z etc)
*/
-int __kill_pg_info(int sig, struct siginfo *info, pid_t pgrp)
+int __kill_pgrp_info(int sig, struct siginfo *info, struct pid *pgrp)
{
struct task_struct *p = NULL;
int retval, success;
- if (pgrp <= 0)
- return -EINVAL;
-
success = 0;
retval = -ESRCH;
- do_each_task_pid(pgrp, PIDTYPE_PGID, p) {
+ do_each_pid_task(pgrp, PIDTYPE_PGID, p) {
int err = group_send_sig_info(sig, info, p);
success |= !err;
retval = err;
- } while_each_task_pid(pgrp, PIDTYPE_PGID, p);
+ } while_each_pid_task(pgrp, PIDTYPE_PGID, p);
return success ? 0 : retval;
}
+int kill_pgrp_info(int sig, struct siginfo *info, struct pid *pgrp)
+{
+ int retval;
+
+ read_lock(&tasklist_lock);
+ retval = __kill_pgrp_info(sig, info, pgrp);
+ read_unlock(&tasklist_lock);
+
+ return retval;
+}
+
+int __kill_pg_info(int sig, struct siginfo *info, pid_t pgrp)
+{
+ if (pgrp <= 0)
+ return -EINVAL;
+
+ return __kill_pgrp_info(sig, info, find_pid(pgrp));
+}
+
int
kill_pg_info(int sig, struct siginfo *info, pid_t pgrp)
{
@@ -1091,8 +1105,7 @@ kill_pg_info(int sig, struct siginfo *info, pid_t pgrp)
return retval;
}
-int
-kill_proc_info(int sig, struct siginfo *info, pid_t pid)
+int kill_pid_info(int sig, struct siginfo *info, struct pid *pid)
{
int error;
int acquired_tasklist_lock = 0;
@@ -1103,7 +1116,7 @@ kill_proc_info(int sig, struct siginfo *info, pid_t pid)
read_lock(&tasklist_lock);
acquired_tasklist_lock = 1;
}
- p = find_task_by_pid(pid);
+ p = pid_task(pid, PIDTYPE_PID);
error = -ESRCH;
if (p)
error = group_send_sig_info(sig, info, p);
@@ -1113,8 +1126,18 @@ kill_proc_info(int sig, struct siginfo *info, pid_t pid)
return error;
}
-/* like kill_proc_info(), but doesn't use uid/euid of "current" */
-int kill_proc_info_as_uid(int sig, struct siginfo *info, pid_t pid,
+int
+kill_proc_info(int sig, struct siginfo *info, pid_t pid)
+{
+ int error;
+ rcu_read_lock();
+ error = kill_pid_info(sig, info, find_pid(pid));
+ rcu_read_unlock();
+ return error;
+}
+
+/* like kill_pid_info(), but doesn't use uid/euid of "current" */
+int kill_pid_info_as_uid(int sig, struct siginfo *info, struct pid *pid,
uid_t uid, uid_t euid, u32 secid)
{
int ret = -EINVAL;
@@ -1124,7 +1147,7 @@ int kill_proc_info_as_uid(int sig, struct siginfo *info, pid_t pid,
return ret;
read_lock(&tasklist_lock);
- p = find_task_by_pid(pid);
+ p = pid_task(pid, PIDTYPE_PID);
if (!p) {
ret = -ESRCH;
goto out_unlock;
@@ -1148,7 +1171,7 @@ out_unlock:
read_unlock(&tasklist_lock);
return ret;
}
-EXPORT_SYMBOL_GPL(kill_proc_info_as_uid);
+EXPORT_SYMBOL_GPL(kill_pid_info_as_uid);
/*
* kill_something_info() interprets pid in interesting ways just like kill(2).
@@ -1266,6 +1289,18 @@ force_sigsegv(int sig, struct task_struct *p)
return 0;
}
+int kill_pgrp(struct pid *pid, int sig, int priv)
+{
+ return kill_pgrp_info(sig, __si_special(priv), pid);
+}
+EXPORT_SYMBOL(kill_pgrp);
+
+int kill_pid(struct pid *pid, int sig, int priv)
+{
+ return kill_pid_info(sig, __si_special(priv), pid);
+}
+EXPORT_SYMBOL(kill_pid);
+
int
kill_pg(pid_t pgrp, int sig, int priv)
{
diff --git a/kernel/softirq.c b/kernel/softirq.c
index 3789ca98197c..bf25015dce16 100644
--- a/kernel/softirq.c
+++ b/kernel/softirq.c
@@ -612,7 +612,9 @@ static struct notifier_block __cpuinitdata cpu_nfb = {
__init int spawn_ksoftirqd(void)
{
void *cpu = (void *)(long)smp_processor_id();
- cpu_callback(&cpu_nfb, CPU_UP_PREPARE, cpu);
+ int err = cpu_callback(&cpu_nfb, CPU_UP_PREPARE, cpu);
+
+ BUG_ON(err == NOTIFY_BAD);
cpu_callback(&cpu_nfb, CPU_ONLINE, cpu);
register_cpu_notifier(&cpu_nfb);
return 0;
diff --git a/kernel/softlockup.c b/kernel/softlockup.c
index 03e6a2b0b787..50afeb813305 100644
--- a/kernel/softlockup.c
+++ b/kernel/softlockup.c
@@ -149,8 +149,9 @@ static struct notifier_block __cpuinitdata cpu_nfb = {
__init void spawn_softlockup_task(void)
{
void *cpu = (void *)(long)smp_processor_id();
+ int err = cpu_callback(&cpu_nfb, CPU_UP_PREPARE, cpu);
- cpu_callback(&cpu_nfb, CPU_UP_PREPARE, cpu);
+ BUG_ON(err == NOTIFY_BAD);
cpu_callback(&cpu_nfb, CPU_ONLINE, cpu);
register_cpu_notifier(&cpu_nfb);
diff --git a/kernel/spinlock.c b/kernel/spinlock.c
index 9644a41e0bef..476c3741511b 100644
--- a/kernel/spinlock.c
+++ b/kernel/spinlock.c
@@ -21,17 +21,6 @@
#include <linux/debug_locks.h>
#include <linux/module.h>
-/*
- * Generic declaration of the raw read_trylock() function,
- * architectures are supposed to optimize this:
- */
-int __lockfunc generic__raw_read_trylock(raw_rwlock_t *lock)
-{
- __raw_read_lock(lock);
- return 1;
-}
-EXPORT_SYMBOL(generic__raw_read_trylock);
-
int __lockfunc _spin_trylock(spinlock_t *lock)
{
preempt_disable();
@@ -226,7 +215,7 @@ void __lockfunc _##op##_lock(locktype##_t *lock) \
if (!(lock)->break_lock) \
(lock)->break_lock = 1; \
while (!op##_can_lock(lock) && (lock)->break_lock) \
- cpu_relax(); \
+ _raw_##op##_relax(&lock->raw_lock); \
} \
(lock)->break_lock = 0; \
} \
@@ -248,7 +237,7 @@ unsigned long __lockfunc _##op##_lock_irqsave(locktype##_t *lock) \
if (!(lock)->break_lock) \
(lock)->break_lock = 1; \
while (!op##_can_lock(lock) && (lock)->break_lock) \
- cpu_relax(); \
+ _raw_##op##_relax(&lock->raw_lock); \
} \
(lock)->break_lock = 0; \
return flags; \
diff --git a/kernel/stop_machine.c b/kernel/stop_machine.c
index 51cacd111dbd..12458040e665 100644
--- a/kernel/stop_machine.c
+++ b/kernel/stop_machine.c
@@ -1,3 +1,6 @@
+/* Copyright 2005 Rusty Russell rusty@rustcorp.com.au IBM Corporation.
+ * GPL v2 and any later version.
+ */
#include <linux/stop_machine.h>
#include <linux/kthread.h>
#include <linux/sched.h>
diff --git a/kernel/sys.c b/kernel/sys.c
index 3f894775488d..2314867ae34f 100644
--- a/kernel/sys.c
+++ b/kernel/sys.c
@@ -92,7 +92,8 @@ EXPORT_SYMBOL(fs_overflowgid);
*/
int C_A_D = 1;
-int cad_pid = 1;
+struct pid *cad_pid;
+EXPORT_SYMBOL(cad_pid);
/*
* Notifier list for kernel code which wants to be called
@@ -221,7 +222,7 @@ EXPORT_SYMBOL_GPL(atomic_notifier_chain_unregister);
* of the last notifier function called.
*/
-int atomic_notifier_call_chain(struct atomic_notifier_head *nh,
+int __kprobes atomic_notifier_call_chain(struct atomic_notifier_head *nh,
unsigned long val, void *v)
{
int ret;
@@ -607,12 +608,10 @@ static void kernel_restart_prepare(char *cmd)
void kernel_restart(char *cmd)
{
kernel_restart_prepare(cmd);
- if (!cmd) {
+ if (!cmd)
printk(KERN_EMERG "Restarting system.\n");
- } else {
+ else
printk(KERN_EMERG "Restarting system with command '%s'.\n", cmd);
- }
- printk(".\n");
machine_restart(cmd);
}
EXPORT_SYMBOL_GPL(kernel_restart);
@@ -628,9 +627,8 @@ static void kernel_kexec(void)
#ifdef CONFIG_KEXEC
struct kimage *image;
image = xchg(&kexec_image, NULL);
- if (!image) {
+ if (!image)
return;
- }
kernel_restart_prepare(NULL);
printk(KERN_EMERG "Starting new kernel\n");
machine_shutdown();
@@ -776,10 +774,9 @@ void ctrl_alt_del(void)
if (C_A_D)
schedule_work(&cad_work);
else
- kill_proc(cad_pid, SIGINT, 1);
+ kill_cad_pid(SIGINT, 1);
}
-
/*
* Unprivileged users may change the real gid to the effective gid
* or vice versa. (BSD-style)
@@ -824,12 +821,10 @@ asmlinkage long sys_setregid(gid_t rgid, gid_t egid)
(current->sgid == egid) ||
capable(CAP_SETGID))
new_egid = egid;
- else {
+ else
return -EPERM;
- }
}
- if (new_egid != old_egid)
- {
+ if (new_egid != old_egid) {
current->mm->dumpable = suid_dumpable;
smp_wmb();
}
@@ -858,19 +853,14 @@ asmlinkage long sys_setgid(gid_t gid)
if (retval)
return retval;
- if (capable(CAP_SETGID))
- {
- if(old_egid != gid)
- {
+ if (capable(CAP_SETGID)) {
+ if (old_egid != gid) {
current->mm->dumpable = suid_dumpable;
smp_wmb();
}
current->gid = current->egid = current->sgid = current->fsgid = gid;
- }
- else if ((gid == current->gid) || (gid == current->sgid))
- {
- if(old_egid != gid)
- {
+ } else if ((gid == current->gid) || (gid == current->sgid)) {
+ if (old_egid != gid) {
current->mm->dumpable = suid_dumpable;
smp_wmb();
}
@@ -901,8 +891,7 @@ static int set_user(uid_t new_ruid, int dumpclear)
switch_uid(new_user);
- if(dumpclear)
- {
+ if (dumpclear) {
current->mm->dumpable = suid_dumpable;
smp_wmb();
}
@@ -958,8 +947,7 @@ asmlinkage long sys_setreuid(uid_t ruid, uid_t euid)
if (new_ruid != old_ruid && set_user(new_ruid, new_euid != old_euid) < 0)
return -EAGAIN;
- if (new_euid != old_euid)
- {
+ if (new_euid != old_euid) {
current->mm->dumpable = suid_dumpable;
smp_wmb();
}
@@ -1009,8 +997,7 @@ asmlinkage long sys_setuid(uid_t uid)
} else if ((uid != current->uid) && (uid != new_suid))
return -EPERM;
- if (old_euid != uid)
- {
+ if (old_euid != uid) {
current->mm->dumpable = suid_dumpable;
smp_wmb();
}
@@ -1055,8 +1042,7 @@ asmlinkage long sys_setresuid(uid_t ruid, uid_t euid, uid_t suid)
return -EAGAIN;
}
if (euid != (uid_t) -1) {
- if (euid != current->euid)
- {
+ if (euid != current->euid) {
current->mm->dumpable = suid_dumpable;
smp_wmb();
}
@@ -1106,8 +1092,7 @@ asmlinkage long sys_setresgid(gid_t rgid, gid_t egid, gid_t sgid)
return -EPERM;
}
if (egid != (gid_t) -1) {
- if (egid != current->egid)
- {
+ if (egid != current->egid) {
current->mm->dumpable = suid_dumpable;
smp_wmb();
}
@@ -1152,10 +1137,8 @@ asmlinkage long sys_setfsuid(uid_t uid)
if (uid == current->uid || uid == current->euid ||
uid == current->suid || uid == current->fsuid ||
- capable(CAP_SETUID))
- {
- if (uid != old_fsuid)
- {
+ capable(CAP_SETUID)) {
+ if (uid != old_fsuid) {
current->mm->dumpable = suid_dumpable;
smp_wmb();
}
@@ -1183,10 +1166,8 @@ asmlinkage long sys_setfsgid(gid_t gid)
if (gid == current->gid || gid == current->egid ||
gid == current->sgid || gid == current->fsgid ||
- capable(CAP_SETGID))
- {
- if (gid != old_fsgid)
- {
+ capable(CAP_SETGID)) {
+ if (gid != old_fsgid) {
current->mm->dumpable = suid_dumpable;
smp_wmb();
}
@@ -1322,9 +1303,9 @@ out:
asmlinkage long sys_getpgid(pid_t pid)
{
- if (!pid) {
+ if (!pid)
return process_group(current);
- } else {
+ else {
int retval;
struct task_struct *p;
@@ -1354,9 +1335,9 @@ asmlinkage long sys_getpgrp(void)
asmlinkage long sys_getsid(pid_t pid)
{
- if (!pid) {
+ if (!pid)
return current->signal->session;
- } else {
+ else {
int retval;
struct task_struct *p;
@@ -1364,7 +1345,7 @@ asmlinkage long sys_getsid(pid_t pid)
p = find_task_by_pid(pid);
retval = -ESRCH;
- if(p) {
+ if (p) {
retval = security_task_getsid(p);
if (!retval)
retval = p->signal->session;
@@ -1432,9 +1413,9 @@ struct group_info *groups_alloc(int gidsetsize)
group_info->nblocks = nblocks;
atomic_set(&group_info->usage, 1);
- if (gidsetsize <= NGROUPS_SMALL) {
+ if (gidsetsize <= NGROUPS_SMALL)
group_info->blocks[0] = group_info->small_block;
- } else {
+ else {
for (i = 0; i < nblocks; i++) {
gid_t *b;
b = (void *)__get_free_page(GFP_USER);
@@ -1490,7 +1471,7 @@ static int groups_to_user(gid_t __user *grouplist,
/* fill a group_info from a user-space array - it must be allocated already */
static int groups_from_user(struct group_info *group_info,
gid_t __user *grouplist)
- {
+{
int i;
int count = group_info->ngroups;
@@ -1648,9 +1629,8 @@ asmlinkage long sys_setgroups(int gidsetsize, gid_t __user *grouplist)
int in_group_p(gid_t grp)
{
int retval = 1;
- if (grp != current->fsgid) {
+ if (grp != current->fsgid)
retval = groups_search(current->group_info, grp);
- }
return retval;
}
@@ -1659,9 +1639,8 @@ EXPORT_SYMBOL(in_group_p);
int in_egroup_p(gid_t grp)
{
int retval = 1;
- if (grp != current->egid) {
+ if (grp != current->egid)
retval = groups_search(current->group_info, grp);
- }
return retval;
}
@@ -1676,7 +1655,7 @@ asmlinkage long sys_newuname(struct new_utsname __user * name)
int errno = 0;
down_read(&uts_sem);
- if (copy_to_user(name,&system_utsname,sizeof *name))
+ if (copy_to_user(name, utsname(), sizeof *name))
errno = -EFAULT;
up_read(&uts_sem);
return errno;
@@ -1694,8 +1673,8 @@ asmlinkage long sys_sethostname(char __user *name, int len)
down_write(&uts_sem);
errno = -EFAULT;
if (!copy_from_user(tmp, name, len)) {
- memcpy(system_utsname.nodename, tmp, len);
- system_utsname.nodename[len] = 0;
+ memcpy(utsname()->nodename, tmp, len);
+ utsname()->nodename[len] = 0;
errno = 0;
}
up_write(&uts_sem);
@@ -1711,11 +1690,11 @@ asmlinkage long sys_gethostname(char __user *name, int len)
if (len < 0)
return -EINVAL;
down_read(&uts_sem);
- i = 1 + strlen(system_utsname.nodename);
+ i = 1 + strlen(utsname()->nodename);
if (i > len)
i = len;
errno = 0;
- if (copy_to_user(name, system_utsname.nodename, i))
+ if (copy_to_user(name, utsname()->nodename, i))
errno = -EFAULT;
up_read(&uts_sem);
return errno;
@@ -1740,8 +1719,8 @@ asmlinkage long sys_setdomainname(char __user *name, int len)
down_write(&uts_sem);
errno = -EFAULT;
if (!copy_from_user(tmp, name, len)) {
- memcpy(system_utsname.domainname, tmp, len);
- system_utsname.domainname[len] = 0;
+ memcpy(utsname()->domainname, tmp, len);
+ utsname()->domainname[len] = 0;
errno = 0;
}
up_write(&uts_sem);
@@ -1776,9 +1755,9 @@ asmlinkage long sys_old_getrlimit(unsigned int resource, struct rlimit __user *r
task_lock(current->group_leader);
x = current->signal->rlim[resource];
task_unlock(current->group_leader);
- if(x.rlim_cur > 0x7FFFFFFF)
+ if (x.rlim_cur > 0x7FFFFFFF)
x.rlim_cur = 0x7FFFFFFF;
- if(x.rlim_max > 0x7FFFFFFF)
+ if (x.rlim_max > 0x7FFFFFFF)
x.rlim_max = 0x7FFFFFFF;
return copy_to_user(rlim, &x, sizeof(x))?-EFAULT:0;
}
@@ -2084,12 +2063,12 @@ asmlinkage long sys_getcpu(unsigned __user *cpup, unsigned __user *nodep,
* padding
*/
unsigned long t0, t1;
- get_user(t0, &cache->t0);
- get_user(t1, &cache->t1);
+ get_user(t0, &cache->blob[0]);
+ get_user(t1, &cache->blob[1]);
t0++;
t1++;
- put_user(t0, &cache->t0);
- put_user(t1, &cache->t1);
+ put_user(t0, &cache->blob[0]);
+ put_user(t1, &cache->blob[1]);
}
return err ? -EFAULT : 0;
}
diff --git a/kernel/sys_ni.c b/kernel/sys_ni.c
index 6991bece67e8..7a3b2e75f040 100644
--- a/kernel/sys_ni.c
+++ b/kernel/sys_ni.c
@@ -134,3 +134,8 @@ cond_syscall(sys_madvise);
cond_syscall(sys_mremap);
cond_syscall(sys_remap_file_pages);
cond_syscall(compat_sys_move_pages);
+
+/* block-layer dependent */
+cond_syscall(sys_bdflush);
+cond_syscall(sys_ioprio_set);
+cond_syscall(sys_ioprio_get);
diff --git a/kernel/sysctl.c b/kernel/sysctl.c
index 8bfa7d117c54..8020fb273c4f 100644
--- a/kernel/sysctl.c
+++ b/kernel/sysctl.c
@@ -52,6 +52,10 @@
extern int proc_nr_files(ctl_table *table, int write, struct file *filp,
void __user *buffer, size_t *lenp, loff_t *ppos);
+#ifdef CONFIG_X86
+#include <asm/nmi.h>
+#endif
+
#if defined(CONFIG_SYSCTL)
/* External variables not in a header file. */
@@ -64,7 +68,6 @@ extern int sysrq_enabled;
extern int core_uses_pid;
extern int suid_dumpable;
extern char core_pattern[];
-extern int cad_pid;
extern int pid_max;
extern int min_free_kbytes;
extern int printk_ratelimit_jiffies;
@@ -74,13 +77,6 @@ extern int sysctl_drop_caches;
extern int percpu_pagelist_fraction;
extern int compat_log;
-#if defined(CONFIG_X86_LOCAL_APIC) && defined(CONFIG_X86)
-int unknown_nmi_panic;
-int nmi_watchdog_enabled;
-extern int proc_nmi_enabled(struct ctl_table *, int , struct file *,
- void __user *, size_t *, loff_t *);
-#endif
-
/* this is needed for the proc_dointvec_minmax for [fs_]overflow UID and GID */
static int maxolduid = 65535;
static int minolduid;
@@ -95,13 +91,8 @@ extern char modprobe_path[];
extern int sg_big_buff;
#endif
#ifdef CONFIG_SYSVIPC
-extern size_t shm_ctlmax;
-extern size_t shm_ctlall;
-extern int shm_ctlmni;
-extern int msg_ctlmax;
-extern int msg_ctlmnb;
-extern int msg_ctlmni;
-extern int sem_ctls[];
+static int proc_do_ipc_string(ctl_table *table, int write, struct file *filp,
+ void __user *buffer, size_t *lenp, loff_t *ppos);
#endif
#ifdef __sparc__
@@ -142,7 +133,10 @@ static int parse_table(int __user *, int, void __user *, size_t __user *,
void __user *, size_t, ctl_table *, void **);
#endif
-static int proc_doutsstring(ctl_table *table, int write, struct file *filp,
+static int proc_do_uts_string(ctl_table *table, int write, struct file *filp,
+ void __user *buffer, size_t *lenp, loff_t *ppos);
+
+static int proc_do_cad_pid(ctl_table *table, int write, struct file *filp,
void __user *buffer, size_t *lenp, loff_t *ppos);
static ctl_table root_table[];
@@ -232,51 +226,100 @@ static ctl_table root_table[] = {
};
static ctl_table kern_table[] = {
+#ifndef CONFIG_UTS_NS
+ {
+ .ctl_name = KERN_OSTYPE,
+ .procname = "ostype",
+ .data = init_uts_ns.name.sysname,
+ .maxlen = sizeof(init_uts_ns.name.sysname),
+ .mode = 0444,
+ .proc_handler = &proc_do_uts_string,
+ .strategy = &sysctl_string,
+ },
+ {
+ .ctl_name = KERN_OSRELEASE,
+ .procname = "osrelease",
+ .data = init_uts_ns.name.release,
+ .maxlen = sizeof(init_uts_ns.name.release),
+ .mode = 0444,
+ .proc_handler = &proc_do_uts_string,
+ .strategy = &sysctl_string,
+ },
+ {
+ .ctl_name = KERN_VERSION,
+ .procname = "version",
+ .data = init_uts_ns.name.version,
+ .maxlen = sizeof(init_uts_ns.name.version),
+ .mode = 0444,
+ .proc_handler = &proc_do_uts_string,
+ .strategy = &sysctl_string,
+ },
+ {
+ .ctl_name = KERN_NODENAME,
+ .procname = "hostname",
+ .data = init_uts_ns.name.nodename,
+ .maxlen = sizeof(init_uts_ns.name.nodename),
+ .mode = 0644,
+ .proc_handler = &proc_do_uts_string,
+ .strategy = &sysctl_string,
+ },
+ {
+ .ctl_name = KERN_DOMAINNAME,
+ .procname = "domainname",
+ .data = init_uts_ns.name.domainname,
+ .maxlen = sizeof(init_uts_ns.name.domainname),
+ .mode = 0644,
+ .proc_handler = &proc_do_uts_string,
+ .strategy = &sysctl_string,
+ },
+#else /* !CONFIG_UTS_NS */
{
.ctl_name = KERN_OSTYPE,
.procname = "ostype",
- .data = system_utsname.sysname,
- .maxlen = sizeof(system_utsname.sysname),
+ .data = NULL,
+ /* could maybe use __NEW_UTS_LEN here? */
+ .maxlen = FIELD_SIZEOF(struct new_utsname, sysname),
.mode = 0444,
- .proc_handler = &proc_doutsstring,
+ .proc_handler = &proc_do_uts_string,
.strategy = &sysctl_string,
},
{
.ctl_name = KERN_OSRELEASE,
.procname = "osrelease",
- .data = system_utsname.release,
- .maxlen = sizeof(system_utsname.release),
+ .data = NULL,
+ .maxlen = FIELD_SIZEOF(struct new_utsname, release),
.mode = 0444,
- .proc_handler = &proc_doutsstring,
+ .proc_handler = &proc_do_uts_string,
.strategy = &sysctl_string,
},
{
.ctl_name = KERN_VERSION,
.procname = "version",
- .data = system_utsname.version,
- .maxlen = sizeof(system_utsname.version),
+ .data = NULL,
+ .maxlen = FIELD_SIZEOF(struct new_utsname, version),
.mode = 0444,
- .proc_handler = &proc_doutsstring,
+ .proc_handler = &proc_do_uts_string,
.strategy = &sysctl_string,
},
{
.ctl_name = KERN_NODENAME,
.procname = "hostname",
- .data = system_utsname.nodename,
- .maxlen = sizeof(system_utsname.nodename),
+ .data = NULL,
+ .maxlen = FIELD_SIZEOF(struct new_utsname, nodename),
.mode = 0644,
- .proc_handler = &proc_doutsstring,
+ .proc_handler = &proc_do_uts_string,
.strategy = &sysctl_string,
},
{
.ctl_name = KERN_DOMAINNAME,
.procname = "domainname",
- .data = system_utsname.domainname,
- .maxlen = sizeof(system_utsname.domainname),
+ .data = NULL,
+ .maxlen = FIELD_SIZEOF(struct new_utsname, domainname),
.mode = 0644,
- .proc_handler = &proc_doutsstring,
+ .proc_handler = &proc_do_uts_string,
.strategy = &sysctl_string,
},
+#endif /* !CONFIG_UTS_NS */
{
.ctl_name = KERN_PANIC,
.procname = "panic",
@@ -297,7 +340,7 @@ static ctl_table kern_table[] = {
.ctl_name = KERN_CORE_PATTERN,
.procname = "core_pattern",
.data = core_pattern,
- .maxlen = 64,
+ .maxlen = 128,
.mode = 0644,
.proc_handler = &proc_dostring,
.strategy = &sysctl_string,
@@ -435,58 +478,58 @@ static ctl_table kern_table[] = {
{
.ctl_name = KERN_SHMMAX,
.procname = "shmmax",
- .data = &shm_ctlmax,
+ .data = NULL,
.maxlen = sizeof (size_t),
.mode = 0644,
- .proc_handler = &proc_doulongvec_minmax,
+ .proc_handler = &proc_do_ipc_string,
},
{
.ctl_name = KERN_SHMALL,
.procname = "shmall",
- .data = &shm_ctlall,
+ .data = NULL,
.maxlen = sizeof (size_t),
.mode = 0644,
- .proc_handler = &proc_doulongvec_minmax,
+ .proc_handler = &proc_do_ipc_string,
},
{
.ctl_name = KERN_SHMMNI,
.procname = "shmmni",
- .data = &shm_ctlmni,
+ .data = NULL,
.maxlen = sizeof (int),
.mode = 0644,
- .proc_handler = &proc_dointvec,
+ .proc_handler = &proc_do_ipc_string,
},
{
.ctl_name = KERN_MSGMAX,
.procname = "msgmax",
- .data = &msg_ctlmax,
+ .data = NULL,
.maxlen = sizeof (int),
.mode = 0644,
- .proc_handler = &proc_dointvec,
+ .proc_handler = &proc_do_ipc_string,
},
{
.ctl_name = KERN_MSGMNI,
.procname = "msgmni",
- .data = &msg_ctlmni,
+ .data = NULL,
.maxlen = sizeof (int),
.mode = 0644,
- .proc_handler = &proc_dointvec,
+ .proc_handler = &proc_do_ipc_string,
},
{
.ctl_name = KERN_MSGMNB,
.procname = "msgmnb",
- .data = &msg_ctlmnb,
+ .data = NULL,
.maxlen = sizeof (int),
.mode = 0644,
- .proc_handler = &proc_dointvec,
+ .proc_handler = &proc_do_ipc_string,
},
{
.ctl_name = KERN_SEM,
.procname = "sem",
- .data = &sem_ctls,
+ .data = NULL,
.maxlen = 4*sizeof (int),
.mode = 0644,
- .proc_handler = &proc_dointvec,
+ .proc_handler = &proc_do_ipc_string,
},
#endif
#ifdef CONFIG_MAGIC_SYSRQ
@@ -502,10 +545,10 @@ static ctl_table kern_table[] = {
{
.ctl_name = KERN_CADPID,
.procname = "cad_pid",
- .data = &cad_pid,
+ .data = NULL,
.maxlen = sizeof (int),
.mode = 0600,
- .proc_handler = &proc_dointvec,
+ .proc_handler = &proc_do_cad_pid,
},
{
.ctl_name = KERN_MAX_THREADS,
@@ -1627,32 +1670,15 @@ static ssize_t proc_writesys(struct file * file, const char __user * buf,
return do_rw_proc(1, file, (char __user *) buf, count, ppos);
}
-/**
- * proc_dostring - read a string sysctl
- * @table: the sysctl table
- * @write: %TRUE if this is a write to the sysctl file
- * @filp: the file structure
- * @buffer: the user buffer
- * @lenp: the size of the user buffer
- * @ppos: file position
- *
- * Reads/writes a string from/to the user buffer. If the kernel
- * buffer provided is not large enough to hold the string, the
- * string is truncated. The copied string is %NULL-terminated.
- * If the string is being read by the user process, it is copied
- * and a newline '\n' is added. It is truncated if the buffer is
- * not large enough.
- *
- * Returns 0 on success.
- */
-int proc_dostring(ctl_table *table, int write, struct file *filp,
- void __user *buffer, size_t *lenp, loff_t *ppos)
+static int _proc_do_string(void* data, int maxlen, int write,
+ struct file *filp, void __user *buffer,
+ size_t *lenp, loff_t *ppos)
{
size_t len;
char __user *p;
char c;
- if (!table->data || !table->maxlen || !*lenp ||
+ if (!data || !maxlen || !*lenp ||
(*ppos && !write)) {
*lenp = 0;
return 0;
@@ -1668,20 +1694,20 @@ int proc_dostring(ctl_table *table, int write, struct file *filp,
break;
len++;
}
- if (len >= table->maxlen)
- len = table->maxlen-1;
- if(copy_from_user(table->data, buffer, len))
+ if (len >= maxlen)
+ len = maxlen-1;
+ if(copy_from_user(data, buffer, len))
return -EFAULT;
- ((char *) table->data)[len] = 0;
+ ((char *) data)[len] = 0;
*ppos += *lenp;
} else {
- len = strlen(table->data);
- if (len > table->maxlen)
- len = table->maxlen;
+ len = strlen(data);
+ if (len > maxlen)
+ len = maxlen;
if (len > *lenp)
len = *lenp;
if (len)
- if(copy_to_user(buffer, table->data, len))
+ if(copy_to_user(buffer, data, len))
return -EFAULT;
if (len < *lenp) {
if(put_user('\n', ((char __user *) buffer) + len))
@@ -1694,12 +1720,38 @@ int proc_dostring(ctl_table *table, int write, struct file *filp,
return 0;
}
+/**
+ * proc_dostring - read a string sysctl
+ * @table: the sysctl table
+ * @write: %TRUE if this is a write to the sysctl file
+ * @filp: the file structure
+ * @buffer: the user buffer
+ * @lenp: the size of the user buffer
+ * @ppos: file position
+ *
+ * Reads/writes a string from/to the user buffer. If the kernel
+ * buffer provided is not large enough to hold the string, the
+ * string is truncated. The copied string is %NULL-terminated.
+ * If the string is being read by the user process, it is copied
+ * and a newline '\n' is added. It is truncated if the buffer is
+ * not large enough.
+ *
+ * Returns 0 on success.
+ */
+int proc_dostring(ctl_table *table, int write, struct file *filp,
+ void __user *buffer, size_t *lenp, loff_t *ppos)
+{
+ return _proc_do_string(table->data, table->maxlen, write, filp,
+ buffer, lenp, ppos);
+}
+
/*
* Special case of dostring for the UTS structure. This has locks
* to observe. Should this be in kernel/sys.c ????
*/
-static int proc_doutsstring(ctl_table *table, int write, struct file *filp,
+#ifndef CONFIG_UTS_NS
+static int proc_do_uts_string(ctl_table *table, int write, struct file *filp,
void __user *buffer, size_t *lenp, loff_t *ppos)
{
int r;
@@ -1715,6 +1767,48 @@ static int proc_doutsstring(ctl_table *table, int write, struct file *filp,
}
return r;
}
+#else /* !CONFIG_UTS_NS */
+static int proc_do_uts_string(ctl_table *table, int write, struct file *filp,
+ void __user *buffer, size_t *lenp, loff_t *ppos)
+{
+ int r;
+ struct uts_namespace* uts_ns = current->nsproxy->uts_ns;
+ char* which;
+
+ switch (table->ctl_name) {
+ case KERN_OSTYPE:
+ which = uts_ns->name.sysname;
+ break;
+ case KERN_NODENAME:
+ which = uts_ns->name.nodename;
+ break;
+ case KERN_OSRELEASE:
+ which = uts_ns->name.release;
+ break;
+ case KERN_VERSION:
+ which = uts_ns->name.version;
+ break;
+ case KERN_DOMAINNAME:
+ which = uts_ns->name.domainname;
+ break;
+ default:
+ r = -EINVAL;
+ goto out;
+ }
+
+ if (!write) {
+ down_read(&uts_sem);
+ r=_proc_do_string(which,table->maxlen,0,filp,buffer,lenp, ppos);
+ up_read(&uts_sem);
+ } else {
+ down_write(&uts_sem);
+ r=_proc_do_string(which,table->maxlen,1,filp,buffer,lenp, ppos);
+ up_write(&uts_sem);
+ }
+ out:
+ return r;
+}
+#endif /* !CONFIG_UTS_NS */
static int do_proc_dointvec_conv(int *negp, unsigned long *lvalp,
int *valp,
@@ -1735,8 +1829,9 @@ static int do_proc_dointvec_conv(int *negp, unsigned long *lvalp,
return 0;
}
-static int do_proc_dointvec(ctl_table *table, int write, struct file *filp,
- void __user *buffer, size_t *lenp, loff_t *ppos,
+static int __do_proc_dointvec(void *tbl_data, ctl_table *table,
+ int write, struct file *filp, void __user *buffer,
+ size_t *lenp, loff_t *ppos,
int (*conv)(int *negp, unsigned long *lvalp, int *valp,
int write, void *data),
void *data)
@@ -1749,13 +1844,13 @@ static int do_proc_dointvec(ctl_table *table, int write, struct file *filp,
char buf[TMPBUFLEN], *p;
char __user *s = buffer;
- if (!table->data || !table->maxlen || !*lenp ||
+ if (!tbl_data || !table->maxlen || !*lenp ||
(*ppos && !write)) {
*lenp = 0;
return 0;
}
- i = (int *) table->data;
+ i = (int *) tbl_data;
vleft = table->maxlen / sizeof(*i);
left = *lenp;
@@ -1844,6 +1939,16 @@ static int do_proc_dointvec(ctl_table *table, int write, struct file *filp,
#undef TMPBUFLEN
}
+static int do_proc_dointvec(ctl_table *table, int write, struct file *filp,
+ void __user *buffer, size_t *lenp, loff_t *ppos,
+ int (*conv)(int *negp, unsigned long *lvalp, int *valp,
+ int write, void *data),
+ void *data)
+{
+ return __do_proc_dointvec(table->data, table, write, filp,
+ buffer, lenp, ppos, conv, data);
+}
+
/**
* proc_dointvec - read a vector of integers
* @table: the sysctl table
@@ -1915,7 +2020,7 @@ int proc_dointvec_bset(ctl_table *table, int write, struct file *filp,
return -EPERM;
}
- op = (current->pid == 1) ? OP_SET : OP_AND;
+ op = is_init(current) ? OP_SET : OP_AND;
return do_proc_dointvec(table,write,filp,buffer,lenp,ppos,
do_proc_dointvec_bset_conv,&op);
}
@@ -1977,7 +2082,7 @@ int proc_dointvec_minmax(ctl_table *table, int write, struct file *filp,
do_proc_dointvec_minmax_conv, &param);
}
-static int do_proc_doulongvec_minmax(ctl_table *table, int write,
+static int __do_proc_doulongvec_minmax(void *data, ctl_table *table, int write,
struct file *filp,
void __user *buffer,
size_t *lenp, loff_t *ppos,
@@ -1991,13 +2096,13 @@ static int do_proc_doulongvec_minmax(ctl_table *table, int write,
char buf[TMPBUFLEN], *p;
char __user *s = buffer;
- if (!table->data || !table->maxlen || !*lenp ||
+ if (!data || !table->maxlen || !*lenp ||
(*ppos && !write)) {
*lenp = 0;
return 0;
}
- i = (unsigned long *) table->data;
+ i = (unsigned long *) data;
min = (unsigned long *) table->extra1;
max = (unsigned long *) table->extra2;
vleft = table->maxlen / sizeof(unsigned long);
@@ -2082,6 +2187,17 @@ static int do_proc_doulongvec_minmax(ctl_table *table, int write,
#undef TMPBUFLEN
}
+static int do_proc_doulongvec_minmax(ctl_table *table, int write,
+ struct file *filp,
+ void __user *buffer,
+ size_t *lenp, loff_t *ppos,
+ unsigned long convmul,
+ unsigned long convdiv)
+{
+ return __do_proc_doulongvec_minmax(table->data, table, write,
+ filp, buffer, lenp, ppos, convmul, convdiv);
+}
+
/**
* proc_doulongvec_minmax - read a vector of long integers with min/max values
* @table: the sysctl table
@@ -2270,6 +2386,71 @@ int proc_dointvec_ms_jiffies(ctl_table *table, int write, struct file *filp,
do_proc_dointvec_ms_jiffies_conv, NULL);
}
+#ifdef CONFIG_SYSVIPC
+static int proc_do_ipc_string(ctl_table *table, int write, struct file *filp,
+ void __user *buffer, size_t *lenp, loff_t *ppos)
+{
+ void *data;
+ struct ipc_namespace *ns;
+
+ ns = current->nsproxy->ipc_ns;
+
+ switch (table->ctl_name) {
+ case KERN_SHMMAX:
+ data = &ns->shm_ctlmax;
+ goto proc_minmax;
+ case KERN_SHMALL:
+ data = &ns->shm_ctlall;
+ goto proc_minmax;
+ case KERN_SHMMNI:
+ data = &ns->shm_ctlmni;
+ break;
+ case KERN_MSGMAX:
+ data = &ns->msg_ctlmax;
+ break;
+ case KERN_MSGMNI:
+ data = &ns->msg_ctlmni;
+ break;
+ case KERN_MSGMNB:
+ data = &ns->msg_ctlmnb;
+ break;
+ case KERN_SEM:
+ data = &ns->sem_ctls;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return __do_proc_dointvec(data, table, write, filp, buffer,
+ lenp, ppos, NULL, NULL);
+proc_minmax:
+ return __do_proc_doulongvec_minmax(data, table, write, filp, buffer,
+ lenp, ppos, 1l, 1l);
+}
+#endif
+
+static int proc_do_cad_pid(ctl_table *table, int write, struct file *filp,
+ void __user *buffer, size_t *lenp, loff_t *ppos)
+{
+ struct pid *new_pid;
+ pid_t tmp;
+ int r;
+
+ tmp = pid_nr(cad_pid);
+
+ r = __do_proc_dointvec(&tmp, table, write, filp, buffer,
+ lenp, ppos, NULL, NULL);
+ if (r || !write)
+ return r;
+
+ new_pid = find_get_pid(tmp);
+ if (!new_pid)
+ return -ESRCH;
+
+ put_pid(xchg(&cad_pid, new_pid));
+ return 0;
+}
+
#else /* CONFIG_PROC_FS */
int proc_dostring(ctl_table *table, int write, struct file *filp,
@@ -2278,12 +2459,20 @@ int proc_dostring(ctl_table *table, int write, struct file *filp,
return -ENOSYS;
}
-static int proc_doutsstring(ctl_table *table, int write, struct file *filp,
- void __user *buffer, size_t *lenp, loff_t *ppos)
+static int proc_do_uts_string(ctl_table *table, int write, struct file *filp,
+ void __user *buffer, size_t *lenp, loff_t *ppos)
{
return -ENOSYS;
}
+#ifdef CONFIG_SYSVIPC
+static int proc_do_ipc_string(ctl_table *table, int write, struct file *filp,
+ void __user *buffer, size_t *lenp, loff_t *ppos)
+{
+ return -ENOSYS;
+}
+#endif
+
int proc_dointvec(ctl_table *table, int write, struct file *filp,
void __user *buffer, size_t *lenp, loff_t *ppos)
{
diff --git a/kernel/taskstats.c b/kernel/taskstats.c
index 2ed4040d0dc5..5d6a8c54ee85 100644
--- a/kernel/taskstats.c
+++ b/kernel/taskstats.c
@@ -18,7 +18,9 @@
#include <linux/kernel.h>
#include <linux/taskstats_kern.h>
+#include <linux/tsacct_kern.h>
#include <linux/delayacct.h>
+#include <linux/tsacct_kern.h>
#include <linux/cpumask.h>
#include <linux/percpu.h>
#include <net/genetlink.h>
@@ -75,7 +77,7 @@ static int prepare_reply(struct genl_info *info, u8 cmd, struct sk_buff **skbp,
/*
* If new attributes are added, please revisit this allocation
*/
- skb = nlmsg_new(size, GFP_KERNEL);
+ skb = nlmsg_new(genlmsg_total_size(size), GFP_KERNEL);
if (!skb)
return -ENOMEM;
@@ -198,7 +200,13 @@ static int fill_pid(pid_t pid, struct task_struct *pidtsk,
*/
delayacct_add_tsk(stats, tsk);
+
+ /* fill in basic acct fields */
stats->version = TASKSTATS_VERSION;
+ bacct_add_tsk(stats, tsk);
+
+ /* fill in extended acct fields */
+ xacct_add_tsk(stats, tsk);
/* Define err: label here if needed */
put_task_struct(tsk);
diff --git a/kernel/time.c b/kernel/time.c
index 5bd489747643..0e017bff4c19 100644
--- a/kernel/time.c
+++ b/kernel/time.c
@@ -202,179 +202,6 @@ asmlinkage long sys_settimeofday(struct timeval __user *tv,
return do_sys_settimeofday(tv ? &new_ts : NULL, tz ? &new_tz : NULL);
}
-/* we call this to notify the arch when the clock is being
- * controlled. If no such arch routine, do nothing.
- */
-void __attribute__ ((weak)) notify_arch_cmos_timer(void)
-{
- return;
-}
-
-/* adjtimex mainly allows reading (and writing, if superuser) of
- * kernel time-keeping variables. used by xntpd.
- */
-int do_adjtimex(struct timex *txc)
-{
- long ltemp, mtemp, save_adjust;
- int result;
-
- /* In order to modify anything, you gotta be super-user! */
- if (txc->modes && !capable(CAP_SYS_TIME))
- return -EPERM;
-
- /* Now we validate the data before disabling interrupts */
-
- if ((txc->modes & ADJ_OFFSET_SINGLESHOT) == ADJ_OFFSET_SINGLESHOT)
- /* singleshot must not be used with any other mode bits */
- if (txc->modes != ADJ_OFFSET_SINGLESHOT)
- return -EINVAL;
-
- if (txc->modes != ADJ_OFFSET_SINGLESHOT && (txc->modes & ADJ_OFFSET))
- /* adjustment Offset limited to +- .512 seconds */
- if (txc->offset <= - MAXPHASE || txc->offset >= MAXPHASE )
- return -EINVAL;
-
- /* if the quartz is off by more than 10% something is VERY wrong ! */
- if (txc->modes & ADJ_TICK)
- if (txc->tick < 900000/USER_HZ ||
- txc->tick > 1100000/USER_HZ)
- return -EINVAL;
-
- write_seqlock_irq(&xtime_lock);
- result = time_state; /* mostly `TIME_OK' */
-
- /* Save for later - semantics of adjtime is to return old value */
- save_adjust = time_next_adjust ? time_next_adjust : time_adjust;
-
-#if 0 /* STA_CLOCKERR is never set yet */
- time_status &= ~STA_CLOCKERR; /* reset STA_CLOCKERR */
-#endif
- /* If there are input parameters, then process them */
- if (txc->modes)
- {
- if (txc->modes & ADJ_STATUS) /* only set allowed bits */
- time_status = (txc->status & ~STA_RONLY) |
- (time_status & STA_RONLY);
-
- if (txc->modes & ADJ_FREQUENCY) { /* p. 22 */
- if (txc->freq > MAXFREQ || txc->freq < -MAXFREQ) {
- result = -EINVAL;
- goto leave;
- }
- time_freq = txc->freq;
- }
-
- if (txc->modes & ADJ_MAXERROR) {
- if (txc->maxerror < 0 || txc->maxerror >= NTP_PHASE_LIMIT) {
- result = -EINVAL;
- goto leave;
- }
- time_maxerror = txc->maxerror;
- }
-
- if (txc->modes & ADJ_ESTERROR) {
- if (txc->esterror < 0 || txc->esterror >= NTP_PHASE_LIMIT) {
- result = -EINVAL;
- goto leave;
- }
- time_esterror = txc->esterror;
- }
-
- if (txc->modes & ADJ_TIMECONST) { /* p. 24 */
- if (txc->constant < 0) { /* NTP v4 uses values > 6 */
- result = -EINVAL;
- goto leave;
- }
- time_constant = txc->constant;
- }
-
- if (txc->modes & ADJ_OFFSET) { /* values checked earlier */
- if (txc->modes == ADJ_OFFSET_SINGLESHOT) {
- /* adjtime() is independent from ntp_adjtime() */
- if ((time_next_adjust = txc->offset) == 0)
- time_adjust = 0;
- }
- else if (time_status & STA_PLL) {
- ltemp = txc->offset;
-
- /*
- * Scale the phase adjustment and
- * clamp to the operating range.
- */
- if (ltemp > MAXPHASE)
- time_offset = MAXPHASE << SHIFT_UPDATE;
- else if (ltemp < -MAXPHASE)
- time_offset = -(MAXPHASE << SHIFT_UPDATE);
- else
- time_offset = ltemp << SHIFT_UPDATE;
-
- /*
- * Select whether the frequency is to be controlled
- * and in which mode (PLL or FLL). Clamp to the operating
- * range. Ugly multiply/divide should be replaced someday.
- */
-
- if (time_status & STA_FREQHOLD || time_reftime == 0)
- time_reftime = xtime.tv_sec;
- mtemp = xtime.tv_sec - time_reftime;
- time_reftime = xtime.tv_sec;
- if (time_status & STA_FLL) {
- if (mtemp >= MINSEC) {
- ltemp = (time_offset / mtemp) << (SHIFT_USEC -
- SHIFT_UPDATE);
- time_freq += shift_right(ltemp, SHIFT_KH);
- } else /* calibration interval too short (p. 12) */
- result = TIME_ERROR;
- } else { /* PLL mode */
- if (mtemp < MAXSEC) {
- ltemp *= mtemp;
- time_freq += shift_right(ltemp,(time_constant +
- time_constant +
- SHIFT_KF - SHIFT_USEC));
- } else /* calibration interval too long (p. 12) */
- result = TIME_ERROR;
- }
- time_freq = min(time_freq, time_tolerance);
- time_freq = max(time_freq, -time_tolerance);
- } /* STA_PLL */
- } /* txc->modes & ADJ_OFFSET */
- if (txc->modes & ADJ_TICK) {
- tick_usec = txc->tick;
- tick_nsec = TICK_USEC_TO_NSEC(tick_usec);
- }
- } /* txc->modes */
-leave: if ((time_status & (STA_UNSYNC|STA_CLOCKERR)) != 0)
- result = TIME_ERROR;
-
- if ((txc->modes & ADJ_OFFSET_SINGLESHOT) == ADJ_OFFSET_SINGLESHOT)
- txc->offset = save_adjust;
- else {
- txc->offset = shift_right(time_offset, SHIFT_UPDATE);
- }
- txc->freq = time_freq;
- txc->maxerror = time_maxerror;
- txc->esterror = time_esterror;
- txc->status = time_status;
- txc->constant = time_constant;
- txc->precision = time_precision;
- txc->tolerance = time_tolerance;
- txc->tick = tick_usec;
-
- /* PPS is not implemented, so these are zero */
- txc->ppsfreq = 0;
- txc->jitter = 0;
- txc->shift = 0;
- txc->stabil = 0;
- txc->jitcnt = 0;
- txc->calcnt = 0;
- txc->errcnt = 0;
- txc->stbcnt = 0;
- write_sequnlock_irq(&xtime_lock);
- do_gettimeofday(&txc->time);
- notify_arch_cmos_timer();
- return(result);
-}
-
asmlinkage long sys_adjtimex(struct timex __user *txc_p)
{
struct timex txc; /* Local copy of parameter */
diff --git a/kernel/time/Makefile b/kernel/time/Makefile
index e1dfd8e86cce..61a3907d16fb 100644
--- a/kernel/time/Makefile
+++ b/kernel/time/Makefile
@@ -1 +1 @@
-obj-y += clocksource.o jiffies.o
+obj-y += ntp.o clocksource.o jiffies.o
diff --git a/kernel/time/ntp.c b/kernel/time/ntp.c
new file mode 100644
index 000000000000..47195fa0ec4f
--- /dev/null
+++ b/kernel/time/ntp.c
@@ -0,0 +1,350 @@
+/*
+ * linux/kernel/time/ntp.c
+ *
+ * NTP state machine interfaces and logic.
+ *
+ * This code was mainly moved from kernel/timer.c and kernel/time.c
+ * Please see those files for relevant copyright info and historical
+ * changelogs.
+ */
+
+#include <linux/mm.h>
+#include <linux/time.h>
+#include <linux/timex.h>
+
+#include <asm/div64.h>
+#include <asm/timex.h>
+
+/*
+ * Timekeeping variables
+ */
+unsigned long tick_usec = TICK_USEC; /* USER_HZ period (usec) */
+unsigned long tick_nsec; /* ACTHZ period (nsec) */
+static u64 tick_length, tick_length_base;
+
+#define MAX_TICKADJ 500 /* microsecs */
+#define MAX_TICKADJ_SCALED (((u64)(MAX_TICKADJ * NSEC_PER_USEC) << \
+ TICK_LENGTH_SHIFT) / HZ)
+
+/*
+ * phase-lock loop variables
+ */
+/* TIME_ERROR prevents overwriting the CMOS clock */
+static int time_state = TIME_OK; /* clock synchronization status */
+int time_status = STA_UNSYNC; /* clock status bits */
+static long time_offset; /* time adjustment (ns) */
+static long time_constant = 2; /* pll time constant */
+long time_maxerror = NTP_PHASE_LIMIT; /* maximum error (us) */
+long time_esterror = NTP_PHASE_LIMIT; /* estimated error (us) */
+long time_freq; /* frequency offset (scaled ppm)*/
+static long time_reftime; /* time at last adjustment (s) */
+long time_adjust;
+
+#define CLOCK_TICK_OVERFLOW (LATCH * HZ - CLOCK_TICK_RATE)
+#define CLOCK_TICK_ADJUST (((s64)CLOCK_TICK_OVERFLOW * NSEC_PER_SEC) / \
+ (s64)CLOCK_TICK_RATE)
+
+static void ntp_update_frequency(void)
+{
+ tick_length_base = (u64)(tick_usec * NSEC_PER_USEC * USER_HZ) << TICK_LENGTH_SHIFT;
+ tick_length_base += (s64)CLOCK_TICK_ADJUST << TICK_LENGTH_SHIFT;
+ tick_length_base += (s64)time_freq << (TICK_LENGTH_SHIFT - SHIFT_NSEC);
+
+ do_div(tick_length_base, HZ);
+
+ tick_nsec = tick_length_base >> TICK_LENGTH_SHIFT;
+}
+
+/**
+ * ntp_clear - Clears the NTP state variables
+ *
+ * Must be called while holding a write on the xtime_lock
+ */
+void ntp_clear(void)
+{
+ time_adjust = 0; /* stop active adjtime() */
+ time_status |= STA_UNSYNC;
+ time_maxerror = NTP_PHASE_LIMIT;
+ time_esterror = NTP_PHASE_LIMIT;
+
+ ntp_update_frequency();
+
+ tick_length = tick_length_base;
+ time_offset = 0;
+}
+
+/*
+ * this routine handles the overflow of the microsecond field
+ *
+ * The tricky bits of code to handle the accurate clock support
+ * were provided by Dave Mills (Mills@UDEL.EDU) of NTP fame.
+ * They were originally developed for SUN and DEC kernels.
+ * All the kudos should go to Dave for this stuff.
+ */
+void second_overflow(void)
+{
+ long time_adj;
+
+ /* Bump the maxerror field */
+ time_maxerror += MAXFREQ >> SHIFT_USEC;
+ if (time_maxerror > NTP_PHASE_LIMIT) {
+ time_maxerror = NTP_PHASE_LIMIT;
+ time_status |= STA_UNSYNC;
+ }
+
+ /*
+ * Leap second processing. If in leap-insert state at the end of the
+ * day, the system clock is set back one second; if in leap-delete
+ * state, the system clock is set ahead one second. The microtime()
+ * routine or external clock driver will insure that reported time is
+ * always monotonic. The ugly divides should be replaced.
+ */
+ switch (time_state) {
+ case TIME_OK:
+ if (time_status & STA_INS)
+ time_state = TIME_INS;
+ else if (time_status & STA_DEL)
+ time_state = TIME_DEL;
+ break;
+ case TIME_INS:
+ if (xtime.tv_sec % 86400 == 0) {
+ xtime.tv_sec--;
+ wall_to_monotonic.tv_sec++;
+ /*
+ * The timer interpolator will make time change
+ * gradually instead of an immediate jump by one second
+ */
+ time_interpolator_update(-NSEC_PER_SEC);
+ time_state = TIME_OOP;
+ clock_was_set();
+ printk(KERN_NOTICE "Clock: inserting leap second "
+ "23:59:60 UTC\n");
+ }
+ break;
+ case TIME_DEL:
+ if ((xtime.tv_sec + 1) % 86400 == 0) {
+ xtime.tv_sec++;
+ wall_to_monotonic.tv_sec--;
+ /*
+ * Use of time interpolator for a gradual change of
+ * time
+ */
+ time_interpolator_update(NSEC_PER_SEC);
+ time_state = TIME_WAIT;
+ clock_was_set();
+ printk(KERN_NOTICE "Clock: deleting leap second "
+ "23:59:59 UTC\n");
+ }
+ break;
+ case TIME_OOP:
+ time_state = TIME_WAIT;
+ break;
+ case TIME_WAIT:
+ if (!(time_status & (STA_INS | STA_DEL)))
+ time_state = TIME_OK;
+ }
+
+ /*
+ * Compute the phase adjustment for the next second. The offset is
+ * reduced by a fixed factor times the time constant.
+ */
+ tick_length = tick_length_base;
+ time_adj = shift_right(time_offset, SHIFT_PLL + time_constant);
+ time_offset -= time_adj;
+ tick_length += (s64)time_adj << (TICK_LENGTH_SHIFT - SHIFT_UPDATE);
+
+ if (unlikely(time_adjust)) {
+ if (time_adjust > MAX_TICKADJ) {
+ time_adjust -= MAX_TICKADJ;
+ tick_length += MAX_TICKADJ_SCALED;
+ } else if (time_adjust < -MAX_TICKADJ) {
+ time_adjust += MAX_TICKADJ;
+ tick_length -= MAX_TICKADJ_SCALED;
+ } else {
+ time_adjust = 0;
+ tick_length += (s64)(time_adjust * NSEC_PER_USEC /
+ HZ) << TICK_LENGTH_SHIFT;
+ }
+ }
+}
+
+/*
+ * Return how long ticks are at the moment, that is, how much time
+ * update_wall_time_one_tick will add to xtime next time we call it
+ * (assuming no calls to do_adjtimex in the meantime).
+ * The return value is in fixed-point nanoseconds shifted by the
+ * specified number of bits to the right of the binary point.
+ * This function has no side-effects.
+ */
+u64 current_tick_length(void)
+{
+ return tick_length;
+}
+
+
+void __attribute__ ((weak)) notify_arch_cmos_timer(void)
+{
+ return;
+}
+
+/* adjtimex mainly allows reading (and writing, if superuser) of
+ * kernel time-keeping variables. used by xntpd.
+ */
+int do_adjtimex(struct timex *txc)
+{
+ long ltemp, mtemp, save_adjust;
+ s64 freq_adj, temp64;
+ int result;
+
+ /* In order to modify anything, you gotta be super-user! */
+ if (txc->modes && !capable(CAP_SYS_TIME))
+ return -EPERM;
+
+ /* Now we validate the data before disabling interrupts */
+
+ if ((txc->modes & ADJ_OFFSET_SINGLESHOT) == ADJ_OFFSET_SINGLESHOT)
+ /* singleshot must not be used with any other mode bits */
+ if (txc->modes != ADJ_OFFSET_SINGLESHOT)
+ return -EINVAL;
+
+ if (txc->modes != ADJ_OFFSET_SINGLESHOT && (txc->modes & ADJ_OFFSET))
+ /* adjustment Offset limited to +- .512 seconds */
+ if (txc->offset <= - MAXPHASE || txc->offset >= MAXPHASE )
+ return -EINVAL;
+
+ /* if the quartz is off by more than 10% something is VERY wrong ! */
+ if (txc->modes & ADJ_TICK)
+ if (txc->tick < 900000/USER_HZ ||
+ txc->tick > 1100000/USER_HZ)
+ return -EINVAL;
+
+ write_seqlock_irq(&xtime_lock);
+ result = time_state; /* mostly `TIME_OK' */
+
+ /* Save for later - semantics of adjtime is to return old value */
+ save_adjust = time_adjust;
+
+#if 0 /* STA_CLOCKERR is never set yet */
+ time_status &= ~STA_CLOCKERR; /* reset STA_CLOCKERR */
+#endif
+ /* If there are input parameters, then process them */
+ if (txc->modes)
+ {
+ if (txc->modes & ADJ_STATUS) /* only set allowed bits */
+ time_status = (txc->status & ~STA_RONLY) |
+ (time_status & STA_RONLY);
+
+ if (txc->modes & ADJ_FREQUENCY) { /* p. 22 */
+ if (txc->freq > MAXFREQ || txc->freq < -MAXFREQ) {
+ result = -EINVAL;
+ goto leave;
+ }
+ time_freq = ((s64)txc->freq * NSEC_PER_USEC) >> (SHIFT_USEC - SHIFT_NSEC);
+ }
+
+ if (txc->modes & ADJ_MAXERROR) {
+ if (txc->maxerror < 0 || txc->maxerror >= NTP_PHASE_LIMIT) {
+ result = -EINVAL;
+ goto leave;
+ }
+ time_maxerror = txc->maxerror;
+ }
+
+ if (txc->modes & ADJ_ESTERROR) {
+ if (txc->esterror < 0 || txc->esterror >= NTP_PHASE_LIMIT) {
+ result = -EINVAL;
+ goto leave;
+ }
+ time_esterror = txc->esterror;
+ }
+
+ if (txc->modes & ADJ_TIMECONST) { /* p. 24 */
+ if (txc->constant < 0) { /* NTP v4 uses values > 6 */
+ result = -EINVAL;
+ goto leave;
+ }
+ time_constant = min(txc->constant + 4, (long)MAXTC);
+ }
+
+ if (txc->modes & ADJ_OFFSET) { /* values checked earlier */
+ if (txc->modes == ADJ_OFFSET_SINGLESHOT) {
+ /* adjtime() is independent from ntp_adjtime() */
+ time_adjust = txc->offset;
+ }
+ else if (time_status & STA_PLL) {
+ ltemp = txc->offset * NSEC_PER_USEC;
+
+ /*
+ * Scale the phase adjustment and
+ * clamp to the operating range.
+ */
+ time_offset = min(ltemp, MAXPHASE * NSEC_PER_USEC);
+ time_offset = max(time_offset, -MAXPHASE * NSEC_PER_USEC);
+
+ /*
+ * Select whether the frequency is to be controlled
+ * and in which mode (PLL or FLL). Clamp to the operating
+ * range. Ugly multiply/divide should be replaced someday.
+ */
+
+ if (time_status & STA_FREQHOLD || time_reftime == 0)
+ time_reftime = xtime.tv_sec;
+ mtemp = xtime.tv_sec - time_reftime;
+ time_reftime = xtime.tv_sec;
+
+ freq_adj = (s64)time_offset * mtemp;
+ freq_adj = shift_right(freq_adj, time_constant * 2 +
+ (SHIFT_PLL + 2) * 2 - SHIFT_NSEC);
+ if (mtemp >= MINSEC && (time_status & STA_FLL || mtemp > MAXSEC)) {
+ temp64 = (s64)time_offset << (SHIFT_NSEC - SHIFT_FLL);
+ if (time_offset < 0) {
+ temp64 = -temp64;
+ do_div(temp64, mtemp);
+ freq_adj -= temp64;
+ } else {
+ do_div(temp64, mtemp);
+ freq_adj += temp64;
+ }
+ }
+ freq_adj += time_freq;
+ freq_adj = min(freq_adj, (s64)MAXFREQ_NSEC);
+ time_freq = max(freq_adj, (s64)-MAXFREQ_NSEC);
+ time_offset = (time_offset / HZ) << SHIFT_UPDATE;
+ } /* STA_PLL */
+ } /* txc->modes & ADJ_OFFSET */
+ if (txc->modes & ADJ_TICK)
+ tick_usec = txc->tick;
+
+ if (txc->modes & (ADJ_TICK|ADJ_FREQUENCY|ADJ_OFFSET))
+ ntp_update_frequency();
+ } /* txc->modes */
+leave: if ((time_status & (STA_UNSYNC|STA_CLOCKERR)) != 0)
+ result = TIME_ERROR;
+
+ if ((txc->modes & ADJ_OFFSET_SINGLESHOT) == ADJ_OFFSET_SINGLESHOT)
+ txc->offset = save_adjust;
+ else
+ txc->offset = shift_right(time_offset, SHIFT_UPDATE) * HZ / 1000;
+ txc->freq = (time_freq / NSEC_PER_USEC) << (SHIFT_USEC - SHIFT_NSEC);
+ txc->maxerror = time_maxerror;
+ txc->esterror = time_esterror;
+ txc->status = time_status;
+ txc->constant = time_constant;
+ txc->precision = 1;
+ txc->tolerance = MAXFREQ;
+ txc->tick = tick_usec;
+
+ /* PPS is not implemented, so these are zero */
+ txc->ppsfreq = 0;
+ txc->jitter = 0;
+ txc->shift = 0;
+ txc->stabil = 0;
+ txc->jitcnt = 0;
+ txc->calcnt = 0;
+ txc->errcnt = 0;
+ txc->stbcnt = 0;
+ write_sequnlock_irq(&xtime_lock);
+ do_gettimeofday(&txc->time);
+ notify_arch_cmos_timer();
+ return(result);
+}
diff --git a/kernel/timer.c b/kernel/timer.c
index 1d7dd6267c2d..c1c7fbcffec1 100644
--- a/kernel/timer.c
+++ b/kernel/timer.c
@@ -41,12 +41,6 @@
#include <asm/timex.h>
#include <asm/io.h>
-#ifdef CONFIG_TIME_INTERPOLATION
-static void time_interpolator_update(long delta_nsec);
-#else
-#define time_interpolator_update(x)
-#endif
-
u64 jiffies_64 __cacheline_aligned_in_smp = INITIAL_JIFFIES;
EXPORT_SYMBOL(jiffies_64);
@@ -136,7 +130,7 @@ static void internal_add_timer(tvec_base_t *base, struct timer_list *timer)
list_add_tail(&timer->entry, vec);
}
-/***
+/**
* init_timer - initialize a timer.
* @timer: the timer to be initialized
*
@@ -175,6 +169,7 @@ static inline void detach_timer(struct timer_list *timer,
*/
static tvec_base_t *lock_timer_base(struct timer_list *timer,
unsigned long *flags)
+ __acquires(timer->base->lock)
{
tvec_base_t *base;
@@ -235,7 +230,7 @@ int __mod_timer(struct timer_list *timer, unsigned long expires)
EXPORT_SYMBOL(__mod_timer);
-/***
+/**
* add_timer_on - start a timer on a particular CPU
* @timer: the timer to be added
* @cpu: the CPU to start it on
@@ -255,9 +250,10 @@ void add_timer_on(struct timer_list *timer, int cpu)
}
-/***
+/**
* mod_timer - modify a timer's timeout
* @timer: the timer to be modified
+ * @expires: new timeout in jiffies
*
* mod_timer is a more efficient way to update the expire field of an
* active timer (if the timer is inactive it will be activated)
@@ -291,7 +287,7 @@ int mod_timer(struct timer_list *timer, unsigned long expires)
EXPORT_SYMBOL(mod_timer);
-/***
+/**
* del_timer - deactive a timer.
* @timer: the timer to be deactivated
*
@@ -323,7 +319,10 @@ int del_timer(struct timer_list *timer)
EXPORT_SYMBOL(del_timer);
#ifdef CONFIG_SMP
-/*
+/**
+ * try_to_del_timer_sync - Try to deactivate a timer
+ * @timer: timer do del
+ *
* This function tries to deactivate a timer. Upon successful (ret >= 0)
* exit the timer is not queued and the handler is not running on any CPU.
*
@@ -351,7 +350,7 @@ out:
return ret;
}
-/***
+/**
* del_timer_sync - deactivate a timer and wait for the handler to finish.
* @timer: the timer to be deactivated
*
@@ -401,15 +400,15 @@ static int cascade(tvec_base_t *base, tvec_t *tv, int index)
return index;
}
-/***
+#define INDEX(N) ((base->timer_jiffies >> (TVR_BITS + (N) * TVN_BITS)) & TVN_MASK)
+
+/**
* __run_timers - run all expired timers (if any) on this CPU.
* @base: the timer vector to be processed.
*
* This function cascades all vectors and executes all expired timer
* vectors.
*/
-#define INDEX(N) ((base->timer_jiffies >> (TVR_BITS + (N) * TVN_BITS)) & TVN_MASK)
-
static inline void __run_timers(tvec_base_t *base)
{
struct timer_list *timer;
@@ -563,12 +562,6 @@ found:
/******************************************************************/
-/*
- * Timekeeping variables
- */
-unsigned long tick_usec = TICK_USEC; /* USER_HZ period (usec) */
-unsigned long tick_nsec = TICK_NSEC; /* ACTHZ period (nsec) */
-
/*
* The current time
* wall_to_monotonic is what we need to add to xtime (or xtime corrected
@@ -582,209 +575,6 @@ struct timespec wall_to_monotonic __attribute__ ((aligned (16)));
EXPORT_SYMBOL(xtime);
-/* Don't completely fail for HZ > 500. */
-int tickadj = 500/HZ ? : 1; /* microsecs */
-
-
-/*
- * phase-lock loop variables
- */
-/* TIME_ERROR prevents overwriting the CMOS clock */
-int time_state = TIME_OK; /* clock synchronization status */
-int time_status = STA_UNSYNC; /* clock status bits */
-long time_offset; /* time adjustment (us) */
-long time_constant = 2; /* pll time constant */
-long time_tolerance = MAXFREQ; /* frequency tolerance (ppm) */
-long time_precision = 1; /* clock precision (us) */
-long time_maxerror = NTP_PHASE_LIMIT; /* maximum error (us) */
-long time_esterror = NTP_PHASE_LIMIT; /* estimated error (us) */
-long time_freq = (((NSEC_PER_SEC + HZ/2) % HZ - HZ/2) << SHIFT_USEC) / NSEC_PER_USEC;
- /* frequency offset (scaled ppm)*/
-static long time_adj; /* tick adjust (scaled 1 / HZ) */
-long time_reftime; /* time at last adjustment (s) */
-long time_adjust;
-long time_next_adjust;
-
-/*
- * this routine handles the overflow of the microsecond field
- *
- * The tricky bits of code to handle the accurate clock support
- * were provided by Dave Mills (Mills@UDEL.EDU) of NTP fame.
- * They were originally developed for SUN and DEC kernels.
- * All the kudos should go to Dave for this stuff.
- *
- */
-static void second_overflow(void)
-{
- long ltemp;
-
- /* Bump the maxerror field */
- time_maxerror += time_tolerance >> SHIFT_USEC;
- if (time_maxerror > NTP_PHASE_LIMIT) {
- time_maxerror = NTP_PHASE_LIMIT;
- time_status |= STA_UNSYNC;
- }
-
- /*
- * Leap second processing. If in leap-insert state at the end of the
- * day, the system clock is set back one second; if in leap-delete
- * state, the system clock is set ahead one second. The microtime()
- * routine or external clock driver will insure that reported time is
- * always monotonic. The ugly divides should be replaced.
- */
- switch (time_state) {
- case TIME_OK:
- if (time_status & STA_INS)
- time_state = TIME_INS;
- else if (time_status & STA_DEL)
- time_state = TIME_DEL;
- break;
- case TIME_INS:
- if (xtime.tv_sec % 86400 == 0) {
- xtime.tv_sec--;
- wall_to_monotonic.tv_sec++;
- /*
- * The timer interpolator will make time change
- * gradually instead of an immediate jump by one second
- */
- time_interpolator_update(-NSEC_PER_SEC);
- time_state = TIME_OOP;
- clock_was_set();
- printk(KERN_NOTICE "Clock: inserting leap second "
- "23:59:60 UTC\n");
- }
- break;
- case TIME_DEL:
- if ((xtime.tv_sec + 1) % 86400 == 0) {
- xtime.tv_sec++;
- wall_to_monotonic.tv_sec--;
- /*
- * Use of time interpolator for a gradual change of
- * time
- */
- time_interpolator_update(NSEC_PER_SEC);
- time_state = TIME_WAIT;
- clock_was_set();
- printk(KERN_NOTICE "Clock: deleting leap second "
- "23:59:59 UTC\n");
- }
- break;
- case TIME_OOP:
- time_state = TIME_WAIT;
- break;
- case TIME_WAIT:
- if (!(time_status & (STA_INS | STA_DEL)))
- time_state = TIME_OK;
- }
-
- /*
- * Compute the phase adjustment for the next second. In PLL mode, the
- * offset is reduced by a fixed factor times the time constant. In FLL
- * mode the offset is used directly. In either mode, the maximum phase
- * adjustment for each second is clamped so as to spread the adjustment
- * over not more than the number of seconds between updates.
- */
- ltemp = time_offset;
- if (!(time_status & STA_FLL))
- ltemp = shift_right(ltemp, SHIFT_KG + time_constant);
- ltemp = min(ltemp, (MAXPHASE / MINSEC) << SHIFT_UPDATE);
- ltemp = max(ltemp, -(MAXPHASE / MINSEC) << SHIFT_UPDATE);
- time_offset -= ltemp;
- time_adj = ltemp << (SHIFT_SCALE - SHIFT_HZ - SHIFT_UPDATE);
-
- /*
- * Compute the frequency estimate and additional phase adjustment due
- * to frequency error for the next second.
- */
- ltemp = time_freq;
- time_adj += shift_right(ltemp,(SHIFT_USEC + SHIFT_HZ - SHIFT_SCALE));
-
-#if HZ == 100
- /*
- * Compensate for (HZ==100) != (1 << SHIFT_HZ). Add 25% and 3.125% to
- * get 128.125; => only 0.125% error (p. 14)
- */
- time_adj += shift_right(time_adj, 2) + shift_right(time_adj, 5);
-#endif
-#if HZ == 250
- /*
- * Compensate for (HZ==250) != (1 << SHIFT_HZ). Add 1.5625% and
- * 0.78125% to get 255.85938; => only 0.05% error (p. 14)
- */
- time_adj += shift_right(time_adj, 6) + shift_right(time_adj, 7);
-#endif
-#if HZ == 1000
- /*
- * Compensate for (HZ==1000) != (1 << SHIFT_HZ). Add 1.5625% and
- * 0.78125% to get 1023.4375; => only 0.05% error (p. 14)
- */
- time_adj += shift_right(time_adj, 6) + shift_right(time_adj, 7);
-#endif
-}
-
-/*
- * Returns how many microseconds we need to add to xtime this tick
- * in doing an adjustment requested with adjtime.
- */
-static long adjtime_adjustment(void)
-{
- long time_adjust_step;
-
- time_adjust_step = time_adjust;
- if (time_adjust_step) {
- /*
- * We are doing an adjtime thing. Prepare time_adjust_step to
- * be within bounds. Note that a positive time_adjust means we
- * want the clock to run faster.
- *
- * Limit the amount of the step to be in the range
- * -tickadj .. +tickadj
- */
- time_adjust_step = min(time_adjust_step, (long)tickadj);
- time_adjust_step = max(time_adjust_step, (long)-tickadj);
- }
- return time_adjust_step;
-}
-
-/* in the NTP reference this is called "hardclock()" */
-static void update_ntp_one_tick(void)
-{
- long time_adjust_step;
-
- time_adjust_step = adjtime_adjustment();
- if (time_adjust_step)
- /* Reduce by this step the amount of time left */
- time_adjust -= time_adjust_step;
-
- /* Changes by adjtime() do not take effect till next tick. */
- if (time_next_adjust != 0) {
- time_adjust = time_next_adjust;
- time_next_adjust = 0;
- }
-}
-
-/*
- * Return how long ticks are at the moment, that is, how much time
- * update_wall_time_one_tick will add to xtime next time we call it
- * (assuming no calls to do_adjtimex in the meantime).
- * The return value is in fixed-point nanoseconds shifted by the
- * specified number of bits to the right of the binary point.
- * This function has no side-effects.
- */
-u64 current_tick_length(void)
-{
- long delta_nsec;
- u64 ret;
-
- /* calculate the finest interval NTP will allow.
- * ie: nanosecond value shifted by (SHIFT_SCALE - 10)
- */
- delta_nsec = tick_nsec + adjtime_adjustment() * 1000;
- ret = (u64)delta_nsec << TICK_LENGTH_SHIFT;
- ret += (s64)time_adj << (TICK_LENGTH_SHIFT - (SHIFT_SCALE - 10));
-
- return ret;
-}
/* XXX - all of this timekeeping code should be later moved to time.c */
#include <linux/clocksource.h>
@@ -961,21 +751,24 @@ void __init timekeeping_init(void)
unsigned long flags;
write_seqlock_irqsave(&xtime_lock, flags);
+
+ ntp_clear();
+
clock = clocksource_get_next();
clocksource_calculate_interval(clock, tick_nsec);
clock->cycle_last = clocksource_read(clock);
- ntp_clear();
+
write_sequnlock_irqrestore(&xtime_lock, flags);
}
static int timekeeping_suspended;
-/*
+/**
* timekeeping_resume - Resumes the generic timekeeping subsystem.
* @dev: unused
*
* This is for the generic clocksource timekeeping.
- * xtime/wall_to_monotonic/jiffies/wall_jiffies/etc are
+ * xtime/wall_to_monotonic/jiffies/etc are
* still managed by arch specific suspend/resume code.
*/
static int timekeeping_resume(struct sys_device *dev)
@@ -1106,7 +899,7 @@ static void clocksource_adjust(struct clocksource *clock, s64 offset)
clock->error -= (interval - offset) << (TICK_LENGTH_SHIFT - clock->shift);
}
-/*
+/**
* update_wall_time - Uses the current clocksource to increment the wall time
*
* Called from the timer interrupt, must hold a write on xtime_lock.
@@ -1144,8 +937,6 @@ static void update_wall_time(void)
/* interpolator bits */
time_interpolator_update(clock->xtime_interval
>> clock->shift);
- /* increment the NTP state machine */
- update_ntp_one_tick();
/* accumulate error between NTP and clock interval */
clock->error += current_tick_length();
@@ -1217,19 +1008,14 @@ static inline void calc_load(unsigned long ticks)
unsigned long active_tasks; /* fixed-point */
static int count = LOAD_FREQ;
- count -= ticks;
- if (count < 0) {
- count += LOAD_FREQ;
- active_tasks = count_active_tasks();
+ active_tasks = count_active_tasks();
+ for (count -= ticks; count < 0; count += LOAD_FREQ) {
CALC_LOAD(avenrun[0], EXP_1, active_tasks);
CALC_LOAD(avenrun[1], EXP_5, active_tasks);
CALC_LOAD(avenrun[2], EXP_15, active_tasks);
}
}
-/* jiffies at the most recent update of wall time */
-unsigned long wall_jiffies = INITIAL_JIFFIES;
-
/*
* This read-write spinlock protects us from races in SMP while
* playing with xtime and avenrun.
@@ -1265,12 +1051,8 @@ void run_local_timers(void)
* Called by the timer interrupt. xtime_lock must already be taken
* by the timer IRQ!
*/
-static inline void update_times(void)
+static inline void update_times(unsigned long ticks)
{
- unsigned long ticks;
-
- ticks = jiffies - wall_jiffies;
- wall_jiffies += ticks;
update_wall_time();
calc_load(ticks);
}
@@ -1281,12 +1063,10 @@ static inline void update_times(void)
* jiffies is defined in the linker script...
*/
-void do_timer(struct pt_regs *regs)
+void do_timer(unsigned long ticks)
{
- jiffies_64++;
- /* prevent loading jiffies before storing new jiffies_64 value. */
- barrier();
- update_times();
+ jiffies_64 += ticks;
+ update_times(ticks);
}
#ifdef __ARCH_WANT_SYS_ALARM
@@ -1470,8 +1250,9 @@ asmlinkage long sys_gettid(void)
return current->pid;
}
-/*
+/**
* sys_sysinfo - fill in sysinfo struct
+ * @info: pointer to buffer to fill
*/
asmlinkage long sys_sysinfo(struct sysinfo __user *info)
{
@@ -1688,8 +1469,10 @@ static struct notifier_block __cpuinitdata timers_nb = {
void __init init_timers(void)
{
- timer_cpu_notify(&timers_nb, (unsigned long)CPU_UP_PREPARE,
+ int err = timer_cpu_notify(&timers_nb, (unsigned long)CPU_UP_PREPARE,
(void *)(long)smp_processor_id());
+
+ BUG_ON(err == NOTIFY_BAD);
register_cpu_notifier(&timers_nb);
open_softirq(TIMER_SOFTIRQ, run_timer_softirq, NULL);
}
@@ -1774,7 +1557,7 @@ unsigned long time_interpolator_get_offset(void)
#define INTERPOLATOR_ADJUST 65536
#define INTERPOLATOR_MAX_SKIP 10*INTERPOLATOR_ADJUST
-static void time_interpolator_update(long delta_nsec)
+void time_interpolator_update(long delta_nsec)
{
u64 counter;
unsigned long offset;
diff --git a/kernel/tsacct.c b/kernel/tsacct.c
new file mode 100644
index 000000000000..db443221ba5b
--- /dev/null
+++ b/kernel/tsacct.c
@@ -0,0 +1,124 @@
+/*
+ * tsacct.c - System accounting over taskstats interface
+ *
+ * Copyright (C) Jay Lan, <jlan@sgi.com>
+ *
+ *
+ * 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.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/tsacct_kern.h>
+#include <linux/acct.h>
+#include <linux/jiffies.h>
+
+
+#define USEC_PER_TICK (USEC_PER_SEC/HZ)
+/*
+ * fill in basic accounting fields
+ */
+void bacct_add_tsk(struct taskstats *stats, struct task_struct *tsk)
+{
+ struct timespec uptime, ts;
+ s64 ac_etime;
+
+ BUILD_BUG_ON(TS_COMM_LEN < TASK_COMM_LEN);
+
+ /* calculate task elapsed time in timespec */
+ do_posix_clock_monotonic_gettime(&uptime);
+ ts = timespec_sub(uptime, current->group_leader->start_time);
+ /* rebase elapsed time to usec */
+ ac_etime = timespec_to_ns(&ts);
+ do_div(ac_etime, NSEC_PER_USEC);
+ stats->ac_etime = ac_etime;
+ stats->ac_btime = xtime.tv_sec - ts.tv_sec;
+ if (thread_group_leader(tsk)) {
+ stats->ac_exitcode = tsk->exit_code;
+ if (tsk->flags & PF_FORKNOEXEC)
+ stats->ac_flag |= AFORK;
+ }
+ if (tsk->flags & PF_SUPERPRIV)
+ stats->ac_flag |= ASU;
+ if (tsk->flags & PF_DUMPCORE)
+ stats->ac_flag |= ACORE;
+ if (tsk->flags & PF_SIGNALED)
+ stats->ac_flag |= AXSIG;
+ stats->ac_nice = task_nice(tsk);
+ stats->ac_sched = tsk->policy;
+ stats->ac_uid = tsk->uid;
+ stats->ac_gid = tsk->gid;
+ stats->ac_pid = tsk->pid;
+ stats->ac_ppid = (tsk->parent) ? tsk->parent->pid : 0;
+ stats->ac_utime = cputime_to_msecs(tsk->utime) * USEC_PER_MSEC;
+ stats->ac_stime = cputime_to_msecs(tsk->stime) * USEC_PER_MSEC;
+ stats->ac_minflt = tsk->min_flt;
+ stats->ac_majflt = tsk->maj_flt;
+
+ strncpy(stats->ac_comm, tsk->comm, sizeof(stats->ac_comm));
+}
+
+
+#ifdef CONFIG_TASK_XACCT
+
+#define KB 1024
+#define MB (1024*KB)
+/*
+ * fill in extended accounting fields
+ */
+void xacct_add_tsk(struct taskstats *stats, struct task_struct *p)
+{
+ /* convert pages-jiffies to Mbyte-usec */
+ stats->coremem = jiffies_to_usecs(p->acct_rss_mem1) * PAGE_SIZE / MB;
+ stats->virtmem = jiffies_to_usecs(p->acct_vm_mem1) * PAGE_SIZE / MB;
+ if (p->mm) {
+ /* adjust to KB unit */
+ stats->hiwater_rss = p->mm->hiwater_rss * PAGE_SIZE / KB;
+ stats->hiwater_vm = p->mm->hiwater_vm * PAGE_SIZE / KB;
+ }
+ stats->read_char = p->rchar;
+ stats->write_char = p->wchar;
+ stats->read_syscalls = p->syscr;
+ stats->write_syscalls = p->syscw;
+}
+#undef KB
+#undef MB
+
+/**
+ * acct_update_integrals - update mm integral fields in task_struct
+ * @tsk: task_struct for accounting
+ */
+void acct_update_integrals(struct task_struct *tsk)
+{
+ if (likely(tsk->mm)) {
+ long delta = cputime_to_jiffies(
+ cputime_sub(tsk->stime, tsk->acct_stimexpd));
+
+ if (delta == 0)
+ return;
+ tsk->acct_stimexpd = tsk->stime;
+ tsk->acct_rss_mem1 += delta * get_mm_rss(tsk->mm);
+ tsk->acct_vm_mem1 += delta * tsk->mm->total_vm;
+ }
+}
+
+/**
+ * acct_clear_integrals - clear the mm integral fields in task_struct
+ * @tsk: task_struct whose accounting fields are cleared
+ */
+void acct_clear_integrals(struct task_struct *tsk)
+{
+ tsk->acct_stimexpd = 0;
+ tsk->acct_rss_mem1 = 0;
+ tsk->acct_vm_mem1 = 0;
+}
+#endif
diff --git a/kernel/unwind.c b/kernel/unwind.c
index 3430475fcd88..2e2368607aab 100644
--- a/kernel/unwind.c
+++ b/kernel/unwind.c
@@ -102,7 +102,7 @@ static struct unwind_table {
unsigned long size;
struct unwind_table *link;
const char *name;
-} root_table, *last_table;
+} root_table;
struct unwind_item {
enum item_location {
@@ -174,6 +174,8 @@ void __init unwind_init(void)
#ifdef CONFIG_MODULES
+static struct unwind_table *last_table;
+
/* Must be called with module_mutex held. */
void *unwind_add_table(struct module *module,
const void *table_start,
diff --git a/kernel/utsname.c b/kernel/utsname.c
new file mode 100644
index 000000000000..c859164a6993
--- /dev/null
+++ b/kernel/utsname.c
@@ -0,0 +1,95 @@
+/*
+ * Copyright (C) 2004 IBM Corporation
+ *
+ * Author: Serge Hallyn <serue@us.ibm.com>
+ *
+ * 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.
+ */
+
+#include <linux/module.h>
+#include <linux/uts.h>
+#include <linux/utsname.h>
+#include <linux/version.h>
+
+/*
+ * Clone a new ns copying an original utsname, setting refcount to 1
+ * @old_ns: namespace to clone
+ * Return NULL on error (failure to kmalloc), new ns otherwise
+ */
+static struct uts_namespace *clone_uts_ns(struct uts_namespace *old_ns)
+{
+ struct uts_namespace *ns;
+
+ ns = kmalloc(sizeof(struct uts_namespace), GFP_KERNEL);
+ if (ns) {
+ memcpy(&ns->name, &old_ns->name, sizeof(ns->name));
+ kref_init(&ns->kref);
+ }
+ return ns;
+}
+
+/*
+ * unshare the current process' utsname namespace.
+ * called only in sys_unshare()
+ */
+int unshare_utsname(unsigned long unshare_flags, struct uts_namespace **new_uts)
+{
+ if (unshare_flags & CLONE_NEWUTS) {
+ if (!capable(CAP_SYS_ADMIN))
+ return -EPERM;
+
+ *new_uts = clone_uts_ns(current->nsproxy->uts_ns);
+ if (!*new_uts)
+ return -ENOMEM;
+ }
+
+ return 0;
+}
+
+/*
+ * Copy task tsk's utsname namespace, or clone it if flags
+ * specifies CLONE_NEWUTS. In latter case, changes to the
+ * utsname of this process won't be seen by parent, and vice
+ * versa.
+ */
+int copy_utsname(int flags, struct task_struct *tsk)
+{
+ struct uts_namespace *old_ns = tsk->nsproxy->uts_ns;
+ struct uts_namespace *new_ns;
+ int err = 0;
+
+ if (!old_ns)
+ return 0;
+
+ get_uts_ns(old_ns);
+
+ if (!(flags & CLONE_NEWUTS))
+ return 0;
+
+ if (!capable(CAP_SYS_ADMIN)) {
+ err = -EPERM;
+ goto out;
+ }
+
+ new_ns = clone_uts_ns(old_ns);
+ if (!new_ns) {
+ err = -ENOMEM;
+ goto out;
+ }
+ tsk->nsproxy->uts_ns = new_ns;
+
+out:
+ put_uts_ns(old_ns);
+ return err;
+}
+
+void free_uts_ns(struct kref *kref)
+{
+ struct uts_namespace *ns;
+
+ ns = container_of(kref, struct uts_namespace, kref);
+ kfree(ns);
+}
diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
index b0f5ca72599f..756a908c441d 100644
--- a/lib/Kconfig.debug
+++ b/lib/Kconfig.debug
@@ -320,6 +320,15 @@ config DEBUG_VM
If unsure, say N.
+config DEBUG_LIST
+ bool "Debug linked list manipulation"
+ depends on DEBUG_KERNEL
+ help
+ Enable this to turn on extended checks in the linked-list
+ walking routines.
+
+ If unsure, say N.
+
config FRAME_POINTER
bool "Compile the kernel with frame pointers"
depends on DEBUG_KERNEL && (X86 || CRIS || M68K || M68KNOMMU || FRV || UML || S390 || AVR32 || SUPERH)
@@ -375,3 +384,17 @@ config RCU_TORTURE_TEST
at boot time (you probably don't).
Say M if you want the RCU torture tests to build as a module.
Say N if you are unsure.
+
+config LKDTM
+ tristate "Linux Kernel Dump Test Tool Module"
+ depends on KPROBES
+ default n
+ help
+ This module enables testing of the different dumping mechanisms by
+ inducing system failures at predefined crash points.
+ If you don't need it: say N
+ Choose M here to compile this code as a module. The module will be
+ called lkdtm.
+
+ Documentation on how to use the module can be found in
+ drivers/misc/lkdtm.c
diff --git a/lib/Makefile b/lib/Makefile
index ef1d37afbbb6..b0361756e22e 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -2,11 +2,12 @@
# Makefile for some libs needed in the kernel.
#
-lib-y := errno.o ctype.o string.o vsprintf.o cmdline.o \
+lib-y := ctype.o string.o vsprintf.o cmdline.o \
bust_spinlocks.o rbtree.o radix-tree.o dump_stack.o \
idr.o div64.o int_sqrt.o bitmap.o extable.o prio_tree.o \
sha1.o
+lib-$(CONFIG_MMU) += ioremap.o
lib-$(CONFIG_SMP) += cpumask.o
lib-y += kobject.o kref.o kobject_uevent.o klist.o
@@ -28,6 +29,7 @@ lib-$(CONFIG_GENERIC_HWEIGHT) += hweight.o
obj-$(CONFIG_LOCK_KERNEL) += kernel_lock.o
obj-$(CONFIG_PLIST) += plist.o
obj-$(CONFIG_DEBUG_PREEMPT) += smp_processor_id.o
+obj-$(CONFIG_DEBUG_LIST) += list_debug.o
ifneq ($(CONFIG_HAVE_DEC_LOCK),y)
lib-y += dec_and_lock.o
diff --git a/lib/cpumask.c b/lib/cpumask.c
index 3a67dc5ada7d..7a2a73f88d59 100644
--- a/lib/cpumask.c
+++ b/lib/cpumask.c
@@ -43,3 +43,19 @@ int __any_online_cpu(const cpumask_t *mask)
return cpu;
}
EXPORT_SYMBOL(__any_online_cpu);
+
+#if MAX_NUMNODES > 1
+/*
+ * Find the highest possible node id.
+ */
+int highest_possible_node_id(void)
+{
+ unsigned int node;
+ unsigned int highest = 0;
+
+ for_each_node_mask(node, node_possible_map)
+ highest = node;
+ return highest;
+}
+EXPORT_SYMBOL(highest_possible_node_id);
+#endif
diff --git a/lib/errno.c b/lib/errno.c
deleted file mode 100644
index 41cb9d76c052..000000000000
--- a/lib/errno.c
+++ /dev/null
@@ -1,7 +0,0 @@
-/*
- * linux/lib/errno.c
- *
- * Copyright (C) 1991, 1992 Linus Torvalds
- */
-
-int errno;
diff --git a/lib/genalloc.c b/lib/genalloc.c
index 71338b48e889..75ae68ce03e1 100644
--- a/lib/genalloc.c
+++ b/lib/genalloc.c
@@ -14,11 +14,13 @@
#include <linux/genalloc.h>
-/*
- * Create a new special memory pool.
- *
+/**
+ * gen_pool_create - create a new special memory pool
* @min_alloc_order: log base 2 of number of bytes each bitmap bit represents
* @nid: node id of the node the pool structure should be allocated on, or -1
+ *
+ * Create a new special memory pool that can be used to manage special purpose
+ * memory not managed by the regular kmalloc/kfree interface.
*/
struct gen_pool *gen_pool_create(int min_alloc_order, int nid)
{
@@ -34,15 +36,15 @@ struct gen_pool *gen_pool_create(int min_alloc_order, int nid)
}
EXPORT_SYMBOL(gen_pool_create);
-
-/*
- * Add a new chunk of memory to the specified pool.
- *
+/**
+ * gen_pool_add - add a new chunk of special memory to the pool
* @pool: pool to add new memory chunk to
* @addr: starting address of memory chunk to add to pool
* @size: size in bytes of the memory chunk to add to pool
* @nid: node id of the node the chunk structure and bitmap should be
* allocated on, or -1
+ *
+ * Add a new chunk of special memory to the specified pool.
*/
int gen_pool_add(struct gen_pool *pool, unsigned long addr, size_t size,
int nid)
@@ -69,13 +71,44 @@ int gen_pool_add(struct gen_pool *pool, unsigned long addr, size_t size,
}
EXPORT_SYMBOL(gen_pool_add);
-
-/*
- * Allocate the requested number of bytes from the specified pool.
- * Uses a first-fit algorithm.
+/**
+ * gen_pool_destroy - destroy a special memory pool
+ * @pool: pool to destroy
*
+ * Destroy the specified special memory pool. Verifies that there are no
+ * outstanding allocations.
+ */
+void gen_pool_destroy(struct gen_pool *pool)
+{
+ struct list_head *_chunk, *_next_chunk;
+ struct gen_pool_chunk *chunk;
+ int order = pool->min_alloc_order;
+ int bit, end_bit;
+
+
+ write_lock(&pool->lock);
+ list_for_each_safe(_chunk, _next_chunk, &pool->chunks) {
+ chunk = list_entry(_chunk, struct gen_pool_chunk, next_chunk);
+ list_del(&chunk->next_chunk);
+
+ end_bit = (chunk->end_addr - chunk->start_addr) >> order;
+ bit = find_next_bit(chunk->bits, end_bit, 0);
+ BUG_ON(bit < end_bit);
+
+ kfree(chunk);
+ }
+ kfree(pool);
+ return;
+}
+EXPORT_SYMBOL(gen_pool_destroy);
+
+/**
+ * gen_pool_alloc - allocate special memory from the pool
* @pool: pool to allocate from
* @size: number of bytes to allocate from the pool
+ *
+ * Allocate the requested number of bytes from the specified pool.
+ * Uses a first-fit algorithm.
*/
unsigned long gen_pool_alloc(struct gen_pool *pool, size_t size)
{
@@ -127,13 +160,13 @@ unsigned long gen_pool_alloc(struct gen_pool *pool, size_t size)
}
EXPORT_SYMBOL(gen_pool_alloc);
-
-/*
- * Free the specified memory back to the specified pool.
- *
+/**
+ * gen_pool_free - free allocated special memory back to the pool
* @pool: pool to free to
* @addr: starting address of memory to free back to pool
* @size: size in bytes of memory to free
+ *
+ * Free previously allocated special memory back to the specified pool.
*/
void gen_pool_free(struct gen_pool *pool, unsigned long addr, size_t size)
{
diff --git a/lib/ioremap.c b/lib/ioremap.c
new file mode 100644
index 000000000000..99fa277f9f7b
--- /dev/null
+++ b/lib/ioremap.c
@@ -0,0 +1,92 @@
+/*
+ * Re-map IO memory to kernel address space so that we can access it.
+ * This is needed for high PCI addresses that aren't mapped in the
+ * 640k-1MB IO memory area on PC's
+ *
+ * (C) Copyright 1995 1996 Linus Torvalds
+ */
+#include <linux/io.h>
+#include <linux/vmalloc.h>
+#include <linux/mm.h>
+
+#include <asm/cacheflush.h>
+#include <asm/pgtable.h>
+
+static int ioremap_pte_range(pmd_t *pmd, unsigned long addr,
+ unsigned long end, unsigned long phys_addr, pgprot_t prot)
+{
+ pte_t *pte;
+ unsigned long pfn;
+
+ pfn = phys_addr >> PAGE_SHIFT;
+ pte = pte_alloc_kernel(pmd, addr);
+ if (!pte)
+ return -ENOMEM;
+ do {
+ BUG_ON(!pte_none(*pte));
+ set_pte_at(&init_mm, addr, pte, pfn_pte(pfn, prot));
+ pfn++;
+ } while (pte++, addr += PAGE_SIZE, addr != end);
+ return 0;
+}
+
+static inline int ioremap_pmd_range(pud_t *pud, unsigned long addr,
+ unsigned long end, unsigned long phys_addr, pgprot_t prot)
+{
+ pmd_t *pmd;
+ unsigned long next;
+
+ phys_addr -= addr;
+ pmd = pmd_alloc(&init_mm, pud, addr);
+ if (!pmd)
+ return -ENOMEM;
+ do {
+ next = pmd_addr_end(addr, end);
+ if (ioremap_pte_range(pmd, addr, next, phys_addr + addr, prot))
+ return -ENOMEM;
+ } while (pmd++, addr = next, addr != end);
+ return 0;
+}
+
+static inline int ioremap_pud_range(pgd_t *pgd, unsigned long addr,
+ unsigned long end, unsigned long phys_addr, pgprot_t prot)
+{
+ pud_t *pud;
+ unsigned long next;
+
+ phys_addr -= addr;
+ pud = pud_alloc(&init_mm, pgd, addr);
+ if (!pud)
+ return -ENOMEM;
+ do {
+ next = pud_addr_end(addr, end);
+ if (ioremap_pmd_range(pud, addr, next, phys_addr + addr, prot))
+ return -ENOMEM;
+ } while (pud++, addr = next, addr != end);
+ return 0;
+}
+
+int ioremap_page_range(unsigned long addr,
+ unsigned long end, unsigned long phys_addr, pgprot_t prot)
+{
+ pgd_t *pgd;
+ unsigned long start;
+ unsigned long next;
+ int err;
+
+ BUG_ON(addr >= end);
+
+ start = addr;
+ phys_addr -= addr;
+ pgd = pgd_offset_k(addr);
+ do {
+ next = pgd_addr_end(addr, end);
+ err = ioremap_pud_range(pgd, addr, next, phys_addr+addr, prot);
+ if (err)
+ break;
+ } while (pgd++, addr = next, addr != end);
+
+ flush_cache_vmap(start, end);
+
+ return err;
+}
diff --git a/lib/list_debug.c b/lib/list_debug.c
new file mode 100644
index 000000000000..7ba9d823d388
--- /dev/null
+++ b/lib/list_debug.c
@@ -0,0 +1,76 @@
+/*
+ * Copyright 2006, Red Hat, Inc., Dave Jones
+ * Released under the General Public License (GPL).
+ *
+ * This file contains the linked list implementations for
+ * DEBUG_LIST.
+ */
+
+#include <linux/module.h>
+#include <linux/list.h>
+
+/*
+ * Insert a new entry between two known consecutive entries.
+ *
+ * This is only for internal list manipulation where we know
+ * the prev/next entries already!
+ */
+
+void __list_add(struct list_head *new,
+ struct list_head *prev,
+ struct list_head *next)
+{
+ if (unlikely(next->prev != prev)) {
+ printk(KERN_ERR "list_add corruption. next->prev should be %p, but was %p\n",
+ prev, next->prev);
+ BUG();
+ }
+ if (unlikely(prev->next != next)) {
+ printk(KERN_ERR "list_add corruption. prev->next should be %p, but was %p\n",
+ next, prev->next);
+ BUG();
+ }
+ next->prev = new;
+ new->next = next;
+ new->prev = prev;
+ prev->next = new;
+}
+EXPORT_SYMBOL(__list_add);
+
+/**
+ * list_add - add a new entry
+ * @new: new entry to be added
+ * @head: list head to add it after
+ *
+ * Insert a new entry after the specified head.
+ * This is good for implementing stacks.
+ */
+void list_add(struct list_head *new, struct list_head *head)
+{
+ __list_add(new, head, head->next);
+}
+EXPORT_SYMBOL(list_add);
+
+/**
+ * list_del - deletes entry from list.
+ * @entry: the element to delete from the list.
+ * Note: list_empty on entry does not return true after this, the entry is
+ * in an undefined state.
+ */
+void list_del(struct list_head *entry)
+{
+ if (unlikely(entry->prev->next != entry)) {
+ printk(KERN_ERR "list_del corruption. prev->next should be %p, "
+ "but was %p\n", entry, entry->prev->next);
+ BUG();
+ }
+ if (unlikely(entry->next->prev != entry)) {
+ printk(KERN_ERR "list_del corruption. next->prev should be %p, "
+ "but was %p\n", entry, entry->next->prev);
+ BUG();
+ }
+ __list_del(entry->prev, entry->next);
+ entry->next = LIST_POISON1;
+ entry->prev = LIST_POISON2;
+}
+EXPORT_SYMBOL(list_del);
diff --git a/lib/rbtree.c b/lib/rbtree.c
index 1e55ba1c2edf..48499c2d88cc 100644
--- a/lib/rbtree.c
+++ b/lib/rbtree.c
@@ -322,6 +322,9 @@ struct rb_node *rb_next(struct rb_node *node)
{
struct rb_node *parent;
+ if (rb_parent(node) == node)
+ return NULL;
+
/* If we have a right-hand child, go down and then left as far
as we can. */
if (node->rb_right) {
@@ -348,6 +351,9 @@ struct rb_node *rb_prev(struct rb_node *node)
{
struct rb_node *parent;
+ if (rb_parent(node) == node)
+ return NULL;
+
/* If we have a left-hand child, go down and then right as far
as we can. */
if (node->rb_left) {
diff --git a/lib/rwsem.c b/lib/rwsem.c
index b322421c2969..901d0e7da892 100644
--- a/lib/rwsem.c
+++ b/lib/rwsem.c
@@ -146,7 +146,7 @@ __rwsem_do_wake(struct rw_semaphore *sem, int downgrading)
/*
* wait for a lock to be granted
*/
-static inline struct rw_semaphore *
+static struct rw_semaphore *
rwsem_down_failed_common(struct rw_semaphore *sem,
struct rwsem_waiter *waiter, signed long adjustment)
{
diff --git a/lib/sort.c b/lib/sort.c
index 5f3b51ffa1dc..488788b341cb 100644
--- a/lib/sort.c
+++ b/lib/sort.c
@@ -49,15 +49,15 @@ void sort(void *base, size_t num, size_t size,
void (*swap)(void *, void *, int size))
{
/* pre-scale counters for performance */
- int i = (num/2) * size, n = num * size, c, r;
+ int i = (num/2 - 1) * size, n = num * size, c, r;
if (!swap)
swap = (size == 4 ? u32_swap : generic_swap);
/* heapify */
for ( ; i >= 0; i -= size) {
- for (r = i; r * 2 < n; r = c) {
- c = r * 2;
+ for (r = i; r * 2 + size < n; r = c) {
+ c = r * 2 + size;
if (c < n - size && cmp(base + c, base + c + size) < 0)
c += size;
if (cmp(base + r, base + c) >= 0)
@@ -69,8 +69,8 @@ void sort(void *base, size_t num, size_t size,
/* sort */
for (i = n - size; i >= 0; i -= size) {
swap(base, base + i, size);
- for (r = 0; r * 2 < i; r = c) {
- c = r * 2;
+ for (r = 0; r * 2 + size < i; r = c) {
+ c = r * 2 + size;
if (c < i - size && cmp(base + c, base + c + size) < 0)
c += size;
if (cmp(base + r, base + c) >= 0)
diff --git a/lib/spinlock_debug.c b/lib/spinlock_debug.c
index 58c577dd82e5..dafaf1de2491 100644
--- a/lib/spinlock_debug.c
+++ b/lib/spinlock_debug.c
@@ -99,11 +99,12 @@ static inline void debug_spin_unlock(spinlock_t *lock)
static void __spin_lock_debug(spinlock_t *lock)
{
- int print_once = 1;
u64 i;
+ u64 loops = loops_per_jiffy * HZ;
+ int print_once = 1;
for (;;) {
- for (i = 0; i < loops_per_jiffy * HZ; i++) {
+ for (i = 0; i < loops; i++) {
if (__raw_spin_trylock(&lock->raw_lock))
return;
__delay(1);
@@ -165,11 +166,12 @@ static void rwlock_bug(rwlock_t *lock, const char *msg)
#if 0 /* __write_lock_debug() can lock up - maybe this can too? */
static void __read_lock_debug(rwlock_t *lock)
{
- int print_once = 1;
u64 i;
+ u64 loops = loops_per_jiffy * HZ;
+ int print_once = 1;
for (;;) {
- for (i = 0; i < loops_per_jiffy * HZ; i++) {
+ for (i = 0; i < loops; i++) {
if (__raw_read_trylock(&lock->raw_lock))
return;
__delay(1);
@@ -239,11 +241,12 @@ static inline void debug_write_unlock(rwlock_t *lock)
#if 0 /* This can cause lockups */
static void __write_lock_debug(rwlock_t *lock)
{
- int print_once = 1;
u64 i;
+ u64 loops = loops_per_jiffy * HZ;
+ int print_once = 1;
for (;;) {
- for (i = 0; i < loops_per_jiffy * HZ; i++) {
+ for (i = 0; i < loops; i++) {
if (__raw_write_trylock(&lock->raw_lock))
return;
__delay(1);
diff --git a/lib/ts_fsm.c b/lib/ts_fsm.c
index 87847c2ae9e2..af575b61526b 100644
--- a/lib/ts_fsm.c
+++ b/lib/ts_fsm.c
@@ -12,13 +12,13 @@
*
* A finite state machine consists of n states (struct ts_fsm_token)
* representing the pattern as a finite automation. The data is read
- * sequentially on a octet basis. Every state token specifies the number
+ * sequentially on an octet basis. Every state token specifies the number
* of recurrences and the type of value accepted which can be either a
* specific character or ctype based set of characters. The available
* type of recurrences include 1, (0|1), [0 n], and [1 n].
*
- * The algorithm differs between strict/non-strict mode specyfing
- * whether the pattern has to start at the first octect. Strict mode
+ * The algorithm differs between strict/non-strict mode specifying
+ * whether the pattern has to start at the first octet. Strict mode
* is enabled by default and can be disabled by inserting
* TS_FSM_HEAD_IGNORE as the first token in the chain.
*
@@ -44,7 +44,7 @@ struct ts_fsm
#define _W 0x200 /* wildcard */
/* Map to _ctype flags and some magic numbers */
-static u16 token_map[TS_FSM_TYPE_MAX+1] = {
+static const u16 token_map[TS_FSM_TYPE_MAX+1] = {
[TS_FSM_SPECIFIC] = 0,
[TS_FSM_WILDCARD] = _W,
[TS_FSM_CNTRL] = _C,
@@ -61,7 +61,7 @@ static u16 token_map[TS_FSM_TYPE_MAX+1] = {
[TS_FSM_ASCII] = _A,
};
-static u16 token_lookup_tbl[256] = {
+static const u16 token_lookup_tbl[256] = {
_W|_A|_C, _W|_A|_C, _W|_A|_C, _W|_A|_C, /* 0- 3 */
_W|_A|_C, _W|_A|_C, _W|_A|_C, _W|_A|_C, /* 4- 7 */
_W|_A|_C, _W|_A|_C|_S, _W|_A|_C|_S, _W|_A|_C|_S, /* 8- 11 */
diff --git a/mm/Kconfig b/mm/Kconfig
index 8f5b45615f7b..5d88489ef2de 100644
--- a/mm/Kconfig
+++ b/mm/Kconfig
@@ -115,12 +115,17 @@ config SPARSEMEM_EXTREME
# eventually, we can have this option just 'select SPARSEMEM'
config MEMORY_HOTPLUG
bool "Allow for memory hot-add"
- depends on SPARSEMEM && HOTPLUG && !SOFTWARE_SUSPEND && ARCH_ENABLE_MEMORY_HOTPLUG
+ depends on SPARSEMEM || X86_64_ACPI_NUMA
+ depends on HOTPLUG && !SOFTWARE_SUSPEND && ARCH_ENABLE_MEMORY_HOTPLUG
depends on (IA64 || X86 || PPC64)
comment "Memory hotplug is currently incompatible with Software Suspend"
depends on SPARSEMEM && HOTPLUG && SOFTWARE_SUSPEND
+config MEMORY_HOTPLUG_SPARSE
+ def_bool y
+ depends on SPARSEMEM && MEMORY_HOTPLUG
+
# Heavily threaded applications may benefit from splitting the mm-wide
# page_table_lock, so that faults on different parts of the user address
# space can be handled with less contention: split it at this NR_CPUS.
diff --git a/mm/Makefile b/mm/Makefile
index 60c56c0b5e10..12b3a4eee88d 100644
--- a/mm/Makefile
+++ b/mm/Makefile
@@ -12,11 +12,15 @@ obj-y := bootmem.o filemap.o mempool.o oom_kill.o fadvise.o \
readahead.o swap.o truncate.o vmscan.o \
prio_tree.o util.o mmzone.o vmstat.o $(mmu-y)
+ifeq ($(CONFIG_MMU)$(CONFIG_BLOCK),yy)
+obj-y += bounce.o
+endif
obj-$(CONFIG_SWAP) += page_io.o swap_state.o swapfile.o thrash.o
obj-$(CONFIG_HUGETLBFS) += hugetlb.o
obj-$(CONFIG_NUMA) += mempolicy.o
obj-$(CONFIG_SPARSEMEM) += sparse.o
obj-$(CONFIG_SHMEM) += shmem.o
+obj-$(CONFIG_TMPFS_POSIX_ACL) += shmem_acl.o
obj-$(CONFIG_TINY_SHMEM) += tiny-shmem.o
obj-$(CONFIG_SLOB) += slob.o
obj-$(CONFIG_SLAB) += slab.o
diff --git a/mm/bounce.c b/mm/bounce.c
new file mode 100644
index 000000000000..e4b62d2a4024
--- /dev/null
+++ b/mm/bounce.c
@@ -0,0 +1,302 @@
+/* bounce buffer handling for block devices
+ *
+ * - Split from highmem.c
+ */
+
+#include <linux/mm.h>
+#include <linux/module.h>
+#include <linux/swap.h>
+#include <linux/bio.h>
+#include <linux/pagemap.h>
+#include <linux/mempool.h>
+#include <linux/blkdev.h>
+#include <linux/init.h>
+#include <linux/hash.h>
+#include <linux/highmem.h>
+#include <linux/blktrace_api.h>
+#include <asm/tlbflush.h>
+
+#define POOL_SIZE 64
+#define ISA_POOL_SIZE 16
+
+static mempool_t *page_pool, *isa_page_pool;
+
+#ifdef CONFIG_HIGHMEM
+static __init int init_emergency_pool(void)
+{
+ struct sysinfo i;
+ si_meminfo(&i);
+ si_swapinfo(&i);
+
+ if (!i.totalhigh)
+ return 0;
+
+ page_pool = mempool_create_page_pool(POOL_SIZE, 0);
+ BUG_ON(!page_pool);
+ printk("highmem bounce pool size: %d pages\n", POOL_SIZE);
+
+ return 0;
+}
+
+__initcall(init_emergency_pool);
+
+/*
+ * highmem version, map in to vec
+ */
+static void bounce_copy_vec(struct bio_vec *to, unsigned char *vfrom)
+{
+ unsigned long flags;
+ unsigned char *vto;
+
+ local_irq_save(flags);
+ vto = kmap_atomic(to->bv_page, KM_BOUNCE_READ);
+ memcpy(vto + to->bv_offset, vfrom, to->bv_len);
+ kunmap_atomic(vto, KM_BOUNCE_READ);
+ local_irq_restore(flags);
+}
+
+#else /* CONFIG_HIGHMEM */
+
+#define bounce_copy_vec(to, vfrom) \
+ memcpy(page_address((to)->bv_page) + (to)->bv_offset, vfrom, (to)->bv_len)
+
+#endif /* CONFIG_HIGHMEM */
+
+/*
+ * allocate pages in the DMA region for the ISA pool
+ */
+static void *mempool_alloc_pages_isa(gfp_t gfp_mask, void *data)
+{
+ return mempool_alloc_pages(gfp_mask | GFP_DMA, data);
+}
+
+/*
+ * gets called "every" time someone init's a queue with BLK_BOUNCE_ISA
+ * as the max address, so check if the pool has already been created.
+ */
+int init_emergency_isa_pool(void)
+{
+ if (isa_page_pool)
+ return 0;
+
+ isa_page_pool = mempool_create(ISA_POOL_SIZE, mempool_alloc_pages_isa,
+ mempool_free_pages, (void *) 0);
+ BUG_ON(!isa_page_pool);
+
+ printk("isa bounce pool size: %d pages\n", ISA_POOL_SIZE);
+ return 0;
+}
+
+/*
+ * Simple bounce buffer support for highmem pages. Depending on the
+ * queue gfp mask set, *to may or may not be a highmem page. kmap it
+ * always, it will do the Right Thing
+ */
+static void copy_to_high_bio_irq(struct bio *to, struct bio *from)
+{
+ unsigned char *vfrom;
+ struct bio_vec *tovec, *fromvec;
+ int i;
+
+ __bio_for_each_segment(tovec, to, i, 0) {
+ fromvec = from->bi_io_vec + i;
+
+ /*
+ * not bounced
+ */
+ if (tovec->bv_page == fromvec->bv_page)
+ continue;
+
+ /*
+ * fromvec->bv_offset and fromvec->bv_len might have been
+ * modified by the block layer, so use the original copy,
+ * bounce_copy_vec already uses tovec->bv_len
+ */
+ vfrom = page_address(fromvec->bv_page) + tovec->bv_offset;
+
+ flush_dcache_page(tovec->bv_page);
+ bounce_copy_vec(tovec, vfrom);
+ }
+}
+
+static void bounce_end_io(struct bio *bio, mempool_t *pool, int err)
+{
+ struct bio *bio_orig = bio->bi_private;
+ struct bio_vec *bvec, *org_vec;
+ int i;
+
+ if (test_bit(BIO_EOPNOTSUPP, &bio->bi_flags))
+ set_bit(BIO_EOPNOTSUPP, &bio_orig->bi_flags);
+
+ /*
+ * free up bounce indirect pages used
+ */
+ __bio_for_each_segment(bvec, bio, i, 0) {
+ org_vec = bio_orig->bi_io_vec + i;
+ if (bvec->bv_page == org_vec->bv_page)
+ continue;
+
+ dec_zone_page_state(bvec->bv_page, NR_BOUNCE);
+ mempool_free(bvec->bv_page, pool);
+ }
+
+ bio_endio(bio_orig, bio_orig->bi_size, err);
+ bio_put(bio);
+}
+
+static int bounce_end_io_write(struct bio *bio, unsigned int bytes_done, int err)
+{
+ if (bio->bi_size)
+ return 1;
+
+ bounce_end_io(bio, page_pool, err);
+ return 0;
+}
+
+static int bounce_end_io_write_isa(struct bio *bio, unsigned int bytes_done, int err)
+{
+ if (bio->bi_size)
+ return 1;
+
+ bounce_end_io(bio, isa_page_pool, err);
+ return 0;
+}
+
+static void __bounce_end_io_read(struct bio *bio, mempool_t *pool, int err)
+{
+ struct bio *bio_orig = bio->bi_private;
+
+ if (test_bit(BIO_UPTODATE, &bio->bi_flags))
+ copy_to_high_bio_irq(bio_orig, bio);
+
+ bounce_end_io(bio, pool, err);
+}
+
+static int bounce_end_io_read(struct bio *bio, unsigned int bytes_done, int err)
+{
+ if (bio->bi_size)
+ return 1;
+
+ __bounce_end_io_read(bio, page_pool, err);
+ return 0;
+}
+
+static int bounce_end_io_read_isa(struct bio *bio, unsigned int bytes_done, int err)
+{
+ if (bio->bi_size)
+ return 1;
+
+ __bounce_end_io_read(bio, isa_page_pool, err);
+ return 0;
+}
+
+static void __blk_queue_bounce(request_queue_t *q, struct bio **bio_orig,
+ mempool_t *pool)
+{
+ struct page *page;
+ struct bio *bio = NULL;
+ int i, rw = bio_data_dir(*bio_orig);
+ struct bio_vec *to, *from;
+
+ bio_for_each_segment(from, *bio_orig, i) {
+ page = from->bv_page;
+
+ /*
+ * is destination page below bounce pfn?
+ */
+ if (page_to_pfn(page) < q->bounce_pfn)
+ continue;
+
+ /*
+ * irk, bounce it
+ */
+ if (!bio)
+ bio = bio_alloc(GFP_NOIO, (*bio_orig)->bi_vcnt);
+
+ to = bio->bi_io_vec + i;
+
+ to->bv_page = mempool_alloc(pool, q->bounce_gfp);
+ to->bv_len = from->bv_len;
+ to->bv_offset = from->bv_offset;
+ inc_zone_page_state(to->bv_page, NR_BOUNCE);
+
+ if (rw == WRITE) {
+ char *vto, *vfrom;
+
+ flush_dcache_page(from->bv_page);
+ vto = page_address(to->bv_page) + to->bv_offset;
+ vfrom = kmap(from->bv_page) + from->bv_offset;
+ memcpy(vto, vfrom, to->bv_len);
+ kunmap(from->bv_page);
+ }
+ }
+
+ /*
+ * no pages bounced
+ */
+ if (!bio)
+ return;
+
+ /*
+ * at least one page was bounced, fill in possible non-highmem
+ * pages
+ */
+ __bio_for_each_segment(from, *bio_orig, i, 0) {
+ to = bio_iovec_idx(bio, i);
+ if (!to->bv_page) {
+ to->bv_page = from->bv_page;
+ to->bv_len = from->bv_len;
+ to->bv_offset = from->bv_offset;
+ }
+ }
+
+ bio->bi_bdev = (*bio_orig)->bi_bdev;
+ bio->bi_flags |= (1 << BIO_BOUNCED);
+ bio->bi_sector = (*bio_orig)->bi_sector;
+ bio->bi_rw = (*bio_orig)->bi_rw;
+
+ bio->bi_vcnt = (*bio_orig)->bi_vcnt;
+ bio->bi_idx = (*bio_orig)->bi_idx;
+ bio->bi_size = (*bio_orig)->bi_size;
+
+ if (pool == page_pool) {
+ bio->bi_end_io = bounce_end_io_write;
+ if (rw == READ)
+ bio->bi_end_io = bounce_end_io_read;
+ } else {
+ bio->bi_end_io = bounce_end_io_write_isa;
+ if (rw == READ)
+ bio->bi_end_io = bounce_end_io_read_isa;
+ }
+
+ bio->bi_private = *bio_orig;
+ *bio_orig = bio;
+}
+
+void blk_queue_bounce(request_queue_t *q, struct bio **bio_orig)
+{
+ mempool_t *pool;
+
+ /*
+ * for non-isa bounce case, just check if the bounce pfn is equal
+ * to or bigger than the highest pfn in the system -- in that case,
+ * don't waste time iterating over bio segments
+ */
+ if (!(q->bounce_gfp & GFP_DMA)) {
+ if (q->bounce_pfn >= blk_max_pfn)
+ return;
+ pool = page_pool;
+ } else {
+ BUG_ON(!isa_page_pool);
+ pool = isa_page_pool;
+ }
+
+ blk_add_trace_bio(q, *bio_orig, BLK_TA_BOUNCE);
+
+ /*
+ * slow path
+ */
+ __blk_queue_bounce(q, bio_orig, pool);
+}
+
+EXPORT_SYMBOL(blk_queue_bounce);
diff --git a/mm/filemap.c b/mm/filemap.c
index afcdc72b5e90..ec469235985d 100644
--- a/mm/filemap.c
+++ b/mm/filemap.c
@@ -1149,13 +1149,14 @@ success:
* that can use the page cache directly.
*/
ssize_t
-__generic_file_aio_read(struct kiocb *iocb, const struct iovec *iov,
- unsigned long nr_segs, loff_t *ppos)
+generic_file_aio_read(struct kiocb *iocb, const struct iovec *iov,
+ unsigned long nr_segs, loff_t pos)
{
struct file *filp = iocb->ki_filp;
ssize_t retval;
unsigned long seg;
size_t count;
+ loff_t *ppos = &iocb->ki_pos;
count = 0;
for (seg = 0; seg < nr_segs; seg++) {
@@ -1179,7 +1180,7 @@ __generic_file_aio_read(struct kiocb *iocb, const struct iovec *iov,
/* coalesce the iovecs and go direct-to-BIO for O_DIRECT */
if (filp->f_flags & O_DIRECT) {
- loff_t pos = *ppos, size;
+ loff_t size;
struct address_space *mapping;
struct inode *inode;
@@ -1223,33 +1224,8 @@ __generic_file_aio_read(struct kiocb *iocb, const struct iovec *iov,
out:
return retval;
}
-EXPORT_SYMBOL(__generic_file_aio_read);
-
-ssize_t
-generic_file_aio_read(struct kiocb *iocb, char __user *buf, size_t count, loff_t pos)
-{
- struct iovec local_iov = { .iov_base = buf, .iov_len = count };
-
- BUG_ON(iocb->ki_pos != pos);
- return __generic_file_aio_read(iocb, &local_iov, 1, &iocb->ki_pos);
-}
EXPORT_SYMBOL(generic_file_aio_read);
-ssize_t
-generic_file_read(struct file *filp, char __user *buf, size_t count, loff_t *ppos)
-{
- struct iovec local_iov = { .iov_base = buf, .iov_len = count };
- struct kiocb kiocb;
- ssize_t ret;
-
- init_sync_kiocb(&kiocb, filp);
- ret = __generic_file_aio_read(&kiocb, &local_iov, 1, ppos);
- if (-EIOCBQUEUED == ret)
- ret = wait_on_sync_kiocb(&kiocb);
- return ret;
-}
-EXPORT_SYMBOL(generic_file_read);
-
int file_send_actor(read_descriptor_t * desc, struct page *page, unsigned long offset, unsigned long size)
{
ssize_t written;
@@ -1471,7 +1447,7 @@ outside_data_content:
* accessible..
*/
if (area->vm_mm == current->mm)
- return NULL;
+ return NOPAGE_SIGBUS;
/* Fall through to the non-read-ahead case */
no_cached_page:
/*
@@ -1496,7 +1472,7 @@ no_cached_page:
*/
if (error == -ENOMEM)
return NOPAGE_OOM;
- return NULL;
+ return NOPAGE_SIGBUS;
page_not_uptodate:
if (!did_readaround) {
@@ -1565,7 +1541,7 @@ page_not_uptodate:
*/
shrink_readahead_size_eio(file, ra);
page_cache_release(page);
- return NULL;
+ return NOPAGE_SIGBUS;
}
EXPORT_SYMBOL(filemap_nopage);
@@ -2020,6 +1996,7 @@ inline int generic_write_checks(struct file *file, loff_t *pos, size_t *count, i
if (unlikely(*pos + *count > inode->i_sb->s_maxbytes))
*count = inode->i_sb->s_maxbytes - *pos;
} else {
+#ifdef CONFIG_BLOCK
loff_t isize;
if (bdev_read_only(I_BDEV(inode)))
return -EPERM;
@@ -2031,6 +2008,9 @@ inline int generic_write_checks(struct file *file, loff_t *pos, size_t *count, i
if (*pos + *count > isize)
*count = isize - *pos;
+#else
+ return -EPERM;
+#endif
}
return 0;
}
@@ -2311,22 +2291,22 @@ out:
current->backing_dev_info = NULL;
return written ? written : err;
}
-EXPORT_SYMBOL(generic_file_aio_write_nolock);
-ssize_t
-generic_file_aio_write_nolock(struct kiocb *iocb, const struct iovec *iov,
- unsigned long nr_segs, loff_t *ppos)
+ssize_t generic_file_aio_write_nolock(struct kiocb *iocb,
+ const struct iovec *iov, unsigned long nr_segs, loff_t pos)
{
struct file *file = iocb->ki_filp;
struct address_space *mapping = file->f_mapping;
struct inode *inode = mapping->host;
ssize_t ret;
- loff_t pos = *ppos;
- ret = __generic_file_aio_write_nolock(iocb, iov, nr_segs, ppos);
+ BUG_ON(iocb->ki_pos != pos);
+
+ ret = __generic_file_aio_write_nolock(iocb, iov, nr_segs,
+ &iocb->ki_pos);
if (ret > 0 && ((file->f_flags & O_SYNC) || IS_SYNC(inode))) {
- int err;
+ ssize_t err;
err = sync_page_range_nolock(inode, mapping, pos, ret);
if (err < 0)
@@ -2334,51 +2314,21 @@ generic_file_aio_write_nolock(struct kiocb *iocb, const struct iovec *iov,
}
return ret;
}
+EXPORT_SYMBOL(generic_file_aio_write_nolock);
-static ssize_t
-__generic_file_write_nolock(struct file *file, const struct iovec *iov,
- unsigned long nr_segs, loff_t *ppos)
-{
- struct kiocb kiocb;
- ssize_t ret;
-
- init_sync_kiocb(&kiocb, file);
- ret = __generic_file_aio_write_nolock(&kiocb, iov, nr_segs, ppos);
- if (ret == -EIOCBQUEUED)
- ret = wait_on_sync_kiocb(&kiocb);
- return ret;
-}
-
-ssize_t
-generic_file_write_nolock(struct file *file, const struct iovec *iov,
- unsigned long nr_segs, loff_t *ppos)
-{
- struct kiocb kiocb;
- ssize_t ret;
-
- init_sync_kiocb(&kiocb, file);
- ret = generic_file_aio_write_nolock(&kiocb, iov, nr_segs, ppos);
- if (-EIOCBQUEUED == ret)
- ret = wait_on_sync_kiocb(&kiocb);
- return ret;
-}
-EXPORT_SYMBOL(generic_file_write_nolock);
-
-ssize_t generic_file_aio_write(struct kiocb *iocb, const char __user *buf,
- size_t count, loff_t pos)
+ssize_t generic_file_aio_write(struct kiocb *iocb, const struct iovec *iov,
+ unsigned long nr_segs, loff_t pos)
{
struct file *file = iocb->ki_filp;
struct address_space *mapping = file->f_mapping;
struct inode *inode = mapping->host;
ssize_t ret;
- struct iovec local_iov = { .iov_base = (void __user *)buf,
- .iov_len = count };
BUG_ON(iocb->ki_pos != pos);
mutex_lock(&inode->i_mutex);
- ret = __generic_file_aio_write_nolock(iocb, &local_iov, 1,
- &iocb->ki_pos);
+ ret = __generic_file_aio_write_nolock(iocb, iov, nr_segs,
+ &iocb->ki_pos);
mutex_unlock(&inode->i_mutex);
if (ret > 0 && ((file->f_flags & O_SYNC) || IS_SYNC(inode))) {
@@ -2392,66 +2342,6 @@ ssize_t generic_file_aio_write(struct kiocb *iocb, const char __user *buf,
}
EXPORT_SYMBOL(generic_file_aio_write);
-ssize_t generic_file_write(struct file *file, const char __user *buf,
- size_t count, loff_t *ppos)
-{
- struct address_space *mapping = file->f_mapping;
- struct inode *inode = mapping->host;
- ssize_t ret;
- struct iovec local_iov = { .iov_base = (void __user *)buf,
- .iov_len = count };
-
- mutex_lock(&inode->i_mutex);
- ret = __generic_file_write_nolock(file, &local_iov, 1, ppos);
- mutex_unlock(&inode->i_mutex);
-
- if (ret > 0 && ((file->f_flags & O_SYNC) || IS_SYNC(inode))) {
- ssize_t err;
-
- err = sync_page_range(inode, mapping, *ppos - ret, ret);
- if (err < 0)
- ret = err;
- }
- return ret;
-}
-EXPORT_SYMBOL(generic_file_write);
-
-ssize_t generic_file_readv(struct file *filp, const struct iovec *iov,
- unsigned long nr_segs, loff_t *ppos)
-{
- struct kiocb kiocb;
- ssize_t ret;
-
- init_sync_kiocb(&kiocb, filp);
- ret = __generic_file_aio_read(&kiocb, iov, nr_segs, ppos);
- if (-EIOCBQUEUED == ret)
- ret = wait_on_sync_kiocb(&kiocb);
- return ret;
-}
-EXPORT_SYMBOL(generic_file_readv);
-
-ssize_t generic_file_writev(struct file *file, const struct iovec *iov,
- unsigned long nr_segs, loff_t *ppos)
-{
- struct address_space *mapping = file->f_mapping;
- struct inode *inode = mapping->host;
- ssize_t ret;
-
- mutex_lock(&inode->i_mutex);
- ret = __generic_file_write_nolock(file, iov, nr_segs, ppos);
- mutex_unlock(&inode->i_mutex);
-
- if (ret > 0 && ((file->f_flags & O_SYNC) || IS_SYNC(inode))) {
- int err;
-
- err = sync_page_range(inode, mapping, *ppos - ret, ret);
- if (err < 0)
- ret = err;
- }
- return ret;
-}
-EXPORT_SYMBOL(generic_file_writev);
-
/*
* Called under i_mutex for writes to S_ISREG files. Returns -EIO if something
* went wrong during pagecache shootdown.
@@ -2491,3 +2381,33 @@ generic_file_direct_IO(int rw, struct kiocb *iocb, const struct iovec *iov,
}
return retval;
}
+
+/**
+ * try_to_release_page() - release old fs-specific metadata on a page
+ *
+ * @page: the page which the kernel is trying to free
+ * @gfp_mask: memory allocation flags (and I/O mode)
+ *
+ * The address_space is to try to release any data against the page
+ * (presumably at page->private). If the release was successful, return `1'.
+ * Otherwise return zero.
+ *
+ * The @gfp_mask argument specifies whether I/O may be performed to release
+ * this page (__GFP_IO), and whether the call may block (__GFP_WAIT).
+ *
+ * NOTE: @gfp_mask may go away, and this function may become non-blocking.
+ */
+int try_to_release_page(struct page *page, gfp_t gfp_mask)
+{
+ struct address_space * const mapping = page->mapping;
+
+ BUG_ON(!PageLocked(page));
+ if (PageWriteback(page))
+ return 0;
+
+ if (mapping && mapping->a_ops->releasepage)
+ return mapping->a_ops->releasepage(page, gfp_mask);
+ return try_to_free_buffers(page);
+}
+
+EXPORT_SYMBOL(try_to_release_page);
diff --git a/mm/fremap.c b/mm/fremap.c
index aa30618ec6b2..7a9d0f5d246d 100644
--- a/mm/fremap.c
+++ b/mm/fremap.c
@@ -39,7 +39,7 @@ static int zap_pte(struct mm_struct *mm, struct vm_area_struct *vma,
} else {
if (!pte_file(pte))
free_swap_and_cache(pte_to_swp_entry(pte));
- pte_clear(mm, addr, ptep);
+ pte_clear_not_present_full(mm, addr, ptep, 0);
}
return !!page;
}
diff --git a/mm/highmem.c b/mm/highmem.c
index ee5519b176ee..0206e7e5018c 100644
--- a/mm/highmem.c
+++ b/mm/highmem.c
@@ -29,13 +29,6 @@
#include <linux/blktrace_api.h>
#include <asm/tlbflush.h>
-static mempool_t *page_pool, *isa_page_pool;
-
-static void *mempool_alloc_pages_isa(gfp_t gfp_mask, void *data)
-{
- return mempool_alloc_pages(gfp_mask | GFP_DMA, data);
-}
-
/*
* Virtual_count is not a pure "count".
* 0 means that it is not mapped, and has not been mapped
@@ -217,282 +210,8 @@ void fastcall kunmap_high(struct page *page)
}
EXPORT_SYMBOL(kunmap_high);
-
-#define POOL_SIZE 64
-
-static __init int init_emergency_pool(void)
-{
- struct sysinfo i;
- si_meminfo(&i);
- si_swapinfo(&i);
-
- if (!i.totalhigh)
- return 0;
-
- page_pool = mempool_create_page_pool(POOL_SIZE, 0);
- BUG_ON(!page_pool);
- printk("highmem bounce pool size: %d pages\n", POOL_SIZE);
-
- return 0;
-}
-
-__initcall(init_emergency_pool);
-
-/*
- * highmem version, map in to vec
- */
-static void bounce_copy_vec(struct bio_vec *to, unsigned char *vfrom)
-{
- unsigned long flags;
- unsigned char *vto;
-
- local_irq_save(flags);
- vto = kmap_atomic(to->bv_page, KM_BOUNCE_READ);
- memcpy(vto + to->bv_offset, vfrom, to->bv_len);
- kunmap_atomic(vto, KM_BOUNCE_READ);
- local_irq_restore(flags);
-}
-
-#else /* CONFIG_HIGHMEM */
-
-#define bounce_copy_vec(to, vfrom) \
- memcpy(page_address((to)->bv_page) + (to)->bv_offset, vfrom, (to)->bv_len)
-
#endif
-#define ISA_POOL_SIZE 16
-
-/*
- * gets called "every" time someone init's a queue with BLK_BOUNCE_ISA
- * as the max address, so check if the pool has already been created.
- */
-int init_emergency_isa_pool(void)
-{
- if (isa_page_pool)
- return 0;
-
- isa_page_pool = mempool_create(ISA_POOL_SIZE, mempool_alloc_pages_isa,
- mempool_free_pages, (void *) 0);
- BUG_ON(!isa_page_pool);
-
- printk("isa bounce pool size: %d pages\n", ISA_POOL_SIZE);
- return 0;
-}
-
-/*
- * Simple bounce buffer support for highmem pages. Depending on the
- * queue gfp mask set, *to may or may not be a highmem page. kmap it
- * always, it will do the Right Thing
- */
-static void copy_to_high_bio_irq(struct bio *to, struct bio *from)
-{
- unsigned char *vfrom;
- struct bio_vec *tovec, *fromvec;
- int i;
-
- __bio_for_each_segment(tovec, to, i, 0) {
- fromvec = from->bi_io_vec + i;
-
- /*
- * not bounced
- */
- if (tovec->bv_page == fromvec->bv_page)
- continue;
-
- /*
- * fromvec->bv_offset and fromvec->bv_len might have been
- * modified by the block layer, so use the original copy,
- * bounce_copy_vec already uses tovec->bv_len
- */
- vfrom = page_address(fromvec->bv_page) + tovec->bv_offset;
-
- flush_dcache_page(tovec->bv_page);
- bounce_copy_vec(tovec, vfrom);
- }
-}
-
-static void bounce_end_io(struct bio *bio, mempool_t *pool, int err)
-{
- struct bio *bio_orig = bio->bi_private;
- struct bio_vec *bvec, *org_vec;
- int i;
-
- if (test_bit(BIO_EOPNOTSUPP, &bio->bi_flags))
- set_bit(BIO_EOPNOTSUPP, &bio_orig->bi_flags);
-
- /*
- * free up bounce indirect pages used
- */
- __bio_for_each_segment(bvec, bio, i, 0) {
- org_vec = bio_orig->bi_io_vec + i;
- if (bvec->bv_page == org_vec->bv_page)
- continue;
-
- dec_zone_page_state(bvec->bv_page, NR_BOUNCE);
- mempool_free(bvec->bv_page, pool);
- }
-
- bio_endio(bio_orig, bio_orig->bi_size, err);
- bio_put(bio);
-}
-
-static int bounce_end_io_write(struct bio *bio, unsigned int bytes_done, int err)
-{
- if (bio->bi_size)
- return 1;
-
- bounce_end_io(bio, page_pool, err);
- return 0;
-}
-
-static int bounce_end_io_write_isa(struct bio *bio, unsigned int bytes_done, int err)
-{
- if (bio->bi_size)
- return 1;
-
- bounce_end_io(bio, isa_page_pool, err);
- return 0;
-}
-
-static void __bounce_end_io_read(struct bio *bio, mempool_t *pool, int err)
-{
- struct bio *bio_orig = bio->bi_private;
-
- if (test_bit(BIO_UPTODATE, &bio->bi_flags))
- copy_to_high_bio_irq(bio_orig, bio);
-
- bounce_end_io(bio, pool, err);
-}
-
-static int bounce_end_io_read(struct bio *bio, unsigned int bytes_done, int err)
-{
- if (bio->bi_size)
- return 1;
-
- __bounce_end_io_read(bio, page_pool, err);
- return 0;
-}
-
-static int bounce_end_io_read_isa(struct bio *bio, unsigned int bytes_done, int err)
-{
- if (bio->bi_size)
- return 1;
-
- __bounce_end_io_read(bio, isa_page_pool, err);
- return 0;
-}
-
-static void __blk_queue_bounce(request_queue_t *q, struct bio **bio_orig,
- mempool_t *pool)
-{
- struct page *page;
- struct bio *bio = NULL;
- int i, rw = bio_data_dir(*bio_orig);
- struct bio_vec *to, *from;
-
- bio_for_each_segment(from, *bio_orig, i) {
- page = from->bv_page;
-
- /*
- * is destination page below bounce pfn?
- */
- if (page_to_pfn(page) < q->bounce_pfn)
- continue;
-
- /*
- * irk, bounce it
- */
- if (!bio)
- bio = bio_alloc(GFP_NOIO, (*bio_orig)->bi_vcnt);
-
- to = bio->bi_io_vec + i;
-
- to->bv_page = mempool_alloc(pool, q->bounce_gfp);
- to->bv_len = from->bv_len;
- to->bv_offset = from->bv_offset;
- inc_zone_page_state(to->bv_page, NR_BOUNCE);
-
- if (rw == WRITE) {
- char *vto, *vfrom;
-
- flush_dcache_page(from->bv_page);
- vto = page_address(to->bv_page) + to->bv_offset;
- vfrom = kmap(from->bv_page) + from->bv_offset;
- memcpy(vto, vfrom, to->bv_len);
- kunmap(from->bv_page);
- }
- }
-
- /*
- * no pages bounced
- */
- if (!bio)
- return;
-
- /*
- * at least one page was bounced, fill in possible non-highmem
- * pages
- */
- __bio_for_each_segment(from, *bio_orig, i, 0) {
- to = bio_iovec_idx(bio, i);
- if (!to->bv_page) {
- to->bv_page = from->bv_page;
- to->bv_len = from->bv_len;
- to->bv_offset = from->bv_offset;
- }
- }
-
- bio->bi_bdev = (*bio_orig)->bi_bdev;
- bio->bi_flags |= (1 << BIO_BOUNCED);
- bio->bi_sector = (*bio_orig)->bi_sector;
- bio->bi_rw = (*bio_orig)->bi_rw;
-
- bio->bi_vcnt = (*bio_orig)->bi_vcnt;
- bio->bi_idx = (*bio_orig)->bi_idx;
- bio->bi_size = (*bio_orig)->bi_size;
-
- if (pool == page_pool) {
- bio->bi_end_io = bounce_end_io_write;
- if (rw == READ)
- bio->bi_end_io = bounce_end_io_read;
- } else {
- bio->bi_end_io = bounce_end_io_write_isa;
- if (rw == READ)
- bio->bi_end_io = bounce_end_io_read_isa;
- }
-
- bio->bi_private = *bio_orig;
- *bio_orig = bio;
-}
-
-void blk_queue_bounce(request_queue_t *q, struct bio **bio_orig)
-{
- mempool_t *pool;
-
- /*
- * for non-isa bounce case, just check if the bounce pfn is equal
- * to or bigger than the highest pfn in the system -- in that case,
- * don't waste time iterating over bio segments
- */
- if (!(q->bounce_gfp & GFP_DMA)) {
- if (q->bounce_pfn >= blk_max_pfn)
- return;
- pool = page_pool;
- } else {
- BUG_ON(!isa_page_pool);
- pool = isa_page_pool;
- }
-
- blk_add_trace_bio(q, *bio_orig, BLK_TA_BOUNCE);
-
- /*
- * slow path
- */
- __blk_queue_bounce(q, bio_orig, pool);
-}
-
-EXPORT_SYMBOL(blk_queue_bounce);
-
#if defined(HASHED_PAGE_VIRTUAL)
#define PA_HASH_ORDER 7
diff --git a/mm/memory.c b/mm/memory.c
index 601159a46ab6..9cf3f341a28a 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -467,7 +467,7 @@ copy_one_pte(struct mm_struct *dst_mm, struct mm_struct *src_mm,
*/
if (is_cow_mapping(vm_flags)) {
ptep_set_wrprotect(src_mm, addr, src_pte);
- pte = *src_pte;
+ pte = pte_wrprotect(pte);
}
/*
@@ -506,6 +506,7 @@ again:
src_pte = pte_offset_map_nested(src_pmd, addr);
src_ptl = pte_lockptr(src_mm, src_pmd);
spin_lock_nested(src_ptl, SINGLE_DEPTH_NESTING);
+ arch_enter_lazy_mmu_mode();
do {
/*
@@ -527,6 +528,7 @@ again:
progress += 8;
} while (dst_pte++, src_pte++, addr += PAGE_SIZE, addr != end);
+ arch_leave_lazy_mmu_mode();
spin_unlock(src_ptl);
pte_unmap_nested(src_pte - 1);
add_mm_rss(dst_mm, rss[0], rss[1]);
@@ -628,6 +630,7 @@ static unsigned long zap_pte_range(struct mmu_gather *tlb,
int anon_rss = 0;
pte = pte_offset_map_lock(mm, pmd, addr, &ptl);
+ arch_enter_lazy_mmu_mode();
do {
pte_t ptent = *pte;
if (pte_none(ptent)) {
@@ -690,10 +693,11 @@ static unsigned long zap_pte_range(struct mmu_gather *tlb,
continue;
if (!pte_file(ptent))
free_swap_and_cache(pte_to_swp_entry(ptent));
- pte_clear_full(mm, addr, pte, tlb->fullmm);
+ pte_clear_not_present_full(mm, addr, pte, tlb->fullmm);
} while (pte++, addr += PAGE_SIZE, (addr != end && *zap_work > 0));
add_mm_rss(mm, file_rss, anon_rss);
+ arch_leave_lazy_mmu_mode();
pte_unmap_unlock(pte - 1, ptl);
return addr;
@@ -1109,6 +1113,7 @@ static int zeromap_pte_range(struct mm_struct *mm, pmd_t *pmd,
pte = pte_alloc_map_lock(mm, pmd, addr, &ptl);
if (!pte)
return -ENOMEM;
+ arch_enter_lazy_mmu_mode();
do {
struct page *page = ZERO_PAGE(addr);
pte_t zero_pte = pte_wrprotect(mk_pte(page, prot));
@@ -1118,6 +1123,7 @@ static int zeromap_pte_range(struct mm_struct *mm, pmd_t *pmd,
BUG_ON(!pte_none(*pte));
set_pte_at(mm, addr, pte, zero_pte);
} while (pte++, addr += PAGE_SIZE, addr != end);
+ arch_leave_lazy_mmu_mode();
pte_unmap_unlock(pte - 1, ptl);
return 0;
}
@@ -1275,11 +1281,13 @@ static int remap_pte_range(struct mm_struct *mm, pmd_t *pmd,
pte = pte_alloc_map_lock(mm, pmd, addr, &ptl);
if (!pte)
return -ENOMEM;
+ arch_enter_lazy_mmu_mode();
do {
BUG_ON(!pte_none(*pte));
set_pte_at(mm, addr, pte, pfn_pte(pfn, prot));
pfn++;
} while (pte++, addr += PAGE_SIZE, addr != end);
+ arch_leave_lazy_mmu_mode();
pte_unmap_unlock(pte - 1, ptl);
return 0;
}
@@ -1577,7 +1585,14 @@ gotten:
entry = mk_pte(new_page, vma->vm_page_prot);
entry = maybe_mkwrite(pte_mkdirty(entry), vma);
lazy_mmu_prot_update(entry);
- ptep_establish(vma, address, page_table, entry);
+ /*
+ * Clear the pte entry and flush it first, before updating the
+ * pte with the new entry. This will avoid a race condition
+ * seen in the presence of one thread doing SMC and another
+ * thread doing COW.
+ */
+ ptep_clear_flush(vma, address, page_table);
+ set_pte_at(mm, address, page_table, entry);
update_mmu_cache(vma, address, entry);
lru_cache_add_active(new_page);
page_add_new_anon_rmap(new_page, vma, address);
diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c
index c37319542b70..fd678a662eae 100644
--- a/mm/memory_hotplug.c
+++ b/mm/memory_hotplug.c
@@ -13,6 +13,7 @@
#include <linux/compiler.h>
#include <linux/module.h>
#include <linux/pagevec.h>
+#include <linux/writeback.h>
#include <linux/slab.h>
#include <linux/sysctl.h>
#include <linux/cpu.h>
@@ -21,11 +22,41 @@
#include <linux/highmem.h>
#include <linux/vmalloc.h>
#include <linux/ioport.h>
+#include <linux/cpuset.h>
#include <asm/tlbflush.h>
-extern void zonetable_add(struct zone *zone, int nid, int zid, unsigned long pfn,
- unsigned long size);
+/* add this memory to iomem resource */
+static struct resource *register_memory_resource(u64 start, u64 size)
+{
+ struct resource *res;
+ res = kzalloc(sizeof(struct resource), GFP_KERNEL);
+ BUG_ON(!res);
+
+ res->name = "System RAM";
+ res->start = start;
+ res->end = start + size - 1;
+ res->flags = IORESOURCE_MEM;
+ if (request_resource(&iomem_resource, res) < 0) {
+ printk("System RAM resource %llx - %llx cannot be added\n",
+ (unsigned long long)res->start, (unsigned long long)res->end);
+ kfree(res);
+ res = NULL;
+ }
+ return res;
+}
+
+static void release_memory_resource(struct resource *res)
+{
+ if (!res)
+ return;
+ release_resource(res);
+ kfree(res);
+ return;
+}
+
+
+#ifdef CONFIG_MEMORY_HOTPLUG_SPARSE
static int __add_zone(struct zone *zone, unsigned long phys_start_pfn)
{
struct pglist_data *pgdat = zone->zone_pgdat;
@@ -45,8 +76,6 @@ static int __add_zone(struct zone *zone, unsigned long phys_start_pfn)
return 0;
}
-extern int sparse_add_one_section(struct zone *zone, unsigned long start_pfn,
- int nr_pages);
static int __add_section(struct zone *zone, unsigned long phys_start_pfn)
{
int nr_pages = PAGES_PER_SECTION;
@@ -191,8 +220,10 @@ int online_pages(unsigned long pfn, unsigned long nr_pages)
if (need_zonelists_rebuild)
build_all_zonelists();
vm_total_pages = nr_free_pagecache_pages();
+ writeback_set_ratelimit();
return 0;
}
+#endif /* CONFIG_MEMORY_HOTPLUG_SPARSE */
static pg_data_t *hotadd_new_pgdat(int nid, u64 start)
{
@@ -222,36 +253,6 @@ static void rollback_node_hotadd(int nid, pg_data_t *pgdat)
return;
}
-/* add this memory to iomem resource */
-static struct resource *register_memory_resource(u64 start, u64 size)
-{
- struct resource *res;
- res = kzalloc(sizeof(struct resource), GFP_KERNEL);
- BUG_ON(!res);
-
- res->name = "System RAM";
- res->start = start;
- res->end = start + size - 1;
- res->flags = IORESOURCE_MEM;
- if (request_resource(&iomem_resource, res) < 0) {
- printk("System RAM resource %llx - %llx cannot be added\n",
- (unsigned long long)res->start, (unsigned long long)res->end);
- kfree(res);
- res = NULL;
- }
- return res;
-}
-
-static void release_memory_resource(struct resource *res)
-{
- if (!res)
- return;
- release_resource(res);
- kfree(res);
- return;
-}
-
-
int add_memory(int nid, u64 start, u64 size)
{
@@ -283,6 +284,8 @@ int add_memory(int nid, u64 start, u64 size)
/* we online node here. we can't roll back from here. */
node_set_online(nid);
+ cpuset_track_online_nodes();
+
if (new_pgdat) {
ret = register_one_node(nid);
/*
diff --git a/mm/mempolicy.c b/mm/mempolicy.c
index cf18f0942553..25788b1b7fcf 100644
--- a/mm/mempolicy.c
+++ b/mm/mempolicy.c
@@ -1324,12 +1324,11 @@ struct mempolicy *__mpol_copy(struct mempolicy *old)
atomic_set(&new->refcnt, 1);
if (new->policy == MPOL_BIND) {
int sz = ksize(old->v.zonelist);
- new->v.zonelist = kmalloc(sz, SLAB_KERNEL);
+ new->v.zonelist = kmemdup(old->v.zonelist, sz, SLAB_KERNEL);
if (!new->v.zonelist) {
kmem_cache_free(policy_cache, new);
return ERR_PTR(-ENOMEM);
}
- memcpy(new->v.zonelist, old->v.zonelist, sz);
}
return new;
}
diff --git a/mm/migrate.c b/mm/migrate.c
index 20a8c2687b1e..ba2453f9483d 100644
--- a/mm/migrate.c
+++ b/mm/migrate.c
@@ -409,6 +409,7 @@ int migrate_page(struct address_space *mapping,
}
EXPORT_SYMBOL(migrate_page);
+#ifdef CONFIG_BLOCK
/*
* Migration function for pages with buffers. This function can only be used
* if the underlying filesystem guarantees that no other references to "page"
@@ -466,6 +467,7 @@ int buffer_migrate_page(struct address_space *mapping,
return 0;
}
EXPORT_SYMBOL(buffer_migrate_page);
+#endif
/*
* Writeback a page to clean the dirty state
@@ -525,7 +527,7 @@ static int fallback_migrate_page(struct address_space *mapping,
* Buffers may be managed in a filesystem specific way.
* We must have no buffers or drop them.
*/
- if (page_has_buffers(page) &&
+ if (PagePrivate(page) &&
!try_to_release_page(page, GFP_KERNEL))
return -EAGAIN;
diff --git a/mm/mprotect.c b/mm/mprotect.c
index 955f9d0e38aa..3b8f3c0c63f3 100644
--- a/mm/mprotect.c
+++ b/mm/mprotect.c
@@ -34,6 +34,7 @@ static void change_pte_range(struct mm_struct *mm, pmd_t *pmd,
spinlock_t *ptl;
pte = pte_offset_map_lock(mm, pmd, addr, &ptl);
+ arch_enter_lazy_mmu_mode();
do {
oldpte = *pte;
if (pte_present(oldpte)) {
@@ -70,6 +71,7 @@ static void change_pte_range(struct mm_struct *mm, pmd_t *pmd,
}
} while (pte++, addr += PAGE_SIZE, addr != end);
+ arch_leave_lazy_mmu_mode();
pte_unmap_unlock(pte - 1, ptl);
}
diff --git a/mm/mremap.c b/mm/mremap.c
index 7c15cf3373ad..9c769fa29f32 100644
--- a/mm/mremap.c
+++ b/mm/mremap.c
@@ -98,6 +98,7 @@ static void move_ptes(struct vm_area_struct *vma, pmd_t *old_pmd,
new_ptl = pte_lockptr(mm, new_pmd);
if (new_ptl != old_ptl)
spin_lock_nested(new_ptl, SINGLE_DEPTH_NESTING);
+ arch_enter_lazy_mmu_mode();
for (; old_addr < old_end; old_pte++, old_addr += PAGE_SIZE,
new_pte++, new_addr += PAGE_SIZE) {
@@ -109,6 +110,7 @@ static void move_ptes(struct vm_area_struct *vma, pmd_t *old_pmd,
set_pte_at(mm, new_addr, new_pte, pte);
}
+ arch_leave_lazy_mmu_mode();
if (new_ptl != old_ptl)
spin_unlock(new_ptl);
pte_unmap_nested(new_pte - 1);
diff --git a/mm/nommu.c b/mm/nommu.c
index 564540662192..365019599df8 100644
--- a/mm/nommu.c
+++ b/mm/nommu.c
@@ -948,7 +948,8 @@ unsigned long do_mmap_pgoff(struct file *file,
up_write(&nommu_vma_sem);
kfree(vml);
if (vma) {
- fput(vma->vm_file);
+ if (vma->vm_file)
+ fput(vma->vm_file);
kfree(vma);
}
return ret;
diff --git a/mm/oom_kill.c b/mm/oom_kill.c
index bada3d03119f..20f41b082e16 100644
--- a/mm/oom_kill.c
+++ b/mm/oom_kill.c
@@ -204,16 +204,30 @@ static struct task_struct *select_bad_process(unsigned long *ppoints)
do_posix_clock_monotonic_gettime(&uptime);
do_each_thread(g, p) {
unsigned long points;
- int releasing;
- /* skip kernel threads */
+ /*
+ * skip kernel threads and tasks which have already released
+ * their mm.
+ */
if (!p->mm)
continue;
- /* skip the init task with pid == 1 */
- if (p->pid == 1)
+ /* skip the init task */
+ if (is_init(p))
continue;
/*
+ * This task already has access to memory reserves and is
+ * being killed. Don't allow any other task access to the
+ * memory reserve.
+ *
+ * Note: this may have a chance of deadlock if it gets
+ * blocked waiting for another task which itself is waiting
+ * for memory. Is there a better alternative?
+ */
+ if (test_tsk_thread_flag(p, TIF_MEMDIE))
+ return ERR_PTR(-1UL);
+
+ /*
* This is in the process of releasing memory so wait for it
* to finish before killing some other task by mistake.
*
@@ -221,21 +235,16 @@ static struct task_struct *select_bad_process(unsigned long *ppoints)
* go ahead if it is exiting: this will simply set TIF_MEMDIE,
* which will allow it to gain access to memory reserves in
* the process of exiting and releasing its resources.
- * Otherwise we could get an OOM deadlock.
+ * Otherwise we could get an easy OOM deadlock.
*/
- releasing = test_tsk_thread_flag(p, TIF_MEMDIE) ||
- p->flags & PF_EXITING;
- if (releasing) {
- /* PF_DEAD tasks have already released their mm */
- if (p->flags & PF_DEAD)
- continue;
- if (p->flags & PF_EXITING && p == current) {
- chosen = p;
- *ppoints = ULONG_MAX;
- break;
- }
- return ERR_PTR(-1UL);
+ if (p->flags & PF_EXITING) {
+ if (p != current)
+ return ERR_PTR(-1UL);
+
+ chosen = p;
+ *ppoints = ULONG_MAX;
}
+
if (p->oomkilladj == OOM_DISABLE)
continue;
@@ -245,6 +254,7 @@ static struct task_struct *select_bad_process(unsigned long *ppoints)
*ppoints = points;
}
} while_each_thread(g, p);
+
return chosen;
}
@@ -255,20 +265,17 @@ static struct task_struct *select_bad_process(unsigned long *ppoints)
*/
static void __oom_kill_task(struct task_struct *p, const char *message)
{
- if (p->pid == 1) {
+ if (is_init(p)) {
WARN_ON(1);
printk(KERN_WARNING "tried to kill init!\n");
return;
}
- task_lock(p);
- if (!p->mm || p->mm == &init_mm) {
+ if (!p->mm) {
WARN_ON(1);
printk(KERN_WARNING "tried to kill an mm-less task!\n");
- task_unlock(p);
return;
}
- task_unlock(p);
if (message) {
printk(KERN_ERR "%s: Killed process %d (%s).\n",
@@ -302,7 +309,7 @@ static int oom_kill_task(struct task_struct *p, const char *message)
* However, this is of no concern to us.
*/
- if (mm == NULL || mm == &init_mm)
+ if (mm == NULL)
return 1;
__oom_kill_task(p, message);
diff --git a/mm/page-writeback.c b/mm/page-writeback.c
index 555752907dc3..c0d4ce144dec 100644
--- a/mm/page-writeback.c
+++ b/mm/page-writeback.c
@@ -30,6 +30,8 @@
#include <linux/sysctl.h>
#include <linux/cpu.h>
#include <linux/syscalls.h>
+#include <linux/buffer_head.h>
+#include <linux/pagevec.h>
/*
* The maximum number of pages to writeout in a single bdflush/kupdate
@@ -46,7 +48,6 @@
*/
static long ratelimit_pages = 32;
-static long total_pages; /* The total number of pages in the machine. */
static int dirty_exceeded __cacheline_aligned_in_smp; /* Dirty mem may be over limit */
/*
@@ -126,7 +127,7 @@ get_dirty_limits(long *pbackground, long *pdirty,
int unmapped_ratio;
long background;
long dirty;
- unsigned long available_memory = total_pages;
+ unsigned long available_memory = vm_total_pages;
struct task_struct *tsk;
#ifdef CONFIG_HIGHMEM
@@ -141,7 +142,7 @@ get_dirty_limits(long *pbackground, long *pdirty,
unmapped_ratio = 100 - ((global_page_state(NR_FILE_MAPPED) +
global_page_state(NR_ANON_PAGES)) * 100) /
- total_pages;
+ vm_total_pages;
dirty_ratio = vm_dirty_ratio;
if (dirty_ratio > unmapped_ratio / 2)
@@ -502,9 +503,9 @@ void laptop_sync_completion(void)
* will write six megabyte chunks, max.
*/
-static void set_ratelimit(void)
+void writeback_set_ratelimit(void)
{
- ratelimit_pages = total_pages / (num_online_cpus() * 32);
+ ratelimit_pages = vm_total_pages / (num_online_cpus() * 32);
if (ratelimit_pages < 16)
ratelimit_pages = 16;
if (ratelimit_pages * PAGE_CACHE_SIZE > 4096 * 1024)
@@ -514,7 +515,7 @@ static void set_ratelimit(void)
static int __cpuinit
ratelimit_handler(struct notifier_block *self, unsigned long u, void *v)
{
- set_ratelimit();
+ writeback_set_ratelimit();
return 0;
}
@@ -533,9 +534,7 @@ void __init page_writeback_init(void)
long buffer_pages = nr_free_buffer_pages();
long correction;
- total_pages = nr_free_pagecache_pages();
-
- correction = (100 * 4 * buffer_pages) / total_pages;
+ correction = (100 * 4 * buffer_pages) / vm_total_pages;
if (correction < 100) {
dirty_background_ratio *= correction;
@@ -549,10 +548,143 @@ void __init page_writeback_init(void)
vm_dirty_ratio = 1;
}
mod_timer(&wb_timer, jiffies + dirty_writeback_interval);
- set_ratelimit();
+ writeback_set_ratelimit();
register_cpu_notifier(&ratelimit_nb);
}
+/**
+ * generic_writepages - walk the list of dirty pages of the given
+ * address space and writepage() all of them.
+ *
+ * @mapping: address space structure to write
+ * @wbc: subtract the number of written pages from *@wbc->nr_to_write
+ *
+ * This is a library function, which implements the writepages()
+ * address_space_operation.
+ *
+ * If a page is already under I/O, generic_writepages() skips it, even
+ * if it's dirty. This is desirable behaviour for memory-cleaning writeback,
+ * but it is INCORRECT for data-integrity system calls such as fsync(). fsync()
+ * and msync() need to guarantee that all the data which was dirty at the time
+ * the call was made get new I/O started against them. If wbc->sync_mode is
+ * WB_SYNC_ALL then we were called for data integrity and we must wait for
+ * existing IO to complete.
+ *
+ * Derived from mpage_writepages() - if you fix this you should check that
+ * also!
+ */
+int generic_writepages(struct address_space *mapping,
+ struct writeback_control *wbc)
+{
+ struct backing_dev_info *bdi = mapping->backing_dev_info;
+ int ret = 0;
+ int done = 0;
+ int (*writepage)(struct page *page, struct writeback_control *wbc);
+ struct pagevec pvec;
+ int nr_pages;
+ pgoff_t index;
+ pgoff_t end; /* Inclusive */
+ int scanned = 0;
+ int range_whole = 0;
+
+ if (wbc->nonblocking && bdi_write_congested(bdi)) {
+ wbc->encountered_congestion = 1;
+ return 0;
+ }
+
+ writepage = mapping->a_ops->writepage;
+
+ /* deal with chardevs and other special file */
+ if (!writepage)
+ return 0;
+
+ pagevec_init(&pvec, 0);
+ if (wbc->range_cyclic) {
+ index = mapping->writeback_index; /* Start from prev offset */
+ end = -1;
+ } else {
+ index = wbc->range_start >> PAGE_CACHE_SHIFT;
+ end = wbc->range_end >> PAGE_CACHE_SHIFT;
+ if (wbc->range_start == 0 && wbc->range_end == LLONG_MAX)
+ range_whole = 1;
+ scanned = 1;
+ }
+retry:
+ while (!done && (index <= end) &&
+ (nr_pages = pagevec_lookup_tag(&pvec, mapping, &index,
+ PAGECACHE_TAG_DIRTY,
+ min(end - index, (pgoff_t)PAGEVEC_SIZE-1) + 1))) {
+ unsigned i;
+
+ scanned = 1;
+ for (i = 0; i < nr_pages; i++) {
+ struct page *page = pvec.pages[i];
+
+ /*
+ * At this point we hold neither mapping->tree_lock nor
+ * lock on the page itself: the page may be truncated or
+ * invalidated (changing page->mapping to NULL), or even
+ * swizzled back from swapper_space to tmpfs file
+ * mapping
+ */
+ lock_page(page);
+
+ if (unlikely(page->mapping != mapping)) {
+ unlock_page(page);
+ continue;
+ }
+
+ if (!wbc->range_cyclic && page->index > end) {
+ done = 1;
+ unlock_page(page);
+ continue;
+ }
+
+ if (wbc->sync_mode != WB_SYNC_NONE)
+ wait_on_page_writeback(page);
+
+ if (PageWriteback(page) ||
+ !clear_page_dirty_for_io(page)) {
+ unlock_page(page);
+ continue;
+ }
+
+ ret = (*writepage)(page, wbc);
+ if (ret) {
+ if (ret == -ENOSPC)
+ set_bit(AS_ENOSPC, &mapping->flags);
+ else
+ set_bit(AS_EIO, &mapping->flags);
+ }
+
+ if (unlikely(ret == AOP_WRITEPAGE_ACTIVATE))
+ unlock_page(page);
+ if (ret || (--(wbc->nr_to_write) <= 0))
+ done = 1;
+ if (wbc->nonblocking && bdi_write_congested(bdi)) {
+ wbc->encountered_congestion = 1;
+ done = 1;
+ }
+ }
+ pagevec_release(&pvec);
+ cond_resched();
+ }
+ if (!scanned && !done) {
+ /*
+ * We hit the last page and there is more work to be done: wrap
+ * back to the start of the file
+ */
+ scanned = 1;
+ index = 0;
+ goto retry;
+ }
+ if (wbc->range_cyclic || (range_whole && wbc->nr_to_write > 0))
+ mapping->writeback_index = index;
+ return ret;
+}
+
+EXPORT_SYMBOL(generic_writepages);
+
int do_writepages(struct address_space *mapping, struct writeback_control *wbc)
{
int ret;
@@ -675,9 +807,11 @@ int fastcall set_page_dirty(struct page *page)
if (likely(mapping)) {
int (*spd)(struct page *) = mapping->a_ops->set_page_dirty;
- if (spd)
- return (*spd)(page);
- return __set_page_dirty_buffers(page);
+#ifdef CONFIG_BLOCK
+ if (!spd)
+ spd = __set_page_dirty_buffers;
+#endif
+ return (*spd)(page);
}
if (!PageDirty(page)) {
if (!TestSetPageDirty(page))
diff --git a/mm/shmem.c b/mm/shmem.c
index eda907c3a86a..bb8ca7ef7094 100644
--- a/mm/shmem.c
+++ b/mm/shmem.c
@@ -26,6 +26,8 @@
#include <linux/module.h>
#include <linux/init.h>
#include <linux/fs.h>
+#include <linux/xattr.h>
+#include <linux/generic_acl.h>
#include <linux/mm.h>
#include <linux/mman.h>
#include <linux/file.h>
@@ -177,6 +179,7 @@ static const struct address_space_operations shmem_aops;
static struct file_operations shmem_file_operations;
static struct inode_operations shmem_inode_operations;
static struct inode_operations shmem_dir_inode_operations;
+static struct inode_operations shmem_special_inode_operations;
static struct vm_operations_struct shmem_vm_ops;
static struct backing_dev_info shmem_backing_dev_info __read_mostly = {
@@ -637,7 +640,7 @@ static int shmem_notify_change(struct dentry *dentry, struct iattr *attr)
struct page *page = NULL;
int error;
- if (attr->ia_valid & ATTR_SIZE) {
+ if (S_ISREG(inode->i_mode) && (attr->ia_valid & ATTR_SIZE)) {
if (attr->ia_size < inode->i_size) {
/*
* If truncating down to a partial page, then
@@ -670,6 +673,10 @@ static int shmem_notify_change(struct dentry *dentry, struct iattr *attr)
error = inode_change_ok(inode, attr);
if (!error)
error = inode_setattr(inode, attr);
+#ifdef CONFIG_TMPFS_POSIX_ACL
+ if (!error && (attr->ia_valid & ATTR_MODE))
+ error = generic_acl_chmod(inode, &shmem_acl_ops);
+#endif
if (page)
page_cache_release(page);
return error;
@@ -1362,6 +1369,7 @@ shmem_get_inode(struct super_block *sb, int mode, dev_t dev)
switch (mode & S_IFMT) {
default:
+ inode->i_op = &shmem_special_inode_operations;
init_special_inode(inode, mode, dev);
break;
case S_IFREG:
@@ -1371,7 +1379,7 @@ shmem_get_inode(struct super_block *sb, int mode, dev_t dev)
&sbinfo->policy_nodes);
break;
case S_IFDIR:
- inode->i_nlink++;
+ inc_nlink(inode);
/* Some things misbehave if size == 0 on a directory */
inode->i_size = 2 * BOGO_DIRENT_SIZE;
inode->i_op = &shmem_dir_inode_operations;
@@ -1682,7 +1690,11 @@ shmem_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev)
iput(inode);
return error;
}
- error = 0;
+ }
+ error = shmem_acl_init(inode, dir);
+ if (error) {
+ iput(inode);
+ return error;
}
if (dir->i_mode & S_ISGID) {
inode->i_gid = dir->i_gid;
@@ -1703,7 +1715,7 @@ static int shmem_mkdir(struct inode *dir, struct dentry *dentry, int mode)
if ((error = shmem_mknod(dir, dentry, mode | S_IFDIR, 0)))
return error;
- dir->i_nlink++;
+ inc_nlink(dir);
return 0;
}
@@ -1738,7 +1750,7 @@ static int shmem_link(struct dentry *old_dentry, struct inode *dir, struct dentr
dir->i_size += BOGO_DIRENT_SIZE;
inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME;
- inode->i_nlink++;
+ inc_nlink(inode);
atomic_inc(&inode->i_count); /* New dentry reference */
dget(dentry); /* Extra pinning count for the created dentry */
d_instantiate(dentry, inode);
@@ -1760,7 +1772,7 @@ static int shmem_unlink(struct inode *dir, struct dentry *dentry)
dir->i_size -= BOGO_DIRENT_SIZE;
inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME;
- inode->i_nlink--;
+ drop_nlink(inode);
dput(dentry); /* Undo the count from "create" - this does all the work */
return 0;
}
@@ -1770,8 +1782,8 @@ static int shmem_rmdir(struct inode *dir, struct dentry *dentry)
if (!simple_empty(dentry))
return -ENOTEMPTY;
- dentry->d_inode->i_nlink--;
- dir->i_nlink--;
+ drop_nlink(dentry->d_inode);
+ drop_nlink(dir);
return shmem_unlink(dir, dentry);
}
@@ -1792,10 +1804,10 @@ static int shmem_rename(struct inode *old_dir, struct dentry *old_dentry, struct
if (new_dentry->d_inode) {
(void) shmem_unlink(new_dir, new_dentry);
if (they_are_dirs)
- old_dir->i_nlink--;
+ drop_nlink(old_dir);
} else if (they_are_dirs) {
- old_dir->i_nlink--;
- new_dir->i_nlink++;
+ drop_nlink(old_dir);
+ inc_nlink(new_dir);
}
old_dir->i_size -= BOGO_DIRENT_SIZE;
@@ -1897,6 +1909,53 @@ static struct inode_operations shmem_symlink_inode_operations = {
.put_link = shmem_put_link,
};
+#ifdef CONFIG_TMPFS_POSIX_ACL
+/**
+ * Superblocks without xattr inode operations will get security.* xattr
+ * support from the VFS "for free". As soon as we have any other xattrs
+ * like ACLs, we also need to implement the security.* handlers at
+ * filesystem level, though.
+ */
+
+static size_t shmem_xattr_security_list(struct inode *inode, char *list,
+ size_t list_len, const char *name,
+ size_t name_len)
+{
+ return security_inode_listsecurity(inode, list, list_len);
+}
+
+static int shmem_xattr_security_get(struct inode *inode, const char *name,
+ void *buffer, size_t size)
+{
+ if (strcmp(name, "") == 0)
+ return -EINVAL;
+ return security_inode_getsecurity(inode, name, buffer, size,
+ -EOPNOTSUPP);
+}
+
+static int shmem_xattr_security_set(struct inode *inode, const char *name,
+ const void *value, size_t size, int flags)
+{
+ if (strcmp(name, "") == 0)
+ return -EINVAL;
+ return security_inode_setsecurity(inode, name, value, size, flags);
+}
+
+struct xattr_handler shmem_xattr_security_handler = {
+ .prefix = XATTR_SECURITY_PREFIX,
+ .list = shmem_xattr_security_list,
+ .get = shmem_xattr_security_get,
+ .set = shmem_xattr_security_set,
+};
+
+static struct xattr_handler *shmem_xattr_handlers[] = {
+ &shmem_xattr_acl_access_handler,
+ &shmem_xattr_acl_default_handler,
+ &shmem_xattr_security_handler,
+ NULL
+};
+#endif
+
static int shmem_parse_options(char *options, int *mode, uid_t *uid,
gid_t *gid, unsigned long *blocks, unsigned long *inodes,
int *policy, nodemask_t *policy_nodes)
@@ -2094,6 +2153,10 @@ static int shmem_fill_super(struct super_block *sb,
sb->s_magic = TMPFS_MAGIC;
sb->s_op = &shmem_ops;
sb->s_time_gran = 1;
+#ifdef CONFIG_TMPFS_POSIX_ACL
+ sb->s_xattr = shmem_xattr_handlers;
+ sb->s_flags |= MS_POSIXACL;
+#endif
inode = shmem_get_inode(sb, S_IFDIR | mode, 0);
if (!inode)
@@ -2130,6 +2193,7 @@ static void shmem_destroy_inode(struct inode *inode)
/* only struct inode is valid if it's an inline symlink */
mpol_free_shared_policy(&SHMEM_I(inode)->policy);
}
+ shmem_acl_destroy_inode(inode);
kmem_cache_free(shmem_inode_cachep, SHMEM_I(inode));
}
@@ -2141,6 +2205,10 @@ static void init_once(void *foo, struct kmem_cache *cachep,
if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) ==
SLAB_CTOR_CONSTRUCTOR) {
inode_init_once(&p->vfs_inode);
+#ifdef CONFIG_TMPFS_POSIX_ACL
+ p->i_acl = NULL;
+ p->i_default_acl = NULL;
+#endif
}
}
@@ -2184,6 +2252,14 @@ static struct inode_operations shmem_inode_operations = {
.truncate = shmem_truncate,
.setattr = shmem_notify_change,
.truncate_range = shmem_truncate_range,
+#ifdef CONFIG_TMPFS_POSIX_ACL
+ .setxattr = generic_setxattr,
+ .getxattr = generic_getxattr,
+ .listxattr = generic_listxattr,
+ .removexattr = generic_removexattr,
+ .permission = shmem_permission,
+#endif
+
};
static struct inode_operations shmem_dir_inode_operations = {
@@ -2198,6 +2274,25 @@ static struct inode_operations shmem_dir_inode_operations = {
.mknod = shmem_mknod,
.rename = shmem_rename,
#endif
+#ifdef CONFIG_TMPFS_POSIX_ACL
+ .setattr = shmem_notify_change,
+ .setxattr = generic_setxattr,
+ .getxattr = generic_getxattr,
+ .listxattr = generic_listxattr,
+ .removexattr = generic_removexattr,
+ .permission = shmem_permission,
+#endif
+};
+
+static struct inode_operations shmem_special_inode_operations = {
+#ifdef CONFIG_TMPFS_POSIX_ACL
+ .setattr = shmem_notify_change,
+ .setxattr = generic_setxattr,
+ .getxattr = generic_getxattr,
+ .listxattr = generic_listxattr,
+ .removexattr = generic_removexattr,
+ .permission = shmem_permission,
+#endif
};
static struct super_operations shmem_ops = {
diff --git a/mm/shmem_acl.c b/mm/shmem_acl.c
new file mode 100644
index 000000000000..c946bf468718
--- /dev/null
+++ b/mm/shmem_acl.c
@@ -0,0 +1,197 @@
+/*
+ * mm/shmem_acl.c
+ *
+ * (C) 2005 Andreas Gruenbacher <agruen@suse.de>
+ *
+ * This file is released under the GPL.
+ */
+
+#include <linux/fs.h>
+#include <linux/shmem_fs.h>
+#include <linux/xattr.h>
+#include <linux/generic_acl.h>
+
+/**
+ * shmem_get_acl - generic_acl_operations->getacl() operation
+ */
+static struct posix_acl *
+shmem_get_acl(struct inode *inode, int type)
+{
+ struct posix_acl *acl = NULL;
+
+ spin_lock(&inode->i_lock);
+ switch(type) {
+ case ACL_TYPE_ACCESS:
+ acl = posix_acl_dup(SHMEM_I(inode)->i_acl);
+ break;
+
+ case ACL_TYPE_DEFAULT:
+ acl = posix_acl_dup(SHMEM_I(inode)->i_default_acl);
+ break;
+ }
+ spin_unlock(&inode->i_lock);
+
+ return acl;
+}
+
+/**
+ * shmem_get_acl - generic_acl_operations->setacl() operation
+ */
+static void
+shmem_set_acl(struct inode *inode, int type, struct posix_acl *acl)
+{
+ struct posix_acl *free = NULL;
+
+ spin_lock(&inode->i_lock);
+ switch(type) {
+ case ACL_TYPE_ACCESS:
+ free = SHMEM_I(inode)->i_acl;
+ SHMEM_I(inode)->i_acl = posix_acl_dup(acl);
+ break;
+
+ case ACL_TYPE_DEFAULT:
+ free = SHMEM_I(inode)->i_default_acl;
+ SHMEM_I(inode)->i_default_acl = posix_acl_dup(acl);
+ break;
+ }
+ spin_unlock(&inode->i_lock);
+ posix_acl_release(free);
+}
+
+struct generic_acl_operations shmem_acl_ops = {
+ .getacl = shmem_get_acl,
+ .setacl = shmem_set_acl,
+};
+
+/**
+ * shmem_list_acl_access, shmem_get_acl_access, shmem_set_acl_access,
+ * shmem_xattr_acl_access_handler - plumbing code to implement the
+ * system.posix_acl_access xattr using the generic acl functions.
+ */
+
+static size_t
+shmem_list_acl_access(struct inode *inode, char *list, size_t list_size,
+ const char *name, size_t name_len)
+{
+ return generic_acl_list(inode, &shmem_acl_ops, ACL_TYPE_ACCESS,
+ list, list_size);
+}
+
+static int
+shmem_get_acl_access(struct inode *inode, const char *name, void *buffer,
+ size_t size)
+{
+ if (strcmp(name, "") != 0)
+ return -EINVAL;
+ return generic_acl_get(inode, &shmem_acl_ops, ACL_TYPE_ACCESS, buffer,
+ size);
+}
+
+static int
+shmem_set_acl_access(struct inode *inode, const char *name, const void *value,
+ size_t size, int flags)
+{
+ if (strcmp(name, "") != 0)
+ return -EINVAL;
+ return generic_acl_set(inode, &shmem_acl_ops, ACL_TYPE_ACCESS, value,
+ size);
+}
+
+struct xattr_handler shmem_xattr_acl_access_handler = {
+ .prefix = POSIX_ACL_XATTR_ACCESS,
+ .list = shmem_list_acl_access,
+ .get = shmem_get_acl_access,
+ .set = shmem_set_acl_access,
+};
+
+/**
+ * shmem_list_acl_default, shmem_get_acl_default, shmem_set_acl_default,
+ * shmem_xattr_acl_default_handler - plumbing code to implement the
+ * system.posix_acl_default xattr using the generic acl functions.
+ */
+
+static size_t
+shmem_list_acl_default(struct inode *inode, char *list, size_t list_size,
+ const char *name, size_t name_len)
+{
+ return generic_acl_list(inode, &shmem_acl_ops, ACL_TYPE_DEFAULT,
+ list, list_size);
+}
+
+static int
+shmem_get_acl_default(struct inode *inode, const char *name, void *buffer,
+ size_t size)
+{
+ if (strcmp(name, "") != 0)
+ return -EINVAL;
+ return generic_acl_get(inode, &shmem_acl_ops, ACL_TYPE_DEFAULT, buffer,
+ size);
+}
+
+static int
+shmem_set_acl_default(struct inode *inode, const char *name, const void *value,
+ size_t size, int flags)
+{
+ if (strcmp(name, "") != 0)
+ return -EINVAL;
+ return generic_acl_set(inode, &shmem_acl_ops, ACL_TYPE_DEFAULT, value,
+ size);
+}
+
+struct xattr_handler shmem_xattr_acl_default_handler = {
+ .prefix = POSIX_ACL_XATTR_DEFAULT,
+ .list = shmem_list_acl_default,
+ .get = shmem_get_acl_default,
+ .set = shmem_set_acl_default,
+};
+
+/**
+ * shmem_acl_init - Inizialize the acl(s) of a new inode
+ */
+int
+shmem_acl_init(struct inode *inode, struct inode *dir)
+{
+ return generic_acl_init(inode, dir, &shmem_acl_ops);
+}
+
+/**
+ * shmem_acl_destroy_inode - destroy acls hanging off the in-memory inode
+ *
+ * This is done before destroying the actual inode.
+ */
+
+void
+shmem_acl_destroy_inode(struct inode *inode)
+{
+ if (SHMEM_I(inode)->i_acl)
+ posix_acl_release(SHMEM_I(inode)->i_acl);
+ SHMEM_I(inode)->i_acl = NULL;
+ if (SHMEM_I(inode)->i_default_acl)
+ posix_acl_release(SHMEM_I(inode)->i_default_acl);
+ SHMEM_I(inode)->i_default_acl = NULL;
+}
+
+/**
+ * shmem_check_acl - check_acl() callback for generic_permission()
+ */
+static int
+shmem_check_acl(struct inode *inode, int mask)
+{
+ struct posix_acl *acl = shmem_get_acl(inode, ACL_TYPE_ACCESS);
+
+ if (acl) {
+ int error = posix_acl_permission(inode, acl, mask);
+ posix_acl_release(acl);
+ return error;
+ }
+ return -EAGAIN;
+}
+
+/**
+ * shmem_permission - permission() inode operation
+ */
+int
+shmem_permission(struct inode *inode, int mask, struct nameidata *nd)
+{
+ return generic_permission(inode, mask, shmem_check_acl);
+}
diff --git a/mm/slab.c b/mm/slab.c
index 792bfe320a8b..3dbd6f4e7477 100644
--- a/mm/slab.c
+++ b/mm/slab.c
@@ -1683,10 +1683,32 @@ static void poison_obj(struct kmem_cache *cachep, void *addr, unsigned char val)
static void dump_line(char *data, int offset, int limit)
{
int i;
+ unsigned char error = 0;
+ int bad_count = 0;
+
printk(KERN_ERR "%03x:", offset);
- for (i = 0; i < limit; i++)
+ for (i = 0; i < limit; i++) {
+ if (data[offset + i] != POISON_FREE) {
+ error = data[offset + i];
+ bad_count++;
+ }
printk(" %02x", (unsigned char)data[offset + i]);
+ }
printk("\n");
+
+ if (bad_count == 1) {
+ error ^= POISON_FREE;
+ if (!(error & (error - 1))) {
+ printk(KERN_ERR "Single bit error detected. Probably "
+ "bad RAM.\n");
+#ifdef CONFIG_X86
+ printk(KERN_ERR "Run memtest86+ or a similar memory "
+ "test tool.\n");
+#else
+ printk(KERN_ERR "Run a memory test tool.\n");
+#endif
+ }
+ }
}
#endif
diff --git a/mm/swapfile.c b/mm/swapfile.c
index f1f5ec783781..a15def63f28f 100644
--- a/mm/swapfile.c
+++ b/mm/swapfile.c
@@ -1723,13 +1723,14 @@ get_swap_info_struct(unsigned type)
*/
int valid_swaphandles(swp_entry_t entry, unsigned long *offset)
{
- int ret = 0, i = 1 << page_cluster;
+ int our_page_cluster = page_cluster;
+ int ret = 0, i = 1 << our_page_cluster;
unsigned long toff;
struct swap_info_struct *swapdev = swp_type(entry) + swap_info;
- if (!page_cluster) /* no readahead */
+ if (!our_page_cluster) /* no readahead */
return 0;
- toff = (swp_offset(entry) >> page_cluster) << page_cluster;
+ toff = (swp_offset(entry) >> our_page_cluster) << our_page_cluster;
if (!toff) /* first page is swap header */
toff++, i--;
*offset = toff;
diff --git a/mm/truncate.c b/mm/truncate.c
index a654928323dc..f4edbc179d14 100644
--- a/mm/truncate.c
+++ b/mm/truncate.c
@@ -17,6 +17,32 @@
do_invalidatepage */
+/**
+ * do_invalidatepage - invalidate part of all of a page
+ * @page: the page which is affected
+ * @offset: the index of the truncation point
+ *
+ * do_invalidatepage() is called when all or part of the page has become
+ * invalidated by a truncate operation.
+ *
+ * do_invalidatepage() does not have to release all buffers, but it must
+ * ensure that no dirty buffer is left outside @offset and that no I/O
+ * is underway against any of the blocks which are outside the truncation
+ * point. Because the caller is about to free (and possibly reuse) those
+ * blocks on-disk.
+ */
+void do_invalidatepage(struct page *page, unsigned long offset)
+{
+ void (*invalidatepage)(struct page *, unsigned long);
+ invalidatepage = page->mapping->a_ops->invalidatepage;
+#ifdef CONFIG_BLOCK
+ if (!invalidatepage)
+ invalidatepage = block_invalidatepage;
+#endif
+ if (invalidatepage)
+ (*invalidatepage)(page, offset);
+}
+
static inline void truncate_partial_page(struct page *page, unsigned partial)
{
memclear_highpage_flush(page, partial, PAGE_CACHE_SIZE-partial);
@@ -261,9 +287,39 @@ unsigned long invalidate_inode_pages(struct address_space *mapping)
{
return invalidate_mapping_pages(mapping, 0, ~0UL);
}
-
EXPORT_SYMBOL(invalidate_inode_pages);
+/*
+ * This is like invalidate_complete_page(), except it ignores the page's
+ * refcount. We do this because invalidate_inode_pages2() needs stronger
+ * invalidation guarantees, and cannot afford to leave pages behind because
+ * shrink_list() has a temp ref on them, or because they're transiently sitting
+ * in the lru_cache_add() pagevecs.
+ */
+static int
+invalidate_complete_page2(struct address_space *mapping, struct page *page)
+{
+ if (page->mapping != mapping)
+ return 0;
+
+ if (PagePrivate(page) && !try_to_release_page(page, 0))
+ return 0;
+
+ write_lock_irq(&mapping->tree_lock);
+ if (PageDirty(page))
+ goto failed;
+
+ BUG_ON(PagePrivate(page));
+ __remove_from_page_cache(page);
+ write_unlock_irq(&mapping->tree_lock);
+ ClearPageUptodate(page);
+ page_cache_release(page); /* pagecache ref */
+ return 1;
+failed:
+ write_unlock_irq(&mapping->tree_lock);
+ return 0;
+}
+
/**
* invalidate_inode_pages2_range - remove range of pages from an address_space
* @mapping: the address_space
@@ -330,7 +386,7 @@ int invalidate_inode_pages2_range(struct address_space *mapping,
}
}
was_dirty = test_clear_page_dirty(page);
- if (!invalidate_complete_page(mapping, page)) {
+ if (!invalidate_complete_page2(mapping, page)) {
if (was_dirty)
set_page_dirty(page);
ret = -EIO;
diff --git a/mm/util.c b/mm/util.c
index 7368479220b3..e14fa84ef39a 100644
--- a/mm/util.c
+++ b/mm/util.c
@@ -40,6 +40,24 @@ char *kstrdup(const char *s, gfp_t gfp)
}
EXPORT_SYMBOL(kstrdup);
+/**
+ * kmemdup - duplicate region of memory
+ *
+ * @src: memory region to duplicate
+ * @len: memory region length
+ * @gfp: GFP mask to use
+ */
+void *kmemdup(const void *src, size_t len, gfp_t gfp)
+{
+ void *p;
+
+ p = ____kmalloc(len, gfp);
+ if (p)
+ memcpy(p, src, len);
+ return p;
+}
+EXPORT_SYMBOL(kmemdup);
+
/*
* strndup_user - duplicate an existing string from user space
*
diff --git a/net/802/tr.c b/net/802/tr.c
index d7d8f40c4fed..829deb41ce81 100644
--- a/net/802/tr.c
+++ b/net/802/tr.c
@@ -164,7 +164,7 @@ static int tr_rebuild_header(struct sk_buff *skb)
*/
if(trllc->ethertype != htons(ETH_P_IP)) {
- printk("tr_rebuild_header: Don't know how to resolve type %04X addresses ?\n",(unsigned int)htons(trllc->ethertype));
+ printk("tr_rebuild_header: Don't know how to resolve type %04X addresses ?\n", ntohs(trllc->ethertype));
return 0;
}
@@ -186,7 +186,7 @@ static int tr_rebuild_header(struct sk_buff *skb)
* it via SNAP.
*/
-unsigned short tr_type_trans(struct sk_buff *skb, struct net_device *dev)
+__be16 tr_type_trans(struct sk_buff *skb, struct net_device *dev)
{
struct trh_hdr *trh=(struct trh_hdr *)skb->data;
@@ -229,15 +229,15 @@ unsigned short tr_type_trans(struct sk_buff *skb, struct net_device *dev)
*/
if (trllc->dsap == EXTENDED_SAP &&
- (trllc->ethertype == ntohs(ETH_P_IP) ||
- trllc->ethertype == ntohs(ETH_P_IPV6) ||
- trllc->ethertype == ntohs(ETH_P_ARP)))
+ (trllc->ethertype == htons(ETH_P_IP) ||
+ trllc->ethertype == htons(ETH_P_IPV6) ||
+ trllc->ethertype == htons(ETH_P_ARP)))
{
skb_pull(skb, sizeof(struct trllc));
return trllc->ethertype;
}
- return ntohs(ETH_P_TR_802_2);
+ return htons(ETH_P_TR_802_2);
}
/*
diff --git a/net/Kconfig b/net/Kconfig
index 6528a935622c..a81aca43932f 100644
--- a/net/Kconfig
+++ b/net/Kconfig
@@ -231,7 +231,7 @@ config NET_TCPPROBE
TCP congestion avoidance modules. If you don't understand
what was just said, you don't need it: say N.
- Documentation on how to use the packet generator can be found
+ Documentation on how to use TCP connection probing can be found
at http://linux-net.osdl.org/index.php/TcpProbe
To compile this code as a module, choose M here: the
diff --git a/net/appletalk/ddp.c b/net/appletalk/ddp.c
index 96dc6bb52d14..708e2e0371af 100644
--- a/net/appletalk/ddp.c
+++ b/net/appletalk/ddp.c
@@ -1002,7 +1002,7 @@ static unsigned long atalk_sum_skb(const struct sk_buff *skb, int offset,
return sum;
}
-static unsigned short atalk_checksum(const struct sk_buff *skb, int len)
+static __be16 atalk_checksum(const struct sk_buff *skb, int len)
{
unsigned long sum;
@@ -1010,7 +1010,7 @@ static unsigned short atalk_checksum(const struct sk_buff *skb, int len)
sum = atalk_sum_skb(skb, 4, len-4, 0);
/* Use 0xFFFF for 0. 0 itself means none */
- return sum ? htons((unsigned short)sum) : 0xFFFF;
+ return sum ? htons((unsigned short)sum) : htons(0xFFFF);
}
static struct proto ddp_proto = {
@@ -1289,7 +1289,7 @@ static int handle_ip_over_ddp(struct sk_buff *skb)
#endif
static void atalk_route_packet(struct sk_buff *skb, struct net_device *dev,
- struct ddpehdr *ddp, struct ddpebits *ddphv,
+ struct ddpehdr *ddp, __u16 len_hops,
int origlen)
{
struct atalk_route *rt;
@@ -1317,10 +1317,12 @@ static void atalk_route_packet(struct sk_buff *skb, struct net_device *dev,
/* Route the packet */
rt = atrtr_find(&ta);
- if (!rt || ddphv->deh_hops == DDP_MAXHOPS)
+ /* increment hops count */
+ len_hops += 1 << 10;
+ if (!rt || !(len_hops & (15 << 10)))
goto free_it;
+
/* FIXME: use skb->cb to be able to use shared skbs */
- ddphv->deh_hops++;
/*
* Route goes through another gateway, so set the target to the
@@ -1335,11 +1337,10 @@ static void atalk_route_packet(struct sk_buff *skb, struct net_device *dev,
/* Fix up skb->len field */
skb_trim(skb, min_t(unsigned int, origlen,
(rt->dev->hard_header_len +
- ddp_dl->header_length + ddphv->deh_len)));
+ ddp_dl->header_length + (len_hops & 1023))));
- /* Mend the byte order */
/* FIXME: use skb->cb to be able to use shared skbs */
- *((__u16 *)ddp) = ntohs(*((__u16 *)ddphv));
+ ddp->deh_len_hops = htons(len_hops);
/*
* Send the buffer onwards
@@ -1394,7 +1395,7 @@ static int atalk_rcv(struct sk_buff *skb, struct net_device *dev,
struct atalk_iface *atif;
struct sockaddr_at tosat;
int origlen;
- struct ddpebits ddphv;
+ __u16 len_hops;
/* Don't mangle buffer if shared */
if (!(skb = skb_share_check(skb, GFP_ATOMIC)))
@@ -1406,16 +1407,11 @@ static int atalk_rcv(struct sk_buff *skb, struct net_device *dev,
ddp = ddp_hdr(skb);
- /*
- * Fix up the length field [Ok this is horrible but otherwise
- * I end up with unions of bit fields and messy bit field order
- * compiler/endian dependencies..]
- */
- *((__u16 *)&ddphv) = ntohs(*((__u16 *)ddp));
+ len_hops = ntohs(ddp->deh_len_hops);
/* Trim buffer in case of stray trailing data */
origlen = skb->len;
- skb_trim(skb, min_t(unsigned int, skb->len, ddphv.deh_len));
+ skb_trim(skb, min_t(unsigned int, skb->len, len_hops & 1023));
/*
* Size check to see if ddp->deh_len was crap
@@ -1430,7 +1426,7 @@ static int atalk_rcv(struct sk_buff *skb, struct net_device *dev,
* valid for net byte orders all over the networking code...
*/
if (ddp->deh_sum &&
- atalk_checksum(skb, ddphv.deh_len) != ddp->deh_sum)
+ atalk_checksum(skb, len_hops & 1023) != ddp->deh_sum)
/* Not a valid AppleTalk frame - dustbin time */
goto freeit;
@@ -1444,7 +1440,7 @@ static int atalk_rcv(struct sk_buff *skb, struct net_device *dev,
/* Not ours, so we route the packet via the correct
* AppleTalk iface
*/
- atalk_route_packet(skb, dev, ddp, &ddphv, origlen);
+ atalk_route_packet(skb, dev, ddp, len_hops, origlen);
goto out;
}
@@ -1489,7 +1485,7 @@ static int ltalk_rcv(struct sk_buff *skb, struct net_device *dev,
/* Find our address */
struct atalk_addr *ap = atalk_find_dev_addr(dev);
- if (!ap || skb->len < sizeof(struct ddpshdr))
+ if (!ap || skb->len < sizeof(__be16) || skb->len > 1023)
goto freeit;
/* Don't mangle buffer if shared */
@@ -1519,11 +1515,8 @@ static int ltalk_rcv(struct sk_buff *skb, struct net_device *dev,
/*
* Not sure about this bit...
*/
- ddp->deh_len = skb->len;
- ddp->deh_hops = DDP_MAXHOPS; /* Non routable, so force a drop
- if we slip up later */
- /* Mend the byte order */
- *((__u16 *)ddp) = htons(*((__u16 *)ddp));
+ /* Non routable, so force a drop if we slip up later */
+ ddp->deh_len_hops = htons(skb->len + (DDP_MAXHOPS << 10));
}
skb->h.raw = skb->data;
@@ -1622,16 +1615,7 @@ static int atalk_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr
SOCK_DEBUG(sk, "SK %p: Begin build.\n", sk);
ddp = (struct ddpehdr *)skb_put(skb, sizeof(struct ddpehdr));
- ddp->deh_pad = 0;
- ddp->deh_hops = 0;
- ddp->deh_len = len + sizeof(*ddp);
- /*
- * Fix up the length field [Ok this is horrible but otherwise
- * I end up with unions of bit fields and messy bit field order
- * compiler/endian dependencies..
- */
- *((__u16 *)ddp) = ntohs(*((__u16 *)ddp));
-
+ ddp->deh_len_hops = htons(len + sizeof(*ddp));
ddp->deh_dnet = usat->sat_addr.s_net;
ddp->deh_snet = at->src_net;
ddp->deh_dnode = usat->sat_addr.s_node;
@@ -1712,8 +1696,8 @@ static int atalk_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr
struct sockaddr_at *sat = (struct sockaddr_at *)msg->msg_name;
struct ddpehdr *ddp;
int copied = 0;
+ int offset = 0;
int err = 0;
- struct ddpebits ddphv;
struct sk_buff *skb = skb_recv_datagram(sk, flags & ~MSG_DONTWAIT,
flags & MSG_DONTWAIT, &err);
if (!skb)
@@ -1721,25 +1705,18 @@ static int atalk_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr
/* FIXME: use skb->cb to be able to use shared skbs */
ddp = ddp_hdr(skb);
- *((__u16 *)&ddphv) = ntohs(*((__u16 *)ddp));
+ copied = ntohs(ddp->deh_len_hops) & 1023;
- if (sk->sk_type == SOCK_RAW) {
- copied = ddphv.deh_len;
- if (copied > size) {
- copied = size;
- msg->msg_flags |= MSG_TRUNC;
- }
+ if (sk->sk_type != SOCK_RAW) {
+ offset = sizeof(*ddp);
+ copied -= offset;
+ }
- err = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied);
- } else {
- copied = ddphv.deh_len - sizeof(*ddp);
- if (copied > size) {
- copied = size;
- msg->msg_flags |= MSG_TRUNC;
- }
- err = skb_copy_datagram_iovec(skb, sizeof(*ddp),
- msg->msg_iov, copied);
+ if (copied > size) {
+ copied = size;
+ msg->msg_flags |= MSG_TRUNC;
}
+ err = skb_copy_datagram_iovec(skb, offset, msg->msg_iov, copied);
if (!err) {
if (sat) {
diff --git a/net/atm/lec.c b/net/atm/lec.c
index b4aa489849df..66c57c1091a8 100644
--- a/net/atm/lec.c
+++ b/net/atm/lec.c
@@ -1,7 +1,7 @@
/*
* lec.c: Lan Emulation driver
- * Marko Kiiskila mkiiskila@yahoo.com
*
+ * Marko Kiiskila <mkiiskila@yahoo.com>
*/
#include <linux/kernel.h>
@@ -38,7 +38,7 @@
#include <linux/if_bridge.h>
#include "../bridge/br_private.h"
-static unsigned char bridge_ula_lec[] = {0x01, 0x80, 0xc2, 0x00, 0x00};
+static unsigned char bridge_ula_lec[] = { 0x01, 0x80, 0xc2, 0x00, 0x00 };
#endif
/* Modular too */
@@ -55,38 +55,41 @@ static unsigned char bridge_ula_lec[] = {0x01, 0x80, 0xc2, 0x00, 0x00};
#define DPRINTK(format,args...)
#endif
-#define DUMP_PACKETS 0 /* 0 = None,
- * 1 = 30 first bytes
- * 2 = Whole packet
- */
+#define DUMP_PACKETS 0 /*
+ * 0 = None,
+ * 1 = 30 first bytes
+ * 2 = Whole packet
+ */
-#define LEC_UNRES_QUE_LEN 8 /* number of tx packets to queue for a
- single destination while waiting for SVC */
+#define LEC_UNRES_QUE_LEN 8 /*
+ * number of tx packets to queue for a
+ * single destination while waiting for SVC
+ */
static int lec_open(struct net_device *dev);
static int lec_start_xmit(struct sk_buff *skb, struct net_device *dev);
static int lec_close(struct net_device *dev);
static struct net_device_stats *lec_get_stats(struct net_device *dev);
static void lec_init(struct net_device *dev);
-static struct lec_arp_table* lec_arp_find(struct lec_priv *priv,
- unsigned char *mac_addr);
+static struct lec_arp_table *lec_arp_find(struct lec_priv *priv,
+ unsigned char *mac_addr);
static int lec_arp_remove(struct lec_priv *priv,
- struct lec_arp_table *to_remove);
+ struct lec_arp_table *to_remove);
/* LANE2 functions */
-static void lane2_associate_ind (struct net_device *dev, u8 *mac_address,
- u8 *tlvs, u32 sizeoftlvs);
+static void lane2_associate_ind(struct net_device *dev, u8 *mac_address,
+ u8 *tlvs, u32 sizeoftlvs);
static int lane2_resolve(struct net_device *dev, u8 *dst_mac, int force,
- u8 **tlvs, u32 *sizeoftlvs);
-static int lane2_associate_req (struct net_device *dev, u8 *lan_dst,
- u8 *tlvs, u32 sizeoftlvs);
+ u8 **tlvs, u32 *sizeoftlvs);
+static int lane2_associate_req(struct net_device *dev, u8 *lan_dst,
+ u8 *tlvs, u32 sizeoftlvs);
-static int lec_addr_delete(struct lec_priv *priv, unsigned char *atm_addr,
+static int lec_addr_delete(struct lec_priv *priv, unsigned char *atm_addr,
unsigned long permanent);
static void lec_arp_check_empties(struct lec_priv *priv,
struct atm_vcc *vcc, struct sk_buff *skb);
static void lec_arp_destroy(struct lec_priv *priv);
static void lec_arp_init(struct lec_priv *priv);
-static struct atm_vcc* lec_arp_resolve(struct lec_priv *priv,
+static struct atm_vcc *lec_arp_resolve(struct lec_priv *priv,
unsigned char *mac_to_find,
int is_rdesc,
struct lec_arp_table **ret_entry);
@@ -100,16 +103,30 @@ static void lec_set_flush_tran_id(struct lec_priv *priv,
unsigned long tran_id);
static void lec_vcc_added(struct lec_priv *priv, struct atmlec_ioc *ioc_data,
struct atm_vcc *vcc,
- void (*old_push)(struct atm_vcc *vcc, struct sk_buff *skb));
+ void (*old_push) (struct atm_vcc *vcc,
+ struct sk_buff *skb));
static void lec_vcc_close(struct lec_priv *priv, struct atm_vcc *vcc);
+/* must be done under lec_arp_lock */
+static inline void lec_arp_hold(struct lec_arp_table *entry)
+{
+ atomic_inc(&entry->usage);
+}
+
+static inline void lec_arp_put(struct lec_arp_table *entry)
+{
+ if (atomic_dec_and_test(&entry->usage))
+ kfree(entry);
+}
+
+
static struct lane2_ops lane2_ops = {
- lane2_resolve, /* resolve, spec 3.1.3 */
- lane2_associate_req, /* associate_req, spec 3.1.4 */
- NULL /* associate indicator, spec 3.1.5 */
+ lane2_resolve, /* resolve, spec 3.1.3 */
+ lane2_associate_req, /* associate_req, spec 3.1.4 */
+ NULL /* associate indicator, spec 3.1.5 */
};
-static unsigned char bus_mac[ETH_ALEN] = {0xff,0xff,0xff,0xff,0xff,0xff};
+static unsigned char bus_mac[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
/* Device structures */
static struct net_device *dev_lec[MAX_LEC_ITF];
@@ -117,36 +134,39 @@ static struct net_device *dev_lec[MAX_LEC_ITF];
#if defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE)
static void lec_handle_bridge(struct sk_buff *skb, struct net_device *dev)
{
- struct ethhdr *eth;
- char *buff;
- struct lec_priv *priv;
-
- /* Check if this is a BPDU. If so, ask zeppelin to send
- * LE_TOPOLOGY_REQUEST with the same value of Topology Change bit
- * as the Config BPDU has */
- eth = (struct ethhdr *)skb->data;
- buff = skb->data + skb->dev->hard_header_len;
- if (*buff++ == 0x42 && *buff++ == 0x42 && *buff++ == 0x03) {
+ struct ethhdr *eth;
+ char *buff;
+ struct lec_priv *priv;
+
+ /*
+ * Check if this is a BPDU. If so, ask zeppelin to send
+ * LE_TOPOLOGY_REQUEST with the same value of Topology Change bit
+ * as the Config BPDU has
+ */
+ eth = (struct ethhdr *)skb->data;
+ buff = skb->data + skb->dev->hard_header_len;
+ if (*buff++ == 0x42 && *buff++ == 0x42 && *buff++ == 0x03) {
struct sock *sk;
- struct sk_buff *skb2;
- struct atmlec_msg *mesg;
-
- skb2 = alloc_skb(sizeof(struct atmlec_msg), GFP_ATOMIC);
- if (skb2 == NULL) return;
- skb2->len = sizeof(struct atmlec_msg);
- mesg = (struct atmlec_msg *)skb2->data;
- mesg->type = l_topology_change;
- buff += 4;
- mesg->content.normal.flag = *buff & 0x01; /* 0x01 is topology change */
-
- priv = (struct lec_priv *)dev->priv;
- atm_force_charge(priv->lecd, skb2->truesize);
+ struct sk_buff *skb2;
+ struct atmlec_msg *mesg;
+
+ skb2 = alloc_skb(sizeof(struct atmlec_msg), GFP_ATOMIC);
+ if (skb2 == NULL)
+ return;
+ skb2->len = sizeof(struct atmlec_msg);
+ mesg = (struct atmlec_msg *)skb2->data;
+ mesg->type = l_topology_change;
+ buff += 4;
+ mesg->content.normal.flag = *buff & 0x01; /* 0x01 is topology change */
+
+ priv = (struct lec_priv *)dev->priv;
+ atm_force_charge(priv->lecd, skb2->truesize);
sk = sk_atm(priv->lecd);
- skb_queue_tail(&sk->sk_receive_queue, skb2);
- sk->sk_data_ready(sk, skb2->len);
- }
+ skb_queue_tail(&sk->sk_receive_queue, skb2);
+ sk->sk_data_ready(sk, skb2->len);
+ }
- return;
+ return;
}
#endif /* defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE) */
@@ -162,36 +182,35 @@ static void lec_handle_bridge(struct sk_buff *skb, struct net_device *dev)
#ifdef CONFIG_TR
static unsigned char *get_tr_dst(unsigned char *packet, unsigned char *rdesc)
{
- struct trh_hdr *trh;
- int riflen, num_rdsc;
-
- trh = (struct trh_hdr *)packet;
- if (trh->daddr[0] & (uint8_t)0x80)
- return bus_mac; /* multicast */
-
- if (trh->saddr[0] & TR_RII) {
- riflen = (ntohs(trh->rcf) & TR_RCF_LEN_MASK) >> 8;
- if ((ntohs(trh->rcf) >> 13) != 0)
- return bus_mac; /* ARE or STE */
- }
- else
- return trh->daddr; /* not source routed */
-
- if (riflen < 6)
- return trh->daddr; /* last hop, source routed */
-
- /* riflen is 6 or more, packet has more than one route descriptor */
- num_rdsc = (riflen/2) - 1;
- memset(rdesc, 0, ETH_ALEN);
- /* offset 4 comes from LAN destination field in LE control frames */
- if (trh->rcf & htons((uint16_t)TR_RCF_DIR_BIT))
- memcpy(&rdesc[4], &trh->rseg[num_rdsc-2], sizeof(uint16_t));
- else {
- memcpy(&rdesc[4], &trh->rseg[1], sizeof(uint16_t));
- rdesc[5] = ((ntohs(trh->rseg[0]) & 0x000f) | (rdesc[5] & 0xf0));
- }
-
- return NULL;
+ struct trh_hdr *trh;
+ int riflen, num_rdsc;
+
+ trh = (struct trh_hdr *)packet;
+ if (trh->daddr[0] & (uint8_t) 0x80)
+ return bus_mac; /* multicast */
+
+ if (trh->saddr[0] & TR_RII) {
+ riflen = (ntohs(trh->rcf) & TR_RCF_LEN_MASK) >> 8;
+ if ((ntohs(trh->rcf) >> 13) != 0)
+ return bus_mac; /* ARE or STE */
+ } else
+ return trh->daddr; /* not source routed */
+
+ if (riflen < 6)
+ return trh->daddr; /* last hop, source routed */
+
+ /* riflen is 6 or more, packet has more than one route descriptor */
+ num_rdsc = (riflen / 2) - 1;
+ memset(rdesc, 0, ETH_ALEN);
+ /* offset 4 comes from LAN destination field in LE control frames */
+ if (trh->rcf & htons((uint16_t) TR_RCF_DIR_BIT))
+ memcpy(&rdesc[4], &trh->rseg[num_rdsc - 2], sizeof(uint16_t));
+ else {
+ memcpy(&rdesc[4], &trh->rseg[1], sizeof(uint16_t));
+ rdesc[5] = ((ntohs(trh->rseg[0]) & 0x000f) | (rdesc[5] & 0xf0));
+ }
+
+ return NULL;
}
#endif /* CONFIG_TR */
@@ -204,15 +223,14 @@ static unsigned char *get_tr_dst(unsigned char *packet, unsigned char *rdesc)
* there is non-reboot way to recover if something goes wrong.
*/
-static int
-lec_open(struct net_device *dev)
+static int lec_open(struct net_device *dev)
{
- struct lec_priv *priv = (struct lec_priv *)dev->priv;
-
+ struct lec_priv *priv = (struct lec_priv *)dev->priv;
+
netif_start_queue(dev);
- memset(&priv->stats,0,sizeof(struct net_device_stats));
-
- return 0;
+ memset(&priv->stats, 0, sizeof(struct net_device_stats));
+
+ return 0;
}
static __inline__ void
@@ -231,160 +249,166 @@ lec_send(struct atm_vcc *vcc, struct sk_buff *skb, struct lec_priv *priv)
priv->stats.tx_bytes += skb->len;
}
-static void
-lec_tx_timeout(struct net_device *dev)
+static void lec_tx_timeout(struct net_device *dev)
{
printk(KERN_INFO "%s: tx timeout\n", dev->name);
dev->trans_start = jiffies;
netif_wake_queue(dev);
}
-static int
-lec_start_xmit(struct sk_buff *skb, struct net_device *dev)
+static int lec_start_xmit(struct sk_buff *skb, struct net_device *dev)
{
- struct sk_buff *skb2;
- struct lec_priv *priv = (struct lec_priv *)dev->priv;
- struct lecdatahdr_8023 *lec_h;
- struct atm_vcc *vcc;
+ struct sk_buff *skb2;
+ struct lec_priv *priv = (struct lec_priv *)dev->priv;
+ struct lecdatahdr_8023 *lec_h;
+ struct atm_vcc *vcc;
struct lec_arp_table *entry;
- unsigned char *dst;
+ unsigned char *dst;
int min_frame_size;
#ifdef CONFIG_TR
- unsigned char rdesc[ETH_ALEN]; /* Token Ring route descriptor */
+ unsigned char rdesc[ETH_ALEN]; /* Token Ring route descriptor */
#endif
- int is_rdesc;
+ int is_rdesc;
#if DUMP_PACKETS > 0
- char buf[300];
- int i=0;
+ char buf[300];
+ int i = 0;
#endif /* DUMP_PACKETS >0 */
-
- DPRINTK("lec_start_xmit called\n");
- if (!priv->lecd) {
- printk("%s:No lecd attached\n",dev->name);
- priv->stats.tx_errors++;
- netif_stop_queue(dev);
- return -EUNATCH;
- }
-
- DPRINTK("skbuff head:%lx data:%lx tail:%lx end:%lx\n",
- (long)skb->head, (long)skb->data, (long)skb->tail,
- (long)skb->end);
+
+ DPRINTK("lec_start_xmit called\n");
+ if (!priv->lecd) {
+ printk("%s:No lecd attached\n", dev->name);
+ priv->stats.tx_errors++;
+ netif_stop_queue(dev);
+ return -EUNATCH;
+ }
+
+ DPRINTK("skbuff head:%lx data:%lx tail:%lx end:%lx\n",
+ (long)skb->head, (long)skb->data, (long)skb->tail,
+ (long)skb->end);
#if defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE)
- if (memcmp(skb->data, bridge_ula_lec, sizeof(bridge_ula_lec)) == 0)
- lec_handle_bridge(skb, dev);
+ if (memcmp(skb->data, bridge_ula_lec, sizeof(bridge_ula_lec)) == 0)
+ lec_handle_bridge(skb, dev);
#endif
- /* Make sure we have room for lec_id */
- if (skb_headroom(skb) < 2) {
+ /* Make sure we have room for lec_id */
+ if (skb_headroom(skb) < 2) {
- DPRINTK("lec_start_xmit: reallocating skb\n");
- skb2 = skb_realloc_headroom(skb, LEC_HEADER_LEN);
- kfree_skb(skb);
- if (skb2 == NULL) return 0;
- skb = skb2;
- }
- skb_push(skb, 2);
+ DPRINTK("lec_start_xmit: reallocating skb\n");
+ skb2 = skb_realloc_headroom(skb, LEC_HEADER_LEN);
+ kfree_skb(skb);
+ if (skb2 == NULL)
+ return 0;
+ skb = skb2;
+ }
+ skb_push(skb, 2);
- /* Put le header to place, works for TokenRing too */
- lec_h = (struct lecdatahdr_8023*)skb->data;
- lec_h->le_header = htons(priv->lecid);
+ /* Put le header to place, works for TokenRing too */
+ lec_h = (struct lecdatahdr_8023 *)skb->data;
+ lec_h->le_header = htons(priv->lecid);
#ifdef CONFIG_TR
- /* Ugly. Use this to realign Token Ring packets for
- * e.g. PCA-200E driver. */
- if (priv->is_trdev) {
- skb2 = skb_realloc_headroom(skb, LEC_HEADER_LEN);
- kfree_skb(skb);
- if (skb2 == NULL) return 0;
- skb = skb2;
- }
+ /*
+ * Ugly. Use this to realign Token Ring packets for
+ * e.g. PCA-200E driver.
+ */
+ if (priv->is_trdev) {
+ skb2 = skb_realloc_headroom(skb, LEC_HEADER_LEN);
+ kfree_skb(skb);
+ if (skb2 == NULL)
+ return 0;
+ skb = skb2;
+ }
#endif
#if DUMP_PACKETS > 0
- printk("%s: send datalen:%ld lecid:%4.4x\n", dev->name,
- skb->len, priv->lecid);
+ printk("%s: send datalen:%ld lecid:%4.4x\n", dev->name,
+ skb->len, priv->lecid);
#if DUMP_PACKETS >= 2
- for(i=0;i<skb->len && i <99;i++) {
- sprintf(buf+i*3,"%2.2x ",0xff&skb->data[i]);
- }
+ for (i = 0; i < skb->len && i < 99; i++) {
+ sprintf(buf + i * 3, "%2.2x ", 0xff & skb->data[i]);
+ }
#elif DUMP_PACKETS >= 1
- for(i=0;i<skb->len && i < 30;i++) {
- sprintf(buf+i*3,"%2.2x ", 0xff&skb->data[i]);
- }
+ for (i = 0; i < skb->len && i < 30; i++) {
+ sprintf(buf + i * 3, "%2.2x ", 0xff & skb->data[i]);
+ }
#endif /* DUMP_PACKETS >= 1 */
- if (i==skb->len)
- printk("%s\n",buf);
- else
- printk("%s...\n",buf);
+ if (i == skb->len)
+ printk("%s\n", buf);
+ else
+ printk("%s...\n", buf);
#endif /* DUMP_PACKETS > 0 */
- /* Minimum ethernet-frame size */
+ /* Minimum ethernet-frame size */
#ifdef CONFIG_TR
- if (priv->is_trdev)
- min_frame_size = LEC_MINIMUM_8025_SIZE;
+ if (priv->is_trdev)
+ min_frame_size = LEC_MINIMUM_8025_SIZE;
else
#endif
- min_frame_size = LEC_MINIMUM_8023_SIZE;
- if (skb->len < min_frame_size) {
- if ((skb->len + skb_tailroom(skb)) < min_frame_size) {
- skb2 = skb_copy_expand(skb, 0,
- min_frame_size - skb->truesize, GFP_ATOMIC);
- dev_kfree_skb(skb);
- if (skb2 == NULL) {
- priv->stats.tx_dropped++;
- return 0;
- }
- skb = skb2;
- }
+ min_frame_size = LEC_MINIMUM_8023_SIZE;
+ if (skb->len < min_frame_size) {
+ if ((skb->len + skb_tailroom(skb)) < min_frame_size) {
+ skb2 = skb_copy_expand(skb, 0,
+ min_frame_size - skb->truesize,
+ GFP_ATOMIC);
+ dev_kfree_skb(skb);
+ if (skb2 == NULL) {
+ priv->stats.tx_dropped++;
+ return 0;
+ }
+ skb = skb2;
+ }
skb_put(skb, min_frame_size - skb->len);
- }
-
- /* Send to right vcc */
- is_rdesc = 0;
- dst = lec_h->h_dest;
+ }
+
+ /* Send to right vcc */
+ is_rdesc = 0;
+ dst = lec_h->h_dest;
#ifdef CONFIG_TR
- if (priv->is_trdev) {
- dst = get_tr_dst(skb->data+2, rdesc);
- if (dst == NULL) {
- dst = rdesc;
- is_rdesc = 1;
- }
- }
+ if (priv->is_trdev) {
+ dst = get_tr_dst(skb->data + 2, rdesc);
+ if (dst == NULL) {
+ dst = rdesc;
+ is_rdesc = 1;
+ }
+ }
#endif
- entry = NULL;
- vcc = lec_arp_resolve(priv, dst, is_rdesc, &entry);
- DPRINTK("%s:vcc:%p vcc_flags:%x, entry:%p\n", dev->name,
- vcc, vcc?vcc->flags:0, entry);
- if (!vcc || !test_bit(ATM_VF_READY,&vcc->flags)) {
- if (entry && (entry->tx_wait.qlen < LEC_UNRES_QUE_LEN)) {
- DPRINTK("%s:lec_start_xmit: queuing packet, ", dev->name);
- DPRINTK("MAC address 0x%02x:%02x:%02x:%02x:%02x:%02x\n",
- lec_h->h_dest[0], lec_h->h_dest[1], lec_h->h_dest[2],
- lec_h->h_dest[3], lec_h->h_dest[4], lec_h->h_dest[5]);
- skb_queue_tail(&entry->tx_wait, skb);
- } else {
- DPRINTK("%s:lec_start_xmit: tx queue full or no arp entry, dropping, ", dev->name);
- DPRINTK("MAC address 0x%02x:%02x:%02x:%02x:%02x:%02x\n",
- lec_h->h_dest[0], lec_h->h_dest[1], lec_h->h_dest[2],
- lec_h->h_dest[3], lec_h->h_dest[4], lec_h->h_dest[5]);
- priv->stats.tx_dropped++;
- dev_kfree_skb(skb);
- }
- return 0;
- }
-
-#if DUMP_PACKETS > 0
- printk("%s:sending to vpi:%d vci:%d\n", dev->name,
- vcc->vpi, vcc->vci);
+ entry = NULL;
+ vcc = lec_arp_resolve(priv, dst, is_rdesc, &entry);
+ DPRINTK("%s:vcc:%p vcc_flags:%x, entry:%p\n", dev->name,
+ vcc, vcc ? vcc->flags : 0, entry);
+ if (!vcc || !test_bit(ATM_VF_READY, &vcc->flags)) {
+ if (entry && (entry->tx_wait.qlen < LEC_UNRES_QUE_LEN)) {
+ DPRINTK("%s:lec_start_xmit: queuing packet, ",
+ dev->name);
+ DPRINTK("MAC address 0x%02x:%02x:%02x:%02x:%02x:%02x\n",
+ lec_h->h_dest[0], lec_h->h_dest[1],
+ lec_h->h_dest[2], lec_h->h_dest[3],
+ lec_h->h_dest[4], lec_h->h_dest[5]);
+ skb_queue_tail(&entry->tx_wait, skb);
+ } else {
+ DPRINTK
+ ("%s:lec_start_xmit: tx queue full or no arp entry, dropping, ",
+ dev->name);
+ DPRINTK("MAC address 0x%02x:%02x:%02x:%02x:%02x:%02x\n",
+ lec_h->h_dest[0], lec_h->h_dest[1],
+ lec_h->h_dest[2], lec_h->h_dest[3],
+ lec_h->h_dest[4], lec_h->h_dest[5]);
+ priv->stats.tx_dropped++;
+ dev_kfree_skb(skb);
+ }
+ goto out;
+ }
+#if DUMP_PACKETS > 0
+ printk("%s:sending to vpi:%d vci:%d\n", dev->name, vcc->vpi, vcc->vci);
#endif /* DUMP_PACKETS > 0 */
-
- while (entry && (skb2 = skb_dequeue(&entry->tx_wait))) {
- DPRINTK("lec.c: emptying tx queue, ");
- DPRINTK("MAC address 0x%02x:%02x:%02x:%02x:%02x:%02x\n",
- lec_h->h_dest[0], lec_h->h_dest[1], lec_h->h_dest[2],
- lec_h->h_dest[3], lec_h->h_dest[4], lec_h->h_dest[5]);
+
+ while (entry && (skb2 = skb_dequeue(&entry->tx_wait))) {
+ DPRINTK("lec.c: emptying tx queue, ");
+ DPRINTK("MAC address 0x%02x:%02x:%02x:%02x:%02x:%02x\n",
+ lec_h->h_dest[0], lec_h->h_dest[1], lec_h->h_dest[2],
+ lec_h->h_dest[3], lec_h->h_dest[4], lec_h->h_dest[5]);
lec_send(vcc, skb2, priv);
- }
+ }
lec_send(vcc, skb, priv);
@@ -404,210 +428,219 @@ lec_start_xmit(struct sk_buff *skb, struct net_device *dev)
netif_wake_queue(dev);
}
+out:
+ if (entry)
+ lec_arp_put(entry);
dev->trans_start = jiffies;
- return 0;
+ return 0;
}
/* The inverse routine to net_open(). */
-static int
-lec_close(struct net_device *dev)
+static int lec_close(struct net_device *dev)
{
- netif_stop_queue(dev);
- return 0;
+ netif_stop_queue(dev);
+ return 0;
}
/*
* Get the current statistics.
* This may be called with the card open or closed.
*/
-static struct net_device_stats *
-lec_get_stats(struct net_device *dev)
+static struct net_device_stats *lec_get_stats(struct net_device *dev)
{
- return &((struct lec_priv *)dev->priv)->stats;
+ return &((struct lec_priv *)dev->priv)->stats;
}
-static int
-lec_atm_send(struct atm_vcc *vcc, struct sk_buff *skb)
+static int lec_atm_send(struct atm_vcc *vcc, struct sk_buff *skb)
{
unsigned long flags;
- struct net_device *dev = (struct net_device*)vcc->proto_data;
- struct lec_priv *priv = (struct lec_priv*)dev->priv;
- struct atmlec_msg *mesg;
- struct lec_arp_table *entry;
- int i;
- char *tmp; /* FIXME */
+ struct net_device *dev = (struct net_device *)vcc->proto_data;
+ struct lec_priv *priv = (struct lec_priv *)dev->priv;
+ struct atmlec_msg *mesg;
+ struct lec_arp_table *entry;
+ int i;
+ char *tmp; /* FIXME */
atomic_sub(skb->truesize, &sk_atm(vcc)->sk_wmem_alloc);
- mesg = (struct atmlec_msg *)skb->data;
- tmp = skb->data;
- tmp += sizeof(struct atmlec_msg);
- DPRINTK("%s: msg from zeppelin:%d\n", dev->name, mesg->type);
- switch(mesg->type) {
- case l_set_mac_addr:
- for (i=0;i<6;i++) {
- dev->dev_addr[i] = mesg->content.normal.mac_addr[i];
- }
- break;
- case l_del_mac_addr:
- for(i=0;i<6;i++) {
- dev->dev_addr[i] = 0;
- }
- break;
- case l_addr_delete:
- lec_addr_delete(priv, mesg->content.normal.atm_addr,
- mesg->content.normal.flag);
- break;
- case l_topology_change:
- priv->topology_change = mesg->content.normal.flag;
- break;
- case l_flush_complete:
- lec_flush_complete(priv, mesg->content.normal.flag);
- break;
- case l_narp_req: /* LANE2: see 7.1.35 in the lane2 spec */
+ mesg = (struct atmlec_msg *)skb->data;
+ tmp = skb->data;
+ tmp += sizeof(struct atmlec_msg);
+ DPRINTK("%s: msg from zeppelin:%d\n", dev->name, mesg->type);
+ switch (mesg->type) {
+ case l_set_mac_addr:
+ for (i = 0; i < 6; i++) {
+ dev->dev_addr[i] = mesg->content.normal.mac_addr[i];
+ }
+ break;
+ case l_del_mac_addr:
+ for (i = 0; i < 6; i++) {
+ dev->dev_addr[i] = 0;
+ }
+ break;
+ case l_addr_delete:
+ lec_addr_delete(priv, mesg->content.normal.atm_addr,
+ mesg->content.normal.flag);
+ break;
+ case l_topology_change:
+ priv->topology_change = mesg->content.normal.flag;
+ break;
+ case l_flush_complete:
+ lec_flush_complete(priv, mesg->content.normal.flag);
+ break;
+ case l_narp_req: /* LANE2: see 7.1.35 in the lane2 spec */
spin_lock_irqsave(&priv->lec_arp_lock, flags);
- entry = lec_arp_find(priv, mesg->content.normal.mac_addr);
- lec_arp_remove(priv, entry);
+ entry = lec_arp_find(priv, mesg->content.normal.mac_addr);
+ lec_arp_remove(priv, entry);
spin_unlock_irqrestore(&priv->lec_arp_lock, flags);
- if (mesg->content.normal.no_source_le_narp)
- break;
- /* FALL THROUGH */
- case l_arp_update:
- lec_arp_update(priv, mesg->content.normal.mac_addr,
- mesg->content.normal.atm_addr,
- mesg->content.normal.flag,
- mesg->content.normal.targetless_le_arp);
- DPRINTK("lec: in l_arp_update\n");
- if (mesg->sizeoftlvs != 0) { /* LANE2 3.1.5 */
- DPRINTK("lec: LANE2 3.1.5, got tlvs, size %d\n", mesg->sizeoftlvs);
- lane2_associate_ind(dev,
- mesg->content.normal.mac_addr,
- tmp, mesg->sizeoftlvs);
- }
- break;
- case l_config:
- priv->maximum_unknown_frame_count =
- mesg->content.config.maximum_unknown_frame_count;
- priv->max_unknown_frame_time =
- (mesg->content.config.max_unknown_frame_time*HZ);
- priv->max_retry_count =
- mesg->content.config.max_retry_count;
- priv->aging_time = (mesg->content.config.aging_time*HZ);
- priv->forward_delay_time =
- (mesg->content.config.forward_delay_time*HZ);
- priv->arp_response_time =
- (mesg->content.config.arp_response_time*HZ);
- priv->flush_timeout = (mesg->content.config.flush_timeout*HZ);
- priv->path_switching_delay =
- (mesg->content.config.path_switching_delay*HZ);
- priv->lane_version = mesg->content.config.lane_version; /* LANE2 */
+ if (mesg->content.normal.no_source_le_narp)
+ break;
+ /* FALL THROUGH */
+ case l_arp_update:
+ lec_arp_update(priv, mesg->content.normal.mac_addr,
+ mesg->content.normal.atm_addr,
+ mesg->content.normal.flag,
+ mesg->content.normal.targetless_le_arp);
+ DPRINTK("lec: in l_arp_update\n");
+ if (mesg->sizeoftlvs != 0) { /* LANE2 3.1.5 */
+ DPRINTK("lec: LANE2 3.1.5, got tlvs, size %d\n",
+ mesg->sizeoftlvs);
+ lane2_associate_ind(dev, mesg->content.normal.mac_addr,
+ tmp, mesg->sizeoftlvs);
+ }
+ break;
+ case l_config:
+ priv->maximum_unknown_frame_count =
+ mesg->content.config.maximum_unknown_frame_count;
+ priv->max_unknown_frame_time =
+ (mesg->content.config.max_unknown_frame_time * HZ);
+ priv->max_retry_count = mesg->content.config.max_retry_count;
+ priv->aging_time = (mesg->content.config.aging_time * HZ);
+ priv->forward_delay_time =
+ (mesg->content.config.forward_delay_time * HZ);
+ priv->arp_response_time =
+ (mesg->content.config.arp_response_time * HZ);
+ priv->flush_timeout = (mesg->content.config.flush_timeout * HZ);
+ priv->path_switching_delay =
+ (mesg->content.config.path_switching_delay * HZ);
+ priv->lane_version = mesg->content.config.lane_version; /* LANE2 */
priv->lane2_ops = NULL;
if (priv->lane_version > 1)
priv->lane2_ops = &lane2_ops;
if (dev->change_mtu(dev, mesg->content.config.mtu))
printk("%s: change_mtu to %d failed\n", dev->name,
- mesg->content.config.mtu);
+ mesg->content.config.mtu);
priv->is_proxy = mesg->content.config.is_proxy;
- break;
- case l_flush_tran_id:
- lec_set_flush_tran_id(priv, mesg->content.normal.atm_addr,
- mesg->content.normal.flag);
- break;
- case l_set_lecid:
- priv->lecid=(unsigned short)(0xffff&mesg->content.normal.flag);
- break;
- case l_should_bridge: {
+ break;
+ case l_flush_tran_id:
+ lec_set_flush_tran_id(priv, mesg->content.normal.atm_addr,
+ mesg->content.normal.flag);
+ break;
+ case l_set_lecid:
+ priv->lecid =
+ (unsigned short)(0xffff & mesg->content.normal.flag);
+ break;
+ case l_should_bridge:
#if defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE)
- struct net_bridge_fdb_entry *f;
-
- DPRINTK("%s: bridge zeppelin asks about 0x%02x:%02x:%02x:%02x:%02x:%02x\n",
- dev->name,
- mesg->content.proxy.mac_addr[0], mesg->content.proxy.mac_addr[1],
- mesg->content.proxy.mac_addr[2], mesg->content.proxy.mac_addr[3],
- mesg->content.proxy.mac_addr[4], mesg->content.proxy.mac_addr[5]);
-
- if (br_fdb_get_hook == NULL || dev->br_port == NULL)
- break;
-
- f = br_fdb_get_hook(dev->br_port->br, mesg->content.proxy.mac_addr);
- if (f != NULL &&
- f->dst->dev != dev &&
- f->dst->state == BR_STATE_FORWARDING) {
- /* hit from bridge table, send LE_ARP_RESPONSE */
- struct sk_buff *skb2;
- struct sock *sk;
-
- DPRINTK("%s: entry found, responding to zeppelin\n", dev->name);
- skb2 = alloc_skb(sizeof(struct atmlec_msg), GFP_ATOMIC);
- if (skb2 == NULL) {
- br_fdb_put_hook(f);
- break;
- }
- skb2->len = sizeof(struct atmlec_msg);
- memcpy(skb2->data, mesg, sizeof(struct atmlec_msg));
- atm_force_charge(priv->lecd, skb2->truesize);
- sk = sk_atm(priv->lecd);
- skb_queue_tail(&sk->sk_receive_queue, skb2);
- sk->sk_data_ready(sk, skb2->len);
- }
- if (f != NULL) br_fdb_put_hook(f);
+ {
+ struct net_bridge_fdb_entry *f;
+
+ DPRINTK
+ ("%s: bridge zeppelin asks about 0x%02x:%02x:%02x:%02x:%02x:%02x\n",
+ dev->name, mesg->content.proxy.mac_addr[0],
+ mesg->content.proxy.mac_addr[1],
+ mesg->content.proxy.mac_addr[2],
+ mesg->content.proxy.mac_addr[3],
+ mesg->content.proxy.mac_addr[4],
+ mesg->content.proxy.mac_addr[5]);
+
+ if (br_fdb_get_hook == NULL || dev->br_port == NULL)
+ break;
+
+ f = br_fdb_get_hook(dev->br_port->br,
+ mesg->content.proxy.mac_addr);
+ if (f != NULL && f->dst->dev != dev
+ && f->dst->state == BR_STATE_FORWARDING) {
+ /* hit from bridge table, send LE_ARP_RESPONSE */
+ struct sk_buff *skb2;
+ struct sock *sk;
+
+ DPRINTK
+ ("%s: entry found, responding to zeppelin\n",
+ dev->name);
+ skb2 =
+ alloc_skb(sizeof(struct atmlec_msg),
+ GFP_ATOMIC);
+ if (skb2 == NULL) {
+ br_fdb_put_hook(f);
+ break;
+ }
+ skb2->len = sizeof(struct atmlec_msg);
+ memcpy(skb2->data, mesg,
+ sizeof(struct atmlec_msg));
+ atm_force_charge(priv->lecd, skb2->truesize);
+ sk = sk_atm(priv->lecd);
+ skb_queue_tail(&sk->sk_receive_queue, skb2);
+ sk->sk_data_ready(sk, skb2->len);
+ }
+ if (f != NULL)
+ br_fdb_put_hook(f);
+ }
#endif /* defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE) */
- }
- break;
- default:
- printk("%s: Unknown message type %d\n", dev->name, mesg->type);
- dev_kfree_skb(skb);
- return -EINVAL;
- }
- dev_kfree_skb(skb);
- return 0;
+ break;
+ default:
+ printk("%s: Unknown message type %d\n", dev->name, mesg->type);
+ dev_kfree_skb(skb);
+ return -EINVAL;
+ }
+ dev_kfree_skb(skb);
+ return 0;
}
-static void
-lec_atm_close(struct atm_vcc *vcc)
+static void lec_atm_close(struct atm_vcc *vcc)
{
- struct sk_buff *skb;
- struct net_device *dev = (struct net_device *)vcc->proto_data;
- struct lec_priv *priv = (struct lec_priv *)dev->priv;
+ struct sk_buff *skb;
+ struct net_device *dev = (struct net_device *)vcc->proto_data;
+ struct lec_priv *priv = (struct lec_priv *)dev->priv;
- priv->lecd = NULL;
- /* Do something needful? */
+ priv->lecd = NULL;
+ /* Do something needful? */
- netif_stop_queue(dev);
- lec_arp_destroy(priv);
+ netif_stop_queue(dev);
+ lec_arp_destroy(priv);
- if (skb_peek(&sk_atm(vcc)->sk_receive_queue))
+ if (skb_peek(&sk_atm(vcc)->sk_receive_queue))
printk("%s lec_atm_close: closing with messages pending\n",
- dev->name);
- while ((skb = skb_dequeue(&sk_atm(vcc)->sk_receive_queue)) != NULL) {
- atm_return(vcc, skb->truesize);
+ dev->name);
+ while ((skb = skb_dequeue(&sk_atm(vcc)->sk_receive_queue)) != NULL) {
+ atm_return(vcc, skb->truesize);
dev_kfree_skb(skb);
- }
-
+ }
+
printk("%s: Shut down!\n", dev->name);
- module_put(THIS_MODULE);
+ module_put(THIS_MODULE);
}
static struct atmdev_ops lecdev_ops = {
- .close = lec_atm_close,
- .send = lec_atm_send
+ .close = lec_atm_close,
+ .send = lec_atm_send
};
static struct atm_dev lecatm_dev = {
- .ops = &lecdev_ops,
- .type = "lec",
- .number = 999, /* dummy device number */
- .lock = SPIN_LOCK_UNLOCKED
+ .ops = &lecdev_ops,
+ .type = "lec",
+ .number = 999, /* dummy device number */
+ .lock = SPIN_LOCK_UNLOCKED
};
/*
* LANE2: new argument struct sk_buff *data contains
* the LE_ARP based TLVs introduced in the LANE2 spec
*/
-static int
-send_to_lecd(struct lec_priv *priv, atmlec_msg_type type,
- unsigned char *mac_addr, unsigned char *atm_addr,
- struct sk_buff *data)
+static int
+send_to_lecd(struct lec_priv *priv, atmlec_msg_type type,
+ unsigned char *mac_addr, unsigned char *atm_addr,
+ struct sk_buff *data)
{
struct sock *sk;
struct sk_buff *skb;
@@ -621,187 +654,193 @@ send_to_lecd(struct lec_priv *priv, atmlec_msg_type type,
return -1;
skb->len = sizeof(struct atmlec_msg);
mesg = (struct atmlec_msg *)skb->data;
- memset(mesg, 0, sizeof(struct atmlec_msg));
+ memset(mesg, 0, sizeof(struct atmlec_msg));
mesg->type = type;
- if (data != NULL)
- mesg->sizeoftlvs = data->len;
+ if (data != NULL)
+ mesg->sizeoftlvs = data->len;
if (mac_addr)
memcpy(&mesg->content.normal.mac_addr, mac_addr, ETH_ALEN);
- else
- mesg->content.normal.targetless_le_arp = 1;
+ else
+ mesg->content.normal.targetless_le_arp = 1;
if (atm_addr)
memcpy(&mesg->content.normal.atm_addr, atm_addr, ATM_ESA_LEN);
- atm_force_charge(priv->lecd, skb->truesize);
+ atm_force_charge(priv->lecd, skb->truesize);
sk = sk_atm(priv->lecd);
skb_queue_tail(&sk->sk_receive_queue, skb);
- sk->sk_data_ready(sk, skb->len);
+ sk->sk_data_ready(sk, skb->len);
- if (data != NULL) {
- DPRINTK("lec: about to send %d bytes of data\n", data->len);
- atm_force_charge(priv->lecd, data->truesize);
- skb_queue_tail(&sk->sk_receive_queue, data);
- sk->sk_data_ready(sk, skb->len);
- }
+ if (data != NULL) {
+ DPRINTK("lec: about to send %d bytes of data\n", data->len);
+ atm_force_charge(priv->lecd, data->truesize);
+ skb_queue_tail(&sk->sk_receive_queue, data);
+ sk->sk_data_ready(sk, skb->len);
+ }
- return 0;
+ return 0;
}
/* shamelessly stolen from drivers/net/net_init.c */
static int lec_change_mtu(struct net_device *dev, int new_mtu)
{
- if ((new_mtu < 68) || (new_mtu > 18190))
- return -EINVAL;
- dev->mtu = new_mtu;
- return 0;
+ if ((new_mtu < 68) || (new_mtu > 18190))
+ return -EINVAL;
+ dev->mtu = new_mtu;
+ return 0;
}
static void lec_set_multicast_list(struct net_device *dev)
{
- /* by default, all multicast frames arrive over the bus.
- * eventually support selective multicast service
- */
- return;
+ /*
+ * by default, all multicast frames arrive over the bus.
+ * eventually support selective multicast service
+ */
+ return;
}
-static void
-lec_init(struct net_device *dev)
+static void lec_init(struct net_device *dev)
{
- dev->change_mtu = lec_change_mtu;
- dev->open = lec_open;
- dev->stop = lec_close;
- dev->hard_start_xmit = lec_start_xmit;
+ dev->change_mtu = lec_change_mtu;
+ dev->open = lec_open;
+ dev->stop = lec_close;
+ dev->hard_start_xmit = lec_start_xmit;
dev->tx_timeout = lec_tx_timeout;
- dev->get_stats = lec_get_stats;
- dev->set_multicast_list = lec_set_multicast_list;
- dev->do_ioctl = NULL;
- printk("%s: Initialized!\n",dev->name);
- return;
+ dev->get_stats = lec_get_stats;
+ dev->set_multicast_list = lec_set_multicast_list;
+ dev->do_ioctl = NULL;
+ printk("%s: Initialized!\n", dev->name);
+ return;
}
static unsigned char lec_ctrl_magic[] = {
- 0xff,
- 0x00,
- 0x01,
- 0x01 };
+ 0xff,
+ 0x00,
+ 0x01,
+ 0x01
+};
#define LEC_DATA_DIRECT_8023 2
#define LEC_DATA_DIRECT_8025 3
static int lec_is_data_direct(struct atm_vcc *vcc)
-{
+{
return ((vcc->sap.blli[0].l3.tr9577.snap[4] == LEC_DATA_DIRECT_8023) ||
(vcc->sap.blli[0].l3.tr9577.snap[4] == LEC_DATA_DIRECT_8025));
-}
+}
-static void
-lec_push(struct atm_vcc *vcc, struct sk_buff *skb)
+static void lec_push(struct atm_vcc *vcc, struct sk_buff *skb)
{
unsigned long flags;
- struct net_device *dev = (struct net_device *)vcc->proto_data;
- struct lec_priv *priv = (struct lec_priv *)dev->priv;
+ struct net_device *dev = (struct net_device *)vcc->proto_data;
+ struct lec_priv *priv = (struct lec_priv *)dev->priv;
#if DUMP_PACKETS >0
- int i=0;
- char buf[300];
+ int i = 0;
+ char buf[300];
- printk("%s: lec_push vcc vpi:%d vci:%d\n", dev->name,
- vcc->vpi, vcc->vci);
+ printk("%s: lec_push vcc vpi:%d vci:%d\n", dev->name,
+ vcc->vpi, vcc->vci);
#endif
- if (!skb) {
- DPRINTK("%s: null skb\n",dev->name);
- lec_vcc_close(priv, vcc);
- return;
- }
+ if (!skb) {
+ DPRINTK("%s: null skb\n", dev->name);
+ lec_vcc_close(priv, vcc);
+ return;
+ }
#if DUMP_PACKETS > 0
- printk("%s: rcv datalen:%ld lecid:%4.4x\n", dev->name,
- skb->len, priv->lecid);
+ printk("%s: rcv datalen:%ld lecid:%4.4x\n", dev->name,
+ skb->len, priv->lecid);
#if DUMP_PACKETS >= 2
- for(i=0;i<skb->len && i <99;i++) {
- sprintf(buf+i*3,"%2.2x ",0xff&skb->data[i]);
- }
+ for (i = 0; i < skb->len && i < 99; i++) {
+ sprintf(buf + i * 3, "%2.2x ", 0xff & skb->data[i]);
+ }
#elif DUMP_PACKETS >= 1
- for(i=0;i<skb->len && i < 30;i++) {
- sprintf(buf+i*3,"%2.2x ", 0xff&skb->data[i]);
- }
+ for (i = 0; i < skb->len && i < 30; i++) {
+ sprintf(buf + i * 3, "%2.2x ", 0xff & skb->data[i]);
+ }
#endif /* DUMP_PACKETS >= 1 */
- if (i==skb->len)
- printk("%s\n",buf);
- else
- printk("%s...\n",buf);
+ if (i == skb->len)
+ printk("%s\n", buf);
+ else
+ printk("%s...\n", buf);
#endif /* DUMP_PACKETS > 0 */
- if (memcmp(skb->data, lec_ctrl_magic, 4) ==0) { /* Control frame, to daemon*/
+ if (memcmp(skb->data, lec_ctrl_magic, 4) == 0) { /* Control frame, to daemon */
struct sock *sk = sk_atm(vcc);
- DPRINTK("%s: To daemon\n",dev->name);
- skb_queue_tail(&sk->sk_receive_queue, skb);
- sk->sk_data_ready(sk, skb->len);
- } else { /* Data frame, queue to protocol handlers */
+ DPRINTK("%s: To daemon\n", dev->name);
+ skb_queue_tail(&sk->sk_receive_queue, skb);
+ sk->sk_data_ready(sk, skb->len);
+ } else { /* Data frame, queue to protocol handlers */
struct lec_arp_table *entry;
- unsigned char *src, *dst;
-
- atm_return(vcc,skb->truesize);
- if (*(uint16_t *)skb->data == htons(priv->lecid) ||
- !priv->lecd ||
- !(dev->flags & IFF_UP)) {
- /* Probably looping back, or if lecd is missing,
- lecd has gone down */
- DPRINTK("Ignoring frame...\n");
- dev_kfree_skb(skb);
- return;
- }
+ unsigned char *src, *dst;
+
+ atm_return(vcc, skb->truesize);
+ if (*(uint16_t *) skb->data == htons(priv->lecid) ||
+ !priv->lecd || !(dev->flags & IFF_UP)) {
+ /*
+ * Probably looping back, or if lecd is missing,
+ * lecd has gone down
+ */
+ DPRINTK("Ignoring frame...\n");
+ dev_kfree_skb(skb);
+ return;
+ }
#ifdef CONFIG_TR
- if (priv->is_trdev)
- dst = ((struct lecdatahdr_8025 *) skb->data)->h_dest;
- else
+ if (priv->is_trdev)
+ dst = ((struct lecdatahdr_8025 *)skb->data)->h_dest;
+ else
#endif
- dst = ((struct lecdatahdr_8023 *) skb->data)->h_dest;
+ dst = ((struct lecdatahdr_8023 *)skb->data)->h_dest;
- /* If this is a Data Direct VCC, and the VCC does not match
+ /*
+ * If this is a Data Direct VCC, and the VCC does not match
* the LE_ARP cache entry, delete the LE_ARP cache entry.
*/
spin_lock_irqsave(&priv->lec_arp_lock, flags);
if (lec_is_data_direct(vcc)) {
#ifdef CONFIG_TR
if (priv->is_trdev)
- src = ((struct lecdatahdr_8025 *) skb->data)->h_source;
+ src =
+ ((struct lecdatahdr_8025 *)skb->data)->
+ h_source;
else
#endif
- src = ((struct lecdatahdr_8023 *) skb->data)->h_source;
+ src =
+ ((struct lecdatahdr_8023 *)skb->data)->
+ h_source;
entry = lec_arp_find(priv, src);
if (entry && entry->vcc != vcc) {
lec_arp_remove(priv, entry);
- kfree(entry);
+ lec_arp_put(entry);
}
}
spin_unlock_irqrestore(&priv->lec_arp_lock, flags);
- if (!(dst[0]&0x01) && /* Never filter Multi/Broadcast */
- !priv->is_proxy && /* Proxy wants all the packets */
+ if (!(dst[0] & 0x01) && /* Never filter Multi/Broadcast */
+ !priv->is_proxy && /* Proxy wants all the packets */
memcmp(dst, dev->dev_addr, dev->addr_len)) {
- dev_kfree_skb(skb);
- return;
- }
- if (priv->lec_arp_empty_ones) {
- lec_arp_check_empties(priv, vcc, skb);
- }
- skb->dev = dev;
- skb_pull(skb, 2); /* skip lec_id */
+ dev_kfree_skb(skb);
+ return;
+ }
+ if (!hlist_empty(&priv->lec_arp_empty_ones)) {
+ lec_arp_check_empties(priv, vcc, skb);
+ }
+ skb->dev = dev;
+ skb_pull(skb, 2); /* skip lec_id */
#ifdef CONFIG_TR
- if (priv->is_trdev) skb->protocol = tr_type_trans(skb, dev);
- else
+ if (priv->is_trdev)
+ skb->protocol = tr_type_trans(skb, dev);
+ else
#endif
- skb->protocol = eth_type_trans(skb, dev);
- priv->stats.rx_packets++;
- priv->stats.rx_bytes += skb->len;
- memset(ATM_SKB(skb), 0, sizeof(struct atm_skb_data));
- netif_rx(skb);
- }
+ skb->protocol = eth_type_trans(skb, dev);
+ priv->stats.rx_packets++;
+ priv->stats.rx_bytes += skb->len;
+ memset(ATM_SKB(skb), 0, sizeof(struct atm_skb_data));
+ netif_rx(skb);
+ }
}
-static void
-lec_pop(struct atm_vcc *vcc, struct sk_buff *skb)
+static void lec_pop(struct atm_vcc *vcc, struct sk_buff *skb)
{
struct lec_vcc_priv *vpriv = LEC_VCC_PRIV(vcc);
struct net_device *dev = skb->dev;
@@ -820,123 +859,121 @@ lec_pop(struct atm_vcc *vcc, struct sk_buff *skb)
}
}
-static int
-lec_vcc_attach(struct atm_vcc *vcc, void __user *arg)
+static int lec_vcc_attach(struct atm_vcc *vcc, void __user *arg)
{
struct lec_vcc_priv *vpriv;
- int bytes_left;
- struct atmlec_ioc ioc_data;
-
- /* Lecd must be up in this case */
- bytes_left = copy_from_user(&ioc_data, arg, sizeof(struct atmlec_ioc));
- if (bytes_left != 0) {
- printk("lec: lec_vcc_attach, copy from user failed for %d bytes\n",
- bytes_left);
- }
- if (ioc_data.dev_num < 0 || ioc_data.dev_num >= MAX_LEC_ITF ||
- !dev_lec[ioc_data.dev_num])
- return -EINVAL;
+ int bytes_left;
+ struct atmlec_ioc ioc_data;
+
+ /* Lecd must be up in this case */
+ bytes_left = copy_from_user(&ioc_data, arg, sizeof(struct atmlec_ioc));
+ if (bytes_left != 0) {
+ printk
+ ("lec: lec_vcc_attach, copy from user failed for %d bytes\n",
+ bytes_left);
+ }
+ if (ioc_data.dev_num < 0 || ioc_data.dev_num >= MAX_LEC_ITF ||
+ !dev_lec[ioc_data.dev_num])
+ return -EINVAL;
if (!(vpriv = kmalloc(sizeof(struct lec_vcc_priv), GFP_KERNEL)))
return -ENOMEM;
vpriv->xoff = 0;
vpriv->old_pop = vcc->pop;
vcc->user_back = vpriv;
vcc->pop = lec_pop;
- lec_vcc_added(dev_lec[ioc_data.dev_num]->priv,
- &ioc_data, vcc, vcc->push);
- vcc->proto_data = dev_lec[ioc_data.dev_num];
- vcc->push = lec_push;
- return 0;
+ lec_vcc_added(dev_lec[ioc_data.dev_num]->priv,
+ &ioc_data, vcc, vcc->push);
+ vcc->proto_data = dev_lec[ioc_data.dev_num];
+ vcc->push = lec_push;
+ return 0;
}
-static int
-lec_mcast_attach(struct atm_vcc *vcc, int arg)
+static int lec_mcast_attach(struct atm_vcc *vcc, int arg)
{
- if (arg <0 || arg >= MAX_LEC_ITF || !dev_lec[arg])
- return -EINVAL;
- vcc->proto_data = dev_lec[arg];
- return (lec_mcast_make((struct lec_priv*)dev_lec[arg]->priv, vcc));
+ if (arg < 0 || arg >= MAX_LEC_ITF || !dev_lec[arg])
+ return -EINVAL;
+ vcc->proto_data = dev_lec[arg];
+ return (lec_mcast_make((struct lec_priv *)dev_lec[arg]->priv, vcc));
}
/* Initialize device. */
-static int
-lecd_attach(struct atm_vcc *vcc, int arg)
-{
- int i;
- struct lec_priv *priv;
-
- if (arg<0)
- i = 0;
- else
- i = arg;
+static int lecd_attach(struct atm_vcc *vcc, int arg)
+{
+ int i;
+ struct lec_priv *priv;
+
+ if (arg < 0)
+ i = 0;
+ else
+ i = arg;
#ifdef CONFIG_TR
- if (arg >= MAX_LEC_ITF)
- return -EINVAL;
-#else /* Reserve the top NUM_TR_DEVS for TR */
- if (arg >= (MAX_LEC_ITF-NUM_TR_DEVS))
- return -EINVAL;
+ if (arg >= MAX_LEC_ITF)
+ return -EINVAL;
+#else /* Reserve the top NUM_TR_DEVS for TR */
+ if (arg >= (MAX_LEC_ITF - NUM_TR_DEVS))
+ return -EINVAL;
#endif
- if (!dev_lec[i]) {
- int is_trdev, size;
+ if (!dev_lec[i]) {
+ int is_trdev, size;
- is_trdev = 0;
- if (i >= (MAX_LEC_ITF - NUM_TR_DEVS))
- is_trdev = 1;
+ is_trdev = 0;
+ if (i >= (MAX_LEC_ITF - NUM_TR_DEVS))
+ is_trdev = 1;
- size = sizeof(struct lec_priv);
+ size = sizeof(struct lec_priv);
#ifdef CONFIG_TR
- if (is_trdev)
- dev_lec[i] = alloc_trdev(size);
- else
+ if (is_trdev)
+ dev_lec[i] = alloc_trdev(size);
+ else
#endif
- dev_lec[i] = alloc_etherdev(size);
- if (!dev_lec[i])
- return -ENOMEM;
- snprintf(dev_lec[i]->name, IFNAMSIZ, "lec%d", i);
- if (register_netdev(dev_lec[i])) {
- free_netdev(dev_lec[i]);
- return -EINVAL;
- }
-
- priv = dev_lec[i]->priv;
- priv->is_trdev = is_trdev;
- lec_init(dev_lec[i]);
- } else {
- priv = dev_lec[i]->priv;
- if (priv->lecd)
- return -EADDRINUSE;
- }
- lec_arp_init(priv);
- priv->itfnum = i; /* LANE2 addition */
- priv->lecd = vcc;
- vcc->dev = &lecatm_dev;
- vcc_insert_socket(sk_atm(vcc));
-
- vcc->proto_data = dev_lec[i];
- set_bit(ATM_VF_META,&vcc->flags);
- set_bit(ATM_VF_READY,&vcc->flags);
-
- /* Set default values to these variables */
- priv->maximum_unknown_frame_count = 1;
- priv->max_unknown_frame_time = (1*HZ);
- priv->vcc_timeout_period = (1200*HZ);
- priv->max_retry_count = 1;
- priv->aging_time = (300*HZ);
- priv->forward_delay_time = (15*HZ);
- priv->topology_change = 0;
- priv->arp_response_time = (1*HZ);
- priv->flush_timeout = (4*HZ);
- priv->path_switching_delay = (6*HZ);
-
- if (dev_lec[i]->flags & IFF_UP) {
- netif_start_queue(dev_lec[i]);
- }
- __module_get(THIS_MODULE);
- return i;
+ dev_lec[i] = alloc_etherdev(size);
+ if (!dev_lec[i])
+ return -ENOMEM;
+ snprintf(dev_lec[i]->name, IFNAMSIZ, "lec%d", i);
+ if (register_netdev(dev_lec[i])) {
+ free_netdev(dev_lec[i]);
+ return -EINVAL;
+ }
+
+ priv = dev_lec[i]->priv;
+ priv->is_trdev = is_trdev;
+ lec_init(dev_lec[i]);
+ } else {
+ priv = dev_lec[i]->priv;
+ if (priv->lecd)
+ return -EADDRINUSE;
+ }
+ lec_arp_init(priv);
+ priv->itfnum = i; /* LANE2 addition */
+ priv->lecd = vcc;
+ vcc->dev = &lecatm_dev;
+ vcc_insert_socket(sk_atm(vcc));
+
+ vcc->proto_data = dev_lec[i];
+ set_bit(ATM_VF_META, &vcc->flags);
+ set_bit(ATM_VF_READY, &vcc->flags);
+
+ /* Set default values to these variables */
+ priv->maximum_unknown_frame_count = 1;
+ priv->max_unknown_frame_time = (1 * HZ);
+ priv->vcc_timeout_period = (1200 * HZ);
+ priv->max_retry_count = 1;
+ priv->aging_time = (300 * HZ);
+ priv->forward_delay_time = (15 * HZ);
+ priv->topology_change = 0;
+ priv->arp_response_time = (1 * HZ);
+ priv->flush_timeout = (4 * HZ);
+ priv->path_switching_delay = (6 * HZ);
+
+ if (dev_lec[i]->flags & IFF_UP) {
+ netif_start_queue(dev_lec[i]);
+ }
+ __module_get(THIS_MODULE);
+ return i;
}
#ifdef CONFIG_PROC_FS
-static char* lec_arp_get_status_string(unsigned char status)
+static char *lec_arp_get_status_string(unsigned char status)
{
static char *lec_arp_status_string[] = {
"ESI_UNKNOWN ",
@@ -966,52 +1003,54 @@ static void lec_info(struct seq_file *seq, struct lec_arp_table *entry)
if (entry->vcc)
seq_printf(seq, "%3d %3d ", entry->vcc->vpi, entry->vcc->vci);
else
- seq_printf(seq, " ");
+ seq_printf(seq, " ");
if (entry->recv_vcc) {
seq_printf(seq, " %3d %3d", entry->recv_vcc->vpi,
entry->recv_vcc->vci);
- }
- seq_putc(seq, '\n');
+ }
+ seq_putc(seq, '\n');
}
-
struct lec_state {
unsigned long flags;
struct lec_priv *locked;
- struct lec_arp_table *entry;
+ struct hlist_node *node;
struct net_device *dev;
int itf;
int arp_table;
int misc_table;
};
-static void *lec_tbl_walk(struct lec_state *state, struct lec_arp_table *tbl,
+static void *lec_tbl_walk(struct lec_state *state, struct hlist_head *tbl,
loff_t *l)
{
- struct lec_arp_table *e = state->entry;
+ struct hlist_node *e = state->node;
+ struct lec_arp_table *tmp;
if (!e)
- e = tbl;
+ e = tbl->first;
if (e == (void *)1) {
- e = tbl;
+ e = tbl->first;
--*l;
}
- for (; e; e = e->next) {
+
+ hlist_for_each_entry_from(tmp, e, next) {
if (--*l < 0)
break;
}
- state->entry = e;
+ state->node = e;
+
return (*l < 0) ? state : NULL;
}
static void *lec_arp_walk(struct lec_state *state, loff_t *l,
- struct lec_priv *priv)
+ struct lec_priv *priv)
{
void *v = NULL;
int p;
for (p = state->arp_table; p < LEC_ARP_TABLE_SIZE; p++) {
- v = lec_tbl_walk(state, priv->lec_arp_tables[p], l);
+ v = lec_tbl_walk(state, &priv->lec_arp_tables[p], l);
if (v)
break;
}
@@ -1022,10 +1061,10 @@ static void *lec_arp_walk(struct lec_state *state, loff_t *l,
static void *lec_misc_walk(struct lec_state *state, loff_t *l,
struct lec_priv *priv)
{
- struct lec_arp_table *lec_misc_tables[] = {
- priv->lec_arp_empty_ones,
- priv->lec_no_forward,
- priv->mcast_fwds
+ struct hlist_head *lec_misc_tables[] = {
+ &priv->lec_arp_empty_ones,
+ &priv->lec_no_forward,
+ &priv->mcast_fwds
};
void *v = NULL;
int q;
@@ -1046,8 +1085,7 @@ static void *lec_priv_walk(struct lec_state *state, loff_t *l,
state->locked = priv;
spin_lock_irqsave(&priv->lec_arp_lock, state->flags);
}
- if (!lec_arp_walk(state, l, priv) &&
- !lec_misc_walk(state, l, priv)) {
+ if (!lec_arp_walk(state, l, priv) && !lec_misc_walk(state, l, priv)) {
spin_unlock_irqrestore(&priv->lec_arp_lock, state->flags);
state->locked = NULL;
/* Partial state reset for the next time we get called */
@@ -1081,7 +1119,7 @@ static void *lec_get_idx(struct lec_state *state, loff_t l)
if (v)
break;
}
- return v;
+ return v;
}
static void *lec_seq_start(struct seq_file *seq, loff_t *pos)
@@ -1093,9 +1131,9 @@ static void *lec_seq_start(struct seq_file *seq, loff_t *pos)
state->locked = NULL;
state->arp_table = 0;
state->misc_table = 0;
- state->entry = (void *)1;
+ state->node = (void *)1;
- return *pos ? lec_get_idx(state, *pos) : (void*)1;
+ return *pos ? lec_get_idx(state, *pos) : (void *)1;
}
static void lec_seq_stop(struct seq_file *seq, void *v)
@@ -1120,27 +1158,28 @@ static void *lec_seq_next(struct seq_file *seq, void *v, loff_t *pos)
static int lec_seq_show(struct seq_file *seq, void *v)
{
- static char lec_banner[] = "Itf MAC ATM destination"
- " Status Flags "
- "VPI/VCI Recv VPI/VCI\n";
+ static char lec_banner[] = "Itf MAC ATM destination"
+ " Status Flags "
+ "VPI/VCI Recv VPI/VCI\n";
if (v == (void *)1)
seq_puts(seq, lec_banner);
else {
struct lec_state *state = seq->private;
- struct net_device *dev = state->dev;
+ struct net_device *dev = state->dev;
+ struct lec_arp_table *entry = hlist_entry(state->node, struct lec_arp_table, next);
seq_printf(seq, "%s ", dev->name);
- lec_info(seq, state->entry);
+ lec_info(seq, entry);
}
return 0;
}
static struct seq_operations lec_seq_ops = {
- .start = lec_seq_start,
- .next = lec_seq_next,
- .stop = lec_seq_stop,
- .show = lec_seq_show,
+ .start = lec_seq_start,
+ .next = lec_seq_next,
+ .stop = lec_seq_stop,
+ .show = lec_seq_show,
};
static int lec_seq_open(struct inode *inode, struct file *file)
@@ -1174,11 +1213,11 @@ static int lec_seq_release(struct inode *inode, struct file *file)
}
static struct file_operations lec_seq_fops = {
- .owner = THIS_MODULE,
- .open = lec_seq_open,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = lec_seq_release,
+ .owner = THIS_MODULE,
+ .open = lec_seq_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = lec_seq_release,
};
#endif
@@ -1186,38 +1225,38 @@ static int lane_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
{
struct atm_vcc *vcc = ATM_SD(sock);
int err = 0;
-
+
switch (cmd) {
- case ATMLEC_CTRL:
- case ATMLEC_MCAST:
- case ATMLEC_DATA:
- if (!capable(CAP_NET_ADMIN))
- return -EPERM;
- break;
- default:
- return -ENOIOCTLCMD;
+ case ATMLEC_CTRL:
+ case ATMLEC_MCAST:
+ case ATMLEC_DATA:
+ if (!capable(CAP_NET_ADMIN))
+ return -EPERM;
+ break;
+ default:
+ return -ENOIOCTLCMD;
}
switch (cmd) {
- case ATMLEC_CTRL:
- err = lecd_attach(vcc, (int) arg);
- if (err >= 0)
- sock->state = SS_CONNECTED;
- break;
- case ATMLEC_MCAST:
- err = lec_mcast_attach(vcc, (int) arg);
- break;
- case ATMLEC_DATA:
- err = lec_vcc_attach(vcc, (void __user *) arg);
- break;
+ case ATMLEC_CTRL:
+ err = lecd_attach(vcc, (int)arg);
+ if (err >= 0)
+ sock->state = SS_CONNECTED;
+ break;
+ case ATMLEC_MCAST:
+ err = lec_mcast_attach(vcc, (int)arg);
+ break;
+ case ATMLEC_DATA:
+ err = lec_vcc_attach(vcc, (void __user *)arg);
+ break;
}
return err;
}
static struct atm_ioctl lane_ioctl_ops = {
- .owner = THIS_MODULE,
- .ioctl = lane_ioctl,
+ .owner = THIS_MODULE,
+ .ioctl = lane_ioctl,
};
static int __init lane_module_init(void)
@@ -1231,29 +1270,29 @@ static int __init lane_module_init(void)
#endif
register_atm_ioctl(&lane_ioctl_ops);
- printk("lec.c: " __DATE__ " " __TIME__ " initialized\n");
- return 0;
+ printk("lec.c: " __DATE__ " " __TIME__ " initialized\n");
+ return 0;
}
static void __exit lane_module_cleanup(void)
{
- int i;
- struct lec_priv *priv;
+ int i;
+ struct lec_priv *priv;
remove_proc_entry("lec", atm_proc_root);
deregister_atm_ioctl(&lane_ioctl_ops);
- for (i = 0; i < MAX_LEC_ITF; i++) {
- if (dev_lec[i] != NULL) {
- priv = (struct lec_priv *)dev_lec[i]->priv;
+ for (i = 0; i < MAX_LEC_ITF; i++) {
+ if (dev_lec[i] != NULL) {
+ priv = (struct lec_priv *)dev_lec[i]->priv;
unregister_netdev(dev_lec[i]);
- free_netdev(dev_lec[i]);
- dev_lec[i] = NULL;
- }
- }
+ free_netdev(dev_lec[i]);
+ dev_lec[i] = NULL;
+ }
+ }
- return;
+ return;
}
module_init(lane_module_init);
@@ -1267,34 +1306,34 @@ module_exit(lane_module_cleanup);
* If dst_mac == NULL, targetless LE_ARP will be sent
*/
static int lane2_resolve(struct net_device *dev, u8 *dst_mac, int force,
- u8 **tlvs, u32 *sizeoftlvs)
+ u8 **tlvs, u32 *sizeoftlvs)
{
unsigned long flags;
- struct lec_priv *priv = (struct lec_priv *)dev->priv;
- struct lec_arp_table *table;
- struct sk_buff *skb;
- int retval;
+ struct lec_priv *priv = (struct lec_priv *)dev->priv;
+ struct lec_arp_table *table;
+ struct sk_buff *skb;
+ int retval;
- if (force == 0) {
+ if (force == 0) {
spin_lock_irqsave(&priv->lec_arp_lock, flags);
- table = lec_arp_find(priv, dst_mac);
+ table = lec_arp_find(priv, dst_mac);
spin_unlock_irqrestore(&priv->lec_arp_lock, flags);
- if(table == NULL)
- return -1;
-
- *tlvs = kmalloc(table->sizeoftlvs, GFP_ATOMIC);
- if (*tlvs == NULL)
- return -1;
-
- memcpy(*tlvs, table->tlvs, table->sizeoftlvs);
- *sizeoftlvs = table->sizeoftlvs;
-
- return 0;
- }
+ if (table == NULL)
+ return -1;
+
+ *tlvs = kmalloc(table->sizeoftlvs, GFP_ATOMIC);
+ if (*tlvs == NULL)
+ return -1;
+
+ memcpy(*tlvs, table->tlvs, table->sizeoftlvs);
+ *sizeoftlvs = table->sizeoftlvs;
+
+ return 0;
+ }
if (sizeoftlvs == NULL)
retval = send_to_lecd(priv, l_arp_xmt, dst_mac, NULL, NULL);
-
+
else {
skb = alloc_skb(*sizeoftlvs, GFP_ATOMIC);
if (skb == NULL)
@@ -1303,9 +1342,8 @@ static int lane2_resolve(struct net_device *dev, u8 *dst_mac, int force,
memcpy(skb->data, *tlvs, *sizeoftlvs);
retval = send_to_lecd(priv, l_arp_xmt, dst_mac, NULL, skb);
}
- return retval;
-}
-
+ return retval;
+}
/*
* LANE2: 3.1.4, LE_ASSOCIATE.request
@@ -1314,80 +1352,85 @@ static int lane2_resolve(struct net_device *dev, u8 *dst_mac, int force,
* Returns 1 for success, 0 for failure (out of memory)
*
*/
-static int lane2_associate_req (struct net_device *dev, u8 *lan_dst,
- u8 *tlvs, u32 sizeoftlvs)
+static int lane2_associate_req(struct net_device *dev, u8 *lan_dst,
+ u8 *tlvs, u32 sizeoftlvs)
{
- int retval;
- struct sk_buff *skb;
- struct lec_priv *priv = (struct lec_priv*)dev->priv;
-
- if (compare_ether_addr(lan_dst, dev->dev_addr))
- return (0); /* not our mac address */
-
- kfree(priv->tlvs); /* NULL if there was no previous association */
-
- priv->tlvs = kmalloc(sizeoftlvs, GFP_KERNEL);
- if (priv->tlvs == NULL)
- return (0);
- priv->sizeoftlvs = sizeoftlvs;
- memcpy(priv->tlvs, tlvs, sizeoftlvs);
-
- skb = alloc_skb(sizeoftlvs, GFP_ATOMIC);
- if (skb == NULL)
- return 0;
- skb->len = sizeoftlvs;
- memcpy(skb->data, tlvs, sizeoftlvs);
- retval = send_to_lecd(priv, l_associate_req, NULL, NULL, skb);
- if (retval != 0)
- printk("lec.c: lane2_associate_req() failed\n");
- /* If the previous association has changed we must
- * somehow notify other LANE entities about the change
- */
- return (1);
+ int retval;
+ struct sk_buff *skb;
+ struct lec_priv *priv = (struct lec_priv *)dev->priv;
+
+ if (compare_ether_addr(lan_dst, dev->dev_addr))
+ return (0); /* not our mac address */
+
+ kfree(priv->tlvs); /* NULL if there was no previous association */
+
+ priv->tlvs = kmalloc(sizeoftlvs, GFP_KERNEL);
+ if (priv->tlvs == NULL)
+ return (0);
+ priv->sizeoftlvs = sizeoftlvs;
+ memcpy(priv->tlvs, tlvs, sizeoftlvs);
+
+ skb = alloc_skb(sizeoftlvs, GFP_ATOMIC);
+ if (skb == NULL)
+ return 0;
+ skb->len = sizeoftlvs;
+ memcpy(skb->data, tlvs, sizeoftlvs);
+ retval = send_to_lecd(priv, l_associate_req, NULL, NULL, skb);
+ if (retval != 0)
+ printk("lec.c: lane2_associate_req() failed\n");
+ /*
+ * If the previous association has changed we must
+ * somehow notify other LANE entities about the change
+ */
+ return (1);
}
/*
* LANE2: 3.1.5, LE_ASSOCIATE.indication
*
*/
-static void lane2_associate_ind (struct net_device *dev, u8 *mac_addr,
- u8 *tlvs, u32 sizeoftlvs)
+static void lane2_associate_ind(struct net_device *dev, u8 *mac_addr,
+ u8 *tlvs, u32 sizeoftlvs)
{
#if 0
- int i = 0;
+ int i = 0;
#endif
struct lec_priv *priv = (struct lec_priv *)dev->priv;
-#if 0 /* Why have the TLVs in LE_ARP entries since we do not use them? When you
- uncomment this code, make sure the TLVs get freed when entry is killed */
- struct lec_arp_table *entry = lec_arp_find(priv, mac_addr);
+#if 0 /*
+ * Why have the TLVs in LE_ARP entries
+ * since we do not use them? When you
+ * uncomment this code, make sure the
+ * TLVs get freed when entry is killed
+ */
+ struct lec_arp_table *entry = lec_arp_find(priv, mac_addr);
- if (entry == NULL)
- return; /* should not happen */
+ if (entry == NULL)
+ return; /* should not happen */
- kfree(entry->tlvs);
+ kfree(entry->tlvs);
- entry->tlvs = kmalloc(sizeoftlvs, GFP_KERNEL);
- if (entry->tlvs == NULL)
- return;
+ entry->tlvs = kmalloc(sizeoftlvs, GFP_KERNEL);
+ if (entry->tlvs == NULL)
+ return;
- entry->sizeoftlvs = sizeoftlvs;
- memcpy(entry->tlvs, tlvs, sizeoftlvs);
+ entry->sizeoftlvs = sizeoftlvs;
+ memcpy(entry->tlvs, tlvs, sizeoftlvs);
#endif
#if 0
- printk("lec.c: lane2_associate_ind()\n");
- printk("dump of tlvs, sizeoftlvs=%d\n", sizeoftlvs);
- while (i < sizeoftlvs)
- printk("%02x ", tlvs[i++]);
-
- printk("\n");
+ printk("lec.c: lane2_associate_ind()\n");
+ printk("dump of tlvs, sizeoftlvs=%d\n", sizeoftlvs);
+ while (i < sizeoftlvs)
+ printk("%02x ", tlvs[i++]);
+
+ printk("\n");
#endif
- /* tell MPOA about the TLVs we saw */
- if (priv->lane2_ops && priv->lane2_ops->associate_indicator) {
- priv->lane2_ops->associate_indicator(dev, mac_addr,
- tlvs, sizeoftlvs);
- }
- return;
+ /* tell MPOA about the TLVs we saw */
+ if (priv->lane2_ops && priv->lane2_ops->associate_indicator) {
+ priv->lane2_ops->associate_indicator(dev, mac_addr,
+ tlvs, sizeoftlvs);
+ }
+ return;
}
/*
@@ -1395,7 +1438,6 @@ static void lane2_associate_ind (struct net_device *dev, u8 *mac_addr,
*
* lec_arpc.c was added here when making
* lane client modular. October 1997
- *
*/
#include <linux/types.h>
@@ -1406,7 +1448,6 @@ static void lane2_associate_ind (struct net_device *dev, u8 *mac_addr,
#include <linux/inetdevice.h>
#include <net/route.h>
-
#if 0
#define DPRINTK(format,args...)
/*
@@ -1417,7 +1458,7 @@ static void lane2_associate_ind (struct net_device *dev, u8 *mac_addr,
#define LEC_ARP_REFRESH_INTERVAL (3*HZ)
-static void lec_arp_check_expire(unsigned long data);
+static void lec_arp_check_expire(void *data);
static void lec_arp_expire_arp(unsigned long data);
/*
@@ -1429,474 +1470,397 @@ static void lec_arp_expire_arp(unsigned long data);
/*
* Initialization of arp-cache
*/
-static void
-lec_arp_init(struct lec_priv *priv)
+static void lec_arp_init(struct lec_priv *priv)
{
- unsigned short i;
+ unsigned short i;
- for (i = 0; i < LEC_ARP_TABLE_SIZE; i++) {
- priv->lec_arp_tables[i] = NULL;
- }
+ for (i = 0; i < LEC_ARP_TABLE_SIZE; i++) {
+ INIT_HLIST_HEAD(&priv->lec_arp_tables[i]);
+ }
+ INIT_HLIST_HEAD(&priv->lec_arp_empty_ones);
+ INIT_HLIST_HEAD(&priv->lec_no_forward);
+ INIT_HLIST_HEAD(&priv->mcast_fwds);
spin_lock_init(&priv->lec_arp_lock);
- init_timer(&priv->lec_arp_timer);
- priv->lec_arp_timer.expires = jiffies + LEC_ARP_REFRESH_INTERVAL;
- priv->lec_arp_timer.data = (unsigned long)priv;
- priv->lec_arp_timer.function = lec_arp_check_expire;
- add_timer(&priv->lec_arp_timer);
+ INIT_WORK(&priv->lec_arp_work, lec_arp_check_expire, priv);
+ schedule_delayed_work(&priv->lec_arp_work, LEC_ARP_REFRESH_INTERVAL);
}
-static void
-lec_arp_clear_vccs(struct lec_arp_table *entry)
+static void lec_arp_clear_vccs(struct lec_arp_table *entry)
{
- if (entry->vcc) {
+ if (entry->vcc) {
struct atm_vcc *vcc = entry->vcc;
struct lec_vcc_priv *vpriv = LEC_VCC_PRIV(vcc);
- struct net_device *dev = (struct net_device*) vcc->proto_data;
+ struct net_device *dev = (struct net_device *)vcc->proto_data;
- vcc->pop = vpriv->old_pop;
+ vcc->pop = vpriv->old_pop;
if (vpriv->xoff)
netif_wake_queue(dev);
kfree(vpriv);
vcc->user_back = NULL;
- vcc->push = entry->old_push;
+ vcc->push = entry->old_push;
vcc_release_async(vcc, -EPIPE);
- vcc = NULL;
- }
- if (entry->recv_vcc) {
- entry->recv_vcc->push = entry->old_recv_push;
+ entry->vcc = NULL;
+ }
+ if (entry->recv_vcc) {
+ entry->recv_vcc->push = entry->old_recv_push;
vcc_release_async(entry->recv_vcc, -EPIPE);
- entry->recv_vcc = NULL;
- }
+ entry->recv_vcc = NULL;
+ }
}
/*
* Insert entry to lec_arp_table
* LANE2: Add to the end of the list to satisfy 8.1.13
*/
-static inline void
-lec_arp_add(struct lec_priv *priv, struct lec_arp_table *to_add)
+static inline void
+lec_arp_add(struct lec_priv *priv, struct lec_arp_table *entry)
{
- unsigned short place;
- struct lec_arp_table *tmp;
-
- place = HASH(to_add->mac_addr[ETH_ALEN-1]);
- tmp = priv->lec_arp_tables[place];
- to_add->next = NULL;
- if (tmp == NULL)
- priv->lec_arp_tables[place] = to_add;
-
- else { /* add to the end */
- while (tmp->next)
- tmp = tmp->next;
- tmp->next = to_add;
- }
-
- DPRINTK("LEC_ARP: Added entry:%2.2x %2.2x %2.2x %2.2x %2.2x %2.2x\n",
- 0xff&to_add->mac_addr[0], 0xff&to_add->mac_addr[1],
- 0xff&to_add->mac_addr[2], 0xff&to_add->mac_addr[3],
- 0xff&to_add->mac_addr[4], 0xff&to_add->mac_addr[5]);
+ struct hlist_head *tmp;
+
+ tmp = &priv->lec_arp_tables[HASH(entry->mac_addr[ETH_ALEN - 1])];
+ hlist_add_head(&entry->next, tmp);
+
+ DPRINTK("LEC_ARP: Added entry:%2.2x %2.2x %2.2x %2.2x %2.2x %2.2x\n",
+ 0xff & entry->mac_addr[0], 0xff & entry->mac_addr[1],
+ 0xff & entry->mac_addr[2], 0xff & entry->mac_addr[3],
+ 0xff & entry->mac_addr[4], 0xff & entry->mac_addr[5]);
}
/*
* Remove entry from lec_arp_table
*/
-static int
-lec_arp_remove(struct lec_priv *priv,
- struct lec_arp_table *to_remove)
+static int
+lec_arp_remove(struct lec_priv *priv, struct lec_arp_table *to_remove)
{
- unsigned short place;
- struct lec_arp_table *tmp;
- int remove_vcc=1;
-
- if (!to_remove) {
- return -1;
- }
- place = HASH(to_remove->mac_addr[ETH_ALEN-1]);
- tmp = priv->lec_arp_tables[place];
- if (tmp == to_remove) {
- priv->lec_arp_tables[place] = tmp->next;
- } else {
- while(tmp && tmp->next != to_remove) {
- tmp = tmp->next;
- }
- if (!tmp) {/* Entry was not found */
- return -1;
- }
- }
- tmp->next = to_remove->next;
- del_timer(&to_remove->timer);
-
- /* If this is the only MAC connected to this VCC, also tear down
- the VCC */
- if (to_remove->status >= ESI_FLUSH_PENDING) {
- /*
- * ESI_FLUSH_PENDING, ESI_FORWARD_DIRECT
- */
- for(place = 0; place < LEC_ARP_TABLE_SIZE; place++) {
- for(tmp = priv->lec_arp_tables[place]; tmp != NULL; tmp = tmp->next) {
- if (memcmp(tmp->atm_addr, to_remove->atm_addr,
- ATM_ESA_LEN)==0) {
- remove_vcc=0;
- break;
- }
- }
- }
- if (remove_vcc)
- lec_arp_clear_vccs(to_remove);
- }
- skb_queue_purge(&to_remove->tx_wait); /* FIXME: good place for this? */
-
- DPRINTK("LEC_ARP: Removed entry:%2.2x %2.2x %2.2x %2.2x %2.2x %2.2x\n",
- 0xff&to_remove->mac_addr[0], 0xff&to_remove->mac_addr[1],
- 0xff&to_remove->mac_addr[2], 0xff&to_remove->mac_addr[3],
- 0xff&to_remove->mac_addr[4], 0xff&to_remove->mac_addr[5]);
- return 0;
+ struct hlist_node *node;
+ struct lec_arp_table *entry;
+ int i, remove_vcc = 1;
+
+ if (!to_remove) {
+ return -1;
+ }
+
+ hlist_del(&to_remove->next);
+ del_timer(&to_remove->timer);
+
+ /* If this is the only MAC connected to this VCC, also tear down the VCC */
+ if (to_remove->status >= ESI_FLUSH_PENDING) {
+ /*
+ * ESI_FLUSH_PENDING, ESI_FORWARD_DIRECT
+ */
+ for (i = 0; i < LEC_ARP_TABLE_SIZE; i++) {
+ hlist_for_each_entry(entry, node, &priv->lec_arp_tables[i], next) {
+ if (memcmp(to_remove->atm_addr,
+ entry->atm_addr, ATM_ESA_LEN) == 0) {
+ remove_vcc = 0;
+ break;
+ }
+ }
+ }
+ if (remove_vcc)
+ lec_arp_clear_vccs(to_remove);
+ }
+ skb_queue_purge(&to_remove->tx_wait); /* FIXME: good place for this? */
+
+ DPRINTK("LEC_ARP: Removed entry:%2.2x %2.2x %2.2x %2.2x %2.2x %2.2x\n",
+ 0xff & to_remove->mac_addr[0], 0xff & to_remove->mac_addr[1],
+ 0xff & to_remove->mac_addr[2], 0xff & to_remove->mac_addr[3],
+ 0xff & to_remove->mac_addr[4], 0xff & to_remove->mac_addr[5]);
+ return 0;
}
#if DEBUG_ARP_TABLE
-static char*
-get_status_string(unsigned char st)
+static char *get_status_string(unsigned char st)
{
- switch(st) {
- case ESI_UNKNOWN:
- return "ESI_UNKNOWN";
- case ESI_ARP_PENDING:
- return "ESI_ARP_PENDING";
- case ESI_VC_PENDING:
- return "ESI_VC_PENDING";
- case ESI_FLUSH_PENDING:
- return "ESI_FLUSH_PENDING";
- case ESI_FORWARD_DIRECT:
- return "ESI_FORWARD_DIRECT";
- default:
- return "<UNKNOWN>";
- }
+ switch (st) {
+ case ESI_UNKNOWN:
+ return "ESI_UNKNOWN";
+ case ESI_ARP_PENDING:
+ return "ESI_ARP_PENDING";
+ case ESI_VC_PENDING:
+ return "ESI_VC_PENDING";
+ case ESI_FLUSH_PENDING:
+ return "ESI_FLUSH_PENDING";
+ case ESI_FORWARD_DIRECT:
+ return "ESI_FORWARD_DIRECT";
+ default:
+ return "<UNKNOWN>";
+ }
}
-#endif
-static void
-dump_arp_table(struct lec_priv *priv)
+static void dump_arp_table(struct lec_priv *priv)
{
-#if DEBUG_ARP_TABLE
- int i,j, offset;
- struct lec_arp_table *rulla;
- char buf[1024];
- struct lec_arp_table **lec_arp_tables =
- (struct lec_arp_table **)priv->lec_arp_tables;
- struct lec_arp_table *lec_arp_empty_ones =
- (struct lec_arp_table *)priv->lec_arp_empty_ones;
- struct lec_arp_table *lec_no_forward =
- (struct lec_arp_table *)priv->lec_no_forward;
- struct lec_arp_table *mcast_fwds = priv->mcast_fwds;
-
-
- printk("Dump %p:\n",priv);
- for (i=0;i<LEC_ARP_TABLE_SIZE;i++) {
- rulla = lec_arp_tables[i];
- offset = 0;
- offset += sprintf(buf,"%d: %p\n",i, rulla);
- while (rulla) {
- offset += sprintf(buf+offset,"Mac:");
- for(j=0;j<ETH_ALEN;j++) {
- offset+=sprintf(buf+offset,
- "%2.2x ",
- rulla->mac_addr[j]&0xff);
- }
- offset +=sprintf(buf+offset,"Atm:");
- for(j=0;j<ATM_ESA_LEN;j++) {
- offset+=sprintf(buf+offset,
- "%2.2x ",
- rulla->atm_addr[j]&0xff);
- }
- offset+=sprintf(buf+offset,
- "Vcc vpi:%d vci:%d, Recv_vcc vpi:%d vci:%d Last_used:%lx, Timestamp:%lx, No_tries:%d ",
- rulla->vcc?rulla->vcc->vpi:0,
- rulla->vcc?rulla->vcc->vci:0,
- rulla->recv_vcc?rulla->recv_vcc->vpi:0,
- rulla->recv_vcc?rulla->recv_vcc->vci:0,
- rulla->last_used,
- rulla->timestamp, rulla->no_tries);
- offset+=sprintf(buf+offset,
- "Flags:%x, Packets_flooded:%x, Status: %s ",
- rulla->flags, rulla->packets_flooded,
- get_status_string(rulla->status));
- offset+=sprintf(buf+offset,"->%p\n",rulla->next);
- rulla = rulla->next;
- }
- printk("%s",buf);
- }
- rulla = lec_no_forward;
- if (rulla)
- printk("No forward\n");
- while(rulla) {
- offset=0;
- offset += sprintf(buf+offset,"Mac:");
- for(j=0;j<ETH_ALEN;j++) {
- offset+=sprintf(buf+offset,"%2.2x ",
- rulla->mac_addr[j]&0xff);
- }
- offset +=sprintf(buf+offset,"Atm:");
- for(j=0;j<ATM_ESA_LEN;j++) {
- offset+=sprintf(buf+offset,"%2.2x ",
- rulla->atm_addr[j]&0xff);
- }
- offset+=sprintf(buf+offset,
- "Vcc vpi:%d vci:%d, Recv_vcc vpi:%d vci:%d Last_used:%lx, Timestamp:%lx, No_tries:%d ",
- rulla->vcc?rulla->vcc->vpi:0,
- rulla->vcc?rulla->vcc->vci:0,
- rulla->recv_vcc?rulla->recv_vcc->vpi:0,
- rulla->recv_vcc?rulla->recv_vcc->vci:0,
- rulla->last_used,
- rulla->timestamp, rulla->no_tries);
- offset+=sprintf(buf+offset,
- "Flags:%x, Packets_flooded:%x, Status: %s ",
- rulla->flags, rulla->packets_flooded,
- get_status_string(rulla->status));
- offset+=sprintf(buf+offset,"->%lx\n",(long)rulla->next);
- rulla = rulla->next;
- printk("%s",buf);
- }
- rulla = lec_arp_empty_ones;
- if (rulla)
- printk("Empty ones\n");
- while(rulla) {
- offset=0;
- offset += sprintf(buf+offset,"Mac:");
- for(j=0;j<ETH_ALEN;j++) {
- offset+=sprintf(buf+offset,"%2.2x ",
- rulla->mac_addr[j]&0xff);
- }
- offset +=sprintf(buf+offset,"Atm:");
- for(j=0;j<ATM_ESA_LEN;j++) {
- offset+=sprintf(buf+offset,"%2.2x ",
- rulla->atm_addr[j]&0xff);
- }
- offset+=sprintf(buf+offset,
- "Vcc vpi:%d vci:%d, Recv_vcc vpi:%d vci:%d Last_used:%lx, Timestamp:%lx, No_tries:%d ",
- rulla->vcc?rulla->vcc->vpi:0,
- rulla->vcc?rulla->vcc->vci:0,
- rulla->recv_vcc?rulla->recv_vcc->vpi:0,
- rulla->recv_vcc?rulla->recv_vcc->vci:0,
- rulla->last_used,
- rulla->timestamp, rulla->no_tries);
- offset+=sprintf(buf+offset,
- "Flags:%x, Packets_flooded:%x, Status: %s ",
- rulla->flags, rulla->packets_flooded,
- get_status_string(rulla->status));
- offset+=sprintf(buf+offset,"->%lx\n",(long)rulla->next);
- rulla = rulla->next;
- printk("%s",buf);
- }
-
- rulla = mcast_fwds;
- if (rulla)
- printk("Multicast Forward VCCs\n");
- while(rulla) {
- offset=0;
- offset += sprintf(buf+offset,"Mac:");
- for(j=0;j<ETH_ALEN;j++) {
- offset+=sprintf(buf+offset,"%2.2x ",
- rulla->mac_addr[j]&0xff);
- }
- offset +=sprintf(buf+offset,"Atm:");
- for(j=0;j<ATM_ESA_LEN;j++) {
- offset+=sprintf(buf+offset,"%2.2x ",
- rulla->atm_addr[j]&0xff);
- }
- offset+=sprintf(buf+offset,
- "Vcc vpi:%d vci:%d, Recv_vcc vpi:%d vci:%d Last_used:%lx, Timestamp:%lx, No_tries:%d ",
- rulla->vcc?rulla->vcc->vpi:0,
- rulla->vcc?rulla->vcc->vci:0,
- rulla->recv_vcc?rulla->recv_vcc->vpi:0,
- rulla->recv_vcc?rulla->recv_vcc->vci:0,
- rulla->last_used,
- rulla->timestamp, rulla->no_tries);
- offset+=sprintf(buf+offset,
- "Flags:%x, Packets_flooded:%x, Status: %s ",
- rulla->flags, rulla->packets_flooded,
- get_status_string(rulla->status));
- offset+=sprintf(buf+offset,"->%lx\n",(long)rulla->next);
- rulla = rulla->next;
- printk("%s",buf);
- }
+ struct hlist_node *node;
+ struct lec_arp_table *rulla;
+ char buf[256];
+ int i, j, offset;
+
+ printk("Dump %p:\n", priv);
+ for (i = 0; i < LEC_ARP_TABLE_SIZE; i++) {
+ hlist_for_each_entry(rulla, node, &priv->lec_arp_tables[i], next) {
+ offset = 0;
+ offset += sprintf(buf, "%d: %p\n", i, rulla);
+ offset += sprintf(buf + offset, "Mac:");
+ for (j = 0; j < ETH_ALEN; j++) {
+ offset += sprintf(buf + offset,
+ "%2.2x ",
+ rulla->mac_addr[j] & 0xff);
+ }
+ offset += sprintf(buf + offset, "Atm:");
+ for (j = 0; j < ATM_ESA_LEN; j++) {
+ offset += sprintf(buf + offset,
+ "%2.2x ",
+ rulla->atm_addr[j] & 0xff);
+ }
+ offset += sprintf(buf + offset,
+ "Vcc vpi:%d vci:%d, Recv_vcc vpi:%d vci:%d Last_used:%lx, Timestamp:%lx, No_tries:%d ",
+ rulla->vcc ? rulla->vcc->vpi : 0,
+ rulla->vcc ? rulla->vcc->vci : 0,
+ rulla->recv_vcc ? rulla->recv_vcc->
+ vpi : 0,
+ rulla->recv_vcc ? rulla->recv_vcc->
+ vci : 0, rulla->last_used,
+ rulla->timestamp, rulla->no_tries);
+ offset +=
+ sprintf(buf + offset,
+ "Flags:%x, Packets_flooded:%x, Status: %s ",
+ rulla->flags, rulla->packets_flooded,
+ get_status_string(rulla->status));
+ printk("%s\n", buf);
+ }
+ }
+
+ if (!hlist_empty(&priv->lec_no_forward))
+ printk("No forward\n");
+ hlist_for_each_entry(rulla, node, &priv->lec_no_forward, next) {
+ offset = 0;
+ offset += sprintf(buf + offset, "Mac:");
+ for (j = 0; j < ETH_ALEN; j++) {
+ offset += sprintf(buf + offset, "%2.2x ",
+ rulla->mac_addr[j] & 0xff);
+ }
+ offset += sprintf(buf + offset, "Atm:");
+ for (j = 0; j < ATM_ESA_LEN; j++) {
+ offset += sprintf(buf + offset, "%2.2x ",
+ rulla->atm_addr[j] & 0xff);
+ }
+ offset += sprintf(buf + offset,
+ "Vcc vpi:%d vci:%d, Recv_vcc vpi:%d vci:%d Last_used:%lx, Timestamp:%lx, No_tries:%d ",
+ rulla->vcc ? rulla->vcc->vpi : 0,
+ rulla->vcc ? rulla->vcc->vci : 0,
+ rulla->recv_vcc ? rulla->recv_vcc->vpi : 0,
+ rulla->recv_vcc ? rulla->recv_vcc->vci : 0,
+ rulla->last_used,
+ rulla->timestamp, rulla->no_tries);
+ offset += sprintf(buf + offset,
+ "Flags:%x, Packets_flooded:%x, Status: %s ",
+ rulla->flags, rulla->packets_flooded,
+ get_status_string(rulla->status));
+ printk("%s\n", buf);
+ }
+
+ if (!hlist_empty(&priv->lec_arp_empty_ones))
+ printk("Empty ones\n");
+ hlist_for_each_entry(rulla, node, &priv->lec_arp_empty_ones, next) {
+ offset = 0;
+ offset += sprintf(buf + offset, "Mac:");
+ for (j = 0; j < ETH_ALEN; j++) {
+ offset += sprintf(buf + offset, "%2.2x ",
+ rulla->mac_addr[j] & 0xff);
+ }
+ offset += sprintf(buf + offset, "Atm:");
+ for (j = 0; j < ATM_ESA_LEN; j++) {
+ offset += sprintf(buf + offset, "%2.2x ",
+ rulla->atm_addr[j] & 0xff);
+ }
+ offset += sprintf(buf + offset,
+ "Vcc vpi:%d vci:%d, Recv_vcc vpi:%d vci:%d Last_used:%lx, Timestamp:%lx, No_tries:%d ",
+ rulla->vcc ? rulla->vcc->vpi : 0,
+ rulla->vcc ? rulla->vcc->vci : 0,
+ rulla->recv_vcc ? rulla->recv_vcc->vpi : 0,
+ rulla->recv_vcc ? rulla->recv_vcc->vci : 0,
+ rulla->last_used,
+ rulla->timestamp, rulla->no_tries);
+ offset += sprintf(buf + offset,
+ "Flags:%x, Packets_flooded:%x, Status: %s ",
+ rulla->flags, rulla->packets_flooded,
+ get_status_string(rulla->status));
+ printk("%s", buf);
+ }
+
+ if (!hlist_empty(&priv->mcast_fwds))
+ printk("Multicast Forward VCCs\n");
+ hlist_for_each_entry(rulla, node, &priv->mcast_fwds, next) {
+ offset = 0;
+ offset += sprintf(buf + offset, "Mac:");
+ for (j = 0; j < ETH_ALEN; j++) {
+ offset += sprintf(buf + offset, "%2.2x ",
+ rulla->mac_addr[j] & 0xff);
+ }
+ offset += sprintf(buf + offset, "Atm:");
+ for (j = 0; j < ATM_ESA_LEN; j++) {
+ offset += sprintf(buf + offset, "%2.2x ",
+ rulla->atm_addr[j] & 0xff);
+ }
+ offset += sprintf(buf + offset,
+ "Vcc vpi:%d vci:%d, Recv_vcc vpi:%d vci:%d Last_used:%lx, Timestamp:%lx, No_tries:%d ",
+ rulla->vcc ? rulla->vcc->vpi : 0,
+ rulla->vcc ? rulla->vcc->vci : 0,
+ rulla->recv_vcc ? rulla->recv_vcc->vpi : 0,
+ rulla->recv_vcc ? rulla->recv_vcc->vci : 0,
+ rulla->last_used,
+ rulla->timestamp, rulla->no_tries);
+ offset += sprintf(buf + offset,
+ "Flags:%x, Packets_flooded:%x, Status: %s ",
+ rulla->flags, rulla->packets_flooded,
+ get_status_string(rulla->status));
+ printk("%s\n", buf);
+ }
-#endif
}
+#else
+#define dump_arp_table(priv) do { } while (0)
+#endif
/*
* Destruction of arp-cache
*/
-static void
-lec_arp_destroy(struct lec_priv *priv)
+static void lec_arp_destroy(struct lec_priv *priv)
{
unsigned long flags;
- struct lec_arp_table *entry, *next;
- int i;
+ struct hlist_node *node, *next;
+ struct lec_arp_table *entry;
+ int i;
+
+ cancel_rearming_delayed_work(&priv->lec_arp_work);
- del_timer_sync(&priv->lec_arp_timer);
-
- /*
- * Remove all entries
- */
+ /*
+ * Remove all entries
+ */
spin_lock_irqsave(&priv->lec_arp_lock, flags);
- for (i = 0; i < LEC_ARP_TABLE_SIZE; i++) {
- for(entry = priv->lec_arp_tables[i]; entry != NULL; entry=next) {
- next = entry->next;
- lec_arp_remove(priv, entry);
- kfree(entry);
- }
- }
- entry = priv->lec_arp_empty_ones;
- while(entry) {
- next = entry->next;
- del_timer_sync(&entry->timer);
- lec_arp_clear_vccs(entry);
- kfree(entry);
- entry = next;
- }
- priv->lec_arp_empty_ones = NULL;
- entry = priv->lec_no_forward;
- while(entry) {
- next = entry->next;
- del_timer_sync(&entry->timer);
- lec_arp_clear_vccs(entry);
- kfree(entry);
- entry = next;
- }
- priv->lec_no_forward = NULL;
- entry = priv->mcast_fwds;
- while(entry) {
- next = entry->next;
- /* No timer, LANEv2 7.1.20 and 2.3.5.3 */
- lec_arp_clear_vccs(entry);
- kfree(entry);
- entry = next;
- }
- priv->mcast_fwds = NULL;
- priv->mcast_vcc = NULL;
- memset(priv->lec_arp_tables, 0,
- sizeof(struct lec_arp_table *) * LEC_ARP_TABLE_SIZE);
+ for (i = 0; i < LEC_ARP_TABLE_SIZE; i++) {
+ hlist_for_each_entry_safe(entry, node, next, &priv->lec_arp_tables[i], next) {
+ lec_arp_remove(priv, entry);
+ lec_arp_put(entry);
+ }
+ INIT_HLIST_HEAD(&priv->lec_arp_tables[i]);
+ }
+
+ hlist_for_each_entry_safe(entry, node, next, &priv->lec_arp_empty_ones, next) {
+ del_timer_sync(&entry->timer);
+ lec_arp_clear_vccs(entry);
+ hlist_del(&entry->next);
+ lec_arp_put(entry);
+ }
+ INIT_HLIST_HEAD(&priv->lec_arp_empty_ones);
+
+ hlist_for_each_entry_safe(entry, node, next, &priv->lec_no_forward, next) {
+ del_timer_sync(&entry->timer);
+ lec_arp_clear_vccs(entry);
+ hlist_del(&entry->next);
+ lec_arp_put(entry);
+ }
+ INIT_HLIST_HEAD(&priv->lec_no_forward);
+
+ hlist_for_each_entry_safe(entry, node, next, &priv->mcast_fwds, next) {
+ /* No timer, LANEv2 7.1.20 and 2.3.5.3 */
+ lec_arp_clear_vccs(entry);
+ hlist_del(&entry->next);
+ lec_arp_put(entry);
+ }
+ INIT_HLIST_HEAD(&priv->mcast_fwds);
+ priv->mcast_vcc = NULL;
spin_unlock_irqrestore(&priv->lec_arp_lock, flags);
}
-
/*
* Find entry by mac_address
*/
-static struct lec_arp_table*
-lec_arp_find(struct lec_priv *priv,
- unsigned char *mac_addr)
+static struct lec_arp_table *lec_arp_find(struct lec_priv *priv,
+ unsigned char *mac_addr)
{
- unsigned short place;
- struct lec_arp_table *to_return;
-
- DPRINTK("LEC_ARP: lec_arp_find :%2.2x %2.2x %2.2x %2.2x %2.2x %2.2x\n",
- mac_addr[0]&0xff, mac_addr[1]&0xff, mac_addr[2]&0xff,
- mac_addr[3]&0xff, mac_addr[4]&0xff, mac_addr[5]&0xff);
- place = HASH(mac_addr[ETH_ALEN-1]);
-
- to_return = priv->lec_arp_tables[place];
- while(to_return) {
- if (!compare_ether_addr(mac_addr, to_return->mac_addr)) {
- return to_return;
- }
- to_return = to_return->next;
- }
- return NULL;
+ struct hlist_node *node;
+ struct hlist_head *head;
+ struct lec_arp_table *entry;
+
+ DPRINTK("LEC_ARP: lec_arp_find :%2.2x %2.2x %2.2x %2.2x %2.2x %2.2x\n",
+ mac_addr[0] & 0xff, mac_addr[1] & 0xff, mac_addr[2] & 0xff,
+ mac_addr[3] & 0xff, mac_addr[4] & 0xff, mac_addr[5] & 0xff);
+
+ head = &priv->lec_arp_tables[HASH(mac_addr[ETH_ALEN - 1])];
+ hlist_for_each_entry(entry, node, head, next) {
+ if (!compare_ether_addr(mac_addr, entry->mac_addr)) {
+ return entry;
+ }
+ }
+ return NULL;
}
-static struct lec_arp_table*
-make_entry(struct lec_priv *priv, unsigned char *mac_addr)
+static struct lec_arp_table *make_entry(struct lec_priv *priv,
+ unsigned char *mac_addr)
{
- struct lec_arp_table *to_return;
-
- to_return = kzalloc(sizeof(struct lec_arp_table), GFP_ATOMIC);
- if (!to_return) {
- printk("LEC: Arp entry kmalloc failed\n");
- return NULL;
- }
- memcpy(to_return->mac_addr, mac_addr, ETH_ALEN);
- init_timer(&to_return->timer);
- to_return->timer.function = lec_arp_expire_arp;
- to_return->timer.data = (unsigned long) to_return;
- to_return->last_used = jiffies;
- to_return->priv = priv;
- skb_queue_head_init(&to_return->tx_wait);
- return to_return;
+ struct lec_arp_table *to_return;
+
+ to_return = kzalloc(sizeof(struct lec_arp_table), GFP_ATOMIC);
+ if (!to_return) {
+ printk("LEC: Arp entry kmalloc failed\n");
+ return NULL;
+ }
+ memcpy(to_return->mac_addr, mac_addr, ETH_ALEN);
+ INIT_HLIST_NODE(&to_return->next);
+ init_timer(&to_return->timer);
+ to_return->timer.function = lec_arp_expire_arp;
+ to_return->timer.data = (unsigned long)to_return;
+ to_return->last_used = jiffies;
+ to_return->priv = priv;
+ skb_queue_head_init(&to_return->tx_wait);
+ atomic_set(&to_return->usage, 1);
+ return to_return;
}
-/*
- *
- * Arp sent timer expired
- *
- */
-static void
-lec_arp_expire_arp(unsigned long data)
+/* Arp sent timer expired */
+static void lec_arp_expire_arp(unsigned long data)
{
- struct lec_arp_table *entry;
-
- entry = (struct lec_arp_table *)data;
-
- DPRINTK("lec_arp_expire_arp\n");
- if (entry->status == ESI_ARP_PENDING) {
- if (entry->no_tries <= entry->priv->max_retry_count) {
- if (entry->is_rdesc)
- send_to_lecd(entry->priv, l_rdesc_arp_xmt, entry->mac_addr, NULL, NULL);
- else
- send_to_lecd(entry->priv, l_arp_xmt, entry->mac_addr, NULL, NULL);
- entry->no_tries++;
- }
- mod_timer(&entry->timer, jiffies + (1*HZ));
- }
+ struct lec_arp_table *entry;
+
+ entry = (struct lec_arp_table *)data;
+
+ DPRINTK("lec_arp_expire_arp\n");
+ if (entry->status == ESI_ARP_PENDING) {
+ if (entry->no_tries <= entry->priv->max_retry_count) {
+ if (entry->is_rdesc)
+ send_to_lecd(entry->priv, l_rdesc_arp_xmt,
+ entry->mac_addr, NULL, NULL);
+ else
+ send_to_lecd(entry->priv, l_arp_xmt,
+ entry->mac_addr, NULL, NULL);
+ entry->no_tries++;
+ }
+ mod_timer(&entry->timer, jiffies + (1 * HZ));
+ }
}
-/*
- *
- * Unknown/unused vcc expire, remove associated entry
- *
- */
-static void
-lec_arp_expire_vcc(unsigned long data)
+/* Unknown/unused vcc expire, remove associated entry */
+static void lec_arp_expire_vcc(unsigned long data)
{
unsigned long flags;
- struct lec_arp_table *to_remove = (struct lec_arp_table*)data;
- struct lec_priv *priv = (struct lec_priv *)to_remove->priv;
- struct lec_arp_table *entry = NULL;
+ struct lec_arp_table *to_remove = (struct lec_arp_table *)data;
+ struct lec_priv *priv = (struct lec_priv *)to_remove->priv;
- del_timer(&to_remove->timer);
+ del_timer(&to_remove->timer);
- DPRINTK("LEC_ARP %p %p: lec_arp_expire_vcc vpi:%d vci:%d\n",
- to_remove, priv,
- to_remove->vcc?to_remove->recv_vcc->vpi:0,
- to_remove->vcc?to_remove->recv_vcc->vci:0);
- DPRINTK("eo:%p nf:%p\n",priv->lec_arp_empty_ones,priv->lec_no_forward);
+ DPRINTK("LEC_ARP %p %p: lec_arp_expire_vcc vpi:%d vci:%d\n",
+ to_remove, priv,
+ to_remove->vcc ? to_remove->recv_vcc->vpi : 0,
+ to_remove->vcc ? to_remove->recv_vcc->vci : 0);
spin_lock_irqsave(&priv->lec_arp_lock, flags);
- if (to_remove == priv->lec_arp_empty_ones)
- priv->lec_arp_empty_ones = to_remove->next;
- else {
- entry = priv->lec_arp_empty_ones;
- while (entry && entry->next != to_remove)
- entry = entry->next;
- if (entry)
- entry->next = to_remove->next;
- }
- if (!entry) {
- if (to_remove == priv->lec_no_forward) {
- priv->lec_no_forward = to_remove->next;
- } else {
- entry = priv->lec_no_forward;
- while (entry && entry->next != to_remove)
- entry = entry->next;
- if (entry)
- entry->next = to_remove->next;
- }
- }
+ hlist_del(&to_remove->next);
spin_unlock_irqrestore(&priv->lec_arp_lock, flags);
- lec_arp_clear_vccs(to_remove);
- kfree(to_remove);
+ lec_arp_clear_vccs(to_remove);
+ lec_arp_put(to_remove);
}
/*
@@ -1915,158 +1879,171 @@ lec_arp_expire_vcc(unsigned long data)
* to ESI_FORWARD_DIRECT. This causes the flush period to end
* regardless of the progress of the flush protocol.
*/
-static void
-lec_arp_check_expire(unsigned long data)
+static void lec_arp_check_expire(void *data)
{
unsigned long flags;
- struct lec_priv *priv = (struct lec_priv *)data;
- struct lec_arp_table *entry, *next;
- unsigned long now;
- unsigned long time_to_check;
- int i;
-
- DPRINTK("lec_arp_check_expire %p\n",priv);
- DPRINTK("expire: eo:%p nf:%p\n",priv->lec_arp_empty_ones,
- priv->lec_no_forward);
+ struct lec_priv *priv = data;
+ struct hlist_node *node, *next;
+ struct lec_arp_table *entry;
+ unsigned long now;
+ unsigned long time_to_check;
+ int i;
+
+ DPRINTK("lec_arp_check_expire %p\n", priv);
now = jiffies;
+restart:
spin_lock_irqsave(&priv->lec_arp_lock, flags);
- for(i = 0; i < LEC_ARP_TABLE_SIZE; i++) {
- for(entry = priv->lec_arp_tables[i]; entry != NULL; ) {
- if ((entry->flags) & LEC_REMOTE_FLAG &&
+ for (i = 0; i < LEC_ARP_TABLE_SIZE; i++) {
+ hlist_for_each_entry_safe(entry, node, next, &priv->lec_arp_tables[i], next) {
+ if ((entry->flags) & LEC_REMOTE_FLAG &&
priv->topology_change)
time_to_check = priv->forward_delay_time;
else
time_to_check = priv->aging_time;
DPRINTK("About to expire: %lx - %lx > %lx\n",
- now,entry->last_used, time_to_check);
- if( time_after(now, entry->last_used+
- time_to_check) &&
- !(entry->flags & LEC_PERMANENT_FLAG) &&
- !(entry->mac_addr[0] & 0x01) ) { /* LANE2: 7.1.20 */
+ now, entry->last_used, time_to_check);
+ if (time_after(now, entry->last_used + time_to_check)
+ && !(entry->flags & LEC_PERMANENT_FLAG)
+ && !(entry->mac_addr[0] & 0x01)) { /* LANE2: 7.1.20 */
/* Remove entry */
DPRINTK("LEC:Entry timed out\n");
- next = entry->next;
lec_arp_remove(priv, entry);
- kfree(entry);
- entry = next;
+ lec_arp_put(entry);
} else {
/* Something else */
if ((entry->status == ESI_VC_PENDING ||
- entry->status == ESI_ARP_PENDING)
+ entry->status == ESI_ARP_PENDING)
&& time_after_eq(now,
- entry->timestamp +
- priv->max_unknown_frame_time)) {
+ entry->timestamp +
+ priv->
+ max_unknown_frame_time)) {
entry->timestamp = jiffies;
entry->packets_flooded = 0;
if (entry->status == ESI_VC_PENDING)
- send_to_lecd(priv, l_svc_setup, entry->mac_addr, entry->atm_addr, NULL);
+ send_to_lecd(priv, l_svc_setup,
+ entry->mac_addr,
+ entry->atm_addr,
+ NULL);
}
- if (entry->status == ESI_FLUSH_PENDING
- &&
- time_after_eq(now, entry->timestamp+
- priv->path_switching_delay)) {
+ if (entry->status == ESI_FLUSH_PENDING
+ &&
+ time_after_eq(now, entry->timestamp +
+ priv->path_switching_delay)) {
struct sk_buff *skb;
+ struct atm_vcc *vcc = entry->vcc;
+ lec_arp_hold(entry);
+ spin_unlock_irqrestore(&priv->lec_arp_lock, flags);
while ((skb = skb_dequeue(&entry->tx_wait)) != NULL)
- lec_send(entry->vcc, skb, entry->priv);
+ lec_send(vcc, skb, entry->priv);
entry->last_used = jiffies;
- entry->status =
- ESI_FORWARD_DIRECT;
+ entry->status = ESI_FORWARD_DIRECT;
+ lec_arp_put(entry);
+ goto restart;
}
- entry = entry->next;
}
}
}
spin_unlock_irqrestore(&priv->lec_arp_lock, flags);
- mod_timer(&priv->lec_arp_timer, jiffies + LEC_ARP_REFRESH_INTERVAL);
+ schedule_delayed_work(&priv->lec_arp_work, LEC_ARP_REFRESH_INTERVAL);
}
+
/*
* Try to find vcc where mac_address is attached.
*
*/
-static struct atm_vcc*
-lec_arp_resolve(struct lec_priv *priv, unsigned char *mac_to_find,
- int is_rdesc, struct lec_arp_table **ret_entry)
+static struct atm_vcc *lec_arp_resolve(struct lec_priv *priv,
+ unsigned char *mac_to_find, int is_rdesc,
+ struct lec_arp_table **ret_entry)
{
unsigned long flags;
- struct lec_arp_table *entry;
+ struct lec_arp_table *entry;
struct atm_vcc *found;
- if (mac_to_find[0] & 0x01) {
- switch (priv->lane_version) {
- case 1:
- return priv->mcast_vcc;
- break;
- case 2: /* LANE2 wants arp for multicast addresses */
- if (!compare_ether_addr(mac_to_find, bus_mac))
- return priv->mcast_vcc;
- break;
- default:
- break;
- }
- }
+ if (mac_to_find[0] & 0x01) {
+ switch (priv->lane_version) {
+ case 1:
+ return priv->mcast_vcc;
+ break;
+ case 2: /* LANE2 wants arp for multicast addresses */
+ if (!compare_ether_addr(mac_to_find, bus_mac))
+ return priv->mcast_vcc;
+ break;
+ default:
+ break;
+ }
+ }
spin_lock_irqsave(&priv->lec_arp_lock, flags);
- entry = lec_arp_find(priv, mac_to_find);
-
- if (entry) {
- if (entry->status == ESI_FORWARD_DIRECT) {
- /* Connection Ok */
- entry->last_used = jiffies;
- *ret_entry = entry;
- found = entry->vcc;
+ entry = lec_arp_find(priv, mac_to_find);
+
+ if (entry) {
+ if (entry->status == ESI_FORWARD_DIRECT) {
+ /* Connection Ok */
+ entry->last_used = jiffies;
+ lec_arp_hold(entry);
+ *ret_entry = entry;
+ found = entry->vcc;
goto out;
- }
- /* If the LE_ARP cache entry is still pending, reset count to 0
+ }
+ /*
+ * If the LE_ARP cache entry is still pending, reset count to 0
* so another LE_ARP request can be made for this frame.
*/
if (entry->status == ESI_ARP_PENDING) {
entry->no_tries = 0;
}
- /* Data direct VC not yet set up, check to see if the unknown
- frame count is greater than the limit. If the limit has
- not been reached, allow the caller to send packet to
- BUS. */
- if (entry->status != ESI_FLUSH_PENDING &&
- entry->packets_flooded<priv->maximum_unknown_frame_count) {
- entry->packets_flooded++;
- DPRINTK("LEC_ARP: Flooding..\n");
- found = priv->mcast_vcc;
+ /*
+ * Data direct VC not yet set up, check to see if the unknown
+ * frame count is greater than the limit. If the limit has
+ * not been reached, allow the caller to send packet to
+ * BUS.
+ */
+ if (entry->status != ESI_FLUSH_PENDING &&
+ entry->packets_flooded <
+ priv->maximum_unknown_frame_count) {
+ entry->packets_flooded++;
+ DPRINTK("LEC_ARP: Flooding..\n");
+ found = priv->mcast_vcc;
goto out;
- }
- /* We got here because entry->status == ESI_FLUSH_PENDING
+ }
+ /*
+ * We got here because entry->status == ESI_FLUSH_PENDING
* or BUS flood limit was reached for an entry which is
* in ESI_ARP_PENDING or ESI_VC_PENDING state.
*/
- *ret_entry = entry;
- DPRINTK("lec: entry->status %d entry->vcc %p\n", entry->status, entry->vcc);
- found = NULL;
- } else {
- /* No matching entry was found */
- entry = make_entry(priv, mac_to_find);
- DPRINTK("LEC_ARP: Making entry\n");
- if (!entry) {
- found = priv->mcast_vcc;
+ lec_arp_hold(entry);
+ *ret_entry = entry;
+ DPRINTK("lec: entry->status %d entry->vcc %p\n", entry->status,
+ entry->vcc);
+ found = NULL;
+ } else {
+ /* No matching entry was found */
+ entry = make_entry(priv, mac_to_find);
+ DPRINTK("LEC_ARP: Making entry\n");
+ if (!entry) {
+ found = priv->mcast_vcc;
goto out;
- }
- lec_arp_add(priv, entry);
- /* We want arp-request(s) to be sent */
- entry->packets_flooded =1;
- entry->status = ESI_ARP_PENDING;
- entry->no_tries = 1;
- entry->last_used = entry->timestamp = jiffies;
- entry->is_rdesc = is_rdesc;
- if (entry->is_rdesc)
- send_to_lecd(priv, l_rdesc_arp_xmt, mac_to_find, NULL, NULL);
- else
- send_to_lecd(priv, l_arp_xmt, mac_to_find, NULL, NULL);
- entry->timer.expires = jiffies + (1*HZ);
- entry->timer.function = lec_arp_expire_arp;
- add_timer(&entry->timer);
- found = priv->mcast_vcc;
- }
+ }
+ lec_arp_add(priv, entry);
+ /* We want arp-request(s) to be sent */
+ entry->packets_flooded = 1;
+ entry->status = ESI_ARP_PENDING;
+ entry->no_tries = 1;
+ entry->last_used = entry->timestamp = jiffies;
+ entry->is_rdesc = is_rdesc;
+ if (entry->is_rdesc)
+ send_to_lecd(priv, l_rdesc_arp_xmt, mac_to_find, NULL,
+ NULL);
+ else
+ send_to_lecd(priv, l_arp_xmt, mac_to_find, NULL, NULL);
+ entry->timer.expires = jiffies + (1 * HZ);
+ entry->timer.function = lec_arp_expire_arp;
+ add_timer(&entry->timer);
+ found = priv->mcast_vcc;
+ }
out:
spin_unlock_irqrestore(&priv->lec_arp_lock, flags);
@@ -2074,30 +2051,30 @@ out:
}
static int
-lec_addr_delete(struct lec_priv *priv, unsigned char *atm_addr,
- unsigned long permanent)
+lec_addr_delete(struct lec_priv *priv, unsigned char *atm_addr,
+ unsigned long permanent)
{
unsigned long flags;
- struct lec_arp_table *entry, *next;
- int i;
+ struct hlist_node *node, *next;
+ struct lec_arp_table *entry;
+ int i;
- DPRINTK("lec_addr_delete\n");
+ DPRINTK("lec_addr_delete\n");
spin_lock_irqsave(&priv->lec_arp_lock, flags);
- for(i = 0; i < LEC_ARP_TABLE_SIZE; i++) {
- for(entry = priv->lec_arp_tables[i]; entry != NULL; entry = next) {
- next = entry->next;
- if (!memcmp(atm_addr, entry->atm_addr, ATM_ESA_LEN)
- && (permanent ||
- !(entry->flags & LEC_PERMANENT_FLAG))) {
+ for (i = 0; i < LEC_ARP_TABLE_SIZE; i++) {
+ hlist_for_each_entry_safe(entry, node, next, &priv->lec_arp_tables[i], next) {
+ if (!memcmp(atm_addr, entry->atm_addr, ATM_ESA_LEN)
+ && (permanent ||
+ !(entry->flags & LEC_PERMANENT_FLAG))) {
lec_arp_remove(priv, entry);
- kfree(entry);
- }
+ lec_arp_put(entry);
+ }
spin_unlock_irqrestore(&priv->lec_arp_lock, flags);
- return 0;
- }
- }
+ return 0;
+ }
+ }
spin_unlock_irqrestore(&priv->lec_arp_lock, flags);
- return -1;
+ return -1;
}
/*
@@ -2105,109 +2082,98 @@ lec_addr_delete(struct lec_priv *priv, unsigned char *atm_addr,
*/
static void
lec_arp_update(struct lec_priv *priv, unsigned char *mac_addr,
- unsigned char *atm_addr, unsigned long remoteflag,
- unsigned int targetless_le_arp)
+ unsigned char *atm_addr, unsigned long remoteflag,
+ unsigned int targetless_le_arp)
{
unsigned long flags;
- struct lec_arp_table *entry, *tmp;
- int i;
+ struct hlist_node *node, *next;
+ struct lec_arp_table *entry, *tmp;
+ int i;
- DPRINTK("lec:%s", (targetless_le_arp) ? "targetless ": " ");
- DPRINTK("lec_arp_update mac:%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x\n",
- mac_addr[0],mac_addr[1],mac_addr[2],mac_addr[3],
- mac_addr[4],mac_addr[5]);
+ DPRINTK("lec:%s", (targetless_le_arp) ? "targetless " : " ");
+ DPRINTK("lec_arp_update mac:%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x\n",
+ mac_addr[0], mac_addr[1], mac_addr[2], mac_addr[3],
+ mac_addr[4], mac_addr[5]);
spin_lock_irqsave(&priv->lec_arp_lock, flags);
- entry = lec_arp_find(priv, mac_addr);
- if (entry == NULL && targetless_le_arp)
- goto out; /* LANE2: ignore targetless LE_ARPs for which
- * we have no entry in the cache. 7.1.30
- */
- if (priv->lec_arp_empty_ones) {
- entry = priv->lec_arp_empty_ones;
- if (!memcmp(entry->atm_addr, atm_addr, ATM_ESA_LEN)) {
- priv->lec_arp_empty_ones = entry->next;
- } else {
- while(entry->next && memcmp(entry->next->atm_addr,
- atm_addr, ATM_ESA_LEN))
- entry = entry->next;
- if (entry->next) {
- tmp = entry;
- entry = entry->next;
- tmp->next = entry->next;
- } else
- entry = NULL;
-
- }
- if (entry) {
- del_timer(&entry->timer);
- tmp = lec_arp_find(priv, mac_addr);
- if (tmp) {
- del_timer(&tmp->timer);
- tmp->status = ESI_FORWARD_DIRECT;
- memcpy(tmp->atm_addr, atm_addr, ATM_ESA_LEN);
- tmp->vcc = entry->vcc;
- tmp->old_push = entry->old_push;
- tmp->last_used = jiffies;
- del_timer(&entry->timer);
- kfree(entry);
- entry=tmp;
- } else {
- entry->status = ESI_FORWARD_DIRECT;
- memcpy(entry->mac_addr, mac_addr, ETH_ALEN);
- entry->last_used = jiffies;
- lec_arp_add(priv, entry);
- }
- if (remoteflag)
- entry->flags|=LEC_REMOTE_FLAG;
- else
- entry->flags&=~LEC_REMOTE_FLAG;
- DPRINTK("After update\n");
- dump_arp_table(priv);
- goto out;
- }
- }
- entry = lec_arp_find(priv, mac_addr);
- if (!entry) {
- entry = make_entry(priv, mac_addr);
- if (!entry)
+ entry = lec_arp_find(priv, mac_addr);
+ if (entry == NULL && targetless_le_arp)
+ goto out; /*
+ * LANE2: ignore targetless LE_ARPs for which
+ * we have no entry in the cache. 7.1.30
+ */
+ if (!hlist_empty(&priv->lec_arp_empty_ones)) {
+ hlist_for_each_entry_safe(entry, node, next, &priv->lec_arp_empty_ones, next) {
+ if (memcmp(entry->atm_addr, atm_addr, ATM_ESA_LEN) == 0) {
+ hlist_del(&entry->next);
+ del_timer(&entry->timer);
+ tmp = lec_arp_find(priv, mac_addr);
+ if (tmp) {
+ del_timer(&tmp->timer);
+ tmp->status = ESI_FORWARD_DIRECT;
+ memcpy(tmp->atm_addr, atm_addr, ATM_ESA_LEN);
+ tmp->vcc = entry->vcc;
+ tmp->old_push = entry->old_push;
+ tmp->last_used = jiffies;
+ del_timer(&entry->timer);
+ lec_arp_put(entry);
+ entry = tmp;
+ } else {
+ entry->status = ESI_FORWARD_DIRECT;
+ memcpy(entry->mac_addr, mac_addr, ETH_ALEN);
+ entry->last_used = jiffies;
+ lec_arp_add(priv, entry);
+ }
+ if (remoteflag)
+ entry->flags |= LEC_REMOTE_FLAG;
+ else
+ entry->flags &= ~LEC_REMOTE_FLAG;
+ DPRINTK("After update\n");
+ dump_arp_table(priv);
+ goto out;
+ }
+ }
+ }
+
+ entry = lec_arp_find(priv, mac_addr);
+ if (!entry) {
+ entry = make_entry(priv, mac_addr);
+ if (!entry)
goto out;
- entry->status = ESI_UNKNOWN;
- lec_arp_add(priv, entry);
- /* Temporary, changes before end of function */
- }
- memcpy(entry->atm_addr, atm_addr, ATM_ESA_LEN);
- del_timer(&entry->timer);
- for(i = 0; i < LEC_ARP_TABLE_SIZE; i++) {
- for(tmp = priv->lec_arp_tables[i]; tmp; tmp=tmp->next) {
- if (entry != tmp &&
- !memcmp(tmp->atm_addr, atm_addr,
- ATM_ESA_LEN)) {
- /* Vcc to this host exists */
- if (tmp->status > ESI_VC_PENDING) {
- /*
- * ESI_FLUSH_PENDING,
- * ESI_FORWARD_DIRECT
- */
- entry->vcc = tmp->vcc;
- entry->old_push=tmp->old_push;
- }
- entry->status=tmp->status;
- break;
- }
- }
- }
- if (remoteflag)
- entry->flags|=LEC_REMOTE_FLAG;
- else
- entry->flags&=~LEC_REMOTE_FLAG;
- if (entry->status == ESI_ARP_PENDING ||
- entry->status == ESI_UNKNOWN) {
- entry->status = ESI_VC_PENDING;
- send_to_lecd(priv, l_svc_setup, entry->mac_addr, atm_addr, NULL);
- }
- DPRINTK("After update2\n");
- dump_arp_table(priv);
+ entry->status = ESI_UNKNOWN;
+ lec_arp_add(priv, entry);
+ /* Temporary, changes before end of function */
+ }
+ memcpy(entry->atm_addr, atm_addr, ATM_ESA_LEN);
+ del_timer(&entry->timer);
+ for (i = 0; i < LEC_ARP_TABLE_SIZE; i++) {
+ hlist_for_each_entry(tmp, node, &priv->lec_arp_tables[i], next) {
+ if (entry != tmp &&
+ !memcmp(tmp->atm_addr, atm_addr, ATM_ESA_LEN)) {
+ /* Vcc to this host exists */
+ if (tmp->status > ESI_VC_PENDING) {
+ /*
+ * ESI_FLUSH_PENDING,
+ * ESI_FORWARD_DIRECT
+ */
+ entry->vcc = tmp->vcc;
+ entry->old_push = tmp->old_push;
+ }
+ entry->status = tmp->status;
+ break;
+ }
+ }
+ }
+ if (remoteflag)
+ entry->flags |= LEC_REMOTE_FLAG;
+ else
+ entry->flags &= ~LEC_REMOTE_FLAG;
+ if (entry->status == ESI_ARP_PENDING || entry->status == ESI_UNKNOWN) {
+ entry->status = ESI_VC_PENDING;
+ send_to_lecd(priv, l_svc_setup, entry->mac_addr, atm_addr, NULL);
+ }
+ DPRINTK("After update2\n");
+ dump_arp_table(priv);
out:
spin_unlock_irqrestore(&priv->lec_arp_lock, flags);
}
@@ -2217,299 +2183,299 @@ out:
*/
static void
lec_vcc_added(struct lec_priv *priv, struct atmlec_ioc *ioc_data,
- struct atm_vcc *vcc,
- void (*old_push)(struct atm_vcc *vcc, struct sk_buff *skb))
+ struct atm_vcc *vcc,
+ void (*old_push) (struct atm_vcc *vcc, struct sk_buff *skb))
{
unsigned long flags;
- struct lec_arp_table *entry;
- int i, found_entry=0;
+ struct hlist_node *node;
+ struct lec_arp_table *entry;
+ int i, found_entry = 0;
spin_lock_irqsave(&priv->lec_arp_lock, flags);
- if (ioc_data->receive == 2) {
- /* Vcc for Multicast Forward. No timer, LANEv2 7.1.20 and 2.3.5.3 */
+ if (ioc_data->receive == 2) {
+ /* Vcc for Multicast Forward. No timer, LANEv2 7.1.20 and 2.3.5.3 */
- DPRINTK("LEC_ARP: Attaching mcast forward\n");
+ DPRINTK("LEC_ARP: Attaching mcast forward\n");
#if 0
- entry = lec_arp_find(priv, bus_mac);
- if (!entry) {
- printk("LEC_ARP: Multicast entry not found!\n");
+ entry = lec_arp_find(priv, bus_mac);
+ if (!entry) {
+ printk("LEC_ARP: Multicast entry not found!\n");
goto out;
- }
- memcpy(entry->atm_addr, ioc_data->atm_addr, ATM_ESA_LEN);
- entry->recv_vcc = vcc;
- entry->old_recv_push = old_push;
+ }
+ memcpy(entry->atm_addr, ioc_data->atm_addr, ATM_ESA_LEN);
+ entry->recv_vcc = vcc;
+ entry->old_recv_push = old_push;
#endif
- entry = make_entry(priv, bus_mac);
- if (entry == NULL)
+ entry = make_entry(priv, bus_mac);
+ if (entry == NULL)
goto out;
- del_timer(&entry->timer);
- memcpy(entry->atm_addr, ioc_data->atm_addr, ATM_ESA_LEN);
- entry->recv_vcc = vcc;
- entry->old_recv_push = old_push;
- entry->next = priv->mcast_fwds;
- priv->mcast_fwds = entry;
- goto out;
- } else if (ioc_data->receive == 1) {
- /* Vcc which we don't want to make default vcc, attach it
- anyway. */
- DPRINTK("LEC_ARP:Attaching data direct, not default :%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x\n",
- ioc_data->atm_addr[0],ioc_data->atm_addr[1],
- ioc_data->atm_addr[2],ioc_data->atm_addr[3],
- ioc_data->atm_addr[4],ioc_data->atm_addr[5],
- ioc_data->atm_addr[6],ioc_data->atm_addr[7],
- ioc_data->atm_addr[8],ioc_data->atm_addr[9],
- ioc_data->atm_addr[10],ioc_data->atm_addr[11],
- ioc_data->atm_addr[12],ioc_data->atm_addr[13],
- ioc_data->atm_addr[14],ioc_data->atm_addr[15],
- ioc_data->atm_addr[16],ioc_data->atm_addr[17],
- ioc_data->atm_addr[18],ioc_data->atm_addr[19]);
- entry = make_entry(priv, bus_mac);
- if (entry == NULL)
+ del_timer(&entry->timer);
+ memcpy(entry->atm_addr, ioc_data->atm_addr, ATM_ESA_LEN);
+ entry->recv_vcc = vcc;
+ entry->old_recv_push = old_push;
+ hlist_add_head(&entry->next, &priv->mcast_fwds);
+ goto out;
+ } else if (ioc_data->receive == 1) {
+ /*
+ * Vcc which we don't want to make default vcc,
+ * attach it anyway.
+ */
+ DPRINTK
+ ("LEC_ARP:Attaching data direct, not default: "
+ "%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x\n",
+ ioc_data->atm_addr[0], ioc_data->atm_addr[1],
+ ioc_data->atm_addr[2], ioc_data->atm_addr[3],
+ ioc_data->atm_addr[4], ioc_data->atm_addr[5],
+ ioc_data->atm_addr[6], ioc_data->atm_addr[7],
+ ioc_data->atm_addr[8], ioc_data->atm_addr[9],
+ ioc_data->atm_addr[10], ioc_data->atm_addr[11],
+ ioc_data->atm_addr[12], ioc_data->atm_addr[13],
+ ioc_data->atm_addr[14], ioc_data->atm_addr[15],
+ ioc_data->atm_addr[16], ioc_data->atm_addr[17],
+ ioc_data->atm_addr[18], ioc_data->atm_addr[19]);
+ entry = make_entry(priv, bus_mac);
+ if (entry == NULL)
goto out;
- memcpy(entry->atm_addr, ioc_data->atm_addr, ATM_ESA_LEN);
- memset(entry->mac_addr, 0, ETH_ALEN);
- entry->recv_vcc = vcc;
- entry->old_recv_push = old_push;
- entry->status = ESI_UNKNOWN;
- entry->timer.expires = jiffies + priv->vcc_timeout_period;
- entry->timer.function = lec_arp_expire_vcc;
- add_timer(&entry->timer);
- entry->next = priv->lec_no_forward;
- priv->lec_no_forward = entry;
+ memcpy(entry->atm_addr, ioc_data->atm_addr, ATM_ESA_LEN);
+ memset(entry->mac_addr, 0, ETH_ALEN);
+ entry->recv_vcc = vcc;
+ entry->old_recv_push = old_push;
+ entry->status = ESI_UNKNOWN;
+ entry->timer.expires = jiffies + priv->vcc_timeout_period;
+ entry->timer.function = lec_arp_expire_vcc;
+ hlist_add_head(&entry->next, &priv->lec_no_forward);
+ add_timer(&entry->timer);
dump_arp_table(priv);
goto out;
- }
- DPRINTK("LEC_ARP:Attaching data direct, default:%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x\n",
- ioc_data->atm_addr[0],ioc_data->atm_addr[1],
- ioc_data->atm_addr[2],ioc_data->atm_addr[3],
- ioc_data->atm_addr[4],ioc_data->atm_addr[5],
- ioc_data->atm_addr[6],ioc_data->atm_addr[7],
- ioc_data->atm_addr[8],ioc_data->atm_addr[9],
- ioc_data->atm_addr[10],ioc_data->atm_addr[11],
- ioc_data->atm_addr[12],ioc_data->atm_addr[13],
- ioc_data->atm_addr[14],ioc_data->atm_addr[15],
- ioc_data->atm_addr[16],ioc_data->atm_addr[17],
- ioc_data->atm_addr[18],ioc_data->atm_addr[19]);
- for (i = 0; i < LEC_ARP_TABLE_SIZE; i++) {
- for (entry = priv->lec_arp_tables[i]; entry; entry=entry->next) {
- if (memcmp(ioc_data->atm_addr, entry->atm_addr,
- ATM_ESA_LEN)==0) {
- DPRINTK("LEC_ARP: Attaching data direct\n");
- DPRINTK("Currently -> Vcc: %d, Rvcc:%d\n",
- entry->vcc?entry->vcc->vci:0,
- entry->recv_vcc?entry->recv_vcc->vci:0);
- found_entry=1;
- del_timer(&entry->timer);
- entry->vcc = vcc;
- entry->old_push = old_push;
- if (entry->status == ESI_VC_PENDING) {
- if(priv->maximum_unknown_frame_count
- ==0)
- entry->status =
- ESI_FORWARD_DIRECT;
- else {
- entry->timestamp = jiffies;
- entry->status =
- ESI_FLUSH_PENDING;
+ }
+ DPRINTK
+ ("LEC_ARP:Attaching data direct, default: "
+ "%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x\n",
+ ioc_data->atm_addr[0], ioc_data->atm_addr[1],
+ ioc_data->atm_addr[2], ioc_data->atm_addr[3],
+ ioc_data->atm_addr[4], ioc_data->atm_addr[5],
+ ioc_data->atm_addr[6], ioc_data->atm_addr[7],
+ ioc_data->atm_addr[8], ioc_data->atm_addr[9],
+ ioc_data->atm_addr[10], ioc_data->atm_addr[11],
+ ioc_data->atm_addr[12], ioc_data->atm_addr[13],
+ ioc_data->atm_addr[14], ioc_data->atm_addr[15],
+ ioc_data->atm_addr[16], ioc_data->atm_addr[17],
+ ioc_data->atm_addr[18], ioc_data->atm_addr[19]);
+ for (i = 0; i < LEC_ARP_TABLE_SIZE; i++) {
+ hlist_for_each_entry(entry, node, &priv->lec_arp_tables[i], next) {
+ if (memcmp
+ (ioc_data->atm_addr, entry->atm_addr,
+ ATM_ESA_LEN) == 0) {
+ DPRINTK("LEC_ARP: Attaching data direct\n");
+ DPRINTK("Currently -> Vcc: %d, Rvcc:%d\n",
+ entry->vcc ? entry->vcc->vci : 0,
+ entry->recv_vcc ? entry->recv_vcc->
+ vci : 0);
+ found_entry = 1;
+ del_timer(&entry->timer);
+ entry->vcc = vcc;
+ entry->old_push = old_push;
+ if (entry->status == ESI_VC_PENDING) {
+ if (priv->maximum_unknown_frame_count
+ == 0)
+ entry->status =
+ ESI_FORWARD_DIRECT;
+ else {
+ entry->timestamp = jiffies;
+ entry->status =
+ ESI_FLUSH_PENDING;
#if 0
- send_to_lecd(priv,l_flush_xmt,
- NULL,
- entry->atm_addr,
- NULL);
+ send_to_lecd(priv, l_flush_xmt,
+ NULL,
+ entry->atm_addr,
+ NULL);
#endif
- }
- } else {
- /* They were forming a connection
- to us, and we to them. Our
- ATM address is numerically lower
- than theirs, so we make connection
- we formed into default VCC (8.1.11).
- Connection they made gets torn
- down. This might confuse some
- clients. Can be changed if
- someone reports trouble... */
- ;
- }
- }
- }
- }
- if (found_entry) {
- DPRINTK("After vcc was added\n");
- dump_arp_table(priv);
+ }
+ } else {
+ /*
+ * They were forming a connection
+ * to us, and we to them. Our
+ * ATM address is numerically lower
+ * than theirs, so we make connection
+ * we formed into default VCC (8.1.11).
+ * Connection they made gets torn
+ * down. This might confuse some
+ * clients. Can be changed if
+ * someone reports trouble...
+ */
+ ;
+ }
+ }
+ }
+ }
+ if (found_entry) {
+ DPRINTK("After vcc was added\n");
+ dump_arp_table(priv);
goto out;
- }
- /* Not found, snatch address from first data packet that arrives from
- this vcc */
- entry = make_entry(priv, bus_mac);
- if (!entry)
+ }
+ /*
+ * Not found, snatch address from first data packet that arrives
+ * from this vcc
+ */
+ entry = make_entry(priv, bus_mac);
+ if (!entry)
goto out;
- entry->vcc = vcc;
- entry->old_push = old_push;
- memcpy(entry->atm_addr, ioc_data->atm_addr, ATM_ESA_LEN);
- memset(entry->mac_addr, 0, ETH_ALEN);
- entry->status = ESI_UNKNOWN;
- entry->next = priv->lec_arp_empty_ones;
- priv->lec_arp_empty_ones = entry;
- entry->timer.expires = jiffies + priv->vcc_timeout_period;
- entry->timer.function = lec_arp_expire_vcc;
- add_timer(&entry->timer);
- DPRINTK("After vcc was added\n");
+ entry->vcc = vcc;
+ entry->old_push = old_push;
+ memcpy(entry->atm_addr, ioc_data->atm_addr, ATM_ESA_LEN);
+ memset(entry->mac_addr, 0, ETH_ALEN);
+ entry->status = ESI_UNKNOWN;
+ hlist_add_head(&entry->next, &priv->lec_arp_empty_ones);
+ entry->timer.expires = jiffies + priv->vcc_timeout_period;
+ entry->timer.function = lec_arp_expire_vcc;
+ add_timer(&entry->timer);
+ DPRINTK("After vcc was added\n");
dump_arp_table(priv);
out:
spin_unlock_irqrestore(&priv->lec_arp_lock, flags);
}
-static void
-lec_flush_complete(struct lec_priv *priv, unsigned long tran_id)
+static void lec_flush_complete(struct lec_priv *priv, unsigned long tran_id)
{
unsigned long flags;
- struct lec_arp_table *entry;
- int i;
-
- DPRINTK("LEC:lec_flush_complete %lx\n",tran_id);
+ struct hlist_node *node;
+ struct lec_arp_table *entry;
+ int i;
+
+ DPRINTK("LEC:lec_flush_complete %lx\n", tran_id);
+restart:
spin_lock_irqsave(&priv->lec_arp_lock, flags);
- for (i = 0; i < LEC_ARP_TABLE_SIZE; i++) {
- for (entry = priv->lec_arp_tables[i]; entry; entry=entry->next) {
- if (entry->flush_tran_id == tran_id &&
- entry->status == ESI_FLUSH_PENDING) {
- struct sk_buff *skb;
-
- while ((skb = skb_dequeue(&entry->tx_wait)) != NULL)
- lec_send(entry->vcc, skb, entry->priv);
- entry->status = ESI_FORWARD_DIRECT;
- DPRINTK("LEC_ARP: Flushed\n");
- }
- }
- }
+ for (i = 0; i < LEC_ARP_TABLE_SIZE; i++) {
+ hlist_for_each_entry(entry, node, &priv->lec_arp_tables[i], next) {
+ if (entry->flush_tran_id == tran_id
+ && entry->status == ESI_FLUSH_PENDING) {
+ struct sk_buff *skb;
+ struct atm_vcc *vcc = entry->vcc;
+
+ lec_arp_hold(entry);
+ spin_unlock_irqrestore(&priv->lec_arp_lock, flags);
+ while ((skb = skb_dequeue(&entry->tx_wait)) != NULL)
+ lec_send(vcc, skb, entry->priv);
+ entry->last_used = jiffies;
+ entry->status = ESI_FORWARD_DIRECT;
+ lec_arp_put(entry);
+ DPRINTK("LEC_ARP: Flushed\n");
+ goto restart;
+ }
+ }
+ }
spin_unlock_irqrestore(&priv->lec_arp_lock, flags);
- dump_arp_table(priv);
+ dump_arp_table(priv);
}
static void
lec_set_flush_tran_id(struct lec_priv *priv,
- unsigned char *atm_addr, unsigned long tran_id)
+ unsigned char *atm_addr, unsigned long tran_id)
{
unsigned long flags;
- struct lec_arp_table *entry;
- int i;
+ struct hlist_node *node;
+ struct lec_arp_table *entry;
+ int i;
spin_lock_irqsave(&priv->lec_arp_lock, flags);
- for (i = 0; i < LEC_ARP_TABLE_SIZE; i++)
- for(entry = priv->lec_arp_tables[i]; entry; entry=entry->next)
- if (!memcmp(atm_addr, entry->atm_addr, ATM_ESA_LEN)) {
- entry->flush_tran_id = tran_id;
- DPRINTK("Set flush transaction id to %lx for %p\n",tran_id,entry);
- }
+ for (i = 0; i < LEC_ARP_TABLE_SIZE; i++)
+ hlist_for_each_entry(entry, node, &priv->lec_arp_tables[i], next) {
+ if (!memcmp(atm_addr, entry->atm_addr, ATM_ESA_LEN)) {
+ entry->flush_tran_id = tran_id;
+ DPRINTK("Set flush transaction id to %lx for %p\n",
+ tran_id, entry);
+ }
+ }
spin_unlock_irqrestore(&priv->lec_arp_lock, flags);
}
-static int
-lec_mcast_make(struct lec_priv *priv, struct atm_vcc *vcc)
+static int lec_mcast_make(struct lec_priv *priv, struct atm_vcc *vcc)
{
unsigned long flags;
- unsigned char mac_addr[] = {
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
- struct lec_arp_table *to_add;
+ unsigned char mac_addr[] = {
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
+ };
+ struct lec_arp_table *to_add;
struct lec_vcc_priv *vpriv;
int err = 0;
-
+
if (!(vpriv = kmalloc(sizeof(struct lec_vcc_priv), GFP_KERNEL)))
return -ENOMEM;
vpriv->xoff = 0;
vpriv->old_pop = vcc->pop;
vcc->user_back = vpriv;
- vcc->pop = lec_pop;
+ vcc->pop = lec_pop;
spin_lock_irqsave(&priv->lec_arp_lock, flags);
- to_add = make_entry(priv, mac_addr);
- if (!to_add) {
+ to_add = make_entry(priv, mac_addr);
+ if (!to_add) {
vcc->pop = vpriv->old_pop;
kfree(vpriv);
- err = -ENOMEM;
+ err = -ENOMEM;
goto out;
- }
- memcpy(to_add->atm_addr, vcc->remote.sas_addr.prv, ATM_ESA_LEN);
- to_add->status = ESI_FORWARD_DIRECT;
- to_add->flags |= LEC_PERMANENT_FLAG;
- to_add->vcc = vcc;
- to_add->old_push = vcc->push;
- vcc->push = lec_push;
- priv->mcast_vcc = vcc;
- lec_arp_add(priv, to_add);
+ }
+ memcpy(to_add->atm_addr, vcc->remote.sas_addr.prv, ATM_ESA_LEN);
+ to_add->status = ESI_FORWARD_DIRECT;
+ to_add->flags |= LEC_PERMANENT_FLAG;
+ to_add->vcc = vcc;
+ to_add->old_push = vcc->push;
+ vcc->push = lec_push;
+ priv->mcast_vcc = vcc;
+ lec_arp_add(priv, to_add);
out:
spin_unlock_irqrestore(&priv->lec_arp_lock, flags);
- return err;
+ return err;
}
-static void
-lec_vcc_close(struct lec_priv *priv, struct atm_vcc *vcc)
+static void lec_vcc_close(struct lec_priv *priv, struct atm_vcc *vcc)
{
unsigned long flags;
- struct lec_arp_table *entry, *next;
- int i;
+ struct hlist_node *node, *next;
+ struct lec_arp_table *entry;
+ int i;
+
+ DPRINTK("LEC_ARP: lec_vcc_close vpi:%d vci:%d\n", vcc->vpi, vcc->vci);
+ dump_arp_table(priv);
- DPRINTK("LEC_ARP: lec_vcc_close vpi:%d vci:%d\n",vcc->vpi,vcc->vci);
- dump_arp_table(priv);
spin_lock_irqsave(&priv->lec_arp_lock, flags);
- for(i=0;i<LEC_ARP_TABLE_SIZE;i++) {
- for(entry = priv->lec_arp_tables[i];entry; entry=next) {
- next = entry->next;
- if (vcc == entry->vcc) {
- lec_arp_remove(priv, entry);
- kfree(entry);
- if (priv->mcast_vcc == vcc) {
- priv->mcast_vcc = NULL;
- }
- }
- }
- }
-
- entry = priv->lec_arp_empty_ones;
- priv->lec_arp_empty_ones = NULL;
- while (entry != NULL) {
- next = entry->next;
- if (entry->vcc == vcc) { /* leave it out from the list */
- lec_arp_clear_vccs(entry);
- del_timer(&entry->timer);
- kfree(entry);
- }
- else { /* put it back to the list */
- entry->next = priv->lec_arp_empty_ones;
- priv->lec_arp_empty_ones = entry;
- }
- entry = next;
- }
-
- entry = priv->lec_no_forward;
- priv->lec_no_forward = NULL;
- while (entry != NULL) {
- next = entry->next;
- if (entry->recv_vcc == vcc) {
- lec_arp_clear_vccs(entry);
- del_timer(&entry->timer);
- kfree(entry);
- }
- else {
- entry->next = priv->lec_no_forward;
- priv->lec_no_forward = entry;
- }
- entry = next;
- }
-
- entry = priv->mcast_fwds;
- priv->mcast_fwds = NULL;
- while (entry != NULL) {
- next = entry->next;
- if (entry->recv_vcc == vcc) {
- lec_arp_clear_vccs(entry);
- /* No timer, LANEv2 7.1.20 and 2.3.5.3 */
- kfree(entry);
- }
- else {
- entry->next = priv->mcast_fwds;
- priv->mcast_fwds = entry;
- }
- entry = next;
- }
+
+ for (i = 0; i < LEC_ARP_TABLE_SIZE; i++) {
+ hlist_for_each_entry_safe(entry, node, next, &priv->lec_arp_tables[i], next) {
+ if (vcc == entry->vcc) {
+ lec_arp_remove(priv, entry);
+ lec_arp_put(entry);
+ if (priv->mcast_vcc == vcc) {
+ priv->mcast_vcc = NULL;
+ }
+ }
+ }
+ }
+
+ hlist_for_each_entry_safe(entry, node, next, &priv->lec_arp_empty_ones, next) {
+ if (entry->vcc == vcc) {
+ lec_arp_clear_vccs(entry);
+ del_timer(&entry->timer);
+ hlist_del(&entry->next);
+ lec_arp_put(entry);
+ }
+ }
+
+ hlist_for_each_entry_safe(entry, node, next, &priv->lec_no_forward, next) {
+ if (entry->recv_vcc == vcc) {
+ lec_arp_clear_vccs(entry);
+ del_timer(&entry->timer);
+ hlist_del(&entry->next);
+ lec_arp_put(entry);
+ }
+ }
+
+ hlist_for_each_entry_safe(entry, node, next, &priv->mcast_fwds, next) {
+ if (entry->recv_vcc == vcc) {
+ lec_arp_clear_vccs(entry);
+ /* No timer, LANEv2 7.1.20 and 2.3.5.3 */
+ hlist_del(&entry->next);
+ lec_arp_put(entry);
+ }
+ }
spin_unlock_irqrestore(&priv->lec_arp_lock, flags);
dump_arp_table(priv);
@@ -2517,57 +2483,42 @@ lec_vcc_close(struct lec_priv *priv, struct atm_vcc *vcc)
static void
lec_arp_check_empties(struct lec_priv *priv,
- struct atm_vcc *vcc, struct sk_buff *skb)
+ struct atm_vcc *vcc, struct sk_buff *skb)
{
- unsigned long flags;
- struct lec_arp_table *entry, *prev;
- struct lecdatahdr_8023 *hdr = (struct lecdatahdr_8023 *)skb->data;
- unsigned char *src;
+ unsigned long flags;
+ struct hlist_node *node, *next;
+ struct lec_arp_table *entry, *tmp;
+ struct lecdatahdr_8023 *hdr = (struct lecdatahdr_8023 *)skb->data;
+ unsigned char *src;
#ifdef CONFIG_TR
- struct lecdatahdr_8025 *tr_hdr = (struct lecdatahdr_8025 *)skb->data;
+ struct lecdatahdr_8025 *tr_hdr = (struct lecdatahdr_8025 *)skb->data;
- if (priv->is_trdev) src = tr_hdr->h_source;
- else
+ if (priv->is_trdev)
+ src = tr_hdr->h_source;
+ else
#endif
- src = hdr->h_source;
+ src = hdr->h_source;
spin_lock_irqsave(&priv->lec_arp_lock, flags);
- entry = priv->lec_arp_empty_ones;
- if (vcc == entry->vcc) {
- del_timer(&entry->timer);
- memcpy(entry->mac_addr, src, ETH_ALEN);
- entry->status = ESI_FORWARD_DIRECT;
- entry->last_used = jiffies;
- priv->lec_arp_empty_ones = entry->next;
- /* We might have got an entry */
- if ((prev = lec_arp_find(priv,src))) {
- lec_arp_remove(priv, prev);
- kfree(prev);
- }
- lec_arp_add(priv, entry);
- goto out;
- }
- prev = entry;
- entry = entry->next;
- while (entry && entry->vcc != vcc) {
- prev= entry;
- entry = entry->next;
- }
- if (!entry) {
- DPRINTK("LEC_ARP: Arp_check_empties: entry not found!\n");
- goto out;
- }
- del_timer(&entry->timer);
- memcpy(entry->mac_addr, src, ETH_ALEN);
- entry->status = ESI_FORWARD_DIRECT;
- entry->last_used = jiffies;
- prev->next = entry->next;
- if ((prev = lec_arp_find(priv, src))) {
- lec_arp_remove(priv, prev);
- kfree(prev);
- }
- lec_arp_add(priv, entry);
+ hlist_for_each_entry_safe(entry, node, next, &priv->lec_arp_empty_ones, next) {
+ if (vcc == entry->vcc) {
+ del_timer(&entry->timer);
+ memcpy(entry->mac_addr, src, ETH_ALEN);
+ entry->status = ESI_FORWARD_DIRECT;
+ entry->last_used = jiffies;
+ /* We might have got an entry */
+ if ((tmp = lec_arp_find(priv, src))) {
+ lec_arp_remove(priv, tmp);
+ lec_arp_put(tmp);
+ }
+ hlist_del(&entry->next);
+ lec_arp_add(priv, entry);
+ goto out;
+ }
+ }
+ DPRINTK("LEC_ARP: Arp_check_empties: entry not found!\n");
out:
spin_unlock_irqrestore(&priv->lec_arp_lock, flags);
}
+
MODULE_LICENSE("GPL");
diff --git a/net/atm/lec.h b/net/atm/lec.h
index c22a8bfa1f81..8ac6b7321635 100644
--- a/net/atm/lec.h
+++ b/net/atm/lec.h
@@ -1,14 +1,13 @@
/*
- *
* Lan Emulation client header file
*
- * Marko Kiiskila mkiiskila@yahoo.com
- *
+ * Marko Kiiskila <mkiiskila@yahoo.com>
*/
#ifndef _LEC_H_
#define _LEC_H_
+#include <linux/config.h>
#include <linux/atmdev.h>
#include <linux/netdevice.h>
#include <linux/atmlec.h>
@@ -16,18 +15,18 @@
#define LEC_HEADER_LEN 16
struct lecdatahdr_8023 {
- unsigned short le_header;
- unsigned char h_dest[ETH_ALEN];
- unsigned char h_source[ETH_ALEN];
- unsigned short h_type;
+ unsigned short le_header;
+ unsigned char h_dest[ETH_ALEN];
+ unsigned char h_source[ETH_ALEN];
+ unsigned short h_type;
};
struct lecdatahdr_8025 {
- unsigned short le_header;
- unsigned char ac_pad;
- unsigned char fc;
- unsigned char h_dest[ETH_ALEN];
- unsigned char h_source[ETH_ALEN];
+ unsigned short le_header;
+ unsigned char ac_pad;
+ unsigned char fc;
+ unsigned char h_dest[ETH_ALEN];
+ unsigned char h_source[ETH_ALEN];
};
#define LEC_MINIMUM_8023_SIZE 62
@@ -44,17 +43,18 @@ struct lecdatahdr_8025 {
*
*/
struct lane2_ops {
- int (*resolve)(struct net_device *dev, u8 *dst_mac, int force,
- u8 **tlvs, u32 *sizeoftlvs);
- int (*associate_req)(struct net_device *dev, u8 *lan_dst,
- u8 *tlvs, u32 sizeoftlvs);
- void (*associate_indicator)(struct net_device *dev, u8 *mac_addr,
- u8 *tlvs, u32 sizeoftlvs);
+ int (*resolve) (struct net_device *dev, u8 *dst_mac, int force,
+ u8 **tlvs, u32 *sizeoftlvs);
+ int (*associate_req) (struct net_device *dev, u8 *lan_dst,
+ u8 *tlvs, u32 sizeoftlvs);
+ void (*associate_indicator) (struct net_device *dev, u8 *mac_addr,
+ u8 *tlvs, u32 sizeoftlvs);
};
/*
* ATM LAN Emulation supports both LLC & Dix Ethernet EtherType
* frames.
+ *
* 1. Dix Ethernet EtherType frames encoded by placing EtherType
* field in h_type field. Data follows immediatelly after header.
* 2. LLC Data frames whose total length, including LLC field and data,
@@ -70,72 +70,88 @@ struct lane2_ops {
#define LEC_ARP_TABLE_SIZE 16
struct lec_priv {
- struct net_device_stats stats;
- unsigned short lecid; /* Lecid of this client */
- struct lec_arp_table *lec_arp_empty_ones;
- /* Used for storing VCC's that don't have a MAC address attached yet */
- struct lec_arp_table *lec_arp_tables[LEC_ARP_TABLE_SIZE];
- /* Actual LE ARP table */
- struct lec_arp_table *lec_no_forward;
- /* Used for storing VCC's (and forward packets from) which are to
- age out by not using them to forward packets.
- This is because to some LE clients there will be 2 VCCs. Only
- one of them gets used. */
- struct lec_arp_table *mcast_fwds;
- /* With LANEv2 it is possible that BUS (or a special multicast server)
- establishes multiple Multicast Forward VCCs to us. This list
- collects all those VCCs. LANEv1 client has only one item in this
- list. These entries are not aged out. */
- spinlock_t lec_arp_lock;
- struct atm_vcc *mcast_vcc; /* Default Multicast Send VCC */
- struct atm_vcc *lecd;
- struct timer_list lec_arp_timer;
- /* C10 */
- unsigned int maximum_unknown_frame_count;
-/* Within the period of time defined by this variable, the client will send
- no more than C10 frames to BUS for a given unicast destination. (C11) */
- unsigned long max_unknown_frame_time;
-/* If no traffic has been sent in this vcc for this period of time,
- vcc will be torn down (C12)*/
- unsigned long vcc_timeout_period;
-/* An LE Client MUST not retry an LE_ARP_REQUEST for a
- given frame's LAN Destination more than maximum retry count times,
- after the first LEC_ARP_REQUEST (C13)*/
- unsigned short max_retry_count;
-/* Max time the client will maintain an entry in its arp cache in
- absence of a verification of that relationship (C17)*/
- unsigned long aging_time;
-/* Max time the client will maintain an entry in cache when
- topology change flag is true (C18) */
- unsigned long forward_delay_time;
-/* Topology change flag (C19)*/
- int topology_change;
-/* Max time the client expects an LE_ARP_REQUEST/LE_ARP_RESPONSE
- cycle to take (C20)*/
- unsigned long arp_response_time;
-/* Time limit ot wait to receive an LE_FLUSH_RESPONSE after the
- LE_FLUSH_REQUEST has been sent before taking recover action. (C21)*/
- unsigned long flush_timeout;
-/* The time since sending a frame to the bus after which the
- LE Client may assume that the frame has been either discarded or
- delivered to the recipient (C22) */
- unsigned long path_switching_delay;
+ struct net_device_stats stats;
+ unsigned short lecid; /* Lecid of this client */
+ struct hlist_head lec_arp_empty_ones;
+ /* Used for storing VCC's that don't have a MAC address attached yet */
+ struct hlist_head lec_arp_tables[LEC_ARP_TABLE_SIZE];
+ /* Actual LE ARP table */
+ struct hlist_head lec_no_forward;
+ /*
+ * Used for storing VCC's (and forward packets from) which are to
+ * age out by not using them to forward packets.
+ * This is because to some LE clients there will be 2 VCCs. Only
+ * one of them gets used.
+ */
+ struct hlist_head mcast_fwds;
+ /*
+ * With LANEv2 it is possible that BUS (or a special multicast server)
+ * establishes multiple Multicast Forward VCCs to us. This list
+ * collects all those VCCs. LANEv1 client has only one item in this
+ * list. These entries are not aged out.
+ */
+ spinlock_t lec_arp_lock;
+ struct atm_vcc *mcast_vcc; /* Default Multicast Send VCC */
+ struct atm_vcc *lecd;
+ struct work_struct lec_arp_work; /* C10 */
+ unsigned int maximum_unknown_frame_count;
+ /*
+ * Within the period of time defined by this variable, the client will send
+ * no more than C10 frames to BUS for a given unicast destination. (C11)
+ */
+ unsigned long max_unknown_frame_time;
+ /*
+ * If no traffic has been sent in this vcc for this period of time,
+ * vcc will be torn down (C12)
+ */
+ unsigned long vcc_timeout_period;
+ /*
+ * An LE Client MUST not retry an LE_ARP_REQUEST for a
+ * given frame's LAN Destination more than maximum retry count times,
+ * after the first LEC_ARP_REQUEST (C13)
+ */
+ unsigned short max_retry_count;
+ /*
+ * Max time the client will maintain an entry in its arp cache in
+ * absence of a verification of that relationship (C17)
+ */
+ unsigned long aging_time;
+ /*
+ * Max time the client will maintain an entry in cache when
+ * topology change flag is true (C18)
+ */
+ unsigned long forward_delay_time; /* Topology change flag (C19) */
+ int topology_change;
+ /*
+ * Max time the client expects an LE_ARP_REQUEST/LE_ARP_RESPONSE
+ * cycle to take (C20)
+ */
+ unsigned long arp_response_time;
+ /*
+ * Time limit ot wait to receive an LE_FLUSH_RESPONSE after the
+ * LE_FLUSH_REQUEST has been sent before taking recover action. (C21)
+ */
+ unsigned long flush_timeout;
+ /* The time since sending a frame to the bus after which the
+ * LE Client may assume that the frame has been either discarded or
+ * delivered to the recipient (C22)
+ */
+ unsigned long path_switching_delay;
- u8 *tlvs; /* LANE2: TLVs are new */
- u32 sizeoftlvs; /* The size of the tlv array in bytes */
- int lane_version; /* LANE2 */
- int itfnum; /* e.g. 2 for lec2, 5 for lec5 */
- struct lane2_ops *lane2_ops; /* can be NULL for LANE v1 */
- int is_proxy; /* bridge between ATM and Ethernet */
- int is_trdev; /* Device type, 0 = Ethernet, 1 = TokenRing */
+ u8 *tlvs; /* LANE2: TLVs are new */
+ u32 sizeoftlvs; /* The size of the tlv array in bytes */
+ int lane_version; /* LANE2 */
+ int itfnum; /* e.g. 2 for lec2, 5 for lec5 */
+ struct lane2_ops *lane2_ops; /* can be NULL for LANE v1 */
+ int is_proxy; /* bridge between ATM and Ethernet */
+ int is_trdev; /* Device type, 0 = Ethernet, 1 = TokenRing */
};
struct lec_vcc_priv {
- void (*old_pop)(struct atm_vcc *vcc, struct sk_buff *skb);
+ void (*old_pop) (struct atm_vcc *vcc, struct sk_buff *skb);
int xoff;
};
#define LEC_VCC_PRIV(vcc) ((struct lec_vcc_priv *)((vcc)->user_back))
-#endif /* _LEC_H_ */
-
+#endif /* _LEC_H_ */
diff --git a/net/atm/lec_arpc.h b/net/atm/lec_arpc.h
index 397448094648..ec67435a40a6 100644
--- a/net/atm/lec_arpc.h
+++ b/net/atm/lec_arpc.h
@@ -1,92 +1,96 @@
/*
* Lec arp cache
- * Marko Kiiskila mkiiskila@yahoo.com
*
+ * Marko Kiiskila <mkiiskila@yahoo.com>
*/
-#ifndef _LEC_ARP_H
-#define _LEC_ARP_H
+#ifndef _LEC_ARP_H_
+#define _LEC_ARP_H_
#include <linux/atm.h>
#include <linux/atmdev.h>
#include <linux/if_ether.h>
#include <linux/atmlec.h>
struct lec_arp_table {
- struct lec_arp_table *next; /* Linked entry list */
- unsigned char atm_addr[ATM_ESA_LEN]; /* Atm address */
- unsigned char mac_addr[ETH_ALEN]; /* Mac address */
- int is_rdesc; /* Mac address is a route descriptor */
- struct atm_vcc *vcc; /* Vcc this entry is attached */
- struct atm_vcc *recv_vcc; /* Vcc we receive data from */
- void (*old_push)(struct atm_vcc *vcc,struct sk_buff *skb);
- /* Push that leads to daemon */
- void (*old_recv_push)(struct atm_vcc *vcc, struct sk_buff *skb);
- /* Push that leads to daemon */
- void (*old_close)(struct atm_vcc *vcc);
- /* We want to see when this
- * vcc gets closed */
- unsigned long last_used; /* For expiry */
- unsigned long timestamp; /* Used for various timestamping
- * things:
- * 1. FLUSH started
- * (status=ESI_FLUSH_PENDING)
- * 2. Counting to
- * max_unknown_frame_time
- * (status=ESI_ARP_PENDING||
- * status=ESI_VC_PENDING)
- */
- unsigned char no_tries; /* No of times arp retry has been
- tried */
- unsigned char status; /* Status of this entry */
- unsigned short flags; /* Flags for this entry */
- unsigned short packets_flooded; /* Data packets flooded */
- unsigned long flush_tran_id; /* Transaction id in flush protocol */
- struct timer_list timer; /* Arping timer */
- struct lec_priv *priv; /* Pointer back */
+ struct hlist_node next; /* Linked entry list */
+ unsigned char atm_addr[ATM_ESA_LEN]; /* Atm address */
+ unsigned char mac_addr[ETH_ALEN]; /* Mac address */
+ int is_rdesc; /* Mac address is a route descriptor */
+ struct atm_vcc *vcc; /* Vcc this entry is attached */
+ struct atm_vcc *recv_vcc; /* Vcc we receive data from */
- u8 *tlvs; /* LANE2: Each MAC address can have TLVs */
- u32 sizeoftlvs; /* associated with it. sizeoftlvs tells the */
- /* the length of the tlvs array */
- struct sk_buff_head tx_wait; /* wait queue for outgoing packets */
+ void (*old_push) (struct atm_vcc *vcc, struct sk_buff *skb);
+ /* Push that leads to daemon */
+
+ void (*old_recv_push) (struct atm_vcc *vcc, struct sk_buff *skb);
+ /* Push that leads to daemon */
+
+ unsigned long last_used; /* For expiry */
+ unsigned long timestamp; /* Used for various timestamping things:
+ * 1. FLUSH started
+ * (status=ESI_FLUSH_PENDING)
+ * 2. Counting to
+ * max_unknown_frame_time
+ * (status=ESI_ARP_PENDING||
+ * status=ESI_VC_PENDING)
+ */
+ unsigned char no_tries; /* No of times arp retry has been tried */
+ unsigned char status; /* Status of this entry */
+ unsigned short flags; /* Flags for this entry */
+ unsigned short packets_flooded; /* Data packets flooded */
+ unsigned long flush_tran_id; /* Transaction id in flush protocol */
+ struct timer_list timer; /* Arping timer */
+ struct lec_priv *priv; /* Pointer back */
+ u8 *tlvs;
+ u32 sizeoftlvs; /*
+ * LANE2: Each MAC address can have TLVs
+ * associated with it. sizeoftlvs tells the
+ * the length of the tlvs array
+ */
+ struct sk_buff_head tx_wait; /* wait queue for outgoing packets */
+ atomic_t usage; /* usage count */
};
-struct tlv { /* LANE2: Template tlv struct for accessing */
- /* the tlvs in the lec_arp_table->tlvs array*/
- u32 type;
- u8 length;
- u8 value[255];
+/*
+ * LANE2: Template tlv struct for accessing
+ * the tlvs in the lec_arp_table->tlvs array
+ */
+struct tlv {
+ u32 type;
+ u8 length;
+ u8 value[255];
};
/* Status fields */
-#define ESI_UNKNOWN 0 /*
- * Next packet sent to this mac address
- * causes ARP-request to be sent
- */
-#define ESI_ARP_PENDING 1 /*
- * There is no ATM address associated with this
- * 48-bit address. The LE-ARP protocol is in
- * progress.
- */
-#define ESI_VC_PENDING 2 /*
- * There is a valid ATM address associated with
- * this 48-bit address but there is no VC set
- * up to that ATM address. The signaling
- * protocol is in process.
- */
-#define ESI_FLUSH_PENDING 4 /*
- * The LEC has been notified of the FLUSH_START
- * status and it is assumed that the flush
- * protocol is in process.
- */
-#define ESI_FORWARD_DIRECT 5 /*
- * Either the Path Switching Delay (C22) has
- * elapsed or the LEC has notified the Mapping
- * that the flush protocol has completed. In
- * either case, it is safe to forward packets
- * to this address via the data direct VC.
- */
+#define ESI_UNKNOWN 0 /*
+ * Next packet sent to this mac address
+ * causes ARP-request to be sent
+ */
+#define ESI_ARP_PENDING 1 /*
+ * There is no ATM address associated with this
+ * 48-bit address. The LE-ARP protocol is in
+ * progress.
+ */
+#define ESI_VC_PENDING 2 /*
+ * There is a valid ATM address associated with
+ * this 48-bit address but there is no VC set
+ * up to that ATM address. The signaling
+ * protocol is in process.
+ */
+#define ESI_FLUSH_PENDING 4 /*
+ * The LEC has been notified of the FLUSH_START
+ * status and it is assumed that the flush
+ * protocol is in process.
+ */
+#define ESI_FORWARD_DIRECT 5 /*
+ * Either the Path Switching Delay (C22) has
+ * elapsed or the LEC has notified the Mapping
+ * that the flush protocol has completed. In
+ * either case, it is safe to forward packets
+ * to this address via the data direct VC.
+ */
/* Flag values */
#define LEC_REMOTE_FLAG 0x0001
#define LEC_PERMANENT_FLAG 0x0002
-#endif
+#endif /* _LEC_ARP_H_ */
diff --git a/net/atm/mpc.c b/net/atm/mpc.c
index b87c2a88bdce..0d2b994af511 100644
--- a/net/atm/mpc.c
+++ b/net/atm/mpc.c
@@ -560,7 +560,6 @@ static int atm_mpoa_vcc_attach(struct atm_vcc *vcc, void __user *arg)
struct atmmpc_ioc ioc_data;
in_cache_entry *in_entry;
uint32_t ipaddr;
- unsigned char *ip;
bytes_left = copy_from_user(&ioc_data, arg, sizeof(struct atmmpc_ioc));
if (bytes_left != 0) {
@@ -583,9 +582,8 @@ static int atm_mpoa_vcc_attach(struct atm_vcc *vcc, void __user *arg)
if (in_entry != NULL) mpc->in_ops->put(in_entry);
return -EINVAL;
}
- ip = (unsigned char*)&in_entry->ctrl_info.in_dst_ip;
printk("mpoa: (%s) mpc_vcc_attach: attaching ingress SVC, entry = %u.%u.%u.%u\n",
- mpc->dev->name, ip[0], ip[1], ip[2], ip[3]);
+ mpc->dev->name, NIPQUAD(in_entry->ctrl_info.in_dst_ip));
in_entry->shortcut = vcc;
mpc->in_ops->put(in_entry);
} else {
@@ -616,10 +614,8 @@ static void mpc_vcc_close(struct atm_vcc *vcc, struct net_device *dev)
dprintk("mpoa: (%s) mpc_vcc_close:\n", dev->name);
in_entry = mpc->in_ops->get_by_vcc(vcc, mpc);
if (in_entry) {
- unsigned char *ip __attribute__ ((unused)) =
- (unsigned char *)&in_entry->ctrl_info.in_dst_ip;
dprintk("mpoa: (%s) mpc_vcc_close: ingress SVC closed ip = %u.%u.%u.%u\n",
- mpc->dev->name, ip[0], ip[1], ip[2], ip[3]);
+ mpc->dev->name, NIPQUAD(in_entry->ctrl_info.in_dst_ip));
in_entry->shortcut = NULL;
mpc->in_ops->put(in_entry);
}
@@ -1154,18 +1150,17 @@ static void ingress_purge_rcvd(struct k_message *msg, struct mpoa_client *mpc)
{
uint32_t dst_ip = msg->content.in_info.in_dst_ip;
uint32_t mask = msg->ip_mask;
- unsigned char *ip = (unsigned char *)&dst_ip;
in_cache_entry *entry = mpc->in_ops->get_with_mask(dst_ip, mpc, mask);
if(entry == NULL){
printk("mpoa: (%s) ingress_purge_rcvd: purge for a non-existing entry, ", mpc->dev->name);
- printk("ip = %u.%u.%u.%u\n", ip[0], ip[1], ip[2], ip[3]);
+ printk("ip = %u.%u.%u.%u\n", NIPQUAD(dst_ip));
return;
}
do {
dprintk("mpoa: (%s) ingress_purge_rcvd: removing an ingress entry, ip = %u.%u.%u.%u\n" ,
- mpc->dev->name, ip[0], ip[1], ip[2], ip[3]);
+ mpc->dev->name, NIPQUAD(dst_ip));
write_lock_bh(&mpc->ingress_lock);
mpc->in_ops->remove_entry(entry, mpc);
write_unlock_bh(&mpc->ingress_lock);
diff --git a/net/atm/mpoa_caches.c b/net/atm/mpoa_caches.c
index 781ed1b9329d..fbf13cdcf46e 100644
--- a/net/atm/mpoa_caches.c
+++ b/net/atm/mpoa_caches.c
@@ -87,7 +87,6 @@ static in_cache_entry *in_cache_get_by_vcc(struct atm_vcc *vcc,
static in_cache_entry *in_cache_add_entry(uint32_t dst_ip,
struct mpoa_client *client)
{
- unsigned char *ip __attribute__ ((unused)) = (unsigned char *)&dst_ip;
in_cache_entry* entry = kmalloc(sizeof(in_cache_entry), GFP_KERNEL);
if (entry == NULL) {
@@ -95,7 +94,7 @@ static in_cache_entry *in_cache_add_entry(uint32_t dst_ip,
return NULL;
}
- dprintk("mpoa: mpoa_caches.c: adding an ingress entry, ip = %u.%u.%u.%u\n", ip[0], ip[1], ip[2], ip[3]);
+ dprintk("mpoa: mpoa_caches.c: adding an ingress entry, ip = %u.%u.%u.%u\n", NIPQUAD(dst_ip));
memset(entry,0,sizeof(in_cache_entry));
atomic_set(&entry->use, 1);
@@ -152,10 +151,7 @@ static int cache_hit(in_cache_entry *entry, struct mpoa_client *mpc)
if( entry->count > mpc->parameters.mpc_p1 &&
entry->entry_state == INGRESS_INVALID){
- unsigned char *ip __attribute__ ((unused)) =
- (unsigned char *)&entry->ctrl_info.in_dst_ip;
-
- dprintk("mpoa: (%s) mpoa_caches.c: threshold exceeded for ip %u.%u.%u.%u, sending MPOA res req\n", mpc->dev->name, ip[0], ip[1], ip[2], ip[3]);
+ dprintk("mpoa: (%s) mpoa_caches.c: threshold exceeded for ip %u.%u.%u.%u, sending MPOA res req\n", mpc->dev->name, NIPQUAD(entry->ctrl_info.in_dst_ip));
entry->entry_state = INGRESS_RESOLVING;
msg.type = SND_MPOA_RES_RQST;
memcpy(msg.MPS_ctrl, mpc->mps_ctrl_addr, ATM_ESA_LEN );
@@ -187,11 +183,9 @@ static void in_cache_remove_entry(in_cache_entry *entry,
{
struct atm_vcc *vcc;
struct k_message msg;
- unsigned char *ip;
vcc = entry->shortcut;
- ip = (unsigned char *)&entry->ctrl_info.in_dst_ip;
- dprintk("mpoa: mpoa_caches.c: removing an ingress entry, ip = %u.%u.%u.%u\n",ip[0], ip[1], ip[2], ip[3]);
+ dprintk("mpoa: mpoa_caches.c: removing an ingress entry, ip = %u.%u.%u.%u\n",NIPQUAD(entry->ctrl_info.in_dst_ip));
if (entry->prev != NULL)
entry->prev->next = entry->next;
diff --git a/net/bluetooth/af_bluetooth.c b/net/bluetooth/af_bluetooth.c
index 788ea7a2b744..305a099b7477 100644
--- a/net/bluetooth/af_bluetooth.c
+++ b/net/bluetooth/af_bluetooth.c
@@ -276,7 +276,7 @@ int bt_sock_wait_state(struct sock *sk, int state, unsigned long timeo)
set_current_state(TASK_INTERRUPTIBLE);
if (!timeo) {
- err = -EAGAIN;
+ err = -EINPROGRESS;
break;
}
diff --git a/net/bluetooth/bnep/core.c b/net/bluetooth/bnep/core.c
index e620061fb50f..2312d050eeed 100644
--- a/net/bluetooth/bnep/core.c
+++ b/net/bluetooth/bnep/core.c
@@ -51,6 +51,7 @@
#include <asm/unaligned.h>
#include <net/bluetooth/bluetooth.h>
+#include <net/bluetooth/hci_core.h>
#include <net/bluetooth/l2cap.h>
#include "bnep.h"
@@ -515,6 +516,26 @@ static int bnep_session(void *arg)
return 0;
}
+static struct device *bnep_get_device(struct bnep_session *session)
+{
+ bdaddr_t *src = &bt_sk(session->sock->sk)->src;
+ bdaddr_t *dst = &bt_sk(session->sock->sk)->dst;
+ struct hci_dev *hdev;
+ struct hci_conn *conn;
+
+ hdev = hci_get_route(dst, src);
+ if (!hdev)
+ return NULL;
+
+ conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, dst);
+ if (!conn)
+ return NULL;
+
+ hci_dev_put(hdev);
+
+ return &conn->dev;
+}
+
int bnep_add_connection(struct bnep_connadd_req *req, struct socket *sock)
{
struct net_device *dev;
@@ -534,7 +555,6 @@ int bnep_add_connection(struct bnep_connadd_req *req, struct socket *sock)
if (!dev)
return -ENOMEM;
-
down_write(&bnep_session_sem);
ss = __bnep_get_session(dst);
@@ -551,7 +571,7 @@ int bnep_add_connection(struct bnep_connadd_req *req, struct socket *sock)
memcpy(s->eh.h_source, &dst, ETH_ALEN);
memcpy(dev->dev_addr, s->eh.h_dest, ETH_ALEN);
- s->dev = dev;
+ s->dev = dev;
s->sock = sock;
s->role = req->role;
s->state = BT_CONNECTED;
@@ -568,6 +588,8 @@ int bnep_add_connection(struct bnep_connadd_req *req, struct socket *sock)
bnep_set_default_proto_filter(s);
#endif
+ SET_NETDEV_DEV(dev, bnep_get_device(s));
+
err = register_netdev(dev);
if (err) {
goto failed;
diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
index 420ed4d7e57e..90e3a285a17e 100644
--- a/net/bluetooth/hci_conn.c
+++ b/net/bluetooth/hci_conn.c
@@ -84,6 +84,20 @@ static void hci_acl_connect(struct hci_conn *conn)
hci_send_cmd(hdev, OGF_LINK_CTL, OCF_CREATE_CONN, sizeof(cp), &cp);
}
+static void hci_acl_connect_cancel(struct hci_conn *conn)
+{
+ struct hci_cp_create_conn_cancel cp;
+
+ BT_DBG("%p", conn);
+
+ if (conn->hdev->hci_ver < 2)
+ return;
+
+ bacpy(&cp.bdaddr, &conn->dst);
+ hci_send_cmd(conn->hdev, OGF_LINK_CTL,
+ OCF_CREATE_CONN_CANCEL, sizeof(cp), &cp);
+}
+
void hci_acl_disconn(struct hci_conn *conn, __u8 reason)
{
struct hci_cp_disconnect cp;
@@ -94,7 +108,8 @@ void hci_acl_disconn(struct hci_conn *conn, __u8 reason)
cp.handle = __cpu_to_le16(conn->handle);
cp.reason = reason;
- hci_send_cmd(conn->hdev, OGF_LINK_CTL, OCF_DISCONNECT, sizeof(cp), &cp);
+ hci_send_cmd(conn->hdev, OGF_LINK_CTL,
+ OCF_DISCONNECT, sizeof(cp), &cp);
}
void hci_add_sco(struct hci_conn *conn, __u16 handle)
@@ -124,12 +139,20 @@ static void hci_conn_timeout(unsigned long arg)
return;
hci_dev_lock(hdev);
- if (conn->state == BT_CONNECTED)
+
+ switch (conn->state) {
+ case BT_CONNECT:
+ hci_acl_connect_cancel(conn);
+ break;
+ case BT_CONNECTED:
hci_acl_disconn(conn, 0x13);
- else
+ break;
+ default:
conn->state = BT_CLOSED;
+ break;
+ }
+
hci_dev_unlock(hdev);
- return;
}
static void hci_conn_idle(unsigned long arg)
@@ -179,6 +202,8 @@ struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst)
if (hdev->notify)
hdev->notify(hdev, HCI_NOTIFY_CONN_ADD);
+ hci_conn_add_sysfs(conn);
+
tasklet_enable(&hdev->tx_task);
return conn;
@@ -211,6 +236,8 @@ int hci_conn_del(struct hci_conn *conn)
tasklet_disable(&hdev->tx_task);
+ hci_conn_del_sysfs(conn);
+
hci_conn_hash_del(hdev, conn);
if (hdev->notify)
hdev->notify(hdev, HCI_NOTIFY_CONN_DEL);
@@ -221,7 +248,9 @@ int hci_conn_del(struct hci_conn *conn)
hci_dev_put(hdev);
- kfree(conn);
+ /* will free via device release */
+ put_device(&conn->dev);
+
return 0;
}
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index 5ed474277903..338ae977a31b 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -206,6 +206,9 @@ static void hci_init_req(struct hci_dev *hdev, unsigned long opt)
/* Read Local Supported Features */
hci_send_cmd(hdev, OGF_INFO_PARAM, OCF_READ_LOCAL_FEATURES, 0, NULL);
+ /* Read Local Version */
+ hci_send_cmd(hdev, OGF_INFO_PARAM, OCF_READ_LOCAL_VERSION, 0, NULL);
+
/* Read Buffer Size (ACL mtu, max pkt, etc.) */
hci_send_cmd(hdev, OGF_INFO_PARAM, OCF_READ_BUFFER_SIZE, 0, NULL);
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index 3896dabab11d..d43d0c890975 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -62,6 +62,7 @@ static void hci_cc_link_ctl(struct hci_dev *hdev, __u16 ocf, struct sk_buff *skb
switch (ocf) {
case OCF_INQUIRY_CANCEL:
+ case OCF_EXIT_PERIODIC_INQ:
status = *((__u8 *) skb->data);
if (status) {
@@ -297,6 +298,7 @@ static void hci_cc_host_ctl(struct hci_dev *hdev, __u16 ocf, struct sk_buff *skb
/* Command Complete OGF INFO_PARAM */
static void hci_cc_info_param(struct hci_dev *hdev, __u16 ocf, struct sk_buff *skb)
{
+ struct hci_rp_read_loc_version *lv;
struct hci_rp_read_local_features *lf;
struct hci_rp_read_buffer_size *bs;
struct hci_rp_read_bd_addr *ba;
@@ -304,6 +306,23 @@ static void hci_cc_info_param(struct hci_dev *hdev, __u16 ocf, struct sk_buff *s
BT_DBG("%s ocf 0x%x", hdev->name, ocf);
switch (ocf) {
+ case OCF_READ_LOCAL_VERSION:
+ lv = (struct hci_rp_read_loc_version *) skb->data;
+
+ if (lv->status) {
+ BT_DBG("%s READ_LOCAL_VERSION failed %d", hdev->name, lf->status);
+ break;
+ }
+
+ hdev->hci_ver = lv->hci_ver;
+ hdev->hci_rev = btohs(lv->hci_rev);
+ hdev->manufacturer = btohs(lv->manufacturer);
+
+ BT_DBG("%s: manufacturer %d hci_ver %d hci_rev %d", hdev->name,
+ hdev->manufacturer, hdev->hci_ver, hdev->hci_rev);
+
+ break;
+
case OCF_READ_LOCAL_FEATURES:
lf = (struct hci_rp_read_local_features *) skb->data;
@@ -328,7 +347,8 @@ static void hci_cc_info_param(struct hci_dev *hdev, __u16 ocf, struct sk_buff *s
if (hdev->features[1] & LMP_HV3)
hdev->pkt_type |= (HCI_HV3);
- BT_DBG("%s: features 0x%x 0x%x 0x%x", hdev->name, lf->features[0], lf->features[1], lf->features[2]);
+ BT_DBG("%s: features 0x%x 0x%x 0x%x", hdev->name,
+ lf->features[0], lf->features[1], lf->features[2]);
break;
@@ -757,6 +777,10 @@ static inline void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *s
hci_send_cmd(hdev, OGF_LINK_CTL,
OCF_CHANGE_CONN_PTYPE, sizeof(cp), &cp);
+ } else {
+ /* Update disconnect timer */
+ hci_conn_hold(conn);
+ hci_conn_put(conn);
}
} else
conn->state = BT_CLOSED;
diff --git a/net/bluetooth/hci_sysfs.c b/net/bluetooth/hci_sysfs.c
index 3987d167f04e..989b22d9042e 100644
--- a/net/bluetooth/hci_sysfs.c
+++ b/net/bluetooth/hci_sysfs.c
@@ -13,16 +13,32 @@
#define BT_DBG(D...)
#endif
-static ssize_t show_name(struct device *dev, struct device_attribute *attr, char *buf)
+static inline char *typetostr(int type)
{
- struct hci_dev *hdev = dev_get_drvdata(dev);
- return sprintf(buf, "%s\n", hdev->name);
+ switch (type) {
+ case HCI_VIRTUAL:
+ return "VIRTUAL";
+ case HCI_USB:
+ return "USB";
+ case HCI_PCCARD:
+ return "PCCARD";
+ case HCI_UART:
+ return "UART";
+ case HCI_RS232:
+ return "RS232";
+ case HCI_PCI:
+ return "PCI";
+ case HCI_SDIO:
+ return "SDIO";
+ default:
+ return "UNKNOWN";
+ }
}
static ssize_t show_type(struct device *dev, struct device_attribute *attr, char *buf)
{
struct hci_dev *hdev = dev_get_drvdata(dev);
- return sprintf(buf, "%d\n", hdev->type);
+ return sprintf(buf, "%s\n", typetostr(hdev->type));
}
static ssize_t show_address(struct device *dev, struct device_attribute *attr, char *buf)
@@ -33,10 +49,22 @@ static ssize_t show_address(struct device *dev, struct device_attribute *attr, c
return sprintf(buf, "%s\n", batostr(&bdaddr));
}
-static ssize_t show_flags(struct device *dev, struct device_attribute *attr, char *buf)
+static ssize_t show_manufacturer(struct device *dev, struct device_attribute *attr, char *buf)
+{
+ struct hci_dev *hdev = dev_get_drvdata(dev);
+ return sprintf(buf, "%d\n", hdev->manufacturer);
+}
+
+static ssize_t show_hci_version(struct device *dev, struct device_attribute *attr, char *buf)
{
struct hci_dev *hdev = dev_get_drvdata(dev);
- return sprintf(buf, "0x%lx\n", hdev->flags);
+ return sprintf(buf, "%d\n", hdev->hci_ver);
+}
+
+static ssize_t show_hci_revision(struct device *dev, struct device_attribute *attr, char *buf)
+{
+ struct hci_dev *hdev = dev_get_drvdata(dev);
+ return sprintf(buf, "%d\n", hdev->hci_rev);
}
static ssize_t show_inquiry_cache(struct device *dev, struct device_attribute *attr, char *buf)
@@ -141,10 +169,11 @@ static ssize_t store_sniff_min_interval(struct device *dev, struct device_attrib
return count;
}
-static DEVICE_ATTR(name, S_IRUGO, show_name, NULL);
static DEVICE_ATTR(type, S_IRUGO, show_type, NULL);
static DEVICE_ATTR(address, S_IRUGO, show_address, NULL);
-static DEVICE_ATTR(flags, S_IRUGO, show_flags, NULL);
+static DEVICE_ATTR(manufacturer, S_IRUGO, show_manufacturer, NULL);
+static DEVICE_ATTR(hci_version, S_IRUGO, show_hci_version, NULL);
+static DEVICE_ATTR(hci_revision, S_IRUGO, show_hci_revision, NULL);
static DEVICE_ATTR(inquiry_cache, S_IRUGO, show_inquiry_cache, NULL);
static DEVICE_ATTR(idle_timeout, S_IRUGO | S_IWUSR,
@@ -155,10 +184,11 @@ static DEVICE_ATTR(sniff_min_interval, S_IRUGO | S_IWUSR,
show_sniff_min_interval, store_sniff_min_interval);
static struct device_attribute *bt_attrs[] = {
- &dev_attr_name,
&dev_attr_type,
&dev_attr_address,
- &dev_attr_flags,
+ &dev_attr_manufacturer,
+ &dev_attr_hci_version,
+ &dev_attr_hci_revision,
&dev_attr_inquiry_cache,
&dev_attr_idle_timeout,
&dev_attr_sniff_max_interval,
@@ -166,6 +196,32 @@ static struct device_attribute *bt_attrs[] = {
NULL
};
+static ssize_t show_conn_type(struct device *dev, struct device_attribute *attr, char *buf)
+{
+ struct hci_conn *conn = dev_get_drvdata(dev);
+ return sprintf(buf, "%s\n", conn->type == ACL_LINK ? "ACL" : "SCO");
+}
+
+static ssize_t show_conn_address(struct device *dev, struct device_attribute *attr, char *buf)
+{
+ struct hci_conn *conn = dev_get_drvdata(dev);
+ bdaddr_t bdaddr;
+ baswap(&bdaddr, &conn->dst);
+ return sprintf(buf, "%s\n", batostr(&bdaddr));
+}
+
+#define CONN_ATTR(_name,_mode,_show,_store) \
+struct device_attribute conn_attr_##_name = __ATTR(_name,_mode,_show,_store)
+
+static CONN_ATTR(type, S_IRUGO, show_conn_type, NULL);
+static CONN_ATTR(address, S_IRUGO, show_conn_address, NULL);
+
+static struct device_attribute *conn_attrs[] = {
+ &conn_attr_type,
+ &conn_attr_address,
+ NULL
+};
+
struct class *bt_class = NULL;
EXPORT_SYMBOL_GPL(bt_class);
@@ -177,8 +233,57 @@ static struct platform_device *bt_platform;
static void bt_release(struct device *dev)
{
- struct hci_dev *hdev = dev_get_drvdata(dev);
- kfree(hdev);
+ void *data = dev_get_drvdata(dev);
+ kfree(data);
+}
+
+static void add_conn(void *data)
+{
+ struct hci_conn *conn = data;
+ int i;
+
+ device_register(&conn->dev);
+
+ for (i = 0; conn_attrs[i]; i++)
+ device_create_file(&conn->dev, conn_attrs[i]);
+}
+
+void hci_conn_add_sysfs(struct hci_conn *conn)
+{
+ struct hci_dev *hdev = conn->hdev;
+ bdaddr_t *ba = &conn->dst;
+
+ BT_DBG("conn %p", conn);
+
+ conn->dev.parent = &hdev->dev;
+ conn->dev.release = bt_release;
+
+ snprintf(conn->dev.bus_id, BUS_ID_SIZE,
+ "%s%2.2X%2.2X%2.2X%2.2X%2.2X%2.2X",
+ conn->type == ACL_LINK ? "acl" : "sco",
+ ba->b[5], ba->b[4], ba->b[3],
+ ba->b[2], ba->b[1], ba->b[0]);
+
+ dev_set_drvdata(&conn->dev, conn);
+
+ INIT_WORK(&conn->work, add_conn, (void *) conn);
+
+ schedule_work(&conn->work);
+}
+
+static void del_conn(void *data)
+{
+ struct hci_conn *conn = data;
+ device_del(&conn->dev);
+}
+
+void hci_conn_del_sysfs(struct hci_conn *conn)
+{
+ BT_DBG("conn %p", conn);
+
+ INIT_WORK(&conn->work, del_conn, (void *) conn);
+
+ schedule_work(&conn->work);
}
int hci_register_sysfs(struct hci_dev *hdev)
@@ -214,11 +319,9 @@ int hci_register_sysfs(struct hci_dev *hdev)
void hci_unregister_sysfs(struct hci_dev *hdev)
{
- struct device *dev = &hdev->dev;
-
BT_DBG("%p name %s type %d", hdev, hdev->name, hdev->type);
- device_del(dev);
+ device_del(&hdev->dev);
}
int __init bt_sysfs_init(void)
@@ -245,7 +348,7 @@ int __init bt_sysfs_init(void)
return 0;
}
-void __exit bt_sysfs_cleanup(void)
+void bt_sysfs_cleanup(void)
{
class_destroy(bt_class);
diff --git a/net/bluetooth/hidp/core.c b/net/bluetooth/hidp/core.c
index c6e3a2c27c6e..03b5dadb4951 100644
--- a/net/bluetooth/hidp/core.c
+++ b/net/bluetooth/hidp/core.c
@@ -40,6 +40,7 @@
#include <linux/input.h>
#include <net/bluetooth/bluetooth.h>
+#include <net/bluetooth/hci_core.h>
#include <net/bluetooth/l2cap.h>
#include "hidp.h"
@@ -528,6 +529,26 @@ static int hidp_session(void *arg)
return 0;
}
+static struct device *hidp_get_device(struct hidp_session *session)
+{
+ bdaddr_t *src = &bt_sk(session->ctrl_sock->sk)->src;
+ bdaddr_t *dst = &bt_sk(session->ctrl_sock->sk)->dst;
+ struct hci_dev *hdev;
+ struct hci_conn *conn;
+
+ hdev = hci_get_route(dst, src);
+ if (!hdev)
+ return NULL;
+
+ conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, dst);
+ if (!conn)
+ return NULL;
+
+ hci_dev_put(hdev);
+
+ return &conn->dev;
+}
+
static inline void hidp_setup_input(struct hidp_session *session, struct hidp_connadd_req *req)
{
struct input_dev *input = session->input;
@@ -566,6 +587,8 @@ static inline void hidp_setup_input(struct hidp_session *session, struct hidp_co
input->relbit[0] |= BIT(REL_WHEEL);
}
+ input->cdev.dev = hidp_get_device(session);
+
input->event = hidp_input_event;
input_register_device(input);
diff --git a/net/bluetooth/rfcomm/core.c b/net/bluetooth/rfcomm/core.c
index 332dd8f436ea..468df3b953f6 100644
--- a/net/bluetooth/rfcomm/core.c
+++ b/net/bluetooth/rfcomm/core.c
@@ -644,7 +644,7 @@ static struct rfcomm_session *rfcomm_session_create(bdaddr_t *src, bdaddr_t *dst
addr.l2_family = AF_BLUETOOTH;
addr.l2_psm = htobs(RFCOMM_PSM);
*err = sock->ops->connect(sock, (struct sockaddr *) &addr, sizeof(addr), O_NONBLOCK);
- if (*err == 0 || *err == -EAGAIN)
+ if (*err == 0 || *err == -EINPROGRESS)
return s;
rfcomm_session_del(s);
diff --git a/net/bluetooth/rfcomm/tty.c b/net/bluetooth/rfcomm/tty.c
index bd8d671a0ba6..1958ad1b8541 100644
--- a/net/bluetooth/rfcomm/tty.c
+++ b/net/bluetooth/rfcomm/tty.c
@@ -38,6 +38,7 @@
#include <linux/skbuff.h>
#include <net/bluetooth/bluetooth.h>
+#include <net/bluetooth/hci_core.h>
#include <net/bluetooth/rfcomm.h>
#ifndef CONFIG_BT_RFCOMM_DEBUG
@@ -161,6 +162,24 @@ static inline struct rfcomm_dev *rfcomm_dev_get(int id)
return dev;
}
+static struct device *rfcomm_get_device(struct rfcomm_dev *dev)
+{
+ struct hci_dev *hdev;
+ struct hci_conn *conn;
+
+ hdev = hci_get_route(&dev->dst, &dev->src);
+ if (!hdev)
+ return NULL;
+
+ conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &dev->dst);
+ if (!conn)
+ return NULL;
+
+ hci_dev_put(hdev);
+
+ return &conn->dev;
+}
+
static int rfcomm_dev_add(struct rfcomm_dev_req *req, struct rfcomm_dlc *dlc)
{
struct rfcomm_dev *dev;
@@ -244,7 +263,7 @@ out:
return err;
}
- tty_register_device(rfcomm_tty_driver, dev->id, NULL);
+ tty_register_device(rfcomm_tty_driver, dev->id, rfcomm_get_device(dev));
return dev->id;
}
@@ -992,7 +1011,7 @@ static int rfcomm_tty_tiocmset(struct tty_struct *tty, struct file *filp, unsign
/* ---- TTY structure ---- */
-static struct tty_operations rfcomm_ops = {
+static const struct tty_operations rfcomm_ops = {
.open = rfcomm_tty_open,
.close = rfcomm_tty_close,
.write = rfcomm_tty_write,
diff --git a/net/bridge/netfilter/ebt_arpreply.c b/net/bridge/netfilter/ebt_arpreply.c
index d19fc4b328dc..0aa7b9910a86 100644
--- a/net/bridge/netfilter/ebt_arpreply.c
+++ b/net/bridge/netfilter/ebt_arpreply.c
@@ -20,7 +20,7 @@ static int ebt_target_reply(struct sk_buff **pskb, unsigned int hooknr,
const void *data, unsigned int datalen)
{
struct ebt_arpreply_info *info = (struct ebt_arpreply_info *)data;
- u32 _sip, *siptr, _dip, *diptr;
+ __be32 _sip, *siptr, _dip, *diptr;
struct arphdr _ah, *ap;
unsigned char _sha[ETH_ALEN], *shp;
struct sk_buff *skb = *pskb;
diff --git a/net/core/dev.c b/net/core/dev.c
index 14de297d024d..4d891beab138 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -1480,14 +1480,16 @@ gso:
if (q->enqueue) {
/* Grab device queue */
spin_lock(&dev->queue_lock);
+ q = dev->qdisc;
+ if (q->enqueue) {
+ rc = q->enqueue(skb, q);
+ qdisc_run(dev);
+ spin_unlock(&dev->queue_lock);
- rc = q->enqueue(skb, q);
-
- qdisc_run(dev);
-
+ rc = rc == NET_XMIT_BYPASS ? NET_XMIT_SUCCESS : rc;
+ goto out;
+ }
spin_unlock(&dev->queue_lock);
- rc = rc == NET_XMIT_BYPASS ? NET_XMIT_SUCCESS : rc;
- goto out;
}
/* The device has no queue. Common case for software devices:
diff --git a/net/core/ethtool.c b/net/core/ethtool.c
index e0ca04f38cef..87dc556fd9d6 100644
--- a/net/core/ethtool.c
+++ b/net/core/ethtool.c
@@ -806,13 +806,6 @@ int dev_ethtool(struct ifreq *ifr)
int rc;
unsigned long old_features;
- /*
- * XXX: This can be pushed down into the ethtool_* handlers that
- * need it. Keep existing behaviour for the moment.
- */
- if (!capable(CAP_NET_ADMIN))
- return -EPERM;
-
if (!dev || !netif_device_present(dev))
return -ENODEV;
@@ -822,6 +815,27 @@ int dev_ethtool(struct ifreq *ifr)
if (copy_from_user(&ethcmd, useraddr, sizeof (ethcmd)))
return -EFAULT;
+ /* Allow some commands to be done by anyone */
+ switch(ethcmd) {
+ case ETHTOOL_GDRVINFO:
+ case ETHTOOL_GMSGLVL:
+ case ETHTOOL_GCOALESCE:
+ case ETHTOOL_GRINGPARAM:
+ case ETHTOOL_GPAUSEPARAM:
+ case ETHTOOL_GRXCSUM:
+ case ETHTOOL_GTXCSUM:
+ case ETHTOOL_GSG:
+ case ETHTOOL_GSTRINGS:
+ case ETHTOOL_GTSO:
+ case ETHTOOL_GPERMADDR:
+ case ETHTOOL_GUFO:
+ case ETHTOOL_GGSO:
+ break;
+ default:
+ if (!capable(CAP_NET_ADMIN))
+ return -EPERM;
+ }
+
if(dev->ethtool_ops->begin)
if ((rc = dev->ethtool_ops->begin(dev)) < 0)
return rc;
@@ -947,6 +961,10 @@ int dev_ethtool(struct ifreq *ifr)
return rc;
ioctl:
+ /* Keep existing behaviour for the moment. */
+ if (!capable(CAP_NET_ADMIN))
+ return -EPERM;
+
if (dev->do_ioctl)
return dev->do_ioctl(dev, ifr, SIOCETHTOOL);
return -EOPNOTSUPP;
diff --git a/net/core/neighbour.c b/net/core/neighbour.c
index b6c69e1463e8..8ce8c471d868 100644
--- a/net/core/neighbour.c
+++ b/net/core/neighbour.c
@@ -1079,7 +1079,7 @@ struct neighbour *neigh_event_ns(struct neigh_table *tbl,
}
static void neigh_hh_init(struct neighbour *n, struct dst_entry *dst,
- u16 protocol)
+ __be16 protocol)
{
struct hh_cache *hh;
struct net_device *dev = dst->dev;
diff --git a/net/core/pktgen.c b/net/core/pktgen.c
index 72145d4a2600..dd023fd28304 100644
--- a/net/core/pktgen.c
+++ b/net/core/pktgen.c
@@ -109,6 +109,8 @@
*
* MPLS support by Steven Whitehouse <steve@chygwyn.com>
*
+ * 802.1Q/Q-in-Q support by Francesco Fondelli (FF) <francesco.fondelli@gmail.com>
+ *
*/
#include <linux/sys.h>
#include <linux/types.h>
@@ -137,6 +139,7 @@
#include <linux/inetdevice.h>
#include <linux/rtnetlink.h>
#include <linux/if_arp.h>
+#include <linux/if_vlan.h>
#include <linux/in.h>
#include <linux/ip.h>
#include <linux/ipv6.h>
@@ -157,7 +160,7 @@
#include <asm/div64.h> /* do_div */
#include <asm/timex.h>
-#define VERSION "pktgen v2.67: Packet Generator for packet performance testing.\n"
+#define VERSION "pktgen v2.68: Packet Generator for packet performance testing.\n"
/* #define PG_DEBUG(a) a */
#define PG_DEBUG(a)
@@ -178,6 +181,8 @@
#define F_TXSIZE_RND (1<<6) /* Transmit size is random */
#define F_IPV6 (1<<7) /* Interface in IPV6 Mode */
#define F_MPLS_RND (1<<8) /* Random MPLS labels */
+#define F_VID_RND (1<<9) /* Random VLAN ID */
+#define F_SVID_RND (1<<10) /* Random SVLAN ID */
/* Thread control flag bits */
#define T_TERMINATE (1<<0)
@@ -198,6 +203,9 @@ static struct proc_dir_entry *pg_proc_dir = NULL;
#define MAX_CFLOWS 65536
+#define VLAN_TAG_SIZE(x) ((x)->vlan_id == 0xffff ? 0 : 4)
+#define SVLAN_TAG_SIZE(x) ((x)->svlan_id == 0xffff ? 0 : 4)
+
struct flow_state {
__u32 cur_daddr;
int count;
@@ -284,10 +292,23 @@ struct pktgen_dev {
__u16 udp_dst_min; /* inclusive, dest UDP port */
__u16 udp_dst_max; /* exclusive, dest UDP port */
+ /* DSCP + ECN */
+ __u8 tos; /* six most significant bits of (former) IPv4 TOS are for dscp codepoint */
+ __u8 traffic_class; /* ditto for the (former) Traffic Class in IPv6 (see RFC 3260, sec. 4) */
+
/* MPLS */
unsigned nr_labels; /* Depth of stack, 0 = no MPLS */
__be32 labels[MAX_MPLS_LABELS];
+ /* VLAN/SVLAN (802.1Q/Q-in-Q) */
+ __u8 vlan_p;
+ __u8 vlan_cfi;
+ __u16 vlan_id; /* 0xffff means no vlan tag */
+
+ __u8 svlan_p;
+ __u8 svlan_cfi;
+ __u16 svlan_id; /* 0xffff means no svlan tag */
+
__u32 src_mac_count; /* How many MACs to iterate through */
__u32 dst_mac_count; /* How many MACs to iterate through */
@@ -644,6 +665,24 @@ static int pktgen_if_show(struct seq_file *seq, void *v)
i == pkt_dev->nr_labels-1 ? "\n" : ", ");
}
+ if (pkt_dev->vlan_id != 0xffff) {
+ seq_printf(seq, " vlan_id: %u vlan_p: %u vlan_cfi: %u\n",
+ pkt_dev->vlan_id, pkt_dev->vlan_p, pkt_dev->vlan_cfi);
+ }
+
+ if (pkt_dev->svlan_id != 0xffff) {
+ seq_printf(seq, " svlan_id: %u vlan_p: %u vlan_cfi: %u\n",
+ pkt_dev->svlan_id, pkt_dev->svlan_p, pkt_dev->svlan_cfi);
+ }
+
+ if (pkt_dev->tos) {
+ seq_printf(seq, " tos: 0x%02x\n", pkt_dev->tos);
+ }
+
+ if (pkt_dev->traffic_class) {
+ seq_printf(seq, " traffic_class: 0x%02x\n", pkt_dev->traffic_class);
+ }
+
seq_printf(seq, " Flags: ");
if (pkt_dev->flags & F_IPV6)
@@ -673,6 +712,12 @@ static int pktgen_if_show(struct seq_file *seq, void *v)
if (pkt_dev->flags & F_MACDST_RND)
seq_printf(seq, "MACDST_RND ");
+ if (pkt_dev->flags & F_VID_RND)
+ seq_printf(seq, "VID_RND ");
+
+ if (pkt_dev->flags & F_SVID_RND)
+ seq_printf(seq, "SVID_RND ");
+
seq_puts(seq, "\n");
sa = pkt_dev->started_at;
@@ -715,12 +760,12 @@ static int pktgen_if_show(struct seq_file *seq, void *v)
}
-static int hex32_arg(const char __user *user_buffer, __u32 *num)
+static int hex32_arg(const char __user *user_buffer, unsigned long maxlen, __u32 *num)
{
int i = 0;
*num = 0;
- for(; i < 8; i++) {
+ for(; i < maxlen; i++) {
char c;
*num <<= 4;
if (get_user(c, &user_buffer[i]))
@@ -815,7 +860,7 @@ static ssize_t get_labels(const char __user *buffer, struct pktgen_dev *pkt_dev)
pkt_dev->nr_labels = 0;
do {
__u32 tmp;
- len = hex32_arg(&buffer[i], &tmp);
+ len = hex32_arg(&buffer[i], 8, &tmp);
if (len <= 0)
return len;
pkt_dev->labels[n] = htonl(tmp);
@@ -1140,11 +1185,27 @@ static ssize_t pktgen_if_write(struct file *file,
else if (strcmp(f, "!MPLS_RND") == 0)
pkt_dev->flags &= ~F_MPLS_RND;
+ else if (strcmp(f, "VID_RND") == 0)
+ pkt_dev->flags |= F_VID_RND;
+
+ else if (strcmp(f, "!VID_RND") == 0)
+ pkt_dev->flags &= ~F_VID_RND;
+
+ else if (strcmp(f, "SVID_RND") == 0)
+ pkt_dev->flags |= F_SVID_RND;
+
+ else if (strcmp(f, "!SVID_RND") == 0)
+ pkt_dev->flags &= ~F_SVID_RND;
+
+ else if (strcmp(f, "!IPV6") == 0)
+ pkt_dev->flags &= ~F_IPV6;
+
else {
sprintf(pg_result,
"Flag -:%s:- unknown\nAvailable flags, (prepend ! to un-set flag):\n%s",
f,
- "IPSRC_RND, IPDST_RND, TXSIZE_RND, UDPSRC_RND, UDPDST_RND, MACSRC_RND, MACDST_RND\n");
+ "IPSRC_RND, IPDST_RND, UDPSRC_RND, UDPDST_RND, "
+ "MACSRC_RND, MACDST_RND, TXSIZE_RND, IPV6, MPLS_RND, VID_RND, SVID_RND\n");
return count;
}
sprintf(pg_result, "OK: flags=0x%x", pkt_dev->flags);
@@ -1445,6 +1506,160 @@ static ssize_t pktgen_if_write(struct file *file,
offset += sprintf(pg_result + offset,
"%08x%s", ntohl(pkt_dev->labels[n]),
n == pkt_dev->nr_labels-1 ? "" : ",");
+
+ if (pkt_dev->nr_labels && pkt_dev->vlan_id != 0xffff) {
+ pkt_dev->vlan_id = 0xffff; /* turn off VLAN/SVLAN */
+ pkt_dev->svlan_id = 0xffff;
+
+ if (debug)
+ printk("pktgen: VLAN/SVLAN auto turned off\n");
+ }
+ return count;
+ }
+
+ if (!strcmp(name, "vlan_id")) {
+ len = num_arg(&user_buffer[i], 4, &value);
+ if (len < 0) {
+ return len;
+ }
+ i += len;
+ if (value <= 4095) {
+ pkt_dev->vlan_id = value; /* turn on VLAN */
+
+ if (debug)
+ printk("pktgen: VLAN turned on\n");
+
+ if (debug && pkt_dev->nr_labels)
+ printk("pktgen: MPLS auto turned off\n");
+
+ pkt_dev->nr_labels = 0; /* turn off MPLS */
+ sprintf(pg_result, "OK: vlan_id=%u", pkt_dev->vlan_id);
+ } else {
+ pkt_dev->vlan_id = 0xffff; /* turn off VLAN/SVLAN */
+ pkt_dev->svlan_id = 0xffff;
+
+ if (debug)
+ printk("pktgen: VLAN/SVLAN turned off\n");
+ }
+ return count;
+ }
+
+ if (!strcmp(name, "vlan_p")) {
+ len = num_arg(&user_buffer[i], 1, &value);
+ if (len < 0) {
+ return len;
+ }
+ i += len;
+ if ((value <= 7) && (pkt_dev->vlan_id != 0xffff)) {
+ pkt_dev->vlan_p = value;
+ sprintf(pg_result, "OK: vlan_p=%u", pkt_dev->vlan_p);
+ } else {
+ sprintf(pg_result, "ERROR: vlan_p must be 0-7");
+ }
+ return count;
+ }
+
+ if (!strcmp(name, "vlan_cfi")) {
+ len = num_arg(&user_buffer[i], 1, &value);
+ if (len < 0) {
+ return len;
+ }
+ i += len;
+ if ((value <= 1) && (pkt_dev->vlan_id != 0xffff)) {
+ pkt_dev->vlan_cfi = value;
+ sprintf(pg_result, "OK: vlan_cfi=%u", pkt_dev->vlan_cfi);
+ } else {
+ sprintf(pg_result, "ERROR: vlan_cfi must be 0-1");
+ }
+ return count;
+ }
+
+ if (!strcmp(name, "svlan_id")) {
+ len = num_arg(&user_buffer[i], 4, &value);
+ if (len < 0) {
+ return len;
+ }
+ i += len;
+ if ((value <= 4095) && ((pkt_dev->vlan_id != 0xffff))) {
+ pkt_dev->svlan_id = value; /* turn on SVLAN */
+
+ if (debug)
+ printk("pktgen: SVLAN turned on\n");
+
+ if (debug && pkt_dev->nr_labels)
+ printk("pktgen: MPLS auto turned off\n");
+
+ pkt_dev->nr_labels = 0; /* turn off MPLS */
+ sprintf(pg_result, "OK: svlan_id=%u", pkt_dev->svlan_id);
+ } else {
+ pkt_dev->vlan_id = 0xffff; /* turn off VLAN/SVLAN */
+ pkt_dev->svlan_id = 0xffff;
+
+ if (debug)
+ printk("pktgen: VLAN/SVLAN turned off\n");
+ }
+ return count;
+ }
+
+ if (!strcmp(name, "svlan_p")) {
+ len = num_arg(&user_buffer[i], 1, &value);
+ if (len < 0) {
+ return len;
+ }
+ i += len;
+ if ((value <= 7) && (pkt_dev->svlan_id != 0xffff)) {
+ pkt_dev->svlan_p = value;
+ sprintf(pg_result, "OK: svlan_p=%u", pkt_dev->svlan_p);
+ } else {
+ sprintf(pg_result, "ERROR: svlan_p must be 0-7");
+ }
+ return count;
+ }
+
+ if (!strcmp(name, "svlan_cfi")) {
+ len = num_arg(&user_buffer[i], 1, &value);
+ if (len < 0) {
+ return len;
+ }
+ i += len;
+ if ((value <= 1) && (pkt_dev->svlan_id != 0xffff)) {
+ pkt_dev->svlan_cfi = value;
+ sprintf(pg_result, "OK: svlan_cfi=%u", pkt_dev->svlan_cfi);
+ } else {
+ sprintf(pg_result, "ERROR: svlan_cfi must be 0-1");
+ }
+ return count;
+ }
+
+ if (!strcmp(name, "tos")) {
+ __u32 tmp_value = 0;
+ len = hex32_arg(&user_buffer[i], 2, &tmp_value);
+ if (len < 0) {
+ return len;
+ }
+ i += len;
+ if (len == 2) {
+ pkt_dev->tos = tmp_value;
+ sprintf(pg_result, "OK: tos=0x%02x", pkt_dev->tos);
+ } else {
+ sprintf(pg_result, "ERROR: tos must be 00-ff");
+ }
+ return count;
+ }
+
+ if (!strcmp(name, "traffic_class")) {
+ __u32 tmp_value = 0;
+ len = hex32_arg(&user_buffer[i], 2, &tmp_value);
+ if (len < 0) {
+ return len;
+ }
+ i += len;
+ if (len == 2) {
+ pkt_dev->traffic_class = tmp_value;
+ sprintf(pg_result, "OK: traffic_class=0x%02x", pkt_dev->traffic_class);
+ } else {
+ sprintf(pg_result, "ERROR: traffic_class must be 00-ff");
+ }
return count;
}
@@ -1949,6 +2164,14 @@ static void mod_cur_headers(struct pktgen_dev *pkt_dev)
htonl(0x000fffff));
}
+ if ((pkt_dev->flags & F_VID_RND) && (pkt_dev->vlan_id != 0xffff)) {
+ pkt_dev->vlan_id = pktgen_random() % 4096;
+ }
+
+ if ((pkt_dev->flags & F_SVID_RND) && (pkt_dev->svlan_id != 0xffff)) {
+ pkt_dev->svlan_id = pktgen_random() % 4096;
+ }
+
if (pkt_dev->udp_src_min < pkt_dev->udp_src_max) {
if (pkt_dev->flags & F_UDPSRC_RND)
pkt_dev->cur_udp_src =
@@ -2092,10 +2315,18 @@ static struct sk_buff *fill_packet_ipv4(struct net_device *odev,
struct pktgen_hdr *pgh = NULL;
__be16 protocol = __constant_htons(ETH_P_IP);
__be32 *mpls;
+ __be16 *vlan_tci = NULL; /* Encapsulates priority and VLAN ID */
+ __be16 *vlan_encapsulated_proto = NULL; /* packet type ID field (or len) for VLAN tag */
+ __be16 *svlan_tci = NULL; /* Encapsulates priority and SVLAN ID */
+ __be16 *svlan_encapsulated_proto = NULL; /* packet type ID field (or len) for SVLAN tag */
+
if (pkt_dev->nr_labels)
protocol = __constant_htons(ETH_P_MPLS_UC);
+ if (pkt_dev->vlan_id != 0xffff)
+ protocol = __constant_htons(ETH_P_8021Q);
+
/* Update any of the values, used when we're incrementing various
* fields.
*/
@@ -2103,7 +2334,9 @@ static struct sk_buff *fill_packet_ipv4(struct net_device *odev,
datalen = (odev->hard_header_len + 16) & ~0xf;
skb = alloc_skb(pkt_dev->cur_pkt_size + 64 + datalen +
- pkt_dev->nr_labels*sizeof(u32), GFP_ATOMIC);
+ pkt_dev->nr_labels*sizeof(u32) +
+ VLAN_TAG_SIZE(pkt_dev) + SVLAN_TAG_SIZE(pkt_dev),
+ GFP_ATOMIC);
if (!skb) {
sprintf(pkt_dev->result, "No memory");
return NULL;
@@ -2116,6 +2349,24 @@ static struct sk_buff *fill_packet_ipv4(struct net_device *odev,
mpls = (__be32 *)skb_put(skb, pkt_dev->nr_labels*sizeof(__u32));
if (pkt_dev->nr_labels)
mpls_push(mpls, pkt_dev);
+
+ if (pkt_dev->vlan_id != 0xffff) {
+ if(pkt_dev->svlan_id != 0xffff) {
+ svlan_tci = (__be16 *)skb_put(skb, sizeof(__be16));
+ *svlan_tci = htons(pkt_dev->svlan_id);
+ *svlan_tci |= pkt_dev->svlan_p << 5;
+ *svlan_tci |= pkt_dev->svlan_cfi << 4;
+ svlan_encapsulated_proto = (__be16 *)skb_put(skb, sizeof(__be16));
+ *svlan_encapsulated_proto = __constant_htons(ETH_P_8021Q);
+ }
+ vlan_tci = (__be16 *)skb_put(skb, sizeof(__be16));
+ *vlan_tci = htons(pkt_dev->vlan_id);
+ *vlan_tci |= pkt_dev->vlan_p << 5;
+ *vlan_tci |= pkt_dev->vlan_cfi << 4;
+ vlan_encapsulated_proto = (__be16 *)skb_put(skb, sizeof(__be16));
+ *vlan_encapsulated_proto = __constant_htons(ETH_P_IP);
+ }
+
iph = (struct iphdr *)skb_put(skb, sizeof(struct iphdr));
udph = (struct udphdr *)skb_put(skb, sizeof(struct udphdr));
@@ -2124,7 +2375,7 @@ static struct sk_buff *fill_packet_ipv4(struct net_device *odev,
/* Eth + IPh + UDPh + mpls */
datalen = pkt_dev->cur_pkt_size - 14 - 20 - 8 -
- pkt_dev->nr_labels*sizeof(u32);
+ pkt_dev->nr_labels*sizeof(u32) - VLAN_TAG_SIZE(pkt_dev) - SVLAN_TAG_SIZE(pkt_dev);
if (datalen < sizeof(struct pktgen_hdr))
datalen = sizeof(struct pktgen_hdr);
@@ -2136,7 +2387,7 @@ static struct sk_buff *fill_packet_ipv4(struct net_device *odev,
iph->ihl = 5;
iph->version = 4;
iph->ttl = 32;
- iph->tos = 0;
+ iph->tos = pkt_dev->tos;
iph->protocol = IPPROTO_UDP; /* UDP */
iph->saddr = pkt_dev->cur_saddr;
iph->daddr = pkt_dev->cur_daddr;
@@ -2146,7 +2397,8 @@ static struct sk_buff *fill_packet_ipv4(struct net_device *odev,
iph->check = 0;
iph->check = ip_fast_csum((void *)iph, iph->ihl);
skb->protocol = protocol;
- skb->mac.raw = ((u8 *) iph) - 14 - pkt_dev->nr_labels*sizeof(u32);
+ skb->mac.raw = ((u8 *) iph) - 14 - pkt_dev->nr_labels*sizeof(u32) -
+ VLAN_TAG_SIZE(pkt_dev) - SVLAN_TAG_SIZE(pkt_dev);
skb->dev = odev;
skb->pkt_type = PACKET_HOST;
skb->nh.iph = iph;
@@ -2218,7 +2470,6 @@ static struct sk_buff *fill_packet_ipv4(struct net_device *odev,
pgh->tv_sec = htonl(timestamp.tv_sec);
pgh->tv_usec = htonl(timestamp.tv_usec);
}
- pkt_dev->seq_num++;
return skb;
}
@@ -2402,17 +2653,26 @@ static struct sk_buff *fill_packet_ipv6(struct net_device *odev,
struct pktgen_hdr *pgh = NULL;
__be16 protocol = __constant_htons(ETH_P_IPV6);
__be32 *mpls;
+ __be16 *vlan_tci = NULL; /* Encapsulates priority and VLAN ID */
+ __be16 *vlan_encapsulated_proto = NULL; /* packet type ID field (or len) for VLAN tag */
+ __be16 *svlan_tci = NULL; /* Encapsulates priority and SVLAN ID */
+ __be16 *svlan_encapsulated_proto = NULL; /* packet type ID field (or len) for SVLAN tag */
if (pkt_dev->nr_labels)
protocol = __constant_htons(ETH_P_MPLS_UC);
+ if (pkt_dev->vlan_id != 0xffff)
+ protocol = __constant_htons(ETH_P_8021Q);
+
/* Update any of the values, used when we're incrementing various
* fields.
*/
mod_cur_headers(pkt_dev);
skb = alloc_skb(pkt_dev->cur_pkt_size + 64 + 16 +
- pkt_dev->nr_labels*sizeof(u32), GFP_ATOMIC);
+ pkt_dev->nr_labels*sizeof(u32) +
+ VLAN_TAG_SIZE(pkt_dev) + SVLAN_TAG_SIZE(pkt_dev),
+ GFP_ATOMIC);
if (!skb) {
sprintf(pkt_dev->result, "No memory");
return NULL;
@@ -2425,16 +2685,34 @@ static struct sk_buff *fill_packet_ipv6(struct net_device *odev,
mpls = (__be32 *)skb_put(skb, pkt_dev->nr_labels*sizeof(__u32));
if (pkt_dev->nr_labels)
mpls_push(mpls, pkt_dev);
+
+ if (pkt_dev->vlan_id != 0xffff) {
+ if(pkt_dev->svlan_id != 0xffff) {
+ svlan_tci = (__be16 *)skb_put(skb, sizeof(__be16));
+ *svlan_tci = htons(pkt_dev->svlan_id);
+ *svlan_tci |= pkt_dev->svlan_p << 5;
+ *svlan_tci |= pkt_dev->svlan_cfi << 4;
+ svlan_encapsulated_proto = (__be16 *)skb_put(skb, sizeof(__be16));
+ *svlan_encapsulated_proto = __constant_htons(ETH_P_8021Q);
+ }
+ vlan_tci = (__be16 *)skb_put(skb, sizeof(__be16));
+ *vlan_tci = htons(pkt_dev->vlan_id);
+ *vlan_tci |= pkt_dev->vlan_p << 5;
+ *vlan_tci |= pkt_dev->vlan_cfi << 4;
+ vlan_encapsulated_proto = (__be16 *)skb_put(skb, sizeof(__be16));
+ *vlan_encapsulated_proto = __constant_htons(ETH_P_IPV6);
+ }
+
iph = (struct ipv6hdr *)skb_put(skb, sizeof(struct ipv6hdr));
udph = (struct udphdr *)skb_put(skb, sizeof(struct udphdr));
memcpy(eth, pkt_dev->hh, 12);
- *(u16 *) & eth[12] = __constant_htons(ETH_P_IPV6);
+ *(u16 *) & eth[12] = protocol;
/* Eth + IPh + UDPh + mpls */
datalen = pkt_dev->cur_pkt_size - 14 -
sizeof(struct ipv6hdr) - sizeof(struct udphdr) -
- pkt_dev->nr_labels*sizeof(u32);
+ pkt_dev->nr_labels*sizeof(u32) - VLAN_TAG_SIZE(pkt_dev) - SVLAN_TAG_SIZE(pkt_dev);
if (datalen < sizeof(struct pktgen_hdr)) {
datalen = sizeof(struct pktgen_hdr);
@@ -2450,6 +2728,11 @@ static struct sk_buff *fill_packet_ipv6(struct net_device *odev,
*(u32 *) iph = __constant_htonl(0x60000000); /* Version + flow */
+ if (pkt_dev->traffic_class) {
+ /* Version + traffic class + flow (0) */
+ *(u32 *)iph |= htonl(0x60000000 | (pkt_dev->traffic_class << 20));
+ }
+
iph->hop_limit = 32;
iph->payload_len = htons(sizeof(struct udphdr) + datalen);
@@ -2458,7 +2741,8 @@ static struct sk_buff *fill_packet_ipv6(struct net_device *odev,
ipv6_addr_copy(&iph->daddr, &pkt_dev->cur_in6_daddr);
ipv6_addr_copy(&iph->saddr, &pkt_dev->cur_in6_saddr);
- skb->mac.raw = ((u8 *) iph) - 14 - pkt_dev->nr_labels*sizeof(u32);
+ skb->mac.raw = ((u8 *) iph) - 14 - pkt_dev->nr_labels*sizeof(u32) -
+ VLAN_TAG_SIZE(pkt_dev) - SVLAN_TAG_SIZE(pkt_dev);
skb->protocol = protocol;
skb->dev = odev;
skb->pkt_type = PACKET_HOST;
@@ -2531,7 +2815,7 @@ static struct sk_buff *fill_packet_ipv6(struct net_device *odev,
pgh->tv_sec = htonl(timestamp.tv_sec);
pgh->tv_usec = htonl(timestamp.tv_usec);
}
- pkt_dev->seq_num++;
+ /* pkt_dev->seq_num++; FF: you really mean this? */
return skb;
}
@@ -3177,6 +3461,13 @@ static int pktgen_add_device(struct pktgen_thread *t, const char *ifname)
pkt_dev->udp_dst_min = 9;
pkt_dev->udp_dst_max = 9;
+ pkt_dev->vlan_p = 0;
+ pkt_dev->vlan_cfi = 0;
+ pkt_dev->vlan_id = 0xffff;
+ pkt_dev->svlan_p = 0;
+ pkt_dev->svlan_cfi = 0;
+ pkt_dev->svlan_id = 0xffff;
+
strncpy(pkt_dev->ifname, ifname, IFNAMSIZ);
if (!pktgen_setup_dev(pkt_dev)) {
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index d8e25e08cb7e..221e4038216b 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -562,7 +562,7 @@ static int rtnl_getlink(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg)
err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFLA_MAX, ifla_policy);
if (err < 0)
- goto errout;
+ return err;
ifm = nlmsg_data(nlh);
if (ifm->ifi_index >= 0) {
diff --git a/net/core/utils.c b/net/core/utils.c
index 2682490777de..94c5d761c830 100644
--- a/net/core/utils.c
+++ b/net/core/utils.c
@@ -3,7 +3,7 @@
*
* Authors:
* net_random Alan Cox
- * net_ratelimit Andy Kleen
+ * net_ratelimit Andi Kleen
* in{4,6}_pton YOSHIFUJI Hideaki, Copyright (C)2006 USAGI/WIDE Project
*
* Created by Alexey Kuznetsov <kuznet@ms2.inr.ac.ru>
diff --git a/net/dccp/ipv4.c b/net/dccp/ipv4.c
index 66be29b6f508..bf692c1c116f 100644
--- a/net/dccp/ipv4.c
+++ b/net/dccp/ipv4.c
@@ -50,7 +50,7 @@ int dccp_v4_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len)
struct dccp_sock *dp = dccp_sk(sk);
const struct sockaddr_in *usin = (struct sockaddr_in *)uaddr;
struct rtable *rt;
- u32 daddr, nexthop;
+ __be32 daddr, nexthop;
int tmp;
int err;
diff --git a/net/ethernet/eth.c b/net/ethernet/eth.c
index 43863933f27f..4bd78c8cfb26 100644
--- a/net/ethernet/eth.c
+++ b/net/ethernet/eth.c
@@ -223,7 +223,7 @@ static int eth_header_parse(struct sk_buff *skb, unsigned char *haddr)
*/
int eth_header_cache(struct neighbour *neigh, struct hh_cache *hh)
{
- unsigned short type = hh->hh_type;
+ __be16 type = hh->hh_type;
struct ethhdr *eth;
struct net_device *dev = neigh->dev;
diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c
index fdd89e37b9aa..edcf0932ac6d 100644
--- a/net/ipv4/af_inet.c
+++ b/net/ipv4/af_inet.c
@@ -996,7 +996,7 @@ static int inet_sk_reselect_saddr(struct sock *sk)
struct rtable *rt;
__u32 old_saddr = inet->saddr;
__u32 new_saddr;
- __u32 daddr = inet->daddr;
+ __be32 daddr = inet->daddr;
if (inet->opt && inet->opt->srr)
daddr = inet->opt->faddr;
@@ -1043,7 +1043,7 @@ int inet_sk_rebuild_header(struct sock *sk)
{
struct inet_sock *inet = inet_sk(sk);
struct rtable *rt = (struct rtable *)__sk_dst_check(sk, 0);
- u32 daddr;
+ __be32 daddr;
int err;
/* Route is OK, nothing to do. */
@@ -1342,10 +1342,10 @@ static int __init inet_init(void)
rc = 0;
out:
return rc;
-out_unregister_tcp_proto:
- proto_unregister(&tcp_prot);
out_unregister_udp_proto:
proto_unregister(&udp_prot);
+out_unregister_tcp_proto:
+ proto_unregister(&tcp_prot);
goto out;
}
diff --git a/net/ipv4/arp.c b/net/ipv4/arp.c
index c8a3723bc001..cfe5c8474286 100644
--- a/net/ipv4/arp.c
+++ b/net/ipv4/arp.c
@@ -234,7 +234,7 @@ static u32 arp_hash(const void *pkey, const struct net_device *dev)
static int arp_constructor(struct neighbour *neigh)
{
- u32 addr = *(u32*)neigh->primary_key;
+ __be32 addr = *(__be32*)neigh->primary_key;
struct net_device *dev = neigh->dev;
struct in_device *in_dev;
struct neigh_parms *parms;
@@ -330,10 +330,10 @@ static void arp_error_report(struct neighbour *neigh, struct sk_buff *skb)
static void arp_solicit(struct neighbour *neigh, struct sk_buff *skb)
{
- u32 saddr = 0;
+ __be32 saddr = 0;
u8 *dst_ha = NULL;
struct net_device *dev = neigh->dev;
- u32 target = *(u32*)neigh->primary_key;
+ __be32 target = *(__be32*)neigh->primary_key;
int probes = atomic_read(&neigh->probes);
struct in_device *in_dev = in_dev_get(dev);
@@ -385,7 +385,7 @@ static void arp_solicit(struct neighbour *neigh, struct sk_buff *skb)
}
static int arp_ignore(struct in_device *in_dev, struct net_device *dev,
- u32 sip, u32 tip)
+ __be32 sip, __be32 tip)
{
int scope;
@@ -420,7 +420,7 @@ static int arp_ignore(struct in_device *in_dev, struct net_device *dev,
return !inet_confirm_addr(dev, sip, tip, scope);
}
-static int arp_filter(__u32 sip, __u32 tip, struct net_device *dev)
+static int arp_filter(__be32 sip, __be32 tip, struct net_device *dev)
{
struct flowi fl = { .nl_u = { .ip4_u = { .daddr = sip,
.saddr = tip } } };
@@ -449,7 +449,7 @@ static int arp_filter(__u32 sip, __u32 tip, struct net_device *dev)
* is allowed to use this function, it is scheduled to be removed. --ANK
*/
-static int arp_set_predefined(int addr_hint, unsigned char * haddr, u32 paddr, struct net_device * dev)
+static int arp_set_predefined(int addr_hint, unsigned char * haddr, __be32 paddr, struct net_device * dev)
{
switch (addr_hint) {
case RTN_LOCAL:
@@ -470,7 +470,7 @@ static int arp_set_predefined(int addr_hint, unsigned char * haddr, u32 paddr, s
int arp_find(unsigned char *haddr, struct sk_buff *skb)
{
struct net_device *dev = skb->dev;
- u32 paddr;
+ __be32 paddr;
struct neighbour *n;
if (!skb->dst) {
@@ -511,7 +511,7 @@ int arp_bind_neighbour(struct dst_entry *dst)
if (dev == NULL)
return -EINVAL;
if (n == NULL) {
- u32 nexthop = ((struct rtable*)dst)->rt_gateway;
+ __be32 nexthop = ((struct rtable*)dst)->rt_gateway;
if (dev->flags&(IFF_LOOPBACK|IFF_POINTOPOINT))
nexthop = 0;
n = __neigh_lookup_errno(
@@ -560,8 +560,8 @@ static inline int arp_fwd_proxy(struct in_device *in_dev, struct rtable *rt)
* Create an arp packet. If (dest_hw == NULL), we create a broadcast
* message.
*/
-struct sk_buff *arp_create(int type, int ptype, u32 dest_ip,
- struct net_device *dev, u32 src_ip,
+struct sk_buff *arp_create(int type, int ptype, __be32 dest_ip,
+ struct net_device *dev, __be32 src_ip,
unsigned char *dest_hw, unsigned char *src_hw,
unsigned char *target_hw)
{
@@ -675,8 +675,8 @@ void arp_xmit(struct sk_buff *skb)
/*
* Create and send an arp packet.
*/
-void arp_send(int type, int ptype, u32 dest_ip,
- struct net_device *dev, u32 src_ip,
+void arp_send(int type, int ptype, __be32 dest_ip,
+ struct net_device *dev, __be32 src_ip,
unsigned char *dest_hw, unsigned char *src_hw,
unsigned char *target_hw)
{
@@ -710,7 +710,7 @@ static int arp_process(struct sk_buff *skb)
unsigned char *arp_ptr;
struct rtable *rt;
unsigned char *sha, *tha;
- u32 sip, tip;
+ __be32 sip, tip;
u16 dev_type = dev->type;
int addr_type;
struct neighbour *n;
@@ -969,13 +969,13 @@ out_of_mem:
static int arp_req_set(struct arpreq *r, struct net_device * dev)
{
- u32 ip = ((struct sockaddr_in *) &r->arp_pa)->sin_addr.s_addr;
+ __be32 ip = ((struct sockaddr_in *) &r->arp_pa)->sin_addr.s_addr;
struct neighbour *neigh;
int err;
if (r->arp_flags&ATF_PUBL) {
- u32 mask = ((struct sockaddr_in *) &r->arp_netmask)->sin_addr.s_addr;
- if (mask && mask != 0xFFFFFFFF)
+ __be32 mask = ((struct sockaddr_in *) &r->arp_netmask)->sin_addr.s_addr;
+ if (mask && mask != htonl(0xFFFFFFFF))
return -EINVAL;
if (!dev && (r->arp_flags & ATF_COM)) {
dev = dev_getbyhwaddr(r->arp_ha.sa_family, r->arp_ha.sa_data);
@@ -1063,7 +1063,7 @@ static unsigned arp_state_to_flags(struct neighbour *neigh)
static int arp_req_get(struct arpreq *r, struct net_device *dev)
{
- u32 ip = ((struct sockaddr_in *) &r->arp_pa)->sin_addr.s_addr;
+ __be32 ip = ((struct sockaddr_in *) &r->arp_pa)->sin_addr.s_addr;
struct neighbour *neigh;
int err = -ENXIO;
@@ -1084,13 +1084,13 @@ static int arp_req_get(struct arpreq *r, struct net_device *dev)
static int arp_req_delete(struct arpreq *r, struct net_device * dev)
{
int err;
- u32 ip = ((struct sockaddr_in *)&r->arp_pa)->sin_addr.s_addr;
+ __be32 ip = ((struct sockaddr_in *)&r->arp_pa)->sin_addr.s_addr;
struct neighbour *neigh;
if (r->arp_flags & ATF_PUBL) {
- u32 mask =
+ __be32 mask =
((struct sockaddr_in *)&r->arp_netmask)->sin_addr.s_addr;
- if (mask == 0xFFFFFFFF)
+ if (mask == htonl(0xFFFFFFFF))
return pneigh_delete(&arp_tbl, &ip, dev);
if (mask == 0) {
if (dev == NULL) {
diff --git a/net/ipv4/cipso_ipv4.c b/net/ipv4/cipso_ipv4.c
index e6ce0b3ba62a..a8e2e879a647 100644
--- a/net/ipv4/cipso_ipv4.c
+++ b/net/ipv4/cipso_ipv4.c
@@ -474,6 +474,7 @@ doi_add_failure_rlock:
/**
* cipso_v4_doi_remove - Remove an existing DOI from the CIPSO protocol engine
* @doi: the DOI value
+ * @audit_secid: the LSM secid to use in the audit message
* @callback: the DOI cleanup/free callback
*
* Description:
@@ -483,7 +484,9 @@ doi_add_failure_rlock:
* success and negative values on failure.
*
*/
-int cipso_v4_doi_remove(u32 doi, void (*callback) (struct rcu_head * head))
+int cipso_v4_doi_remove(u32 doi,
+ struct netlbl_audit *audit_info,
+ void (*callback) (struct rcu_head * head))
{
struct cipso_v4_doi *doi_def;
struct cipso_v4_domhsh_entry *dom_iter;
@@ -502,7 +505,8 @@ int cipso_v4_doi_remove(u32 doi, void (*callback) (struct rcu_head * head))
spin_unlock(&cipso_v4_doi_list_lock);
list_for_each_entry_rcu(dom_iter, &doi_def->dom_list, list)
if (dom_iter->valid)
- netlbl_domhsh_remove(dom_iter->domain);
+ netlbl_domhsh_remove(dom_iter->domain,
+ audit_info);
cipso_v4_cache_invalidate();
rcu_read_unlock();
diff --git a/net/ipv4/datagram.c b/net/ipv4/datagram.c
index ec5da4fbd9f4..7b068a891953 100644
--- a/net/ipv4/datagram.c
+++ b/net/ipv4/datagram.c
@@ -25,7 +25,7 @@ int ip4_datagram_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len)
struct inet_sock *inet = inet_sk(sk);
struct sockaddr_in *usin = (struct sockaddr_in *) uaddr;
struct rtable *rt;
- u32 saddr;
+ __be32 saddr;
int oif;
int err;
diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c
index 8e8d1f17d77a..7602c79a389b 100644
--- a/net/ipv4/devinet.c
+++ b/net/ipv4/devinet.c
@@ -224,7 +224,7 @@ static void inetdev_destroy(struct in_device *in_dev)
call_rcu(&in_dev->rcu_head, in_dev_rcu_put);
}
-int inet_addr_onlink(struct in_device *in_dev, u32 a, u32 b)
+int inet_addr_onlink(struct in_device *in_dev, __be32 a, __be32 b)
{
rcu_read_lock();
for_primary_ifa(in_dev) {
@@ -429,8 +429,8 @@ struct in_device *inetdev_by_index(int ifindex)
/* Called only from RTNL semaphored context. No locks. */
-struct in_ifaddr *inet_ifa_byprefix(struct in_device *in_dev, u32 prefix,
- u32 mask)
+struct in_ifaddr *inet_ifa_byprefix(struct in_device *in_dev, __be32 prefix,
+ __be32 mask)
{
ASSERT_RTNL();
@@ -467,7 +467,7 @@ static int inet_rtm_deladdr(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg
for (ifap = &in_dev->ifa_list; (ifa = *ifap) != NULL;
ifap = &ifa->ifa_next) {
if (tb[IFA_LOCAL] &&
- ifa->ifa_local != nla_get_u32(tb[IFA_LOCAL]))
+ ifa->ifa_local != nla_get_be32(tb[IFA_LOCAL]))
continue;
if (tb[IFA_LABEL] && nla_strcmp(tb[IFA_LABEL], ifa->ifa_label))
@@ -475,7 +475,7 @@ static int inet_rtm_deladdr(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg
if (tb[IFA_ADDRESS] &&
(ifm->ifa_prefixlen != ifa->ifa_prefixlen ||
- !inet_ifa_match(nla_get_u32(tb[IFA_ADDRESS]), ifa)))
+ !inet_ifa_match(nla_get_be32(tb[IFA_ADDRESS]), ifa)))
continue;
__inet_del_ifa(in_dev, ifap, 1, nlh, NETLINK_CB(skb).pid);
@@ -540,14 +540,14 @@ static struct in_ifaddr *rtm_to_ifaddr(struct nlmsghdr *nlh)
ifa->ifa_scope = ifm->ifa_scope;
ifa->ifa_dev = in_dev;
- ifa->ifa_local = nla_get_u32(tb[IFA_LOCAL]);
- ifa->ifa_address = nla_get_u32(tb[IFA_ADDRESS]);
+ ifa->ifa_local = nla_get_be32(tb[IFA_LOCAL]);
+ ifa->ifa_address = nla_get_be32(tb[IFA_ADDRESS]);
if (tb[IFA_BROADCAST])
- ifa->ifa_broadcast = nla_get_u32(tb[IFA_BROADCAST]);
+ ifa->ifa_broadcast = nla_get_be32(tb[IFA_BROADCAST]);
if (tb[IFA_ANYCAST])
- ifa->ifa_anycast = nla_get_u32(tb[IFA_ANYCAST]);
+ ifa->ifa_anycast = nla_get_be32(tb[IFA_ANYCAST]);
if (tb[IFA_LABEL])
nla_strlcpy(ifa->ifa_label, tb[IFA_LABEL], IFNAMSIZ);
@@ -805,7 +805,7 @@ int devinet_ioctl(unsigned int cmd, void __user *arg)
break;
ret = 0;
if (ifa->ifa_mask != sin->sin_addr.s_addr) {
- u32 old_mask = ifa->ifa_mask;
+ __be32 old_mask = ifa->ifa_mask;
inet_del_ifa(in_dev, ifap, 0);
ifa->ifa_mask = sin->sin_addr.s_addr;
ifa->ifa_prefixlen = inet_mask_len(ifa->ifa_mask);
@@ -876,9 +876,9 @@ out:
return done;
}
-u32 inet_select_addr(const struct net_device *dev, u32 dst, int scope)
+__be32 inet_select_addr(const struct net_device *dev, __be32 dst, int scope)
{
- u32 addr = 0;
+ __be32 addr = 0;
struct in_device *in_dev;
rcu_read_lock();
@@ -927,11 +927,11 @@ out:
return addr;
}
-static u32 confirm_addr_indev(struct in_device *in_dev, u32 dst,
- u32 local, int scope)
+static __be32 confirm_addr_indev(struct in_device *in_dev, __be32 dst,
+ __be32 local, int scope)
{
int same = 0;
- u32 addr = 0;
+ __be32 addr = 0;
for_ifa(in_dev) {
if (!addr &&
@@ -971,9 +971,9 @@ static u32 confirm_addr_indev(struct in_device *in_dev, u32 dst,
* - local: address, 0=autoselect the local address
* - scope: maximum allowed scope value for the local address
*/
-u32 inet_confirm_addr(const struct net_device *dev, u32 dst, u32 local, int scope)
+__be32 inet_confirm_addr(const struct net_device *dev, __be32 dst, __be32 local, int scope)
{
- u32 addr = 0;
+ __be32 addr = 0;
struct in_device *in_dev;
if (dev) {
@@ -1138,16 +1138,16 @@ static int inet_fill_ifaddr(struct sk_buff *skb, struct in_ifaddr *ifa,
ifm->ifa_index = ifa->ifa_dev->dev->ifindex;
if (ifa->ifa_address)
- NLA_PUT_U32(skb, IFA_ADDRESS, ifa->ifa_address);
+ NLA_PUT_BE32(skb, IFA_ADDRESS, ifa->ifa_address);
if (ifa->ifa_local)
- NLA_PUT_U32(skb, IFA_LOCAL, ifa->ifa_local);
+ NLA_PUT_BE32(skb, IFA_LOCAL, ifa->ifa_local);
if (ifa->ifa_broadcast)
- NLA_PUT_U32(skb, IFA_BROADCAST, ifa->ifa_broadcast);
+ NLA_PUT_BE32(skb, IFA_BROADCAST, ifa->ifa_broadcast);
if (ifa->ifa_anycast)
- NLA_PUT_U32(skb, IFA_ANYCAST, ifa->ifa_anycast);
+ NLA_PUT_BE32(skb, IFA_ANYCAST, ifa->ifa_anycast);
if (ifa->ifa_label[0])
NLA_PUT_STRING(skb, IFA_LABEL, ifa->ifa_label);
diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c
index cfb527c060e4..9c399a70dd5d 100644
--- a/net/ipv4/fib_frontend.c
+++ b/net/ipv4/fib_frontend.c
@@ -122,7 +122,7 @@ static void fib_flush(void)
* Find the first device with a given source address.
*/
-struct net_device * ip_dev_find(u32 addr)
+struct net_device * ip_dev_find(__be32 addr)
{
struct flowi fl = { .nl_u = { .ip4_u = { .daddr = addr } } };
struct fib_result res;
@@ -146,7 +146,7 @@ out:
return dev;
}
-unsigned inet_addr_type(u32 addr)
+unsigned inet_addr_type(__be32 addr)
{
struct flowi fl = { .nl_u = { .ip4_u = { .daddr = addr } } };
struct fib_result res;
@@ -180,8 +180,8 @@ unsigned inet_addr_type(u32 addr)
- check, that packet arrived from expected physical interface.
*/
-int fib_validate_source(u32 src, u32 dst, u8 tos, int oif,
- struct net_device *dev, u32 *spec_dst, u32 *itag)
+int fib_validate_source(__be32 src, __be32 dst, u8 tos, int oif,
+ struct net_device *dev, __be32 *spec_dst, u32 *itag)
{
struct in_device *in_dev;
struct flowi fl = { .nl_u = { .ip4_u =
@@ -253,7 +253,7 @@ e_inval:
#ifndef CONFIG_IP_NOSIOCRT
-static inline u32 sk_extract_addr(struct sockaddr *addr)
+static inline __be32 sk_extract_addr(struct sockaddr *addr)
{
return ((struct sockaddr_in *) addr)->sin_addr.s_addr;
}
@@ -273,7 +273,7 @@ static int put_rtax(struct nlattr *mx, int len, int type, u32 value)
static int rtentry_to_fib_config(int cmd, struct rtentry *rt,
struct fib_config *cfg)
{
- u32 addr;
+ __be32 addr;
int plen;
memset(cfg, 0, sizeof(*cfg));
@@ -292,7 +292,7 @@ static int rtentry_to_fib_config(int cmd, struct rtentry *rt,
plen = 32;
addr = sk_extract_addr(&rt->rt_dst);
if (!(rt->rt_flags & RTF_HOST)) {
- u32 mask = sk_extract_addr(&rt->rt_genmask);
+ __be32 mask = sk_extract_addr(&rt->rt_genmask);
if (rt->rt_genmask.sa_family != AF_INET) {
if (mask || rt->rt_genmask.sa_family)
@@ -499,22 +499,22 @@ static int rtm_to_fib_config(struct sk_buff *skb, struct nlmsghdr *nlh,
nlmsg_for_each_attr(attr, nlh, sizeof(struct rtmsg), remaining) {
switch (attr->nla_type) {
case RTA_DST:
- cfg->fc_dst = nla_get_u32(attr);
+ cfg->fc_dst = nla_get_be32(attr);
break;
case RTA_SRC:
- cfg->fc_src = nla_get_u32(attr);
+ cfg->fc_src = nla_get_be32(attr);
break;
case RTA_OIF:
cfg->fc_oif = nla_get_u32(attr);
break;
case RTA_GATEWAY:
- cfg->fc_gw = nla_get_u32(attr);
+ cfg->fc_gw = nla_get_be32(attr);
break;
case RTA_PRIORITY:
cfg->fc_priority = nla_get_u32(attr);
break;
case RTA_PREFSRC:
- cfg->fc_prefsrc = nla_get_u32(attr);
+ cfg->fc_prefsrc = nla_get_be32(attr);
break;
case RTA_METRICS:
cfg->fc_mx = nla_data(attr);
@@ -627,8 +627,7 @@ out:
only when netlink is already locked.
*/
-static void fib_magic(int cmd, int type, u32 dst, int dst_len,
- struct in_ifaddr *ifa)
+static void fib_magic(int cmd, int type, __be32 dst, int dst_len, struct in_ifaddr *ifa)
{
struct fib_table *tb;
struct fib_config cfg = {
@@ -667,9 +666,9 @@ void fib_add_ifaddr(struct in_ifaddr *ifa)
struct in_device *in_dev = ifa->ifa_dev;
struct net_device *dev = in_dev->dev;
struct in_ifaddr *prim = ifa;
- u32 mask = ifa->ifa_mask;
- u32 addr = ifa->ifa_local;
- u32 prefix = ifa->ifa_address&mask;
+ __be32 mask = ifa->ifa_mask;
+ __be32 addr = ifa->ifa_local;
+ __be32 prefix = ifa->ifa_address&mask;
if (ifa->ifa_flags&IFA_F_SECONDARY) {
prim = inet_ifa_byprefix(in_dev, prefix, mask);
@@ -685,7 +684,7 @@ void fib_add_ifaddr(struct in_ifaddr *ifa)
return;
/* Add broadcast address, if it is explicitly assigned. */
- if (ifa->ifa_broadcast && ifa->ifa_broadcast != 0xFFFFFFFF)
+ if (ifa->ifa_broadcast && ifa->ifa_broadcast != htonl(0xFFFFFFFF))
fib_magic(RTM_NEWROUTE, RTN_BROADCAST, ifa->ifa_broadcast, 32, prim);
if (!ZERONET(prefix) && !(ifa->ifa_flags&IFA_F_SECONDARY) &&
@@ -707,8 +706,8 @@ static void fib_del_ifaddr(struct in_ifaddr *ifa)
struct net_device *dev = in_dev->dev;
struct in_ifaddr *ifa1;
struct in_ifaddr *prim = ifa;
- u32 brd = ifa->ifa_address|~ifa->ifa_mask;
- u32 any = ifa->ifa_address&ifa->ifa_mask;
+ __be32 brd = ifa->ifa_address|~ifa->ifa_mask;
+ __be32 any = ifa->ifa_address&ifa->ifa_mask;
#define LOCAL_OK 1
#define BRD_OK 2
#define BRD0_OK 4
diff --git a/net/ipv4/fib_hash.c b/net/ipv4/fib_hash.c
index 88133b383dc5..107bb6cbb0b3 100644
--- a/net/ipv4/fib_hash.c
+++ b/net/ipv4/fib_hash.c
@@ -51,7 +51,7 @@ static kmem_cache_t *fn_alias_kmem __read_mostly;
struct fib_node {
struct hlist_node fn_hash;
struct list_head fn_alias;
- u32 fn_key;
+ __be32 fn_key;
};
struct fn_zone {
@@ -64,7 +64,7 @@ struct fn_zone {
#define FZ_HASHMASK(fz) ((fz)->fz_hashmask)
int fz_order; /* Zone order */
- u32 fz_mask;
+ __be32 fz_mask;
#define FZ_MASK(fz) ((fz)->fz_mask)
};
@@ -77,7 +77,7 @@ struct fn_hash {
struct fn_zone *fn_zone_list;
};
-static inline u32 fn_hash(u32 key, struct fn_zone *fz)
+static inline u32 fn_hash(__be32 key, struct fn_zone *fz)
{
u32 h = ntohl(key)>>(32 - fz->fz_order);
h ^= (h>>20);
@@ -87,7 +87,7 @@ static inline u32 fn_hash(u32 key, struct fn_zone *fz)
return h;
}
-static inline u32 fz_key(u32 dst, struct fn_zone *fz)
+static inline __be32 fz_key(__be32 dst, struct fn_zone *fz)
{
return dst & FZ_MASK(fz);
}
@@ -254,7 +254,7 @@ fn_hash_lookup(struct fib_table *tb, const struct flowi *flp, struct fib_result
struct hlist_head *head;
struct hlist_node *node;
struct fib_node *f;
- u32 k = fz_key(flp->fl4_dst, fz);
+ __be32 k = fz_key(flp->fl4_dst, fz);
head = &fz->fz_hash[fn_hash(k, fz)];
hlist_for_each_entry(f, node, head, fn_hash) {
@@ -365,7 +365,7 @@ static inline void fib_insert_node(struct fn_zone *fz, struct fib_node *f)
}
/* Return the node in FZ matching KEY. */
-static struct fib_node *fib_find_node(struct fn_zone *fz, u32 key)
+static struct fib_node *fib_find_node(struct fn_zone *fz, __be32 key)
{
struct hlist_head *head = &fz->fz_hash[fn_hash(key, fz)];
struct hlist_node *node;
@@ -387,7 +387,7 @@ static int fn_hash_insert(struct fib_table *tb, struct fib_config *cfg)
struct fn_zone *fz;
struct fib_info *fi;
u8 tos = cfg->fc_tos;
- u32 key;
+ __be32 key;
int err;
if (cfg->fc_dst_len > 32)
@@ -541,7 +541,7 @@ static int fn_hash_delete(struct fib_table *tb, struct fib_config *cfg)
struct fib_node *f;
struct fib_alias *fa, *fa_to_delete;
struct fn_zone *fz;
- u32 key;
+ __be32 key;
if (cfg->fc_dst_len > 32)
return -EINVAL;
@@ -966,7 +966,7 @@ static void fib_seq_stop(struct seq_file *seq, void *v)
read_unlock(&fib_hash_lock);
}
-static unsigned fib_flag_trans(int type, u32 mask, struct fib_info *fi)
+static unsigned fib_flag_trans(int type, __be32 mask, struct fib_info *fi)
{
static const unsigned type2flags[RTN_MAX + 1] = {
[7] = RTF_REJECT, [8] = RTF_REJECT,
@@ -975,7 +975,7 @@ static unsigned fib_flag_trans(int type, u32 mask, struct fib_info *fi)
if (fi && fi->fib_nh->nh_gw)
flags |= RTF_GATEWAY;
- if (mask == 0xFFFFFFFF)
+ if (mask == htonl(0xFFFFFFFF))
flags |= RTF_HOST;
flags |= RTF_UP;
return flags;
@@ -991,7 +991,7 @@ static int fib_seq_show(struct seq_file *seq, void *v)
{
struct fib_iter_state *iter;
char bf[128];
- u32 prefix, mask;
+ __be32 prefix, mask;
unsigned flags;
struct fib_node *f;
struct fib_alias *fa;
diff --git a/net/ipv4/fib_lookup.h b/net/ipv4/fib_lookup.h
index fd6f7769f8ab..0e8b70bad4e1 100644
--- a/net/ipv4/fib_lookup.h
+++ b/net/ipv4/fib_lookup.h
@@ -20,16 +20,16 @@ struct fib_alias {
/* Exported by fib_semantics.c */
extern int fib_semantic_match(struct list_head *head,
const struct flowi *flp,
- struct fib_result *res, __u32 zone, __u32 mask,
+ struct fib_result *res, __be32 zone, __be32 mask,
int prefixlen);
extern void fib_release_info(struct fib_info *);
extern struct fib_info *fib_create_info(struct fib_config *cfg);
extern int fib_nh_match(struct fib_config *cfg, struct fib_info *fi);
extern int fib_dump_info(struct sk_buff *skb, u32 pid, u32 seq, int event,
- u32 tb_id, u8 type, u8 scope, u32 dst,
+ u32 tb_id, u8 type, u8 scope, __be32 dst,
int dst_len, u8 tos, struct fib_info *fi,
unsigned int);
-extern void rtmsg_fib(int event, u32 key, struct fib_alias *fa,
+extern void rtmsg_fib(int event, __be32 key, struct fib_alias *fa,
int dst_len, u32 tb_id, struct nl_info *info);
extern struct fib_alias *fib_find_alias(struct list_head *fah,
u8 tos, u32 prio);
diff --git a/net/ipv4/fib_rules.c b/net/ipv4/fib_rules.c
index 52b2adae4f22..0852b9cd065a 100644
--- a/net/ipv4/fib_rules.c
+++ b/net/ipv4/fib_rules.c
@@ -40,10 +40,10 @@ struct fib4_rule
u8 dst_len;
u8 src_len;
u8 tos;
- u32 src;
- u32 srcmask;
- u32 dst;
- u32 dstmask;
+ __be32 src;
+ __be32 srcmask;
+ __be32 dst;
+ __be32 dstmask;
#ifdef CONFIG_IP_ROUTE_FWMARK
u32 fwmark;
u32 fwmask;
@@ -150,8 +150,8 @@ void fib_select_default(const struct flowi *flp, struct fib_result *res)
static int fib4_rule_match(struct fib_rule *rule, struct flowi *fl, int flags)
{
struct fib4_rule *r = (struct fib4_rule *) rule;
- u32 daddr = fl->fl4_dst;
- u32 saddr = fl->fl4_src;
+ __be32 daddr = fl->fl4_dst;
+ __be32 saddr = fl->fl4_src;
if (((saddr ^ r->src) & r->srcmask) ||
((daddr ^ r->dst) & r->dstmask))
@@ -215,10 +215,10 @@ static int fib4_rule_configure(struct fib_rule *rule, struct sk_buff *skb,
}
if (tb[FRA_SRC])
- rule4->src = nla_get_u32(tb[FRA_SRC]);
+ rule4->src = nla_get_be32(tb[FRA_SRC]);
if (tb[FRA_DST])
- rule4->dst = nla_get_u32(tb[FRA_DST]);
+ rule4->dst = nla_get_be32(tb[FRA_DST]);
#ifdef CONFIG_IP_ROUTE_FWMARK
if (tb[FRA_FWMARK]) {
@@ -277,10 +277,10 @@ static int fib4_rule_compare(struct fib_rule *rule, struct fib_rule_hdr *frh,
return 0;
#endif
- if (tb[FRA_SRC] && (rule4->src != nla_get_u32(tb[FRA_SRC])))
+ if (tb[FRA_SRC] && (rule4->src != nla_get_be32(tb[FRA_SRC])))
return 0;
- if (tb[FRA_DST] && (rule4->dst != nla_get_u32(tb[FRA_DST])))
+ if (tb[FRA_DST] && (rule4->dst != nla_get_be32(tb[FRA_DST])))
return 0;
return 1;
@@ -305,10 +305,10 @@ static int fib4_rule_fill(struct fib_rule *rule, struct sk_buff *skb,
#endif
if (rule4->dst_len)
- NLA_PUT_U32(skb, FRA_DST, rule4->dst);
+ NLA_PUT_BE32(skb, FRA_DST, rule4->dst);
if (rule4->src_len)
- NLA_PUT_U32(skb, FRA_SRC, rule4->src);
+ NLA_PUT_BE32(skb, FRA_SRC, rule4->src);
#ifdef CONFIG_NET_CLS_ROUTE
if (rule4->tclassid)
diff --git a/net/ipv4/fib_semantics.c b/net/ipv4/fib_semantics.c
index 2ead09543f68..884d176e0082 100644
--- a/net/ipv4/fib_semantics.c
+++ b/net/ipv4/fib_semantics.c
@@ -203,7 +203,7 @@ static inline unsigned int fib_info_hashfn(const struct fib_info *fi)
unsigned int val = fi->fib_nhs;
val ^= fi->fib_protocol;
- val ^= fi->fib_prefsrc;
+ val ^= (__force u32)fi->fib_prefsrc;
val ^= fi->fib_priority;
return (val ^ (val >> 7) ^ (val >> 12)) & mask;
@@ -248,7 +248,7 @@ static inline unsigned int fib_devindex_hashfn(unsigned int val)
Used only by redirect accept routine.
*/
-int ip_fib_check_default(u32 gw, struct net_device *dev)
+int ip_fib_check_default(__be32 gw, struct net_device *dev)
{
struct hlist_head *head;
struct hlist_node *node;
@@ -273,7 +273,7 @@ int ip_fib_check_default(u32 gw, struct net_device *dev)
return -1;
}
-void rtmsg_fib(int event, u32 key, struct fib_alias *fa,
+void rtmsg_fib(int event, __be32 key, struct fib_alias *fa,
int dst_len, u32 tb_id, struct nl_info *info)
{
struct sk_buff *skb;
@@ -374,7 +374,7 @@ static int fib_get_nhs(struct fib_info *fi, struct rtnexthop *rtnh,
struct nlattr *nla, *attrs = rtnh_attrs(rtnh);
nla = nla_find(attrs, attrlen, RTA_GATEWAY);
- nh->nh_gw = nla ? nla_get_u32(nla) : 0;
+ nh->nh_gw = nla ? nla_get_be32(nla) : 0;
#ifdef CONFIG_NET_CLS_ROUTE
nla = nla_find(attrs, attrlen, RTA_FLOW);
nh->nh_tclassid = nla ? nla_get_u32(nla) : 0;
@@ -427,7 +427,7 @@ int fib_nh_match(struct fib_config *cfg, struct fib_info *fi)
struct nlattr *nla, *attrs = rtnh_attrs(rtnh);
nla = nla_find(attrs, attrlen, RTA_GATEWAY);
- if (nla && nla_get_u32(nla) != nh->nh_gw)
+ if (nla && nla_get_be32(nla) != nh->nh_gw)
return 1;
#ifdef CONFIG_NET_CLS_ROUTE
nla = nla_find(attrs, attrlen, RTA_FLOW);
@@ -568,11 +568,11 @@ out:
return 0;
}
-static inline unsigned int fib_laddr_hashfn(u32 val)
+static inline unsigned int fib_laddr_hashfn(__be32 val)
{
unsigned int mask = (fib_hash_size - 1);
- return (val ^ (val >> 7) ^ (val >> 14)) & mask;
+ return ((__force u32)val ^ ((__force u32)val >> 7) ^ ((__force u32)val >> 14)) & mask;
}
static struct hlist_head *fib_hash_alloc(int bytes)
@@ -847,7 +847,7 @@ failure:
/* Note! fib_semantic_match intentionally uses RCU list functions. */
int fib_semantic_match(struct list_head *head, const struct flowi *flp,
- struct fib_result *res, __u32 zone, __u32 mask,
+ struct fib_result *res, __be32 zone, __be32 mask,
int prefixlen)
{
struct fib_alias *fa;
@@ -914,8 +914,7 @@ out_fill_res:
res->fi = fa->fa_info;
#ifdef CONFIG_IP_ROUTE_MULTIPATH_CACHED
res->netmask = mask;
- res->network = zone &
- (0xFFFFFFFF >> (32 - prefixlen));
+ res->network = zone & inet_make_mask(prefixlen);
#endif
atomic_inc(&res->fi->fib_clntref);
return 0;
@@ -923,13 +922,13 @@ out_fill_res:
/* Find appropriate source address to this destination */
-u32 __fib_res_prefsrc(struct fib_result *res)
+__be32 __fib_res_prefsrc(struct fib_result *res)
{
return inet_select_addr(FIB_RES_DEV(*res), FIB_RES_GW(*res), res->scope);
}
int fib_dump_info(struct sk_buff *skb, u32 pid, u32 seq, int event,
- u32 tb_id, u8 type, u8 scope, u32 dst, int dst_len, u8 tos,
+ u32 tb_id, u8 type, u8 scope, __be32 dst, int dst_len, u8 tos,
struct fib_info *fi, unsigned int flags)
{
struct nlmsghdr *nlh;
@@ -952,7 +951,7 @@ int fib_dump_info(struct sk_buff *skb, u32 pid, u32 seq, int event,
rtm->rtm_protocol = fi->fib_protocol;
if (rtm->rtm_dst_len)
- NLA_PUT_U32(skb, RTA_DST, dst);
+ NLA_PUT_BE32(skb, RTA_DST, dst);
if (fi->fib_priority)
NLA_PUT_U32(skb, RTA_PRIORITY, fi->fib_priority);
@@ -961,11 +960,11 @@ int fib_dump_info(struct sk_buff *skb, u32 pid, u32 seq, int event,
goto nla_put_failure;
if (fi->fib_prefsrc)
- NLA_PUT_U32(skb, RTA_PREFSRC, fi->fib_prefsrc);
+ NLA_PUT_BE32(skb, RTA_PREFSRC, fi->fib_prefsrc);
if (fi->fib_nhs == 1) {
if (fi->fib_nh->nh_gw)
- NLA_PUT_U32(skb, RTA_GATEWAY, fi->fib_nh->nh_gw);
+ NLA_PUT_BE32(skb, RTA_GATEWAY, fi->fib_nh->nh_gw);
if (fi->fib_nh->nh_oif)
NLA_PUT_U32(skb, RTA_OIF, fi->fib_nh->nh_oif);
@@ -993,7 +992,7 @@ int fib_dump_info(struct sk_buff *skb, u32 pid, u32 seq, int event,
rtnh->rtnh_ifindex = nh->nh_oif;
if (nh->nh_gw)
- NLA_PUT_U32(skb, RTA_GATEWAY, nh->nh_gw);
+ NLA_PUT_BE32(skb, RTA_GATEWAY, nh->nh_gw);
#ifdef CONFIG_NET_CLS_ROUTE
if (nh->nh_tclassid)
NLA_PUT_U32(skb, RTA_FLOW, nh->nh_tclassid);
@@ -1018,7 +1017,7 @@ nla_put_failure:
- device went down -> we must shutdown all nexthops going via it.
*/
-int fib_sync_down(u32 local, struct net_device *dev, int force)
+int fib_sync_down(__be32 local, struct net_device *dev, int force)
{
int ret = 0;
int scope = RT_SCOPE_NOWHERE;
diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c
index 9c3ff6ba6e21..d17990ec724f 100644
--- a/net/ipv4/fib_trie.c
+++ b/net/ipv4/fib_trie.c
@@ -1834,7 +1834,7 @@ static int fn_trie_dump_fa(t_key key, int plen, struct list_head *fah, struct fi
int i, s_i;
struct fib_alias *fa;
- u32 xkey = htonl(key);
+ __be32 xkey = htonl(key);
s_i = cb->args[4];
i = 0;
@@ -2281,7 +2281,7 @@ static int fib_trie_seq_show(struct seq_file *seq, void *v)
if (IS_TNODE(n)) {
struct tnode *tn = (struct tnode *) n;
- t_key prf = ntohl(MASK_PFX(tn->key, tn->pos));
+ __be32 prf = htonl(MASK_PFX(tn->key, tn->pos));
if (!NODE_PARENT(n)) {
if (iter->trie == trie_local)
@@ -2297,7 +2297,7 @@ static int fib_trie_seq_show(struct seq_file *seq, void *v)
} else {
struct leaf *l = (struct leaf *) n;
int i;
- u32 val = ntohl(l->key);
+ __be32 val = htonl(l->key);
seq_indent(seq, iter->depth);
seq_printf(seq, " |-- %d.%d.%d.%d\n", NIPQUAD(val));
@@ -2360,7 +2360,7 @@ static struct file_operations fib_trie_fops = {
.release = seq_release_private,
};
-static unsigned fib_flag_trans(int type, u32 mask, const struct fib_info *fi)
+static unsigned fib_flag_trans(int type, __be32 mask, const struct fib_info *fi)
{
static unsigned type2flags[RTN_MAX + 1] = {
[7] = RTF_REJECT, [8] = RTF_REJECT,
@@ -2369,7 +2369,7 @@ static unsigned fib_flag_trans(int type, u32 mask, const struct fib_info *fi)
if (fi && fi->fib_nh->nh_gw)
flags |= RTF_GATEWAY;
- if (mask == 0xFFFFFFFF)
+ if (mask == htonl(0xFFFFFFFF))
flags |= RTF_HOST;
flags |= RTF_UP;
return flags;
@@ -2403,7 +2403,7 @@ static int fib_route_seq_show(struct seq_file *seq, void *v)
for (i=32; i>=0; i--) {
struct leaf_info *li = find_leaf_info(l, i);
struct fib_alias *fa;
- u32 mask, prefix;
+ __be32 mask, prefix;
if (!li)
continue;
diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c
index c2ad07e48ab4..b39a37a47545 100644
--- a/net/ipv4/icmp.c
+++ b/net/ipv4/icmp.c
@@ -104,7 +104,7 @@ struct icmp_bxm {
struct {
struct icmphdr icmph;
- __u32 times[3];
+ __be32 times[3];
} data;
int head_len;
struct ip_options replyopts;
@@ -381,7 +381,7 @@ static void icmp_reply(struct icmp_bxm *icmp_param, struct sk_buff *skb)
struct inet_sock *inet = inet_sk(sk);
struct ipcm_cookie ipc;
struct rtable *rt = (struct rtable *)skb->dst;
- u32 daddr;
+ __be32 daddr;
if (ip_options_echo(&icmp_param->replyopts, skb))
return;
@@ -430,14 +430,14 @@ out_unlock:
* MUST reply to only the first fragment.
*/
-void icmp_send(struct sk_buff *skb_in, int type, int code, u32 info)
+void icmp_send(struct sk_buff *skb_in, int type, int code, __be32 info)
{
struct iphdr *iph;
int room;
struct icmp_bxm icmp_param;
struct rtable *rt = (struct rtable *)skb_in->dst;
struct ipcm_cookie ipc;
- u32 saddr;
+ __be32 saddr;
u8 tos;
if (!rt)
@@ -895,7 +895,7 @@ static void icmp_address_reply(struct sk_buff *skb)
if (in_dev->ifa_list &&
IN_DEV_LOG_MARTIANS(in_dev) &&
IN_DEV_FORWARD(in_dev)) {
- u32 _mask, *mp;
+ __be32 _mask, *mp;
mp = skb_header_pointer(skb, 0, sizeof(_mask), &_mask);
BUG_ON(mp == NULL);
diff --git a/net/ipv4/igmp.c b/net/ipv4/igmp.c
index 58be8227b0cb..6eee71647b7c 100644
--- a/net/ipv4/igmp.c
+++ b/net/ipv4/igmp.c
@@ -138,14 +138,14 @@
time_before(jiffies, (in_dev)->mr_v2_seen)))
static void igmpv3_add_delrec(struct in_device *in_dev, struct ip_mc_list *im);
-static void igmpv3_del_delrec(struct in_device *in_dev, __u32 multiaddr);
+static void igmpv3_del_delrec(struct in_device *in_dev, __be32 multiaddr);
static void igmpv3_clear_delrec(struct in_device *in_dev);
static int sf_setstate(struct ip_mc_list *pmc);
static void sf_markstate(struct ip_mc_list *pmc);
#endif
static void ip_mc_clear_src(struct ip_mc_list *pmc);
-static int ip_mc_add_src(struct in_device *in_dev, __u32 *pmca, int sfmode,
- int sfcount, __u32 *psfsrc, int delta);
+static int ip_mc_add_src(struct in_device *in_dev, __be32 *pmca, int sfmode,
+ int sfcount, __be32 *psfsrc, int delta);
static void ip_ma_put(struct ip_mc_list *im)
{
@@ -426,7 +426,7 @@ static struct sk_buff *add_grec(struct sk_buff *skb, struct ip_mc_list *pmc,
first = 1;
psf_prev = NULL;
for (psf=*psf_list; psf; psf=psf_next) {
- u32 *psrc;
+ __be32 *psrc;
psf_next = psf->sf_next;
@@ -439,7 +439,7 @@ static struct sk_buff *add_grec(struct sk_buff *skb, struct ip_mc_list *pmc,
if (isquery)
psf->sf_gsresp = 0;
- if (AVAILABLE(skb) < sizeof(u32) +
+ if (AVAILABLE(skb) < sizeof(__be32) +
first*sizeof(struct igmpv3_grec)) {
if (truncate && !first)
break; /* truncate these */
@@ -455,7 +455,7 @@ static struct sk_buff *add_grec(struct sk_buff *skb, struct ip_mc_list *pmc,
skb = add_grhead(skb, pmc, type, &pgr);
first = 0;
}
- psrc = (u32 *)skb_put(skb, sizeof(u32));
+ psrc = (__be32 *)skb_put(skb, sizeof(__be32));
*psrc = psf->sf_inaddr;
scount++; stotal++;
if ((type == IGMPV3_ALLOW_NEW_SOURCES ||
@@ -630,8 +630,8 @@ static int igmp_send_report(struct in_device *in_dev, struct ip_mc_list *pmc,
struct igmphdr *ih;
struct rtable *rt;
struct net_device *dev = in_dev->dev;
- u32 group = pmc ? pmc->multiaddr : 0;
- u32 dst;
+ __be32 group = pmc ? pmc->multiaddr : 0;
+ __be32 dst;
if (type == IGMPV3_HOST_MEMBERSHIP_REPORT)
return igmpv3_send_report(in_dev, pmc);
@@ -748,7 +748,7 @@ static void igmp_timer_expire(unsigned long data)
}
/* mark EXCLUDE-mode sources */
-static int igmp_xmarksources(struct ip_mc_list *pmc, int nsrcs, __u32 *srcs)
+static int igmp_xmarksources(struct ip_mc_list *pmc, int nsrcs, __be32 *srcs)
{
struct ip_sf_list *psf;
int i, scount;
@@ -775,7 +775,7 @@ static int igmp_xmarksources(struct ip_mc_list *pmc, int nsrcs, __u32 *srcs)
return 1;
}
-static int igmp_marksources(struct ip_mc_list *pmc, int nsrcs, __u32 *srcs)
+static int igmp_marksources(struct ip_mc_list *pmc, int nsrcs, __be32 *srcs)
{
struct ip_sf_list *psf;
int i, scount;
@@ -803,7 +803,7 @@ static int igmp_marksources(struct ip_mc_list *pmc, int nsrcs, __u32 *srcs)
return 1;
}
-static void igmp_heard_report(struct in_device *in_dev, u32 group)
+static void igmp_heard_report(struct in_device *in_dev, __be32 group)
{
struct ip_mc_list *im;
@@ -828,7 +828,7 @@ static void igmp_heard_query(struct in_device *in_dev, struct sk_buff *skb,
struct igmphdr *ih = skb->h.igmph;
struct igmpv3_query *ih3 = (struct igmpv3_query *)ih;
struct ip_mc_list *im;
- u32 group = ih->group;
+ __be32 group = ih->group;
int max_delay;
int mark = 0;
@@ -862,7 +862,7 @@ static void igmp_heard_query(struct in_device *in_dev, struct sk_buff *skb,
ih3 = (struct igmpv3_query *) skb->h.raw;
if (ih3->nsrcs) {
if (!pskb_may_pull(skb, sizeof(struct igmpv3_query)
- + ntohs(ih3->nsrcs)*sizeof(__u32)))
+ + ntohs(ih3->nsrcs)*sizeof(__be32)))
return;
ih3 = (struct igmpv3_query *) skb->h.raw;
}
@@ -985,7 +985,7 @@ drop:
* Add a filter to a device
*/
-static void ip_mc_filter_add(struct in_device *in_dev, u32 addr)
+static void ip_mc_filter_add(struct in_device *in_dev, __be32 addr)
{
char buf[MAX_ADDR_LEN];
struct net_device *dev = in_dev->dev;
@@ -1005,7 +1005,7 @@ static void ip_mc_filter_add(struct in_device *in_dev, u32 addr)
* Remove a filter from a device
*/
-static void ip_mc_filter_del(struct in_device *in_dev, u32 addr)
+static void ip_mc_filter_del(struct in_device *in_dev, __be32 addr)
{
char buf[MAX_ADDR_LEN];
struct net_device *dev = in_dev->dev;
@@ -1055,7 +1055,7 @@ static void igmpv3_add_delrec(struct in_device *in_dev, struct ip_mc_list *im)
spin_unlock_bh(&in_dev->mc_tomb_lock);
}
-static void igmpv3_del_delrec(struct in_device *in_dev, __u32 multiaddr)
+static void igmpv3_del_delrec(struct in_device *in_dev, __be32 multiaddr)
{
struct ip_mc_list *pmc, *pmc_prev;
struct ip_sf_list *psf, *psf_next;
@@ -1193,7 +1193,7 @@ static void igmp_group_added(struct ip_mc_list *im)
* A socket has joined a multicast group on device dev.
*/
-void ip_mc_inc_group(struct in_device *in_dev, u32 addr)
+void ip_mc_inc_group(struct in_device *in_dev, __be32 addr)
{
struct ip_mc_list *im;
@@ -1252,7 +1252,7 @@ out:
* A socket has left a multicast group on device dev
*/
-void ip_mc_dec_group(struct in_device *in_dev, u32 addr)
+void ip_mc_dec_group(struct in_device *in_dev, __be32 addr)
{
struct ip_mc_list *i, **ip;
@@ -1402,7 +1402,7 @@ int sysctl_igmp_max_msf __read_mostly = IP_MAX_MSF;
static int ip_mc_del1_src(struct ip_mc_list *pmc, int sfmode,
- __u32 *psfsrc)
+ __be32 *psfsrc)
{
struct ip_sf_list *psf, *psf_prev;
int rv = 0;
@@ -1450,8 +1450,8 @@ static int ip_mc_del1_src(struct ip_mc_list *pmc, int sfmode,
#define igmp_ifc_event(x) do { } while (0)
#endif
-static int ip_mc_del_src(struct in_device *in_dev, __u32 *pmca, int sfmode,
- int sfcount, __u32 *psfsrc, int delta)
+static int ip_mc_del_src(struct in_device *in_dev, __be32 *pmca, int sfmode,
+ int sfcount, __be32 *psfsrc, int delta)
{
struct ip_mc_list *pmc;
int changerec = 0;
@@ -1517,7 +1517,7 @@ out_unlock:
* Add multicast single-source filter to the interface list
*/
static int ip_mc_add1_src(struct ip_mc_list *pmc, int sfmode,
- __u32 *psfsrc, int delta)
+ __be32 *psfsrc, int delta)
{
struct ip_sf_list *psf, *psf_prev;
@@ -1623,8 +1623,8 @@ static int sf_setstate(struct ip_mc_list *pmc)
/*
* Add multicast source filter list to the interface list
*/
-static int ip_mc_add_src(struct in_device *in_dev, __u32 *pmca, int sfmode,
- int sfcount, __u32 *psfsrc, int delta)
+static int ip_mc_add_src(struct in_device *in_dev, __be32 *pmca, int sfmode,
+ int sfcount, __be32 *psfsrc, int delta)
{
struct ip_mc_list *pmc;
int isexclude;
@@ -1717,7 +1717,7 @@ static void ip_mc_clear_src(struct ip_mc_list *pmc)
int ip_mc_join_group(struct sock *sk , struct ip_mreqn *imr)
{
int err;
- u32 addr = imr->imr_multiaddr.s_addr;
+ __be32 addr = imr->imr_multiaddr.s_addr;
struct ip_mc_socklist *iml=NULL, *i;
struct in_device *in_dev;
struct inet_sock *inet = inet_sk(sk);
@@ -1791,7 +1791,7 @@ int ip_mc_leave_group(struct sock *sk, struct ip_mreqn *imr)
struct inet_sock *inet = inet_sk(sk);
struct ip_mc_socklist *iml, **imlp;
struct in_device *in_dev;
- u32 group = imr->imr_multiaddr.s_addr;
+ __be32 group = imr->imr_multiaddr.s_addr;
u32 ifindex;
int ret = -EADDRNOTAVAIL;
@@ -1829,7 +1829,7 @@ int ip_mc_source(int add, int omode, struct sock *sk, struct
{
int err;
struct ip_mreqn imr;
- u32 addr = mreqs->imr_multiaddr;
+ __be32 addr = mreqs->imr_multiaddr;
struct ip_mc_socklist *pmc;
struct in_device *in_dev = NULL;
struct inet_sock *inet = inet_sk(sk);
@@ -1883,7 +1883,7 @@ int ip_mc_source(int add, int omode, struct sock *sk, struct
rv = !0;
for (i=0; i<psl->sl_count; i++) {
rv = memcmp(&psl->sl_addr[i], &mreqs->imr_sourceaddr,
- sizeof(__u32));
+ sizeof(__be32));
if (rv == 0)
break;
}
@@ -1935,7 +1935,7 @@ int ip_mc_source(int add, int omode, struct sock *sk, struct
rv = 1; /* > 0 for insert logic below if sl_count is 0 */
for (i=0; i<psl->sl_count; i++) {
rv = memcmp(&psl->sl_addr[i], &mreqs->imr_sourceaddr,
- sizeof(__u32));
+ sizeof(__be32));
if (rv == 0)
break;
}
@@ -1960,7 +1960,7 @@ int ip_mc_msfilter(struct sock *sk, struct ip_msfilter *msf, int ifindex)
{
int err = 0;
struct ip_mreqn imr;
- u32 addr = msf->imsf_multiaddr;
+ __be32 addr = msf->imsf_multiaddr;
struct ip_mc_socklist *pmc;
struct in_device *in_dev;
struct inet_sock *inet = inet_sk(sk);
@@ -2044,7 +2044,7 @@ int ip_mc_msfget(struct sock *sk, struct ip_msfilter *msf,
{
int err, len, count, copycount;
struct ip_mreqn imr;
- u32 addr = msf->imsf_multiaddr;
+ __be32 addr = msf->imsf_multiaddr;
struct ip_mc_socklist *pmc;
struct in_device *in_dev;
struct inet_sock *inet = inet_sk(sk);
@@ -2103,7 +2103,7 @@ int ip_mc_gsfget(struct sock *sk, struct group_filter *gsf,
{
int err, i, count, copycount;
struct sockaddr_in *psin;
- u32 addr;
+ __be32 addr;
struct ip_mc_socklist *pmc;
struct inet_sock *inet = inet_sk(sk);
struct ip_sf_socklist *psl;
@@ -2156,7 +2156,7 @@ done:
/*
* check if a multicast source filter allows delivery for a given <src,dst,intf>
*/
-int ip_mc_sf_allow(struct sock *sk, u32 loc_addr, u32 rmt_addr, int dif)
+int ip_mc_sf_allow(struct sock *sk, __be32 loc_addr, __be32 rmt_addr, int dif)
{
struct inet_sock *inet = inet_sk(sk);
struct ip_mc_socklist *pmc;
@@ -2216,7 +2216,7 @@ void ip_mc_drop_socket(struct sock *sk)
rtnl_unlock();
}
-int ip_check_mc(struct in_device *in_dev, u32 mc_addr, u32 src_addr, u16 proto)
+int ip_check_mc(struct in_device *in_dev, __be32 mc_addr, __be32 src_addr, u16 proto)
{
struct ip_mc_list *im;
struct ip_sf_list *psf;
diff --git a/net/ipv4/inet_connection_sock.c b/net/ipv4/inet_connection_sock.c
index 07204391d083..96bbe2a0aa1b 100644
--- a/net/ipv4/inet_connection_sock.c
+++ b/net/ipv4/inet_connection_sock.c
@@ -39,7 +39,7 @@ int sysctl_local_port_range[2] = { 1024, 4999 };
int inet_csk_bind_conflict(const struct sock *sk,
const struct inet_bind_bucket *tb)
{
- const u32 sk_rcv_saddr = inet_rcv_saddr(sk);
+ const __be32 sk_rcv_saddr = inet_rcv_saddr(sk);
struct sock *sk2;
struct hlist_node *node;
int reuse = sk->sk_reuse;
@@ -52,7 +52,7 @@ int inet_csk_bind_conflict(const struct sock *sk,
sk->sk_bound_dev_if == sk2->sk_bound_dev_if)) {
if (!reuse || !sk2->sk_reuse ||
sk2->sk_state == TCP_LISTEN) {
- const u32 sk2_rcv_saddr = inet_rcv_saddr(sk2);
+ const __be32 sk2_rcv_saddr = inet_rcv_saddr(sk2);
if (!sk2_rcv_saddr || !sk_rcv_saddr ||
sk2_rcv_saddr == sk_rcv_saddr)
break;
@@ -342,10 +342,10 @@ struct dst_entry* inet_csk_route_req(struct sock *sk,
EXPORT_SYMBOL_GPL(inet_csk_route_req);
-static inline u32 inet_synq_hash(const u32 raddr, const u16 rport,
+static inline u32 inet_synq_hash(const __be32 raddr, const __be16 rport,
const u32 rnd, const u16 synq_hsize)
{
- return jhash_2words(raddr, (u32)rport, rnd) & (synq_hsize - 1);
+ return jhash_2words((__force u32)raddr, (__force u32)rport, rnd) & (synq_hsize - 1);
}
#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
@@ -356,8 +356,8 @@ static inline u32 inet_synq_hash(const u32 raddr, const u16 rport,
struct request_sock *inet_csk_search_req(const struct sock *sk,
struct request_sock ***prevp,
- const __u16 rport, const __u32 raddr,
- const __u32 laddr)
+ const __be16 rport, const __be32 raddr,
+ const __be32 laddr)
{
const struct inet_connection_sock *icsk = inet_csk(sk);
struct listen_sock *lopt = icsk->icsk_accept_queue.listen_opt;
diff --git a/net/ipv4/inet_diag.c b/net/ipv4/inet_diag.c
index 492858e6faf0..77761ac4f7bb 100644
--- a/net/ipv4/inet_diag.c
+++ b/net/ipv4/inet_diag.c
@@ -36,8 +36,8 @@
static const struct inet_diag_handler **inet_diag_table;
struct inet_diag_entry {
- u32 *saddr;
- u32 *daddr;
+ __be32 *saddr;
+ __be32 *daddr;
u16 sport;
u16 dport;
u16 family;
@@ -294,7 +294,7 @@ out:
return err;
}
-static int bitstring_match(const u32 *a1, const u32 *a2, int bits)
+static int bitstring_match(const __be32 *a1, const __be32 *a2, int bits)
{
int words = bits >> 5;
@@ -305,8 +305,8 @@ static int bitstring_match(const u32 *a1, const u32 *a2, int bits)
return 0;
}
if (bits) {
- __u32 w1, w2;
- __u32 mask;
+ __be32 w1, w2;
+ __be32 mask;
w1 = a1[words];
w2 = a2[words];
@@ -352,7 +352,7 @@ static int inet_diag_bc_run(const void *bc, int len,
case INET_DIAG_BC_S_COND:
case INET_DIAG_BC_D_COND: {
struct inet_diag_hostcond *cond;
- u32 *addr;
+ __be32 *addr;
cond = (struct inet_diag_hostcond *)(op + 1);
if (cond->port != -1 &&
diff --git a/net/ipv4/inet_hashtables.c b/net/ipv4/inet_hashtables.c
index fb296c9a7f3f..244c4f445c7d 100644
--- a/net/ipv4/inet_hashtables.c
+++ b/net/ipv4/inet_hashtables.c
@@ -125,7 +125,7 @@ EXPORT_SYMBOL(inet_listen_wlock);
* wildcarded during the search since they can never be otherwise.
*/
static struct sock *inet_lookup_listener_slow(const struct hlist_head *head,
- const u32 daddr,
+ const __be32 daddr,
const unsigned short hnum,
const int dif)
{
@@ -137,7 +137,7 @@ static struct sock *inet_lookup_listener_slow(const struct hlist_head *head,
const struct inet_sock *inet = inet_sk(sk);
if (inet->num == hnum && !ipv6_only_sock(sk)) {
- const __u32 rcv_saddr = inet->rcv_saddr;
+ const __be32 rcv_saddr = inet->rcv_saddr;
int score = sk->sk_family == PF_INET ? 1 : 0;
if (rcv_saddr) {
@@ -163,7 +163,7 @@ static struct sock *inet_lookup_listener_slow(const struct hlist_head *head,
/* Optimize the common listener case. */
struct sock *__inet_lookup_listener(struct inet_hashinfo *hashinfo,
- const u32 daddr, const unsigned short hnum,
+ const __be32 daddr, const unsigned short hnum,
const int dif)
{
struct sock *sk = NULL;
@@ -197,11 +197,11 @@ static int __inet_check_established(struct inet_timewait_death_row *death_row,
{
struct inet_hashinfo *hinfo = death_row->hashinfo;
struct inet_sock *inet = inet_sk(sk);
- u32 daddr = inet->rcv_saddr;
- u32 saddr = inet->daddr;
+ __be32 daddr = inet->rcv_saddr;
+ __be32 saddr = inet->daddr;
int dif = sk->sk_bound_dev_if;
INET_ADDR_COOKIE(acookie, saddr, daddr)
- const __u32 ports = INET_COMBINED_PORTS(inet->dport, lport);
+ const __portpair ports = INET_COMBINED_PORTS(inet->dport, lport);
unsigned int hash = inet_ehashfn(daddr, lport, saddr, inet->dport);
struct inet_ehash_bucket *head = inet_ehash_bucket(hinfo, hash);
struct sock *sk2;
diff --git a/net/ipv4/inetpeer.c b/net/ipv4/inetpeer.c
index a675602ef295..2b1a54b59c48 100644
--- a/net/ipv4/inetpeer.c
+++ b/net/ipv4/inetpeer.c
@@ -163,7 +163,7 @@ static void unlink_from_unused(struct inet_peer *p)
for (u = peer_root; u != peer_avl_empty; ) { \
if (daddr == u->v4daddr) \
break; \
- if (daddr < u->v4daddr) \
+ if ((__force __u32)daddr < (__force __u32)u->v4daddr) \
v = &u->avl_left; \
else \
v = &u->avl_right; \
@@ -368,7 +368,7 @@ static int cleanup_once(unsigned long ttl)
}
/* Called with or without local BH being disabled. */
-struct inet_peer *inet_getpeer(__u32 daddr, int create)
+struct inet_peer *inet_getpeer(__be32 daddr, int create)
{
struct inet_peer *p, *n;
struct inet_peer **stack[PEER_MAXDEPTH], ***stackptr;
diff --git a/net/ipv4/ip_fragment.c b/net/ipv4/ip_fragment.c
index 165d72859ddf..74046efdf875 100644
--- a/net/ipv4/ip_fragment.c
+++ b/net/ipv4/ip_fragment.c
@@ -77,9 +77,9 @@ struct ipq {
struct hlist_node list;
struct list_head lru_list; /* lru list member */
u32 user;
- u32 saddr;
- u32 daddr;
- u16 id;
+ __be32 saddr;
+ __be32 daddr;
+ __be16 id;
u8 protocol;
u8 last_in;
#define COMPLETE 4
@@ -123,9 +123,10 @@ static __inline__ void ipq_unlink(struct ipq *ipq)
write_unlock(&ipfrag_lock);
}
-static unsigned int ipqhashfn(u16 id, u32 saddr, u32 daddr, u8 prot)
+static unsigned int ipqhashfn(__be16 id, __be32 saddr, __be32 daddr, u8 prot)
{
- return jhash_3words((u32)id << 16 | prot, saddr, daddr,
+ return jhash_3words((__force u32)id << 16 | prot,
+ (__force u32)saddr, (__force u32)daddr,
ipfrag_hash_rnd) & (IPQ_HASHSZ - 1);
}
@@ -387,8 +388,8 @@ out_nomem:
static inline struct ipq *ip_find(struct iphdr *iph, u32 user)
{
__be16 id = iph->id;
- __u32 saddr = iph->saddr;
- __u32 daddr = iph->daddr;
+ __be32 saddr = iph->saddr;
+ __be32 daddr = iph->daddr;
__u8 protocol = iph->protocol;
unsigned int hash;
struct ipq *qp;
diff --git a/net/ipv4/ip_options.c b/net/ipv4/ip_options.c
index e7437c091326..8dabbfc31267 100644
--- a/net/ipv4/ip_options.c
+++ b/net/ipv4/ip_options.c
@@ -38,7 +38,7 @@
*/
void ip_options_build(struct sk_buff * skb, struct ip_options * opt,
- u32 daddr, struct rtable *rt, int is_frag)
+ __be32 daddr, struct rtable *rt, int is_frag)
{
unsigned char * iph = skb->nh.raw;
@@ -57,7 +57,7 @@ void ip_options_build(struct sk_buff * skb, struct ip_options * opt,
ip_rt_get_source(iph+opt->ts+iph[opt->ts+2]-9, rt);
if (opt->ts_needtime) {
struct timeval tv;
- __u32 midtime;
+ __be32 midtime;
do_gettimeofday(&tv);
midtime = htonl((tv.tv_sec % 86400) * 1000 + tv.tv_usec / 1000);
memcpy(iph+opt->ts+iph[opt->ts+2]-5, &midtime, 4);
@@ -91,7 +91,7 @@ int ip_options_echo(struct ip_options * dopt, struct sk_buff * skb)
unsigned char *sptr, *dptr;
int soffset, doffset;
int optlen;
- u32 daddr;
+ __be32 daddr;
memset(dopt, 0, sizeof(struct ip_options));
@@ -148,7 +148,7 @@ int ip_options_echo(struct ip_options * dopt, struct sk_buff * skb)
dopt->ts_needtime = 0;
if (soffset + 8 <= optlen) {
- __u32 addr;
+ __be32 addr;
memcpy(&addr, sptr+soffset-1, 4);
if (inet_addr_type(addr) != RTN_LOCAL) {
@@ -165,7 +165,7 @@ int ip_options_echo(struct ip_options * dopt, struct sk_buff * skb)
}
if (sopt->srr) {
unsigned char * start = sptr+sopt->srr;
- u32 faddr;
+ __be32 faddr;
optlen = start[1];
soffset = start[2];
@@ -362,7 +362,7 @@ int ip_options_compile(struct ip_options * opt, struct sk_buff * skb)
goto error;
}
if (optptr[2] <= optlen) {
- __u32 * timeptr = NULL;
+ __be32 *timeptr = NULL;
if (optptr[2]+3 > optptr[1]) {
pp_ptr = optptr + 2;
goto error;
@@ -371,7 +371,7 @@ int ip_options_compile(struct ip_options * opt, struct sk_buff * skb)
case IPOPT_TS_TSONLY:
opt->ts = optptr - iph;
if (skb)
- timeptr = (__u32*)&optptr[optptr[2]-1];
+ timeptr = (__be32*)&optptr[optptr[2]-1];
opt->ts_needtime = 1;
optptr[2] += 4;
break;
@@ -383,7 +383,7 @@ int ip_options_compile(struct ip_options * opt, struct sk_buff * skb)
opt->ts = optptr - iph;
if (skb) {
memcpy(&optptr[optptr[2]-1], &rt->rt_spec_dst, 4);
- timeptr = (__u32*)&optptr[optptr[2]+3];
+ timeptr = (__be32*)&optptr[optptr[2]+3];
}
opt->ts_needaddr = 1;
opt->ts_needtime = 1;
@@ -396,12 +396,12 @@ int ip_options_compile(struct ip_options * opt, struct sk_buff * skb)
}
opt->ts = optptr - iph;
{
- u32 addr;
+ __be32 addr;
memcpy(&addr, &optptr[optptr[2]-1], 4);
if (inet_addr_type(addr) == RTN_UNICAST)
break;
if (skb)
- timeptr = (__u32*)&optptr[optptr[2]+3];
+ timeptr = (__be32*)&optptr[optptr[2]+3];
}
opt->ts_needtime = 1;
optptr[2] += 8;
@@ -415,10 +415,10 @@ int ip_options_compile(struct ip_options * opt, struct sk_buff * skb)
}
if (timeptr) {
struct timeval tv;
- __u32 midtime;
+ __be32 midtime;
do_gettimeofday(&tv);
midtime = htonl((tv.tv_sec % 86400) * 1000 + tv.tv_usec / 1000);
- memcpy(timeptr, &midtime, sizeof(__u32));
+ memcpy(timeptr, &midtime, sizeof(__be32));
opt->is_changed = 1;
}
} else {
@@ -607,7 +607,7 @@ int ip_options_rcv_srr(struct sk_buff *skb)
{
struct ip_options *opt = &(IPCB(skb)->opt);
int srrspace, srrptr;
- u32 nexthop;
+ __be32 nexthop;
struct iphdr *iph = skb->nh.iph;
unsigned char * optptr = skb->nh.raw + opt->srr;
struct rtable *rt = (struct rtable*)skb->dst;
diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c
index 97aee76fb746..fc195a44fc2e 100644
--- a/net/ipv4/ip_output.c
+++ b/net/ipv4/ip_output.c
@@ -118,7 +118,7 @@ static inline int ip_select_ttl(struct inet_sock *inet, struct dst_entry *dst)
*
*/
int ip_build_and_send_pkt(struct sk_buff *skb, struct sock *sk,
- u32 saddr, u32 daddr, struct ip_options *opt)
+ __be32 saddr, __be32 daddr, struct ip_options *opt)
{
struct inet_sock *inet = inet_sk(sk);
struct rtable *rt = (struct rtable *)skb->dst;
@@ -306,7 +306,7 @@ int ip_queue_xmit(struct sk_buff *skb, int ipfragok)
/* Make sure we can route this packet. */
rt = (struct rtable *)__sk_dst_check(sk, 0);
if (rt == NULL) {
- u32 daddr;
+ __be32 daddr;
/* Use correct destination address if we have options. */
daddr = inet->daddr;
@@ -1340,7 +1340,7 @@ void ip_send_reply(struct sock *sk, struct sk_buff *skb, struct ip_reply_arg *ar
char data[40];
} replyopts;
struct ipcm_cookie ipc;
- u32 daddr;
+ __be32 daddr;
struct rtable *rt = (struct rtable*)skb->dst;
if (ip_options_echo(&replyopts.opt, skb))
diff --git a/net/ipv4/ip_sockglue.c b/net/ipv4/ip_sockglue.c
index 2d05c4133d3e..4b132953bcc2 100644
--- a/net/ipv4/ip_sockglue.c
+++ b/net/ipv4/ip_sockglue.c
@@ -254,7 +254,7 @@ int ip_ra_control(struct sock *sk, unsigned char on, void (*destructor)(struct s
}
void ip_icmp_error(struct sock *sk, struct sk_buff *skb, int err,
- u16 port, u32 info, u8 *payload)
+ __be16 port, u32 info, u8 *payload)
{
struct inet_sock *inet = inet_sk(sk);
struct sock_exterr_skb *serr;
@@ -283,7 +283,7 @@ void ip_icmp_error(struct sock *sk, struct sk_buff *skb, int err,
kfree_skb(skb);
}
-void ip_local_error(struct sock *sk, int err, u32 daddr, u16 port, u32 info)
+void ip_local_error(struct sock *sk, int err, __be32 daddr, __be16 port, u32 info)
{
struct inet_sock *inet = inet_sk(sk);
struct sock_exterr_skb *serr;
diff --git a/net/ipv4/ipcomp.c b/net/ipv4/ipcomp.c
index 17342430a843..2017d36024d4 100644
--- a/net/ipv4/ipcomp.c
+++ b/net/ipv4/ipcomp.c
@@ -183,7 +183,7 @@ out_ok:
static void ipcomp4_err(struct sk_buff *skb, u32 info)
{
- u32 spi;
+ __be32 spi;
struct iphdr *iph = (struct iphdr *)skb->data;
struct ip_comp_hdr *ipch = (struct ip_comp_hdr *)(skb->data+(iph->ihl<<2));
struct xfrm_state *x;
diff --git a/net/ipv4/ipconfig.c b/net/ipv4/ipconfig.c
index 1fbb38415b19..f8ce84759159 100644
--- a/net/ipv4/ipconfig.c
+++ b/net/ipv4/ipconfig.c
@@ -366,7 +366,7 @@ static int __init ic_defaults(void)
*/
if (!ic_host_name_set)
- sprintf(system_utsname.nodename, "%u.%u.%u.%u", NIPQUAD(ic_myaddr));
+ sprintf(init_utsname()->nodename, "%u.%u.%u.%u", NIPQUAD(ic_myaddr));
if (root_server_addr == INADDR_NONE)
root_server_addr = ic_servaddr;
@@ -805,7 +805,7 @@ static void __init ic_do_bootp_ext(u8 *ext)
}
break;
case 12: /* Host name */
- ic_bootp_string(system_utsname.nodename, ext+1, *ext, __NEW_UTS_LEN);
+ ic_bootp_string(utsname()->nodename, ext+1, *ext, __NEW_UTS_LEN);
ic_host_name_set = 1;
break;
case 15: /* Domain name (DNS) */
@@ -816,7 +816,7 @@ static void __init ic_do_bootp_ext(u8 *ext)
ic_bootp_string(root_server_path, ext+1, *ext, sizeof(root_server_path));
break;
case 40: /* NIS Domain name (_not_ DNS) */
- ic_bootp_string(system_utsname.domainname, ext+1, *ext, __NEW_UTS_LEN);
+ ic_bootp_string(utsname()->domainname, ext+1, *ext, __NEW_UTS_LEN);
break;
}
}
@@ -1368,7 +1368,7 @@ static int __init ip_auto_config(void)
printk(", mask=%u.%u.%u.%u", NIPQUAD(ic_netmask));
printk(", gw=%u.%u.%u.%u", NIPQUAD(ic_gateway));
printk(",\n host=%s, domain=%s, nis-domain=%s",
- system_utsname.nodename, ic_domain, system_utsname.domainname);
+ utsname()->nodename, ic_domain, utsname()->domainname);
printk(",\n bootserver=%u.%u.%u.%u", NIPQUAD(ic_servaddr));
printk(", rootserver=%u.%u.%u.%u", NIPQUAD(root_server_addr));
printk(", rootpath=%s", root_server_path);
@@ -1478,11 +1478,11 @@ static int __init ip_auto_config_setup(char *addrs)
case 4:
if ((dp = strchr(ip, '.'))) {
*dp++ = '\0';
- strlcpy(system_utsname.domainname, dp,
- sizeof(system_utsname.domainname));
+ strlcpy(utsname()->domainname, dp,
+ sizeof(utsname()->domainname));
}
- strlcpy(system_utsname.nodename, ip,
- sizeof(system_utsname.nodename));
+ strlcpy(utsname()->nodename, ip,
+ sizeof(utsname()->nodename));
ic_host_name_set = 1;
break;
case 5:
diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c
index ba49588da242..97cfa97c8abb 100644
--- a/net/ipv4/ipmr.c
+++ b/net/ipv4/ipmr.c
@@ -462,7 +462,7 @@ static int vif_add(struct vifctl *vifc, int mrtsock)
return 0;
}
-static struct mfc_cache *ipmr_cache_find(__u32 origin, __u32 mcastgrp)
+static struct mfc_cache *ipmr_cache_find(__be32 origin, __be32 mcastgrp)
{
int line=MFC_HASH(mcastgrp,origin);
struct mfc_cache *c;
@@ -1097,7 +1097,7 @@ static struct notifier_block ip_mr_notifier={
* important for multicast video.
*/
-static void ip_encap(struct sk_buff *skb, u32 saddr, u32 daddr)
+static void ip_encap(struct sk_buff *skb, __be32 saddr, __be32 daddr)
{
struct iphdr *iph = (struct iphdr *)skb_push(skb,sizeof(struct iphdr));
diff --git a/net/ipv4/ipvs/ip_vs_conn.c b/net/ipv4/ipvs/ip_vs_conn.c
index 87b83813cf2c..8832eb517d52 100644
--- a/net/ipv4/ipvs/ip_vs_conn.c
+++ b/net/ipv4/ipvs/ip_vs_conn.c
@@ -115,9 +115,9 @@ static inline void ct_write_unlock_bh(unsigned key)
/*
* Returns hash value for IPVS connection entry
*/
-static unsigned int ip_vs_conn_hashkey(unsigned proto, __u32 addr, __u16 port)
+static unsigned int ip_vs_conn_hashkey(unsigned proto, __be32 addr, __be16 port)
{
- return jhash_3words(addr, port, proto, ip_vs_conn_rnd)
+ return jhash_3words((__force u32)addr, (__force u32)port, proto, ip_vs_conn_rnd)
& IP_VS_CONN_TAB_MASK;
}
@@ -188,7 +188,7 @@ static inline int ip_vs_conn_unhash(struct ip_vs_conn *cp)
* d_addr, d_port: pkt dest address (load balancer)
*/
static inline struct ip_vs_conn *__ip_vs_conn_in_get
-(int protocol, __u32 s_addr, __u16 s_port, __u32 d_addr, __u16 d_port)
+(int protocol, __be32 s_addr, __be16 s_port, __be32 d_addr, __be16 d_port)
{
unsigned hash;
struct ip_vs_conn *cp;
@@ -215,7 +215,7 @@ static inline struct ip_vs_conn *__ip_vs_conn_in_get
}
struct ip_vs_conn *ip_vs_conn_in_get
-(int protocol, __u32 s_addr, __u16 s_port, __u32 d_addr, __u16 d_port)
+(int protocol, __be32 s_addr, __be16 s_port, __be32 d_addr, __be16 d_port)
{
struct ip_vs_conn *cp;
@@ -234,7 +234,7 @@ struct ip_vs_conn *ip_vs_conn_in_get
/* Get reference to connection template */
struct ip_vs_conn *ip_vs_ct_in_get
-(int protocol, __u32 s_addr, __u16 s_port, __u32 d_addr, __u16 d_port)
+(int protocol, __be32 s_addr, __be16 s_port, __be32 d_addr, __be16 d_port)
{
unsigned hash;
struct ip_vs_conn *cp;
@@ -274,7 +274,7 @@ struct ip_vs_conn *ip_vs_ct_in_get
* d_addr, d_port: pkt dest address (foreign host)
*/
struct ip_vs_conn *ip_vs_conn_out_get
-(int protocol, __u32 s_addr, __u16 s_port, __u32 d_addr, __u16 d_port)
+(int protocol, __be32 s_addr, __be16 s_port, __be32 d_addr, __be16 d_port)
{
unsigned hash;
struct ip_vs_conn *cp, *ret=NULL;
@@ -324,7 +324,7 @@ void ip_vs_conn_put(struct ip_vs_conn *cp)
/*
* Fill a no_client_port connection with a client port number
*/
-void ip_vs_conn_fill_cport(struct ip_vs_conn *cp, __u16 cport)
+void ip_vs_conn_fill_cport(struct ip_vs_conn *cp, __be16 cport)
{
if (ip_vs_conn_unhash(cp)) {
spin_lock(&cp->lock);
@@ -508,10 +508,10 @@ int ip_vs_check_template(struct ip_vs_conn *ct)
/*
* Invalidate the connection template
*/
- if (ct->vport != 65535) {
+ if (ct->vport != htons(0xffff)) {
if (ip_vs_conn_unhash(ct)) {
- ct->dport = 65535;
- ct->vport = 65535;
+ ct->dport = htons(0xffff);
+ ct->vport = htons(0xffff);
ct->cport = 0;
ip_vs_conn_hash(ct);
}
@@ -596,8 +596,8 @@ void ip_vs_conn_expire_now(struct ip_vs_conn *cp)
* Create a new connection entry and hash it into the ip_vs_conn_tab
*/
struct ip_vs_conn *
-ip_vs_conn_new(int proto, __u32 caddr, __u16 cport, __u32 vaddr, __u16 vport,
- __u32 daddr, __u16 dport, unsigned flags,
+ip_vs_conn_new(int proto, __be32 caddr, __be16 cport, __be32 vaddr, __be16 vport,
+ __be32 daddr, __be16 dport, unsigned flags,
struct ip_vs_dest *dest)
{
struct ip_vs_conn *cp;
diff --git a/net/ipv4/ipvs/ip_vs_core.c b/net/ipv4/ipvs/ip_vs_core.c
index 3f47ad8e1cad..6dee03935f78 100644
--- a/net/ipv4/ipvs/ip_vs_core.c
+++ b/net/ipv4/ipvs/ip_vs_core.c
@@ -209,14 +209,14 @@ int ip_vs_make_skb_writable(struct sk_buff **pskb, int writable_len)
static struct ip_vs_conn *
ip_vs_sched_persist(struct ip_vs_service *svc,
const struct sk_buff *skb,
- __u16 ports[2])
+ __be16 ports[2])
{
struct ip_vs_conn *cp = NULL;
struct iphdr *iph = skb->nh.iph;
struct ip_vs_dest *dest;
struct ip_vs_conn *ct;
- __u16 dport; /* destination port to forward */
- __u32 snet; /* source network of the client, after masking */
+ __be16 dport; /* destination port to forward */
+ __be32 snet; /* source network of the client, after masking */
/* Mask saddr with the netmask to adjust template granularity */
snet = iph->saddr & svc->netmask;
@@ -383,7 +383,7 @@ ip_vs_schedule(struct ip_vs_service *svc, const struct sk_buff *skb)
struct ip_vs_conn *cp = NULL;
struct iphdr *iph = skb->nh.iph;
struct ip_vs_dest *dest;
- __u16 _ports[2], *pptr;
+ __be16 _ports[2], *pptr;
pptr = skb_header_pointer(skb, iph->ihl*4,
sizeof(_ports), _ports);
@@ -446,7 +446,7 @@ ip_vs_schedule(struct ip_vs_service *svc, const struct sk_buff *skb)
int ip_vs_leave(struct ip_vs_service *svc, struct sk_buff *skb,
struct ip_vs_protocol *pp)
{
- __u16 _ports[2], *pptr;
+ __be16 _ports[2], *pptr;
struct iphdr *iph = skb->nh.iph;
pptr = skb_header_pointer(skb, iph->ihl*4,
@@ -576,7 +576,7 @@ void ip_vs_nat_icmp(struct sk_buff *skb, struct ip_vs_protocol *pp,
/* the TCP/UDP port */
if (IPPROTO_TCP == ciph->protocol || IPPROTO_UDP == ciph->protocol) {
- __u16 *ports = (void *)ciph + ciph->ihl*4;
+ __be16 *ports = (void *)ciph + ciph->ihl*4;
if (inout)
ports[1] = cp->vport;
@@ -775,7 +775,7 @@ ip_vs_out(unsigned int hooknum, struct sk_buff **pskb,
if (sysctl_ip_vs_nat_icmp_send &&
(pp->protocol == IPPROTO_TCP ||
pp->protocol == IPPROTO_UDP)) {
- __u16 _ports[2], *pptr;
+ __be16 _ports[2], *pptr;
pptr = skb_header_pointer(skb, ihl,
sizeof(_ports), _ports);
diff --git a/net/ipv4/ipvs/ip_vs_ctl.c b/net/ipv4/ipvs/ip_vs_ctl.c
index 6a28fafe910c..f261616e4602 100644
--- a/net/ipv4/ipvs/ip_vs_ctl.c
+++ b/net/ipv4/ipvs/ip_vs_ctl.c
@@ -283,7 +283,7 @@ static atomic_t ip_vs_nullsvc_counter = ATOMIC_INIT(0);
* Returns hash value for virtual service
*/
static __inline__ unsigned
-ip_vs_svc_hashkey(unsigned proto, __u32 addr, __u16 port)
+ip_vs_svc_hashkey(unsigned proto, __be32 addr, __be16 port)
{
register unsigned porth = ntohs(port);
@@ -365,7 +365,7 @@ static int ip_vs_svc_unhash(struct ip_vs_service *svc)
* Get service by {proto,addr,port} in the service table.
*/
static __inline__ struct ip_vs_service *
-__ip_vs_service_get(__u16 protocol, __u32 vaddr, __u16 vport)
+__ip_vs_service_get(__u16 protocol, __be32 vaddr, __be16 vport)
{
unsigned hash;
struct ip_vs_service *svc;
@@ -410,7 +410,7 @@ static __inline__ struct ip_vs_service *__ip_vs_svc_fwm_get(__u32 fwmark)
}
struct ip_vs_service *
-ip_vs_service_get(__u32 fwmark, __u16 protocol, __u32 vaddr, __u16 vport)
+ip_vs_service_get(__u32 fwmark, __u16 protocol, __be32 vaddr, __be16 vport)
{
struct ip_vs_service *svc;
@@ -480,7 +480,7 @@ __ip_vs_unbind_svc(struct ip_vs_dest *dest)
/*
* Returns hash value for real service
*/
-static __inline__ unsigned ip_vs_rs_hashkey(__u32 addr, __u16 port)
+static __inline__ unsigned ip_vs_rs_hashkey(__be32 addr, __be16 port)
{
register unsigned porth = ntohs(port);
@@ -531,7 +531,7 @@ static int ip_vs_rs_unhash(struct ip_vs_dest *dest)
* Lookup real service by <proto,addr,port> in the real service table.
*/
struct ip_vs_dest *
-ip_vs_lookup_real_service(__u16 protocol, __u32 daddr, __u16 dport)
+ip_vs_lookup_real_service(__u16 protocol, __be32 daddr, __be16 dport)
{
unsigned hash;
struct ip_vs_dest *dest;
@@ -562,7 +562,7 @@ ip_vs_lookup_real_service(__u16 protocol, __u32 daddr, __u16 dport)
* Lookup destination by {addr,port} in the given service
*/
static struct ip_vs_dest *
-ip_vs_lookup_dest(struct ip_vs_service *svc, __u32 daddr, __u16 dport)
+ip_vs_lookup_dest(struct ip_vs_service *svc, __be32 daddr, __be16 dport)
{
struct ip_vs_dest *dest;
@@ -591,7 +591,7 @@ ip_vs_lookup_dest(struct ip_vs_service *svc, __u32 daddr, __u16 dport)
* scheduling.
*/
static struct ip_vs_dest *
-ip_vs_trash_get_dest(struct ip_vs_service *svc, __u32 daddr, __u16 dport)
+ip_vs_trash_get_dest(struct ip_vs_service *svc, __be32 daddr, __be16 dport)
{
struct ip_vs_dest *dest, *nxt;
@@ -773,8 +773,8 @@ static int
ip_vs_add_dest(struct ip_vs_service *svc, struct ip_vs_dest_user *udest)
{
struct ip_vs_dest *dest;
- __u32 daddr = udest->addr;
- __u16 dport = udest->port;
+ __be32 daddr = udest->addr;
+ __be16 dport = udest->port;
int ret;
EnterFunction(2);
@@ -879,8 +879,8 @@ static int
ip_vs_edit_dest(struct ip_vs_service *svc, struct ip_vs_dest_user *udest)
{
struct ip_vs_dest *dest;
- __u32 daddr = udest->addr;
- __u16 dport = udest->port;
+ __be32 daddr = udest->addr;
+ __be16 dport = udest->port;
EnterFunction(2);
@@ -991,8 +991,8 @@ static int
ip_vs_del_dest(struct ip_vs_service *svc,struct ip_vs_dest_user *udest)
{
struct ip_vs_dest *dest;
- __u32 daddr = udest->addr;
- __u16 dport = udest->port;
+ __be32 daddr = udest->addr;
+ __be16 dport = udest->port;
EnterFunction(2);
diff --git a/net/ipv4/ipvs/ip_vs_dh.c b/net/ipv4/ipvs/ip_vs_dh.c
index 9fee19c4c617..502111fba872 100644
--- a/net/ipv4/ipvs/ip_vs_dh.c
+++ b/net/ipv4/ipvs/ip_vs_dh.c
@@ -66,7 +66,7 @@ struct ip_vs_dh_bucket {
/*
* Returns hash value for IPVS DH entry
*/
-static inline unsigned ip_vs_dh_hashkey(__u32 addr)
+static inline unsigned ip_vs_dh_hashkey(__be32 addr)
{
return (ntohl(addr)*2654435761UL) & IP_VS_DH_TAB_MASK;
}
@@ -76,7 +76,7 @@ static inline unsigned ip_vs_dh_hashkey(__u32 addr)
* Get ip_vs_dest associated with supplied parameters.
*/
static inline struct ip_vs_dest *
-ip_vs_dh_get(struct ip_vs_dh_bucket *tbl, __u32 addr)
+ip_vs_dh_get(struct ip_vs_dh_bucket *tbl, __be32 addr)
{
return (tbl[ip_vs_dh_hashkey(addr)]).dest;
}
diff --git a/net/ipv4/ipvs/ip_vs_ftp.c b/net/ipv4/ipvs/ip_vs_ftp.c
index 37fafb1fbcff..e433cb0ff894 100644
--- a/net/ipv4/ipvs/ip_vs_ftp.c
+++ b/net/ipv4/ipvs/ip_vs_ftp.c
@@ -32,6 +32,7 @@
#include <linux/ip.h>
#include <net/protocol.h>
#include <net/tcp.h>
+#include <asm/unaligned.h>
#include <net/ip_vs.h>
@@ -44,8 +45,8 @@
* List of ports (up to IP_VS_APP_MAX_PORTS) to be handled by helper
* First port is set to the default port.
*/
-static int ports[IP_VS_APP_MAX_PORTS] = {21, 0};
-module_param_array(ports, int, NULL, 0);
+static unsigned short ports[IP_VS_APP_MAX_PORTS] = {21, 0};
+module_param_array(ports, ushort, NULL, 0);
MODULE_PARM_DESC(ports, "Ports to monitor for FTP control commands");
@@ -74,7 +75,7 @@ ip_vs_ftp_done_conn(struct ip_vs_app *app, struct ip_vs_conn *cp)
*/
static int ip_vs_ftp_get_addrport(char *data, char *data_limit,
const char *pattern, size_t plen, char term,
- __u32 *addr, __u16 *port,
+ __be32 *addr, __be16 *port,
char **start, char **end)
{
unsigned char p[6];
@@ -114,8 +115,8 @@ static int ip_vs_ftp_get_addrport(char *data, char *data_limit,
if (i != 5)
return -1;
- *addr = (p[3]<<24) | (p[2]<<16) | (p[1]<<8) | p[0];
- *port = (p[5]<<8) | p[4];
+ *addr = get_unaligned((__be32 *)p);
+ *port = get_unaligned((__be16 *)(p + 4));
return 1;
}
@@ -140,8 +141,8 @@ static int ip_vs_ftp_out(struct ip_vs_app *app, struct ip_vs_conn *cp,
struct tcphdr *th;
char *data, *data_limit;
char *start, *end;
- __u32 from;
- __u16 port;
+ __be32 from;
+ __be16 port;
struct ip_vs_conn *n_cp;
char buf[24]; /* xxx.xxx.xxx.xxx,ppp,ppp\000 */
unsigned buf_len;
@@ -199,7 +200,7 @@ static int ip_vs_ftp_out(struct ip_vs_app *app, struct ip_vs_conn *cp,
from = n_cp->vaddr;
port = n_cp->vport;
sprintf(buf,"%d,%d,%d,%d,%d,%d", NIPQUAD(from),
- port&255, (port>>8)&255);
+ ntohs(port)&255, (ntohs(port)>>8)&255);
buf_len = strlen(buf);
/*
@@ -243,8 +244,8 @@ static int ip_vs_ftp_in(struct ip_vs_app *app, struct ip_vs_conn *cp,
struct tcphdr *th;
char *data, *data_start, *data_limit;
char *start, *end;
- __u32 to;
- __u16 port;
+ __be32 to;
+ __be16 port;
struct ip_vs_conn *n_cp;
/* no diff required for incoming packets */
@@ -365,12 +366,6 @@ static int __init ip_vs_ftp_init(void)
for (i=0; i<IP_VS_APP_MAX_PORTS; i++) {
if (!ports[i])
continue;
- if (ports[i] < 0 || ports[i] > 0xffff) {
- IP_VS_WARNING("ip_vs_ftp: Ignoring invalid "
- "configuration port[%d] = %d\n",
- i, ports[i]);
- continue;
- }
ret = register_ip_vs_app_inc(app, app->protocol, ports[i]);
if (ret)
break;
diff --git a/net/ipv4/ipvs/ip_vs_lblc.c b/net/ipv4/ipvs/ip_vs_lblc.c
index 6e5cb92a5c83..524751e031de 100644
--- a/net/ipv4/ipvs/ip_vs_lblc.c
+++ b/net/ipv4/ipvs/ip_vs_lblc.c
@@ -87,7 +87,7 @@ static int sysctl_ip_vs_lblc_expiration = 24*60*60*HZ;
*/
struct ip_vs_lblc_entry {
struct list_head list;
- __u32 addr; /* destination IP address */
+ __be32 addr; /* destination IP address */
struct ip_vs_dest *dest; /* real server (cache) */
unsigned long lastuse; /* last used time */
};
@@ -160,7 +160,7 @@ static struct ctl_table_header * sysctl_header;
* IP address to a server.
*/
static inline struct ip_vs_lblc_entry *
-ip_vs_lblc_new(__u32 daddr, struct ip_vs_dest *dest)
+ip_vs_lblc_new(__be32 daddr, struct ip_vs_dest *dest)
{
struct ip_vs_lblc_entry *en;
@@ -195,7 +195,7 @@ static inline void ip_vs_lblc_free(struct ip_vs_lblc_entry *en)
/*
* Returns hash value for IPVS LBLC entry
*/
-static inline unsigned ip_vs_lblc_hashkey(__u32 addr)
+static inline unsigned ip_vs_lblc_hashkey(__be32 addr)
{
return (ntohl(addr)*2654435761UL) & IP_VS_LBLC_TAB_MASK;
}
@@ -234,7 +234,7 @@ ip_vs_lblc_hash(struct ip_vs_lblc_table *tbl, struct ip_vs_lblc_entry *en)
* Get ip_vs_lblc_entry associated with supplied parameters.
*/
static inline struct ip_vs_lblc_entry *
-ip_vs_lblc_get(struct ip_vs_lblc_table *tbl, __u32 addr)
+ip_vs_lblc_get(struct ip_vs_lblc_table *tbl, __be32 addr)
{
unsigned hash;
struct ip_vs_lblc_entry *en;
diff --git a/net/ipv4/ipvs/ip_vs_lblcr.c b/net/ipv4/ipvs/ip_vs_lblcr.c
index 32ba37ba72d8..08990192b6ec 100644
--- a/net/ipv4/ipvs/ip_vs_lblcr.c
+++ b/net/ipv4/ipvs/ip_vs_lblcr.c
@@ -276,7 +276,7 @@ static inline struct ip_vs_dest *ip_vs_dest_set_max(struct ip_vs_dest_set *set)
*/
struct ip_vs_lblcr_entry {
struct list_head list;
- __u32 addr; /* destination IP address */
+ __be32 addr; /* destination IP address */
struct ip_vs_dest_set set; /* destination server set */
unsigned long lastuse; /* last used time */
};
@@ -348,7 +348,7 @@ static struct ctl_table_header * sysctl_header;
* new/free a ip_vs_lblcr_entry, which is a mapping of a destination
* IP address to a server.
*/
-static inline struct ip_vs_lblcr_entry *ip_vs_lblcr_new(__u32 daddr)
+static inline struct ip_vs_lblcr_entry *ip_vs_lblcr_new(__be32 daddr)
{
struct ip_vs_lblcr_entry *en;
@@ -381,7 +381,7 @@ static inline void ip_vs_lblcr_free(struct ip_vs_lblcr_entry *en)
/*
* Returns hash value for IPVS LBLCR entry
*/
-static inline unsigned ip_vs_lblcr_hashkey(__u32 addr)
+static inline unsigned ip_vs_lblcr_hashkey(__be32 addr)
{
return (ntohl(addr)*2654435761UL) & IP_VS_LBLCR_TAB_MASK;
}
@@ -420,7 +420,7 @@ ip_vs_lblcr_hash(struct ip_vs_lblcr_table *tbl, struct ip_vs_lblcr_entry *en)
* Get ip_vs_lblcr_entry associated with supplied parameters.
*/
static inline struct ip_vs_lblcr_entry *
-ip_vs_lblcr_get(struct ip_vs_lblcr_table *tbl, __u32 addr)
+ip_vs_lblcr_get(struct ip_vs_lblcr_table *tbl, __be32 addr)
{
unsigned hash;
struct ip_vs_lblcr_entry *en;
diff --git a/net/ipv4/ipvs/ip_vs_proto.c b/net/ipv4/ipvs/ip_vs_proto.c
index 867d4e9c6594..c4528b5c800d 100644
--- a/net/ipv4/ipvs/ip_vs_proto.c
+++ b/net/ipv4/ipvs/ip_vs_proto.c
@@ -176,7 +176,7 @@ ip_vs_tcpudp_debug_packet(struct ip_vs_protocol *pp,
pp->name, NIPQUAD(ih->saddr),
NIPQUAD(ih->daddr));
else {
- __u16 _ports[2], *pptr
+ __be16 _ports[2], *pptr
;
pptr = skb_header_pointer(skb, offset + ih->ihl*4,
sizeof(_ports), _ports);
diff --git a/net/ipv4/ipvs/ip_vs_proto_tcp.c b/net/ipv4/ipvs/ip_vs_proto_tcp.c
index 820e8318d10d..bfe779e74590 100644
--- a/net/ipv4/ipvs/ip_vs_proto_tcp.c
+++ b/net/ipv4/ipvs/ip_vs_proto_tcp.c
@@ -29,7 +29,7 @@ static struct ip_vs_conn *
tcp_conn_in_get(const struct sk_buff *skb, struct ip_vs_protocol *pp,
const struct iphdr *iph, unsigned int proto_off, int inverse)
{
- __u16 _ports[2], *pptr;
+ __be16 _ports[2], *pptr;
pptr = skb_header_pointer(skb, proto_off, sizeof(_ports), _ports);
if (pptr == NULL)
@@ -50,7 +50,7 @@ static struct ip_vs_conn *
tcp_conn_out_get(const struct sk_buff *skb, struct ip_vs_protocol *pp,
const struct iphdr *iph, unsigned int proto_off, int inverse)
{
- __u16 _ports[2], *pptr;
+ __be16 _ports[2], *pptr;
pptr = skb_header_pointer(skb, proto_off, sizeof(_ports), _ports);
if (pptr == NULL)
@@ -112,12 +112,12 @@ tcp_conn_schedule(struct sk_buff *skb,
static inline void
-tcp_fast_csum_update(struct tcphdr *tcph, u32 oldip, u32 newip,
- u16 oldport, u16 newport)
+tcp_fast_csum_update(struct tcphdr *tcph, __be32 oldip, __be32 newip,
+ __be16 oldport, __be16 newport)
{
tcph->check =
ip_vs_check_diff(~oldip, newip,
- ip_vs_check_diff(oldport ^ 0xFFFF,
+ ip_vs_check_diff(oldport ^ htonl(0xFFFF),
newport, tcph->check));
}
diff --git a/net/ipv4/ipvs/ip_vs_proto_udp.c b/net/ipv4/ipvs/ip_vs_proto_udp.c
index 90c8166c0ec1..54aa7603591f 100644
--- a/net/ipv4/ipvs/ip_vs_proto_udp.c
+++ b/net/ipv4/ipvs/ip_vs_proto_udp.c
@@ -29,7 +29,7 @@ udp_conn_in_get(const struct sk_buff *skb, struct ip_vs_protocol *pp,
const struct iphdr *iph, unsigned int proto_off, int inverse)
{
struct ip_vs_conn *cp;
- __u16 _ports[2], *pptr;
+ __be16 _ports[2], *pptr;
pptr = skb_header_pointer(skb, proto_off, sizeof(_ports), _ports);
if (pptr == NULL)
@@ -54,7 +54,7 @@ udp_conn_out_get(const struct sk_buff *skb, struct ip_vs_protocol *pp,
const struct iphdr *iph, unsigned int proto_off, int inverse)
{
struct ip_vs_conn *cp;
- __u16 _ports[2], *pptr;
+ __be16 _ports[2], *pptr;
pptr = skb_header_pointer(skb, skb->nh.iph->ihl*4,
sizeof(_ports), _ports);
@@ -117,15 +117,15 @@ udp_conn_schedule(struct sk_buff *skb, struct ip_vs_protocol *pp,
static inline void
-udp_fast_csum_update(struct udphdr *uhdr, u32 oldip, u32 newip,
- u16 oldport, u16 newport)
+udp_fast_csum_update(struct udphdr *uhdr, __be32 oldip, __be32 newip,
+ __be16 oldport, __be16 newport)
{
uhdr->check =
ip_vs_check_diff(~oldip, newip,
- ip_vs_check_diff(oldport ^ 0xFFFF,
+ ip_vs_check_diff(oldport ^ htonl(0xFFFF),
newport, uhdr->check));
if (!uhdr->check)
- uhdr->check = 0xFFFF;
+ uhdr->check = htonl(0xFFFF);
}
static int
@@ -173,7 +173,7 @@ udp_snat_handler(struct sk_buff **pskb,
cp->protocol,
(*pskb)->csum);
if (udph->check == 0)
- udph->check = 0xFFFF;
+ udph->check = htonl(0xFFFF);
IP_VS_DBG(11, "O-pkt: %s O-csum=%d (+%zd)\n",
pp->name, udph->check,
(char*)&(udph->check) - (char*)udph);
diff --git a/net/ipv4/ipvs/ip_vs_sh.c b/net/ipv4/ipvs/ip_vs_sh.c
index 7775e6cc68be..338668f88fe2 100644
--- a/net/ipv4/ipvs/ip_vs_sh.c
+++ b/net/ipv4/ipvs/ip_vs_sh.c
@@ -63,7 +63,7 @@ struct ip_vs_sh_bucket {
/*
* Returns hash value for IPVS SH entry
*/
-static inline unsigned ip_vs_sh_hashkey(__u32 addr)
+static inline unsigned ip_vs_sh_hashkey(__be32 addr)
{
return (ntohl(addr)*2654435761UL) & IP_VS_SH_TAB_MASK;
}
@@ -73,7 +73,7 @@ static inline unsigned ip_vs_sh_hashkey(__u32 addr)
* Get ip_vs_dest associated with supplied parameters.
*/
static inline struct ip_vs_dest *
-ip_vs_sh_get(struct ip_vs_sh_bucket *tbl, __u32 addr)
+ip_vs_sh_get(struct ip_vs_sh_bucket *tbl, __be32 addr)
{
return (tbl[ip_vs_sh_hashkey(addr)]).dest;
}
diff --git a/net/ipv4/ipvs/ip_vs_sync.c b/net/ipv4/ipvs/ip_vs_sync.c
index 1bca714bda3d..91a075edd68e 100644
--- a/net/ipv4/ipvs/ip_vs_sync.c
+++ b/net/ipv4/ipvs/ip_vs_sync.c
@@ -48,16 +48,16 @@ struct ip_vs_sync_conn {
/* Protocol, addresses and port numbers */
__u8 protocol; /* Which protocol (TCP/UDP) */
- __u16 cport;
- __u16 vport;
- __u16 dport;
- __u32 caddr; /* client address */
- __u32 vaddr; /* virtual address */
- __u32 daddr; /* destination address */
+ __be16 cport;
+ __be16 vport;
+ __be16 dport;
+ __be32 caddr; /* client address */
+ __be32 vaddr; /* virtual address */
+ __be32 daddr; /* destination address */
/* Flags and state transition */
- __u16 flags; /* status flags */
- __u16 state; /* state info */
+ __be16 flags; /* status flags */
+ __be16 state; /* state info */
/* The sequence options start here */
};
@@ -464,7 +464,7 @@ join_mcast_group(struct sock *sk, struct in_addr *addr, char *ifname)
static int bind_mcastif_addr(struct socket *sock, char *ifname)
{
struct net_device *dev;
- u32 addr;
+ __be32 addr;
struct sockaddr_in sin;
if ((dev = __dev_get_by_name(ifname)) == NULL)
@@ -836,7 +836,7 @@ static int fork_sync_thread(void *startup)
int start_sync_thread(int state, char *mcast_ifn, __u8 syncid)
{
- DECLARE_COMPLETION(startup);
+ DECLARE_COMPLETION_ONSTACK(startup);
pid_t pid;
if ((state == IP_VS_STATE_MASTER && sync_master_pid) ||
diff --git a/net/ipv4/ipvs/ip_vs_xmit.c b/net/ipv4/ipvs/ip_vs_xmit.c
index 52c12e9edbbc..e1f77bd7c9a5 100644
--- a/net/ipv4/ipvs/ip_vs_xmit.c
+++ b/net/ipv4/ipvs/ip_vs_xmit.c
@@ -232,7 +232,7 @@ ip_vs_nat_xmit(struct sk_buff *skb, struct ip_vs_conn *cp,
/* check if it is a connection of no-client-port */
if (unlikely(cp->flags & IP_VS_CONN_F_NO_CPORT)) {
- __u16 _pt, *p;
+ __be16 _pt, *p;
p = skb_header_pointer(skb, iph->ihl*4, sizeof(_pt), &_pt);
if (p == NULL)
goto tx_error;
diff --git a/net/ipv4/multipath_wrandom.c b/net/ipv4/multipath_wrandom.c
index d25ec4ae09e5..92b04823e034 100644
--- a/net/ipv4/multipath_wrandom.c
+++ b/net/ipv4/multipath_wrandom.c
@@ -60,8 +60,8 @@ struct multipath_dest {
struct list_head list;
const struct fib_nh *nh_info;
- __u32 netmask;
- __u32 network;
+ __be32 netmask;
+ __be32 network;
unsigned char prefixlen;
struct rcu_head rcu;
@@ -76,7 +76,7 @@ struct multipath_route {
struct list_head list;
int oif;
- __u32 gw;
+ __be32 gw;
struct list_head dests;
struct rcu_head rcu;
@@ -128,8 +128,8 @@ static unsigned char __multipath_lookup_weight(const struct flowi *fl,
/* find state entry for destination */
list_for_each_entry_rcu(d, &target_route->dests, list) {
- __u32 targetnetwork = fl->fl4_dst &
- (0xFFFFFFFF >> (32 - d->prefixlen));
+ __be32 targetnetwork = fl->fl4_dst &
+ inet_make_mask(d->prefixlen);
if ((targetnetwork & d->netmask) == d->network) {
weight = d->nh_info->nh_weight;
@@ -217,8 +217,8 @@ static void wrandom_select_route(const struct flowi *flp,
*rp = decision;
}
-static void wrandom_set_nhinfo(__u32 network,
- __u32 netmask,
+static void wrandom_set_nhinfo(__be32 network,
+ __be32 netmask,
unsigned char prefixlen,
const struct fib_nh *nh)
{
diff --git a/net/ipv4/netfilter.c b/net/ipv4/netfilter.c
index f88347de21a9..5ac15379a0cf 100644
--- a/net/ipv4/netfilter.c
+++ b/net/ipv4/netfilter.c
@@ -128,8 +128,8 @@ EXPORT_SYMBOL(ip_nat_decode_session);
*/
struct ip_rt_info {
- u_int32_t daddr;
- u_int32_t saddr;
+ __be32 daddr;
+ __be32 saddr;
u_int8_t tos;
};
diff --git a/net/ipv4/netfilter/arp_tables.c b/net/ipv4/netfilter/arp_tables.c
index 85f0d73ebfb4..17e1a687ab45 100644
--- a/net/ipv4/netfilter/arp_tables.c
+++ b/net/ipv4/netfilter/arp_tables.c
@@ -80,7 +80,7 @@ static inline int arp_packet_match(const struct arphdr *arphdr,
{
char *arpptr = (char *)(arphdr + 1);
char *src_devaddr, *tgt_devaddr;
- u32 src_ipaddr, tgt_ipaddr;
+ __be32 src_ipaddr, tgt_ipaddr;
int i, ret;
#define FWINV(bool,invflg) ((bool) ^ !!(arpinfo->invflags & invflg))
diff --git a/net/ipv4/netfilter/ip_conntrack_amanda.c b/net/ipv4/netfilter/ip_conntrack_amanda.c
index 0a7bd7f04061..6c7383a8e42b 100644
--- a/net/ipv4/netfilter/ip_conntrack_amanda.c
+++ b/net/ipv4/netfilter/ip_conntrack_amanda.c
@@ -155,11 +155,11 @@ static int help(struct sk_buff **pskb,
exp->tuple.dst.protonum = IPPROTO_TCP;
exp->tuple.dst.u.tcp.port = htons(port);
- exp->mask.src.ip = 0xFFFFFFFF;
+ exp->mask.src.ip = htonl(0xFFFFFFFF);
exp->mask.src.u.tcp.port = 0;
- exp->mask.dst.ip = 0xFFFFFFFF;
+ exp->mask.dst.ip = htonl(0xFFFFFFFF);
exp->mask.dst.protonum = 0xFF;
- exp->mask.dst.u.tcp.port = 0xFFFF;
+ exp->mask.dst.u.tcp.port = htons(0xFFFF);
if (ip_nat_amanda_hook)
ret = ip_nat_amanda_hook(pskb, ctinfo, off - dataoff,
diff --git a/net/ipv4/netfilter/ip_conntrack_core.c b/net/ipv4/netfilter/ip_conntrack_core.c
index c432b3163609..143c4668538b 100644
--- a/net/ipv4/netfilter/ip_conntrack_core.c
+++ b/net/ipv4/netfilter/ip_conntrack_core.c
@@ -149,8 +149,8 @@ static unsigned int ip_conntrack_hash_rnd;
static u_int32_t __hash_conntrack(const struct ip_conntrack_tuple *tuple,
unsigned int size, unsigned int rnd)
{
- return (jhash_3words(tuple->src.ip,
- (tuple->dst.ip ^ tuple->dst.protonum),
+ return (jhash_3words((__force u32)tuple->src.ip,
+ ((__force u32)tuple->dst.ip ^ tuple->dst.protonum),
(tuple->src.u.all | (tuple->dst.u.all << 16)),
rnd) % size);
}
@@ -1169,9 +1169,9 @@ void __ip_ct_refresh_acct(struct ip_conntrack *ct,
int ip_ct_port_tuple_to_nfattr(struct sk_buff *skb,
const struct ip_conntrack_tuple *tuple)
{
- NFA_PUT(skb, CTA_PROTO_SRC_PORT, sizeof(u_int16_t),
+ NFA_PUT(skb, CTA_PROTO_SRC_PORT, sizeof(__be16),
&tuple->src.u.tcp.port);
- NFA_PUT(skb, CTA_PROTO_DST_PORT, sizeof(u_int16_t),
+ NFA_PUT(skb, CTA_PROTO_DST_PORT, sizeof(__be16),
&tuple->dst.u.tcp.port);
return 0;
@@ -1186,9 +1186,9 @@ int ip_ct_port_nfattr_to_tuple(struct nfattr *tb[],
return -EINVAL;
t->src.u.tcp.port =
- *(u_int16_t *)NFA_DATA(tb[CTA_PROTO_SRC_PORT-1]);
+ *(__be16 *)NFA_DATA(tb[CTA_PROTO_SRC_PORT-1]);
t->dst.u.tcp.port =
- *(u_int16_t *)NFA_DATA(tb[CTA_PROTO_DST_PORT-1]);
+ *(__be16 *)NFA_DATA(tb[CTA_PROTO_DST_PORT-1]);
return 0;
}
diff --git a/net/ipv4/netfilter/ip_conntrack_ftp.c b/net/ipv4/netfilter/ip_conntrack_ftp.c
index 1d18c863f064..93dcf960662f 100644
--- a/net/ipv4/netfilter/ip_conntrack_ftp.c
+++ b/net/ipv4/netfilter/ip_conntrack_ftp.c
@@ -425,8 +425,8 @@ static int help(struct sk_buff **pskb,
exp->tuple.src.u.tcp.port = 0; /* Don't care. */
exp->tuple.dst.protonum = IPPROTO_TCP;
exp->mask = ((struct ip_conntrack_tuple)
- { { 0xFFFFFFFF, { 0 } },
- { 0xFFFFFFFF, { .tcp = { 0xFFFF } }, 0xFF }});
+ { { htonl(0xFFFFFFFF), { 0 } },
+ { htonl(0xFFFFFFFF), { .tcp = { htons(0xFFFF) } }, 0xFF }});
exp->expectfn = NULL;
exp->flags = 0;
@@ -488,7 +488,7 @@ static int __init ip_conntrack_ftp_init(void)
for (i = 0; i < ports_c; i++) {
ftp[i].tuple.src.u.tcp.port = htons(ports[i]);
ftp[i].tuple.dst.protonum = IPPROTO_TCP;
- ftp[i].mask.src.u.tcp.port = 0xFFFF;
+ ftp[i].mask.src.u.tcp.port = htons(0xFFFF);
ftp[i].mask.dst.protonum = 0xFF;
ftp[i].max_expected = 1;
ftp[i].timeout = 5 * 60; /* 5 minutes */
diff --git a/net/ipv4/netfilter/ip_conntrack_helper_h323.c b/net/ipv4/netfilter/ip_conntrack_helper_h323.c
index 9a39e2969712..7b7441202bfd 100644
--- a/net/ipv4/netfilter/ip_conntrack_helper_h323.c
+++ b/net/ipv4/netfilter/ip_conntrack_helper_h323.c
@@ -49,11 +49,11 @@ MODULE_PARM_DESC(callforward_filter, "only create call forwarding expectations "
int (*set_h245_addr_hook) (struct sk_buff ** pskb,
unsigned char **data, int dataoff,
H245_TransportAddress * addr,
- u_int32_t ip, u_int16_t port);
+ __be32 ip, u_int16_t port);
int (*set_h225_addr_hook) (struct sk_buff ** pskb,
unsigned char **data, int dataoff,
TransportAddress * addr,
- u_int32_t ip, u_int16_t port);
+ __be32 ip, u_int16_t port);
int (*set_sig_addr_hook) (struct sk_buff ** pskb,
struct ip_conntrack * ct,
enum ip_conntrack_info ctinfo,
@@ -209,7 +209,7 @@ static int get_tpkt_data(struct sk_buff **pskb, struct ip_conntrack *ct,
/****************************************************************************/
static int get_h245_addr(unsigned char *data, H245_TransportAddress * addr,
- u_int32_t * ip, u_int16_t * port)
+ __be32 * ip, u_int16_t * port)
{
unsigned char *p;
@@ -232,7 +232,7 @@ static int expect_rtp_rtcp(struct sk_buff **pskb, struct ip_conntrack *ct,
{
int dir = CTINFO2DIR(ctinfo);
int ret = 0;
- u_int32_t ip;
+ __be32 ip;
u_int16_t port;
u_int16_t rtp_port;
struct ip_conntrack_expect *rtp_exp;
@@ -254,10 +254,10 @@ static int expect_rtp_rtcp(struct sk_buff **pskb, struct ip_conntrack *ct,
rtp_exp->tuple.dst.ip = ct->tuplehash[!dir].tuple.dst.ip;
rtp_exp->tuple.dst.u.udp.port = htons(rtp_port);
rtp_exp->tuple.dst.protonum = IPPROTO_UDP;
- rtp_exp->mask.src.ip = 0xFFFFFFFF;
+ rtp_exp->mask.src.ip = htonl(0xFFFFFFFF);
rtp_exp->mask.src.u.udp.port = 0;
- rtp_exp->mask.dst.ip = 0xFFFFFFFF;
- rtp_exp->mask.dst.u.udp.port = 0xFFFF;
+ rtp_exp->mask.dst.ip = htonl(0xFFFFFFFF);
+ rtp_exp->mask.dst.u.udp.port = htons(0xFFFF);
rtp_exp->mask.dst.protonum = 0xFF;
rtp_exp->flags = 0;
@@ -271,10 +271,10 @@ static int expect_rtp_rtcp(struct sk_buff **pskb, struct ip_conntrack *ct,
rtcp_exp->tuple.dst.ip = ct->tuplehash[!dir].tuple.dst.ip;
rtcp_exp->tuple.dst.u.udp.port = htons(rtp_port + 1);
rtcp_exp->tuple.dst.protonum = IPPROTO_UDP;
- rtcp_exp->mask.src.ip = 0xFFFFFFFF;
+ rtcp_exp->mask.src.ip = htonl(0xFFFFFFFF);
rtcp_exp->mask.src.u.udp.port = 0;
- rtcp_exp->mask.dst.ip = 0xFFFFFFFF;
- rtcp_exp->mask.dst.u.udp.port = 0xFFFF;
+ rtcp_exp->mask.dst.ip = htonl(0xFFFFFFFF);
+ rtcp_exp->mask.dst.u.udp.port = htons(0xFFFF);
rtcp_exp->mask.dst.protonum = 0xFF;
rtcp_exp->flags = 0;
@@ -325,7 +325,7 @@ static int expect_t120(struct sk_buff **pskb,
{
int dir = CTINFO2DIR(ctinfo);
int ret = 0;
- u_int32_t ip;
+ __be32 ip;
u_int16_t port;
struct ip_conntrack_expect *exp = NULL;
@@ -342,10 +342,10 @@ static int expect_t120(struct sk_buff **pskb,
exp->tuple.dst.ip = ct->tuplehash[!dir].tuple.dst.ip;
exp->tuple.dst.u.tcp.port = htons(port);
exp->tuple.dst.protonum = IPPROTO_TCP;
- exp->mask.src.ip = 0xFFFFFFFF;
+ exp->mask.src.ip = htonl(0xFFFFFFFF);
exp->mask.src.u.tcp.port = 0;
- exp->mask.dst.ip = 0xFFFFFFFF;
- exp->mask.dst.u.tcp.port = 0xFFFF;
+ exp->mask.dst.ip = htonl(0xFFFFFFFF);
+ exp->mask.dst.u.tcp.port = htons(0xFFFF);
exp->mask.dst.protonum = 0xFF;
exp->flags = IP_CT_EXPECT_PERMANENT; /* Accept multiple channels */
@@ -626,7 +626,7 @@ void ip_conntrack_h245_expect(struct ip_conntrack *new,
/****************************************************************************/
int get_h225_addr(unsigned char *data, TransportAddress * addr,
- u_int32_t * ip, u_int16_t * port)
+ __be32 * ip, u_int16_t * port)
{
unsigned char *p;
@@ -648,7 +648,7 @@ static int expect_h245(struct sk_buff **pskb, struct ip_conntrack *ct,
{
int dir = CTINFO2DIR(ctinfo);
int ret = 0;
- u_int32_t ip;
+ __be32 ip;
u_int16_t port;
struct ip_conntrack_expect *exp = NULL;
@@ -665,10 +665,10 @@ static int expect_h245(struct sk_buff **pskb, struct ip_conntrack *ct,
exp->tuple.dst.ip = ct->tuplehash[!dir].tuple.dst.ip;
exp->tuple.dst.u.tcp.port = htons(port);
exp->tuple.dst.protonum = IPPROTO_TCP;
- exp->mask.src.ip = 0xFFFFFFFF;
+ exp->mask.src.ip = htonl(0xFFFFFFFF);
exp->mask.src.u.tcp.port = 0;
- exp->mask.dst.ip = 0xFFFFFFFF;
- exp->mask.dst.u.tcp.port = 0xFFFF;
+ exp->mask.dst.ip = htonl(0xFFFFFFFF);
+ exp->mask.dst.u.tcp.port = htons(0xFFFF);
exp->mask.dst.protonum = 0xFF;
exp->flags = 0;
@@ -709,7 +709,7 @@ static int expect_callforwarding(struct sk_buff **pskb,
{
int dir = CTINFO2DIR(ctinfo);
int ret = 0;
- u_int32_t ip;
+ __be32 ip;
u_int16_t port;
struct ip_conntrack_expect *exp = NULL;
@@ -751,10 +751,10 @@ static int expect_callforwarding(struct sk_buff **pskb,
exp->tuple.dst.ip = ip;
exp->tuple.dst.u.tcp.port = htons(port);
exp->tuple.dst.protonum = IPPROTO_TCP;
- exp->mask.src.ip = 0xFFFFFFFF;
+ exp->mask.src.ip = htonl(0xFFFFFFFF);
exp->mask.src.u.tcp.port = 0;
- exp->mask.dst.ip = 0xFFFFFFFF;
- exp->mask.dst.u.tcp.port = 0xFFFF;
+ exp->mask.dst.ip = htonl(0xFFFFFFFF);
+ exp->mask.dst.u.tcp.port = htons(0xFFFF);
exp->mask.dst.protonum = 0xFF;
exp->flags = 0;
@@ -791,7 +791,7 @@ static int process_setup(struct sk_buff **pskb, struct ip_conntrack *ct,
int dir = CTINFO2DIR(ctinfo);
int ret;
int i;
- u_int32_t ip;
+ __be32 ip;
u_int16_t port;
DEBUGP("ip_ct_q931: Setup\n");
@@ -1188,7 +1188,7 @@ static unsigned char *get_udp_data(struct sk_buff **pskb, int *datalen)
/****************************************************************************/
static struct ip_conntrack_expect *find_expect(struct ip_conntrack *ct,
- u_int32_t ip, u_int16_t port)
+ __be32 ip, u_int16_t port)
{
struct ip_conntrack_expect *exp;
struct ip_conntrack_tuple tuple;
@@ -1228,7 +1228,7 @@ static int expect_q931(struct sk_buff **pskb, struct ip_conntrack *ct,
int dir = CTINFO2DIR(ctinfo);
int ret = 0;
int i;
- u_int32_t ip;
+ __be32 ip;
u_int16_t port;
struct ip_conntrack_expect *exp;
@@ -1251,10 +1251,10 @@ static int expect_q931(struct sk_buff **pskb, struct ip_conntrack *ct,
exp->tuple.dst.ip = ct->tuplehash[!dir].tuple.dst.ip;
exp->tuple.dst.u.tcp.port = htons(port);
exp->tuple.dst.protonum = IPPROTO_TCP;
- exp->mask.src.ip = gkrouted_only ? 0xFFFFFFFF : 0;
+ exp->mask.src.ip = gkrouted_only ? htonl(0xFFFFFFFF) : 0;
exp->mask.src.u.tcp.port = 0;
- exp->mask.dst.ip = 0xFFFFFFFF;
- exp->mask.dst.u.tcp.port = 0xFFFF;
+ exp->mask.dst.ip = htonl(0xFFFFFFFF);
+ exp->mask.dst.u.tcp.port = htons(0xFFFF);
exp->mask.dst.protonum = 0xFF;
exp->flags = IP_CT_EXPECT_PERMANENT; /* Accept multiple calls */
@@ -1307,7 +1307,7 @@ static int process_gcf(struct sk_buff **pskb, struct ip_conntrack *ct,
{
int dir = CTINFO2DIR(ctinfo);
int ret = 0;
- u_int32_t ip;
+ __be32 ip;
u_int16_t port;
struct ip_conntrack_expect *exp;
@@ -1333,10 +1333,10 @@ static int process_gcf(struct sk_buff **pskb, struct ip_conntrack *ct,
exp->tuple.dst.ip = ip;
exp->tuple.dst.u.tcp.port = htons(port);
exp->tuple.dst.protonum = IPPROTO_UDP;
- exp->mask.src.ip = 0xFFFFFFFF;
+ exp->mask.src.ip = htonl(0xFFFFFFFF);
exp->mask.src.u.tcp.port = 0;
- exp->mask.dst.ip = 0xFFFFFFFF;
- exp->mask.dst.u.tcp.port = 0xFFFF;
+ exp->mask.dst.ip = htonl(0xFFFFFFFF);
+ exp->mask.dst.u.tcp.port = htons(0xFFFF);
exp->mask.dst.protonum = 0xFF;
exp->flags = 0;
exp->expectfn = ip_conntrack_ras_expect;
@@ -1477,7 +1477,7 @@ static int process_arq(struct sk_buff **pskb, struct ip_conntrack *ct,
{
struct ip_ct_h323_master *info = &ct->help.ct_h323_info;
int dir = CTINFO2DIR(ctinfo);
- u_int32_t ip;
+ __be32 ip;
u_int16_t port;
DEBUGP("ip_ct_ras: ARQ\n");
@@ -1513,7 +1513,7 @@ static int process_acf(struct sk_buff **pskb, struct ip_conntrack *ct,
{
int dir = CTINFO2DIR(ctinfo);
int ret = 0;
- u_int32_t ip;
+ __be32 ip;
u_int16_t port;
struct ip_conntrack_expect *exp;
@@ -1538,10 +1538,10 @@ static int process_acf(struct sk_buff **pskb, struct ip_conntrack *ct,
exp->tuple.dst.ip = ip;
exp->tuple.dst.u.tcp.port = htons(port);
exp->tuple.dst.protonum = IPPROTO_TCP;
- exp->mask.src.ip = 0xFFFFFFFF;
+ exp->mask.src.ip = htonl(0xFFFFFFFF);
exp->mask.src.u.tcp.port = 0;
- exp->mask.dst.ip = 0xFFFFFFFF;
- exp->mask.dst.u.tcp.port = 0xFFFF;
+ exp->mask.dst.ip = htonl(0xFFFFFFFF);
+ exp->mask.dst.u.tcp.port = htons(0xFFFF);
exp->mask.dst.protonum = 0xFF;
exp->flags = IP_CT_EXPECT_PERMANENT;
exp->expectfn = ip_conntrack_q931_expect;
@@ -1581,7 +1581,7 @@ static int process_lcf(struct sk_buff **pskb, struct ip_conntrack *ct,
{
int dir = CTINFO2DIR(ctinfo);
int ret = 0;
- u_int32_t ip;
+ __be32 ip;
u_int16_t port;
struct ip_conntrack_expect *exp = NULL;
@@ -1598,10 +1598,10 @@ static int process_lcf(struct sk_buff **pskb, struct ip_conntrack *ct,
exp->tuple.dst.ip = ip;
exp->tuple.dst.u.tcp.port = htons(port);
exp->tuple.dst.protonum = IPPROTO_TCP;
- exp->mask.src.ip = 0xFFFFFFFF;
+ exp->mask.src.ip = htonl(0xFFFFFFFF);
exp->mask.src.u.tcp.port = 0;
- exp->mask.dst.ip = 0xFFFFFFFF;
- exp->mask.dst.u.tcp.port = 0xFFFF;
+ exp->mask.dst.ip = htonl(0xFFFFFFFF);
+ exp->mask.dst.u.tcp.port = htons(0xFFFF);
exp->mask.dst.protonum = 0xFF;
exp->flags = IP_CT_EXPECT_PERMANENT;
exp->expectfn = ip_conntrack_q931_expect;
diff --git a/net/ipv4/netfilter/ip_conntrack_helper_pptp.c b/net/ipv4/netfilter/ip_conntrack_helper_pptp.c
index fb0aee691721..a2af5e0c7f99 100644
--- a/net/ipv4/netfilter/ip_conntrack_helper_pptp.c
+++ b/net/ipv4/netfilter/ip_conntrack_helper_pptp.c
@@ -242,10 +242,10 @@ exp_gre(struct ip_conntrack *ct,
exp_orig->tuple.dst.u.gre.key = callid;
exp_orig->tuple.dst.protonum = IPPROTO_GRE;
- exp_orig->mask.src.ip = 0xffffffff;
+ exp_orig->mask.src.ip = htonl(0xffffffff);
exp_orig->mask.src.u.all = 0;
exp_orig->mask.dst.u.gre.key = htons(0xffff);
- exp_orig->mask.dst.ip = 0xffffffff;
+ exp_orig->mask.dst.ip = htonl(0xffffffff);
exp_orig->mask.dst.protonum = 0xff;
exp_orig->master = ct;
diff --git a/net/ipv4/netfilter/ip_conntrack_irc.c b/net/ipv4/netfilter/ip_conntrack_irc.c
index 44889075f3b2..75f7c3db1619 100644
--- a/net/ipv4/netfilter/ip_conntrack_irc.c
+++ b/net/ipv4/netfilter/ip_conntrack_irc.c
@@ -218,7 +218,8 @@ static int help(struct sk_buff **pskb,
IPPROTO_TCP }});
exp->mask = ((struct ip_conntrack_tuple)
{ { 0, { 0 } },
- { 0xFFFFFFFF, { .tcp = { 0xFFFF } }, 0xFF }});
+ { htonl(0xFFFFFFFF),
+ { .tcp = { htons(0xFFFF) } }, 0xFF }});
exp->expectfn = NULL;
exp->flags = 0;
if (ip_nat_irc_hook)
@@ -266,7 +267,7 @@ static int __init ip_conntrack_irc_init(void)
hlpr = &irc_helpers[i];
hlpr->tuple.src.u.tcp.port = htons(ports[i]);
hlpr->tuple.dst.protonum = IPPROTO_TCP;
- hlpr->mask.src.u.tcp.port = 0xFFFF;
+ hlpr->mask.src.u.tcp.port = htons(0xFFFF);
hlpr->mask.dst.protonum = 0xFF;
hlpr->max_expected = max_dcc_channels;
hlpr->timeout = dcc_timeout;
diff --git a/net/ipv4/netfilter/ip_conntrack_netbios_ns.c b/net/ipv4/netfilter/ip_conntrack_netbios_ns.c
index 3d0b438783db..a1d6a89f64aa 100644
--- a/net/ipv4/netfilter/ip_conntrack_netbios_ns.c
+++ b/net/ipv4/netfilter/ip_conntrack_netbios_ns.c
@@ -48,7 +48,7 @@ static int help(struct sk_buff **pskb,
struct iphdr *iph = (*pskb)->nh.iph;
struct rtable *rt = (struct rtable *)(*pskb)->dst;
struct in_device *in_dev;
- u_int32_t mask = 0;
+ __be32 mask = 0;
/* we're only interested in locally generated packets */
if ((*pskb)->sk == NULL)
@@ -78,12 +78,12 @@ static int help(struct sk_buff **pskb,
goto out;
exp->tuple = ct->tuplehash[IP_CT_DIR_REPLY].tuple;
- exp->tuple.src.u.udp.port = ntohs(NMBD_PORT);
+ exp->tuple.src.u.udp.port = htons(NMBD_PORT);
exp->mask.src.ip = mask;
- exp->mask.src.u.udp.port = 0xFFFF;
- exp->mask.dst.ip = 0xFFFFFFFF;
- exp->mask.dst.u.udp.port = 0xFFFF;
+ exp->mask.src.u.udp.port = htons(0xFFFF);
+ exp->mask.dst.ip = htonl(0xFFFFFFFF);
+ exp->mask.dst.u.udp.port = htons(0xFFFF);
exp->mask.dst.protonum = 0xFF;
exp->expectfn = NULL;
@@ -115,7 +115,7 @@ static struct ip_conntrack_helper helper = {
.src = {
.u = {
.udp = {
- .port = 0xFFFF,
+ .port = __constant_htons(0xFFFF),
}
}
},
diff --git a/net/ipv4/netfilter/ip_conntrack_netlink.c b/net/ipv4/netfilter/ip_conntrack_netlink.c
index 52eddea27e93..53b6dffea6c2 100644
--- a/net/ipv4/netfilter/ip_conntrack_netlink.c
+++ b/net/ipv4/netfilter/ip_conntrack_netlink.c
@@ -78,8 +78,8 @@ ctnetlink_dump_tuples_ip(struct sk_buff *skb,
{
struct nfattr *nest_parms = NFA_NEST(skb, CTA_TUPLE_IP);
- NFA_PUT(skb, CTA_IP_V4_SRC, sizeof(u_int32_t), &tuple->src.ip);
- NFA_PUT(skb, CTA_IP_V4_DST, sizeof(u_int32_t), &tuple->dst.ip);
+ NFA_PUT(skb, CTA_IP_V4_SRC, sizeof(__be32), &tuple->src.ip);
+ NFA_PUT(skb, CTA_IP_V4_DST, sizeof(__be32), &tuple->dst.ip);
NFA_NEST_END(skb, nest_parms);
@@ -110,7 +110,7 @@ ctnetlink_dump_tuples(struct sk_buff *skb,
static inline int
ctnetlink_dump_status(struct sk_buff *skb, const struct ip_conntrack *ct)
{
- u_int32_t status = htonl((u_int32_t) ct->status);
+ __be32 status = htonl((u_int32_t) ct->status);
NFA_PUT(skb, CTA_STATUS, sizeof(status), &status);
return 0;
@@ -122,7 +122,7 @@ static inline int
ctnetlink_dump_timeout(struct sk_buff *skb, const struct ip_conntrack *ct)
{
long timeout_l = ct->timeout.expires - jiffies;
- u_int32_t timeout;
+ __be32 timeout;
if (timeout_l < 0)
timeout = 0;
@@ -192,13 +192,13 @@ ctnetlink_dump_counters(struct sk_buff *skb, const struct ip_conntrack *ct,
{
enum ctattr_type type = dir ? CTA_COUNTERS_REPLY: CTA_COUNTERS_ORIG;
struct nfattr *nest_count = NFA_NEST(skb, type);
- u_int32_t tmp;
+ __be32 tmp;
tmp = htonl(ct->counters[dir].packets);
- NFA_PUT(skb, CTA_COUNTERS32_PACKETS, sizeof(u_int32_t), &tmp);
+ NFA_PUT(skb, CTA_COUNTERS32_PACKETS, sizeof(__be32), &tmp);
tmp = htonl(ct->counters[dir].bytes);
- NFA_PUT(skb, CTA_COUNTERS32_BYTES, sizeof(u_int32_t), &tmp);
+ NFA_PUT(skb, CTA_COUNTERS32_BYTES, sizeof(__be32), &tmp);
NFA_NEST_END(skb, nest_count);
@@ -215,9 +215,9 @@ nfattr_failure:
static inline int
ctnetlink_dump_mark(struct sk_buff *skb, const struct ip_conntrack *ct)
{
- u_int32_t mark = htonl(ct->mark);
+ __be32 mark = htonl(ct->mark);
- NFA_PUT(skb, CTA_MARK, sizeof(u_int32_t), &mark);
+ NFA_PUT(skb, CTA_MARK, sizeof(__be32), &mark);
return 0;
nfattr_failure:
@@ -230,8 +230,8 @@ nfattr_failure:
static inline int
ctnetlink_dump_id(struct sk_buff *skb, const struct ip_conntrack *ct)
{
- u_int32_t id = htonl(ct->id);
- NFA_PUT(skb, CTA_ID, sizeof(u_int32_t), &id);
+ __be32 id = htonl(ct->id);
+ NFA_PUT(skb, CTA_ID, sizeof(__be32), &id);
return 0;
nfattr_failure:
@@ -241,9 +241,9 @@ nfattr_failure:
static inline int
ctnetlink_dump_use(struct sk_buff *skb, const struct ip_conntrack *ct)
{
- u_int32_t use = htonl(atomic_read(&ct->ct_general.use));
+ __be32 use = htonl(atomic_read(&ct->ct_general.use));
- NFA_PUT(skb, CTA_USE, sizeof(u_int32_t), &use);
+ NFA_PUT(skb, CTA_USE, sizeof(__be32), &use);
return 0;
nfattr_failure:
@@ -457,8 +457,8 @@ out:
}
static const size_t cta_min_ip[CTA_IP_MAX] = {
- [CTA_IP_V4_SRC-1] = sizeof(u_int32_t),
- [CTA_IP_V4_DST-1] = sizeof(u_int32_t),
+ [CTA_IP_V4_SRC-1] = sizeof(__be32),
+ [CTA_IP_V4_DST-1] = sizeof(__be32),
};
static inline int
@@ -475,11 +475,11 @@ ctnetlink_parse_tuple_ip(struct nfattr *attr, struct ip_conntrack_tuple *tuple)
if (!tb[CTA_IP_V4_SRC-1])
return -EINVAL;
- tuple->src.ip = *(u_int32_t *)NFA_DATA(tb[CTA_IP_V4_SRC-1]);
+ tuple->src.ip = *(__be32 *)NFA_DATA(tb[CTA_IP_V4_SRC-1]);
if (!tb[CTA_IP_V4_DST-1])
return -EINVAL;
- tuple->dst.ip = *(u_int32_t *)NFA_DATA(tb[CTA_IP_V4_DST-1]);
+ tuple->dst.ip = *(__be32 *)NFA_DATA(tb[CTA_IP_V4_DST-1]);
DEBUGP("leaving\n");
@@ -602,8 +602,8 @@ static int ctnetlink_parse_nat_proto(struct nfattr *attr,
}
static const size_t cta_min_nat[CTA_NAT_MAX] = {
- [CTA_NAT_MINIP-1] = sizeof(u_int32_t),
- [CTA_NAT_MAXIP-1] = sizeof(u_int32_t),
+ [CTA_NAT_MINIP-1] = sizeof(__be32),
+ [CTA_NAT_MAXIP-1] = sizeof(__be32),
};
static inline int
@@ -623,12 +623,12 @@ ctnetlink_parse_nat(struct nfattr *nat,
return -EINVAL;
if (tb[CTA_NAT_MINIP-1])
- range->min_ip = *(u_int32_t *)NFA_DATA(tb[CTA_NAT_MINIP-1]);
+ range->min_ip = *(__be32 *)NFA_DATA(tb[CTA_NAT_MINIP-1]);
if (!tb[CTA_NAT_MAXIP-1])
range->max_ip = range->min_ip;
else
- range->max_ip = *(u_int32_t *)NFA_DATA(tb[CTA_NAT_MAXIP-1]);
+ range->max_ip = *(__be32 *)NFA_DATA(tb[CTA_NAT_MAXIP-1]);
if (range->min_ip)
range->flags |= IP_NAT_RANGE_MAP_IPS;
@@ -663,11 +663,11 @@ ctnetlink_parse_help(struct nfattr *attr, char **helper_name)
}
static const size_t cta_min[CTA_MAX] = {
- [CTA_STATUS-1] = sizeof(u_int32_t),
- [CTA_TIMEOUT-1] = sizeof(u_int32_t),
- [CTA_MARK-1] = sizeof(u_int32_t),
- [CTA_USE-1] = sizeof(u_int32_t),
- [CTA_ID-1] = sizeof(u_int32_t)
+ [CTA_STATUS-1] = sizeof(__be32),
+ [CTA_TIMEOUT-1] = sizeof(__be32),
+ [CTA_MARK-1] = sizeof(__be32),
+ [CTA_USE-1] = sizeof(__be32),
+ [CTA_ID-1] = sizeof(__be32)
};
static int
@@ -706,7 +706,7 @@ ctnetlink_del_conntrack(struct sock *ctnl, struct sk_buff *skb,
ct = tuplehash_to_ctrack(h);
if (cda[CTA_ID-1]) {
- u_int32_t id = ntohl(*(u_int32_t *)NFA_DATA(cda[CTA_ID-1]));
+ u_int32_t id = ntohl(*(__be32 *)NFA_DATA(cda[CTA_ID-1]));
if (ct->id != id) {
ip_conntrack_put(ct);
return -ENOENT;
@@ -808,7 +808,7 @@ static inline int
ctnetlink_change_status(struct ip_conntrack *ct, struct nfattr *cda[])
{
unsigned long d;
- unsigned status = ntohl(*(u_int32_t *)NFA_DATA(cda[CTA_STATUS-1]));
+ unsigned status = ntohl(*(__be32 *)NFA_DATA(cda[CTA_STATUS-1]));
d = ct->status ^ status;
if (d & (IPS_EXPECTED|IPS_CONFIRMED|IPS_DYING))
@@ -903,7 +903,7 @@ ctnetlink_change_helper(struct ip_conntrack *ct, struct nfattr *cda[])
static inline int
ctnetlink_change_timeout(struct ip_conntrack *ct, struct nfattr *cda[])
{
- u_int32_t timeout = ntohl(*(u_int32_t *)NFA_DATA(cda[CTA_TIMEOUT-1]));
+ u_int32_t timeout = ntohl(*(__be32 *)NFA_DATA(cda[CTA_TIMEOUT-1]));
if (!del_timer(&ct->timeout))
return -ETIME;
@@ -966,7 +966,7 @@ ctnetlink_change_conntrack(struct ip_conntrack *ct, struct nfattr *cda[])
#if defined(CONFIG_IP_NF_CONNTRACK_MARK)
if (cda[CTA_MARK-1])
- ct->mark = ntohl(*(u_int32_t *)NFA_DATA(cda[CTA_MARK-1]));
+ ct->mark = ntohl(*(__be32 *)NFA_DATA(cda[CTA_MARK-1]));
#endif
DEBUGP("all done\n");
@@ -989,7 +989,7 @@ ctnetlink_create_conntrack(struct nfattr *cda[],
if (!cda[CTA_TIMEOUT-1])
goto err;
- ct->timeout.expires = ntohl(*(u_int32_t *)NFA_DATA(cda[CTA_TIMEOUT-1]));
+ ct->timeout.expires = ntohl(*(__be32 *)NFA_DATA(cda[CTA_TIMEOUT-1]));
ct->timeout.expires = jiffies + ct->timeout.expires * HZ;
ct->status |= IPS_CONFIRMED;
@@ -1006,7 +1006,7 @@ ctnetlink_create_conntrack(struct nfattr *cda[],
#if defined(CONFIG_IP_NF_CONNTRACK_MARK)
if (cda[CTA_MARK-1])
- ct->mark = ntohl(*(u_int32_t *)NFA_DATA(cda[CTA_MARK-1]));
+ ct->mark = ntohl(*(__be32 *)NFA_DATA(cda[CTA_MARK-1]));
#endif
ct->helper = ip_conntrack_helper_find_get(rtuple);
@@ -1138,8 +1138,8 @@ ctnetlink_exp_dump_expect(struct sk_buff *skb,
const struct ip_conntrack_expect *exp)
{
struct ip_conntrack *master = exp->master;
- u_int32_t timeout = htonl((exp->timeout.expires - jiffies) / HZ);
- u_int32_t id = htonl(exp->id);
+ __be32 timeout = htonl((exp->timeout.expires - jiffies) / HZ);
+ __be32 id = htonl(exp->id);
if (ctnetlink_exp_dump_tuple(skb, &exp->tuple, CTA_EXPECT_TUPLE) < 0)
goto nfattr_failure;
@@ -1150,8 +1150,8 @@ ctnetlink_exp_dump_expect(struct sk_buff *skb,
CTA_EXPECT_MASTER) < 0)
goto nfattr_failure;
- NFA_PUT(skb, CTA_EXPECT_TIMEOUT, sizeof(timeout), &timeout);
- NFA_PUT(skb, CTA_EXPECT_ID, sizeof(u_int32_t), &id);
+ NFA_PUT(skb, CTA_EXPECT_TIMEOUT, sizeof(__be32), &timeout);
+ NFA_PUT(skb, CTA_EXPECT_ID, sizeof(__be32), &id);
return 0;
@@ -1272,8 +1272,8 @@ out:
}
static const size_t cta_min_exp[CTA_EXPECT_MAX] = {
- [CTA_EXPECT_TIMEOUT-1] = sizeof(u_int32_t),
- [CTA_EXPECT_ID-1] = sizeof(u_int32_t)
+ [CTA_EXPECT_TIMEOUT-1] = sizeof(__be32),
+ [CTA_EXPECT_ID-1] = sizeof(__be32)
};
static int
@@ -1321,7 +1321,7 @@ ctnetlink_get_expect(struct sock *ctnl, struct sk_buff *skb,
return -ENOENT;
if (cda[CTA_EXPECT_ID-1]) {
- u_int32_t id = *(u_int32_t *)NFA_DATA(cda[CTA_EXPECT_ID-1]);
+ __be32 id = *(__be32 *)NFA_DATA(cda[CTA_EXPECT_ID-1]);
if (exp->id != ntohl(id)) {
ip_conntrack_expect_put(exp);
return -ENOENT;
@@ -1375,8 +1375,8 @@ ctnetlink_del_expect(struct sock *ctnl, struct sk_buff *skb,
return -ENOENT;
if (cda[CTA_EXPECT_ID-1]) {
- u_int32_t id =
- *(u_int32_t *)NFA_DATA(cda[CTA_EXPECT_ID-1]);
+ __be32 id =
+ *(__be32 *)NFA_DATA(cda[CTA_EXPECT_ID-1]);
if (exp->id != ntohl(id)) {
ip_conntrack_expect_put(exp);
return -ENOENT;
diff --git a/net/ipv4/netfilter/ip_conntrack_proto_icmp.c b/net/ipv4/netfilter/ip_conntrack_proto_icmp.c
index 09c40ebe3345..295b6fa340db 100644
--- a/net/ipv4/netfilter/ip_conntrack_proto_icmp.c
+++ b/net/ipv4/netfilter/ip_conntrack_proto_icmp.c
@@ -261,7 +261,7 @@ icmp_error(struct sk_buff *skb, enum ip_conntrack_info *ctinfo,
static int icmp_tuple_to_nfattr(struct sk_buff *skb,
const struct ip_conntrack_tuple *t)
{
- NFA_PUT(skb, CTA_PROTO_ICMP_ID, sizeof(u_int16_t),
+ NFA_PUT(skb, CTA_PROTO_ICMP_ID, sizeof(__be16),
&t->src.u.icmp.id);
NFA_PUT(skb, CTA_PROTO_ICMP_TYPE, sizeof(u_int8_t),
&t->dst.u.icmp.type);
@@ -287,7 +287,7 @@ static int icmp_nfattr_to_tuple(struct nfattr *tb[],
tuple->dst.u.icmp.code =
*(u_int8_t *)NFA_DATA(tb[CTA_PROTO_ICMP_CODE-1]);
tuple->src.u.icmp.id =
- *(u_int16_t *)NFA_DATA(tb[CTA_PROTO_ICMP_ID-1]);
+ *(__be16 *)NFA_DATA(tb[CTA_PROTO_ICMP_ID-1]);
if (tuple->dst.u.icmp.type >= sizeof(invmap)
|| !invmap[tuple->dst.u.icmp.type])
diff --git a/net/ipv4/netfilter/ip_conntrack_proto_sctp.c b/net/ipv4/netfilter/ip_conntrack_proto_sctp.c
index b908a4842e18..2443322e4128 100644
--- a/net/ipv4/netfilter/ip_conntrack_proto_sctp.c
+++ b/net/ipv4/netfilter/ip_conntrack_proto_sctp.c
@@ -210,7 +210,7 @@ static int sctp_print_conntrack(struct seq_file *s,
for (offset = skb->nh.iph->ihl * 4 + sizeof(sctp_sctphdr_t), count = 0; \
offset < skb->len && \
(sch = skb_header_pointer(skb, offset, sizeof(_sch), &_sch)); \
- offset += (htons(sch->length) + 3) & ~3, count++)
+ offset += (ntohs(sch->length) + 3) & ~3, count++)
/* Some validity checks to make sure the chunks are fine */
static int do_basic_checks(struct ip_conntrack *conntrack,
diff --git a/net/ipv4/netfilter/ip_conntrack_proto_tcp.c b/net/ipv4/netfilter/ip_conntrack_proto_tcp.c
index 03ae9a04cb37..06e4e8a6dd9f 100644
--- a/net/ipv4/netfilter/ip_conntrack_proto_tcp.c
+++ b/net/ipv4/netfilter/ip_conntrack_proto_tcp.c
@@ -519,8 +519,8 @@ static void tcp_sack(const struct sk_buff *skb,
/* Fast path for timestamp-only option */
if (length == TCPOLEN_TSTAMP_ALIGNED*4
- && *(__u32 *)ptr ==
- __constant_ntohl((TCPOPT_NOP << 24)
+ && *(__be32 *)ptr ==
+ __constant_htonl((TCPOPT_NOP << 24)
| (TCPOPT_NOP << 16)
| (TCPOPT_TIMESTAMP << 8)
| TCPOLEN_TIMESTAMP))
@@ -551,7 +551,7 @@ static void tcp_sack(const struct sk_buff *skb,
for (i = 0;
i < (opsize - TCPOLEN_SACK_BASE);
i += TCPOLEN_SACK_PERBLOCK) {
- tmp = ntohl(*((u_int32_t *)(ptr+i)+1));
+ tmp = ntohl(*((__be32 *)(ptr+i)+1));
if (after(tmp, *sack))
*sack = tmp;
diff --git a/net/ipv4/netfilter/ip_conntrack_sip.c b/net/ipv4/netfilter/ip_conntrack_sip.c
index 2893e9c74850..f4f75995a9e4 100644
--- a/net/ipv4/netfilter/ip_conntrack_sip.c
+++ b/net/ipv4/netfilter/ip_conntrack_sip.c
@@ -193,7 +193,7 @@ static int skp_digits_len(const char *dptr, const char *limit, int *shift)
/* Simple ipaddr parser.. */
static int parse_ipaddr(const char *cp, const char **endp,
- u_int32_t *ipaddr, const char *limit)
+ __be32 *ipaddr, const char *limit)
{
unsigned long int val;
int i, digit = 0;
@@ -227,7 +227,7 @@ static int parse_ipaddr(const char *cp, const char **endp,
static int epaddr_len(const char *dptr, const char *limit, int *shift)
{
const char *aux = dptr;
- u_int32_t ip;
+ __be32 ip;
if (parse_ipaddr(dptr, &dptr, &ip, limit) < 0) {
DEBUGP("ip: %s parse failed.!\n", dptr);
@@ -302,7 +302,7 @@ int ct_sip_get_info(const char *dptr, size_t dlen,
static int set_expected_rtp(struct sk_buff **pskb,
struct ip_conntrack *ct,
enum ip_conntrack_info ctinfo,
- u_int32_t ipaddr, u_int16_t port,
+ __be32 ipaddr, u_int16_t port,
const char *dptr)
{
struct ip_conntrack_expect *exp;
@@ -319,10 +319,10 @@ static int set_expected_rtp(struct sk_buff **pskb,
exp->tuple.dst.u.udp.port = htons(port);
exp->tuple.dst.protonum = IPPROTO_UDP;
- exp->mask.src.ip = 0xFFFFFFFF;
+ exp->mask.src.ip = htonl(0xFFFFFFFF);
exp->mask.src.u.udp.port = 0;
- exp->mask.dst.ip = 0xFFFFFFFF;
- exp->mask.dst.u.udp.port = 0xFFFF;
+ exp->mask.dst.ip = htonl(0xFFFFFFFF);
+ exp->mask.dst.u.udp.port = htons(0xFFFF);
exp->mask.dst.protonum = 0xFF;
exp->expectfn = NULL;
@@ -349,7 +349,7 @@ static int sip_help(struct sk_buff **pskb,
const char *dptr;
int ret = NF_ACCEPT;
int matchoff, matchlen;
- u_int32_t ipaddr;
+ __be32 ipaddr;
u_int16_t port;
/* No Data ? */
@@ -439,7 +439,7 @@ static int __init init(void)
sip[i].tuple.dst.protonum = IPPROTO_UDP;
sip[i].tuple.src.u.udp.port = htons(ports[i]);
- sip[i].mask.src.u.udp.port = 0xFFFF;
+ sip[i].mask.src.u.udp.port = htons(0xFFFF);
sip[i].mask.dst.protonum = 0xFF;
sip[i].max_expected = 2;
sip[i].timeout = 3 * 60; /* 3 minutes */
diff --git a/net/ipv4/netfilter/ip_conntrack_tftp.c b/net/ipv4/netfilter/ip_conntrack_tftp.c
index 7e33d3bed5e3..fe0b634dd377 100644
--- a/net/ipv4/netfilter/ip_conntrack_tftp.c
+++ b/net/ipv4/netfilter/ip_conntrack_tftp.c
@@ -70,10 +70,10 @@ static int tftp_help(struct sk_buff **pskb,
return NF_DROP;
exp->tuple = ct->tuplehash[IP_CT_DIR_REPLY].tuple;
- exp->mask.src.ip = 0xffffffff;
+ exp->mask.src.ip = htonl(0xffffffff);
exp->mask.src.u.udp.port = 0;
- exp->mask.dst.ip = 0xffffffff;
- exp->mask.dst.u.udp.port = 0xffff;
+ exp->mask.dst.ip = htonl(0xffffffff);
+ exp->mask.dst.u.udp.port = htons(0xffff);
exp->mask.dst.protonum = 0xff;
exp->expectfn = NULL;
exp->flags = 0;
@@ -129,7 +129,7 @@ static int __init ip_conntrack_tftp_init(void)
tftp[i].tuple.dst.protonum = IPPROTO_UDP;
tftp[i].tuple.src.u.udp.port = htons(ports[i]);
tftp[i].mask.dst.protonum = 0xFF;
- tftp[i].mask.src.u.udp.port = 0xFFFF;
+ tftp[i].mask.src.u.udp.port = htons(0xFFFF);
tftp[i].max_expected = 1;
tftp[i].timeout = 5 * 60; /* 5 minutes */
tftp[i].me = THIS_MODULE;
diff --git a/net/ipv4/netfilter/ip_nat_core.c b/net/ipv4/netfilter/ip_nat_core.c
index 71f3e09cbc84..4b6260a97408 100644
--- a/net/ipv4/netfilter/ip_nat_core.c
+++ b/net/ipv4/netfilter/ip_nat_core.c
@@ -82,7 +82,7 @@ static inline unsigned int
hash_by_src(const struct ip_conntrack_tuple *tuple)
{
/* Original src, to ensure we map it consistently if poss. */
- return jhash_3words(tuple->src.ip, tuple->src.u.all,
+ return jhash_3words((__force u32)tuple->src.ip, tuple->src.u.all,
tuple->dst.protonum, 0) % ip_nat_htable_size;
}
@@ -190,7 +190,7 @@ find_best_ips_proto(struct ip_conntrack_tuple *tuple,
const struct ip_conntrack *conntrack,
enum ip_nat_manip_type maniptype)
{
- u_int32_t *var_ipp;
+ __be32 *var_ipp;
/* Host order */
u_int32_t minip, maxip, j;
@@ -217,7 +217,7 @@ find_best_ips_proto(struct ip_conntrack_tuple *tuple,
* like this), even across reboots. */
minip = ntohl(range->min_ip);
maxip = ntohl(range->max_ip);
- j = jhash_2words(tuple->src.ip, tuple->dst.ip, 0);
+ j = jhash_2words((__force u32)tuple->src.ip, (__force u32)tuple->dst.ip, 0);
*var_ipp = htonl(minip + j % (maxip - minip + 1));
}
@@ -534,9 +534,9 @@ int
ip_nat_port_range_to_nfattr(struct sk_buff *skb,
const struct ip_nat_range *range)
{
- NFA_PUT(skb, CTA_PROTONAT_PORT_MIN, sizeof(u_int16_t),
+ NFA_PUT(skb, CTA_PROTONAT_PORT_MIN, sizeof(__be16),
&range->min.tcp.port);
- NFA_PUT(skb, CTA_PROTONAT_PORT_MAX, sizeof(u_int16_t),
+ NFA_PUT(skb, CTA_PROTONAT_PORT_MAX, sizeof(__be16),
&range->max.tcp.port);
return 0;
@@ -555,7 +555,7 @@ ip_nat_port_nfattr_to_range(struct nfattr *tb[], struct ip_nat_range *range)
if (tb[CTA_PROTONAT_PORT_MIN-1]) {
ret = 1;
range->min.tcp.port =
- *(u_int16_t *)NFA_DATA(tb[CTA_PROTONAT_PORT_MIN-1]);
+ *(__be16 *)NFA_DATA(tb[CTA_PROTONAT_PORT_MIN-1]);
}
if (!tb[CTA_PROTONAT_PORT_MAX-1]) {
@@ -564,7 +564,7 @@ ip_nat_port_nfattr_to_range(struct nfattr *tb[], struct ip_nat_range *range)
} else {
ret = 1;
range->max.tcp.port =
- *(u_int16_t *)NFA_DATA(tb[CTA_PROTONAT_PORT_MAX-1]);
+ *(__be16 *)NFA_DATA(tb[CTA_PROTONAT_PORT_MAX-1]);
}
return ret;
diff --git a/net/ipv4/netfilter/ip_nat_ftp.c b/net/ipv4/netfilter/ip_nat_ftp.c
index 3328fc5c5f50..a71c233d8112 100644
--- a/net/ipv4/netfilter/ip_nat_ftp.c
+++ b/net/ipv4/netfilter/ip_nat_ftp.c
@@ -34,7 +34,7 @@ MODULE_DESCRIPTION("ftp NAT helper");
static int
mangle_rfc959_packet(struct sk_buff **pskb,
- u_int32_t newip,
+ __be32 newip,
u_int16_t port,
unsigned int matchoff,
unsigned int matchlen,
@@ -57,7 +57,7 @@ mangle_rfc959_packet(struct sk_buff **pskb,
/* |1|132.235.1.2|6275| */
static int
mangle_eprt_packet(struct sk_buff **pskb,
- u_int32_t newip,
+ __be32 newip,
u_int16_t port,
unsigned int matchoff,
unsigned int matchlen,
@@ -79,7 +79,7 @@ mangle_eprt_packet(struct sk_buff **pskb,
/* |1|132.235.1.2|6275| */
static int
mangle_epsv_packet(struct sk_buff **pskb,
- u_int32_t newip,
+ __be32 newip,
u_int16_t port,
unsigned int matchoff,
unsigned int matchlen,
@@ -98,7 +98,7 @@ mangle_epsv_packet(struct sk_buff **pskb,
matchlen, buffer, strlen(buffer));
}
-static int (*mangle[])(struct sk_buff **, u_int32_t, u_int16_t,
+static int (*mangle[])(struct sk_buff **, __be32, u_int16_t,
unsigned int,
unsigned int,
struct ip_conntrack *,
@@ -120,7 +120,7 @@ static unsigned int ip_nat_ftp(struct sk_buff **pskb,
struct ip_conntrack_expect *exp,
u32 *seq)
{
- u_int32_t newip;
+ __be32 newip;
u_int16_t port;
int dir = CTINFO2DIR(ctinfo);
struct ip_conntrack *ct = exp->master;
diff --git a/net/ipv4/netfilter/ip_nat_helper.c b/net/ipv4/netfilter/ip_nat_helper.c
index 7f6a75984f6c..3bf858480558 100644
--- a/net/ipv4/netfilter/ip_nat_helper.c
+++ b/net/ipv4/netfilter/ip_nat_helper.c
@@ -189,7 +189,7 @@ ip_nat_mangle_tcp_packet(struct sk_buff **pskb,
datalen, 0));
} else
tcph->check = nf_proto_csum_update(*pskb,
- htons(oldlen) ^ 0xFFFF,
+ htons(oldlen) ^ htons(0xFFFF),
htons(datalen),
tcph->check, 1);
@@ -267,7 +267,7 @@ ip_nat_mangle_udp_packet(struct sk_buff **pskb,
udph->check = -1;
} else
udph->check = nf_proto_csum_update(*pskb,
- htons(oldlen) ^ 0xFFFF,
+ htons(oldlen) ^ htons(0xFFFF),
htons(datalen),
udph->check, 1);
return 1;
@@ -283,27 +283,25 @@ sack_adjust(struct sk_buff *skb,
struct ip_nat_seq *natseq)
{
while (sackoff < sackend) {
- struct tcp_sack_block *sack;
- u_int32_t new_start_seq, new_end_seq;
+ struct tcp_sack_block_wire *sack;
+ __be32 new_start_seq, new_end_seq;
sack = (void *)skb->data + sackoff;
if (after(ntohl(sack->start_seq) - natseq->offset_before,
natseq->correction_pos))
- new_start_seq = ntohl(sack->start_seq)
- - natseq->offset_after;
+ new_start_seq = htonl(ntohl(sack->start_seq)
+ - natseq->offset_after);
else
- new_start_seq = ntohl(sack->start_seq)
- - natseq->offset_before;
- new_start_seq = htonl(new_start_seq);
+ new_start_seq = htonl(ntohl(sack->start_seq)
+ - natseq->offset_before);
if (after(ntohl(sack->end_seq) - natseq->offset_before,
natseq->correction_pos))
- new_end_seq = ntohl(sack->end_seq)
- - natseq->offset_after;
+ new_end_seq = htonl(ntohl(sack->end_seq)
+ - natseq->offset_after);
else
- new_end_seq = ntohl(sack->end_seq)
- - natseq->offset_before;
- new_end_seq = htonl(new_end_seq);
+ new_end_seq = htonl(ntohl(sack->end_seq)
+ - natseq->offset_before);
DEBUGP("sack_adjust: start_seq: %d->%d, end_seq: %d->%d\n",
ntohl(sack->start_seq), new_start_seq,
@@ -375,7 +373,8 @@ ip_nat_seq_adjust(struct sk_buff **pskb,
enum ip_conntrack_info ctinfo)
{
struct tcphdr *tcph;
- int dir, newseq, newack;
+ int dir;
+ __be32 newseq, newack;
struct ip_nat_seq *this_way, *other_way;
dir = CTINFO2DIR(ctinfo);
@@ -388,17 +387,15 @@ ip_nat_seq_adjust(struct sk_buff **pskb,
tcph = (void *)(*pskb)->data + (*pskb)->nh.iph->ihl*4;
if (after(ntohl(tcph->seq), this_way->correction_pos))
- newseq = ntohl(tcph->seq) + this_way->offset_after;
+ newseq = htonl(ntohl(tcph->seq) + this_way->offset_after);
else
- newseq = ntohl(tcph->seq) + this_way->offset_before;
- newseq = htonl(newseq);
+ newseq = htonl(ntohl(tcph->seq) + this_way->offset_before);
if (after(ntohl(tcph->ack_seq) - other_way->offset_before,
other_way->correction_pos))
- newack = ntohl(tcph->ack_seq) - other_way->offset_after;
+ newack = htonl(ntohl(tcph->ack_seq) - other_way->offset_after);
else
- newack = ntohl(tcph->ack_seq) - other_way->offset_before;
- newack = htonl(newack);
+ newack = htonl(ntohl(tcph->ack_seq) - other_way->offset_before);
tcph->check = nf_proto_csum_update(*pskb, ~tcph->seq, newseq,
tcph->check, 0);
diff --git a/net/ipv4/netfilter/ip_nat_helper_h323.c b/net/ipv4/netfilter/ip_nat_helper_h323.c
index 419b878fb467..4a7d34466ee2 100644
--- a/net/ipv4/netfilter/ip_nat_helper_h323.c
+++ b/net/ipv4/netfilter/ip_nat_helper_h323.c
@@ -32,13 +32,13 @@
/****************************************************************************/
static int set_addr(struct sk_buff **pskb,
unsigned char **data, int dataoff,
- unsigned int addroff, u_int32_t ip, u_int16_t port)
+ unsigned int addroff, __be32 ip, u_int16_t port)
{
enum ip_conntrack_info ctinfo;
struct ip_conntrack *ct = ip_conntrack_get(*pskb, &ctinfo);
struct {
- u_int32_t ip;
- u_int16_t port;
+ __be32 ip;
+ __be16 port;
} __attribute__ ((__packed__)) buf;
struct tcphdr _tcph, *th;
@@ -86,7 +86,7 @@ static int set_addr(struct sk_buff **pskb,
static int set_h225_addr(struct sk_buff **pskb,
unsigned char **data, int dataoff,
TransportAddress * addr,
- u_int32_t ip, u_int16_t port)
+ __be32 ip, u_int16_t port)
{
return set_addr(pskb, data, dataoff, addr->ipAddress.ip, ip, port);
}
@@ -95,7 +95,7 @@ static int set_h225_addr(struct sk_buff **pskb,
static int set_h245_addr(struct sk_buff **pskb,
unsigned char **data, int dataoff,
H245_TransportAddress * addr,
- u_int32_t ip, u_int16_t port)
+ __be32 ip, u_int16_t port)
{
return set_addr(pskb, data, dataoff,
addr->unicastAddress.iPAddress.network, ip, port);
@@ -110,7 +110,7 @@ static int set_sig_addr(struct sk_buff **pskb, struct ip_conntrack *ct,
struct ip_ct_h323_master *info = &ct->help.ct_h323_info;
int dir = CTINFO2DIR(ctinfo);
int i;
- u_int32_t ip;
+ __be32 ip;
u_int16_t port;
for (i = 0; i < count; i++) {
@@ -164,7 +164,7 @@ static int set_ras_addr(struct sk_buff **pskb, struct ip_conntrack *ct,
{
int dir = CTINFO2DIR(ctinfo);
int i;
- u_int32_t ip;
+ __be32 ip;
u_int16_t port;
for (i = 0; i < count; i++) {
@@ -433,7 +433,7 @@ static int nat_q931(struct sk_buff **pskb, struct ip_conntrack *ct,
struct ip_ct_h323_master *info = &ct->help.ct_h323_info;
int dir = CTINFO2DIR(ctinfo);
u_int16_t nated_port = port;
- u_int32_t ip;
+ __be32 ip;
/* Set expectations for NAT */
exp->saved_proto.tcp.port = exp->tuple.dst.u.tcp.port;
diff --git a/net/ipv4/netfilter/ip_nat_helper_pptp.c b/net/ipv4/netfilter/ip_nat_helper_pptp.c
index 2ff578807123..329fdcd7d702 100644
--- a/net/ipv4/netfilter/ip_nat_helper_pptp.c
+++ b/net/ipv4/netfilter/ip_nat_helper_pptp.c
@@ -51,7 +51,7 @@
#define IP_NAT_PPTP_VERSION "3.0"
-#define REQ_CID(req, off) (*(u_int16_t *)((char *)(req) + (off)))
+#define REQ_CID(req, off) (*(__be16 *)((char *)(req) + (off)))
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Harald Welte <laforge@gnumonks.org>");
diff --git a/net/ipv4/netfilter/ip_nat_proto_icmp.c b/net/ipv4/netfilter/ip_nat_proto_icmp.c
index ec50cc295317..3f6efc13ac74 100644
--- a/net/ipv4/netfilter/ip_nat_proto_icmp.c
+++ b/net/ipv4/netfilter/ip_nat_proto_icmp.c
@@ -67,7 +67,7 @@ icmp_manip_pkt(struct sk_buff **pskb,
hdr = (struct icmphdr *)((*pskb)->data + hdroff);
hdr->checksum = nf_proto_csum_update(*pskb,
- hdr->un.echo.id ^ 0xFFFF,
+ hdr->un.echo.id ^ htons(0xFFFF),
tuple->src.u.icmp.id,
hdr->checksum, 0);
hdr->un.echo.id = tuple->src.u.icmp.id;
diff --git a/net/ipv4/netfilter/ip_nat_proto_tcp.c b/net/ipv4/netfilter/ip_nat_proto_tcp.c
index 72a6307bd2db..12deb13b93b1 100644
--- a/net/ipv4/netfilter/ip_nat_proto_tcp.c
+++ b/net/ipv4/netfilter/ip_nat_proto_tcp.c
@@ -24,7 +24,7 @@ tcp_in_range(const struct ip_conntrack_tuple *tuple,
const union ip_conntrack_manip_proto *min,
const union ip_conntrack_manip_proto *max)
{
- u_int16_t port;
+ __be16 port;
if (maniptype == IP_NAT_MANIP_SRC)
port = tuple->src.u.tcp.port;
@@ -42,7 +42,7 @@ tcp_unique_tuple(struct ip_conntrack_tuple *tuple,
const struct ip_conntrack *conntrack)
{
static u_int16_t port;
- u_int16_t *portptr;
+ __be16 *portptr;
unsigned int range_size, min, i;
if (maniptype == IP_NAT_MANIP_SRC)
@@ -93,8 +93,8 @@ tcp_manip_pkt(struct sk_buff **pskb,
struct iphdr *iph = (struct iphdr *)((*pskb)->data + iphdroff);
struct tcphdr *hdr;
unsigned int hdroff = iphdroff + iph->ihl*4;
- u32 oldip, newip;
- u16 *portptr, newport, oldport;
+ __be32 oldip, newip;
+ __be16 *portptr, newport, oldport;
int hdrsize = 8; /* TCP connection tracking guarantees this much */
/* this could be a inner header returned in icmp packet; in such
@@ -130,7 +130,7 @@ tcp_manip_pkt(struct sk_buff **pskb,
return 1;
hdr->check = nf_proto_csum_update(*pskb, ~oldip, newip, hdr->check, 1);
- hdr->check = nf_proto_csum_update(*pskb, oldport ^ 0xFFFF, newport,
+ hdr->check = nf_proto_csum_update(*pskb, oldport ^ htons(0xFFFF), newport,
hdr->check, 0);
return 1;
}
diff --git a/net/ipv4/netfilter/ip_nat_proto_udp.c b/net/ipv4/netfilter/ip_nat_proto_udp.c
index 5da196ae758c..4bbec7730d18 100644
--- a/net/ipv4/netfilter/ip_nat_proto_udp.c
+++ b/net/ipv4/netfilter/ip_nat_proto_udp.c
@@ -24,7 +24,7 @@ udp_in_range(const struct ip_conntrack_tuple *tuple,
const union ip_conntrack_manip_proto *min,
const union ip_conntrack_manip_proto *max)
{
- u_int16_t port;
+ __be16 port;
if (maniptype == IP_NAT_MANIP_SRC)
port = tuple->src.u.udp.port;
@@ -42,7 +42,7 @@ udp_unique_tuple(struct ip_conntrack_tuple *tuple,
const struct ip_conntrack *conntrack)
{
static u_int16_t port;
- u_int16_t *portptr;
+ __be16 *portptr;
unsigned int range_size, min, i;
if (maniptype == IP_NAT_MANIP_SRC)
@@ -91,8 +91,8 @@ udp_manip_pkt(struct sk_buff **pskb,
struct iphdr *iph = (struct iphdr *)((*pskb)->data + iphdroff);
struct udphdr *hdr;
unsigned int hdroff = iphdroff + iph->ihl*4;
- u32 oldip, newip;
- u16 *portptr, newport;
+ __be32 oldip, newip;
+ __be16 *portptr, newport;
if (!skb_make_writable(pskb, hdroff + sizeof(*hdr)))
return 0;
@@ -118,7 +118,7 @@ udp_manip_pkt(struct sk_buff **pskb,
hdr->check = nf_proto_csum_update(*pskb, ~oldip, newip,
hdr->check, 1);
hdr->check = nf_proto_csum_update(*pskb,
- *portptr ^ 0xFFFF, newport,
+ *portptr ^ htons(0xFFFF), newport,
hdr->check, 0);
if (!hdr->check)
hdr->check = -1;
diff --git a/net/ipv4/netfilter/ip_nat_rule.c b/net/ipv4/netfilter/ip_nat_rule.c
index 7b703839aa58..a176aa3031e0 100644
--- a/net/ipv4/netfilter/ip_nat_rule.c
+++ b/net/ipv4/netfilter/ip_nat_rule.c
@@ -119,7 +119,7 @@ static unsigned int ipt_snat_target(struct sk_buff **pskb,
}
/* Before 2.6.11 we did implicit source NAT if required. Warn about change. */
-static void warn_if_extra_mangle(u32 dstip, u32 srcip)
+static void warn_if_extra_mangle(__be32 dstip, __be32 srcip)
{
static int warned = 0;
struct flowi fl = { .nl_u = { .ip4_u = { .daddr = dstip } } };
@@ -205,7 +205,7 @@ alloc_null_binding(struct ip_conntrack *conntrack,
per-proto parts (hence not IP_NAT_RANGE_PROTO_SPECIFIED).
Use reply in case it's already been mangled (eg local packet).
*/
- u_int32_t ip
+ __be32 ip
= (HOOK2MANIP(hooknum) == IP_NAT_MANIP_SRC
? conntrack->tuplehash[IP_CT_DIR_REPLY].tuple.dst.ip
: conntrack->tuplehash[IP_CT_DIR_REPLY].tuple.src.ip);
@@ -222,7 +222,7 @@ alloc_null_binding_confirmed(struct ip_conntrack *conntrack,
struct ip_nat_info *info,
unsigned int hooknum)
{
- u_int32_t ip
+ __be32 ip
= (HOOK2MANIP(hooknum) == IP_NAT_MANIP_SRC
? conntrack->tuplehash[IP_CT_DIR_REPLY].tuple.dst.ip
: conntrack->tuplehash[IP_CT_DIR_REPLY].tuple.src.ip);
diff --git a/net/ipv4/netfilter/ip_nat_sip.c b/net/ipv4/netfilter/ip_nat_sip.c
index 6ffba63adca2..71fc2730a007 100644
--- a/net/ipv4/netfilter/ip_nat_sip.c
+++ b/net/ipv4/netfilter/ip_nat_sip.c
@@ -60,8 +60,8 @@ static unsigned int ip_nat_sip(struct sk_buff **pskb,
enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo);
char buffer[sizeof("nnn.nnn.nnn.nnn:nnnnn")];
unsigned int bufflen, dataoff;
- u_int32_t ip;
- u_int16_t port;
+ __be32 ip;
+ __be16 port;
dataoff = (*pskb)->nh.iph->ihl*4 + sizeof(struct udphdr);
@@ -159,7 +159,7 @@ static int mangle_content_len(struct sk_buff **pskb,
static unsigned int mangle_sdp(struct sk_buff **pskb,
enum ip_conntrack_info ctinfo,
struct ip_conntrack *ct,
- u_int32_t newip, u_int16_t port,
+ __be32 newip, u_int16_t port,
const char *dptr)
{
char buffer[sizeof("nnn.nnn.nnn.nnn")];
@@ -195,7 +195,7 @@ static unsigned int ip_nat_sdp(struct sk_buff **pskb,
{
struct ip_conntrack *ct = exp->master;
enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo);
- u_int32_t newip;
+ __be32 newip;
u_int16_t port;
DEBUGP("ip_nat_sdp():\n");
diff --git a/net/ipv4/netfilter/ip_nat_snmp_basic.c b/net/ipv4/netfilter/ip_nat_snmp_basic.c
index 18b7fbdccb61..168f45fa1898 100644
--- a/net/ipv4/netfilter/ip_nat_snmp_basic.c
+++ b/net/ipv4/netfilter/ip_nat_snmp_basic.c
@@ -1211,7 +1211,7 @@ static int snmp_translate(struct ip_conntrack *ct,
struct sk_buff **pskb)
{
struct iphdr *iph = (*pskb)->nh.iph;
- struct udphdr *udph = (struct udphdr *)((u_int32_t *)iph + iph->ihl);
+ struct udphdr *udph = (struct udphdr *)((__be32 *)iph + iph->ihl);
u_int16_t udplen = ntohs(udph->len);
u_int16_t paylen = udplen - sizeof(struct udphdr);
int dir = CTINFO2DIR(ctinfo);
diff --git a/net/ipv4/netfilter/ip_nat_standalone.c b/net/ipv4/netfilter/ip_nat_standalone.c
index 9c577db62047..021395b67463 100644
--- a/net/ipv4/netfilter/ip_nat_standalone.c
+++ b/net/ipv4/netfilter/ip_nat_standalone.c
@@ -191,7 +191,7 @@ ip_nat_in(unsigned int hooknum,
int (*okfn)(struct sk_buff *))
{
unsigned int ret;
- u_int32_t daddr = (*pskb)->nh.iph->daddr;
+ __be32 daddr = (*pskb)->nh.iph->daddr;
ret = ip_nat_fn(hooknum, pskb, in, out, okfn);
if (ret != NF_DROP && ret != NF_STOLEN
diff --git a/net/ipv4/netfilter/ipt_CLUSTERIP.c b/net/ipv4/netfilter/ipt_CLUSTERIP.c
index 41589665fc5d..7a29d6e7baa7 100644
--- a/net/ipv4/netfilter/ipt_CLUSTERIP.c
+++ b/net/ipv4/netfilter/ipt_CLUSTERIP.c
@@ -52,7 +52,7 @@ struct clusterip_config {
atomic_t entries; /* number of entries/rules
* referencing us */
- u_int32_t clusterip; /* the IP address */
+ __be32 clusterip; /* the IP address */
u_int8_t clustermac[ETH_ALEN]; /* the MAC address */
struct net_device *dev; /* device */
u_int16_t num_total_nodes; /* total number of nodes */
@@ -119,7 +119,7 @@ clusterip_config_entry_put(struct clusterip_config *c)
}
static struct clusterip_config *
-__clusterip_config_find(u_int32_t clusterip)
+__clusterip_config_find(__be32 clusterip)
{
struct list_head *pos;
@@ -136,7 +136,7 @@ __clusterip_config_find(u_int32_t clusterip)
}
static inline struct clusterip_config *
-clusterip_config_find_get(u_int32_t clusterip, int entry)
+clusterip_config_find_get(__be32 clusterip, int entry)
{
struct clusterip_config *c;
@@ -166,7 +166,7 @@ clusterip_config_init_nodelist(struct clusterip_config *c,
}
static struct clusterip_config *
-clusterip_config_init(struct ipt_clusterip_tgt_info *i, u_int32_t ip,
+clusterip_config_init(struct ipt_clusterip_tgt_info *i, __be32 ip,
struct net_device *dev)
{
struct clusterip_config *c;
@@ -387,7 +387,7 @@ checkentry(const char *tablename,
return 0;
}
- if (e->ip.dmsk.s_addr != 0xffffffff
+ if (e->ip.dmsk.s_addr != htonl(0xffffffff)
|| e->ip.dst.s_addr == 0) {
printk(KERN_ERR "CLUSTERIP: Please specify destination IP\n");
return 0;
@@ -476,9 +476,9 @@ static struct ipt_target clusterip_tgt = {
/* hardcoded for 48bit ethernet and 32bit ipv4 addresses */
struct arp_payload {
u_int8_t src_hw[ETH_ALEN];
- u_int32_t src_ip;
+ __be32 src_ip;
u_int8_t dst_hw[ETH_ALEN];
- u_int32_t dst_ip;
+ __be32 dst_ip;
} __attribute__ ((packed));
#ifdef CLUSTERIP_DEBUG
diff --git a/net/ipv4/netfilter/ipt_ECN.c b/net/ipv4/netfilter/ipt_ECN.c
index 23f9c7ebe7eb..12a818a2462f 100644
--- a/net/ipv4/netfilter/ipt_ECN.c
+++ b/net/ipv4/netfilter/ipt_ECN.c
@@ -28,7 +28,7 @@ static inline int
set_ect_ip(struct sk_buff **pskb, const struct ipt_ECN_info *einfo)
{
struct iphdr *iph = (*pskb)->nh.iph;
- u_int16_t oldtos;
+ __be16 oldtos;
if ((iph->tos & IPT_ECN_IP_MASK) != (einfo->ip_ect & IPT_ECN_IP_MASK)) {
if (!skb_make_writable(pskb, sizeof(struct iphdr)))
@@ -37,7 +37,7 @@ set_ect_ip(struct sk_buff **pskb, const struct ipt_ECN_info *einfo)
oldtos = iph->tos;
iph->tos &= ~IPT_ECN_IP_MASK;
iph->tos |= (einfo->ip_ect & IPT_ECN_IP_MASK);
- iph->check = nf_csum_update(oldtos ^ 0xFFFF, iph->tos,
+ iph->check = nf_csum_update(oldtos ^ htons(0xFFFF), iph->tos,
iph->check);
}
return 1;
@@ -48,7 +48,7 @@ static inline int
set_ect_tcp(struct sk_buff **pskb, const struct ipt_ECN_info *einfo)
{
struct tcphdr _tcph, *tcph;
- u_int16_t oldval;
+ __be16 oldval;
/* Not enought header? */
tcph = skb_header_pointer(*pskb, (*pskb)->nh.iph->ihl*4,
@@ -66,15 +66,15 @@ set_ect_tcp(struct sk_buff **pskb, const struct ipt_ECN_info *einfo)
return 0;
tcph = (void *)(*pskb)->nh.iph + (*pskb)->nh.iph->ihl*4;
- oldval = ((u_int16_t *)tcph)[6];
+ oldval = ((__be16 *)tcph)[6];
if (einfo->operation & IPT_ECN_OP_SET_ECE)
tcph->ece = einfo->proto.tcp.ece;
if (einfo->operation & IPT_ECN_OP_SET_CWR)
tcph->cwr = einfo->proto.tcp.cwr;
tcph->check = nf_proto_csum_update((*pskb),
- oldval ^ 0xFFFF,
- ((u_int16_t *)tcph)[6],
+ oldval ^ htons(0xFFFF),
+ ((__be16 *)tcph)[6],
tcph->check, 0);
return 1;
}
diff --git a/net/ipv4/netfilter/ipt_MASQUERADE.c b/net/ipv4/netfilter/ipt_MASQUERADE.c
index bc65168a3437..3dbfcfac8a84 100644
--- a/net/ipv4/netfilter/ipt_MASQUERADE.c
+++ b/net/ipv4/netfilter/ipt_MASQUERADE.c
@@ -70,7 +70,7 @@ masquerade_target(struct sk_buff **pskb,
const struct ip_nat_multi_range_compat *mr;
struct ip_nat_range newrange;
struct rtable *rt;
- u_int32_t newsrc;
+ __be32 newsrc;
IP_NF_ASSERT(hooknum == NF_IP_POST_ROUTING);
diff --git a/net/ipv4/netfilter/ipt_NETMAP.c b/net/ipv4/netfilter/ipt_NETMAP.c
index beb2914225ff..58a88f227108 100644
--- a/net/ipv4/netfilter/ipt_NETMAP.c
+++ b/net/ipv4/netfilter/ipt_NETMAP.c
@@ -58,7 +58,7 @@ target(struct sk_buff **pskb,
{
struct ip_conntrack *ct;
enum ip_conntrack_info ctinfo;
- u_int32_t new_ip, netmask;
+ __be32 new_ip, netmask;
const struct ip_nat_multi_range_compat *mr = targinfo;
struct ip_nat_range newrange;
diff --git a/net/ipv4/netfilter/ipt_REDIRECT.c b/net/ipv4/netfilter/ipt_REDIRECT.c
index f03d43671c6d..c0dcfe9d610c 100644
--- a/net/ipv4/netfilter/ipt_REDIRECT.c
+++ b/net/ipv4/netfilter/ipt_REDIRECT.c
@@ -61,7 +61,7 @@ redirect_target(struct sk_buff **pskb,
{
struct ip_conntrack *ct;
enum ip_conntrack_info ctinfo;
- u_int32_t newdst;
+ __be32 newdst;
const struct ip_nat_multi_range_compat *mr = targinfo;
struct ip_nat_range newrange;
diff --git a/net/ipv4/netfilter/ipt_REJECT.c b/net/ipv4/netfilter/ipt_REJECT.c
index b81821edd893..fd0c05efed8a 100644
--- a/net/ipv4/netfilter/ipt_REJECT.c
+++ b/net/ipv4/netfilter/ipt_REJECT.c
@@ -104,8 +104,8 @@ static void send_reset(struct sk_buff *oldskb, int hook)
struct iphdr *iph = oldskb->nh.iph;
struct tcphdr _otcph, *oth, *tcph;
struct rtable *rt;
- u_int16_t tmp_port;
- u_int32_t tmp_addr;
+ __be16 tmp_port;
+ __be32 tmp_addr;
int needs_ack;
int hh_len;
diff --git a/net/ipv4/netfilter/ipt_SAME.c b/net/ipv4/netfilter/ipt_SAME.c
index efbcb1198832..b38b13328d73 100644
--- a/net/ipv4/netfilter/ipt_SAME.c
+++ b/net/ipv4/netfilter/ipt_SAME.c
@@ -135,7 +135,8 @@ same_target(struct sk_buff **pskb,
{
struct ip_conntrack *ct;
enum ip_conntrack_info ctinfo;
- u_int32_t tmpip, aindex, new_ip;
+ u_int32_t tmpip, aindex;
+ __be32 new_ip;
const struct ipt_same_info *same = targinfo;
struct ip_nat_range newrange;
const struct ip_conntrack_tuple *t;
diff --git a/net/ipv4/netfilter/ipt_TCPMSS.c b/net/ipv4/netfilter/ipt_TCPMSS.c
index 4246c4321e5b..108b6b76311f 100644
--- a/net/ipv4/netfilter/ipt_TCPMSS.c
+++ b/net/ipv4/netfilter/ipt_TCPMSS.c
@@ -42,7 +42,8 @@ ipt_tcpmss_target(struct sk_buff **pskb,
const struct ipt_tcpmss_info *tcpmssinfo = targinfo;
struct tcphdr *tcph;
struct iphdr *iph;
- u_int16_t tcplen, newtotlen, oldval, newmss;
+ u_int16_t tcplen, newmss;
+ __be16 newtotlen, oldval;
unsigned int i;
u_int8_t *opt;
@@ -97,7 +98,7 @@ ipt_tcpmss_target(struct sk_buff **pskb,
opt[i+3] = (newmss & 0x00ff);
tcph->check = nf_proto_csum_update(*pskb,
- htons(oldmss)^0xFFFF,
+ htons(oldmss)^htons(0xFFFF),
htons(newmss),
tcph->check, 0);
return IPT_CONTINUE;
@@ -126,7 +127,7 @@ ipt_tcpmss_target(struct sk_buff **pskb,
memmove(opt + TCPOLEN_MSS, opt, tcplen - sizeof(struct tcphdr));
tcph->check = nf_proto_csum_update(*pskb,
- htons(tcplen) ^ 0xFFFF,
+ htons(tcplen) ^ htons(0xFFFF),
htons(tcplen + TCPOLEN_MSS),
tcph->check, 1);
opt[0] = TCPOPT_MSS;
@@ -134,18 +135,18 @@ ipt_tcpmss_target(struct sk_buff **pskb,
opt[2] = (newmss & 0xff00) >> 8;
opt[3] = (newmss & 0x00ff);
- tcph->check = nf_proto_csum_update(*pskb, ~0, *((u_int32_t *)opt),
+ tcph->check = nf_proto_csum_update(*pskb, htonl(~0), *((__be32 *)opt),
tcph->check, 0);
- oldval = ((u_int16_t *)tcph)[6];
+ oldval = ((__be16 *)tcph)[6];
tcph->doff += TCPOLEN_MSS/4;
tcph->check = nf_proto_csum_update(*pskb,
- oldval ^ 0xFFFF,
- ((u_int16_t *)tcph)[6],
+ oldval ^ htons(0xFFFF),
+ ((__be16 *)tcph)[6],
tcph->check, 0);
newtotlen = htons(ntohs(iph->tot_len) + TCPOLEN_MSS);
- iph->check = nf_csum_update(iph->tot_len ^ 0xFFFF,
+ iph->check = nf_csum_update(iph->tot_len ^ htons(0xFFFF),
newtotlen, iph->check);
iph->tot_len = newtotlen;
return IPT_CONTINUE;
diff --git a/net/ipv4/netfilter/ipt_TOS.c b/net/ipv4/netfilter/ipt_TOS.c
index 471a4c438b0a..6b8b14ccc3d3 100644
--- a/net/ipv4/netfilter/ipt_TOS.c
+++ b/net/ipv4/netfilter/ipt_TOS.c
@@ -30,7 +30,7 @@ target(struct sk_buff **pskb,
{
const struct ipt_tos_target_info *tosinfo = targinfo;
struct iphdr *iph = (*pskb)->nh.iph;
- u_int16_t oldtos;
+ __be16 oldtos;
if ((iph->tos & IPTOS_TOS_MASK) != tosinfo->tos) {
if (!skb_make_writable(pskb, sizeof(struct iphdr)))
@@ -38,7 +38,7 @@ target(struct sk_buff **pskb,
iph = (*pskb)->nh.iph;
oldtos = iph->tos;
iph->tos = (iph->tos & IPTOS_PREC_MASK) | tosinfo->tos;
- iph->check = nf_csum_update(oldtos ^ 0xFFFF, iph->tos,
+ iph->check = nf_csum_update(oldtos ^ htons(0xFFFF), iph->tos,
iph->check);
}
return IPT_CONTINUE;
diff --git a/net/ipv4/netfilter/ipt_TTL.c b/net/ipv4/netfilter/ipt_TTL.c
index 96e79cc6d0f2..ac9517d62af0 100644
--- a/net/ipv4/netfilter/ipt_TTL.c
+++ b/net/ipv4/netfilter/ipt_TTL.c
@@ -54,8 +54,8 @@ ipt_ttl_target(struct sk_buff **pskb,
}
if (new_ttl != iph->ttl) {
- iph->check = nf_csum_update(ntohs((iph->ttl << 8)) ^ 0xFFFF,
- ntohs(new_ttl << 8),
+ iph->check = nf_csum_update(htons((iph->ttl << 8)) ^ htons(0xFFFF),
+ htons(new_ttl << 8),
iph->check);
iph->ttl = new_ttl;
}
diff --git a/net/ipv4/netfilter/ipt_addrtype.c b/net/ipv4/netfilter/ipt_addrtype.c
index 893dae210b04..7b60eb74788b 100644
--- a/net/ipv4/netfilter/ipt_addrtype.c
+++ b/net/ipv4/netfilter/ipt_addrtype.c
@@ -22,7 +22,7 @@ MODULE_LICENSE("GPL");
MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>");
MODULE_DESCRIPTION("iptables addrtype match");
-static inline int match_type(u_int32_t addr, u_int16_t mask)
+static inline int match_type(__be32 addr, u_int16_t mask)
{
return !!(mask & (1 << inet_addr_type(addr)));
}
diff --git a/net/ipv4/netfilter/ipt_hashlimit.c b/net/ipv4/netfilter/ipt_hashlimit.c
index 4f73a61aa3dd..33ccdbf8e794 100644
--- a/net/ipv4/netfilter/ipt_hashlimit.c
+++ b/net/ipv4/netfilter/ipt_hashlimit.c
@@ -50,11 +50,11 @@ static struct file_operations dl_file_ops;
/* hash table crap */
struct dsthash_dst {
- u_int32_t src_ip;
- u_int32_t dst_ip;
+ __be32 src_ip;
+ __be32 dst_ip;
/* ports have to be consecutive !!! */
- u_int16_t src_port;
- u_int16_t dst_port;
+ __be16 src_port;
+ __be16 dst_port;
};
struct dsthash_ent {
@@ -106,8 +106,10 @@ static inline int dst_cmp(const struct dsthash_ent *ent, struct dsthash_dst *b)
static inline u_int32_t
hash_dst(const struct ipt_hashlimit_htable *ht, const struct dsthash_dst *dst)
{
- return (jhash_3words(dst->dst_ip, (dst->dst_port<<16 | dst->src_port),
- dst->src_ip, ht->rnd) % ht->cfg.size);
+ return (jhash_3words((__force u32)dst->dst_ip,
+ ((__force u32)dst->dst_port<<16 |
+ (__force u32)dst->src_port),
+ (__force u32)dst->src_ip, ht->rnd) % ht->cfg.size);
}
static inline struct dsthash_ent *
@@ -406,7 +408,7 @@ hashlimit_match(const struct sk_buff *skb,
dst.src_ip = skb->nh.iph->saddr;
if (hinfo->cfg.mode & IPT_HASHLIMIT_HASH_DPT
||hinfo->cfg.mode & IPT_HASHLIMIT_HASH_SPT) {
- u_int16_t _ports[2], *ports;
+ __be16 _ports[2], *ports;
switch (skb->nh.iph->protocol) {
case IPPROTO_TCP:
diff --git a/net/ipv4/netfilter/ipt_recent.c b/net/ipv4/netfilter/ipt_recent.c
index 32ae8d7ac506..126db44e71a8 100644
--- a/net/ipv4/netfilter/ipt_recent.c
+++ b/net/ipv4/netfilter/ipt_recent.c
@@ -50,11 +50,10 @@ MODULE_PARM_DESC(ip_list_perms, "permissions on /proc/net/ipt_recent/* files");
MODULE_PARM_DESC(ip_list_uid,"owner of /proc/net/ipt_recent/* files");
MODULE_PARM_DESC(ip_list_gid,"owning group of /proc/net/ipt_recent/* files");
-
struct recent_entry {
struct list_head list;
struct list_head lru_list;
- u_int32_t addr;
+ __be32 addr;
u_int8_t ttl;
u_int8_t index;
u_int16_t nstamps;
@@ -85,17 +84,17 @@ static struct file_operations recent_fops;
static u_int32_t hash_rnd;
static int hash_rnd_initted;
-static unsigned int recent_entry_hash(u_int32_t addr)
+static unsigned int recent_entry_hash(__be32 addr)
{
if (!hash_rnd_initted) {
get_random_bytes(&hash_rnd, 4);
hash_rnd_initted = 1;
}
- return jhash_1word(addr, hash_rnd) & (ip_list_hash_size - 1);
+ return jhash_1word((__force u32)addr, hash_rnd) & (ip_list_hash_size - 1);
}
static struct recent_entry *
-recent_entry_lookup(const struct recent_table *table, u_int32_t addr, u_int8_t ttl)
+recent_entry_lookup(const struct recent_table *table, __be32 addr, u_int8_t ttl)
{
struct recent_entry *e;
unsigned int h;
@@ -116,7 +115,7 @@ static void recent_entry_remove(struct recent_table *t, struct recent_entry *e)
}
static struct recent_entry *
-recent_entry_init(struct recent_table *t, u_int32_t addr, u_int8_t ttl)
+recent_entry_init(struct recent_table *t, __be32 addr, u_int8_t ttl)
{
struct recent_entry *e;
@@ -178,7 +177,7 @@ ipt_recent_match(const struct sk_buff *skb,
const struct ipt_recent_info *info = matchinfo;
struct recent_table *t;
struct recent_entry *e;
- u_int32_t addr;
+ __be32 addr;
u_int8_t ttl;
int ret = info->invert;
@@ -406,7 +405,7 @@ static ssize_t recent_proc_write(struct file *file, const char __user *input,
struct recent_table *t = pde->data;
struct recent_entry *e;
char buf[sizeof("+255.255.255.255")], *c = buf;
- u_int32_t addr;
+ __be32 addr;
int add;
if (size > sizeof(buf))
diff --git a/net/ipv4/netfilter/iptable_mangle.c b/net/ipv4/netfilter/iptable_mangle.c
index 79336cb42527..e62ea2bb9c0a 100644
--- a/net/ipv4/netfilter/iptable_mangle.c
+++ b/net/ipv4/netfilter/iptable_mangle.c
@@ -131,7 +131,7 @@ ipt_local_hook(unsigned int hook,
{
unsigned int ret;
u_int8_t tos;
- u_int32_t saddr, daddr;
+ __be32 saddr, daddr;
unsigned long nfmark;
/* root is playing with raw sockets. */
diff --git a/net/ipv4/raw.c b/net/ipv4/raw.c
index 0e935b4c8741..b430cf2a4f66 100644
--- a/net/ipv4/raw.c
+++ b/net/ipv4/raw.c
@@ -381,8 +381,8 @@ static int raw_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
struct ipcm_cookie ipc;
struct rtable *rt = NULL;
int free = 0;
- u32 daddr;
- u32 saddr;
+ __be32 daddr;
+ __be32 saddr;
u8 tos;
int err;
diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index 20ffe8e88c0f..c41ddba02e9d 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -261,6 +261,10 @@ static unsigned int rt_hash_code(u32 daddr, u32 saddr)
& rt_hash_mask);
}
+#define rt_hash(daddr, saddr, idx) \
+ rt_hash_code((__force u32)(__be32)(daddr),\
+ (__force u32)(__be32)(saddr) ^ ((idx) << 5))
+
#ifdef CONFIG_PROC_FS
struct rt_cache_iter_state {
int bucket;
@@ -1074,7 +1078,7 @@ static void ip_select_fb_ident(struct iphdr *iph)
u32 salt;
spin_lock_bh(&ip_fb_id_lock);
- salt = secure_ip_id(ip_fallback_id ^ iph->daddr);
+ salt = secure_ip_id((__force __be32)ip_fallback_id ^ iph->daddr);
iph->id = htons(salt & 0xFFFF);
ip_fallback_id = salt;
spin_unlock_bh(&ip_fb_id_lock);
@@ -1118,13 +1122,13 @@ static void rt_del(unsigned hash, struct rtable *rt)
spin_unlock_bh(rt_hash_lock_addr(hash));
}
-void ip_rt_redirect(u32 old_gw, u32 daddr, u32 new_gw,
- u32 saddr, struct net_device *dev)
+void ip_rt_redirect(__be32 old_gw, __be32 daddr, __be32 new_gw,
+ __be32 saddr, struct net_device *dev)
{
int i, k;
struct in_device *in_dev = in_dev_get(dev);
struct rtable *rth, **rthp;
- u32 skeys[2] = { saddr, 0 };
+ __be32 skeys[2] = { saddr, 0 };
int ikeys[2] = { dev->ifindex, 0 };
struct netevent_redirect netevent;
@@ -1147,8 +1151,7 @@ void ip_rt_redirect(u32 old_gw, u32 daddr, u32 new_gw,
for (i = 0; i < 2; i++) {
for (k = 0; k < 2; k++) {
- unsigned hash = rt_hash_code(daddr,
- skeys[i] ^ (ikeys[k] << 5));
+ unsigned hash = rt_hash(daddr, skeys[i], ikeys[k]);
rthp=&rt_hash_table[hash].chain;
@@ -1260,9 +1263,8 @@ static struct dst_entry *ipv4_negative_advice(struct dst_entry *dst)
ret = NULL;
} else if ((rt->rt_flags & RTCF_REDIRECTED) ||
rt->u.dst.expires) {
- unsigned hash = rt_hash_code(rt->fl.fl4_dst,
- rt->fl.fl4_src ^
- (rt->fl.oif << 5));
+ unsigned hash = rt_hash(rt->fl.fl4_dst, rt->fl.fl4_src,
+ rt->fl.oif);
#if RT_CACHE_DEBUG >= 1
printk(KERN_DEBUG "ip_rt_advice: redirect to "
"%u.%u.%u.%u/%02x dropped\n",
@@ -1397,15 +1399,15 @@ unsigned short ip_rt_frag_needed(struct iphdr *iph, unsigned short new_mtu)
int i;
unsigned short old_mtu = ntohs(iph->tot_len);
struct rtable *rth;
- u32 skeys[2] = { iph->saddr, 0, };
- u32 daddr = iph->daddr;
+ __be32 skeys[2] = { iph->saddr, 0, };
+ __be32 daddr = iph->daddr;
unsigned short est_mtu = 0;
if (ipv4_config.no_pmtu_disc)
return 0;
for (i = 0; i < 2; i++) {
- unsigned hash = rt_hash_code(daddr, skeys[i]);
+ unsigned hash = rt_hash(daddr, skeys[i], 0);
rcu_read_lock();
for (rth = rcu_dereference(rt_hash_table[hash].chain); rth;
@@ -1530,7 +1532,7 @@ static int ip_rt_bug(struct sk_buff *skb)
void ip_rt_get_source(u8 *addr, struct rtable *rt)
{
- u32 src;
+ __be32 src;
struct fib_result res;
if (rt->fl.iif == 0)
@@ -1596,12 +1598,12 @@ static void rt_set_nexthop(struct rtable *rt, struct fib_result *res, u32 itag)
rt->rt_type = res->type;
}
-static int ip_route_input_mc(struct sk_buff *skb, u32 daddr, u32 saddr,
+static int ip_route_input_mc(struct sk_buff *skb, __be32 daddr, __be32 saddr,
u8 tos, struct net_device *dev, int our)
{
unsigned hash;
struct rtable *rth;
- u32 spec_dst;
+ __be32 spec_dst;
struct in_device *in_dev = in_dev_get(dev);
u32 itag = 0;
@@ -1665,7 +1667,7 @@ static int ip_route_input_mc(struct sk_buff *skb, u32 daddr, u32 saddr,
RT_CACHE_STAT_INC(in_slow_mc);
in_dev_put(in_dev);
- hash = rt_hash_code(daddr, saddr ^ (dev->ifindex << 5));
+ hash = rt_hash(daddr, saddr, dev->ifindex);
return rt_intern_hash(hash, rth, (struct rtable**) &skb->dst);
e_nobufs:
@@ -1681,8 +1683,8 @@ e_inval:
static void ip_handle_martian_source(struct net_device *dev,
struct in_device *in_dev,
struct sk_buff *skb,
- u32 daddr,
- u32 saddr)
+ __be32 daddr,
+ __be32 saddr)
{
RT_CACHE_STAT_INC(in_martian_src);
#ifdef CONFIG_IP_ROUTE_VERBOSE
@@ -1712,7 +1714,7 @@ static void ip_handle_martian_source(struct net_device *dev,
static inline int __mkroute_input(struct sk_buff *skb,
struct fib_result* res,
struct in_device *in_dev,
- u32 daddr, u32 saddr, u32 tos,
+ __be32 daddr, __be32 saddr, u32 tos,
struct rtable **result)
{
@@ -1720,7 +1722,8 @@ static inline int __mkroute_input(struct sk_buff *skb,
int err;
struct in_device *out_dev;
unsigned flags = 0;
- u32 spec_dst, itag;
+ __be32 spec_dst;
+ u32 itag;
/* get a working reference to the output device */
out_dev = in_dev_get(FIB_RES_DEV(*res));
@@ -1813,7 +1816,7 @@ static inline int ip_mkroute_input_def(struct sk_buff *skb,
struct fib_result* res,
const struct flowi *fl,
struct in_device *in_dev,
- u32 daddr, u32 saddr, u32 tos)
+ __be32 daddr, __be32 saddr, u32 tos)
{
struct rtable* rth = NULL;
int err;
@@ -1830,7 +1833,7 @@ static inline int ip_mkroute_input_def(struct sk_buff *skb,
return err;
/* put it into the cache */
- hash = rt_hash_code(daddr, saddr ^ (fl->iif << 5));
+ hash = rt_hash(daddr, saddr, fl->iif);
return rt_intern_hash(hash, rth, (struct rtable**)&skb->dst);
}
@@ -1838,7 +1841,7 @@ static inline int ip_mkroute_input(struct sk_buff *skb,
struct fib_result* res,
const struct flowi *fl,
struct in_device *in_dev,
- u32 daddr, u32 saddr, u32 tos)
+ __be32 daddr, __be32 saddr, u32 tos)
{
#ifdef CONFIG_IP_ROUTE_MULTIPATH_CACHED
struct rtable* rth = NULL, *rtres;
@@ -1871,7 +1874,7 @@ static inline int ip_mkroute_input(struct sk_buff *skb,
return err;
/* put it into the cache */
- hash = rt_hash_code(daddr, saddr ^ (fl->iif << 5));
+ hash = rt_hash(daddr, saddr, fl->iif);
err = rt_intern_hash(hash, rth, &rtres);
if (err)
return err;
@@ -1901,7 +1904,7 @@ static inline int ip_mkroute_input(struct sk_buff *skb,
* 2. IP spoofing attempts are filtered with 100% of guarantee.
*/
-static int ip_route_input_slow(struct sk_buff *skb, u32 daddr, u32 saddr,
+static int ip_route_input_slow(struct sk_buff *skb, __be32 daddr, __be32 saddr,
u8 tos, struct net_device *dev)
{
struct fib_result res;
@@ -1920,7 +1923,7 @@ static int ip_route_input_slow(struct sk_buff *skb, u32 daddr, u32 saddr,
u32 itag = 0;
struct rtable * rth;
unsigned hash;
- u32 spec_dst;
+ __be32 spec_dst;
int err = -EINVAL;
int free_res = 0;
@@ -1936,7 +1939,7 @@ static int ip_route_input_slow(struct sk_buff *skb, u32 daddr, u32 saddr,
if (MULTICAST(saddr) || BADCLASS(saddr) || LOOPBACK(saddr))
goto martian_source;
- if (daddr == 0xFFFFFFFF || (saddr == 0 && daddr == 0))
+ if (daddr == htonl(0xFFFFFFFF) || (saddr == 0 && daddr == 0))
goto brd_input;
/* Accept zero addresses only to limited broadcast;
@@ -2048,7 +2051,7 @@ local_input:
rth->rt_flags &= ~RTCF_LOCAL;
}
rth->rt_type = res.type;
- hash = rt_hash_code(daddr, saddr ^ (fl.iif << 5));
+ hash = rt_hash(daddr, saddr, fl.iif);
err = rt_intern_hash(hash, rth, (struct rtable**)&skb->dst);
goto done;
@@ -2087,7 +2090,7 @@ martian_source:
goto e_inval;
}
-int ip_route_input(struct sk_buff *skb, u32 daddr, u32 saddr,
+int ip_route_input(struct sk_buff *skb, __be32 daddr, __be32 saddr,
u8 tos, struct net_device *dev)
{
struct rtable * rth;
@@ -2095,7 +2098,7 @@ int ip_route_input(struct sk_buff *skb, u32 daddr, u32 saddr,
int iif = dev->ifindex;
tos &= IPTOS_RT_MASK;
- hash = rt_hash_code(daddr, saddr ^ (iif << 5));
+ hash = rt_hash(daddr, saddr, iif);
rcu_read_lock();
for (rth = rcu_dereference(rt_hash_table[hash].chain); rth;
@@ -2169,7 +2172,7 @@ static inline int __mkroute_output(struct rtable **result,
if (LOOPBACK(fl->fl4_src) && !(dev_out->flags&IFF_LOOPBACK))
return -EINVAL;
- if (fl->fl4_dst == 0xFFFFFFFF)
+ if (fl->fl4_dst == htonl(0xFFFFFFFF))
res->type = RTN_BROADCAST;
else if (MULTICAST(fl->fl4_dst))
res->type = RTN_MULTICAST;
@@ -2293,8 +2296,7 @@ static inline int ip_mkroute_output_def(struct rtable **rp,
int err = __mkroute_output(&rth, res, fl, oldflp, dev_out, flags);
unsigned hash;
if (err == 0) {
- hash = rt_hash_code(oldflp->fl4_dst,
- oldflp->fl4_src ^ (oldflp->oif << 5));
+ hash = rt_hash(oldflp->fl4_dst, oldflp->fl4_src, oldflp->oif);
err = rt_intern_hash(hash, rth, rp);
}
@@ -2336,9 +2338,8 @@ static inline int ip_mkroute_output(struct rtable** rp,
if (err != 0)
goto cleanup;
- hash = rt_hash_code(oldflp->fl4_dst,
- oldflp->fl4_src ^
- (oldflp->oif << 5));
+ hash = rt_hash(oldflp->fl4_dst, oldflp->fl4_src,
+ oldflp->oif);
err = rt_intern_hash(hash, rth, rp);
/* forward hop information to multipath impl. */
@@ -2417,7 +2418,7 @@ static int ip_route_output_slow(struct rtable **rp, const struct flowi *oldflp)
*/
if (oldflp->oif == 0
- && (MULTICAST(oldflp->fl4_dst) || oldflp->fl4_dst == 0xFFFFFFFF)) {
+ && (MULTICAST(oldflp->fl4_dst) || oldflp->fl4_dst == htonl(0xFFFFFFFF))) {
/* Special hack: user can direct multicasts
and limited broadcast via necessary interface
without fiddling with IP_MULTICAST_IF or IP_PKTINFO.
@@ -2454,7 +2455,7 @@ static int ip_route_output_slow(struct rtable **rp, const struct flowi *oldflp)
goto out; /* Wrong error code */
}
- if (LOCAL_MCAST(oldflp->fl4_dst) || oldflp->fl4_dst == 0xFFFFFFFF) {
+ if (LOCAL_MCAST(oldflp->fl4_dst) || oldflp->fl4_dst == htonl(0xFFFFFFFF)) {
if (!fl.fl4_src)
fl.fl4_src = inet_select_addr(dev_out, 0,
RT_SCOPE_LINK);
@@ -2567,7 +2568,7 @@ int __ip_route_output_key(struct rtable **rp, const struct flowi *flp)
unsigned hash;
struct rtable *rth;
- hash = rt_hash_code(flp->fl4_dst, flp->fl4_src ^ (flp->oif << 5));
+ hash = rt_hash(flp->fl4_dst, flp->fl4_src, flp->oif);
rcu_read_lock_bh();
for (rth = rcu_dereference(rt_hash_table[hash].chain); rth;
@@ -2660,11 +2661,11 @@ static int rt_fill_info(struct sk_buff *skb, u32 pid, u32 seq, int event,
if (rt->rt_flags & RTCF_NOTIFY)
r->rtm_flags |= RTM_F_NOTIFY;
- NLA_PUT_U32(skb, RTA_DST, rt->rt_dst);
+ NLA_PUT_BE32(skb, RTA_DST, rt->rt_dst);
if (rt->fl.fl4_src) {
r->rtm_src_len = 32;
- NLA_PUT_U32(skb, RTA_SRC, rt->fl.fl4_src);
+ NLA_PUT_BE32(skb, RTA_SRC, rt->fl.fl4_src);
}
if (rt->u.dst.dev)
NLA_PUT_U32(skb, RTA_OIF, rt->u.dst.dev->ifindex);
@@ -2677,12 +2678,12 @@ static int rt_fill_info(struct sk_buff *skb, u32 pid, u32 seq, int event,
NLA_PUT_U32(skb, RTA_MP_ALGO, rt->rt_multipath_alg);
#endif
if (rt->fl.iif)
- NLA_PUT_U32(skb, RTA_PREFSRC, rt->rt_spec_dst);
+ NLA_PUT_BE32(skb, RTA_PREFSRC, rt->rt_spec_dst);
else if (rt->rt_src != rt->fl.fl4_src)
- NLA_PUT_U32(skb, RTA_PREFSRC, rt->rt_src);
+ NLA_PUT_BE32(skb, RTA_PREFSRC, rt->rt_src);
if (rt->rt_dst != rt->rt_gateway)
- NLA_PUT_U32(skb, RTA_GATEWAY, rt->rt_gateway);
+ NLA_PUT_BE32(skb, RTA_GATEWAY, rt->rt_gateway);
if (rtnetlink_put_metrics(skb, rt->u.dst.metrics) < 0)
goto nla_put_failure;
@@ -2706,7 +2707,7 @@ static int rt_fill_info(struct sk_buff *skb, u32 pid, u32 seq, int event,
if (rt->fl.iif) {
#ifdef CONFIG_IP_MROUTE
- u32 dst = rt->rt_dst;
+ __be32 dst = rt->rt_dst;
if (MULTICAST(dst) && !LOCAL_MCAST(dst) &&
ipv4_devconf.mc_forwarding) {
@@ -2740,7 +2741,9 @@ int inet_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr* nlh, void *arg)
struct rtmsg *rtm;
struct nlattr *tb[RTA_MAX+1];
struct rtable *rt = NULL;
- u32 dst, src, iif;
+ __be32 dst = 0;
+ __be32 src = 0;
+ u32 iif;
int err;
struct sk_buff *skb;
@@ -2765,8 +2768,8 @@ int inet_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr* nlh, void *arg)
skb->nh.iph->protocol = IPPROTO_ICMP;
skb_reserve(skb, MAX_HEADER + sizeof(struct iphdr));
- src = tb[RTA_SRC] ? nla_get_u32(tb[RTA_SRC]) : 0;
- dst = tb[RTA_DST] ? nla_get_u32(tb[RTA_DST]) : 0;
+ src = tb[RTA_SRC] ? nla_get_be32(tb[RTA_SRC]) : 0;
+ dst = tb[RTA_DST] ? nla_get_be32(tb[RTA_DST]) : 0;
iif = tb[RTA_IIF] ? nla_get_u32(tb[RTA_IIF]) : 0;
if (iif) {
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index b3def0df14fb..3f884cea14ff 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -935,7 +935,7 @@ tcp_sacktag_write_queue(struct sock *sk, struct sk_buff *ack_skb, u32 prior_snd_
const struct inet_connection_sock *icsk = inet_csk(sk);
struct tcp_sock *tp = tcp_sk(sk);
unsigned char *ptr = ack_skb->h.raw + TCP_SKB_CB(ack_skb)->sacked;
- struct tcp_sack_block *sp = (struct tcp_sack_block *)(ptr+2);
+ struct tcp_sack_block_wire *sp = (struct tcp_sack_block_wire *)(ptr+2);
int num_sacks = (ptr[1] - TCPOLEN_SACK_BASE)>>3;
int reord = tp->packets_out;
int prior_fackets;
@@ -2239,13 +2239,12 @@ static int tcp_tso_acked(struct sock *sk, struct sk_buff *skb,
return acked;
}
-static u32 tcp_usrtt(const struct sk_buff *skb)
+static u32 tcp_usrtt(struct timeval *tv)
{
- struct timeval tv, now;
+ struct timeval now;
do_gettimeofday(&now);
- skb_get_timestamp(skb, &tv);
- return (now.tv_sec - tv.tv_sec) * 1000000 + (now.tv_usec - tv.tv_usec);
+ return (now.tv_sec - tv->tv_sec) * 1000000 + (now.tv_usec - tv->tv_usec);
}
/* Remove acknowledged frames from the retransmission queue. */
@@ -2260,6 +2259,7 @@ static int tcp_clean_rtx_queue(struct sock *sk, __s32 *seq_rtt_p)
u32 pkts_acked = 0;
void (*rtt_sample)(struct sock *sk, u32 usrtt)
= icsk->icsk_ca_ops->rtt_sample;
+ struct timeval tv;
while ((skb = skb_peek(&sk->sk_write_queue)) &&
skb != sk->sk_send_head) {
@@ -2308,8 +2308,7 @@ static int tcp_clean_rtx_queue(struct sock *sk, __s32 *seq_rtt_p)
seq_rtt = -1;
} else if (seq_rtt < 0) {
seq_rtt = now - scb->when;
- if (rtt_sample)
- (*rtt_sample)(sk, tcp_usrtt(skb));
+ skb_get_timestamp(skb, &tv);
}
if (sacked & TCPCB_SACKED_ACKED)
tp->sacked_out -= tcp_skb_pcount(skb);
@@ -2322,8 +2321,7 @@ static int tcp_clean_rtx_queue(struct sock *sk, __s32 *seq_rtt_p)
}
} else if (seq_rtt < 0) {
seq_rtt = now - scb->when;
- if (rtt_sample)
- (*rtt_sample)(sk, tcp_usrtt(skb));
+ skb_get_timestamp(skb, &tv);
}
tcp_dec_pcount_approx(&tp->fackets_out, skb);
tcp_packets_out_dec(tp, skb);
@@ -2335,6 +2333,8 @@ static int tcp_clean_rtx_queue(struct sock *sk, __s32 *seq_rtt_p)
if (acked&FLAG_ACKED) {
tcp_ack_update_rtt(sk, acked, seq_rtt);
tcp_ack_packets_out(sk, tp);
+ if (rtt_sample && !(acked & FLAG_RETRANS_DATA_ACKED))
+ (*rtt_sample)(sk, tcp_usrtt(&tv));
if (icsk->icsk_ca_ops->pkts_acked)
icsk->icsk_ca_ops->pkts_acked(sk, pkts_acked);
@@ -2629,7 +2629,7 @@ void tcp_parse_options(struct sk_buff *skb, struct tcp_options_received *opt_rx,
switch(opcode) {
case TCPOPT_MSS:
if(opsize==TCPOLEN_MSS && th->syn && !estab) {
- u16 in_mss = ntohs(get_unaligned((__u16 *)ptr));
+ u16 in_mss = ntohs(get_unaligned((__be16 *)ptr));
if (in_mss) {
if (opt_rx->user_mss && opt_rx->user_mss < in_mss)
in_mss = opt_rx->user_mss;
@@ -2657,8 +2657,8 @@ void tcp_parse_options(struct sk_buff *skb, struct tcp_options_received *opt_rx,
if ((estab && opt_rx->tstamp_ok) ||
(!estab && sysctl_tcp_timestamps)) {
opt_rx->saw_tstamp = 1;
- opt_rx->rcv_tsval = ntohl(get_unaligned((__u32 *)ptr));
- opt_rx->rcv_tsecr = ntohl(get_unaligned((__u32 *)(ptr+4)));
+ opt_rx->rcv_tsval = ntohl(get_unaligned((__be32 *)ptr));
+ opt_rx->rcv_tsecr = ntohl(get_unaligned((__be32 *)(ptr+4)));
}
}
break;
@@ -2695,8 +2695,8 @@ static int tcp_fast_parse_options(struct sk_buff *skb, struct tcphdr *th,
return 0;
} else if (tp->rx_opt.tstamp_ok &&
th->doff == (sizeof(struct tcphdr)>>2)+(TCPOLEN_TSTAMP_ALIGNED>>2)) {
- __u32 *ptr = (__u32 *)(th + 1);
- if (*ptr == ntohl((TCPOPT_NOP << 24) | (TCPOPT_NOP << 16)
+ __be32 *ptr = (__be32 *)(th + 1);
+ if (*ptr == htonl((TCPOPT_NOP << 24) | (TCPOPT_NOP << 16)
| (TCPOPT_TIMESTAMP << 8) | TCPOLEN_TIMESTAMP)) {
tp->rx_opt.saw_tstamp = 1;
++ptr;
@@ -3911,10 +3911,10 @@ int tcp_rcv_established(struct sock *sk, struct sk_buff *skb,
/* Check timestamp */
if (tcp_header_len == sizeof(struct tcphdr) + TCPOLEN_TSTAMP_ALIGNED) {
- __u32 *ptr = (__u32 *)(th + 1);
+ __be32 *ptr = (__be32 *)(th + 1);
/* No? Slow path! */
- if (*ptr != ntohl((TCPOPT_NOP << 24) | (TCPOPT_NOP << 16)
+ if (*ptr != htonl((TCPOPT_NOP << 24) | (TCPOPT_NOP << 16)
| (TCPOPT_TIMESTAMP << 8) | TCPOLEN_TIMESTAMP))
goto slow_path;
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
index 39b179856082..c83938b8fcb1 100644
--- a/net/ipv4/tcp_ipv4.c
+++ b/net/ipv4/tcp_ipv4.c
@@ -159,7 +159,7 @@ int tcp_v4_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len)
struct tcp_sock *tp = tcp_sk(sk);
struct sockaddr_in *usin = (struct sockaddr_in *)uaddr;
struct rtable *rt;
- u32 daddr, nexthop;
+ __be32 daddr, nexthop;
int tmp;
int err;
@@ -734,8 +734,8 @@ int tcp_v4_conn_request(struct sock *sk, struct sk_buff *skb)
struct inet_request_sock *ireq;
struct tcp_options_received tmp_opt;
struct request_sock *req;
- __u32 saddr = skb->nh.iph->saddr;
- __u32 daddr = skb->nh.iph->daddr;
+ __be32 saddr = skb->nh.iph->saddr;
+ __be32 daddr = skb->nh.iph->daddr;
__u32 isn = TCP_SKB_CB(skb)->when;
struct dst_entry *dst = NULL;
#ifdef CONFIG_SYN_COOKIES
@@ -1763,7 +1763,7 @@ static void get_tcp4_sock(struct sock *sp, char *tmpbuf, int i)
static void get_timewait4_sock(struct inet_timewait_sock *tw, char *tmpbuf, int i)
{
- unsigned int dest, src;
+ __be32 dest, src;
__u16 destp, srcp;
int ttd = tw->tw_ttd - jiffies;
diff --git a/net/ipv4/tcp_lp.c b/net/ipv4/tcp_lp.c
index 308fb7e071c5..f0ebaf0e21cb 100644
--- a/net/ipv4/tcp_lp.c
+++ b/net/ipv4/tcp_lp.c
@@ -31,8 +31,6 @@
* Hung Hing Lun, Mike <hlhung3i@gmail.com>
* SourceForge project page:
* http://tcp-lp-mod.sourceforge.net/
- *
- * Version: $Id: tcp_lp.c,v 1.24 2006/09/05 20:22:53 hswong3i Exp $
*/
#include <linux/module.h>
@@ -164,7 +162,7 @@ static u32 tcp_lp_remote_hz_estimator(struct sock *sk)
out:
/* record time for successful remote HZ calc */
- if (rhz > 0)
+ if ((rhz >> 6) > 0)
lp->flag |= LP_VALID_RHZ;
else
lp->flag &= ~LP_VALID_RHZ;
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
index 061edfae0c29..9a253faefc81 100644
--- a/net/ipv4/tcp_output.c
+++ b/net/ipv4/tcp_output.c
@@ -269,7 +269,7 @@ static u16 tcp_select_window(struct sock *sk)
return new_win;
}
-static void tcp_build_and_update_options(__u32 *ptr, struct tcp_sock *tp,
+static void tcp_build_and_update_options(__be32 *ptr, struct tcp_sock *tp,
__u32 tstamp)
{
if (tp->rx_opt.tstamp_ok) {
@@ -305,7 +305,7 @@ static void tcp_build_and_update_options(__u32 *ptr, struct tcp_sock *tp,
* MAX_SYN_SIZE to match the new maximum number of options that you
* can generate.
*/
-static void tcp_syn_build_options(__u32 *ptr, int mss, int ts, int sack,
+static void tcp_syn_build_options(__be32 *ptr, int mss, int ts, int sack,
int offer_wscale, int wscale, __u32 tstamp,
__u32 ts_recent)
{
@@ -424,7 +424,7 @@ static int tcp_transmit_skb(struct sock *sk, struct sk_buff *skb, int clone_it,
th->dest = inet->dport;
th->seq = htonl(tcb->seq);
th->ack_seq = htonl(tp->rcv_nxt);
- *(((__u16 *)th) + 6) = htons(((tcp_header_size >> 2) << 12) |
+ *(((__be16 *)th) + 6) = htons(((tcp_header_size >> 2) << 12) |
tcb->flags);
if (unlikely(tcb->flags & TCPCB_FLAG_SYN)) {
@@ -445,7 +445,7 @@ static int tcp_transmit_skb(struct sock *sk, struct sk_buff *skb, int clone_it,
}
if (unlikely(tcb->flags & TCPCB_FLAG_SYN)) {
- tcp_syn_build_options((__u32 *)(th + 1),
+ tcp_syn_build_options((__be32 *)(th + 1),
tcp_advertise_mss(sk),
(sysctl_flags & SYSCTL_FLAG_TSTAMPS),
(sysctl_flags & SYSCTL_FLAG_SACK),
@@ -454,7 +454,7 @@ static int tcp_transmit_skb(struct sock *sk, struct sk_buff *skb, int clone_it,
tcb->when,
tp->rx_opt.ts_recent);
} else {
- tcp_build_and_update_options((__u32 *)(th + 1),
+ tcp_build_and_update_options((__be32 *)(th + 1),
tp, tcb->when);
TCP_ECN_send(sk, tp, skb, tcp_header_size);
}
@@ -2070,7 +2070,7 @@ struct sk_buff * tcp_make_synack(struct sock *sk, struct dst_entry *dst,
th->window = htons(req->rcv_wnd);
TCP_SKB_CB(skb)->when = tcp_time_stamp;
- tcp_syn_build_options((__u32 *)(th + 1), dst_metric(dst, RTAX_ADVMSS), ireq->tstamp_ok,
+ tcp_syn_build_options((__be32 *)(th + 1), dst_metric(dst, RTAX_ADVMSS), ireq->tstamp_ok,
ireq->sack_ok, ireq->wscale_ok, ireq->rcv_wscale,
TCP_SKB_CB(skb)->when,
req->ts_recent);
diff --git a/net/ipv4/tcp_probe.c b/net/ipv4/tcp_probe.c
index dab37d2f65fc..4be336f17883 100644
--- a/net/ipv4/tcp_probe.c
+++ b/net/ipv4/tcp_probe.c
@@ -99,8 +99,10 @@ static int jtcp_sendmsg(struct kiocb *iocb, struct sock *sk,
}
static struct jprobe tcp_send_probe = {
- .kp = { .addr = (kprobe_opcode_t *) &tcp_sendmsg, },
- .entry = (kprobe_opcode_t *) &jtcp_sendmsg,
+ .kp = {
+ .symbol_name = "tcp_sendmsg",
+ },
+ .entry = JPROBE_ENTRY(jtcp_sendmsg),
};
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
index 77e265d7bb8f..6d6142f9c478 100644
--- a/net/ipv4/udp.c
+++ b/net/ipv4/udp.c
@@ -243,8 +243,8 @@ static void udp_v4_unhash(struct sock *sk)
/* UDP is nearly always wildcards out the wazoo, it makes no sense to try
* harder than this. -DaveM
*/
-static struct sock *udp_v4_lookup_longway(u32 saddr, u16 sport,
- u32 daddr, u16 dport, int dif)
+static struct sock *udp_v4_lookup_longway(__be32 saddr, __be16 sport,
+ __be32 daddr, __be16 dport, int dif)
{
struct sock *sk, *result = NULL;
struct hlist_node *node;
@@ -288,8 +288,8 @@ static struct sock *udp_v4_lookup_longway(u32 saddr, u16 sport,
return result;
}
-static __inline__ struct sock *udp_v4_lookup(u32 saddr, u16 sport,
- u32 daddr, u16 dport, int dif)
+static __inline__ struct sock *udp_v4_lookup(__be32 saddr, __be16 sport,
+ __be32 daddr, __be16 dport, int dif)
{
struct sock *sk;
@@ -302,8 +302,8 @@ static __inline__ struct sock *udp_v4_lookup(u32 saddr, u16 sport,
}
static inline struct sock *udp_v4_mcast_next(struct sock *sk,
- u16 loc_port, u32 loc_addr,
- u16 rmt_port, u32 rmt_addr,
+ __be16 loc_port, __be32 loc_addr,
+ __be16 rmt_port, __be32 rmt_addr,
int dif)
{
struct hlist_node *node;
@@ -498,7 +498,7 @@ out:
}
-static unsigned short udp_check(struct udphdr *uh, int len, unsigned long saddr, unsigned long daddr, unsigned long base)
+static unsigned short udp_check(struct udphdr *uh, int len, __be32 saddr, __be32 daddr, unsigned long base)
{
return(csum_tcpudp_magic(saddr, daddr, len, IPPROTO_UDP, base));
}
@@ -513,8 +513,8 @@ int udp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
struct rtable *rt = NULL;
int free = 0;
int connected = 0;
- u32 daddr, faddr, saddr;
- u16 dport;
+ __be32 daddr, faddr, saddr;
+ __be16 dport;
u8 tos;
int err;
int corkreq = up->corkflag || msg->msg_flags&MSG_MORE;
@@ -931,7 +931,7 @@ static int udp_encap_rcv(struct sock * sk, struct sk_buff *skb)
int iphlen, len;
__u8 *udpdata = (__u8 *)uh + sizeof(struct udphdr);
- __u32 *udpdata32 = (__u32 *)udpdata;
+ __be32 *udpdata32 = (__be32 *)udpdata;
__u16 encap_type = up->encap_type;
/* if we're overly short, let UDP handle it */
@@ -1080,7 +1080,7 @@ static int udp_queue_rcv_skb(struct sock * sk, struct sk_buff *skb)
* so we don't need to lock the hashes.
*/
static int udp_v4_mcast_deliver(struct sk_buff *skb, struct udphdr *uh,
- u32 saddr, u32 daddr)
+ __be32 saddr, __be32 daddr)
{
struct sock *sk;
int dif;
@@ -1121,7 +1121,7 @@ static int udp_v4_mcast_deliver(struct sk_buff *skb, struct udphdr *uh,
* including udp header and folding it to skb->csum.
*/
static void udp_checksum_init(struct sk_buff *skb, struct udphdr *uh,
- unsigned short ulen, u32 saddr, u32 daddr)
+ unsigned short ulen, __be32 saddr, __be32 daddr)
{
if (uh->check == 0) {
skb->ip_summed = CHECKSUM_UNNECESSARY;
@@ -1146,8 +1146,8 @@ int udp_rcv(struct sk_buff *skb)
struct udphdr *uh;
unsigned short ulen;
struct rtable *rt = (struct rtable*)skb->dst;
- u32 saddr = skb->nh.iph->saddr;
- u32 daddr = skb->nh.iph->daddr;
+ __be32 saddr = skb->nh.iph->saddr;
+ __be32 daddr = skb->nh.iph->daddr;
int len = skb->len;
/*
@@ -1563,8 +1563,8 @@ void udp_proc_unregister(struct udp_seq_afinfo *afinfo)
static void udp4_format_sock(struct sock *sp, char *tmpbuf, int bucket)
{
struct inet_sock *inet = inet_sk(sp);
- unsigned int dest = inet->daddr;
- unsigned int src = inet->rcv_saddr;
+ __be32 dest = inet->daddr;
+ __be32 src = inet->rcv_saddr;
__u16 destp = ntohs(inet->dport);
__u16 srcp = ntohs(inet->sport);
diff --git a/net/ipv4/xfrm4_input.c b/net/ipv4/xfrm4_input.c
index 040e8475f295..8655d038364c 100644
--- a/net/ipv4/xfrm4_input.c
+++ b/net/ipv4/xfrm4_input.c
@@ -23,7 +23,7 @@ int xfrm4_rcv(struct sk_buff *skb)
EXPORT_SYMBOL(xfrm4_rcv);
-static int xfrm4_parse_spi(struct sk_buff *skb, u8 nexthdr, u32 *spi, u32 *seq)
+static int xfrm4_parse_spi(struct sk_buff *skb, u8 nexthdr, __be32 *spi, __be32 *seq)
{
switch (nexthdr) {
case IPPROTO_IPIP:
@@ -55,7 +55,7 @@ drop:
int xfrm4_rcv_encap(struct sk_buff *skb, __u16 encap_type)
{
int err;
- u32 spi, seq;
+ __be32 spi, seq;
struct xfrm_state *xfrm_vec[XFRM_MAX_DEPTH];
struct xfrm_state *x;
int xfrm_nr = 0;
diff --git a/net/ipv4/xfrm4_policy.c b/net/ipv4/xfrm4_policy.c
index eabcd27b1767..7a7a00147e55 100644
--- a/net/ipv4/xfrm4_policy.c
+++ b/net/ipv4/xfrm4_policy.c
@@ -221,7 +221,7 @@ _decode_session4(struct sk_buff *skb, struct flowi *fl)
case IPPROTO_ESP:
if (pskb_may_pull(skb, xprth + 4 - skb->data)) {
- u32 *ehdr = (u32 *)xprth;
+ __be32 *ehdr = (__be32 *)xprth;
fl->fl_ipsec_spi = ehdr[0];
}
@@ -229,7 +229,7 @@ _decode_session4(struct sk_buff *skb, struct flowi *fl)
case IPPROTO_AH:
if (pskb_may_pull(skb, xprth + 8 - skb->data)) {
- u32 *ah_hdr = (u32*)xprth;
+ __be32 *ah_hdr = (__be32*)xprth;
fl->fl_ipsec_spi = ah_hdr[1];
}
@@ -237,7 +237,7 @@ _decode_session4(struct sk_buff *skb, struct flowi *fl)
case IPPROTO_COMP:
if (pskb_may_pull(skb, xprth + 4 - skb->data)) {
- u16 *ipcomp_hdr = (u16 *)xprth;
+ __be16 *ipcomp_hdr = (__be16 *)xprth;
fl->fl_ipsec_spi = htonl(ntohs(ipcomp_hdr[1]));
}
diff --git a/net/ipv4/xfrm4_state.c b/net/ipv4/xfrm4_state.c
index fe2034494d08..3cc3df0c6ece 100644
--- a/net/ipv4/xfrm4_state.c
+++ b/net/ipv4/xfrm4_state.c
@@ -29,9 +29,9 @@ __xfrm4_init_tempsel(struct xfrm_state *x, struct flowi *fl,
x->sel.daddr.a4 = fl->fl4_dst;
x->sel.saddr.a4 = fl->fl4_src;
x->sel.dport = xfrm_flowi_dport(fl);
- x->sel.dport_mask = ~0;
+ x->sel.dport_mask = htons(0xffff);
x->sel.sport = xfrm_flowi_sport(fl);
- x->sel.sport_mask = ~0;
+ x->sel.sport_mask = htons(0xffff);
x->sel.prefixlen_d = 32;
x->sel.prefixlen_s = 32;
x->sel.proto = fl->proto;
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index c18676352397..e03c33b2465b 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -1258,8 +1258,8 @@ int ipv6_rcv_saddr_equal(const struct sock *sk, const struct sock *sk2)
{
const struct in6_addr *sk_rcv_saddr6 = &inet6_sk(sk)->rcv_saddr;
const struct in6_addr *sk2_rcv_saddr6 = inet6_rcv_saddr(sk2);
- u32 sk_rcv_saddr = inet_sk(sk)->rcv_saddr;
- u32 sk2_rcv_saddr = inet_rcv_saddr(sk2);
+ __be32 sk_rcv_saddr = inet_sk(sk)->rcv_saddr;
+ __be32 sk2_rcv_saddr = inet_rcv_saddr(sk2);
int sk_ipv6only = ipv6_only_sock(sk);
int sk2_ipv6only = inet_v6_ipv6only(sk2);
int addr_type = ipv6_addr_type(sk_rcv_saddr6);
diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c
index bf6e8aff19d4..e94eccb99707 100644
--- a/net/ipv6/af_inet6.c
+++ b/net/ipv6/af_inet6.c
@@ -246,7 +246,7 @@ int inet6_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
struct sock *sk = sock->sk;
struct inet_sock *inet = inet_sk(sk);
struct ipv6_pinfo *np = inet6_sk(sk);
- __u32 v4addr = 0;
+ __be32 v4addr = 0;
unsigned short snum;
int addr_type = 0;
int err = 0;
diff --git a/net/ipv6/inet6_hashtables.c b/net/ipv6/inet6_hashtables.c
index d2f3fc990bfa..8accd1fbeeda 100644
--- a/net/ipv6/inet6_hashtables.c
+++ b/net/ipv6/inet6_hashtables.c
@@ -64,7 +64,7 @@ struct sock *__inet6_lookup_established(struct inet_hashinfo *hashinfo,
{
struct sock *sk;
const struct hlist_node *node;
- const __u32 ports = INET_COMBINED_PORTS(sport, hnum);
+ const __portpair ports = INET_COMBINED_PORTS(sport, hnum);
/* Optimize here for direct hit, only listening connections can
* have wildcards anyways.
*/
@@ -82,7 +82,7 @@ struct sock *__inet6_lookup_established(struct inet_hashinfo *hashinfo,
sk_for_each(sk, node, &(head + hashinfo->ehash_size)->chain) {
const struct inet_timewait_sock *tw = inet_twsk(sk);
- if(*((__u32 *)&(tw->tw_dport)) == ports &&
+ if(*((__portpair *)&(tw->tw_dport)) == ports &&
sk->sk_family == PF_INET6) {
const struct inet6_timewait_sock *tw6 = inet6_twsk(sk);
@@ -171,7 +171,7 @@ static int __inet6_check_established(struct inet_timewait_death_row *death_row,
const struct in6_addr *daddr = &np->rcv_saddr;
const struct in6_addr *saddr = &np->daddr;
const int dif = sk->sk_bound_dev_if;
- const u32 ports = INET_COMBINED_PORTS(inet->dport, lport);
+ const __portpair ports = INET_COMBINED_PORTS(inet->dport, lport);
const unsigned int hash = inet6_ehashfn(daddr, inet->num, saddr,
inet->dport);
struct inet_ehash_bucket *head = inet_ehash_bucket(hinfo, hash);
@@ -188,7 +188,7 @@ static int __inet6_check_established(struct inet_timewait_death_row *death_row,
tw = inet_twsk(sk2);
- if(*((__u32 *)&(tw->tw_dport)) == ports &&
+ if(*((__portpair *)&(tw->tw_dport)) == ports &&
sk2->sk_family == PF_INET6 &&
ipv6_addr_equal(&tw6->tw_v6_daddr, saddr) &&
ipv6_addr_equal(&tw6->tw_v6_rcv_saddr, daddr) &&
diff --git a/net/ipv6/ipcomp6.c b/net/ipv6/ipcomp6.c
index ad9c6e824e62..a2860e35efd7 100644
--- a/net/ipv6/ipcomp6.c
+++ b/net/ipv6/ipcomp6.c
@@ -178,7 +178,7 @@ out_ok:
static void ipcomp6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
int type, int code, int offset, __u32 info)
{
- u32 spi;
+ __be32 spi;
struct ipv6hdr *iph = (struct ipv6hdr*)skb->data;
struct ipv6_comp_hdr *ipcomph = (struct ipv6_comp_hdr*)(skb->data+offset);
struct xfrm_state *x;
@@ -234,7 +234,7 @@ static int ipcomp6_tunnel_attach(struct xfrm_state *x)
{
int err = 0;
struct xfrm_state *t = NULL;
- u32 spi;
+ __be32 spi;
spi = xfrm6_tunnel_spi_lookup((xfrm_address_t *)&x->props.saddr);
if (spi)
diff --git a/net/ipv6/ipv6_sockglue.c b/net/ipv6/ipv6_sockglue.c
index 4f3bb7fcc8b5..de6b91981b30 100644
--- a/net/ipv6/ipv6_sockglue.c
+++ b/net/ipv6/ipv6_sockglue.c
@@ -123,6 +123,9 @@ static struct sk_buff *ipv6_gso_segment(struct sk_buff *skb, int features)
struct ipv6hdr *ipv6h;
struct inet6_protocol *ops;
+ if (!(features & NETIF_F_HW_CSUM))
+ features &= ~NETIF_F_SG;
+
if (unlikely(skb_shinfo(skb)->gso_type &
~(SKB_GSO_UDP |
SKB_GSO_DODGY |
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
index 2546fc9f0a78..3b6575478fcc 100644
--- a/net/ipv6/tcp_ipv6.c
+++ b/net/ipv6/tcp_ipv6.c
@@ -1237,7 +1237,7 @@ process:
skb->dev = NULL;
- bh_lock_sock(sk);
+ bh_lock_sock_nested(sk);
ret = 0;
if (!sock_owned_by_user(sk)) {
#ifdef CONFIG_NET_DMA
diff --git a/net/ipv6/xfrm6_input.c b/net/ipv6/xfrm6_input.c
index a40a05789013..5c8b7a568800 100644
--- a/net/ipv6/xfrm6_input.c
+++ b/net/ipv6/xfrm6_input.c
@@ -16,10 +16,10 @@
#include <net/ipv6.h>
#include <net/xfrm.h>
-int xfrm6_rcv_spi(struct sk_buff *skb, u32 spi)
+int xfrm6_rcv_spi(struct sk_buff *skb, __be32 spi)
{
int err;
- u32 seq;
+ __be32 seq;
struct xfrm_state *xfrm_vec[XFRM_MAX_DEPTH];
struct xfrm_state *x;
int xfrm_nr = 0;
diff --git a/net/ipv6/xfrm6_state.c b/net/ipv6/xfrm6_state.c
index 711bfafb2472..9ddaa9d41539 100644
--- a/net/ipv6/xfrm6_state.c
+++ b/net/ipv6/xfrm6_state.c
@@ -29,9 +29,9 @@ __xfrm6_init_tempsel(struct xfrm_state *x, struct flowi *fl,
ipv6_addr_copy((struct in6_addr *)&x->sel.daddr, &fl->fl6_dst);
ipv6_addr_copy((struct in6_addr *)&x->sel.saddr, &fl->fl6_src);
x->sel.dport = xfrm_flowi_dport(fl);
- x->sel.dport_mask = ~0;
+ x->sel.dport_mask = htons(0xffff);
x->sel.sport = xfrm_flowi_sport(fl);
- x->sel.sport_mask = ~0;
+ x->sel.sport_mask = htons(0xffff);
x->sel.prefixlen_d = 128;
x->sel.prefixlen_s = 128;
x->sel.proto = fl->proto;
diff --git a/net/ipv6/xfrm6_tunnel.c b/net/ipv6/xfrm6_tunnel.c
index 59685ee8f700..7af227bb1551 100644
--- a/net/ipv6/xfrm6_tunnel.c
+++ b/net/ipv6/xfrm6_tunnel.c
@@ -258,7 +258,7 @@ static int xfrm6_tunnel_input(struct xfrm_state *x, struct sk_buff *skb)
static int xfrm6_tunnel_rcv(struct sk_buff *skb)
{
struct ipv6hdr *iph = skb->nh.ipv6h;
- u32 spi;
+ __be32 spi;
spi = xfrm6_tunnel_spi_lookup((xfrm_address_t *)&iph->saddr);
return xfrm6_rcv_spi(skb, spi);
diff --git a/net/irda/af_irda.c b/net/irda/af_irda.c
index 17699eeb64d7..7e1aea89ef05 100644
--- a/net/irda/af_irda.c
+++ b/net/irda/af_irda.c
@@ -132,13 +132,14 @@ static void irda_disconnect_indication(void *instance, void *sap,
/* Prevent race conditions with irda_release() and irda_shutdown() */
if (!sock_flag(sk, SOCK_DEAD) && sk->sk_state != TCP_CLOSE) {
+ lock_sock(sk);
sk->sk_state = TCP_CLOSE;
sk->sk_err = ECONNRESET;
sk->sk_shutdown |= SEND_SHUTDOWN;
sk->sk_state_change(sk);
- /* Uh-oh... Should use sock_orphan ? */
- sock_set_flag(sk, SOCK_DEAD);
+ sock_orphan(sk);
+ release_sock(sk);
/* Close our TSAP.
* If we leave it open, IrLMP put it back into the list of
@@ -308,7 +309,8 @@ static void irda_connect_response(struct irda_sock *self)
IRDA_ASSERT(self != NULL, return;);
- skb = alloc_skb(64, GFP_ATOMIC);
+ skb = alloc_skb(TTP_MAX_HEADER + TTP_SAR_HEADER,
+ GFP_ATOMIC);
if (skb == NULL) {
IRDA_DEBUG(0, "%s() Unable to allocate sk_buff!\n",
__FUNCTION__);
@@ -1212,6 +1214,7 @@ static int irda_release(struct socket *sock)
if (sk == NULL)
return 0;
+ lock_sock(sk);
sk->sk_state = TCP_CLOSE;
sk->sk_shutdown |= SEND_SHUTDOWN;
sk->sk_state_change(sk);
@@ -1221,6 +1224,7 @@ static int irda_release(struct socket *sock)
sock_orphan(sk);
sock->sk = NULL;
+ release_sock(sk);
/* Purge queues (see sock_init_data()) */
skb_queue_purge(&sk->sk_receive_queue);
@@ -1353,6 +1357,7 @@ static int irda_recvmsg_dgram(struct kiocb *iocb, struct socket *sock,
IRDA_DEBUG(4, "%s()\n", __FUNCTION__);
IRDA_ASSERT(self != NULL, return -1;);
+ IRDA_ASSERT(!sock_error(sk), return -1;);
skb = skb_recv_datagram(sk, flags & ~MSG_DONTWAIT,
flags & MSG_DONTWAIT, &err);
@@ -1405,6 +1410,7 @@ static int irda_recvmsg_stream(struct kiocb *iocb, struct socket *sock,
IRDA_DEBUG(3, "%s()\n", __FUNCTION__);
IRDA_ASSERT(self != NULL, return -1;);
+ IRDA_ASSERT(!sock_error(sk), return -1;);
if (sock->flags & __SO_ACCEPTCON)
return(-EINVAL);
diff --git a/net/irda/ircomm/ircomm_lmp.c b/net/irda/ircomm/ircomm_lmp.c
index 959874b6451f..c8e0d89ee11f 100644
--- a/net/irda/ircomm/ircomm_lmp.c
+++ b/net/irda/ircomm/ircomm_lmp.c
@@ -81,7 +81,7 @@ static int ircomm_lmp_connect_response(struct ircomm_cb *self,
/* Any userdata supplied? */
if (userdata == NULL) {
- tx_skb = alloc_skb(64, GFP_ATOMIC);
+ tx_skb = alloc_skb(LMP_MAX_HEADER, GFP_ATOMIC);
if (!tx_skb)
return -ENOMEM;
@@ -115,7 +115,7 @@ static int ircomm_lmp_disconnect_request(struct ircomm_cb *self,
IRDA_DEBUG(0, "%s()\n", __FUNCTION__ );
if (!userdata) {
- tx_skb = alloc_skb(64, GFP_ATOMIC);
+ tx_skb = alloc_skb(LMP_MAX_HEADER, GFP_ATOMIC);
if (!tx_skb)
return -ENOMEM;
diff --git a/net/irda/ircomm/ircomm_tty.c b/net/irda/ircomm/ircomm_tty.c
index 3bcdb467efc5..d50a02030ad7 100644
--- a/net/irda/ircomm/ircomm_tty.c
+++ b/net/irda/ircomm/ircomm_tty.c
@@ -79,7 +79,7 @@ static struct tty_driver *driver;
hashbin_t *ircomm_tty = NULL;
-static struct tty_operations ops = {
+static const struct tty_operations ops = {
.open = ircomm_tty_open,
.close = ircomm_tty_close,
.write = ircomm_tty_write,
diff --git a/net/irda/iriap.c b/net/irda/iriap.c
index 61128aa05b40..415cf4eec23b 100644
--- a/net/irda/iriap.c
+++ b/net/irda/iriap.c
@@ -345,10 +345,11 @@ static void iriap_disconnect_request(struct iriap_cb *self)
IRDA_ASSERT(self != NULL, return;);
IRDA_ASSERT(self->magic == IAS_MAGIC, return;);
- tx_skb = alloc_skb(64, GFP_ATOMIC);
+ tx_skb = alloc_skb(LMP_MAX_HEADER, GFP_ATOMIC);
if (tx_skb == NULL) {
- IRDA_DEBUG(0, "%s(), Could not allocate an sk_buff of length %d\n",
- __FUNCTION__, 64);
+ IRDA_DEBUG(0,
+ "%s(), Could not allocate an sk_buff of length %d\n",
+ __FUNCTION__, LMP_MAX_HEADER);
return;
}
@@ -701,7 +702,7 @@ void iriap_send_ack(struct iriap_cb *self)
IRDA_ASSERT(self != NULL, return;);
IRDA_ASSERT(self->magic == IAS_MAGIC, return;);
- tx_skb = alloc_skb(64, GFP_ATOMIC);
+ tx_skb = alloc_skb(LMP_MAX_HEADER + 1, GFP_ATOMIC);
if (!tx_skb)
return;
diff --git a/net/irda/iriap_event.c b/net/irda/iriap_event.c
index da17395df05a..99b18dc7a0b7 100644
--- a/net/irda/iriap_event.c
+++ b/net/irda/iriap_event.c
@@ -365,7 +365,7 @@ static void state_r_disconnect(struct iriap_cb *self, IRIAP_EVENT event,
switch (event) {
case IAP_LM_CONNECT_INDICATION:
- tx_skb = alloc_skb(64, GFP_ATOMIC);
+ tx_skb = alloc_skb(LMP_MAX_HEADER, GFP_ATOMIC);
if (tx_skb == NULL) {
IRDA_WARNING("%s: unable to malloc!\n", __FUNCTION__);
return;
diff --git a/net/irda/irlan/irlan_common.c b/net/irda/irlan/irlan_common.c
index 7dd0a2fe1d20..9b962f247714 100644
--- a/net/irda/irlan/irlan_common.c
+++ b/net/irda/irlan/irlan_common.c
@@ -636,7 +636,8 @@ void irlan_get_provider_info(struct irlan_cb *self)
IRDA_ASSERT(self != NULL, return;);
IRDA_ASSERT(self->magic == IRLAN_MAGIC, return;);
- skb = alloc_skb(64, GFP_ATOMIC);
+ skb = alloc_skb(IRLAN_MAX_HEADER + IRLAN_CMD_HEADER,
+ GFP_ATOMIC);
if (!skb)
return;
@@ -668,7 +669,10 @@ void irlan_open_data_channel(struct irlan_cb *self)
IRDA_ASSERT(self != NULL, return;);
IRDA_ASSERT(self->magic == IRLAN_MAGIC, return;);
- skb = alloc_skb(64, GFP_ATOMIC);
+ skb = alloc_skb(IRLAN_MAX_HEADER + IRLAN_CMD_HEADER +
+ IRLAN_STRING_PARAMETER_LEN("MEDIA", "802.3") +
+ IRLAN_STRING_PARAMETER_LEN("ACCESS_TYPE", "DIRECT"),
+ GFP_ATOMIC);
if (!skb)
return;
@@ -704,7 +708,9 @@ void irlan_close_data_channel(struct irlan_cb *self)
if (self->client.tsap_ctrl == NULL)
return;
- skb = alloc_skb(64, GFP_ATOMIC);
+ skb = alloc_skb(IRLAN_MAX_HEADER + IRLAN_CMD_HEADER +
+ IRLAN_BYTE_PARAMETER_LEN("DATA_CHAN"),
+ GFP_ATOMIC);
if (!skb)
return;
@@ -715,7 +721,7 @@ void irlan_close_data_channel(struct irlan_cb *self)
/* Build frame */
frame[0] = CMD_CLOSE_DATA_CHAN;
- frame[1] = 0x01; /* Two parameters */
+ frame[1] = 0x01; /* One parameter */
irlan_insert_byte_param(skb, "DATA_CHAN", self->dtsap_sel_data);
@@ -739,7 +745,11 @@ static void irlan_open_unicast_addr(struct irlan_cb *self)
IRDA_ASSERT(self != NULL, return;);
IRDA_ASSERT(self->magic == IRLAN_MAGIC, return;);
- skb = alloc_skb(128, GFP_ATOMIC);
+ skb = alloc_skb(IRLAN_MAX_HEADER + IRLAN_CMD_HEADER +
+ IRLAN_BYTE_PARAMETER_LEN("DATA_CHAN") +
+ IRLAN_STRING_PARAMETER_LEN("FILTER_TYPE", "DIRECTED") +
+ IRLAN_STRING_PARAMETER_LEN("FILTER_MODE", "FILTER"),
+ GFP_ATOMIC);
if (!skb)
return;
@@ -777,7 +787,12 @@ void irlan_set_broadcast_filter(struct irlan_cb *self, int status)
IRDA_ASSERT(self != NULL, return;);
IRDA_ASSERT(self->magic == IRLAN_MAGIC, return;);
- skb = alloc_skb(128, GFP_ATOMIC);
+ skb = alloc_skb(IRLAN_MAX_HEADER + IRLAN_CMD_HEADER +
+ IRLAN_BYTE_PARAMETER_LEN("DATA_CHAN") +
+ IRLAN_STRING_PARAMETER_LEN("FILTER_TYPE", "BROADCAST") +
+ /* We may waste one byte here...*/
+ IRLAN_STRING_PARAMETER_LEN("FILTER_MODE", "FILTER"),
+ GFP_ATOMIC);
if (!skb)
return;
@@ -816,7 +831,12 @@ void irlan_set_multicast_filter(struct irlan_cb *self, int status)
IRDA_ASSERT(self != NULL, return;);
IRDA_ASSERT(self->magic == IRLAN_MAGIC, return;);
- skb = alloc_skb(128, GFP_ATOMIC);
+ skb = alloc_skb(IRLAN_MAX_HEADER + IRLAN_CMD_HEADER +
+ IRLAN_BYTE_PARAMETER_LEN("DATA_CHAN") +
+ IRLAN_STRING_PARAMETER_LEN("FILTER_TYPE", "MULTICAST") +
+ /* We may waste one byte here...*/
+ IRLAN_STRING_PARAMETER_LEN("FILTER_MODE", "NONE"),
+ GFP_ATOMIC);
if (!skb)
return;
@@ -856,7 +876,12 @@ static void irlan_get_unicast_addr(struct irlan_cb *self)
IRDA_ASSERT(self != NULL, return;);
IRDA_ASSERT(self->magic == IRLAN_MAGIC, return;);
- skb = alloc_skb(128, GFP_ATOMIC);
+ skb = alloc_skb(IRLAN_MAX_HEADER + IRLAN_CMD_HEADER +
+ IRLAN_BYTE_PARAMETER_LEN("DATA_CHAN") +
+ IRLAN_STRING_PARAMETER_LEN("FILTER_TYPE", "DIRECTED") +
+ IRLAN_STRING_PARAMETER_LEN("FILTER_OPERATION",
+ "DYNAMIC"),
+ GFP_ATOMIC);
if (!skb)
return;
@@ -891,7 +916,10 @@ void irlan_get_media_char(struct irlan_cb *self)
IRDA_ASSERT(self != NULL, return;);
IRDA_ASSERT(self->magic == IRLAN_MAGIC, return;);
- skb = alloc_skb(64, GFP_ATOMIC);
+ skb = alloc_skb(IRLAN_MAX_HEADER + IRLAN_CMD_HEADER +
+ IRLAN_STRING_PARAMETER_LEN("MEDIA", "802.3"),
+ GFP_ATOMIC);
+
if (!skb)
return;
diff --git a/net/irda/irlan/irlan_provider.c b/net/irda/irlan/irlan_provider.c
index 9c0df86044d7..58efde919667 100644
--- a/net/irda/irlan/irlan_provider.c
+++ b/net/irda/irlan/irlan_provider.c
@@ -296,7 +296,14 @@ void irlan_provider_send_reply(struct irlan_cb *self, int command,
IRDA_ASSERT(self != NULL, return;);
IRDA_ASSERT(self->magic == IRLAN_MAGIC, return;);
- skb = alloc_skb(128, GFP_ATOMIC);
+ skb = alloc_skb(IRLAN_MAX_HEADER + IRLAN_CMD_HEADER +
+ /* Bigger param length comes from CMD_GET_MEDIA_CHAR */
+ IRLAN_STRING_PARAMETER_LEN("FILTER_TYPE", "DIRECTED") +
+ IRLAN_STRING_PARAMETER_LEN("FILTER_TYPE", "BORADCAST") +
+ IRLAN_STRING_PARAMETER_LEN("FILTER_TYPE", "MULTICAST") +
+ IRLAN_STRING_PARAMETER_LEN("ACCESS_TYPE", "HOSTED"),
+ GFP_ATOMIC);
+
if (!skb)
return;
@@ -354,8 +361,7 @@ void irlan_provider_send_reply(struct irlan_cb *self, int command,
} else
skb->data[1] = 0x02; /* 2 parameters */
irlan_insert_byte_param(skb, "DATA_CHAN", self->stsap_sel_data);
- irlan_insert_array_param(skb, "RECONNECT_KEY", "LINUX RULES!",
- 12);
+ irlan_insert_string_param(skb, "RECONNECT_KEY", "LINUX RULES!");
break;
case CMD_FILTER_OPERATION:
irlan_filter_request(self, skb);
diff --git a/net/irda/irlap_frame.c b/net/irda/irlap_frame.c
index ccb983bf0f4a..dba349c832d0 100644
--- a/net/irda/irlap_frame.c
+++ b/net/irda/irlap_frame.c
@@ -117,7 +117,9 @@ void irlap_send_snrm_frame(struct irlap_cb *self, struct qos_info *qos)
IRDA_ASSERT(self->magic == LAP_MAGIC, return;);
/* Allocate frame */
- tx_skb = alloc_skb(64, GFP_ATOMIC);
+ tx_skb = alloc_skb(sizeof(struct snrm_frame) +
+ IRLAP_NEGOCIATION_PARAMS_LEN,
+ GFP_ATOMIC);
if (!tx_skb)
return;
@@ -136,7 +138,7 @@ void irlap_send_snrm_frame(struct irlap_cb *self, struct qos_info *qos)
* If we are establishing a connection then insert QoS paramerters
*/
if (qos) {
- skb_put(tx_skb, 9); /* 21 left */
+ skb_put(tx_skb, 9); /* 25 left */
frame->saddr = cpu_to_le32(self->saddr);
frame->daddr = cpu_to_le32(self->daddr);
@@ -210,7 +212,9 @@ void irlap_send_ua_response_frame(struct irlap_cb *self, struct qos_info *qos)
IRDA_ASSERT(self->magic == LAP_MAGIC, return;);
/* Allocate frame */
- tx_skb = alloc_skb(64, GFP_ATOMIC);
+ tx_skb = alloc_skb(sizeof(struct ua_frame) +
+ IRLAP_NEGOCIATION_PARAMS_LEN,
+ GFP_ATOMIC);
if (!tx_skb)
return;
@@ -245,23 +249,23 @@ void irlap_send_ua_response_frame(struct irlap_cb *self, struct qos_info *qos)
void irlap_send_dm_frame( struct irlap_cb *self)
{
struct sk_buff *tx_skb = NULL;
- __u8 *frame;
+ struct dm_frame *frame;
IRDA_ASSERT(self != NULL, return;);
IRDA_ASSERT(self->magic == LAP_MAGIC, return;);
- tx_skb = alloc_skb(32, GFP_ATOMIC);
+ tx_skb = alloc_skb(sizeof(struct dm_frame), GFP_ATOMIC);
if (!tx_skb)
return;
- frame = skb_put(tx_skb, 2);
+ frame = (struct dm_frame *)skb_put(tx_skb, 2);
if (self->state == LAP_NDM)
- frame[0] = CBROADCAST;
+ frame->caddr = CBROADCAST;
else
- frame[0] = self->caddr;
+ frame->caddr = self->caddr;
- frame[1] = DM_RSP | PF_BIT;
+ frame->control = DM_RSP | PF_BIT;
irlap_queue_xmit(self, tx_skb);
}
@@ -275,21 +279,21 @@ void irlap_send_dm_frame( struct irlap_cb *self)
void irlap_send_disc_frame(struct irlap_cb *self)
{
struct sk_buff *tx_skb = NULL;
- __u8 *frame;
+ struct disc_frame *frame;
IRDA_DEBUG(3, "%s()\n", __FUNCTION__);
IRDA_ASSERT(self != NULL, return;);
IRDA_ASSERT(self->magic == LAP_MAGIC, return;);
- tx_skb = alloc_skb(16, GFP_ATOMIC);
+ tx_skb = alloc_skb(sizeof(struct disc_frame), GFP_ATOMIC);
if (!tx_skb)
return;
- frame = skb_put(tx_skb, 2);
+ frame = (struct disc_frame *)skb_put(tx_skb, 2);
- frame[0] = self->caddr | CMD_FRAME;
- frame[1] = DISC_CMD | PF_BIT;
+ frame->caddr = self->caddr | CMD_FRAME;
+ frame->control = DISC_CMD | PF_BIT;
irlap_queue_xmit(self, tx_skb);
}
@@ -315,7 +319,8 @@ void irlap_send_discovery_xid_frame(struct irlap_cb *self, int S, __u8 s,
IRDA_ASSERT(self->magic == LAP_MAGIC, return;);
IRDA_ASSERT(discovery != NULL, return;);
- tx_skb = alloc_skb(64, GFP_ATOMIC);
+ tx_skb = alloc_skb(sizeof(struct xid_frame) + IRLAP_DISCOVERY_INFO_LEN,
+ GFP_ATOMIC);
if (!tx_skb)
return;
@@ -573,18 +578,18 @@ static void irlap_recv_discovery_xid_cmd(struct irlap_cb *self,
void irlap_send_rr_frame(struct irlap_cb *self, int command)
{
struct sk_buff *tx_skb;
- __u8 *frame;
+ struct rr_frame *frame;
- tx_skb = alloc_skb(16, GFP_ATOMIC);
+ tx_skb = alloc_skb(sizeof(struct rr_frame), GFP_ATOMIC);
if (!tx_skb)
return;
- frame = skb_put(tx_skb, 2);
+ frame = (struct rr_frame *)skb_put(tx_skb, 2);
- frame[0] = self->caddr;
- frame[0] |= (command) ? CMD_FRAME : 0;
+ frame->caddr = self->caddr;
+ frame->caddr |= (command) ? CMD_FRAME : 0;
- frame[1] = RR | PF_BIT | (self->vr << 5);
+ frame->control = RR | PF_BIT | (self->vr << 5);
irlap_queue_xmit(self, tx_skb);
}
@@ -598,16 +603,16 @@ void irlap_send_rr_frame(struct irlap_cb *self, int command)
void irlap_send_rd_frame(struct irlap_cb *self)
{
struct sk_buff *tx_skb;
- __u8 *frame;
+ struct rd_frame *frame;
- tx_skb = alloc_skb(16, GFP_ATOMIC);
+ tx_skb = alloc_skb(sizeof(struct rd_frame), GFP_ATOMIC);
if (!tx_skb)
return;
- frame = skb_put(tx_skb, 2);
+ frame = (struct rd_frame *)skb_put(tx_skb, 2);
- frame[0] = self->caddr;
- frame[1] = RD_RSP | PF_BIT;
+ frame->caddr = self->caddr;
+ frame->caddr = RD_RSP | PF_BIT;
irlap_queue_xmit(self, tx_skb);
}
@@ -1214,7 +1219,7 @@ void irlap_send_test_frame(struct irlap_cb *self, __u8 caddr, __u32 daddr,
struct test_frame *frame;
__u8 *info;
- tx_skb = alloc_skb(cmd->len+sizeof(struct test_frame), GFP_ATOMIC);
+ tx_skb = alloc_skb(cmd->len + sizeof(struct test_frame), GFP_ATOMIC);
if (!tx_skb)
return;
diff --git a/net/irda/irlmp.c b/net/irda/irlmp.c
index c440913dee14..5073261b9d0c 100644
--- a/net/irda/irlmp.c
+++ b/net/irda/irlmp.c
@@ -392,7 +392,7 @@ int irlmp_connect_request(struct lsap_cb *self, __u8 dlsap_sel,
/* Any userdata? */
if (tx_skb == NULL) {
- tx_skb = alloc_skb(64, GFP_ATOMIC);
+ tx_skb = alloc_skb(LMP_MAX_HEADER, GFP_ATOMIC);
if (!tx_skb)
return -ENOMEM;
diff --git a/net/irda/irttp.c b/net/irda/irttp.c
index 42acf1cde737..3c2e70b77df1 100644
--- a/net/irda/irttp.c
+++ b/net/irda/irttp.c
@@ -804,12 +804,12 @@ static inline void irttp_give_credit(struct tsap_cb *self)
self->send_credit, self->avail_credit, self->remote_credit);
/* Give credit to peer */
- tx_skb = alloc_skb(64, GFP_ATOMIC);
+ tx_skb = alloc_skb(TTP_MAX_HEADER, GFP_ATOMIC);
if (!tx_skb)
return;
/* Reserve space for LMP, and LAP header */
- skb_reserve(tx_skb, self->max_header_size);
+ skb_reserve(tx_skb, LMP_MAX_HEADER);
/*
* Since we can transmit and receive frames concurrently,
@@ -1093,7 +1093,8 @@ int irttp_connect_request(struct tsap_cb *self, __u8 dtsap_sel,
/* Any userdata supplied? */
if (userdata == NULL) {
- tx_skb = alloc_skb(64, GFP_ATOMIC);
+ tx_skb = alloc_skb(TTP_MAX_HEADER + TTP_SAR_HEADER,
+ GFP_ATOMIC);
if (!tx_skb)
return -ENOMEM;
@@ -1341,7 +1342,8 @@ int irttp_connect_response(struct tsap_cb *self, __u32 max_sdu_size,
/* Any userdata supplied? */
if (userdata == NULL) {
- tx_skb = alloc_skb(64, GFP_ATOMIC);
+ tx_skb = alloc_skb(TTP_MAX_HEADER + TTP_SAR_HEADER,
+ GFP_ATOMIC);
if (!tx_skb)
return -ENOMEM;
@@ -1540,14 +1542,14 @@ int irttp_disconnect_request(struct tsap_cb *self, struct sk_buff *userdata,
if (!userdata) {
struct sk_buff *tx_skb;
- tx_skb = alloc_skb(64, GFP_ATOMIC);
+ tx_skb = alloc_skb(LMP_MAX_HEADER, GFP_ATOMIC);
if (!tx_skb)
return -ENOMEM;
/*
* Reserve space for MUX and LAP header
*/
- skb_reserve(tx_skb, TTP_MAX_HEADER);
+ skb_reserve(tx_skb, LMP_MAX_HEADER);
userdata = tx_skb;
}
diff --git a/net/key/af_key.c b/net/key/af_key.c
index 83b443ddc72f..ff98e70b0931 100644
--- a/net/key/af_key.c
+++ b/net/key/af_key.c
@@ -2140,7 +2140,7 @@ static int pfkey_spdadd(struct sock *sk, struct sk_buff *skb, struct sadb_msg *h
xp->selector.proto = pfkey_proto_to_xfrm(sa->sadb_address_proto);
xp->selector.sport = ((struct sockaddr_in *)(sa+1))->sin_port;
if (xp->selector.sport)
- xp->selector.sport_mask = ~0;
+ xp->selector.sport_mask = htons(0xffff);
sa = ext_hdrs[SADB_EXT_ADDRESS_DST-1],
pfkey_sadb_addr2xfrm_addr(sa, &xp->selector.daddr);
@@ -2153,7 +2153,7 @@ static int pfkey_spdadd(struct sock *sk, struct sk_buff *skb, struct sadb_msg *h
xp->selector.dport = ((struct sockaddr_in *)(sa+1))->sin_port;
if (xp->selector.dport)
- xp->selector.dport_mask = ~0;
+ xp->selector.dport_mask = htons(0xffff);
sec_ctx = (struct sadb_x_sec_ctx *) ext_hdrs[SADB_X_EXT_SEC_CTX-1];
if (sec_ctx != NULL) {
@@ -2243,7 +2243,7 @@ static int pfkey_spddelete(struct sock *sk, struct sk_buff *skb, struct sadb_msg
sel.proto = pfkey_proto_to_xfrm(sa->sadb_address_proto);
sel.sport = ((struct sockaddr_in *)(sa+1))->sin_port;
if (sel.sport)
- sel.sport_mask = ~0;
+ sel.sport_mask = htons(0xffff);
sa = ext_hdrs[SADB_EXT_ADDRESS_DST-1],
pfkey_sadb_addr2xfrm_addr(sa, &sel.daddr);
@@ -2251,7 +2251,7 @@ static int pfkey_spddelete(struct sock *sk, struct sk_buff *skb, struct sadb_msg
sel.proto = pfkey_proto_to_xfrm(sa->sadb_address_proto);
sel.dport = ((struct sockaddr_in *)(sa+1))->sin_port;
if (sel.dport)
- sel.dport_mask = ~0;
+ sel.dport_mask = htons(0xffff);
sec_ctx = (struct sadb_x_sec_ctx *) ext_hdrs[SADB_X_EXT_SEC_CTX-1];
memset(&tmp, 0, sizeof(struct xfrm_policy));
diff --git a/net/netlabel/netlabel_cipso_v4.c b/net/netlabel/netlabel_cipso_v4.c
index 4125a55f469f..a6ce1d6d5c59 100644
--- a/net/netlabel/netlabel_cipso_v4.c
+++ b/net/netlabel/netlabel_cipso_v4.c
@@ -32,6 +32,7 @@
#include <linux/socket.h>
#include <linux/string.h>
#include <linux/skbuff.h>
+#include <linux/audit.h>
#include <net/sock.h>
#include <net/netlink.h>
#include <net/genetlink.h>
@@ -162,8 +163,7 @@ static int netlbl_cipsov4_add_std(struct genl_info *info)
int nla_a_rem;
int nla_b_rem;
- if (!info->attrs[NLBL_CIPSOV4_A_DOI] ||
- !info->attrs[NLBL_CIPSOV4_A_TAGLST] ||
+ if (!info->attrs[NLBL_CIPSOV4_A_TAGLST] ||
!info->attrs[NLBL_CIPSOV4_A_MLSLVLLST])
return -EINVAL;
@@ -344,8 +344,7 @@ static int netlbl_cipsov4_add_pass(struct genl_info *info)
int ret_val;
struct cipso_v4_doi *doi_def = NULL;
- if (!info->attrs[NLBL_CIPSOV4_A_DOI] ||
- !info->attrs[NLBL_CIPSOV4_A_TAGLST])
+ if (!info->attrs[NLBL_CIPSOV4_A_TAGLST])
return -EINVAL;
doi_def = kmalloc(sizeof(*doi_def), GFP_KERNEL);
@@ -381,21 +380,40 @@ static int netlbl_cipsov4_add(struct sk_buff *skb, struct genl_info *info)
{
int ret_val = -EINVAL;
- u32 map_type;
+ u32 type;
+ u32 doi;
+ const char *type_str = "(unknown)";
+ struct audit_buffer *audit_buf;
+ struct netlbl_audit audit_info;
- if (!info->attrs[NLBL_CIPSOV4_A_MTYPE])
+ if (!info->attrs[NLBL_CIPSOV4_A_DOI] ||
+ !info->attrs[NLBL_CIPSOV4_A_MTYPE])
return -EINVAL;
- map_type = nla_get_u32(info->attrs[NLBL_CIPSOV4_A_MTYPE]);
- switch (map_type) {
+ doi = nla_get_u32(info->attrs[NLBL_CIPSOV4_A_DOI]);
+ netlbl_netlink_auditinfo(skb, &audit_info);
+
+ type = nla_get_u32(info->attrs[NLBL_CIPSOV4_A_MTYPE]);
+ switch (type) {
case CIPSO_V4_MAP_STD:
+ type_str = "std";
ret_val = netlbl_cipsov4_add_std(info);
break;
case CIPSO_V4_MAP_PASS:
+ type_str = "pass";
ret_val = netlbl_cipsov4_add_pass(info);
break;
}
+ audit_buf = netlbl_audit_start_common(AUDIT_MAC_CIPSOV4_ADD,
+ &audit_info);
+ audit_log_format(audit_buf,
+ " cipso_doi=%u cipso_type=%s res=%u",
+ doi,
+ type_str,
+ ret_val == 0 ? 1 : 0);
+ audit_log_end(audit_buf);
+
return ret_val;
}
@@ -653,12 +671,27 @@ static int netlbl_cipsov4_listall(struct sk_buff *skb,
static int netlbl_cipsov4_remove(struct sk_buff *skb, struct genl_info *info)
{
int ret_val = -EINVAL;
- u32 doi;
+ u32 doi = 0;
+ struct audit_buffer *audit_buf;
+ struct netlbl_audit audit_info;
- if (info->attrs[NLBL_CIPSOV4_A_DOI]) {
- doi = nla_get_u32(info->attrs[NLBL_CIPSOV4_A_DOI]);
- ret_val = cipso_v4_doi_remove(doi, netlbl_cipsov4_doi_free);
- }
+ if (!info->attrs[NLBL_CIPSOV4_A_DOI])
+ return -EINVAL;
+
+ doi = nla_get_u32(info->attrs[NLBL_CIPSOV4_A_DOI]);
+ netlbl_netlink_auditinfo(skb, &audit_info);
+
+ ret_val = cipso_v4_doi_remove(doi,
+ &audit_info,
+ netlbl_cipsov4_doi_free);
+
+ audit_buf = netlbl_audit_start_common(AUDIT_MAC_CIPSOV4_DEL,
+ &audit_info);
+ audit_log_format(audit_buf,
+ " cipso_doi=%u res=%u",
+ doi,
+ ret_val == 0 ? 1 : 0);
+ audit_log_end(audit_buf);
return ret_val;
}
diff --git a/net/netlabel/netlabel_domainhash.c b/net/netlabel/netlabel_domainhash.c
index f56d7a8ac7b7..af4371d3b459 100644
--- a/net/netlabel/netlabel_domainhash.c
+++ b/net/netlabel/netlabel_domainhash.c
@@ -35,12 +35,14 @@
#include <linux/skbuff.h>
#include <linux/spinlock.h>
#include <linux/string.h>
+#include <linux/audit.h>
#include <net/netlabel.h>
#include <net/cipso_ipv4.h>
#include <asm/bug.h>
#include "netlabel_mgmt.h"
#include "netlabel_domainhash.h"
+#include "netlabel_user.h"
struct netlbl_domhsh_tbl {
struct list_head *tbl;
@@ -186,6 +188,7 @@ int netlbl_domhsh_init(u32 size)
/**
* netlbl_domhsh_add - Adds a entry to the domain hash table
* @entry: the entry to add
+ * @audit_info: NetLabel audit information
*
* Description:
* Adds a new entry to the domain hash table and handles any updates to the
@@ -193,10 +196,13 @@ int netlbl_domhsh_init(u32 size)
* negative on failure.
*
*/
-int netlbl_domhsh_add(struct netlbl_dom_map *entry)
+int netlbl_domhsh_add(struct netlbl_dom_map *entry,
+ struct netlbl_audit *audit_info)
{
int ret_val;
u32 bkt;
+ struct audit_buffer *audit_buf;
+ char *audit_domain;
switch (entry->type) {
case NETLBL_NLTYPE_UNLABELED:
@@ -236,6 +242,26 @@ int netlbl_domhsh_add(struct netlbl_dom_map *entry)
spin_unlock(&netlbl_domhsh_def_lock);
} else
ret_val = -EINVAL;
+
+ if (entry->domain != NULL)
+ audit_domain = entry->domain;
+ else
+ audit_domain = "(default)";
+ audit_buf = netlbl_audit_start_common(AUDIT_MAC_MAP_ADD, audit_info);
+ audit_log_format(audit_buf, " nlbl_domain=%s", audit_domain);
+ switch (entry->type) {
+ case NETLBL_NLTYPE_UNLABELED:
+ audit_log_format(audit_buf, " nlbl_protocol=unlbl");
+ break;
+ case NETLBL_NLTYPE_CIPSOV4:
+ audit_log_format(audit_buf,
+ " nlbl_protocol=cipsov4 cipso_doi=%u",
+ entry->type_def.cipsov4->doi);
+ break;
+ }
+ audit_log_format(audit_buf, " res=%u", ret_val == 0 ? 1 : 0);
+ audit_log_end(audit_buf);
+
rcu_read_unlock();
if (ret_val != 0) {
@@ -254,6 +280,7 @@ int netlbl_domhsh_add(struct netlbl_dom_map *entry)
/**
* netlbl_domhsh_add_default - Adds the default entry to the domain hash table
* @entry: the entry to add
+ * @audit_info: NetLabel audit information
*
* Description:
* Adds a new default entry to the domain hash table and handles any updates
@@ -261,14 +288,16 @@ int netlbl_domhsh_add(struct netlbl_dom_map *entry)
* negative on failure.
*
*/
-int netlbl_domhsh_add_default(struct netlbl_dom_map *entry)
+int netlbl_domhsh_add_default(struct netlbl_dom_map *entry,
+ struct netlbl_audit *audit_info)
{
- return netlbl_domhsh_add(entry);
+ return netlbl_domhsh_add(entry, audit_info);
}
/**
* netlbl_domhsh_remove - Removes an entry from the domain hash table
* @domain: the domain to remove
+ * @audit_info: NetLabel audit information
*
* Description:
* Removes an entry from the domain hash table and handles any updates to the
@@ -276,10 +305,12 @@ int netlbl_domhsh_add_default(struct netlbl_dom_map *entry)
* negative on failure.
*
*/
-int netlbl_domhsh_remove(const char *domain)
+int netlbl_domhsh_remove(const char *domain, struct netlbl_audit *audit_info)
{
int ret_val = -ENOENT;
struct netlbl_dom_map *entry;
+ struct audit_buffer *audit_buf;
+ char *audit_domain;
rcu_read_lock();
if (domain != NULL)
@@ -316,6 +347,18 @@ int netlbl_domhsh_remove(const char *domain)
ret_val = -ENOENT;
spin_unlock(&netlbl_domhsh_def_lock);
}
+
+ if (entry->domain != NULL)
+ audit_domain = entry->domain;
+ else
+ audit_domain = "(default)";
+ audit_buf = netlbl_audit_start_common(AUDIT_MAC_MAP_DEL, audit_info);
+ audit_log_format(audit_buf,
+ " nlbl_domain=%s res=%u",
+ audit_domain,
+ ret_val == 0 ? 1 : 0);
+ audit_log_end(audit_buf);
+
if (ret_val == 0)
call_rcu(&entry->rcu, netlbl_domhsh_free_entry);
@@ -326,6 +369,7 @@ remove_return:
/**
* netlbl_domhsh_remove_default - Removes the default entry from the table
+ * @audit_info: NetLabel audit information
*
* Description:
* Removes/resets the default entry for the domain hash table and handles any
@@ -333,9 +377,9 @@ remove_return:
* success, non-zero on failure.
*
*/
-int netlbl_domhsh_remove_default(void)
+int netlbl_domhsh_remove_default(struct netlbl_audit *audit_info)
{
- return netlbl_domhsh_remove(NULL);
+ return netlbl_domhsh_remove(NULL, audit_info);
}
/**
diff --git a/net/netlabel/netlabel_domainhash.h b/net/netlabel/netlabel_domainhash.h
index 02af72a7877c..3689956c3436 100644
--- a/net/netlabel/netlabel_domainhash.h
+++ b/net/netlabel/netlabel_domainhash.h
@@ -57,9 +57,11 @@ struct netlbl_dom_map {
int netlbl_domhsh_init(u32 size);
/* Manipulate the domain hash table */
-int netlbl_domhsh_add(struct netlbl_dom_map *entry);
-int netlbl_domhsh_add_default(struct netlbl_dom_map *entry);
-int netlbl_domhsh_remove_default(void);
+int netlbl_domhsh_add(struct netlbl_dom_map *entry,
+ struct netlbl_audit *audit_info);
+int netlbl_domhsh_add_default(struct netlbl_dom_map *entry,
+ struct netlbl_audit *audit_info);
+int netlbl_domhsh_remove_default(struct netlbl_audit *audit_info);
struct netlbl_dom_map *netlbl_domhsh_getentry(const char *domain);
int netlbl_domhsh_walk(u32 *skip_bkt,
u32 *skip_chain,
diff --git a/net/netlabel/netlabel_mgmt.c b/net/netlabel/netlabel_mgmt.c
index 8626c9f678eb..53c9079ad2c3 100644
--- a/net/netlabel/netlabel_mgmt.c
+++ b/net/netlabel/netlabel_mgmt.c
@@ -87,11 +87,14 @@ static int netlbl_mgmt_add(struct sk_buff *skb, struct genl_info *info)
struct netlbl_dom_map *entry = NULL;
size_t tmp_size;
u32 tmp_val;
+ struct netlbl_audit audit_info;
if (!info->attrs[NLBL_MGMT_A_DOMAIN] ||
!info->attrs[NLBL_MGMT_A_PROTOCOL])
goto add_failure;
+ netlbl_netlink_auditinfo(skb, &audit_info);
+
entry = kzalloc(sizeof(*entry), GFP_KERNEL);
if (entry == NULL) {
ret_val = -ENOMEM;
@@ -108,7 +111,7 @@ static int netlbl_mgmt_add(struct sk_buff *skb, struct genl_info *info)
switch (entry->type) {
case NETLBL_NLTYPE_UNLABELED:
- ret_val = netlbl_domhsh_add(entry);
+ ret_val = netlbl_domhsh_add(entry, &audit_info);
break;
case NETLBL_NLTYPE_CIPSOV4:
if (!info->attrs[NLBL_MGMT_A_CV4DOI])
@@ -125,7 +128,7 @@ static int netlbl_mgmt_add(struct sk_buff *skb, struct genl_info *info)
rcu_read_unlock();
goto add_failure;
}
- ret_val = netlbl_domhsh_add(entry);
+ ret_val = netlbl_domhsh_add(entry, &audit_info);
rcu_read_unlock();
break;
default:
@@ -156,12 +159,15 @@ add_failure:
static int netlbl_mgmt_remove(struct sk_buff *skb, struct genl_info *info)
{
char *domain;
+ struct netlbl_audit audit_info;
if (!info->attrs[NLBL_MGMT_A_DOMAIN])
return -EINVAL;
+ netlbl_netlink_auditinfo(skb, &audit_info);
+
domain = nla_data(info->attrs[NLBL_MGMT_A_DOMAIN]);
- return netlbl_domhsh_remove(domain);
+ return netlbl_domhsh_remove(domain, &audit_info);
}
/**
@@ -264,10 +270,13 @@ static int netlbl_mgmt_adddef(struct sk_buff *skb, struct genl_info *info)
int ret_val = -EINVAL;
struct netlbl_dom_map *entry = NULL;
u32 tmp_val;
+ struct netlbl_audit audit_info;
if (!info->attrs[NLBL_MGMT_A_PROTOCOL])
goto adddef_failure;
+ netlbl_netlink_auditinfo(skb, &audit_info);
+
entry = kzalloc(sizeof(*entry), GFP_KERNEL);
if (entry == NULL) {
ret_val = -ENOMEM;
@@ -277,7 +286,7 @@ static int netlbl_mgmt_adddef(struct sk_buff *skb, struct genl_info *info)
switch (entry->type) {
case NETLBL_NLTYPE_UNLABELED:
- ret_val = netlbl_domhsh_add_default(entry);
+ ret_val = netlbl_domhsh_add_default(entry, &audit_info);
break;
case NETLBL_NLTYPE_CIPSOV4:
if (!info->attrs[NLBL_MGMT_A_CV4DOI])
@@ -294,7 +303,7 @@ static int netlbl_mgmt_adddef(struct sk_buff *skb, struct genl_info *info)
rcu_read_unlock();
goto adddef_failure;
}
- ret_val = netlbl_domhsh_add_default(entry);
+ ret_val = netlbl_domhsh_add_default(entry, &audit_info);
rcu_read_unlock();
break;
default:
@@ -322,7 +331,11 @@ adddef_failure:
*/
static int netlbl_mgmt_removedef(struct sk_buff *skb, struct genl_info *info)
{
- return netlbl_domhsh_remove_default();
+ struct netlbl_audit audit_info;
+
+ netlbl_netlink_auditinfo(skb, &audit_info);
+
+ return netlbl_domhsh_remove_default(&audit_info);
}
/**
diff --git a/net/netlabel/netlabel_unlabeled.c b/net/netlabel/netlabel_unlabeled.c
index 440f5c4e1e2d..1833ad233b39 100644
--- a/net/netlabel/netlabel_unlabeled.c
+++ b/net/netlabel/netlabel_unlabeled.c
@@ -64,6 +64,34 @@ static struct nla_policy netlbl_unlabel_genl_policy[NLBL_UNLABEL_A_MAX + 1] = {
};
/*
+ * Helper Functions
+ */
+
+/**
+ * netlbl_unlabel_acceptflg_set - Set the unlabeled accept flag
+ * @value: desired value
+ * @audit_info: NetLabel audit information
+ *
+ * Description:
+ * Set the value of the unlabeled accept flag to @value.
+ *
+ */
+static void netlbl_unlabel_acceptflg_set(u8 value,
+ struct netlbl_audit *audit_info)
+{
+ struct audit_buffer *audit_buf;
+ u8 old_val;
+
+ old_val = atomic_read(&netlabel_unlabel_accept_flg);
+ atomic_set(&netlabel_unlabel_accept_flg, value);
+
+ audit_buf = netlbl_audit_start_common(AUDIT_MAC_UNLBL_ALLOW,
+ audit_info);
+ audit_log_format(audit_buf, " unlbl_accept=%u old=%u", value, old_val);
+ audit_log_end(audit_buf);
+}
+
+/*
* NetLabel Command Handlers
*/
@@ -79,18 +107,19 @@ static struct nla_policy netlbl_unlabel_genl_policy[NLBL_UNLABEL_A_MAX + 1] = {
*/
static int netlbl_unlabel_accept(struct sk_buff *skb, struct genl_info *info)
{
- int ret_val = -EINVAL;
u8 value;
+ struct netlbl_audit audit_info;
if (info->attrs[NLBL_UNLABEL_A_ACPTFLG]) {
value = nla_get_u8(info->attrs[NLBL_UNLABEL_A_ACPTFLG]);
if (value == 1 || value == 0) {
- atomic_set(&netlabel_unlabel_accept_flg, value);
- ret_val = 0;
+ netlbl_netlink_auditinfo(skb, &audit_info);
+ netlbl_unlabel_acceptflg_set(value, &audit_info);
+ return 0;
}
}
- return ret_val;
+ return -EINVAL;
}
/**
@@ -229,16 +258,23 @@ int netlbl_unlabel_defconf(void)
{
int ret_val;
struct netlbl_dom_map *entry;
+ struct netlbl_audit audit_info;
+
+ /* Only the kernel is allowed to call this function and the only time
+ * it is called is at bootup before the audit subsystem is reporting
+ * messages so don't worry to much about these values. */
+ security_task_getsecid(current, &audit_info.secid);
+ audit_info.loginuid = 0;
entry = kzalloc(sizeof(*entry), GFP_KERNEL);
if (entry == NULL)
return -ENOMEM;
entry->type = NETLBL_NLTYPE_UNLABELED;
- ret_val = netlbl_domhsh_add_default(entry);
+ ret_val = netlbl_domhsh_add_default(entry, &audit_info);
if (ret_val != 0)
return ret_val;
- atomic_set(&netlabel_unlabel_accept_flg, 1);
+ netlbl_unlabel_acceptflg_set(1, &audit_info);
return 0;
}
diff --git a/net/netlabel/netlabel_user.c b/net/netlabel/netlabel_user.c
index eeb7d768d2bb..98a416381e61 100644
--- a/net/netlabel/netlabel_user.c
+++ b/net/netlabel/netlabel_user.c
@@ -32,6 +32,9 @@
#include <linux/types.h>
#include <linux/list.h>
#include <linux/socket.h>
+#include <linux/audit.h>
+#include <linux/tty.h>
+#include <linux/security.h>
#include <net/sock.h>
#include <net/netlink.h>
#include <net/genetlink.h>
@@ -74,3 +77,41 @@ int netlbl_netlink_init(void)
return 0;
}
+
+/*
+ * NetLabel Audit Functions
+ */
+
+/**
+ * netlbl_audit_start_common - Start an audit message
+ * @type: audit message type
+ * @audit_info: NetLabel audit information
+ *
+ * Description:
+ * Start an audit message using the type specified in @type and fill the audit
+ * message with some fields common to all NetLabel audit messages. Returns
+ * a pointer to the audit buffer on success, NULL on failure.
+ *
+ */
+struct audit_buffer *netlbl_audit_start_common(int type,
+ struct netlbl_audit *audit_info)
+{
+ struct audit_context *audit_ctx = current->audit_context;
+ struct audit_buffer *audit_buf;
+ char *secctx;
+ u32 secctx_len;
+
+ audit_buf = audit_log_start(audit_ctx, GFP_ATOMIC, type);
+ if (audit_buf == NULL)
+ return NULL;
+
+ audit_log_format(audit_buf, "netlabel: auid=%u", audit_info->loginuid);
+
+ if (audit_info->secid != 0 &&
+ security_secid_to_secctx(audit_info->secid,
+ &secctx,
+ &secctx_len) == 0)
+ audit_log_format(audit_buf, " subj=%s", secctx);
+
+ return audit_buf;
+}
diff --git a/net/netlabel/netlabel_user.h b/net/netlabel/netlabel_user.h
index 3f9386b917df..47967ef32964 100644
--- a/net/netlabel/netlabel_user.h
+++ b/net/netlabel/netlabel_user.h
@@ -34,6 +34,7 @@
#include <linux/types.h>
#include <linux/skbuff.h>
#include <linux/capability.h>
+#include <linux/audit.h>
#include <net/netlink.h>
#include <net/genetlink.h>
#include <net/netlabel.h>
@@ -71,8 +72,25 @@ static inline void *netlbl_netlink_hdr_put(struct sk_buff *skb,
NETLBL_PROTO_VERSION);
}
+/**
+ * netlbl_netlink_auditinfo - Fetch the audit information from a NETLINK msg
+ * @skb: the packet
+ * @audit_info: NetLabel audit information
+ */
+static inline void netlbl_netlink_auditinfo(struct sk_buff *skb,
+ struct netlbl_audit *audit_info)
+{
+ audit_info->secid = NETLINK_CB(skb).sid;
+ audit_info->loginuid = NETLINK_CB(skb).loginuid;
+}
+
/* NetLabel NETLINK I/O functions */
int netlbl_netlink_init(void);
+/* NetLabel Audit Functions */
+
+struct audit_buffer *netlbl_audit_start_common(int type,
+ struct netlbl_audit *audit_info);
+
#endif
diff --git a/net/rxrpc/transport.c b/net/rxrpc/transport.c
index 465efc86fccf..94b2e2fe6fdb 100644
--- a/net/rxrpc/transport.c
+++ b/net/rxrpc/transport.c
@@ -381,11 +381,10 @@ static int rxrpc_incoming_msg(struct rxrpc_transport *trans,
/* allocate a new message record */
ret = -ENOMEM;
- msg = kmalloc(sizeof(struct rxrpc_message), GFP_KERNEL);
+ msg = kmemdup(jumbomsg, sizeof(struct rxrpc_message), GFP_KERNEL);
if (!msg)
goto error;
- memcpy(msg, jumbomsg, sizeof(*msg));
list_add_tail(&msg->link, msgq);
/* adjust the jumbo packet */
diff --git a/net/sched/cls_api.c b/net/sched/cls_api.c
index 7e14f14058e9..37a184021647 100644
--- a/net/sched/cls_api.c
+++ b/net/sched/cls_api.c
@@ -401,7 +401,7 @@ static int tc_dump_tfilter(struct sk_buff *skb, struct netlink_callback *cb)
if ((dev = dev_get_by_index(tcm->tcm_ifindex)) == NULL)
return skb->len;
- read_lock_bh(&qdisc_tree_lock);
+ read_lock(&qdisc_tree_lock);
if (!tcm->tcm_parent)
q = dev->qdisc_sleeping;
else
@@ -458,7 +458,7 @@ errout:
if (cl)
cops->put(q, cl);
out:
- read_unlock_bh(&qdisc_tree_lock);
+ read_unlock(&qdisc_tree_lock);
dev_put(dev);
return skb->len;
}
diff --git a/net/sched/cls_basic.c b/net/sched/cls_basic.c
index 86cac49a0531..09fda68c8b39 100644
--- a/net/sched/cls_basic.c
+++ b/net/sched/cls_basic.c
@@ -194,7 +194,7 @@ static int basic_change(struct tcf_proto *tp, unsigned long base, u32 handle,
if (handle)
f->handle = handle;
else {
- int i = 0x80000000;
+ unsigned int i = 0x80000000;
do {
if (++head->hgenerator == 0x7FFFFFFF)
head->hgenerator = 1;
diff --git a/net/sched/sch_api.c b/net/sched/sch_api.c
index a19eff12cf78..0b6489291140 100644
--- a/net/sched/sch_api.c
+++ b/net/sched/sch_api.c
@@ -195,14 +195,14 @@ struct Qdisc *qdisc_lookup(struct net_device *dev, u32 handle)
{
struct Qdisc *q;
- read_lock_bh(&qdisc_tree_lock);
+ read_lock(&qdisc_tree_lock);
list_for_each_entry(q, &dev->qdisc_list, list) {
if (q->handle == handle) {
- read_unlock_bh(&qdisc_tree_lock);
+ read_unlock(&qdisc_tree_lock);
return q;
}
}
- read_unlock_bh(&qdisc_tree_lock);
+ read_unlock(&qdisc_tree_lock);
return NULL;
}
@@ -837,7 +837,7 @@ static int tc_dump_qdisc(struct sk_buff *skb, struct netlink_callback *cb)
continue;
if (idx > s_idx)
s_q_idx = 0;
- read_lock_bh(&qdisc_tree_lock);
+ read_lock(&qdisc_tree_lock);
q_idx = 0;
list_for_each_entry(q, &dev->qdisc_list, list) {
if (q_idx < s_q_idx) {
@@ -846,12 +846,12 @@ static int tc_dump_qdisc(struct sk_buff *skb, struct netlink_callback *cb)
}
if (tc_fill_qdisc(skb, q, q->parent, NETLINK_CB(cb->skb).pid,
cb->nlh->nlmsg_seq, NLM_F_MULTI, RTM_NEWQDISC) <= 0) {
- read_unlock_bh(&qdisc_tree_lock);
+ read_unlock(&qdisc_tree_lock);
goto done;
}
q_idx++;
}
- read_unlock_bh(&qdisc_tree_lock);
+ read_unlock(&qdisc_tree_lock);
}
done:
@@ -1074,7 +1074,7 @@ static int tc_dump_tclass(struct sk_buff *skb, struct netlink_callback *cb)
s_t = cb->args[0];
t = 0;
- read_lock_bh(&qdisc_tree_lock);
+ read_lock(&qdisc_tree_lock);
list_for_each_entry(q, &dev->qdisc_list, list) {
if (t < s_t || !q->ops->cl_ops ||
(tcm->tcm_parent &&
@@ -1096,7 +1096,7 @@ static int tc_dump_tclass(struct sk_buff *skb, struct netlink_callback *cb)
break;
t++;
}
- read_unlock_bh(&qdisc_tree_lock);
+ read_unlock(&qdisc_tree_lock);
cb->args[0] = t;
diff --git a/net/sched/sch_generic.c b/net/sched/sch_generic.c
index 6f9151899795..88c6a99ce53c 100644
--- a/net/sched/sch_generic.c
+++ b/net/sched/sch_generic.c
@@ -45,11 +45,10 @@
The idea is the following:
- enqueue, dequeue are serialized via top level device
spinlock dev->queue_lock.
- - tree walking is protected by read_lock_bh(qdisc_tree_lock)
+ - tree walking is protected by read_lock(qdisc_tree_lock)
and this lock is used only in process context.
- - updates to tree are made under rtnl semaphore or
- from softirq context (__qdisc_destroy rcu-callback)
- hence this lock needs local bh disabling.
+ - updates to tree are made only under rtnl semaphore,
+ hence this lock may be made without local bh disabling.
qdisc_tree_lock must be grabbed BEFORE dev->queue_lock!
*/
@@ -57,14 +56,14 @@ DEFINE_RWLOCK(qdisc_tree_lock);
void qdisc_lock_tree(struct net_device *dev)
{
- write_lock_bh(&qdisc_tree_lock);
+ write_lock(&qdisc_tree_lock);
spin_lock_bh(&dev->queue_lock);
}
void qdisc_unlock_tree(struct net_device *dev)
{
spin_unlock_bh(&dev->queue_lock);
- write_unlock_bh(&qdisc_tree_lock);
+ write_unlock(&qdisc_tree_lock);
}
/*
@@ -483,20 +482,6 @@ void qdisc_reset(struct Qdisc *qdisc)
static void __qdisc_destroy(struct rcu_head *head)
{
struct Qdisc *qdisc = container_of(head, struct Qdisc, q_rcu);
- struct Qdisc_ops *ops = qdisc->ops;
-
-#ifdef CONFIG_NET_ESTIMATOR
- gen_kill_estimator(&qdisc->bstats, &qdisc->rate_est);
-#endif
- write_lock(&qdisc_tree_lock);
- if (ops->reset)
- ops->reset(qdisc);
- if (ops->destroy)
- ops->destroy(qdisc);
- write_unlock(&qdisc_tree_lock);
- module_put(ops->owner);
-
- dev_put(qdisc->dev);
kfree((char *) qdisc - qdisc->padded);
}
@@ -504,32 +489,23 @@ static void __qdisc_destroy(struct rcu_head *head)
void qdisc_destroy(struct Qdisc *qdisc)
{
- struct list_head cql = LIST_HEAD_INIT(cql);
- struct Qdisc *cq, *q, *n;
+ struct Qdisc_ops *ops = qdisc->ops;
if (qdisc->flags & TCQ_F_BUILTIN ||
- !atomic_dec_and_test(&qdisc->refcnt))
+ !atomic_dec_and_test(&qdisc->refcnt))
return;
- if (!list_empty(&qdisc->list)) {
- if (qdisc->ops->cl_ops == NULL)
- list_del(&qdisc->list);
- else
- list_move(&qdisc->list, &cql);
- }
-
- /* unlink inner qdiscs from dev->qdisc_list immediately */
- list_for_each_entry(cq, &cql, list)
- list_for_each_entry_safe(q, n, &qdisc->dev->qdisc_list, list)
- if (TC_H_MAJ(q->parent) == TC_H_MAJ(cq->handle)) {
- if (q->ops->cl_ops == NULL)
- list_del_init(&q->list);
- else
- list_move_tail(&q->list, &cql);
- }
- list_for_each_entry_safe(cq, n, &cql, list)
- list_del_init(&cq->list);
+ list_del(&qdisc->list);
+#ifdef CONFIG_NET_ESTIMATOR
+ gen_kill_estimator(&qdisc->bstats, &qdisc->rate_est);
+#endif
+ if (ops->reset)
+ ops->reset(qdisc);
+ if (ops->destroy)
+ ops->destroy(qdisc);
+ module_put(ops->owner);
+ dev_put(qdisc->dev);
call_rcu(&qdisc->q_rcu, __qdisc_destroy);
}
@@ -549,15 +525,15 @@ void dev_activate(struct net_device *dev)
printk(KERN_INFO "%s: activation failed\n", dev->name);
return;
}
- write_lock_bh(&qdisc_tree_lock);
+ write_lock(&qdisc_tree_lock);
list_add_tail(&qdisc->list, &dev->qdisc_list);
- write_unlock_bh(&qdisc_tree_lock);
+ write_unlock(&qdisc_tree_lock);
} else {
qdisc = &noqueue_qdisc;
}
- write_lock_bh(&qdisc_tree_lock);
+ write_lock(&qdisc_tree_lock);
dev->qdisc_sleeping = qdisc;
- write_unlock_bh(&qdisc_tree_lock);
+ write_unlock(&qdisc_tree_lock);
}
if (!netif_carrier_ok(dev))
diff --git a/net/sched/sch_htb.c b/net/sched/sch_htb.c
index bb3ddd4784b1..6c058e3660c0 100644
--- a/net/sched/sch_htb.c
+++ b/net/sched/sch_htb.c
@@ -391,7 +391,7 @@ static inline void htb_add_class_to_row(struct htb_sched *q,
/* If this triggers, it is a bug in this code, but it need not be fatal */
static void htb_safe_rb_erase(struct rb_node *rb, struct rb_root *root)
{
- if (RB_EMPTY_NODE(rb)) {
+ if (!RB_EMPTY_NODE(rb)) {
WARN_ON(1);
} else {
rb_erase(rb, root);
diff --git a/net/sctp/input.c b/net/sctp/input.c
index 03f65de75d88..64f630102532 100644
--- a/net/sctp/input.c
+++ b/net/sctp/input.c
@@ -218,12 +218,6 @@ int sctp_rcv(struct sk_buff *skb)
}
}
- /* SCTP seems to always need a timestamp right now (FIXME) */
- if (skb->tstamp.off_sec == 0) {
- __net_timestamp(skb);
- sock_enable_timestamp(sk);
- }
-
if (!xfrm_policy_check(sk, XFRM_POLICY_IN, skb, family))
goto discard_release;
nf_reset(skb);
@@ -388,7 +382,7 @@ void sctp_icmp_frag_needed(struct sock *sk, struct sctp_association *asoc,
* pmtu discovery on this transport.
*/
t->pathmtu = SCTP_DEFAULT_MINSEGMENT;
- t->param_flags = (t->param_flags & ~SPP_HB) |
+ t->param_flags = (t->param_flags & ~SPP_PMTUD) |
SPP_PMTUD_DISABLE;
} else {
t->pathmtu = pmtu;
diff --git a/net/sctp/output.c b/net/sctp/output.c
index cdc5a3936766..3ef4351dd956 100644
--- a/net/sctp/output.c
+++ b/net/sctp/output.c
@@ -633,7 +633,7 @@ static sctp_xmit_t sctp_packet_append_data(struct sctp_packet *packet,
* data will fit or delay in hopes of bundling a full
* sized packet.
*/
- if (len < asoc->pathmtu - packet->overhead) {
+ if (len < asoc->frag_point) {
retval = SCTP_XMIT_NAGLE_DELAY;
goto finish;
}
@@ -645,7 +645,13 @@ static sctp_xmit_t sctp_packet_append_data(struct sctp_packet *packet,
/* Keep track of how many bytes are in flight to the receiver. */
asoc->outqueue.outstanding_bytes += datasize;
- /* Update our view of the receiver's rwnd. */
+ /* Update our view of the receiver's rwnd. Include sk_buff overhead
+ * while updating peer.rwnd so that it reduces the chances of a
+ * receiver running out of receive buffer space even when receive
+ * window is still open. This can happen when a sender is sending
+ * sending small messages.
+ */
+ datasize += sizeof(struct sk_buff);
if (datasize < rwnd)
rwnd -= datasize;
else
diff --git a/net/sctp/outqueue.c b/net/sctp/outqueue.c
index 37074a39ecbb..739582415bf6 100644
--- a/net/sctp/outqueue.c
+++ b/net/sctp/outqueue.c
@@ -416,7 +416,8 @@ void sctp_retransmit_mark(struct sctp_outq *q,
* (Section 7.2.4)), add the data size of those
* chunks to the rwnd.
*/
- q->asoc->peer.rwnd += sctp_data_size(chunk);
+ q->asoc->peer.rwnd += (sctp_data_size(chunk) +
+ sizeof(struct sk_buff));
q->outstanding_bytes -= sctp_data_size(chunk);
transport->flight_size -= sctp_data_size(chunk);
diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c
index 7745bdea7817..507dff72c585 100644
--- a/net/sctp/sm_make_chunk.c
+++ b/net/sctp/sm_make_chunk.c
@@ -1447,8 +1447,16 @@ no_hmac:
/* Check to see if the cookie is stale. If there is already
* an association, there is no need to check cookie's expiration
* for init collision case of lost COOKIE ACK.
+ * If skb has been timestamped, then use the stamp, otherwise
+ * use current time. This introduces a small possibility that
+ * that a cookie may be considered expired, but his would only slow
+ * down the new association establishment instead of every packet.
*/
- skb_get_timestamp(skb, &tv);
+ if (sock_flag(ep->base.sk, SOCK_TIMESTAMP))
+ skb_get_timestamp(skb, &tv);
+ else
+ do_gettimeofday(&tv);
+
if (!asoc && tv_lt(bear_cookie->expiration, tv)) {
__u16 len;
/*
diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index 79c3e072cf28..3fe906d65069 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -3084,8 +3084,8 @@ SCTP_STATIC int sctp_init_sock(struct sock *sk)
*/
sp->disable_fragments = 0;
- /* Turn on/off any Nagle-like algorithm. */
- sp->nodelay = 1;
+ /* Enable Nagle algorithm by default. */
+ sp->nodelay = 0;
/* Enable by default. */
sp->v4mapped = 1;
diff --git a/net/socket.c b/net/socket.c
index 1bc4167e0da8..6c9b9b326d76 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -95,10 +95,10 @@
#include <linux/netfilter.h>
static int sock_no_open(struct inode *irrelevant, struct file *dontcare);
-static ssize_t sock_aio_read(struct kiocb *iocb, char __user *buf,
- size_t size, loff_t pos);
-static ssize_t sock_aio_write(struct kiocb *iocb, const char __user *buf,
- size_t size, loff_t pos);
+static ssize_t sock_aio_read(struct kiocb *iocb, const struct iovec *iov,
+ unsigned long nr_segs, loff_t pos);
+static ssize_t sock_aio_write(struct kiocb *iocb, const struct iovec *iov,
+ unsigned long nr_segs, loff_t pos);
static int sock_mmap(struct file *file, struct vm_area_struct *vma);
static int sock_close(struct inode *inode, struct file *file);
@@ -110,10 +110,6 @@ static long compat_sock_ioctl(struct file *file,
unsigned int cmd, unsigned long arg);
#endif
static int sock_fasync(int fd, struct file *filp, int on);
-static ssize_t sock_readv(struct file *file, const struct iovec *vector,
- unsigned long count, loff_t *ppos);
-static ssize_t sock_writev(struct file *file, const struct iovec *vector,
- unsigned long count, loff_t *ppos);
static ssize_t sock_sendpage(struct file *file, struct page *page,
int offset, size_t size, loff_t *ppos, int more);
@@ -136,8 +132,6 @@ static struct file_operations socket_file_ops = {
.open = sock_no_open, /* special open code to disallow open via /proc */
.release = sock_close,
.fasync = sock_fasync,
- .readv = sock_readv,
- .writev = sock_writev,
.sendpage = sock_sendpage,
.splice_write = generic_splice_sendpage,
};
@@ -664,7 +658,6 @@ static ssize_t sock_sendpage(struct file *file, struct page *page,
}
static struct sock_iocb *alloc_sock_iocb(struct kiocb *iocb,
- char __user *ubuf, size_t size,
struct sock_iocb *siocb)
{
if (!is_sync_kiocb(iocb)) {
@@ -675,16 +668,13 @@ static struct sock_iocb *alloc_sock_iocb(struct kiocb *iocb,
}
siocb->kiocb = iocb;
- siocb->async_iov.iov_base = ubuf;
- siocb->async_iov.iov_len = size;
-
iocb->private = siocb;
return siocb;
}
static ssize_t do_sock_read(struct msghdr *msg, struct kiocb *iocb,
- struct file *file, struct iovec *iov,
- unsigned long nr_segs)
+ struct file *file, const struct iovec *iov,
+ unsigned long nr_segs)
{
struct socket *sock = file->private_data;
size_t size = 0;
@@ -704,43 +694,27 @@ static ssize_t do_sock_read(struct msghdr *msg, struct kiocb *iocb,
return __sock_recvmsg(iocb, sock, msg, size, msg->msg_flags);
}
-static ssize_t sock_readv(struct file *file, const struct iovec *iov,
- unsigned long nr_segs, loff_t *ppos)
-{
- struct kiocb iocb;
- struct sock_iocb siocb;
- struct msghdr msg;
- int ret;
-
- init_sync_kiocb(&iocb, NULL);
- iocb.private = &siocb;
-
- ret = do_sock_read(&msg, &iocb, file, (struct iovec *)iov, nr_segs);
- if (-EIOCBQUEUED == ret)
- ret = wait_on_sync_kiocb(&iocb);
- return ret;
-}
-
-static ssize_t sock_aio_read(struct kiocb *iocb, char __user *ubuf,
- size_t count, loff_t pos)
+static ssize_t sock_aio_read(struct kiocb *iocb, const struct iovec *iov,
+ unsigned long nr_segs, loff_t pos)
{
struct sock_iocb siocb, *x;
if (pos != 0)
return -ESPIPE;
- if (count == 0) /* Match SYS5 behaviour */
+
+ if (iocb->ki_left == 0) /* Match SYS5 behaviour */
return 0;
- x = alloc_sock_iocb(iocb, ubuf, count, &siocb);
+
+ x = alloc_sock_iocb(iocb, &siocb);
if (!x)
return -ENOMEM;
- return do_sock_read(&x->async_msg, iocb, iocb->ki_filp,
- &x->async_iov, 1);
+ return do_sock_read(&x->async_msg, iocb, iocb->ki_filp, iov, nr_segs);
}
static ssize_t do_sock_write(struct msghdr *msg, struct kiocb *iocb,
- struct file *file, struct iovec *iov,
- unsigned long nr_segs)
+ struct file *file, const struct iovec *iov,
+ unsigned long nr_segs)
{
struct socket *sock = file->private_data;
size_t size = 0;
@@ -762,39 +736,22 @@ static ssize_t do_sock_write(struct msghdr *msg, struct kiocb *iocb,
return __sock_sendmsg(iocb, sock, msg, size);
}
-static ssize_t sock_writev(struct file *file, const struct iovec *iov,
- unsigned long nr_segs, loff_t *ppos)
-{
- struct msghdr msg;
- struct kiocb iocb;
- struct sock_iocb siocb;
- int ret;
-
- init_sync_kiocb(&iocb, NULL);
- iocb.private = &siocb;
-
- ret = do_sock_write(&msg, &iocb, file, (struct iovec *)iov, nr_segs);
- if (-EIOCBQUEUED == ret)
- ret = wait_on_sync_kiocb(&iocb);
- return ret;
-}
-
-static ssize_t sock_aio_write(struct kiocb *iocb, const char __user *ubuf,
- size_t count, loff_t pos)
+static ssize_t sock_aio_write(struct kiocb *iocb, const struct iovec *iov,
+ unsigned long nr_segs, loff_t pos)
{
struct sock_iocb siocb, *x;
if (pos != 0)
return -ESPIPE;
- if (count == 0) /* Match SYS5 behaviour */
+
+ if (iocb->ki_left == 0) /* Match SYS5 behaviour */
return 0;
- x = alloc_sock_iocb(iocb, (void __user *)ubuf, count, &siocb);
+ x = alloc_sock_iocb(iocb, &siocb);
if (!x)
return -ENOMEM;
- return do_sock_write(&x->async_msg, iocb, iocb->ki_filp,
- &x->async_iov, 1);
+ return do_sock_write(&x->async_msg, iocb, iocb->ki_filp, iov, nr_segs);
}
/*
@@ -868,7 +825,7 @@ static long sock_ioctl(struct file *file, unsigned cmd, unsigned long arg)
break;
case FIOGETOWN:
case SIOCGPGRP:
- err = put_user(sock->file->f_owner.pid,
+ err = put_user(f_getown(sock->file),
(int __user *)argp);
break;
case SIOCGIFBR:
diff --git a/net/sunrpc/auth.c b/net/sunrpc/auth.c
index 55163af3dcaf..993ff1a5d945 100644
--- a/net/sunrpc/auth.c
+++ b/net/sunrpc/auth.c
@@ -331,8 +331,8 @@ rpcauth_unbindcred(struct rpc_task *task)
task->tk_msg.rpc_cred = NULL;
}
-u32 *
-rpcauth_marshcred(struct rpc_task *task, u32 *p)
+__be32 *
+rpcauth_marshcred(struct rpc_task *task, __be32 *p)
{
struct rpc_cred *cred = task->tk_msg.rpc_cred;
@@ -342,8 +342,8 @@ rpcauth_marshcred(struct rpc_task *task, u32 *p)
return cred->cr_ops->crmarshal(task, p);
}
-u32 *
-rpcauth_checkverf(struct rpc_task *task, u32 *p)
+__be32 *
+rpcauth_checkverf(struct rpc_task *task, __be32 *p)
{
struct rpc_cred *cred = task->tk_msg.rpc_cred;
@@ -355,7 +355,7 @@ rpcauth_checkverf(struct rpc_task *task, u32 *p)
int
rpcauth_wrap_req(struct rpc_task *task, kxdrproc_t encode, void *rqstp,
- u32 *data, void *obj)
+ __be32 *data, void *obj)
{
struct rpc_cred *cred = task->tk_msg.rpc_cred;
@@ -369,7 +369,7 @@ rpcauth_wrap_req(struct rpc_task *task, kxdrproc_t encode, void *rqstp,
int
rpcauth_unwrap_resp(struct rpc_task *task, kxdrproc_t decode, void *rqstp,
- u32 *data, void *obj)
+ __be32 *data, void *obj)
{
struct rpc_cred *cred = task->tk_msg.rpc_cred;
diff --git a/net/sunrpc/auth_gss/auth_gss.c b/net/sunrpc/auth_gss/auth_gss.c
index 6eed3e166ba3..a6ed2d22a6e6 100644
--- a/net/sunrpc/auth_gss/auth_gss.c
+++ b/net/sunrpc/auth_gss/auth_gss.c
@@ -826,14 +826,14 @@ out:
* Marshal credentials.
* Maybe we should keep a cached credential for performance reasons.
*/
-static u32 *
-gss_marshal(struct rpc_task *task, u32 *p)
+static __be32 *
+gss_marshal(struct rpc_task *task, __be32 *p)
{
struct rpc_cred *cred = task->tk_msg.rpc_cred;
struct gss_cred *gss_cred = container_of(cred, struct gss_cred,
gc_base);
struct gss_cl_ctx *ctx = gss_cred_get_ctx(cred);
- u32 *cred_len;
+ __be32 *cred_len;
struct rpc_rqst *req = task->tk_rqstp;
u32 maj_stat = 0;
struct xdr_netobj mic;
@@ -894,12 +894,12 @@ gss_refresh(struct rpc_task *task)
return 0;
}
-static u32 *
-gss_validate(struct rpc_task *task, u32 *p)
+static __be32 *
+gss_validate(struct rpc_task *task, __be32 *p)
{
struct rpc_cred *cred = task->tk_msg.rpc_cred;
struct gss_cl_ctx *ctx = gss_cred_get_ctx(cred);
- u32 seq;
+ __be32 seq;
struct kvec iov;
struct xdr_buf verf_buf;
struct xdr_netobj mic;
@@ -940,13 +940,14 @@ out_bad:
static inline int
gss_wrap_req_integ(struct rpc_cred *cred, struct gss_cl_ctx *ctx,
- kxdrproc_t encode, struct rpc_rqst *rqstp, u32 *p, void *obj)
+ kxdrproc_t encode, struct rpc_rqst *rqstp, __be32 *p, void *obj)
{
struct xdr_buf *snd_buf = &rqstp->rq_snd_buf;
struct xdr_buf integ_buf;
- u32 *integ_len = NULL;
+ __be32 *integ_len = NULL;
struct xdr_netobj mic;
- u32 offset, *q;
+ u32 offset;
+ __be32 *q;
struct kvec *iov;
u32 maj_stat = 0;
int status = -EIO;
@@ -1032,13 +1033,13 @@ out:
static inline int
gss_wrap_req_priv(struct rpc_cred *cred, struct gss_cl_ctx *ctx,
- kxdrproc_t encode, struct rpc_rqst *rqstp, u32 *p, void *obj)
+ kxdrproc_t encode, struct rpc_rqst *rqstp, __be32 *p, void *obj)
{
struct xdr_buf *snd_buf = &rqstp->rq_snd_buf;
u32 offset;
u32 maj_stat;
int status;
- u32 *opaque_len;
+ __be32 *opaque_len;
struct page **inpages;
int first;
int pad;
@@ -1095,7 +1096,7 @@ gss_wrap_req_priv(struct rpc_cred *cred, struct gss_cl_ctx *ctx,
static int
gss_wrap_req(struct rpc_task *task,
- kxdrproc_t encode, void *rqstp, u32 *p, void *obj)
+ kxdrproc_t encode, void *rqstp, __be32 *p, void *obj)
{
struct rpc_cred *cred = task->tk_msg.rpc_cred;
struct gss_cred *gss_cred = container_of(cred, struct gss_cred,
@@ -1132,7 +1133,7 @@ out:
static inline int
gss_unwrap_resp_integ(struct rpc_cred *cred, struct gss_cl_ctx *ctx,
- struct rpc_rqst *rqstp, u32 **p)
+ struct rpc_rqst *rqstp, __be32 **p)
{
struct xdr_buf *rcv_buf = &rqstp->rq_rcv_buf;
struct xdr_buf integ_buf;
@@ -1169,7 +1170,7 @@ gss_unwrap_resp_integ(struct rpc_cred *cred, struct gss_cl_ctx *ctx,
static inline int
gss_unwrap_resp_priv(struct rpc_cred *cred, struct gss_cl_ctx *ctx,
- struct rpc_rqst *rqstp, u32 **p)
+ struct rpc_rqst *rqstp, __be32 **p)
{
struct xdr_buf *rcv_buf = &rqstp->rq_rcv_buf;
u32 offset;
@@ -1198,13 +1199,13 @@ gss_unwrap_resp_priv(struct rpc_cred *cred, struct gss_cl_ctx *ctx,
static int
gss_unwrap_resp(struct rpc_task *task,
- kxdrproc_t decode, void *rqstp, u32 *p, void *obj)
+ kxdrproc_t decode, void *rqstp, __be32 *p, void *obj)
{
struct rpc_cred *cred = task->tk_msg.rpc_cred;
struct gss_cred *gss_cred = container_of(cred, struct gss_cred,
gc_base);
struct gss_cl_ctx *ctx = gss_cred_get_ctx(cred);
- u32 *savedp = p;
+ __be32 *savedp = p;
struct kvec *head = ((struct rpc_rqst *)rqstp)->rq_rcv_buf.head;
int savedlen = head->iov_len;
int status = -EIO;
diff --git a/net/sunrpc/auth_gss/gss_krb5_seal.c b/net/sunrpc/auth_gss/gss_krb5_seal.c
index 2f312164d6d5..08601ee4cd73 100644
--- a/net/sunrpc/auth_gss/gss_krb5_seal.c
+++ b/net/sunrpc/auth_gss/gss_krb5_seal.c
@@ -115,7 +115,7 @@ gss_get_mic_kerberos(struct gss_ctx *gss_ctx, struct xdr_buf *text,
krb5_hdr = ptr - 2;
msg_start = krb5_hdr + 24;
- *(u16 *)(krb5_hdr + 2) = htons(ctx->signalg);
+ *(__be16 *)(krb5_hdr + 2) = htons(ctx->signalg);
memset(krb5_hdr + 4, 0xff, 4);
if (make_checksum(checksum_type, krb5_hdr, 8, text, 0, &md5cksum))
diff --git a/net/sunrpc/auth_gss/gss_krb5_wrap.c b/net/sunrpc/auth_gss/gss_krb5_wrap.c
index f179415d0c38..cc45c1605f80 100644
--- a/net/sunrpc/auth_gss/gss_krb5_wrap.c
+++ b/net/sunrpc/auth_gss/gss_krb5_wrap.c
@@ -177,9 +177,9 @@ gss_wrap_kerberos(struct gss_ctx *ctx, int offset,
msg_start = krb5_hdr + 24;
/* XXXJBF: */ BUG_ON(buf->head[0].iov_base + offset + headlen != msg_start + blocksize);
- *(u16 *)(krb5_hdr + 2) = htons(kctx->signalg);
+ *(__be16 *)(krb5_hdr + 2) = htons(kctx->signalg);
memset(krb5_hdr + 4, 0xff, 4);
- *(u16 *)(krb5_hdr + 4) = htons(kctx->sealalg);
+ *(__be16 *)(krb5_hdr + 4) = htons(kctx->sealalg);
make_confounder(msg_start, blocksize);
diff --git a/net/sunrpc/auth_gss/svcauth_gss.c b/net/sunrpc/auth_gss/svcauth_gss.c
index 94217ec9e2dd..638c0b576203 100644
--- a/net/sunrpc/auth_gss/svcauth_gss.c
+++ b/net/sunrpc/auth_gss/svcauth_gss.c
@@ -607,7 +607,7 @@ svc_safe_getnetobj(struct kvec *argv, struct xdr_netobj *o)
if (argv->iov_len < 4)
return -1;
- o->len = ntohl(svc_getu32(argv));
+ o->len = svc_getnl(argv);
l = round_up_to_quad(o->len);
if (argv->iov_len < l)
return -1;
@@ -620,17 +620,17 @@ svc_safe_getnetobj(struct kvec *argv, struct xdr_netobj *o)
static inline int
svc_safe_putnetobj(struct kvec *resv, struct xdr_netobj *o)
{
- u32 *p;
+ u8 *p;
if (resv->iov_len + 4 > PAGE_SIZE)
return -1;
- svc_putu32(resv, htonl(o->len));
+ svc_putnl(resv, o->len);
p = resv->iov_base + resv->iov_len;
resv->iov_len += round_up_to_quad(o->len);
if (resv->iov_len > PAGE_SIZE)
return -1;
memcpy(p, o->data, o->len);
- memset((u8 *)p + o->len, 0, round_up_to_quad(o->len) - o->len);
+ memset(p + o->len, 0, round_up_to_quad(o->len) - o->len);
return 0;
}
@@ -640,7 +640,7 @@ svc_safe_putnetobj(struct kvec *resv, struct xdr_netobj *o)
*/
static int
gss_verify_header(struct svc_rqst *rqstp, struct rsc *rsci,
- u32 *rpcstart, struct rpc_gss_wire_cred *gc, u32 *authp)
+ __be32 *rpcstart, struct rpc_gss_wire_cred *gc, __be32 *authp)
{
struct gss_ctx *ctx_id = rsci->mechctx;
struct xdr_buf rpchdr;
@@ -657,7 +657,7 @@ gss_verify_header(struct svc_rqst *rqstp, struct rsc *rsci,
*authp = rpc_autherr_badverf;
if (argv->iov_len < 4)
return SVC_DENIED;
- flavor = ntohl(svc_getu32(argv));
+ flavor = svc_getnl(argv);
if (flavor != RPC_AUTH_GSS)
return SVC_DENIED;
if (svc_safe_getnetobj(argv, &checksum))
@@ -687,9 +687,9 @@ gss_verify_header(struct svc_rqst *rqstp, struct rsc *rsci,
static int
gss_write_null_verf(struct svc_rqst *rqstp)
{
- u32 *p;
+ __be32 *p;
- svc_putu32(rqstp->rq_res.head, htonl(RPC_AUTH_NULL));
+ svc_putnl(rqstp->rq_res.head, RPC_AUTH_NULL);
p = rqstp->rq_res.head->iov_base + rqstp->rq_res.head->iov_len;
/* don't really need to check if head->iov_len > PAGE_SIZE ... */
*p++ = 0;
@@ -701,14 +701,14 @@ gss_write_null_verf(struct svc_rqst *rqstp)
static int
gss_write_verf(struct svc_rqst *rqstp, struct gss_ctx *ctx_id, u32 seq)
{
- u32 xdr_seq;
+ __be32 xdr_seq;
u32 maj_stat;
struct xdr_buf verf_data;
struct xdr_netobj mic;
- u32 *p;
+ __be32 *p;
struct kvec iov;
- svc_putu32(rqstp->rq_res.head, htonl(RPC_AUTH_GSS));
+ svc_putnl(rqstp->rq_res.head, RPC_AUTH_GSS);
xdr_seq = htonl(seq);
iov.iov_base = &xdr_seq;
@@ -782,7 +782,7 @@ EXPORT_SYMBOL(svcauth_gss_register_pseudoflavor);
static inline int
read_u32_from_xdr_buf(struct xdr_buf *buf, int base, u32 *obj)
{
- u32 raw;
+ __be32 raw;
int status;
status = read_bytes_from_xdr_buf(buf, base, &raw, sizeof(*obj));
@@ -805,7 +805,7 @@ unwrap_integ_data(struct xdr_buf *buf, u32 seq, struct gss_ctx *ctx)
struct xdr_netobj mic;
struct xdr_buf integ_buf;
- integ_len = ntohl(svc_getu32(&buf->head[0]));
+ integ_len = svc_getnl(&buf->head[0]);
if (integ_len & 3)
goto out;
if (integ_len > buf->len)
@@ -825,7 +825,7 @@ unwrap_integ_data(struct xdr_buf *buf, u32 seq, struct gss_ctx *ctx)
maj_stat = gss_verify_mic(ctx, &integ_buf, &mic);
if (maj_stat != GSS_S_COMPLETE)
goto out;
- if (ntohl(svc_getu32(&buf->head[0])) != seq)
+ if (svc_getnl(&buf->head[0]) != seq)
goto out;
stat = 0;
out:
@@ -857,7 +857,7 @@ unwrap_priv_data(struct svc_rqst *rqstp, struct xdr_buf *buf, u32 seq, struct gs
rqstp->rq_sendfile_ok = 0;
- priv_len = ntohl(svc_getu32(&buf->head[0]));
+ priv_len = svc_getnl(&buf->head[0]);
if (rqstp->rq_deferred) {
/* Already decrypted last time through! The sequence number
* check at out_seq is unnecessary but harmless: */
@@ -895,7 +895,7 @@ unwrap_priv_data(struct svc_rqst *rqstp, struct xdr_buf *buf, u32 seq, struct gs
if (maj_stat != GSS_S_COMPLETE)
return -EINVAL;
out_seq:
- if (ntohl(svc_getu32(&buf->head[0])) != seq)
+ if (svc_getnl(&buf->head[0]) != seq)
return -EINVAL;
return 0;
}
@@ -905,7 +905,7 @@ struct gss_svc_data {
struct rpc_gss_wire_cred clcred;
/* pointer to the beginning of the procedure-specific results,
* which may be encrypted/checksummed in svcauth_gss_release: */
- u32 *body_start;
+ __be32 *body_start;
struct rsc *rsci;
};
@@ -946,7 +946,7 @@ gss_write_init_verf(struct svc_rqst *rqstp, struct rsi *rsip)
* response here and return SVC_COMPLETE.
*/
static int
-svcauth_gss_accept(struct svc_rqst *rqstp, u32 *authp)
+svcauth_gss_accept(struct svc_rqst *rqstp, __be32 *authp)
{
struct kvec *argv = &rqstp->rq_arg.head[0];
struct kvec *resv = &rqstp->rq_res.head[0];
@@ -956,8 +956,8 @@ svcauth_gss_accept(struct svc_rqst *rqstp, u32 *authp)
struct rpc_gss_wire_cred *gc;
struct rsc *rsci = NULL;
struct rsi *rsip, rsikey;
- u32 *rpcstart;
- u32 *reject_stat = resv->iov_base + resv->iov_len;
+ __be32 *rpcstart;
+ __be32 *reject_stat = resv->iov_base + resv->iov_len;
int ret;
dprintk("RPC: svcauth_gss: argv->iov_len = %zd\n",argv->iov_len);
@@ -985,12 +985,12 @@ svcauth_gss_accept(struct svc_rqst *rqstp, u32 *authp)
if (argv->iov_len < 5 * 4)
goto auth_err;
- crlen = ntohl(svc_getu32(argv));
- if (ntohl(svc_getu32(argv)) != RPC_GSS_VERSION)
+ crlen = svc_getnl(argv);
+ if (svc_getnl(argv) != RPC_GSS_VERSION)
goto auth_err;
- gc->gc_proc = ntohl(svc_getu32(argv));
- gc->gc_seq = ntohl(svc_getu32(argv));
- gc->gc_svc = ntohl(svc_getu32(argv));
+ gc->gc_proc = svc_getnl(argv);
+ gc->gc_seq = svc_getnl(argv);
+ gc->gc_svc = svc_getnl(argv);
if (svc_safe_getnetobj(argv, &gc->gc_ctx))
goto auth_err;
if (crlen != round_up_to_quad(gc->gc_ctx.len) + 5 * 4)
@@ -1016,9 +1016,9 @@ svcauth_gss_accept(struct svc_rqst *rqstp, u32 *authp)
case RPC_GSS_PROC_CONTINUE_INIT:
if (argv->iov_len < 2 * 4)
goto auth_err;
- if (ntohl(svc_getu32(argv)) != RPC_AUTH_NULL)
+ if (svc_getnl(argv) != RPC_AUTH_NULL)
goto auth_err;
- if (ntohl(svc_getu32(argv)) != 0)
+ if (svc_getnl(argv) != 0)
goto auth_err;
break;
case RPC_GSS_PROC_DATA:
@@ -1076,14 +1076,14 @@ svcauth_gss_accept(struct svc_rqst *rqstp, u32 *authp)
goto drop;
if (resv->iov_len + 4 > PAGE_SIZE)
goto drop;
- svc_putu32(resv, rpc_success);
+ svc_putnl(resv, RPC_SUCCESS);
if (svc_safe_putnetobj(resv, &rsip->out_handle))
goto drop;
if (resv->iov_len + 3 * 4 > PAGE_SIZE)
goto drop;
- svc_putu32(resv, htonl(rsip->major_status));
- svc_putu32(resv, htonl(rsip->minor_status));
- svc_putu32(resv, htonl(GSS_SEQ_WIN));
+ svc_putnl(resv, rsip->major_status);
+ svc_putnl(resv, rsip->minor_status);
+ svc_putnl(resv, GSS_SEQ_WIN);
if (svc_safe_putnetobj(resv, &rsip->out_token))
goto drop;
rqstp->rq_client = NULL;
@@ -1093,7 +1093,7 @@ svcauth_gss_accept(struct svc_rqst *rqstp, u32 *authp)
set_bit(CACHE_NEGATIVE, &rsci->h.flags);
if (resv->iov_len + 4 > PAGE_SIZE)
goto drop;
- svc_putu32(resv, rpc_success);
+ svc_putnl(resv, RPC_SUCCESS);
goto complete;
case RPC_GSS_PROC_DATA:
*authp = rpcsec_gsserr_ctxproblem;
@@ -1111,8 +1111,8 @@ svcauth_gss_accept(struct svc_rqst *rqstp, u32 *authp)
goto auth_err;
/* placeholders for length and seq. number: */
svcdata->body_start = resv->iov_base + resv->iov_len;
- svc_putu32(resv, 0);
- svc_putu32(resv, 0);
+ svc_putnl(resv, 0);
+ svc_putnl(resv, 0);
break;
case RPC_GSS_SVC_PRIVACY:
if (unwrap_priv_data(rqstp, &rqstp->rq_arg,
@@ -1120,8 +1120,8 @@ svcauth_gss_accept(struct svc_rqst *rqstp, u32 *authp)
goto auth_err;
/* placeholders for length and seq. number: */
svcdata->body_start = resv->iov_base + resv->iov_len;
- svc_putu32(resv, 0);
- svc_putu32(resv, 0);
+ svc_putnl(resv, 0);
+ svc_putnl(resv, 0);
break;
default:
goto auth_err;
@@ -1156,7 +1156,7 @@ svcauth_gss_wrap_resp_integ(struct svc_rqst *rqstp)
struct xdr_buf integ_buf;
struct xdr_netobj mic;
struct kvec *resv;
- u32 *p;
+ __be32 *p;
int integ_offset, integ_len;
int stat = -EINVAL;
@@ -1199,7 +1199,7 @@ svcauth_gss_wrap_resp_integ(struct svc_rqst *rqstp)
mic.data = (u8 *)resv->iov_base + resv->iov_len + 4;
if (gss_get_mic(gsd->rsci->mechctx, &integ_buf, &mic))
goto out_err;
- svc_putu32(resv, htonl(mic.len));
+ svc_putnl(resv, mic.len);
memset(mic.data + mic.len, 0,
round_up_to_quad(mic.len) - mic.len);
resv->iov_len += XDR_QUADLEN(mic.len) << 2;
@@ -1219,8 +1219,8 @@ svcauth_gss_wrap_resp_priv(struct svc_rqst *rqstp)
struct rpc_gss_wire_cred *gc = &gsd->clcred;
struct xdr_buf *resbuf = &rqstp->rq_res;
struct page **inpages = NULL;
- u32 *p;
- int offset, *len;
+ __be32 *p, *len;
+ int offset;
int pad;
p = gsd->body_start;
@@ -1264,7 +1264,7 @@ svcauth_gss_wrap_resp_priv(struct svc_rqst *rqstp)
return -ENOMEM;
*len = htonl(resbuf->len - offset);
pad = 3 - ((resbuf->len - offset - 1)&3);
- p = (u32 *)(resbuf->tail[0].iov_base + resbuf->tail[0].iov_len);
+ p = (__be32 *)(resbuf->tail[0].iov_base + resbuf->tail[0].iov_len);
memset(p, 0, pad);
resbuf->tail[0].iov_len += pad;
resbuf->len += pad;
diff --git a/net/sunrpc/auth_null.c b/net/sunrpc/auth_null.c
index 2eccffa96ba1..3be257dc32b2 100644
--- a/net/sunrpc/auth_null.c
+++ b/net/sunrpc/auth_null.c
@@ -60,8 +60,8 @@ nul_match(struct auth_cred *acred, struct rpc_cred *cred, int taskflags)
/*
* Marshal credential.
*/
-static u32 *
-nul_marshal(struct rpc_task *task, u32 *p)
+static __be32 *
+nul_marshal(struct rpc_task *task, __be32 *p)
{
*p++ = htonl(RPC_AUTH_NULL);
*p++ = 0;
@@ -81,8 +81,8 @@ nul_refresh(struct rpc_task *task)
return 0;
}
-static u32 *
-nul_validate(struct rpc_task *task, u32 *p)
+static __be32 *
+nul_validate(struct rpc_task *task, __be32 *p)
{
rpc_authflavor_t flavor;
u32 size;
diff --git a/net/sunrpc/auth_unix.c b/net/sunrpc/auth_unix.c
index 74c7406a1054..f7f990c9afe2 100644
--- a/net/sunrpc/auth_unix.c
+++ b/net/sunrpc/auth_unix.c
@@ -137,12 +137,12 @@ unx_match(struct auth_cred *acred, struct rpc_cred *rcred, int flags)
* Marshal credentials.
* Maybe we should keep a cached credential for performance reasons.
*/
-static u32 *
-unx_marshal(struct rpc_task *task, u32 *p)
+static __be32 *
+unx_marshal(struct rpc_task *task, __be32 *p)
{
struct rpc_clnt *clnt = task->tk_client;
struct unx_cred *cred = (struct unx_cred *) task->tk_msg.rpc_cred;
- u32 *base, *hold;
+ __be32 *base, *hold;
int i;
*p++ = htonl(RPC_AUTH_UNIX);
@@ -178,8 +178,8 @@ unx_refresh(struct rpc_task *task)
return 0;
}
-static u32 *
-unx_validate(struct rpc_task *task, u32 *p)
+static __be32 *
+unx_validate(struct rpc_task *task, __be32 *p)
{
rpc_authflavor_t flavor;
u32 size;
diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c
index 084a0ad5c64e..78696f2dc7d6 100644
--- a/net/sunrpc/clnt.c
+++ b/net/sunrpc/clnt.c
@@ -60,8 +60,8 @@ static void call_refreshresult(struct rpc_task *task);
static void call_timeout(struct rpc_task *task);
static void call_connect(struct rpc_task *task);
static void call_connect_status(struct rpc_task *task);
-static u32 * call_header(struct rpc_task *task);
-static u32 * call_verify(struct rpc_task *task);
+static __be32 * call_header(struct rpc_task *task);
+static __be32 * call_verify(struct rpc_task *task);
static int
@@ -161,10 +161,10 @@ static struct rpc_clnt * rpc_new_client(struct rpc_xprt *xprt, char *servname, s
}
/* save the nodename */
- clnt->cl_nodelen = strlen(system_utsname.nodename);
+ clnt->cl_nodelen = strlen(utsname()->nodename);
if (clnt->cl_nodelen > UNX_MAXNODENAME)
clnt->cl_nodelen = UNX_MAXNODENAME;
- memcpy(clnt->cl_nodename, system_utsname.nodename, clnt->cl_nodelen);
+ memcpy(clnt->cl_nodename, utsname()->nodename, clnt->cl_nodelen);
return clnt;
out_no_auth:
@@ -782,7 +782,7 @@ call_encode(struct rpc_task *task)
struct xdr_buf *rcvbuf = &req->rq_rcv_buf;
unsigned int bufsiz;
kxdrproc_t encode;
- u32 *p;
+ __be32 *p;
dprintk("RPC: %4d call_encode (status %d)\n",
task->tk_pid, task->tk_status);
@@ -1100,7 +1100,7 @@ call_decode(struct rpc_task *task)
struct rpc_clnt *clnt = task->tk_client;
struct rpc_rqst *req = task->tk_rqstp;
kxdrproc_t decode = task->tk_msg.rpc_proc->p_decode;
- u32 *p;
+ __be32 *p;
dprintk("RPC: %4d call_decode (status %d)\n",
task->tk_pid, task->tk_status);
@@ -1197,12 +1197,12 @@ call_refreshresult(struct rpc_task *task)
/*
* Call header serialization
*/
-static u32 *
+static __be32 *
call_header(struct rpc_task *task)
{
struct rpc_clnt *clnt = task->tk_client;
struct rpc_rqst *req = task->tk_rqstp;
- u32 *p = req->rq_svec[0].iov_base;
+ __be32 *p = req->rq_svec[0].iov_base;
/* FIXME: check buffer size? */
@@ -1221,12 +1221,13 @@ call_header(struct rpc_task *task)
/*
* Reply header verification
*/
-static u32 *
+static __be32 *
call_verify(struct rpc_task *task)
{
struct kvec *iov = &task->tk_rqstp->rq_rcv_buf.head[0];
int len = task->tk_rqstp->rq_rcv_buf.len >> 2;
- u32 *p = iov->iov_base, n;
+ __be32 *p = iov->iov_base;
+ u32 n;
int error = -EACCES;
if ((task->tk_rqstp->rq_rcv_buf.len & 3) != 0) {
@@ -1303,7 +1304,7 @@ call_verify(struct rpc_task *task)
printk(KERN_WARNING "call_verify: auth check failed\n");
goto out_garbage; /* bad verifier, retry */
}
- len = p - (u32 *)iov->iov_base - 1;
+ len = p - (__be32 *)iov->iov_base - 1;
if (len < 0)
goto out_overflow;
switch ((n = ntohl(*p++))) {
@@ -1358,12 +1359,12 @@ out_overflow:
goto out_garbage;
}
-static int rpcproc_encode_null(void *rqstp, u32 *data, void *obj)
+static int rpcproc_encode_null(void *rqstp, __be32 *data, void *obj)
{
return 0;
}
-static int rpcproc_decode_null(void *rqstp, u32 *data, void *obj)
+static int rpcproc_decode_null(void *rqstp, __be32 *data, void *obj)
{
return 0;
}
diff --git a/net/sunrpc/pmap_clnt.c b/net/sunrpc/pmap_clnt.c
index c04609d3476a..919d5ba7ca0a 100644
--- a/net/sunrpc/pmap_clnt.c
+++ b/net/sunrpc/pmap_clnt.c
@@ -300,7 +300,7 @@ static struct rpc_clnt *pmap_create(char *hostname, struct sockaddr_in *srvaddr,
/*
* XDR encode/decode functions for PMAP
*/
-static int xdr_encode_mapping(struct rpc_rqst *req, u32 *p, struct portmap_args *map)
+static int xdr_encode_mapping(struct rpc_rqst *req, __be32 *p, struct portmap_args *map)
{
dprintk("RPC: xdr_encode_mapping(%u, %u, %u, %u)\n",
map->pm_prog, map->pm_vers, map->pm_prot, map->pm_port);
@@ -313,13 +313,13 @@ static int xdr_encode_mapping(struct rpc_rqst *req, u32 *p, struct portmap_args
return 0;
}
-static int xdr_decode_port(struct rpc_rqst *req, u32 *p, unsigned short *portp)
+static int xdr_decode_port(struct rpc_rqst *req, __be32 *p, unsigned short *portp)
{
*portp = (unsigned short) ntohl(*p++);
return 0;
}
-static int xdr_decode_bool(struct rpc_rqst *req, u32 *p, unsigned int *boolp)
+static int xdr_decode_bool(struct rpc_rqst *req, __be32 *p, unsigned int *boolp)
{
*boolp = (unsigned int) ntohl(*p++);
return 0;
diff --git a/net/sunrpc/rpc_pipe.c b/net/sunrpc/rpc_pipe.c
index 700c6e061a04..9a0b41a97f90 100644
--- a/net/sunrpc/rpc_pipe.c
+++ b/net/sunrpc/rpc_pipe.c
@@ -494,7 +494,7 @@ rpc_get_inode(struct super_block *sb, int mode)
case S_IFDIR:
inode->i_fop = &simple_dir_operations;
inode->i_op = &simple_dir_inode_operations;
- inode->i_nlink++;
+ inc_nlink(inode);
default:
break;
}
@@ -571,7 +571,7 @@ rpc_populate(struct dentry *parent,
if (private)
rpc_inode_setowner(inode, private);
if (S_ISDIR(mode))
- dir->i_nlink++;
+ inc_nlink(dir);
d_add(dentry, inode);
}
mutex_unlock(&dir->i_mutex);
@@ -593,7 +593,7 @@ __rpc_mkdir(struct inode *dir, struct dentry *dentry)
goto out_err;
inode->i_ino = iunique(dir->i_sb, 100);
d_instantiate(dentry, inode);
- dir->i_nlink++;
+ inc_nlink(dir);
inode_dir_notify(dir, DN_CREATE);
return 0;
out_err:
diff --git a/net/sunrpc/sunrpc_syms.c b/net/sunrpc/sunrpc_syms.c
index 26c0531d7e25..192dff5dabcb 100644
--- a/net/sunrpc/sunrpc_syms.c
+++ b/net/sunrpc/sunrpc_syms.c
@@ -70,6 +70,8 @@ EXPORT_SYMBOL(put_rpccred);
/* RPC server stuff */
EXPORT_SYMBOL(svc_create);
EXPORT_SYMBOL(svc_create_thread);
+EXPORT_SYMBOL(svc_create_pooled);
+EXPORT_SYMBOL(svc_set_num_threads);
EXPORT_SYMBOL(svc_exit_thread);
EXPORT_SYMBOL(svc_destroy);
EXPORT_SYMBOL(svc_drop);
diff --git a/net/sunrpc/svc.c b/net/sunrpc/svc.c
index b76a227dd3ad..a99e67b164c1 100644
--- a/net/sunrpc/svc.c
+++ b/net/sunrpc/svc.c
@@ -4,6 +4,10 @@
* High-level RPC service routines
*
* Copyright (C) 1995, 1996 Olaf Kirch <okir@monad.swb.de>
+ *
+ * Multiple threads pools and NUMAisation
+ * Copyright (c) 2006 Silicon Graphics, Inc.
+ * by Greg Banks <gnb@melbourne.sgi.com>
*/
#include <linux/linkage.h>
@@ -12,6 +16,8 @@
#include <linux/net.h>
#include <linux/in.h>
#include <linux/mm.h>
+#include <linux/interrupt.h>
+#include <linux/module.h>
#include <linux/sunrpc/types.h>
#include <linux/sunrpc/xdr.h>
@@ -23,14 +29,252 @@
#define RPC_PARANOIA 1
/*
+ * Mode for mapping cpus to pools.
+ */
+enum {
+ SVC_POOL_NONE = -1, /* uninitialised, choose one of the others */
+ SVC_POOL_GLOBAL, /* no mapping, just a single global pool
+ * (legacy & UP mode) */
+ SVC_POOL_PERCPU, /* one pool per cpu */
+ SVC_POOL_PERNODE /* one pool per numa node */
+};
+
+/*
+ * Structure for mapping cpus to pools and vice versa.
+ * Setup once during sunrpc initialisation.
+ */
+static struct svc_pool_map {
+ int mode; /* Note: int not enum to avoid
+ * warnings about "enumeration value
+ * not handled in switch" */
+ unsigned int npools;
+ unsigned int *pool_to; /* maps pool id to cpu or node */
+ unsigned int *to_pool; /* maps cpu or node to pool id */
+} svc_pool_map = {
+ .mode = SVC_POOL_NONE
+};
+
+
+/*
+ * Detect best pool mapping mode heuristically,
+ * according to the machine's topology.
+ */
+static int
+svc_pool_map_choose_mode(void)
+{
+ unsigned int node;
+
+ if (num_online_nodes() > 1) {
+ /*
+ * Actually have multiple NUMA nodes,
+ * so split pools on NUMA node boundaries
+ */
+ return SVC_POOL_PERNODE;
+ }
+
+ node = any_online_node(node_online_map);
+ if (nr_cpus_node(node) > 2) {
+ /*
+ * Non-trivial SMP, or CONFIG_NUMA on
+ * non-NUMA hardware, e.g. with a generic
+ * x86_64 kernel on Xeons. In this case we
+ * want to divide the pools on cpu boundaries.
+ */
+ return SVC_POOL_PERCPU;
+ }
+
+ /* default: one global pool */
+ return SVC_POOL_GLOBAL;
+}
+
+/*
+ * Allocate the to_pool[] and pool_to[] arrays.
+ * Returns 0 on success or an errno.
+ */
+static int
+svc_pool_map_alloc_arrays(struct svc_pool_map *m, unsigned int maxpools)
+{
+ m->to_pool = kcalloc(maxpools, sizeof(unsigned int), GFP_KERNEL);
+ if (!m->to_pool)
+ goto fail;
+ m->pool_to = kcalloc(maxpools, sizeof(unsigned int), GFP_KERNEL);
+ if (!m->pool_to)
+ goto fail_free;
+
+ return 0;
+
+fail_free:
+ kfree(m->to_pool);
+fail:
+ return -ENOMEM;
+}
+
+/*
+ * Initialise the pool map for SVC_POOL_PERCPU mode.
+ * Returns number of pools or <0 on error.
+ */
+static int
+svc_pool_map_init_percpu(struct svc_pool_map *m)
+{
+ unsigned int maxpools = highest_possible_processor_id()+1;
+ unsigned int pidx = 0;
+ unsigned int cpu;
+ int err;
+
+ err = svc_pool_map_alloc_arrays(m, maxpools);
+ if (err)
+ return err;
+
+ for_each_online_cpu(cpu) {
+ BUG_ON(pidx > maxpools);
+ m->to_pool[cpu] = pidx;
+ m->pool_to[pidx] = cpu;
+ pidx++;
+ }
+ /* cpus brought online later all get mapped to pool0, sorry */
+
+ return pidx;
+};
+
+
+/*
+ * Initialise the pool map for SVC_POOL_PERNODE mode.
+ * Returns number of pools or <0 on error.
+ */
+static int
+svc_pool_map_init_pernode(struct svc_pool_map *m)
+{
+ unsigned int maxpools = highest_possible_node_id()+1;
+ unsigned int pidx = 0;
+ unsigned int node;
+ int err;
+
+ err = svc_pool_map_alloc_arrays(m, maxpools);
+ if (err)
+ return err;
+
+ for_each_node_with_cpus(node) {
+ /* some architectures (e.g. SN2) have cpuless nodes */
+ BUG_ON(pidx > maxpools);
+ m->to_pool[node] = pidx;
+ m->pool_to[pidx] = node;
+ pidx++;
+ }
+ /* nodes brought online later all get mapped to pool0, sorry */
+
+ return pidx;
+}
+
+
+/*
+ * Build the global map of cpus to pools and vice versa.
+ */
+static unsigned int
+svc_pool_map_init(void)
+{
+ struct svc_pool_map *m = &svc_pool_map;
+ int npools = -1;
+
+ if (m->mode != SVC_POOL_NONE)
+ return m->npools;
+
+ m->mode = svc_pool_map_choose_mode();
+
+ switch (m->mode) {
+ case SVC_POOL_PERCPU:
+ npools = svc_pool_map_init_percpu(m);
+ break;
+ case SVC_POOL_PERNODE:
+ npools = svc_pool_map_init_pernode(m);
+ break;
+ }
+
+ if (npools < 0) {
+ /* default, or memory allocation failure */
+ npools = 1;
+ m->mode = SVC_POOL_GLOBAL;
+ }
+ m->npools = npools;
+
+ return m->npools;
+}
+
+/*
+ * Set the current thread's cpus_allowed mask so that it
+ * will only run on cpus in the given pool.
+ *
+ * Returns 1 and fills in oldmask iff a cpumask was applied.
+ */
+static inline int
+svc_pool_map_set_cpumask(unsigned int pidx, cpumask_t *oldmask)
+{
+ struct svc_pool_map *m = &svc_pool_map;
+ unsigned int node; /* or cpu */
+
+ /*
+ * The caller checks for sv_nrpools > 1, which
+ * implies that we've been initialized and the
+ * map mode is not NONE.
+ */
+ BUG_ON(m->mode == SVC_POOL_NONE);
+
+ switch (m->mode)
+ {
+ default:
+ return 0;
+ case SVC_POOL_PERCPU:
+ node = m->pool_to[pidx];
+ *oldmask = current->cpus_allowed;
+ set_cpus_allowed(current, cpumask_of_cpu(node));
+ return 1;
+ case SVC_POOL_PERNODE:
+ node = m->pool_to[pidx];
+ *oldmask = current->cpus_allowed;
+ set_cpus_allowed(current, node_to_cpumask(node));
+ return 1;
+ }
+}
+
+/*
+ * Use the mapping mode to choose a pool for a given CPU.
+ * Used when enqueueing an incoming RPC. Always returns
+ * a non-NULL pool pointer.
+ */
+struct svc_pool *
+svc_pool_for_cpu(struct svc_serv *serv, int cpu)
+{
+ struct svc_pool_map *m = &svc_pool_map;
+ unsigned int pidx = 0;
+
+ /*
+ * SVC_POOL_NONE happens in a pure client when
+ * lockd is brought up, so silently treat it the
+ * same as SVC_POOL_GLOBAL.
+ */
+
+ switch (m->mode) {
+ case SVC_POOL_PERCPU:
+ pidx = m->to_pool[cpu];
+ break;
+ case SVC_POOL_PERNODE:
+ pidx = m->to_pool[cpu_to_node(cpu)];
+ break;
+ }
+ return &serv->sv_pools[pidx % serv->sv_nrpools];
+}
+
+
+/*
* Create an RPC service
*/
-struct svc_serv *
-svc_create(struct svc_program *prog, unsigned int bufsize)
+static struct svc_serv *
+__svc_create(struct svc_program *prog, unsigned int bufsize, int npools,
+ void (*shutdown)(struct svc_serv *serv))
{
struct svc_serv *serv;
int vers;
unsigned int xdrsize;
+ unsigned int i;
if (!(serv = kzalloc(sizeof(*serv), GFP_KERNEL)))
return NULL;
@@ -39,6 +283,7 @@ svc_create(struct svc_program *prog, unsigned int bufsize)
serv->sv_nrthreads = 1;
serv->sv_stats = prog->pg_stats;
serv->sv_bufsz = bufsize? bufsize : 4096;
+ serv->sv_shutdown = shutdown;
xdrsize = 0;
while (prog) {
prog->pg_lovers = prog->pg_nvers-1;
@@ -53,20 +298,68 @@ svc_create(struct svc_program *prog, unsigned int bufsize)
prog = prog->pg_next;
}
serv->sv_xdrsize = xdrsize;
- INIT_LIST_HEAD(&serv->sv_threads);
- INIT_LIST_HEAD(&serv->sv_sockets);
INIT_LIST_HEAD(&serv->sv_tempsocks);
INIT_LIST_HEAD(&serv->sv_permsocks);
+ init_timer(&serv->sv_temptimer);
spin_lock_init(&serv->sv_lock);
+ serv->sv_nrpools = npools;
+ serv->sv_pools =
+ kcalloc(sizeof(struct svc_pool), serv->sv_nrpools,
+ GFP_KERNEL);
+ if (!serv->sv_pools) {
+ kfree(serv);
+ return NULL;
+ }
+
+ for (i = 0; i < serv->sv_nrpools; i++) {
+ struct svc_pool *pool = &serv->sv_pools[i];
+
+ dprintk("initialising pool %u for %s\n",
+ i, serv->sv_name);
+
+ pool->sp_id = i;
+ INIT_LIST_HEAD(&pool->sp_threads);
+ INIT_LIST_HEAD(&pool->sp_sockets);
+ INIT_LIST_HEAD(&pool->sp_all_threads);
+ spin_lock_init(&pool->sp_lock);
+ }
+
+
/* Remove any stale portmap registrations */
svc_register(serv, 0, 0);
return serv;
}
+struct svc_serv *
+svc_create(struct svc_program *prog, unsigned int bufsize,
+ void (*shutdown)(struct svc_serv *serv))
+{
+ return __svc_create(prog, bufsize, /*npools*/1, shutdown);
+}
+
+struct svc_serv *
+svc_create_pooled(struct svc_program *prog, unsigned int bufsize,
+ void (*shutdown)(struct svc_serv *serv),
+ svc_thread_fn func, int sig, struct module *mod)
+{
+ struct svc_serv *serv;
+ unsigned int npools = svc_pool_map_init();
+
+ serv = __svc_create(prog, bufsize, npools, shutdown);
+
+ if (serv != NULL) {
+ serv->sv_function = func;
+ serv->sv_kill_signal = sig;
+ serv->sv_module = mod;
+ }
+
+ return serv;
+}
+
/*
- * Destroy an RPC service
+ * Destroy an RPC service. Should be called with the BKL held
*/
void
svc_destroy(struct svc_serv *serv)
@@ -85,12 +378,17 @@ svc_destroy(struct svc_serv *serv)
} else
printk("svc_destroy: no threads for serv=%p!\n", serv);
+ del_timer_sync(&serv->sv_temptimer);
+
while (!list_empty(&serv->sv_tempsocks)) {
svsk = list_entry(serv->sv_tempsocks.next,
struct svc_sock,
sk_list);
svc_delete_socket(svsk);
}
+ if (serv->sv_shutdown)
+ serv->sv_shutdown(serv);
+
while (!list_empty(&serv->sv_permsocks)) {
svsk = list_entry(serv->sv_permsocks.next,
struct svc_sock,
@@ -102,6 +400,7 @@ svc_destroy(struct svc_serv *serv)
/* Unregister service with the portmapper */
svc_register(serv, 0, 0);
+ kfree(serv->sv_pools);
kfree(serv);
}
@@ -150,13 +449,18 @@ svc_release_buffer(struct svc_rqst *rqstp)
}
/*
- * Create a server thread
+ * Create a thread in the given pool. Caller must hold BKL.
+ * On a NUMA or SMP machine, with a multi-pool serv, the thread
+ * will be restricted to run on the cpus belonging to the pool.
*/
-int
-svc_create_thread(svc_thread_fn func, struct svc_serv *serv)
+static int
+__svc_create_thread(svc_thread_fn func, struct svc_serv *serv,
+ struct svc_pool *pool)
{
struct svc_rqst *rqstp;
int error = -ENOMEM;
+ int have_oldmask = 0;
+ cpumask_t oldmask;
rqstp = kzalloc(sizeof(*rqstp), GFP_KERNEL);
if (!rqstp)
@@ -170,8 +474,21 @@ svc_create_thread(svc_thread_fn func, struct svc_serv *serv)
goto out_thread;
serv->sv_nrthreads++;
+ spin_lock_bh(&pool->sp_lock);
+ pool->sp_nrthreads++;
+ list_add(&rqstp->rq_all, &pool->sp_all_threads);
+ spin_unlock_bh(&pool->sp_lock);
rqstp->rq_server = serv;
+ rqstp->rq_pool = pool;
+
+ if (serv->sv_nrpools > 1)
+ have_oldmask = svc_pool_map_set_cpumask(pool->sp_id, &oldmask);
+
error = kernel_thread((int (*)(void *)) func, rqstp, 0);
+
+ if (have_oldmask)
+ set_cpus_allowed(current, oldmask);
+
if (error < 0)
goto out_thread;
svc_sock_update_bufs(serv);
@@ -185,17 +502,136 @@ out_thread:
}
/*
- * Destroy an RPC server thread
+ * Create a thread in the default pool. Caller must hold BKL.
+ */
+int
+svc_create_thread(svc_thread_fn func, struct svc_serv *serv)
+{
+ return __svc_create_thread(func, serv, &serv->sv_pools[0]);
+}
+
+/*
+ * Choose a pool in which to create a new thread, for svc_set_num_threads
+ */
+static inline struct svc_pool *
+choose_pool(struct svc_serv *serv, struct svc_pool *pool, unsigned int *state)
+{
+ if (pool != NULL)
+ return pool;
+
+ return &serv->sv_pools[(*state)++ % serv->sv_nrpools];
+}
+
+/*
+ * Choose a thread to kill, for svc_set_num_threads
+ */
+static inline struct task_struct *
+choose_victim(struct svc_serv *serv, struct svc_pool *pool, unsigned int *state)
+{
+ unsigned int i;
+ struct task_struct *task = NULL;
+
+ if (pool != NULL) {
+ spin_lock_bh(&pool->sp_lock);
+ } else {
+ /* choose a pool in round-robin fashion */
+ for (i = 0; i < serv->sv_nrpools; i++) {
+ pool = &serv->sv_pools[--(*state) % serv->sv_nrpools];
+ spin_lock_bh(&pool->sp_lock);
+ if (!list_empty(&pool->sp_all_threads))
+ goto found_pool;
+ spin_unlock_bh(&pool->sp_lock);
+ }
+ return NULL;
+ }
+
+found_pool:
+ if (!list_empty(&pool->sp_all_threads)) {
+ struct svc_rqst *rqstp;
+
+ /*
+ * Remove from the pool->sp_all_threads list
+ * so we don't try to kill it again.
+ */
+ rqstp = list_entry(pool->sp_all_threads.next, struct svc_rqst, rq_all);
+ list_del_init(&rqstp->rq_all);
+ task = rqstp->rq_task;
+ }
+ spin_unlock_bh(&pool->sp_lock);
+
+ return task;
+}
+
+/*
+ * Create or destroy enough new threads to make the number
+ * of threads the given number. If `pool' is non-NULL, applies
+ * only to threads in that pool, otherwise round-robins between
+ * all pools. Must be called with a svc_get() reference and
+ * the BKL held.
+ *
+ * Destroying threads relies on the service threads filling in
+ * rqstp->rq_task, which only the nfs ones do. Assumes the serv
+ * has been created using svc_create_pooled().
+ *
+ * Based on code that used to be in nfsd_svc() but tweaked
+ * to be pool-aware.
+ */
+int
+svc_set_num_threads(struct svc_serv *serv, struct svc_pool *pool, int nrservs)
+{
+ struct task_struct *victim;
+ int error = 0;
+ unsigned int state = serv->sv_nrthreads-1;
+
+ if (pool == NULL) {
+ /* The -1 assumes caller has done a svc_get() */
+ nrservs -= (serv->sv_nrthreads-1);
+ } else {
+ spin_lock_bh(&pool->sp_lock);
+ nrservs -= pool->sp_nrthreads;
+ spin_unlock_bh(&pool->sp_lock);
+ }
+
+ /* create new threads */
+ while (nrservs > 0) {
+ nrservs--;
+ __module_get(serv->sv_module);
+ error = __svc_create_thread(serv->sv_function, serv,
+ choose_pool(serv, pool, &state));
+ if (error < 0) {
+ module_put(serv->sv_module);
+ break;
+ }
+ }
+ /* destroy old threads */
+ while (nrservs < 0 &&
+ (victim = choose_victim(serv, pool, &state)) != NULL) {
+ send_sig(serv->sv_kill_signal, victim, 1);
+ nrservs++;
+ }
+
+ return error;
+}
+
+/*
+ * Called from a server thread as it's exiting. Caller must hold BKL.
*/
void
svc_exit_thread(struct svc_rqst *rqstp)
{
struct svc_serv *serv = rqstp->rq_server;
+ struct svc_pool *pool = rqstp->rq_pool;
svc_release_buffer(rqstp);
kfree(rqstp->rq_resp);
kfree(rqstp->rq_argp);
kfree(rqstp->rq_auth_data);
+
+ spin_lock_bh(&pool->sp_lock);
+ pool->sp_nrthreads--;
+ list_del(&rqstp->rq_all);
+ spin_unlock_bh(&pool->sp_lock);
+
kfree(rqstp);
/* Release the server */
@@ -248,19 +684,20 @@ svc_register(struct svc_serv *serv, int proto, unsigned short port)
* Process the RPC request.
*/
int
-svc_process(struct svc_serv *serv, struct svc_rqst *rqstp)
+svc_process(struct svc_rqst *rqstp)
{
struct svc_program *progp;
struct svc_version *versp = NULL; /* compiler food */
struct svc_procedure *procp = NULL;
struct kvec * argv = &rqstp->rq_arg.head[0];
struct kvec * resv = &rqstp->rq_res.head[0];
+ struct svc_serv *serv = rqstp->rq_server;
kxdrproc_t xdr;
- u32 *statp;
- u32 dir, prog, vers, proc,
- auth_stat, rpc_stat;
+ __be32 *statp;
+ u32 dir, prog, vers, proc;
+ __be32 auth_stat, rpc_stat;
int auth_res;
- u32 *accept_statp;
+ __be32 *accept_statp;
rpc_stat = rpc_success;
@@ -284,16 +721,16 @@ svc_process(struct svc_serv *serv, struct svc_rqst *rqstp)
rqstp->rq_sendfile_ok = 1;
/* tcp needs a space for the record length... */
if (rqstp->rq_prot == IPPROTO_TCP)
- svc_putu32(resv, 0);
+ svc_putnl(resv, 0);
rqstp->rq_xid = svc_getu32(argv);
svc_putu32(resv, rqstp->rq_xid);
- dir = ntohl(svc_getu32(argv));
- vers = ntohl(svc_getu32(argv));
+ dir = svc_getnl(argv);
+ vers = svc_getnl(argv);
/* First words of reply: */
- svc_putu32(resv, xdr_one); /* REPLY */
+ svc_putnl(resv, 1); /* REPLY */
if (dir != 0) /* direction != CALL */
goto err_bad_dir;
@@ -303,11 +740,11 @@ svc_process(struct svc_serv *serv, struct svc_rqst *rqstp)
/* Save position in case we later decide to reject: */
accept_statp = resv->iov_base + resv->iov_len;
- svc_putu32(resv, xdr_zero); /* ACCEPT */
+ svc_putnl(resv, 0); /* ACCEPT */
- rqstp->rq_prog = prog = ntohl(svc_getu32(argv)); /* program number */
- rqstp->rq_vers = vers = ntohl(svc_getu32(argv)); /* version number */
- rqstp->rq_proc = proc = ntohl(svc_getu32(argv)); /* procedure number */
+ rqstp->rq_prog = prog = svc_getnl(argv); /* program number */
+ rqstp->rq_vers = vers = svc_getnl(argv); /* version number */
+ rqstp->rq_proc = proc = svc_getnl(argv); /* procedure number */
progp = serv->sv_program;
@@ -361,7 +798,7 @@ svc_process(struct svc_serv *serv, struct svc_rqst *rqstp)
/* Build the reply header. */
statp = resv->iov_base +resv->iov_len;
- svc_putu32(resv, rpc_success); /* RPC_SUCCESS */
+ svc_putnl(resv, RPC_SUCCESS);
/* Bump per-procedure stats counter */
procp->pc_count++;
@@ -439,10 +876,10 @@ err_bad_dir:
err_bad_rpc:
serv->sv_stats->rpcbadfmt++;
- svc_putu32(resv, xdr_one); /* REJECT */
- svc_putu32(resv, xdr_zero); /* RPC_MISMATCH */
- svc_putu32(resv, xdr_two); /* Only RPCv2 supported */
- svc_putu32(resv, xdr_two);
+ svc_putnl(resv, 1); /* REJECT */
+ svc_putnl(resv, 0); /* RPC_MISMATCH */
+ svc_putnl(resv, 2); /* Only RPCv2 supported */
+ svc_putnl(resv, 2);
goto sendit;
err_bad_auth:
@@ -450,15 +887,15 @@ err_bad_auth:
serv->sv_stats->rpcbadauth++;
/* Restore write pointer to location of accept status: */
xdr_ressize_check(rqstp, accept_statp);
- svc_putu32(resv, xdr_one); /* REJECT */
- svc_putu32(resv, xdr_one); /* AUTH_ERROR */
- svc_putu32(resv, auth_stat); /* status */
+ svc_putnl(resv, 1); /* REJECT */
+ svc_putnl(resv, 1); /* AUTH_ERROR */
+ svc_putnl(resv, ntohl(auth_stat)); /* status */
goto sendit;
err_bad_prog:
dprintk("svc: unknown program %d\n", prog);
serv->sv_stats->rpcbadfmt++;
- svc_putu32(resv, rpc_prog_unavail);
+ svc_putnl(resv, RPC_PROG_UNAVAIL);
goto sendit;
err_bad_vers:
@@ -466,9 +903,9 @@ err_bad_vers:
printk("svc: unknown version (%d)\n", vers);
#endif
serv->sv_stats->rpcbadfmt++;
- svc_putu32(resv, rpc_prog_mismatch);
- svc_putu32(resv, htonl(progp->pg_lovers));
- svc_putu32(resv, htonl(progp->pg_hivers));
+ svc_putnl(resv, RPC_PROG_MISMATCH);
+ svc_putnl(resv, progp->pg_lovers);
+ svc_putnl(resv, progp->pg_hivers);
goto sendit;
err_bad_proc:
@@ -476,7 +913,7 @@ err_bad_proc:
printk("svc: unknown procedure (%d)\n", proc);
#endif
serv->sv_stats->rpcbadfmt++;
- svc_putu32(resv, rpc_proc_unavail);
+ svc_putnl(resv, RPC_PROC_UNAVAIL);
goto sendit;
err_garbage:
@@ -486,6 +923,6 @@ err_garbage:
rpc_stat = rpc_garbage_args;
err_bad:
serv->sv_stats->rpcbadfmt++;
- svc_putu32(resv, rpc_stat);
+ svc_putnl(resv, ntohl(rpc_stat));
goto sendit;
}
diff --git a/net/sunrpc/svcauth.c b/net/sunrpc/svcauth.c
index 5b28c6176806..8f2320aded5c 100644
--- a/net/sunrpc/svcauth.c
+++ b/net/sunrpc/svcauth.c
@@ -35,14 +35,14 @@ static struct auth_ops *authtab[RPC_AUTH_MAXFLAVOR] = {
};
int
-svc_authenticate(struct svc_rqst *rqstp, u32 *authp)
+svc_authenticate(struct svc_rqst *rqstp, __be32 *authp)
{
rpc_authflavor_t flavor;
struct auth_ops *aops;
*authp = rpc_auth_ok;
- flavor = ntohl(svc_getu32(&rqstp->rq_arg.head[0]));
+ flavor = svc_getnl(&rqstp->rq_arg.head[0]);
dprintk("svc: svc_authenticate (%d)\n", flavor);
diff --git a/net/sunrpc/svcauth_unix.c b/net/sunrpc/svcauth_unix.c
index 7e5707e2d6b6..40d41a2831d7 100644
--- a/net/sunrpc/svcauth_unix.c
+++ b/net/sunrpc/svcauth_unix.c
@@ -145,7 +145,7 @@ static void ip_map_request(struct cache_detail *cd,
{
char text_addr[20];
struct ip_map *im = container_of(h, struct ip_map, h);
- __u32 addr = im->m_addr.s_addr;
+ __be32 addr = im->m_addr.s_addr;
snprintf(text_addr, 20, "%u.%u.%u.%u",
ntohl(addr) >> 24 & 0xff,
@@ -249,10 +249,10 @@ static int ip_map_show(struct seq_file *m,
seq_printf(m, "%s %d.%d.%d.%d %s\n",
im->m_class,
- htonl(addr.s_addr) >> 24 & 0xff,
- htonl(addr.s_addr) >> 16 & 0xff,
- htonl(addr.s_addr) >> 8 & 0xff,
- htonl(addr.s_addr) >> 0 & 0xff,
+ ntohl(addr.s_addr) >> 24 & 0xff,
+ ntohl(addr.s_addr) >> 16 & 0xff,
+ ntohl(addr.s_addr) >> 8 & 0xff,
+ ntohl(addr.s_addr) >> 0 & 0xff,
dom
);
return 0;
@@ -348,12 +348,9 @@ int auth_unix_forget_old(struct auth_domain *dom)
struct auth_domain *auth_unix_lookup(struct in_addr addr)
{
- struct ip_map key, *ipm;
+ struct ip_map *ipm;
struct auth_domain *rv;
- strcpy(key.m_class, "nfsd");
- key.m_addr = addr;
-
ipm = ip_map_lookup("nfsd", addr);
if (!ipm)
@@ -410,7 +407,7 @@ svcauth_unix_set_client(struct svc_rqst *rqstp)
}
static int
-svcauth_null_accept(struct svc_rqst *rqstp, u32 *authp)
+svcauth_null_accept(struct svc_rqst *rqstp, __be32 *authp)
{
struct kvec *argv = &rqstp->rq_arg.head[0];
struct kvec *resv = &rqstp->rq_res.head[0];
@@ -427,7 +424,7 @@ svcauth_null_accept(struct svc_rqst *rqstp, u32 *authp)
*authp = rpc_autherr_badcred;
return SVC_DENIED;
}
- if (svc_getu32(argv) != RPC_AUTH_NULL || svc_getu32(argv) != 0) {
+ if (svc_getu32(argv) != htonl(RPC_AUTH_NULL) || svc_getu32(argv) != 0) {
dprintk("svc: bad null verf\n");
*authp = rpc_autherr_badverf;
return SVC_DENIED;
@@ -441,8 +438,8 @@ svcauth_null_accept(struct svc_rqst *rqstp, u32 *authp)
return SVC_DROP; /* kmalloc failure - client must retry */
/* Put NULL verifier */
- svc_putu32(resv, RPC_AUTH_NULL);
- svc_putu32(resv, 0);
+ svc_putnl(resv, RPC_AUTH_NULL);
+ svc_putnl(resv, 0);
return SVC_OK;
}
@@ -472,7 +469,7 @@ struct auth_ops svcauth_null = {
static int
-svcauth_unix_accept(struct svc_rqst *rqstp, u32 *authp)
+svcauth_unix_accept(struct svc_rqst *rqstp, __be32 *authp)
{
struct kvec *argv = &rqstp->rq_arg.head[0];
struct kvec *resv = &rqstp->rq_res.head[0];
@@ -488,31 +485,31 @@ svcauth_unix_accept(struct svc_rqst *rqstp, u32 *authp)
svc_getu32(argv); /* length */
svc_getu32(argv); /* time stamp */
- slen = XDR_QUADLEN(ntohl(svc_getu32(argv))); /* machname length */
+ slen = XDR_QUADLEN(svc_getnl(argv)); /* machname length */
if (slen > 64 || (len -= (slen + 3)*4) < 0)
goto badcred;
- argv->iov_base = (void*)((u32*)argv->iov_base + slen); /* skip machname */
+ argv->iov_base = (void*)((__be32*)argv->iov_base + slen); /* skip machname */
argv->iov_len -= slen*4;
- cred->cr_uid = ntohl(svc_getu32(argv)); /* uid */
- cred->cr_gid = ntohl(svc_getu32(argv)); /* gid */
- slen = ntohl(svc_getu32(argv)); /* gids length */
+ cred->cr_uid = svc_getnl(argv); /* uid */
+ cred->cr_gid = svc_getnl(argv); /* gid */
+ slen = svc_getnl(argv); /* gids length */
if (slen > 16 || (len -= (slen + 2)*4) < 0)
goto badcred;
cred->cr_group_info = groups_alloc(slen);
if (cred->cr_group_info == NULL)
return SVC_DROP;
for (i = 0; i < slen; i++)
- GROUP_AT(cred->cr_group_info, i) = ntohl(svc_getu32(argv));
+ GROUP_AT(cred->cr_group_info, i) = svc_getnl(argv);
- if (svc_getu32(argv) != RPC_AUTH_NULL || svc_getu32(argv) != 0) {
+ if (svc_getu32(argv) != htonl(RPC_AUTH_NULL) || svc_getu32(argv) != 0) {
*authp = rpc_autherr_badverf;
return SVC_DENIED;
}
/* Put NULL verifier */
- svc_putu32(resv, RPC_AUTH_NULL);
- svc_putu32(resv, 0);
+ svc_putnl(resv, RPC_AUTH_NULL);
+ svc_putnl(resv, 0);
return SVC_OK;
diff --git a/net/sunrpc/svcsock.c b/net/sunrpc/svcsock.c
index 953aff89bcac..cba85d195222 100644
--- a/net/sunrpc/svcsock.c
+++ b/net/sunrpc/svcsock.c
@@ -31,6 +31,7 @@
#include <linux/slab.h>
#include <linux/netdevice.h>
#include <linux/skbuff.h>
+#include <linux/file.h>
#include <net/sock.h>
#include <net/checksum.h>
#include <net/ip.h>
@@ -45,13 +46,16 @@
/* SMP locking strategy:
*
- * svc_serv->sv_lock protects most stuff for that service.
+ * svc_pool->sp_lock protects most of the fields of that pool.
+ * svc_serv->sv_lock protects sv_tempsocks, sv_permsocks, sv_tmpcnt.
+ * when both need to be taken (rare), svc_serv->sv_lock is first.
+ * BKL protects svc_serv->sv_nrthread.
+ * svc_sock->sk_defer_lock protects the svc_sock->sk_deferred list
+ * svc_sock->sk_flags.SK_BUSY prevents a svc_sock being enqueued multiply.
*
* Some flags can be set to certain values at any time
* providing that certain rules are followed:
*
- * SK_BUSY can be set to 0 at any time.
- * svc_sock_enqueue must be called afterwards
* SK_CONN, SK_DATA, can be set or cleared at any time.
* after a set, svc_sock_enqueue must be called.
* after a clear, the socket must be read/accepted
@@ -73,23 +77,30 @@ static struct svc_deferred_req *svc_deferred_dequeue(struct svc_sock *svsk);
static int svc_deferred_recv(struct svc_rqst *rqstp);
static struct cache_deferred_req *svc_defer(struct cache_req *req);
+/* apparently the "standard" is that clients close
+ * idle connections after 5 minutes, servers after
+ * 6 minutes
+ * http://www.connectathon.org/talks96/nfstcp.pdf
+ */
+static int svc_conn_age_period = 6*60;
+
/*
- * Queue up an idle server thread. Must have serv->sv_lock held.
+ * Queue up an idle server thread. Must have pool->sp_lock held.
* Note: this is really a stack rather than a queue, so that we only
- * use as many different threads as we need, and the rest don't polute
+ * use as many different threads as we need, and the rest don't pollute
* the cache.
*/
static inline void
-svc_serv_enqueue(struct svc_serv *serv, struct svc_rqst *rqstp)
+svc_thread_enqueue(struct svc_pool *pool, struct svc_rqst *rqstp)
{
- list_add(&rqstp->rq_list, &serv->sv_threads);
+ list_add(&rqstp->rq_list, &pool->sp_threads);
}
/*
- * Dequeue an nfsd thread. Must have serv->sv_lock held.
+ * Dequeue an nfsd thread. Must have pool->sp_lock held.
*/
static inline void
-svc_serv_dequeue(struct svc_serv *serv, struct svc_rqst *rqstp)
+svc_thread_dequeue(struct svc_pool *pool, struct svc_rqst *rqstp)
{
list_del(&rqstp->rq_list);
}
@@ -140,7 +151,9 @@ static void
svc_sock_enqueue(struct svc_sock *svsk)
{
struct svc_serv *serv = svsk->sk_server;
+ struct svc_pool *pool;
struct svc_rqst *rqstp;
+ int cpu;
if (!(svsk->sk_flags &
( (1<<SK_CONN)|(1<<SK_DATA)|(1<<SK_CLOSE)|(1<<SK_DEFERRED)) ))
@@ -148,10 +161,14 @@ svc_sock_enqueue(struct svc_sock *svsk)
if (test_bit(SK_DEAD, &svsk->sk_flags))
return;
- spin_lock_bh(&serv->sv_lock);
+ cpu = get_cpu();
+ pool = svc_pool_for_cpu(svsk->sk_server, cpu);
+ put_cpu();
- if (!list_empty(&serv->sv_threads) &&
- !list_empty(&serv->sv_sockets))
+ spin_lock_bh(&pool->sp_lock);
+
+ if (!list_empty(&pool->sp_threads) &&
+ !list_empty(&pool->sp_sockets))
printk(KERN_ERR
"svc_sock_enqueue: threads and sockets both waiting??\n");
@@ -161,73 +178,79 @@ svc_sock_enqueue(struct svc_sock *svsk)
goto out_unlock;
}
- if (test_bit(SK_BUSY, &svsk->sk_flags)) {
- /* Don't enqueue socket while daemon is receiving */
+ /* Mark socket as busy. It will remain in this state until the
+ * server has processed all pending data and put the socket back
+ * on the idle list. We update SK_BUSY atomically because
+ * it also guards against trying to enqueue the svc_sock twice.
+ */
+ if (test_and_set_bit(SK_BUSY, &svsk->sk_flags)) {
+ /* Don't enqueue socket while already enqueued */
dprintk("svc: socket %p busy, not enqueued\n", svsk->sk_sk);
goto out_unlock;
}
+ BUG_ON(svsk->sk_pool != NULL);
+ svsk->sk_pool = pool;
set_bit(SOCK_NOSPACE, &svsk->sk_sock->flags);
- if (((svsk->sk_reserved + serv->sv_bufsz)*2
+ if (((atomic_read(&svsk->sk_reserved) + serv->sv_bufsz)*2
> svc_sock_wspace(svsk))
&& !test_bit(SK_CLOSE, &svsk->sk_flags)
&& !test_bit(SK_CONN, &svsk->sk_flags)) {
/* Don't enqueue while not enough space for reply */
dprintk("svc: socket %p no space, %d*2 > %ld, not enqueued\n",
- svsk->sk_sk, svsk->sk_reserved+serv->sv_bufsz,
+ svsk->sk_sk, atomic_read(&svsk->sk_reserved)+serv->sv_bufsz,
svc_sock_wspace(svsk));
+ svsk->sk_pool = NULL;
+ clear_bit(SK_BUSY, &svsk->sk_flags);
goto out_unlock;
}
clear_bit(SOCK_NOSPACE, &svsk->sk_sock->flags);
- /* Mark socket as busy. It will remain in this state until the
- * server has processed all pending data and put the socket back
- * on the idle list.
- */
- set_bit(SK_BUSY, &svsk->sk_flags);
- if (!list_empty(&serv->sv_threads)) {
- rqstp = list_entry(serv->sv_threads.next,
+ if (!list_empty(&pool->sp_threads)) {
+ rqstp = list_entry(pool->sp_threads.next,
struct svc_rqst,
rq_list);
dprintk("svc: socket %p served by daemon %p\n",
svsk->sk_sk, rqstp);
- svc_serv_dequeue(serv, rqstp);
+ svc_thread_dequeue(pool, rqstp);
if (rqstp->rq_sock)
printk(KERN_ERR
"svc_sock_enqueue: server %p, rq_sock=%p!\n",
rqstp, rqstp->rq_sock);
rqstp->rq_sock = svsk;
- svsk->sk_inuse++;
+ atomic_inc(&svsk->sk_inuse);
rqstp->rq_reserved = serv->sv_bufsz;
- svsk->sk_reserved += rqstp->rq_reserved;
+ atomic_add(rqstp->rq_reserved, &svsk->sk_reserved);
+ BUG_ON(svsk->sk_pool != pool);
wake_up(&rqstp->rq_wait);
} else {
dprintk("svc: socket %p put into queue\n", svsk->sk_sk);
- list_add_tail(&svsk->sk_ready, &serv->sv_sockets);
+ list_add_tail(&svsk->sk_ready, &pool->sp_sockets);
+ BUG_ON(svsk->sk_pool != pool);
}
out_unlock:
- spin_unlock_bh(&serv->sv_lock);
+ spin_unlock_bh(&pool->sp_lock);
}
/*
- * Dequeue the first socket. Must be called with the serv->sv_lock held.
+ * Dequeue the first socket. Must be called with the pool->sp_lock held.
*/
static inline struct svc_sock *
-svc_sock_dequeue(struct svc_serv *serv)
+svc_sock_dequeue(struct svc_pool *pool)
{
struct svc_sock *svsk;
- if (list_empty(&serv->sv_sockets))
+ if (list_empty(&pool->sp_sockets))
return NULL;
- svsk = list_entry(serv->sv_sockets.next,
+ svsk = list_entry(pool->sp_sockets.next,
struct svc_sock, sk_ready);
list_del_init(&svsk->sk_ready);
dprintk("svc: socket %p dequeued, inuse=%d\n",
- svsk->sk_sk, svsk->sk_inuse);
+ svsk->sk_sk, atomic_read(&svsk->sk_inuse));
return svsk;
}
@@ -241,6 +264,7 @@ svc_sock_dequeue(struct svc_serv *serv)
static inline void
svc_sock_received(struct svc_sock *svsk)
{
+ svsk->sk_pool = NULL;
clear_bit(SK_BUSY, &svsk->sk_flags);
svc_sock_enqueue(svsk);
}
@@ -262,10 +286,8 @@ void svc_reserve(struct svc_rqst *rqstp, int space)
if (space < rqstp->rq_reserved) {
struct svc_sock *svsk = rqstp->rq_sock;
- spin_lock_bh(&svsk->sk_server->sv_lock);
- svsk->sk_reserved -= (rqstp->rq_reserved - space);
+ atomic_sub((rqstp->rq_reserved - space), &svsk->sk_reserved);
rqstp->rq_reserved = space;
- spin_unlock_bh(&svsk->sk_server->sv_lock);
svc_sock_enqueue(svsk);
}
@@ -277,17 +299,11 @@ void svc_reserve(struct svc_rqst *rqstp, int space)
static inline void
svc_sock_put(struct svc_sock *svsk)
{
- struct svc_serv *serv = svsk->sk_server;
-
- spin_lock_bh(&serv->sv_lock);
- if (!--(svsk->sk_inuse) && test_bit(SK_DEAD, &svsk->sk_flags)) {
- spin_unlock_bh(&serv->sv_lock);
+ if (atomic_dec_and_test(&svsk->sk_inuse) && test_bit(SK_DEAD, &svsk->sk_flags)) {
dprintk("svc: releasing dead socket\n");
sock_release(svsk->sk_sock);
kfree(svsk);
}
- else
- spin_unlock_bh(&serv->sv_lock);
}
static void
@@ -321,25 +337,33 @@ svc_sock_release(struct svc_rqst *rqstp)
/*
* External function to wake up a server waiting for data
+ * This really only makes sense for services like lockd
+ * which have exactly one thread anyway.
*/
void
svc_wake_up(struct svc_serv *serv)
{
struct svc_rqst *rqstp;
-
- spin_lock_bh(&serv->sv_lock);
- if (!list_empty(&serv->sv_threads)) {
- rqstp = list_entry(serv->sv_threads.next,
- struct svc_rqst,
- rq_list);
- dprintk("svc: daemon %p woken up.\n", rqstp);
- /*
- svc_serv_dequeue(serv, rqstp);
- rqstp->rq_sock = NULL;
- */
- wake_up(&rqstp->rq_wait);
+ unsigned int i;
+ struct svc_pool *pool;
+
+ for (i = 0; i < serv->sv_nrpools; i++) {
+ pool = &serv->sv_pools[i];
+
+ spin_lock_bh(&pool->sp_lock);
+ if (!list_empty(&pool->sp_threads)) {
+ rqstp = list_entry(pool->sp_threads.next,
+ struct svc_rqst,
+ rq_list);
+ dprintk("svc: daemon %p woken up.\n", rqstp);
+ /*
+ svc_thread_dequeue(pool, rqstp);
+ rqstp->rq_sock = NULL;
+ */
+ wake_up(&rqstp->rq_wait);
+ }
+ spin_unlock_bh(&pool->sp_lock);
}
- spin_unlock_bh(&serv->sv_lock);
}
/*
@@ -429,6 +453,51 @@ out:
}
/*
+ * Report socket names for nfsdfs
+ */
+static int one_sock_name(char *buf, struct svc_sock *svsk)
+{
+ int len;
+
+ switch(svsk->sk_sk->sk_family) {
+ case AF_INET:
+ len = sprintf(buf, "ipv4 %s %u.%u.%u.%u %d\n",
+ svsk->sk_sk->sk_protocol==IPPROTO_UDP?
+ "udp" : "tcp",
+ NIPQUAD(inet_sk(svsk->sk_sk)->rcv_saddr),
+ inet_sk(svsk->sk_sk)->num);
+ break;
+ default:
+ len = sprintf(buf, "*unknown-%d*\n",
+ svsk->sk_sk->sk_family);
+ }
+ return len;
+}
+
+int
+svc_sock_names(char *buf, struct svc_serv *serv, char *toclose)
+{
+ struct svc_sock *svsk, *closesk = NULL;
+ int len = 0;
+
+ if (!serv)
+ return 0;
+ spin_lock(&serv->sv_lock);
+ list_for_each_entry(svsk, &serv->sv_permsocks, sk_list) {
+ int onelen = one_sock_name(buf+len, svsk);
+ if (toclose && strcmp(toclose, buf+len) == 0)
+ closesk = svsk;
+ else
+ len += onelen;
+ }
+ spin_unlock(&serv->sv_lock);
+ if (closesk)
+ svc_delete_socket(closesk);
+ return len;
+}
+EXPORT_SYMBOL(svc_sock_names);
+
+/*
* Check input queue length
*/
static int
@@ -557,7 +626,10 @@ svc_udp_recvfrom(struct svc_rqst *rqstp)
/* udp sockets need large rcvbuf as all pending
* requests are still in that buffer. sndbuf must
* also be large enough that there is enough space
- * for one reply per thread.
+ * for one reply per thread. We count all threads
+ * rather than threads in a particular pool, which
+ * provides an upper bound on the number of threads
+ * which will access the socket.
*/
svc_sock_setbufsize(svsk->sk_sock,
(serv->sv_nrthreads+3) * serv->sv_bufsz,
@@ -844,7 +916,7 @@ svc_tcp_accept(struct svc_sock *svsk)
struct svc_sock,
sk_list);
set_bit(SK_CLOSE, &svsk->sk_flags);
- svsk->sk_inuse ++;
+ atomic_inc(&svsk->sk_inuse);
}
spin_unlock_bh(&serv->sv_lock);
@@ -902,6 +974,11 @@ svc_tcp_recvfrom(struct svc_rqst *rqstp)
/* sndbuf needs to have room for one request
* per thread, otherwise we can stall even when the
* network isn't a bottleneck.
+ *
+ * We count all threads rather than threads in a
+ * particular pool, which provides an upper bound
+ * on the number of threads which will access the socket.
+ *
* rcvbuf just needs to be able to hold a few requests.
* Normally they will be removed from the queue
* as soon a a complete request arrives.
@@ -1030,7 +1107,7 @@ svc_tcp_sendto(struct svc_rqst *rqstp)
{
struct xdr_buf *xbufp = &rqstp->rq_res;
int sent;
- u32 reclen;
+ __be32 reclen;
/* Set up the first element of the reply kvec.
* Any other kvecs that may be in use have been taken
@@ -1117,12 +1194,16 @@ svc_sock_update_bufs(struct svc_serv *serv)
}
/*
- * Receive the next request on any socket.
+ * Receive the next request on any socket. This code is carefully
+ * organised not to touch any cachelines in the shared svc_serv
+ * structure, only cachelines in the local svc_pool.
*/
int
-svc_recv(struct svc_serv *serv, struct svc_rqst *rqstp, long timeout)
+svc_recv(struct svc_rqst *rqstp, long timeout)
{
struct svc_sock *svsk =NULL;
+ struct svc_serv *serv = rqstp->rq_server;
+ struct svc_pool *pool = rqstp->rq_pool;
int len;
int pages;
struct xdr_buf *arg;
@@ -1172,32 +1253,15 @@ svc_recv(struct svc_serv *serv, struct svc_rqst *rqstp, long timeout)
if (signalled())
return -EINTR;
- spin_lock_bh(&serv->sv_lock);
- if (!list_empty(&serv->sv_tempsocks)) {
- svsk = list_entry(serv->sv_tempsocks.next,
- struct svc_sock, sk_list);
- /* apparently the "standard" is that clients close
- * idle connections after 5 minutes, servers after
- * 6 minutes
- * http://www.connectathon.org/talks96/nfstcp.pdf
- */
- if (get_seconds() - svsk->sk_lastrecv < 6*60
- || test_bit(SK_BUSY, &svsk->sk_flags))
- svsk = NULL;
- }
- if (svsk) {
- set_bit(SK_BUSY, &svsk->sk_flags);
- set_bit(SK_CLOSE, &svsk->sk_flags);
+ spin_lock_bh(&pool->sp_lock);
+ if ((svsk = svc_sock_dequeue(pool)) != NULL) {
rqstp->rq_sock = svsk;
- svsk->sk_inuse++;
- } else if ((svsk = svc_sock_dequeue(serv)) != NULL) {
- rqstp->rq_sock = svsk;
- svsk->sk_inuse++;
+ atomic_inc(&svsk->sk_inuse);
rqstp->rq_reserved = serv->sv_bufsz;
- svsk->sk_reserved += rqstp->rq_reserved;
+ atomic_add(rqstp->rq_reserved, &svsk->sk_reserved);
} else {
/* No data pending. Go to sleep */
- svc_serv_enqueue(serv, rqstp);
+ svc_thread_enqueue(pool, rqstp);
/*
* We have to be able to interrupt this wait
@@ -1205,26 +1269,26 @@ svc_recv(struct svc_serv *serv, struct svc_rqst *rqstp, long timeout)
*/
set_current_state(TASK_INTERRUPTIBLE);
add_wait_queue(&rqstp->rq_wait, &wait);
- spin_unlock_bh(&serv->sv_lock);
+ spin_unlock_bh(&pool->sp_lock);
schedule_timeout(timeout);
try_to_freeze();
- spin_lock_bh(&serv->sv_lock);
+ spin_lock_bh(&pool->sp_lock);
remove_wait_queue(&rqstp->rq_wait, &wait);
if (!(svsk = rqstp->rq_sock)) {
- svc_serv_dequeue(serv, rqstp);
- spin_unlock_bh(&serv->sv_lock);
+ svc_thread_dequeue(pool, rqstp);
+ spin_unlock_bh(&pool->sp_lock);
dprintk("svc: server %p, no data yet\n", rqstp);
return signalled()? -EINTR : -EAGAIN;
}
}
- spin_unlock_bh(&serv->sv_lock);
+ spin_unlock_bh(&pool->sp_lock);
- dprintk("svc: server %p, socket %p, inuse=%d\n",
- rqstp, svsk, svsk->sk_inuse);
+ dprintk("svc: server %p, pool %u, socket %p, inuse=%d\n",
+ rqstp, pool->sp_id, svsk, atomic_read(&svsk->sk_inuse));
len = svsk->sk_recvfrom(rqstp);
dprintk("svc: got len=%d\n", len);
@@ -1235,13 +1299,7 @@ svc_recv(struct svc_serv *serv, struct svc_rqst *rqstp, long timeout)
return -EAGAIN;
}
svsk->sk_lastrecv = get_seconds();
- if (test_bit(SK_TEMP, &svsk->sk_flags)) {
- /* push active sockets to end of list */
- spin_lock_bh(&serv->sv_lock);
- if (!list_empty(&svsk->sk_list))
- list_move_tail(&svsk->sk_list, &serv->sv_tempsocks);
- spin_unlock_bh(&serv->sv_lock);
- }
+ clear_bit(SK_OLD, &svsk->sk_flags);
rqstp->rq_secure = ntohs(rqstp->rq_addr.sin_port) < 1024;
rqstp->rq_chandle.defer = svc_defer;
@@ -1301,6 +1359,58 @@ svc_send(struct svc_rqst *rqstp)
}
/*
+ * Timer function to close old temporary sockets, using
+ * a mark-and-sweep algorithm.
+ */
+static void
+svc_age_temp_sockets(unsigned long closure)
+{
+ struct svc_serv *serv = (struct svc_serv *)closure;
+ struct svc_sock *svsk;
+ struct list_head *le, *next;
+ LIST_HEAD(to_be_aged);
+
+ dprintk("svc_age_temp_sockets\n");
+
+ if (!spin_trylock_bh(&serv->sv_lock)) {
+ /* busy, try again 1 sec later */
+ dprintk("svc_age_temp_sockets: busy\n");
+ mod_timer(&serv->sv_temptimer, jiffies + HZ);
+ return;
+ }
+
+ list_for_each_safe(le, next, &serv->sv_tempsocks) {
+ svsk = list_entry(le, struct svc_sock, sk_list);
+
+ if (!test_and_set_bit(SK_OLD, &svsk->sk_flags))
+ continue;
+ if (atomic_read(&svsk->sk_inuse) || test_bit(SK_BUSY, &svsk->sk_flags))
+ continue;
+ atomic_inc(&svsk->sk_inuse);
+ list_move(le, &to_be_aged);
+ set_bit(SK_CLOSE, &svsk->sk_flags);
+ set_bit(SK_DETACHED, &svsk->sk_flags);
+ }
+ spin_unlock_bh(&serv->sv_lock);
+
+ while (!list_empty(&to_be_aged)) {
+ le = to_be_aged.next;
+ /* fiddling the sk_list node is safe 'cos we're SK_DETACHED */
+ list_del_init(le);
+ svsk = list_entry(le, struct svc_sock, sk_list);
+
+ dprintk("queuing svsk %p for closing, %lu seconds old\n",
+ svsk, get_seconds() - svsk->sk_lastrecv);
+
+ /* a thread will dequeue and close it soon */
+ svc_sock_enqueue(svsk);
+ svc_sock_put(svsk);
+ }
+
+ mod_timer(&serv->sv_temptimer, jiffies + svc_conn_age_period * HZ);
+}
+
+/*
* Initialize socket for RPC use and create svc_sock struct
* XXX: May want to setsockopt SO_SNDBUF and SO_RCVBUF.
*/
@@ -1337,7 +1447,9 @@ svc_setup_socket(struct svc_serv *serv, struct socket *sock,
svsk->sk_odata = inet->sk_data_ready;
svsk->sk_owspace = inet->sk_write_space;
svsk->sk_server = serv;
+ atomic_set(&svsk->sk_inuse, 0);
svsk->sk_lastrecv = get_seconds();
+ spin_lock_init(&svsk->sk_defer_lock);
INIT_LIST_HEAD(&svsk->sk_deferred);
INIT_LIST_HEAD(&svsk->sk_ready);
mutex_init(&svsk->sk_mutex);
@@ -1353,6 +1465,13 @@ svc_setup_socket(struct svc_serv *serv, struct socket *sock,
set_bit(SK_TEMP, &svsk->sk_flags);
list_add(&svsk->sk_list, &serv->sv_tempsocks);
serv->sv_tmpcnt++;
+ if (serv->sv_temptimer.function == NULL) {
+ /* setup timer to age temp sockets */
+ setup_timer(&serv->sv_temptimer, svc_age_temp_sockets,
+ (unsigned long)serv);
+ mod_timer(&serv->sv_temptimer,
+ jiffies + svc_conn_age_period * HZ);
+ }
} else {
clear_bit(SK_TEMP, &svsk->sk_flags);
list_add(&svsk->sk_list, &serv->sv_permsocks);
@@ -1367,6 +1486,38 @@ svc_setup_socket(struct svc_serv *serv, struct socket *sock,
return svsk;
}
+int svc_addsock(struct svc_serv *serv,
+ int fd,
+ char *name_return,
+ int *proto)
+{
+ int err = 0;
+ struct socket *so = sockfd_lookup(fd, &err);
+ struct svc_sock *svsk = NULL;
+
+ if (!so)
+ return err;
+ if (so->sk->sk_family != AF_INET)
+ err = -EAFNOSUPPORT;
+ else if (so->sk->sk_protocol != IPPROTO_TCP &&
+ so->sk->sk_protocol != IPPROTO_UDP)
+ err = -EPROTONOSUPPORT;
+ else if (so->state > SS_UNCONNECTED)
+ err = -EISCONN;
+ else {
+ svsk = svc_setup_socket(serv, so, &err, 1);
+ if (svsk)
+ err = 0;
+ }
+ if (err) {
+ sockfd_put(so);
+ return err;
+ }
+ if (proto) *proto = so->sk->sk_protocol;
+ return one_sock_name(name_return, svsk);
+}
+EXPORT_SYMBOL_GPL(svc_addsock);
+
/*
* Create socket for RPC service.
*/
@@ -1393,14 +1544,12 @@ svc_create_socket(struct svc_serv *serv, int protocol, struct sockaddr_in *sin)
if ((error = sock_create_kern(PF_INET, type, protocol, &sock)) < 0)
return error;
- if (sin != NULL) {
- if (type == SOCK_STREAM)
- sock->sk->sk_reuse = 1; /* allow address reuse */
- error = kernel_bind(sock, (struct sockaddr *) sin,
- sizeof(*sin));
- if (error < 0)
- goto bummer;
- }
+ if (type == SOCK_STREAM)
+ sock->sk->sk_reuse = 1; /* allow address reuse */
+ error = kernel_bind(sock, (struct sockaddr *) sin,
+ sizeof(*sin));
+ if (error < 0)
+ goto bummer;
if (protocol == IPPROTO_TCP) {
if ((error = kernel_listen(sock, 64)) < 0)
@@ -1436,15 +1585,25 @@ svc_delete_socket(struct svc_sock *svsk)
spin_lock_bh(&serv->sv_lock);
- list_del_init(&svsk->sk_list);
- list_del_init(&svsk->sk_ready);
+ if (!test_and_set_bit(SK_DETACHED, &svsk->sk_flags))
+ list_del_init(&svsk->sk_list);
+ /*
+ * We used to delete the svc_sock from whichever list
+ * it's sk_ready node was on, but we don't actually
+ * need to. This is because the only time we're called
+ * while still attached to a queue, the queue itself
+ * is about to be destroyed (in svc_destroy).
+ */
if (!test_and_set_bit(SK_DEAD, &svsk->sk_flags))
if (test_bit(SK_TEMP, &svsk->sk_flags))
serv->sv_tmpcnt--;
- if (!svsk->sk_inuse) {
+ if (!atomic_read(&svsk->sk_inuse)) {
spin_unlock_bh(&serv->sv_lock);
- sock_release(svsk->sk_sock);
+ if (svsk->sk_sock->file)
+ sockfd_put(svsk->sk_sock);
+ else
+ sock_release(svsk->sk_sock);
kfree(svsk);
} else {
spin_unlock_bh(&serv->sv_lock);
@@ -1475,7 +1634,6 @@ svc_makesock(struct svc_serv *serv, int protocol, unsigned short port)
static void svc_revisit(struct cache_deferred_req *dreq, int too_many)
{
struct svc_deferred_req *dr = container_of(dreq, struct svc_deferred_req, handle);
- struct svc_serv *serv = dreq->owner;
struct svc_sock *svsk;
if (too_many) {
@@ -1486,9 +1644,9 @@ static void svc_revisit(struct cache_deferred_req *dreq, int too_many)
dprintk("revisit queued\n");
svsk = dr->svsk;
dr->svsk = NULL;
- spin_lock_bh(&serv->sv_lock);
+ spin_lock_bh(&svsk->sk_defer_lock);
list_add(&dr->handle.recent, &svsk->sk_deferred);
- spin_unlock_bh(&serv->sv_lock);
+ spin_unlock_bh(&svsk->sk_defer_lock);
set_bit(SK_DEFERRED, &svsk->sk_flags);
svc_sock_enqueue(svsk);
svc_sock_put(svsk);
@@ -1520,10 +1678,8 @@ svc_defer(struct cache_req *req)
dr->argslen = rqstp->rq_arg.len >> 2;
memcpy(dr->args, rqstp->rq_arg.head[0].iov_base-skip, dr->argslen<<2);
}
- spin_lock_bh(&rqstp->rq_server->sv_lock);
- rqstp->rq_sock->sk_inuse++;
+ atomic_inc(&rqstp->rq_sock->sk_inuse);
dr->svsk = rqstp->rq_sock;
- spin_unlock_bh(&rqstp->rq_server->sv_lock);
dr->handle.revisit = svc_revisit;
return &dr->handle;
@@ -1550,11 +1706,10 @@ static int svc_deferred_recv(struct svc_rqst *rqstp)
static struct svc_deferred_req *svc_deferred_dequeue(struct svc_sock *svsk)
{
struct svc_deferred_req *dr = NULL;
- struct svc_serv *serv = svsk->sk_server;
if (!test_bit(SK_DEFERRED, &svsk->sk_flags))
return NULL;
- spin_lock_bh(&serv->sv_lock);
+ spin_lock_bh(&svsk->sk_defer_lock);
clear_bit(SK_DEFERRED, &svsk->sk_flags);
if (!list_empty(&svsk->sk_deferred)) {
dr = list_entry(svsk->sk_deferred.next,
@@ -1563,6 +1718,6 @@ static struct svc_deferred_req *svc_deferred_dequeue(struct svc_sock *svsk)
list_del_init(&dr->handle.recent);
set_bit(SK_DEFERRED, &svsk->sk_flags);
}
- spin_unlock_bh(&serv->sv_lock);
+ spin_unlock_bh(&svsk->sk_defer_lock);
return dr;
}
diff --git a/net/sunrpc/xdr.c b/net/sunrpc/xdr.c
index 6ac45103a272..9022eb8b37ed 100644
--- a/net/sunrpc/xdr.c
+++ b/net/sunrpc/xdr.c
@@ -18,8 +18,8 @@
/*
* XDR functions for basic NFS types
*/
-u32 *
-xdr_encode_netobj(u32 *p, const struct xdr_netobj *obj)
+__be32 *
+xdr_encode_netobj(__be32 *p, const struct xdr_netobj *obj)
{
unsigned int quadlen = XDR_QUADLEN(obj->len);
@@ -29,8 +29,8 @@ xdr_encode_netobj(u32 *p, const struct xdr_netobj *obj)
return p + XDR_QUADLEN(obj->len);
}
-u32 *
-xdr_decode_netobj(u32 *p, struct xdr_netobj *obj)
+__be32 *
+xdr_decode_netobj(__be32 *p, struct xdr_netobj *obj)
{
unsigned int len;
@@ -55,7 +55,7 @@ xdr_decode_netobj(u32 *p, struct xdr_netobj *obj)
* Returns the updated current XDR buffer position
*
*/
-u32 *xdr_encode_opaque_fixed(u32 *p, const void *ptr, unsigned int nbytes)
+__be32 *xdr_encode_opaque_fixed(__be32 *p, const void *ptr, unsigned int nbytes)
{
if (likely(nbytes != 0)) {
unsigned int quadlen = XDR_QUADLEN(nbytes);
@@ -79,21 +79,21 @@ EXPORT_SYMBOL(xdr_encode_opaque_fixed);
*
* Returns the updated current XDR buffer position
*/
-u32 *xdr_encode_opaque(u32 *p, const void *ptr, unsigned int nbytes)
+__be32 *xdr_encode_opaque(__be32 *p, const void *ptr, unsigned int nbytes)
{
*p++ = htonl(nbytes);
return xdr_encode_opaque_fixed(p, ptr, nbytes);
}
EXPORT_SYMBOL(xdr_encode_opaque);
-u32 *
-xdr_encode_string(u32 *p, const char *string)
+__be32 *
+xdr_encode_string(__be32 *p, const char *string)
{
return xdr_encode_array(p, string, strlen(string));
}
-u32 *
-xdr_decode_string_inplace(u32 *p, char **sp, int *lenp, int maxlen)
+__be32 *
+xdr_decode_string_inplace(__be32 *p, char **sp, int *lenp, int maxlen)
{
unsigned int len;
@@ -432,7 +432,7 @@ xdr_shift_buf(struct xdr_buf *buf, size_t len)
* of the buffer length, and takes care of adjusting the kvec
* length for us.
*/
-void xdr_init_encode(struct xdr_stream *xdr, struct xdr_buf *buf, uint32_t *p)
+void xdr_init_encode(struct xdr_stream *xdr, struct xdr_buf *buf, __be32 *p)
{
struct kvec *iov = buf->head;
int scratch_len = buf->buflen - buf->page_len - buf->tail[0].iov_len;
@@ -440,8 +440,8 @@ void xdr_init_encode(struct xdr_stream *xdr, struct xdr_buf *buf, uint32_t *p)
BUG_ON(scratch_len < 0);
xdr->buf = buf;
xdr->iov = iov;
- xdr->p = (uint32_t *)((char *)iov->iov_base + iov->iov_len);
- xdr->end = (uint32_t *)((char *)iov->iov_base + scratch_len);
+ xdr->p = (__be32 *)((char *)iov->iov_base + iov->iov_len);
+ xdr->end = (__be32 *)((char *)iov->iov_base + scratch_len);
BUG_ON(iov->iov_len > scratch_len);
if (p != xdr->p && p != NULL) {
@@ -465,10 +465,10 @@ EXPORT_SYMBOL(xdr_init_encode);
* bytes of data. If so, update the total xdr_buf length, and
* adjust the length of the current kvec.
*/
-uint32_t * xdr_reserve_space(struct xdr_stream *xdr, size_t nbytes)
+__be32 * xdr_reserve_space(struct xdr_stream *xdr, size_t nbytes)
{
- uint32_t *p = xdr->p;
- uint32_t *q;
+ __be32 *p = xdr->p;
+ __be32 *q;
/* align nbytes on the next 32-bit boundary */
nbytes += 3;
@@ -524,7 +524,7 @@ EXPORT_SYMBOL(xdr_write_pages);
* @buf: pointer to XDR buffer from which to decode data
* @p: current pointer inside XDR buffer
*/
-void xdr_init_decode(struct xdr_stream *xdr, struct xdr_buf *buf, uint32_t *p)
+void xdr_init_decode(struct xdr_stream *xdr, struct xdr_buf *buf, __be32 *p)
{
struct kvec *iov = buf->head;
unsigned int len = iov->iov_len;
@@ -534,7 +534,7 @@ void xdr_init_decode(struct xdr_stream *xdr, struct xdr_buf *buf, uint32_t *p)
xdr->buf = buf;
xdr->iov = iov;
xdr->p = p;
- xdr->end = (uint32_t *)((char *)iov->iov_base + len);
+ xdr->end = (__be32 *)((char *)iov->iov_base + len);
}
EXPORT_SYMBOL(xdr_init_decode);
@@ -548,10 +548,10 @@ EXPORT_SYMBOL(xdr_init_decode);
* If so return the current pointer, then update the current
* pointer position.
*/
-uint32_t * xdr_inline_decode(struct xdr_stream *xdr, size_t nbytes)
+__be32 * xdr_inline_decode(struct xdr_stream *xdr, size_t nbytes)
{
- uint32_t *p = xdr->p;
- uint32_t *q = p + XDR_QUADLEN(nbytes);
+ __be32 *p = xdr->p;
+ __be32 *q = p + XDR_QUADLEN(nbytes);
if (unlikely(q > xdr->end || q < p))
return NULL;
@@ -599,8 +599,8 @@ void xdr_read_pages(struct xdr_stream *xdr, unsigned int len)
* Position current pointer at beginning of tail, and
* set remaining message length.
*/
- xdr->p = (uint32_t *)((char *)iov->iov_base + padding);
- xdr->end = (uint32_t *)((char *)iov->iov_base + end);
+ xdr->p = (__be32 *)((char *)iov->iov_base + padding);
+ xdr->end = (__be32 *)((char *)iov->iov_base + end);
}
EXPORT_SYMBOL(xdr_read_pages);
@@ -624,8 +624,8 @@ void xdr_enter_page(struct xdr_stream *xdr, unsigned int len)
*/
if (len > PAGE_CACHE_SIZE - xdr->buf->page_base)
len = PAGE_CACHE_SIZE - xdr->buf->page_base;
- xdr->p = (uint32_t *)(kaddr + xdr->buf->page_base);
- xdr->end = (uint32_t *)((char *)xdr->p + len);
+ xdr->p = (__be32 *)(kaddr + xdr->buf->page_base);
+ xdr->end = (__be32 *)((char *)xdr->p + len);
}
EXPORT_SYMBOL(xdr_enter_page);
@@ -743,7 +743,7 @@ out:
int
xdr_decode_word(struct xdr_buf *buf, int base, u32 *obj)
{
- u32 raw;
+ __be32 raw;
int status;
status = read_bytes_from_xdr_buf(buf, base, &raw, sizeof(*obj));
@@ -756,7 +756,7 @@ xdr_decode_word(struct xdr_buf *buf, int base, u32 *obj)
int
xdr_encode_word(struct xdr_buf *buf, int base, u32 obj)
{
- u32 raw = htonl(obj);
+ __be32 raw = htonl(obj);
return write_bytes_to_xdr_buf(buf, base, &raw, sizeof(obj));
}
diff --git a/net/sunrpc/xprt.c b/net/sunrpc/xprt.c
index 1f786f68729d..80857470dc11 100644
--- a/net/sunrpc/xprt.c
+++ b/net/sunrpc/xprt.c
@@ -594,7 +594,7 @@ static void xprt_connect_status(struct rpc_task *task)
* @xid: RPC XID of incoming reply
*
*/
-struct rpc_rqst *xprt_lookup_rqst(struct rpc_xprt *xprt, u32 xid)
+struct rpc_rqst *xprt_lookup_rqst(struct rpc_xprt *xprt, __be32 xid)
{
struct list_head *pos;
@@ -801,7 +801,7 @@ void xprt_reserve(struct rpc_task *task)
spin_unlock(&xprt->reserve_lock);
}
-static inline u32 xprt_alloc_xid(struct rpc_xprt *xprt)
+static inline __be32 xprt_alloc_xid(struct rpc_xprt *xprt)
{
return xprt->xid++;
}
diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c
index 9b62923a9c06..28100e019225 100644
--- a/net/sunrpc/xprtsock.c
+++ b/net/sunrpc/xprtsock.c
@@ -548,7 +548,8 @@ static void xs_udp_data_ready(struct sock *sk, int len)
struct rpc_rqst *rovr;
struct sk_buff *skb;
int err, repsize, copied;
- u32 _xid, *xp;
+ u32 _xid;
+ __be32 *xp;
read_lock(&sk->sk_callback_lock);
dprintk("RPC: xs_udp_data_ready...\n");
diff --git a/net/xfrm/xfrm_hash.h b/net/xfrm/xfrm_hash.h
index d3abb0b7dc62..6ac4e4f033ac 100644
--- a/net/xfrm/xfrm_hash.h
+++ b/net/xfrm/xfrm_hash.h
@@ -58,10 +58,10 @@ static inline unsigned __xfrm_src_hash(xfrm_address_t *saddr,
}
static inline unsigned int
-__xfrm_spi_hash(xfrm_address_t *daddr, u32 spi, u8 proto, unsigned short family,
+__xfrm_spi_hash(xfrm_address_t *daddr, __be32 spi, u8 proto, unsigned short family,
unsigned int hmask)
{
- unsigned int h = spi ^ proto;
+ unsigned int h = (__force u32)spi ^ proto;
switch (family) {
case AF_INET:
h ^= __xfrm4_addr_hash(daddr);
diff --git a/net/xfrm/xfrm_input.c b/net/xfrm/xfrm_input.c
index dfc90bb1cf1f..e8198a2c785d 100644
--- a/net/xfrm/xfrm_input.c
+++ b/net/xfrm/xfrm_input.c
@@ -46,7 +46,7 @@ EXPORT_SYMBOL(secpath_dup);
/* Fetch spi and seq from ipsec header */
-int xfrm_parse_spi(struct sk_buff *skb, u8 nexthdr, u32 *spi, u32 *seq)
+int xfrm_parse_spi(struct sk_buff *skb, u8 nexthdr, __be32 *spi, __be32 *seq)
{
int offset, offset_seq;
@@ -62,7 +62,7 @@ int xfrm_parse_spi(struct sk_buff *skb, u8 nexthdr, u32 *spi, u32 *seq)
case IPPROTO_COMP:
if (!pskb_may_pull(skb, sizeof(struct ip_comp_hdr)))
return -EINVAL;
- *spi = htonl(ntohs(*(u16*)(skb->h.raw + 2)));
+ *spi = htonl(ntohs(*(__be16*)(skb->h.raw + 2)));
*seq = 0;
return 0;
default:
@@ -72,8 +72,8 @@ int xfrm_parse_spi(struct sk_buff *skb, u8 nexthdr, u32 *spi, u32 *seq)
if (!pskb_may_pull(skb, 16))
return -EINVAL;
- *spi = *(u32*)(skb->h.raw + offset);
- *seq = *(u32*)(skb->h.raw + offset_seq);
+ *spi = *(__be32*)(skb->h.raw + offset);
+ *seq = *(__be32*)(skb->h.raw + offset_seq);
return 0;
}
EXPORT_SYMBOL(xfrm_parse_spi);
diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c
index 9f63edd39346..f927b7330f02 100644
--- a/net/xfrm/xfrm_state.c
+++ b/net/xfrm/xfrm_state.c
@@ -70,7 +70,7 @@ static inline unsigned int xfrm_src_hash(xfrm_address_t *addr,
}
static inline unsigned int
-xfrm_spi_hash(xfrm_address_t *daddr, u32 spi, u8 proto, unsigned short family)
+xfrm_spi_hash(xfrm_address_t *daddr, __be32 spi, u8 proto, unsigned short family)
{
return __xfrm_spi_hash(daddr, spi, proto, family, xfrm_state_hmask);
}
@@ -96,9 +96,12 @@ static void xfrm_hash_transfer(struct hlist_head *list,
nhashmask);
hlist_add_head(&x->bysrc, nsrctable+h);
- h = __xfrm_spi_hash(&x->id.daddr, x->id.spi, x->id.proto,
- x->props.family, nhashmask);
- hlist_add_head(&x->byspi, nspitable+h);
+ if (x->id.spi) {
+ h = __xfrm_spi_hash(&x->id.daddr, x->id.spi,
+ x->id.proto, x->props.family,
+ nhashmask);
+ hlist_add_head(&x->byspi, nspitable+h);
+ }
}
}
@@ -421,7 +424,7 @@ xfrm_init_tempsel(struct xfrm_state *x, struct flowi *fl,
return 0;
}
-static struct xfrm_state *__xfrm_state_lookup(xfrm_address_t *daddr, u32 spi, u8 proto, unsigned short family)
+static struct xfrm_state *__xfrm_state_lookup(xfrm_address_t *daddr, __be32 spi, u8 proto, unsigned short family)
{
unsigned int h = xfrm_spi_hash(daddr, spi, proto, family);
struct xfrm_state *x;
@@ -622,7 +625,7 @@ static void __xfrm_state_insert(struct xfrm_state *x)
h = xfrm_src_hash(&x->props.saddr, x->props.family);
hlist_add_head(&x->bysrc, xfrm_state_bysrc+h);
- if (xfrm_id_proto_match(x->id.proto, IPSEC_PROTO_ANY)) {
+ if (x->id.spi) {
h = xfrm_spi_hash(&x->id.daddr, x->id.spi, x->id.proto,
x->props.family);
@@ -916,7 +919,7 @@ err:
EXPORT_SYMBOL(xfrm_state_check);
struct xfrm_state *
-xfrm_state_lookup(xfrm_address_t *daddr, u32 spi, u8 proto,
+xfrm_state_lookup(xfrm_address_t *daddr, __be32 spi, u8 proto,
unsigned short family)
{
struct xfrm_state *x;
@@ -1040,7 +1043,7 @@ u32 xfrm_get_acqseq(void)
EXPORT_SYMBOL(xfrm_get_acqseq);
void
-xfrm_alloc_spi(struct xfrm_state *x, u32 minspi, u32 maxspi)
+xfrm_alloc_spi(struct xfrm_state *x, __be32 minspi, __be32 maxspi)
{
unsigned int h;
struct xfrm_state *x0;
@@ -1057,10 +1060,10 @@ xfrm_alloc_spi(struct xfrm_state *x, u32 minspi, u32 maxspi)
x->id.spi = minspi;
} else {
u32 spi = 0;
- minspi = ntohl(minspi);
- maxspi = ntohl(maxspi);
- for (h=0; h<maxspi-minspi+1; h++) {
- spi = minspi + net_random()%(maxspi-minspi+1);
+ u32 low = ntohl(minspi);
+ u32 high = ntohl(maxspi);
+ for (h=0; h<high-low+1; h++) {
+ spi = low + net_random()%(high-low+1);
x0 = xfrm_state_lookup(&x->id.daddr, htonl(spi), x->id.proto, x->props.family);
if (x0 == NULL) {
x->id.spi = htonl(spi);
@@ -1180,11 +1183,10 @@ static void xfrm_replay_timer_handler(unsigned long data)
spin_unlock(&x->lock);
}
-int xfrm_replay_check(struct xfrm_state *x, u32 seq)
+int xfrm_replay_check(struct xfrm_state *x, __be32 net_seq)
{
u32 diff;
-
- seq = ntohl(seq);
+ u32 seq = ntohl(net_seq);
if (unlikely(seq == 0))
return -EINVAL;
@@ -1206,11 +1208,10 @@ int xfrm_replay_check(struct xfrm_state *x, u32 seq)
}
EXPORT_SYMBOL(xfrm_replay_check);
-void xfrm_replay_advance(struct xfrm_state *x, u32 seq)
+void xfrm_replay_advance(struct xfrm_state *x, __be32 net_seq)
{
u32 diff;
-
- seq = ntohl(seq);
+ u32 seq = ntohl(net_seq);
if (seq > x->replay.seq) {
diff = seq - x->replay.seq;
diff --git a/scripts/.gitignore b/scripts/.gitignore
index a234e524a490..a1f52cb47200 100644
--- a/scripts/.gitignore
+++ b/scripts/.gitignore
@@ -5,3 +5,4 @@ conmakehash
kallsyms
pnmtologo
bin2c
+unifdef
diff --git a/scripts/Makefile b/scripts/Makefile
index ea41de8fb7f5..1c73c5aea66b 100644
--- a/scripts/Makefile
+++ b/scripts/Makefile
@@ -13,7 +13,7 @@ hostprogs-$(CONFIG_VT) += conmakehash
hostprogs-$(CONFIG_PROM_CONSOLE) += conmakehash
hostprogs-$(CONFIG_IKCONFIG) += bin2c
-always := $(hostprogs-y)
+always := $(hostprogs-y) $(hostprogs-m)
# The following hostprogs-y programs are only build on demand
hostprogs-y += unifdef
diff --git a/scripts/Makefile.modpost b/scripts/Makefile.modpost
index 4b2721ca97da..6c5469b1473b 100644
--- a/scripts/Makefile.modpost
+++ b/scripts/Makefile.modpost
@@ -32,6 +32,10 @@
# Step 4 is solely used to allow module versioning in external modules,
# where the CRC of each module is retrieved from the Module.symers file.
+# KBUILD_MODPOST_WARN can be set to avoid error out in case of undefined
+# symbols in the final module linking stage
+# KBUILD_MODPOST_NOFINAL can be set to skip the final link of modules.
+# This is solely usefull to speed up test compiles
PHONY := _modpost
_modpost: __modpost
@@ -46,7 +50,8 @@ modulesymfile := $(KBUILD_EXTMOD)/Module.symvers
__modules := $(sort $(shell grep -h '\.ko' /dev/null $(wildcard $(MODVERDIR)/*.mod)))
modules := $(patsubst %.o,%.ko, $(wildcard $(__modules:.ko=.o)))
-_modpost: $(modules)
+# Stop after building .o files if NOFINAL is set. Makes compile tests quicker
+_modpost: $(if $(KBUILD_MODPOST_NOFINAL), $(modules:.ko:.o),$(modules))
# Step 2), invoke modpost
@@ -58,7 +63,7 @@ quiet_cmd_modpost = MODPOST $(words $(filter-out vmlinux FORCE, $^)) modules
$(if $(KBUILD_EXTMOD),-i,-o) $(kernelsymfile) \
$(if $(KBUILD_EXTMOD),-I $(modulesymfile)) \
$(if $(KBUILD_EXTMOD),-o $(modulesymfile)) \
- $(if $(KBUILD_EXTMOD),-w) \
+ $(if $(KBUILD_EXTMOD)$(KBUILD_MODPOST_WARN),-w) \
$(wildcard vmlinux) $(filter-out FORCE,$^)
PHONY += __modpost
@@ -92,7 +97,7 @@ targets += $(modules:.ko=.mod.o)
# Step 6), final link of the modules
quiet_cmd_ld_ko_o = LD [M] $@
- cmd_ld_ko_o = $(LD) $(LDFLAGS) $(LDFLAGS_MODULE) -o $@ \
+ cmd_ld_ko_o = $(LD) $(LDFLAGS) $(LDFLAGS_MODULE) -o $@ \
$(filter-out FORCE,$^)
$(modules): %.ko :%.o %.mod.o FORCE
diff --git a/scripts/basic/docproc.c b/scripts/basic/docproc.c
index cb02baa63256..4ab6cbf09225 100644
--- a/scripts/basic/docproc.c
+++ b/scripts/basic/docproc.c
@@ -177,6 +177,7 @@ void find_export_symbols(char * filename)
{
fprintf(stderr, "docproc: ");
perror(real_filename);
+ exit(1);
}
while(fgets(line, MAXLINESZ, fp)) {
char *p;
diff --git a/scripts/kconfig/Makefile b/scripts/kconfig/Makefile
index a90d3cc76bfa..7e7e147875bf 100644
--- a/scripts/kconfig/Makefile
+++ b/scripts/kconfig/Makefile
@@ -11,7 +11,6 @@ gconfig: $(obj)/gconf
$< arch/$(ARCH)/Kconfig
menuconfig: $(obj)/mconf
- $(Q)$(MAKE) $(build)=scripts/kconfig/lxdialog
$< arch/$(ARCH)/Kconfig
config: $(obj)/conf
@@ -81,6 +80,23 @@ help:
@echo ' allyesconfig - New config where all options are accepted with yes'
@echo ' allnoconfig - New config where all options are answered with no'
+# lxdialog stuff
+check-lxdialog := $(srctree)/$(src)/lxdialog/check-lxdialog.sh
+
+# Use reursively expanded variables so we do not call gcc unless
+# we really need to do so. (Do not call gcc as part of make mrproper)
+HOST_EXTRACFLAGS = $(shell $(CONFIG_SHELL) $(check-lxdialog) -ccflags)
+HOST_LOADLIBES = $(shell $(CONFIG_SHELL) $(check-lxdialog) -ldflags $(HOSTCC))
+
+HOST_EXTRACFLAGS += -DLOCALE
+
+PHONY += $(obj)/dochecklxdialog
+$(obj)/dochecklxdialog:
+ $(Q)$(CONFIG_SHELL) $(check-lxdialog) -check $(HOSTCC) $(HOST_LOADLIBES)
+
+always := dochecklxdialog
+
+
# ===========================================================================
# Shared Makefile for the various kconfig executables:
# conf: Used for defconfig, oldconfig and related targets
@@ -92,11 +108,19 @@ help:
# Based on GTK which needs to be installed to compile it
# object files used by all kconfig flavours
-hostprogs-y := conf mconf qconf gconf kxgettext
+lxdialog := lxdialog/checklist.o lxdialog/util.o lxdialog/inputbox.o
+lxdialog += lxdialog/textbox.o lxdialog/yesno.o lxdialog/menubox.o
+
conf-objs := conf.o zconf.tab.o
-mconf-objs := mconf.o zconf.tab.o
+mconf-objs := mconf.o zconf.tab.o $(lxdialog)
kxgettext-objs := kxgettext.o zconf.tab.o
+hostprogs-y := conf qconf gconf kxgettext
+
+ifeq ($(MAKECMDGOALS),menuconfig)
+ hostprogs-y += mconf
+endif
+
ifeq ($(MAKECMDGOALS),xconfig)
qconf-target := 1
endif
@@ -116,7 +140,6 @@ endif
clean-files := lkc_defs.h qconf.moc .tmp_qtcheck \
.tmp_gtkcheck zconf.tab.c lex.zconf.c zconf.hash.c
-subdir- += lxdialog
# Needed for systems without gettext
KBUILD_HAVE_NLS := $(shell \
diff --git a/scripts/kconfig/confdata.c b/scripts/kconfig/confdata.c
index 69f96b398c22..66b15ef02931 100644
--- a/scripts/kconfig/confdata.c
+++ b/scripts/kconfig/confdata.c
@@ -517,7 +517,7 @@ int conf_write(const char *name)
fclose(out);
if (*tmpname) {
- strcat(dirname, name ? name : conf_get_configname());
+ strcat(dirname, basename);
strcat(dirname, ".old");
rename(newname, dirname);
if (rename(tmpname, newname))
diff --git a/scripts/kconfig/lxdialog/Makefile b/scripts/kconfig/lxdialog/Makefile
deleted file mode 100644
index a8b026326247..000000000000
--- a/scripts/kconfig/lxdialog/Makefile
+++ /dev/null
@@ -1,21 +0,0 @@
-# Makefile to build lxdialog package
-#
-
-check-lxdialog := $(srctree)/$(src)/check-lxdialog.sh
-
-# Use reursively expanded variables so we do not call gcc unless
-# we really need to do so. (Do not call gcc as part of make mrproper)
-HOST_EXTRACFLAGS = $(shell $(CONFIG_SHELL) $(check-lxdialog) -ccflags)
-HOST_LOADLIBES = $(shell $(CONFIG_SHELL) $(check-lxdialog) -ldflags $(HOSTCC))
-
-HOST_EXTRACFLAGS += -DLOCALE
-
-PHONY += dochecklxdialog
-$(obj)/dochecklxdialog:
- $(Q)$(CONFIG_SHELL) $(check-lxdialog) -check $(HOSTCC) $(HOST_LOADLIBES)
-
-hostprogs-y := lxdialog
-always := $(hostprogs-y) dochecklxdialog
-
-lxdialog-objs := checklist.o menubox.o textbox.o yesno.o inputbox.o \
- util.o lxdialog.o msgbox.o
diff --git a/scripts/kconfig/lxdialog/checklist.c b/scripts/kconfig/lxdialog/checklist.c
index 79886413b6d5..cf697080dddd 100644
--- a/scripts/kconfig/lxdialog/checklist.c
+++ b/scripts/kconfig/lxdialog/checklist.c
@@ -28,25 +28,25 @@ static int list_width, check_x, item_x;
/*
* Print list item
*/
-static void print_item(WINDOW * win, const char *item, int status, int choice,
- int selected)
+static void print_item(WINDOW * win, int choice, int selected)
{
int i;
/* Clear 'residue' of last item */
- wattrset(win, menubox_attr);
+ wattrset(win, dlg.menubox.atr);
wmove(win, choice, 0);
for (i = 0; i < list_width; i++)
waddch(win, ' ');
wmove(win, choice, check_x);
- wattrset(win, selected ? check_selected_attr : check_attr);
- wprintw(win, "(%c)", status ? 'X' : ' ');
-
- wattrset(win, selected ? tag_selected_attr : tag_attr);
- mvwaddch(win, choice, item_x, item[0]);
- wattrset(win, selected ? item_selected_attr : item_attr);
- waddstr(win, (char *)item + 1);
+ wattrset(win, selected ? dlg.check_selected.atr
+ : dlg.check.atr);
+ wprintw(win, "(%c)", item_is_tag('X') ? 'X' : ' ');
+
+ wattrset(win, selected ? dlg.tag_selected.atr : dlg.tag.atr);
+ mvwaddch(win, choice, item_x, item_str()[0]);
+ wattrset(win, selected ? dlg.item_selected.atr : dlg.item.atr);
+ waddstr(win, (char *)item_str() + 1);
if (selected) {
wmove(win, choice, check_x + 1);
wrefresh(win);
@@ -62,11 +62,11 @@ static void print_arrows(WINDOW * win, int choice, int item_no, int scroll,
wmove(win, y, x);
if (scroll > 0) {
- wattrset(win, uarrow_attr);
+ wattrset(win, dlg.uarrow.atr);
waddch(win, ACS_UARROW);
waddstr(win, "(-)");
} else {
- wattrset(win, menubox_attr);
+ wattrset(win, dlg.menubox.atr);
waddch(win, ACS_HLINE);
waddch(win, ACS_HLINE);
waddch(win, ACS_HLINE);
@@ -77,11 +77,11 @@ static void print_arrows(WINDOW * win, int choice, int item_no, int scroll,
wmove(win, y, x);
if ((height < item_no) && (scroll + choice < item_no - 1)) {
- wattrset(win, darrow_attr);
+ wattrset(win, dlg.darrow.atr);
waddch(win, ACS_DARROW);
waddstr(win, "(+)");
} else {
- wattrset(win, menubox_border_attr);
+ wattrset(win, dlg.menubox_border.atr);
waddch(win, ACS_HLINE);
waddch(win, ACS_HLINE);
waddch(win, ACS_HLINE);
@@ -109,32 +109,29 @@ static void print_buttons(WINDOW * dialog, int height, int width, int selected)
* in the style of radiolist (only one option turned on at a time).
*/
int dialog_checklist(const char *title, const char *prompt, int height,
- int width, int list_height, int item_no,
- const char *const *items)
+ int width, int list_height)
{
int i, x, y, box_x, box_y;
- int key = 0, button = 0, choice = 0, scroll = 0, max_choice, *status;
+ int key = 0, button = 0, choice = 0, scroll = 0, max_choice;
WINDOW *dialog, *list;
- /* Allocate space for storing item on/off status */
- if ((status = malloc(sizeof(int) * item_no)) == NULL) {
- endwin();
- fprintf(stderr,
- "\nCan't allocate memory in dialog_checklist().\n");
- exit(-1);
+ /* which item to highlight */
+ item_foreach() {
+ if (item_is_tag('X'))
+ choice = item_n();
+ if (item_is_selected()) {
+ choice = item_n();
+ break;
+ }
}
- /* Initializes status */
- for (i = 0; i < item_no; i++) {
- status[i] = !strcasecmp(items[i * 3 + 2], "on");
- if ((!choice && status[i])
- || !strcasecmp(items[i * 3 + 2], "selected"))
- choice = i + 1;
- }
- if (choice)
- choice--;
+do_resize:
+ if (getmaxy(stdscr) < (height + 6))
+ return -ERRDISPLAYTOOSMALL;
+ if (getmaxx(stdscr) < (width + 6))
+ return -ERRDISPLAYTOOSMALL;
- max_choice = MIN(list_height, item_no);
+ max_choice = MIN(list_height, item_count());
/* center dialog box on screen */
x = (COLS - width) / 2;
@@ -145,17 +142,18 @@ int dialog_checklist(const char *title, const char *prompt, int height,
dialog = newwin(height, width, y, x);
keypad(dialog, TRUE);
- draw_box(dialog, 0, 0, height, width, dialog_attr, border_attr);
- wattrset(dialog, border_attr);
+ draw_box(dialog, 0, 0, height, width,
+ dlg.dialog.atr, dlg.border.atr);
+ wattrset(dialog, dlg.border.atr);
mvwaddch(dialog, height - 3, 0, ACS_LTEE);
for (i = 0; i < width - 2; i++)
waddch(dialog, ACS_HLINE);
- wattrset(dialog, dialog_attr);
+ wattrset(dialog, dlg.dialog.atr);
waddch(dialog, ACS_RTEE);
print_title(dialog, title, width);
- wattrset(dialog, dialog_attr);
+ wattrset(dialog, dlg.dialog.atr);
print_autowrap(dialog, prompt, width - 2, 1, 3);
list_width = width - 6;
@@ -170,12 +168,12 @@ int dialog_checklist(const char *title, const char *prompt, int height,
/* draw a box around the list items */
draw_box(dialog, box_y, box_x, list_height + 2, list_width + 2,
- menubox_border_attr, menubox_attr);
+ dlg.menubox_border.atr, dlg.menubox.atr);
/* Find length of longest item in order to center checklist */
check_x = 0;
- for (i = 0; i < item_no; i++)
- check_x = MAX(check_x, +strlen(items[i * 3 + 1]) + 4);
+ item_foreach()
+ check_x = MAX(check_x, strlen(item_str()) + 4);
check_x = (list_width - check_x) / 2;
item_x = check_x + 4;
@@ -187,14 +185,11 @@ int dialog_checklist(const char *title, const char *prompt, int height,
/* Print the list */
for (i = 0; i < max_choice; i++) {
- if (i != choice)
- print_item(list, items[(scroll + i) * 3 + 1],
- status[i + scroll], i, 0);
+ item_set(scroll + i);
+ print_item(list, i, i == choice);
}
- print_item(list, items[(scroll + choice) * 3 + 1],
- status[choice + scroll], choice, 1);
- print_arrows(dialog, choice, item_no, scroll,
+ print_arrows(dialog, choice, item_count(), scroll,
box_y, box_x + check_x + 5, list_height);
print_buttons(dialog, height, width, 0);
@@ -203,13 +198,14 @@ int dialog_checklist(const char *title, const char *prompt, int height,
wnoutrefresh(list);
doupdate();
- while (key != ESC) {
+ while (key != KEY_ESC) {
key = wgetch(dialog);
- for (i = 0; i < max_choice; i++)
- if (toupper(key) ==
- toupper(items[(scroll + i) * 3 + 1][0]))
+ for (i = 0; i < max_choice; i++) {
+ item_set(i + scroll);
+ if (toupper(key) == toupper(item_str()[0]))
break;
+ }
if (i < max_choice || key == KEY_UP || key == KEY_DOWN ||
key == '+' || key == '-') {
@@ -220,15 +216,16 @@ int dialog_checklist(const char *title, const char *prompt, int height,
/* Scroll list down */
if (list_height > 1) {
/* De-highlight current first item */
- print_item(list, items[scroll * 3 + 1],
- status[scroll], 0, FALSE);
+ item_set(scroll);
+ print_item(list, 0, FALSE);
scrollok(list, TRUE);
wscrl(list, -1);
scrollok(list, FALSE);
}
scroll--;
- print_item(list, items[scroll * 3 + 1], status[scroll], 0, TRUE);
- print_arrows(dialog, choice, item_no,
+ item_set(scroll);
+ print_item(list, 0, TRUE);
+ print_arrows(dialog, choice, item_count(),
scroll, box_y, box_x + check_x + 5, list_height);
wnoutrefresh(dialog);
@@ -239,23 +236,24 @@ int dialog_checklist(const char *title, const char *prompt, int height,
i = choice - 1;
} else if (key == KEY_DOWN || key == '+') {
if (choice == max_choice - 1) {
- if (scroll + choice >= item_no - 1)
+ if (scroll + choice >= item_count() - 1)
continue;
/* Scroll list up */
if (list_height > 1) {
/* De-highlight current last item before scrolling up */
- print_item(list, items[(scroll + max_choice - 1) * 3 + 1],
- status[scroll + max_choice - 1],
- max_choice - 1, FALSE);
+ item_set(scroll + max_choice - 1);
+ print_item(list,
+ max_choice - 1,
+ FALSE);
scrollok(list, TRUE);
wscrl(list, 1);
scrollok(list, FALSE);
}
scroll++;
- print_item(list, items[(scroll + max_choice - 1) * 3 + 1],
- status[scroll + max_choice - 1], max_choice - 1, TRUE);
+ item_set(scroll + max_choice - 1);
+ print_item(list, max_choice - 1, TRUE);
- print_arrows(dialog, choice, item_no,
+ print_arrows(dialog, choice, item_count(),
scroll, box_y, box_x + check_x + 5, list_height);
wnoutrefresh(dialog);
@@ -267,12 +265,12 @@ int dialog_checklist(const char *title, const char *prompt, int height,
}
if (i != choice) {
/* De-highlight current item */
- print_item(list, items[(scroll + choice) * 3 + 1],
- status[scroll + choice], choice, FALSE);
+ item_set(scroll + choice);
+ print_item(list, choice, FALSE);
/* Highlight new item */
choice = i;
- print_item(list, items[(scroll + choice) * 3 + 1],
- status[scroll + choice], choice, TRUE);
+ item_set(scroll + choice);
+ print_item(list, choice, TRUE);
wnoutrefresh(dialog);
wrefresh(list);
}
@@ -282,10 +280,19 @@ int dialog_checklist(const char *title, const char *prompt, int height,
case 'H':
case 'h':
case '?':
- fprintf(stderr, "%s", items[(scroll + choice) * 3]);
+ button = 1;
+ /* fall-through */
+ case 'S':
+ case 's':
+ case ' ':
+ case '\n':
+ item_foreach()
+ item_set_selected(0);
+ item_set(scroll + choice);
+ item_set_selected(1);
+ delwin(list);
delwin(dialog);
- free(status);
- return 1;
+ return button;
case TAB:
case KEY_LEFT:
case KEY_RIGHT:
@@ -295,42 +302,24 @@ int dialog_checklist(const char *title, const char *prompt, int height,
print_buttons(dialog, height, width, button);
wrefresh(dialog);
break;
- case 'S':
- case 's':
- case ' ':
- case '\n':
- if (!button) {
- if (!status[scroll + choice]) {
- for (i = 0; i < item_no; i++)
- status[i] = 0;
- status[scroll + choice] = 1;
- for (i = 0; i < max_choice; i++)
- print_item(list, items[(scroll + i) * 3 + 1],
- status[scroll + i], i, i == choice);
- }
- wnoutrefresh(dialog);
- wrefresh(list);
-
- for (i = 0; i < item_no; i++)
- if (status[i])
- fprintf(stderr, "%s", items[i * 3]);
- } else
- fprintf(stderr, "%s", items[(scroll + choice) * 3]);
- delwin(dialog);
- free(status);
- return button;
case 'X':
case 'x':
- key = ESC;
- case ESC:
+ key = KEY_ESC;
+ break;
+ case KEY_ESC:
+ key = on_key_esc(dialog);
break;
+ case KEY_RESIZE:
+ delwin(list);
+ delwin(dialog);
+ on_key_resize();
+ goto do_resize;
}
/* Now, update everything... */
doupdate();
}
-
+ delwin(list);
delwin(dialog);
- free(status);
- return -1; /* ESC pressed */
+ return key; /* ESC pressed */
}
diff --git a/scripts/kconfig/lxdialog/colors.h b/scripts/kconfig/lxdialog/colors.h
deleted file mode 100644
index db071df12bbb..000000000000
--- a/scripts/kconfig/lxdialog/colors.h
+++ /dev/null
@@ -1,154 +0,0 @@
-/*
- * colors.h -- color attribute definitions
- *
- * AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
- *
- * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-/*
- * Default color definitions
- *
- * *_FG = foreground
- * *_BG = background
- * *_HL = highlight?
- */
-#define SCREEN_FG COLOR_CYAN
-#define SCREEN_BG COLOR_BLUE
-#define SCREEN_HL TRUE
-
-#define SHADOW_FG COLOR_BLACK
-#define SHADOW_BG COLOR_BLACK
-#define SHADOW_HL TRUE
-
-#define DIALOG_FG COLOR_BLACK
-#define DIALOG_BG COLOR_WHITE
-#define DIALOG_HL FALSE
-
-#define TITLE_FG COLOR_YELLOW
-#define TITLE_BG COLOR_WHITE
-#define TITLE_HL TRUE
-
-#define BORDER_FG COLOR_WHITE
-#define BORDER_BG COLOR_WHITE
-#define BORDER_HL TRUE
-
-#define BUTTON_ACTIVE_FG COLOR_WHITE
-#define BUTTON_ACTIVE_BG COLOR_BLUE
-#define BUTTON_ACTIVE_HL TRUE
-
-#define BUTTON_INACTIVE_FG COLOR_BLACK
-#define BUTTON_INACTIVE_BG COLOR_WHITE
-#define BUTTON_INACTIVE_HL FALSE
-
-#define BUTTON_KEY_ACTIVE_FG COLOR_WHITE
-#define BUTTON_KEY_ACTIVE_BG COLOR_BLUE
-#define BUTTON_KEY_ACTIVE_HL TRUE
-
-#define BUTTON_KEY_INACTIVE_FG COLOR_RED
-#define BUTTON_KEY_INACTIVE_BG COLOR_WHITE
-#define BUTTON_KEY_INACTIVE_HL FALSE
-
-#define BUTTON_LABEL_ACTIVE_FG COLOR_YELLOW
-#define BUTTON_LABEL_ACTIVE_BG COLOR_BLUE
-#define BUTTON_LABEL_ACTIVE_HL TRUE
-
-#define BUTTON_LABEL_INACTIVE_FG COLOR_BLACK
-#define BUTTON_LABEL_INACTIVE_BG COLOR_WHITE
-#define BUTTON_LABEL_INACTIVE_HL TRUE
-
-#define INPUTBOX_FG COLOR_BLACK
-#define INPUTBOX_BG COLOR_WHITE
-#define INPUTBOX_HL FALSE
-
-#define INPUTBOX_BORDER_FG COLOR_BLACK
-#define INPUTBOX_BORDER_BG COLOR_WHITE
-#define INPUTBOX_BORDER_HL FALSE
-
-#define SEARCHBOX_FG COLOR_BLACK
-#define SEARCHBOX_BG COLOR_WHITE
-#define SEARCHBOX_HL FALSE
-
-#define SEARCHBOX_TITLE_FG COLOR_YELLOW
-#define SEARCHBOX_TITLE_BG COLOR_WHITE
-#define SEARCHBOX_TITLE_HL TRUE
-
-#define SEARCHBOX_BORDER_FG COLOR_WHITE
-#define SEARCHBOX_BORDER_BG COLOR_WHITE
-#define SEARCHBOX_BORDER_HL TRUE
-
-#define POSITION_INDICATOR_FG COLOR_YELLOW
-#define POSITION_INDICATOR_BG COLOR_WHITE
-#define POSITION_INDICATOR_HL TRUE
-
-#define MENUBOX_FG COLOR_BLACK
-#define MENUBOX_BG COLOR_WHITE
-#define MENUBOX_HL FALSE
-
-#define MENUBOX_BORDER_FG COLOR_WHITE
-#define MENUBOX_BORDER_BG COLOR_WHITE
-#define MENUBOX_BORDER_HL TRUE
-
-#define ITEM_FG COLOR_BLACK
-#define ITEM_BG COLOR_WHITE
-#define ITEM_HL FALSE
-
-#define ITEM_SELECTED_FG COLOR_WHITE
-#define ITEM_SELECTED_BG COLOR_BLUE
-#define ITEM_SELECTED_HL TRUE
-
-#define TAG_FG COLOR_YELLOW
-#define TAG_BG COLOR_WHITE
-#define TAG_HL TRUE
-
-#define TAG_SELECTED_FG COLOR_YELLOW
-#define TAG_SELECTED_BG COLOR_BLUE
-#define TAG_SELECTED_HL TRUE
-
-#define TAG_KEY_FG COLOR_YELLOW
-#define TAG_KEY_BG COLOR_WHITE
-#define TAG_KEY_HL TRUE
-
-#define TAG_KEY_SELECTED_FG COLOR_YELLOW
-#define TAG_KEY_SELECTED_BG COLOR_BLUE
-#define TAG_KEY_SELECTED_HL TRUE
-
-#define CHECK_FG COLOR_BLACK
-#define CHECK_BG COLOR_WHITE
-#define CHECK_HL FALSE
-
-#define CHECK_SELECTED_FG COLOR_WHITE
-#define CHECK_SELECTED_BG COLOR_BLUE
-#define CHECK_SELECTED_HL TRUE
-
-#define UARROW_FG COLOR_GREEN
-#define UARROW_BG COLOR_WHITE
-#define UARROW_HL TRUE
-
-#define DARROW_FG COLOR_GREEN
-#define DARROW_BG COLOR_WHITE
-#define DARROW_HL TRUE
-
-/* End of default color definitions */
-
-#define C_ATTR(x,y) ((x ? A_BOLD : 0) | COLOR_PAIR((y)))
-#define COLOR_NAME_LEN 10
-#define COLOR_COUNT 8
-
-/*
- * Global variables
- */
-
-extern int color_table[][3];
diff --git a/scripts/kconfig/lxdialog/dialog.h b/scripts/kconfig/lxdialog/dialog.h
index af3cf716e215..8dea47f9d3e4 100644
--- a/scripts/kconfig/lxdialog/dialog.h
+++ b/scripts/kconfig/lxdialog/dialog.h
@@ -48,7 +48,7 @@
#define TR(params) _tracef params
-#define ESC 27
+#define KEY_ESC 27
#define TAB 9
#define MAX_LEN 2048
#define BUF_SIZE (10*1024)
@@ -86,63 +86,111 @@
#define ACS_DARROW 'v'
#endif
+/* error return codes */
+#define ERRDISPLAYTOOSMALL (KEY_MAX + 1)
+
/*
- * Attribute names
+ * Color definitions
*/
-#define screen_attr attributes[0]
-#define shadow_attr attributes[1]
-#define dialog_attr attributes[2]
-#define title_attr attributes[3]
-#define border_attr attributes[4]
-#define button_active_attr attributes[5]
-#define button_inactive_attr attributes[6]
-#define button_key_active_attr attributes[7]
-#define button_key_inactive_attr attributes[8]
-#define button_label_active_attr attributes[9]
-#define button_label_inactive_attr attributes[10]
-#define inputbox_attr attributes[11]
-#define inputbox_border_attr attributes[12]
-#define searchbox_attr attributes[13]
-#define searchbox_title_attr attributes[14]
-#define searchbox_border_attr attributes[15]
-#define position_indicator_attr attributes[16]
-#define menubox_attr attributes[17]
-#define menubox_border_attr attributes[18]
-#define item_attr attributes[19]
-#define item_selected_attr attributes[20]
-#define tag_attr attributes[21]
-#define tag_selected_attr attributes[22]
-#define tag_key_attr attributes[23]
-#define tag_key_selected_attr attributes[24]
-#define check_attr attributes[25]
-#define check_selected_attr attributes[26]
-#define uarrow_attr attributes[27]
-#define darrow_attr attributes[28]
-
-/* number of attributes */
-#define ATTRIBUTE_COUNT 29
+struct dialog_color {
+ chtype atr; /* Color attribute */
+ int fg; /* foreground */
+ int bg; /* background */
+ int hl; /* highlight this item */
+};
+
+struct dialog_info {
+ const char *backtitle;
+ struct dialog_color screen;
+ struct dialog_color shadow;
+ struct dialog_color dialog;
+ struct dialog_color title;
+ struct dialog_color border;
+ struct dialog_color button_active;
+ struct dialog_color button_inactive;
+ struct dialog_color button_key_active;
+ struct dialog_color button_key_inactive;
+ struct dialog_color button_label_active;
+ struct dialog_color button_label_inactive;
+ struct dialog_color inputbox;
+ struct dialog_color inputbox_border;
+ struct dialog_color searchbox;
+ struct dialog_color searchbox_title;
+ struct dialog_color searchbox_border;
+ struct dialog_color position_indicator;
+ struct dialog_color menubox;
+ struct dialog_color menubox_border;
+ struct dialog_color item;
+ struct dialog_color item_selected;
+ struct dialog_color tag;
+ struct dialog_color tag_selected;
+ struct dialog_color tag_key;
+ struct dialog_color tag_key_selected;
+ struct dialog_color check;
+ struct dialog_color check_selected;
+ struct dialog_color uarrow;
+ struct dialog_color darrow;
+};
/*
* Global variables
*/
-extern bool use_colors;
-extern bool use_shadow;
-
-extern chtype attributes[];
-
-extern const char *backtitle;
+extern struct dialog_info dlg;
+extern char dialog_input_result[];
/*
* Function prototypes
*/
-extern void create_rc(const char *filename);
-extern int parse_rc(void);
-void init_dialog(void);
+/* item list as used by checklist and menubox */
+void item_reset(void);
+void item_make(const char *fmt, ...);
+void item_add_str(const char *fmt, ...);
+void item_set_tag(char tag);
+void item_set_data(void *p);
+void item_set_selected(int val);
+int item_activate_selected(void);
+void *item_data(void);
+char item_tag(void);
+
+/* item list manipulation for lxdialog use */
+#define MAXITEMSTR 200
+struct dialog_item {
+ char str[MAXITEMSTR]; /* promtp displayed */
+ char tag;
+ void *data; /* pointer to menu item - used by menubox+checklist */
+ int selected; /* Set to 1 by dialog_*() function if selected. */
+};
+
+/* list of lialog_items */
+struct dialog_list {
+ struct dialog_item node;
+ struct dialog_list *next;
+};
+
+extern struct dialog_list *item_cur;
+extern struct dialog_list item_nil;
+extern struct dialog_list *item_head;
+
+int item_count(void);
+void item_set(int n);
+int item_n(void);
+const char *item_str(void);
+int item_is_selected(void);
+int item_is_tag(char tag);
+#define item_foreach() \
+ for (item_cur = item_head ? item_head: item_cur; \
+ item_cur && (item_cur != &item_nil); item_cur = item_cur->next)
+
+/* generic key handlers */
+int on_key_esc(WINDOW *win);
+int on_key_resize(void);
+
+void init_dialog(const char *backtitle);
+void reset_dialog(void);
void end_dialog(void);
void attr_clear(WINDOW * win, int height, int width, chtype attr);
void dialog_clear(void);
-void color_setup(void);
void print_autowrap(WINDOW * win, const char *prompt, int width, int y, int x);
void print_button(WINDOW * win, const char *label, int y, int x, int selected);
void print_title(WINDOW *dialog, const char *title, int width);
@@ -155,12 +203,10 @@ int dialog_yesno(const char *title, const char *prompt, int height, int width);
int dialog_msgbox(const char *title, const char *prompt, int height,
int width, int pause);
int dialog_textbox(const char *title, const char *file, int height, int width);
-int dialog_menu(const char *title, const char *prompt, int height, int width,
- int menu_height, const char *choice, int item_no,
- const char *const *items);
+int dialog_menu(const char *title, const char *prompt,
+ const void *selected, int *s_scroll);
int dialog_checklist(const char *title, const char *prompt, int height,
- int width, int list_height, int item_no,
- const char *const *items);
+ int width, int list_height);
extern char dialog_input_result[];
int dialog_inputbox(const char *title, const char *prompt, int height,
int width, const char *init);
diff --git a/scripts/kconfig/lxdialog/inputbox.c b/scripts/kconfig/lxdialog/inputbox.c
index 779503726b0a..05e72066b359 100644
--- a/scripts/kconfig/lxdialog/inputbox.c
+++ b/scripts/kconfig/lxdialog/inputbox.c
@@ -49,6 +49,17 @@ int dialog_inputbox(const char *title, const char *prompt, int height, int width
char *instr = dialog_input_result;
WINDOW *dialog;
+ if (!init)
+ instr[0] = '\0';
+ else
+ strcpy(instr, init);
+
+do_resize:
+ if (getmaxy(stdscr) <= (height - 2))
+ return -ERRDISPLAYTOOSMALL;
+ if (getmaxx(stdscr) <= (width - 2))
+ return -ERRDISPLAYTOOSMALL;
+
/* center dialog box on screen */
x = (COLS - width) / 2;
y = (LINES - height) / 2;
@@ -58,17 +69,18 @@ int dialog_inputbox(const char *title, const char *prompt, int height, int width
dialog = newwin(height, width, y, x);
keypad(dialog, TRUE);
- draw_box(dialog, 0, 0, height, width, dialog_attr, border_attr);
- wattrset(dialog, border_attr);
+ draw_box(dialog, 0, 0, height, width,
+ dlg.dialog.atr, dlg.border.atr);
+ wattrset(dialog, dlg.border.atr);
mvwaddch(dialog, height - 3, 0, ACS_LTEE);
for (i = 0; i < width - 2; i++)
waddch(dialog, ACS_HLINE);
- wattrset(dialog, dialog_attr);
+ wattrset(dialog, dlg.dialog.atr);
waddch(dialog, ACS_RTEE);
print_title(dialog, title, width);
- wattrset(dialog, dialog_attr);
+ wattrset(dialog, dlg.dialog.atr);
print_autowrap(dialog, prompt, width - 2, 1, 3);
/* Draw the input field box */
@@ -76,18 +88,14 @@ int dialog_inputbox(const char *title, const char *prompt, int height, int width
getyx(dialog, y, x);
box_y = y + 2;
box_x = (width - box_width) / 2;
- draw_box(dialog, y + 1, box_x - 1, 3, box_width + 2, border_attr, dialog_attr);
+ draw_box(dialog, y + 1, box_x - 1, 3, box_width + 2,
+ dlg.border.atr, dlg.dialog.atr);
print_buttons(dialog, height, width, 0);
/* Set up the initial value */
wmove(dialog, box_y, box_x);
- wattrset(dialog, inputbox_attr);
-
- if (!init)
- instr[0] = '\0';
- else
- strcpy(instr, init);
+ wattrset(dialog, dlg.inputbox.atr);
input_x = strlen(instr);
@@ -104,7 +112,7 @@ int dialog_inputbox(const char *title, const char *prompt, int height, int width
wrefresh(dialog);
- while (key != ESC) {
+ while (key != KEY_ESC) {
key = wgetch(dialog);
if (button == -1) { /* Input box selected */
@@ -120,7 +128,7 @@ int dialog_inputbox(const char *title, const char *prompt, int height, int width
case KEY_BACKSPACE:
case 127:
if (input_x || scroll) {
- wattrset(dialog, inputbox_attr);
+ wattrset(dialog, dlg.inputbox.atr);
if (!input_x) {
scroll = scroll < box_width - 1 ? 0 : scroll - (box_width - 1);
wmove(dialog, box_y, box_x);
@@ -140,7 +148,7 @@ int dialog_inputbox(const char *title, const char *prompt, int height, int width
default:
if (key < 0x100 && isprint(key)) {
if (scroll + input_x < MAX_LEN) {
- wattrset(dialog, inputbox_attr);
+ wattrset(dialog, dlg.inputbox.atr);
instr[scroll + input_x] = key;
instr[scroll + input_x + 1] = '\0';
if (input_x == box_width - 1) {
@@ -213,12 +221,18 @@ int dialog_inputbox(const char *title, const char *prompt, int height, int width
return (button == -1 ? 0 : button);
case 'X':
case 'x':
- key = ESC;
- case ESC:
+ key = KEY_ESC;
+ break;
+ case KEY_ESC:
+ key = on_key_esc(dialog);
break;
+ case KEY_RESIZE:
+ delwin(dialog);
+ on_key_resize();
+ goto do_resize;
}
}
delwin(dialog);
- return -1; /* ESC pressed */
+ return KEY_ESC; /* ESC pressed */
}
diff --git a/scripts/kconfig/lxdialog/lxdialog.c b/scripts/kconfig/lxdialog/lxdialog.c
deleted file mode 100644
index 79f6c5fb5cef..000000000000
--- a/scripts/kconfig/lxdialog/lxdialog.c
+++ /dev/null
@@ -1,204 +0,0 @@
-/*
- * dialog - Display simple dialog boxes from shell scripts
- *
- * ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
- * MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcap@cfw.com)
- *
- * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include "dialog.h"
-
-static void Usage(const char *name);
-
-typedef int (jumperFn) (const char *title, int argc, const char *const *argv);
-
-struct Mode {
- char *name;
- int argmin, argmax, argmod;
- jumperFn *jumper;
-};
-
-jumperFn j_menu, j_radiolist, j_yesno, j_textbox, j_inputbox;
-jumperFn j_msgbox, j_infobox;
-
-static struct Mode modes[] = {
- {"--menu", 9, 0, 3, j_menu},
- {"--radiolist", 9, 0, 3, j_radiolist},
- {"--yesno", 5, 5, 1, j_yesno},
- {"--textbox", 5, 5, 1, j_textbox},
- {"--inputbox", 5, 6, 1, j_inputbox},
- {"--msgbox", 5, 5, 1, j_msgbox},
- {"--infobox", 5, 5, 1, j_infobox},
- {NULL, 0, 0, 0, NULL}
-};
-
-static struct Mode *modePtr;
-
-#ifdef LOCALE
-#include <locale.h>
-#endif
-
-int main(int argc, const char *const *argv)
-{
- int offset = 0, opt_clear = 0, end_common_opts = 0, retval;
- const char *title = NULL;
-
-#ifdef LOCALE
- (void)setlocale(LC_ALL, "");
-#endif
-
-#ifdef TRACE
- trace(TRACE_CALLS | TRACE_UPDATE);
-#endif
- if (argc < 2) {
- Usage(argv[0]);
- exit(-1);
- }
-
- while (offset < argc - 1 && !end_common_opts) { /* Common options */
- if (!strcmp(argv[offset + 1], "--title")) {
- if (argc - offset < 3 || title != NULL) {
- Usage(argv[0]);
- exit(-1);
- } else {
- title = argv[offset + 2];
- offset += 2;
- }
- } else if (!strcmp(argv[offset + 1], "--backtitle")) {
- if (backtitle != NULL) {
- Usage(argv[0]);
- exit(-1);
- } else {
- backtitle = argv[offset + 2];
- offset += 2;
- }
- } else if (!strcmp(argv[offset + 1], "--clear")) {
- if (opt_clear) { /* Hey, "--clear" can't appear twice! */
- Usage(argv[0]);
- exit(-1);
- } else if (argc == 2) { /* we only want to clear the screen */
- init_dialog();
- refresh(); /* init_dialog() will clear the screen for us */
- end_dialog();
- return 0;
- } else {
- opt_clear = 1;
- offset++;
- }
- } else /* no more common options */
- end_common_opts = 1;
- }
-
- if (argc - 1 == offset) { /* no more options */
- Usage(argv[0]);
- exit(-1);
- }
- /* use a table to look for the requested mode, to avoid code duplication */
-
- for (modePtr = modes; modePtr->name; modePtr++) /* look for the mode */
- if (!strcmp(argv[offset + 1], modePtr->name))
- break;
-
- if (!modePtr->name)
- Usage(argv[0]);
- if (argc - offset < modePtr->argmin)
- Usage(argv[0]);
- if (modePtr->argmax && argc - offset > modePtr->argmax)
- Usage(argv[0]);
-
- init_dialog();
- retval = (*(modePtr->jumper)) (title, argc - offset, argv + offset);
-
- if (opt_clear) { /* clear screen before exit */
- attr_clear(stdscr, LINES, COLS, screen_attr);
- refresh();
- }
- end_dialog();
-
- exit(retval);
-}
-
-/*
- * Print program usage
- */
-static void Usage(const char *name)
-{
- fprintf(stderr, "\
-\ndialog, by Savio Lam (lam836@cs.cuhk.hk).\
-\n patched by Stuart Herbert (S.Herbert@shef.ac.uk)\
-\n modified/gutted for use as a Linux kernel config tool by \
-\n William Roadcap (roadcapw@cfw.com)\
-\n\
-\n* Display dialog boxes from shell scripts *\
-\n\
-\nUsage: %s --clear\
-\n %s [--title <title>] [--backtitle <backtitle>] --clear <Box options>\
-\n\
-\nBox options:\
-\n\
-\n --menu <text> <height> <width> <menu height> <tag1> <item1>...\
-\n --radiolist <text> <height> <width> <list height> <tag1> <item1> <status1>...\
-\n --textbox <file> <height> <width>\
-\n --inputbox <text> <height> <width> [<init>]\
-\n --yesno <text> <height> <width>\
-\n", name, name);
- exit(-1);
-}
-
-/*
- * These are the program jumpers
- */
-
-int j_menu(const char *t, int ac, const char *const *av)
-{
- return dialog_menu(t, av[2], atoi(av[3]), atoi(av[4]),
- atoi(av[5]), av[6], (ac - 6) / 2, av + 7);
-}
-
-int j_radiolist(const char *t, int ac, const char *const *av)
-{
- return dialog_checklist(t, av[2], atoi(av[3]), atoi(av[4]),
- atoi(av[5]), (ac - 6) / 3, av + 6);
-}
-
-int j_textbox(const char *t, int ac, const char *const *av)
-{
- return dialog_textbox(t, av[2], atoi(av[3]), atoi(av[4]));
-}
-
-int j_yesno(const char *t, int ac, const char *const *av)
-{
- return dialog_yesno(t, av[2], atoi(av[3]), atoi(av[4]));
-}
-
-int j_inputbox(const char *t, int ac, const char *const *av)
-{
- int ret = dialog_inputbox(t, av[2], atoi(av[3]), atoi(av[4]),
- ac == 6 ? av[5] : (char *)NULL);
- if (ret == 0)
- fprintf(stderr, dialog_input_result);
- return ret;
-}
-
-int j_msgbox(const char *t, int ac, const char *const *av)
-{
- return dialog_msgbox(t, av[2], atoi(av[3]), atoi(av[4]), 1);
-}
-
-int j_infobox(const char *t, int ac, const char *const *av)
-{
- return dialog_msgbox(t, av[2], atoi(av[3]), atoi(av[4]), 0);
-}
diff --git a/scripts/kconfig/lxdialog/menubox.c b/scripts/kconfig/lxdialog/menubox.c
index bf8052f4fd4a..0d83159d9012 100644
--- a/scripts/kconfig/lxdialog/menubox.c
+++ b/scripts/kconfig/lxdialog/menubox.c
@@ -63,19 +63,19 @@ static int menu_width, item_x;
/*
* Print menu item
*/
-static void do_print_item(WINDOW * win, const char *item, int choice,
+static void do_print_item(WINDOW * win, const char *item, int line_y,
int selected, int hotkey)
{
int j;
char *menu_item = malloc(menu_width + 1);
strncpy(menu_item, item, menu_width - item_x);
- menu_item[menu_width] = 0;
+ menu_item[menu_width - item_x] = '\0';
j = first_alpha(menu_item, "YyNnMmHh");
/* Clear 'residue' of last item */
- wattrset(win, menubox_attr);
- wmove(win, choice, 0);
+ wattrset(win, dlg.menubox.atr);
+ wmove(win, line_y, 0);
#if OLD_NCURSES
{
int i;
@@ -85,23 +85,24 @@ static void do_print_item(WINDOW * win, const char *item, int choice,
#else
wclrtoeol(win);
#endif
- wattrset(win, selected ? item_selected_attr : item_attr);
- mvwaddstr(win, choice, item_x, menu_item);
+ wattrset(win, selected ? dlg.item_selected.atr : dlg.item.atr);
+ mvwaddstr(win, line_y, item_x, menu_item);
if (hotkey) {
- wattrset(win, selected ? tag_key_selected_attr : tag_key_attr);
- mvwaddch(win, choice, item_x + j, menu_item[j]);
+ wattrset(win, selected ? dlg.tag_key_selected.atr
+ : dlg.tag_key.atr);
+ mvwaddch(win, line_y, item_x + j, menu_item[j]);
}
if (selected) {
- wmove(win, choice, item_x + 1);
+ wmove(win, line_y, item_x + 1);
}
free(menu_item);
wrefresh(win);
}
-#define print_item(index, choice, selected) \
-do {\
- int hotkey = (items[(index) * 2][0] != ':'); \
- do_print_item(menu, items[(index) * 2 + 1], choice, selected, hotkey); \
+#define print_item(index, choice, selected) \
+do { \
+ item_set(index); \
+ do_print_item(menu, item_str(), choice, selected, !item_is_tag(':')); \
} while (0)
/*
@@ -117,11 +118,11 @@ static void print_arrows(WINDOW * win, int item_no, int scroll, int y, int x,
wmove(win, y, x);
if (scroll > 0) {
- wattrset(win, uarrow_attr);
+ wattrset(win, dlg.uarrow.atr);
waddch(win, ACS_UARROW);
waddstr(win, "(-)");
} else {
- wattrset(win, menubox_attr);
+ wattrset(win, dlg.menubox.atr);
waddch(win, ACS_HLINE);
waddch(win, ACS_HLINE);
waddch(win, ACS_HLINE);
@@ -133,11 +134,11 @@ static void print_arrows(WINDOW * win, int item_no, int scroll, int y, int x,
wrefresh(win);
if ((height < item_no) && (scroll + height < item_no)) {
- wattrset(win, darrow_attr);
+ wattrset(win, dlg.darrow.atr);
waddch(win, ACS_DARROW);
waddstr(win, "(+)");
} else {
- wattrset(win, menubox_border_attr);
+ wattrset(win, dlg.menubox_border.atr);
waddch(win, ACS_HLINE);
waddch(win, ACS_HLINE);
waddch(win, ACS_HLINE);
@@ -178,17 +179,26 @@ static void do_scroll(WINDOW *win, int *scroll, int n)
/*
* Display a menu for choosing among a number of options
*/
-int dialog_menu(const char *title, const char *prompt, int height, int width,
- int menu_height, const char *current, int item_no,
- const char *const *items)
+int dialog_menu(const char *title, const char *prompt,
+ const void *selected, int *s_scroll)
{
int i, j, x, y, box_x, box_y;
+ int height, width, menu_height;
int key = 0, button = 0, scroll = 0, choice = 0;
int first_item = 0, max_choice;
WINDOW *dialog, *menu;
- FILE *f;
- max_choice = MIN(menu_height, item_no);
+do_resize:
+ height = getmaxy(stdscr);
+ width = getmaxx(stdscr);
+ if (height < 15 || width < 65)
+ return -ERRDISPLAYTOOSMALL;
+
+ height -= 4;
+ width -= 5;
+ menu_height = height - 10;
+
+ max_choice = MIN(menu_height, item_count());
/* center dialog box on screen */
x = (COLS - width) / 2;
@@ -199,18 +209,19 @@ int dialog_menu(const char *title, const char *prompt, int height, int width,
dialog = newwin(height, width, y, x);
keypad(dialog, TRUE);
- draw_box(dialog, 0, 0, height, width, dialog_attr, border_attr);
- wattrset(dialog, border_attr);
+ draw_box(dialog, 0, 0, height, width,
+ dlg.dialog.atr, dlg.border.atr);
+ wattrset(dialog, dlg.border.atr);
mvwaddch(dialog, height - 3, 0, ACS_LTEE);
for (i = 0; i < width - 2; i++)
waddch(dialog, ACS_HLINE);
- wattrset(dialog, dialog_attr);
- wbkgdset(dialog, dialog_attr & A_COLOR);
+ wattrset(dialog, dlg.dialog.atr);
+ wbkgdset(dialog, dlg.dialog.atr & A_COLOR);
waddch(dialog, ACS_RTEE);
print_title(dialog, title, width);
- wattrset(dialog, dialog_attr);
+ wattrset(dialog, dlg.dialog.atr);
print_autowrap(dialog, prompt, width - 2, 1, 3);
menu_width = width - 6;
@@ -224,33 +235,29 @@ int dialog_menu(const char *title, const char *prompt, int height, int width,
/* draw a box around the menu items */
draw_box(dialog, box_y, box_x, menu_height + 2, menu_width + 2,
- menubox_border_attr, menubox_attr);
+ dlg.menubox_border.atr, dlg.menubox.atr);
- item_x = (menu_width - 70) / 2;
+ if (menu_width >= 80)
+ item_x = (menu_width - 70) / 2;
+ else
+ item_x = 4;
/* Set choice to default item */
- for (i = 0; i < item_no; i++)
- if (strcmp(current, items[i * 2]) == 0)
- choice = i;
-
- /* get the scroll info from the temp file */
- if ((f = fopen("lxdialog.scrltmp", "r")) != NULL) {
- if ((fscanf(f, "%d\n", &scroll) == 1) && (scroll <= choice) &&
- (scroll + max_choice > choice) && (scroll >= 0) &&
- (scroll + max_choice <= item_no)) {
- first_item = scroll;
- choice = choice - scroll;
- fclose(f);
- } else {
- scroll = 0;
- remove("lxdialog.scrltmp");
- fclose(f);
- f = NULL;
- }
+ item_foreach()
+ if (selected && (selected == item_data()))
+ choice = item_n();
+ /* get the saved scroll info */
+ scroll = *s_scroll;
+ if ((scroll <= choice) && (scroll + max_choice > choice) &&
+ (scroll >= 0) && (scroll + max_choice <= item_count())) {
+ first_item = scroll;
+ choice = choice - scroll;
+ } else {
+ scroll = 0;
}
- if ((choice >= max_choice) || (f == NULL && choice >= max_choice / 2)) {
- if (choice >= item_no - max_choice / 2)
- scroll = first_item = item_no - max_choice;
+ if ((choice >= max_choice)) {
+ if (choice >= item_count() - max_choice / 2)
+ scroll = first_item = item_count() - max_choice;
else
scroll = first_item = choice - max_choice / 2;
choice = choice - scroll;
@@ -263,14 +270,14 @@ int dialog_menu(const char *title, const char *prompt, int height, int width,
wnoutrefresh(menu);
- print_arrows(dialog, item_no, scroll,
+ print_arrows(dialog, item_count(), scroll,
box_y, box_x + item_x + 1, menu_height);
print_buttons(dialog, height, width, 0);
wmove(menu, choice, item_x + 1);
wrefresh(menu);
- while (key != ESC) {
+ while (key != KEY_ESC) {
key = wgetch(menu);
if (key < 256 && isalpha(key))
@@ -280,14 +287,16 @@ int dialog_menu(const char *title, const char *prompt, int height, int width,
i = max_choice;
else {
for (i = choice + 1; i < max_choice; i++) {
- j = first_alpha(items[(scroll + i) * 2 + 1], "YyNnMmHh");
- if (key == tolower(items[(scroll + i) * 2 + 1][j]))
+ item_set(scroll + i);
+ j = first_alpha(item_str(), "YyNnMmHh");
+ if (key == tolower(item_str()[j]))
break;
}
if (i == max_choice)
for (i = 0; i < max_choice; i++) {
- j = first_alpha(items [(scroll + i) * 2 + 1], "YyNnMmHh");
- if (key == tolower(items[(scroll + i) * 2 + 1][j]))
+ item_set(scroll + i);
+ j = first_alpha(item_str(), "YyNnMmHh");
+ if (key == tolower(item_str()[j]))
break;
}
}
@@ -312,7 +321,7 @@ int dialog_menu(const char *title, const char *prompt, int height, int width,
print_item(scroll+choice, choice, FALSE);
if ((choice > max_choice - 3) &&
- (scroll + max_choice < item_no)) {
+ (scroll + max_choice < item_count())) {
/* Scroll menu up */
do_scroll(menu, &scroll, 1);
@@ -335,7 +344,7 @@ int dialog_menu(const char *title, const char *prompt, int height, int width,
} else if (key == KEY_NPAGE) {
for (i = 0; (i < max_choice); i++) {
- if (scroll + max_choice < item_no) {
+ if (scroll + max_choice < item_count()) {
do_scroll(menu, &scroll, 1);
print_item(scroll+max_choice-1,
max_choice - 1, FALSE);
@@ -349,7 +358,7 @@ int dialog_menu(const char *title, const char *prompt, int height, int width,
print_item(scroll + choice, choice, TRUE);
- print_arrows(dialog, item_no, scroll,
+ print_arrows(dialog, item_count(), scroll,
box_y, box_x + item_x + 1, menu_height);
wnoutrefresh(dialog);
@@ -375,12 +384,11 @@ int dialog_menu(const char *title, const char *prompt, int height, int width,
case 'm':
case '/':
/* save scroll info */
- if ((f = fopen("lxdialog.scrltmp", "w")) != NULL) {
- fprintf(f, "%d\n", scroll);
- fclose(f);
- }
+ *s_scroll = scroll;
+ delwin(menu);
delwin(dialog);
- fprintf(stderr, "%s\n", items[(scroll + choice) * 2]);
+ item_set(scroll + choice);
+ item_set_selected(1);
switch (key) {
case 's':
return 3;
@@ -400,27 +408,27 @@ int dialog_menu(const char *title, const char *prompt, int height, int width,
case '?':
button = 2;
case '\n':
+ *s_scroll = scroll;
+ delwin(menu);
delwin(dialog);
- if (button == 2)
- fprintf(stderr, "%s \"%s\"\n",
- items[(scroll + choice) * 2],
- items[(scroll + choice) * 2 + 1] +
- first_alpha(items [(scroll + choice) * 2 + 1], ""));
- else
- fprintf(stderr, "%s\n",
- items[(scroll + choice) * 2]);
-
- remove("lxdialog.scrltmp");
+ item_set(scroll + choice);
+ item_set_selected(1);
return button;
case 'e':
case 'x':
- key = ESC;
- case ESC:
+ key = KEY_ESC;
+ break;
+ case KEY_ESC:
+ key = on_key_esc(menu);
break;
+ case KEY_RESIZE:
+ on_key_resize();
+ delwin(menu);
+ delwin(dialog);
+ goto do_resize;
}
}
-
+ delwin(menu);
delwin(dialog);
- remove("lxdialog.scrltmp");
- return -1; /* ESC pressed */
+ return key; /* ESC pressed */
}
diff --git a/scripts/kconfig/lxdialog/msgbox.c b/scripts/kconfig/lxdialog/msgbox.c
deleted file mode 100644
index 7323f5471f69..000000000000
--- a/scripts/kconfig/lxdialog/msgbox.c
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * msgbox.c -- implements the message box and info box
- *
- * ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
- * MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcapw@cfw.com)
- *
- * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include "dialog.h"
-
-/*
- * Display a message box. Program will pause and display an "OK" button
- * if the parameter 'pause' is non-zero.
- */
-int dialog_msgbox(const char *title, const char *prompt, int height, int width,
- int pause)
-{
- int i, x, y, key = 0;
- WINDOW *dialog;
-
- /* center dialog box on screen */
- x = (COLS - width) / 2;
- y = (LINES - height) / 2;
-
- draw_shadow(stdscr, y, x, height, width);
-
- dialog = newwin(height, width, y, x);
- keypad(dialog, TRUE);
-
- draw_box(dialog, 0, 0, height, width, dialog_attr, border_attr);
-
- print_title(dialog, title, width);
-
- wattrset(dialog, dialog_attr);
- print_autowrap(dialog, prompt, width - 2, 1, 2);
-
- if (pause) {
- wattrset(dialog, border_attr);
- mvwaddch(dialog, height - 3, 0, ACS_LTEE);
- for (i = 0; i < width - 2; i++)
- waddch(dialog, ACS_HLINE);
- wattrset(dialog, dialog_attr);
- waddch(dialog, ACS_RTEE);
-
- print_button(dialog, " Ok ", height - 2, width / 2 - 4, TRUE);
-
- wrefresh(dialog);
- while (key != ESC && key != '\n' && key != ' ' &&
- key != 'O' && key != 'o' && key != 'X' && key != 'x')
- key = wgetch(dialog);
- } else {
- key = '\n';
- wrefresh(dialog);
- }
-
- delwin(dialog);
- return key == ESC ? -1 : 0;
-}
diff --git a/scripts/kconfig/lxdialog/textbox.c b/scripts/kconfig/lxdialog/textbox.c
index 77848bb8e07f..fabfc1ad789d 100644
--- a/scripts/kconfig/lxdialog/textbox.c
+++ b/scripts/kconfig/lxdialog/textbox.c
@@ -25,56 +25,62 @@ static void back_lines(int n);
static void print_page(WINDOW * win, int height, int width);
static void print_line(WINDOW * win, int row, int width);
static char *get_line(void);
-static void print_position(WINDOW * win, int height, int width);
+static void print_position(WINDOW * win);
+
+static int hscroll;
+static int begin_reached, end_reached, page_length;
+static const char *buf;
+static const char *page;
+
+/*
+ * refresh window content
+ */
+static void refresh_text_box(WINDOW *dialog, WINDOW *box, int boxh, int boxw,
+ int cur_y, int cur_x)
+{
+ print_page(box, boxh, boxw);
+ print_position(dialog);
+ wmove(dialog, cur_y, cur_x); /* Restore cursor position */
+ wrefresh(dialog);
+}
-static int hscroll, fd, file_size, bytes_read;
-static int begin_reached = 1, end_reached, page_length;
-static char *buf, *page;
/*
* Display text from a file in a dialog box.
*/
-int dialog_textbox(const char *title, const char *file, int height, int width)
+int dialog_textbox(const char *title, const char *tbuf,
+ int initial_height, int initial_width)
{
- int i, x, y, cur_x, cur_y, fpos, key = 0;
+ int i, x, y, cur_x, cur_y, key = 0;
+ int height, width, boxh, boxw;
int passed_end;
- char search_term[MAX_LEN + 1];
- WINDOW *dialog, *text;
-
- search_term[0] = '\0'; /* no search term entered yet */
+ WINDOW *dialog, *box;
- /* Open input file for reading */
- if ((fd = open(file, O_RDONLY)) == -1) {
- endwin();
- fprintf(stderr, "\nCan't open input file in dialog_textbox().\n");
- exit(-1);
- }
- /* Get file size. Actually, 'file_size' is the real file size - 1,
- since it's only the last byte offset from the beginning */
- if ((file_size = lseek(fd, 0, SEEK_END)) == -1) {
- endwin();
- fprintf(stderr, "\nError getting file size in dialog_textbox().\n");
- exit(-1);
- }
- /* Restore file pointer to beginning of file after getting file size */
- if (lseek(fd, 0, SEEK_SET) == -1) {
- endwin();
- fprintf(stderr, "\nError moving file pointer in dialog_textbox().\n");
- exit(-1);
- }
- /* Allocate space for read buffer */
- if ((buf = malloc(BUF_SIZE + 1)) == NULL) {
- endwin();
- fprintf(stderr, "\nCan't allocate memory in dialog_textbox().\n");
- exit(-1);
- }
- if ((bytes_read = read(fd, buf, BUF_SIZE)) == -1) {
- endwin();
- fprintf(stderr, "\nError reading file in dialog_textbox().\n");
- exit(-1);
- }
- buf[bytes_read] = '\0'; /* mark end of valid data */
- page = buf; /* page is pointer to start of page to be displayed */
+ begin_reached = 1;
+ end_reached = 0;
+ page_length = 0;
+ hscroll = 0;
+ buf = tbuf;
+ page = buf; /* page is pointer to start of page to be displayed */
+
+do_resize:
+ getmaxyx(stdscr, height, width);
+ if (height < 8 || width < 8)
+ return -ERRDISPLAYTOOSMALL;
+ if (initial_height != 0)
+ height = initial_height;
+ else
+ if (height > 4)
+ height -= 4;
+ else
+ height = 0;
+ if (initial_width != 0)
+ width = initial_width;
+ else
+ if (width > 5)
+ width -= 5;
+ else
+ width = 0;
/* center dialog box on screen */
x = (COLS - width) / 2;
@@ -85,22 +91,25 @@ int dialog_textbox(const char *title, const char *file, int height, int width)
dialog = newwin(height, width, y, x);
keypad(dialog, TRUE);
- /* Create window for text region, used for scrolling text */
- text = subwin(dialog, height - 4, width - 2, y + 1, x + 1);
- wattrset(text, dialog_attr);
- wbkgdset(text, dialog_attr & A_COLOR);
+ /* Create window for box region, used for scrolling text */
+ boxh = height - 4;
+ boxw = width - 2;
+ box = subwin(dialog, boxh, boxw, y + 1, x + 1);
+ wattrset(box, dlg.dialog.atr);
+ wbkgdset(box, dlg.dialog.atr & A_COLOR);
- keypad(text, TRUE);
+ keypad(box, TRUE);
/* register the new window, along with its borders */
- draw_box(dialog, 0, 0, height, width, dialog_attr, border_attr);
+ draw_box(dialog, 0, 0, height, width,
+ dlg.dialog.atr, dlg.border.atr);
- wattrset(dialog, border_attr);
+ wattrset(dialog, dlg.border.atr);
mvwaddch(dialog, height - 3, 0, ACS_LTEE);
for (i = 0; i < width - 2; i++)
waddch(dialog, ACS_HLINE);
- wattrset(dialog, dialog_attr);
- wbkgdset(dialog, dialog_attr & A_COLOR);
+ wattrset(dialog, dlg.dialog.atr);
+ wbkgdset(dialog, dlg.dialog.atr & A_COLOR);
waddch(dialog, ACS_RTEE);
print_title(dialog, title, width);
@@ -110,85 +119,37 @@ int dialog_textbox(const char *title, const char *file, int height, int width)
getyx(dialog, cur_y, cur_x); /* Save cursor position */
/* Print first page of text */
- attr_clear(text, height - 4, width - 2, dialog_attr);
- print_page(text, height - 4, width - 2);
- print_position(dialog, height, width);
- wmove(dialog, cur_y, cur_x); /* Restore cursor position */
- wrefresh(dialog);
+ attr_clear(box, boxh, boxw, dlg.dialog.atr);
+ refresh_text_box(dialog, box, boxh, boxw, cur_y, cur_x);
- while ((key != ESC) && (key != '\n')) {
+ while ((key != KEY_ESC) && (key != '\n')) {
key = wgetch(dialog);
switch (key) {
case 'E': /* Exit */
case 'e':
case 'X':
case 'x':
+ delwin(box);
delwin(dialog);
- free(buf);
- close(fd);
return 0;
case 'g': /* First page */
case KEY_HOME:
if (!begin_reached) {
begin_reached = 1;
- /* First page not in buffer? */
- if ((fpos = lseek(fd, 0, SEEK_CUR)) == -1) {
- endwin();
- fprintf(stderr, "\nError moving file pointer in dialog_textbox().\n");
- exit(-1);
- }
- if (fpos > bytes_read) { /* Yes, we have to read it in */
- if (lseek(fd, 0, SEEK_SET) == -1) {
- endwin();
- fprintf(stderr, "\nError moving file pointer in "
- "dialog_textbox().\n");
- exit(-1);
- }
- if ((bytes_read =
- read(fd, buf, BUF_SIZE)) == -1) {
- endwin();
- fprintf(stderr, "\nError reading file in dialog_textbox().\n");
- exit(-1);
- }
- buf[bytes_read] = '\0';
- }
page = buf;
- print_page(text, height - 4, width - 2);
- print_position(dialog, height, width);
- wmove(dialog, cur_y, cur_x); /* Restore cursor position */
- wrefresh(dialog);
+ refresh_text_box(dialog, box, boxh, boxw,
+ cur_y, cur_x);
}
break;
case 'G': /* Last page */
case KEY_END:
end_reached = 1;
- /* Last page not in buffer? */
- if ((fpos = lseek(fd, 0, SEEK_CUR)) == -1) {
- endwin();
- fprintf(stderr, "\nError moving file pointer in dialog_textbox().\n");
- exit(-1);
- }
- if (fpos < file_size) { /* Yes, we have to read it in */
- if (lseek(fd, -BUF_SIZE, SEEK_END) == -1) {
- endwin();
- fprintf(stderr, "\nError moving file pointer in dialog_textbox().\n");
- exit(-1);
- }
- if ((bytes_read =
- read(fd, buf, BUF_SIZE)) == -1) {
- endwin();
- fprintf(stderr, "\nError reading file in dialog_textbox().\n");
- exit(-1);
- }
- buf[bytes_read] = '\0';
- }
- page = buf + bytes_read;
- back_lines(height - 4);
- print_page(text, height - 4, width - 2);
- print_position(dialog, height, width);
- wmove(dialog, cur_y, cur_x); /* Restore cursor position */
- wrefresh(dialog);
+ /* point to last char in buf */
+ page = buf + strlen(buf);
+ back_lines(boxh);
+ refresh_text_box(dialog, box, boxh, boxw,
+ cur_y, cur_x);
break;
case 'K': /* Previous line */
case 'k':
@@ -196,21 +157,23 @@ int dialog_textbox(const char *title, const char *file, int height, int width)
if (!begin_reached) {
back_lines(page_length + 1);
- /* We don't call print_page() here but use scrolling to ensure
- faster screen update. However, 'end_reached' and
- 'page_length' should still be updated, and 'page' should
- point to start of next page. This is done by calling
- get_line() in the following 'for' loop. */
- scrollok(text, TRUE);
- wscrl(text, -1); /* Scroll text region down one line */
- scrollok(text, FALSE);
+ /* We don't call print_page() here but use
+ * scrolling to ensure faster screen update.
+ * However, 'end_reached' and 'page_length'
+ * should still be updated, and 'page' should
+ * point to start of next page. This is done
+ * by calling get_line() in the following
+ * 'for' loop. */
+ scrollok(box, TRUE);
+ wscrl(box, -1); /* Scroll box region down one line */
+ scrollok(box, FALSE);
page_length = 0;
passed_end = 0;
- for (i = 0; i < height - 4; i++) {
+ for (i = 0; i < boxh; i++) {
if (!i) {
/* print first line of page */
- print_line(text, 0, width - 2);
- wnoutrefresh(text);
+ print_line(box, 0, boxw);
+ wnoutrefresh(box);
} else
/* Called to update 'end_reached' and 'page' */
get_line();
@@ -220,7 +183,7 @@ int dialog_textbox(const char *title, const char *file, int height, int width)
passed_end = 1;
}
- print_position(dialog, height, width);
+ print_position(dialog);
wmove(dialog, cur_y, cur_x); /* Restore cursor position */
wrefresh(dialog);
}
@@ -230,23 +193,21 @@ int dialog_textbox(const char *title, const char *file, int height, int width)
case KEY_PPAGE:
if (begin_reached)
break;
- back_lines(page_length + height - 4);
- print_page(text, height - 4, width - 2);
- print_position(dialog, height, width);
- wmove(dialog, cur_y, cur_x);
- wrefresh(dialog);
+ back_lines(page_length + boxh);
+ refresh_text_box(dialog, box, boxh, boxw,
+ cur_y, cur_x);
break;
case 'J': /* Next line */
case 'j':
case KEY_DOWN:
if (!end_reached) {
begin_reached = 0;
- scrollok(text, TRUE);
- scroll(text); /* Scroll text region up one line */
- scrollok(text, FALSE);
- print_line(text, height - 5, width - 2);
- wnoutrefresh(text);
- print_position(dialog, height, width);
+ scrollok(box, TRUE);
+ scroll(box); /* Scroll box region up one line */
+ scrollok(box, FALSE);
+ print_line(box, boxh - 1, boxw);
+ wnoutrefresh(box);
+ print_position(dialog);
wmove(dialog, cur_y, cur_x); /* Restore cursor position */
wrefresh(dialog);
}
@@ -257,10 +218,8 @@ int dialog_textbox(const char *title, const char *file, int height, int width)
break;
begin_reached = 0;
- print_page(text, height - 4, width - 2);
- print_position(dialog, height, width);
- wmove(dialog, cur_y, cur_x);
- wrefresh(dialog);
+ refresh_text_box(dialog, box, boxh, boxw,
+ cur_y, cur_x);
break;
case '0': /* Beginning of line */
case 'H': /* Scroll left */
@@ -275,9 +234,8 @@ int dialog_textbox(const char *title, const char *file, int height, int width)
hscroll--;
/* Reprint current page to scroll horizontally */
back_lines(page_length);
- print_page(text, height - 4, width - 2);
- wmove(dialog, cur_y, cur_x);
- wrefresh(dialog);
+ refresh_text_box(dialog, box, boxh, boxw,
+ cur_y, cur_x);
break;
case 'L': /* Scroll right */
case 'l':
@@ -287,131 +245,56 @@ int dialog_textbox(const char *title, const char *file, int height, int width)
hscroll++;
/* Reprint current page to scroll horizontally */
back_lines(page_length);
- print_page(text, height - 4, width - 2);
- wmove(dialog, cur_y, cur_x);
- wrefresh(dialog);
+ refresh_text_box(dialog, box, boxh, boxw,
+ cur_y, cur_x);
break;
- case ESC:
+ case KEY_ESC:
+ key = on_key_esc(dialog);
break;
+ case KEY_RESIZE:
+ back_lines(height);
+ delwin(box);
+ delwin(dialog);
+ on_key_resize();
+ goto do_resize;
}
}
-
+ delwin(box);
delwin(dialog);
- free(buf);
- close(fd);
- return -1; /* ESC pressed */
+ return key; /* ESC pressed */
}
/*
- * Go back 'n' lines in text file. Called by dialog_textbox().
+ * Go back 'n' lines in text. Called by dialog_textbox().
* 'page' will be updated to point to the desired line in 'buf'.
*/
static void back_lines(int n)
{
- int i, fpos;
+ int i;
begin_reached = 0;
- /* We have to distinguish between end_reached and !end_reached
- since at end of file, the line is not ended by a '\n'.
- The code inside 'if' basically does a '--page' to move one
- character backward so as to skip '\n' of the previous line */
- if (!end_reached) {
- /* Either beginning of buffer or beginning of file reached? */
- if (page == buf) {
- if ((fpos = lseek(fd, 0, SEEK_CUR)) == -1) {
- endwin();
- fprintf(stderr, "\nError moving file pointer in "
- "back_lines().\n");
- exit(-1);
- }
- if (fpos > bytes_read) { /* Not beginning of file yet */
- /* We've reached beginning of buffer, but not beginning of
- file yet, so read previous part of file into buffer.
- Note that we only move backward for BUF_SIZE/2 bytes,
- but not BUF_SIZE bytes to avoid re-reading again in
- print_page() later */
- /* Really possible to move backward BUF_SIZE/2 bytes? */
- if (fpos < BUF_SIZE / 2 + bytes_read) {
- /* No, move less then */
- if (lseek(fd, 0, SEEK_SET) == -1) {
- endwin();
- fprintf(stderr, "\nError moving file pointer in "
- "back_lines().\n");
- exit(-1);
- }
- page = buf + fpos - bytes_read;
- } else { /* Move backward BUF_SIZE/2 bytes */
- if (lseek (fd, -(BUF_SIZE / 2 + bytes_read), SEEK_CUR) == -1) {
- endwin();
- fprintf(stderr, "\nError moving file pointer "
- "in back_lines().\n");
- exit(-1);
- }
- page = buf + BUF_SIZE / 2;
- }
- if ((bytes_read =
- read(fd, buf, BUF_SIZE)) == -1) {
- endwin();
- fprintf(stderr, "\nError reading file in back_lines().\n");
- exit(-1);
- }
- buf[bytes_read] = '\0';
- } else { /* Beginning of file reached */
- begin_reached = 1;
- return;
+ /* Go back 'n' lines */
+ for (i = 0; i < n; i++) {
+ if (*page == '\0') {
+ if (end_reached) {
+ end_reached = 0;
+ continue;
}
}
- if (*(--page) != '\n') { /* '--page' here */
- /* Something's wrong... */
- endwin();
- fprintf(stderr, "\nInternal error in back_lines().\n");
- exit(-1);
+ if (page == buf) {
+ begin_reached = 1;
+ return;
}
- }
- /* Go back 'n' lines */
- for (i = 0; i < n; i++)
+ page--;
do {
if (page == buf) {
- if ((fpos = lseek(fd, 0, SEEK_CUR)) == -1) {
- endwin();
- fprintf(stderr, "\nError moving file pointer in back_lines().\n");
- exit(-1);
- }
- if (fpos > bytes_read) {
- /* Really possible to move backward BUF_SIZE/2 bytes? */
- if (fpos < BUF_SIZE / 2 + bytes_read) {
- /* No, move less then */
- if (lseek(fd, 0, SEEK_SET) == -1) {
- endwin();
- fprintf(stderr, "\nError moving file pointer "
- "in back_lines().\n");
- exit(-1);
- }
- page = buf + fpos - bytes_read;
- } else { /* Move backward BUF_SIZE/2 bytes */
- if (lseek (fd, -(BUF_SIZE / 2 + bytes_read), SEEK_CUR) == -1) {
- endwin();
- fprintf(stderr, "\nError moving file pointer"
- " in back_lines().\n");
- exit(-1);
- }
- page = buf + BUF_SIZE / 2;
- }
- if ((bytes_read =
- read(fd, buf, BUF_SIZE)) == -1) {
- endwin();
- fprintf(stderr, "\nError reading file in "
- "back_lines().\n");
- exit(-1);
- }
- buf[bytes_read] = '\0';
- } else { /* Beginning of file reached */
- begin_reached = 1;
- return;
- }
+ begin_reached = 1;
+ return;
}
- } while (*(--page) != '\n');
- page++;
+ page--;
+ } while (*page != '\n');
+ page++;
+ }
}
/*
@@ -466,33 +349,14 @@ static void print_line(WINDOW * win, int row, int width)
*/
static char *get_line(void)
{
- int i = 0, fpos;
+ int i = 0;
static char line[MAX_LEN + 1];
end_reached = 0;
while (*page != '\n') {
if (*page == '\0') {
- /* Either end of file or end of buffer reached */
- if ((fpos = lseek(fd, 0, SEEK_CUR)) == -1) {
- endwin();
- fprintf(stderr, "\nError moving file pointer in "
- "get_line().\n");
- exit(-1);
- }
- if (fpos < file_size) { /* Not end of file yet */
- /* We've reached end of buffer, but not end of file yet,
- so read next part of file into buffer */
- if ((bytes_read =
- read(fd, buf, BUF_SIZE)) == -1) {
- endwin();
- fprintf(stderr, "\nError reading file in get_line().\n");
- exit(-1);
- }
- buf[bytes_read] = '\0';
- page = buf;
- } else {
- if (!end_reached)
- end_reached = 1;
+ if (!end_reached) {
+ end_reached = 1;
break;
}
} else if (i < MAX_LEN)
@@ -515,19 +379,13 @@ static char *get_line(void)
/*
* Print current position
*/
-static void print_position(WINDOW * win, int height, int width)
+static void print_position(WINDOW * win)
{
- int fpos, percent;
+ int percent;
- if ((fpos = lseek(fd, 0, SEEK_CUR)) == -1) {
- endwin();
- fprintf(stderr, "\nError moving file pointer in print_position().\n");
- exit(-1);
- }
- wattrset(win, position_indicator_attr);
- wbkgdset(win, position_indicator_attr & A_COLOR);
- percent = !file_size ?
- 100 : ((fpos - bytes_read + page - buf) * 100) / file_size;
- wmove(win, height - 3, width - 9);
+ wattrset(win, dlg.position_indicator.atr);
+ wbkgdset(win, dlg.position_indicator.atr & A_COLOR);
+ percent = (page - buf) * 100 / strlen(buf);
+ wmove(win, getmaxy(win) - 3, getmaxx(win) - 9);
wprintw(win, "(%3d%%)", percent);
}
diff --git a/scripts/kconfig/lxdialog/util.c b/scripts/kconfig/lxdialog/util.c
index f82cebb9ff06..ebc781b493d7 100644
--- a/scripts/kconfig/lxdialog/util.c
+++ b/scripts/kconfig/lxdialog/util.c
@@ -21,85 +21,217 @@
#include "dialog.h"
-/* use colors by default? */
-bool use_colors = 1;
+struct dialog_info dlg;
-const char *backtitle = NULL;
+static void set_mono_theme(void)
+{
+ dlg.screen.atr = A_NORMAL;
+ dlg.shadow.atr = A_NORMAL;
+ dlg.dialog.atr = A_NORMAL;
+ dlg.title.atr = A_BOLD;
+ dlg.border.atr = A_NORMAL;
+ dlg.button_active.atr = A_REVERSE;
+ dlg.button_inactive.atr = A_DIM;
+ dlg.button_key_active.atr = A_REVERSE;
+ dlg.button_key_inactive.atr = A_BOLD;
+ dlg.button_label_active.atr = A_REVERSE;
+ dlg.button_label_inactive.atr = A_NORMAL;
+ dlg.inputbox.atr = A_NORMAL;
+ dlg.inputbox_border.atr = A_NORMAL;
+ dlg.searchbox.atr = A_NORMAL;
+ dlg.searchbox_title.atr = A_BOLD;
+ dlg.searchbox_border.atr = A_NORMAL;
+ dlg.position_indicator.atr = A_BOLD;
+ dlg.menubox.atr = A_NORMAL;
+ dlg.menubox_border.atr = A_NORMAL;
+ dlg.item.atr = A_NORMAL;
+ dlg.item_selected.atr = A_REVERSE;
+ dlg.tag.atr = A_BOLD;
+ dlg.tag_selected.atr = A_REVERSE;
+ dlg.tag_key.atr = A_BOLD;
+ dlg.tag_key_selected.atr = A_REVERSE;
+ dlg.check.atr = A_BOLD;
+ dlg.check_selected.atr = A_REVERSE;
+ dlg.uarrow.atr = A_BOLD;
+ dlg.darrow.atr = A_BOLD;
+}
+
+#define DLG_COLOR(dialog, f, b, h) \
+do { \
+ dlg.dialog.fg = (f); \
+ dlg.dialog.bg = (b); \
+ dlg.dialog.hl = (h); \
+} while (0)
+
+static void set_classic_theme(void)
+{
+ DLG_COLOR(screen, COLOR_CYAN, COLOR_BLUE, true);
+ DLG_COLOR(shadow, COLOR_BLACK, COLOR_BLACK, true);
+ DLG_COLOR(dialog, COLOR_BLACK, COLOR_WHITE, false);
+ DLG_COLOR(title, COLOR_YELLOW, COLOR_WHITE, true);
+ DLG_COLOR(border, COLOR_WHITE, COLOR_WHITE, true);
+ DLG_COLOR(button_active, COLOR_WHITE, COLOR_BLUE, true);
+ DLG_COLOR(button_inactive, COLOR_BLACK, COLOR_WHITE, false);
+ DLG_COLOR(button_key_active, COLOR_WHITE, COLOR_BLUE, true);
+ DLG_COLOR(button_key_inactive, COLOR_RED, COLOR_WHITE, false);
+ DLG_COLOR(button_label_active, COLOR_YELLOW, COLOR_BLUE, true);
+ DLG_COLOR(button_label_inactive, COLOR_BLACK, COLOR_WHITE, true);
+ DLG_COLOR(inputbox, COLOR_BLACK, COLOR_WHITE, false);
+ DLG_COLOR(inputbox_border, COLOR_BLACK, COLOR_WHITE, false);
+ DLG_COLOR(searchbox, COLOR_BLACK, COLOR_WHITE, false);
+ DLG_COLOR(searchbox_title, COLOR_YELLOW, COLOR_WHITE, true);
+ DLG_COLOR(searchbox_border, COLOR_WHITE, COLOR_WHITE, true);
+ DLG_COLOR(position_indicator, COLOR_YELLOW, COLOR_WHITE, true);
+ DLG_COLOR(menubox, COLOR_BLACK, COLOR_WHITE, false);
+ DLG_COLOR(menubox_border, COLOR_WHITE, COLOR_WHITE, true);
+ DLG_COLOR(item, COLOR_BLACK, COLOR_WHITE, false);
+ DLG_COLOR(item_selected, COLOR_WHITE, COLOR_BLUE, true);
+ DLG_COLOR(tag, COLOR_YELLOW, COLOR_WHITE, true);
+ DLG_COLOR(tag_selected, COLOR_YELLOW, COLOR_BLUE, true);
+ DLG_COLOR(tag_key, COLOR_YELLOW, COLOR_WHITE, true);
+ DLG_COLOR(tag_key_selected, COLOR_YELLOW, COLOR_BLUE, true);
+ DLG_COLOR(check, COLOR_BLACK, COLOR_WHITE, false);
+ DLG_COLOR(check_selected, COLOR_WHITE, COLOR_BLUE, true);
+ DLG_COLOR(uarrow, COLOR_GREEN, COLOR_WHITE, true);
+ DLG_COLOR(darrow, COLOR_GREEN, COLOR_WHITE, true);
+}
+
+static void set_blackbg_theme(void)
+{
+ DLG_COLOR(screen, COLOR_RED, COLOR_BLACK, true);
+ DLG_COLOR(shadow, COLOR_BLACK, COLOR_BLACK, false);
+ DLG_COLOR(dialog, COLOR_WHITE, COLOR_BLACK, false);
+ DLG_COLOR(title, COLOR_RED, COLOR_BLACK, false);
+ DLG_COLOR(border, COLOR_BLACK, COLOR_BLACK, true);
+
+ DLG_COLOR(button_active, COLOR_YELLOW, COLOR_RED, false);
+ DLG_COLOR(button_inactive, COLOR_YELLOW, COLOR_BLACK, false);
+ DLG_COLOR(button_key_active, COLOR_YELLOW, COLOR_RED, true);
+ DLG_COLOR(button_key_inactive, COLOR_RED, COLOR_BLACK, false);
+ DLG_COLOR(button_label_active, COLOR_WHITE, COLOR_RED, false);
+ DLG_COLOR(button_label_inactive, COLOR_BLACK, COLOR_BLACK, true);
+
+ DLG_COLOR(inputbox, COLOR_YELLOW, COLOR_BLACK, false);
+ DLG_COLOR(inputbox_border, COLOR_YELLOW, COLOR_BLACK, false);
+
+ DLG_COLOR(searchbox, COLOR_YELLOW, COLOR_BLACK, false);
+ DLG_COLOR(searchbox_title, COLOR_YELLOW, COLOR_BLACK, true);
+ DLG_COLOR(searchbox_border, COLOR_BLACK, COLOR_BLACK, true);
+
+ DLG_COLOR(position_indicator, COLOR_RED, COLOR_BLACK, false);
+
+ DLG_COLOR(menubox, COLOR_YELLOW, COLOR_BLACK, false);
+ DLG_COLOR(menubox_border, COLOR_BLACK, COLOR_BLACK, true);
+
+ DLG_COLOR(item, COLOR_WHITE, COLOR_BLACK, false);
+ DLG_COLOR(item_selected, COLOR_WHITE, COLOR_RED, false);
+
+ DLG_COLOR(tag, COLOR_RED, COLOR_BLACK, false);
+ DLG_COLOR(tag_selected, COLOR_YELLOW, COLOR_RED, true);
+ DLG_COLOR(tag_key, COLOR_RED, COLOR_BLACK, false);
+ DLG_COLOR(tag_key_selected, COLOR_YELLOW, COLOR_RED, true);
+
+ DLG_COLOR(check, COLOR_YELLOW, COLOR_BLACK, false);
+ DLG_COLOR(check_selected, COLOR_YELLOW, COLOR_RED, true);
+
+ DLG_COLOR(uarrow, COLOR_RED, COLOR_BLACK, false);
+ DLG_COLOR(darrow, COLOR_RED, COLOR_BLACK, false);
+}
+
+static void set_bluetitle_theme(void)
+{
+ set_classic_theme();
+ DLG_COLOR(title, COLOR_BLUE, COLOR_WHITE, true);
+ DLG_COLOR(button_key_active, COLOR_YELLOW, COLOR_BLUE, true);
+ DLG_COLOR(button_label_active, COLOR_WHITE, COLOR_BLUE, true);
+ DLG_COLOR(searchbox_title, COLOR_BLUE, COLOR_WHITE, true);
+ DLG_COLOR(position_indicator, COLOR_BLUE, COLOR_WHITE, true);
+ DLG_COLOR(tag, COLOR_BLUE, COLOR_WHITE, true);
+ DLG_COLOR(tag_key, COLOR_BLUE, COLOR_WHITE, true);
+
+}
/*
- * Attribute values, default is for mono display
+ * Select color theme
*/
-chtype attributes[] = {
- A_NORMAL, /* screen_attr */
- A_NORMAL, /* shadow_attr */
- A_NORMAL, /* dialog_attr */
- A_BOLD, /* title_attr */
- A_NORMAL, /* border_attr */
- A_REVERSE, /* button_active_attr */
- A_DIM, /* button_inactive_attr */
- A_REVERSE, /* button_key_active_attr */
- A_BOLD, /* button_key_inactive_attr */
- A_REVERSE, /* button_label_active_attr */
- A_NORMAL, /* button_label_inactive_attr */
- A_NORMAL, /* inputbox_attr */
- A_NORMAL, /* inputbox_border_attr */
- A_NORMAL, /* searchbox_attr */
- A_BOLD, /* searchbox_title_attr */
- A_NORMAL, /* searchbox_border_attr */
- A_BOLD, /* position_indicator_attr */
- A_NORMAL, /* menubox_attr */
- A_NORMAL, /* menubox_border_attr */
- A_NORMAL, /* item_attr */
- A_REVERSE, /* item_selected_attr */
- A_BOLD, /* tag_attr */
- A_REVERSE, /* tag_selected_attr */
- A_BOLD, /* tag_key_attr */
- A_REVERSE, /* tag_key_selected_attr */
- A_BOLD, /* check_attr */
- A_REVERSE, /* check_selected_attr */
- A_BOLD, /* uarrow_attr */
- A_BOLD /* darrow_attr */
-};
-
-#include "colors.h"
+static int set_theme(const char *theme)
+{
+ int use_color = 1;
+ if (!theme)
+ set_bluetitle_theme();
+ else if (strcmp(theme, "classic") == 0)
+ set_classic_theme();
+ else if (strcmp(theme, "bluetitle") == 0)
+ set_bluetitle_theme();
+ else if (strcmp(theme, "blackbg") == 0)
+ set_blackbg_theme();
+ else if (strcmp(theme, "mono") == 0)
+ use_color = 0;
+
+ return use_color;
+}
+
+static void init_one_color(struct dialog_color *color)
+{
+ static int pair = 0;
+
+ pair++;
+ init_pair(pair, color->fg, color->bg);
+ if (color->hl)
+ color->atr = A_BOLD | COLOR_PAIR(pair);
+ else
+ color->atr = COLOR_PAIR(pair);
+}
+
+static void init_dialog_colors(void)
+{
+ init_one_color(&dlg.screen);
+ init_one_color(&dlg.shadow);
+ init_one_color(&dlg.dialog);
+ init_one_color(&dlg.title);
+ init_one_color(&dlg.border);
+ init_one_color(&dlg.button_active);
+ init_one_color(&dlg.button_inactive);
+ init_one_color(&dlg.button_key_active);
+ init_one_color(&dlg.button_key_inactive);
+ init_one_color(&dlg.button_label_active);
+ init_one_color(&dlg.button_label_inactive);
+ init_one_color(&dlg.inputbox);
+ init_one_color(&dlg.inputbox_border);
+ init_one_color(&dlg.searchbox);
+ init_one_color(&dlg.searchbox_title);
+ init_one_color(&dlg.searchbox_border);
+ init_one_color(&dlg.position_indicator);
+ init_one_color(&dlg.menubox);
+ init_one_color(&dlg.menubox_border);
+ init_one_color(&dlg.item);
+ init_one_color(&dlg.item_selected);
+ init_one_color(&dlg.tag);
+ init_one_color(&dlg.tag_selected);
+ init_one_color(&dlg.tag_key);
+ init_one_color(&dlg.tag_key_selected);
+ init_one_color(&dlg.check);
+ init_one_color(&dlg.check_selected);
+ init_one_color(&dlg.uarrow);
+ init_one_color(&dlg.darrow);
+}
/*
- * Table of color values
+ * Setup for color display
*/
-int color_table[][3] = {
- {SCREEN_FG, SCREEN_BG, SCREEN_HL},
- {SHADOW_FG, SHADOW_BG, SHADOW_HL},
- {DIALOG_FG, DIALOG_BG, DIALOG_HL},
- {TITLE_FG, TITLE_BG, TITLE_HL},
- {BORDER_FG, BORDER_BG, BORDER_HL},
- {BUTTON_ACTIVE_FG, BUTTON_ACTIVE_BG, BUTTON_ACTIVE_HL},
- {BUTTON_INACTIVE_FG, BUTTON_INACTIVE_BG, BUTTON_INACTIVE_HL},
- {BUTTON_KEY_ACTIVE_FG, BUTTON_KEY_ACTIVE_BG, BUTTON_KEY_ACTIVE_HL},
- {BUTTON_KEY_INACTIVE_FG, BUTTON_KEY_INACTIVE_BG,
- BUTTON_KEY_INACTIVE_HL},
- {BUTTON_LABEL_ACTIVE_FG, BUTTON_LABEL_ACTIVE_BG,
- BUTTON_LABEL_ACTIVE_HL},
- {BUTTON_LABEL_INACTIVE_FG, BUTTON_LABEL_INACTIVE_BG,
- BUTTON_LABEL_INACTIVE_HL},
- {INPUTBOX_FG, INPUTBOX_BG, INPUTBOX_HL},
- {INPUTBOX_BORDER_FG, INPUTBOX_BORDER_BG, INPUTBOX_BORDER_HL},
- {SEARCHBOX_FG, SEARCHBOX_BG, SEARCHBOX_HL},
- {SEARCHBOX_TITLE_FG, SEARCHBOX_TITLE_BG, SEARCHBOX_TITLE_HL},
- {SEARCHBOX_BORDER_FG, SEARCHBOX_BORDER_BG, SEARCHBOX_BORDER_HL},
- {POSITION_INDICATOR_FG, POSITION_INDICATOR_BG, POSITION_INDICATOR_HL},
- {MENUBOX_FG, MENUBOX_BG, MENUBOX_HL},
- {MENUBOX_BORDER_FG, MENUBOX_BORDER_BG, MENUBOX_BORDER_HL},
- {ITEM_FG, ITEM_BG, ITEM_HL},
- {ITEM_SELECTED_FG, ITEM_SELECTED_BG, ITEM_SELECTED_HL},
- {TAG_FG, TAG_BG, TAG_HL},
- {TAG_SELECTED_FG, TAG_SELECTED_BG, TAG_SELECTED_HL},
- {TAG_KEY_FG, TAG_KEY_BG, TAG_KEY_HL},
- {TAG_KEY_SELECTED_FG, TAG_KEY_SELECTED_BG, TAG_KEY_SELECTED_HL},
- {CHECK_FG, CHECK_BG, CHECK_HL},
- {CHECK_SELECTED_FG, CHECK_SELECTED_BG, CHECK_SELECTED_HL},
- {UARROW_FG, UARROW_BG, UARROW_HL},
- {DARROW_FG, DARROW_BG, DARROW_HL},
-}; /* color_table */
+static void color_setup(const char *theme)
+{
+ if (set_theme(theme)) {
+ if (has_colors()) { /* Terminal supports color? */
+ start_color();
+ init_dialog_colors();
+ }
+ }
+ else
+ {
+ set_mono_theme();
+ }
+}
/*
* Set window to attribute 'attr'
@@ -119,13 +251,13 @@ void attr_clear(WINDOW * win, int height, int width, chtype attr)
void dialog_clear(void)
{
- attr_clear(stdscr, LINES, COLS, screen_attr);
+ attr_clear(stdscr, LINES, COLS, dlg.screen.atr);
/* Display background title if it exists ... - SLH */
- if (backtitle != NULL) {
+ if (dlg.backtitle != NULL) {
int i;
- wattrset(stdscr, screen_attr);
- mvwaddstr(stdscr, 0, 1, (char *)backtitle);
+ wattrset(stdscr, dlg.screen.atr);
+ mvwaddstr(stdscr, 0, 1, (char *)dlg.backtitle);
wmove(stdscr, 1, 1);
for (i = 1; i < COLS - 1; i++)
waddch(stdscr, ACS_HLINE);
@@ -136,40 +268,22 @@ void dialog_clear(void)
/*
* Do some initialization for dialog
*/
-void init_dialog(void)
+void init_dialog(const char *backtitle)
+{
+ dlg.backtitle = backtitle;
+ color_setup(getenv("MENUCONFIG_COLOR"));
+}
+
+void reset_dialog(void)
{
initscr(); /* Init curses */
keypad(stdscr, TRUE);
cbreak();
noecho();
-
- if (use_colors) /* Set up colors */
- color_setup();
-
dialog_clear();
}
/*
- * Setup for color display
- */
-void color_setup(void)
-{
- int i;
-
- if (has_colors()) { /* Terminal supports color? */
- start_color();
-
- /* Initialize color pairs */
- for (i = 0; i < ATTRIBUTE_COUNT; i++)
- init_pair(i + 1, color_table[i][0], color_table[i][1]);
-
- /* Setup color attributes */
- for (i = 0; i < ATTRIBUTE_COUNT; i++)
- attributes[i] = C_ATTR(color_table[i][2], i + 1);
- }
-}
-
-/*
* End using dialog functions.
*/
void end_dialog(void)
@@ -184,7 +298,7 @@ void print_title(WINDOW *dialog, const char *title, int width)
{
if (title) {
int tlen = MIN(width - 2, strlen(title));
- wattrset(dialog, title_attr);
+ wattrset(dialog, dlg.title.atr);
mvwaddch(dialog, 0, (width - tlen) / 2 - 1, ' ');
mvwaddnstr(dialog, 0, (width - tlen)/2, title, tlen);
waddch(dialog, ' ');
@@ -264,21 +378,23 @@ void print_button(WINDOW * win, const char *label, int y, int x, int selected)
int i, temp;
wmove(win, y, x);
- wattrset(win, selected ? button_active_attr : button_inactive_attr);
+ wattrset(win, selected ? dlg.button_active.atr
+ : dlg.button_inactive.atr);
waddstr(win, "<");
temp = strspn(label, " ");
label += temp;
- wattrset(win, selected ? button_label_active_attr
- : button_label_inactive_attr);
+ wattrset(win, selected ? dlg.button_label_active.atr
+ : dlg.button_label_inactive.atr);
for (i = 0; i < temp; i++)
waddch(win, ' ');
- wattrset(win, selected ? button_key_active_attr
- : button_key_inactive_attr);
+ wattrset(win, selected ? dlg.button_key_active.atr
+ : dlg.button_key_inactive.atr);
waddch(win, label[0]);
- wattrset(win, selected ? button_label_active_attr
- : button_label_inactive_attr);
+ wattrset(win, selected ? dlg.button_label_active.atr
+ : dlg.button_label_inactive.atr);
waddstr(win, (char *)label + 1);
- wattrset(win, selected ? button_active_attr : button_inactive_attr);
+ wattrset(win, selected ? dlg.button_active.atr
+ : dlg.button_inactive.atr);
waddstr(win, ">");
wmove(win, y, x + temp + 1);
}
@@ -326,7 +442,7 @@ void draw_shadow(WINDOW * win, int y, int x, int height, int width)
int i;
if (has_colors()) { /* Whether terminal supports color? */
- wattrset(win, shadow_attr);
+ wattrset(win, dlg.shadow.atr);
wmove(win, y + height, x + 2);
for (i = 0; i < width; i++)
waddch(win, winch(win) & A_CHARTEXT);
@@ -360,3 +476,167 @@ int first_alpha(const char *string, const char *exempt)
return 0;
}
+
+/*
+ * ncurses uses ESC to detect escaped char sequences. This resutl in
+ * a small timeout before ESC is actually delivered to the application.
+ * lxdialog suggest <ESC> <ESC> which is correctly translated to two
+ * times esc. But then we need to ignore the second esc to avoid stepping
+ * out one menu too much. Filter away all escaped key sequences since
+ * keypad(FALSE) turn off ncurses support for escape sequences - and thats
+ * needed to make notimeout() do as expected.
+ */
+int on_key_esc(WINDOW *win)
+{
+ int key;
+ int key2;
+ int key3;
+
+ nodelay(win, TRUE);
+ keypad(win, FALSE);
+ key = wgetch(win);
+ key2 = wgetch(win);
+ do {
+ key3 = wgetch(win);
+ } while (key3 != ERR);
+ nodelay(win, FALSE);
+ keypad(win, TRUE);
+ if (key == KEY_ESC && key2 == ERR)
+ return KEY_ESC;
+ else if (key != ERR && key != KEY_ESC && key2 == ERR)
+ ungetch(key);
+
+ return -1;
+}
+
+/* redraw screen in new size */
+int on_key_resize(void)
+{
+ dialog_clear();
+ return KEY_RESIZE;
+}
+
+struct dialog_list *item_cur;
+struct dialog_list item_nil;
+struct dialog_list *item_head;
+
+void item_reset(void)
+{
+ struct dialog_list *p, *next;
+
+ for (p = item_head; p; p = next) {
+ next = p->next;
+ free(p);
+ }
+ item_head = NULL;
+ item_cur = &item_nil;
+}
+
+void item_make(const char *fmt, ...)
+{
+ va_list ap;
+ struct dialog_list *p = malloc(sizeof(*p));
+
+ if (item_head)
+ item_cur->next = p;
+ else
+ item_head = p;
+ item_cur = p;
+ memset(p, 0, sizeof(*p));
+
+ va_start(ap, fmt);
+ vsnprintf(item_cur->node.str, sizeof(item_cur->node.str), fmt, ap);
+ va_end(ap);
+}
+
+void item_add_str(const char *fmt, ...)
+{
+ va_list ap;
+ size_t avail;
+
+ avail = sizeof(item_cur->node.str) - strlen(item_cur->node.str);
+
+ va_start(ap, fmt);
+ vsnprintf(item_cur->node.str + strlen(item_cur->node.str),
+ avail, fmt, ap);
+ item_cur->node.str[sizeof(item_cur->node.str) - 1] = '\0';
+ va_end(ap);
+}
+
+void item_set_tag(char tag)
+{
+ item_cur->node.tag = tag;
+}
+void item_set_data(void *ptr)
+{
+ item_cur->node.data = ptr;
+}
+
+void item_set_selected(int val)
+{
+ item_cur->node.selected = val;
+}
+
+int item_activate_selected(void)
+{
+ item_foreach()
+ if (item_is_selected())
+ return 1;
+ return 0;
+}
+
+void *item_data(void)
+{
+ return item_cur->node.data;
+}
+
+char item_tag(void)
+{
+ return item_cur->node.tag;
+}
+
+int item_count(void)
+{
+ int n = 0;
+ struct dialog_list *p;
+
+ for (p = item_head; p; p = p->next)
+ n++;
+ return n;
+}
+
+void item_set(int n)
+{
+ int i = 0;
+ item_foreach()
+ if (i++ == n)
+ return;
+}
+
+int item_n(void)
+{
+ int n = 0;
+ struct dialog_list *p;
+
+ for (p = item_head; p; p = p->next) {
+ if (p == item_cur)
+ return n;
+ n++;
+ }
+ return 0;
+}
+
+const char *item_str(void)
+{
+ return item_cur->node.str;
+}
+
+int item_is_selected(void)
+{
+ return (item_cur->node.selected != 0);
+}
+
+int item_is_tag(char tag)
+{
+ return (item_cur->node.tag == tag);
+}
diff --git a/scripts/kconfig/lxdialog/yesno.c b/scripts/kconfig/lxdialog/yesno.c
index cb2568aae3ed..ee0a04e3e012 100644
--- a/scripts/kconfig/lxdialog/yesno.c
+++ b/scripts/kconfig/lxdialog/yesno.c
@@ -44,6 +44,12 @@ int dialog_yesno(const char *title, const char *prompt, int height, int width)
int i, x, y, key = 0, button = 0;
WINDOW *dialog;
+do_resize:
+ if (getmaxy(stdscr) < (height + 4))
+ return -ERRDISPLAYTOOSMALL;
+ if (getmaxx(stdscr) < (width + 4))
+ return -ERRDISPLAYTOOSMALL;
+
/* center dialog box on screen */
x = (COLS - width) / 2;
y = (LINES - height) / 2;
@@ -53,22 +59,23 @@ int dialog_yesno(const char *title, const char *prompt, int height, int width)
dialog = newwin(height, width, y, x);
keypad(dialog, TRUE);
- draw_box(dialog, 0, 0, height, width, dialog_attr, border_attr);
- wattrset(dialog, border_attr);
+ draw_box(dialog, 0, 0, height, width,
+ dlg.dialog.atr, dlg.border.atr);
+ wattrset(dialog, dlg.border.atr);
mvwaddch(dialog, height - 3, 0, ACS_LTEE);
for (i = 0; i < width - 2; i++)
waddch(dialog, ACS_HLINE);
- wattrset(dialog, dialog_attr);
+ wattrset(dialog, dlg.dialog.atr);
waddch(dialog, ACS_RTEE);
print_title(dialog, title, width);
- wattrset(dialog, dialog_attr);
+ wattrset(dialog, dlg.dialog.atr);
print_autowrap(dialog, prompt, width - 2, 1, 3);
print_buttons(dialog, height, width, 0);
- while (key != ESC) {
+ while (key != KEY_ESC) {
key = wgetch(dialog);
switch (key) {
case 'Y':
@@ -92,11 +99,16 @@ int dialog_yesno(const char *title, const char *prompt, int height, int width)
case '\n':
delwin(dialog);
return button;
- case ESC:
+ case KEY_ESC:
+ key = on_key_esc(dialog);
break;
+ case KEY_RESIZE:
+ delwin(dialog);
+ on_key_resize();
+ goto do_resize;
}
}
delwin(dialog);
- return -1; /* ESC pressed */
+ return key; /* ESC pressed */
}
diff --git a/scripts/kconfig/mconf.c b/scripts/kconfig/mconf.c
index 7f973195e79a..08a4c7af93ea 100644
--- a/scripts/kconfig/mconf.c
+++ b/scripts/kconfig/mconf.c
@@ -24,6 +24,7 @@
#define LKC_DIRECT_LINK
#include "lkc.h"
+#include "lxdialog/dialog.h"
static char menu_backtitle[128];
static const char mconf_readme[] = N_(
@@ -159,7 +160,21 @@ static const char mconf_readme[] = N_(
"\n"
"Note that this mode can eventually be a little more CPU expensive\n"
"(especially with a larger number of unrolled categories) than the\n"
-"default mode.\n"),
+"default mode.\n"
+"\n"
+"Different color themes available\n"
+"--------------------------------\n"
+"It is possible to select different color themes using the variable\n"
+"MENUCONFIG_COLOR. To select a theme use:\n"
+"\n"
+"make MENUCONFIG_COLOR=<theme> menuconfig\n"
+"\n"
+"Available themes are\n"
+" mono => selects colors suitable for monochrome displays\n"
+" blackbg => selects a color scheme with black background\n"
+" classic => theme with blue background. The classic look\n"
+" bluetitle => a LCD friendly version of classic. (default)\n"
+"\n"),
menu_instructions[] = N_(
"Arrow keys navigate the menu. "
"<Enter> selects submenus --->. "
@@ -256,16 +271,12 @@ search_help[] = N_(
" USB$ => find all CONFIG_ symbols ending with USB\n"
"\n");
-static char buf[4096], *bufptr = buf;
-static char input_buf[4096];
static char filename[PATH_MAX+1] = ".config";
-static char *args[1024], **argptr = args;
static int indent;
static struct termios ios_org;
static int rows = 0, cols = 0;
static struct menu *current_menu;
static int child_count;
-static int do_resize;
static int single_menu_mode;
static void conf(struct menu *menu);
@@ -276,12 +287,6 @@ static void conf_save(void);
static void show_textbox(const char *title, const char *text, int r, int c);
static void show_helptext(const char *title, const char *text);
static void show_help(struct menu *menu);
-static void show_file(const char *filename, const char *title, int r, int c);
-
-static void cprint_init(void);
-static int cprint1(const char *fmt, ...);
-static void cprint_done(void);
-static int cprint(const char *fmt, ...);
static void init_wsize(void)
{
@@ -318,54 +323,6 @@ static void init_wsize(void)
cols -= 5;
}
-static void cprint_init(void)
-{
- bufptr = buf;
- argptr = args;
- memset(args, 0, sizeof(args));
- indent = 0;
- child_count = 0;
- cprint("./scripts/kconfig/lxdialog/lxdialog");
- cprint("--backtitle");
- cprint(menu_backtitle);
-}
-
-static int cprint1(const char *fmt, ...)
-{
- va_list ap;
- int res;
-
- if (!*argptr)
- *argptr = bufptr;
- va_start(ap, fmt);
- res = vsprintf(bufptr, fmt, ap);
- va_end(ap);
- bufptr += res;
-
- return res;
-}
-
-static void cprint_done(void)
-{
- *bufptr++ = 0;
- argptr++;
-}
-
-static int cprint(const char *fmt, ...)
-{
- va_list ap;
- int res;
-
- *argptr++ = bufptr;
- va_start(ap, fmt);
- res = vsprintf(bufptr, fmt, ap);
- va_end(ap);
- bufptr += res;
- *bufptr++ = 0;
-
- return res;
-}
-
static void get_prompt_str(struct gstr *r, struct property *prop)
{
int i, j;
@@ -438,108 +395,17 @@ static struct gstr get_relations_str(struct symbol **sym_arr)
return res;
}
-pid_t pid;
-
-static void winch_handler(int sig)
-{
- if (!do_resize) {
- kill(pid, SIGINT);
- do_resize = 1;
- }
-}
-
-static int exec_conf(void)
-{
- int pipefd[2], stat, size;
- struct sigaction sa;
- sigset_t sset, osset;
-
- sigemptyset(&sset);
- sigaddset(&sset, SIGINT);
- sigprocmask(SIG_BLOCK, &sset, &osset);
-
- signal(SIGINT, SIG_DFL);
-
- sa.sa_handler = winch_handler;
- sigemptyset(&sa.sa_mask);
- sa.sa_flags = SA_RESTART;
- sigaction(SIGWINCH, &sa, NULL);
-
- *argptr++ = NULL;
-
- pipe(pipefd);
- pid = fork();
- if (pid == 0) {
- sigprocmask(SIG_SETMASK, &osset, NULL);
- dup2(pipefd[1], 2);
- close(pipefd[0]);
- close(pipefd[1]);
- execv(args[0], args);
- _exit(EXIT_FAILURE);
- }
-
- close(pipefd[1]);
- bufptr = input_buf;
- while (1) {
- size = input_buf + sizeof(input_buf) - bufptr;
- size = read(pipefd[0], bufptr, size);
- if (size <= 0) {
- if (size < 0) {
- if (errno == EINTR || errno == EAGAIN)
- continue;
- perror("read");
- }
- break;
- }
- bufptr += size;
- }
- *bufptr++ = 0;
- close(pipefd[0]);
- waitpid(pid, &stat, 0);
-
- if (do_resize) {
- init_wsize();
- do_resize = 0;
- sigprocmask(SIG_SETMASK, &osset, NULL);
- return -1;
- }
- if (WIFSIGNALED(stat)) {
- printf("\finterrupted(%d)\n", WTERMSIG(stat));
- exit(1);
- }
-#if 0
- printf("\fexit state: %d\nexit data: '%s'\n", WEXITSTATUS(stat), input_buf);
- sleep(1);
-#endif
- sigpending(&sset);
- if (sigismember(&sset, SIGINT)) {
- printf("\finterrupted\n");
- exit(1);
- }
- sigprocmask(SIG_SETMASK, &osset, NULL);
-
- return WEXITSTATUS(stat);
-}
-
static void search_conf(void)
{
struct symbol **sym_arr;
- int stat;
struct gstr res;
-
+ int dres;
again:
- cprint_init();
- cprint("--title");
- cprint(_("Search Configuration Parameter"));
- cprint("--inputbox");
- cprint(_("Enter CONFIG_ (sub)string to search for (omit CONFIG_)"));
- cprint("10");
- cprint("75");
- cprint("");
- stat = exec_conf();
- if (stat < 0)
- goto again;
- switch (stat) {
+ dialog_clear();
+ dres = dialog_inputbox(_("Search Configuration Parameter"),
+ _("Enter CONFIG_ (sub)string to search for (omit CONFIG_)"),
+ 10, 75, "");
+ switch (dres) {
case 0:
break;
case 1:
@@ -549,7 +415,7 @@ again:
return;
}
- sym_arr = sym_re_search(input_buf);
+ sym_arr = sym_re_search(dialog_input_result);
res = get_relations_str(sym_arr);
free(sym_arr);
show_textbox(_("Search Results"), str_get(&res), 0, 0);
@@ -576,24 +442,24 @@ static void build_conf(struct menu *menu)
switch (prop->type) {
case P_MENU:
child_count++;
- cprint("m%p", menu);
-
if (single_menu_mode) {
- cprint1("%s%*c%s",
- menu->data ? "-->" : "++>",
- indent + 1, ' ', prompt);
+ item_make("%s%*c%s",
+ menu->data ? "-->" : "++>",
+ indent + 1, ' ', prompt);
} else
- cprint1(" %*c%s --->", indent + 1, ' ', prompt);
+ item_make(" %*c%s --->", indent + 1, ' ', prompt);
- cprint_done();
+ item_set_tag('m');
+ item_set_data(menu);
if (single_menu_mode && menu->data)
goto conf_childs;
return;
default:
if (prompt) {
child_count++;
- cprint(":%p", menu);
- cprint("---%*c%s", indent + 1, ' ', prompt);
+ item_make("---%*c%s", indent + 1, ' ', prompt);
+ item_set_tag(':');
+ item_set_data(menu);
}
}
} else
@@ -614,10 +480,9 @@ static void build_conf(struct menu *menu)
val = sym_get_tristate_value(sym);
if (sym_is_changable(sym)) {
- cprint("t%p", menu);
switch (type) {
case S_BOOLEAN:
- cprint1("[%c]", val == no ? ' ' : '*');
+ item_make("[%c]", val == no ? ' ' : '*');
break;
case S_TRISTATE:
switch (val) {
@@ -625,84 +490,87 @@ static void build_conf(struct menu *menu)
case mod: ch = 'M'; break;
default: ch = ' '; break;
}
- cprint1("<%c>", ch);
+ item_make("<%c>", ch);
break;
}
+ item_set_tag('t');
+ item_set_data(menu);
} else {
- cprint("%c%p", def_menu ? 't' : ':', menu);
- cprint1(" ");
+ item_make(" ");
+ item_set_tag(def_menu ? 't' : ':');
+ item_set_data(menu);
}
- cprint1("%*c%s", indent + 1, ' ', menu_get_prompt(menu));
+ item_add_str("%*c%s", indent + 1, ' ', menu_get_prompt(menu));
if (val == yes) {
if (def_menu) {
- cprint1(" (%s)", menu_get_prompt(def_menu));
- cprint1(" --->");
- cprint_done();
+ item_add_str(" (%s)", menu_get_prompt(def_menu));
+ item_add_str(" --->");
if (def_menu->list) {
indent += 2;
build_conf(def_menu);
indent -= 2;
}
- } else
- cprint_done();
+ }
return;
}
- cprint_done();
} else {
if (menu == current_menu) {
- cprint(":%p", menu);
- cprint("---%*c%s", indent + 1, ' ', menu_get_prompt(menu));
+ item_make("---%*c%s", indent + 1, ' ', menu_get_prompt(menu));
+ item_set_tag(':');
+ item_set_data(menu);
goto conf_childs;
}
child_count++;
val = sym_get_tristate_value(sym);
if (sym_is_choice_value(sym) && val == yes) {
- cprint(":%p", menu);
- cprint1(" ");
+ item_make(" ");
+ item_set_tag(':');
+ item_set_data(menu);
} else {
switch (type) {
case S_BOOLEAN:
- cprint("t%p", menu);
if (sym_is_changable(sym))
- cprint1("[%c]", val == no ? ' ' : '*');
+ item_make("[%c]", val == no ? ' ' : '*');
else
- cprint1("---");
+ item_make("---");
+ item_set_tag('t');
+ item_set_data(menu);
break;
case S_TRISTATE:
- cprint("t%p", menu);
switch (val) {
case yes: ch = '*'; break;
case mod: ch = 'M'; break;
default: ch = ' '; break;
}
if (sym_is_changable(sym))
- cprint1("<%c>", ch);
+ item_make("<%c>", ch);
else
- cprint1("---");
+ item_make("---");
+ item_set_tag('t');
+ item_set_data(menu);
break;
default:
- cprint("s%p", menu);
- tmp = cprint1("(%s)", sym_get_string_value(sym));
+ tmp = 2 + strlen(sym_get_string_value(sym)); /* () = 2 */
+ item_make("(%s)", sym_get_string_value(sym));
tmp = indent - tmp + 4;
if (tmp < 0)
tmp = 0;
- cprint1("%*c%s%s", tmp, ' ', menu_get_prompt(menu),
- (sym_has_value(sym) || !sym_is_changable(sym)) ?
- "" : " (NEW)");
- cprint_done();
+ item_add_str("%*c%s%s", tmp, ' ', menu_get_prompt(menu),
+ (sym_has_value(sym) || !sym_is_changable(sym)) ?
+ "" : " (NEW)");
+ item_set_tag('s');
+ item_set_data(menu);
goto conf_childs;
}
}
- cprint1("%*c%s%s", indent + 1, ' ', menu_get_prompt(menu),
- (sym_has_value(sym) || !sym_is_changable(sym)) ?
- "" : " (NEW)");
+ item_add_str("%*c%s%s", indent + 1, ' ', menu_get_prompt(menu),
+ (sym_has_value(sym) || !sym_is_changable(sym)) ?
+ "" : " (NEW)");
if (menu->prompt->type == P_MENU) {
- cprint1(" --->");
- cprint_done();
+ item_add_str(" --->");
return;
}
- cprint_done();
}
conf_childs:
@@ -717,59 +585,45 @@ static void conf(struct menu *menu)
struct menu *submenu;
const char *prompt = menu_get_prompt(menu);
struct symbol *sym;
- char active_entry[40];
- int stat, type, i;
+ struct menu *active_menu = NULL;
+ int res;
+ int s_scroll = 0;
- unlink("lxdialog.scrltmp");
- active_entry[0] = 0;
while (1) {
- cprint_init();
- cprint("--title");
- cprint("%s", prompt ? prompt : _("Main Menu"));
- cprint("--menu");
- cprint(_(menu_instructions));
- cprint("%d", rows);
- cprint("%d", cols);
- cprint("%d", rows - 10);
- cprint("%s", active_entry);
+ item_reset();
current_menu = menu;
build_conf(menu);
if (!child_count)
break;
if (menu == &rootmenu) {
- cprint(":");
- cprint("--- ");
- cprint("L");
- cprint(_(" Load an Alternate Configuration File"));
- cprint("S");
- cprint(_(" Save Configuration to an Alternate File"));
+ item_make("--- ");
+ item_set_tag(':');
+ item_make(_(" Load an Alternate Configuration File"));
+ item_set_tag('L');
+ item_make(_(" Save an Alternate Configuration File"));
+ item_set_tag('S');
}
- stat = exec_conf();
- if (stat < 0)
- continue;
-
- if (stat == 1 || stat == 255)
+ dialog_clear();
+ res = dialog_menu(prompt ? prompt : _("Main Menu"),
+ _(menu_instructions),
+ active_menu, &s_scroll);
+ if (res == 1 || res == KEY_ESC || res == -ERRDISPLAYTOOSMALL)
break;
-
- type = input_buf[0];
- if (!type)
+ if (!item_activate_selected())
+ continue;
+ if (!item_tag())
continue;
- for (i = 0; input_buf[i] && !isspace(input_buf[i]); i++)
- ;
- if (i >= sizeof(active_entry))
- i = sizeof(active_entry) - 1;
- input_buf[i] = 0;
- strcpy(active_entry, input_buf);
-
- sym = NULL;
- submenu = NULL;
- if (sscanf(input_buf + 1, "%p", &submenu) == 1)
+ submenu = item_data();
+ active_menu = item_data();
+ if (submenu)
sym = submenu->sym;
+ else
+ sym = NULL;
- switch (stat) {
+ switch (res) {
case 0:
- switch (type) {
+ switch (item_tag()) {
case 'm':
if (single_menu_mode)
submenu->data = (void *) (long) !submenu->data;
@@ -800,7 +654,7 @@ static void conf(struct menu *menu)
show_helptext("README", _(mconf_readme));
break;
case 3:
- if (type == 't') {
+ if (item_is_tag('t')) {
if (sym_set_tristate_value(sym, yes))
break;
if (sym_set_tristate_value(sym, mod))
@@ -808,17 +662,17 @@ static void conf(struct menu *menu)
}
break;
case 4:
- if (type == 't')
+ if (item_is_tag('t'))
sym_set_tristate_value(sym, no);
break;
case 5:
- if (type == 't')
+ if (item_is_tag('t'))
sym_set_tristate_value(sym, mod);
break;
case 6:
- if (type == 't')
+ if (item_is_tag('t'))
sym_toggle_tristate_value(sym);
- else if (type == 'm')
+ else if (item_is_tag('m'))
conf(submenu);
break;
case 7:
@@ -830,13 +684,8 @@ static void conf(struct menu *menu)
static void show_textbox(const char *title, const char *text, int r, int c)
{
- int fd;
-
- fd = creat(".help.tmp", 0777);
- write(fd, text, strlen(text));
- close(fd);
- show_file(".help.tmp", title, r, c);
- unlink(".help.tmp");
+ dialog_clear();
+ dialog_textbox(title, text, r, c);
}
static void show_helptext(const char *title, const char *text)
@@ -864,68 +713,52 @@ static void show_help(struct menu *menu)
str_free(&help);
}
-static void show_file(const char *filename, const char *title, int r, int c)
-{
- do {
- cprint_init();
- if (title) {
- cprint("--title");
- cprint("%s", title);
- }
- cprint("--textbox");
- cprint("%s", filename);
- cprint("%d", r ? r : rows);
- cprint("%d", c ? c : cols);
- } while (exec_conf() < 0);
-}
-
static void conf_choice(struct menu *menu)
{
const char *prompt = menu_get_prompt(menu);
struct menu *child;
struct symbol *active;
- int stat;
active = sym_get_choice_value(menu->sym);
while (1) {
- cprint_init();
- cprint("--title");
- cprint("%s", prompt ? prompt : _("Main Menu"));
- cprint("--radiolist");
- cprint(_(radiolist_instructions));
- cprint("15");
- cprint("70");
- cprint("6");
+ int res;
+ int selected;
+ item_reset();
current_menu = menu;
for (child = menu->list; child; child = child->next) {
if (!menu_is_visible(child))
continue;
- cprint("%p", child);
- cprint("%s", menu_get_prompt(child));
+ item_make("%s", menu_get_prompt(child));
+ item_set_data(child);
+ if (child->sym == active)
+ item_set_selected(1);
if (child->sym == sym_get_choice_value(menu->sym))
- cprint("ON");
- else if (child->sym == active)
- cprint("SELECTED");
- else
- cprint("OFF");
+ item_set_tag('X');
}
-
- stat = exec_conf();
- switch (stat) {
+ dialog_clear();
+ res = dialog_checklist(prompt ? prompt : _("Main Menu"),
+ _(radiolist_instructions),
+ 15, 70, 6);
+ selected = item_activate_selected();
+ switch (res) {
case 0:
- if (sscanf(input_buf, "%p", &child) != 1)
- break;
- sym_set_tristate_value(child->sym, yes);
+ if (selected) {
+ child = item_data();
+ sym_set_tristate_value(child->sym, yes);
+ }
return;
case 1:
- if (sscanf(input_buf, "%p", &child) == 1) {
+ if (selected) {
+ child = item_data();
show_help(child);
active = child->sym;
} else
show_help(menu);
break;
- case 255:
+ case KEY_ESC:
+ return;
+ case -ERRDISPLAYTOOSMALL:
return;
}
}
@@ -934,40 +767,38 @@ static void conf_choice(struct menu *menu)
static void conf_string(struct menu *menu)
{
const char *prompt = menu_get_prompt(menu);
- int stat;
while (1) {
- cprint_init();
- cprint("--title");
- cprint("%s", prompt ? prompt : _("Main Menu"));
- cprint("--inputbox");
+ int res;
+ char *heading;
+
switch (sym_get_type(menu->sym)) {
case S_INT:
- cprint(_(inputbox_instructions_int));
+ heading = _(inputbox_instructions_int);
break;
case S_HEX:
- cprint(_(inputbox_instructions_hex));
+ heading = _(inputbox_instructions_hex);
break;
case S_STRING:
- cprint(_(inputbox_instructions_string));
+ heading = _(inputbox_instructions_string);
break;
default:
- /* panic? */;
+ heading = "Internal mconf error!";
}
- cprint("10");
- cprint("75");
- cprint("%s", sym_get_string_value(menu->sym));
- stat = exec_conf();
- switch (stat) {
+ dialog_clear();
+ res = dialog_inputbox(prompt ? prompt : _("Main Menu"),
+ heading, 10, 75,
+ sym_get_string_value(menu->sym));
+ switch (res) {
case 0:
- if (sym_set_string_value(menu->sym, input_buf))
+ if (sym_set_string_value(menu->sym, dialog_input_result))
return;
show_textbox(NULL, _("You have made an invalid entry."), 5, 43);
break;
case 1:
show_help(menu);
break;
- case 255:
+ case KEY_ESC:
return;
}
}
@@ -975,28 +806,24 @@ static void conf_string(struct menu *menu)
static void conf_load(void)
{
- int stat;
while (1) {
- cprint_init();
- cprint("--inputbox");
- cprint(load_config_text);
- cprint("11");
- cprint("55");
- cprint("%s", filename);
- stat = exec_conf();
- switch(stat) {
+ int res;
+ dialog_clear();
+ res = dialog_inputbox(NULL, load_config_text,
+ 11, 55, filename);
+ switch(res) {
case 0:
- if (!input_buf[0])
+ if (!dialog_input_result[0])
return;
- if (!conf_read(input_buf))
+ if (!conf_read(dialog_input_result))
return;
show_textbox(NULL, _("File does not exist!"), 5, 38);
break;
case 1:
show_helptext(_("Load Alternate Configuration"), load_config_help);
break;
- case 255:
+ case KEY_ESC:
return;
}
}
@@ -1004,28 +831,23 @@ static void conf_load(void)
static void conf_save(void)
{
- int stat;
-
while (1) {
- cprint_init();
- cprint("--inputbox");
- cprint(save_config_text);
- cprint("11");
- cprint("55");
- cprint("%s", filename);
- stat = exec_conf();
- switch(stat) {
+ int res;
+ dialog_clear();
+ res = dialog_inputbox(NULL, save_config_text,
+ 11, 55, filename);
+ switch(res) {
case 0:
- if (!input_buf[0])
+ if (!dialog_input_result[0])
return;
- if (!conf_write(input_buf))
+ if (!conf_write(dialog_input_result))
return;
show_textbox(NULL, _("Can't create file! Probably a nonexistent directory."), 5, 60);
break;
case 1:
show_helptext(_("Save Alternate Configuration"), save_config_help);
break;
- case 255:
+ case KEY_ESC:
return;
}
}
@@ -1034,15 +856,13 @@ static void conf_save(void)
static void conf_cleanup(void)
{
tcsetattr(1, TCSAFLUSH, &ios_org);
- unlink(".help.tmp");
- unlink("lxdialog.scrltmp");
}
int main(int ac, char **av)
{
struct symbol *sym;
char *mode;
- int stat;
+ int res;
setlocale(LC_ALL, "");
bindtextdomain(PACKAGE, LOCALEDIR);
@@ -1065,18 +885,19 @@ int main(int ac, char **av)
tcgetattr(1, &ios_org);
atexit(conf_cleanup);
init_wsize();
- conf(&rootmenu);
-
+ reset_dialog();
+ init_dialog(menu_backtitle);
do {
- cprint_init();
- cprint("--yesno");
- cprint(_("Do you wish to save your new kernel configuration?"));
- cprint("5");
- cprint("60");
- stat = exec_conf();
- } while (stat < 0);
-
- if (stat == 0) {
+ conf(&rootmenu);
+ dialog_clear();
+ res = dialog_yesno(NULL,
+ _("Do you wish to save your "
+ "new kernel configuration?\n"
+ "<ESC><ESC> to continue."),
+ 6, 60);
+ } while (res == KEY_ESC);
+ end_dialog();
+ if (res == 0) {
if (conf_write(NULL)) {
fprintf(stderr, _("\n\n"
"Error during writing of the kernel configuration.\n"
diff --git a/security/Kconfig b/security/Kconfig
index 67785df264e5..460e5c9cf496 100644
--- a/security/Kconfig
+++ b/security/Kconfig
@@ -93,18 +93,6 @@ config SECURITY_ROOTPLUG
If you are unsure how to answer this question, answer N.
-config SECURITY_SECLVL
- tristate "BSD Secure Levels"
- depends on SECURITY
- select CRYPTO
- select CRYPTO_SHA1
- help
- Implements BSD Secure Levels as an LSM. See
- <file:Documentation/seclvl.txt> for instructions on how to use this
- module.
-
- If you are unsure how to answer this question, answer N.
-
source security/selinux/Kconfig
endmenu
diff --git a/security/Makefile b/security/Makefile
index 8cbbf2f36709..ef87df2f50a4 100644
--- a/security/Makefile
+++ b/security/Makefile
@@ -16,4 +16,3 @@ obj-$(CONFIG_SECURITY) += security.o dummy.o inode.o
obj-$(CONFIG_SECURITY_SELINUX) += selinux/built-in.o
obj-$(CONFIG_SECURITY_CAPABILITIES) += commoncap.o capability.o
obj-$(CONFIG_SECURITY_ROOTPLUG) += commoncap.o root_plug.o
-obj-$(CONFIG_SECURITY_SECLVL) += seclvl.o
diff --git a/security/commoncap.c b/security/commoncap.c
index f50fc298cf80..5a5ef5ca7ea9 100644
--- a/security/commoncap.c
+++ b/security/commoncap.c
@@ -169,7 +169,7 @@ void cap_bprm_apply_creds (struct linux_binprm *bprm, int unsafe)
/* For init, we want to retain the capabilities set
* in the init_task struct. Thus we skip the usual
* capability rules */
- if (current->pid != 1) {
+ if (!is_init(current)) {
current->cap_permitted = new_permitted;
current->cap_effective =
cap_intersect (new_permitted, bprm->cap_effective);
diff --git a/security/inode.c b/security/inode.c
index 49ee51529396..9b16e14f3a80 100644
--- a/security/inode.c
+++ b/security/inode.c
@@ -78,7 +78,7 @@ static struct inode *get_inode(struct super_block *sb, int mode, dev_t dev)
inode->i_fop = &simple_dir_operations;
/* directory inodes start off with i_nlink == 2 (for "." entry) */
- inode->i_nlink++;
+ inc_nlink(inode);
break;
}
}
@@ -111,7 +111,7 @@ static int mkdir(struct inode *dir, struct dentry *dentry, int mode)
mode = (mode & (S_IRWXUGO | S_ISVTX)) | S_IFDIR;
res = mknod(dir, dentry, mode, 0);
if (!res)
- dir->i_nlink++;
+ inc_nlink(dir);
return res;
}
diff --git a/security/seclvl.c b/security/seclvl.c
deleted file mode 100644
index 8f6291991fbc..000000000000
--- a/security/seclvl.c
+++ /dev/null
@@ -1,671 +0,0 @@
-/**
- * BSD Secure Levels LSM
- *
- * Maintainers:
- * Michael A. Halcrow <mike@halcrow.us>
- * Serge Hallyn <hallyn@cs.wm.edu>
- *
- * Copyright (c) 2001 WireX Communications, Inc <chris@wirex.com>
- * Copyright (c) 2001 Greg Kroah-Hartman <greg@kroah.com>
- * Copyright (c) 2002 International Business Machines <robb@austin.ibm.com>
- * Copyright (c) 2006 Davi E. M. Arnaut <davi.arnaut@gmail.com>
- *
- * 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 <linux/err.h>
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/security.h>
-#include <linux/netlink.h>
-#include <linux/fs.h>
-#include <linux/namei.h>
-#include <linux/mount.h>
-#include <linux/capability.h>
-#include <linux/time.h>
-#include <linux/proc_fs.h>
-#include <linux/kobject.h>
-#include <linux/crypto.h>
-#include <asm/scatterlist.h>
-#include <linux/scatterlist.h>
-#include <linux/gfp.h>
-#include <linux/sysfs.h>
-
-#define SHA1_DIGEST_SIZE 20
-
-/**
- * Module parameter that defines the initial secure level.
- *
- * When built as a module, it defaults to seclvl 1, which is the
- * behavior of BSD secure levels. Note that this default behavior
- * wrecks havoc on a machine when the seclvl module is compiled into
- * the kernel. In that case, we default to seclvl 0.
- */
-#ifdef CONFIG_SECURITY_SECLVL_MODULE
-static int initlvl = 1;
-#else
-static int initlvl;
-#endif
-module_param(initlvl, int, 0);
-MODULE_PARM_DESC(initlvl, "Initial secure level (defaults to 1)");
-
-/* Module parameter that defines the verbosity level */
-static int verbosity;
-module_param(verbosity, int, 0);
-MODULE_PARM_DESC(verbosity, "Initial verbosity level (0 or 1; defaults to "
- "0, which is Quiet)");
-
-/**
- * Optional password which can be passed in to bring seclvl to 0
- * (i.e., for halt/reboot). Defaults to NULL (the passwd attribute
- * file will not be registered in sysfs).
- *
- * This gets converted to its SHA1 hash when stored. It's probably
- * not a good idea to use this parameter when loading seclvl from a
- * script; use sha1_passwd instead.
- */
-
-#define MAX_PASSWD_SIZE 32
-static char passwd[MAX_PASSWD_SIZE];
-module_param_string(passwd, passwd, sizeof(passwd), 0);
-MODULE_PARM_DESC(passwd,
- "Plaintext of password that sets seclvl=0 when written to "
- "(sysfs mount point)/seclvl/passwd\n");
-
-/**
- * SHA1 hashed version of the optional password which can be passed in
- * to bring seclvl to 0 (i.e., for halt/reboot). Must be in
- * hexadecimal format (40 characters). Defaults to NULL (the passwd
- * attribute file will not be registered in sysfs).
- *
- * Use the sha1sum utility to generate the SHA1 hash of a password:
- *
- * echo -n "secret" | sha1sum
- */
-#define MAX_SHA1_PASSWD 41
-static char sha1_passwd[MAX_SHA1_PASSWD];
-module_param_string(sha1_passwd, sha1_passwd, sizeof(sha1_passwd), 0);
-MODULE_PARM_DESC(sha1_passwd,
- "SHA1 hash (40 hexadecimal characters) of password that "
- "sets seclvl=0 when plaintext password is written to "
- "(sysfs mount point)/seclvl/passwd\n");
-
-static int hideHash = 1;
-module_param(hideHash, int, 0);
-MODULE_PARM_DESC(hideHash, "When set to 0, reading seclvl/passwd from sysfs "
- "will return the SHA1-hashed value of the password that "
- "lowers the secure level to 0.\n");
-
-#define MY_NAME "seclvl"
-
-/**
- * This time-limits log writes to one per second.
- */
-#define seclvl_printk(verb, type, fmt, arg...) \
- do { \
- if (verbosity >= verb) { \
- static unsigned long _prior; \
- unsigned long _now = jiffies; \
- if ((_now - _prior) > HZ) { \
- printk(type "%s: %s: " fmt, \
- MY_NAME, __FUNCTION__ , \
- ## arg); \
- _prior = _now; \
- } \
- } \
- } while (0)
-
-/**
- * The actual security level. Ranges between -1 and 2 inclusive.
- */
-static int seclvl;
-
-/**
- * flag to keep track of how we were registered
- */
-static int secondary;
-
-/**
- * Verifies that the requested secure level is valid, given the current
- * secure level.
- */
-static int seclvl_sanity(int reqlvl)
-{
- if ((reqlvl < -1) || (reqlvl > 2)) {
- seclvl_printk(1, KERN_WARNING, "Attempt to set seclvl out of "
- "range: [%d]\n", reqlvl);
- return -EINVAL;
- }
- if ((seclvl == 0) && (reqlvl == -1))
- return 0;
- if (reqlvl < seclvl) {
- seclvl_printk(1, KERN_WARNING, "Attempt to lower seclvl to "
- "[%d]\n", reqlvl);
- return -EPERM;
- }
- return 0;
-}
-
-/**
- * security level advancement rules:
- * Valid levels are -1 through 2, inclusive.
- * From -1, stuck. [ in case compiled into kernel ]
- * From 0 or above, can only increment.
- */
-static void do_seclvl_advance(void *data, u64 val)
-{
- int ret;
- int newlvl = (int)val;
-
- ret = seclvl_sanity(newlvl);
- if (ret)
- return;
-
- if (newlvl > 2) {
- seclvl_printk(1, KERN_WARNING, "Cannot advance to seclvl "
- "[%d]\n", newlvl);
- return;
- }
- if (seclvl == -1) {
- seclvl_printk(1, KERN_WARNING, "Not allowed to advance to "
- "seclvl [%d]\n", seclvl);
- return;
- }
- seclvl = newlvl; /* would it be more "correct" to set *data? */
- return;
-}
-
-static u64 seclvl_int_get(void *data)
-{
- return *(int *)data;
-}
-
-DEFINE_SIMPLE_ATTRIBUTE(seclvl_file_ops, seclvl_int_get, do_seclvl_advance, "%lld\n");
-
-static unsigned char hashedPassword[SHA1_DIGEST_SIZE];
-
-/**
- * Converts a block of plaintext of into its SHA1 hashed value.
- *
- * It would be nice if crypto had a wrapper to do this for us linear
- * people...
- */
-static int
-plaintext_to_sha1(unsigned char *hash, const char *plaintext, unsigned int len)
-{
- struct hash_desc desc;
- struct scatterlist sg;
- int err;
-
- if (len > PAGE_SIZE) {
- seclvl_printk(0, KERN_ERR, "Plaintext password too large (%d "
- "characters). Largest possible is %lu "
- "bytes.\n", len, PAGE_SIZE);
- return -EINVAL;
- }
- desc.tfm = crypto_alloc_hash("sha1", 0, CRYPTO_ALG_ASYNC);
- if (IS_ERR(desc.tfm)) {
- seclvl_printk(0, KERN_ERR,
- "Failed to load transform for SHA1\n");
- return -EINVAL;
- }
- sg_init_one(&sg, (u8 *)plaintext, len);
- desc.flags = CRYPTO_TFM_REQ_MAY_SLEEP;
- err = crypto_hash_digest(&desc, &sg, len, hash);
- crypto_free_hash(desc.tfm);
- return err;
-}
-
-/**
- * Called whenever the user writes to the sysfs passwd handle to this kernel
- * object. It hashes the password and compares the hashed results.
- */
-static ssize_t
-passwd_write_file(struct file * file, const char __user * buf,
- size_t count, loff_t *ppos)
-{
- char *p;
- int len;
- unsigned char tmp[SHA1_DIGEST_SIZE];
-
- if (!*passwd && !*sha1_passwd) {
- seclvl_printk(0, KERN_ERR, "Attempt to password-unlock the "
- "seclvl module, but neither a plain text "
- "password nor a SHA1 hashed password was "
- "passed in as a module parameter! This is a "
- "bug, since it should not be possible to be in "
- "this part of the module; please tell a "
- "maintainer about this event.\n");
- return -EINVAL;
- }
-
- if (count >= PAGE_SIZE)
- return -EINVAL;
- if (*ppos != 0)
- return -EINVAL;
- p = kmalloc(count, GFP_KERNEL);
- if (!p)
- return -ENOMEM;
- len = -EFAULT;
- if (copy_from_user(p, buf, count))
- goto out;
-
- len = count;
- /* ``echo "secret" > seclvl/passwd'' includes a newline */
- if (p[len - 1] == '\n')
- len--;
- /* Hash the password, then compare the hashed values */
- if ((len = plaintext_to_sha1(tmp, p, len))) {
- seclvl_printk(0, KERN_ERR, "Error hashing password: rc = "
- "[%d]\n", len);
- goto out;
- }
-
- len = -EPERM;
- if (memcmp(hashedPassword, tmp, SHA1_DIGEST_SIZE))
- goto out;
-
- seclvl_printk(0, KERN_INFO,
- "Password accepted; seclvl reduced to 0.\n");
- seclvl = 0;
- len = count;
-
-out:
- kfree (p);
- return len;
-}
-
-static struct file_operations passwd_file_ops = {
- .write = passwd_write_file,
-};
-
-/**
- * Explicitely disallow ptrace'ing the init process.
- */
-static int seclvl_ptrace(struct task_struct *parent, struct task_struct *child)
-{
- if (seclvl >= 0 && child->pid == 1) {
- seclvl_printk(1, KERN_WARNING, "Attempt to ptrace "
- "the init process dissallowed in "
- "secure level %d\n", seclvl);
- return -EPERM;
- }
- return 0;
-}
-
-/**
- * Capability checks for seclvl. The majority of the policy
- * enforcement for seclvl takes place here.
- */
-static int seclvl_capable(struct task_struct *tsk, int cap)
-{
- int rc = 0;
-
- /* init can do anything it wants */
- if (tsk->pid == 1)
- return 0;
-
- if (seclvl > 0) {
- rc = -EPERM;
-
- if (cap == CAP_LINUX_IMMUTABLE)
- seclvl_printk(1, KERN_WARNING, "Attempt to modify "
- "the IMMUTABLE and/or APPEND extended "
- "attribute on a file with the IMMUTABLE "
- "and/or APPEND extended attribute set "
- "denied in seclvl [%d]\n", seclvl);
- else if (cap == CAP_SYS_RAWIO)
- seclvl_printk(1, KERN_WARNING, "Attempt to perform "
- "raw I/O while in secure level [%d] "
- "denied\n", seclvl);
- else if (cap == CAP_NET_ADMIN)
- seclvl_printk(1, KERN_WARNING, "Attempt to perform "
- "network administrative task while "
- "in secure level [%d] denied\n", seclvl);
- else if (cap == CAP_SETUID)
- seclvl_printk(1, KERN_WARNING, "Attempt to setuid "
- "while in secure level [%d] denied\n",
- seclvl);
- else if (cap == CAP_SETGID)
- seclvl_printk(1, KERN_WARNING, "Attempt to setgid "
- "while in secure level [%d] denied\n",
- seclvl);
- else if (cap == CAP_SYS_MODULE)
- seclvl_printk(1, KERN_WARNING, "Attempt to perform "
- "a module operation while in secure "
- "level [%d] denied\n", seclvl);
- else
- rc = 0;
- }
-
- if (!rc) {
- if (!(cap_is_fs_cap(cap) ? tsk->fsuid == 0 : tsk->euid == 0))
- rc = -EPERM;
- }
-
- if (rc)
- seclvl_printk(1, KERN_WARNING, "Capability denied\n");
-
- return rc;
-}
-
-/**
- * Disallow reversing the clock in seclvl > 1
- */
-static int seclvl_settime(struct timespec *tv, struct timezone *tz)
-{
- if (tv && seclvl > 1) {
- struct timespec now;
- now = current_kernel_time();
- if (tv->tv_sec < now.tv_sec ||
- (tv->tv_sec == now.tv_sec && tv->tv_nsec < now.tv_nsec)) {
- seclvl_printk(1, KERN_WARNING, "Attempt to decrement "
- "time in secure level %d denied: "
- "current->pid = [%d], "
- "current->group_leader->pid = [%d]\n",
- seclvl, current->pid,
- current->group_leader->pid);
- return -EPERM;
- } /* if attempt to decrement time */
- } /* if seclvl > 1 */
- return 0;
-}
-
-/* claim the blockdev to exclude mounters, release on file close */
-static int seclvl_bd_claim(struct inode *inode)
-{
- int holder;
- struct block_device *bdev = NULL;
- dev_t dev = inode->i_rdev;
- bdev = open_by_devnum(dev, FMODE_WRITE);
- if (bdev) {
- if (bd_claim(bdev, &holder)) {
- blkdev_put(bdev);
- return -EPERM;
- }
- /* claimed, mark it to release on close */
- inode->i_security = current;
- }
- return 0;
-}
-
-/* release the blockdev if you claimed it */
-static void seclvl_bd_release(struct inode *inode)
-{
- if (inode && S_ISBLK(inode->i_mode) && inode->i_security == current) {
- struct block_device *bdev = inode->i_bdev;
- if (bdev) {
- bd_release(bdev);
- blkdev_put(bdev);
- inode->i_security = NULL;
- }
- }
-}
-
-/**
- * Security for writes to block devices is regulated by this seclvl
- * function. Deny all writes to block devices in seclvl 2. In
- * seclvl 1, we only deny writes to *mounted* block devices.
- */
-static int
-seclvl_inode_permission(struct inode *inode, int mask, struct nameidata *nd)
-{
- if (current->pid != 1 && S_ISBLK(inode->i_mode) && (mask & MAY_WRITE)) {
- switch (seclvl) {
- case 2:
- seclvl_printk(1, KERN_WARNING, "Write to block device "
- "denied in secure level [%d]\n", seclvl);
- return -EPERM;
- case 1:
- if (seclvl_bd_claim(inode)) {
- seclvl_printk(1, KERN_WARNING,
- "Write to mounted block device "
- "denied in secure level [%d]\n",
- seclvl);
- return -EPERM;
- }
- }
- }
- return 0;
-}
-
-/**
- * The SUID and SGID bits cannot be set in seclvl >= 1
- */
-static int seclvl_inode_setattr(struct dentry *dentry, struct iattr *iattr)
-{
- if (seclvl > 0) {
- if (iattr->ia_valid & ATTR_MODE)
- if (iattr->ia_mode & S_ISUID ||
- iattr->ia_mode & S_ISGID) {
- seclvl_printk(1, KERN_WARNING, "Attempt to "
- "modify SUID or SGID bit "
- "denied in seclvl [%d]\n",
- seclvl);
- return -EPERM;
- }
- }
- return 0;
-}
-
-/* release busied block devices */
-static void seclvl_file_free_security(struct file *filp)
-{
- struct dentry *dentry = filp->f_dentry;
-
- if (dentry)
- seclvl_bd_release(dentry->d_inode);
-}
-
-/**
- * Cannot unmount in secure level 2
- */
-static int seclvl_umount(struct vfsmount *mnt, int flags)
-{
- if (current->pid != 1 && seclvl == 2) {
- seclvl_printk(1, KERN_WARNING, "Attempt to unmount in secure "
- "level %d\n", seclvl);
- return -EPERM;
- }
- return 0;
-}
-
-static struct security_operations seclvl_ops = {
- .ptrace = seclvl_ptrace,
- .capable = seclvl_capable,
- .inode_permission = seclvl_inode_permission,
- .inode_setattr = seclvl_inode_setattr,
- .file_free_security = seclvl_file_free_security,
- .settime = seclvl_settime,
- .sb_umount = seclvl_umount,
-};
-
-/**
- * Process the password-related module parameters
- */
-static int processPassword(void)
-{
- int rc = 0;
- if (*passwd) {
- char *p;
-
- if (*sha1_passwd) {
- seclvl_printk(0, KERN_ERR, "Error: Both "
- "passwd and sha1_passwd "
- "were set, but they are mutually "
- "exclusive.\n");
- return -EINVAL;
- }
-
- p = kstrdup(passwd, GFP_KERNEL);
- if (p == NULL)
- return -ENOMEM;
-
- if ((rc = plaintext_to_sha1(hashedPassword, p, strlen(p))))
- seclvl_printk(0, KERN_ERR, "Error: SHA1 support not "
- "in kernel\n");
-
- kfree (p);
- /* All static data goes to the BSS, which zero's the
- * plaintext password out for us. */
- } else if (*sha1_passwd) { // Base 16
- int i;
- i = strlen(sha1_passwd);
- if (i != (SHA1_DIGEST_SIZE * 2)) {
- seclvl_printk(0, KERN_ERR, "Received [%d] bytes; "
- "expected [%d] for the hexadecimal "
- "representation of the SHA1 hash of "
- "the password.\n",
- i, (SHA1_DIGEST_SIZE * 2));
- return -EINVAL;
- }
- while ((i -= 2) + 2) {
- unsigned char tmp;
- tmp = sha1_passwd[i + 2];
- sha1_passwd[i + 2] = '\0';
- hashedPassword[i / 2] = (unsigned char)
- simple_strtol(&sha1_passwd[i], NULL, 16);
- sha1_passwd[i + 2] = tmp;
- }
- }
- return rc;
-}
-
-/**
- * securityfs registrations
- */
-struct dentry *dir_ino, *seclvl_ino, *passwd_ino;
-
-static int seclvlfs_register(void)
-{
- int rc = 0;
-
- dir_ino = securityfs_create_dir("seclvl", NULL);
-
- if (IS_ERR(dir_ino))
- return PTR_ERR(dir_ino);
-
- seclvl_ino = securityfs_create_file("seclvl", S_IRUGO | S_IWUSR,
- dir_ino, &seclvl, &seclvl_file_ops);
- if (IS_ERR(seclvl_ino)) {
- rc = PTR_ERR(seclvl_ino);
- goto out_deldir;
- }
- if (*passwd || *sha1_passwd) {
- passwd_ino = securityfs_create_file("passwd", S_IRUGO | S_IWUSR,
- dir_ino, NULL, &passwd_file_ops);
- if (IS_ERR(passwd_ino)) {
- rc = PTR_ERR(passwd_ino);
- goto out_delf;
- }
- }
- return rc;
-
-out_delf:
- securityfs_remove(seclvl_ino);
-
-out_deldir:
- securityfs_remove(dir_ino);
-
- return rc;
-}
-
-static void seclvlfs_unregister(void)
-{
- securityfs_remove(seclvl_ino);
-
- if (*passwd || *sha1_passwd)
- securityfs_remove(passwd_ino);
-
- securityfs_remove(dir_ino);
-}
-
-/**
- * Initialize the seclvl module.
- */
-static int __init seclvl_init(void)
-{
- int rc = 0;
- static char once;
-
- if (verbosity < 0 || verbosity > 1) {
- printk(KERN_ERR "Error: bad verbosity [%d]; only 0 or 1 "
- "are valid values\n", verbosity);
- rc = -EINVAL;
- goto exit;
- }
- if (initlvl < -1 || initlvl > 2) {
- seclvl_printk(0, KERN_ERR, "Error: bad initial securelevel "
- "[%d].\n", initlvl);
- rc = -EINVAL;
- goto exit;
- }
- seclvl = initlvl;
- if ((rc = processPassword())) {
- seclvl_printk(0, KERN_ERR, "Error processing the password "
- "module parameter(s): rc = [%d]\n", rc);
- goto exit;
- }
-
- if ((rc = seclvlfs_register())) {
- seclvl_printk(0, KERN_ERR, "Error registering with sysfs\n");
- goto exit;
- }
- /* register ourselves with the security framework */
- if (register_security(&seclvl_ops)) {
- seclvl_printk(0, KERN_ERR,
- "seclvl: Failure registering with the "
- "kernel.\n");
- /* try registering with primary module */
- rc = mod_reg_security(MY_NAME, &seclvl_ops);
- if (rc) {
- seclvl_printk(0, KERN_ERR, "seclvl: Failure "
- "registering with primary security "
- "module.\n");
- seclvlfs_unregister();
- goto exit;
- } /* if primary module registered */
- secondary = 1;
- } /* if we registered ourselves with the security framework */
-
- seclvl_printk(0, KERN_INFO, "seclvl: Successfully initialized.\n");
-
- if (once) {
- once = 1;
- seclvl_printk(0, KERN_INFO, "seclvl is going away. It has been "
- "buggy for ages. Also, be warned that "
- "Securelevels are useless.");
- }
- exit:
- if (rc)
- printk(KERN_ERR "seclvl: Error during initialization: rc = "
- "[%d]\n", rc);
- return rc;
-}
-
-/**
- * Remove the seclvl module.
- */
-static void __exit seclvl_exit(void)
-{
- seclvlfs_unregister();
-
- if (secondary)
- mod_unreg_security(MY_NAME, &seclvl_ops);
- else if (unregister_security(&seclvl_ops))
- seclvl_printk(0, KERN_INFO,
- "seclvl: Failure unregistering with the "
- "kernel\n");
-}
-
-module_init(seclvl_init);
-module_exit(seclvl_exit);
-
-MODULE_AUTHOR("Michael A. Halcrow <mike@halcrow.us>");
-MODULE_DESCRIPTION("LSM implementation of the BSD Secure Levels");
-MODULE_LICENSE("GPL");
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index e4d81a42fca4..e9969a2fc846 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -398,7 +398,7 @@ static int try_context_mount(struct super_block *sb, void *data)
/* Standard string-based options. */
char *p, *options = data;
- while ((p = strsep(&options, ",")) != NULL) {
+ while ((p = strsep(&options, "|")) != NULL) {
int token;
substring_t args[MAX_OPT_ARGS];
@@ -1923,18 +1923,40 @@ static inline void take_option(char **to, char *from, int *first, int len)
if (!*first) {
**to = ',';
*to += 1;
- }
- else
+ } else
*first = 0;
memcpy(*to, from, len);
*to += len;
}
+static inline void take_selinux_option(char **to, char *from, int *first,
+ int len)
+{
+ int current_size = 0;
+
+ if (!*first) {
+ **to = '|';
+ *to += 1;
+ }
+ else
+ *first = 0;
+
+ while (current_size < len) {
+ if (*from != '"') {
+ **to = *from;
+ *to += 1;
+ }
+ from += 1;
+ current_size += 1;
+ }
+}
+
static int selinux_sb_copy_data(struct file_system_type *type, void *orig, void *copy)
{
int fnosec, fsec, rc = 0;
char *in_save, *in_curr, *in_end;
char *sec_curr, *nosec_save, *nosec;
+ int open_quote = 0;
in_curr = orig;
sec_curr = copy;
@@ -1956,11 +1978,14 @@ static int selinux_sb_copy_data(struct file_system_type *type, void *orig, void
in_save = in_end = orig;
do {
- if (*in_end == ',' || *in_end == '\0') {
+ if (*in_end == '"')
+ open_quote = !open_quote;
+ if ((*in_end == ',' && open_quote == 0) ||
+ *in_end == '\0') {
int len = in_end - in_curr;
if (selinux_option(in_curr, len))
- take_option(&sec_curr, in_curr, &fsec, len);
+ take_selinux_option(&sec_curr, in_curr, &fsec, len);
else
take_option(&nosec, in_curr, &fnosec, len);
@@ -3594,7 +3619,9 @@ static void selinux_sock_graft(struct sock* sk, struct socket *parent)
struct inode_security_struct *isec = SOCK_INODE(parent)->i_security;
struct sk_security_struct *sksec = sk->sk_security;
- isec->sid = sksec->sid;
+ if (sk->sk_family == PF_INET || sk->sk_family == PF_INET6 ||
+ sk->sk_family == PF_UNIX)
+ isec->sid = sksec->sid;
selinux_netlbl_sock_graft(sk, parent);
}
diff --git a/security/selinux/selinuxfs.c b/security/selinux/selinuxfs.c
index bab7b386cb8d..cd244419c980 100644
--- a/security/selinux/selinuxfs.c
+++ b/security/selinux/selinuxfs.c
@@ -1253,10 +1253,10 @@ static int sel_make_dir(struct inode *dir, struct dentry *dentry)
inode->i_op = &simple_dir_inode_operations;
inode->i_fop = &simple_dir_operations;
/* directory inodes start off with i_nlink == 2 (for "." entry) */
- inode->i_nlink++;
+ inc_nlink(inode);
d_add(dentry, inode);
/* bump link count on parent directory, too */
- dir->i_nlink++;
+ inc_nlink(dir);
out:
return ret;
}
diff --git a/sound/Makefile b/sound/Makefile
index 1f60797afa8a..5f6bef57e825 100644
--- a/sound/Makefile
+++ b/sound/Makefile
@@ -2,6 +2,7 @@
#
obj-$(CONFIG_SOUND) += soundcore.o
+obj-$(CONFIG_SOUND_PRIME) += sound_firmware.o
obj-$(CONFIG_SOUND_PRIME) += oss/
obj-$(CONFIG_DMASOUND) += oss/
obj-$(CONFIG_SND) += core/ i2c/ drivers/ isa/ pci/ ppc/ arm/ synth/ usb/ sparc/ parisc/ pcmcia/ mips/
@@ -11,4 +12,4 @@ ifeq ($(CONFIG_SND),y)
obj-y += last.o
endif
-soundcore-objs := sound_core.o sound_firmware.o
+soundcore-objs := sound_core.o
diff --git a/sound/core/info_oss.c b/sound/core/info_oss.c
index 3ebc34919c76..a444bfe2cf74 100644
--- a/sound/core/info_oss.c
+++ b/sound/core/info_oss.c
@@ -96,11 +96,11 @@ static void snd_sndstat_proc_read(struct snd_info_entry *entry,
{
snd_iprintf(buffer, "Sound Driver:3.8.1a-980706 (ALSA v" CONFIG_SND_VERSION " emulation code)\n");
snd_iprintf(buffer, "Kernel: %s %s %s %s %s\n",
- system_utsname.sysname,
- system_utsname.nodename,
- system_utsname.release,
- system_utsname.version,
- system_utsname.machine);
+ init_utsname()->sysname,
+ init_utsname()->nodename,
+ init_utsname()->release,
+ init_utsname()->version,
+ init_utsname()->machine);
snd_iprintf(buffer, "Config options: 0\n");
snd_iprintf(buffer, "\nInstalled drivers: \n");
snd_iprintf(buffer, "Type 10: ALSA emulation\n");
diff --git a/sound/core/pcm.c b/sound/core/pcm.c
index bf8f412988b8..fbbbcd20c4cc 100644
--- a/sound/core/pcm.c
+++ b/sound/core/pcm.c
@@ -629,6 +629,9 @@ int snd_pcm_new_stream(struct snd_pcm *pcm, int stream, int substream_count)
substream->number = idx;
substream->stream = stream;
sprintf(substream->name, "subdevice #%i", idx);
+ snprintf(substream->latency_id, sizeof(substream->latency_id),
+ "ALSA-PCM%d-%d%c%d", pcm->card->number, pcm->device,
+ (stream ? 'c' : 'p'), idx);
substream->buffer_bytes_max = UINT_MAX;
if (prev == NULL)
pstr->substream = substream;
diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c
index 0224c70414f5..37b4b10850ae 100644
--- a/sound/core/pcm_native.c
+++ b/sound/core/pcm_native.c
@@ -25,6 +25,7 @@
#include <linux/file.h>
#include <linux/slab.h>
#include <linux/time.h>
+#include <linux/latency.h>
#include <linux/uio.h>
#include <sound/core.h>
#include <sound/control.h>
@@ -347,11 +348,26 @@ out:
return err;
}
+static int period_to_usecs(struct snd_pcm_runtime *runtime)
+{
+ int usecs;
+
+ if (! runtime->rate)
+ return -1; /* invalid */
+
+ /* take 75% of period time as the deadline */
+ usecs = (750000 / runtime->rate) * runtime->period_size;
+ usecs += ((750000 % runtime->rate) * runtime->period_size) /
+ runtime->rate;
+
+ return usecs;
+}
+
static int snd_pcm_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params)
{
struct snd_pcm_runtime *runtime;
- int err;
+ int err, usecs;
unsigned int bits;
snd_pcm_uframes_t frames;
@@ -431,6 +447,10 @@ static int snd_pcm_hw_params(struct snd_pcm_substream *substream,
snd_pcm_timer_resolution_change(substream);
runtime->status->state = SNDRV_PCM_STATE_SETUP;
+
+ remove_acceptable_latency(substream->latency_id);
+ if ((usecs = period_to_usecs(runtime)) >= 0)
+ set_acceptable_latency(substream->latency_id, usecs);
return 0;
_error:
/* hardware might be unuseable from this time,
@@ -490,6 +510,7 @@ static int snd_pcm_hw_free(struct snd_pcm_substream *substream)
if (substream->ops->hw_free)
result = substream->ops->hw_free(substream);
runtime->status->state = SNDRV_PCM_STATE_OPEN;
+ remove_acceptable_latency(substream->latency_id);
return result;
}
@@ -2831,8 +2852,8 @@ static ssize_t snd_pcm_write(struct file *file, const char __user *buf,
return result;
}
-static ssize_t snd_pcm_readv(struct file *file, const struct iovec *_vector,
- unsigned long count, loff_t * offset)
+static ssize_t snd_pcm_aio_read(struct kiocb *iocb, const struct iovec *iov,
+ unsigned long nr_segs, loff_t pos)
{
struct snd_pcm_file *pcm_file;
@@ -2843,22 +2864,22 @@ static ssize_t snd_pcm_readv(struct file *file, const struct iovec *_vector,
void __user **bufs;
snd_pcm_uframes_t frames;
- pcm_file = file->private_data;
+ pcm_file = iocb->ki_filp->private_data;
substream = pcm_file->substream;
snd_assert(substream != NULL, return -ENXIO);
runtime = substream->runtime;
if (runtime->status->state == SNDRV_PCM_STATE_OPEN)
return -EBADFD;
- if (count > 1024 || count != runtime->channels)
+ if (nr_segs > 1024 || nr_segs != runtime->channels)
return -EINVAL;
- if (!frame_aligned(runtime, _vector->iov_len))
+ if (!frame_aligned(runtime, iov->iov_len))
return -EINVAL;
- frames = bytes_to_samples(runtime, _vector->iov_len);
- bufs = kmalloc(sizeof(void *) * count, GFP_KERNEL);
+ frames = bytes_to_samples(runtime, iov->iov_len);
+ bufs = kmalloc(sizeof(void *) * nr_segs, GFP_KERNEL);
if (bufs == NULL)
return -ENOMEM;
- for (i = 0; i < count; ++i)
- bufs[i] = _vector[i].iov_base;
+ for (i = 0; i < nr_segs; ++i)
+ bufs[i] = iov[i].iov_base;
result = snd_pcm_lib_readv(substream, bufs, frames);
if (result > 0)
result = frames_to_bytes(runtime, result);
@@ -2866,8 +2887,8 @@ static ssize_t snd_pcm_readv(struct file *file, const struct iovec *_vector,
return result;
}
-static ssize_t snd_pcm_writev(struct file *file, const struct iovec *_vector,
- unsigned long count, loff_t * offset)
+static ssize_t snd_pcm_aio_write(struct kiocb *iocb, const struct iovec *iov,
+ unsigned long nr_segs, loff_t pos)
{
struct snd_pcm_file *pcm_file;
struct snd_pcm_substream *substream;
@@ -2877,7 +2898,7 @@ static ssize_t snd_pcm_writev(struct file *file, const struct iovec *_vector,
void __user **bufs;
snd_pcm_uframes_t frames;
- pcm_file = file->private_data;
+ pcm_file = iocb->ki_filp->private_data;
substream = pcm_file->substream;
snd_assert(substream != NULL, result = -ENXIO; goto end);
runtime = substream->runtime;
@@ -2885,17 +2906,17 @@ static ssize_t snd_pcm_writev(struct file *file, const struct iovec *_vector,
result = -EBADFD;
goto end;
}
- if (count > 128 || count != runtime->channels ||
- !frame_aligned(runtime, _vector->iov_len)) {
+ if (nr_segs > 128 || nr_segs != runtime->channels ||
+ !frame_aligned(runtime, iov->iov_len)) {
result = -EINVAL;
goto end;
}
- frames = bytes_to_samples(runtime, _vector->iov_len);
- bufs = kmalloc(sizeof(void *) * count, GFP_KERNEL);
+ frames = bytes_to_samples(runtime, iov->iov_len);
+ bufs = kmalloc(sizeof(void *) * nr_segs, GFP_KERNEL);
if (bufs == NULL)
return -ENOMEM;
- for (i = 0; i < count; ++i)
- bufs[i] = _vector[i].iov_base;
+ for (i = 0; i < nr_segs; ++i)
+ bufs[i] = iov[i].iov_base;
result = snd_pcm_lib_writev(substream, bufs, frames);
if (result > 0)
result = frames_to_bytes(runtime, result);
@@ -3405,7 +3426,7 @@ struct file_operations snd_pcm_f_ops[2] = {
{
.owner = THIS_MODULE,
.write = snd_pcm_write,
- .writev = snd_pcm_writev,
+ .aio_write = snd_pcm_aio_write,
.open = snd_pcm_playback_open,
.release = snd_pcm_release,
.poll = snd_pcm_playback_poll,
@@ -3417,7 +3438,7 @@ struct file_operations snd_pcm_f_ops[2] = {
{
.owner = THIS_MODULE,
.read = snd_pcm_read,
- .readv = snd_pcm_readv,
+ .aio_read = snd_pcm_aio_read,
.open = snd_pcm_capture_open,
.release = snd_pcm_release,
.poll = snd_pcm_capture_poll,
diff --git a/sound/mips/au1x00.c b/sound/mips/au1x00.c
index c31b38659221..ff6e6fc198a1 100644
--- a/sound/mips/au1x00.c
+++ b/sound/mips/au1x00.c
@@ -258,7 +258,7 @@ au1000_dma_interrupt(int irq, void *dev_id, struct pt_regs *regs)
static unsigned int rates[] = {8000, 11025, 16000, 22050};
static struct snd_pcm_hw_constraint_list hw_constraints_rates = {
- .count = sizeof(rates) / sizeof(rates[0]),
+ .count = ARRAY_SIZE(rates),
.list = rates,
.mask = 0,
};
diff --git a/sound/oss/COPYING b/sound/oss/COPYING
deleted file mode 100644
index 916d1f0f2842..000000000000
--- a/sound/oss/COPYING
+++ /dev/null
@@ -1,339 +0,0 @@
- GNU GENERAL PUBLIC LICENSE
- Version 2, June 1991
-
- Copyright (C) 1989, 1991 Free Software Foundation, Inc.
- 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
- Preamble
-
- The licenses for most software are designed to take away your
-freedom to share and change it. By contrast, the GNU General Public
-License is intended to guarantee your freedom to share and change free
-software--to make sure the software is free for all its users. This
-General Public License applies to most of the Free Software
-Foundation's software and to any other program whose authors commit to
-using it. (Some other Free Software Foundation software is covered by
-the GNU Library General Public License instead.) You can apply it to
-your programs, too.
-
- When we speak of free software, we are referring to freedom, not
-price. Our General Public Licenses are designed to make sure that you
-have the freedom to distribute copies of free software (and charge for
-this service if you wish), that you receive source code or can get it
-if you want it, that you can change the software or use pieces of it
-in new free programs; and that you know you can do these things.
-
- To protect your rights, we need to make restrictions that forbid
-anyone to deny you these rights or to ask you to surrender the rights.
-These restrictions translate to certain responsibilities for you if you
-distribute copies of the software, or if you modify it.
-
- For example, if you distribute copies of such a program, whether
-gratis or for a fee, you must give the recipients all the rights that
-you have. You must make sure that they, too, receive or can get the
-source code. And you must show them these terms so they know their
-rights.
-
- We protect your rights with two steps: (1) copyright the software, and
-(2) offer you this license which gives you legal permission to copy,
-distribute and/or modify the software.
-
- Also, for each author's protection and ours, we want to make certain
-that everyone understands that there is no warranty for this free
-software. If the software is modified by someone else and passed on, we
-want its recipients to know that what they have is not the original, so
-that any problems introduced by others will not reflect on the original
-authors' reputations.
-
- Finally, any free program is threatened constantly by software
-patents. We wish to avoid the danger that redistributors of a free
-program will individually obtain patent licenses, in effect making the
-program proprietary. To prevent this, we have made it clear that any
-patent must be licensed for everyone's free use or not licensed at all.
-
- The precise terms and conditions for copying, distribution and
-modification follow.
-
- GNU GENERAL PUBLIC LICENSE
- TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
-
- 0. This License applies to any program or other work which contains
-a notice placed by the copyright holder saying it may be distributed
-under the terms of this General Public License. The "Program", below,
-refers to any such program or work, and a "work based on the Program"
-means either the Program or any derivative work under copyright law:
-that is to say, a work containing the Program or a portion of it,
-either verbatim or with modifications and/or translated into another
-language. (Hereinafter, translation is included without limitation in
-the term "modification".) Each licensee is addressed as "you".
-
-Activities other than copying, distribution and modification are not
-covered by this License; they are outside its scope. The act of
-running the Program is not restricted, and the output from the Program
-is covered only if its contents constitute a work based on the
-Program (independent of having been made by running the Program).
-Whether that is true depends on what the Program does.
-
- 1. You may copy and distribute verbatim copies of the Program's
-source code as you receive it, in any medium, provided that you
-conspicuously and appropriately publish on each copy an appropriate
-copyright notice and disclaimer of warranty; keep intact all the
-notices that refer to this License and to the absence of any warranty;
-and give any other recipients of the Program a copy of this License
-along with the Program.
-
-You may charge a fee for the physical act of transferring a copy, and
-you may at your option offer warranty protection in exchange for a fee.
-
- 2. You may modify your copy or copies of the Program or any portion
-of it, thus forming a work based on the Program, and copy and
-distribute such modifications or work under the terms of Section 1
-above, provided that you also meet all of these conditions:
-
- a) You must cause the modified files to carry prominent notices
- stating that you changed the files and the date of any change.
-
- b) You must cause any work that you distribute or publish, that in
- whole or in part contains or is derived from the Program or any
- part thereof, to be licensed as a whole at no charge to all third
- parties under the terms of this License.
-
- c) If the modified program normally reads commands interactively
- when run, you must cause it, when started running for such
- interactive use in the most ordinary way, to print or display an
- announcement including an appropriate copyright notice and a
- notice that there is no warranty (or else, saying that you provide
- a warranty) and that users may redistribute the program under
- these conditions, and telling the user how to view a copy of this
- License. (Exception: if the Program itself is interactive but
- does not normally print such an announcement, your work based on
- the Program is not required to print an announcement.)
-
-These requirements apply to the modified work as a whole. If
-identifiable sections of that work are not derived from the Program,
-and can be reasonably considered independent and separate works in
-themselves, then this License, and its terms, do not apply to those
-sections when you distribute them as separate works. But when you
-distribute the same sections as part of a whole which is a work based
-on the Program, the distribution of the whole must be on the terms of
-this License, whose permissions for other licensees extend to the
-entire whole, and thus to each and every part regardless of who wrote it.
-
-Thus, it is not the intent of this section to claim rights or contest
-your rights to work written entirely by you; rather, the intent is to
-exercise the right to control the distribution of derivative or
-collective works based on the Program.
-
-In addition, mere aggregation of another work not based on the Program
-with the Program (or with a work based on the Program) on a volume of
-a storage or distribution medium does not bring the other work under
-the scope of this License.
-
- 3. You may copy and distribute the Program (or a work based on it,
-under Section 2) in object code or executable form under the terms of
-Sections 1 and 2 above provided that you also do one of the following:
-
- a) Accompany it with the complete corresponding machine-readable
- source code, which must be distributed under the terms of Sections
- 1 and 2 above on a medium customarily used for software interchange; or,
-
- b) Accompany it with a written offer, valid for at least three
- years, to give any third party, for a charge no more than your
- cost of physically performing source distribution, a complete
- machine-readable copy of the corresponding source code, to be
- distributed under the terms of Sections 1 and 2 above on a medium
- customarily used for software interchange; or,
-
- c) Accompany it with the information you received as to the offer
- to distribute corresponding source code. (This alternative is
- allowed only for noncommercial distribution and only if you
- received the program in object code or executable form with such
- an offer, in accord with Subsection b above.)
-
-The source code for a work means the preferred form of the work for
-making modifications to it. For an executable work, complete source
-code means all the source code for all modules it contains, plus any
-associated interface definition files, plus the scripts used to
-control compilation and installation of the executable. However, as a
-special exception, the source code distributed need not include
-anything that is normally distributed (in either source or binary
-form) with the major components (compiler, kernel, and so on) of the
-operating system on which the executable runs, unless that component
-itself accompanies the executable.
-
-If distribution of executable or object code is made by offering
-access to copy from a designated place, then offering equivalent
-access to copy the source code from the same place counts as
-distribution of the source code, even though third parties are not
-compelled to copy the source along with the object code.
-
- 4. You may not copy, modify, sublicense, or distribute the Program
-except as expressly provided under this License. Any attempt
-otherwise to copy, modify, sublicense or distribute the Program is
-void, and will automatically terminate your rights under this License.
-However, parties who have received copies, or rights, from you under
-this License will not have their licenses terminated so long as such
-parties remain in full compliance.
-
- 5. You are not required to accept this License, since you have not
-signed it. However, nothing else grants you permission to modify or
-distribute the Program or its derivative works. These actions are
-prohibited by law if you do not accept this License. Therefore, by
-modifying or distributing the Program (or any work based on the
-Program), you indicate your acceptance of this License to do so, and
-all its terms and conditions for copying, distributing or modifying
-the Program or works based on it.
-
- 6. Each time you redistribute the Program (or any work based on the
-Program), the recipient automatically receives a license from the
-original licensor to copy, distribute or modify the Program subject to
-these terms and conditions. You may not impose any further
-restrictions on the recipients' exercise of the rights granted herein.
-You are not responsible for enforcing compliance by third parties to
-this License.
-
- 7. If, as a consequence of a court judgment or allegation of patent
-infringement or for any other reason (not limited to patent issues),
-conditions are imposed on you (whether by court order, agreement or
-otherwise) that contradict the conditions of this License, they do not
-excuse you from the conditions of this License. If you cannot
-distribute so as to satisfy simultaneously your obligations under this
-License and any other pertinent obligations, then as a consequence you
-may not distribute the Program at all. For example, if a patent
-license would not permit royalty-free redistribution of the Program by
-all those who receive copies directly or indirectly through you, then
-the only way you could satisfy both it and this License would be to
-refrain entirely from distribution of the Program.
-
-If any portion of this section is held invalid or unenforceable under
-any particular circumstance, the balance of the section is intended to
-apply and the section as a whole is intended to apply in other
-circumstances.
-
-It is not the purpose of this section to induce you to infringe any
-patents or other property right claims or to contest validity of any
-such claims; this section has the sole purpose of protecting the
-integrity of the free software distribution system, which is
-implemented by public license practices. Many people have made
-generous contributions to the wide range of software distributed
-through that system in reliance on consistent application of that
-system; it is up to the author/donor to decide if he or she is willing
-to distribute software through any other system and a licensee cannot
-impose that choice.
-
-This section is intended to make thoroughly clear what is believed to
-be a consequence of the rest of this License.
-
- 8. If the distribution and/or use of the Program is restricted in
-certain countries either by patents or by copyrighted interfaces, the
-original copyright holder who places the Program under this License
-may add an explicit geographical distribution limitation excluding
-those countries, so that distribution is permitted only in or among
-countries not thus excluded. In such case, this License incorporates
-the limitation as if written in the body of this License.
-
- 9. The Free Software Foundation may publish revised and/or new versions
-of the General Public License from time to time. Such new versions will
-be similar in spirit to the present version, but may differ in detail to
-address new problems or concerns.
-
-Each version is given a distinguishing version number. If the Program
-specifies a version number of this License which applies to it and "any
-later version", you have the option of following the terms and conditions
-either of that version or of any later version published by the Free
-Software Foundation. If the Program does not specify a version number of
-this License, you may choose any version ever published by the Free Software
-Foundation.
-
- 10. If you wish to incorporate parts of the Program into other free
-programs whose distribution conditions are different, write to the author
-to ask for permission. For software which is copyrighted by the Free
-Software Foundation, write to the Free Software Foundation; we sometimes
-make exceptions for this. Our decision will be guided by the two goals
-of preserving the free status of all derivatives of our free software and
-of promoting the sharing and reuse of software generally.
-
- NO WARRANTY
-
- 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
-FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
-OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
-PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
-OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
-TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
-PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
-REPAIR OR CORRECTION.
-
- 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
-WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
-REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
-INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
-OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
-TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
-YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
-PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGES.
-
- END OF TERMS AND CONDITIONS
-
- Appendix: How to Apply These Terms to Your New Programs
-
- If you develop a new program, and you want it to be of the greatest
-possible use to the public, the best way to achieve this is to make it
-free software which everyone can redistribute and change under these terms.
-
- To do so, attach the following notices to the program. It is safest
-to attach them to the start of each source file to most effectively
-convey the exclusion of warranty; and each file should have at least
-the "copyright" line and a pointer to where the full notice is found.
-
- <one line to give the program's name and a brief idea of what it does.>
- Copyright (C) 19yy <name of author>
-
- 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
-
-Also add information on how to contact you by electronic and paper mail.
-
-If the program is interactive, make it output a short notice like this
-when it starts in an interactive mode:
-
- Gnomovision version 69, Copyright (C) 19yy name of author
- Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
- This is free software, and you are welcome to redistribute it
- under certain conditions; type `show c' for details.
-
-The hypothetical commands `show w' and `show c' should show the appropriate
-parts of the General Public License. Of course, the commands you use may
-be called something other than `show w' and `show c'; they could even be
-mouse-clicks or menu items--whatever suits your program.
-
-You should also get your employer (if you work as a programmer) or your
-school, if any, to sign a "copyright disclaimer" for the program, if
-necessary. Here is a sample; alter the names:
-
- Yoyodyne, Inc., hereby disclaims all copyright interest in the program
- `Gnomovision' (which makes passes at compilers) written by James Hacker.
-
- <signature of Ty Coon>, 1 April 1989
- Ty Coon, President of Vice
-
-This General Public License does not permit incorporating your program into
-proprietary programs. If your program is a subroutine library, you may
-consider it more useful to permit linking proprietary applications with the
-library. If this is what you want to do, use the GNU Library General
-Public License instead of this License.
diff --git a/sound/oss/cs46xx.c b/sound/oss/cs46xx.c
index 5195bf933cb8..43193581f836 100644
--- a/sound/oss/cs46xx.c
+++ b/sound/oss/cs46xx.c
@@ -96,7 +96,7 @@
#include <asm/dma.h>
#include <asm/uaccess.h>
-#include "cs46xxpm-24.h"
+#include "cs46xxpm.h"
#include "cs46xx_wrapper-24.h"
#include "cs461x.h"
@@ -389,8 +389,10 @@ static int cs_hardware_init(struct cs_card *card);
static int cs46xx_powerup(struct cs_card *card, unsigned int type);
static int cs461x_powerdown(struct cs_card *card, unsigned int type, int suspendflag);
static void cs461x_clear_serial_FIFOs(struct cs_card *card, int type);
+#ifdef CONFIG_PM
static int cs46xx_suspend_tbl(struct pci_dev *pcidev, pm_message_t state);
static int cs46xx_resume_tbl(struct pci_dev *pcidev);
+#endif
#if CSDEBUG
@@ -2980,7 +2982,7 @@ static void clkrun_hack(struct cs_card *card, int change)
card->active+=change;
- acpi_dev = pci_find_device(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB_3, NULL);
+ acpi_dev = pci_get_device(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB_3, NULL);
if (acpi_dev == NULL)
return; /* Not a thinkpad thats for sure */
@@ -3006,6 +3008,7 @@ static void clkrun_hack(struct cs_card *card, int change)
change,card->active));
outw(control&~0x2000, port+0x10);
}
+ pci_dev_put(acpi_dev);
}
@@ -5389,8 +5392,10 @@ static struct pci_driver cs46xx_pci_driver = {
.id_table = cs46xx_pci_tbl,
.probe = cs46xx_probe,
.remove = __devexit_p(cs46xx_remove),
- .suspend = CS46XX_SUSPEND_TBL,
- .resume = CS46XX_RESUME_TBL,
+#ifdef CONFIG_PM
+ .suspend = cs46xx_suspend_tbl,
+ .resume = cs46xx_resume_tbl,
+#endif
};
static int __init cs46xx_init_module(void)
@@ -5420,7 +5425,7 @@ static void __exit cs46xx_cleanup_module(void)
module_init(cs46xx_init_module);
module_exit(cs46xx_cleanup_module);
-#if CS46XX_ACPI_SUPPORT
+#ifdef CONFIG_PM
static int cs46xx_suspend_tbl(struct pci_dev *pcidev, pm_message_t state)
{
struct cs_card *s = PCI_GET_DRIVER_DATA(pcidev);
diff --git a/sound/oss/cs46xxpm-24.h b/sound/oss/cs46xxpm-24.h
deleted file mode 100644
index ad82db84d013..000000000000
--- a/sound/oss/cs46xxpm-24.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/*******************************************************************************
-*
-* "cs46xxpm-24.h" -- Cirrus Logic-Crystal CS46XX linux audio driver.
-*
-* Copyright (C) 2000,2001 Cirrus Logic Corp.
-* -- tom woller (twoller@crystal.cirrus.com) or
-* (pcaudio@crystal.cirrus.com).
-*
-* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
-*
-* 12/22/00 trw - new file.
-*
-*******************************************************************************/
-#ifndef __CS46XXPM24_H
-#define __CS46XXPM24_H
-
-#include <linux/pm.h>
-#include "cs46xxpm.h"
-
-
-#define CS46XX_ACPI_SUPPORT 1
-#ifdef CS46XX_ACPI_SUPPORT
-/*
-* for now (12/22/00) only enable the pm_register PM support.
-* allow these table entries to be null.
-*/
-static int cs46xx_suspend_tbl(struct pci_dev *pcidev, pm_message_t state);
-static int cs46xx_resume_tbl(struct pci_dev *pcidev);
-#define CS46XX_SUSPEND_TBL cs46xx_suspend_tbl
-#define CS46XX_RESUME_TBL cs46xx_resume_tbl
-#else
-#define CS46XX_SUSPEND_TBL cs46xx_null
-#define CS46XX_RESUME_TBL cs46xx_null
-#endif
-
-#endif
diff --git a/sound/oss/swarm_cs4297a.c b/sound/oss/swarm_cs4297a.c
index eb5ea32fd1b0..3edf8d4ac998 100644
--- a/sound/oss/swarm_cs4297a.c
+++ b/sound/oss/swarm_cs4297a.c
@@ -725,7 +725,7 @@ static int serdma_reg_access(struct cs4297a_state *s, u64 data)
serdma_t *d = &s->dma_dac;
u64 *data_p;
unsigned swptr;
- int flags;
+ unsigned long flags;
serdma_descr_t *descr;
if (s->reg_request) {
diff --git a/sound/oss/trident.c b/sound/oss/trident.c
index 2813e4c8e365..147c816a1f22 100644
--- a/sound/oss/trident.c
+++ b/sound/oss/trident.c
@@ -488,10 +488,6 @@ static void ali_set_spdif_out_rate(struct trident_card *card, unsigned int rate)
static void ali_enable_special_channel(struct trident_state *stat);
static struct trident_channel *ali_alloc_rec_pcm_channel(struct trident_card *card);
static struct trident_channel *ali_alloc_pcm_channel(struct trident_card *card);
-static void ali_restore_regs(struct trident_card *card);
-static void ali_save_regs(struct trident_card *card);
-static int trident_suspend(struct pci_dev *dev, pm_message_t unused);
-static int trident_resume(struct pci_dev *dev);
static void ali_free_pcm_channel(struct trident_card *card, unsigned int channel);
static int ali_setup_multi_channels(struct trident_card *card, int chan_nums);
static unsigned int ali_get_spdif_in_rate(struct trident_card *card);
@@ -507,13 +503,6 @@ static int ali_allocate_other_states_resources(struct trident_state *state,
int chan_nums);
static void ali_free_other_states_resources(struct trident_state *state);
-/* save registers for ALi Power Management */
-static struct ali_saved_registers {
- unsigned long global_regs[ALI_GLOBAL_REGS];
- unsigned long channel_regs[ALI_CHANNELS][ALI_CHANNEL_REGS];
- unsigned mixer_regs[ALI_MIXER_REGS];
-} ali_registers;
-
#define seek_offset(dma_ptr, buffer, cnt, offset, copy_count) do { \
(dma_ptr) += (offset); \
(buffer) += (offset); \
@@ -1873,7 +1862,7 @@ trident_read(struct file *file, char __user *buffer, size_t count, loff_t * ppos
unsigned swptr;
int cnt;
- pr_debug("trident: trident_read called, count = %d\n", count);
+ pr_debug("trident: trident_read called, count = %zd\n", count);
VALIDATE_STATE(state);
@@ -1989,7 +1978,7 @@ trident_write(struct file *file, const char __user *buffer, size_t count, loff_t
unsigned int copy_count;
int lret; /* for lock_set_fmt */
- pr_debug("trident: trident_write called, count = %d\n", count);
+ pr_debug("trident: trident_write called, count = %zd\n", count);
VALIDATE_STATE(state);
@@ -3280,8 +3269,8 @@ ali_setup_spdif_out(struct trident_card *card, int flag)
char temp;
struct pci_dev *pci_dev = NULL;
- pci_dev = pci_find_device(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M1533,
- pci_dev);
+ pci_dev = pci_get_device(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M1533,
+ pci_dev);
if (pci_dev == NULL)
return;
pci_read_config_byte(pci_dev, 0x61, &temp);
@@ -3295,6 +3284,8 @@ ali_setup_spdif_out(struct trident_card *card, int flag)
temp |= 0x10;
pci_write_config_byte(pci_dev, 0x7e, temp);
+ pci_dev_put(pci_dev);
+
ch = inb(TRID_REG(card, ALI_SCTRL));
outb(ch | ALI_SPDIF_OUT_ENABLE, TRID_REG(card, ALI_SCTRL));
ch = inb(TRID_REG(card, ALI_SPDIF_CTRL));
@@ -3501,16 +3492,19 @@ ali_close_multi_channels(void)
char temp = 0;
struct pci_dev *pci_dev = NULL;
- pci_dev = pci_find_device(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M1533,
- pci_dev);
+ pci_dev = pci_get_device(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M1533,
+ pci_dev);
if (pci_dev == NULL)
return -1;
+
pci_read_config_byte(pci_dev, 0x59, &temp);
temp &= ~0x80;
pci_write_config_byte(pci_dev, 0x59, temp);
- pci_dev = pci_find_device(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M7101,
- pci_dev);
+ pci_dev_put(pci_dev);
+
+ pci_dev = pci_get_device(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M7101,
+ NULL);
if (pci_dev == NULL)
return -1;
@@ -3518,6 +3512,8 @@ ali_close_multi_channels(void)
temp &= ~0x20;
pci_write_config_byte(pci_dev, 0xB8, temp);
+ pci_dev_put(pci_dev);
+
return 0;
}
@@ -3528,21 +3524,26 @@ ali_setup_multi_channels(struct trident_card *card, int chan_nums)
char temp = 0;
struct pci_dev *pci_dev = NULL;
- pci_dev = pci_find_device(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M1533,
- pci_dev);
+ pci_dev = pci_get_device(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M1533,
+ pci_dev);
if (pci_dev == NULL)
return -1;
pci_read_config_byte(pci_dev, 0x59, &temp);
temp |= 0x80;
pci_write_config_byte(pci_dev, 0x59, temp);
- pci_dev = pci_find_device(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M7101,
- pci_dev);
+ pci_dev_put(pci_dev);
+
+ pci_dev = pci_get_device(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M7101,
+ NULL);
if (pci_dev == NULL)
return -1;
pci_read_config_byte(pci_dev, (int) 0xB8, &temp);
temp |= 0x20;
pci_write_config_byte(pci_dev, (int) 0xB8, (u8) temp);
+
+ pci_dev_put(pci_dev);
+
if (chan_nums == 6) {
dwValue = inl(TRID_REG(card, ALI_SCTRL)) | 0x000f0000;
outl(dwValue, TRID_REG(card, ALI_SCTRL));
@@ -3653,6 +3654,14 @@ ali_allocate_other_states_resources(struct trident_state *state, int chan_nums)
return 0;
}
+#ifdef CONFIG_PM
+/* save registers for ALi Power Management */
+static struct ali_saved_registers {
+ unsigned long global_regs[ALI_GLOBAL_REGS];
+ unsigned long channel_regs[ALI_CHANNELS][ALI_CHANNEL_REGS];
+ unsigned mixer_regs[ALI_MIXER_REGS];
+} ali_registers;
+
static void
ali_save_regs(struct trident_card *card)
{
@@ -3746,6 +3755,7 @@ trident_resume(struct pci_dev *dev)
}
return 0;
}
+#endif
static struct trident_channel *
ali_alloc_pcm_channel(struct trident_card *card)
@@ -4105,8 +4115,8 @@ ali_reset_5451(struct trident_card *card)
unsigned int dwVal;
unsigned short wCount, wReg;
- pci_dev = pci_find_device(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M1533,
- pci_dev);
+ pci_dev = pci_get_device(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M1533,
+ pci_dev);
if (pci_dev == NULL)
return -1;
@@ -4116,6 +4126,7 @@ ali_reset_5451(struct trident_card *card)
pci_read_config_dword(pci_dev, 0x7c, &dwVal);
pci_write_config_dword(pci_dev, 0x7c, dwVal & 0xf7ffffff);
udelay(5000);
+ pci_dev_put(pci_dev);
pci_dev = card->pci_dev;
if (pci_dev == NULL)
@@ -4395,7 +4406,7 @@ trident_probe(struct pci_dev *pci_dev, const struct pci_device_id *pci_id)
init_timer(&card->timer);
card->iobase = iobase;
- card->pci_dev = pci_dev;
+ card->pci_dev = pci_dev_get(pci_dev);
card->pci_id = pci_id->device;
card->revision = revision;
card->irq = pci_dev->irq;
@@ -4549,6 +4560,7 @@ out_unregister_sound_dsp:
out_free_irq:
free_irq(card->irq, card);
out_proc_fs:
+ pci_dev_put(card->pci_dev);
if (res) {
remove_proc_entry("ALi5451", NULL);
res = NULL;
@@ -4599,9 +4611,9 @@ trident_remove(struct pci_dev *pci_dev)
}
unregister_sound_dsp(card->dev_audio);
- kfree(card);
-
pci_set_drvdata(pci_dev, NULL);
+ pci_dev_put(card->pci_dev);
+ kfree(card);
}
MODULE_AUTHOR("Alan Cox, Aaron Holtzman, Ollie Lho, Ching Ling Lee, Muli Ben-Yehuda");
@@ -4616,8 +4628,10 @@ static struct pci_driver trident_pci_driver = {
.id_table = trident_pci_tbl,
.probe = trident_probe,
.remove = __devexit_p(trident_remove),
+#ifdef CONFIG_PM
.suspend = trident_suspend,
.resume = trident_resume
+#endif
};
static int __init
diff --git a/sound/oss/via82cxxx_audio.c b/sound/oss/via82cxxx_audio.c
index 08d8c94d01b2..2fec42fc3482 100644
--- a/sound/oss/via82cxxx_audio.c
+++ b/sound/oss/via82cxxx_audio.c
@@ -1547,7 +1547,7 @@ static int via_mixer_open (struct inode *inode, struct file *file)
DPRINTK ("ENTER\n");
- while ((pdev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, pdev)) != NULL) {
+ while ((pdev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pdev)) != NULL) {
drvr = pci_dev_driver (pdev);
if (drvr == &via_driver) {
assert (pci_get_drvdata (pdev) != NULL);
@@ -1562,6 +1562,7 @@ static int via_mixer_open (struct inode *inode, struct file *file)
return -ENODEV;
match:
+ pci_dev_put(pdev);
file->private_data = card->ac97;
DPRINTK ("EXIT, returning 0\n");
@@ -3245,7 +3246,7 @@ static int via_dsp_open (struct inode *inode, struct file *file)
}
card = NULL;
- while ((pdev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, pdev)) != NULL) {
+ while ((pdev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pdev)) != NULL) {
drvr = pci_dev_driver (pdev);
if (drvr == &via_driver) {
assert (pci_get_drvdata (pdev) != NULL);
@@ -3264,6 +3265,7 @@ static int via_dsp_open (struct inode *inode, struct file *file)
return -ENODEV;
match:
+ pci_dev_put(pdev);
if (nonblock) {
if (!mutex_trylock(&card->open_mutex)) {
DPRINTK ("EXIT, returning -EAGAIN\n");
diff --git a/sound/pci/echoaudio/layla24_dsp.c b/sound/pci/echoaudio/layla24_dsp.c
index 7ec5b63d0dce..97e42e115147 100644
--- a/sound/pci/echoaudio/layla24_dsp.c
+++ b/sound/pci/echoaudio/layla24_dsp.c
@@ -302,11 +302,11 @@ static int switch_asic(struct echoaudio *chip, const struct firmware *asic)
/* Check to see if this is already loaded */
if (asic != chip->asic_code) {
- monitors = kmalloc(MONITOR_ARRAY_SIZE, GFP_KERNEL);
+ monitors = kmemdup(chip->comm_page->monitors,
+ MONITOR_ARRAY_SIZE, GFP_KERNEL);
if (! monitors)
return -ENOMEM;
- memcpy(monitors, chip->comm_page->monitors, MONITOR_ARRAY_SIZE);
memset(chip->comm_page->monitors, ECHOGAIN_MUTED,
MONITOR_ARRAY_SIZE);
diff --git a/sound/sound_core.c b/sound/sound_core.c
index 62d4d0c81261..0b0a016ca6d6 100644
--- a/sound/sound_core.c
+++ b/sound/sound_core.c
@@ -551,10 +551,6 @@ int soundcore_open(struct inode *inode, struct file *file)
return -ENODEV;
}
-extern int mod_firmware_load(const char *, char **);
-EXPORT_SYMBOL(mod_firmware_load);
-
-
MODULE_DESCRIPTION("Core sound module");
MODULE_AUTHOR("Alan Cox");
MODULE_LICENSE("GPL");
diff --git a/sound/sound_firmware.c b/sound/sound_firmware.c
index 6ddadfac35ad..3a181d4c0dc6 100644
--- a/sound/sound_firmware.c
+++ b/sound/sound_firmware.c
@@ -4,6 +4,7 @@
#include <linux/mm.h>
#include <linux/slab.h>
#include <asm/uaccess.h>
+#include "oss/sound_firmware.h"
static int do_mod_firmware_load(const char *fn, char **fp)
{
@@ -59,8 +60,7 @@ static int do_mod_firmware_load(const char *fn, char **fp)
* value zero on a failure.
*
* Caution: This API is not recommended. Firmware should be loaded via
- * an ioctl call and a setup application. This function may disappear
- * in future.
+ * request_firmware.
*/
int mod_firmware_load(const char *fn, char **fp)
@@ -73,4 +73,6 @@ int mod_firmware_load(const char *fn, char **fp)
set_fs(fs);
return r;
}
+EXPORT_SYMBOL(mod_firmware_load);
+MODULE_LICENSE("GPL");
diff --git a/sound/sparc/dbri.c b/sound/sparc/dbri.c
index 8016541ec16d..5a97be689b40 100644
--- a/sound/sparc/dbri.c
+++ b/sound/sparc/dbri.c
@@ -2412,8 +2412,6 @@ static struct snd_kcontrol_new dbri_controls[] __devinitdata = {
CS4215_SINGLE("Mic boost", 4, 4, 1, 1)
};
-#define NUM_CS4215_CONTROLS (sizeof(dbri_controls)/sizeof(struct snd_kcontrol_new))
-
static int __init snd_dbri_mixer(struct snd_dbri * dbri)
{
struct snd_card *card;
@@ -2424,7 +2422,7 @@ static int __init snd_dbri_mixer(struct snd_dbri * dbri)
card = dbri->card;
strcpy(card->mixername, card->shortname);
- for (idx = 0; idx < NUM_CS4215_CONTROLS; idx++) {
+ for (idx = 0; idx < ARRAY_SIZE(dbri_controls); idx++) {
if ((err = snd_ctl_add(card,
snd_ctl_new1(&dbri_controls[idx], dbri))) < 0)
return err;
diff --git a/sound/usb/usbaudio.c b/sound/usb/usbaudio.c
index 49248fa7aef4..a42acf6d7b68 100644
--- a/sound/usb/usbaudio.c
+++ b/sound/usb/usbaudio.c
@@ -2046,10 +2046,9 @@ int snd_usb_ctl_msg(struct usb_device *dev, unsigned int pipe, __u8 request,
void *buf = NULL;
if (size > 0) {
- buf = kmalloc(size, GFP_KERNEL);
+ buf = kmemdup(data, size, GFP_KERNEL);
if (!buf)
return -ENOMEM;
- memcpy(buf, data, size);
}
err = usb_control_msg(dev, pipe, request, requesttype,
value, index, buf, size, timeout);
@@ -2846,12 +2845,11 @@ static int create_fixed_stream_quirk(struct snd_usb_audio *chip,
int stream, err;
int *rate_table = NULL;
- fp = kmalloc(sizeof(*fp), GFP_KERNEL);
+ fp = kmemdup(quirk->data, sizeof(*fp), GFP_KERNEL);
if (! fp) {
- snd_printk(KERN_ERR "cannot malloc\n");
+ snd_printk(KERN_ERR "cannot memdup\n");
return -ENOMEM;
}
- memcpy(fp, quirk->data, sizeof(*fp));
if (fp->nr_rates > 0) {
rate_table = kmalloc(sizeof(int) * fp->nr_rates, GFP_KERNEL);
if (!rate_table) {
@@ -3029,10 +3027,9 @@ static int create_ua1000_quirk(struct snd_usb_audio *chip,
altsd->bNumEndpoints != 1)
return -ENXIO;
- fp = kmalloc(sizeof(*fp), GFP_KERNEL);
+ fp = kmemdup(&ua1000_format, sizeof(*fp), GFP_KERNEL);
if (!fp)
return -ENOMEM;
- memcpy(fp, &ua1000_format, sizeof(*fp));
fp->channels = alts->extra[4];
fp->iface = altsd->bInterfaceNumber;
diff --git a/sound/usb/usbmidi.c b/sound/usb/usbmidi.c
index abe29dadd979..0dcf78adb99a 100644
--- a/sound/usb/usbmidi.c
+++ b/sound/usb/usbmidi.c
@@ -323,10 +323,9 @@ static int send_bulk_static_data(struct snd_usb_midi_out_endpoint* ep,
const void *data, int len)
{
int err;
- void *buf = kmalloc(len, GFP_KERNEL);
+ void *buf = kmemdup(data, len, GFP_KERNEL);
if (!buf)
return -ENOMEM;
- memcpy(buf, data, len);
dump_urb("sending", buf, len);
err = usb_bulk_msg(ep->umidi->chip->dev, ep->urb->pipe, buf, len,
NULL, 250);